Possible to filter \\.\PhysicalDriveX access?

Hello,

I’ll first start with the obligatory “what are you trying to do?” description. I’d like to prevent direct physical disk access, even to admin accounts, according to policy. Creating a disk class filter this all works as expected when SetupDiXxx is used and the device path is opened directly via CreateFile. I get the IRP_MJ_CREATE, in the context of my user app, and if I complete the IRP as STATUS_ACCESS_DENIED, the user CreateFile call fails with that same status.

But if the user app opens \.\PhysicalDrive0 I do get a couple of calls into the disk filter, but completing them as access denied doesn’t cause the user app’s CreateFile to fail. As well, the call stack looks a bit “indirect” in these cases:

00 fffffe89f63e9018 fffff80122810b2a diskperf!DiskPerfCreate [d:\winddk\7600.16385.1\src\storage\filters\diskperf\diskperf.c @ 1020]
01 fffffe89f63e9020 fffff80122ebbd29 nt!IopfCallDriver+0x56
02 fffffe89f63e9060 fffff8012288e7af nt!IovCallDriver+0x275
03 fffffe89f63e90a0 fffff80122b6eba3 nt!IofCallDriver+0x14c97f
04 fffffe89f63e90e0 fffff80122b9e82b nt!IopParseDevice+0x773
05 fffffe89f63e92b0 fffff80122b6ccdf nt!ObpLookupObjectName+0x73b
06 fffffe89f63e9490 fffff80122b69045 nt!ObOpenObjectByNameEx+0x1df
07 fffffe89f63e95d0 fffff80122bba908 nt!IopCreateFile+0x3f5
08 fffffe89f63e9670 fffff80122863743 nt!NtOpenFile+0x58
09 fffffe89f63e9700 fffff80122856ac0 nt!KiSystemServiceCopyEnd+0x13
0a fffffe89f63e9908 fffff80122b3a163 nt!KiServiceLinkage
0b fffffe89f63e9910 fffff8004409b551 nt!IoGetDeviceObjectPointer+0x83
0c fffffe89f63e99a0 fffff8004409b3de fileinfo!FIVolumeGetInfo+0x111
0d fffffe89f63e9a90 fffff800433b7d53 fileinfo!FIVolumeQueryWorker+0x7e
0e fffffe89f63e9af0 fffff8012275eb25 FLTMGR!FltpProcessGenericWorkItem+0x93
0f fffffe89f63e9b80 fffff801227d92f7 nt!ExpWorkerThread+0xf5
10 fffffe89f63e9c10 fffff8012285a536 nt!PspSystemThreadStartup+0x47
11 fffffe89f63e9c60 0000000000000000 nt!KiStartSystemThread+0x16

This first call comes in via a fltmgr worker thread. At this same time I can see my app is waiting on a fltmgr queued request:

00 fffffe89f85bdd90 fffff80122859593 nt!KxDispatchInterrupt+0x12f
01 fffffe89f85bded0 fffff8012275e969 nt!KiDpcInterrupt+0x2a3
02 fffffe89f85be060 fffff801226bdeed nt!ExpQueueWorkItem+0x1d9
03 fffffe89f85be0f0 fffff8004338b7a5 nt!ExQueueWorkItem+0x3d
04 fffffe89f85be130 fffff8004409b7de FLTMGR!FltQueueGenericWorkItem+0xd5
05 fffffe89f85be190 fffff8004409d6a1 fileinfo!FIVolumeQueueQuery+0xde
06 fffffe89f85be1e0 fffff80043385cd4 fileinfo!FIPostCreateCallback+0x151
07 fffffe89f85be290 fffff80043385683 FLTMGR!FltpPerformPostCallbacks+0x2f4
08 fffffe89f85be360 fffff8004338726a FLTMGR!FltpPassThroughCompletionWorker+0x73
09 fffffe89f85be3d0 fffff800433bbbcd FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x1ba
0a fffffe89f85be440 fffff80122810b2a FLTMGR!FltpCreate+0x2dd
0b fffffe89f85be4f0 fffff80122ebbd29 nt!IopfCallDriver+0x56
0c fffffe89f85be530 fffff8012288e7af nt!IovCallDriver+0x275
0d fffffe89f85be570 fffff80122b6eba3 nt!IofCallDriver+0x14c97f
0e fffffe89f85be5b0 fffff80122b9e82b nt!IopParseDevice+0x773
0f fffffe89f85be780 fffff80122b6ccdf nt!ObpLookupObjectName+0x73b
10 fffffe89f85be960 fffff80122b69045 nt!ObOpenObjectByNameEx+0x1df
11 fffffe89f85beaa0 fffff80122bfb425 nt!IopCreateFile+0x3f5
12 fffffe89f85beb40 fffff800433be845 nt!IoCreateFileEx+0x115
13 fffffe89f85bebe0 fffff800433c0656 FLTMGR!FltpCreateFile+0x1cd
14 fffffe89f85bece0 fffff800433c0899 FLTMGR!FltOpenVolume+0xa6
15 fffffe89f85bedb0 fffff8004416d31a FLTMGR!FltQueryVolumeInformation+0x29
16 fffffe89f85bee00 fffff80044179719 WdFilter+0x1d31a
17 fffffe89f85beee0 fffff800433c02cc WdFilter+0x29719
18 fffffe89f85befd0 fffff800433bf62f FLTMGR!FltpDoInstanceSetupNotification+0x8c
19 fffffe89f85bf040 fffff800433bfbc4 FLTMGR!FltpInitInstance+0x2f3
1a fffffe89f85bf100 fffff800433bfe51 FLTMGR!FltpCreateInstanceFromName+0x1a0
1b fffffe89f85bf1e0 fffff800433c04fd FLTMGR!FltpEnumerateRegistryInstances+0x145
1c fffffe89f85bf280 fffff800433bbce9 FLTMGR!FltpDoFilterNotificationForNewVolume+0x131
1d fffffe89f85bf300 fffff80122810b2a FLTMGR!FltpCreate+0x3f9
1e fffffe89f85bf3b0 fffff80122ebbd29 nt!IopfCallDriver+0x56
1f fffffe89f85bf3f0 fffff8012288e7af nt!IovCallDriver+0x275
20 fffffe89f85bf430 fffff80122b6eba3 nt!IofCallDriver+0x14c97f
21 fffffe89f85bf470 fffff80122b9e82b nt!IopParseDevice+0x773
22 fffffe89f85bf640 fffff80122b6ccdf nt!ObpLookupObjectName+0x73b
23 fffffe89f85bf820 fffff80122b69045 nt!ObOpenObjectByNameEx+0x1df
24 fffffe89f85bf960 fffff80122b687a9 nt!IopCreateFile+0x3f5
25 fffffe89f85bfa00 fffff80122863743 nt!NtCreateFile+0x79
26 fffffe89f85bfa90 00007fff7b05b444 nt!KiSystemServiceCopyEnd+0x13
27 0000004f4a90f968 00007fff77684be8 ntdll!NtCreateFile+0x14
28 0000004f4a90f970 00007fff776848d6 KERNELBASE!CreateFileInternal+0x2f8
29 0000004f4a90fae0 00007ff723006b1f KERNELBASE!CreateFileW+0x66
2a 0000004f4a90fb40 00007ff72306a110 u!wmain+0x4f [d:\temp\u.cpp @ 17]

I fail that one with access denied and then I get one into the disk filter directly from my app:

