FltGetDestinationFileNameInformation and remote symlinks

Hi everyone,

I’m been wrestling with implementing renames in a reparse minifilter. Following the example “simrep” minifilter posted by microsoft, it seems I’m supposed to be able to call FltGetDestinationFileNameInformation() and it will give me the correct reparsed filename back. However, I have been getting STATUS_INVALID_PARAMETER back from this function if I pass in a destination file name that is a symlink to a UNC path.

Let’s say I have \server\share\file.txt and I want to rename it to \server\share\file2.txt:

move \server\share\file.txt \server\share\file2.txt

Issuing the command above will enter my minifilter and the call to FltGetDestinationFileName succeeds, resulting in the file name \Device\Mup\server\share\file2.txt.

mklink /d C:\test \server\share
move C:\test\file.txt C:\test\file2.txt

The second command above enters the filter again, but this time FltGetDestinationFileNameInformation returns STATUS_INVALID_PARAMETER.

I don’t have a “real” symlink in the reparse minifilter, but I’m hoping that the mklink /d step duplicates what is normally happening – after all, I’m seeing the same result: FltGetDestinationFileNameInfromation will call my PreCreateFile callback, which I will return it IO_REPARSE / STATUS_REPARSE. Then the function simply returns STATUS_INVALID_PARAMETER.

Any ideas? I appreciate them!

Thanks
Stephen

From your description I’m not sure you’re using
FltGetDestinationFileNameInformation() correctly. It is only supposed to be
used in the context of an operation that is either a hard-link creation or
a rename… In general the target of a rename or hard-link can either be a
full path relative to the beginning of the volume (and it must not contain
any reparse points) or a relative to a directory handle, in which case the
reparse point would have been resolved at the time the directory was opened.

So for which operation exactly are you calling
FltGetDestinationFileNameInformation() ? If you’re calling it for a
FileRenameInformation or FileLinkInformation, please explain if it’s a
relative or absolute open and whether the path contains a reparse point or
not…

Thanks,
Alex.

On Tue, Mar 4, 2014 at 11:19 AM, wrote:

> Hi everyone,
>
> I’m been wrestling with implementing renames in a reparse minifilter.
> Following the example “simrep” minifilter posted by microsoft, it seems
> I’m supposed to be able to call FltGetDestinationFileNameInformation() and
> it will give me the correct reparsed filename back. However, I have been
> getting STATUS_INVALID_PARAMETER back from this function if I pass in a
> destination file name that is a symlink to a UNC path.
>
> Let’s say I have \server\share\file.txt and I want to rename it to
> \server\share\file2.txt:
>
> > move \server\share\file.txt \server\share\file2.txt
>
> Issuing the command above will enter my minifilter and the call to
> FltGetDestinationFileName succeeds, resulting in the file name
> \Device\Mup\server\share\file2.txt.
>
> > mklink /d C:\test \server\share
> > move C:\test\file.txt C:\test\file2.txt
>
> The second command above enters the filter again, but this time
> FltGetDestinationFileNameInformation returns STATUS_INVALID_PARAMETER.
>
> I don’t have a “real” symlink in the reparse minifilter, but I’m hoping
> that the mklink /d step duplicates what is normally happening – after all,
> I’m seeing the same result: FltGetDestinationFileNameInfromation will call
> my PreCreateFile callback, which I will return it IO_REPARSE /
> STATUS_REPARSE. Then the function simply returns STATUS_INVALID_PARAMETER.
>
> Any ideas? I appreciate them!
>
> Thanks
> Stephen
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Hi Alex,

Thanks for the quick reply. I am indeed only calling FltGetDestinationFilenameInformation for renames. I wrote a do-nothing function in my driver that looks like the following:

