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 | } | ||
