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/)
-   -   Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht (https://www.delphipraxis.net/194308-windows-10-getmodulehandle-user32-dll-lockworkstation-funktioniert-nicht.html)

361 7. Nov 2017 19:01

Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Guten Abend Euch,

ich habe heute leider feststellen müssen, dass folgender Code zum Sperren einer Windows-Maschine nicht mehr unter Windows 10 zum gewünschten Erfolg - nämlich das Sperren der Maschine - führt. Ich bekomme leider auch keine Fehlermeldung, alles scheint in Ordnung aber die Maschine sperrt sich nicht. Mit XP funktioniert der Code. Nun habe ich im Internet gesucht, aber keine Lösung dazu gefunden. Hat jemand von Euch vielleicht eine Idee, was ich falsch machen oder sich geändert haben könnte?

Vielen Dank und liebe Grüße :)

Code:
class function TWindows.Windows_Lock : Boolean;
type
  TLockWorkStation = function : Boolean;
var
  hL_User32         : HMODULE;
  LockWorkStation  : TLockWorkStation;
begin
  Result               := (False);

  hL_User32             := (GetModuleHandle('USER32.DLL'));
  if (hL_User32 <> 0) then begin
    @LockWorkStation   := (GetProcAddress(hL_User32, 'LockWorkStation'));
    if (@LockWorkStation <> NIL) then begin
      LockWorkStation;
      Result           := True;
    end;
  end;
end;

Dalai 7. Nov 2017 19:36

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Gibt es einen Grund, warum du das Rad neu erfindest? Selbst Delphi 5 hat diese Funktion bereits deklariert. Und warum nutzt du nicht direkt die Rückgabe der Funktion LockWorkstation für das Result deiner Funktion Windows_Lock? GetLastError bei LockWorkstation=False kann zudem auch nicht schaden, um herauszufinden, warum es nicht geht.

Übrigns gibt es einen Unterschied zwischen BOOL und Boolean: BOOL = 4 Byte, Boolean = 1 Byte. Bin mir nicht sicher, ob das hier eine Rolle spielt.

Grüße
Dalai

hoika 7. Nov 2017 19:49

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Hallo,
gerade mal unter D10.2 (32 Bit) kompiliert, klappt.

361 8. Nov 2017 06:59

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Guten Morgen,

ich bedanke mich für die Antworten.

@Dalei: Wo ist diese Funktion denn zu finden und wie heißt sie? Ich habe diesen Code seit irgendwann Anfang 2000 und das mit dem Rückgabewert ist mir auch gerade aufgefallen und korrigiert worden.

@Heiko: Hast Du meinen Code dazu verwendet oder die von Dalei vorgeschlagene mir noch unbekannte native Delphi-Implementierung? Unter Windows 10 (1703) habe ich lediglich das Problem, Standardinstallation mit Standardeinstellungen.

TiGü 8. Nov 2017 08:25

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Zitat:

Zitat von 361 (Beitrag 1385568)
@Dalei: Wo ist diese Funktion denn zu finden und wie heißt sie? Ich habe diesen Code seit irgendwann Anfang 2000 und das mit dem Rückgabewert ist mir auch gerade aufgefallen und korrigiert worden.

Ich würde ja zuerst in Winapi.Windows gucken und wenn das nicht von Erfolg gekrönt ist dann in den anderen Winapi-Units in bspw. C:\Program Files (x86)\Embarcadero\Studio\19.0\source\rtl\win

jaenicke 8. Nov 2017 10:19

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Die Funktion liegt schon ganz normal in der Unit Winapi.Windows bzw. früher nur Windows.

Du hast bei deiner eigenen Deklaration das stdcall vergessen und wie schon erwähnt wurde den falschen Rückgabewert benutzt.

361 8. Nov 2017 14:04

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Vielen Dank für die Antworten. Ich konnte mein Problem näher einkreisen: der Code ist korrekt (auch wenn optimierungsbedürftig), das Problem ist, dass dieser in einem Service ausgeführt wird. Unter Windows XP klappt das noch, aber ab Windows 7 läuft das nicht mehr. Hat jemand eine Idee, wie man das lösen könnte?

himitsu 8. Nov 2017 14:20

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Zitat:

