Skip to content

Commit

Permalink
Win: handle \\?\UNC\ prefix in realPathFromHandle (PR43204)
Browse files Browse the repository at this point in the history
After r361885, realPathFromHandle() ends up getting called on the working
directory on each Clang invocation. This unveiled that the code didn't work for
paths on network shares.

For example, if one maps the local dir c:\src\tmp to x:

  net use x: \\localhost\c$\tmp

and run e.g. "clang -c foo.cc" in x:\, realPathFromHandle will get
\\?\UNC\localhost\c$\src\tmp\ back from GetFinalPathNameByHandleW, and would
strip off the initial \\?\ prefix, ending up with a path that doesn't work.

This patch makes the prefix stripping a little smarter to handle this case.

Differential revision: https://reviews.llvm.org/D67166

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@371035 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
zmodem committed Sep 5, 2019
1 parent f4cf1dd commit 4ded9b4
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions lib/Support/Windows/Path.inc
Original file line number Diff line number Diff line change
Expand Up @@ -371,13 +371,19 @@ static std::error_code realPathFromHandle(HANDLE H,
if (std::error_code EC = realPathFromHandle(H, Buffer))
return EC;

const wchar_t *Data = Buffer.data();
// Strip the \\?\ prefix. We don't want it ending up in output, and such
// paths don't get canonicalized by file APIs.
wchar_t *Data = Buffer.data();
DWORD CountChars = Buffer.size();
if (CountChars >= 4) {
if (0 == ::memcmp(Data, L"\\\\?\\", 8)) {
CountChars -= 4;
Data += 4;
}
if (CountChars >= 8 && ::memcmp(Data, L"\\\\?\\UNC\\", 16) == 0) {
// Convert \\?\UNC\foo\bar to \\foo\bar
CountChars -= 6;
Data += 6;
Data[0] = '\\';
} else if (CountChars >= 4 && ::memcmp(Data, L"\\\\?\\", 8) == 0) {
// Convert \\?\c:\foo to c:\foo
CountChars -= 4;
Data += 4;
}

// Convert the result from UTF-16 to UTF-8.
Expand Down

0 comments on commit 4ded9b4

Please sign in to comment.