00 fffffe89f85be0e8 fffff80122810b2a diskperf!DiskPerfCreate [d:\winddk\7600.16385.1\src\storage\filters\diskperf\diskperf.c @ 1020]
01 fffffe89f85be0f0 fffff80122ebbd29 nt!IopfCallDriver+0x56
02 fffffe89f85be130 fffff8012288e7af nt!IovCallDriver+0x275
03 fffffe89f85be170 fffff80122b6eba3 nt!IofCallDriver+0x14c97f
04 fffffe89f85be1b0 fffff80122b9e82b nt!IopParseDevice+0x773
05 fffffe89f85be380 fffff80122b6ccdf nt!ObpLookupObjectName+0x73b
06 fffffe89f85be560 fffff80122b69045 nt!ObOpenObjectByNameEx+0x1df
07 fffffe89f85be6a0 fffff80122bba908 nt!IopCreateFile+0x3f5
08 fffffe89f85be740 fffff80122863743 nt!NtOpenFile+0x58
09 fffffe89f85be7d0 fffff80122856ac0 nt!KiSystemServiceCopyEnd+0x13
0a fffffe89f85be9d8 fffff80122b3a163 nt!KiServiceLinkage
0b fffffe89f85be9e0 fffff80043d6a45f nt!IoGetDeviceObjectPointer+0x83
0c fffffe89f85bea70 fffff80043d6a382 mountmgr!QueryPointsFromMemory+0x6f
0d fffffe89f85beb70 fffff80043d6a0b7 mountmgr!MountMgrQueryPoints+0x1a2
0e fffffe89f85bebe0 fffff80122810b2a mountmgr!MountMgrDeviceControl+0xa7
0f fffffe89f85bec40 fffff80122ebbd29 nt!IopfCallDriver+0x56
10 fffffe89f85bec80 fffff8012288e7af nt!IovCallDriver+0x275
11 fffffe89f85becc0 fffff800433b5263 nt!IofCallDriver+0x14c97f
12 fffffe89f85bed00 fffff8004416d47d FLTMGR!FltGetVolumeGuidName+0x193
13 fffffe89f85bee00 fffff80044179719 WdFilter+0x1d47d
14 fffffe89f85beee0 fffff800433c02cc WdFilter+0x29719
15 fffffe89f85befd0 fffff800433bf62f FLTMGR!FltpDoInstanceSetupNotification+0x8c
16 fffffe89f85bf040 fffff800433bfbc4 FLTMGR!FltpInitInstance+0x2f3
17 fffffe89f85bf100 fffff800433bfe51 FLTMGR!FltpCreateInstanceFromName+0x1a0
18 fffffe89f85bf1e0 fffff800433c04fd FLTMGR!FltpEnumerateRegistryInstances+0x145
19 fffffe89f85bf280 fffff800433bbce9 FLTMGR!FltpDoFilterNotificationForNewVolume+0x131
1a fffffe89f85bf300 fffff80122810b2a FLTMGR!FltpCreate+0x3f9
1b fffffe89f85bf3b0 fffff80122ebbd29 nt!IopfCallDriver+0x56
1c fffffe89f85bf3f0 fffff8012288e7af nt!IovCallDriver+0x275
1d fffffe89f85bf430 fffff80122b6eba3 nt!IofCallDriver+0x14c97f
1e fffffe89f85bf470 fffff80122b9e82b nt!IopParseDevice+0x773
1f fffffe89f85bf640 fffff80122b6ccdf nt!ObpLookupObjectName+0x73b
20 fffffe89f85bf820 fffff80122b69045 nt!ObOpenObjectByNameEx+0x1df
21 fffffe89f85bf960 fffff80122b687a9 nt!IopCreateFile+0x3f5
22 fffffe89f85bfa00 fffff80122863743 nt!NtCreateFile+0x79
23 fffffe89f85bfa90 00007fff7b05b444 nt!KiSystemServiceCopyEnd+0x13
24 0000004f4a90f968 00007fff77684be8 ntdll!NtCreateFile+0x14
25 0000004f4a90f970 00007fff776848d6 KERNELBASE!CreateFileInternal+0x2f8
26 0000004f4a90fae0 00007ff723006b1f KERNELBASE!CreateFileW+0x66
27 0000004f4a90fb40 00007ff72306a110 u!wmain+0x4f [d:\temp\u.cpp @ 17]

Failed that one with access denied as well. And still the app gets success and a handle back from CreateFile.

I read through this old thread where Scott discussed a bit of the differences between the two namespaces, but my takeaway from that discussion was a disk filter should catch everything. It also seemed to suggest that a minifilter would catch the symlink names (but not the device interface names). However, I have a minifilter with a dbgbreak set in PreCreate on any file object where FileName->Buffer is NULL or FileName->Length is 0, and this never hits during the execution of my app. So it would appear that a minifilter is not able to reliably intercept this access, nor the disk filter. Is this by design? If a direct symlink is created to a device, as disk class seems to do with the PhysicalDriveX names, is that just not able to be filtered?

ref: https://community.osr.com/discussion/264621/filtering-disk-io

Thanks,
-JT

1 Like

I may be wrong here, but, IIRC, when you open a disk in a “.\PhysicalDrive0” form, what you are actually opening is not a disk per se
(i.e. a DO created by Disk.sys) but the one that is mounted on it (i.e. the one that, in actuality, owned and managed by the “Raw FS” filesystem). A call stack trace that you have provided seems to support my theory - otherwise, I just don’t see any reason why mountmgr and
fltmgr should be on a call stack

In other words, you may be just filtering the wrong device.

Anton Bassov

Thanks for the reply.

What I’m seeing is the device interface path is this:

\?\scsi#disk&ven_vmware_&prod_vmware_virtual_s#5&1ec51bf7&0&000100#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}

And per WinObj that maps to \Device\00000069

\?\PhysicalDrive0 maps to \Device\Harddisk0\DR0

I can also see that the disk class driver creates the \Device\Harddisk0\DR0 name and links it to the FDO. So it would seem that PhysicalDrive0 does point to a disk class device object. But my question is whether a disk class filter will be involved in the opening of this symlink or if that access will go directly to the disk class level and bypass any upper filters.

ref: https://github.com/microsoft/Windows-driver-samples/blob/3428c5feaac7c1a5e2a09db0ed93392f7568f9e6/storage/class/disk/src/disk.c#L417

