Skip to content

Commit

Permalink
Force the use of the static pseudoconsole functions in TConn (#3582)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
DHowett committed Nov 16, 2019
1 parent efa68ab commit cc8faaf
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 27 deletions.
4 changes: 2 additions & 2 deletions src/cascadia/TerminalConnection/ConptyConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) }));
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/cascadia/TerminalConnection/ConptyConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down
26 changes: 26 additions & 0 deletions src/inc/conpty-static.h
Original file line number Diff line number Diff line change
@@ -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
6 changes: 3 additions & 3 deletions src/winconpty/dll/winconpty.def
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
EXPORTS
CreatePseudoConsole
ResizePseudoConsole
ClosePseudoConsole
CreatePseudoConsole = ConptyCreatePseudoConsole
ResizePseudoConsole = ConptyResizePseudoConsole
ClosePseudoConsole = ConptyClosePseudoConsole
29 changes: 15 additions & 14 deletions src/winconpty/winconpty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down
12 changes: 6 additions & 6 deletions src/winconpty/winconpty.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down

0 comments on commit cc8faaf

Please sign in to comment.