共用方式為


使用 C++ 執行特殊許可權作業

特殊用戶端應用程式可能會叫用特殊許可權作業。 例如,應用程式可讓管理員重新啟動沒有響應的辦公室電腦。 藉由使用 Windows Management Instrumentation(WMI),您可以透過呼叫 WMI 提供者來執行特權操作。

下列程式描述如何呼叫特殊許可權作業的提供者。

要呼叫執行特殊權限操作的提供者

  1. 取得用戶端程序執行特權操作的許可權。

    一般而言,系統管理員會先使用系統管理工具來設定許可權,再執行進程。

  2. 取得允許提供者程序啟用特權操作的權限。

    一般而言,您可以使用呼叫 AdjustTokenPrivileges 函式來設定提供者許可權。

  3. 取得用戶端程序執行高權限操作所需的許可權。

    只有在提供者位於用戶端本地時,才需要此步驟。 如果用戶端和提供者存在於同一部計算機上,客戶端必須使用下列其中一種技術來特別啟用特殊許可權作業:

    • 如果客戶端擁有進程,用戶端可以使用 AdjustTokenPrivileges,在呼叫 WMI 之前調整進程令牌。 在此情況下,您不需要再撰寫任何程序代碼。
    • 如果客戶端無法存取用戶端令牌,用戶端可以使用下列程式來建立線程令牌,並使用該令牌上的 AdjustTokenPrivileges

下列程序說明如何建立線程令牌,並在該令牌上使用 AdjustTokenPrivileges

若要建立線程令牌,並在該令牌上使用 AdjustTokenPrivileges

  1. 呼叫 ImpersonateSelf,以創建該進程令牌的副本。

  2. 呼叫 GetTokenInformation,以擷取新建立的線程令牌。

  3. 在新的令牌上,以呼叫 AdjustTokenPrivileges 啟用特殊許可權作業。

  4. 取得 IWbemServices指標。

  5. 使用對 CoSetProxyBlanket的呼叫來遮蔽 IWbemServices 指標

  6. 在每個對 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;