summaryrefslogtreecommitdiffhomepage
path: root/dev/Kernel/FSKit
diff options
context:
space:
mode:
Diffstat (limited to 'dev/Kernel/FSKit')
-rw-r--r--dev/Kernel/FSKit/Defines.h12
-rw-r--r--dev/Kernel/FSKit/HPFS.h30
-rw-r--r--dev/Kernel/FSKit/IndexableProperty.h63
-rw-r--r--dev/Kernel/FSKit/NeFS.h402
4 files changed, 507 insertions, 0 deletions
diff --git a/dev/Kernel/FSKit/Defines.h b/dev/Kernel/FSKit/Defines.h
new file mode 100644
index 00000000..9176e3dd
--- /dev/null
+++ b/dev/Kernel/FSKit/Defines.h
@@ -0,0 +1,12 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, TQ B.V, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+#define FSKIT_VERSION "1.0.0"
+#define FSKIT_VERSION_BCD 0x0100
diff --git a/dev/Kernel/FSKit/HPFS.h b/dev/Kernel/FSKit/HPFS.h
new file mode 100644
index 00000000..f6aec5be
--- /dev/null
+++ b/dev/Kernel/FSKit/HPFS.h
@@ -0,0 +1,30 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, TQ B.V, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+/// @file HPFS.h
+/// @brief HPFS filesystem support.
+
+#define kHPFSVersion 0x0100
+#define kHPFSMagic " HPFS"
+#define kHPFSMagicLen 8
+
+#define kHPFSMinimumDiskSize (gib_cast(64))
+
+enum
+{
+ kHPFSInvalidDrive,
+ kHPFSHDDDrive,
+ kHPFSSSDDrive,
+ kHPFSMassStorageDrive,
+ kHPFSSCSIDrive,
+ kHPFSDriveCount,
+};
+
+struct HPFS_EXPLICIT_BOOT_SECTOR;
diff --git a/dev/Kernel/FSKit/IndexableProperty.h b/dev/Kernel/FSKit/IndexableProperty.h
new file mode 100644
index 00000000..412a1205
--- /dev/null
+++ b/dev/Kernel/FSKit/IndexableProperty.h
@@ -0,0 +1,63 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, TQ B.V, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <CFKit/Property.h>
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DriveMgr.h>
+
+#define kIndexerNodeNameLength 255
+#define kIndexerClaimed 0xCF
+
+namespace Kernel
+{
+ namespace Indexer
+ {
+ struct IndexProperty final
+ {
+ public:
+ Char Drive[kDriveNameLen];
+ Char Path[kIndexerNodeNameLength];
+ };
+
+ class IndexableProperty final : public Property
+ {
+ public:
+ explicit IndexableProperty()
+ : Property()
+ {
+ Kernel::KString strProp(kMaxPropLen);
+ strProp += "/Properties/Indexable";
+
+ this->GetKey() = strProp;
+ }
+
+ ~IndexableProperty() override = default;
+
+ ZKA_COPY_DEFAULT(IndexableProperty);
+
+ public:
+ IndexProperty& Leak() noexcept;
+
+ public:
+ void AddFlag(Int16 flag);
+ void RemoveFlag(Int16 flag);
+ Int16 HasFlag(Int16 flag);
+
+ private:
+ IndexProperty fIndex;
+ UInt32 fFlags;
+ };
+
+ /// @brief Index a file into the indexer instance.
+ /// @param filename path
+ /// @param filenameLen used bytes in path.
+ /// @param indexer the filesystem indexer.
+ /// @return none.
+ Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer);
+ } // namespace Indexer
+} // namespace Kernel
diff --git a/dev/Kernel/FSKit/NeFS.h b/dev/Kernel/FSKit/NeFS.h
new file mode 100644
index 00000000..42857df9
--- /dev/null
+++ b/dev/Kernel/FSKit/NeFS.h
@@ -0,0 +1,402 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, TQ B.V, all rights reserved.
+
+ FILE: NeFS.h
+ PURPOSE: NeFS (New FileSystem) support.
+
+ Revision History:
+
+ ?/?/?: Added file (amlel)
+ 12/02/24: Add UUID macro for EPM and GPT partition schemes.
+ 3/16/24: Add mandatory sector size, kNeFSSectorSz is set to 2048 by
+default.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <HintKit/CompilerHint.h>
+#include <KernelKit/DriveMgr.h>
+#include <NewKit/Defines.h>
+
+/**
+ @brief New File System specification.
+ @author TQ B.V (TQ B.V, amlalelmahrouss at icloud dot com)
+*/
+
+#define kNeFSInvalidFork (-1)
+#define kNeFSInvalidCatalog (-1)
+#define kNeFSNodeNameLen (256)
+
+#define kNeFSMinimumDiskSize (gib_cast(4))
+
+#define kNeFSSectorSz (512)
+#define kNeFSForkDataSz (mib_cast(16))
+
+#define kNeFSIdentLen (8)
+#define kNeFSIdent " NeFS"
+#define kNeFSPadLen (392)
+
+#define kNeFSMetaFilePrefix '$'
+
+#define kNeFSVersionInteger (0x0129)
+#define kNeFSVerionString "1.2.9"
+
+/// @brief Standard fork types.
+#define kNeFSDataFork "main_data"
+#define kNeFSResourceFork "main_rsrc"
+
+#define kNeFSForkSize (sizeof(NFS_FORK_STRUCT))
+
+#define kNeFSPartitionTypeStandard (7)
+#define kNeFSPartitionTypePage (8)
+#define kNeFSPartitionTypeBoot (9)
+
+#define kNeFSCatalogKindFile (1)
+#define kNeFSCatalogKindDir (2)
+#define kNeFSCatalogKindAlias (3)
+
+//! Shared between network and/or partitions. Export forks as .zip when copying.
+#define kNeFSCatalogKindShared (4)
+
+#define kNeFSCatalogKindResource (5)
+#define kNeFSCatalogKindExecutable (6)
+
+#define kNeFSCatalogKindPage (8)
+
+#define kNeFSCatalogKindDevice (9)
+#define kNeFSCatalogKindLock (10)
+
+#define kNeFSCatalogKindRLE (11)
+#define kNeFSCatalogKindMetaFile (12)
+
+#define kNeFSCatalogKindTTF (13)
+#define kNeFSCatalogKindRIFF (14)
+#define kNeFSCatalogKindMPEG (15)
+#define kNeFSCatalogKindDVX (16)
+
+#define kNeFSSeparator '/'
+#define kNeFSSeparatorAlt '/'
+
+#define kNeFSUpDir ".."
+#define kNeFSRoot "/"
+#define kNeFSRootAlt "/"
+
+#define kNeFSLF '\r'
+#define kNeFSEOF (-1)
+
+#define kNeFSBitWidth (sizeof(Kernel::Char))
+#define kNeFSLbaType (Kernel::Lba)
+
+/// @note Start after the partition map header. (Virtual addressing)
+#define kNeFSRootCatalogStartAddress (1024)
+#define kNeFSCatalogStartAddress ((2048) + sizeof(NFS_ROOT_PARTITION_BLOCK))
+
+#define kResourceTypeDialog (10)
+#define kResourceTypeString (11)
+#define kResourceTypeMenu (12)
+#define kResourceTypeSound (13)
+#define kResourceTypeFont (14)
+
+#define kConfigLen (64)
+#define kPartLen (32)
+
+#define kNeFSFlagDeleted (70)
+#define kNeFSFlagUnallocated (0)
+#define kNeFSFlagCreated (71)
+
+#define kNeFSMimeNameLen (200)
+#define kNeFSForkNameLen (200)
+
+#define kNeFSFrameworkExt ".fwrk"
+#define kNeFSApplicationExt ".app"
+#define kNeFSJournalExt ".jrnl"
+
+struct NFS_CATALOG_STRUCT;
+struct NFS_FORK_STRUCT;
+struct NFS_ROOT_PARTITION_BLOCK;
+
+enum
+{
+ kNeFSHardDrive = 0xC0, // Hard Drive
+ kNeFSSolidStateDrive = 0xC1, // Solid State Drive
+ kNeFSOpticalDrive = 0x0C, // Blu-Ray/DVD
+ kNeFSMassStorageDevice = 0xCC, // USB
+ kNeFSScsiDrive = 0xC4, // SCSI Hard Drive
+ kNeFSFlashDrive = 0xC6,
+ kNeFSUnknown = 0xFF, // Unknown device.
+ kNeFSDriveCount = 7,
+};
+
+/// @brief Catalog type.
+struct PACKED NFS_CATALOG_STRUCT final
+{
+ Kernel::Char Name[kNeFSNodeNameLen];
+ Kernel::Char Mime[kNeFSMimeNameLen];
+
+ /// Catalog status flag.
+ Kernel::UInt16 Flags;
+ /// Custom catalog flags.
+ Kernel::UInt16 FilkMMFlags;
+ /// Catalog kind.
+ Kernel::Int32 Kind;
+
+ /// Size of the data fork.
+ Kernel::Lba DataForkSize;
+
+ /// Size of all resource forks.
+ Kernel::Lba ResourceForkSize;
+
+ Kernel::Lba DataFork;
+ Kernel::Lba ResourceFork;
+
+ Kernel::Lba NextSibling;
+ Kernel::Lba PrevSibling;
+};
+
+/// @brief Fork type, contains a data page.
+/// @note The way we store is way different than how other filesystems do, specific chunk of code are
+/// written into either the data fork or resource fork, the resource fork is reserved for file metadata.
+/// whereas the data fork is reserved for file data.
+struct PACKED NFS_FORK_STRUCT final
+{
+ Kernel::Char ForkName[kNeFSForkNameLen];
+ Kernel::Char CatalogName[kNeFSNodeNameLen];
+
+ Kernel::Int32 Flags;
+ Kernel::Int32 Kind;
+
+ Kernel::Int64 ResourceId;
+ Kernel::Int32 ResourceKind;
+ Kernel::Int32 ResourckMMFlags;
+
+ Kernel::Lba DataOffset; // 8 Where to look for this data?
+ Kernel::SizeT DataSize; /// Data size according using sector count.
+
+ Kernel::Lba NextSibling;
+ Kernel::Lba PreviousSibling;
+};
+
+/// @brief Partition block type
+struct PACKED NFS_ROOT_PARTITION_BLOCK final
+{
+ Kernel::Char Ident[kNeFSIdentLen];
+ Kernel::Char PartitionName[kPartLen];
+
+ Kernel::Int32 Flags;
+ Kernel::Int32 Kind;
+
+ Kernel::Lba StartCatalog;
+ Kernel::SizeT CatalogCount;
+
+ Kernel::SizeT DiskSize;
+
+ Kernel::SizeT FreeCatalog;
+ Kernel::SizeT FreeSectors;
+
+ Kernel::SizeT SectorCount;
+ Kernel::SizeT SectorSize;
+
+ Kernel::UInt64 Version;
+
+ Kernel::Lba EpmBlock;
+
+ Kernel::Char Pad[kNeFSPadLen];
+};
+
+namespace Kernel
+{
+ class NeFileSystemParser;
+ class NeFileSystemJournal;
+ class NeFileSystemHelper;
+
+ enum
+ {
+ kNeFSSubDriveA,
+ kNeFSSubDriveB,
+ kNeFSSubDriveC,
+ kNeFSSubDriveD,
+ kNeFSSubDriveInvalid,
+ kNeFSSubDriveCount,
+ };
+
+ /// \brief Resource fork kind.
+ enum
+ {
+ kNeFSRsrcForkKind = 0,
+ kNeFSDataForkKind = 1
+ };
+
+ ///
+ /// \name NeFileSystemParser
+ /// \brief NeFS parser class. (catalog creation, remove removal, root,
+ /// forks...) Designed like the DOM, detects the filesystem automatically.
+ ///
+ class NeFileSystemParser final
+ {
+ public:
+ explicit NeFileSystemParser() = default;
+ ~NeFileSystemParser() = default;
+
+ public:
+ ZKA_COPY_DEFAULT(NeFileSystemParser);
+
+ public:
+ /// @brief Creates a new fork inside the New filesystem partition.
+ /// @param catalog it's catalog
+ /// @param theFork the fork itself.
+ /// @return the fork
+ _Output NFS_FORK_STRUCT* CreateFork(_Input NFS_CATALOG_STRUCT* catalog,
+ _Input NFS_FORK_STRUCT& theFork);
+
+ /// @brief Find fork inside New filesystem.
+ /// @param catalog the catalog.
+ /// @param name the fork name.
+ /// @return the fork.
+ _Output NFS_FORK_STRUCT* FindFork(_Input NFS_CATALOG_STRUCT* catalog,
+ _Input const Char* name,
+ Boolean dataOrRsrc);
+
+ _Output Void RemoveFork(_Input NFS_FORK_STRUCT* fork);
+
+ _Output Void CloseFork(_Input NFS_FORK_STRUCT* fork);
+
+ _Output NFS_CATALOG_STRUCT* FindCatalog(_Input const Char* catalogName, Lba& outLba);
+
+ _Output NFS_CATALOG_STRUCT* GetCatalog(_Input const Char* name);
+
+ _Output NFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name,
+ _Input const Int32& flags,
+ _Input const Int32& kind);
+
+ _Output NFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name);
+
+ Bool WriteCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog,
+ _Input Bool isRsrcFork,
+ _Input VoidPtr data,
+ _Input SizeT sizeOfData,
+ _Input const Char* forkName);
+
+ VoidPtr ReadCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog,
+ _Input Bool isRsrcFork,
+ _Input SizeT dataSz,
+ _Input const Char* forkName);
+
+ bool Seek(_Input _Output NFS_CATALOG_STRUCT* catalog, SizeT off);
+
+ SizeT Tell(_Input _Output NFS_CATALOG_STRUCT* catalog);
+
+ bool RemoveCatalog(_Input const Char* catalog);
+
+ bool CloseCatalog(_InOut NFS_CATALOG_STRUCT* catalog);
+
+ /// @brief Make a EPM+NeFS drive out of the disk.
+ /// @param drive The drive to write on.
+ /// @return If it was sucessful, see err_local_get().
+ bool Format(_Input _Output DriveTrait* drive, _Input const Lba endLba, _Input const Int32 flags, const Char* part_name);
+
+ public:
+ Int32 mDriveIndex{kNeFSSubDriveA};
+ };
+
+ ///
+ /// \name NeFileSystemHelper
+ /// \brief Filesystem helper and utils.
+ ///
+
+ class NeFileSystemHelper final
+ {
+ public:
+ STATIC const Char* Root();
+ STATIC const Char* UpDir();
+ STATIC const Char Separator();
+ STATIC const Char MetaFile();
+ };
+
+ /// @brief Journal class for NeFS.
+ class NeFileSystemJournal final
+ {
+ public:
+ explicit NeFileSystemJournal(const char* stamp)
+ {
+ if (!stamp)
+ {
+ kcout << "Invalid: Journal Stamp, using default name.\r";
+ return;
+ }
+
+ kcout << "Info: Journal stamp: " << stamp << endl;
+ rt_copy_memory((VoidPtr)stamp, this->mStamp, rt_string_len(stamp));
+ }
+
+ ~NeFileSystemJournal() = default;
+
+ ZKA_COPY_DEFAULT(NeFileSystemJournal);
+
+ Bool CreateJournal(NeFileSystemParser* parser)
+ {
+ if (!parser)
+ return NO;
+
+ auto node = parser->CreateCatalog(mStamp);
+
+ if (!node)
+ return NO;
+
+ delete node;
+ node = nullptr;
+
+ return YES;
+ }
+
+ Bool IsJournalValid(NeFileSystemParser* parser)
+ {
+ if (!parser)
+ return NO;
+
+ if (auto node = parser->GetCatalog(mStamp);
+ node)
+ {
+ delete node;
+ node = nullptr;
+
+ return YES;
+ }
+
+ return NO;
+ }
+
+ Void Commit() {}
+
+ Void Start() {}
+
+ private:
+ Char mStamp[255] = { "/System/FileSystemStamp.jrnl" };
+
+ };
+
+ namespace Detail
+ {
+ Boolean fs_init_newfs(Void) noexcept;
+ } // namespace Detail
+} // namespace Kernel
+
+/// @brief Write to newfs disk.
+/// @param drv_mnt mounted interface.
+/// @param drv_trait drive info
+/// @param drv_indx drive index.
+/// @return status code.
+Kernel::Int32 fs_newfs_write(Kernel::MountpointInterface* drv_mnt,
+ Kernel::DriveTrait& drv_trait,
+ Kernel::Int32 drv_indx);
+
+/// @brief Read from newfs disk.
+/// @param drv_mnt mounted interface.
+/// @param drv_trait drive info
+/// @param drv_indx drive index.
+/// @return status code.
+Kernel::Int32 fs_newfs_read(Kernel::MountpointInterface* drv_mnt,
+ Kernel::DriveTrait& drv_trait,
+ Kernel::Int32 drv_indx);