Implemented ReadConsoleOutputA() and WriteConsoleInputA().

svn path=/trunk/; revision=3746
This commit is contained in:
Marty Dill 2002-11-12 00:48:26 +00:00
parent 13aca9ca62
commit 49c384301b
5 changed files with 299 additions and 9 deletions

View file

@ -311,6 +311,31 @@ typedef struct
DWORD Length;
} CSRSS_PEEK_CONSOLE_INPUT_REPLY, *PCSRSS_PEEK_CONSOLE_INPUT_REPLY;
typedef struct
{
HANDLE ConsoleHandle;
COORD BufferSize;
COORD BufferCoord;
SMALL_RECT ReadRegion;
CHAR_INFO* CharInfo;
} CSRSS_READ_CONSOLE_OUTPUT_REQUEST, *PCSRSS_READ_CONSOLE_OUTPUT_REQUEST;
typedef struct
{
SMALL_RECT ReadRegion;
} CSRSS_READ_CONSOLE_OUTPUT_REPLY, *PCSRSS_READ_CONSOLE_OUTPUT_REPLY;
typedef struct
{
HANDLE ConsoleHandle;
DWORD Length;
INPUT_RECORD* InputRecord;
} CSRSS_WRITE_CONSOLE_INPUT_REQUEST, *PCSRSS_WRITE_CONSOLE_INPUT_REQUEST;
typedef struct
{
DWORD Length;
} CSRSS_WRITE_CONSOLE_INPUT_REPLY, *PCSRSS_WRITE_CONSOLE_INPUT_REPLY;
#define CSRSS_MAX_WRITE_CONSOLE_REQUEST \
(MAX_MESSAGE_DATA - sizeof(ULONG) - sizeof(CSRSS_WRITE_CONSOLE_REQUEST))
@ -364,7 +389,8 @@ typedef struct
#define CSRSS_GET_SHUTDOWN_PARAMETERS (0x1F)
#define CSRSS_SET_SHUTDOWN_PARAMETERS (0x20)
#define CSRSS_PEEK_CONSOLE_INPUT (0x21)
#define CSRSS_READ_CONSOLE_OUTPUT (0x22)
#define CSRSS_WRITE_CONSOLE_INPUT (0x23)
/* Keep in sync with definition below. */
#define CSRSS_REQUEST_HEADER_SIZE (sizeof(LPC_MESSAGE) + sizeof(ULONG))
@ -406,6 +432,8 @@ typedef struct
CSRSS_EXIT_REACTOS_REQUEST ExitReactosRequest;
CSRSS_SHUTDOWN_PARAMETERS SetShutdownParametersRequest;
CSRSS_PEEK_CONSOLE_INPUT_REQUEST PeekConsoleInputRequest;
CSRSS_READ_CONSOLE_OUTPUT_REQUEST ReadConsoleOutputRequest;
CSRSS_WRITE_CONSOLE_INPUT_REQUEST WriteConsoleInputRequest;
} Data;
} CSRSS_API_REQUEST, *PCSRSS_API_REQUEST;
@ -434,6 +462,8 @@ typedef struct
CSRSS_GET_NUM_INPUT_EVENTS_REPLY GetNumInputEventsReply;
CSRSS_SHUTDOWN_PARAMETERS GetShutdownParametersReply;
CSRSS_PEEK_CONSOLE_INPUT_REPLY PeekConsoleInputReply;
CSRSS_READ_CONSOLE_OUTPUT_REPLY ReadConsoleOutputReply;
CSRSS_WRITE_CONSOLE_INPUT_REPLY WriteConsoleInputReply;
} Data;
} CSRSS_API_REPLY, *PCSRSS_API_REPLY;

View file

@ -1,4 +1,4 @@
/* $Id: console.c,v 1.47 2002/11/03 20:01:05 chorns Exp $
/* $Id: console.c,v 1.48 2002/11/12 00:48:25 mdill Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -937,7 +937,7 @@ PeekConsoleInputA(
LPDWORD lpNumberOfEventsRead
)
{
PCSRSS_API_REQUEST Request;
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
PVOID BufferBase;
@ -1118,8 +1118,55 @@ WriteConsoleInputA(
LPDWORD lpNumberOfEventsWritten
)
{
/* TO DO */
return FALSE;
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
PVOID BufferBase, BufferTargetBase;
NTSTATUS Status;
DWORD Size;
if(lpBuffer == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
Size = nLength * sizeof(INPUT_RECORD);
Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
if(!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
if(Request == NULL)
{
SetLastError(ERROR_OUTOFMEMORY);
CsrReleaseParameterBuffer(BufferBase);
return FALSE;
}
Request->Type = CSRSS_WRITE_CONSOLE_INPUT;
Request->Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
Request->Data.WriteConsoleInputRequest.Length = nLength;
Request->Data.WriteConsoleInputRequest.InputRecord = (PINPUT_RECORD)BufferTargetBase;
Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
{
RtlFreeHeap(GetProcessHeap(), 0, Request);
CsrReleaseParameterBuffer(BufferBase);
return FALSE;
}
if(lpNumberOfEventsWritten != NULL)
lpNumberOfEventsWritten = Reply.Data.WriteConsoleInputReply.Length;
RtlFreeHeap(GetProcessHeap(), 0, Request);
CsrReleaseParameterBuffer(BufferBase);
return TRUE;
}
@ -1155,8 +1202,62 @@ ReadConsoleOutputA(
PSMALL_RECT lpReadRegion
)
{
/* TO DO */
return FALSE;
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
PVOID BufferBase;
PVOID BufferTargetBase;
NTSTATUS Status;
DWORD Size, SizeX, SizeY;
if(lpBuffer == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
if(!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
if(Request == NULL)
{
SetLastError(ERROR_OUTOFMEMORY);
CsrReleaseParameterBuffer(BufferBase);
return FALSE;
}
Request->Type = CSRSS_READ_CONSOLE_OUTPUT;
Request->Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
Request->Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
Request->Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
Request->Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
Request->Data.ReadConsoleOutputRequest.CharInfo = (PCHAR_INFO)BufferTargetBase;
Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
{
SetLastErrorByStatus(Status);
RtlFreeHeap(GetProcessHeap(), 0, Request);
CsrReleaseParameterBuffer(BufferBase);
return FALSE;
}
SizeX = Reply.Data.ReadConsoleOutputReply.ReadRegion.Right - Reply.Data.ReadConsoleOutputReply.ReadRegion.Left + 1;
SizeY = Reply.Data.ReadConsoleOutputReply.ReadRegion.Bottom - Reply.Data.ReadConsoleOutputReply.ReadRegion.Top + 1;
memcpy(lpBuffer, BufferBase, sizeof(CHAR_INFO) * SizeX * SizeY);
*lpReadRegion = Reply.Data.ReadConsoleOutputReply.ReadRegion;
RtlFreeHeap(GetProcessHeap(), 0, Request);
CsrReleaseParameterBuffer(BufferBase);
return TRUE;
}

View file

@ -129,6 +129,8 @@ CSR_API(CsrExitReactos);
CSR_API(CsrGetShutdownParameters);
CSR_API(CsrSetShutdownParameters);
CSR_API(CsrPeekConsoleInput);
CSR_API(CsrReadConsoleOutput);
CSR_API(CsrWriteConsoleInput);
/* print.c */
VOID STDCALL DisplayString(LPCWSTR lpwString);

View file

@ -1,4 +1,4 @@
/* $Id: conio.c,v 1.37 2002/11/03 20:01:07 chorns Exp $
/* $Id: conio.c,v 1.38 2002/11/12 00:48:26 mdill Exp $
*
* reactos/subsys/csrss/api/conio.c
*
@ -1764,6 +1764,8 @@ CSR_API(CsrWriteConsoleOutput)
UNLOCK;
Reply->Data.WriteConsoleOutputReply.WriteRegion.Right = WriteRegion.Left + SizeX - 1;
Reply->Data.WriteConsoleOutputReply.WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
Reply->Data.WriteConsoleOutputReply.WriteRegion.Left = WriteRegion.Left;
Reply->Data.WriteConsoleOutputReply.WriteRegion.Top = WriteRegion.Top;
return (Reply->Status = STATUS_SUCCESS);
}
@ -2147,4 +2149,157 @@ CSR_API(CsrPeekConsoleInput)
return Reply->Status;
}
CSR_API(CsrReadConsoleOutput)
{
PCHAR_INFO CharInfo;
PCHAR_INFO CurCharInfo;
PCSRSS_SCREEN_BUFFER ScreenBuffer;
DWORD Size;
DWORD Length;
DWORD SizeX, SizeY;
NTSTATUS Status;
COORD BufferSize;
COORD BufferCoord;
SMALL_RECT ReadRegion;
SMALL_RECT ScreenRect;
DWORD i, Y, X, Offset;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
LOCK;
Status = CsrGetObject(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, (Object_t**)&ScreenBuffer);
if(!NT_SUCCESS(Status))
{
Reply->Status = Status;
UNLOCK;
return Reply->Status;
}
if(ScreenBuffer->Header.Type != CSRSS_SCREEN_BUFFER_MAGIC)
{
Reply->Status = STATUS_INVALID_HANDLE;
UNLOCK;
return Reply->Status;
}
CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo;
ReadRegion = Request->Data.ReadConsoleOutputRequest.ReadRegion;
BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize;
BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord;
Length = BufferSize.X * BufferSize.Y;
Size = Length * sizeof(INPUT_RECORD);
if(((PVOID)CharInfo < ProcessData->CsrSectionViewBase)
|| (((PVOID)CharInfo + Size) > (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
{
UNLOCK;
Reply->Status = STATUS_ACCESS_VIOLATION;
return Reply->Status ;
}
SizeY = RtlMin(BufferSize.Y - BufferCoord.Y, CsrpRectHeight(ReadRegion));
SizeX = RtlMin(BufferSize.X - BufferCoord.X, CsrpRectWidth(ReadRegion));
ReadRegion.Bottom = ReadRegion.Top + SizeY;
ReadRegion.Right = ReadRegion.Left + SizeX;
CsrpInitRect(ScreenRect, 0, 0, ScreenBuffer->MaxY - 1, ScreenBuffer->MaxX - 1);
if (!CsrpGetIntersection(&ReadRegion, ScreenRect, ReadRegion))
{
UNLOCK;
Reply->Status = STATUS_SUCCESS;
return Reply->Status;
}
for(i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y)
{
CurCharInfo = CharInfo + (i * BufferSize.Y);
Offset = (Y * ScreenBuffer->MaxX + ReadRegion.Left) * 2;
for(X = ReadRegion.Left; X < ReadRegion.Right; ++X)
{
CurCharInfo->Char.AsciiChar = GET_CELL_BUFFER(ScreenBuffer, Offset);
CurCharInfo->Attributes = GET_CELL_BUFFER(ScreenBuffer, Offset);
++CurCharInfo;
}
}
UNLOCK;
Reply->Status = STATUS_SUCCESS;
Reply->Data.ReadConsoleOutputReply.ReadRegion.Right = ReadRegion.Left + SizeX - 1;
Reply->Data.ReadConsoleOutputReply.ReadRegion.Bottom = ReadRegion.Top + SizeY - 1;
Reply->Data.ReadConsoleOutputReply.ReadRegion.Left = ReadRegion.Left;
Reply->Data.ReadConsoleOutputReply.ReadRegion.Top = ReadRegion.Top;
return Reply->Status;
}
CSR_API(CsrWriteConsoleInput)
{
PINPUT_RECORD InputRecord;
PCSRSS_CONSOLE Console;
NTSTATUS Status;
DWORD Length;
DWORD Size;
DWORD i;
PLIST_ENTRY NextItem;
ConsoleInput* Record;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
LOCK;
Status = CsrGetObject(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, (Object_t**)&Console);
if(!NT_SUCCESS(Status))
{
Reply->Status = Status;
UNLOCK;
return Reply->Status;
}
if(Console->Header.Type != CSRSS_CONSOLE_MAGIC)
{
Reply->Status = STATUS_INVALID_HANDLE;
UNLOCK;
return Reply->Status;
}
InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord;
Length = Request->Data.WriteConsoleInputRequest.Length;
Size = Length * sizeof(INPUT_RECORD);
if(((PVOID)InputRecord < ProcessData->CsrSectionViewBase)
|| (((PVOID)InputRecord + Size) > (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
{
UNLOCK;
Reply->Status = STATUS_ACCESS_VIOLATION;
return Reply->Status ;
}
for(i = 0; i < Length; ++i)
{
Record = RtlAllocateHeap(CsrssApiHeap, 0, sizeof(ConsoleInput));
if(Record == NULL)
{
UNLOCK;
Reply->Status = STATUS_INSUFFICIENT_RESOURCES;
return Reply->Status;
}
Record->InputEvent = *InputRecord++;
InsertTailList(&Console->InputEvents, &Record->ListEntry);
}
UNLOCK;
Reply->Status = STATUS_SUCCESS;
Reply->Data.WriteConsoleInputReply.Length = i;
return Reply->Status;
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: wapi.c,v 1.24 2002/10/31 01:50:00 ekohl Exp $
/* $Id: wapi.c,v 1.25 2002/11/12 00:48:26 mdill Exp $
*
* reactos/subsys/csrss/api/wapi.c
*
@ -61,6 +61,8 @@ static const CsrFunc CsrFuncs[] = {
CsrGetShutdownParameters,
CsrSetShutdownParameters,
CsrPeekConsoleInput,
CsrReadConsoleOutput,
CsrWriteConsoleInput,
0 };
static void Thread_Api2(HANDLE ServerPort)