diff options
Diffstat (limited to '')
| -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 | } |
