Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow remote control consent and chat on Windows Login screen. #924

Merged
merged 1 commit into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions Agent/Services/Windows/AppLauncherWin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ public async Task<int> LaunchChatService(string pipeName, string userConnectionI
$" --org-name \"{orgName}\"" +
$" --org-id \"{orgId}\"",
targetSessionId: -1,
forceConsoleSession: false,
desktopName: "default",
hiddenWindow: false,
out var procInfo);
if (!result)
Expand Down Expand Up @@ -122,8 +120,6 @@ await hubConnection.SendAsync("DisplayMessage",
$" --session-id \"{sessionId}\"" +
$" --access-key \"{accessKey}\"",
targetSessionId: targetSessionId,
forceConsoleSession: Shlwapi.IsOS(OsType.OS_ANYSERVER) && targetSessionId == -1,
desktopName: "default",
hiddenWindow: false,
out _);
if (!result)
Expand Down Expand Up @@ -180,8 +176,6 @@ public async Task RestartScreenCaster(string[] viewerIds, string sessionId, stri
$" --viewers {string.Join(",", viewerIds)}",

targetSessionId: targetSessionID,
forceConsoleSession: Shlwapi.IsOS(OsType.OS_ANYSERVER) && targetSessionID == -1,
desktopName: "default",
hiddenWindow: false,
out _);

Expand Down
73 changes: 52 additions & 21 deletions Desktop.Native/Windows/Win32Interop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,9 @@ public static nint OpenInputDesktop()

public static bool CreateInteractiveSystemProcess(
string commandLine,
int targetSessionId,
bool forceConsoleSession,
string desktopName,
bool hiddenWindow,
out PROCESS_INFORMATION procInfo)
int targetSessionId,
bool hiddenWindow,
out PROCESS_INFORMATION procInfo)
{
uint winlogonPid = 0;
var hUserTokenDup = nint.Zero;
Expand All @@ -117,21 +115,7 @@ public static bool CreateInteractiveSystemProcess(

procInfo = new PROCESS_INFORMATION();

// If not force console, find target session. If not present,
// use last active session.
var dwSessionId = Kernel32.WTSGetActiveConsoleSessionId();
if (!forceConsoleSession)
{
var activeSessions = GetActiveSessions();
if (activeSessions.Any(x => x.Id == targetSessionId))
{
dwSessionId = (uint)targetSessionId;
}
else
{
dwSessionId = activeSessions.Last().Id;
}
}
var dwSessionId = ResolveWindowsSession(targetSessionId);

// Obtain the process ID of the winlogon process that is running within the currently active session.
var processes = Process.GetProcessesByName("winlogon");
Expand Down Expand Up @@ -171,7 +155,7 @@ public static bool CreateInteractiveSystemProcess(
// interaction with the new process.
var si = new STARTUPINFO();
si.cb = Marshal.SizeOf(si);
si.lpDesktop = @"winsta0\" + desktopName;
si.lpDesktop = @"winsta0\" + ResolveDesktopName(dwSessionId);

// Flags that specify the priority and creation method of the process.
uint dwCreationFlags;
Expand Down Expand Up @@ -208,6 +192,53 @@ public static bool CreateInteractiveSystemProcess(
return result;
}

public static string ResolveDesktopName(uint targetSessionId)
{
var winDir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
var logonUiPath = Path.Combine(winDir, "System32", "LogonUI.exe");
var consentPath = Path.Combine(winDir, "System32", "consent.exe");

var isLogonScreenVisible = Process
.GetProcessesByName("LogonUI")
.Any(x => x.SessionId == targetSessionId && x.MainModule?.FileName.Equals(logonUiPath, StringComparison.OrdinalIgnoreCase) == true);

var isSecureDesktopVisible = Process
.GetProcessesByName("consent")
.Any(x => x.SessionId == targetSessionId && x.MainModule?.FileName.Equals(consentPath, StringComparison.OrdinalIgnoreCase) == true);

if (isLogonScreenVisible || isSecureDesktopVisible)
{
return "Winlogon";
}

return "Default";
}

public static uint ResolveWindowsSession(int targetSessionId)
{
var activeSessions = GetActiveSessions();
if (activeSessions.Any(x => x.Id == targetSessionId))
{
// If exact match is found, return that session.
return (uint)targetSessionId;
}

if (Shlwapi.IsOS(OsType.OS_ANYSERVER))
{
// If Windows Server, default to console session.
return Kernel32.WTSGetActiveConsoleSessionId();
}

// If consumer version and there's an RDP session active, return that.
if (activeSessions.Find(x => x.Type == WindowsSessionType.RDP) is { } rdSession)
{
return rdSession.Id;
}

// Otherwise, return the console session.
return Kernel32.WTSGetActiveConsoleSessionId();
}

public static void SetMonitorState(MonitorState state)
{
SendMessage(0xFFFF, 0x112, 0xF170, (int)state);
Expand Down
2 changes: 0 additions & 2 deletions Desktop.Shared/Startup/IServiceProviderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,6 @@ private static void RelaunchElevated()
commandLine,
-1,
false,
"default",
true,
out var procInfo);
Console.WriteLine($"Elevate result: {result}. Process ID: {procInfo.dwProcessId}.");
Environment.Exit(0);
Expand Down
Loading