type
PLogonUserThreadInfo = ^TLogonUserThreadInfo;
TLogonUserThreadInfo = record
Token: THandle;
Handle: THandle;
end;
function LogonUserThread(const AUserName, ADomain, APassword: string;
ALogonType: Cardinal; AThreadHandle: THandle): Pointer;
var
LLogonInfo: PLogonUserThreadInfo absolute Result;
LLogonToken: THandle;
LImpersonateToken: THandle;
begin
GetMem(LLogonInfo, SizeOf(LLogonInfo^));
try
LLogonInfo^.Token := 0;
if not OpenThreadToken(AThreadHandle, TOKEN_IMPERSONATE, True, LLogonInfo^.Token) and
(GetLastError <> ERROR_NO_TOKEN)
then
RaiseLastOSError;
try
Win32Check(LogonUser(PChar(AUserName), PChar(ADomain), PChar(APassword),
ALogonType, LOGON32_PROVIDER_DEFAULT, LLogonToken));
try
Win32Check(DuplicateToken(LLogonToken, SecurityImpersonation, @LImpersonateToken));
try
Win32Check(SetThreadToken(@AThreadHandle, LImpersonateToken));
finally
CloseHandle(LImpersonateToken);
end;
finally
CloseHandle(LLogonToken);
end;
except
CloseHandle(LLogonInfo^.Token);
raise;
end;
LLogonInfo^.Handle := AThreadHandle;
except
if LLogonInfo^.Token <> 0 then
CloseHandle(LLogonInfo^.Token);
FreeMem(LLogonInfo);
raise;
end;
end;
procedure LogoffUserThread(AData: Pointer);
var
LLogonInfo: PLogonUserThreadInfo absolute AData;
begin
try
Win32Check(SetThreadToken(@LLogonInfo^.Handle, LLogonInfo^.Token));
finally
if LLogonInfo^.Token <> 0 then
CloseHandle(LLogonInfo^.Token);
FreeMem(LLogonInfo);
end;
end;
|