Skip to content

Commit

Permalink
Merge ReadConsoleA/W API routines (#15780)
Browse files Browse the repository at this point in the history
This is a minor cleanup to deduplicate the two ReadConsole methods
and will help with making changes to how `COOKED_READ_DATA` is called.
It additionally changes the initial data payload from a `string_view`
to a `wstring_view` as it is guaranteed to be `wchar_t`.
This matches the current `COOKED_READ_DATA` implementation which
blindly assumes that the initial data consists of `wchar_t`.

Closes #5618
  • Loading branch information
lhecker committed Aug 1, 2023
1 parent a4340af commit 07566fa
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 185 deletions.
3 changes: 1 addition & 2 deletions src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp
Expand Up @@ -2891,8 +2891,7 @@ void ConptyRoundtripTests::TestResizeWithCookedRead()
m_state->PrepareReadHandle();
// TODO GH#5618: This string will get mangled, but we don't really care
// about the buffer contents in this test, so it doesn't really matter.
const std::string_view cookedReadContents{ "This is some cooked read data" };
m_state->PrepareCookedReadData(cookedReadContents);
m_state->PrepareCookedReadData(L"This is some cooked read data");

Log::Comment(L"Painting the frame");
VERIFY_SUCCEEDED(renderer.PaintFrame());
Expand Down
32 changes: 11 additions & 21 deletions src/host/ApiRoutines.h
Expand Up @@ -57,27 +57,17 @@ class ApiRoutines : public IApiRoutines
const bool IsPeek,
std::unique_ptr<IWaitRoutine>& waiter) noexcept override;

[[nodiscard]] HRESULT ReadConsoleAImpl(IConsoleInputObject& context,
std::span<char> buffer,
size_t& written,
std::unique_ptr<IWaitRoutine>& waiter,
const std::string_view initialData,
const std::wstring_view exeName,
INPUT_READ_HANDLE_DATA& readHandleState,
const HANDLE clientHandle,
const DWORD controlWakeupMask,
DWORD& controlKeyState) noexcept override;

[[nodiscard]] HRESULT ReadConsoleWImpl(IConsoleInputObject& context,
std::span<char> buffer,
size_t& written,
std::unique_ptr<IWaitRoutine>& waiter,
const std::string_view initialData,
const std::wstring_view exeName,
INPUT_READ_HANDLE_DATA& readHandleState,
const HANDLE clientHandle,
const DWORD controlWakeupMask,
DWORD& controlKeyState) noexcept override;
[[nodiscard]] HRESULT ReadConsoleImpl(IConsoleInputObject& context,
std::span<char> buffer,
size_t& written,
std::unique_ptr<IWaitRoutine>& waiter,
const std::wstring_view initialData,
const std::wstring_view exeName,
INPUT_READ_HANDLE_DATA& readHandleState,
const bool IsUnicode,
const HANDLE clientHandle,
const DWORD controlWakeupMask,
DWORD& controlKeyState) noexcept override;

[[nodiscard]] HRESULT WriteConsoleAImpl(IConsoleOutputObject& context,
const std::string_view buffer,
Expand Down
49 changes: 13 additions & 36 deletions src/host/VtApiRoutines.cpp
Expand Up @@ -119,42 +119,19 @@ void VtApiRoutines::_SynchronizeCursor(std::unique_ptr<IWaitRoutine>& waiter) no
return hr;
}

