Auto-detect whether to create a GUI or a TUI console
authorGé van Geldorp <ge@gse.nl>
Sun, 11 Jan 2004 17:31:16 +0000 (17:31 +0000)
committerGé van Geldorp <ge@gse.nl>
Sun, 11 Jan 2004 17:31:16 +0000 (17:31 +0000)
svn path=/trunk/; revision=7571

17 files changed:
reactos/drivers/dd/blue/blue.c
reactos/drivers/dd/blue/makefile
reactos/include/ddk/ntddblue.h
reactos/subsys/csrss/api/handle.c
reactos/subsys/csrss/api/process.c
reactos/subsys/csrss/include/api.h
reactos/subsys/csrss/include/conio.h
reactos/subsys/csrss/include/desktopbg.h
reactos/subsys/csrss/include/win32csr.h
reactos/subsys/csrss/win32csr/Makefile
reactos/subsys/csrss/win32csr/conio.c
reactos/subsys/csrss/win32csr/desktopbg.c
reactos/subsys/csrss/win32csr/dllmain.c
reactos/subsys/csrss/win32csr/guiconsole.c
reactos/subsys/csrss/win32csr/guiconsole.h
reactos/subsys/csrss/win32csr/tuiconsole.c [new file with mode: 0644]
reactos/subsys/csrss/win32csr/tuiconsole.h [new file with mode: 0644]

index b494737..06d66ff 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: blue.c,v 1.41 2003/11/17 02:12:48 hyperion Exp $
+/* $Id: blue.c,v 1.42 2004/01/11 17:31:14 gvg Exp $
  *
  * COPYRIGHT:            See COPYING in the top level directory
  * PROJECT:              ReactOS kernel
@@ -302,290 +302,327 @@ NTSTATUS STDCALL
 ScrIoControl(PDEVICE_OBJECT DeviceObject,
             PIRP Irp)
 {
-    PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
-    PDEVICE_EXTENSION DeviceExtension;
-    NTSTATUS Status;
-    DeviceExtension = DeviceObject->DeviceExtension;
-    switch (stk->Parameters.DeviceIoControl.IoControlCode)
-    {
-        case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO:
-            {
-                PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
-                int rows = DeviceExtension->Rows;
-                int columns = DeviceExtension->Columns;
-                unsigned int offset;
-
-                /* read cursor position from crtc */
-                __asm__("cli\n\t");
-                WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
-                offset = READ_PORT_UCHAR (CRTC_DATA);
-                WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
-                offset += (READ_PORT_UCHAR (CRTC_DATA) << 8);
-                __asm__("sti\n\t");
-
-                pcsbi->dwSize.X = columns;
-                pcsbi->dwSize.Y = rows;
-
-                pcsbi->dwCursorPosition.X = (SHORT)(offset % columns);
-                pcsbi->dwCursorPosition.Y = (SHORT)(offset / columns);
-
-                pcsbi->wAttributes = DeviceExtension->CharAttribute;
-
-                pcsbi->srWindow.Left   = 0;
-                pcsbi->srWindow.Right  = columns - 1;
-                pcsbi->srWindow.Top    = 0;
-                pcsbi->srWindow.Bottom = rows - 1;
-
-                pcsbi->dwMaximumWindowSize.X = columns;
-                pcsbi->dwMaximumWindowSize.Y = rows;
-
-                Irp->IoStatus.Information = sizeof (CONSOLE_SCREEN_BUFFER_INFO);
-                Status = STATUS_SUCCESS;
-            }
-            break;
+  PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
+  PDEVICE_EXTENSION DeviceExtension;
+  NTSTATUS Status;
 
-        case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO:
+  DeviceExtension = DeviceObject->DeviceExtension;
+  switch (stk->Parameters.DeviceIoControl.IoControlCode)
+    {
+      case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO:
+        {
+          PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
+          int rows = DeviceExtension->Rows;
+          int columns = DeviceExtension->Columns;
+          unsigned int offset;
+
+          /* read cursor position from crtc */
+          __asm__("cli\n\t");
+          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
+          offset = READ_PORT_UCHAR (CRTC_DATA);
+          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
+          offset += (READ_PORT_UCHAR (CRTC_DATA) << 8);
+          __asm__("sti\n\t");
+
+          pcsbi->dwSize.X = columns;
+          pcsbi->dwSize.Y = rows;
+
+          pcsbi->dwCursorPosition.X = (SHORT)(offset % columns);
+          pcsbi->dwCursorPosition.Y = (SHORT)(offset / columns);
+
+          pcsbi->wAttributes = DeviceExtension->CharAttribute;
+
+          pcsbi->srWindow.Left   = 0;
+          pcsbi->srWindow.Right  = columns - 1;
+          pcsbi->srWindow.Top    = 0;
+          pcsbi->srWindow.Bottom = rows - 1;
+
+          pcsbi->dwMaximumWindowSize.X = columns;
+          pcsbi->dwMaximumWindowSize.Y = rows;
+
+          Irp->IoStatus.Information = sizeof (CONSOLE_SCREEN_BUFFER_INFO);
+          Status = STATUS_SUCCESS;
+        }
+        break;
+
+      case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO:
+        {
+          PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
+          unsigned int offset;
+
+          DeviceExtension->CharAttribute = pcsbi->wAttributes;
+          offset = (pcsbi->dwCursorPosition.Y * DeviceExtension->Columns) +
+                    pcsbi->dwCursorPosition.X;
+
+          __asm__("cli\n\t");
+          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
+          WRITE_PORT_UCHAR (CRTC_DATA, offset);
+          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
+          WRITE_PORT_UCHAR (CRTC_DATA, offset>>8);
+          __asm__("sti\n\t");
+
+          Irp->IoStatus.Information = 0;
+          Status = STATUS_SUCCESS;
+        }
+        break;
+
+      case IOCTL_CONSOLE_GET_CURSOR_INFO:
+        {
+          PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
+
+          pcci->dwSize = DeviceExtension->CursorSize;
+          pcci->bVisible = DeviceExtension->CursorVisible;
+
+          Irp->IoStatus.Information = sizeof (CONSOLE_CURSOR_INFO);
+          Status = STATUS_SUCCESS;
+        }
+        break;
+
+      case IOCTL_CONSOLE_SET_CURSOR_INFO:
+        {
+          PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
+          BYTE data, value;
+          DWORD size, height;
+
+          DeviceExtension->CursorSize = pcci->dwSize;
+          DeviceExtension->CursorVisible = pcci->bVisible;
+          height = DeviceExtension->ScanLines;
+          data = (pcci->bVisible) ? 0x00 : 0x20;
+
+          size = (pcci->dwSize * height) / 100;
+          if (size < 1)
             {
-                PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
-                unsigned int offset;
-
-                DeviceExtension->CharAttribute = pcsbi->wAttributes;
-                offset = (pcsbi->dwCursorPosition.Y * DeviceExtension->Columns) +
-                          pcsbi->dwCursorPosition.X;
-
-                __asm__("cli\n\t");
-                WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
-                WRITE_PORT_UCHAR (CRTC_DATA, offset);
-                WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
-                WRITE_PORT_UCHAR (CRTC_DATA, offset>>8);
-                __asm__("sti\n\t");
-
-                Irp->IoStatus.Information = 0;
-                Status = STATUS_SUCCESS;
+              size = 1;
             }
-            break;
 
-        case IOCTL_CONSOLE_GET_CURSOR_INFO:
-            {
-                PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
+          data |= (BYTE)(height - size);
 
-                pcci->dwSize = DeviceExtension->CursorSize;
-                pcci->bVisible = DeviceExtension->CursorVisible;
+          __asm__("cli\n\t");
+          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
+          WRITE_PORT_UCHAR (CRTC_DATA, data);
+          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
+          value = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
+          WRITE_PORT_UCHAR (CRTC_DATA, value | (height - 1));
 
-                Irp->IoStatus.Information = sizeof (CONSOLE_CURSOR_INFO);
-                Status = STATUS_SUCCESS;
-            }
-            break;
+          __asm__("sti\n\t");
 
-        case IOCTL_CONSOLE_SET_CURSOR_INFO:
-            {
-                PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
-                BYTE data, value;
-                DWORD size, height;
+          Irp->IoStatus.Information = 0;
+          Status = STATUS_SUCCESS;
+        }
+        break;
 
-                DeviceExtension->CursorSize = pcci->dwSize;
-                DeviceExtension->CursorVisible = pcci->bVisible;
-                height = DeviceExtension->ScanLines;
-                data = (pcci->bVisible) ? 0x40 : 0x20;
+      case IOCTL_CONSOLE_GET_MODE:
+        {
+          PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
 
-                size = (pcci->dwSize * height) / 100;
-                if (size < 1)
-                    size = 1;
+          pcm->dwMode = DeviceExtension->Mode;
 
-                data |= (BYTE)(height - size);
+          Irp->IoStatus.Information = sizeof(CONSOLE_MODE);
+          Status = STATUS_SUCCESS;
+        }
+        break;
 
-                __asm__("cli\n\t");
-                WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
-                WRITE_PORT_UCHAR (CRTC_DATA, data);
-                WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
-                value = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
-                WRITE_PORT_UCHAR (CRTC_DATA, value | (height - 1));
+      case IOCTL_CONSOLE_SET_MODE:
+        {
+          PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
 
-                __asm__("sti\n\t");
+          DeviceExtension->Mode = pcm->dwMode;
 
-                Irp->IoStatus.Information = 0;
-                Status = STATUS_SUCCESS;
-            }
-            break;
+          Irp->IoStatus.Information = 0;
+          Status = STATUS_SUCCESS;
+        }
+        break;
 
-        case IOCTL_CONSOLE_GET_MODE:
-            {
-                PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
-
-                pcm->dwMode = DeviceExtension->Mode;
+      case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE:
+        {
+          POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
+          char *vidmem;
+          int offset;
+          DWORD dwCount;
 
-                Irp->IoStatus.Information = sizeof(CONSOLE_MODE);
-                Status = STATUS_SUCCESS;
-            }
-            break;
+          vidmem = DeviceExtension->VideoMemory;
+          offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
+                    (Buf->dwCoord.X * 2) + 1;
 
-        case IOCTL_CONSOLE_SET_MODE:
+          for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
             {
-                PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
-
-                DeviceExtension->Mode = pcm->dwMode;
-
-                Irp->IoStatus.Information = 0;
-                Status = STATUS_SUCCESS;
+              vidmem[offset + (dwCount * 2)] = (char) Buf->wAttribute;
             }
-            break;
 
-        case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE:
-            {
-                POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
-                char *vidmem;
-                int offset;
-                DWORD dwCount;
-
-                vidmem = DeviceExtension->VideoMemory;
-                offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
-                         (Buf->dwCoord.X * 2) + 1;
-
-                for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
-                {
-                    vidmem[offset + (dwCount * 2)] = (char) Buf->wAttribute;
-                }
-
-                Buf->dwTransfered = Buf->nLength;
+          Buf->dwTransfered = Buf->nLength;
                 
-                Irp->IoStatus.Information = 0;
-                Status = STATUS_SUCCESS;
+          Irp->IoStatus.Information = 0;
+          Status = STATUS_SUCCESS;
+        }
+        break;
+
+      case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE:
+        {
+          POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
+          PWORD pAttr = (PWORD)MmGetSystemAddressForMdl(Irp->MdlAddress);
+          char *vidmem;
+          int offset;
+          DWORD dwCount;
+
+          vidmem = DeviceExtension->VideoMemory;
+          offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
+                   (Buf->dwCoord.X * 2) + 1;
+
+          for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pAttr++)
+            {
+              (char) *pAttr = vidmem[offset + (dwCount * 2)];
             }
-            break;
 
-        case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE:
-            {
-                POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
-                PWORD pAttr = (PWORD)MmGetSystemAddressForMdl(Irp->MdlAddress);
-                char *vidmem;
-                int offset;
-                DWORD dwCount;
+          Buf->dwTransfered = dwCount;
 
-                vidmem = DeviceExtension->VideoMemory;
-                offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
-                         (Buf->dwCoord.X * 2) + 1;
+          Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
+          Status = STATUS_SUCCESS;
+        }
+        break;
 
-                for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pAttr++)
-                {
-                    (char) *pAttr = vidmem[offset + (dwCount * 2)];
-                }
+      case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE:
+        {
+          COORD *pCoord = (COORD *)MmGetSystemAddressForMdl(Irp->MdlAddress);
+          CHAR *pAttr = (CHAR *)(pCoord + 1);
+          char *vidmem;
+          int offset;
+          DWORD dwCount;
 
-                Buf->dwTransfered = dwCount;
+          vidmem = DeviceExtension->VideoMemory;
+          offset = (pCoord->Y * DeviceExtension->Columns * 2) +
+                   (pCoord->X * 2) + 1;
 
-                Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
-                Status = STATUS_SUCCESS;
-            }
-            break;
-
-        case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE:
+          for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.InputBufferLength - sizeof( COORD )); dwCount++, pAttr++)
             {
-                COORD *pCoord = (COORD *)MmGetSystemAddressForMdl(Irp->MdlAddress);
-               CHAR *pAttr = (CHAR *)(pCoord + 1);
-                char *vidmem;
-                int offset;
-                DWORD dwCount;
-
-                vidmem = DeviceExtension->VideoMemory;
-                offset = (pCoord->Y * DeviceExtension->Columns * 2) +
-                         (pCoord->X * 2) + 1;
-
-                for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.InputBufferLength - sizeof( COORD )); dwCount++, pAttr++)
-                {
-                    vidmem[offset + (dwCount * 2)] = *pAttr;
-                }
-                Irp->IoStatus.Information = 0;
-                Status = STATUS_SUCCESS;
+              vidmem[offset + (dwCount * 2)] = *pAttr;
             }
-            break;
-
-        case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE:
-            DeviceExtension->CharAttribute = (WORD)*(PWORD)Irp->AssociatedIrp.SystemBuffer;
-            Irp->IoStatus.Information = 0;
-            Status = STATUS_SUCCESS;
-            break;
-
-
-        case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER:
+          Irp->IoStatus.Information = 0;
+          Status = STATUS_SUCCESS;
+        }
+        break;
+
+      case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE:
+        DeviceExtension->CharAttribute = (WORD)*(PWORD)Irp->AssociatedIrp.SystemBuffer;
+        Irp->IoStatus.Information = 0;
+        Status = STATUS_SUCCESS;
+        break;
+
+      case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER:
+        {
+          POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
+          char *vidmem;
+          int offset;
+          DWORD dwCount;
+
+          vidmem = DeviceExtension->VideoMemory;
+          offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
+                   (Buf->dwCoord.X * 2);
+
+          CHECKPOINT
+
+          for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
             {
-                POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
-                char *vidmem;
-                int offset;
-                DWORD dwCount;
+              vidmem[offset + (dwCount * 2)] = (char) Buf->cCharacter;
+            }
 
-                vidmem = DeviceExtension->VideoMemory;
-                offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
-                         (Buf->dwCoord.X * 2);
+          Buf->dwTransfered = Buf->nLength;
 
-                CHECKPOINT
+          Irp->IoStatus.Information = 0;
+          Status = STATUS_SUCCESS;
+        }
+        break;
 
-                for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
-                {
-                    vidmem[offset + (dwCount * 2)] = (char) Buf->cCharacter;
-                }
+      case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER:
+        {
+          POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
+          LPSTR pChar = (LPSTR)MmGetSystemAddressForMdl(Irp->MdlAddress);
+          char *vidmem;
+          int offset;
+          DWORD dwCount;
 
-                Buf->dwTransfered = Buf->nLength;
+          vidmem = DeviceExtension->VideoMemory;
+          offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
+                   (Buf->dwCoord.X * 2);
 
-                Irp->IoStatus.Information = 0;
-                Status = STATUS_SUCCESS;
+          for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pChar++)
+            {
+              *pChar = vidmem[offset + (dwCount * 2)];
             }
-            break;
 
-        case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER:
-            {
-                POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
-                LPSTR pChar = (LPSTR)MmGetSystemAddressForMdl(Irp->MdlAddress);
-                char *vidmem;
-                int offset;
-                DWORD dwCount;
+          Buf->dwTransfered = dwCount;
 
-                vidmem = DeviceExtension->VideoMemory;
-                offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
-                         (Buf->dwCoord.X * 2);
+          Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
+          Status = STATUS_SUCCESS;
+        }
+        break;
 
-                for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pChar++)
-                {
-                    *pChar = vidmem[offset + (dwCount * 2)];
-                }
+      case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER:
+        {
+          COORD *pCoord;
+          LPSTR pChar;
+          char *vidmem;
+          int offset;
+          DWORD dwCount;
 
-                Buf->dwTransfered = dwCount;
+          pCoord = (COORD *)MmGetSystemAddressForMdl(Irp->MdlAddress);
+          pChar = (CHAR *)(pCoord + 1);
+          vidmem = DeviceExtension->VideoMemory;
+          offset = (pCoord->Y * DeviceExtension->Columns * 2) +
+                   (pCoord->X * 2);
 
-                Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
-                Status = STATUS_SUCCESS;
+          for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.InputBufferLength - sizeof( COORD )); dwCount++, pChar++)
+            {
+              vidmem[offset + (dwCount * 2)] = *pChar;
             }
-            break;
 
-        case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER:
+          Irp->IoStatus.Information = 0;
+          Status = STATUS_SUCCESS;
+        }
+        break;
+
+      case IOCTL_CONSOLE_DRAW:
+        {
+          PCONSOLE_DRAW ConsoleDraw;
+          char *Src, *Dest;
+          UINT SrcDelta, DestDelta, i, Offset;
+
+          ConsoleDraw = (PCONSOLE_DRAW) MmGetSystemAddressForMdl(Irp->MdlAddress);
+          Src = (char *) (ConsoleDraw + 1);
+          SrcDelta = ConsoleDraw->SizeX * 2;
+          Dest = DeviceExtension->VideoMemory +
+                 (ConsoleDraw->Y * DeviceExtension->Columns + ConsoleDraw->X) * 2;
+          DestDelta = DeviceExtension->Columns * 2;
+
+          for (i = 0; i < ConsoleDraw->SizeY; i++)
             {
-               COORD *pCoord;
-                LPSTR pChar;
-                char *vidmem;
-                int offset;
-                DWORD dwCount;
-               pCoord = (COORD *)MmGetSystemAddressForMdl(Irp->MdlAddress);
-               pChar = (CHAR *)(pCoord + 1);
-                vidmem = DeviceExtension->VideoMemory;
-                offset = (pCoord->Y * DeviceExtension->Columns * 2) +
-                         (pCoord->X * 2);
-
-                for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.InputBufferLength - sizeof( COORD )); dwCount++, pChar++)
-                {
-                    vidmem[offset + (dwCount * 2)] = *pChar;
-                }
-
-               Irp->IoStatus.Information = 0;
-                Status = STATUS_SUCCESS;
+              RtlCopyMemory(Dest, Src, SrcDelta);
+              Src += SrcDelta;
+              Dest += DestDelta;
             }
-            break;
 
+          Offset = (ConsoleDraw->CursorY * DeviceExtension->Columns) +
+                   ConsoleDraw->CursorX;
 
-        default:
-            Status = STATUS_NOT_IMPLEMENTED;
+          __asm__("cli\n\t");
+          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
+          WRITE_PORT_UCHAR (CRTC_DATA, Offset);
+          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
+          WRITE_PORT_UCHAR (CRTC_DATA, Offset >> 8);
+          __asm__("sti\n\t");
+
+          Irp->IoStatus.Information = 0;
+          Status = STATUS_SUCCESS;
+        }
+        break;
+
+      default:
+        Status = STATUS_NOT_IMPLEMENTED;
     }
 
-    Irp->IoStatus.Status = Status;
-    IoCompleteRequest (Irp, IO_NO_INCREMENT);
+  Irp->IoStatus.Status = Status;
+  IoCompleteRequest (Irp, IO_NO_INCREMENT);
 
-    return (Status);
+  return Status;
 }
 
 
index 55f72a7..a02b408 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.21 2003/11/13 14:20:53 ekohl Exp $
+# $Id: makefile,v 1.22 2004/01/11 17:31:14 gvg Exp $
 
 PATH_TO_TOP = ../../..
 
@@ -15,3 +15,6 @@ TARGET_CFLAGS = -Wall -Werror
 include $(PATH_TO_TOP)/rules.mak
 
 include $(TOOLS_PATH)/helper.mk
+
+DEP_OBJECTS := $(TARGET_OBJECTS)
+include $(PATH_TO_TOP)/tools/depend.mk
index 818a989..582d631 100644 (file)
 #define IOCTL_CONSOLE_READ_OUTPUT_CHARACTER     CTL_CODE(FILE_DEVICE_SCREEN, 0x821, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
 #define IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER    CTL_CODE(FILE_DEVICE_SCREEN, 0x822, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
 
-
-#define IOCTL_CONSOLE_DRAW                      CTL_CODE(FILE_DEVICE_SCREEN, 0x830, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
+#define IOCTL_CONSOLE_DRAW                      CTL_CODE(FILE_DEVICE_SCREEN, 0x830, METHOD_IN_DIRECT, FILE_WRITE_ACCESS)
 
 
 /* TYPEDEFS **************************************************************/
 
 
-typedef struct _CONSOLE_MODE
+typedef struct tagCONSOLE_MODE
 {
-    DWORD dwMode;
+  DWORD dwMode;
 } CONSOLE_MODE, *PCONSOLE_MODE;
 
 
-typedef struct _OUTPUT_ATTRIBUTE
+typedef struct tagOUTPUT_ATTRIBUTE
 {
-    WORD  wAttribute;
-    DWORD nLength;
-    COORD dwCoord;
-    DWORD dwTransfered;
+  WORD  wAttribute;
+  DWORD nLength;
+  COORD dwCoord;
+  DWORD dwTransfered;
 } OUTPUT_ATTRIBUTE, *POUTPUT_ATTRIBUTE;
 
 
-typedef struct _OUTPUT_CHARACTER
+typedef struct tagOUTPUT_CHARACTER
 {
-    CHAR  cCharacter;
-    DWORD nLength;
-    COORD dwCoord;
-    DWORD dwTransfered;
+  CHAR  cCharacter;
+  DWORD nLength;
+  COORD dwCoord;
+  DWORD dwTransfered;
 } OUTPUT_CHARACTER, *POUTPUT_CHARACTER;
 
 
-typedef struct _CONSOLE_DRAW
+typedef struct tagCONSOLE_DRAW
 {
-       SHORT   X;              /* Origin */
-       SHORT   Y;
-       SHORT   SizeX;          /* Size of the screen buffer */
-       SHORT   SizeY;
+  UINT X;       /* Origin */
+  UINT Y;
+  UINT SizeX;   /* Size of the screen buffer (chars) */
+  UINT SizeY;
+  UINT CursorX; /* New cursor position (screen-relative) */
+  UINT CursorY;
+  /* Followed by screen buffer in char/attrib format */
 } CONSOLE_DRAW, *PCONSOLE_DRAW;
 
 
index 43c7fc5..ebc61c0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: handle.c,v 1.15 2003/12/02 11:38:47 gvg Exp $
+/* $Id: handle.c,v 1.16 2004/01/11 17:31:15 gvg Exp $
  *
  * reactos/subsys/csrss/api/handle.c
  *
@@ -60,21 +60,21 @@ CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions)
 
 NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object )
 {
-   ULONG h = (((ULONG)Handle) >> 2) - 1;
-   DPRINT("CsrGetObject, Object: %x, %x, %x\n", Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0);
+  ULONG h = (((ULONG)Handle) >> 2) - 1;
+  DPRINT("CsrGetObject, Object: %x, %x, %x\n", Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0);
 
-   if (ProcessData == NULL)
-   {
+  if (ProcessData == NULL)
+    {
       return STATUS_INVALID_PARAMETER;
-   }
-   if( h >= ProcessData->HandleTableSize )
-     {
-       DPRINT("CsrGetObject returning invalid handle\n");
-       return STATUS_INVALID_HANDLE;
-     }
-   *Object = ProcessData->HandleTable[h];
-   //   DbgPrint( "CsrGetObject returning\n" );
-   return *Object ? STATUS_SUCCESS : STATUS_INVALID_HANDLE;
+    }
+  if (ProcessData->HandleTableSize <= h)
+    {
+      DPRINT1("CsrGetObject returning invalid handle\n");
+      return STATUS_INVALID_HANDLE;
+    }
+  *Object = ProcessData->HandleTable[h];
+  //   DbgPrint( "CsrGetObject returning\n" );
+  return *Object ? STATUS_SUCCESS : STATUS_INVALID_HANDLE;
 }
 
 
index d15c42b..ef36f19 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.31 2003/12/18 09:51:08 gvg Exp $
+/* $Id: process.c,v 1.32 2004/01/11 17:31:15 gvg Exp $
  *
  * reactos/subsys/csrss/api/process.c
  *
@@ -14,6 +14,7 @@
 #include <csrss/csrss.h>
 #include <ntdll/rtl.h>
 #include "api.h"
+#include "conio.h"
 
 #define NDEBUG
 #include <debug.h>
index 8b35905..7358c39 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: api.h,v 1.3 2003/12/02 11:38:46 gvg Exp $
+/* $Id: api.h,v 1.4 2004/01/11 17:31:15 gvg Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -15,8 +15,9 @@
 
 typedef struct Object_tt
 {
-   LONG Type;
-   LONG ReferenceCount;
+  LONG Type;
+  LONG ReferenceCount;
+  CRITICAL_SECTION Lock;
 } Object_t;
 
 typedef struct ConsoleInput_t
@@ -28,63 +29,7 @@ typedef struct ConsoleInput_t
   BOOLEAN NotChar;       // message should not be used to return a character
 } ConsoleInput;
 
-typedef struct CSRSS_CONSOLE_t *PCSRSS_CONSOLE;
-
-/************************************************************************
- * Screen buffer structure represents the win32 screen buffer object.   *
- * Internally, the portion of the buffer being shown CAN loop past the  *
- * bottom of the virtual buffer and wrap around to the top.  Win32 does *
- * not do this.  I decided to do this because it eliminates the need to *
- * do a massive memcpy() to scroll the contents of the buffer up to     *
- * scroll the screen on output, instead I just shift down the position  *
- * to be displayed, and let it wrap around to the top again.            *
- * The VirtualX member keeps track of the top X coord that win32        *
- * clients THINK is currently being displayed, because they think that  *
- * when the display reaches the bottom of the buffer and another line   *
- * being printed causes another line to scroll down, that the buffer IS *
- * memcpy()'s up, and the bottom of the buffer is still displayed, but  *
- * internally, I just wrap back to the top of the buffer.               *
- ***********************************************************************/
-
-typedef struct CSRSS_SCREEN_BUFFER_t
-{
-   Object_t Header;                 /* Object header */
-   BYTE *Buffer;                    /* pointer to screen buffer */
-   USHORT MaxX, MaxY;               /* size of the entire scrollback buffer */
-   USHORT ShowX, ShowY;             /* beginning offset for the actual display area */
-   ULONG CurrentX;                  /* Current X cursor position */
-   ULONG CurrentY;                  /* Current Y cursor position */
-   BYTE DefaultAttrib;              /* default char attribute */
-   USHORT VirtualX;                 /* top row of buffer being displayed, reported to callers */
-   CONSOLE_CURSOR_INFO CursorInfo;
-   USHORT Mode;
-   PCSRSS_CONSOLE Console;          /* Console this buffer is currently attached to */
-   CRITICAL_SECTION Lock;
-} CSRSS_SCREEN_BUFFER, *PCSRSS_SCREEN_BUFFER;
-
-typedef struct CSRSS_CONSOLE_t
-{
-   Object_t Header;                      /* Object header */
-   struct CSRSS_CONSOLE_t *Prev, *Next;  /* Next and Prev consoles in console wheel */
-   HANDLE ActiveEvent;
-   LIST_ENTRY InputEvents;               /* List head for input event queue */
-   WORD WaitingChars;
-   WORD WaitingLines;                    /* number of chars and lines in input queue */
-   PCSRSS_SCREEN_BUFFER ActiveBuffer;    /* Pointer to currently active screen buffer */
-   WORD Mode;                            /* Console mode flags */
-   WORD EchoCount;                       /* count of chars to echo, in line buffered mode */
-   UNICODE_STRING Title;                 /* Title of console */
-   struct {                             /* active code pages */
-          UINT Input;
-          UINT Output;
-   } CodePageId;
-   BOOL EarlyReturn;                     /* wake client and return data, even if we are in line buffered mode, and we don't have a complete line */
-   DWORD HardwareState;                  /* _GDI_MANAGED, _DIRECT */
-   HWND hWindow;
-   COORD Size;
-   PVOID GuiConsoleData;
-   LIST_ENTRY ProcessList;
-} CSRSS_CONSOLE;
+typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE;
 
 typedef struct _CSRSS_PROCESS_DATA
 {
@@ -157,11 +102,6 @@ VOID Console_Api( DWORD Ignored );
 extern HANDLE CsrssApiHeap;
 
 /* api/conio.c */
-NTSTATUS STDCALL CsrInitConsole(PCSRSS_CONSOLE Console);
-NTSTATUS STDCALL CsrInitConsoleScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer,
-                                            PCSRSS_CONSOLE Console,
-                                            unsigned Width,
-                                            unsigned Height);
 VOID STDCALL CsrInitConsoleSupport(VOID);
 
 /* api/process.c */
