这个函数是抄自 JCL 的 IsAdministrator,我把它改成了 C++ 的版本,好象没有什么可说的,就这样吧,感谢 Jedi Project。
bool __fastcall IsAdministrator()
{
DWORD RelativeGroupID = DOMAIN_ALIAS_RID_ADMINS;
void * psidAdmin;
HANDLE Token;
DWORD Count;
PTokenGroups TokenInfo;
bool HaveToken;
OSVERSIONINFO ov;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&ov);
if (ov.dwPlatformId != VER_PLATFORM_WIN32_NT)
{
return true;
}
psidAdmin = NULL;
TokenInfo = NULL;
HaveToken = false;
try
{
Token = 0;
HaveToken = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, True,
&Token);
if ((!HaveToken) && (GetLastError() == ERROR_NO_TOKEN))
{
HaveToken = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY,
&Token);
}
if (HaveToken)
{
if (!AllocateAndInitializeSid(&NtAuthority, 2,
SECURITY_BUILTIN_DOMAIN_RID, RelativeGroupID, 0, 0, 0, 0, 0, 0,
&psidAdmin))
{
return false;
}
}
else
{
ShowMessage(SysErrorMessage(GetLastError()));
return false;
}
if (GetTokenInformation(Token, TokenGroups, NULL, 0, &Count) ||
(GetLastError() != ERROR_INSUFFICIENT_BUFFER))
{
return false;
}
TokenInfo = (PTokenGroups)AllocMem(Count);
if (!GetTokenInformation(Token, TokenGroups, TokenInfo, Count, &Count))
{
return false;
}
for (DWORD I = 0; I < TokenInfo->GroupCount; I++)
{
if (EqualSid(psidAdmin, TokenInfo->Groups[I].Sid))
{
// consider denied ACE with Administrator SID
return (TokenInfo->Groups[I]
.Attributes & SE_GROUP_USE_FOR_DENY_ONLY)
!= SE_GROUP_USE_FOR_DENY_ONLY;
}
}
}
__finally
{
if (TokenInfo)
{
FreeMemory(TokenInfo);
}
if (HaveToken)
{
CloseHandle(Token);
}
if (psidAdmin)
{
FreeSid(psidAdmin);
}
}
return false;
}
