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 fffff801
22810b2a diskperf!DiskPerfCreate [d:\winddk\7600.16385.1\src\storage\filters\diskperf\diskperf.c @ 1020]
01 fffffe89f63e9020 fffff801
22ebbd29 nt!IopfCallDriver+0x56
02 fffffe89f63e9060 fffff801
2288e7af nt!IovCallDriver+0x275
03 fffffe89f63e90a0 fffff801
22b6eba3 nt!IofCallDriver+0x14c97f
04 fffffe89f63e90e0 fffff801
22b9e82b nt!IopParseDevice+0x773
05 fffffe89f63e92b0 fffff801
22b6ccdf nt!ObpLookupObjectName+0x73b
06 fffffe89f63e9490 fffff801
22b69045 nt!ObOpenObjectByNameEx+0x1df
07 fffffe89f63e95d0 fffff801
22bba908 nt!IopCreateFile+0x3f5
08 fffffe89f63e9670 fffff801
22863743 nt!NtOpenFile+0x58
09 fffffe89f63e9700 fffff801
22856ac0 nt!KiSystemServiceCopyEnd+0x13
0a fffffe89f63e9908 fffff801
22b3a163 nt!KiServiceLinkage
0b fffffe89f63e9910 fffff800
4409b551 nt!IoGetDeviceObjectPointer+0x83
0c fffffe89f63e99a0 fffff800
4409b3de fileinfo!FIVolumeGetInfo+0x111
0d fffffe89f63e9a90 fffff800
433b7d53 fileinfo!FIVolumeQueryWorker+0x7e
0e fffffe89f63e9af0 fffff801
2275eb25 FLTMGR!FltpProcessGenericWorkItem+0x93
0f fffffe89f63e9b80 fffff801
227d92f7 nt!ExpWorkerThread+0xf5
10 fffffe89f63e9c10 fffff801
2285a536 nt!PspSystemThreadStartup+0x47
11 fffffe89f63e9c60 00000000
00000000 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 fffff801
22859593 nt!KxDispatchInterrupt+0x12f
01 fffffe89f85bded0 fffff801
2275e969 nt!KiDpcInterrupt+0x2a3
02 fffffe89f85be060 fffff801
226bdeed nt!ExpQueueWorkItem+0x1d9
03 fffffe89f85be0f0 fffff800
4338b7a5 nt!ExQueueWorkItem+0x3d
04 fffffe89f85be130 fffff800
4409b7de FLTMGR!FltQueueGenericWorkItem+0xd5
05 fffffe89f85be190 fffff800
4409d6a1 fileinfo!FIVolumeQueueQuery+0xde
06 fffffe89f85be1e0 fffff800
43385cd4 fileinfo!FIPostCreateCallback+0x151
07 fffffe89f85be290 fffff800
43385683 FLTMGR!FltpPerformPostCallbacks+0x2f4
08 fffffe89f85be360 fffff800
4338726a FLTMGR!FltpPassThroughCompletionWorker+0x73
09 fffffe89f85be3d0 fffff800
433bbbcd FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x1ba
0a fffffe89f85be440 fffff801
22810b2a FLTMGR!FltpCreate+0x2dd
0b fffffe89f85be4f0 fffff801
22ebbd29 nt!IopfCallDriver+0x56
0c fffffe89f85be530 fffff801
2288e7af nt!IovCallDriver+0x275
0d fffffe89f85be570 fffff801
22b6eba3 nt!IofCallDriver+0x14c97f
0e fffffe89f85be5b0 fffff801
22b9e82b nt!IopParseDevice+0x773
0f fffffe89f85be780 fffff801
22b6ccdf nt!ObpLookupObjectName+0x73b
10 fffffe89f85be960 fffff801
22b69045 nt!ObOpenObjectByNameEx+0x1df
11 fffffe89f85beaa0 fffff801
22bfb425 nt!IopCreateFile+0x3f5
12 fffffe89f85beb40 fffff800
433be845 nt!IoCreateFileEx+0x115
13 fffffe89f85bebe0 fffff800
433c0656 FLTMGR!FltpCreateFile+0x1cd
14 fffffe89f85bece0 fffff800
433c0899 FLTMGR!FltOpenVolume+0xa6
15 fffffe89f85bedb0 fffff800
4416d31a FLTMGR!FltQueryVolumeInformation+0x29
16 fffffe89f85bee00 fffff800
44179719 WdFilter+0x1d31a
17 fffffe89f85beee0 fffff800
433c02cc WdFilter+0x29719
18 fffffe89f85befd0 fffff800
433bf62f FLTMGR!FltpDoInstanceSetupNotification+0x8c
19 fffffe89f85bf040 fffff800
433bfbc4 FLTMGR!FltpInitInstance+0x2f3
1a fffffe89f85bf100 fffff800
433bfe51 FLTMGR!FltpCreateInstanceFromName+0x1a0
1b fffffe89f85bf1e0 fffff800
433c04fd FLTMGR!FltpEnumerateRegistryInstances+0x145
1c fffffe89f85bf280 fffff800
433bbce9 FLTMGR!FltpDoFilterNotificationForNewVolume+0x131
1d fffffe89f85bf300 fffff801
22810b2a FLTMGR!FltpCreate+0x3f9
1e fffffe89f85bf3b0 fffff801
22ebbd29 nt!IopfCallDriver+0x56
1f fffffe89f85bf3f0 fffff801
2288e7af nt!IovCallDriver+0x275
20 fffffe89f85bf430 fffff801
22b6eba3 nt!IofCallDriver+0x14c97f
21 fffffe89f85bf470 fffff801
22b9e82b nt!IopParseDevice+0x773
22 fffffe89f85bf640 fffff801
22b6ccdf nt!ObpLookupObjectName+0x73b
23 fffffe89f85bf820 fffff801
22b69045 nt!ObOpenObjectByNameEx+0x1df
24 fffffe89f85bf960 fffff801
22b687a9 nt!IopCreateFile+0x3f5
25 fffffe89f85bfa00 fffff801
22863743 nt!NtCreateFile+0x79
26 fffffe89f85bfa90 00007fff
7b05b444 nt!KiSystemServiceCopyEnd+0x13
27 0000004f4a90f968 00007fff
77684be8 ntdll!NtCreateFile+0x14
28 0000004f4a90f970 00007fff
776848d6 KERNELBASE!CreateFileInternal+0x2f8
29 0000004f4a90fae0 00007ff7
23006b1f KERNELBASE!CreateFileW+0x66
2a 0000004f4a90fb40 00007ff7
2306a110 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 fffff801
22810b2a diskperf!DiskPerfCreate [d:\winddk\7600.16385.1\src\storage\filters\diskperf\diskperf.c @ 1020]
01 fffffe89f85be0f0 fffff801
22ebbd29 nt!IopfCallDriver+0x56
02 fffffe89f85be130 fffff801
2288e7af nt!IovCallDriver+0x275
03 fffffe89f85be170 fffff801
22b6eba3 nt!IofCallDriver+0x14c97f
04 fffffe89f85be1b0 fffff801
22b9e82b nt!IopParseDevice+0x773
05 fffffe89f85be380 fffff801
22b6ccdf nt!ObpLookupObjectName+0x73b
06 fffffe89f85be560 fffff801
22b69045 nt!ObOpenObjectByNameEx+0x1df
07 fffffe89f85be6a0 fffff801
22bba908 nt!IopCreateFile+0x3f5
08 fffffe89f85be740 fffff801
22863743 nt!NtOpenFile+0x58
09 fffffe89f85be7d0 fffff801
22856ac0 nt!KiSystemServiceCopyEnd+0x13
0a fffffe89f85be9d8 fffff801
22b3a163 nt!KiServiceLinkage
0b fffffe89f85be9e0 fffff800
43d6a45f nt!IoGetDeviceObjectPointer+0x83
0c fffffe89f85bea70 fffff800
43d6a382 mountmgr!QueryPointsFromMemory+0x6f
0d fffffe89f85beb70 fffff800
43d6a0b7 mountmgr!MountMgrQueryPoints+0x1a2
0e fffffe89f85bebe0 fffff801
22810b2a mountmgr!MountMgrDeviceControl+0xa7
0f fffffe89f85bec40 fffff801
22ebbd29 nt!IopfCallDriver+0x56
10 fffffe89f85bec80 fffff801
2288e7af nt!IovCallDriver+0x275
11 fffffe89f85becc0 fffff800
433b5263 nt!IofCallDriver+0x14c97f
12 fffffe89f85bed00 fffff800
4416d47d FLTMGR!FltGetVolumeGuidName+0x193
13 fffffe89f85bee00 fffff800
44179719 WdFilter+0x1d47d
14 fffffe89f85beee0 fffff800
433c02cc WdFilter+0x29719
15 fffffe89f85befd0 fffff800
433bf62f FLTMGR!FltpDoInstanceSetupNotification+0x8c
16 fffffe89f85bf040 fffff800
433bfbc4 FLTMGR!FltpInitInstance+0x2f3
17 fffffe89f85bf100 fffff800
433bfe51 FLTMGR!FltpCreateInstanceFromName+0x1a0
18 fffffe89f85bf1e0 fffff800
433c04fd FLTMGR!FltpEnumerateRegistryInstances+0x145
19 fffffe89f85bf280 fffff800
433bbce9 FLTMGR!FltpDoFilterNotificationForNewVolume+0x131
1a fffffe89f85bf300 fffff801
22810b2a FLTMGR!FltpCreate+0x3f9
1b fffffe89f85bf3b0 fffff801
22ebbd29 nt!IopfCallDriver+0x56
1c fffffe89f85bf3f0 fffff801
2288e7af nt!IovCallDriver+0x275
1d fffffe89f85bf430 fffff801
22b6eba3 nt!IofCallDriver+0x14c97f
1e fffffe89f85bf470 fffff801
22b9e82b nt!IopParseDevice+0x773
1f fffffe89f85bf640 fffff801
22b6ccdf nt!ObpLookupObjectName+0x73b
20 fffffe89f85bf820 fffff801
22b69045 nt!ObOpenObjectByNameEx+0x1df
21 fffffe89f85bf960 fffff801
22b687a9 nt!IopCreateFile+0x3f5
22 fffffe89f85bfa00 fffff801
22863743 nt!NtCreateFile+0x79
23 fffffe89f85bfa90 00007fff
7b05b444 nt!KiSystemServiceCopyEnd+0x13
24 0000004f4a90f968 00007fff
77684be8 ntdll!NtCreateFile+0x14
25 0000004f4a90f970 00007fff
776848d6 KERNELBASE!CreateFileInternal+0x2f8
26 0000004f4a90fae0 00007ff7
23006b1f KERNELBASE!CreateFileW+0x66
27 0000004f4a90fb40 00007ff7
2306a110 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