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 | } | ||
