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

View file

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

View file

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

View file

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

View file

@ -524,7 +524,7 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console,
OUT PVOID StringBuffer,
IN ULONG NumCodesToRead,
IN PCOORD ReadCoord,
OUT PCOORD EndCoord,
// OUT PCOORD EndCoord,
OUT PULONG CodesRead);
CSR_API(SrvReadConsoleOutputString)
{
@ -533,6 +533,8 @@ CSR_API(SrvReadConsoleOutputString)
PTEXTMODE_SCREEN_BUFFER Buffer;
ULONG CodeSize;
PVOID pCode;
DPRINT("SrvReadConsoleOutputString\n");
switch (ReadOutputCodeRequest->CodeType)
@ -553,12 +555,32 @@ CSR_API(SrvReadConsoleOutputString)
return STATUS_INVALID_PARAMETER;
}
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&ReadOutputCodeRequest->pCode.pCode,
ReadOutputCodeRequest->NumCodesToRead,
CodeSize))
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than eighty
* 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),
@ -569,11 +591,11 @@ CSR_API(SrvReadConsoleOutputString)
Status = ConDrvReadConsoleOutputString(Buffer->Header.Console,
Buffer,
ReadOutputCodeRequest->CodeType,
ReadOutputCodeRequest->pCode.pCode,
ReadOutputCodeRequest->NumCodesToRead,
&ReadOutputCodeRequest->ReadCoord,
&ReadOutputCodeRequest->EndCoord,
&ReadOutputCodeRequest->CodesRead);
pCode,
ReadOutputCodeRequest->NumCodes,
&ReadOutputCodeRequest->Coord,
// &ReadOutputCodeRequest->EndCoord,
&ReadOutputCodeRequest->NumCodes);
ConSrvReleaseScreenBuffer(Buffer, TRUE);
return Status;
@ -595,6 +617,8 @@ CSR_API(SrvWriteConsoleOutputString)
PTEXTMODE_SCREEN_BUFFER Buffer;
ULONG CodeSize;
PVOID pCode;
DPRINT("SrvWriteConsoleOutputString\n");
switch (WriteOutputCodeRequest->CodeType)
@ -615,12 +639,32 @@ CSR_API(SrvWriteConsoleOutputString)
return STATUS_INVALID_PARAMETER;
}
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&WriteOutputCodeRequest->pCode.pCode,
WriteOutputCodeRequest->Length,
CodeSize))
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than eighty
* 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),
@ -631,9 +675,9 @@ CSR_API(SrvWriteConsoleOutputString)
Status = ConDrvWriteConsoleOutputString(Buffer->Header.Console,
Buffer,
WriteOutputCodeRequest->CodeType,
WriteOutputCodeRequest->pCode.pCode,
WriteOutputCodeRequest->Length, // NumCodesToWrite,
&WriteOutputCodeRequest->Coord /*, // WriteCoord,
pCode,
WriteOutputCodeRequest->NumCodes,
&WriteOutputCodeRequest->Coord /*,
&WriteOutputCodeRequest->EndCoord,
&WriteOutputCodeRequest->NrCharactersWritten */);
@ -676,8 +720,8 @@ CSR_API(SrvFillConsoleOutput)
Buffer,
CodeType,
&FillOutputRequest->Code,
FillOutputRequest->Length, // NumCodesToWrite,
&FillOutputRequest->Coord /*, // WriteCoord,
FillOutputRequest->NumCodes,
&FillOutputRequest->WriteCoord /*,
&FillOutputRequest->NrCharactersWritten */);
// FillOutputRequest->NrCharactersWritten = Written;