MSDN文档Naming Files, Paths, and Namespaces讨论了\\?\
前缀。引用:
对于文件I / O," \?\"路径字符串的前缀告诉Windows API禁用所有字符串解析并将其后面的字符串直接发送到文件系统。
实验向我展示了\??\
前缀具有相同的效果,包括禁用路径解析(..
处理)和启用长于MAX_PATH
的路径。
MSDN将\\?
称为" Win32文件命名空间",它是纯粹由Win32用户模式API知道并在NT命名空间中转换为\??
吗?无论如何,通过Winobj我在NT命名空间中看到GLOBAL??
,而不是??
。
答案 0 :(得分:10)
您的问题的答案是,是的,将\\?\
和\??\
传递给用户模式功能之间存在差异。
在内部,NT始终表示具有\??\
前缀的路径。通常,当您使用正常路径(如CreateDirectoryW
)调用用户模式函数(例如C:\foo
)时,用户模式函数会调用名为RtlDosPathNameToNtPathName_U
的内部函数,该函数将其转换为NT样式以\??\
为前缀的路径。这种转换是使用固定大小的静态缓冲区完成的,这是着名的MAX_PATH
限制的来源。
当您调用指定\\?\
前缀的用户模式功能时(请注意,只有一个?
),RtlDosPathNameToNtPathName_U
不被调用。相反,第二个反斜杠变成了?字符和路径是逐字使用的。这就是当他们谈论\\?\
关闭" ...自动扩展路径字符串时文档的含义。"
但是,当您使用\??\
前缀调用用户模式函数时,该前缀记住是内部NT前缀,此扩展仍然完成。
用户模式功能专门查找\\?\
以禁用自动扩展过程,并且由于您未提供此功能,因此您的路径将被视为非加前缀路径并被送至{{1} }。此功能足够智能,不会在路径的开头添加额外的RtlDosPathNameToNtPathName_U
前缀,但仍然使用固定大小的静态缓冲区。
这是关键的区别。当您将\??\
作为前缀传递时,您的路径仍受\??\
长度限制。
以下示例程序演示了这一点。 MAX_PATH
函数只是尝试创建(然后删除)长度大于TestNestedDir
个字符的路径,一次一个级别。如果您运行此代码,您将看到的结果是:
MAX_PATH
只有使用CreateDir, no prefix = 0
CreateDir, prefix \\?\ = 1
CreateDir, prefix \??\ = 0
前缀完成的创建才会成功。
\\?\