Correctly filtering rename operations.

As stated in the “Filter Driver Development Guide” chapter 11.2, FltGetDestinationFileNameInformation should be used in the pre callback for IRP_MJ_SET_INFORMATION, and FltGetTunneledName should be used in post in order to vaidate that the name retrieved in the pre operation was not affected by name tunneling.

When testing with mapped network drives I noticed that FltGetTunneledName always returns a FLT_FILE_NAME_INFORMATION (the result is not NULL), meaning that the name was affected by name tunneling. The initially retrieved name (in the pre callback) correctly pointed to the new (renamed) path. The name returned by FltGetTunneledName was always the initial path (before the rename)

I also noticed that FltGetDestinationFileNameInformation returns the correct path (after the rename) in the post operation callback. But, as stated in the documentation, FltGetDestinationFileNameInformation should be called in the pre operation callback.

Another approach that I’ve tried was calling FltGetFileNameInformation in the post opereation callback, but this also returned the original (not renamed) path.

What’s interesting is that when testing with UNC paths (not mapped network drives) the problem didn’t appear.

So far i’ve tested on windows 10 RS5 and windows 10 RS6.

  1. How can I retrieve the correct path for the file object in the IRP_MJ_SET_INFORMATION post callback for a FileRenameInformation.
  2. Why does FltGetTunneledName return the original name for renames on \Device\Mup
  3. Why does FltGetFileNameInformation always return the original name in the post-operation of a file rename on a mapped network drive.
  4. If i retrieve the name in the pre-operation callback and the post-operation callback succeedes, is the name still valid?

sample code that reproduces my issue: https://pastebin.com/MDfMyLQV
log output for both cases: https://pastebin.com/njCPw7vY

Did you notice a very particular difference between the two cases in the output?
Namely that one is using Hgfs (VMware’s Host Shared Folders
redirector) and the other is using SMB?

You’ll have a looooot of “fun” figuring all the cases here. FG(D)FNI
have soooo many cases where they just work a tad differently, or fail
and you have to revert to your own code to get the result. Add to that
the fact that they only really work on Microsoft’s FSes “properly”
(imagine how many issues are present on other FSes)

Good luck - you will need it. And if it feels like it works in all
cases in less than 6 months, be ready for some crash dumps or at least
incorrect behaviours.

On 5/22/19, andrei wrote:
> OSR https://community.osr.com/
> andrei started a new discussion: Correctly filtering rename operations.
>
> As stated in the “Filter Driver Development Guide” chapter 11.2,
> FltGetDestinationFileNameInformation should be used in the pre callback for
> IRP_MJ_SET_INFORMATION, and FltGetTunneledName should be used in post in
> order to vaidate that the name retrieved in the pre operation was not
> affected by name tunneling.
>
> When testing with mapped network drives I noticed that FltGetTunneledName
> always returns a FLT_FILE_NAME_INFORMATION (the result is not NULL), meaning
> that the name was affected by name tunneling. The initially retrieved name
> (in the pre callback) correctly pointed to the new (renamed) path. The name
> returned by FltGetTunneledName was always the initial path (before the
> rename)
>
> I also noticed that FltGetDestinationFileNameInformation returns the
> correct path (after the rename) in the post operation callback. But, as
> stated in the documentation, FltGetDestinationFileNameInformation should be
> called in the pre operation callback.
>
> Another approach that I’ve tried was calling FltGetFileNameInformation in
> the post opereation callback, but this also returned the original (not
> renamed) path.
>
> What’s interesting is that when testing with UNC paths (not mapped network
> drives) the problem didn’t appear.
>
> So far i’ve tested on windows 10 RS5 and windows 10 RS6.
>
>
> * How can I retrieve the correct path for the file object in the
> IRP_MJ_SET_INFORMATION post callback for a FileRenameInformation.
> * Why does FltGetTunneledName return the original name for renames on
> \Device\Mup
> * Why does FltGetFileNameInformation always return the original name in the
> post-operation of a file rename.
> * If i retrieve the name in the pre-operation callback and the
> post-operation callback succeedes, is the name still valid?
>
> sample code that reproduces my issue: https://pastebin.com/MDfMyLQV
>
> log output for both cases: https://pastebin.com/njCPw7vY
>
> –
> Reply to this email directly or follow the link below to check it out:
> https://community.osr.com/discussion/291343/correctly-filtering-rename-operations
>
> Check it out:
> https://community.osr.com/discussion/291343/correctly-filtering-rename-operations
>

Note: The email was trying to reply to an invalid Discussion (291343).

I tested on my workplace environment and the issue reproduced with actual remote file shares (this time with both mapped network drives AND UNC paths). I noticed that whenever FltGetTunneledName returns a non-NULL result, the problem appears. FGFNI returns the original (before rename) path in the post callback.

Shouldn’t the original name be unavailable in a post-callback for a rename if the rename was successful?

@Dejan_Maksimovic said:
Did you notice a very particular difference between the two cases in the output?
Namely that one is using Hgfs (VMware’s Host Shared Folders
redirector) and the other is using SMB?

You’ll have a looooot of “fun” figuring all the cases here. FG(D)FNI
have soooo many cases where they just work a tad differently, or fail
and you have to revert to your own code to get the result. Add to that
the fact that they only really work on Microsoft’s FSes “properly”
(imagine how many issues are present on other FSes)

Good luck - you will need it. And if it feels like it works in all
cases in less than 6 months, be ready for some crash dumps or at least
incorrect behaviours.

On 5/22/19, andrei wrote:

OSR https://community.osr.com/
andrei started a new discussion: Correctly filtering rename operations.