[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleAImpl(IConsoleInputObject& context,
std::span<char> buffer,
size_t& written,
std::unique_ptr<IWaitRoutine>& waiter,
const std::string_view initialData,
const std::wstring_view exeName,
INPUT_READ_HANDLE_DATA& readHandleState,
const HANDLE clientHandle,
const DWORD controlWakeupMask,
DWORD& controlKeyState) noexcept
{
const auto hr = m_pUsualRoutines->ReadConsoleAImpl(context, buffer, written, waiter, initialData, exeName, readHandleState, clientHandle, controlWakeupMask, controlKeyState);
// If we're about to tell the caller to wait, let's synchronize the cursor we have with what
// the terminal is presenting in case there's a cooked read going on.
// TODO GH10001: we only need to do this in cooked read mode.
if (clientHandle)
{
m_listeningForDSR = true;
(void)m_pVtEngine->_ListenForDSR();
(void)m_pVtEngine->RequestCursor();
}
return hr;
}

[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleWImpl(IConsoleInputObject& context,
std::span<char> buffer,
size_t& written,
std::unique_ptr<IWaitRoutine>& waiter,
const std::string_view initialData,
const std::wstring_view exeName,
INPUT_READ_HANDLE_DATA& readHandleState,
const HANDLE clientHandle,
const DWORD controlWakeupMask,
DWORD& controlKeyState) noexcept
{
const auto hr = m_pUsualRoutines->ReadConsoleWImpl(context, buffer, written, waiter, initialData, exeName, readHandleState, clientHandle, controlWakeupMask, controlKeyState);
[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleImpl(IConsoleInputObject& context,
std::span<char> buffer,
size_t& written,
std::unique_ptr<IWaitRoutine>& waiter,
const std::wstring_view initialData,
const std::wstring_view exeName,
INPUT_READ_HANDLE_DATA& readHandleState,
const bool IsUnicode,
const HANDLE clientHandle,
const DWORD controlWakeupMask,
DWORD& controlKeyState) noexcept
{
const auto hr = m_pUsualRoutines->ReadConsoleImpl(context, buffer, written, waiter, initialData, exeName, readHandleState, IsUnicode, clientHandle, controlWakeupMask, controlKeyState);
// If we're about to tell the caller to wait, let's synchronize the cursor we have with what
// the terminal is presenting in case there's a cooked read going on.
// TODO GH10001: we only need to do this in cooked read mode.
Expand Down
32 changes: 11 additions & 21 deletions src/host/VtApiRoutines.h
Expand Up @@ -60,27 +60,17 @@ class VtApiRoutines : public IApiRoutines
const bool IsPeek,
std::unique_ptr<IWaitRoutine>& waiter) noexcept override;

[[nodiscard]] HRESULT ReadConsoleAImpl(IConsoleInputObject& context,
std::span<char> buffer,
size_t& written,
std::unique_ptr<IWaitRoutine>& waiter,
const std::string_view initialData,
const std::wstring_view exeName,
INPUT_READ_HANDLE_DATA& readHandleState,
const HANDLE clientHandle,
const DWORD controlWakeupMask,
DWORD& controlKeyState) noexcept override;

[[nodiscard]] HRESULT ReadConsoleWImpl(IConsoleInputObject& context,
std::span<char> buffer,
size_t& written,
std::unique_ptr<IWaitRoutine>& waiter,
const std::string_view initialData,
const std::wstring_view exeName,
INPUT_READ_HANDLE_DATA& readHandleState,
const HANDLE clientHandle,
const DWORD controlWakeupMask,
DWORD& controlKeyState) noexcept override;
[[nodiscard]] HRESULT ReadConsoleImpl(IConsoleInputObject& context,
std::span<char> buffer,
size_t& written,
std::unique_ptr<IWaitRoutine>& waiter,
const std::wstring_view initialData,
const std::wstring_view exeName,
INPUT_READ_HANDLE_DATA& readHandleState,
const bool IsUnicode,
const HANDLE clientHandle,
const DWORD controlWakeupMask,
DWORD& controlKeyState) noexcept override;

[[nodiscard]] HRESULT WriteConsoleAImpl(IConsoleOutputObject& context,
const std::string_view buffer,
Expand Down
8 changes: 4 additions & 4 deletions src/host/readDataCooked.cpp
Expand Up @@ -50,7 +50,7 @@ COOKED_READ_DATA::COOKED_READ_DATA(_In_ InputBuffer* const pInputBuffer,
_In_ char* UserBuffer,
_In_ ULONG CtrlWakeupMask,
_In_ const std::wstring_view exeName,
_In_ const std::string_view initialData,
_In_ const std::wstring_view initialData,
_In_ ConsoleProcessHandle* const pClientProcess) :
ReadData(pInputBuffer, pInputReadHandleData),
_screenInfo{ screenInfo },
Expand Down Expand Up @@ -97,11 +97,11 @@ COOKED_READ_DATA::COOKED_READ_DATA(_In_ InputBuffer* const pInputBuffer,

if (!initialData.empty())
{
memcpy_s(_bufPtr, _bufferSize, initialData.data(), initialData.size());
memcpy_s(_bufPtr, _bufferSize, initialData.data(), initialData.size() * 2);

_bytesRead += initialData.size();
_bytesRead += initialData.size() * 2;

const auto cchInitialData = initialData.size() / sizeof(wchar_t);
const auto cchInitialData = initialData.size();
VisibleCharCount() = cchInitialData;
_bufPtr += cchInitialData;
_currentPosition = cchInitialData;
Expand Down
2 changes: 1 addition & 1 deletion src/host/readDataCooked.hpp
Expand Up @@ -40,7 +40,7 @@ class COOKED_READ_DATA final : public ReadData
_In_ char* UserBuffer,
_In_ ULONG CtrlWakeupMask,
_In_ const std::wstring_view exeName,
_In_ const std::string_view initialData,
_In_ const std::wstring_view initialData,
_In_ ConsoleProcessHandle* const pClientProcess);

~COOKED_READ_DATA() override;
Expand Down
79 changes: 24 additions & 55 deletions src/host/stream.cpp
Expand Up @@ -354,7 +354,7 @@ NT_CATCH_RETURN()
std::span<char> buffer,
size_t& bytesRead,
DWORD& controlKeyState,
const std::string_view initialData,
const std::wstring_view initialData,
const DWORD ctrlWakeupMask,
INPUT_READ_HANDLE_DATA& readHandleState,
const std::wstring_view exeName,
Expand Down Expand Up @@ -492,7 +492,7 @@ NT_CATCH_RETURN()
std::span<char> buffer,
size_t& bytesRead,
ULONG& controlKeyState,
const std::string_view initialData,
const std::wstring_view initialData,
const DWORD ctrlWakeupMask,
INPUT_READ_HANDLE_DATA& readHandleState,
const std::wstring_view exeName,
Expand Down Expand Up @@ -552,60 +552,29 @@ NT_CATCH_RETURN()
CATCH_RETURN();
}

[[nodiscard]] HRESULT ApiRoutines::ReadConsoleAImpl(IConsoleInputObject& context,
std::span<char> buffer,
size_t& written,
std::unique_ptr<IWaitRoutine>& waiter,
const std::string_view initialData,
const std::wstring_view exeName,
INPUT_READ_HANDLE_DATA& readHandleState,
const HANDLE clientHandle,
const DWORD controlWakeupMask,
DWORD& controlKeyState) noexcept
[[nodiscard]] HRESULT ApiRoutines::ReadConsoleImpl(IConsoleInputObject& context,
std::span<char> buffer,
size_t& written,
std::unique_ptr<IWaitRoutine>& waiter,
const std::wstring_view initialData,
const std::wstring_view exeName,
INPUT_READ_HANDLE_DATA& readHandleState,
const bool IsUnicode,
const HANDLE clientHandle,
const DWORD controlWakeupMask,
DWORD& controlKeyState) noexcept
{
try
{
return HRESULT_FROM_NT(DoReadConsole(context,
clientHandle,
buffer,
written,
controlKeyState,
initialData,
controlWakeupMask,
readHandleState,
exeName,
false,
waiter));
}
CATCH_RETURN();
}

[[nodiscard]] HRESULT ApiRoutines::ReadConsoleWImpl(IConsoleInputObject& context,
std::span<char> buffer,
size_t& written,
std::unique_ptr<IWaitRoutine>& waiter,
const std::string_view initialData,
const std::wstring_view exeName,
INPUT_READ_HANDLE_DATA& readHandleState,
const HANDLE clientHandle,
const DWORD controlWakeupMask,
DWORD& controlKeyState) noexcept
{
try
{
return HRESULT_FROM_NT(DoReadConsole(context,
clientHandle,
buffer,
written,
controlKeyState,
initialData,
controlWakeupMask,
readHandleState,
exeName,
true,
waiter));
}
CATCH_RETURN();
return HRESULT_FROM_NT(DoReadConsole(context,
clientHandle,
buffer,
written,
controlKeyState,
initialData,
controlWakeupMask,
readHandleState,
exeName,
IsUnicode,
waiter));
}

void UnblockWriteConsole(const DWORD dwReason)
Expand Down
2 changes: 1 addition & 1 deletion src/inc/test/CommonState.hpp
Expand Up @@ -144,7 +144,7 @@ class CommonState
delete gci.pInputBuffer;
}

void PrepareCookedReadData(const std::string_view initialData = {})
void PrepareCookedReadData(const std::wstring_view initialData = {})
{
CONSOLE_INFORMATION& gci = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals().getConsoleInformation();
auto* readData = new COOKED_READ_DATA(gci.pInputBuffer,
Expand Down

0 comments on commit 07566fa

Please sign in to comment.