reparse points in NTFS

Hi all,

I am trying to create a reparse point in NTFS that points to my file system,
so that it can be mounted inside C: instead of its own drive letter. My
file system is virtual, it has no VDOs or VPBs. It has one CDO named
“\Pifs”, and a symbolic link that points to it: “\GLOBAL??\PiFS” –>
“\Pifs”. I am running on XP SP2.

The threads on this mailing list wrt reparse points are about implementing
reparse points in custom FSD filters, but I am not interested in that as
much. The documentation on “Microsoft style” reparse points is sparse an
incomplete it seems, but I found a few link on the web, the best of which is
this:

http://www.sysinternals.com/Utilities/Junction.html

With this tool, I can create a junction like this:

junction.exe C:\temp\mnt\ “C:\Program Files”

which works correctly. Trying to create a junction to my file system
generates the infamous “The data present in the reparse point buffer is
invalid”.

Looking at the junction code, it declares its own data structure
REPARSE_MOUNTPOINT_DATA_BUFFER which it passes to
DeviceIoControl(FSCTL_SET_REPASE_POINT). It always prepends "??" to the
link target, and strips off the trailing "" iff the second last character
is a “:”.

I modified the code to not do the link target manipulations to allow me more
room for experimentation. I tried the following:

Junction c:\temp\mnt\ \Pifs // nope
Junction c:\temp\mnt\ ??\Pifs // uh-un
Junction c:\temp\mnt\ \?\Pifs // please try again
Junction c:\temp\mnt\ ????\Pifs // no way
Junction c:\temp\mnt\ \???\Pifs // you’re kidding right?

All fail in one of two ways. The first way is with the invalid buffer
message. The second way works when calling DeviceIoControl(), but says
directory not found when I do “dir c:\temp\mnt”.

Again in the junction code, I noticed that it handles a reparse tag of
0x80000000|IO_REPARSE_TAG_SYMBOLIC_LINK when displaying the reparse
information for a directory. I modified the code to use this instead of
IO_REPARSE_TAG_MOUNT_POINT when creating a junction, but it did not help
(DeviceIoControl succeeded, but dir failed).

Is there a way to create a reparse point in NTFS so that it acts just like
an object manager symbolic link? If so, what is the structure to pass to
DeviceIoControl() and how do you fill in the fields? I can create drive
letter symbolic links, like “\GLOBAL??\P:” –> “\Pifs” and that works fine.

Thanks.

=================================================
Roger Tawa
http://tawacentral.net/
[One thing about paradigms: shift happens.]
[When you stop, you’re done.]

> The second way works when calling DeviceIoControl(), but says

directory not found when I do “dir c:\temp\mnt”.

This would indicate that the reparse point is in place, but that it now
points to somewhere invalid. I’m assuming that in this case you are sure
that you are not getting a IRP at your file system?

Have a look at the reparse point (filetest is your friend). Where is it
pointing?

It sounds as though something is being helpful and checking the parameters,
It might be worth attaching filespy (both to C abnd to your device) and see
what is going on (and if it were I, I would use filetest so I was sure I was
sending a single IRP).

As a side note, from the point of view of an implementing filesystem, an
object manager symbolic link (which have been there since NT3.51) is not the
same as a reparse point (W2k?). They differ in the values which are
returned in Irp->IoStatus.Information and in the way in which the new name
is returned.

“Roger Tawa” wrote in message news:xxxxx@ntfsd…
> Hi all,
>
> I am trying to create a reparse point in NTFS that points to my file
> system,
> so that it can be mounted inside C: instead of its own drive letter. My
> file system is virtual, it has no VDOs or VPBs. It has one CDO named
> “\Pifs”, and a symbolic link that points to it: “\GLOBAL??\PiFS” –>
> “\Pifs”. I am running on XP SP2.
>
> The threads on this mailing list wrt reparse points are about implementing
> reparse points in custom FSD filters, but I am not interested in that as
> much. The documentation on “Microsoft style” reparse points is sparse an
> incomplete it seems, but I found a few link on the web, the best of which
> is
> this:
>
> http://www.sysinternals.com/Utilities/Junction.html
>
> With this tool, I can create a junction like this:
>
> junction.exe C:\temp\mnt\ “C:\Program Files”
>
> which works correctly. Trying to create a junction to my file system
> generates the infamous “The data present in the reparse point buffer is
> invalid”.
>
> Looking at the junction code, it declares its own data structure
> REPARSE_MOUNTPOINT_DATA_BUFFER which it passes to
> DeviceIoControl(FSCTL_SET_REPASE_POINT). It always prepends "??" to the
> link target, and strips off the trailing "" iff the second last character
> is a “:”.
>
> I modified the code to not do the link target manipulations to allow me
> more
> room for experimentation. I tried the following:
>
> Junction c:\temp\mnt\ \Pifs // nope
> Junction c:\temp\mnt\ ??\Pifs // uh-un
> Junction c:\temp\mnt\ \?\Pifs // please try again
> Junction c:\temp\mnt\ ????\Pifs // no way
> Junction c:\temp\mnt\ \???\Pifs // you’re kidding right?
>
> All fail in one of two ways. The first way is with the invalid buffer
> message. The second way works when calling DeviceIoControl(), but says
> directory not found when I do “dir c:\temp\mnt”.
>
> Again in the junction code, I noticed that it handles a reparse tag of
> 0x80000000|IO_REPARSE_TAG_SYMBOLIC_LINK when displaying the reparse
> information for a directory. I modified the code to use this instead of
> IO_REPARSE_TAG_MOUNT_POINT when creating a junction, but it did not help
> (DeviceIoControl succeeded, but dir failed).
>
> Is there a way to create a reparse point in NTFS so that it acts just like
> an object manager symbolic link? If so, what is the structure to pass to
> DeviceIoControl() and how do you fill in the fields? I can create drive
> letter symbolic links, like “\GLOBAL??\P:” –> “\Pifs” and that works
> fine.
>
> Thanks.
>
> =================================================
> Roger Tawa
> http://tawacentral.net/
> [One thing about paradigms: shift happens.]
> [When you stop, you’re done.]
>
>
>
>

