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.

Merged PR 6882227: [Git2Git] Merged PR 6881763: Change to hardcoded system GUIDs to appease manifest validation

Manifest validation won't accept migration/initialization of HKCU-based registry keys anymore. The enforcement scripts says that they should be defined in code instead. So here it is: defined in code insteead.

Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 67c720b628de4acefbc381891b7e7d29d387038e

Related work items: MSFT-37867666
  • Loading branch information
leonMSFT authored and DHowett committed Jan 31, 2022
1 parent 42e5671 commit 2c3bf18
Show file tree
Hide file tree
Showing 8 changed files with 113 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;
}
41 changes: 39 additions & 2 deletions src/propslib/DelegationConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
#include <Windows.ApplicationModel.h>
#include <Windows.ApplicationModel.AppExtensions.h>

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

#include <initguid.h>

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

DEFINE_GUID(CLSID_SystemDelegationConsole, 0x2eaca947, 0x7f5f, 0x4cfa, 0xba, 0x87, 0x8f, 0x7f, 0xbe, 0xef, 0xbe, 0x69);
DEFINE_GUID(CLSID_SystemDelegationTerminal, 0xe12cff52, 0xa866, 0x4c77, 0x9a, 0x90, 0xf5, 0x70, 0xa7, 0xaa, 0x2c, 0x6b);

#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 +269,43 @@ 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 hardcoded
// delegation console/terminal instead.
iid = CLSID_SystemDelegationConsole;
hr = S_OK;
}
}

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 hardcoded
// delegation console/terminal instead.
iid = CLSID_SystemDelegationTerminal;
hr = S_OK;
}
}

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 @@ -139,6 +139,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 @@ -160,6 +185,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 @@ -334,6 +368,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 @@ -343,7 +384,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

1 comment on commit 2c3bf18

@github-actions
Copy link

@github-actions github-actions bot commented on 2c3bf18 Jan 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@check-spelling-bot Report

Unrecognized words, please review:

  • hwinsta
  • Lsa
  • lsass
  • UOI
  • USEROBJECTFLAGS
  • winsta
  • winstamin
  • WSF
Previously acknowledged words that are now absent adaa carlos coffgroup coffgrp datetime deconstructed devicefamily dpg eae emplate GENPROFILE GTR guardxfg HHmm Hostx installationpath MMdd pgorepro pgort PGU sid SPACEBAR timelines Unregister vcvarsall xfg xIcon yIcon zamora
To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands

... in a clone of the git@github.com:microsoft/terminal.git repository
on the release-1.12 branch:

update_files() {
perl -e '
my @expect_files=qw('".github/actions/spelling/expect/alphabet.txt
.github/actions/spelling/expect/expect.txt
.github/actions/spelling/expect/web.txt"');
@ARGV=@expect_files;
my @stale=qw('"$patch_remove"');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spelling/expect/2c3bf1880d7f14372376a0e94ed70ef7d572bff3.txt";
use File::Path qw(make_path);
use File::Basename qw(dirname);
make_path (dirname($new_expect_file));
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"$patch_add"');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a)."-".$a cmp lc($b)."-".$b} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;
system("git", "add", $new_expect_file);
'
}

comment_json=$(mktemp)
curl -L -s -S \
  --header "Content-Type: application/json" \
  "https://api.github.com/repos/microsoft/terminal/comments/65705276" > "$comment_json"
comment_body=$(mktemp)
jq -r .body < "$comment_json" > $comment_body
rm $comment_json

patch_remove=$(perl -ne 'next unless s{^</summary>(.*)</details>$}{$1}; print' < "$comment_body")
  

patch_add=$(perl -e '$/=undef;
$_=<>;
s{<details>.*}{}s;
s{^#.*}{};
s{\n##.*}{};
s{(?:^|\n)\s*\*}{}g;
s{\s+}{ }g;
print' < "$comment_body")
  
update_files
rm $comment_body
git add -u
✏️ Contributor please read this

By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.

⚠️ The command is written for posix shells. You can copy the contents of each perl command excluding the outer ' marks and dropping any '"/"' quotation mark pairs into a file and then run perl file.pl from the root of the repository to run the code. Alternatively, you can manually insert the items...

If the listed items are:

  • ... misspelled, then please correct them instead of using the command.
  • ... names, please add them to .github/actions/spelling/allow/names.txt.
  • ... APIs, you can add them to a file in .github/actions/spelling/allow/.
  • ... just things you're using, please add them to an appropriate file in .github/actions/spelling/expect/.
  • ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in .github/actions/spelling/patterns/.

See the README.md in each directory for more information.

🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉

🗜️ If you see a bunch of garbage

If it relates to a ...

well-formed pattern

See if there's a pattern that would match it.

If not, try writing one and adding it to a patterns/{file}.txt.

Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

Note that patterns can't match multiline strings.

binary-ish string

Please add a file path to the excludes.txt file instead of just accepting the garbage.

File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

Please sign in to comment.