GetFullPathNameA limited to GetFullPathNameA characters because it pre-converts the ANSI name to UNICODE using the hard-coded buffer MAX_PATH -sized (in characters) UNICODE . If the conversion does not fail due to length restrictions, GetFullPathNameW (or the direct GetFullPathName_U[Ex] ) is called, and the resulting UNICODE name is converted to ANSI.
GetFullPathNameW very thin shell over GetFullPathName_U . It is limited by the length of MAXSHORT (0x7fff) in WCHAR, regardless of the \\?\ File prefix. Even without \\?\ , This will work for long (> MAX_PATH ) relative names. However, if the lpFileName parameter lpFileName not start with the \\?\ Prefix, the result name in the lpBuffer parameter also will not start with \\?\ .
if you use lpBuffer with functions such as CreateFileW , this function internally converts Win32Name to NtName . and the result will depend on the type of neck ( RTL_PATH_TYPE ). if the name does not start with the prefix \\?\ , the conversion will fail because RtlDosPathNameToRelativeNtPathName_U[_WithStatus] will fail (because if the path does not start with \\?\ , it will be called internally by GetFullPathName_U (the same function that GetFullPathNameW calls ) with nBufferLength hardcoded to MAX_PATH (exactly 2*MAX_PATH in bytes - NTDLL functions use the size of the buffer in bytes rather than in WCHAR s.) If the name starts with the prefix \\?\ , another case is RtlDosPathNameToRelativeNtPathName_U[_WithStatus] in RtlDosPathNameToRelativeNtPathName_U[_WithStatus] RtlpWin32NtNameToNtPathName , which replaces \\?\ RtlpWin32NtNameToNtPathName \??\ and has no MAX_PATH restriction
So the solution might look like this:
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, ...); } }
So, we need to specify the path with the prefix \\?\ Attached, but not before GetFullPathName - after!
For more information, read this - Complete Guide to Converting a Win32 Path to NT
source share