Einzelnen Beitrag anzeigen

Scorpion3000

Registriert seit: 18. Apr 2004
47 Beiträge
 
Delphi 7 Enterprise
 
#1

Den aktiven Benutzer bzw Status des Benutzers bekommen

  Alt 29. Nov 2005, 11:03
Hallo Leute!

Hab in diesem Forum leider noch nichts zu diesem Thema gefunden. In mühevoller Kleinarbeit hab ich mir den Code selber zusammen gebaut:

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 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 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:= nil;
   //Auflisten der LogOnSessions
   i1:= lsaNtStatusToWinError(LsaEnumerateLogonSessions(@Count, @List));
   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);
                if LookupAccountSID(nil, sessionData.SID, OwnerName,
                   SizeNeeded, DomainName, SizeNeeded2, OwnerType) then begin
                   if OwnerType = 1 then begin
                      //Wenn Benutzer verbunden
                      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;
                   end;
                end;
             end;
             inc(List);
         until (i1 = Count-1) or (result <> nil);
      end;
   end;
end;
Vielleicht entdeckt noch irgend jemand einen Fehler bzw kennt eine bessere Methode.
Ich hoff ich kann jemandem damit helfen!

Mfg Scorpion 3000
  Mit Zitat antworten Zitat