FLT_PREOP_CALLBACK_STATUS
RsFilterSetInformation (
__inout PFLT_CALLBACK_DATA pData,
__in PCFLT_RELATED_OBJECTS pFltObjects,
__deref_out_opt PVOID* ppCompletionContext
)
{
FLT_PREOP_CALLBACK_STATUS retStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
PFLT_FILE_NAME_INFORMATION TargetFileName = NULL;

UNREFERENCED_PARAMETER(ppCompletionContext);

if (pData->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION)
{
if (pData->Iopb->Parameters.SetFileInformation.FileInformationClass == FileRenameInformation)
{
PFILE_RENAME_INFORMATION RenameInformation = (PFILE_RENAME_INFORMATION) pData->Iopb->Parameters.SetFileInformation.InfoBuffer;
NTSTATUS Status;

//
// Get the destination file name information.
//

Status = FltGetDestinationFileNameInformation(
pFltObjects->Instance,
pFltObjects->FileObject,
RenameInformation->RootDirectory,
RenameInformation->FileName,
RenameInformation->FileNameLength,
FLT_FILE_NAME_OPENED | FLT_FILE_NAME_QUERY_DEFAULT,
&TargetFileName);
if (!NT_SUCCESS(Status))
{
goto Finished;
}

Status = FltParseFileNameInformation(TargetFileName);
if (!NT_SUCCESS(Status))
{
goto Finished;
}
}
}

Finished:
if (TargetFileName != NULL)
{
FltReleaseFileNameInformation(TargetFileName);
}

return retStatus;
}

when i try
“move \server\share\file.txt \server\share\file2.txt” in cmd, the FltGetDestinationFileNameInformation call above returns 0. In that case, RootDirectory is NULL in the rename information struct, and the filename is the entire path “??\UNC\server\share\file2.txt”.

I then tried to make a symlink pointing to \server\share in order to simulate what my reparse filter does:

“mklink /d C:\test \server\share”

i.e. in my minifilter, I/O operations to C:\test* resolve to \server\share*.

Then I tried to move a file:

“move C:\test\file.txt C:\test\file2.txt”

In this case, FltGetDestinationFileNameInformation as implemented above returns STATUS_INVALID_PARAMETER. RootDirectory is still NULL, and FileName contains the absolute path “??\C:\test\file2.txt”.

