ReactOS 0.4.15-dev-7953-g1f49173
coninput.c File Reference
#include "consrv.h"
#include <debug.h>
Include dependency graph for coninput.c:

Go to the source code of this file.

Classes

struct  _GET_INPUT_INFO
 

Macros

#define NDEBUG
 
#define ConSrvGetInputBuffer(ProcessData, Handle, Ptr, Access, LockConsole)
 
#define ConSrvGetInputBufferAndHandleEntry(ProcessData, Handle, Ptr, Entry, Access, LockConsole)
 
#define ConSrvReleaseInputBuffer(Buff, IsConsoleLocked)    ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked))
 
#define ConsoleInputUnicodeToAnsiChar(Console, dChar, sWChar)
 
#define ConsoleInputAnsiToUnicodeChar(Console, dWChar, sChar)
 

Typedefs

typedef struct _GET_INPUT_INFO GET_INPUT_INFO
 
typedef struct _GET_INPUT_INFOPGET_INPUT_INFO
 

Functions

static VOID ConioInputEventToAnsi (PCONSOLE Console, PINPUT_RECORD InputEvent)
 
static VOID ConioInputEventToUnicode (PCONSOLE Console, PINPUT_RECORD InputEvent)
 
static ULONG PreprocessInput (PCONSRV_CONSOLE Console, PINPUT_RECORD InputEvent, ULONG NumEventsToWrite)
 
static VOID PostprocessInput (PCONSRV_CONSOLE Console)
 
NTSTATUS NTAPI ConDrvWriteConsoleInput (IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer, IN BOOLEAN AppendToEnd, IN PINPUT_RECORD InputRecord, IN ULONG NumEventsToWrite, OUT PULONG NumEventsWritten OPTIONAL)
 
static NTSTATUS ConioAddInputEvents (PCONSRV_CONSOLE Console, PINPUT_RECORD InputRecords, ULONG NumEventsToWrite, PULONG NumEventsWritten, BOOLEAN AppendToEnd)
 
NTSTATUS ConioProcessInputEvent (PCONSRV_CONSOLE Console, PINPUT_RECORD InputEvent)
 
static NTSTATUS WaitBeforeReading (IN PGET_INPUT_INFO InputInfo, IN PCSR_API_MESSAGE ApiMessage, IN CSR_WAIT_FUNCTION WaitFunction OPTIONAL, IN BOOLEAN CreateWaitBlock OPTIONAL)
 
static NTSTATUS ReadChars (IN PGET_INPUT_INFO InputInfo, IN PCSR_API_MESSAGE ApiMessage, IN BOOLEAN CreateWaitBlock OPTIONAL)
 
static BOOLEAN NTAPI ReadCharsThread (IN PLIST_ENTRY WaitList, IN PCSR_THREAD WaitThread, IN PCSR_API_MESSAGE WaitApiMessage, IN PVOID WaitContext, IN PVOID WaitArgument1, IN PVOID WaitArgument2, IN ULONG WaitFlags)
 
NTSTATUS NTAPI ConDrvReadConsole (IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer, IN BOOLEAN Unicode, OUT PVOID Buffer, IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl, IN PVOID Parameter OPTIONAL, IN ULONG NumCharsToRead, OUT PULONG NumCharsRead OPTIONAL)
 
static NTSTATUS ReadInputBuffer (IN PGET_INPUT_INFO InputInfo, IN PCSR_API_MESSAGE ApiMessage, IN BOOLEAN CreateWaitBlock OPTIONAL)
 
static BOOLEAN NTAPI ReadInputBufferThread (IN PLIST_ENTRY WaitList, IN PCSR_THREAD WaitThread, IN PCSR_API_MESSAGE WaitApiMessage, IN PVOID WaitContext, IN PVOID WaitArgument1, IN PVOID WaitArgument2, IN ULONG WaitFlags)
 
NTSTATUS NTAPI ConDrvGetConsoleInput (IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer, IN BOOLEAN KeepEvents, IN BOOLEAN WaitForMoreEvents, OUT PINPUT_RECORD InputRecord, IN ULONG NumEventsToRead, OUT PULONG NumEventsRead OPTIONAL)
 
 CON_API (SrvReadConsole, CONSOLE_READCONSOLE, ReadConsoleRequest)
 
 CON_API (SrvGetConsoleInput, CONSOLE_GETINPUT, GetInputRequest)
 
 CON_API (SrvWriteConsoleInput, CONSOLE_WRITEINPUT, WriteInputRequest)
 
NTSTATUS NTAPI ConDrvFlushConsoleInputBuffer (IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer)
 
 CON_API (SrvFlushConsoleInputBuffer, CONSOLE_FLUSHINPUTBUFFER, FlushInputBufferRequest)
 
NTSTATUS NTAPI ConDrvGetConsoleNumberOfInputEvents (IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer, OUT PULONG NumberOfEvents)
 
 CON_API (SrvGetConsoleNumberOfInputEvents, CONSOLE_GETNUMINPUTEVENTS, GetNumInputEventsRequest)
 

Macro Definition Documentation

◆ ConsoleInputAnsiToUnicodeChar

#define ConsoleInputAnsiToUnicodeChar (   Console,
  dWChar,
  sChar 
)
Value:
do { \
ASSERT((ULONG_PTR)(dWChar) != (ULONG_PTR)(sChar)); \
MultiByteToWideChar((Console)->InputCodePage, 0, (sChar), 1, (dWChar), 1); \
} while (0)
CConsole Console
UINT InputCodePage
Definition: console.c:25
uint32_t ULONG_PTR
Definition: typedefs.h:65

Definition at line 43 of file coninput.c.

◆ ConsoleInputUnicodeToAnsiChar

#define ConsoleInputUnicodeToAnsiChar (   Console,
  dChar,
  sWChar 
)
Value:
do { \
ASSERT((ULONG_PTR)(dChar) != (ULONG_PTR)(sWChar)); \
WideCharToMultiByte((Console)->InputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL); \
} while (0)
#define NULL
Definition: types.h:112

Definition at line 37 of file coninput.c.

◆ ConSrvGetInputBuffer

