IRP

来源:互联网 发布:python DAG教程 编辑:程序博客网 时间:2024/05/01 02:21

IRP

(英文原文来自WDK)

  IRP是一个部分公开的结构,它表示一个I/O请求包。驱动可以使用IRP结构的以下成员。

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;

 

成员:

  MdlAddress

指向MDL(描述一个用户缓冲区)的指针,如果驱动使用直接I/O(direct I/O),并且IRP的主功能号是以下其中一个的话:

IRP_MJ_READ

  则MDL描述一个空的缓冲区,并由设备或驱动填写

IRP_MJ_WRITE

  则MDL描述一个缓冲区,其中包含要发送给设备或驱动的数据

……其它的我还不用在意

 

如果驱动没有使用直接I/O,则该指针为空

 

Flags

文件系统驱动使用这个域,对于所有驱动来说它是只读的。网络或者最高层的设备驱动也可能会读这个域,它可以被设置为一个或者多个如下系统已定义好的值:

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

  AssociatedIrp.MasterIrp

指向由最高层的驱动调用IoMakeAssociatedIrp而创建的IRP中的主IRP的指针

  AssociatedIrp.SystemBuffer

指向系统空间的buffer

如果驱动正在使用缓冲I/O(buffered I/O),则缓冲区的目的是由IRP的主功能号决定的,如下:

IRP_MG_READ

  缓冲区接收来自设备或者驱动的数据,缓冲区的长度是由IO_STACK_LOCATIONZ结构中的Parameters.Read.Length指定的

IRP_MJ_WRITE

  缓冲区为设备或驱动提供数据。,缓冲区的长度是由IO_STACK_LOCATIONZ结构中的Parameters.Write.Length指定的

……其它先暂且不考虑了

如果驱动正在使用直接I/O,,则缓冲区的目的有IRP的主功能号决定,如下:

 IRP_MJ_READ

   NULL

 IRP_MJ_WRITE

   NULL

  ……其它的暂且不考虑

 

  IoStatus

     包含一个IO_STATUS_BLOCK结构,驱动在调用IoCompleteRequest之前在其中存放状态和信息

 

  RequestorMode

     表明操作的原始请求者的执行模式,只能是UserMode或者KernelMode

 

  PendingReturned

     如果设置为TRUE,一个驱动就已经将一个IRP标志为挂起状态。每一个I/O完成函数(I/OCompletion)都应该检查这个值。如果flag是TRUE并且如果I/OCompletion不返回STATUS_MORE_PROCESSING_REQUIRED,则该函数应该调用IoMarkIrpPending来将这个挂起状态传播给设备栈中该驱动上面的所有驱动。

 

  Cancel

     如果设置为TRUE,或者被取消,或者应该被取消

 

  CancelIrql

     包含当IoAcquireCancelSpinLock被调用时一个驱动正在运行的IRQL

  CancelRoutine

     驱动提供的Cancel函数的入口点,该函数在一个IRP被取消时被调用。NULL标识IRP当前是不可取消的

  UserBuffer

如果在I/O stack location中的主功能号是IRP_MJ_DEVICE或者IRP_MJDEVICE_CONTROL并且I/O控制码用METHOD_NEITHER来定义,则它包含输出缓冲区的地址

 

注释

  IRP为公开的成员是被保留的,只被I/O管理器使用,在一些情况下也被FSD使用

  IRP是基本的I/O管理器结构,用来与驱动通信,并且允许驱动之间进行通信。一个IRP包分为两个不同的部分:

  头部,或者包的固定部分——这通常被I/O管理器用来存储关于原始请求的信息,如调用者的设备独立的参数,设备对象的地址(在该设备上,一个文件被打开)等等。它也被驱动用来存储信息如:请求的最终状态

  I/O stack locations——在header后面是一组I/O stack locations,请求绑定的成层的驱动的链条上的每一个驱动都有一个I/O STACK LOCATIONS。每一个stack location包含参数,函数代码和上下文,而这些被驱动用来决定应该做什么,关于更多的信息请看IO_STACK_LOCATION结构

 

0 0
原创粉丝点击