static NTSTATUS WaitBeforeReading(IN PGET_INPUT_INFO InputInfo, IN PCSR_API_MESSAGE ApiMessage, IN CSR_WAIT_FUNCTION WaitFunction OPTIONAL, IN BOOL CreateWaitBlock OPTIONAL) { if (CreateWaitBlock) { PGET_INPUT_INFO CapturedInputInfo; CapturedInputInfo = ConsoleAllocHeap(0, sizeof(GET_INPUT_INFO)); if (!CapturedInputInfo) return STATUS_NO_MEMORY; RtlMoveMemory(CapturedInputInfo, InputInfo, sizeof(GET_INPUT_INFO)); if (!CsrCreateWait(&InputInfo->InputBuffer->ReadWaitQueue, WaitFunction, InputInfo->CallingThread, ApiMessage, CapturedInputInfo, NULL)) { ConsoleFreeHeap(CapturedInputInfo); return STATUS_NO_MEMORY; } } /* Wait for input */ return STATUS_PENDING; }
static NTSTATUS DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage, IN PCSR_THREAD ClientThread, IN BOOL CreateWaitBlock OPTIONAL) { NTSTATUS Status; PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest; PTEXTMODE_SCREEN_BUFFER ScreenBuffer; Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(ClientThread->Process), WriteConsoleRequest->OutputHandle, &ScreenBuffer, GENERIC_WRITE, FALSE); if (!NT_SUCCESS(Status)) return Status; Status = ConDrvWriteConsole(ScreenBuffer->Header.Console, ScreenBuffer, WriteConsoleRequest->Unicode, WriteConsoleRequest->Buffer, WriteConsoleRequest->NrCharactersToWrite, &WriteConsoleRequest->NrCharactersWritten); if (Status == STATUS_PENDING) { if (CreateWaitBlock) { if (!CsrCreateWait(&ScreenBuffer->Header.Console->WriteWaitQueue, WriteConsoleThread, ClientThread, ApiMessage, NULL, NULL)) { /* Fail */ Status = STATUS_NO_MEMORY; goto Quit; } } /* Wait until we un-pause the console */ // Status = STATUS_PENDING; } Quit: ConSrvReleaseScreenBuffer(ScreenBuffer, FALSE); return Status; }