Skip to content

Commit

Permalink
Launch app into Winlogon desktop when LogonUI.exe or consent.exe is p…
Browse files Browse the repository at this point in the history
…resent in the target session.
  • Loading branch information
bitbound committed Aug 6, 2024
1 parent 8417df7 commit 232ab26
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 29 deletions.
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

0 comments on commit 232ab26

Please sign in to comment.