判断是否以管理员身份权限运行的C++代码源码

本篇文章属于《518抽奖软件开发日志》系列文章的一部分。

我在开发《518抽奖软件》(www.518cj.net)的时候,有时候需要判断,进程是否以管理员身份权限运行。网上找了一些代码,很多不能用或不全面,现整理代码如下。

BOOL Tfuns::is_userAdmin()
{
	return is_admin(FALSE);
}
BOOL Tfuns::is_runasAdmin()
{
	return is_admin(TRUE);
}

static BOOL is_admin(BOOL CheckTokenForGroupDeny)
{
	WCHAR  *pGroup = NULL;
	HANDLE  hToken = NULL;
	struct group
	{
		DWORD auth_id;
		WCHAR *name;
	};
	struct group groups[] =
	{
		{ DOMAIN_ALIAS_RID_USERS, L"User" },
		{ DOMAIN_ALIAS_RID_GUESTS, L"Guest" },
		{ DOMAIN_ALIAS_RID_POWER_USERS, L"Power" },
		{ DOMAIN_ALIAS_RID_ADMINS, L"Admin" }
	};
	if (GetVersion() & 0x80000000) return TRUE;  //Not NT

	if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken) ||
		OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
	{
		SID_IDENTIFIER_AUTHORITY SystemSidAuthority = { SECURITY_NT_AUTHORITY };
		TOKEN_GROUPS* ptg = NULL;
		BOOL       ValidTokenGroups = FALSE;
		DWORD      cbTokenGroups;
		DWORD      i, j;

		if (CheckTokenForGroupDeny)
			pCheckTokenMembership = (CHECKTOKENMEMBERSHIP)GetProcAddress(GetModuleHandle(L"ADVAPI32"), "CheckTokenMembership");

		if (!CheckTokenForGroupDeny || pCheckTokenMembership == NULL)
		{
			if (!GetTokenInformation(hToken, TokenGroups, NULL, 0, &cbTokenGroups) &&
				GetLastError() == ERROR_INSUFFICIENT_BUFFER)
			{
				if ((ptg = (TOKEN_GROUPS*)GlobalAlloc(GPTR, cbTokenGroups)) &&
					GetTokenInformation(hToken, TokenGroups, ptg, cbTokenGroups, &cbTokenGroups))
				{
					ValidTokenGroups = TRUE;
				}
			}
		}

		if (ValidTokenGroups || (CheckTokenForGroupDeny && pCheckTokenMembership))
		{
			PSID psid;
			for (i = 0; i < sizeof(groups) / sizeof(struct group); i++)
			{
				if (AllocateAndInitializeSid(&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
					groups[i].auth_id, 0, 0, 0, 0, 0, 0, &psid))
				{
					BOOL IsMember = FALSE;
					if (CheckTokenForGroupDeny && pCheckTokenMembership)
						pCheckTokenMembership(0, psid, &IsMember);
					else if (ValidTokenGroups)
					{
						for (j = 0; j < ptg->GroupCount; j++)
						{
							if (EqualSid(ptg->Groups[j].Sid, psid)) IsMember = TRUE;
						}
					}
					if (IsMember) pGroup = groups[i].name;
					FreeSid(psid);
				}
			}//for groups
		}
		if (ptg) GlobalFree(ptg);
		CloseHandle(hToken);

		if (pGroup && _wcsicmp(pGroup, L"Admin") == 0) return TRUE;
		else return FALSE;
	}
	return FALSE;
}

你可能感兴趣的:(技术文章,c++)