diff --git a/src/host/ConsoleArguments.cpp b/src/host/ConsoleArguments.cpp index 7bd34b8392..a95bb38002 100644 --- a/src/host/ConsoleArguments.cpp +++ b/src/host/ConsoleArguments.cpp @@ -14,6 +14,7 @@ const std::wstring_view ConsoleArguments::SIGNAL_HANDLE_ARG = L"--signal"; const std::wstring_view ConsoleArguments::HANDLE_PREFIX = L"0x"; const std::wstring_view ConsoleArguments::CLIENT_COMMANDLINE_ARG = L"--"; const std::wstring_view ConsoleArguments::FORCE_V1_ARG = L"-ForceV1"; +const std::wstring_view ConsoleArguments::FORCE_NO_HANDOFF_ARG = L"-ForceNoHandoff"; const std::wstring_view ConsoleArguments::FILEPATH_LEADER_PREFIX = L"\\??\\"; const std::wstring_view ConsoleArguments::WIDTH_ARG = L"--width"; const std::wstring_view ConsoleArguments::HEIGHT_ARG = L"--height"; @@ -115,6 +116,7 @@ ConsoleArguments::ConsoleArguments(const std::wstring& commandline, _serverHandle = 0; _signalHandle = 0; _forceV1 = false; + _forceNoHandoff = false; _width = 0; _height = 0; _inheritCursor = false; @@ -144,6 +146,7 @@ ConsoleArguments& ConsoleArguments::operator=(const ConsoleArguments& other) _inheritCursor = other._inheritCursor; _receivedEarlySizeChange = other._receivedEarlySizeChange; _runAsComServer = other._runAsComServer; + _forceNoHandoff = other._forceNoHandoff; } return *this; @@ -449,6 +452,13 @@ void ConsoleArguments::s_ConsumeArg(_Inout_ std::vector& args, _In s_ConsumeArg(args, i); hr = S_OK; } + else if (arg == FORCE_NO_HANDOFF_ARG) + { + // Prevent default application handoff to a different console/terminal + _forceNoHandoff = true; + s_ConsumeArg(args, i); + hr = S_OK; + } else if (arg == COM_SERVER_ARG) { _runAsComServer = true; @@ -630,6 +640,11 @@ bool ConsoleArguments::GetForceV1() const return _forceV1; } +bool ConsoleArguments::GetForceNoHandoff() const +{ + return _forceNoHandoff; +} + short ConsoleArguments::GetWidth() const { return _width; diff --git a/src/host/ConsoleArguments.hpp b/src/host/ConsoleArguments.hpp index 86c43be056..5d0e5b31ea 100644 --- a/src/host/ConsoleArguments.hpp +++ b/src/host/ConsoleArguments.hpp @@ -48,6 +48,7 @@ public: std::wstring GetClientCommandline() const; std::wstring GetVtMode() const; bool GetForceV1() const; + bool GetForceNoHandoff() const; short GetWidth() const; short GetHeight() const; @@ -68,6 +69,7 @@ public: static const std::wstring_view HANDLE_PREFIX; static const std::wstring_view CLIENT_COMMANDLINE_ARG; static const std::wstring_view FORCE_V1_ARG; + static const std::wstring_view FORCE_NO_HANDOFF_ARG; static const std::wstring_view FILEPATH_LEADER_PREFIX; static const std::wstring_view WIDTH_ARG; static const std::wstring_view HEIGHT_ARG; @@ -89,6 +91,7 @@ private: const short width, const short height, const bool forceV1, + const bool forceNoHandoff, const bool headless, const bool createServerHandle, const DWORD serverHandle, @@ -103,6 +106,7 @@ private: _width(width), _height(height), _forceV1(forceV1), + _forceNoHandoff(forceNoHandoff), _headless(headless), _createServerHandle(createServerHandle), _serverHandle(serverHandle), @@ -127,6 +131,7 @@ private: std::wstring _vtMode; + bool _forceNoHandoff; bool _forceV1; bool _headless; diff --git a/src/host/ut_host/ConsoleArgumentsTests.cpp b/src/host/ut_host/ConsoleArgumentsTests.cpp index b210899b76..69ab4debe8 100644 --- a/src/host/ut_host/ConsoleArgumentsTests.cpp +++ b/src/host/ut_host/ConsoleArgumentsTests.cpp @@ -77,6 +77,7 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff true, // headless true, // createServerHandle 0, // serverHandle @@ -98,6 +99,7 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -119,6 +121,7 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff true, // headless true, // createServerHandle 0, // serverHandle @@ -140,6 +143,7 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff true, // headless false, // createServerHandle 0x4, // serverHandle @@ -161,6 +165,7 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff true, // headless true, // createServerHandle 0, // serverHandle @@ -182,6 +187,7 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -203,6 +209,7 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -224,6 +231,7 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -245,6 +253,7 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -271,6 +280,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -292,6 +302,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -313,6 +324,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -334,6 +346,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -355,6 +368,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -376,6 +390,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -397,6 +412,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -418,6 +434,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff true, // headless true, // createServerHandle 0, // serverHandle @@ -439,6 +456,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -460,6 +478,7 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -486,6 +505,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless false, // createServerHandle 4ul, // serverHandle @@ -507,6 +527,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless false, // createServerHandle 4ul, // serverHandle @@ -528,6 +549,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless false, // createServerHandle 4ul, // serverHandle @@ -549,6 +571,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless false, // createServerHandle 4ul, // serverHandle @@ -570,6 +593,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless false, // createServerHandle 4ul, // serverHandle @@ -591,6 +615,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless false, // createServerHandle 4ul, // serverHandle @@ -612,6 +637,7 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 0, // width 0, // height true, // forceV1 + false, // forceNoHandoff false, // headless false, // createServerHandle 4ul, // serverHandle @@ -633,6 +659,51 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 0, // width 0, // height true, // forceV1 + false, // forceNoHandoff + false, // headless + true, // createServerHandle + 0, // serverHandle + 0, // signalHandle + false, // inheritCursor + false), // runAsComServer + true); // successful parse? + + commandline = L"conhost.exe 0x4 -ForceNoHandoff"; + ArgTestsRunner(L"#9 #7 Check that ConDrv handle + -ForceNoHandoff succeeds", + commandline, + INVALID_HANDLE_VALUE, + INVALID_HANDLE_VALUE, + ConsoleArguments(commandline, + L"", // clientCommandLine + INVALID_HANDLE_VALUE, + INVALID_HANDLE_VALUE, + L"", // vtMode + 0, // width + 0, // height + false, // forceV1 + true, // forceNoHandoff + false, // headless + false, // createServerHandle + 4ul, // serverHandle + 0, // signalHandle + false, // inheritCursor + false), // runAsComServer + true); // successful parse? + + commandline = L"conhost.exe -ForceNoHandoff"; + ArgTestsRunner(L"#10 Check that -ForceNoHandoff parses on its own", + commandline, + INVALID_HANDLE_VALUE, + INVALID_HANDLE_VALUE, + ConsoleArguments(commandline, + L"", // clientCommandLine + INVALID_HANDLE_VALUE, + INVALID_HANDLE_VALUE, + L"", // vtMode + 0, // width + 0, // height + false, // forceV1 + true, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -683,6 +754,7 @@ void ConsoleArgumentsTests::CombineVtPipeHandleTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0ul, // serverHandle @@ -704,6 +776,7 @@ void ConsoleArgumentsTests::CombineVtPipeHandleTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0ul, // serverHandle @@ -740,6 +813,7 @@ void ConsoleArgumentsTests::InitialSizeTests() 120, // width 30, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0ul, // serverHandle @@ -761,6 +835,7 @@ void ConsoleArgumentsTests::InitialSizeTests() 120, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0ul, // serverHandle @@ -782,6 +857,7 @@ void ConsoleArgumentsTests::InitialSizeTests() 0, // width 30, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0ul, // serverHandle @@ -803,6 +879,7 @@ void ConsoleArgumentsTests::InitialSizeTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0ul, // serverHandle @@ -824,6 +901,7 @@ void ConsoleArgumentsTests::InitialSizeTests() -1, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0ul, // serverHandle @@ -845,6 +923,7 @@ void ConsoleArgumentsTests::InitialSizeTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0ul, // serverHandle @@ -866,6 +945,7 @@ void ConsoleArgumentsTests::InitialSizeTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0ul, // serverHandle @@ -887,6 +967,7 @@ void ConsoleArgumentsTests::InitialSizeTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0ul, // serverHandle @@ -913,6 +994,7 @@ void ConsoleArgumentsTests::HeadlessArgTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff true, // headless true, // createServerHandle 0, // serverHandle @@ -934,6 +1016,7 @@ void ConsoleArgumentsTests::HeadlessArgTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff true, // headless false, // createServerHandle 4ul, // serverHandle @@ -955,6 +1038,7 @@ void ConsoleArgumentsTests::HeadlessArgTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff true, // headless true, // createServerHandle 0, // serverHandle @@ -976,6 +1060,7 @@ void ConsoleArgumentsTests::HeadlessArgTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -1006,6 +1091,7 @@ void ConsoleArgumentsTests::SignalHandleTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless false, // createServerHandle 4ul, // serverHandle @@ -1027,6 +1113,7 @@ void ConsoleArgumentsTests::SignalHandleTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless false, // createServerHandle 4ul, // serverHandle @@ -1048,6 +1135,7 @@ void ConsoleArgumentsTests::SignalHandleTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0ul, // serverHandle @@ -1078,6 +1166,7 @@ void ConsoleArgumentsTests::FeatureArgTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -1098,6 +1187,7 @@ void ConsoleArgumentsTests::FeatureArgTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -1119,6 +1209,7 @@ void ConsoleArgumentsTests::FeatureArgTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -1140,6 +1231,7 @@ void ConsoleArgumentsTests::FeatureArgTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -1161,6 +1253,7 @@ void ConsoleArgumentsTests::FeatureArgTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle @@ -1182,6 +1275,7 @@ void ConsoleArgumentsTests::FeatureArgTests() 0, // width 0, // height false, // forceV1 + false, // forceNoHandoff false, // headless true, // createServerHandle 0, // serverHandle diff --git a/src/server/IoDispatchers.cpp b/src/server/IoDispatchers.cpp index 58909c7d95..c6009e9d4b 100644 --- a/src/server/IoDispatchers.cpp +++ b/src/server/IoDispatchers.cpp @@ -159,6 +159,22 @@ static bool _shouldAttemptHandoff(const Globals& globals, #else + // 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. + if (globals.launchArgs.GetForceNoHandoff()) + { + return false; + } + + // Someone double clicked this console or explicitly tried + // to use it to launch a child process. Host it within this one + // and do not hand off. + if (globals.launchArgs.ShouldCreateServerHandle()) + { + return false; + } + // This console is already initialized. Do not // attempt handoff to another one. // Note you can have a non-attach secondary connect for a child process