@@ -177,10 +117,7 @@ BOOL STDCALL CsrServerInitialization (ULONG ArgumentCount, PWSTR *ArgumentArray)
 NTSTATUS STDCALL CsrReleaseObjectByPointer(Object_t *Object);
 NTSTATUS STDCALL CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object );
 NTSTATUS STDCALL CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object );
-VOID STDCALL CsrDrawConsole(PCSRSS_CONSOLE Console);
-NTSTATUS CsrpEchoUnicodeChar( PCSRSS_SCREEN_BUFFER Console, 
-                             WCHAR UnicodeChar );
-NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWORD Length, BOOL Attrib );
+
 CSR_API(CsrGetInputHandle);
 CSR_API(CsrGetOutputHandle);
 CSR_API(CsrCloseHandle);
index a0ab381..d4466ba 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: conio.h,v 1.1 2003/12/02 11:38:46 gvg Exp $
+/* $Id: conio.h,v 1.2 2004/01/11 17:31:15 gvg Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
 #define CONIO_H_INCLUDED
 
 #include "api.h"
+#include "win32csr.h"
 
 /* Object type magic numbers */
 
 #define CONIO_CONSOLE_MAGIC         0x00000001
 #define CONIO_SCREEN_BUFFER_MAGIC   0x00000002
 
+/************************************************************************
+ * Screen buffer structure represents the win32 screen buffer object.   *
+ * Internally, the portion of the buffer being shown CAN loop past the  *
+ * bottom of the virtual buffer and wrap around to the top.  Win32 does *
+ * not do this.  I decided to do this because it eliminates the need to *
+ * do a massive memcpy() to scroll the contents of the buffer up to     *
+ * scroll the screen on output, instead I just shift down the position  *
+ * to be displayed, and let it wrap around to the top again.            *
+ * The VirtualX member keeps track of the top X coord that win32        *
+ * clients THINK is currently being displayed, because they think that  *
+ * when the display reaches the bottom of the buffer and another line   *
+ * being printed causes another line to scroll down, that the buffer IS *
+ * memcpy()'s up, and the bottom of the buffer is still displayed, but  *
+ * internally, I just wrap back to the top of the buffer.               *
+ ***********************************************************************/
+
+typedef struct tagCSRSS_SCREEN_BUFFER
+{
+  Object_t Header;                 /* Object header */
+  BYTE *Buffer;                    /* pointer to screen buffer */
+  USHORT MaxX, MaxY;               /* size of the entire scrollback buffer */
+  USHORT ShowX, ShowY;             /* beginning offset for the actual display area */
+  ULONG CurrentX;                  /* Current X cursor position */
+  ULONG CurrentY;                  /* Current Y cursor position */
+  BYTE DefaultAttrib;              /* default char attribute */
+  USHORT VirtualX;                 /* top row of buffer being displayed, reported to callers */
+  CONSOLE_CURSOR_INFO CursorInfo;
+  USHORT Mode;
+} CSRSS_SCREEN_BUFFER, *PCSRSS_SCREEN_BUFFER;
+
+typedef struct tagCSRSS_CONSOLE_VTBL
+{
+  VOID (STDCALL *InitScreenBuffer)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer);
+  VOID (STDCALL *WriteStream)(PCSRSS_CONSOLE Console, RECT *Block, UINT CursorStartX, UINT CursorStartY,
+                              UINT ScrolledLines, CHAR *Buffer, UINT Length);
+  VOID (STDCALL *DrawRegion)(PCSRSS_CONSOLE Console, RECT *Region);
+  BOOL (STDCALL *SetCursorInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer);
+  BOOL (STDCALL *SetScreenInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer,
+                                UINT OldCursorX, UINT OldCursorY);
+  BOOL (STDCALL *ChangeTitle)(PCSRSS_CONSOLE Console);
+  VOID (STDCALL *CleanupConsole)(PCSRSS_CONSOLE Console);
+} CSRSS_CONSOLE_VTBL, *PCSRSS_CONSOLE_VTBL;
+
+typedef struct tagCSRSS_CONSOLE
+{
+  Object_t Header;                      /* Object header */
+  PCSRSS_CONSOLE Prev, Next;            /* Next and Prev consoles in console wheel */
+  HANDLE ActiveEvent;
+  LIST_ENTRY InputEvents;               /* List head for input event queue */
+  WORD WaitingChars;
+  WORD WaitingLines;                    /* number of chars and lines in input queue */
+  PCSRSS_SCREEN_BUFFER ActiveBuffer;    /* Pointer to currently active screen buffer */
+  WORD Mode;                            /* Console mode flags */
+  WORD EchoCount;                       /* count of chars to echo, in line buffered mode */
+  UNICODE_STRING Title;                 /* Title of console */
+  struct                               /* active code pages */
+    {
+      UINT Input;
+      UINT Output;
+    } CodePageId;
+  BOOL EarlyReturn;                     /* wake client and return data, even if we are in line buffered mode, and we don't have a complete line */
+  DWORD HardwareState;                  /* _GDI_MANAGED, _DIRECT */
+  HWND hWindow;
+  COORD Size;
+  PVOID PrivateData;
+  PCSRSS_CONSOLE_VTBL Vtbl;
+  LIST_ENTRY ProcessList;
+} CSRSS_CONSOLE;
+
 VOID STDCALL ConioDeleteConsole(Object_t *Object);
 VOID STDCALL ConioDeleteScreenBuffer(Object_t *Buffer);
-void STDCALL CsrProcessKey(MSG *msg, PCSRSS_CONSOLE Console);
+void STDCALL ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode);
+void FASTCALL ConioPhysicalToLogical(PCSRSS_SCREEN_BUFFER Buff,
+                                     ULONG PhysicalX,
+                                     ULONG PhysicalY,
+                                     LONG *LogicalX,
+                                     LONG *LogicalY);
+VOID FASTCALL ConioDrawConsole(PCSRSS_CONSOLE Console);
 
 /* api/conio.c */
 CSR_API(CsrWriteConsole);
@@ -54,6 +130,31 @@ CSR_API(CsrWriteConsoleInput);
 CSR_API(CsrHardwareStateProperty);
 CSR_API(CsrGetConsoleWindow);
 
+#define ConioInitScreenBuffer(Console, Buff) (Console)->Vtbl->InitScreenBuffer((Console), (Buff))
+#define ConioDrawRegion(Console, Region) (Console)->Vtbl->DrawRegion((Console), (Region))
+#define ConioWriteStream(Console, Block, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \
+          (Console)->Vtbl->WriteStream((Console), (Block), (CurStartX), (CurStartY), \
+                                       (ScrolledLines), (Buffer), (Length))
+#define ConioSetCursorInfo(Console, Buff) (Console)->Vtbl->SetCursorInfo((Console), (Buff))
+#define ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY) \
+          (Console)->Vtbl->SetScreenInfo((Console), (Buff), (OldCursorX), (OldCursorY))
+#define ConioChangeTitle(Console) (Console)->Vtbl->ChangeTitle(Console)
+#define ConioCleanupConsole(Console) (Console)->Vtbl->CleanupConsole(Console)
+
+#define ConioRectHeight(Rect) \
+    (((Rect)->top) > ((Rect)->bottom) ? 0 : ((Rect)->bottom) - ((Rect)->top) + 1)
+#define ConioRectWidth(Rect) \
+    (((Rect)->left) > ((Rect)->right) ? 0 : ((Rect)->right) - ((Rect)->left) + 1)
+
+#define ConioLockConsole(ProcessData, Handle, Ptr) \
+    Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), CONIO_CONSOLE_MAGIC)
+#define ConioUnlockConsole(Console) \
+    Win32CsrUnlockObject((Object_t *) Console)
+#define ConioLockScreenBuffer(ProcessData, Handle, Ptr) \
+    Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), CONIO_SCREEN_BUFFER_MAGIC)
+#define ConioUnlockScreenBuffer(Buff) \
+    Win32CsrUnlockObject((Object_t *) Buff)
+
 #endif /* CONIO_H_INCLUDED */
 
 /* EOF */
index 7d32251..1a8cdc8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: desktopbg.h,v 1.1 2003/12/07 23:02:57 gvg Exp $
+/* $Id: desktopbg.h,v 1.2 2004/01/11 17:31:15 gvg Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -16,6 +16,8 @@ CSR_API(CsrCreateDesktop);
 CSR_API(CsrShowDesktop);
 CSR_API(CsrHideDesktop);
 
+BOOL FASTCALL DtbgIsDesktopVisible(VOID);
+
 #endif /* DESKTOPBG_H_INCLUDED */
 
 /* EOF */
index d85bf01..efb827d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: win32csr.h,v 1.1 2003/12/02 11:38:46 gvg Exp $
+/* $Id: win32csr.h,v 1.2 2004/01/11 17:31:15 gvg Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -6,6 +6,10 @@
  * PURPOSE:         Interface to win32csr.dll
  */
 
+
+#ifndef WIN32CSR_H_INCLUDED
+#define WIN32CSR_H_INCLUDED
+
 #include <windows.h>
 
 extern HANDLE Win32CsrApiHeap;
@@ -13,8 +17,20 @@ extern HANDLE Win32CsrApiHeap;
 NTSTATUS FASTCALL Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData,
                                        PHANDLE Handle,
                                        Object_t *Object);
+NTSTATUS FASTCALL Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData,
+                                     HANDLE Handle,
+                                     Object_t **Object,
+                                     long Type);
+VOID FASTCALL Win32CsrUnlockObject(Object_t *Object);
+
+#ifndef TODO
 NTSTATUS FASTCALL Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData,
                                     HANDLE Handle,
                                     Object_t **Object);
 NTSTATUS FASTCALL Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
                                         HANDLE Object);
+#endif
+
+#endif /* WIN32CSR_H_INCLUDED */
+
+/* EOF */
index e6332ea..084a56b 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.2 2003/12/07 23:02:57 gvg Exp $
+# $Id: Makefile,v 1.3 2004/01/11 17:31:15 gvg Exp $
 
 PATH_TO_TOP = ../../..
 
@@ -15,7 +15,7 @@ TARGET_LFLAGS = -nostartfiles -nostdlib
 
 TARGET_SDKLIBS = ntdll.a kernel32.a user32.a gdi32.a
 
-TARGET_OBJECTS = dllmain.o conio.o guiconsole.o desktopbg.o
+TARGET_OBJECTS = dllmain.o conio.o desktopbg.o guiconsole.o tuiconsole.o
 
 TARGET_ENTRY = _DllMain@12
 
index 27cef02..362abf7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: conio.c,v 1.2 2003/12/18 09:51:08 gvg Exp $
+/* $Id: conio.c,v 1.3 2004/01/11 17:31:16 gvg Exp $
  *
  * reactos/subsys/csrss/win32csr/conio.c
  *
 #include <rosrtl/minmax.h>
 #include "api.h"
 #include "conio.h"
+#include "desktopbg.h"
 #include "guiconsole.h"
+#include "tuiconsole.h"
 #include "win32csr.h"
 
 #define NDEBUG
 #include <debug.h>
 
-#define LOCK   RtlEnterCriticalSection(&ActiveConsoleLock)
-#define UNLOCK RtlLeaveCriticalSection(&ActiveConsoleLock)
-
 /* FIXME: Is there a way to create real aliasses with gcc? [CSH] */
 #define ALIAS(Name, Target) typeof(Target) Name = Target
-extern VOID CsrConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData);
 
 /* Private user32 routines for CSRSS, not defined in any header file */
 extern VOID STDCALL PrivateCsrssRegisterPrimitive(VOID);
@@ -39,235 +37,189 @@ extern VOID STDCALL PrivateCsrssAcquireOrReleaseInputOwnership(BOOL Release);
 
 /* GLOBALS *******************************************************************/
 
-static HANDLE ConsoleDeviceHandle;
-static PCSRSS_CONSOLE ActiveConsole;
-CRITICAL_SECTION ActiveConsoleLock;
-static COORD PhysicalConsoleSize;
-static BOOL TextMode = TRUE;
-static BOOL GuiConsolesInitialized = FALSE;
-
-#define CsrpInitRect(_Rect, _Top, _Left, _Bottom, _Right) \
-{ \
-  ((_Rect).Top) = _Top; \
-  ((_Rect).Left) = _Left; \
-  ((_Rect).Bottom) = _Bottom; \
-  ((_Rect).Right) = _Right; \
-}
-
-#define CsrpRectHeight(Rect) \
-    ((Rect.Top) > (Rect.Bottom) ? 0 : (Rect.Bottom) - (Rect.Top) + 1)
-
-#define CsrpRectWidth(Rect) \
-    ((Rect.Left) > (Rect.Right) ? 0 : (Rect.Right) - (Rect.Left) + 1)
+#define ConioInitRect(Rect, Top, Left, Bottom, Right) \
+  ((Rect)->top) = Top; \
+  ((Rect)->left) = Left; \
+  ((Rect)->bottom) = Bottom; \
+  ((Rect)->right) = Right
 
-#define CsrpIsRectEmpty(Rect) \
-  ((Rect.Left > Rect.Right) || (Rect.Top > Rect.Bottom))
+#define ConioIsRectEmpty(Rect) \
+  (((Rect)->left > (Rect)->right) || ((Rect)->top > (Rect)->bottom))
 
 /* FUNCTIONS *****************************************************************/
 
-/* Text (blue screen) console support ****************************************/
-
-static BOOL FASTCALL
-CsrInitTextConsoleSupport(VOID)
+STATIC NTSTATUS FASTCALL
+ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console)
 {
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING DeviceName;
-  NTSTATUS Status;
-  IO_STATUS_BLOCK Iosb;
-  CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
-   
-  RtlRosInitUnicodeStringFromLiteral(&DeviceName, L"\\??\\BlueScreen");
-  InitializeObjectAttributes(&ObjectAttributes,
-                             &DeviceName,
-                             0,
-                             NULL,
-                             NULL);
-  Status = NtOpenFile(&ConsoleDeviceHandle,
-                      FILE_ALL_ACCESS,
-                      &ObjectAttributes,
-                      &Iosb,
-                      0,
-                      FILE_SYNCHRONOUS_IO_ALERT);
-  if (! NT_SUCCESS(Status))
-    {
-      DPRINT1("CSR: Failed to open console. Expect problems.\n");
-      return FALSE;
-    }
-
-  ActiveConsole = 0;
-  RtlInitializeCriticalSection(&ActiveConsoleLock);
-  Status = NtDeviceIoControlFile(ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO, 0, 0, &ScrInfo, sizeof(ScrInfo));
-  if (! NT_SUCCESS(Status))
+  if (NULL == ProcessData->Console)
     {
-      DPRINT1("CSR: Failed to get console info, expect trouble\n");
-      return FALSE;
+      *Console = NULL;
+      return STATUS_SUCCESS;
     }
-  PhysicalConsoleSize = ScrInfo.dwSize;
-
-  return TRUE;
-}
-
-/*
- * Screen buffer must be locked when this function is called
- */
-inline NTSTATUS CsrpSetConsoleDeviceCursor(PCSRSS_SCREEN_BUFFER ScreenBuffer, SHORT X, SHORT Y)
-{
-   CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
-   IO_STATUS_BLOCK Iosb;
 
-   ScrInfo.dwCursorPosition.X = X;
-   ScrInfo.dwCursorPosition.Y = Y;
-   ScrInfo.wAttributes = ScreenBuffer->DefaultAttrib;
+  EnterCriticalSection(&(ProcessData->Console->Header.Lock));
+  *Console = ProcessData->Console;
 
-   return NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
-     IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, &ScrInfo, sizeof( ScrInfo ), 0, 0 );
+  return STATUS_SUCCESS;
 }
 
-static VOID FASTCALL
-CsrTextConsoleDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT Region)
+STATIC VOID FASTCALL
+CsrConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData)
 {
-  IO_STATUS_BLOCK Iosb;
-  NTSTATUS Status;
-  CONSOLE_MODE Mode;
-  int i, y;
-  DWORD BytesPerLine;
-  DWORD SrcOffset;
-  DWORD SrcDelta;
-  PCSRSS_SCREEN_BUFFER ScreenBuffer = Console->ActiveBuffer;
-
-  Mode.dwMode = 0; /* clear ENABLE_PROCESSED_OUTPUT mode */
-  Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
-    IOCTL_CONSOLE_SET_MODE, &Mode, sizeof( Mode ), 0, 0 );
-  if( !NT_SUCCESS( Status ) )
-    {
-      DbgPrint( "CSR: Failed to set console mode\n" );
-      return;
-    }
+  HANDLE Process, Thread;
+       
+  DPRINT("CsrConsoleCtrlEvent Parent ProcessId = %x\n",        ClientId.UniqueProcess);
 
-  /* blast out buffer */
-  BytesPerLine = CsrpRectWidth(Region) * 2;
-  SrcOffset = (((Region.Top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY) * ScreenBuffer->MaxX + Region.Left + ScreenBuffer->ShowX) * 2;
-  SrcDelta = ScreenBuffer->MaxX * 2;
-  for( i = Region.Top, y = ScreenBuffer->ShowY; i <= Region.Bottom; i++ )
+  if (ProcessData->CtrlDispatcher)
     {
-      /* Position the cursor correctly */
-      Status = CsrpSetConsoleDeviceCursor(ScreenBuffer, Region.Left, i);
-      if( !NT_SUCCESS( Status ) )
+      Process = OpenProcess(PROCESS_DUP_HANDLE, FALSE, ProcessData->ProcessId);
+      if (NULL == Process)
         {
-          DbgPrint( "CSR: Failed to set console info\n" );
+          DPRINT1("Failed for handle duplication\n");
           return;
         }
 
-      Status = NtWriteFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
-        &ScreenBuffer->Buffer[ SrcOffset ],
-        BytesPerLine, 0, 0 );
-      if( !NT_SUCCESS( Status ) )
-        {
-          DbgPrint( "CSR: Write to console failed\n" );
-          return;
-        }
+      DPRINT("CsrConsoleCtrlEvent Process Handle = %x\n", Process);
 
-      /* wrap back around the end of the buffer */
-      if( ++y == ScreenBuffer->MaxY )
-        {
-          y = 0;
-          SrcOffset = (Region.Left + ScreenBuffer->ShowX) * 2;
-        }
-      else
+      Thread = CreateRemoteThread(Process, NULL, 0,
+                                  (LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher,
+                                  (PVOID) Event, 0, NULL);
+      if (NULL == Thread)
         {
-          SrcOffset += SrcDelta;
+          DPRINT1("Failed thread creation\n");
+          CloseHandle(Process);
+          return;
         }
-    }
-  Mode.dwMode = ENABLE_PROCESSED_OUTPUT;
-  Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
-    IOCTL_CONSOLE_SET_MODE, &Mode, sizeof( Mode ), 0, 0 );
-  if( !NT_SUCCESS( Status ) )
-    {
-      DbgPrint( "CSR: Failed to set console mode\n" );
-      return;
-    }
-  Status = CsrpSetConsoleDeviceCursor(
-    ScreenBuffer,
-    ScreenBuffer->CurrentX - ScreenBuffer->ShowX,
-    ((ScreenBuffer->CurrentY + ScreenBuffer->MaxY) - ScreenBuffer->ShowY) % ScreenBuffer->MaxY);
-  if( !NT_SUCCESS( Status ) )
-    {
-      DbgPrint( "CSR: Failed to set console info\n" );
-      return;
-    }
-  Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
-    IOCTL_CONSOLE_SET_CURSOR_INFO, &ScreenBuffer->CursorInfo,
-    sizeof( ScreenBuffer->CursorInfo ), 0, 0 );
-  if( !NT_SUCCESS( Status ) )
-    {
-      DbgPrint( "CSR: Failed to set cursor info\n" );
-      return;
+      CloseHandle(Thread);
+      CloseHandle(Process);
     }
 }
 
-/* Graphics console support **************************************************/
+#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);
 
 static VOID FASTCALL
-CsrInitGraphicsConsoleSupport(VOID)
+ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff)
 {
-  RtlInitializeCriticalSection(&ActiveConsoleLock);
-  GuiConsolesInitialized = FALSE;
+  DWORD Offset = 2 * (Buff->CurrentY * Buff->MaxX);
+  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)
+    }
 }
 
-/*
- * Region - Region of virtual screen buffer to draw onto the physical console
- * Screen buffer must be locked when this function is called
- */
-static VOID CsrpDrawRegion(
-  PCSRSS_CONSOLE Console,
-  SMALL_RECT Region)
+STATIC NTSTATUS FASTCALL
+CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
+                           PCSRSS_SCREEN_BUFFER Buffer)
 {
-  if (TextMode)
+  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);
+  if (NULL == Buffer->Buffer)
     {
-      CsrTextConsoleDrawRegion(Console, Region);
+      return STATUS_INSUFFICIENT_RESOURCES;
     }
-  else
+  ConioInitScreenBuffer(Console, Buffer);
+  /* initialize buffer to be empty with default attributes */
+  for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++)
     {
-      GuiConsoleDrawRegion(Console, Region);
+      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;
+}
 
-VOID CsrConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData)
+STATIC NTSTATUS STDCALL
+CsrInitConsole(PCSRSS_CONSOLE Console)
 {
-    HANDLE Process, hThread;
-    NTSTATUS Status;
-    CLIENT_ID ClientId, ClientId1;
-       
-    DPRINT1("CsrConsoleCtrlEvent Parent ProcessId = %x\n",     ClientId.UniqueProcess);
+  NTSTATUS Status;
+  SECURITY_ATTRIBUTES SecurityAttributes;
+  PCSRSS_SCREEN_BUFFER NewBuffer;
+  BOOL GuiMode;
 
-    if (ProcessData->CtrlDispatcher)
-    {
-       ClientId.UniqueProcess = (HANDLE) ProcessData->ProcessId;
-       Status = NtOpenProcess( &Process, PROCESS_DUP_HANDLE, 0, &ClientId );
-       if( !NT_SUCCESS( Status ) )
-       {
-           DPRINT("CsrConsoleCtrlEvent: Failed for handle duplication\n");
-           return;
-       }
+  Console->Title.MaximumLength = Console->Title.Length = 0;
+  Console->Title.Buffer = NULL;
+  
+  RtlCreateUnicodeString(&Console->Title, L"Command Prompt");
+  
+  Console->Header.ReferenceCount = 0;
+  Console->WaitingChars = 0;
+  Console->WaitingLines = 0;
+  Console->EchoCount = 0;
+  Console->Header.Type = CONIO_CONSOLE_MAGIC;
+  Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
+  Console->EarlyReturn = FALSE;
+  Console->ActiveBuffer = NULL;
+  InitializeListHead(&Console->InputEvents);
+  InitializeListHead(&Console->ProcessList);
 
-       DPRINT1("CsrConsoleCtrlEvent Process Handle = %x\n", Process);
+  SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+  SecurityAttributes.lpSecurityDescriptor = NULL;
+  SecurityAttributes.bInheritHandle = TRUE;
 
+  Console->ActiveEvent = CreateEventW(&SecurityAttributes, FALSE, FALSE, NULL);
+  if (NULL == Console->ActiveEvent)
+    {
+      return STATUS_UNSUCCESSFUL;
+    }
+  Console->PrivateData = NULL;
+  GuiMode = DtbgIsDesktopVisible();
+  if (! GuiMode)
+    {
+      Status = TuiInitConsole(Console);
+      if (! NT_SUCCESS(Status))
+        {
+          DPRINT1("Failed to open text-mode console, switching to gui-mode\n");
+          GuiMode = TRUE;
+        }
+    }
+  if (GuiMode)
+    {
+      Status = GuiInitConsole(Console);
+      if (! NT_SUCCESS(Status))
+        {
+          CloseHandle(Console->ActiveEvent);
+          return Status;
+        }
+    }
 
-       Status = RtlCreateUserThread(Process, NULL, FALSE, 0, NULL, NULL,
-                                   (PTHREAD_START_ROUTINE)ProcessData->CtrlDispatcher,
-                                   (PVOID) Event, &hThread, &ClientId1);
-       if( !NT_SUCCESS( Status ) )
-       {
-           DPRINT("CsrConsoleCtrlEvent: Failed Thread creation\n");
-           NtClose(Process);
-           return;
-       }
-       DPRINT1("CsrConsoleCtrlEvent Parent ProcessId = %x, ReturnPId = %x, hT = %x\n",
-               ClientId.UniqueProcess, ClientId1.UniqueProcess, hThread);
-       NtClose(hThread);
-       NtClose(Process);
+  NewBuffer = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_SCREEN_BUFFER));
+  if (NULL == NewBuffer)
+    {
+      CloseHandle(Console->ActiveEvent);
+      return STATUS_INSUFFICIENT_RESOURCES;
+    }
+  Status = CsrInitConsoleScreenBuffer(Console, NewBuffer);
+  if (! NT_SUCCESS(Status))
+    {
+      CloseHandle(Console->ActiveEvent);
+      HeapFree(Win32CsrApiHeap, 0, NewBuffer);
+      return Status;
     }
+  Console->ActiveBuffer = NewBuffer;
+  /* add a reference count because the buffer is tied to the console */
+  Console->ActiveBuffer->Header.ReferenceCount++;
+  /* make console active, and insert into console list */
+  /* copy buffer contents to screen */
+  ConioDrawConsole(Console);
+
+  return STATUS_SUCCESS;
 }
 
 
@@ -276,7 +228,6 @@ CSR_API(CsrAllocConsole)
   PCSRSS_CONSOLE Console;
   HANDLE Process;
   NTSTATUS Status;
-  CLIENT_ID ClientId;
 
   DPRINT("CsrAllocConsole\n");
 
@@ -285,7 +236,7 @@ CSR_API(CsrAllocConsole)
 
   if (ProcessData == NULL)
     {
-      return(Reply->Status = STATUS_INVALID_PARAMETER);
+      return Reply->Status = STATUS_INVALID_PARAMETER;
     }
 
   if (ProcessData->Console)
@@ -294,14 +245,8 @@ CSR_API(CsrAllocConsole)
       return STATUS_INVALID_PARAMETER;
     }
 
-  if (! GuiConsolesInitialized && ! TextMode)
-    {
-      GuiConsoleInitConsoleSupport();
-      GuiConsolesInitialized = TRUE;
-    }
-
   Reply->Status = STATUS_SUCCESS;
-  Console = RtlAllocateHeap( Win32CsrApiHeap, 0, sizeof( CSRSS_CONSOLE ) );
+  Console = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_CONSOLE));
   if (NULL == Console)
     {
       Reply->Status = STATUS_NO_MEMORY;
@@ -310,7 +255,7 @@ CSR_API(CsrAllocConsole)
   Reply->Status = CsrInitConsole(Console);
   if (! NT_SUCCESS(Reply->Status))
     {
-      RtlFreeHeap(Win32CsrApiHeap, 0, Console);
+      HeapFree(Win32CsrApiHeap, 0, Console);
       return Reply->Status;
     }
   ProcessData->Console = Console;
@@ -334,11 +279,10 @@ CSR_API(CsrAllocConsole)
       return Reply->Status = Status;
     }
 
-  ClientId.UniqueProcess = (HANDLE) ProcessData->ProcessId;
-  Status = NtOpenProcess(&Process, PROCESS_DUP_HANDLE, 0, &ClientId);
-  if (! NT_SUCCESS(Status))
+  Process = OpenProcess(PROCESS_DUP_HANDLE, FALSE, ProcessData->ProcessId);
+  if (NULL == Process)
     {
-      DbgPrint( "CSR: NtOpenProcess() failed for handle duplication\n" );
+      DPRINT1("OpenProcess() failed for handle duplication\n");
       Console->Header.ReferenceCount--;
       ProcessData->Console = 0;
       Win32CsrReleaseObject(ProcessData, Reply->Data.AllocConsoleReply.OutputHandle);
@@ -346,11 +290,11 @@ CSR_API(CsrAllocConsole)
       Reply->Status = Status;
       return Status;
     }
-  Status = NtDuplicateObject(NtCurrentProcess(), ProcessData->Console->ActiveEvent, Process, &ProcessData->ConsoleEvent, SYNCHRONIZE, FALSE, 0);
-  if (! NT_SUCCESS(Status))
+  if (! DuplicateHandle(GetCurrentProcess(), ProcessData->Console->ActiveEvent,
+                        Process, &ProcessData->ConsoleEvent, EVENT_ALL_ACCESS, FALSE, 0))
     {
-      DbgPrint( "CSR: NtDuplicateObject() failed: %x\n", Status );
-      NtClose(Process);
+      DPRINT1("DuplicateHandle() failed: %d\n", GetLastError);
+      CloseHandle(Process);
       Console->Header.ReferenceCount--;
       Win32CsrReleaseObject(ProcessData, Reply->Data.AllocConsoleReply.OutputHandle);
       Win32CsrReleaseObject(ProcessData, Reply->Data.AllocConsoleReply.InputHandle);
@@ -358,324 +302,167 @@ CSR_API(CsrAllocConsole)
       Reply->Status = Status;
       return Status;
     }
-  NtClose(Process);
-  LOCK;
+  CloseHandle(Process);
   ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher;
   DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);      
   InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry);
