IRP

IRP

IRP 结构体部分不透明,它代表了一个IO请求包。驱动程序可以使用结构的以下成员:

typedef struct _IRP {

  .

  .

  PMDL  MdlAddress;

  ULONG  Flags;

  union {

    struct _IRP  *MasterIrp;

    .

    .

    PVOID  SystemBuffer;

  } AssociatedIrp;

  .

  .

  IO_STATUS_BLOCK  IoStatus;

  KPROCESSOR_MODE  RequestorMode;

  BOOLEAN PendingReturned;

  .

  .

  BOOLEAN  Cancel;

  KIRQL  CancelIrql;

  .

  .

  PDRIVER_CANCEL  CancelRoutine;

  PVOID UserBuffer;

  union {

    struct {

    .

    .

    union {

      KDEVICE_QUEUE_ENTRY DeviceQueueEntry;

      struct {

        PVOID  DriverContext[4];

      };

    };

    .

    .

    PETHREAD  Thread;

    .

    .

    LIST_ENTRY  ListEntry;

    .

    .

    } Overlay;

  .

  .

  } Tail;

} IRP, *PIRP;    

   

Members

MdlAddress

指向描述用户缓冲区的MDL指针,如果驱动程序使用直接IO,并且IRP 主功能号是以下之一:

IRP_MJ_READ

MDL 描述了一个供设备或者驱动填入的缓冲区。

IRP_MJ_WRITE

MDL 描述了要写入到设备或者驱动程序中的缓冲区。

IRP_MJ_DEVICE_CONTROL or IRP_MJ_INTERNAL_DEVICE_CONTROL

如果IOCTL code 指定了METHOD_IN_DIRECT 传输类型, MDL 描述了一个为设备和驱动提供的包含数据的缓冲区。

如果IOCTL code 指定了METHOD_OUT_DIRECT 传输类型,MDL描述了一个供设备或者驱动程序填入的空的缓冲区。

有关METHOD_IN_DIRECT METHOD_OUT_DIRECT传输类型关联的缓冲区信息,见Buffer Descriptions for I/O Control Codes.

如果驱动程序不使用直接IO,那么这个指针为NULL。

Flags

文件系统使用这一块,对所有的驱动程序而言都是只读的。网络和可能的高层设备驱动也可能读取这一块的数据。这块数据可能设置为0或者是按位与的以下系统定义的符号位:

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.MasterIrp

指向高层驱动程序调用 IoMakeAssociatedIrp创建的IRP中的主IRP。

AssociatedIrp.SystemBuffer

指向系统空间的缓冲区。如果驱动程序使用了缓冲I/O,此缓冲区的目的屈居于IRP主功能号,如下所示:

IRP_MJ_READ

缓冲区从设备和驱动程序获取数据。长度由驱动程序结构中的IO_STACK_LOCATION Parameters.Read.Length 成员指定。

IRP_MJ_WRITE

此缓冲区用于为设备或驱动程序提供数据。驱动程序的IO_STACK_LOCATION  Parameters.Write.Length 成员指定了缓冲区的长度。

IRP_MJ_DEVICE_CONTROL or IRP_MJ_INTERNAL_DEVICE_CONTROL

此参数代表提供给 DeviceIoControl IoBuildDeviceIoControlRequest.函数的输入和输出缓冲区,输出数据覆盖输入数据。作为输入参数它的长度由驱动程序的IO_STACK_LOCATION 的成员 Parameters.DeviceIoControl.InputBufferLength 指定。作为输出参数,缓冲区的长度由驱动程序的IO_STACK_LOCATION 的成员Parameters.DeviceIoControl.OutputBufferLength指定。更多相关信息见 Buffer Descriptions for I/O Control Codes.

如果驱动程序使用的是直接 I/O, 该缓冲区的使用目的由IRP的主功能号决定。如下所示:

IRP_MJ_READ

NULL.

IRP_MJ_WRITE

NULL.

IRP_MJ_DEVICE_CONTROL or IRP_MJ_INTERNAL_DEVICE_CONTROL

缓冲区代表了供DeviceIoControl and IoBuildDeviceIoControlRequest使用的输入参数,缓冲区的长度由驱动程序的IO_STACK_LOCATION成员 Parameters.DeviceIoControl.InputBufferLength 指定。

