// Public nt-lite DDK IRP declarations. #pragma once // This is the legacy IRP shape made self-contained for DDK users. The next // architectural step is to hide this layout behind request accessors. #include #include #include #include #include #include struct EVENT; struct SEMAPHORE; struct KAPC; typedef struct DEVICE_OBJECT DEVICE_OBJECT; // IRP major functions. typedef enum IO_MAJOR_FUNCTION { IRP_MJ_CREATE = 0, IRP_MJ_CLOSE = 1, IRP_MJ_READ = 2, IRP_MJ_WRITE = 3, IRP_MJ_FLUSH_BUFFERS = 4, IRP_MJ_DEVICE_CONTROL = 5, IRP_MJ_INTERNAL_DEVICE_CONTROL = 6, IRP_MJ_PNP = 7, IRP_MJ_POWER = 8, IRP_MJ_MAXIMUM_FUNCTION = 9, } IO_MAJOR_FUNCTION; // PnP minor functions. typedef enum IO_PNP_MINOR_FUNCTION { IRP_MN_START_DEVICE = 0, IRP_MN_QUERY_REMOVE_DEVICE = 1, IRP_MN_CANCEL_REMOVE_DEVICE = 2, IRP_MN_SURPRISE_REMOVAL = 3, IRP_MN_REMOVE_DEVICE = 4, IRP_MN_QUERY_DEVICE_RELATIONS = 5, IRP_MN_QUERY_ID = 6, IRP_MN_QUERY_CAPABILITIES = 7, } IO_PNP_MINOR_FUNCTION; // Device relation query types. typedef enum IO_DEVICE_RELATION_TYPE { IoBusRelations = 0, IoRemovalRelations = 1, } IO_DEVICE_RELATION_TYPE; #define IRP_FLAG_PRIORITY (1u << 0) #define IRP_FLAG_CANCELLED (1u << 1) #define IRP_FLAG_COMPLETED (1u << 2) // Current public IRP stack location layout. typedef struct IO_STACK_LOCATION { IO_MAJOR_FUNCTION MajorFunction; uint8_t MinorFunction; DEVICE_OBJECT* DeviceObject; union { struct { uint64_t ByteOffset; uint32_t Length; } ReadWrite; struct { uint32_t IoControlCode; void* InputBuffer; uint32_t InputLength; void* OutputBuffer; uint32_t OutputLength; } DeviceIoControl; struct { IO_DEVICE_RELATION_TYPE RelationType; } QueryDeviceRelations; struct { uint32_t IdType; } QueryId; } Parameters; } IO_STACK_LOCATION; typedef struct IRP IRP; typedef void (*IRP_COMPLETION_FN)(IRP* irp, void* ctx); typedef void (*IRP_CANCEL_ROUTINE)(DEVICE_OBJECT* device, IRP* irp); // Current public IRP layout. typedef struct IRP { LIST_ENTRY Link; volatile KSTATUS Status; volatile size_t Information; uint32_t Flags; volatile bool Cancel; SPINLOCK CancelLock; KIRQL CancelIrql; IRP_CANCEL_ROUTINE CancelRoutine; struct EVENT* CompletionEvent; struct KAPC* CompletionApc; IRP_COMPLETION_FN CompletionFn; void* CompletionCtx; void* UserBuffer; void* SystemBuffer; uint8_t StackCount; uint8_t CurrentLocation; uint8_t HwSlot; void* DriverCtx; IO_STACK_LOCATION Stack[1]; } IRP; // Current remove-lock layout. typedef struct IO_REMOVE_LOCK { SPINLOCK Lock; volatile long IoCount; bool Removing; struct EVENT* RemovedEvent; } IO_REMOVE_LOCK; // Current per-driver IRP queue layout. typedef struct IRP_QUEUE { SPINLOCK Lock; LIST_ENTRY Head; struct SEMAPHORE* Semaphore; } IRP_QUEUE; typedef void (*IRP_QUEUE_CANCEL_CALLBACK)(IRP* irp, void* context); // Initializes a remove lock before it is used by a device. __declspec(dllexport) KSTATUS IoInitializeRemoveLock(IO_REMOVE_LOCK* lock); // Destroys a remove lock after the owning device has drained I/O. __declspec(dllexport) void IoDestroyRemoveLock(IO_REMOVE_LOCK* lock); // Acquires a remove lock for a request. __declspec(dllexport) KSTATUS IoAcquireRemoveLock(IO_REMOVE_LOCK* lock, IRP* irp); // Releases a remove lock for a request. __declspec(dllexport) void IoReleaseRemoveLock(IO_REMOVE_LOCK* lock, IRP* irp); // Releases a remove lock and waits for outstanding requests to drain. __declspec(dllexport) void IoReleaseRemoveLockAndWait(IO_REMOVE_LOCK* lock, IRP* removeIrp); // Initializes a driver-internal IRP queue. __declspec(dllexport) void IrpQueueInit(IRP_QUEUE* q, struct SEMAPHORE* sem); // Enqueues an IRP into a driver-internal queue. __declspec(dllexport) void IrpQueueEnqueue(IRP_QUEUE* q, IRP* irp); // Dequeues an IRP from a driver-internal queue. __declspec(dllexport) IRP* IrpQueueDequeue(IRP_QUEUE* q); // Cancels every IRP in a queue and invokes a callback for each one. __declspec(dllexport) void IrpQueueCancelAllWithCallback(IRP_QUEUE* q, KSTATUS status, IRP_QUEUE_CANCEL_CALLBACK callback, void* context); // Cancels every IRP in a queue. __declspec(dllexport) void IrpQueueCancelAll(IRP_QUEUE* q, KSTATUS status); // Allocates an IRP with the requested stack depth. __declspec(dllexport) KSTATUS IoAllocateIrp(uint8_t stackCount, IRP** outIrp); // Frees an IRP allocated by IoAllocateIrp. __declspec(dllexport) void IoFreeIrp(IRP* irp); // Reinitializes an existing IRP for reuse. __declspec(dllexport) void IoInitializeIrp(IRP* irp, uint8_t stackCount); // Returns the current IRP stack location. __declspec(dllexport) IO_STACK_LOCATION* IoGetCurrentIrpStackLocation(IRP* irp); // Returns the next lower IRP stack location. __declspec(dllexport) IO_STACK_LOCATION* IoGetNextIrpStackLocation(IRP* irp); // Advances the IRP without copying stack parameters. __declspec(dllexport) void IoSkipCurrentIrpStackLocation(IRP* irp); // Copies the current stack location to the next lower location. __declspec(dllexport) void IoCopyCurrentIrpStackLocationToNext(IRP* irp); // Registers a completion callback for an IRP. __declspec(dllexport) void IoSetCompletionRoutine(IRP* irp, IRP_COMPLETION_FN fn, void* ctx); // Sets the cancel routine and returns the previous one. __declspec(dllexport) IRP_CANCEL_ROUTINE IoSetCancelRoutine(IRP* irp, IRP_CANCEL_ROUTINE routine); // Marks an IRP cancelled and invokes its cancel routine when present. __declspec(dllexport) void IoCancelIrp(IRP* irp); // Builds a read or write IRP. __declspec(dllexport) void IoBuildReadWriteIrp(IRP* irp, IO_MAJOR_FUNCTION major, uint64_t byteOffset, uint32_t length, void* buffer); // Builds a PnP IRP. __declspec(dllexport) void IoBuildPnpIrp(IRP* irp, IO_PNP_MINOR_FUNCTION minor); // Builds a device-control IRP. __declspec(dllexport) void IoBuildDeviceIoControlIrp(IRP* irp, IO_MAJOR_FUNCTION major, uint32_t ioControlCode, void* inputBuffer, uint32_t inputLength, void* outputBuffer, uint32_t outputLength); // Completes an IRP exactly once. __declspec(dllexport) KSTATUS IoCompleteRequest(IRP* irp, KSTATUS status, size_t information); // Submits an IRP to a specific top-of-stack device object. __declspec(dllexport) KSTATUS IoSubmitIrp(DEVICE_OBJECT* device, IRP* irp); // Submits an IRP and waits for completion. __declspec(dllexport) KSTATUS IoSubmitIrpSync(DEVICE_OBJECT* device, IRP* irp);