summaryrefslogtreecommitdiffstats
path: root/Source/kwsys/EncodingCXX.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2017-04-19 12:02:06 (GMT)
committerBrad King <brad.king@kitware.com>2017-04-19 12:02:06 (GMT)
commit697a5d64d86d73b1353a90a5bfc9f444b97fedd7 (patch)
tree9780e3e1266b0d5231d1904f45808214ae9be5ba /Source/kwsys/EncodingCXX.cxx
parent3d3144bb023a98392594038973576cfbf046c039 (diff)
parent5785482ce0be9187ff94c1042f8978d2f11285e8 (diff)
downloadCMake-697a5d64d86d73b1353a90a5bfc9f444b97fedd7.zip
CMake-697a5d64d86d73b1353a90a5bfc9f444b97fedd7.tar.gz
CMake-697a5d64d86d73b1353a90a5bfc9f444b97fedd7.tar.bz2
Merge branch 'upstream-KWSys' into update-kwsys
* upstream-KWSys: KWSys 2017-04-19 (9f6ffaff)
Diffstat (limited to 'Source/kwsys/EncodingCXX.cxx')
-rw-r--r--Source/kwsys/EncodingCXX.cxx58
1 files changed, 58 insertions, 0 deletions
diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx
index e904c1a..641c0e6 100644
--- a/Source/kwsys/EncodingCXX.cxx
+++ b/Source/kwsys/EncodingCXX.cxx
@@ -29,6 +29,7 @@
#if defined(_WIN32)
#include <windows.h>
+#include <ctype.h>
#include <shellapi.h>
#endif
@@ -214,6 +215,63 @@ std::string Encoding::ToNarrow(const wchar_t* wcstr)
}
return str;
}
+
+#if defined(_WIN32)
+// Convert local paths to UNC style paths
+std::wstring Encoding::ToWindowsExtendedPath(std::string const& source)
+{
+ std::wstring wsource = Encoding::ToWide(source);
+
+ // Resolve any relative paths
+ DWORD wfull_len;
+
+ /* The +3 is a workaround for a bug in some versions of GetFullPathNameW that
+ * won't return a large enough buffer size if the input is too small */
+ wfull_len = GetFullPathNameW(wsource.c_str(), 0, NULL, NULL) + 3;
+ std::vector<wchar_t> wfull(wfull_len);
+ GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], NULL);
+
+ /* This should get the correct size without any extra padding from the
+ * previous size workaround. */
+ wfull_len = static_cast<DWORD>(wcslen(&wfull[0]));
+
+ if (wfull_len >= 2 && isalpha(wfull[0]) &&
+ wfull[1] == L':') { /* C:\Foo\bar\FooBar.txt */
+ return L"\\\\?\\" + std::wstring(&wfull[0]);
+ } else if (wfull_len >= 2 && wfull[0] == L'\\' &&
+ wfull[1] == L'\\') { /* Starts with \\ */
+ if (wfull_len >= 4 && wfull[2] == L'?' &&
+ wfull[3] == L'\\') { /* Starts with \\?\ */
+ if (wfull_len >= 8 && wfull[4] == L'U' && wfull[5] == L'N' &&
+ wfull[6] == L'C' &&
+ wfull[7] == L'\\') { /* \\?\UNC\Foo\bar\FooBar.txt */
+ return std::wstring(&wfull[0]);
+ } else if (wfull_len >= 6 && isalpha(wfull[4]) &&
+ wfull[5] == L':') { /* \\?\C:\Foo\bar\FooBar.txt */
+ return std::wstring(&wfull[0]);
+ } else if (wfull_len >= 5) { /* \\?\Foo\bar\FooBar.txt */
+ return L"\\\\?\\UNC\\" + std::wstring(&wfull[4]);
+ }
+ } else if (wfull_len >= 4 && wfull[2] == L'.' &&
+ wfull[3] == L'\\') { /* Starts with \\.\ a device name */
+ if (wfull_len >= 6 && isalpha(wfull[4]) &&
+ wfull[5] == L':') { /* \\.\C:\Foo\bar\FooBar.txt */
+ return L"\\\\?\\" + std::wstring(&wfull[4]);
+ } else if (wfull_len >=
+ 5) { /* \\.\Foo\bar\ Device name is left unchanged */
+ return std::wstring(&wfull[0]);
+ }
+ } else if (wfull_len >= 3) { /* \\Foo\bar\FooBar.txt */
+ return L"\\\\?\\UNC\\" + std::wstring(&wfull[2]);
+ }
+ }
+
+ // If this case has been reached, then the path is invalid. Leave it
+ // unchanged
+ return Encoding::ToWide(source);
+}
+#endif
+
#endif // KWSYS_STL_HAS_WSTRING
} // namespace KWSYS_NAMESPACE