Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Winlogon, Welcome Screen (https://www.delphipraxis.net/112848-winlogon-welcome-screen.html)

stOrM 28. Apr 2008 11:35


Winlogon, Welcome Screen
 
Hi,
ich bin mir nicht mehr so ganz sicher, wo ich die sources gefunden habe, aber dabei kam mir folgende Idee...

Wenn man z.B. Kaspersky Antivirus installiert, dann zeichnen die im Windows XP Welcome Screen, den Text: "Kaspersky Antivirus" das würde ich auch gerne erreichen, nur halt mit meinen Text...

Jetzt hab ich mal ein wenig gelesen und bin dabei über die Möglichkeit: Winlogon Notification Packages gestossen, demnach sollte das ja möglich sein, wenn man seine DLL im System registriert (entsprechender Registry Pfad)...

Problem: Irgendwie zeichend er mir den Text jetzt leider nur hinter den Welcome Screen (denke mal ist der User Desktop), wie bekomme ich das denn hin, dass er mir den meinen Text auf den Welcome Screen z.B. ganz oben links zeichnet?????? vermutlich ist dass Problem das ich nicht weiss, wie ich den Welcome Desktop Screen ermitteln soll und somit auf den Canvas meinen Text zeichnen kann...

Mal der Source (wie gesagt kann mich nicht mehr erinnern wo der her ist...) :-(

Delphi-Quellcode:
library sLogon;

uses
  Windows,
  Graphics,
  Sysutils,
  types;

type
  PWSTR = PWideChar;
  HANDLE = Longword;
  PFNMSGECALLBACK = function(bVerbose: BOOL; lpMessage: LPWSTR): DWORD; stdcall;

  _WLX_NOTIFICATION_INFO = record
    Size: ULONG;
    Flags: ULONG;
    UserName: PWSTR;
    Domain: PWSTR;
    WindowStation: PWSTR;
    hToken: HANDLE;
    hDesktop: HDESK;
    pStatusCallback: PFNMSGECALLBACK;
  end;
  WLX_NOTIFICATION_INFO = _WLX_NOTIFICATION_INFO;
  PWLX_NOTIFICATION_INFO = ^WLX_NOTIFICATION_INFO;

procedure DrawPicture(const FileName: String; Width: Integer = 0;
  Height: Integer = 0; Top: Integer = 0; Left: Integer = 0);
var
  DC       : HDC;
  Canvas   : TCanvas;
  Bitmap   : TBitmap;
begin
  // Falls die Datei existiert, dann fortfahren
  if FileExists(FileName) then
  begin
    Bitmap := TBitmap.Create();

    try
      Bitmap.LoadFromFile(FileName);
      // Falls eigene Parameter angeben sind, werden diese benutzt.
      if Height > 0 then
        Bitmap.Height := Height;
      if Width > 0 then
        Bitmap.Width := Width;
      // Wir holen uns den 'Device Context' vom Desktop
      DC := GetWindowDC(GetDesktopWindow());
      try
        Canvas := TCanvas.Create();
        try
          // Wir weisen den DC dem Canvas zu
          Canvas.Handle := DC;
          // Das Bild wird an Left / Top auf den Desktop gezeichnet
          Canvas.Draw(Left, Top, Bitmap);

        finally
          Canvas.Free;
        end;
      finally
        ReleaseDC(0, DC);
      end;
    finally
      Bitmap.Free;
    end;
  end;
end;

procedure WLEventLogon(pInfo: PWLX_NOTIFICATION_INFO); stdcall;
begin
  DrawPicture('MG.bmp', 0, 0, 0, 0);

end;

procedure WLEventLogoff(pInfo: PWLX_NOTIFICATION_INFO); stdcall;
begin
  DrawPicture('MG.bmp', 0, 0, 0, 0);

end;

exports
  WLEventLogon,
  WLEventLogoff;

begin

end.
Vielen Dank
Marc

Dezipaitor 28. Apr 2008 11:56

Re: Winlogon, Welcome Screen
 
Wundert mich eigentlich :
Der Desktop ist auch nur ein Fenster. Wenn eine externe Anwendung dort was draufmalt, und dies nicht ständig wiederholt, dann wird der Text irgendwann überschrieben.

stOrM 28. Apr 2008 15:57

Re: Winlogon, Welcome Screen
 
Zitat:

Zitat von Dezipaitor
Wundert mich eigentlich :
Der Desktop ist auch nur ein Fenster. Wenn eine externe Anwendung dort was draufmalt, und dies nicht ständig wiederholt, dann wird der Text irgendwann überschrieben.

Öhm der Desktop iss ja nicht das Problem ich versuchs nochmal anders zu erklären...
Ich würde gerne oben links in der Ecke von Welcome Screen unter XP etwas malen...

Obiger Code mal aber auf den User Desktop, daher Frage: wie bekomme ich den DC vom Welcome Screen?

Siehe DrawPicture:

// Wir holen uns den 'Device Context' vom Desktop
DC := GetWindowDC(GetDesktopWindow());

Dürfte hier wohl falsch sein, da GetDesktopWindow wohl nicht den Willkommen Bildschirm holt, anstelle dessen aber den Benutzerbildschirm (wie ich darauf komme? Weiss ich auch nicht so genau, aber wenn ich die dll in der Registry eintrage und einen Neustart mache dann sieht man ganz kurz, bevor der Willkommensbildschirm kommt meinen Text, welcher anscheinend hinter dem Willkommensbildschirm liegt (also Benutzerdesktop)?

Gruss
s!

Dezipaitor 28. Apr 2008 18:40

Re: Winlogon, Welcome Screen
 
Was ist der Willkommensbildschirm für dich?

Der Desktop mit dem LoginDialog ist ein anderer als der normale Desktop für die Anwendungen.

Ich nehme an, du willst den Anmeldebildschirm-Desktop oder? Dieser Desktop heißt "winlogon". Er ist von normalen Benutzerprogrammen nicht erreichbar. Man müsste ein Program durch einen Dienst in die Session des Benutzers starten (mit SYSTEM Rechten). Dieses programm könnte ein kleines Fenster mit dem Text in den Winlogonbildschirm einblenden. Ohne Fensterrand und mit Hintergrundfarbe (oder Transparenz) sieht das so aus, als ob da ein Text auf dem Desktop steht.

Wenn du auf den normalen Desktop einfach so - und nur einmal - einen Text zeichnest, dann wird dieser Text gelöscht, sobald der Desktop sich neumalt, z.B. weil ein Fenster darüber bewegt wird.

Wen dein Code als Systembenutzer ausgeführt wird, dann kannst du mit OpenDesktop('winlogon',...) und SetThreadDesktop sowie GetDesktopWindow den winlogon Desktop möglicherweise auch bekommen.

Die JWSCL kann das in OOP. Ich vermute mal, es sieht etwa so aus, wie im Quelltext. Aber ich kann nicht versprechen, dass es funkz:

Delphi-Quellcode:
uses Windows, JwsclDesktops;
var
     Desktop: TJwSecurityDesktop;

begin
      Desktop:=TJwSecurityDesktop.OpenDesktop('winlogon', [], false, GENERIC_ALL);
      Desktop.SetThreadDesktop;
      try
        DrawPicture('MG.bmp', 0, 0, 0, 0);
      finally
        Desktop.Free;
      end;
end;
Der Code muss als SYSTEM Benutzer ausgeführt werden. Zudem muss die SessionID des Prozesses, die Session des jeweiligen angemeldeten Benutzers sein.
Z.B.
Windows XP
- Ein Benutzer angemeldet. Session ID muss 0 sein. Das kann noch ein Dienst machen.
- Zwei Benutzer angemeldet. Session ID muss 0 und 1 sein. Also hier brauchen wir zwei Prozesse in Session 0 (erster Benutzer) und Session 1 (zweiter Benutzer). Session 0 kann noch ein Dienst machen. Session 1 nicht mehr. Hier muss der Dienst ein Programm in diese Session starten.
Windows Vista.
-Ein Benutzer angeldet. Session ID muss 1 sein. Ein Dienst kann hier nichts machen. Hier muss der Dienst ein Programm in diese Session starten.
-weitere Benutzer, wie in XP

stOrM 29. Apr 2008 01:10

Re: Winlogon, Welcome Screen
 
Zitat:

Zitat von Dezipaitor
Man müsste ein Program durch einen Dienst in die Session des Benutzers starten (mit SYSTEM Rechten). Dieses programm könnte ein kleines Fenster mit dem Text in den Winlogonbildschirm einblenden. Ohne Fensterrand und mit Hintergrundfarbe (oder Transparenz) sieht das so aus, als ob da ein Text auf dem Desktop steht.


???????????????? Bahnhof!
Mir ist deine Erklärung nicht ganz klar, weil ich nicht verstehe wofür ich einen Dienst brauche, wenn man so wie ich das verstanden habe dem System (OS) mittels Registryeintrag bekannt gibt, das man eine Notification DLL gebaut hat....?
Meine DLL wird ja von der Winlogon.exe geladen (merk ich daran, wenn ich meine DLL aus dem System32 Verzeichnis löschen will, meckert Windows, das Winlogon.exe Zugriff auf meine DLL hat (Unlocker sei dank!) abgesehen davon kann ich ja z.B. ne Messagebox im Winlogon ausgeben also bin ich doch in der richtigen Ebene oder meinst du, wenn ich den Winlogon Zeichnen will dann brauch ich nen Service????...

Besteht nicht die Möglichkeit, aus meiner DLL ein Fenster zu starten, welches sich in meiner DLL befindet?
Quasi in etwa so:

Delphi-Quellcode:
procedure WLEventLogon(pInfo: PWLX_NOTIFICATION_INFO); stdcall;
begin

  dllFormShow.ShowForm;

end;

hathor 29. Apr 2008 08:16

Re: Winlogon, Welcome Screen
 
Das WINDOWS-eigene Programm, das für den Logon-Bildschirm zuständig ist, heisst Gina.DLL(msgina.dll,shgina.dll). Google einfach danach. Es gibt massenhaft Programme, die Gina.DLL ersetzen.

http://www.google.com/codesearch?hl=...DLL&btnG=Suche

Dezipaitor 29. Apr 2008 08:59

Re: Winlogon, Welcome Screen
 
1. GINA gibt es nicht mehr in Vista
2. Ich bin mir nicht sicher, aber die Callbackfunktion könnte ohne eigenen Thread aufgerufen werden. Solange du also in der Callbackfunktion irgendwas machst, kwird der Winlogon Prozess nicht funktionieren.
3. Wenn dein Programmcode innerhalb von Winlogon crasht, wird der Prozess beendet und der PC startet automatisch neu.

stOrM 13. Mai 2008 22:05

Re: Winlogon, Welcome Screen
 
Yo da bin ich nochmal, ich verzweifel langsam!

Vielleicht drehen wir das ganze nochmal ein wenig zurück, sofern noch interesse besteht, ich hänge mal am Schluß meines Fragekataloges den Quelltext der DLL mit rein...

Folgendes hat sich geändert, ich versuche jetzt nicht mehr direkt, auf den Winlogon zu zeichnen, dass klappt irgendwie mal überhaupt nicht, keine Ahnung wie Kaspersky das gemacht hat, aber ich vermute mal das der KAV Dienst dabei behilflich ist...

Ich verfolge da einen anderen Ansatz, nämlich den, den du (Dezipaitor) erwähnt hattest, ein Fenster transparent zu machen und so einen, pseudo gezeichneten Text auf den Winlogon erscheinen zu lassen.

Dafür hatte ich die Idee in meiner Winlogon Notification Package (was für ein Name!) über CreateProcess bei Logon / Logoff eine executeable aufzurufen, diese könnte dann das unsichtbare Fenster mit text usw enthalten...

Problem 1:
Ich bin jetzt mittlerweile soweit, das die exe aufgerufen wird bei jedem Logon / Logoff nur da gibt es ein extremes Problem...
Sie wird ausgeführt nachdem der User sich mittels Password authentifiziert hat, soll heissen, nach Eingabe des Passwords im Winlogon erscheint mein Fenster auf dem "normalen" User Desktop, was natürlich extrem dumm ist, sie sollte eigentlich im Winlogon ausgeführt werden... Ich vermute mal wenn ich dich richtig verstanden habe "Dezipaitor" dann liegt das daran, das meine exe keine Systemrechte hat????

Dann wäre da folgende Frage, gibt es die Möglichkeit in meiner DLL mittels CreateProcess einer exe diese Rechte zu geben, wenn ja währe ich extrem fröhlich, wenn man dafür ein Beispiel hätte... :-)

Das Problen an der ganzen Sache ist, ich möchte keinen Dienst schreiben dafür, wobei dort ebenfalls das gleiche Problem wäre, CreateProcess mit Systemrecht...

Vielleicht schaust Du bitte nochmals über meine DLL eventuell weisst Du ja was falsch ist?
Ich glaube der CreateProcess Teil war sogar von dir?? :-)

Delphi-Quellcode:
library swxLogonNotify;

uses
  SysUtils,
  Classes,
  Windows,
  JwaWindows,
  JwsclStrings;

type
  TFnMsgeCallback = function (bVerbose: Boolean; lpMessage: PWideChar): Cardinal; stdcall;

TWlxNotificationInfo = record
    Size: Cardinal;
    Flags: Cardinal;
    UserName: PWideChar;
    Domain: PWideChar;
    WindowStation: PWideChar;
    Token: Cardinal;
    Desktop: Cardinal;
    StatusCallback: TFnMsgeCallback;
  end;
  PWlxNotificationInfo = ^TWlxNotificationInfo;

{$R *.res}

procedure StartApp(const App, Parameters, CurDir : TJwString);
var
  StartupInfo: {$IFDEF UNICODE}TStartupInfoW{$ELSE}TStartupInfoA{$ENDIF};
  ProcInfo : TProcessInformation;
  pEnv : Pointer;
  pCurDir,
  pCmdLine : TJwPChar;
begin

  ZeroMemory(@StartupInfo, sizeof(StartupInfo));
  StartupInfo.cb         := SizeOf(StartupInfo);
  StartupInfo.lpDesktop  := 'winsta0\default';
  CreateEnvironmentBlock(@pEnv, 0, true);
  try
    if Length(Parameters) > 0 then
      pCmdLine := TJwPChar('"'+App+'" ' + Parameters)
    else
      pCmdLine := TJwPChar('"'+App+'" ');
    pCurDir := Nil;
    if Length(CurDir) > 0 then
      pCurDir := TJwPChar(CurDir);
   if not

{$IFDEF UNICODE}CreateProcessW{$ELSE}CreateProcessA{$ENDIF}(

    TJwPChar(App),//__in_opt    LPCTSTR lpApplicationName,
    pCmdLine, //__inout_opt LPTSTR lpCommandLine,
    nil,//__in_opt    LPSECURITY_ATTRIBUTES lpProcessAttributes,
    nil,//__in_opt    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    true,//__in        BOOL bInheritHandles,
    CREATE_NEW_CONSOLE or CREATE_UNICODE_ENVIRONMENT,//__in        DWORD dwCreationFlags,
    pEnv,//__in_opt    LPVOID lpEnvironment,
   pCurDir,//__in_opt    LPCTSTR lpCurrentDirectory,
    StartupInfo,//__in        LPSTARTUPINFO lpStartupInfo,
    ProcInfo,//__out       LPPROCESS_INFORMATION lpProcessInformation
  ) then
   raiseLastOsError;

  finally
    DestroyEnvironmentBlock(pEnv);
  end;
  CloseHandle(ProcInfo.hProcess);
  CloseHandle(ProcInfo.hThread);
end;

procedure StartupHandler(Info: PWlxNotificationInfo); stdcall;
begin

end;

procedure LogonHandler(Info: PWlxNotificationInfo); stdcall;
begin
  StartApp('c:\windows\system32\storm.exe', '', '');
end;

procedure StartShellHandler(Info: PWlxNotificationInfo); stdcall;
begin

end;

procedure LockHandler(Info: PWlxNotificationInfo); stdcall;
begin

end;

procedure UnLockHandler(Info: PWlxNotificationInfo); stdcall;
begin

end;

procedure StartScreenSaverHandler(Info: PWlxNotificationInfo); stdcall;
begin

end;

procedure StopScreenSaverHandler(Info: PWlxNotificationInfo); stdcall;
begin

end;

procedure LogoffHandler(Info: PWlxNotificationInfo); stdcall;
begin
  StartApp('c:\windows\system32\storm.exe', '', '');
end;

procedure ShutdownHandler(Info: PWlxNotificationInfo); stdcall;
begin

end;

procedure DisconnectHandler(Info: PWlxNotificationInfo); stdcall;
begin

end;

procedure ReconnectHandler(Info: PWlxNotificationInfo); stdcall;
begin

end;

procedure PostShellHandler(Info: PWlxNotificationInfo); stdcall;
begin

end;



//Nachfolgender Bereich verdunkelt mit das Hirn, brauch ich den unbedingt???

procedure EntryPointProc(reason: integer);
begin
  case reason of
    DLL_PROCESS_ATTACH: //1
      begin
        DisableThreadLibraryCalls(hInstance);
      end;
    DLL_THREAD_ATTACH:  //2
      begin

      end;
    DLL_PROCESS_DETACH: //3
      begin

      end;
    DLL_THREAD_DETACH:  //0
      begin

      end;
  end;

end;

exports
  StartupHandler,
  LogonHandler,
  StartShellHandler,
  LockHandler,
  UnLockHandler,
  StartScreenSaverHandler,
  StopScreenSaverHandler,
  LogoffHandler,
  ShutdownHandler,
  DisconnectHandler,
  ReconnectHandler,
  PostShellHandler;

begin
  DllProc := @EntryPointProc;
  DllProc(DLL_PROCESS_ATTACH);
end.
Vielen Dank!
Marc

Dezipaitor 13. Mai 2008 23:06

Re: Winlogon, Welcome Screen
 
da steht
Delphi-Quellcode:
StartupInfo.lpDesktop  := 'winsta0\default';
sollte net so sein, oder?

stOrM 13. Mai 2008 23:28

Re: Winlogon, Welcome Screen
 
öhm nicht? :oops:


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:03 Uhr.
Seite 1 von 2  1 2      

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