安装驱动程序(3)--调整过滤驱动位置

    前面写了安装功能驱动,过滤驱动,本篇谈谈调整过滤驱动的位置。设备栈上总线驱动和功能驱动的数量比较固定,但过滤驱动就不一样了,可以不断的往设备栈上叠加。如果仅仅像垒书本一样,往现有堆栈顶添加过滤驱动使得设备栈的深度不断增加,倒也简单。但如果要调整一下过滤驱动的位置,比如从最顶端移到较低的位置,那该怎么做?本篇的写作目的就是回答这个疑问。

    仍然以toaster的过滤驱动为例(不要质问我为什么老拿它开刀,因为其他的我也不会)。我为toaster添加了2个类下层过滤驱动:将clslower.sys一式两份,取名为clslower.sys和clslower1.sys。同时修改clafilter用以添加这对双胞胎:

下列为clslower.sys的inf文件clslower.inf
[Version]
signature = "$Windows NT$"
 
[SourceDisksNames]
1 = %ClasFilt.MediaDesc%

[SourceDisksFiles]
clslower.sys = 1 


[DestinationDirs]
DefaultDestDir = 12	; DIRID_DRIVERS

[DefaultInstall.NT]
CopyFiles = @clslower.sys
AddReg = ClassFilter_AddReg
 
[ClassFilter_AddReg]
HKLM, System\CurrentControlSet\Control\Class\{b85b7c50-6a01-11d2-b841-00c04fad5171}, LowerFilters, 0x00010008, clasfilt0


[DefaultInstall.NT.Services]
AddService = clasfilt0, , clasfilt_Service_Inst

[clasfilt_Service_Inst]
DisplayName    = %ClasFilt.SvcDesc%
ServiceType    = %SERVICE_KERNEL_DRIVER%
StartType      = %SERVICE_DEMAND_START%
ErrorControl   = %SERVICE_ERROR_IGNORE%
ServiceBinary  = %12%\clslower.sys


[Strings]
ClasFilt.SvcDesc	= "Lower Class 0 Filter Driver"
ClasFilt.MediaDesc 	= "Class Filter 0 Driver Disc"

SERVICE_KERNEL_DRIVER = 1
SERVICE_DEMAND_START  = 3
SERVICE_ERROR_IGNORE  = 0
REG_EXPAND_SZ         = 0x00020000
REG_DWORD             = 0x00010001

下列为clslower1.sys的inf文件clslower1.inf

 
  
[Version]
signature = "$Windows NT$"

[SourceDisksNames]
1 = %ClasFilt.MediaDesc%

[SourceDisksFiles]
clslower1.sys = 1 


[DestinationDirs]
DefaultDestDir = 12	; DIRID_DRIVERS
 
[DefaultInstall.NT]
CopyFiles = @clslower1.sys
AddReg = ClassFilter_AddReg
 
[ClassFilter_AddReg]
HKLM, System\CurrentControlSet\Control\Class\{b85b7c50-6a01-11d2-b841-00c04fad5171}, LowerFilters, 0x00010008, clasfilt

[DefaultInstall.NT.Services]
AddService = clasfilt, , clasfilt_Service_Inst
[clasfilt_Service_Inst]
DisplayName    = %ClasFilt.SvcDesc%
ServiceType    = %SERVICE_KERNEL_DRIVER%
StartType      = %SERVICE_DEMAND_START%
ErrorControl   = %SERVICE_ERROR_IGNORE%
ServiceBinary  = %12%\clslower1.sys


[Strings]
ClasFilt.SvcDesc	= "Lower Class Filter Driver"

ClasFilt.MediaDesc 	= "Class Filter Driver Disc"

SERVICE_KERNEL_DRIVER = 1
SERVICE_DEMAND_START  = 3
SERVICE_ERROR_IGNORE  = 0
REG_EXPAND_SZ         = 0x00020000
REG_DWORD             = 0x00010001
右键安装这两个类过滤驱动后,可以看到如下结果:

安装驱动程序(3)--调整过滤驱动位置_第1张图片

安装驱动程序(3)--调整过滤驱动位置_第2张图片

注册表LowerFilter项显示toaster类设备有两个类下层驱动;设备管理器大概也是从注册表读取信息,因此有同样的值。用windbg查看toaster设备栈:

kd> !drvobj toaster  ;参看toaster驱动对象信息
Driver object (fffffa80051dbe70) is for:
 \Driver\toaster
Driver Extension List: (id , addr)

Device Object list:
fffffa8005a56bb0  fffffa80051dccc0
kd> !devstack fffffa8005a56bb0 ;toaster设备对象的设备栈信息
  !DevObj   !DrvObj            !DevExt   ObjectName
> fffffa8005a56bb0  \Driver\toaster    fffffa8005a56d00  -->toaster功能设备
  fffffa80059ce8c0  \Driver\clasfilt0  fffffa80059cea10  -->类过滤驱动
  fffffa8003e7a460  \Driver\clasfilt   fffffa8003e7a5b0  -->类过滤驱动
  fffffa8003dfb080  \Driver\busenum    fffffa8003dfb1d0  000000b6
!DevNode fffffa8004b2e9d0 :
  DeviceInst is "{B85B7C50-6A01-11d2-B841-00C04FAD5171}\MsToaster\1&79f5d87&0&01"
  ServiceName is "toaster"
windbg罗列了toaster设备栈的堆叠情况,从结果来看classfilter0堆叠在clasfilter之上。如果你看过前一篇文章,可能记得 删除驱动时会调用GetFilters,GetFilters通过GetDeviceRegistryProperty函数从注册表中获得过滤驱动的信息,返回的结果是一个字符串数组。对于这里的情况,字符串数组的内容应该包括clasfilt和clasfilt0两个字符串。移除驱动的时候,是把其中一个字符串从字符串数组中移除,然后再调用SetDeviceRegistryProperty把结果写回注册表。受此启发,你可能会想到,可以直接在注册表中调整两个字符串的位置,到达调整驱动位置的目的。为此,我们来验证这个猜想的正确性。

    验证的步骤如下:首先停用设备然后修改注册表LowerFilter,最后启用设备用windbg查看设备栈:

安装驱动程序(3)--调整过滤驱动位置_第3张图片

图为修改后注册表的值,重新启用设备,查看设备栈的值:

kd> !drvobj toaster
Driver object (fffffa80051dbe70) is for:
 \Driver\toaster
Driver Extension List: (id , addr)

Device Object list:
fffffa8005a12cc0  fffffa80051dccc0  
kd> !devstack fffffa8005a12cc0
  !DevObj   !DrvObj            !DevExt   ObjectName
> fffffa8005a12cc0  \Driver\toaster    fffffa8005a12e10  
  fffffa8003fc7600  \Driver\clasfilt   fffffa8003fc7750  
  fffffa800408b040  \Driver\clasfilt0  fffffa800408b190  
  fffffa8003dfb080  \Driver\busenum    fffffa8003dfb1d0  000000b6
!DevNode fffffa8004b2e9d0 :
  DeviceInst is "{B85B7C50-6A01-11d2-B841-00C04FAD5171}\MsToaster\1&79f5d87&0&01"
  ServiceName is "toaster"
不出所料,设备栈中的过滤驱动果然发生了变化,猜想可行,接下来就是用程序实现调整驱动了。其实winddk已经实现了这部分代码为于src/setup/devcon/Cmds.cpp的cmdClassFilter函数中。这个函数对应于强大的devcon classfilter命令,可以通过devcon help classfilter查看命令帮助文档。

你可能感兴趣的:(win内核)