aboutsummaryrefslogtreecommitdiff
path: root/src/libs/dutil/WixToolset.DUtil/osutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/osutil.cpp')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/osutil.cpp251
1 files changed, 251 insertions, 0 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/osutil.cpp b/src/libs/dutil/WixToolset.DUtil/osutil.cpp
new file mode 100644
index 00000000..880ec3ea
--- /dev/null
+++ b/src/libs/dutil/WixToolset.DUtil/osutil.cpp
@@ -0,0 +1,251 @@
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 OsExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_OSUTIL, x, s, __VA_ARGS__)
8#define OsExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_OSUTIL, x, s, __VA_ARGS__)
9#define OsExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_OSUTIL, x, s, __VA_ARGS__)
10#define OsExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_OSUTIL, x, s, __VA_ARGS__)
11#define OsExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_OSUTIL, x, s, __VA_ARGS__)
12#define OsExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_OSUTIL, x, s, __VA_ARGS__)
13#define OsExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_OSUTIL, p, x, e, s, __VA_ARGS__)
14#define OsExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_OSUTIL, p, x, s, __VA_ARGS__)
15#define OsExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_OSUTIL, p, x, e, s, __VA_ARGS__)
16#define OsExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_OSUTIL, p, x, s, __VA_ARGS__)
17#define OsExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_OSUTIL, e, x, s, __VA_ARGS__)
18#define OsExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_OSUTIL, g, x, s, __VA_ARGS__)
19
20typedef NTSTATUS(NTAPI* PFN_RTL_GET_VERSION)(_Out_ PRTL_OSVERSIONINFOEXW lpVersionInformation);
21
22OS_VERSION vOsVersion = OS_VERSION_UNKNOWN;
23DWORD vdwOsServicePack = 0;
24RTL_OSVERSIONINFOEXW vovix = { };
25
26/********************************************************************
27 OsGetVersion
28
29********************************************************************/
30extern "C" void DAPI OsGetVersion(
31 __out OS_VERSION* pVersion,
32 __out DWORD* pdwServicePack
33 )
34{
35 OSVERSIONINFOEXW ovi = { };
36
37 if (OS_VERSION_UNKNOWN == vOsVersion)
38 {
39 ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
40
41#pragma warning (push)
42#pragma warning(suppress: 4996) // deprecated
43#pragma warning (push)
44#pragma warning(suppress: 28159)// deprecated, use other function instead
45 ::GetVersionExW(reinterpret_cast<OSVERSIONINFOW*>(&ovi)); // only fails if version info size is set incorrectly.
46#pragma warning (pop)
47#pragma warning (pop)
48
49 vdwOsServicePack = static_cast<DWORD>(ovi.wServicePackMajor) << 16 | ovi.wServicePackMinor;
50 if (4 == ovi.dwMajorVersion)
51 {
52 vOsVersion = OS_VERSION_WINNT;
53 }
54 else if (5 == ovi.dwMajorVersion)
55 {
56 if (0 == ovi.dwMinorVersion)
57 {
58 vOsVersion = OS_VERSION_WIN2000;
59 }
60 else if (1 == ovi.dwMinorVersion)
61 {
62 vOsVersion = OS_VERSION_WINXP;
63 }
64 else if (2 == ovi.dwMinorVersion)
65 {
66 vOsVersion = OS_VERSION_WIN2003;
67 }
68 else
69 {
70 vOsVersion = OS_VERSION_FUTURE;
71 }
72 }
73 else if (6 == ovi.dwMajorVersion)
74 {
75 if (0 == ovi.dwMinorVersion)
76 {
77 vOsVersion = (VER_NT_WORKSTATION == ovi.wProductType) ? OS_VERSION_VISTA : OS_VERSION_WIN2008;
78 }
79 else if (1 == ovi.dwMinorVersion)
80 {
81 vOsVersion = (VER_NT_WORKSTATION == ovi.wProductType) ? OS_VERSION_WIN7 : OS_VERSION_WIN2008_R2;
82 }
83 else
84 {
85 vOsVersion = OS_VERSION_FUTURE;
86 }
87 }
88 else
89 {
90 vOsVersion = OS_VERSION_FUTURE;
91 }
92 }
93
94 *pVersion = vOsVersion;
95 *pdwServicePack = vdwOsServicePack;
96}
97
98extern "C" HRESULT DAPI OsCouldRunPrivileged(
99 __out BOOL* pfPrivileged
100 )
101{
102 HRESULT hr = S_OK;
103 BOOL fUacEnabled = FALSE;
104 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
105 PSID AdministratorsGroup = NULL;
106
107 // Do a best effort check to see if UAC is enabled on this machine.
108 OsIsUacEnabled(&fUacEnabled);
109
110 // If UAC is enabled then the process could run privileged by asking to elevate.
111 if (fUacEnabled)
112 {
113 *pfPrivileged = TRUE;
114 }
115 else // no UAC so only privilged if user is in administrators group.
116 {
117 *pfPrivileged = ::AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup);
118 if (*pfPrivileged)
119 {
120 if (!::CheckTokenMembership(NULL, AdministratorsGroup, pfPrivileged))
121 {
122 *pfPrivileged = FALSE;
123 }
124 }
125 }
126
127 ReleaseSid(AdministratorsGroup);
128 return hr;
129}
130
131extern "C" HRESULT DAPI OsIsRunningPrivileged(
132 __out BOOL* pfPrivileged
133 )
134{
135 HRESULT hr = S_OK;
136 UINT er = ERROR_SUCCESS;
137 HANDLE hToken = NULL;
138 TOKEN_ELEVATION_TYPE elevationType = TokenElevationTypeDefault;
139 DWORD dwSize = 0;
140 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
141 PSID AdministratorsGroup = NULL;
142
143 if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &hToken))
144 {
145 OsExitOnLastError(hr, "Failed to open process token.");
146 }
147
148 if (::GetTokenInformation(hToken, TokenElevationType, &elevationType, sizeof(TOKEN_ELEVATION_TYPE), &dwSize))
149 {
150 *pfPrivileged = (TokenElevationTypeFull == elevationType);
151 ExitFunction1(hr = S_OK);
152 }
153
154 // If it's invalid argument, this means they don't support TokenElevationType, and we should fallback to another check
155 er = ::GetLastError();
156 if (ERROR_INVALID_FUNCTION == er)
157 {
158 er = ERROR_SUCCESS;
159 }
160 OsExitOnWin32Error(er, hr, "Failed to get process token information.");
161
162 // Fallback to this check for some OS's (like XP)
163 *pfPrivileged = ::AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup);
164 if (*pfPrivileged)
165 {
166 if (!::CheckTokenMembership(NULL, AdministratorsGroup, pfPrivileged))
167 {
168 *pfPrivileged = FALSE;
169 }
170 }
171
172LExit:
173 ReleaseSid(AdministratorsGroup);
174
175 if (hToken)
176 {
177 ::CloseHandle(hToken);
178 }
179
180 return hr;
181}
182
183extern "C" HRESULT DAPI OsIsUacEnabled(
184 __out BOOL* pfUacEnabled
185 )
186{
187 HRESULT hr = S_OK;
188 HKEY hk = NULL;
189 DWORD dwUacEnabled = 0;
190
191 *pfUacEnabled = FALSE; // assume UAC not enabled.
192
193 hr = RegOpen(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", KEY_READ, &hk);
194 if (E_FILENOTFOUND == hr)
195 {
196 ExitFunction1(hr = S_OK);
197 }
198 OsExitOnFailure(hr, "Failed to open system policy key to detect UAC.");
199
200 hr = RegReadNumber(hk, L"EnableLUA", &dwUacEnabled);
201 if (E_FILENOTFOUND == hr)
202 {
203 ExitFunction1(hr = S_OK);
204 }
205 OsExitOnFailure(hr, "Failed to read registry value to detect UAC.");
206
207 *pfUacEnabled = (0 != dwUacEnabled);
208
209LExit:
210 ReleaseRegKey(hk);
211
212 return hr;
213}
214
215HRESULT DAPI OsRtlGetVersion(
216 __inout RTL_OSVERSIONINFOEXW* pOvix
217 )
218{
219 HRESULT hr = S_OK;
220 HMODULE hNtdll = NULL;
221 PFN_RTL_GET_VERSION pfnRtlGetVersion = NULL;
222
223 if (vovix.dwOSVersionInfoSize)
224 {
225 ExitFunction();
226 }
227
228 vovix.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
229
230 hr = LoadSystemLibrary(L"ntdll.dll", &hNtdll);
231 if (E_MODNOTFOUND == hr)
232 {
233 OsExitOnRootFailure(hr = E_NOTIMPL, "Failed to load ntdll.dll");
234 }
235 OsExitOnFailure(hr, "Failed to load ntdll.dll.");
236
237 pfnRtlGetVersion = reinterpret_cast<PFN_RTL_GET_VERSION>(::GetProcAddress(hNtdll, "RtlGetVersion"));
238 OsExitOnNullWithLastError(pfnRtlGetVersion, hr, "Failed to locate RtlGetVersion.");
239
240 hr = static_cast<HRESULT>(pfnRtlGetVersion(&vovix));
241
242LExit:
243 memcpy(pOvix, &vovix, sizeof(RTL_OSVERSIONINFOEXW));
244
245 if (hNtdll)
246 {
247 ::FreeLibrary(hNtdll);
248 }
249
250 return hr;
251}