使用 C++ 执行特权操作
特殊的客户端应用程序可能会调用特权操作。 例如,应用程序可允许管理员重启无响应的办公计算机。 通过使用 Windows Management Instrumentation (WMI),可以通过为特权操作调用 WMI 提供程序来执行特权操作。
以下过程介绍如何为特权操作调用提供程序。
为特权操作调用提供程序
获取客户端进程权限以执行特权操作。
通常在运行进程之前,管理员会使用系统管理工具设置权限。
获取提供程序进程权限以启用特权操作。
通常,可以通过调用 AdjustTokenPrivileges 函数来设置提供程序权限。
获取客户端进程权限以启用特权操作。
仅当提供程序是客户端的本地提供程序时,才需要执行此步骤。 如果客户端和提供程序位于同一台计算机上,客户端必须使用以下技术之一专门启用特权操作:
- 如果客户端拥有进程,则在调用 WMI 之前,客户端可使用 AdjustTokenPrivileges 调整进程令牌。 在这种情况下,无需进一步编码。
- 如果客户端无法访问客户端令牌,客户端可按照以下过程创建线程令牌并对该令牌使用 AdjustTokenPrivileges。
以下过程介绍如何创建线程令牌并对该令牌使用 AdjustTokenPrivileges。
创建线程令牌并对该令牌使用 AdjustTokenPrivileges
通过调用 ImpersonateSelf 创建进程令牌的副本。
通过调用 GetTokenInformation 检索新创建的线程令牌。
通过对新令牌调用 AdjustTokenPrivileges 启用特权操作。
获取指向 IWbemServices 的指针。
通过调用 CoSetProxyBlanket 掩蔽指向 IWbemServices 的指针。
每次调用 WMI 时都重复步骤 1 到 5。
注意
必须重复这些步骤,因为 COM 错误地缓存了令牌。
本主题中的代码示例需要以下 #include 语句才能正确编译。
#include <wbemidl.h>
以下代码示例演示如何在本地计算机上启用特权。
// Get the privileges
// The token has been obtained outside the scope of this code sample
// ==================
DWORD dwLen;
bool bRes;
HANDLE hToken;
// obtain dwLen
bRes = GetTokenInformation(
hToken,
TokenPrivileges,
NULL,
0,
&dwLen
);
BYTE* pBuffer = new BYTE[dwLen];
if(pBuffer == NULL)
{
CloseHandle(hToken);
return WBEM_E_OUT_OF_MEMORY;
}
bRes = GetTokenInformation(
hToken,
TokenPrivileges,
pBuffer,
dwLen,
&dwLen
);
if (!bRes)
{
CloseHandle(hToken);
delete [] pBuffer;
return WBEM_E_ACCESS_DENIED;
}
// Iterate through all the privileges and enable them all
// ======================================================
TOKEN_PRIVILEGES* pPrivs = (TOKEN_PRIVILEGES*)pBuffer;
for (DWORD i = 0; i < pPrivs->PrivilegeCount; i++)
{
pPrivs->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED;
}
// Store the information back in the token
// =========================================
bRes = AdjustTokenPrivileges(
hToken,
FALSE,
pPrivs,
0, NULL, NULL
);
delete [] pBuffer;
CloseHandle(hToken);
if (!bRes)
return WBEM_E_ACCESS_DENIED;
else
return WBEM_S_NO_ERROR;