Zitat von 361 (Beitrag 1385668)
Unter Windows XP klappt das noch, aber ab Windows 7 läuft das nicht mehr. Hat jemand eine Idee, wie man das lösen könnte?

Unter XP liefen viele Services noch im Context des Benutzers.

Inzwischen laufen standardmäßig die meisten Services getrennt vom "Desktop".
Standardmäßig hat ein Service keinen Zugriff auf den Desktop des aktiven Benutzers. Er kann also selbstständig auch keinerlei Programmfenster anzeigen.
Das kann man ändern > Interactive Services

361 8. Nov 2017 14:27

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Hallo Himitsu,

ich habe mit dem Haken (Zugriff auf Desktop) schon gespielt, aber es ändert nichts daran.


Nun habe ich bei meiner Recherche Code im StackOverflow zur Lösung gefunden. Ich weiß nicht, ob es gestattet ist, dazu zu verlinken (wenn nicht bitte kurz mitteilen, dann entferne ich den Link, jedoch weiß ich nicht wie das mit dem Urheberrecht beim Kopieren wäre, daher der Link):

https://stackoverflow.com/questions/...indows-service

Dort steht bei der ersten Antwort die dritte Lösung ohne Batch-Datei. Beherrscht irgendjemand VB um das nach Delphi zu übersetzen?

EDIT: Ich versuche es aktuell zu übersetzen, jedoch bisher nicht erfolgversprechend, da ich mit VB schon sehr lange nicht mehr zu tun hatte.

jaenicke 8. Nov 2017 14:35

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Zitat:

Zitat von 361 (Beitrag 1385668)
das Problem ist, dass dieser in einem Service ausgeführt wird. Unter Windows XP klappt das noch, aber ab Windows 7 läuft das nicht mehr. Hat jemand eine Idee, wie man das lösen könnte?

Das steht ja auch in der Dokumentation...
https://msdn.microsoft.com/de-de/lib...or=-2147217396
Zitat:

The LockWorkStation function is callable only by processes running on the interactive desktop. In addition, the user must be logged on, and the workstation cannot already be locked.
Das wirst du auch nicht umgehen können außer indem du im aktiven Userdesktop einen Prozess startest, der das macht.

Im Dienst funktioniert das nicht, weil es auch mehrere interaktive Desktops parallel geben könnte. Das System wüsste also nicht welche es sperren sollte.

// EDIT:
CreateProcessAsUser kannst du in Delphi einfach aufrufen, das gibt es in der Unit Windows schon.

Alternativ kannst du evtl. auch alle Sessions enumerieren (WTSEnumerateSessions) und trennen (WTSDisconnectSession), aber ich weiß nicht, ob das auch ohne RDP funktioniert.

