/* INCLUDES ******************************************************************/
-#include "w32csr.h"
-
#define NDEBUG
+#include "w32csr.h"
#include <debug.h>
-/* FIXME: Is there a way to create real aliasses with gcc? [CSH] */
-#define ALIAS(Name, Target) typeof(Target) Name = Target
-
-/* Private user32 routines for CSRSS, not defined in any header file */
-extern VOID STDCALL PrivateCsrssRegisterPrimitive(VOID);
-extern VOID STDCALL PrivateCsrssAcquireOrReleaseInputOwnership(BOOL Release);
-
/* GLOBALS *******************************************************************/
#define ConioInitRect(Rect, Top, Left, Bottom, Right) \
#define ConioIsRectEmpty(Rect) \
(((Rect)->left > (Rect)->right) || ((Rect)->top > (Rect)->bottom))
-#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
+#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
-#define ConsoleAnsiCharToUnicodeChar(Console, sWChar, dChar) \
- MultiByteToWideChar((Console)->CodePage, 0, (dChar), 1, (sWChar), 1)
+#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
+ MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1)
+
+#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
+ WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
+
+#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \
+ MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
/* FUNCTIONS *****************************************************************/
-static NTSTATUS FASTCALL
+NTSTATUS FASTCALL
ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console)
{
- if (NULL == ProcessData->Console)
+ PCSRSS_CONSOLE ProcessConsole;
+
+ RtlEnterCriticalSection(&ProcessData->HandleTableLock);
+ ProcessConsole = ProcessData->Console;
+
+ if (!ProcessConsole)
{
*Console = NULL;
- return STATUS_SUCCESS;
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ return STATUS_INVALID_HANDLE;
}
- EnterCriticalSection(&(ProcessData->Console->Header.Lock));
- *Console = ProcessData->Console;
+ InterlockedIncrement(&ProcessConsole->Header.ReferenceCount);
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ EnterCriticalSection(&(ProcessConsole->Header.Lock));
+ *Console = ProcessConsole;
return STATUS_SUCCESS;
}
{
HANDLE Thread;
- DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->ProcessId);
+ DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->ProcessId);
if (ProcessData->CtrlDispatcher)
{
Thread = CreateRemoteThread(ProcessData->Process, NULL, 0,
(LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher,
- (PVOID) Event, 0, NULL);
+ UlongToPtr(Event), 0, NULL);
if (NULL == Thread)
{
DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
VOID FASTCALL
ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData)
{
- ConioConsoleCtrlEventTimeout(Event, ProcessData, INFINITE);
+ ConioConsoleCtrlEventTimeout(Event, ProcessData, 0);
}
-#define GET_CELL_BUFFER(b,o)\
-(b)->Buffer[(o)++]
-
-#define SET_CELL_BUFFER(b,o,c,a)\
-(b)->Buffer[(o)++]=(c),\
-(b)->Buffer[(o)++]=(a)
+PBYTE FASTCALL
+ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buff, ULONG X, ULONG Y)
+{
+ return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->MaxY) * Buff->MaxX + X)];
+}
static VOID FASTCALL
ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff)
{
- DWORD Offset = 2 * (Buff->CurrentY * Buff->MaxX);
+ PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CurrentY);
UINT Pos;
for (Pos = 0; Pos < Buff->MaxX; Pos++)
{
- /* Fill the cell: Offset is incremented by the macro */
- SET_CELL_BUFFER(Buff, Offset, ' ', Buff->DefaultAttrib);
+ /* Fill the cell */
+ *Ptr++ = ' ';
+ *Ptr++ = Buff->DefaultAttrib;
}
}
CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
PCSRSS_SCREEN_BUFFER Buffer)
{
+ DPRINT("CsrInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY);
+
Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC;
Buffer->Header.ReferenceCount = 0;
- Buffer->MaxX = Console->Size.X;
- Buffer->MaxY = Console->Size.Y;
Buffer->ShowX = 0;
Buffer->ShowY = 0;
- Buffer->Buffer = HeapAlloc(Win32CsrApiHeap, 0, Buffer->MaxX * Buffer->MaxY * 2);
+ Buffer->VirtualY = 0;
+ Buffer->Buffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, Buffer->MaxX * Buffer->MaxY * 2);
if (NULL == Buffer->Buffer)
{
return STATUS_INSUFFICIENT_RESOURCES;
{
ClearLineBuffer(Buffer);
}
- Buffer->CursorInfo.bVisible = TRUE;
- Buffer->CursorInfo.dwSize = 5;
Buffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
Buffer->CurrentX = 0;
Buffer->CurrentY = 0;
return STATUS_SUCCESS;
}
-static NTSTATUS STDCALL
+static NTSTATUS WINAPI
CsrInitConsole(PCSRSS_CONSOLE Console)
{
NTSTATUS Status;
Console->Title.MaximumLength = Console->Title.Length = 0;
Console->Title.Buffer = NULL;
+ //FIXME
RtlCreateUnicodeString(&Console->Title, L"Command Prompt");
Console->Header.ReferenceCount = 0;
Console->EarlyReturn = FALSE;
Console->ActiveBuffer = NULL;
InitializeListHead(&Console->InputEvents);
- InitializeListHead(&Console->ProcessList);
-
Console->CodePage = GetOEMCP();
Console->OutputCodePage = GetOEMCP();
}
Console->PrivateData = NULL;
InitializeCriticalSection(&Console->Header.Lock);
+
GuiMode = DtbgIsDesktopVisible();
+
+ /* allocate console screen buffer */
+ NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER));
+ if (NULL == NewBuffer)
+ {
+ RtlFreeUnicodeString(&Console->Title);
+ DeleteCriticalSection(&Console->Header.Lock);
+ CloseHandle(Console->ActiveEvent);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ /* init screen buffer with defaults */
+ NewBuffer->CursorInfo.bVisible = TRUE;
+ NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
+ /* make console active, and insert into console list */
+ Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer;
+
if (! GuiMode)
{
Status = TuiInitConsole(Console);
Status = GuiInitConsole(Console);
if (! NT_SUCCESS(Status))
{
+ HeapFree(Win32CsrApiHeap,0, NewBuffer);
RtlFreeUnicodeString(&Console->Title);
- DeleteCriticalSection(&Console->Header.Lock);
+ DeleteCriticalSection(&Console->Header.Lock);
CloseHandle(Console->ActiveEvent);
+ DPRINT1("GuiInitConsole: failed\n");
return Status;
}
}
- NewBuffer = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_SCREEN_BUFFER));
- if (NULL == NewBuffer)
- {
- ConioCleanupConsole(Console);
- RtlFreeUnicodeString(&Console->Title);
- DeleteCriticalSection(&Console->Header.Lock);
- CloseHandle(Console->ActiveEvent);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
Status = CsrInitConsoleScreenBuffer(Console, NewBuffer);
if (! NT_SUCCESS(Status))
{
DeleteCriticalSection(&Console->Header.Lock);
CloseHandle(Console->ActiveEvent);
HeapFree(Win32CsrApiHeap, 0, NewBuffer);
+ DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
return Status;
}
- Console->ActiveBuffer = NewBuffer;
+
/* add a reference count because the buffer is tied to the console */
InterlockedIncrement(&Console->ActiveBuffer->Header.ReferenceCount);
- /* make console active, and insert into console list */
+
/* copy buffer contents to screen */
ConioDrawConsole(Console);
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- if (ProcessData == NULL)
- {
- DPRINT1("No process data\n");
- return Request->Status = STATUS_INVALID_PARAMETER;
- }
-
+ RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (ProcessData->Console)
{
DPRINT1("Process already has a console\n");
- Request->Status = STATUS_INVALID_PARAMETER;
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_PARAMETER;
}
- /* Assume success */
- Request->Status = STATUS_SUCCESS;
-
/* If we don't need a console, then get out of here */
if (!Request->Data.AllocConsoleRequest.ConsoleNeeded)
{
DPRINT("No console needed\n");
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
{
/* Allocate a console structure */
NewConsole = TRUE;
- Console = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_CONSOLE));
+ Console = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_CONSOLE));
if (NULL == Console)
{
DPRINT1("Not enough memory for console\n");
- Request->Status = STATUS_NO_MEMORY;
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_NO_MEMORY;
}
-
+ /* initialize list head */
+ InitializeListHead(&Console->ProcessList);
+ /* insert process data required for GUI initialization */
+ InsertHeadList(&Console->ProcessList, &ProcessData->ProcessEntry);
/* Initialize the Console */
- Request->Status = CsrInitConsole(Console);
- if (!NT_SUCCESS(Request->Status))
+ Status = CsrInitConsole(Console);
+ if (!NT_SUCCESS(Status))
{
DPRINT1("Console init failed\n");
HeapFree(Win32CsrApiHeap, 0, Console);
- return Request->Status;
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ return Status;
}
}
else
if (NewConsole || !ProcessData->bInheritHandles)
{
/* Insert the Objects */
- Status = Win32CsrInsertObject(ProcessData,
- &Request->Data.AllocConsoleRequest.InputHandle,
- &Console->Header);
+ Status = Win32CsrInsertObject(ProcessData,
+ &Request->Data.AllocConsoleRequest.InputHandle,
+ &Console->Header,
+ GENERIC_READ | GENERIC_WRITE,
+ TRUE);
if (! NT_SUCCESS(Status))
{
DPRINT1("Failed to insert object\n");
ConioDeleteConsole((Object_t *) Console);
ProcessData->Console = 0;
- return Request->Status = Status;
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ return Status;
}
-
- Status = Win32CsrInsertObject(ProcessData,
- &Request->Data.AllocConsoleRequest.OutputHandle,
- &Console->ActiveBuffer->Header);
+
+ Status = Win32CsrInsertObject(ProcessData,
+ &Request->Data.AllocConsoleRequest.OutputHandle,
+ &Console->ActiveBuffer->Header,
+ GENERIC_READ | GENERIC_WRITE,
+ TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert object\n");
ConioDeleteConsole((Object_t *) Console);
- Win32CsrReleaseObject(ProcessData,
+ Win32CsrReleaseObject(ProcessData,
Request->Data.AllocConsoleRequest.InputHandle);
ProcessData->Console = 0;
- return Request->Status = Status;
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ return Status;
}
}
/* Duplicate the Event */
- if (!DuplicateHandle(GetCurrentProcess(),
+ if (!DuplicateHandle(GetCurrentProcess(),
ProcessData->Console->ActiveEvent,
- ProcessData->Process,
- &ProcessData->ConsoleEvent,
- EVENT_ALL_ACCESS,
- FALSE,
+ ProcessData->Process,
+ &ProcessData->ConsoleEvent,
+ EVENT_ALL_ACCESS,
+ FALSE,
0))
{
DPRINT1("DuplicateHandle() failed: %d\n", GetLastError);
Request->Data.AllocConsoleRequest.InputHandle);
}
ProcessData->Console = 0;
- return Request->Status = Status;
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ return Status;
}
/* Set the Ctrl Dispatcher */
ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher;
DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
- /* Insert into the list */
-////////////////////////////
- InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry);
-///////////////////////////
+ if (!NewConsole)
+ {
+ /* Insert into the list if it has not been added */
+ InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry);
+ }
+
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
CSR_API(CsrFreeConsole)
{
- PCSRSS_CONSOLE Console;
-
- DPRINT("CsrFreeConsole\n");
-
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- if (ProcessData == NULL || ProcessData->Console == NULL)
- {
- return Request->Status = STATUS_INVALID_PARAMETER;
- }
-
- Console = ProcessData->Console;
- ProcessData->Console = NULL;
- if (0 == InterlockedDecrement(&Console->Header.ReferenceCount))
- {
- ConioDeleteConsole((Object_t *) Console);
- }
-
- return STATUS_SUCCESS;
+ return Win32CsrReleaseConsole(ProcessData);
}
static VOID FASTCALL
ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines)
{
- /* slide the viewable screen */
- if (((Buff->CurrentY - Buff->ShowY + Buff->MaxY) % Buff->MaxY) == (ULONG)Buff->MaxY - 1)
+ /* If we hit bottom, slide the viewable screen */
+ if (++Buff->CurrentY == Buff->MaxY)
{
- if (++Buff->ShowY == Buff->MaxY)
+ Buff->CurrentY--;
+ if (++Buff->VirtualY == Buff->MaxY)
{
- Buff->ShowY = 0;
+ Buff->VirtualY = 0;
}
(*ScrolledLines)++;
- }
- if (++Buff->CurrentY == Buff->MaxY)
- {
- Buff->CurrentY = 0;
- }
- ClearLineBuffer(Buff);
- UpdateRect->left = 0;
- UpdateRect->right = Buff->MaxX - 1;
- if (UpdateRect->top == (LONG)Buff->CurrentY)
- {
- if (++UpdateRect->top == Buff->MaxY)
+ ClearLineBuffer(Buff);
+ if (UpdateRect->top != 0)
{
- UpdateRect->top = 0;
+ UpdateRect->top--;
}
}
+ UpdateRect->left = 0;
+ UpdateRect->right = Buff->MaxX - 1;
UpdateRect->bottom = Buff->CurrentY;
}
CHAR *Buffer, DWORD Length, BOOL Attrib)
{
UINT i;
- DWORD Offset;
+ PBYTE Ptr;
RECT UpdateRect;
LONG CursorStartX, CursorStartY;
UINT ScrolledLines;
- ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &CursorStartX, &CursorStartY);
+ CursorStartX = Buff->CurrentX;
+ CursorStartY = Buff->CurrentY;
UpdateRect.left = Buff->MaxX;
UpdateRect.top = Buff->CurrentY;
UpdateRect.right = -1;
else if (Buffer[i] == '\b')
{
/* Only handle BS if we're not on the first pos of the first line */
- if (0 != Buff->CurrentX || Buff->ShowY != Buff->CurrentY)
+ if (0 != Buff->CurrentX || 0 != Buff->CurrentY)
{
if (0 == Buff->CurrentX)
{
/* slide virtual position up */
Buff->CurrentX = Buff->MaxX - 1;
- if (0 == Buff->CurrentY)
- {
- Buff->CurrentY = Buff->MaxY;
- }
- else
- {
- Buff->CurrentY--;
- }
- if ((0 == UpdateRect.top && UpdateRect.bottom < (LONG)Buff->CurrentY)
- || (0 != UpdateRect.top && (LONG)Buff->CurrentY < UpdateRect.top))
- {
- UpdateRect.top = Buff->CurrentY;
- }
+ Buff->CurrentY--;
+ UpdateRect.top = min(UpdateRect.top, (LONG)Buff->CurrentY);
}
else
{
- Buff->CurrentX--;
+ Buff->CurrentX--;
}
- Offset = 2 * ((Buff->CurrentY * Buff->MaxX) + Buff->CurrentX);
- SET_CELL_BUFFER(Buff, Offset, ' ', Buff->DefaultAttrib);
+ Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
+ Ptr[0] = ' ';
+ Ptr[1] = Buff->DefaultAttrib;
UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX);
UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
}
{
EndX = Buff->MaxX;
}
- Offset = 2 * (((Buff->CurrentY * Buff->MaxX)) + Buff->CurrentX);
+ Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
while (Buff->CurrentX < EndX)
{
- Buff->Buffer[Offset] = ' ';
- Offset += 2;
+ *Ptr++ = ' ';
+ *Ptr++ = Buff->DefaultAttrib;
Buff->CurrentX++;
}
UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX - 1);
}
UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX);
UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
- Offset = 2 * (((Buff->CurrentY * Buff->MaxX)) + Buff->CurrentX);
- Buff->Buffer[Offset++] = Buffer[i];
+ Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
+ Ptr[0] = Buffer[i];
if (Attrib)
{
- Buff->Buffer[Offset] = Buff->DefaultAttrib;
+ Ptr[1] = Buff->DefaultAttrib;
}
Buff->CurrentX++;
if (Buff->CurrentX == Buff->MaxX)
}
}
- ConioPhysicalToLogical(Buff, UpdateRect.left, UpdateRect.top, &(UpdateRect.left),
- &(UpdateRect.top));
- ConioPhysicalToLogical(Buff, UpdateRect.right, UpdateRect.bottom, &(UpdateRect.right),
- &(UpdateRect.bottom));
- if (! ConioIsRectEmpty(&UpdateRect) && NULL != Console && Buff == Console->ActiveBuffer)
+ if (! ConioIsRectEmpty(&UpdateRect) && Buff == Console->ActiveBuffer)
{
ConioWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, ScrolledLines,
Buffer, Length);
Buffer = Request->Data.ReadConsoleRequest.Buffer;
UnicodeBuffer = (PWCHAR)Buffer;
Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle,
- &Console);
+ &Console, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent;
for (i = 0; i < nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++)
CurrentEntry = RemoveHeadList(&Console->InputEvents);
if (IsListEmpty(&Console->InputEvents))
{
- CHECKPOINT;
ResetEvent(Console->ActiveEvent);
}
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
&& Input->InputEvent.Event.KeyEvent.bKeyDown
&& Input->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\0')
{
- /* backspace handling */
- if ('\b' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar)
+ /*
+ * backspace handling - if we are in charge of echoing it then we handle it here
+ * otherwise we treat it like a normal char.
+ */
+ if ('\b' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar && 0
+ != (Console->Mode & ENABLE_ECHO_INPUT))
{
/* echo if it has not already been done, and either we or the client has chars to be deleted */
if (! Input->Echoed
i -= 2; /* if we already have something to return, just back it up by 2 */
}
else
- {
- /* otherwise, we will treat the backspace just like any other char and let the client decide what to do */
+ { /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */
Console->WaitingChars--;
ConioUnlockConsole(Console);
HeapFree(Win32CsrApiHeap, 0, Input);
- Request->Data.ReadConsoleRequest.NrCharactersRead++;
- Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar;
- return Request->Status;
+ Request->Data.ReadConsoleRequest.NrCharactersRead = 0;
+ return STATUS_NOTIFY_CLEANUP;
+
}
Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--;
Input->Echoed = TRUE; /* mark as echoed so we don't echo it below */
else
{
if(Request->Data.ReadConsoleRequest.Unicode)
- UnicodeBuffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar; /* FIXME */
+ ConsoleInputAnsiCharToUnicodeChar(Console, &UnicodeBuffer[i], &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar);
else
Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar;
}
Request->Data.ReadConsoleRequest.NrCharactersRead = i;
if (0 == i)
{
- Request->Status = STATUS_PENDING; /* we didn't read anything */
+ Status = STATUS_PENDING; /* we didn't read anything */
}
else if (0 != (Console->Mode & ENABLE_LINE_INPUT))
{
if (0 == Console->WaitingLines ||
(Request->Data.ReadConsoleRequest.Unicode ? (L'\n' != UnicodeBuffer[i - 1]) : ('\n' != Buffer[i - 1])))
{
- Request->Status = STATUS_PENDING; /* line buffered, didn't get a complete line */
+ Status = STATUS_PENDING; /* line buffered, didn't get a complete line */
}
else
{
Console->WaitingLines--;
- Request->Status = STATUS_SUCCESS; /* line buffered, did get a complete line */
+ Status = STATUS_SUCCESS; /* line buffered, did get a complete line */
}
}
else
{
- Request->Status = STATUS_SUCCESS; /* not line buffered, did read something */
+ Status = STATUS_SUCCESS; /* not line buffered, did read something */
}
- if (Request->Status == STATUS_PENDING)
+ if (Status == STATUS_PENDING)
{
Console->EchoCount = nNumberOfCharsToRead - i;
}
Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
}
- return Request->Status;
+ return Status;
}
-VOID FASTCALL
-ConioPhysicalToLogical(PCSRSS_SCREEN_BUFFER Buff,
- ULONG PhysicalX,
- ULONG PhysicalY,
- LONG *LogicalX,
- LONG *LogicalY)
-{
- *LogicalX = PhysicalX;
- if (PhysicalY < Buff->ShowY)
- {
- *LogicalY = Buff->MaxY - Buff->ShowY + PhysicalY;
- }
- else
- {
- *LogicalY = PhysicalY - Buff->ShowY;
- }
-}
-
-inline BOOLEAN ConioIsEqualRect(
- RECT *Rect1,
- RECT *Rect2)
-{
- return ((Rect1->left == Rect2->left) && (Rect1->right == Rect2->right) &&
- (Rect1->top == Rect2->top) && (Rect1->bottom == Rect2->bottom));
-}
-
-inline BOOLEAN ConioGetIntersection(
+__inline BOOLEAN ConioGetIntersection(
RECT *Intersection,
RECT *Rect1,
RECT *Rect2)
return TRUE;
}
-inline BOOLEAN ConioGetUnion(
+__inline BOOLEAN ConioGetUnion(
RECT *Union,
RECT *Rect1,
RECT *Rect2)
return TRUE;
}
-inline BOOLEAN ConioSubtractRect(
- RECT *Subtraction,
- RECT *Rect1,
- RECT *Rect2)
+/* 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,
+ RECT *SrcRegion,
+ RECT *DstRegion,
+ RECT *ClipRegion,
+ WORD Fill)
{
- RECT tmp;
-
- if (ConioIsRectEmpty(Rect1))
- {
- ConioInitRect(Subtraction, 0, -1, 0, -1);
- return FALSE;
- }
- *Subtraction = *Rect1;
- if (ConioGetIntersection(&tmp, Rect1, Rect2))
- {
- if (ConioIsEqualRect(&tmp, Subtraction))
- {
- ConioInitRect(Subtraction, 0, -1, 0, -1);
- return FALSE;
- }
- if ((tmp.top == Subtraction->top) && (tmp.bottom == Subtraction->bottom))
- {
- if (tmp.left == Subtraction->left)
+ int Width = ConioRectWidth(SrcRegion);
+ int Height = ConioRectHeight(SrcRegion);
+ int SX, SY;
+ int DX, DY;
+ int XDelta, YDelta;
+ int i, j;
+
+ SY = SrcRegion->top;
+ DY = DstRegion->top;
+ YDelta = 1;
+ if (SY < DY)
+ {
+ /* Moving down: work from bottom up */
+ SY = SrcRegion->bottom;
+ DY = DstRegion->bottom;
+ YDelta = -1;
+ }
+ for (i = 0; i < Height; i++)
+ {
+ PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY);
+ PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY);
+
+ SX = SrcRegion->left;
+ DX = DstRegion->left;
+ XDelta = 1;
+ if (SX < DX)
+ {
+ /* Moving right: work from right to left */
+ SX = SrcRegion->right;
+ DX = DstRegion->right;
+ XDelta = -1;
+ }
+ for (j = 0; j < Width; j++)
+ {
+ WORD Cell = SRow[SX];
+ if (SX >= ClipRegion->left && SX <= ClipRegion->right
+ && SY >= ClipRegion->top && SY <= ClipRegion->bottom)
{
- Subtraction->left = tmp.right;
+ SRow[SX] = Fill;
}
- else if (tmp.right == Subtraction->right)
+ if (DX >= ClipRegion->left && DX <= ClipRegion->right
+ && DY >= ClipRegion->top && DY <= ClipRegion->bottom)
{
- Subtraction->right = tmp.left;
- }
- }
- else if ((tmp.left == Subtraction->left) && (tmp.right == Subtraction->right))
- {
- if (tmp.top == Subtraction->top)
- {
- Subtraction->top = tmp.bottom;
- }
- else if (tmp.bottom == Subtraction->bottom)
- {
- Subtraction->bottom = tmp.top;
+ DRow[DX] = Cell;
}
+ SX += XDelta;
+ DX += XDelta;
}
- }
-
- return TRUE;
-}
-
-static VOID FASTCALL
-ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
- RECT *SrcRegion,
- RECT *DstRegion)
-{
- SHORT SrcY, DstY;
- DWORD SrcOffset;
- DWORD DstOffset;
- DWORD BytesPerLine;
- LONG i;
-
- DstY = DstRegion->top;
- BytesPerLine = ConioRectWidth(DstRegion) * 2;
-
- SrcY = (SrcRegion->top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
- DstY = (DstRegion->top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
- SrcOffset = (SrcY * ScreenBuffer->MaxX + SrcRegion->left + ScreenBuffer->ShowX) * 2;
- DstOffset = (DstY * ScreenBuffer->MaxX + DstRegion->left + ScreenBuffer->ShowX) * 2;
-
- for (i = SrcRegion->top; i <= SrcRegion->bottom; i++)
- {
- RtlCopyMemory(
- &ScreenBuffer->Buffer[DstOffset],
- &ScreenBuffer->Buffer[SrcOffset],
- BytesPerLine);
-
- if (++DstY == ScreenBuffer->MaxY)
- {
- DstY = 0;
- DstOffset = (DstRegion->left + ScreenBuffer->ShowX) * 2;
- }
- else
- {
- DstOffset += ScreenBuffer->MaxX * 2;
- }
-
- if (++SrcY == ScreenBuffer->MaxY)
- {
- SrcY = 0;
- SrcOffset = (SrcRegion->left + ScreenBuffer->ShowX) * 2;
- }
- else
- {
- SrcOffset += ScreenBuffer->MaxX * 2;
- }
- }
-}
-
-static VOID FASTCALL
-ConioFillRegion(PCSRSS_CONSOLE Console,
- PCSRSS_SCREEN_BUFFER ScreenBuffer,
- RECT *Region,
- CHAR_INFO *CharInfo,
- BOOL bUnicode)
-{
- SHORT X, Y;
- DWORD Offset;
- DWORD Delta;
- LONG i;
- CHAR Char;
-
- if(bUnicode)
- ConsoleUnicodeCharToAnsiChar(Console, &Char, &CharInfo->Char.UnicodeChar);
- else
- Char = CharInfo->Char.AsciiChar;
-
- Y = (Region->top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
- Offset = (Y * ScreenBuffer->MaxX + Region->left + ScreenBuffer->ShowX) * 2;
- Delta = (ScreenBuffer->MaxX - ConioRectWidth(Region)) * 2;
-
- for (i = Region->top; i <= Region->bottom; i++)
- {
- for (X = Region->left; X <= Region->right; X++)
- {
- SET_CELL_BUFFER(ScreenBuffer, Offset, Char, CharInfo->Attributes);
- }
- if (++Y == ScreenBuffer->MaxY)
- {
- Y = 0;
- Offset = (Region->left + ScreenBuffer->ShowX) * 2;
- }
- else
- {
- Offset += Delta;
- }
+ SY += YDelta;
+ DY += YDelta;
}
}
{
WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
- ConsoleUnicodeCharToAnsiChar(Console,
- &InputEvent->Event.KeyEvent.uChar.AsciiChar,
- &UnicodeChar);
+ ConsoleInputUnicodeCharToAnsiChar(Console,
+ &InputEvent->Event.KeyEvent.uChar.AsciiChar,
+ &UnicodeChar);
}
}
DPRINT("CsrWriteConsole\n");
if (Request->Header.u1.s1.TotalLength
- < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE)
+ < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE)
+ (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize))
{
DPRINT1("Invalid request size\n");
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- return Request->Status = STATUS_INVALID_PARAMETER;
+ return STATUS_INVALID_PARAMETER;
}
Status = ConioConsoleFromProcessData(ProcessData, &Console);
-
+
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
-
+
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
if(Request->Data.WriteConsoleRequest.Unicode)
{
- Length = WideCharToMultiByte(Console->CodePage, 0,
- (PWCHAR)Request->Data.WriteConsoleRequest.Buffer,
- Request->Data.WriteConsoleRequest.NrCharactersToWrite,
+ Length = WideCharToMultiByte(Console->OutputCodePage, 0,
+ (PWCHAR)Request->Data.WriteConsoleRequest.Buffer,
+ Request->Data.WriteConsoleRequest.NrCharactersToWrite,
NULL, 0, NULL, NULL);
Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length);
if (Buffer)
{
- WideCharToMultiByte(Console->CodePage, 0,
- (PWCHAR)Request->Data.WriteConsoleRequest.Buffer,
- Request->Data.WriteConsoleRequest.NrCharactersToWrite,
+ WideCharToMultiByte(Console->OutputCodePage, 0,
+ (PWCHAR)Request->Data.WriteConsoleRequest.Buffer,
+ Request->Data.WriteConsoleRequest.NrCharactersToWrite,
Buffer, Length, NULL, NULL);
}
else
{
Buffer = (PCHAR)Request->Data.WriteConsoleRequest.Buffer;
}
-
+
if (Buffer)
{
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff);
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (NT_SUCCESS(Status))
{
- Request->Status = ConioWriteConsole(Console, Buff, Buffer,
- Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
+ Status = ConioWriteConsole(Console, Buff, Buffer,
+ Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
if (NT_SUCCESS(Status))
{
Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite;
RtlFreeHeap(GetProcessHeap(), 0, Buffer);
}
}
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
+ ConioUnlockConsole(Console);
Request->Data.WriteConsoleRequest.NrCharactersWritten = Written;
- return Request->Status = Status;
+ return Status;
}
-VOID STDCALL
+VOID WINAPI
ConioDeleteScreenBuffer(Object_t *Object)
{
PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object;
}
-VOID STDCALL
+VOID WINAPI
ConioDeleteConsole(Object_t *Object)
{
PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object;
HeapFree(Win32CsrApiHeap, 0, Event);
}
+ ConioCleanupConsole(Console);
if (0 == InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
{
ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
}
Console->ActiveBuffer = NULL;
- ConioCleanupConsole(Console);
CloseHandle(Console->ActiveEvent);
DeleteCriticalSection(&Console->Header.Lock);
RtlFreeUnicodeString(&Console->Title);
+ IntDeleteAllAliases(Console->Aliases);
HeapFree(Win32CsrApiHeap, 0, Console);
}
-VOID STDCALL
+VOID WINAPI
CsrInitConsoleSupport(VOID)
{
DPRINT("CSR: CsrInitConsoleSupport()\n");
ConsoleInput *KeyEventRecord)
{
BOOL updown;
- BOOL bClientWake = FALSE;
ConsoleInput *TempInput;
- /* process Ctrl-C and Ctrl-Break */
- if (Console->Mode & ENABLE_PROCESSED_INPUT &&
- KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown &&
- ((KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) ||
- (KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == 'C')) &&
- (KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))
- {
- PCSRSS_PROCESS_DATA current;
- PLIST_ENTRY current_entry;
- DPRINT1("Console_Api Ctrl-C\n");
- current_entry = Console->ProcessList.Flink;
- while (current_entry != &Console->ProcessList)
- {
- current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
- current_entry = current_entry->Flink;
- ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current);
- }
- HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
- return;
- }
-
- if (0 != (KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState
- & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
- && (VK_UP == KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode
- || VK_DOWN == KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode))
- {
- if (KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown)
- {
- /* scroll up or down */
- if (NULL == Console)
- {
- DPRINT1("No Active Console!\n");
- HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
- return;
- }
- if (VK_UP == KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode)
- {
- /* only scroll up if there is room to scroll up into */
- if (Console->ActiveBuffer->ShowY != ((Console->ActiveBuffer->CurrentY + 1) %
- Console->ActiveBuffer->MaxY))
- {
- Console->ActiveBuffer->ShowY = (Console->ActiveBuffer->ShowY +
- Console->ActiveBuffer->MaxY - 1) %
- Console->ActiveBuffer->MaxY;
- }
- }
- else if (Console->ActiveBuffer->ShowY != Console->ActiveBuffer->CurrentY)
- /* only scroll down if there is room to scroll down into */
- {
- if (Console->ActiveBuffer->ShowY % Console->ActiveBuffer->MaxY !=
- Console->ActiveBuffer->CurrentY)
- {
- if (((Console->ActiveBuffer->CurrentY + 1) % Console->ActiveBuffer->MaxY) !=
- (Console->ActiveBuffer->ShowY + Console->ActiveBuffer->MaxY) %
- Console->ActiveBuffer->MaxY)
- {
- Console->ActiveBuffer->ShowY = (Console->ActiveBuffer->ShowY + 1) %
- Console->ActiveBuffer->MaxY;
- }
- }
- }
- ConioDrawConsole(Console);
- }
- HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
- return;
- }
- if (NULL == Console)
- {
- DPRINT1("No Active Console!\n");
- HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
- return;
- }
-
if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)))
{
switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar)
{
Console->WaitingLines++;
}
- bClientWake = TRUE;
- SetEvent(Console->ActiveEvent);
}
KeyEventRecord->Echoed = FALSE;
if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT))
{
/* walk the input queue looking for a char to backspace */
for (TempInput = (ConsoleInput *) Console->InputEvents.Blink;
- TempInput != (ConsoleInput *) &Console->InputEvents
+ TempInput != (ConsoleInput *) &Console->InputEvents
&& (KEY_EVENT == TempInput->InputEvent.EventType
|| ! TempInput->InputEvent.Event.KeyEvent.bKeyDown
|| '\b' == TempInput->InputEvent.Event.KeyEvent.uChar.AsciiChar);
- TempInput = (ConsoleInput *) TempInput->ListEntry.Blink)
+ TempInput = (ConsoleInput *) TempInput->ListEntry.Blink)
{
/* NOP */;
}
/* if we found one, delete it, otherwise, wake the client */
if (TempInput != (ConsoleInput *) &Console->InputEvents)
- {
- /* delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue */
- RemoveEntryList(&TempInput->ListEntry);
- if (TempInput->Echoed)
+ {
+ /* delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue */
+ RemoveEntryList(&TempInput->ListEntry);
+ if (TempInput->Echoed)
{
ConioWriteConsole(Console, Console->ActiveBuffer,
&KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar,
1, TRUE);
}
HeapFree(Win32CsrApiHeap, 0, TempInput);
- RemoveEntryList(&KeyEventRecord->ListEntry);
- HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
- Console->WaitingChars -= 2;
- }
- else
- {
- SetEvent(Console->ActiveEvent);
+ RemoveEntryList(&KeyEventRecord->ListEntry);
+ HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
+ Console->WaitingChars -= 2;
+ return;
}
}
else
}
/* Console->WaitingChars++; */
- if (bClientWake || 0 == (Console->Mode & ENABLE_LINE_INPUT))
- {
- SetEvent(Console->ActiveEvent);
- }
+ SetEvent(Console->ActiveEvent);
}
static DWORD FASTCALL
return ssOut;
}
-VOID STDCALL
+VOID WINAPI
ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
{
static BYTE KeyState[256] = { 0 };
if (NULL == Console)
{
+ DPRINT1("No Active Console!\n");
return;
}
LastVirtualKey = msg->wParam;
DPRINT ("csrss: %s %s %s %s %02x %02x '%c' %04x\n",
- Down ? "down" : "up ",
- (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
- "char" : "key ",
- ConInRec->Fake ? "fake" : "real",
- ConInRec->NotChar ? "notc" : "char",
- VirtualScanCode,
- VirtualKeyCode,
- (AsciiChar >= ' ') ? AsciiChar : '.',
- ShiftState);
-
- if (! ConInRec->Fake || ! ConInRec->NotChar)
+ Down ? "down" : "up ",
+ (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
+ "char" : "key ",
+ ConInRec->Fake ? "fake" : "real",
+ ConInRec->NotChar ? "notc" : "char",
+ VirtualScanCode,
+ VirtualKeyCode,
+ (AsciiChar >= ' ') ? AsciiChar : '.',
+ ShiftState);
+
+ if (ConInRec->Fake && ConInRec->NotChar)
{
- /* FIXME - convert to ascii */
- ConioProcessChar(Console, ConInRec);
+ HeapFree(Win32CsrApiHeap, 0, ConInRec);
+ return;
}
- else
+
+ /* process Ctrl-C and Ctrl-Break */
+ if (Console->Mode & ENABLE_PROCESSED_INPUT &&
+ er.Event.KeyEvent.bKeyDown &&
+ ((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) ||
+ (er.Event.KeyEvent.wVirtualKeyCode == 'C')) &&
+ (er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))
{
+ PCSRSS_PROCESS_DATA current;
+ PLIST_ENTRY current_entry;
+ DPRINT1("Console_Api Ctrl-C\n");
+ current_entry = Console->ProcessList.Flink;
+ while (current_entry != &Console->ProcessList)
+ {
+ current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
+ current_entry = current_entry->Flink;
+ ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current);
+ }
HeapFree(Win32CsrApiHeap, 0, ConInRec);
+ return;
}
-}
-DWORD STDCALL
-Console_Api (PVOID unused)
-{
- /* keep reading events from the keyboard and stuffing them into the current
- console's input queue */
- MSG msg;
-
- /* This call establishes our message queue */
- PeekMessageW(&msg, 0, 0, 0, PM_NOREMOVE);
- /* This call registers our message queue */
- PrivateCsrssRegisterPrimitive();
- /* This call turns on the input system in win32k */
- PrivateCsrssAcquireOrReleaseInputOwnership(FALSE);
-
- while (TRUE)
+ if (0 != (er.Event.KeyEvent.dwControlKeyState
+ & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
+ && (VK_UP == er.Event.KeyEvent.wVirtualKeyCode
+ || VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode))
{
- GetMessageW(&msg, 0, 0, 0);
- TranslateMessage(&msg);
-
- if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR ||
- msg.message == WM_KEYDOWN || msg.message == WM_KEYUP ||
- msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP)
+ if (er.Event.KeyEvent.bKeyDown)
{
- ConioProcessKey(&msg, TuiGetFocusConsole(), TRUE);
+ /* scroll up or down */
+ if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode)
+ {
+ /* only scroll up if there is room to scroll up into */
+ if (Console->ActiveBuffer->CurrentY != Console->ActiveBuffer->MaxY - 1)
+ {
+ Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
+ Console->ActiveBuffer->MaxY - 1) %
+ Console->ActiveBuffer->MaxY;
+ Console->ActiveBuffer->CurrentY++;
+ }
+ }
+ else
+ {
+ /* only scroll down if there is room to scroll down into */
+ if (Console->ActiveBuffer->CurrentY != 0)
+ {
+ Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
+ Console->ActiveBuffer->MaxY;
+ Console->ActiveBuffer->CurrentY--;
+ }
+ }
+ ConioDrawConsole(Console);
}
+ HeapFree(Win32CsrApiHeap, 0, ConInRec);
+ return;
}
-
- PrivateCsrssAcquireOrReleaseInputOwnership(TRUE);
- return 0;
+ /* FIXME - convert to ascii */
+ ConioProcessChar(Console, ConInRec);
}
CSR_API(CsrGetScreenBufferInfo)
{
NTSTATUS Status;
+ PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff;
PCONSOLE_SCREEN_BUFFER_INFO pInfo;
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff);
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ ConioUnlockConsole(Console);
+ return Status;
}
pInfo = &Request->Data.ScreenBufferInfoRequest.Info;
pInfo->dwSize.X = Buff->MaxX;
pInfo->dwSize.Y = Buff->MaxY;
- pInfo->dwCursorPosition.X = Buff->CurrentX - Buff->ShowX;
- pInfo->dwCursorPosition.Y = (Buff->CurrentY + Buff->MaxY - Buff->ShowY) % Buff->MaxY;
+ pInfo->dwCursorPosition.X = Buff->CurrentX;
+ pInfo->dwCursorPosition.Y = Buff->CurrentY;
pInfo->wAttributes = Buff->DefaultAttrib;
- pInfo->srWindow.Left = 0;
- pInfo->srWindow.Right = Buff->MaxX - 1;
- pInfo->srWindow.Top = 0;
- pInfo->srWindow.Bottom = Buff->MaxY - 1;
+ 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);
+ ConioUnlockConsole(Console);
- Request->Status = STATUS_SUCCESS;
-
- return Request->Status;
+ return STATUS_SUCCESS;
}
CSR_API(CsrSetCursor)
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff);
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
- return Request->Status = Status;
+ ConioUnlockConsole(Console);
+ return Status;
}
NewCursorX = Request->Data.SetCursorRequest.Position.X;
NewCursorY < 0 || NewCursorY >= Buff->MaxY)
{
ConioUnlockScreenBuffer(Buff);
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
- return Request->Status = STATUS_INVALID_PARAMETER;
+ ConioUnlockConsole(Console);
+ return STATUS_INVALID_PARAMETER;
}
- ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &OldCursorX, &OldCursorY);
- Buff->CurrentX = NewCursorX + Buff->ShowX;
- Buff->CurrentY = (NewCursorY + Buff->ShowY) % Buff->MaxY;
- if (NULL != Console && Buff == Console->ActiveBuffer)
+ OldCursorX = Buff->CurrentX;
+ OldCursorY = Buff->CurrentY;
+ Buff->CurrentX = NewCursorX;
+ Buff->CurrentY = NewCursorY;
+ if (Buff == Console->ActiveBuffer)
{
if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
{
ConioUnlockScreenBuffer(Buff);
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
- return Request->Status = STATUS_UNSUCCESSFUL;
+ ConioUnlockConsole(Console);
+ return STATUS_UNSUCCESSFUL;
}
}
- ConioUnlockScreenBuffer(Buff);
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
-
- return Request->Status = STATUS_SUCCESS;
+ ConioUnlockScreenBuffer(Buff);
+ ConioUnlockConsole(Console);
+
+ return STATUS_SUCCESS;
}
-static FASTCALL VOID
+static VOID FASTCALL
ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, COORD *Start, UINT Length)
{
if (Buff->MaxX <= Start->X + Length)
CharSize = (Request->Data.WriteConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
if (Request->Header.u1.s1.TotalLength
- < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
+ < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
+ (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize))
{
DPRINT1("Invalid request size\n");
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- return Request->Status = STATUS_INVALID_PARAMETER;
+ return STATUS_INVALID_PARAMETER;
}
Status = ConioConsoleFromProcessData(ProcessData, &Console);
{
if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
{
- Length = WideCharToMultiByte(Console->CodePage, 0,
- (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String,
- Request->Data.WriteConsoleOutputCharRequest.Length,
+ Length = WideCharToMultiByte(Console->OutputCodePage, 0,
+ (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String,
+ Request->Data.WriteConsoleOutputCharRequest.Length,
NULL, 0, NULL, NULL);
tmpString = String = RtlAllocateHeap(GetProcessHeap(), 0, Length);
if (String)
{
- WideCharToMultiByte(Console->CodePage, 0,
- (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String,
- Request->Data.WriteConsoleOutputCharRequest.Length,
+ WideCharToMultiByte(Console->OutputCodePage, 0,
+ (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String,
+ Request->Data.WriteConsoleOutputCharRequest.Length,
String, Length, NULL, NULL);
}
else
{
String = (PCHAR)Request->Data.WriteConsoleOutputCharRequest.String;
}
-
+
if (String)
{
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
- &Buff);
+ &Buff,
+ GENERIC_WRITE);
if (NT_SUCCESS(Status))
{
- X = Request->Data.WriteConsoleOutputCharRequest.Coord.X + Buff->ShowX;
- Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->ShowY) % Buff->MaxY;
+ X = Request->Data.WriteConsoleOutputCharRequest.Coord.X;
+ Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY;
Length = Request->Data.WriteConsoleOutputCharRequest.Length;
Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
while (Length--)
X = 0;
}
}
- if (NULL != Console && Buff == Console->ActiveBuffer)
+ if (Buff == Console->ActiveBuffer)
{
ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputCharRequest.Coord,
Request->Data.WriteConsoleOutputCharRequest.Length);
ConioDrawRegion(Console, &UpdateRect);
}
- Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X - Buff->ShowX;
- Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->ShowY) % Buff->MaxY;
+ Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X;
+ Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY;
ConioUnlockScreenBuffer(Buff);
}
RtlFreeHeap(GetProcessHeap(), 0, tmpString);
}
}
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
+ ConioUnlockConsole(Console);
}
Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written;
- return Request->Status = Status;
+ return Status;
}
CSR_API(CsrFillOutputChar)
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff);
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
- return Request->Status = Status;
+ ConioUnlockConsole(Console);
+ return Status;
}
- X = Request->Data.FillOutputRequest.Position.X + Buff->ShowX;
- Y = (Request->Data.FillOutputRequest.Position.Y + Buff->ShowY) % Buff->MaxY;
+ X = Request->Data.FillOutputRequest.Position.X;
+ Y = (Request->Data.FillOutputRequest.Position.Y + Buff->VirtualY) % Buff->MaxY;
Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
if(Request->Data.FillOutputRequest.Unicode)
ConsoleUnicodeCharToAnsiChar(Console, &Char, &Request->Data.FillOutputRequest.Char.UnicodeChar);
}
}
- if (NULL != Console && Buff == Console->ActiveBuffer)
+ if (Buff == Console->ActiveBuffer)
{
ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputRequest.Position,
Request->Data.FillOutputRequest.Length);
}
ConioUnlockScreenBuffer(Buff);
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
+ ConioUnlockConsole(Console);
Length = Request->Data.FillOutputRequest.Length;
Request->Data.FillOutputRequest.NrCharactersWritten = Length;
- return Request->Status;
+ return STATUS_SUCCESS;
}
CSR_API(CsrReadInputEvent)
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent;
- Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console);
+ Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
/* only get input if there is any */
if (Done && !Input->Fake)
{
- Request->Data.ReadInputRequest.MoreEvents = TRUE;
- break;
- }
+ Request->Data.ReadInputRequest.MoreEvents = TRUE;
+ break;
+ }
RemoveEntryList(&Input->ListEntry);
{
ConioInputEventToAnsi(Console, &Request->Data.ReadInputRequest.Input);
}
- Done = TRUE;
- }
+ Done = TRUE;
+ }
if (Input->InputEvent.EventType == KEY_EVENT)
{
if (0 != (Console->Mode & ENABLE_LINE_INPUT)
- && Input->InputEvent.Event.KeyEvent.bKeyDown
- && '\r' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar)
+ && Input->InputEvent.Event.KeyEvent.bKeyDown
+ && '\r' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar)
{
Console->WaitingLines--;
}
ConioUnlockConsole(Console);
- return Request->Status = Status;
+ return Status;
}
CSR_API(CsrWriteConsoleOutputAttrib)
DPRINT1("Invalid request size\n");
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- return Request->Status = STATUS_INVALID_PARAMETER;
+ return STATUS_INVALID_PARAMETER;
}
Status = ConioConsoleFromProcessData(ProcessData, &Console);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle,
- &Buff);
+ &Buff,
+ GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
- return Request->Status = Status;
+ ConioUnlockConsole(Console);
+ return Status;
}
- X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X + Buff->ShowX;
- Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->ShowY) % Buff->MaxY;
+ X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X;
+ Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY;
Length = Request->Data.WriteConsoleOutputAttribRequest.Length;
Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1];
Attribute = Request->Data.WriteConsoleOutputAttribRequest.Attribute;
}
}
- if (NULL != Console && Buff == Console->ActiveBuffer)
+ if (Buff == Console->ActiveBuffer)
{
ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputAttribRequest.Coord,
Request->Data.WriteConsoleOutputAttribRequest.Length);
ConioDrawRegion(Console, &UpdateRect);
}
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
+ ConioUnlockConsole(Console);
- Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = Buff->CurrentX - Buff->ShowX;
- Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Buff->CurrentY + Buff->MaxY - Buff->ShowY) % Buff->MaxY;
+ Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = X;
+ Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY;
ConioUnlockScreenBuffer(Buff);
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
CSR_API(CsrFillOutputAttrib)
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff);
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
- return Request->Status = Status;
+ ConioUnlockConsole(Console);
+ return Status;
}
- X = Request->Data.FillOutputAttribRequest.Coord.X + Buff->ShowX;
- Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->ShowY) % Buff->MaxY;
+ X = Request->Data.FillOutputAttribRequest.Coord.X;
+ Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY;
Length = Request->Data.FillOutputAttribRequest.Length;
Attr = Request->Data.FillOutputAttribRequest.Attribute;
Buffer = &Buff->Buffer[(Y * Buff->MaxX * 2) + (X * 2) + 1];
}
}
- if (NULL != Console && Buff == Console->ActiveBuffer)
+ if (Buff == Console->ActiveBuffer)
{
ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputAttribRequest.Coord,
Request->Data.FillOutputAttribRequest.Length);
}
ConioUnlockScreenBuffer(Buff);
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
+ ConioUnlockConsole(Console);
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff);
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
- Request->Data.GetCursorInfoRequest.Info = Buff->CursorInfo;
+ Request->Data.GetCursorInfoRequest.Info.bVisible = Buff->CursorInfo.bVisible;
+ Request->Data.GetCursorInfoRequest.Info.dwSize = Buff->CursorInfo.dwSize;
ConioUnlockScreenBuffer(Buff);
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
CSR_API(CsrSetCursorInfo)
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff);
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
- return Request->Status = Status;
+ ConioUnlockConsole(Console);
+ return Status;
}
Size = Request->Data.SetCursorInfoRequest.Info.dwSize;
Buff->CursorInfo.dwSize = Size;
Buff->CursorInfo.bVisible = Visible;
- if (NULL != Console && ! ConioSetCursorInfo(Console, Buff))
+ if (! ConioSetCursorInfo(Console, Buff))
{
ConioUnlockScreenBuffer(Buff);
ConioUnlockConsole(Console);
- return Request->Status = STATUS_UNSUCCESSFUL;
+ return STATUS_UNSUCCESSFUL;
}
}
ConioUnlockScreenBuffer(Buff);
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
+ ConioUnlockConsole(Console);
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
CSR_API(CsrSetTextAttrib)
NTSTATUS Status;
PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff;
- LONG OldCursorX, OldCursorY;
DPRINT("CsrSetTextAttrib\n");
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff);
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
- return Request->Status = Status;
+ ConioUnlockConsole(Console);
+ return Status;
}
- ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &OldCursorX, &OldCursorY);
-
Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib;
- if (NULL != Console && Buff == Console->ActiveBuffer)
+ if (Buff == Console->ActiveBuffer)
{
- if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
+ if (! ConioUpdateScreenInfo(Console, Buff))
{
ConioUnlockScreenBuffer(Buff);
ConioUnlockConsole(Console);
- return Request->Status = STATUS_UNSUCCESSFUL;
+ return STATUS_UNSUCCESSFUL;
}
}
ConioUnlockScreenBuffer(Buff);
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
+ ConioUnlockConsole(Console);
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
CSR_API(CsrSetConsoleMode)
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = Win32CsrGetObject(ProcessData,
Request->Data.SetConsoleModeRequest.ConsoleHandle,
- (Object_t **) &Console);
+ (Object_t **) &Console, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
Buff = (PCSRSS_SCREEN_BUFFER)Console;
}
else
{
- return Request->Status = STATUS_INVALID_HANDLE;
+ Status = STATUS_INVALID_HANDLE;
}
- Request->Status = STATUS_SUCCESS;
+ Win32CsrReleaseObjectByPointer((Object_t *)Console);
- return Request->Status;
+ return Status;
}
CSR_API(CsrGetConsoleMode)
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = Win32CsrGetObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
- (Object_t **) &Console);
+ (Object_t **) &Console, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
- Request->Status = STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
Buff = (PCSRSS_SCREEN_BUFFER) Console;
if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
{
}
else
{
- Request->Status = STATUS_INVALID_HANDLE;
+ Status = STATUS_INVALID_HANDLE;
}
- return Request->Status;
+ Win32CsrReleaseObjectByPointer((Object_t *)Console);
+ return Status;
}
CSR_API(CsrCreateScreenBuffer)
DPRINT("CsrCreateScreenBuffer\n");
- if (ProcessData == NULL)
- {
- return Request->Status = STATUS_INVALID_PARAMETER;
- }
-
+ RtlEnterCriticalSection(&ProcessData->HandleTableLock);
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
- }
- if (NULL == Console)
- {
- return Request->Status = STATUS_INVALID_HANDLE;
+ return Status;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Buff = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_SCREEN_BUFFER));
- if (NULL == Buff)
- {
- Request->Status = STATUS_INSUFFICIENT_RESOURCES;
- }
+ Buff = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER));
- Status = CsrInitConsoleScreenBuffer(Console, Buff);
- if(! NT_SUCCESS(Status))
+ if (Buff != NULL)
{
- Request->Status = Status;
+ if (Console->ActiveBuffer)
+ {
+ Buff->MaxX = Console->ActiveBuffer->MaxX;
+ Buff->MaxY = Console->ActiveBuffer->MaxY;
+ Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible;
+ Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize;
+ }
+ else
+ {
+ Buff->CursorInfo.bVisible = TRUE;
+ Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
+ }
+
+ if (Buff->MaxX == 0)
+ {
+ Buff->MaxX = 80;
+ }
+
+ if (Buff->MaxY == 0)
+ {
+ Buff->MaxY = 25;
+ }
+
+ Status = CsrInitConsoleScreenBuffer(Console, Buff);
+ if(NT_SUCCESS(Status))
+ {
+ Status = Win32CsrInsertObject(ProcessData,
+ &Request->Data.CreateScreenBufferRequest.OutputHandle,
+ &Buff->Header,
+ Request->Data.CreateScreenBufferRequest.Access,
+ Request->Data.CreateScreenBufferRequest.Inheritable);
+ }
}
else
{
- Request->Status = Win32CsrInsertObject(ProcessData, &Request->Data.CreateScreenBufferRequest.OutputHandle, &Buff->Header);
+ Status = STATUS_INSUFFICIENT_RESOURCES;
}
ConioUnlockConsole(Console);
-
- return Request->Status;
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ return Status;
}
CSR_API(CsrSetScreenBuffer)
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
- }
- if (NULL == Console)
- {
- DPRINT1("Trying to set screen buffer for app without console\n");
- return Request->Status = STATUS_INVALID_HANDLE;
+ return Status;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff);
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
ConioUnlockConsole(Console);
- return Request->Status;
+ return Status;
}
if (Buff == Console->ActiveBuffer)
ConioUnlockScreenBuffer(Buff);
ConioUnlockConsole(Console);
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
CSR_API(CsrSetTitle)
DPRINT1("Invalid request size\n");
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- return Request->Status = STATUS_INVALID_PARAMETER;
+ return STATUS_INVALID_PARAMETER;
}
- Status = ConioLockConsole(ProcessData, Request->Data.SetTitleRequest.Console, &Console);
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- if(! NT_SUCCESS(Status))
- {
- Request->Status = Status;
- }
- else
+ if(NT_SUCCESS(Status))
{
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length);
if (Buffer)
memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length);
if (! ConioChangeTitle(Console))
{
- Request->Status = STATUS_UNSUCCESSFUL;
+ Status = STATUS_UNSUCCESSFUL;
}
else
{
- Request->Status = STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
}
}
else
{
- Request->Status = STATUS_NO_MEMORY;
+ Status = STATUS_NO_MEMORY;
}
+ ConioUnlockConsole(Console);
}
- ConioUnlockConsole(Console);
- return Request->Status;
+ return Status;
}
CSR_API(CsrGetTitle)
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioLockConsole(ProcessData,
- Request->Data.GetTitleRequest.ConsoleHandle,
- &Console);
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
DPRINT1("Can't get console\n");
- return Request->Status = Status;
+ return Status;
}
/* Copy title of the console to the user title buffer */
RtlZeroMemory(&Request->Data.GetTitleRequest, sizeof(CSRSS_GET_TITLE));
- Request->Data.GetTitleRequest.ConsoleHandle = Request->Data.GetTitleRequest.ConsoleHandle;
Request->Data.GetTitleRequest.Length = Console->Title.Length;
memcpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer,
Console->Title.Length);
Request->Header.u1.s1.TotalLength = Length;
Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE);
}
- Request->Status = STATUS_SUCCESS;
-
- return Request->Status;
+ return STATUS_SUCCESS;
}
CSR_API(CsrWriteConsoleOutput)
COORD BufferCoord;
COORD BufferSize;
NTSTATUS Status;
- DWORD Offset;
+ PBYTE Ptr;
DWORD PSize;
DPRINT("CsrWriteConsoleOutput\n");
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.WriteConsoleOutputRequest.ConsoleHandle,
- &Buff);
+ &Buff,
+ GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
- return Request->Status = Status;
+ ConioUnlockConsole(Console);
+ return Status;
}
BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize;
{
ConioUnlockScreenBuffer(Buff);
ConioUnlockConsole(Console);
- return Request->Status = STATUS_ACCESS_VIOLATION;
+ return STATUS_ACCESS_VIOLATION;
}
WriteRegion.left = Request->Data.WriteConsoleOutputRequest.WriteRegion.Left;
WriteRegion.top = Request->Data.WriteConsoleOutputRequest.WriteRegion.Top;
/* It is okay to have a WriteRegion completely outside the screen buffer.
No data is written then. */
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
for (i = 0, Y = WriteRegion.top; Y <= WriteRegion.bottom; i++, Y++)
{
CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X;
- Offset = (((Y + Buff->ShowY) % Buff->MaxY) * Buff->MaxX + WriteRegion.left) * 2;
+ Ptr = ConioCoordToPointer(Buff, WriteRegion.left, Y);
for (X = WriteRegion.left; X <= WriteRegion.right; X++)
{
+ CHAR AsciiChar;
if (Request->Data.WriteConsoleOutputRequest.Unicode)
{
- CHAR AsciiChar;
ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar);
- SET_CELL_BUFFER(Buff, Offset, AsciiChar, CurCharInfo->Attributes);
}
else
{
- SET_CELL_BUFFER(Buff, Offset, CurCharInfo->Char.AsciiChar, CurCharInfo->Attributes);
+ AsciiChar = CurCharInfo->Char.AsciiChar;
}
+ *Ptr++ = AsciiChar;
+ *Ptr++ = CurCharInfo->Attributes;
CurCharInfo++;
}
}
- if (NULL != Console)
- {
- ConioDrawRegion(Console, &WriteRegion);
- }
+ ConioDrawRegion(Console, &WriteRegion);
ConioUnlockScreenBuffer(Buff);
ConioUnlockConsole(Console);
Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.left;
Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.top;
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
CSR_API(CsrFlushInputBuffer)
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockConsole(ProcessData,
Request->Data.FlushInputBufferRequest.ConsoleInput,
- &Console);
+ &Console,
+ GENERIC_WRITE);
if(! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
/* Discard all entries in the input event queue */
ConioUnlockConsole(Console);
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
CSR_API(CsrScrollConsoleScreenBuffer)
RECT ScreenBuffer;
RECT SrcRegion;
RECT DstRegion;
- RECT FillRegion;
+ RECT UpdateRegion;
RECT ScrollRectangle;
RECT ClipRectangle;
NTSTATUS Status;
- BOOLEAN DoFill;
+ HANDLE ConsoleHandle;
+ BOOLEAN UseClipRectangle;
+ COORD DestinationOrigin;
+ CHAR_INFO Fill;
+ CHAR FillChar;
DPRINT("CsrScrollConsoleScreenBuffer\n");
- ALIAS(ConsoleHandle,Request->Data.ScrollConsoleScreenBufferRequest.ConsoleHandle);
- ALIAS(UseClipRectangle,Request->Data.ScrollConsoleScreenBufferRequest.UseClipRectangle);
- ALIAS(DestinationOrigin,Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin);
- ALIAS(Fill,Request->Data.ScrollConsoleScreenBufferRequest.Fill);
+ ConsoleHandle = Request->Data.ScrollConsoleScreenBufferRequest.ConsoleHandle;
+ UseClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.UseClipRectangle;
+ DestinationOrigin = Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin;
+ Fill = Request->Data.ScrollConsoleScreenBufferRequest.Fill;
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff);
+ Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
- return Request->Status = Status;
+ ConioUnlockConsole(Console);
+ return Status;
}
ScrollRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Left;
ScrollRectangle.top = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Top;
ScrollRectangle.right = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Right;
ScrollRectangle.bottom = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Bottom;
- ClipRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Left;
- ClipRectangle.top = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Top;
- ClipRectangle.right = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Right;
- ClipRectangle.bottom = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Bottom;
/* Make sure source rectangle is inside the screen buffer */
ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle))
{
ConioUnlockScreenBuffer(Buff);
- return Request->Status = STATUS_INVALID_PARAMETER;
+ ConioUnlockConsole(Console);
+ return STATUS_SUCCESS;
}
- if (UseClipRectangle && ! ConioGetIntersection(&SrcRegion, &SrcRegion, &ClipRectangle))
+ /* If the source was clipped on the left or top, adjust the destination accordingly */
+ if (ScrollRectangle.left < 0)
{
- ConioUnlockScreenBuffer(Buff);
- return Request->Status = STATUS_SUCCESS;
+ DestinationOrigin.X -= ScrollRectangle.left;
+ }
+ if (ScrollRectangle.top < 0)
+ {
+ DestinationOrigin.Y -= ScrollRectangle.top;
}
+ if (UseClipRectangle)
+ {
+ ClipRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Left;
+ ClipRectangle.top = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Top;
+ ClipRectangle.right = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Right;
+ ClipRectangle.bottom = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Bottom;
+ if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer))
+ {
+ ConioUnlockConsole(Console);
+ ConioUnlockScreenBuffer(Buff);
+ return STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ ClipRectangle = ScreenBuffer;
+ }
ConioInitRect(&DstRegion,
DestinationOrigin.Y,
DestinationOrigin.X,
- DestinationOrigin.Y + ConioRectHeight(&ScrollRectangle) - 1,
- DestinationOrigin.X + ConioRectWidth(&ScrollRectangle) - 1);
-
- /* Make sure destination rectangle is inside the screen buffer */
- if (! ConioGetIntersection(&DstRegion, &DstRegion, &ScreenBuffer))
- {
- ConioUnlockScreenBuffer(Buff);
- return Request->Status = STATUS_INVALID_PARAMETER;
- }
-
- ConioCopyRegion(Buff, &SrcRegion, &DstRegion);
+ DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1,
+ DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1);
- /* Get the region that should be filled with the specified character and attributes */
-
- DoFill = FALSE;
-
- ConioGetUnion(&FillRegion, &SrcRegion, &DstRegion);
-
- if (ConioSubtractRect(&FillRegion, &FillRegion, &DstRegion))
- {
- /* FIXME: The subtracted rectangle is off by one line */
- FillRegion.top += 1;
+ if (Request->Data.ScrollConsoleScreenBufferRequest.Unicode)
+ ConsoleUnicodeCharToAnsiChar(Console, &FillChar, &Fill.Char.UnicodeChar);
+ else
+ FillChar = Fill.Char.AsciiChar;
- ConioFillRegion(Console, Buff, &FillRegion, &Fill, Request->Data.ScrollConsoleScreenBufferRequest.Unicode);
- DoFill = TRUE;
- }
+ ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, Fill.Attributes << 8 | (BYTE)FillChar);
- if (NULL != Console && Buff == Console->ActiveBuffer)
+ if (Buff == Console->ActiveBuffer)
{
- /* Draw destination region */
- ConioDrawRegion(Console, &DstRegion);
-
- if (DoFill)
+ ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion);
+ if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &ClipRectangle))
{
- /* Draw filled region */
- ConioDrawRegion(Console, &FillRegion);
+ /* Draw update region */
+ ConioDrawRegion(Console, &UpdateRegion);
}
}
ConioUnlockScreenBuffer(Buff);
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
+ ConioUnlockConsole(Console);
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
CSR_API(CsrReadConsoleOutputChar)
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff);
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ ConioUnlockConsole(Console);
+ return Status;
}
- Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X + Buff->ShowX;
- Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->ShowY) % Buff->MaxY;
+ Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X;
+ Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY;
for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i)
{
Xpos++;
if (Xpos == Buff->MaxX)
- {
- Xpos = 0;
- Ypos++;
+ {
+ Xpos = 0;
+ Ypos++;
- if (Ypos == Buff->MaxY)
+ if (Ypos == Buff->MaxY)
{
Ypos = 0;
}
- }
+ }
}
*ReadBuffer = 0;
- Request->Status = STATUS_SUCCESS;
- Request->Data.ReadConsoleOutputCharRequest.EndCoord.X = Xpos - Buff->ShowX;
- Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->ShowY + Buff->MaxY) % Buff->MaxY;
+ Request->Data.ReadConsoleOutputCharRequest.EndCoord.X = Xpos;
+ Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY;
ConioUnlockScreenBuffer(Buff);
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
+ ConioUnlockConsole(Console);
Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize;
if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE))
Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
}
- return Request->Status;
+ return STATUS_SUCCESS;
}
Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
ReadBuffer = Request->Data.ReadConsoleOutputAttribRequest.Attribute;
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff);
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
- Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X + Buff->ShowX;
- Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + Buff->ShowY) % Buff->MaxY;
+ Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X;
+ Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY;
for (i = 0; i < Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; ++i)
{
*ReadBuffer = 0;
- Request->Status = STATUS_SUCCESS;
- Request->Data.ReadConsoleOutputAttribRequest.EndCoord.X = Xpos - Buff->ShowX;
- Request->Data.ReadConsoleOutputAttribRequest.EndCoord.Y = (Ypos - Buff->ShowY + Buff->MaxY) % Buff->MaxY;
+ Request->Data.ReadConsoleOutputAttribRequest.EndCoord.X = Xpos;
+ Request->Data.ReadConsoleOutputAttribRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY;
ConioUnlockScreenBuffer(Buff);
Request->Header.u1.s1.DataLength = CurrentLength - sizeof(PORT_MESSAGE);
}
- return Request->Status;
+ return STATUS_SUCCESS;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
- Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console);
+ Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
CurrentItem = Console->InputEvents.Flink;
if (!Input->Fake)
{
NumEvents++;
- }
+ }
}
ConioUnlockConsole(Console);
- Request->Status = STATUS_SUCCESS;
Request->Data.GetNumInputEventsRequest.NumInputEvents = NumEvents;
- return Request->Status;
+ return STATUS_SUCCESS;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console);
+ Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
if(! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord;
|| (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
{
ConioUnlockConsole(Console);
- Request->Status = STATUS_ACCESS_VIOLATION;
- return Request->Status ;
+ return STATUS_ACCESS_VIOLATION;
}
NumItems = 0;
ConioUnlockConsole(Console);
- Request->Status = STATUS_SUCCESS;
Request->Data.PeekConsoleInputRequest.Length = NumItems;
- return Request->Status;
+ return STATUS_SUCCESS;
}
COORD BufferCoord;
RECT ReadRegion;
RECT ScreenRect;
- DWORD i, Offset;
+ DWORD i;
+ PBYTE Ptr;
LONG X, Y;
UINT CodePage;
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff);
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo;
|| (((ULONG_PTR)CharInfo + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
{
ConioUnlockScreenBuffer(Buff);
- Request->Status = STATUS_ACCESS_VIOLATION;
- return Request->Status ;
+ return STATUS_ACCESS_VIOLATION;
}
SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion));
if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion))
{
ConioUnlockScreenBuffer(Buff);
- Request->Status = STATUS_SUCCESS;
- return Request->Status;
+ return STATUS_SUCCESS;
}
for (i = 0, Y = ReadRegion.top; Y < ReadRegion.bottom; ++i, ++Y)
{
CurCharInfo = CharInfo + (i * BufferSize.X);
- Offset = (((Y + Buff->ShowY) % Buff->MaxY) * Buff->MaxX + ReadRegion.left) * 2;
+ Ptr = ConioCoordToPointer(Buff, ReadRegion.left, Y);
for (X = ReadRegion.left; X < ReadRegion.right; ++X)
{
if (Request->Data.ReadConsoleOutputRequest.Unicode)
{
MultiByteToWideChar(CodePage, 0,
- (PCHAR)&GET_CELL_BUFFER(Buff, Offset), 1,
+ (PCHAR)Ptr++, 1,
&CurCharInfo->Char.UnicodeChar, 1);
}
else
{
- CurCharInfo->Char.AsciiChar = GET_CELL_BUFFER(Buff, Offset);
+ CurCharInfo->Char.AsciiChar = *Ptr++;
}
- CurCharInfo->Attributes = GET_CELL_BUFFER(Buff, Offset);
+ CurCharInfo->Attributes = *Ptr++;
++CurCharInfo;
}
}
ConioUnlockScreenBuffer(Buff);
- Request->Status = STATUS_SUCCESS;
Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.left + SizeX - 1;
Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.top + SizeY - 1;
Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.left;
Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.top;
- return Request->Status;
+ return STATUS_SUCCESS;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console);
+ Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord;
|| (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
{
ConioUnlockConsole(Console);
- Request->Status = STATUS_ACCESS_VIOLATION;
- return Request->Status ;
+ return STATUS_ACCESS_VIOLATION;
}
for (i = 0; i < Length; i++)
if (NULL == Record)
{
ConioUnlockConsole(Console);
- Request->Status = STATUS_INSUFFICIENT_RESOURCES;
- return Request->Status;
+ return STATUS_INSUFFICIENT_RESOURCES;
}
Record->Echoed = FALSE;
Record->Fake = FALSE;
- Record->InputEvent = *InputRecord++;
+ //Record->InputEvent = *InputRecord++;
+ memcpy(&Record->InputEvent, &InputRecord[i], sizeof(INPUT_RECORD));
if (KEY_EVENT == Record->InputEvent.EventType)
{
/* FIXME - convert from unicode to ascii!! */
ConioUnlockConsole(Console);
- Request->Status = STATUS_SUCCESS;
Request->Data.WriteConsoleInputRequest.Length = i;
- return Request->Status;
+ return STATUS_SUCCESS;
}
/**********************************************************************
Status = ConioLockConsole(ProcessData,
Request->Data.ConsoleHardwareStateRequest.ConsoleHandle,
- &Console);
+ &Console,
+ GENERIC_READ);
if (! NT_SUCCESS(Status))
{
DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
- return Request->Status = Status;
+ return Status;
}
switch (Request->Data.ConsoleHardwareStateRequest.SetGet)
case CONSOLE_HARDWARE_STATE_SET:
DPRINT("Setting console hardware state.\n");
- Request->Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State);
+ Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State);
break;
default:
- Request->Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */
+ Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */
break;
}
ConioUnlockConsole(Console);
- return Request->Status;
+ return Status;
}
CSR_API(CsrGetConsoleWindow)
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow;
ConioUnlockConsole(Console);
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
CSR_API(CsrSetConsoleIcon)
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
- Console->hWindowIcon = Request->Data.SetConsoleIconRequest.WindowIcon;
- Request->Status = (ConioChangeIcon(Console) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
+ Status = (ConioChangeIcon(Console, Request->Data.SetConsoleIconRequest.WindowIcon)
+ ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
ConioUnlockConsole(Console);
- return Request->Status;
+ return Status;
}
CSR_API(CsrGetConsoleCodePage)
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Request->Data.GetConsoleCodePage.CodePage = Console->CodePage;
ConioUnlockConsole(Console);
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
CSR_API(CsrSetConsoleCodePage)
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage))
{
Console->CodePage = Request->Data.SetConsoleCodePage.CodePage;
ConioUnlockConsole(Console);
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
+
ConioUnlockConsole(Console);
- return Request->Status = STATUS_UNSUCCESSFUL;
+ return STATUS_INVALID_PARAMETER;
}
CSR_API(CsrGetConsoleOutputCodePage)
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage;
ConioUnlockConsole(Console);
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
CSR_API(CsrSetConsoleOutputCodePage)
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage))
{
Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage;
ConioUnlockConsole(Console);
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
+
ConioUnlockConsole(Console);
- return Request->Status = STATUS_UNSUCCESSFUL;
+ return STATUS_INVALID_PARAMETER;
}
CSR_API(CsrGetProcessList)
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
- return Request->Status = Status;
+ return Status;
}
DPRINT1("Console_Api Ctrl-C\n");
current_entry = current_entry->Flink)
{
current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
- if(nItems++ < Request->Data.GetProcessListRequest.nMaxIds)
+ if(++nItems < Request->Data.GetProcessListRequest.nMaxIds)
{
*(Buffer++) = current->ProcessId;
nCopied++;
Request->Header.u1.s1.TotalLength = Length;
Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE);
}
- return Request->Status = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
+}
+
+CSR_API(CsrGenerateCtrlEvent)
+{
+ PCSRSS_CONSOLE Console;
+ PCSRSS_PROCESS_DATA current;
+ PLIST_ENTRY current_entry;
+ DWORD Group;
+ NTSTATUS Status;
+
+ Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+ Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ Group = Request->Data.GenerateCtrlEvent.ProcessGroup;
+ Status = STATUS_INVALID_PARAMETER;
+ for (current_entry = Console->ProcessList.Flink;
+ current_entry != &Console->ProcessList;
+ current_entry = current_entry->Flink)
+ {
+ current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
+ if (Group == 0 || current->ProcessGroup == Group)
+ {
+ ConioConsoleCtrlEvent(Request->Data.GenerateCtrlEvent.Event, current);
+ Status = STATUS_SUCCESS;
+ }
+ }
+
+ ConioUnlockConsole(Console);
+
+ return Status;
+}
+
+CSR_API(CsrSetScreenBufferSize)
+{
+ NTSTATUS Status;
+ PCSRSS_CONSOLE Console;
+ PCSRSS_SCREEN_BUFFER Buff;
+
+ Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+ Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferSize.OutputHandle, &Buff, GENERIC_WRITE);
+ if (!NT_SUCCESS(Status))
+ {
+ ConioUnlockConsole(Console);
+ return Status;
+ }
+
+ Status = ConioResizeBuffer(Console, Buff, Request->Data.SetScreenBufferSize.Size);
+ ConioUnlockScreenBuffer(Buff);
+ ConioUnlockConsole(Console);
+
+ return Status;
}
/* EOF */