- Allocate the csrss request buffer from heap if the necessary length is larger than...
[reactos.git] / reactos / subsys / csrss / win32csr / conio.c
index 55e8559..51084e1 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: conio.c,v 1.6 2004/02/25 23:33:42 hbirr Exp $
- *
+/*
  * reactos/subsys/csrss/win32csr/conio.c
  *
  * Console I/O functions
@@ -9,21 +8,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <string.h>
-#include <windows.h>
-
-#include <csrss/csrss.h>
-#include <ntdll/rtl.h>
-#include <ntdll/ldr.h>
-#include <ddk/ntddblue.h>
-#include <rosrtl/string.h>
-#include <rosrtl/minmax.h>
-#include "api.h"
-#include "conio.h"
-#include "desktopbg.h"
-#include "guiconsole.h"
-#include "tuiconsole.h"
-#include "win32csr.h"
+#include "w32csr.h"
 
 #define NDEBUG
 #include <debug.h>
@@ -46,6 +31,13 @@ extern VOID STDCALL PrivateCsrssAcquireOrReleaseInputOwnership(BOOL Release);
 #define ConioIsRectEmpty(Rect) \
   (((Rect)->left > (Rect)->right) || ((Rect)->top > (Rect)->bottom))
 
+#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
+  WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
+
+#define ConsoleAnsiCharToUnicodeChar(Console, sWChar, dChar) \
+  MultiByteToWideChar((Console)->CodePage, 0, (dChar), 1, (sWChar), 1)
+
+
 /* FUNCTIONS *****************************************************************/
 
 STATIC NTSTATUS FASTCALL
@@ -63,55 +55,45 @@ ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Con
   return STATUS_SUCCESS;
 }
 
-STATIC VOID FASTCALL
-CsrConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData)
+VOID FASTCALL
+ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData)
 {
-  HANDLE Process, Thread;
-       
-  DPRINT("CsrConsoleCtrlEvent Parent ProcessId = %x\n",        ClientId.UniqueProcess);
+  HANDLE Thread;
+
+  DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n",      ProcessData->ProcessId);
 
   if (ProcessData->CtrlDispatcher)
     {
-      Process = OpenProcess(PROCESS_DUP_HANDLE, FALSE, ProcessData->ProcessId);
-      if (NULL == Process)
-        {
-          DPRINT1("Failed for handle duplication\n");
-          return;
-        }
 
-      DPRINT("CsrConsoleCtrlEvent Process Handle = %x\n", Process);
-
-      Thread = CreateRemoteThread(Process, NULL, 0,
+      Thread = CreateRemoteThread(ProcessData->Process, NULL, 0,
                                   (LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher,
                                   (PVOID) Event, 0, NULL);
       if (NULL == Thread)
         {
-          DPRINT1("Failed thread creation\n");
-          CloseHandle(Process);
+          DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
           return;
         }
       CloseHandle(Thread);
-      CloseHandle(Process);
     }
 }
 
 #define GET_CELL_BUFFER(b,o)\
-(b)->Buffer[(o)++];
+(b)->Buffer[(o)++]
 
 #define SET_CELL_BUFFER(b,o,c,a)\
-(b)->Buffer[(o)++]=(c);\
-(b)->Buffer[(o)++]=(a);
+(b)->Buffer[(o)++]=(c),\
+(b)->Buffer[(o)++]=(a)
 
 static VOID FASTCALL
 ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff)
 {
   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)
+      SET_CELL_BUFFER(Buff, Offset, ' ', Buff->DefaultAttrib);
     }
 }
 
@@ -130,7 +112,7 @@ CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
     {
       return STATUS_INSUFFICIENT_RESOURCES;
     }
-  RtlInitializeCriticalSection(&Buffer->Header.Lock);
+  InitializeCriticalSection(&Buffer->Header.Lock);
   ConioInitScreenBuffer(Console, Buffer);
   /* initialize buffer to be empty with default attributes */
   for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++)
@@ -156,9 +138,9 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
 
   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;
@@ -170,16 +152,21 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
   InitializeListHead(&Console->InputEvents);
   InitializeListHead(&Console->ProcessList);
 
+  Console->CodePage = GetOEMCP();
+  Console->OutputCodePage = GetOEMCP();
+
   SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
   SecurityAttributes.lpSecurityDescriptor = NULL;
   SecurityAttributes.bInheritHandle = TRUE;
 
-  Console->ActiveEvent = CreateEventW(&SecurityAttributes, FALSE, FALSE, NULL);
+  Console->ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL);
   if (NULL == Console->ActiveEvent)
     {
+      RtlFreeUnicodeString(&Console->Title);
       return STATUS_UNSUCCESSFUL;
     }
   Console->PrivateData = NULL;
+  InitializeCriticalSection(&Console->Header.Lock);
   GuiMode = DtbgIsDesktopVisible();
   if (! GuiMode)
     {
@@ -195,6 +182,8 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
       Status = GuiInitConsole(Console);
       if (! NT_SUCCESS(Status))
         {
+          RtlFreeUnicodeString(&Console->Title);
+         DeleteCriticalSection(&Console->Header.Lock);
           CloseHandle(Console->ActiveEvent);
           return Status;
         }
@@ -203,19 +192,25 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
   NewBuffer = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_SCREEN_BUFFER));
   if (NULL == NewBuffer)
     {
+      ConioCleanupConsole(Console);
+      RtlFreeUnicodeString(&Console->Title);
+      DeleteCriticalSection(&Console->Header.Lock);
       CloseHandle(Console->ActiveEvent);
       return STATUS_INSUFFICIENT_RESOURCES;
     }
   Status = CsrInitConsoleScreenBuffer(Console, NewBuffer);
   if (! NT_SUCCESS(Status))
     {
+      ConioCleanupConsole(Console);
+      RtlFreeUnicodeString(&Console->Title);
+      DeleteCriticalSection(&Console->Header.Lock);
       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++;
+  InterlockedIncrement(&Console->ActiveBuffer->Header.ReferenceCount);
   /* make console active, and insert into console list */
   /* copy buffer contents to screen */
   ConioDrawConsole(Console);
@@ -226,89 +221,135 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
 
 CSR_API(CsrAllocConsole)
 {
-  PCSRSS_CONSOLE Console;
-  HANDLE Process;
-  NTSTATUS Status;
+    PCSRSS_CONSOLE Console;
+    NTSTATUS Status = STATUS_SUCCESS;
+    BOOLEAN NewConsole = FALSE;
 
-  DPRINT("CsrAllocConsole\n");
+    DPRINT("CsrAllocConsole\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+    Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+    Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
-  if (ProcessData == NULL)
+    if (ProcessData == NULL)
     {
-      return Reply->Status = STATUS_INVALID_PARAMETER;
+        DPRINT1("No process data\n");
+        return Request->Status = STATUS_INVALID_PARAMETER;
     }
 
-  if (ProcessData->Console)
+    if (ProcessData->Console)
     {
-      Reply->Status = STATUS_INVALID_PARAMETER;
-      return STATUS_INVALID_PARAMETER;
+        DPRINT1("Process already has a console\n");
+        Request->Status = STATUS_INVALID_PARAMETER;
+        return STATUS_INVALID_PARAMETER;
     }
 
-  Reply->Status = STATUS_SUCCESS;
-  Console = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_CONSOLE));
-  if (NULL == Console)
-    {
-      Reply->Status = STATUS_NO_MEMORY;
-      return STATUS_NO_MEMORY;
-    }
-  Reply->Status = CsrInitConsole(Console);
-  if (! NT_SUCCESS(Reply->Status))
+    /* Assume success */
+    Request->Status = STATUS_SUCCESS;
+
+    /* If we don't need a console, then get out of here */
+    if (!Request->Data.AllocConsoleRequest.ConsoleNeeded)
     {
-      HeapFree(Win32CsrApiHeap, 0, Console);
-      return Reply->Status;
+        DPRINT("No console needed\n");
+        return STATUS_SUCCESS;
     }
-  ProcessData->Console = Console;
-  Reply->Data.AllocConsoleReply.Console = Console;
 
-  /* add a reference count because the process is tied to the console */
-  Console->Header.ReferenceCount++;
-  Status = Win32CsrInsertObject(ProcessData, &Reply->Data.AllocConsoleReply.InputHandle, &Console->Header);
-  if (! NT_SUCCESS(Status))
+    /* If we already have one, then don't create a new one... */
+    if (!Request->Data.AllocConsoleRequest.Console ||
+        Request->Data.AllocConsoleRequest.Console != ProcessData->ParentConsole)
     {
-      ConioDeleteConsole((Object_t *) Console);
-      ProcessData->Console = 0;
-      return Reply->Status = Status;
+        /* Allocate a console structure */
+        NewConsole = TRUE;
+        Console = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_CONSOLE));
+        if (NULL == Console)
+        {
+            DPRINT1("Not enough memory for console\n");
+            Request->Status = STATUS_NO_MEMORY;
+            return STATUS_NO_MEMORY;
+        }
+
+        /* Initialize the Console */
+        Request->Status = CsrInitConsole(Console);
+        if (!NT_SUCCESS(Request->Status))
+        {
+            DPRINT1("Console init failed\n");
+            HeapFree(Win32CsrApiHeap, 0, Console);
+            return Request->Status;
+        }
     }
-  Status = Win32CsrInsertObject(ProcessData, &Reply->Data.AllocConsoleReply.OutputHandle, &Console->ActiveBuffer->Header);
-  if (!NT_SUCCESS(Status))
+    else
     {
-      Console->Header.ReferenceCount--;
-      Win32CsrReleaseObject(ProcessData, Reply->Data.AllocConsoleReply.InputHandle);
-      ProcessData->Console = 0;
-      return Reply->Status = Status;
+        /* Reuse our current console */
+        Console = Request->Data.AllocConsoleRequest.Console;
     }
 
-  Process = OpenProcess(PROCESS_DUP_HANDLE, FALSE, ProcessData->ProcessId);
-  if (NULL == Process)
+    /* Set the Process Console */
+    ProcessData->Console = Console;
+
+    /* Return it to the caller */
+    Request->Data.AllocConsoleRequest.Console = Console;
+
+    /* Add a reference count because the process is tied to the console */
+    Console->Header.ReferenceCount++;
+
+    if (NewConsole || !ProcessData->bInheritHandles)
     {
-      DPRINT1("OpenProcess() failed for handle duplication\n");
-      Console->Header.ReferenceCount--;
-      ProcessData->Console = 0;
-      Win32CsrReleaseObject(ProcessData, Reply->Data.AllocConsoleReply.OutputHandle);
-      Win32CsrReleaseObject(ProcessData, Reply->Data.AllocConsoleReply.InputHandle);
-      Reply->Status = Status;
-      return Status;
+        /* Insert the Objects */
+        Status = Win32CsrInsertObject(ProcessData, 
+                                      &Request->Data.AllocConsoleRequest.InputHandle, 
+                                      &Console->Header);
+        if (! NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to insert object\n");
+            ConioDeleteConsole((Object_t *) Console);
+            ProcessData->Console = 0;
+            return Request->Status = Status;
+        }
+    
+        Status = Win32CsrInsertObject(ProcessData, 
+                                      &Request->Data.AllocConsoleRequest.OutputHandle, 
+                                      &Console->ActiveBuffer->Header);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to insert object\n");
+            ConioDeleteConsole((Object_t *) Console);
+            Win32CsrReleaseObject(ProcessData, 
+                                  Request->Data.AllocConsoleRequest.InputHandle);
+            ProcessData->Console = 0;
+            return Request->Status = Status;
+        }
     }
