Search code examples
delphifreepascallazarus

How to get Windows user privileges information with Lazarus/Free Pascal


Using Lazarus/Free Pascal, how can I get the user privileges of the user running my program (whether he's an Administrator, Regular user, or Guest)?


Solution

  • As David says in a comment you can use the CheckTokenMembership function to determine the membership of an user account.

    check this sample which runs on FPC and Delphi.

    program Test;
    
    {$IFDEF FPC}
      {$mode objfpc}{$H+}
    {$ELSE}
      {$APPTYPE CONSOLE}
    {$ENDIF}
    
    uses
      SysUtils,
      Windows,
      Classes;
    
    Const
     SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
     SECURITY_BUILTIN_DOMAIN_RID = $00000020;
     DOMAIN_ALIAS_RID_ADMINS     = $00000220;
     DOMAIN_ALIAS_RID_USERS      = $00000221;
     DOMAIN_ALIAS_RID_GUESTS     = $00000222;
     DOMAIN_ALIAS_RID_POWER_USERS= $00000223;
    
     function CheckTokenMembership(TokenHandle: THandle; SidToCheck: PSID; var IsMember: BOOL): BOOL; stdcall; external advapi32;
    
     function  UserInGroup(Group :DWORD) : Boolean;
     var
      pIdentifierAuthority :TSIDIdentifierAuthority;
      pSid : Windows.PSID;
      IsMember    : BOOL;
     begin
      pIdentifierAuthority := SECURITY_NT_AUTHORITY;
      Result := AllocateAndInitializeSid(pIdentifierAuthority,2, SECURITY_BUILTIN_DOMAIN_RID, Group, 0, 0, 0, 0, 0, 0, pSid);
      try
        if Result then
          if not CheckTokenMembership(0, pSid, IsMember) then //passing 0 means which the function will be use the token of the calling thread.
             Result:= False
          else
             Result:=IsMember;
      finally
         FreeSid(pSid);
      end;
     end;
    
    
    begin
     Writeln(Format('Current user is Admin        %s',[BoolToStr(UserInGroup(DOMAIN_ALIAS_RID_ADMINS),True)]));
     Writeln(Format('Current user is Guest        %s',[BoolToStr(UserInGroup(DOMAIN_ALIAS_RID_GUESTS),True)]));
     Writeln(Format('Current user is Power User   %s',[BoolToStr(UserInGroup(DOMAIN_ALIAS_RID_POWER_USERS),True)]));
     readln;
    end.
    

    Also you can use the WMI , check the Win32_UserAccount, Win32_GroupUser and Win32_Group classes.