From 90229a39a0af4f487c30ec696a0e2f06338eb441 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Mon, 19 Nov 2012 23:26:36 +0000 Subject: [PATCH] [KERNEL32/CONSRV] - Merge IntWriteConsoleOutputCharacter and WriteConsoleOutputAttribute functions into IntWriteConsoleOutputCode helper functions, which is used inside WriteConsoleOutputAttribute and WriteConsoleOutputCharacterW/A. - In server-side, merge CsrWriteConsoleOutputChar and CsrWriteConsoleOutputAttrib into the server API SrvWriteConsoleOutputString. - The structures CSRSS_WRITE_CONSOLE_OUTPUT_CHAR and CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB are merged into CSRSS_WRITE_CONSOLE_OUTPUT_CODE. [CONSRV] - Add a CsrValidateMessageBuffer usage. svn path=/branches/ros-csrss/; revision=57740 --- dll/win32/kernel32/client/console/readwrite.c | 205 ++++++++------- include/reactos/subsys/win/conmsg.h | 60 ++--- win32ss/user/consrv/conoutput.c | 238 ++++++++---------- 3 files changed, 232 insertions(+), 271 deletions(-) diff --git a/dll/win32/kernel32/client/console/readwrite.c b/dll/win32/kernel32/client/console/readwrite.c index 7025a6e7898..5cda80672ce 100644 --- a/dll/win32/kernel32/client/console/readwrite.c +++ b/dll/win32/kernel32/client/console/readwrite.c @@ -436,6 +436,7 @@ IntWriteConsole(HANDLE hConsoleOutput, ULONG /* SizeBytes, */ CharSize; // DWORD Written = 0; + /* Determine the needed size */ CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); WriteConsoleRequest->BufferSize = nNumberOfCharsToWrite * CharSize; @@ -654,75 +655,109 @@ IntWriteConsoleOutput(HANDLE hConsoleOutput, static BOOL -IntWriteConsoleOutputCharacter(HANDLE hConsoleOutput, - PVOID lpCharacter, - DWORD nLength, - COORD dwWriteCoord, - LPDWORD lpNumberOfCharsWritten, - BOOL bUnicode) +IntWriteConsoleOutputCode(HANDLE hConsoleOutput, + CODE_TYPE CodeType, + CONST VOID *pCode, + DWORD nLength, + COORD dwWriteCoord, + LPDWORD lpNumberOfCodesWritten) { - PCSR_API_MESSAGE Request; - ULONG CsrRequest; NTSTATUS Status; - ULONG CharSize, nChars; - //ULONG SizeBytes; - DWORD Written = 0; + CONSOLE_API_MESSAGE ApiMessage; + PCSRSS_WRITE_CONSOLE_OUTPUT_CODE WriteConsoleOutputCodeRequest = &ApiMessage.Data.WriteConsoleOutputCodeRequest; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CodeSize; //, nChars; + // ULONG SizeBytes; + // DWORD Written = 0; - CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); + /* Determine the needed size */ +/* + CodeSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); + nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CodeSize); + SizeBytes = nChars * CodeSize; +*/ + switch (CodeType) + { + case CODE_ASCII: + CodeSize = sizeof(CHAR); + break; - nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize); - //SizeBytes = nChars * CharSize; + case CODE_UNICODE: + CodeSize = sizeof(WCHAR); + break; - Request = RtlAllocateHeap(RtlGetProcessHeap(), 0, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) - + min (nChars, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize)); - if (Request == NULL) + case CODE_ATTRIBUTE: + CodeSize = sizeof(WORD); + break; + + default: + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + WriteConsoleOutputCodeRequest->BufferSize = nLength * CodeSize; + + /* Allocate a Capture Buffer */ + CaptureBuffer = CsrAllocateCaptureBuffer(1, WriteConsoleOutputCodeRequest->BufferSize); + if (CaptureBuffer == NULL) { + DPRINT1("CsrAllocateCaptureBuffer failed!\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - CsrRequest = CSR_CREATE_API_NUMBER(CSR_CONSOLE, WRITE_CONSOLE_OUTPUT_CHAR); - Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord; +/* + /\* Allocate space in the Buffer *\/ + CsrAllocateMessagePointer(CaptureBuffer, + SizeBytes, + (PVOID*)&WriteConsoleOutputCodeRequest->pCode.pCode); +*/ + /* Capture the buffer to write */ + CsrCaptureMessageBuffer(CaptureBuffer, + (PVOID)pCode, + WriteConsoleOutputCodeRequest->BufferSize, + (PVOID*)&WriteConsoleOutputCodeRequest->pCode.pCode); - while (nLength > 0) - { - DWORD BytesWrite; + /* Start writing */ + WriteConsoleOutputCodeRequest->ConsoleHandle = hConsoleOutput; + WriteConsoleOutputCodeRequest->CodeType = CodeType; + WriteConsoleOutputCodeRequest->Coord = dwWriteCoord; - Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput; - Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode; - Request->Data.WriteConsoleOutputCharRequest.Length = (WORD)min(nLength, nChars); - BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize; + /** + ** TODO: HACK: Surely it has to go into CONSRV !! + **/ + // while (nLength > 0) + { + // DWORD BytesWrite; - memcpy(Request->Data.WriteConsoleOutputCharRequest.String, lpCharacter, BytesWrite); + WriteConsoleOutputCodeRequest->Length = nLength; // (WORD)min(nLength, nChars); + // BytesWrite = WriteConsoleOutputCodeRequest->Length * CodeSize; - Status = CsrClientCallServer(Request, - NULL, - CsrRequest, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + BytesWrite)); + // memcpy(WriteConsoleOutputCodeRequest->pCode.pCode, pCode, BytesWrite); - if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status)) + Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, + CaptureBuffer, + CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutputString), + sizeof(CSRSS_WRITE_CONSOLE_OUTPUT_CODE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status)) { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); + CsrFreeCaptureBuffer(CaptureBuffer); BaseSetLastNTError(Status); return FALSE; } - nLength -= Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten; - lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)(Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten * CharSize)); - Written += Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten; + // nLength -= WriteConsoleOutputCodeRequest->NrCharactersWritten; + // pCode = (PVOID)((ULONG_PTR)pCode + /*(ULONG_PTR)(*/WriteConsoleOutputCodeRequest->NrCharactersWritten * CodeSize/*)*/); + // Written += WriteConsoleOutputCodeRequest->NrCharactersWritten; - Request->Data.WriteConsoleOutputCharRequest.Coord = Request->Data.WriteConsoleOutputCharRequest.EndCoord; + WriteConsoleOutputCodeRequest->Coord = WriteConsoleOutputCodeRequest->EndCoord; } - if (lpNumberOfCharsWritten != NULL) - { - *lpNumberOfCharsWritten = Written; - } + if (lpNumberOfCodesWritten != NULL) + // *lpNumberOfCodesWritten = Written; + // *lpNumberOfCodesWritten = WriteConsoleOutputCodeRequest->NrCharactersWritten; + *lpNumberOfCodesWritten = WriteConsoleOutputCodeRequest->Length; - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); + CsrFreeCaptureBuffer(CaptureBuffer); return TRUE; } @@ -778,7 +813,7 @@ IntFillConsoleOutputCode(HANDLE hConsoleOutput, if (lpNumberOfCodesWritten) *lpNumberOfCodesWritten = FillOutputRequest->Length; - // *lpNumberOfCharsWritten = Request.Data.FillOutputRequest.NrCharactersWritten; + // *lpNumberOfCodesWritten = Request.Data.FillOutputRequest.NrCharactersWritten; return TRUE; } @@ -1191,12 +1226,12 @@ WriteConsoleOutputCharacterW(HANDLE hConsoleOutput, COORD dwWriteCoord, LPDWORD lpNumberOfCharsWritten) { - return IntWriteConsoleOutputCharacter(hConsoleOutput, - (PVOID)lpCharacter, - nLength, - dwWriteCoord, - lpNumberOfCharsWritten, - TRUE); + return IntWriteConsoleOutputCode(hConsoleOutput, + CODE_UNICODE, + lpCharacter, + nLength, + dwWriteCoord, + lpNumberOfCharsWritten); } @@ -1213,12 +1248,12 @@ WriteConsoleOutputCharacterA(HANDLE hConsoleOutput, COORD dwWriteCoord, LPDWORD lpNumberOfCharsWritten) { - return IntWriteConsoleOutputCharacter(hConsoleOutput, - (PVOID)lpCharacter, - nLength, - dwWriteCoord, - lpNumberOfCharsWritten, - FALSE); + return IntWriteConsoleOutputCode(hConsoleOutput, + CODE_ASCII, + lpCharacter, + nLength, + dwWriteCoord, + lpNumberOfCharsWritten); } @@ -1235,54 +1270,12 @@ WriteConsoleOutputAttribute(HANDLE hConsoleOutput, COORD dwWriteCoord, LPDWORD lpNumberOfAttrsWritten) { - PCSR_API_MESSAGE Request; - ULONG CsrRequest; - NTSTATUS Status; - WORD Size; - - Request = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) - + min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD))); - if (Request == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - CsrRequest = CSR_CREATE_API_NUMBER(CSR_CONSOLE, WRITE_CONSOLE_OUTPUT_ATTRIB); - Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord; - - if (lpNumberOfAttrsWritten) - *lpNumberOfAttrsWritten = nLength; - while (nLength) - { - Size = (WORD)min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)); - Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput; - Request->Data.WriteConsoleOutputAttribRequest.Length = Size; - memcpy(Request->Data.WriteConsoleOutputAttribRequest.Attribute, lpAttribute, Size * sizeof(WORD)); - - Status = CsrClientCallServer(Request, - NULL, - CsrRequest, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD))); - - if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status)) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - BaseSetLastNTError (Status); - return FALSE; - } - nLength -= Size; - lpAttribute += Size; - Request->Data.WriteConsoleOutputAttribRequest.Coord = Request->Data.WriteConsoleOutputAttribRequest.EndCoord; - } - - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - - return TRUE; + return IntWriteConsoleOutputCode(hConsoleOutput, + CODE_ATTRIBUTE, + lpAttribute, + nLength, + dwWriteCoord, + lpNumberOfAttrsWritten); } diff --git a/include/reactos/subsys/win/conmsg.h b/include/reactos/subsys/win/conmsg.h index 604154a567e..32b1faee6f4 100644 --- a/include/reactos/subsys/win/conmsg.h +++ b/include/reactos/subsys/win/conmsg.h @@ -26,7 +26,7 @@ typedef enum _CONSRV_API_NUMBER ConsolepReadConsoleOutput, ConsolepWriteConsoleOutput, ConsolepReadConsoleOutputString, - // ConsolepWriteConsoleOutputString, + ConsolepWriteConsoleOutputString, ConsolepFillConsoleOutput, ConsolepGetMode, // ConsolepGetNumberOfFonts, @@ -112,13 +112,6 @@ typedef enum _CONSRV_API_NUMBER } CONSRV_API_NUMBER, *PCONSRV_API_NUMBER; -#define CSR_API_MESSAGE_HEADER_SIZE(Type) (FIELD_OFFSET(CSR_API_MESSAGE, Data) + sizeof(Type)) -#define CSRSS_MAX_WRITE_CONSOLE (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE)) -#define CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)) -#define CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)) -#define CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR)) -#define CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)) - #define CONSOLE_INPUT_MODE_VALID (0x0f) #define CONSOLE_OUTPUT_MODE_VALID (0x03) @@ -150,12 +143,12 @@ typedef struct WORD NrCharactersRead; HANDLE EventHandle; - PVOID Buffer; - ULONG BufferSize; - UNICODE_STRING ExeName; DWORD CtrlWakeupMask; DWORD ControlKeyState; + + ULONG BufferSize; + PVOID Buffer; } CSRSS_READ_CONSOLE, *PCSRSS_READ_CONSOLE; typedef struct @@ -185,26 +178,6 @@ typedef struct COORD Position; } CSRSS_SET_CURSOR_POSITION, *PCSRSS_SET_CURSOR_POSITION; -typedef struct -{ - HANDLE ConsoleHandle; - BOOL Unicode; - WORD Length; - COORD Coord; - COORD EndCoord; - ULONG NrCharactersWritten; - CHAR String[0]; -} CSRSS_WRITE_CONSOLE_OUTPUT_CHAR, *PCSRSS_WRITE_CONSOLE_OUTPUT_CHAR; - -typedef struct -{ - HANDLE ConsoleHandle; - WORD Length; - COORD Coord; - COORD EndCoord; - WORD Attribute[0]; -} CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB, *PCSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB; - typedef struct { HANDLE ConsoleHandle; @@ -301,6 +274,28 @@ typedef struct } pCode; // Either a pointer to a character or to an attribute. } CSRSS_READ_CONSOLE_OUTPUT_CODE, *PCSRSS_READ_CONSOLE_OUTPUT_CODE; +typedef struct +{ + HANDLE ConsoleHandle; + USHORT CodeType; + + ULONG BufferSize; + WORD Length; + COORD Coord; + COORD EndCoord; + + ULONG NrCharactersWritten; + + union + { + // PVOID String; + PVOID pCode; + PCHAR AsciiChar; + PWCHAR UnicodeChar; + PWORD Attribute; + } pCode; // Either a pointer to a character or to an attribute. +} CSRSS_WRITE_CONSOLE_OUTPUT_CODE, *PCSRSS_WRITE_CONSOLE_OUTPUT_CODE; + typedef struct { HANDLE ConsoleHandle; @@ -588,8 +583,7 @@ typedef struct _CONSOLE_API_MESSAGE CSRSS_WRITE_CONSOLE WriteConsoleRequest; // SrvWriteConsole / WriteConsole CSRSS_WRITE_CONSOLE_INPUT WriteConsoleInputRequest; CSRSS_WRITE_CONSOLE_OUTPUT WriteConsoleOutputRequest; - CSRSS_WRITE_CONSOLE_OUTPUT_CHAR WriteConsoleOutputCharRequest; - CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB WriteConsoleOutputAttribRequest; + CSRSS_WRITE_CONSOLE_OUTPUT_CODE WriteConsoleOutputCodeRequest; CSRSS_FILL_OUTPUT FillOutputRequest; CSRSS_SET_ATTRIB SetAttribRequest; diff --git a/win32ss/user/consrv/conoutput.c b/win32ss/user/consrv/conoutput.c index e49b31aa253..623a5f65fba 100644 --- a/win32ss/user/consrv/conoutput.c +++ b/win32ss/user/consrv/conoutput.c @@ -469,6 +469,11 @@ CSR_API(SrvReadConsoleOutput) DPRINT("SrvReadConsoleOutput\n"); + CharInfo = ReadConsoleOutputRequest->CharInfo; + ReadRegion = ReadConsoleOutputRequest->ReadRegion; + BufferSize = ReadConsoleOutputRequest->BufferSize; + BufferCoord = ReadConsoleOutputRequest->BufferCoord; + if (!CsrValidateMessageBuffer(ApiMessage, (PVOID*)&ReadConsoleOutputRequest->CharInfo, BufferSize.X * BufferSize.Y, @@ -480,11 +485,6 @@ CSR_API(SrvReadConsoleOutput) Status = ConioLockScreenBuffer(ProcessData, ReadConsoleOutputRequest->ConsoleHandle, &Buff, GENERIC_READ); if (!NT_SUCCESS(Status)) return Status; - CharInfo = ReadConsoleOutputRequest->CharInfo; - ReadRegion = ReadConsoleOutputRequest->ReadRegion; - BufferSize = ReadConsoleOutputRequest->BufferSize; - BufferCoord = ReadConsoleOutputRequest->BufferCoord; - /* if (!Win32CsrValidateBuffer(ProcessData->Process, CharInfo, BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO))) @@ -648,6 +648,10 @@ CSR_API(SrvWriteConsoleOutput) DPRINT("SrvWriteConsoleOutput\n"); + BufferSize = WriteConsoleOutputRequest->BufferSize; + BufferCoord = WriteConsoleOutputRequest->BufferCoord; + CharInfo = WriteConsoleOutputRequest->CharInfo; + if (!CsrValidateMessageBuffer(ApiMessage, (PVOID*)&WriteConsoleOutputRequest->CharInfo, BufferSize.X * BufferSize.Y, @@ -664,10 +668,6 @@ CSR_API(SrvWriteConsoleOutput) Console = Buff->Header.Console; - BufferSize = WriteConsoleOutputRequest->BufferSize; - BufferCoord = WriteConsoleOutputRequest->BufferCoord; - CharInfo = WriteConsoleOutputRequest->CharInfo; - /* if (!Win32CsrValidateBuffer(ProcessData->Process, CharInfo, BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO))) @@ -743,8 +743,6 @@ CSR_API(SrvReadConsoleOutputString) DPRINT("SrvReadConsoleOutputString\n"); - ReadBuffer = ReadConsoleOutputCodeRequest->pCode.pCode; - CodeType = ReadConsoleOutputCodeRequest->CodeType; switch (CodeType) { @@ -764,11 +762,20 @@ CSR_API(SrvReadConsoleOutputString) return STATUS_INVALID_PARAMETER; } + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&ReadConsoleOutputCodeRequest->pCode.pCode, + ReadConsoleOutputCodeRequest->NumCodesToRead, + CodeSize)) + { + return STATUS_INVALID_PARAMETER; + } + Status = ConioLockScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), ReadConsoleOutputCodeRequest->ConsoleHandle, &Buff, GENERIC_READ); if (!NT_SUCCESS(Status)) return Status; Console = Buff->Header.Console; + ReadBuffer = ReadConsoleOutputCodeRequest->pCode.pCode; Xpos = ReadConsoleOutputCodeRequest->ReadCoord.X; Ypos = (ReadConsoleOutputCodeRequest->ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; @@ -845,169 +852,136 @@ CSR_API(SrvReadConsoleOutputString) return STATUS_SUCCESS; } -CSR_API(CsrWriteConsoleOutputChar) +CSR_API(SrvWriteConsoleOutputString) { NTSTATUS Status; - PCSRSS_WRITE_CONSOLE_OUTPUT_CHAR WriteConsoleOutputCharRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleOutputCharRequest; - PCHAR String, tmpString = NULL; - PBYTE Buffer; + PCSRSS_WRITE_CONSOLE_OUTPUT_CODE WriteConsoleOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleOutputCodeRequest; PCSRSS_CONSOLE Console; PCSRSS_SCREEN_BUFFER Buff; - DWORD X, Y, Length, CharSize, Written = 0; + USHORT CodeType; + PBYTE Buffer; // PUCHAR + PCHAR String, tmpString = NULL; + DWORD X, Y, Length; // , Written = 0; + ULONG CodeSize; SMALL_RECT UpdateRect; - DPRINT("CsrWriteConsoleOutputChar\n"); + DPRINT("SrvWriteConsoleOutputString\n"); + + CodeType = WriteConsoleOutputCodeRequest->CodeType; + switch (CodeType) + { + case CODE_ASCII: + CodeSize = sizeof(CHAR); + break; - CharSize = (WriteConsoleOutputCharRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + case CODE_UNICODE: + CodeSize = sizeof(WCHAR); + break; + + case CODE_ATTRIBUTE: + CodeSize = sizeof(WORD); + break; - if (ApiMessage->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) - + (WriteConsoleOutputCharRequest->Length * CharSize)) + default: + return STATUS_INVALID_PARAMETER; + } + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&WriteConsoleOutputCodeRequest->pCode.pCode, + WriteConsoleOutputCodeRequest->Length, + CodeSize)) { - DPRINT1("Invalid ApiMessage size\n"); return STATUS_INVALID_PARAMETER; } - Status = ConioLockScreenBuffer(CsrGetClientThread()->Process, - WriteConsoleOutputCharRequest->ConsoleHandle, + Status = ConioLockScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + WriteConsoleOutputCodeRequest->ConsoleHandle, &Buff, GENERIC_WRITE); - if (NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) return Status; + + Console = Buff->Header.Console; + + switch (CodeType) { - Console = Buff->Header.Console; - if(WriteConsoleOutputCharRequest->Unicode) + case CODE_UNICODE: { Length = WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)WriteConsoleOutputCharRequest->String, - WriteConsoleOutputCharRequest->Length, + (PWCHAR)WriteConsoleOutputCodeRequest->pCode.UnicodeChar, + WriteConsoleOutputCodeRequest->Length, NULL, 0, NULL, NULL); tmpString = String = RtlAllocateHeap(GetProcessHeap(), 0, Length); if (String) { WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)WriteConsoleOutputCharRequest->String, - WriteConsoleOutputCharRequest->Length, + (PWCHAR)WriteConsoleOutputCodeRequest->pCode.UnicodeChar, + WriteConsoleOutputCodeRequest->Length, String, Length, NULL, NULL); } else { Status = STATUS_NO_MEMORY; } - } - else - { - String = (PCHAR)WriteConsoleOutputCharRequest->String; - } - if (String) - { - if (NT_SUCCESS(Status)) - { - X = WriteConsoleOutputCharRequest->Coord.X; - Y = (WriteConsoleOutputCharRequest->Coord.Y + Buff->VirtualY) % Buff->MaxY; - Length = WriteConsoleOutputCharRequest->Length; - Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; - while (Length--) - { - *Buffer = *String++; - Written++; - Buffer += 2; - if (++X == Buff->MaxX) - { - if (++Y == Buff->MaxY) - { - Y = 0; - Buffer = Buff->Buffer; - } - X = 0; - } - } - if (Buff == Console->ActiveBuffer) - { - ConioComputeUpdateRect(Buff, &UpdateRect, &WriteConsoleOutputCharRequest->Coord, - WriteConsoleOutputCharRequest->Length); - ConioDrawRegion(Console, &UpdateRect); - } - - WriteConsoleOutputCharRequest->EndCoord.X = X; - WriteConsoleOutputCharRequest->EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; - - } - if (WriteConsoleOutputCharRequest->Unicode) - { - RtlFreeHeap(GetProcessHeap(), 0, tmpString); - } + break; } - ConioUnlockScreenBuffer(Buff); - } - WriteConsoleOutputCharRequest->NrCharactersWritten = Written; - return Status; -} - -CSR_API(CsrWriteConsoleOutputAttrib) -{ - PCSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB WriteConsoleOutputAttribRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleOutputAttribRequest; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - PUCHAR Buffer; - PWORD Attribute; - int X, Y, Length; - NTSTATUS Status; - SMALL_RECT UpdateRect; - DPRINT("CsrWriteConsoleOutputAttrib\n"); + case CODE_ASCII: + String = (PCHAR)WriteConsoleOutputCodeRequest->pCode.AsciiChar; + break; - if (ApiMessage->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) - + WriteConsoleOutputAttribRequest->Length * sizeof(WORD)) - { - DPRINT1("Invalid ApiMessage size\n"); - return STATUS_INVALID_PARAMETER; + case CODE_ATTRIBUTE: + default: + // *(ReadBuffer++) = Code; + String = (PCHAR)WriteConsoleOutputCodeRequest->pCode.Attribute; + break; } - Status = ConioLockScreenBuffer(CsrGetClientThread()->Process, - WriteConsoleOutputAttribRequest->ConsoleHandle, - &Buff, - GENERIC_WRITE); - if (! NT_SUCCESS(Status)) + if (String && NT_SUCCESS(Status)) { - return Status; - } - Console = Buff->Header.Console; + X = WriteConsoleOutputCodeRequest->Coord.X; + Y = (WriteConsoleOutputCodeRequest->Coord.Y + Buff->VirtualY) % Buff->MaxY; + Length = WriteConsoleOutputCodeRequest->Length; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)]; - X = WriteConsoleOutputAttribRequest->Coord.X; - Y = (WriteConsoleOutputAttribRequest->Coord.Y + Buff->VirtualY) % Buff->MaxY; - Length = WriteConsoleOutputAttribRequest->Length; - Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1]; - Attribute = WriteConsoleOutputAttribRequest->Attribute; - while (Length--) - { - *Buffer = (UCHAR)(*Attribute++); - Buffer += 2; - if (++X == Buff->MaxX) + while (Length--) { - if (++Y == Buff->MaxY) + *Buffer = *String++; + // ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize); + String = (PCHAR)((ULONG_PTR)String + CodeSize); + // Written++; + Buffer += 2; + if (++X == Buff->MaxX) { - Y = 0; - Buffer = Buff->Buffer + 1; + if (++Y == Buff->MaxY) + { + Y = 0; + Buffer = Buff->Buffer + (CodeType == CODE_ATTRIBUTE ? 1 : 0); + } + X = 0; } - X = 0; } + + if (Buff == Console->ActiveBuffer) + { + ConioComputeUpdateRect(Buff, &UpdateRect, &WriteConsoleOutputCodeRequest->Coord, + WriteConsoleOutputCodeRequest->Length); + ConioDrawRegion(Console, &UpdateRect); + } + + WriteConsoleOutputCodeRequest->EndCoord.X = X; + WriteConsoleOutputCodeRequest->EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; } - if (Buff == Console->ActiveBuffer) + if (tmpString) { - ConioComputeUpdateRect(Buff, &UpdateRect, &WriteConsoleOutputAttribRequest->Coord, - WriteConsoleOutputAttribRequest->Length); - ConioDrawRegion(Console, &UpdateRect); + RtlFreeHeap(GetProcessHeap(), 0, tmpString); } - WriteConsoleOutputAttribRequest->EndCoord.X = X; - WriteConsoleOutputAttribRequest->EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; - ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; + // WriteConsoleOutputCodeRequest->NrCharactersWritten = Written; + return Status; } CSR_API(SrvFillConsoleOutput) @@ -1016,7 +990,7 @@ CSR_API(SrvFillConsoleOutput) PCSRSS_FILL_OUTPUT FillOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FillOutputRequest; PCSRSS_CONSOLE Console; PCSRSS_SCREEN_BUFFER Buff; - DWORD X, Y, Length, Start; // , Written = 0; + DWORD X, Y, Length; // , Written = 0; USHORT CodeType; BYTE Code; PBYTE Buffer; @@ -1034,8 +1008,7 @@ CSR_API(SrvFillConsoleOutput) X = FillOutputRequest->Coord.X; Y = (FillOutputRequest->Coord.Y + Buff->VirtualY) % Buff->MaxY; Length = FillOutputRequest->Length; - Start = 2 * (Y * Buff->MaxX + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0); - Buffer = &Buff->Buffer[Start]; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)]; switch (CodeType) { @@ -1296,7 +1269,7 @@ CSR_API(SrvGetConsoleScreenBufferInfo) PCSRSS_SCREEN_BUFFER_INFO ScreenBufferInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScreenBufferInfoRequest; PCSRSS_CONSOLE Console; PCSRSS_SCREEN_BUFFER Buff; - PCONSOLE_SCREEN_BUFFER_INFO pInfo; + PCONSOLE_SCREEN_BUFFER_INFO pInfo = &ScreenBufferInfoRequest->Info; DPRINT("SrvGetConsoleScreenBufferInfo\n"); @@ -1304,7 +1277,7 @@ CSR_API(SrvGetConsoleScreenBufferInfo) if (!NT_SUCCESS(Status)) return Status; Console = Buff->Header.Console; - pInfo = &ScreenBufferInfoRequest->Info; + pInfo->dwSize.X = Buff->MaxX; pInfo->dwSize.Y = Buff->MaxY; pInfo->dwCursorPosition.X = Buff->CurrentX; @@ -1316,6 +1289,7 @@ CSR_API(SrvGetConsoleScreenBufferInfo) pInfo->srWindow.Bottom = Buff->ShowY + Console->Size.Y - 1; pInfo->dwMaximumWindowSize.X = Buff->MaxX; pInfo->dwMaximumWindowSize.Y = Buff->MaxY; + ConioUnlockScreenBuffer(Buff); return STATUS_SUCCESS; -- 2.17.1