-  if (! DuplicateHandle(GetCurrentProcess(), ProcessData->Console->ActiveEvent,
-                        Process, &ProcessData->ConsoleEvent, EVENT_ALL_ACCESS, FALSE, 0))
+
+    /* Duplicate the Event */
+    if (!DuplicateHandle(GetCurrentProcess(), 
+                         ProcessData->Console->ActiveEvent,
+                         ProcessData->Process, 
+                         &ProcessData->ConsoleEvent, 
+                         EVENT_ALL_ACCESS, 
+                         FALSE, 
+                         0))
     {
-      DPRINT1("DuplicateHandle() failed: %d\n", GetLastError);
-      CloseHandle(Process);
-      Console->Header.ReferenceCount--;
-      Win32CsrReleaseObject(ProcessData, Reply->Data.AllocConsoleReply.OutputHandle);
-      Win32CsrReleaseObject(ProcessData, Reply->Data.AllocConsoleReply.InputHandle);
-      ProcessData->Console = 0;
-      Reply->Status = Status;
-      return Status;
+        DPRINT1("DuplicateHandle() failed: %d\n", GetLastError);
+        ConioDeleteConsole((Object_t *) Console);
+        if (NewConsole || !ProcessData->bInheritHandles)
+        {
+            Win32CsrReleaseObject(ProcessData,
+                                  Request->Data.AllocConsoleRequest.OutputHandle);
+            Win32CsrReleaseObject(ProcessData,
+                                  Request->Data.AllocConsoleRequest.InputHandle);
+        }
+        ProcessData->Console = 0;
+        return Request->Status = Status;
     }
-  CloseHandle(Process);
-  ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher;
-  DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);      
-  InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry);
 
-  return STATUS_SUCCESS;
+    /* Set the Ctrl Dispatcher */
+    ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher;
+    DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
+
+    /* Insert into the list */
+////////////////////////////
+    InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry);
+///////////////////////////
+    return STATUS_SUCCESS;
 }
 
 CSR_API(CsrFreeConsole)
@@ -317,22 +358,21 @@ CSR_API(CsrFreeConsole)
 
   DPRINT("CsrFreeConsole\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   if (ProcessData == NULL || ProcessData->Console == NULL)
     {
-      return Reply->Status = STATUS_INVALID_PARAMETER;
+      return Request->Status = STATUS_INVALID_PARAMETER;
     }
 
   Console = ProcessData->Console;
-  Console->Header.ReferenceCount--;
   ProcessData->Console = NULL;
-  if (0 == Console->Header.ReferenceCount)
+  if (0 == InterlockedDecrement(&Console->Header.ReferenceCount))
     {
       ConioDeleteConsole((Object_t *) Console);
     }
-   
+
   return STATUS_SUCCESS;
 }
 
@@ -340,7 +380,7 @@ STATIC VOID FASTCALL
 ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines)
 {
   /* slide the viewable screen */
-  if (((Buff->CurrentY - Buff->ShowY + Buff->MaxY) % Buff->MaxY) == Buff->MaxY - 1)
+  if (((Buff->CurrentY - Buff->ShowY + Buff->MaxY) % Buff->MaxY) == (ULONG)Buff->MaxY - 1)
     {
       if (++Buff->ShowY == Buff->MaxY)
         {
@@ -355,7 +395,7 @@ ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines)
   ClearLineBuffer(Buff);
   UpdateRect->left = 0;
   UpdateRect->right = Buff->MaxX - 1;
-  if (UpdateRect->top == Buff->CurrentY)
+  if (UpdateRect->top == (LONG)Buff->CurrentY)
     {
       if (++UpdateRect->top == Buff->MaxY)
         {
@@ -369,7 +409,7 @@ STATIC NTSTATUS FASTCALL
 ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
                   CHAR *Buffer, DWORD Length, BOOL Attrib)
 {
-  int i;
+  UINT i;
   DWORD Offset;
   RECT UpdateRect;
   LONG CursorStartX, CursorStartY;
@@ -384,63 +424,66 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
 
   for (i = 0; i < Length; i++)
     {
-      switch(Buffer[i])
+      if (Buff->Mode & ENABLE_PROCESSED_OUTPUT)
         {
           /* --- LF --- */
-          case '\n':
-            Buff->CurrentX = 0;
-            ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
-            break;
-
+          if (Buffer[i] == '\n')
+            {
+              Buff->CurrentX = 0;
+              ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
+              continue;
+            }
           /* --- BS --- */
-          case '\b':
-            /* Only handle BS if we're not on the first pos of the first line */
-            if (0 != Buff->CurrentX || Buff->ShowY != Buff->CurrentY)
-              {
-                if (0 == Buff->CurrentX)
-                  {
-                    /* slide virtual position up */
-                    Buff->CurrentX = Buff->MaxX - 1;
-                    if (0 == Buff->CurrentY)
-                      {
-                        Buff->CurrentY = Buff->MaxY;
-                      }
-                    else
-                      {
-                        Buff->CurrentY--;
-                      }
-                    if ((0 == UpdateRect.top && UpdateRect.bottom < Buff->CurrentY)
-                        || (0 != UpdateRect.top && Buff->CurrentY < UpdateRect.top))
-                      {
-                        UpdateRect.top = Buff->CurrentY;
-                      }
-                  }
-                else
-                  {
-                     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);
-              }
-            break;
-
+          else if (Buffer[i] == '\b')
+            {
+              /* Only handle BS if we're not on the first pos of the first line */
+              if (0 != Buff->CurrentX || Buff->ShowY != Buff->CurrentY)
+                {
+                  if (0 == Buff->CurrentX)
+                    {
+                      /* slide virtual position up */
+                      Buff->CurrentX = Buff->MaxX - 1;
+                      if (0 == Buff->CurrentY)
+                        {
+                          Buff->CurrentY = Buff->MaxY;
+                        }
+                      else
+                        {
+                          Buff->CurrentY--;
+                        }
+                      if ((0 == UpdateRect.top && UpdateRect.bottom < (LONG)Buff->CurrentY)
+                          || (0 != UpdateRect.top && (LONG)Buff->CurrentY < UpdateRect.top))
+                        {
+                          UpdateRect.top = Buff->CurrentY;
+                        }
+                    }
+                  else
+                    {
+                       Buff->CurrentX--;
+                    }
+                  Offset = 2 * ((Buff->CurrentY * Buff->MaxX) + Buff->CurrentX);
+                  SET_CELL_BUFFER(Buff, Offset, ' ', Buff->DefaultAttrib);
+                  UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX);
+                  UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
+                }
+                continue;
+            }
           /* --- CR --- */
-          case '\r':
-            Buff->CurrentX = 0;
-            UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
-            UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX);
-            break;
-
+          else if (Buffer[i] == '\r')
+            {
+              Buff->CurrentX = 0;
+              UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX);
+              UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
+              continue;
+            }
           /* --- TAB --- */
-          case '\t':
+          else if (Buffer[i] == '\t')
             {
               UINT EndX;
 
-              UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
-              EndX = 8 * ((Buff->CurrentX + 8) / 8);
-              if (Buff->MaxX < EndX)
+              UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX);
+              EndX = (Buff->CurrentX + 8) & ~7;
+              if (EndX > Buff->MaxX)
                 {
                   EndX = Buff->MaxX;
                 }
@@ -451,32 +494,42 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
                   Offset += 2;
                   Buff->CurrentX++;
                 }
-              UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX - 1);
+              UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX - 1);
               if (Buff->CurrentX == Buff->MaxX)
                 {
-                  Buff->CurrentX = 0;
-                  ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
+                  if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
+                    {
+                      Buff->CurrentX = 0;
+                      ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
+                    }
+                  else
+                    {
+                      Buff->CurrentX--;
+                    }
                 }
+              continue;
+            }
+        }
+      UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX);
+      UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
+      Offset = 2 * (((Buff->CurrentY * Buff->MaxX)) + Buff->CurrentX);
+      Buff->Buffer[Offset++] = Buffer[i];
+      if (Attrib)
+        {
+          Buff->Buffer[Offset] = Buff->DefaultAttrib;
+        }
+      Buff->CurrentX++;
+      if (Buff->CurrentX == Buff->MaxX)
+        {
+          if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
+            {
+              Buff->CurrentX = 0;
+              ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
+            }
+          else
+            {
+              Buff->CurrentX = CursorStartX;
             }
-            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)
-              {
-                Buff->Buffer[Offset] = Buff->DefaultAttrib;
-              }
-            Buff->CurrentX++;
-            if (Buff->CurrentX == Buff->MaxX)
-              {
-                Buff->CurrentX = 0;
-                ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
-              }
-            break;
         }
     }
 
@@ -497,37 +550,46 @@ CSR_API(CsrReadConsole)
 {
   PLIST_ENTRY CurrentEntry;
   ConsoleInput *Input;
-  PCHAR Buffer;
-  int i;
-  ULONG nNumberOfCharsToRead;
+  PUCHAR Buffer;
+  PWCHAR UnicodeBuffer;
+  ULONG i;
+  ULONG nNumberOfCharsToRead, CharSize;
   PCSRSS_CONSOLE Console;
   NTSTATUS Status;
-   
+
   DPRINT("CsrReadConsole\n");
 
+  CharSize = (Request->Data.ReadConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
+
   /* 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);
+  nNumberOfCharsToRead = min(Request->Data.ReadConsoleRequest.NrCharactersToRead, CSRSS_MAX_READ_CONSOLE / CharSize);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
-  Buffer = Reply->Data.ReadConsoleReply.Buffer;
+  Buffer = Request->Data.ReadConsoleRequest.Buffer;
+  UnicodeBuffer = (PWCHAR)Buffer;
   Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle,
                                &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
-  Reply->Data.ReadConsoleReply.EventHandle = ProcessData->ConsoleEvent;
+  Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent;
   for (i = 0; i < nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++)
     {
       /* remove input event from queue */
       CurrentEntry = RemoveHeadList(&Console->InputEvents);
+      if (IsListEmpty(&Console->InputEvents))
+      {
+         CHECKPOINT;
+         ResetEvent(Console->ActiveEvent);
+      }
       Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
 
       /* only pay attention to valid ascii chars, on key down */
       if (KEY_EVENT == Input->InputEvent.EventType
           && Input->InputEvent.Event.KeyEvent.bKeyDown
-          && Input->InputEvent.Event.KeyEvent.uChar.AsciiChar)
+          && Input->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\0')
         {
           /* backspace handling */
           if ('\b' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar)
@@ -537,7 +599,7 @@ CSR_API(CsrReadConsole)
                   && (0 !=  i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted))
                 {
                   ConioWriteConsole(Console, Console->ActiveBuffer,
-                                   &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE);
+                                    &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE);
                 }
               if (0 != i)
                 {
@@ -545,11 +607,11 @@ CSR_API(CsrReadConsole)
                 }
               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);
