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
|
|
|
NTSTATUS Status;
|
|
|
|
CONSOLE_API_MESSAGE ApiMessage;
|
|
|
|
PCSRSS_READ_CONSOLE 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);
|
|
|
|
|
|
|
|
ReadConsoleRequest->ConsoleHandle = hConsoleInput;
|
|
|
|
ReadConsoleRequest->Unicode = bUnicode;
|
|
|
|
ReadConsoleRequest->NrCharactersToRead = (WORD)nNumberOfCharsToRead;
|
|
|
|
ReadConsoleRequest->NrCharactersRead = 0;
|
|
|
|
ReadConsoleRequest->CtrlWakeupMask = 0;
|
2012-11-15 18:06:17 +00:00
|
|
|
if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
|
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
ReadConsoleRequest->NrCharactersRead = pInputControl->nInitialChars;
|
|
|
|
memcpy(ReadConsoleRequest->Buffer,
|
2012-11-15 18:06:17 +00:00
|
|
|
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-11-17 21:39:41 +00:00
|
|
|
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
|
|
|
CaptureBuffer,
|
|
|
|
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsole),
|
|
|
|
sizeof(CSRSS_READ_CONSOLE));
|
|
|
|
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
DPRINT1("CSR returned error in ReadConsole\n");
|
|
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
|
|
|
BaseSetLastNTError(Status);
|
|
|
|
return FALSE;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(lpBuffer,
|
2012-11-17 21:39:41 +00:00
|
|
|
ReadConsoleRequest->Buffer,
|
|
|
|
ReadConsoleRequest->NrCharactersRead * CharSize);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
if (lpNumberOfCharsRead != NULL)
|
2012-11-17 21:39:41 +00:00
|
|
|
*lpNumberOfCharsRead = ReadConsoleRequest->NrCharactersRead;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
|
2012-11-17 21:39:41 +00:00
|
|
|
pInputControl->dwControlKeyState = ReadConsoleRequest->ControlKeyState;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
2012-11-17 21:39:41 +00:00
|
|
|
IntGetConsoleInput(HANDLE hConsoleInput,
|
|
|
|
BOOL bRead,
|
|
|
|
PINPUT_RECORD lpBuffer,
|
|
|
|
DWORD nLength,
|
|
|
|
LPDWORD lpNumberOfEventsRead,
|
|
|
|
BOOL bUnicode)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
CONSOLE_API_MESSAGE ApiMessage;
|
|
|
|
PCSRSS_GET_CONSOLE_INPUT GetConsoleInputRequest = &ApiMessage.Data.GetConsoleInputRequest;
|
2012-11-15 18:06:17 +00:00
|
|
|
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
|
|
|
ULONG Size;
|
|
|
|
|
|
|
|
if (lpBuffer == NULL)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Size = nLength * sizeof(INPUT_RECORD);
|
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
DPRINT("IntGetConsoleInput: %lx %p\n", Size, lpNumberOfEventsRead);
|
|
|
|
|
2012-11-15 18:06:17 +00:00
|
|
|
/* 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 */
|
2012-11-17 21:39:41 +00:00
|
|
|
CsrAllocateMessagePointer(CaptureBuffer,
|
|
|
|
Size,
|
|
|
|
(PVOID*)&GetConsoleInputRequest->InputRecord);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
/* Set up the data to send to the Console Server */
|
2012-11-17 21:39:41 +00:00
|
|
|
GetConsoleInputRequest->ConsoleHandle = hConsoleInput;
|
|
|
|
GetConsoleInputRequest->Unicode = bUnicode;
|
|
|
|
GetConsoleInputRequest->bRead = bRead;
|
|
|
|
if (bRead == TRUE)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
GetConsoleInputRequest->InputsRead = 0;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
2012-11-17 21:39:41 +00:00
|
|
|
GetConsoleInputRequest->Length = nLength;
|
|
|
|
|
|
|
|
/* Call the server */
|
|
|
|
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
|
|
|
CaptureBuffer,
|
|
|
|
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleInput),
|
|
|
|
sizeof(CSRSS_GET_CONSOLE_INPUT));
|
|
|
|
DPRINT("Server returned: %x\n", ApiMessage.Status);
|
|
|
|
|
|
|
|
/** For Read only **
|
|
|
|
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
// BaseSetLastNTError(Status); ????
|
|
|
|
if (GetConsoleInputRequest->InputsRead == 0)
|
|
|
|
{
|
|
|
|
/\* we couldn't read a single record, fail *\/
|
|
|
|
BaseSetLastNTError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/\* FIXME - fail gracefully in case we already read at least one record? *\/
|
|
|
|
// break;
|
|
|
|
}
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
2012-11-17 21:39:41 +00:00
|
|
|
**/
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
/**
|
|
|
|
** TODO: !! Simplify the function !!
|
|
|
|
**/
|
|
|
|
if (bRead == TRUE) // ReadConsoleInput call.
|
|
|
|
{
|
|
|
|
/* Check for success */
|
|
|
|
if (NT_SUCCESS(Status) || NT_SUCCESS(Status = ApiMessage.Status))
|
|
|
|
{
|
|
|
|
/* Return the number of events read */
|
|
|
|
DPRINT("Events read: %lx\n", GetConsoleInputRequest->InputsRead/*Length*/);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
if (lpNumberOfEventsRead != NULL)
|
|
|
|
*lpNumberOfEventsRead = GetConsoleInputRequest->InputsRead/*Length*/;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
/* Copy into the buffer */
|
|
|
|
DPRINT("Copying to buffer\n");
|
|
|
|
RtlCopyMemory(lpBuffer,
|
|
|
|
GetConsoleInputRequest->InputRecord,
|
|
|
|
sizeof(INPUT_RECORD) * GetConsoleInputRequest->InputsRead/*Length*/);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (lpNumberOfEventsRead != NULL)
|
|
|
|
*lpNumberOfEventsRead = 0;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
/* Error out */
|
|
|
|
BaseSetLastNTError(ApiMessage.Status);
|
|
|
|
}
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
/* Release the capture buffer */
|
|
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
return (GetConsoleInputRequest->InputsRead > 0);
|
|
|
|
}
|
|
|
|
else // PeekConsoleInput call.
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
/* Check for success */
|
|
|
|
if (NT_SUCCESS(Status) || NT_SUCCESS(ApiMessage.Status))
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
/* Return the number of events read */
|
|
|
|
DPRINT("Events read: %lx\n", GetConsoleInputRequest->Length);
|
|
|
|
|
|
|
|
if (lpNumberOfEventsRead != NULL)
|
|
|
|
*lpNumberOfEventsRead = GetConsoleInputRequest->Length;
|
|
|
|
|
|
|
|
/* Copy into the buffer */
|
|
|
|
DPRINT("Copying to buffer\n");
|
|
|
|
RtlCopyMemory(lpBuffer,
|
|
|
|
GetConsoleInputRequest->InputRecord,
|
|
|
|
sizeof(INPUT_RECORD) * GetConsoleInputRequest->Length);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
if (lpNumberOfEventsRead != NULL)
|
|
|
|
*lpNumberOfEventsRead = 0;
|
|
|
|
|
|
|
|
/* Error out */
|
|
|
|
BaseSetLastNTError(ApiMessage.Status);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
/* Release the capture buffer */
|
|
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
/* Return TRUE or FALSE */
|
|
|
|
return NT_SUCCESS(ApiMessage.Status);
|
|
|
|
}
|
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;
|
|
|
|
PCSRSS_READ_CONSOLE_OUTPUT ReadConsoleOutputRequest = &ApiMessage.Data.ReadConsoleOutputRequest;
|
2012-11-15 18:06:17 +00:00
|
|
|
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
|
|
|
DWORD Size, SizeX, SizeY;
|
|
|
|
|
|
|
|
if (lpBuffer == NULL)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
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,
|
|
|
|
(PVOID*)&ReadConsoleOutputRequest->CharInfo);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
/* Set up the data to send to the Console Server */
|
2012-11-17 21:39:41 +00:00
|
|
|
ReadConsoleOutputRequest->ConsoleHandle = hConsoleOutput;
|
|
|
|
ReadConsoleOutputRequest->Unicode = bUnicode;
|
|
|
|
ReadConsoleOutputRequest->BufferSize = dwBufferSize;
|
|
|
|
ReadConsoleOutputRequest->BufferCoord = dwBufferCoord;
|
|
|
|
ReadConsoleOutputRequest->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),
|
|
|
|
sizeof(CSRSS_READ_CONSOLE_OUTPUT));
|
|
|
|
DPRINT("Server returned: %x\n", ApiMessage.Status);
|
2012-11-15 18:06:17 +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");
|
2012-11-17 21:39:41 +00:00
|
|
|
SizeX = ReadConsoleOutputRequest->ReadRegion.Right -
|
|
|
|
ReadConsoleOutputRequest->ReadRegion.Left + 1;
|
|
|
|
SizeY = ReadConsoleOutputRequest->ReadRegion.Bottom -
|
|
|
|
ReadConsoleOutputRequest->ReadRegion.Top + 1;
|
2012-11-15 18:06:17 +00:00
|
|
|
RtlCopyMemory(lpBuffer,
|
2012-11-17 21:39:41 +00:00
|
|
|
ReadConsoleOutputRequest->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 */
|
2012-11-17 21:39:41 +00:00
|
|
|
DPRINT("read region: %lx\n", ReadConsoleOutputRequest->ReadRegion);
|
|
|
|
*lpReadRegion = ReadConsoleOutputRequest->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
|
2012-11-17 21:39:41 +00:00
|
|
|
IntReadConsoleOutputCode(HANDLE hConsoleOutput,
|
|
|
|
USHORT CodeType,
|
|
|
|
PVOID pCode,
|
|
|
|
DWORD nLength,
|
|
|
|
COORD dwReadCoord,
|
|
|
|
LPDWORD lpNumberOfCodesRead)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2012-11-17 21:39:41 +00:00
|
|
|
CONSOLE_API_MESSAGE ApiMessage;
|
|
|
|
PCSRSS_READ_CONSOLE_OUTPUT_CODE ReadConsoleOutputCodeRequest = &ApiMessage.Data.ReadConsoleOutputCodeRequest;
|
|
|
|
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
|
|
|
ULONG SizeBytes, CodeSize;
|
|
|
|
DWORD /*CodesRead = 0,*/ BytesRead;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
/* Determine the needed size */
|
|
|
|
switch (CodeType)
|
|
|
|
{
|
|
|
|
case CODE_ASCII:
|
|
|
|
CodeSize = sizeof(CHAR);
|
|
|
|
break;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
case CODE_UNICODE:
|
|
|
|
CodeSize = sizeof(WCHAR);
|
|
|
|
break;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
case CODE_ATTRIBUTE:
|
|
|
|
CodeSize = sizeof(WORD);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
SizeBytes = nLength * CodeSize;
|
|
|
|
|
|
|
|
/* Allocate a Capture Buffer */
|
|
|
|
CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
|
|
|
|
if (CaptureBuffer == NULL)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
|
2012-11-15 18:06:17 +00:00
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
/* Allocate space in the Buffer */
|
|
|
|
CsrAllocateMessagePointer(CaptureBuffer,
|
|
|
|
SizeBytes,
|
|
|
|
(PVOID*)&ReadConsoleOutputCodeRequest->pCode.pCode);
|
|
|
|
|
|
|
|
/* Start reading */
|
|
|
|
ReadConsoleOutputCodeRequest->ConsoleHandle = hConsoleOutput;
|
|
|
|
ReadConsoleOutputCodeRequest->CodeType = CodeType;
|
|
|
|
ReadConsoleOutputCodeRequest->ReadCoord = dwReadCoord;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
// while (nLength > 0)
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
ReadConsoleOutputCodeRequest->NumCodesToRead = nLength;
|
|
|
|
// SizeBytes = ReadConsoleOutputCodeRequest->NumCodesToRead * CodeSize;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
|
|
|
CaptureBuffer,
|
|
|
|
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutputString),
|
|
|
|
sizeof(CSRSS_READ_CONSOLE_OUTPUT_CODE));
|
|
|
|
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
|
2012-11-15 18:06:17 +00:00
|
|
|
{
|
|
|
|
BaseSetLastNTError(Status);
|
2012-11-17 21:39:41 +00:00
|
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
|
|
|
return FALSE;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
BytesRead = ReadConsoleOutputCodeRequest->CodesRead * CodeSize;
|
|
|
|
memcpy(pCode, ReadConsoleOutputCodeRequest->pCode.pCode, BytesRead);
|
|
|
|
// pCode = (PVOID)((ULONG_PTR)pCode + /*(ULONG_PTR)*/BytesRead);
|
|
|
|
// nLength -= ReadConsoleOutputCodeRequest->CodesRead;
|
|
|
|
// CodesRead += ReadConsoleOutputCodeRequest->CodesRead;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
ReadConsoleOutputCodeRequest->ReadCoord = ReadConsoleOutputCodeRequest->EndCoord;
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
if (lpNumberOfCodesRead != NULL)
|
|
|
|
*lpNumberOfCodesRead = /*CodesRead;*/ ReadConsoleOutputCodeRequest->CodesRead;
|
2012-11-15 18:06:17 +00:00
|
|
|
|
2012-11-17 21:39:41 +00:00
|
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
2012-11-15 18:06:17 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*******************
|
|
|
|
* Write functions *
|
|
|
|
*******************/
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
IntWriteConsole(HANDLE hConsoleOutput,
|
|
|
|
PVOID lpBuffer,
|
|
|
|
DWORD nNumberOfCharsToWrite,
|
|
|
|
LPDWORD lpNumberOfCharsWritten,
|
|
|
|
LPVOID lpReserved,
|
|
|
|
BOOL bUnicode)
|
|
|
|
{
|
|
|
|
PCSR_API_MESSAGE Request;
|
|
|
|
ULONG CsrRequest;
|
|
|
|
NTSTATUS Status;
|
|
|
|
USHORT nChars;
|
|
|
|
ULONG SizeBytes, CharSize;
|
|
|
|
DWORD Written = 0;
|
|
|
|
|
|
|
|
CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
|
|
|
|
Request = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
|
|
0,
|
|
|
|
max(sizeof(CSR_API_MESSAGE),
|
|
|
|
CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + min(nNumberOfCharsToWrite,
|
|
|
|
CSRSS_MAX_WRITE_CONSOLE / CharSize) * CharSize));
|
|
|
|
if (Request == NULL)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
CsrRequest = CSR_CREATE_API_NUMBER(CSR_CONSOLE, WRITE_CONSOLE);
|
|
|
|
|
|
|
|
while (nNumberOfCharsToWrite > 0)
|
|
|
|
{
|
|
|
|
Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
|
|
|
|
Request->Data.WriteConsoleRequest.Unicode = bUnicode;
|
|
|
|
|
|
|
|
nChars = (USHORT)min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize);
|
|
|
|
Request->Data.WriteConsoleRequest.NrCharactersToWrite = nChars;
|
|
|
|
|
|
|
|
SizeBytes = nChars * CharSize;
|
|
|
|
|
|
|
|
memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, SizeBytes);
|
|
|
|
|
|
|
|
Status = CsrClientCallServer(Request,
|
|
|
|
NULL,
|
|
|
|
CsrRequest,
|
|
|
|
max(sizeof(CSR_API_MESSAGE),
|
|
|
|
CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes));
|
|
|
|
|
|
|
|
if (Status == STATUS_PENDING)
|
|
|
|
{
|
|
|
|
WaitForSingleObject(Request->Data.WriteConsoleRequest.UnpauseEvent, INFINITE);
|
|
|
|
CloseHandle(Request->Data.WriteConsoleRequest.UnpauseEvent);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
|
|
|
|
{
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
|
|
|
|
BaseSetLastNTError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nNumberOfCharsToWrite -= nChars;
|
|
|
|
lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
|
|
|
|
Written += Request->Data.WriteConsoleRequest.NrCharactersWritten;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lpNumberOfCharsWritten != NULL)
|
|
|
|
{
|
|
|
|
*lpNumberOfCharsWritten = Written;
|
|
|
|
}
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
IntWriteConsoleInput(HANDLE hConsoleInput,
|
|
|
|
PINPUT_RECORD lpBuffer,
|
|
|
|
DWORD nLength,
|
|
|
|
LPDWORD lpNumberOfEventsWritten,
|
|
|
|
BOOL bUnicode)
|
|
|
|
{
|
|
|
|
CSR_API_MESSAGE Request;
|
|
|
|
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
|
|
|
DWORD Size;
|
|
|
|
|
|
|
|
if (lpBuffer == NULL)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Size = nLength * sizeof(INPUT_RECORD);
|
|
|
|
|
|
|
|
/* Allocate a Capture Buffer */
|
|
|
|
DPRINT("IntWriteConsoleInput: %lx %p\n", Size, lpNumberOfEventsWritten);
|
|
|
|
CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
|
|
|
|
if (CaptureBuffer == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate space in the Buffer */
|
|
|
|
CsrCaptureMessageBuffer(CaptureBuffer,
|
|
|
|
lpBuffer,
|
|
|
|
Size,
|
|
|
|
(PVOID*)&Request.Data.WriteConsoleInputRequest.InputRecord);
|
|
|
|
|
|
|
|
/* Set up the data to send to the Console Server */
|
|
|
|
Request.Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
|
|
|
|
Request.Data.WriteConsoleInputRequest.Unicode = bUnicode;
|
|
|
|
Request.Data.WriteConsoleInputRequest.Length = nLength;
|
|
|
|
|
|
|
|
/* Call the server */
|
|
|
|
CsrClientCallServer(&Request,
|
|
|
|
CaptureBuffer,
|
|
|
|
CSR_CREATE_API_NUMBER(CSR_CONSOLE, WRITE_CONSOLE_INPUT),
|
|
|
|
sizeof(CSR_API_MESSAGE));
|
|
|
|
DPRINT("Server returned: %x\n", Request.Status);
|
|
|
|
|
|
|
|
/* Check for success*/
|
|
|
|
if (NT_SUCCESS(Request.Status))
|
|
|
|
{
|
|
|
|
/* Return the number of events read */
|
|
|
|
DPRINT("Events read: %lx\n", Request.Data.WriteConsoleInputRequest.Length);
|
|
|
|
*lpNumberOfEventsWritten = Request.Data.WriteConsoleInputRequest.Length;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Error out */
|
|
|
|
*lpNumberOfEventsWritten = 0;
|
|
|
|
BaseSetLastNTError(Request.Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Release the capture buffer */
|
|
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
|
|
|
|
|
|
|
/* Return TRUE or FALSE */
|
|
|
|
return NT_SUCCESS(Request.Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
IntWriteConsoleOutput(HANDLE hConsoleOutput,
|
|
|
|
CONST CHAR_INFO *lpBuffer,
|
|
|
|
COORD dwBufferSize,
|
|
|
|
COORD dwBufferCoord,
|
|
|
|
PSMALL_RECT lpWriteRegion,
|
|
|
|
BOOL bUnicode)
|
|
|
|
{
|
|
|
|
CSR_API_MESSAGE Request;
|
|
|
|
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
|
|
|
ULONG Size;
|
|
|
|
|
|
|
|
Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
|
|
|
|
|
|
|
|
/* Allocate a Capture Buffer */
|
|
|
|
DPRINT("IntWriteConsoleOutput: %lx %p\n", Size, lpWriteRegion);
|
|
|
|
CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
|
|
|
|
if (CaptureBuffer == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate space in the Buffer */
|
|
|
|
CsrCaptureMessageBuffer(CaptureBuffer,
|
|
|
|
NULL,
|
|
|
|
Size,
|
|
|
|
(PVOID*)&Request.Data.WriteConsoleOutputRequest.CharInfo);
|
|
|
|
|
|
|
|
/* Copy from the buffer */
|
|
|
|
RtlCopyMemory(Request.Data.WriteConsoleOutputRequest.CharInfo, lpBuffer, Size);
|
|
|
|
|
|
|
|
/* Set up the data to send to the Console Server */
|
|
|
|
Request.Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
|
|
|
|
Request.Data.WriteConsoleOutputRequest.Unicode = bUnicode;
|
|
|
|
Request.Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
|
|
|
|
Request.Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
|
|
|
|
Request.Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
|
|
|
|
|
|
|
|
/* Call the server */
|
|
|
|
CsrClientCallServer(&Request,
|
|
|
|
CaptureBuffer,
|
|
|
|
CSR_CREATE_API_NUMBER(CSR_CONSOLE, WRITE_CONSOLE_OUTPUT),
|
|
|
|
sizeof(CSR_API_MESSAGE));
|
|
|
|
DPRINT("Server returned: %x\n", Request.Status);
|
|
|
|
|
|
|
|
/* Check for success*/
|
|
|
|
if (!NT_SUCCESS(Request.Status))
|
|
|
|
{
|
|
|
|
/* Error out */
|
|
|
|
BaseSetLastNTError(Request.Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the read region */
|
|
|
|
DPRINT("read region: %lx\n", Request.Data.WriteConsoleOutputRequest.WriteRegion);
|
|
|
|
*lpWriteRegion = Request.Data.WriteConsoleOutputRequest.WriteRegion;
|
|
|
|
|
|
|
|
/* Release the capture buffer */
|
|
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
|
|
|
|
|
|
|
/* Return TRUE or FALSE */
|
|
|
|
return NT_SUCCESS(Request.Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
IntWriteConsoleOutputCharacter(HANDLE hConsoleOutput,
|
|
|
|
PVOID lpCharacter,
|
|
|
|
DWORD nLength,
|
|
|
|
COORD dwWriteCoord,
|
|
|
|
LPDWORD lpNumberOfCharsWritten,
|
|
|
|
BOOL bUnicode)
|
|
|
|
{
|
|
|
|
PCSR_API_MESSAGE Request;
|
|
|
|
ULONG CsrRequest;
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG CharSize, nChars;
|
|
|
|
//ULONG SizeBytes;
|
|
|
|
DWORD Written = 0;
|
|
|
|
|
|
|
|
CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
|
|
|
|
|
|
|
|
nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize);
|
|
|
|
//SizeBytes = nChars * CharSize;
|
|
|
|
|
|
|
|
Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
|
|
|
|
max(sizeof(CSR_API_MESSAGE),
|
|
|
|
CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
|
|
|
|
+ min (nChars, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
|
|
|
|
if (Request == NULL)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
CsrRequest = CSR_CREATE_API_NUMBER(CSR_CONSOLE, WRITE_CONSOLE_OUTPUT_CHAR);
|
|
|
|
Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
|
|
|
|
|
|
|
|
while (nLength > 0)
|
|
|
|
{
|
|
|
|
DWORD BytesWrite;
|
|
|
|
|
|
|
|
Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
|
|
|
|
Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode;
|
|
|
|
Request->Data.WriteConsoleOutputCharRequest.Length = (WORD)min(nLength, nChars);
|
|
|
|
BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize;
|
|
|
|
|
|
|
|
memcpy(Request->Data.WriteConsoleOutputCharRequest.String, lpCharacter, BytesWrite);
|
|
|
|
|
|
|
|
Status = CsrClientCallServer(Request,
|
|
|
|
NULL,
|
|
|
|
CsrRequest,
|
|
|
|
max(sizeof(CSR_API_MESSAGE),
|
|
|
|
CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + BytesWrite));
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
|
|
|
|
{
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
|
|
|
|
BaseSetLastNTError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nLength -= Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
|
|
|
|
lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)(Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten * CharSize));
|
|
|
|
Written += Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
|
|
|
|
|
|
|
|
Request->Data.WriteConsoleOutputCharRequest.Coord = Request->Data.WriteConsoleOutputCharRequest.EndCoord;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lpNumberOfCharsWritten != NULL)
|
|
|
|
{
|
|
|
|
*lpNumberOfCharsWritten = Written;
|
|
|
|
}
|
|
|
|
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
IntFillConsoleOutputCharacter(HANDLE hConsoleOutput,
|
|
|
|
PVOID cCharacter,
|
|
|
|
DWORD nLength,
|
|
|
|
COORD dwWriteCoord,
|
|
|
|
LPDWORD lpNumberOfCharsWritten,
|
|
|
|
BOOL bUnicode)
|
|
|
|
{
|
|
|
|
CSR_API_MESSAGE Request;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
|
|
|
|
Request.Data.FillOutputRequest.Unicode = bUnicode;
|
|
|
|
|
|
|
|
if(bUnicode)
|
|
|
|
Request.Data.FillOutputRequest.Char.UnicodeChar = *((WCHAR*)cCharacter);
|
|
|
|
else
|
|
|
|
Request.Data.FillOutputRequest.Char.AsciiChar = *((CHAR*)cCharacter);
|
|
|
|
|
|
|
|
Request.Data.FillOutputRequest.Position = dwWriteCoord;
|
|
|
|
Request.Data.FillOutputRequest.Length = (WORD)nLength;
|
|
|
|
|
|
|
|
Status = CsrClientCallServer(&Request,
|
|
|
|
NULL,
|
|
|
|
CSR_CREATE_API_NUMBER(CSR_CONSOLE, FILL_OUTPUT),
|
|
|
|
sizeof(CSR_API_MESSAGE));
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
|
|
|
|
{
|
|
|
|
BaseSetLastNTError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(lpNumberOfCharsWritten != NULL)
|
|
|
|
{
|
|
|
|
*lpNumberOfCharsWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 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
|
|
|
|
PeekConsoleInputW(HANDLE hConsoleInput,
|
|
|
|
PINPUT_RECORD lpBuffer,
|
|
|
|
DWORD nLength,
|
|
|
|
LPDWORD lpNumberOfEventsRead)
|
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
return IntGetConsoleInput(hConsoleInput,
|
|
|
|
FALSE,
|
|
|
|
lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsRead,
|
|
|
|
TRUE);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* PeekConsoleInputA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
PeekConsoleInputA(HANDLE hConsoleInput,
|
|
|
|
PINPUT_RECORD lpBuffer,
|
|
|
|
DWORD nLength,
|
|
|
|
LPDWORD lpNumberOfEventsRead)
|
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
return IntGetConsoleInput(hConsoleInput,
|
|
|
|
FALSE,
|
|
|
|
lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsRead,
|
|
|
|
FALSE);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* ReadConsoleInputW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
ReadConsoleInputW(HANDLE hConsoleInput,
|
|
|
|
PINPUT_RECORD lpBuffer,
|
|
|
|
DWORD nLength,
|
|
|
|
LPDWORD lpNumberOfEventsRead)
|
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
return IntGetConsoleInput(hConsoleInput,
|
|
|
|
TRUE,
|
|
|
|
lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsRead,
|
|
|
|
TRUE);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* ReadConsoleInputA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
ReadConsoleInputA(HANDLE hConsoleInput,
|
|
|
|
PINPUT_RECORD lpBuffer,
|
|
|
|
DWORD nLength,
|
|
|
|
LPDWORD lpNumberOfEventsRead)
|
|
|
|
{
|
2012-11-17 21:39:41 +00:00
|
|
|
return IntGetConsoleInput(hConsoleInput,
|
|
|
|
TRUE,
|
|
|
|
lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsRead,
|
|
|
|
FALSE);
|
2012-11-15 18:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
ReadConsoleInputExW(HANDLE hConsole, LPVOID lpBuffer, DWORD dwLen, LPDWORD Unknown1, DWORD Unknown2)
|
|
|
|
{
|
|
|
|
STUB;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
ReadConsoleInputExA(HANDLE hConsole, LPVOID lpBuffer, DWORD dwLen, LPDWORD Unknown1, DWORD Unknown2)
|
|
|
|
{
|
|
|
|
STUB;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* 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
|
|
|
|
ReadConsoleOutputCharacterW(HANDLE hConsoleOutput,
|
|
|
|
LPWSTR lpCharacter,
|
|
|
|
DWORD nLength,
|
|
|
|
COORD dwReadCoord,
|
|
|
|
LPDWORD lpNumberOfCharsRead)
|
|
|
|
{
|
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
|
|
|
|
ReadConsoleOutputCharacterA(HANDLE hConsoleOutput,
|
|
|
|
LPSTR lpCharacter,
|
|
|
|
DWORD nLength,
|
|
|
|
COORD dwReadCoord,
|
|
|
|
LPDWORD lpNumberOfCharsRead)
|
|
|
|
{
|
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
|
|
|
|
ReadConsoleOutputAttribute(HANDLE hConsoleOutput,
|
|
|
|
LPWORD lpAttribute,
|
|
|
|
DWORD nLength,
|
|
|
|
COORD dwReadCoord,
|
|
|
|
LPDWORD lpNumberOfAttrsRead)
|
|
|
|
{
|
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
|
|
|
|
WriteConsoleInputW(HANDLE hConsoleInput,
|
|
|
|
CONST INPUT_RECORD *lpBuffer,
|
|
|
|
DWORD nLength,
|
|
|
|
LPDWORD lpNumberOfEventsWritten)
|
|
|
|
{
|
|
|
|
return IntWriteConsoleInput(hConsoleInput,
|
|
|
|
(PINPUT_RECORD)lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsWritten,
|
|
|
|
TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleInputA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
WriteConsoleInputA(HANDLE hConsoleInput,
|
|
|
|
CONST INPUT_RECORD *lpBuffer,
|
|
|
|
DWORD nLength,
|
|
|
|
LPDWORD lpNumberOfEventsWritten)
|
|
|
|
{
|
|
|
|
return IntWriteConsoleInput(hConsoleInput,
|
|
|
|
(PINPUT_RECORD)lpBuffer,
|
|
|
|
nLength,
|
|
|
|
lpNumberOfEventsWritten,
|
|
|
|
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
|
|
|
|
WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
|
|
|
|
LPCWSTR lpCharacter,
|
|
|
|
DWORD nLength,
|
|
|
|
COORD dwWriteCoord,
|
|
|
|
LPDWORD lpNumberOfCharsWritten)
|
|
|
|
{
|
|
|
|
return IntWriteConsoleOutputCharacter(hConsoleOutput,
|
|
|
|
(PVOID)lpCharacter,
|
|
|
|
nLength,
|
|
|
|
dwWriteCoord,
|
|
|
|
lpNumberOfCharsWritten,
|
|
|
|
TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleOutputCharacterA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
|
|
|
|
LPCSTR lpCharacter,
|
|
|
|
DWORD nLength,
|
|
|
|
COORD dwWriteCoord,
|
|
|
|
LPDWORD lpNumberOfCharsWritten)
|
|
|
|
{
|
|
|
|
return IntWriteConsoleOutputCharacter(hConsoleOutput,
|
|
|
|
(PVOID)lpCharacter,
|
|
|
|
nLength,
|
|
|
|
dwWriteCoord,
|
|
|
|
lpNumberOfCharsWritten,
|
|
|
|
FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* WriteConsoleOutputAttribute
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
WriteConsoleOutputAttribute(HANDLE hConsoleOutput,
|
|
|
|
CONST WORD *lpAttribute,
|
|
|
|
DWORD nLength,
|
|
|
|
COORD dwWriteCoord,
|
|
|
|
LPDWORD lpNumberOfAttrsWritten)
|
|
|
|
{
|
|
|
|
PCSR_API_MESSAGE Request;
|
|
|
|
ULONG CsrRequest;
|
|
|
|
NTSTATUS Status;
|
|
|
|
WORD Size;
|
|
|
|
|
|
|
|
Request = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
|
|
0,
|
|
|
|
max(sizeof(CSR_API_MESSAGE),
|
|
|
|
CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
|
|
|
|
+ min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
|
|
|
|
if (Request == NULL)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
CsrRequest = CSR_CREATE_API_NUMBER(CSR_CONSOLE, WRITE_CONSOLE_OUTPUT_ATTRIB);
|
|
|
|
Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
|
|
|
|
|
|
|
|
if (lpNumberOfAttrsWritten)
|
|
|
|
*lpNumberOfAttrsWritten = nLength;
|
|
|
|
while (nLength)
|
|
|
|
{
|
|
|
|
Size = (WORD)min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD));
|
|
|
|
Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
|
|
|
|
Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
|
|
|
|
memcpy(Request->Data.WriteConsoleOutputAttribRequest.Attribute, lpAttribute, Size * sizeof(WORD));
|
|
|
|
|
|
|
|
Status = CsrClientCallServer(Request,
|
|
|
|
NULL,
|
|
|
|
CsrRequest,
|
|
|
|
max(sizeof(CSR_API_MESSAGE),
|
|
|
|
CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
|
|
|
|
{
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
|
|
|
|
BaseSetLastNTError (Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
nLength -= Size;
|
|
|
|
lpAttribute += Size;
|
|
|
|
Request->Data.WriteConsoleOutputAttribRequest.Coord = Request->Data.WriteConsoleOutputAttribRequest.EndCoord;
|
|
|
|
}
|
|
|
|
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* FillConsoleOutputCharacterW
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
FillConsoleOutputCharacterW(HANDLE hConsoleOutput,
|
|
|
|
WCHAR cCharacter,
|
|
|
|
DWORD nLength,
|
|
|
|
COORD dwWriteCoord,
|
|
|
|
LPDWORD lpNumberOfCharsWritten)
|
|
|
|
{
|
|
|
|
return IntFillConsoleOutputCharacter(hConsoleOutput,
|
|
|
|
&cCharacter,
|
|
|
|
nLength,
|
|
|
|
dwWriteCoord,
|
|
|
|
lpNumberOfCharsWritten,
|
|
|
|
TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* FillConsoleOutputCharacterA
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
FillConsoleOutputCharacterA(HANDLE hConsoleOutput,
|
|
|
|
CHAR cCharacter,
|
|
|
|
DWORD nLength,
|
|
|
|
COORD dwWriteCoord,
|
|
|
|
LPDWORD lpNumberOfCharsWritten)
|
|
|
|
{
|
|
|
|
return IntFillConsoleOutputCharacter(hConsoleOutput,
|
|
|
|
&cCharacter,
|
|
|
|
nLength,
|
|
|
|
dwWriteCoord,
|
|
|
|
lpNumberOfCharsWritten,
|
|
|
|
FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------
|
|
|
|
* FillConsoleOutputAttribute
|
|
|
|
*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
FillConsoleOutputAttribute(HANDLE hConsoleOutput,
|
|
|
|
WORD wAttribute,
|
|
|
|
DWORD nLength,
|
|
|
|
COORD dwWriteCoord,
|
|
|
|
LPDWORD lpNumberOfAttrsWritten)
|
|
|
|
{
|
|
|
|
CSR_API_MESSAGE Request;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
|
|
|
|
Request.Data.FillOutputAttribRequest.Attribute = (CHAR)wAttribute;
|
|
|
|
Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
|
|
|
|
Request.Data.FillOutputAttribRequest.Length = (WORD)nLength;
|
|
|
|
|
|
|
|
Status = CsrClientCallServer(&Request,
|
|
|
|
NULL,
|
|
|
|
CSR_CREATE_API_NUMBER(CSR_CONSOLE, FILL_OUTPUT_ATTRIB),
|
|
|
|
sizeof(CSR_API_MESSAGE));
|
|
|
|
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
|
|
|
|
{
|
|
|
|
BaseSetLastNTError ( Status );
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lpNumberOfAttrsWritten)
|
|
|
|
*lpNumberOfAttrsWritten = nLength;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|