As stated in the “Filter Driver Development Guide” chapter 11.2,
FltGetDestinationFileNameInformation should be used in the pre callback for
IRP_MJ_SET_INFORMATION, and FltGetTunneledName should be used in post in
order to vaidate that the name retrieved in the pre operation was not
affected by name tunneling.

When testing with mapped network drives I noticed that FltGetTunneledName
always returns a FLT_FILE_NAME_INFORMATION (the result is not NULL), meaning
that the name was affected by name tunneling. The initially retrieved name
(in the pre callback) correctly pointed to the new (renamed) path. The name
returned by FltGetTunneledName was always the initial path (before the
rename)

I also noticed that FltGetDestinationFileNameInformation returns the
correct path (after the rename) in the post operation callback. But, as
stated in the documentation, FltGetDestinationFileNameInformation should be
called in the pre operation callback.

Another approach that I’ve tried was calling FltGetFileNameInformation in
the post opereation callback, but this also returned the original (not
renamed) path.

What’s interesting is that when testing with UNC paths (not mapped network
drives) the problem didn’t appear.

So far i’ve tested on windows 10 RS5 and windows 10 RS6.

  • How can I retrieve the correct path for the file object in the
    IRP_MJ_SET_INFORMATION post callback for a FileRenameInformation.
  • Why does FltGetTunneledName return the original name for renames on
    \Device\Mup
  • Why does FltGetFileNameInformation always return the original name in the
    post-operation of a file rename.
  • If i retrieve the name in the pre-operation callback and the
    post-operation callback succeedes, is the name still valid?

sample code that reproduces my issue: https://pastebin.com/MDfMyLQV

log output for both cases: https://pastebin.com/njCPw7vY


Reply to this email directly or follow the link below to check it out:
https://community.osr.com/discussion/291343/correctly-filtering-rename-operations

Check it out:
https://community.osr.com/discussion/291343/correctly-filtering-rename-operations

Note: The email was trying to reply to an invalid Discussion (291343).

> I tested on my workplace environment and the issue reproduced with actual

remote file shares (this time with both mapped network drives AND UNC
paths). I noticed that whenever FltGetTunneledName returns a non-NULL
result, the problem appears. FGFNI returns the original (before rename) path
in the post callback.
On an actual network it happened on an SMB share?
Notice that the issue occurs on HGFS in your debug output, but not on
SMB shares.

Shouldn’t the original name be unavailable in a post-callback for a rename
if the rename was successful?
Well, it should provide the cached file name, but I am not sure about
the case of QUERY_FILE_SYSTEM_ONLY flag. I imagine it should NOT, but
it might be playing some magic in that particular case.
Technically, in all SUCCESSFUL post-rename cases, FGFNI should return
the new file name. If it does not on SMB shares, it is one of its
quirks.
I sure doubt it has anything to do with caching, since FltMgr can
request the file name directly.

Ah, the note is back. So here’s an answer I prepared earlier…

How can I retrieve the correct path for the file object in the IRP_MJ_SET_INFORMATION post callback for a FileRenameInformation.

On MUP/RDR you cannot. Once a file object has been renamed the ONLY operations that work on it are close and cleanup (or that was the case last time I went there)

Why does FltGetTunneledName return the original name for renames on \Device\Mup

Pass. but IMO its about 30 years too late to still be worrying about name tunnelling. The apps will have stopped working of have been ported. Of course I’ll walk in to a bug later today which proves me wrong

Why does FltGetFileNameInformation always return the original name in the post-operation of a file rename.

See above

If i retrieve the name in the pre-operation callback and the post-operation callback succeedes, is the name still valid?

I wouldn’t bet on it. My general rule of thumb over the network, particularly with respect to ‘filesystem’ (as opposed to ‘data’) operations is that you can never rely on anything (for insyance include the rule that “you only ever get one StreamContext for any stream” just isn’t true.

In this case in particular you are totally dependant on the remote file system which may or may not allow any other person out there to rename the file again after your rename has worked. And I would’t even assume that MUP/RDR is holding a HANDLE on the file on the server at this stage.

On an actual network it happened on an SMB share?
Notice that the issue occurs on HGFS in your debug output, but not on
SMB shares
Yes, it also happened over an SMB share. It was the same behavior as with HGFS

Pass. but IMO its about 30 years too late to still be worrying about name tunnelling. The apps will have stopped working of have been ported. Of course I’ll walk in to a bug later today which proves me wrong

I agree, but what bugs me is that FltGetTunneledName gives me the wrong name in the post callback (and so does FGFNI, since FGTN internally calls FGFNI). The only API that gives me the new name in the post callback is FGDFNI, but afaik this is dangerous to call in a post callback, because it requires the “RootDirectory” parameter. In a post callback we might be in an arbitrary context , and the RootDirectory could be a user-mode handle. I actually encountered a bugcheck with driver verifier enabled because FGDFNI was trying to reference a user-mode handle in the context of a system thread (where the I/O was completed).

The strategy I currently use is to check if in the post callback we are in the context of the I/O requestor. If so, I call FGDFNI, else, I use the name returned by FGDFNI in the pre-callback. Do you see any potential issues with this approach?

In this case in particular you are totally dependant on the remote file system which may or may not allow any other person out there to rename the file again after your rename has worked. And I would’t even assume that MUP/RDR is holding a HANDLE on the file on the server at this stage.

I don’t care if the file was immediately renamed again by some client. All i really care about is if the rename was succesful and what was the final destination normalized name.

Thank you for your time.

I have little succour beyond saying that I have never found reason to doubt that FGDFNI returns the correct speculative name in pre.

In a post callback we might be in an arbitrary context

I tend to the brute force and ignorance approache to these issues if I’m outside the IO paths and say FLT_PREOP_SYNCRHONIZE. For reads and writes (expecially to a local disk) I’ll pull every trick possible to not get in the way of completion