(wdm.h) 的 IRP 结构
IRP 结构是表示 I/O 请求数据包的部分不透明结构。 驱动程序可以使用 IRP 结构的以下成员。
语法
typedef struct _IRP {
CSHORT Type;
USHORT Size;
PMDL MdlAddress;
ULONG Flags;
union {
struct _IRP *MasterIrp;
__volatile LONG IrpCount;
PVOID SystemBuffer;
} AssociatedIrp;
LIST_ENTRY ThreadListEntry;
IO_STATUS_BLOCK IoStatus;
KPROCESSOR_MODE RequestorMode;
BOOLEAN PendingReturned;
CHAR StackCount;
CHAR CurrentLocation;
BOOLEAN Cancel;
KIRQL CancelIrql;
CCHAR ApcEnvironment;
UCHAR AllocationFlags;
union {
PIO_STATUS_BLOCK UserIosb;
PVOID IoRingContext;
};
PKEVENT UserEvent;
union {
struct {
union {
PIO_APC_ROUTINE UserApcRoutine;
PVOID IssuingProcess;
};
union {
PVOID UserApcContext;
#if ...
_IORING_OBJECT *IoRing;
#else
struct _IORING_OBJECT *IoRing;
#endif
};
} AsynchronousParameters;
LARGE_INTEGER AllocationSize;
} Overlay;
__volatile PDRIVER_CANCEL CancelRoutine;
PVOID UserBuffer;
union {
struct {
union {
KDEVICE_QUEUE_ENTRY DeviceQueueEntry;
struct {
PVOID DriverContext[4];
};
};
PETHREAD Thread;
PCHAR AuxiliaryBuffer;
struct {
LIST_ENTRY ListEntry;
union {
struct _IO_STACK_LOCATION *CurrentStackLocation;
ULONG PacketType;
};
};
PFILE_OBJECT OriginalFileObject;
} Overlay;
KAPC Apc;
PVOID CompletionKey;
} Tail;
} IRP;
成员
Type
Size
MdlAddress
指向描述用户缓冲区的 MDL 的指针(如果驱动程序使用直接 I/O,并且 IRP 主要函数代码为以下代码之一):
IRP_MJ_READ
MDL 描述设备或驱动程序填充的空缓冲区。
IRP_MJ_WRITE
MDL 描述包含设备或驱动程序数据的缓冲区。
IRP_MJ_DEVICE_CONTROL或IRP_MJ_INTERNAL_DEVICE_CONTROL
如果 IOCTL 代码指定METHOD_IN_DIRECT传输类型,则 MDL 描述包含设备或驱动程序数据的缓冲区。
如果 IOCTL 代码指定METHOD_OUT_DIRECT传输类型,则 MDL 描述设备或驱动程序填充的空缓冲区。
有关与 IOCTL 代码中的METHOD_IN_DIRECT和METHOD_OUT_DIRECT传输类型关联的缓冲区的详细信息,请参阅 I/O 控制代码的缓冲区说明。
如果驱动程序未使用直接 I/O,则此指针为 NULL。
Flags
文件系统驱动程序使用此字段,该字段对所有驱动程序都是只读的。 网络和可能的最高级别的设备驱动程序也可能读取此字段。 此字段设置为零,或设置为以下一个或多个系统定义的标志位的按位 OR:
IRP_NOCACHE
IRP_PAGING_IO
IRP_MOUNT_COMPLETION
IRP_SYNCHRONOUS_API
IRP_ASSOCIATED_IRP
IRP_BUFFERED_IO
IRP_DEALLOCATE_BUFFER
IRP_INPUT_OPERATION
IRP_SYNCHRONOUS_PAGING_IO
IRP_CREATE_OPERATION
IRP_READ_OPERATION
IRP_WRITE_OPERATION
IRP_CLOSE_OPERATION
IRP_DEFER_IO_COMPLETION
IRP_OB_QUERY_NAME
IRP_HOLD_DEVICE_QUEUE
IRP_UM_DRIVER_INITIATED_IO
AssociatedIrp
AssociatedIrp.MasterIrp
指向 IRP 中的主 IRP 的指针,该 IRP 由最高级别的驱动程序调用 IoMakeAssociatedIrp 创建。
AssociatedIrp.IrpCount
AssociatedIrp.SystemBuffer
指向系统空间缓冲区的指针。
如果驱动程序使用缓冲 I/O,则缓冲区的用途由 IRP 主要函数代码确定,如下所示:
SystemBuffer.IRP_MJ_READ
缓冲区从设备或驱动程序接收数据。 缓冲区的长度由驱动程序的 IO_STACK_LOCATION 结构中的 Parameters.Read.Length 指定。
NULL。
SystemBuffer.IRP_MJ_WRITE
缓冲区为设备或驱动程序提供数据。 缓冲区的长度由驱动程序的 IO_STACK_LOCATION 结构中的 Parameters.Write.Length 指定。
NULL。
SystemBuffer.IRP_MJ_DEVICE_CONTROL或IRP_MJ_INTERNAL_DEVICE_CONTROL
缓冲区表示提供给 DeviceIoControl 和 IoBuildDeviceIoControlRequest 的输入和输出缓冲区。 输出数据将覆盖输入数据。
对于输入,缓冲区的长度由驱动程序的 IO_STACK_LOCATION 结构中的 Parameters.DeviceIoControl.InputBufferLength 指定。
对于输出,缓冲区的长度由驱动程序的 IO_STACK_LOCATION 结构中的 Parameters.DeviceIoControl.OutputBufferLength 指定。
有关详细信息,请参阅 I/O 控制代码的缓冲区说明。
缓冲区表示提供给 DeviceIoControl 和 IoBuildDeviceIoControlRequest 的输入缓冲区。
缓冲区的长度由驱动程序的 IO_STACK_LOCATION 结构中的 Parameters.DeviceIoControl.InputBufferLength 指定。
有关详细信息,请参阅 I/O 控制代码的缓冲区说明。
如果驱动程序使用直接 I/O,则缓冲区的用途由 IRP 主要函数代码确定,如下所示:
ThreadListEntry
IoStatus
包含 IO_STATUS_BLOCK 结构,其中驱动程序在调用 IoCompleteRequest 之前存储状态和信息。
RequestorMode
指示操作的原始请求者的执行模式, 即 UserMode 或 KernelMode 之一。
PendingReturned
如果设置为 TRUE,则驱动程序已将 IRP 标记为挂起。 每个 IoCompletion 例程都应检查此标志的值。 如果标志为 TRUE,并且 IoCompletion 例程不会返回STATUS_MORE_PROCESSING_REQUIRED,则例程应调用 IoMarkIrpPending 以将挂起状态传播到设备堆栈中高于它的驱动程序。
StackCount
CurrentLocation
Cancel
如果设置为 TRUE,则 IRP 为 或 应取消。
CancelIrql
包含调用 IoAcquireCancelSpinLock 时驱动程序运行的 IRQL。
ApcEnvironment
AllocationFlags
UserIosb
IoRingContext
UserEvent
Overlay
Overlay.AsynchronousParameters
Overlay.AsynchronousParameters.UserApcRoutine
Overlay.AsynchronousParameters.IssuingProcess
Overlay.AsynchronousParameters.UserApcContext
Overlay.AsynchronousParameters.IoRing
Overlay.AllocationSize
CancelRoutine
包含驱动程序提供的 取消 例程的入口点,如果取消 IRP,则调用该例程。 NULL 表示 IRP 当前不可取消。
UserBuffer
如果以下两个条件都适用,则包含输出缓冲区的地址:
- I/O 堆栈位置中的主要函数代码是 IRP_MJ_DEVICE_CONTROL 或 IRP_MJ_INTERNAL_DEVICE_CONTROL。
- I/O 控制代码是使用 METHOD_NEITHER 或 METHOD_BUFFERED 定义的。
Tail
Tail.Overlay
Tail.Overlay.DeviceQueueEntry
如果 IRP 在与驱动程序的设备对象关联的设备队列中排队,则此字段将链接设备队列中的 IRP。 这些链接只能在驱动程序处理 IRP 时使用。
Tail.Overlay.DriverContext[4]
如果 IRP 未在与驱动程序的设备对象关联的设备队列中排队,驱动程序可以使用此字段来存储最多四个指针。 仅当驱动程序拥有 IRP 时,才能使用此字段。
Tail.Overlay.Thread
指向调用方线程控制块的指针 (TCB) 。 对于源自用户模式的请求,I/O 管理器始终将此字段设置为指向发出请求的线程的 TCB。
Tail.Overlay.AuxiliaryBuffer
Tail.Overlay.ListEntry
如果驱动程序管理其自己的 IRP 内部队列,它将使用此字段将一个 IRP 链接到下一个 IRP。 仅当驱动程序在其队列中保存 IRP 或正在处理 IRP 时,才能使用这些链接。
Tail.Overlay.CurrentStackLocation
Tail.Overlay.PacketType
Tail.Overlay.OriginalFileObject
Tail.Apc
Tail.CompletionKey
注解
IRP 结构的未记录成员是保留的,仅由 I/O 管理器使用,在某些情况下由 FSD 使用。
IRP 是用于与驱动程序通信并允许驱动程序相互通信的基本 I/O 管理器结构。 数据包由两个不同的部分组成:
- 标头,或 数据包的固定部分 - I/O 管理器使用此来存储有关原始请求的信息,例如调用方与设备无关的参数、打开文件的设备对象的地址等。 驱动程序还使用它来存储信息,例如请求的最终状态。
- I/O 堆栈位置 - 标头后面的是一组 I/O 堆栈位置,每个驱动程序在绑定请求的分层驱动程序链中各一个。 每个堆栈位置都包含相应的驱动程序用来确定其应执行的操作的参数、函数代码和上下文。 有关详细信息,请参阅 IO_STACK_LOCATION 结构。
要求
标头 | wdm.h(包括 Wdm.h、Ntddk.h、Ntifs.h) |