diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2022-06-03 17:47:31 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2022-06-07 19:44:36 -0500 |
commit | 8a4d03207633e9fdc364aaed82bd167f844679f9 (patch) | |
tree | 9ca862bb51fd3507fc5867c292aef236e3411867 /src | |
parent | 5d35ff01e33b8ffdab04a49ddc5927185309391a (diff) | |
download | wix-8a4d03207633e9fdc364aaed82bd167f844679f9.tar.gz wix-8a4d03207633e9fdc364aaed82bd167f844679f9.tar.bz2 wix-8a4d03207633e9fdc364aaed82bd167f844679f9.zip |
Resolve paths while parsing them from the command line.
The current directory is a process wide setting that can potentially be changed by any thread.
Remove fileutil methods that had equivalent pathutil methods.
Diffstat (limited to 'src')
-rw-r--r-- | src/burn/engine/core.cpp | 18 | ||||
-rw-r--r-- | src/burn/engine/logging.cpp | 5 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/cabcutil.cpp | 8 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/cabutil.cpp | 4 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/dirutil.cpp | 55 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/fileutil.cpp | 118 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/dirutil.h | 3 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/fileutil.h | 7 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/pathutil.h | 10 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/logutil.cpp | 15 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/pathutil.cpp | 104 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/sceutil.cpp | 7 | ||||
-rw-r--r-- | src/libs/dutil/test/DUtilUnitTest/DirUtilTests.cpp | 2 | ||||
-rw-r--r-- | src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp | 129 | ||||
-rw-r--r-- | src/wix/WixToolset.Core.Native/WixNativeExe.cs | 1 | ||||
-rw-r--r-- | src/wix/wixnative/smartcab.cpp | 25 |
16 files changed, 301 insertions, 210 deletions
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index 4255fa6b..39836bce 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
@@ -1419,7 +1419,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
1419 | 1419 | ||
1420 | ++i; | 1420 | ++i; |
1421 | 1421 | ||
1422 | hr = StrAllocString(&pInternalCommand->sczLogFile, argv[i], 0); | 1422 | hr = PathExpand(&pInternalCommand->sczLogFile, argv[i], PATH_EXPAND_FULLPATH); |
1423 | ExitOnFailure(hr, "Failed to copy log file path."); | 1423 | ExitOnFailure(hr, "Failed to copy log file path."); |
1424 | } | 1424 | } |
1425 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"?", -1) || | 1425 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"?", -1) || |
@@ -1516,7 +1516,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
1516 | } | 1516 | } |
1517 | 1517 | ||
1518 | ++i; | 1518 | ++i; |
1519 | hr = StrAllocString(&pInternalCommand->sczOriginalSource, argv[i], 0); | 1519 | hr = PathExpand(&pInternalCommand->sczOriginalSource, argv[i], PATH_EXPAND_FULLPATH); |
1520 | ExitOnFailure(hr, "Failed to copy last used source."); | 1520 | ExitOnFailure(hr, "Failed to copy last used source."); |
1521 | } | 1521 | } |
1522 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_PARENT, -1)) | 1522 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_PARENT, -1)) |
@@ -1547,7 +1547,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
1547 | 1547 | ||
1548 | ++i; | 1548 | ++i; |
1549 | 1549 | ||
1550 | hr = StrAllocString(&pInternalCommand->sczLogFile, argv[i], 0); | 1550 | hr = PathExpand(&pInternalCommand->sczLogFile, argv[i], PATH_EXPAND_FULLPATH); |
1551 | ExitOnFailure(hr, "Failed to copy append log file path."); | 1551 | ExitOnFailure(hr, "Failed to copy append log file path."); |
1552 | 1552 | ||
1553 | pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_APPEND; | 1553 | pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_APPEND; |
@@ -1638,7 +1638,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
1638 | } | 1638 | } |
1639 | else if (L'\0' != wzParam[1]) | 1639 | else if (L'\0' != wzParam[1]) |
1640 | { | 1640 | { |
1641 | hr = StrAllocString(&pInternalCommand->sczSourceProcessPath, wzParam + 1, 0); | 1641 | hr = PathExpand(&pInternalCommand->sczSourceProcessPath, wzParam + 1, PATH_EXPAND_FULLPATH); |
1642 | ExitOnFailure(hr, "Failed to copy source process path."); | 1642 | ExitOnFailure(hr, "Failed to copy source process path."); |
1643 | } | 1643 | } |
1644 | } | 1644 | } |
@@ -1807,16 +1807,10 @@ extern "C" HRESULT CoreParseCommandLine( | |||
1807 | fInvalidCommandLine = TRUE; | 1807 | fInvalidCommandLine = TRUE; |
1808 | TraceLog(E_INVALIDARG, "Invalid switch: %ls", argv[i]); | 1808 | TraceLog(E_INVALIDARG, "Invalid switch: %ls", argv[i]); |
1809 | } | 1809 | } |
1810 | else if (L'\0' == wzParam[1]) | ||
1811 | { | ||
1812 | // Need to grab the current directory here since this is passed on to other processes. | ||
1813 | hr = DirGetCurrent(&pInternalCommand->sczEngineWorkingDirectory); | ||
1814 | ExitOnFailure(hr, "Failed to get current directory for custom working directory."); | ||
1815 | } | ||
1816 | else | 1810 | else |
1817 | { | 1811 | { |
1818 | hr = StrAllocString(&pInternalCommand->sczEngineWorkingDirectory, wzParam + 1, 0); | 1812 | hr = PathExpand(&pInternalCommand->sczEngineWorkingDirectory, wzParam + 1, PATH_EXPAND_FULLPATH); |
1819 | ExitOnFailure(hr, "Failed to allocate the custom working directory."); | 1813 | ExitOnFailure(hr, "Failed to store the custom working directory."); |
1820 | } | 1814 | } |
1821 | } | 1815 | } |
1822 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED), BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED, lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED))) | 1816 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED), BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED, lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED))) |
diff --git a/src/burn/engine/logging.cpp b/src/burn/engine/logging.cpp index 8e89957b..3a403025 100644 --- a/src/burn/engine/logging.cpp +++ b/src/burn/engine/logging.cpp | |||
@@ -84,9 +84,6 @@ extern "C" HRESULT LoggingOpen( | |||
84 | { | 84 | { |
85 | DWORD cRetry = 0; | 85 | DWORD cRetry = 0; |
86 | 86 | ||
87 | hr = DirGetCurrent(&sczLoggingBaseFolder); | ||
88 | ExitOnFailure(hr, "Failed to get current directory."); | ||
89 | |||
90 | // Try pretty hard to open the log file when appending. | 87 | // Try pretty hard to open the log file when appending. |
91 | do | 88 | do |
92 | { | 89 | { |
@@ -95,7 +92,7 @@ extern "C" HRESULT LoggingOpen( | |||
95 | ::Sleep(LOG_OPEN_RETRY_WAIT); | 92 | ::Sleep(LOG_OPEN_RETRY_WAIT); |
96 | } | 93 | } |
97 | 94 | ||
98 | hr = LogOpen(sczLoggingBaseFolder, pLog->sczPath, NULL, NULL, pLog->dwAttributes & BURN_LOGGING_ATTRIBUTE_APPEND, FALSE, &pLog->sczPath); | 95 | hr = LogOpen(NULL, pLog->sczPath, NULL, NULL, pLog->dwAttributes & BURN_LOGGING_ATTRIBUTE_APPEND, FALSE, &pLog->sczPath); |
99 | if (pLog->dwAttributes & BURN_LOGGING_ATTRIBUTE_APPEND && HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION) == hr) | 96 | if (pLog->dwAttributes & BURN_LOGGING_ATTRIBUTE_APPEND && HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION) == hr) |
100 | { | 97 | { |
101 | ++cRetry; | 98 | ++cRetry; |
diff --git a/src/libs/dutil/WixToolset.DUtil/cabcutil.cpp b/src/libs/dutil/WixToolset.DUtil/cabcutil.cpp index 9cc45a83..d1edc54d 100644 --- a/src/libs/dutil/WixToolset.DUtil/cabcutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/cabcutil.cpp | |||
@@ -503,7 +503,7 @@ extern "C" HRESULT DAPI CabCFinish( | |||
503 | } | 503 | } |
504 | else | 504 | else |
505 | { | 505 | { |
506 | LPCWSTR pwzTemp = FileFromPath(fileInfo.wzSourcePath); | 506 | LPCWSTR pwzTemp = PathFile(fileInfo.wzSourcePath); |
507 | hr = StrAnsiAllocString(&pszFileToken, pwzTemp, 0, CP_ACP); | 507 | hr = StrAnsiAllocString(&pszFileToken, pwzTemp, 0, CP_ACP); |
508 | CabcExitOnFailure(hr, "failed to convert file name to ANSI: %ls", pwzTemp); | 508 | CabcExitOnFailure(hr, "failed to convert file name to ANSI: %ls", pwzTemp); |
509 | } | 509 | } |
@@ -538,7 +538,7 @@ extern "C" HRESULT DAPI CabCFinish( | |||
538 | } | 538 | } |
539 | else | 539 | else |
540 | { | 540 | { |
541 | LPCWSTR pwzTemp = FileFromPath(fileInfo.wzSourcePath); | 541 | LPCWSTR pwzTemp = PathFile(fileInfo.wzSourcePath); |
542 | hr = StrAnsiAllocString(&pszFileToken, pwzTemp, 0, CP_ACP); | 542 | hr = StrAnsiAllocString(&pszFileToken, pwzTemp, 0, CP_ACP); |
543 | CabcExitOnFailure(hr, "failed to convert duplicate file name to ANSI: %ls", pwzTemp); | 543 | CabcExitOnFailure(hr, "failed to convert duplicate file name to ANSI: %ls", pwzTemp); |
544 | } | 544 | } |
@@ -1386,7 +1386,7 @@ static __callback BOOL DIAMONDAPI CabCGetNextCabinet( | |||
1386 | if (pccab->iCab == 1) | 1386 | if (pccab->iCab == 1) |
1387 | { | 1387 | { |
1388 | pcd->wzFirstCabinetName[0] = '\0'; | 1388 | pcd->wzFirstCabinetName[0] = '\0'; |
1389 | LPCWSTR pwzCabinetName = FileFromPath(pcd->wzCabinetPath); | 1389 | LPCWSTR pwzCabinetName = PathFile(pcd->wzCabinetPath); |
1390 | size_t len = wcsnlen(pwzCabinetName, sizeof(pwzCabinetName)); | 1390 | size_t len = wcsnlen(pwzCabinetName, sizeof(pwzCabinetName)); |
1391 | if (len > 4) | 1391 | if (len > 4) |
1392 | { | 1392 | { |
@@ -1439,7 +1439,7 @@ static __callback BOOL DIAMONDAPI CabCGetNextCabinet( | |||
1439 | else | 1439 | else |
1440 | { | 1440 | { |
1441 | LPCWSTR wzSourcePath = pcd->prgFiles[0].pwzSourcePath; | 1441 | LPCWSTR wzSourcePath = pcd->prgFiles[0].pwzSourcePath; |
1442 | pwzFileToken = FileFromPath(wzSourcePath); | 1442 | pwzFileToken = PathFile(wzSourcePath); |
1443 | } | 1443 | } |
1444 | 1444 | ||
1445 | // The call back to Binder to Add File Transfer for new Cab and add new Cab to Media table | 1445 | // The call back to Binder to Add File Transfer for new Cab and add new Cab to Media table |
diff --git a/src/libs/dutil/WixToolset.DUtil/cabutil.cpp b/src/libs/dutil/WixToolset.DUtil/cabutil.cpp index 5d77e483..f3629d57 100644 --- a/src/libs/dutil/WixToolset.DUtil/cabutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/cabutil.cpp | |||
@@ -106,7 +106,7 @@ static HANDLE OpenFileWithRetry( | |||
106 | __in LPCWSTR wzPath, | 106 | __in LPCWSTR wzPath, |
107 | __in DWORD dwDesiredAccess, | 107 | __in DWORD dwDesiredAccess, |
108 | __in DWORD dwCreationDisposition | 108 | __in DWORD dwCreationDisposition |
109 | ) | 109 | ) |
110 | { | 110 | { |
111 | HANDLE hFile = INVALID_HANDLE_VALUE; | 111 | HANDLE hFile = INVALID_HANDLE_VALUE; |
112 | 112 | ||
@@ -286,7 +286,7 @@ static HRESULT DAPI CabOperation( | |||
286 | // | 286 | // |
287 | // split the cabinet full path into directory and filename and convert to multi-byte (ick!) | 287 | // split the cabinet full path into directory and filename and convert to multi-byte (ick!) |
288 | // | 288 | // |
289 | pwz = FileFromPath(sczCabinet); | 289 | pwz = PathFile(sczCabinet); |
290 | CabExitOnNull(pwz, hr, E_INVALIDARG, "failed to process cabinet path: %ls", wzCabinet); | 290 | CabExitOnNull(pwz, hr, E_INVALIDARG, "failed to process cabinet path: %ls", wzCabinet); |
291 | 291 | ||
292 | if (!::WideCharToMultiByte(CP_UTF8, 0, pwz, -1, szCabFile, countof(szCabFile), NULL, NULL)) | 292 | if (!::WideCharToMultiByte(CP_UTF8, 0, pwz, -1, szCabFile, countof(szCabFile), NULL, NULL)) |
diff --git a/src/libs/dutil/WixToolset.DUtil/dirutil.cpp b/src/libs/dutil/WixToolset.DUtil/dirutil.cpp index ae2c5e1c..c106a467 100644 --- a/src/libs/dutil/WixToolset.DUtil/dirutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/dirutil.cpp | |||
@@ -9,6 +9,7 @@ | |||
9 | #define DirExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_DIRUTIL, x, s, __VA_ARGS__) | 9 | #define DirExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_DIRUTIL, x, s, __VA_ARGS__) |
10 | #define DirExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_DIRUTIL, x, s, __VA_ARGS__) | 10 | #define DirExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_DIRUTIL, x, s, __VA_ARGS__) |
11 | #define DirExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_DIRUTIL, x, s, __VA_ARGS__) | 11 | #define DirExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_DIRUTIL, x, s, __VA_ARGS__) |
12 | #define DirExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_DIRUTIL, x, e, s, __VA_ARGS__) | ||
12 | #define DirExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_DIRUTIL, x, s, __VA_ARGS__) | 13 | #define DirExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_DIRUTIL, x, s, __VA_ARGS__) |
13 | #define DirExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_DIRUTIL, p, x, e, s, __VA_ARGS__) | 14 | #define DirExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_DIRUTIL, p, x, e, s, __VA_ARGS__) |
14 | #define DirExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_DIRUTIL, p, x, s, __VA_ARGS__) | 15 | #define DirExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_DIRUTIL, p, x, s, __VA_ARGS__) |
@@ -388,32 +389,58 @@ LExit: | |||
388 | 389 | ||
389 | *******************************************************************/ | 390 | *******************************************************************/ |
390 | extern "C" HRESULT DAPI DirGetCurrent( | 391 | extern "C" HRESULT DAPI DirGetCurrent( |
391 | __deref_out_z LPWSTR* psczCurrentDirectory | 392 | __deref_out_z LPWSTR* psczCurrentDirectory, |
393 | __out_opt SIZE_T* pcch | ||
392 | ) | 394 | ) |
393 | { | 395 | { |
396 | Assert(psczCurrentDirectory); | ||
397 | |||
394 | HRESULT hr = S_OK; | 398 | HRESULT hr = S_OK; |
395 | SIZE_T cch = 0; | 399 | SIZE_T cchMax = 0; |
400 | DWORD cch = 0; | ||
401 | DWORD cchBuffer = 0; | ||
402 | DWORD dwAttempts = 0; | ||
403 | const DWORD dwMaxAttempts = 10; | ||
396 | 404 | ||
397 | if (psczCurrentDirectory && *psczCurrentDirectory) | 405 | if (*psczCurrentDirectory) |
398 | { | 406 | { |
399 | hr = StrMaxLength(*psczCurrentDirectory, &cch); | 407 | hr = StrMaxLength(*psczCurrentDirectory, &cchMax); |
400 | DirExitOnFailure(hr, "Failed to determine size of current directory."); | 408 | DirExitOnFailure(hr, "Failed to get max length of input buffer."); |
401 | } | ||
402 | 409 | ||
403 | DWORD cchRequired = ::GetCurrentDirectoryW((DWORD)min(DWORD_MAX, cch), 0 == cch ? NULL : *psczCurrentDirectory); | 410 | cchBuffer = (DWORD)min(DWORD_MAX, cchMax); |
404 | if (0 == cchRequired) | 411 | } |
412 | else | ||
405 | { | 413 | { |
406 | DirExitWithLastError(hr, "Failed to get current directory."); | 414 | cchBuffer = MAX_PATH + 1; |
415 | |||
416 | hr = StrAlloc(psczCurrentDirectory, cchBuffer); | ||
417 | DirExitOnFailure(hr, "Failed to allocate space for current directory."); | ||
407 | } | 418 | } |
408 | else if (cch < cchRequired) | 419 | |
420 | for (; dwAttempts < dwMaxAttempts; ++dwAttempts) | ||
409 | { | 421 | { |
410 | hr = StrAlloc(psczCurrentDirectory, cchRequired); | 422 | cch = ::GetCurrentDirectoryW(cchBuffer, *psczCurrentDirectory); |
411 | DirExitOnFailure(hr, "Failed to allocate string for current directory."); | 423 | DirExitOnNullWithLastError(cch, hr, "Failed to get current directory."); |
412 | 424 | ||
413 | if (!::GetCurrentDirectoryW(cchRequired, *psczCurrentDirectory)) | 425 | if (cch < cchBuffer) |
414 | { | 426 | { |
415 | DirExitWithLastError(hr, "Failed to get current directory using allocated string."); | 427 | break; |
416 | } | 428 | } |
429 | |||
430 | hr = StrAlloc(psczCurrentDirectory, cch); | ||
431 | DirExitOnFailure(hr, "Failed to reallocate space for current directory."); | ||
432 | |||
433 | cchBuffer = cch; | ||
434 | } | ||
435 | |||
436 | if (dwMaxAttempts == dwAttempts) | ||
437 | { | ||
438 | DirExitWithRootFailure(hr, E_INSUFFICIENT_BUFFER, "GetCurrentDirectoryW results never converged."); | ||
439 | } | ||
440 | |||
441 | if (pcch) | ||
442 | { | ||
443 | *pcch = cch; | ||
417 | } | 444 | } |
418 | 445 | ||
419 | LExit: | 446 | LExit: |
diff --git a/src/libs/dutil/WixToolset.DUtil/fileutil.cpp b/src/libs/dutil/WixToolset.DUtil/fileutil.cpp index 1822727a..2fe04de1 100644 --- a/src/libs/dutil/WixToolset.DUtil/fileutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/fileutil.cpp | |||
@@ -25,124 +25,6 @@ const BYTE UTF16BOM[] = {0xFF, 0xFE}; | |||
25 | const LPCWSTR REGISTRY_PENDING_FILE_RENAME_KEY = L"SYSTEM\\CurrentControlSet\\Control\\Session Manager"; | 25 | const LPCWSTR REGISTRY_PENDING_FILE_RENAME_KEY = L"SYSTEM\\CurrentControlSet\\Control\\Session Manager"; |
26 | const LPCWSTR REGISTRY_PENDING_FILE_RENAME_VALUE = L"PendingFileRenameOperations"; | 26 | const LPCWSTR REGISTRY_PENDING_FILE_RENAME_VALUE = L"PendingFileRenameOperations"; |
27 | 27 | ||
28 | /******************************************************************* | ||
29 | FileFromPath - returns a pointer to the file part of the path | ||
30 | |||
31 | ********************************************************************/ | ||
32 | extern "C" LPWSTR DAPI FileFromPath( | ||
33 | __in_z LPCWSTR wzPath | ||
34 | ) | ||
35 | { | ||
36 | if (!wzPath) | ||
37 | return NULL; | ||
38 | |||
39 | LPWSTR wzFile = const_cast<LPWSTR>(wzPath); | ||
40 | for (LPWSTR wz = wzFile; *wz; ++wz) | ||
41 | { | ||
42 | // valid delineators | ||
43 | // \ => Windows path | ||
44 | // / => unix and URL path | ||
45 | // : => relative path from mapped root | ||
46 | if (L'\\' == *wz || L'/' == *wz || L':' == *wz) | ||
47 | wzFile = wz + 1; | ||
48 | } | ||
49 | |||
50 | return wzFile; | ||
51 | } | ||
52 | |||
53 | |||
54 | /******************************************************************* | ||
55 | FileResolvePath - gets the full path to a file resolving environment | ||
56 | variables along the way. | ||
57 | |||
58 | ********************************************************************/ | ||
59 | extern "C" HRESULT DAPI FileResolvePath( | ||
60 | __in_z LPCWSTR wzRelativePath, | ||
61 | __out LPWSTR *ppwzFullPath | ||
62 | ) | ||
63 | { | ||
64 | Assert(wzRelativePath && *wzRelativePath); | ||
65 | |||
66 | HRESULT hr = S_OK; | ||
67 | DWORD cch = 0; | ||
68 | LPWSTR pwzExpandedPath = NULL; | ||
69 | DWORD cchExpandedPath = 0; | ||
70 | |||
71 | LPWSTR pwzFullPath = NULL; | ||
72 | DWORD cchFullPath = 0; | ||
73 | |||
74 | LPWSTR wzFileName = NULL; | ||
75 | |||
76 | // | ||
77 | // First, expand any environment variables. | ||
78 | // | ||
79 | cchExpandedPath = MAX_PATH; | ||
80 | hr = StrAlloc(&pwzExpandedPath, cchExpandedPath); | ||
81 | FileExitOnFailure(hr, "Failed to allocate space for expanded path."); | ||
82 | |||
83 | cch = ::ExpandEnvironmentStringsW(wzRelativePath, pwzExpandedPath, cchExpandedPath); | ||
84 | if (0 == cch) | ||
85 | { | ||
86 | FileExitWithLastError(hr, "Failed to expand environment variables in string: %ls", wzRelativePath); | ||
87 | } | ||
88 | else if (cchExpandedPath < cch) | ||
89 | { | ||
90 | cchExpandedPath = cch; | ||
91 | hr = StrAlloc(&pwzExpandedPath, cchExpandedPath); | ||
92 | FileExitOnFailure(hr, "Failed to re-allocate more space for expanded path."); | ||
93 | |||
94 | cch = ::ExpandEnvironmentStringsW(wzRelativePath, pwzExpandedPath, cchExpandedPath); | ||
95 | if (0 == cch) | ||
96 | { | ||
97 | FileExitWithLastError(hr, "Failed to expand environment variables in string: %ls", wzRelativePath); | ||
98 | } | ||
99 | else if (cchExpandedPath < cch) | ||
100 | { | ||
101 | hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); | ||
102 | FileExitOnRootFailure(hr, "Failed to allocate buffer for expanded path."); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | // | ||
107 | // Second, get the full path. | ||
108 | // | ||
109 | cchFullPath = MAX_PATH; | ||
110 | hr = StrAlloc(&pwzFullPath, cchFullPath); | ||
111 | FileExitOnFailure(hr, "Failed to allocate space for full path."); | ||
112 | |||
113 | cch = ::GetFullPathNameW(pwzExpandedPath, cchFullPath, pwzFullPath, &wzFileName); | ||
114 | if (0 == cch) | ||
115 | { | ||
116 | FileExitWithLastError(hr, "Failed to get full path for string: %ls", pwzExpandedPath); | ||
117 | } | ||
118 | else if (cchFullPath < cch) | ||
119 | { | ||
120 | cchFullPath = cch; | ||
121 | hr = StrAlloc(&pwzFullPath, cchFullPath); | ||
122 | FileExitOnFailure(hr, "Failed to re-allocate more space for full path."); | ||
123 | |||
124 | cch = ::GetFullPathNameW(pwzExpandedPath, cchFullPath, pwzFullPath, &wzFileName); | ||
125 | if (0 == cch) | ||
126 | { | ||
127 | FileExitWithLastError(hr, "Failed to get full path for string: %ls", pwzExpandedPath); | ||
128 | } | ||
129 | else if (cchFullPath < cch) | ||
130 | { | ||
131 | hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); | ||
132 | FileExitOnRootFailure(hr, "Failed to allocate buffer for full path."); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | *ppwzFullPath = pwzFullPath; | ||
137 | pwzFullPath = NULL; | ||
138 | |||
139 | LExit: | ||
140 | ReleaseStr(pwzFullPath); | ||
141 | ReleaseStr(pwzExpandedPath); | ||
142 | |||
143 | return hr; | ||
144 | } | ||
145 | |||
146 | 28 | ||
147 | /******************************************************************* | 29 | /******************************************************************* |
148 | FileStripExtension - Strip extension from filename | 30 | FileStripExtension - Strip extension from filename |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/dirutil.h b/src/libs/dutil/WixToolset.DUtil/inc/dirutil.h index 539b3a73..42268a16 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/dirutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/dirutil.h | |||
@@ -46,7 +46,8 @@ DWORD DAPI DirDeleteEmptyDirectoriesToRoot( | |||
46 | ); | 46 | ); |
47 | 47 | ||
48 | HRESULT DAPI DirGetCurrent( | 48 | HRESULT DAPI DirGetCurrent( |
49 | __deref_out_z LPWSTR* psczCurrentDirectory | 49 | __deref_out_z LPWSTR* psczCurrentDirectory, |
50 | __out_opt SIZE_T* pcch | ||
50 | ); | 51 | ); |
51 | 52 | ||
52 | HRESULT DAPI DirSetCurrent( | 53 | HRESULT DAPI DirSetCurrent( |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/fileutil.h b/src/libs/dutil/WixToolset.DUtil/inc/fileutil.h index d3e326f7..868312dc 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/fileutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/fileutil.h | |||
@@ -34,13 +34,6 @@ typedef enum FILE_ENCODING | |||
34 | } FILE_ENCODING; | 34 | } FILE_ENCODING; |
35 | 35 | ||
36 | 36 | ||
37 | LPWSTR DAPI FileFromPath( | ||
38 | __in_z LPCWSTR wzPath | ||
39 | ); | ||
40 | HRESULT DAPI FileResolvePath( | ||
41 | __in_z LPCWSTR wzRelativePath, | ||
42 | __out LPWSTR *ppwzFullPath | ||
43 | ); | ||
44 | HRESULT DAPI FileStripExtension( | 37 | HRESULT DAPI FileStripExtension( |
45 | __in_z LPCWSTR wzFileName, | 38 | __in_z LPCWSTR wzFileName, |
46 | __out LPWSTR *ppwzFileNameNoExtension | 39 | __out LPWSTR *ppwzFileNameNoExtension |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h b/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h index 941793f8..871e706b 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h | |||
@@ -68,6 +68,16 @@ DAPI_(HRESULT) PathExpand( | |||
68 | ); | 68 | ); |
69 | 69 | ||
70 | /******************************************************************* | 70 | /******************************************************************* |
71 | PathGetFullPathName - wrapper around GetFullPathNameW. | ||
72 | *******************************************************************/ | ||
73 | DAPI_(HRESULT) PathGetFullPathName( | ||
74 | __in_z LPCWSTR wzPath, | ||
75 | __deref_out_z LPWSTR* psczFullPath, | ||
76 | __inout_z_opt LPCWSTR* pwzFileName, | ||
77 | __out_opt SIZE_T* pcch | ||
78 | ); | ||
79 | |||
80 | /******************************************************************* | ||
71 | PathPrefix - prefixes a full path with \\?\ or \\?\UNC as | 81 | PathPrefix - prefixes a full path with \\?\ or \\?\UNC as |
72 | appropriate. | 82 | appropriate. |
73 | ********************************************************************/ | 83 | ********************************************************************/ |
diff --git a/src/libs/dutil/WixToolset.DUtil/logutil.cpp b/src/libs/dutil/WixToolset.DUtil/logutil.cpp index bd21098c..94c21374 100644 --- a/src/libs/dutil/WixToolset.DUtil/logutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/logutil.cpp | |||
@@ -117,6 +117,7 @@ extern "C" HRESULT DAPI LogOpen( | |||
117 | { | 117 | { |
118 | HRESULT hr = S_OK; | 118 | HRESULT hr = S_OK; |
119 | BOOL fEnteredCriticalSection = FALSE; | 119 | BOOL fEnteredCriticalSection = FALSE; |
120 | LPWSTR sczCombined = NULL; | ||
120 | LPWSTR sczLogDirectory = NULL; | 121 | LPWSTR sczLogDirectory = NULL; |
121 | 122 | ||
122 | ::EnterCriticalSection(&LogUtil_csLog); | 123 | ::EnterCriticalSection(&LogUtil_csLog); |
@@ -129,9 +130,20 @@ extern "C" HRESULT DAPI LogOpen( | |||
129 | } | 130 | } |
130 | else | 131 | else |
131 | { | 132 | { |
132 | hr = PathConcat(wzDirectory, wzLog, &LogUtil_sczLogPath); | 133 | hr = PathConcat(wzDirectory, wzLog, &sczCombined); |
133 | LoguExitOnFailure(hr, "Failed to combine the log path."); | 134 | LoguExitOnFailure(hr, "Failed to combine the log path."); |
134 | 135 | ||
136 | if (!PathIsFullyQualified(sczCombined, NULL)) | ||
137 | { | ||
138 | hr = PathExpand(&LogUtil_sczLogPath, sczCombined, PATH_EXPAND_FULLPATH); | ||
139 | LoguExitOnFailure(hr, "Failed to expand the log path."); | ||
140 | } | ||
141 | else | ||
142 | { | ||
143 | LogUtil_sczLogPath = sczCombined; | ||
144 | sczCombined = NULL; | ||
145 | } | ||
146 | |||
135 | hr = PathGetDirectory(LogUtil_sczLogPath, &sczLogDirectory); | 147 | hr = PathGetDirectory(LogUtil_sczLogPath, &sczLogDirectory); |
136 | LoguExitOnFailure(hr, "Failed to get log directory."); | 148 | LoguExitOnFailure(hr, "Failed to get log directory."); |
137 | 149 | ||
@@ -176,6 +188,7 @@ LExit: | |||
176 | ::LeaveCriticalSection(&LogUtil_csLog); | 188 | ::LeaveCriticalSection(&LogUtil_csLog); |
177 | } | 189 | } |
178 | 190 | ||
191 | ReleaseStr(sczCombined); | ||
179 | ReleaseStr(sczLogDirectory); | 192 | ReleaseStr(sczLogDirectory); |
180 | 193 | ||
181 | return hr; | 194 | return hr; |
diff --git a/src/libs/dutil/WixToolset.DUtil/pathutil.cpp b/src/libs/dutil/WixToolset.DUtil/pathutil.cpp index 99be003c..a9a19b9f 100644 --- a/src/libs/dutil/WixToolset.DUtil/pathutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/pathutil.cpp | |||
@@ -157,11 +157,12 @@ DAPI_(HRESULT) PathExpand( | |||
157 | __in DWORD dwResolveFlags | 157 | __in DWORD dwResolveFlags |
158 | ) | 158 | ) |
159 | { | 159 | { |
160 | Assert(wzRelativePath && *wzRelativePath); | 160 | Assert(wzRelativePath); |
161 | 161 | ||
162 | HRESULT hr = S_OK; | 162 | HRESULT hr = S_OK; |
163 | DWORD cch = 0; | 163 | DWORD cch = 0; |
164 | LPWSTR sczExpandedPath = NULL; | 164 | LPWSTR sczExpandedPath = NULL; |
165 | SIZE_T cchWritten = 0; | ||
165 | DWORD cchExpandedPath = 0; | 166 | DWORD cchExpandedPath = 0; |
166 | SIZE_T cbSize = 0; | 167 | SIZE_T cbSize = 0; |
167 | 168 | ||
@@ -221,37 +222,12 @@ DAPI_(HRESULT) PathExpand( | |||
221 | // | 222 | // |
222 | if (dwResolveFlags & PATH_EXPAND_FULLPATH) | 223 | if (dwResolveFlags & PATH_EXPAND_FULLPATH) |
223 | { | 224 | { |
224 | LPWSTR wzFileName = NULL; | ||
225 | LPCWSTR wzPath = sczExpandedPath ? sczExpandedPath : wzRelativePath; | 225 | LPCWSTR wzPath = sczExpandedPath ? sczExpandedPath : wzRelativePath; |
226 | DWORD cchFullPath = max(PATH_GOOD_ENOUGH, cchExpandedPath); | ||
227 | 226 | ||
228 | hr = StrAlloc(&sczFullPath, cchFullPath); | 227 | hr = PathGetFullPathName(wzPath, &sczFullPath, NULL, &cchWritten); |
229 | PathExitOnFailure(hr, "Failed to allocate space for full path."); | 228 | PathExitOnFailure(hr, "Failed to get full path for string: %ls", wzPath); |
230 | |||
231 | cch = ::GetFullPathNameW(wzPath, cchFullPath, sczFullPath, &wzFileName); | ||
232 | if (0 == cch) | ||
233 | { | ||
234 | PathExitWithLastError(hr, "Failed to get full path for string: %ls", wzPath); | ||
235 | } | ||
236 | else if (cchFullPath < cch) | ||
237 | { | ||
238 | cchFullPath = cch < MAX_PATH ? cch : cch + 7; // ensure space for "\\?\UNC" prefix if needed | ||
239 | hr = StrAlloc(&sczFullPath, cchFullPath); | ||
240 | PathExitOnFailure(hr, "Failed to re-allocate more space for full path."); | ||
241 | 229 | ||
242 | cch = ::GetFullPathNameW(wzPath, cchFullPath, sczFullPath, &wzFileName); | 230 | if (MAX_PATH < cchWritten) |
243 | if (0 == cch) | ||
244 | { | ||
245 | PathExitWithLastError(hr, "Failed to get full path for string: %ls", wzPath); | ||
246 | } | ||
247 | else if (cchFullPath < cch) | ||
248 | { | ||
249 | hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); | ||
250 | PathExitOnRootFailure(hr, "Failed to allocate buffer for full path."); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | if (MAX_PATH < cch) | ||
255 | { | 231 | { |
256 | hr = PathPrefix(&sczFullPath); | 232 | hr = PathPrefix(&sczFullPath); |
257 | PathExitOnFailure(hr, "Failed to prefix long path after expanding."); | 233 | PathExitOnFailure(hr, "Failed to prefix long path after expanding."); |
@@ -263,7 +239,7 @@ DAPI_(HRESULT) PathExpand( | |||
263 | sczExpandedPath = NULL; | 239 | sczExpandedPath = NULL; |
264 | } | 240 | } |
265 | 241 | ||
266 | hr = StrAllocString(psczFullPath, sczFullPath? sczFullPath : wzRelativePath, 0); | 242 | hr = StrAllocString(psczFullPath, sczFullPath ? sczFullPath : wzRelativePath, 0); |
267 | PathExitOnFailure(hr, "Failed to copy relative path into full path."); | 243 | PathExitOnFailure(hr, "Failed to copy relative path into full path."); |
268 | 244 | ||
269 | LExit: | 245 | LExit: |
@@ -274,6 +250,74 @@ LExit: | |||
274 | } | 250 | } |
275 | 251 | ||
276 | 252 | ||
253 | DAPI_(HRESULT) PathGetFullPathName( | ||
254 | __in_z LPCWSTR wzPath, | ||
255 | __deref_out_z LPWSTR* psczFullPath, | ||
256 | __inout_z_opt LPCWSTR* pwzFileName, | ||
257 | __out_opt SIZE_T* pcch | ||
258 | ) | ||
259 | { | ||
260 | HRESULT hr = S_OK; | ||
261 | SIZE_T cchMax = 0; | ||
262 | DWORD cchBuffer = 0; | ||
263 | DWORD cch = 0; | ||
264 | DWORD dwAttempts = 0; | ||
265 | const DWORD dwMaxAttempts = 10; | ||
266 | |||
267 | if (!wzPath || !*wzPath) | ||
268 | { | ||
269 | hr = DirGetCurrent(psczFullPath, pcch); | ||
270 | PathExitOnFailure(hr, "Failed to get current directory."); | ||
271 | |||
272 | ExitFunction(); | ||
273 | } | ||
274 | |||
275 | if (*psczFullPath) | ||
276 | { | ||
277 | hr = StrMaxLength(*psczFullPath, &cchMax); | ||
278 | PathExitOnFailure(hr, "Failed to get max length of input buffer."); | ||
279 | |||
280 | cchBuffer = (DWORD)min(DWORD_MAX, cchMax); | ||
281 | } | ||
282 | else | ||
283 | { | ||
284 | cchBuffer = MAX_PATH + 1; | ||
285 | |||
286 | hr = StrAlloc(psczFullPath, cchBuffer); | ||
287 | PathExitOnFailure(hr, "Failed to allocate space for full path."); | ||
288 | } | ||
289 | |||
290 | for (; dwAttempts < dwMaxAttempts; ++dwAttempts) | ||
291 | { | ||
292 | cch = ::GetFullPathNameW(wzPath, cchBuffer, *psczFullPath, const_cast<LPWSTR*>(pwzFileName)); | ||
293 | PathExitOnNullWithLastError(cch, hr, "Failed to get full path for string: %ls", wzPath); | ||
294 | |||
295 | if (cch < cchBuffer) | ||
296 | { | ||
297 | break; | ||
298 | } | ||
299 | |||
300 | hr = StrAlloc(psczFullPath, cch); | ||
301 | PathExitOnFailure(hr, "Failed to reallocate space for full path."); | ||
302 | |||
303 | cchBuffer = cch; | ||
304 | } | ||
305 | |||
306 | if (dwMaxAttempts == dwAttempts) | ||
307 | { | ||
308 | PathExitWithRootFailure(hr, E_INSUFFICIENT_BUFFER, "GetFullPathNameW results never converged."); | ||
309 | } | ||
310 | |||
311 | if (pcch) | ||
312 | { | ||
313 | *pcch = cch; | ||
314 | } | ||
315 | |||
316 | LExit: | ||
317 | return hr; | ||
318 | } | ||
319 | |||
320 | |||
277 | DAPI_(HRESULT) PathPrefix( | 321 | DAPI_(HRESULT) PathPrefix( |
278 | __inout LPWSTR *psczFullPath | 322 | __inout LPWSTR *psczFullPath |
279 | ) | 323 | ) |
diff --git a/src/libs/dutil/WixToolset.DUtil/sceutil.cpp b/src/libs/dutil/WixToolset.DUtil/sceutil.cpp index cdb1623b..4eede74f 100644 --- a/src/libs/dutil/WixToolset.DUtil/sceutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/sceutil.cpp | |||
@@ -1491,11 +1491,8 @@ static HRESULT CreateSqlCe( | |||
1491 | // If that failed, fallback to loading from current path | 1491 | // If that failed, fallback to loading from current path |
1492 | if (NULL == *phSqlCeDll) | 1492 | if (NULL == *phSqlCeDll) |
1493 | { | 1493 | { |
1494 | hr = DirGetCurrent(&sczDirectory); | 1494 | hr = PathGetFullPathName(wzSqlCeDllPath, &sczDllFullPath, NULL, NULL); |
1495 | ExitOnFailure(hr, "Failed to get current directory"); | 1495 | ExitOnFailure(hr, "Failed to get full path for DLL"); |
1496 | |||
1497 | hr = PathConcat(sczDirectory, wzSqlCeDllPath, &sczDllFullPath); | ||
1498 | ExitOnFailure(hr, "Failed to concatenate current directory and DLL filename"); | ||
1499 | 1496 | ||
1500 | *phSqlCeDll = ::LoadLibraryW(sczDllFullPath); | 1497 | *phSqlCeDll = ::LoadLibraryW(sczDllFullPath); |
1501 | ExitOnNullWithLastError(*phSqlCeDll, hr, "Failed to open Sql CE DLL: %ls", sczDllFullPath); | 1498 | ExitOnNullWithLastError(*phSqlCeDll, hr, "Failed to open Sql CE DLL: %ls", sczDllFullPath); |
diff --git a/src/libs/dutil/test/DUtilUnitTest/DirUtilTests.cpp b/src/libs/dutil/test/DUtilUnitTest/DirUtilTests.cpp index 7643366f..14ed7807 100644 --- a/src/libs/dutil/test/DUtilUnitTest/DirUtilTests.cpp +++ b/src/libs/dutil/test/DUtilUnitTest/DirUtilTests.cpp | |||
@@ -25,7 +25,7 @@ namespace DutilTests | |||
25 | hr = GuidCreate(&sczGuid); | 25 | hr = GuidCreate(&sczGuid); |
26 | NativeAssert::Succeeded(hr, "Failed to create guid."); | 26 | NativeAssert::Succeeded(hr, "Failed to create guid."); |
27 | 27 | ||
28 | hr = DirGetCurrent(&sczCurrentDir); | 28 | hr = DirGetCurrent(&sczCurrentDir, NULL); |
29 | NativeAssert::Succeeded(hr, "Failed to get current directory."); | 29 | NativeAssert::Succeeded(hr, "Failed to get current directory."); |
30 | 30 | ||
31 | hr = PathConcat(sczCurrentDir, sczGuid, &sczFolder); | 31 | hr = PathConcat(sczCurrentDir, sczGuid, &sczFolder); |
diff --git a/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp b/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp index 52698b98..554c6f00 100644 --- a/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp +++ b/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp | |||
@@ -3,6 +3,7 @@ | |||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | 4 | ||
5 | using namespace System; | 5 | using namespace System; |
6 | using namespace System::IO; | ||
6 | using namespace Xunit; | 7 | using namespace Xunit; |
7 | using namespace WixBuildTools::TestSupport; | 8 | using namespace WixBuildTools::TestSupport; |
8 | 9 | ||
@@ -403,6 +404,70 @@ namespace DutilTests | |||
403 | } | 404 | } |
404 | 405 | ||
405 | [Fact] | 406 | [Fact] |
407 | void PathExpandEnvironmentVariablesTest() | ||
408 | { | ||
409 | HRESULT hr = S_OK; | ||
410 | LPWSTR sczExpanded = NULL; | ||
411 | LPCWSTR rgwzPaths[4] = | ||
412 | { | ||
413 | L"", L"", | ||
414 | L"\\\\?\\", L"%TEMP%;%PATH%;C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", | ||
415 | }; | ||
416 | |||
417 | try | ||
418 | { | ||
419 | for (DWORD i = 0; i < countof(rgwzPaths); i += 2) | ||
420 | { | ||
421 | hr = PathExpand(&sczExpanded, rgwzPaths[i + 1], PATH_EXPAND_ENVIRONMENT); | ||
422 | NativeAssert::Succeeded(hr, "PathExpand: {0}", rgwzPaths[i + 1]); | ||
423 | WixAssert::StringEqual((gcnew String(rgwzPaths[i])) + Environment::ExpandEnvironmentVariables(gcnew String(rgwzPaths[i + 1])), gcnew String(sczExpanded), false); | ||
424 | } | ||
425 | } | ||
426 | finally | ||
427 | { | ||
428 | ReleaseStr(sczExpanded); | ||
429 | } | ||
430 | } | ||
431 | |||
432 | [Fact] | ||
433 | void PathExpandFullPathTest() | ||
434 | { | ||
435 | HRESULT hr = S_OK; | ||
436 | LPWSTR sczExpanded = NULL; | ||
437 | LPCWSTR wzGreaterThanMaxPathString = L"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\\a.txt"; | ||
438 | |||
439 | try | ||
440 | { | ||
441 | hr = PathExpand(&sczExpanded, wzGreaterThanMaxPathString, PATH_EXPAND_FULLPATH); | ||
442 | NativeAssert::Succeeded(hr, "Failed to expand greater than MAX_PATH string."); | ||
443 | WixAssert::StringEqual((gcnew String("\\\\?\\")) + Path::Combine(Environment::CurrentDirectory, gcnew String(wzGreaterThanMaxPathString)), gcnew String(sczExpanded), false); | ||
444 | } | ||
445 | finally | ||
446 | { | ||
447 | ReleaseStr(sczExpanded); | ||
448 | } | ||
449 | } | ||
450 | |||
451 | [Fact] | ||
452 | void PathExpandAllTest() | ||
453 | { | ||
454 | HRESULT hr = S_OK; | ||
455 | LPWSTR sczExpanded = NULL; | ||
456 | LPCWSTR wzRelativeEnvironmentVariableString = L"%USERNAME%\\abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\\a.txt"; | ||
457 | |||
458 | try | ||
459 | { | ||
460 | hr = PathExpand(&sczExpanded, wzRelativeEnvironmentVariableString, PATH_EXPAND_ENVIRONMENT | PATH_EXPAND_FULLPATH); | ||
461 | NativeAssert::Succeeded(hr, "Failed to expand path."); | ||
462 | WixAssert::StringEqual((gcnew String("\\\\?\\")) + Path::Combine(Environment::CurrentDirectory, Environment::ExpandEnvironmentVariables(gcnew String(wzRelativeEnvironmentVariableString))), gcnew String(sczExpanded), false); | ||
463 | } | ||
464 | finally | ||
465 | { | ||
466 | ReleaseStr(sczExpanded); | ||
467 | } | ||
468 | } | ||
469 | |||
470 | [Fact] | ||
406 | void PathGetDirectoryTest() | 471 | void PathGetDirectoryTest() |
407 | { | 472 | { |
408 | HRESULT hr = S_OK; | 473 | HRESULT hr = S_OK; |
@@ -436,6 +501,70 @@ namespace DutilTests | |||
436 | } | 501 | } |
437 | 502 | ||
438 | [Fact] | 503 | [Fact] |
504 | void PathGetFullPathNameTest() | ||
505 | { | ||
506 | HRESULT hr = S_OK; | ||
507 | LPWSTR sczPath = NULL; | ||
508 | LPCWSTR wzFileName = NULL; | ||
509 | LPCWSTR rgwzPaths[33] = | ||
510 | { | ||
511 | L"C:\\", L"C:\\", NULL, | ||
512 | L"C:\\file", L"C:\\file", L"file", | ||
513 | L"C:\\..\\file", L"C:\\file", L"file", | ||
514 | L"C:\\dir\\..\\file.txt", L"C:\\file.txt", L"file.txt", | ||
515 | L"C:\\dir\\\\file.txt.txt", L"C:\\dir\\file.txt.txt", L"file.txt.txt", | ||
516 | L"C:\\dir/.file", L"C:\\dir\\.file", L".file", | ||
517 | L"\\\\?\\C:\\file", L"\\\\?\\C:\\file", L"file", | ||
518 | L"\\\\server\\share\\file", L"\\\\server\\share\\file", L"file", | ||
519 | L"\\\\server\\share\\..\\file", L"\\\\server\\share\\file", L"file", | ||
520 | L"\\\\?\\UNC\\server\\share\\file", L"\\\\?\\UNC\\server\\share\\file", L"file", | ||
521 | L"C:\\abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\\a.txt", L"C:\\abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\\a.txt", L"a.txt", | ||
522 | }; | ||
523 | |||
524 | try | ||
525 | { | ||
526 | for (DWORD i = 0; i < countof(rgwzPaths); i += 3) | ||
527 | { | ||
528 | hr = PathGetFullPathName(rgwzPaths[i], &sczPath, &wzFileName, NULL); | ||
529 | NativeAssert::Succeeded(hr, "PathGetFullPathName: {0}", rgwzPaths[i]); | ||
530 | NativeAssert::StringEqual(rgwzPaths[i + 1], sczPath); | ||
531 | NativeAssert::StringEqual(rgwzPaths[i + 2], wzFileName); | ||
532 | } | ||
533 | } | ||
534 | finally | ||
535 | { | ||
536 | ReleaseStr(sczPath); | ||
537 | } | ||
538 | } | ||
539 | |||
540 | [Fact] | ||
541 | void PathGetFullPathNameRelativeTest() | ||
542 | { | ||
543 | HRESULT hr = S_OK; | ||
544 | LPWSTR sczPath = NULL; | ||
545 | LPCWSTR rgwzPaths[4] = | ||
546 | { | ||
547 | L"", | ||
548 | L"a.txt", | ||
549 | L"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\\a.txt", | ||
550 | }; | ||
551 | |||
552 | try | ||
553 | { | ||
554 | for (DWORD i = 0; i < countof(rgwzPaths); ++i) | ||
555 | { | ||
556 | hr = PathGetFullPathName(rgwzPaths[i], &sczPath, NULL, NULL); | ||
557 | NativeAssert::Succeeded(hr, "PathGetFullPathName: {0}", rgwzPaths[i]); | ||
558 | WixAssert::StringEqual(Path::Combine(Environment::CurrentDirectory, gcnew String(rgwzPaths[i])), gcnew String(sczPath), false); | ||
559 | } | ||
560 | } | ||
561 | finally | ||
562 | { | ||
563 | ReleaseStr(sczPath); | ||
564 | } | ||
565 | } | ||
566 | |||
567 | [Fact] | ||
439 | void PathGetHierarchyArrayTest() | 568 | void PathGetHierarchyArrayTest() |
440 | { | 569 | { |
441 | HRESULT hr = S_OK; | 570 | HRESULT hr = S_OK; |
diff --git a/src/wix/WixToolset.Core.Native/WixNativeExe.cs b/src/wix/WixToolset.Core.Native/WixNativeExe.cs index f5ff8bf0..90439c5d 100644 --- a/src/wix/WixToolset.Core.Native/WixNativeExe.cs +++ b/src/wix/WixToolset.Core.Native/WixNativeExe.cs | |||
@@ -36,6 +36,7 @@ namespace WixToolset.Core.Native | |||
36 | 36 | ||
37 | var wixNativeInfo = new ProcessStartInfo(PathToWixNativeExe, this.commandLine) | 37 | var wixNativeInfo = new ProcessStartInfo(PathToWixNativeExe, this.commandLine) |
38 | { | 38 | { |
39 | WorkingDirectory = Environment.CurrentDirectory, | ||
39 | RedirectStandardInput = true, | 40 | RedirectStandardInput = true, |
40 | RedirectStandardOutput = true, | 41 | RedirectStandardOutput = true, |
41 | RedirectStandardError = true, | 42 | RedirectStandardError = true, |
diff --git a/src/wix/wixnative/smartcab.cpp b/src/wix/wixnative/smartcab.cpp index dedcbc2d..b5f20736 100644 --- a/src/wix/wixnative/smartcab.cpp +++ b/src/wix/wixnative/smartcab.cpp | |||
@@ -9,10 +9,10 @@ static void __stdcall CabNamesCallback(__in_z LPWSTR wzFirstCabName, __in_z LPWS | |||
9 | HRESULT SmartCabCommand( | 9 | HRESULT SmartCabCommand( |
10 | __in int argc, | 10 | __in int argc, |
11 | __in_ecount(argc) LPWSTR argv[] | 11 | __in_ecount(argc) LPWSTR argv[] |
12 | ) | 12 | ) |
13 | { | 13 | { |
14 | HRESULT hr = E_INVALIDARG; | 14 | HRESULT hr = E_INVALIDARG; |
15 | LPCWSTR wzCabPath = NULL; | 15 | LPWSTR sczCabPath = NULL; |
16 | LPCWSTR wzCabName = NULL; | 16 | LPCWSTR wzCabName = NULL; |
17 | LPWSTR sczCabDir = NULL; | 17 | LPWSTR sczCabDir = NULL; |
18 | UINT uiFileCount = 0; | 18 | UINT uiFileCount = 0; |
@@ -27,11 +27,13 @@ HRESULT SmartCabCommand( | |||
27 | } | 27 | } |
28 | else | 28 | else |
29 | { | 29 | { |
30 | wzCabPath = argv[0]; | 30 | hr = PathExpand(&sczCabPath, argv[0], PATH_EXPAND_FULLPATH); |
31 | wzCabName = PathFile(wzCabPath); | 31 | ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Could not expand path: %ls", argv[0]); |
32 | 32 | ||
33 | hr = PathGetDirectory(wzCabPath, &sczCabDir); | 33 | wzCabName = PathFile(sczCabPath); |
34 | ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Could not parse directory from path: %ls", wzCabPath); | 34 | |
35 | hr = PathGetDirectory(sczCabPath, &sczCabDir); | ||
36 | ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Could not parse directory from path: %ls", sczCabPath); | ||
35 | 37 | ||
36 | if (argc > 1) | 38 | if (argc > 1) |
37 | { | 39 | { |
@@ -62,7 +64,7 @@ HRESULT SmartCabCommand( | |||
62 | } | 64 | } |
63 | 65 | ||
64 | hr = CabCBegin(wzCabName, sczCabDir, uiFileCount, uiMaxSize, uiMaxThresh, ct, &hCab); | 66 | hr = CabCBegin(wzCabName, sczCabDir, uiFileCount, uiMaxSize, uiMaxThresh, ct, &hCab); |
65 | ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "failed to initialize cabinet: %ls", wzCabPath); | 67 | ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "failed to initialize cabinet: %ls", sczCabPath); |
66 | 68 | ||
67 | if (uiFileCount > 0) | 69 | if (uiFileCount > 0) |
68 | { | 70 | { |
@@ -70,12 +72,12 @@ HRESULT SmartCabCommand( | |||
70 | ExitOnFailure(hr, "failed to read stdin preamble before smartcabbing"); | 72 | ExitOnFailure(hr, "failed to read stdin preamble before smartcabbing"); |
71 | 73 | ||
72 | hr = CompressFiles(hCab); | 74 | hr = CompressFiles(hCab); |
73 | ExitOnFailure(hr, "failed to compress files into cabinet: %ls", wzCabPath); | 75 | ExitOnFailure(hr, "failed to compress files into cabinet: %ls", sczCabPath); |
74 | } | 76 | } |
75 | 77 | ||
76 | hr = CabCFinish(hCab, CabNamesCallback); | 78 | hr = CabCFinish(hCab, CabNamesCallback); |
77 | hCab = NULL; // once finish is called, the handle is invalid. | 79 | hCab = NULL; // once finish is called, the handle is invalid. |
78 | ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "failed to compress cabinet: %ls", wzCabPath); | 80 | ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "failed to compress cabinet: %ls", sczCabPath); |
79 | 81 | ||
80 | 82 | ||
81 | LExit: | 83 | LExit: |
@@ -84,6 +86,7 @@ LExit: | |||
84 | CabCCancel(hCab); | 86 | CabCCancel(hCab); |
85 | } | 87 | } |
86 | ReleaseStr(sczCabDir); | 88 | ReleaseStr(sczCabDir); |
89 | ReleaseStr(sczCabPath); | ||
87 | 90 | ||
88 | return hr; | 91 | return hr; |
89 | } | 92 | } |
@@ -91,7 +94,7 @@ LExit: | |||
91 | 94 | ||
92 | static HRESULT CompressFiles( | 95 | static HRESULT CompressFiles( |
93 | __in HANDLE hCab | 96 | __in HANDLE hCab |
94 | ) | 97 | ) |
95 | { | 98 | { |
96 | HRESULT hr = S_OK; | 99 | HRESULT hr = S_OK; |
97 | LPWSTR sczLine = NULL; | 100 | LPWSTR sczLine = NULL; |
@@ -157,7 +160,7 @@ static void __stdcall CabNamesCallback( | |||
157 | __in_z LPWSTR wzFirstCabName, | 160 | __in_z LPWSTR wzFirstCabName, |
158 | __in_z LPWSTR wzNewCabName, | 161 | __in_z LPWSTR wzNewCabName, |
159 | __in_z LPWSTR wzFileToken | 162 | __in_z LPWSTR wzFileToken |
160 | ) | 163 | ) |
161 | { | 164 | { |
162 | ConsoleWriteLine(CONSOLE_COLOR_NORMAL, "%ls\t%ls\t%ls", wzFirstCabName, wzNewCabName, wzFileToken); | 165 | ConsoleWriteLine(CONSOLE_COLOR_NORMAL, "%ls\t%ls\t%ls", wzFirstCabName, wzNewCabName, wzFileToken); |
163 | } | 166 | } |