-  UNLOCK;
 
   return STATUS_SUCCESS;
 }
 
 CSR_API(CsrFreeConsole)
 {
-   PCSRSS_CONSOLE Console;
-
-   DPRINT("CsrFreeConsole\n");
-
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
-     sizeof(LPC_MESSAGE);
-
-   LOCK;
-   if (ProcessData == NULL || ProcessData->Console == NULL)
-   {
-     UNLOCK;
-     return(Reply->Status = STATUS_INVALID_PARAMETER);
-   }
-
-   Console = ProcessData->Console;
-   Console->Header.ReferenceCount--;
-     ProcessData->Console = 0;
-   if( Console->Header.ReferenceCount == 0 ) {
-     if( Console != ActiveConsole ) 
-       ConioDeleteConsole((Object_t *) Console);
-   }
-
-   UNLOCK;
-   
-   return(STATUS_SUCCESS);
-}
-
-CSR_API(CsrReadConsole)
-{
-   PLIST_ENTRY CurrentEntry;
-   ConsoleInput *Input;
-   PCHAR Buffer;
-   int   i = 0;
-   ULONG nNumberOfCharsToRead;
-   PCSRSS_CONSOLE Console;
-   NTSTATUS Status;
-   
-   DPRINT("CsrReadConsole\n");
-
-  /* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */
-   nNumberOfCharsToRead = Request->Data.ReadConsoleRequest.NrCharactersToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : Request->Data.ReadConsoleRequest.NrCharactersToRead;
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = Reply->Header.MessageSize -
-     sizeof(LPC_MESSAGE);
-
-   Buffer = Reply->Data.ReadConsoleReply.Buffer;
-   LOCK;   
-   Status = Win32CsrGetObject( ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle, (Object_t **)&Console );
-   if( !NT_SUCCESS( Status ) )
-      {
-        Reply->Status = Status;
-        UNLOCK;
-        return Status;
-      }
-   if( Console->Header.Type != CONIO_CONSOLE_MAGIC )
-      {
-        Reply->Status = STATUS_INVALID_HANDLE;
-        UNLOCK;
-        return STATUS_INVALID_HANDLE;
-      }
-   Reply->Data.ReadConsoleReply.EventHandle = ProcessData->ConsoleEvent;
-   for (; i<nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++ )     
-      {
-        // remove input event from queue
-        CurrentEntry = RemoveHeadList(&Console->InputEvents);
-        Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
-
-        // only pay attention to valid ascii chars, on key down
-        if( Input->InputEvent.EventType == KEY_EVENT &&
-            Input->InputEvent.Event.KeyEvent.bKeyDown == TRUE &&
-            Input->InputEvent.Event.KeyEvent.uChar.AsciiChar )
-           {
-              // backspace handling
-              if( Input->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\b' )
-                 {
-                    // echo if it has not already been done, and either we or the client has chars to be deleted
-                    if( !Input->Echoed && ( i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted ) )
-                       CsrpWriteConsole( Console->ActiveBuffer, &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE );
-                    if( i )
-                       i-=2;        // if we already have something to return, just back it up by 2
-                    else
-                       {            // otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer
-                          Reply->Data.ReadConsoleReply.NrCharactersRead = 0;
-                          Reply->Status = STATUS_NOTIFY_CLEANUP;
-                          Console->WaitingChars--;
-                          RtlFreeHeap( Win32CsrApiHeap, 0, Input );
-                          UNLOCK;
-                          return STATUS_NOTIFY_CLEANUP;
-                       }
-                    Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--;
-                    Input->Echoed = TRUE;   // mark as echoed so we don't echo it below
-                 }
-              // do not copy backspace to buffer
-              else {
-                 Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar;
-               }
-              // echo to screen if enabled and we did not already echo the char
-              if( Console->Mode & ENABLE_ECHO_INPUT &&
-                  !Input->Echoed &&
-                  Input->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\r' )
-                 CsrpWriteConsole( Console->ActiveBuffer, &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE );
-           }
-        else i--;
-        Console->WaitingChars--;
-        RtlFreeHeap( Win32CsrApiHeap, 0, Input );
-      }
-   Reply->Data.ReadConsoleReply.NrCharactersRead = i;
-   if( !i )
-      Reply->Status = STATUS_PENDING;    // we didn't read anything
-   else if( Console->Mode & ENABLE_LINE_INPUT )
-      if( !Console->WaitingLines || Buffer[i-1] != '\n' )
-        {
-           Reply->Status = STATUS_PENDING; // line buffered, didn't get a complete line
-        }
-      else {
-        Console->WaitingLines--;
-        Reply->Status = STATUS_SUCCESS; // line buffered, did get a complete line
-      }
-   else Reply->Status = STATUS_SUCCESS;  // not line buffered, did read something
-   if( Reply->Status == STATUS_PENDING )
-      {
-        Console->EchoCount = nNumberOfCharsToRead - i;
-      }
-   else {
-      Console->EchoCount = 0;             // if the client is no longer waiting on input, do not echo
-   }
-   Reply->Header.MessageSize += i;
-   UNLOCK;
-   return Reply->Status;
-}
-
-void FASTCALL
-CsrpPhysicalToLogical(PCSRSS_SCREEN_BUFFER Buff,
-                      ULONG PhysicalX,
-                      ULONG PhysicalY,
-                      SHORT *LogicalX,
-                      SHORT *LogicalY)
-{
-   *LogicalX = PhysicalX;
-   if (PhysicalY < Buff->ShowY)
-     {
-       *LogicalY = Buff->MaxY - Buff->ShowY + PhysicalY;
-     }
-   else
-     {
-       *LogicalY = PhysicalY - Buff->ShowY;
-     }
-}
+  PCSRSS_CONSOLE Console;
 
-#define GET_CELL_BUFFER(b,o)\
-(b)->Buffer[(o)++];
+  DPRINT("CsrFreeConsole\n");
 
-#define SET_CELL_BUFFER(b,o,c,a)\
-(b)->Buffer[(o)++]=(c);\
-(b)->Buffer[(o)++]=(a);
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
 
-static VOID FASTCALL
-ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff, DWORD StartX, BOOL Redraw)
-{
-  DWORD Offset   = 2 * ((Buff->CurrentY * Buff->MaxX) + StartX);
-  SMALL_RECT UpdateRect;
-       
-  CsrpPhysicalToLogical(Buff, StartX, Buff->CurrentY, &(UpdateRect.Left),
-                        &(UpdateRect.Top));
-  for ( ; StartX < Buff->MaxX; StartX ++)
+  if (ProcessData == NULL || ProcessData->Console == NULL)
     {
-      /* Fill the cell: Offset is incremented by the macro */
-      SET_CELL_BUFFER(Buff, Offset, ' ', Buff->DefaultAttrib)
+      return Reply->Status = STATUS_INVALID_PARAMETER;
     }
 
-  if (! TextMode && Redraw && NULL != Buff->Console)
+  Console = ProcessData->Console;
+  Console->Header.ReferenceCount--;
+  ProcessData->Console = NULL;
+  if (0 == Console->Header.ReferenceCount)
     {
-      CsrpPhysicalToLogical(Buff, Buff->MaxX - 1, Buff->CurrentY, &(UpdateRect.Right),
-                            &(UpdateRect.Bottom));
-      CsrpDrawRegion(Buff->Console, UpdateRect);
+      ConioDeleteConsole((Object_t *) Console);
     }
+   
+  return STATUS_SUCCESS;
 }
 
-static VOID FASTCALL
-CsrpScrollUpOneLine(PCSRSS_CONSOLE Console)
+STATIC VOID FASTCALL
+ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines)
 {
-  RECT Source, Dest;
-
-  if (! TextMode)
+  /* slide the viewable screen */
+  if (((Buff->CurrentY - Buff->ShowY + Buff->MaxY) % Buff->MaxY) == Buff->MaxY - 1)
     {
-      Source.top = 1;
-      Source.left = 0;
-      Source.bottom = Console->Size.Y - 1;
-      Source.right = Console->Size.X - 1;
-      Dest.top = 0;
-      Dest.left = 0;
-      Dest.bottom = Console->Size.Y - 2;
-      Dest.right = Console->Size.X - 1;
-
-      GuiConsoleCopyRegion(Console, &Source, &Dest);
+      if (++Buff->ShowY == Buff->MaxY)
+        {
+          Buff->ShowY = 0;
+        }
+      (*ScrolledLines)++;
+    }
+  if (++Buff->CurrentY == Buff->MaxY)
+    {
+      Buff->CurrentY = 0;
+    }
+  ClearLineBuffer(Buff);
+  UpdateRect->left = 0;
+  UpdateRect->right = Buff->MaxX - 1;
+  if (UpdateRect->top == Buff->CurrentY)
+    {
+      if (++UpdateRect->top == Buff->MaxY)
+        {
+          UpdateRect->top = 0;
+        }
     }
+  UpdateRect->bottom = Buff->CurrentY;
 }
 
-NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWORD Length, BOOL Attrib )
+STATIC NTSTATUS FASTCALL
+ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
+                  CHAR *Buffer, DWORD Length, BOOL Attrib)
 {
-  IO_STATUS_BLOCK Iosb;
-  NTSTATUS Status;
   int i;
   DWORD Offset;
-  SMALL_RECT UpdateRect;
+  RECT UpdateRect;
+  LONG CursorStartX, CursorStartY;
+  UINT ScrolledLines;
 
-  CsrpPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &(UpdateRect.Left),
-                        &(UpdateRect.Top));
+  ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &CursorStartX, &CursorStartY);
+  UpdateRect.left = Buff->MaxX;
+  UpdateRect.top = Buff->CurrentY;
+  UpdateRect.right = -1;
+  UpdateRect.bottom = Buff->CurrentY;
+  ScrolledLines = 0;
 
   for (i = 0; i < Length; i++)
     {
-      switch(Buffer[i])
-        {
-          case '\n':
-          case '\b':
-          case '\r':
-          case '\t':
-            if (! TextMode && NULL != Buff->Console)
-              {
-                CsrpPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
-                                      &(UpdateRect.Right), &(UpdateRect.Bottom));
-                CsrpDrawRegion(Buff->Console, UpdateRect);
-              }
-            break;
-        }
-
       switch(Buffer[i])
         {
           /* --- LF --- */
           case '\n':
             Buff->CurrentX = 0;
-            /* slide the viewable screen */
-            if (((Buff->CurrentY - Buff->ShowY + Buff->MaxY) % Buff->MaxY) == Buff->MaxY - 1)
-              {
-                if (NULL != Buff->Console)
-                  {
-                    CsrpScrollUpOneLine(Buff->Console);
-                  }
-                if (++Buff->ShowY == Buff->MaxY)
-                  {
-                    Buff->ShowY = 0;
-                  }
-              }
-            if (++Buff->CurrentY == Buff->MaxY)
-              {
-                Buff->CurrentY = 0;
-              }
-            ClearLineBuffer(Buff, 0, TRUE);
-            CsrpPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
-                                  &(UpdateRect.Left), &(UpdateRect.Top));
+            ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
             break;
 
           /* --- BS --- */
           case '\b':
-            if (0 == Buff->CurrentX)
+            /* Only handle BS if we're not on the first pos of the first line */
+            if (0 != Buff->CurrentX || Buff->ShowY != Buff->CurrentY)
               {
-                /* slide viewable screen up */
-                if (Buff->ShowY == Buff->CurrentY)
+                if (0 == Buff->CurrentX)
                   {
-                    if (Buff->ShowY == 0)
+                    /* slide virtual position up */
+                    Buff->CurrentX = Buff->MaxX - 1;
+                    if (0 == Buff->CurrentY)
                       {
-                        Buff->ShowY = Buff->MaxY;
+                        Buff->CurrentY = Buff->MaxY;
                       }
                     else
                       {
-                        Buff->ShowY--;
+                        Buff->CurrentY--;
+                      }
+                    if ((0 == UpdateRect.top && UpdateRect.bottom < Buff->CurrentY)
+                        || (0 != UpdateRect.top && Buff->CurrentY < UpdateRect.top))
+                      {
+                        UpdateRect.top = Buff->CurrentY;
                       }
-                  }
-                /* slide virtual position up */
-                Buff->CurrentX = Buff->MaxX;
-                if (0 == Buff->CurrentY)
-                  {
-                    Buff->CurrentY = Buff->MaxY;
                   }
                 else
                   {
-                    Buff->CurrentY--;
+                     Buff->CurrentX--;
                   }
+                Offset = 2 * ((Buff->CurrentY * Buff->MaxX) + Buff->CurrentX);
+                SET_CELL_BUFFER(Buff, Offset, ' ', Buff->DefaultAttrib);
+                UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
+                UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX);
               }
-            else
-              {
-                 Buff->CurrentX--;
-              }
-            Offset = 2 * ((Buff->CurrentY * Buff->MaxX) + Buff->CurrentX);
-            SET_CELL_BUFFER(Buff, Offset, ' ', Buff->DefaultAttrib);
-            CsrpPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
-                                  &(UpdateRect.Left), &(UpdateRect.Top));
             break;
 
           /* --- CR --- */
           case '\r':
             Buff->CurrentX = 0;
-            CsrpPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
-                                  &(UpdateRect.Left), &(UpdateRect.Top));
+            UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
+            UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX);
             break;
 
           /* --- TAB --- */
           case '\t':
-            CsrpWriteConsole(Buff, "        ", (8 - (Buff->CurrentX % 8)), FALSE);
-            CsrpPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
-                                  &(UpdateRect.Left), &(UpdateRect.Top));
+            {
+              UINT EndX;
+
+              UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
+              EndX = 8 * ((Buff->CurrentX + 8) / 8);
+              if (Buff->MaxX < EndX)
+                {
+                  EndX = Buff->MaxX;
+                }
+              Offset = 2 * (((Buff->CurrentY * Buff->MaxX)) + Buff->CurrentX);
+              while (Buff->CurrentX < EndX)
+                {
+                  Buff->Buffer[Offset] = ' ';
+                  Offset += 2;
+                  Buff->CurrentX++;
+                }
+              UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX - 1);
+              if (Buff->CurrentX == Buff->MaxX)
+                {
+                  Buff->CurrentX = 0;
+                  ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
+                }
+            }
             break;
 
           /* --- */
           default:
+            UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
+            UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX);
             Offset = 2 * (((Buff->CurrentY * Buff->MaxX)) + Buff->CurrentX);
             Buff->Buffer[Offset++] = Buffer[i];
             if (Attrib)
@@ -685,175 +472,281 @@ NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWOR
             Buff->CurrentX++;
             if (Buff->CurrentX == Buff->MaxX)
               {
-                /* if end of line, go to next */
-                if (! TextMode && NULL != Buff->Console)
-                  {
-                    CsrpPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
-                                          &(UpdateRect.Right), &(UpdateRect.Bottom));
-                    CsrpDrawRegion(Buff->Console, UpdateRect);
-                  }
-
                 Buff->CurrentX = 0;
-                /* slide the viewable screen */
-                if (((Buff->CurrentY - Buff->ShowY + Buff->MaxY) % Buff->MaxY) == Buff->MaxY - 1)
-                  {
-                    if (NULL != Buff->Console)
-                      {
-                        CsrpScrollUpOneLine(Buff->Console);
-                      }
-                    if (++Buff->ShowY == Buff->MaxY)
-                      {
-                        Buff->ShowY = 0;
-                      }
-                  }
-                if (++Buff->CurrentY == Buff->MaxY)
-                  {
-                    /* if end of buffer, wrap back to beginning */
-                    Buff->CurrentY = 0;
-                  }
-                /* clear new line */
-                ClearLineBuffer(Buff, 0, TRUE);
-                CsrpPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
-                                      &(UpdateRect.Left), &(UpdateRect.Top));
+                ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
               }
             break;
         }
     }
 
-  CsrpPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &(UpdateRect.Right),
-                        &(UpdateRect.Bottom));
-  if (! TextMode && NULL != Buff->Console)
+  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)
     {
-      CsrpDrawRegion(Buff->Console, UpdateRect);
-    }
-  else if (TextMode && Buff == ActiveConsole->ActiveBuffer)
-    {    /* only write to screen if Console is Active, and not scrolled up */
-      if (Attrib)
-        {
-          Status = NtWriteFile(ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, Buffer, Length, NULL, 0);
-          if (!NT_SUCCESS(Status))
-            {
-              DbgPrint("CSR: Write failed\n");
-            }
-        }
+      ConioWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, ScrolledLines,
+                       Buffer, Length);
     }
 
-  return(STATUS_SUCCESS);
-}
-
-inline BOOLEAN CsrpIsEqualRect(
-  SMALL_RECT Rect1,
-  SMALL_RECT Rect2)
-{
-  return ((Rect1.Left == Rect2.Left) && (Rect1.Right == Rect2.Right) &&
-         (Rect1.Top == Rect2.Top) && (Rect1.Bottom == Rect2.Bottom));
+  return STATUS_SUCCESS;
 }
 
-inline BOOLEAN CsrpGetIntersection(
-  PSMALL_RECT Intersection,
-  SMALL_RECT Rect1,
-  SMALL_RECT Rect2)
+CSR_API(CsrReadConsole)
 {
-  if (CsrpIsRectEmpty(Rect1) ||
-    (CsrpIsRectEmpty(Rect2)) ||
-    (Rect1.Top > Rect2.Bottom) ||
-    (Rect1.Left > Rect2.Right) ||
-    (Rect1.Bottom < Rect2.Top) ||
-    (Rect1.Right < Rect2.Left))
-  {
-    /* The rectangles do not intersect */
-    CsrpInitRect(*Intersection, 0, -1, 0, -1)
-    return FALSE;
-  }
+  PLIST_ENTRY CurrentEntry;
+  ConsoleInput *Input;
+  PCHAR Buffer;
+  int i;
+  ULONG nNumberOfCharsToRead;
+  PCSRSS_CONSOLE Console;
+  NTSTATUS Status;
+   
+  DPRINT("CsrReadConsole\n");
 
-  CsrpInitRect(
-    *Intersection,
-    RtlRosMax(Rect1.Top, Rect2.Top),
-    RtlRosMax(Rect1.Left, Rect2.Left),
-    RtlRosMin(Rect1.Bottom, Rect2.Bottom),
-    RtlRosMin(Rect1.Right, Rect2.Right));
-  return TRUE;
-}
+  /* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */
+  nNumberOfCharsToRead = Request->Data.ReadConsoleRequest.NrCharactersToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : Request->Data.ReadConsoleRequest.NrCharactersToRead;
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = Reply->Header.MessageSize - sizeof(LPC_MESSAGE);
 
-inline BOOLEAN CsrpGetUnion(
-  PSMALL_RECT Union,
-  SMALL_RECT Rect1,
-  SMALL_RECT Rect2)
-{
-  if (CsrpIsRectEmpty(Rect1))
+  Buffer = Reply->Data.ReadConsoleReply.Buffer;
+  Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle,
+                               &Console);
+  if (! NT_SUCCESS(Status))
     {
-           if (CsrpIsRectEmpty(Rect2))
-           {
-             CsrpInitRect(*Union, 0, -1, 0, -1);
-             return FALSE;
-           }
-         else
-      *Union = Rect2;
+      return Reply->Status = Status;
     }
-  else
+  Reply->Data.ReadConsoleReply.EventHandle = ProcessData->ConsoleEvent;
+  for (i = 0; i < nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++)
     {
-           if (CsrpIsRectEmpty(Rect2))
+      /* remove input event from queue */
+      CurrentEntry = RemoveHeadList(&Console->InputEvents);
+      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.AsciiChar)
         {
-        *Union = Rect1;
+          /* backspace handling */
+          if ('\b' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar)
+            {
+              /* echo if it has not already been done, and either we or the client has chars to be deleted */
+              if (! Input->Echoed
+                  && (0 !=  i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted))
+                {
+                  ConioWriteConsole(Console, Console->ActiveBuffer,
+                                   &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE);
+                }
+              if (0 != i)
+                {
+                  i -= 2;        /* if we already have something to return, just back it up by 2 */
+                }
+              else
+                {            /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */
+                  Reply->Data.ReadConsoleReply.NrCharactersRead = 0;
+                  Reply->Status = STATUS_NOTIFY_CLEANUP;
+                  Console->WaitingChars--;
+                  HeapFree(Win32CsrApiHeap, 0, Input);
+                  ConioUnlockConsole(Console);
+                  return STATUS_NOTIFY_CLEANUP;
+                }
+              Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--;
+              Input->Echoed = TRUE;   /* mark as echoed so we don't echo it below */
+            }
+          /* do not copy backspace to buffer */
+          else
+            {
+              Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar;
+            }
+          /* echo to screen if enabled and we did not already echo the char */
+          if (0 != (Console->Mode & ENABLE_ECHO_INPUT)
+              && ! Input->Echoed
+              && '\r' != Input->InputEvent.Event.KeyEvent.uChar.AsciiChar)
+            {
+              ConioWriteConsole(Console, Console->ActiveBuffer,
+                               &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE);
+            }
         }
-           else
-             {
-          CsrpInitRect(
-            *Union,
-            RtlRosMin(Rect1.Top, Rect2.Top),
-            RtlRosMin(Rect1.Left, Rect2.Left),
-            RtlRosMax(Rect1.Bottom, Rect2.Bottom),
-            RtlRosMax(Rect1.Right, Rect2.Right));
-             }
-    }
-  return TRUE;
+      else
+        {
+          i--;
+        }
+      Console->WaitingChars--;
+      HeapFree(Win32CsrApiHeap, 0, Input);
+    }
+  Reply->Data.ReadConsoleReply.NrCharactersRead = i;
+  if (0 == i)
+    {
+      Reply->Status = STATUS_PENDING;    /* we didn't read anything */
+    }
+  else if (0 != (Console->Mode & ENABLE_LINE_INPUT))
+    {
+      if (0 == Console->WaitingLines || '\n' != Buffer[i - 1])
+        {
+          Reply->Status = STATUS_PENDING; /* line buffered, didn't get a complete line */
+        }
+      else
+        {
+          Console->WaitingLines--;
+          Reply->Status = STATUS_SUCCESS; /* line buffered, did get a complete line */
+        }
+    }
+  else
+    {
+      Reply->Status = STATUS_SUCCESS;  /* not line buffered, did read something */
+    }
+
+  if (Reply->Status == STATUS_PENDING)
+    {
+      Console->EchoCount = nNumberOfCharsToRead - i;
+    }
+  else
+    {
+      Console->EchoCount = 0;             /* if the client is no longer waiting on input, do not echo */
+    }
+  Reply->Header.MessageSize += i;
+
+  ConioUnlockConsole(Console);
+  return Reply->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(
+  RECT *Intersection,
+  RECT *Rect1,
+  RECT *Rect2)
+{
+  if (ConioIsRectEmpty(Rect1) ||
+    (ConioIsRectEmpty(Rect2)) ||
+    (Rect1->top > Rect2->bottom) ||
+    (Rect1->left > Rect2->right) ||
+    (Rect1->bottom < Rect2->top) ||
+    (Rect1->right < Rect2->left))
+  {
+    /* The rectangles do not intersect */
+    ConioInitRect(Intersection, 0, -1, 0, -1);
+    return FALSE;
+  }
+
+  ConioInitRect(Intersection,
+               RtlRosMax(Rect1->top, Rect2->top),
+               RtlRosMax(Rect1->left, Rect2->left),
+               RtlRosMin(Rect1->bottom, Rect2->bottom),
+               RtlRosMin(Rect1->right, Rect2->right));
+
+  return TRUE;
 }
 
-inline BOOLEAN CsrpSubtractRect(
-  PSMALL_RECT Subtraction,
-  SMALL_RECT Rect1,
-  SMALL_RECT Rect2)
+inline BOOLEAN ConioGetUnion(
+  RECT *Union,
+  RECT *Rect1,
+  RECT *Rect2)
 {
-  SMALL_RECT tmp;
-
-  if (CsrpIsRectEmpty(Rect1))
-    {
-           CsrpInitRect(*Subtraction, 0, -1, 0, -1);
-           return FALSE;
-    }
-  *Subtraction = Rect1;
-  if (CsrpGetIntersection(&tmp, Rect1, Rect2))
-    {
-           if (CsrpIsEqualRect(tmp, *Subtraction))
-             {
-               CsrpInitRect(*Subtraction, 0, -1, 0, -1);
-               return FALSE;
-             }
-           if ((tmp.Top == Subtraction->Top) && (tmp.Bottom == Subtraction->Bottom))
-             {
-               if (tmp.Left == Subtraction->Left)
-            Subtraction->Left = tmp.Right;
-               else if (tmp.Right == Subtraction->Right)
-            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;
-             }
+  if (ConioIsRectEmpty(Rect1))
+    {
+      if (ConioIsRectEmpty(Rect2))
+        {
+          ConioInitRect(Union, 0, -1, 0, -1);
+          return FALSE;
+        }
+      else
+        {
+          *Union = *Rect2;
+        }
+    }
+  else if (ConioIsRectEmpty(Rect2))
+    {
+      *Union = *Rect1;
+    }
+  else
+    {
+      ConioInitRect(Union,
+                   RtlRosMin(Rect1->top, Rect2->top),
+                   RtlRosMin(Rect1->left, Rect2->left),
+                   RtlRosMax(Rect1->bottom, Rect2->bottom),
+                   RtlRosMax(Rect1->right, Rect2->right));
     }
+
   return TRUE;
 }
 
-/*
- * Screen buffer must be locked when this function is called
- */
-static VOID CsrpCopyRegion(
-  PCSRSS_SCREEN_BUFFER ScreenBuffer,
-  SMALL_RECT SrcRegion,
-  SMALL_RECT DstRegion)
+inline BOOLEAN ConioSubtractRect(
+  RECT *Subtraction,
+  RECT *Rect1,
+  RECT *Rect2)
+{
+  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)
+            {
+              Subtraction->left = tmp.right;
+            }
+          else if (tmp.right == Subtraction->right)
+            {
+              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;
+            }
+        }
+    }
+
+  return TRUE;
+}
+
+STATIC VOID FASTCALL
+ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
+                RECT *SrcRegion,
+                RECT *DstRegion)
 {
   SHORT SrcY, DstY;
   DWORD SrcOffset;
@@ -861,82 +754,81 @@ static VOID CsrpCopyRegion(
   DWORD BytesPerLine;
   ULONG i;
 
-  DstY = DstRegion.Top;
-  BytesPerLine = CsrpRectWidth(DstRegion) * 2;
+  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;
+  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
+  for (i = SrcRegion->top; i <= SrcRegion->bottom; i++)
     {
-      DstOffset += ScreenBuffer->MaxX * 2;
-    }
+      RtlCopyMemory(
+        &ScreenBuffer->Buffer[DstOffset],
+        &ScreenBuffer->Buffer[SrcOffset],
+        BytesPerLine);
 
-    if (++SrcY == ScreenBuffer->MaxY)
-    {
-      SrcY = 0;
-      SrcOffset = (SrcRegion.Left + ScreenBuffer->ShowX) * 2;
-    }
-    else
-    {
-      SrcOffset += ScreenBuffer->MaxX * 2;
+      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;
+        }
     }
-  }
 }
 
-/*
- * Screen buffer must be locked when this function is called
- */
-static VOID CsrpFillRegion(
-  PCSRSS_SCREEN_BUFFER ScreenBuffer,
-  SMALL_RECT Region,
-  CHAR_INFO CharInfo)
+STATIC VOID FASTCALL
+ConioFillRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
+                RECT *Region,
+                CHAR_INFO CharInfo)
 {
   SHORT X, Y;
   DWORD Offset;
   DWORD Delta;
   ULONG i;
 
-  Y = (Region.Top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
-  Offset = (Y * ScreenBuffer->MaxX + Region.Left + ScreenBuffer->ShowX) * 2;
-  Delta = (ScreenBuffer->MaxX - CsrpRectWidth(Region)) * 2;
+  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, CharInfo.Char.AsciiChar, CharInfo.Attributes);
-    }
-    if (++Y == ScreenBuffer->MaxY)
-    {
-      Y = 0;
-      Offset = (Region.Left + ScreenBuffer->ShowX) * 2;
-    }
-    else
+  for (i = Region->top; i <= Region->bottom; i++)
     {
-      Offset += Delta;
+      for (X = Region->left; X <= Region->right; X++)
+        {
+          SET_CELL_BUFFER(ScreenBuffer, Offset, CharInfo.Char.AsciiChar, CharInfo.Attributes);
+        }
+      if (++Y == ScreenBuffer->MaxY)
+        {
+          Y = 0;
+          Offset = (Region->left + ScreenBuffer->ShowX) * 2;
+        }
+      else
+        {
+          Offset += Delta;
+        }
     }
-  }
 }
 
 CSR_API(CsrWriteConsole)
 {
+  NTSTATUS Status;
   BYTE *Buffer = Request->Data.WriteConsoleRequest.Buffer;
   PCSRSS_SCREEN_BUFFER Buff;
+  PCSRSS_CONSOLE Console;
 
   DPRINT("CsrWriteConsole\n");
    
@@ -951,222 +843,94 @@ CSR_API(CsrWriteConsole)
       DPRINT1("Invalid request size\n");
       return Reply->Status = STATUS_INVALID_PARAMETER;
     }
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
 
-  LOCK;
-  if (! NT_SUCCESS(Win32CsrGetObject(ProcessData,
-                                     Request->Data.WriteConsoleRequest.ConsoleHandle,
-                                     (Object_t **) &Buff))
-      || Buff->Header.Type != CONIO_SCREEN_BUFFER_MAGIC)
-    {
-        UNLOCK;
-        return Reply->Status = STATUS_INVALID_HANDLE;
-      }
-   RtlEnterCriticalSection(&(Buff->Lock));
-   CsrpWriteConsole( Buff, Buffer, Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE );
-   RtlLeaveCriticalSection(&(Buff->Lock));
-   UNLOCK;
-   return Reply->Status = STATUS_SUCCESS;
-}
-
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff);
+  if (! NT_SUCCESS(Status))
+    {
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
+      return Reply->Status = Status;
+    }
 
