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 OpenDialog mit Benutzerumgebung aus System-Prozess (https://www.delphipraxis.net/158305-opendialog-mit-benutzerumgebung-aus-system-prozess.html)

CodeX 12. Feb 2011 18:55

OpenDialog mit Benutzerumgebung aus System-Prozess
 
Ich habe eine Software im System-Kontext laufen. Nun möchte ich aus dieser heraus einen TOpenDialog öffnen und den Benutzer eine Datei auswählen lassen. Das funktioniert zwar, aber der Dialog läuft im System-Kontext und deshalb sieht der Anwendet z.B. nicht seine Favoriten (Vista/7) und der Desktop führt auch nicht auf den Benutzer-Desktop sondern nach "C:\Windows\system32\config\systemprofile\Desk top" und noch ein paar andere Nachteile.

Nun habe ich mit Hilfe der JWSCL versucht, das per ImpersonateLoggedOnUser zu regeln, was aber leider nicht funktioniert. Generell tut ImpersonateLoggedOnUser ja, aber es regelt wohl nur die Rechte, nicht aber die Umgebung (Environment).

Wie geht das dann also richtig?

Delphi-Quellcode:
var
  isSystem : Boolean;
  UserToken : TJwSecurityToken;
begin

  isSystem := JwIsSystem;

  if isSystem then
  begin
    //get the token of the logged in user
    if is2000 then
      UserToken := TJwSecurityToken.CreateCompatibilityQueryUserToken(MAXIMUM_ALLOWED, 'explorer.exe')
    else //XP, 2003, Vista, 2008
      UserToken := TJwSecurityToken.CreateWTSQueryUserTokenEx(nil, WtsGetActiveConsoleSessionID);
    TJwAutoPointer.Wrap(UserToken);

    UserToken.ImpersonateLoggedOnUser;
  end;

  if MyOpenDialog.Execute then
  begin
  //...
  end;

  if isSystem then
  begin
    UserToken.RevertToSelf;
  end;
end;

himitsu 12. Feb 2011 19:45

AW: OpenDialog mit Benutzerumgebung aus System-Prozess
 
Auch wenn ich jetzt nicht wirklich helfen kann,
aber notfalls die Anwendung (GUI) im Benutzerkontext belassen und die entsprechenden Stellen, welche den Systemkontext benötigen, in einen Out-of-Process-Server (DLL) auslagern.

Rechte innerhalb einer Anwendung zu mischen ist nicht immer möglich, bzw. manchmal könnte es sogar ein Sicherheitsrisiko darstellen.

wicht 12. Feb 2011 20:33

AW: OpenDialog mit Benutzerumgebung aus System-Prozess
 
Wird nicht sowieso davon abgeraten, einen Dienst mit dem Desktop interagieren zu lassen? Bei >=Vista kommt doch vor dem Anzeigen eines Fensters sogar so eine Warnmeldung, weil das u.U. ein Sicherheitsrisiko darstellt.
Entweder so machen wie von himi vorgeschlagen, ansonsten vielleicht über Shared-Memory, Pipes, oder Sockets.. für all das braucht man natürlich eine 'Client'-Anwendung, die beim Benutzer im Autorun oder so liegen müsste, aber ich würde das eher irgendwie so regeln.

Luckie 12. Feb 2011 20:35

AW: OpenDialog mit Benutzerumgebung aus System-Prozess
 
Warum zur Hölle läuft die Anwendung im Systemkontext und hat eine Benutzeroberfläche?

CodeX 12. Feb 2011 20:53

AW: OpenDialog mit Benutzerumgebung aus System-Prozess
 
Ach herrje, schweift das hier jetzt ab...
Letztlich gab es diese Diskussionen doch schon zu genüge und seit diesem Thread, wo ich mit Hilfe von Dezipaitor eine Lösung erarbeitet habe, setze ich das auch auch erfolgreich ein. Es geht bei meiner Frage wirklich nicht darum, ob das alle für eine gute Idee halten oder nicht - ich habe meine Gründe dafür, einige stehen im verlinkten Thread. Wüde mich freuen, wenn jemand zur eigentlichen Frage etwas sagen könnte.

Dezipaitor 12. Feb 2011 22:58

AW: OpenDialog mit Benutzerumgebung aus System-Prozess
 
Nur mal ins blaue geraten:
Es kann gut sein, dass TOpenDialog schon vor Impersonate die Vereichnisse und alles einstellt, also im Konstruktor. Dü müsstest also den OpenDialog im Code nach ImpersonateLU erstellen.

CodeX 13. Feb 2011 13:18

AW: OpenDialog mit Benutzerumgebung aus System-Prozess
 
Habe ich mal ausprobiert:
Delphi-Quellcode:
var
  isSystem : Boolean;
  UserToken : TJwSecurityToken;
  od : TOpenDialog;
begin
  isSystem := JwIsSystem;

  if isSystem then
  begin
    if is2000 then
      UserToken := TJwSecurityToken.CreateCompatibilityQueryUserToken(MAXIMUM_ALLOWED, 'explorer.exe')
    else
      UserToken := TJwSecurityToken.CreateWTSQueryUserTokenEx(nil, WtsGetActiveConsoleSessionID);
    TJwAutoPointer.Wrap(UserToken);
    UserToken.ImpersonateLoggedOnUser;
  end;

  od := TOpenDialog.Create(Form1);
  od.Execute;
  od.Free;

  if isSystem then
    UserToken.RevertToSelf;
end;
Leider mit dem gleichen Ergebnis. Generell funktioniert das Impersonate schon korrekt (GetUserName gibt zb vorher SYSTEM und danach den Benutzernamen aus. Aber irgendwie ist die Personifizierung nicht vollständig oder es fehlt ganz einfach der Environment-Block. Ich weiß nur leider nicht, wie man das da mit einbauen könnte. Die Verwendung eines Envirunment-Blocks kenne ich nur beim Starten eines neuen Prozesses.
Hättest Du noch eine andere Idee? Kannst das Code-Schnippsel auch gern selbst ausprobieren. Vielleicht wird die Ursache dann offensichtlicher.

Dezipaitor 13. Feb 2011 20:01

AW: OpenDialog mit Benutzerumgebung aus System-Prozess
 
Der Umgebungsblock ist nur für den gesamten Prozess bestimmbar. Nachträglich ändern ist nicht offiziell möglich.

Der OpenDialog könnte mit SHGetFolderPath die Pfade auslesen, was bedeutet, dass Impersonate nicht funktioniert, weil man das Token direkt übergeben müsste. D.h. es wird ein neuer Prozess benötigt.


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

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