LizardByte / Sunshine

Self-hosted game stream host for Moonlight.
http://app.lizardbyte.dev/Sunshine/
GNU General Public License v3.0
18.44k stars 893 forks source link

WTSGetActiveConsoleSessionId returns 0 when user only logged in from Remote Desktop #2119

Closed fffonion closed 6 months ago

fffonion commented 7 months ago

Is there an existing issue for this?

Is your issue described in the documentation?

Is your issue present in the nightly release?

Describe the Bug

When a user has only logged in to the Remote Desktop, WTSGetActiveConsoleSessionId could return 0, and causes following to fail (src/platform/windows/misc.cpp):

if (!WTSQueryUserToken(consoleSessionId, &userToken)) {
      BOOST_LOG(debug) << "QueryUserToken failed, this would prevent commands from launching under the users profile.";
      return nullptr;
    }

And further fails to run elevated command randomly.

Ref

Expected Behavior

No response

Additional Context

No response

Host Operating System

Windows

Operating System Version

Windows 11 Pro 22631.3085

Architecture

64 bit

Sunshine commit or version

0.21.0.358aac9277dce563817c0d3cf7a020478275ecf9

Package

Windows - installer

GPU Type

Nvidia

GPU Model

GeForce RTX 4090D

GPU Driver/Mesa Version

551.23

Capture Method (Linux Only)

No response

Config

<empty>

Apps

No response

Relevant log output

[2024:02:08:21:53:38]: Info: Executing Do Cmd: [cmd /C reg add HKCU\Software\miHoYo\原神 /v "Screenmanager Resolution Width_h182942802" /t REG_DWORD /d %SUNSHINE_CLIENT_WIDTH% /f]
[2024:02:08:21:53:38]: Debug: QueryUserToken failed, this would prevent commands from launching under the users profile.
[2024:02:08:21:53:38]: Error: Couldn't run [cmd /C reg add HKCU\Software\miHoYo\原神 /v "Screenmanager Resolution Width_h182942802" /t REG_DWORD /d %SUNSHINE_CLIENT_WIDTH% /f]: System: Permission denied
ReenigneArcher commented 7 months ago

Not really any value in fixing this, since streaming won't work when the user is connected via a RDP session anyway.

fffonion commented 7 months ago

streaming won't work when the user is connected via a RDP session anyway.

@ReenigneArcher Actually, this is limitation that current implementation causes. Because it always finds the RDP session as "active" session. I have a PoC code here that modifies from the linked stackoverflow thread, and verifies it's working. When a physical console connects (either from a realworld monitor or Sunshine starts an application), RDP will automatically close. Well technically you still stcan't have both RDP session and Sunshine streaming at same time, but this is not the issue I'm proposing at this issue.

Although this solution could not solve the case where no other user has logged in apart from the RDP session. However, it could be solved by either logged in using a physical monitor, or use the "Desktop" app to create a logged in session.

fffonion commented 7 months ago

This will be a very useful feature or fix if user doesn't want their physical monitor to always on when streaming.

Please consider the following use case:

In current implementation, this workflow won't work. One will have to go to the computer physically login once in order for the elevation to work properly.

ReenigneArcher commented 7 months ago

The Windows desktop duplication API does not allow us to capture the screen if you are simultaneously using a RDP session.

fffonion commented 7 months ago

@ReenigneArcher you are absolutely right. I'm not trying to use Sunshine and RDP at the same time, but found that Sunshine is incorrectly picking up a session (maybe a disconnected RDP session? not having enough win32api knowledge to figure out a shortest reproduction path) and fails to impersonate user from it, instead of using the session that are not logged in from RDP. The evidence is that if session is found at all, WTSGetActiveConsoleSessionId should have returned 0xFFFFFFFF instead, and throw a different debug message.

cgutman commented 7 months ago

What are you expecting Sunshine to do in this case? You have an RDP session active and no session active at the physical console.

Are you expecting Sunshine to launch your app inside the RDP session then just stream the login screen and wait for you to sign in?

fffonion commented 7 months ago

@cgutman My typical workflow is to use the "Desktop" application in Sunshine to login, close it, and then switch to the actual game application (with elevation) for streaming. And it works without issue. Sometimes, I would also use RDP to do some unrelated work, like copy a file etc. And if I do my "typical workflow" after I do the RDP session, it seems Sunshine would have trouble finding the correct session.

And unfortunately I can't reproduce this issue with a simple RDP login, close it (which automatically logs out), Sunshine desktop login, stream an application with elevation. But it does happen several times before.

Are you expecting Sunshine to launch your app inside the RDP session then just stream the login screen and wait for you to sign in?

That would work as well yes. But having RDP session open when I start streaming is not really a requirement on my side. I usually already closed the RDP session before I start streaming.

SPdevs commented 7 months ago

Not really any value in fixing this, since streaming won't work when the user is connected via a RDP session anyway.

It works if you're running a portable version of sunshine in the RDP session. Works for me. I have to use RDP daily for work and its too laggy for me so I run a portable Version of sunlight in every session and is able to connect to it on 5+ sessions at the same time without much problems.

Nonary commented 6 months ago

Closing this issue again, this is a limitation of the Windows API. We cannot impersonate user sessions if there is no active console session.