Thanks for the pointers Rod.

This would indicate that the reparse point is in place, but that it now
points to somewhere invalid. I’m assuming that in this case you are sure
that you are not getting a IRP at your file system?
Correct, no IRPs to my file system. This is what I see from the
filespy output. It evetually gets to this:

IRP_MJ_CREATE C:\Temp\mnt STATUS_REPARSE FILE_OPEN CreOpts: 0x00000021
Access: 0x00100001 Share: 0x00000003 Attrib: 0

and then nothing more.

Have a look at the reparse point (filetest is your friend). Where is it
pointing?
How do you use filetest to see the reparse point data? This data
cannot be read in the normal way, and I don’t see how to send ioctls
with filetest? I am using version 1.7.0.92. The junction tool from
sysinternal shows:

C:\Temp\mnt: SYMBOLIC LINK
Substibute name: ??\Pifs

It sounds as though something is being helpful and checking the parameters,
It might be worth attaching filespy (both to C abnd to your device) and see
what is going on (and if it were I, I would use filetest so I was sure I was
sending a single IRP).
Yes, very helpful :slight_smile: With FileSpy, I see the status_reparse being
returned. But unfortunately it does not show what the new path
returned is. I am using version 2.0.0.180, driver version
1.2.5112.308.

As a side note, from the point of view of an implementing filesystem, an
object manager symbolic link (which have been there since NT3.51) is not the
same as a reparse point (W2k?). They differ in the values which are
returned in Irp->IoStatus.Information and in the way in which the new name
is returned.
Where can I find out/read more about this?

=================================================
Roger Tawa
http://tawacentral.net/
[One thing about paradigms: shift happens.]
[When you stop, you’re done.]

>> Have a look at the reparse point (filetest is your friend). Where is it

> pointing?
How do you use filetest to see the reparse point data? This data
cannot be read in the normal way, and I don’t see how to send ioctls
with filetest?

My bad. It doesn’t seem like you can. (But I’m sure Ladislav is listening
:slight_smile:

The junction tool from
sysinternal shows:

C:\Temp\mnt: SYMBOLIC LINK
Substibute name: ??\Pifs

Which does seem strange since in my understanding of the object manager this
should eventually resolve to \global??\pifs

I’m fast running out of ideas now - Everytime I have used symbolic links and
reparse points the object manager is ‘just worked’

Thanks for all your time Rod.

I’m fast running out of ideas now - Everytime I have used symbolic links and
reparse points the object manager is ‘just worked’

Last night, while searching for more info, I found this:

http://support.microsoft.com/kb/253344

which seems to imply that reparse points only support “local drives”
as targets. Its unclear though if this is a linkd.exe limitation or a
limitation of NTFS reparse points, although I am suspecting the
latter, because of this:

http://support.microsoft.com/kb/205524

It compares DFS junction points to NTFS junction points, and under
NTFS it says the target is “any valid windows 2000 local path”. I
guess “??\Pifs” does not meet the requirements of a “local path” or a
“local drive”.

Its strange because I have a symbolic link “\GLOBAL??\P:” –> “\Pifs”,
giving me access to my file system via P:, but creating an NTFS
junction from “C:\Temp\mnt” to "P:" also does not work
(DeviceIoControl fails).

=================================================
Roger Tawa
http://tawacentral.net/
[One thing about paradigms: shift happens.]
[When you stop, you’re done.]