From 648f370f7966b2738c1446601057d888bbd2c70f Mon Sep 17 00:00:00 2001 From: Sean Hall <r.sean.hall@gmail.com> Date: Fri, 3 Jun 2022 17:48:57 -0500 Subject: Make PathGetSystemPath return an array of paths ordered by preference. --- src/libs/dutil/WixToolset.DUtil/guidutil.cpp | 4 +-- src/libs/dutil/WixToolset.DUtil/inc/pathutil.h | 9 ++--- src/libs/dutil/WixToolset.DUtil/pathutil.cpp | 38 +++++++++++++++++----- src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp | 28 ++++++++++++++++ 4 files changed, 64 insertions(+), 15 deletions(-) (limited to 'src/libs/dutil') diff --git a/src/libs/dutil/WixToolset.DUtil/guidutil.cpp b/src/libs/dutil/WixToolset.DUtil/guidutil.cpp index 204c9af2..946c256f 100644 --- a/src/libs/dutil/WixToolset.DUtil/guidutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/guidutil.cpp @@ -9,6 +9,7 @@ #define GuidExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_GUIDUTIL, x, s, __VA_ARGS__) #define GuidExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_GUIDUTIL, x, s, __VA_ARGS__) #define GuidExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_GUIDUTIL, x, s, __VA_ARGS__) +#define GuidExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_GUIDUTIL, x, e, s, __VA_ARGS__) #define GuidExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_GUIDUTIL, x, s, __VA_ARGS__) #define GuidExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_GUIDUTIL, p, x, e, s, __VA_ARGS__) #define GuidExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_GUIDUTIL, p, x, s, __VA_ARGS__) @@ -29,8 +30,7 @@ extern "C" HRESULT DAPI GuidFixedCreate( if (!::StringFromGUID2(guid, wzGuid, GUID_STRING_LENGTH)) { - hr = E_OUTOFMEMORY; - GuidExitOnRootFailure(hr, "Failed to convert guid into string."); + GuidExitWithRootFailure(hr, E_OUTOFMEMORY, "Failed to convert guid into string."); } LExit: diff --git a/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h b/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h index 727318f2..875cfafb 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h @@ -205,11 +205,12 @@ DAPI_(HRESULT) PathGetTempPath( ); /******************************************************************* - PathGetSystemTempPath - returns the path to the system temp folder - that is backslash terminated. + PathGetSystemTempPaths - returns the paths to system temp folders + that are backslash terminated with higher preference first. *******************************************************************/ -DAPI_(HRESULT) PathGetSystemTempPath( - __out_z LPWSTR* psczSystemTempPath +DAPI_(HRESULT) PathGetSystemTempPaths( + __inout_z LPWSTR** prgsczSystemTempPaths, + __inout DWORD* pcSystemTempPaths ); /******************************************************************* diff --git a/src/libs/dutil/WixToolset.DUtil/pathutil.cpp b/src/libs/dutil/WixToolset.DUtil/pathutil.cpp index 1ac76626..dc33e656 100644 --- a/src/libs/dutil/WixToolset.DUtil/pathutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/pathutil.cpp @@ -923,12 +923,14 @@ LExit: } -DAPI_(HRESULT) PathGetSystemTempPath( - __out_z LPWSTR* psczSystemTempPath +DAPI_(HRESULT) PathGetSystemTempPaths( + __inout_z LPWSTR** prgsczSystemTempPaths, + __inout DWORD* pcSystemTempPaths ) { HRESULT hr = S_OK; HKEY hKey = NULL; + LPWSTR sczTemp = NULL; WCHAR wzTempPath[MAX_PATH + 1] = { }; DWORD cch = 0; @@ -940,26 +942,36 @@ DAPI_(HRESULT) PathGetSystemTempPath( // Follow documented precedence rules for TMP/TEMP from ::GetTempPath. // TODO: values will be expanded with the current environment variables instead of the system environment variables. - hr = RegReadString(hKey, L"TMP", psczSystemTempPath); + hr = RegReadString(hKey, L"TMP", &sczTemp); if (E_FILENOTFOUND != hr) { PathExitOnFailure(hr, "Failed to get system TMP value."); - hr = PathBackslashTerminate(psczSystemTempPath); + hr = PathBackslashTerminate(&sczTemp); PathExitOnFailure(hr, "Failed to backslash terminate system TMP value."); - ExitFunction(); + hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczSystemTempPaths), *pcSystemTempPaths, 1, sizeof(LPWSTR), 3); + PathExitOnFailure(hr, "Failed to ensure array size for system TMP value."); + + (*prgsczSystemTempPaths)[*pcSystemTempPaths] = sczTemp; + sczTemp = NULL; + *pcSystemTempPaths += 1; } - hr = RegReadString(hKey, L"TEMP", psczSystemTempPath); + hr = RegReadString(hKey, L"TEMP", &sczTemp); if (E_FILENOTFOUND != hr) { PathExitOnFailure(hr, "Failed to get system TEMP value."); - hr = PathBackslashTerminate(psczSystemTempPath); + hr = PathBackslashTerminate(&sczTemp); PathExitOnFailure(hr, "Failed to backslash terminate system TEMP value."); - ExitFunction(); + hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczSystemTempPaths), *pcSystemTempPaths, 1, sizeof(LPWSTR), 2); + PathExitOnFailure(hr, "Failed to ensure array size for system TEMP value."); + + (*prgsczSystemTempPaths)[*pcSystemTempPaths] = sczTemp; + sczTemp = NULL; + *pcSystemTempPaths += 1; } } @@ -973,11 +985,19 @@ DAPI_(HRESULT) PathGetSystemTempPath( PathExitWithRootFailure(hr, E_INSUFFICIENT_BUFFER, "Windows directory path too long."); } - hr = PathConcat(wzTempPath, L"TEMP\\", psczSystemTempPath); + hr = PathConcat(wzTempPath, L"TEMP\\", &sczTemp); PathExitOnFailure(hr, "Failed to concat Temp directory on Windows directory path."); + hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczSystemTempPaths), *pcSystemTempPaths, 1, sizeof(LPWSTR), 1); + PathExitOnFailure(hr, "Failed to ensure array size for Windows\\TEMP value."); + + (*prgsczSystemTempPaths)[*pcSystemTempPaths] = sczTemp; + sczTemp = NULL; + *pcSystemTempPaths += 1; + LExit: ReleaseRegKey(hKey); + ReleaseStr(sczTemp); return hr; } diff --git a/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp b/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp index d1d304d3..e9ef1047 100644 --- a/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp +++ b/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp @@ -799,6 +799,34 @@ namespace DutilTests } } + [Fact] + void PathGetSystemTempPathsTest() + { + HRESULT hr = S_OK; + LPWSTR* rgsczPaths = NULL; + DWORD cPaths = 0; + DWORD cPathsOriginal = 0; + + try + { + hr = PathGetSystemTempPaths(&rgsczPaths, &cPaths); + NativeAssert::Succeeded(hr, "PathGetSystemTempPaths failed."); + + Assert::InRange<DWORD>(cPaths, 1, 3); + WixAssert::StringEqual(Environment::ExpandEnvironmentVariables("%windir%\\temp\\"), gcnew String(rgsczPaths[cPaths - 1]), true); + + cPathsOriginal = cPaths; + + hr = PathGetSystemTempPaths(&rgsczPaths, &cPaths); + NativeAssert::Succeeded(hr, "PathGetSystemTempPaths failed."); + Assert::Equal(cPathsOriginal * 2, cPaths); + } + finally + { + ReleaseStrArray(rgsczPaths, cPaths); + } + } + [Fact] void PathNormalizeSlashesFixedTest() { -- cgit v1.2.3-55-g6feb