0,0 → 1,159 |
(******************************************************************************) |
(* SPGetSid - Retrieve the current user's SID in text format *) |
(* *) |
(* Copyright (c) 2004 Shorter Path Software *) |
(* http://www.shorterpath.com *) |
(******************************************************************************) |
|
|
{ |
SID is a data structure of variable length that identifies user, group, |
and computer accounts. |
Every account on a network is issued a unique SID when the account is first created. |
Internal processes in Windows refer to an account's SID |
rather than the account's user or group name. |
} |
|
|
unit SPGetSid; |
|
interface |
|
uses |
Windows, SysUtils; |
|
function GetCurrentUserSid: string; |
|
implementation |
|
const |
HEAP_ZERO_MEMORY = $00000008; |
SID_REVISION = 1; // Current revision level |
|
type |
PTokenUser = ^TTokenUser; |
TTokenUser = packed record |
User: TSidAndAttributes; |
end; |
|
function ConvertSid(Sid: PSID; pszSidText: PChar; var dwBufferLen: DWORD): BOOL; |
var |
psia: PSIDIdentifierAuthority; |
dwSubAuthorities: DWORD; |
dwSidRev: DWORD; |
dwCounter: DWORD; |
dwSidSize: DWORD; |
begin |
Result := False; |
|
dwSidRev := SID_REVISION; |
|
if not IsValidSid(Sid) then Exit; |
|
psia := GetSidIdentifierAuthority(Sid); |
|
dwSubAuthorities := GetSidSubAuthorityCount(Sid)^; |
|
dwSidSize := (15 + 12 + (12 * dwSubAuthorities) + 1) * SizeOf(Char); |
|
if (dwBufferLen < dwSidSize) then |
begin |
dwBufferLen := dwSidSize; |
SetLastError(ERROR_INSUFFICIENT_BUFFER); |
Exit; |
end; |
|
StrFmt(pszSidText, 'S-%u-', [dwSidRev]); |
|
if (psia.Value[0] <> 0) or (psia.Value[1] <> 0) then |
StrFmt(pszSidText + StrLen(pszSidText), |
'0x%.2x%.2x%.2x%.2x%.2x%.2x', |
[psia.Value[0], psia.Value[1], psia.Value[2], |
psia.Value[3], psia.Value[4], psia.Value[5]]) |
else |
StrFmt(pszSidText + StrLen(pszSidText), |
'%u', |
[DWORD(psia.Value[5]) + |
DWORD(psia.Value[4] shl 8) + |
DWORD(psia.Value[3] shl 16) + |
DWORD(psia.Value[2] shl 24)]); |
|
dwSidSize := StrLen(pszSidText); |
|
for dwCounter := 0 to dwSubAuthorities - 1 do |
begin |
StrFmt(pszSidText + dwSidSize, '-%u', |
[GetSidSubAuthority(Sid, dwCounter)^]); |
dwSidSize := StrLen(pszSidText); |
end; |
|
Result := True; |
end; |
|
function ObtainTextSid(hToken: THandle; pszSid: PChar; |
var dwBufferLen: DWORD): BOOL; |
var |
dwReturnLength: DWORD; |
dwTokenUserLength: DWORD; |
tic: TTokenInformationClass; |
ptu: Pointer; |
begin |
Result := False; |
dwReturnLength := 0; |
dwTokenUserLength := 0; |
tic := TokenUser; |
ptu := nil; |
|
if not GetTokenInformation(hToken, tic, ptu, dwTokenUserLength, |
dwReturnLength) then |
begin |
if GetLastError = ERROR_INSUFFICIENT_BUFFER then |
begin |
ptu := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwReturnLength); |
if ptu = nil then Exit; |
dwTokenUserLength := dwReturnLength; |
dwReturnLength := 0; |
|
if not GetTokenInformation(hToken, tic, ptu, dwTokenUserLength, |
dwReturnLength) then Exit; |
end |
else |
Exit; |
end; |
|
if not ConvertSid((PTokenUser(ptu).User).Sid, pszSid, dwBufferLen) then Exit; |
|
if not HeapFree(GetProcessHeap, 0, ptu) then Exit; |
|
Result := True; |
end; |
|
function GetCurrentUserSid: string; |
var |
hAccessToken: THandle; |
bSuccess: BOOL; |
dwBufferLen: DWORD; |
szSid: array[0..260] of Char; |
begin |
Result := ''; |
|
bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, |
hAccessToken); |
if not bSuccess then |
begin |
if GetLastError = ERROR_NO_TOKEN then |
bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, |
hAccessToken); |
end; |
if bSuccess then |
begin |
ZeroMemory(@szSid, SizeOf(szSid)); |
dwBufferLen := SizeOf(szSid); |
|
if ObtainTextSid(hAccessToken, szSid, dwBufferLen) then |
Result := szSid; |
CloseHandle(hAccessToken); |
end; |
end; |
|
end. |