diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2022-06-03 17:50:22 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2022-06-07 19:44:36 -0500 |
commit | 8810aa8908ed7887616d86dd5fb821fcfa92f444 (patch) | |
tree | 8bc05667c36cc0d3db73504c867e85b01f1a79b0 /src/libs/dutil | |
parent | 266b097c0b0a13dd4934f55f61cad62ffcbb953d (diff) | |
download | wix-8810aa8908ed7887616d86dd5fb821fcfa92f444.tar.gz wix-8810aa8908ed7887616d86dd5fb821fcfa92f444.tar.bz2 wix-8810aa8908ed7887616d86dd5fb821fcfa92f444.zip |
Update Burn algorithm for picking elevated temp path to use SystemTemp.
Diffstat (limited to 'src/libs/dutil')
17 files changed, 518 insertions, 81 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj index 9d057461..3100768d 100644 --- a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj +++ b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj | |||
@@ -65,6 +65,7 @@ | |||
65 | <PrecompiledHeader>Create</PrecompiledHeader> | 65 | <PrecompiledHeader>Create</PrecompiledHeader> |
66 | <DisableSpecificWarnings>4091;4458</DisableSpecificWarnings> | 66 | <DisableSpecificWarnings>4091;4458</DisableSpecificWarnings> |
67 | </ClCompile> | 67 | </ClCompile> |
68 | <ClCompile Include="env2util.cpp" /> | ||
68 | <ClCompile Include="envutil.cpp" /> | 69 | <ClCompile Include="envutil.cpp" /> |
69 | <ClCompile Include="eseutil.cpp" /> | 70 | <ClCompile Include="eseutil.cpp" /> |
70 | <ClCompile Include="file2utl.cpp" /> | 71 | <ClCompile Include="file2utl.cpp" /> |
@@ -82,6 +83,7 @@ | |||
82 | <ClCompile Include="monutil.cpp" /> | 83 | <ClCompile Include="monutil.cpp" /> |
83 | <ClCompile Include="osutil.cpp" /> | 84 | <ClCompile Include="osutil.cpp" /> |
84 | <ClCompile Include="path2utl.cpp" /> | 85 | <ClCompile Include="path2utl.cpp" /> |
86 | <ClCompile Include="path3utl.cpp" /> | ||
85 | <ClCompile Include="pathutil.cpp" /> | 87 | <ClCompile Include="pathutil.cpp" /> |
86 | <ClCompile Include="perfutil.cpp" /> | 88 | <ClCompile Include="perfutil.cpp" /> |
87 | <ClCompile Include="polcutil.cpp" /> | 89 | <ClCompile Include="polcutil.cpp" /> |
diff --git a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters index 556468b7..c966c965 100644 --- a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters +++ b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters | |||
@@ -66,6 +66,9 @@ | |||
66 | <ClCompile Include="dutil.cpp"> | 66 | <ClCompile Include="dutil.cpp"> |
67 | <Filter>Source Files</Filter> | 67 | <Filter>Source Files</Filter> |
68 | </ClCompile> | 68 | </ClCompile> |
69 | <ClCompile Include="env2util.cpp"> | ||
70 | <Filter>Source Files</Filter> | ||
71 | </ClCompile> | ||
69 | <ClCompile Include="envutil.cpp"> | 72 | <ClCompile Include="envutil.cpp"> |
70 | <Filter>Source Files</Filter> | 73 | <Filter>Source Files</Filter> |
71 | </ClCompile> | 74 | </ClCompile> |
@@ -111,6 +114,9 @@ | |||
111 | <ClCompile Include="osutil.cpp"> | 114 | <ClCompile Include="osutil.cpp"> |
112 | <Filter>Source Files</Filter> | 115 | <Filter>Source Files</Filter> |
113 | </ClCompile> | 116 | </ClCompile> |
117 | <ClCompile Include="path3utl.cpp"> | ||
118 | <Filter>Source Files</Filter> | ||
119 | </ClCompile> | ||
114 | <ClCompile Include="path2utl.cpp"> | 120 | <ClCompile Include="path2utl.cpp"> |
115 | <Filter>Source Files</Filter> | 121 | <Filter>Source Files</Filter> |
116 | </ClCompile> | 122 | </ClCompile> |
diff --git a/src/libs/dutil/WixToolset.DUtil/env2util.cpp b/src/libs/dutil/WixToolset.DUtil/env2util.cpp new file mode 100644 index 00000000..21bbd101 --- /dev/null +++ b/src/libs/dutil/WixToolset.DUtil/env2util.cpp | |||
@@ -0,0 +1,80 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | #include "precomp.h" | ||
4 | |||
5 | |||
6 | // Exit macros | ||
7 | #define EnvExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_ENVUTIL, x, s, __VA_ARGS__) | ||
8 | #define EnvExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_ENVUTIL, x, s, __VA_ARGS__) | ||
9 | #define EnvExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_ENVUTIL, x, s, __VA_ARGS__) | ||
10 | #define EnvExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_ENVUTIL, x, s, __VA_ARGS__) | ||
11 | #define EnvExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_ENVUTIL, x, s, __VA_ARGS__) | ||
12 | #define EnvExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_ENVUTIL, x, e, s, __VA_ARGS__) | ||
13 | #define EnvExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_ENVUTIL, x, s, __VA_ARGS__) | ||
14 | #define EnvExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_ENVUTIL, p, x, e, s, __VA_ARGS__) | ||
15 | #define EnvExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_ENVUTIL, p, x, s, __VA_ARGS__) | ||
16 | #define EnvExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_ENVUTIL, p, x, e, s, __VA_ARGS__) | ||
17 | #define EnvExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_ENVUTIL, p, x, s, __VA_ARGS__) | ||
18 | #define EnvExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_ENVUTIL, e, x, s, __VA_ARGS__) | ||
19 | #define EnvExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_ENVUTIL, g, x, s, __VA_ARGS__) | ||
20 | |||
21 | #define ENV2_GOOD_ENOUGH 64 | ||
22 | |||
23 | DAPI_(HRESULT) EnvExpandEnvironmentStringsForUser( | ||
24 | __in_opt HANDLE hToken, | ||
25 | __in LPCWSTR wzSource, | ||
26 | __out LPWSTR* psczExpanded, | ||
27 | __out_opt SIZE_T* pcchExpanded | ||
28 | ) | ||
29 | { | ||
30 | HRESULT hr = S_OK; | ||
31 | DWORD cchExpanded = 0; | ||
32 | SIZE_T cchMax = 0; | ||
33 | const DWORD dwMaxAttempts = 20; | ||
34 | |||
35 | if (*psczExpanded) | ||
36 | { | ||
37 | hr = StrMaxLength(*psczExpanded, &cchMax); | ||
38 | EnvExitOnFailure(hr, "Failed to get max length of input buffer."); | ||
39 | |||
40 | cchExpanded = (DWORD)min(DWORD_MAX, cchMax); | ||
41 | } | ||
42 | else | ||
43 | { | ||
44 | cchExpanded = ENV2_GOOD_ENOUGH; | ||
45 | |||
46 | hr = StrAlloc(psczExpanded, cchExpanded); | ||
47 | EnvExitOnFailure(hr, "Failed to allocate space for expanded path."); | ||
48 | } | ||
49 | |||
50 | for (DWORD i = 0; i < dwMaxAttempts; ++i) | ||
51 | { | ||
52 | if (::ExpandEnvironmentStringsForUserW(hToken, wzSource, *psczExpanded, cchExpanded)) | ||
53 | { | ||
54 | break; | ||
55 | } | ||
56 | |||
57 | hr = HRESULT_FROM_WIN32(::GetLastError()); | ||
58 | if (E_INSUFFICIENT_BUFFER != hr || (dwMaxAttempts - 1) == i) | ||
59 | { | ||
60 | EnvExitWithRootFailure(hr, hr, "Failed to expand environment variables in string: %ls", wzSource); | ||
61 | } | ||
62 | |||
63 | cchExpanded *= 2; | ||
64 | |||
65 | hr = StrAlloc(psczExpanded, cchExpanded); | ||
66 | EnvExitOnFailure(hr, "Failed to re-allocate more space for expanded path."); | ||
67 | } | ||
68 | |||
69 | if (pcchExpanded) | ||
70 | { | ||
71 | hr = ::StringCchLengthW(*psczExpanded, STRSAFE_MAX_LENGTH, reinterpret_cast<size_t*>(pcchExpanded)); | ||
72 | EnvExitOnFailure(hr, "Failed to get max length of written input buffer."); | ||
73 | |||
74 | // Add 1 for null terminator. | ||
75 | *pcchExpanded += 1; | ||
76 | } | ||
77 | |||
78 | LExit: | ||
79 | return hr; | ||
80 | } | ||
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/envutil.h b/src/libs/dutil/WixToolset.DUtil/inc/envutil.h index 8491b27b..4e4f6197 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/envutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/envutil.h | |||
@@ -16,6 +16,17 @@ HRESULT DAPI EnvExpandEnvironmentStrings( | |||
16 | __out_opt SIZE_T* pcchExpanded | 16 | __out_opt SIZE_T* pcchExpanded |
17 | ); | 17 | ); |
18 | 18 | ||
19 | /******************************************************************** | ||
20 | EnvExpandEnvironmentStringsForUser - Wrapper for ::ExpandEnvironmentStringsForUser. | ||
21 | |||
22 | *******************************************************************/ | ||
23 | HRESULT DAPI EnvExpandEnvironmentStringsForUser( | ||
24 | __in_opt HANDLE hToken, | ||
25 | __in LPCWSTR wzSource, | ||
26 | __out LPWSTR* psczExpanded, | ||
27 | __out_opt SIZE_T* pcchExpanded | ||
28 | ); | ||
29 | |||
19 | #ifdef __cplusplus | 30 | #ifdef __cplusplus |
20 | } | 31 | } |
21 | #endif | 32 | #endif |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h b/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h index 875cfafb..f36e6ebc 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h | |||
@@ -205,6 +205,15 @@ DAPI_(HRESULT) PathGetTempPath( | |||
205 | ); | 205 | ); |
206 | 206 | ||
207 | /******************************************************************* | 207 | /******************************************************************* |
208 | PathSystemWindowsSubdirectory - returns the path to the Windows folder | ||
209 | or a subdirectory of that folder that is backslash terminated. | ||
210 | *******************************************************************/ | ||
211 | DAPI_(HRESULT) PathSystemWindowsSubdirectory( | ||
212 | __in_z_opt LPCWSTR wzSubdirectory, | ||
213 | __out_z LPWSTR* psczFullPath | ||
214 | ); | ||
215 | |||
216 | /******************************************************************* | ||
208 | PathGetSystemTempPaths - returns the paths to system temp folders | 217 | PathGetSystemTempPaths - returns the paths to system temp folders |
209 | that are backslash terminated with higher preference first. | 218 | that are backslash terminated with higher preference first. |
210 | *******************************************************************/ | 219 | *******************************************************************/ |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/polcutil.h b/src/libs/dutil/WixToolset.DUtil/inc/polcutil.h index 13618043..7c873b80 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/polcutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/polcutil.h | |||
@@ -34,6 +34,20 @@ HRESULT DAPI PolcReadString( | |||
34 | __deref_out_z LPWSTR* pscz | 34 | __deref_out_z LPWSTR* pscz |
35 | ); | 35 | ); |
36 | 36 | ||
37 | /******************************************************************** | ||
38 | PolcReadUnexpandedString - reads a string from policy, without expanding it. | ||
39 | |||
40 | NOTE: S_FALSE returned if policy not set. | ||
41 | NOTE: out is set to default on S_FALSE or any error. | ||
42 | ********************************************************************/ | ||
43 | HRESULT DAPI PolcReadUnexpandedString( | ||
44 | __in_z LPCWSTR wzPolicyPath, | ||
45 | __in_z LPCWSTR wzPolicyName, | ||
46 | __in_z_opt LPCWSTR wzDefault, | ||
47 | __inout BOOL* pfNeedsExpansion, | ||
48 | __deref_out_z LPWSTR* pscz | ||
49 | ); | ||
50 | |||
37 | #ifdef __cplusplus | 51 | #ifdef __cplusplus |
38 | } | 52 | } |
39 | #endif | 53 | #endif |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/procutil.h b/src/libs/dutil/WixToolset.DUtil/inc/procutil.h index 4f49313b..d5ab9242 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/procutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/procutil.h | |||
@@ -18,6 +18,16 @@ HRESULT DAPI ProcElevated( | |||
18 | __out BOOL* pfElevated | 18 | __out BOOL* pfElevated |
19 | ); | 19 | ); |
20 | 20 | ||
21 | HRESULT DAPI ProcSystem( | ||
22 | __in HANDLE hProcess, | ||
23 | __out BOOL* pfSystem | ||
24 | ); | ||
25 | |||
26 | HRESULT DAPI ProcTokenUser( | ||
27 | __in HANDLE hProcess, | ||
28 | __out TOKEN_USER** ppTokenUser | ||
29 | ); | ||
30 | |||
21 | HRESULT DAPI ProcWow64( | 31 | HRESULT DAPI ProcWow64( |
22 | __in HANDLE hProcess, | 32 | __in HANDLE hProcess, |
23 | __out BOOL* pfWow64 | 33 | __out BOOL* pfWow64 |
diff --git a/src/libs/dutil/WixToolset.DUtil/path2utl.cpp b/src/libs/dutil/WixToolset.DUtil/path2utl.cpp index 9e48f9d5..c6ff608c 100644 --- a/src/libs/dutil/WixToolset.DUtil/path2utl.cpp +++ b/src/libs/dutil/WixToolset.DUtil/path2utl.cpp | |||
@@ -246,3 +246,41 @@ LExit: | |||
246 | ReleaseStr(sczCanonicalizedDirectory); | 246 | ReleaseStr(sczCanonicalizedDirectory); |
247 | return hr; | 247 | return hr; |
248 | } | 248 | } |
249 | |||
250 | |||
251 | DAPI_(HRESULT) PathSystemWindowsSubdirectory( | ||
252 | __in_z_opt LPCWSTR wzSubdirectory, | ||
253 | __out_z LPWSTR* psczFullPath | ||
254 | ) | ||
255 | { | ||
256 | HRESULT hr = S_OK; | ||
257 | WCHAR wzTempPath[MAX_PATH + 1] = { }; | ||
258 | DWORD cch = 0; | ||
259 | |||
260 | cch = ::GetSystemWindowsDirectoryW(wzTempPath, countof(wzTempPath)); | ||
261 | if (!cch) | ||
262 | { | ||
263 | PathExitWithLastError(hr, "Failed to get Windows directory path."); | ||
264 | } | ||
265 | else if (cch >= countof(wzTempPath)) | ||
266 | { | ||
267 | PathExitWithRootFailure(hr, E_INSUFFICIENT_BUFFER, "Windows directory path too long."); | ||
268 | } | ||
269 | |||
270 | if (wzSubdirectory) | ||
271 | { | ||
272 | hr = PathConcatRelativeToBase(wzTempPath, wzSubdirectory, psczFullPath); | ||
273 | PathExitOnFailure(hr, "Failed to concat subdirectory on Windows directory path."); | ||
274 | } | ||
275 | else | ||
276 | { | ||
277 | hr = StrAllocString(psczFullPath, wzTempPath, 0); | ||
278 | PathExitOnFailure(hr, "Failed to copy Windows directory path."); | ||
279 | } | ||
280 | |||
281 | hr = PathBackslashTerminate(psczFullPath); | ||
282 | PathExitOnFailure(hr, "Failed to terminate Windows directory path with backslash."); | ||
283 | |||
284 | LExit: | ||
285 | return hr; | ||
286 | } | ||
diff --git a/src/libs/dutil/WixToolset.DUtil/path3utl.cpp b/src/libs/dutil/WixToolset.DUtil/path3utl.cpp new file mode 100644 index 00000000..cb6ce6d5 --- /dev/null +++ b/src/libs/dutil/WixToolset.DUtil/path3utl.cpp | |||
@@ -0,0 +1,143 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | #include "precomp.h" | ||
4 | |||
5 | |||
6 | // Exit macros | ||
7 | #define PathExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_PATHUTIL, x, s, __VA_ARGS__) | ||
8 | #define PathExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_PATHUTIL, x, s, __VA_ARGS__) | ||
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__) | ||
16 | #define PathExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_PATHUTIL, p, x, e, s, __VA_ARGS__) | ||
17 | #define PathExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_PATHUTIL, p, x, s, __VA_ARGS__) | ||
18 | #define PathExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_PATHUTIL, e, x, s, __VA_ARGS__) | ||
19 | #define PathExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_PATHUTIL, g, x, s, __VA_ARGS__) | ||
20 | |||
21 | static HRESULT GetTempPathFromSystemEnvironmentVariable( | ||
22 | __in HKEY hKey, | ||
23 | __in_z LPCWSTR wzName, | ||
24 | __out_z LPWSTR* psczPath | ||
25 | ); | ||
26 | |||
27 | DAPI_(HRESULT) PathGetSystemTempPaths( | ||
28 | __inout_z LPWSTR** prgsczSystemTempPaths, | ||
29 | __inout DWORD* pcSystemTempPaths | ||
30 | ) | ||
31 | { | ||
32 | HRESULT hr = S_OK; | ||
33 | HMODULE hModule = NULL; | ||
34 | BOOL fSystem = FALSE; | ||
35 | HKEY hKey = NULL; | ||
36 | LPWSTR sczTemp = NULL; | ||
37 | |||
38 | // Follow documented precedence rules for SystemTemp/%TMP%/%TEMP% from ::GetTempPath2. | ||
39 | hr = LoadSystemLibrary(L"kernel32.dll", &hModule); | ||
40 | PathExitOnFailure(hr, "Failed to load kernel32.dll"); | ||
41 | |||
42 | // The SystemTemp folder was added at the same time as ::GetTempPath2. | ||
43 | if (::GetProcAddress(hModule, "GetTempPath2W")) | ||
44 | { | ||
45 | hr = ProcSystem(::GetCurrentProcess(), &fSystem); | ||
46 | PathExitOnFailure(hr, "Failed to check if running as system."); | ||
47 | |||
48 | if (fSystem) | ||
49 | { | ||
50 | hr = PathSystemWindowsSubdirectory(L"SystemTemp", &sczTemp); | ||
51 | PathExitOnFailure(hr, "Failed to get system Windows subdirectory path SystemTemp."); | ||
52 | |||
53 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczSystemTempPaths), *pcSystemTempPaths, 1, sizeof(LPWSTR), 4); | ||
54 | PathExitOnFailure(hr, "Failed to ensure array size for Windows\\SystemTemp value."); | ||
55 | |||
56 | (*prgsczSystemTempPaths)[*pcSystemTempPaths] = sczTemp; | ||
57 | sczTemp = NULL; | ||
58 | *pcSystemTempPaths += 1; | ||
59 | } | ||
60 | } | ||
61 | |||
62 | // There is no documented API to get system environment variables, so read them from the registry. | ||
63 | hr = RegOpen(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\Session Manager\\Environment", KEY_READ, &hKey); | ||
64 | if (E_FILENOTFOUND != hr) | ||
65 | { | ||
66 | PathExitOnFailure(hr, "Failed to open system environment registry key."); | ||
67 | |||
68 | hr = GetTempPathFromSystemEnvironmentVariable(hKey, L"TMP", &sczTemp); | ||
69 | PathExitOnFailure(hr, "Failed to get temp path from system TMP."); | ||
70 | |||
71 | if (S_FALSE != hr) | ||
72 | { | ||
73 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczSystemTempPaths), *pcSystemTempPaths, 1, sizeof(LPWSTR), 3); | ||
74 | PathExitOnFailure(hr, "Failed to ensure array size for system TMP value."); | ||
75 | |||
76 | (*prgsczSystemTempPaths)[*pcSystemTempPaths] = sczTemp; | ||
77 | sczTemp = NULL; | ||
78 | *pcSystemTempPaths += 1; | ||
79 | } | ||
80 | |||
81 | hr = GetTempPathFromSystemEnvironmentVariable(hKey, L"TEMP", &sczTemp); | ||
82 | PathExitOnFailure(hr, "Failed to get temp path from system TEMP."); | ||
83 | |||
84 | if (S_FALSE != hr) | ||
85 | { | ||
86 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczSystemTempPaths), *pcSystemTempPaths, 1, sizeof(LPWSTR), 2); | ||
87 | PathExitOnFailure(hr, "Failed to ensure array size for system TEMP value."); | ||
88 | |||
89 | (*prgsczSystemTempPaths)[*pcSystemTempPaths] = sczTemp; | ||
90 | sczTemp = NULL; | ||
91 | *pcSystemTempPaths += 1; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | hr = PathSystemWindowsSubdirectory(L"TEMP", &sczTemp); | ||
96 | PathExitOnFailure(hr, "Failed to get system Windows subdirectory path TEMP."); | ||
97 | |||
98 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczSystemTempPaths), *pcSystemTempPaths, 1, sizeof(LPWSTR), 1); | ||
99 | PathExitOnFailure(hr, "Failed to ensure array size for Windows\\TEMP value."); | ||
100 | |||
101 | (*prgsczSystemTempPaths)[*pcSystemTempPaths] = sczTemp; | ||
102 | sczTemp = NULL; | ||
103 | *pcSystemTempPaths += 1; | ||
104 | |||
105 | LExit: | ||
106 | ReleaseRegKey(hKey); | ||
107 | ReleaseStr(sczTemp); | ||
108 | |||
109 | return hr; | ||
110 | } | ||
111 | |||
112 | static HRESULT GetTempPathFromSystemEnvironmentVariable( | ||
113 | __in HKEY hKey, | ||
114 | __in_z LPCWSTR wzName, | ||
115 | __out_z LPWSTR* psczPath | ||
116 | ) | ||
117 | { | ||
118 | HRESULT hr = S_OK; | ||
119 | LPWSTR sczValue = NULL; | ||
120 | BOOL fNeedsExpansion = FALSE; | ||
121 | |||
122 | // Read the value unexpanded so that it can be expanded with system environment variables. | ||
123 | hr = RegReadUnexpandedString(hKey, wzName, &fNeedsExpansion, &sczValue); | ||
124 | if (E_FILENOTFOUND == hr) | ||
125 | { | ||
126 | ExitFunction1(hr = S_FALSE); | ||
127 | } | ||
128 | PathExitOnFailure(hr, "Failed to get system '%ls' value.", wzName); | ||
129 | |||
130 | if (fNeedsExpansion) | ||
131 | { | ||
132 | hr = EnvExpandEnvironmentStringsForUser(NULL, sczValue, psczPath, NULL); | ||
133 | PathExitOnFailure(hr, "Failed to expand environment variables for system in string: %ls", sczValue); | ||
134 | } | ||
135 | |||
136 | hr = PathBackslashTerminate(psczPath); | ||
137 | PathExitOnFailure(hr, "Failed to backslash terminate system '%ls' value.", wzName); | ||
138 | |||
139 | LExit: | ||
140 | ReleaseStr(sczValue); | ||
141 | |||
142 | return hr; | ||
143 | } | ||
diff --git a/src/libs/dutil/WixToolset.DUtil/pathutil.cpp b/src/libs/dutil/WixToolset.DUtil/pathutil.cpp index becfc67e..0e2a5dec 100644 --- a/src/libs/dutil/WixToolset.DUtil/pathutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/pathutil.cpp | |||
@@ -894,86 +894,6 @@ LExit: | |||
894 | } | 894 | } |
895 | 895 | ||
896 | 896 | ||
897 | DAPI_(HRESULT) PathGetSystemTempPaths( | ||
898 | __inout_z LPWSTR** prgsczSystemTempPaths, | ||
899 | __inout DWORD* pcSystemTempPaths | ||
900 | ) | ||
901 | { | ||
902 | HRESULT hr = S_OK; | ||
903 | HKEY hKey = NULL; | ||
904 | LPWSTR sczTemp = NULL; | ||
905 | WCHAR wzTempPath[MAX_PATH + 1] = { }; | ||
906 | DWORD cch = 0; | ||
907 | |||
908 | // There is no documented API to get system environment variables, so read them from the registry. | ||
909 | hr = RegOpen(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\Session Manager\\Environment", KEY_READ, &hKey); | ||
910 | if (E_FILENOTFOUND != hr) | ||
911 | { | ||
912 | PathExitOnFailure(hr, "Failed to open system environment registry key."); | ||
913 | |||
914 | // Follow documented precedence rules for TMP/TEMP from ::GetTempPath. | ||
915 | // TODO: values will be expanded with the current environment variables instead of the system environment variables. | ||
916 | hr = RegReadString(hKey, L"TMP", &sczTemp); | ||
917 | if (E_FILENOTFOUND != hr) | ||
918 | { | ||
919 | PathExitOnFailure(hr, "Failed to get system TMP value."); | ||
920 | |||
921 | hr = PathBackslashTerminate(&sczTemp); | ||
922 | PathExitOnFailure(hr, "Failed to backslash terminate system TMP value."); | ||
923 | |||
924 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczSystemTempPaths), *pcSystemTempPaths, 1, sizeof(LPWSTR), 3); | ||
925 | PathExitOnFailure(hr, "Failed to ensure array size for system TMP value."); | ||
926 | |||
927 | (*prgsczSystemTempPaths)[*pcSystemTempPaths] = sczTemp; | ||
928 | sczTemp = NULL; | ||
929 | *pcSystemTempPaths += 1; | ||
930 | } | ||
931 | |||
932 | hr = RegReadString(hKey, L"TEMP", &sczTemp); | ||
933 | if (E_FILENOTFOUND != hr) | ||
934 | { | ||
935 | PathExitOnFailure(hr, "Failed to get system TEMP value."); | ||
936 | |||
937 | hr = PathBackslashTerminate(&sczTemp); | ||
938 | PathExitOnFailure(hr, "Failed to backslash terminate system TEMP value."); | ||
939 | |||
940 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczSystemTempPaths), *pcSystemTempPaths, 1, sizeof(LPWSTR), 2); | ||
941 | PathExitOnFailure(hr, "Failed to ensure array size for system TEMP value."); | ||
942 | |||
943 | (*prgsczSystemTempPaths)[*pcSystemTempPaths] = sczTemp; | ||
944 | sczTemp = NULL; | ||
945 | *pcSystemTempPaths += 1; | ||
946 | } | ||
947 | } | ||
948 | |||
949 | cch = ::GetSystemWindowsDirectoryW(wzTempPath, countof(wzTempPath)); | ||
950 | if (!cch) | ||
951 | { | ||
952 | PathExitWithLastError(hr, "Failed to get Windows directory path."); | ||
953 | } | ||
954 | else if (cch >= countof(wzTempPath)) | ||
955 | { | ||
956 | PathExitWithRootFailure(hr, E_INSUFFICIENT_BUFFER, "Windows directory path too long."); | ||
957 | } | ||
958 | |||
959 | hr = PathConcat(wzTempPath, L"TEMP\\", &sczTemp); | ||
960 | PathExitOnFailure(hr, "Failed to concat Temp directory on Windows directory path."); | ||
961 | |||
962 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczSystemTempPaths), *pcSystemTempPaths, 1, sizeof(LPWSTR), 1); | ||
963 | PathExitOnFailure(hr, "Failed to ensure array size for Windows\\TEMP value."); | ||
964 | |||
965 | (*prgsczSystemTempPaths)[*pcSystemTempPaths] = sczTemp; | ||
966 | sczTemp = NULL; | ||
967 | *pcSystemTempPaths += 1; | ||
968 | |||
969 | LExit: | ||
970 | ReleaseRegKey(hKey); | ||
971 | ReleaseStr(sczTemp); | ||
972 | |||
973 | return hr; | ||
974 | } | ||
975 | |||
976 | |||
977 | DAPI_(HRESULT) PathGetKnownFolder( | 897 | DAPI_(HRESULT) PathGetKnownFolder( |
978 | __in int csidl, | 898 | __in int csidl, |
979 | __out LPWSTR* psczKnownFolder | 899 | __out LPWSTR* psczKnownFolder |
diff --git a/src/libs/dutil/WixToolset.DUtil/polcutil.cpp b/src/libs/dutil/WixToolset.DUtil/polcutil.cpp index 1fdfa18c..c2247bc1 100644 --- a/src/libs/dutil/WixToolset.DUtil/polcutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/polcutil.cpp | |||
@@ -102,6 +102,49 @@ LExit: | |||
102 | return hr; | 102 | return hr; |
103 | } | 103 | } |
104 | 104 | ||
105 | extern "C" HRESULT DAPI PolcReadUnexpandedString( | ||
106 | __in_z LPCWSTR wzPolicyPath, | ||
107 | __in_z LPCWSTR wzPolicyName, | ||
108 | __in_z_opt LPCWSTR wzDefault, | ||
109 | __inout BOOL* pfNeedsExpansion, | ||
110 | __deref_out_z LPWSTR* pscz | ||
111 | ) | ||
112 | { | ||
113 | HRESULT hr = S_OK; | ||
114 | HKEY hk = NULL; | ||
115 | |||
116 | hr = OpenPolicyKey(wzPolicyPath, &hk); | ||
117 | if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr) | ||
118 | { | ||
119 | ExitFunction1(hr = S_FALSE); | ||
120 | } | ||
121 | PolcExitOnFailure(hr, "Failed to open policy key: %ls", wzPolicyPath); | ||
122 | |||
123 | hr = RegReadUnexpandedString(hk, wzPolicyName, pfNeedsExpansion, pscz); | ||
124 | if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr) | ||
125 | { | ||
126 | ExitFunction1(hr = S_FALSE); | ||
127 | } | ||
128 | PolcExitOnFailure(hr, "Failed to open policy key: %ls, name: %ls", wzPolicyPath, wzPolicyName); | ||
129 | |||
130 | LExit: | ||
131 | ReleaseRegKey(hk); | ||
132 | |||
133 | if (S_FALSE == hr || FAILED(hr)) | ||
134 | { | ||
135 | if (NULL == wzDefault) | ||
136 | { | ||
137 | ReleaseNullStr(*pscz); | ||
138 | } | ||
139 | else | ||
140 | { | ||
141 | hr = StrAllocString(pscz, wzDefault, 0); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | return hr; | ||
146 | } | ||
147 | |||
105 | 148 | ||
106 | // internal functions | 149 | // internal functions |
107 | 150 | ||
diff --git a/src/libs/dutil/WixToolset.DUtil/procutil.cpp b/src/libs/dutil/WixToolset.DUtil/procutil.cpp index a3131b7a..340a0cda 100644 --- a/src/libs/dutil/WixToolset.DUtil/procutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/procutil.cpp | |||
@@ -9,6 +9,7 @@ | |||
9 | #define ProcExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) | 9 | #define ProcExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) |
10 | #define ProcExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) | 10 | #define ProcExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) |
11 | #define ProcExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) | 11 | #define ProcExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) |
12 | #define ProcExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_PROCUTIL, x, e, s, __VA_ARGS__) | ||
12 | #define ProcExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) | 13 | #define ProcExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) |
13 | #define ProcExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_PROCUTIL, p, x, e, s, __VA_ARGS__) | 14 | #define ProcExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_PROCUTIL, p, x, e, s, __VA_ARGS__) |
14 | #define ProcExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_PROCUTIL, p, x, s, __VA_ARGS__) | 15 | #define ProcExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_PROCUTIL, p, x, s, __VA_ARGS__) |
@@ -75,6 +76,73 @@ LExit: | |||
75 | return hr; | 76 | return hr; |
76 | } | 77 | } |
77 | 78 | ||
79 | extern "C" HRESULT DAPI ProcSystem( | ||
80 | __in HANDLE hProcess, | ||
81 | __out BOOL* pfSystem | ||
82 | ) | ||
83 | { | ||
84 | HRESULT hr = S_OK; | ||
85 | TOKEN_USER* pTokenUser = NULL; | ||
86 | |||
87 | hr = ProcTokenUser(hProcess, &pTokenUser); | ||
88 | ProcExitOnFailure(hr, "Failed to get TokenUser from process token."); | ||
89 | |||
90 | *pfSystem = ::IsWellKnownSid(pTokenUser->User.Sid, WinLocalSystemSid); | ||
91 | |||
92 | LExit: | ||
93 | ReleaseMem(pTokenUser); | ||
94 | |||
95 | return hr; | ||
96 | } | ||
97 | |||
98 | extern "C" HRESULT DAPI ProcTokenUser( | ||
99 | __in HANDLE hProcess, | ||
100 | __out TOKEN_USER** ppTokenUser | ||
101 | ) | ||
102 | { | ||
103 | HRESULT hr = S_OK; | ||
104 | DWORD er = ERROR_SUCCESS; | ||
105 | HANDLE hToken = NULL; | ||
106 | TOKEN_USER* pTokenUser = NULL; | ||
107 | DWORD cbToken = 0; | ||
108 | |||
109 | if (!::OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) | ||
110 | { | ||
111 | ProcExitWithLastError(hr, "Failed to open process token."); | ||
112 | } | ||
113 | |||
114 | if (::GetTokenInformation(hToken, TokenUser, pTokenUser, 0, &cbToken)) | ||
115 | { | ||
116 | er = ERROR_SUCCESS; | ||
117 | } | ||
118 | else | ||
119 | { | ||
120 | er = ::GetLastError(); | ||
121 | } | ||
122 | |||
123 | if (er != ERROR_INSUFFICIENT_BUFFER) | ||
124 | { | ||
125 | ProcExitOnWin32Error(er, hr, "Failed to get user from process token size."); | ||
126 | } | ||
127 | |||
128 | pTokenUser = reinterpret_cast<TOKEN_USER*>(MemAlloc(cbToken, TRUE)); | ||
129 | ProcExitOnNull(pTokenUser, hr, E_OUTOFMEMORY, "Failed to allocate token information."); | ||
130 | |||
131 | if (!::GetTokenInformation(hToken, TokenUser, pTokenUser, cbToken, &cbToken)) | ||
132 | { | ||
133 | ProcExitWithLastError(hr, "Failed to get user from process token."); | ||
134 | } | ||
135 | |||
136 | *ppTokenUser = pTokenUser; | ||
137 | pTokenUser = NULL; | ||
138 | |||
139 | LExit: | ||
140 | ReleaseMem(pTokenUser); | ||
141 | ReleaseHandle(hToken); | ||
142 | |||
143 | return hr; | ||
144 | } | ||
145 | |||
78 | extern "C" HRESULT DAPI ProcWow64( | 146 | extern "C" HRESULT DAPI ProcWow64( |
79 | __in HANDLE hProcess, | 147 | __in HANDLE hProcess, |
80 | __out BOOL* pfWow64 | 148 | __out BOOL* pfWow64 |
diff --git a/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj b/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj index ee9f505e..a1f13239 100644 --- a/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj +++ b/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj | |||
@@ -40,7 +40,7 @@ | |||
40 | 40 | ||
41 | <PropertyGroup> | 41 | <PropertyGroup> |
42 | <ProjectAdditionalIncludeDirectories>..\..\WixToolset.DUtil\inc</ProjectAdditionalIncludeDirectories> | 42 | <ProjectAdditionalIncludeDirectories>..\..\WixToolset.DUtil\inc</ProjectAdditionalIncludeDirectories> |
43 | <ProjectAdditionalLinkLibraries>rpcrt4.lib;Mpr.lib;Ws2_32.lib;shlwapi.lib;urlmon.lib;wininet.lib</ProjectAdditionalLinkLibraries> | 43 | <ProjectAdditionalLinkLibraries>rpcrt4.lib;Mpr.lib;Ws2_32.lib;shlwapi.lib;urlmon.lib;userenv.lib;wininet.lib</ProjectAdditionalLinkLibraries> |
44 | </PropertyGroup> | 44 | </PropertyGroup> |
45 | 45 | ||
46 | <ItemGroup> | 46 | <ItemGroup> |
@@ -57,6 +57,7 @@ | |||
57 | <ClCompile Include="MemUtilTest.cpp" /> | 57 | <ClCompile Include="MemUtilTest.cpp" /> |
58 | <ClCompile Include="MonUtilTest.cpp" /> | 58 | <ClCompile Include="MonUtilTest.cpp" /> |
59 | <ClCompile Include="PathUtilTest.cpp" /> | 59 | <ClCompile Include="PathUtilTest.cpp" /> |
60 | <ClCompile Include="ProcUtilTest.cpp" /> | ||
60 | <ClCompile Include="precomp.cpp"> | 61 | <ClCompile Include="precomp.cpp"> |
61 | <PrecompiledHeader>Create</PrecompiledHeader> | 62 | <PrecompiledHeader>Create</PrecompiledHeader> |
62 | <!-- Warnings from referencing netstandard dlls --> | 63 | <!-- Warnings from referencing netstandard dlls --> |
diff --git a/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters b/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters index bcda6df0..cb0c8a73 100644 --- a/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters +++ b/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters | |||
@@ -54,6 +54,9 @@ | |||
54 | <ClCompile Include="PathUtilTest.cpp"> | 54 | <ClCompile Include="PathUtilTest.cpp"> |
55 | <Filter>Source Files</Filter> | 55 | <Filter>Source Files</Filter> |
56 | </ClCompile> | 56 | </ClCompile> |
57 | <ClCompile Include="ProcUtilTest.cpp"> | ||
58 | <Filter>Source Files</Filter> | ||
59 | </ClCompile> | ||
57 | <ClCompile Include="precomp.cpp"> | 60 | <ClCompile Include="precomp.cpp"> |
58 | <Filter>Source Files</Filter> | 61 | <Filter>Source Files</Filter> |
59 | </ClCompile> | 62 | </ClCompile> |
diff --git a/src/libs/dutil/test/DUtilUnitTest/EnvUtilTests.cpp b/src/libs/dutil/test/DUtilUnitTest/EnvUtilTests.cpp index 76dfa774..94b9ab8e 100644 --- a/src/libs/dutil/test/DUtilUnitTest/EnvUtilTests.cpp +++ b/src/libs/dutil/test/DUtilUnitTest/EnvUtilTests.cpp | |||
@@ -3,8 +3,10 @@ | |||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | 4 | ||
5 | using namespace System; | 5 | using namespace System; |
6 | using namespace System::Collections; | ||
6 | using namespace Xunit; | 7 | using namespace Xunit; |
7 | using namespace WixBuildTools::TestSupport; | 8 | using namespace WixBuildTools::TestSupport; |
9 | using namespace WixBuildTools::TestSupport::XunitExtensions; | ||
8 | 10 | ||
9 | namespace DutilTests | 11 | namespace DutilTests |
10 | { | 12 | { |
@@ -46,5 +48,48 @@ namespace DutilTests | |||
46 | ReleaseStr(sczExpanded); | 48 | ReleaseStr(sczExpanded); |
47 | } | 49 | } |
48 | } | 50 | } |
51 | |||
52 | [SkippableFact] | ||
53 | void EnvExpandEnvironmentStringsForUserTest() | ||
54 | { | ||
55 | HRESULT hr = S_OK; | ||
56 | LPWSTR sczExpanded = NULL; | ||
57 | SIZE_T cchExpanded = 0; | ||
58 | String^ variableName = nullptr; | ||
59 | String^ variableValue = nullptr; | ||
60 | |||
61 | // Find a system environment variable that doesn't have variables in its value; | ||
62 | for each (DictionaryEntry^ entry in Environment::GetEnvironmentVariables(EnvironmentVariableTarget::Machine)) | ||
63 | { | ||
64 | variableValue = (String^)entry->Value; | ||
65 | if (variableValue->Contains("%")) | ||
66 | { | ||
67 | continue; | ||
68 | } | ||
69 | |||
70 | variableName = (String^)entry->Key; | ||
71 | break; | ||
72 | } | ||
73 | |||
74 | if (nullptr == variableName) | ||
75 | { | ||
76 | WixAssert::Skip("No suitable system environment variables"); | ||
77 | } | ||
78 | |||
79 | pin_ptr<const wchar_t> wzUnexpanded = PtrToStringChars("%" + variableName + "%_%USERNAME%"); | ||
80 | String^ expandedValue = variableValue + "_SYSTEM"; | ||
81 | |||
82 | try | ||
83 | { | ||
84 | hr = EnvExpandEnvironmentStringsForUser(NULL, wzUnexpanded, &sczExpanded, &cchExpanded); | ||
85 | NativeAssert::Succeeded(hr, "Failed to expand %ls.", wzUnexpanded); | ||
86 | WixAssert::StringEqual(expandedValue, gcnew String(sczExpanded), false); | ||
87 | NativeAssert::Equal<SIZE_T>(expandedValue->Length + 1, cchExpanded); | ||
88 | } | ||
89 | finally | ||
90 | { | ||
91 | ReleaseStr(sczExpanded); | ||
92 | } | ||
93 | } | ||
49 | }; | 94 | }; |
50 | } | 95 | } |
diff --git a/src/libs/dutil/test/DUtilUnitTest/ProcUtilTest.cpp b/src/libs/dutil/test/DUtilUnitTest/ProcUtilTest.cpp new file mode 100644 index 00000000..297d90f4 --- /dev/null +++ b/src/libs/dutil/test/DUtilUnitTest/ProcUtilTest.cpp | |||
@@ -0,0 +1,42 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | #include "precomp.h" | ||
4 | |||
5 | using namespace System; | ||
6 | using namespace System::Security::Principal; | ||
7 | using namespace Xunit; | ||
8 | using namespace WixBuildTools::TestSupport; | ||
9 | |||
10 | namespace DutilTests | ||
11 | { | ||
12 | public ref class ProcUtil | ||
13 | { | ||
14 | public: | ||
15 | [Fact] | ||
16 | void ProcTokenUserTest() | ||
17 | { | ||
18 | HRESULT hr = S_OK; | ||
19 | TOKEN_USER* pTokenUser = NULL; | ||
20 | LPWSTR sczSid = NULL; | ||
21 | |||
22 | try | ||
23 | { | ||
24 | hr = ProcTokenUser(::GetCurrentProcess(), &pTokenUser); | ||
25 | NativeAssert::Succeeded(hr, "Failed to get TokenUser for current process."); | ||
26 | |||
27 | if (!::ConvertSidToStringSidW(pTokenUser->User.Sid, &sczSid)) | ||
28 | { | ||
29 | hr = HRESULT_FROM_WIN32(::GetLastError()); | ||
30 | NativeAssert::Succeeded(hr, "Failed to get string SID from TokenUser SID."); | ||
31 | } | ||
32 | |||
33 | Assert::Equal<String^>(WindowsIdentity::GetCurrent()->User->Value, gcnew String(sczSid)); | ||
34 | } | ||
35 | finally | ||
36 | { | ||
37 | ReleaseMem(pTokenUser); | ||
38 | ReleaseStr(sczSid); | ||
39 | } | ||
40 | } | ||
41 | }; | ||
42 | } | ||
diff --git a/src/libs/dutil/test/DUtilUnitTest/precomp.h b/src/libs/dutil/test/DUtilUnitTest/precomp.h index bc628816..ac57cdd4 100644 --- a/src/libs/dutil/test/DUtilUnitTest/precomp.h +++ b/src/libs/dutil/test/DUtilUnitTest/precomp.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <windows.h> | 5 | #include <windows.h> |
6 | #include <strsafe.h> | 6 | #include <strsafe.h> |
7 | #include <ShlObj.h> | 7 | #include <ShlObj.h> |
8 | #include <sddl.h> | ||
8 | 9 | ||
9 | // Include error.h before dutil.h | 10 | // Include error.h before dutil.h |
10 | #include <dutilsources.h> | 11 | #include <dutilsources.h> |
@@ -21,6 +22,7 @@ | |||
21 | #include <iniutil.h> | 22 | #include <iniutil.h> |
22 | #include <memutil.h> | 23 | #include <memutil.h> |
23 | #include <pathutil.h> | 24 | #include <pathutil.h> |
25 | #include <procutil.h> | ||
24 | #include <strutil.h> | 26 | #include <strutil.h> |
25 | #include <monutil.h> | 27 | #include <monutil.h> |
26 | #include <regutil.h> | 28 | #include <regutil.h> |