i think it works
This commit is contained in:
commit
0e1479b168
167 files changed
+27008
No files matched your search
@@ -0,0 +1,113 @@
|
||||
// io_file.c - VFS dispatch layer
|
||||
#include "ke_list.h"
|
||||
#include "io_file.h"
|
||||
#include "mm_virt.h"
|
||||
#include "ob_object.h"
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_DRIVES 8
|
||||
|
||||
typedef struct {
|
||||
IO_FILESYSTEM *Fs;
|
||||
IO_VOLUME_PARAMS Vol;
|
||||
} VOLUME_ENTRY;
|
||||
|
||||
static VOLUME_ENTRY gVolumes[MAX_DRIVES];
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Registration
|
||||
// ---------------------------------------------------------------------------
|
||||
KSTATUS IoRegisterFilesystem(uint8_t volumeIndex,
|
||||
IO_FILESYSTEM *fs,
|
||||
const IO_VOLUME_PARAMS *vol) {
|
||||
if (volumeIndex >= MAX_DRIVES || !fs || !vol)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (gVolumes[volumeIndex].Fs)
|
||||
return STATUS_ALREADY_EXISTS;
|
||||
gVolumes[volumeIndex].Fs = fs;
|
||||
gVolumes[volumeIndex].Vol = *vol;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Path parsing - "0:\apps\shell.exe" or just "apps\shell.exe" (drive 0)
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint8_t ParseDrive(const char* path, const char **pathOut) {
|
||||
// Accept "N:\..." prefix, otherwise default to drive 0.
|
||||
if (path[0] >= '0' && path[0] <= '7' &&
|
||||
path[1] == ':' && (path[2] == '\\' || path[2] == '/')) {
|
||||
*pathOut = path + 3;
|
||||
return (uint8_t)(path[0] - '0');
|
||||
}
|
||||
*pathOut = path;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Destructor
|
||||
// ---------------------------------------------------------------------------
|
||||
static void FileDestroy(OBJECT* obj) {
|
||||
FILE_OBJECT* f = CONTAINING_RECORD(obj, FILE_OBJECT, Header);
|
||||
if (f->Fs && f->FileCtx) f->Fs->Close(f->Fs, f->FileCtx);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// IoOpenFile
|
||||
// ---------------------------------------------------------------------------
|
||||
KSTATUS IoOpenFile(const char* path, FILE_OBJECT **out) {
|
||||
if (!path || !out) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
const char* relPath;
|
||||
uint8_t drive = ParseDrive(path, &relPath);
|
||||
|
||||
IO_FILESYSTEM* fs = gVolumes[drive].Fs;
|
||||
if (!fs) return STATUS_NOT_FOUND;
|
||||
|
||||
void* fileCtx;
|
||||
KSTATUS s = fs->Open(fs, relPath, &fileCtx);
|
||||
if (!KSUCCESS(s)) return s;
|
||||
|
||||
FILE_OBJECT* f = (FILE_OBJECT *)ObAllocateObject(ObjectTypeFile /* reuse slot */,
|
||||
sizeof(FILE_OBJECT));
|
||||
if (!f) { fs->Close(fs, fileCtx); return STATUS_NO_MEMORY; }
|
||||
f->Header.Destroy = FileDestroy;
|
||||
f->Fs = fs;
|
||||
f->FileCtx = fileCtx;
|
||||
f->Size = fs->GetSize(fs, fileCtx);
|
||||
f->Offset = 0;
|
||||
|
||||
*out = f;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// IoReadFile - sequential read at current offset
|
||||
// ---------------------------------------------------------------------------
|
||||
KSTATUS IoReadFile(FILE_OBJECT* file, void* buf, size_t size, size_t* bytesRead) {
|
||||
if (!file || !buf) return STATUS_INVALID_PARAMETER;
|
||||
if (file->Offset >= file->Size) { *bytesRead = 0; return STATUS_SUCCESS; }
|
||||
|
||||
// Clamp to remaining bytes.
|
||||
size_t remaining = (size_t)(file->Size - file->Offset);
|
||||
if (size > remaining) size = remaining;
|
||||
|
||||
KSTATUS s = file->Fs->Read(file->Fs, file->FileCtx,
|
||||
file->Offset, buf, size, bytesRead);
|
||||
if (KSUCCESS(s)) file->Offset += *bytesRead;
|
||||
return s;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
KSTATUS IoSeekFile(FILE_OBJECT* file, uint64_t offset) {
|
||||
if (!file) return STATUS_INVALID_PARAMETER;
|
||||
file->Offset = offset;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
uint64_t IoGetFileSize(FILE_OBJECT* file) {
|
||||
return file ? file->Size : 0;
|
||||
}
|
||||
|
||||
void IoCloseFile(FILE_OBJECT* file) {
|
||||
if (file) ObDereferenceObject(&file->Header);
|
||||
}
|
||||
Reference in new issue
Block a user