[KERNEL32][CONSRV]

- Make kernel32 / winsrv console CSR structures Win2k3-compliant for Read/WriteConsoleCharacter/Attribute and FillConsoleOutputCharacter/Attribute functions.
  The underlying CONSOLE_READOUTPUTCODE and CONSOLE_WRITEOUTPUTCODE structures are the same.
  It should be noticed, as for the Read/WriteConsoleInput functions of r63754 and the other Read/WriteConsole*** functions, that for performance purposes Windows uses a local buffer for "small" sizes;
  we should do the same too because both the client and the server use the number of elements to actually read/write in order to determine which buffer one should use (local or some shared buffer).
- Some memcpy --> RtlCopyMemory.

Part 7/X

CORE-7931

svn path=/branches/condrv_restructure/; revision=63755
This commit is contained in:
Hermès Bélusca-Maïto 2014-07-29 00:00:21 +00:00
parent e9c7111b66
commit 19e30db97b
5 changed files with 193 additions and 138 deletions

View file

@ -71,9 +71,9 @@ IntReadConsole(HANDLE hConsoleInput,
* For ANSI mode, set this parameter to NULL." * For ANSI mode, set this parameter to NULL."
*/ */
ReadConsoleRequest->NrCharactersRead = pInputControl->nInitialChars; ReadConsoleRequest->NrCharactersRead = pInputControl->nInitialChars;
memcpy(ReadConsoleRequest->Buffer, RtlCopyMemory(ReadConsoleRequest->Buffer,
lpBuffer, lpBuffer,
pInputControl->nInitialChars * sizeof(WCHAR)); pInputControl->nInitialChars * sizeof(WCHAR));
ReadConsoleRequest->CtrlWakeupMask = pInputControl->dwCtrlWakeupMask; ReadConsoleRequest->CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
} }
@ -86,9 +86,9 @@ IntReadConsole(HANDLE hConsoleInput,
/* Check for success */ /* Check for success */
if (NT_SUCCESS(ApiMessage.Status)) if (NT_SUCCESS(ApiMessage.Status))
{ {
memcpy(lpBuffer, RtlCopyMemory(lpBuffer,
ReadConsoleRequest->Buffer, ReadConsoleRequest->Buffer,
ReadConsoleRequest->NrCharactersRead * CharSize); ReadConsoleRequest->NrCharactersRead * CharSize);
if (lpNumberOfCharsRead != NULL) if (lpNumberOfCharsRead != NULL)
*lpNumberOfCharsRead = ReadConsoleRequest->NrCharactersRead; *lpNumberOfCharsRead = ReadConsoleRequest->NrCharactersRead;
@ -312,14 +312,21 @@ IntReadConsoleOutputCode(HANDLE hConsoleOutput,
COORD dwReadCoord, COORD dwReadCoord,
LPDWORD lpNumberOfCodesRead) LPDWORD lpNumberOfCodesRead)
{ {
BOOL bRet = TRUE;
CONSOLE_API_MESSAGE ApiMessage; CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &ApiMessage.Data.ReadOutputCodeRequest; PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &ApiMessage.Data.ReadOutputCodeRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer; PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
ULONG SizeBytes, CodeSize; ULONG SizeBytes, CodeSize;
DWORD CodesRead;
DPRINT("IntReadConsoleOutputCode\n");
/* Set up the data to send to the Console Server */
ReadOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
ReadOutputCodeRequest->OutputHandle = hConsoleOutput;
ReadOutputCodeRequest->Coord = dwReadCoord;
ReadOutputCodeRequest->NumCodes = nLength;
/* Determine the needed size */ /* Determine the needed size */
ReadOutputCodeRequest->CodeType = CodeType;
switch (CodeType) switch (CodeType)
{ {
case CODE_ASCII: case CODE_ASCII:
@ -340,26 +347,33 @@ IntReadConsoleOutputCode(HANDLE hConsoleOutput,
} }
SizeBytes = nLength * CodeSize; SizeBytes = nLength * CodeSize;
/* Allocate a Capture Buffer */ /*
CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes); * For optimization purposes, Windows (and hence ReactOS, too, for
if (CaptureBuffer == NULL) * compatibility reasons) uses a static buffer if no more than eighty
* bytes are read. Otherwise a new buffer is allocated.
* This behaviour is also expected in the server-side.
*/
if (SizeBytes <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
{ {
DPRINT1("CsrAllocateCaptureBuffer failed!\n"); ReadOutputCodeRequest->pCode.pCode = ReadOutputCodeRequest->CodeStaticBuffer;
SetLastError(ERROR_NOT_ENOUGH_MEMORY); // CaptureBuffer = NULL;
return FALSE;
} }
else
{
/* Allocate a Capture Buffer */
CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
if (CaptureBuffer == NULL)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
/* Allocate space in the Buffer */ /* Allocate space in the Buffer */
CsrAllocateMessagePointer(CaptureBuffer, CsrAllocateMessagePointer(CaptureBuffer,
SizeBytes, SizeBytes,
(PVOID*)&ReadOutputCodeRequest->pCode.pCode); (PVOID*)&ReadOutputCodeRequest->pCode.pCode);
}
/* Start reading */
ReadOutputCodeRequest->OutputHandle = hConsoleOutput;
ReadOutputCodeRequest->CodeType = CodeType;
ReadOutputCodeRequest->ReadCoord = dwReadCoord;
ReadOutputCodeRequest->NumCodesToRead = nLength;
/* Call the server */ /* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
@ -370,15 +384,13 @@ IntReadConsoleOutputCode(HANDLE hConsoleOutput,
/* Check for success */ /* Check for success */
if (NT_SUCCESS(ApiMessage.Status)) if (NT_SUCCESS(ApiMessage.Status))
{ {
CodesRead = ReadOutputCodeRequest->CodesRead; DWORD NumCodes = ReadOutputCodeRequest->NumCodes;
memcpy(pCode, ReadOutputCodeRequest->pCode.pCode, CodesRead * CodeSize); RtlCopyMemory(pCode,
ReadOutputCodeRequest->pCode.pCode,
// ReadOutputCodeRequest->ReadCoord = ReadOutputCodeRequest->EndCoord; NumCodes * CodeSize);
if (lpNumberOfCodesRead != NULL) if (lpNumberOfCodesRead != NULL)
*lpNumberOfCodesRead = CodesRead; *lpNumberOfCodesRead = NumCodes;
bRet = TRUE;
} }
else else
{ {
@ -387,12 +399,13 @@ IntReadConsoleOutputCode(HANDLE hConsoleOutput,
/* Error out */ /* Error out */
BaseSetLastNTError(ApiMessage.Status); BaseSetLastNTError(ApiMessage.Status);
bRet = FALSE;
} }
CsrFreeCaptureBuffer(CaptureBuffer); /* Release the capture buffer if needed */
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
return bRet; /* Return TRUE or FALSE */
return NT_SUCCESS(ApiMessage.Status);
} }
@ -651,13 +664,27 @@ IntWriteConsoleOutputCode(HANDLE hConsoleOutput,
COORD dwWriteCoord, COORD dwWriteCoord,
LPDWORD lpNumberOfCodesWritten) LPDWORD lpNumberOfCodesWritten)
{ {
BOOL bRet = TRUE;
CONSOLE_API_MESSAGE ApiMessage; CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &ApiMessage.Data.WriteOutputCodeRequest; PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &ApiMessage.Data.WriteOutputCodeRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer; PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
ULONG CodeSize; ULONG SizeBytes, CodeSize;
if (pCode == NULL)
{
SetLastError(ERROR_INVALID_ACCESS);
return FALSE;
}
DPRINT("IntWriteConsoleOutputCode\n");
/* Set up the data to send to the Console Server */
WriteOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
WriteOutputCodeRequest->OutputHandle = hConsoleOutput;
WriteOutputCodeRequest->Coord = dwWriteCoord;
WriteOutputCodeRequest->NumCodes = nLength;
/* Determine the needed size */ /* Determine the needed size */
WriteOutputCodeRequest->CodeType = CodeType;
switch (CodeType) switch (CodeType)
{ {
case CODE_ASCII: case CODE_ASCII:
@ -676,29 +703,40 @@ IntWriteConsoleOutputCode(HANDLE hConsoleOutput,
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
WriteOutputCodeRequest->BufferSize = nLength * CodeSize; SizeBytes = nLength * CodeSize;
/* Allocate a Capture Buffer */ /*
CaptureBuffer = CsrAllocateCaptureBuffer(1, WriteOutputCodeRequest->BufferSize); * For optimization purposes, Windows (and hence ReactOS, too, for
if (CaptureBuffer == NULL) * compatibility reasons) uses a static buffer if no more than eighty
* bytes are written. Otherwise a new buffer is allocated.
* This behaviour is also expected in the server-side.
*/
if (SizeBytes <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
{ {
DPRINT1("CsrAllocateCaptureBuffer failed!\n"); WriteOutputCodeRequest->pCode.pCode = WriteOutputCodeRequest->CodeStaticBuffer;
SetLastError(ERROR_NOT_ENOUGH_MEMORY); // CaptureBuffer = NULL;
return FALSE;
RtlCopyMemory(WriteOutputCodeRequest->pCode.pCode,
pCode,
SizeBytes);
} }
else
{
/* Allocate a Capture Buffer */
CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
if (CaptureBuffer == NULL)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
/* Capture the buffer to write */ /* Capture the buffer to write */
CsrCaptureMessageBuffer(CaptureBuffer, CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)pCode, (PVOID)pCode,
WriteOutputCodeRequest->BufferSize, SizeBytes,
(PVOID*)&WriteOutputCodeRequest->pCode.pCode); (PVOID*)&WriteOutputCodeRequest->pCode.pCode);
}
/* Start writing */
WriteOutputCodeRequest->OutputHandle = hConsoleOutput;
WriteOutputCodeRequest->CodeType = CodeType;
WriteOutputCodeRequest->Coord = dwWriteCoord;
WriteOutputCodeRequest->Length = (USHORT)nLength;
/* Call the server */ /* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
@ -706,16 +744,14 @@ IntWriteConsoleOutputCode(HANDLE hConsoleOutput,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutputString), CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutputString),
sizeof(*WriteOutputCodeRequest)); sizeof(*WriteOutputCodeRequest));
/* Release the capture buffer if needed */
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
/* Check for success */ /* Check for success */
if (NT_SUCCESS(ApiMessage.Status)) if (NT_SUCCESS(ApiMessage.Status))
{ {
// WriteOutputCodeRequest->Coord = WriteOutputCodeRequest->EndCoord;
if (lpNumberOfCodesWritten != NULL) if (lpNumberOfCodesWritten != NULL)
// *lpNumberOfCodesWritten = WriteOutputCodeRequest->NrCharactersWritten; *lpNumberOfCodesWritten = WriteOutputCodeRequest->NumCodes;
*lpNumberOfCodesWritten = WriteOutputCodeRequest->Length;
bRet = TRUE;
} }
else else
{ {
@ -724,12 +760,10 @@ IntWriteConsoleOutputCode(HANDLE hConsoleOutput,
/* Error out */ /* Error out */
BaseSetLastNTError(ApiMessage.Status); BaseSetLastNTError(ApiMessage.Status);
bRet = FALSE;
} }
CsrFreeCaptureBuffer(CaptureBuffer); /* Return TRUE or FALSE */
return NT_SUCCESS(ApiMessage.Status);
return bRet;
} }
@ -745,9 +779,13 @@ IntFillConsoleOutputCode(HANDLE hConsoleOutput,
CONSOLE_API_MESSAGE ApiMessage; CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &ApiMessage.Data.FillOutputRequest; PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &ApiMessage.Data.FillOutputRequest;
FillOutputRequest->OutputHandle = hConsoleOutput; /* Set up the data to send to the Console Server */
FillOutputRequest->CodeType = CodeType; FillOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
FillOutputRequest->OutputHandle = hConsoleOutput;
FillOutputRequest->WriteCoord = dwWriteCoord;
FillOutputRequest->NumCodes = nLength;
FillOutputRequest->CodeType = CodeType;
switch (CodeType) switch (CodeType)
{ {
case CODE_ASCII: case CODE_ASCII:
@ -767,10 +805,6 @@ IntFillConsoleOutputCode(HANDLE hConsoleOutput,
return FALSE; return FALSE;
} }
/* Set up the data to send to the Console Server */
FillOutputRequest->Coord = dwWriteCoord;
FillOutputRequest->Length = nLength;
/* Call the server */ /* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL, NULL,
@ -781,10 +815,7 @@ IntFillConsoleOutputCode(HANDLE hConsoleOutput,
if (NT_SUCCESS(ApiMessage.Status)) if (NT_SUCCESS(ApiMessage.Status))
{ {
if (lpNumberOfCodesWritten != NULL) if (lpNumberOfCodesWritten != NULL)
*lpNumberOfCodesWritten = FillOutputRequest->Length; *lpNumberOfCodesWritten = FillOutputRequest->NumCodes;
// *lpNumberOfCodesWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
return TRUE;
} }
else else
{ {
@ -792,8 +823,10 @@ IntFillConsoleOutputCode(HANDLE hConsoleOutput,
*lpNumberOfCodesWritten = 0; *lpNumberOfCodesWritten = 0;
BaseSetLastNTError(ApiMessage.Status); BaseSetLastNTError(ApiMessage.Status);
return FALSE;
} }
/* Return TRUE or FALSE */
return NT_SUCCESS(ApiMessage.Status);
} }

View file

@ -423,7 +423,7 @@ typedef struct
BOOL Unicode; BOOL Unicode;
COORD BufferSize; COORD BufferSize;
COORD BufferCoord; COORD BufferCoord; // WriteCoord
SMALL_RECT WriteRegion; SMALL_RECT WriteRegion;
PCHAR_INFO CharInfo; PCHAR_INFO CharInfo;
} CONSOLE_WRITEOUTPUT, *PCONSOLE_WRITEOUTPUT; } CONSOLE_WRITEOUTPUT, *PCONSOLE_WRITEOUTPUT;
@ -461,15 +461,12 @@ typedef enum _CODE_TYPE
typedef struct typedef struct
{ {
HANDLE ConsoleHandle;
HANDLE OutputHandle; HANDLE OutputHandle;
COORD Coord;
DWORD NumCodesToRead;
COORD ReadCoord;
COORD EndCoord;
DWORD CodesRead;
CODE_TYPE CodeType; CODE_TYPE CodeType;
CHAR CodeStaticBuffer[80];
union union
{ {
PVOID pCode; PVOID pCode;
@ -477,32 +474,16 @@ typedef struct
PWCHAR UnicodeChar; PWCHAR UnicodeChar;
PWORD Attribute; PWORD Attribute;
} pCode; // Either a pointer to a character or to an attribute. } pCode; // Either a pointer to a character or to an attribute.
} CONSOLE_READOUTPUTCODE, *PCONSOLE_READOUTPUTCODE;
ULONG NumCodes;
typedef struct } CONSOLE_READOUTPUTCODE , *PCONSOLE_READOUTPUTCODE,
{ CONSOLE_WRITEOUTPUTCODE, *PCONSOLE_WRITEOUTPUTCODE;
HANDLE OutputHandle;
ULONG BufferSize; // Seems unusued
WORD Length;
COORD Coord;
COORD EndCoord;
ULONG NrCharactersWritten; // Seems unusued
CODE_TYPE CodeType;
union
{
PVOID pCode;
PCHAR AsciiChar;
PWCHAR UnicodeChar;
PWORD Attribute;
} pCode; // Either a pointer to a character or to an attribute.
} CONSOLE_WRITEOUTPUTCODE, *PCONSOLE_WRITEOUTPUTCODE;
typedef struct typedef struct
{ {
HANDLE ConsoleHandle;
HANDLE OutputHandle; HANDLE OutputHandle;
COORD WriteCoord;
CODE_TYPE CodeType; CODE_TYPE CodeType;
union union
@ -512,10 +493,7 @@ typedef struct
WORD Attribute; WORD Attribute;
} Code; // Either a character or an attribute. } Code; // Either a character or an attribute.
COORD Coord; ULONG NumCodes;
ULONG Length;
ULONG NrCharactersWritten; // FIXME: Only for chars, is it removable ?
} CONSOLE_FILLOUTPUTCODE, *PCONSOLE_FILLOUTPUTCODE; } CONSOLE_FILLOUTPUTCODE, *PCONSOLE_FILLOUTPUTCODE;
typedef struct typedef struct

View file

@ -891,7 +891,7 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console,
OUT PVOID StringBuffer, OUT PVOID StringBuffer,
IN ULONG NumCodesToRead, IN ULONG NumCodesToRead,
IN PCOORD ReadCoord, IN PCOORD ReadCoord,
OUT PCOORD EndCoord, // OUT PCOORD EndCoord,
OUT PULONG CodesRead) OUT PULONG CodesRead)
{ {
SHORT Xpos, Ypos; SHORT Xpos, Ypos;
@ -901,7 +901,7 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console,
PCHAR_INFO Ptr; PCHAR_INFO Ptr;
if (Console == NULL || Buffer == NULL || if (Console == NULL || Buffer == NULL ||
ReadCoord == NULL || EndCoord == NULL || CodesRead == NULL) ReadCoord == NULL || /* EndCoord == NULL || */ CodesRead == NULL)
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
@ -997,8 +997,8 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console,
// break; // break;
// } // }
EndCoord->X = Xpos; // EndCoord->X = Xpos;
EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % Buffer->ScreenBufferSize.Y; // EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % Buffer->ScreenBufferSize.Y;
*CodesRead = (ULONG)((ULONG_PTR)ReadBuffer - (ULONG_PTR)StringBuffer) / CodeSize; *CodesRead = (ULONG)((ULONG_PTR)ReadBuffer - (ULONG_PTR)StringBuffer) / CodeSize;
// <= NumCodesToRead // <= NumCodesToRead

View file

@ -383,7 +383,7 @@ CSR_API(SrvGetConsoleInput)
* Adjust the internal pointer, because its old value points to * Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure. * the static buffer in the original ApiMessage structure.
*/ */
// GetInputRequest->RecordBufPtr = &GetInputRequest->RecordStaticBuffer; // GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer;
} }
else else
{ {

View file

@ -524,7 +524,7 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console,
OUT PVOID StringBuffer, OUT PVOID StringBuffer,
IN ULONG NumCodesToRead, IN ULONG NumCodesToRead,
IN PCOORD ReadCoord, IN PCOORD ReadCoord,
OUT PCOORD EndCoord, // OUT PCOORD EndCoord,
OUT PULONG CodesRead); OUT PULONG CodesRead);
CSR_API(SrvReadConsoleOutputString) CSR_API(SrvReadConsoleOutputString)
{ {
@ -533,6 +533,8 @@ CSR_API(SrvReadConsoleOutputString)
PTEXTMODE_SCREEN_BUFFER Buffer; PTEXTMODE_SCREEN_BUFFER Buffer;
ULONG CodeSize; ULONG CodeSize;
PVOID pCode;
DPRINT("SrvReadConsoleOutputString\n"); DPRINT("SrvReadConsoleOutputString\n");
switch (ReadOutputCodeRequest->CodeType) switch (ReadOutputCodeRequest->CodeType)
@ -553,12 +555,32 @@ CSR_API(SrvReadConsoleOutputString)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
if (!CsrValidateMessageBuffer(ApiMessage, /*
(PVOID*)&ReadOutputCodeRequest->pCode.pCode, * For optimization purposes, Windows (and hence ReactOS, too, for
ReadOutputCodeRequest->NumCodesToRead, * compatibility reasons) uses a static buffer if no more than eighty
CodeSize)) * bytes are read. Otherwise a new buffer is used.
* The client-side expects that we know this behaviour.
*/
if (ReadOutputCodeRequest->NumCodes * CodeSize <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
{ {
return STATUS_INVALID_PARAMETER; /*
* Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure.
*/
// ReadOutputCodeRequest->pCode.pCode = ReadOutputCodeRequest->CodeStaticBuffer;
pCode = ReadOutputCodeRequest->CodeStaticBuffer;
}
else
{
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&ReadOutputCodeRequest->pCode.pCode,
ReadOutputCodeRequest->NumCodes,
CodeSize))
{
return STATUS_INVALID_PARAMETER;
}
pCode = ReadOutputCodeRequest->pCode.pCode;
} }
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
@ -569,11 +591,11 @@ CSR_API(SrvReadConsoleOutputString)
Status = ConDrvReadConsoleOutputString(Buffer->Header.Console, Status = ConDrvReadConsoleOutputString(Buffer->Header.Console,
Buffer, Buffer,
ReadOutputCodeRequest->CodeType, ReadOutputCodeRequest->CodeType,
ReadOutputCodeRequest->pCode.pCode, pCode,
ReadOutputCodeRequest->NumCodesToRead, ReadOutputCodeRequest->NumCodes,
&ReadOutputCodeRequest->ReadCoord, &ReadOutputCodeRequest->Coord,
&ReadOutputCodeRequest->EndCoord, // &ReadOutputCodeRequest->EndCoord,
&ReadOutputCodeRequest->CodesRead); &ReadOutputCodeRequest->NumCodes);
ConSrvReleaseScreenBuffer(Buffer, TRUE); ConSrvReleaseScreenBuffer(Buffer, TRUE);
return Status; return Status;
@ -595,6 +617,8 @@ CSR_API(SrvWriteConsoleOutputString)
PTEXTMODE_SCREEN_BUFFER Buffer; PTEXTMODE_SCREEN_BUFFER Buffer;
ULONG CodeSize; ULONG CodeSize;
PVOID pCode;
DPRINT("SrvWriteConsoleOutputString\n"); DPRINT("SrvWriteConsoleOutputString\n");
switch (WriteOutputCodeRequest->CodeType) switch (WriteOutputCodeRequest->CodeType)
@ -615,12 +639,32 @@ CSR_API(SrvWriteConsoleOutputString)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
if (!CsrValidateMessageBuffer(ApiMessage, /*
(PVOID*)&WriteOutputCodeRequest->pCode.pCode, * For optimization purposes, Windows (and hence ReactOS, too, for
WriteOutputCodeRequest->Length, * compatibility reasons) uses a static buffer if no more than eighty
CodeSize)) * bytes are written. Otherwise a new buffer is used.
* The client-side expects that we know this behaviour.
*/
if (WriteOutputCodeRequest->NumCodes * CodeSize <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
{ {
return STATUS_INVALID_PARAMETER; /*
* Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure.
*/
// WriteOutputCodeRequest->pCode.pCode = WriteOutputCodeRequest->CodeStaticBuffer;
pCode = WriteOutputCodeRequest->CodeStaticBuffer;
}
else
{
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&WriteOutputCodeRequest->pCode.pCode,
WriteOutputCodeRequest->NumCodes,
CodeSize))
{
return STATUS_INVALID_PARAMETER;
}
pCode = WriteOutputCodeRequest->pCode.pCode;
} }
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
@ -631,9 +675,9 @@ CSR_API(SrvWriteConsoleOutputString)
Status = ConDrvWriteConsoleOutputString(Buffer->Header.Console, Status = ConDrvWriteConsoleOutputString(Buffer->Header.Console,
Buffer, Buffer,
WriteOutputCodeRequest->CodeType, WriteOutputCodeRequest->CodeType,
WriteOutputCodeRequest->pCode.pCode, pCode,
WriteOutputCodeRequest->Length, // NumCodesToWrite, WriteOutputCodeRequest->NumCodes,
&WriteOutputCodeRequest->Coord /*, // WriteCoord, &WriteOutputCodeRequest->Coord /*,
&WriteOutputCodeRequest->EndCoord, &WriteOutputCodeRequest->EndCoord,
&WriteOutputCodeRequest->NrCharactersWritten */); &WriteOutputCodeRequest->NrCharactersWritten */);
@ -676,8 +720,8 @@ CSR_API(SrvFillConsoleOutput)
Buffer, Buffer,
CodeType, CodeType,
&FillOutputRequest->Code, &FillOutputRequest->Code,
FillOutputRequest->Length, // NumCodesToWrite, FillOutputRequest->NumCodes,
&FillOutputRequest->Coord /*, // WriteCoord, &FillOutputRequest->WriteCoord /*,
&FillOutputRequest->NrCharactersWritten */); &FillOutputRequest->NrCharactersWritten */);
// FillOutputRequest->NrCharactersWritten = Written; // FillOutputRequest->NrCharactersWritten = Written;