Closed lischach closed 10 months ago
WinSafe does perform both calls when needed, like in RegQueryValueEx
. The problem with GetTokenInformation
appears to be simply my lack of knowledge about how to properly use this function. I thought it received predetermined structures, not dynamically allocated ones, so the implementation is lacking, as far as I can see...
Can you show me an example in C, so I can fix it?
Sure. This stack overflow answer contains c++ code that calls GetTokenInformation
twice.
You can ignore the code there that calls ConvertSidToStringSid
since it's not relevant for the use case.
Attaching the relevant code from that post:
#define MAX_NAME 256
BOOL RetriveGroupSid(VOID)
{
DWORD i, dwSize = 0, dwResult = 0;
HANDLE hToken;
PTOKEN_GROUPS pGroupInfo;
SID_NAME_USE SidType;
char lpName[MAX_NAME];
char lpDomain[MAX_NAME];
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
// Open a handle to the access token for the calling process.
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
printf("OpenProcessToken Error %u\n", GetLastError());
return FALSE;
}
// Call GetTokenInformation to get the buffer size.
if (!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize))
{
dwResult = GetLastError();
if (dwResult != ERROR_INSUFFICIENT_BUFFER) {
printf("GetTokenInformation Error %u\n", dwResult);
return FALSE;
}
}
// Allocate the buffer.
pGroupInfo = (PTOKEN_GROUPS)GlobalAlloc(GPTR, dwSize);
// Call GetTokenInformation again to get the group information.
if (!GetTokenInformation(hToken, TokenGroups, pGroupInfo,
dwSize, &dwSize))
{
printf("GetTokenInformation Error %u\n", GetLastError());
return FALSE;
}
for (i = 0; i < pGroupInfo->GroupCount; i++)
{
dwSize = MAX_NAME;
LPSTR sid;
...
This was way harder to implement that I thought it would be.
The function accepts only the co::TOKEN_INFORMATION_CLASS
, then automatically allocs the proper struct, retrieves it, and returns it inside the enum, which will have the same variant. All the hard work is done inside the function, the API looks very clean to me.
An usage example can be found in the docs.
Let me know if this works for you.
There are some Windows APIs that need to be called twice in order to get them to work. For example -
GetTokenInformation
withTokenGroups
asTokenInformationClass
parameter. First time we call it with empty[out, optional] TokenInformation
in order to get the correct[out] ReturnLength
. Second time, we call it after we initialized theTOKEN_GROUPS
struct with the correct size.What is the best practice for achieving this behavior with
winsafe
crate? I took a look at GetTokenInformation implementation, but it looks like there is no way of using it withTokenGroups
as input.Am I missing anything? Is the recommended way for using these sorts of API calls, to fallback to using the
windows
orwindows-sys
crates?