KIrp类:
一、Overview
KIrp类抽象了IRP(IO请求),这个类是设备驱动程序中操作的核心。这个类的目标是:
(1)提供对IRP中各个域的存取方法。
(2)提供一些可以结合相关操作的函数
(3)提供重载操作符来使类实例以对IRP本身类似的操作来使用
IRP结构的复杂性足以使任何不熟悉它的开发人员畏惧,并且写出来的操作它的代码也是容易出错和不易阅读的。比较下面用C写的代码和用DriverWorks类库写的代码:
// Straight C version
PIRP pIrp;
IO_STACK_LOCATION pStack;
pStack = IoGetCurrentIrpStackLocation(pIrp);
switch (pStack->Parameters.DeviceIoControl.IoControlCode)
{
. . .
}
// Using class library
KIrp I(pIrp);
switch (I.IoctlCode())
{
. . .
}
这些存取器函数被设计的很简洁,写出的代码更具可读性,而不会牺牲效率。最终所有的函数都是in-line方式实现的。对生成代码的分析表明使用这些存取器函数可以达到极佳的优化效果。
某些存取器函数对内嵌的IO_STACK_LOCATION结构体进行操作。每个IRP在它的末尾都有这么一个结构。它们用来向下层分层驱动栈传递参数,每层一个结构体。一个给定的驱动程序可以控制当前的location和下一个location。每个存取IO_STACK_LOCATION域的存取器函数都要求一个参数来区别操作的是当前location还是下一个location,并且每个函数的默认参数是CURRENT(当前)。在这任一种情况下,参数都几乎都是一个常数(constant),使编译器从生成的代码中删除对使用哪个栈单元(stack location)的决定(decision)。
除了存取器函数,类的提供者函数也简化了普通的操作。作为一个例子,可以考虑一下Complete函数,这个函数有一个status和一个priority boost(优先级改变)作为参数,后者默认值是IO_NO_INCREMENT。这个函数返回传进去的status值,在源代码里使代码得到了缩减:
比较:
// Straight C version
status = STATUS_SUCCESS;
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
// Using class library
return I.Complete(STATUS_SUCCESS);
每当类KIrp的实例指针可用时,它的实例也可用,反之亦然。这可能是因为:
(1)KIrp的构造函数只有一个单一参数,就是PIRP。因此编译器可以自动把PIRP类型转换为KIrp。
(2)这个类提供了重载的转换成PIRP的运算符,简单的返回一个下层的PIRP数据成员。因此编译器可以自动把KIrp转化成PIRP类型。
(3)这个类提供了重载指针操作符->,返回值类型为PIRP。这意味着“KIrp->"与KIRP的操作极其相似。
(4)因为KIrp没有虚函数,只有一个成员变量(PIRP类型),它可以作为参数有效的传递进去。因此,KIrp的指针就很少派的上用场。
没有哪个KIrp的函数可以超越几行代码的功能,但是作为一个团队,大家都希望有一种方法来有效的缩减源代码的行数,并且使驱动程序更易读,更具可维护性。
对于经常用到的IRP域和IO_STACK_LOCATION都有相应的存取函数。对于不常使用的IRP域和IO_STACK_LOCATION,我们可以使用成员函数CurrentStackLocation 和 NextStackLocation 来包含一个指向栈单元的指针。然后通过返回的指针使用成员变量。IO_STACK_LOCATION的定义在ntddk和wdm.h文件中,这两个文件都在DDK中。
注意:KIrp的数据大小只有32位。它只包含一个指向实际IRP的指针,而不是包含了整个IRP对象。由于这种原因,对象可以把栈信息传递过去而不用担心性能损失。要为一个新的IRP申请实际的存储空间的话,要用静态函数(static) Allocate()。
二、Member Functions
1、KIrp - Constructor.构造函数,以PIRP为参数。
2、IsNull - Tests if the IRP is NULL.测试IRP是否为空。
3、WasCanceled - Tests if the IRP has been canceled.测试IRP是否已经被取消。
4、Complete - Completes the IRP.完成IRP。
5、Status - Accessor to IRP status.获得IRP状态。
6、Information - Accessor to IRP information.获得IRP信息域(information域),返回IoStatus.Information。
7、BufferedWriteSource - Accessor to buffer for buffered write operation.为缓冲写操作返回AssociatedIrp.SystemBuffer的参考。
8、BufferedReadDest - Accessor to buffer for buffered read operation.为缓冲读操作返回AssociatedIrp.SystemBuffer的参考。
9、IoctlBuffer - Accessor to buffer for buffered IOCTL operation.为缓冲IO control操作返回AssociatedIrp.SystemBuffer的参考。
10、MarkPending - Mark the IRP as pending.把IRP标记为挂起。
11、ForceReuseOfCurrentStackLocationInCalldown - Manipulates IRP stack location pointer.在IRP传给下一个驱动程序之前伪造一个当前栈单元指针。
12、SetCancelRoutine - Set/clear routine to be called if IRP is canceled.指定或清除IRP被取消时要执行的例程函数。
13、TestAndSetCancelRoutine - Set/clear routine to be called if IRP is canceled, checking cancel flag.自动测试IRP是否已经被取消了,并指定或清除IRP被取消时要执行的例程函数。
14、CopyParametersDown - Copy current parameter stack to next.把当前的IO_STACK_LOCATION拷贝到下一个栈单元。
15、SetCompletionRoutine - Set routine to be called when IRP is completed.设置当IRP被完成时需要调用的例程函数。
16、DeviceQueueEntry - 获取IRP的设备队列入口Tail.Overlay.DeviceQueueEntry。
17、Mdl - Accessor to MDL for all direct I/O operations.获取IRP的内存描述府列表的地址MdlAddress。
18、CancelIrql - Accessor to cancel IRQL field.获取IRP的域CancelIrql的参考。
19、MajorFunction - Accessor to major function for current or next stack.获取当前栈或下一栈的主功能代码。
20、MinorFunction - Accessor to minor function for current or next stack.获取当前栈或下一栈的次功能代码。
21、IoctlCode - Accessor to IOCTL code for current or next stack.获取当前栈或下一栈的IO控制码。
22、ReadSize - Accessor to size of read operation for current or next stack.获取当前栈或下一栈的读操作字节大小。
23、WriteSize - Accessor to size of write operation for current or next stack.获取当前栈或下一栈的写操作字节大小。
24、IoctlOutputBufferSize - Accessor to size of IOCTL output buffer for current or next stack.获取当前栈或下一栈的主功能代码为IRP_MJ_DEVICECONTROL的输出缓冲区字节大小。
25、IoctlInputBufferSize - Accessor to size of IOCTL input buffer for current or next stack.获取当前栈或下一栈的主功能代码为IRP_MJ_DEVICECONTROL的输入缓冲区字节大小。
26、IoctlType3InputBuffer - Accessor to retrieve the address of the input buffer for certain control calls.获取当前栈或下一栈的输入缓冲区字节大小,当DeviceIoControl操作的IO方法选择METHOD_NEITHER的时候用到。
27、UserBuffer - Accessor to retrieve buffer for certain read, write, and control calls.当主功能码为IRP_MJ_READ或IRP_MJ_WRITE ,且参数中既没有DO_DIRECT_IO ,也没有DO_BUFFERED_IO时,这个缓冲区地址的参考将作为ReadFile或WriteFile的缓冲区参数返回给应用程序。
28、ReadOffset - Accessor to offset on device of data to be read.读操作中数据距离读操作的初始地址的偏移
29、WriteOffset - Accessor to offset on device of data to be written.写操作中数据距离写操作的初始地址的偏移
30、FileObject - Accessor to system file object associated with this request.获得和这个请求相关的系统文件对象。
31、DeviceObject - Accessor to system device object associated with this request.获得和这个请求相关的系统设备对象。
32、QueryFileInformationClass - Accessor to InformationClass field of a QueryFile IRP.当主功能代码为
IRP_MJ_QUERY_INFORMATION时,获得IRP的InformationClass 域的值。
33、SetFileInformationClass - Accessor to InformationClass field of a SetFile IRP.当主功能代码为IRP_MJ_QUERY_INFORMATION时,设置IRP的InformationClass 域的值。
34、DriverContext - Accessor to the DriverContext area of the IRP.获取IRP的DriverContext 域。
35、operator-> - Overloaded pointer-to-member operator.重载将指针转换为对象的操作符 ->。
36、operator PIRP( ) - Overloaded cast operator.重载类型转换操作符。
37、Allocate - Static member to allocate a system I/O request object.静态分配一个IRP。
38、Deallocate - Static member to release an IRP allocated with Allocate.静态释放一个IRP。
39、CurrentStackLocation - Retrieve a pointer to the current stack location.获取一个指向当前栈单元的指针。
40、NextStackLocation - Retrieve a pointer to the next stack location.获取一个指向下一个栈单元的指针。
41、SetNextStackLocation - Increments the KIrp stack location. 递增KIrp栈单元。
三、WDM Only Members
1、DeviceRelationType - Accessor to device relation type返回一个主功能代码为IRP_MJ_PNP且次功能代码为
IRP_MN_QUERY_DEVICE_RELATIONS的IRP的Parameters.QueryDeviceRelations.Type域的参考。
2、DeviceCapabilities - Accessor to device capabilities返回一个主功能代码为IRP_MJ_PNP且次功能代码为
IRP_MN_QUERY_CAPABILITIES的IRP的Parameters.DeviceCapabilities.Capabilities域的参考。
3、AllocatedResources - Accessor to allocated resource list返回一个主功能代码为IRP_MJ_PNP且次功能代码为IRP_MN_START_DEVICE的IRP的Parameters.StartDevice.AllocatedResources域的参考。
4、TranslatedResources - Accessor to translated allocated resource list返回一个主功能代码为IRP_MJ_PNP且次功能代码为IRP_MN_START_DEVICE的IRP的Parameters.StartDevice.AllocatedResourcesTranslated域的参考。
5、WaitWakePowerState - Accessor to wait/wake power state返回一个主功能代码为IRP_MJ_ POWER且次功能代码为IRP_MN_WAIT_WAKE的IRP的Parameters.SetResourceRequirements.IoResourceRequirementList域的参考。
6、PowerSequence - Accessor to power sequence返回一个主功能代码为IRP_MJ_ POWER且次功能代码为IRP_MN_POWER_SEQUENCE的IRP的Parameters.SetResourceRequirements.IoResourceRequirementList域的参考。
7、Urb - Accessor to URB pointer (for USB devices)返回一个主功能代码为IRP_MJ_INTERNAL_DEVICE_CONTROL的IRP的Parameters.Others.Argument1 域的参考(USB设备适用)。
8、QueryIdType - Accessor to id type for query (IRP_MN_QUERY_ID)返回一个主功能代码为IRP_MJ_PNP且次功能代码为IRP_MN_QUERY_ID的IRP域的参考。
9、IndicatePowerIrpProcessed - Report completion of power IRP to system power manager告诉系统说驱动程序已经完成对电源(power) IRP的处理。
----------------
§ 译自"DriverWorks帮助文件" §
§ 李文凯 2008年04月01日 §
----------------