DiskGenerateDeviceName is the routine that comes up the the Harddisk0\DR0 syntax.

ref: https://github.com/microsoft/Windows-driver-samples/blob/6c1981b8504329521343ad00f32daa847fa6083a/storage/class/disk/src/pnp.c#L630

Also, looking in DeviceTree, I see \Device\Harddisk0\DR0 under \Driver\Disk and I see \Driver\partmgr attached to the device and my filter attached to partmgr. So if the create were going down the disk stack from the top it should be hitting me, right?

-JT

But my question is whether a disk class filter will be involved in the opening of this symlink or if that access will go directly to the disk class level and bypass any upper filters.

Well, no. I’d be very surprised to find the filter bypassed.

If the open is being redirected via the file system, however, I’m not sure there’s any reason that you’d see the Create IRP. Creates aren’t necessarily “passed down”…

Can you give us the same data the guy did in the other thread? Using the debugger, dump the handle, the file object, and the device stack. That would clear things up nicely here (as it did there).

Peter

?\PhysicalDrive0 maps to \Device\Harddisk0\DR0

If this is, indeed, the case, I simply don’t understand why we see fltmgr and mntmgr in a call stack trace.
After all, their presence in a call stack somehow implies a mounted device, so that I would not expect to see them in a call stack
trace if a request was sent directly to \Device\Harddisk0\DR0

Also, looking in DeviceTree, I see \Device\Harddisk0\DR0 under \Driver\Disk and I see \Driver\partmgr attached to the device
and my filter attached to partmgr.

However, you don’t see either fltmgr or mntmgr on this stack, do you. Therefore, it is pretty obvious that a call to
CreateFile( “?\PhysicalDrive0” ,…) results in IRP_MJ_CREATE request that gets sent to some device that is NOT on the same device stack
with \Device\Harddisk0\DR0, and this device’s driver subsequently sends a secondary request to \Device\Harddisk0\DR0.
Your filter is on the same stack with the target \Device\Harddisk0\DR0, so that it is in a position to abort this secondary request with STATUS_ACCESS_DENIED. However, it does not necessarily imply that the original IRP_MJ_CREATE request gets aborted with the same
status - after all, this is a different device stack, so that your filter cannot directly control it.

Sounds reasonable, don’t you think?

Anton Bassov

This is the first call stack in the disk filter’s create dispatch, coming in under a system worker thread:

00 ffff920e0eee4018 fffff8016f203b2a diskperf!DiskPerfCreate [d:\winddk\7600.16385.1\src\storage\filters\diskperf\diskperf.c @ 1020]
01 ffff920e0eee4020 fffff8016f8aed29 nt!IopfCallDriver+0x56
02 ffff920e0eee4060 fffff8016f2817af nt!IovCallDriver+0x275
03 ffff920e0eee40a0 fffff8016f561ba3 nt!IofCallDriver+0x14c97f
04 ffff920e0eee40e0 fffff8016f59182b nt!IopParseDevice+0x773
05 ffff920e0eee42b0 fffff8016f55fcdf nt!ObpLookupObjectName+0x73b
06 ffff920e0eee4490 fffff8016f55c045 nt!ObOpenObjectByNameEx+0x1df
07 ffff920e0eee45d0 fffff8016f5ad908 nt!IopCreateFile+0x3f5
08 ffff920e0eee4670 fffff8016f256743 nt!NtOpenFile+0x58
09 ffff920e0eee4700 fffff8016f249ac0 nt!KiSystemServiceCopyEnd+0x13
0a ffff920e0eee4908 fffff8016f52d163 nt!KiServiceLinkage
0b ffff920e0eee4910 fffff80de5cfb551 nt!IoGetDeviceObjectPointer+0x83
0c ffff920e0eee49a0 fffff80de5cfb3de fileinfo!FIVolumeGetInfo+0x111
0d ffff920e0eee4a90 fffff80de4e37d53 fileinfo!FIVolumeQueryWorker+0x7e
0e ffff920e0eee4af0 fffff8016f151b25 FLTMGR!FltpProcessGenericWorkItem+0x93
0f ffff920e0eee4b80 fffff8016f1cc2f7 nt!ExpWorkerThread+0xf5
10 ffff920e0eee4c10 fffff8016f24d536 nt!PspSystemThreadStartup+0x47
11 ffff920e0eee4c60 0000000000000000 nt!KiStartSystemThread+0x16

fileobj = 0xffffe78114d6a360, devobj = 0xffffe78114c3b290

