磁盘设备栈的设备传递
(2013-01-09 11:22:11)
理理清楚,主要是今天需要获取c盘对应的DRx设备。
文件访问的时候,关系到的设备栈如下:
ntfs device -> volume device -> partmgr device -> disk device -> port(mini-port) device
其中,文件系统设备到卷设备使用vpb;而分区设备到下面使用attach设备关系就可以找到。不过实际中,disk device到下层设备使用了extension+8,而不是attach关系设备。
剩下一个问题,卷设备如何传递到分区设备呢?
下个断点看到这样的栈:
1: kd> kb
ChildEBP RetAddr
Args to Child
97d47cf0 81a4ba7c 856827b0 85b0a7e0 85b0a7e0 CLASSPNP!ClassGlobalDispatch
97d47d0c 889e82ed 00000000 85682430 857acc04 nt!IofCallDriver+0x3f
97d47d3c 81a4ba7c 00682430 85b0a7e0 857accd8 partmgr!PmGlobalDispatch+0x2e8
97d47d58 82862120 00000000 857acc20 82e6f404 nt!IofCallDriver+0x3f
97d47d7c 81a4ba7c 857acc20 85b0a7e0 82e6f420 volmgr!VmReadWrite+0x11b
97d47d98 82e6bc98 85b0a7e0 f9bd6000 857ad0d8 nt!IofCallDriver+0x3f
97d47dac 82e6bd9c 857ad0d8 85b0a7e0 00000001 fvevol!FveRequestPassThrough+0x5e
97d47dc8 82e6bfa9 00000001 f9bd6000 00000000 fvevol!FveReadWrite+0x38
97d47df8 82e6c03e 00000001 97d47e20 81a4ba7c fvevol!FveFilterRundownReadWrit
e+0x159
97d47e04 81a4ba7c 857ad020 85b0a7e0 000a0245 fvevol!FveFilterRundownWrite+0x48
97d47e20 82f1e740 85b0a7e0 00000000 00000003 nt!IofCallDriver+0x3f
97d47e94 82f1e86f 857add20 00000000 857adc68 rdyboost!SmdProcessReadWrite+0x73b
97d47ebc 81a4ba7c 857adc68 85b0a7e0 857ab0d8 rdyboost!SmdDispatchReadWrite+0x104
97d47ed8 82ed8782 00000000 857ab020 84a80004 nt!IofCallDriver+0x3f
97d47f0c 82ed84c6 85b0a7e0 97d47f34 81a4ba7c volsnap!VolsnapWriteFilter+0x277
97d47f18 81a4ba7c 857ab020 85b0a7e0 84a80040 volsnap!VolSnapWrite+0x19
97d47f34 88a2bc44 891872f8 97d47f54 81b0b3ba nt!IofCallDriver+0x3f
97d47f40 81b0b3ba 891873d4 ffffffff 81b317e8 Ntfs!NtfsStorageDriverCallout
+0x14
97d47f40 81ac3150 891873d4 ffffffff 81b317e8 nt!KiSwitchKernelStackAndCa
llout+0x9e
89187388 81ac2fcf 88a2bc30 891873d4 00003000 nt!KeExpandKernelStackAndCa
lloutInternal+0x16b
891873a8 88a26bd0 88a2bc30 891873d4 00003000 nt!KeExpandKernelStackAndCa
lloutEx+0x1f
89187400 88a260bf 00000001 857ab020 88a2bc8c Ntfs!NtfsMultipleAsync+0xb7
8918756c 88a21233 89187710 0001f000 00000000 Ntfs!NtfsNonCachedIo+0x2f7
89187708 88a22e3a 0150070a 00000000 00100801 Ntfs!NtfsCommonWrite+0xe00
891878dc 81a4ba7c 857d7018 85b0a7e0 85be7768 Ntfs!NtfsFsdWrite+0x187
891878f8 82a21a9f 85b0a7e0 857f5ba0 857f5ba0 nt!IofCallDriver+0x3f
89187934 82a217db 89187958 00000000 00000000 fltmgr!FltpLegacyProcessingAfte
rPreCallbacksCompleted+0x24c
89187970 81a816be 857f5ba0 85b0a7e0 89187a80 fltmgr!FltpDispatch+0xc6
8918798c 81a81281 84a80274 00187a80 891879d4 nt!IoSynchronousPageWrite+0x1de
volmgr!VmReadWrite第一个参数就是卷设备:
1: kd> !object 857acc20
Object: 857acc20
Type: (84a8c040) Device
然后,
VmReadWrite内部调用
IofCallDriver把irp传递给下层分区设备处理,分区设备是怎么找到的呢?看下ida这个函数的实现,咋调用
IofCallDriver的:
原来是通过卷设备的DeviceExtension+d0处找到下层分区设备的,这个disk到(小)端口设备很像,那个是+8:
1: kd> dt nt!_device_object 857acc20
1: kd> dd 0x857accd8+d0 l1
857acda8
85682430
1: kd> !object 85682430
Object: 85682430
Type: (84a8c040) Device
1: kd> !devobj 85682430
Device object (85682430) is for:
Current Irp 00000000 RefCount 0 Type 00000007 Flags 00000010
Dacl 8c0d152c DevExt 856824e8 DevObjExt 85682740
ExtensionFlags (0x00000800)
AttachedTo (Lower) 856827b0 \Driver\disk
Device queue is not busy.
1: kd> !devstack 85682430
> 85682430
\Driver\partmgr
856824e8
!DevNode 8554adc0 :
现在,怎么传递已经清楚了。那么,系统是如何获取卷设备下层的分区设备并填充在卷设备的扩展中的呢?
TODO