// Public nt-lite legacy I/O driver declarations. #pragma once // io_driver.h - legacy kernel driver/device I/O model. // Device lifetime is owned by the I/O manager. Bus drivers create PDOs, // function/filter drivers attach FDOs, and PnP/remove IRPs tear stacks down. // Disk indexes are only a compatibility namespace above DEVICE_OBJECTs. #include #include #include #include #include #include #include #include typedef void (*DRIVER_UNLOAD_FN)(void); typedef struct DRIVER_OBJECT DRIVER_OBJECT; typedef struct DEVICE_OBJECT DEVICE_OBJECT; typedef struct IRP IRP; struct IO_DMA_ADAPTER; typedef KSTATUS (*PDRIVER_DISPATCH)(DEVICE_OBJECT* device, IRP* irp); typedef KSTATUS (*PDRIVER_ADD_DEVICE)(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject); // Bus / identity. typedef enum IO_BUS_TYPE { IoBusUnknown = 0, IoBusPci = 1, IoBusUsb = 2, } IO_BUS_TYPE; typedef struct IO_DEVICE_ID { IO_BUS_TYPE BusType; SYS_STRING_VIEW Id; } IO_DEVICE_ID; typedef struct IO_DRIVER_ID_TABLE { const IO_DEVICE_ID* Ids; size_t Count; } IO_DRIVER_ID_TABLE; #define IO_MAX_DEVICE_IDS 8u #define IO_MAX_DEVICE_ID_CHARS 96u #define IO_MAX_DEVICE_NAME_CHARS 64u // Driver/device objects. typedef enum DEVICE_OBJECT_TYPE { DeviceObjectPhysical = 1, DeviceObjectFunction = 2, DeviceObjectFilter = 3, } DEVICE_OBJECT_TYPE; typedef enum DEVICE_PNP_STATE { DevicePnpNotStarted = 0, DevicePnpStarted, DevicePnpStopPending, DevicePnpStopped, DevicePnpRemovePending, DevicePnpSurpriseRemoved, DevicePnpDeleted, } DEVICE_PNP_STATE; struct DRIVER_OBJECT { OBJECT Header; SYS_STRING_VIEW Name; PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION]; PDRIVER_ADD_DEVICE DriverAddDevice; DRIVER_UNLOAD_FN DriverUnload; const IO_DRIVER_ID_TABLE* IdTable; }; struct DEVICE_OBJECT { OBJECT Header; DRIVER_OBJECT* DriverObject; DEVICE_OBJECT_TYPE Type; DEVICE_PNP_STATE PnpState; DEVICE_OBJECT* Parent; DEVICE_OBJECT* FirstChild; DEVICE_OBJECT* NextSibling; DEVICE_OBJECT* AttachedDevice; // device directly above this object DEVICE_OBJECT* LowerDevice; // device directly below this FDO/filter void* DeviceExtension; struct IO_DMA_ADAPTER* DmaAdapter; uint32_t Flags; uint32_t Characteristics; uint32_t AlignmentRequirement; SPINLOCK Lock; volatile int32_t OutstandingIrps; bool DeletePending; SYS_STRING_VIEW Name; char NameStorage[IO_MAX_DEVICE_NAME_CHARS]; union { struct { IO_BUS_TYPE BusType; void* BusContext; void* DeviceContext; IO_DEVICE_ID Ids[IO_MAX_DEVICE_IDS]; char IdStorage[IO_MAX_DEVICE_IDS][IO_MAX_DEVICE_ID_CHARS]; uint8_t IdCount; } Pdo; struct { uint8_t DiskIndex; uint64_t SectorCount; uint32_t SectorSize; } Disk; } u; }; #define DEVICE_OBJECT_DISK 0x00000001u #define DEVICE_OBJECT_REMOVABLE 0x00000002u // Object/device creation and stack management. __declspec(dllexport) void IoInitializeDriverObject(DRIVER_OBJECT* driver, SYS_STRING_VIEW name); __declspec(dllexport) KSTATUS IoCreateDevice(DRIVER_OBJECT* driver, size_t extensionSize, DEVICE_OBJECT** outDevice); __declspec(dllexport) KSTATUS IoCreatePhysicalDevice(DRIVER_OBJECT* busDriver, DEVICE_OBJECT* parent, const IO_DEVICE_ID* ids, size_t idCount, size_t extensionSize, DEVICE_OBJECT** outPdo); __declspec(dllexport) KSTATUS IoRegisterPhysicalDevice(DEVICE_OBJECT* pdo); __declspec(dllexport) KSTATUS IoSetDeviceName(DEVICE_OBJECT* device, SYS_STRING_VIEW name); __declspec(dllexport) void IoReferenceDeviceObject(DEVICE_OBJECT* device); __declspec(dllexport) void IoDereferenceDeviceObject(DEVICE_OBJECT* device); __declspec(dllexport) void IoDeleteDevice(DEVICE_OBJECT* device); __declspec(dllexport) DEVICE_OBJECT* IoAttachDeviceToDeviceStack(DEVICE_OBJECT* source, DEVICE_OBJECT* target); __declspec(dllexport) void IoDetachDevice(DEVICE_OBJECT* source); __declspec(dllexport) DEVICE_OBJECT* IoGetAttachedDeviceReference(DEVICE_OBJECT* device); __declspec(dllexport) KSTATUS IoCallDriver(DEVICE_OBJECT* device, IRP* irp); __declspec(dllexport) KSTATUS IoForwardIrpToLower(DEVICE_OBJECT* device, IRP* irp); __declspec(dllexport) uint8_t IoGetDeviceStackSize(DEVICE_OBJECT* device); __declspec(dllexport) KSTATUS IoSendPnpIrpSync(DEVICE_OBJECT* device, IO_PNP_MINOR_FUNCTION minor); // Disk namespace above storage DEVICE_OBJECTs. typedef enum IO_DEVICE_CHANGE { IoDeviceArrived = 0, IoDeviceQueryRemove, IoDeviceSurpriseRemoved, IoDeviceRemoved, } IO_DEVICE_CHANGE; typedef void (*IO_DISK_CHANGE_CALLBACK)(uint8_t driveIndex, DEVICE_OBJECT* device, IO_DEVICE_CHANGE change, void* context); typedef void (*IO_DISK_ARRIVAL_CALLBACK)(uint8_t driveIndex, DEVICE_OBJECT* device, void* context); typedef struct IO_DISK_STATS { uint64_t RegisteredDisks; uint64_t ReadRequests; uint64_t ReadSectors; uint64_t WriteRequests; uint64_t WriteSectors; uint64_t MaxReadSectors; uint64_t MaxWriteSectors; } IO_DISK_STATS; __declspec(dllexport) KSTATUS IoRegisterDiskDevice(uint8_t driveIndex, DEVICE_OBJECT* device); __declspec(dllexport) KSTATUS IoNotifyDiskSurpriseRemoved(uint8_t driveIndex); __declspec(dllexport) KSTATUS IoUnregisterDiskDevice(uint8_t driveIndex); __declspec(dllexport) DEVICE_OBJECT* IoGetDiskDevice(uint8_t driveIndex); __declspec(dllexport) DEVICE_OBJECT* IoReferenceDiskDevice(uint8_t driveIndex); __declspec(dllexport) bool IoDiskDevicePresent(uint8_t driveIndex); __declspec(dllexport) uint64_t IoDiskSectorCount(uint8_t driveIndex); __declspec(dllexport) KSTATUS IoRegisterDiskArrivalCallback(IO_DISK_ARRIVAL_CALLBACK callback, void* context); __declspec(dllexport) KSTATUS IoRegisterDiskChangeCallback(IO_DISK_CHANGE_CALLBACK callback, void* context); __declspec(dllexport) KSTATUS IoEnumerateDiskDevices(IO_DISK_ARRIVAL_CALLBACK callback, void* context); // Dynamic partition discovery above registered block devices. Filesystem providers receive only immutable extents. typedef enum IO_PARTITION_CHANGE { IoPartitionArrived = 0, IoPartitionSurpriseRemoved, IoPartitionRemoved, } IO_PARTITION_CHANGE; typedef struct IO_PARTITION_INFO { uint8_t DiskIndex; uint64_t StartLba; uint64_t SectorCount; } IO_PARTITION_INFO; typedef void (*IO_PARTITION_CHANGE_CALLBACK)(const IO_PARTITION_INFO* partition, IO_PARTITION_CHANGE change, void* context); // Registers one partition-change consumer and replays every currently discovered partition before returning. __declspec(dllexport) KSTATUS IoRegisterPartitionChangeCallback(IO_PARTITION_CHANGE_CALLBACK callback, void* context); __declspec(dllexport) KSTATUS IoReadDiskSectors(uint8_t driveIndex, uint64_t lba, uint32_t count, void* buffer); __declspec(dllexport) KSTATUS IoWriteDiskSectors(uint8_t driveIndex, uint64_t lba, uint32_t count, const void* buffer); __declspec(dllexport) KSTATUS IoFlushDisk(uint8_t driveIndex); __declspec(dllexport) void IoQueryDiskStats(IO_DISK_STATS* out);