[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
This commit is contained in:
Hermès Bélusca-Maïto 2012-11-19 23:26:36 +00:00
parent 5e77b6714d
commit 90229a39a0
3 changed files with 236 additions and 275 deletions

View file

@ -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));
nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize);
//SizeBytes = nChars * CharSize;
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)
/* 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;
case CODE_UNICODE:
CodeSize = sizeof(WCHAR);
break;
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)
/* Start writing */
WriteConsoleOutputCodeRequest->ConsoleHandle = hConsoleOutput;
WriteConsoleOutputCodeRequest->CodeType = CodeType;
WriteConsoleOutputCodeRequest->Coord = dwWriteCoord;
/**
** TODO: HACK: Surely it has to go into CONSRV !!
**/
// while (nLength > 0)
{
DWORD BytesWrite;
// DWORD BytesWrite;
Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode;
Request->Data.WriteConsoleOutputCharRequest.Length = (WORD)min(nLength, nChars);
BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize;
WriteConsoleOutputCodeRequest->Length = nLength; // (WORD)min(nLength, nChars);
// BytesWrite = WriteConsoleOutputCodeRequest->Length * CodeSize;
memcpy(Request->Data.WriteConsoleOutputCharRequest.String, lpCharacter, BytesWrite);
// memcpy(WriteConsoleOutputCodeRequest->pCode.pCode, pCode, BytesWrite);
Status = CsrClientCallServer(Request,
NULL,
CsrRequest,
max(sizeof(CSR_API_MESSAGE),
CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + 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);
}

View file

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

View file

@ -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");
CharSize = (WriteConsoleOutputCharRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR));
if (ApiMessage->Header.u1.s1.TotalLength
< CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
+ (WriteConsoleOutputCharRequest->Length * CharSize))
CodeType = WriteConsoleOutputCodeRequest->CodeType;
switch (CodeType)
{
case CODE_ASCII:
CodeSize = sizeof(CHAR);
break;
case CODE_UNICODE:
CodeSize = sizeof(WCHAR);
break;
case CODE_ATTRIBUTE:
CodeSize = sizeof(WORD);
break;
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;
break;
}
if (String)
case CODE_ASCII:
String = (PCHAR)WriteConsoleOutputCodeRequest->pCode.AsciiChar;
break;
case CODE_ATTRIBUTE:
default:
// *(ReadBuffer++) = Code;
String = (PCHAR)WriteConsoleOutputCodeRequest->pCode.Attribute;
break;
}
if (String && NT_SUCCESS(Status))
{
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)];
while (Length--)
{
if (NT_SUCCESS(Status))
*Buffer = *String++;
// ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize);
String = (PCHAR)((ULONG_PTR)String + CodeSize);
// Written++;
Buffer += 2;
if (++X == Buff->MaxX)
{
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--)
if (++Y == Buff->MaxY)
{
*Buffer = *String++;
Written++;
Buffer += 2;
if (++X == Buff->MaxX)
{
if (++Y == Buff->MaxY)
{
Y = 0;
Buffer = Buff->Buffer;
}
X = 0;
}
Y = 0;
Buffer = Buff->Buffer + (CodeType == CODE_ATTRIBUTE ? 1 : 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);
X = 0;
}
}
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");
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;
}
Status = ConioLockScreenBuffer(CsrGetClientThread()->Process,
WriteConsoleOutputAttribRequest->ConsoleHandle,
&Buff,
GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
return Status;
}
Console = Buff->Header.Console;
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)
if (Buff == Console->ActiveBuffer)
{
if (++Y == Buff->MaxY)
{
Y = 0;
Buffer = Buff->Buffer + 1;
}
X = 0;
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;