mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +00:00
Implemented ReadConsoleOutputA() and WriteConsoleInputA().
svn path=/trunk/; revision=3746
This commit is contained in:
parent
13aca9ca62
commit
49c384301b
5 changed files with 299 additions and 9 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue