- Don't use STATIC
[reactos.git] / reactos / subsys / csrss / win32csr / conio.c
index d6b697f..b2cc24f 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: conio.c,v 1.14 2004/08/25 10:37:14 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,9 +31,16 @@ 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
+static NTSTATUS FASTCALL
 ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console)
 {
   if (NULL == ProcessData->Console)
@@ -63,35 +55,25 @@ 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",        ProcessData->ProcessId);
+  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);
     }
 }
 
@@ -107,7 +89,7 @@ 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 */
@@ -115,7 +97,7 @@ ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff)
     }
 }
 
-STATIC NTSTATUS FASTCALL
+static NTSTATUS FASTCALL
 CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
                            PCSRSS_SCREEN_BUFFER Buffer)
 {
@@ -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++)
@@ -146,7 +128,7 @@ CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
   return STATUS_SUCCESS;
 }
 
-STATIC NTSTATUS STDCALL
+static NTSTATUS STDCALL
 CsrInitConsole(PCSRSS_CONSOLE Console)
 {
   NTSTATUS Status;
@@ -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;
@@ -177,14 +159,14 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
   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;
-  RtlInitializeCriticalSection(&Console->Header.Lock);
+  InitializeCriticalSection(&Console->Header.Lock);
   GuiMode = DtbgIsDesktopVisible();
   if (! GuiMode)
     {
@@ -201,7 +183,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
       if (! NT_SUCCESS(Status))
         {
           RtlFreeUnicodeString(&Console->Title);
-         RtlDeleteCriticalSection(&Console->Header.Lock);
+         DeleteCriticalSection(&Console->Header.Lock);
           CloseHandle(Console->ActiveEvent);
           return Status;
         }
@@ -210,23 +192,25 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
   NewBuffer = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_SCREEN_BUFFER));
   if (NULL == NewBuffer)
     {
+      ConioCleanupConsole(Console);
       RtlFreeUnicodeString(&Console->Title);
-      RtlDeleteCriticalSection(&Console->Header.Lock);
+      DeleteCriticalSection(&Console->Header.Lock);
       CloseHandle(Console->ActiveEvent);
       return STATUS_INSUFFICIENT_RESOURCES;
     }
   Status = CsrInitConsoleScreenBuffer(Console, NewBuffer);
   if (! NT_SUCCESS(Status))
     {
+      ConioCleanupConsole(Console);
       RtlFreeUnicodeString(&Console->Title);
-      RtlDeleteCriticalSection(&Console->Header.Lock);
+      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);
@@ -237,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) - LPC_MESSAGE_BASE_SIZE;
+    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)
@@ -328,30 +358,29 @@ CSR_API(CsrFreeConsole)
 
   DPRINT("CsrFreeConsole\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
+  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;
 }
 
-STATIC VOID FASTCALL
+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)
         {
@@ -366,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)
         {
@@ -376,11 +405,11 @@ ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines)
   UpdateRect->bottom = Buff->CurrentY;
 }
 
-STATIC NTSTATUS FASTCALL
+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;
@@ -422,8 +451,8 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
                         {
                           Buff->CurrentY--;
                         }
-                      if ((0 == UpdateRect.top && UpdateRect.bottom < Buff->CurrentY)
-                          || (0 != UpdateRect.top && Buff->CurrentY < UpdateRect.top))
+                      if ((0 == UpdateRect.top && UpdateRect.bottom < (LONG)Buff->CurrentY)
+                          || (0 != UpdateRect.top && (LONG)Buff->CurrentY < UpdateRect.top))
                         {
                           UpdateRect.top = Buff->CurrentY;
                         }
@@ -434,8 +463,8 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
                     }
                   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);
+                  UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX);
+                  UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
                 }
                 continue;
             }
@@ -443,8 +472,8 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
           else if (Buffer[i] == '\r')
             {
               Buff->CurrentX = 0;
-              UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
-              UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX);
+              UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX);
+              UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
               continue;
             }
           /* --- TAB --- */
@@ -452,7 +481,7 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
             {
               UINT EndX;
 
-              UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
+              UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX);
               EndX = (Buff->CurrentX + 8) & ~7;
               if (EndX > Buff->MaxX)
                 {
@@ -465,7 +494,7 @@ 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)
                 {
                   if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
@@ -481,8 +510,8 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
               continue;
             }
         }
