aboutsummaryrefslogtreecommitdiff
path: root/src/dutil/osutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dutil/osutil.cpp')
-rw-r--r--src/dutil/osutil.cpp188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/dutil/osutil.cpp b/src/dutil/osutil.cpp
new file mode 100644
index 00000000..d1a4dd9a
--- /dev/null
+++ b/src/dutil/osutil.cpp
@@ -0,0 +1,188 @@
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
5OS_VERSION vOsVersion = OS_VERSION_UNKNOWN;
6DWORD vdwOsServicePack = 0;
7
8/********************************************************************
9 OsGetVersion
10
11********************************************************************/
12extern "C" void DAPI OsGetVersion(
13 __out OS_VERSION* pVersion,
14 __out DWORD* pdwServicePack
15 )
16{
17 OSVERSIONINFOEXW ovi = { };
18
19 if (OS_VERSION_UNKNOWN == vOsVersion)
20 {
21 ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
22 ::GetVersionExW(reinterpret_cast<OSVERSIONINFOW*>(&ovi)); // only fails if version info size is set incorrectly.
23
24 vdwOsServicePack = static_cast<DWORD>(ovi.wServicePackMajor) << 16 | ovi.wServicePackMinor;
25 if (4 == ovi.dwMajorVersion)
26 {
27 vOsVersion = OS_VERSION_WINNT;
28 }
29 else if (5 == ovi.dwMajorVersion)
30 {
31 if (0 == ovi.dwMinorVersion)
32 {
33 vOsVersion = OS_VERSION_WIN2000;
34 }
35 else if (1 == ovi.dwMinorVersion)
36 {
37 vOsVersion = OS_VERSION_WINXP;
38 }
39 else if (2 == ovi.dwMinorVersion)
40 {
41 vOsVersion = OS_VERSION_WIN2003;
42 }
43 else
44 {
45 vOsVersion = OS_VERSION_FUTURE;
46 }
47 }
48 else if (6 == ovi.dwMajorVersion)
49 {
50 if (0 == ovi.dwMinorVersion)
51 {
52 vOsVersion = (VER_NT_WORKSTATION == ovi.wProductType) ? OS_VERSION_VISTA : OS_VERSION_WIN2008;
53 }
54 else if (1 == ovi.dwMinorVersion)
55 {
56 vOsVersion = (VER_NT_WORKSTATION == ovi.wProductType) ? OS_VERSION_WIN7 : OS_VERSION_WIN2008_R2;
57 }
58 else
59 {
60 vOsVersion = OS_VERSION_FUTURE;
61 }
62 }
63 else
64 {
65 vOsVersion = OS_VERSION_FUTURE;
66 }
67 }
68
69 *pVersion = vOsVersion;
70 *pdwServicePack = vdwOsServicePack;
71}
72
73extern "C" HRESULT DAPI OsCouldRunPrivileged(
74 __out BOOL* pfPrivileged
75 )
76{
77 HRESULT hr = S_OK;
78 BOOL fUacEnabled = FALSE;
79 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
80 PSID AdministratorsGroup = NULL;
81
82 // Do a best effort check to see if UAC is enabled on this machine.
83 OsIsUacEnabled(&fUacEnabled);
84
85 // If UAC is enabled then the process could run privileged by asking to elevate.
86 if (fUacEnabled)
87 {
88 *pfPrivileged = TRUE;
89 }
90 else // no UAC so only privilged if user is in administrators group.
91 {
92 *pfPrivileged = ::AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup);
93 if (*pfPrivileged)
94 {
95 if (!::CheckTokenMembership(NULL, AdministratorsGroup, pfPrivileged))
96 {
97 *pfPrivileged = FALSE;
98 }
99 }
100 }
101
102 ReleaseSid(AdministratorsGroup);
103 return hr;
104}
105
106extern "C" HRESULT DAPI OsIsRunningPrivileged(
107 __out BOOL* pfPrivileged
108 )
109{
110 HRESULT hr = S_OK;
111 UINT er = ERROR_SUCCESS;
112 HANDLE hToken = NULL;
113 TOKEN_ELEVATION_TYPE elevationType = TokenElevationTypeDefault;
114 DWORD dwSize = 0;
115 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
116 PSID AdministratorsGroup = NULL;
117
118 if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &hToken))
119 {
120 ExitOnLastError(hr, "Failed to open process token.");
121 }
122
123 if (::GetTokenInformation(hToken, TokenElevationType, &elevationType, sizeof(TOKEN_ELEVATION_TYPE), &dwSize))
124 {
125 *pfPrivileged = (TokenElevationTypeFull == elevationType);
126 ExitFunction1(hr = S_OK);
127 }
128
129 // If it's invalid argument, this means they don't support TokenElevationType, and we should fallback to another check
130 er = ::GetLastError();
131 if (ERROR_INVALID_FUNCTION == er)
132 {
133 er = ERROR_SUCCESS;
134 }
135 ExitOnWin32Error(er, hr, "Failed to get process token information.");
136
137 // Fallback to this check for some OS's (like XP)
138 *pfPrivileged = ::AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup);
139 if (*pfPrivileged)
140 {
141 if (!::CheckTokenMembership(NULL, AdministratorsGroup, pfPrivileged))
142 {
143 *pfPrivileged = FALSE;
144 }
145 }
146
147LExit:
148 ReleaseSid(AdministratorsGroup);
149
150 if (hToken)
151 {
152 ::CloseHandle(hToken);
153 }
154
155 return hr;
156}
157
158extern "C" HRESULT DAPI OsIsUacEnabled(
159 __out BOOL* pfUacEnabled
160 )
161{
162 HRESULT hr = S_OK;
163 HKEY hk = NULL;
164 DWORD dwUacEnabled = 0;
165
166 *pfUacEnabled = FALSE; // assume UAC not enabled.
167
168 hr = RegOpen(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", KEY_READ, &hk);
169 if (E_FILENOTFOUND == hr)
170 {
171 ExitFunction1(hr = S_OK);
172 }
173 ExitOnFailure(hr, "Failed to open system policy key to detect UAC.");
174
175 hr = RegReadNumber(hk, L"EnableLUA", &dwUacEnabled);
176 if (E_FILENOTFOUND == hr)
177 {
178 ExitFunction1(hr = S_OK);
179 }
180 ExitOnFailure(hr, "Failed to read registry value to detect UAC.");
181
182 *pfUacEnabled = (0 != dwUacEnabled);
183
184LExit:
185 ReleaseRegKey(hk);
186
187 return hr;
188}