Author: hbelusca
Date: Sat Nov 17 15:41:31 2012
New Revision: 57717
URL:
http://svn.reactos.org/svn/reactos?rev=57717&view=rev
Log:
[CONSRV]
Code reorganization only, no code changes.
Modified:
branches/ros-csrss/win32ss/user/consrv/coninput.c
branches/ros-csrss/win32ss/user/consrv/conoutput.c
Modified: branches/ros-csrss/win32ss/user/consrv/coninput.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/c…
==============================================================================
--- branches/ros-csrss/win32ss/user/consrv/coninput.c [iso-8859-1] (original)
+++ branches/ros-csrss/win32ss/user/consrv/coninput.c [iso-8859-1] Sat Nov 17 15:41:31
2012
@@ -6,7 +6,7 @@
* PROGRAMMERS:
*/
-/* INCLUDES ******************************************************************/
+/* INCLUDES *******************************************************************/
#include "consrv.h"
#include "conio.h"
@@ -15,7 +15,8 @@
#define NDEBUG
#include <debug.h>
-/* GLOBALS *******************************************************************/
+
+/* GLOBALS ********************************************************************/
#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
@@ -23,147 +24,8 @@
#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1)
-/* FUNCTIONS *****************************************************************/
-
-CSR_API(SrvReadConsole)
-{
- PCSRSS_READ_CONSOLE ReadConsoleRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest;
- PLIST_ENTRY CurrentEntry;
- ConsoleInput *Input;
- PCHAR Buffer;
- PWCHAR UnicodeBuffer;
- ULONG i = 0;
- ULONG nNumberOfCharsToRead, CharSize;
- PCSR_PROCESS ProcessData = CsrGetClientThread()->Process;
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
-
- DPRINT("SrvReadConsole\n");
-
- CharSize = (ReadConsoleRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR));
-
- nNumberOfCharsToRead = ReadConsoleRequest->NrCharactersToRead;
-
- Buffer = (PCHAR)ReadConsoleRequest->Buffer;
- UnicodeBuffer = (PWCHAR)Buffer;
- if (!Win32CsrValidateBuffer(ProcessData, Buffer, nNumberOfCharsToRead, CharSize))
- return STATUS_ACCESS_VIOLATION;
-
- if (ReadConsoleRequest->NrCharactersRead * sizeof(WCHAR) > nNumberOfCharsToRead
* CharSize)
- return STATUS_INVALID_PARAMETER;
-
- Status = ConioLockConsole(ProcessData, ReadConsoleRequest->ConsoleHandle,
- &Console, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- ReadConsoleRequest->EventHandle = ProcessData->ConsoleEvent;
-
- Status = STATUS_PENDING; /* we haven't read anything (yet) */
- if (Console->Mode & ENABLE_LINE_INPUT)
- {
- if (Console->LineBuffer == NULL)
- {
- /* Starting a new line */
- Console->LineMaxSize = max(256, nNumberOfCharsToRead);
- Console->LineBuffer = HeapAlloc(ConSrvHeap, 0, Console->LineMaxSize *
sizeof(WCHAR));
- if (Console->LineBuffer == NULL)
- {
- Status = STATUS_NO_MEMORY;
- goto done;
- }
- Console->LineComplete = FALSE;
- Console->LineUpPressed = FALSE;
- Console->LineInsertToggle = 0;
- Console->LineWakeupMask = ReadConsoleRequest->CtrlWakeupMask;
- Console->LineSize = ReadConsoleRequest->NrCharactersRead;
- Console->LinePos = Console->LineSize;
- /* pre-filling the buffer is only allowed in the Unicode API,
- * so we don't need to worry about conversion */
- memcpy(Console->LineBuffer, Buffer, Console->LineSize *
sizeof(WCHAR));
- if (Console->LineSize == Console->LineMaxSize)
- {
- Console->LineComplete = TRUE;
- Console->LinePos = 0;
- }
- }
-
- /* If we don't have a complete line yet, process the pending input */
- while (!Console->LineComplete &&
!IsListEmpty(&Console->InputEvents))
- {
- /* remove input event from queue */
- CurrentEntry = RemoveHeadList(&Console->InputEvents);
- if (IsListEmpty(&Console->InputEvents))
- {
- ResetEvent(Console->ActiveEvent);
- }
- Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
-
- /* only pay attention to key down */
- if (KEY_EVENT == Input->InputEvent.EventType
- && Input->InputEvent.Event.KeyEvent.bKeyDown)
- {
- LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent);
- ReadConsoleRequest->ControlKeyState =
Input->InputEvent.Event.KeyEvent.dwControlKeyState;
- }
- HeapFree(ConSrvHeap, 0, Input);
- }
-
- /* Check if we have a complete line to read from */
- if (Console->LineComplete)
- {
- while (i < nNumberOfCharsToRead && Console->LinePos !=
Console->LineSize)
- {
- WCHAR Char = Console->LineBuffer[Console->LinePos++];
- if (ReadConsoleRequest->Unicode)
- UnicodeBuffer[i++] = Char;
- else
- ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++],
&Char);
- }
- if (Console->LinePos == Console->LineSize)
- {
- /* Entire line has been read */
- HeapFree(ConSrvHeap, 0, Console->LineBuffer);
- Console->LineBuffer = NULL;
- }
- Status = STATUS_SUCCESS;
- }
- }
- else
- {
- /* Character input */
- while (i < nNumberOfCharsToRead &&
!IsListEmpty(&Console->InputEvents))
- {
- /* remove input event from queue */
- CurrentEntry = RemoveHeadList(&Console->InputEvents);
- if (IsListEmpty(&Console->InputEvents))
- {
- ResetEvent(Console->ActiveEvent);
- }
- Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
-
- /* only pay attention to valid ascii chars, on key down */
- if (KEY_EVENT == Input->InputEvent.EventType
- && Input->InputEvent.Event.KeyEvent.bKeyDown
- && Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar !=
L'\0')
- {
- WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;
- if (ReadConsoleRequest->Unicode)
- UnicodeBuffer[i++] = Char;
- else
- ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++],
&Char);
- Status = STATUS_SUCCESS; /* did read something */
- }
- HeapFree(ConSrvHeap, 0, Input);
- }
- }
-done:
- ReadConsoleRequest->NrCharactersRead = i;
- ConioUnlockConsole(Console);
-
- return Status;
-}
+
+/* PRIVATE FUNCTIONS **********************************************************/
static VOID FASTCALL
ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent)
@@ -425,135 +287,8 @@
ConioProcessChar(Console, &er);
}
-CSR_API(CsrReadInputEvent)
-{
- PCSRSS_READ_INPUT ReadInputRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadInputRequest;
- PLIST_ENTRY CurrentEntry;
- PCSR_PROCESS ProcessData = CsrGetClientThread()->Process;
- PCSRSS_CONSOLE Console;
- NTSTATUS Status;
- BOOLEAN Done = FALSE;
- ConsoleInput *Input;
-
- DPRINT("CsrReadInputEvent\n");
-
- ReadInputRequest->Event = ProcessData->ConsoleEvent;
-
- Status = ConioLockConsole(ProcessData, ReadInputRequest->ConsoleHandle,
&Console, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- /* only get input if there is any */
- CurrentEntry = Console->InputEvents.Flink;
- while (CurrentEntry != &Console->InputEvents)
- {
- Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
- CurrentEntry = CurrentEntry->Flink;
-
- if (Done)
- {
- ReadInputRequest->MoreEvents = TRUE;
- break;
- }
-
- RemoveEntryList(&Input->ListEntry);
-
- if (!Done)
- {
- ReadInputRequest->Input = Input->InputEvent;
- if (ReadInputRequest->Unicode == FALSE)
- {
- ConioInputEventToAnsi(Console, &ReadInputRequest->Input);
- }
- Done = TRUE;
- }
-
- HeapFree(ConSrvHeap, 0, Input);
- }
-
- if (Done)
- Status = STATUS_SUCCESS;
- else
- Status = STATUS_PENDING;
-
- if (IsListEmpty(&Console->InputEvents))
- {
- ResetEvent(Console->ActiveEvent);
- }
-
- ConioUnlockConsole(Console);
-
- return Status;
-}
-
-CSR_API(SrvFlushConsoleInputBuffer)
-{
- PCSRSS_FLUSH_INPUT_BUFFER FlushInputBufferRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FlushInputBufferRequest;
- PLIST_ENTRY CurrentEntry;
- PCSRSS_CONSOLE Console;
- ConsoleInput* Input;
- NTSTATUS Status;
-
- DPRINT("SrvFlushConsoleInputBuffer\n");
-
- Status = ConioLockConsole(CsrGetClientThread()->Process,
- FlushInputBufferRequest->ConsoleInput,
- &Console,
- GENERIC_WRITE);
- if(! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- /* Discard all entries in the input event queue */
- while (!IsListEmpty(&Console->InputEvents))
- {
- CurrentEntry = RemoveHeadList(&Console->InputEvents);
- Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
- /* Destroy the event */
- HeapFree(ConSrvHeap, 0, Input);
- }
- ResetEvent(Console->ActiveEvent);
-
- ConioUnlockConsole(Console);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(SrvGetConsoleNumberOfInputEvents)
-{
- NTSTATUS Status;
- PCSRSS_GET_NUM_INPUT_EVENTS GetNumInputEventsRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetNumInputEventsRequest;
- PCSRSS_CONSOLE Console;
- PLIST_ENTRY CurrentItem;
- DWORD NumEvents;
-
- DPRINT("SrvGetConsoleNumberOfInputEvents\n");
-
- Status = ConioLockConsole(CsrGetClientThread()->Process,
GetNumInputEventsRequest->ConsoleHandle, &Console, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- CurrentItem = Console->InputEvents.Flink;
- NumEvents = 0;
-
- /* If there are any events ... */
- while (CurrentItem != &Console->InputEvents)
- {
- CurrentItem = CurrentItem->Flink;
- NumEvents++;
- }
-
- ConioUnlockConsole(Console);
-
- GetNumInputEventsRequest->NumInputEvents = NumEvents;
-
- return STATUS_SUCCESS;
-}
+
+/* PUBLIC APIS ****************************************************************/
CSR_API(SrvGetConsoleInput)
{
@@ -661,4 +396,274 @@
return Status;
}
+CSR_API(SrvReadConsole)
+{
+ PCSRSS_READ_CONSOLE ReadConsoleRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest;
+ PLIST_ENTRY CurrentEntry;
+ ConsoleInput *Input;
+ PCHAR Buffer;
+ PWCHAR UnicodeBuffer;
+ ULONG i = 0;
+ ULONG nNumberOfCharsToRead, CharSize;
+ PCSR_PROCESS ProcessData = CsrGetClientThread()->Process;
+ PCSRSS_CONSOLE Console;
+ NTSTATUS Status;
+
+ DPRINT("SrvReadConsole\n");
+
+ CharSize = (ReadConsoleRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR));
+
+ nNumberOfCharsToRead = ReadConsoleRequest->NrCharactersToRead;
+
+ Buffer = (PCHAR)ReadConsoleRequest->Buffer;
+ UnicodeBuffer = (PWCHAR)Buffer;
+ if (!Win32CsrValidateBuffer(ProcessData, Buffer, nNumberOfCharsToRead, CharSize))
+ return STATUS_ACCESS_VIOLATION;
+
+ if (ReadConsoleRequest->NrCharactersRead * sizeof(WCHAR) > nNumberOfCharsToRead
* CharSize)
+ return STATUS_INVALID_PARAMETER;
+
+ Status = ConioLockConsole(ProcessData, ReadConsoleRequest->ConsoleHandle,
+ &Console, GENERIC_READ);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ ReadConsoleRequest->EventHandle = ProcessData->ConsoleEvent;
+
+ Status = STATUS_PENDING; /* we haven't read anything (yet) */
+ if (Console->Mode & ENABLE_LINE_INPUT)
+ {
+ if (Console->LineBuffer == NULL)
+ {
+ /* Starting a new line */
+ Console->LineMaxSize = max(256, nNumberOfCharsToRead);
+ Console->LineBuffer = HeapAlloc(ConSrvHeap, 0, Console->LineMaxSize *
sizeof(WCHAR));
+ if (Console->LineBuffer == NULL)
+ {
+ Status = STATUS_NO_MEMORY;
+ goto done;
+ }
+ Console->LineComplete = FALSE;
+ Console->LineUpPressed = FALSE;
+ Console->LineInsertToggle = 0;
+ Console->LineWakeupMask = ReadConsoleRequest->CtrlWakeupMask;
+ Console->LineSize = ReadConsoleRequest->NrCharactersRead;
+ Console->LinePos = Console->LineSize;
+ /* pre-filling the buffer is only allowed in the Unicode API,
+ * so we don't need to worry about conversion */
+ memcpy(Console->LineBuffer, Buffer, Console->LineSize *
sizeof(WCHAR));
+ if (Console->LineSize == Console->LineMaxSize)
+ {
+ Console->LineComplete = TRUE;
+ Console->LinePos = 0;
+ }
+ }
+
+ /* If we don't have a complete line yet, process the pending input */
+ while (!Console->LineComplete &&
!IsListEmpty(&Console->InputEvents))
+ {
+ /* remove input event from queue */
+ CurrentEntry = RemoveHeadList(&Console->InputEvents);
+ if (IsListEmpty(&Console->InputEvents))
+ {
+ ResetEvent(Console->ActiveEvent);
+ }
+ Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
+
+ /* only pay attention to key down */
+ if (KEY_EVENT == Input->InputEvent.EventType
+ && Input->InputEvent.Event.KeyEvent.bKeyDown)
+ {
+ LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent);
+ ReadConsoleRequest->ControlKeyState =
Input->InputEvent.Event.KeyEvent.dwControlKeyState;
+ }
+ HeapFree(ConSrvHeap, 0, Input);
+ }
+
+ /* Check if we have a complete line to read from */
+ if (Console->LineComplete)
+ {
+ while (i < nNumberOfCharsToRead && Console->LinePos !=
Console->LineSize)
+ {
+ WCHAR Char = Console->LineBuffer[Console->LinePos++];
+ if (ReadConsoleRequest->Unicode)
+ UnicodeBuffer[i++] = Char;
+ else
+ ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++],
&Char);
+ }
+ if (Console->LinePos == Console->LineSize)
+ {
+ /* Entire line has been read */
+ HeapFree(ConSrvHeap, 0, Console->LineBuffer);
+ Console->LineBuffer = NULL;
+ }
+ Status = STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ /* Character input */
+ while (i < nNumberOfCharsToRead &&
!IsListEmpty(&Console->InputEvents))
+ {
+ /* remove input event from queue */
+ CurrentEntry = RemoveHeadList(&Console->InputEvents);
+ if (IsListEmpty(&Console->InputEvents))
+ {
+ ResetEvent(Console->ActiveEvent);
+ }
+ Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
+
+ /* only pay attention to valid ascii chars, on key down */
+ if (KEY_EVENT == Input->InputEvent.EventType
+ && Input->InputEvent.Event.KeyEvent.bKeyDown
+ && Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar !=
L'\0')
+ {
+ WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;
+ if (ReadConsoleRequest->Unicode)
+ UnicodeBuffer[i++] = Char;
+ else
+ ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++],
&Char);
+ Status = STATUS_SUCCESS; /* did read something */
+ }
+ HeapFree(ConSrvHeap, 0, Input);
+ }
+ }
+done:
+ ReadConsoleRequest->NrCharactersRead = i;
+ ConioUnlockConsole(Console);
+
+ return Status;
+}
+
+CSR_API(CsrReadInputEvent)
+{
+ PCSRSS_READ_INPUT ReadInputRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadInputRequest;
+ PLIST_ENTRY CurrentEntry;
+ PCSR_PROCESS ProcessData = CsrGetClientThread()->Process;
+ PCSRSS_CONSOLE Console;
+ NTSTATUS Status;
+ BOOLEAN Done = FALSE;
+ ConsoleInput *Input;
+
+ DPRINT("CsrReadInputEvent\n");
+
+ ReadInputRequest->Event = ProcessData->ConsoleEvent;
+
+ Status = ConioLockConsole(ProcessData, ReadInputRequest->ConsoleHandle,
&Console, GENERIC_READ);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* only get input if there is any */
+ CurrentEntry = Console->InputEvents.Flink;
+ while (CurrentEntry != &Console->InputEvents)
+ {
+ Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
+ CurrentEntry = CurrentEntry->Flink;
+
+ if (Done)
+ {
+ ReadInputRequest->MoreEvents = TRUE;
+ break;
+ }
+
+ RemoveEntryList(&Input->ListEntry);
+
+ if (!Done)
+ {
+ ReadInputRequest->Input = Input->InputEvent;
+ if (ReadInputRequest->Unicode == FALSE)
+ {
+ ConioInputEventToAnsi(Console, &ReadInputRequest->Input);
+ }
+ Done = TRUE;
+ }
+
+ HeapFree(ConSrvHeap, 0, Input);
+ }
+
+ if (Done)
+ Status = STATUS_SUCCESS;
+ else
+ Status = STATUS_PENDING;
+
+ if (IsListEmpty(&Console->InputEvents))
+ {
+ ResetEvent(Console->ActiveEvent);
+ }
+
+ ConioUnlockConsole(Console);
+
+ return Status;
+}
+
+CSR_API(SrvFlushConsoleInputBuffer)
+{
+ PCSRSS_FLUSH_INPUT_BUFFER FlushInputBufferRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FlushInputBufferRequest;
+ PLIST_ENTRY CurrentEntry;
+ PCSRSS_CONSOLE Console;
+ ConsoleInput* Input;
+ NTSTATUS Status;
+
+ DPRINT("SrvFlushConsoleInputBuffer\n");
+
+ Status = ConioLockConsole(CsrGetClientThread()->Process,
+ FlushInputBufferRequest->ConsoleInput,
+ &Console,
+ GENERIC_WRITE);
+ if(! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Discard all entries in the input event queue */
+ while (!IsListEmpty(&Console->InputEvents))
+ {
+ CurrentEntry = RemoveHeadList(&Console->InputEvents);
+ Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
+ /* Destroy the event */
+ HeapFree(ConSrvHeap, 0, Input);
+ }
+ ResetEvent(Console->ActiveEvent);
+
+ ConioUnlockConsole(Console);
+
+ return STATUS_SUCCESS;
+}
+
+CSR_API(SrvGetConsoleNumberOfInputEvents)
+{
+ NTSTATUS Status;
+ PCSRSS_GET_NUM_INPUT_EVENTS GetNumInputEventsRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetNumInputEventsRequest;
+ PCSRSS_CONSOLE Console;
+ PLIST_ENTRY CurrentItem;
+ DWORD NumEvents;
+
+ DPRINT("SrvGetConsoleNumberOfInputEvents\n");
+
+ Status = ConioLockConsole(CsrGetClientThread()->Process,
GetNumInputEventsRequest->ConsoleHandle, &Console, GENERIC_READ);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ CurrentItem = Console->InputEvents.Flink;
+ NumEvents = 0;
+
+ /* If there are any events ... */
+ while (CurrentItem != &Console->InputEvents)
+ {
+ CurrentItem = CurrentItem->Flink;
+ NumEvents++;
+ }
+
+ ConioUnlockConsole(Console);
+
+ GetNumInputEventsRequest->NumInputEvents = NumEvents;
+
+ return STATUS_SUCCESS;
+}
+
/* EOF */
Modified: branches/ros-csrss/win32ss/user/consrv/conoutput.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/c…
==============================================================================
--- branches/ros-csrss/win32ss/user/consrv/conoutput.c [iso-8859-1] (original)
+++ branches/ros-csrss/win32ss/user/consrv/conoutput.c [iso-8859-1] Sat Nov 17 15:41:31
2012
@@ -6,7 +6,7 @@
* PROGRAMMERS:
*/
-/* INCLUDES ******************************************************************/
+/* INCLUDES *******************************************************************/
#include "consrv.h"
#include "conio.h"
@@ -14,13 +14,16 @@
#define NDEBUG
#include <debug.h>
-/* GLOBALS *******************************************************************/
+
+/* GLOBALS ********************************************************************/
#define ConioInitRect(Rect, top, left, bottom, right) \
- ((Rect)->Top) = top; \
- ((Rect)->Left) = left; \
- ((Rect)->Bottom) = bottom; \
- ((Rect)->Right) = right
+do { \
+ ((Rect)->Top) = top; \
+ ((Rect)->Left) = left; \
+ ((Rect)->Bottom) = bottom; \
+ ((Rect)->Right) = right; \
+} while(0)
#define ConioIsRectEmpty(Rect) \
(((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom))
@@ -31,7 +34,8 @@
#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \
MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
-/* FUNCTIONS *****************************************************************/
+
+/* PRIVATE FUNCTIONS **********************************************************/
PBYTE FASTCALL
ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buff, ULONG X, ULONG Y)
@@ -294,8 +298,10 @@
return TRUE;
}
-/* Move from one rectangle to another. We must be careful about the order that
- * this is done, to avoid overwriting parts of the source before they are moved. */
+/*
+ * Move from one rectangle to another. We must be careful about the order that
+ * this is done, to avoid overwriting parts of the source before they are moved.
+ */
static VOID FASTCALL
ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
SMALL_RECT *SrcRegion,
@@ -356,6 +362,162 @@
}
}
+VOID WINAPI
+ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer)
+{
+ PCSRSS_CONSOLE Console = Buffer->Header.Console;
+
+ RemoveEntryList(&Buffer->ListEntry);
+ if (Buffer == Console->ActiveBuffer)
+ {
+ /* Deleted active buffer; switch to most recently created */
+ Console->ActiveBuffer = NULL;
+ if (!IsListEmpty(&Console->BufferList))
+ {
+ Console->ActiveBuffer = CONTAINING_RECORD(Console->BufferList.Flink,
CSRSS_SCREEN_BUFFER, ListEntry);
+ ConioDrawConsole(Console);
+ }
+ }
+
+ HeapFree(ConSrvHeap, 0, Buffer->Buffer);
+ HeapFree(ConSrvHeap, 0, Buffer);
+}
+
+VOID FASTCALL
+ConioDrawConsole(PCSRSS_CONSOLE Console)
+{
+ SMALL_RECT Region;
+
+ ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1);
+
+ ConioDrawRegion(Console, &Region);
+}
+
+static VOID FASTCALL
+ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, COORD *Start,
UINT Length)
+{
+ if (Buff->MaxX <= Start->X + Length)
+ {
+ UpdateRect->Left = 0;
+ }
+ else
+ {
+ UpdateRect->Left = Start->X;
+ }
+ if (Buff->MaxX <= Start->X + Length)
+ {
+ UpdateRect->Right = Buff->MaxX - 1;
+ }
+ else
+ {
+ UpdateRect->Right = Start->X + Length - 1;
+ }
+ UpdateRect->Top = Start->Y;
+ UpdateRect->Bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX;
+ if (Buff->MaxY <= UpdateRect->Bottom)
+ {
+ UpdateRect->Bottom = Buff->MaxY - 1;
+ }
+}
+
+DWORD FASTCALL
+ConioEffectiveCursorSize(PCSRSS_CONSOLE Console, DWORD Scale)
+{
+ DWORD Size = (Console->ActiveBuffer->CursorInfo.dwSize * Scale + 99) / 100;
+ /* If line input in progress, perhaps adjust for insert toggle */
+ if (Console->LineBuffer && !Console->LineComplete &&
Console->LineInsertToggle)
+ return (Size * 2 <= Scale) ? (Size * 2) : (Size / 2);
+ return Size;
+}
+
+
+/* PUBLIC APIS ****************************************************************/
+
+CSR_API(SrvReadConsoleOutput)
+{
+ PCSRSS_READ_CONSOLE_OUTPUT ReadConsoleOutputRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleOutputRequest;
+ PCSR_PROCESS ProcessData = CsrGetClientThread()->Process;
+ PCHAR_INFO CharInfo;
+ PCHAR_INFO CurCharInfo;
+ PCSRSS_SCREEN_BUFFER Buff;
+ DWORD SizeX, SizeY;
+ NTSTATUS Status;
+ COORD BufferSize;
+ COORD BufferCoord;
+ SMALL_RECT ReadRegion;
+ SMALL_RECT ScreenRect;
+ DWORD i;
+ PBYTE Ptr;
+ LONG X, Y;
+ UINT CodePage;
+
+ DPRINT("SrvReadConsoleOutput\n");
+
+ Status = ConioLockScreenBuffer(ProcessData,
ReadConsoleOutputRequest->ConsoleHandle, &Buff, GENERIC_READ);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ CharInfo = ReadConsoleOutputRequest->CharInfo;
+ ReadRegion = ReadConsoleOutputRequest->ReadRegion;
+ BufferSize = ReadConsoleOutputRequest->BufferSize;
+ BufferCoord = ReadConsoleOutputRequest->BufferCoord;
+
+ /* FIXME: Is this correct? */
+ CodePage = ProcessData->Console->OutputCodePage;
+
+ if (!Win32CsrValidateBuffer(ProcessData, CharInfo,
+ BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO)))
+ {
+ ConioUnlockScreenBuffer(Buff);
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion));
+ SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion));
+ ReadRegion.Bottom = ReadRegion.Top + SizeY;
+ ReadRegion.Right = ReadRegion.Left + SizeX;
+
+ ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX);
+ if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion))
+ {
+ ConioUnlockScreenBuffer(Buff);
+ return STATUS_SUCCESS;
+ }
+
+ for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y)
+ {
+ CurCharInfo = CharInfo + (i * BufferSize.X);
+
+ Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y);
+ for (X = ReadRegion.Left; X < ReadRegion.Right; ++X)
+ {
+ if (ReadConsoleOutputRequest->Unicode)
+ {
+ MultiByteToWideChar(CodePage, 0,
+ (PCHAR)Ptr++, 1,
+ &CurCharInfo->Char.UnicodeChar, 1);
+ }
+ else
+ {
+ CurCharInfo->Char.AsciiChar = *Ptr++;
+ }
+ CurCharInfo->Attributes = *Ptr++;
+ ++CurCharInfo;
+ }
+ }
+
+ ConioUnlockScreenBuffer(Buff);
+
+ ReadConsoleOutputRequest->ReadRegion.Right = ReadRegion.Left + SizeX - 1;
+ ReadConsoleOutputRequest->ReadRegion.Bottom = ReadRegion.Top + SizeY - 1;
+ ReadConsoleOutputRequest->ReadRegion.Left = ReadRegion.Left;
+ ReadConsoleOutputRequest->ReadRegion.Top = ReadRegion.Top;
+
+ return STATUS_SUCCESS;
+}
+
CSR_API(SrvWriteConsole)
{
NTSTATUS Status;
@@ -441,139 +603,222 @@
return Status;
}
-VOID WINAPI
-ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer)
-{
- PCSRSS_CONSOLE Console = Buffer->Header.Console;
-
- RemoveEntryList(&Buffer->ListEntry);
- if (Buffer == Console->ActiveBuffer)
- {
- /* Deleted active buffer; switch to most recently created */
- Console->ActiveBuffer = NULL;
- if (!IsListEmpty(&Console->BufferList))
- {
- Console->ActiveBuffer = CONTAINING_RECORD(Console->BufferList.Flink,
CSRSS_SCREEN_BUFFER, ListEntry);
- ConioDrawConsole(Console);
- }
- }
-
- HeapFree(ConSrvHeap, 0, Buffer->Buffer);
- HeapFree(ConSrvHeap, 0, Buffer);
-}
-
-VOID FASTCALL
-ConioDrawConsole(PCSRSS_CONSOLE Console)
-{
- SMALL_RECT Region;
-
- ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1);
-
- ConioDrawRegion(Console, &Region);
-}
-
-CSR_API(SrvGetConsoleScreenBufferInfo) // CsrGetScreenBufferInfo
-{
- NTSTATUS Status;
- PCSRSS_SCREEN_BUFFER_INFO ScreenBufferInfoRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScreenBufferInfoRequest;
+CSR_API(SrvWriteConsoleOutput)
+{
+ PCSRSS_WRITE_CONSOLE_OUTPUT WriteConsoleOutputRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleOutputRequest;
+ SHORT i, X, Y, SizeX, SizeY;
+ PCSR_PROCESS ProcessData = CsrGetClientThread()->Process;
PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff;
- PCONSOLE_SCREEN_BUFFER_INFO pInfo;
-
- DPRINT("SrvGetConsoleScreenBufferInfo\n");
-
- Status = ConioLockScreenBuffer(CsrGetClientThread()->Process,
ScreenBufferInfoRequest->ConsoleHandle, &Buff, GENERIC_READ);
+ SMALL_RECT ScreenBuffer;
+ CHAR_INFO* CurCharInfo;
+ SMALL_RECT WriteRegion;
+ CHAR_INFO* CharInfo;
+ COORD BufferCoord;
+ COORD BufferSize;
+ NTSTATUS Status;
+ PBYTE Ptr;
+
+ DPRINT("SrvWriteConsoleOutput\n");
+
+ Status = ConioLockScreenBuffer(ProcessData,
+ WriteConsoleOutputRequest->ConsoleHandle,
+ &Buff,
+ GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
return Status;
}
Console = Buff->Header.Console;
- pInfo = &ScreenBufferInfoRequest->Info;
- pInfo->dwSize.X = Buff->MaxX;
- pInfo->dwSize.Y = Buff->MaxY;
- pInfo->dwCursorPosition.X = Buff->CurrentX;
- pInfo->dwCursorPosition.Y = Buff->CurrentY;
- pInfo->wAttributes = Buff->DefaultAttrib;
- pInfo->srWindow.Left = Buff->ShowX;
- pInfo->srWindow.Right = Buff->ShowX + Console->Size.X - 1;
- pInfo->srWindow.Top = Buff->ShowY;
- pInfo->srWindow.Bottom = Buff->ShowY + Console->Size.Y - 1;
- pInfo->dwMaximumWindowSize.X = Buff->MaxX;
- pInfo->dwMaximumWindowSize.Y = Buff->MaxY;
- ConioUnlockScreenBuffer(Buff);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(SrvSetConsoleCursor)
-{
- NTSTATUS Status;
- PCSRSS_SET_CURSOR SetCursorRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetCursorRequest;
+
+ BufferSize = WriteConsoleOutputRequest->BufferSize;
+ BufferCoord = WriteConsoleOutputRequest->BufferCoord;
+ CharInfo = WriteConsoleOutputRequest->CharInfo;
+ if (!Win32CsrValidateBuffer(ProcessData, CharInfo,
+ BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO)))
+ {
+ ConioUnlockScreenBuffer(Buff);
+ return STATUS_ACCESS_VIOLATION;
+ }
+ WriteRegion = WriteConsoleOutputRequest->WriteRegion;
+
+ SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion));
+ SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion));
+ WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
+ WriteRegion.Right = WriteRegion.Left + SizeX - 1;
+
+ /* Make sure WriteRegion is inside the screen buffer */
+ ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
+ if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion))
+ {
+ ConioUnlockScreenBuffer(Buff);
+
+ /* It is okay to have a WriteRegion completely outside the screen buffer.
+ No data is written then. */
+ return STATUS_SUCCESS;
+ }
+
+ for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++)
+ {
+ CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X;
+ Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y);
+ for (X = WriteRegion.Left; X <= WriteRegion.Right; X++)
+ {
+ CHAR AsciiChar;
+ if (WriteConsoleOutputRequest->Unicode)
+ {
+ ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar,
&CurCharInfo->Char.UnicodeChar);
+ }
+ else
+ {
+ AsciiChar = CurCharInfo->Char.AsciiChar;
+ }
+ *Ptr++ = AsciiChar;
+ *Ptr++ = CurCharInfo->Attributes;
+ CurCharInfo++;
+ }
+ }
+
+ ConioDrawRegion(Console, &WriteRegion);
+
+ ConioUnlockScreenBuffer(Buff);
+
+ WriteConsoleOutputRequest->WriteRegion.Right = WriteRegion.Left + SizeX - 1;
+ WriteConsoleOutputRequest->WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
+ WriteConsoleOutputRequest->WriteRegion.Left = WriteRegion.Left;
+ WriteConsoleOutputRequest->WriteRegion.Top = WriteRegion.Top;
+
+ return STATUS_SUCCESS;
+}
+
+CSR_API(CsrReadConsoleOutputChar)
+{
+ NTSTATUS Status;
+ PCSRSS_READ_CONSOLE_OUTPUT_CHAR ReadConsoleOutputCharRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleOutputCharRequest;
PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff;
- LONG OldCursorX, OldCursorY;
- LONG NewCursorX, NewCursorY;
-
- DPRINT("SrvSetConsoleCursor\n");
-
- Status = ConioLockScreenBuffer(CsrGetClientThread()->Process,
SetCursorRequest->ConsoleHandle, &Buff, GENERIC_WRITE);
+ DWORD Xpos, Ypos;
+ PCHAR ReadBuffer;
+ DWORD i;
+ ULONG CharSize;
+ CHAR Char;
+
+ DPRINT("CsrReadConsoleOutputChar\n");
+
+ ReadBuffer = ReadConsoleOutputCharRequest->String;
+
+ CharSize = (ReadConsoleOutputCharRequest->Unicode ? sizeof(WCHAR) :
sizeof(CHAR));
+
+ Status = ConioLockScreenBuffer(CsrGetClientThread()->Process,
ReadConsoleOutputCharRequest->ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
return Status;
}
Console = Buff->Header.Console;
- NewCursorX = SetCursorRequest->Position.X;
- NewCursorY = SetCursorRequest->Position.Y;
- if (NewCursorX < 0 || NewCursorX >= Buff->MaxX ||
- NewCursorY < 0 || NewCursorY >= Buff->MaxY)
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_INVALID_PARAMETER;
- }
- OldCursorX = Buff->CurrentX;
- OldCursorY = Buff->CurrentY;
- Buff->CurrentX = NewCursorX;
- Buff->CurrentY = NewCursorY;
- if (Buff == Console->ActiveBuffer)
- {
- if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_UNSUCCESSFUL;
- }
- }
-
- ConioUnlockScreenBuffer(Buff);
-
- return STATUS_SUCCESS;
-}
-
-static VOID FASTCALL
-ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, COORD *Start,
UINT Length)
-{
- if (Buff->MaxX <= Start->X + Length)
- {
- UpdateRect->Left = 0;
- }
- else
- {
- UpdateRect->Left = Start->X;
- }
- if (Buff->MaxX <= Start->X + Length)
- {
- UpdateRect->Right = Buff->MaxX - 1;
- }
- else
- {
- UpdateRect->Right = Start->X + Length - 1;
- }
- UpdateRect->Top = Start->Y;
- UpdateRect->Bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX;
- if (Buff->MaxY <= UpdateRect->Bottom)
- {
- UpdateRect->Bottom = Buff->MaxY - 1;
- }
+ Xpos = ReadConsoleOutputCharRequest->ReadCoord.X;
+ Ypos = (ReadConsoleOutputCharRequest->ReadCoord.Y + Buff->VirtualY) %
Buff->MaxY;
+
+ for (i = 0; i < ReadConsoleOutputCharRequest->NumCharsToRead; ++i)
+ {
+ Char = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)];
+
+ if(ReadConsoleOutputCharRequest->Unicode)
+ {
+ ConsoleAnsiCharToUnicodeChar(Console, (WCHAR*)ReadBuffer, &Char);
+ ReadBuffer += sizeof(WCHAR);
+ }
+ else
+ *(ReadBuffer++) = Char;
+
+ Xpos++;
+
+ if (Xpos == Buff->MaxX)
+ {
+ Xpos = 0;
+ Ypos++;
+
+ if (Ypos == Buff->MaxY)
+ {
+ Ypos = 0;
+ }
+ }
+ }
+
+ *ReadBuffer = 0;
+ ReadConsoleOutputCharRequest->EndCoord.X = Xpos;
+ ReadConsoleOutputCharRequest->EndCoord.Y = (Ypos - Buff->VirtualY +
Buff->MaxY) % Buff->MaxY;
+
+ ConioUnlockScreenBuffer(Buff);
+
+ ReadConsoleOutputCharRequest->CharsRead = (DWORD)((ULONG_PTR)ReadBuffer -
(ULONG_PTR)ReadConsoleOutputCharRequest->String) / CharSize;
+ if (ReadConsoleOutputCharRequest->CharsRead * CharSize +
CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE))
+ {
+ DPRINT1("Length won't fit in message\n");
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+CSR_API(CsrReadConsoleOutputAttrib)
+{
+ NTSTATUS Status;
+ PCSRSS_READ_CONSOLE_OUTPUT_ATTRIB ReadConsoleOutputAttribRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleOutputAttribRequest;
+ PCSRSS_SCREEN_BUFFER Buff;
+ DWORD Xpos, Ypos;
+ PWORD ReadBuffer;
+ DWORD i;
+ DWORD CurrentLength;
+
+ DPRINT("CsrReadConsoleOutputAttrib\n");
+
+ ReadBuffer = ReadConsoleOutputAttribRequest->Attribute;
+
+ Status = ConioLockScreenBuffer(CsrGetClientThread()->Process,
ReadConsoleOutputAttribRequest->ConsoleHandle, &Buff, GENERIC_READ);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ Xpos = ReadConsoleOutputAttribRequest->ReadCoord.X;
+ Ypos = (ReadConsoleOutputAttribRequest->ReadCoord.Y + Buff->VirtualY) %
Buff->MaxY;
+
+ for (i = 0; i < ReadConsoleOutputAttribRequest->NumAttrsToRead; ++i)
+ {
+ *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX) + 1];
+
+ ReadBuffer++;
+ Xpos++;
+
+ if (Xpos == Buff->MaxX)
+ {
+ Xpos = 0;
+ Ypos++;
+
+ if (Ypos == Buff->MaxY)
+ {
+ Ypos = 0;
+ }
+ }
+ }
+
+ *ReadBuffer = 0;
+
+ ReadConsoleOutputAttribRequest->EndCoord.X = Xpos;
+ ReadConsoleOutputAttribRequest->EndCoord.Y = (Ypos - Buff->VirtualY +
Buff->MaxY) % Buff->MaxY;
+
+ ConioUnlockScreenBuffer(Buff);
+
+ CurrentLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
+ + ReadConsoleOutputAttribRequest->NumAttrsToRead * sizeof(WORD);
+ if (CurrentLength > sizeof(CSR_API_MESSAGE))
+ {
+ DPRINT1("Length won't fit in message\n");
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ return STATUS_SUCCESS;
}
CSR_API(CsrWriteConsoleOutputChar)
@@ -675,6 +920,72 @@
return Status;
}
+CSR_API(CsrWriteConsoleOutputAttrib)
+{
+ PCSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB WriteConsoleOutputAttribRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleOutputAttribRequest;
+ PCSRSS_CONSOLE Console;
+ PCSRSS_SCREEN_BUFFER Buff;
+ PUCHAR Buffer;
+ PWORD Attribute;
+ int X, Y, Length;
+ NTSTATUS Status;
+ SMALL_RECT UpdateRect;
+
+ DPRINT("CsrWriteConsoleOutputAttrib\n");
+
+ if (ApiMessage->Header.u1.s1.TotalLength
+ < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
+ + WriteConsoleOutputAttribRequest->Length * sizeof(WORD))
+ {
+ DPRINT1("Invalid ApiMessage size\n");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Status = ConioLockScreenBuffer(CsrGetClientThread()->Process,
+ WriteConsoleOutputAttribRequest->ConsoleHandle,
+ &Buff,
+ GENERIC_WRITE);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ Console = Buff->Header.Console;
+
+ X = WriteConsoleOutputAttribRequest->Coord.X;
+ Y = (WriteConsoleOutputAttribRequest->Coord.Y + Buff->VirtualY) %
Buff->MaxY;
+ Length = WriteConsoleOutputAttribRequest->Length;
+ Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1];
+ Attribute = WriteConsoleOutputAttribRequest->Attribute;
+ while (Length--)
+ {
+ *Buffer = (UCHAR)(*Attribute++);
+ Buffer += 2;
+ if (++X == Buff->MaxX)
+ {
+ if (++Y == Buff->MaxY)
+ {
+ Y = 0;
+ Buffer = Buff->Buffer + 1;
+ }
+ X = 0;
+ }
+ }
+
+ if (Buff == Console->ActiveBuffer)
+ {
+ ConioComputeUpdateRect(Buff, &UpdateRect,
&WriteConsoleOutputAttribRequest->Coord,
+ WriteConsoleOutputAttribRequest->Length);
+ ConioDrawRegion(Console, &UpdateRect);
+ }
+
+ WriteConsoleOutputAttribRequest->EndCoord.X = X;
+ WriteConsoleOutputAttribRequest->EndCoord.Y = (Y + Buff->MaxY -
Buff->VirtualY) % Buff->MaxY;
+
+ ConioUnlockScreenBuffer(Buff);
+
+ return STATUS_SUCCESS;
+}
+
CSR_API(CsrFillOutputChar)
{
NTSTATUS Status;
@@ -732,72 +1043,6 @@
return STATUS_SUCCESS;
}
-CSR_API(CsrWriteConsoleOutputAttrib)
-{
- PCSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB WriteConsoleOutputAttribRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleOutputAttribRequest;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- PUCHAR Buffer;
- PWORD Attribute;
- int X, Y, Length;
- NTSTATUS Status;
- SMALL_RECT UpdateRect;
-
- DPRINT("CsrWriteConsoleOutputAttrib\n");
-
- if (ApiMessage->Header.u1.s1.TotalLength
- < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
- + WriteConsoleOutputAttribRequest->Length * sizeof(WORD))
- {
- DPRINT1("Invalid ApiMessage size\n");
- return STATUS_INVALID_PARAMETER;
- }
-
- Status = ConioLockScreenBuffer(CsrGetClientThread()->Process,
- WriteConsoleOutputAttribRequest->ConsoleHandle,
- &Buff,
- GENERIC_WRITE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- X = WriteConsoleOutputAttribRequest->Coord.X;
- Y = (WriteConsoleOutputAttribRequest->Coord.Y + Buff->VirtualY) %
Buff->MaxY;
- Length = WriteConsoleOutputAttribRequest->Length;
- Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1];
- Attribute = WriteConsoleOutputAttribRequest->Attribute;
- while (Length--)
- {
- *Buffer = (UCHAR)(*Attribute++);
- Buffer += 2;
- if (++X == Buff->MaxX)
- {
- if (++Y == Buff->MaxY)
- {
- Y = 0;
- Buffer = Buff->Buffer + 1;
- }
- X = 0;
- }
- }
-
- if (Buff == Console->ActiveBuffer)
- {
- ConioComputeUpdateRect(Buff, &UpdateRect,
&WriteConsoleOutputAttribRequest->Coord,
- WriteConsoleOutputAttribRequest->Length);
- ConioDrawRegion(Console, &UpdateRect);
- }
-
- WriteConsoleOutputAttribRequest->EndCoord.X = X;
- WriteConsoleOutputAttribRequest->EndCoord.Y = (Y + Buff->MaxY -
Buff->VirtualY) % Buff->MaxY;
-
- ConioUnlockScreenBuffer(Buff);
-
- return STATUS_SUCCESS;
-}
-
CSR_API(CsrFillOutputAttrib)
{
PCSRSS_FILL_OUTPUT_ATTRIB FillOutputAttribRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FillOutputAttribRequest;
@@ -850,16 +1095,6 @@
return STATUS_SUCCESS;
}
-DWORD FASTCALL
-ConioEffectiveCursorSize(PCSRSS_CONSOLE Console, DWORD Scale)
-{
- DWORD Size = (Console->ActiveBuffer->CursorInfo.dwSize * Scale + 99) / 100;
- /* If line input in progress, perhaps adjust for insert toggle */
- if (Console->LineBuffer && !Console->LineComplete &&
Console->LineInsertToggle)
- return (Size * 2 <= Scale) ? (Size * 2) : (Size / 2);
- return Size;
-}
-
CSR_API(SrvGetConsoleCursorInfo)
{
NTSTATUS Status;
@@ -916,6 +1151,50 @@
Buff->CursorInfo.bVisible = Visible;
if (! ConioSetCursorInfo(Console, Buff))
+ {
+ ConioUnlockScreenBuffer(Buff);
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ ConioUnlockScreenBuffer(Buff);
+
+ return STATUS_SUCCESS;
+}
+
+CSR_API(SrvSetConsoleCursorPosition)
+{
+ NTSTATUS Status;
+ PCSRSS_SET_CURSOR SetCursorRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetCursorRequest;
+ PCSRSS_CONSOLE Console;
+ PCSRSS_SCREEN_BUFFER Buff;
+ LONG OldCursorX, OldCursorY;
+ LONG NewCursorX, NewCursorY;
+
+ DPRINT("SrvSetConsoleCursorPosition\n");
+
+ Status = ConioLockScreenBuffer(CsrGetClientThread()->Process,
SetCursorRequest->ConsoleHandle, &Buff, GENERIC_WRITE);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ Console = Buff->Header.Console;
+
+ NewCursorX = SetCursorRequest->Position.X;
+ NewCursorY = SetCursorRequest->Position.Y;
+ if (NewCursorX < 0 || NewCursorX >= Buff->MaxX ||
+ NewCursorY < 0 || NewCursorY >= Buff->MaxY)
+ {
+ ConioUnlockScreenBuffer(Buff);
+ return STATUS_INVALID_PARAMETER;
+ }
+ OldCursorX = Buff->CurrentX;
+ OldCursorY = Buff->CurrentY;
+ Buff->CurrentX = NewCursorX;
+ Buff->CurrentY = NewCursorY;
+ if (Buff == Console->ActiveBuffer)
+ {
+ if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
{
ConioUnlockScreenBuffer(Buff);
return STATUS_UNSUCCESSFUL;
@@ -1023,6 +1302,39 @@
return Status;
}
+CSR_API(SrvGetConsoleScreenBufferInfo) // CsrGetScreenBufferInfo
+{
+ NTSTATUS Status;
+ PCSRSS_SCREEN_BUFFER_INFO ScreenBufferInfoRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScreenBufferInfoRequest;
+ PCSRSS_CONSOLE Console;
+ PCSRSS_SCREEN_BUFFER Buff;
+ PCONSOLE_SCREEN_BUFFER_INFO pInfo;
+
+ DPRINT("SrvGetConsoleScreenBufferInfo\n");
+
+ Status = ConioLockScreenBuffer(CsrGetClientThread()->Process,
ScreenBufferInfoRequest->ConsoleHandle, &Buff, GENERIC_READ);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ Console = Buff->Header.Console;
+ pInfo = &ScreenBufferInfoRequest->Info;
+ pInfo->dwSize.X = Buff->MaxX;
+ pInfo->dwSize.Y = Buff->MaxY;
+ pInfo->dwCursorPosition.X = Buff->CurrentX;
+ pInfo->dwCursorPosition.Y = Buff->CurrentY;
+ pInfo->wAttributes = Buff->DefaultAttrib;
+ pInfo->srWindow.Left = Buff->ShowX;
+ pInfo->srWindow.Right = Buff->ShowX + Console->Size.X - 1;
+ pInfo->srWindow.Top = Buff->ShowY;
+ pInfo->srWindow.Bottom = Buff->ShowY + Console->Size.Y - 1;
+ pInfo->dwMaximumWindowSize.X = Buff->MaxX;
+ pInfo->dwMaximumWindowSize.Y = Buff->MaxY;
+ ConioUnlockScreenBuffer(Buff);
+
+ return STATUS_SUCCESS;
+}
+
CSR_API(SrvSetConsoleActiveScreenBuffer)
{
NTSTATUS Status;
@@ -1056,94 +1368,6 @@
ConioDrawConsole(Console);
ConioUnlockScreenBuffer(Buff);
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(SrvWriteConsoleOutput)
-{
- PCSRSS_WRITE_CONSOLE_OUTPUT WriteConsoleOutputRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleOutputRequest;
- SHORT i, X, Y, SizeX, SizeY;
- PCSR_PROCESS ProcessData = CsrGetClientThread()->Process;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- SMALL_RECT ScreenBuffer;
- CHAR_INFO* CurCharInfo;
- SMALL_RECT WriteRegion;
- CHAR_INFO* CharInfo;
- COORD BufferCoord;
- COORD BufferSize;
- NTSTATUS Status;
- PBYTE Ptr;
-
- DPRINT("SrvWriteConsoleOutput\n");
-
- Status = ConioLockScreenBuffer(ProcessData,
- WriteConsoleOutputRequest->ConsoleHandle,
- &Buff,
- GENERIC_WRITE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- BufferSize = WriteConsoleOutputRequest->BufferSize;
- BufferCoord = WriteConsoleOutputRequest->BufferCoord;
- CharInfo = WriteConsoleOutputRequest->CharInfo;
- if (!Win32CsrValidateBuffer(ProcessData, CharInfo,
- BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO)))
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_ACCESS_VIOLATION;
- }
- WriteRegion = WriteConsoleOutputRequest->WriteRegion;
-
- SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion));
- SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion));
- WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
- WriteRegion.Right = WriteRegion.Left + SizeX - 1;
-
- /* Make sure WriteRegion is inside the screen buffer */
- ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
- if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion))
- {
- ConioUnlockScreenBuffer(Buff);
-
- /* It is okay to have a WriteRegion completely outside the screen buffer.
- No data is written then. */
- return STATUS_SUCCESS;
- }
-
- for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++)
- {
- CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X;
- Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y);
- for (X = WriteRegion.Left; X <= WriteRegion.Right; X++)
- {
- CHAR AsciiChar;
- if (WriteConsoleOutputRequest->Unicode)
- {
- ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar,
&CurCharInfo->Char.UnicodeChar);
- }
- else
- {
- AsciiChar = CurCharInfo->Char.AsciiChar;
- }
- *Ptr++ = AsciiChar;
- *Ptr++ = CurCharInfo->Attributes;
- CurCharInfo++;
- }
- }
-
- ConioDrawRegion(Console, &WriteRegion);
-
- ConioUnlockScreenBuffer(Buff);
-
- WriteConsoleOutputRequest->WriteRegion.Right = WriteRegion.Left + SizeX - 1;
- WriteConsoleOutputRequest->WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
- WriteConsoleOutputRequest->WriteRegion.Left = WriteRegion.Left;
- WriteConsoleOutputRequest->WriteRegion.Top = WriteRegion.Top;
return STATUS_SUCCESS;
}
@@ -1242,221 +1466,6 @@
return STATUS_SUCCESS;
}
-CSR_API(CsrReadConsoleOutputChar)
-{
- NTSTATUS Status;
- PCSRSS_READ_CONSOLE_OUTPUT_CHAR ReadConsoleOutputCharRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleOutputCharRequest;
- PCSRSS_CONSOLE Console;
- PCSRSS_SCREEN_BUFFER Buff;
- DWORD Xpos, Ypos;
- PCHAR ReadBuffer;
- DWORD i;
- ULONG CharSize;
- CHAR Char;
-
- DPRINT("CsrReadConsoleOutputChar\n");
-
- ReadBuffer = ReadConsoleOutputCharRequest->String;
-
- CharSize = (ReadConsoleOutputCharRequest->Unicode ? sizeof(WCHAR) :
sizeof(CHAR));
-
- Status = ConioLockScreenBuffer(CsrGetClientThread()->Process,
ReadConsoleOutputCharRequest->ConsoleHandle, &Buff, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- Console = Buff->Header.Console;
-
- Xpos = ReadConsoleOutputCharRequest->ReadCoord.X;
- Ypos = (ReadConsoleOutputCharRequest->ReadCoord.Y + Buff->VirtualY) %
Buff->MaxY;
-
- for (i = 0; i < ReadConsoleOutputCharRequest->NumCharsToRead; ++i)
- {
- Char = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)];
-
- if(ReadConsoleOutputCharRequest->Unicode)
- {
- ConsoleAnsiCharToUnicodeChar(Console, (WCHAR*)ReadBuffer, &Char);
- ReadBuffer += sizeof(WCHAR);
- }
- else
- *(ReadBuffer++) = Char;
-
- Xpos++;
-
- if (Xpos == Buff->MaxX)
- {
- Xpos = 0;
- Ypos++;
-
- if (Ypos == Buff->MaxY)
- {
- Ypos = 0;
- }
- }
- }
-
- *ReadBuffer = 0;
- ReadConsoleOutputCharRequest->EndCoord.X = Xpos;
- ReadConsoleOutputCharRequest->EndCoord.Y = (Ypos - Buff->VirtualY +
Buff->MaxY) % Buff->MaxY;
-
- ConioUnlockScreenBuffer(Buff);
-
- ReadConsoleOutputCharRequest->CharsRead = (DWORD)((ULONG_PTR)ReadBuffer -
(ULONG_PTR)ReadConsoleOutputCharRequest->String) / CharSize;
- if (ReadConsoleOutputCharRequest->CharsRead * CharSize +
CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE))
- {
- DPRINT1("Length won't fit in message\n");
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(CsrReadConsoleOutputAttrib)
-{
- NTSTATUS Status;
- PCSRSS_READ_CONSOLE_OUTPUT_ATTRIB ReadConsoleOutputAttribRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleOutputAttribRequest;
- PCSRSS_SCREEN_BUFFER Buff;
- DWORD Xpos, Ypos;
- PWORD ReadBuffer;
- DWORD i;
- DWORD CurrentLength;
-
- DPRINT("CsrReadConsoleOutputAttrib\n");
-
- ReadBuffer = ReadConsoleOutputAttribRequest->Attribute;
-
- Status = ConioLockScreenBuffer(CsrGetClientThread()->Process,
ReadConsoleOutputAttribRequest->ConsoleHandle, &Buff, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- Xpos = ReadConsoleOutputAttribRequest->ReadCoord.X;
- Ypos = (ReadConsoleOutputAttribRequest->ReadCoord.Y + Buff->VirtualY) %
Buff->MaxY;
-
- for (i = 0; i < ReadConsoleOutputAttribRequest->NumAttrsToRead; ++i)
- {
- *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX) + 1];
-
- ReadBuffer++;
- Xpos++;
-
- if (Xpos == Buff->MaxX)
- {
- Xpos = 0;
- Ypos++;
-
- if (Ypos == Buff->MaxY)
- {
- Ypos = 0;
- }
- }
- }
-
- *ReadBuffer = 0;
-
- ReadConsoleOutputAttribRequest->EndCoord.X = Xpos;
- ReadConsoleOutputAttribRequest->EndCoord.Y = (Ypos - Buff->VirtualY +
Buff->MaxY) % Buff->MaxY;
-
- ConioUnlockScreenBuffer(Buff);
-
- CurrentLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
- + ReadConsoleOutputAttribRequest->NumAttrsToRead * sizeof(WORD);
- if (CurrentLength > sizeof(CSR_API_MESSAGE))
- {
- DPRINT1("Length won't fit in message\n");
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- return STATUS_SUCCESS;
-}
-
-CSR_API(SrvReadConsoleOutput)
-{
- PCSRSS_READ_CONSOLE_OUTPUT ReadConsoleOutputRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleOutputRequest;
- PCSR_PROCESS ProcessData = CsrGetClientThread()->Process;
- PCHAR_INFO CharInfo;
- PCHAR_INFO CurCharInfo;
- PCSRSS_SCREEN_BUFFER Buff;
- DWORD SizeX, SizeY;
- NTSTATUS Status;
- COORD BufferSize;
- COORD BufferCoord;
- SMALL_RECT ReadRegion;
- SMALL_RECT ScreenRect;
- DWORD i;
- PBYTE Ptr;
- LONG X, Y;
- UINT CodePage;
-
- DPRINT("SrvReadConsoleOutput\n");
-
- Status = ConioLockScreenBuffer(ProcessData,
ReadConsoleOutputRequest->ConsoleHandle, &Buff, GENERIC_READ);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- CharInfo = ReadConsoleOutputRequest->CharInfo;
- ReadRegion = ReadConsoleOutputRequest->ReadRegion;
- BufferSize = ReadConsoleOutputRequest->BufferSize;
- BufferCoord = ReadConsoleOutputRequest->BufferCoord;
-
- /* FIXME: Is this correct? */
- CodePage = ProcessData->Console->OutputCodePage;
-
- if (!Win32CsrValidateBuffer(ProcessData, CharInfo,
- BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO)))
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_ACCESS_VIOLATION;
- }
-
- SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion));
- SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion));
- ReadRegion.Bottom = ReadRegion.Top + SizeY;
- ReadRegion.Right = ReadRegion.Left + SizeX;
-
- ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX);
- if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion))
- {
- ConioUnlockScreenBuffer(Buff);
- return STATUS_SUCCESS;
- }
-
- for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y)
- {
- CurCharInfo = CharInfo + (i * BufferSize.X);
-
- Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y);
- for (X = ReadRegion.Left; X < ReadRegion.Right; ++X)
- {
- if (ReadConsoleOutputRequest->Unicode)
- {
- MultiByteToWideChar(CodePage, 0,
- (PCHAR)Ptr++, 1,
- &CurCharInfo->Char.UnicodeChar, 1);
- }
- else
- {
- CurCharInfo->Char.AsciiChar = *Ptr++;
- }
- CurCharInfo->Attributes = *Ptr++;
- ++CurCharInfo;
- }
- }
-
- ConioUnlockScreenBuffer(Buff);
-
- ReadConsoleOutputRequest->ReadRegion.Right = ReadRegion.Left + SizeX - 1;
- ReadConsoleOutputRequest->ReadRegion.Bottom = ReadRegion.Top + SizeY - 1;
- ReadConsoleOutputRequest->ReadRegion.Left = ReadRegion.Left;
- ReadConsoleOutputRequest->ReadRegion.Top = ReadRegion.Top;
-
- return STATUS_SUCCESS;
-}
-
CSR_API(SrvSetConsoleScreenBufferSize)
{
NTSTATUS Status;