Rework virtual filesystem implementation

This commit is contained in:
Alex 2023-04-21 18:32:20 +03:00
parent f2eab6c64f
commit dc7b1fc4c9
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
14 changed files with 138 additions and 136 deletions

View File

@ -219,10 +219,10 @@ namespace Driver
DriverConfigFile << "/config.ini"; DriverConfigFile << "/config.ini";
fixme("Loading driver config file: %s", DriverConfigFile.c_str()); fixme("Loading driver config file: %s", DriverConfigFile.c_str());
std::shared_ptr<VirtualFileSystem::File> DriverDirectory = vfs->Open(Config.DriverDirectory); VirtualFileSystem::File DriverDirectory = vfs->Open(Config.DriverDirectory);
if (DriverDirectory->Status == VirtualFileSystem::FileStatus::OK) if (DriverDirectory.IsOK())
{ {
foreach (auto driver in DriverDirectory->node->Children) foreach (auto driver in DriverDirectory.node->Children)
if (driver->Flags == VirtualFileSystem::NodeFlags::FILE) if (driver->Flags == VirtualFileSystem::NodeFlags::FILE)
if (cwk_path_has_extension(driver->Name)) if (cwk_path_has_extension(driver->Name))
{ {
@ -246,7 +246,7 @@ namespace Driver
} }
else else
{ {
KPrint("\eE85230Failed to open driver directory: %s! (Status: %#lx)", Config.DriverDirectory, DriverDirectory->Status); KPrint("\eE85230Failed to open driver directory: %s! (Status: %#lx)", Config.DriverDirectory, DriverDirectory.Status);
CPU::Stop(); CPU::Stop();
} }
vfs->Close(DriverDirectory); vfs->Close(DriverDirectory);

View File

@ -131,9 +131,9 @@ namespace Execute
cwk_path_get_basename(Path, &BaseName, nullptr); cwk_path_get_basename(Path, &BaseName, nullptr);
TaskArchitecture Arch = TaskArchitecture::UnknownArchitecture; TaskArchitecture Arch = TaskArchitecture::UnknownArchitecture;
std::shared_ptr<File> ExFile = vfs->Open(Path); File ExFile = vfs->Open(Path);
if (ExFile->Status != FileStatus::OK) if (ExFile.Status != FileStatus::OK)
{ {
vfs->Close(ExFile); vfs->Close(ExFile);
error("Failed to open file: %s", Path); error("Failed to open file: %s", Path);
@ -141,7 +141,7 @@ namespace Execute
} }
else else
{ {
if (ExFile->node->Flags != NodeFlags::FILE) if (ExFile.node->Flags != NodeFlags::FILE)
{ {
vfs->Close(ExFile); vfs->Close(ExFile);
error("Invalid file path: %s", Path); error("Invalid file path: %s", Path);
@ -155,12 +155,12 @@ namespace Execute
} }
} }
size_t ExFileSize = ExFile->node->Length; size_t ExFileSize = ExFile.node->Length;
/* Allocate elf in memory */ /* Allocate elf in memory */
void *ElfFile = KernelAllocator.RequestPages(TO_PAGES(ExFileSize + 1)); void *ElfFile = KernelAllocator.RequestPages(TO_PAGES(ExFileSize + 1));
/* Copy the file to the allocated memory */ /* Copy the file to the allocated memory */
memcpy(ElfFile, (void *)ExFile->node->Address, ExFileSize); memcpy(ElfFile, (void *)ExFile.node->Address, ExFileSize);
debug("Image Size: %#lx - %#lx (length: %ld)", ElfFile, (uintptr_t)ElfFile + ExFileSize, ExFileSize); debug("Image Size: %#lx - %#lx (length: %ld)", ElfFile, (uintptr_t)ElfFile + ExFileSize, ExFileSize);
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile; Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile;
@ -220,13 +220,13 @@ namespace Execute
switch (ELFHeader->e_type) switch (ELFHeader->e_type)
{ {
case ET_REL: case ET_REL:
bl = ELFLoadRel(ElfFile, ExFile.get(), Process); bl = ELFLoadRel(ElfFile, ExFile, Process);
break; break;
case ET_EXEC: case ET_EXEC:
bl = ELFLoadExec(ElfFile, ExFile.get(), Process); bl = ELFLoadExec(ElfFile, ExFile, Process);
break; break;
case ET_DYN: case ET_DYN:
bl = ELFLoadDyn(ElfFile, ExFile.get(), Process); bl = ELFLoadDyn(ElfFile, ExFile, Process);
break; break;
case ET_CORE: case ET_CORE:
{ {

View File

@ -32,7 +32,7 @@ using namespace Tasking;
namespace Execute namespace Execute
{ {
ELFBaseLoad ELFLoadDyn(void *BaseImage, ELFBaseLoad ELFLoadDyn(void *BaseImage,
VirtualFileSystem::File *ExFile, VirtualFileSystem::File &ExFile,
Tasking::PCB *Process) Tasking::PCB *Process)
{ {
fixme("Not implemented"); fixme("Not implemented");

View File

@ -32,7 +32,7 @@ using namespace Tasking;
namespace Execute namespace Execute
{ {
ELFBaseLoad ELFLoadExec(void *ElfFile, ELFBaseLoad ELFLoadExec(void *ElfFile,
VirtualFileSystem::File *ExFile, VirtualFileSystem::File &ExFile,
Tasking::PCB *Process) Tasking::PCB *Process)
{ {
debug("Executable"); debug("Executable");
@ -46,7 +46,7 @@ namespace Execute
uintptr_t BaseAddress = UINTPTR_MAX; uintptr_t BaseAddress = UINTPTR_MAX;
uint64_t ElfAppSize = 0; uint64_t ElfAppSize = 0;
uintptr_t EntryPoint = ELFHeader->e_entry; uintptr_t EntryPoint = ELFHeader->e_entry;
debug("%s's entry point is %#lx", ExFile->Name, EntryPoint); debug("%s's entry point is %#lx", ExFile.Name, EntryPoint);
Elf64_Phdr ItrPhdr; Elf64_Phdr ItrPhdr;
@ -171,8 +171,8 @@ namespace Execute
memcpy((void *)InterpreterPath, (uint8_t *)ElfFile + ItrPhdr.p_offset, 256); memcpy((void *)InterpreterPath, (uint8_t *)ElfFile + ItrPhdr.p_offset, 256);
debug("Interpreter: %s", InterpreterPath); debug("Interpreter: %s", InterpreterPath);
std::shared_ptr<VirtualFileSystem::File> InterpreterFile = vfs->Open(InterpreterPath); VirtualFileSystem::File InterpreterFile = vfs->Open(InterpreterPath);
if (InterpreterFile->Status != VirtualFileSystem::FileStatus::OK) if (!InterpreterFile.IsOK())
warn("Failed to open interpreter file: %s", InterpreterPath); warn("Failed to open interpreter file: %s", InterpreterPath);
vfs->Close(InterpreterFile); vfs->Close(InterpreterFile);
@ -206,7 +206,7 @@ namespace Execute
strcpy(aux_platform, "x86_64"); strcpy(aux_platform, "x86_64");
ELFBase.auxv.push_back({.archaux = {.a_type = AT_NULL, .a_un = {.a_val = 0}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_NULL, .a_un = {.a_val = 0}}});
ELFBase.auxv.push_back({.archaux = {.a_type = AT_EXECFN, .a_un = {.a_val = (uint64_t)vfs->GetPathFromNode(ExFile->node).get()}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_EXECFN, .a_un = {.a_val = (uint64_t)vfs->GetPathFromNode(ExFile.node).get()}}});
ELFBase.auxv.push_back({.archaux = {.a_type = AT_PLATFORM, .a_un = {.a_val = (uint64_t)aux_platform}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_PLATFORM, .a_un = {.a_val = (uint64_t)aux_platform}}});
ELFBase.auxv.push_back({.archaux = {.a_type = AT_ENTRY, .a_un = {.a_val = (uint64_t)EntryPoint}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_ENTRY, .a_un = {.a_val = (uint64_t)EntryPoint}}});
ELFBase.auxv.push_back({.archaux = {.a_type = AT_BASE, .a_un = {.a_val = (uint64_t)MemoryImage.Virtual}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_BASE, .a_un = {.a_val = (uint64_t)MemoryImage.Virtual}}});

View File

@ -232,9 +232,9 @@ namespace Execute
} }
/* No need to check if it's valid, the GetBinaryType() call above does that. */ /* No need to check if it's valid, the GetBinaryType() call above does that. */
std::shared_ptr<VirtualFileSystem::File> File = vfs->Open(Interpreter); VirtualFileSystem::File File = vfs->Open(Interpreter);
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)File->node->Address; Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)File.node->Address;
#ifdef DEBUG #ifdef DEBUG
const char *InterpreterType[6] = { const char *InterpreterType[6] = {
@ -259,7 +259,7 @@ namespace Execute
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++) for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
{ {
memcpy(&ItrPhdr, memcpy(&ItrPhdr,
(uint8_t *)File->node->Address + ELFHeader->e_phoff + ELFHeader->e_phentsize * i, (uint8_t *)File.node->Address + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
sizeof(Elf64_Phdr)); sizeof(Elf64_Phdr));
BaseAddress = MIN(BaseAddress, ItrPhdr.p_vaddr); BaseAddress = MIN(BaseAddress, ItrPhdr.p_vaddr);
@ -269,7 +269,7 @@ namespace Execute
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++) for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
{ {
memcpy(&ItrPhdr, memcpy(&ItrPhdr,
(uint8_t *)File->node->Address + ELFHeader->e_phoff + ELFHeader->e_phentsize * i, (uint8_t *)File.node->Address + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
sizeof(Elf64_Phdr)); sizeof(Elf64_Phdr));
uintptr_t SegmentEnd; uintptr_t SegmentEnd;
@ -277,12 +277,12 @@ namespace Execute
ElfAppSize = MAX(ElfAppSize, SegmentEnd); ElfAppSize = MAX(ElfAppSize, SegmentEnd);
} }
MmImage MemoryImage = ELFCreateMemoryImage(mem, pV, (void *)File->node->Address, ElfAppSize); MmImage MemoryImage = ELFCreateMemoryImage(mem, pV, (void *)File.node->Address, ElfAppSize);
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++) for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
{ {
memcpy(&ItrPhdr, memcpy(&ItrPhdr,
(uint8_t *)File->node->Address + ELFHeader->e_phoff + ELFHeader->e_phentsize * i, (uint8_t *)File.node->Address + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
sizeof(Elf64_Phdr)); sizeof(Elf64_Phdr));
if (ItrPhdr.p_type == PT_LOAD) if (ItrPhdr.p_type == PT_LOAD)
@ -296,8 +296,8 @@ namespace Execute
(ItrPhdr.p_flags & PF_W) ? "W" : "", (ItrPhdr.p_flags & PF_W) ? "W" : "",
(ItrPhdr.p_flags & PF_X) ? "X" : ""); (ItrPhdr.p_flags & PF_X) ? "X" : "");
memcpy((void *)MAddr, (uint8_t *)File->node->Address + ItrPhdr.p_offset, ItrPhdr.p_filesz); memcpy((void *)MAddr, (uint8_t *)File.node->Address + ItrPhdr.p_offset, ItrPhdr.p_filesz);
debug("memcpy: %#lx => %#lx (%ld bytes)", (uint8_t *)File->node->Address + ItrPhdr.p_offset, MAddr, ItrPhdr.p_filesz); debug("memcpy: %#lx => %#lx (%ld bytes)", (uint8_t *)File.node->Address + ItrPhdr.p_offset, MAddr, ItrPhdr.p_filesz);
} }
} }

View File

@ -27,7 +27,7 @@ namespace Execute
/* Originally from https://wiki.osdev.org/ELF_Tutorial */ /* Originally from https://wiki.osdev.org/ELF_Tutorial */
ELFBaseLoad ELFLoadRel(void *BaseImage, ELFBaseLoad ELFLoadRel(void *BaseImage,
VirtualFileSystem::File *ExFile, VirtualFileSystem::File &ExFile,
Tasking::PCB *Process) Tasking::PCB *Process)
{ {
debug("Relocatable"); debug("Relocatable");

View File

@ -86,12 +86,12 @@ namespace Execute
BinaryType GetBinaryType(char *Path) BinaryType GetBinaryType(char *Path)
{ {
BinaryType Type = BinaryType::BinTypeInvalid; BinaryType Type = BinaryType::BinTypeInvalid;
std::shared_ptr<VirtualFileSystem::File> ExFile = vfs->Open(Path); VirtualFileSystem::File ExFile = vfs->Open(Path);
if (ExFile->Status == VirtualFileSystem::FileStatus::OK) if (ExFile.IsOK())
{ {
debug("File opened: %s", Path); debug("File opened: %s", Path);
Type = GetBinaryType((void *)ExFile->node->Address); Type = GetBinaryType((void *)ExFile.node->Address);
} }
vfs->Close(ExFile); vfs->Close(ExFile);

View File

@ -37,11 +37,11 @@ namespace Execute
.Process = nullptr, .Process = nullptr,
.Thread = nullptr}; .Thread = nullptr};
std::shared_ptr<VirtualFileSystem::File> ExFile = vfs->Open(Path); VirtualFileSystem::File ExFile = vfs->Open(Path);
if (ExFile->Status == VirtualFileSystem::FileStatus::OK) if (ExFile.IsOK())
{ {
if (ExFile->node->Flags != VirtualFileSystem::NodeFlags::FILE) if (ExFile.node->Flags != VirtualFileSystem::NodeFlags::FILE)
{ {
ret.Status = ExStatus::InvalidFilePath; ret.Status = ExStatus::InvalidFilePath;
goto Exit; goto Exit;
@ -51,17 +51,17 @@ namespace Execute
{ {
case BinaryType::BinTypeFex: case BinaryType::BinTypeFex:
{ {
Fex *FexHdr = (Fex *)ExFile->node->Address; Fex *FexHdr = (Fex *)ExFile.node->Address;
if (FexHdr->Type == FexFormatType::FexFormatType_Executable) if (FexHdr->Type == FexFormatType::FexFormatType_Executable)
{ {
const char *BaseName; const char *BaseName;
cwk_path_get_basename(Path, &BaseName, nullptr); cwk_path_get_basename(Path, &BaseName, nullptr);
PCB *Process = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), BaseName, TaskTrustLevel::User); PCB *Process = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), BaseName, TaskTrustLevel::User);
void *BaseImage = KernelAllocator.RequestPages(TO_PAGES(ExFile->node->Length + 1)); void *BaseImage = KernelAllocator.RequestPages(TO_PAGES(ExFile.node->Length + 1));
memcpy(BaseImage, (void *)ExFile->node->Address, ExFile->node->Length); memcpy(BaseImage, (void *)ExFile.node->Address, ExFile.node->Length);
Memory::Virtual(Process->PageTable).Map((void *)BaseImage, (void *)BaseImage, ExFile->node->Length, Memory::PTFlag::RW | Memory::PTFlag::US); Memory::Virtual(Process->PageTable).Map((void *)BaseImage, (void *)BaseImage, ExFile.node->Length, Memory::PTFlag::RW | Memory::PTFlag::US);
std::vector<AuxiliaryVector> auxv; // TODO! std::vector<AuxiliaryVector> auxv; // TODO!
@ -97,7 +97,7 @@ namespace Execute
} }
} }
} }
else if (ExFile->Status == VirtualFileSystem::FileStatus::NotFound) else if (ExFile.Status == VirtualFileSystem::FileStatus::NotFound)
ret.Status = ExStatus::InvalidFilePath; ret.Status = ExStatus::InvalidFilePath;
else else
ret.Status = ExStatus::InvalidFile; ret.Status = ExStatus::InvalidFile;

View File

@ -168,11 +168,11 @@ namespace VirtualFileSystem
return nullptr; return nullptr;
} }
std::shared_ptr<File> Virtual::ConvertNodeToFILE(Node *node) File Virtual::ConvertNodeToFILE(Node *node)
{ {
std::shared_ptr<File> file = std::make_shared<File>(); File file{};
file->Status = FileStatus::OK; file.Status = FileStatus::OK;
file->node = node; file.node = node;
return file; return file;
} }
@ -454,92 +454,86 @@ namespace VirtualFileSystem
FileStatus Virtual::Delete(Node *Path, bool Recursive, Node *Parent) { return Delete(GetPathFromNode(Path).get(), Recursive, Parent); } FileStatus Virtual::Delete(Node *Path, bool Recursive, Node *Parent) { return Delete(GetPathFromNode(Path).get(), Recursive, Parent); }
/* TODO: REWORK */ /* TODO: REWORK */
std::shared_ptr<File> Virtual::Mount(const char *Path, FileSystemOperations *Operator) File Virtual::Mount(const char *Path, FileSystemOperations *Operator)
{ {
SmartLock(VFSLock); SmartLock(VFSLock);
std::shared_ptr<File> file = std::make_shared<File>(); File file{};
if (unlikely(!Operator)) if (unlikely(!Operator))
{ {
file->Status = FileStatus::InvalidOperator; file.Status = FileStatus::InvalidOperator;
return file; return file;
} }
if (unlikely(isempty((char *)Path))) if (unlikely(isempty((char *)Path)))
{ {
file->Status = FileStatus::InvalidParameter; file.Status = FileStatus::InvalidParameter;
return file; return file;
} }
vfsdbg("Mounting %s", Path); vfsdbg("Mounting %s", Path);
const char *PathCopy; const char *PathCopy;
cwk_path_get_basename(Path, &PathCopy, 0); cwk_path_get_basename(Path, &PathCopy, 0);
strcpy(file->Name, PathCopy); strcpy(file.Name, PathCopy);
file->Status = FileStatus::OK; file.Status = FileStatus::OK;
file->node = Create(Path, NodeFlags::MOUNTPOINT); file.node = Create(Path, NodeFlags::MOUNTPOINT);
file->node->Operator = Operator; file.node->Operator = Operator;
return file; return file;
} }
FileStatus Virtual::Unmount(std::shared_ptr<File> File) FileStatus Virtual::Unmount(File &File)
{ {
SmartLock(VFSLock); SmartLock(VFSLock);
if (unlikely(File.get())) if (unlikely(!File.node))
return FileStatus::InvalidParameter; return FileStatus::InvalidParameter;
fixme("Unmounting %s", File->Name); fixme("Unmounting %s", File.Name);
return FileStatus::OK; return FileStatus::OK;
} }
size_t Virtual::Read(std::shared_ptr<File> File, size_t Offset, uint8_t *Buffer, size_t Size) size_t Virtual::Read(File &File, size_t Offset, uint8_t *Buffer, size_t Size)
{ {
SmartLock(VFSLock); SmartLock(VFSLock);
if (unlikely(!File.get())) if (unlikely(!File.node))
return 0;
if (unlikely(!File->node))
{ {
File->Status = FileStatus::InvalidNode; File.Status = FileStatus::InvalidNode;
return 0; return 0;
} }
if (unlikely(!File->node->Operator)) if (unlikely(!File.node->Operator))
{ {
File->Status = FileStatus::InvalidOperator; File.Status = FileStatus::InvalidOperator;
return 0; return 0;
} }
File->Status = FileStatus::OK; File.Status = FileStatus::OK;
vfsdbg("Reading %s out->%016x", File->Name, Buffer); vfsdbg("Reading %s out->%016x", File.Name, Buffer);
return File->node->Operator->Read(File->node, Offset, Size, Buffer); return File.node->Operator->Read(File.node, Offset, Size, Buffer);
} }
size_t Virtual::Write(std::shared_ptr<File> File, size_t Offset, uint8_t *Buffer, size_t Size) size_t Virtual::Write(File &File, size_t Offset, uint8_t *Buffer, size_t Size)
{ {
SmartLock(VFSLock); SmartLock(VFSLock);
if (unlikely(!File.get())) if (unlikely(!File.node))
return 0;
if (unlikely(!File->node))
{ {
File->Status = FileStatus::InvalidNode; File.Status = FileStatus::InvalidNode;
return 0; return 0;
} }
if (unlikely(!File->node->Operator)) if (unlikely(!File.node->Operator))
{ {
File->Status = FileStatus::InvalidOperator; File.Status = FileStatus::InvalidOperator;
return 0; return 0;
} }
File->Status = FileStatus::OK; File.Status = FileStatus::OK;
vfsdbg("Writing %s out->%016x", File->Name, Buffer); vfsdbg("Writing %s out->%016x", File.Name, Buffer);
return File->node->Operator->Write(File->node, Offset, Size, Buffer); return File.node->Operator->Write(File.node, Offset, Size, Buffer);
} }
/* TODO: CHECK Open */ /* TODO: CHECK Open */
std::shared_ptr<File> Virtual::Open(const char *Path, Node *Parent) File Virtual::Open(const char *Path, Node *Parent)
{ {
SmartLock(VFSLock); SmartLock(VFSLock);
vfsdbg("Opening %s with parent %s", Path, Parent ? Parent->Name : "(null)"); vfsdbg("Opening %s with parent %s", Path, Parent ? Parent->Name : "(null)");
@ -547,41 +541,41 @@ namespace VirtualFileSystem
if (strcmp(Path, "/") == 0) if (strcmp(Path, "/") == 0)
{ {
std::shared_ptr<File> file = std::make_shared<File>(); File file{};
file->node = FileSystemRoot; file.node = FileSystemRoot;
strcpy(file->Name, "/"); strcpy(file.Name, "/");
return file; return file;
} }
if (strcmp(Path, ".") == 0) if (strcmp(Path, ".") == 0)
{ {
std::shared_ptr<File> file = std::make_shared<File>(); File file{};
file->node = Parent; file.node = Parent;
if (unlikely(!file->node)) if (unlikely(!file.node))
file->Status = FileStatus::NotFound; file.Status = FileStatus::NotFound;
cwk_path_get_basename(GetPathFromNode(Parent).get(), &basename, nullptr); cwk_path_get_basename(GetPathFromNode(Parent).get(), &basename, nullptr);
strcpy(file->Name, basename); strcpy(file.Name, basename);
return file; return file;
} }
if (strcmp(Path, "..") == 0) if (strcmp(Path, "..") == 0)
{ {
std::shared_ptr<File> file = std::make_shared<File>(); File file{};
if (Parent->Parent != nullptr) if (Parent->Parent != nullptr)
file->node = Parent->Parent; file.node = Parent->Parent;
if (!file->node) if (!file.node)
file->Status = FileStatus::NotFound; file.Status = FileStatus::NotFound;
cwk_path_get_basename(GetPathFromNode(Parent).get(), &basename, nullptr); cwk_path_get_basename(GetPathFromNode(Parent).get(), &basename, nullptr);
strcpy(file->Name, basename); strcpy(file.Name, basename);
return file; return file;
} }
Node *CurrentParent = this->GetParent(Path, Parent); Node *CurrentParent = this->GetParent(Path, Parent);
std::shared_ptr<char> CleanPath = NormalizePath(Path, CurrentParent); std::shared_ptr<char> CleanPath = NormalizePath(Path, CurrentParent);
std::shared_ptr<File> file = std::make_shared<File>(); File file{};
/* TODO: Check for other errors */ /* TODO: Check for other errors */
if (!PathExists(CleanPath.get(), CurrentParent)) if (!PathExists(CleanPath.get(), CurrentParent))
@ -590,45 +584,45 @@ namespace VirtualFileSystem
{ {
if (strcmp(Child->Name, CleanPath.get()) == 0) if (strcmp(Child->Name, CleanPath.get()) == 0)
{ {
file->node = Child; file.node = Child;
if (file->node == nullptr) if (file.node == nullptr)
{ {
file->Status = FileStatus::UnknownFileStatusError; file.Status = FileStatus::UnknownFileStatusError;
file->node = nullptr; file.node = nullptr;
return file; return file;
} }
cwk_path_get_basename(GetPathFromNode(Child).get(), &basename, nullptr); cwk_path_get_basename(GetPathFromNode(Child).get(), &basename, nullptr);
strcpy(file->Name, basename); strcpy(file.Name, basename);
return file; return file;
} }
} }
file->node = GetNodeFromPath(CleanPath.get(), FileSystemRoot->Children[0]); file.node = GetNodeFromPath(CleanPath.get(), FileSystemRoot->Children[0]);
if (file->node) if (file.node)
{ {
cwk_path_get_basename(GetPathFromNode(file->node).get(), &basename, nullptr); cwk_path_get_basename(GetPathFromNode(file.node).get(), &basename, nullptr);
strcpy(file->Name, basename); strcpy(file.Name, basename);
return file; return file;
} }
} }
else else
{ {
file->node = GetNodeFromPath(CleanPath.get(), CurrentParent); file.node = GetNodeFromPath(CleanPath.get(), CurrentParent);
cwk_path_get_basename(CleanPath.get(), &basename, nullptr); cwk_path_get_basename(CleanPath.get(), &basename, nullptr);
strcpy(file->Name, basename); strcpy(file.Name, basename);
return file; return file;
} }
file->Status = FileStatus::NotFound; file.Status = FileStatus::NotFound;
return file; return file;
} }
FileStatus Virtual::Close(std::shared_ptr<File> File) FileStatus Virtual::Close(File &File)
{ {
SmartLock(VFSLock); SmartLock(VFSLock);
if (unlikely(!File.get())) if (unlikely(!File.node))
return FileStatus::InvalidHandle; return FileStatus::InvalidHandle;
vfsdbg("Closing %s", File->Name); vfsdbg("Closing %s", File.Name);
return FileStatus::OK; return FileStatus::OK;
} }

View File

@ -426,42 +426,42 @@ EXTERNC NIF void Main(BootInfo *Info)
DevFS = vfs->Create("/system/dev", NodeFlags::DIRECTORY); DevFS = vfs->Create("/system/dev", NodeFlags::DIRECTORY);
else else
{ {
std::shared_ptr<File> dev = vfs->Open("/system/dev"); File dev = vfs->Open("/system/dev");
if (dev->node->Flags != NodeFlags::DIRECTORY) if (dev.node->Flags != NodeFlags::DIRECTORY)
{ {
KPrint("\eE85230/system/dev is not a directory! Halting..."); KPrint("\eE85230/system/dev is not a directory! Halting...");
CPU::Stop(); CPU::Stop();
} }
vfs->Close(dev); vfs->Close(dev);
DevFS = dev->node; DevFS = dev.node;
} }
if (!vfs->PathExists("/system/mnt")) if (!vfs->PathExists("/system/mnt"))
MntFS = vfs->Create("/system/mnt", NodeFlags::DIRECTORY); MntFS = vfs->Create("/system/mnt", NodeFlags::DIRECTORY);
else else
{ {
std::shared_ptr<File> mnt = vfs->Open("/system/mnt"); File mnt = vfs->Open("/system/mnt");
if (mnt->node->Flags != NodeFlags::DIRECTORY) if (mnt.node->Flags != NodeFlags::DIRECTORY)
{ {
KPrint("\eE85230/system/mnt is not a directory! Halting..."); KPrint("\eE85230/system/mnt is not a directory! Halting...");
CPU::Stop(); CPU::Stop();
} }
vfs->Close(mnt); vfs->Close(mnt);
MntFS = mnt->node; MntFS = mnt.node;
} }
if (!vfs->PathExists("/system/proc")) if (!vfs->PathExists("/system/proc"))
ProcFS = vfs->Create("/system/proc", NodeFlags::DIRECTORY); ProcFS = vfs->Create("/system/proc", NodeFlags::DIRECTORY);
else else
{ {
std::shared_ptr<File> proc = vfs->Open("/system/proc", nullptr); File proc = vfs->Open("/system/proc", nullptr);
if (proc->node->Flags != NodeFlags::DIRECTORY) if (proc.node->Flags != NodeFlags::DIRECTORY)
{ {
KPrint("\eE85230/system/proc is not a directory! Halting..."); KPrint("\eE85230/system/proc is not a directory! Halting...");
CPU::Stop(); CPU::Stop();
} }
vfs->Close(proc); vfs->Close(proc);
ProcFS = proc->node; ProcFS = proc.node;
} }
KPrint("\e058C19################################"); KPrint("\e058C19################################");

View File

@ -176,17 +176,17 @@ void BootLogoAnimationThread()
while (FrameCount < 27) while (FrameCount < 27)
{ {
sprintf(BootAnimPath, "%d.tga", FrameCount); sprintf(BootAnimPath, "%d.tga", FrameCount);
std::shared_ptr<File> ba = bootanim_vfs->Open(BootAnimPath); File ba = bootanim_vfs->Open(BootAnimPath);
if (ba->Status != FileStatus::OK) if (!ba.IsOK())
{ {
bootanim_vfs->Close(ba); bootanim_vfs->Close(ba);
debug("Failed to load boot animation frame %s", BootAnimPath); debug("Failed to load boot animation frame %s", BootAnimPath);
break; break;
} }
FrameSizes[FrameCount] = s_cst(uint32_t, ba->node->Length); FrameSizes[FrameCount] = s_cst(uint32_t, ba.node->Length);
Frames[FrameCount] = new uint8_t[ba->node->Length]; Frames[FrameCount] = new uint8_t[ba.node->Length];
memcpy((void *)Frames[FrameCount], (void *)ba->node->Address, ba->node->Length); memcpy((void *)Frames[FrameCount], (void *)ba.node->Address, ba.node->Length);
bootanim_vfs->Close(ba); bootanim_vfs->Close(ba);
FrameCount++; FrameCount++;
} }

View File

@ -70,25 +70,25 @@ namespace Recovery
return; return;
} }
std::shared_ptr<VirtualFileSystem::File> pcm = vfs->Open(AudioFile); VirtualFileSystem::File pcm = vfs->Open(AudioFile);
if (pcm->Status != FileStatus::OK) if (!pcm.IsOK())
{ {
error("Cannot open audio file! Cannot play audio!"); error("Cannot open audio file! Cannot play audio!");
return; return;
} }
void *PCMRaw = KernelAllocator.RequestPages(TO_PAGES(pcm->node->Length + 1)); void *PCMRaw = KernelAllocator.RequestPages(TO_PAGES(pcm.node->Length + 1));
memcpy(PCMRaw, (void *)pcm->node->Address, pcm->node->Length); memcpy(PCMRaw, (void *)pcm.node->Address, pcm.node->Length);
KernelCallback callback{}; KernelCallback callback{};
callback.Reason = SendReason; callback.Reason = SendReason;
callback.AudioCallback.Send.Data = (uint8_t *)PCMRaw; callback.AudioCallback.Send.Data = (uint8_t *)PCMRaw;
callback.AudioCallback.Send.Length = pcm->node->Length; callback.AudioCallback.Send.Length = pcm.node->Length;
debug("Playing audio..."); debug("Playing audio...");
int status = DriverManager->IOCB(AudioDrv.DriverUID, &callback); int status = DriverManager->IOCB(AudioDrv.DriverUID, &callback);
debug("Audio played! %d", status); debug("Audio played! %d", status);
KernelAllocator.FreePages((void *)PCMRaw, TO_PAGES(pcm->node->Length + 1)); KernelAllocator.FreePages((void *)PCMRaw, TO_PAGES(pcm.node->Length + 1));
vfs->Close(pcm); vfs->Close(pcm);
TEXIT(0); TEXIT(0);
} }

View File

@ -125,15 +125,15 @@ namespace Execute
uintptr_t LoadELFInterpreter(Memory::MemMgr *mem, Memory::Virtual &pV, const char *Interpreter); uintptr_t LoadELFInterpreter(Memory::MemMgr *mem, Memory::Virtual &pV, const char *Interpreter);
ELFBaseLoad ELFLoadRel(void *ElfFile, ELFBaseLoad ELFLoadRel(void *ElfFile,
VirtualFileSystem::File *ExFile, VirtualFileSystem::File &ExFile,
Tasking::PCB *Process); Tasking::PCB *Process);
ELFBaseLoad ELFLoadExec(void *ElfFile, ELFBaseLoad ELFLoadExec(void *ElfFile,
VirtualFileSystem::File *ExFile, VirtualFileSystem::File &ExFile,
Tasking::PCB *Process); Tasking::PCB *Process);
ELFBaseLoad ELFLoadDyn(void *ElfFile, ELFBaseLoad ELFLoadDyn(void *ElfFile,
VirtualFileSystem::File *ExFile, VirtualFileSystem::File &ExFile,
Tasking::PCB *Process); Tasking::PCB *Process);
void StartExecuteService(); void StartExecuteService();

View File

@ -19,7 +19,6 @@
#define __FENNIX_KERNEL_FILESYSTEM_H__ #define __FENNIX_KERNEL_FILESYSTEM_H__
#include <types.h> #include <types.h>
#include <smart_ptr.hpp> #include <smart_ptr.hpp>
#include <vector> #include <vector>
@ -129,6 +128,8 @@ namespace VirtualFileSystem
char Name[FILENAME_LENGTH]; char Name[FILENAME_LENGTH];
FileStatus Status; FileStatus Status;
Node *node; Node *node;
bool IsOK() { return Status == FileStatus::OK; }
}; };
/* Manage / etc.. */ /* Manage / etc.. */
@ -140,7 +141,14 @@ namespace VirtualFileSystem
public: public:
std::shared_ptr<char> GetPathFromNode(Node *node); std::shared_ptr<char> GetPathFromNode(Node *node);
Node *GetNodeFromPath(const char *Path, Node *Parent = nullptr); Node *GetNodeFromPath(const char *Path, Node *Parent = nullptr);
std::shared_ptr<File> ConvertNodeToFILE(Node *node);
/**
* @brief Convert a Node to a File
*
* @param node Node to convert
* @return Converted node
*/
File ConvertNodeToFILE(Node *node);
Node *GetParent(const char *Path, Node *Parent); Node *GetParent(const char *Path, Node *Parent);
Node *GetRootNode() { return FileSystemRoot; } Node *GetRootNode() { return FileSystemRoot; }
@ -157,14 +165,14 @@ namespace VirtualFileSystem
FileStatus Delete(const char *Path, bool Recursive = false, Node *Parent = nullptr); FileStatus Delete(const char *Path, bool Recursive = false, Node *Parent = nullptr);
FileStatus Delete(Node *Path, bool Recursive = false, Node *Parent = nullptr); FileStatus Delete(Node *Path, bool Recursive = false, Node *Parent = nullptr);
std::shared_ptr<File> Mount(const char *Path, FileSystemOperations *Operator); File Mount(const char *Path, FileSystemOperations *Operator);
FileStatus Unmount(std::shared_ptr<File> File); FileStatus Unmount(File &File);
size_t Read(std::shared_ptr<File> File, size_t Offset, uint8_t *Buffer, size_t Size); size_t Read(File &File, size_t Offset, uint8_t *Buffer, size_t Size);
size_t Write(std::shared_ptr<File> File, size_t Offset, uint8_t *Buffer, size_t Size); size_t Write(File &File, size_t Offset, uint8_t *Buffer, size_t Size);
std::shared_ptr<File> Open(const char *Path, Node *Parent = nullptr); File Open(const char *Path, Node *Parent = nullptr);
FileStatus Close(std::shared_ptr<File> File); FileStatus Close(File &File);
Virtual(); Virtual();
~Virtual(); ~Virtual();