[llvm] r371035 - Win: handle \\?\UNC\ prefix in realPathFromHandle (PR43204)

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 5 02:07:05 PDT 2019


Author: hans
Date: Thu Sep  5 02:07:05 2019
New Revision: 371035

URL: http://llvm.org/viewvc/llvm-project?rev=371035&view=rev
Log:
Win: handle \\?\UNC\ prefix in realPathFromHandle (PR43204)

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

Modified:
    llvm/trunk/lib/Support/Windows/Path.inc

Modified: llvm/trunk/lib/Support/Windows/Path.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Path.inc?rev=371035&r1=371034&r2=371035&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Windows/Path.inc (original)
+++ llvm/trunk/lib/Support/Windows/Path.inc Thu Sep  5 02:07:05 2019
@@ -371,13 +371,19 @@ static std::error_code realPathFromHandl
   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.




More information about the llvm-commits mailing list