GetTokenInformation()首先调用。做什么的?

时间:2010-09-08 18:52:21

标签: c++ c windows delphi winapi

查看GetTokenInformation()Getting the Logon SID示例的MSDN文档,需要调用GetTokenInformation()两次。第一个调用是获取缓冲区大小。

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

提前致谢

5 个答案:

答案 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)

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