diff options
Diffstat (limited to 'dev/Kernel/FSKit')
| -rw-r--r-- | dev/Kernel/FSKit/Defines.h | 12 | ||||
| -rw-r--r-- | dev/Kernel/FSKit/HPFS.h | 30 | ||||
| -rw-r--r-- | dev/Kernel/FSKit/IndexableProperty.h | 63 | ||||
| -rw-r--r-- | dev/Kernel/FSKit/NeFS.h | 402 |
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); |