+                  HeapFree(Win32CsrApiHeap, 0, Input);
+                  Request->Data.ReadConsoleRequest.NrCharactersRead = 0;
+                  Request->Status = STATUS_NOTIFY_CLEANUP;
                   return STATUS_NOTIFY_CLEANUP;
                 }
               Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--;
@@ -558,7 +620,10 @@ CSR_API(CsrReadConsole)
           /* do not copy backspace to buffer */
           else
             {
-              Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar;
+              if(Request->Data.ReadConsoleRequest.Unicode)
+                UnicodeBuffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar; /* FIXME */
+              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)
@@ -576,29 +641,30 @@ CSR_API(CsrReadConsole)
       Console->WaitingChars--;
       HeapFree(Win32CsrApiHeap, 0, Input);
     }
-  Reply->Data.ReadConsoleReply.NrCharactersRead = i;
+  Request->Data.ReadConsoleRequest.NrCharactersRead = i;
   if (0 == i)
     {
-      Reply->Status = STATUS_PENDING;    /* we didn't read anything */
+      Request->Status = STATUS_PENDING;    /* we didn't read anything */
     }
   else if (0 != (Console->Mode & ENABLE_LINE_INPUT))
     {
-      if (0 == Console->WaitingLines || '\n' != Buffer[i - 1])
+      if (0 == Console->WaitingLines ||
+          (Request->Data.ReadConsoleRequest.Unicode ? (L'\n' != UnicodeBuffer[i - 1]) : ('\n' != Buffer[i - 1])))
         {
-          Reply->Status = STATUS_PENDING; /* line buffered, didn't get a complete line */
+          Request->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 */
+          Request->Status = STATUS_SUCCESS; /* line buffered, did get a complete line */
         }
     }
   else
     {
-      Reply->Status = STATUS_SUCCESS;  /* not line buffered, did read something */
+      Request->Status = STATUS_SUCCESS;  /* not line buffered, did read something */
     }
 
-  if (Reply->Status == STATUS_PENDING)
+  if (Request->Status == STATUS_PENDING)
     {
       Console->EchoCount = nNumberOfCharsToRead - i;
     }
@@ -606,10 +672,16 @@ CSR_API(CsrReadConsole)
     {
       Console->EchoCount = 0;             /* if the client is no longer waiting on input, do not echo */
     }
-  Reply->Header.MessageSize += i;
 
   ConioUnlockConsole(Console);
-  return Reply->Status;
+
+  if (CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize > sizeof(CSR_API_MESSAGE))
+    {
+      Request->Header.u1.s1.TotalLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize;
+      Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
+    }
+
+  return Request->Status;
 }
 
 VOID FASTCALL
@@ -656,10 +728,10 @@ inline BOOLEAN ConioGetIntersection(
   }
 
   ConioInitRect(Intersection,
-               RtlRosMax(Rect1->top, Rect2->top),
-               RtlRosMax(Rect1->left, Rect2->left),
-               RtlRosMin(Rect1->bottom, Rect2->bottom),
-               RtlRosMin(Rect1->right, Rect2->right));
+               max(Rect1->top, Rect2->top),
+               max(Rect1->left, Rect2->left),
+               min(Rect1->bottom, Rect2->bottom),
+               min(Rect1->right, Rect2->right));
 
   return TRUE;
 }
@@ -688,10 +760,10 @@ inline BOOLEAN ConioGetUnion(
   else
     {
       ConioInitRect(Union,
-                   RtlRosMin(Rect1->top, Rect2->top),
-                   RtlRosMin(Rect1->left, Rect2->left),
-                   RtlRosMax(Rect1->bottom, Rect2->bottom),
-                   RtlRosMax(Rect1->right, Rect2->right));
+                   min(Rect1->top, Rect2->top),
+                   min(Rect1->left, Rect2->left),
+                   max(Rect1->bottom, Rect2->bottom),
+                   max(Rect1->right, Rect2->right));
     }
 
   return TRUE;
@@ -753,7 +825,7 @@ ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
   DWORD SrcOffset;
   DWORD DstOffset;
   DWORD BytesPerLine;
-  ULONG i;
+  LONG i;
 
   DstY = DstRegion->top;
   BytesPerLine = ConioRectWidth(DstRegion) * 2;
@@ -762,7 +834,7 @@ ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
   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(
@@ -793,14 +865,22 @@ ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
 }
 
 STATIC VOID FASTCALL
-ConioFillRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
+ConioFillRegion(PCSRSS_CONSOLE Console,
+                PCSRSS_SCREEN_BUFFER ScreenBuffer,
                 RECT *Region,
-                CHAR_INFO CharInfo)
+                CHAR_INFO *CharInfo,
+                BOOL bUnicode)
 {
   SHORT X, Y;
   DWORD Offset;
   DWORD Delta;
-  ULONG i;
+  LONG i;
+  CHAR Char;
+
+  if(bUnicode)
+    ConsoleUnicodeCharToAnsiChar(Console, &Char, &CharInfo->Char.UnicodeChar);
+  else
+    Char = CharInfo->Char.AsciiChar;
 
   Y = (Region->top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
   Offset = (Y * ScreenBuffer->MaxX + Region->left + ScreenBuffer->ShowX) * 2;
@@ -810,7 +890,7 @@ ConioFillRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
     {
       for (X = Region->left; X <= Region->right; X++)
         {
-          SET_CELL_BUFFER(ScreenBuffer, Offset, CharInfo.Char.AsciiChar, CharInfo.Attributes);
+          SET_CELL_BUFFER(ScreenBuffer, Offset, Char, CharInfo->Attributes);
         }
       if (++Y == ScreenBuffer->MaxY)
         {
@@ -824,58 +904,107 @@ ConioFillRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
     }
 }
 
+STATIC VOID FASTCALL
+ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent)
+{
+  if (InputEvent->EventType == KEY_EVENT)
+    {
+      WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
+      InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
+      ConsoleUnicodeCharToAnsiChar(Console,
+                                   &InputEvent->Event.KeyEvent.uChar.AsciiChar,
+                                   &UnicodeChar);
+    }
+}
+
 CSR_API(CsrWriteConsole)
 {
   NTSTATUS Status;
-  BYTE *Buffer = Request->Data.WriteConsoleRequest.Buffer;
+  PCHAR Buffer;
   PCSRSS_SCREEN_BUFFER Buff;
   PCSRSS_CONSOLE Console;
+  DWORD Written = 0;
+  ULONG Length;
+  ULONG CharSize = (Request->Data.WriteConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
 
   DPRINT("CsrWriteConsole\n");
-   
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
-                           sizeof(LPC_MESSAGE);
 
-  if (Request->Header.DataSize
-      < sizeof(CSRSS_WRITE_CONSOLE_REQUEST) - 1
-        + Request->Data.WriteConsoleRequest.NrCharactersToWrite)
+  if (Request->Header.u1.s1.TotalLength
+      < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) 
+        + (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize))
     {
       DPRINT1("Invalid request size\n");
-      return Reply->Status = STATUS_INVALID_PARAMETER;
+      Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+      Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+      return Request->Status = STATUS_INVALID_PARAMETER;
     }
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+  
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
-  Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff);
-  if (! NT_SUCCESS(Status))
+  if(Request->Data.WriteConsoleRequest.Unicode)
     {
-      if (NULL != Console)
+      Length = WideCharToMultiByte(Console->CodePage, 0, 
+                                   (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, 
+                                   Request->Data.WriteConsoleRequest.NrCharactersToWrite, 
+                                   NULL, 0, NULL, NULL);
+      Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length);
+      if (Buffer)
         {
-          ConioUnlockConsole(Console);
+          WideCharToMultiByte(Console->CodePage, 0, 
+                              (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, 
+                              Request->Data.WriteConsoleRequest.NrCharactersToWrite, 
+                              Buffer, Length, NULL, NULL);
+        }
+      else
+        {
+          Status = STATUS_NO_MEMORY;
+        }
+    }
+  else
+    {
+      Buffer = (PCHAR)Request->Data.WriteConsoleRequest.Buffer;
+    }
+  
+  if (Buffer)
+    {
+      Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff);
+      if (NT_SUCCESS(Status))
+        {
+          Request->Status = ConioWriteConsole(Console, Buff, Buffer,
+                                              Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
+          if (NT_SUCCESS(Status))
+            {
+              Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite;
+            }
+          ConioUnlockScreenBuffer(Buff);
+        }
+      if (Request->Data.WriteConsoleRequest.Unicode)
+        {
+          RtlFreeHeap(GetProcessHeap(), 0, Buffer);
         }
-      return Reply->Status = Status;
     }
-
-  ConioWriteConsole(Console, Buff, Buffer,
-                    Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
-  ConioUnlockScreenBuffer(Buff);
   if (NULL != Console)
     {
       ConioUnlockConsole(Console);
     }
 
-  return Reply->Status = STATUS_SUCCESS;
+  Request->Data.WriteConsoleRequest.NrCharactersWritten = Written;
+
+  return Request->Status = Status;
 }
 
 VOID STDCALL
 ConioDeleteScreenBuffer(Object_t *Object)
 {
   PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object;
-  RtlDeleteCriticalSection(&Buffer->Header.Lock);
+  DeleteCriticalSection(&Buffer->Header.Lock);
   HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
   HeapFree(Win32CsrApiHeap, 0, Buffer);
 }
@@ -908,7 +1037,7 @@ ConioDeleteConsole(Object_t *Object)
       HeapFree(Win32CsrApiHeap, 0, Event);
     }
 
-  if (0 == --Console->ActiveBuffer->Header.ReferenceCount)
+  if (0 == InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
     {
       ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
     }
@@ -917,6 +1046,7 @@ ConioDeleteConsole(Object_t *Object)
   ConioCleanupConsole(Console);
 
   CloseHandle(Console->ActiveEvent);
+  DeleteCriticalSection(&Console->Header.Lock);
   RtlFreeUnicodeString(&Console->Title);
   HeapFree(Win32CsrApiHeap, 0, Console);
 }
@@ -931,7 +1061,7 @@ CsrInitConsoleSupport(VOID)
 
 STATIC VOID FASTCALL
 ConioProcessChar(PCSRSS_CONSOLE Console,
-                            ConsoleInput *KeyEventRecord)
+                 ConsoleInput *KeyEventRecord)
 {
   BOOL updown;
   BOOL bClientWake = FALSE;
@@ -940,7 +1070,7 @@ ConioProcessChar(PCSRSS_CONSOLE Console,
   /* process Ctrl-C and Ctrl-Break */
   if (Console->Mode & ENABLE_PROCESSED_INPUT &&
       KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown &&
-      ((KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) || 
+      ((KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) ||
        (KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == 'C')) &&
       (KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))
     {
@@ -952,7 +1082,7 @@ ConioProcessChar(PCSRSS_CONSOLE Console,
        {
          current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
          current_entry = current_entry->Flink;
-         CsrConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current);
+         ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current);
        }
       HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
       return;
@@ -986,10 +1116,10 @@ ConioProcessChar(PCSRSS_CONSOLE Console,
          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 != 
+             if (Console->ActiveBuffer->ShowY % Console->ActiveBuffer->MaxY !=
                  Console->ActiveBuffer->CurrentY)
                 {
-                  if (((Console->ActiveBuffer->CurrentY + 1) % Console->ActiveBuffer->MaxY) != 
+                  if (((Console->ActiveBuffer->CurrentY + 1) % Console->ActiveBuffer->MaxY) !=
                       (Console->ActiveBuffer->ShowY + Console->ActiveBuffer->MaxY) %
                       Console->ActiveBuffer->MaxY)
                     {
@@ -1045,7 +1175,7 @@ ConioProcessChar(PCSRSS_CONSOLE Console,
   if (0 == (Console->Mode & ENABLE_LINE_INPUT)
       || Console->EarlyReturn
       || ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar
-          && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown))
+          && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown))
     {
       if ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar)
         {
@@ -1078,7 +1208,7 @@ ConioProcessChar(PCSRSS_CONSOLE Console,
             {
               ConioWriteConsole(Console, Console->ActiveBuffer,
                                &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar,
-                               1, TRUE);       
+                               1, TRUE);
             }
           HeapFree(Win32CsrApiHeap, 0, TempInput);
          RemoveEntryList(&KeyEventRecord->ListEntry);
@@ -1117,43 +1247,29 @@ ConioProcessChar(PCSRSS_CONSOLE Console,
 STATIC DWORD FASTCALL
 ConioGetShiftState(PBYTE KeyState)
 {
-  int i;
   DWORD ssOut = 0;
 
-  for (i = 0; i < 0x100; i++)
-    {
-      if (0 != (KeyState[i] & 0x80))
-        {
-          UINT vk = MapVirtualKeyExW(i, 3, 0) & 0xff;
-          switch(vk)
-            {
-              case VK_CAPITAL:
-                ssOut |= CAPSLOCK_ON;
-                break;
+  if (KeyState[VK_CAPITAL] & 1)
+      ssOut |= CAPSLOCK_ON;
 
-              case VK_NUMLOCK:
-                ssOut |= NUMLOCK_ON;
-                break;
+  if (KeyState[VK_NUMLOCK] & 1)
+      ssOut |= NUMLOCK_ON;
 
-              case VK_SCROLL:
-                ssOut |= SCROLLLOCK_ON;
-                break;
-            }
-        }
-    }
+  if (KeyState[VK_SCROLL] & 1)
+      ssOut |= SCROLLLOCK_ON;
 
-  if (KeyState[VK_LSHIFT] & 0x80 || KeyState[VK_RSHIFT] & 0x80)
+  if (KeyState[VK_SHIFT] & 0x80)
       ssOut |= SHIFT_PRESSED;
 
   if (KeyState[VK_LCONTROL] & 0x80)
-      ssOut |= RIGHT_CTRL_PRESSED;
-  else if (KeyState[VK_RCONTROL] & 0x80)
       ssOut |= LEFT_CTRL_PRESSED;
+  if (KeyState[VK_RCONTROL] & 0x80)
+      ssOut |= RIGHT_CTRL_PRESSED;
 
   if (KeyState[VK_LMENU] & 0x80)
-      ssOut |= RIGHT_ALT_PRESSED;
-  else if (KeyState[VK_RMENU] & 0x80)
       ssOut |= LEFT_ALT_PRESSED;
+  if (KeyState[VK_RMENU] & 0x80)
+      ssOut |= RIGHT_ALT_PRESSED;
 
   return ssOut;
 }
@@ -1179,7 +1295,7 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
 
   RepeatCount = 1;
   VirtualScanCode = (msg->lParam >> 16) & 0xff;
-  Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR || 
+  Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
     msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
 
   GetKeyboardState(KeyState);
@@ -1189,9 +1305,9 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
     {
       VirtualKeyCode = LastVirtualKey;
       UnicodeChar = msg->wParam;
-    } 
+    }
   else
-    { 
+    {
       WCHAR Chars[2];
       INT RetChars = 0;
 
@@ -1206,29 +1322,21 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
       UnicodeChar = (1 == RetChars ? Chars[0] : 0);
     }
 
-  if (UnicodeChar)
-    {
-      RtlUnicodeToOemN(&AsciiChar,
-                       1,
-                       &ResultSize,
-                       &UnicodeChar,
-                       sizeof(WCHAR));
-    }
   if (0 == ResultSize)
     {
       AsciiChar = 0;
     }
-  
+
   er.EventType = KEY_EVENT;
   er.Event.KeyEvent.bKeyDown = Down;
   er.Event.KeyEvent.wRepeatCount = RepeatCount;
-  er.Event.KeyEvent.uChar.UnicodeChar = AsciiChar & 0xff;
+  er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
   er.Event.KeyEvent.dwControlKeyState = ShiftState;
   er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
   er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
 
   if (TextMode)
-    {    
+    {
       if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
           && VK_TAB == VirtualKeyCode)
         {
@@ -1248,7 +1356,7 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
         }
     }
 
-  if (NULL == Console) 
+  if (NULL == Console)
     {
       return;
     }
@@ -1259,9 +1367,9 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
     {
       return;
     }
-    
+
   ConInRec->InputEvent = er;
-  ConInRec->Fake = AsciiChar && 
+  ConInRec->Fake = UnicodeChar &&
     (msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
      msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
   ConInRec->NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
@@ -1279,9 +1387,10 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
           VirtualKeyCode,
           (AsciiChar >= ' ') ? AsciiChar : '.',
           ShiftState);
-    
+
   if (! ConInRec->Fake || ! ConInRec->NotChar)
     {
+      /* FIXME - convert to ascii */
       ConioProcessChar(Console, ConInRec);
     }
   else
@@ -1290,8 +1399,8 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
     }
 }
 
-VOID
-Console_Api(DWORD RefreshEvent)
+DWORD STDCALL
+Console_Api (PVOID unused)
 {
   /* keep reading events from the keyboard and stuffing them into the current
      console's input queue */
@@ -1303,7 +1412,7 @@ Console_Api(DWORD RefreshEvent)
   PrivateCsrssRegisterPrimitive();
   /* This call turns on the input system in win32k */
   PrivateCsrssAcquireOrReleaseInputOwnership(FALSE);
-  
+
   while (TRUE)
     {
       GetMessageW(&msg, 0, 0, 0);
@@ -1318,6 +1427,7 @@ Console_Api(DWORD RefreshEvent)
     }
 
   PrivateCsrssAcquireOrReleaseInputOwnership(TRUE);
+  return 0;
 }
 
 CSR_API(CsrGetScreenBufferInfo)
@@ -1325,18 +1435,18 @@ CSR_API(CsrGetScreenBufferInfo)
   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);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
-  pInfo = &Reply->Data.ScreenBufferInfoReply.Info;
+  pInfo = &Request->Data.ScreenBufferInfoRequest.Info;
   pInfo->dwSize.X = Buff->MaxX;
   pInfo->dwSize.Y = Buff->MaxY;
   pInfo->dwCursorPosition.X = Buff->CurrentX - Buff->ShowX;
@@ -1350,9 +1460,9 @@ CSR_API(CsrGetScreenBufferInfo)
   pInfo->dwMaximumWindowSize.Y = Buff->MaxY;
   ConioUnlockScreenBuffer(Buff);
 
-  Reply->Status = STATUS_SUCCESS;
+  Request->Status = STATUS_SUCCESS;
 
-  return Reply->Status;
+  return Request->Status;
 }
 
 CSR_API(CsrSetCursor)
@@ -1361,17 +1471,18 @@ CSR_API(CsrSetCursor)
   PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
   LONG OldCursorX, OldCursorY;
-   
+  LONG NewCursorX, NewCursorY;
+
   DPRINT("CsrSetCursor\n");
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
@@ -1380,18 +1491,26 @@ CSR_API(CsrSetCursor)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
+  NewCursorX = Request->Data.SetCursorRequest.Position.X;
+  NewCursorY = Request->Data.SetCursorRequest.Position.Y;
+  if (NewCursorX < 0 || NewCursorX >= Buff->MaxX ||
+      NewCursorY < 0 || NewCursorY >= Buff->MaxY)
+    {
+      ConioUnlockScreenBuffer(Buff);
+      return Request->Status = STATUS_INVALID_PARAMETER;
+    }
   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;
+  Buff->CurrentX = NewCursorX + Buff->ShowX;
+  Buff->CurrentY = (NewCursorY + Buff->ShowY) % Buff->MaxY;
   if (NULL != Console && Buff == Console->ActiveBuffer)
     {
       if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
         {
           ConioUnlockScreenBuffer(Buff);
-          return Reply->Status = STATUS_UNSUCCESSFUL;
+          return Request->Status = STATUS_UNSUCCESSFUL;
         }
     }
 
@@ -1401,7 +1520,7 @@ CSR_API(CsrSetCursor)
       ConioUnlockConsole(Console);
     }
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 STATIC FASTCALL VOID
@@ -1434,81 +1553,106 @@ ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, COORD *Start
 CSR_API(CsrWriteConsoleOutputChar)
 {
   NTSTATUS Status;
-  PBYTE String = Request->Data.WriteConsoleOutputCharRequest.String;
+  PCHAR String, tmpString = NULL;
   PBYTE Buffer;
   PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
-  DWORD X, Y, Length;
+  DWORD X, Y, Length, CharSize, Written = 0;
   RECT UpdateRect;
 
   DPRINT("CsrWriteConsoleOutputChar\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
-                           sizeof(LPC_MESSAGE);
+  CharSize = (Request->Data.WriteConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
 
-  if (Request->Header.DataSize
-      < sizeof(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REQUEST) - 1
-        + Request->Data.WriteConsoleOutputCharRequest.Length)
+  if (Request->Header.u1.s1.TotalLength
+      < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) 
+        + (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize))
     {
       DPRINT1("Invalid request size\n");
-      return Reply->Status = STATUS_INVALID_PARAMETER;
+      Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+      Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+      return Request->Status = STATUS_INVALID_PARAMETER;
     }
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
-  if (! NT_SUCCESS(Status))
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+  if (NT_SUCCESS(Status))
     {
-      return 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)];
-  while (Length--)
-    {
-      *Buffer = *String++;
-      Buffer += 2;
-      if (++X == Buff->MaxX)
+      if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
         {
-          if (++Y == Buff->MaxY)
+          Length = WideCharToMultiByte(Console->CodePage, 0, 
+                                      (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, 
+                                       Request->Data.WriteConsoleOutputCharRequest.Length, 
+                                       NULL, 0, NULL, NULL);
+          tmpString = String = RtlAllocateHeap(GetProcessHeap(), 0, Length);
+          if (String)
             {
-              Y = 0;
-              Buffer = Buff->Buffer;
+              WideCharToMultiByte(Console->CodePage, 0, 
+                                  (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, 
+                                  Request->Data.WriteConsoleOutputCharRequest.Length, 
+                                  String, Length, NULL, NULL);
+            }
+          else
+            {
+              Status = STATUS_NO_MEMORY;
             }
-          X = 0;
         }
-    }
-
-  if (NULL != Console && Buff == Console->ActiveBuffer)
-    {
-      ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputCharRequest.Coord,
-                             Request->Data.WriteConsoleOutputCharRequest.Length);
-      ConioDrawRegion(Console, &UpdateRect);
-    }
+      else
+        {
+          String = (PCHAR)Request->Data.WriteConsoleOutputCharRequest.String;
+        }
+      
+      if (String)
+        {
+          Status = ConioLockScreenBuffer(ProcessData,
+                                         Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
+                                         &Buff);
+          if (NT_SUCCESS(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)];
+              while (Length--)
+                {
+                  *Buffer = *String++;
+                  Written++;
+                  Buffer += 2;
+                  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.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;
+                Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X - Buff->ShowX;
+                Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->ShowY) % Buff->MaxY;
 
-  ConioUnlockScreenBuffer(Buff);
-  if (NULL != Console)
-    {
-      ConioUnlockConsole(Console);
+                ConioUnlockScreenBuffer(Buff);
+            }
+          if (Request->Data.WriteConsoleRequest.Unicode)
+            {
+              RtlFreeHeap(GetProcessHeap(), 0, tmpString);
+            }
+        }
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
     }
-
-  return Reply->Status = STATUS_SUCCESS;
+  Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written;
+  return Request->Status = Status;
 }
 
 CSR_API(CsrFillOutputChar)
@@ -1516,20 +1660,20 @@ CSR_API(CsrFillOutputChar)
   NTSTATUS Status;
   PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
-  DWORD X, Y, Length;
-  BYTE Char;
+  DWORD X, Y, Length, Written = 0;
+  CHAR 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);
+
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff);
@@ -1539,18 +1683,22 @@ CSR_API(CsrFillOutputChar)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->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;
+  if(Request->Data.FillOutputRequest.Unicode)
+    ConsoleUnicodeCharToAnsiChar(Console, &Char, &Request->Data.FillOutputRequest.Char.UnicodeChar);
+  else
+    Char = Request->Data.FillOutputRequest.Char.AsciiChar;
   Length = Request->Data.FillOutputRequest.Length;
   while (Length--)
     {
       *Buffer = Char;
       Buffer += 2;
+      Written++;
       if (++X == Buff->MaxX)
         {
           if (++Y == Buff->MaxY)
@@ -1574,8 +1722,9 @@ CSR_API(CsrFillOutputChar)
     {
       ConioUnlockConsole(Console);
     }
-
-  return Reply->Status;
+  Length = Request->Data.FillOutputRequest.Length;
+  Request->Data.FillOutputRequest.NrCharactersWritten = Length;
+  return Request->Status;
 }
 
 CSR_API(CsrReadInputEvent)
@@ -1585,26 +1734,43 @@ CSR_API(CsrReadInputEvent)
   NTSTATUS Status;
   BOOLEAN Done = FALSE;
   ConsoleInput *Input;
-   
+
   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;
-   
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+  Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent;
+
   Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   /* only get input if there is any */
-  while (Console->InputEvents.Flink != &Console->InputEvents && ! Done)
+  CurrentEntry = Console->InputEvents.Flink;
+  while (CurrentEntry != &Console->InputEvents)
     {
-      CurrentEntry = RemoveHeadList(&Console->InputEvents);
       Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
-      Done = !Input->Fake;
-      Reply->Data.ReadInputReply.Input = Input->InputEvent;
+      CurrentEntry = CurrentEntry->Flink;
+
+      if (Done && !Input->Fake)
+        {
+         Request->Data.ReadInputRequest.MoreEvents = TRUE;
+         break;
+       }
+
+      RemoveEntryList(&Input->ListEntry);
+
+      if (!Done && !Input->Fake)
+        {
+          Request->Data.ReadInputRequest.Input = Input->InputEvent;
+          if (Request->Data.ReadInputRequest.Unicode == FALSE)
+            {
+              ConioInputEventToAnsi(Console, &Request->Data.ReadInputRequest.Input);
+            }
+         Done = TRUE;
+       }
 
       if (Input->InputEvent.EventType == KEY_EVENT)
         {
@@ -1617,50 +1783,57 @@ CSR_API(CsrReadInputEvent)
           Console->WaitingChars--;
         }
       HeapFree(Win32CsrApiHeap, 0, Input);
+    }
 
-      Reply->Data.ReadInputReply.MoreEvents = (Console->InputEvents.Flink != &Console->InputEvents);
+  if (Done)
+    {
       Status = STATUS_SUCCESS;
-      Console->EarlyReturn = FALSE; /* clear early return */
+      Console->EarlyReturn = FALSE;
     }
-   
-  if (! Done)
+  else
     {
       Status = STATUS_PENDING;
       Console->EarlyReturn = TRUE;  /* mark for early return */
     }
 
+  if (IsListEmpty(&Console->InputEvents))
+    {
+      ResetEvent(Console->ActiveEvent);
+    }
+
   ConioUnlockConsole(Console);
 
-  return Reply->Status = Status;
+  return Request->Status = Status;
 }
 
 CSR_API(CsrWriteConsoleOutputAttrib)
 {
   PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
-  PUCHAR Buffer, Attribute;
+  PUCHAR Buffer;
+  PWORD Attribute;
   int X, Y, Length;
   NTSTATUS Status;
   RECT UpdateRect;
 
   DPRINT("CsrWriteConsoleOutputAttrib\n");
-   
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
-                           sizeof(LPC_MESSAGE);
 
-  if (Request->Header.DataSize
-      < sizeof(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB_REQUEST) - 1
-        + Request->Data.WriteConsoleOutputAttribRequest.Length)
+  if (Request->Header.u1.s1.TotalLength
+      < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
+        + Request->Data.WriteConsoleOutputAttribRequest.Length * sizeof(WORD))
     {
       DPRINT1("Invalid request size\n");
-      return Reply->Status = STATUS_INVALID_PARAMETER;
+      Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+      Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+      return Request->Status = STATUS_INVALID_PARAMETER;
     }
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   Status = ConioLockScreenBuffer(ProcessData,
@@ -1672,17 +1845,17 @@ CSR_API(CsrWriteConsoleOutputAttrib)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->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;
+  Attribute = Request->Data.WriteConsoleOutputAttribRequest.Attribute;
   while (Length--)
     {
-      *Buffer = *Attribute++;
+      *Buffer = (UCHAR)(*Attribute++);
       Buffer += 2;
       if (++X == Buff->MaxX)
         {
@@ -1707,18 +1880,18 @@ CSR_API(CsrWriteConsoleOutputAttrib)
       ConioUnlockConsole(Console);
     }
 
-  Reply->Data.WriteConsoleOutputAttribReply.EndCoord.X = Buff->CurrentX - Buff->ShowX;
-  Reply->Data.WriteConsoleOutputAttribReply.EndCoord.Y = (Buff->CurrentY + Buff->MaxY - Buff->ShowY) % Buff->MaxY;
+  Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = Buff->CurrentX - Buff->ShowX;
+  Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Buff->CurrentY + Buff->MaxY - Buff->ShowY) % Buff->MaxY;
 
   ConioUnlockScreenBuffer(Buff);
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrFillOutputAttrib)
 {
   PCSRSS_SCREEN_BUFFER Buff;
-  PCHAR Buffer;
+  PUCHAR Buffer;
   NTSTATUS Status;
   int X, Y, Length;
   UCHAR Attr;
@@ -1730,11 +1903,11 @@ CSR_API(CsrFillOutputAttrib)
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
-   
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
     {
@@ -1742,7 +1915,7 @@ CSR_API(CsrFillOutputAttrib)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   X = Request->Data.FillOutputAttribRequest.Coord.X + Buff->ShowX;
@@ -1778,7 +1951,7 @@ CSR_API(CsrFillOutputAttrib)
       ConioUnlockConsole(Console);
     }
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 
@@ -1786,21 +1959,21 @@ CSR_API(CsrGetCursorInfo)
 {
   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);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
-  Reply->Data.GetCursorInfoReply.Info = Buff->CursorInfo;
+  Request->Data.GetCursorInfoRequest.Info = Buff->CursorInfo;
   ConioUnlockScreenBuffer(Buff);
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetCursorInfo)
@@ -1810,16 +1983,16 @@ CSR_API(CsrSetCursorInfo)
   DWORD Size;
   BOOL Visible;
   NTSTATUS Status;
-   
+
   DPRINT("CsrSetCursorInfo\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff);
@@ -1829,7 +2002,7 @@ CSR_API(CsrSetCursorInfo)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   Size = Request->Data.SetCursorInfoRequest.Info.dwSize;
@@ -1853,7 +2026,7 @@ CSR_API(CsrSetCursorInfo)
         {
           ConioUnlockScreenBuffer(Buff);
           ConioUnlockConsole(Console);
-          return Reply->Status = STATUS_UNSUCCESSFUL;
+          return Request->Status = STATUS_UNSUCCESSFUL;
         }
     }
 
@@ -1863,7 +2036,7 @@ CSR_API(CsrSetCursorInfo)
       ConioUnlockConsole(Console);
     }
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetTextAttrib)
@@ -1871,14 +2044,14 @@ CSR_API(CsrSetTextAttrib)
   NTSTATUS Status;
   PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
