如何从TOKEN_INFORMATION_CLASS获取PSID?

rsk*_*k82 3 c++ winapi sid

我尝试使用这篇文章中的信息:https://stackoverflow.com/a/251267/393087

我想出的代码是:

HANDLE hToken;
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES, &hToken);
DWORD dwSize;
TOKEN_INFORMATION_CLASS tokenInformationClass;
GetTokenInformation(hToken, tokenInformationClass, NULL, sizeof(TOKEN_INFORMATION_CLASS), &dwSize);
Run Code Online (Sandbox Code Playgroud)

好了,我得到了TOKEN_INFORMATION_CLASS,但如何从这个得到PSID那个ConvertSidToStringSid()需要?PSIDtic手册页中没有任何字数(http://msdn.microsoft.com/en-us/library/windows/desktop/aa379626(v=vs.85).aspx).

0xC*_*22L 8

实际上,这是微不足道的.选择你想要的任何令牌信息类(我猜你想要的TokenUser),然后确保你传递匹配的TOKEN_USER结构GetTokenInformation,然后到达TOKEN_USER结构来访问TOKEN_USER::User::Sid获取PSID.

当然,您可能还需要另一个令牌信息类,但原理是相同的.完整的示例程序(.cpp在MSVC中编译为文件):

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif                      
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <Sddl.h> // for ConvertSidToStringSid()

BOOL printTokenUserSid(HANDLE hToken)
{
    PTOKEN_USER ptu = NULL;
    DWORD dwSize = 0;
    if(!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize)
        && ERROR_INSUFFICIENT_BUFFER != GetLastError())
    {
        return FALSE;
    }
    if(NULL != (ptu = (PTOKEN_USER)LocalAlloc(LPTR, dwSize)))
    {
        LPTSTR StringSid = NULL;
        if(!GetTokenInformation(hToken, TokenUser, ptu, dwSize, &dwSize))
        {
            LocalFree((HLOCAL)ptu);
            return FALSE;
        }
        if(ConvertSidToStringSid(ptu->User.Sid, &StringSid))
        {
            _tprintf(_T("%s\n"), StringSid);
            LocalFree((HLOCAL)StringSid);
            LocalFree((HLOCAL)ptu);
            return TRUE;
        }
        LocalFree((HLOCAL)ptu);
    }
    return FALSE;
}

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hToken = NULL;
    if(OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken)
        || OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
    {
        if(!printTokenUserSid(hToken))
        {
            _tprintf(_T("Something failed, Win32 error: %d\n"), GetLastError());
        }
        CloseHandle(hToken);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 实际上它稍微复杂一点,因为传递给GetTokenInformation()的缓冲区需要足够大以容纳SID(TOKEN_USER只有足够的空间来指向SID). (2认同)