77.windbg-!drvobj、.devstack(驱动对象,设备栈,AttachedDevice)

引言

      

驱动的设备栈可以参看:http://blog.csdn.net/hgy413/article/details/17737517,如下:

驱动设备的创建顺序是,先创建底层PDO,再创建高层的FDO,PDO和FDO之间可能夹杂着各种过滤驱动,每次的设备对象由不同驱动程序所创建,有的驱动程序是系统自带的,有的需要程序员来编写,底层设备对象寻找上层的设备对象,是依靠底层设备对象的AttachedDevice寻找的,如果某一设备的AttachedDevice为空,说明已经到了设备堆栈的顶部,而高层设备找低一层的设备对象,只能能过设备扩展来记录,如下图:


   

PDO:物理设备对象,由总线(BUS)创建

FDO:功能驱动对象,实现PDO的某些功能

FIDO:可插入由PDO-FDO组在的设备栈中,参与IRP处理

CDO:控制设备对象,不对应真实/逻辑的物理设备,我们大部分是写这种,一般来讲,一个驱动程序只会创建唯一的功能设备对象, 功能设备对象一般不用来处理具体的物理设备功能,仅仅作为 驱动程序的编程接口,与其他模块交互

   

设备栈 

1.系统中的I/O请求虽然发送给指定的设备对象,但请求却是通过 设备栈来传递的

2.最上层的设备对象首先获得机会处理请求,然后传递给下层设 备对象。如果上层设备对象处理完请求,则可以拒绝将命令继 续下传,下层设备对象就失去了处理的机会
 
3.功能设备对象会完成大多数的工作,只把部分I/O请求传递给物 理设备对象。  I/O请求在设备栈中传递完毕后,还会有一次从栈底开始的逆向 回调过程,进行完成后操作

4.过滤设备对象可以把自己插入到设备栈中任意位置,过滤顺向 的IO请求包,或者逆序的回调过程。多个过滤设备对象可以叠 加

       

!drvobj 

!drvobj 扩展命令显示DRIVER_OBJECT 的详细信息。
Flags
(Windows 2000和之后) 可以是下面这些位的任意组合。(默认为0x01)
Bit 0 (0x1)
显示驱动拥有的设备对象。
Bit 1 (0x2)
显示驱动的dispatch例程的入口点。
Bit 2 (0x4)
显示驱动的设备对象的详细信息(需要设置bit 0)
以打印机驱动为例:

0: kd> !drvobj parport
Driver object (89a48ce8) is for:
 \Driver\Parport
Driver Extension List: (id , addr)

Device Object list:
895e3040  8969d030  
等同于
0: kd> !drvobj \Driver\Parport
Driver object (89a48ce8) is for:
 \Driver\Parport
Driver Extension List: (id , addr)

Device Object list:
895e3040  8969d030  
等同于
0: kd> !drvobj 89a48ce8
Driver object (89a48ce8) is for:
 \Driver\Parport
Driver Extension List: (id , addr)

Device Object list:
895e3040  8969d030  
   

!devstack

!devstack 扩展显示设备对象关联的设备栈的格式化后的信息。
DeviceObject
指定设备对象。可以是DEVICE_OBJECT 结构的16进制地址或者设备名。
以上面为例:
0: kd> !devstack 895e3040
  !DevObj   !DrvObj            !DevExt   ObjectName
> 895e3040  \Driver\Parport    895e30f8  Parallel0
!DevNode 899ce970 :
  DeviceInst is "LPTENUM\MicrosoftRawPort\6&16ccfde1&0&LPT1"
0: kd> !devstack 8969d030  
  !DevObj   !DrvObj            !DevExt   ObjectName
> 8969d030  \Driver\Parport    8969d0e8  ParallelPort0
  89a56bb8  \Driver\ACPI       89bfeb30  00000071
!DevNode 89a56728 :
  DeviceInst is "ACPI\PNP0400\5&324d5432&0"
  ServiceName is "Parport"
从上面可以看到设备栈,它的底层设备栈是89a56bb8,对应的驱动是ACPI,
我们来看看ACPI一共创建了多少个设备:
0: kd> !drvobj \Driver\ACPI
Driver object (89c5c8b0) is for:
 \Driver\ACPI
Driver Extension List: (id , addr)


Device Object list:
89ba9870  89ba9988  89ba9aa0  89ba9bb8
89ad59a0  89ad5ab8  89ad5bd0  89ad5ce8
89ad5e00  89ad5f18  89ad5030  8971c2b0
8971c3c8  8971c4e0  8971cce8  8971ce00
8971cf18  89a87208  89ae4770  89ae4888
89ae49a0  89ae4ab8  89ae4bd0  89ae4ce8
89ae4e00  89ae4f18  89a63540  89a63658
89a63770  89a63888  89a639a0  89a63ab8
89a63bd0  89a63ce8  89a63e00  89a63f18
89c14658  89c14770  89c14888  89c149a0
89c14ab8  89c14bd0  89c14ce8  89c14e00
89c14f18  89bab4c8  89c46db0  89c10f18
89baa6b8  89bf91f8  89c471f8  89aa74e8
89b94378  897068a8  8972d218  89bcb1a8
89be01a8  89bf51a8  89c11e70  89c11920
89c5c520  
有点多啊,它们分布在不同的设备栈中,随便取个看看,比如第三个:
0: kd> !devstack  89ba9aa0
  !DevObj   !DrvObj            !DevExt   ObjectName
  8970f030  \Driver\serenum    8970f0e8  
  89b84638  \Driver\Serial     89b846f0  Serial0
> 89ba9aa0  \Driver\ACPI       89c474a0  00000074
!DevNode 89ba9608 :
  DeviceInst is "ACPI\PNP0501\1"
  ServiceName is "Serial"
来看看AttachedDevice,当一个FDO附加在一个PDO上时,PDO的AttachedDevice会记录FDO的位置,PDO会被称为底层驱动或下层驱动,而FDO会被称为高层驱动或上层驱动,越上层越接近发出IO请求的地方,如上面,
0: kd> dt 89ba9aa0 _DEVICE_OBJECT -y AttachedDevice
nt!_DEVICE_OBJECT
   +0x010 AttachedDevice : 0x89b84638 _DEVICE_OBJECT
0: kd> dt 89b84638 _DEVICE_OBJECT -y AttachedDevice
nt!_DEVICE_OBJECT
   +0x010 AttachedDevice : 0x8970f030 _DEVICE_OBJECT
0: kd> dt 8970f030 _DEVICE_OBJECT -y AttachedDevice
nt!_DEVICE_OBJECT
   +0x010 AttachedDevice : (null) 
可以看到_DEVICE_OBJECT的AttachedDevice可以从下向上遍历设备栈,而设备栈中每一层设备都分属于不同驱动,而_DEVICE_OBJECT的NextDevice可以遍历当前驱动创建的所有设备,这是两个不同的概念

































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值