Does the "SubstituteName" string in the PathBuffer of a REPARSE_DATA_BUFFER structure always start with the prefix "\??\", and if so, why?

StackOverflow https://stackoverflow.com/questions/14329653

  •  15-01-2022
  •  | 
  •  

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.

其他提示

The \??\ prefix means the path is not parsed. It is not guaranteed on every name, so you will have to look for the prefix on a per-name basis and skip it if present.

Update: I could not find any definitive documentation explaining exactly that \??\ actually represents, but here are some links that mention the \??\ prefix in action:

http://www.flexhex.com/docs/articles/hard-links.phtml

Note that szTarget string must contain the path prefixed with the "non-parsed" prefix "\??\", and terminated with the backslash character, for example "\??\C:\Some Dir\".

http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/908b3927-1ee9-4e03-9922-b4fd49fc51a6

http://mjunction.googlecode.com/svn-history/r5/trunk/MJunction/MJunction/JunctionPoint.cs

This prefix indicates to NTFS that the path is to be treated as a non-interpreted path in the virtual file system.

Private Const NonInterpretedPathPrefix As String = "\??\"

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top