@joebigelow / wix-1 / commits / ed57d171

Get system TEMP path from the registry.

Also, correctly handle return codes from related path APIs.

Sean Hall committed Aug 3, 2021 at 15:41 UTC ed57d171f6fb6bb4e180696cc12caa568599566a
4 files changed +112 -15
src/burn/engine/cache.cpp
+9 -14
@@ -1281,7 +1281,7 @@ static HRESULT CalculateWorkingFolder(
1281 HRESULT hr = S_OK;
1282 RPC_STATUS rs = RPC_S_OK;
1283 BOOL fElevated = FALSE;
1284 - WCHAR wzTempPath[MAX_PATH] = { };
1284 + LPWSTR sczTempPath = NULL;
1285 UUID guid = {};
1286 WCHAR wzGuid[39];
1287
@@ -1291,20 +1291,13 @@ static HRESULT CalculateWorkingFolder(
1291
1292 if (fElevated)
1293 {
1294 - if (!::GetWindowsDirectoryW(wzTempPath, countof(wzTempPath)))
1295 - {
1296 - ExitWithLastError(hr, "Failed to get windows path for working folder.");
1297 - }
1298 -
1299 - hr = PathFixedBackslashTerminate(wzTempPath, countof(wzTempPath));
1300 - ExitOnFailure(hr, "Failed to ensure windows path for working folder ended in backslash.");
1301 -
1302 - hr = ::StringCchCatW(wzTempPath, countof(wzTempPath), L"Temp\\");
1303 - ExitOnFailure(hr, "Failed to concat Temp directory on windows path for working folder.");
1294 + hr = PathGetSystemTempPath(&sczTempPath);
1295 + ExitOnFailure(hr, "Failed to get system temp folder path for working folder.");
1296 }
1305 - else if (0 == ::GetTempPathW(countof(wzTempPath), wzTempPath))
1297 + else
1298 {
1307 - ExitWithLastError(hr, "Failed to get temp path for working folder.");
1299 + hr = PathGetTempPath(&sczTempPath);
1300 + ExitOnFailure(hr, "Failed to get temp folder path for working folder.");
1301 }
1302
1303 rs = ::UuidCreate(&guid);
@@ -1317,7 +1310,7 @@ static HRESULT CalculateWorkingFolder(
1310 ExitOnRootFailure(hr, "Failed to convert working folder guid into string.");
1311 }
1312
1320 - hr = StrAllocFormatted(&vsczWorkingFolder, L"%ls%ls\\", wzTempPath, wzGuid);
1313 + hr = StrAllocFormatted(&vsczWorkingFolder, L"%ls%ls\\", sczTempPath, wzGuid);
1314 ExitOnFailure(hr, "Failed to append bundle id on to temp path for working folder.");
1315 }
1316
@@ -1325,6 +1318,8 @@ static HRESULT CalculateWorkingFolder(
1318 ExitOnFailure(hr, "Failed to copy working folder path.");
1319
1320 LExit:
1321 + ReleaseStr(sczTempPath);
1322 +
1323 return hr;
1324 }
1325
src/burn/engine/variable.cpp
-1
@@ -1916,7 +1916,6 @@ static HRESULT InitializeVariableTempFolder(
1916 HRESULT hr = S_OK;
1917 WCHAR wzPath[MAX_PATH] = { };
1918
1919 - // get volume path name
1919 if (!::GetTempPathW(MAX_PATH, wzPath))
1920 {
1921 ExitWithLastError(hr, "Failed to get temp path.");
src/libs/dutil/WixToolset.DUtil/inc/pathutil.h
+16
@@ -150,6 +150,22 @@ DAPI_(HRESULT) PathCreateTempDirectory(
150 __out LPWSTR* psczTempDirectory
151 );
152
153 +/*******************************************************************
154 + PathGetTempPath - returns the path to the temp folder
155 + that is backslash terminated.
156 +*******************************************************************/
157 +DAPI_(HRESULT) PathGetTempPath(
158 + __out_z LPWSTR* psczTempPath
159 + );
160 +
161 +/*******************************************************************
162 + PathGetSystemTempPath - returns the path to the system temp folder
163 + that is backslash terminated.
164 +*******************************************************************/
165 +DAPI_(HRESULT) PathGetSystemTempPath(
166 + __out_z LPWSTR* psczSystemTempPath
167 + );
168 +
169 /*******************************************************************
170 PathGetKnownFolder - returns the path to a well-known shell folder
171
src/libs/dutil/WixToolset.DUtil/pathutil.cpp
+87
@@ -9,6 +9,7 @@
9 #define PathExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_PATHUTIL, x, s, __VA_ARGS__)
10 #define PathExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_PATHUTIL, x, s, __VA_ARGS__)
11 #define PathExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_PATHUTIL, x, s, __VA_ARGS__)
12 +#define PathExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_PATHUTIL, x, e, s, __VA_ARGS__)
13 #define PathExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_PATHUTIL, x, s, __VA_ARGS__)
14 #define PathExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_PATHUTIL, p, x, e, s, __VA_ARGS__)
15 #define PathExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_PATHUTIL, p, x, s, __VA_ARGS__)
@@ -814,6 +815,92 @@ LExit:
815 }
816
817
818 +DAPI_(HRESULT) PathGetTempPath(
819 + __out_z LPWSTR* psczTempPath
820 + )
821 +{
822 + HRESULT hr = S_OK;
823 + WCHAR wzTempPath[MAX_PATH + 1] = { };
824 + DWORD cch = 0;
825 +
826 + cch = ::GetTempPathW(countof(wzTempPath), wzTempPath);
827 + if (!cch)
828 + {
829 + PathExitWithLastError(hr, "Failed to GetTempPath.");
830 + }
831 + else if (cch >= countof(wzTempPath))
832 + {
833 + PathExitWithRootFailure(hr, E_INSUFFICIENT_BUFFER, "TEMP directory path too long.");
834 + }
835 +
836 + hr = StrAllocString(psczTempPath, wzTempPath, cch);
837 + PathExitOnFailure(hr, "Failed to copy TEMP directory path.");
838 +
839 +LExit:
840 + return hr;
841 +}
842 +
843 +
844 +DAPI_(HRESULT) PathGetSystemTempPath(
845 + __out_z LPWSTR* psczSystemTempPath
846 + )
847 +{
848 + HRESULT hr = S_OK;
849 + HKEY hKey = NULL;
850 + WCHAR wzTempPath[MAX_PATH + 1] = { };
851 + DWORD cch = 0;
852 +
853 + // There is no documented API to get system environment variables, so read them from the registry.
854 + hr = RegOpen(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\Session Manager\\Environment", KEY_READ, &hKey);
855 + if (E_FILENOTFOUND != hr)
856 + {
857 + PathExitOnFailure(hr, "Failed to open system environment registry key.");
858 +
859 + // Follow documented precedence rules for TMP/TEMP from ::GetTempPath.
860 + // TODO: values will be expanded with the current environment variables instead of the system environment variables.
861 + hr = RegReadString(hKey, L"TMP", psczSystemTempPath);
862 + if (E_FILENOTFOUND != hr)
863 + {
864 + PathExitOnFailure(hr, "Failed to get system TMP value.");
865 +
866 + hr = PathBackslashTerminate(psczSystemTempPath);
867 + PathExitOnFailure(hr, "Failed to backslash terminate system TMP value.");
868 +
869 + ExitFunction();
870 + }
871 +
872 + hr = RegReadString(hKey, L"TEMP", psczSystemTempPath);
873 + if (E_FILENOTFOUND != hr)
874 + {
875 + PathExitOnFailure(hr, "Failed to get system TEMP value.");
876 +
877 + hr = PathBackslashTerminate(psczSystemTempPath);
878 + PathExitOnFailure(hr, "Failed to backslash terminate system TEMP value.");
879 +
880 + ExitFunction();
881 + }
882 + }
883 +
884 + cch = ::GetSystemWindowsDirectoryW(wzTempPath, countof(wzTempPath));
885 + if (!cch)
886 + {
887 + PathExitWithLastError(hr, "Failed to get Windows directory path.");
888 + }
889 + else if (cch >= countof(wzTempPath))
890 + {
891 + PathExitWithRootFailure(hr, E_INSUFFICIENT_BUFFER, "Windows directory path too long.");
892 + }
893 +
894 + hr = PathConcat(wzTempPath, L"TEMP\\", psczSystemTempPath);
895 + PathExitOnFailure(hr, "Failed to concat Temp directory on Windows directory path.");
896 +
897 +LExit:
898 + ReleaseRegKey(hKey);
899 +
900 + return hr;
901 +}
902 +
903 +
904 DAPI_(HRESULT) PathGetKnownFolder(
905 __in int csidl,
906 __out LPWSTR* psczKnownFolder