共用方式為


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

特殊用戶端應用程式可能會叫用特殊許可權作業。 例如,應用程式可讓經理重新開機沒有回應的辦公室電腦。 藉由使用 Windows Management Instrumentation (WMI) ,您可以呼叫 WMI 提供者以執行特殊許可權作業。

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

呼叫特殊許可權作業的提供者

  1. 取得用戶端進程執行特殊許可權作業的許可權。

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

  2. 取得提供者進程的許可權,以啟用特殊許可權作業。

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

  3. 取得用戶端進程的許可權,以啟用特殊許可權作業。

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

    • 如果用戶端擁有進程,用戶端可以使用 AdjustTokenPrivileges 來調整進程權杖,再呼叫 WMI。 在此情況下,您不需要進一步撰寫程式碼。
    • 如果用戶端無法存取用戶端權杖,用戶端可以使用下列程式來建立執行緒權杖,並在該權杖上使用 AdjustTokenPrivileges

下列程式描述如何建立執行緒權杖,並在該權杖上使用 AdjustTokenPrivileges

若要建立執行緒權杖,並在該權杖上使用 AdjustTokenPrivileges

  1. 呼叫 ImpersonateSelf以建立進程權杖的複本。

  2. 呼叫 GetTokenInformation以擷取新建立的執行緒權杖。

  3. 啟用特殊許可權作業,並在新的權杖上呼叫 AdjustTokenPrivileges

  4. 取得 IWbemServices 的指標。

  5. Cloak IWbemServices 的指標,並呼叫 CoSetProxyBlanket

  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;