(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

缓冲区表示提供给 DeviceIoControlIoBuildDeviceIoControlRequest 的输入和输出缓冲区。 输出数据将覆盖输入数据。

对于输入,缓冲区的长度由驱动程序的 IO_STACK_LOCATION 结构中的 Parameters.DeviceIoControl.InputBufferLength 指定。

对于输出,缓冲区的长度由驱动程序的 IO_STACK_LOCATION 结构中的 Parameters.DeviceIoControl.OutputBufferLength 指定。

有关详细信息,请参阅 I/O 控制代码的缓冲区说明

缓冲区表示提供给 DeviceIoControlIoBuildDeviceIoControlRequest 的输入缓冲区。

缓冲区的长度由驱动程序的 IO_STACK_LOCATION 结构中的 Parameters.DeviceIoControl.InputBufferLength 指定。

有关详细信息,请参阅 I/O 控制代码的缓冲区说明

如果驱动程序使用直接 I/O,则缓冲区的用途由 IRP 主要函数代码确定,如下所示:

ThreadListEntry

IoStatus

包含 IO_STATUS_BLOCK 结构,其中驱动程序在调用 IoCompleteRequest 之前存储状态和信息。

RequestorMode

指示操作的原始请求者的执行模式, 即 UserModeKernelMode 之一。

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

如果以下两个条件都适用,则包含输出缓冲区的地址:

对于METHOD_BUFFERED,驱动程序应使用 Irp->AssociatedIrp.SystemBuffer 指向的缓冲区作为输出缓冲区。 驱动程序完成请求后,I/O 管理器将此缓冲区的内容复制到 Irp->UserBuffer 指向的输出缓冲区。 驱动程序不应直接写入 Irp->UserBuffer 指向的缓冲区。 有关详细信息,请参阅 I/O 控制代码的缓冲区说明

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 结构。
虽然较高级别的驱动程序可能检查 IRP 中 Cancel Boolean 的值,但即使该值为 TRUE,该驱动程序也不能假定 IRP 将由较低级别的驱动程序STATUS_CANCELLED完成。

要求

   
标头 wdm.h(包括 Wdm.h、Ntddk.h、Ntifs.h)

另请参阅

IO_STACK_LOCATION

IO_STATUS_BLOCK

IoCreateDevice

IoGetCurrentIrpStackLocation

IoGetNextIrpStackLocation

IoSetCancelRoutine

IoSetNextIrpStackLocation