#define ConSrvGetInputBuffer (   ProcessData,
  Handle,
  Ptr,
  Access,
  LockConsole 
)
Value:
ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), NULL, \
(Access), (LockConsole), INPUT_BUFFER)
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
ULONG Handle
Definition: gdb_input.c:15
NTSTATUS ConSrvGetObject(IN PCONSOLE_PROCESS_DATA ProcessData, IN HANDLE Handle, OUT PCONSOLE_IO_OBJECT *Object, OUT PVOID *Entry OPTIONAL, IN ULONG Access, IN BOOLEAN LockConsole, IN CONSOLE_IO_OBJECT_TYPE Type)
Definition: handle.c:318
@ INPUT_BUFFER
Definition: conio.h:28

Definition at line 19 of file coninput.c.

◆ ConSrvGetInputBufferAndHandleEntry

#define ConSrvGetInputBufferAndHandleEntry (   ProcessData,
  Handle,
  Ptr,
  Entry,
  Access,
  LockConsole 
)
Value:
ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), (Entry), \
(Access), (LockConsole), INPUT_BUFFER)
base of all file and directory entries
Definition: entries.h:83

Definition at line 23 of file coninput.c.

◆ ConSrvReleaseInputBuffer

#define ConSrvReleaseInputBuffer (   Buff,
  IsConsoleLocked 
)     ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked))

Definition at line 27 of file coninput.c.

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file coninput.c.

Typedef Documentation

◆ GET_INPUT_INFO

◆ PGET_INPUT_INFO

Function Documentation

◆ CON_API() [1/5]

CON_API ( SrvFlushConsoleInputBuffer  ,
CONSOLE_FLUSHINPUTBUFFER  ,
FlushInputBufferRequest   
)

Definition at line 807 of file coninput.c.

809{
812
813 Status = ConSrvGetInputBuffer(ProcessData,
814 FlushInputBufferRequest->InputHandle,
816 if (!NT_SUCCESS(Status))
817 return Status;
818
819 ASSERT((PCONSOLE)Console == InputBuffer->Header.Console);
820
822
824 return Status;
825}
LONG NTSTATUS
Definition: precomp.h:26
#define ConSrvReleaseInputBuffer(Buff, IsConsoleLocked)
Definition: coninput.c:27
#define ConSrvGetInputBuffer(ProcessData, Handle, Ptr, Access, LockConsole)
Definition: coninput.c:19
NTSTATUS NTAPI ConDrvFlushConsoleInputBuffer(IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer)
Definition: coninput.c:357
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
#define ASSERT(a)
Definition: mode.c:44
#define GENERIC_WRITE
Definition: nt_native.h:90
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953

◆ CON_API() [2/5]

CON_API ( SrvGetConsoleInput  ,
CONSOLE_GETINPUT  ,
GetInputRequest   
)

Definition at line 649 of file coninput.c.

651{
653 PVOID HandleEntry;
655 GET_INPUT_INFO InputInfo;
656
657 DPRINT("SrvGetConsoleInput\n");
658
659 if (GetInputRequest->Flags & ~(CONSOLE_READ_NOREMOVE | CONSOLE_READ_NOWAIT))
660 {
662 }
663
664 /*
665 * For optimization purposes, Windows (and hence ReactOS, too, for
666 * compatibility reasons) uses a static buffer if no more than five
667 * input records are read. Otherwise a new buffer is used.
668 * The client-side expects that we know this behaviour.
669 */
670 if (GetInputRequest->NumRecords <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
671 {
672 /*
673 * Adjust the internal pointer, because its old value points to
674 * the static buffer in the original ApiMessage structure.
675 */
676 // GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer;
677 }
678 else
679 {
680 if (!CsrValidateMessageBuffer(ApiMessage,
681 (PVOID*)&GetInputRequest->RecordBufPtr,
682 GetInputRequest->NumRecords,
683 sizeof(INPUT_RECORD)))
684 {
686 }
687 }
688
690 GetInputRequest->InputHandle,
692 &HandleEntry,
694 TRUE);
695 if (!NT_SUCCESS(Status))
696 return Status;
697
698 ASSERT((PCONSOLE)Console == InputBuffer->Header.Console);
699
700 InputInfo.CallingThread = CsrGetClientThread();
701 InputInfo.HandleEntry = HandleEntry;
702 InputInfo.InputBuffer = InputBuffer;
703
704 Status = ReadInputBuffer(&InputInfo, ApiMessage, TRUE);
705
707
708 if (Status == STATUS_PENDING) *ReplyCode = CsrReplyPending;
709
710 return Status;
711}
static NTSTATUS ReadInputBuffer(IN PGET_INPUT_INFO InputInfo, IN PCSR_API_MESSAGE ApiMessage, IN BOOLEAN CreateWaitBlock OPTIONAL)
Definition: coninput.c:506
#define ConSrvGetInputBufferAndHandleEntry(ProcessData, Handle, Ptr, Entry, Access, LockConsole)
Definition: coninput.c:23
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1430
#define CsrGetClientThread()
Definition: csrsrv.h:77
@ CsrReplyPending
Definition: csrsrv.h:132
#define GENERIC_READ
Definition: compat.h:135
#define STATUS_PENDING
Definition: ntstatus.h:82
#define DPRINT
Definition: sndvol32.h:71
PCONSOLE_INPUT_BUFFER InputBuffer
Definition: coninput.c:54
PCSR_THREAD CallingThread
Definition: coninput.c:52
PVOID HandleEntry
Definition: coninput.c:53
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define CONSOLE_READ_NOREMOVE
Definition: wincon.h:122
#define CONSOLE_READ_NOWAIT
Definition: wincon.h:123

◆ CON_API() [3/5]

CON_API ( SrvGetConsoleNumberOfInputEvents  ,
CONSOLE_GETNUMINPUTEVENTS  ,
GetNumInputEventsRequest   
)

Definition at line 832 of file coninput.c.

834{
837
838 Status = ConSrvGetInputBuffer(ProcessData,
839 GetNumInputEventsRequest->InputHandle,
841 if (!NT_SUCCESS(Status))
842 return Status;
843
844 ASSERT((PCONSOLE)Console == InputBuffer->Header.Console);
845
848 &GetNumInputEventsRequest->NumberOfEvents);
849
851 return Status;
852}
NTSTATUS NTAPI ConDrvGetConsoleNumberOfInputEvents(IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer, OUT PULONG NumberOfEvents)
Definition: coninput.c:374

◆ CON_API() [4/5]

CON_API ( SrvReadConsole  ,
CONSOLE_READCONSOLE  ,
ReadConsoleRequest   
)

Definition at line 584 of file coninput.c.

586{
588 PVOID HandleEntry;
590 GET_INPUT_INFO InputInfo;
591
592 DPRINT("SrvReadConsole\n");
593
594 /*
595 * For optimization purposes, Windows (and hence ReactOS, too, for
596 * compatibility reasons) uses a static buffer if no more than eighty
597 * bytes are read. Otherwise a new buffer is used.
598 * The client-side expects that we know this behaviour.
599 */
600 if (ReadConsoleRequest->CaptureBufferSize <= sizeof(ReadConsoleRequest->StaticBuffer))
601 {
602 /*
603 * Adjust the internal pointer, because its old value points to
604 * the static buffer in the original ApiMessage structure.
605 */
606 // ReadConsoleRequest->Buffer = ReadConsoleRequest->StaticBuffer;
607 }
608 else
609 {
610 if (!CsrValidateMessageBuffer(ApiMessage,
611 (PVOID*)&ReadConsoleRequest->Buffer,
612 ReadConsoleRequest->CaptureBufferSize,
613 sizeof(BYTE)))
614 {
616 }
617 }
618
619 if (ReadConsoleRequest->InitialNumBytes > ReadConsoleRequest->NumBytes)
620 {
622 }
623
625 ReadConsoleRequest->InputHandle,
627 &HandleEntry,
629 TRUE);
630 if (!NT_SUCCESS(Status))
631 return Status;
632
633 ASSERT((PCONSOLE)Console == InputBuffer->Header.Console);
634
635 InputInfo.CallingThread = CsrGetClientThread();
636 InputInfo.HandleEntry = HandleEntry;
637 InputInfo.InputBuffer = InputBuffer;
638
639 Status = ReadChars(&InputInfo, ApiMessage, TRUE);
640
642
643 if (Status == STATUS_PENDING) *ReplyCode = CsrReplyPending;
644
645 return Status;
646}
static NTSTATUS ReadChars(IN PGET_INPUT_INFO InputInfo, IN PCSR_API_MESSAGE ApiMessage, IN BOOLEAN CreateWaitBlock OPTIONAL)
Definition: coninput.c:343
unsigned char BYTE
Definition: xxhash.c:193

