stascorp / rdpwrap

RDP Wrapper Library
Apache License 2.0
14.68k stars 3.83k forks source link

Disable blocking the UI on session lock or disconnect #3127

Open afish opened 5 months ago

afish commented 5 months ago

Let's say that I use mstsc.exe to connect between machines like this:

Local ----> Windows Server 2016 ----> Remote

If I close mstsc.exe on Local or lock the workstation with WIN+L on Local, then the GUI on Remote works well. For instance, I can connect to Remote directly with VNC or use applications that capture the screen.

However, when I use Windows Server 2019

Local ----> Windows Server 2019 ----> Remote

then it doesn't work anymore. Disconnecting mstsc.exe on Local or locking the workstation with WIN+L on local makes the GUI on Remote inaccessible until I reconnect. I hoped maybe setting RemoteDesktop_SuppressWhenMinimized on Windows Server 2019 but it didn't help (the GUI on Remote is still inaccessible after I close mstsc.exe on Local). I'm quite sure Windows Server 2012 worked just like Windows Server 2016 (so it wasn't making GUI inaccessible on mstsc.exe close or workstation lock). I also see I'm not the only one that was using this trick: https://stackoverflow.com/a/15954852

Is it possible to patch termsrv.dll in Windows 10 or Windows Server 2019 to restore the behavior of Windows Server 2016 (so not make the GUI inaccessible)? If you happen to have any knowledge about how this mechanism works, which API functions are used to disable the GUI, or any technical terms explaining the behavior, I'd appreciate if you share them.

binarymaster commented 5 months ago

It's not possible for the session to be active (thus screenshot-able) when client is not connected. The client has to be an active RDP session or the server console.

afish commented 5 months ago

Like I said above, it is possible with Windows Server 2016 as a jump host even today. I'm not experienced enough with WinAPI or Windows internals to explain why they are different, but I guess Windows Server 2019 detects that Local disconnects (or locks the workstation) and handles the situation (disconnects the GUI) explicitly.

afish commented 5 months ago

Just to shed some more light:

  1. If you stop mstsc.exe from getting the WinAPI notification about the workstation lock, then the UI is not detached when the user presses WIN+L. Therefore, this must be an explicit action caused by mstsc.exe sending something to the terminal server.
  2. Similarly, if you keep the TCP connection alive with mstsc.exe suspended (for instance by task manager or debugger), then the UI doesn't break even thought mstsc.exe is not responding. You can even kill mstsc.exe as long as something keeps the TCP connection up.

You can read more in my article if you want to learn the details https://blog.adamfurmanek.pl/2024/06/05/bit-twiddling-part-6/

Based on the above, the UI disconnection must be somewhere in the terminal services. There must be some code that explicitly "disconnects" the UI when the client notifies about the workstation lock or terminates gracefully.

binarymaster commented 5 months ago

I'm only aware that mstsc.exe sends inactive notifications to the server when minimizing its window, perhaps they recently added the same reaction to workstation locking at the client side.