更多信息见 Buffer Descriptions for I/O Control Codes.

IoStatus

包含了在调用IoCompleteRequest之前驱动用于储存状态和信息的 IO_STATUS_BLOCK 结构 .

RequestorMode

此操作的最初请求者的执行模式, UserMode  KernelMode之一。

PendingReturned

如设置为TRUE一个驱动程序已经设置这个IRP为阻塞状态。任何一个 IoCompletion 例程应当检查这个标志的值。如果这个标志位是TRUE,而且如果 IoCompletion 例程不会返回STATUS_MORE_PROCESSING_REQUIRED, 那么例程应当调用IoMarkIrpPending 以将这个阻塞状态扩散到在这个设备栈之上的驱动程序中。

Cancel

如设置为TRUE, IRP已经被取消或者应当被取消。

CancelIrql

IoAcquireCancelSpinLock调用时驱动程序运行的IRQL级别。

CancelRoutine

包含了如果IRP被取消时,驱动程序提供的Cancel 例程入口点。 NULL 标识IRP当前不可取消。

UserBuffer

当以下条件满足时,包含了输出缓冲区的地址:

l I/O栈位置上的主功能号是IRP_MJ_DEVICE_CONTROL 或者是IRP_MJ_INTERNAL_DEVICE_CONTROL.

l I/O 控制码定义时使用METHOD_NEITHER或METHOD_BUFFERED

METHOD_BUFFERED而言,驱动程序应使用 Irp->AssociatedIrp.SystemBuffer 作为输出缓冲区。当驱动程序完成了请求,I/O 管理器拷贝这个缓冲区的内容到Irp->UserBuffer指向的缓冲区中。 驱动程序不应直接写入数据到Irp->UserBuffer指向的缓冲区。更多信息,见Buffer Descriptions for I/O Control Codes.

Tail.Overlay.DeviceQueueEntry

如果IRPs 在驱动程序关联的设备队列中被排队,这个域链接设备队列中的IRP这些链接仅能在驱动处理IRP时使用。

Tail.Overlay.DriverContext

如果IRPs 没有在驱动程序关联的设备对象中被排队,驱动程序可以使用这个域储存最多4个指针,这个域仅能在驱动程序拥有IRP时使用。

Tail.Overlay.Thread

指向调用者线程的TCB(线程控制块thread control block对于最初在用户模式下产生的请求,I/O 管理器总是设置这个域为指向发布这个请求的线程的TCB。

Tail.Overlay.ListEntry

如果一个驱动管理它自己的内部IRP队列。它使用这个域去链接一个IRP到下一个IRP,这些链接仅能用于当驱动在它的队列中正在掌握(?)这些IRP(while the driver is holding the IRP in its queue)或者是正在处理IRP时。

Remarks

未文档化的成员被保留,仅能被I/O manager使用或是某些情况下被FSDs使用。

IRP 是基本的 I/O 管理结构,用于与驱动程序通信,或是驱动程序之间相互通信。一个IRP由以下两个不同的部分组成:

· 

头,或者是包的固定部分— 这用于让I/O 管理器储存关于初始请求的信息。例如调用者设备无关的参数,文件在设备对象上打开时的地址等等.同样它也被驱动程序用于储存一些信息,如请求的最终状态。

· 

I/O 栈位置— 在头之后是一系列的 I/O 栈位置 (I/O stack locations每一个对应了IRP请求所绑定的在驱动层链中的一个驱动程序。(one per driver in the chain of layered drivers for which the request is bound)。 每一个stack location 包含参数,功能号还有上下文,用于让对应的驱动程序决定它该去做什么。更多信息见IO_STACK_LOCATION 结构.

· 

高层的驱动程序可能会检查IRP Cancel 的值,驱动程序不能假设IRP被低层的驱动程序完成时将返回STATUS_CANCELLED 即使这个值是TRUE.

Requirements

Header

Wdm.h (include Wdm.h, Ntddk.h, or Ntifs.h)

See also

IoCreateDevice

IoGetCurrentIrpStackLocation

IoGetNextIrpStackLocation

IoSetCancelRoutine

IoSetNextIrpStackLocation

IO_STACK_LOCATION

IO_STATUS_BLOCK

你可能感兴趣的:(WDK翻译)