cb037f3953
This fixes an issue where two CPRs could end up corrupted in the input buffer. An application that sent two CPRs back-to-back could end up reading the first few characters of the first prepended CPR before handing us another CPR. We would dutifully prepend it to the buffer, causing them to overlap. ``` ^[^[2;2R[1;1R ^^ ^^^^^ First CPR ^^^^^^ Second CPR ``` The end result of this corruption is that a requesting application would receive an unbidden `R` on stdin; for vim, this would trigger replace mode immediately on startup. Response prepending was implemented in !997738 without much comment. There's very little in the way of audit trail as to why we switched. Michael believes that we wanted to make sure that applications got DSR responses immediately. It had the unfortunate side effect of causing subsequence CPRs across cursor moves to come out in the wrong order. I discussed our options with him, and he suggested that we could implement a priority queue in InputBuffer and make sure that "response" input was dispatched to a client application before any application- or user-generated input. This was deemed to be too much work. We decided that DSR responses getting top billing was likely to be a stronger guarantee than most terminals are capable of giving, and that we should be fine if we just switch it back to append. Thanks to @k-takata, @tekki and @brammool for the investigation on the vim side. Fixes #1637.
36 lines
1.3 KiB
C++
36 lines
1.3 KiB
C++
/*++
|
|
Copyright (c) Microsoft Corporation
|
|
Licensed under the MIT license.
|
|
|
|
Module Name:
|
|
- directio.h
|
|
|
|
Abstract:
|
|
- This file implements the NT console direct I/O API (read/write STDIO streams)
|
|
|
|
Author:
|
|
- KazuM Apr.19.1996
|
|
|
|
Revision History:
|
|
--*/
|
|
|
|
#pragma once
|
|
|
|
#include "conapi.h"
|
|
#include "inputBuffer.hpp"
|
|
|
|
class SCREEN_INFORMATION;
|
|
|
|
[[nodiscard]] HRESULT DoSrvPrivateWriteConsoleInputW(_Inout_ InputBuffer* const pInputBuffer,
|
|
_Inout_ std::deque<std::unique_ptr<IInputEvent>>& events,
|
|
_Out_ size_t& eventsWritten,
|
|
const bool append) noexcept;
|
|
|
|
[[nodiscard]] NTSTATUS ConsoleCreateScreenBuffer(std::unique_ptr<ConsoleHandleData>& handle,
|
|
_In_ PCONSOLE_API_MSG Message,
|
|
_In_ PCD_CREATE_OBJECT_INFORMATION Information,
|
|
_In_ PCONSOLE_CREATESCREENBUFFER_MSG a);
|
|
|
|
[[nodiscard]] NTSTATUS DoSrvPrivateWriteConsoleControlInput(_Inout_ InputBuffer* const pInputBuffer,
|
|
_In_ KeyEvent key);
|