unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TfMain = class(TForm)
    mm: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  fMain: TfMain;

  Sid : PSID;
  UName, Domain, StringSid : PWideChar;
  NameSize      : Cardinal = 200;
  SidSize       : Cardinal = 200;
  DomainSize    : Cardinal = 200;
  StringSidSize : Cardinal = 200;

const
  SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority =
    (Value: (0, 0, 0, 0, 0, 5));
  SECURITY_BUILTIN_DOMAIN_RID = $00000020;
  DOMAIN_ALIAS_RID_ADMINS = $00000220;

function ConvertSidToStringSidW(Sid : PSID; var StringSid : PWideChar):Boolean;stdcall;external 'advapi32.dll';
//function ConvertStringSidToSid(StringSid : PWideChar; var Sid : PSID):Boolean;stdcall;external 'advapi32.dll';

implementation

{$R *.dfm}

procedure GetSIDForUser(lpName : PWideChar);
var peUse : Cardinal;
begin
  if not LookupAccountName(nil, lpName, Sid, SidSize, Domain, DomainSize, peUse)
    and (GetLastError = ERROR_INSUFFICIENT_BUFFER)
  then begin
    ReAllocMem(Sid, SidSize);
    ReAllocMem(Domain, DomainSize * SizeOf(WideChar));
    if not LookupAccountName(nil, lpName, Sid, SidSize, Domain, DomainSize, peUse)
      then MessageBox(0, PWideChar(SysErrorMessage(GetLastError)), 'Error', MB_OK);
  end;
end;

procedure GetUserNameBySID(Sid : PSID);
var peUse : Cardinal;
begin
  if not LookupAccountSid(nil, Sid, UName, NameSize, Domain, DomainSize, peUse)
    and (GetLastError = ERROR_INSUFFICIENT_BUFFER)
  then begin
    ReAllocMem(UName, NameSize * SizeOf(WideChar));
    ReAllocMem(Domain, DomainSize * SizeOf(WideChar));
    if not LookupAccountSid(nil, Sid, UName, NameSize, Domain, DomainSize, peUse)
      then MessageBox(0, PWideChar(SysErrorMessage(GetLastError)), 'Error', MB_OK);
  end;
end;

function IsAdmin: Boolean;
var
  hAccessToken: THandle;
  ptgGroups: PTokenGroups;
  dwInfoBufferSize: DWORD;
  psidAdministrators: PSID;
  i: Integer;
  bSuccess: BOOL;
begin
  Result := false;
  bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, hAccessToken);
  if bSuccess then begin
    GetMem(ptgGroups, 1024);
    bSuccess := GetTokenInformation(hAccessToken, TokenGroups,
      ptgGroups, 1024, dwInfoBufferSize);
    CloseHandle(hAccessToken);
    if bSuccess then begin
      AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
        SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
        0, 0, 0, 0, 0, 0, psidAdministrators);
      for i := 0 to ptgGroups.GroupCount - 1 do
        if EqualSid(psidAdministrators, ptgGroups.Groups[i].Sid) then begin
          Result := True;
          Break;
        end;
      FreeSid(psidAdministrators);
    end;
    FreeMem(ptgGroups);
  end;
end;

procedure TfMain.FormCreate(Sender: TObject);
var S : string;
begin
 GetMem(Sid, SidSize);
 GetMem(Domain, DomainSize * SizeOf(WideChar));
 GetMem(StringSid, StringSidSize);

 GetSidForUser('IC');
 ConvertSidToStringSidW(Sid, StringSid);
 mm.Lines.Add('Рядкове представлення SID користувача IC: ');
 mm.Lines.Add(StringSid);
 mm.Lines.Add('');

 GetUserNameBySID(Sid);
 mm.Lines.Add('Назва користувача для SID ' + StringSid + ': ' + UName);
 mm.Lines.Add('');

 FreeMem(Sid);
 Freemem(Domain);
 FreeMem(UName);
// FreeMem(StringSid);

 if IsAdmin then S := 'Запущено з правами адміністратора' else
   S := 'Прав адміністратора немає';
 mm.Lines.Add(S);
 mm.Lines.Add('');
end;

end.
