\ ?? \和\\?\路径之间有区别吗?

时间:2014-08-01 23:26:48

标签: winapi internals

MSDN文档Naming Files, Paths, and Namespaces讨论了\\?\前缀。引用:

  

对于文件I / O," \?\"路径字符串的前缀告诉Windows API禁用所有字符串解析并将其后面的字符串直接发送到文件系统。

实验向我展示了\??\前缀具有相同的效果,包括禁用路径解析(..处理)和启用长于MAX_PATH的路径。

MSDN将\\?称为" Win32文件命名空间",它是纯粹由Win32用户模式API知道并在NT命名空间中转换为\??吗?无论如何,通过Winobj我在NT命名空间中看到GLOBAL??,而不是??

1 个答案:

答案 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 前缀完成的创建才会成功。

\\?\