-      UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
-      UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX);
+      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)
@@ -521,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 - LPC_MESSAGE_BASE_SIZE;
+  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)
@@ -561,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)
                 {
@@ -569,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--;
@@ -582,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)
@@ -600,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;
     }
@@ -630,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
@@ -680,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;
 }
@@ -712,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;
@@ -768,7 +816,7 @@ inline BOOLEAN ConioSubtractRect(
   return TRUE;
 }
 
-STATIC VOID FASTCALL
+static VOID FASTCALL
 ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
                 RECT *SrcRegion,
                 RECT *DstRegion)
@@ -777,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;
@@ -786,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(
@@ -816,15 +864,23 @@ ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
     }
 }
 
-STATIC VOID FASTCALL
-ConioFillRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
+static VOID FASTCALL
+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;
@@ -834,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)
         {
@@ -848,69 +904,107 @@ ConioFillRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
     }
 }
 
-STATIC VOID FASTCALL
+static VOID FASTCALL
 ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent)
 {
   if (InputEvent->EventType == KEY_EVENT)
     {
-      WideCharToMultiByte(Console->CodePage, 0,
-                          &InputEvent->Event.KeyEvent.uChar.UnicodeChar, 1,
-                          &InputEvent->Event.KeyEvent.uChar.AsciiChar, 1,
-                          NULL, NULL);
+      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) - LPC_MESSAGE_BASE_SIZE;
 
-  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);
 }
@@ -943,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);
     }
@@ -952,7 +1046,7 @@ ConioDeleteConsole(Object_t *Object)
   ConioCleanupConsole(Console);
 
   CloseHandle(Console->ActiveEvent);
-  RtlDeleteCriticalSection(&Console->Header.Lock);
+  DeleteCriticalSection(&Console->Header.Lock);
   RtlFreeUnicodeString(&Console->Title);
   HeapFree(Win32CsrApiHeap, 0, Console);
 }
@@ -965,9 +1059,9 @@ CsrInitConsoleSupport(VOID)
   /* Should call LoadKeyboardLayout */
 }
 
-STATIC VOID FASTCALL
+static VOID FASTCALL
 ConioProcessChar(PCSRSS_CONSOLE Console,
-                            ConsoleInput *KeyEventRecord)
+                 ConsoleInput *KeyEventRecord)
 {
   BOOL updown;
   BOOL bClientWake = FALSE;
@@ -976,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)))
     {
@@ -988,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;
@@ -1022,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)
                     {
@@ -1081,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)
         {
@@ -1114,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);
@@ -1150,7 +1244,7 @@ ConioProcessChar(PCSRSS_CONSOLE Console,
     }
 }
 
-STATIC DWORD FASTCALL
+static DWORD FASTCALL
 ConioGetShiftState(PBYTE KeyState)
 {
   DWORD ssOut = 0;
@@ -1201,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);
@@ -1211,9 +1305,9 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
     {
       VirtualKeyCode = LastVirtualKey;
       UnicodeChar = msg->wParam;
-    } 
+    }
   else
-    { 
+    {
       WCHAR Chars[2];
       INT RetChars = 0;
 
@@ -1232,7 +1326,7 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
     {
       AsciiChar = 0;
     }
-  
+
   er.EventType = KEY_EVENT;
   er.Event.KeyEvent.bKeyDown = Down;
   er.Event.KeyEvent.wRepeatCount = RepeatCount;
@@ -1242,7 +1336,7 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
   er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
 
   if (TextMode)
-    {    
+    {
       if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
           && VK_TAB == VirtualKeyCode)
         {
@@ -1262,7 +1356,7 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
         }
     }
 
-  if (NULL == Console) 
+  if (NULL == Console)
     {
       return;
     }
@@ -1273,9 +1367,9 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
     {
       return;
     }
-    
+
   ConInRec->InputEvent = er;
-  ConInRec->Fake = UnicodeChar && 
+  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);
@@ -1293,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
@@ -1304,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 */
@@ -1317,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);
@@ -1332,6 +1427,7 @@ Console_Api(DWORD RefreshEvent)
     }
 
   PrivateCsrssAcquireOrReleaseInputOwnership(TRUE);
+  return 0;
 }
 
 CSR_API(CsrGetScreenBufferInfo)
@@ -1339,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) - LPC_MESSAGE_BASE_SIZE;
+  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;
@@ -1364,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)
@@ -1376,17 +1472,17 @@ CSR_API(CsrSetCursor)
   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) - LPC_MESSAGE_BASE_SIZE;
