#pragma once // io_file.h - VFS layer // Filesystem drivers register an IO_FILESYSTEM vtable via IoRegisterFilesystem. // Kernel and user code open files through IoOpenFile. #include #include #include #include #include #include // --------------------------------------------------------------------------- // KDIR_ENTRY - one directory entry returned by ReadDir / SYS_READ_DIR // Attribute flags match FAT32/Win32: ATTR_DIRECTORY=0x10, ATTR_ARCHIVE=0x20 // --------------------------------------------------------------------------- #define KDIR_NAME_MAX 260 typedef struct KDIR_ENTRY { char Name[KDIR_NAME_MAX]; // null-terminated filename uint8_t Attr; // FAT attribute byte (0x10=dir, 0x20=file) uint32_t FileSize; // 0 for directories } KDIR_ENTRY; // Native asynchronous filesystem completion. Filesystems that provide // ReadAsync/WriteAsync accept the operation, return STATUS_PENDING, and later // call Complete(CompleteContext, status, information). Filesystems without // these callbacks fall back to the generic VFS async worker. typedef void (*IO_FS_ASYNC_COMPLETE)(void* completeContext, KSTATUS status, size_t information); // --------------------------------------------------------------------------- // Filesystem driver vtable - filled in by fat32.sys (or any future fs driver) // --------------------------------------------------------------------------- typedef struct IO_FILESYSTEM { // Open a file by absolute path (e.g. "apps\\shell.exe"). // Returns an opaque per-file driver cookie in* fileCtx. KSTATUS (*Open)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW path, void **fileCtx); // Read up to 'size' bytes at 'offset' into 'buf'. // Sets* bytesRead to actual bytes copied. KSTATUS (*Read)(struct IO_FILESYSTEM* fs, void* fileCtx, uint64_t offset, void* buf, size_t size, size_t* bytesRead); KSTATUS (*Write)(struct IO_FILESYSTEM* fs, void* fileCtx, uint64_t offset, const void* buf, size_t size, size_t* bytesWritten); KSTATUS (*ReadAsync)(struct IO_FILESYSTEM* fs, void* fileCtx, uint64_t offset, void* buf, size_t size, IO_FS_ASYNC_COMPLETE complete, void* completeContext); KSTATUS (*WriteAsync)(struct IO_FILESYSTEM* fs, void* fileCtx, uint64_t offset, const void* buf, size_t size, IO_FS_ASYNC_COMPLETE complete, void* completeContext); // Create a new file at 'path'; returns an open fileCtx on success. KSTATUS (*Create)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW path, void** fileCtx); // Delete the file at 'path'. KSTATUS (*Delete)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW path); // Rename or move a file/directory within the same filesystem. KSTATUS (*Rename)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW oldPath, SYS_STRING_VIEW newPath); // Create or remove directories. KSTATUS (*CreateDir)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW path); KSTATUS (*RemoveDir)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW path); // Truncate or extend the file to exactly 'newSize' bytes. KSTATUS (*Truncate)(struct IO_FILESYSTEM* fs, void* fileCtx, uint64_t newSize); // Return the file size in bytes. uint64_t (*GetSize)(struct IO_FILESYSTEM* fs, void* fileCtx); // Release any resources the driver allocated for fileCtx. void (*Close)(struct IO_FILESYSTEM* fs, void* fileCtx); // Optional driver-private data. void* DriverCtx; // --------------------------------------------------------------------------- // Directory enumeration (optional - may be NULL if not supported) // --------------------------------------------------------------------------- // Open a directory iterator for 'dirPath' (relative or drive-prefixed). // Returns an opaque per-iteration driver cookie in *dirCtx. KSTATUS (*OpenDir)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW dirPath, void** dirCtx); // Advance to the next entry. // Fills 'out' with name, attributes, and size. // Returns STATUS_NO_MORE_FILES when the directory is exhausted. KSTATUS (*ReadDir)(struct IO_FILESYSTEM* fs, void* dirCtx, struct KDIR_ENTRY* out); // Release resources allocated by OpenDir. void (*CloseDir)(struct IO_FILESYSTEM* fs, void* dirCtx); } IO_FILESYSTEM; // --------------------------------------------------------------------------- // IO_STATUS_BLOCK - completion status visible to async callers // --------------------------------------------------------------------------- typedef struct IO_STATUS_BLOCK { volatile KSTATUS Status; volatile size_t Information; } IO_STATUS_BLOCK; struct EVENT; struct KAPC; typedef struct IO_ASYNC_FILE_REQUEST_OBJECT IO_ASYNC_FILE_REQUEST_OBJECT; // --------------------------------------------------------------------------- // FILE_OBJECT - the kernel object returned to callers // --------------------------------------------------------------------------- typedef struct FILE_OBJECT { OBJECT Header; // must be first IO_FILESYSTEM* Fs; void* FileCtx; // driver cookie SPINLOCK Lock; // protects cached Size/Offset updates uint64_t Size; uint64_t Offset; // current position for sequential reads } FILE_OBJECT; // --------------------------------------------------------------------------- // DIR_OBJECT - kernel object for an open directory iterator // --------------------------------------------------------------------------- typedef struct DIR_OBJECT { OBJECT Header; // must be first IO_FILESYSTEM* Fs; void* DirCtx; // driver cookie (opaque iteration state) } DIR_OBJECT; typedef struct IO_VOLUME_PARAMS { uint8_t DiskIndex; // registered disk DEVICE_OBJECT index uint64_t PartitionLba; // starting LBA of this partition uint64_t PartitionSize; // sectors, for bounds checking } IO_VOLUME_PARAMS; // --------------------------------------------------------------------------- // Registration - called by fat32.sys from DriverEntry // --------------------------------------------------------------------------- // driveIndex matches the index passed to IoRegisterDiskDevice. __declspec(dllexport) KSTATUS IoRegisterFilesystem(uint8_t driveIndex, IO_FILESYSTEM* fs, const IO_VOLUME_PARAMS *vol); // --------------------------------------------------------------------------- // Kernel-side API // --------------------------------------------------------------------------- __declspec(dllexport) KSTATUS IoOpenFile(SYS_STRING_VIEW path, FILE_OBJECT **out); __declspec(dllexport) KSTATUS IoReadFile(FILE_OBJECT* file, void* buf, size_t size, size_t* bytesRead); __declspec(dllexport) KSTATUS IoReadFileAt(FILE_OBJECT* file, uint64_t offset, void* buf, size_t size, size_t* bytesRead); __declspec(dllexport) KSTATUS IoWriteFile (FILE_OBJECT* file, const void* buf, size_t size, size_t* bytesWritten); __declspec(dllexport) KSTATUS IoWriteFileAt(FILE_OBJECT* file, uint64_t offset, const void* buf, size_t size, size_t* bytesWritten); __declspec(dllexport) KSTATUS IoReadFileAsyncKernel(FILE_OBJECT* file, void* buf, size_t size, uint64_t offset, IO_STATUS_BLOCK* iosb, struct EVENT* completionEvent, struct KAPC* completionApc, IO_ASYNC_FILE_REQUEST_OBJECT** requestOut); __declspec(dllexport) KSTATUS IoWriteFileAsyncKernel(FILE_OBJECT* file, const void* buf, size_t size, uint64_t offset, IO_STATUS_BLOCK* iosb, struct EVENT* completionEvent, struct KAPC* completionApc, IO_ASYNC_FILE_REQUEST_OBJECT** requestOut); __declspec(dllexport) OBJECT* IoAsyncFileRequestObject(IO_ASYNC_FILE_REQUEST_OBJECT* request); __declspec(dllexport) KSTATUS IoCancelAsyncFileRequest(IO_ASYNC_FILE_REQUEST_OBJECT* request); __declspec(dllexport) KSTATUS IoQueryAsyncFileRequest(IO_ASYNC_FILE_REQUEST_OBJECT* request, IO_STATUS_BLOCK* iosbOut); __declspec(dllexport) KSTATUS IoCreateFile (SYS_STRING_VIEW path, FILE_OBJECT** out); __declspec(dllexport) KSTATUS IoDeleteFile (SYS_STRING_VIEW path); __declspec(dllexport) KSTATUS IoRenameFile (SYS_STRING_VIEW oldPath, SYS_STRING_VIEW newPath); __declspec(dllexport) KSTATUS IoCreateDir (SYS_STRING_VIEW path); __declspec(dllexport) KSTATUS IoRemoveDir (SYS_STRING_VIEW path); __declspec(dllexport) KSTATUS IoTruncateFile(FILE_OBJECT* file, uint64_t newSize); __declspec(dllexport) KSTATUS IoSeekFile(FILE_OBJECT* file, uint64_t offset); __declspec(dllexport) uint64_t IoGetFileSize(FILE_OBJECT* file); __declspec(dllexport) void IoCloseFile(FILE_OBJECT* file); // --------------------------------------------------------------------------- // Directory enumeration API // --------------------------------------------------------------------------- __declspec(dllexport) KSTATUS IoOpenDir (SYS_STRING_VIEW dirPath, DIR_OBJECT** out); __declspec(dllexport) KSTATUS IoReadDir (DIR_OBJECT* dir, KDIR_ENTRY* entryOut); __declspec(dllexport) void IoCloseDir(DIR_OBJECT* dir); // --------------------------------------------------------------------------- // Current Working Directory // --------------------------------------------------------------------------- __declspec(dllexport) KSTATUS IoSetCwd(SYS_STRING_VIEW path); __declspec(dllexport) KSTATUS IoGetCwd(char* buf, size_t size);