-NTSTATUS STDCALL CsrInitConsoleScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer,
-                                            PCSRSS_CONSOLE Console,
-                                            unsigned Width,
-                                            unsigned Height)
-{
-  Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC;
-  Buffer->Header.ReferenceCount = 0;
-  Buffer->MaxX = Width;
-  Buffer->MaxY = Height;
-  Buffer->ShowX = 0;
-  Buffer->ShowY = 0;
-  Buffer->CurrentX = 0;
-  Buffer->CurrentY = 0;
-  Buffer->Buffer = RtlAllocateHeap( Win32CsrApiHeap, 0, Buffer->MaxX * Buffer->MaxY * 2 );
-  if( Buffer->Buffer == 0 )
-    return STATUS_INSUFFICIENT_RESOURCES;
-  Buffer->DefaultAttrib = (TextMode ? 0x17 : 0x0f);
-  /* initialize buffer to be empty with default attributes */
-  for( ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++ )
+  ConioWriteConsole(Console, Buff, Buffer,
+                    Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
+  ConioUnlockScreenBuffer(Buff);
+  if (NULL != Console)
     {
-      ClearLineBuffer(Buffer, 0, FALSE);
+      ConioUnlockConsole(Console);
     }
-  Buffer->CursorInfo.bVisible = TRUE;
-  Buffer->CursorInfo.dwSize = 5;
-  Buffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
-  Buffer->CurrentX = 0;
-  Buffer->CurrentY = 0;
-  Buffer->Console = Console;
-  RtlInitializeCriticalSection(&(Buffer->Lock));
 
-  return STATUS_SUCCESS;
+  return Reply->Status = STATUS_SUCCESS;
 }
 
-VOID STDCALL ConioDeleteScreenBuffer(Object_t *Object)
+VOID STDCALL
+ConioDeleteScreenBuffer(Object_t *Object)
 {
   PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object;
-  RtlFreeHeap(Win32CsrApiHeap, 0, Buffer->Buffer);
-  RtlFreeHeap(Win32CsrApiHeap, 0, Buffer);
-}
-
-NTSTATUS STDCALL CsrInitConsole(PCSRSS_CONSOLE Console)
-{
-  NTSTATUS Status;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  PCSRSS_SCREEN_BUFFER NewBuffer;
-
-  Console->Title.MaximumLength = Console->Title.Length = 0;
-  Console->Title.Buffer = 0;
-  
-  RtlCreateUnicodeString( &Console->Title, L"Command Prompt" );
-  
-  Console->Header.ReferenceCount = 0;
-  Console->WaitingChars = 0;
-  Console->WaitingLines = 0;
-  Console->EchoCount = 0;
-  Console->Header.Type = CONIO_CONSOLE_MAGIC;
-  Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
-  Console->EarlyReturn = FALSE;
-  InitializeListHead(&Console->InputEvents);
-  InitializeListHead(&Console->ProcessList);
-
-  InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_INHERIT, NULL, NULL);
-
-  Status = NtCreateEvent( &Console->ActiveEvent, STANDARD_RIGHTS_ALL, &ObjectAttributes, FALSE, FALSE );
-  if( !NT_SUCCESS( Status ) )
-    {
-      return Status;
-    }
-  Console->GuiConsoleData = NULL;
-  if (! TextMode)
-     {
-        Console->ActiveBuffer = NULL;
-        GuiConsoleInitConsole(Console);
-     }
-  else
-     {
-        Console->hWindow = (HWND) NULL;
-        Console->Size = PhysicalConsoleSize;
-     }
-  NewBuffer = RtlAllocateHeap( Win32CsrApiHeap, 0, sizeof( CSRSS_SCREEN_BUFFER ) );
-  if (! NewBuffer )
-     {
-       NtClose(Console->ActiveEvent);
-       return STATUS_INSUFFICIENT_RESOURCES;
-     }
-  Status = CsrInitConsoleScreenBuffer(NewBuffer, Console, Console->Size.X, Console->Size.Y);
-  if( !NT_SUCCESS( Status ) )
-     {
-       NtClose( Console->ActiveEvent );
-       RtlFreeHeap( Win32CsrApiHeap, 0, NewBuffer );
-       return Status;
-     }
-  Console->ActiveBuffer = NewBuffer;
-  /* add a reference count because the buffer is tied to the console */
-  Console->ActiveBuffer->Header.ReferenceCount++;
-  /* make console active, and insert into console list */
-  LOCK;
-  if( ActiveConsole )
-     {
-       Console->Prev = ActiveConsole;
-       Console->Next = ActiveConsole->Next;
-       ActiveConsole->Next->Prev = Console;
-       ActiveConsole->Next = Console;
-     }
-  else {
-     Console->Prev = Console;
-     Console->Next = Console;
-  }
-  ActiveConsole = Console;
-  /* copy buffer contents to screen */
-  CsrDrawConsole(Console);
-  UNLOCK;
-  return STATUS_SUCCESS;
+  HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
+  HeapFree(Win32CsrApiHeap, 0, Buffer);
 }
 
-/***************************************************************
- *  CsrDrawConsole blasts the console buffer onto the screen   *
- *  must be called while holding the active console lock       *
- **************************************************************/
-VOID STDCALL CsrDrawConsole(PCSRSS_CONSOLE Console)
+VOID FASTCALL
+ConioDrawConsole(PCSRSS_CONSOLE Console)
 {
-   SMALL_RECT Region;
+   RECT Region;
 
-   CsrpInitRect(
-     Region,
-     0,
-     0,
-     Console->Size.Y - 1,
-     Console->Size.X - 1);
+   ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1);
 
-   CsrpDrawRegion(Console, Region);
+   ConioDrawRegion(Console, &Region);
 }
 
 
-VOID STDCALL ConioDeleteConsole(Object_t *Object)
+VOID STDCALL
+ConioDeleteConsole(Object_t *Object)
 {
   PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object;
   ConsoleInput *Event;
+
   DPRINT("ConioDeleteConsole\n");
-  LOCK;
+
   /* Drain input event queue */
   while (Console->InputEvents.Flink != &Console->InputEvents)
     {
       Event = (ConsoleInput *) Console->InputEvents.Flink;
       Console->InputEvents.Flink = Console->InputEvents.Flink->Flink;
       Console->InputEvents.Flink->Flink->Blink = &Console->InputEvents;
-      RtlFreeHeap(Win32CsrApiHeap, 0, Event);
-    }
-  /* Switch to next console */
-  if (ActiveConsole == Console)
-    {
-      ActiveConsole = Console->Next != Console ? Console->Next : NULL;
-    }
-  if (Console->Next != Console)
-    {
-      Console->Prev->Next = Console->Next;
-      Console->Next->Prev = Console->Prev;
-    }
-   
-  if (ActiveConsole)
-    {
-      CsrDrawConsole(ActiveConsole);
+      HeapFree(Win32CsrApiHeap, 0, Event);
     }
 
-  if (! --Console->ActiveBuffer->Header.ReferenceCount)
+  if (0 == --Console->ActiveBuffer->Header.ReferenceCount)
     {
       ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
     }
+
   Console->ActiveBuffer = NULL;
-  if (! TextMode)
-    {
-      GuiConsoleDeleteConsole(Console);
-    }
-  UNLOCK;
-  NtClose(Console->ActiveEvent);
+  ConioCleanupConsole(Console);
+
+  CloseHandle(Console->ActiveEvent);
   RtlFreeUnicodeString(&Console->Title);
-  RtlFreeHeap(Win32CsrApiHeap, 0, Console);
+  HeapFree(Win32CsrApiHeap, 0, Console);
 }
 
-VOID STDCALL CsrInitConsoleSupport(VOID)
+VOID STDCALL
+CsrInitConsoleSupport(VOID)
 {
   DPRINT("CSR: CsrInitConsoleSupport()\n");
 
   /* Should call LoadKeyboardLayout */
-
-  if (TextMode)
-    {
-      TextMode = CsrInitTextConsoleSupport();
-    }
-
-  if (! TextMode)
-    {
-      CsrInitGraphicsConsoleSupport();
-    }
 }
 
-static void CsrpProcessChar( PCSRSS_CONSOLE Console,
-                            ConsoleInput *KeyEventRecord ) {
+STATIC VOID FASTCALL
+ConioProcessChar(PCSRSS_CONSOLE Console,
+                            ConsoleInput *KeyEventRecord)
+{
   BOOL updown;
   BOOL bClientWake = FALSE;
   ConsoleInput *TempInput;
@@ -1181,7 +945,6 @@ static void CsrpProcessChar( PCSRSS_CONSOLE Console,
       PCSRSS_PROCESS_DATA current;
       PLIST_ENTRY current_entry;
       DPRINT1("Console_Api Ctrl-C\n");
-      LOCK;
       current_entry = Console->ProcessList.Flink;
       while (current_entry != &Console->ProcessList)
        {
@@ -1189,197 +952,224 @@ static void CsrpProcessChar( PCSRSS_CONSOLE Console,
          current_entry = current_entry->Flink;
          CsrConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current);
        }
-      UNLOCK;
-      RtlFreeHeap( Win32CsrApiHeap, 0, KeyEventRecord );
+      HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
       return;
     }
-  if( KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState &
-      ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED ) &&
-      ( KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_UP ||
-       KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_DOWN) )
+
+  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 == TRUE )
+      if (KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown)
        {
          /* scroll up or down */
-         LOCK;
-         if( Console == 0 )
+         if (NULL == Console)
            {
-             DbgPrint( "CSR: No Active Console!\n" );
-             UNLOCK;
-             RtlFreeHeap( Win32CsrApiHeap, 0, KeyEventRecord );
+             DPRINT1("No Active Console!\n");
+             HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
              return;
            }
-         if( KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_UP )
+         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 )
+             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;
-         CsrDrawConsole(Console);
-         UNLOCK;
-       }
-      RtlFreeHeap( Win32CsrApiHeap, 0, KeyEventRecord );
+            {
+             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( Console == 0 )
+  if (NULL == Console)
     {
-      DbgPrint( "CSR: No Active Console!\n" );
-      UNLOCK;
-      RtlFreeHeap( Win32CsrApiHeap, 0, KeyEventRecord );
+      DPRINT1("No Active Console!\n");
+      HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
       return;
     }
 
-  if( Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT) )
-    switch( KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar )
-      {
-      case '\r':
-       // first add the \r
-        KeyEventRecord->InputEvent.EventType = KEY_EVENT;
-       updown = KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown;
-       KeyEventRecord->Echoed = FALSE;
-       KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
-       KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\r';
-        InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry);
-       Console->WaitingChars++;
-       KeyEventRecord = RtlAllocateHeap( Win32CsrApiHeap, 0, sizeof( ConsoleInput ) );
-       if( !KeyEventRecord )
-         {
-           DbgPrint( "CSR: Failed to allocate KeyEventRecord\n" );
-           return;
-         }
-       KeyEventRecord->InputEvent.EventType = KEY_EVENT;
-       KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown = updown;
-       KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = 0;
-       KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualScanCode = 0;
-       KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\n';
-       KeyEventRecord->Fake = TRUE;
-      }
-  // add event to the queue
+  if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)))
+    {
+      switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar)
+        {
+          case '\r':
+            /* first add the \r */
+            KeyEventRecord->InputEvent.EventType = KEY_EVENT;
+            updown = KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown;
+            KeyEventRecord->Echoed = FALSE;
+            KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
+            KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\r';
+            InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry);
+            Console->WaitingChars++;
+            KeyEventRecord = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput));
+            if (NULL == KeyEventRecord)
+              {
+                DPRINT1("Failed to allocate KeyEventRecord\n");
+                return;
+              }
+            KeyEventRecord->InputEvent.EventType = KEY_EVENT;
+            KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown = updown;
+            KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = 0;
+            KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualScanCode = 0;
+            KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\n';
+            KeyEventRecord->Fake = TRUE;
+            break;
+        }
+    }
+  /* add event to the queue */
   InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry);
   Console->WaitingChars++;
-  // if line input mode is enabled, only wake the client on enter key down
-  if( !(Console->Mode & ENABLE_LINE_INPUT ) ||
-      Console->EarlyReturn ||
-      ( KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\n' &&
-       KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown == FALSE) )
-    {
-      if( KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\n' )
-       Console->WaitingLines++;
+  /* if line input mode is enabled, only wake the client on enter key down */
+  if (0 == (Console->Mode & ENABLE_LINE_INPUT)
+      || Console->EarlyReturn
+      || ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar
+          && ! KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown))
+    {
+      if ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar)
+        {
+          Console->WaitingLines++;
+        }
       bClientWake = TRUE;
-      NtSetEvent( Console->ActiveEvent, 0 );
+      SetEvent(Console->ActiveEvent);
     }
   KeyEventRecord->Echoed = FALSE;
-  if( Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT) &&
-      KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\b' &&
-      KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown )
-    {
-      // walk the input queue looking for a char to backspace
-      for( TempInput = (ConsoleInput *)Console->InputEvents.Blink;
-          TempInput != (ConsoleInput *)&Console->InputEvents &&
-            (TempInput->InputEvent.EventType != KEY_EVENT ||
-             TempInput->InputEvent.Event.KeyEvent.bKeyDown == FALSE ||
-             TempInput->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\b' );
-          TempInput = (ConsoleInput *)TempInput->ListEntry.Blink );
-      // if we found one, delete it, otherwise, wake the client
-      if( TempInput != (ConsoleInput *)&Console->InputEvents )
+  if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT))
+      && '\b' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar
+      && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown)
+    {
+      /* walk the input queue looking for a char to backspace */
+      for (TempInput = (ConsoleInput *) Console->InputEvents.Blink;
+          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)
+        {
+          /* 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
+         /* delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue */
          RemoveEntryList(&TempInput->ListEntry);
-         if( TempInput->Echoed )
-           CsrpWriteConsole( Console->ActiveBuffer, &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE );     
-  RtlFreeHeap( Win32CsrApiHeap, 0, TempInput );
+         if (TempInput->Echoed)
+            {
+              ConioWriteConsole(Console, Console->ActiveBuffer,
+                               &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar,
+                               1, TRUE);       
+            }
+          HeapFree(Win32CsrApiHeap, 0, TempInput);
          RemoveEntryList(&KeyEventRecord->ListEntry);
-         RtlFreeHeap( Win32CsrApiHeap, 0, KeyEventRecord );
+         HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
          Console->WaitingChars -= 2;
        }
-      else {
-          NtSetEvent( Console->ActiveEvent, 0 );
-      }
-    }
-  else {
-    // echo chars if we are supposed to and client is waiting for some
-    if( ( Console->Mode & ENABLE_ECHO_INPUT ) && Console->EchoCount &&
-       KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar &&
-       KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown == TRUE &&
-       KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\r' )
-      {
-       // mark the char as already echoed
-       CsrpWriteConsole( Console->ActiveBuffer, &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE );
-       Console->EchoCount--;
-       KeyEventRecord->Echoed = TRUE;
-      }
-  }
+      else
+        {
+          SetEvent(Console->ActiveEvent);
+        }
+    }
+  else
+    {
+      /* echo chars if we are supposed to and client is waiting for some */
+      if (0 != (Console->Mode & ENABLE_ECHO_INPUT) && Console->EchoCount
+          && KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar
+          && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown
+          && '\r' != KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar)
+        {
+          /* mark the char as already echoed */
+          ConioWriteConsole(Console, Console->ActiveBuffer,
+                           &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar,
+                           1, TRUE);
+          Console->EchoCount--;
+          KeyEventRecord->Echoed = TRUE;
+        }
+    }
+
   /* Console->WaitingChars++; */
-  if( bClientWake || !(Console->Mode & ENABLE_LINE_INPUT) ) {
-    NtSetEvent( Console->ActiveEvent, 0 );
-  }
+  if (bClientWake || 0 == (Console->Mode & ENABLE_LINE_INPUT))
+    {
+      SetEvent(Console->ActiveEvent);
+    }
 }
 
-static DWORD CsrpGetShiftState( PBYTE KeyState ) {
+STATIC DWORD FASTCALL
+ConioGetShiftState(PBYTE KeyState)
+{
   int i;
   DWORD ssOut = 0;
 
-  for( i = 0; i < 0x100; i++ ) {
-    if( KeyState[i] & 0x80 ) {
-      UINT vk = MapVirtualKeyExW( i, 3, 0 ) & 0xff;
-      switch( vk ) {
-      case VK_LSHIFT:
-      case VK_RSHIFT:
-      case VK_SHIFT:
-       ssOut |= SHIFT_PRESSED;
-       break;
-
-      case VK_LCONTROL:
-      case VK_CONTROL:
-       ssOut |= LEFT_CTRL_PRESSED;
-       break;
-
-      case VK_RCONTROL:
-       ssOut |= RIGHT_CTRL_PRESSED | ENHANCED_KEY;
-       break;
-
-      case VK_LMENU:
-      case VK_MENU:
-       ssOut |= LEFT_ALT_PRESSED;
-       break;
-
-      case VK_RMENU:
-       ssOut |= RIGHT_ALT_PRESSED | ENHANCED_KEY;
-       break;
-
-      case VK_CAPITAL:
-       ssOut |= CAPSLOCK_ON;
-       break;
-
-      case VK_NUMLOCK:
-       ssOut |= NUMLOCK_ON;
-       break;
-
-      case VK_SCROLL:
-       ssOut |= SCROLLLOCK_ON;
-       break;
-      }
+  for (i = 0; i < 0x100; i++)
+    {
+      if (0 != (KeyState[i] & 0x80))
+        {
+          UINT vk = MapVirtualKeyExW(i, 3, 0) & 0xff;
+          switch(vk)
+            {
+              case VK_LSHIFT:
+              case VK_RSHIFT:
+              case VK_SHIFT:
+                ssOut |= SHIFT_PRESSED;
+                break;
+
+              case VK_LCONTROL:
+              case VK_CONTROL:
+                ssOut |= LEFT_CTRL_PRESSED;
+                break;
+
+              case VK_RCONTROL:
+                ssOut |= RIGHT_CTRL_PRESSED | ENHANCED_KEY;
+                break;
+
+              case VK_LMENU:
+              case VK_MENU:
+                ssOut |= LEFT_ALT_PRESSED;
+                break;
+
+              case VK_RMENU:
+                ssOut |= RIGHT_ALT_PRESSED | ENHANCED_KEY;
+                break;
+
+              case VK_CAPITAL:
+                ssOut |= CAPSLOCK_ON;
+                break;
+
+              case VK_NUMLOCK:
+                ssOut |= NUMLOCK_ON;
+                break;
+
+              case VK_SCROLL:
+                ssOut |= SCROLLLOCK_ON;
+                break;
+            }
+        }
     }
-  }
 
   return ssOut;
 }
 
-void STDCALL
-CsrProcessKey(MSG *msg, PCSRSS_CONSOLE Console)
+VOID STDCALL
+ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
 {
-  static PCSRSS_CONSOLE SwapConsole = 0; /* console we are thinking about swapping with */
   static BYTE KeyState[256] = { 0 };
   /* MSDN mentions that you should use the last virtual key code received
    * when putting a virtual key identity to a WM_CHAR message since multiple
@@ -1394,8 +1184,6 @@ CsrProcessKey(MSG *msg, PCSRSS_CONSOLE Console)
   UINT VirtualScanCode;
   BOOL Down = FALSE;
   INPUT_RECORD er;
-  NTSTATUS Status;
-  IO_STATUS_BLOCK Iosb;
   ULONG ResultSize = 0;
 
   RepeatCount = 1;
@@ -1404,7 +1192,7 @@ CsrProcessKey(MSG *msg, PCSRSS_CONSOLE Console)
     msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
 
   GetKeyboardState(KeyState);
-  ShiftState = CsrpGetShiftState(KeyState);
+  ShiftState = ConioGetShiftState(KeyState);
 
   if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
     {
@@ -1428,12 +1216,17 @@ CsrProcessKey(MSG *msg, PCSRSS_CONSOLE Console)
     }
 
   if (UnicodeChar)
-    RtlUnicodeToOemN(&AsciiChar,
-                    1,
-                    &ResultSize,
-                    &UnicodeChar,
-                    sizeof(WCHAR));
-  if (!ResultSize) AsciiChar = 0;
+    {
+      RtlUnicodeToOemN(&AsciiChar,
+                       1,
+                       &ResultSize,
+                       &UnicodeChar,
+                       sizeof(WCHAR));
+    }
+  if (0 == ResultSize)
+    {
+      AsciiChar = 0;
+    }
   
   er.EventType = KEY_EVENT;
   er.Event.KeyEvent.bKeyDown = Down;
@@ -1442,95 +1235,37 @@ CsrProcessKey(MSG *msg, PCSRSS_CONSOLE Console)
   er.Event.KeyEvent.dwControlKeyState = ShiftState;
   er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
   er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
-    
-  if (TextMode && ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)
-      && VirtualKeyCode == VK_TAB )
-    {
-      if (Down)
+
+  if (TextMode)
+    {    
+      if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
+          && VK_TAB == VirtualKeyCode)
         {
-          ANSI_STRING Title;
-          void * Buffer;
-          COORD *pos;
-             
-          /* alt-tab, swap consoles */
-          /* move SwapConsole to next console, and print its title */
-          LOCK;
-          if (! SwapConsole)
+          if (Down)
             {
-              SwapConsole = ActiveConsole;
+              TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1);
             }
-             
-          SwapConsole = (ShiftState & SHIFT_PRESSED ? SwapConsole->Prev :
-                         SwapConsole->Next);
-          Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Title);
-          Title.Length = 0;
-          Buffer = RtlAllocateHeap(Win32CsrApiHeap,
-                                  0,
-                                  sizeof( COORD ) + Title.MaximumLength);
-          pos = (COORD *)Buffer;
-          Title.Buffer = Buffer + sizeof( COORD );
-
-          RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Title, FALSE);
-          pos->Y = PhysicalConsoleSize.Y / 2;
-          pos->X = ( PhysicalConsoleSize.X - Title.Length ) / 2;
-          /* redraw the console to clear off old title */
-          CsrDrawConsole(ActiveConsole);
-          Status = NtDeviceIoControlFile(ConsoleDeviceHandle,
-                                         NULL,
-                                         NULL,
-                                         NULL,
-                                         &Iosb,
-                                         IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
-                                         Buffer,
-                                         sizeof(COORD) + Title.Length,
-                                         NULL,
-                                         0);
-          if (! NT_SUCCESS(Status))
-            {
-              DPRINT1( "Error writing to console\n" );
-           }
-          RtlFreeHeap(Win32CsrApiHeap, 0, Buffer);
-             
-          UNLOCK;
-        }
-
-      return;
-    }
-  else if (TextMode && SwapConsole && VirtualKeyCode == VK_MENU && ! Down)
-    {
-      /* alt key released, swap consoles */
 
-      LOCK;
-      if (SwapConsole != ActiveConsole)
+          return;
+        }
+      else if (VK_MENU == VirtualKeyCode && ! Down)
         {
-          /* first remove swapconsole from the list */
-          SwapConsole->Prev->Next = SwapConsole->Next;
-          SwapConsole->Next->Prev = SwapConsole->Prev;
-          /* now insert before activeconsole */
-          SwapConsole->Next = ActiveConsole;
-          SwapConsole->Prev = ActiveConsole->Prev;
-          ActiveConsole->Prev->Next = SwapConsole;
-          ActiveConsole->Prev = SwapConsole;
+          if (TuiSwapConsole(0))
+            {
+              return;
+            }
         }
-      ActiveConsole = SwapConsole;
-      SwapConsole = 0;
-      CsrDrawConsole(ActiveConsole);
-      UNLOCK;
-      return;
     }
 
-  LOCK;
   if (NULL == Console) 
     {
-      UNLOCK;
       return;
     }
 
-  ConInRec = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ConsoleInput));
+  ConInRec = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput));
 
   if (NULL == ConInRec)
     {
-      UNLOCK;
       return;
     }
     
@@ -1554,152 +1289,166 @@ CsrProcessKey(MSG *msg, PCSRSS_CONSOLE Console)
         (AsciiChar >= ' ') ? AsciiChar : '.',
         ShiftState);
     
-  if (!ConInRec->Fake || !ConInRec->NotChar)
-    CsrpProcessChar(Console, ConInRec);
+  if (! ConInRec->Fake || ! ConInRec->NotChar)
+    {
+      ConioProcessChar(Console, ConInRec);
+    }
   else
-    RtlFreeHeap(Win32CsrApiHeap,0,ConInRec);
-  UNLOCK;
+    {
+      HeapFree(Win32CsrApiHeap, 0, ConInRec);
+    }
 }
 
-VOID Console_Api( DWORD RefreshEvent )
+VOID
+Console_Api(DWORD RefreshEvent)
 {
   /* 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 );
+  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) {
-    GetMessageW(&msg, 0, 0, 0);
-    TranslateMessage(&msg);
+  while (TRUE)
+    {
+      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)) {
-       CsrProcessKey(&msg, ActiveConsole);
+      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)
+        {
+          ConioProcessKey(&msg, TuiGetFocusConsole(), TRUE);
+        }
     }
-  }
 
-  PrivateCsrssAcquireOrReleaseInputOwnership( TRUE );
+  PrivateCsrssAcquireOrReleaseInputOwnership(TRUE);
 }
 
 CSR_API(CsrGetScreenBufferInfo)
 {
-   NTSTATUS Status;
-   PCSRSS_SCREEN_BUFFER Buff;
-   PCONSOLE_SCREEN_BUFFER_INFO pInfo;
-   IO_STATUS_BLOCK Iosb;
+  NTSTATUS Status;
+  PCSRSS_SCREEN_BUFFER Buff;
+  PCONSOLE_SCREEN_BUFFER_INFO pInfo;
    
-   DPRINT("CsrGetScreenBufferInfo\n");
-
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
-     sizeof(LPC_MESSAGE);
-
-   LOCK;
-   if( !NT_SUCCESS( Win32CsrGetObject( ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle,
-     (Object_t **)&Buff ) ) || Buff->Header.Type != CONIO_SCREEN_BUFFER_MAGIC )
-      {
-        UNLOCK;
-        return Reply->Status = STATUS_INVALID_HANDLE;
-      }
-   pInfo = &Reply->Data.ScreenBufferInfoReply.Info;
-   if(Buff == ActiveConsole->ActiveBuffer && TextMode)
-     {
-       Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
-    IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO, 0, 0, pInfo, sizeof( *pInfo ) );
-       if( !NT_SUCCESS( Status ) )
-          DbgPrint( "CSR: Failed to get console info, expect trouble\n" );
-       Reply->Status = Status;
-     }
-   else {
-      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->wAttributes = Buff->DefaultAttrib;
-      pInfo->srWindow.Left = 0;
-      pInfo->srWindow.Right = Buff->MaxX - 1;
-      pInfo->srWindow.Top = 0;
-      pInfo->srWindow.Bottom = Buff->MaxY - 1;
-      Reply->Status = STATUS_SUCCESS;
-   }
-   UNLOCK;
-   return Reply->Status;
+  DPRINT("CsrGetScreenBufferInfo\n");
+
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
+  pInfo = &Reply->Data.ScreenBufferInfoReply.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->wAttributes = Buff->DefaultAttrib;
+  pInfo->srWindow.Left = 0;
+  pInfo->srWindow.Right = Buff->MaxX - 1;
+  pInfo->srWindow.Top = 0;
+  pInfo->srWindow.Bottom = Buff->MaxY - 1;
+  pInfo->dwMaximumWindowSize.X = Buff->MaxX;
+  pInfo->dwMaximumWindowSize.Y = Buff->MaxY;
+  ConioUnlockScreenBuffer(Buff);
+
+  Reply->Status = STATUS_SUCCESS;
+
+  return Reply->Status;
 }
 
 CSR_API(CsrSetCursor)
 {
   NTSTATUS Status;
+  PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
-  CONSOLE_SCREEN_BUFFER_INFO Info;
-  IO_STATUS_BLOCK Iosb;
-  SMALL_RECT UpdateRect;
+  LONG OldCursorX, OldCursorY;
    
   DPRINT("CsrSetCursor\n");
 
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
+
   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
 
-  LOCK;
-  if( !NT_SUCCESS( Win32CsrGetObject( ProcessData, Request->Data.SetCursorRequest.ConsoleHandle,
-     (Object_t **)&Buff ) ) || Buff->Header.Type != CONIO_SCREEN_BUFFER_MAGIC )
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff);
+  if (! NT_SUCCESS(Status))
     {
-      UNLOCK;
-      return Reply->Status = STATUS_INVALID_HANDLE;
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
+      return Reply->Status = Status;
     }
-  RtlEnterCriticalSection(&(Buff->Lock));
-  Info.dwCursorPosition = Request->Data.SetCursorRequest.Position;
-  Info.wAttributes = Buff->DefaultAttrib;
-
-  CsrpPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
-                        &(UpdateRect.Left), &(UpdateRect.Top));
-  Buff->CurrentX = Info.dwCursorPosition.X + Buff->ShowX;
-  Buff->CurrentY = (Info.dwCursorPosition.Y + Buff->ShowY) % Buff->MaxY;
-  if (! TextMode && ProcessData->Console->ActiveBuffer == Buff)
-    {
-      /* Redraw char at old position (removes cursor) */
-      UpdateRect.Right = UpdateRect.Left;
-      UpdateRect.Bottom = UpdateRect.Top;
-      CsrpDrawRegion(Buff->Console, UpdateRect);
-      /* Redraw char at new position (shows cursor) */
-      CsrpPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
-                            &(UpdateRect.Left), &(UpdateRect.Top));
-      UpdateRect.Right = UpdateRect.Left;
-      UpdateRect.Bottom = UpdateRect.Top;
-      CsrpDrawRegion(Buff->Console, UpdateRect);
-    }
-  else if (TextMode && Buff == ActiveConsole->ActiveBuffer)
-    {
-      Status = NtDeviceIoControlFile(ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
-                                     IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, &Info,
-                                     sizeof(Info), 0, 0);
-      if (! NT_SUCCESS(Status))
+
+  ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &OldCursorX, &OldCursorY);
+  Buff->CurrentX = Request->Data.SetCursorRequest.Position.X + Buff->ShowX;
+  Buff->CurrentY = (Request->Data.SetCursorRequest.Position.Y + Buff->ShowY) % Buff->MaxY;
+  if (NULL != Console && Buff == Console->ActiveBuffer)
+    {
+      if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
         {
-          DbgPrint( "CSR: Failed to set console info, expect trouble\n" );
+          ConioUnlockScreenBuffer(Buff);
+          return Reply->Status = STATUS_UNSUCCESSFUL;
         }
     }
 
