Einzelnen Beitrag anzeigen

virus82

Registriert seit: 29. Jun 2007
Ort: Leipzig
34 Beiträge
 
Delphi 2009 Professional
 
#1

LsaEnumerateLogonSessions gibt nicht eingeloggte User in Liste aus

  Alt 6. Jan 2012, 10:41
Hallo,

ich hab ein Problem mit LsaEnumerateLogonSessions. Ich hab hier das Forum schon durchwühlt und war froh, als ich Informationen gefunden habe, wie ich die eingeloggten User Sessions auflisten kann. Das habe ich dann mit Hilfe des Forums und der MSDN umgesetzt und vorerst auch keinen Fehler festgestellt.

Dann musste ich allerdings feststellen, das nicht immer das richtige Ergebniss ausgegeben wird. Und zwar immer dann wenn ein User (Benutzer1) sich anmeldet, abmeldet und ein anderer User (Benutzer2) sich anmeldet. Wenn Benutzer2 jetzt mein Programm ausführt, liefert mir LsaEnumerateLogonSessions auch noch Benutzer1 in der Liste mit.

Kann man mit LsaEnumerateLogonSessions auch herausbekommen welche User sich abgemeldet haben? Ich dachte es werden nur die angemeldeten User angezeigt.

Hier mein Code (in meinem Formular nutze ich AllocConsole um mit WriteLn die Infos ausgeben zu lassen:

Delphi-Quellcode:

uses
  Windows, SysUtils;

type
  PLuid = ^LUID;
  _LUID = record
    LowPart: DWORD;
    HighPart: LongInt;
  end;
  LUID = _LUID;

  USHORT = Word;

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

  _SECURITY_LOGON_TYPE = (
    Interactive = 2,
    Network,
    Batch,
    Service,
    Proxy,
    Unlock,
    NetworkCleartext,
    NewCredentials,
    RemoteInteractive,
    CachedInteractive,
    CachedRemoteInteractive);
  SECURITY_LOGON_TYPE = _SECURITY_LOGON_TYPE;
  TSecurityLogonType = 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;
  TSecurityLogonSessionData = SECURITY_LOGON_SESSION_DATA;

function LsaNtStatusToWinError(Status: cardinal): ULONG; stdcall; external 'Advapi32.dll';
function LsaEnumerateLogonSessions(LogonSessionCount: PULONG; LogonSessionList: PLUID): LongInt; stdcall; external 'Secur32.dll';
function LsaGetLogonSessionData(LogonId: PLUID; var ppLogonSessionData: PSECURITY_LOGON_SESSION_DATA): ULONG; stdcall; external 'Secur32.dll';
function LsaFreeReturnBuffer(Buffer: Pointer): ULONG; stdcall; external 'Secur32.dll';

implementation

...


procedure TForm1.Button3Click(Sender: TObject);
var
   iRes: Integer;
   Count: Cardinal;
   List: PLUID;
   Test: LUID;
   SessionData: PSECURITY_LOGON_SESSION_DATA;
   i: Integer;
   tc64: Int64;
   ldt: TDateTime;
   SIDInfo: TSIDInfo;
begin
  // based on
  // http://www.delphipraxis.net/90606-den-aktiven-benutzer-bzw-status-des-benutzers-bekommen.html

  // get list of sessions
  iRes:= LsaNtStatusToWinError(LsaEnumerateLogonSessions(@Count, @List));
  // check result of list
  if (iRes = ERROR_SUCCESS) then
  begin
    // no error
    // check count of list
    if (Count > 0) then
    begin
      // min 1 session
      WriteLn(Format('Count: %d', [Count]));
      WriteLn('');
      // enumerate list
      for i := 0 to Count - 1 do
      begin
        // for each item in list get session data
        iRes := LsaNtStatusToWinError(LsaGetLogonSessionData(List, SessionData));
        // test, display item in list, also if result is not successfull
        Test := List^;
        Writeln(Format('Session %d: %u %u', [i, Test.LowPart, Test.HighPart]));
        // check result of sessiondata
        if (iRes = ERROR_SUCCESS) then
        begin
          // only interactive users
          if SessionData.LogonType in [Interactive] then
          begin
            // write infos
            WriteLn(Format(' LogonId: %d', [Int64(SessionData.LogonId)]));
            WriteLn(Format(' UserName: %s', [String(SessionData.UserName.Buffer)]));
            WriteLn(Format(' LogonDomain: %s', [String(SessionData.LogonDomain.Buffer)]));
            WriteLn(Format(' Session: %d', [SessionData.Session]));
            WriteLn(Format(' SID: %s %s', [SIDToName(SessionData.Sid), SIDToStrSID(SessionData.Sid)]));
            WriteLn(Format(' LogonServer: %s', [String(SessionData.LogonServer.Buffer)]));
            WriteLn(Format(' LogonType: %d', [Integer(SessionData.LogonType)]));
            tc64 := GetTickCount64;
            ldt := FileTimeToDateTime(SessionData.LogonTime);
            WriteLn(Format(' LogonTime: DateTime: %s Unix: %u', [DateTimeToStr(ldt), DateTimeToUnixTrunc(ldt)]));
            WriteLn(Format(' TickCount: ms: %u', [tc64]));
            // get sid info
            if GetSIDInfo(SessionData.Sid, SIDInfo) then
            begin
              // is user
              if (SIDInfo.SIDType = SidTypeUser) then
              begin
                // write sid infos
                WriteLn(Format(' SIDInfo.Name: %s', [SIDInfo.Name]));
                WriteLn(Format(' SIDInfo.ReferenceDomainName: %s', [SIDInfo.ReferenceDomainName]));
                WriteLn(Format(' SIDInfo.SIDType: %u', [Integer(SIDInfo.SIDType)]));
              end;
            end;
          end;
          // free sessiondata
          iRes := LsaNtStatusToWinError(LsaFreeReturnBuffer(SessionData));
          if (iRes <> ERROR_SUCCESS) then
          begin
            // error free sessiondata
            WriteLn(SysErrorMessage(iRes));
          end;
        end else
        begin
          // error sessiondata
          WriteLn(SysErrorMessage(iRes));
        end;
        // space
        WriteLn('');
        // inc list
        Inc(List);
      end;
    end else
    begin
      // no sessions found
      WriteLn('No Sessions');
    end;
    // free list
    iRes := LsaNtStatusToWinError(LsaFreeReturnBuffer(List));
    if (iRes <> ERROR_SUCCESS) then
    begin
      // error free list
      WriteLn(SysErrorMessage(iRes));
    end;
  end else
  begin
    // error list sessions
    WriteLn(SysErrorMessage(iRes));
  end;
end;
Im Anhang das Ergebnis der Console, wo beide User angezeigt werden. Ich möchte gern nur das Ergebnis aus dem TaskManager haben, der nur die angemeldeten User anzeigt.

Kann mir jemand helfen oder mir Erklären was da LsaEnumerateLogonSessions macht. Ich habe LsaEnumerateLogonSessions genommen, da ich mit LsaGetLogonSessionData auch die LogOn Zeit ermitteln kann. Jetzt müsste ich nur noch alle aktiven Sessions herausfiltern. Nur wie???

Nachvollziehen kann ich das unter WinXP SP3 und Win7 SP1 mit Delphi 2009.

Gruß, Marco.
Miniaturansicht angehängter Grafiken
console.jpg   taskmgr.jpg  
Marco

Geändert von virus82 ( 6. Jan 2012 um 11:30 Uhr)
  Mit Zitat antworten Zitat