如何检查我的程序是否由用户以管理员身份运行(Vista/Win7、C++)

发布于 2024-09-15 09:49:11 字数 45 浏览 6 评论 0原文

我看到 IsInRole 方法,但找不到有关如何在 C++ 中使用它的信息。

I saw IsInRole method but I can't find information on how to use it with C++.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

迷你仙 2024-09-22 09:49:11

这个旧答案中有一个 C++ 代码片段来自 CodePlex 上的 UACHelpers 项目。

There's a C++ code snippet in this old answer taken from the UACHelpers project on CodePlex.

旧街凉风 2024-09-22 09:49:11

这段代码解决了你的问题。请随意使用它。它适用于 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);
}

This code solves your problem. Feel free to use it. It works with 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);
}
泪是无色的血 2024-09-22 09:49:11

IsUSerAnAdmin 的文档解释说,它是自 Vista 起已弃用,但会引导您访问 CheckTokenMembership。这应该适合你。

The documentation of IsUSerAnAdmin explains that it's deprecated since Vista, but points you to CheckTokenMembership. That should do the job for you.

滥情空心 2024-09-22 09:49:11

你可以尝试一下这段代码。它给出了需要做什么的草图:

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, ¬Used))
    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;

You might try this piece of code. It gives a sketch of what needs to be done:

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, ¬Used))
    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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文