高级语言程序设计(C++)_第1页
高级语言程序设计(C++)_第2页
高级语言程序设计(C++)_第3页
高级语言程序设计(C++)_第4页
高级语言程序设计(C++)_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、WDM驱动程序设计I/O请求包(IRP)IRP的总体结构Windows操作系统使用一种称为I/O请求包(IRP)的数据结构与内核模式驱动程序通信。Windows驱动程序中几乎所有的I/O操作都是包驱动的。一个I/O请求包由一个IRP首部加一系列的栈单元组成。每个栈单元是一个IO_SATCK_LOCATION结构。IRP首部栈单元1栈单元2栈单元3 当前栈单元驱动程序栈与I/O栈单元之间的关系栈单元数组(I/O堆栈)中的每个堆栈单元都对应一个将处理该IRP的驱动程序。IRP首部的结构IRP首部的重要字段MdlAddress(PMDL):指向一个内存描述符表(MDL),它描述了一个与该请求关联的用

2、户模式缓冲区。在驱动程序与用户模式程序之间利用“直接I/O方式”进行通信时,驱动程序利用该字段访问用户模式的虚拟内存。AssociatedIrp:是一个三指针联合(union)。其中,与NT式驱动程序相关的指针是AssociatedIrp.SystemBuffer。 SystemBuffer指针指向一个数据缓冲区,该缓冲区位于内核模式的非分页内存中。在驱动程序与用户模式程序之间利用“缓冲I/O方式”进行通信时,驱动程序利用该缓冲区输入输出数据。I/O管理器会自动将用户模式缓冲区中的数据复制到SystemBuffer缓冲区,或者自动将SystemBuffer缓冲区中的数据复制到用户模式缓冲区。I

3、RP首部的重要字段IoStatus(IO_STATUS_BLOCK):是一个仅包含两个域的结构,驱动程序在最终完成请求时设置这个结构。IoStatus.Status域将收到一个NTSTATUS代码,而IoStatus.Information的类型为ULONG_PTR,它将收到一个信息值,该信息值的确切含义要取决于具体的IRP类型和请求完成的状态。IoStatus.Information域的一个公认用法是用于保存数据传输操作,如IRP_MJ_READ,的流量总计。某些PnP请求把这个域作为指向另外一个结构的指针,这个结构通常包含查询请求的结果。RequestorMode:是一个枚举常量,取值为U

4、serMode或KernelMode,指定IRP的最初来源。驱动程序有时需要查看这个值来决定是否要信任某些参数。IRP首部的重要字段PendingReturned(BOOLEAN):如果为TRUE,则表明处理该IRP的低级派遣例程返回了STATUS_PENDING。完成例程通过参考该域来避免自己与派遣例程间的潜在竞争。Cancel(BOOLEAN):如果为TRUE,则表明内核服务函数IoCancelIrp已被某个程序实体在该IRP所调用,该函数用于取消这个IRP。如果为FALSE,则表明没有被取消。CancelIrql(KIRQL):是一个IRQL值,表明那个专用的取消自旋锁是在这个IRQL上

5、获取的。当在取消例程中释放自旋锁时应参考这个域。CancelRoutine(PDRIVER_CANCEL):是一个回调函数指针,指向取消例程。在取消某个IRP时,取消例程会被自动调用。应该使用IoSetCancelRoutine函数设置这个域而不是直接修改该域。IRP首部的重要字段UserBuffer(PVOID) :对于METHOD_NEITHER方式的IRP_MJ_DEVICE_CONTROL请求,该域用于保存读写请求缓冲区的用户模式虚拟地址 。Tail:是一个联合,其结构如下所示:IRP首部的重要字段CurrentLocation (CHAR):当前栈单元在数组中的索引。Tail.Ove

6、rlay.CurrentStackLocation(PIO_STACK_LOCATION):指向当前栈单元的指针。一般不在驱动程序中直接访问这两个字段,可以使用象IoGetCurrentIrpStackLocation这样的函数获取这些信息。IO_STACK_LOCATION的结构 栈单元的重要字段MajorFunction(UCHAR):表示该IRP的主功能码。这个代码应该为类似IRP_MJ_READ一样的值,并与驱动程序对象中MajorFunction表的某个派遣函数指针相对应。MinorFunction(UCHAR):表示该IRP的副功能码。它进一步指出该IRP属于哪个主功能类。例如,I

