Force the use of the static pseudoconsole functions in TConn (#3582)

This commit renames the functions in conpty.lib to Conpty* so that they
can be explicitly linked and introduces a header so they can be located.

It also updates the DEF for conpty.dll to reexport them with their
original names.

The crux of the issue here is that TerminalConnection is consuming the
_import_ symbols for the *PseudoConsole family of APIs, which simply
cannot be supplanted by a static library.

Avenues explored: * Exporting __imp_x from the static library to get all
up in kernel32's business.  * Using /ALTERNATENAME:__imp_X=StaticX. It
turns out ALTERNATENAME is only consulted when the symbol isn't found
through traditional means.

This, renaming them, is the straightest path forward.

Fixes #3553.
This commit is contained in:
Dustin L. Howett (MSFT) 2019-11-15 17:02:38 -08:00 committed by GitHub
parent efa68abd3d
commit cc8faaf04f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 55 additions and 27 deletions

View file

@ -32,7 +32,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
RETURN_IF_WIN32_BOOL_FALSE(CreatePipe(&inPipePseudoConsoleSide, &inPipeOurSide, NULL, 0));
RETURN_IF_WIN32_BOOL_FALSE(CreatePipe(&outPipeOurSide, &outPipePseudoConsoleSide, NULL, 0));
RETURN_IF_FAILED(CreatePseudoConsole(size, inPipePseudoConsoleSide.get(), outPipePseudoConsoleSide.get(), dwFlags, phPC));
RETURN_IF_FAILED(ConptyCreatePseudoConsole(size, inPipePseudoConsoleSide.get(), outPipePseudoConsoleSide.get(), dwFlags, phPC));
*phInput = inPipeOurSide.release();
*phOutput = outPipeOurSide.release();
return S_OK;
@ -250,7 +250,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
}
else if (!_closing.load())
{
THROW_IF_FAILED(ResizePseudoConsole(_hPC.get(), { Utils::ClampToShortMax(columns, 1), Utils::ClampToShortMax(rows, 1) }));
THROW_IF_FAILED(ConptyResizePseudoConsole(_hPC.get(), { Utils::ClampToShortMax(columns, 1), Utils::ClampToShortMax(rows, 1) }));
}
}

View file

@ -4,11 +4,12 @@
#pragma once
#include "ConptyConnection.g.h"
#include <conpty-static.h>
namespace wil
{
// These belong in WIL upstream, so when we reingest the change that has them we'll get rid of ours.
using unique_pseudoconsole_handle = wil::unique_any<HPCON, decltype(&::ClosePseudoConsole), ::ClosePseudoConsole>;
using unique_static_pseudoconsole_handle = wil::unique_any<HPCON, decltype(&::ConptyClosePseudoConsole), ::ConptyClosePseudoConsole>;
}
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
@ -51,7 +52,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
wil::unique_hfile _outPipe; // The pipe for reading output from
wil::unique_handle _hOutputThread;
wil::unique_process_information _piClient;
wil::unique_pseudoconsole_handle _hPC;
wil::unique_static_pseudoconsole_handle _hPC;
wil::unique_threadpool_wait _clientExitWait;
DWORD _OutputThread();

26
src/inc/conpty-static.h Normal file
View file

@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// This header prototypes the Pseudoconsole symbols from conpty.lib with their original names.
// This is required because we cannot import __imp_CreatePseudoConsole from a static library
// as it doesn't produce an import lib.
// We can't use an /ALTERNATENAME trick because it seems that that name is only resolved when the
// linker cannot otherwise find the symbol.
#pragma once
#include <consoleapi.h>
#ifdef __cplusplus
extern "C" {
#endif
HRESULT WINAPI ConptyCreatePseudoConsole(COORD size, HANDLE hInput, HANDLE hOutput, DWORD dwFlags, HPCON* phPC);
HRESULT WINAPI ConptyResizePseudoConsole(HPCON hPC, COORD size);
VOID WINAPI ConptyClosePseudoConsole(HPCON hPC);
#ifdef __cplusplus
}
#endif

View file

