From 8a4d03207633e9fdc364aaed82bd167f844679f9 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Fri, 3 Jun 2022 17:47:31 -0500 Subject: 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. --- src/libs/dutil/WixToolset.DUtil/dirutil.cpp | 55 +++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 14 deletions(-) (limited to 'src/libs/dutil/WixToolset.DUtil/dirutil.cpp') 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 @@ #define DirExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_DIRUTIL, x, s, __VA_ARGS__) #define DirExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_DIRUTIL, x, s, __VA_ARGS__) #define DirExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_DIRUTIL, x, s, __VA_ARGS__) +#define DirExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_DIRUTIL, x, e, s, __VA_ARGS__) #define DirExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_DIRUTIL, x, s, __VA_ARGS__) #define DirExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_DIRUTIL, p, x, e, s, __VA_ARGS__) #define DirExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_DIRUTIL, p, x, s, __VA_ARGS__) @@ -388,32 +389,58 @@ LExit: *******************************************************************/ extern "C" HRESULT DAPI DirGetCurrent( - __deref_out_z LPWSTR* psczCurrentDirectory + __deref_out_z LPWSTR* psczCurrentDirectory, + __out_opt SIZE_T* pcch ) { + Assert(psczCurrentDirectory); + HRESULT hr = S_OK; - SIZE_T cch = 0; + SIZE_T cchMax = 0; + DWORD cch = 0; + DWORD cchBuffer = 0; + DWORD dwAttempts = 0; + const DWORD dwMaxAttempts = 10; - if (psczCurrentDirectory && *psczCurrentDirectory) + if (*psczCurrentDirectory) { - hr = StrMaxLength(*psczCurrentDirectory, &cch); - DirExitOnFailure(hr, "Failed to determine size of current directory."); - } + hr = StrMaxLength(*psczCurrentDirectory, &cchMax); + DirExitOnFailure(hr, "Failed to get max length of input buffer."); - DWORD cchRequired = ::GetCurrentDirectoryW((DWORD)min(DWORD_MAX, cch), 0 == cch ? NULL : *psczCurrentDirectory); - if (0 == cchRequired) + cchBuffer = (DWORD)min(DWORD_MAX, cchMax); + } + else { - DirExitWithLastError(hr, "Failed to get current directory."); + cchBuffer = MAX_PATH + 1; + + hr = StrAlloc(psczCurrentDirectory, cchBuffer); + DirExitOnFailure(hr, "Failed to allocate space for current directory."); } - else if (cch < cchRequired) + + for (; dwAttempts < dwMaxAttempts; ++dwAttempts) { - hr = StrAlloc(psczCurrentDirectory, cchRequired); - DirExitOnFailure(hr, "Failed to allocate string for current directory."); + cch = ::GetCurrentDirectoryW(cchBuffer, *psczCurrentDirectory); + DirExitOnNullWithLastError(cch, hr, "Failed to get current directory."); - if (!::GetCurrentDirectoryW(cchRequired, *psczCurrentDirectory)) + if (cch < cchBuffer) { - DirExitWithLastError(hr, "Failed to get current directory using allocated string."); + break; } + + hr = StrAlloc(psczCurrentDirectory, cch); + DirExitOnFailure(hr, "Failed to reallocate space for current directory."); + + cchBuffer = cch; + } + + if (dwMaxAttempts == dwAttempts) + { + DirExitWithRootFailure(hr, E_INSUFFICIENT_BUFFER, "GetCurrentDirectoryW results never converged."); + } + + if (pcch) + { + *pcch = cch; } LExit: -- cgit v1.2.3-55-g6feb