Cha*_*ald 7 c++ windows winapi ntfs
在我当前个人项目的Windows版本中,我希望支持扩展长度的文件路径.因此,我对如何使用GetFullPathNameW API来解析长文件路径的全名感到困惑.
根据MSDN(关于lpFileName参数):
在此函数的ANSI版本中,名称仅限于MAX_PATH字符.要将此限制扩展为32,767个宽字符,请调用该函数的Unicode版本并在路径前添加"\?\".有关更多信息,请参阅命名文件.
如果我正确理解这一点,为了使用扩展长度的文件路径GetFullPathNameW,我需要指定一个\\?\附加前缀的路径.由于\\?\前缀仅在卷字母或UNC路径之前有效,这意味着API无法用于解析相对于当前目录的路径的全名.
如果是这种情况,我是否可以使用另一个API来解析文件路径的全名,..\somedir\somefile.txt如果结果名称的长度超过MAX_PATH?如果没有,我是否能够GetCurrentDirectory与相对文件路径(\\?\C:\my\cwd\..\somedir\somefile.txt)结合并使用它GetFullPathNameW,或者我需要自己处理所有文件路径解析?
RbM*_*bMm 10
GetFullPathNameA仅限于MAX_PATH字符,因为它UNICODE使用硬编码的MAX_PATH(字符)UNICODE缓冲区预先将ANSI名称转换为名称.如果转换由于长度限制而未失败,则调用GetFullPathNameW(或直接GetFullPathName_U[Ex])并将结果UNICODE名称转换为ANSI.
GetFullPathNameW是一个非常薄的壳GetFullPathName_U.它仅限MAXSHORT (0x7fff)于WCHAR中的长度,与\\?\文件前缀无关.即使没有\\?\,它也适用于长(> MAX_PATH)相对名称.但是,如果lpFileName参数不以\\?\前缀开头,则参数中的结果名称lpBuffer也不会以\\?\任何一个开头.
如果你将使用lpBuffer像CreateFileW这样的函数 - 这个函数在内部转换Win32Name为NtName.结果将取决于nape type(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, ...);
}
}
Run Code Online (Sandbox Code Playgroud)
所以我们需要指定一个\\?\附加前缀的路径,但不要在GetFullPathName之后 - 之后!
有关详细信息,请阅读此 - Win32到NT路径转换的权威指南
| 归档时间: |
|
| 查看次数: |
2382 次 |
| 最近记录: |