static NTSTATUS ReadInputBuffer(IN PGET_INPUT_INFO InputInfo, IN BOOL Wait, // TRUE --> Read ; FALSE --> Peek IN PCSR_API_MESSAGE ApiMessage, IN BOOL CreateWaitBlock OPTIONAL) { NTSTATUS Status; PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest; PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer; // GetInputRequest->InputsRead = 0; Status = ConDrvGetConsoleInput(InputBuffer->Header.Console, InputBuffer, Wait, GetInputRequest->Unicode, GetInputRequest->InputRecord, GetInputRequest->Length, &GetInputRequest->InputsRead); if (Status == STATUS_PENDING) { /* We haven't completed a read, so start a wait */ return WaitBeforeReading(InputInfo, ApiMessage, ReadInputBufferThread, CreateWaitBlock); } else { /* We read all what we wanted, we return the error code we were given */ return Status; // return STATUS_SUCCESS; } }
static NTSTATUS ReadChars(IN PGET_INPUT_INFO InputInfo, IN PCSR_API_MESSAGE ApiMessage, IN BOOL CreateWaitBlock OPTIONAL) { NTSTATUS Status; PCONSOLE_READCONSOLE ReadConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest; PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer; CONSOLE_READCONSOLE_CONTROL ReadControl; ReadControl.nLength = sizeof(CONSOLE_READCONSOLE_CONTROL); ReadControl.nInitialChars = ReadConsoleRequest->NrCharactersRead; ReadControl.dwCtrlWakeupMask = ReadConsoleRequest->CtrlWakeupMask; ReadControl.dwControlKeyState = ReadConsoleRequest->ControlKeyState; Status = ConDrvReadConsole(InputBuffer->Header.Console, InputBuffer, ReadConsoleRequest->Unicode, ReadConsoleRequest->Buffer, &ReadControl, ReadConsoleRequest->NrCharactersToRead, &ReadConsoleRequest->NrCharactersRead); ReadConsoleRequest->ControlKeyState = ReadControl.dwControlKeyState; if (Status == STATUS_PENDING) { /* We haven't completed a read, so start a wait */ return WaitBeforeReading(InputInfo, ApiMessage, ReadCharsThread, CreateWaitBlock); } else { /* We read all what we wanted, we return the error code we were given */ return Status; // return STATUS_SUCCESS; } }
static NTSTATUS ReadInputBuffer(IN PGET_INPUT_INFO InputInfo, IN PCSR_API_MESSAGE ApiMessage, IN BOOLEAN CreateWaitBlock OPTIONAL) { NTSTATUS Status; PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest; PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer; ULONG NumEventsRead; PINPUT_RECORD InputRecord; /* * For optimization purposes, Windows (and hence ReactOS, too, for * compatibility reasons) uses a static buffer if no more than five * input records are read. Otherwise a new buffer is used. * The client-side expects that we know this behaviour. */ if (GetInputRequest->NumRecords <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD)) { /* * Adjust the internal pointer, because its old value points to * the static buffer in the original ApiMessage structure. */ // GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer; InputRecord = GetInputRequest->RecordStaticBuffer; } else { InputRecord = GetInputRequest->RecordBufPtr; } NumEventsRead = 0; Status = ConDrvGetConsoleInput(InputBuffer->Header.Console, InputBuffer, (GetInputRequest->Flags & CONSOLE_READ_KEEPEVENT) != 0, (GetInputRequest->Flags & CONSOLE_READ_CONTINUE ) == 0, InputRecord, GetInputRequest->NumRecords, &NumEventsRead); if (Status == STATUS_PENDING) { /* We haven't completed a read, so start a wait */ return WaitBeforeReading(InputInfo, ApiMessage, ReadInputBufferThread, CreateWaitBlock); } else { /* * We read all what we wanted. Set the number of events read and * return the error code we were given. */ GetInputRequest->NumRecords = NumEventsRead; if (NT_SUCCESS(Status)) { /* Now translate everything to ANSI */ if (!GetInputRequest->Unicode) { for (; NumEventsRead > 0; --NumEventsRead) { ConioInputEventToAnsi(InputBuffer->Header.Console, --InputRecord); } } } return Status; // return STATUS_SUCCESS; } }
static NTSTATUS ReadChars(IN PGET_INPUT_INFO InputInfo, IN PCSR_API_MESSAGE ApiMessage, IN BOOLEAN CreateWaitBlock OPTIONAL) { NTSTATUS Status; PCONSOLE_READCONSOLE ReadConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest; PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer; CONSOLE_READCONSOLE_CONTROL ReadControl; UNICODE_STRING ExeName; PVOID Buffer; ULONG NrCharactersRead = 0; ULONG CharSize = (ReadConsoleRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR)); /* Retrieve the executable name, if needed */ if (ReadConsoleRequest->InitialNumBytes == 0 && ReadConsoleRequest->ExeLength <= sizeof(ReadConsoleRequest->StaticBuffer)) { ExeName.Length = ExeName.MaximumLength = ReadConsoleRequest->ExeLength; ExeName.Buffer = (PWCHAR)ReadConsoleRequest->StaticBuffer; } else { ExeName.Length = ExeName.MaximumLength = 0; ExeName.Buffer = NULL; } /* Build the ReadControl structure */ ReadControl.nLength = sizeof(CONSOLE_READCONSOLE_CONTROL); ReadControl.nInitialChars = ReadConsoleRequest->InitialNumBytes / CharSize; ReadControl.dwCtrlWakeupMask = ReadConsoleRequest->CtrlWakeupMask; ReadControl.dwControlKeyState = ReadConsoleRequest->ControlKeyState; /* * For optimization purposes, Windows (and hence ReactOS, too, for * compatibility reasons) uses a static buffer if no more than eighty * bytes are read. Otherwise a new buffer is used. * The client-side expects that we know this behaviour. */ if (ReadConsoleRequest->CaptureBufferSize <= sizeof(ReadConsoleRequest->StaticBuffer)) { /* * Adjust the internal pointer, because its old value points to * the static buffer in the original ApiMessage structure. */ // ReadConsoleRequest->Buffer = ReadConsoleRequest->StaticBuffer; Buffer = ReadConsoleRequest->StaticBuffer; } else { Buffer = ReadConsoleRequest->Buffer; } DPRINT("Calling ConDrvReadConsole(%wZ)\n", &ExeName); Status = ConDrvReadConsole(InputBuffer->Header.Console, InputBuffer, ReadConsoleRequest->Unicode, Buffer, &ReadControl, &ExeName, ReadConsoleRequest->NumBytes / CharSize, // NrCharactersToRead &NrCharactersRead); DPRINT("ConDrvReadConsole returned (%d ; Status = 0x%08x)\n", NrCharactersRead, Status); // ReadConsoleRequest->ControlKeyState = ReadControl.dwControlKeyState; if (Status == STATUS_PENDING) { /* We haven't completed a read, so start a wait */ return WaitBeforeReading(InputInfo, ApiMessage, ReadCharsThread, CreateWaitBlock); } else { /* * We read all what we wanted. Set the number of bytes read and * return the error code we were given. */ ReadConsoleRequest->NumBytes = NrCharactersRead * CharSize; ReadConsoleRequest->ControlKeyState = ReadControl.dwControlKeyState; return Status; // return STATUS_SUCCESS; } }