+  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))
@@ -1395,7 +1491,7 @@ CSR_API(CsrSetCursor)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   NewCursorX = Request->Data.SetCursorRequest.Position.X;
@@ -1404,7 +1500,11 @@ CSR_API(CsrSetCursor)
       NewCursorY < 0 || NewCursorY >= Buff->MaxY)
     {
       ConioUnlockScreenBuffer(Buff);
-      return Reply->Status = STATUS_INVALID_PARAMETER;
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
+      return Request->Status = STATUS_INVALID_PARAMETER;
     }
   ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &OldCursorX, &OldCursorY);
   Buff->CurrentX = NewCursorX + Buff->ShowX;
@@ -1414,7 +1514,11 @@ CSR_API(CsrSetCursor)
       if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
         {
           ConioUnlockScreenBuffer(Buff);
-          return Reply->Status = STATUS_UNSUCCESSFUL;
+          if (NULL != Console)
+            {
+              ConioUnlockConsole(Console);
+            }
+          return Request->Status = STATUS_UNSUCCESSFUL;
         }
     }
 
@@ -1424,10 +1528,10 @@ CSR_API(CsrSetCursor)
       ConioUnlockConsole(Console);
     }
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
-STATIC FASTCALL VOID
+static FASTCALL VOID
 ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, COORD *Start, UINT Length)
 {
   if (Buff->MaxX <= Start->X + Length)
@@ -1457,80 +1561,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) - LPC_MESSAGE_BASE_SIZE;
+  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))
-    {
-      return Reply->Status = Status;
-    }
-
-  Status = ConioLockScreenBuffer(ProcessData,
-                                 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
-                                 &Buff);
-  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))
     {
-      if (NULL != Console)
+      if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
         {
-          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 (++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)
@@ -1538,20 +1668,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) - LPC_MESSAGE_BASE_SIZE;
+
+  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);
@@ -1561,18 +1691,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)
@@ -1596,8 +1730,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)
@@ -1607,31 +1742,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) - LPC_MESSAGE_BASE_SIZE;
-  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 (Request->Data.ReadInputRequest.Unicode == FALSE)
+      if (Done && !Input->Fake)
         {
-          ConioInputEventToAnsi(Console, &Reply->Data.ReadInputReply.Input);
-        }
+         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)
         {
@@ -1644,49 +1791,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) - LPC_MESSAGE_BASE_SIZE;
 
-  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,
@@ -1698,17 +1853,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)
         {
@@ -1733,18 +1888,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;
@@ -1756,11 +1911,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) - LPC_MESSAGE_BASE_SIZE;
+
+  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))
     {
@@ -1768,7 +1923,7 @@ CSR_API(CsrFillOutputAttrib)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   X = Request->Data.FillOutputAttribRequest.Coord.X + Buff->ShowX;
@@ -1804,7 +1959,7 @@ CSR_API(CsrFillOutputAttrib)
       ConioUnlockConsole(Console);
     }
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 
@@ -1812,21 +1967,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) - LPC_MESSAGE_BASE_SIZE;
+  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)
@@ -1836,16 +1991,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) - LPC_MESSAGE_BASE_SIZE;
+  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);
@@ -1855,7 +2010,7 @@ CSR_API(CsrSetCursorInfo)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   Size = Request->Data.SetCursorInfoRequest.Info.dwSize;
@@ -1879,7 +2034,7 @@ CSR_API(CsrSetCursorInfo)
         {
           ConioUnlockScreenBuffer(Buff);
           ConioUnlockConsole(Console);
-          return Reply->Status = STATUS_UNSUCCESSFUL;
+          return Request->Status = STATUS_UNSUCCESSFUL;
         }
     }
 
@@ -1889,7 +2044,7 @@ CSR_API(CsrSetCursorInfo)
       ConioUnlockConsole(Console);
     }
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetTextAttrib)
@@ -1897,14 +2052,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);
@@ -1914,7 +2069,7 @@ CSR_API(CsrSetTextAttrib)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &OldCursorX, &OldCursorY);
@@ -1926,7 +2081,7 @@ CSR_API(CsrSetTextAttrib)
         {
           ConioUnlockScreenBuffer(Buff);
           ConioUnlockConsole(Console);
-          return Reply->Status = STATUS_UNSUCCESSFUL;
+          return Request->Status = STATUS_UNSUCCESSFUL;
         }
     }
 
