gpt4 book ai didi

c++ - GetTokenInformation 在 Windows XP 64 位上的意外行为

转载 作者:行者123 更新时间:2023-11-28 00:28:21 25 4
gpt4 key购买 nike

我很好奇我在理解 API 时是否遗漏了一些应该首先使用 NULL 参数调用以检索所需缓冲区大小然后在分配缓冲区后再次调用它们的内容。

我的理解是,从第一次调用到第二次调用,此缓冲区长度不会改变。 (好吧,假设我们没有处于“竞争条件”的情况,那是另一回事了。)

下面是我在 Windows XP SP2(64 位)上观察到的一个简单的真实示例。以下方法获取当前用户的SID:

HANDLE hToken;
if(OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
DWORD dwSize = 0;
if(!GetTokenInformation(hToken, TokenUser, NULL, dwSize, &dwSize) &&
::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
BYTE* pb = new (std::nothrow) BYTE[dwSize];
if(pb)
{
TOKEN_USER* pTU = (TOKEN_USER*)pb;
DWORD dwSize2;
if(GetTokenInformation(hToken, TokenUser, pTU, dwSize, &dwSize2) &&
dwSize == dwSize2)
{
LPWSTR pName;
if(ConvertSidToStringSid(pTU->User.Sid, &pName))
{
//Got it!
_tprintf(L"User SID=%s\n", pName);

LocalFree(pName);
}
}

delete[] pb;
}
}

CloseHandle(hToken);
}

我在第二次调用 GetTokenInformation 之后执行 dwSize == dwSize2 的部分,它失败了,因为 dwSize 返回为 44 来自第一次调用 GetTokenInformation,然后 dwSize2 从第二次调用返回为 36

这种行为正常吗?

最佳答案

API 在检索所需的字节大小时返回较大的值(可能出于对齐目的而四舍五入等),然后相同的 API 在检索实际大小时返回较小的值并非闻所未闻数据,因为它报告实际写入分配内存的字节数。您不必比较这两个大小,相信如果函数说它成功而不是实际成功,并且写入的大小 <= 分配的大小。

如果您担心竞争条件会改变所需的字节大小,请使用循环分配内存直到成功:

HANDLE hToken;
if (OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
BYTE* pb = NULL;
DWORD dwSize = 0;
TOKEN_USER* pTU = NULL;
BOOL bRet;

do
{
bRet = GetTokenInformation(hToken, TokenUser, pTU, dwSize, &dwSize);
if (bRet)
break;

if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
break;

delete[] pb;
pb = new (std::nothrow) BYTE[dwSize];
if (!pb)
break;

pTU = (TOKEN_USER*)pb;
}
while (true);

if (bRet)
{
// use pTU as needed...
}

delete[] pb;
CloseHandle(hToken);
}

关于c++ - GetTokenInformation 在 Windows XP 64 位上的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23976777/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com