7、RP_MJ_PNP请求就有很多的副功能码,如IRP_MN_START_DEVICE、IRP_MN_REMOVE_DEVICE,等等。Parameters(union):它是几个子结构的联合,每个请求类型都有自己专用的参数,而每个子结构就是一种参数。这些子结构包括Create(IRP_MJ_CREATE请求)、Read(IRP_MJ_READ请求)、StartDevice(IRP_MJ_PNP的IRP_MN_START_DEVICE子类型),等等。栈单元的重要字段DeviceObject(PDEVICE_OBJECT):表示与该堆栈单元对应的设备对象的地址。FileObject(PFILE_OB

8、JECT):表示与该堆栈单元对应的驱动程序内核文件的地址。IRP的目标就是这个文件对象。驱动程序通常在处理清除请求(IRP_MJ_CLEANUP)时使用FileObject指针,以区分队列中与该文件对象无关的IRP。CompletionRoutine(PIO_COMPLETION_ROUTINE):是一个I/O完成例程的地址,该地址是由与这个堆栈单元对应的驱动程序的更上一层驱动程序设置的。绝对不要直接设置这个域,应该调用IoSetCompletionRoutine函数。Context(PVOID):是一个任意的与上下文相关的值,将作为参数传递给完成例程。绝对不要直接设置该域;它由IoSetCo

9、mpletionRoutine函数自动设置。将IRP发往派遣例程操作系统创建完IRP后,调用IoGetNextIrpStackLocation函数获得该IRP下一个栈单元的指针。然后初始化这个栈单元。堆栈单元初始化完成后,就可以调用IoCallDriver函数把IRP发送到设备驱动程序。PDEVICE_OBJECT DeviceObject; /someone gives you thisPIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp);stack-MajorFunction = IRP_MJ_Xxx; / 其它初始化操作NTS

10、TATUS status = IoCallDriver(DeviceObject, Irp);IoCallDriver函数NTSTATUS IoCallDriver(PDEVICE_OBJECT device, PIRP Irp) IoSetNextIrpStackLocation(Irp); PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); stack-DeviceObject = device; ULONG fcn = stack-MajorFunction; PDRIVER_OBJECT driver = devi

11、ce-DriverObject; return (*driver-MajorFunctionfcn)(device, Irp);派遣例程的职责IRP派遣例程的原型看起来像下面这样:NTSTATUS DispatchXxx(PDEVICE_OBJECT device, PIRP Irp) PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) device-DeviceExtension; . . . . / 处理该IRP请求 return

12、STATUS_Xxx;派遣例程的职责驱动程序的派遣例程接收到一个IRP后一般有三种处理方式:派遣函数立即完成该IRP(例如取得驱动程序版本)。 把该IRP传递到处于同一堆栈的下层驱动程序。 排队该IRP以便由这个驱动程序中的其它例程来处理。IRP的完成当一个IRP所请求的操作被做完之后,必须对该IRP做最后一步处理:完成该IRP。程序员要完成一IRP所做的主要工作是:(1)用恰当的状态码填充IRP首部的IoStatus结构的Status成员,以向的发起者传送该IRP被完成的状态;(2)填充IRP首部的IoStatus结构的Information成员,以传递其它完成信息;(3)以该IRP为参数调

13、用IoCompleteRequest例程。IoCompleteRequest完成的主要工作:(1)依次调用挂接在该IRP上的完成例程;(2)将MdlAddress域所对应的物理内存解锁;(3)触发一个同步事件,激活该IRP的发起者,发起者会对该IRP做最后的清除工作。辅助函数在驱动程序中有很多地方都要完成一个IRP,所以通常编写一个辅助函数来完成IRP:NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status, ULONG_PTR Information) Irp-IoStatus.Status = status; Irp-IoStatus.Info

14、rmation = Information; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; Status的取值状态代码描述STATUS_SUCCESS正常完成STATUS_UNSUCCESSFUL请求失败,没有描述失败原因的代码STATUS_NOT_IMPLEMENTED一个没有实现的功能STATUS_INVALID_HANDLE提供给该操作的句柄无效STATUS_INVALID_PARAMETER参数错误STATUS_INVALID_DEVICE_REQUEST该请求对这个设备无效STATUS_END_OF_FILE到达文件尾STATUS_DELETE_PENDING设备正处于被从系统中删除过程中STATUS_INSUFFICIENT_RESOURCES没有足够的系统资源(通常是内存)来执行该操作优先级推进IoCompleteRequest的第二个参数为等待线程提供的一个优先级推进值,该值将用于提高等待该请求完成的线程的优先级。一般说来,需要根据设备类型来选择这个推进值。优先级的调整提高了那些需要频繁等待I/O操作完成的线程的吞吐量。对于那些直接响应用户的事件,如键盘或鼠标操作,应该有一个比较大的优先级推进,以提高交互性能。推进值常量优先级推进值IO_NO_I

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论