implement proper IRQL, DPCs, kernel and user APCs, alertable waits, async file I/O with cancellation, trap frames, selftests, a real driver/device model, native async FAT32, VFAT dotfile fixes, syscall ABI cleanup, async_apc and async_cancel tests, POSIX multi-volume paths, and pimp the readme.
This commit is contained in:
1 parent
f5fd7bdd75
commit
529f816166
75 files changed
+9969
-5675
No files matched your search
+2
-93
@@ -1,93 +1,2 @@
|
||||
// hal_disk.c - drive registry; drivers register themselves via IoRegisterDisk.
|
||||
//
|
||||
// This file lives in the HAL layer and must NOT reference any kernel sync
|
||||
// objects (KeEventCreate, KeSignalEvent, KeWaitForEvent, ObDereferenceObject).
|
||||
// All IRP event signalling is done in kernel/ke_irp.c, which sits above us
|
||||
// in the dependency graph.
|
||||
//
|
||||
// HalDiskDispatch is the one bridge: it calls the driver's SubmitIrp (async)
|
||||
// or runs the sync callbacks inline and writes irp->Status. It does not
|
||||
// touch irp->CompletionEvent - that is ke_irp.c's responsibility.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <hal_api.h>
|
||||
#include <io_driver.h>
|
||||
#include <ke_irp.h>
|
||||
|
||||
#define MAX_DRIVES 8
|
||||
|
||||
static DISK_DRIVER gDrives[MAX_DRIVES];
|
||||
static bool gPresent[MAX_DRIVES];
|
||||
|
||||
__declspec(dllexport) KSTATUS IoRegisterDisk(uint8_t index, const DISK_DRIVER *driver) {
|
||||
if (index >= MAX_DRIVES || !driver) return STATUS_INVALID_PARAMETER;
|
||||
if (gPresent[index]) return STATUS_ALREADY_EXISTS;
|
||||
gDrives[index] = *driver;
|
||||
gPresent[index] = true;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// HalDiskDispatch - called exclusively by ke_irp.c::IoSubmitIrp()
|
||||
// -------------------------------------------------------------------------
|
||||
// Separating dispatch here keeps hal_disk.c free of event primitives while
|
||||
// still allowing ke_irp.c (kernel layer) to fire completion hooks after we
|
||||
// return.
|
||||
//
|
||||
// Returns STATUS_PENDING - driver accepted the IRP asynchronously.
|
||||
// ke_irp.c must NOT touch irp->CompletionEvent
|
||||
// yet; the driver will fire it.
|
||||
// Returns STATUS_SUCCESS - sync fallback ran; irp->Status is already
|
||||
// written. ke_irp.c should fire completion hooks.
|
||||
// Returns STATUS_NOT_FOUND - drive not registered.
|
||||
|
||||
__declspec(dllexport) KSTATUS HalDiskDispatch(uint8_t drive, IRP *irp) {
|
||||
if (drive >= MAX_DRIVES || !gPresent[drive]) return STATUS_NOT_FOUND;
|
||||
DISK_DRIVER *drv = &gDrives[drive];
|
||||
|
||||
if (drv->SubmitIrp)
|
||||
return drv->SubmitIrp(drv->Ctx, irp); // STATUS_PENDING
|
||||
|
||||
// Sync fallback: execute inline, write result, let caller fire hooks.
|
||||
bool write = !!(irp->Flags & IRP_FLAG_WRITE);
|
||||
if (write)
|
||||
irp->Status = drv->WriteSectors(drv->Ctx, irp->Lba, irp->SectorCount, irp->Buffer);
|
||||
else
|
||||
irp->Status = drv->ReadSectors (drv->Ctx, irp->Lba, irp->SectorCount, irp->Buffer);
|
||||
|
||||
return STATUS_SUCCESS; // ran synchronously
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Legacy HAL_DISK vtable - direct sync calls, no IRP involvement.
|
||||
// Existing callers (FAT32, shell) use this path unchanged.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
static KSTATUS DiskRead(uint8_t drive, uint64_t lba,
|
||||
uint32_t count, void *buf) {
|
||||
if (drive >= MAX_DRIVES || !gPresent[drive]) return STATUS_NOT_FOUND;
|
||||
return gDrives[drive].ReadSectors(gDrives[drive].Ctx, lba, count, buf);
|
||||
}
|
||||
|
||||
static KSTATUS DiskWrite(uint8_t drive, uint64_t lba,
|
||||
uint32_t count, const void *buf) {
|
||||
if (drive >= MAX_DRIVES || !gPresent[drive]) return STATUS_NOT_FOUND;
|
||||
return gDrives[drive].WriteSectors(gDrives[drive].Ctx, lba, count, buf);
|
||||
}
|
||||
|
||||
static bool DiskPresent(uint8_t drive) {
|
||||
return drive < MAX_DRIVES && gPresent[drive];
|
||||
}
|
||||
|
||||
static uint64_t DiskSectorCount(uint8_t drive) {
|
||||
if (drive >= MAX_DRIVES || !gPresent[drive]) return 0;
|
||||
return gDrives[drive].SectorCount;
|
||||
}
|
||||
|
||||
void HalDiskInitialize(HAL_DISK *out) {
|
||||
out->ReadSectors = DiskRead;
|
||||
out->WriteSectors = DiskWrite;
|
||||
out->DrivePresent = DiskPresent;
|
||||
out->DriveSectorCount = DiskSectorCount;
|
||||
}
|
||||
// hal_disk.c intentionally left empty.
|
||||
// Disk registration and dispatch live in kernel/io_device.c.
|
||||
Reference in new issue
Block a user