I had it originally implemented, in working order, following your blog post (http://fsfilters.blogspot.com/2011/06/rename-in-file-system-filters-part-ii.html) where I did the steps 1-8 as you wrote. I then looked at simrep, which uses the FltGetDestinationFileNameInformation, and have been trying to get that working. Should I just go back to following your blog post instead of trying to use what simrep has?

Thanks!!

Hi Stephen,

hmm… My blog post specifically refers to issuing your own rename. Is this
a rename you issue ? I’m not quite sure how my post helps with
FltGetDestinationFileNameInformation(), can you please clarify this ?

This is pretty interesting… I’m not sure what to make of this. I don’t
like how in the IRP_MJ_SET_INFORMATION you get the path is
“??\C:\test\file2.txt”.
There are multiple problems here:

  1. Why is there a volume name in the FileName buffer (“??\C:”) ? This
    doesn’t make sense since renames can only happen on a the same volume so
    why even send the volume name to the file system ?
  2. Why is the volume name in this format ? Is underlying file system
    supposed to start iterating over object manager’s namespace ? This is
    pretty strange.

So as far as I’m concerned this rename is pretty broken. The question is,
who sent it ?

Thanks,
Alex.

On Tue, Mar 4, 2014 at 1:32 PM, wrote:

> Hi Alex,
>
> Thanks for the quick reply. I am indeed only calling
> FltGetDestinationFilenameInformation for renames. I wrote a do-nothing
> function in my driver that looks like the following:
>
>
>
> FLT_PREOP_CALLBACK_STATUS
> RsFilterSetInformation (
> inout PFLT_CALLBACK_DATA pData,
>
in PCFLT_RELATED_OBJECTS pFltObjects,
> __deref_out_opt PVOID* ppCompletionContext
> )
> {
> FLT_PREOP_CALLBACK_STATUS retStatus =
> FLT_PREOP_SUCCESS_NO_CALLBACK;
> PFLT_FILE_NAME_INFORMATION TargetFileName = NULL;
>
> UNREFERENCED_PARAMETER(ppCompletionContext);
>
> if (pData->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION)
> {
> if
> (pData->Iopb->Parameters.SetFileInformation.FileInformationClass ==
> FileRenameInformation)
> {
> PFILE_RENAME_INFORMATION RenameInformation =
> (PFILE_RENAME_INFORMATION)
> pData->Iopb->Parameters.SetFileInformation.InfoBuffer;
> NTSTATUS Status;
>
> //
> // Get the destination file name information.
> //
>
> Status = FltGetDestinationFileNameInformation(
> pFltObjects->Instance,
> pFltObjects->FileObject,
> RenameInformation->RootDirectory,
> RenameInformation->FileName,
> RenameInformation->FileNameLength,
> FLT_FILE_NAME_OPENED | FLT_FILE_NAME_QUERY_DEFAULT,
> &TargetFileName);
> if (!NT_SUCCESS(Status))
> {
> goto Finished;
> }
>
> Status = FltParseFileNameInformation(TargetFileName);
> if (!NT_SUCCESS(Status))
> {
> goto Finished;
> }
> }
> }
>
> Finished:
> if (TargetFileName != NULL)
> {
> FltReleaseFileNameInformation(TargetFileName);
> }
>
> return retStatus;
> }
>
> when i try
> “move \server\share\file.txt \server\share\file2.txt” in cmd, the
> FltGetDestinationFileNameInformation call above returns 0. In that case,
> RootDirectory is NULL in the rename information struct, and the filename is
> the entire path “??\UNC\server\share\file2.txt”.
>
> I then tried to make a symlink pointing to \server\share in order to
> simulate what my reparse filter does:
>
> “mklink /d C:\test \server\share”
>
> i.e. in my minifilter, I/O operations to C:\test* resolve to
> \server\share*.
>
> Then I tried to move a file:
>
> “move C:\test\file.txt C:\test\file2.txt”
>
> In this case, FltGetDestinationFileNameInformation as implemented above
> returns STATUS_INVALID_PARAMETER. RootDirectory is still NULL, and
> FileName contains the absolute path “??\C:\test\file2.txt”.
>
> I had it originally implemented, in working order, following your blog
> post (
> http://fsfilters.blogspot.com/2011/06/rename-in-file-system-filters-part-ii.html)
> where I did the steps 1-8 as you wrote. I then looked at simrep, which
> uses the FltGetDestinationFileNameInformation, and have been trying to get
> that working. Should I just go back to following your blog post instead of
> trying to use what simrep has?
>
> Thanks!!
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

I believe you get the full path that was given to the call to MoveFile(). The IRP_SET_INFORMATION received was the result of me typing “move (absolutepath) (absolutepath)” into CMD. i.e.: “move C:\test\one.txt C:\test\two.txt”. The minifilter will get an IRP with the RootDirectory being NULL and the FileName containing “??\C:\test\two.txt”. It seems many applications call MoveFile with absolute paths instead of relative paths, so it’s a case that must be handled.

A quick step back: I’m writing a reparse minifilter, which currently changes a path like C:\Test to a UNC share, \server\share. I have a function which takes in a PFLT_FILE_NAME_INFORMATION and checks to see if the path (The Name + (Volume.Length / sizeof(WCHAR))) portion starts with \Test, in which case it’ll replace the path with ??\UNC\Server\share.…

The SimRep example posted pretty much does the same thing; its implementation of SetInformation first uses FltGetDestinationFileNameInformation() to get a PFLT_FILE_NAME_INFORMATION from the data in the FILE_RENAME_INFORMATION struct. I also wanted to use it for the same purpose, so I can pass the thing it returns into my function. Once I have that, if my function replaced the path, I would then go on to issue my own rename. But the function doesn’t seem to work when symlinks are involved (with a absolute path), hence my posting here.

Do you think it’s a bug with FltGetDestinationFileNameInformation?

Thanks!
Stephen

Hi Stephen,

Sorry, I was wrong. I didn’t think the name in the FILE_RENAME_INFORMATION
structure could be an IO manager level absolute path (anything starting
with ??), I thought it would always be a volume absolute path (in your
case i expected “\file2.txt”), but I was wrong. I think I’ll have to spend
some time debugging this to figure it out…

Anyway, on to your question, it does feel like
FltGetDestinationFileNameInformation() might have a bug and since I don’t
really understand the semantics all that well I don’t know what to
recommend. If your implementation based on my blog post works in this case
then perhaps you should use that (if you want to be super careful you could
call FltGetDestinationFileNameInformation() first and only if that fails
with STATUS_INVALID_PARAMETER call your function).

I’ll need to debug this more before I figure out where the
STATUS_INVALID_PARAMETER is coming from and how renames with IO manager
level absolute paths work. If I get any time to do this debugging I’ll post
an update here (or on my blog, depending on how interesting it turns out to
be).

In the meantime perhaps someone more knowledgeable could post something to
explain this :).

Thanks,
Alex.

On Tue, Mar 4, 2014 at 3:46 PM, wrote:

> I believe you get the full path that was given to the call to MoveFile().
> The IRP_SET_INFORMATION received was the result of me typing “move
> (absolutepath) (absolutepath)” into CMD. i.e.: “move C:\test\one.txt
> C:\test\two.txt”. The minifilter will get an IRP with the RootDirectory
> being NULL and the FileName containing “??\C:\test\two.txt”. It seems
> many applications call MoveFile with absolute paths instead of relative
> paths, so it’s a case that must be handled.
>
> A quick step back: I’m writing a reparse minifilter, which currently
> changes a path like C:\Test to a UNC share, \server\share. I have a
> function which takes in a PFLT_FILE_NAME_INFORMATION and checks to see if
> the path (The Name + (Volume.Length / sizeof(WCHAR))) portion starts with
> \Test, in which case it’ll replace the path with ??\UNC\Server\share.…
>
> The SimRep example posted pretty much does the same thing; its
> implementation of SetInformation first uses
> FltGetDestinationFileNameInformation() to get a PFLT_FILE_NAME_INFORMATION
> from the data in the FILE_RENAME_INFORMATION struct. I also wanted to use
> it for the same purpose, so I can pass the thing it returns into my
> function. Once I have that, if my function replaced the path, I would then
> go on to issue my own rename. But the function doesn’t seem to work when
> symlinks are involved (with a absolute path), hence my posting here.
>
> Do you think it’s a bug with FltGetDestinationFileNameInformation?
>
> Thanks!
> Stephen
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Oooh, if only this were the only bug for FGDFNI and FGFNI APIs :slight_smile:
Bottom line - the FGDFNI API is broken and useless in many, still alive,
cases. You will often have to roll back to using your own function for
rename operations.
I suggest writing your own and using it always, rather than relying on it,
only whne FGDFNI does not work. It’ll save you some time debugging your
code when it doesn’t work (and if you do use FGDFNI when possible, you’ll
run into a lot of random cases of your code not working randomly)

Kind regards, Dejan.

On Wed, Mar 5, 2014 at 7:36 PM, Alex Carp wrote:

> Hi Stephen,
>
> Sorry, I was wrong. I didn’t think the name in the FILE_RENAME_INFORMATION
> structure could be an IO manager level absolute path (anything starting
> with ??), I thought it would always be a volume absolute path (in your
> case i expected “\file2.txt”), but I was wrong. I think I’ll have to spend
> some time debugging this to figure it out…
>
> Anyway, on to your question, it does feel like
> FltGetDestinationFileNameInformation() might have a bug and since I don’t
> really understand the semantics all that well I don’t know what to
> recommend. If your implementation based on my blog post works in this case
> then perhaps you should use that (if you want to be super careful you could
> call FltGetDestinationFileNameInformation() first and only if that fails
> with STATUS_INVALID_PARAMETER call your function).
>
> I’ll need to debug this more before I figure out where the
> STATUS_INVALID_PARAMETER is coming from and how renames with IO manager
> level absolute paths work. If I get any time to do this debugging I’ll post
> an update here (or on my blog, depending on how interesting it turns out to
> be).
>
> In the meantime perhaps someone more knowledgeable could post something to
> explain this :).
>
> Thanks,
> Alex.
>
>
>
>
> On Tue, Mar 4, 2014 at 3:46 PM, wrote:
>
>> I believe you get the full path that was given to the call to MoveFile().
>> The IRP_SET_INFORMATION received was the result of me typing “move
>> (absolutepath) (absolutepath)” into CMD. i.e.: “move C:\test\one.txt
>> C:\test\two.txt”. The minifilter will get an IRP with the RootDirectory
>> being NULL and the FileName containing “??\C:\test\two.txt”. It seems
>> many applications call MoveFile with absolute paths instead of relative
>> paths, so it’s a case that must be handled.
>>
>> A quick step back: I’m writing a reparse minifilter, which currently
>> changes a path like C:\Test to a UNC share, \server\share. I have a
>> function which takes in a PFLT_FILE_NAME_INFORMATION and checks to see if
>> the path (The Name + (Volume.Length / sizeof(WCHAR))) portion starts with
>> \Test, in which case it’ll replace the path with ??\UNC\Server\share.…
>>
>> The SimRep example posted pretty much does the same thing; its
>> implementation of SetInformation first uses
>> FltGetDestinationFileNameInformation() to get a PFLT_FILE_NAME_INFORMATION
>> from the data in the FILE_RENAME_INFORMATION struct. I also wanted to use
>> it for the same purpose, so I can pass the thing it returns into my
>> function. Once I have that, if my function replaced the path, I would then
>> go on to issue my own rename. But the function doesn’t seem to work when
>> symlinks are involved (with a absolute path), hence my posting here.
>>
>> Do you think it’s a bug with FltGetDestinationFileNameInformation?
>>
>> Thanks!
>> Stephen
>>
>> —
>> NTFSD is sponsored by OSR
>>
>> OSR is hiring!! Info at http://www.osr.com/careers
>>
>> For our schedule of debugging and file system seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>>
>
> — NTFSD is sponsored by OSR OSR is hiring!! Info at
> http://www.osr.com/careers For our schedule of debugging and file system
> seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
> List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