-  LONG OldCursorX, OldCursorY;   
+  LONG OldCursorX, OldCursorY;
 
   DPRINT("CsrSetTextAttrib\n");
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff);
@@ -1888,7 +2061,7 @@ CSR_API(CsrSetTextAttrib)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &OldCursorX, &OldCursorY);
@@ -1900,7 +2073,7 @@ CSR_API(CsrSetTextAttrib)
         {
           ConioUnlockScreenBuffer(Buff);
           ConioUnlockConsole(Console);
-          return Reply->Status = STATUS_UNSUCCESSFUL;
+          return Request->Status = STATUS_UNSUCCESSFUL;
         }
     }
 
@@ -1910,7 +2083,7 @@ CSR_API(CsrSetTextAttrib)
       ConioUnlockConsole(Console);
     }
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetConsoleMode)
@@ -1921,14 +2094,14 @@ CSR_API(CsrSetConsoleMode)
 
   DPRINT("CsrSetConsoleMode\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = Win32CsrGetObject(ProcessData,
                              Request->Data.SetConsoleModeRequest.ConsoleHandle,
                              (Object_t **) &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   Buff = (PCSRSS_SCREEN_BUFFER)Console;
@@ -1942,12 +2115,12 @@ CSR_API(CsrSetConsoleMode)
     }
   else
     {
-      return Reply->Status = STATUS_INVALID_HANDLE;
+      return Request->Status = STATUS_INVALID_HANDLE;
     }
 
