class function TUserInfo.GetCurrentUserSID: PSID;
var
LToken: THandle;
begin
Win32Check(OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, LToken));
try
Result := CreateUserSID(LToken);
finally
CloseHandle(LToken);
end;
end;
class procedure TUserInfo.GetUserName(ASID: PSID; out ADomain, AUser: string);
var
LError: Cardinal;
LUserLen: Cardinal;
LDomainLen: Cardinal;
LUse: SID_NAME_USE;
begin
LUserLen := 0;
LDomainLen := 0;
LookupAccountSid(nil, ASID, nil, LUserLen, nil, LDomainLen, LUse);
LError := GetLastError;
if LError <> ERROR_INSUFFICIENT_BUFFER then
RaiseLastOSError(LError);
if LUserLen > 0 then begin
SetLength(AUser, LUserLen - 1);
SetLength(ADomain, LDomainLen - 1);
Win32Check(LookupAccountSid(nil, ASID, PChar(AUser), LUserLen, PChar(ADomain), LDomainLen, LUse));
end else begin
ADomain := '';
AUser := SIDToString(ASID);
end;
end;
function TUserInfo.GetFullQualifiedUserName: string;
begin
Result := GetFullQualifiedUserName(SID);
end;
class function TUserInfo.GetFullQualifiedUserName(ASID: PSID): string;
var
LDomain, LUser: string;
begin
GetUserName(ASID, LDomain, LUser);
Result := LDomain + '\' + LUser;
end;
function TUserInfo.GetLocalGroups: TArray<string>;
var
LErr: NET_API_STATUS;
LBuf: PByte;
LCurBuf: PLOCALGROUP_USERS_INFO_0;
LRead, LTotal: Cardinal;
Li: Cardinal;
begin
LErr := NetUserGetLocalGroups(
nil, PChar(GetFullQualifiedUserName),
0,
LG_INCLUDE_INDIRECT,
LBuf,
MAX_PREFERRED_LENGTH,
@LRead,
@LTotal
);
if LErr <> ERROR_SUCCESS then
RaiseLastOSError(LErr);
try
SetLength(Result, LRead);
if LRead <> 0 then begin
LCurBuf := PLOCALGROUP_USERS_INFO_0(LBuf);
for Li := 0 to LRead - 1 do begin
Result[Li] := LCurBuf^.lgrui0_name;
Inc(LCurBuf);
end;
end;
finally
NetApiBufferFree(LBuf);
end;
end;
|