…“It’ll save you some time debugging your code when it [the OS function]
doesn’t work” … But how else is one supposed to learn really good
debugging skills ? Look at what’s happening with Linux kernel developers,
they’re hardly aware debuggers even exist…

Thanks,
Alex.

On Wed, Mar 5, 2014 at 1:55 PM, Dejan Maksimovic > wrote:

> Oooh, if only this were the only bug for FGDFNI and FGFNI APIs :slight_smile:
> Bottom line - the FGDFNI API is broken and useless in many, still alive,
> cases. You will often have to roll back to using your own function for
> rename operations.
> I suggest writing your own and using it always, rather than relying on it,
> only whne FGDFNI does not work. It’ll save you some time debugging your
> code when it doesn’t work (and if you do use FGDFNI when possible, you’ll
> run into a lot of random cases of your code not working randomly)
>
> Kind regards, Dejan.
>
>
> On Wed, Mar 5, 2014 at 7:36 PM, Alex Carp wrote:
>
>> Hi Stephen,
>>
>> Sorry, I was wrong. I didn’t think the name in the
>> FILE_RENAME_INFORMATION structure could be an IO manager level absolute
>> path (anything starting with ??), I thought it would always be a volume
>> absolute path (in your case i expected “\file2.txt”), but I was wrong. I
>> think I’ll have to spend some time debugging this to figure it out…
>>
>> Anyway, on to your question, it does feel like
>> FltGetDestinationFileNameInformation() might have a bug and since I don’t
>> really understand the semantics all that well I don’t know what to
>> recommend. If your implementation based on my blog post works in this case
>> then perhaps you should use that (if you want to be super careful you could
>> call FltGetDestinationFileNameInformation() first and only if that fails
>> with STATUS_INVALID_PARAMETER call your function).
>>
>> I’ll need to debug this more before I figure out where the
>> STATUS_INVALID_PARAMETER is coming from and how renames with IO manager
>> level absolute paths work. If I get any time to do this debugging I’ll post
>> an update here (or on my blog, depending on how interesting it turns out to
>> be).
>>
>> In the meantime perhaps someone more knowledgeable could post something
>> to explain this :).
>>
>> Thanks,
>> Alex.
>>
>>
>>
>>
>> On Tue, Mar 4, 2014 at 3:46 PM, wrote:
>>
>>> I believe you get the full path that was given to the call to
>>> MoveFile(). The IRP_SET_INFORMATION received was the result of me typing
>>> “move (absolutepath) (absolutepath)” into CMD. i.e.: “move C:\test\one.txt
>>> C:\test\two.txt”. The minifilter will get an IRP with the RootDirectory
>>> being NULL and the FileName containing “??\C:\test\two.txt”. It seems
>>> many applications call MoveFile with absolute paths instead of relative
>>> paths, so it’s a case that must be handled.
>>>
>>> A quick step back: I’m writing a reparse minifilter, which currently
>>> changes a path like C:\Test to a UNC share, \server\share. I have a
>>> function which takes in a PFLT_FILE_NAME_INFORMATION and checks to see if
>>> the path (The Name + (Volume.Length / sizeof(WCHAR))) portion starts with
>>> \Test, in which case it’ll replace the path with ??\UNC\Server\share.…
>>>
>>> The SimRep example posted pretty much does the same thing; its
>>> implementation of SetInformation first uses
>>> FltGetDestinationFileNameInformation() to get a PFLT_FILE_NAME_INFORMATION
>>> from the data in the FILE_RENAME_INFORMATION struct. I also wanted to use
>>> it for the same purpose, so I can pass the thing it returns into my
>>> function. Once I have that, if my function replaced the path, I would then
>>> go on to issue my own rename. But the function doesn’t seem to work when
>>> symlinks are involved (with a absolute path), hence my posting here.
>>>
>>> Do you think it’s a bug with FltGetDestinationFileNameInformation?
>>>
>>> Thanks!
>>> Stephen
>>>
>>> —
>>> NTFSD is sponsored by OSR
>>>
>>> OSR is hiring!! Info at http://www.osr.com/careers
>>>
>>> For our schedule of debugging and file system seminars visit:
>>> http://www.osr.com/seminars
>>>
>>> To unsubscribe, visit the List Server section of OSR Online at
>>> http://www.osronline.com/page.cfm?name=ListServer
>>>
>>
>> — NTFSD is sponsored by OSR OSR is hiring!! Info at
>> http://www.osr.com/careers For our schedule of debugging and file system
>> seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
>> List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>>
>
> — NTFSD is sponsored by OSR OSR is hiring!! Info at
> http://www.osr.com/careers For our schedule of debugging and file system
> seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
> List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Here’s another question then:

My replacement function currently operates on \Device\HardDisk… style paths. Since FltGetDestinationFileNameInformation won’t work, is there a OS provided function that takes a ??\C:\blah\blah\blah path and turns it into a \Device\HardDisk0\blah\blah\blah path? It seems prickly to try to parse that myself. Is the ??\ path format documented anywhere? It’s a difficult thing to query search engines about due to the all-punctuation thing.

Thanks for the help thus far!
stephen

Hi Stephen,

This is tricky because the volume name mount point doesn’t have to be C:
but instead could be C:\blah so then the final path would be
\Device\HardDisk0\blah\blah (one less blah). It could also be something
completely different, with all the symlinks and mount points and directory
junctions and even other reparse filters like yours the name "
??\C:\blah\blah\blah" could simply become “\Device\HardDisk7\foo\bar”.

This volume mount point thing is all done with reparse points and I would
only attempt to resolve a path through all these mount points by using the
create path. So I would try to open ??\C:\blah\blah\blah and if it
succeeds I’d have a FILE_OBJECT for which I can query both the file name
and the volume name (FltGetVolumeFromFileObject() and
then FltGetVolumeName()).

On the other hand, renames can only happen within the same volume (
http://msdn.microsoft.com/en-us/library/windows/hardware/ff540344(v=vs.85).aspxstates
that this is the case) so you know the volume you’re on because the
IRP_MJ_SET_INFORMATION is sent on a FILE_OBJECT on that same volume.
However, I don’t know how you’d be able to use that because just knowing
the volume name tells you nothing about the file name (as explained above).
So my advice is to really try to open the path, I’m not really aware of
anything else that goes through all the steps…

