From 9e746d42d2e3faa526f12ba222f5ee6924dd30f9 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Fri, 26 Dec 2025 10:08:33 +0100 Subject: feat! breaking API changes, use header guards and libSystem fixes. Signed-off-by: Amlal El Mahrouss --- src/kernel/FSKit/Config.h | 5 +- src/kernel/FSKit/Ext2+IFS.h | 5 +- src/kernel/FSKit/Ext2.h | 5 +- src/kernel/FSKit/IndexableProperty.h | 5 +- src/kernel/FSKit/NeFS.h | 5 +- src/kernel/FSKit/OpenHeFS.h | 871 ++++++++++++++++++----------------- 6 files changed, 457 insertions(+), 439 deletions(-) (limited to 'src/kernel/FSKit') diff --git a/src/kernel/FSKit/Config.h b/src/kernel/FSKit/Config.h index 2324633f..b7dfad53 100644 --- a/src/kernel/FSKit/Config.h +++ b/src/kernel/FSKit/Config.h @@ -4,9 +4,12 @@ ======================================== */ -#pragma once +#ifndef FSKIT_CONFIG_H +#define FSKIT_CONFIG_H #include #define FSKIT_VERSION "0.0.2" #define FSKIT_VERSION_BCD 0x0002 + +#endif diff --git a/src/kernel/FSKit/Ext2+IFS.h b/src/kernel/FSKit/Ext2+IFS.h index a010f8b1..743e5159 100644 --- a/src/kernel/FSKit/Ext2+IFS.h +++ b/src/kernel/FSKit/Ext2+IFS.h @@ -4,7 +4,8 @@ ======================================== */ -#pragma once +#ifndef FSKIT_EXT2_IFS_H +#define FSKIT_EXT2_IFS_H #include #include @@ -271,3 +272,5 @@ class Ext2FileSystemParser final { BOOL GetInfo(VoidPtr node, VoidPtr info); }; } // namespace Kernel + +#endif diff --git a/src/kernel/FSKit/Ext2.h b/src/kernel/FSKit/Ext2.h index 35b2bf23..373607be 100644 --- a/src/kernel/FSKit/Ext2.h +++ b/src/kernel/FSKit/Ext2.h @@ -4,7 +4,8 @@ ======================================== */ -#pragma once +#ifndef FSKIT_EXT2_H +#define FSKIT_EXT2_H #include #include @@ -146,3 +147,5 @@ struct Ext2Node { EXT2_INODE inode; Kernel::UInt32 cursor{0}; }; + +#endif diff --git a/src/kernel/FSKit/IndexableProperty.h b/src/kernel/FSKit/IndexableProperty.h index 9eb64f81..68196fee 100644 --- a/src/kernel/FSKit/IndexableProperty.h +++ b/src/kernel/FSKit/IndexableProperty.h @@ -4,7 +4,8 @@ ======================================== */ -#pragma once +#ifndef FSKIT_INDEXABLEPROPERTY_H +#define FSKIT_INDEXABLEPROPERTY_H #include #include @@ -56,3 +57,5 @@ namespace Indexer { Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer); } // namespace Indexer } // namespace Kernel + +#endif diff --git a/src/kernel/FSKit/NeFS.h b/src/kernel/FSKit/NeFS.h index 5e38aaf5..d39de143 100644 --- a/src/kernel/FSKit/NeFS.h +++ b/src/kernel/FSKit/NeFS.h @@ -14,7 +14,8 @@ default. ======================================== */ -#pragma once +#ifndef FSKIT_NEFS_H +#define FSKIT_NEFS_H #include #include @@ -411,3 +412,5 @@ namespace NeFS { Boolean fs_init_nefs(Void); } // namespace NeFS } // namespace Kernel + +#endif diff --git a/src/kernel/FSKit/OpenHeFS.h b/src/kernel/FSKit/OpenHeFS.h index 16647095..cecad2ee 100644 --- a/src/kernel/FSKit/OpenHeFS.h +++ b/src/kernel/FSKit/OpenHeFS.h @@ -1,434 +1,437 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -/// @file OpenHeFS.h -/// @brief OpenHeFS filesystem support. - -#define kOpenHeFSVersion (0x0104) -#define kOpenHeFSMagic "OpenHeFS" -#define kOpenHeFSMagicLen (9U) - -#define kOpenHeFSBlockLen (512U) -#define kOpenHeFSFileNameLen (256U) -#define kOpenHeFSPartNameLen (128U) - -#define kOpenHeFSMinimumDiskSize (gib_cast(128)) - -#define kOpenHeFSDefaultVolumeName u8"OpenHeFS Volume" - -#define kOpenHeFSINDStartOffset (sizeof(HEFS_BOOT_NODE)) -#define kOpenHeFSINStartOffset (sizeof(HEFS_INDEX_NODE_DIRECTORY)) - -#define kOpenHeFSRootDirectory "/" -#define kOpenHeFSRootDirectoryU8 u8"/" - -#define kOpenHeFSSeparator '/' -#define kOpenHeFSUpDir ".." - -#define kOpenHeFSRootDirectoryLen (2U) - -#define kOpenHeFSSearchAllStr u8"*" - -struct HEFS_BOOT_NODE; -struct HEFS_INDEX_NODE; -struct HEFS_INDEX_NODE_DIRECTORY; -struct HEFS_JOURNAL_NODE; - -enum : UInt8 { - kOpenHeFSHardDrive = 0xC0, // Hard Drive - kOpenHeFSSolidStateDrive = 0xC1, // Solid State Drive - kOpenHeFSOpticalDrive = 0x0C, // Blu-Ray/DVD - kOpenHeFSMassStorageDevice = 0xCC, // USB - kOpenHeFSScsiDrive = 0xC4, // SCSI Hard Drive - kOpenHeFSFlashDrive = 0xC6, - kOpenHeFSUnknown = 0xFF, // Unknown device. - kOpenHeFSDriveCount = 8, -}; - -enum : UInt8 { - kOpenHeFSStatusUnlocked = 0x18, - kOpenHeFSStatusLocked, - kOpenHeFSStatusError, - kOpenHeFSStatusInvalid, - kOpenHeFSStatusCount, -}; - -enum : UInt16 { - kOpenHeFSEncodingFlagsUTF8 = 0x50, - kOpenHeFSEncodingFlagsUTF16, - kOpenHeFSEncodingFlagsUTF32, - kOpenHeFSEncodingFlagsUTF16BE, - kOpenHeFSEncodingFlagsUTF16LE, - kOpenHeFSEncodingFlagsUTF32BE, - kOpenHeFSEncodingFlagsUTF32LE, - kOpenHeFSEncodingFlagsUTF8BE, - kOpenHeFSEncodingFlagsUTF8LE, - kOpenHeFSEncodingFlagsBinary, - kOpenHeFSEncodingFlagsCount = 11, - kOpenHeFSFlagsNone = 0, - kOpenHeFSFlagsReadOnly = 0x100, - kOpenHeFSFlagsHidden, - kOpenHeFSFlagsSystem, - kOpenHeFSFlagsArchive, - kOpenHeFSFlagsDevice, - kOpenHeFSFlagsCount = 7 -}; - -inline constexpr UInt16 kOpenHeFSFileKindRegular = 0x00; -inline constexpr UInt16 kOpenHeFSFileKindDirectory = 0x01; -inline constexpr UInt16 kOpenHeFSFileKindBlock = 0x02; -inline constexpr UInt16 kOpenHeFSFileKindCharacter = 0x03; -inline constexpr UInt16 kOpenHeFSFileKindFIFO = 0x04; -inline constexpr UInt16 kOpenHeFSFileKindSocket = 0x05; -inline constexpr UInt16 kOpenHeFSFileKindSymbolicLink = 0x06; -inline constexpr UInt16 kOpenHeFSFileKindUnknown = 0x07; -inline constexpr UInt16 kOpenHeFSFileKindCount = 0x08; - -/// @brief OpenHeFS blocks are array containing sparse blocks of data. -/// @details The blocks are used to store the data of a file. Each block is a pointer to a block of -/// data on the disk. -inline constexpr UInt16 kOpenHeFSSliceCount = 0x10; - -inline constexpr UInt16 kOpenHeFSInvalidVID = 0xFFFF; - -namespace Kernel { -/// @brief Access time type. -/// @details Used to keep track of the INode, INodeDir allocation status. -typedef UInt64 ATime; - -/// @brief OpenHeFS Boot node. -/// @details Acts like a superblock, it contains the information about the filesystem. -/// @note The boot node is the first block of the filesystem. -struct PACKED HEFS_BOOT_NODE final { - Char fMagic[kOpenHeFSMagicLen]; /// @brief Magic number of the filesystem. - Utf8Char fVolName[kOpenHeFSPartNameLen]; /// @brief Volume name. - UInt32 fVersion; /// @brief Version of the filesystem. - UInt64 fBadSectors; /// @brief Number of bad sectors in the filesystem. - UInt64 fSectorCount; /// @brief Number of sectors in the filesystem. - UInt64 fSectorSize; /// @brief Size of the sector. - UInt32 fChecksum; /// @brief Checksum of the boot node. - UInt8 fDiskKind; /// @brief Kind of the drive. (Hard Drive, Solid State Drive, Optical - /// Drive, etc). - UInt8 fEncoding; /// @brief Encoding of the filesystem. (UTF-8, UTF-16, etc). - UInt64 fStartIND; /// @brief Start of the INode directory tree. - UInt64 fEndIND; /// @brief End of the INode directory tree. - UInt64 fINDCount; /// @brief Number of leafs in the INode tree. - UInt64 fDiskSize; /// @brief Size of the disk. (Could be a virtual size, that is not the - /// real size of the disk.) - UInt16 fDiskStatus; /// @brief Status of the disk. (locked, unlocked, error, invalid). - UInt16 fDiskFlags; /// @brief Flags of the disk. (read-only, read-write, etc). - UInt16 fVID; /// @brief Virtual Identification Number within an EPM disk. (0xFFFF if not used). - UInt64 fStartIN; /// @brief Start INodes range - UInt64 fEndIN; /// @brief End INodes range - UInt64 fStartBlock; /// @brief Start Blocks range - UInt64 fEndBlock; /// @brief End Blocks range - UInt64 fJournalLBA; /// @brief Boot Node's COW journal LBA. - Char fPad[264]; -}; - -inline constexpr ATime kOpenHeFSTimeInvalid = 0x0000000000000000; -inline constexpr ATime kOpenHeFSTimeMax = 0xFFFFFFFFFFFFFFFF - 1; - -/// @brief Journal Node structure -/// @param fHashPath target hash path -/// @param fStatus target status -/// @param fCopyElem copy of element -/// @param fCopyKind kind of element -struct PACKED HEFS_JOURNAL_NODE { - UInt64 fHashPath; - UInt64 fStatus; - UInt64 fCopyElem; - UInt8 fCopyKind; - UInt8 fPad[487]; -}; - -/// @brief This enum defines the opcode of the journal, here mentioned as 'kinds' -enum HeFSJournalKind : UInt8 { - kJournalKindInvalid = 0x00, - kJournalKindWrite = 0x01, - kJournalKindRename = 0x02, - kJournalKindDelete = 0x03, - kJournalKindFlagEdit = 0x04, - kJournalKindCreate = 0x05, - kJournalKindCount, -}; - -/// @brief OpenHeFS index node. -/// @details This structure is used to store the file information of a file. -/// @note The index node is a special type of INode that contains the file information. -/// @note The index node is used to store the file information of a file. -struct PACKED HEFS_INDEX_NODE final { - UInt64 fHashPath; /// @brief File name. - UInt32 fFlags; /// @brief File flags. - UInt16 fKind; /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket, - /// Symbolic Link, Unknown). - UInt32 fSize; /// @brief File size. - UInt32 fChecksum; /// @brief Checksum. - - Boolean fSymLink; /// @brief Is this a symbolic link? (if yes, the fName is the path to - /// the file and blocklinkstart and end contains it's inodes.) - - ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps. - UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. - UInt32 fMode; /// @brief File mode. (read, write, execute, etc). - - /// @brief Extents system by using blocks - /// @details Using an offset to ask fBase, and fLength to compute each slice's length. - UInt32 fOffsetSliceLow; - UInt32 fOffsetSliceHigh; - - Char fPad[437]; -}; - -enum { - kOpenHeFSInvalidColor = 0, - kOpenHeFSRed = 100, - kOpenHeFSBlack, - kOpenHeFSColorCount, -}; - -/// @brief OpenHeFS directory node. -/// @details This structure is used to store the directory information of a file. -/// @note The directory node is a special type of INode that contains the directory entries. -struct PACKED HEFS_INDEX_NODE_DIRECTORY final { - UInt64 fHashPath; /// @brief Directory path as FNV hash. - - UInt32 fFlags; /// @brief File flags. - UInt16 fReserved; /// @note Reserved for future use. - UInt32 fEntryCount; /// @brief Entry Count of this directory inode. - UInt32 fChecksum; /// @brief Checksum of the file, index node checksum. - - ATime fCreated, fAccessed, fModified, - fDeleted; /// @brief File timestamps and allocation status. - UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. - UInt32 fMode; /// @brief File mode. (read, write, execute, etc). - - /// @note These slices are organized as: - /// [0] = OFFSET - /// [1] = SIZE - /// @note Thus the += 2 when iterating over them. - UInt64 fINSlices[kOpenHeFSSliceCount]; /// @brief Start of the index node. - - UInt8 fColor; /// @brief Color of the node. (Red or Black). - Lba fNext, fPrev, fChild, fParent; /// @brief Red-black tree pointers. - - Char fPad[285]; -}; -} // namespace Kernel - -namespace Kernel::Detail { -/// @brief OpenHeFS get year from ATime. -/// @param raw_atime the raw ATime value. -/// @return the year value. -/// @note The year is stored in the upper 32 bits of the ATime value. -inline UInt32 hefs_year_get(ATime raw_atime) { - return (raw_atime) >> 32; -} - -/// @brief OpenHeFS get month from ATime. -/// @param raw_atime the raw ATime value. -/// @return the month value. -/// @note The month is stored in the upper 24 bits of the ATime value. -inline UInt32 hefs_month_get(ATime raw_atime) { - return (raw_atime) >> 24; -} - -/// @brief OpenHeFS get day from ATime. -/// @param raw_atime the raw ATime value. -/// @return the day value. -/// @note The day is stored in the upper 16 bits of the ATime value. -inline UInt32 hefs_day_get(ATime raw_atime) { - return (raw_atime) >> 16; -} - -/// @brief OpenHeFS get hour from ATime. -/// @param raw_atime the raw ATime value. -/// @return the hour value. -/// @note The hour is stored in the upper 8 bits of the ATime value. -inline UInt32 hefs_hour_get(ATime raw_atime) { - return (raw_atime) >> 8; -} - -/// @brief OpenHeFS get minute from ATime. -/// @param raw_atime the raw ATime value. -/// @return the minute value. -/// @note The minute is stored in the lower 8 bits of the ATime value. -inline UInt32 hefs_minute_get(ATime raw_atime) { - return (raw_atime) & 0xFF; -} - -inline constexpr UInt32 kOpenHeFSBaseYear = 1970; -inline constexpr UInt32 kOpenHeFSBaseMonth = 1; -inline constexpr UInt32 kOpenHeFSBaseDay = 1; -inline constexpr UInt32 kOpenHeFSBaseHour = 0; -inline constexpr UInt32 kOpenHeFSBaseMinute = 0; - -inline const Char* hefs_status_to_string(UInt16 status) { - switch (status) { - case kOpenHeFSStatusUnlocked: - return "Unlocked"; - case kOpenHeFSStatusLocked: - return "Locked"; - case kOpenHeFSStatusError: - return "Error"; - case kOpenHeFSStatusInvalid: - return "Invalid"; - default: - return "Unknown"; - } -} - -inline const Char* hefs_drive_kind_to_string(UInt8 kind) { - switch (kind) { - case kOpenHeFSHardDrive: - return "Hard Drive"; - case kOpenHeFSSolidStateDrive: - return "Solid State Drive"; - case kOpenHeFSOpticalDrive: - return "Optical Drive"; - case kOpenHeFSMassStorageDevice: - return "Mass Storage Device"; - case kOpenHeFSScsiDrive: - return "SCSI/SAS Drive"; - case kOpenHeFSFlashDrive: - return "Flash Drive"; - case kOpenHeFSUnknown: - default: - return "Unknown"; - } -} - -inline const Char* hefs_encoding_to_string(UInt8 encoding) { - switch (encoding) { - case kOpenHeFSEncodingFlagsUTF8: - return "UTF-8"; - case kOpenHeFSEncodingFlagsUTF16: - return "UTF-16"; - case kOpenHeFSEncodingFlagsUTF32: - return "UTF-32"; - case kOpenHeFSEncodingFlagsUTF16BE: - return "UTF-16BE"; - case kOpenHeFSEncodingFlagsUTF16LE: - return "UTF-16LE"; - case kOpenHeFSEncodingFlagsUTF32BE: - return "UTF-32BE"; - case kOpenHeFSEncodingFlagsUTF32LE: - return "UTF-32LE"; - case kOpenHeFSEncodingFlagsUTF8BE: - return "UTF-8BE"; - case kOpenHeFSEncodingFlagsUTF8LE: - return "UTF-8LE"; - default: - return "Unknown"; - } -} - -inline const Char* hefs_file_kind_to_string(UInt16 kind) { - switch (kind) { - case kOpenHeFSFileKindRegular: - return "Regular File"; - case kOpenHeFSFileKindDirectory: - return "Directory"; - case kOpenHeFSFileKindBlock: - return "Block Device"; - case kOpenHeFSFileKindCharacter: - return "Character Device"; - case kOpenHeFSFileKindFIFO: - return "FIFO"; - case kOpenHeFSFileKindSocket: - return "Socket"; - case kOpenHeFSFileKindSymbolicLink: - return "Symbolic Link"; - case kOpenHeFSFileKindUnknown: - default: - return "Unknown"; - } -} - -inline const Char* hefs_file_flags_to_string(UInt32 flags) { - switch (flags) { - case kOpenHeFSFlagsNone: - return "No Flags"; - case kOpenHeFSFlagsReadOnly: - return "Read Only"; - case kOpenHeFSFlagsHidden: - return "Hidden"; - case kOpenHeFSFlagsSystem: - return "System"; - case kOpenHeFSFlagsArchive: - return "Archive"; - case kOpenHeFSFlagsDevice: - return "Device"; - default: - return "Unknown"; - } -} -} // namespace Kernel::Detail - -namespace Kernel { -/// @brief OpenHeFS filesystem parser class. -/// @details This class is used to parse the OpenHeFS filesystem. -class HeFileSystemParser final { - public: - HeFileSystemParser() = default; - ~HeFileSystemParser() = default; - - public: - HeFileSystemParser(const HeFileSystemParser&) = delete; - HeFileSystemParser& operator=(const HeFileSystemParser&) = delete; - - HeFileSystemParser(HeFileSystemParser&&) = delete; - HeFileSystemParser& operator=(HeFileSystemParser&&) = delete; - - public: - /// @brief Make a EPM+OpenHeFS drive out of the disk. - /// @param drive The drive to write on. - /// @return If it was sucessful, see err_local_get(). - _Output Bool Format(_Input _Output DriveTrait* drive, _Input const Int32 flags, - const Utf8Char* part_name); - - _Output Bool CreateINodeDirectory(_Input DriveTrait* drive, _Input const Int32 flags, - const Utf8Char* dir); - - _Output Bool RemoveINodeDirectory(_Input DriveTrait* drive, _Input const Int32 flags, - const Utf8Char* dir); - - _Output Bool CreateINode(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir, - const Utf8Char* name, const UInt8 kind); - - _Output Bool DeleteINode(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir, - const Utf8Char* name, const UInt8 kind); - - _Output Bool INodeManip(_Input DriveTrait* drive, VoidPtr block, SizeT block_sz, - const Utf8Char* dir, const Utf8Char* name, const UInt8 kind, - const BOOL input); - - private: - _Output Bool INodeCtlManip(_Input DriveTrait* drive, _Input const Int32 flags, - const Utf8Char* dir, const Utf8Char* name, const BOOL delete_or_create, - const UInt8 kind); - - _Output Bool INodeDirectoryCtlManip(_Input DriveTrait* drive, _Input const Int32 flags, - const Utf8Char* dir, const BOOL delete_or_create); -}; - -namespace OpenHeFS { - - /// @brief Initialize OpenHeFS inside the main disk. - /// @return Whether it successfuly formated it or not. - Boolean fs_init_openhefs(Void); -} // namespace OpenHeFS -} // namespace Kernel +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#ifndef FSKIT_OPENHEFS_H +#define FSKIT_OPENHEFS_H + +#include +#include +#include +#include +#include +#include +#include + +/// @file OpenHeFS.h +/// @brief OpenHeFS filesystem support. + +#define kOpenHeFSVersion (0x0104) +#define kOpenHeFSMagic "OpenHeFS" +#define kOpenHeFSMagicLen (9U) + +#define kOpenHeFSBlockLen (512U) +#define kOpenHeFSFileNameLen (256U) +#define kOpenHeFSPartNameLen (128U) + +#define kOpenHeFSMinimumDiskSize (gib_cast(128)) + +#define kOpenHeFSDefaultVolumeName u8"OpenHeFS Volume" + +#define kOpenHeFSINDStartOffset (sizeof(HEFS_BOOT_NODE)) +#define kOpenHeFSINStartOffset (sizeof(HEFS_INDEX_NODE_DIRECTORY)) + +#define kOpenHeFSRootDirectory "/" +#define kOpenHeFSRootDirectoryU8 u8"/" + +#define kOpenHeFSSeparator '/' +#define kOpenHeFSUpDir ".." + +#define kOpenHeFSRootDirectoryLen (2U) + +#define kOpenHeFSSearchAllStr u8"*" + +struct HEFS_BOOT_NODE; +struct HEFS_INDEX_NODE; +struct HEFS_INDEX_NODE_DIRECTORY; +struct HEFS_JOURNAL_NODE; + +enum : UInt8 { + kOpenHeFSHardDrive = 0xC0, // Hard Drive + kOpenHeFSSolidStateDrive = 0xC1, // Solid State Drive + kOpenHeFSOpticalDrive = 0x0C, // Blu-Ray/DVD + kOpenHeFSMassStorageDevice = 0xCC, // USB + kOpenHeFSScsiDrive = 0xC4, // SCSI Hard Drive + kOpenHeFSFlashDrive = 0xC6, + kOpenHeFSUnknown = 0xFF, // Unknown device. + kOpenHeFSDriveCount = 8, +}; + +enum : UInt8 { + kOpenHeFSStatusUnlocked = 0x18, + kOpenHeFSStatusLocked, + kOpenHeFSStatusError, + kOpenHeFSStatusInvalid, + kOpenHeFSStatusCount, +}; + +enum : UInt16 { + kOpenHeFSEncodingFlagsUTF8 = 0x50, + kOpenHeFSEncodingFlagsUTF16, + kOpenHeFSEncodingFlagsUTF32, + kOpenHeFSEncodingFlagsUTF16BE, + kOpenHeFSEncodingFlagsUTF16LE, + kOpenHeFSEncodingFlagsUTF32BE, + kOpenHeFSEncodingFlagsUTF32LE, + kOpenHeFSEncodingFlagsUTF8BE, + kOpenHeFSEncodingFlagsUTF8LE, + kOpenHeFSEncodingFlagsBinary, + kOpenHeFSEncodingFlagsCount = 11, + kOpenHeFSFlagsNone = 0, + kOpenHeFSFlagsReadOnly = 0x100, + kOpenHeFSFlagsHidden, + kOpenHeFSFlagsSystem, + kOpenHeFSFlagsArchive, + kOpenHeFSFlagsDevice, + kOpenHeFSFlagsCount = 7 +}; + +inline constexpr UInt16 kOpenHeFSFileKindRegular = 0x00; +inline constexpr UInt16 kOpenHeFSFileKindDirectory = 0x01; +inline constexpr UInt16 kOpenHeFSFileKindBlock = 0x02; +inline constexpr UInt16 kOpenHeFSFileKindCharacter = 0x03; +inline constexpr UInt16 kOpenHeFSFileKindFIFO = 0x04; +inline constexpr UInt16 kOpenHeFSFileKindSocket = 0x05; +inline constexpr UInt16 kOpenHeFSFileKindSymbolicLink = 0x06; +inline constexpr UInt16 kOpenHeFSFileKindUnknown = 0x07; +inline constexpr UInt16 kOpenHeFSFileKindCount = 0x08; + +/// @brief OpenHeFS blocks are array containing sparse blocks of data. +/// @details The blocks are used to store the data of a file. Each block is a pointer to a block of +/// data on the disk. +inline constexpr UInt16 kOpenHeFSSliceCount = 0x10; + +inline constexpr UInt16 kOpenHeFSInvalidVID = 0xFFFF; + +namespace Kernel { +/// @brief Access time type. +/// @details Used to keep track of the INode, INodeDir allocation status. +typedef UInt64 ATime; + +/// @brief OpenHeFS Boot node. +/// @details Acts like a superblock, it contains the information about the filesystem. +/// @note The boot node is the first block of the filesystem. +struct PACKED HEFS_BOOT_NODE final { + Char fMagic[kOpenHeFSMagicLen]; /// @brief Magic number of the filesystem. + Utf8Char fVolName[kOpenHeFSPartNameLen]; /// @brief Volume name. + UInt32 fVersion; /// @brief Version of the filesystem. + UInt64 fBadSectors; /// @brief Number of bad sectors in the filesystem. + UInt64 fSectorCount; /// @brief Number of sectors in the filesystem. + UInt64 fSectorSize; /// @brief Size of the sector. + UInt32 fChecksum; /// @brief Checksum of the boot node. + UInt8 fDiskKind; /// @brief Kind of the drive. (Hard Drive, Solid State Drive, Optical + /// Drive, etc). + UInt8 fEncoding; /// @brief Encoding of the filesystem. (UTF-8, UTF-16, etc). + UInt64 fStartIND; /// @brief Start of the INode directory tree. + UInt64 fEndIND; /// @brief End of the INode directory tree. + UInt64 fINDCount; /// @brief Number of leafs in the INode tree. + UInt64 fDiskSize; /// @brief Size of the disk. (Could be a virtual size, that is not the + /// real size of the disk.) + UInt16 fDiskStatus; /// @brief Status of the disk. (locked, unlocked, error, invalid). + UInt16 fDiskFlags; /// @brief Flags of the disk. (read-only, read-write, etc). + UInt16 fVID; /// @brief Virtual Identification Number within an EPM disk. (0xFFFF if not used). + UInt64 fStartIN; /// @brief Start INodes range + UInt64 fEndIN; /// @brief End INodes range + UInt64 fStartBlock; /// @brief Start Blocks range + UInt64 fEndBlock; /// @brief End Blocks range + UInt64 fJournalLBA; /// @brief Boot Node's COW journal LBA. + Char fPad[264]; +}; + +inline constexpr ATime kOpenHeFSTimeInvalid = 0x0000000000000000; +inline constexpr ATime kOpenHeFSTimeMax = 0xFFFFFFFFFFFFFFFF - 1; + +/// @brief Journal Node structure +/// @param fHashPath target hash path +/// @param fStatus target status +/// @param fCopyElem copy of element +/// @param fCopyKind kind of element +struct PACKED HEFS_JOURNAL_NODE { + UInt64 fHashPath; + UInt64 fStatus; + UInt64 fCopyElem; + UInt8 fCopyKind; + UInt8 fPad[487]; +}; + +/// @brief This enum defines the opcode of the journal, here mentioned as 'kinds' +enum HeFSJournalKind : UInt8 { + kJournalKindInvalid = 0x00, + kJournalKindWrite = 0x01, + kJournalKindRename = 0x02, + kJournalKindDelete = 0x03, + kJournalKindFlagEdit = 0x04, + kJournalKindCreate = 0x05, + kJournalKindCount, +}; + +/// @brief OpenHeFS index node. +/// @details This structure is used to store the file information of a file. +/// @note The index node is a special type of INode that contains the file information. +/// @note The index node is used to store the file information of a file. +struct PACKED HEFS_INDEX_NODE final { + UInt64 fHashPath; /// @brief File name. + UInt32 fFlags; /// @brief File flags. + UInt16 fKind; /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket, + /// Symbolic Link, Unknown). + UInt32 fSize; /// @brief File size. + UInt32 fChecksum; /// @brief Checksum. + + Boolean fSymLink; /// @brief Is this a symbolic link? (if yes, the fName is the path to + /// the file and blocklinkstart and end contains it's inodes.) + + ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps. + UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. + UInt32 fMode; /// @brief File mode. (read, write, execute, etc). + + /// @brief Extents system by using blocks + /// @details Using an offset to ask fBase, and fLength to compute each slice's length. + UInt32 fOffsetSliceLow; + UInt32 fOffsetSliceHigh; + + Char fPad[437]; +}; + +enum { + kOpenHeFSInvalidColor = 0, + kOpenHeFSRed = 100, + kOpenHeFSBlack, + kOpenHeFSColorCount, +}; + +/// @brief OpenHeFS directory node. +/// @details This structure is used to store the directory information of a file. +/// @note The directory node is a special type of INode that contains the directory entries. +struct PACKED HEFS_INDEX_NODE_DIRECTORY final { + UInt64 fHashPath; /// @brief Directory path as FNV hash. + + UInt32 fFlags; /// @brief File flags. + UInt16 fReserved; /// @note Reserved for future use. + UInt32 fEntryCount; /// @brief Entry Count of this directory inode. + UInt32 fChecksum; /// @brief Checksum of the file, index node checksum. + + ATime fCreated, fAccessed, fModified, + fDeleted; /// @brief File timestamps and allocation status. + UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. + UInt32 fMode; /// @brief File mode. (read, write, execute, etc). + + /// @note These slices are organized as: + /// [0] = OFFSET + /// [1] = SIZE + /// @note Thus the += 2 when iterating over them. + UInt64 fINSlices[kOpenHeFSSliceCount]; /// @brief Start of the index node. + + UInt8 fColor; /// @brief Color of the node. (Red or Black). + Lba fNext, fPrev, fChild, fParent; /// @brief Red-black tree pointers. + + Char fPad[285]; +}; +} // namespace Kernel + +namespace Kernel::Detail { +/// @brief OpenHeFS get year from ATime. +/// @param raw_atime the raw ATime value. +/// @return the year value. +/// @note The year is stored in the upper 32 bits of the ATime value. +inline UInt32 hefs_year_get(ATime raw_atime) { + return (raw_atime) >> 32; +} + +/// @brief OpenHeFS get month from ATime. +/// @param raw_atime the raw ATime value. +/// @return the month value. +/// @note The month is stored in the upper 24 bits of the ATime value. +inline UInt32 hefs_month_get(ATime raw_atime) { + return (raw_atime) >> 24; +} + +/// @brief OpenHeFS get day from ATime. +/// @param raw_atime the raw ATime value. +/// @return the day value. +/// @note The day is stored in the upper 16 bits of the ATime value. +inline UInt32 hefs_day_get(ATime raw_atime) { + return (raw_atime) >> 16; +} + +/// @brief OpenHeFS get hour from ATime. +/// @param raw_atime the raw ATime value. +/// @return the hour value. +/// @note The hour is stored in the upper 8 bits of the ATime value. +inline UInt32 hefs_hour_get(ATime raw_atime) { + return (raw_atime) >> 8; +} + +/// @brief OpenHeFS get minute from ATime. +/// @param raw_atime the raw ATime value. +/// @return the minute value. +/// @note The minute is stored in the lower 8 bits of the ATime value. +inline UInt32 hefs_minute_get(ATime raw_atime) { + return (raw_atime) & 0xFF; +} + +inline constexpr UInt32 kOpenHeFSBaseYear = 1970; +inline constexpr UInt32 kOpenHeFSBaseMonth = 1; +inline constexpr UInt32 kOpenHeFSBaseDay = 1; +inline constexpr UInt32 kOpenHeFSBaseHour = 0; +inline constexpr UInt32 kOpenHeFSBaseMinute = 0; + +inline const Char* hefs_status_to_string(UInt16 status) { + switch (status) { + case kOpenHeFSStatusUnlocked: + return "Unlocked"; + case kOpenHeFSStatusLocked: + return "Locked"; + case kOpenHeFSStatusError: + return "Error"; + case kOpenHeFSStatusInvalid: + return "Invalid"; + default: + return "Unknown"; + } +} + +inline const Char* hefs_drive_kind_to_string(UInt8 kind) { + switch (kind) { + case kOpenHeFSHardDrive: + return "Hard Drive"; + case kOpenHeFSSolidStateDrive: + return "Solid State Drive"; + case kOpenHeFSOpticalDrive: + return "Optical Drive"; + case kOpenHeFSMassStorageDevice: + return "Mass Storage Device"; + case kOpenHeFSScsiDrive: + return "SCSI/SAS Drive"; + case kOpenHeFSFlashDrive: + return "Flash Drive"; + case kOpenHeFSUnknown: + default: + return "Unknown"; + } +} + +inline const Char* hefs_encoding_to_string(UInt8 encoding) { + switch (encoding) { + case kOpenHeFSEncodingFlagsUTF8: + return "UTF-8"; + case kOpenHeFSEncodingFlagsUTF16: + return "UTF-16"; + case kOpenHeFSEncodingFlagsUTF32: + return "UTF-32"; + case kOpenHeFSEncodingFlagsUTF16BE: + return "UTF-16BE"; + case kOpenHeFSEncodingFlagsUTF16LE: + return "UTF-16LE"; + case kOpenHeFSEncodingFlagsUTF32BE: + return "UTF-32BE"; + case kOpenHeFSEncodingFlagsUTF32LE: + return "UTF-32LE"; + case kOpenHeFSEncodingFlagsUTF8BE: + return "UTF-8BE"; + case kOpenHeFSEncodingFlagsUTF8LE: + return "UTF-8LE"; + default: + return "Unknown"; + } +} + +inline const Char* hefs_file_kind_to_string(UInt16 kind) { + switch (kind) { + case kOpenHeFSFileKindRegular: + return "Regular File"; + case kOpenHeFSFileKindDirectory: + return "Directory"; + case kOpenHeFSFileKindBlock: + return "Block Device"; + case kOpenHeFSFileKindCharacter: + return "Character Device"; + case kOpenHeFSFileKindFIFO: + return "FIFO"; + case kOpenHeFSFileKindSocket: + return "Socket"; + case kOpenHeFSFileKindSymbolicLink: + return "Symbolic Link"; + case kOpenHeFSFileKindUnknown: + default: + return "Unknown"; + } +} + +inline const Char* hefs_file_flags_to_string(UInt32 flags) { + switch (flags) { + case kOpenHeFSFlagsNone: + return "No Flags"; + case kOpenHeFSFlagsReadOnly: + return "Read Only"; + case kOpenHeFSFlagsHidden: + return "Hidden"; + case kOpenHeFSFlagsSystem: + return "System"; + case kOpenHeFSFlagsArchive: + return "Archive"; + case kOpenHeFSFlagsDevice: + return "Device"; + default: + return "Unknown"; + } +} +} // namespace Kernel::Detail + +namespace Kernel { +/// @brief OpenHeFS filesystem parser class. +/// @details This class is used to parse the OpenHeFS filesystem. +class HeFileSystemParser final { + public: + HeFileSystemParser() = default; + ~HeFileSystemParser() = default; + + public: + HeFileSystemParser(const HeFileSystemParser&) = delete; + HeFileSystemParser& operator=(const HeFileSystemParser&) = delete; + + HeFileSystemParser(HeFileSystemParser&&) = delete; + HeFileSystemParser& operator=(HeFileSystemParser&&) = delete; + + public: + /// @brief Make a EPM+OpenHeFS drive out of the disk. + /// @param drive The drive to write on. + /// @return If it was sucessful, see err_local_get(). + _Output Bool Format(_Input _Output DriveTrait* drive, _Input const Int32 flags, + const Utf8Char* part_name); + + _Output Bool CreateINodeDirectory(_Input DriveTrait* drive, _Input const Int32 flags, + const Utf8Char* dir); + + _Output Bool RemoveINodeDirectory(_Input DriveTrait* drive, _Input const Int32 flags, + const Utf8Char* dir); + + _Output Bool CreateINode(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir, + const Utf8Char* name, const UInt8 kind); + + _Output Bool DeleteINode(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir, + const Utf8Char* name, const UInt8 kind); + + _Output Bool INodeManip(_Input DriveTrait* drive, VoidPtr block, SizeT block_sz, + const Utf8Char* dir, const Utf8Char* name, const UInt8 kind, + const BOOL input); + + private: + _Output Bool INodeCtlManip(_Input DriveTrait* drive, _Input const Int32 flags, + const Utf8Char* dir, const Utf8Char* name, const BOOL delete_or_create, + const UInt8 kind); + + _Output Bool INodeDirectoryCtlManip(_Input DriveTrait* drive, _Input const Int32 flags, + const Utf8Char* dir, const BOOL delete_or_create); +}; + +namespace OpenHeFS { + + /// @brief Initialize OpenHeFS inside the main disk. + /// @return Whether it successfuly formated it or not. + Boolean fs_init_openhefs(Void); +} // namespace OpenHeFS +} // namespace Kernel + +#endif -- cgit v1.2.3