Apply audit mode to TerminalConnection/Core/Settings and WinCon… (#4016)

## Summary of the Pull Request
- Enables auditing of some Terminal libraries (Connection, Core, Settings)
- Also audit WinConPTY.LIB since Connection depends on it

## PR Checklist
* [x] Rolls audit out to more things
* [x] I work here
* [x] Tests should still pass
* [x] Am core contributor

## Detailed Description of the Pull Request / Additional comments
This is turning on the auditing of these projects (as enabled by the heavier lifting in the other refactor) and then cleaning up the remaining warnings.

## Validation Steps Performed
- [x] Built it
- [x] Ran the tests
This commit is contained in:
Michael Niksa 2020-01-03 10:44:27 -08:00 committed by GitHub
parent 322989d017
commit d711d731d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 552 additions and 391 deletions

View File

@ -954,7 +954,8 @@ Global
{48D21369-3D7B-4431-9967-24E81292CF62}.Release|x86.Build.0 = Release|Win32 {48D21369-3D7B-4431-9967-24E81292CF62}.Release|x86.Build.0 = Release|Win32
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.AuditMode|Any CPU.ActiveCfg = Debug|Win32 {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.AuditMode|Any CPU.ActiveCfg = Debug|Win32
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.AuditMode|ARM64.ActiveCfg = Release|ARM64 {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.AuditMode|ARM64.ActiveCfg = Release|ARM64
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.AuditMode|x64.ActiveCfg = Release|x64 {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.AuditMode|x64.ActiveCfg = AuditMode|x64
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.AuditMode|x64.Build.0 = AuditMode|x64
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.AuditMode|x86.ActiveCfg = Release|Win32 {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.AuditMode|x86.ActiveCfg = Release|Win32
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.Debug|Any CPU.ActiveCfg = Debug|Win32 {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.Debug|Any CPU.ActiveCfg = Debug|Win32
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.Debug|ARM64.ActiveCfg = Debug|ARM64 {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.Debug|ARM64.ActiveCfg = Debug|ARM64
@ -972,8 +973,8 @@ Global
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.Release|x86.Build.0 = Release|Win32 {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}.Release|x86.Build.0 = Release|Win32
{CA5CAD1A-ABCD-429C-B551-8562EC954746}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32 {CA5CAD1A-ABCD-429C-B551-8562EC954746}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{CA5CAD1A-ABCD-429C-B551-8562EC954746}.AuditMode|ARM64.ActiveCfg = Release|ARM64 {CA5CAD1A-ABCD-429C-B551-8562EC954746}.AuditMode|ARM64.ActiveCfg = Release|ARM64
{CA5CAD1A-ABCD-429C-B551-8562EC954746}.AuditMode|x64.ActiveCfg = Release|x64 {CA5CAD1A-ABCD-429C-B551-8562EC954746}.AuditMode|x64.ActiveCfg = AuditMode|x64
{CA5CAD1A-ABCD-429C-B551-8562EC954746}.AuditMode|x64.Build.0 = Release|x64 {CA5CAD1A-ABCD-429C-B551-8562EC954746}.AuditMode|x64.Build.0 = AuditMode|x64
{CA5CAD1A-ABCD-429C-B551-8562EC954746}.AuditMode|x86.ActiveCfg = Release|Win32 {CA5CAD1A-ABCD-429C-B551-8562EC954746}.AuditMode|x86.ActiveCfg = Release|Win32
{CA5CAD1A-ABCD-429C-B551-8562EC954746}.Debug|Any CPU.ActiveCfg = Debug|Win32 {CA5CAD1A-ABCD-429C-B551-8562EC954746}.Debug|Any CPU.ActiveCfg = Debug|Win32
{CA5CAD1A-ABCD-429C-B551-8562EC954746}.Debug|ARM64.ActiveCfg = Debug|ARM64 {CA5CAD1A-ABCD-429C-B551-8562EC954746}.Debug|ARM64.ActiveCfg = Debug|ARM64
@ -1045,8 +1046,8 @@ Global
{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}.Release|x86.Build.0 = Release|Win32 {CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}.Release|x86.Build.0 = Release|Win32
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|Any CPU.ActiveCfg = Debug|Win32 {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|Any CPU.ActiveCfg = Debug|Win32
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|ARM64.ActiveCfg = Release|ARM64 {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|ARM64.ActiveCfg = Release|ARM64
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x64.ActiveCfg = Release|x64 {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x64.ActiveCfg = AuditMode|x64
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x64.Build.0 = Release|x64 {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x64.Build.0 = AuditMode|x64
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x86.ActiveCfg = Release|Win32 {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x86.ActiveCfg = Release|Win32
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|Any CPU.ActiveCfg = Debug|Win32 {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|Any CPU.ActiveCfg = Debug|Win32
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|ARM64.ActiveCfg = Debug|ARM64 {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|ARM64.ActiveCfg = Debug|ARM64
@ -1279,7 +1280,8 @@ Global
{58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32 {58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 {58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 {58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
{58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.AuditMode|x64.ActiveCfg = Release|x64 {58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.AuditMode|x64.ActiveCfg = AuditMode|x64
{58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.AuditMode|x64.Build.0 = AuditMode|x64
{58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.AuditMode|x86.ActiveCfg = AuditMode|Win32 {58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.AuditMode|x86.Build.0 = AuditMode|Win32 {58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.AuditMode|x86.Build.0 = AuditMode|Win32
{58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.Debug|Any CPU.ActiveCfg = Debug|Win32 {58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}.Debug|Any CPU.ActiveCfg = Debug|Win32

View File

@ -809,23 +809,23 @@ void TextBuffer::Reset()
// - newSize - new size of screen. // - newSize - new size of screen.
// Return Value: // Return Value:
// - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed. // - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
[[nodiscard]] NTSTATUS TextBuffer::ResizeTraditional(const COORD newSize) [[nodiscard]] NTSTATUS TextBuffer::ResizeTraditional(const COORD newSize) noexcept
{ {
RETURN_HR_IF(E_INVALIDARG, newSize.X < 0 || newSize.Y < 0); RETURN_HR_IF(E_INVALIDARG, newSize.X < 0 || newSize.Y < 0);
const auto currentSize = GetSize().Dimensions();
const auto attributes = GetCurrentAttributes();
SHORT TopRow = 0; // new top row of the screen buffer
if (newSize.Y <= GetCursor().GetPosition().Y)
{
TopRow = GetCursor().GetPosition().Y - newSize.Y + 1;
}
const SHORT TopRowIndex = (GetFirstRowIndex() + TopRow) % currentSize.Y;
// rotate rows until the top row is at index 0
try try
{ {
const auto currentSize = GetSize().Dimensions();
const auto attributes = GetCurrentAttributes();
SHORT TopRow = 0; // new top row of the screen buffer
if (newSize.Y <= GetCursor().GetPosition().Y)
{
TopRow = GetCursor().GetPosition().Y - newSize.Y + 1;
}
const SHORT TopRowIndex = (GetFirstRowIndex() + TopRow) % currentSize.Y;
// rotate rows until the top row is at index 0
const ROW& newTopRow = _storage.at(TopRowIndex); const ROW& newTopRow = _storage.at(TopRowIndex);
while (&newTopRow != &_storage.front()) while (&newTopRow != &_storage.front())
{ {

View File

@ -123,7 +123,7 @@ public:
void Reset(); void Reset();
[[nodiscard]] HRESULT ResizeTraditional(const COORD newSize); [[nodiscard]] HRESULT ResizeTraditional(const COORD newSize) noexcept;
const UnicodeStorage& GetUnicodeStorage() const noexcept; const UnicodeStorage& GetUnicodeStorage() const noexcept;
UnicodeStorage& GetUnicodeStorage() noexcept; UnicodeStorage& GetUnicodeStorage() noexcept;

View File

@ -3,6 +3,4 @@
#pragma once #pragma once
#include <cpprest/details/web_utilities.h> static constexpr std::wstring_view AzureClientID = L"0";
const utility::string_t AzureClientID = U("0");

View File

@ -37,14 +37,17 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// This function exists because the clientID only gets added by the release pipelines // This function exists because the clientID only gets added by the release pipelines
// and is not available on local builds, so we want to be able to make sure we don't // and is not available on local builds, so we want to be able to make sure we don't
// try to make an Azure connection if its a local build // try to make an Azure connection if its a local build
bool AzureConnection::IsAzureConnectionAvailable() bool AzureConnection::IsAzureConnectionAvailable() noexcept
{ {
return (AzureClientID != L"0"); return (AzureClientID != L"0");
} }
AzureConnection::AzureConnection(const uint32_t initialRows, const uint32_t initialCols) : AzureConnection::AzureConnection(const uint32_t initialRows, const uint32_t initialCols) :
_initialRows{ initialRows }, _initialRows{ initialRows },
_initialCols{ initialCols } _initialCols{ initialCols },
_maxStored{},
_maxSize{},
_expiry{}
{ {
} }
@ -186,7 +189,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
const auto str = winrt::to_string(data); const auto str = winrt::to_string(data);
msg.set_utf8_message(str); msg.set_utf8_message(str);
_cloudShellSocket.send(msg); _cloudShellSocket.send(msg).get();
} }
default: default:
return; return;
@ -217,7 +220,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
terminalRequest.set_body(json::value(L"")); terminalRequest.set_body(json::value(L""));
// Send the request // Send the request
_RequestHelper(terminalClient, terminalRequest); const auto response = _RequestHelper(terminalClient, terminalRequest);
} }
} }
@ -269,8 +272,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// - the exit code of the thread // - the exit code of the thread
DWORD WINAPI AzureConnection::StaticOutputThreadProc(LPVOID lpParameter) DWORD WINAPI AzureConnection::StaticOutputThreadProc(LPVOID lpParameter)
{ {
AzureConnection* const pInstance = (AzureConnection*)lpParameter; AzureConnection* const pInstance = static_cast<AzureConnection*>(lpParameter);
return pInstance->_OutputThread(); if (pInstance)
{
return pInstance->_OutputThread();
}
return gsl::narrow_cast<DWORD>(E_INVALIDARG);
} }
// Method description: // Method description:
@ -703,7 +710,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
http_request commonRequest(L"POST"); http_request commonRequest(L"POST");
commonRequest.set_request_uri(L"common/oauth2/devicecode"); commonRequest.set_request_uri(L"common/oauth2/devicecode");
const auto body = L"client_id=" + AzureClientID + L"&resource=" + _wantedResource; const auto body = L"client_id=" + AzureClientID + L"&resource=" + _wantedResource;
commonRequest.set_body(body, L"application/x-www-form-urlencoded"); commonRequest.set_body(body.c_str(), L"application/x-www-form-urlencoded");
// Send the request and receive the response as a json value // Send the request and receive the response as a json value
return _RequestHelper(loginClient, commonRequest); return _RequestHelper(loginClient, commonRequest);
@ -724,7 +731,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
http_client pollingClient(_loginUri); http_client pollingClient(_loginUri);
// Continuously send a poll request until the user authenticates // Continuously send a poll request until the user authenticates
const auto body = L"grant_type=device_code&resource=" + _wantedResource + L"&client_id=" + AzureClientID + L"&code=" + deviceCode; const auto body = hstring() + L"grant_type=device_code&resource=" + _wantedResource + L"&client_id=" + AzureClientID + L"&code=" + deviceCode;
const auto requestUri = L"common/oauth2/token"; const auto requestUri = L"common/oauth2/token";
json::value responseJson; json::value responseJson;
for (int count = 0; count < expiresIn / pollInterval; count++) for (int count = 0; count < expiresIn / pollInterval; count++)
@ -736,7 +743,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
} }
http_request pollRequest(L"POST"); http_request pollRequest(L"POST");
pollRequest.set_request_uri(requestUri); pollRequest.set_request_uri(requestUri);
pollRequest.set_body(body, L"application/x-www-form-urlencoded"); pollRequest.set_body(body.c_str(), L"application/x-www-form-urlencoded");
responseJson = _RequestHelper(pollingClient, pollRequest); responseJson = _RequestHelper(pollingClient, pollRequest);
@ -789,7 +796,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
http_request refreshRequest(L"POST"); http_request refreshRequest(L"POST");
refreshRequest.set_request_uri(_tenantID + L"/oauth2/token"); refreshRequest.set_request_uri(_tenantID + L"/oauth2/token");
const auto body = L"client_id=" + AzureClientID + L"&resource=" + _wantedResource + L"&grant_type=refresh_token" + L"&refresh_token=" + _refreshToken; const auto body = L"client_id=" + AzureClientID + L"&resource=" + _wantedResource + L"&grant_type=refresh_token" + L"&refresh_token=" + _refreshToken;
refreshRequest.set_body(body, L"application/x-www-form-urlencoded"); refreshRequest.set_body(body.c_str(), L"application/x-www-form-urlencoded");
refreshRequest.headers().add(L"User-Agent", HttpUserAgent); refreshRequest.headers().add(L"User-Agent", HttpUserAgent);
// Send the request and return the response as a json value // Send the request and return the response as a json value

View File

@ -18,7 +18,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{ {
struct AzureConnection : AzureConnectionT<AzureConnection>, ConnectionStateHolder<AzureConnection> struct AzureConnection : AzureConnectionT<AzureConnection>, ConnectionStateHolder<AzureConnection>
{ {
static bool IsAzureConnectionAvailable(); static bool IsAzureConnectionAvailable() noexcept;
AzureConnection(const uint32_t rows, const uint32_t cols); AzureConnection(const uint32_t rows, const uint32_t cols);
void Start(); void Start();

View File

@ -13,6 +13,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
TYPED_EVENT(StateChanged, ITerminalConnection, winrt::Windows::Foundation::IInspectable); TYPED_EVENT(StateChanged, ITerminalConnection, winrt::Windows::Foundation::IInspectable);
protected: protected:
#pragma warning(push)
#pragma warning(disable : 26447) // Analyzer is still upset about noexcepts throwing even with function level try.
// Method Description: // Method Description:
// - Attempt to transition to and signal the specified connection state. // - Attempt to transition to and signal the specified connection state.
// The transition will only be effected if the state is "beyond" the current state. // The transition will only be effected if the state is "beyond" the current state.
@ -21,6 +23,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// Return Value: // Return Value:
// Whether we've successfully transitioned to the new state. // Whether we've successfully transitioned to the new state.
bool _transitionToState(const ConnectionState state) noexcept bool _transitionToState(const ConnectionState state) noexcept
try
{ {
{ {
std::lock_guard<std::mutex> stateLock{ _stateMutex }; std::lock_guard<std::mutex> stateLock{ _stateMutex };
@ -32,9 +35,11 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
_connectionState = state; _connectionState = state;
} }
// Dispatch the event outside of lock. // Dispatch the event outside of lock.
#pragma warning(suppress : 26491) // We can't avoid static_cast downcast because this is template magic.
_StateChangedHandlers(*static_cast<T*>(this), nullptr); _StateChangedHandlers(*static_cast<T*>(this), nullptr);
return true; return true;
} }
CATCH_FAIL_FAST()
// Method Description: // Method Description:
// - Returns whether the state is one of the N specified states. // - Returns whether the state is one of the N specified states.
@ -43,7 +48,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// Return Value: // Return Value:
// Whether we're in one of the states. // Whether we're in one of the states.
template<typename... Args> template<typename... Args>
bool _isStateOneOf(Args&&... args) const noexcept bool _isStateOneOf(const Args&&... args) const noexcept
try
{ {
// Dark magic! This function uses C++17 fold expressions. These fold expressions roughly expand as follows: // Dark magic! This function uses C++17 fold expressions. These fold expressions roughly expand as follows:
// (... OP (expression_using_args)) // (... OP (expression_using_args))
@ -56,6 +62,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
std::lock_guard<std::mutex> stateLock{ _stateMutex }; std::lock_guard<std::mutex> stateLock{ _stateMutex };
return (... || (_connectionState == args)); return (... || (_connectionState == args));
} }
CATCH_FAIL_FAST()
// Method Description: // Method Description:
// - Returns whether the state has reached or surpassed the specified state. // - Returns whether the state has reached or surpassed the specified state.
@ -64,10 +71,13 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// Return Value: // Return Value:
// Whether we're at or beyond the specified state // Whether we're at or beyond the specified state
bool _isStateAtOrBeyond(const ConnectionState state) const noexcept bool _isStateAtOrBeyond(const ConnectionState state) const noexcept
try
{ {
std::lock_guard<std::mutex> stateLock{ _stateMutex }; std::lock_guard<std::mutex> stateLock{ _stateMutex };
return _connectionState >= state; return _connectionState >= state;
} }
CATCH_FAIL_FAST()
#pragma warning(pop)
// Method Description: // Method Description:
// - (Convenience:) Returns whether we're "connected". // - (Convenience:) Returns whether we're "connected".

View File

@ -44,15 +44,16 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// - phInput: Receives the handle to the newly-created anonymous pipe for writing input to the conpty. // - phInput: Receives the handle to the newly-created anonymous pipe for writing input to the conpty.
// - phOutput: Receives the handle to the newly-created anonymous pipe for reading the output of the conpty. // - 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 // - phPc: Receives a token value to identify this conpty
static HRESULT _CreatePseudoConsoleAndPipes(const COORD size, const DWORD dwFlags, HANDLE* phInput, HANDLE* phOutput, HPCON* phPC) #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
{ {
RETURN_HR_IF(E_INVALIDARG, phPC == nullptr || phInput == nullptr || phOutput == nullptr); RETURN_HR_IF(E_INVALIDARG, phPC == nullptr || phInput == nullptr || phOutput == nullptr);
wil::unique_hfile outPipeOurSide, outPipePseudoConsoleSide; wil::unique_hfile outPipeOurSide, outPipePseudoConsoleSide;
wil::unique_hfile inPipeOurSide, inPipePseudoConsoleSide; wil::unique_hfile inPipeOurSide, inPipePseudoConsoleSide;
RETURN_IF_WIN32_BOOL_FALSE(CreatePipe(&inPipePseudoConsoleSide, &inPipeOurSide, NULL, 0)); RETURN_IF_WIN32_BOOL_FALSE(CreatePipe(&inPipePseudoConsoleSide, &inPipeOurSide, nullptr, 0));
RETURN_IF_WIN32_BOOL_FALSE(CreatePipe(&outPipeOurSide, &outPipePseudoConsoleSide, NULL, 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(ConptyCreatePseudoConsole(size, inPipePseudoConsoleSide.get(), outPipePseudoConsoleSide.get(), dwFlags, phPC));
*phInput = inPipeOurSide.release(); *phInput = inPipeOurSide.release();
*phOutput = outPipeOurSide.release(); *phOutput = outPipeOurSide.release();
@ -62,25 +63,27 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// Function Description: // Function Description:
// - launches the client application attached to the new pseudoconsole // - launches the client application attached to the new pseudoconsole
HRESULT ConptyConnection::_LaunchAttachedClient() noexcept HRESULT ConptyConnection::_LaunchAttachedClient() noexcept
try
{ {
STARTUPINFOEX siEx{ 0 }; STARTUPINFOEX siEx{ 0 };
siEx.StartupInfo.cb = sizeof(STARTUPINFOEX); siEx.StartupInfo.cb = sizeof(STARTUPINFOEX);
siEx.StartupInfo.dwFlags = STARTF_USESTDHANDLES; siEx.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
SIZE_T size{};
size_t size{};
// This call will return an error (by design); we are ignoring it. // This call will return an error (by design); we are ignoring it.
InitializeProcThreadAttributeList(NULL, 1, 0, (PSIZE_T)&size); InitializeProcThreadAttributeList(nullptr, 1, 0, &size);
#pragma warning(suppress : 26414) // We don't move/touch this smart pointer, but we have to allocate strangely for the adjustable size list.
auto attrList{ std::make_unique<std::byte[]>(size) }; auto attrList{ std::make_unique<std::byte[]>(size) };
#pragma warning(suppress : 26490) // We have to use reinterpret_cast because we allocated a byte array as a proxy for the adjustable size list.
siEx.lpAttributeList = reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(attrList.get()); siEx.lpAttributeList = reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(attrList.get());
RETURN_IF_WIN32_BOOL_FALSE(InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, (PSIZE_T)&size)); RETURN_IF_WIN32_BOOL_FALSE(InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, &size));
RETURN_IF_WIN32_BOOL_FALSE(UpdateProcThreadAttribute(siEx.lpAttributeList, RETURN_IF_WIN32_BOOL_FALSE(UpdateProcThreadAttribute(siEx.lpAttributeList,
0, 0,
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
_hPC.get(), _hPC.get(),
sizeof(HPCON), sizeof(HPCON),
NULL, nullptr,
NULL)); nullptr));
std::wstring cmdline{ wil::ExpandEnvironmentStringsW<std::wstring>(_commandline.c_str()) }; // mutable copy -- required for CreateProcessW std::wstring cmdline{ wil::ExpandEnvironmentStringsW<std::wstring>(_commandline.c_str()) }; // mutable copy -- required for CreateProcessW
@ -91,14 +94,14 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
std::wstring wsGuid{ Utils::GuidToString(_guid) }; std::wstring wsGuid{ Utils::GuidToString(_guid) };
wsGuid.pop_back(); wsGuid.pop_back();
const wchar_t* const pwszGuid{ wsGuid.data() + 1 }; const auto guidSubStr = std::wstring_view{ wsGuid }.substr(1);
// Ensure every connection has the unique identifier in the environment. // Ensure every connection has the unique identifier in the environment.
environment.emplace(L"WT_SESSION", pwszGuid); environment.emplace(L"WT_SESSION", guidSubStr.data());
} }
std::vector<wchar_t> newEnvVars; std::vector<wchar_t> newEnvVars;
auto zeroNewEnv = wil::scope_exit([&] { auto zeroNewEnv = wil::scope_exit([&]() noexcept {
::SecureZeroMemory(newEnvVars.data(), ::SecureZeroMemory(newEnvVars.data(),
newEnvVars.size() * sizeof(decltype(newEnvVars.begin())::value_type)); newEnvVars.size() * sizeof(decltype(newEnvVars.begin())::value_type));
}); });
@ -146,6 +149,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
return S_OK; return S_OK;
} }
CATCH_RETURN();
ConptyConnection::ConptyConnection(const hstring& commandline, ConptyConnection::ConptyConnection(const hstring& commandline,
const hstring& startingDirectory, const hstring& startingDirectory,
@ -186,9 +190,13 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
_hOutputThread.reset(CreateThread( _hOutputThread.reset(CreateThread(
nullptr, nullptr,
0, 0,
[](LPVOID lpParameter) { [](LPVOID lpParameter) noexcept {
ConptyConnection* const pInstance = reinterpret_cast<ConptyConnection*>(lpParameter); ConptyConnection* const pInstance = static_cast<ConptyConnection*>(lpParameter);
return pInstance->_OutputThread(); if (pInstance)
{
return pInstance->_OutputThread();
}
return gsl::narrow_cast<DWORD>(E_INVALIDARG);
}, },
this, this,
0, 0,
@ -197,9 +205,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
THROW_LAST_ERROR_IF_NULL(_hOutputThread); THROW_LAST_ERROR_IF_NULL(_hOutputThread);
_clientExitWait.reset(CreateThreadpoolWait( _clientExitWait.reset(CreateThreadpoolWait(
[](PTP_CALLBACK_INSTANCE /*callbackInstance*/, PVOID context, PTP_WAIT /*wait*/, TP_WAIT_RESULT /*waitResult*/) { [](PTP_CALLBACK_INSTANCE /*callbackInstance*/, PVOID context, PTP_WAIT /*wait*/, TP_WAIT_RESULT /*waitResult*/) noexcept {
ConptyConnection* const pInstance = reinterpret_cast<ConptyConnection*>(context); ConptyConnection* const pInstance = static_cast<ConptyConnection*>(context);
pInstance->_ClientTerminated(); if (pInstance)
{
pInstance->_ClientTerminated();
}
}, },
this, this,
nullptr)); nullptr));
@ -213,7 +224,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// EXIT POINT // EXIT POINT
const auto hr = wil::ResultFromCaughtException(); const auto hr = wil::ResultFromCaughtException();
winrt::hstring failureText{ wil::str_printf<std::wstring>(RS_(L"ProcessFailedToLaunch").c_str(), static_cast<unsigned int>(hr), _commandline.c_str()) }; winrt::hstring failureText{ wil::str_printf<std::wstring>(RS_(L"ProcessFailedToLaunch").c_str(), gsl::narrow_cast<unsigned int>(hr), _commandline.c_str()) };
_TerminalOutputHandlers(failureText); _TerminalOutputHandlers(failureText);
_transitionToState(ConnectionState::Failed); _transitionToState(ConnectionState::Failed);
@ -229,7 +240,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{ {
try try
{ {
winrt::hstring exitText{ wil::str_printf<std::wstring>(RS_(L"ProcessExited").c_str(), (unsigned int)status) }; winrt::hstring exitText{ wil::str_printf<std::wstring>(RS_(L"ProcessExited").c_str(), status) };
_TerminalOutputHandlers(L"\r\n"); _TerminalOutputHandlers(L"\r\n");
_TerminalOutputHandlers(exitText); _TerminalOutputHandlers(exitText);
} }
@ -293,7 +304,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
} }
} }
void ConptyConnection::Close() void ConptyConnection::Close() noexcept
{ {
if (_transitionToState(ConnectionState::Closing)) if (_transitionToState(ConnectionState::Closing))
{ {
@ -332,7 +343,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// process the data of the output pipe in a loop // process the data of the output pipe in a loop
while (true) while (true)
{ {
HRESULT result = pipeReader.Read(strView); const HRESULT result = pipeReader.Read(strView);
if (FAILED(result) || result == S_FALSE) if (FAILED(result) || result == S_FALSE)
{ {
if (_isStateAtOrBeyond(ConnectionState::Closing)) if (_isStateAtOrBeyond(ConnectionState::Closing))
@ -344,7 +355,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// EXIT POINT // EXIT POINT
_indicateExitWithStatus(result); // print a message _indicateExitWithStatus(result); // print a message
_transitionToState(ConnectionState::Failed); _transitionToState(ConnectionState::Failed);
return (DWORD)-1; return gsl::narrow_cast<DWORD>(-1);
} }
if (strView.empty()) if (strView.empty())
@ -354,9 +365,10 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
if (!_recievedFirstByte) if (!_recievedFirstByte)
{ {
auto now = std::chrono::high_resolution_clock::now(); const auto now = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> delta = now - _startTime; const std::chrono::duration<double> delta = now - _startTime;
#pragma warning(suppress : 26477 26485 26494 26482 26446) // We don't control TraceLoggingWrite
TraceLoggingWrite(g_hTerminalConnectionProvider, TraceLoggingWrite(g_hTerminalConnectionProvider,
"RecievedFirstByte", "RecievedFirstByte",
TraceLoggingDescription("An event emitted when the connection recieves the first byte"), TraceLoggingDescription("An event emitted when the connection recieves the first byte"),

View File

@ -24,7 +24,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
void Start(); void Start();
void WriteInput(hstring const& data); void WriteInput(hstring const& data);
void Resize(uint32_t rows, uint32_t columns); void Resize(uint32_t rows, uint32_t columns);
void Close(); void Close() noexcept;
winrt::guid Guid() const noexcept; winrt::guid Guid() const noexcept;

View File

@ -5,26 +5,30 @@
#include "EchoConnection.h" #include "EchoConnection.h"
#include <sstream> #include <sstream>
// We have to define GSL here, not PCH
// because TelnetConnection has a conflicting GSL implementation.
#include <gsl/gsl>
#include "EchoConnection.g.cpp" #include "EchoConnection.g.cpp"
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{ {
EchoConnection::EchoConnection() EchoConnection::EchoConnection() noexcept
{ {
} }
void EchoConnection::Start() void EchoConnection::Start() noexcept
{ {
} }
void EchoConnection::WriteInput(hstring const& data) void EchoConnection::WriteInput(hstring const& data)
{ {
std::wstringstream prettyPrint; std::wstringstream prettyPrint;
for (wchar_t wch : data) for (const auto& wch : data)
{ {
if (wch < 0x20) if (wch < 0x20)
{ {
prettyPrint << L"^" << (wchar_t)(wch + 0x40); prettyPrint << L"^" << gsl::narrow_cast<wchar_t>(wch + 0x40);
} }
else if (wch == 0x7f) else if (wch == 0x7f)
{ {
@ -38,13 +42,11 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
_TerminalOutputHandlers(prettyPrint.str()); _TerminalOutputHandlers(prettyPrint.str());
} }
void EchoConnection::Resize(uint32_t rows, uint32_t columns) void EchoConnection::Resize(uint32_t /*rows*/, uint32_t /*columns*/) noexcept
{ {
rows;
columns;
} }
void EchoConnection::Close() void EchoConnection::Close() noexcept
{ {
} }
} }

View File

@ -11,12 +11,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{ {
struct EchoConnection : EchoConnectionT<EchoConnection> struct EchoConnection : EchoConnectionT<EchoConnection>
{ {
EchoConnection(); EchoConnection() noexcept;
void Start(); void Start() noexcept;
void WriteInput(hstring const& data); void WriteInput(hstring const& data);
void Resize(uint32_t rows, uint32_t columns); void Resize(uint32_t rows, uint32_t columns) noexcept;
void Close(); void Close() noexcept;
ConnectionState State() const noexcept { return ConnectionState::Connected; } ConnectionState State() const noexcept { return ConnectionState::Connected; }

View File

@ -19,7 +19,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
TelnetConnection::TelnetConnection(const hstring& uri) : TelnetConnection::TelnetConnection(const hstring& uri) :
_reader{ nullptr }, _reader{ nullptr },
_writer{ nullptr }, _writer{ nullptr },
_uri{ uri } _uri{ uri },
_receiveBuffer{}
{ {
_session.install(_nawsServer); _session.install(_nawsServer);
_nawsServer.activate([](auto&&) {}); _nawsServer.activate([](auto&&) {});
@ -37,8 +38,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
nullptr, nullptr,
0, 0,
[](LPVOID lpParameter) { [](LPVOID lpParameter) {
auto pInstance = reinterpret_cast<TelnetConnection*>(lpParameter); auto pInstance = static_cast<TelnetConnection*>(lpParameter);
return pInstance->_outputThread(); if (pInstance)
{
return pInstance->_outputThread();
}
return gsl::narrow_cast<DWORD>(ERROR_BAD_ARGUMENTS);
}, },
this, this,
0, 0,
@ -75,6 +80,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
str = "\r\n"; str = "\r\n";
} }
#pragma warning(suppress : 26490) // Using something that isn't reinterpret_cast to forward stream bytes is more clumsy than just using it.
telnetpp::bytes bytes(reinterpret_cast<const uint8_t*>(str.data()), str.size()); telnetpp::bytes bytes(reinterpret_cast<const uint8_t*>(str.data()), str.size());
_session.send(bytes, [=](telnetpp::bytes data) { _session.send(bytes, [=](telnetpp::bytes data) {
_socketSend(data); _socketSend(data);
@ -238,8 +244,16 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// - <none> // - <none>
void TelnetConnection::_socketBufferedSend(telnetpp::bytes data) void TelnetConnection::_socketBufferedSend(telnetpp::bytes data)
{ {
// winrt::array_view should take data/size but it doesn't.
// We contacted the WinRT owners and they said, more or less, that it's not worth fixing
// with std::span on the horizon instead of this. So we're suppressing the warning
// and hoping for a std::span future that will eliminate winrt::array_view<T>
#pragma warning(push)
#pragma warning(disable : 26481)
const uint8_t* first = data.data(); const uint8_t* first = data.data();
const uint8_t* last = data.data() + data.size(); const uint8_t* last = data.data() + data.size();
#pragma warning(pop)
const winrt::array_view<const uint8_t> arrayView(first, last); const winrt::array_view<const uint8_t> arrayView(first, last);
_writer.WriteBytes(arrayView); _writer.WriteBytes(arrayView);
} }
@ -283,9 +297,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// mad at us for it) to use a public array_view constructor. // mad at us for it) to use a public array_view constructor.
// The WinRT team isn't fixing this because std::span is coming // The WinRT team isn't fixing this because std::span is coming
// soon and that will do it. // soon and that will do it.
// So just do this for now and suppress the warnings. #pragma warning(push)
#pragma warning(disable : 26481)
const auto first = buffer.data(); const auto first = buffer.data();
const auto last = first + bytesLoaded; const auto last = first + bytesLoaded;
#pragma warning(pop)
const winrt::array_view<uint8_t> arrayView(first, last); const winrt::array_view<uint8_t> arrayView(first, last);
_reader.ReadBytes(arrayView); _reader.ReadBytes(arrayView);
return bytesLoaded; return bytesLoaded;
@ -304,6 +321,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
std::function<void(telnetpp::bytes)> const& /*send*/) std::function<void(telnetpp::bytes)> const& /*send*/)
{ {
// Convert telnetpp bytes to standard string_view // Convert telnetpp bytes to standard string_view
#pragma warning(suppress : 26490) // Using something that isn't reinterpret_cast to forward stream bytes is more clumsy than just using it.
const auto stringView = std::string_view{ reinterpret_cast<const char*>(data.data()), gsl::narrow<size_t>(data.size()) }; const auto stringView = std::string_view{ reinterpret_cast<const char*>(data.data()), gsl::narrow<size_t>(data.size()) };
// Convert to hstring // Convert to hstring

View File

@ -5,6 +5,7 @@
#include <LibraryResources.h> #include <LibraryResources.h>
// Note: Generate GUID using TlgGuid.exe tool // Note: Generate GUID using TlgGuid.exe tool
#pragma warning(suppress : 26477) // One of the macros uses 0/NULL. We don't have control to make it nullptr.
TRACELOGGING_DEFINE_PROVIDER( TRACELOGGING_DEFINE_PROVIDER(
g_hTerminalConnectionProvider, g_hTerminalConnectionProvider,
"Microsoft.Windows.Terminal.Connection", "Microsoft.Windows.Terminal.Connection",
@ -12,6 +13,7 @@ TRACELOGGING_DEFINE_PROVIDER(
(0xe912fe7b, 0xeeb6, 0x52a5, 0xc6, 0x28, 0xab, 0xe3, 0x88, 0xe5, 0xf7, 0x92), (0xe912fe7b, 0xeeb6, 0x52a5, 0xc6, 0x28, 0xab, 0xe3, 0x88, 0xe5, 0xf7, 0x92),
TraceLoggingOptionMicrosoftTelemetry()); TraceLoggingOptionMicrosoftTelemetry());
#pragma warning(suppress : 26440) // Not interested in changing the specification of DllMain to make it noexcept given it's an interface to the OS.
BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID /*reserved*/) BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID /*reserved*/)
{ {
switch (reason) switch (reason)

View File

@ -15,34 +15,34 @@ namespace Microsoft::Terminal::Core
ITerminalApi& operator=(const ITerminalApi&) = default; ITerminalApi& operator=(const ITerminalApi&) = default;
ITerminalApi& operator=(ITerminalApi&&) = default; ITerminalApi& operator=(ITerminalApi&&) = default;
virtual bool PrintString(std::wstring_view string) = 0; virtual bool PrintString(std::wstring_view string) noexcept = 0;
virtual bool ExecuteChar(wchar_t wch) = 0; virtual bool ExecuteChar(wchar_t wch) noexcept = 0;
virtual bool SetTextToDefaults(bool foreground, bool background) = 0; virtual bool SetTextToDefaults(bool foreground, bool background) noexcept = 0;
virtual bool SetTextForegroundIndex(BYTE colorIndex) = 0; virtual bool SetTextForegroundIndex(BYTE colorIndex) noexcept = 0;
virtual bool SetTextBackgroundIndex(BYTE colorIndex) = 0; virtual bool SetTextBackgroundIndex(BYTE colorIndex) noexcept = 0;
virtual bool SetTextRgbColor(COLORREF color, bool foreground) = 0; virtual bool SetTextRgbColor(COLORREF color, bool foreground) noexcept = 0;
virtual bool BoldText(bool boldOn) = 0; virtual bool BoldText(bool boldOn) noexcept = 0;
virtual bool UnderlineText(bool underlineOn) = 0; virtual bool UnderlineText(bool underlineOn) noexcept = 0;
virtual bool ReverseText(bool reversed) = 0; virtual bool ReverseText(bool reversed) noexcept = 0;
virtual bool SetCursorPosition(short x, short y) = 0; virtual bool SetCursorPosition(short x, short y) noexcept = 0;
virtual COORD GetCursorPosition() = 0; virtual COORD GetCursorPosition() noexcept = 0;
virtual bool DeleteCharacter(const size_t count) = 0; virtual bool DeleteCharacter(const size_t count) noexcept = 0;
virtual bool InsertCharacter(const size_t count) = 0; virtual bool InsertCharacter(const size_t count) noexcept = 0;
virtual bool EraseCharacters(const size_t numChars) = 0; virtual bool EraseCharacters(const size_t numChars) noexcept = 0;
virtual bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) = 0; virtual bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept = 0;
virtual bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) = 0; virtual bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept = 0;
virtual bool SetWindowTitle(std::wstring_view title) = 0; virtual bool SetWindowTitle(std::wstring_view title) noexcept = 0;
virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD color) = 0; virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD color) noexcept = 0;
virtual bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) = 0; virtual bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept = 0;
virtual bool SetDefaultForeground(const DWORD color) = 0; virtual bool SetDefaultForeground(const DWORD color) noexcept = 0;
virtual bool SetDefaultBackground(const DWORD color) = 0; virtual bool SetDefaultBackground(const DWORD color) noexcept = 0;
protected: protected:
ITerminalApi() = default; ITerminalApi() = default;

View File

@ -22,21 +22,22 @@ using namespace Microsoft::Console::VirtualTerminal;
static std::wstring _KeyEventsToText(std::deque<std::unique_ptr<IInputEvent>>& inEventsToWrite) static std::wstring _KeyEventsToText(std::deque<std::unique_ptr<IInputEvent>>& inEventsToWrite)
{ {
std::wstring wstr = L""; std::wstring wstr = L"";
for (auto& ev : inEventsToWrite) for (const auto& ev : inEventsToWrite)
{ {
if (ev->EventType() == InputEventType::KeyEvent) if (ev->EventType() == InputEventType::KeyEvent)
{ {
auto& k = static_cast<KeyEvent&>(*ev); const auto& k = static_cast<KeyEvent&>(*ev);
auto wch = k.GetCharData(); const auto wch = k.GetCharData();
wstr += wch; wstr += wch;
} }
} }
return wstr; return wstr;
} }
#pragma warning(suppress : 26455) // default constructor is throwing, too much effort to rearrange at this time.
Terminal::Terminal() : Terminal::Terminal() :
_mutableViewport{ Viewport::Empty() }, _mutableViewport{ Viewport::Empty() },
_title{ L"" }, _title{},
_colorTable{}, _colorTable{},
_defaultFg{ RGB(255, 255, 255) }, _defaultFg{ RGB(255, 255, 255) },
_defaultBg{ ARGB(0, 0, 0, 0) }, _defaultBg{ ARGB(0, 0, 0, 0) },
@ -139,7 +140,7 @@ void Terminal::UpdateSettings(winrt::Microsoft::Terminal::Settings::ICoreSetting
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
{ {
_colorTable[i] = settings.GetColorTableEntry(i); _colorTable.at(i) = settings.GetColorTableEntry(i);
} }
_snapOnInput = settings.SnapOnInput(); _snapOnInput = settings.SnapOnInput();
@ -310,32 +311,37 @@ WORD Terminal::_ScanCodeFromVirtualKey(const WORD vkey) noexcept
// Return Value: // Return Value:
// - The character that would result from this virtual key code and keyboard state. // - The character that would result from this virtual key code and keyboard state.
wchar_t Terminal::_CharacterFromKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states) noexcept wchar_t Terminal::_CharacterFromKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states) noexcept
try
{ {
const auto sc = scanCode != 0 ? scanCode : _ScanCodeFromVirtualKey(vkey); const auto sc = scanCode != 0 ? scanCode : _ScanCodeFromVirtualKey(vkey);
// We might want to use GetKeyboardState() instead of building our own keyState. // We might want to use GetKeyboardState() instead of building our own keyState.
// The question is whether that's necessary though. For now it seems to work fine as it is. // The question is whether that's necessary though. For now it seems to work fine as it is.
BYTE keyState[256] = {}; std::array<BYTE, 256> keyState = {};
keyState[VK_SHIFT] = states.IsShiftPressed() ? 0x80 : 0; keyState.at(VK_SHIFT) = states.IsShiftPressed() ? 0x80 : 0;
keyState[VK_CONTROL] = states.IsCtrlPressed() ? 0x80 : 0; keyState.at(VK_CONTROL) = states.IsCtrlPressed() ? 0x80 : 0;
keyState[VK_MENU] = states.IsAltPressed() ? 0x80 : 0; keyState.at(VK_MENU) = states.IsAltPressed() ? 0x80 : 0;
// For the following use of ToUnicodeEx() please look here: // For the following use of ToUnicodeEx() please look here:
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-tounicodeex // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-tounicodeex
// Technically ToUnicodeEx() can produce arbitrarily long sequences of diacritics etc. // Technically ToUnicodeEx() can produce arbitrarily long sequences of diacritics etc.
// Since we only handle the case of a single UTF-16 code point, we can set the buffer size to 2 though. // Since we only handle the case of a single UTF-16 code point, we can set the buffer size to 2 though.
constexpr size_t bufferSize = 2; std::array<wchar_t, 2> buffer;
wchar_t buffer[bufferSize];
// wFlags: // wFlags:
// * If bit 0 is set, a menu is active. // * If bit 0 is set, a menu is active.
// If this flag is not specified ToUnicodeEx will send us character events on certain Alt+Key combinations (e.g. Alt+Arrow-Up). // If this flag is not specified ToUnicodeEx will send us character events on certain Alt+Key combinations (e.g. Alt+Arrow-Up).
// * If bit 2 is set, keyboard state is not changed (Windows 10, version 1607 and newer) // * If bit 2 is set, keyboard state is not changed (Windows 10, version 1607 and newer)
const auto result = ToUnicodeEx(vkey, sc, keyState, buffer, bufferSize, 0b101, nullptr); const auto result = ToUnicodeEx(vkey, sc, keyState.data(), buffer.data(), gsl::narrow_cast<int>(buffer.size()), 0b101, nullptr);
// TODO:GH#2853 We're only handling single UTF-16 code points right now, since that's the only thing KeyEvent supports. // TODO:GH#2853 We're only handling single UTF-16 code points right now, since that's the only thing KeyEvent supports.
return result == 1 || result == -1 ? buffer[0] : 0; return result == 1 || result == -1 ? buffer.at(0) : 0;
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
return UNICODE_INVALID;
} }
// Method Description: // Method Description:
@ -416,7 +422,7 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
for (size_t i = 0; i < stringView.size(); i++) for (size_t i = 0; i < stringView.size(); i++)
{ {
wchar_t wch = stringView[i]; const auto wch = stringView.at(i);
const COORD cursorPosBefore = cursor.GetPosition(); const COORD cursorPosBefore = cursor.GetPosition();
COORD proposedCursorPosition = cursorPosBefore; COORD proposedCursorPosition = cursorPosBefore;
bool notifyScroll = false; bool notifyScroll = false;
@ -452,7 +458,7 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
// This is not great but I need it demoable. Fix by making a buffer stream writer. // This is not great but I need it demoable. Fix by making a buffer stream writer.
if (wch >= 0xD800 && wch <= 0xDFFF) if (wch >= 0xD800 && wch <= 0xDFFF)
{ {
OutputCellIterator it{ stringView.substr(i, 2), _buffer->GetCurrentAttributes() }; const OutputCellIterator it{ stringView.substr(i, 2), _buffer->GetCurrentAttributes() };
const auto end = _buffer->Write(it); const auto end = _buffer->Write(it);
const auto cellDistance = end.GetCellDistance(it); const auto cellDistance = end.GetCellDistance(it);
i += cellDistance - 1; i += cellDistance - 1;
@ -460,7 +466,7 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
} }
else else
{ {
OutputCellIterator it{ stringView.substr(i, 1), _buffer->GetCurrentAttributes() }; const OutputCellIterator it{ stringView.substr(i, 1), _buffer->GetCurrentAttributes() };
const auto end = _buffer->Write(it); const auto end = _buffer->Write(it);
const auto cellDistance = end.GetCellDistance(it); const auto cellDistance = end.GetCellDistance(it);
proposedCursorPosition.X += gsl::narrow<SHORT>(cellDistance); proposedCursorPosition.X += gsl::narrow<SHORT>(cellDistance);
@ -517,12 +523,13 @@ void Terminal::UserScrollViewport(const int viewTop)
_buffer->GetRenderTarget().TriggerRedrawAll(); _buffer->GetRenderTarget().TriggerRedrawAll();
} }
int Terminal::GetScrollOffset() int Terminal::GetScrollOffset() noexcept
{ {
return _VisibleStartIndex(); return _VisibleStartIndex();
} }
void Terminal::_NotifyScrollEvent() void Terminal::_NotifyScrollEvent() noexcept
try
{ {
if (_pfnScrollPositionChanged) if (_pfnScrollPositionChanged)
{ {
@ -533,20 +540,21 @@ void Terminal::_NotifyScrollEvent()
_pfnScrollPositionChanged(top, height, bottom); _pfnScrollPositionChanged(top, height, bottom);
} }
} }
CATCH_LOG()
void Terminal::SetWriteInputCallback(std::function<void(std::wstring&)> pfn) noexcept void Terminal::SetWriteInputCallback(std::function<void(std::wstring&)> pfn) noexcept
{ {
_pfnWriteInput = pfn; _pfnWriteInput.swap(pfn);
} }
void Terminal::SetTitleChangedCallback(std::function<void(const std::wstring_view&)> pfn) noexcept void Terminal::SetTitleChangedCallback(std::function<void(const std::wstring_view&)> pfn) noexcept
{ {
_pfnTitleChanged = pfn; _pfnTitleChanged.swap(pfn);
} }
void Terminal::SetScrollPositionChangedCallback(std::function<void(const int, const int, const int)> pfn) noexcept void Terminal::SetScrollPositionChangedCallback(std::function<void(const int, const int, const int)> pfn) noexcept
{ {
_pfnScrollPositionChanged = pfn; _pfnScrollPositionChanged.swap(pfn);
} }
// Method Description: // Method Description:
@ -555,12 +563,13 @@ void Terminal::SetScrollPositionChangedCallback(std::function<void(const int, co
// - pfn: a function callback that takes a uint32 (DWORD COLORREF) color in the format 0x00BBGGRR // - pfn: a function callback that takes a uint32 (DWORD COLORREF) color in the format 0x00BBGGRR
void Terminal::SetBackgroundCallback(std::function<void(const uint32_t)> pfn) noexcept void Terminal::SetBackgroundCallback(std::function<void(const uint32_t)> pfn) noexcept
{ {
_pfnBackgroundColorChanged = pfn; _pfnBackgroundColorChanged.swap(pfn);
} }
void Terminal::_InitializeColorTable() void Terminal::_InitializeColorTable()
try
{ {
gsl::span<COLORREF> tableView = { &_colorTable[0], gsl::narrow<ptrdiff_t>(_colorTable.size()) }; const gsl::span<COLORREF> tableView = { _colorTable.data(), gsl::narrow<ptrdiff_t>(_colorTable.size()) };
// First set up the basic 256 colors // First set up the basic 256 colors
Utils::Initialize256ColorTable(tableView); Utils::Initialize256ColorTable(tableView);
// Then use fill the first 16 values with the Campbell scheme // Then use fill the first 16 values with the Campbell scheme
@ -568,6 +577,7 @@ void Terminal::_InitializeColorTable()
// Then make sure all the values have an alpha of 255 // Then make sure all the values have an alpha of 255
Utils::SetColorTableAlpha(tableView, 0xff); Utils::SetColorTableAlpha(tableView, 0xff);
} }
CATCH_LOG()
// Method Description: // Method Description:
// - Sets the visibility of the text cursor. // - Sets the visibility of the text cursor.

View File

@ -64,27 +64,27 @@ public:
#pragma region ITerminalApi #pragma region ITerminalApi
// These methods are defined in TerminalApi.cpp // These methods are defined in TerminalApi.cpp
bool PrintString(std::wstring_view stringView) override; bool PrintString(std::wstring_view stringView) noexcept override;
bool ExecuteChar(wchar_t wch) override; bool ExecuteChar(wchar_t wch) noexcept override;
bool SetTextToDefaults(bool foreground, bool background) override; bool SetTextToDefaults(bool foreground, bool background) noexcept override;
bool SetTextForegroundIndex(BYTE colorIndex) override; bool SetTextForegroundIndex(BYTE colorIndex) noexcept override;
bool SetTextBackgroundIndex(BYTE colorIndex) override; bool SetTextBackgroundIndex(BYTE colorIndex) noexcept override;
bool SetTextRgbColor(COLORREF color, bool foreground) override; bool SetTextRgbColor(COLORREF color, bool foreground) noexcept override;
bool BoldText(bool boldOn) override; bool BoldText(bool boldOn) noexcept override;
bool UnderlineText(bool underlineOn) override; bool UnderlineText(bool underlineOn) noexcept override;
bool ReverseText(bool reversed) override; bool ReverseText(bool reversed) noexcept override;
bool SetCursorPosition(short x, short y) override; bool SetCursorPosition(short x, short y) noexcept override;
COORD GetCursorPosition() override; COORD GetCursorPosition() noexcept override;
bool DeleteCharacter(const size_t count) override; bool DeleteCharacter(const size_t count) noexcept override;
bool InsertCharacter(const size_t count) override; bool InsertCharacter(const size_t count) noexcept override;
bool EraseCharacters(const size_t numChars) override; bool EraseCharacters(const size_t numChars) noexcept override;
bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override; bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override;
bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override; bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override;
bool SetWindowTitle(std::wstring_view title) override; bool SetWindowTitle(std::wstring_view title) noexcept override;
bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) override; bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept override;
bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) override; bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept override;
bool SetDefaultForeground(const COLORREF color) override; bool SetDefaultForeground(const COLORREF color) noexcept override;
bool SetDefaultBackground(const COLORREF color) override; bool SetDefaultBackground(const COLORREF color) noexcept override;
#pragma endregion #pragma endregion
#pragma region ITerminalInput #pragma region ITerminalInput
@ -94,7 +94,7 @@ public:
[[nodiscard]] HRESULT UserResize(const COORD viewportSize) noexcept override; [[nodiscard]] HRESULT UserResize(const COORD viewportSize) noexcept override;
void UserScrollViewport(const int viewTop) override; void UserScrollViewport(const int viewTop) override;
int GetScrollOffset() override; int GetScrollOffset() noexcept override;
void TrySnapOnInput() override; void TrySnapOnInput() override;
#pragma endregion #pragma endregion
@ -128,7 +128,7 @@ public:
#pragma region IUiaData #pragma region IUiaData
std::vector<Microsoft::Console::Types::Viewport> GetSelectionRects() noexcept override; std::vector<Microsoft::Console::Types::Viewport> GetSelectionRects() noexcept override;
const bool IsSelectionActive() const noexcept; const bool IsSelectionActive() const noexcept override;
void ClearSelection() override; void ClearSelection() override;
void SelectNewRegion(const COORD coordStart, const COORD coordEnd) override; void SelectNewRegion(const COORD coordStart, const COORD coordEnd) override;
const COORD GetSelectionAnchor() const override; const COORD GetSelectionAnchor() const override;
@ -230,7 +230,7 @@ private:
void _WriteBuffer(const std::wstring_view& stringView); void _WriteBuffer(const std::wstring_view& stringView);
void _NotifyScrollEvent(); void _NotifyScrollEvent() noexcept;
#pragma region TextSelection #pragma region TextSelection
// These methods are defined in TerminalSelection.cpp // These methods are defined in TerminalSelection.cpp

View File

@ -10,20 +10,23 @@ using namespace Microsoft::Console::Types;
using namespace Microsoft::Console::VirtualTerminal; using namespace Microsoft::Console::VirtualTerminal;
// Print puts the text in the buffer and moves the cursor // Print puts the text in the buffer and moves the cursor
bool Terminal::PrintString(std::wstring_view stringView) bool Terminal::PrintString(std::wstring_view stringView) noexcept
try
{ {
_WriteBuffer(stringView); _WriteBuffer(stringView);
return true; return true;
} }
CATCH_LOG_RETURN_FALSE()
bool Terminal::ExecuteChar(wchar_t wch) bool Terminal::ExecuteChar(wchar_t wch) noexcept
try
{ {
std::wstring_view view{ &wch, 1 }; _WriteBuffer({ &wch, 1 });
_WriteBuffer(view);
return true; return true;
} }
CATCH_LOG_RETURN_FALSE()
bool Terminal::SetTextToDefaults(bool foreground, bool background) bool Terminal::SetTextToDefaults(bool foreground, bool background) noexcept
{ {
TextAttribute attrs = _buffer->GetCurrentAttributes(); TextAttribute attrs = _buffer->GetCurrentAttributes();
if (foreground) if (foreground)
@ -38,7 +41,7 @@ bool Terminal::SetTextToDefaults(bool foreground, bool background)
return true; return true;
} }
bool Terminal::SetTextForegroundIndex(BYTE colorIndex) bool Terminal::SetTextForegroundIndex(BYTE colorIndex) noexcept
{ {
TextAttribute attrs = _buffer->GetCurrentAttributes(); TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetIndexedAttributes({ colorIndex }, {}); attrs.SetIndexedAttributes({ colorIndex }, {});
@ -46,7 +49,7 @@ bool Terminal::SetTextForegroundIndex(BYTE colorIndex)
return true; return true;
} }
bool Terminal::SetTextBackgroundIndex(BYTE colorIndex) bool Terminal::SetTextBackgroundIndex(BYTE colorIndex) noexcept
{ {
TextAttribute attrs = _buffer->GetCurrentAttributes(); TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetIndexedAttributes({}, { colorIndex }); attrs.SetIndexedAttributes({}, { colorIndex });
@ -54,7 +57,7 @@ bool Terminal::SetTextBackgroundIndex(BYTE colorIndex)
return true; return true;
} }
bool Terminal::SetTextRgbColor(COLORREF color, bool foreground) bool Terminal::SetTextRgbColor(COLORREF color, bool foreground) noexcept
{ {
TextAttribute attrs = _buffer->GetCurrentAttributes(); TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetColor(color, foreground); attrs.SetColor(color, foreground);
@ -62,7 +65,7 @@ bool Terminal::SetTextRgbColor(COLORREF color, bool foreground)
return true; return true;
} }
bool Terminal::BoldText(bool boldOn) bool Terminal::BoldText(bool boldOn) noexcept
{ {
TextAttribute attrs = _buffer->GetCurrentAttributes(); TextAttribute attrs = _buffer->GetCurrentAttributes();
if (boldOn) if (boldOn)
@ -77,7 +80,7 @@ bool Terminal::BoldText(bool boldOn)
return true; return true;
} }
bool Terminal::UnderlineText(bool underlineOn) bool Terminal::UnderlineText(bool underlineOn) noexcept
{ {
TextAttribute attrs = _buffer->GetCurrentAttributes(); TextAttribute attrs = _buffer->GetCurrentAttributes();
WORD metaAttrs = attrs.GetMetaAttributes(); WORD metaAttrs = attrs.GetMetaAttributes();
@ -89,7 +92,7 @@ bool Terminal::UnderlineText(bool underlineOn)
return true; return true;
} }
bool Terminal::ReverseText(bool reversed) bool Terminal::ReverseText(bool reversed) noexcept
{ {
TextAttribute attrs = _buffer->GetCurrentAttributes(); TextAttribute attrs = _buffer->GetCurrentAttributes();
WORD metaAttrs = attrs.GetMetaAttributes(); WORD metaAttrs = attrs.GetMetaAttributes();
@ -101,7 +104,8 @@ bool Terminal::ReverseText(bool reversed)
return true; return true;
} }
bool Terminal::SetCursorPosition(short x, short y) bool Terminal::SetCursorPosition(short x, short y) noexcept
try
{ {
const auto viewport = _GetMutableViewport(); const auto viewport = _GetMutableViewport();
const auto viewOrigin = viewport.Origin(); const auto viewOrigin = viewport.Origin();
@ -113,8 +117,9 @@ bool Terminal::SetCursorPosition(short x, short y)
return true; return true;
} }
CATCH_LOG_RETURN_FALSE()
COORD Terminal::GetCursorPosition() COORD Terminal::GetCursorPosition() noexcept
{ {
const auto absoluteCursorPos = _buffer->GetCursor().GetPosition(); const auto absoluteCursorPos = _buffer->GetCursor().GetPosition();
const auto viewport = _GetMutableViewport(); const auto viewport = _GetMutableViewport();
@ -137,7 +142,8 @@ COORD Terminal::GetCursorPosition()
// - count, the number of characters to delete // - count, the number of characters to delete
// Return value: // Return value:
// - true if succeeded, false otherwise // - true if succeeded, false otherwise
bool Terminal::DeleteCharacter(const size_t count) bool Terminal::DeleteCharacter(const size_t count) noexcept
try
{ {
SHORT dist; SHORT dist;
if (!SUCCEEDED(SizeTToShort(count, &dist))) if (!SUCCEEDED(SizeTToShort(count, &dist)))
@ -147,7 +153,7 @@ bool Terminal::DeleteCharacter(const size_t count)
const auto cursorPos = _buffer->GetCursor().GetPosition(); const auto cursorPos = _buffer->GetCursor().GetPosition();
const auto copyToPos = cursorPos; const auto copyToPos = cursorPos;
const COORD copyFromPos{ cursorPos.X + dist, cursorPos.Y }; const COORD copyFromPos{ cursorPos.X + dist, cursorPos.Y };
auto sourceWidth = _mutableViewport.RightExclusive() - copyFromPos.X; const auto sourceWidth = _mutableViewport.RightExclusive() - copyFromPos.X;
SHORT width; SHORT width;
if (!SUCCEEDED(UIntToShort(sourceWidth, &width))) if (!SUCCEEDED(UIntToShort(sourceWidth, &width)))
{ {
@ -173,6 +179,7 @@ bool Terminal::DeleteCharacter(const size_t count)
return true; return true;
} }
CATCH_LOG_RETURN_FALSE()
// Method Description: // Method Description:
// - Inserts count spaces starting from the cursor's current position, moving over the existing text // - Inserts count spaces starting from the cursor's current position, moving over the existing text
@ -183,7 +190,8 @@ bool Terminal::DeleteCharacter(const size_t count)
// - count, the number of spaces to insert // - count, the number of spaces to insert
// Return value: // Return value:
// - true if succeeded, false otherwise // - true if succeeded, false otherwise
bool Terminal::InsertCharacter(const size_t count) bool Terminal::InsertCharacter(const size_t count) noexcept
try
{ {
// NOTE: the code below is _extremely_ similar to DeleteCharacter // NOTE: the code below is _extremely_ similar to DeleteCharacter
// We will want to use this same logic and implement a helper function instead // We will want to use this same logic and implement a helper function instead
@ -197,7 +205,7 @@ bool Terminal::InsertCharacter(const size_t count)
const auto cursorPos = _buffer->GetCursor().GetPosition(); const auto cursorPos = _buffer->GetCursor().GetPosition();
const auto copyFromPos = cursorPos; const auto copyFromPos = cursorPos;
const COORD copyToPos{ cursorPos.X + dist, cursorPos.Y }; const COORD copyToPos{ cursorPos.X + dist, cursorPos.Y };
auto sourceWidth = _mutableViewport.RightExclusive() - copyFromPos.X; const auto sourceWidth = _mutableViewport.RightExclusive() - copyFromPos.X;
SHORT width; SHORT width;
if (!SUCCEEDED(UIntToShort(sourceWidth, &width))) if (!SUCCEEDED(UIntToShort(sourceWidth, &width)))
{ {
@ -221,22 +229,25 @@ bool Terminal::InsertCharacter(const size_t count)
const auto data = OutputCell(*(_buffer->GetCellDataAt(sourcePos))); const auto data = OutputCell(*(_buffer->GetCellDataAt(sourcePos)));
_buffer->Write(OutputCellIterator({ &data, 1 }), targetPos); _buffer->Write(OutputCellIterator({ &data, 1 }), targetPos);
} while (source.WalkInBounds(sourcePos, walkDirection) && target.WalkInBounds(targetPos, walkDirection)); } while (source.WalkInBounds(sourcePos, walkDirection) && target.WalkInBounds(targetPos, walkDirection));
auto eraseIter = OutputCellIterator(UNICODE_SPACE, _buffer->GetCurrentAttributes(), dist); const auto eraseIter = OutputCellIterator(UNICODE_SPACE, _buffer->GetCurrentAttributes(), dist);
_buffer->Write(eraseIter, cursorPos); _buffer->Write(eraseIter, cursorPos);
return true; return true;
} }
CATCH_LOG_RETURN_FALSE()
bool Terminal::EraseCharacters(const size_t numChars) bool Terminal::EraseCharacters(const size_t numChars) noexcept
try
{ {
const auto absoluteCursorPos = _buffer->GetCursor().GetPosition(); const auto absoluteCursorPos = _buffer->GetCursor().GetPosition();
const auto viewport = _GetMutableViewport(); const auto viewport = _GetMutableViewport();
const short distanceToRight = viewport.RightExclusive() - absoluteCursorPos.X; const short distanceToRight = viewport.RightExclusive() - absoluteCursorPos.X;
const short fillLimit = std::min(static_cast<short>(numChars), distanceToRight); const short fillLimit = std::min(static_cast<short>(numChars), distanceToRight);
auto eraseIter = OutputCellIterator(UNICODE_SPACE, _buffer->GetCurrentAttributes(), fillLimit); const auto eraseIter = OutputCellIterator(UNICODE_SPACE, _buffer->GetCurrentAttributes(), fillLimit);
_buffer->Write(eraseIter, absoluteCursorPos); _buffer->Write(eraseIter, absoluteCursorPos);
return true; return true;
} }
CATCH_LOG_RETURN_FALSE()
// Method description: // Method description:
// - erases a line of text, either from // - erases a line of text, either from
@ -248,7 +259,8 @@ bool Terminal::EraseCharacters(const size_t numChars)
// - the erase type // - the erase type
// Return value: // Return value:
// - true if succeeded, false otherwise // - true if succeeded, false otherwise
bool Terminal::EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) bool Terminal::EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept
try
{ {
const auto cursorPos = _buffer->GetCursor().GetPosition(); const auto cursorPos = _buffer->GetCursor().GetPosition();
const auto viewport = _GetMutableViewport(); const auto viewport = _GetMutableViewport();
@ -275,12 +287,13 @@ bool Terminal::EraseInLine(const ::Microsoft::Console::VirtualTerminal::Dispatch
return false; return false;
} }
auto eraseIter = OutputCellIterator(UNICODE_SPACE, _buffer->GetCurrentAttributes(), nlength); const auto eraseIter = OutputCellIterator(UNICODE_SPACE, _buffer->GetCurrentAttributes(), nlength);
// Explicitly turn off end-of-line wrap-flag-setting when erasing cells. // Explicitly turn off end-of-line wrap-flag-setting when erasing cells.
_buffer->Write(eraseIter, startPos, false); _buffer->Write(eraseIter, startPos, false);
return true; return true;
} }
CATCH_LOG_RETURN_FALSE()
// Method description: // Method description:
// - erases text in the buffer in two ways depending on erase type // - erases text in the buffer in two ways depending on erase type
@ -290,10 +303,12 @@ bool Terminal::EraseInLine(const ::Microsoft::Console::VirtualTerminal::Dispatch
// - the erase type // - the erase type
// Return Value: // Return Value:
// - true if succeeded, false otherwise // - true if succeeded, false otherwise
bool Terminal::EraseInDisplay(const DispatchTypes::EraseType eraseType) bool Terminal::EraseInDisplay(const DispatchTypes::EraseType eraseType) noexcept
try
{ {
// Store the relative cursor position so we can restore it later after we move the viewport // Store the relative cursor position so we can restore it later after we move the viewport
const auto cursorPos = _buffer->GetCursor().GetPosition(); const auto cursorPos = _buffer->GetCursor().GetPosition();
#pragma warning(suppress : 26496) // This is written by ConvertToOrigin, cpp core checks is wrong saying it should be const.
auto relativeCursor = cursorPos; auto relativeCursor = cursorPos;
_mutableViewport.ConvertToOrigin(&relativeCursor); _mutableViewport.ConvertToOrigin(&relativeCursor);
@ -337,8 +352,8 @@ bool Terminal::EraseInDisplay(const DispatchTypes::EraseType eraseType)
// Since we only did a rotation, the text that was in the scrollback is now _below_ where we are going to move the viewport // Since we only did a rotation, the text that was in the scrollback is now _below_ where we are going to move the viewport
// and we have to make sure we erase that text // and we have to make sure we erase that text
auto eraseStart = _mutableViewport.Height(); const auto eraseStart = _mutableViewport.Height();
auto eraseEnd = _buffer->GetLastNonSpaceCharacter(_mutableViewport).Y; const auto eraseEnd = _buffer->GetLastNonSpaceCharacter(_mutableViewport).Y;
for (SHORT i = eraseStart; i <= eraseEnd; i++) for (SHORT i = eraseStart; i <= eraseEnd; i++)
{ {
_buffer->GetRowByOffset(i).Reset(_buffer->GetCurrentAttributes()); _buffer->GetRowByOffset(i).Reset(_buffer->GetCurrentAttributes());
@ -362,8 +377,10 @@ bool Terminal::EraseInDisplay(const DispatchTypes::EraseType eraseType)
return true; return true;
} }
CATCH_LOG_RETURN_FALSE()
bool Terminal::SetWindowTitle(std::wstring_view title) bool Terminal::SetWindowTitle(std::wstring_view title) noexcept
try
{ {
_title = _suppressApplicationTitle ? _startingTitle : title; _title = _suppressApplicationTitle ? _startingTitle : title;
@ -371,6 +388,7 @@ bool Terminal::SetWindowTitle(std::wstring_view title)
return true; return true;
} }
CATCH_LOG_RETURN_FALSE()
// Method Description: // Method Description:
// - Updates the value in the colortable at index tableIndex to the new color // - Updates the value in the colortable at index tableIndex to the new color
@ -380,21 +398,16 @@ bool Terminal::SetWindowTitle(std::wstring_view title)
// - color: the new COLORREF to use as that color table value. // - color: the new COLORREF to use as that color table value.
// Return Value: // Return Value:
// - true iff we successfully updated the color table entry. // - true iff we successfully updated the color table entry.
bool Terminal::SetColorTableEntry(const size_t tableIndex, const COLORREF color) bool Terminal::SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept
try
{ {
try _colorTable.at(tableIndex) = color;
{
_colorTable.at(tableIndex) = color;
// Repaint everything - the colors might have changed // Repaint everything - the colors might have changed
_buffer->GetRenderTarget().TriggerRedrawAll(); _buffer->GetRenderTarget().TriggerRedrawAll();
return true; return true;
}
catch (std::out_of_range&)
{
return false;
}
} }
CATCH_LOG_RETURN_FALSE()
// Method Description: // Method Description:
// - Sets the cursor style to the given style. // - Sets the cursor style to the given style.
@ -402,10 +415,10 @@ bool Terminal::SetColorTableEntry(const size_t tableIndex, const COLORREF color)
// - cursorStyle: the style to be set for the cursor // - cursorStyle: the style to be set for the cursor
// Return Value: // Return Value:
// - true iff we successfully set the cursor style // - true iff we successfully set the cursor style
bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) noexcept
{ {
CursorType finalCursorType; CursorType finalCursorType = CursorType::Legacy;
bool fShouldBlink; bool shouldBlink = false;
switch (cursorStyle) switch (cursorStyle)
{ {
@ -413,35 +426,35 @@ bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
[[fallthrough]]; [[fallthrough]];
case DispatchTypes::CursorStyle::BlinkingBlock: case DispatchTypes::CursorStyle::BlinkingBlock:
finalCursorType = CursorType::FullBox; finalCursorType = CursorType::FullBox;
fShouldBlink = true; shouldBlink = true;
break; break;
case DispatchTypes::CursorStyle::SteadyBlock: case DispatchTypes::CursorStyle::SteadyBlock:
finalCursorType = CursorType::FullBox; finalCursorType = CursorType::FullBox;
fShouldBlink = false; shouldBlink = false;
break; break;
case DispatchTypes::CursorStyle::BlinkingUnderline: case DispatchTypes::CursorStyle::BlinkingUnderline:
finalCursorType = CursorType::Underscore; finalCursorType = CursorType::Underscore;
fShouldBlink = true; shouldBlink = true;
break; break;
case DispatchTypes::CursorStyle::SteadyUnderline: case DispatchTypes::CursorStyle::SteadyUnderline:
finalCursorType = CursorType::Underscore; finalCursorType = CursorType::Underscore;
fShouldBlink = false; shouldBlink = false;
break; break;
case DispatchTypes::CursorStyle::BlinkingBar: case DispatchTypes::CursorStyle::BlinkingBar:
finalCursorType = CursorType::VerticalBar; finalCursorType = CursorType::VerticalBar;
fShouldBlink = true; shouldBlink = true;
break; break;
case DispatchTypes::CursorStyle::SteadyBar: case DispatchTypes::CursorStyle::SteadyBar:
finalCursorType = CursorType::VerticalBar; finalCursorType = CursorType::VerticalBar;
fShouldBlink = false; shouldBlink = false;
break; break;
default: default:
finalCursorType = CursorType::Legacy; finalCursorType = CursorType::Legacy;
fShouldBlink = false; shouldBlink = false;
} }
_buffer->GetCursor().SetType(finalCursorType); _buffer->GetCursor().SetType(finalCursorType);
_buffer->GetCursor().SetBlinkingAllowed(fShouldBlink); _buffer->GetCursor().SetBlinkingAllowed(shouldBlink);
return true; return true;
} }
@ -452,7 +465,8 @@ bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
// - color: the new COLORREF to use as the default foreground color // - color: the new COLORREF to use as the default foreground color
// Return Value: // Return Value:
// - true // - true
bool Terminal::SetDefaultForeground(const COLORREF color) bool Terminal::SetDefaultForeground(const COLORREF color) noexcept
try
{ {
_defaultFg = color; _defaultFg = color;
@ -460,6 +474,7 @@ bool Terminal::SetDefaultForeground(const COLORREF color)
_buffer->GetRenderTarget().TriggerRedrawAll(); _buffer->GetRenderTarget().TriggerRedrawAll();
return true; return true;
} }
CATCH_LOG_RETURN_FALSE()
// Method Description: // Method Description:
// - Updates the default background color from a COLORREF, format 0x00BBGGRR. // - Updates the default background color from a COLORREF, format 0x00BBGGRR.
@ -467,7 +482,8 @@ bool Terminal::SetDefaultForeground(const COLORREF color)
// - color: the new COLORREF to use as the default background color // - color: the new COLORREF to use as the default background color
// Return Value: // Return Value:
// - true // - true
bool Terminal::SetDefaultBackground(const COLORREF color) bool Terminal::SetDefaultBackground(const COLORREF color) noexcept
try
{ {
_defaultBg = color; _defaultBg = color;
_pfnBackgroundColorChanged(color); _pfnBackgroundColorChanged(color);
@ -476,3 +492,4 @@ bool Terminal::SetDefaultBackground(const COLORREF color)
_buffer->GetRenderTarget().TriggerRedrawAll(); _buffer->GetRenderTarget().TriggerRedrawAll();
return true; return true;
} }
CATCH_LOG_RETURN_FALSE()

View File

@ -10,66 +10,83 @@ using namespace ::Microsoft::Console::VirtualTerminal;
// Functions related to Set Graphics Renditions (SGR) are in // Functions related to Set Graphics Renditions (SGR) are in
// TerminalDispatchGraphics.cpp, not this file // TerminalDispatchGraphics.cpp, not this file
TerminalDispatch::TerminalDispatch(ITerminalApi& terminalApi) : TerminalDispatch::TerminalDispatch(ITerminalApi& terminalApi) noexcept :
_terminalApi{ terminalApi } _terminalApi{ terminalApi }
{ {
} }
void TerminalDispatch::Execute(const wchar_t wchControl) void TerminalDispatch::Execute(const wchar_t wchControl) noexcept
{ {
_terminalApi.ExecuteChar(wchControl); _terminalApi.ExecuteChar(wchControl);
} }
void TerminalDispatch::Print(const wchar_t wchPrintable) void TerminalDispatch::Print(const wchar_t wchPrintable) noexcept
{ {
_terminalApi.PrintString({ &wchPrintable, 1 }); _terminalApi.PrintString({ &wchPrintable, 1 });
} }
void TerminalDispatch::PrintString(const std::wstring_view string) void TerminalDispatch::PrintString(const std::wstring_view string) noexcept
{ {
_terminalApi.PrintString(string); _terminalApi.PrintString(string);
} }
bool TerminalDispatch::CursorPosition(const size_t line, bool TerminalDispatch::CursorPosition(const size_t line,
const size_t column) noexcept const size_t column) noexcept
try
{ {
const auto columnInBufferSpace = column - 1; SHORT x{ 0 };
const auto lineInBufferSpace = line - 1; SHORT y{ 0 };
short x = static_cast<short>(column - 1);
short y = static_cast<short>(line - 1); RETURN_BOOL_IF_FALSE(FAILED(SizeTToShort(column, &x)) ||
FAILED(SizeTToShort(line, &y)));
RETURN_BOOL_IF_FALSE(FAILED(ShortSub(x, 1, &x)) ||
FAILED(ShortSub(y, 1, &y)));
return _terminalApi.SetCursorPosition(x, y); return _terminalApi.SetCursorPosition(x, y);
} }
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::CursorForward(const size_t distance) noexcept bool TerminalDispatch::CursorForward(const size_t distance) noexcept
try
{ {
const auto cursorPos = _terminalApi.GetCursorPosition(); const auto cursorPos = _terminalApi.GetCursorPosition();
const COORD newCursorPos{ cursorPos.X + gsl::narrow<short>(distance), cursorPos.Y }; const COORD newCursorPos{ cursorPos.X + gsl::narrow<short>(distance), cursorPos.Y };
return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y); return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
} }
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::CursorBackward(const size_t distance) noexcept bool TerminalDispatch::CursorBackward(const size_t distance) noexcept
try
{ {
const auto cursorPos = _terminalApi.GetCursorPosition(); const auto cursorPos = _terminalApi.GetCursorPosition();
const COORD newCursorPos{ cursorPos.X - gsl::narrow<short>(distance), cursorPos.Y }; const COORD newCursorPos{ cursorPos.X - gsl::narrow<short>(distance), cursorPos.Y };
return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y); return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
} }
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::CursorUp(const size_t distance) noexcept bool TerminalDispatch::CursorUp(const size_t distance) noexcept
try
{ {
const auto cursorPos = _terminalApi.GetCursorPosition(); const auto cursorPos = _terminalApi.GetCursorPosition();
const COORD newCursorPos{ cursorPos.X, cursorPos.Y + gsl::narrow<short>(distance) }; const COORD newCursorPos{ cursorPos.X, cursorPos.Y + gsl::narrow<short>(distance) };
return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y); return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
} }
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::EraseCharacters(const size_t numChars) noexcept bool TerminalDispatch::EraseCharacters(const size_t numChars) noexcept
try
{ {
return _terminalApi.EraseCharacters(numChars); return _terminalApi.EraseCharacters(numChars);
} }
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::SetWindowTitle(std::wstring_view title) noexcept bool TerminalDispatch::SetWindowTitle(std::wstring_view title) noexcept
try
{ {
return _terminalApi.SetWindowTitle(title); return _terminalApi.SetWindowTitle(title);
} }
CATCH_LOG_RETURN_FALSE()
// Method Description: // Method Description:
// - Sets a single entry of the colortable to a new value // - Sets a single entry of the colortable to a new value
@ -80,14 +97,18 @@ bool TerminalDispatch::SetWindowTitle(std::wstring_view title) noexcept
// True if handled successfully. False otherwise. // True if handled successfully. False otherwise.
bool TerminalDispatch::SetColorTableEntry(const size_t tableIndex, bool TerminalDispatch::SetColorTableEntry(const size_t tableIndex,
const DWORD color) noexcept const DWORD color) noexcept
try
{ {
return _terminalApi.SetColorTableEntry(tableIndex, color); return _terminalApi.SetColorTableEntry(tableIndex, color);
} }
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) noexcept bool TerminalDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) noexcept
try
{ {
return _terminalApi.SetCursorStyle(cursorStyle); return _terminalApi.SetCursorStyle(cursorStyle);
} }
CATCH_LOG_RETURN_FALSE()
// Method Description: // Method Description:
// - Sets the default foreground color to a new value // - Sets the default foreground color to a new value
@ -96,9 +117,11 @@ bool TerminalDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorSty
// Return Value: // Return Value:
// True if handled successfully. False otherwise. // True if handled successfully. False otherwise.
bool TerminalDispatch::SetDefaultForeground(const DWORD color) noexcept bool TerminalDispatch::SetDefaultForeground(const DWORD color) noexcept
try
{ {
return _terminalApi.SetDefaultForeground(color); return _terminalApi.SetDefaultForeground(color);
} }
CATCH_LOG_RETURN_FALSE()
// Method Description: // Method Description:
// - Sets the default background color to a new value // - Sets the default background color to a new value
@ -107,9 +130,11 @@ bool TerminalDispatch::SetDefaultForeground(const DWORD color) noexcept
// Return Value: // Return Value:
// True if handled successfully. False otherwise. // True if handled successfully. False otherwise.
bool TerminalDispatch::SetDefaultBackground(const DWORD color) noexcept bool TerminalDispatch::SetDefaultBackground(const DWORD color) noexcept
try
{ {
return _terminalApi.SetDefaultBackground(color); return _terminalApi.SetDefaultBackground(color);
} }
CATCH_LOG_RETURN_FALSE()
// Method Description: // Method Description:
// - Erases characters in the buffer depending on the erase type // - Erases characters in the buffer depending on the erase type
@ -118,9 +143,11 @@ bool TerminalDispatch::SetDefaultBackground(const DWORD color) noexcept
// Return Value: // Return Value:
// True if handled successfully. False otherwise. // True if handled successfully. False otherwise.
bool TerminalDispatch::EraseInLine(const DispatchTypes::EraseType eraseType) noexcept bool TerminalDispatch::EraseInLine(const DispatchTypes::EraseType eraseType) noexcept
try
{ {
return _terminalApi.EraseInLine(eraseType); return _terminalApi.EraseInLine(eraseType);
} }
CATCH_LOG_RETURN_FALSE()
// Method Description: // Method Description:
// - Deletes count number of characters starting from where the cursor is currently // - Deletes count number of characters starting from where the cursor is currently
@ -129,9 +156,11 @@ bool TerminalDispatch::EraseInLine(const DispatchTypes::EraseType eraseType) noe
// Return Value: // Return Value:
// True if handled successfully. False otherwise. // True if handled successfully. False otherwise.
bool TerminalDispatch::DeleteCharacter(const size_t count) noexcept bool TerminalDispatch::DeleteCharacter(const size_t count) noexcept
try
{ {
return _terminalApi.DeleteCharacter(count); return _terminalApi.DeleteCharacter(count);
} }
CATCH_LOG_RETURN_FALSE()
// Method Description: // Method Description:
// - Adds count number of spaces starting from where the cursor is currently // - Adds count number of spaces starting from where the cursor is currently
@ -140,9 +169,11 @@ bool TerminalDispatch::DeleteCharacter(const size_t count) noexcept
// Return Value: // Return Value:
// True if handled successfully, false otherwise // True if handled successfully, false otherwise
bool TerminalDispatch::InsertCharacter(const size_t count) noexcept bool TerminalDispatch::InsertCharacter(const size_t count) noexcept
try
{ {
return _terminalApi.InsertCharacter(count); return _terminalApi.InsertCharacter(count);
} }
CATCH_LOG_RETURN_FALSE()
// Method Description: // Method Description:
// - Moves the viewport and erases text from the buffer depending on the eraseType // - Moves the viewport and erases text from the buffer depending on the eraseType
@ -151,6 +182,8 @@ bool TerminalDispatch::InsertCharacter(const size_t count) noexcept
// Return Value: // Return Value:
// True if handled successfully. False otherwise // True if handled successfully. False otherwise
bool TerminalDispatch::EraseInDisplay(const DispatchTypes::EraseType eraseType) noexcept bool TerminalDispatch::EraseInDisplay(const DispatchTypes::EraseType eraseType) noexcept
try
{ {
return _terminalApi.EraseInDisplay(eraseType); return _terminalApi.EraseInDisplay(eraseType);
} }
CATCH_LOG_RETURN_FALSE()

View File

@ -7,16 +7,16 @@
class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatch class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatch
{ {
public: public:
TerminalDispatch(::Microsoft::Terminal::Core::ITerminalApi& terminalApi); TerminalDispatch(::Microsoft::Terminal::Core::ITerminalApi& terminalApi) noexcept;
virtual ~TerminalDispatch(){};
virtual void Execute(const wchar_t wchControl) override; void Execute(const wchar_t wchControl) noexcept override;
virtual void Print(const wchar_t wchPrintable) override; void Print(const wchar_t wchPrintable) noexcept override;
virtual void PrintString(const std::wstring_view string) override; void PrintString(const std::wstring_view string) noexcept override;
bool SetGraphicsRendition(const std::basic_string_view<::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions> options) noexcept override; bool SetGraphicsRendition(const std::basic_string_view<::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions> options) noexcept override;
virtual bool CursorPosition(const size_t line, bool CursorPosition(const size_t line,
const size_t column) noexcept override; // CUP const size_t column) noexcept override; // CUP
bool CursorForward(const size_t distance) noexcept override; bool CursorForward(const size_t distance) noexcept override;
bool CursorBackward(const size_t distance) noexcept override; bool CursorBackward(const size_t distance) noexcept override;
@ -38,13 +38,9 @@ public:
private: private:
::Microsoft::Terminal::Core::ITerminalApi& _terminalApi; ::Microsoft::Terminal::Core::ITerminalApi& _terminalApi;
static bool s_IsRgbColorOption(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
static bool s_IsBoldColorOption(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
static bool s_IsDefaultColorOption(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
bool _SetRgbColorsHelper(const std::basic_string_view<::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions> options, bool _SetRgbColorsHelper(const std::basic_string_view<::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions> options,
size_t& optionsConsumed); size_t& optionsConsumed) noexcept;
bool _SetBoldColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions option); bool _SetBoldColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
bool _SetDefaultColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions option); bool _SetDefaultColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
void _SetGraphicsOptionHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt); void _SetGraphicsOptionHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
}; };

View File

@ -34,7 +34,7 @@ const BYTE BRIGHT_WHITE = BRIGHT_ATTR | RED_ATTR | GREEN_ATTR | BLUE_ATTR;
// These are followed by up to 4 more values which compose the entire option. // These are followed by up to 4 more values which compose the entire option.
// Return Value: // Return Value:
// - true if the opt is the indicator for an extended color sequence, false otherwise. // - true if the opt is the indicator for an extended color sequence, false otherwise.
bool TerminalDispatch::s_IsRgbColorOption(const DispatchTypes::GraphicsOptions opt) noexcept static constexpr bool _isRgbColorOption(const DispatchTypes::GraphicsOptions opt) noexcept
{ {
return opt == DispatchTypes::GraphicsOptions::ForegroundExtended || return opt == DispatchTypes::GraphicsOptions::ForegroundExtended ||
opt == DispatchTypes::GraphicsOptions::BackgroundExtended; opt == DispatchTypes::GraphicsOptions::BackgroundExtended;
@ -45,7 +45,7 @@ bool TerminalDispatch::s_IsRgbColorOption(const DispatchTypes::GraphicsOptions o
// These are followed by up to 4 more values which compose the entire option. // These are followed by up to 4 more values which compose the entire option.
// Return Value: // Return Value:
// - true if the opt is the indicator for an extended color sequence, false otherwise. // - true if the opt is the indicator for an extended color sequence, false otherwise.
bool TerminalDispatch::s_IsBoldColorOption(const DispatchTypes::GraphicsOptions opt) noexcept static constexpr bool _isBoldColorOption(const DispatchTypes::GraphicsOptions opt) noexcept
{ {
return opt == DispatchTypes::GraphicsOptions::BoldBright || return opt == DispatchTypes::GraphicsOptions::BoldBright ||
opt == DispatchTypes::GraphicsOptions::UnBold; opt == DispatchTypes::GraphicsOptions::UnBold;
@ -56,7 +56,7 @@ bool TerminalDispatch::s_IsBoldColorOption(const DispatchTypes::GraphicsOptions
//the default attributes. //the default attributes.
// Return Value: // Return Value:
// - true if the opt sets either/or attribute to the defaults, false otherwise. // - true if the opt sets either/or attribute to the defaults, false otherwise.
bool TerminalDispatch::s_IsDefaultColorOption(const DispatchTypes::GraphicsOptions opt) noexcept static constexpr bool _isDefaultColorOption(const DispatchTypes::GraphicsOptions opt) noexcept
{ {
return opt == DispatchTypes::GraphicsOptions::Off || return opt == DispatchTypes::GraphicsOptions::Off ||
opt == DispatchTypes::GraphicsOptions::ForegroundDefault || opt == DispatchTypes::GraphicsOptions::ForegroundDefault ||
@ -79,18 +79,18 @@ bool TerminalDispatch::s_IsDefaultColorOption(const DispatchTypes::GraphicsOptio
// 3 - true, parsed an xterm index to a color // 3 - true, parsed an xterm index to a color
// 5 - true, parsed an RGB color. // 5 - true, parsed an RGB color.
bool TerminalDispatch::_SetRgbColorsHelper(const std::basic_string_view<DispatchTypes::GraphicsOptions> options, bool TerminalDispatch::_SetRgbColorsHelper(const std::basic_string_view<DispatchTypes::GraphicsOptions> options,
size_t& optionsConsumed) size_t& optionsConsumed) noexcept
{ {
COLORREF color = 0; COLORREF color = 0;
bool isForeground = false; bool isForeground = false;
bool success = false; bool success = false;
optionsConsumed = 1; optionsConsumed = 1;
if (options.size() >= 2 && s_IsRgbColorOption(options.front())) if (options.size() >= 2 && _isRgbColorOption(options.front()))
{ {
optionsConsumed = 2; optionsConsumed = 2;
DispatchTypes::GraphicsOptions extendedOpt = options.at(0); const auto extendedOpt = til::at(options, 0);
DispatchTypes::GraphicsOptions typeOpt = options.at(1); const auto typeOpt = til::at(options, 1);
if (extendedOpt == DispatchTypes::GraphicsOptions::ForegroundExtended) if (extendedOpt == DispatchTypes::GraphicsOptions::ForegroundExtended)
{ {
@ -105,7 +105,7 @@ bool TerminalDispatch::_SetRgbColorsHelper(const std::basic_string_view<Dispatch
{ {
optionsConsumed = 5; optionsConsumed = 5;
// ensure that each value fits in a byte // ensure that each value fits in a byte
const auto limit = (DispatchTypes::GraphicsOptions)255; const auto limit = static_cast<DispatchTypes::GraphicsOptions>(255);
const auto red = std::min(options.at(2), limit); const auto red = std::min(options.at(2), limit);
const auto green = std::min(options.at(3), limit); const auto green = std::min(options.at(3), limit);
const auto blue = std::min(options.at(4), limit); const auto blue = std::min(options.at(4), limit);
@ -119,23 +119,23 @@ bool TerminalDispatch::_SetRgbColorsHelper(const std::basic_string_view<Dispatch
optionsConsumed = 3; optionsConsumed = 3;
if (options.at(2) <= 255) // ensure that the provided index is on the table if (options.at(2) <= 255) // ensure that the provided index is on the table
{ {
unsigned int tableIndex = options.at(2); const auto tableIndex = til::at(options, 2);
success = isForeground ? success = isForeground ?
_terminalApi.SetTextForegroundIndex((BYTE)tableIndex) : _terminalApi.SetTextForegroundIndex(gsl::narrow_cast<BYTE>(tableIndex)) :
_terminalApi.SetTextBackgroundIndex((BYTE)tableIndex); _terminalApi.SetTextBackgroundIndex(gsl::narrow_cast<BYTE>(tableIndex));
} }
} }
} }
return success; return success;
} }
bool TerminalDispatch::_SetBoldColorHelper(const DispatchTypes::GraphicsOptions option) bool TerminalDispatch::_SetBoldColorHelper(const DispatchTypes::GraphicsOptions option) noexcept
{ {
const bool bold = (option == DispatchTypes::GraphicsOptions::BoldBright); const bool bold = (option == DispatchTypes::GraphicsOptions::BoldBright);
return _terminalApi.BoldText(bold); return _terminalApi.BoldText(bold);
} }
bool TerminalDispatch::_SetDefaultColorHelper(const DispatchTypes::GraphicsOptions option) bool TerminalDispatch::_SetDefaultColorHelper(const DispatchTypes::GraphicsOptions option) noexcept
{ {
const bool fg = option == DispatchTypes::GraphicsOptions::Off || option == DispatchTypes::GraphicsOptions::ForegroundDefault; const bool fg = option == DispatchTypes::GraphicsOptions::Off || option == DispatchTypes::GraphicsOptions::ForegroundDefault;
const bool bg = option == DispatchTypes::GraphicsOptions::Off || option == DispatchTypes::GraphicsOptions::BackgroundDefault; const bool bg = option == DispatchTypes::GraphicsOptions::Off || option == DispatchTypes::GraphicsOptions::BackgroundDefault;
@ -160,7 +160,7 @@ bool TerminalDispatch::_SetDefaultColorHelper(const DispatchTypes::GraphicsOptio
// - pAttr - Pointer to the font attribute field to adjust // - pAttr - Pointer to the font attribute field to adjust
// Return Value: // Return Value:
// - <none> // - <none>
void TerminalDispatch::_SetGraphicsOptionHelper(const DispatchTypes::GraphicsOptions opt) void TerminalDispatch::_SetGraphicsOptionHelper(const DispatchTypes::GraphicsOptions opt) noexcept
{ {
switch (opt) switch (opt)
{ {
@ -293,16 +293,16 @@ bool TerminalDispatch::SetGraphicsRendition(const std::basic_string_view<Dispatc
// Run through the graphics options and apply them // Run through the graphics options and apply them
for (size_t i = 0; i < options.size(); i++) for (size_t i = 0; i < options.size(); i++)
{ {
DispatchTypes::GraphicsOptions opt = options.at(i); const auto opt = options.at(i);
if (s_IsDefaultColorOption(opt)) if (_isDefaultColorOption(opt))
{ {
success = _SetDefaultColorHelper(opt); success = _SetDefaultColorHelper(opt);
} }
else if (s_IsBoldColorOption(opt)) else if (_isBoldColorOption(opt))
{ {
success = _SetBoldColorHelper(opt); success = _SetBoldColorHelper(opt);
} }
else if (s_IsRgbColorOption(opt)) else if (_isRgbColorOption(opt))
{ {
size_t optionsConsumed = 0; size_t optionsConsumed = 0;

View File

@ -240,6 +240,7 @@ const bool Terminal::IsCopyOnSelectActive() const noexcept
// - position: the (x,y) coordinate on the visible viewport // - position: the (x,y) coordinate on the visible viewport
void Terminal::DoubleClickSelection(const COORD position) void Terminal::DoubleClickSelection(const COORD position)
{ {
#pragma warning(suppress : 26496) // cpp core checks wants this const but .Clamp() can write it.
COORD positionWithOffsets = _ConvertToBufferCell(position); COORD positionWithOffsets = _ConvertToBufferCell(position);
// scan leftwards until delimiter is found and // scan leftwards until delimiter is found and
@ -364,6 +365,7 @@ const TextBuffer::TextAndColor Terminal::RetrieveSelectedTextFromBuffer(bool tri
COORD Terminal::_ExpandDoubleClickSelectionLeft(const COORD position) const COORD Terminal::_ExpandDoubleClickSelectionLeft(const COORD position) const
{ {
// force position to be within bounds // force position to be within bounds
#pragma warning(suppress : 26496) // cpp core checks wants this const but .Clamp() can write it.
COORD positionWithOffsets = position; COORD positionWithOffsets = position;
_buffer->GetSize().Clamp(positionWithOffsets); _buffer->GetSize().Clamp(positionWithOffsets);
@ -380,6 +382,7 @@ COORD Terminal::_ExpandDoubleClickSelectionLeft(const COORD position) const
COORD Terminal::_ExpandDoubleClickSelectionRight(const COORD position) const COORD Terminal::_ExpandDoubleClickSelectionRight(const COORD position) const
{ {
// force position to be within bounds // force position to be within bounds
#pragma warning(suppress : 26496) // cpp core checks wants this const but .Clamp() can write it.
COORD positionWithOffsets = position; COORD positionWithOffsets = position;
_buffer->GetSize().Clamp(positionWithOffsets); _buffer->GetSize().Clamp(positionWithOffsets);

View File

@ -10,6 +10,11 @@
<RootNamespace>Microsoft.Terminal.Core</RootNamespace> <RootNamespace>Microsoft.Terminal.Core</RootNamespace>
</PropertyGroup> </PropertyGroup>
<!-- Imported WinRT generated files must go up here to get excluded from Audit correctly. -->
<PropertyGroup Condition="'$(Configuration)'=='AuditMode'">
<CAExcludePath>"$(SolutionDir)\src\cascadia\TerminalSettings\Generated Files\winrt";$(SolutionDir)src\cascadia\TerminalSettings;$(CAExcludePath)</CAExcludePath>
</PropertyGroup>
<Import Project="..\..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" /> <Import Project="..\..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(SolutionDir)src\common.build.pre.props" /> <Import Project="$(SolutionDir)src\common.build.pre.props" />
@ -49,7 +54,6 @@
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
<Import Project="$(SolutionDir)src\common.build.post.props" /> <Import Project="$(SolutionDir)src\common.build.post.props" />
</Project> </Project>

View File

@ -27,6 +27,11 @@ const TextBuffer& Terminal::GetTextBuffer() noexcept
return *_buffer; return *_buffer;
} }
// Creating a FontInfo can technically throw (on string allocation) and this is noexcept.
// That means this will std::terminate. We could come back and make there be a default constructor
// backup to FontInfo that throws no exceptions and allocates a default FontInfo structure.
#pragma warning(push)
#pragma warning(disable : 26447)
const FontInfo& Terminal::GetFontInfo() noexcept const FontInfo& Terminal::GetFontInfo() noexcept
{ {
// TODO: This font value is only used to check if the font is a raster font. // TODO: This font value is only used to check if the font is a raster font.
@ -38,6 +43,7 @@ const FontInfo& Terminal::GetFontInfo() noexcept
static const FontInfo _fakeFontInfo(DEFAULT_FONT_FACE.c_str(), TMPF_TRUETYPE, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false); static const FontInfo _fakeFontInfo(DEFAULT_FONT_FACE.c_str(), TMPF_TRUETYPE, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false);
return _fakeFontInfo; return _fakeFontInfo;
} }
#pragma warning(pop)
const TextAttribute Terminal::GetDefaultBrushColors() noexcept const TextAttribute Terminal::GetDefaultBrushColors() noexcept
{ {
@ -46,12 +52,12 @@ const TextAttribute Terminal::GetDefaultBrushColors() noexcept
const COLORREF Terminal::GetForegroundColor(const TextAttribute& attr) const noexcept const COLORREF Terminal::GetForegroundColor(const TextAttribute& attr) const noexcept
{ {
return 0xff000000 | attr.CalculateRgbForeground({ &_colorTable[0], _colorTable.size() }, _defaultFg, _defaultBg); return 0xff000000 | attr.CalculateRgbForeground({ _colorTable.data(), _colorTable.size() }, _defaultFg, _defaultBg);
} }
const COLORREF Terminal::GetBackgroundColor(const TextAttribute& attr) const noexcept const COLORREF Terminal::GetBackgroundColor(const TextAttribute& attr) const noexcept
{ {
const auto bgColor = attr.CalculateRgbBackground({ &_colorTable[0], _colorTable.size() }, _defaultFg, _defaultBg); const auto bgColor = attr.CalculateRgbBackground({ _colorTable.data(), _colorTable.size() }, _defaultFg, _defaultBg);
// We only care about alpha for the default BG (which enables acrylic) // We only care about alpha for the default BG (which enables acrylic)
// If the bg isn't the default bg color, then make it fully opaque. // If the bg isn't the default bg color, then make it fully opaque.
if (!attr.BackgroundIsDefault()) if (!attr.BackgroundIsDefault())
@ -115,6 +121,7 @@ const bool Terminal::IsGridLineDrawingAllowed() noexcept
} }
std::vector<Microsoft::Console::Types::Viewport> Terminal::GetSelectionRects() noexcept std::vector<Microsoft::Console::Types::Viewport> Terminal::GetSelectionRects() noexcept
try
{ {
std::vector<Viewport> result; std::vector<Viewport> result;
@ -125,11 +132,19 @@ std::vector<Microsoft::Console::Types::Viewport> Terminal::GetSelectionRects() n
return result; return result;
} }
catch (...)
{
LOG_CAUGHT_EXCEPTION();
return {};
}
void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd) void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
{ {
#pragma warning(push)
#pragma warning(disable : 26496) // cpp core checks wants these const, but they're decremented below.
COORD realCoordStart = coordStart; COORD realCoordStart = coordStart;
COORD realCoordEnd = coordEnd; COORD realCoordEnd = coordEnd;
#pragma warning(pop)
bool notifyScrollChange = false; bool notifyScrollChange = false;
if (coordStart.Y < _VisibleStartIndex()) if (coordStart.Y < _VisibleStartIndex())
@ -162,9 +177,15 @@ void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
} }
const std::wstring Terminal::GetConsoleTitle() const noexcept const std::wstring Terminal::GetConsoleTitle() const noexcept
try
{ {
return _title; return _title;
} }
catch (...)
{
LOG_CAUGHT_EXCEPTION();
return {};
}
// Method Description: // Method Description:
// - Lock the terminal for reading the contents of the buffer. Ensures that the // - Lock the terminal for reading the contents of the buffer. Ensures that the

View File

@ -8,7 +8,13 @@
namespace winrt::Microsoft::Terminal::Settings::implementation namespace winrt::Microsoft::Terminal::Settings::implementation
{ {
KeyChord::KeyChord(bool ctrl, bool alt, bool shift, int32_t vkey) : KeyChord::KeyChord() noexcept :
_modifiers{ 0 },
_vkey{ 0 }
{
}
KeyChord::KeyChord(bool ctrl, bool alt, bool shift, int32_t vkey) noexcept :
_modifiers{ (ctrl ? Settings::KeyModifiers::Ctrl : Settings::KeyModifiers::None) | _modifiers{ (ctrl ? Settings::KeyModifiers::Ctrl : Settings::KeyModifiers::None) |
(alt ? Settings::KeyModifiers::Alt : Settings::KeyModifiers::None) | (alt ? Settings::KeyModifiers::Alt : Settings::KeyModifiers::None) |
(shift ? Settings::KeyModifiers::Shift : Settings::KeyModifiers::None) }, (shift ? Settings::KeyModifiers::Shift : Settings::KeyModifiers::None) },
@ -16,28 +22,28 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
{ {
} }
KeyChord::KeyChord(Settings::KeyModifiers const& modifiers, int32_t vkey) : KeyChord::KeyChord(Settings::KeyModifiers const& modifiers, int32_t vkey) noexcept :
_modifiers{ modifiers }, _modifiers{ modifiers },
_vkey{ vkey } _vkey{ vkey }
{ {
} }
Settings::KeyModifiers KeyChord::Modifiers() Settings::KeyModifiers KeyChord::Modifiers() noexcept
{ {
return _modifiers; return _modifiers;
} }
void KeyChord::Modifiers(Settings::KeyModifiers const& value) void KeyChord::Modifiers(Settings::KeyModifiers const& value) noexcept
{ {
_modifiers = value; _modifiers = value;
} }
int32_t KeyChord::Vkey() int32_t KeyChord::Vkey() noexcept
{ {
return _vkey; return _vkey;
} }
void KeyChord::Vkey(int32_t value) void KeyChord::Vkey(int32_t value) noexcept
{ {
_vkey = value; _vkey = value;
} }

View File

@ -9,14 +9,14 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
{ {
struct KeyChord : KeyChordT<KeyChord> struct KeyChord : KeyChordT<KeyChord>
{ {
KeyChord() = default; KeyChord() noexcept;
KeyChord(Settings::KeyModifiers const& modifiers, int32_t vkey); KeyChord(Settings::KeyModifiers const& modifiers, int32_t vkey) noexcept;
KeyChord(bool ctrl, bool alt, bool shift, int32_t vkey); KeyChord(bool ctrl, bool alt, bool shift, int32_t vkey) noexcept;
Settings::KeyModifiers Modifiers(); Settings::KeyModifiers Modifiers() noexcept;
void Modifiers(Settings::KeyModifiers const& value); void Modifiers(Settings::KeyModifiers const& value) noexcept;
int32_t Vkey(); int32_t Vkey() noexcept;
void Vkey(int32_t value); void Vkey(int32_t value) noexcept;
private: private:
Settings::KeyModifiers _modifiers; Settings::KeyModifiers _modifiers;

View File

@ -9,6 +9,10 @@
namespace winrt::Microsoft::Terminal::Settings::implementation namespace winrt::Microsoft::Terminal::Settings::implementation
{ {
// Disable "default constructor may not throw."
// We put default values into the hstrings here, which allocates and could throw.
// Working around that situation is more headache than it's worth at the moment.
#pragma warning(suppress : 26455)
TerminalSettings::TerminalSettings() : TerminalSettings::TerminalSettings() :
_defaultForeground{ DEFAULT_FOREGROUND_WITH_ALPHA }, _defaultForeground{ DEFAULT_FOREGROUND_WITH_ALPHA },
_defaultBackground{ DEFAULT_BACKGROUND_WITH_ALPHA }, _defaultBackground{ DEFAULT_BACKGROUND_WITH_ALPHA },
@ -38,94 +42,94 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
{ {
} }
uint32_t TerminalSettings::DefaultForeground() uint32_t TerminalSettings::DefaultForeground() noexcept
{ {
return _defaultForeground; return _defaultForeground;
} }
void TerminalSettings::DefaultForeground(uint32_t value) void TerminalSettings::DefaultForeground(uint32_t value) noexcept
{ {
_defaultForeground = value; _defaultForeground = value;
} }
uint32_t TerminalSettings::DefaultBackground() uint32_t TerminalSettings::DefaultBackground() noexcept
{ {
return _defaultBackground; return _defaultBackground;
} }
void TerminalSettings::DefaultBackground(uint32_t value) void TerminalSettings::DefaultBackground(uint32_t value) noexcept
{ {
_defaultBackground = value; _defaultBackground = value;
} }
uint32_t TerminalSettings::SelectionBackground() uint32_t TerminalSettings::SelectionBackground() noexcept
{ {
return _selectionBackground; return _selectionBackground;
} }
void TerminalSettings::SelectionBackground(uint32_t value) void TerminalSettings::SelectionBackground(uint32_t value) noexcept
{ {
_selectionBackground = value; _selectionBackground = value;
} }
uint32_t TerminalSettings::GetColorTableEntry(int32_t index) const uint32_t TerminalSettings::GetColorTableEntry(int32_t index) const noexcept
{ {
return _colorTable[index]; return _colorTable.at(index);
} }
void TerminalSettings::SetColorTableEntry(int32_t index, uint32_t value) void TerminalSettings::SetColorTableEntry(int32_t index, uint32_t value)
{ {
auto const colorTableCount = gsl::narrow_cast<decltype(index)>(_colorTable.size()); auto const colorTableCount = gsl::narrow_cast<decltype(index)>(_colorTable.size());
THROW_HR_IF(E_INVALIDARG, index >= colorTableCount); THROW_HR_IF(E_INVALIDARG, index >= colorTableCount);
_colorTable[index] = value; _colorTable.at(index) = value;
} }
int32_t TerminalSettings::HistorySize() int32_t TerminalSettings::HistorySize() noexcept
{ {
return _historySize; return _historySize;
} }
void TerminalSettings::HistorySize(int32_t value) void TerminalSettings::HistorySize(int32_t value) noexcept
{ {
_historySize = value; _historySize = value;
} }
int32_t TerminalSettings::InitialRows() int32_t TerminalSettings::InitialRows() noexcept
{ {
return _initialRows; return _initialRows;
} }
void TerminalSettings::InitialRows(int32_t value) void TerminalSettings::InitialRows(int32_t value) noexcept
{ {
_initialRows = value; _initialRows = value;
} }
int32_t TerminalSettings::InitialCols() int32_t TerminalSettings::InitialCols() noexcept
{ {
return _initialCols; return _initialCols;
} }
void TerminalSettings::InitialCols(int32_t value) void TerminalSettings::InitialCols(int32_t value) noexcept
{ {
_initialCols = value; _initialCols = value;
} }
bool TerminalSettings::SnapOnInput() bool TerminalSettings::SnapOnInput() noexcept
{ {
return _snapOnInput; return _snapOnInput;
} }
void TerminalSettings::SnapOnInput(bool value) void TerminalSettings::SnapOnInput(bool value) noexcept
{ {
_snapOnInput = value; _snapOnInput = value;
} }
uint32_t TerminalSettings::CursorColor() uint32_t TerminalSettings::CursorColor() noexcept
{ {
return _cursorColor; return _cursorColor;
} }
void TerminalSettings::CursorColor(uint32_t value) void TerminalSettings::CursorColor(uint32_t value) noexcept
{ {
_cursorColor = value; _cursorColor = value;
} }
@ -140,12 +144,12 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_cursorShape = value; _cursorShape = value;
} }
uint32_t TerminalSettings::CursorHeight() uint32_t TerminalSettings::CursorHeight() noexcept
{ {
return _cursorHeight; return _cursorHeight;
} }
void TerminalSettings::CursorHeight(uint32_t value) void TerminalSettings::CursorHeight(uint32_t value) noexcept
{ {
_cursorHeight = value; _cursorHeight = value;
} }
@ -160,32 +164,32 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_wordDelimiters = value; _wordDelimiters = value;
} }
bool TerminalSettings::CopyOnSelect() bool TerminalSettings::CopyOnSelect() noexcept
{ {
return _copyOnSelect; return _copyOnSelect;
} }
void TerminalSettings::CopyOnSelect(bool value) void TerminalSettings::CopyOnSelect(bool value) noexcept
{ {
_copyOnSelect = value; _copyOnSelect = value;
} }
bool TerminalSettings::UseAcrylic() bool TerminalSettings::UseAcrylic() noexcept
{ {
return _useAcrylic; return _useAcrylic;
} }
void TerminalSettings::UseAcrylic(bool value) void TerminalSettings::UseAcrylic(bool value) noexcept
{ {
_useAcrylic = value; _useAcrylic = value;
} }
double TerminalSettings::TintOpacity() double TerminalSettings::TintOpacity() noexcept
{ {
return _tintOpacity; return _tintOpacity;
} }
void TerminalSettings::TintOpacity(double value) void TerminalSettings::TintOpacity(double value) noexcept
{ {
_tintOpacity = value; _tintOpacity = value;
} }
@ -210,12 +214,12 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_fontFace = value; _fontFace = value;
} }
int32_t TerminalSettings::FontSize() int32_t TerminalSettings::FontSize() noexcept
{ {
return _fontSize; return _fontSize;
} }
void TerminalSettings::FontSize(int32_t value) void TerminalSettings::FontSize(int32_t value) noexcept
{ {
_fontSize = value; _fontSize = value;
} }
@ -230,52 +234,52 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
return _backgroundImage; return _backgroundImage;
} }
void TerminalSettings::BackgroundImageOpacity(double value) void TerminalSettings::BackgroundImageOpacity(double value) noexcept
{ {
_backgroundImageOpacity = value; _backgroundImageOpacity = value;
} }
double TerminalSettings::BackgroundImageOpacity() double TerminalSettings::BackgroundImageOpacity() noexcept
{ {
return _backgroundImageOpacity; return _backgroundImageOpacity;
} }
winrt::Windows::UI::Xaml::Media::Stretch TerminalSettings::BackgroundImageStretchMode() winrt::Windows::UI::Xaml::Media::Stretch TerminalSettings::BackgroundImageStretchMode() noexcept
{ {
return _backgroundImageStretchMode; return _backgroundImageStretchMode;
} }
void TerminalSettings::BackgroundImageStretchMode(winrt::Windows::UI::Xaml::Media::Stretch value) void TerminalSettings::BackgroundImageStretchMode(winrt::Windows::UI::Xaml::Media::Stretch value) noexcept
{ {
_backgroundImageStretchMode = value; _backgroundImageStretchMode = value;
} }
winrt::Windows::UI::Xaml::HorizontalAlignment TerminalSettings::BackgroundImageHorizontalAlignment() winrt::Windows::UI::Xaml::HorizontalAlignment TerminalSettings::BackgroundImageHorizontalAlignment() noexcept
{ {
return _backgroundImageHorizontalAlignment; return _backgroundImageHorizontalAlignment;
} }
void TerminalSettings::BackgroundImageHorizontalAlignment(winrt::Windows::UI::Xaml::HorizontalAlignment value) void TerminalSettings::BackgroundImageHorizontalAlignment(winrt::Windows::UI::Xaml::HorizontalAlignment value) noexcept
{ {
_backgroundImageHorizontalAlignment = value; _backgroundImageHorizontalAlignment = value;
} }
winrt::Windows::UI::Xaml::VerticalAlignment TerminalSettings::BackgroundImageVerticalAlignment() winrt::Windows::UI::Xaml::VerticalAlignment TerminalSettings::BackgroundImageVerticalAlignment() noexcept
{ {
return _backgroundImageVerticalAlignment; return _backgroundImageVerticalAlignment;
} }
void TerminalSettings::BackgroundImageVerticalAlignment(winrt::Windows::UI::Xaml::VerticalAlignment value) void TerminalSettings::BackgroundImageVerticalAlignment(winrt::Windows::UI::Xaml::VerticalAlignment value) noexcept
{ {
_backgroundImageVerticalAlignment = value; _backgroundImageVerticalAlignment = value;
} }
Settings::IKeyBindings TerminalSettings::KeyBindings() Settings::IKeyBindings TerminalSettings::KeyBindings() noexcept
{ {
return _keyBindings; return _keyBindings;
} }
void TerminalSettings::KeyBindings(Settings::IKeyBindings const& value) void TerminalSettings::KeyBindings(Settings::IKeyBindings const& value) noexcept
{ {
_keyBindings = value; _keyBindings = value;
} }
@ -310,12 +314,12 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_startingTitle = value; _startingTitle = value;
} }
bool TerminalSettings::SuppressApplicationTitle() bool TerminalSettings::SuppressApplicationTitle() noexcept
{ {
return _suppressApplicationTitle; return _suppressApplicationTitle;
} }
void TerminalSettings::SuppressApplicationTitle(bool value) void TerminalSettings::SuppressApplicationTitle(bool value) noexcept
{ {
_suppressApplicationTitle = value; _suppressApplicationTitle = value;
} }
@ -340,12 +344,12 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_scrollbarState = value; _scrollbarState = value;
} }
bool TerminalSettings::RetroTerminalEffect() bool TerminalSettings::RetroTerminalEffect() noexcept
{ {
return _retroTerminalEffect; return _retroTerminalEffect;
} }
void TerminalSettings::RetroTerminalEffect(bool value) void TerminalSettings::RetroTerminalEffect(bool value) noexcept
{ {
_retroTerminalEffect = value; _retroTerminalEffect = value;
} }

View File

@ -25,59 +25,59 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
// --------------------------- Core Settings --------------------------- // --------------------------- Core Settings ---------------------------
// All of these settings are defined in ICoreSettings. // All of these settings are defined in ICoreSettings.
uint32_t DefaultForeground(); uint32_t DefaultForeground() noexcept;
void DefaultForeground(uint32_t value); void DefaultForeground(uint32_t value) noexcept;
uint32_t DefaultBackground(); uint32_t DefaultBackground() noexcept;
void DefaultBackground(uint32_t value); void DefaultBackground(uint32_t value) noexcept;
uint32_t SelectionBackground(); uint32_t SelectionBackground() noexcept;
void SelectionBackground(uint32_t value); void SelectionBackground(uint32_t value) noexcept;
uint32_t GetColorTableEntry(int32_t index) const; uint32_t GetColorTableEntry(int32_t index) const noexcept;
void SetColorTableEntry(int32_t index, uint32_t value); void SetColorTableEntry(int32_t index, uint32_t value);
int32_t HistorySize(); int32_t HistorySize() noexcept;
void HistorySize(int32_t value); void HistorySize(int32_t value) noexcept;
int32_t InitialRows(); int32_t InitialRows() noexcept;
void InitialRows(int32_t value); void InitialRows(int32_t value) noexcept;
int32_t InitialCols(); int32_t InitialCols() noexcept;
void InitialCols(int32_t value); void InitialCols(int32_t value) noexcept;
bool SnapOnInput(); bool SnapOnInput() noexcept;
void SnapOnInput(bool value); void SnapOnInput(bool value) noexcept;
uint32_t CursorColor(); uint32_t CursorColor() noexcept;
void CursorColor(uint32_t value); void CursorColor(uint32_t value) noexcept;
CursorStyle CursorShape() const noexcept; CursorStyle CursorShape() const noexcept;
void CursorShape(winrt::Microsoft::Terminal::Settings::CursorStyle const& value) noexcept; void CursorShape(winrt::Microsoft::Terminal::Settings::CursorStyle const& value) noexcept;
uint32_t CursorHeight(); uint32_t CursorHeight() noexcept;
void CursorHeight(uint32_t value); void CursorHeight(uint32_t value) noexcept;
hstring WordDelimiters(); hstring WordDelimiters();
void WordDelimiters(hstring const& value); void WordDelimiters(hstring const& value);
bool CopyOnSelect(); bool CopyOnSelect() noexcept;
void CopyOnSelect(bool value); void CopyOnSelect(bool value) noexcept;
// ------------------------ End of Core Settings ----------------------- // ------------------------ End of Core Settings -----------------------
bool UseAcrylic(); bool UseAcrylic() noexcept;
void UseAcrylic(bool value); void UseAcrylic(bool value) noexcept;
double TintOpacity(); double TintOpacity() noexcept;
void TintOpacity(double value); void TintOpacity(double value) noexcept;
hstring Padding(); hstring Padding();
void Padding(hstring value); void Padding(hstring value);
hstring FontFace(); hstring FontFace();
void FontFace(hstring const& value); void FontFace(hstring const& value);
int32_t FontSize(); int32_t FontSize() noexcept;
void FontSize(int32_t value); void FontSize(int32_t value) noexcept;
hstring BackgroundImage(); hstring BackgroundImage();
void BackgroundImage(hstring const& value); void BackgroundImage(hstring const& value);
double BackgroundImageOpacity(); double BackgroundImageOpacity() noexcept;
void BackgroundImageOpacity(double value); void BackgroundImageOpacity(double value) noexcept;
winrt::Windows::UI::Xaml::Media::Stretch BackgroundImageStretchMode(); winrt::Windows::UI::Xaml::Media::Stretch BackgroundImageStretchMode() noexcept;
void BackgroundImageStretchMode(winrt::Windows::UI::Xaml::Media::Stretch value); void BackgroundImageStretchMode(winrt::Windows::UI::Xaml::Media::Stretch value) noexcept;
winrt::Windows::UI::Xaml::HorizontalAlignment BackgroundImageHorizontalAlignment(); winrt::Windows::UI::Xaml::HorizontalAlignment BackgroundImageHorizontalAlignment() noexcept;
void BackgroundImageHorizontalAlignment(winrt::Windows::UI::Xaml::HorizontalAlignment value); void BackgroundImageHorizontalAlignment(winrt::Windows::UI::Xaml::HorizontalAlignment value) noexcept;
winrt::Windows::UI::Xaml::VerticalAlignment BackgroundImageVerticalAlignment(); winrt::Windows::UI::Xaml::VerticalAlignment BackgroundImageVerticalAlignment() noexcept;
void BackgroundImageVerticalAlignment(winrt::Windows::UI::Xaml::VerticalAlignment value); void BackgroundImageVerticalAlignment(winrt::Windows::UI::Xaml::VerticalAlignment value) noexcept;
winrt::Microsoft::Terminal::Settings::IKeyBindings KeyBindings(); winrt::Microsoft::Terminal::Settings::IKeyBindings KeyBindings() noexcept;
void KeyBindings(winrt::Microsoft::Terminal::Settings::IKeyBindings const& value); void KeyBindings(winrt::Microsoft::Terminal::Settings::IKeyBindings const& value) noexcept;
hstring Commandline(); hstring Commandline();
void Commandline(hstring const& value); void Commandline(hstring const& value);
@ -88,8 +88,8 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
hstring StartingTitle(); hstring StartingTitle();
void StartingTitle(hstring const& value); void StartingTitle(hstring const& value);
bool SuppressApplicationTitle(); bool SuppressApplicationTitle() noexcept;
void SuppressApplicationTitle(bool value); void SuppressApplicationTitle(bool value) noexcept;
hstring EnvironmentVariables(); hstring EnvironmentVariables();
void EnvironmentVariables(hstring const& value); void EnvironmentVariables(hstring const& value);
@ -97,8 +97,8 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
ScrollbarState ScrollState() const noexcept; ScrollbarState ScrollState() const noexcept;
void ScrollState(winrt::Microsoft::Terminal::Settings::ScrollbarState const& value) noexcept; void ScrollState(winrt::Microsoft::Terminal::Settings::ScrollbarState const& value) noexcept;
bool RetroTerminalEffect(); bool RetroTerminalEffect() noexcept;
void RetroTerminalEffect(bool value); void RetroTerminalEffect(bool value) noexcept;
private: private:
uint32_t _defaultForeground; uint32_t _defaultForeground;

View File

@ -59,7 +59,9 @@ namespace Microsoft::Console::Utils
#endif #endif
// Array-to-pointer decay might technically be avoidable, but this is elegant and clean.
#define UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(x) \ #define UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(x) \
__pragma(warning(suppress : 26485)); \
__declspec(selectany) extern const wchar_t* g_WinRTUtilsLibraryResourceScope{ (x) }; __declspec(selectany) extern const wchar_t* g_WinRTUtilsLibraryResourceScope{ (x) };
winrt::hstring GetLibraryResourceString(const std::wstring_view key); winrt::hstring GetLibraryResourceString(const std::wstring_view key);

View File

@ -66,7 +66,7 @@ private:
#define TYPED_EVENT(name, sender, args) \ #define TYPED_EVENT(name, sender, args) \
public: \ public: \
winrt::event_token name(winrt::Windows::Foundation::TypedEventHandler<sender, args> const& handler) { return _##name##Handlers.add(handler); } \ winrt::event_token name(winrt::Windows::Foundation::TypedEventHandler<sender, args> const& handler) { return _##name##Handlers.add(handler); } \
void name(winrt::event_token const& token) noexcept { _##name##Handlers.remove(token); } \ void name(winrt::event_token const& token) { _##name##Handlers.remove(token); } \
\ \
private: \ private: \
winrt::event<winrt::Windows::Foundation::TypedEventHandler<sender, args>> _##name##Handlers; winrt::event<winrt::Windows::Foundation::TypedEventHandler<sender, args>> _##name##Handlers;
@ -77,12 +77,12 @@ private:
// signatures and define them both for you, because they don't really vary from // signatures and define them both for you, because they don't really vary from
// event to event. // event to event.
// Use this in a class's header if you have a "delegate" type in your IDL. // Use this in a class's header if you have a "delegate" type in your IDL.
#define WINRT_CALLBACK(name, args) \ #define WINRT_CALLBACK(name, args) \
public: \ public: \
winrt::event_token name(args const& handler) { return _##name##Handlers.add(handler); } \ winrt::event_token name(args const& handler) { return _##name##Handlers.add(handler); } \
void name(winrt::event_token const& token) noexcept { _##name##Handlers.remove(token); } \ void name(winrt::event_token const& token) { _##name##Handlers.remove(token); } \
\ \
private: \ private: \
winrt::event<args> _##name##Handlers; winrt::event<args> _##name##Handlers;
// This is a helper macro for both declaring the signature and body of an event // This is a helper macro for both declaring the signature and body of an event

View File

@ -146,7 +146,9 @@
<CodeAnalysisRuleSet>$(SolutionDir)\src\StaticAnalysis.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>$(SolutionDir)\src\StaticAnalysis.ruleset</CodeAnalysisRuleSet>
<EnableCppCoreCheck>true</EnableCppCoreCheck> <EnableCppCoreCheck>true</EnableCppCoreCheck>
<RunCodeAnalysis>true</RunCodeAnalysis> <RunCodeAnalysis>true</RunCodeAnalysis>
<CAExcludePath>$(SolutionDir)\dep</CAExcludePath> <CAExcludePath>$(CAExcludePath);$(SolutionDir)\dep;$(SolutionDir)\packages</CAExcludePath>
<OpenConsoleVcpkgConfiguration>Release</OpenConsoleVcpkgConfiguration>
<OpenConsoleTppVcpkgConfiguration>Release</OpenConsoleTppVcpkgConfiguration>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='AuditMode'"> <ItemDefinitionGroup Condition="'$(Configuration)'=='AuditMode'">
<ClCompile> <ClCompile>

View File

@ -58,7 +58,7 @@ DeviceHandle::CreateServerHandle(
return _CreateHandle(Handle, return _CreateHandle(Handle,
L"\\Device\\ConDrv\\Server", L"\\Device\\ConDrv\\Server",
GENERIC_ALL, GENERIC_ALL,
NULL, nullptr,
Inheritable, Inheritable,
0); 0);
} }
@ -98,16 +98,18 @@ DeviceHandle::_CreateHandle(
} }
UNICODE_STRING Name; UNICODE_STRING Name;
Name.Buffer = (wchar_t*)DeviceName; #pragma warning(suppress : 26492) // const_cast is prohibited, but we can't avoid it for filling UNICODE_STRING.
Name.Length = (USHORT)(wcslen(DeviceName) * sizeof(wchar_t)); Name.Buffer = const_cast<wchar_t*>(DeviceName);
Name.Length = gsl::narrow_cast<USHORT>((wcslen(DeviceName) * sizeof(wchar_t)));
Name.MaximumLength = Name.Length + sizeof(wchar_t); Name.MaximumLength = Name.Length + sizeof(wchar_t);
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
#pragma warning(suppress : 26477) // The QOS part of this macro in the define is 0. Can't fix that.
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&Name, &Name,
Flags, Flags,
Parent, Parent,
NULL); nullptr);
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
return WinNTControl::NtOpenFile(Handle, return WinNTControl::NtOpenFile(Handle,

View File

@ -7,6 +7,8 @@
// Routine Description: // Routine Description:
// - Creates an instance of the NTDLL method-invoking class. // - Creates an instance of the NTDLL method-invoking class.
// - This class helps maintain a loose coupling on NTDLL without reliance on the driver kit headers/libs. // - This class helps maintain a loose coupling on NTDLL without reliance on the driver kit headers/libs.
#pragma warning(suppress : 26490) // reinterpret_cast is prohibited but it's way more steps to make it happy
#pragma warning(suppress : 26455) // Default constructors cannot throw, but passing the library in is clumsy.
WinNTControl::WinNTControl() : WinNTControl::WinNTControl() :
// NOTE: Use LoadLibraryExW with LOAD_LIBRARY_SEARCH_SYSTEM32 flag below to avoid unneeded directory traversal. // NOTE: Use LoadLibraryExW with LOAD_LIBRARY_SEARCH_SYSTEM32 flag below to avoid unneeded directory traversal.
// This has triggered CPG boot IO warnings in the past. // This has triggered CPG boot IO warnings in the past.
@ -15,12 +17,6 @@ WinNTControl::WinNTControl() :
{ {
} }
// Routine Description:
// - Destructs an instance of the NTDLL method-invoking class.
WinNTControl::~WinNTControl()
{
}
// Routine Description: // Routine Description:
// - Provides the singleton pattern for WinNT control. Stores the single instance and returns it. // - Provides the singleton pattern for WinNT control. Stores the single instance and returns it.
// Arguments: // Arguments:

View File

@ -26,8 +26,6 @@ public:
_In_ ULONG ShareAccess, _In_ ULONG ShareAccess,
_In_ ULONG OpenOptions); _In_ ULONG OpenOptions);
~WinNTControl();
private: private:
WinNTControl(); WinNTControl();

View File

@ -263,6 +263,9 @@ void AdaptDispatch::_SetGraphicsOptionHelper(const DispatchTypes::GraphicsOption
} }
} }
#pragma warning(push)
#pragma warning(disable : 26497) // we do not want constexpr compilation because these always evaluate at runtime
// Routine Description: // Routine Description:
// Returns true if the GraphicsOption represents an extended text attribute. // Returns true if the GraphicsOption represents an extended text attribute.
// These include things such as Underlined, Italics, Blinking, etc. // These include things such as Underlined, Italics, Blinking, etc.
@ -321,6 +324,8 @@ static constexpr bool _isDefaultColorOption(const DispatchTypes::GraphicsOptions
opt == DispatchTypes::GraphicsOptions::BackgroundDefault; opt == DispatchTypes::GraphicsOptions::BackgroundDefault;
} }
#pragma warning(pop)
// Routine Description: // Routine Description:
// - Helper to parse extended graphics options, which start with 38 (FG) or 48 (BG) // - Helper to parse extended graphics options, which start with 38 (FG) or 48 (BG)
// These options are followed by either a 2 (RGB) or 5 (xterm index) // These options are followed by either a 2 (RGB) or 5 (xterm index)

View File

@ -1324,6 +1324,9 @@ bool OutputStateMachineEngine::s_HexToUint(const wchar_t wch,
return success; return success;
} }
#pragma warning(push)
#pragma warning(disable : 26497) // We don't use any of these "constexprable" functions in that fashion
// Routine Description: // Routine Description:
// - Determines if a character is a valid number character, 0-9. // - Determines if a character is a valid number character, 0-9.
// Arguments: // Arguments:
@ -1348,6 +1351,8 @@ static constexpr bool _isHexNumber(const wchar_t wch) noexcept
(wch >= L'a' && wch <= L'f'); (wch >= L'a' && wch <= L'f');
} }
#pragma warning(pop)
// Routine Description: // Routine Description:
// - Given a color spec string, attempts to parse the color that's encoded. // - Given a color spec string, attempts to parse the color that's encoded.
// The only supported spec currently is the following: // The only supported spec currently is the following:

View File

@ -43,6 +43,9 @@ static constexpr bool _isNumber(const wchar_t wch) noexcept
return wch >= L'0' && wch <= L'9'; // 0x30 - 0x39 return wch >= L'0' && wch <= L'9'; // 0x30 - 0x39
} }
#pragma warning(push)
#pragma warning(disable : 26497) // We don't use any of these "constexprable" functions in that fashion
// Routine Description: // Routine Description:
// - Determines if a character belongs to the C0 escape range. // - Determines if a character belongs to the C0 escape range.
// This is character sequences less than a space character (null, backspace, new line, etc.) // This is character sequences less than a space character (null, backspace, new line, etc.)
@ -279,6 +282,8 @@ static constexpr bool _isActionableFromGround(const wchar_t wch) noexcept
return (wch <= AsciiChars::US) || _isC1Csi(wch) || _isDelete(wch); return (wch <= AsciiChars::US) || _isC1Csi(wch) || _isDelete(wch);
} }
#pragma warning(pop)
// Routine Description: // Routine Description:
// - Triggers the Execute action to indicate that the listener should immediately respond to a C0 control character. // - Triggers the Execute action to indicate that the listener should immediately respond to a C0 control character.
// Arguments: // Arguments:

View File

@ -20,6 +20,7 @@
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4273) // inconsistent dll linkage (we are exporting things kernel32 also exports) #pragma warning(disable : 4273) // inconsistent dll linkage (we are exporting things kernel32 also exports)
#pragma warning(disable : 26485) // array-to-pointer decay is virtually impossible to avoid when we can't use STL.
// Function Description: // Function Description:
// - Returns the path to either conhost.exe or the side-by-side OpenConsole, depending on whether this // - Returns the path to either conhost.exe or the side-by-side OpenConsole, depending on whether this
@ -57,7 +58,7 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
const DWORD dwFlags, const DWORD dwFlags,
_Inout_ PseudoConsole* pPty) _Inout_ PseudoConsole* pPty)
{ {
if (pPty == NULL) if (pPty == nullptr)
{ {
return E_INVALIDARG; return E_INVALIDARG;
} }
@ -76,14 +77,14 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
sa.nLength = sizeof(sa); sa.nLength = sizeof(sa);
// Mark inheritable for signal handle when creating. It'll have the same value on the other side. // Mark inheritable for signal handle when creating. It'll have the same value on the other side.
sa.bInheritHandle = FALSE; sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = NULL; sa.lpSecurityDescriptor = nullptr;
RETURN_IF_WIN32_BOOL_FALSE(CreatePipe(signalPipeConhostSide.addressof(), signalPipeOurSide.addressof(), &sa, 0)); RETURN_IF_WIN32_BOOL_FALSE(CreatePipe(signalPipeConhostSide.addressof(), signalPipeOurSide.addressof(), &sa, 0));
RETURN_IF_WIN32_BOOL_FALSE(SetHandleInformation(signalPipeConhostSide.get(), HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)); RETURN_IF_WIN32_BOOL_FALSE(SetHandleInformation(signalPipeConhostSide.get(), HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT));
const wchar_t* pwszFormat = L"%s --headless %s--width %hu --height %hu --signal 0x%x --server 0x%x"; const wchar_t* pwszFormat = L"%s --headless %s--width %hu --height %hu --signal 0x%x --server 0x%x";
// This is plenty of space to hold the formatted string // This is plenty of space to hold the formatted string
wchar_t cmd[MAX_PATH]; wchar_t cmd[MAX_PATH]{};
const BOOL bInheritCursor = (dwFlags & PSEUDOCONSOLE_INHERIT_CURSOR) == PSEUDOCONSOLE_INHERIT_CURSOR; const BOOL bInheritCursor = (dwFlags & PSEUDOCONSOLE_INHERIT_CURSOR) == PSEUDOCONSOLE_INHERIT_CURSOR;
swprintf_s(cmd, swprintf_s(cmd,
MAX_PATH, MAX_PATH,
@ -112,19 +113,19 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
// Get the size of the attribute list. We need one attribute, the handle list. // Get the size of the attribute list. We need one attribute, the handle list.
SIZE_T listSize = 0; SIZE_T listSize = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &listSize); InitializeProcThreadAttributeList(nullptr, 1, 0, &listSize);
// I have to use a HeapAlloc here because kernelbase can't link new[] or delete[] // I have to use a HeapAlloc here because kernelbase can't link new[] or delete[]
PPROC_THREAD_ATTRIBUTE_LIST attrList = reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, listSize)); PPROC_THREAD_ATTRIBUTE_LIST attrList = static_cast<PPROC_THREAD_ATTRIBUTE_LIST>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, listSize));
RETURN_IF_NULL_ALLOC(attrList); RETURN_IF_NULL_ALLOC(attrList);
auto attrListDelete = wil::scope_exit([&] { auto attrListDelete = wil::scope_exit([&]() noexcept {
HeapFree(GetProcessHeap(), 0, attrList); HeapFree(GetProcessHeap(), 0, attrList);
}); });
siEx.lpAttributeList = attrList; siEx.lpAttributeList = attrList;
RETURN_IF_WIN32_BOOL_FALSE(InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, &listSize)); RETURN_IF_WIN32_BOOL_FALSE(InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, &listSize));
// Set cleanup data for ProcThreadAttributeList when successful. // Set cleanup data for ProcThreadAttributeList when successful.
auto cleanupProcThreadAttribute = wil::scope_exit([&] { auto cleanupProcThreadAttribute = wil::scope_exit([&]() noexcept {
DeleteProcThreadAttributeList(siEx.lpAttributeList); DeleteProcThreadAttributeList(siEx.lpAttributeList);
}); });
RETURN_IF_WIN32_BOOL_FALSE(UpdateProcThreadAttribute(siEx.lpAttributeList, RETURN_IF_WIN32_BOOL_FALSE(UpdateProcThreadAttribute(siEx.lpAttributeList,
@ -132,8 +133,8 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
PROC_THREAD_ATTRIBUTE_HANDLE_LIST, PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
inheritedHandles, inheritedHandles,
(INHERITED_HANDLES_COUNT * sizeof(HANDLE)), (INHERITED_HANDLES_COUNT * sizeof(HANDLE)),
NULL, nullptr,
NULL)); nullptr));
wil::unique_process_information pi; wil::unique_process_information pi;
{ // wow64 disabled filesystem redirection scope { // wow64 disabled filesystem redirection scope
#if defined(BUILD_WOW6432) #if defined(BUILD_WOW6432)
@ -145,17 +146,17 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
RtlWow64EnableFsRedirectionEx(RedirectionFlag, &RedirectionFlag); RtlWow64EnableFsRedirectionEx(RedirectionFlag, &RedirectionFlag);
}); });
#endif #endif
if (hToken == INVALID_HANDLE_VALUE || hToken == NULL) if (hToken == INVALID_HANDLE_VALUE || hToken == nullptr)
{ {
// Call create process // Call create process
RETURN_IF_WIN32_BOOL_FALSE(CreateProcessW(NULL, RETURN_IF_WIN32_BOOL_FALSE(CreateProcessW(nullptr,
cmd, cmd,
NULL, nullptr,
NULL, nullptr,
TRUE, TRUE,
EXTENDED_STARTUPINFO_PRESENT, EXTENDED_STARTUPINFO_PRESENT,
NULL, nullptr,
NULL, nullptr,
&siEx.StartupInfo, &siEx.StartupInfo,
pi.addressof())); pi.addressof()));
} }
@ -163,14 +164,14 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
{ {
// Call create process // Call create process
RETURN_IF_WIN32_BOOL_FALSE(CreateProcessAsUserW(hToken, RETURN_IF_WIN32_BOOL_FALSE(CreateProcessAsUserW(hToken,
NULL, nullptr,
cmd, cmd,
NULL, nullptr,
NULL, nullptr,
TRUE, TRUE,
EXTENDED_STARTUPINFO_PRESENT, EXTENDED_STARTUPINFO_PRESENT,
NULL, nullptr,
NULL, nullptr,
&siEx.StartupInfo, &siEx.StartupInfo,
pi.addressof())); pi.addressof()));
} }
@ -178,7 +179,7 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
// Move the process handle out of the PROCESS_INFORMATION into out Pseudoconsole // Move the process handle out of the PROCESS_INFORMATION into out Pseudoconsole
pPty->hConPtyProcess = pi.hProcess; pPty->hConPtyProcess = pi.hProcess;
pi.hProcess = NULL; pi.hProcess = nullptr;
RETURN_IF_NTSTATUS_FAILED(CreateClientHandle(&pPty->hPtyReference, RETURN_IF_NTSTATUS_FAILED(CreateClientHandle(&pPty->hPtyReference,
serverHandle.get(), serverHandle.get(),
@ -200,7 +201,7 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
// write the resize message to the pty. // write the resize message to the pty.
HRESULT _ResizePseudoConsole(_In_ const PseudoConsole* const pPty, _In_ const COORD size) HRESULT _ResizePseudoConsole(_In_ const PseudoConsole* const pPty, _In_ const COORD size)
{ {
if (pPty == NULL || size.X < 0 || size.Y < 0) if (pPty == nullptr || size.X < 0 || size.Y < 0)
{ {
return E_INVALIDARG; return E_INVALIDARG;
} }
@ -210,7 +211,7 @@ HRESULT _ResizePseudoConsole(_In_ const PseudoConsole* const pPty, _In_ const CO
signalPacket[1] = size.X; signalPacket[1] = size.X;
signalPacket[2] = size.Y; signalPacket[2] = size.Y;
BOOL fSuccess = WriteFile(pPty->hSignal, signalPacket, sizeof(signalPacket), NULL, NULL); const BOOL fSuccess = WriteFile(pPty->hSignal, signalPacket, sizeof(signalPacket), nullptr, nullptr);
return fSuccess ? S_OK : HRESULT_FROM_WIN32(GetLastError()); return fSuccess ? S_OK : HRESULT_FROM_WIN32(GetLastError());
} }
@ -225,14 +226,14 @@ HRESULT _ResizePseudoConsole(_In_ const PseudoConsole* const pPty, _In_ const CO
// - <none> // - <none>
void _ClosePseudoConsoleMembers(_In_ PseudoConsole* pPty) void _ClosePseudoConsoleMembers(_In_ PseudoConsole* pPty)
{ {
if (pPty != NULL) if (pPty != nullptr)
{ {
// See MSFT:19918626 // See MSFT:19918626
// First break the signal pipe - this will trigger conhost to tear itself down // First break the signal pipe - this will trigger conhost to tear itself down
if (_HandleIsValid(pPty->hSignal)) if (_HandleIsValid(pPty->hSignal))
{ {
CloseHandle(pPty->hSignal); CloseHandle(pPty->hSignal);
pPty->hSignal = 0; pPty->hSignal = nullptr;
} }
// Then, wait on the conhost process before killing it. // Then, wait on the conhost process before killing it.
// We do this to make sure the conhost finishes flushing any output it // We do this to make sure the conhost finishes flushing any output it
@ -252,7 +253,7 @@ void _ClosePseudoConsoleMembers(_In_ PseudoConsole* pPty)
} }
TerminateProcess(pPty->hConPtyProcess, 0); TerminateProcess(pPty->hConPtyProcess, 0);
pPty->hConPtyProcess = 0; pPty->hConPtyProcess = nullptr;
} }
// Then take care of the reference handle. // Then take care of the reference handle.
// TODO GH#1810: Closing the reference handle late leaves conhost thinking // TODO GH#1810: Closing the reference handle late leaves conhost thinking
@ -260,7 +261,7 @@ void _ClosePseudoConsoleMembers(_In_ PseudoConsole* pPty)
if (_HandleIsValid(pPty->hPtyReference)) if (_HandleIsValid(pPty->hPtyReference))
{ {
CloseHandle(pPty->hPtyReference); CloseHandle(pPty->hPtyReference);
pPty->hPtyReference = 0; pPty->hPtyReference = nullptr;
} }
} }
} }
@ -275,7 +276,7 @@ void _ClosePseudoConsoleMembers(_In_ PseudoConsole* pPty)
// - <none> // - <none>
VOID _ClosePseudoConsole(_In_ PseudoConsole* pPty) VOID _ClosePseudoConsole(_In_ PseudoConsole* pPty)
{ {
if (pPty != NULL) if (pPty != nullptr)
{ {
_ClosePseudoConsoleMembers(pPty); _ClosePseudoConsoleMembers(pPty);
HeapFree(GetProcessHeap(), 0, pPty); HeapFree(GetProcessHeap(), 0, pPty);
@ -325,11 +326,11 @@ extern "C" HRESULT ConptyCreatePseudoConsoleAsUser(_In_ HANDLE hToken,
_In_ DWORD dwFlags, _In_ DWORD dwFlags,
_Out_ HPCON* phPC) _Out_ HPCON* phPC)
{ {
if (phPC == NULL) if (phPC == nullptr)
{ {
return E_INVALIDARG; return E_INVALIDARG;
} }
*phPC = NULL; *phPC = nullptr;
if ((!_HandleIsValid(hInput)) && (!_HandleIsValid(hOutput))) if ((!_HandleIsValid(hInput)) && (!_HandleIsValid(hOutput)))
{ {
return E_INVALIDARG; return E_INVALIDARG;
@ -337,7 +338,7 @@ extern "C" HRESULT ConptyCreatePseudoConsoleAsUser(_In_ HANDLE hToken,
PseudoConsole* pPty = (PseudoConsole*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PseudoConsole)); PseudoConsole* pPty = (PseudoConsole*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PseudoConsole));
RETURN_IF_NULL_ALLOC(pPty); RETURN_IF_NULL_ALLOC(pPty);
auto cleanupPty = wil::scope_exit([&] { auto cleanupPty = wil::scope_exit([&]() noexcept {
_ClosePseudoConsole(pPty); _ClosePseudoConsole(pPty);
}); });
@ -358,8 +359,8 @@ extern "C" HRESULT ConptyCreatePseudoConsoleAsUser(_In_ HANDLE hToken,
// Resizes the given conpty to the specified size, in characters. // Resizes the given conpty to the specified size, in characters.
extern "C" HRESULT WINAPI ConptyResizePseudoConsole(_In_ HPCON hPC, _In_ COORD size) extern "C" HRESULT WINAPI ConptyResizePseudoConsole(_In_ HPCON hPC, _In_ COORD size)
{ {
PseudoConsole* const pPty = (PseudoConsole*)hPC; const PseudoConsole* const pPty = (PseudoConsole*)hPC;
HRESULT hr = pPty == NULL ? E_INVALIDARG : S_OK; HRESULT hr = pPty == nullptr ? E_INVALIDARG : S_OK;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = _ResizePseudoConsole(pPty, size); hr = _ResizePseudoConsole(pPty, size);
@ -376,7 +377,7 @@ extern "C" HRESULT WINAPI ConptyResizePseudoConsole(_In_ HPCON hPC, _In_ COORD s
extern "C" VOID WINAPI ConptyClosePseudoConsole(_In_ HPCON hPC) extern "C" VOID WINAPI ConptyClosePseudoConsole(_In_ HPCON hPC)
{ {
PseudoConsole* const pPty = (PseudoConsole*)hPC; PseudoConsole* const pPty = (PseudoConsole*)hPC;
if (pPty != NULL) if (pPty != nullptr)
{ {
_ClosePseudoConsole(pPty); _ClosePseudoConsole(pPty);
} }