mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-24 23:22:27 +00:00
Compare commits
2 Commits
dev/lhecke
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3bed10aed0 | ||
|
|
68d854011e |
@@ -41,7 +41,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
// - phOutput: Receives the handle to the newly-created anonymous pipe for reading the output of the conpty.
|
||||
// - phPc: Receives a token value to identify this conpty
|
||||
#pragma warning(suppress : 26430) // This statement sufficiently checks the out parameters. Analyzer cannot find this.
|
||||
static HRESULT _CreatePseudoConsoleAndPipes(const COORD size, const DWORD dwFlags, HANDLE* phInput, HANDLE* phOutput, HPCON* phPC) noexcept
|
||||
static HRESULT _CreatePseudoConsoleAndPipes(const COORD size, const DWORD dwFlags, HWND ownerHwnd, HANDLE* phInput, HANDLE* phOutput, HPCON* phPC) noexcept
|
||||
{
|
||||
RETURN_HR_IF(E_INVALIDARG, phPC == nullptr || phInput == nullptr || phOutput == nullptr);
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
|
||||
RETURN_IF_WIN32_BOOL_FALSE(CreatePipe(&inPipePseudoConsoleSide, &inPipeOurSide, nullptr, 0));
|
||||
RETURN_IF_WIN32_BOOL_FALSE(CreatePipe(&outPipeOurSide, &outPipePseudoConsoleSide, nullptr, 0));
|
||||
RETURN_IF_FAILED(ConptyCreatePseudoConsole(size, inPipePseudoConsoleSide.get(), outPipePseudoConsoleSide.get(), dwFlags, phPC));
|
||||
RETURN_IF_FAILED(ConptyCreatePseudoConsoleWithWindow(ownerHwnd, INVALID_HANDLE_VALUE, size, inPipePseudoConsoleSide.get(), outPipePseudoConsoleSide.get(), dwFlags, phPC));
|
||||
*phInput = inPipeOurSide.release();
|
||||
*phOutput = outPipeOurSide.release();
|
||||
return S_OK;
|
||||
@@ -338,12 +338,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
}
|
||||
}
|
||||
|
||||
THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(til::unwrap_coord_size(dimensions), flags, &_inPipe, &_outPipe, &_hPC));
|
||||
THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(til::unwrap_coord_size(dimensions), flags, reinterpret_cast<HWND>(_initialParentHwnd), &_inPipe, &_outPipe, &_hPC));
|
||||
|
||||
if (_initialParentHwnd != 0)
|
||||
{
|
||||
THROW_IF_FAILED(ConptyReparentPseudoConsole(_hPC.get(), reinterpret_cast<HWND>(_initialParentHwnd)));
|
||||
}
|
||||
// if (_initialParentHwnd != 0)
|
||||
// {
|
||||
// THROW_IF_FAILED(ConptyReparentPseudoConsole(_hPC.get(), reinterpret_cast<HWND>(_initialParentHwnd)));
|
||||
// }
|
||||
|
||||
// GH#12515: The conpty assumes it's hidden at the start. If we're visible, let it know now.
|
||||
if (_initialVisibility)
|
||||
|
||||
@@ -25,6 +25,7 @@ const std::wstring_view ConsoleArguments::FEATURE_ARG = L"--feature";
|
||||
const std::wstring_view ConsoleArguments::FEATURE_PTY_ARG = L"pty";
|
||||
const std::wstring_view ConsoleArguments::COM_SERVER_ARG = L"-Embedding";
|
||||
const std::wstring_view ConsoleArguments::PASSTHROUGH_ARG = L"--passthrough";
|
||||
const std::wstring_view ConsoleArguments::OWNER_ARG = L"--owner";
|
||||
// NOTE: Thinking about adding more commandline args that control conpty, for
|
||||
// the Terminal? Make sure you add them to the commandline in
|
||||
// ConsoleEstablishHandoff. We use that to initialize the ConsoleArguments for a
|
||||
@@ -124,6 +125,7 @@ ConsoleArguments::ConsoleArguments(const std::wstring& commandline,
|
||||
_width = 0;
|
||||
_height = 0;
|
||||
_inheritCursor = false;
|
||||
_ownerHwnd = 0;
|
||||
}
|
||||
|
||||
ConsoleArguments::ConsoleArguments() :
|
||||
@@ -150,6 +152,7 @@ ConsoleArguments& ConsoleArguments::operator=(const ConsoleArguments& other)
|
||||
_inheritCursor = other._inheritCursor;
|
||||
_runAsComServer = other._runAsComServer;
|
||||
_forceNoHandoff = other._forceNoHandoff;
|
||||
_ownerHwnd = other._ownerHwnd;
|
||||
}
|
||||
|
||||
return *this;
|
||||
@@ -521,6 +524,17 @@ void ConsoleArguments::s_ConsumeArg(_Inout_ std::vector<std::wstring>& args, _In
|
||||
s_ConsumeArg(args, i);
|
||||
hr = S_OK;
|
||||
}
|
||||
else if (arg == OWNER_ARG)
|
||||
{
|
||||
std::wstring ownerHwndVal;
|
||||
hr = s_GetArgumentValue(args, i, &ownerHwndVal);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
std::ignore = s_ParseHandleArg(ownerHwndVal, _ownerHwnd);
|
||||
// We actually don't care if this fails to parse. "0x0" is gonna parse as 0 and return E_INVALIDARG, and that's a totally fine result to return
|
||||
}
|
||||
}
|
||||
else if (arg == CLIENT_COMMANDLINE_ARG)
|
||||
{
|
||||
// Everything after this is the explicit commandline
|
||||
@@ -681,6 +695,10 @@ bool ConsoleArguments::IsWin32InputModeEnabled() const
|
||||
{
|
||||
return _win32InputMode;
|
||||
}
|
||||
HWND ConsoleArguments::GetOwnerHwnd() const
|
||||
{
|
||||
return static_cast<HWND>(ULongToHandle( _ownerHwnd ));
|
||||
}
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
// Method Description:
|
||||
|
||||
@@ -57,6 +57,8 @@ public:
|
||||
bool IsResizeQuirkEnabled() const;
|
||||
bool IsWin32InputModeEnabled() const;
|
||||
|
||||
HWND GetOwnerHwnd() const;
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
void EnableConptyModeForTests();
|
||||
#endif
|
||||
@@ -79,6 +81,7 @@ public:
|
||||
static const std::wstring_view FEATURE_PTY_ARG;
|
||||
static const std::wstring_view COM_SERVER_ARG;
|
||||
static const std::wstring_view PASSTHROUGH_ARG;
|
||||
static const std::wstring_view OWNER_ARG;
|
||||
|
||||
private:
|
||||
#ifdef UNIT_TESTING
|
||||
@@ -98,7 +101,8 @@ private:
|
||||
const DWORD signalHandle,
|
||||
const bool inheritCursor,
|
||||
const bool runAsComServer,
|
||||
const bool passthroughMode) :
|
||||
const bool passthroughMode,
|
||||
const DWORD ownerHwnd = 0) :
|
||||
_commandline(commandline),
|
||||
_clientCommandline(clientCommandline),
|
||||
_vtInHandle(vtInHandle),
|
||||
@@ -115,7 +119,8 @@ private:
|
||||
_inheritCursor(inheritCursor),
|
||||
_resizeQuirk(false),
|
||||
_runAsComServer{ runAsComServer },
|
||||
_passthroughMode{ passthroughMode }
|
||||
_passthroughMode{ passthroughMode },
|
||||
_ownerHwnd{ ownerHwnd }
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@@ -145,6 +150,7 @@ private:
|
||||
bool _inheritCursor;
|
||||
bool _resizeQuirk{ false };
|
||||
bool _win32InputMode{ false };
|
||||
DWORD _ownerHwnd{ 0 };
|
||||
|
||||
[[nodiscard]] HRESULT _GetClientCommandline(_Inout_ std::vector<std::wstring>& args,
|
||||
const size_t index,
|
||||
@@ -195,6 +201,7 @@ namespace WEX
|
||||
L"Inherit Cursor: '%ws'\r\n",
|
||||
L"Run As Com Server: '%ws'\r\n",
|
||||
L"Passthrough Mode: '%ws'\r\n",
|
||||
L"Owner HWND: '0x%x'\r\n",
|
||||
ci.GetClientCommandline().c_str(),
|
||||
s_ToBoolString(ci.HasVtHandles()),
|
||||
ci.GetVtInHandle(),
|
||||
@@ -210,7 +217,8 @@ namespace WEX
|
||||
ci.GetSignalHandle(),
|
||||
s_ToBoolString(ci.GetInheritCursor()),
|
||||
s_ToBoolString(ci.ShouldRunAsComServer()),
|
||||
s_ToBoolString(ci.IsPassthroughMode()));
|
||||
s_ToBoolString(ci.IsPassthroughMode()),
|
||||
ci.GetOwnerHwnd());
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -241,7 +249,8 @@ namespace WEX
|
||||
expected.GetSignalHandle() == actual.GetSignalHandle() &&
|
||||
expected.GetInheritCursor() == actual.GetInheritCursor() &&
|
||||
expected.ShouldRunAsComServer() == actual.ShouldRunAsComServer() &&
|
||||
expected.IsPassthroughMode() == actual.IsPassthroughMode();
|
||||
expected.IsPassthroughMode() == actual.IsPassthroughMode() &&
|
||||
expected.GetOwnerHwnd() == actual.GetOwnerHwnd();
|
||||
}
|
||||
|
||||
static bool AreSame(const ConsoleArguments& expected, const ConsoleArguments& actual)
|
||||
@@ -268,7 +277,8 @@ namespace WEX
|
||||
(object.GetSignalHandle() == 0 || object.GetSignalHandle() == INVALID_HANDLE_VALUE) &&
|
||||
!object.GetInheritCursor() &&
|
||||
!object.ShouldRunAsComServer() &&
|
||||
!object.IsPassthroughMode();
|
||||
!object.IsPassthroughMode() &&
|
||||
object.GetOwnerHwnd() == 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -85,9 +85,9 @@ void PtySignalInputThread::ConnectConsole() noexcept
|
||||
// this here ensures that the window is first created with the initial owner
|
||||
// set up (if so specified).
|
||||
// - Refer to GH#13066 for details.
|
||||
void PtySignalInputThread::CreatePseudoWindow()
|
||||
void PtySignalInputThread::CreatePseudoWindow(HWND ownerHwnd /*= HWND_DESKTOP*/)
|
||||
{
|
||||
HWND owner = _earlyReparent.has_value() ? reinterpret_cast<HWND>((*_earlyReparent).handle) : HWND_DESKTOP;
|
||||
HWND owner = _earlyReparent.has_value() ? reinterpret_cast<HWND>((*_earlyReparent).handle) : ownerHwnd;
|
||||
ServiceLocator::LocatePseudoWindow(owner);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Microsoft::Console
|
||||
PtySignalInputThread& operator=(const PtySignalInputThread&) = delete;
|
||||
|
||||
void ConnectConsole() noexcept;
|
||||
void CreatePseudoWindow();
|
||||
void CreatePseudoWindow(HWND ownerHwnd);
|
||||
|
||||
private:
|
||||
enum class PtySignal : unsigned short
|
||||
|
||||
@@ -74,6 +74,7 @@ VtIo::VtIo() :
|
||||
_resizeQuirk = pArgs->IsResizeQuirkEnabled();
|
||||
_win32InputMode = pArgs->IsWin32InputModeEnabled();
|
||||
_passthroughMode = pArgs->IsPassthroughMode();
|
||||
_originalOwnerHwnd = pArgs->GetOwnerHwnd();
|
||||
|
||||
// If we were already given VT handles, set up the VT IO engine to use those.
|
||||
if (pArgs->InConptyMode())
|
||||
@@ -329,7 +330,7 @@ void VtIo::CreatePseudoWindow()
|
||||
{
|
||||
if (_pPtySignalInputThread)
|
||||
{
|
||||
_pPtySignalInputThread->CreatePseudoWindow();
|
||||
_pPtySignalInputThread->CreatePseudoWindow(_originalOwnerHwnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -71,6 +71,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
bool _win32InputMode{ false };
|
||||
bool _passthroughMode{ false };
|
||||
bool _closeEventSent{ false };
|
||||
HWND _originalOwnerHwnd{ HWND_DESKTOP };
|
||||
|
||||
std::unique_ptr<Microsoft::Console::Render::VtEngine> _pVtRenderEngine;
|
||||
std::unique_ptr<Microsoft::Console::VtInputThread> _pVtInputThread;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
CONPTY_EXPORT HRESULT WINAPI ConptyCreatePseudoConsole(COORD size, HANDLE hInput, HANDLE hOutput, DWORD dwFlags, HPCON* phPC);
|
||||
CONPTY_EXPORT HRESULT WINAPI ConptyCreatePseudoConsoleAsUser(HANDLE hToken, COORD size, HANDLE hInput, HANDLE hOutput, DWORD dwFlags, HPCON* phPC);
|
||||
CONPTY_EXPORT HRESULT WINAPI ConptyCreatePseudoConsoleWithWindow(HWND hOwner, HANDLE hToken, COORD size, HANDLE hInput, HANDLE hOutput, DWORD dwFlags, HPCON* phPC);
|
||||
|
||||
CONPTY_EXPORT HRESULT WINAPI ConptyResizePseudoConsole(HPCON hPC, COORD size);
|
||||
CONPTY_EXPORT HRESULT WINAPI ConptyClearPseudoConsole(HPCON hPC);
|
||||
|
||||
@@ -2,6 +2,7 @@ EXPORTS
|
||||
; Plain old normal aliases
|
||||
ConptyCreatePseudoConsole
|
||||
ConptyCreatePseudoConsoleAsUser
|
||||
ConptyCreatePseudoConsoleWithWindow
|
||||
ConptyResizePseudoConsole
|
||||
ConptyClosePseudoConsole
|
||||
ConptyClosePseudoConsoleTimeout
|
||||
|
||||
@@ -109,7 +109,7 @@ static HRESULT _CreatePseudoConsole(const COORD size,
|
||||
const DWORD dwFlags,
|
||||
_Inout_ PseudoConsole* pPty)
|
||||
{
|
||||
return _CreatePseudoConsole(INVALID_HANDLE_VALUE, size, hInput, hOutput, dwFlags, pPty);
|
||||
return _CreatePseudoConsole(HWND_DESKTOP, INVALID_HANDLE_VALUE, size, hInput, hOutput, dwFlags, pPty);
|
||||
}
|
||||
|
||||
static HRESULT AttachPseudoConsole(HPCON hPC, std::wstring command, PROCESS_INFORMATION* ppi)
|
||||
|
||||
@@ -93,7 +93,8 @@ static bool _HandleIsValid(HANDLE h) noexcept
|
||||
return (h != INVALID_HANDLE_VALUE) && (h != nullptr);
|
||||
}
|
||||
|
||||
HRESULT _CreatePseudoConsole(const HANDLE hToken,
|
||||
HRESULT _CreatePseudoConsole(const HWND hOwner,
|
||||
const HANDLE hToken,
|
||||
const COORD size,
|
||||
const HANDLE hInput,
|
||||
const HANDLE hOutput,
|
||||
@@ -133,7 +134,7 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
|
||||
RETURN_IF_WIN32_BOOL_FALSE(SetHandleInformation(signalPipeConhostSide.get(), HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT));
|
||||
|
||||
// GH4061: Ensure that the path to executable in the format is escaped so C:\Program.exe cannot collide with C:\Program Files
|
||||
auto pwszFormat = L"\"%s\" --headless %s%s%s%s--width %hu --height %hu --signal 0x%x --server 0x%x";
|
||||
auto pwszFormat = L"\"%s\" --headless %s%s%s%s--width %hu --height %hu --signal 0x%x --server 0x%x --owner 0x%x";
|
||||
// This is plenty of space to hold the formatted string
|
||||
wchar_t cmd[MAX_PATH]{};
|
||||
const BOOL bInheritCursor = (dwFlags & PSEUDOCONSOLE_INHERIT_CURSOR) == PSEUDOCONSOLE_INHERIT_CURSOR;
|
||||
@@ -151,7 +152,8 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
|
||||
size.X,
|
||||
size.Y,
|
||||
signalPipeConhostSide.get(),
|
||||
serverHandle.get());
|
||||
serverHandle.get(),
|
||||
hOwner);
|
||||
|
||||
STARTUPINFOEXW siEx{ 0 };
|
||||
siEx.StartupInfo.cb = sizeof(STARTUPINFOEXW);
|
||||
@@ -440,12 +442,13 @@ extern "C" HRESULT WINAPI ConptyCreatePseudoConsole(_In_ COORD size,
|
||||
return ConptyCreatePseudoConsoleAsUser(INVALID_HANDLE_VALUE, size, hInput, hOutput, dwFlags, phPC);
|
||||
}
|
||||
|
||||
extern "C" HRESULT WINAPI ConptyCreatePseudoConsoleAsUser(_In_ HANDLE hToken,
|
||||
_In_ COORD size,
|
||||
_In_ HANDLE hInput,
|
||||
_In_ HANDLE hOutput,
|
||||
_In_ DWORD dwFlags,
|
||||
_Out_ HPCON* phPC)
|
||||
extern "C" HRESULT WINAPI ConptyCreatePseudoConsoleWithWindow(_In_ HWND hOwner,
|
||||
_In_ HANDLE hToken,
|
||||
_In_ COORD size,
|
||||
_In_ HANDLE hInput,
|
||||
_In_ HANDLE hOutput,
|
||||
_In_ DWORD dwFlags,
|
||||
_Out_ HPCON* phPC)
|
||||
{
|
||||
if (phPC == nullptr)
|
||||
{
|
||||
@@ -468,7 +471,7 @@ extern "C" HRESULT WINAPI ConptyCreatePseudoConsoleAsUser(_In_ HANDLE hToken,
|
||||
RETURN_IF_WIN32_BOOL_FALSE(DuplicateHandle(GetCurrentProcess(), hInput, GetCurrentProcess(), duplicatedInput.addressof(), 0, TRUE, DUPLICATE_SAME_ACCESS));
|
||||
RETURN_IF_WIN32_BOOL_FALSE(DuplicateHandle(GetCurrentProcess(), hOutput, GetCurrentProcess(), duplicatedOutput.addressof(), 0, TRUE, DUPLICATE_SAME_ACCESS));
|
||||
|
||||
RETURN_IF_FAILED(_CreatePseudoConsole(hToken, size, duplicatedInput.get(), duplicatedOutput.get(), dwFlags, pPty));
|
||||
RETURN_IF_FAILED(_CreatePseudoConsole(hOwner, hToken, size, duplicatedInput.get(), duplicatedOutput.get(), dwFlags, pPty));
|
||||
|
||||
*phPC = (HPCON)pPty;
|
||||
cleanupPty.release();
|
||||
@@ -476,6 +479,16 @@ extern "C" HRESULT WINAPI ConptyCreatePseudoConsoleAsUser(_In_ HANDLE hToken,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
extern "C" HRESULT WINAPI ConptyCreatePseudoConsoleAsUser(_In_ HANDLE hToken,
|
||||
_In_ COORD size,
|
||||
_In_ HANDLE hInput,
|
||||
_In_ HANDLE hOutput,
|
||||
_In_ DWORD dwFlags,
|
||||
_Out_ HPCON* phPC)
|
||||
{
|
||||
return ConptyCreatePseudoConsoleWithWindow(HWND_DESKTOP, hToken, size, hInput, hOutput, dwFlags, phPC);
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// Resizes the given conpty to the specified size, in characters.
|
||||
extern "C" HRESULT WINAPI ConptyResizePseudoConsole(_In_ HPCON hPC, _In_ COORD size)
|
||||
|
||||
@@ -63,7 +63,8 @@ typedef struct _PseudoConsole
|
||||
#endif
|
||||
|
||||
// Implementations of the various PseudoConsole functions.
|
||||
HRESULT _CreatePseudoConsole(const HANDLE hToken,
|
||||
HRESULT _CreatePseudoConsole(const HWND hOwner,
|
||||
const HANDLE hToken,
|
||||
const COORD size,
|
||||
const HANDLE hInput,
|
||||
const HANDLE hOutput,
|
||||
|
||||
Reference in New Issue
Block a user