◆ CON_API() [5/5]

CON_API ( SrvWriteConsoleInput  ,
CONSOLE_WRITEINPUT  ,
WriteInputRequest   
)

Definition at line 724 of file coninput.c.

726{
729 ULONG NumEventsWritten;
730 PINPUT_RECORD InputRecord;
731
732 /*
733 * For optimization purposes, Windows (and hence ReactOS, too, for
734 * compatibility reasons) uses a static buffer if no more than five
735 * input records are written. Otherwise a new buffer is used.
736 * The client-side expects that we know this behaviour.
737 */
738 if (WriteInputRequest->NumRecords <= sizeof(WriteInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
739 {
740 /*
741 * Adjust the internal pointer, because its old value points to
742 * the static buffer in the original ApiMessage structure.
743 */
744 // WriteInputRequest->RecordBufPtr = WriteInputRequest->RecordStaticBuffer;
745 InputRecord = WriteInputRequest->RecordStaticBuffer;
746 }
747 else
748 {
749 if (!CsrValidateMessageBuffer(ApiMessage,
750 (PVOID*)&WriteInputRequest->RecordBufPtr,
751 WriteInputRequest->NumRecords,
752 sizeof(INPUT_RECORD)))
753 {
755 }
756
757 InputRecord = WriteInputRequest->RecordBufPtr;
758 }
759
760 Status = ConSrvGetInputBuffer(ProcessData,
761 WriteInputRequest->InputHandle,
763 if (!NT_SUCCESS(Status))
764 {
765 WriteInputRequest->NumRecords = 0;
766 return Status;
767 }
768
769 ASSERT((PCONSOLE)Console == InputBuffer->Header.Console);
770
771 /* First translate everything to UNICODE */
772 if (!WriteInputRequest->Unicode)
773 {
774 ULONG i;
775 for (i = 0; i < WriteInputRequest->NumRecords; ++i)
776 {
778 }
779 }
780
781 /* Now, add the events */
782 NumEventsWritten = 0;
784 // InputBuffer,
785 InputRecord,
786 WriteInputRequest->NumRecords,
787 &NumEventsWritten,
788 WriteInputRequest->AppendToEnd);
789
790 // Status = ConDrvWriteConsoleInput((PCONSOLE)Console,
791 // InputBuffer,
792 // WriteInputRequest->AppendToEnd,
793 // InputRecord,
794 // WriteInputRequest->NumRecords,
795 // &NumEventsWritten);
796
797 WriteInputRequest->NumRecords = NumEventsWritten;
798
800 return Status;
801}
static NTSTATUS ConioAddInputEvents(PCONSRV_CONSOLE Console, PINPUT_RECORD InputRecords, ULONG NumEventsToWrite, PULONG NumEventsWritten, BOOLEAN AppendToEnd)
Definition: coninput.c:167
static VOID ConioInputEventToUnicode(PCONSOLE Console, PINPUT_RECORD InputEvent)
Definition: coninput.c:74
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
uint32_t ULONG
Definition: typedefs.h:59

◆ ConDrvFlushConsoleInputBuffer()

NTSTATUS NTAPI ConDrvFlushConsoleInputBuffer ( IN PCONSOLE  Console,
IN PCONSOLE_INPUT_BUFFER  InputBuffer 
)

Definition at line 357 of file coninput.c.

359{
360 if (Console == NULL || InputBuffer == NULL)
362
363 /* Validity check */
364 ASSERT(Console == InputBuffer->Header.Console);
365
366 /* Discard all entries in the input event queue */
368 NtClearEvent(InputBuffer->ActiveEvent);
369
370 return STATUS_SUCCESS;
371}
static VOID PurgeInputBuffer(IN PCONSOLE_INPUT_BUFFER InputBuffer)
Definition: coninput.c:174
NTSTATUS NTAPI NtClearEvent(IN HANDLE EventHandle)
Definition: event.c:65
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by CON_API().

◆ ConDrvGetConsoleInput()

NTSTATUS NTAPI ConDrvGetConsoleInput ( IN PCONSOLE  Console,
IN PCONSOLE_INPUT_BUFFER  InputBuffer,
IN BOOLEAN  KeepEvents,
IN BOOLEAN  WaitForMoreEvents,
OUT PINPUT_RECORD  InputRecord,
IN ULONG  NumEventsToRead,
OUT PULONG NumEventsRead  OPTIONAL 
)

Definition at line 264 of file coninput.c.

271{
272 PLIST_ENTRY CurrentInput;
274 ULONG i = 0;
275
276 if (Console == NULL || InputBuffer == NULL /* || InputRecord == NULL */)
278
279 /* Validity checks */
280 ASSERT(Console == InputBuffer->Header.Console);
281 ASSERT((InputRecord != NULL) || (InputRecord == NULL && NumEventsToRead == 0));
282
283 if (NumEventsRead) *NumEventsRead = 0;
284
285 if (IsListEmpty(&InputBuffer->InputEvents))
286 {
287 /*
288 * No input is available. Wait for more input if requested,
289 * otherwise, we don't wait, so we return success.
290 */
291 return (WaitForMoreEvents ? STATUS_PENDING : STATUS_SUCCESS);
292 }
293
294 /* Only get input if there is any */
295 CurrentInput = InputBuffer->InputEvents.Flink;
296 i = 0;
297 while ((CurrentInput != &InputBuffer->InputEvents) && (i < NumEventsToRead))
298 {
299 Input = CONTAINING_RECORD(CurrentInput, ConsoleInput, ListEntry);
300
301 *InputRecord = Input->InputEvent;
302
303 ++InputRecord;
304 ++i;
305 CurrentInput = CurrentInput->Flink;
306
307 /* Remove the events from the queue if needed */
308 if (!KeepEvents)
309 {
310 _InterlockedDecrement((PLONG)&InputBuffer->NumberOfEvents);
311 RemoveEntryList(&Input->ListEntry);
313 }
314 }
315
316 if (NumEventsRead) *NumEventsRead = i;
317
318 if (IsListEmpty(&InputBuffer->InputEvents))
319 {
320 NtClearEvent(InputBuffer->ActiveEvent);
321 }
322
323 // FIXME: If we add back UNICODE support, it's here that we need to do the translation.
324
325 /* We read all the inputs available, we return success */
326 return STATUS_SUCCESS;
327}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
long __cdecl _InterlockedDecrement(_Interlocked_operand_ long volatile *_Addend)
@ Input
Definition: arc.h:84
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
int32_t * PLONG
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define ConsoleFreeHeap(HeapBase)
Definition: heap.h:15

Referenced by ReadInputBuffer().

◆ ConDrvGetConsoleNumberOfInputEvents()

NTSTATUS NTAPI ConDrvGetConsoleNumberOfInputEvents ( IN PCONSOLE  Console,
IN PCONSOLE_INPUT_BUFFER  InputBuffer,
OUT PULONG  NumberOfEvents 
)

Definition at line 374 of file coninput.c.

377{
378 if (Console == NULL || InputBuffer == NULL || NumberOfEvents == NULL)
380
381 /* Validity check */
382 ASSERT(Console == InputBuffer->Header.Console);
383
384 *NumberOfEvents = InputBuffer->NumberOfEvents;
385 return STATUS_SUCCESS;
386}

Referenced by CON_API().

◆ ConDrvReadConsole()

NTSTATUS NTAPI ConDrvReadConsole ( IN PCONSOLE  Console,
IN PCONSOLE_INPUT_BUFFER  InputBuffer,
IN BOOLEAN  Unicode,
OUT PVOID  Buffer,
IN OUT PCONSOLE_READCONSOLE_CONTROL  ReadControl,
IN PVOID Parameter  OPTIONAL,
IN ULONG  NumCharsToRead,
OUT PULONG NumCharsRead  OPTIONAL 
)

Definition at line 231 of file coninput.c.

239{
240 // STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait.
241 // NTSTATUS Status; = STATUS_PENDING;
242
243 if (Console == NULL || InputBuffer == NULL || /* Buffer == NULL || */
244 ReadControl == NULL || ReadControl->nLength != sizeof(CONSOLE_READCONSOLE_CONTROL))
245 {
247 }
248
249 /* Validity checks */
250 ASSERT(Console == InputBuffer->Header.Console);
251 ASSERT((Buffer != NULL) || (Buffer == NULL && NumCharsToRead == 0));
252
253 /* Call the line-discipline */
254 return TermReadStream(Console,
255 Unicode,
256 Buffer,
257 ReadControl,
258 Parameter,
259 NumCharsToRead,
260 NumCharsRead);
261}
Definition: bufpool.h:45
#define TermReadStream(Console, Unicode, Buffer, ReadControl, Parameter, NumCharsToRead, NumCharsRead)
Definition: term.h:13
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323

Referenced by ReadChars().

◆ ConDrvWriteConsoleInput()

NTSTATUS NTAPI ConDrvWriteConsoleInput ( IN PCONSOLE  Console,
IN PCONSOLE_INPUT_BUFFER  InputBuffer,
IN BOOLEAN  AppendToEnd,
IN PINPUT_RECORD  InputRecord,
IN ULONG  NumEventsToWrite,
OUT PULONG NumEventsWritten  OPTIONAL 
)

Definition at line 330 of file coninput.c.

336{
337 if (Console == NULL || InputBuffer == NULL /* || InputRecord == NULL */)
339
340 /* Validity checks */
341 ASSERT(Console == InputBuffer->Header.Console);
342 ASSERT((InputRecord != NULL) || (InputRecord == NULL && NumEventsToWrite == 0));
343
344 /* Now, add the events */
345 if (NumEventsWritten) *NumEventsWritten = 0;
346
347 // FIXME: If we add back UNICODE support, it's here that we need to do the translation.
348
349 return AddInputEvents(Console,
350 InputRecord,
351 NumEventsToWrite,
352 NumEventsWritten,
353 AppendToEnd);
354}
static NTSTATUS AddInputEvents(PCONSOLE Console, PINPUT_RECORD InputRecords, ULONG NumEventsToWrite, PULONG NumEventsWritten, BOOLEAN AppendToEnd)
Definition: coninput.c:21

Referenced by ConioAddInputEvents().

◆ ConioAddInputEvents()

static NTSTATUS ConioAddInputEvents ( PCONSRV_CONSOLE  Console,
PINPUT_RECORD  InputRecords,
ULONG  NumEventsToWrite,
PULONG  NumEventsWritten,
BOOLEAN  AppendToEnd 
)
static

Definition at line 167 of file coninput.c.

172{
174
175 if (NumEventsWritten) *NumEventsWritten = 0;
176
177 NumEventsToWrite = PreprocessInput(Console, InputRecords, NumEventsToWrite);
178 if (NumEventsToWrite == 0) return STATUS_SUCCESS;
179
180 // Status = ConDrvAddInputEvents(Console,
181 // InputRecords,
182 // NumEventsToWrite,
183 // NumEventsWritten,
184 // AppendToEnd);
185
187 &Console->InputBuffer,
188 AppendToEnd,
189 InputRecords,
190 NumEventsToWrite,
191 NumEventsWritten);
192
193 // if (NT_SUCCESS(Status))
195
196 return Status;
197}
static VOID PostprocessInput(PCONSRV_CONSOLE Console)
Definition: coninput.c:146
NTSTATUS NTAPI ConDrvWriteConsoleInput(IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer, IN BOOLEAN AppendToEnd, IN PINPUT_RECORD InputRecord, IN ULONG NumEventsToWrite, OUT PULONG NumEventsWritten OPTIONAL)
Definition: coninput.c:330
static ULONG PreprocessInput(PCONSRV_CONSOLE Console, PINPUT_RECORD InputEvent, ULONG NumEventsToWrite)
Definition: coninput.c:87

Referenced by CON_API(), and ConioProcessInputEvent().

◆ ConioInputEventToAnsi()

static VOID ConioInputEventToAnsi ( PCONSOLE  Console,
PINPUT_RECORD  InputEvent 
)
static

Definition at line 61 of file coninput.c.

62{
63 if (InputEvent->EventType == KEY_EVENT)
64 {
65 WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
66 InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
68 &InputEvent->Event.KeyEvent.uChar.AsciiChar,
69 &UnicodeChar);
70 }
71}
#define ConsoleInputUnicodeToAnsiChar(Console, dChar, sWChar)
Definition: coninput.c:37
union _INPUT_RECORD::@3292 Event
WORD EventType
Definition: wincon.h:273
KEY_EVENT_RECORD KeyEvent
Definition: wincon.h:275
union _KEY_EVENT_RECORD::@3291 uChar
WCHAR UnicodeChar
Definition: wincon.h:245
#define KEY_EVENT
Definition: wincon.h:128
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ReadInputBuffer().