361 8. Nov 2017 15:17

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Da das Beispiel im StackOverflow zu gehen scheint, wäre mir sehr geholfen, wenn jemand ausreichende VB-Kenntnisse hätte, um die Lösung der ersten Antwort zu übersetzen. Mir gelingt es nicht, ich scheitere an dem ersten Code-Beispiel, welches ja für das dritte Code-Beispiel benötigt wird :(

TiGü 8. Nov 2017 15:36

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Zitat:

Zitat von 361 (Beitrag 1385685)
Da das Beispiel im StackOverflow zu gehen scheint, wäre mir sehr geholfen, wenn jemand ausreichende VB-Kenntnisse hätte, um die Lösung der ersten Antwort zu übersetzen. Mir gelingt es nicht, ich scheitere an dem ersten Code-Beispiel, welches ja für das dritte Code-Beispiel benötigt wird :(

Bitte die Stack Overflow Antwort nochmal genau lesen und auf das EDIT in der Mitte achten!

Es sollte dann klar werden, dass er den ganzen Quark aus dem ersten Code-Beispiel nicht braucht, sondern direkt CreateProcessAsUser aufruft (drittes Code-Beispiel) mit dem Handle aus WTSQueryUserToken.

TiGü 8. Nov 2017 16:11

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Mal so runtergetippt und ungetestet:

Delphi-Quellcode:
function WTSQueryUserToken(SessionId: ULONG; phToken: PDWORD): BOOL; stdcall; external wtsapi32;
function WTSGetActiveConsoleSessionId: DWORD; stdcall; external kernel32;

procedure Test;
var
  SessionId: DWORD;
  UserTokenHandle: DWORD;
  StartInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  IsCreated: BOOL;
begin
  UserTokenHandle := 0;
  SessionId := WTSGetActiveConsoleSessionId;
  if WTSQueryUserToken(SessionId, @UserTokenHandle) then
  begin
    FillChar(StartInfo, SizeOf(StartInfo), 0);
    StartInfo.cb := SizeOf(StartInfo);
    FillChar(ProcessInfo, SizeOf(ProcessInfo), 0);

    IsCreated := CreateProcessAsUser(
      UserTokenHandle,
      'rundll32.exe',
      'rundll32.exe user32.dll,LockWorkStation',
      nil, nil, False, 0, nil, nil,
      StartInfo, ProcessInfo);

    if not IsCreated then
      RaiseLastOSError;
  end
  else
    RaiseLastOSError;
end;

361 9. Nov 2017 15:12

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Guten Abend TiGü,

und erst einmal vielen herzlichen Dank für Deine Mühe, weiß ich sehr zu schätzen. DANKE! :thumb:

Ich habe den Code gerade getestet und erhalte folgende Fehlermeldung:
Code:
System Error. Code: 1314. Dem Client fehlt ein erforderliches Recht.
Bei Ausführung von Zeile:
Code:
if WTSQueryUserToken(SessionId, @UserTokenHandle) then
läuft in den Else-Zweig hinein, sprich liefert "False". SessionId ist "1".

Vielleicht hat noch jemand eine Idee? Ich habe einfach eine kleine VCL-Testanwendung dazu gebaut und erhielt dann den Fehler.

Viele Grüße

TiGü 9. Nov 2017 15:22

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Zitat:

Zitat von 361 (Beitrag 1385806)
Vielleicht hat noch jemand eine Idee? Ich habe einfach eine kleine VCL-Testanwendung dazu gebaut und erhielt dann den Fehler.

Anhand des zweiten Satzes der MSDN-Dokumentation zu dieser Funktion hätte es mich auch schwer gewundert, wenn in einer normalen Desktop-VCL-Anwendung im User-Account etwas bei rumgekommen wäre. :roll:

361 9. Nov 2017 15:27

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Zitat:

Zitat von TiGü (Beitrag 1385811)
Zitat:

Zitat von 361 (Beitrag 1385806)
Vielleicht hat noch jemand eine Idee? Ich habe einfach eine kleine VCL-Testanwendung dazu gebaut und erhielt dann den Fehler.

Anhand des zweiten Satzes der MSDN-Dokumentation zu dieser Funktion hätte es mich auch schwer gewundert, wenn in einer normalen Desktop-VCL-Anwendung im User-Account etwas bei rumgekommen wäre. :roll:

Ich habe es auch schon gelesen, auch hier im Forum gab es schon etwas dazu. Danke. Ich teste es jetzt mal als Service.

Dalai 9. Nov 2017 15:29

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Anders ausgedrückt: Du musst zusätzlich noch prüfen, ob dein Code im Dienst läuft oder nicht, und WTSQueryUserToken nur aufrufen, wenn es im Dienst ist.

Grüße
Dalai

361 9. Nov 2017 15:35

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
@Dalai: Ja, ich weiß. Ich bin gerade am Testen und berichte gleich noch einmal dazu :)

361 9. Nov 2017 15:51

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Zusammenfassung: Der von TiGü gepostete Code funktioniert nach meinen Tests unter Windows XP, Windows 7, Windows 10 (1703) und Windows Server 2016.

ACHTUNG: Der Code funktioniert nicht, wenn nur eine RDP-Session besteht jedoch keine Benutzer angemeldet sind. Dazu gibt es im MSDN auch einige Informationen zu finden und in diesem Fall erhält man folgende Fehlermeldung:
Zitat:

System Error. Code: 1008.Es wurde versucht, auf ein Token zuzugreifen, das nicht vorhanden ist
Vielen Dank noch einmal für Eure Hilfe und ich hoffe, der Code hilft vielleicht dem einen oder anderen auch weiter.

Viele Grüße

361 9. Nov 2017 16:37

AW: Windows 10 - GetModuleHandle('USER32.DLL') & LockWorkStation funktioniert nicht
 
Problem gelöst (Thema keine offene Frage mehr) :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:12 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