Einzelnen Beitrag anzeigen

Benutzerbild von Manzoni
Manzoni

Registriert seit: 15. Feb 2004
Ort: Berlin
120 Beiträge
 
Delphi 7 Enterprise
 
#1

Den aktiven Benutzer bzw Status des Benutzers bekommen

  Alt 20. Apr 2007, 13:25
Das Problem den aktiven Benutzer unter WinXP aus einem Dienst heraus zu ermitteln wurde hier besprochen. Ich habe den Speicherfehler des Codes behoben:

Delphi-Quellcode:
const
  WTS_CURRENT_SERVER_HANDLE = 0;

type
  PTOKEN_USER = ^TOKEN_USER;
  _TOKEN_USER = record
    User: TSidAndAttributes;
  end;
  TOKEN_USER = _TOKEN_USER;

  USHORT = word;
    
  _LSA_UNICODE_STRING = record
    Length: USHORT;
    MaximumLength: USHORT;
    Buffer: LPWSTR;
  end;
  LSA_UNICODE_STRING = _LSA_UNICODE_STRING;

  PLuid = ^LUID;
  _LUID = record
    LowPart: DWORD;
    HighPart: LongInt;
  end;
  LUID = _LUID;
  
  _SECURITY_LOGON_TYPE = (
    seltFiller0, seltFiller1,
    Interactive,
    Network,
    Batch,
    Service,
    Proxy,
    Unlock,
    NetworkCleartext,
    NewCredentials,
    RemoteInteractive,
    CachedInteractive,
    CachedRemoteInteractive);
  SECURITY_LOGON_TYPE = _SECURITY_LOGON_TYPE;

  PSECURITY_LOGON_SESSION_DATA = ^SECURITY_LOGON_SESSION_DATA;
  _SECURITY_LOGON_SESSION_DATA = record
    Size: ULONG;
    LogonId: LUID;
    UserName: LSA_UNICODE_STRING;
    LogonDomain: LSA_UNICODE_STRING;
    AuthenticationPackage: LSA_UNICODE_STRING;
    LogonType: SECURITY_LOGON_TYPE;
    Session: ULONG;
    Sid: PSID;
    LogonTime: LARGE_INTEGER;
    LogonServer: LSA_UNICODE_STRING;
    DnsDomainName: LSA_UNICODE_STRING;
    Upn: LSA_UNICODE_STRING;
  end;
  SECURITY_LOGON_SESSION_DATA = _SECURITY_LOGON_SESSION_DATA;

  _WTS_INFO_CLASS = (
    WTSInitialProgram,
    WTSApplicationName,
    WTSWorkingDirectory,
    WTSOEMId,
    WTSSessionId,
    WTSUserName,
    WTSWinStationName,
    WTSDomainName,
    WTSConnectState,
    WTSClientBuildNumber,
    WTSClientName,
    WTSClientDirectory,
    WTSClientProductId,
    WTSClientHardwareId,
    WTSClientAddress,
    WTSClientDisplay,
    WTSClientProtocolType);
  WTS_INFO_CLASS = _WTS_INFO_CLASS;

  _WTS_CONNECTSTATE_CLASS = (
    WTSActive, // User logged on to WinStation
    WTSConnected, // WinStation connected to client
    WTSConnectQuery, // In the process of connecting to client
    WTSShadow, // Shadowing another WinStation
    WTSDisconnected, // WinStation logged on without client
    WTSIdle, // Waiting for client to connect
    WTSListen, // WinStation is listening for connection
    WTSReset, // WinStation is being reset
    WTSDown, // WinStation is down due to error
    WTSInit); // WinStation in initialization
  WTS_CONNECTSTATE_CLASS = _WTS_CONNECTSTATE_CLASS;

  function LsaFreeReturnBuffer(Buffer: pointer): Integer; stdcall;

  function WTSGetActiveConsoleSessionId: DWORD; external 'Kernel32.dll';

  function LsaGetLogonSessionData(LogonId: PLUID;
     var ppLogonSessionData: PSECURITY_LOGON_SESSION_DATA): LongInt; stdcall;
     external 'Secur32.dll';

  function LsaNtStatusToWinError(Status: cardinal): ULONG; stdcall;
     external 'Advapi32.dll';

  function LsaEnumerateLogonSessions(Count: PULONG; List: PLUID): LongInt;
     stdcall; external 'Secur32.dll';

  function WTSQuerySessionInformationA(hServer: THandle; SessionId: DWORD;
     WTSInfoClass: WTS_INFO_CLASS; var pBuffer: Pointer;
     var pBytesReturned: DWORD): BOOL; stdcall; external 'Wtsapi32.dll';

implementation

{$R *.dfm} 

function LsaFreeReturnBuffer; external 'secur32.dllname 'LsaFreeReturnBuffer';

function GetActiveUserName: string;
var
   Count: cardinal;
   List: PLUID;
   sessionData: PSECURITY_LOGON_SESSION_DATA;
   i1: integer;
   SizeNeeded, SizeNeeded2: DWORD;
   OwnerName, DomainName: PChar;
   OwnerType: SID_NAME_USE;
   pBuffer: Pointer;
   pBytesreturned: DWord;
begin
   result:= '';
   //Auflisten der LogOnSessions
   i1:= lsaNtStatusToWinError(LsaEnumerateLogonSessions(@Count, @List));
   try
      if i1 = 0 then
      begin
          i1:= -1;
          if Count > 0 then
          begin
              repeat
                inc(i1);
                LsaGetLogonSessionData(List, sessionData);
                //Wenn es sich um einen interaktive LogOnSession handelt
                if sessionData.LogonType = Interactive then
                begin
                    //Prufen ob es sich um einen Benutzer handelt
                    SizeNeeded := MAX_PATH;
                    SizeNeeded2:= MAX_PATH;
                    GetMem(OwnerName, MAX_PATH);
                    GetMem(DomainName, MAX_PATH);
                    try
                    if LookupAccountSID(nil, sessionData.SID, OwnerName,
                                       SizeNeeded, DomainName,SizeNeeded2,
                                       OwnerType) then
                    begin
                      if OwnerType = 1 then
                      begin
                          //Wenn Benutzer an lokaler console angemeldet
                          //unter Windows NT 4.0 und Windows 2000 ist die SessionID
                          //der Konsole immer "0"
                          if sessionData.Session = WTSGetActiveConsoleSessionId then
                          begin
                            //Wenn Benutzer aktiv
                            try
                                if WTSQuerySessionInformationA
                                   (WTS_CURRENT_SERVER_HANDLE,
                                    sessionData.Session, WTSConnectState,
                                    pBuffer,
                                    pBytesreturned) then
                                begin
                                    if WTS_CONNECTSTATE_CLASS(pBuffer^) = WTSActive then
                                        result:= sessionData.UserName.Buffer;
                                end;
                            finally
                              LSAFreeReturnBuffer(pBuffer);
                            end;
                          end;
                      end;
                    end;
                    finally
                    FreeMem(OwnerName);
                    FreeMem(DomainName);
                    end;
                end;
                inc(List);
                try
                    LSAFreeReturnBuffer(sessionData);
                except
                end;
            until (i1 = Count-1) or (result <> '');
          end;
      end;
   finally
      LSAFreeReturnBuffer(List);
   end;
end;
Bob
  Mit Zitat antworten Zitat