Network mini-redirector driver, CopyFile, STATUS_REDIRECTOR_HAS_OPEN_HANDLES

Hi,
can anyone help me solve this issue? I’m writing a network mini-redirector
to access files on an archive server. I’ve helped myself with the SmbMrx and
NulMrx sample projects in the IFS DDK kit. I have written a user mode application
that registers and starts the kernel minirdr driver and also stops and unregisters
it on my command. I’m testing basic Windows API files functions with a simple
user mode console application. The problem I’m having is stopping the kernel
driver when CopyFile function is used in user mode test application. CopyFile
successfully copies a file, but the RxStopMinirdr returns
STATUS_REDIRECTOR_HAS_OPEN_HANDLES.

Now this is what I’ve noticed. When I use CreateFile, ReadFile (or WriteFile) and
than CloseHandle in a test application, the cleanup routines called by the RDBSS
are MRxCleanupFobx, MRxCloseSrvOpen, MRxDeallocateForFobx, MRxForcedClosed,
MRxDeallocateForFcb. But when I use CopyFile, the only cleanup routine
called is MRxCleanupFobx, one for the source and one for the destination file. I’ve
noticed that the RxContext->RxDeviceObject->NumberOfActiveFcbs = 2 in
the MRxCleanupFobx when I use CopyFile, and not 1 like it the case of reading or
writing a file.

Any ideas on how to fix this? How can I invoke a proper cleanup when CopyFile is
used, so that I can stop and unregister the driver.

Thx, Robert

Cleanup is called when all user handles were closed. It seems that system (Cache Manager/Memory Manager) holds handles to your source and destination file. In normal FSD you call CcPurgeCacheSection() or MmFlushImageSection() on members on FSRTL_COMMON_FCB_HEADER from cleanup routine, but my belief is that it is handled by RDBSS. To be sure check import table of your sys by dumpbin/dependency walker.

Big warning! If you use WDK, for older platforms than WLH, the mini-redirector libraries are compiled under IFS Kit WS2003 SP1. The FSRTL_ADVANCED_FCB_HEADER structure was extended in WDK by two members, so sizeof(FSRTL_ADVANCED_FCB_HEADER) is different in your source code then in precompiled libraries. I had to modify ntifs.h to fix this issue.

> Cleanup is called when all user handles were closed. It seems that system

(Cache Manager/Memory Manager) holds handles to your source and
destination file.

Cc and Mm never ever hold the handles, they only addref the file object.

So, no activity of Cc or Mm can prevent MJ_CLEANUP. It is sent only due to a)
ZwClose b) CloseHandle c) process death, and not due to any Cc’s or Mm’s
activities.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

> Cleanup is called when all user handles were closed. It seems

that system (Cache Manager/Memory Manager) holds handles to your
source and destination file.

I agree. I tried to use some Rx routines in the MRxCleanupFobx
routine to invoke other MRx finalize routines, but with no luck.

In normal FSD you call CcPurgeCacheSection() or MmFlushImageSection()
on members on FSRTL_COMMON_FCB_HEADER from cleanup routine, but my
belief is that it is handled by RDBSS.

I’ve tried CcPurgeCacheSection() and I’m happy to report that a call

CcPurgeCacheSection(RxContext->CurrentIrpSp->FileObject->SectionObjectPointer, NULL, 0, TRUE)

in MRxCleanupFobx in my case actualy works! Thx Bronislav!!
It triggers MRxCloseSrvOpen, MRxDeallocateForFobx, MRxForcedClosed
and MRxDeallocateForFcb for both source and dest files. If the last
parameter is FALSE, this is the case for only source file and the
return is still STATUS_REDIRECTOR_HAS_OPEN_HANDLES.
MmFlushImageSection does not have an effect.

I’m just not sure if the CcPurgeCacheSection call is in the right
MRx routine, that is in MRxCleanupFobx. I don’t mind, if the system
holds handles while the driver is loaded and runing, I just
want to ensure that the driver gets properly stoped and unloaded
when needed, thats before the call to RxStopMinirdr.

To be sure check import table of your sys by dumpbin/dependency walker.

I’m not sure what you meant by that. I’ve checked sys in the dependency
walker and found both CcPurgeCacheSection() and MmFlushImageSection()
in NTOSKRNL.EXE…

Big warning! If you use WDK, for older platforms than WLH, the
mini-redirector libraries are compiled under IFS Kit WS2003 SP1.
The FSRTL_ADVANCED_FCB_HEADER structure was extended in WDK by
two members, so sizeof(FSRTL_ADVANCED_FCB_HEADER) is different
in your source code then in precompiled libraries. I had to
modify ntifs.h to fix this issue.

I’m using IFS DDK 2003 on WinXP. Does this warning apply in my case?
How should I modify ntifs.h if it does?

> Cc and Mm never ever hold the handles, they only addref the file object.
Maxim thanks for correction. I know it, it was my wrong/vague declaration.

So, no activity of Cc or Mm can prevent MJ_CLEANUP.
But it can prevent IRP_MJ_CLOSE, isn’t it?

I’m using IFS DDK 2003 on WinXP. Does this warning apply in my case?
How should I modify ntifs.h if it does?

This problem is not your case. But just for case you will upgrade to WDK. I added compile time condition to:

  1. eliminate two members (PushLock, FileContextSupportPointer)
  2. change definition for macro FsRtlSetupAdvancedHeader so it sets correct version 0 and behaves like in ntifs.h IFS KIT WS2003 SP1.

In case you use redirector connection engine, there is also problem which was introduced in IFS KIT WS2003 SP1. The structure RXCE_CONNECTION_EVENT_HANDLER has switched members RxCeSendCompleteEventHandler and RxCeSendSubmittedEventHandler for Win2k and
WinXP.

> I’m not sure what you meant by that. I’ve checked sys in the dependency

walker and found both CcPurgeCacheSection() and MmFlushImageSection()
in NTOSKRNL.EXE…
If they are is in import table of your driver it means that it is used by rdbss library. But for some reason are not called. :slight_smile: