228 lines
7.7 KiB
C
228 lines
7.7 KiB
C
// 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 <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <ntlite/status.h>
|
|
#include <ntlite/ddk/list.h>
|
|
#include <ntlite/ddk/sync.h>
|
|
|
|
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);
|