-  RtlLeaveCriticalSection(&(Buff->Lock));
-  UNLOCK;
+  ConioUnlockScreenBuffer(Buff);
+  if (NULL != Console)
+    {
+      ConioUnlockConsole(Console);
+    }
 
-  return Reply->Status = Status;
+  return Reply->Status = STATUS_SUCCESS;
+}
+
+STATIC FASTCALL VOID
+ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, 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;
+    }
 }
 
 CSR_API(CsrWriteConsoleOutputChar)
 {
+  NTSTATUS Status;
   PBYTE String = Request->Data.WriteConsoleOutputCharRequest.String;
   PBYTE Buffer;
+  PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
   DWORD X, Y, Length;
-  NTSTATUS Status;
-  IO_STATUS_BLOCK Iosb;
-  SMALL_RECT UpdateRect;
+  RECT UpdateRect;
 
   DPRINT("CsrWriteConsoleOutputChar\n");
 
@@ -1715,34 +1464,34 @@ CSR_API(CsrWriteConsoleOutputChar)
       return Reply->Status = STATUS_INVALID_PARAMETER;
     }
 
-  LOCK;
-  if (! NT_SUCCESS(Win32CsrGetObject(ProcessData,
-                                     Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
-                                     (Object_t **) &Buff))
-      || Buff->Header.Type != CONIO_SCREEN_BUFFER_MAGIC)
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
     {
-      UNLOCK;
-      return Reply->Status = STATUS_INVALID_HANDLE;
+      return Reply->Status = Status;
     }
 
+  Status = ConioLockScreenBuffer(ProcessData,
+                                 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
+                                 &Buff);
+  if (! NT_SUCCESS(Status))
+    {
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
+      return Reply->Status = Status;
+    }
 
   X = Request->Data.WriteConsoleOutputCharRequest.Coord.X + Buff->ShowX;
   Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->ShowY) % Buff->MaxY;
   Length = Request->Data.WriteConsoleOutputCharRequest.Length;
   Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
-  CsrpPhysicalToLogical(Buff, X, Y, &(UpdateRect.Left), &(UpdateRect.Top));
   while (Length--)
     {
       *Buffer = *String++;
       Buffer += 2;
       if (++X == Buff->MaxX)
         {
-          if (! TextMode && NULL != Buff->Console)
-            {
-              CsrpPhysicalToLogical(Buff, X - 1, Y, &(UpdateRect.Right), &(UpdateRect.Bottom));
-              CsrpDrawRegion(Buff->Console, UpdateRect);
-              CsrpPhysicalToLogical(Buff, 0, Y + 1, &(UpdateRect.Left), &(UpdateRect.Top));
-            }
           if (++Y == Buff->MaxY)
             {
               Y = 0;
@@ -1752,177 +1501,156 @@ CSR_API(CsrWriteConsoleOutputChar)
         }
     }
 
-  if (! TextMode && NULL != Buff->Console)
+  if (NULL != Console && Buff == Console->ActiveBuffer)
     {
-      CsrpPhysicalToLogical(Buff, X - 1, Y, &(UpdateRect.Right), &(UpdateRect.Bottom));
-      CsrpDrawRegion(Buff->Console, UpdateRect);
-    }
-  else if (TextMode && ActiveConsole->ActiveBuffer == Buff)
-    {
-      Status = NtDeviceIoControlFile(ConsoleDeviceHandle,
-                                     NULL,
-                                    NULL,
-                                    NULL,
-                                    &Iosb,
-                                    IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
-                                    &Request->Data.WriteConsoleOutputCharRequest.Coord,
-                                    sizeof(COORD) + Request->Data.WriteConsoleOutputCharRequest.Length,
-                                    NULL,
-                                    0);
-      if (! NT_SUCCESS(Status))
-        {
-          DPRINT1( "Failed to write output chars: %x\n", Status );
-        }
+      ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputCharRequest.Coord,
+                             Request->Data.WriteConsoleOutputCharRequest.Length);
+      ConioDrawRegion(Console, &UpdateRect);
     }
+
   Reply->Data.WriteConsoleOutputCharReply.EndCoord.X = X - Buff->ShowX;
   Reply->Data.WriteConsoleOutputCharReply.EndCoord.Y = (Y + Buff->MaxY - Buff->ShowY) % Buff->MaxY;
-  UNLOCK;
+
+  ConioUnlockScreenBuffer(Buff);
+  if (NULL != Console)
+    {
+      ConioUnlockConsole(Console);
+    }
+
   return Reply->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrFillOutputChar)
 {
-   PCSRSS_SCREEN_BUFFER Buff;
-   DWORD X, Y, Length;
-   BYTE Char;
-   OUTPUT_CHARACTER Character;
-   PBYTE Buffer;
-   NTSTATUS Status;
-   IO_STATUS_BLOCK Iosb;
-   SMALL_RECT UpdateRect;
-
-   DPRINT("CsrFillOutputChar\n");
+  NTSTATUS Status;
+  PCSRSS_CONSOLE Console;
+  PCSRSS_SCREEN_BUFFER Buff;
+  DWORD X, Y, Length;
+  BYTE Char;
+  PBYTE Buffer;
+  RECT UpdateRect;
+
+  DPRINT("CsrFillOutputChar\n");
    
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
-     sizeof(LPC_MESSAGE);
-
-   LOCK;
-   if( !NT_SUCCESS( Win32CsrGetObject( ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, (Object_t **)&Buff ) ) || Buff->Header.Type != CONIO_SCREEN_BUFFER_MAGIC )
-      {
-        UNLOCK;
-        return Reply->Status = STATUS_INVALID_HANDLE;
-      }
-   X = Request->Data.FillOutputRequest.Position.X + Buff->ShowX;
-   Y = (Request->Data.FillOutputRequest.Position.Y + Buff->ShowY) % Buff->MaxY;
-   Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
-   Char = Request->Data.FillOutputRequest.Char;
-   Length = Request->Data.FillOutputRequest.Length;
-   CsrpPhysicalToLogical(Buff, X, Y, &(UpdateRect.Left), &(UpdateRect.Top));
-   while (Length--)
-   {
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
+
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff);
+  if (! NT_SUCCESS(Status))
+    {
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
+      return Reply->Status = Status;
+    }
+
+  X = Request->Data.FillOutputRequest.Position.X + Buff->ShowX;
+  Y = (Request->Data.FillOutputRequest.Position.Y + Buff->ShowY) % Buff->MaxY;
+  Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
+  Char = Request->Data.FillOutputRequest.Char;
+  Length = Request->Data.FillOutputRequest.Length;
+  while (Length--)
+    {
       *Buffer = Char;
       Buffer += 2;
-      if( ++X == Buff->MaxX )
-      {
-         if (! TextMode && NULL != Buff->Console)
-         {
-            CsrpPhysicalToLogical(Buff, X - 1, Y, &(UpdateRect.Right), &(UpdateRect.Bottom));
-            CsrpDrawRegion(Buff->Console, UpdateRect);
-            CsrpPhysicalToLogical(Buff, 0, Y + 1, &(UpdateRect.Left), &(UpdateRect.Top));
-         }
-         if( ++Y == Buff->MaxY )
-        {
-           Y = 0;
-           Buffer = Buff->Buffer;
-        }
-        X = 0;
-      }
-   }
-   if (! TextMode && NULL != Buff->Console)
-     {
-       CsrpPhysicalToLogical(Buff, X - 1, Y, &(UpdateRect.Right), &(UpdateRect.Bottom));
-       CsrpDrawRegion(Buff->Console, UpdateRect);
-     }
-   else if (TextMode && Buff == ActiveConsole->ActiveBuffer)
-     {
-       Character.dwCoord = Request->Data.FillOutputRequest.Position;
-       Character.cCharacter = Char;
-       Character.nLength = Request->Data.FillOutputRequest.Length;
-       Status = NtDeviceIoControlFile(ConsoleDeviceHandle, 
-                                      NULL, 
-                                      NULL, 
-                                      NULL, 
-                                      &Iosb,
-                                      IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER,
-                                      &Character,
-                                      sizeof(Character),
-                                      NULL,
-                                      0);
-       if (!NT_SUCCESS(Status))
-         DPRINT1( "Failed to write output characters to console\n" );
-     }
-   UNLOCK;
-   return Reply->Status;
+      if (++X == Buff->MaxX)
+        {
+          if (++Y == Buff->MaxY)
+            {
+              Y = 0;
+              Buffer = Buff->Buffer;
+            }
+          X = 0;
+        }
+    }
+
+  if (NULL != Console && Buff == Console->ActiveBuffer)
+    {
+      ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputRequest.Position,
+                             Request->Data.FillOutputRequest.Length);
+      ConioDrawRegion(Console, &UpdateRect);
+    }
+
+  ConioUnlockScreenBuffer(Buff);
+  if (NULL != Console)
+    {
+      ConioUnlockConsole(Console);
+    }
+
+  return Reply->Status;
 }
 
 CSR_API(CsrReadInputEvent)
 {
-   PLIST_ENTRY CurrentEntry;
-   PCSRSS_CONSOLE Console;
-   NTSTATUS Status;
-   BOOLEAN Done = FALSE;
-   ConsoleInput *Input;
+  PLIST_ENTRY CurrentEntry;
+  PCSRSS_CONSOLE Console;
+  NTSTATUS Status;
+  BOOLEAN Done = FALSE;
+  ConsoleInput *Input;
    
-   DPRINT("CsrReadInputEvent\n");
+  DPRINT("CsrReadInputEvent\n");
 
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
-      sizeof(LPC_MESSAGE);
-   Reply->Data.ReadInputReply.Event = ProcessData->ConsoleEvent;
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Reply->Data.ReadInputReply.Event = ProcessData->ConsoleEvent;
    
-   LOCK;
-   Status = Win32CsrGetObject( ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, (Object_t **)&Console );
-   if( !NT_SUCCESS( Status ) || (Status = Console->Header.Type == CONIO_CONSOLE_MAGIC ? 0 : STATUS_INVALID_HANDLE))
-      {
-         Reply->Status = Status;
-         UNLOCK;
-         return Status;
-      }
-
-   // only get input if there is any
-   while( Console->InputEvents.Flink != &Console->InputEvents &&
-         !Done )
-     {
-       CurrentEntry = RemoveHeadList(&Console->InputEvents);
-       Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
-       Done = !Input->Fake;
-       Reply->Data.ReadInputReply.Input = Input->InputEvent;
-
-       if( Input->InputEvent.EventType == KEY_EVENT )
-        {
-          if( Console->Mode & ENABLE_LINE_INPUT &&
-              Input->InputEvent.Event.KeyEvent.bKeyDown == TRUE &&
-              Input->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\r' ) {
-            Console->WaitingLines--;
-           }
-          Console->WaitingChars--;
-        }
-       RtlFreeHeap( Win32CsrApiHeap, 0, Input );
-
-       Reply->Data.ReadInputReply.MoreEvents = (Console->InputEvents.Flink != &Console->InputEvents) ? TRUE : FALSE;
-       Status = STATUS_SUCCESS;
-       Console->EarlyReturn = FALSE; // clear early return
-     }
+  Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
+
+  /* only get input if there is any */
+  while (Console->InputEvents.Flink != &Console->InputEvents && ! Done)
+    {
+      CurrentEntry = RemoveHeadList(&Console->InputEvents);
+      Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
+      Done = !Input->Fake;
+      Reply->Data.ReadInputReply.Input = Input->InputEvent;
+
+      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)
+            {
+              Console->WaitingLines--;
+            }
+          Console->WaitingChars--;
+        }
+      HeapFree(Win32CsrApiHeap, 0, Input);
+
+      Reply->Data.ReadInputReply.MoreEvents = (Console->InputEvents.Flink != &Console->InputEvents);
+      Status = STATUS_SUCCESS;
+      Console->EarlyReturn = FALSE; /* clear early return */
+    }
    
-   if( !Done )
-     {
-       Status = STATUS_PENDING;
-       Console->EarlyReturn = TRUE;  // mark for early return
-     }
+  if (! Done)
+    {
+      Status = STATUS_PENDING;
+      Console->EarlyReturn = TRUE;  /* mark for early return */
+    }
+
+  ConioUnlockConsole(Console);
 
-   UNLOCK;
-   return Reply->Status = Status;
+  return Reply->Status = Status;
 }
 
 CSR_API(CsrWriteConsoleOutputAttrib)
 {
+  PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
   PUCHAR Buffer, Attribute;
-  NTSTATUS Status;
   int X, Y, Length;
-  IO_STATUS_BLOCK Iosb;
-  SMALL_RECT UpdateRect;
+  NTSTATUS Status;
+  RECT UpdateRect;
 
   DPRINT("CsrWriteConsoleOutputAttrib\n");
    
@@ -1938,35 +1666,35 @@ CSR_API(CsrWriteConsoleOutputAttrib)
       return Reply->Status = STATUS_INVALID_PARAMETER;
     }
 
-  LOCK;
-  Status = Win32CsrGetObject(ProcessData,
-                             Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle,
-                             (Object_t **) &Buff);
-  if (! NT_SUCCESS(Status)
-      || (Status = Buff->Header.Type == CONIO_SCREEN_BUFFER_MAGIC ? 0 : STATUS_INVALID_HANDLE ))
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
     {
-      Reply->Status = Status;
-      UNLOCK;
-      return Status;
+      return Reply->Status = Status;
+    }
+
+  Status = ConioLockScreenBuffer(ProcessData,
+                                 Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle,
+                                 &Buff);
+  if (! NT_SUCCESS(Status))
+    {
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
+      return Reply->Status = Status;
     }
+
   X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X + Buff->ShowX;
   Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->ShowY) % Buff->MaxY;
   Length = Request->Data.WriteConsoleOutputAttribRequest.Length;
   Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1];
   Attribute = Request->Data.WriteConsoleOutputAttribRequest.String;
-  CsrpPhysicalToLogical(Buff, X, Y, &(UpdateRect.Left), &(UpdateRect.Top));
   while (Length--)
     {
       *Buffer = *Attribute++;
       Buffer += 2;
-      if( ++X == Buff->MaxX )
+      if (++X == Buff->MaxX)
         {
-          if (! TextMode && NULL != Buff->Console)
-            {
-              CsrpPhysicalToLogical(Buff, X - 1, Y, &(UpdateRect.Right), &(UpdateRect.Bottom));
-              CsrpDrawRegion(Buff->Console, UpdateRect);
-              CsrpPhysicalToLogical(Buff, 0, Y + 1, &(UpdateRect.Left), &(UpdateRect.Top));
-            }
           if (++Y == Buff->MaxY)
             {
               Y = 0;
@@ -1976,370 +1704,394 @@ CSR_API(CsrWriteConsoleOutputAttrib)
         }
     }
 
-  if (! TextMode && NULL != Buff->Console)
+  if (NULL != Console && Buff == Console->ActiveBuffer)
     {
-      CsrpPhysicalToLogical(Buff, X - 1, Y, &(UpdateRect.Right), &(UpdateRect.Bottom));
-      CsrpDrawRegion(Buff->Console, UpdateRect);
+      ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputAttribRequest.Coord,
+                             Request->Data.WriteConsoleOutputAttribRequest.Length);
+      ConioDrawRegion(Console, &UpdateRect);
     }
-  else if (TextMode && Buff == ActiveConsole->ActiveBuffer)
+
+  if (NULL != Console)
     {
-      Status = NtDeviceIoControlFile(ConsoleDeviceHandle,
-                                     NULL,
-                                     NULL,
-                                     NULL,
-                                     &Iosb,
-                                     IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE,
-                                     &Request->Data.WriteConsoleOutputAttribRequest.Coord,
-                                     Request->Data.WriteConsoleOutputAttribRequest.Length +
-                                     sizeof(COORD),
-                                     NULL,
-                                     0);
-      if (! NT_SUCCESS(Status))
-        {
-          DPRINT1( "Failed to write output attributes to console\n" );
-        }
+      ConioUnlockConsole(Console);
     }
 
   Reply->Data.WriteConsoleOutputAttribReply.EndCoord.X = Buff->CurrentX - Buff->ShowX;
-  Reply->Data.WriteConsoleOutputAttribReply.EndCoord.Y = ( Buff->CurrentY + Buff->MaxY - Buff->ShowY ) % Buff->MaxY;
-  UNLOCK;
+  Reply->Data.WriteConsoleOutputAttribReply.EndCoord.Y = (Buff->CurrentY + Buff->MaxY - Buff->ShowY) % Buff->MaxY;
+
+  ConioUnlockScreenBuffer(Buff);
 
   return Reply->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrFillOutputAttrib)
 {
-   OUTPUT_ATTRIBUTE Attribute;
-   PCSRSS_SCREEN_BUFFER Buff;
-   PCHAR Buffer;
-   NTSTATUS Status;
-   int X, Y, Length;
-   IO_STATUS_BLOCK Iosb;
-   UCHAR Attr;
-   SMALL_RECT UpdateRect;
-
-   DPRINT("CsrFillOutputAttrib\n");
+  PCSRSS_SCREEN_BUFFER Buff;
+  PCHAR Buffer;
+  NTSTATUS Status;
+  int X, Y, Length;
+  UCHAR Attr;
+  RECT UpdateRect;
+  PCSRSS_CONSOLE Console;
+
+  DPRINT("CsrFillOutputAttrib\n");
+
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
    
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
-      sizeof(LPC_MESSAGE);
-   LOCK;
-   Status = Win32CsrGetObject( ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, (Object_t **)&Buff );
-   if( !NT_SUCCESS( Status ) || (Status = Buff->Header.Type == CONIO_SCREEN_BUFFER_MAGIC ? 0 : STATUS_INVALID_HANDLE ))
-      {
-        Reply->Status = Status;
-        UNLOCK;
-        return Status;
-      }
-   X = Request->Data.FillOutputAttribRequest.Coord.X + Buff->ShowX;
-   Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->ShowY) % Buff->MaxY;
-   Length = Request->Data.FillOutputAttribRequest.Length;
-   Attr = Request->Data.FillOutputAttribRequest.Attribute;
-   Buffer = &Buff->Buffer[(Y * Buff->MaxX * 2) + (X * 2) + 1];
-   UpdateRect.Left = X;
-   UpdateRect.Top = Y;
-   while(Length--)
-   {
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff);
+  if (! NT_SUCCESS(Status))
+    {
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
+      return Reply->Status = Status;
+    }
+
+  X = Request->Data.FillOutputAttribRequest.Coord.X + Buff->ShowX;
+  Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->ShowY) % Buff->MaxY;
+  Length = Request->Data.FillOutputAttribRequest.Length;
+  Attr = Request->Data.FillOutputAttribRequest.Attribute;
+  Buffer = &Buff->Buffer[(Y * Buff->MaxX * 2) + (X * 2) + 1];
+  while (Length--)
+    {
       *Buffer = Attr;
       Buffer += 2;
-      if( ++X == Buff->MaxX )
-      {
-         if (! TextMode && NULL != Buff->Console)
-         {
-            UpdateRect.Right = X - 1;
-            UpdateRect.Bottom = Y;
-            CsrpDrawRegion(Buff->Console, UpdateRect);
-            UpdateRect.Left = 0;
-            UpdateRect.Top = Y + 1;
-         }
-        if( ++Y == Buff->MaxY )
-        {
-           Y = 0;
-           Buffer = Buff->Buffer + 1;
-            UpdateRect.Top = 0;
-        }
-         X = 0;
-      }
-   }
-   UpdateRect.Right = X - 1;
-   UpdateRect.Bottom = Y;
-   if (! TextMode && NULL != Buff->Console)
-     {
-       CsrpDrawRegion(Buff->Console, UpdateRect);
-     }
-   else if (TextMode && Buff == ActiveConsole->ActiveBuffer)
-     {
-       Attribute.wAttribute = Attr;
-       Attribute.nLength = Request->Data.FillOutputAttribRequest.Length;
-       Attribute.dwCoord = Request->Data.FillOutputAttribRequest.Coord;
-       Status = NtDeviceIoControlFile(ConsoleDeviceHandle, 
-                                     NULL, 
-                                     NULL, 
-                                     NULL, 
-                                     &Iosb,
-                                     IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE, 
-                                     &Attribute,
-                                     sizeof(OUTPUT_ATTRIBUTE), 
-                                     NULL, 
-                                     0);
-       if( !NT_SUCCESS( Status ) )
-         DPRINT1( "Failed to fill output attributes to console\n" );
-     }
-   UNLOCK;
-   return Reply->Status = STATUS_SUCCESS;
+      if (++X == Buff->MaxX)
+        {
+          if (++Y == Buff->MaxY)
+            {
+              Y = 0;
+              Buffer = Buff->Buffer + 1;
+            }
+          X = 0;
+        }
+    }
+
+  if (NULL != Console && Buff == Console->ActiveBuffer)
+    {
+      ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputAttribRequest.Coord,
+                             Request->Data.FillOutputAttribRequest.Length);
+      ConioDrawRegion(Console, &UpdateRect);
+    }
+
+  ConioUnlockScreenBuffer(Buff);
+  if (NULL != Console)
+    {
+      ConioUnlockConsole(Console);
+    }
+
+  return Reply->Status = STATUS_SUCCESS;
 }
 
 
 CSR_API(CsrGetCursorInfo)
 {
-   PCSRSS_SCREEN_BUFFER Buff;
-   NTSTATUS Status;
+  PCSRSS_SCREEN_BUFFER Buff;
+  NTSTATUS Status;
    
-   DPRINT("CsrGetCursorInfo\n");
-
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
-      sizeof(LPC_MESSAGE);
-   LOCK;
-   Status = Win32CsrGetObject( ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, (Object_t **)&Buff );
-   if( !NT_SUCCESS( Status ) || (Status = Buff->Header.Type == CONIO_SCREEN_BUFFER_MAGIC ? 0 : STATUS_INVALID_HANDLE ))
-      {
-        Reply->Status = Status;
-        UNLOCK;
-        return Status;
-      }
-   Reply->Data.GetCursorInfoReply.Info = Buff->CursorInfo;
-   UNLOCK;
-   return Reply->Status = STATUS_SUCCESS;
+  DPRINT("CsrGetCursorInfo\n");
+
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
+  Reply->Data.GetCursorInfoReply.Info = Buff->CursorInfo;
+  ConioUnlockScreenBuffer(Buff);
+
+  return Reply->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetCursorInfo)
 {
+  PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
+  DWORD Size;
+  BOOL Visible;
   NTSTATUS Status;
-  IO_STATUS_BLOCK Iosb;
-  SMALL_RECT UpdateRect;
    
   DPRINT("CsrSetCursorInfo\n");
 
   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-  LOCK;
-  Status = Win32CsrGetObject( ProcessData,
-     Request->Data.SetCursorInfoRequest.ConsoleHandle, (Object_t **)&Buff );
 
-  if (! NT_SUCCESS(Status) || (Status = Buff->Header.Type == CONIO_SCREEN_BUFFER_MAGIC ? 0 : STATUS_INVALID_HANDLE ))
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
     {
-      Reply->Status = Status;
-      UNLOCK;
-      return Status;
+      return Reply->Status = Status;
     }
-  RtlEnterCriticalSection(&(Buff->Lock));
-  Buff->CursorInfo = Request->Data.SetCursorInfoRequest.Info;
-  if (Buff->CursorInfo.dwSize < 1)
+
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff);
+  if (! NT_SUCCESS(Status))
     {
-      Buff->CursorInfo.dwSize = 1;
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
+      return Reply->Status = Status;
     }
-  if (100 < Buff->CursorInfo.dwSize)
+
+  Size = Request->Data.SetCursorInfoRequest.Info.dwSize;
+  Visible = Request->Data.SetCursorInfoRequest.Info.bVisible;
+  if (Size < 1)
     {
-      Buff->CursorInfo.dwSize = 100;
+      Size = 1;
     }
-  if (! TextMode && ProcessData->Console->ActiveBuffer == Buff)
+  if (100 < Size)
     {
-      CsrpPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
-                            &UpdateRect.Left, &UpdateRect.Top);
-      UpdateRect.Right = UpdateRect.Left;
-      UpdateRect.Bottom = UpdateRect.Top;
-      CsrpDrawRegion(ProcessData->Console, UpdateRect);
+      Size = 100;
     }
-  else if (TextMode && Buff == ActiveConsole->ActiveBuffer)
+
+  if (Size != Buff->CursorInfo.dwSize
+      || (Visible && ! Buff->CursorInfo.bVisible) || (! Visible && Buff->CursorInfo.bVisible))
     {
-      Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_CURSOR_INFO, &Buff->CursorInfo, sizeof( Buff->CursorInfo ), 0, 0 );
-      if (! NT_SUCCESS(Status))
+      Buff->CursorInfo.dwSize = Size;
+      Buff->CursorInfo.bVisible = Visible;
+
+      if (NULL != Console && ! ConioSetCursorInfo(Console, Buff))
         {
-          DbgPrint( "CSR: Failed to set cursor info\n" );
-          return Reply->Status = Status;
+          ConioUnlockScreenBuffer(Buff);
+          ConioUnlockConsole(Console);
+          return Reply->Status = STATUS_UNSUCCESSFUL;
         }
     }