-  Reply->Status = STATUS_SUCCESS;
+  Request->Status = STATUS_SUCCESS;
 
-  return Reply->Status;
+  return Request->Status;
 }
 
 CSR_API(CsrGetConsoleMode)
@@ -1958,30 +2131,30 @@ CSR_API(CsrGetConsoleMode)
 
   DPRINT("CsrGetConsoleMode\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = Win32CsrGetObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
                              (Object_t **) &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
-  Reply->Status = STATUS_SUCCESS;
+  Request->Status = STATUS_SUCCESS;
   Buff = (PCSRSS_SCREEN_BUFFER) Console;
   if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
     {
-      Reply->Data.GetConsoleModeReply.ConsoleMode = Console->Mode;
+      Request->Data.GetConsoleModeRequest.ConsoleMode = Console->Mode;
     }
   else if (CONIO_SCREEN_BUFFER_MAGIC == Buff->Header.Type)
     {
-      Reply->Data.GetConsoleModeReply.ConsoleMode = Buff->Mode;
+      Request->Data.GetConsoleModeRequest.ConsoleMode = Buff->Mode;
     }
   else
     {
-      Reply->Status = STATUS_INVALID_HANDLE;
+      Request->Status = STATUS_INVALID_HANDLE;
     }
 
-  return Reply->Status;
+  return Request->Status;
 }
 
 CSR_API(CsrCreateScreenBuffer)
@@ -1989,46 +2162,46 @@ CSR_API(CsrCreateScreenBuffer)
   PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
   NTSTATUS Status;
-   
+
   DPRINT("CsrCreateScreenBuffer\n");
 
   if (ProcessData == NULL)
     {
-      return Reply->Status = STATUS_INVALID_PARAMETER;
+      return Request->Status = STATUS_INVALID_PARAMETER;
     }
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
   if (NULL == Console)
     {
-      return Reply->Status = STATUS_INVALID_HANDLE;
+      return Request->Status = STATUS_INVALID_HANDLE;
     }
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Buff = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_SCREEN_BUFFER));
   if (NULL == Buff)
     {
-      Reply->Status = STATUS_INSUFFICIENT_RESOURCES;
+      Request->Status = STATUS_INSUFFICIENT_RESOURCES;
     }
 
   Status = CsrInitConsoleScreenBuffer(Console, Buff);
   if(! NT_SUCCESS(Status))
     {
-      Reply->Status = Status;
+      Request->Status = Status;
     }
   else
     {
-      Reply->Status = Win32CsrInsertObject(ProcessData, &Reply->Data.CreateScreenBufferReply.OutputHandle, &Buff->Header);
+      Request->Status = Win32CsrInsertObject(ProcessData, &Request->Data.CreateScreenBufferRequest.OutputHandle, &Buff->Header);
     }
 
   ConioUnlockConsole(Console);
 
-  return Reply->Status;
+  return Request->Status;
 }
 
 CSR_API(CsrSetScreenBuffer)
@@ -2042,22 +2215,22 @@ CSR_API(CsrSetScreenBuffer)
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
   if (NULL == Console)
     {
       DPRINT1("Trying to set screen buffer for app without console\n");
-      return Reply->Status = STATUS_INVALID_HANDLE;
+      return Request->Status = STATUS_INVALID_HANDLE;
     }
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff);
   if (! NT_SUCCESS(Status))
     {
       ConioUnlockConsole(Console);
-      return Reply->Status;
+      return Request->Status;
     }
 
   if (Buff == Console->ActiveBuffer)
@@ -2082,81 +2255,99 @@ CSR_API(CsrSetScreenBuffer)
   ConioUnlockScreenBuffer(Buff);
   ConioUnlockConsole(Console);
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetTitle)
 {
   NTSTATUS Status;
   PCSRSS_CONSOLE Console;
+  PWCHAR Buffer;
 
   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
+  if (Request->Header.u1.s1.TotalLength
+      < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE)
         + Request->Data.SetTitleRequest.Length)
     {
       DPRINT1("Invalid request size\n");
-      return Reply->Status = STATUS_INVALID_PARAMETER;
+      Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+      Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+      return Request->Status = STATUS_INVALID_PARAMETER;
     }
 
   Status = ConioLockConsole(ProcessData, Request->Data.SetTitleRequest.Console, &Console);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   if(! NT_SUCCESS(Status))
     {
-      Reply->Status = Status;  
+      Request->Status = Status;
     }
   else
     {
-      /* copy title to console */
-      RtlFreeUnicodeString(&Console->Title);
-      RtlCreateUnicodeString(&Console->Title, Request->Data.SetTitleRequest.Title);
-      if (! ConioChangeTitle(Console))
+      Buffer =  RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length);
+      if (Buffer)
         {
-          Reply->Status = STATUS_UNSUCCESSFUL;
+          /* copy title to console */
+          RtlFreeUnicodeString(&Console->Title);
+          Console->Title.Buffer = Buffer;
+          Console->Title.Length = Console->Title.MaximumLength = Request->Data.SetTitleRequest.Length;
+          memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length);
+          if (! ConioChangeTitle(Console))
+            {
+              Request->Status = STATUS_UNSUCCESSFUL;
+            }
+          else
+            {
+              Request->Status = STATUS_SUCCESS;
+            }
         }
       else
         {
-          Reply->Status = STATUS_SUCCESS;
+          Request->Status = STATUS_NO_MEMORY;
         }
     }
   ConioUnlockConsole(Console);
 
-  return Reply->Status;
+  return Request->Status;
 }
 
 CSR_API(CsrGetTitle)
 {
   NTSTATUS Status;
   PCSRSS_CONSOLE Console;
-  
+  DWORD Length;
+
   DPRINT("CsrGetTitle\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = ConioLockConsole(ProcessData,
                             Request->Data.GetTitleRequest.ConsoleHandle,
                             &Console);
   if (! NT_SUCCESS(Status))
     {
       DPRINT1("Can't get console\n");
-      return Reply->Status = Status;
+      return Request->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;
+  RtlZeroMemory(&Request->Data.GetTitleRequest, sizeof(CSRSS_GET_TITLE));
+  Request->Data.GetTitleRequest.ConsoleHandle = Request->Data.GetTitleRequest.ConsoleHandle;
+  Request->Data.GetTitleRequest.Length = Console->Title.Length;
+  wcscpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer);
+  Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + Console->Title.Length;
 
   ConioUnlockConsole(Console);
 
-  return Reply->Status;
+  if (Length > sizeof(CSR_API_MESSAGE))
+    {
+      Request->Header.u1.s1.TotalLength = Length;
+      Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE);
+    }
+  Request->Status = STATUS_SUCCESS;
+
+  return Request->Status;
 }
 
 CSR_API(CsrWriteConsoleOutput)
@@ -2179,11 +2370,11 @@ CSR_API(CsrWriteConsoleOutput)
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = ConioLockScreenBuffer(ProcessData,
                                  Request->Data.WriteConsoleOutputRequest.ConsoleHandle,
                                  &Buff);
@@ -2193,7 +2384,7 @@ CSR_API(CsrWriteConsoleOutput)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize;
@@ -2201,20 +2392,20 @@ CSR_API(CsrWriteConsoleOutput)
   BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord;
   CharInfo = Request->Data.WriteConsoleOutputRequest.CharInfo;
   if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) ||
-      (((PVOID)CharInfo + PSize) > 
-       (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
+      (((ULONG_PTR)CharInfo + PSize) >
+       ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
     {
       ConioUnlockScreenBuffer(Buff);
       ConioUnlockConsole(Console);
-      return Reply->Status = STATUS_ACCESS_VIOLATION;
+      return Request->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;
 
-  SizeY = RtlRosMin(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion));
-  SizeX = RtlRosMin(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion));
+  SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion));
+  SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion));
   WriteRegion.bottom = WriteRegion.top + SizeY - 1;
   WriteRegion.right = WriteRegion.left + SizeX - 1;
 
@@ -2227,7 +2418,7 @@ CSR_API(CsrWriteConsoleOutput)
 
       /* It is okay to have a WriteRegion completely outside the screen buffer.
          No data is written then. */
-      return Reply->Status = STATUS_SUCCESS;
+      return Request->Status = STATUS_SUCCESS;
     }
 
   for (i = 0, Y = WriteRegion.top; Y <= WriteRegion.bottom; i++, Y++)
@@ -2236,7 +2427,16 @@ CSR_API(CsrWriteConsoleOutput)
       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);
+          if (Request->Data.WriteConsoleOutputRequest.Unicode)
+            {
+              CHAR AsciiChar;
+              ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar);
+              SET_CELL_BUFFER(Buff, Offset, AsciiChar, CurCharInfo->Attributes);
+            }
+          else
+            {
+              SET_CELL_BUFFER(Buff, Offset, CurCharInfo->Char.AsciiChar, CurCharInfo->Attributes);
+            }
           CurCharInfo++;
         }
     }
@@ -2249,12 +2449,12 @@ CSR_API(CsrWriteConsoleOutput)
   ConioUnlockScreenBuffer(Buff);
   ConioUnlockConsole(Console);
 
