FltReadFile Reentrancy

Hi,

I am writing a mini-filter for Vista. The documentation for FltReadFile states that the request will only be passed to lower filters as well as the file system. This seems to be the case for local file systems, but in the case of network file systems I am being re-entered. See the following trace:

nt!DbgBreakPoint
cpdrm!DrmGenericPreop+0x49
fltmgr!FltpPerformPreCallbacks+0x2e5
fltmgr!FltpPassThroughInternal+0x32
fltmgr!FltpPassThrough+0x1a3
fltmgr!FltpDispatch+0xb1
nt!IofCallDriver+0x63
nt!IoPageRead+0x172
nt!MiDispatchFault+0xd18
nt!MmAccessFault+0x10ac
nt!MmCheckCachedPageState+0x801
nt!CcCopyRead+0x435
rdbss!RxCommonRead+0xadd
rdbss!RxFsdCommonDispatch+0x59c
rdbss!RxFsdDispatch+0x19f
mrxsmb!MRxSmbFsdDispatch+0x99
nt!IofCallDriver+0x63
mup!MupiCallUncProvider+0x10d
mup!MupStateMachine+0x9b
mup!MupFsdIrpPassThrough+0xc8
nt!IofCallDriver+0x63
fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x251
fltmgr!FltPerformSynchronousIo+0xb9
fltmgr!FltReadFile+0x2ed
cpdrm!UtSyncReadFile+0x95
cpdrm!DrmpSyncReadNextSector+0x5b
cpdrm!DrmcIsProtectedFile+0x4b
cpdrm!DrmPostCreate+0x19b
fltmgr!FltpPerformPostCallbacks+0x1f1
fltmgr!FltpProcessIoCompletion+0x10
fltmgr!FltpPassThroughCompletion+0x94
fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x2e1
fltmgr!FltpCreate+0x2a1
nt!IofCallDriver+0x63
nt!IopParseDevice+0xf61
nt!ObpLookupObjectName+0x5a8
nt!ObOpenObjectByName+0x13c
nt!IopCreateFile+0x63b
nt!NtCreateFile+0x34
nt!KiFastCallEntry+0x12a
ntdll!KiFastSystemCallRet
ntdll!ZwCreateFile+0xc
kernel32!CreateFileW+0x379
notepad!NPInit+0x49f
notepad!WinMain+0x56
notepad!_initterm_e+0x1a1
kernel32!BaseThreadInitThunk+0xe
ntdll!__RtlUserThreadStart+0x23
ntdll!_RtlUserThreadStart+0x1b

Is this expected (so I should plan for it) or am I doing something else wrong.

Thanks,
Matt

This looks like a standard call sequence to me. You get called (on top
of MUP) and then MUP calls RDR. RDR copies the file out of the cache
and (since it isn’t there) it page faults and you get invoked to process
the read page fault.

You should see the same behavior on local file systems as well.

Tony
OSR

Thanks. I haven’t seen this on a local file system yet, but I also just started and have done little testing so I’m not surprised.

So the documentation should really read: You will not get called for a file system operation unless the operation generates a page fault and then the fault will propagate through the entire file system stack.

Question: If I get re-entered due to a fault that is a result of my own file operation, I would like to just pass it through. I can accomplish this by keeping track of whether I am entering the file system in the stream context. If I detect this I can just immediately pass through the request. Is there a better / more accepted way of doing this? i.e. is there a way from analyzing the IRP that I can tell that my filter generated the IO request.

Thanks

Take a look at FLT_OPERATION_REGISTRATION and set flag FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO in your Flags field.

Also take a look at FLT_IS_FS_FILTER_OPERATION

Correct me if I am wrong but I don’t think I can use FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO becasue I want to handle memory mapped files properly.

(I am still trying to understand all of the complexity of handling memory mapped files).