[C++] 判断当前程序是否运行在管理员身份下

这个函数是抄自 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;
	}

 

分享到: