Skip to content

Commit

Permalink
PR 6616045: Hand off to Windows Terminal Stable by default (!)
Browse files Browse the repository at this point in the history
This commit also introduces a check that we are in an interactive
session before we perform handoff, so as to not break service accounts.

It also adds some tracing.
  • Loading branch information
leonMSFT authored and DHowett committed Jan 25, 2022
1 parent 038917d commit 33c2cd4
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/host/sources.inc
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ TARGETLIBS = \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-rawinput-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-sysparams-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-window-ext-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-winstamin-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-shell-shell32-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uxtheme-themes-l1.lib \
$(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-dataobject-l1.lib \
Expand Down Expand Up @@ -234,6 +235,7 @@ DELAYLOAD = \
ext-ms-win-rtcore-ntuser-rawinput-l1.dll; \
ext-ms-win-rtcore-ntuser-sysparams-l1.dll; \
ext-ms-win-rtcore-ntuser-window-ext-l1.dll; \
ext-ms-win-rtcore-ntuser-winstamin-l1.dll; \
ext-ms-win-shell-shell32-l1.dll; \
ext-ms-win-uiacore-l1.dll; \
ext-ms-win-uxtheme-themes-l1.dll; \
Expand Down
1 change: 1 addition & 0 deletions src/inc/conint.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ namespace Microsoft::Console::Internal
namespace DefaultApp
{
[[nodiscard]] HRESULT CheckDefaultAppPolicy(bool& isEnabled) noexcept;
[[nodiscard]] HRESULT CheckShouldTerminalBeDefault(bool& isEnabled) noexcept;
}
}
2 changes: 2 additions & 0 deletions src/interactivity/win32/ut_interactivity_win32/sources
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ TARGETLIBS = \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-rawinput-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-sysparams-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-window-ext-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-winstamin-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-shell-shell32-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uxtheme-themes-l1.lib \
$(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-dataobject-l1.lib \
Expand Down Expand Up @@ -132,6 +133,7 @@ DELAYLOAD = \
ext-ms-win-rtcore-ntuser-rawinput-l1.dll; \
ext-ms-win-rtcore-ntuser-sysparams-l1.dll; \
ext-ms-win-rtcore-ntuser-window-ext-l1.dll; \
ext-ms-win-rtcore-ntuser-winstamin-l1.dll; \
ext-ms-win-shell-shell32-l1.dll; \
ext-ms-win-uiacore-l1.dll; \
ext-ms-win-uxtheme-themes-l1.dll; \
Expand Down
9 changes: 9 additions & 0 deletions src/internal/stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,12 @@ void EdpPolicy::AuditClipboard(const std::wstring_view /*destinationName*/) noex
isEnabled = true;
return S_OK;
}

[[nodiscard]] HRESULT DefaultApp::CheckShouldTerminalBeDefault(bool& isEnabled) noexcept
{
// False since setting Terminal as the default app is an OS feature and probably
// should not be done in the open source conhost. We can always decide to turn it
// on in the future though.
isEnabled = false;
return S_OK;
}
37 changes: 35 additions & 2 deletions src/propslib/DelegationConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <Windows.ApplicationModel.h>
#include <Windows.ApplicationModel.AppExtensions.h>

#include "../inc/conint.h"

using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
Expand All @@ -25,6 +27,9 @@ using namespace ABI::Windows::ApplicationModel::AppExtensions;
#define DELEGATION_CONSOLE_KEY_NAME L"DelegationConsole"
#define DELEGATION_TERMINAL_KEY_NAME L"DelegationTerminal"

#define SYSTEM_DELEGATION_CONSOLE_KEY_NAME L"SystemDelegationConsole"
#define SYSTEM_DELEGATION_TERMINAL_KEY_NAME L"SystemDelegationTerminal"

#define DELEGATION_CONSOLE_EXTENSION_NAME L"com.microsoft.windows.console.host"
#define DELEGATION_TERMINAL_EXTENSION_NAME L"com.microsoft.windows.terminal.host"

Expand Down Expand Up @@ -262,13 +267,41 @@ CATCH_RETURN()
[[nodiscard]] HRESULT DelegationConfig::s_GetDefaultConsoleId(IID& iid) noexcept
{
iid = { 0 };
return s_Get(DELEGATION_CONSOLE_KEY_NAME, iid);

auto hr = s_Get(DELEGATION_CONSOLE_KEY_NAME, iid);

bool defApp = false;
if (SUCCEEDED(Microsoft::Console::Internal::DefaultApp::CheckShouldTerminalBeDefault(defApp)) && defApp)
{
if (FAILED(hr))
{
// If we can't find a user-defined delegation console/terminal, use the system-defined
// delegation console/terminal instead.
hr = s_Get(SYSTEM_DELEGATION_CONSOLE_KEY_NAME, iid);
}
}

return hr;
}

[[nodiscard]] HRESULT DelegationConfig::s_GetDefaultTerminalId(IID& iid) noexcept
{
iid = { 0 };
return s_Get(DELEGATION_TERMINAL_KEY_NAME, iid);

auto hr = s_Get(DELEGATION_TERMINAL_KEY_NAME, iid);

bool defApp = false;
if (SUCCEEDED(Microsoft::Console::Internal::DefaultApp::CheckShouldTerminalBeDefault(defApp)) && defApp)
{
if (FAILED(hr))
{
// If we can't find a user-defined delegation console/terminal, use the system-defined
// delegation console/terminal instead.
hr = s_Get(SYSTEM_DELEGATION_TERMINAL_KEY_NAME, iid);
}
}

return hr;
}

