IRP packet

  比如说你开发了一个USB接口的设备, 那么为了在windows上使用它, 你需要开发一个驱动程序,也许还需要一个应用程序.有些硬件是"免驱"的.但事实上不是不需要驱动,而是他所需要的驱动已经存在在windows中了,不需要你另外安装而已.

  你使用应用程序可以控制该硬件的行为,过程是应用程序发出需要,OS负责将该需要转化为一个IRP数据包,交给驱动程序,驱动程序根据该包中的数据来决定如何去控制该硬件.

  所以编写驱动(WDM驱动,其它的驱动不知道是不是一样)的过程主要是对各种IRP包进行处理的过程.首先就是对IRP包的结构了解才成. 以下的解释请参考programming WDM一书中的 Figure 5.1.

  1 MdlAddress: 这里保存的是一个地址(用户模式的).在该地址中的空间是要读写的数据所存放的地方.比如应用程序要向设备中写入10个字符.那么他首先要把这十个字符告诉驱动程序.方法就是把存放这些字符的地址告诉驱动程序.但是这里的MdlAddress是用户模式的地址.驱动程序不应该直接使用这个地址.因为驱动程序直接操作用户模式的地址的话,如果此时刚才OS切换去执行另外一个进程,那么驱动程序操作的就是那个进程的空间(因为进程的低2GB是各个进程分别具有一个,但是驱动的高2GB却是所有进程共享的).这个就会造成了意外的损坏.

  2 AssociateIrp: 这是一个共用体.其中最常用的AssociateIrp.SystemBuffer, 这也是一个地址,只是它是存在于内核模式中的地址.它与1中讲到的MdlAddress有关系,当APP利用writeFile(buffer)向驱动发送一些数据时,这些数据就放在AssociateIrp中.这样驱动就不会去破坏其他进程的数据了.注意这个SystemBuffer一定要是非分页内存(nonPaged kernel-mode memory).非分页内存是指该内存必须一直呆在RAM中,不可以被交换到硬盘中的文件(paging file)中去

  3 IoStatus 是一个结构体,其中包含两个成员.一个是Status, 它是一个NTSTATUS CODE,标识这个IRP是否已经被驱动程序处理完.另外一个是Information, 这个成员的含义不确定,它要根据IRP的类型和完成情况(status)来决定.比如,对于irp_mj_read, Information代表读取的字节数.

  4 RequestorMode: 是UserMode或者KernelMode.如果该IRP是由应用程序发出来的,则是UserMode.如果是由驱动程序发送出来的,则是KernelMode.

         PendingReturnd: 是一个布尔变量.如果最底层的分发例程返回了STATUS_PENDING,就代表这个IRP还没有被彻底完成.

  6 Cancel: 是一个布尔变量.如果IrpCancelIrp函数被调用了,那么该值是真,否则是假.

  7     CancelIrql: Irql(Interrupt request level)即中断请求级. 即被申请的取消自旋锁 要运行在什么中断请求级上.

  8 CancelRoutine: 处理取消请求的函数的地址.你不应该直接来修改该成员,而是应该使用IoSetCancelRoutine去做.

  9 UserBuffer: 也是否个地址.用来存放应用程序给驱动程序的数据. 应用程序与驱动程序之间通信有三种方式:METHOD_NEITHER 

DO_BUFFERED_IO DO_DIRECT_IO.在上面的1中提到的MdlAddress是当模式选择为DO_BUFFERED_IO时用户模式数据的存放的地址,而UserBuffer是在METHOD_NEITHER模式下用户模式数据的地址.你在编写驱动时候,会在iocreatedevice中设置这个模式.

      10  Tail: 是一个共用体.包括Tail.OverLay, Tail.Apc, Tail.CompletionKey. 在Tail中我们有用的成员不多, 在有些时候, 连续会有很多个IRP需要驱动来处理,他们必须要排除等待处理, 那么就需要有一种方法来标识谁先谁后, Tail中的数据成员用来实现该功能.  比如:I/O管理器使用Tail.DeviceQueueEntry来知道在标准队列中的下一个请求是谁.当你实现一个自己的私有队列时,可以用Tail.Overlay.ListEntry来标识下一个请求.

      11 CurrentLocation (CHAR) and Tail.Overlay.CurrentStackLocation : windows没有公布他们的使用文档.因为windows认为我们不需要直接使用这两个值,且提供了一个接口函数IoGetCurrentIrpStackLocation 来实现相应功能.

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值