GetTokenInformation 在第一次调用中返回 ERROR_INSUFFICIENT_BUFFER

问题描述 投票:0回答:2

从 MS 文档中我读到您应该调用 func 两次,第一次是获取令牌长度,第二次是获取其信息。我的问题是它在第一次调用时失败(错误122)但仍然写入32的长度。

const char*  CSystemHelper::ReturnUserByProcessHandle(const PROCESSENTRY32 &PENTRY) {

    HANDLE hToken, tHandle;
    DWORD ErrorCode;

    if ((tHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, PENTRY.th32ProcessID)) == 0) {
        ErrorCode = GetLastError();
        CMessage::DEFAULT_MESSAGE(ErrorCode);
        return "UNIDENTIFIED";
    }

    if (!OpenProcessToken(tHandle, TOKEN_QUERY, &hToken)) {
        ErrorCode = GetLastError();
        CMessage::DEFAULT_MESSAGE(ErrorCode);
        return "UNIDENTIFIED";
    }
    
    DWORD len = 0;
// this call fails, but len is set to 32 
    if (!GetTokenInformation(hToken, TokenOwner, NULL, 0, &len)) {
        ErrorCode = GetLastError();
        CMessage::DEFAULT_MESSAGE(ErrorCode);
        CloseHandle(hToken);
        return "UNIDENTIFIED";
    }

    PTOKEN_OWNER TOKENOWNER = (PTOKEN_OWNER)LocalAlloc(LPTR, len);

    if (!TOKENOWNER) {
        LocalFree(TOKENOWNER);
        CloseHandle(hToken);
        return "UNIDENTIFIED";
    }

    if (!GetTokenInformation(hToken, TokenOwner, TOKENOWNER, len, &len)) {
        LocalFree(TOKENOWNER);
        CloseHandle(hToken);
        return "UNIDENTIFIED";
    }

    char Username[256] = { 0 }, LocalDomain[256] = { 0 };
    DWORD UsernameLength = 256, LocalDomainLength = 256;
    SID_NAME_USE SIDNAMEUSE;

    if (!LookupAccountSidA(NULL, TOKENOWNER->Owner, Username, &UsernameLength, LocalDomain, &LocalDomainLength, &SIDNAMEUSE)){
        LocalFree(TOKENOWNER);
        CloseHandle(hToken);
        return "UNIDENTIFIED";
    }

    return Username;
}

如果重要的话,句柄是通过 processentry 打开的,不会引发任何错误

c++
2个回答
0
投票

是的。这是正常操作。

当TokenInformation参数为空时,GetTokenInformation函数返回122(ERROR_INSUFFICIENT_BUFFER)。

所以你的代码必须像这样改变。

DWORD len = 0;
// this call fails, but len is set to 32 
if (!GetTokenInformation(hToken, TokenOwner, NULL, 0, &len)) {
    ErrorCode = GetLastError();
    if (ErrorCode != ERROR_INSUFFICIENT_BUFFER || len == 0)
    {
        CMessage::DEFAULT_MESSAGE(ErrorCode);
        CloseHandle(hToken);
        return "UNIDENTIFIED";
     }
}

PTOKEN_OWNER TOKENOWNER = (PTOKEN_OWNER)LocalAlloc(LPTR, len);

if (!TOKENOWNER) {
    LocalFree(TOKENOWNER);
    CloseHandle(hToken);
    return "UNIDENTIFIED";
}

0
投票

感谢您的回复。结合 Jack Lee 和 Karsten Loop 的答案,我得出了解决方案。我尝试省略错误检查并返回用户名,但它纯粹是垃圾,所以我决定使用 std::string 而不是 c 风格的字符数组,一切正常。

© www.soinside.com 2019 - 2024. All rights reserved.