For more information about ??\ here are some links that explain
(hopefully) what’s happening:
1.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx-\>
in particular the section about win32 file namespaces
2. http://www.osronline.com/article.cfm?id=107 -> this talks about the
mount manager and drive letter mappings and it also explains a bit about
??\ and Global??
3. http://www.osronline.com/article.cfm?article=381 -> this talks in more
detail about Global??

Thanks,
Alex.

On Wed, Mar 5, 2014 at 5:36 PM, wrote:

> Here’s another question then:
>
> My replacement function currently operates on \Device\HardDisk… style
> paths. Since FltGetDestinationFileNameInformation won’t work, is there a
> OS provided function that takes a ??\C:\blah\blah\blah path and turns it
> into a \Device\HardDisk0\blah\blah\blah path? It seems prickly to try to
> parse that myself. Is the ??\ path format documented anywhere? It’s a
> difficult thing to query search engines about due to the all-punctuation
> thing.
>
> Thanks for the help thus far!
> stephen
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Considering that renames are the most rare file operation, thus not worth
noting as a costly operation, the above suggestion is your easiest and
safest bet to resolve mount points. This is what we used since FGDFNI does
not work in quite a few cases.

Kind regards, Dejan.

On Thu, Mar 6, 2014 at 5:56 PM, Alex Carp wrote:

