C++ GetFullPathNameW和长Windows文件路径
在我当前个人项目的Windows版本中,我希望获得支持。因此,我对如何使用API解析长文件路径的全名有点困惑 根据MSDN(关于lpFileName参数): 在该函数的ANSI版本中,名称仅限于MAX_路径字符。要将此限制扩展到32767个宽字符,请调用Unicode版本的函数,并在路径前加上“\?\”。有关详细信息,请参见命名文件 如果我正确理解了这一点,为了使用扩展长度的文件路径和C++ GetFullPathNameW和长Windows文件路径,c++,windows,winapi,ntfs,C++,Windows,Winapi,Ntfs,在我当前个人项目的Windows版本中,我希望获得支持。因此,我对如何使用API解析长文件路径的全名有点困惑 根据MSDN(关于lpFileName参数): 在该函数的ANSI版本中,名称仅限于MAX_路径字符。要将此限制扩展到32767个宽字符,请调用Unicode版本的函数,并在路径前加上“\?\”。有关详细信息,请参见命名文件 如果我正确理解了这一点,为了使用扩展长度的文件路径和GetFullPathNameW,我需要指定一个带有\\?\前缀的路径。由于\\?\前缀仅在卷号或UNC路径之前
GetFullPathNameW
,我需要指定一个带有\\?\
前缀的路径。由于\\?\
前缀仅在卷号或UNC路径之前有效,这意味着API无法解析相对于当前目录的路径的全名
如果是这种情况,是否有其他API可用于解析文件路径的全名,如。\somedir\somefile.txt
,如果结果名称的长度超过MAX\u PATH
?如果没有,我是否能够将GetCurrentDirectory
与相对文件路径(\?\C:\my\cwd\..\somedir\somefile.txt
)结合使用,或者需要自己处理所有文件路径解析
GetFullPathNameA
仅限于MAX\u PATH
个字符,因为它预先使用硬编码的MAX\u PATH
缓冲区将ANSI名称转换为UNICODE
名称。如果转换没有由于长度限制而失败,则调用GetFullPathNameW
(或directGetFullPathName\U[Ex]
)并将生成的UNICODE
名称转换为ANSIGetFullPathName w
是GetFullPathName\U
之上的一个非常薄的外壳。它被限制为WCHARs中的MAXSHORT(0x7fff)
长度,与\\?\
文件前缀无关。即使没有\\?\
,它也会对长(>MAX\u PATH
)相对名称起作用。但是,如果lpFileName
参数不是以\\?\
前缀开头,则lpBuffer
参数中的结果名称也不会以\\?\
开头lpBuffer
与CreateFileW
等函数一起使用,则此函数将Win32Name
内部转换为NtName
。结果将取决于nape类型(RTL\u PATH\u类型
)。如果名称不以前缀\\?\
开头,转换将失败,因为rtldospathnametorerelativentpathname\U[\U with status]
失败(因为如果路径不以\\?\
开头,它将在内部调用GetFullPathName\U
(与GetFullPathNameW
调用的函数相同)使用nBufferLength
硬编码到MAX\U PATH(精确地说是2*MAX\U PATH
以字节为单位–NTDLL函数使用以字节为单位的缓冲区大小,而不是以WCHAR
s为单位)。如果名称以\\?\
前缀开头,则在rtldospathname torelativentpathname\U[\U with status]中使用另一种情况执行
-RtlpWin32NtNameToNtPathName
,它将\\?\
替换为\??\
,并且没有最大路径
限制if(ULONG len = GetFullPathNameW(FileName, 0, 0, 0))
{
PWSTR buf = (PWSTR)_alloca((4 + len) * sizeof(WCHAR));
buf[0] = L'\\', buf[1] = L'\\', buf[2] = L'?', buf[3] = L'\\';
if (len - 1 == GetFullPathName(FileName, len, buf + 4, &c))
{
CreateFile(buf, ...);
}
}
所以我们需要指定一个带有\\?\
前缀的路径,但不能在GetFullPathName之前-之后
有关更多信息,请阅读以下内容-
GetFullPathNameA
仅限于MAX\u PATH
字符,因为它预先使用硬编码的MAX\u PATH
大小(以字符为单位)的UNICODE
缓冲区将ANSI名称转换为UNICODE
名称。如果转换没有由于长度限制而失败,则GetFullPathNameW
(或直接调用GetFullPathName\U[Ex]
)并将生成的UNICODE
名称转换为ANSIGetFullPathName w
是GetFullPathName\U
之上的一个非常薄的外壳。它在WCHARs中仅限于MAXSHORT(0x7fff)
长度,与\?\
文件前缀无关。即使没有\?\
,它也会工作很长时间(>MAX\U PATH
)相对名称。但是,如果lpFileName
参数不是以\\?\
前缀开头,则lpBuffer
参数中的结果名称也不会以\\?\
开头lpBuffer
与CreateFileW
等函数一起使用,则此函数将Win32Name
内部转换为NtName
。结果将取决于nape类型(RTL\u PATH\u type
)。如果名称不以前缀\\?\
开头,转换将失败,因为rtldospathname to relativentpathname\U[\U with status]
失败(因为如果路径不以\?\
开头,它将在内部调用GetFullPathName\U
(与GetFullPathName
调用的函数相同)使用nBufferLength
硬编码到MAX\U PATH(精确地说是2*MAX\U PATH
以字节为单位–NTDLL函数使用以字节为单位的缓冲区大小,而不是以WCHAR
s为单位)。如果名称以\\?\
前缀开头,则在rtldospathname torelativentpathname\U[\U with status]中使用另一种情况执行
-RtlpWin32NtNameToNtPathName
,它将\\?\
替换为\??\
,并且没有最大路径
限制if(ULONG len = GetFullPathNameW(FileName, 0, 0, 0))
{
PWSTR buf = (PWSTR)_alloca((4 + len) * sizeof(WCHAR));
buf[0] = L'\\', buf[1] = L'\\', buf[2] = L'?', buf[3] = L'\\';
if (len - 1 == GetFullPathName(FileName, len, buf + 4, &c))
{
CreateFile(buf, ...);
}
}
所以我们需要指定一个带有\\?\
前缀的路径,但不能在GetFullPathName之前-之后
有关更多信息,请阅读此-以更新当前状态: 从Windows10版本1607开始,已取消最大路径限制