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