◆ ConioInputEventToUnicode()

static VOID ConioInputEventToUnicode ( PCONSOLE  Console,
PINPUT_RECORD  InputEvent 
)
static

Definition at line 74 of file coninput.c.

75{
76 if (InputEvent->EventType == KEY_EVENT)
77 {
78 CHAR AsciiChar = InputEvent->Event.KeyEvent.uChar.AsciiChar;
79 InputEvent->Event.KeyEvent.uChar.AsciiChar = 0;
81 &InputEvent->Event.KeyEvent.uChar.UnicodeChar,
82 &AsciiChar);
83 }
84}
#define ConsoleInputAnsiToUnicodeChar(Console, dWChar, sChar)
Definition: coninput.c:43
char CHAR
Definition: xmlstorage.h:175

Referenced by CON_API().

◆ ConioProcessInputEvent()

NTSTATUS ConioProcessInputEvent ( PCONSRV_CONSOLE  Console,
PINPUT_RECORD  InputEvent 
)

Definition at line 201 of file coninput.c.

203{
204 ULONG NumEventsWritten;
205
206 if (InputEvent->EventType == KEY_EVENT)
207 {
208 BOOL Down = InputEvent->Event.KeyEvent.bKeyDown;
209 UINT VirtualKeyCode = InputEvent->Event.KeyEvent.wVirtualKeyCode;
210 DWORD ShiftState = InputEvent->Event.KeyEvent.dwControlKeyState;
211
212 /* Process Ctrl-C and Ctrl-Break */
214 Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') &&
215 (ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) )
216 {
217 DPRINT1("Console_Api Ctrl-C\n");
219
220 if (Console->LineBuffer && !Console->LineComplete)
221 {
222 /* Line input is in progress; end it */
223 Console->LinePos = Console->LineSize = 0;
224 Console->LineComplete = TRUE;
225 }
226 return STATUS_SUCCESS; // STATUS_CONTROL_C_EXIT;
227 }
228 }
229
231 InputEvent,
232 1,
233 &NumEventsWritten,
234 TRUE);
235}
#define DPRINT1
Definition: precomp.h:8
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned int UINT
Definition: ndis.h:50
DWORD dwControlKeyState
Definition: wincon.h:248
WORD wVirtualKeyCode
Definition: wincon.h:242
NTSTATUS NTAPI ConSrvConsoleProcessCtrlEvent(IN PCONSRV_CONSOLE Console, IN ULONG ProcessGroupId, IN ULONG CtrlEvent)
Definition: console.c:1402
#define GetConsoleInputBufferMode(Console)
Definition: conio.h:320
#define CTRL_C_EVENT
Definition: wincon.h:68
#define LEFT_CTRL_PRESSED
Definition: wincon.h:140
#define RIGHT_CTRL_PRESSED
Definition: wincon.h:139
#define ENABLE_PROCESSED_INPUT
Definition: wincon.h:78
#define VK_PAUSE
Definition: winuser.h:2205

