GetTokenInformation()第一次调用。 做什么的?

查看GetDokenInformation()的 MSDN文档和获取loginSID示例,GetTokenInformation()需要被调用两次。 第一个调用是获取缓冲区大小。

那么,缓冲区大小是什么? 只要说我使用TokenUser作为第二个参数,我看到由第一次调用返回的dwReturnLength不是TOKEN_USER结构的大小。

提前致谢

TOKEN_USER结构包含指针(特别是指向本身具有可变长度的SID的指针)。 这些指针必须指向某个地方。 API函数将期望一个足够大的缓冲区来存放不仅TOKEN_USER结构,而且还包含所有结构指向的东西。 该函数告诉你它需要多少内存。 它将全部驻留在相邻的存储器中。

第二个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; } 

看看最后三个参数:

TokenInformation [out,可选]

指向缓冲区的指针填充请求的信息。 放入此缓冲区的结构取决于TokenInformationClass参数指定的信息类型。

TokenInformationLength [in]

指定由TokenInformation参数指向的缓冲区的大小(以字节为单位)。 如果TokenInformation为NULL,则此参数必须为零。

ReturnLength [out]

指向一个变量的指针,该变量接收TokenInformation参数指向的缓冲区所需的字节数。 如果此值大于TokenInformationLength参数中指定的值,则该函数将失败并将任何数据存储在缓冲区中。

如果TokenInformationClass参数的值是TokenDefaultDacl并且该标记没有默认的DACL,则该函数将ReturnLength指向的变量设置为sizeof(TOKEN_DEFAULT_DACL),并将TOKEN_DEFAULT_DACL结构的DefaultDacl成员设置为NULL。

由于您不知道参数2需要传递多大的缓冲区,因此您需要查询API的确切大小。 然后你通过一个足够大的缓冲区并取回你想要的信息。

你总是可以猜测缓冲区的大小,它可能会工作。

请注意,这是一个典型的Win32 APIs。 它有助于一劳永逸地得到这个成语。

在结构中嵌入的是一个长度可变的SID,所以缓冲区的大小将取决于将被包含在结果中的SID的大小。

如果你的缓冲区足够大,你可以在第一个调用中做这个工作。 大多数使用这些方法的代码将首先尝试使用固定大小的缓冲区,然后在调用指示需要更多内存时分配更大的缓冲区。