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/libs/dutil/WixToolset.DUtil/dirutil.cpp | |
| 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/libs/dutil/WixToolset.DUtil/dirutil.cpp')
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/dirutil.cpp | 55 |
1 files changed, 41 insertions, 14 deletions
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: |