-  RtlLeaveCriticalSection(&(Buff->Lock));
-  UNLOCK;
+
+  ConioUnlockScreenBuffer(Buff);
+  if (NULL != Console)
+    {
+      ConioUnlockConsole(Console);
+    }
 
   return Reply->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetTextAttrib)
 {
-   NTSTATUS Status;
-   CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
-   IO_STATUS_BLOCK Iosb;
-   PCSRSS_SCREEN_BUFFER Buff;
+  NTSTATUS Status;
+  PCSRSS_CONSOLE Console;
+  PCSRSS_SCREEN_BUFFER Buff;
+  LONG OldCursorX, OldCursorY;   
 
-   DPRINT("CsrSetTextAttrib\n");
-   
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
-      sizeof(LPC_MESSAGE);
-   LOCK;
-   Status = Win32CsrGetObject( ProcessData, Request->Data.SetAttribRequest.ConsoleHandle, (Object_t **)&Buff );
-   if( !NT_SUCCESS( Status ) || (Status = Buff->Header.Type == CONIO_SCREEN_BUFFER_MAGIC ? 0 : STATUS_INVALID_HANDLE ))
-      {
-        Reply->Status = Status;
-        UNLOCK;
-        return Status;
-      }
-   Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib;
-   if (! TextMode && Buff == ActiveConsole->ActiveBuffer)
-      {
-        ScrInfo.wAttributes = Buff->DefaultAttrib;
-        ScrInfo.dwCursorPosition.X = Buff->CurrentX - Buff->ShowX;   
-        ScrInfo.dwCursorPosition.Y = ((Buff->CurrentY + Buff->MaxY) - Buff->ShowY) % Buff->MaxY;
-        Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, &ScrInfo, sizeof( ScrInfo ), 0, 0 );
-        if( !NT_SUCCESS( Status ) )
-           {
-              DbgPrint( "CSR: Failed to set console info\n" );
-              UNLOCK;
-              return Reply->Status = Status;
-           }
-      }
-   UNLOCK;
-   return Reply->Status = STATUS_SUCCESS;
+  DPRINT("CsrSetTextAttrib\n");
+
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
+
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff);
+  if (! NT_SUCCESS(Status))
+    {
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
+      return Reply->Status = Status;
+    }
+
+  ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &OldCursorX, &OldCursorY);
+
+  Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib;
+  if (NULL != Console && Buff == Console->ActiveBuffer)
+    {
+      if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
+        {
+          ConioUnlockScreenBuffer(Buff);
+          ConioUnlockConsole(Console);
+          return Reply->Status = STATUS_UNSUCCESSFUL;
+        }
+    }
+
+  ConioUnlockScreenBuffer(Buff);
+  if (NULL != Console)
+    {
+      ConioUnlockConsole(Console);
+    }
+
+  return Reply->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetConsoleMode)
 {
-   NTSTATUS Status;
-   PCSRSS_CONSOLE Console;
-   PCSRSS_SCREEN_BUFFER Buff;
-
-   DPRINT("CsrSetConsoleMode\n");
-
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-   LOCK;
-   Status = Win32CsrGetObject( ProcessData,
-     Request->Data.SetConsoleModeRequest.ConsoleHandle,
-     (Object_t **)&Console );
-   if( !NT_SUCCESS( Status ) )
-      {
-        Reply->Status = Status;
-        UNLOCK;
-        return Status;
-      }
-
-   Buff = (PCSRSS_SCREEN_BUFFER)Console;
-   if( Console->Header.Type == CONIO_CONSOLE_MAGIC )
+  NTSTATUS Status;
+  PCSRSS_CONSOLE Console;
+  PCSRSS_SCREEN_BUFFER Buff;
+
+  DPRINT("CsrSetConsoleMode\n");
+
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Status = Win32CsrGetObject(ProcessData,
+                             Request->Data.SetConsoleModeRequest.ConsoleHandle,
+                             (Object_t **) &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
+
+  Buff = (PCSRSS_SCREEN_BUFFER)Console;
+  if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
+    {
       Console->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_INPUT_MODE_VALID;
-   else if( Console->Header.Type == CONIO_SCREEN_BUFFER_MAGIC )
+    }
+  else if (CONIO_SCREEN_BUFFER_MAGIC == Console->Header.Type)
+    {
       Buff->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_OUTPUT_MODE_VALID;
-   else {
-      Reply->Status = STATUS_INVALID_HANDLE;
-      UNLOCK;
-      return Status;
-   }
-   UNLOCK;
-   Reply->Status = STATUS_SUCCESS;
-   return Reply->Status;
+    }
+  else
+    {
+      return Reply->Status = STATUS_INVALID_HANDLE;
+    }
+
+  Reply->Status = STATUS_SUCCESS;
+
+  return Reply->Status;
 }
 
 CSR_API(CsrGetConsoleMode)
 {
-   NTSTATUS Status;
-   PCSRSS_CONSOLE Console;
-   PCSRSS_SCREEN_BUFFER Buff;   /* gee, I really wish I could use an anonymous union here */
-
-   DPRINT("CsrGetConsoleMode\n");
-
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-   LOCK;
-   Status = Win32CsrGetObject( ProcessData,
-     Request->Data.GetConsoleModeRequest.ConsoleHandle,
-     (Object_t **)&Console );
-   if( !NT_SUCCESS( Status ) )
-      {
-        Reply->Status = Status;
-        UNLOCK;
-        return Status;
-      }
-   Reply->Status = STATUS_SUCCESS;
-   Buff = (PCSRSS_SCREEN_BUFFER)Console;
-   if( Console->Header.Type == CONIO_CONSOLE_MAGIC )
+  NTSTATUS Status;
+  PCSRSS_CONSOLE Console;
+  PCSRSS_SCREEN_BUFFER Buff;   /* gee, I really wish I could use an anonymous union here */
+
+  DPRINT("CsrGetConsoleMode\n");
+
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Status = Win32CsrGetObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
+                             (Object_t **) &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
+  Reply->Status = STATUS_SUCCESS;
+  Buff = (PCSRSS_SCREEN_BUFFER) Console;
+  if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
+    {
       Reply->Data.GetConsoleModeReply.ConsoleMode = Console->Mode;
-   else if( Buff->Header.Type == CONIO_SCREEN_BUFFER_MAGIC )
+    }
+  else if (CONIO_SCREEN_BUFFER_MAGIC == Buff->Header.Type)
+    {
       Reply->Data.GetConsoleModeReply.ConsoleMode = Buff->Mode;
-   else Status = STATUS_INVALID_HANDLE;
-   UNLOCK;
-   return Reply->Status;
+    }
+  else
+    {
+      Reply->Status = STATUS_INVALID_HANDLE;
+    }
+
+  return Reply->Status;
 }
 
 CSR_API(CsrCreateScreenBuffer)
 {
-   PCSRSS_SCREEN_BUFFER Buff;
-   NTSTATUS Status;
+  PCSRSS_CONSOLE Console;
+  PCSRSS_SCREEN_BUFFER Buff;
+  NTSTATUS Status;
    
-   DPRINT("CsrCreateScreenBuffer\n");
+  DPRINT("CsrCreateScreenBuffer\n");
 
-   Reply->Header.MessageSize = sizeof( CSRSS_API_REPLY );
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  if (ProcessData == NULL)
+    {
+      return Reply->Status = STATUS_INVALID_PARAMETER;
+    }
 
-   if (ProcessData == NULL)
-   {
-     return(Reply->Status = STATUS_INVALID_PARAMETER);
-   }
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
+  if (NULL == Console)
+    {
+      return Reply->Status = STATUS_INVALID_HANDLE;
+    }
+
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
 
-   Buff = RtlAllocateHeap( Win32CsrApiHeap, 0, sizeof( CSRSS_SCREEN_BUFFER ) );
-   if( !Buff )
+  Buff = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_SCREEN_BUFFER));
+  if (NULL == Buff)
+    {
       Reply->Status = STATUS_INSUFFICIENT_RESOURCES;
-   LOCK;
-   if (TextMode)
-   {
-     Status = CsrInitConsoleScreenBuffer(Buff, NULL, PhysicalConsoleSize.X, PhysicalConsoleSize.Y);
-   } else {
-     /* FIXME From where do we get the size???? */
-     Status = CsrInitConsoleScreenBuffer(Buff, NULL, 80, 25);
-   }
-   if( !NT_SUCCESS( Status ) )
+    }
+
+  Status = CsrInitConsoleScreenBuffer(Console, Buff);
+  if(! NT_SUCCESS(Status))
+    {
       Reply->Status = Status;
-   else {
-      Status = Win32CsrInsertObject( ProcessData, &Reply->Data.CreateScreenBufferReply.OutputHandle, &Buff->Header );
-      if( !NT_SUCCESS( Status ) )
-        Reply->Status = Status;
-      else Reply->Status = STATUS_SUCCESS;
-   }
-   UNLOCK;
-   return Reply->Status;
+    }
+  else
+    {
+      Reply->Status = Win32CsrInsertObject(ProcessData, &Reply->Data.CreateScreenBufferReply.OutputHandle, &Buff->Header);
+    }
+
+  ConioUnlockConsole(Console);
+
+  return Reply->Status;
 }
 
 CSR_API(CsrSetScreenBuffer)
 {
-   NTSTATUS Status;
-   PCSRSS_SCREEN_BUFFER Buff;
+  NTSTATUS Status;
+  PCSRSS_CONSOLE Console;
+  PCSRSS_SCREEN_BUFFER Buff;
 
-   DPRINT("CsrSetScreenBuffer\n");
+  DPRINT("CsrSetScreenBuffer\n");
 
-   Reply->Header.MessageSize = sizeof( CSRSS_API_REPLY );
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-   LOCK;
-   Status = Win32CsrGetObject( ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, (Object_t **)&Buff );
-   if( !NT_SUCCESS( Status ) )
-      Reply->Status = Status;
-   else {
-      // drop reference to old buffer, maybe delete
-      ProcessData->Console->ActiveBuffer->Console = NULL;
-      if( !InterlockedDecrement( &ProcessData->Console->ActiveBuffer->Header.ReferenceCount ) )
-        ConioDeleteScreenBuffer((Object_t *) ProcessData->Console->ActiveBuffer);
-      // tie console to new buffer
-      ProcessData->Console->ActiveBuffer = Buff;
-      Buff->Console = ProcessData->Console;
-      // inc ref count on new buffer
-      InterlockedIncrement( &Buff->Header.ReferenceCount );
-      // if the console is active, redraw it
-      if (! TextMode || ActiveConsole == ProcessData->Console)
-        CsrDrawConsole(ProcessData->Console);
-      Reply->Status = STATUS_SUCCESS;
-   }
-   UNLOCK;
-   return Reply->Status;
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
+  if (NULL == Console)
+    {
+      DPRINT1("Trying to set screen buffer for app without console\n");
+      return Reply->Status = STATUS_INVALID_HANDLE;
+    }
+
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff);
+  if (! NT_SUCCESS(Status))
+    {
+      ConioUnlockConsole(Console);
+      return Reply->Status;
+    }
+
+  if (Buff == Console->ActiveBuffer)
+    {
+      ConioUnlockScreenBuffer(Buff);
+      ConioUnlockConsole(Console);
+      return STATUS_SUCCESS;
+    }
+
+  /* drop reference to old buffer, maybe delete */
+  if (! InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
+    {
+      ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
+    }
+  /* tie console to new buffer */
+  Console->ActiveBuffer = Buff;
+  /* inc ref count on new buffer */
+  InterlockedIncrement(&Buff->Header.ReferenceCount);
+  /* Redraw the console */
+  ConioDrawConsole(Console);
+
+  ConioUnlockScreenBuffer(Buff);
+  ConioUnlockConsole(Console);
+
+  return Reply->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetTitle)
@@ -2347,163 +2099,171 @@ CSR_API(CsrSetTitle)
   NTSTATUS Status;
   PCSRSS_CONSOLE Console;
 
-  DPRINT("CsrSetTitle\n");
+  DPRINT("CsrSetTitle\n");
+
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+
+  if (Request->Header.DataSize
+      < sizeof(CSRSS_SET_TITLE_REQUEST) - 1
+        + Request->Data.SetTitleRequest.Length)
+    {
+      DPRINT1("Invalid request size\n");
+      return Reply->Status = STATUS_INVALID_PARAMETER;
+    }
+
+  Status = ConioLockConsole(ProcessData, Request->Data.SetTitleRequest.Console, &Console);
+  if(! NT_SUCCESS(Status))
+    {
+      Reply->Status = Status;  
+    }
+  else
+    {
+      /* copy title to console */
+      RtlFreeUnicodeString(&Console->Title);
+      RtlCreateUnicodeString(&Console->Title, Request->Data.SetTitleRequest.Title);
+      if (! ConioChangeTitle(Console))
+        {
+          Reply->Status = STATUS_UNSUCCESSFUL;
+        }
+      else
+        {
+          Reply->Status = STATUS_SUCCESS;
+        }
+    }
+  ConioUnlockConsole(Console);
+
+  return Reply->Status;
+}
+
+CSR_API(CsrGetTitle)
+{
+  NTSTATUS Status;
+  PCSRSS_CONSOLE Console;
+  
+  DPRINT("CsrGetTitle\n");
+
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Status = ConioLockConsole(ProcessData,
+                            Request->Data.GetTitleRequest.ConsoleHandle,
+                            &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      DPRINT1("Can't get console\n");
+      return Reply->Status = Status;
+    }
+               
+  /* Copy title of the console to the user title buffer */
+  RtlZeroMemory(&Reply->Data.GetTitleReply, sizeof(CSRSS_GET_TITLE_REPLY));
+  Reply->Data.GetTitleReply.ConsoleHandle = Request->Data.GetTitleRequest.ConsoleHandle;
+  Reply->Data.GetTitleReply.Length = Console->Title.Length;
+  wcscpy (Reply->Data.GetTitleReply.Title, Console->Title.Buffer);
+  Reply->Header.MessageSize += Console->Title.Length;
+  Reply->Header.DataSize += Console->Title.Length;
+  Reply->Status = STATUS_SUCCESS;
+
+  ConioUnlockConsole(Console);
+
+  return Reply->Status;
+}
+
+CSR_API(CsrWriteConsoleOutput)
+{
+  SHORT i, X, Y, SizeX, SizeY;
+  PCSRSS_CONSOLE Console;
+  PCSRSS_SCREEN_BUFFER Buff;
+  RECT ScreenBuffer;
+  CHAR_INFO* CurCharInfo;
+  RECT WriteRegion;
+  CHAR_INFO* CharInfo;
+  COORD BufferCoord;
+  COORD BufferSize;
+  NTSTATUS Status;
+  DWORD Offset;
+  DWORD PSize;
+
+  DPRINT("CsrWriteConsoleOutput\n");
+
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
 
-  Reply->Header.MessageSize = sizeof( CSRSS_API_REPLY );
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Status = ConioLockScreenBuffer(ProcessData,
+                                 Request->Data.WriteConsoleOutputRequest.ConsoleHandle,
+                                 &Buff);
+  if (! NT_SUCCESS(Status))
+    {
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
+      return Reply->Status = Status;
+    }
 
-  if (Request->Header.DataSize
-      < sizeof(CSRSS_SET_TITLE_REQUEST) - 1
-        + Request->Data.SetTitleRequest.Length)
+  BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize;
+  PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO);
+  BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord;
+  CharInfo = Request->Data.WriteConsoleOutputRequest.CharInfo;
+  if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) ||
+      (((PVOID)CharInfo + PSize) > 
+       (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
     {
-      DPRINT1("Invalid request size\n");
-      return Reply->Status = STATUS_INVALID_PARAMETER;
+      ConioUnlockScreenBuffer(Buff);
+      ConioUnlockConsole(Console);
+      return Reply->Status = STATUS_ACCESS_VIOLATION;
     }
+  WriteRegion.left = Request->Data.WriteConsoleOutputRequest.WriteRegion.Left;
+  WriteRegion.top = Request->Data.WriteConsoleOutputRequest.WriteRegion.Top;
+  WriteRegion.right = Request->Data.WriteConsoleOutputRequest.WriteRegion.Right;
+  WriteRegion.bottom = Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom;
 
-  LOCK;
-  Status = Win32CsrGetObject(ProcessData,
-                             Request->Data.SetTitleRequest.Console,
-                             (Object_t **) &Console);
-  if(! NT_SUCCESS(Status))
+  SizeY = RtlRosMin(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion));
+  SizeX = RtlRosMin(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))
     {
-      Reply->Status = Status;  
+      ConioUnlockScreenBuffer(Buff);
+      ConioUnlockConsole(Console);
+
+      /* It is okay to have a WriteRegion completely outside the screen buffer.
+         No data is written then. */
+      return Reply->Status = STATUS_SUCCESS;
     }
-  else
+
+  for (i = 0, Y = WriteRegion.top; Y <= WriteRegion.bottom; i++, Y++)
     {
-      /* copy title to console */
-      RtlFreeUnicodeString(&Console->Title);
-      RtlCreateUnicodeString(&Console->Title, Request->Data.SetTitleRequest.Title);
-      if (! TextMode)
+      CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X;
+      Offset = (((Y + Buff->ShowY) % Buff->MaxY) * Buff->MaxX + WriteRegion.left) * 2;
+      for (X = WriteRegion.left; X <= WriteRegion.right; X++)
         {
-          GuiConsoleChangeTitle(Console);
+          SET_CELL_BUFFER(Buff, Offset, CurCharInfo->Char.AsciiChar, CurCharInfo->Attributes);
+          CurCharInfo++;
         }
-      Reply->Status = STATUS_SUCCESS;
     }
 
-  UNLOCK;
-
-  return Reply->Status;
-}
+  if (NULL != Console)
+    {
+      ConioDrawRegion(Console, &WriteRegion);
+    }
 
-CSR_API(CsrGetTitle)
-{
-       NTSTATUS        Status;
-       PCSRSS_CONSOLE  Console;
-  
-       DPRINT("CsrGetTitle\n");
-
-       Reply->Header.MessageSize = sizeof (CSRSS_API_REPLY);
-       Reply->Header.DataSize =
-               sizeof (CSRSS_API_REPLY)
-               - sizeof(LPC_MESSAGE);
-       LOCK;
-       Status = Win32CsrGetObject (
-                       ProcessData,
-                       Request->Data.GetTitleRequest.ConsoleHandle,
-                       (Object_t **) & Console
-                       );
-   if ( !NT_SUCCESS( Status ) )
-   {
-      Reply->Status = Status;
-   }
-       else
-       {
-               HANDLE ConsoleHandle = Request->Data.GetTitleRequest.ConsoleHandle;
-               
-               /* Copy title of the console to the user title buffer */
-               RtlZeroMemory (
-                       & Reply->Data.GetTitleReply,
-                       sizeof (CSRSS_GET_TITLE_REPLY)
-                       );
-               Reply->Data.GetTitleReply.ConsoleHandle = ConsoleHandle;
-               Reply->Data.GetTitleReply.Length = Console->Title.Length;
-               wcscpy (Reply->Data.GetTitleReply.Title, Console->Title.Buffer);
-               Reply->Header.MessageSize += Console->Title.Length;
-               Reply->Header.DataSize += Console->Title.Length;
-               Reply->Status = STATUS_SUCCESS;
-       }
-       UNLOCK;
-       return Reply->Status;
-}
+  ConioUnlockScreenBuffer(Buff);
+  ConioUnlockConsole(Console);
 
-CSR_API(CsrWriteConsoleOutput)
-{
-   SHORT i, X, Y, SizeX, SizeY;
-   PCSRSS_SCREEN_BUFFER Buff;
-   SMALL_RECT ScreenBuffer;
-   CHAR_INFO* CurCharInfo;
-   SMALL_RECT WriteRegion;
-   CHAR_INFO* CharInfo;
-   COORD BufferCoord;
-   COORD BufferSize;
-   NTSTATUS Status;
-   DWORD Offset;
-   DWORD PSize;
-
-   DPRINT("CsrWriteConsoleOutput\n");
-
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-   LOCK;
-   Status = Win32CsrGetObject( ProcessData, Request->Data.WriteConsoleOutputRequest.ConsoleHandle, (Object_t **)&Buff );
-   if( !NT_SUCCESS( Status ) || (Status = Buff->Header.Type == CONIO_SCREEN_BUFFER_MAGIC ? STATUS_SUCCESS : STATUS_INVALID_HANDLE ))
-      {
-        Reply->Status = Status;
-        UNLOCK;
-        return Status;
-      }
-
-   BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize;
-   PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO);
-   BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord;
-   CharInfo = Request->Data.WriteConsoleOutputRequest.CharInfo;
-   if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) ||
-       (((PVOID)CharInfo + PSize) > 
-       (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
-     {
-       UNLOCK;
-       Reply->Status = STATUS_ACCESS_VIOLATION;
-       return(Reply->Status);
-     }
-   WriteRegion = Request->Data.WriteConsoleOutputRequest.WriteRegion;
-
-   SizeY = RtlRosMin(BufferSize.Y - BufferCoord.Y, CsrpRectHeight(WriteRegion));
-   SizeX = RtlRosMin(BufferSize.X - BufferCoord.X, CsrpRectWidth(WriteRegion));
-   WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
-   WriteRegion.Right = WriteRegion.Left + SizeX - 1;
-
-   /* Make sure WriteRegion is inside the screen buffer */
-   CsrpInitRect(ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
-   if (!CsrpGetIntersection(&WriteRegion, ScreenBuffer, WriteRegion))
-      {
-         UNLOCK;
-         /* It is okay to have a WriteRegion completely outside the screen buffer.
-            No data is written then. */
-         return (Reply->Status = 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;
-     for ( X = WriteRegion.Left; X <= WriteRegion.Right; X++ )
-      {
-        SET_CELL_BUFFER(Buff, Offset, CurCharInfo->Char.AsciiChar, CurCharInfo->Attributes);
-        CurCharInfo++;
-      }
-   }
-
-   if( Buff == ActiveConsole->ActiveBuffer )
-     {
-        CsrpDrawRegion(ActiveConsole, WriteRegion);
-     }
+  Reply->Data.WriteConsoleOutputReply.WriteRegion.Right = WriteRegion.left + SizeX - 1;
+  Reply->Data.WriteConsoleOutputReply.WriteRegion.Bottom = WriteRegion.top + SizeY - 1;
+  Reply->Data.WriteConsoleOutputReply.WriteRegion.Left = WriteRegion.left;
+  Reply->Data.WriteConsoleOutputReply.WriteRegion.Top = WriteRegion.top;
 
-   UNLOCK;
-   Reply->Data.WriteConsoleOutputReply.WriteRegion.Right = WriteRegion.Left + SizeX - 1;
-   Reply->Data.WriteConsoleOutputReply.WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
-   Reply->Data.WriteConsoleOutputReply.WriteRegion.Left = WriteRegion.Left;
-   Reply->Data.WriteConsoleOutputReply.WriteRegion.Top = WriteRegion.Top;
-   return (Reply->Status = STATUS_SUCCESS);
+  return Reply->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrFlushInputBuffer)
@@ -2517,13 +2277,12 @@ CSR_API(CsrFlushInputBuffer)
 
   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-  LOCK;
-  Status = Win32CsrGetObject( ProcessData, Request->Data.FlushInputBufferRequest.ConsoleInput, (Object_t **)&Console );
-  if( !NT_SUCCESS( Status ) || (Status = Console->Header.Type == CONIO_CONSOLE_MAGIC ? STATUS_SUCCESS : STATUS_INVALID_HANDLE ))
+  Status = ConioLockConsole(ProcessData,
+                            Request->Data.FlushInputBufferRequest.ConsoleInput,
+                            &Console);
+  if(! NT_SUCCESS(Status))
     {
-       Reply->Status = Status;
-       UNLOCK;
-       return Status;
+      return Reply->Status = Status;
     }
 
   /* Discard all entries in the input event queue */
@@ -2532,115 +2291,132 @@ CSR_API(CsrFlushInputBuffer)
       CurrentEntry = RemoveHeadList(&Console->InputEvents);
       Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
       /* Destroy the event */
-      RtlFreeHeap( Win32CsrApiHeap, 0, Input );
+      HeapFree(Win32CsrApiHeap, 0, Input);
     }
   Console->WaitingChars=0;
-  UNLOCK;
 
-  return (Reply->Status = STATUS_SUCCESS);
+  ConioUnlockConsole(Console);
+
+  return Reply->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrScrollConsoleScreenBuffer)
 {
+  PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
-  SMALL_RECT ScreenBuffer;
-  SMALL_RECT SrcRegion;
-  SMALL_RECT DstRegion;
-  SMALL_RECT FillRegion;
+  RECT ScreenBuffer;
+  RECT SrcRegion;
+  RECT DstRegion;
+  RECT FillRegion;
+  RECT ScrollRectangle;
+  RECT ClipRectangle;
   NTSTATUS Status;
   BOOLEAN DoFill;
 
   DPRINT("CsrScrollConsoleScreenBuffer\n");
 
   ALIAS(ConsoleHandle,Request->Data.ScrollConsoleScreenBufferRequest.ConsoleHandle);
-  ALIAS(ScrollRectangle,Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle);
   ALIAS(UseClipRectangle,Request->Data.ScrollConsoleScreenBufferRequest.UseClipRectangle);
-  ALIAS(ClipRectangle,Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle);
   ALIAS(DestinationOrigin,Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin);
   ALIAS(Fill,Request->Data.ScrollConsoleScreenBufferRequest.Fill);
 
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
+
   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-  LOCK;
-  Status = Win32CsrGetObject( ProcessData, ConsoleHandle, (Object_t **)&Buff );
-  if( !NT_SUCCESS( Status ) || (Status = Buff->Header.Type == CONIO_SCREEN_BUFFER_MAGIC ? STATUS_SUCCESS : STATUS_INVALID_HANDLE ))
-  {
-    Reply->Status = Status;
-    UNLOCK;
-    return Status;
-  }
+  Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff);
+  if (! NT_SUCCESS(Status))
+    {
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
+      return Reply->Status = 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 */
-  CsrpInitRect(ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
-  if (!CsrpGetIntersection(&SrcRegion, ScreenBuffer, ScrollRectangle))
+  ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
+  if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle))
     {
-      UNLOCK;
-      return (Reply->Status = STATUS_INVALID_PARAMETER);
+      ConioUnlockScreenBuffer(Buff);
+      return Reply->Status = STATUS_INVALID_PARAMETER;
     }
 
-  if (UseClipRectangle)
+  if (UseClipRectangle && ! ConioGetIntersection(&SrcRegion, &SrcRegion, &ClipRectangle))
     {
-      if (!CsrpGetIntersection(&SrcRegion, SrcRegion, ClipRectangle))
-        {
-          UNLOCK;
-          return (Reply->Status = STATUS_SUCCESS);
-        }
+      ConioUnlockScreenBuffer(Buff);
+      return Reply->Status = STATUS_SUCCESS;
     }
 
 
-  CsrpInitRect(
-    DstRegion,
-    DestinationOrigin.Y,
-    DestinationOrigin.X,
-    DestinationOrigin.Y + CsrpRectHeight(ScrollRectangle) - 1,
-    DestinationOrigin.X + CsrpRectWidth(ScrollRectangle) - 1)
+  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 (!CsrpGetIntersection(&DstRegion, DstRegion, ScreenBuffer))
+  if (! ConioGetIntersection(&DstRegion, &DstRegion, &ScreenBuffer))
     {
-      UNLOCK;
-      return (Reply->Status = STATUS_INVALID_PARAMETER);
+      ConioUnlockScreenBuffer(Buff);
+      return Reply->Status = STATUS_INVALID_PARAMETER;
     }
 
-  CsrpCopyRegion(Buff, SrcRegion, DstRegion);
-
+  ConioCopyRegion(Buff, &SrcRegion, &DstRegion);
 
   /* Get the region that should be filled with the specified character and attributes */
 
   DoFill = FALSE;
 
-  CsrpGetUnion(&FillRegion, SrcRegion, DstRegion);
+  ConioGetUnion(&FillRegion, &SrcRegion, &DstRegion);
 
-  if (CsrpSubtractRect(&FillRegion, FillRegion, DstRegion))
+  if (ConioSubtractRect(&FillRegion, &FillRegion, &DstRegion))
     {
       /* FIXME: The subtracted rectangle is off by one line */
-      FillRegion.Top += 1;
+      FillRegion.top += 1;
 
-      CsrpFillRegion(Buff, FillRegion, Fill);
+      ConioFillRegion(Buff, &FillRegion, Fill);
       DoFill = TRUE;
     }
 
-  if (Buff == ActiveConsole->ActiveBuffer)
+  if (NULL != Console && Buff == Console->ActiveBuffer)
     {
       /* Draw destination region */
-      CsrpDrawRegion(ActiveConsole, DstRegion);
+      ConioDrawRegion(Console, &DstRegion);
 
       if (DoFill)
         {
           /* Draw filled region */
-          CsrpDrawRegion(ActiveConsole, FillRegion);
+          ConioDrawRegion(Console, &FillRegion);
         }
     }
 
-  UNLOCK;
-  return(Reply->Status = STATUS_SUCCESS);
-}
+  ConioUnlockScreenBuffer(Buff);
+  if (NULL != Console)
+    {
+      ConioUnlockConsole(Console);
+    }
 
+  return Reply->Status = STATUS_SUCCESS;
+}
 
 CSR_API(CsrReadConsoleOutputChar)
 {
   NTSTATUS Status;
-  PCSRSS_SCREEN_BUFFER ScreenBuffer;
+  PCSRSS_SCREEN_BUFFER Buff;
   DWORD Xpos, Ypos;
   BYTE* ReadBuffer;
   DWORD i;
@@ -2651,61 +2427,51 @@ CSR_API(CsrReadConsoleOutputChar)
   Reply->Header.DataSize = Reply->Header.MessageSize - sizeof(LPC_MESSAGE);
   ReadBuffer = Reply->Data.ReadConsoleOutputCharReply.String;
 
-  LOCK;
-
-  Status = Win32CsrGetObject(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, (Object_t**)&ScreenBuffer);
-  if (!NT_SUCCESS(Status))
-    {
-      Reply->Status = Status;
-      UNLOCK;
-      return(Reply->Status);
-    }
-
-  if (ScreenBuffer->Header.Type != CONIO_SCREEN_BUFFER_MAGIC)
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, Buff);
+  if (! NT_SUCCESS(Status))
     {
-      Reply->Status = STATUS_INVALID_HANDLE;
-      UNLOCK;
-      return(Reply->Status);
+      return Reply->Status = Status;
     }
 
-  Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X + ScreenBuffer->ShowX;
-  Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
+  Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X + Buff->ShowX;
+  Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->ShowY) % Buff->MaxY;
 
   for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i)
     {
-      *ReadBuffer = ScreenBuffer->Buffer[(Xpos * 2) + (Ypos * 2 * ScreenBuffer->MaxX)];
+      *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)];
 
       ReadBuffer++;
       Xpos++;
 
-      if (Xpos == ScreenBuffer->MaxX)
+      if (Xpos == Buff->MaxX)
        {
          Xpos = 0;
          Ypos++;
 
-         if (Ypos == ScreenBuffer->MaxY)
-           Ypos = 0;
+         if (Ypos == Buff->MaxY)
+            {
+              Ypos = 0;
+            }
        }
     }
 
   *ReadBuffer = 0;
-
   Reply->Status = STATUS_SUCCESS;
-  Reply->Data.ReadConsoleOutputCharReply.EndCoord.X = Xpos - ScreenBuffer->ShowX;
-  Reply->Data.ReadConsoleOutputCharReply.EndCoord.Y = (Ypos - ScreenBuffer->ShowY + ScreenBuffer->MaxY) % ScreenBuffer->MaxY;
+  Reply->Data.ReadConsoleOutputCharReply.EndCoord.X = Xpos - Buff->ShowX;
+  Reply->Data.ReadConsoleOutputCharReply.EndCoord.Y = (Ypos - Buff->ShowY + Buff->MaxY) % Buff->MaxY;
   Reply->Header.MessageSize += Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead;
   Reply->Header.DataSize += Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead;
 
-  UNLOCK;
+  ConioUnlockScreenBuffer(Buff);
 
