GetTokenInformation() first call. What for?
Looking at MSDN documentaion for GetTokenInformation() and the Getting the Logon SID example, GetTokenInformation() needs t开发者_JAVA技巧o be called twice. The first call is to get the buffer size.
So, buffer size of what? Just say I use TokenUser as its second parameter, I see that the dwReturnLength returned by first call is not the size of TOKEN_USER structure.
Thanks in advance
The TOKEN_USER
structure contains pointers (in particular, a pointer to a SID
that itself has variable length). Those pointers have to point somewhere. The API function will expect a buffer big enough to hold not only the the TOKEN_USER
structure, but also all the things that structure points to. The function tells you how much memory it needs for everything. It will all reside in adjacent memory.
The full example from your second URL should make it clear that how the length returned from the first call is used. You use this to allocate raw memory of that size - here this is the variable ptg
- and cast it to PTOKEN_GROUPS for use in the second call.
// 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;
}
Look at the last three parameters:
TokenInformation [out, optional]
A pointer to a buffer the function fills with the requested information. The structure put into this buffer depends upon the type of information specified by the TokenInformationClass parameter.
TokenInformationLength [in]
Specifies the size, in bytes, of the buffer pointed to by the TokenInformation parameter. If TokenInformation is NULL, this parameter must be zero.
ReturnLength [out]
A pointer to a variable that receives the number of bytes needed for the buffer pointed to by the TokenInformation parameter. If this value is larger than the value specified in the TokenInformationLength parameter, the function fails and stores no data in the buffer.
If the value of the TokenInformationClass parameter is TokenDefaultDacl and the token has no default DACL, the function sets the variable pointed to by ReturnLength to sizeof(TOKEN_DEFAULT_DACL) and sets the DefaultDacl member of the TOKEN_DEFAULT_DACL structure to NULL.
Since you don't know how big a buffer you need to pass for parameter #2, you need to query the API for the exact size. And then you pass-in a sufficiently large buffer and get back the information you want.
You could always guess the buffer size and it may work.
Note that this is a typical of Win32 APIs. It helps to get this idiom right once and for all.
Imbedded in the structure is a SID which is variable length, so the buffer size will depend on the size of the SID that will be included in the result.
You can make this work in the first call if your buffer is large enough. Most code that use these methods will try first with a fixed size buffer and then allocate a larger buffer if the call indicated that it needs more memory.
精彩评论