kd> !fileobj 0xffffe781`14d6a360
Device Object: 0xffffe78114c3b6d0 \Driver\Disk
Vpb is NULL

Flags: 0x800
Direct Device Open

CurrentByteOffset: 0

kd> !devobj 0xffffe781`14c3b290
Device object (ffffe78114c3b290) is for:
\Driver\diskperf DriverObject ffffe78114c31750
Current Irp 00000000 RefCount 0 Type 00000007 Flags 00000010
Vpb ffffe78114c3b1f0 SecurityDescriptor ffff9d89207528a0 DevExt ffffe78114c3b3e0 DevObjExt ffffe78114c3b520 Dope ffffe78114c3b180
ExtensionFlags (0x80000800) DOE_DEFAULT_SD_PRESENT, DOE_DESIGNATED_FDO
Characteristics (0x00040100) FILE_DEVICE_SECURE_OPEN, FILE_PORTABLE_DEVICE
AttachedTo (Lower) ffffe78114c3c040 \Driver\partmgr

Then this is the second time the disk filter’s create dispatch is entered, this time in the context of my app

00 ffff920e113d30e8 fffff8016f203b2a diskperf!DiskPerfCreate [d:\winddk\7600.16385.1\src\storage\filters\diskperf\diskperf.c @ 1020]
01 ffff920e113d30f0 fffff8016f8aed29 nt!IopfCallDriver+0x56
02 ffff920e113d3130 fffff8016f2817af nt!IovCallDriver+0x275
03 ffff920e113d3170 fffff8016f561ba3 nt!IofCallDriver+0x14c97f
04 ffff920e113d31b0 fffff8016f59182b nt!IopParseDevice+0x773
05 ffff920e113d3380 fffff8016f55fcdf nt!ObpLookupObjectName+0x73b
06 ffff920e113d3560 fffff8016f55c045 nt!ObOpenObjectByNameEx+0x1df
07 ffff920e113d36a0 fffff8016f5ad908 nt!IopCreateFile+0x3f5
08 ffff920e113d3740 fffff8016f256743 nt!NtOpenFile+0x58
09 ffff920e113d37d0 fffff8016f249ac0 nt!KiSystemServiceCopyEnd+0x13
0a ffff920e113d39d8 fffff8016f52d163 nt!KiServiceLinkage
0b ffff920e113d39e0 fffff80de658a45f nt!IoGetDeviceObjectPointer+0x83
0c ffff920e113d3a70 fffff80de658a382 mountmgr!QueryPointsFromMemory+0x6f
0d ffff920e113d3b70 fffff80de658a0b7 mountmgr!MountMgrQueryPoints+0x1a2
0e ffff920e113d3be0 fffff8016f203b2a mountmgr!MountMgrDeviceControl+0xa7
0f ffff920e113d3c40 fffff8016f8aed29 nt!IopfCallDriver+0x56
10 ffff920e113d3c80 fffff8016f2817af nt!IovCallDriver+0x275
11 ffff920e113d3cc0 fffff80de4e35263 nt!IofCallDriver+0x14c97f
12 ffff920e113d3d00 fffff80de5dcd47d FLTMGR!FltGetVolumeGuidName+0x193
13 ffff920e113d3e00 fffff80de5dd9719 WdFilter+0x1d47d
14 ffff920e113d3ee0 fffff80de4e402cc WdFilter+0x29719
15 ffff920e113d3fd0 fffff80de4e3f62f FLTMGR!FltpDoInstanceSetupNotification+0x8c
16 ffff920e113d4040 fffff80de4e3fbc4 FLTMGR!FltpInitInstance+0x2f3
17 ffff920e113d4100 fffff80de4e3fe51 FLTMGR!FltpCreateInstanceFromName+0x1a0
18 ffff920e113d41e0 fffff80de4e404fd FLTMGR!FltpEnumerateRegistryInstances+0x145
19 ffff920e113d4280 fffff80de4e3bce9 FLTMGR!FltpDoFilterNotificationForNewVolume+0x131
1a ffff920e113d4300 fffff8016f203b2a FLTMGR!FltpCreate+0x3f9
1b ffff920e113d43b0 fffff8016f8aed29 nt!IopfCallDriver+0x56
1c ffff920e113d43f0 fffff8016f2817af nt!IovCallDriver+0x275
1d ffff920e113d4430 fffff8016f561ba3 nt!IofCallDriver+0x14c97f
1e ffff920e113d4470 fffff8016f59182b nt!IopParseDevice+0x773
1f ffff920e113d4640 fffff8016f55fcdf nt!ObpLookupObjectName+0x73b
20 ffff920e113d4820 fffff8016f55c045 nt!ObOpenObjectByNameEx+0x1df
21 ffff920e113d4960 fffff8016f55b7a9 nt!IopCreateFile+0x3f5
22 ffff920e113d4a00 fffff8016f256743 nt!NtCreateFile+0x79
23 ffff920e113d4a90 00007ffa4581b444 nt!KiSystemServiceCopyEnd+0x13
24 000000ce1d0ff418 00007ffa426d4be8 ntdll!NtCreateFile+0x14
25 000000ce1d0ff420 00007ffa426d48d6 KERNELBASE!CreateFileInternal+0x2f8
26 000000ce1d0ff590 00007ff7c808b771 KERNELBASE!CreateFileW+0x66
27 000000ce1d0ff5f0 006b007300000000 u!wmain+0x71 [d:\temp\u.cpp @ 19]