Referenced by ConioProcessKey(), OnFocus(), OnMouse(), PasteText(), and SendMenuEvent().

◆ PostprocessInput()

static VOID PostprocessInput ( PCONSRV_CONSOLE  Console)
static

Definition at line 146 of file coninput.c.

147{
148 CsrNotifyWait(&Console->ReadWaitQueue,
149 FALSE,
150 NULL,
151 NULL);
152 if (!IsListEmpty(&Console->ReadWaitQueue))
153 {
154 CsrDereferenceWait(&Console->ReadWaitQueue);
155 }
156}
VOID NTAPI CsrDereferenceWait(IN PLIST_ENTRY WaitList)
Definition: wait.c:266
BOOLEAN NTAPI CsrNotifyWait(IN PLIST_ENTRY WaitList, IN BOOLEAN NotifyAll, IN PVOID WaitArgument1, IN PVOID WaitArgument2)
Definition: wait.c:388
#define FALSE
Definition: types.h:117

Referenced by ConioAddInputEvents().

◆ PreprocessInput()

static ULONG PreprocessInput ( PCONSRV_CONSOLE  Console,
PINPUT_RECORD  InputEvent,
ULONG  NumEventsToWrite 
)
static

Definition at line 87 of file coninput.c.

90{
91 ULONG NumEvents;
92
93 /*
94 * Loop each event, and for each, check for pause or unpause
95 * and perform adequate behaviour.
96 */
97 for (NumEvents = NumEventsToWrite; NumEvents > 0; --NumEvents)
98 {
99 /* Check for pause or unpause */
100 if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown)
101 {
102 WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode;
103 if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD))
104 {
105 DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState;
106 if (Console->InputBuffer.Mode & ENABLE_LINE_INPUT &&
107 (vk == VK_PAUSE ||
108 (vk == 'S' && (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) &&
109 !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)))))
110 {
112
113 /* Skip the event */
114 RtlMoveMemory(InputEvent,
115 InputEvent + 1,
116 (NumEvents - 1) * sizeof(INPUT_RECORD));
117 --NumEventsToWrite;
118 continue;
119 }
120 }
121 else
122 {
123 if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN &&
124 vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL)
125 {
127
128 /* Skip the event */
129 RtlMoveMemory(InputEvent,
130 InputEvent + 1,
131 (NumEvents - 1) * sizeof(INPUT_RECORD));
132 --NumEventsToWrite;
133 continue;
134 }
135 }
136 }
137
138 /* Go to the next event */
139 ++InputEvent;
140 }
141
142 return NumEventsToWrite;
143}
#define PAUSED_FROM_KEYBOARD
Definition: conio_winsrv.h:109
unsigned short WORD
Definition: ntddk_ex.h:93
WORD vk
Definition: input.c:77
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
VOID ConioUnpause(PCONSRV_CONSOLE Console, UCHAR Flags)
Definition: console.c:866
VOID ConioPause(PCONSRV_CONSOLE Console, UCHAR Flags)
Definition: console.c:859
#define RIGHT_ALT_PRESSED
Definition: wincon.h:137
#define LEFT_ALT_PRESSED
Definition: wincon.h:138
#define ENABLE_LINE_INPUT
Definition: wincon.h:79
#define VK_CAPITAL
Definition: winuser.h:2206
#define VK_SCROLL
Definition: winuser.h:2280
#define VK_LWIN
Definition: winuser.h:2235
#define VK_NUMLOCK
Definition: winuser.h:2279
#define VK_RWIN
Definition: winuser.h:2236