[[nodiscard]] HRESULT DelegationConfig::s_Get(PCWSTR value, IID& iid) noexcept
Expand Down
57 changes: 56 additions & 1 deletion src/server/IoDispatchers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,31 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleCloseObject(_In_ PCONSOLE_API_MSG pMessag
return pMessage;
}

// LsaGetLoginSessionData might also fit the bill here, but it looks like it does RPC with lsass.exe. Using user32 is cheaper.
static bool _isInteractiveUserSession()
{
DWORD sessionId{};
if (ProcessIdToSessionId(GetCurrentProcessId(), &sessionId) && sessionId == 0)
{
return false;
}

// don't call CloseWindowStation on GetProcessWindowStation handle or switch this to a unique_hwinsta
HWINSTA winsta{ GetProcessWindowStation() };
if (winsta)
{
USEROBJECTFLAGS flags{};
if (GetUserObjectInformationW(winsta, UOI_FLAGS, &flags, sizeof(flags), nullptr))
{
// An invisible window station suggests that we aren't interactive.
return WI_IsFlagSet(flags.dwFlags, WSF_VISIBLE);
}
}

// Assume that we are interactive if the flags can't be looked up or there's no window station
return true;
}

// Routine Description:
// - Uses some information about current console state and
// the incoming process state and preferences to determine
Expand All @@ -152,6 +177,15 @@ static bool _shouldAttemptHandoff(const Globals& globals,

#else

// Service desktops and non-interactive sessions should not
// try to hand off -- they probably don't have any terminals
// installed, and we don't want to risk breaking a service if
// they *do*.
if (!_isInteractiveUserSession())
{
return false;
}

// This console was started with a command line argument to
// specifically block handoff to another console. We presume
// this was for good reason (compatibility) and give up here.
Expand Down Expand Up @@ -341,6 +375,13 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleHandleConnectionRequest(_In_ PCONSOLE_API
// Start it if it was successfully created.
THROW_IF_FAILED(hostSignalThread->Start());

TraceLoggingWrite(g_hConhostV2EventTraceProvider,
"ConsoleHandoffSucceeded",
TraceLoggingDescription("successfully handed off console connection"),
TraceLoggingGuid(Globals.handoffConsoleClsid.value(), "handoffCLSID"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));

// Unlock in case anything tries to spool down as we exit.
UnlockConsole();

Expand All @@ -350,7 +391,21 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleHandleConnectionRequest(_In_ PCONSOLE_API
// Exit process to clean up any outstanding things we have open.
ExitProcess(S_OK);
}
CATCH_LOG(); // Just log, don't do anything more. We'll move on to launching normally on failure.
catch (...)
{
const auto hr = wil::ResultFromCaughtException();

TraceLoggingWrite(g_hConhostV2EventTraceProvider,
"ConsoleHandoffFailed",
TraceLoggingDescription("failed while attempting handoff"),
TraceLoggingGuid(Globals.handoffConsoleClsid.value(), "handoffCLSID"),
TraceLoggingHResult(hr),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));

// Just log, don't do anything more. We'll move on to launching normally on failure.
LOG_CAUGHT_EXCEPTION();
}
}

Status = NTSTATUS_FROM_HRESULT(gci.ProcessHandleList.AllocProcessData(dwProcessId,
Expand Down
2 changes: 2 additions & 0 deletions src/terminal/adapter/ut_adapter/sources
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ TARGETLIBS = \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-rawinput-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-sysparams-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-window-ext-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-winstamin-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-shell-shell32-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uxtheme-themes-l1.lib \
$(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-dataobject-l1.lib \
Expand Down Expand Up @@ -131,6 +132,7 @@ DELAYLOAD = \
ext-ms-win-rtcore-ntuser-rawinput-l1.dll; \
ext-ms-win-rtcore-ntuser-sysparams-l1.dll; \
ext-ms-win-rtcore-ntuser-window-ext-l1.dll; \
ext-ms-win-rtcore-ntuser-winstamin-l1.dll; \
ext-ms-win-shell-shell32-l1.dll; \
ext-ms-win-uiacore-l1.dll; \
ext-ms-win-uxtheme-themes-l1.dll; \
Expand Down
2 changes: 2 additions & 0 deletions src/terminal/parser/ut_parser/sources
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ TARGETLIBS = \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-rawinput-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-sysparams-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-window-ext-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-winstamin-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-shell-shell32-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uxtheme-themes-l1.lib \
$(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-dataobject-l1.lib \
Expand Down Expand Up @@ -128,6 +129,7 @@ DELAYLOAD = \
ext-ms-win-rtcore-ntuser-rawinput-l1.dll; \
ext-ms-win-rtcore-ntuser-sysparams-l1.dll; \
ext-ms-win-rtcore-ntuser-window-ext-l1.dll; \
ext-ms-win-rtcore-ntuser-winstamin-l1.dll; \
ext-ms-win-shell-shell32-l1.dll; \
ext-ms-win-uiacore-l1.dll; \
ext-ms-win-uxtheme-themes-l1.dll; \
Expand Down

0 comments on commit 33c2cd4

Please sign in to comment.