Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Nachricht auf allen Desktops anzeigen - und wieder schließen (https://www.delphipraxis.net/117589-nachricht-auf-allen-desktops-anzeigen-und-wieder-schliessen.html)

Dezipaitor 23. Jul 2008 08:17

Re: Nachricht auf allen Desktops anzeigen - und wieder schli
 
Wie gesagt, ein Prozess kann nicht das Token eines anderern Prozesses nachträglich ersetzen unter Vista. Es gibt eine 5.

Wenn die SessionID gesetzt wurde und der Prozess läuft, liefert SetTokenInformation einen Fehler zurück.

new32 23. Jul 2008 09:29

Re: Nachricht auf allen Desktops anzeigen - und wieder schli
 
Danke für den Hinweis!

Eines meiner Programme benutzt nämlich ZwSetInformationProcess um sein Token mit bestimmten Rechten auszustatten.
Und tatsächlich Vista sagt nur c0000005 dazu. :oops:

xpmd 23. Jul 2008 10:50

geschafft
 
Zitat:

Zitat von Apollonius
Die Ansätze 1 und 3 können gar nicht funktionieren: Die TS eines Prozesses kann nicht geändert werden.
Der Ansatz 2 ist korrekt. Hast du in der StartupInfo-Struktur Desktop und Window-Station angegeben? Hast du im Token die SessionID gesetzt?

Danke! Habs jetzt mit Ansatz 2 umgesetzt und so klappts auch. Das Setzen der WindowStation/Desktop für den Prozessstart ist gar nicht nötig.
Das Programm startet sich 1x pro Terminal Session mit dem Parameter STOPX selbst. Durch den Start mit diesem Parameter werden im entsprechenden Kontext alle Fenster der entsprechenden Session durchlaufen.

Da die WTSSendMessage MB_SERVICE_NOTIFICATION nun auch die MessageBox im Login-Screen und beim "gesperrtem" Bildschirm anzeigt, muss ich es noch irgendwie schaffen an diese Fenster zu kommen. Ich lasse vom Hauptprozess unter Session0 / System nochmal zusätzlich alle verfügbaren WindowStations und Desktops nach der MessageBox durchsuchen. Allerdings wird sie nicht gefunden. Ich werde da noch probieren, einen zusätzlichen Prozess unter expliziter Angabe der WinSta0\Winlogon und WinSta0\Disconnect zu starten.

Delphi-Quellcode:
for i := 0 to Length(SessionInfos) - 1 do begin
  UserToken := QueryUserToken(SessionInfos[i].SessionId);
  ZeroMemory(@SI, SizeOf(SI));
  ZeroMemory(@PI, SizeOf(PI));
 
  SI.lpDesktop := nil;
  SI.dwFlags := STARTF_USESHOWWINDOW;
  SI.wShowWindow := SW_HIDE;
  SI.cb := SizeOf(si);
 
  DuplicateTokenEx(UserToken, MAXIMUM_ALLOWED, nil, SecurityImpersonation, TokenPrimary, DuplicatedToken);
  if(DuplicatedToken <> 0) then begin
    SetTokenSessionId(DuplicatedToken, SessionInfos[i].SessionId);
    CreateProcessAsUser(DuplicatedToken,PAnsiChar(ParamStr(0)) , PAnsiChar(ParamStr(0) + ' STOPX'), nil, nil, false,          CREATE_NEW_CONSOLE, nil, nil, SI, PI);
  end;
  CloseHandle(UserToken);
  CloseHandle(DuplicatedToken);
end;
hier der Code für SetTokenSessionId:

Delphi-Quellcode:
{$EXTERNALSYM _SetTokenInformation}
function _SetTokenInformation(TokenHandle: Cardinal; TokenInformationClass: Integer; TokenInformation: PDWORD; TokenInformationLength: DWORD): bool; stdcall;
function SetTokenSessionId(UserToken: Cardinal; SessionId: integer): bool;

implementation

function _SetTokenInformation; external 'Advapi32.dll' name 'SetTokenInformation';
function SetTokenSessionId(UserToken: Cardinal; SessionId: integer): bool;
var Information: DWORD;
begin
  Information := DWORD(SessionId);
  result := _SetTokenInformation(UserToken, 12, @Information, Cardinal(SizeOf(Information)));
end;

xpmd 23. Jul 2008 11:46

Re: geschafft
 
Zitat:

Zitat von xpmd
Da die WTSSendMessage MB_SERVICE_NOTIFICATION nun auch die MessageBox im Login-Screen und beim "gesperrtem" Bildschirm anzeigt, muss ich es noch irgendwie schaffen an diese Fenster zu kommen. Ich lasse vom Hauptprozess unter Session0 / System nochmal zusätzlich alle verfügbaren WindowStations und Desktops nach der MessageBox durchsuchen. Allerdings wird sie nicht gefunden. Ich werde da noch probieren, einen zusätzlichen Prozess unter expliziter Angabe der WinSta0\Winlogon und WinSta0\Disconnect zu starten.

Klappt leider nicht. :-(

Unter diesen Desktops werden keine Fenster gefunden. Hat jemand ne Idee wie ich diese auch noch zum schließen bringe?

Dezipaitor 23. Jul 2008 12:57

Re: Nachricht auf allen Desktops anzeigen - und wieder schli
 
Wenn du pro Session eh schon ein Programm hast, dann kannst du die DialogBox auch gleich selbst anzeigen :D

Schau dir mal an, von welchem Prozess der Dialog angezeigt wird. Wenn der Prozess Systemrechte besitzt, dann wirst du es nicht finden,
wenn deine Suche nicht auch von einem Prozess mit Sysrechten ausgeführt wird.

xpmd 23. Jul 2008 13:20

Re: Nachricht auf allen Desktops anzeigen - und wieder schli
 
Laut den Infos von hier: http://www.uvnc.com/vista/ müsste ich den Schließen-Prozess unter jeder Session am Desktop Winlogon mit SYSTEM-Rechten starten, um auf dessen Fenster zugreifen zu können. Die WTSSendMessage Nachricht wird offenbar von einem Windows-Systemprozess angezeigt. Frage ist jetz wie ich eben einen Prozess z.B. unter Session 2\Winsta0\Winlogon und User SYSTEM starte.

STARTUPINFO lpDesktop auf Winsta0\Winlogon setzen und über SetTokenInformation die Session des UserTokens auf die entsprechende Session setzen würde ich jetzt sagen. Aber wie geht das mit User SYSTEM?

QueryUserToken auf Session 0 liefert einen Token 0 zurück. Diesen dupliziert ergibt auch 0 ;-) Entsprechen kann ich keine andere Session über SetTokenInformation setzen und den Schließen-Prozess damit starten. Hat SYSTEM überhaupt ein UserToken? Oder bin ich da auf dem Holzweg?

:|

Apollonius 23. Jul 2008 13:59

Re: Nachricht auf allen Desktops anzeigen - und wieder schli
 
Wenn dein Service als System läuft, hat er auch ein entsprechendes Token. Also kannst du einfach dein Prozess-Token duplizieren und das Duplikat verwenden, nachdem du dort die Session-ID gesetzt hast.

Dezipaitor 23. Jul 2008 18:17

Re: Nachricht auf allen Desktops anzeigen - und wieder schli
 
vorsicht: WTSQueryUserToken liefert unter xp das user token zurück.

xpmd 24. Jul 2008 14:19

Re: Nachricht auf allen Desktops anzeigen - und wieder schli
 
es ist zum verzweifeln :(

Jetz paßt alles soweit, die MEssageBox wird überall wieder geschlossen bis auf einen Fall: Wenn mehrere Sessions unter Vista aktiv sind, wird das Fenster zwar in jeder session geschlossen. Scheinbar überwacht aber WTSSendMessage jedes Nachrichtenfenster, ob es automatisch geschlossen wird ohne dass es der User sehen konnte. Also quasi Wenn es in einer Session die grad nicht verbunden ist, geschlossen wird. Anders kann ichs mir nicht erklären. Das Fenster wird laut Debug-Outputs geschlossen erscheint aber sofort drauf wieder mit neuem Handle. Irgendwie eine undokumentierte Funktion von WTSSendMEssage?

eine Lösung wüsst ich für den Fall noch. Ich lass den Schließen-Prozess so lange im Kreis laufen bis keine MessageBox mehr existiert. Der prozess läuft quasi dann so lange bis sich der angemeldete Benutzer zu der Session verbindet. Anschließend kann das Fenster dann geschlossen werden.

Echt frustrieren das. Mal sehen obs so dann auch wirklich zu 100% alle existierenden Nachrichtenfenster schließen kann, oder ob der 281 Stolperstein auftaucht :wall:

Dezipaitor 24. Jul 2008 15:02

Re: Nachricht auf allen Desktops anzeigen - und wieder schli
 
Warum machst du nicht einfach deinen eigenen MessageBox Prozess?


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:43 Uhr.
Seite 2 von 3     12 3      

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