implemented IsTokenRestricted(), inspired by a patch to winehq by James Hawkins
Modified: trunk/reactos/lib/advapi32/advapi32.def
Modified: trunk/reactos/lib/advapi32/token/token.c

Modified: trunk/reactos/lib/advapi32/advapi32.def
--- trunk/reactos/lib/advapi32/advapi32.def	2005-06-17 09:46:21 UTC (rev 15957)
+++ trunk/reactos/lib/advapi32/advapi32.def	2005-06-17 09:46:29 UTC (rev 15958)
@@ -319,7 +319,7 @@
 InitiateSystemShutdownW@20
 ;InstallApplication
 IsTextUnicode@12=NTDLL.RtlIsTextUnicode
-;IsTokenRestricted
+IsTokenRestricted@4
 ;IsTokenUntrusted
 IsValidAcl@4
 IsValidSecurityDescriptor@4

Modified: trunk/reactos/lib/advapi32/token/token.c
--- trunk/reactos/lib/advapi32/token/token.c	2005-06-17 09:46:21 UTC (rev 15957)
+++ trunk/reactos/lib/advapi32/token/token.c	2005-06-17 09:46:29 UTC (rev 15958)
@@ -401,4 +401,71 @@
   return Result;
 }
 
+BOOL STDCALL
+IsTokenRestricted(HANDLE TokenHandle)
+{
+  ULONG RetLength;
+  PTOKEN_GROUPS lpGroups;
+  NTSTATUS Status;
+  BOOL Ret = FALSE;
+  
+  /* determine the required buffer size and allocate enough memory to read the
+     list of restricted SIDs */
+
+  Status = NtQueryInformationToken(TokenHandle,
+                                   TokenRestrictedSids,
+                                   NULL,
+                                   0,
+                                   &RetLength);
+  if (Status != STATUS_BUFFER_TOO_SMALL)
+  {
+    SetLastError(RtlNtStatusToDosError(Status));
+    return FALSE;
+  }
+  
+AllocAndReadRestrictedSids:
+  lpGroups = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
+                                      0,
+                                      RetLength);
+  if (lpGroups == NULL)
+  {
+    SetLastError(ERROR_OUTOFMEMORY);
+    return FALSE;
+  }
+  
+  /* actually read the list of the restricted SIDs */
+  
+  Status = NtQueryInformationToken(TokenHandle,
+                                   TokenRestrictedSids,
+                                   lpGroups,
+                                   RetLength,
+                                   &RetLength);
+  if (NT_SUCCESS(Status))
+  {
+    Ret = (lpGroups->GroupCount != 0);
+  }
+  else if (Status == STATUS_BUFFER_TOO_SMALL)
+  {
+    /* looks like the token was modified in the meanwhile, let's just try again */
+
+    HeapFree(GetProcessHeap(),
+             0,
+             lpGroups);
+
+    goto AllocAndReadRestrictedSids;
+  }
+  else
+  {
+    SetLastError(RtlNtStatusToDosError(Status));
+  }
+  
+  /* free allocated memory */
+
+  HeapFree(GetProcessHeap(),
+           0,
+           lpGroups);
+
+  return Ret;
+}
+
 /* EOF */