Referenced by ConioAddInputEvents().

◆ ReadChars()

static NTSTATUS ReadChars ( IN PGET_INPUT_INFO  InputInfo,
IN PCSR_API_MESSAGE  ApiMessage,
IN BOOLEAN CreateWaitBlock  OPTIONAL 
)
static

Definition at line 343 of file coninput.c.

346{
348 PCONSOLE_READCONSOLE ReadConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest;
349 PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer;
350 CONSOLE_READCONSOLE_CONTROL ReadControl;
351
352 UNICODE_STRING ExeName;
353
355 ULONG NrCharactersRead = 0;
356 ULONG CharSize = (ReadConsoleRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR));
357
358 /* Retrieve the executable name, if needed */
359 if (ReadConsoleRequest->InitialNumBytes == 0 &&
360 ReadConsoleRequest->ExeLength <= sizeof(ReadConsoleRequest->StaticBuffer))
361 {
362 ExeName.Length = ExeName.MaximumLength = ReadConsoleRequest->ExeLength;
363 ExeName.Buffer = (PWCHAR)ReadConsoleRequest->StaticBuffer;
364 }
365 else
366 {
367 ExeName.Length = ExeName.MaximumLength = 0;
368 ExeName.Buffer = NULL;
369 }
370
371 /* Build the ReadControl structure */
372 ReadControl.nLength = sizeof(CONSOLE_READCONSOLE_CONTROL);
373 ReadControl.nInitialChars = ReadConsoleRequest->InitialNumBytes / CharSize;
374 ReadControl.dwCtrlWakeupMask = ReadConsoleRequest->CtrlWakeupMask;
375 ReadControl.dwControlKeyState = ReadConsoleRequest->ControlKeyState;
376
377 /*
378 * For optimization purposes, Windows (and hence ReactOS, too, for
379 * compatibility reasons) uses a static buffer if no more than eighty
380 * bytes are read. Otherwise a new buffer is used.
381 * The client-side expects that we know this behaviour.
382 */
383 if (ReadConsoleRequest->CaptureBufferSize <= sizeof(ReadConsoleRequest->StaticBuffer))
384 {
385 /*
386 * Adjust the internal pointer, because its old value points to
387 * the static buffer in the original ApiMessage structure.
388 */
389 // ReadConsoleRequest->Buffer = ReadConsoleRequest->StaticBuffer;
390 Buffer = ReadConsoleRequest->StaticBuffer;
391 }
392 else
393 {
394 Buffer = ReadConsoleRequest->Buffer;
395 }
396
397 DPRINT("Calling ConDrvReadConsole(%wZ)\n", &ExeName);
398 Status = ConDrvReadConsole(InputBuffer->Header.Console,
400 ReadConsoleRequest->Unicode,
401 Buffer,
402 &ReadControl,
403 &ExeName,
404 ReadConsoleRequest->NumBytes / CharSize, // NrCharactersToRead
405 &NrCharactersRead);
406 DPRINT("ConDrvReadConsole returned (%d ; Status = 0x%08x)\n",
407 NrCharactersRead, Status);
408
409 // ReadConsoleRequest->ControlKeyState = ReadControl.dwControlKeyState;
410
411 if (Status == STATUS_PENDING)
412 {
413 /* We haven't completed a read, so start a wait */
414 return WaitBeforeReading(InputInfo,
415 ApiMessage,
417 CreateWaitBlock);
418 }
419 else
420 {
421 /*
422 * We read all what we wanted. Set the number of bytes read and
423 * return the error code we were given.
424 */
425 ReadConsoleRequest->NumBytes = NrCharactersRead * CharSize;
426 ReadConsoleRequest->ControlKeyState = ReadControl.dwControlKeyState;
427
428 return Status;
429 // return STATUS_SUCCESS;
430 }
431}
NTSTATUS NTAPI ConDrvReadConsole(IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer, IN BOOLEAN Unicode, OUT PVOID Buffer, IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl, IN PVOID Parameter OPTIONAL, IN ULONG NumCharsToRead, OUT PULONG NumCharsRead OPTIONAL)
Definition: coninput.c:231
static NTSTATUS WaitBeforeReading(IN PGET_INPUT_INFO InputInfo, IN PCSR_API_MESSAGE ApiMessage, IN CSR_WAIT_FUNCTION WaitFunction OPTIONAL, IN BOOLEAN CreateWaitBlock OPTIONAL)
Definition: coninput.c:239
static BOOLEAN NTAPI ReadCharsThread(IN PLIST_ENTRY WaitList, IN PCSR_THREAD WaitThread, IN PCSR_API_MESSAGE WaitApiMessage, IN PVOID WaitContext, IN PVOID WaitArgument1, IN PVOID WaitArgument2, IN ULONG WaitFlags)
Definition: coninput.c:277
struct _CONSOLE_API_MESSAGE * PCONSOLE_API_MESSAGE
ULONG CtrlWakeupMask
Definition: conmsg.h:267
ULONG ControlKeyState
Definition: conmsg.h:268
ULONG CaptureBufferSize
Definition: conmsg.h:264
CHAR StaticBuffer[80]
Definition: conmsg.h:260
ULONG InitialNumBytes
Definition: conmsg.h:266
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWCHAR
Definition: typedefs.h:56
struct _CONSOLE_READCONSOLE_CONTROL CONSOLE_READCONSOLE_CONTROL