@@ -1936,7 +2091,7 @@ CSR_API(CsrSetTextAttrib)
       ConioUnlockConsole(Console);
     }
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetConsoleMode)
@@ -1947,14 +2102,14 @@ CSR_API(CsrSetConsoleMode)
 
   DPRINT("CsrSetConsoleMode\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
+  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;
@@ -1968,12 +2123,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)
@@ -1984,30 +2139,30 @@ CSR_API(CsrGetConsoleMode)
 
   DPRINT("CsrGetConsoleMode\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
+  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)
@@ -2015,46 +2170,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) - LPC_MESSAGE_BASE_SIZE;
+  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)
@@ -2068,22 +2223,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) - LPC_MESSAGE_BASE_SIZE;
+  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)
@@ -2108,81 +2263,100 @@ 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) - LPC_MESSAGE_BASE_SIZE;
-
-  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) - LPC_MESSAGE_BASE_SIZE;
+  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;
+  memcpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer,
+          Console->Title.Length);
+  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)
@@ -2205,11 +2379,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) - LPC_MESSAGE_BASE_SIZE;
+  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);
@@ -2219,7 +2393,7 @@ CSR_API(CsrWriteConsoleOutput)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize;
@@ -2227,20 +2401,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;
 
@@ -2253,7 +2427,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++)
@@ -2265,9 +2439,7 @@ CSR_API(CsrWriteConsoleOutput)
           if (Request->Data.WriteConsoleOutputRequest.Unicode)
             {
               CHAR AsciiChar;
-              WideCharToMultiByte(Console->OutputCodePage, 0,
-                                  &CurCharInfo->Char.UnicodeChar, 1,
-                                  &AsciiChar, 1, NULL, NULL);
+              ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar);
               SET_CELL_BUFFER(Buff, Offset, AsciiChar, CurCharInfo->Attributes);
             }
           else
@@ -2286,12 +2458,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)
@@ -2303,14 +2475,14 @@ CSR_API(CsrFlushInputBuffer)
 
   DPRINT("CsrFlushInputBuffer\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
+  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 */
@@ -2321,11 +2493,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)
@@ -2351,11 +2524,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) - LPC_MESSAGE_BASE_SIZE;
+  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))
     {
@@ -2363,7 +2536,7 @@ CSR_API(CsrScrollConsoleScreenBuffer)
         {
           ConioUnlockConsole(Console);
         }
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   ScrollRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Left;
@@ -2380,13 +2553,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;
     }
 
 
@@ -2400,7 +2573,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);
@@ -2416,7 +2589,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;
     }
 
@@ -2438,27 +2611,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 - LPC_MESSAGE_BASE_SIZE;
-  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);
   if (! NT_SUCCESS(Status))
     {
-      return Reply->Status = Status;
+      return Request->Status = Status;
     }
 
   Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X + Buff->ShowX;
@@ -2466,9 +2650,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)
@@ -2484,15 +2675,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);
+    }
+
+  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 Reply->Status;
+  return Request->Status;
 }
 
 
@@ -2501,19 +2701,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 - LPC_MESSAGE_BASE_SIZE;
-  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;
@@ -2540,15 +2741,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;
 }
 
 
@@ -2559,21 +2766,21 @@ CSR_API(CsrGetNumberOfConsoleInputEvents)
   PLIST_ENTRY CurrentItem;
   DWORD NumEvents;
   ConsoleInput *Input;
-  
+
   DPRINT("CsrGetNumberOfConsoleInputEvents\n");
 
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = Reply->Header.MessageSize - LPC_MESSAGE_BASE_SIZE;
+  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.Flink;
   NumEvents = 0;
-  
+
   /* If there are any events ... */
   while (CurrentItem != &Console->InputEvents)
     {
@@ -2586,11 +2793,11 @@ CSR_API(CsrGetNumberOfConsoleInputEvents)
     }
 
   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;
 }
 
 
@@ -2604,36 +2811,36 @@ 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) - LPC_MESSAGE_BASE_SIZE;
-   
+  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.Flink;
-   
+
       while (CurrentItem != &Console->InputEvents && NumItems < Length)
         {
           Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry);
@@ -2643,7 +2850,7 @@ CSR_API(CsrPeekConsoleInput)
               CurrentItem = CurrentItem->Flink;
               continue;
             }