-  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;
+  Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.left + SizeX - 1;
+  Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.top + SizeY - 1;
+  Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.left;
+  Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.top;
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrFlushInputBuffer)
@@ -2266,14 +2466,14 @@ CSR_API(CsrFlushInputBuffer)
 
   DPRINT("CsrFlushInputBuffer\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = ConioLockConsole(ProcessData,
                             Request->Data.FlushInputBufferRequest.ConsoleInput,
                             &Console);
   if(! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   /* Discard all entries in the input event queue */
@@ -2284,11 +2484,12 @@ CSR_API(CsrFlushInputBuffer)
       /* Destroy the event */
       HeapFree(Win32CsrApiHeap, 0, Input);
     }
+  ResetEvent(Console->ActiveEvent);
   Console->WaitingChars=0;
 
   ConioUnlockConsole(Console);
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrScrollConsoleScreenBuffer)
@@ -2314,11 +2515,11 @@ CSR_API(CsrScrollConsoleScreenBuffer)
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
     {
@@ -2326,7 +2527,7 @@ CSR_API(CsrScrollConsoleScreenBuffer)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   ScrollRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Left;
@@ -2343,13 +2544,13 @@ CSR_API(CsrScrollConsoleScreenBuffer)
   if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle))
     {
       ConioUnlockScreenBuffer(Buff);
-      return Reply->Status = STATUS_INVALID_PARAMETER;
+      return Request->Status = STATUS_INVALID_PARAMETER;
     }
 
   if (UseClipRectangle && ! ConioGetIntersection(&SrcRegion, &SrcRegion, &ClipRectangle))
     {
       ConioUnlockScreenBuffer(Buff);
-      return Reply->Status = STATUS_SUCCESS;
+      return Request->Status = STATUS_SUCCESS;
     }
 
 
@@ -2363,7 +2564,7 @@ CSR_API(CsrScrollConsoleScreenBuffer)
   if (! ConioGetIntersection(&DstRegion, &DstRegion, &ScreenBuffer))
     {
       ConioUnlockScreenBuffer(Buff);
-      return Reply->Status = STATUS_INVALID_PARAMETER;
+      return Request->Status = STATUS_INVALID_PARAMETER;
     }
 
   ConioCopyRegion(Buff, &SrcRegion, &DstRegion);
@@ -2379,7 +2580,7 @@ CSR_API(CsrScrollConsoleScreenBuffer)
       /* FIXME: The subtracted rectangle is off by one line */
       FillRegion.top += 1;
 
-      ConioFillRegion(Buff, &FillRegion, Fill);
+      ConioFillRegion(Console, Buff, &FillRegion, &Fill, Request->Data.ScrollConsoleScreenBufferRequest.Unicode);
       DoFill = TRUE;
     }
 
@@ -2401,27 +2602,38 @@ CSR_API(CsrScrollConsoleScreenBuffer)
       ConioUnlockConsole(Console);
     }
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrReadConsoleOutputChar)
 {
   NTSTATUS Status;
+  PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
   DWORD Xpos, Ypos;
-  BYTE* ReadBuffer;
+  PCHAR ReadBuffer;
   DWORD i;
+  ULONG CharSize;
+  CHAR Char;
 
   DPRINT("CsrReadConsoleOutputChar\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = Reply->Header.MessageSize - sizeof(LPC_MESSAGE);
-  ReadBuffer = Reply->Data.ReadConsoleOutputCharReply.String;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
+  ReadBuffer = Request->Data.ReadConsoleOutputCharRequest.String;
+
+  CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
+
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Request->Status = Status;
+    }
 
-  Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, Buff);
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X + Buff->ShowX;
@@ -2429,9 +2641,16 @@ CSR_API(CsrReadConsoleOutputChar)
 
   for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i)
     {
-      *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)];
+      Char = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)];
+
+      if(Request->Data.ReadConsoleOutputCharRequest.Unicode)
+      {
+        ConsoleAnsiCharToUnicodeChar(Console, (WCHAR*)ReadBuffer, &Char);
+        ReadBuffer += sizeof(WCHAR);
+      }
+      else
+        *(ReadBuffer++) = Char;
 
-      ReadBuffer++;
       Xpos++;
 
       if (Xpos == Buff->MaxX)
@@ -2447,15 +2666,24 @@ CSR_API(CsrReadConsoleOutputChar)
     }
 
   *ReadBuffer = 0;
-  Reply->Status = STATUS_SUCCESS;
-  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;
+  Request->Status = STATUS_SUCCESS;
+  Request->Data.ReadConsoleOutputCharRequest.EndCoord.X = Xpos - Buff->ShowX;
+  Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->ShowY + Buff->MaxY) % Buff->MaxY;
 
   ConioUnlockScreenBuffer(Buff);
+  if (NULL != Console)
+    {
+      ConioUnlockConsole(Console);
+    }
 
-  return Reply->Status;
+  Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize;
+  if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE))
+    {
+      Request->Header.u1.s1.TotalLength = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR);
+      Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
+    }
+
+  return Request->Status;
 }
 
 
@@ -2464,19 +2692,20 @@ CSR_API(CsrReadConsoleOutputAttrib)
   NTSTATUS Status;
   PCSRSS_SCREEN_BUFFER Buff;
   DWORD Xpos, Ypos;
-  CHAR* ReadBuffer;
+  PWORD ReadBuffer;
   DWORD i;
+  DWORD CurrentLength;
 
   DPRINT("CsrReadConsoleOutputAttrib\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = Reply->Header.MessageSize - sizeof(LPC_MESSAGE);
-  ReadBuffer = Reply->Data.ReadConsoleOutputAttribReply.String;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
+  ReadBuffer = Request->Data.ReadConsoleOutputAttribRequest.Attribute;
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X + Buff->ShowX;
@@ -2503,15 +2732,21 @@ CSR_API(CsrReadConsoleOutputAttrib)
 
   *ReadBuffer = 0;
 
-  Reply->Status = STATUS_SUCCESS;
-  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;
+  Request->Status = STATUS_SUCCESS;
+  Request->Data.ReadConsoleOutputAttribRequest.EndCoord.X = Xpos - Buff->ShowX;
+  Request->Data.ReadConsoleOutputAttribRequest.EndCoord.Y = (Ypos - Buff->ShowY + Buff->MaxY) % Buff->MaxY;
 
   ConioUnlockScreenBuffer(Buff);
 
-  return Reply->Status;
+  CurrentLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
+                     + Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead * sizeof(WORD);
+  if (CurrentLength > sizeof(CSR_API_MESSAGE))
+    {
+      Request->Header.u1.s1.TotalLength = CurrentLength;
+      Request->Header.u1.s1.DataLength = CurrentLength - sizeof(PORT_MESSAGE);
+    }
+
+  return Request->Status;
 }
 
 
@@ -2521,38 +2756,39 @@ CSR_API(CsrGetNumberOfConsoleInputEvents)
   PCSRSS_CONSOLE Console;
   PLIST_ENTRY CurrentItem;
   DWORD NumEvents;
-  
+  ConsoleInput *Input;
+
   DPRINT("CsrGetNumberOfConsoleInputEvents\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = Reply->Header.MessageSize - sizeof(LPC_MESSAGE);
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
 
   Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
-  
-  CurrentItem = &Console->InputEvents;
+
+  CurrentItem = Console->InputEvents.Flink;
   NumEvents = 0;
-  
+
   /* If there are any events ... */
-  if (CurrentItem->Flink != CurrentItem)
+  while (CurrentItem != &Console->InputEvents)
     {
-      do
+      Input = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry);
+      CurrentItem = CurrentItem->Flink;
+      if (!Input->Fake)
         {
-          CurrentItem = CurrentItem->Flink;
-          ++NumEvents;
-        }
-      while (CurrentItem != &Console->InputEvents);
+          NumEvents++;
+       }
     }
 
   ConioUnlockConsole(Console);
-  
-  Reply->Status = STATUS_SUCCESS;
-  Reply->Data.GetNumInputEventsReply.NumInputEvents = NumEvents;
-   
-  return Reply->Status;
+
+  Request->Status = STATUS_SUCCESS;
+  Request->Data.GetNumInputEventsRequest.NumInputEvents = NumEvents;
+
+  return Request->Status;
 }
 
 
@@ -2566,59 +2802,65 @@ CSR_API(CsrPeekConsoleInput)
   PINPUT_RECORD InputRecord;
   ConsoleInput* Item;
   UINT NumItems;
-   
+
   DPRINT("CsrPeekConsoleInput\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-   
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
   Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console);
   if(! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
-   
+
   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)))
+      || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
     {
       ConioUnlockConsole(Console);
-      Reply->Status = STATUS_ACCESS_VIOLATION;
-      return Reply->Status ;
+      Request->Status = STATUS_ACCESS_VIOLATION;
+      return Request->Status ;
     }
-   
+
   NumItems = 0;
-   
+
   if (! IsListEmpty(&Console->InputEvents))
     {
-      CurrentItem = &Console->InputEvents;
-   
-      while (NumItems < Length)
+      CurrentItem = Console->InputEvents.Flink;
+
+      while (CurrentItem != &Console->InputEvents && NumItems < Length)
         {
-          ++NumItems;
           Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry);
-          *InputRecord++ = Item->InputEvent;
-         
-          if (CurrentItem->Flink == &Console->InputEvents)
+
+          if (Item->Fake)
             {
-              break;
+              CurrentItem = CurrentItem->Flink;
+              continue;
             }
-          else
+
+          ++NumItems;
+          *InputRecord = Item->InputEvent;
+
+          if (Request->Data.ReadInputRequest.Unicode == FALSE)
             {
-              CurrentItem = CurrentItem->Flink;
+              ConioInputEventToAnsi(Console, InputRecord);
             }
+
+          InputRecord++;
+          CurrentItem = CurrentItem->Flink;
         }
     }
 
   ConioUnlockConsole(Console);
 
-  Reply->Status = STATUS_SUCCESS;
-  Reply->Data.PeekConsoleInputReply.Length = NumItems;
+  Request->Status = STATUS_SUCCESS;
+  Request->Data.PeekConsoleInputRequest.Length = NumItems;
 
-  return Reply->Status;
+  return Request->Status;
 }
 
 
@@ -2635,19 +2877,21 @@ CSR_API(CsrReadConsoleOutput)
   COORD BufferCoord;
   RECT ReadRegion;
   RECT ScreenRect;
