Link to home
Start Free TrialLog in
Avatar of klompen
klompen

asked on

Convert SID to Hex

Hi,

Anyone has Delphi function to convert SID to Hex (string)?

What I meant with SID is the SID value of Windows account that we could retrieve using "LookupAccountName()" Win32 API.

I got some codes from here:
http://www.delphi3000.com/articles/article_3391.asp?SK=

That converts the SID to STRING.

What I want is a HEX string ... for example:

0x0105000000000005150000009C4A9809E221B876E0276300E8250000

Note that the function should be compatible with Windows 2000 and Windows 2003.

Thanks
Avatar of ChristianWimmer
ChristianWimmer
Flag of Albania image

A sid is not a number but a identifier as a string. It is saved in a variable length structure (usually a record or array) and contains the letter 'S' to identify the SID as a SID.
There are routines like ConvertStringSidToSid which support SID strings and their variable length structures. I think you should use them instead. Or do you have a very good reason to use a hex value which is also a string like the SID string?
Avatar of MichaelSteiner
MichaelSteiner

Take a look at ConvertSidToStringSid Should work from Windows 2000 to Windows 2008.
ASKER CERTIFIED SOLUTION
Avatar of klompen
klompen

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Here is a working example, Hope this helps:

function UInt64ToHex(Value: UInt64; Digits: Integer): string;
begin
 FmtStr(Result, '%.*x', [Digits, Value]);
end;

function UInt64ToHexLE(Value: UInt64; Digits: Integer): string;
var
 i,p,l : Integer;
 s : String;
begin
 FmtStr(s, '%.*x', [Digits, Value]);
 l := Length(s);
 p := l;
 SetLength(Result,l);

 repeat
  Result := Copy(s,p-1,2);
  dec(p,2);
 until p=0;
end;

function GetSIDAsHex: String;
var
 UserName : array[0..255] of Char;
 BufferLen,SidSize,DomainSize,SubAuthorities,Counter : DWORD;
 Sid : PSID;
 AccountType : SID_NAME_USE;
 Domain : array[0..1024] of Char;
 psia : Windows.PSIDIDENTIFIERAUTHORITY;
begin
 Result := 'Error';
 BufferLen := sizeof(UserName);
 DomainSize := sizeof(Domain);
 SidSize := 0;

 if GetUserName(UserName, BufferLen) = true then
  begin
   LookupAccountName(nil, UserName, Sid, SidSize, Domain, DomainSize, AccountType);
   if SidSize <> 0 then
    begin
     GetMem(Sid,SidSize);
     if LookupAccountName(nil, UserName, Sid, SidSize, Domain, DomainSize, AccountType) = true then
      if IsValidSid(Sid) = true then
       begin
        psia := GetSidIdentifierAuthority(Sid);
        SubAuthorities := GetSidSubAuthorityCount(Sid)^;
        Result := UInt64ToHex(1,2) + UInt64ToHex(SubAuthorities,2)+
            UInt64ToHex(DWORD(psia^.Value [5])+DWORD(psia^.Value [4] shl 8) +
                                          DWORD(psia^.Value [3] shl 16)+DWORD(psia^.Value [2] shl 24),12);
        for Counter := 0 to SubAuthorities - 1 do
         Result := Result + UInt64ToHex(GetSidSubAuthority(sid,Counter)^,8);
       end;
    end;
  end;
end;
Sorry for that last post. It had been awhile sine I had tried this code. Here's the corrected code:

function UInt64ToHex(Value: UInt64; Digits: Integer): string;
begin
 FmtStr(Result, '%.*x', [Digits, Value]);
end;

function UInt64ToHexLE(Value: UInt64; Digits: Integer): string;
var
 i,p,l : Integer;
 s : String;
 t : array of Char;
begin
 FmtStr(s, '%.*x', [Digits, Value]);
 l := Length(s);
 p := l;
 SetLength(t,l);
 i := 0;

 repeat
  t[i] := s[p-1];
  t[i+1] := s[p];
  inc(i,2);
  dec(p,2);
 until p=0;
 Result := String(t);
end;

function GetSIDAsHex: String;
var
 UserName : array[0..255] of Char;
 BufferLen,SidSize,DomainSize,SubAuthorities,Counter : DWORD;
 Sid : PSID;
 AccountType : SID_NAME_USE;
 Domain : array[0..1024] of Char;
 psia : Windows.PSIDIDENTIFIERAUTHORITY;
begin
 Result := 'Error';
 BufferLen := sizeof(UserName);
 DomainSize := sizeof(Domain);
 SidSize := 0;

 if GetUserName(UserName, BufferLen) = true then
  begin
   LookupAccountName(nil, UserName, Sid, SidSize, Domain, DomainSize, AccountType);
   if SidSize <> 0 then
    begin
     GetMem(Sid,SidSize);
     if LookupAccountName(nil, UserName, Sid, SidSize, Domain, DomainSize, AccountType) = true then
      if IsValidSid(Sid) = true then
       begin
        psia := GetSidIdentifierAuthority(Sid);
        SubAuthorities := GetSidSubAuthorityCount(Sid)^;
        Result := UInt64ToHex(1,2) + UInt64ToHex(SubAuthorities,2)+
            UInt64ToHex(DWORD(psia^.Value [5])+DWORD(psia^.Value [4] shl 8) +
                                          DWORD(psia^.Value [3] shl 16)+DWORD(psia^.Value [2] shl 24),12);
        for Counter := 0 to SubAuthorities - 1 do
         Result := Result + UInt64ToHexLE(GetSidSubAuthority(sid,Counter)^,8);
       end;
    end;
  end;
end;