查看GetTokenInformation()和Getting the Logon SID示例的MSDN文档,需要调用GetTokenInformation()两次。第一个调用是获取缓冲区大小。
那么,缓冲区大小是什么?只是说我使用TokenUser作为它的第二个参数,我看到第一次调用返回的dwReturnLength不是TOKEN_USER结构的大小。提前致谢
答案 0 :(得分:8)
TOKEN_USER
结构包含指针(特别是指向SID
的指针,它本身具有可变长度)。那些指针必须指向某个地方。 API函数将期望一个足够大的缓冲区,不仅可以容纳TOKEN_USER
结构,还可以容纳结构所指向的所有内容。该函数告诉您所有内容需要多少内存。它将全部驻留在相邻的内存中。
答案 1 :(得分:4)
第二个URL中的完整示例应该清楚说明如何使用第一次调用返回的长度。您可以使用它来分配该大小的原始内存 - 这里是变量ptg
- 并将其转换为PTOKEN_GROUPS以便在第二次调用中使用。
// Get required buffer size and allocate the TOKEN_GROUPS buffer.
if (!GetTokenInformation(
hToken, // handle to the access token
TokenGroups, // get information about the token's groups
(LPVOID) ptg, // pointer to TOKEN_GROUPS buffer
0, // size of buffer
&dwLength // receives required buffer size
))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
goto Cleanup;
ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, dwLength);
if (ptg == NULL)
goto Cleanup;
}
// Get the token group information from the access token.
if (!GetTokenInformation(
hToken, // handle to the access token
TokenGroups, // get information about the token's groups
(LPVOID) ptg, // pointer to TOKEN_GROUPS buffer
dwLength, // size of buffer
&dwLength // receives required buffer size
))
{
goto Cleanup;
}
答案 2 :(得分:4)
查看最后三个参数:
TokenInformation [out,optional]
指向缓冲区的指针,该函数填充所请求的信息。 结构放入此缓冲区 取决于信息的类型 由TokenInformationClass指定 参数。
TokenInformationLength [in]
指定由其指向的缓冲区的大小(以字节为单位) TokenInformation参数。如果 TokenInformation是NULL,这个 参数必须为零。
ReturnLength [out]
指向接收所需字节数的变量的指针 对于指向的缓冲区 TokenInformation参数。如果这 value大于该值 在...中指定 TokenInformationLength参数, 功能失败并且不存储任何数据 缓冲区。
如果TokenInformationClass参数的值是 TokenDefaultDacl和令牌没有 默认DACL,该函数设置 ReturnLength指向的变量 sizeof(TOKEN_DEFAULT_DACL)和设置 的DefaultDacl成员 TOKEN_DEFAULT_DACL结构为NULL。
由于您不知道需要为参数#2传递多大的缓冲区,因此您需要查询API以获取确切的大小。然后你传入一个足够大的缓冲区并获取你想要的信息。
您总是可以猜测缓冲区大小,它可能会起作用。
请注意,这是典型的Win32 API。它有助于让这个成语一劳永逸。
答案 3 :(得分:3)
结构中嵌入的是一个可变长度的SID,因此缓冲区大小将取决于结果中包含的SID的大小。
答案 4 :(得分:1)
如果缓冲区足够大,您可以在第一次调用时使其工作。大多数使用这些方法的代码将首先使用固定大小的缓冲区,然后在调用指示需要更多内存时分配更大的缓冲区。