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/co... ============================================================================== --- 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/co... ============================================================================== --- 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;