summaryrefslogtreecommitdiff
path: root/src/libs/dutil/WixToolset.DUtil/pathutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/pathutil.cpp')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/pathutil.cpp102
1 files changed, 85 insertions, 17 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/pathutil.cpp b/src/libs/dutil/WixToolset.DUtil/pathutil.cpp
index 9823779b..314eab85 100644
--- a/src/libs/dutil/WixToolset.DUtil/pathutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/pathutil.cpp
@@ -20,6 +20,10 @@
20 20
21#define PATH_GOOD_ENOUGH 64 21#define PATH_GOOD_ENOUGH 64
22 22
23static BOOL IsValidDriveChar(
24 __in WCHAR wc
25 );
26
23 27
24DAPI_(LPWSTR) PathFile( 28DAPI_(LPWSTR) PathFile(
25 __in_z LPCWSTR wzPath 29 __in_z LPCWSTR wzPath
@@ -272,29 +276,30 @@ DAPI_(HRESULT) PathPrefix(
272 276
273 HRESULT hr = S_OK; 277 HRESULT hr = S_OK;
274 LPWSTR wzFullPath = *psczFullPath; 278 LPWSTR wzFullPath = *psczFullPath;
279 BOOL fFullyQualified = FALSE;
280 BOOL fHasPrefix = FALSE;
275 SIZE_T cbFullPath = 0; 281 SIZE_T cbFullPath = 0;
276 282
277 if (((L'a' <= wzFullPath[0] && L'z' >= wzFullPath[0]) || 283 fFullyQualified = PathIsFullyQualified(wzFullPath, &fHasPrefix);
278 (L'A' <= wzFullPath[0] && L'Z' >= wzFullPath[0])) && 284 if (fHasPrefix)
279 L':' == wzFullPath[1] && 285 {
280 L'\\' == wzFullPath[2]) // normal path 286 ExitFunction();
287 }
288
289 if (fFullyQualified && L':' == wzFullPath[1]) // normal path
281 { 290 {
282 hr = StrAllocPrefix(psczFullPath, L"\\\\?\\", 4); 291 hr = StrAllocPrefix(psczFullPath, L"\\\\?\\", 4);
283 PathExitOnFailure(hr, "Failed to add prefix to file path."); 292 PathExitOnFailure(hr, "Failed to add prefix to file path.");
284 } 293 }
285 else if (L'\\' == wzFullPath[0] && L'\\' == wzFullPath[1]) // UNC 294 else if (fFullyQualified && L'\\' == wzFullPath[1]) // UNC
286 { 295 {
287 // ensure that we're not already prefixed 296 hr = StrSize(*psczFullPath, &cbFullPath);
288 if (!(L'?' == wzFullPath[2] && L'\\' == wzFullPath[3])) 297 PathExitOnFailure(hr, "Failed to get size of full path.");
289 {
290 hr = StrSize(*psczFullPath, &cbFullPath);
291 PathExitOnFailure(hr, "Failed to get size of full path.");
292 298
293 memmove_s(wzFullPath, cbFullPath, wzFullPath + 1, cbFullPath - sizeof(WCHAR)); 299 memmove_s(wzFullPath, cbFullPath, wzFullPath + 1, cbFullPath - sizeof(WCHAR));
294 300
295 hr = StrAllocPrefix(psczFullPath, L"\\\\?\\UNC", 7); 301 hr = StrAllocPrefix(psczFullPath, L"\\\\?\\UNC", 7);
296 PathExitOnFailure(hr, "Failed to add prefix to UNC path."); 302 PathExitOnFailure(hr, "Failed to add prefix to UNC path.");
297 }
298 } 303 }
299 else 304 else
300 { 305 {
@@ -814,11 +819,66 @@ LExit:
814} 819}
815 820
816 821
817DAPI_(BOOL) PathIsAbsolute( 822DAPI_(BOOL) PathIsFullyQualified(
823 __in_z LPCWSTR wzPath,
824 __out_opt BOOL* pfHasLongPathPrefix
825 )
826{
827 BOOL fFullyQualified = FALSE;
828 BOOL fHasLongPathPrefix = FALSE;
829
830 if (!wzPath || !wzPath[0] || !wzPath[1])
831 {
832 // There is no way to specify a fully qualified path with one character (or less).
833 ExitFunction();
834 }
835
836 if (L'\\' != wzPath[0])
837 {
838 // The only way to specify a fully qualified path that doesn't begin with a slash
839 // is the drive, colon, slash format (C:\).
840 if (IsValidDriveChar(wzPath[0]) &&
841 L':' == wzPath[1] &&
842 L'\\' == wzPath[2])
843 {
844 fFullyQualified = TRUE;
845 }
846
847 ExitFunction();
848 }
849
850 // Non-drive fully qualified paths must start with \\ or \?.
851 // \??\ is an archaic form of \\?\.
852 if (L'?' != wzPath[1] && L'\\' != wzPath[1])
853 {
854 ExitFunction();
855 }
856
857 fFullyQualified = TRUE;
858
859 if (L'?' == wzPath[2] && L'\\' == wzPath[3])
860 {
861 fHasLongPathPrefix = TRUE;
862 }
863
864
865LExit:
866 if (pfHasLongPathPrefix)
867 {
868 *pfHasLongPathPrefix = fHasLongPathPrefix;
869 }
870
871 return fFullyQualified;
872}
873
874
875DAPI_(BOOL) PathIsRooted(
818 __in_z LPCWSTR wzPath 876 __in_z LPCWSTR wzPath
819 ) 877 )
820{ 878{
821 return wzPath && wzPath[0] && wzPath[1] && (wzPath[0] == L'\\') || (wzPath[1] == L':'); 879 return wzPath &&
880 (wzPath[0] == L'\\' ||
881 IsValidDriveChar(wzPath[0]) && wzPath[1] == L':');
822} 882}
823 883
824 884
@@ -847,7 +907,7 @@ DAPI_(HRESULT) PathConcatCch(
847 hr = StrAllocString(psczCombined, wzPath1, cchPath1); 907 hr = StrAllocString(psczCombined, wzPath1, cchPath1);
848 PathExitOnFailure(hr, "Failed to copy just path1 to output."); 908 PathExitOnFailure(hr, "Failed to copy just path1 to output.");
849 } 909 }
850 else if (!wzPath1 || !*wzPath1 || PathIsAbsolute(wzPath2)) 910 else if (!wzPath1 || !*wzPath1 || PathIsRooted(wzPath2))
851 { 911 {
852 hr = StrAllocString(psczCombined, wzPath2, cchPath2); 912 hr = StrAllocString(psczCombined, wzPath2, cchPath2);
853 PathExitOnFailure(hr, "Failed to copy just path2 to output."); 913 PathExitOnFailure(hr, "Failed to copy just path2 to output.");
@@ -1002,3 +1062,11 @@ LExit:
1002 1062
1003 return hr; 1063 return hr;
1004} 1064}
1065
1066static BOOL IsValidDriveChar(
1067 __in WCHAR wc
1068 )
1069{
1070 return L'a' <= wc && L'z' >= wc ||
1071 L'A' <= wc && L'Z' >= wc;
1072}