diff options
Diffstat (limited to 'src/dutil/osutil.cpp')
-rw-r--r-- | src/dutil/osutil.cpp | 188 |
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 | |||
5 | OS_VERSION vOsVersion = OS_VERSION_UNKNOWN; | ||
6 | DWORD vdwOsServicePack = 0; | ||
7 | |||
8 | /******************************************************************** | ||
9 | OsGetVersion | ||
10 | |||
11 | ********************************************************************/ | ||
12 | extern "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 | |||
73 | extern "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 | |||
106 | extern "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 | |||
147 | LExit: | ||
148 | ReleaseSid(AdministratorsGroup); | ||
149 | |||
150 | if (hToken) | ||
151 | { | ||
152 | ::CloseHandle(hToken); | ||
153 | } | ||
154 | |||
155 | return hr; | ||
156 | } | ||
157 | |||
158 | extern "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 | |||
184 | LExit: | ||
185 | ReleaseRegKey(hk); | ||
186 | |||
187 | return hr; | ||
188 | } | ||