2012-11-15 18:06:17 +00:00
|
|
|
/*
|
|
|
|
* 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>
|
|
|
|
|
|
|
|
|
|
|
|
/* PRIVATE FUNCTIONS **********************************************************/
|
|
|
|
|
|
|
|
/******************
|
|
|
|
* Read functions *
|
|
|
|
******************/
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
IntReadConsole(HANDLE hConsoleInput,
|
|
|
|
PVOID lpBuffer,
|
|
|
|
DWORD nNumberOfCharsToRead,
|
|
|
|
LPDWORD lpNumberOfCharsRead,
|
|
|
|
PCONSOLE_READCONSOLE_CONTROL pInputControl,
|
|
|
|
BOOL bUnicode)
|
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
CONSOLE_API_MESSAGE ApiMessage;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_READCONSOLE ReadConsoleRequest = &ApiMessage.Data.ReadConsoleRequest;
|
2012-11-15 18:06:17 +00:00
|
|
|
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
2012-11-17 21:39:41 +00:00
|
|
|
ULONG CharSize;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
/* Determine the needed size */
|
|
|
|
CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
|
|
|
|
ReadConsoleRequest->BufferSize = nNumberOfCharsToRead * CharSize;
|
|
|
|
|
|
|
|
/* Allocate a Capture Buffer */
|
|
|
|
CaptureBuffer = CsrAllocateCaptureBuffer(1, ReadConsoleRequest->BufferSize);
|
2012-11-15 18:06:17 +00:00
|
|
|
if (CaptureBuffer == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
/* Allocate space in the Buffer */
|
2012-11-15 18:06:17 +00:00
|
|
|
CsrAllocateMessagePointer(CaptureBuffer,
|
2012-11-17 21:39:41 +00:00
|
|
|
ReadConsoleRequest->BufferSize,
|
|
|
|
(PVOID*)&ReadConsoleRequest->Buffer);
|
|
|
|
|
2012-12-08 00:39:24 +00:00
|
|
|
/* Set up the data to send to the Console Server */
|
2013-01-05 23:10:12 +00:00
|
|
|
ReadConsoleRequest->InputHandle = hConsoleInput;
|
2012-11-17 21:39:41 +00:00
|
|
|
ReadConsoleRequest->Unicode = bUnicode;
|
2013-06-27 00:20:58 +00:00
|
|
|
ReadConsoleRequest->NrCharactersToRead = nNumberOfCharsToRead;
|
2012-11-17 21:39:41 +00:00
|
|
|
ReadConsoleRequest->NrCharactersRead = 0;
|
|
|
|
ReadConsoleRequest->CtrlWakeupMask = 0;
|
2012-11-15 18:06:17 +00:00
|
|
|
if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
|
|
|
|
{
|
2013-06-27 00:20:58 +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."
|
|
|
|
*/
|
2012-11-17 21:39:41 +00:00
|
|
|
ReadConsoleRequest->NrCharactersRead = pInputControl->nInitialChars;
|
2014-07-29 00:00:21 +00:00
|
|
|
RtlCopyMemory(ReadConsoleRequest->Buffer,
|
|
|
|
lpBuffer,
|
|
|
|
pInputControl->nInitialChars * sizeof(WCHAR));
|
2012-11-17 21:39:41 +00:00
|
|
|
ReadConsoleRequest->CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
2012-12-08 00:39:24 +00:00
|
|
|
/* Call the server */
|
2014-07-28 13:37:54 +00:00
|
|
|
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
|
|
|
CaptureBuffer,
|
|
|
|
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsole),
|
|
|
|
sizeof(*ReadConsoleRequest));
|
2012-12-08 00:39:24 +00:00
|
|
|
|
|
|
|
/* Check for success */
|
2014-07-28 13:37:54 +00:00
|
|
|
if (NT_SUCCESS(ApiMessage.Status))
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-29 00:00:21 +00:00
|
|
|
RtlCopyMemory(lpBuffer,
|
|
|
|
ReadConsoleRequest->Buffer,
|
|
|
|
ReadConsoleRequest->NrCharactersRead * CharSize);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-12-08 00:39:24 +00:00
|
|
|
if (lpNumberOfCharsRead != NULL)
|
|
|
|
*lpNumberOfCharsRead = ReadConsoleRequest->NrCharactersRead;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-12-08 00:39:24 +00:00
|
|
|
if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
|
|
|
|
pInputControl->dwControlKeyState = ReadConsoleRequest->ControlKeyState;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINT1("CSR returned error in ReadConsole\n");
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-12-08 00:39:24 +00:00
|
|
|
if (lpNumberOfCharsRead != NULL)
|
|
|
|
*lpNumberOfCharsRead = 0;
|
|
|
|
|
|
|
|
/* Error out */
|
2014-07-28 13:37:54 +00:00
|
|
|
BaseSetLastNTError(ApiMessage.Status);
|
2012-12-08 00:39:24 +00:00
|
|
|
}
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
|
|
|
|
2012-12-08 00:39:24 +00:00
|
|
|
/* Return TRUE or FALSE */
|
|
|
|
// return TRUE;
|
|
|
|
return (ReadConsoleRequest->NrCharactersRead > 0);
|
2014-07-28 13:37:54 +00:00
|
|
|
// return NT_SUCCESS(ApiMessage.Status);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
2014-07-29 15:59:17 +00:00
|
|
|
IntGetConsoleInput(IN HANDLE hConsoleInput,
|
|
|
|
OUT PINPUT_RECORD lpBuffer,
|
|
|
|
IN DWORD nLength,
|
|
|
|
OUT LPDWORD lpNumberOfEventsRead,
|
|
|
|
IN WORD wFlags,
|
|
|
|
IN BOOLEAN bUnicode)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
BOOL Success;
|
2012-11-17 21:39:41 +00:00
|
|
|
CONSOLE_API_MESSAGE ApiMessage;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_GETINPUT GetInputRequest = &ApiMessage.Data.GetInputRequest;
|
2014-07-28 21:20:36 +00:00
|
|
|
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2014-07-28 21:20:36 +00:00
|
|
|
if (!IsConsoleHandle(hConsoleInput))
|
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
_SEH2_TRY
|
|
|
|
{
|
2014-07-28 21:20:36 +00:00
|
|
|
*lpNumberOfEventsRead = 0;
|
2014-07-29 15:59:17 +00:00
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_ACCESS);
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
2012-11-17 21:39:41 +00:00
|
|
|
|
2012-11-15 18:06:17 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2014-07-28 21:20:36 +00:00
|
|
|
DPRINT("IntGetConsoleInput: %lx %p\n", nLength, lpNumberOfEventsRead);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
/* Set up the data to send to the Console Server */
|
2014-07-28 21:20:36 +00:00
|
|
|
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);
|
|
|
|
}
|
2012-11-17 21:39:41 +00:00
|
|
|
|
|
|
|
/* Call the server */
|
2014-07-28 13:37:54 +00:00
|
|
|
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
|
|
|
CaptureBuffer,
|
|
|
|
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleInput),
|
|
|
|
sizeof(*GetInputRequest));
|
2012-11-17 21:39:41 +00:00
|
|
|
|
2012-12-08 00:39:24 +00:00
|
|
|
/* Check for success */
|
2014-07-29 15:59:17 +00:00
|
|
|
Success = NT_SUCCESS(ApiMessage.Status);
|
|
|
|
|
|
|
|
/* Retrieve the results */
|
|
|
|
_SEH2_TRY
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-28 21:20:36 +00:00
|
|
|
DPRINT("Events read: %lx\n", GetInputRequest->NumRecords);
|
2014-07-29 15:59:17 +00:00
|
|
|
*lpNumberOfEventsRead = GetInputRequest->NumRecords;
|
2012-12-08 00:39:24 +00:00
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
if (Success)
|
|
|
|
{
|
|
|
|
RtlCopyMemory(lpBuffer,
|
|
|
|
GetInputRequest->RecordBufPtr,
|
|
|
|
GetInputRequest->NumRecords * sizeof(INPUT_RECORD));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
BaseSetLastNTError(ApiMessage.Status);
|
|
|
|
}
|
2012-12-08 00:39:24 +00:00
|
|
|
}
|
2014-07-29 15:59:17 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
2012-12-08 00:39:24 +00:00
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
SetLastError(ERROR_INVALID_ACCESS);
|
|
|
|
Success = FALSE;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
2014-07-29 15:59:17 +00:00
|
|
|
_SEH2_END;
|
2012-11-17 21:39:41 +00:00
|
|
|
|
2014-07-28 21:20:36 +00:00
|
|
|
/* Release the capture buffer if needed */
|
|
|
|
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
/* Return success status */
|
|
|
|
return Success;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
IntReadConsoleOutput(HANDLE hConsoleOutput,
|
|
|
|
PCHAR_INFO lpBuffer,
|
|
|
|
COORD dwBufferSize,
|
|
|
|
COORD dwBufferCoord,
|
|
|
|
PSMALL_RECT lpReadRegion,
|
|
|
|
BOOL bUnicode)
|
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
CONSOLE_API_MESSAGE ApiMessage;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_READOUTPUT ReadOutputRequest = &ApiMessage.Data.ReadOutputRequest;
|
2012-11-15 18:06:17 +00:00
|
|
|
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
|
|
|
DWORD Size, SizeX, SizeY;
|
|
|
|
|
|
|
|
if (lpBuffer == NULL)
|
|
|
|
{
|
2014-07-28 21:20:36 +00:00
|
|
|
SetLastError(ERROR_INVALID_ACCESS);
|
2012-11-15 18:06:17 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
|
|
|
|
|
|
|
|
DPRINT("IntReadConsoleOutput: %lx %p\n", Size, lpReadRegion);
|
2012-11-17 21:39:41 +00:00
|
|
|
|
|
|
|
/* Allocate a Capture Buffer */
|
2012-11-15 18:06:17 +00:00
|
|
|
CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
|
|
|
|
if (CaptureBuffer == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("CsrAllocateCaptureBuffer failed with size 0x%x!\n", Size);
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate space in the Buffer */
|
2012-11-17 21:39:41 +00:00
|
|
|
CsrAllocateMessagePointer(CaptureBuffer,
|
|
|
|
Size,
|
2013-01-05 23:10:12 +00:00
|
|
|
(PVOID*)&ReadOutputRequest->CharInfo);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
/* Set up the data to send to the Console Server */
|
2013-01-05 23:10:12 +00:00
|
|
|
ReadOutputRequest->OutputHandle = hConsoleOutput;
|
|
|
|
ReadOutputRequest->Unicode = bUnicode;
|
|
|
|
ReadOutputRequest->BufferSize = dwBufferSize;
|
|
|
|
ReadOutputRequest->BufferCoord = dwBufferCoord;
|
|
|
|
ReadOutputRequest->ReadRegion = *lpReadRegion;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
/* Call the server */
|
2012-11-17 21:39:41 +00:00
|
|
|
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
2012-11-15 18:06:17 +00:00
|
|
|
CaptureBuffer,
|
2012-11-17 21:39:41 +00:00
|
|
|
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutput),
|
2014-07-28 13:37:54 +00:00
|
|
|
sizeof(*ReadOutputRequest));
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2013-03-09 01:39:49 +00:00
|
|
|
/* Check for success */
|
2012-11-17 21:39:41 +00:00
|
|
|
if (NT_SUCCESS(ApiMessage.Status))
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
|
|
|
/* Copy into the buffer */
|
|
|
|
DPRINT("Copying to buffer\n");
|
2013-01-05 23:10:12 +00:00
|
|
|
SizeX = ReadOutputRequest->ReadRegion.Right -
|
|
|
|
ReadOutputRequest->ReadRegion.Left + 1;
|
|
|
|
SizeY = ReadOutputRequest->ReadRegion.Bottom -
|
|
|
|
ReadOutputRequest->ReadRegion.Top + 1;
|
2012-11-15 18:06:17 +00:00
|
|
|
RtlCopyMemory(lpBuffer,
|
2013-01-05 23:10:12 +00:00
|
|
|
ReadOutputRequest->CharInfo,
|
2012-11-15 18:06:17 +00:00
|
|
|
sizeof(CHAR_INFO) * SizeX * SizeY);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Error out */
|
2012-11-17 21:39:41 +00:00
|
|
|
BaseSetLastNTError(ApiMessage.Status);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the read region */
|
2013-08-29 20:37:02 +00:00
|
|
|
DPRINT("read region: %p\n", ReadOutputRequest->ReadRegion);
|
2013-01-05 23:10:12 +00:00
|
|
|
*lpReadRegion = ReadOutputRequest->ReadRegion;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
/* Release the capture buffer */
|
|
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
|
|
|
|
|
|
|
/* Return TRUE or FALSE */
|
2012-11-17 21:39:41 +00:00
|
|
|
return NT_SUCCESS(ApiMessage.Status);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
2014-07-29 15:59:17 +00:00
|
|
|
IntReadConsoleOutputCode(IN HANDLE hConsoleOutput,
|
|
|
|
IN CODE_TYPE CodeType,
|
|
|
|
OUT PVOID pCode,
|
|
|
|
IN DWORD nLength,
|
|
|
|
IN COORD dwReadCoord,
|
|
|
|
OUT LPDWORD lpNumberOfCodesRead)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
BOOL Success;
|
2012-11-17 21:39:41 +00:00
|
|
|
CONSOLE_API_MESSAGE ApiMessage;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &ApiMessage.Data.ReadOutputCodeRequest;
|
2014-07-29 00:00:21 +00:00
|
|
|
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
|
2012-11-17 21:39:41 +00:00
|
|
|
ULONG SizeBytes, CodeSize;
|
2014-07-29 00:00:21 +00:00
|
|
|
|
|
|
|
DPRINT("IntReadConsoleOutputCode\n");
|
|
|
|
|
2014-07-29 13:49:03 +00:00
|
|
|
if ( (CodeType != CODE_ASCII ) &&
|
|
|
|
(CodeType != CODE_UNICODE ) &&
|
|
|
|
(CodeType != CODE_ATTRIBUTE) )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2014-07-29 00:00:21 +00:00
|
|
|
/* Set up the data to send to the Console Server */
|
|
|
|
ReadOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
|
|
|
|
ReadOutputCodeRequest->OutputHandle = hConsoleOutput;
|
|
|
|
ReadOutputCodeRequest->Coord = dwReadCoord;
|
|
|
|
ReadOutputCodeRequest->NumCodes = nLength;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
/* Determine the needed size */
|
2014-07-29 00:00:21 +00:00
|
|
|
ReadOutputCodeRequest->CodeType = CodeType;
|
2012-11-17 21:39:41 +00:00
|
|
|
switch (CodeType)
|
|
|
|
{
|
|
|
|
case CODE_ASCII:
|
2014-07-29 13:49:03 +00:00
|
|
|
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
|
2012-11-17 21:39:41 +00:00
|
|
|
break;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
case CODE_UNICODE:
|
2014-07-29 13:49:03 +00:00
|
|
|
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
|
2012-11-17 21:39:41 +00:00
|
|
|
break;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
case CODE_ATTRIBUTE:
|
2014-07-29 13:49:03 +00:00
|
|
|
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
|
2012-11-17 21:39:41 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
SizeBytes = nLength * CodeSize;
|
|
|
|
|
2014-07-29 00:00:21 +00:00
|
|
|
/*
|
|
|
|
* 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))
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-29 13:49:03 +00:00
|
|
|
ReadOutputCodeRequest->pCode = ReadOutputCodeRequest->CodeStaticBuffer;
|
2014-07-29 00:00:21 +00:00
|
|
|
// CaptureBuffer = NULL;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
2014-07-29 00:00:21 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Allocate a Capture Buffer */
|
|
|
|
CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
|
|
|
|
if (CaptureBuffer == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2014-07-29 00:00:21 +00:00
|
|
|
/* Allocate space in the Buffer */
|
|
|
|
CsrAllocateMessagePointer(CaptureBuffer,
|
|
|
|
SizeBytes,
|
2014-07-29 13:49:03 +00:00
|
|
|
(PVOID*)&ReadOutputCodeRequest->pCode);
|
2014-07-29 00:00:21 +00:00
|
|
|
}
|
2013-01-26 19:07:59 +00:00
|
|
|
|
2013-03-09 01:39:49 +00:00
|
|
|
/* Call the server */
|
2014-07-28 13:37:54 +00:00
|
|
|
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
|
|
|
CaptureBuffer,
|
|
|
|
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutputString),
|
|
|
|
sizeof(*ReadOutputCodeRequest));
|
2013-03-09 01:39:49 +00:00
|
|
|
|
|
|
|
/* Check for success */
|
2014-07-29 15:59:17 +00:00
|
|
|
Success = NT_SUCCESS(ApiMessage.Status);
|
|
|
|
|
|
|
|
/* Retrieve the results */
|
|
|
|
_SEH2_TRY
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
*lpNumberOfCodesRead = ReadOutputCodeRequest->NumCodes;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
if (Success)
|
|
|
|
{
|
|
|
|
RtlCopyMemory(pCode,
|
|
|
|
ReadOutputCodeRequest->pCode,
|
|
|
|
ReadOutputCodeRequest->NumCodes * CodeSize);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
BaseSetLastNTError(ApiMessage.Status);
|
|
|
|
}
|
2013-03-09 01:39:49 +00:00
|
|
|
}
|
2014-07-29 15:59:17 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
2013-03-09 01:39:49 +00:00
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
SetLastError(ERROR_INVALID_ACCESS);
|
|
|
|
Success = FALSE;
|
2013-03-09 01:39:49 +00:00
|
|
|
}
|
2014-07-29 15:59:17 +00:00
|
|
|
_SEH2_END;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2014-07-29 00:00:21 +00:00
|
|
|
/* Release the capture buffer if needed */
|
|
|
|
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
/* Return success status */
|
|
|
|
return Success;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*******************
|
|
|
|
* Write functions *
|
|
|
|
*******************/
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
IntWriteConsole(HANDLE hConsoleOutput,
|
|
|
|
PVOID lpBuffer,
|
|
|
|
DWORD nNumberOfCharsToWrite,
|
|
|
|
LPDWORD lpNumberOfCharsWritten,
|
|
|
|
LPVOID lpReserved,
|
|
|
|
BOOL bUnicode)
|
|
|
|
{
|
2013-03-09 01:39:49 +00:00
|
|
|
BOOL bRet = TRUE;
|
2012-11-19 21:48:22 +00:00
|
|
|
CONSOLE_API_MESSAGE ApiMessage;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_WRITECONSOLE WriteConsoleRequest = &ApiMessage.Data.WriteConsoleRequest;
|
2012-11-19 21:48:22 +00:00
|
|
|
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
2013-03-09 21:08:23 +00:00
|
|
|
ULONG CharSize;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-19 23:26:36 +00:00
|
|
|
/* Determine the needed size */
|
2012-11-15 18:06:17 +00:00
|
|
|
CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
|
2012-11-19 21:48:22 +00:00
|
|
|
WriteConsoleRequest->BufferSize = nNumberOfCharsToWrite * CharSize;
|
|
|
|
|
|
|
|
/* Allocate a Capture Buffer */
|
|
|
|
CaptureBuffer = CsrAllocateCaptureBuffer(1, WriteConsoleRequest->BufferSize);
|
|
|
|
if (CaptureBuffer == NULL)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-19 21:48:22 +00:00
|
|
|
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
|
2012-11-15 18:06:17 +00:00
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2012-11-19 21:48:22 +00:00
|
|
|
/* Capture the buffer to write */
|
|
|
|
CsrCaptureMessageBuffer(CaptureBuffer,
|
|
|
|
(PVOID)lpBuffer,
|
|
|
|
WriteConsoleRequest->BufferSize,
|
|
|
|
(PVOID*)&WriteConsoleRequest->Buffer);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-19 21:48:22 +00:00
|
|
|
/* Start writing */
|
|
|
|
WriteConsoleRequest->NrCharactersToWrite = nNumberOfCharsToWrite;
|
2013-01-05 23:10:12 +00:00
|
|
|
WriteConsoleRequest->OutputHandle = hConsoleOutput;
|
2012-11-19 21:48:22 +00:00
|
|
|
WriteConsoleRequest->Unicode = bUnicode;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2013-03-09 01:39:49 +00:00
|
|
|
/* Call the server */
|
2014-07-28 13:37:54 +00:00
|
|
|
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
|
|
|
CaptureBuffer,
|
|
|
|
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsole),
|
|
|
|
sizeof(*WriteConsoleRequest));
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2013-03-09 01:39:49 +00:00
|
|
|
/* Check for success */
|
2014-07-28 13:37:54 +00:00
|
|
|
if (NT_SUCCESS(ApiMessage.Status))
|
2013-03-09 01:39:49 +00:00
|
|
|
{
|
|
|
|
if (lpNumberOfCharsWritten != NULL)
|
|
|
|
*lpNumberOfCharsWritten = WriteConsoleRequest->NrCharactersWritten;
|
|
|
|
|
|
|
|
bRet = TRUE;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
2013-03-09 01:39:49 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (lpNumberOfCharsWritten != NULL)
|
|
|
|
*lpNumberOfCharsWritten = 0;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2013-03-09 01:39:49 +00:00
|
|
|
/* Error out */
|
2014-07-28 13:37:54 +00:00
|
|
|
BaseSetLastNTError(ApiMessage.Status);
|
2013-03-09 01:39:49 +00:00
|
|
|
bRet = FALSE;
|
|
|
|
}
|
2012-11-19 21:48:22 +00:00
|
|
|
|
|
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2013-03-09 01:39:49 +00:00
|
|
|
return bRet;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
2014-07-29 15:59:17 +00:00
|
|
|
IntWriteConsoleInput(IN HANDLE hConsoleInput,
|
|
|
|
IN PINPUT_RECORD lpBuffer,
|
|
|
|
IN DWORD nLength,
|
|
|
|
OUT LPDWORD lpNumberOfEventsWritten,
|
|
|
|
IN BOOLEAN bUnicode,
|
|
|
|
IN BOOLEAN bAppendToEnd)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
BOOL Success;
|
2012-11-18 13:54:32 +00:00
|
|
|
CONSOLE_API_MESSAGE ApiMessage;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_WRITEINPUT WriteInputRequest = &ApiMessage.Data.WriteInputRequest;
|
2014-07-28 21:20:36 +00:00
|
|
|
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
|
2012-11-18 13:54:32 +00:00
|
|
|
|
2014-07-28 21:20:36 +00:00
|
|
|
DPRINT("IntWriteConsoleInput: %lx %p\n", nLength, lpNumberOfEventsWritten);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
/* Set up the data to send to the Console Server */
|
2014-07-28 21:20:36 +00:00
|
|
|
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;
|
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
RtlCopyMemory(WriteInputRequest->RecordBufPtr,
|
|
|
|
lpBuffer,
|
|
|
|
nLength * sizeof(INPUT_RECORD));
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_ACCESS);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
2014-07-28 21:20:36 +00:00
|
|
|
}
|
|
|
|
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);
|
|
|
|
}
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
/* Call the server */
|
2012-11-18 13:54:32 +00:00
|
|
|
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
2012-11-15 18:06:17 +00:00
|
|
|
CaptureBuffer,
|
2012-11-18 13:54:32 +00:00
|
|
|
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleInput),
|
2014-07-28 13:37:54 +00:00
|
|
|
sizeof(*WriteInputRequest));
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
/* Check for success */
|
|
|
|
Success = NT_SUCCESS(ApiMessage.Status);
|
|
|
|
|
2014-07-28 21:20:36 +00:00
|
|
|
/* Release the capture buffer if needed */
|
|
|
|
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
|
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
/* Retrieve the results */
|
|
|
|
_SEH2_TRY
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-28 21:20:36 +00:00
|
|
|
DPRINT("Events written: %lx\n", WriteInputRequest->NumRecords);
|
2014-07-29 15:59:17 +00:00
|
|
|
*lpNumberOfEventsWritten = WriteInputRequest->NumRecords;
|
2012-11-18 13:54:32 +00:00
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
if (!Success)
|
|
|
|
BaseSetLastNTError(ApiMessage.Status);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
2014-07-29 15:59:17 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
SetLastError(ERROR_INVALID_ACCESS);
|
|
|
|
Success = FALSE;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
2014-07-29 15:59:17 +00:00
|
|
|
_SEH2_END;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
/* Return success status */
|
|
|
|
return Success;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
IntWriteConsoleOutput(HANDLE hConsoleOutput,
|
|
|
|
CONST CHAR_INFO *lpBuffer,
|
|
|
|
COORD dwBufferSize,
|
|
|
|
COORD dwBufferCoord,
|
|
|
|
PSMALL_RECT lpWriteRegion,
|
|
|
|
BOOL bUnicode)
|
|
|
|
{
|
2012-11-18 13:54:32 +00:00
|
|
|
CONSOLE_API_MESSAGE ApiMessage;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_WRITEOUTPUT WriteOutputRequest = &ApiMessage.Data.WriteOutputRequest;
|
2012-11-15 18:06:17 +00:00
|
|
|
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
|
|
|
ULONG Size;
|
|
|
|
|
2012-11-18 13:54:32 +00:00
|
|
|
if ((lpBuffer == NULL) || (lpWriteRegion == NULL))
|
|
|
|
{
|
2014-07-28 21:20:36 +00:00
|
|
|
SetLastError(ERROR_INVALID_ACCESS);
|
2012-11-18 13:54:32 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2013-03-09 14:18:10 +00:00
|
|
|
/*
|
|
|
|
if (lpWriteRegion == NULL)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
*/
|
2012-11-18 13:54:32 +00:00
|
|
|
|
2012-11-15 18:06:17 +00:00
|
|
|
Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
|
|
|
|
|
|
|
|
DPRINT("IntWriteConsoleOutput: %lx %p\n", Size, lpWriteRegion);
|
2012-11-18 13:54:32 +00:00
|
|
|
|
|
|
|
/* Allocate a Capture Buffer */
|
2012-11-15 18:06:17 +00:00
|
|
|
CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
|
|
|
|
if (CaptureBuffer == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2012-11-18 13:54:32 +00:00
|
|
|
/* Capture the user buffer */
|
2012-11-15 18:06:17 +00:00
|
|
|
CsrCaptureMessageBuffer(CaptureBuffer,
|
2012-11-18 13:54:32 +00:00
|
|
|
(PVOID)lpBuffer,
|
2012-11-15 18:06:17 +00:00
|
|
|
Size,
|
2013-01-05 23:10:12 +00:00
|
|
|
(PVOID*)&WriteOutputRequest->CharInfo);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
/* Set up the data to send to the Console Server */
|
2013-01-05 23:10:12 +00:00
|
|
|
WriteOutputRequest->OutputHandle = hConsoleOutput;
|
|
|
|
WriteOutputRequest->Unicode = bUnicode;
|
|
|
|
WriteOutputRequest->BufferSize = dwBufferSize;
|
|
|
|
WriteOutputRequest->BufferCoord = dwBufferCoord;
|
|
|
|
WriteOutputRequest->WriteRegion = *lpWriteRegion;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
/* Call the server */
|
2012-11-18 13:54:32 +00:00
|
|
|
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
2012-11-15 18:06:17 +00:00
|
|
|
CaptureBuffer,
|
2012-11-18 13:54:32 +00:00
|
|
|
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutput),
|
2014-07-28 13:37:54 +00:00
|
|
|
sizeof(*WriteOutputRequest));
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2013-03-09 01:39:49 +00:00
|
|
|
/* Check for success */
|
2012-11-18 13:54:32 +00:00
|
|
|
if (!NT_SUCCESS(ApiMessage.Status))
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
|
|
|
/* Error out */
|
2012-11-18 13:54:32 +00:00
|
|
|
BaseSetLastNTError(ApiMessage.Status);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the read region */
|
2013-08-29 20:37:02 +00:00
|
|
|
DPRINT("read region: %p\n", WriteOutputRequest->WriteRegion);
|
2013-01-05 23:10:12 +00:00
|
|
|
*lpWriteRegion = WriteOutputRequest->WriteRegion;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
/* Release the capture buffer */
|
|
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
|
|
|
|
|
|
|
/* Return TRUE or FALSE */
|
2012-11-18 13:54:32 +00:00
|
|
|
return NT_SUCCESS(ApiMessage.Status);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
2014-07-29 15:59:17 +00:00
|
|
|
IntWriteConsoleOutputCode(IN HANDLE hConsoleOutput,
|
|
|
|
IN CODE_TYPE CodeType,
|
|
|
|
IN CONST VOID *pCode,
|
|
|
|
IN DWORD nLength,
|
|
|
|
IN COORD dwWriteCoord,
|
|
|
|
OUT LPDWORD lpNumberOfCodesWritten)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
BOOL Success;
|
2012-11-19 23:26:36 +00:00
|
|
|
CONSOLE_API_MESSAGE ApiMessage;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &ApiMessage.Data.WriteOutputCodeRequest;
|
2014-07-29 00:00:21 +00:00
|
|
|
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
|
|
|
|
ULONG SizeBytes, CodeSize;
|
|
|
|
|
2014-07-29 13:49:03 +00:00
|
|
|
if ( (CodeType != CODE_ASCII ) &&
|
|
|
|
(CodeType != CODE_UNICODE ) &&
|
|
|
|
(CodeType != CODE_ATTRIBUTE) )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2014-07-29 00:00:21 +00:00
|
|
|
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;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-19 23:26:36 +00:00
|
|
|
/* Determine the needed size */
|
2014-07-29 00:00:21 +00:00
|
|
|
WriteOutputCodeRequest->CodeType = CodeType;
|
2012-11-19 23:26:36 +00:00
|
|
|
switch (CodeType)
|
|
|
|
{
|
|
|
|
case CODE_ASCII:
|
2014-07-29 13:49:03 +00:00
|
|
|
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
|
2012-11-19 23:26:36 +00:00
|
|
|
break;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-19 23:26:36 +00:00
|
|
|
case CODE_UNICODE:
|
2014-07-29 13:49:03 +00:00
|
|
|
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
|
2012-11-19 23:26:36 +00:00
|
|
|
break;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-19 23:26:36 +00:00
|
|
|
case CODE_ATTRIBUTE:
|
2014-07-29 13:49:03 +00:00
|
|
|
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
|
2012-11-19 23:26:36 +00:00
|
|
|
break;
|
|
|
|
}
|
2014-07-29 00:00:21 +00:00
|
|
|
SizeBytes = nLength * CodeSize;
|
2012-11-19 23:26:36 +00:00
|
|
|
|
2014-07-29 00:00:21 +00:00
|
|
|
/*
|
|
|
|
* 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))
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-29 13:49:03 +00:00
|
|
|
WriteOutputCodeRequest->pCode = WriteOutputCodeRequest->CodeStaticBuffer;
|
2014-07-29 00:00:21 +00:00
|
|
|
// CaptureBuffer = NULL;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
RtlCopyMemory(WriteOutputCodeRequest->pCode,
|
|
|
|
pCode,
|
|
|
|
SizeBytes);
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_ACCESS);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
2014-07-29 00:00:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Allocate a Capture Buffer */
|
|
|
|
CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
|
|
|
|
if (CaptureBuffer == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2014-07-29 00:00:21 +00:00
|
|
|
/* Capture the buffer to write */
|
|
|
|
CsrCaptureMessageBuffer(CaptureBuffer,
|
|
|
|
(PVOID)pCode,
|
|
|
|
SizeBytes,
|
2014-07-29 13:49:03 +00:00
|
|
|
(PVOID*)&WriteOutputCodeRequest->pCode);
|
2014-07-29 00:00:21 +00:00
|
|
|
}
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2013-03-09 01:39:49 +00:00
|
|
|
/* Call the server */
|
2014-07-28 13:37:54 +00:00
|
|
|
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
|
|
|
CaptureBuffer,
|
|
|
|
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutputString),
|
|
|
|
sizeof(*WriteOutputCodeRequest));
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
/* Check for success */
|
|
|
|
Success = NT_SUCCESS(ApiMessage.Status);
|
|
|
|
|
2014-07-29 00:00:21 +00:00
|
|
|
/* Release the capture buffer if needed */
|
|
|
|
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
|
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
/* Retrieve the results */
|
|
|
|
_SEH2_TRY
|
2013-03-09 01:39:49 +00:00
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
*lpNumberOfCodesWritten = WriteOutputCodeRequest->NumCodes;
|
|
|
|
|
|
|
|
if (!Success)
|
|
|
|
BaseSetLastNTError(ApiMessage.Status);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
2014-07-29 15:59:17 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
2013-03-09 01:39:49 +00:00
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
SetLastError(ERROR_INVALID_ACCESS);
|
|
|
|
Success = FALSE;
|
2013-03-09 01:39:49 +00:00
|
|
|
}
|
2014-07-29 15:59:17 +00:00
|
|
|
_SEH2_END;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
/* Return success status */
|
|
|
|
return Success;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
2014-07-29 15:59:17 +00:00
|
|
|
IntFillConsoleOutputCode(IN HANDLE hConsoleOutput,
|
|
|
|
IN CODE_TYPE CodeType,
|
|
|
|
IN CODE_ELEMENT Code,
|
|
|
|
IN DWORD nLength,
|
|
|
|
IN COORD dwWriteCoord,
|
|
|
|
OUT LPDWORD lpNumberOfCodesWritten)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
BOOL Success;
|
2012-11-18 17:06:48 +00:00
|
|
|
CONSOLE_API_MESSAGE ApiMessage;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &ApiMessage.Data.FillOutputRequest;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2014-07-29 13:49:03 +00:00
|
|
|
DPRINT("IntFillConsoleOutputCode\n");
|
|
|
|
|
2014-07-29 13:18:59 +00:00
|
|
|
if ( (CodeType != CODE_ASCII ) &&
|
|
|
|
(CodeType != CODE_UNICODE ) &&
|
|
|
|
(CodeType != CODE_ATTRIBUTE) )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2014-07-29 00:00:21 +00:00
|
|
|
/* Set up the data to send to the Console Server */
|
|
|
|
FillOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
|
|
|
|
FillOutputRequest->OutputHandle = hConsoleOutput;
|
|
|
|
FillOutputRequest->WriteCoord = dwWriteCoord;
|
|
|
|
FillOutputRequest->CodeType = CodeType;
|
2014-07-29 13:18:59 +00:00
|
|
|
FillOutputRequest->Code = Code;
|
|
|
|
FillOutputRequest->NumCodes = nLength;
|
2012-11-18 17:06:48 +00:00
|
|
|
|
2013-03-09 01:39:49 +00:00
|
|
|
/* Call the server */
|
2014-07-28 13:37:54 +00:00
|
|
|
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
|
|
|
NULL,
|
|
|
|
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFillConsoleOutput),
|
|
|
|
sizeof(*FillOutputRequest));
|
2013-03-09 01:39:49 +00:00
|
|
|
|
|
|
|
/* Check for success */
|
2014-07-29 15:59:17 +00:00
|
|
|
Success = NT_SUCCESS(ApiMessage.Status);
|
|
|
|
|
|
|
|
/* Retrieve the results */
|
|
|
|
_SEH2_TRY
|
2013-03-09 01:39:49 +00:00
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
*lpNumberOfCodesWritten = FillOutputRequest->NumCodes;
|
|
|
|
|
|
|
|
if (!Success)
|
|
|
|
BaseSetLastNTError(ApiMessage.Status);
|
2013-03-09 01:39:49 +00:00
|
|
|
}
|
2014-07-29 15:59:17 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-29 15:59:17 +00:00
|
|
|
SetLastError(ERROR_INVALID_ACCESS);
|
|
|
|
Success = FALSE;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
2014-07-29 15:59:17 +00:00
|
|
|
_SEH2_END;
|
2014-07-29 00:00:21 +00:00
|
|
|
|
2014-07-29 15:59:17 +00:00
|
|
|
/* Return success status */
|
|
|
|
return Success;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
|
|
|
|
/******************
|
|
|
|
* Read functions *
|
|
|
|
******************/
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* ReadConsoleW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
ReadConsoleW(HANDLE hConsoleInput,
|
|
|
|
LPVOID lpBuffer,
|
|
|
|
DWORD nNumberOfCharsToRead,
|
|
|
|
LPDWORD lpNumberOfCharsRead,
|
|
|
|
PCONSOLE_READCONSOLE_CONTROL pInputControl)
|
|
|
|
{
|
|
|
|
return IntReadConsole(hConsoleInput,
|
|
|
|
lpBuffer,
|
|
|
|
nNumberOfCharsToRead,
|
|
|
|
lpNumberOfCharsRead,
|
|
|
|
pInputControl,
|
|
|
|
TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* ReadConsoleA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
ReadConsoleA(HANDLE hConsoleInput,
|
|
|
|
LPVOID lpBuffer,
|
|
|
|
DWORD nNumberOfCharsToRead,
|
|
|
|
LPDWORD lpNumberOfCharsRead,
|
|
|
|
PCONSOLE_READCONSOLE_CONTROL pInputControl)
|
|
|
|
{
|
|
|
|
return IntReadConsole(hConsoleInput,
|
|
|
|
lpBuffer,
|
|
|
|
nNumberOfCharsToRead,
|
|
|
|
lpNumberOfCharsRead,
|
|
|
|
NULL,
|
|
|
|
FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* PeekConsoleInputW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
PeekConsoleInputW(IN HANDLE hConsoleInput,
|
|
|
|
OUT PINPUT_RECORD lpBuffer,
|
|
|
|
IN DWORD nLength,
|
|
|
|
OUT LPDWORD lpNumberOfEventsRead)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
return IntGetConsoleInput(hConsoleInput,
|
|
|
|
lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsRead,
|
2013-11-10 20:20:57 +00:00
|
|
|
CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE,
|
2012-11-17 21:39:41 +00:00
|
|
|
TRUE);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* PeekConsoleInputA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
PeekConsoleInputA(IN HANDLE hConsoleInput,
|
|
|
|
OUT PINPUT_RECORD lpBuffer,
|
|
|
|
IN DWORD nLength,
|
|
|
|
OUT LPDWORD lpNumberOfEventsRead)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
return IntGetConsoleInput(hConsoleInput,
|
|
|
|
lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsRead,
|
2013-11-10 20:20:57 +00:00
|
|
|
CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE,
|
2012-11-17 21:39:41 +00:00
|
|
|
FALSE);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* ReadConsoleInputW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
ReadConsoleInputW(IN HANDLE hConsoleInput,
|
|
|
|
OUT PINPUT_RECORD lpBuffer,
|
|
|
|
IN DWORD nLength,
|
|
|
|
OUT LPDWORD lpNumberOfEventsRead)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
return IntGetConsoleInput(hConsoleInput,
|
|
|
|
lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsRead,
|
2013-11-10 20:20:57 +00:00
|
|
|
0,
|
2012-11-17 21:39:41 +00:00
|
|
|
TRUE);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* ReadConsoleInputA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
ReadConsoleInputA(IN HANDLE hConsoleInput,
|
|
|
|
OUT PINPUT_RECORD lpBuffer,
|
|
|
|
IN DWORD nLength,
|
|
|
|
OUT LPDWORD lpNumberOfEventsRead)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
return IntGetConsoleInput(hConsoleInput,
|
|
|
|
lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsRead,
|
2013-11-10 20:20:57 +00:00
|
|
|
0,
|
2012-11-17 21:39:41 +00:00
|
|
|
FALSE);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-11-10 20:20:57 +00:00
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* ReadConsoleInputExW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2012-11-15 18:06:17 +00:00
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
ReadConsoleInputExW(IN HANDLE hConsoleInput,
|
|
|
|
OUT PINPUT_RECORD lpBuffer,
|
|
|
|
IN DWORD nLength,
|
|
|
|
OUT LPDWORD lpNumberOfEventsRead,
|
|
|
|
IN WORD wFlags)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2013-11-10 20:20:57 +00:00
|
|
|
return IntGetConsoleInput(hConsoleInput,
|
|
|
|
lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsRead,
|
|
|
|
wFlags,
|
|
|
|
TRUE);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-11-10 20:20:57 +00:00
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* ReadConsoleInputExA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2012-11-15 18:06:17 +00:00
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
ReadConsoleInputExA(IN HANDLE hConsoleInput,
|
|
|
|
OUT PINPUT_RECORD lpBuffer,
|
|
|
|
IN DWORD nLength,
|
|
|
|
OUT LPDWORD lpNumberOfEventsRead,
|
|
|
|
IN WORD wFlags)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2013-11-10 20:20:57 +00:00
|
|
|
return IntGetConsoleInput(hConsoleInput,
|
|
|
|
lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsRead,
|
|
|
|
wFlags,
|
|
|
|
FALSE);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* ReadConsoleOutputW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
ReadConsoleOutputW(HANDLE hConsoleOutput,
|
|
|
|
PCHAR_INFO lpBuffer,
|
|
|
|
COORD dwBufferSize,
|
|
|
|
COORD dwBufferCoord,
|
|
|
|
PSMALL_RECT lpReadRegion)
|
|
|
|
{
|
|
|
|
return IntReadConsoleOutput(hConsoleOutput,
|
|
|
|
lpBuffer,
|
|
|
|
dwBufferSize,
|
|
|
|
dwBufferCoord,
|
|
|
|
lpReadRegion,
|
|
|
|
TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* ReadConsoleOutputA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
ReadConsoleOutputA(HANDLE hConsoleOutput,
|
|
|
|
PCHAR_INFO lpBuffer,
|
|
|
|
COORD dwBufferSize,
|
|
|
|
COORD dwBufferCoord,
|
|
|
|
PSMALL_RECT lpReadRegion)
|
|
|
|
{
|
|
|
|
return IntReadConsoleOutput(hConsoleOutput,
|
|
|
|
lpBuffer,
|
|
|
|
dwBufferSize,
|
|
|
|
dwBufferCoord,
|
|
|
|
lpReadRegion,
|
|
|
|
FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* ReadConsoleOutputCharacterW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
ReadConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
|
|
|
|
OUT LPWSTR lpCharacter,
|
|
|
|
IN DWORD nLength,
|
|
|
|
IN COORD dwReadCoord,
|
|
|
|
OUT LPDWORD lpNumberOfCharsRead)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
return IntReadConsoleOutputCode(hConsoleOutput,
|
|
|
|
CODE_UNICODE,
|
|
|
|
lpCharacter,
|
|
|
|
nLength,
|
|
|
|
dwReadCoord,
|
|
|
|
lpNumberOfCharsRead);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* ReadConsoleOutputCharacterA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
ReadConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
|
|
|
|
OUT LPSTR lpCharacter,
|
|
|
|
IN DWORD nLength,
|
|
|
|
IN COORD dwReadCoord,
|
|
|
|
OUT LPDWORD lpNumberOfCharsRead)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
return IntReadConsoleOutputCode(hConsoleOutput,
|
|
|
|
CODE_ASCII,
|
|
|
|
lpCharacter,
|
|
|
|
nLength,
|
|
|
|
dwReadCoord,
|
|
|
|
lpNumberOfCharsRead);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* ReadConsoleOutputAttribute
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
ReadConsoleOutputAttribute(IN HANDLE hConsoleOutput,
|
|
|
|
OUT LPWORD lpAttribute,
|
|
|
|
IN DWORD nLength,
|
|
|
|
IN COORD dwReadCoord,
|
|
|
|
OUT LPDWORD lpNumberOfAttrsRead)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
return IntReadConsoleOutputCode(hConsoleOutput,
|
|
|
|
CODE_ATTRIBUTE,
|
|
|
|
lpAttribute,
|
|
|
|
nLength,
|
|
|
|
dwReadCoord,
|
|
|
|
lpNumberOfAttrsRead);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*******************
|
|
|
|
* Write functions *
|
|
|
|
*******************/
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
WriteConsoleW(HANDLE hConsoleOutput,
|
|
|
|
CONST VOID *lpBuffer,
|
|
|
|
DWORD nNumberOfCharsToWrite,
|
|
|
|
LPDWORD lpNumberOfCharsWritten,
|
|
|
|
LPVOID lpReserved)
|
|
|
|
{
|
|
|
|
return IntWriteConsole(hConsoleOutput,
|
|
|
|
(PVOID)lpBuffer,
|
|
|
|
nNumberOfCharsToWrite,
|
|
|
|
lpNumberOfCharsWritten,
|
|
|
|
lpReserved,
|
|
|
|
TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
WriteConsoleA(HANDLE hConsoleOutput,
|
|
|
|
CONST VOID *lpBuffer,
|
|
|
|
DWORD nNumberOfCharsToWrite,
|
|
|
|
LPDWORD lpNumberOfCharsWritten,
|
|
|
|
LPVOID lpReserved)
|
|
|
|
{
|
|
|
|
return IntWriteConsole(hConsoleOutput,
|
|
|
|
(PVOID)lpBuffer,
|
|
|
|
nNumberOfCharsToWrite,
|
|
|
|
lpNumberOfCharsWritten,
|
|
|
|
lpReserved,
|
|
|
|
FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleInputW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
WriteConsoleInputW(IN HANDLE hConsoleInput,
|
|
|
|
IN CONST INPUT_RECORD *lpBuffer,
|
|
|
|
IN DWORD nLength,
|
|
|
|
OUT LPDWORD lpNumberOfEventsWritten)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
|
|
|
return IntWriteConsoleInput(hConsoleInput,
|
|
|
|
(PINPUT_RECORD)lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsWritten,
|
2013-10-26 20:53:05 +00:00
|
|
|
TRUE,
|
2012-11-15 18:06:17 +00:00
|
|
|
TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleInputA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
WriteConsoleInputA(IN HANDLE hConsoleInput,
|
|
|
|
IN CONST INPUT_RECORD *lpBuffer,
|
|
|
|
IN DWORD nLength,
|
|
|
|
OUT LPDWORD lpNumberOfEventsWritten)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
|
|
|
return IntWriteConsoleInput(hConsoleInput,
|
|
|
|
(PINPUT_RECORD)lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsWritten,
|
2013-10-26 20:53:05 +00:00
|
|
|
FALSE,
|
|
|
|
TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleInputVDMW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
WriteConsoleInputVDMW(IN HANDLE hConsoleInput,
|
|
|
|
IN CONST INPUT_RECORD *lpBuffer,
|
|
|
|
IN DWORD nLength,
|
|
|
|
OUT LPDWORD lpNumberOfEventsWritten)
|
2013-10-26 20:53:05 +00:00
|
|
|
{
|
|
|
|
return IntWriteConsoleInput(hConsoleInput,
|
|
|
|
(PINPUT_RECORD)lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsWritten,
|
|
|
|
TRUE,
|
|
|
|
FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleInputVDMA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
WriteConsoleInputVDMA(IN HANDLE hConsoleInput,
|
|
|
|
IN CONST INPUT_RECORD *lpBuffer,
|
|
|
|
IN DWORD nLength,
|
|
|
|
OUT LPDWORD lpNumberOfEventsWritten)
|
2013-10-26 20:53:05 +00:00
|
|
|
{
|
|
|
|
return IntWriteConsoleInput(hConsoleInput,
|
|
|
|
(PINPUT_RECORD)lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsWritten,
|
|
|
|
FALSE,
|
2012-11-15 18:06:17 +00:00
|
|
|
FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleOutputW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
WriteConsoleOutputW(HANDLE hConsoleOutput,
|
|
|
|
CONST CHAR_INFO *lpBuffer,
|
|
|
|
COORD dwBufferSize,
|
|
|
|
COORD dwBufferCoord,
|
|
|
|
PSMALL_RECT lpWriteRegion)
|
|
|
|
{
|
|
|
|
return IntWriteConsoleOutput(hConsoleOutput,
|
|
|
|
lpBuffer,
|
|
|
|
dwBufferSize,
|
|
|
|
dwBufferCoord,
|
|
|
|
lpWriteRegion,
|
|
|
|
TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleOutputA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
WriteConsoleOutputA(HANDLE hConsoleOutput,
|
|
|
|
CONST CHAR_INFO *lpBuffer,
|
|
|
|
COORD dwBufferSize,
|
|
|
|
COORD dwBufferCoord,
|
|
|
|
PSMALL_RECT lpWriteRegion)
|
|
|
|
{
|
|
|
|
return IntWriteConsoleOutput(hConsoleOutput,
|
|
|
|
lpBuffer,
|
|
|
|
dwBufferSize,
|
|
|
|
dwBufferCoord,
|
|
|
|
lpWriteRegion,
|
|
|
|
FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleOutputCharacterW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
WriteConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
|
|
|
|
IN LPCWSTR lpCharacter,
|
|
|
|
IN DWORD nLength,
|
|
|
|
IN COORD dwWriteCoord,
|
|
|
|
OUT LPDWORD lpNumberOfCharsWritten)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-19 23:26:36 +00:00
|
|
|
return IntWriteConsoleOutputCode(hConsoleOutput,
|
|
|
|
CODE_UNICODE,
|
|
|
|
lpCharacter,
|
|
|
|
nLength,
|
|
|
|
dwWriteCoord,
|
|
|
|
lpNumberOfCharsWritten);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleOutputCharacterA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
WriteConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
|
|
|
|
IN LPCSTR lpCharacter,
|
|
|
|
IN DWORD nLength,
|
|
|
|
IN COORD dwWriteCoord,
|
|
|
|
OUT LPDWORD lpNumberOfCharsWritten)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-19 23:26:36 +00:00
|
|
|
return IntWriteConsoleOutputCode(hConsoleOutput,
|
|
|
|
CODE_ASCII,
|
|
|
|
lpCharacter,
|
|
|
|
nLength,
|
|
|
|
dwWriteCoord,
|
|
|
|
lpNumberOfCharsWritten);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleOutputAttribute
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
WriteConsoleOutputAttribute(IN HANDLE hConsoleOutput,
|
|
|
|
IN CONST WORD *lpAttribute,
|
|
|
|
IN DWORD nLength,
|
|
|
|
IN COORD dwWriteCoord,
|
|
|
|
OUT LPDWORD lpNumberOfAttrsWritten)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-19 23:26:36 +00:00
|
|
|
return IntWriteConsoleOutputCode(hConsoleOutput,
|
|
|
|
CODE_ATTRIBUTE,
|
|
|
|
lpAttribute,
|
|
|
|
nLength,
|
|
|
|
dwWriteCoord,
|
|
|
|
lpNumberOfAttrsWritten);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* FillConsoleOutputCharacterW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
FillConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
|
|
|
|
IN WCHAR cCharacter,
|
|
|
|
IN DWORD nLength,
|
|
|
|
IN COORD dwWriteCoord,
|
|
|
|
OUT LPDWORD lpNumberOfCharsWritten)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-29 13:18:59 +00:00
|
|
|
CODE_ELEMENT Code;
|
|
|
|
Code.UnicodeChar = cCharacter;
|
2012-11-18 17:06:48 +00:00
|
|
|
return IntFillConsoleOutputCode(hConsoleOutput,
|
|
|
|
CODE_UNICODE,
|
2014-07-29 13:18:59 +00:00
|
|
|
Code,
|
2012-11-18 17:06:48 +00:00
|
|
|
nLength,
|
|
|
|
dwWriteCoord,
|
|
|
|
lpNumberOfCharsWritten);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* FillConsoleOutputCharacterA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
FillConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
|
|
|
|
IN CHAR cCharacter,
|
|
|
|
IN DWORD nLength,
|
|
|
|
IN COORD dwWriteCoord,
|
2012-11-15 18:06:17 +00:00
|
|
|
LPDWORD lpNumberOfCharsWritten)
|
|
|
|
{
|
2014-07-29 13:18:59 +00:00
|
|
|
CODE_ELEMENT Code;
|
|
|
|
Code.AsciiChar = cCharacter;
|
2012-11-18 17:06:48 +00:00
|
|
|
return IntFillConsoleOutputCode(hConsoleOutput,
|
|
|
|
CODE_ASCII,
|
2014-07-29 13:18:59 +00:00
|
|
|
Code,
|
2012-11-18 17:06:48 +00:00
|
|
|
nLength,
|
|
|
|
dwWriteCoord,
|
|
|
|
lpNumberOfCharsWritten);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* FillConsoleOutputAttribute
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
2014-07-29 15:59:17 +00:00
|
|
|
FillConsoleOutputAttribute(IN HANDLE hConsoleOutput,
|
|
|
|
IN WORD wAttribute,
|
|
|
|
IN DWORD nLength,
|
|
|
|
IN COORD dwWriteCoord,
|
|
|
|
OUT LPDWORD lpNumberOfAttrsWritten)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2014-07-29 13:18:59 +00:00
|
|
|
CODE_ELEMENT Code;
|
|
|
|
Code.Attribute = wAttribute;
|
2012-11-18 17:06:48 +00:00
|
|
|
return IntFillConsoleOutputCode(hConsoleOutput,
|
|
|
|
CODE_ATTRIBUTE,
|
2014-07-29 13:18:59 +00:00
|
|
|
Code,
|
2012-11-18 17:06:48 +00:00
|
|
|
nLength,
|
|
|
|
dwWriteCoord,
|
|
|
|
lpNumberOfAttrsWritten);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|