[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
This commit is contained in:
Hermès Bélusca-Maïto 2012-11-19 21:48:22 +00:00
parent e71f1dd200
commit ef1e1fc82b
2 changed files with 79 additions and 51 deletions

View file

@ -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;
}

View file

@ -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;