This time, fileobj = 0xffffe78118240b90, devobj = 0xffffe78114c3b290

kd> !fileobj 0xffffe781`18240b90

Device Object: 0xffffe78114c3b6d0 \Driver\Disk
Vpb is NULL

Flags: 0x800
Direct Device Open

CurrentByteOffset: 0

!devobj 0xffffe781`14c3b290

Device object (ffffe78114c3b290) is for:
\Driver\diskperf DriverObject ffffe78114c31750
Current Irp 00000000 RefCount 0 Type 00000007 Flags 00000010
Vpb ffffe78114c3b1f0 SecurityDescriptor ffff9d89207528a0 DevExt ffffe78114c3b3e0 DevObjExt ffffe78114c3b520 Dope ffffe78114c3b180
ExtensionFlags (0x80000800) DOE_DEFAULT_SD_PRESENT, DOE_DESIGNATED_FDO
Characteristics (0x00040100) FILE_DEVICE_SECURE_OPEN, FILE_PORTABLE_DEVICE
AttachedTo (Lower) ffffe78114c3c040 \Driver\partmgr

This is the 3rd time it comes into the disk filter’s create:

00 ffff920e113d3208 fffff8016f203b2a diskperf!DiskPerfCreate [d:\winddk\7600.16385.1\src\storage\filters\diskperf\diskperf.c @ 1020]
01 ffff920e113d3210 fffff8016f8aed29 nt!IopfCallDriver+0x56
02 ffff920e113d3250 fffff8016f2817af nt!IovCallDriver+0x275
03 ffff920e113d3290 fffff8016f561ba3 nt!IofCallDriver+0x14c97f
04 ffff920e113d32d0 fffff8016f59182b nt!IopParseDevice+0x773
05 ffff920e113d34a0 fffff8016f55fcdf nt!ObpLookupObjectName+0x73b
06 ffff920e113d3680 fffff8016f55c045 nt!ObOpenObjectByNameEx+0x1df
07 ffff920e113d37c0 fffff8016f5ad908 nt!IopCreateFile+0x3f5
08 ffff920e113d3860 fffff8016f256743 nt!NtOpenFile+0x58
09 ffff920e113d38f0 fffff8016f249ac0 nt!KiSystemServiceCopyEnd+0x13
0a ffff920e113d3af8 fffff8016f52d163 nt!KiServiceLinkage
0b ffff920e113d3b00 fffff80de658a45f nt!IoGetDeviceObjectPointer+0x83
0c ffff920e113d3b90 fffff80de658a382 mountmgr!QueryPointsFromMemory+0x6f
0d ffff920e113d3c90 fffff80de658a0b7 mountmgr!MountMgrQueryPoints+0x1a2
0e ffff920e113d3d00 fffff8016f203b2a mountmgr!MountMgrDeviceControl+0xa7
0f ffff920e113d3d60 fffff8016f8aed29 nt!IopfCallDriver+0x56
10 ffff920e113d3da0 fffff8016f2817af nt!IovCallDriver+0x275
11 ffff920e113d3de0 fffff80de4e35263 nt!IofCallDriver+0x14c97f
12 ffff920e113d3e20 fffff80de8f67626 FLTMGR!FltGetVolumeGuidName+0x193
13 ffff920e113d3f20 fffff80de4e5dea5 TestMini!TestMiniInstanceSetup+0x126
14 ffff920e113d3f70 fffff80de4e402cc FLTMGR!FltvInstanceSetup+0x55
15 ffff920e113d3fd0 fffff80de4e3f62f FLTMGR!FltpDoInstanceSetupNotification+0x8c
16 ffff920e113d4040 fffff80de4e3fbc4 FLTMGR!FltpInitInstance+0x2f3
17 ffff920e113d4100 fffff80de4e3fe51 FLTMGR!FltpCreateInstanceFromName+0x1a0
18 ffff920e113d41e0 fffff80de4e404fd FLTMGR!FltpEnumerateRegistryInstances+0x145
19 ffff920e113d4280 fffff80de4e3bce9 FLTMGR!FltpDoFilterNotificationForNewVolume+0x131
1a ffff920e113d4300 fffff8016f203b2a FLTMGR!FltpCreate+0x3f9
1b ffff920e113d43b0 fffff8016f8aed29 nt!IopfCallDriver+0x56
1c ffff920e113d43f0 fffff8016f2817af nt!IovCallDriver+0x275
1d ffff920e113d4430 fffff8016f561ba3 nt!IofCallDriver+0x14c97f
1e ffff920e113d4470 fffff8016f59182b nt!IopParseDevice+0x773
1f ffff920e113d4640 fffff8016f55fcdf nt!ObpLookupObjectName+0x73b
20 ffff920e113d4820 fffff8016f55c045 nt!ObOpenObjectByNameEx+0x1df
21 ffff920e113d4960 fffff8016f55b7a9 nt!IopCreateFile+0x3f5
22 ffff920e113d4a00 fffff8016f256743 nt!NtCreateFile+0x79
23 ffff920e113d4a90 00007ffa4581b444 nt!KiSystemServiceCopyEnd+0x13
24 000000ce1d0ff418 00007ffa426d4be8 ntdll!NtCreateFile+0x14
25 000000ce1d0ff420 00007ffa426d48d6 KERNELBASE!CreateFileInternal+0x2f8
26 000000ce1d0ff590 00007ff7c808b771 KERNELBASE!CreateFileW+0x66
27 000000ce1d0ff5f0 006b007300000000 u!wmain+0x71 [d:\temp\u.cpp @ 19]

