diff options
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/pathutil.cpp')
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/pathutil.cpp | 102 |
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 | ||
23 | static BOOL IsValidDriveChar( | ||
24 | __in WCHAR wc | ||
25 | ); | ||
26 | |||
23 | 27 | ||
24 | DAPI_(LPWSTR) PathFile( | 28 | DAPI_(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 | ||
817 | DAPI_(BOOL) PathIsAbsolute( | 822 | DAPI_(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 | |||
865 | LExit: | ||
866 | if (pfHasLongPathPrefix) | ||
867 | { | ||
868 | *pfHasLongPathPrefix = fHasLongPathPrefix; | ||
869 | } | ||
870 | |||
871 | return fFullyQualified; | ||
872 | } | ||
873 | |||
874 | |||
875 | DAPI_(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 | |||
1066 | static BOOL IsValidDriveChar( | ||
1067 | __in WCHAR wc | ||
1068 | ) | ||
1069 | { | ||
1070 | return L'a' <= wc && L'z' >= wc || | ||
1071 | L'A' <= wc && L'Z' >= wc; | ||
1072 | } | ||