I am trying to use Windows API functions compatible with Windows XP and up to find the target of a junction or symbolic link. I am using CreateFile
to get a handle to the reparse point, then DeviceIoControl
with the FSCTL_GET_REPARSE_POINT
flag to read the reparse data into a REPARSE_DATA_BUFFER
. Then, I use the offsets and lengths in the buffer to extract the SubstituteName
and PrintName
strings.
In Windows 8, extracting the PrintName
works perfectly, giving me a normal path (ie c:\filename.ext
), but in XP the PrintName
section of the REPARSE_DATA_BUFFER
seems to always have a length of 0, leaving me with an empty string.
Using the SubsituteName
seems to work in both, but I always end up with a prefix of \??\
on the beginning of the file path (ie \??\c:\filename.ext
). (as a side note, fsutil reparsepoint query
shows the \??\
prefix as well).
I've read through much of the documentation on MSDN, but I can't find any explanation of this prefix. If the prefix is guaranteed to begin every SubstituteName
, then I can just exclude the first four characters when I copy the file path from the buffer, but I'm not sure that this is the case. I would love to know if the "\??\"
prefix appears in the SubstituteName
for all Microsoft reparse points and why.
The Windows kernel has a "DOS Devices namespace" \DosDevices\
which is basically where anything you can open with CreateFile
resides. (QueryDosDevice
is a function which gives you all the members of that namespace.)
Because it's such a commonly used path, \??\
also redirects to that namespace. So, to the kernel, the path C:\Windows
is invalid -- it should really be written as something like \??\C:\Windows
. That's where this notation comes from.