supporting removable media

Hi all,

I am writing a file system filter driver, which mounts files as volumes and translates IO requests to/from the volume to/from the mounted file. My volume DeviceObject is marked as removable and I read the MSDN articles referring to removable media support.
Here is how I think media change in my case should be detected:

  • whenever a IOCTL_DISK_CHECK_VERIFY arrives to the volume, I check whether the mounted file is available; this is done by sending a FSCTL_IS_VOLUME_MOUNTED request to the FS hosting the file
  • if the call succeeds, the “media” is still there
  • if the call fails, the “media” has changed and the following procedure is followed:
  • if the volume is mounted, the DO_VERIFY_VOLUME bit is set and STATUS_VERIFY_REQUIRED returned
  • if it is not mounted, STATUS_IO_DEVICE_ERROR is returned
    However, when I forcefully make the mounted file unavailable (removing the USB stick hosting it, for example), my driver causes a double fault bugcheck, because of kernel stack overflow. If I check for FSCTL_IS_VOLUME_MOUNTED but return success whatever the result is (not marking DO_VERIFY_VOLUME), no blue screen happens.
    Any help would be welcome.
    Here is the debug data I gathered:

BugCheck 7F, {8, 807c9750, 0, 0}
1: kd> kf
99dce024 82a85f4e nt!_SEH_prolog4+0x1a
14 99dce038 82a8242a nt!NtContinue+0x22
0 99dce038 82a7fe55 nt!KiFastCallEntry+0x12a
80 99dce0b8 82af85cc nt!ZwContinue+0x11
3a0 99dce458 93a41303 nt!RtlUnwind+0xc3
24 99dce47c 93a410a7 fastfat!_EH4_GlobalUnwind+0x15
28 99dce4a4 82aa7822 fastfat!_except_handler4+0xe7
24 99dce4c8 82aa77f4 nt!ExecuteHandler2+0x26
bc 99dce584 82a7f97b nt!ExecuteHandler+0x24
330 99dce8b4 93a5ebac nt!RtlRaiseStatus+0x47
14 99dce8c8 93a5f00b fastfat!FatQuickVerifyVcb+0x32
2c 99dce8f4 93a57495 fastfat!FatVerifyVcb+0xd7
20 99dce914 93a5a247 fastfat!FatIsVolumeMounted+0x37
14 99dce928 93a5a3e6 fastfat!FatUserFsCtrl+0x89
18 99dce940 93a5a478 fastfat!FatCommonFileSystemControl+0x56
4c 99dce98c 82a7b4bc fastfat!FatFsdFileSystemControl+0x82
18 99dce9a4 88a2b20c nt!IofCallDriver+0x63
24 99dce9c8 88a3ece8 fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x2aa
38 99dcea00 82a7b4bc fltmgr!FltpFsControl+0xe8
18 99dcea18 82c7ceee nt!IofCallDriver+0x63
20 99dcea38 82c99cd1 nt!IopSynchronousServiceTail+0x1f8
9c 99dcead4 82ca2d08 nt!IopXxxControlFile+0x6aa
34 99dceb08 82a8242a nt!NtFsControlFile+0x2a
0 99dceb08 82a8041d nt!KiFastCallEntry+0x12a
a0 99dceba8 9e079989 nt!ZwFsControlFile+0x11
6c 99dcec14 9e0779a8 LxrSII1d!lxrVolumeDeviceControl+0x429 [e:\dmydrv\driver\ntvolume.c @ 497]
2c 99dcec40 82a7b4bc LxrSII1d!lxrDispatchQueueIRP+0x2b8 [e:\dmydrv\driver\ntdriver.c @ 217]
18 99dcec58 93a4d618 nt!IofCallDriver+0x63
28 99dcec80 93a5927b fastfat!FatPerformDevIoCtrl+0x6a
170 99dcedf0 93a5a3bc fastfat!FatVerifyVolume+0xfd
18 99dcee08 93a5a478 fastfat!FatCommonFileSystemControl+0x2c
4c 99dcee54 82a7b4bc fastfat!FatFsdFileSystemControl+0x82
18 99dcee6c 88a2b20c nt!IofCallDriver+0x63
24 99dcee90 88a3ece8 fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x2aa
38 99dceec8 82a7b4bc fltmgr!FltpFsControl+0xe8
18 99dceee0 82cd0fa5 nt!IofCallDriver+0x63
44 99dcef24 93a5ecce nt!IoVerifyVolume+0xde
48 99dcef6c 93a53360 fastfat!FatPerformVerify+0x70
48 99dcefb4 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf000 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf048 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf094 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf0dc 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf128 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf170 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf1bc 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf204 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf250 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf298 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf2e4 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf32c 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf378 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf3c0 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf40c 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf454 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf4a0 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf4e8 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf534 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf57c 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf5c8 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf610 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf65c 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf6a4 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf6f0 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf738 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf784 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf7cc 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf818 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf860 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf8ac 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf8f4 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf940 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcf988 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcf9d4 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcfa1c 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcfa68 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcfab0 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcfafc 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcfb44 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcfb90 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcfbd8 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcfc24 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcfc6c 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcfcb8 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcfd00 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcfd4c 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcfd94 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcfde0 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcfe28 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcfe74 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcfebc 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcff08 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcff50 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dcff9c 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dcffe4 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd0030 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd0078 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd00c4 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd010c 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd0158 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd01a0 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd01ec 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd0234 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd0280 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd02c8 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd0314 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd035c 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd03a8 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd03f0 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd043c 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd0484 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd04d0 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd0518 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd0564 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd05ac 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd05f8 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd0640 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd068c 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd06d4 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd0720 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd0768 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd07b4 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd07fc 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd0848 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd0890 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd08dc 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd0924 93a5ee3b fastfat!FatProcessException+0x1b6
4c 99dd0970 93a53360 fastfat!FatPerformVerify+0x1dd
48 99dd09b8 93a4d1b3 fastfat!FatProcessException+0x1b6
48 99dd0a00 82a7b4bc fastfat!FatFsdCreate+0x83
18 99dd0a18 88a2b20c nt!IofCallDriver+0x63
24 99dd0a3c 88a3e8c9 fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x2aa
4c 99dd0a88 82a7b4bc fltmgr!FltpCreate+0x2db
18 99dd0aa0 82c7f62d nt!IofCallDriver+0x63
d8 99dd0b78 82c601d7 nt!IopParseDevice+0xed7
7c 99dd0bf4 82c8624d nt!ObpLookupObjectName+0x4fa
5c 99dd0c50 82c7e5ab nt!ObOpenObjectByName+0x159
7c 99dd0ccc 82cb95ee nt!IopCreateFile+0x673
48 99dd0d14 82a8242a nt!NtOpenFile+0x2a
0 99dd0d14 774464f4 nt!KiFastCallEntry+0x12a
01a8f988 75d78312 ntdll!RtlpInitParameterBlock+0x24
34 01a8f9bc 7742b5e9 SHELL32!CListViewHost::_UpdateListViewItemCount+0xfa
74 01a8fa30 7742e8d1 ntdll!RtlAllocateHandle+0x1a1
160 01a8fb90 76e01174 ntdll!RtlpReAllocateHeap+0x864
c 01a8fb9c 7745b3f5 kernel32!BaseThreadInitThunk+0xe
40 01a8fbdc 7745b3c8 ntdll!TppWaiterpThread+0x34d
18 01a8fbf4 00000000 ntdll!TppWaiterpThread+0x320

> - whenever a IOCTL_DISK_CHECK_VERIFY arrives to the volume

You have a bug in this path, it causes SEH exception and FAT tries to handle it.

Look at FatPerformVerify source in FASTFAT - what queries can it sent to your driver? you can have a bug in them too.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

I stepped into the fastfat sources and in the function FatPerformVerify, on line no. 1901 of Win7\verfysup.c, IoVerifyVolume returns STATUS_VERIFY_REQUIRED for some reason. This will make the ASSERT( STATUS_VERIFY_REQUIRED != Status) fail in line no. 1994, throwing an exception and calling FatProcessException. This in turn calls FatPerformVerify again and a ping-pong match begins between these two and thus the kernel stack overflow, I guess.

IoVerifyVolume sends an IRP_MJ_FILE_SYSTEM_CONTROL/IRP_MN_VERIFY_VOLUME.
I suggest that something you are doing is causing this status to be
returned as a result of this IRP. My advice would be to walk into this
function, back into your own code and see if you can determine the
cause.

Tony
OSR

I am not listening for MJ_FILE_SYSTEM requests, STATUS_INVALID_DEVICE_REQUEST is being returned.