Referenced by CON_API(), and ReadCharsThread().

◆ ReadCharsThread()

static BOOLEAN NTAPI ReadCharsThread ( IN PLIST_ENTRY  WaitList,
IN PCSR_THREAD  WaitThread,
IN PCSR_API_MESSAGE  WaitApiMessage,
IN PVOID  WaitContext,
IN PVOID  WaitArgument1,
IN PVOID  WaitArgument2,
IN ULONG  WaitFlags 
)
static

Definition at line 277 of file coninput.c.

284{
286 PGET_INPUT_INFO InputInfo = (PGET_INPUT_INFO)WaitContext;
287
288 PVOID InputHandle = WaitArgument2;
289
290 DPRINT("ReadCharsThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags);
291
292 /*
293 * If we are notified of the process termination via a call
294 * to CsrNotifyWaitBlock triggered by CsrDestroyProcess or
295 * CsrDestroyThread, just return.
296 */
297 if (WaitFlags & CsrProcessTerminating)
298 {
300 goto Quit;
301 }
302
303 /*
304 * Somebody is closing a handle to this input buffer,
305 * by calling ConSrvCloseHandleEntry.
306 * See whether we are linked to that handle (ie. we
307 * are a waiter for this handle), and if so, return.
308 * Otherwise, ignore the call and continue waiting.
309 */
310 if (InputHandle != NULL)
311 {
314 goto Quit;
315 }
316
317 /*
318 * If we go there, that means we are notified for some new input.
319 * The console is therefore already locked.
320 */
321 Status = ReadChars(InputInfo, WaitApiMessage, FALSE);
322
323Quit:
324 if (Status != STATUS_PENDING)
325 {
326 WaitApiMessage->Status = Status;
327 ConsoleFreeHeap(InputInfo);
328 }
329
330 return (Status == STATUS_PENDING ? FALSE : TRUE);
331}
struct _GET_INPUT_INFO * PGET_INPUT_INFO
@ CsrProcessTerminating
Definition: csrsrv.h:85
HANDLE InputHandle
Definition: apc.c:9
#define STATUS_ALERTED
Definition: ntstatus.h:80
#define STATUS_THREAD_IS_TERMINATING
Definition: ntstatus.h:311

Referenced by ReadChars().

◆ ReadInputBuffer()

static NTSTATUS ReadInputBuffer ( IN PGET_INPUT_INFO  InputInfo,
IN PCSR_API_MESSAGE  ApiMessage,
IN BOOLEAN CreateWaitBlock  OPTIONAL 
)
static

Definition at line 506 of file coninput.c.

509{
511 PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest;
512 PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer;
513 ULONG NumEventsRead;
514
515 PINPUT_RECORD InputRecord;
516
517 /*
518 * For optimization purposes, Windows (and hence ReactOS, too, for
519 * compatibility reasons) uses a static buffer if no more than five
520 * input records are read. Otherwise a new buffer is used.
521 * The client-side expects that we know this behaviour.
522 */
523 if (GetInputRequest->NumRecords <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
524 {
525 /*
526 * Adjust the internal pointer, because its old value points to
527 * the static buffer in the original ApiMessage structure.
528 */
529 // GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer;
530 InputRecord = GetInputRequest->RecordStaticBuffer;
531 }
532 else
533 {
534 InputRecord = GetInputRequest->RecordBufPtr;
535 }
536
537 NumEventsRead = 0;
538 Status = ConDrvGetConsoleInput(InputBuffer->Header.Console,
540 (GetInputRequest->Flags & CONSOLE_READ_NOREMOVE) != 0,
541 (GetInputRequest->Flags & CONSOLE_READ_NOWAIT ) == 0,
542 InputRecord,
543 GetInputRequest->NumRecords,
544 &NumEventsRead);
545
546 if (Status == STATUS_PENDING)
547 {
548 /* We haven't completed a read, so start a wait */
549 return WaitBeforeReading(InputInfo,
550 ApiMessage,
552 CreateWaitBlock);
553 }
554 else
555 {
556 /*
557 * We read all what we wanted. Set the number of events read and
558 * return the error code we were given.
559 */
560 GetInputRequest->NumRecords = NumEventsRead;
561
562 if (NT_SUCCESS(Status))
563 {
564 /* Now translate everything to ANSI */
565 if (!GetInputRequest->Unicode)
566 {
567 ULONG i;
568 for (i = 0; i < NumEventsRead; ++i)
569 {
570 ConioInputEventToAnsi(InputBuffer->Header.Console, &InputRecord[i]);
571 }
572 }
573 }
574
575 return Status;
576 // return STATUS_SUCCESS;
577 }
578}
NTSTATUS NTAPI ConDrvGetConsoleInput(IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer, IN BOOLEAN KeepEvents, IN BOOLEAN WaitForMoreEvents, OUT PINPUT_RECORD InputRecord, IN ULONG NumEventsToRead, OUT PULONG NumEventsRead OPTIONAL)
Definition: coninput.c:264
static VOID ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent)
Definition: coninput.c:61
static BOOLEAN NTAPI ReadInputBufferThread(IN PLIST_ENTRY WaitList, IN PCSR_THREAD WaitThread, IN PCSR_API_MESSAGE WaitApiMessage, IN PVOID WaitContext, IN PVOID WaitArgument1, IN PVOID WaitArgument2, IN ULONG WaitFlags)
Definition: coninput.c:441
ULONG NumRecords
Definition: conmsg.h:568
PINPUT_RECORD RecordBufPtr
Definition: conmsg.h:567
BOOLEAN Unicode
Definition: conmsg.h:570
INPUT_RECORD RecordStaticBuffer[5]
Definition: conmsg.h:566
struct _INPUT_RECORD INPUT_RECORD

Referenced by CON_API(), and ReadInputBufferThread().

◆ ReadInputBufferThread()

static BOOLEAN NTAPI ReadInputBufferThread ( IN PLIST_ENTRY  WaitList,
IN PCSR_THREAD  WaitThread,
IN PCSR_API_MESSAGE  WaitApiMessage,
IN PVOID  WaitContext,
IN PVOID  WaitArgument1,
IN PVOID  WaitArgument2,
IN ULONG  WaitFlags 
)
static

Definition at line 441 of file coninput.c.

448{
450 PGET_INPUT_INFO InputInfo = (PGET_INPUT_INFO)WaitContext;
451
452 PVOID InputHandle = WaitArgument2;
453
454 DPRINT("ReadInputBufferThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags);
455
456 /*
457 * If we are notified of the process termination via a call
458 * to CsrNotifyWaitBlock triggered by CsrDestroyProcess or
459 * CsrDestroyThread, just return.
460 */
461 if (WaitFlags & CsrProcessTerminating)
462 {
464 goto Quit;
465 }
466
467 /*
468 * Somebody is closing a handle to this input buffer,
469 * by calling ConSrvCloseHandleEntry.
470 * See whether we are linked to that handle (ie. we
471 * are a waiter for this handle), and if so, return.
472 * Otherwise, ignore the call and continue waiting.
473 */
474 if (InputHandle != NULL)
475 {
478 goto Quit;
479 }
480
481 /*
482 * If we go there, that means we are notified for some new input.
483 * The console is therefore already locked.
484 */
485 Status = ReadInputBuffer(InputInfo, WaitApiMessage, FALSE);
486
487Quit:
488 if (Status != STATUS_PENDING)
489 {
490 WaitApiMessage->Status = Status;
491 ConsoleFreeHeap(InputInfo);
492 }
493
494 return (Status == STATUS_PENDING ? FALSE : TRUE);
495}

Referenced by ReadInputBuffer().

◆ WaitBeforeReading()

static NTSTATUS WaitBeforeReading ( IN PGET_INPUT_INFO  InputInfo,
IN PCSR_API_MESSAGE  ApiMessage,
IN CSR_WAIT_FUNCTION WaitFunction  OPTIONAL,
IN BOOLEAN CreateWaitBlock  OPTIONAL 
)
static

Definition at line 239 of file coninput.c.

243{
244 if (CreateWaitBlock)
245 {
246 PGET_INPUT_INFO CapturedInputInfo;
247 PCONSRV_CONSOLE Console = (PCONSRV_CONSOLE)InputInfo->InputBuffer->Header.Console;
248
249 CapturedInputInfo = ConsoleAllocHeap(0, sizeof(GET_INPUT_INFO));
250 if (!CapturedInputInfo) return STATUS_NO_MEMORY;
251
252 RtlMoveMemory(CapturedInputInfo, InputInfo, sizeof(GET_INPUT_INFO));
253
254 if (!CsrCreateWait(&Console->ReadWaitQueue,
255 WaitFunction,
256 InputInfo->CallingThread,
257 ApiMessage,
258 CapturedInputInfo))
259 {
260 ConsoleFreeHeap(CapturedInputInfo);
261 return STATUS_NO_MEMORY;
262 }
263 }
264
265 /* Wait for input */
266 return STATUS_PENDING;
267}
struct _CONSRV_CONSOLE * PCONSRV_CONSOLE
BOOLEAN NTAPI CsrCreateWait(IN PLIST_ENTRY WaitList, IN CSR_WAIT_FUNCTION WaitFunction, IN PCSR_THREAD CsrWaitThread, IN OUT PCSR_API_MESSAGE WaitApiMessage, IN PVOID WaitContext)
Definition: wait.c:209
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define ConsoleAllocHeap(Flags, Size)
Definition: heap.h:14

Referenced by ReadChars(), and ReadInputBuffer().