TechTricks
Technical answers from the trenches 
 
 
 
 

     
   
Detecting Administrator Privileges
 
   
 Posted: 1 June 2001
 
   
 
 Applies to: Delphi 2.0 and later
 
   
 
Audience: Intermediate
 
       
   

Question: How do I determine if the user has Administrator privileges under Windows 2000/NT?

Answer: This is not a completely intuitive process, however, it can be done by combining a few different Windows API functions, as shown in the following code sample:

function IsAdmin: Boolean;
{ -------------------------------------------------------------
  Returns a boolean indicating whether or not user has admin
  privileges. (Call only then running under NT.)

  ------------------------------------------------------------- }
var
  hAccessToken       : tHandle;
  ptgGroups          : pTokenGroups;
  dwInfoBufferSize   : DWORD;
  psidAdministrators : PSID;
  int                : integer;            // counter
  blnResult          : boolean;            // return flag

const
 SECURITY_NT_AUTHORITY: SID_IDENTIFIER_AUTHORITY =
    (Value: (0,0,0,0,0,5)); // ntifs
 SECURITY_BUILTIN_DOMAIN_RID: DWORD = $00000020;
 DOMAIN_ALIAS_RID_ADMINS: DWORD = $00000220;
 DOMAIN_ALIAS_RID_USERS : DWORD = $00000221;
 DOMAIN_ALIAS_RID_GUESTS: DWORD = $00000222;
 DOMAIN_ALIAS_RID_POWER_: DWORD = $00000223;

begin
  Result := False;
  blnResult := OpenThreadToken( GetCurrentThread, TOKEN_QUERY,
                                True, hAccessToken );
  if ( not blnResult ) then
  begin
    if GetLastError = ERROR_NO_TOKEN then
    blnResult := OpenProcessToken( GetCurrentProcess,
    				   TOKEN_QUERY, hAccessToken );
  end;

  if ( blnResult ) then
  try

    GetMem(ptgGroups, 1024);
    blnResult := GetTokenInformation( hAccessToken, TokenGroups,
                                      ptgGroups, 1024,
                                      dwInfoBufferSize );
    CloseHandle( hAccessToken );

    if ( blnResult ) then
    begin

      AllocateAndInitializeSid( SECURITY_NT_AUTHORITY, 2,
                                SECURITY_BUILTIN_DOMAIN_RID,
                                DOMAIN_ALIAS_RID_ADMINS,
        			0, 0, 0, 0, 0, 0,
        			psidAdministrators );
      {$R-}
      for int := 0 to ptgGroups.GroupCount - 1 do

        if EqualSid( psidAdministrators,
                     ptgGroups.Groups[ int ].Sid ) then
        begin
          Result := True;
          Break;
        end;
      {$R+}

      FreeSid( psidAdministrators );
    end;

  finally
    FreeMem( ptgGroups );
  end;
end;

This is based on Borland's Community Article #26752. Unfortunately, that article fails to define the constants shown above. In addition, we've reworked it slightly to ensure that the memory allocated for the process gets released.

Also, note that this function should only be called when you're sure you're running under Windows 2000/NT. For example, consider the following code (which assumes you're also using the isWinNT() function presented in another article):

   if ( isWinNT() ) then
   begin
      if ( not isAdmin() ) then
         showWarning( 'Not the Admin' )
      else
         doAdminOnlyTask();
   end;

If you run this under Win9.x, it returns false.

Why would I use this?

By and large, there aren't many cases where you'll need to know if users have administrator privileges. Starting with Windows 2000, however, it's possible to prevent users from certain activities, such as installing software. We've used this function in a installation program to determine whether or not the users can actually install the software. In turn, this has prevented certain support calls that end with, "Well, I'm sorry. You'll have to work this out with your system administrator."

If you know of other ways to use this function, we would appreciate hearing about them. Please send feedback through the link presented at the bottom of the page.

 

       

Top

Feedback About Paradox Delphi Assorted Web Stuff
 
 
Copyright © 2000-2004, techtricks.com; All Rights Reserved.
Acknowledgements, Disclaimers, Terms and Conditions.
Article last updated on 31 May 2003

 

Other Sites: Paradox, Delphi, Perl, Web Stuff, and More


 

[- End -]