2019-11-25 23:22:29 +01:00
|
|
|
// Copyright (c) Microsoft Corporation.
|
2019-05-03 00:29:04 +02:00
|
|
|
// Licensed under the MIT license.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "ConptyConnection.g.h"
|
2019-11-25 23:22:29 +01:00
|
|
|
#include "ConnectionStateHolder.h"
|
|
|
|
#include "../inc/cppwinrt_utils.h"
|
|
|
|
|
2019-11-16 02:02:38 +01:00
|
|
|
#include <conpty-static.h>
|
2019-11-07 00:09:01 +01:00
|
|
|
|
|
|
|
namespace wil
|
|
|
|
{
|
|
|
|
// These belong in WIL upstream, so when we reingest the change that has them we'll get rid of ours.
|
2019-11-16 02:02:38 +01:00
|
|
|
using unique_static_pseudoconsole_handle = wil::unique_any<HPCON, decltype(&::ConptyClosePseudoConsole), ::ConptyClosePseudoConsole>;
|
2019-11-07 00:09:01 +01:00
|
|
|
}
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|
|
|
{
|
2019-11-25 23:22:29 +01:00
|
|
|
struct ConptyConnection : ConptyConnectionT<ConptyConnection>, ConnectionStateHolder<ConptyConnection>
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2021-03-26 23:09:49 +01:00
|
|
|
ConptyConnection(const HANDLE hSig,
|
|
|
|
const HANDLE hIn,
|
|
|
|
const HANDLE hOut,
|
2021-05-24 23:56:46 +02:00
|
|
|
const HANDLE hRef,
|
|
|
|
const HANDLE hServerProcess,
|
2021-03-26 23:09:49 +01:00
|
|
|
const HANDLE hClientProcess);
|
|
|
|
|
Switch Connections to use `ValueSet`s to initialize them (#10184)
#### ⚠️ targets #10051
## Summary of the Pull Request
This PR does one big, primary thing. It removes all the constructors from any TerminalConnections, and changes them to use an `Initialize` method that accepts a `ValueSet` of properties.
Why?
For the upcoming window/content process work, we'll need the content process to be able to initialize the connection _in the content process_. However, the window process will be the one that knows what type of connection to make. Enter `ConnectionInformation`. This class will let us specify the class name of the type we want to create, and a set of settings to use when initializing that connection.
**IMPORTANT**: As a part of this, the constructor for a connection must have 0 arguments. `RoActivateInstance` lets you just conjure a WinRT type just by class name, but that class must have a 0 arg ctor. Hence the need for `Initialize`, to actually pass the settings.
We're using a `ValueSet` here because it's basically a json blob, with more steps. In the future, when extension authors want to have custom connections, we can always deserialize the json into a `ValueSet`, pass it to their connection's `Initialize`, and let then get what they need out of it.
## References
* Tear-out: #1256
* Megathread: #5000
* Project: https://github.com/microsoft/terminal/projects/5
## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760298
* [x] I work here
* [n/a] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
`ConnectionInformation` was included as a part of this PR, to demonstrate how this will eventually be used. `ConnectionInformation` is not _currently_ used.
## Validation Steps Performed
It still builds and runs.
2021-07-20 17:02:17 +02:00
|
|
|
ConptyConnection() noexcept = default;
|
|
|
|
void Initialize(const Windows::Foundation::Collections::ValueSet& settings);
|
|
|
|
|
2020-09-10 01:17:33 +02:00
|
|
|
static winrt::fire_and_forget final_release(std::unique_ptr<ConptyConnection> connection);
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
void Start();
|
|
|
|
void WriteInput(hstring const& data);
|
|
|
|
void Resize(uint32_t rows, uint32_t columns);
|
2020-01-03 19:44:27 +01:00
|
|
|
void Close() noexcept;
|
2021-09-02 16:59:42 +02:00
|
|
|
void ClearBuffer();
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-11-07 00:09:01 +01:00
|
|
|
winrt::guid Guid() const noexcept;
|
|
|
|
|
2021-03-26 23:09:49 +01:00
|
|
|
static void StartInboundListener();
|
|
|
|
static void StopInboundListener();
|
|
|
|
|
|
|
|
static winrt::event_token NewConnection(NewConnectionHandler const& handler);
|
|
|
|
static void NewConnection(winrt::event_token const& token);
|
|
|
|
|
Switch Connections to use `ValueSet`s to initialize them (#10184)
#### ⚠️ targets #10051
## Summary of the Pull Request
This PR does one big, primary thing. It removes all the constructors from any TerminalConnections, and changes them to use an `Initialize` method that accepts a `ValueSet` of properties.
Why?
For the upcoming window/content process work, we'll need the content process to be able to initialize the connection _in the content process_. However, the window process will be the one that knows what type of connection to make. Enter `ConnectionInformation`. This class will let us specify the class name of the type we want to create, and a set of settings to use when initializing that connection.
**IMPORTANT**: As a part of this, the constructor for a connection must have 0 arguments. `RoActivateInstance` lets you just conjure a WinRT type just by class name, but that class must have a 0 arg ctor. Hence the need for `Initialize`, to actually pass the settings.
We're using a `ValueSet` here because it's basically a json blob, with more steps. In the future, when extension authors want to have custom connections, we can always deserialize the json into a `ValueSet`, pass it to their connection's `Initialize`, and let then get what they need out of it.
## References
* Tear-out: #1256
* Megathread: #5000
* Project: https://github.com/microsoft/terminal/projects/5
## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760298
* [x] I work here
* [n/a] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
`ConnectionInformation` was included as a part of this PR, to demonstrate how this will eventually be used. `ConnectionInformation` is not _currently_ used.
## Validation Steps Performed
It still builds and runs.
2021-07-20 17:02:17 +02:00
|
|
|
static Windows::Foundation::Collections::ValueSet CreateSettings(const winrt::hstring& cmdline,
|
|
|
|
const winrt::hstring& startingDirectory,
|
|
|
|
const winrt::hstring& startingTitle,
|
|
|
|
Windows::Foundation::Collections::IMapView<hstring, hstring> const& environment,
|
|
|
|
uint32_t rows,
|
|
|
|
uint32_t columns,
|
|
|
|
winrt::guid const& guid);
|
|
|
|
|
2019-11-25 23:22:29 +01:00
|
|
|
WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler);
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
private:
|
2019-11-07 00:09:01 +01:00
|
|
|
HRESULT _LaunchAttachedClient() noexcept;
|
2019-11-25 23:22:29 +01:00
|
|
|
void _indicateExitWithStatus(unsigned int status) noexcept;
|
2019-11-07 00:09:01 +01:00
|
|
|
void _ClientTerminated() noexcept;
|
|
|
|
|
2021-05-24 23:56:46 +02:00
|
|
|
static HRESULT NewHandoff(HANDLE in, HANDLE out, HANDLE signal, HANDLE ref, HANDLE server, HANDLE client) noexcept;
|
2021-03-26 23:09:49 +01:00
|
|
|
|
2019-11-07 00:09:01 +01:00
|
|
|
uint32_t _initialRows{};
|
|
|
|
uint32_t _initialCols{};
|
Switch Connections to use `ValueSet`s to initialize them (#10184)
#### ⚠️ targets #10051
## Summary of the Pull Request
This PR does one big, primary thing. It removes all the constructors from any TerminalConnections, and changes them to use an `Initialize` method that accepts a `ValueSet` of properties.
Why?
For the upcoming window/content process work, we'll need the content process to be able to initialize the connection _in the content process_. However, the window process will be the one that knows what type of connection to make. Enter `ConnectionInformation`. This class will let us specify the class name of the type we want to create, and a set of settings to use when initializing that connection.
**IMPORTANT**: As a part of this, the constructor for a connection must have 0 arguments. `RoActivateInstance` lets you just conjure a WinRT type just by class name, but that class must have a 0 arg ctor. Hence the need for `Initialize`, to actually pass the settings.
We're using a `ValueSet` here because it's basically a json blob, with more steps. In the future, when extension authors want to have custom connections, we can always deserialize the json into a `ValueSet`, pass it to their connection's `Initialize`, and let then get what they need out of it.
## References
* Tear-out: #1256
* Megathread: #5000
* Project: https://github.com/microsoft/terminal/projects/5
## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760298
* [x] I work here
* [n/a] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
`ConnectionInformation` was included as a part of this PR, to demonstrate how this will eventually be used. `ConnectionInformation` is not _currently_ used.
## Validation Steps Performed
It still builds and runs.
2021-07-20 17:02:17 +02:00
|
|
|
hstring _commandline{};
|
|
|
|
hstring _startingDirectory{};
|
|
|
|
hstring _startingTitle{};
|
|
|
|
Windows::Foundation::Collections::ValueSet _environment{ nullptr };
|
2019-11-07 00:09:01 +01:00
|
|
|
guid _guid{}; // A unique session identifier for connected client
|
2020-02-12 21:02:48 +01:00
|
|
|
hstring _clientName{}; // The name of the process hosted by this ConPTY connection (as of launch).
|
2019-11-07 00:09:01 +01:00
|
|
|
|
2020-02-10 21:40:01 +01:00
|
|
|
bool _receivedFirstByte{ false };
|
2019-11-07 00:09:01 +01:00
|
|
|
std::chrono::high_resolution_clock::time_point _startTime{};
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-11-07 00:09:01 +01:00
|
|
|
wil::unique_hfile _inPipe; // The pipe for writing input to
|
|
|
|
wil::unique_hfile _outPipe; // The pipe for reading output from
|
|
|
|
wil::unique_handle _hOutputThread;
|
|
|
|
wil::unique_process_information _piClient;
|
2019-11-16 02:02:38 +01:00
|
|
|
wil::unique_static_pseudoconsole_handle _hPC;
|
2019-11-07 00:09:01 +01:00
|
|
|
wil::unique_threadpool_wait _clientExitWait;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
Switch Connections to use `ValueSet`s to initialize them (#10184)
#### ⚠️ targets #10051
## Summary of the Pull Request
This PR does one big, primary thing. It removes all the constructors from any TerminalConnections, and changes them to use an `Initialize` method that accepts a `ValueSet` of properties.
Why?
For the upcoming window/content process work, we'll need the content process to be able to initialize the connection _in the content process_. However, the window process will be the one that knows what type of connection to make. Enter `ConnectionInformation`. This class will let us specify the class name of the type we want to create, and a set of settings to use when initializing that connection.
**IMPORTANT**: As a part of this, the constructor for a connection must have 0 arguments. `RoActivateInstance` lets you just conjure a WinRT type just by class name, but that class must have a 0 arg ctor. Hence the need for `Initialize`, to actually pass the settings.
We're using a `ValueSet` here because it's basically a json blob, with more steps. In the future, when extension authors want to have custom connections, we can always deserialize the json into a `ValueSet`, pass it to their connection's `Initialize`, and let then get what they need out of it.
## References
* Tear-out: #1256
* Megathread: #5000
* Project: https://github.com/microsoft/terminal/projects/5
## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760298
* [x] I work here
* [n/a] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
`ConnectionInformation` was included as a part of this PR, to demonstrate how this will eventually be used. `ConnectionInformation` is not _currently_ used.
## Validation Steps Performed
It still builds and runs.
2021-07-20 17:02:17 +02:00
|
|
|
til::u8state _u8State{};
|
|
|
|
std::wstring _u16Str{};
|
|
|
|
std::array<char, 4096> _buffer{};
|
2020-01-30 01:55:48 +01:00
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
DWORD _OutputThread();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace winrt::Microsoft::Terminal::TerminalConnection::factory_implementation
|
|
|
|
{
|
|
|
|
struct ConptyConnection : ConptyConnectionT<ConptyConnection, implementation::ConptyConnection>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
}
|