/* * Vfs.hpp * Virtual File System with numerical logical drive identifiers * Copyright (c) 2025 Daniel Hammer */ #pragma once #include #include namespace Fs::Vfs { static constexpr int MaxDrives = 16; struct BackendFile { int driveNumber; int localHandle; uint32_t generation; }; // Metadata for a single path, filled by FsDriver::Stat. Timestamps are UTC // unix seconds; a filesystem that does not record a given time leaves it 0. struct StatInfo { uint64_t size; // file size in bytes int64_t mtime; // last data modification time int64_t ctime; // last inode (metadata) change time int64_t atime; // last access time uint32_t mode; // ext2/POSIX i_mode bits (type + permissions) bool isDir; // true if the entry is a directory }; struct FsDriver { int (*Open)(const char* path); int (*Read)(int handle, uint8_t* buffer, uint64_t offset, uint64_t size); uint64_t (*GetSize)(int handle); void (*Close)(int handle); int (*ReadDir)(const char* path, const char** outNames, int maxEntries); int (*Write)(int handle, const uint8_t* buffer, uint64_t offset, uint64_t size); int (*Create)(const char* path); int (*Delete)(const char* path); int (*Mkdir)(const char* path); int (*Rename)(const char* oldPath, const char* newPath); const char* (*GetLabel)(); // Optional: paginated directory read returning entries [startIndex, startIndex+maxEntries). // Drivers that leave this null are read via ReadDir at startIndex 0 only. int (*ReadDirAt)(const char* path, const char** outNames, int maxEntries, int startIndex); // Optional: fill metadata for a path. Drivers that leave this null do // not support stat and VfsStat returns -1 for their paths. int (*Stat)(const char* path, StatInfo* out); }; void Initialize(); bool IsInitialized(); int RegisterDrive(int driveNumber, FsDriver* driver); int UnregisterDrive(int driveNumber); bool IsDriveRegistered(int driveNumber); int FindLowestAvailableDrive(int firstDrive = 0); int OpenBackendFile(const char* path, BackendFile& outFile); int CreateBackendFile(const char* path, BackendFile& outFile); int ReadBackendFile(const BackendFile& file, uint8_t* buffer, uint64_t offset, uint64_t size); int WriteBackendFile(const BackendFile& file, const uint8_t* buffer, uint64_t offset, uint64_t size); uint64_t GetBackendFileSize(const BackendFile& file); bool BackendFileCanWrite(const BackendFile& file); void CloseBackendFile(BackendFile& file); int VfsDelete(const char* path); int VfsStat(const char* path, StatInfo& out); int VfsReadDir(const char* path, const char** outNames, int maxEntries); int VfsReadDirAt(const char* path, const char** outNames, int maxEntries, int startIndex); int VfsMkdir(const char* path); int VfsRename(const char* oldPath, const char* newPath); // Returns number of registered drives, fills outDrives[] with their indices int VfsDriveList(int* outDrives, int maxEntries); int VfsDriveLabel(int driveNumber, char* outLabel, int maxLen); }