diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-04-29 10:12:36 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-04-29 10:12:36 +0200 |
| commit | 461fe537aa1f9533bfa5c2504cb84843b9eac501 (patch) | |
| tree | 271395a293f788775c09abffdc0861dbf24af4ca | |
| parent | 346558208d39a036effe3a4ec232fa5df5a3c8e7 (diff) | |
MHR-18: Filesystem fixes and improvements see ticket.
- Implement CreateCatalog for file creation, an implementation of
RemoveCatalog is also needed.
- Boot Kit only takes a single root file now. Must be ending with '/'.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
| -rw-r--r-- | Private/Builtins/AHCI/AHCI.hxx | 29 | ||||
| -rw-r--r-- | Private/FSKit/NewFS.hxx | 23 | ||||
| -rw-r--r-- | Private/HALKit/AMD64/Storage/ATA-PIO.cxx | 6 | ||||
| -rw-r--r-- | Private/KernelKit/FileManager.hpp | 4 | ||||
| -rw-r--r-- | Private/NewBoot/BootKit/BootKit.hxx | 145 | ||||
| -rw-r--r-- | Private/NewBoot/BootKit/Vendor/Support.hxx | 3 | ||||
| -rw-r--r-- | Private/NewBoot/Source/HEL/AMD64/BootMain.cxx | 52 | ||||
| -rw-r--r-- | Private/NewKit/Defines.hpp | 4 | ||||
| -rw-r--r-- | Private/Source/AppMain.cxx | 19 | ||||
| -rw-r--r-- | Private/Source/FS/NewFS.cxx | 400 | ||||
| -rw-r--r-- | Private/Source/FileManager.cxx | 44 |
11 files changed, 449 insertions, 280 deletions
diff --git a/Private/Builtins/AHCI/AHCI.hxx b/Private/Builtins/AHCI/AHCI.hxx index f5e139ac..b79299e7 100644 --- a/Private/Builtins/AHCI/AHCI.hxx +++ b/Private/Builtins/AHCI/AHCI.hxx @@ -318,27 +318,34 @@ typedef struct HbaCmdTbl final { /// @brief Initializes an AHCI disk. /// @param PortsImplemented the amount of port that have been detected. -/// @return +/// @return NewOS::Boolean drv_std_init(NewOS::UInt16& PortsImplemented); NewOS::Boolean drv_std_detected(NewOS::Void); /// @brief Read from disk. -/// @param Lba -/// @param Buf -/// @param SectorSz -/// @param Size -/// @return +/// @param Lba +/// @param Buf +/// @param SectorSz +/// @param Size +/// @return NewOS::Void drv_std_read(NewOS::UInt64 Lba, NewOS::Char* Buf, NewOS::SizeT SectorSz, NewOS::SizeT Size); /// @brief Write to disk. -/// @param Lba -/// @param Buf -/// @param SectorSz -/// @param Size -/// @return +/// @param Lba +/// @param Buf +/// @param SectorSz +/// @param Size +/// @return NewOS::Void drv_std_write(NewOS::UInt64 Lba, NewOS::Char* Buf, NewOS::SizeT SectorSz, NewOS::SizeT Size); +/// @brief get sector count. +NewOS::SizeT drv_std_get_sector_count(); + +/// @brief get device size. +NewOS::SizeT drv_std_get_drv_size(); + + #endif // ifdef __KERNEL__ diff --git a/Private/FSKit/NewFS.hxx b/Private/FSKit/NewFS.hxx index 2a783b11..619c6c6b 100644 --- a/Private/FSKit/NewFS.hxx +++ b/Private/FSKit/NewFS.hxx @@ -38,13 +38,13 @@ default. #define kNewFSIdentLen 8 #define kNewFSIdent " NewFS" -#define kNewFSPadLen 408 +#define kNewFSPadLen 400 /// @brief Partition GUID on EPM and GPT disks. #define kNewFSUUID "@{DD997393-9CCE-4288-A8D5-C0FDE3908DBE}" -#define kNewFSVersionInteger 0x122 -#define kNewFSVerionString "1.2.2" +#define kNewFSVersionInteger 0x123 +#define kNewFSVerionString "1.23" /// @brief Standard fork types. #define kNewFSDataFork "data" @@ -83,7 +83,7 @@ default. /// Start After the PM headers, pad 1024 bytes. #define kNewFSAddressAsLba (512) -#define kNewFSCatalogStartAddress (1024 + sizeof(NewPartitionBlock)) +#define kNewFSCatalogStartAddress (1024 + sizeof(NewPartitionBlock) + sizeof(NewCatalog)) #define kResourceTypeDialog 10 #define kResourceTypeString 11 @@ -96,7 +96,7 @@ default. #define kNewFSFlagUnallocated 0x00 #define kNewFSFlagCreated 0x0F -#define kNewFSMimeNameLen (216) +#define kNewFSMimeNameLen (200) typedef NewOS::Char NewCharType; @@ -117,6 +117,12 @@ struct PACKED NewCatalog final { NewOS::Int32 Flags; NewOS::Int32 Kind; + /// Size of the data fork. + NewOS::Lba DataForkSize; + + /// Size of all resource forks. + NewOS::Lba ResourceForkOverallSize; + NewOS::Lba DataFork; NewOS::Lba ResourceFork; @@ -164,6 +170,8 @@ struct PACKED NewPartitionBlock final { NewOS::SizeT SectorCount; NewOS::SizeT SectorSize; + NewOS::UInt64 Version; + NewOS::Char Pad[kNewFSPadLen]; }; @@ -214,7 +222,7 @@ class NewFSParser final { _Output Void CloseFork(_Input NewFork* fork); - _Output NewCatalog* FindCatalog(_Input const char* catalogName); + _Output NewCatalog* FindCatalog(_Input const char* catalogName, Lba& outLba); _Output NewCatalog* GetCatalog(_Input const char* name); @@ -224,7 +232,8 @@ class NewFSParser final { _Output NewCatalog* CreateCatalog(_Input const char* name); - bool WriteCatalog(_Input _Output NewCatalog* catalog, voidPtr data); + bool WriteCatalog(_Input _Output NewCatalog* catalog, + voidPtr data, SizeT sizeOfData); VoidPtr ReadCatalog(_Input _Output NewCatalog* catalog, SizeT dataSz); diff --git a/Private/HALKit/AMD64/Storage/ATA-PIO.cxx b/Private/HALKit/AMD64/Storage/ATA-PIO.cxx index 6fe1e29a..9b37e248 100644 --- a/Private/HALKit/AMD64/Storage/ATA-PIO.cxx +++ b/Private/HALKit/AMD64/Storage/ATA-PIO.cxx @@ -106,7 +106,8 @@ Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, Out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - Out8(IO + ATA_REG_SEC_COUNT0, 2); + /// Compute sector count. + Out8(IO + ATA_REG_SEC_COUNT0, SectorSz / (SectorSz / 2)); Out8(IO + ATA_REG_LBA0, (Lba)); Out8(IO + ATA_REG_LBA1, (Lba) >> 8); @@ -133,9 +134,10 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, drv_std_wait_io(IO); drv_std_select(IO); + /// Compute sector count. Out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - Out8(IO + ATA_REG_SEC_COUNT0, 2); + Out8(IO + ATA_REG_SEC_COUNT0, SectorSz / (SectorSz / 2)); Out8(IO + ATA_REG_LBA0, (Lba)); Out8(IO + ATA_REG_LBA1, (Lba) >> 8); diff --git a/Private/KernelKit/FileManager.hpp b/Private/KernelKit/FileManager.hpp index 603ee06b..ab65bbe1 100644 --- a/Private/KernelKit/FileManager.hpp +++ b/Private/KernelKit/FileManager.hpp @@ -86,7 +86,7 @@ class FilesystemManagerInterface { public: virtual Void Write(_Input NodePtr node, _Input VoidPtr data, - _Input Int32 flags) = 0; + _Input Int32 flags, _Input SizeT size) = 0; virtual _Output VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) = 0; @@ -122,7 +122,7 @@ class NewFilesystemManager final : public FilesystemManagerInterface { public: bool Remove(const char *path) override; NodePtr Open(const char *path, const char *r) override; - Void Write(NodePtr node, VoidPtr data, Int32 flags) override; + Void Write(NodePtr node, VoidPtr data, Int32 flags, SizeT sz) override; VoidPtr Read(NodePtr node, Int32 flags, SizeT sz) override; bool Seek(NodePtr node, SizeT off); SizeT Tell(NodePtr node) override; diff --git a/Private/NewBoot/BootKit/BootKit.hxx b/Private/NewBoot/BootKit/BootKit.hxx index c3e438ae..47a8c9a2 100644 --- a/Private/NewBoot/BootKit/BootKit.hxx +++ b/Private/NewBoot/BootKit/BootKit.hxx @@ -186,16 +186,9 @@ public: Char fForkName[kNewFSNodeNameLen]; Int32 fKind; - Int64 fLba; VoidPtr fBlob; SizeT fBlobSz; - - bool IsCatalogValid() { return fLba != 0 && fLba >= kNewFSCatalogStartAddress; } - - struct BFileDescriptor* fParent; - struct BFileDescriptor* fPrev; - struct BFileDescriptor* fNext; }; public: @@ -236,7 +229,8 @@ public: if (blockPart->DiskSize != this->fDiskDev.GetDiskSize() || blockPart->DiskSize < 1 || - blockPart->SectorSize != BootDev::kSectorSize) { + blockPart->SectorSize != BootDev::kSectorSize || + blockPart->Version != kNewFSVersionInteger) { EFI::ThrowError(L"Invalid-Disk-Geometry", L"Invalid disk geometry."); } else if (blockPart->PartitionName[0] == 0) { EFI::ThrowError(L"Invalid-Partition-Name", L"Invalid disk partition."); @@ -263,103 +257,95 @@ private: Char bufCatalog[sizeof(NewCatalog)] = { 0 }; Char bufFork[sizeof(NewFork)] = { 0 }; - while (blob) { - NewCatalog* catalogKind = (NewCatalog*)bufCatalog; - - blob->fLba = startLba; - - if (!blob->fParent) - catalogKind->PrevSibling = startLba; - else { - if (blob->IsCatalogValid()) { - catalogKind->PrevSibling = blob->fParent->fLba; - } else { - EFI::ThrowError(L"Invalid-Catalog-Location", L"Invalid catalog location."); - } - } - - /// Fill catalog kind. - catalogKind->Kind = blob->fKind; + NewCatalog* catalogKind = (NewCatalog*)bufCatalog; + catalogKind->PrevSibling = startLba; + catalogKind->NextSibling = (sizeof(NewCatalog) + sizeof(NewFork) + blob->fBlobSz); - /// Allocate fork for blob. - if (catalogKind->Kind == kNewFSDataForkKind) { - catalogKind->DataFork = (startLba + sizeof(NewCatalog)); - } else { - catalogKind->ResourceFork = (startLba + sizeof(NewCatalog)); - } + /// Fill catalog kind. + catalogKind->Kind = blob->fKind; - NewFork* forkKind = (NewFork*)bufFork; + /// Allocate fork for blob. + if (catalogKind->Kind == kNewFSDataForkKind) { + catalogKind->DataFork = (startLba + sizeof(NewCatalog)); + catalogKind->DataForkSize += blob->fBlobSz; + } else { + catalogKind->ResourceFork = (startLba + sizeof(NewCatalog)); + catalogKind->ResourceForkOverallSize += blob->fBlobSz; + } - memcpy(forkKind->Name, blob->fForkName, strlen(blob->fForkName)); - forkKind->Kind = (forkKind->Name[0] == kNewFSDataFork[0]) ? kNewFSDataForkKind : kNewFSRsrcForkKind; - forkKind->Flags = kNewFSFlagCreated; + /// before going to forks, we must check for the catalog name first. + if (blob->fKind == kNewFSCatalogKindDir && + blob->fFileName[strlen(blob->fFileName) - 1] != '/') { + EFI::ThrowError(L"Developer-Error", L"This is caused by the developer of the bootloader."); + } - /// We don't know. - forkKind->ResourceFlags = 0; - forkKind->ResourceId = 0; - forkKind->ResourceKind = 0; + NewFork* forkKind = (NewFork*)bufFork; - /// We're the only fork here. - forkKind->NextSibling = forkKind->Kind == kNewFSDataForkKind ? catalogKind->DataFork : catalogKind->ResourceFork; - forkKind->PreviousSibling = kNewFSDataForkKind ? catalogKind->DataFork : catalogKind->ResourceFork; + memcpy(forkKind->Name, blob->fForkName, strlen(blob->fForkName)); + forkKind->Kind = (forkKind->Name[0] == kNewFSDataFork[0]) ? kNewFSDataForkKind : kNewFSRsrcForkKind; + forkKind->Flags = kNewFSFlagCreated; - forkKind->DataOffset = (startLba + sizeof(NewCatalog) + sizeof(NewFork)); - forkKind->DataSize = blob->fBlobSz; + /// We don't know. + forkKind->ResourceFlags = 0; + forkKind->ResourceId = 0; + forkKind->ResourceKind = 0; - SizeT cur = 0UL; + /// We're the only fork here. + forkKind->NextSibling = forkKind->Kind == kNewFSDataForkKind ? catalogKind->DataFork : catalogKind->ResourceFork; + forkKind->PreviousSibling = kNewFSDataForkKind ? catalogKind->DataFork : catalogKind->ResourceFork; - writer.Write((catalogKind->Kind == kNewFSCatalogKindFile) ? L"New Boot: Write-File: " : - L"New Boot: Write-Directory: " ).Write(blob->fFileName).Write(L"\r\n"); + forkKind->DataOffset = (startLba + sizeof(NewCatalog) + sizeof(NewFork)); + forkKind->DataSize = blob->fBlobSz; - /// Set disk cursor here. + SizeT cur = 0UL; - fDiskDev.Leak().mBase = startLba + sizeof(NewCatalog); - fDiskDev.Leak().mSize = sizeof(NewFork); + writer.Write((catalogKind->Kind == kNewFSCatalogKindFile) ? L"New Boot: Write-File: " : + L"New Boot: Write-Directory: " ).Write(blob->fFileName).Write(L"\r\n"); - fDiskDev.Write((Char*)bufFork, sizeof(NewFork)); + /// Set disk cursor here. - do { - this->fDiskDev.Leak().mSize = BootDev::kSectorSize; - this->fDiskDev.Leak().mBase = (forkKind->DataOffset + cur); + fDiskDev.Leak().mBase = startLba + sizeof(NewCatalog); + fDiskDev.Leak().mSize = sizeof(NewFork); - this->fDiskDev.Write((Char*)(blob->fBlob) + cur, BootDev::kSectorSize); + fDiskDev.Write((Char*)bufFork, sizeof(NewFork)); - cur += BootDev::kSectorSize; - } while (cur < forkKind->DataSize); + do { + this->fDiskDev.Leak().mSize = BootDev::kSectorSize; + this->fDiskDev.Leak().mBase = (forkKind->DataOffset + cur); - /// Fork is done. + this->fDiskDev.Write((Char*)(blob->fBlob) + cur, BootDev::kSectorSize); - catalogKind->Kind = blob->fKind; - catalogKind->Flags |= kNewFSFlagCreated; + cur += BootDev::kSectorSize; + } while (cur < forkKind->DataSize); - //// Now write catalog as well.. + /// Fork is done. - /// this mime only applies to file. - if (catalogKind->Kind == kNewFSCatalogKindFile) { - memcpy(catalogKind->Mime, kBKBootFileMime, strlen(kBKBootFileMime)); - } else { - memcpy(catalogKind->Mime, kBKBootDirMime, strlen(kBKBootDirMime)); - } + catalogKind->Kind = blob->fKind; + catalogKind->Flags = kNewFSFlagCreated; - memcpy(catalogKind->Name, blob->fFileName, strlen(blob->fFileName)); + //// Now write catalog as well.. - catalogKind->NextSibling = startLba + (sizeof(NewCatalog) + sizeof(NewFork) + blob->fBlobSz); + /// this mime only applies to file. + if (catalogKind->Kind == kNewFSCatalogKindFile) { + memcpy(catalogKind->Mime, kBKBootFileMime, strlen(kBKBootFileMime)); + } else { + memcpy(catalogKind->Mime, kBKBootDirMime, strlen(kBKBootDirMime)); + } - fDiskDev.Leak().mBase = startLba; - fDiskDev.Leak().mSize = sizeof(NewCatalog); + memcpy(catalogKind->Name, blob->fFileName, strlen(blob->fFileName)); - fDiskDev.Write((Char*)bufCatalog, sizeof(NewCatalog)); + fDiskDev.Leak().mBase = startLba; + fDiskDev.Leak().mSize = sizeof(NewCatalog); - startLba += (sizeof(NewCatalog) + sizeof(NewFork) + blob->fBlobSz); + fDiskDev.Write((Char*)bufCatalog, sizeof(NewCatalog)); - --partBlock.FreeCatalog; - --partBlock.FreeSectors; + startLba += (sizeof(NewCatalog) + sizeof(NewFork) + blob->fBlobSz); - memset(bufFork, 0, sizeof(NewFork)); - memset(bufCatalog, 0, sizeof(NewCatalog)); + --partBlock.FreeCatalog; + --partBlock.FreeSectors; - blob = blob->fNext; - } + memset(bufFork, 0, sizeof(NewFork)); + memset(bufCatalog, 0, sizeof(NewCatalog)); return true; } @@ -391,6 +377,7 @@ inline Boolean BDiskFormatFactory<BootDev>::Format(const char* partName, /// @note A catalog roughly equal to a sector. + partBlock->Version = kNewFSVersionInteger; partBlock->CatalogCount = blobCount; partBlock->Kind = kNewFSHardDrive; partBlock->SectorSize = sectorSz; diff --git a/Private/NewBoot/BootKit/Vendor/Support.hxx b/Private/NewBoot/BootKit/Vendor/Support.hxx index b4ba4f68..fe3d35c3 100644 --- a/Private/NewBoot/BootKit/Vendor/Support.hxx +++ b/Private/NewBoot/BootKit/Vendor/Support.hxx @@ -15,7 +15,8 @@ #define SetMem(dst, c, sz) memset(dst, c, sz) #define MoveMem(dst, src, sz) memcpy(dst, src, sz) -#define CopyMem(dst, src, sz) memcpy(dst,src, sz) +#define CopyMem(dst, src, sz) memcpy(dst, src, sz) +#define StrLen(src) strlen(src) inline int isspace(int c) { return c == ' '; } diff --git a/Private/NewBoot/Source/HEL/AMD64/BootMain.cxx b/Private/NewBoot/Source/HEL/AMD64/BootMain.cxx index 2939c182..96999df8 100644 --- a/Private/NewBoot/Source/HEL/AMD64/BootMain.cxx +++ b/Private/NewBoot/Source/HEL/AMD64/BootMain.cxx @@ -168,61 +168,19 @@ EFI_EXTERN_C EFI_API Int Main(EfiHandlePtr ImageHandle, if (!diskFormatter.IsPartitionValid()) { BDiskFormatFactory<BootDeviceATA>::BFileDescriptor rootDesc{0}; - memcpy(rootDesc.fFileName, "/", strlen("/")); - memcpy(rootDesc.fForkName, kNewFSResourceFork, strlen(kNewFSResourceFork)); + CopyMem(rootDesc.fFileName, "/", StrLen("/")); + CopyMem(rootDesc.fForkName, kNewFSResourceFork, StrLen(kNewFSResourceFork)); rootDesc.fBlobSz = BootDeviceATA::kSectorSize; rootDesc.fBlob = new Char[rootDesc.fBlobSz]; - rootDesc.fParent = &rootDesc; - memset(rootDesc.fBlob, 0, rootDesc.fBlobSz); - - memcpy(rootDesc.fBlob, kMachineModel " startup disk.", + SetMem(rootDesc.fBlob, 0, rootDesc.fBlobSz); + CopyMem(rootDesc.fBlob, kMachineModel " startup disk.", strlen(kMachineModel " startup disk.")); rootDesc.fKind = kNewFSCatalogKindDir; - BDiskFormatFactory<BootDeviceATA>::BFileDescriptor bootDesc{0}; - - bootDesc.fKind = kNewFSCatalogKindDir; - - memcpy(bootDesc.fFileName, "/Boot", strlen("/Boot")); - memcpy(bootDesc.fForkName, kNewFSResourceFork, strlen(kNewFSResourceFork)); - - bootDesc.fBlobSz = BootDeviceATA::kSectorSize; - bootDesc.fBlob = new Char[bootDesc.fBlobSz]; - bootDesc.fParent = &rootDesc; - - memset(bootDesc.fBlob, 0, bootDesc.fBlobSz); - - memcpy(bootDesc.fBlob, kMachineModel " startup folder.", - strlen(kMachineModel " startup folder.")); - - rootDesc.fNext = &bootDesc; - rootDesc.fNext->fPrev = nullptr; - - BDiskFormatFactory<BootDeviceATA>::BFileDescriptor appDesc{0}; - - appDesc.fKind = kNewFSCatalogKindDir; - - memcpy(appDesc.fFileName, "/Applications", strlen("/Applications")); - memcpy(appDesc.fForkName, kNewFSResourceFork, strlen(kNewFSResourceFork)); - - appDesc.fBlobSz = BootDeviceATA::kSectorSize; - appDesc.fBlob = new Char[appDesc.fBlobSz]; - appDesc.fParent = &rootDesc; - - memset(appDesc.fBlob, 0, appDesc.fBlobSz); - - memcpy(appDesc.fBlob, kMachineModel " applications folder.", - strlen(kMachineModel " applications folder.")); - - appDesc.fNext = nullptr; - appDesc.fNext->fPrev = &bootDesc; - - bootDesc.fNext = &appDesc; - - diskFormatter.Format(kMachineModel, &rootDesc, 3); + diskFormatter.Format(kMachineModel, &rootDesc, 1); } EFI::ExitBootServices(*MapKey, ImageHandle); diff --git a/Private/NewKit/Defines.hpp b/Private/NewKit/Defines.hpp index a3b86234..bed02081 100644 --- a/Private/NewKit/Defines.hpp +++ b/Private/NewKit/Defines.hpp @@ -66,7 +66,7 @@ using Utf32Char = char32_t; using Void = void; -using Lba = SSizeT; +using Lba = UInt64; enum class Endian : UChar { kEndianLittle, kEndianBig, kEndianMixed, kCount }; @@ -135,4 +135,4 @@ public: #undef INIT #endif // ifdef INIT -#define INIT(OBJ, TYPE, ...) TYPE OBJ = TYPE(__VA_ARGS__)
\ No newline at end of file +#define INIT(OBJ, TYPE, ...) TYPE OBJ = TYPE(__VA_ARGS__) diff --git a/Private/Source/AppMain.cxx b/Private/Source/AppMain.cxx index 8fa74459..404889d7 100644 --- a/Private/Source/AppMain.cxx +++ b/Private/Source/AppMain.cxx @@ -24,10 +24,21 @@ EXTERN_C NewOS::Void AppMain(NewOS::Void) { NewOS::FilesystemManagerInterface::Mount(newFS); if (newFS->GetImpl()) { - auto catalog = newFS->GetImpl()->GetCatalog("/Boot"); - if (catalog) { - NewOS::kcout << "Catalog-Path-Name: " << catalog->Name << NewOS::endl; - delete catalog; + NewCatalog* mountCatalog = newFS->GetImpl()->GetCatalog("/Boot/"); + + if (mountCatalog) { + delete newFS->GetImpl()->CreateCatalog("/Boot/System/", 0, kNewFSCatalogKindDir); + NewCatalog* newKernelCatalog = newFS->GetImpl()->CreateCatalog("/Boot/System/NewKernel"); + + if (newKernelCatalog) + NewOS::kcout << "Catalog-Path-Name: " << newKernelCatalog->Name << NewOS::endl; + + NewOS::kcout << "Catalog-Path-Name: " << mountCatalog->Name << NewOS::endl; + + delete newKernelCatalog; + delete mountCatalog; + } else { + delete newFS->GetImpl()->CreateCatalog("/Boot/", 0, kNewFSCatalogKindDir); } } diff --git a/Private/Source/FS/NewFS.cxx b/Private/Source/FS/NewFS.cxx index a5dfe45b..a91d440e 100644 --- a/Private/Source/FS/NewFS.cxx +++ b/Private/Source/FS/NewFS.cxx @@ -6,19 +6,20 @@ #ifdef __FSKIT_NEWFS__ +#include <Builtins/AHCI/AHCI.hxx> +#include <Builtins/ATA/ATA.hxx> #include <FSKit/NewFS.hxx> #include <KernelKit/HError.hpp> #include <NewKit/Crc32.hpp> -#include <NewKit/Utils.hpp> #include <NewKit/String.hpp> -#include <Builtins/ATA/ATA.hxx> -#include <Builtins/AHCI/AHCI.hxx> +#include <NewKit/Utils.hpp> using namespace NewOS; /// forward decl. -STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, Boolean isDataFork); +STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, + Boolean isDataFork); STATIC Lba ke_find_free_catalog(SizeT kind, Int32 drv); STATIC MountpointInterface sMountpointInterface; @@ -33,34 +34,35 @@ _Output NewFork* NewFSParser::CreateFork(_Input NewCatalog* catalog, Lba whereFork = 0; theFork.DataOffset = - ke_find_free_fork(theFork.DataSize, this->fDriveIndex, catalog, theFork.Kind == kNewFSDataForkKind); + ke_find_free_fork(theFork.DataSize, this->fDriveIndex, catalog, + theFork.Kind == kNewFSDataForkKind); theFork.Flags |= kNewFSFlagCreated; - Lba lba = theFork.Kind == kNewFSDataForkKind ? catalog->DataFork : catalog->ResourceFork; + Lba lba = theFork.Kind == kNewFSDataForkKind ? catalog->DataFork + : catalog->ResourceFork; - if (lba == 0) { + if (lba <= kNewFSAddressAsLba) { lba = whereFork; } else { - if (lba == 0) { + if (lba <= kNewFSAddressAsLba) { theFork.PreviousSibling = lba; } } if (theFork.Kind == kNewFSDataForkKind) { - if (catalog->DataFork == 0) { - catalog->DataFork = whereFork; - } else { - theFork.PreviousSibling = catalog->DataFork; - } + if (catalog->DataFork == 0) { + catalog->DataFork = whereFork; + } else { + theFork.PreviousSibling = catalog->DataFork; + } } else { - if (catalog->ResourceFork == 0) { - catalog->ResourceFork = whereFork; - } else { - theFork.PreviousSibling = catalog->ResourceFork; - } + if (catalog->ResourceFork == 0) { + catalog->ResourceFork = whereFork; + } else { + theFork.PreviousSibling = catalog->ResourceFork; + } } - if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) - return nullptr; + if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) return nullptr; auto drv = sMountpointInterface.GetAddressOf(this->fDriveIndex); @@ -90,7 +92,7 @@ _Output NewFork* NewFSParser::CreateFork(_Input NewCatalog* catalog, } /// Also update catalog. - this->WriteCatalog(catalog, nullptr); + this->WriteCatalog(catalog, nullptr, 0); return &theFork; } @@ -103,7 +105,8 @@ _Output NewFork* NewFSParser::CreateFork(_Input NewCatalog* catalog, /// @param name the fork name. /// @return the fork. _Output NewFork* NewFSParser::FindFork(_Input NewCatalog* catalog, - _Input const Char* name, Boolean isDataFork) { + _Input const Char* name, + Boolean isDataFork) { auto drv = sMountpointInterface.GetAddressOf(this->fDriveIndex); NewFork* theFork = nullptr; Lba lba = isDataFork ? catalog->DataFork : catalog->ResourceFork; @@ -160,6 +163,187 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name) { _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name, _Input const Int32& flags, _Input const Int32& kind) { + if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) return nullptr; + + Lba outLba = 0UL; + + if (kind == kNewFSCatalogKindDir && + name[rt_string_len(name) - 1] != NewFilesystemHelper::Separator()) + return nullptr; + + /// as well as this, we don't want that. + if (kind != kNewFSCatalogKindDir && + name[rt_string_len(name) - 1] == NewFilesystemHelper::Separator()) + return nullptr; + + NewCatalog* checkForCpy = this->FindCatalog(name, outLba); + + if (checkForCpy) { + return checkForCpy; + } + + char copyName[kNewFSNodeNameLen] = {0}; + + for (SizeT indexName = 0UL; indexName < rt_string_len(name); ++indexName) { + copyName[indexName] = name[indexName]; + } + + if (*copyName == 0) { + DbgLastError() = kErrorFileNotFound; + return nullptr; + } + + for (SizeT indexFill = 0; indexFill < rt_string_len(name); + ++indexFill) { + copyName[indexFill] = name[indexFill]; + } + + SizeT indexReverseCopy = rt_string_len(copyName); + + // zero character. + copyName[--indexReverseCopy] = 0; + + // mandatory / character. + copyName[--indexReverseCopy] = 0; + + while (copyName[indexReverseCopy] != '/') { + copyName[indexReverseCopy] = 0; + --indexReverseCopy; + } + + NewCatalog* catalog = this->FindCatalog(copyName, outLba); + + if (!catalog) { + return nullptr; + } + + if (catalog->Kind == kNewFSCatalogKindFile) { + delete catalog; + return nullptr; + } + + constexpr SizeT cDefaultForkSize = 8096; + + NewCatalog* catalogChild = new NewCatalog(); + + catalogChild->DataFork = 0UL; + catalogChild->ResourceFork = 0UL; + + catalogChild->ResourceForkOverallSize = cDefaultForkSize; + catalogChild->DataForkSize = cDefaultForkSize; + + catalogChild->NextSibling = 0UL; + catalogChild->PrevSibling = outLba; + catalogChild->Flags = flags; + catalogChild->Kind = kind; + catalogChild->Flags |= kNewFSFlagCreated; + + rt_copy_memory((VoidPtr)name, (VoidPtr)catalogChild->Name, + rt_string_len(name)); + + UInt16 sectorBuf[kNewFSMinimumSectorSz] = {0}; + + auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); + + Lba startFree = catalogChild->PrevSibling + catalog->NextSibling; + + kcout << "Next-Catalog: " << hex_number(startFree) << endl; + + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; + drive->fPacket.fLba = startFree; + + drive->fInput(&drive->fPacket); + + while (drive->fPacket.fPacketGood) { + NewCatalog* nextSibling = (NewCatalog*)sectorBuf; + + if (startFree <= kNewFSAddressAsLba) { + delete catalogChild; + delete catalog; + + return nullptr; + } + + /// allocation or reallocation or catalog... + if (StringBuilder::Equals(nextSibling->Name, name) || + (nextSibling->Name[0] == 0 && + nextSibling->Flags != kNewFSFlagCreated)) { + if ((nextSibling->Flags != kNewFSFlagCreated)) { + nextSibling->Flags = kNewFSFlagCreated; + + drive->fPacket.fPacketContent = catalogChild; + drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; + drive->fPacket.fLba = startFree; + + if (catalogChild->Kind == kNewFSCatalogKindFile) { + rt_copy_memory((VoidPtr) "x-kind/file", (VoidPtr)catalogChild->Mime, + rt_string_len("x-kind/file")); + } else { + rt_copy_memory((VoidPtr) "x-kind/dir", (VoidPtr)catalogChild->Mime, + rt_string_len("x-kind/dir")); + } + + catalogChild->NextSibling = sizeof(NewCatalog) + + catalogChild->DataForkSize + + catalogChild->ResourceForkOverallSize; + + drive->fOutput(&drive->fPacket); + + kcout << "New OS: Create new catalog with success!\r\n"; + + Char sectBuf[sizeof(NewCatalog)] = {0}; + + drive->fPacket.fPacketContent = sectBuf; + drive->fPacket.fPacketSize = sizeof(NewCatalog); + drive->fPacket.fLba = catalogChild->PrevSibling; + + drive->fInput(&drive->fPacket); + + NewCatalog* prevCatalog = (NewCatalog*)sectBuf; + prevCatalog->NextSibling = startFree; + + drive->fOutput(&drive->fPacket); + + kcout << "Edit-Catalog: " << prevCatalog->Name << endl; + + Char sectorBufPartBlock[kNewFSMinimumSectorSz] = {0}; + + drive->fPacket.fPacketContent = sectorBufPartBlock; + drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; + drive->fPacket.fLba = kNewFSAddressAsLba; + + drive->fInput(&drive->fPacket); + + NewPartitionBlock* partBlock = (NewPartitionBlock*)sectorBufPartBlock; + + partBlock->SectorCount -= 1; + partBlock->CatalogCount += 1; + partBlock->FreeCatalog -= 1; + + drive->fOutput(&drive->fPacket); + + delete catalog; + return catalogChild; + } else { + delete catalog; + return nullptr; + } + } + + //// @note that's how we find the next catalog in the partition block. + startFree += sizeof(NewFork) + sizeof(NewCatalog) + + nextSibling->DataForkSize + + nextSibling->ResourceForkOverallSize; + + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; + drive->fPacket.fLba = startFree; + + drive->fInput(&drive->fPacket); + } + + delete catalog; return nullptr; } @@ -176,7 +360,7 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) { return false; } - UInt16 sectorBuf[kNewFSMinimumSectorSz] = {0}; + Char sectorBuf[kNewFSMinimumSectorSz] = {0}; drive->fPacket.fPacketContent = sectorBuf; drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; @@ -193,9 +377,12 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) { rt_string_cmp(partBlock->Ident, kNewFSIdent, kNewFSIdentLen)) { /// partition is free and valid. + partBlock->Version = kNewFSVersionInteger; + rt_copy_memory((VoidPtr)kNewFSIdent, (VoidPtr)partBlock->Ident, kNewFSIdentLen); - rt_copy_memory((VoidPtr) "Untitled HD\0", (VoidPtr)partBlock->PartitionName, + rt_copy_memory((VoidPtr) "Untitled HD\0", + (VoidPtr)partBlock->PartitionName, rt_string_len("Untitled HD\0")); SizeT catalogCount = 0; @@ -203,7 +390,8 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) { SizeT diskSize = drv_std_get_drv_size(); partBlock->Kind = kNewFSPartitionTypeStandard; - partBlock->StartCatalog = kNewFSCatalogStartAddress;; + partBlock->StartCatalog = kNewFSCatalogStartAddress; + ; partBlock->CatalogCount = catalogCount; partBlock->SectorCount = sectorCount; partBlock->DiskSize = diskSize; @@ -227,92 +415,99 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) { return false; } -/// @brief -/// @param catalog -/// @param data +/// @brief Writes the data fork into a specific catalog. +/// @param catalog the catalog itself +/// @param data the data. /// @return -bool NewFSParser::WriteCatalog(_Input _Output NewCatalog* catalog, - voidPtr data) { +bool NewFSParser::WriteCatalog(_Input _Output NewCatalog* catalog, voidPtr data, + SizeT sizeOfData) { return false; } /// @brief /// @param catalogName /// @return -_Output NewCatalog* NewFSParser::FindCatalog(_Input const char* catalogName) { - if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) return nullptr; +_Output NewCatalog* NewFSParser::FindCatalog(_Input const char* catalogName, + Lba& outLba) { + if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) return nullptr; - Char* sectorBuf = new Char[sizeof(NewPartitionBlock)]; - auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); + Char* sectorBuf = new Char[sizeof(NewPartitionBlock)]; + auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); - drive->fPacket.fPacketContent = sectorBuf; - drive->fPacket.fPacketSize = sizeof(NewPartitionBlock); - drive->fPacket.fLba = kNewFSAddressAsLba; + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = sizeof(NewPartitionBlock); + drive->fPacket.fLba = kNewFSAddressAsLba; - drive->fInput(&drive->fPacket); + drive->fInput(&drive->fPacket); - NewPartitionBlock* part = (NewPartitionBlock*)sectorBuf; + NewPartitionBlock* part = (NewPartitionBlock*)sectorBuf; - kcout << "Drive-Kind: " << drive->fDriveKind() << endl; + kcout << "Drive-Kind: " << drive->fDriveKind() << endl; - kcout << "Partition-Name: " << part->PartitionName << endl; - kcout << "Start-Catalog: " << number(part->StartCatalog) << endl; - kcout << "Catalog-Count: " << number(part->CatalogCount) << endl; - kcout << "Free-Catalog: " << number(part->FreeCatalog) << endl; - kcout << "Free-Sectors: " << number(part->FreeSectors) << endl; - kcout << "Sector-Size: " << number(part->SectorSize) << endl; + kcout << "Partition-Name: " << part->PartitionName << endl; + kcout << "Start-Catalog: " << number(part->StartCatalog) << endl; + kcout << "Catalog-Count: " << number(part->CatalogCount) << endl; + kcout << "Free-Catalog: " << number(part->FreeCatalog) << endl; + kcout << "Free-Sectors: " << number(part->FreeSectors) << endl; + kcout << "Sector-Size: " << number(part->SectorSize) << endl; - auto start = part->StartCatalog; + auto start = part->StartCatalog; - drive->fPacket.fLba = start; - drive->fPacket.fPacketContent = sectorBuf; - drive->fPacket.fPacketSize = sizeof(NewCatalog); + drive->fPacket.fLba = start; + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = sizeof(NewCatalog); - drive->fInput(&drive->fPacket); + drive->fInput(&drive->fPacket); - while (drive->fPacket.fPacketGood) { - NewCatalog* catalog = (NewCatalog*)sectorBuf; + while (drive->fPacket.fPacketGood) { + NewCatalog* catalog = (NewCatalog*)sectorBuf; - if (StringBuilder::Equals(catalogName, catalog->Name)) { - NewCatalog* catalogPtr = new NewCatalog(); - rt_copy_memory(catalog, catalogPtr, sizeof(NewCatalog)); + if (StringBuilder::Equals(catalogName, catalog->Name)) { + NewCatalog* catalogPtr = new NewCatalog(); + rt_copy_memory(catalog, catalogPtr, sizeof(NewCatalog)); - delete[] sectorBuf; - return catalogPtr; - } + outLba = start; + delete[] sectorBuf; + return catalogPtr; + } - if (catalog->NextSibling == 0) - break; + start = catalog->NextSibling; - drive->fPacket.fLba = catalog->NextSibling; - drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; - drive->fInput(&drive->fPacket); - } + if (start <= kNewFSAddressAsLba) break; + + drive->fPacket.fLba = start; + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = sizeof(NewCatalog); - delete[] sectorBuf; + drive->fInput(&drive->fPacket); + } - return nullptr; + outLba = 0UL; + delete[] sectorBuf; + + return nullptr; } /// @brief /// @param name /// @return _Output NewCatalog* NewFSParser::GetCatalog(_Input const char* name) { - return this->FindCatalog(name); + Lba unused = 0; + return this->FindCatalog(name, unused); } /// @brief /// @param catalog /// @return Boolean NewFSParser::CloseCatalog(_Input _Output NewCatalog* catalog) { - if (this->WriteCatalog(catalog, nullptr)) { - delete catalog; - catalog = nullptr; + if (this->WriteCatalog(catalog, nullptr, 0)) { + delete catalog; + catalog = nullptr; - return true; - } + return true; + } - return false; + return false; } /// @brief Mark catalog as removed. @@ -320,12 +515,12 @@ Boolean NewFSParser::CloseCatalog(_Input _Output NewCatalog* catalog) { /// @return Boolean NewFSParser::RemoveCatalog(_Input _Output NewCatalog* catalog) { if (!catalog) { - DbgLastError() = kErrorFileNotFound; - return false; + DbgLastError() = kErrorFileNotFound; + return false; } catalog->Flags |= kNewFSFlagDeleted; - this->WriteCatalog(catalog, nullptr); + this->WriteCatalog(catalog, nullptr, 0); return false; } @@ -340,12 +535,12 @@ Boolean NewFSParser::RemoveCatalog(_Input _Output NewCatalog* catalog) { /// @return VoidPtr NewFSParser::ReadCatalog(_Input _Output NewCatalog* catalog, SizeT dataSz) { - if (!catalog) { - DbgLastError() = kErrorFileNotFound; - return nullptr; - } - + if (!catalog) { + DbgLastError() = kErrorFileNotFound; return nullptr; + } + + return nullptr; } /// @brief Seek in the data fork. @@ -353,31 +548,31 @@ VoidPtr NewFSParser::ReadCatalog(_Input _Output NewCatalog* catalog, /// @param off /// @return bool NewFSParser::Seek(_Input _Output NewCatalog* catalog, SizeT off) { - if (!catalog) { - DbgLastError() = kErrorFileNotFound; - return false; - } - + if (!catalog) { + DbgLastError() = kErrorFileNotFound; return false; + } + + return false; } /// @brief Tell where we are inside the data fork. /// @param catalog /// @return SizeT NewFSParser::Tell(_Input _Output NewCatalog* catalog) { - if (!catalog) { - DbgLastError() = kErrorFileNotFound; - return false; - } + if (!catalog) { + DbgLastError() = kErrorFileNotFound; + return false; + } - return 0; + return 0; } /// @brief Find a free fork inside the filesystem. /// @param sz the size of the fork to set. /// @return the valid lba. -STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, Boolean isDataFork) { - +STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, + Boolean isDataFork) { if (sMountpointInterface.GetAddressOf(drv)) { auto drive = *sMountpointInterface.GetAddressOf(drv); @@ -413,7 +608,7 @@ STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, Boolean i (fork->Flags == kNewFSFlagDeleted || fork->Flags == kNewFSFlagUnallocated)) { fork->DataSize = sz; - fork->Flags |= kNewFSFlagCreated; + fork->Flags = kNewFSFlagCreated; drive.fOutput(&drive.fPacket); @@ -443,7 +638,6 @@ STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, Boolean i /// @param kind the catalog kind. /// @return the valid lba. STATIC Lba ke_find_free_catalog(SizeT kind, Int32 drv) { - if (sMountpointInterface.GetAddressOf(drv)) { auto drive = *sMountpointInterface.GetAddressOf(drv); UInt16 sectorBuf[kNewFSMinimumSectorSz] = {0}; @@ -478,7 +672,7 @@ STATIC Lba ke_find_free_catalog(SizeT kind, Int32 drv) { if (catalog->Flags == kNewFSFlagUnallocated || catalog->Flags == kNewFSFlagDeleted) { - catalog->Flags |= kNewFSFlagCreated; + catalog->Flags = kNewFSFlagCreated; catalog->Kind |= kind; return startLba; @@ -497,14 +691,14 @@ STATIC Lba ke_find_free_catalog(SizeT kind, Int32 drv) { namespace NewOS::Detail { Boolean fs_init_newfs(Void) noexcept { - sMountpointInterface.A() = construct_main_drive(); - sMountpointInterface.B() = construct_drive(); - sMountpointInterface.C() = construct_drive(); - sMountpointInterface.D() = construct_drive(); + sMountpointInterface.A() = construct_main_drive(); + sMountpointInterface.B() = construct_drive(); + sMountpointInterface.C() = construct_drive(); + sMountpointInterface.D() = construct_drive(); - sMountpointInterface.A().fVerify(&sMountpointInterface.A().fPacket); + sMountpointInterface.A().fVerify(&sMountpointInterface.A().fPacket); - return true; + return true; } } // namespace NewOS::Detail diff --git a/Private/Source/FileManager.cxx b/Private/Source/FileManager.cxx index 4742769c..aab3cff0 100644 --- a/Private/Source/FileManager.cxx +++ b/Private/Source/FileManager.cxx @@ -47,9 +47,9 @@ bool FilesystemManagerInterface::Mount(FilesystemManagerInterface* mountPtr) { #ifdef __FSKIT_NEWFS__ /// @brief Opens a new file. -/// @param path -/// @param r -/// @return +/// @param path +/// @param r +/// @return NodePtr NewFilesystemManager::Open(const char* path, const char* r) { if (!path || *path == 0) return nullptr; @@ -66,14 +66,14 @@ NodePtr NewFilesystemManager::Open(const char* path, const char* r) { } /// @brief Writes to a catalog -/// @param node -/// @param data -/// @param flags -/// @return +/// @param node +/// @param data +/// @param flags +/// @return Void NewFilesystemManager::Write(NodePtr node, VoidPtr data, - Int32 flags) { + Int32 flags, SizeT size) { if ((reinterpret_cast<NewCatalog*>(node))->Kind == kNewFSCatalogKindFile) - fImpl->WriteCatalog(reinterpret_cast<NewCatalog*>(node), data); + fImpl->WriteCatalog(reinterpret_cast<NewCatalog*>(node), data, size); } /** @@ -82,10 +82,10 @@ Void NewFilesystemManager::Write(NodePtr node, VoidPtr data, */ /// @brief Reads from filesystem. -/// @param node -/// @param flags -/// @param sz -/// @return +/// @param node +/// @param flags +/// @param sz +/// @return VoidPtr NewFilesystemManager::Read(NodePtr node, Int32 flags, SizeT sz) { if ((reinterpret_cast<NewCatalog*>(node))->Kind == kNewFSCatalogKindFile) return fImpl->ReadCatalog(reinterpret_cast<NewCatalog*>(node), sz); @@ -94,18 +94,18 @@ VoidPtr NewFilesystemManager::Read(NodePtr node, Int32 flags, SizeT sz) { } /// @brief Seek from Catalog. -/// @param node -/// @param off -/// @return +/// @param node +/// @param off +/// @return bool NewFilesystemManager::Seek(NodePtr node, SizeT off) { if (!node || off == 0) return false; - + return fImpl->Seek(reinterpret_cast<NewCatalog*>(node), off); } /// @brief Tell where the catalog is/ -/// @param node -/// @return +/// @param node +/// @return SizeT NewFilesystemManager::Tell(NodePtr node) { if (!node) return kNPos; @@ -113,8 +113,8 @@ SizeT NewFilesystemManager::Tell(NodePtr node) { } /// @brief Rewind the catalog. -/// @param node -/// @return +/// @param node +/// @return bool NewFilesystemManager::Rewind(NodePtr node) { if (!node) return false; @@ -122,7 +122,7 @@ bool NewFilesystemManager::Rewind(NodePtr node) { } /// @brief The filesystem implementation. -/// @return +/// @return NewFSParser* NewFilesystemManager::GetImpl() noexcept { return fImpl; } #endif // __FSKIT_NEWFS__ } // namespace NewOS |
