Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi LsaGetLogonSessionData - Zugriffsverletzung (https://www.delphipraxis.net/157822-lsagetlogonsessiondata-zugriffsverletzung.html)

Ines 26. Jan 2011 09:35

LsaGetLogonSessionData - Zugriffsverletzung
 
Hallo DP'ler,

ich habe folgenden Code http://www.delphipraxis.net/90606-de...to_threadtools in mein Programm eingefügt.

An manchen Rechnern funktioniert der Aufruf, an manchen bekomme ich eine Zugriffsverletzung.

Alle Rechner sind XP-Clients, der Benutzer ist immer der gleiche (also keine unterschiedlichen Rechte) und ich habe keine Ahnung - und weiß nicht wie ich weitermachen soll.

Gibt es eine andere Möglichkeit herauszufinden, wielange der Nutzer schon angemeldet ist? Mit GetTickCount kann ich abfragen, wielange der Rechner läuft - gibt es so etwas wie "Get_User_TickCount"? :?

Vielen Dank und liebe Grüße
Ines

Delphi2009 Enterprise
Windows XP SP 3

Dezipaitor 26. Jan 2011 17:11

AW: LsaGetLogonSessionData - Zugriffsverletzung
 
Hi, füge mal

Delphi-Quellcode:
{$ALIGN 4}
{$MINENUMSIZE 4}
in den Delphicode ganz oben ein und versuche es erneut.
Damit werden die Recordelemente auf 4Byte-Blöcke ausgerichtet und die Aufzählungstypen werden mindestens 4 Bytes groß.

Assarbad 26. Jan 2011 17:20

AW: LsaGetLogonSessionData - Zugriffsverletzung
 
Früher war eine billige Variante das Datum des Registryschlüssels für den Hive zu benutzen.

Bspw:
HKEY_USERS\S-1-5-21-XXXX-XXXX-XXXX-500

kopernikus 7. Nov 2011 11:30

AW: LsaGetLogonSessionData - Zugriffsverletzung
 
Der unter bereitgestellte Quellcode ist noch nicht ganz wasserdicht. Außerdem funktioniert er nicht bei Remoote-Sitzungen. Daher habe ich folgende Änderungen eingefügt:
  1. Da die verwendeten API-Funktionen nicht in allen Windows-Versionen verfügbar sind, wurden sie dynamisch eingebunden
  2. Der Aufruf von LsaGetLogonSessionData kann einen Fehler verursachen (z.B. Access denied). Durch eine zusätzliche Abfrage wird das abgefangen.
  3. Der LogonType darf auch RemoteInteractive sein.
  4. Die Abfrage WTSGetActiveConsoleSessionId funktioniert nicht bei Remote-Sitzungen und wird durch ProcessIdToSessionId und GetCurrentProcessId ersetzt.

Delphi-Quellcode:
type
  TSessionData = record
    UserLuid : TLUID;
    UserName,
    Domain   : string;
    LogonType : TSecurityLogonType;
    LogonTime : TDateTime;
    end;

function ProcessIdToSessionId (ProcessId : DWORD; var SessionId : DWORD) : BOOL; stdcall; external kernel32 name 'ProcessIdToSessionId'

// Daten des angemeldeten Benutzers ermitteln
function GetUserSessionData (var SessionData : TSessionData) : boolean;
var
  Count: cardinal;
  Luid: PLUID;
  PSesDat: PSecurityLogonSessionData;
  i : integer;
  sid : cardinal;
  SizeNeeded, SizeNeeded2: DWORD;
  OwnerName, DomainName: PChar;
  OwnerType: SID_NAME_USE;
  pBuffer: Pointer;
  pBytesreturned: DWord;
  LocalFileTime: TFileTime;
  Secur32Handle,Wtsapi32Handle : THandle;
  FWTSQuerySessionInformation : TWTSQuerySessionInformation; // ab Win XP
  FWTSGetActiveConsoleSessionId : TWTSGetActiveConsoleSessionId; // ab Win XP
  FLsaEnumerateLogonSessions : TLsaEnumerateLogonSessions; // ab Win XP
  FLsaGetLogonSessionData : TLsaGetLogonSessionData;     // ab Win 2000
  FLsaFreeReturnBuffer : TLsaFreeReturnBuffer;           // ab Win 2000
begin
  result:=false;
  Secur32Handle:=LoadLibrary(secur32);
  if Secur32Handle=0 then Exit;
  FLsaEnumerateLogonSessions:=GetProcAddress(Secur32Handle,'LsaEnumerateLogonSessions');
  if not assigned(FLsaEnumerateLogonSessions) then Exit;
  FLsaGetLogonSessionData:=GetProcAddress(Secur32Handle,'LsaGetLogonSessionData');
  if not assigned(FLsaGetLogonSessionData) then Exit;
  FLsaFreeReturnBuffer:=GetProcAddress(Secur32Handle,'LsaFreeReturnBuffer');
  if not assigned(FLsaFreeReturnBuffer) then Exit;
  Wtsapi32Handle:=LoadLibrary(wtsapi32);
  if Wtsapi32Handle=0 then Exit;
  FWTSQuerySessionInformation:=GetProcAddress(Wtsapi32Handle,'WTSQuerySessionInformationW');
  if not assigned(FWTSQuerySessionInformation) then Exit;
  DllHandle:=GetModuleHandle(kernel32);
  if DllHandle=0 then Exit;
  FWTSGetActiveConsoleSessionId:=GetProcAddress(DllHandle,'WTSGetActiveConsoleSessionId');
  if not assigned(FWTSGetActiveConsoleSessionId) then Exit;
  //Auflisten der LogOnSessions
  try
    if (LsaNtStatusToWinError(FLsaEnumerateLogonSessions(Count,Luid))=0) then begin
      i:= -1;
      if Count > 0 then repeat
        inc(i);
        // Prüfe auf mögliche Fehler (z.B. Access denied)
        if LsaNtStatusToWinError(FLsaGetLogonSessionData(Luid,PSesDat))=0 then begin
          // Prüfe, ob es sich um eine Konsolen- oder Remote-Anmeldung handelt
          if (PSesDat^.LogonType=Interactive) or (PSesDat^.LogonType=RemoteInteractive) then begin
            SizeNeeded := MAX_PATH;
            SizeNeeded2:= MAX_PATH;
            GetMem(OwnerName, MAX_PATH);
            GetMem(DomainName, MAX_PATH);
            try
              if LookupAccountSID(nil, PSesDat^.SID, OwnerName,SizeNeeded,DomainName,SizeNeeded2,
                              OwnerType) then begin
                // Prüfen ob es sich um einen Benutzer handelt und ob es die
                // SessionId des aufrufenden Prozesses ist
                if (OwnerType=1) and ProcessIdToSessionId(GetCurrentProcessId,sid)
                    and(PSesDat^.Session=sid) then begin
                  if FWTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,
                      PSesDat^.Session, WTSConnectState,pBuffer,pBytesreturned) then begin
                    if WTS_CONNECTSTATE_CLASS(pBuffer^) = WTSActive then with SessionData do begin
                      UserLuid:=Luid^;
                      UserName:=PSesDat^.UserName.Buffer;
                      DOmain:=PSesDat^.LogonDomain.Buffer;
                      LogonType:=PSesDat^.LogonType;
                      LogonTime:=Now;
                      if FileTimeToLocalFileTime(TFileTime(PSesDat^.LogonTime),LocalFileTime) then
                        LogonTime:=FileTimeToDateTime(LocalFileTime);
                      result:=true;
                      end;
                    end;
                  FLSAFreeReturnBuffer(pBuffer);
                  end;
                end;
            finally
              FreeMem(OwnerName);
              FreeMem(DomainName);
              end;
            end;
          end;
        inc(Luid);
        try
          FLSAFreeReturnBuffer(PSesDat);
        except
          end;
        until (i = Count-1) or result;
      end;
  finally
    FLSAFreeReturnBuffer(Luid);
    FreeLibrary(Wtsapi32Handle); FreeLibrary(Secur32Handle);
    end;
  end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:13 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz