From ef1e1fc82b45a65a9499ca2f02f0ee35ff11c205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Mon, 19 Nov 2012 21:48:22 +0000 Subject: [PATCH] [KERNEL32/CONSRV] - Modify the helper function IntWriteConsole to make it use of capture buffers for passing things to write. - Now, the loop disappears. - I moved the pause-event wait (introduced in revision r47359) inside consrv, and (concerning the server-api-part SrvWriteConsole), especially in the ConioWriteConsole function, to be sure that all functions calling ConioWriteConsole become sensible to pause event. This REALLY NEEDS testing (and of course the code needs cleaning of the introduced comments, when I'm sure it works). svn path=/branches/ros-csrss/; revision=57738 --- dll/win32/kernel32/client/console/readwrite.c | 81 ++++++++++--------- win32ss/user/consrv/conoutput.c | 49 +++++++---- 2 files changed, 79 insertions(+), 51 deletions(-) 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;