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
{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|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}.Debug|Any CPU.ActiveCfg = Debug|Win32
{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-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|x64.ActiveCfg = Release|x64
{CA5CAD1A-ABCD-429C-B551-8562EC954746}.AuditMode|x64.Build.0 = Release|x64
{CA5CAD1A-ABCD-429C-B551-8562EC954746}.AuditMode|x64.ActiveCfg = AuditMode|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}.Debug|Any CPU.ActiveCfg = Debug|Win32
{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-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|x64.ActiveCfg = Release|x64
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x64.Build.0 = Release|x64
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x64.ActiveCfg = AuditMode|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}.Debug|Any CPU.ActiveCfg = Debug|Win32
{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|ARM64.ActiveCfg = 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.Build.0 = AuditMode|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.
// Return Value:
// - 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);
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
{
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);
while (&newTopRow != &_storage.front())
{

View File

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

View File

@ -3,6 +3,4 @@
#pragma once
#include <cpprest/details/web_utilities.h>
const utility::string_t AzureClientID = U("0");
static constexpr std::wstring_view AzureClientID = L"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
// 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
bool AzureConnection::IsAzureConnectionAvailable()
bool AzureConnection::IsAzureConnectionAvailable() noexcept
{
return (AzureClientID != L"0");
}
AzureConnection::AzureConnection(const uint32_t initialRows, const uint32_t initialCols) :
_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);
msg.set_utf8_message(str);
_cloudShellSocket.send(msg);
_cloudShellSocket.send(msg).get();
}
default:
return;
@ -217,7 +220,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
terminalRequest.set_body(json::value(L""));
// 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
DWORD WINAPI AzureConnection::StaticOutputThreadProc(LPVOID lpParameter)
{
AzureConnection* const pInstance = (AzureConnection*)lpParameter;
return pInstance->_OutputThread();
AzureConnection* const pInstance = static_cast<AzureConnection*>(lpParameter);
if (pInstance)
{
return pInstance->_OutputThread();
}
return gsl::narrow_cast<DWORD>(E_INVALIDARG);
}
// Method description:
@ -703,7 +710,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
http_request commonRequest(L"POST");
commonRequest.set_request_uri(L"common/oauth2/devicecode");
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
return _RequestHelper(loginClient, commonRequest);
@ -724,7 +731,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
http_client pollingClient(_loginUri);
// 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";
json::value responseJson;
for (int count = 0; count < expiresIn / pollInterval; count++)
@ -736,7 +743,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
}
http_request pollRequest(L"POST");
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);
@ -789,7 +796,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
http_request refreshRequest(L"POST");
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;
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);
// 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>
{
static bool IsAzureConnectionAvailable();
static bool IsAzureConnectionAvailable() noexcept;
AzureConnection(const uint32_t rows, const uint32_t cols);
void Start();

View File

@ -13,6 +13,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
TYPED_EVENT(StateChanged, ITerminalConnection, winrt::Windows::Foundation::IInspectable);
protected:
#pragma warning(push)
#pragma warning(disable : 26447) // Analyzer is still upset about noexcepts throwing even with function level try.
// Method Description:
// - Attempt to transition to and signal the specified connection 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:
// Whether we've successfully transitioned to the new state.
bool _transitionToState(const ConnectionState state) noexcept
try
{
{
std::lock_guard<std::mutex> stateLock{ _stateMutex };
@ -32,9 +35,11 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
_connectionState = state;
}
// 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);
return true;
}
CATCH_FAIL_FAST()
// Method Description:
// - Returns whether the state is one of the N specified states.
@ -43,7 +48,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// Return Value:
// Whether we're in one of the states.
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:
// (... OP (expression_using_args))
@ -56,6 +62,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
std::lock_guard<std::mutex> stateLock{ _stateMutex };
return (... || (_connectionState == args));
}
CATCH_FAIL_FAST()
// Method Description:
// - Returns whether the state has reached or surpassed the specified state.
@ -64,10 +71,13 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// Return Value:
// Whether we're at or beyond the specified state
bool _isStateAtOrBeyond(const ConnectionState state) const noexcept
try
{
std::lock_guard<std::mutex> stateLock{ _stateMutex };
return _connectionState >= state;
}
CATCH_FAIL_FAST()
#pragma warning(pop)
// Method Description:
// - (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.
// - 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
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);
wil::unique_hfile outPipeOurSide, outPipePseudoConsoleSide;
wil::unique_hfile inPipeOurSide, inPipePseudoConsoleSide;
RETURN_IF_WIN32_BOOL_FALSE(CreatePipe(&inPipePseudoConsoleSide, &inPipeOurSide, NULL, 0));
RETURN_IF_WIN32_BOOL_FALSE(CreatePipe(&outPipeOurSide, &outPipePseudoConsoleSide, NULL, 0));
RETURN_IF_WIN32_BOOL_FALSE(CreatePipe(&inPipePseudoConsoleSide, &inPipeOurSide, nullptr, 0));
RETURN_IF_WIN32_BOOL_FALSE(CreatePipe(&outPipeOurSide, &outPipePseudoConsoleSide, nullptr, 0));
RETURN_IF_FAILED(ConptyCreatePseudoConsole(size, inPipePseudoConsoleSide.get(), outPipePseudoConsoleSide.get(), dwFlags, phPC));
*phInput = inPipeOurSide.release();
*phOutput = outPipeOurSide.release();
@ -62,25 +63,27 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// Function Description:
// - launches the client application attached to the new pseudoconsole
HRESULT ConptyConnection::_LaunchAttachedClient() noexcept
try
{
STARTUPINFOEX siEx{ 0 };
siEx.StartupInfo.cb = sizeof(STARTUPINFOEX);
siEx.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
size_t size{};
SIZE_T size{};
// 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) };
#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());
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,
0,
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
_hPC.get(),
sizeof(HPCON),
NULL,
NULL));
nullptr,
nullptr));
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) };
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.
environment.emplace(L"WT_SESSION", pwszGuid);
environment.emplace(L"WT_SESSION", guidSubStr.data());
}
std::vector<wchar_t> newEnvVars;
auto zeroNewEnv = wil::scope_exit([&] {
auto zeroNewEnv = wil::scope_exit([&]() noexcept {
::SecureZeroMemory(newEnvVars.data(),
newEnvVars.size() * sizeof(decltype(newEnvVars.begin())::value_type));
});
@ -146,6 +149,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
return S_OK;
}
CATCH_RETURN();
ConptyConnection::ConptyConnection(const hstring& commandline,
const hstring& startingDirectory,
@ -186,9 +190,13 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
_hOutputThread.reset(CreateThread(
nullptr,
0,
[](LPVOID lpParameter) {
ConptyConnection* const pInstance = reinterpret_cast<ConptyConnection*>(lpParameter);
return pInstance->_OutputThread();
[](LPVOID lpParameter) noexcept {
ConptyConnection* const pInstance = static_cast<ConptyConnection*>(lpParameter);
if (pInstance)
{
return pInstance->_OutputThread();
}
return gsl::narrow_cast<DWORD>(E_INVALIDARG);
},
this,
0,
@ -197,9 +205,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
THROW_LAST_ERROR_IF_NULL(_hOutputThread);
_clientExitWait.reset(CreateThreadpoolWait(
[](PTP_CALLBACK_INSTANCE /*callbackInstance*/, PVOID context, PTP_WAIT /*wait*/, TP_WAIT_RESULT /*waitResult*/) {
ConptyConnection* const pInstance = reinterpret_cast<ConptyConnection*>(context);
pInstance->_ClientTerminated();
[](PTP_CALLBACK_INSTANCE /*callbackInstance*/, PVOID context, PTP_WAIT /*wait*/, TP_WAIT_RESULT /*waitResult*/) noexcept {
ConptyConnection* const pInstance = static_cast<ConptyConnection*>(context);
if (pInstance)
{
pInstance->_ClientTerminated();
}
},
this,
nullptr));
@ -213,7 +224,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// EXIT POINT
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);
_transitionToState(ConnectionState::Failed);
@ -229,7 +240,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
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(exitText);
}
@ -293,7 +304,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
}
}
void ConptyConnection::Close()
void ConptyConnection::Close() noexcept
{
if (_transitionToState(ConnectionState::Closing))
{
@ -332,7 +343,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// process the data of the output pipe in a loop
while (true)
{
HRESULT result = pipeReader.Read(strView);
const HRESULT result = pipeReader.Read(strView);
if (FAILED(result) || result == S_FALSE)
{
if (_isStateAtOrBeyond(ConnectionState::Closing))
@ -344,7 +355,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// EXIT POINT
_indicateExitWithStatus(result); // print a message
_transitionToState(ConnectionState::Failed);
return (DWORD)-1;
return gsl::narrow_cast<DWORD>(-1);
}
if (strView.empty())
@ -354,9 +365,10 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
if (!_recievedFirstByte)
{
auto now = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> delta = now - _startTime;
const auto now = std::chrono::high_resolution_clock::now();
const std::chrono::duration<double> delta = now - _startTime;
#pragma warning(suppress : 26477 26485 26494 26482 26446) // We don't control TraceLoggingWrite
TraceLoggingWrite(g_hTerminalConnectionProvider,
"RecievedFirstByte",
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 WriteInput(hstring const& data);
void Resize(uint32_t rows, uint32_t columns);
void Close();
void Close() noexcept;
winrt::guid Guid() const noexcept;

View File

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

View File

@ -19,7 +19,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
TelnetConnection::TelnetConnection(const hstring& uri) :
_reader{ nullptr },
_writer{ nullptr },
_uri{ uri }
_uri{ uri },
_receiveBuffer{}
{
_session.install(_nawsServer);
_nawsServer.activate([](auto&&) {});
@ -37,8 +38,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
nullptr,
0,
[](LPVOID lpParameter) {
auto pInstance = reinterpret_cast<TelnetConnection*>(lpParameter);
return pInstance->_outputThread();
auto pInstance = static_cast<TelnetConnection*>(lpParameter);
if (pInstance)
{
return pInstance->_outputThread();
}
return gsl::narrow_cast<DWORD>(ERROR_BAD_ARGUMENTS);
},
this,
0,
@ -75,6 +80,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
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());
_session.send(bytes, [=](telnetpp::bytes data) {
_socketSend(data);
@ -238,8 +244,16 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// - <none>
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* last = data.data() + data.size();
#pragma warning(pop)
const winrt::array_view<const uint8_t> arrayView(first, last);
_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.
// The WinRT team isn't fixing this because std::span is coming
// 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 last = first + bytesLoaded;
#pragma warning(pop)
const winrt::array_view<uint8_t> arrayView(first, last);
_reader.ReadBytes(arrayView);
return bytesLoaded;
@ -304,6 +321,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
std::function<void(telnetpp::bytes)> const& /*send*/)
{
// 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()) };
// Convert to hstring

View File

@ -5,6 +5,7 @@
#include <LibraryResources.h>
// 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(
g_hTerminalConnectionProvider,
"Microsoft.Windows.Terminal.Connection",
@ -12,6 +13,7 @@ TRACELOGGING_DEFINE_PROVIDER(
(0xe912fe7b, 0xeeb6, 0x52a5, 0xc6, 0x28, 0xab, 0xe3, 0x88, 0xe5, 0xf7, 0x92),
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*/)
{
switch (reason)

View File

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

View File

@ -22,21 +22,22 @@ using namespace Microsoft::Console::VirtualTerminal;
static std::wstring _KeyEventsToText(std::deque<std::unique_ptr<IInputEvent>>& inEventsToWrite)
{
std::wstring wstr = L"";
for (auto& ev : inEventsToWrite)
for (const auto& ev : inEventsToWrite)
{
if (ev->EventType() == InputEventType::KeyEvent)
{
auto& k = static_cast<KeyEvent&>(*ev);
auto wch = k.GetCharData();
const auto& k = static_cast<KeyEvent&>(*ev);
const auto wch = k.GetCharData();
wstr += wch;
}
}
return wstr;
}
#pragma warning(suppress : 26455) // default constructor is throwing, too much effort to rearrange at this time.
Terminal::Terminal() :
_mutableViewport{ Viewport::Empty() },
_title{ L"" },
_title{},
_colorTable{},
_defaultFg{ RGB(255, 255, 255) },
_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++)
{
_colorTable[i] = settings.GetColorTableEntry(i);
_colorTable.at(i) = settings.GetColorTableEntry(i);
}
_snapOnInput = settings.SnapOnInput();
@ -310,32 +311,37 @@ WORD Terminal::_ScanCodeFromVirtualKey(const WORD vkey) noexcept
// Return Value:
// - 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
try
{
const auto sc = scanCode != 0 ? scanCode : _ScanCodeFromVirtualKey(vkey);
// 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.
BYTE keyState[256] = {};
keyState[VK_SHIFT] = states.IsShiftPressed() ? 0x80 : 0;
keyState[VK_CONTROL] = states.IsCtrlPressed() ? 0x80 : 0;
keyState[VK_MENU] = states.IsAltPressed() ? 0x80 : 0;
std::array<BYTE, 256> keyState = {};
keyState.at(VK_SHIFT) = states.IsShiftPressed() ? 0x80 : 0;
keyState.at(VK_CONTROL) = states.IsCtrlPressed() ? 0x80 : 0;
keyState.at(VK_MENU) = states.IsAltPressed() ? 0x80 : 0;
// For the following use of ToUnicodeEx() please look here:
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-tounicodeex
// 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.
constexpr size_t bufferSize = 2;
wchar_t buffer[bufferSize];
std::array<wchar_t, 2> buffer;
// wFlags:
// * 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 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.
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:
@ -416,7 +422,7 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
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();
COORD proposedCursorPosition = cursorPosBefore;
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.
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 cellDistance = end.GetCellDistance(it);
i += cellDistance - 1;
@ -460,7 +466,7 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
}
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 cellDistance = end.GetCellDistance(it);
proposedCursorPosition.X += gsl::narrow<SHORT>(cellDistance);
@ -517,12 +523,13 @@ void Terminal::UserScrollViewport(const int viewTop)
_buffer->GetRenderTarget().TriggerRedrawAll();
}
int Terminal::GetScrollOffset()
int Terminal::GetScrollOffset() noexcept
{
return _VisibleStartIndex();
}
void Terminal::_NotifyScrollEvent()
void Terminal::_NotifyScrollEvent() noexcept
try
{
if (_pfnScrollPositionChanged)
{
@ -533,20 +540,21 @@ void Terminal::_NotifyScrollEvent()
_pfnScrollPositionChanged(top, height, bottom);
}
}
CATCH_LOG()
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
{
_pfnTitleChanged = pfn;
_pfnTitleChanged.swap(pfn);
}
void Terminal::SetScrollPositionChangedCallback(std::function<void(const int, const int, const int)> pfn) noexcept
{
_pfnScrollPositionChanged = pfn;
_pfnScrollPositionChanged.swap(pfn);
}
// 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
void Terminal::SetBackgroundCallback(std::function<void(const uint32_t)> pfn) noexcept
{
_pfnBackgroundColorChanged = pfn;
_pfnBackgroundColorChanged.swap(pfn);
}
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
Utils::Initialize256ColorTable(tableView);
// 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
Utils::SetColorTableAlpha(tableView, 0xff);
}
CATCH_LOG()
// Method Description:
// - Sets the visibility of the text cursor.

View File

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

View File

@ -10,20 +10,23 @@ using namespace Microsoft::Console::Types;
using namespace Microsoft::Console::VirtualTerminal;
// 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);
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(view);
_WriteBuffer({ &wch, 1 });
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();
if (foreground)
@ -38,7 +41,7 @@ bool Terminal::SetTextToDefaults(bool foreground, bool background)
return true;
}
bool Terminal::SetTextForegroundIndex(BYTE colorIndex)
bool Terminal::SetTextForegroundIndex(BYTE colorIndex) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetIndexedAttributes({ colorIndex }, {});
@ -46,7 +49,7 @@ bool Terminal::SetTextForegroundIndex(BYTE colorIndex)
return true;
}
bool Terminal::SetTextBackgroundIndex(BYTE colorIndex)
bool Terminal::SetTextBackgroundIndex(BYTE colorIndex) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetIndexedAttributes({}, { colorIndex });
@ -54,7 +57,7 @@ bool Terminal::SetTextBackgroundIndex(BYTE colorIndex)
return true;
}
bool Terminal::SetTextRgbColor(COLORREF color, bool foreground)
bool Terminal::SetTextRgbColor(COLORREF color, bool foreground) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetColor(color, foreground);
@ -62,7 +65,7 @@ bool Terminal::SetTextRgbColor(COLORREF color, bool foreground)
return true;
}
bool Terminal::BoldText(bool boldOn)
bool Terminal::BoldText(bool boldOn) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
if (boldOn)
@ -77,7 +80,7 @@ bool Terminal::BoldText(bool boldOn)
return true;
}
bool Terminal::UnderlineText(bool underlineOn)
bool Terminal::UnderlineText(bool underlineOn) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
WORD metaAttrs = attrs.GetMetaAttributes();
@ -89,7 +92,7 @@ bool Terminal::UnderlineText(bool underlineOn)
return true;
}
bool Terminal::ReverseText(bool reversed)
bool Terminal::ReverseText(bool reversed) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
WORD metaAttrs = attrs.GetMetaAttributes();
@ -101,7 +104,8 @@ bool Terminal::ReverseText(bool reversed)
return true;
}
bool Terminal::SetCursorPosition(short x, short y)
bool Terminal::SetCursorPosition(short x, short y) noexcept
try
{
const auto viewport = _GetMutableViewport();
const auto viewOrigin = viewport.Origin();
@ -113,8 +117,9 @@ bool Terminal::SetCursorPosition(short x, short y)
return true;
}
CATCH_LOG_RETURN_FALSE()
COORD Terminal::GetCursorPosition()
COORD Terminal::GetCursorPosition() noexcept
{
const auto absoluteCursorPos = _buffer->GetCursor().GetPosition();
const auto viewport = _GetMutableViewport();
@ -137,7 +142,8 @@ COORD Terminal::GetCursorPosition()
// - count, the number of characters to delete
// Return value:
// - true if succeeded, false otherwise
bool Terminal::DeleteCharacter(const size_t count)
bool Terminal::DeleteCharacter(const size_t count) noexcept
try
{
SHORT 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 copyToPos = cursorPos;
const COORD copyFromPos{ cursorPos.X + dist, cursorPos.Y };
auto sourceWidth = _mutableViewport.RightExclusive() - copyFromPos.X;
const auto sourceWidth = _mutableViewport.RightExclusive() - copyFromPos.X;
SHORT width;
if (!SUCCEEDED(UIntToShort(sourceWidth, &width)))
{
@ -173,6 +179,7 @@ bool Terminal::DeleteCharacter(const size_t count)
return true;
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - 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
// Return value:
// - 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
// 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 copyFromPos = cursorPos;
const COORD copyToPos{ cursorPos.X + dist, cursorPos.Y };
auto sourceWidth = _mutableViewport.RightExclusive() - copyFromPos.X;
const auto sourceWidth = _mutableViewport.RightExclusive() - copyFromPos.X;
SHORT width;
if (!SUCCEEDED(UIntToShort(sourceWidth, &width)))
{
@ -221,22 +229,25 @@ bool Terminal::InsertCharacter(const size_t count)
const auto data = OutputCell(*(_buffer->GetCellDataAt(sourcePos)));
_buffer->Write(OutputCellIterator({ &data, 1 }), targetPos);
} 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);
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 viewport = _GetMutableViewport();
const short distanceToRight = viewport.RightExclusive() - absoluteCursorPos.X;
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);
return true;
}
CATCH_LOG_RETURN_FALSE()
// Method description:
// - erases a line of text, either from
@ -248,7 +259,8 @@ bool Terminal::EraseCharacters(const size_t numChars)
// - the erase type
// Return value:
// - 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 viewport = _GetMutableViewport();
@ -275,12 +287,13 @@ bool Terminal::EraseInLine(const ::Microsoft::Console::VirtualTerminal::Dispatch
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.
_buffer->Write(eraseIter, startPos, false);
return true;
}
CATCH_LOG_RETURN_FALSE()
// Method description:
// - 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
// Return Value:
// - 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
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;
_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
// and we have to make sure we erase that text
auto eraseStart = _mutableViewport.Height();
auto eraseEnd = _buffer->GetLastNonSpaceCharacter(_mutableViewport).Y;
const auto eraseStart = _mutableViewport.Height();
const auto eraseEnd = _buffer->GetLastNonSpaceCharacter(_mutableViewport).Y;
for (SHORT i = eraseStart; i <= eraseEnd; i++)
{
_buffer->GetRowByOffset(i).Reset(_buffer->GetCurrentAttributes());
@ -362,8 +377,10 @@ bool Terminal::EraseInDisplay(const DispatchTypes::EraseType eraseType)
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;
@ -371,6 +388,7 @@ bool Terminal::SetWindowTitle(std::wstring_view title)
return true;
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - 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.
// Return Value:
// - 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
_buffer->GetRenderTarget().TriggerRedrawAll();
return true;
}
catch (std::out_of_range&)
{
return false;
}
// Repaint everything - the colors might have changed
_buffer->GetRenderTarget().TriggerRedrawAll();
return true;
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - 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
// Return Value:
// - 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;
bool fShouldBlink;
CursorType finalCursorType = CursorType::Legacy;
bool shouldBlink = false;
switch (cursorStyle)
{
@ -413,35 +426,35 @@ bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
[[fallthrough]];
case DispatchTypes::CursorStyle::BlinkingBlock:
finalCursorType = CursorType::FullBox;
fShouldBlink = true;
shouldBlink = true;
break;
case DispatchTypes::CursorStyle::SteadyBlock:
finalCursorType = CursorType::FullBox;
fShouldBlink = false;
shouldBlink = false;
break;
case DispatchTypes::CursorStyle::BlinkingUnderline:
finalCursorType = CursorType::Underscore;
fShouldBlink = true;
shouldBlink = true;
break;
case DispatchTypes::CursorStyle::SteadyUnderline:
finalCursorType = CursorType::Underscore;
fShouldBlink = false;
shouldBlink = false;
break;
case DispatchTypes::CursorStyle::BlinkingBar:
finalCursorType = CursorType::VerticalBar;
fShouldBlink = true;
shouldBlink = true;
break;
case DispatchTypes::CursorStyle::SteadyBar:
finalCursorType = CursorType::VerticalBar;
fShouldBlink = false;
shouldBlink = false;
break;
default:
finalCursorType = CursorType::Legacy;
fShouldBlink = false;
shouldBlink = false;
}
_buffer->GetCursor().SetType(finalCursorType);
_buffer->GetCursor().SetBlinkingAllowed(fShouldBlink);
_buffer->GetCursor().SetBlinkingAllowed(shouldBlink);
return true;
}
@ -452,7 +465,8 @@ bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
// - color: the new COLORREF to use as the default foreground color
// Return Value:
// - true
bool Terminal::SetDefaultForeground(const COLORREF color)
bool Terminal::SetDefaultForeground(const COLORREF color) noexcept
try
{
_defaultFg = color;
@ -460,6 +474,7 @@ bool Terminal::SetDefaultForeground(const COLORREF color)
_buffer->GetRenderTarget().TriggerRedrawAll();
return true;
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - 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
// Return Value:
// - true
bool Terminal::SetDefaultBackground(const COLORREF color)
bool Terminal::SetDefaultBackground(const COLORREF color) noexcept
try
{
_defaultBg = color;
_pfnBackgroundColorChanged(color);
@ -476,3 +492,4 @@ bool Terminal::SetDefaultBackground(const COLORREF color)
_buffer->GetRenderTarget().TriggerRedrawAll();
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
// TerminalDispatchGraphics.cpp, not this file
TerminalDispatch::TerminalDispatch(ITerminalApi& terminalApi) :
TerminalDispatch::TerminalDispatch(ITerminalApi& terminalApi) noexcept :
_terminalApi{ terminalApi }
{
}
void TerminalDispatch::Execute(const wchar_t wchControl)
void TerminalDispatch::Execute(const wchar_t wchControl) noexcept
{
_terminalApi.ExecuteChar(wchControl);
}
void TerminalDispatch::Print(const wchar_t wchPrintable)
void TerminalDispatch::Print(const wchar_t wchPrintable) noexcept
{
_terminalApi.PrintString({ &wchPrintable, 1 });
}
void TerminalDispatch::PrintString(const std::wstring_view string)
void TerminalDispatch::PrintString(const std::wstring_view string) noexcept
{
_terminalApi.PrintString(string);
}
bool TerminalDispatch::CursorPosition(const size_t line,
const size_t column) noexcept
try
{
const auto columnInBufferSpace = column - 1;
const auto lineInBufferSpace = line - 1;
short x = static_cast<short>(column - 1);
short y = static_cast<short>(line - 1);
SHORT x{ 0 };
SHORT y{ 0 };
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);
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::CursorForward(const size_t distance) noexcept
try
{
const auto cursorPos = _terminalApi.GetCursorPosition();
const COORD newCursorPos{ cursorPos.X + gsl::narrow<short>(distance), cursorPos.Y };
return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::CursorBackward(const size_t distance) noexcept
try
{
const auto cursorPos = _terminalApi.GetCursorPosition();
const COORD newCursorPos{ cursorPos.X - gsl::narrow<short>(distance), cursorPos.Y };
return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::CursorUp(const size_t distance) noexcept
try
{
const auto cursorPos = _terminalApi.GetCursorPosition();
const COORD newCursorPos{ cursorPos.X, cursorPos.Y + gsl::narrow<short>(distance) };
return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::EraseCharacters(const size_t numChars) noexcept
try
{
return _terminalApi.EraseCharacters(numChars);
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::SetWindowTitle(std::wstring_view title) noexcept
try
{
return _terminalApi.SetWindowTitle(title);
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - 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.
bool TerminalDispatch::SetColorTableEntry(const size_t tableIndex,
const DWORD color) noexcept
try
{
return _terminalApi.SetColorTableEntry(tableIndex, color);
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) noexcept
try
{
return _terminalApi.SetCursorStyle(cursorStyle);
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - Sets the default foreground color to a new value
@ -96,9 +117,11 @@ bool TerminalDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorSty
// Return Value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::SetDefaultForeground(const DWORD color) noexcept
try
{
return _terminalApi.SetDefaultForeground(color);
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - Sets the default background color to a new value
@ -107,9 +130,11 @@ bool TerminalDispatch::SetDefaultForeground(const DWORD color) noexcept
// Return Value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::SetDefaultBackground(const DWORD color) noexcept
try
{
return _terminalApi.SetDefaultBackground(color);
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - Erases characters in the buffer depending on the erase type
@ -118,9 +143,11 @@ bool TerminalDispatch::SetDefaultBackground(const DWORD color) noexcept
// Return Value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::EraseInLine(const DispatchTypes::EraseType eraseType) noexcept
try
{
return _terminalApi.EraseInLine(eraseType);
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - 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:
// True if handled successfully. False otherwise.
bool TerminalDispatch::DeleteCharacter(const size_t count) noexcept
try
{
return _terminalApi.DeleteCharacter(count);
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - 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:
// True if handled successfully, false otherwise
bool TerminalDispatch::InsertCharacter(const size_t count) noexcept
try
{
return _terminalApi.InsertCharacter(count);
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - 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:
// True if handled successfully. False otherwise
bool TerminalDispatch::EraseInDisplay(const DispatchTypes::EraseType eraseType) noexcept
try
{
return _terminalApi.EraseInDisplay(eraseType);
}
CATCH_LOG_RETURN_FALSE()

View File

@ -7,16 +7,16 @@
class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatch
{
public:
TerminalDispatch(::Microsoft::Terminal::Core::ITerminalApi& terminalApi);
virtual ~TerminalDispatch(){};
virtual void Execute(const wchar_t wchControl) override;
virtual void Print(const wchar_t wchPrintable) override;
virtual void PrintString(const std::wstring_view string) override;
TerminalDispatch(::Microsoft::Terminal::Core::ITerminalApi& terminalApi) noexcept;
void Execute(const wchar_t wchControl) noexcept override;
void Print(const wchar_t wchPrintable) noexcept 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;
virtual bool CursorPosition(const size_t line,
const size_t column) noexcept override; // CUP
bool CursorPosition(const size_t line,
const size_t column) noexcept override; // CUP
bool CursorForward(const size_t distance) noexcept override;
bool CursorBackward(const size_t distance) noexcept override;
@ -38,13 +38,9 @@ public:
private:
::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,
size_t& optionsConsumed);
bool _SetBoldColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions option);
bool _SetDefaultColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions option);
void _SetGraphicsOptionHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt);
size_t& optionsConsumed) noexcept;
bool _SetBoldColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
bool _SetDefaultColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
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.
// Return Value:
// - 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 ||
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.
// Return Value:
// - 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 ||
opt == DispatchTypes::GraphicsOptions::UnBold;
@ -56,7 +56,7 @@ bool TerminalDispatch::s_IsBoldColorOption(const DispatchTypes::GraphicsOptions
//the default attributes.
// Return Value:
// - 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 ||
opt == DispatchTypes::GraphicsOptions::ForegroundDefault ||
@ -79,18 +79,18 @@ bool TerminalDispatch::s_IsDefaultColorOption(const DispatchTypes::GraphicsOptio
// 3 - true, parsed an xterm index to a color
// 5 - true, parsed an RGB color.
bool TerminalDispatch::_SetRgbColorsHelper(const std::basic_string_view<DispatchTypes::GraphicsOptions> options,
size_t& optionsConsumed)
size_t& optionsConsumed) noexcept
{
COLORREF color = 0;
bool isForeground = false;
bool success = false;
optionsConsumed = 1;
if (options.size() >= 2 && s_IsRgbColorOption(options.front()))
if (options.size() >= 2 && _isRgbColorOption(options.front()))
{
optionsConsumed = 2;
DispatchTypes::GraphicsOptions extendedOpt = options.at(0);
DispatchTypes::GraphicsOptions typeOpt = options.at(1);
const auto extendedOpt = til::at(options, 0);
const auto typeOpt = til::at(options, 1);
if (extendedOpt == DispatchTypes::GraphicsOptions::ForegroundExtended)
{
@ -105,7 +105,7 @@ bool TerminalDispatch::_SetRgbColorsHelper(const std::basic_string_view<Dispatch
{
optionsConsumed = 5;
// 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 green = std::min(options.at(3), 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;
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 ?
_terminalApi.SetTextForegroundIndex((BYTE)tableIndex) :
_terminalApi.SetTextBackgroundIndex((BYTE)tableIndex);
_terminalApi.SetTextForegroundIndex(gsl::narrow_cast<BYTE>(tableIndex)) :
_terminalApi.SetTextBackgroundIndex(gsl::narrow_cast<BYTE>(tableIndex));
}
}
}
return success;
}
bool TerminalDispatch::_SetBoldColorHelper(const DispatchTypes::GraphicsOptions option)
bool TerminalDispatch::_SetBoldColorHelper(const DispatchTypes::GraphicsOptions option) noexcept
{
const bool bold = (option == DispatchTypes::GraphicsOptions::BoldBright);
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 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
// Return Value:
// - <none>
void TerminalDispatch::_SetGraphicsOptionHelper(const DispatchTypes::GraphicsOptions opt)
void TerminalDispatch::_SetGraphicsOptionHelper(const DispatchTypes::GraphicsOptions opt) noexcept
{
switch (opt)
{
@ -293,16 +293,16 @@ bool TerminalDispatch::SetGraphicsRendition(const std::basic_string_view<Dispatc
// Run through the graphics options and apply them
for (size_t i = 0; i < options.size(); i++)
{
DispatchTypes::GraphicsOptions opt = options.at(i);
if (s_IsDefaultColorOption(opt))
const auto opt = options.at(i);
if (_isDefaultColorOption(opt))
{
success = _SetDefaultColorHelper(opt);
}
else if (s_IsBoldColorOption(opt))
else if (_isBoldColorOption(opt))
{
success = _SetBoldColorHelper(opt);
}
else if (s_IsRgbColorOption(opt))
else if (_isRgbColorOption(opt))
{
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
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);
// 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
{
// force position to be within bounds
#pragma warning(suppress : 26496) // cpp core checks wants this const but .Clamp() can write it.
COORD positionWithOffsets = position;
_buffer->GetSize().Clamp(positionWithOffsets);
@ -380,6 +382,7 @@ COORD Terminal::_ExpandDoubleClickSelectionLeft(const COORD position) const
COORD Terminal::_ExpandDoubleClickSelectionRight(const COORD position) const
{
// force position to be within bounds
#pragma warning(suppress : 26496) // cpp core checks wants this const but .Clamp() can write it.
COORD positionWithOffsets = position;
_buffer->GetSize().Clamp(positionWithOffsets);

View File

@ -10,6 +10,11 @@
<RootNamespace>Microsoft.Terminal.Core</RootNamespace>
</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="$(SolutionDir)src\common.build.pre.props" />
@ -49,7 +54,6 @@
</ClCompile>
</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" />
</Project>

View File

@ -27,6 +27,11 @@ const TextBuffer& Terminal::GetTextBuffer() noexcept
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
{
// 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);
return _fakeFontInfo;
}
#pragma warning(pop)
const TextAttribute Terminal::GetDefaultBrushColors() noexcept
{
@ -46,12 +52,12 @@ const TextAttribute Terminal::GetDefaultBrushColors() 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 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)
// If the bg isn't the default bg color, then make it fully opaque.
if (!attr.BackgroundIsDefault())
@ -115,6 +121,7 @@ const bool Terminal::IsGridLineDrawingAllowed() noexcept
}
std::vector<Microsoft::Console::Types::Viewport> Terminal::GetSelectionRects() noexcept
try
{
std::vector<Viewport> result;
@ -125,11 +132,19 @@ std::vector<Microsoft::Console::Types::Viewport> Terminal::GetSelectionRects() n
return result;
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
return {};
}
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 realCoordEnd = coordEnd;
#pragma warning(pop)
bool notifyScrollChange = false;
if (coordStart.Y < _VisibleStartIndex())
@ -162,9 +177,15 @@ void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
}
const std::wstring Terminal::GetConsoleTitle() const noexcept
try
{
return _title;
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
return {};
}
// Method Description:
// - 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
{
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) |
(alt ? Settings::KeyModifiers::Alt : 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 },
_vkey{ vkey }
{
}
Settings::KeyModifiers KeyChord::Modifiers()
Settings::KeyModifiers KeyChord::Modifiers() noexcept
{
return _modifiers;
}
void KeyChord::Modifiers(Settings::KeyModifiers const& value)
void KeyChord::Modifiers(Settings::KeyModifiers const& value) noexcept
{
_modifiers = value;
}
int32_t KeyChord::Vkey()
int32_t KeyChord::Vkey() noexcept
{
return _vkey;
}
void KeyChord::Vkey(int32_t value)
void KeyChord::Vkey(int32_t value) noexcept
{
_vkey = value;
}

View File

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

View File

@ -9,6 +9,10 @@
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() :
_defaultForeground{ DEFAULT_FOREGROUND_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;
}
void TerminalSettings::DefaultForeground(uint32_t value)
void TerminalSettings::DefaultForeground(uint32_t value) noexcept
{
_defaultForeground = value;
}
uint32_t TerminalSettings::DefaultBackground()
uint32_t TerminalSettings::DefaultBackground() noexcept
{
return _defaultBackground;
}
void TerminalSettings::DefaultBackground(uint32_t value)
void TerminalSettings::DefaultBackground(uint32_t value) noexcept
{
_defaultBackground = value;
}
uint32_t TerminalSettings::SelectionBackground()
uint32_t TerminalSettings::SelectionBackground() noexcept
{
return _selectionBackground;
}
void TerminalSettings::SelectionBackground(uint32_t value)
void TerminalSettings::SelectionBackground(uint32_t value) noexcept
{
_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)
{
auto const colorTableCount = gsl::narrow_cast<decltype(index)>(_colorTable.size());
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;
}
void TerminalSettings::HistorySize(int32_t value)
void TerminalSettings::HistorySize(int32_t value) noexcept
{
_historySize = value;
}
int32_t TerminalSettings::InitialRows()
int32_t TerminalSettings::InitialRows() noexcept
{
return _initialRows;
}
void TerminalSettings::InitialRows(int32_t value)
void TerminalSettings::InitialRows(int32_t value) noexcept
{
_initialRows = value;
}
int32_t TerminalSettings::InitialCols()
int32_t TerminalSettings::InitialCols() noexcept
{
return _initialCols;
}
void TerminalSettings::InitialCols(int32_t value)
void TerminalSettings::InitialCols(int32_t value) noexcept
{
_initialCols = value;
}
bool TerminalSettings::SnapOnInput()
bool TerminalSettings::SnapOnInput() noexcept
{
return _snapOnInput;
}
void TerminalSettings::SnapOnInput(bool value)
void TerminalSettings::SnapOnInput(bool value) noexcept
{
_snapOnInput = value;
}
uint32_t TerminalSettings::CursorColor()
uint32_t TerminalSettings::CursorColor() noexcept
{
return _cursorColor;
}
void TerminalSettings::CursorColor(uint32_t value)
void TerminalSettings::CursorColor(uint32_t value) noexcept
{
_cursorColor = value;
}
@ -140,12 +144,12 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_cursorShape = value;
}
uint32_t TerminalSettings::CursorHeight()
uint32_t TerminalSettings::CursorHeight() noexcept
{
return _cursorHeight;
}
void TerminalSettings::CursorHeight(uint32_t value)
void TerminalSettings::CursorHeight(uint32_t value) noexcept
{
_cursorHeight = value;
}
@ -160,32 +164,32 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_wordDelimiters = value;
}
bool TerminalSettings::CopyOnSelect()
bool TerminalSettings::CopyOnSelect() noexcept
{
return _copyOnSelect;
}
void TerminalSettings::CopyOnSelect(bool value)
void TerminalSettings::CopyOnSelect(bool value) noexcept
{
_copyOnSelect = value;
}
bool TerminalSettings::UseAcrylic()
bool TerminalSettings::UseAcrylic() noexcept
{
return _useAcrylic;
}
void TerminalSettings::UseAcrylic(bool value)
void TerminalSettings::UseAcrylic(bool value) noexcept
{
_useAcrylic = value;
}
double TerminalSettings::TintOpacity()
double TerminalSettings::TintOpacity() noexcept
{
return _tintOpacity;
}
void TerminalSettings::TintOpacity(double value)
void TerminalSettings::TintOpacity(double value) noexcept
{
_tintOpacity = value;
}
@ -210,12 +214,12 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_fontFace = value;
}
int32_t TerminalSettings::FontSize()
int32_t TerminalSettings::FontSize() noexcept
{
return _fontSize;
}
void TerminalSettings::FontSize(int32_t value)
void TerminalSettings::FontSize(int32_t value) noexcept
{
_fontSize = value;
}
@ -230,52 +234,52 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
return _backgroundImage;
}
void TerminalSettings::BackgroundImageOpacity(double value)
void TerminalSettings::BackgroundImageOpacity(double value) noexcept
{
_backgroundImageOpacity = value;
}
double TerminalSettings::BackgroundImageOpacity()
double TerminalSettings::BackgroundImageOpacity() noexcept
{
return _backgroundImageOpacity;
}
winrt::Windows::UI::Xaml::Media::Stretch TerminalSettings::BackgroundImageStretchMode()
winrt::Windows::UI::Xaml::Media::Stretch TerminalSettings::BackgroundImageStretchMode() noexcept
{
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;
}
winrt::Windows::UI::Xaml::HorizontalAlignment TerminalSettings::BackgroundImageHorizontalAlignment()
winrt::Windows::UI::Xaml::HorizontalAlignment TerminalSettings::BackgroundImageHorizontalAlignment() noexcept
{
return _backgroundImageHorizontalAlignment;
}
void TerminalSettings::BackgroundImageHorizontalAlignment(winrt::Windows::UI::Xaml::HorizontalAlignment value)
void TerminalSettings::BackgroundImageHorizontalAlignment(winrt::Windows::UI::Xaml::HorizontalAlignment value) noexcept
{
_backgroundImageHorizontalAlignment = value;
}
winrt::Windows::UI::Xaml::VerticalAlignment TerminalSettings::BackgroundImageVerticalAlignment()
winrt::Windows::UI::Xaml::VerticalAlignment TerminalSettings::BackgroundImageVerticalAlignment() noexcept
{
return _backgroundImageVerticalAlignment;
}
void TerminalSettings::BackgroundImageVerticalAlignment(winrt::Windows::UI::Xaml::VerticalAlignment value)
void TerminalSettings::BackgroundImageVerticalAlignment(winrt::Windows::UI::Xaml::VerticalAlignment value) noexcept
{
_backgroundImageVerticalAlignment = value;
}
Settings::IKeyBindings TerminalSettings::KeyBindings()
Settings::IKeyBindings TerminalSettings::KeyBindings() noexcept
{
return _keyBindings;
}
void TerminalSettings::KeyBindings(Settings::IKeyBindings const& value)
void TerminalSettings::KeyBindings(Settings::IKeyBindings const& value) noexcept
{
_keyBindings = value;
}
@ -310,12 +314,12 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_startingTitle = value;
}
bool TerminalSettings::SuppressApplicationTitle()
bool TerminalSettings::SuppressApplicationTitle() noexcept
{
return _suppressApplicationTitle;
}
void TerminalSettings::SuppressApplicationTitle(bool value)
void TerminalSettings::SuppressApplicationTitle(bool value) noexcept
{
_suppressApplicationTitle = value;
}
@ -340,12 +344,12 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_scrollbarState = value;
}
bool TerminalSettings::RetroTerminalEffect()
bool TerminalSettings::RetroTerminalEffect() noexcept
{
return _retroTerminalEffect;
}
void TerminalSettings::RetroTerminalEffect(bool value)
void TerminalSettings::RetroTerminalEffect(bool value) noexcept
{
_retroTerminalEffect = value;
}

View File

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

View File

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

View File

@ -66,7 +66,7 @@ private:
#define TYPED_EVENT(name, sender, args) \
public: \
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: \
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
// event to event.
// Use this in a class's header if you have a "delegate" type in your IDL.
#define WINRT_CALLBACK(name, args) \
public: \
winrt::event_token name(args const& handler) { return _##name##Handlers.add(handler); } \
void name(winrt::event_token const& token) noexcept { _##name##Handlers.remove(token); } \
\
private: \
#define WINRT_CALLBACK(name, args) \
public: \
winrt::event_token name(args const& handler) { return _##name##Handlers.add(handler); } \
void name(winrt::event_token const& token) { _##name##Handlers.remove(token); } \
\
private: \
winrt::event<args> _##name##Handlers;
// 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>
<EnableCppCoreCheck>true</EnableCppCoreCheck>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CAExcludePath>$(SolutionDir)\dep</CAExcludePath>
<CAExcludePath>$(CAExcludePath);$(SolutionDir)\dep;$(SolutionDir)\packages</CAExcludePath>
<OpenConsoleVcpkgConfiguration>Release</OpenConsoleVcpkgConfiguration>
<OpenConsoleTppVcpkgConfiguration>Release</OpenConsoleTppVcpkgConfiguration>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='AuditMode'">
<ClCompile>

View File

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

View File

@ -7,6 +7,8 @@
// Routine Description:
// - 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.
#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() :
// 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.
@ -15,12 +17,6 @@ WinNTControl::WinNTControl() :
{
}
// Routine Description:
// - Destructs an instance of the NTDLL method-invoking class.
WinNTControl::~WinNTControl()
{
}
// Routine Description:
// - Provides the singleton pattern for WinNT control. Stores the single instance and returns it.
// Arguments:

View File

@ -26,8 +26,6 @@ public:
_In_ ULONG ShareAccess,
_In_ ULONG OpenOptions);
~WinNTControl();
private:
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:
// Returns true if the GraphicsOption represents an extended text attribute.
// These include things such as Underlined, Italics, Blinking, etc.
@ -321,6 +324,8 @@ static constexpr bool _isDefaultColorOption(const DispatchTypes::GraphicsOptions
opt == DispatchTypes::GraphicsOptions::BackgroundDefault;
}
#pragma warning(pop)
// Routine Description:
// - 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)

View File

@ -1324,6 +1324,9 @@ bool OutputStateMachineEngine::s_HexToUint(const wchar_t wch,
return success;
}
#pragma warning(push)
#pragma warning(disable : 26497) // We don't use any of these "constexprable" functions in that fashion
// Routine Description:
// - Determines if a character is a valid number character, 0-9.
// Arguments:
@ -1348,6 +1351,8 @@ static constexpr bool _isHexNumber(const wchar_t wch) noexcept
(wch >= L'a' && wch <= L'f');
}
#pragma warning(pop)
// Routine Description:
// - Given a color spec string, attempts to parse the color that's encoded.
// 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
}
#pragma warning(push)
#pragma warning(disable : 26497) // We don't use any of these "constexprable" functions in that fashion
// Routine Description:
// - Determines if a character belongs to the C0 escape range.
// 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);
}
#pragma warning(pop)
// Routine Description:
// - Triggers the Execute action to indicate that the listener should immediately respond to a C0 control character.
// Arguments:

View File

@ -20,6 +20,7 @@
#pragma warning(push)
#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:
// - 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,
_Inout_ PseudoConsole* pPty)
{
if (pPty == NULL)
if (pPty == nullptr)
{
return E_INVALIDARG;
}
@ -76,14 +77,14 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
sa.nLength = sizeof(sa);
// Mark inheritable for signal handle when creating. It'll have the same value on the other side.
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(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";
// 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;
swprintf_s(cmd,
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.
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[]
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);
auto attrListDelete = wil::scope_exit([&] {
auto attrListDelete = wil::scope_exit([&]() noexcept {
HeapFree(GetProcessHeap(), 0, attrList);
});
siEx.lpAttributeList = attrList;
RETURN_IF_WIN32_BOOL_FALSE(InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, &listSize));
// Set cleanup data for ProcThreadAttributeList when successful.
auto cleanupProcThreadAttribute = wil::scope_exit([&] {
auto cleanupProcThreadAttribute = wil::scope_exit([&]() noexcept {
DeleteProcThreadAttributeList(siEx.lpAttributeList);
});
RETURN_IF_WIN32_BOOL_FALSE(UpdateProcThreadAttribute(siEx.lpAttributeList,
@ -132,8 +133,8 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
inheritedHandles,
(INHERITED_HANDLES_COUNT * sizeof(HANDLE)),
NULL,
NULL));
nullptr,
nullptr));
wil::unique_process_information pi;
{ // wow64 disabled filesystem redirection scope
#if defined(BUILD_WOW6432)
@ -145,17 +146,17 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
RtlWow64EnableFsRedirectionEx(RedirectionFlag, &RedirectionFlag);
});
#endif
if (hToken == INVALID_HANDLE_VALUE || hToken == NULL)
if (hToken == INVALID_HANDLE_VALUE || hToken == nullptr)
{
// Call create process
RETURN_IF_WIN32_BOOL_FALSE(CreateProcessW(NULL,
RETURN_IF_WIN32_BOOL_FALSE(CreateProcessW(nullptr,
cmd,
NULL,
NULL,
nullptr,
nullptr,
TRUE,
EXTENDED_STARTUPINFO_PRESENT,
NULL,
NULL,
nullptr,
nullptr,
&siEx.StartupInfo,
pi.addressof()));
}
@ -163,14 +164,14 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
{
// Call create process
RETURN_IF_WIN32_BOOL_FALSE(CreateProcessAsUserW(hToken,
NULL,
nullptr,
cmd,
NULL,
NULL,
nullptr,
nullptr,
TRUE,
EXTENDED_STARTUPINFO_PRESENT,
NULL,
NULL,
nullptr,
nullptr,
&siEx.StartupInfo,
pi.addressof()));
}
@ -178,7 +179,7 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
// Move the process handle out of the PROCESS_INFORMATION into out Pseudoconsole
pPty->hConPtyProcess = pi.hProcess;
pi.hProcess = NULL;
pi.hProcess = nullptr;
RETURN_IF_NTSTATUS_FAILED(CreateClientHandle(&pPty->hPtyReference,
serverHandle.get(),
@ -200,7 +201,7 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken,
// write the resize message to the pty.
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;
}
@ -210,7 +211,7 @@ HRESULT _ResizePseudoConsole(_In_ const PseudoConsole* const pPty, _In_ const CO
signalPacket[1] = size.X;
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());
}
@ -225,14 +226,14 @@ HRESULT _ResizePseudoConsole(_In_ const PseudoConsole* const pPty, _In_ const CO
// - <none>
void _ClosePseudoConsoleMembers(_In_ PseudoConsole* pPty)
{
if (pPty != NULL)
if (pPty != nullptr)
{
// See MSFT:19918626
// First break the signal pipe - this will trigger conhost to tear itself down
if (_HandleIsValid(pPty->hSignal))
{
CloseHandle(pPty->hSignal);
pPty->hSignal = 0;
pPty->hSignal = nullptr;
}
// Then, wait on the conhost process before killing 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);
pPty->hConPtyProcess = 0;
pPty->hConPtyProcess = nullptr;
}
// Then take care of the reference handle.
// TODO GH#1810: Closing the reference handle late leaves conhost thinking
@ -260,7 +261,7 @@ void _ClosePseudoConsoleMembers(_In_ PseudoConsole* pPty)
if (_HandleIsValid(pPty->hPtyReference))
{
CloseHandle(pPty->hPtyReference);
pPty->hPtyReference = 0;
pPty->hPtyReference = nullptr;
}
}
}
@ -275,7 +276,7 @@ void _ClosePseudoConsoleMembers(_In_ PseudoConsole* pPty)
// - <none>
VOID _ClosePseudoConsole(_In_ PseudoConsole* pPty)
{
if (pPty != NULL)
if (pPty != nullptr)
{
_ClosePseudoConsoleMembers(pPty);
HeapFree(GetProcessHeap(), 0, pPty);
@ -325,11 +326,11 @@ extern "C" HRESULT ConptyCreatePseudoConsoleAsUser(_In_ HANDLE hToken,
_In_ DWORD dwFlags,
_Out_ HPCON* phPC)
{
if (phPC == NULL)
if (phPC == nullptr)
{
return E_INVALIDARG;
}
*phPC = NULL;
*phPC = nullptr;
if ((!_HandleIsValid(hInput)) && (!_HandleIsValid(hOutput)))
{
return E_INVALIDARG;
@ -337,7 +338,7 @@ extern "C" HRESULT ConptyCreatePseudoConsoleAsUser(_In_ HANDLE hToken,
PseudoConsole* pPty = (PseudoConsole*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PseudoConsole));
RETURN_IF_NULL_ALLOC(pPty);
auto cleanupPty = wil::scope_exit([&] {
auto cleanupPty = wil::scope_exit([&]() noexcept {
_ClosePseudoConsole(pPty);
});
@ -358,8 +359,8 @@ extern "C" HRESULT ConptyCreatePseudoConsoleAsUser(_In_ HANDLE hToken,
// Resizes the given conpty to the specified size, in characters.
extern "C" HRESULT WINAPI ConptyResizePseudoConsole(_In_ HPCON hPC, _In_ COORD size)
{
PseudoConsole* const pPty = (PseudoConsole*)hPC;
HRESULT hr = pPty == NULL ? E_INVALIDARG : S_OK;
const PseudoConsole* const pPty = (PseudoConsole*)hPC;
HRESULT hr = pPty == nullptr ? E_INVALIDARG : S_OK;
if (SUCCEEDED(hr))
{
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)
{
PseudoConsole* const pPty = (PseudoConsole*)hPC;
if (pPty != NULL)
if (pPty != nullptr)
{
_ClosePseudoConsole(pPty);
}