-  DWORD i, Y, X, Offset;
-      
+  DWORD i, Offset;
+  LONG X, Y;
+  UINT CodePage;
+
   DPRINT("CsrReadConsoleOutput\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-  
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
-   
+
   CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo;
   ReadRegion.left = Request->Data.ReadConsoleOutputRequest.ReadRegion.Left;
   ReadRegion.top = Request->Data.ReadConsoleOutputRequest.ReadRegion.Top;
@@ -2657,17 +2901,20 @@ CSR_API(CsrReadConsoleOutput)
   BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord;
   Length = BufferSize.X * BufferSize.Y;
   Size = Length * sizeof(CHAR_INFO);
-   
+
+  /* FIXME: Is this correct? */
+  CodePage = ProcessData->Console->OutputCodePage;
+
   if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase)
-      || (((PVOID)CharInfo + Size) > (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
+      || (((ULONG_PTR)CharInfo + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
     {
       ConioUnlockScreenBuffer(Buff);
-      Reply->Status = STATUS_ACCESS_VIOLATION;
-      return Reply->Status ;
+      Request->Status = STATUS_ACCESS_VIOLATION;
+      return Request->Status ;
     }
-   
-  SizeY = RtlRosMin(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion));
-  SizeX = RtlRosMin(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion));
+
+  SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion));
+  SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion));
   ReadRegion.bottom = ReadRegion.top + SizeY;
   ReadRegion.right = ReadRegion.left + SizeX;
 
@@ -2675,32 +2922,41 @@ CSR_API(CsrReadConsoleOutput)
   if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion))
     {
       ConioUnlockScreenBuffer(Buff);
-      Reply->Status = STATUS_SUCCESS;
-      return Reply->Status;
+      Request->Status = STATUS_SUCCESS;
+      return Request->Status;
     }
 
   for (i = 0, Y = ReadRegion.top; Y < ReadRegion.bottom; ++i, ++Y)
     {
       CurCharInfo = CharInfo + (i * BufferSize.X);
-     
+
       Offset = (((Y + Buff->ShowY) % Buff->MaxY) * Buff->MaxX + ReadRegion.left) * 2;
       for (X = ReadRegion.left; X < ReadRegion.right; ++X)
         {
-          CurCharInfo->Char.AsciiChar = GET_CELL_BUFFER(Buff, Offset);
+          if (Request->Data.ReadConsoleOutputRequest.Unicode)
+            {
+              MultiByteToWideChar(CodePage, 0,
+                                  (PCHAR)&GET_CELL_BUFFER(Buff, Offset), 1,
+                                  &CurCharInfo->Char.UnicodeChar, 1);
+            }
+          else
+            {
+              CurCharInfo->Char.AsciiChar = GET_CELL_BUFFER(Buff, Offset);
+            }
           CurCharInfo->Attributes = GET_CELL_BUFFER(Buff, Offset);
           ++CurCharInfo;
         }
     }
 
   ConioUnlockScreenBuffer(Buff);
-  
-  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;
+
+  Request->Status = STATUS_SUCCESS;
+  Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.left + SizeX - 1;
+  Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.top + SizeY - 1;
+  Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.left;
+  Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.top;
+
+  return Request->Status;
 }
 
 
@@ -2713,38 +2969,38 @@ CSR_API(CsrWriteConsoleInput)
   DWORD Size;
   DWORD i;
   ConsoleInput* Record;
-   
+
   DPRINT("CsrWriteConsoleInput\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-   
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
   Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
-   
+
   InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord;
   Length = Request->Data.WriteConsoleInputRequest.Length;
   Size = Length * sizeof(INPUT_RECORD);
-   
+
   if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase)
-      || (((PVOID)InputRecord + Size) > (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
+      || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
     {
       ConioUnlockConsole(Console);
-      Reply->Status = STATUS_ACCESS_VIOLATION;
-      return Reply->Status ;
+      Request->Status = STATUS_ACCESS_VIOLATION;
+      return Request->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;
+          Request->Status = STATUS_INSUFFICIENT_RESOURCES;
+          return Request->Status;
         }
 
       Record->Echoed = FALSE;
@@ -2752,16 +3008,17 @@ CSR_API(CsrWriteConsoleInput)
       Record->InputEvent = *InputRecord++;
       if (KEY_EVENT == Record->InputEvent.EventType)
         {
+          /* FIXME - convert from unicode to ascii!! */
           ConioProcessChar(Console, Record);
         }
     }
 
   ConioUnlockConsole(Console);
-   
-  Reply->Status = STATUS_SUCCESS;
-  Reply->Data.WriteConsoleInputReply.Length = i;
 
-  return Reply->Status;
+  Request->Status = STATUS_SUCCESS;
+  Request->Data.WriteConsoleInputRequest.Length = i;
+
+  return Request->Status;
 }
 
 /**********************************************************************
@@ -2773,7 +3030,7 @@ CSR_API(CsrWriteConsoleInput)
  *             output.
  *     ARGUMENTS
  *             Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
- *             object. We use the same object to reply.
+ *             object. We use the same object to Request.
  *     NOTE
  *             ConsoleHwState has the correct size to be compatible
  *             with NT's, but values are not.
@@ -2793,7 +3050,7 @@ SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
           Console->HardwareState = ConsoleHwState;
         }
 
-      return STATUS_SUCCESS;   
+      return STATUS_SUCCESS;
     }
 
   return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */
@@ -2803,40 +3060,40 @@ CSR_API(CsrHardwareStateProperty)
 {
   PCSRSS_CONSOLE Console;
   NTSTATUS Status;
+
   DPRINT("CsrHardwareStateProperty\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-   
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
   Status = ConioLockConsole(ProcessData,
                             Request->Data.ConsoleHardwareStateRequest.ConsoleHandle,
                             &Console);
   if (! NT_SUCCESS(Status))
     {
       DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   switch (Request->Data.ConsoleHardwareStateRequest.SetGet)
     {
       case CONSOLE_HARDWARE_STATE_GET:
-        Reply->Data.ConsoleHardwareStateReply.State = Console->HardwareState;
+        Request->Data.ConsoleHardwareStateRequest.State = Console->HardwareState;
         break;
-      
+
       case CONSOLE_HARDWARE_STATE_SET:
         DPRINT("Setting console hardware state.\n");
-        Reply->Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State);
+        Request->Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State);
         break;
 
       default:
-        Reply->Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */
+        Request->Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */
         break;
     }
 
   ConioUnlockConsole(Console);
 
-  return Reply->Status;
+  return Request->Status;
 }
 
 CSR_API(CsrGetConsoleWindow)
@@ -2845,22 +3102,186 @@ CSR_API(CsrGetConsoleWindow)
   NTSTATUS Status;
 
   DPRINT("CsrGetConsoleWindow\n");
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
-   
-  Status = ConioLockConsole(ProcessData,
-                            Request->Data.ConsoleWindowRequest.ConsoleHandle,
-                            &Console);
+
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
-  Reply->Data.ConsoleWindowReply.WindowHandle = Console->hWindow;
+  Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow;
   ConioUnlockConsole(Console);
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
+}
+
+CSR_API(CsrSetConsoleIcon)
+{
+  PCSRSS_CONSOLE Console;
+  NTSTATUS Status;
+
+  DPRINT("CsrSetConsoleIcon\n");
+
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Request->Status = Status;
+    }
+
+  Console->hWindowIcon = Request->Data.SetConsoleIconRequest.WindowIcon;
+  Request->Status = (ConioChangeIcon(Console) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
+  ConioUnlockConsole(Console);
+
+  return Request->Status;
+}
+
+CSR_API(CsrGetConsoleCodePage)
+{
+  PCSRSS_CONSOLE Console;
+  NTSTATUS Status;
+
+  DPRINT("CsrGetConsoleCodePage\n");
+
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Request->Status = Status;
+    }
+
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+  Request->Data.GetConsoleCodePage.CodePage = Console->CodePage;
+  ConioUnlockConsole(Console);
+  return Request->Status = STATUS_SUCCESS;
+}
+
+CSR_API(CsrSetConsoleCodePage)
+{
+  PCSRSS_CONSOLE Console;
+  NTSTATUS Status;
+
+  DPRINT("CsrSetConsoleCodePage\n");
+
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Request->Status = Status;
+    }
+
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+  if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage))
+    {
+      Console->CodePage = Request->Data.SetConsoleCodePage.CodePage;
+      ConioUnlockConsole(Console);
+      return Request->Status = STATUS_SUCCESS;
+    }
+  ConioUnlockConsole(Console);
+  return Request->Status = STATUS_UNSUCCESSFUL;
+}
+
+CSR_API(CsrGetConsoleOutputCodePage)
+{
+  PCSRSS_CONSOLE Console;
+  NTSTATUS Status;
+
+  DPRINT("CsrGetConsoleOutputCodePage\n");
+
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Request->Status = Status;
+    }
+
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+  Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage;
+  ConioUnlockConsole(Console);
+  return Request->Status = STATUS_SUCCESS;
+}
+
+CSR_API(CsrSetConsoleOutputCodePage)
+{
+  PCSRSS_CONSOLE Console;
+  NTSTATUS Status;
+
+  DPRINT("CsrSetConsoleOutputCodePage\n");
+
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Request->Status = Status;
+    }
+
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+  if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage))
+    {
+      Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage;
+      ConioUnlockConsole(Console);
+      return Request->Status = STATUS_SUCCESS;
+    }
+  ConioUnlockConsole(Console);
+  return Request->Status = STATUS_UNSUCCESSFUL;
+}
+
+CSR_API(CsrGetProcessList)
+{
+  PHANDLE Buffer;
+  PCSRSS_CONSOLE Console;
+  PCSRSS_PROCESS_DATA current;
+  PLIST_ENTRY current_entry;
+  ULONG nItems, nCopied, Length;
+  NTSTATUS Status;
+
+  DPRINT("CsrGetProcessList\n");
+
+  Buffer = Request->Data.GetProcessListRequest.ProcessId;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
+  nItems = nCopied = 0;
+  Request->Data.GetProcessListRequest.nProcessIdsCopied = 0;
+  Request->Data.GetProcessListRequest.nProcessIdsTotal = 0;
+
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+  {
+    return Request->Status = Status;
+  }
+
+  DPRINT1("Console_Api Ctrl-C\n");
+
+  for(current_entry = Console->ProcessList.Flink;
+      current_entry != &Console->ProcessList;
+      current_entry = current_entry->Flink)
+  {
+    current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
+    if(nItems++ < Request->Data.GetProcessListRequest.nMaxIds)
+    {
+      *(Buffer++) = current->ProcessId;
+      nCopied++;
+    }
+  }
+
+  ConioUnlockConsole(Console);
+
+  Request->Data.GetProcessListRequest.nProcessIdsCopied = nCopied;
+  Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems;
+
+  Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST) + nCopied * sizeof(HANDLE);
+  if (Length > sizeof(CSR_API_MESSAGE))
+  {
+     Request->Header.u1.s1.TotalLength = Length;
+     Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE);
+  }
+  return Request->Status = STATUS_SUCCESS;
 }
 
 /* EOF */