Repository: microsoft/terminal
File: src/server/ApiDispatchers.cpp (C++)

Code before:
    const auto cbInitialData = a->InitialNumBytes;
    std::unique_ptr<char[]> pbInitialData;

    try
    {
        if (cbInitialData > 0)
        {
            pbInitialData = std::make_unique<char[]>(cbInitialData);

            // This parameter starts immediately after the exe name so skip by that many bytes.
            RETURN_IF_FAILED(m->ReadMessageInput(cbExeName, pbInitialData.get(), cbInitialData));
        }
    }
    CATCH_RETURN();

    // 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();

    // ReadConsole needs this to store context information across "processed reads" e.g. reads on the same handle
    // across multiple calls when we are simulating a command prompt input line for the client application.
    const auto pInputReadHandleData = HandleData->GetClientInput();

    std::unique_ptr<IWaitRoutine> waiter;
    size_t cbWritten;

    const std::wstring_view initialData(reinterpret_cast<const wchar_t*>(pbInitialData.get()), cbInitialData / sizeof(wchar_t));
    const std::span<char> outputBuffer(reinterpret_cast<char*>(pvBuffer), cbBufferSize);
    auto hr = m->_pApiRoutines->ReadConsoleImpl(*pInputBuffer,
                                                outputBuffer,
                                                cbWritten, // We must set the reply length in bytes.
                                                waiter,
                                                initialData,
                                                exeView,
                                                *pInputReadHandleData,
                                                a->Unicode,
                                                hConsoleClient,
                                                a->CtrlWakeupMask,
                                                a->ControlKeyState);

    LOG_IF_FAILED(SizeTToULong(cbWritten, &a->NumBytes));

    if (nullptr != waiter.get())
    {
        // If we received a waiter, we need to queue the wait and not reply.
        hr = ConsoleWaitQueue::s_CreateWait(m, waiter.release());

        if (SUCCEEDED(hr))
        {
            *pbReplyPending = TRUE;
        }
    }

Review comment (suggestion):
```suggestion
    // initialData is only supported for ReadConsoleW, so we can safely assume that it is a wchar_t* here
    const std::wstring_view initialData(reinterpret_cast<const wchar_t*>(pbInitialData.get()), cbInitialData / sizeof(wchar_t));
```

Code after:
    std::unique_ptr<char[]> pbInitialData;
    std::wstring_view initialData;

    try
    {
        const auto cbInitialData = a->InitialNumBytes;
        if (cbInitialData > 0)
        {
            // InitialNumBytes is only supported for ReadConsoleW (via CONSOLE_READCONSOLE_CONTROL::nInitialChars).
            RETURN_HR_IF(E_INVALIDARG, !a->Unicode);

            pbInitialData = std::make_unique<char[]>(cbInitialData);

            // This parameter starts immediately after the exe name so skip by that many bytes.
            RETURN_IF_FAILED(m->ReadMessageInput(cbExeName, pbInitialData.get(), cbInitialData));

            initialData = { reinterpret_cast<const wchar_t*>(pbInitialData.get()), cbInitialData / sizeof(wchar_t) };
        }
    }
    CATCH_RETURN();

    // 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();

    // ReadConsole needs this to store context information across "processed reads" e.g. reads on the same handle
    // across multiple calls when we are simulating a command prompt input line for the client application.
    const auto pInputReadHandleData = HandleData->GetClientInput();

    std::unique_ptr<IWaitRoutine> waiter;
    size_t cbWritten;

    const std::span<char> outputBuffer(reinterpret_cast<char*>(pvBuffer), cbBufferSize);
    auto hr = m->_pApiRoutines->ReadConsoleImpl(*pInputBuffer,
                                                outputBuffer,
                                                cbWritten, // We must set the reply length in bytes.
                                                waiter,
                                                initialData,
                                                exeView,
                                                *pInputReadHandleData,
                                                a->Unicode,
                                                hConsoleClient,
                                                a->CtrlWakeupMask,
                                                a->ControlKeyState);

    LOG_IF_FAILED(SizeTToULong(cbWritten, &a->NumBytes));

    if (nullptr != waiter.get())
    {
        // If we received a waiter, we need to queue the wait and not reply.
        hr = ConsoleWaitQueue::s_CreateWait(m, waiter.release());