[1536] | 1 | #include "gsPlatform.h"
|
---|
| 2 |
|
---|
| 3 | #define ACCESS_READ 0x01
|
---|
| 4 | #define ACCESS_WRITE 0x02
|
---|
| 5 |
|
---|
[1541] | 6 | #include <stdio.h>
|
---|
| 7 |
|
---|
[1536] | 8 | gsPlatform::gsPlatform()
|
---|
[1763] | 9 | { this->platformInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
---|
| 10 | if (!GetVersionEx(&this->platformInfo))
|
---|
| 11 | {
|
---|
| 12 | }
|
---|
[1536] | 13 | }
|
---|
| 14 |
|
---|
| 15 | bool gsPlatform::isWindows9x()
|
---|
[1543] | 16 | {
|
---|
[1763] | 17 | return (this->platformInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
|
---|
[1536] | 18 | }
|
---|
| 19 |
|
---|
| 20 | bool gsPlatform::isWindowsNT()
|
---|
[1543] | 21 | {
|
---|
[1763] | 22 | return (this->platformInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
|
---|
[1536] | 23 | }
|
---|
| 24 |
|
---|
| 25 | bool gsPlatform::isWindows32s()
|
---|
[1543] | 26 | {
|
---|
[1763] | 27 | return (this->platformInfo.dwPlatformId == VER_PLATFORM_WIN32s);
|
---|
[1536] | 28 | }
|
---|
| 29 |
|
---|
| 30 | bool gsPlatform::isOldWindows32s()
|
---|
[1763] | 31 | {
|
---|
[1543] | 32 | if (this->platformInfo.dwMajorVersion == 0 ||
|
---|
| 33 | this->platformInfo.dwMinorVersion < 30)
|
---|
| 34 | {
|
---|
| 35 | return true;
|
---|
| 36 | }
|
---|
[1536] | 37 | return false;
|
---|
| 38 | }
|
---|
| 39 |
|
---|
| 40 | bool gsPlatform::isExplorerShell()
|
---|
[1543] | 41 | {
|
---|
| 42 | if (this->isWindows9x() ||
|
---|
| 43 | (this->isWindowsNT() && this->platformInfo.dwMajorVersion >= 4))
|
---|
| 44 | {
|
---|
| 45 | return true;
|
---|
| 46 | }
|
---|
[1536] | 47 | return false;
|
---|
| 48 | }
|
---|
| 49 |
|
---|
| 50 | bool gsPlatform::isUserAdministrator()
|
---|
[1541] | 51 | {
|
---|
[1536] | 52 | if (this->isWindowsNT())
|
---|
| 53 | {
|
---|
| 54 | HANDLE token;
|
---|
| 55 | PSID adminId;
|
---|
| 56 | PACL aclData;
|
---|
[1541] | 57 | PSECURITY_DESCRIPTOR psdAdmin = NULL;
|
---|
| 58 | SID_IDENTIFIER_AUTHORITY systemSidAuthority = SECURITY_NT_AUTHORITY;
|
---|
[1536] | 59 | GENERIC_MAPPING genericMapping;
|
---|
| 60 | PRIVILEGE_SET privilegeSet;
|
---|
[1541] | 61 | DWORD aclSize, accessMask, status, structureSize;
|
---|
[1536] | 62 | BOOL result;
|
---|
| 63 |
|
---|
| 64 | // Get an impersonation token
|
---|
| 65 | ImpersonateSelf(SecurityImpersonation);
|
---|
| 66 |
|
---|
| 67 | if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &token))
|
---|
| 68 | {
|
---|
| 69 | if (GetLastError() != ERROR_NO_TOKEN)
|
---|
[1541] | 70 | {
|
---|
[1536] | 71 | return false;
|
---|
| 72 | }
|
---|
| 73 |
|
---|
| 74 | // if we didn't have an access token, take the process token instead
|
---|
| 75 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
|
---|
[1541] | 76 | {
|
---|
[1536] | 77 | return false;
|
---|
| 78 | }
|
---|
| 79 | }
|
---|
| 80 |
|
---|
| 81 | // By now we have a valid process/thread token; now get information on the
|
---|
| 82 | // admin group in this domain
|
---|
| 83 | if (!AllocateAndInitializeSid(&systemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
|
---|
| 84 | DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
|
---|
| 85 | &adminId))
|
---|
[1541] | 86 | {
|
---|
[1536] | 87 | return false;
|
---|
| 88 | }
|
---|
| 89 |
|
---|
| 90 | // allocate space for security descriptor
|
---|
| 91 | psdAdmin = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
|
---|
| 92 | if (psdAdmin == NULL)
|
---|
| 93 | {
|
---|
| 94 | return false;
|
---|
| 95 | }
|
---|
| 96 |
|
---|
| 97 | // initialise descriptor
|
---|
| 98 | if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION))
|
---|
| 99 | {
|
---|
| 100 | return false;
|
---|
| 101 | }
|
---|
| 102 |
|
---|
| 103 | // get ACL size and allocate ACL block
|
---|
| 104 | aclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(adminId) - sizeof(DWORD);
|
---|
| 105 | aclData = (PACL) LocalAlloc(LPTR, aclSize);
|
---|
| 106 | if (aclData == NULL)
|
---|
| 107 | {
|
---|
| 108 | return false;
|
---|
| 109 | }
|
---|
| 110 |
|
---|
| 111 | // initalise the acl block
|
---|
| 112 | if (!InitializeAcl(aclData, aclSize, ACL_REVISION2))
|
---|
[1541] | 113 | {
|
---|
[1536] | 114 | return false;
|
---|
| 115 | }
|
---|
[1543] | 116 |
|
---|
| 117 | accessMask = ACCESS_READ | ACCESS_WRITE;
|
---|
| 118 |
|
---|
[1536] | 119 | // try to add the given item to the Access Control Entry (ACE) list (ACL)
|
---|
[1541] | 120 | if (!AddAccessAllowedAce(aclData, ACL_REVISION2, accessMask, adminId))
|
---|
| 121 | {
|
---|
[1536] | 122 | return false;
|
---|
| 123 | }
|
---|
[1543] | 124 |
|
---|
[1536] | 125 | // endeavour to add the acl to the discretionary acl (DACL)
|
---|
| 126 | if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, aclData, FALSE))
|
---|
| 127 | {
|
---|
| 128 | return false;
|
---|
| 129 | }
|
---|
| 130 |
|
---|
| 131 | // endeavour to set the owner/group identification
|
---|
| 132 | SetSecurityDescriptorGroup(psdAdmin, adminId, FALSE);
|
---|
| 133 | SetSecurityDescriptorOwner(psdAdmin, adminId, FALSE);
|
---|
| 134 |
|
---|
| 135 | // right, we've now built up a discretionary acl on the current user,
|
---|
| 136 | // finally get the generic mapping ready
|
---|
| 137 | genericMapping.GenericRead = ACCESS_READ;
|
---|
| 138 | genericMapping.GenericWrite = ACCESS_WRITE;
|
---|
| 139 | genericMapping.GenericExecute = 0;
|
---|
| 140 | genericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE;
|
---|
| 141 |
|
---|
[1541] | 142 | structureSize = sizeof(PRIVILEGE_SET);
|
---|
| 143 |
|
---|
[1536] | 144 | // do the actual access check
|
---|
| 145 | if (!AccessCheck (psdAdmin, token, ACCESS_READ, &genericMapping,
|
---|
| 146 | &privilegeSet, &structureSize, &status, &result))
|
---|
[1543] | 147 | {
|
---|
| 148 | return false;
|
---|
[1536] | 149 | }
|
---|
[1543] | 150 |
|
---|
[1536] | 151 | // end impersonisation
|
---|
| 152 | RevertToSelf();
|
---|
[1543] | 153 |
|
---|
[1541] | 154 | LocalFree(psdAdmin);
|
---|
| 155 | LocalFree(aclData);
|
---|
| 156 | FreeSid(adminId);
|
---|
[1878] | 157 | return (result != 0);
|
---|
[1536] | 158 | }
|
---|
| 159 | return true;
|
---|
| 160 | }
|
---|
| 161 |
|
---|
| 162 | bool gsPlatform::reboot()
|
---|
| 163 | {
|
---|
| 164 | // Check for appropriate privileges if this is NT
|
---|
| 165 | if (this->isWindowsNT())
|
---|
| 166 | {
|
---|
| 167 | HANDLE token;
|
---|
| 168 | TOKEN_PRIVILEGES tkp;
|
---|
[1543] | 169 |
|
---|
[1536] | 170 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
---|
| 171 | &token))
|
---|
[1541] | 172 | {
|
---|
[1536] | 173 | return false;
|
---|
| 174 | }
|
---|
[1543] | 175 |
|
---|
[1536] | 176 | LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
|
---|
| 177 |
|
---|
| 178 | tkp.PrivilegeCount = 1; // set one privilege
|
---|
| 179 | tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
---|
| 180 |
|
---|
| 181 | // Get the actual shutdown privilege
|
---|
| 182 | AdjustTokenPrivileges(token, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
|
---|
| 183 |
|
---|
| 184 | // as we can't test a return value on the previous call, use GetLastError
|
---|
| 185 | if (GetLastError() != ERROR_SUCCESS)
|
---|
| 186 | {
|
---|
| 187 | return false;
|
---|
| 188 | }
|
---|
| 189 | }
|
---|
[1878] | 190 | return (ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0) != 0);
|
---|
[1536] | 191 | }
|
---|
| 192 |
|
---|
| 193 | string gsPlatform::platformString()
|
---|
| 194 | {
|
---|
| 195 | if (this->isWindowsNT())
|
---|
| 196 | {
|
---|
| 197 | return gsPlatform_WINDOWSNT;
|
---|
| 198 | }
|
---|
| 199 | else if (this->isWindows9x())
|
---|
| 200 | {
|
---|
| 201 | return gsPlatform_WINDOWS9X;
|
---|
| 202 | }
|
---|
| 203 | else if (this->isWindows32s())
|
---|
| 204 | {
|
---|
| 205 | return gsPlatform_WINDOWS32S;
|
---|
| 206 | }
|
---|
| 207 | else
|
---|
| 208 | {
|
---|
| 209 | return gsPlatform_WINDOWS;
|
---|
| 210 | }
|
---|
| 211 | }
|
---|