diff --git a/src/host/_output.cpp b/src/host/_output.cpp index 0804a7ffab9..44701989a51 100644 --- a/src/host/_output.cpp +++ b/src/host/_output.cpp @@ -30,7 +30,6 @@ using Microsoft::Console::Interactivity::ServiceLocator; // - void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region) { - DBGOUTPUT(("WriteToScreen\n")); const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); // update to screen, if we're not iconic. if (!screenInfo.IsActiveScreenBuffer() || WI_IsFlagSet(gci.Flags, CONSOLE_IS_ICONIC)) diff --git a/src/host/misc.cpp b/src/host/misc.cpp index 329328f5672..3cadbf9f4c7 100644 --- a/src/host/misc.cpp +++ b/src/host/misc.cpp @@ -64,7 +64,6 @@ int ConvertToOem(const UINT uiCodePage, const UINT cchTarget) noexcept { FAIL_FAST_IF(!(pwchSource != (LPWSTR)pchTarget)); - DBGCHARS(("ConvertToOem U->%d %.*ls\n", uiCodePage, cchSource > 10 ? 10 : cchSource, pwchSource)); // clang-format off #pragma prefast(suppress: __WARNING_W2A_BEST_FIT, "WC_NO_BEST_FIT_CHARS doesn't work in many codepages. Retain old behavior.") // clang-format on @@ -80,6 +79,5 @@ int ConvertOutputToUnicode(_In_ UINT uiCodePage, { FAIL_FAST_IF(!(cchTarget > 0)); pwchTarget[0] = L'\0'; - DBGCHARS(("ConvertOutputToUnicode %d->U %.*s\n", uiCodePage, cchSource > 10 ? 10 : cchSource, pchSource)); return MultiByteToWideChar(uiCodePage, MB_USEGLYPHCHARS, pchSource, cchSource, pwchTarget, cchTarget); } diff --git a/src/host/tracing.hpp b/src/host/tracing.hpp index 03cf423f4d7..7549d54850e 100644 --- a/src/host/tracing.hpp +++ b/src/host/tracing.hpp @@ -17,28 +17,29 @@ Author(s): #pragma once -#include - #include "../types/inc/Viewport.hpp" -#if DBG -#define DBGCHARS(_params_) \ - { \ - Tracing::s_TraceChars _params_; \ - } -#define DBGOUTPUT(_params_) \ - { \ - Tracing::s_TraceOutput _params_; \ - } -#else -#define DBGCHARS(_params_) -#define DBGOUTPUT(_params_) -#endif - -#define TraceLoggingConsoleCoord(value, name) \ - TraceLoggingStruct(2, name), \ - TraceLoggingInt32(value.X, "X"), \ - TraceLoggingInt32(value.Y, "Y") +#define TraceLoggingConsoleCoord(value, name) \ + TraceLoggingPackedData(&value, sizeof(COORD)), \ + TraceLoggingPackedStruct(2, name), \ + TraceLoggingPackedMetadata(TlgInINT16, "X"), \ + TraceLoggingPackedMetadata(TlgInINT16, "Y") + +#define TraceLoggingConsoleSmallRect(value, name) \ + TraceLoggingPackedData(&value, sizeof(SMALL_RECT)), \ + TraceLoggingPackedStruct(4, name), \ + TraceLoggingInt16(TlgInINT16, "Left"), \ + TraceLoggingInt16(TlgInINT16, "Top"), \ + TraceLoggingInt16(TlgInINT16, "Right"), \ + TraceLoggingInt16(TlgInINT16, "Bottom") + +// We intentionally don't differentiate between A and W versions of CHAR_INFO, because some particularly nasty +// applications smuggle data in the upper bytes of the UnicodeChar field while using the A APIs and then they +// expect to read the same values back at a later time, which is something we stopped supporting. +#define TraceLoggingConsoleCharInfo(value, name) \ + TraceLoggingStruct(2, name), \ + TraceLoggingInt16(value.Char.UnicodeChar, "Char"), \ + TraceLoggingInt16(value.Attributes, "Attributes") class Tracing { diff --git a/src/propsheet/console.h b/src/propsheet/console.h index dfd0efd87ed..ef15b4f3747 100644 --- a/src/propsheet/console.h +++ b/src/propsheet/console.h @@ -196,13 +196,9 @@ void Undo(HWND hControlWindow); #define DBGFONTS(_params_) #define DBGFONTS2(_params_) - #define DBGCHARS(_params_) - #define DBGOUTPUT(_params_) #else #define DBGFONTS(_params_) #define DBGFONTS2(_params_) - #define DBGCHARS(_params_) - #define DBGOUTPUT(_params_) #endif // clang-format on diff --git a/src/server/ApiDispatchers.cpp b/src/server/ApiDispatchers.cpp index 8039977b5e5..9009f71c19f 100644 --- a/src/server/ApiDispatchers.cpp +++ b/src/server/ApiDispatchers.cpp @@ -34,6 +34,15 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) return p ? p->dwThreadId : 0; } +template +constexpr T saturate(auto val) +{ + constexpr auto min = std::numeric_limits::min(); + constexpr auto max = std::numeric_limits::max(); +#pragma warning(suppress : 4267) // '...': conversion from '...' to 'T', possible loss of data + return val < min ? min : (val > max ? max : val); +} + [[nodiscard]] HRESULT ApiDispatchers::ServerGetConsoleCP(_Inout_ CONSOLE_API_MSG* const m, _Inout_ BOOL* const /*pbReplyPending*/) { @@ -88,7 +97,7 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) TraceConsoleAPICallWithOrigin( "SetConsoleMode", TraceLoggingBool(pObjectHandle->IsInputHandle(), "InputHandle"), - TraceLoggingHexULong(a->Mode, "Mode")); + TraceLoggingHexUInt32(a->Mode, "Mode")); if (pObjectHandle->IsInputHandle()) { @@ -115,7 +124,13 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) InputBuffer* pObj; RETURN_IF_FAILED(pObjectHandle->GetInputBuffer(GENERIC_READ, &pObj)); - return m->_pApiRoutines->GetNumberOfConsoleInputEventsImpl(*pObj, a->ReadyEvents); + RETURN_IF_FAILED_EXPECTED(m->_pApiRoutines->GetNumberOfConsoleInputEventsImpl(*pObj, a->ReadyEvents)); + + TraceConsoleAPICallWithOrigin( + "GetNumberOfConsoleInputEvents", + TraceLoggingHexUInt32(a->ReadyEvents, "ReadyEvents")); + + return S_OK; } [[nodiscard]] HRESULT ApiDispatchers::ServerGetConsoleInput(_Inout_ CONSOLE_API_MSG* const m, @@ -135,6 +150,7 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) // Make sure we have a valid input buffer. const auto pHandleData = m->GetObjectHandle(); RETURN_HR_IF_NULL(E_HANDLE, pHandleData); + InputBuffer* pInputBuffer; RETURN_IF_FAILED(pHandleData->GetInputBuffer(GENERIC_READ, &pInputBuffer)); @@ -146,6 +162,12 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) const auto rgRecords = reinterpret_cast(pvBuffer); const auto cRecords = cbBufferSize / sizeof(INPUT_RECORD); + TraceConsoleAPICallWithOrigin( + "GetConsoleInput", + TraceLoggingHexUInt16(a->Flags, "Flags"), + TraceLoggingBoolean(a->Unicode, "Unicode"), + TraceLoggingUIntPtr(cRecords, "Records")); + const auto fIsPeek = WI_IsFlagSet(a->Flags, CONSOLE_READ_NOREMOVE); const auto fIsWaitAllowed = WI_IsFlagClear(a->Flags, CONSOLE_READ_NOWAIT); @@ -269,6 +291,14 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) } CATCH_RETURN(); + TraceConsoleAPICallWithOrigin( + "ReadConsole", + TraceLoggingBoolean(a->Unicode, "Unicode"), + TraceLoggingBoolean(a->ProcessControlZ, "ProcessControlZ"), + TraceLoggingCountedWideString(exeView.data(), saturate(exeView.size()), "ExeName"), + TraceLoggingCountedWideString(initialData.data(), saturate(initialData.size()), "InitialChars"), + TraceLoggingHexUInt32(a->CtrlWakeupMask, "CtrlWakeupMask")); + // ReadConsole needs this to get details associated with an attached process (such as the command history list, telemetry metadata). const auto hConsoleClient = (HANDLE)m->GetProcessHandle(); @@ -408,7 +438,7 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const auto a = &m->u.consoleMsgL2.FillConsoleOutput; // Capture length of initial fill. - size_t fill = a->Length; + const auto fill = a->Length; // Set written length to 0 in case we early return. a->Length = 0; @@ -425,6 +455,12 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { case CONSOLE_ATTRIBUTE: { + TraceConsoleAPICallWithOrigin( + "FillConsoleOutputAttribute", + TraceLoggingConsoleCoord(a->WriteCoord, "WriteCoord"), + TraceLoggingUInt32(fill, "Length"), + TraceLoggingHexUInt16(a->Element, "Attribute")); + hr = m->_pApiRoutines->FillConsoleOutputAttributeImpl(*pScreenInfo, a->Element, fill, @@ -435,6 +471,12 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) case CONSOLE_REAL_UNICODE: case CONSOLE_FALSE_UNICODE: { + TraceConsoleAPICallWithOrigin( + "FillConsoleOutputCharacterW", + TraceLoggingConsoleCoord(a->WriteCoord, "WriteCoord"), + TraceLoggingUInt32(fill, "Length"), + TraceLoggingWChar(a->Element, "Character")); + // GH#3126 if the client application is powershell.exe, then we might // need to enable a compatibility shim. hr = m->_pApiRoutines->FillConsoleOutputCharacterWImpl(*pScreenInfo, @@ -447,6 +489,12 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) } case CONSOLE_ASCII: { + TraceConsoleAPICallWithOrigin( + "FillConsoleOutputCharacterA", + TraceLoggingConsoleCoord(a->WriteCoord, "WriteCoord"), + TraceLoggingUInt32(fill, "Length"), + TraceLoggingChar(static_cast(a->Element), "Character")); + hr = m->_pApiRoutines->FillConsoleOutputCharacterAImpl(*pScreenInfo, static_cast(a->Element), fill, @@ -466,6 +514,8 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) [[nodiscard]] HRESULT ApiDispatchers::ServerSetConsoleActiveScreenBuffer(_Inout_ CONSOLE_API_MSG* const m, _Inout_ BOOL* const /*pbReplyPending*/) { + TraceConsoleAPICallWithOrigin("SetConsoleActiveScreenBuffer"); + const auto pObjectHandle = m->GetObjectHandle(); RETURN_HR_IF_NULL(E_HANDLE, pObjectHandle); @@ -479,6 +529,8 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) [[nodiscard]] HRESULT ApiDispatchers::ServerFlushConsoleInputBuffer(_Inout_ CONSOLE_API_MSG* const m, _Inout_ BOOL* const /*pbReplyPending*/) { + TraceConsoleAPICallWithOrigin("ServerFlushConsoleInputBuffer"); + const auto pObjectHandle = m->GetObjectHandle(); RETURN_HR_IF_NULL(E_HANDLE, pObjectHandle); @@ -494,6 +546,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const auto a = &m->u.consoleMsgL2.SetConsoleCP; + TraceConsoleAPICallWithOrigin( + "SetConsoleCP", + TraceLoggingBool(!a->Output, "InputHandle"), + TraceLoggingHexUInt32(a->CodePage, "CodePage")); + if (a->Output) { return m->_pApiRoutines->SetConsoleOutputCodePageImpl(a->CodePage); @@ -518,6 +575,12 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) auto visible = false; m->_pApiRoutines->GetConsoleCursorInfoImpl(*pObj, a->CursorSize, visible); a->Visible = !!visible; + + TraceConsoleAPICallWithOrigin( + "GetConsoleCursorInfo", + TraceLoggingUInt32(a->CursorSize, "CursorSize"), + TraceLoggingBoolean(a->Visible, "Visible")); + return S_OK; } @@ -526,6 +589,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const auto a = &m->u.consoleMsgL2.SetConsoleCursorInfo; + TraceConsoleAPICallWithOrigin( + "SetConsoleCursorInfo", + TraceLoggingUInt32(a->CursorSize, "CursorSize"), + TraceLoggingBoolean(a->Visible, "Visible")); + const auto pObjectHandle = m->GetObjectHandle(); RETURN_HR_IF_NULL(E_HANDLE, pObjectHandle); @@ -564,6 +632,18 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) a->Attributes = ex.wAttributes; a->PopupAttributes = ex.wPopupAttributes; + TraceConsoleAPICallWithOrigin( + "GetConsoleScreenBufferInfo", + TraceLoggingConsoleCoord(a->Size, "Size"), + TraceLoggingConsoleCoord(a->CursorPosition, "CursorPosition"), + TraceLoggingConsoleCoord(a->ScrollPosition, "ScrollPosition"), + TraceLoggingHexUInt16(a->Attributes, "Attributes"), + TraceLoggingConsoleCoord(a->CurrentWindowSize, "CurrentWindowSize"), + TraceLoggingConsoleCoord(a->MaximumWindowSize, "MaximumWindowSize"), + TraceLoggingHexUInt16(a->PopupAttributes, "PopupAttributes"), + TraceLoggingBoolean(a->FullscreenSupported, "FullscreenSupported"), + TraceLoggingHexULongFixedArray(&a->ColorTable[0], 16, "ColorTable")); + return S_OK; } @@ -572,6 +652,18 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const auto a = &m->u.consoleMsgL2.SetConsoleScreenBufferInfo; + TraceConsoleAPICallWithOrigin( + "SetConsoleScreenBufferInfo", + TraceLoggingConsoleCoord(a->Size, "Size"), + TraceLoggingConsoleCoord(a->CursorPosition, "CursorPosition"), + TraceLoggingConsoleCoord(a->ScrollPosition, "ScrollPosition"), + TraceLoggingHexUInt16(a->Attributes, "Attributes"), + TraceLoggingConsoleCoord(a->CurrentWindowSize, "CurrentWindowSize"), + TraceLoggingConsoleCoord(a->MaximumWindowSize, "MaximumWindowSize"), + TraceLoggingHexUInt16(a->PopupAttributes, "PopupAttributes"), + TraceLoggingBoolean(a->FullscreenSupported, "FullscreenSupported"), + TraceLoggingHexULongFixedArray(&a->ColorTable[0], 16, "ColorTable")); + const auto pObjectHandle = m->GetObjectHandle(); RETURN_HR_IF_NULL(E_HANDLE, pObjectHandle); @@ -594,12 +686,6 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) ex.wAttributes = a->Attributes; ex.wPopupAttributes = a->PopupAttributes; - TraceConsoleAPICallWithOrigin( - "SetConsoleScreenBufferInfoEx", - TraceLoggingConsoleCoord(a->Size, "BufferSize"), - TraceLoggingConsoleCoord(a->CurrentWindowSize, "WindowSize"), - TraceLoggingConsoleCoord(a->MaximumWindowSize, "MaxWindowSize")); - return m->_pApiRoutines->SetConsoleScreenBufferInfoExImpl(*pObj, ex); } @@ -608,16 +694,16 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const auto a = &m->u.consoleMsgL2.SetConsoleScreenBufferSize; + TraceConsoleAPICallWithOrigin( + "SetConsoleScreenBufferSize", + TraceLoggingConsoleCoord(a->Size, "BufferSize")); + const auto pObjectHandle = m->GetObjectHandle(); RETURN_HR_IF_NULL(E_HANDLE, pObjectHandle); SCREEN_INFORMATION* pObj; RETURN_IF_FAILED(pObjectHandle->GetScreenBuffer(GENERIC_WRITE, &pObj)); - TraceConsoleAPICallWithOrigin( - "SetConsoleScreenBufferSize", - TraceLoggingConsoleCoord(a->Size, "BufferSize")); - return m->_pApiRoutines->SetConsoleScreenBufferSizeImpl(*pObj, til::wrap_coord_size(a->Size)); } @@ -626,6 +712,10 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const auto a = &m->u.consoleMsgL2.SetConsoleCursorPosition; + TraceConsoleAPICallWithOrigin( + "SetConsoleCursorPosition", + TraceLoggingConsoleCoord(a->CursorPosition, "CursorPosition")); + const auto pObjectHandle = m->GetObjectHandle(); RETURN_HR_IF_NULL(E_HANDLE, pObjectHandle); @@ -648,7 +738,13 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) auto size = til::wrap_coord_size(a->Size); m->_pApiRoutines->GetLargestConsoleWindowSizeImpl(*pObj, size); - return til::unwrap_coord_size_hr(size, a->Size); + RETURN_IF_FAILED_EXPECTED(til::unwrap_coord_size_hr(size, a->Size)); + + TraceConsoleAPICallWithOrigin( + "GetLargestConsoleWindowSize", + TraceLoggingConsoleCoord(a->Size, "Size")); + + return S_OK; } [[nodiscard]] HRESULT ApiDispatchers::ServerScrollConsoleScreenBuffer(_Inout_ CONSOLE_API_MSG* const m, @@ -656,6 +752,15 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const auto a = &m->u.consoleMsgL2.ScrollConsoleScreenBuffer; + TraceConsoleAPICallWithOrigin( + "ScrollConsoleScreenBuffer", + TraceLoggingConsoleSmallRect(a->ScrollRectangle, "ScrollRectangle"), + TraceLoggingConsoleSmallRect(a->ClipRectangle, "ClipRectangle"), + TraceLoggingBoolean(a->Clip, "Clip"), + TraceLoggingBoolean(a->Unicode, "Unicode"), + TraceLoggingConsoleCoord(a->DestinationOrigin, "DestinationOrigin"), + TraceLoggingConsoleCharInfo(a->Fill, "Fill")); + const auto pObjectHandle = m->GetObjectHandle(); RETURN_HR_IF_NULL(E_HANDLE, pObjectHandle); @@ -690,16 +795,16 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const auto a = &m->u.consoleMsgL2.SetConsoleTextAttribute; + TraceConsoleAPICallWithOrigin( + "SetConsoleTextAttribute", + TraceLoggingHexUInt16(a->Attributes, "Attributes")); + const auto pObjectHandle = m->GetObjectHandle(); RETURN_HR_IF_NULL(E_HANDLE, pObjectHandle); SCREEN_INFORMATION* pObj; RETURN_IF_FAILED(pObjectHandle->GetScreenBuffer(GENERIC_WRITE, &pObj)); - TraceConsoleAPICallWithOrigin( - "SetConsoleTextAttribute", - TraceLoggingHexUInt16(a->Attributes, "Attributes")); - RETURN_HR(m->_pApiRoutines->SetConsoleTextAttributeImpl(*pObj, a->Attributes)); } @@ -708,20 +813,17 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const auto a = &m->u.consoleMsgL2.SetConsoleWindowInfo; + TraceConsoleAPICallWithOrigin( + "SetConsoleWindowInfo", + TraceLoggingBool(a->Absolute, "IsWindowRectAbsolute"), + TraceLoggingConsoleSmallRect(a->Window, "Window")); + const auto pObjectHandle = m->GetObjectHandle(); RETURN_HR_IF_NULL(E_HANDLE, pObjectHandle); SCREEN_INFORMATION* pObj; RETURN_IF_FAILED(pObjectHandle->GetScreenBuffer(GENERIC_WRITE, &pObj)); - TraceConsoleAPICallWithOrigin( - "SetConsoleWindowInfo", - TraceLoggingBool(a->Absolute, "IsWindowRectAbsolute"), - TraceLoggingInt32(a->Window.Left, "WindowRectLeft"), - TraceLoggingInt32(a->Window.Right, "WindowRectRight"), - TraceLoggingInt32(a->Window.Top, "WindowRectTop"), - TraceLoggingInt32(a->Window.Bottom, "WindowRectBottom")); - return m->_pApiRoutines->SetConsoleWindowInfoImpl(*pObj, a->Absolute, til::wrap_small_rect(a->Window)); } @@ -749,6 +851,10 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) case CONSOLE_ATTRIBUTE: { const std::span buffer(reinterpret_cast(pvBuffer), cbBuffer / sizeof(WORD)); + TraceConsoleAPICallWithOrigin( + "ReadConsoleOutputAttribute", + TraceLoggingConsoleCoord(a->ReadCoord, "ReadCoord"), + TraceLoggingUIntPtr(buffer.size(), "Records")); RETURN_IF_FAILED(m->_pApiRoutines->ReadConsoleOutputAttributeImpl(*pScreenInfo, til::wrap_coord(a->ReadCoord), buffer, written)); break; } @@ -756,12 +862,20 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) case CONSOLE_FALSE_UNICODE: { const std::span buffer(reinterpret_cast(pvBuffer), cbBuffer / sizeof(wchar_t)); + TraceConsoleAPICallWithOrigin( + "ReadConsoleOutputCharacterW", + TraceLoggingConsoleCoord(a->ReadCoord, "ReadCoord"), + TraceLoggingUIntPtr(buffer.size(), "Records")); RETURN_IF_FAILED(m->_pApiRoutines->ReadConsoleOutputCharacterWImpl(*pScreenInfo, til::wrap_coord(a->ReadCoord), buffer, written)); break; } case CONSOLE_ASCII: { const std::span buffer(reinterpret_cast(pvBuffer), cbBuffer); + TraceConsoleAPICallWithOrigin( + "ReadConsoleOutputCharacterA", + TraceLoggingConsoleCoord(a->ReadCoord, "ReadCoord"), + TraceLoggingUIntPtr(buffer.size(), "Records")); RETURN_IF_FAILED(m->_pApiRoutines->ReadConsoleOutputCharacterAImpl(*pScreenInfo, til::wrap_coord(a->ReadCoord), buffer, written)); break; } @@ -798,6 +912,13 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) size_t written; std::span buffer(reinterpret_cast(pvBuffer), cbSize / sizeof(INPUT_RECORD)); + + TraceConsoleAPICallWithOrigin( + "WriteConsoleInput", + TraceLoggingBoolean(a->Unicode, "Unicode"), + TraceLoggingBoolean(a->Append, "Append"), + TraceLoggingUIntPtr(buffer.size(), "Records")); + if (!a->Unicode) { RETURN_IF_FAILED(m->_pApiRoutines->WriteConsoleInputAImpl(*pInputBuffer, buffer, written, !!a->Append)); @@ -841,6 +962,13 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) RETURN_HR_IF(E_INVALIDARG, cbSize < regionBytes); // If given fewer bytes on input than we need to do this write, it's invalid. const std::span buffer(reinterpret_cast(pvBuffer), cbSize / sizeof(CHAR_INFO)); + + TraceConsoleAPICallWithOrigin( + "WriteConsoleOutput", + TraceLoggingBoolean(a->Unicode, "Unicode"), + TraceLoggingConsoleSmallRect(a->CharRegion, "CharRegion"), + TraceLoggingUIntPtr(buffer.size(), "Records")); + if (!a->Unicode) { RETURN_IF_FAILED(m->_pApiRoutines->WriteConsoleOutputAImpl(*pScreenInfo, buffer, originalRegion, writtenRegion)); @@ -883,7 +1011,7 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) TraceConsoleAPICallWithOrigin( "WriteConsoleOutputCharacterA", TraceLoggingConsoleCoord(a->WriteCoord, "WriteCoord"), - TraceLoggingUInt32(a->NumRecords, "NumRecords")); + TraceLoggingCountedString(text.data(), saturate(text.size()), "Buffer")); hr = m->_pApiRoutines->WriteConsoleOutputCharacterAImpl(*pScreenInfo, text, @@ -900,7 +1028,7 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) TraceConsoleAPICallWithOrigin( "WriteConsoleOutputCharacterW", TraceLoggingConsoleCoord(a->WriteCoord, "WriteCoord"), - TraceLoggingUInt32(a->NumRecords, "NumRecords")); + TraceLoggingCountedWideString(text.data(), saturate(text.size()), "Buffer")); hr = m->_pApiRoutines->WriteConsoleOutputCharacterWImpl(*pScreenInfo, text, @@ -916,7 +1044,7 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) TraceConsoleAPICallWithOrigin( "WriteConsoleOutputAttribute", TraceLoggingConsoleCoord(a->WriteCoord, "WriteCoord"), - TraceLoggingUInt32(a->NumRecords, "NumRecords")); + TraceLoggingHexUInt16Array(text.data(), saturate(text.size()), "Buffer")); hr = m->_pApiRoutines->WriteConsoleOutputAttributeImpl(*pScreenInfo, text, @@ -965,6 +1093,13 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) RETURN_HR_IF(E_INVALIDARG, regionArea > 0 && ((regionArea > ULONG_MAX / sizeof(CHAR_INFO)) || (cbBuffer < regionBytes))); std::span buffer(reinterpret_cast(pvBuffer), cbBuffer / sizeof(CHAR_INFO)); + + TraceConsoleAPICallWithOrigin( + "ReadConsoleOutput", + TraceLoggingBoolean(a->Unicode, "Unicode"), + TraceLoggingConsoleSmallRect(a->CharRegion, "CharRegion"), + TraceLoggingUIntPtr(buffer.size(), "Records")); + auto finalRegion = Microsoft::Console::Types::Viewport::Empty(); // the actual region read out of the buffer if (!a->Unicode) { @@ -1016,6 +1151,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) LOG_IF_FAILED(m->_pApiRoutines->GetConsoleTitleWImpl(buffer, written, needed)); } + TraceConsoleAPICallWithOrigin( + "GetConsoleTitleW", + TraceLoggingBoolean(a->Original, "Original"), + TraceLoggingCountedWideString(buffer.data(), saturate(written), "Buffer")); + // We must return the needed length of the title string in the TitleLength. LOG_IF_FAILED(SizeTToULong(needed, &a->TitleLength)); @@ -1036,6 +1176,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) hr = m->_pApiRoutines->GetConsoleTitleAImpl(buffer, written, needed); } + TraceConsoleAPICallWithOrigin( + "GetConsoleTitleA", + TraceLoggingBoolean(a->Original, "Original"), + TraceLoggingCountedString(buffer.data(), saturate(written), "Buffer")); + // We must return the needed length of the title string in the TitleLength. LOG_IF_FAILED(SizeTToULong(needed, &a->TitleLength)); @@ -1059,11 +1204,21 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) if (a->Unicode) { const std::wstring_view title(reinterpret_cast(pvBuffer), cbOriginalLength / sizeof(wchar_t)); + + TraceConsoleAPICallWithOrigin( + "SetConsoleTitleW", + TraceLoggingCountedWideString(title.data(), saturate(title.size()), "Buffer")); + return m->_pApiRoutines->SetConsoleTitleWImpl(title); } else { const std::string_view title(reinterpret_cast(pvBuffer), cbOriginalLength); + + TraceConsoleAPICallWithOrigin( + "SetConsoleTitleA", + TraceLoggingCountedString(title.data(), saturate(title.size()), "Buffer")); + return m->_pApiRoutines->SetConsoleTitleAImpl(title); } } @@ -1074,6 +1229,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) const auto a = &m->u.consoleMsgL3.GetConsoleMouseInfo; m->_pApiRoutines->GetNumberOfConsoleMouseButtonsImpl(a->NumButtons); + + TraceConsoleAPICallWithOrigin( + "GetConsoleMouseInfo", + TraceLoggingUInt32(a->NumButtons, "NumButtons")); + return S_OK; } @@ -1090,7 +1250,14 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) auto size = til::wrap_coord_size(a->FontSize); RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleFontSizeImpl(*pObj, a->FontIndex, size)); - return til::unwrap_coord_size_hr(size, a->FontSize); + RETURN_IF_FAILED_EXPECTED(til::unwrap_coord_size_hr(size, a->FontSize)); + + TraceConsoleAPICallWithOrigin( + "GetConsoleFontSize", + TraceLoggingUInt32(a->FontIndex, "FontIndex"), + TraceLoggingConsoleCoord(a->FontSize, "FontSize")); + + return S_OK; } [[nodiscard]] HRESULT ApiDispatchers::ServerGetConsoleCurrentFont(_Inout_ CONSOLE_API_MSG* const m, @@ -1115,6 +1282,15 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) a->FontSize = FontInfo.dwFontSize; a->FontWeight = FontInfo.FontWeight; + TraceConsoleAPICallWithOrigin( + "GetConsoleFontSize", + TraceLoggingBoolean(a->MaximumWindow, "MaximumWindow"), + TraceLoggingUInt32(a->FontIndex, "FontIndex"), + TraceLoggingConsoleCoord(a->FontSize, "FontSize"), + TraceLoggingUInt32(a->FontFamily, "FontFamily"), + TraceLoggingUInt32(a->FontWeight, "FontWeight"), + TraceLoggingWideString(&a->FaceName[0], "FaceName")); + return S_OK; } @@ -1123,6 +1299,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const auto a = &m->u.consoleMsgL3.SetConsoleDisplayMode; + TraceConsoleAPICallWithOrigin( + "SetConsoleDisplayMode", + TraceLoggingHexUInt32(a->dwFlags, "dwFlags"), + TraceLoggingConsoleCoord(a->ScreenBufferDimensions, "ScreenBufferDimensions")); + const auto pObjectHandle = m->GetObjectHandle(); RETURN_HR_IF_NULL(E_HANDLE, pObjectHandle); @@ -1131,7 +1312,9 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) auto size = til::wrap_coord_size(a->ScreenBufferDimensions); RETURN_IF_FAILED(m->_pApiRoutines->SetConsoleDisplayModeImpl(*pObj, a->dwFlags, size)); - return til::unwrap_coord_size_hr(size, a->ScreenBufferDimensions); + RETURN_IF_FAILED_EXPECTED(til::unwrap_coord_size_hr(size, a->ScreenBufferDimensions)); + + return S_OK; } [[nodiscard]] HRESULT ApiDispatchers::ServerGetConsoleDisplayMode(_Inout_ CONSOLE_API_MSG* const m, @@ -1142,6 +1325,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) // Historically this has never checked the handles. It just returns global state. m->_pApiRoutines->GetConsoleDisplayModeImpl(a->ModeFlags); + + TraceConsoleAPICallWithOrigin( + "GetConsoleDisplayMode", + TraceLoggingHexUInt32(a->ModeFlags, "ModeFlags")); + return S_OK; } @@ -1180,6 +1368,12 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) const std::wstring_view inputSource(reinterpret_cast(pvInputSource), cbInputSource / sizeof(wchar_t)); const std::wstring_view inputTarget(reinterpret_cast(pvInputTarget), cbInputTarget / sizeof(wchar_t)); + TraceConsoleAPICallWithOrigin( + "AddConsoleAliasW", + TraceLoggingCountedWideString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingCountedWideString(inputSource.data(), saturate(inputSource.size()), "Source"), + TraceLoggingCountedWideString(inputTarget.data(), saturate(inputTarget.size()), "Target")); + return m->_pApiRoutines->AddConsoleAliasWImpl(inputSource, inputTarget, inputExeName); } else @@ -1188,6 +1382,12 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) const std::string_view inputSource(pvInputSource, cbInputSource); const std::string_view inputTarget(pvInputTarget, cbInputTarget); + TraceConsoleAPICallWithOrigin( + "AddConsoleAliasA", + TraceLoggingCountedString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingCountedString(inputSource.data(), saturate(inputSource.size()), "Source"), + TraceLoggingCountedString(inputTarget.data(), saturate(inputTarget.size()), "Target")); + return m->_pApiRoutines->AddConsoleAliasAImpl(inputSource, inputTarget, inputExeName); } } @@ -1233,6 +1433,12 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) hr = m->_pApiRoutines->GetConsoleAliasWImpl(inputSource, outputBuffer, cchWritten, inputExeName); + TraceConsoleAPICallWithOrigin( + "GetConsoleAliasW", + TraceLoggingCountedWideString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingCountedWideString(inputSource.data(), saturate(inputSource.size()), "Source"), + TraceLoggingCountedWideString(outputBuffer.data(), saturate(cchWritten), "Output")); + // We must set the reply length in bytes. Convert back from characters. RETURN_IF_FAILED(SizeTMult(cchWritten, sizeof(wchar_t), &cbWritten)); } @@ -1245,6 +1451,12 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) hr = m->_pApiRoutines->GetConsoleAliasAImpl(inputSource, outputBuffer, cchWritten, inputExeName); + TraceConsoleAPICallWithOrigin( + "GetConsoleAliasW", + TraceLoggingCountedString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingCountedString(inputSource.data(), saturate(inputSource.size()), "Source"), + TraceLoggingCountedString(outputBuffer.data(), saturate(cchWritten), "Output")); + cbWritten = cchWritten; } @@ -1281,6 +1493,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) size_t cchAliasesLength; RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleAliasesLengthWImpl(inputExeName, cchAliasesLength)); + TraceConsoleAPICallWithOrigin( + "GetConsoleAliasesLengthW", + TraceLoggingCountedWideString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingUIntPtr(cchAliasesLength, "Length")); + RETURN_IF_FAILED(SizeTMult(cchAliasesLength, sizeof(wchar_t), &cbAliasesLength)); } else @@ -1289,6 +1506,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) size_t cchAliasesLength; RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleAliasesLengthAImpl(inputExeName, cchAliasesLength)); + TraceConsoleAPICallWithOrigin( + "GetConsoleAliasesLengthA", + TraceLoggingCountedString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingUIntPtr(cchAliasesLength, "Length")); + cbAliasesLength = cchAliasesLength; } @@ -1307,12 +1529,22 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { size_t cchAliasExesLength; RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleAliasExesLengthWImpl(cchAliasExesLength)); + + TraceConsoleAPICallWithOrigin( + "GetConsoleAliasExesLengthW", + TraceLoggingUIntPtr(cchAliasExesLength, "Length")); + cbAliasExesLength = cchAliasExesLength * sizeof(wchar_t); } else { size_t cchAliasExesLength; RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleAliasExesLengthAImpl(cchAliasExesLength)); + + TraceConsoleAPICallWithOrigin( + "GetConsoleAliasExesLengthA", + TraceLoggingUIntPtr(cchAliasExesLength, "Length")); + cbAliasExesLength = cchAliasExesLength; } @@ -1343,6 +1575,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleAliasesWImpl(inputExeName, outputBuffer, cchWritten)); + TraceConsoleAPICallWithOrigin( + "GetConsoleAliasesW", + TraceLoggingCountedWideString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingCountedWideString(outputBuffer.data(), saturate(cchWritten), "Output")); + // We must set the reply length in bytes. Convert back from characters. RETURN_IF_FAILED(SizeTMult(cchWritten, sizeof(wchar_t), &cbWritten)); } @@ -1354,6 +1591,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleAliasesAImpl(inputExeName, outputBuffer, cchWritten)); + TraceConsoleAPICallWithOrigin( + "GetConsoleAliasesA", + TraceLoggingCountedString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingCountedString(outputBuffer.data(), saturate(cchWritten), "Output")); + cbWritten = cchWritten; } @@ -1380,6 +1622,10 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) size_t cchWritten; RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleAliasExesWImpl(outputBuffer, cchWritten)); + TraceConsoleAPICallWithOrigin( + "GetConsoleAliasExesW", + TraceLoggingCountedWideString(outputBuffer.data(), saturate(cchWritten), "Output")); + RETURN_IF_FAILED(SizeTMult(cchWritten, sizeof(wchar_t), &cbWritten)); } else @@ -1388,6 +1634,10 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) size_t cchWritten; RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleAliasExesAImpl(outputBuffer, cchWritten)); + TraceConsoleAPICallWithOrigin( + "GetConsoleAliasExesA", + TraceLoggingCountedString(outputBuffer.data(), saturate(cchWritten), "Output")); + cbWritten = cchWritten; } @@ -1412,12 +1662,20 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const std::wstring_view inputExeName(reinterpret_cast(pvExeName), cbExeNameLength / sizeof(wchar_t)); + TraceConsoleAPICallWithOrigin( + "ExpungeConsoleCommandHistoryW", + TraceLoggingCountedWideString(inputExeName.data(), saturate(inputExeName.size()), "ExeName")); + return m->_pApiRoutines->ExpungeConsoleCommandHistoryWImpl(inputExeName); } else { const std::string_view inputExeName(reinterpret_cast(pvExeName), cbExeNameLength); + TraceConsoleAPICallWithOrigin( + "ExpungeConsoleCommandHistoryA", + TraceLoggingCountedString(inputExeName.data(), saturate(inputExeName.size()), "ExeName")); + return m->_pApiRoutines->ExpungeConsoleCommandHistoryAImpl(inputExeName); } } @@ -1426,6 +1684,7 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) _Inout_ BOOL* const /*pbReplyPending*/) { const auto a = &m->u.consoleMsgL3.SetConsoleNumberOfCommandsW; + PVOID pvExeName; ULONG cbExeNameLength; RETURN_IF_FAILED(m->GetInputBuffer(&pvExeName, &cbExeNameLength)); @@ -1435,12 +1694,22 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const std::wstring_view inputExeName(reinterpret_cast(pvExeName), cbExeNameLength / sizeof(wchar_t)); + TraceConsoleAPICallWithOrigin( + "SetConsoleNumberOfCommandsW", + TraceLoggingCountedWideString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingUInt32(a->NumCommands, "NumCommands")); + return m->_pApiRoutines->SetConsoleNumberOfCommandsWImpl(inputExeName, NumberOfCommands); } else { const std::string_view inputExeName(reinterpret_cast(pvExeName), cbExeNameLength); + TraceConsoleAPICallWithOrigin( + "SetConsoleNumberOfCommandsA", + TraceLoggingCountedString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingUInt32(a->NumCommands, "NumCommands")); + return m->_pApiRoutines->SetConsoleNumberOfCommandsAImpl(inputExeName, NumberOfCommands); } } @@ -1462,6 +1731,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleCommandHistoryLengthWImpl(inputExeName, cchCommandHistoryLength)); + TraceConsoleAPICallWithOrigin( + "GetConsoleCommandHistoryLengthW", + TraceLoggingCountedWideString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingUIntPtr(cchCommandHistoryLength, "CommandHistoryLength")); + // We must set the reply length in bytes. Convert back from characters. RETURN_IF_FAILED(SizeTMult(cchCommandHistoryLength, sizeof(wchar_t), &cbCommandHistoryLength)); } @@ -1472,6 +1746,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleCommandHistoryLengthAImpl(inputExeName, cchCommandHistoryLength)); + TraceConsoleAPICallWithOrigin( + "GetConsoleCommandHistoryLengthA", + TraceLoggingCountedString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingUIntPtr(cchCommandHistoryLength, "CommandHistoryLength")); + cbCommandHistoryLength = cchCommandHistoryLength; } @@ -1502,6 +1781,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) size_t cchWritten; RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleCommandHistoryWImpl(inputExeName, outputBuffer, cchWritten)); + TraceConsoleAPICallWithOrigin( + "GetConsoleCommandHistoryW", + TraceLoggingCountedWideString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingCountedWideString(outputBuffer.data(), saturate(cchWritten), "Output")); + // We must set the reply length in bytes. Convert back from characters. RETURN_IF_FAILED(SizeTMult(cchWritten, sizeof(wchar_t), &cbWritten)); } @@ -1512,6 +1796,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) size_t cchWritten; RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleCommandHistoryAImpl(inputExeName, outputBuffer, cchWritten)); + TraceConsoleAPICallWithOrigin( + "GetConsoleCommandHistory", + TraceLoggingCountedString(inputExeName.data(), saturate(inputExeName.size()), "ExeName"), + TraceLoggingCountedString(outputBuffer.data(), saturate(cchWritten), "Output")); + cbWritten = cchWritten; } @@ -1529,6 +1818,11 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) const auto a = &m->u.consoleMsgL3.GetConsoleWindow; m->_pApiRoutines->GetConsoleWindowImpl(a->hwnd); + + TraceConsoleAPICallWithOrigin( + "GetConsoleWindow", + TraceLoggingPointer(a->hwnd, "hwnd")); + return S_OK; } @@ -1538,6 +1832,14 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) const auto a = &m->u.consoleMsgL3.GetConsoleSelectionInfo; m->_pApiRoutines->GetConsoleSelectionInfoImpl(a->SelectionInfo); + + TraceConsoleAPICallWithOrigin( + "GetConsoleSelectionInfo", + TraceLoggingStruct(3, "SelectionInfo"), + TraceLoggingUInt32(a->SelectionInfo.dwFlags, "dwFlags"), + TraceLoggingConsoleCoord(a->SelectionInfo.dwSelectionAnchor, "dwSelectionAnchor"), + TraceLoggingConsoleSmallRect(a->SelectionInfo.srSelection, "srSelection")); + return S_OK; } @@ -1555,6 +1857,12 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) a->HistoryBufferSize = info.HistoryBufferSize; a->NumberOfHistoryBuffers = info.NumberOfHistoryBuffers; + TraceConsoleAPICallWithOrigin( + "GetConsoleHistory", + TraceLoggingUInt32(a->HistoryBufferSize, "HistoryBufferSize"), + TraceLoggingUInt32(a->NumberOfHistoryBuffers, "NumberOfHistoryBuffers"), + TraceLoggingUInt32(a->dwFlags, "dwFlags")); + return S_OK; } @@ -1563,6 +1871,12 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const auto a = &m->u.consoleMsgL3.SetConsoleHistory; + TraceConsoleAPICallWithOrigin( + "SetConsoleHistory", + TraceLoggingUInt32(a->HistoryBufferSize, "HistoryBufferSize"), + TraceLoggingUInt32(a->NumberOfHistoryBuffers, "NumberOfHistoryBuffers"), + TraceLoggingUInt32(a->dwFlags, "dwFlags")); + CONSOLE_HISTORY_INFO info; info.cbSize = sizeof(info); info.dwFlags = a->dwFlags; @@ -1577,6 +1891,15 @@ static DWORD TraceGetThreadId(CONSOLE_API_MSG* const m) { const auto a = &m->u.consoleMsgL3.SetCurrentConsoleFont; + TraceConsoleAPICallWithOrigin( + "SetCurrentConsoleFont", + TraceLoggingBoolean(a->MaximumWindow, "MaximumWindow"), + TraceLoggingUInt32(a->FontIndex, "FontIndex"), + TraceLoggingConsoleCoord(a->FontSize, "FontSize"), + TraceLoggingUInt32(a->FontFamily, "FontFamily"), + TraceLoggingUInt32(a->FontWeight, "FontWeight"), + TraceLoggingWideString(&a->FaceName[0], "FaceName")); + const auto pObjectHandle = m->GetObjectHandle(); RETURN_HR_IF_NULL(E_HANDLE, pObjectHandle);