-  return(Reply->Status);
+  return Reply->Status;
 }
 
 
 CSR_API(CsrReadConsoleOutputAttrib)
 {
   NTSTATUS Status;
-  PCSRSS_SCREEN_BUFFER ScreenBuffer;
+  PCSRSS_SCREEN_BUFFER Buff;
   DWORD Xpos, Ypos;
   CHAR* ReadBuffer;
   DWORD i;
@@ -2716,54 +2482,45 @@ CSR_API(CsrReadConsoleOutputAttrib)
   Reply->Header.DataSize = Reply->Header.MessageSize - sizeof(LPC_MESSAGE);
   ReadBuffer = Reply->Data.ReadConsoleOutputAttribReply.String;
 
-  LOCK;
-
-  Status = Win32CsrGetObject(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, (Object_t**)&ScreenBuffer);
-  if (!NT_SUCCESS(Status))
-    {
-      Reply->Status = Status;
-      UNLOCK;
-      return(Reply->Status);
-    }
-
-  if (ScreenBuffer->Header.Type != CONIO_SCREEN_BUFFER_MAGIC)
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff);
+  if (! NT_SUCCESS(Status))
     {
-      Reply->Status = STATUS_INVALID_HANDLE;
-      UNLOCK;
-      return(Reply->Status);
+      return Reply->Status = Status;
     }
 
-  Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X + ScreenBuffer->ShowX;
-  Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
+  Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X + Buff->ShowX;
+  Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + Buff->ShowY) % Buff->MaxY;
 
   for (i = 0; i < Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; ++i)
     {
-      *ReadBuffer = ScreenBuffer->Buffer[(Xpos * 2) + (Ypos * 2 * ScreenBuffer->MaxX) + 1];
+      *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX) + 1];
 
       ReadBuffer++;
       Xpos++;
 
-      if (Xpos == ScreenBuffer->MaxX)
-       {
-         Xpos = 0;
-         Ypos++;
+      if (Xpos == Buff->MaxX)
+        {
+          Xpos = 0;
+          Ypos++;
 
-         if (Ypos == ScreenBuffer->MaxY)
-           Ypos = 0;
-       }
+          if (Ypos == Buff->MaxY)
+            {
+              Ypos = 0;
+            }
+        }
     }
 
   *ReadBuffer = 0;
 
   Reply->Status = STATUS_SUCCESS;
-  Reply->Data.ReadConsoleOutputAttribReply.EndCoord.X = Xpos - ScreenBuffer->ShowX;
-  Reply->Data.ReadConsoleOutputAttribReply.EndCoord.Y = (Ypos - ScreenBuffer->ShowY + ScreenBuffer->MaxY) % ScreenBuffer->MaxY;
+  Reply->Data.ReadConsoleOutputAttribReply.EndCoord.X = Xpos - Buff->ShowX;
+  Reply->Data.ReadConsoleOutputAttribReply.EndCoord.Y = (Ypos - Buff->ShowY + Buff->MaxY) % Buff->MaxY;
   Reply->Header.MessageSize += Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead;
   Reply->Header.DataSize += Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead;
 
-  UNLOCK;
+  ConioUnlockScreenBuffer(Buff);
 
-  return(Reply->Status);
+  return Reply->Status;
 }
 
 
@@ -2779,37 +2536,27 @@ CSR_API(CsrGetNumberOfConsoleInputEvents)
   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
   Reply->Header.DataSize = Reply->Header.MessageSize - sizeof(LPC_MESSAGE);
 
-  LOCK;
-
-  Status = Win32CsrGetObject(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, (Object_t**)&Console);
-  if (!NT_SUCCESS(Status))
-    {
-      Reply->Status = Status;
-      UNLOCK;
-      return(Reply->Status);
-    }
-
-  if (Console->Header.Type != CONIO_CONSOLE_MAGIC)
+  Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console);
+  if (! NT_SUCCESS(Status))
     {
-      Reply->Status = STATUS_INVALID_HANDLE;
-      UNLOCK;
-      return(Reply->Status);
+      return Reply->Status = Status;
     }
   
   CurrentItem = &Console->InputEvents;
   NumEvents = 0;
   
-  // If there are any events ...
-  if(CurrentItem->Flink != CurrentItem)
-  {
-    do
+  /* If there are any events ... */
+  if (CurrentItem->Flink != CurrentItem)
     {
-      CurrentItem = CurrentItem->Flink;
-      ++NumEvents;
-    }while(CurrentItem != &Console->InputEvents);
-  }
-  
-  UNLOCK;
+      do
+        {
+          CurrentItem = CurrentItem->Flink;
+          ++NumEvents;
+        }
+      while (CurrentItem != &Console->InputEvents);
+    }
+
+  ConioUnlockConsole(Console);
   
   Reply->Status = STATUS_SUCCESS;
   Reply->Data.GetNumInputEventsReply.NumInputEvents = NumEvents;
@@ -2820,233 +2567,210 @@ CSR_API(CsrGetNumberOfConsoleInputEvents)
 
 CSR_API(CsrPeekConsoleInput)
 {
-   NTSTATUS Status;
-   PCSRSS_CONSOLE Console;
-   DWORD Size;
-   DWORD Length;
-   PLIST_ENTRY CurrentItem;
-   PINPUT_RECORD InputRecord;
-   ConsoleInput* Item;
-   UINT NumItems;
+  NTSTATUS Status;
+  PCSRSS_CONSOLE Console;
+  DWORD Size;
+  DWORD Length;
+  PLIST_ENTRY CurrentItem;
+  PINPUT_RECORD InputRecord;
+  ConsoleInput* Item;
+  UINT NumItems;
    
-   DPRINT("CsrPeekConsoleInput\n");
+  DPRINT("CsrPeekConsoleInput\n");
 
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-   
-   LOCK;
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
    
-   Status = Win32CsrGetObject(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, (Object_t**)&Console);
-   if(!NT_SUCCESS(Status))
-   {
-      Reply->Status = Status;
-      UNLOCK;
-      return Reply->Status;
-   }
-
-   if(Console->Header.Type != CONIO_CONSOLE_MAGIC)
-   {
-      Reply->Status = STATUS_INVALID_HANDLE;
-      UNLOCK;
-      return Reply->Status;
-   }
+  Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console);
+  if(! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
    
-   InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord;
-   Length = Request->Data.PeekConsoleInputRequest.Length;
-   Size = Length * sizeof(INPUT_RECORD);
+  InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord;
+  Length = Request->Data.PeekConsoleInputRequest.Length;
+  Size = Length * sizeof(INPUT_RECORD);
    
-    if(((PVOID)InputRecord < ProcessData->CsrSectionViewBase)
-         || (((PVOID)InputRecord + Size) > (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
-   {
-      UNLOCK;
+  if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase)
+      || (((PVOID)InputRecord + Size) > (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
+    {
+      ConioUnlockConsole(Console);
       Reply->Status = STATUS_ACCESS_VIOLATION;
       return Reply->Status ;
-   }
+    }
    
-   NumItems = 0;
+  NumItems = 0;
    
-   if(!IsListEmpty(&Console->InputEvents))
-   {
+  if (! IsListEmpty(&Console->InputEvents))
+    {
       CurrentItem = &Console->InputEvents;
    
-      while(NumItems < Length)
-      {
-         ++NumItems;
-         Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry);
-         *InputRecord++ = Item->InputEvent;
+      while (NumItems < Length)
+        {
+          ++NumItems;
+          Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry);
+          *InputRecord++ = Item->InputEvent;
          
-         if(CurrentItem->Flink == &Console->InputEvents)
-            break;
-         else
-            CurrentItem = CurrentItem->Flink;
-      }
-   }
+          if (CurrentItem->Flink == &Console->InputEvents)
+            {
+              break;
+            }
+          else
+            {
+              CurrentItem = CurrentItem->Flink;
+            }
+        }
+    }
 
-   UNLOCK;
-   
-   Reply->Status = STATUS_SUCCESS;
-   Reply->Data.PeekConsoleInputReply.Length = NumItems;
-   return Reply->Status;
+  ConioUnlockConsole(Console);
+
+  Reply->Status = STATUS_SUCCESS;
+  Reply->Data.PeekConsoleInputReply.Length = NumItems;
+
+  return Reply->Status;
 }
 
 
 CSR_API(CsrReadConsoleOutput)
 {
-   PCHAR_INFO CharInfo;
-   PCHAR_INFO CurCharInfo;
-   PCSRSS_SCREEN_BUFFER ScreenBuffer;
-   DWORD Size;
-   DWORD Length;
-   DWORD SizeX, SizeY;
-   NTSTATUS Status;
-   COORD BufferSize;
-   COORD BufferCoord;
-   SMALL_RECT ReadRegion;
-   SMALL_RECT ScreenRect;
-   DWORD i, Y, X, Offset;
+  PCHAR_INFO CharInfo;
+  PCHAR_INFO CurCharInfo;
+  PCSRSS_SCREEN_BUFFER Buff;
+  DWORD Size;
+  DWORD Length;
+  DWORD SizeX, SizeY;
+  NTSTATUS Status;
+  COORD BufferSize;
+  COORD BufferCoord;
+  RECT ReadRegion;
+  RECT ScreenRect;
+  DWORD i, Y, X, Offset;
       
-   DPRINT("CsrReadConsoleOutput\n");
+  DPRINT("CsrReadConsoleOutput\n");
 
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-  
-   LOCK;
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
   
-   Status = Win32CsrGetObject(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, (Object_t**)&ScreenBuffer);
-   if(!NT_SUCCESS(Status))
-   {
-      Reply->Status = Status;
-      UNLOCK;
-      return Reply->Status;
-   }
-
-   if(ScreenBuffer->Header.Type != CONIO_SCREEN_BUFFER_MAGIC)
-   {
-      Reply->Status = STATUS_INVALID_HANDLE;
-      UNLOCK;
-      return Reply->Status;
-   }
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
    
-   CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo;
-   ReadRegion = Request->Data.ReadConsoleOutputRequest.ReadRegion;
-   BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize;
-   BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord;
-   Length = BufferSize.X * BufferSize.Y;
-   Size = Length * sizeof(CHAR_INFO);
+  CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo;
+  ReadRegion.left = Request->Data.ReadConsoleOutputRequest.ReadRegion.Left;
+  ReadRegion.top = Request->Data.ReadConsoleOutputRequest.ReadRegion.Top;
+  ReadRegion.right = Request->Data.ReadConsoleOutputRequest.ReadRegion.Right;
+  ReadRegion.bottom = Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom;
+  BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize;
+  BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord;
+  Length = BufferSize.X * BufferSize.Y;
+  Size = Length * sizeof(CHAR_INFO);
    
-   if(((PVOID)CharInfo < ProcessData->CsrSectionViewBase)
-         || (((PVOID)CharInfo + Size) > (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
-   {
-      UNLOCK;
+  if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase)
+      || (((PVOID)CharInfo + Size) > (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
+    {
+      ConioUnlockScreenBuffer(Buff);
       Reply->Status = STATUS_ACCESS_VIOLATION;
       return Reply->Status ;
-   }
+    }
    
-   SizeY = RtlRosMin(BufferSize.Y - BufferCoord.Y, CsrpRectHeight(ReadRegion));
-   SizeX = RtlRosMin(BufferSize.X - BufferCoord.X, CsrpRectWidth(ReadRegion));
-   ReadRegion.Bottom = ReadRegion.Top + SizeY;
-   ReadRegion.Right = ReadRegion.Left + SizeX;
-
-   CsrpInitRect(ScreenRect, 0, 0, ScreenBuffer->MaxY, ScreenBuffer->MaxX);
-   if (!CsrpGetIntersection(&ReadRegion, ScreenRect, ReadRegion))
-   {
-      UNLOCK;
+  SizeY = RtlRosMin(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion));
+  SizeX = RtlRosMin(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);
       Reply->Status = STATUS_SUCCESS;
       return Reply->Status;
-   }
+    }
 
-   for(i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y)
-   {
-     CurCharInfo = CharInfo + (i * BufferSize.X);
+  for (i = 0, Y = ReadRegion.top; Y < ReadRegion.bottom; ++i, ++Y)
+    {
+      CurCharInfo = CharInfo + (i * BufferSize.X);
      
-     Offset = (((Y + ScreenBuffer->ShowY) % ScreenBuffer->MaxY) * ScreenBuffer->MaxX + ReadRegion.Left) * 2;
-     for(X = ReadRegion.Left; X < ReadRegion.Right; ++X)
-     {
-        CurCharInfo->Char.AsciiChar = GET_CELL_BUFFER(ScreenBuffer, Offset);
-        CurCharInfo->Attributes = GET_CELL_BUFFER(ScreenBuffer, Offset);
-        ++CurCharInfo;
-     }
-  }
+      Offset = (((Y + Buff->ShowY) % Buff->MaxY) * Buff->MaxX + ReadRegion.left) * 2;
+      for (X = ReadRegion.left; X < ReadRegion.right; ++X)
+        {
+          CurCharInfo->Char.AsciiChar = GET_CELL_BUFFER(Buff, Offset);
+          CurCharInfo->Attributes = GET_CELL_BUFFER(Buff, Offset);
+          ++CurCharInfo;
+        }
+    }
+
+  ConioUnlockScreenBuffer(Buff);
   
-   UNLOCK;
-   
-   Reply->Status = STATUS_SUCCESS;
-   Reply->Data.ReadConsoleOutputReply.ReadRegion.Right = ReadRegion.Left + SizeX - 1;
-   Reply->Data.ReadConsoleOutputReply.ReadRegion.Bottom = ReadRegion.Top + SizeY - 1;
-   Reply->Data.ReadConsoleOutputReply.ReadRegion.Left = ReadRegion.Left;
-   Reply->Data.ReadConsoleOutputReply.ReadRegion.Top = ReadRegion.Top;
+  Reply->Status = STATUS_SUCCESS;
+  Reply->Data.ReadConsoleOutputReply.ReadRegion.Right = ReadRegion.left + SizeX - 1;
+  Reply->Data.ReadConsoleOutputReply.ReadRegion.Bottom = ReadRegion.top + SizeY - 1;
+  Reply->Data.ReadConsoleOutputReply.ReadRegion.Left = ReadRegion.left;
+  Reply->Data.ReadConsoleOutputReply.ReadRegion.Top = ReadRegion.top;
    
-   return Reply->Status;
+  return Reply->Status;
 }
 
 
 CSR_API(CsrWriteConsoleInput)
 {
-   PINPUT_RECORD InputRecord;
-   PCSRSS_CONSOLE Console;
-   NTSTATUS Status;
-   DWORD Length;
-   DWORD Size;
-   DWORD i;
-   ConsoleInput* Record;
+  PINPUT_RECORD InputRecord;
+  PCSRSS_CONSOLE Console;
+  NTSTATUS Status;
+  DWORD Length;
+  DWORD Size;
+  DWORD i;
+  ConsoleInput* Record;
    
-   DPRINT("CsrWriteConsoleInput\n");
+  DPRINT("CsrWriteConsoleInput\n");
 
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-   
-   LOCK;
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
    
-   Status = Win32CsrGetObject(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, (Object_t**)&Console);
-   if(!NT_SUCCESS(Status))
-   {
-      Reply->Status = Status;
-      UNLOCK;
-      return Reply->Status;
-   }
-
-   if(Console->Header.Type != CONIO_CONSOLE_MAGIC)
-   {
-      Reply->Status = STATUS_INVALID_HANDLE;
-      UNLOCK;
-      return Reply->Status;
-   }
+  Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
    
-   InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord;
-   Length = Request->Data.WriteConsoleInputRequest.Length;
-   Size = Length * sizeof(INPUT_RECORD);
+  InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord;
+  Length = Request->Data.WriteConsoleInputRequest.Length;
+  Size = Length * sizeof(INPUT_RECORD);
    
-    if(((PVOID)InputRecord < ProcessData->CsrSectionViewBase)
-         || (((PVOID)InputRecord + Size) > (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
-   {
-      UNLOCK;
+  if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase)
+      || (((PVOID)InputRecord + Size) > (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
+    {
+      ConioUnlockConsole(Console);
       Reply->Status = STATUS_ACCESS_VIOLATION;
       return Reply->Status ;
-   }
+    }
    
-   for(i = 0; i < Length; ++i)
-   {
-      Record = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ConsoleInput));
-      if(Record == NULL)
-      {
-         UNLOCK;
-         Reply->Status = STATUS_INSUFFICIENT_RESOURCES;
-         return Reply->Status;
-      }
+  for (i = 0; i < Length; i++)
+    {
+      Record = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput));
+      if (NULL == Record)
+        {
+          ConioUnlockConsole(Console);
+          Reply->Status = STATUS_INSUFFICIENT_RESOURCES;
+          return Reply->Status;
+        }
 
       Record->Echoed = FALSE;
       Record->Fake = FALSE;
       Record->InputEvent = *InputRecord++;
-      if( Record->InputEvent.EventType == KEY_EVENT ) {
-         CsrpProcessChar( Console, Record );
-      }
-   }
-      
-   UNLOCK;
+      if (KEY_EVENT == Record->InputEvent.EventType)
+        {
+          ConioProcessChar(Console, Record);
+        }
+    }
+
+  ConioUnlockConsole(Console);
    
-   Reply->Status = STATUS_SUCCESS;
-   Reply->Data.WriteConsoleInputReply.Length = i;
-   return Reply->Status;
+  Reply->Status = STATUS_SUCCESS;
+  Reply->Data.WriteConsoleInputReply.Length = i;
+
+  return Reply->Status;
 }
 
 /**********************************************************************
@@ -3063,115 +2787,89 @@ CSR_API(CsrWriteConsoleInput)
  *             ConsoleHwState has the correct size to be compatible
  *             with NT's, but values are not.
  */
-static NTSTATUS FASTCALL SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
+STATIC NTSTATUS FASTCALL
+SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
 {
-   DbgPrint( "Console Hardware State: %d\n", ConsoleHwState );
+  DPRINT1("Console Hardware State: %d\n", ConsoleHwState);
 
-   if ( (CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState)
+  if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState)
       ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState))
-   {
+    {
       if (Console->HardwareState != ConsoleHwState)
-      {
-        /* TODO: implement switching from full screen to windowed mode */
-        /* TODO: or back; now simply store the hardware state */
-         Console->HardwareState = ConsoleHwState;
-      }
+        {
+          /* TODO: implement switching from full screen to windowed mode */
+          /* TODO: or back; now simply store the hardware state */
+          Console->HardwareState = ConsoleHwState;
+        }
+
       return STATUS_SUCCESS;   
-   }
-   return STATUS_INVALID_PARAMETER_3; // Client: (handle, set_get, [mode])
+    }
+
+  return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */
 }
 
 CSR_API(CsrHardwareStateProperty)
 {
-   PCSRSS_CONSOLE Console;
-   NTSTATUS       Status;
+  PCSRSS_CONSOLE Console;
+  NTSTATUS Status;
  
-   DPRINT("CsrHardwareStateProperty\n");
+  DPRINT("CsrHardwareStateProperty\n");
 
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-
-   LOCK;
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
    
-   Status = Win32CsrGetObject (
-                  ProcessData,
-                  Request->Data.ConsoleHardwareStateRequest.ConsoleHandle,
-                  (Object_t**) & Console
-                  );
-   if (!NT_SUCCESS(Status))
-   {
-      DbgPrint( "Failed to get console handle in SetConsoleHardwareState\n" );
-      Reply->Status = Status;
-   }
-   else
-   {
-      if(Console->Header.Type != CONIO_CONSOLE_MAGIC)
-      {
-       DbgPrint( "Bad magic on Console: %08x\n", Console->Header.Type );
-        Reply->Status = STATUS_INVALID_HANDLE;
-      }
-      else
-      {
-         switch (Request->Data.ConsoleHardwareStateRequest.SetGet)
-         {
-         case CONSOLE_HARDWARE_STATE_GET:
-            Reply->Data.ConsoleHardwareStateReply.State = Console->HardwareState;
-            break;
+  Status = ConioLockConsole(ProcessData,
+                            Request->Data.ConsoleHardwareStateRequest.ConsoleHandle,
+                            &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
+      return Reply->Status = Status;
+    }
+
+  switch (Request->Data.ConsoleHardwareStateRequest.SetGet)
+    {
+      case CONSOLE_HARDWARE_STATE_GET:
+        Reply->Data.ConsoleHardwareStateReply.State = Console->HardwareState;
+        break;
       
-         case CONSOLE_HARDWARE_STATE_SET:
-           DbgPrint( "Setting console hardware state.\n" );
-            Reply->Status = SetConsoleHardwareState (Console, Request->Data.ConsoleHardwareStateRequest.State);
-            break;
+      case CONSOLE_HARDWARE_STATE_SET:
+        DPRINT("Setting console hardware state.\n");
+        Reply->Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State);
+        break;
 
-         default:
-            Reply->Status = STATUS_INVALID_PARAMETER_2; // Client: (handle, [set_get], mode)
-            break;
-         }
-      }
-   }
+      default:
+        Reply->Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */
+        break;
+    }
 
-   UNLOCK;
+  ConioUnlockConsole(Console);
 
-   return Reply->Status;
+  return Reply->Status;
 }
 
 CSR_API(CsrGetConsoleWindow)
 {
-   PCSRSS_CONSOLE Console;
-   NTSTATUS       Status;
+  PCSRSS_CONSOLE Console;
+  NTSTATUS Status;
 
-   DPRINT("CsrGetConsoleWindow\n");
+  DPRINT("CsrGetConsoleWindow\n");
  
-   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-
-   LOCK;
+  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
    
-   Status = Win32CsrGetObject (
-                  ProcessData,
-                  Request->Data.ConsoleWindowRequest.ConsoleHandle,
-                  (Object_t**) & Console
-                  );
-   if (!NT_SUCCESS(Status))
-   {
-      Reply->Status = Status;
-   }
-   else
-   {
-      if(Console->Header.Type != CONIO_CONSOLE_MAGIC)
-      {
-         Reply->Status = STATUS_INVALID_HANDLE;
-      }
-      else
-      {
-        // Is this GDI handle valid in the client's context?
-        Reply->Data.ConsoleWindowReply.WindowHandle = Console->hWindow;
-      }
-   }
+  Status = ConioLockConsole(ProcessData,
+                            Request->Data.ConsoleWindowRequest.ConsoleHandle,
+                            &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
 
-   UNLOCK;
+  Reply->Data.ConsoleWindowReply.WindowHandle = Console->hWindow;
+  ConioUnlockConsole(Console);
 
-   return Reply->Status;
+  return Reply->Status = STATUS_SUCCESS;
 }
 
 /* EOF */
index b94d50f..76a5eef 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: desktopbg.c,v 1.4 2003/12/27 15:09:51 navaraf Exp $
+/* $Id: desktopbg.c,v 1.5 2004/01/11 17:31:16 gvg Exp $
  *
  * reactos/subsys/csrss/win32csr/desktopbg.c
  *
@@ -32,6 +32,7 @@ typedef struct tagDTBG_THREAD_DATA
 } DTBG_THREAD_DATA, *PDTBG_THREAD_DATA;
 
 static BOOL Initialized = FALSE;
+static HWND VisibleDesktopWindow = NULL;
 
 static LRESULT CALLBACK
 DtbgWindowProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
@@ -68,6 +69,7 @@ DtbgWindowProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
                                 (int)(short) HIWORD(lParam),
                                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOREDRAW);
         UpdateWindow(Wnd);
+        VisibleDesktopWindow = Wnd;
         break;
       case PM_HIDE_DESKTOP:
         Result = ! SetWindowPos(Wnd,
@@ -75,6 +77,7 @@ DtbgWindowProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
                                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE |
                                 SWP_HIDEWINDOW);
         UpdateWindow(Wnd);
+        VisibleDesktopWindow = NULL;
         break;
       default:
         Result = 0;
@@ -95,12 +98,12 @@ DtbgInit()
   WindowStation = OpenWindowStationW(L"WinSta0", FALSE, GENERIC_ALL);
   if (NULL == WindowStation)
     {
-      DPRINT1("Win32Csr: failed to open window station\n");
+      DPRINT1("Failed to open window station\n");
       return FALSE;
     }
   if (! SetProcessWindowStation(WindowStation))
     {
-      DPRINT1("Win32Csr: failed to set process window station\n");
+      DPRINT1("Failed to set process window station\n");
       return FALSE;
     }
 
@@ -121,10 +124,11 @@ DtbgInit()
   ClassAtom = RegisterClassExW(&Class);
   if ((ATOM) 0 == ClassAtom)
     {
-      DPRINT1("Win32Csr: Unable to register desktop background class (error %d)\n",
+      DPRINT1("Unable to register desktop background class (error %d)\n",
               GetLastError());
       return FALSE;
     }
+  VisibleDesktopWindow = NULL;
 
   return TRUE;
 }
@@ -138,7 +142,7 @@ DtbgDesktopThread(PVOID Data)
 
   if (! SetThreadDesktop(ThreadData->Desktop))
     {
-      DPRINT1("Win32Csr: failed to set thread desktop\n");
+      DPRINT1("Failed to set thread desktop\n");
       ThreadData->Status = STATUS_UNSUCCESSFUL;
       SetEvent(ThreadData->Event);
       return 1;
@@ -156,7 +160,7 @@ DtbgDesktopThread(PVOID Data)
                                 NULL);
   if (NULL == BackgroundWnd)
     {
-      DPRINT1("Win32Csr: failed to create desktop background window\n");
+      DPRINT1("Failed to create desktop background window\n");
       ThreadData->Status = STATUS_UNSUCCESSFUL;
       SetEvent(ThreadData->Event);
       return 1;
@@ -198,7 +202,7 @@ CSR_API(CsrCreateDesktop)
                          0, FALSE, GENERIC_ALL);
   if (NULL == Desktop)
     {
-      DPRINT1("Win32Csr: failed to open desktop %S\n",
+      DPRINT1("Failed to open desktop %S\n",
               Request->Data.CreateDesktopRequest.DesktopName);
       return Reply->Status = STATUS_UNSUCCESSFUL;
     }
@@ -207,7 +211,7 @@ CSR_API(CsrCreateDesktop)
   ThreadData.Event = CreateEventW(NULL, FALSE, FALSE, NULL);
   if (NULL == ThreadData.Event)
     {
-      DPRINT1("Win32Csr: Failed to create event (error %d)\n", GetLastError());
+      DPRINT1("Failed to create event (error %d)\n", GetLastError());
       return Reply->Status = STATUS_UNSUCCESSFUL;
     }
   ThreadHandle = CreateThread(NULL,
@@ -219,7 +223,7 @@ CSR_API(CsrCreateDesktop)
   if (NULL == ThreadHandle)
     {
       CloseHandle(ThreadData.Event);
-      DPRINT1("Win32Csr: Failed to create desktop window thread.\n");
+      DPRINT1("Failed to create desktop window thread.\n");
       return Reply->Status = STATUS_UNSUCCESSFUL;
     }
   CloseHandle(ThreadHandle);
@@ -263,4 +267,15 @@ CSR_API(CsrHideDesktop)
   return Reply->Status;
 }
 
+BOOL FASTCALL
+DtbgIsDesktopVisible(VOID)
+{
+  if (NULL != VisibleDesktopWindow && ! IsWindowVisible(VisibleDesktopWindow))
+    {
+      VisibleDesktopWindow = NULL;
+    }
+
+  return NULL != VisibleDesktopWindow;
+}
+
 /* EOF */
index f1ecac9..ad55275 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: dllmain.c,v 1.2 2003/12/07 23:02:57 gvg Exp $
+/* $Id: dllmain.c,v 1.3 2004/01/11 17:31:16 gvg Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -82,9 +82,11 @@ DllMain(HANDLE hDll,
 
 NTSTATUS FASTCALL
 Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData,
-                    PHANDLE Handle,
-                    Object_t *Object)
+                     PHANDLE Handle,
+                     Object_t *Object)
 {
+  InitializeCriticalSection(&(Object->Lock));
+
   return (CsrExports.CsrInsertObjectProc)(ProcessData, Handle, Object);
 }
 
@@ -96,6 +98,36 @@ Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData,
   return (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object);
 }
 
+NTSTATUS FASTCALL
+Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData,
+                   HANDLE Handle,
+                   Object_t **Object,
+                   LONG Type)
+{
+  NTSTATUS Status;
+
+  Status = (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object);
+  if (! NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+
+  if ((*Object)->Type != Type)
+    {
+      return STATUS_INVALID_HANDLE;
+    }
+
+  EnterCriticalSection(&((*Object)->Lock));
+
+  return STATUS_SUCCESS;
+}
+
+VOID FASTCALL
+Win32CsrUnlockObject(Object_t *Object)
+{
+  LeaveCriticalSection(&(Object->Lock));
+}
+
 NTSTATUS FASTCALL
 Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
                      HANDLE Object)
index c1eba1c..1192423 100644 (file)
@@ -1,9 +1,9 @@
-/* $Id: guiconsole.c,v 1.6 2003/12/31 20:16:39 gvg Exp $
+/* $Id: guiconsole.c,v 1.7 2004/01/11 17:31:16 gvg Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
- * FILE:            subsys/csrss/win32csr/dllmain.c
- * PURPOSE:         Initialization 
+ * FILE:            subsys/csrss/win32csr/guiconsole.c
+ * PURPOSE:         Implementation of gui-mode consoles
  */
 
 /* INCLUDES ******************************************************************/
@@ -13,6 +13,9 @@
 #include "guiconsole.h"
 #include "win32csr.h"
 
+#define NDEBUG
+#include <debug.h>
+
 /* Not defined in any header file */
 extern VOID STDCALL PrivateCsrssManualGuiCheck(LONG Check);
 
@@ -38,6 +41,7 @@ typedef struct GUI_CONSOLE_DATA_TAG
 
 #define CURSOR_BLINK_TIME 500
 
+static BOOL Initialized = FALSE;
 static HWND NotifyWnd;
 
 /* FUNCTIONS *****************************************************************/
@@ -46,7 +50,7 @@ static VOID FASTCALL
 GuiConsoleGetDataPointers(HWND hWnd, PCSRSS_CONSOLE *Console, PGUI_CONSOLE_DATA *GuiData)
 {
   *Console = (PCSRSS_CONSOLE) GetWindowLongW(hWnd, GWL_USERDATA);
-  *GuiData = (NULL == *Console ? NULL : (*Console)->GuiConsoleData);
+  *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData);
 }
 
 static BOOL FASTCALL
@@ -64,7 +68,7 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
                       (Console->Size.X + 1) * sizeof(WCHAR));
   if (NULL == GuiData)
     {
-      DbgPrint("GuiConsoleNcCreate: HeapAlloc failed\n");
+      DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n");
       return FALSE;
     }
   GuiData->LineBuffer = (PWCHAR)(GuiData + 1);
