GetFullPathNameA
被限制为MAX_PATH
字符,因为它的ANSI名称转换为UNICODE
名称预先使用尺度的硬编码MAX_PATH
(在字符)UNICODE
缓冲器。如果转换未因长度限制而失败,则调用GetFullPathNameW
(或直接GetFullPathName_U[Ex]
),并将生成的UNICODE
名称转换为ANSI。
GetFullPathNameW
是一个非常薄的外壳而不是GetFullPathName_U
。它限制在WCHAR中的长度为MAXSHORT (0x7fff)
,独立于\\?\
文件前缀。即使没有\\?\
,它也会长时间工作(>MAX_PATH
)相对名称。但是,如果lpFileName
参数未以\\?\
前缀开头,则lpBuffer
参数中的结果名称也不会以\\?\
开头。
如果你将使用lpBuffer
与像CreateFileW
功能 - 这一功能在内部转换Win32Name
到NtName
。结果将取决于颈背型(RTL_PATH_TYPE
)。如果名称不\\?\
前缀开头,则转换失败,因为RtlDosPathNameToRelativeNtPathName_U[_WithStatus]
失败(因为如果路径不是\\?\
开始它会在内部调用GetFullPathName_U
(由GetFullPathNameW
称为相同的功能)与nBufferLength
硬编码到MAX_PATH(以字节完全2*MAX_PATH
- NTDLL函数使用缓冲区大小以字节为单位,而不是在WCHAR
s)。如果名称与\\?\
前缀开头,在RtlDosPathNameToRelativeNtPathName_U[_WithStatus]
另一种情况下,执行 - RtlpWin32NtNameToNtPathName
,这与\??\
取代\\?\
并没有MAX_PATH
限制
因此,解决办法可能是这样的:
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之前 - !
欲了解更多信息,请阅读本 - The Definitive Guide on Win32 to NT Path Conversion
这听起来不是合理的功能找到的完整路径,需要你提供完整的路径。那么为什么不试试这些文档所说的。也许你会感到惊喜。 –
GetCurrentDirectory()是基本上是MAX_PATH阻塞的unixism。本地操作系统没有相对路径或默认目录的概念,您必须*始终*提供完整的路径名称。你必须摆脱它才能超前。 –
@ Cheersandhth.-Alf如果您建议我尝试'\\?\ C:\ my \ cwd \ .. \ somedir \ somefile.txt'或'\\?\ .. \ somedir \ somefile .txt',所以我尝试了两种。第一个正确解析为'\\?\ C:\ my \ somedir \ somefile.txt'(它回答了我的问题的一部分),而第二个错误地解析为'\\?\ somedir \ somefile.txt'。 –