reactos/dll/win32/kernel32/client/console/readwrite.c

1737 lines
52 KiB
C
Raw Normal View History

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: dll/win32/kernel32/client/console/readwrite.c
* PURPOSE: Win32 Console Client read-write functions
* PROGRAMMERS: Emanuele Aliberti
* Marty Dill
* Filip Navara (xnavara@volny.cz)
* Thomas Weidenmueller (w3seek@reactos.org)
* Jeffrey Morlan
*/
/* INCLUDES *******************************************************************/
#include <k32.h>
#define NDEBUG
#include <debug.h>
/* See consrv/include/rect.h */
#define ConioRectHeight(Rect) \
(((Rect)->Top > (Rect)->Bottom) ? 0 : ((Rect)->Bottom - (Rect)->Top + 1))
#define ConioRectWidth(Rect) \
(((Rect)->Left > (Rect)->Right) ? 0 : ((Rect)->Right - (Rect)->Left + 1))
/* PRIVATE FUNCTIONS **********************************************************/
/******************
* Read functions *
******************/
static
BOOL
IntReadConsole(IN HANDLE hConsoleInput,
OUT PVOID lpBuffer,
IN DWORD nNumberOfCharsToRead,
OUT LPDWORD lpNumberOfCharsRead,
IN PCONSOLE_READCONSOLE_CONTROL pInputControl OPTIONAL,
IN BOOLEAN bUnicode)
{
BOOL Success;
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_READCONSOLE ReadConsoleRequest = &ApiMessage.Data.ReadConsoleRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
ULONG CharSize, SizeBytes;
DPRINT("IntReadConsole\n");
/* Set up the data to send to the Console Server */
ReadConsoleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
ReadConsoleRequest->InputHandle = hConsoleInput;
ReadConsoleRequest->Unicode = bUnicode;
/*
[KERNEL32][CONSRV] - Make CONSRV_API_CONNECTINFO, CONSOLE_ALLOCCONSOLE and CONSOLE_ATTACHCONSOLE Windows 2k3-compatible, so that using either their kernel32 in ROS or our kernel32 in windows, works. For that, complete and fix also the CONSOLE_START_INFO and CONSOLE_PROPERTIES structures. - Rewrite Alloc/AttachConsole and the console initialization functions to match what Windows expects when connecting to the console server, and make them compatible with the fixed structures. - Fix SrvAllocConsole and SrvAttachConsole accordingly, and few other console initialization functions in consrv. - Fix input EXE name support and store also the current directory from which we were started. - Use a temporarily define USE_CONSOLE_INIT_HANDLES that is not enabled yet because we do not use console initialization events (used by Windows for Alloc/AttachConsole and console initialization functions). Until this gets implemented in ReactOS, putting windows' kernel32 in ReactOS will fail when it will try to wait on those events. - For SrvAlloc/SrvAttach/SrvFreeConsole, ConSrvConnect and ConSrvDisconnect: correctly mark the process as console app. - Fix process initialization in ConSrvNewProcess. - Get rid of CONSOLE_PROCESS_DATA::ParentConsoleHandle member. - Temporarily move the link settings retrieval in console.c and hack a bit icon setting. [CONSRV] - Move console title setting from condrv back to consrv where it should belong in fact. CORE-7931 #resolve #comment ConsolepAlloc and ConsolepAttach finally fixed in revision 64079. svn path=/branches/condrv_restructure/; revision=64079
2014-09-07 22:53:49 +00:00
* Retrieve the (current) Input EXE name string and length,
* not NULL-terminated (always in UNICODE format).
*/
ReadConsoleRequest->ExeLength =
[KERNEL32][CONSRV] - Make CONSRV_API_CONNECTINFO, CONSOLE_ALLOCCONSOLE and CONSOLE_ATTACHCONSOLE Windows 2k3-compatible, so that using either their kernel32 in ROS or our kernel32 in windows, works. For that, complete and fix also the CONSOLE_START_INFO and CONSOLE_PROPERTIES structures. - Rewrite Alloc/AttachConsole and the console initialization functions to match what Windows expects when connecting to the console server, and make them compatible with the fixed structures. - Fix SrvAllocConsole and SrvAttachConsole accordingly, and few other console initialization functions in consrv. - Fix input EXE name support and store also the current directory from which we were started. - Use a temporarily define USE_CONSOLE_INIT_HANDLES that is not enabled yet because we do not use console initialization events (used by Windows for Alloc/AttachConsole and console initialization functions). Until this gets implemented in ReactOS, putting windows' kernel32 in ReactOS will fail when it will try to wait on those events. - For SrvAlloc/SrvAttach/SrvFreeConsole, ConSrvConnect and ConSrvDisconnect: correctly mark the process as console app. - Fix process initialization in ConSrvNewProcess. - Get rid of CONSOLE_PROCESS_DATA::ParentConsoleHandle member. - Temporarily move the link settings retrieval in console.c and hack a bit icon setting. [CONSRV] - Move console title setting from condrv back to consrv where it should belong in fact. CORE-7931 #resolve #comment ConsolepAlloc and ConsolepAttach finally fixed in revision 64079. svn path=/branches/condrv_restructure/; revision=64079
2014-09-07 22:53:49 +00:00
GetCurrentExeName((PWCHAR)ReadConsoleRequest->StaticBuffer,
sizeof(ReadConsoleRequest->StaticBuffer));
/*** For DEBUGGING purposes ***/
{
UNICODE_STRING ExeName;
ExeName.Length = ExeName.MaximumLength = ReadConsoleRequest->ExeLength;
ExeName.Buffer = (PWCHAR)ReadConsoleRequest->StaticBuffer;
2017-12-09 10:53:54 +00:00
DPRINT("IntReadConsole(ExeName = %wZ)\n", &ExeName);
}
/******************************/
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
/* Determine the needed size */
CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
SizeBytes = nNumberOfCharsToRead * CharSize;
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
ReadConsoleRequest->CaptureBufferSize =
ReadConsoleRequest->NumBytes = SizeBytes;
/*
* 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(ReadConsoleRequest->StaticBuffer))
{
ReadConsoleRequest->Buffer = ReadConsoleRequest->StaticBuffer;
// 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*)&ReadConsoleRequest->Buffer);
}
ReadConsoleRequest->InitialNumBytes = 0;
ReadConsoleRequest->CtrlWakeupMask = 0;
ReadConsoleRequest->ControlKeyState = 0;
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
/*
* From MSDN (ReadConsole function), the description
* for pInputControl says:
* "This parameter requires Unicode input by default.
* For ANSI mode, set this parameter to NULL."
*/
_SEH2_TRY
{
if (bUnicode && pInputControl &&
pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
{
/* Sanity check */
if (pInputControl->nInitialChars <= nNumberOfCharsToRead)
{
ReadConsoleRequest->InitialNumBytes =
pInputControl->nInitialChars * sizeof(WCHAR); // CharSize
if (pInputControl->nInitialChars != 0)
{
/*
* It is possible here to overwrite the static buffer, in case
* the number of bytes to read was smaller than the static buffer.
* In this case, this means we are continuing a pending read,
* and we do not need in fact the executable name that was
* stored in the static buffer because it was first grabbed when
* we started the first read.
*/
RtlCopyMemory(ReadConsoleRequest->Buffer,
lpBuffer,
ReadConsoleRequest->InitialNumBytes);
}
ReadConsoleRequest->CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
}
else
{
// Status = STATUS_INVALID_PARAMETER;
}
}
else
{
/* We are in a situation where pInputControl has no meaning */
pInputControl = NULL;
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
// HACK
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
SetLastError(ERROR_INVALID_ACCESS);
_SEH2_YIELD(return FALSE);
}
_SEH2_END;
/* FIXME: Check for sanity */
/*
if (!NT_SUCCESS(Status) && pInputControl)
{
// Free CaptureBuffer if needed
// Set last error to last status
// Return FALSE
}
*/
/* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsole),
sizeof(*ReadConsoleRequest));
/* Check for success */
Success = NT_SUCCESS(ApiMessage.Status);
/* Retrieve the results */
if (Success)
{
_SEH2_TRY
{
*lpNumberOfCharsRead = ReadConsoleRequest->NumBytes / CharSize;
if (bUnicode && pInputControl)
pInputControl->dwControlKeyState = ReadConsoleRequest->ControlKeyState;
RtlCopyMemory(lpBuffer,
ReadConsoleRequest->Buffer,
ReadConsoleRequest->NumBytes);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
Success = FALSE;
}
_SEH2_END;
}
else
{
BaseSetLastNTError(ApiMessage.Status);
}
/* Release the capture buffer if needed */
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
if (Success)
{
/* Yield execution to another thread if Ctrl-C or Ctrl-Break happened */
if (ApiMessage.Status == STATUS_ALERTED /* || ApiMessage.Status == STATUS_CANCELLED */)
{
NtYieldExecution();
SetLastError(ERROR_OPERATION_ABORTED); // STATUS_CANCELLED
}
}
/* Return success status */
return Success;
}
static
BOOL
IntGetConsoleInput(IN HANDLE hConsoleInput,
OUT PINPUT_RECORD lpBuffer,
IN DWORD nLength,
OUT LPDWORD lpNumberOfEventsRead,
IN WORD wFlags,
IN BOOLEAN bUnicode)
{
BOOL Success;
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETINPUT GetInputRequest = &ApiMessage.Data.GetInputRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
if (!IsConsoleHandle(hConsoleInput))
{
_SEH2_TRY
{
*lpNumberOfEventsRead = 0;
SetLastError(ERROR_INVALID_HANDLE);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
}
_SEH2_END;
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
return FALSE;
}
DPRINT("IntGetConsoleInput: %lx %p\n", nLength, lpNumberOfEventsRead);
/* Set up the data to send to the Console Server */
GetInputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
GetInputRequest->InputHandle = hConsoleInput;
GetInputRequest->NumRecords = nLength;
GetInputRequest->Flags = wFlags;
GetInputRequest->Unicode = bUnicode;
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than five
* input records are read. Otherwise a new buffer is allocated.
* This behaviour is also expected in the server-side.
*/
if (nLength <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
{
GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer;
// CaptureBuffer = NULL;
}
else
{
ULONG Size = nLength * sizeof(INPUT_RECORD);
/* Allocate a Capture Buffer */
CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
if (CaptureBuffer == NULL)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
/* Allocate space in the Buffer */
CsrAllocateMessagePointer(CaptureBuffer,
Size,
(PVOID*)&GetInputRequest->RecordBufPtr);
}
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
/* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleInput),
sizeof(*GetInputRequest));
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
/* Check for success */
Success = NT_SUCCESS(ApiMessage.Status);
/* Retrieve the results */
_SEH2_TRY
{
DPRINT("Events read: %lx\n", GetInputRequest->NumRecords);
*lpNumberOfEventsRead = GetInputRequest->NumRecords;
if (Success)
{
RtlCopyMemory(lpBuffer,
GetInputRequest->RecordBufPtr,
GetInputRequest->NumRecords * sizeof(INPUT_RECORD));
}
else
{
BaseSetLastNTError(ApiMessage.Status);
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
Success = FALSE;
}
_SEH2_END;
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
/* Release the capture buffer if needed */
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
/* Return success status */
return Success;
}
static
BOOL
IntReadConsoleOutput(IN HANDLE hConsoleOutput,
OUT PCHAR_INFO lpBuffer,
IN COORD dwBufferSize,
IN COORD dwBufferCoord,
IN OUT PSMALL_RECT lpReadRegion,
IN BOOLEAN bUnicode)
{
BOOL Success;
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_READOUTPUT ReadOutputRequest = &ApiMessage.Data.ReadOutputRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
SHORT SizeX, SizeY;
ULONG NumCells;
/* Set up the data to send to the Console Server */
ReadOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
ReadOutputRequest->OutputHandle = hConsoleOutput;
ReadOutputRequest->Unicode = bUnicode;
/* Update lpReadRegion */
_SEH2_TRY
{
SizeX = min(dwBufferSize.X - dwBufferCoord.X, ConioRectWidth(lpReadRegion));
SizeY = min(dwBufferSize.Y - dwBufferCoord.Y, ConioRectHeight(lpReadRegion));
if (SizeX <= 0 || SizeY <= 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
_SEH2_YIELD(return FALSE);
}
lpReadRegion->Right = lpReadRegion->Left + SizeX - 1;
lpReadRegion->Bottom = lpReadRegion->Top + SizeY - 1;
ReadOutputRequest->ReadRegion = *lpReadRegion;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
_SEH2_YIELD(return FALSE);
}
_SEH2_END;
NumCells = SizeX * SizeY;
DPRINT("IntReadConsoleOutput: (%d x %d)\n", SizeX, SizeY);
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than one
* cell is read. Otherwise a new buffer is allocated.
* This behaviour is also expected in the server-side.
*/
if (NumCells <= 1)
{
ReadOutputRequest->CharInfo = &ReadOutputRequest->StaticBuffer;
// CaptureBuffer = NULL;
}
else
{
ULONG Size = NumCells * sizeof(CHAR_INFO);
/* Allocate a Capture Buffer */
CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
if (CaptureBuffer == NULL)
{
DPRINT1("CsrAllocateCaptureBuffer failed with size %ld!\n", Size);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
/* Allocate space in the Buffer */
CsrAllocateMessagePointer(CaptureBuffer,
Size,
(PVOID*)&ReadOutputRequest->CharInfo);
}
/* Call the server */
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutput),
sizeof(*ReadOutputRequest));
/* Check for success */
Success = NT_SUCCESS(ApiMessage.Status);
/* Retrieve the results */
_SEH2_TRY
{
*lpReadRegion = ReadOutputRequest->ReadRegion;
if (Success)
{
#if 0
SHORT x, X;
#endif
SHORT y, Y;
/* Copy into the buffer */
SizeX = ConioRectWidth(&ReadOutputRequest->ReadRegion);
for (y = 0, Y = ReadOutputRequest->ReadRegion.Top; Y <= ReadOutputRequest->ReadRegion.Bottom; ++y, ++Y)
{
RtlCopyMemory(lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + dwBufferCoord.X,
ReadOutputRequest->CharInfo + y * SizeX,
SizeX * sizeof(CHAR_INFO));
#if 0
for (x = 0, X = ReadOutputRequest->ReadRegion.Left; X <= ReadOutputRequest->ReadRegion.Right; ++x, ++X)
{
*(lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + (x + dwBufferCoord.X)) =
*(ReadOutputRequest->CharInfo + y * SizeX + x);
}
#endif
}
}
else
{
BaseSetLastNTError(ApiMessage.Status);
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
Success = FALSE;
}
_SEH2_END;
/* Release the capture buffer if needed */
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
/* Return success status */
return Success;
}
static
BOOL
IntReadConsoleOutputCode(IN HANDLE hConsoleOutput,
IN CODE_TYPE CodeType,
OUT PVOID pCode,
IN DWORD nLength,
IN COORD dwReadCoord,
OUT LPDWORD lpNumberOfCodesRead)
{
BOOL Success;
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &ApiMessage.Data.ReadOutputCodeRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
ULONG CodeSize, SizeBytes;
DPRINT("IntReadConsoleOutputCode\n");
if ( (CodeType != CODE_ASCII ) &&
(CodeType != CODE_UNICODE ) &&
(CodeType != CODE_ATTRIBUTE) )
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
/* Set up the data to send to the Console Server */
ReadOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
ReadOutputCodeRequest->OutputHandle = hConsoleOutput;
ReadOutputCodeRequest->Coord = dwReadCoord;
ReadOutputCodeRequest->NumCodes = nLength;
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
/* Determine the needed size */
ReadOutputCodeRequest->CodeType = CodeType;
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
switch (CodeType)
{
case CODE_ASCII:
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
break;
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
case CODE_UNICODE:
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
break;
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
case CODE_ATTRIBUTE:
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
break;
}
SizeBytes = nLength * 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 allocated.
* This behaviour is also expected in the server-side.
*/
if (SizeBytes <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
{
ReadOutputCodeRequest->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);
}
/* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutputString),
sizeof(*ReadOutputCodeRequest));
/* Check for success */
Success = NT_SUCCESS(ApiMessage.Status);
/* Retrieve the results */
_SEH2_TRY
{
*lpNumberOfCodesRead = ReadOutputCodeRequest->NumCodes;
if (Success)
{
RtlCopyMemory(pCode,
ReadOutputCodeRequest->pCode,
ReadOutputCodeRequest->NumCodes * CodeSize);
}
else
{
BaseSetLastNTError(ApiMessage.Status);
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
Success = FALSE;
}
_SEH2_END;
/* Release the capture buffer if needed */
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
/* Return success status */
return Success;
}
/*******************
* Write functions *
*******************/
static
BOOL
IntWriteConsole(IN HANDLE hConsoleOutput,
IN PVOID lpBuffer,
IN DWORD nNumberOfCharsToWrite,
OUT LPDWORD lpNumberOfCharsWritten,
LPVOID lpReserved,
IN BOOLEAN bUnicode)
{
BOOL Success;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_WRITECONSOLE WriteConsoleRequest = &ApiMessage.Data.WriteConsoleRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
ULONG CharSize, SizeBytes;
DPRINT("IntWriteConsole\n");
/* Set up the data to send to the Console Server */
WriteConsoleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
WriteConsoleRequest->OutputHandle = hConsoleOutput;
WriteConsoleRequest->Unicode = bUnicode;
/* Those members are unused by the client, on Windows */
WriteConsoleRequest->Reserved1 = 0;
// WriteConsoleRequest->Reserved2 = {0};
/* Determine the needed size */
CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
SizeBytes = nNumberOfCharsToWrite * CharSize;
WriteConsoleRequest->NumBytes = SizeBytes;
/*
* 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(WriteConsoleRequest->StaticBuffer))
{
WriteConsoleRequest->Buffer = WriteConsoleRequest->StaticBuffer;
// CaptureBuffer = NULL;
WriteConsoleRequest->UsingStaticBuffer = TRUE;
_SEH2_TRY
{
RtlCopyMemory(WriteConsoleRequest->Buffer,
lpBuffer,
SizeBytes);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
_SEH2_YIELD(return FALSE);
}
_SEH2_END;
}
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)lpBuffer,
SizeBytes,
(PVOID*)&WriteConsoleRequest->Buffer);
WriteConsoleRequest->UsingStaticBuffer = FALSE;
}
/* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsole),
sizeof(*WriteConsoleRequest));
/* Check for success */
Success = NT_SUCCESS(ApiMessage.Status);
/* Release the capture buffer if needed */
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
/* Retrieve the results */
if (Success)
{
_SEH2_TRY
{
*lpNumberOfCharsWritten = WriteConsoleRequest->NumBytes / CharSize;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
Success = FALSE;
}
_SEH2_END;
}
else
{
BaseSetLastNTError(ApiMessage.Status);
}
/* Return success status */
return Success;
}
static
BOOL
IntWriteConsoleInput(IN HANDLE hConsoleInput,
IN PINPUT_RECORD lpBuffer,
IN DWORD nLength,
OUT LPDWORD lpNumberOfEventsWritten,
IN BOOLEAN bUnicode,
IN BOOLEAN bAppendToEnd)
{
BOOL Success;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_WRITEINPUT WriteInputRequest = &ApiMessage.Data.WriteInputRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
DPRINT("IntWriteConsoleInput: %lx %p\n", nLength, lpNumberOfEventsWritten);
/* Set up the data to send to the Console Server */
WriteInputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
WriteInputRequest->InputHandle = hConsoleInput;
WriteInputRequest->NumRecords = nLength;
WriteInputRequest->Unicode = bUnicode;
WriteInputRequest->AppendToEnd = bAppendToEnd;
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than five
* input records are written. Otherwise a new buffer is allocated.
* This behaviour is also expected in the server-side.
*/
if (nLength <= sizeof(WriteInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
{
WriteInputRequest->RecordBufPtr = WriteInputRequest->RecordStaticBuffer;
// CaptureBuffer = NULL;
_SEH2_TRY
{
RtlCopyMemory(WriteInputRequest->RecordBufPtr,
lpBuffer,
nLength * sizeof(INPUT_RECORD));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
_SEH2_YIELD(return FALSE);
}
_SEH2_END;
}
else
{
ULONG Size = nLength * sizeof(INPUT_RECORD);
/* Allocate a Capture Buffer */
CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
if (CaptureBuffer == NULL)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
/* Capture the user buffer */
CsrCaptureMessageBuffer(CaptureBuffer,
lpBuffer,
Size,
(PVOID*)&WriteInputRequest->RecordBufPtr);
}
/* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleInput),
sizeof(*WriteInputRequest));
/* Check for success */
Success = NT_SUCCESS(ApiMessage.Status);
/* Release the capture buffer if needed */
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
/* Retrieve the results */
_SEH2_TRY
{
DPRINT("Events written: %lx\n", WriteInputRequest->NumRecords);
*lpNumberOfEventsWritten = WriteInputRequest->NumRecords;
if (!Success)
BaseSetLastNTError(ApiMessage.Status);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
Success = FALSE;
}
_SEH2_END;
/* Return success status */
return Success;
}
static
BOOL
IntWriteConsoleOutput(IN HANDLE hConsoleOutput,
IN CONST CHAR_INFO *lpBuffer,
IN COORD dwBufferSize,
IN COORD dwBufferCoord,
IN OUT PSMALL_RECT lpWriteRegion,
IN BOOLEAN bUnicode)
{
BOOL Success;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_WRITEOUTPUT WriteOutputRequest = &ApiMessage.Data.WriteOutputRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
SHORT SizeX, SizeY;
ULONG NumCells;
/* Set up the data to send to the Console Server */
WriteOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
WriteOutputRequest->OutputHandle = hConsoleOutput;
WriteOutputRequest->Unicode = bUnicode;
/* Update lpWriteRegion */
_SEH2_TRY
{
SizeX = min(dwBufferSize.X - dwBufferCoord.X, ConioRectWidth(lpWriteRegion));
SizeY = min(dwBufferSize.Y - dwBufferCoord.Y, ConioRectHeight(lpWriteRegion));
if (SizeX <= 0 || SizeY <= 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
_SEH2_YIELD(return FALSE);
}
lpWriteRegion->Right = lpWriteRegion->Left + SizeX - 1;
lpWriteRegion->Bottom = lpWriteRegion->Top + SizeY - 1;
WriteOutputRequest->WriteRegion = *lpWriteRegion;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
_SEH2_YIELD(return FALSE);
}
_SEH2_END;
NumCells = SizeX * SizeY;
DPRINT("IntWriteConsoleOutput: (%d x %d)\n", SizeX, SizeY);
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than one
* cell is written. Otherwise a new buffer is allocated.
* This behaviour is also expected in the server-side.
*/
if (NumCells <= 1)
{
WriteOutputRequest->CharInfo = &WriteOutputRequest->StaticBuffer;
// CaptureBuffer = NULL;
WriteOutputRequest->UseVirtualMemory = FALSE;
}
else
{
ULONG Size = NumCells * sizeof(CHAR_INFO);
/* Allocate a Capture Buffer */
CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
if (CaptureBuffer)
{
/* Allocate space in the Buffer */
CsrAllocateMessagePointer(CaptureBuffer,
Size,
(PVOID*)&WriteOutputRequest->CharInfo);
WriteOutputRequest->UseVirtualMemory = FALSE;
}
else
{
/*
* CsrAllocateCaptureBuffer failed because we tried to allocate
* a too large (>= 64 kB, size of the CSR heap) data buffer.
* To circumvent this, Windows uses a trick (that we reproduce for
* compatibility reasons): we allocate a heap buffer in the process'
* memory, and CSR will read it via NtReadVirtualMemory.
*/
DPRINT1("CsrAllocateCaptureBuffer failed with size %ld, let's use local heap buffer...\n", Size);
WriteOutputRequest->CharInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
WriteOutputRequest->UseVirtualMemory = TRUE;
/* Bail out if we still cannot allocate memory */
if (WriteOutputRequest->CharInfo == NULL)
{
DPRINT1("Failed to allocate heap buffer with size %ld!\n", Size);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
}
}
/* Capture the user buffer contents */
_SEH2_TRY
{
#if 0
SHORT x, X;
#endif
SHORT y, Y;
/* Copy into the buffer */
SizeX = ConioRectWidth(&WriteOutputRequest->WriteRegion);
for (y = 0, Y = WriteOutputRequest->WriteRegion.Top; Y <= WriteOutputRequest->WriteRegion.Bottom; ++y, ++Y)
{
RtlCopyMemory(WriteOutputRequest->CharInfo + y * SizeX,
lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + dwBufferCoord.X,
SizeX * sizeof(CHAR_INFO));
#if 0
for (x = 0, X = WriteOutputRequest->WriteRegion.Left; X <= WriteOutputRequest->WriteRegion.Right; ++x, ++X)
{
*(WriteOutputRequest->CharInfo + y * SizeX + x) =
*(lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + (x + dwBufferCoord.X));
}
#endif
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
_SEH2_YIELD(return FALSE);
}
_SEH2_END;
/* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutput),
sizeof(*WriteOutputRequest));
/* Check for success */
Success = NT_SUCCESS(ApiMessage.Status);
/* Release the capture buffer if needed */
if (CaptureBuffer)
{
CsrFreeCaptureBuffer(CaptureBuffer);
}
else
{
/* If we used a heap buffer, free it */
if (WriteOutputRequest->UseVirtualMemory)
RtlFreeHeap(RtlGetProcessHeap(), 0, WriteOutputRequest->CharInfo);
}
/* Retrieve the results */
_SEH2_TRY
{
*lpWriteRegion = WriteOutputRequest->WriteRegion;
if (!Success)
BaseSetLastNTError(ApiMessage.Status);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
Success = FALSE;
}
_SEH2_END;
/* Return success status */
return Success;
}
static
BOOL
IntWriteConsoleOutputCode(IN HANDLE hConsoleOutput,
IN CODE_TYPE CodeType,
IN CONST VOID *pCode,
IN DWORD nLength,
IN COORD dwWriteCoord,
OUT LPDWORD lpNumberOfCodesWritten)
{
BOOL Success;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &ApiMessage.Data.WriteOutputCodeRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
ULONG CodeSize, SizeBytes;
if ( (CodeType != CODE_ASCII ) &&
(CodeType != CODE_UNICODE ) &&
(CodeType != CODE_ATTRIBUTE) )
{
SetLastError(ERROR_INVALID_PARAMETER);
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:
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
break;
case CODE_UNICODE:
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
break;
case CODE_ATTRIBUTE:
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
break;
}
SizeBytes = nLength * 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 allocated.
* This behaviour is also expected in the server-side.
*/
if (SizeBytes <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
{
WriteOutputCodeRequest->pCode = WriteOutputCodeRequest->CodeStaticBuffer;
// CaptureBuffer = NULL;
_SEH2_TRY
{
RtlCopyMemory(WriteOutputCodeRequest->pCode,
pCode,
SizeBytes);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
_SEH2_YIELD(return FALSE);
}
_SEH2_END;
}
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,
SizeBytes,
(PVOID*)&WriteOutputCodeRequest->pCode);
}
/* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutputString),
sizeof(*WriteOutputCodeRequest));
/* Check for success */
Success = NT_SUCCESS(ApiMessage.Status);
/* Release the capture buffer if needed */
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
/* Retrieve the results */
_SEH2_TRY
{
*lpNumberOfCodesWritten = WriteOutputCodeRequest->NumCodes;
if (!Success)
BaseSetLastNTError(ApiMessage.Status);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
Success = FALSE;
}
_SEH2_END;
/* Return success status */
return Success;
}
static
BOOL
IntFillConsoleOutputCode(IN HANDLE hConsoleOutput,
IN CODE_TYPE CodeType,
IN CODE_ELEMENT Code,
IN DWORD nLength,
IN COORD dwWriteCoord,
OUT LPDWORD lpNumberOfCodesWritten)
{
BOOL Success;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &ApiMessage.Data.FillOutputRequest;
DPRINT("IntFillConsoleOutputCode\n");
if ( (CodeType != CODE_ASCII ) &&
(CodeType != CODE_UNICODE ) &&
(CodeType != CODE_ATTRIBUTE) )
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
/* Set up the data to send to the Console Server */
FillOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
FillOutputRequest->OutputHandle = hConsoleOutput;
FillOutputRequest->WriteCoord = dwWriteCoord;
FillOutputRequest->CodeType = CodeType;
FillOutputRequest->Code = Code;
FillOutputRequest->NumCodes = nLength;
/* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFillConsoleOutput),
sizeof(*FillOutputRequest));
/* Check for success */
Success = NT_SUCCESS(ApiMessage.Status);
/* Retrieve the results */
_SEH2_TRY
{
*lpNumberOfCodesWritten = FillOutputRequest->NumCodes;
if (!Success)
BaseSetLastNTError(ApiMessage.Status);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
Success = FALSE;
}
_SEH2_END;
/* Return success status */
return Success;
}
/* FUNCTIONS ******************************************************************/
/******************
* Read functions *
******************/
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
ReadConsoleW(IN HANDLE hConsoleInput,
OUT LPVOID lpBuffer,
IN DWORD nNumberOfCharsToRead,
OUT LPDWORD lpNumberOfCharsRead,
IN PCONSOLE_READCONSOLE_CONTROL pInputControl OPTIONAL)
{
return IntReadConsole(hConsoleInput,
lpBuffer,
nNumberOfCharsToRead,
lpNumberOfCharsRead,
pInputControl,
TRUE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
ReadConsoleA(IN HANDLE hConsoleInput,
OUT LPVOID lpBuffer,
IN DWORD nNumberOfCharsToRead,
OUT LPDWORD lpNumberOfCharsRead,
IN PCONSOLE_READCONSOLE_CONTROL pInputControl OPTIONAL)
{
return IntReadConsole(hConsoleInput,
lpBuffer,
nNumberOfCharsToRead,
lpNumberOfCharsRead,
NULL,
FALSE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
PeekConsoleInputW(IN HANDLE hConsoleInput,
OUT PINPUT_RECORD lpBuffer,
IN DWORD nLength,
OUT LPDWORD lpNumberOfEventsRead)
{
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
return IntGetConsoleInput(hConsoleInput,
lpBuffer,
nLength,
lpNumberOfEventsRead,
CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE,
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
TRUE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
PeekConsoleInputA(IN HANDLE hConsoleInput,
OUT PINPUT_RECORD lpBuffer,
IN DWORD nLength,
OUT LPDWORD lpNumberOfEventsRead)
{
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
return IntGetConsoleInput(hConsoleInput,
lpBuffer,
nLength,
lpNumberOfEventsRead,
CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE,
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
FALSE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
ReadConsoleInputW(IN HANDLE hConsoleInput,
OUT PINPUT_RECORD lpBuffer,
IN DWORD nLength,
OUT LPDWORD lpNumberOfEventsRead)
{
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
return IntGetConsoleInput(hConsoleInput,
lpBuffer,
nLength,
lpNumberOfEventsRead,
0,
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
TRUE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
ReadConsoleInputA(IN HANDLE hConsoleInput,
OUT PINPUT_RECORD lpBuffer,
IN DWORD nLength,
OUT LPDWORD lpNumberOfEventsRead)
{
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
return IntGetConsoleInput(hConsoleInput,
lpBuffer,
nLength,
lpNumberOfEventsRead,
0,
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
FALSE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
ReadConsoleInputExW(IN HANDLE hConsoleInput,
OUT PINPUT_RECORD lpBuffer,
IN DWORD nLength,
OUT LPDWORD lpNumberOfEventsRead,
IN WORD wFlags)
{
return IntGetConsoleInput(hConsoleInput,
lpBuffer,
nLength,
lpNumberOfEventsRead,
wFlags,
TRUE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
ReadConsoleInputExA(IN HANDLE hConsoleInput,
OUT PINPUT_RECORD lpBuffer,
IN DWORD nLength,
OUT LPDWORD lpNumberOfEventsRead,
IN WORD wFlags)
{
return IntGetConsoleInput(hConsoleInput,
lpBuffer,
nLength,
lpNumberOfEventsRead,
wFlags,
FALSE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
ReadConsoleOutputW(IN HANDLE hConsoleOutput,
OUT PCHAR_INFO lpBuffer,
IN COORD dwBufferSize,
IN COORD dwBufferCoord,
IN OUT PSMALL_RECT lpReadRegion)
{
return IntReadConsoleOutput(hConsoleOutput,
lpBuffer,
dwBufferSize,
dwBufferCoord,
lpReadRegion,
TRUE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
ReadConsoleOutputA(IN HANDLE hConsoleOutput,
OUT PCHAR_INFO lpBuffer,
IN COORD dwBufferSize,
IN COORD dwBufferCoord,
IN OUT PSMALL_RECT lpReadRegion)
{
return IntReadConsoleOutput(hConsoleOutput,
lpBuffer,
dwBufferSize,
dwBufferCoord,
lpReadRegion,
FALSE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
ReadConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
OUT LPWSTR lpCharacter,
IN DWORD nLength,
IN COORD dwReadCoord,
OUT LPDWORD lpNumberOfCharsRead)
{
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
return IntReadConsoleOutputCode(hConsoleOutput,
CODE_UNICODE,
lpCharacter,
nLength,
dwReadCoord,
lpNumberOfCharsRead);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
ReadConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
OUT LPSTR lpCharacter,
IN DWORD nLength,
IN COORD dwReadCoord,
OUT LPDWORD lpNumberOfCharsRead)
{
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
return IntReadConsoleOutputCode(hConsoleOutput,
CODE_ASCII,
lpCharacter,
nLength,
dwReadCoord,
lpNumberOfCharsRead);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
ReadConsoleOutputAttribute(IN HANDLE hConsoleOutput,
OUT LPWORD lpAttribute,
IN DWORD nLength,
IN COORD dwReadCoord,
OUT LPDWORD lpNumberOfAttrsRead)
{
[KERNEL32/CONSRV] - Move the waiting loop of IntReadConsole into SrvReadConsole instead. - Merge IntPeekConsoleInput and IntReadConsoleInput helpers into a single IntGetConsoleInput helper function and make PeekConsoleInputW/A and ReadConsoleInputW/A use it. Indeed, the "only" difference between these two functions, is that the first one keeps the data read inside the console input buffer, but on the contrary the second removes the data and does not return until at least one input record has been read. In server-side, CsrReadInputEvent and CsrPeekConsoleInput are merged into SrvGetConsoleInput. Merge the corresponding structures. - Use shorter variable names in IntReadConsoleOutput and use CONSOLE_PROCESS_DATA structure in SrvReadConsoleOutput. - Merge IntReadConsoleOutputCharacter and ReadConsoleOutputAttribute functions into a single IntReadConsoleOutputCode helper function, and make ReadConsoleOutputAttribute and ReadConsoleOutputCharacterW/A use it. In server-side, CsrReadConsoleOutputChar and CsrReadConsoleOutputAttrib are merged into SrvReadConsoleOutputString. (Remark: the SrvReadConsoleOutputString name comes from http://j00ru.vexillium.org/csrss_list/api_list.html and I checked that it was indeed the server function that was called by both ReadConsoleOutputAttribute and ReadConsoleOutputCharacter). The idea behind merging these two functions is, that an attribute or a character are instances of the same entity, namely a "code" (what would be called an (ANSI) escape sequence). Therefore I encode them inside the same CSRSS_READ_CONSOLE_OUTPUT_CODE structure and I use it with the previous functions. [CONSRV] - Make use of the CONSOLE_PROCESS_DATA structure (introduced in r57685). - Use CsrValidateMessageBuffer instead of Win32CsrValidateBuffer. - Reorganize conmsg.h a little bit. svn path=/branches/ros-csrss/; revision=57721
2012-11-17 21:39:41 +00:00
return IntReadConsoleOutputCode(hConsoleOutput,
CODE_ATTRIBUTE,
lpAttribute,
nLength,
dwReadCoord,
lpNumberOfAttrsRead);
}
/*******************
* Write functions *
*******************/
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
WriteConsoleW(IN HANDLE hConsoleOutput,
IN CONST VOID *lpBuffer,
IN DWORD nNumberOfCharsToWrite,
OUT LPDWORD lpNumberOfCharsWritten,
LPVOID lpReserved)
{
return IntWriteConsole(hConsoleOutput,
(PVOID)lpBuffer,
nNumberOfCharsToWrite,
lpNumberOfCharsWritten,
lpReserved,
TRUE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
WriteConsoleA(IN HANDLE hConsoleOutput,
IN CONST VOID *lpBuffer,
IN DWORD nNumberOfCharsToWrite,
OUT LPDWORD lpNumberOfCharsWritten,
LPVOID lpReserved)
{
return IntWriteConsole(hConsoleOutput,
(PVOID)lpBuffer,
nNumberOfCharsToWrite,
lpNumberOfCharsWritten,
lpReserved,
FALSE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
WriteConsoleInputW(IN HANDLE hConsoleInput,
IN CONST INPUT_RECORD *lpBuffer,
IN DWORD nLength,
OUT LPDWORD lpNumberOfEventsWritten)
{
return IntWriteConsoleInput(hConsoleInput,
(PINPUT_RECORD)lpBuffer,
nLength,
lpNumberOfEventsWritten,
TRUE,
TRUE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
WriteConsoleInputA(IN HANDLE hConsoleInput,
IN CONST INPUT_RECORD *lpBuffer,
IN DWORD nLength,
OUT LPDWORD lpNumberOfEventsWritten)
{
return IntWriteConsoleInput(hConsoleInput,
(PINPUT_RECORD)lpBuffer,
nLength,
lpNumberOfEventsWritten,
FALSE,
TRUE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
WriteConsoleInputVDMW(IN HANDLE hConsoleInput,
IN CONST INPUT_RECORD *lpBuffer,
IN DWORD nLength,
OUT LPDWORD lpNumberOfEventsWritten)
{
return IntWriteConsoleInput(hConsoleInput,
(PINPUT_RECORD)lpBuffer,
nLength,
lpNumberOfEventsWritten,
TRUE,
FALSE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
WriteConsoleInputVDMA(IN HANDLE hConsoleInput,
IN CONST INPUT_RECORD *lpBuffer,
IN DWORD nLength,
OUT LPDWORD lpNumberOfEventsWritten)
{
return IntWriteConsoleInput(hConsoleInput,
(PINPUT_RECORD)lpBuffer,
nLength,
lpNumberOfEventsWritten,
FALSE,
FALSE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
WriteConsoleOutputW(IN HANDLE hConsoleOutput,
IN CONST CHAR_INFO *lpBuffer,
IN COORD dwBufferSize,
IN COORD dwBufferCoord,
IN OUT PSMALL_RECT lpWriteRegion)
{
return IntWriteConsoleOutput(hConsoleOutput,
lpBuffer,
dwBufferSize,
dwBufferCoord,
lpWriteRegion,
TRUE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
WriteConsoleOutputA(IN HANDLE hConsoleOutput,
IN CONST CHAR_INFO *lpBuffer,
IN COORD dwBufferSize,
IN COORD dwBufferCoord,
IN OUT PSMALL_RECT lpWriteRegion)
{
return IntWriteConsoleOutput(hConsoleOutput,
lpBuffer,
dwBufferSize,
dwBufferCoord,
lpWriteRegion,
FALSE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
WriteConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
IN LPCWSTR lpCharacter,
IN DWORD nLength,
IN COORD dwWriteCoord,
OUT LPDWORD lpNumberOfCharsWritten)
{
return IntWriteConsoleOutputCode(hConsoleOutput,
CODE_UNICODE,
lpCharacter,
nLength,
dwWriteCoord,
lpNumberOfCharsWritten);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
WriteConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
IN LPCSTR lpCharacter,
IN DWORD nLength,
IN COORD dwWriteCoord,
OUT LPDWORD lpNumberOfCharsWritten)
{
return IntWriteConsoleOutputCode(hConsoleOutput,
CODE_ASCII,
lpCharacter,
nLength,
dwWriteCoord,
lpNumberOfCharsWritten);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
WriteConsoleOutputAttribute(IN HANDLE hConsoleOutput,
IN CONST WORD *lpAttribute,
IN DWORD nLength,
IN COORD dwWriteCoord,
OUT LPDWORD lpNumberOfAttrsWritten)
{
return IntWriteConsoleOutputCode(hConsoleOutput,
CODE_ATTRIBUTE,
lpAttribute,
nLength,
dwWriteCoord,
lpNumberOfAttrsWritten);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
FillConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
IN WCHAR cCharacter,
IN DWORD nLength,
IN COORD dwWriteCoord,
OUT LPDWORD lpNumberOfCharsWritten)
{
CODE_ELEMENT Code;
Code.UnicodeChar = cCharacter;
return IntFillConsoleOutputCode(hConsoleOutput,
CODE_UNICODE,
Code,
nLength,
dwWriteCoord,
lpNumberOfCharsWritten);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
FillConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
IN CHAR cCharacter,
IN DWORD nLength,
IN COORD dwWriteCoord,
LPDWORD lpNumberOfCharsWritten)
{
CODE_ELEMENT Code;
Code.AsciiChar = cCharacter;
return IntFillConsoleOutputCode(hConsoleOutput,
CODE_ASCII,
Code,
nLength,
dwWriteCoord,
lpNumberOfCharsWritten);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
FillConsoleOutputAttribute(IN HANDLE hConsoleOutput,
IN WORD wAttribute,
IN DWORD nLength,
IN COORD dwWriteCoord,
OUT LPDWORD lpNumberOfAttrsWritten)
{
CODE_ELEMENT Code;
Code.Attribute = wAttribute;
return IntFillConsoleOutputCode(hConsoleOutput,
CODE_ATTRIBUTE,
Code,
nLength,
dwWriteCoord,
lpNumberOfAttrsWritten);
}
/* EOF */