static VOID PostprocessInput(PCONSRV_CONSOLE Console) { CsrNotifyWait(&Console->ReadWaitQueue, FALSE, NULL, NULL); if (!IsListEmpty(&Console->ReadWaitQueue)) { CsrDereferenceWait(&Console->ReadWaitQueue); } }
NTSTATUS FASTCALL ConioProcessInputEvent(PCONSOLE Console, PINPUT_RECORD InputEvent) { ConsoleInput *ConInRec; /* Check for pause or unpause */ if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown) { WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode; if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD)) { DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState; if (Console->InputBuffer.Mode & ENABLE_LINE_INPUT && (vk == VK_PAUSE || (vk == 'S' && (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) && !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))))) { ConioPause(Console, PAUSED_FROM_KEYBOARD); return STATUS_SUCCESS; } } else { if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN && vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL) { ConioUnpause(Console, PAUSED_FROM_KEYBOARD); return STATUS_SUCCESS; } } } /* Add event to the queue */ ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput)); if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES; ConInRec->InputEvent = *InputEvent; InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry); SetEvent(Console->InputBuffer.ActiveEvent); CsrNotifyWait(&Console->InputBuffer.ReadWaitQueue, WaitAny, NULL, NULL); if (!IsListEmpty(&Console->InputBuffer.ReadWaitQueue)) { CsrDereferenceWait(&Console->InputBuffer.ReadWaitQueue); } return STATUS_SUCCESS; }
static VOID ConSrvCloseHandle(IN PCONSOLE_IO_HANDLE Handle) { PCONSOLE_IO_OBJECT Object = Handle->Object; if (Object != NULL) { /* * If this is a input handle, notify and dereference * all the waits related to this handle. */ if (Object->Type == INPUT_BUFFER) { // PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object; PCONSOLE Console = Object->Console; /* * Wake up all the writing waiters related to this handle for this * input buffer, if any, then dereference them and purge them all * from the list. * To select them amongst all the waiters for this input buffer, * pass the handle pointer to the waiters, then they will check * whether or not they are related to this handle and if so, they * return. */ CsrNotifyWait(&Console->ReadWaitQueue, TRUE, NULL, (PVOID)Handle); if (!IsListEmpty(&Console->ReadWaitQueue)) { CsrDereferenceWait(&Console->ReadWaitQueue); } } /* If the last handle to a screen buffer is closed, delete it... */ if (AdjustHandleCounts(Handle, -1) == 0) { if (Object->Type == TEXTMODE_BUFFER || Object->Type == GRAPHICS_BUFFER) { PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object; /* ...unless it's the only buffer left. Windows allows deletion * even of the last buffer, but having to deal with a lack of * any active buffer might be error-prone. */ if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink) ConDrvDeleteScreenBuffer(Buffer); } else if (Object->Type == INPUT_BUFFER) { DPRINT("Closing the input buffer\n"); } else { DPRINT1("Invalid object type %d\n", Object->Type); } } /* Invalidate (zero-out) this handle entry */ // Handle->Object = NULL; // RtlZeroMemory(Handle, sizeof(*Handle)); } RtlZeroMemory(Handle, sizeof(*Handle)); // Be sure the whole entry is invalidated. }