diff --git a/dll/win32/kernel32/client/console/readwrite.c b/dll/win32/kernel32/client/console/readwrite.c index 79462148265..7025a6e7898 100644 --- a/dll/win32/kernel32/client/console/readwrite.c +++ b/dll/win32/kernel32/client/console/readwrite.c @@ -428,68 +428,77 @@ IntWriteConsole(HANDLE hConsoleOutput, LPVOID lpReserved, BOOL bUnicode) { - PCSR_API_MESSAGE Request; - ULONG CsrRequest; NTSTATUS Status; - USHORT nChars; - ULONG SizeBytes, CharSize; - DWORD Written = 0; + CONSOLE_API_MESSAGE ApiMessage; + PCSRSS_WRITE_CONSOLE WriteConsoleRequest = &ApiMessage.Data.WriteConsoleRequest; + PCSR_CAPTURE_BUFFER CaptureBuffer; + // USHORT nChars; + ULONG /* SizeBytes, */ CharSize; + // DWORD Written = 0; CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); - Request = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + min(nNumberOfCharsToWrite, - CSRSS_MAX_WRITE_CONSOLE / CharSize) * CharSize)); - if (Request == NULL) + WriteConsoleRequest->BufferSize = nNumberOfCharsToWrite * CharSize; + + /* Allocate a Capture Buffer */ + CaptureBuffer = CsrAllocateCaptureBuffer(1, WriteConsoleRequest->BufferSize); + if (CaptureBuffer == NULL) { + DPRINT1("CsrAllocateCaptureBuffer failed!\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - CsrRequest = CSR_CREATE_API_NUMBER(CSR_CONSOLE, WRITE_CONSOLE); + /* Capture the buffer to write */ + CsrCaptureMessageBuffer(CaptureBuffer, + (PVOID)lpBuffer, + WriteConsoleRequest->BufferSize, + (PVOID*)&WriteConsoleRequest->Buffer); - while (nNumberOfCharsToWrite > 0) + /* Start writing */ + WriteConsoleRequest->NrCharactersToWrite = nNumberOfCharsToWrite; + WriteConsoleRequest->ConsoleHandle = hConsoleOutput; + WriteConsoleRequest->Unicode = bUnicode; + + // while (nNumberOfCharsToWrite > 0) { - Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput; - Request->Data.WriteConsoleRequest.Unicode = bUnicode; + //// nChars = (USHORT)min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize); + // nChars = nNumberOfCharsToWrite; + // WriteConsoleRequest->NrCharactersToWrite = nChars; - nChars = (USHORT)min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize); - Request->Data.WriteConsoleRequest.NrCharactersToWrite = nChars; + // SizeBytes = nChars * CharSize; - SizeBytes = nChars * CharSize; + // memcpy(WriteConsoleRequest->Buffer, lpBuffer, SizeBytes); - memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, SizeBytes); - - Status = CsrClientCallServer(Request, - NULL, - CsrRequest, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes)); + Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, + CaptureBuffer, + CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsole), + sizeof(CSRSS_WRITE_CONSOLE)); +/** FIXME: Added in 47359 for pausing if (Status == STATUS_PENDING) { - WaitForSingleObject(Request->Data.WriteConsoleRequest.UnpauseEvent, INFINITE); - CloseHandle(Request->Data.WriteConsoleRequest.UnpauseEvent); + WaitForSingleObject(WriteConsoleRequest->UnpauseEvent, INFINITE); + CloseHandle(WriteConsoleRequest->UnpauseEvent); continue; } - if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status)) +**/ + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status)) { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); + CsrFreeCaptureBuffer(CaptureBuffer); BaseSetLastNTError(Status); return FALSE; } - nNumberOfCharsToWrite -= nChars; - lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes); - Written += Request->Data.WriteConsoleRequest.NrCharactersWritten; + // nNumberOfCharsToWrite -= nChars; + // lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes); + // Written += WriteConsoleRequest->NrCharactersWritten; } if (lpNumberOfCharsWritten != NULL) - { - *lpNumberOfCharsWritten = Written; - } - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); + // *lpNumberOfCharsWritten = Written; + *lpNumberOfCharsWritten = WriteConsoleRequest->NrCharactersWritten; + + CsrFreeCaptureBuffer(CaptureBuffer); return TRUE; } diff --git a/win32ss/user/consrv/conoutput.c b/win32ss/user/consrv/conoutput.c index 4ffdb1cf56c..e49b31aa253 100644 --- a/win32ss/user/consrv/conoutput.c +++ b/win32ss/user/consrv/conoutput.c @@ -131,6 +131,22 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, for (i = 0; i < Length; i++) { + if (Console->UnpauseEvent) + { +/** FIXME: Added in 47359 for pausing + Status = NtDuplicateObject(NtCurrentProcess(), + Console->UnpauseEvent, + Process->ProcessHandle, + &WriteConsoleRequest->UnpauseEvent, + SYNCHRONIZE, 0, 0); + ConioUnlockScreenBuffer(Buff); + return (NT_SUCCESS(Status) ? STATUS_PENDING : Status); +**/ + + /* Wait on the console unpause event till it becomes signaled */ + WaitForSingleObject(Console->UnpauseEvent, INFINITE); + } + if (Buff->Mode & ENABLE_PROCESSED_OUTPUT) { /* --- LF --- */ @@ -230,7 +246,7 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, } } - if (! ConioIsRectEmpty(&UpdateRect) && Buff == Console->ActiveBuffer) + if (!ConioIsRectEmpty(&UpdateRect) && Buff == Console->ActiveBuffer) { ConioWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, ScrolledLines, Buffer, Length); @@ -532,37 +548,39 @@ CSR_API(SrvWriteConsole) PCSRSS_WRITE_CONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest; PCHAR Buffer; PCSRSS_SCREEN_BUFFER Buff; - PCSR_PROCESS ProcessData = CsrGetClientThread()->Process; + // PCSR_PROCESS Process = CsrGetClientThread()->Process; PCSRSS_CONSOLE Console; DWORD Written = 0; ULONG Length; - ULONG CharSize = (WriteConsoleRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + // ULONG CharSize = (WriteConsoleRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR)); DPRINT("SrvWriteConsole\n"); - if (ApiMessage->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) - + (WriteConsoleRequest->NrCharactersToWrite * CharSize)) + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID)&WriteConsoleRequest->Buffer, + WriteConsoleRequest->BufferSize, + sizeof(BYTE))) { - DPRINT1("Invalid ApiMessage size\n"); return STATUS_INVALID_PARAMETER; } - Status = ConioLockScreenBuffer(ProcessData, WriteConsoleRequest->ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } + Status = ConioLockScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), WriteConsoleRequest->ConsoleHandle, &Buff, GENERIC_WRITE); + if (!NT_SUCCESS(Status)) return Status; + Console = Buff->Header.Console; +/** FIXME: Added in 47359 for pausing if (Console->UnpauseEvent) { - Status = NtDuplicateObject(NtCurrentProcess(), Console->UnpauseEvent, - ProcessData->ProcessHandle, &WriteConsoleRequest->UnpauseEvent, + Status = NtDuplicateObject(NtCurrentProcess(), + Console->UnpauseEvent, + Process->ProcessHandle, + &WriteConsoleRequest->UnpauseEvent, SYNCHRONIZE, 0, 0); ConioUnlockScreenBuffer(Buff); - return NT_SUCCESS(Status) ? STATUS_PENDING : Status; + return (NT_SUCCESS(Status) ? STATUS_PENDING : Status); } +**/ if(WriteConsoleRequest->Unicode) { @@ -604,6 +622,7 @@ CSR_API(SrvWriteConsole) RtlFreeHeap(GetProcessHeap(), 0, Buffer); } } + ConioUnlockScreenBuffer(Buff); WriteConsoleRequest->NrCharactersWritten = Written;