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
@@ -0,0 +1,114 @@
|
||||
// io_device.c - kernel driver/device dispatch and disk registry
|
||||
#include <string.h>
|
||||
#include <io_driver.h>
|
||||
#include <ke_irp.h>
|
||||
#include <mm_virt.h>
|
||||
|
||||
#define MAX_DISK_DEVICES 8
|
||||
|
||||
static DEVICE_OBJECT* gDiskDevices[MAX_DISK_DEVICES];
|
||||
|
||||
__declspec(dllexport) KSTATUS IoCreateDevice(DRIVER_OBJECT* driver,
|
||||
size_t extensionSize,
|
||||
DEVICE_OBJECT** outDevice) {
|
||||
if (!driver || !outDevice) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
size_t total = sizeof(DEVICE_OBJECT) + extensionSize;
|
||||
DEVICE_OBJECT* dev = (DEVICE_OBJECT*)MmAllocatePool(total);
|
||||
if (!dev) return STATUS_NO_MEMORY;
|
||||
|
||||
memset(dev, 0, total);
|
||||
dev->DriverObject = driver;
|
||||
if (extensionSize)
|
||||
dev->DeviceExtension = (void*)((uint8_t*)dev + sizeof(DEVICE_OBJECT));
|
||||
dev->AlignmentRequirement = 1;
|
||||
dev->DiskIndex = 0xFF;
|
||||
|
||||
*outDevice = dev;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
__declspec(dllexport) void IoDeleteDevice(DEVICE_OBJECT* device) {
|
||||
if (!device) return;
|
||||
MmFreePool(device);
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS IoRegisterDiskDevice(uint8_t driveIndex,
|
||||
DEVICE_OBJECT* device) {
|
||||
if (driveIndex >= MAX_DISK_DEVICES || !device || !device->DriverObject)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (gDiskDevices[driveIndex])
|
||||
return STATUS_ALREADY_EXISTS;
|
||||
|
||||
device->Flags |= DEVICE_OBJECT_DISK;
|
||||
device->DiskIndex = driveIndex;
|
||||
gDiskDevices[driveIndex] = device;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
__declspec(dllexport) DEVICE_OBJECT* IoGetDiskDevice(uint8_t driveIndex) {
|
||||
if (driveIndex >= MAX_DISK_DEVICES) return (DEVICE_OBJECT*)0;
|
||||
return gDiskDevices[driveIndex];
|
||||
}
|
||||
|
||||
__declspec(dllexport) bool IoDiskDevicePresent(uint8_t driveIndex) {
|
||||
return IoGetDiskDevice(driveIndex) != (DEVICE_OBJECT*)0;
|
||||
}
|
||||
|
||||
__declspec(dllexport) uint64_t IoDiskSectorCount(uint8_t driveIndex) {
|
||||
DEVICE_OBJECT* dev = IoGetDiskDevice(driveIndex);
|
||||
return dev ? dev->SectorCount : 0;
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS IoCallDriver(DEVICE_OBJECT* device, IRP* irp) {
|
||||
if (!device || !device->DriverObject || !irp)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
IO_MAJOR_FUNCTION major = (irp->Flags & IRP_FLAG_WRITE) ? IRP_MJ_WRITE : IRP_MJ_READ;
|
||||
if (major >= IRP_MJ_MAXIMUM_FUNCTION)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
PDRIVER_DISPATCH dispatch = device->DriverObject->MajorFunction[major];
|
||||
if (!dispatch)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
|
||||
return dispatch(device, irp);
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS IoReadDiskSectors(uint8_t driveIndex,
|
||||
uint64_t lba,
|
||||
uint32_t count,
|
||||
void* buffer) {
|
||||
if (!buffer || count == 0) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
IRP irp;
|
||||
memset(&irp, 0, sizeof(irp));
|
||||
irp.DriveIndex = driveIndex;
|
||||
irp.Flags = 0;
|
||||
irp.Lba = lba;
|
||||
irp.SectorCount = count;
|
||||
irp.Buffer = buffer;
|
||||
irp.Status = STATUS_FAILURE;
|
||||
irp.Information = 0;
|
||||
|
||||
return IoSubmitIrpSync(&irp);
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS IoWriteDiskSectors(uint8_t driveIndex,
|
||||
uint64_t lba,
|
||||
uint32_t count,
|
||||
const void* buffer) {
|
||||
if (!buffer || count == 0) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
IRP irp;
|
||||
memset(&irp, 0, sizeof(irp));
|
||||
irp.DriveIndex = driveIndex;
|
||||
irp.Flags = IRP_FLAG_WRITE;
|
||||
irp.Lba = lba;
|
||||
irp.SectorCount = count;
|
||||
irp.Buffer = (void*)buffer;
|
||||
irp.Status = STATUS_FAILURE;
|
||||
irp.Information = 0;
|
||||
|
||||
return IoSubmitIrpSync(&irp);
|
||||
}
|
||||
Reference in new issue
Block a user