@ -1,4 +1,4 @@
EXPORTS
CreatePseudoConsole
ResizePseudoConsole
ClosePseudoConsole
CreatePseudoConsole = ConptyCreatePseudoConsole
ResizePseudoConsole = ConptyResizePseudoConsole
ClosePseudoConsole = ConptyClosePseudoConsole

View file

@ -308,21 +308,22 @@ VOID _ClosePseudoConsole(_In_ PseudoConsole* pPty)
// reply to this message, the conpty will not process any input until it
// does. Most *nix terminals and the Windows Console (after Windows 10
// Anniversary Update) will be able to handle such a message.
HRESULT WINAPI CreatePseudoConsole(_In_ COORD size,
_In_ HANDLE hInput,
_In_ HANDLE hOutput,
_In_ DWORD dwFlags,
_Out_ HPCON* phPC)
extern "C" HRESULT WINAPI ConptyCreatePseudoConsole(_In_ COORD size,
_In_ HANDLE hInput,
_In_ HANDLE hOutput,
_In_ DWORD dwFlags,
_Out_ HPCON* phPC)
{
return CreatePseudoConsoleAsUser(INVALID_HANDLE_VALUE, size, hInput, hOutput, dwFlags, phPC);
return ConptyCreatePseudoConsoleAsUser(INVALID_HANDLE_VALUE, size, hInput, hOutput, dwFlags, phPC);
}
HRESULT CreatePseudoConsoleAsUser(_In_ HANDLE hToken,
_In_ COORD size,
_In_ HANDLE hInput,
_In_ HANDLE hOutput,
_In_ DWORD dwFlags,
_Out_ HPCON* phPC)
extern "C" HRESULT ConptyCreatePseudoConsoleAsUser(_In_ HANDLE hToken,
_In_ COORD size,
_In_ HANDLE hInput,
_In_ HANDLE hOutput,
_In_ DWORD dwFlags,
_Out_ HPCON* phPC)
{
if (phPC == NULL)
{
@ -355,7 +356,7 @@ HRESULT CreatePseudoConsoleAsUser(_In_ HANDLE hToken,
// Function Description:
// Resizes the given conpty to the specified size, in characters.
HRESULT WINAPI ResizePseudoConsole(_In_ HPCON hPC, _In_ COORD size)
extern "C" HRESULT WINAPI ConptyResizePseudoConsole(_In_ HPCON hPC, _In_ COORD size)
{
PseudoConsole* const pPty = (PseudoConsole*)hPC;
HRESULT hr = pPty == NULL ? E_INVALIDARG : S_OK;
@ -372,7 +373,7 @@ HRESULT WINAPI ResizePseudoConsole(_In_ HPCON hPC, _In_ COORD size)
// console window they were running in was closed.
// This can fail if the conhost hosting the pseudoconsole failed to be
// terminated, or if the pseudoconsole was already terminated.
VOID WINAPI ClosePseudoConsole(_In_ HPCON hPC)
extern "C" VOID WINAPI ConptyClosePseudoConsole(_In_ HPCON hPC)
{
PseudoConsole* const pPty = (PseudoConsole*)hPC;
if (pPty != NULL)

View file

@ -31,12 +31,12 @@ HRESULT _ResizePseudoConsole(_In_ const PseudoConsole* const pPty, _In_ const CO
void _ClosePseudoConsoleMembers(_In_ PseudoConsole* pPty);
VOID _ClosePseudoConsole(_In_ PseudoConsole* pPty);
HRESULT CreatePseudoConsoleAsUser(_In_ HANDLE hToken,
_In_ COORD size,
_In_ HANDLE hInput,
_In_ HANDLE hOutput,
_In_ DWORD dwFlags,
_Out_ HPCON* phPC);
HRESULT ConptyCreatePseudoConsoleAsUser(_In_ HANDLE hToken,
_In_ COORD size,
_In_ HANDLE hInput,
_In_ HANDLE hOutput,
_In_ DWORD dwFlags,
_Out_ HPCON* phPC);
#ifdef __cplusplus
}