2010-08-23 60 views

回答

-1

你可以試試這段代碼。它給出了需要做什麼樣的草圖:

const HANDLE hProcess = GetCurrentProcess(); 
if (hProcess==NULL) 
    return FAILURE; 

HANDLE hToken; 
const BOOL lR = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken); 
if (lR == NULL) 
    return FAILURE; 

PSID psidAdministrators; 
SID_IDENTIFIER_AUTHORITY x = SECURITY_NT_AUTHORITY; 
if (!AllocateAndInitializeSid(
    &x, 2, 
    SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, 
    &psidAdministrators)) 
    return FAILURE; 

bool isAdmin = false; //dummy init 
DWORD size; 
GetTokenInformation(hToken, TokenGroups, NULL, 0, &size); 
char* buffer = new char[size]; 
DWORD notUsed; 
if (!GetTokenInformation(hToken, TokenGroups, (void*)buffer, size, &notUsed)) 
    return FAILURE; 

TOKEN_GROUPS* ptgGroups = (TOKEN_GROUPS*)buffer; 
isAdmin = false; //until proven otherwise 
for (UINT32 i=0; i<ptgGroups->GroupCount; ++i) 
{ 
    if (EqualSid(psidAdministrators, ptgGroups->Groups[i].Sid)) 
    { 
     isAdmin = true; 
     break; 
    } 
} 

FreeSid(psidAdministrators); 
return isAdmin; 
+0

此代碼是檢查SID是否是用戶令牌的一部分的NT4方法,它在新系統上無法正常工作,因此不應使用。請參閱Rup的SO鏈接以獲取我的答案以及調用哪個函數... – Anders 2010-08-23 16:38:14

+0

@Anders:當然,它可以在Windows XP,Windows Vista和Windows 7上運行。這些代碼在這三個系統上進行了相當廣泛的測試。你爲什麼認爲這行不通? – 2010-08-24 06:17:12

+1

我知道它壞了,所以你只是沒有正確測試。有一種叫做拒絕SID的東西,而你當前的代碼並不處理這些,你應該使用CheckTokenMembership。 – Anders 2010-08-24 11:50:17

2

此代碼可解決您的問題。隨意使用它。它適用於SE_GROUP_USE_FOR_DENY_ONLY。

/** 
    IsGroupMember determines if the current thread or process has a token that contais a given and enabled user group. 

    Parameters 
    dwRelativeID: Defines a relative ID (par of a SID) of a user group (e.g. Administrators DOMAIN_ALIAS_RID_ADMINS (544) = S-1-5-32-544) 
    bProcessRelative: Defines whether to use the process token (TRUE) instead of the thread token (FALSE). If FALSE and no thread token is present 
    the process token will be used though. 
    bIsMember: Returns the result of the function. The value returns TRUE if the user is an enabled member of the group; otherwise FALSE. 

    Return Value 
    If the function succeeds, the return value is TRUE; otherwise FALSE. Call GetLastError for more information. 
*/ 
BOOL IsGroupMember(DWORD dwRelativeID, BOOL bProcessRelative, BOOL* pIsMember) 
{ 
    HANDLE hToken, hDupToken; 
    PSID pSid = NULL; 
    SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_NT_AUTHORITY; 

    if (!pIsMember) 
    { 
     SetLastError(ERROR_INVALID_USER_BUFFER); 
     return FALSE; 
    } 

    if (bProcessRelative || !OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_DUPLICATE, TRUE, &hToken)) 
    { 
     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &hToken)) 
     { 
      return FALSE; 
     } 
    } 

    if (!DuplicateToken(hToken, SecurityIdentification, &hDupToken)) 
    { 
     CloseHandle(hToken); 
     return FALSE; 
    } 

    CloseHandle(hToken); 
    hToken = hDupToken; 

    if (!AllocateAndInitializeSid(&SidAuthority, 2, 
      SECURITY_BUILTIN_DOMAIN_RID, dwRelativeID, 0, 0, 0, 0, 0, 0, 
      &pSid)) 
    { 
     CloseHandle(hToken); 
     return FALSE; 
    } 

    if (!CheckTokenMembership(hToken, pSid, pIsMember)) 
    { 
     CloseHandle(hToken); 
     FreeSid(pSid); 

     *pIsMember = FALSE; 
     return FALSE; 
    } 

    CloseHandle(hToken); 
    FreeSid(pSid); 

    return TRUE; 
} 

BOOL IsUserAdministrator(BOOL* pIsAdmin) 
{ 
    return IsGroupMember(DOMAIN_ALIAS_RID_ADMINS, FALSE, pIsAdmin); 
} 
相關問題