-          
+
           ++NumItems;
           *InputRecord = Item->InputEvent;
 
@@ -2651,7 +2858,7 @@ CSR_API(CsrPeekConsoleInput)
             {
               ConioInputEventToAnsi(Console, InputRecord);
             }
-         
+
           InputRecord++;
           CurrentItem = CurrentItem->Flink;
         }
@@ -2659,10 +2866,10 @@ CSR_API(CsrPeekConsoleInput)
 
   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;
 }
 
 
@@ -2679,20 +2886,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) - LPC_MESSAGE_BASE_SIZE;
-  
+  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;
@@ -2705,17 +2913,17 @@ CSR_API(CsrReadConsoleOutput)
 
   /* 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;
 
@@ -2723,21 +2931,21 @@ 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)
         {
           if (Request->Data.ReadConsoleOutputRequest.Unicode)
             {
               MultiByteToWideChar(CodePage, 0,
-                                  &GET_CELL_BUFFER(Buff, Offset), 1,
+                                  (PCHAR)&GET_CELL_BUFFER(Buff, Offset), 1,
                                   &CurCharInfo->Char.UnicodeChar, 1);
             }
           else
@@ -2750,14 +2958,14 @@ CSR_API(CsrReadConsoleOutput)
     }
 
   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;
 }
 
 
@@ -2770,38 +2978,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) - LPC_MESSAGE_BASE_SIZE;
-   
+  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;
@@ -2809,16 +3017,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;
 }
 
 /**********************************************************************
@@ -2830,12 +3039,12 @@ 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.
  */
-STATIC NTSTATUS FASTCALL
+static NTSTATUS FASTCALL
 SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
 {
   DPRINT1("Console Hardware State: %d\n", ConsoleHwState);
@@ -2850,7 +3059,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]) */
@@ -2860,40 +3069,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) - LPC_MESSAGE_BASE_SIZE;
-   
+  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)
@@ -2902,20 +3111,20 @@ CSR_API(CsrGetConsoleWindow)
   NTSTATUS Status;
 
   DPRINT("CsrGetConsoleWindow\n");
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
-   
+
+  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.GetConsoleWindowReply.WindowHandle = Console->hWindow;
+  Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow;
   ConioUnlockConsole(Console);
 
-  return Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetConsoleIcon)
@@ -2924,21 +3133,21 @@ CSR_API(CsrSetConsoleIcon)
   NTSTATUS Status;
 
   DPRINT("CsrSetConsoleIcon\n");
-  Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
-  Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
-   
+
+  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;
     }
 
   Console->hWindowIcon = Request->Data.SetConsoleIconRequest.WindowIcon;
-  Reply->Status = (ConioChangeIcon(Console) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
+  Request->Status = (ConioChangeIcon(Console) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
   ConioUnlockConsole(Console);
 
-  return Reply->Status;
+  return Request->Status;
 }
 
 CSR_API(CsrGetConsoleCodePage)
@@ -2951,14 +3160,14 @@ CSR_API(CsrGetConsoleCodePage)
   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) - LPC_MESSAGE_BASE_SIZE;
-  Reply->Data.GetConsoleCodePage.CodePage = Console->CodePage;
+
+  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 Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetConsoleCodePage)
@@ -2971,19 +3180,19 @@ CSR_API(CsrSetConsoleCodePage)
   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) - LPC_MESSAGE_BASE_SIZE;
+
+  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 Reply->Status = STATUS_SUCCESS;
+      return Request->Status = STATUS_SUCCESS;
     }
   ConioUnlockConsole(Console);
-  return Reply->Status = STATUS_UNSUCCESSFUL;
+  return Request->Status = STATUS_UNSUCCESSFUL;
 }
 
 CSR_API(CsrGetConsoleOutputCodePage)
@@ -2996,14 +3205,14 @@ CSR_API(CsrGetConsoleOutputCodePage)
   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) - LPC_MESSAGE_BASE_SIZE;
-  Reply->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage;
+
+  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 Reply->Status = STATUS_SUCCESS;
+  return Request->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetConsoleOutputCodePage)
@@ -3016,19 +3225,72 @@ CSR_API(CsrSetConsoleOutputCodePage)
   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) - LPC_MESSAGE_BASE_SIZE;
+
+  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 Reply->Status = STATUS_SUCCESS;
+      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);
-  return Reply->Status = STATUS_UNSUCCESSFUL;
+
+  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 */