从 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 打开的,不会引发任何错误
是的。这是正常操作。
当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";
}
感谢您的回复。结合 Jack Lee 和 Karsten Loop 的答案,我得出了解决方案。我尝试省略错误检查并返回用户名,但它纯粹是垃圾,所以我决定使用 std::string 而不是 c 风格的字符数组,一切正常。