(Continued next post, length too long)

This time in the context of my user app and also triggering an instance setup in a minifilter I have loaded

fileobj = 0xffffe78118240b90 , devobj = 0xffffe78114c3b290

kd> !fileobj 0xffffe781`18240b90

Device Object: 0xffffe78114c3b6d0 \Driver\Disk
Vpb is NULL

Flags: 0x800
Direct Device Open

CurrentByteOffset: 0

Of note, I have a breakpoint in the minifilter’s PreCreate for any NULL or 0-length filename fileobjects, but it isn’t hitting. In other words, no real opportunity to intercept via a minifilter it would seem.

Now the post-CreateFile breakpoint hits in the user app, and the handle is explored:

kd> !handle 84

PROCESS ffffe781162a4080
SessionId: 1 Cid: 1950 Peb: ce1ce1e000 ParentCid: 1f18
DirBase: 36480002 ObjectTable: ffff9d89234af040 HandleCount: 33.
Image: u.exe

Handle table at ffff9d89234af040 with 33 entries in use

0084: Object: ffffe7811800fd40 GrantedAccess: 0012019f (Protected) Entry: ffff9d892449b210
Object: ffffe7811800fd40 Type: (ffffe78112320dc0) File
ObjectHeader: ffffe7811800fd10 (new version)
HandleCount: 1 PointerCount: 1

kd> !fileobj ffffe7811800fd40

Device Object: 0xffffe78114c3b6d0 \Driver\Disk
Vpb: 0xffffe78114c3b610
Event signalled
Access: Read Write

Flags: 0x44000a
Synchronous IO
No Intermediate Buffering
Handle Created
Volume Open

FsContext: 0xffffe7811790a3b0 FsContext2: 0x00000000
CurrentByteOffset: 0

In summary, the disk filter’s create is called 3 times, with 3 different fileobjs, none of which correspond to the handle the app eventually gets. The handle refers to a disk device object, yet the disk filter doesn’t seem to get that direct open. The minifilter doesn’t seem to get this either, which makes sense with the VPB being null in all cases.

So where exactly would I filter this such that I could change the outcome of the open?

Thanks!
-JT

Thanks for the input from both of you. In the end, Anton’s comment about the raw file system kept rolling around in my head and I finally figured out a solution. Tracing the NtCreateFile for \?\PhysicalDrive0 didn’t turn up anything in terms of figuring out a particular device stack that an IRP was being sent down. It was simply looking up an existing object in the object manager. But when I looked at that object and saw it was a file object, I saw this time it did have a VPB:

kd> dx -id 0,0,ffffad87f1b56580 -r1 ((ntdll!_VPB *)0xffffad87f2640850)
((ntdll!_VPB *)0xffffad87f2640850) : 0xffffad87f2640850 [Type: _VPB *]
[+0x000] Type : 10 [Type: short]
[+0x002] Size : 96 [Type: short]
[+0x004] Flags : 0x31 [Type: unsigned short]
[+0x006] VolumeLabelLength : 0x0 [Type: unsigned short]
[+0x008] DeviceObject : 0xffffad87f61cb060 : Device for “\FileSystem\RAW” [Type: _DEVICE_OBJECT *]
[+0x010] RealDevice : 0xffffad87f26416d0 : Device for “\Driver\Disk” [Type: _DEVICE_OBJECT *]
[+0x018] SerialNumber : 0xffffffff [Type: unsigned long]
[+0x01c] ReferenceCount : 0x1 [Type: unsigned long]
[+0x020] VolumeLabel : “” [Type: wchar_t [32]]

Seeing the RAW FS immediately triggered the floating Anton bubble saying “I already told you this!”

Next by having my minifilter attach to raw file systems, I got an instance setup (the one we saw earlier) when the CreateFile is issued and now that I’m attached I get a PreCreate with FO_VOLUME_OPEN set in the FO. The “volume” part seems a bit misleading, but querying the volume name I get \Device\Harddisk0\DR0. And, thankfully, if I complete PreCreate with access denied the user mode CreateFile fails accordingly.

So all is well. A minifilter attached to raw instances captures the \.\PhysicalDriveX pathway and a disk filter catches the device interface pathway.

Thanks for sticking with me and shoving me in the right direction.

-JT

You just NEVER can tell when Anton will end-up being helpful.

Glad you got things sorted Mr. Jason_T.

Peter

You just NEVER can tell when Anton will end-up being helpful.

Do you mean that you are about to retract the second half of the statement below? :slight_smile:

[begin quote]

Bear in mind that Anton hasn’t written any code on Windows for about ten years. He just hangs out here for the abuse.

[end quote]

In any case, let’s look at the whole thing objectively. Someone who has not seen a Windows screen since 2007 takes
a brief glance at the call stack trace, and immediately solves the riddle that one of the most renowned experts of
Windows driver development (and I mean it - there is no irony/sarcasm in my words whatsoever) finds confusing.

Don’t you find it…ugh,“amusing”, so to say???

Anton Bassov

Are you familiar with the English aphorism involving a blind squirrel and a nut?

Don’t answer. Just don’t.

Peter

Are you familiar with the English aphorism involving a blind squirrel and a nut?

Well, being a reasonably well-educated person, I am familiar with quite a few things, including, but not limited to,
the English aphorisms involving a blind man/pig/squirrel and respectively a crow/truffle/nut( or acorn, to be more precise).
I just don’t understand how they may possibly apply to this particular situation - apparently, you must be just judging it by
your own standards, right.

In addition to that, I am also familiar with Sir Arthur Conan Doyle’s books. I am not sure if you know it, but so-called
“deductive method”, attributed to his fictional character Sherlock Holmes, was actually used by Dr. Joseph Bell, who happened
to be a real-life prototype (or at least an inspiration) of the above mentioned character.

https://en.wikipedia.org/wiki/Joseph_Bell

Once this method was designed for diagnosing the medical conditions, it may be of the particular use when it comes to debugging,
analysing crash dumps et al. You just had a chance to see with your own eyes how it works when applied to Windows
driver development.

If you look at the whole thing from the app’s perspective, ?\PhysicalDriveX and \Device\HarddiskX\DRX are equivalent.
However, if they actually referred to the same DO (i.e. if one of them was just a symbolic link to another) one would never
had a chance to observe the scenario that the OP had encountered, right. Therefore, we can conclude that these are two different DOs.

Furthermore, we know that you cannot have more than one named device (i.e.a PDO at the bottom of the stack)
in a PnP device stack, right. Therefore, one of these DOs must be mounted on another one, and the call stack trace confirms
this assertion - after all, you can see mountmgr in a call stack. Furthermore, fltmgr is present in the call stack as well,
and, to simplify the things even more for us, it happens to be the first module to appear on the call stack. At this point
we can logically conclude that ?\PhysicalDriveX is managed by some filesystem.

Once ?\PhysicalDriveX and \Device\HarddiskX\DRX are, from the app’s perspective, equivalent to one another, an app must
ALWAYS be in a position to access the target disk as ?\PhysicalDriveX, even if the target disk is not formatted.
This leads us to the conclusion that the only filesystem that may possibly manage ?\PhysicalDriveX is \FileSystem\RAW.

In other words,“Elementary, My Dear Watson” (although, ironically, this particular phrase has NEVER been actually
uttered in any of the original 56 short stories or 4 novels starring Sherlock Holmes)…

Anton Bassov