> Hi Stephen,
>
> This is tricky because the volume name mount point doesn’t have to be C:
> but instead could be C:\blah so then the final path would be
> \Device\HardDisk0\blah\blah (one less blah). It could also be something
> completely different, with all the symlinks and mount points and
> directory junctions and even other reparse filters like yours the name “
> ??\C:\blah\blah\blah” could simply become “\Device\HardDisk7\foo\bar”.
>
> This volume mount point thing is all done with reparse points and I would
> only attempt to resolve a path through all these mount points by using the
> create path. So I would try to open ??\C:\blah\blah\blah and if it
> succeeds I’d have a FILE_OBJECT for which I can query both the file name
> and the volume name (FltGetVolumeFromFileObject() and
> then FltGetVolumeName()).
>
> On the other hand, renames can only happen within the same volume (
> http://msdn.microsoft.com/en-us/library/windows/hardware/ff540344(v=vs.85).aspxstates that this is the case) so you know the volume you’re on because the
> IRP_MJ_SET_INFORMATION is sent on a FILE_OBJECT on that same volume.
> However, I don’t know how you’d be able to use that because just knowing
> the volume name tells you nothing about the file name (as explained above).
> So my advice is to really try to open the path, I’m not really aware of
> anything else that goes through all the steps…
>
> For more information about ??\ here are some links that explain
> (hopefully) what’s happening:
> 1.
> http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx-> in particular the section about win32 file namespaces
> 2. http://www.osronline.com/article.cfm?id=107 -> this talks about the
> mount manager and drive letter mappings and it also explains a bit about
> ??\ and Global??
> 3. http://www.osronline.com/article.cfm?article=381 -> this talks in more
> detail about Global??
>
> Thanks,
> Alex.
>
>
> On Wed, Mar 5, 2014 at 5:36 PM, wrote:
>
>> Here’s another question then:
>>
>> My replacement function currently operates on \Device\HardDisk… style
>> paths. Since FltGetDestinationFileNameInformation won’t work, is there a
>> OS provided function that takes a ??\C:\blah\blah\blah path and turns it
>> into a \Device\HardDisk0\blah\blah\blah path? It seems prickly to try to
>> parse that myself. Is the ??\ path format documented anywhere? It’s a
>> difficult thing to query search engines about due to the all-punctuation
>> thing.
>>
>> Thanks for the help thus far!
>> stephen
>>
>> —
>> NTFSD is sponsored by OSR
>>
>> OSR is hiring!! Info at http://www.osr.com/careers
>>
>> For our schedule of debugging and file system seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>>
>
> — NTFSD is sponsored by OSR OSR is hiring!! Info at
> http://www.osr.com/careers For our schedule of debugging and file system
> seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
> List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer