BOOL TokenCheckPrivilege()

in PPLGuard/utils.cpp [527:609]


BOOL TokenCheckPrivilege(HANDLE hToken, LPCWSTR pwszPrivilege, BOOL bEnablePrivilege)
{
	BOOL bReturnValue = FALSE;
	DWORD dwTokenPrivilegesSize = 0, i = 0, dwPrivilegeNameLength = 0;
	PTOKEN_PRIVILEGES pTokenPrivileges = NULL;
	LUID_AND_ATTRIBUTES laa = { 0 };
	TOKEN_PRIVILEGES tp = { 0 };
	LPWSTR pwszPrivilegeNameTemp = NULL;

	if (!GetTokenInformation(hToken, TokenPrivileges, NULL, dwTokenPrivilegesSize, &dwTokenPrivilegesSize))
	{
		if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
		{
			PrintLastError(L"GetTokenInformation");
			goto end;
		}
	}

	pTokenPrivileges = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, dwTokenPrivilegesSize);
	if (!pTokenPrivileges)
		goto end;

	if (!GetTokenInformation(hToken, TokenPrivileges, pTokenPrivileges, dwTokenPrivilegesSize, &dwTokenPrivilegesSize))
	{
		PrintLastError(L"GetTokenInformation");
		goto end;
	}

	for (i = 0; i < pTokenPrivileges->PrivilegeCount; i++)
	{
		laa = pTokenPrivileges->Privileges[i];
		dwPrivilegeNameLength = 0;

		if (!LookupPrivilegeName(NULL, &(laa.Luid), NULL, &dwPrivilegeNameLength))
		{
			if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
			{
				PrintLastError(L"LookupPrivilegeName");
				goto end;
			}
		}

		dwPrivilegeNameLength++;

		if (pwszPrivilegeNameTemp = (LPWSTR)LocalAlloc(LPTR, dwPrivilegeNameLength * sizeof(WCHAR)))
		{
			if (LookupPrivilegeName(NULL, &(laa.Luid), pwszPrivilegeNameTemp, &dwPrivilegeNameLength))
			{
				if (!_wcsicmp(pwszPrivilegeNameTemp, pwszPrivilege))
				{
					if (bEnablePrivilege)
					{
						ZeroMemory(&tp, sizeof(TOKEN_PRIVILEGES));
						tp.PrivilegeCount = 1;
						tp.Privileges[0].Luid = laa.Luid;
						tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

						if (AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))
							bReturnValue = TRUE;
						else
							PrintLastError(L"AdjustTokenPrivileges");
					}
					else
					{
						bReturnValue = TRUE;
					}

					break;
				}
			}
			else
				PrintLastError(L"LookupPrivilegeName");

			LocalFree(pwszPrivilegeNameTemp);
		}
	}

end:
	if (pTokenPrivileges)
		LocalFree(pTokenPrivileges);

	return bReturnValue;
}