@@ -76,28 +80,28 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
                               L"Bitstream Vera Sans Mono");
   if (NULL == GuiData->Font)
     {
-      DbgPrint("GuiConsoleNcCreate: CreateFont failed\n");
+      DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
       HeapFree(Win32CsrApiHeap, 0, GuiData);
       return FALSE;
     }
   Dc = GetDC(hWnd);
   if (NULL == Dc)
     {
-      DbgPrint("GuiConsoleNcCreate: GetDC failed\n");
+      DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
       HeapFree(Win32CsrApiHeap, 0, GuiData);
       return FALSE;
     }
   OldFont = SelectObject(Dc, GuiData->Font);
   if (NULL == OldFont)
     {
-      DbgPrint("GuiConsoleNcCreate: SelectObject failed\n");
+      DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
       ReleaseDC(hWnd, Dc);
       HeapFree(Win32CsrApiHeap, 0, GuiData);
       return FALSE;
     }
   if (! GetTextMetricsW(Dc, &Metrics))
     {
-      DbgPrint("GuiConsoleNcCreate: GetTextMetrics failed\n");
+      DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n");
       SelectObject(Dc, OldFont);
       ReleaseDC(hWnd, Dc);
       HeapFree(Win32CsrApiHeap, 0, GuiData);
@@ -110,7 +114,7 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
   GuiData->CursorBlinkOn = TRUE;
   GuiData->ForceCursorOff = FALSE;
 
-  Console->GuiConsoleData = GuiData;
+  Console->PrivateData = GuiData;
   SetWindowLongW(hWnd, GWL_USERDATA, (LONG) Console);
 
   GetWindowRect(hWnd, &Rect);
@@ -178,13 +182,13 @@ GuiConsoleHandlePaint(HWND hWnd)
   if (NULL != Console && NULL != GuiData && NULL != Console->ActiveBuffer)
     {
       Buff = Console->ActiveBuffer;
-      EnterCriticalSection(&(Buff->Lock));
+      EnterCriticalSection(&(Buff->Header.Lock));
 
       Dc = BeginPaint(hWnd, &Ps);
       if (Ps.rcPaint.right <= Ps.rcPaint.left || Ps.rcPaint.bottom <= Ps.rcPaint.top)
         {
           EndPaint(hWnd, &Ps);
-          LeaveCriticalSection(&(Buff->Lock));
+          LeaveCriticalSection(&(Buff->Header.Lock));
           return;
         }
       OldFont = SelectObject(Dc, GuiData->Font);
@@ -220,7 +224,8 @@ GuiConsoleHandlePaint(HWND hWnd)
                   Attribute = *(From + 1);
                   if (Attribute != LastAttribute)
                     {
-                      GuiConsoleSetTextColors(Dc, LastAttribute);
+                      GuiConsoleSetTextColors(Dc, Attribute);
+                      LastAttribute = Attribute;
                     }
                 }  
               *((PBYTE) To) = *From;
@@ -258,7 +263,7 @@ GuiConsoleHandlePaint(HWND hWnd)
         }
       EndPaint(hWnd, &Ps);
 
-      LeaveCriticalSection(&(Buff->Lock));
+      LeaveCriticalSection(&(Buff->Header.Lock));
     }
   else
     {
@@ -280,7 +285,7 @@ GuiConsoleHandleKey(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
   Message.wParam = wParam;
   Message.lParam = lParam;
 
-  CsrProcessKey(&Message, Console);
+  ConioProcessKey(&Message, Console, FALSE);
 }
 
 static VOID FASTCALL
@@ -377,23 +382,149 @@ GuiConsoleHandleCopyRegion(HWND hWnd, PRECT Source, PRECT Dest)
     }
 }
 
+static VOID FASTCALL
+GuiIntDrawRegion(PGUI_CONSOLE_DATA GuiData, HWND Wnd, RECT *Region)
+{
+  RECT RegionRect;
+
+  RegionRect.left = Region->left * GuiData->CharWidth;
+  RegionRect.top = Region->top * GuiData->CharHeight;
+  RegionRect.right = (Region->right + 1) * GuiData->CharWidth;
+  RegionRect.bottom = (Region->bottom + 1) * GuiData->CharHeight;
+
+  InvalidateRect(Wnd, &RegionRect, FALSE);
+}
+
+static VOID STDCALL
+GuiDrawRegion(PCSRSS_CONSOLE Console, RECT *Region)
+{
+  PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
+
+  if (NULL == Console->hWindow || NULL == GuiData)
+    {
+      return;
+    }
+
+  GuiIntDrawRegion(GuiData, Console->hWindow, Region);
+}
+
+static VOID FASTCALL
+GuiInvalidateCell(PGUI_CONSOLE_DATA GuiData, HWND Wnd, UINT x, UINT y)
+{
+  RECT CellRect;
+
+  CellRect.left = x;
+  CellRect.top = y;
+  CellRect.right = x;
+  CellRect.bottom = y;
+
+  GuiIntDrawRegion(GuiData, Wnd, &CellRect);
+}
+
+static VOID STDCALL
+GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, UINT CursorStartX, UINT CursorStartY,
+               UINT ScrolledLines, CHAR *Buffer, UINT Length)
+{
+  PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
+  PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
+  LONG CursorEndX, CursorEndY;
+  RECT Source, Dest;
+
+  if (NULL == Console->hWindow || NULL == GuiData)
+    {
+      return;
+    }
+
+  if (0 != ScrolledLines)
+    {
+      Source.left = 0;
+      Source.top = ScrolledLines;
+      Source.right = Console->Size.X - 1;
+      Source.bottom = ScrolledLines + Region->top - 1;
+      Dest.left = 0;
+      Dest.top = 0;
+      Dest.right = Console->Size.X - 1;
+      Dest.bottom = Region->top - 1;
+
+      GuiConsoleCopyRegion(Console, &Source, &Dest);
+    }
+
+  GuiIntDrawRegion(GuiData, Console->hWindow, Region);
+
+  if (CursorStartX < Region->left || Region->right < CursorStartX
+      || CursorStartY < Region->top || Region->bottom < CursorStartY)
+    {
+      GuiInvalidateCell(GuiData, Console->hWindow, CursorStartX, CursorStartY);
+    }
+
+  ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
+                         &CursorEndX, &CursorEndY);
+  if ((CursorEndX < Region->left || Region->right < CursorEndX
+       || CursorEndY < Region->top || Region->bottom < CursorEndY)
+      && (CursorEndX != CursorStartX || CursorEndY != CursorStartY))
+    {
+      GuiInvalidateCell(GuiData, Console->hWindow, CursorEndX, CursorEndY);
+    }
+}
+
+static BOOL STDCALL
+GuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
+{
+  RECT UpdateRect;
+
+  if (Console->ActiveBuffer == Buff)
+    {
+      ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
+                             &UpdateRect.left, &UpdateRect.top);
+      UpdateRect.right = UpdateRect.left;
+      UpdateRect.bottom = UpdateRect.top;
+      ConioDrawRegion(Console, &UpdateRect);
+    }
+
+  return TRUE;
+}
+
+static BOOL STDCALL
+GuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY)
+{
+  RECT UpdateRect;
+
+  if (Console->ActiveBuffer == Buff)
+    {
+      /* Redraw char at old position (removes cursor) */
+      UpdateRect.left = OldCursorX;
+      UpdateRect.top = OldCursorY;
+      UpdateRect.right = OldCursorX;
+      UpdateRect.bottom = OldCursorY;
+      ConioDrawRegion(Console, &UpdateRect);
+      /* Redraw char at new position (shows cursor) */
+      ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
+                             &(UpdateRect.left), &(UpdateRect.top));
+      UpdateRect.right = UpdateRect.left;
+      UpdateRect.bottom = UpdateRect.top;
+      ConioDrawRegion(Console, &UpdateRect);
+    }
+
+  return TRUE;
+}
+
 static VOID FASTCALL
 GuiConsoleHandleTimer(HWND hWnd)
 {
   PCSRSS_CONSOLE Console;
   PGUI_CONSOLE_DATA GuiData;
-  SMALL_RECT CursorRect;
+  RECT CursorRect;
   ULONG CursorX, CursorY;
 
   GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
   GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn;
 
   GuiConsoleGetLogicalCursorPos(Console->ActiveBuffer, &CursorX, &CursorY);
-  CursorRect.Left = CursorX;
-  CursorRect.Top = CursorY;
-  CursorRect.Right = CursorX;
-  CursorRect.Bottom = CursorY;
-  GuiConsoleDrawRegion(Console, CursorRect);
+  CursorRect.left = CursorX;
+  CursorRect.top = CursorY;
+  CursorRect.right = CursorX;
+  CursorRect.bottom = CursorY;
+  GuiDrawRegion(Console, &CursorRect);
 }
 
 static VOID FASTCALL
@@ -410,7 +541,7 @@ GuiConsoleHandleNcDestroy(HWND hWnd)
 
   GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
   KillTimer(hWnd, 1);
-  Console->GuiConsoleData = NULL;
+  Console->PrivateData = NULL;
   HeapFree(Win32CsrApiHeap, 0, GuiData);
 }
 
@@ -546,8 +677,8 @@ GuiConsoleGuiThread(PVOID Data)
   return 1;
 }
 
-VOID FASTCALL
-GuiConsoleInitConsoleSupport(VOID)
+static BOOL FASTCALL
+GuiInit(VOID)
 {
   HDESK Desktop;
   NTSTATUS Status;
@@ -556,8 +687,8 @@ GuiConsoleInitConsoleSupport(VOID)
   Desktop = OpenDesktopW(L"Default", 0, FALSE, GENERIC_ALL);
   if (NULL == Desktop)
     {
-      DbgPrint("Win32Csr: failed to open desktop\n");
-      return;
+      DPRINT1("Failed to open desktop\n");
+      return FALSE;
     }
   Status = NtSetInformationProcess(NtCurrentProcess(),
                                    ProcessDesktop,
@@ -565,13 +696,13 @@ GuiConsoleInitConsoleSupport(VOID)
                                    sizeof(Desktop));
   if (!NT_SUCCESS(Status))
     {
-      DbgPrint("Win32Csr: cannot set default desktop.\n");
-      return;
+      DPRINT1("Cannot set default desktop.\n");
+      return FALSE;
     }
   if (! SetThreadDesktop(Desktop))
     {
-      DbgPrint("Win32Csr: failed to set thread desktop\n");
-      return;
+      DPRINT1("Failed to set thread desktop\n");
+      return FALSE;
     }
 
   wc.lpszClassName = L"Win32CsrCreateNotify";
@@ -586,7 +717,8 @@ GuiConsoleInitConsoleSupport(VOID)
   wc.cbWndExtra = 0;
   if (RegisterClassW(&wc) == 0)
     {
-      return;
+      DPRINT1("Failed to register notify wndproc\n");
+      return FALSE;
     }
 
   wc.lpszClassName = L"Win32CsrConsole";
@@ -601,16 +733,61 @@ GuiConsoleInitConsoleSupport(VOID)
   wc.cbWndExtra = 0;
   if (RegisterClassW(&wc) == 0)
     {
-      return;
+      DPRINT1("Failed to register console wndproc\n");
+      return FALSE;
     }
+
+  return TRUE;
 }
 
-BOOL STDCALL
-GuiConsoleInitConsole(PCSRSS_CONSOLE Console)
+static VOID STDCALL
+GuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer)
+{
+  Buffer->DefaultAttrib = 0x0f;
+}
+
+STATIC BOOL STDCALL
+GuiChangeTitle(PCSRSS_CONSOLE Console)
+{
+  SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Console->Title.Buffer);
+
+  return TRUE;
+}
+
+static VOID STDCALL
+GuiCleanupConsole(PCSRSS_CONSOLE Console)
+{
+  SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console);
+}
+
+static CSRSS_CONSOLE_VTBL GuiVtbl =
+{
+  GuiInitScreenBuffer,
+  GuiWriteStream,
+  GuiDrawRegion,
+  GuiSetCursorInfo,
+  GuiSetScreenInfo,
+  GuiChangeTitle,
+  GuiCleanupConsole
+};
+
+NTSTATUS FASTCALL
+GuiInitConsole(PCSRSS_CONSOLE Console)
 {
   HANDLE GraphicsStartupEvent;
   HANDLE ThreadHandle;
 
+  if (! Initialized)
+    {
+      Initialized = TRUE;
+      if (! GuiInit())
+        {
+          Initialized = FALSE;
+          return STATUS_UNSUCCESSFUL;
+        }
+    }
+
+  Console->Vtbl = &GuiVtbl;
   Console->Size.X = 80;
   Console->Size.Y = 25;
   if (NULL == NotifyWnd)
@@ -618,7 +795,7 @@ GuiConsoleInitConsole(PCSRSS_CONSOLE Console)
       GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
       if (NULL == GraphicsStartupEvent)
         {
-          return FALSE;
+          return STATUS_UNSUCCESSFUL;
         }
 
       ThreadHandle = CreateThread(NULL,
@@ -630,8 +807,8 @@ GuiConsoleInitConsole(PCSRSS_CONSOLE Console)
       if (NULL == ThreadHandle)
         {
           NtClose(GraphicsStartupEvent);
-          DbgPrint("Win32Csr: Failed to create graphics console thread. Expect problems\n");
-          return FALSE;
+          DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n");
+          return STATUS_UNSUCCESSFUL;
         }
       CloseHandle(ThreadHandle);
 
@@ -640,33 +817,14 @@ GuiConsoleInitConsole(PCSRSS_CONSOLE Console)
 
       if (NULL == NotifyWnd)
         {
-          DbgPrint("Win32Csr: Failed to create notification window.\n");
-          return FALSE;
+          DPRINT1("Win32Csr: Failed to create notification window.\n");
+          return STATUS_UNSUCCESSFUL;
         }
     }
 
   PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, 0, (LPARAM) Console);
 
-  return TRUE;
-}
-
-VOID STDCALL
-GuiConsoleDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT Region)
-{
-  PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->GuiConsoleData;
-  RECT RegionRect;
-
-  if (NULL == Console->hWindow || NULL == GuiData)
-    {
-      return;
-    }
-
-  RegionRect.left = Region.Left * GuiData->CharWidth;
-  RegionRect.top = Region.Top * GuiData->CharHeight;
-  RegionRect.right = (Region.Right + 1) * GuiData->CharWidth;
-  RegionRect.bottom = (Region.Bottom + 1) * GuiData->CharHeight;
-
-  InvalidateRect(Console->hWindow, &RegionRect, FALSE);
+  return STATUS_SUCCESS;
 }
 
 VOID STDCALL
@@ -674,21 +832,9 @@ GuiConsoleCopyRegion(PCSRSS_CONSOLE Console,
                      RECT *Source,
                      RECT *Dest)
 {
-  LeaveCriticalSection(&(Console->ActiveBuffer->Lock));
+  LeaveCriticalSection(&(Console->ActiveBuffer->Header.Lock));
   SendMessageW(Console->hWindow, PM_COPY_REGION, (WPARAM) Source, (LPARAM) Dest);
-  EnterCriticalSection(&(Console->ActiveBuffer->Lock));
-}
-
-VOID STDCALL
-GuiConsoleChangeTitle(PCSRSS_CONSOLE Console)
-{
-  SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Console->Title.Buffer);
-}
-
-VOID STDCALL
-GuiConsoleDeleteConsole(PCSRSS_CONSOLE Console)
-{
-  SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console);
+  EnterCriticalSection(&(Console->ActiveBuffer->Header.Lock));
 }
 
 /* EOF */
index 62bcb31..578ab66 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: guiconsole.h,v 1.1 2003/12/02 11:38:46 gvg Exp $
+/* $Id: guiconsole.h,v 1.2 2004/01/11 17:31:16 gvg Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -8,7 +8,7 @@
 
 #include "api.h"
 
-extern BOOL STDCALL GuiConsoleInitConsole(PCSRSS_CONSOLE Console);
+extern NTSTATUS FASTCALL GuiInitConsole(PCSRSS_CONSOLE Console);
 extern VOID STDCALL GuiConsoleDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT Region);
 extern VOID STDCALL GuiConsoleCopyRegion(PCSRSS_CONSOLE Console,
                                          RECT *Source,
@@ -16,6 +16,4 @@ extern VOID STDCALL GuiConsoleCopyRegion(PCSRSS_CONSOLE Console,
 extern VOID STDCALL GuiConsoleChangeTitle(PCSRSS_CONSOLE Console);
 extern VOID STDCALL GuiConsoleDeleteConsole(PCSRSS_CONSOLE Console);
 
-extern VOID FASTCALL GuiConsoleInitConsoleSupport(VOID);
-
 /*EOF*/
diff --git a/reactos/subsys/csrss/win32csr/tuiconsole.c b/reactos/subsys/csrss/win32csr/tuiconsole.c
new file mode 100644 (file)
index 0000000..ac7bc99
--- /dev/null
@@ -0,0 +1,346 @@
+/* $Id: tuiconsole.c,v 1.1 2004/01/11 17:31:16 gvg Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS system libraries
+ * FILE:            subsys/csrss/win32csr/tuiconsole.c
+ * PURPOSE:         Implementation of text-mode consoles
+ */
+
+#include <windows.h>
+#include <ddk/ntddblue.h>
+#include <string.h>
+#include "api.h"
+#include "conio.h"
+#include "tuiconsole.h"
+#include "win32csr.h"
+
+#define NDEBUG
+#include <debug.h>
+
+CRITICAL_SECTION ActiveConsoleLock;
+static COORD PhysicalConsoleSize;
+static HANDLE ConsoleDeviceHandle;
+static PCSRSS_CONSOLE ActiveConsole;
+
+static BOOL Initialized = FALSE;
+
+static BOOL FASTCALL
+TuiInit(VOID)
+{
+  CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
+  DWORD BytesReturned;
+  ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL,
+                                    OPEN_EXISTING, 0, NULL);
+  if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle)
+    {
+      DPRINT1("Failed to open BlueScreen.\n");
+      return FALSE;
+    }
+
+  ActiveConsole = NULL;
+  InitializeCriticalSection(&ActiveConsoleLock);
+  if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
+                        NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL))
+    {
+      DPRINT1("Failed to get console info\n");
+      return FALSE;
+    }
+  PhysicalConsoleSize = ScrInfo.dwSize;
+
+  return TRUE;
+}
+
+static VOID STDCALL
+TuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer)
+{
+  Buffer->DefaultAttrib = 0x17;
+}
+
+static void FASTCALL
+TuiCopyRect(char *Dest, PCSRSS_SCREEN_BUFFER Buff, RECT *Region)
+{
+  UINT SrcDelta, DestDelta, i;
+  char *Src, *SrcEnd;
+
+  Src = Buff->Buffer + (((Region->top + Buff->ShowY) % Buff->MaxY) * Buff->MaxX
+                        + Region->left + Buff->ShowX) * 2;
+  SrcDelta = Buff->MaxX * 2;
+  SrcEnd = Buff->Buffer + Buff->MaxY * Buff->MaxX * 2;
+  DestDelta = ConioRectWidth(Region) * 2;
+  for (i = Region->top; i <= Region->bottom; i++)
+    {
+      memcpy(Dest, Src, DestDelta);
+      Src += SrcDelta;
+      if (SrcEnd <= Src)
+        {
+          Src -= Buff->MaxY * Buff->MaxX * 2;
+        }
+      Dest += DestDelta;
+    }
+}
+
+static VOID STDCALL
+TuiDrawRegion(PCSRSS_CONSOLE Console, RECT *Region)
+{
+  DWORD BytesReturned;
+  PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
+  LONG CursorX, CursorY;
+  PCONSOLE_DRAW ConsoleDraw;
+  UINT ConsoleDrawSize;
+
+  if (ActiveConsole != Console)
+    {
+      return;
+    }
+
+  ConsoleDrawSize = sizeof(CONSOLE_DRAW) +
+                    (ConioRectWidth(Region) * ConioRectHeight(Region)) * 2;
+  ConsoleDraw = HeapAlloc(Win32CsrApiHeap, 0, ConsoleDrawSize);
+  if (NULL == ConsoleDraw)
+    {
+      DPRINT1("HeapAlloc failed\n");
+      return;
+    }
+  ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &CursorX, &CursorY);
+  ConsoleDraw->X = Region->left;
+  ConsoleDraw->Y = Region->top;
+  ConsoleDraw->SizeX = ConioRectWidth(Region);
+  ConsoleDraw->SizeY = ConioRectHeight(Region);
+  ConsoleDraw->CursorX = CursorX;
+  ConsoleDraw->CursorY = CursorY;
+  
+  TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region);
+  
+  if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW,
+                        ConsoleDraw, ConsoleDrawSize, NULL, 0, &BytesReturned, NULL))
+    {
+      DPRINT1("Failed to draw console\n");
+      HeapFree(Win32CsrApiHeap, 0, ConsoleDraw);
+      return;
+    }
+
+  HeapFree(Win32CsrApiHeap, 0, ConsoleDraw);
+}
+
+static VOID STDCALL
+TuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, UINT CursorStartX, UINT CursorStartY,
+               UINT ScrolledLines, CHAR *Buffer, UINT Length)
+{
+  DWORD BytesWritten;
+  PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
+
+  if (ActiveConsole->ActiveBuffer != Buff)
+    {
+      return;
+    }
+
+  if (! WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL))
+    {
+      DPRINT1("Error writing to BlueScreen\n");
+    }
+}
+
+static BOOL STDCALL
+TuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
+{
+  DWORD BytesReturned;
+
+  if (ActiveConsole->ActiveBuffer != Buff)
+    {
+      return TRUE;
+    }
+
+  if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO,
+                        &Buff->CursorInfo, sizeof(Buff->CursorInfo), NULL, 0,
+                        &BytesReturned, NULL))
+    {
+      DPRINT1( "Failed to set cursor info\n" );
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static BOOL STDCALL
+TuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY)
+{
+  CONSOLE_SCREEN_BUFFER_INFO Info;
+  LONG CursorX, CursorY;
+  DWORD BytesReturned;
+
+  if (ActiveConsole->ActiveBuffer != Buff)
+    {
+      return TRUE;
+    }
+
+  ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &CursorX, &CursorY);
+  Info.dwCursorPosition.X = CursorX;
+  Info.dwCursorPosition.Y = CursorY;
+  Info.wAttributes = Buff->DefaultAttrib;
+
+  if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
+                        &Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0,
+                        &BytesReturned, NULL))
+    {
+      DPRINT1( "Failed to set cursor position\n" );
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+STATIC BOOL STDCALL
+TuiChangeTitle(PCSRSS_CONSOLE Console)
+{
+  return TRUE;
+}
+
+STATIC VOID STDCALL
+TuiCleanupConsole(PCSRSS_CONSOLE Console)
+{
+  EnterCriticalSection(&ActiveConsoleLock);
+
+  /* Switch to next console */
+  if (ActiveConsole == Console)
+    {
+      ActiveConsole = Console->Next != Console ? Console->Next : NULL;
+    }
+
+  if (Console->Next != Console)
+    {
+      Console->Prev->Next = Console->Next;
+      Console->Next->Prev = Console->Prev;
+    }
+  LeaveCriticalSection(&ActiveConsoleLock);
+   
+  if (NULL != ActiveConsole)
+    {
+      ConioDrawConsole(ActiveConsole);
+    }
+}
+
+static CSRSS_CONSOLE_VTBL TuiVtbl =
+{
+  TuiInitScreenBuffer,
+  TuiWriteStream,
+  TuiDrawRegion,
+  TuiSetCursorInfo,
+  TuiSetScreenInfo,
+  TuiChangeTitle,
+  TuiCleanupConsole
+};
+
+NTSTATUS FASTCALL
+TuiInitConsole(PCSRSS_CONSOLE Console)
+{
+  if (! Initialized)
+    {
+      Initialized = TRUE;
+      if (! TuiInit())
+        {
+          Initialized = FALSE;
+          return STATUS_UNSUCCESSFUL;
+        }
+    }
+
+  Console->Vtbl = &TuiVtbl;
+  Console->hWindow = (HWND) NULL;
+  Console->Size = PhysicalConsoleSize;
+
+  EnterCriticalSection(&ActiveConsoleLock);
+  if (NULL != ActiveConsole)
+    {
+      Console->Prev = ActiveConsole;
+      Console->Next = ActiveConsole->Next;
+      ActiveConsole->Next->Prev = Console;
+      ActiveConsole->Next = Console;
+    }
+  else
+    {
+      Console->Prev = Console;
+      Console->Next = Console;
+    }
+  ActiveConsole = Console;
+  LeaveCriticalSection(&ActiveConsoleLock);
+
+  return STATUS_SUCCESS;
+}
+
+PCSRSS_CONSOLE FASTCALL
+TuiGetFocusConsole(VOID)
+{
+  return ActiveConsole;
+}
+
+BOOL FASTCALL
+TuiSwapConsole(int Next)
+{
+  static PCSRSS_CONSOLE SwapConsole = NULL; /* console we are thinking about swapping with */
+  DWORD BytesReturned;
+  ANSI_STRING Title;
+  void * Buffer;
+  COORD *pos;
+
+  if (0 != Next)
+    {
+      /* alt-tab, swap consoles */
+      /* move SwapConsole to next console, and print its title */
+      EnterCriticalSection(&ActiveConsoleLock);
+      if (! SwapConsole)
+        {
+          SwapConsole = ActiveConsole;
+        }
+             
+      SwapConsole = (0 < Next ? SwapConsole->Next : SwapConsole->Prev);
+      Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Title);
+      Title.Length = 0;
+      Buffer = HeapAlloc(Win32CsrApiHeap,
+                               0,
+                               sizeof(COORD) + Title.MaximumLength);
+      pos = (COORD *)Buffer;
+      Title.Buffer = Buffer + sizeof( COORD );
+
+      RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Title, FALSE);
+      pos->Y = PhysicalConsoleSize.Y / 2;
+      pos->X = (PhysicalConsoleSize.X - Title.Length) / 2;
+      /* redraw the console to clear off old title */
+      ConioDrawConsole(ActiveConsole);
+      if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
+                            Buffer, sizeof(COORD) + Title.Length, NULL, 0,
+                            &BytesReturned, NULL))
+        {
+          DPRINT1( "Error writing to console\n" );
+        }
+      HeapFree(Win32CsrApiHeap, 0, Buffer);
+      LeaveCriticalSection(&ActiveConsoleLock);
+
+      return TRUE;
+    }
+  else if (NULL != SwapConsole)
+    {
+      EnterCriticalSection(&ActiveConsoleLock);
+      if (SwapConsole != ActiveConsole)
+        {
+          /* first remove swapconsole from the list */
+          SwapConsole->Prev->Next = SwapConsole->Next;
+          SwapConsole->Next->Prev = SwapConsole->Prev;
+          /* now insert before activeconsole */
+          SwapConsole->Next = ActiveConsole;
+          SwapConsole->Prev = ActiveConsole->Prev;
+          ActiveConsole->Prev->Next = SwapConsole;
+          ActiveConsole->Prev = SwapConsole;
+        }
+      ActiveConsole = SwapConsole;
+      SwapConsole = NULL;
+      ConioDrawConsole(ActiveConsole);
+      LeaveCriticalSection(&ActiveConsoleLock);
+      return TRUE;
+    }
+  else
+    {
+      return FALSE;
+    }
+}
+
+/* EOF */
diff --git a/reactos/subsys/csrss/win32csr/tuiconsole.h b/reactos/subsys/csrss/win32csr/tuiconsole.h
new file mode 100644 (file)
index 0000000..85302bb
--- /dev/null
@@ -0,0 +1,15 @@
+/* $Id: tuiconsole.h,v 1.1 2004/01/11 17:31:16 gvg Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS system libraries
+ * FILE:            subsys/csrss/win32csr/tuiconsole.h
+ * PURPOSE:         Interface to text-mode consoles
+ */
+
+#include "api.h"
+
+extern NTSTATUS FASTCALL TuiInitConsole(PCSRSS_CONSOLE Console);
+extern PCSRSS_CONSOLE FASTCALL TuiGetFocusConsole(VOID);
+extern BOOL FASTCALL TuiSwapConsole(int Next);
+
+/* EOF */