1. Implemented WriteConsoleW(), ReadConsoleW(), FillConsoleOutputCharacterW(), WriteC...
authorThomas Bluemel <thomas@reactsoft.com>
Tue, 2 Nov 2004 20:42:06 +0000 (20:42 +0000)
committerThomas Bluemel <thomas@reactsoft.com>
Tue, 2 Nov 2004 20:42:06 +0000 (20:42 +0000)
2. added stub for SetThreadUILanguage()
This get's XP's cmd.exe to start (unfortunately it exits for some reason after one hits the enter key).

svn path=/trunk/; revision=11529

reactos/include/csrss/csrss.h
reactos/lib/kernel32/kernel32.def
reactos/lib/kernel32/misc/console.c
reactos/lib/kernel32/thread/thread.c
reactos/subsys/csrss/win32csr/conio.c

index 61d82cb..f423df5 100644 (file)
@@ -42,6 +42,7 @@ typedef struct
 typedef struct
 {
    HANDLE ConsoleHandle;
+   BOOL Unicode;
    ULONG NrCharactersToWrite;
    BYTE Buffer[1];
 } CSRSS_WRITE_CONSOLE_REQUEST, *PCSRSS_WRITE_CONSOLE_REQUEST;
@@ -54,6 +55,7 @@ typedef struct
 typedef struct
 {
    HANDLE ConsoleHandle;
+   BOOL Unicode;
    WORD NrCharactersToRead;
    WORD nCharsCanBeDeleted;     /* number of chars already in buffer that can be backspaced */
 } CSRSS_READ_CONSOLE_REQUEST, *PCSRSS_READ_CONSOLE_REQUEST;
@@ -108,13 +110,19 @@ typedef struct
 typedef struct
 {
    HANDLE ConsoleHandle;
-   CHAR Char;
+   BOOL Unicode;
+   union
+   {
+     CHAR AsciiChar;
+     WCHAR UnicodeChar;
+   } Char;
    COORD Position;
    WORD Length;
 } CSRSS_FILL_OUTPUT_REQUEST, *PCSRSS_FILL_OUTPUT_REQUEST;
 
 typedef struct
 {
+   ULONG NrCharactersWritten;
 } CSRSS_FILL_OUTPUT_REPLY, *PCSRSS_FILL_OUTPUT_REPLY;
 
 typedef struct
@@ -145,6 +153,7 @@ typedef struct
 typedef struct
 {
    HANDLE ConsoleHandle;
+   BOOL Unicode;
    WORD Length;
    COORD Coord;
    CHAR String[1];
@@ -153,6 +162,7 @@ typedef struct
 typedef struct
 {
    COORD EndCoord;
+   ULONG NrCharactersWritten;
 } CSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REPLY, *PCSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REPLY;
 
 typedef struct
@@ -296,12 +306,13 @@ typedef struct
 
 typedef struct
 {
-  HANDLE     ConsoleHandle;
+  HANDLE ConsoleHandle;
+  BOOL Unicode;
   SMALL_RECT ScrollRectangle;
-  BOOLEAN    UseClipRectangle;
+  BOOLEAN UseClipRectangle;
   SMALL_RECT ClipRectangle;
-  COORD      DestinationOrigin;
-  CHAR_INFO  Fill;
+  COORD DestinationOrigin;
+  CHAR_INFO Fill;
 } CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST, *PCSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST;
 
 typedef struct
@@ -311,6 +322,7 @@ typedef struct
 typedef struct
 {
   HANDLE ConsoleHandle;
+  BOOL Unicode;
   DWORD NumCharsToRead;
   COORD ReadCoord;
 }CSRSS_READ_CONSOLE_OUTPUT_CHAR_REQUEST, *PCSRSS_READ_CONSOLE_OUTPUT_CHAR_REQUEST;
@@ -318,6 +330,7 @@ typedef struct
 typedef struct
 {
   COORD EndCoord;
+  DWORD CharsRead;
   CHAR String[1];
 }CSRSS_READ_CONSOLE_OUTPUT_CHAR_REPLY, *PCSRSS_READ_CONSOLE_OUTPUT_CHAR_REPLY;
 
@@ -414,6 +427,7 @@ typedef struct
 typedef struct
 {
   HANDLE ConsoleHandle;
+  BOOL Unicode;
   DWORD Length;
   INPUT_RECORD* InputRecord;
 } CSRSS_WRITE_CONSOLE_INPUT_REQUEST, *PCSRSS_WRITE_CONSOLE_INPUT_REQUEST;
@@ -701,8 +715,7 @@ typedef struct
         CSRSS_GET_TITLE_REQUEST GetTitleRequest;
         CSRSS_WRITE_CONSOLE_OUTPUT_REQUEST WriteConsoleOutputRequest;
         CSRSS_FLUSH_INPUT_BUFFER_REQUEST FlushInputBufferRequest;
-        CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST 
-        ScrollConsoleScreenBufferRequest;
+        CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST ScrollConsoleScreenBufferRequest;
         CSRSS_READ_CONSOLE_OUTPUT_CHAR_REQUEST ReadConsoleOutputCharRequest;
         CSRSS_READ_CONSOLE_OUTPUT_ATTRIB_REQUEST ReadConsoleOutputAttribRequest;
         CSRSS_GET_NUM_INPUT_EVENTS_REQUEST GetNumInputEventsRequest;
@@ -746,6 +759,7 @@ typedef struct
       {
         CSRSS_CREATE_PROCESS_REPLY CreateProcessReply;
         CSRSS_CONNECT_PROCESS_REPLY ConnectReply;
+        CSRSS_FILL_OUTPUT_REPLY FillOutputReply;
         CSRSS_WRITE_CONSOLE_REPLY WriteConsoleReply;
         CSRSS_READ_CONSOLE_REPLY ReadConsoleReply;
         CSRSS_ALLOC_CONSOLE_REPLY AllocConsoleReply;
index eed5072..33b1145 100644 (file)
@@ -841,7 +841,7 @@ SetThreadIdealProcessor@8
 SetThreadLocale@4
 SetThreadPriority@8
 SetThreadPriorityBoost@8
-;SetThreadUILanguage
+SetThreadUILanguage@4
 SetTimerQueueTimer@24
 SetTimeZoneInformation@4
 SetUnhandledExceptionFilter@4
index 793e6d3..af1ece6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: console.c,v 1.81 2004/09/14 22:30:56 hbirr Exp $
+/* $Id: console.c,v 1.82 2004/11/02 20:42:05 weiden Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -19,7 +19,6 @@
 #define NDEBUG
 #include "../include/debug.h"
 
-#define _NOACHS(__X) (sizeof(__X) / sizeof((__X)[0]))
 extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);
 extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag);
 extern CRITICAL_SECTION ConsoleLock;
@@ -148,6 +147,7 @@ AddConsoleAliasA (LPSTR Source,
                  LPSTR Target,
                  LPSTR ExeName)
 {
+  DPRINT1("AddConsoleAliasA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Source, Target, ExeName);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -161,6 +161,7 @@ AddConsoleAliasW (LPWSTR Source,
                  LPWSTR Target,
                  LPWSTR ExeName)
 {
+  DPRINT1("AddConsoleAliasW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Source, Target, ExeName);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -177,6 +178,7 @@ ConsoleMenuControl (HANDLE  hConsole,
       * Undocumented
       */
 {
+  DPRINT1("ConsoleMenuControl(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsole, Unknown1, Unknown2);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -226,6 +228,7 @@ ExpungeConsoleCommandHistoryW (DWORD        Unknown0)
       * Undocumented
       */
 {
+  DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -240,6 +243,8 @@ ExpungeConsoleCommandHistoryA (DWORD        Unknown0)
       * Undocumented
       */
 {
+
+  DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -257,6 +262,7 @@ GetConsoleAliasW (DWORD     Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -274,8 +280,9 @@ GetConsoleAliasA (DWORD     Unknown0,
       * Undocumented
       */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetConsoleAliasA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
@@ -289,6 +296,7 @@ GetConsoleAliasExesW (DWORD Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasExesW(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -304,8 +312,9 @@ GetConsoleAliasExesA (DWORD Unknown0,
       * Undocumented
       */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetConsoleAliasExesA(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
@@ -318,6 +327,7 @@ GetConsoleAliasExesLengthA (VOID)
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasExesLengthA() UNIMPLEMENTED!\n");
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -332,6 +342,7 @@ GetConsoleAliasExesLengthW (VOID)
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasExesLengthW() UNIMPLEMENTED!\n");
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -348,6 +359,7 @@ GetConsoleAliasesW (DWORD   Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasesW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -364,6 +376,7 @@ GetConsoleAliasesA (DWORD   Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasesA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -378,6 +391,7 @@ GetConsoleAliasesLengthW (DWORD Unknown0)
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasesLengthW(0x%x) UNIMPLEMENTED!\n", Unknown0);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -392,6 +406,7 @@ GetConsoleAliasesLengthA (DWORD Unknown0)
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasesLengthA(0x%x) UNIMPLEMENTED!\n", Unknown0);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -408,6 +423,7 @@ GetConsoleCommandHistoryW (DWORD    Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleCommandHistoryW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -424,6 +440,7 @@ GetConsoleCommandHistoryA (DWORD    Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleCommandHistoryA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -438,6 +455,7 @@ GetConsoleCommandHistoryLengthW (DWORD      Unknown0)
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleCommandHistoryLengthW(0x%x) UNIMPLEMENTED!\n", Unknown0);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -452,6 +470,7 @@ GetConsoleCommandHistoryLengthA (DWORD      Unknown0)
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleCommandHistoryLengthA(0x%x) UNIMPLEMENTED!\n", Unknown0);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -469,6 +488,7 @@ GetConsoleDisplayMode (LPDWORD lpdwMode)
       * STATUS: Undocumented
       */
 {
+  DPRINT1("GetConsoleDisplayMode(0x%x) UNIMPLEMENTED!\n", lpdwMode);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -486,6 +506,7 @@ GetConsoleFontInfo (DWORD   Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleFontInfo(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -498,6 +519,7 @@ DWORD STDCALL
 GetConsoleFontSize(HANDLE hConsoleOutput,
                   DWORD nFont)
 {
+  DPRINT1("GetConsoleFontSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -545,6 +567,7 @@ GetConsoleInputWaitHandle (VOID)
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleInputWaitHandle() UNIMPLEMENTED!\n");
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -558,6 +581,7 @@ GetCurrentConsoleFont(HANDLE hConsoleOutput,
                      BOOL bMaximumWindow,
                      PCONSOLE_FONT_INFO lpConsoleCurrentFont)
 {
+  DPRINT1("GetCurrentConsoleFont(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFont);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -572,6 +596,7 @@ GetNumberOfConsoleFonts (VOID)
       * Undocumented
       */
 {
+  DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 1; /* FIXME: call csrss.exe */
 }
@@ -587,6 +612,7 @@ InvalidateConsoleDIBits (DWORD      Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("InvalidateConsoleDIBits(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -609,7 +635,6 @@ OpenConsoleW (LPWSTR  wsName,
   PHANDLE           phConsole = NULL;
   NTSTATUS          Status = STATUS_SUCCESS;
   
-  
   if(0 == _wcsicmp(wsName, L"CONIN$"))
   {
     Request.Type = CSRSS_GET_INPUT_HANDLE;
@@ -657,6 +682,7 @@ SetConsoleCommandHistoryMode (DWORD dwMode)
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleCommandHistoryMode(0x%x) UNIMPLEMENTED!\n", dwMode);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -672,6 +698,7 @@ SetConsoleCursor (DWORD     Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -692,6 +719,7 @@ SetConsoleDisplayMode (HANDLE hOut,
       *       lpdwOldMode - Address of a variable that receives the old mode.
       */
 {
+  DPRINT1("SetConsoleDisplayMode(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hOut, dwNewMode, lpdwOldMode);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -707,6 +735,7 @@ SetConsoleFont (DWORD       Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleFont(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -757,6 +786,7 @@ SetConsoleKeyShortcuts (DWORD       Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -772,6 +802,7 @@ SetConsoleMaximumWindowSize (DWORD  Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleMaximumWindowSize(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -786,6 +817,7 @@ SetConsoleMenuClose (DWORD  Unknown0)
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -801,6 +833,7 @@ SetConsoleNumberOfCommandsA (DWORD  Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleNumberOfCommandsA(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -816,6 +849,7 @@ SetConsoleNumberOfCommandsW (DWORD  Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleNumberOfCommandsW(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -832,6 +866,7 @@ SetConsolePalette (DWORD    Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("SetConsolePalette(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -846,6 +881,7 @@ SetLastConsoleEventActive (VOID)
       * Undocumented
       */
 {
+  DPRINT1("SetLastConsoleEventActive() UNIMPLEMENTED!\n");
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -861,6 +897,7 @@ ShowConsoleCursor (DWORD    Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -909,6 +946,7 @@ WriteConsoleInputVDMA (DWORD        Unknown0,
                       DWORD    Unknown2,
                       DWORD    Unknown3)
 {
+  DPRINT1("WriteConsoleInputVDMA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -923,6 +961,7 @@ WriteConsoleInputVDMW (DWORD        Unknown0,
                       DWORD    Unknown2,
                       DWORD    Unknown3)
 {
+  DPRINT1("WriteConsoleInputVDMW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -1053,6 +1092,73 @@ SetStdHandle(DWORD nStdHandle,
 }
 
 
+static BOOL
+IntWriteConsole(HANDLE hConsoleOutput,
+                PVOID lpBuffer,
+                DWORD nNumberOfCharsToWrite,
+                LPDWORD lpNumberOfCharsWritten,
+                LPVOID lpReserved,
+                BOOL bUnicode)
+{
+  PCSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+  USHORT nChars;
+  ULONG MessageSize, BufferSize, SizeBytes, CharSize;
+  DWORD Written = 0;
+  
+  CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+
+  BufferSize = sizeof(CSRSS_API_REQUEST) + min(nNumberOfCharsToWrite * CharSize, CSRSS_MAX_WRITE_CONSOLE_REQUEST);
+  Request = RtlAllocateHeap(GetProcessHeap(), 0, BufferSize);
+  if(Request == NULL)
+  {
+    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    return FALSE;
+  }
+
+  Request->Type = CSRSS_WRITE_CONSOLE;
+  Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
+  Request->Data.WriteConsoleRequest.Unicode = bUnicode;
+
+  while(nNumberOfCharsToWrite > 0)
+  {
+    nChars = min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE_REQUEST / CharSize);
+    Request->Data.WriteConsoleRequest.NrCharactersToWrite = nChars;
+
+    SizeBytes = nChars * CharSize;
+
+    memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, SizeBytes);
+
+    MessageSize = CSRSS_REQUEST_HEADER_SIZE + sizeof(CSRSS_WRITE_CONSOLE_REQUEST) + SizeBytes;
+    Status = CsrClientCallServer(Request,
+                                 &Reply,
+                                 MessageSize,
+                                 sizeof(CSRSS_API_REPLY));
+
+    if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+    {
+      RtlFreeHeap(GetProcessHeap(), 0, Request);
+      SetLastErrorByStatus(Status);
+      return FALSE;
+    }
+
+    nNumberOfCharsToWrite -= nChars;
+    lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
+    Written += Reply.Data.WriteConsoleReply.NrCharactersWritten;
+  }
+
+  RtlFreeHeap(GetProcessHeap(), 0, Request);
+  
+  if(lpNumberOfCharsWritten != NULL)
+  {
+    *lpNumberOfCharsWritten = Written;
+  }
+
+  return TRUE;
+}
+
+
 /*--------------------------------------------------------------
  *     WriteConsoleA
  *
@@ -1065,154 +1171,158 @@ WriteConsoleA(HANDLE hConsoleOutput,
              LPDWORD lpNumberOfCharsWritten,
              LPVOID lpReserved)
 {
-  PCSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
-  NTSTATUS Status;
-  USHORT Size;
-  ULONG MessageSize;
+  return IntWriteConsole(hConsoleOutput,
+                         (PVOID)lpBuffer,
+                         nNumberOfCharsToWrite,
+                         lpNumberOfCharsWritten,
+                         lpReserved,
+                         FALSE);
+}
 
-  Request = RtlAllocateHeap(GetProcessHeap(), 0,
-                           sizeof(CSRSS_API_REQUEST) +
-                           min(nNumberOfCharsToWrite,
-                           CSRSS_MAX_WRITE_CONSOLE_REQUEST));
-  if (Request == NULL)
-    {
-      SetLastError(ERROR_OUTOFMEMORY);
-      return(FALSE);
-    }
 
-  Request->Type = CSRSS_WRITE_CONSOLE;
-  Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
-  if (lpNumberOfCharsWritten != NULL)
-    *lpNumberOfCharsWritten = nNumberOfCharsToWrite;
-  while (nNumberOfCharsToWrite)
-    {
-      if (nNumberOfCharsToWrite > CSRSS_MAX_WRITE_CONSOLE_REQUEST)
-       {
-         Size = CSRSS_MAX_WRITE_CONSOLE_REQUEST;
-       }
-      else
-       {
-         Size = nNumberOfCharsToWrite;
-       }
-      Request->Data.WriteConsoleRequest.NrCharactersToWrite = Size;
+/*--------------------------------------------------------------
+ *     WriteConsoleW
+ *
+ * @implemented
+ */
+BOOL STDCALL
+WriteConsoleW(
+       HANDLE           hConsoleOutput,
+       CONST VOID      *lpBuffer,
+       DWORD            nNumberOfCharsToWrite,
+       LPDWORD          lpNumberOfCharsWritten,
+       LPVOID           lpReserved
+       )
+{
+  return IntWriteConsole(hConsoleOutput,
+                         (PVOID)lpBuffer,
+                         nNumberOfCharsToWrite,
+                         lpNumberOfCharsWritten,
+                         lpReserved,
+                         TRUE);
+}
 
-      memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, Size);
 
-      MessageSize = CSRSS_REQUEST_HEADER_SIZE + 
-       sizeof(CSRSS_WRITE_CONSOLE_REQUEST) + Size;
-      Status = CsrClientCallServer(Request,
-                                  &Reply,
-                                  MessageSize,
-                                  sizeof(CSRSS_API_REPLY));
+static BOOL
+IntReadConsole(HANDLE hConsoleInput,
+               PVOID lpBuffer,
+               DWORD nNumberOfCharsToRead,
+               LPDWORD lpNumberOfCharsRead,
+               LPVOID lpReserved,
+               BOOL bUnicode)
+{
+  CSRSS_API_REQUEST Request;
+  PCSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+  ULONG BufferSize, CharSize, CharsRead = 0;
+  
+  CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+  
+  BufferSize = sizeof(CSRSS_API_REQUEST) + min(nNumberOfCharsToRead * CharSize, CSRSS_MAX_READ_CONSOLE_REQUEST);
+  Reply = RtlAllocateHeap(GetProcessHeap(), 0, BufferSize);
+  if(Reply == NULL)
+  {
+    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    return FALSE;
+  }
+  
+  Reply->Status = STATUS_SUCCESS;
 
-      if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
-       {
-         RtlFreeHeap(GetProcessHeap(), 0, Request);
-         SetLastErrorByStatus(Status);
-         return(FALSE);
-       }
-      nNumberOfCharsToWrite -= Size;
-      lpBuffer += Size;
+  do
+  {
+    if(Reply->Status == STATUS_PENDING)
+    {
+      Status = NtWaitForSingleObject(Reply->Data.ReadConsoleReply.EventHandle, FALSE, 0);
+      if(!NT_SUCCESS(Status))
+      {
+        DPRINT1("Wait for console input failed!\n");
+        break;
+      }
     }
+    
+    Request.Type = CSRSS_READ_CONSOLE;
+    Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
+    Request.Data.ReadConsoleRequest.Unicode = bUnicode;
+    Request.Data.ReadConsoleRequest.NrCharactersToRead = min(nNumberOfCharsToRead, CSRSS_MAX_READ_CONSOLE_REQUEST / CharSize);
+    Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = CharsRead;
+    Status = CsrClientCallServer(&Request,
+                                 Reply,
+                                 sizeof(CSRSS_API_REQUEST),
+                                 sizeof(CSRSS_API_REPLY) + (Request.Data.ReadConsoleRequest.NrCharactersToRead * CharSize));
+
+    if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply->Status))
+    {
+      DPRINT1("CSR returned error in ReadConsole\n");
+      SetLastErrorByStatus(Status);
+      RtlFreeHeap(GetProcessHeap(), 0, Reply);
+      return FALSE;
+    }
+    
+    nNumberOfCharsToRead -= Reply->Data.ReadConsoleReply.NrCharactersRead;
+    memcpy((PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)(CharsRead * CharSize)),
+           Reply->Data.ReadConsoleReply.Buffer,
+           Reply->Data.ReadConsoleReply.NrCharactersRead);
+    CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
+    
+    if(Reply->Status == STATUS_NOTIFY_CLEANUP)
+    {
+      if(CharsRead > 0)
+      {
+        CharsRead--;
+        nNumberOfCharsToRead++;
+      }
+      Reply->Status = STATUS_PENDING;
+    }
+  } while(Reply->Status == STATUS_PENDING && nNumberOfCharsToRead > 0);
+  
+  if(lpNumberOfCharsRead != NULL)
+  {
+    *lpNumberOfCharsRead = CharsRead;
+  }
+  
+  return (nNumberOfCharsToRead == 0);
+}
 
-  RtlFreeHeap(GetProcessHeap(), 0, Request);
 
-  return TRUE;
+/*--------------------------------------------------------------
+ *     ReadConsoleA
+ *
+ * @implemented
+ */
+BOOL STDCALL
+ReadConsoleA(HANDLE hConsoleInput,
+             LPVOID lpBuffer,
+             DWORD nNumberOfCharsToRead,
+             LPDWORD lpNumberOfCharsRead,
+             LPVOID lpReserved)
+{
+  return IntReadConsole(hConsoleInput,
+                        lpBuffer,
+                        nNumberOfCharsToRead,
+                        lpNumberOfCharsRead,
+                        lpReserved,
+                        FALSE);
 }
 
 
 /*--------------------------------------------------------------
- *     ReadConsoleA
+ *     ReadConsoleW
  *
  * @implemented
  */
-BOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
-                            LPVOID lpBuffer,
-                            DWORD nNumberOfCharsToRead,
-                            LPDWORD lpNumberOfCharsRead,
-                            LPVOID lpReserved)
+BOOL STDCALL
+ReadConsoleW(HANDLE hConsoleInput,
+             LPVOID lpBuffer,
+             DWORD nNumberOfCharsToRead,
+             LPDWORD lpNumberOfCharsRead,
+             LPVOID lpReserved)
 {
-   CSRSS_API_REQUEST Request;
-   PCSRSS_API_REPLY Reply;
-   NTSTATUS Status;
-   ULONG CharsRead = 0;
-   
-   Reply = RtlAllocateHeap(GetProcessHeap(), 0,
-                           sizeof(CSRSS_API_REPLY) + nNumberOfCharsToRead);
-   if (Reply == NULL)
-     {
-       SetLastError(ERROR_OUTOFMEMORY);
-       return(FALSE);
-     }
-   
-   Request.Type = CSRSS_READ_CONSOLE;
-   Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
-   Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
-   Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = 0;
-   Status = CsrClientCallServer(&Request, 
-                               Reply,
-                               sizeof(CSRSS_API_REQUEST),
-                               sizeof(CSRSS_API_REPLY) + 
-                               Request.Data.ReadConsoleRequest.NrCharactersToRead);
-   if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply->Status ))
-     {
-       DbgPrint( "CSR returned error in ReadConsole\n" );
-       SetLastErrorByStatus ( Status );
-       RtlFreeHeap( GetProcessHeap(), 0, Reply );
-       return(FALSE);
-     }
-   if( Reply->Status == STATUS_NOTIFY_CLEANUP )
-      Reply->Status = STATUS_PENDING;     // ignore backspace because we have no chars to backspace
-   /* There may not be any chars or lines to read yet, so wait */
-   while( Reply->Status == STATUS_PENDING )
-     {
-       /* some chars may have been returned, but not a whole line yet, so recompute buffer and try again */
-       nNumberOfCharsToRead -= Reply->Data.ReadConsoleReply.NrCharactersRead;
-       /* don't overflow caller's buffer, even if you still don't have a complete line */
-       if( !nNumberOfCharsToRead )
-        break;
-       Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
-       /* copy any chars already read to buffer */
-       memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
-       CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
-       /* wait for csrss to signal there is more data to read, but not if we got STATUS_NOTIFY_CLEANUP for backspace */
-       Status = NtWaitForSingleObject( Reply->Data.ReadConsoleReply.EventHandle, FALSE, 0 );
-       if( !NT_SUCCESS( Status ) )
-         {
-            DbgPrint( "Wait for console input failed!\n" );
-            RtlFreeHeap( GetProcessHeap(), 0, Reply );
-            return FALSE;
-         }
-       Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = CharsRead;
-       Status = CsrClientCallServer( &Request, Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) + Request.Data.ReadConsoleRequest.NrCharactersToRead );
-       if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply->Status ) )
-        {
-          SetLastErrorByStatus ( Status );
-          RtlFreeHeap( GetProcessHeap(), 0, Reply );
-          return FALSE;
-        }
-       if( Reply->Status == STATUS_NOTIFY_CLEANUP )
-         {
-            // delete last char
-            if( CharsRead )
-               {
-                  CharsRead--;
-                  nNumberOfCharsToRead++;
-               }
-            Reply->Status = STATUS_PENDING;  // retry
-         }
-     }
-   /* copy data to buffer, count total returned, and return */
-   memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
-   CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
-   if (lpNumberOfCharsRead != NULL)
-     *lpNumberOfCharsRead = CharsRead;
-   RtlFreeHeap(GetProcessHeap(),
-           0,
-           Reply);
-   
-   return(TRUE);
+  return IntReadConsole(hConsoleInput,
+                        lpBuffer,
+                        nNumberOfCharsToRead,
+                        lpNumberOfCharsRead,
+                        lpReserved,
+                        TRUE);
 }
 
 
@@ -1340,6 +1450,45 @@ SetConsoleCursorPosition(
 }
 
 
+static BOOL
+IntFillConsoleOutputCharacter(HANDLE hConsoleOutput,
+                              PVOID cCharacter,
+                              DWORD nLength,
+                              COORD dwWriteCoord,
+                              LPDWORD lpNumberOfCharsWritten,
+                              BOOL bUnicode)
+{
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+
+  Request.Type = CSRSS_FILL_OUTPUT;
+  Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
+  Request.Data.FillOutputRequest.Unicode = bUnicode;
+  if(bUnicode)
+    Request.Data.FillOutputRequest.Char.UnicodeChar = *((WCHAR*)cCharacter);
+  else
+    Request.Data.FillOutputRequest.Char.AsciiChar = *((CHAR*)cCharacter);
+  Request.Data.FillOutputRequest.Position = dwWriteCoord;
+  Request.Data.FillOutputRequest.Length = nLength;
+  Status = CsrClientCallServer(&Request, &Reply,
+                               sizeof(CSRSS_API_REQUEST),
+                               sizeof(CSRSS_API_REPLY));
+
+  if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+
+  if(lpNumberOfCharsWritten != NULL)
+  {
+    *lpNumberOfCharsWritten = Reply.Data.FillOutputReply.NrCharactersWritten;
+  }
+  
+  return TRUE;
+}
+
 /*--------------------------------------------------------------
  *     FillConsoleOutputCharacterA
  *
@@ -1354,31 +1503,19 @@ FillConsoleOutputCharacterA(
        LPDWORD         lpNumberOfCharsWritten
        )
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
-  NTSTATUS Status;
-
-  Request.Type = CSRSS_FILL_OUTPUT;
-  Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
-  Request.Data.FillOutputRequest.Char = cCharacter;
-  Request.Data.FillOutputRequest.Position = dwWriteCoord;
-  Request.Data.FillOutputRequest.Length = nLength;
-  Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-  if ( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
-    {
-      SetLastErrorByStatus(Status);
-      return(FALSE);
-    }
-  if (lpNumberOfCharsWritten != NULL)
-     *lpNumberOfCharsWritten = nLength;
-  return(TRUE);
+  return IntFillConsoleOutputCharacter(hConsoleOutput,
+                                       &cCharacter,
+                                       nLength,
+                                       dwWriteCoord,
+                                       lpNumberOfCharsWritten,
+                                       FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     FillConsoleOutputCharacterW
  *
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
@@ -1390,33 +1527,28 @@ FillConsoleOutputCharacterW(
        LPDWORD         lpNumberOfCharsWritten
        )
 {
-/* TO DO */
-       DbgPrint("%s unimplemented\n", __FUNCTION__);
-       return FALSE;
+  return IntFillConsoleOutputCharacter(hConsoleOutput,
+                                       &cCharacter,
+                                       nLength,
+                                       dwWriteCoord,
+                                       lpNumberOfCharsWritten,
+                                       TRUE);
 }
 
 
-/*--------------------------------------------------------------
- *     IntPeekConsoleInput
- *
- * INTERNAL
- */
-BOOL
-WINAPI
-IntPeekConsoleInput(
-       HANDLE                  hConsoleInput,
-       PINPUT_RECORD           lpBuffer,
-       DWORD                   nLength,
-       LPDWORD                 lpNumberOfEventsRead,
-       BOOL                    bUnicode
-       )
+static BOOL
+IntPeekConsoleInput(HANDLE hConsoleInput,
+                    PINPUT_RECORD lpBuffer,
+                    DWORD nLength,
+                    LPDWORD lpNumberOfEventsRead,
+                    BOOL bUnicode)
 {
   PCSRSS_API_REQUEST Request;
   CSRSS_API_REPLY Reply;
   NTSTATUS Status;
   PVOID BufferBase;
   PVOID BufferTargetBase;
-  DWORD Size;
+  ULONG Size;
   
   if(lpBuffer == NULL)
   {
@@ -1437,7 +1569,7 @@ IntPeekConsoleInput(
   if(Request == NULL)
   {
     CsrReleaseParameterBuffer(BufferBase);
-    SetLastError(ERROR_OUTOFMEMORY);
+    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     return FALSE;
   }
   
@@ -1447,7 +1579,9 @@ IntPeekConsoleInput(
   Request->Data.PeekConsoleInputRequest.Length = nLength;
   Request->Data.PeekConsoleInputRequest.InputRecord = (INPUT_RECORD*)BufferTargetBase;
   
-  Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
+  Status = CsrClientCallServer(Request, &Reply,
+                               sizeof(CSRSS_API_REQUEST),
+                               sizeof(CSRSS_API_REPLY));
   
   if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
   {
@@ -1458,11 +1592,13 @@ IntPeekConsoleInput(
 
   memcpy(lpBuffer, BufferBase, sizeof(INPUT_RECORD) * Reply.Data.PeekConsoleInputReply.Length);
 
+  RtlFreeHeap(GetProcessHeap(), 0, Request);
+  CsrReleaseParameterBuffer(BufferBase);
+  
   if(lpNumberOfEventsRead != NULL)
+  {
     *lpNumberOfEventsRead = Reply.Data.PeekConsoleInputReply.Length;
-
-  RtlFreeHeap(GetProcessHeap(), 0, Request);
-  CsrReleaseParameterBuffer(BufferBase);  
+  }
   
   return TRUE;
 }
@@ -1505,12 +1641,7 @@ PeekConsoleInputW(
 }
 
 
-/*--------------------------------------------------------------
- *     IntReadConsoleInput
- *
- * INTERNAL
- */
-BOOL WINAPI
+static BOOL
 IntReadConsoleInput(HANDLE hConsoleInput,
                     PINPUT_RECORD lpBuffer,
                     DWORD nLength,
@@ -1519,68 +1650,69 @@ IntReadConsoleInput(HANDLE hConsoleInput,
 {
   CSRSS_API_REQUEST Request;
   CSRSS_API_REPLY Reply;
-  DWORD NumEventsRead;
+  ULONG Read;
   NTSTATUS Status;
-
+  
   Request.Type = CSRSS_READ_INPUT;
   Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
-  Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
-                               sizeof(CSRSS_API_REPLY));
-  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  Request.Data.ReadInputRequest.Unicode = bUnicode;
+
+  Read = 0;
+  while(nLength > 0)
+  {
+    Status = CsrClientCallServer(&Request, &Reply,
+                                 sizeof(CSRSS_API_REQUEST),
+                                 sizeof(CSRSS_API_REPLY));
+    if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
     {
-      SetLastErrorByStatus(Status);
-      return(FALSE);
+      if(Read == 0)
+      {
+        /* we couldn't read a single record, fail */
+        SetLastErrorByStatus(Status);
+        return FALSE;
+      }
+      else
+      {
+        /* FIXME - fail gracefully in case we already read at least one record? */
+        break;
+      }
     }
-  
-  while (Status == STATUS_PENDING)
+    else if(Status == STATUS_PENDING)
     {
-      Status = NtWaitForSingleObject(Reply.Data.ReadInputReply.Event, FALSE, 
-                                    0);
-      if(!NT_SUCCESS(Status))
-       {
-         SetLastErrorByStatus(Status);
-         return FALSE;
-       }
-      
-      Request.Type = CSRSS_READ_INPUT;
-      Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
-      Request.Data.ReadInputRequest.Unicode = bUnicode;
-      Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
-                                  sizeof(CSRSS_API_REPLY));
-      if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
-       {
-         SetLastErrorByStatus(Status);
-         return(FALSE);
-       }
+      if(Read == 0)
+      {
+        Status = NtWaitForSingleObject(Reply.Data.ReadInputReply.Event, FALSE, 0);
+        if(!NT_SUCCESS(Status))
+        {
+          SetLastErrorByStatus(Status);
+          break;
+        }
+      }
+      else
+      {
+        /* nothing more to read (waiting for more input??), let's just bail */
+        break;
+      }
     }
-  
-  NumEventsRead = 1;
-  *lpBuffer = Reply.Data.ReadInputReply.Input;
-  lpBuffer++;
-  
-  while ((NumEventsRead < nLength) && (Reply.Data.ReadInputReply.MoreEvents))
+    else
     {
-      Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
-                                  sizeof(CSRSS_API_REPLY));
-      if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
-       {
-         SetLastErrorByStatus(Status);
-         return(FALSE);
-       }
-      
-      if (Status == STATUS_PENDING)
-       {
-         break;
-       }
-      
-      *lpBuffer = Reply.Data.ReadInputReply.Input;
-      lpBuffer++;
-      NumEventsRead++;
-      
+      lpBuffer[Read++] = Reply.Data.ReadInputReply.Input;
+      nLength--;
+
+      if(!Reply.Data.ReadInputReply.MoreEvents)
+      {
+        /* nothing more to read, bail */
+        break;
+      }
     }
-  *lpNumberOfEventsRead = NumEventsRead;
+  }
   
-  return TRUE;
+  if(lpNumberOfEventsRead != NULL)
+  {
+    *lpNumberOfEventsRead = Read;
+  }
+  
+  return (Read > 0);
 }
 
 
@@ -1619,32 +1751,25 @@ ReadConsoleInputW(
 }
 
 
-/*--------------------------------------------------------------
- *     WriteConsoleInputA
- *
- * @implemented
- */
-BOOL
-WINAPI
-WriteConsoleInputA(
-       HANDLE                   hConsoleInput,
-       CONST INPUT_RECORD      *lpBuffer,
-       DWORD                    nLength,
-       LPDWORD                  lpNumberOfEventsWritten
-       )
+static BOOL
+IntWriteConsoleInput(HANDLE hConsoleInput,
+                     PINPUT_RECORD lpBuffer,
+                     DWORD nLength,
+                     LPDWORD lpNumberOfEventsWritten,
+                     BOOL bUnicode)
 {
-  PCSRSS_API_REQUEST Request;
+  CSRSS_API_REQUEST Request;
   CSRSS_API_REPLY Reply;
   PVOID BufferBase, BufferTargetBase;
   NTSTATUS Status;
   DWORD Size;
-  
+
   if(lpBuffer == NULL)
   {
     SetLastError(ERROR_INVALID_PARAMETER);
     return FALSE;
   }
-  
+
   Size = nLength * sizeof(INPUT_RECORD);
 
   Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
@@ -1653,73 +1778,85 @@ WriteConsoleInputA(
     SetLastErrorByStatus(Status);
     return FALSE;
   }
-  
-  Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
-  if(Request == NULL)
-  {
-    SetLastError(ERROR_OUTOFMEMORY);
-    CsrReleaseParameterBuffer(BufferBase);
-    return FALSE;
-  }
 
-  Request->Type = CSRSS_WRITE_CONSOLE_INPUT;
-  Request->Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
-  Request->Data.WriteConsoleInputRequest.Length = nLength;
-  Request->Data.WriteConsoleInputRequest.InputRecord = (PINPUT_RECORD)BufferTargetBase;
+  Request.Type = CSRSS_WRITE_CONSOLE_INPUT;
+  Request.Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
+  Request.Data.WriteConsoleInputRequest.Unicode = bUnicode;
+  Request.Data.WriteConsoleInputRequest.Length = nLength;
+  Request.Data.WriteConsoleInputRequest.InputRecord = (PINPUT_RECORD)BufferTargetBase;
+
+  Status = CsrClientCallServer(&Request, &Reply,
+                               sizeof(CSRSS_API_REQUEST),
+                               sizeof(CSRSS_API_REPLY));
+
+  CsrReleaseParameterBuffer(BufferBase);
   
-  Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
   if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
   {
-    RtlFreeHeap(GetProcessHeap(), 0, Request);
-    CsrReleaseParameterBuffer(BufferBase);
+    SetLastErrorByStatus(Status);
     return FALSE;
   }
   
   if(lpNumberOfEventsWritten != NULL)
+  {
     *lpNumberOfEventsWritten = Reply.Data.WriteConsoleInputReply.Length;
-  
-  RtlFreeHeap(GetProcessHeap(), 0, Request);
-  CsrReleaseParameterBuffer(BufferBase);
-  
+  }
+
   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
- *     WriteConsoleInputW
+ *     WriteConsoleInputA
  *
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
-WriteConsoleInputW(
+WriteConsoleInputA(
        HANDLE                   hConsoleInput,
        CONST INPUT_RECORD      *lpBuffer,
        DWORD                    nLength,
        LPDWORD                  lpNumberOfEventsWritten
        )
 {
-/* TO DO */
-       DbgPrint("%s unimplemented\n", __FUNCTION__);
-       return FALSE;
+  return IntWriteConsoleInput(hConsoleInput,
+                              (PINPUT_RECORD)lpBuffer,
+                              nLength,
+                              lpNumberOfEventsWritten,
+                              FALSE);
 }
 
 
 /*--------------------------------------------------------------
- *     IntReadConsoleOutput
+ *     WriteConsoleInputW
  *
- * INTERNAL
+ * @implemented
  */
 BOOL
 WINAPI
-IntReadConsoleOutput(
-       HANDLE          hConsoleOutput,
-       PCHAR_INFO      lpBuffer,
-       COORD           dwBufferSize,
-       COORD           dwBufferCoord,
-       PSMALL_RECT     lpReadRegion,
-       BOOL            bUnicode
+WriteConsoleInputW(
+       HANDLE                   hConsoleInput,
+       CONST INPUT_RECORD      *lpBuffer,
+       DWORD                    nLength,
+       LPDWORD                  lpNumberOfEventsWritten
        )
+{
+  return IntWriteConsoleInput(hConsoleInput,
+                              (PINPUT_RECORD)lpBuffer,
+                              nLength,
+                              lpNumberOfEventsWritten,
+                              TRUE);
+}
+
+
+static BOOL
+IntReadConsoleOutput(HANDLE hConsoleOutput,
+                     PCHAR_INFO lpBuffer,
+                     COORD dwBufferSize,
+                     COORD dwBufferCoord,
+                     PSMALL_RECT lpReadRegion,
+                     BOOL bUnicode)
 {
   PCSRSS_API_REQUEST Request;
   CSRSS_API_REPLY Reply;
@@ -1746,7 +1883,7 @@ IntReadConsoleOutput(
   Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
   if(Request == NULL)
   {
-    SetLastError(ERROR_OUTOFMEMORY);
+    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     CsrReleaseParameterBuffer(BufferBase);
     return FALSE;
   }
@@ -1759,7 +1896,10 @@ IntReadConsoleOutput(
   Request->Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
   Request->Data.ReadConsoleOutputRequest.CharInfo = (PCHAR_INFO)BufferTargetBase;
   
-  Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
+  Status = CsrClientCallServer(Request, &Reply,
+                               sizeof(CSRSS_API_REQUEST),
+                               sizeof(CSRSS_API_REPLY));
+
   if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
   {
     SetLastErrorByStatus(Status);
@@ -1772,11 +1912,12 @@ IntReadConsoleOutput(
   SizeY = Reply.Data.ReadConsoleOutputReply.ReadRegion.Bottom - Reply.Data.ReadConsoleOutputReply.ReadRegion.Top + 1;
   
   memcpy(lpBuffer, BufferBase, sizeof(CHAR_INFO) * SizeX * SizeY);
-  *lpReadRegion = Reply.Data.ReadConsoleOutputReply.ReadRegion;
   
   RtlFreeHeap(GetProcessHeap(), 0, Request);
   CsrReleaseParameterBuffer(BufferBase);
   
+  *lpReadRegion = Reply.Data.ReadConsoleOutputReply.ReadRegion;
+  
   return TRUE;
 }
 
@@ -1820,18 +1961,13 @@ ReadConsoleOutputW(
 }
 
 
-/*--------------------------------------------------------------
- *     IntWriteConsoleOutput
- *
- * INTERNAL
- */
-BOOL WINAPI
-IntWriteConsoleOutput(HANDLE           hConsoleOutput,
+static BOOL
+IntWriteConsoleOutput(HANDLE hConsoleOutput,
                       CONST CHAR_INFO *lpBuffer,
-                      COORD            dwBufferSize,
-                      COORD            dwBufferCoord,
-                      PSMALL_RECT      lpWriteRegion,
-                      BOOL             bUnicode)
+                      COORD dwBufferSize,
+                      COORD dwBufferCoord,
+                      PSMALL_RECT lpWriteRegion,
+                      BOOL bUnicode)
 {
   PCSRSS_API_REQUEST Request;
   CSRSS_API_REPLY Reply;
@@ -1857,7 +1993,7 @@ IntWriteConsoleOutput(HANDLE           hConsoleOutput,
   if (Request == NULL)
     {
       CsrReleaseParameterBuffer(BufferBase);
-      SetLastError(ERROR_OUTOFMEMORY);
+      SetLastError(ERROR_NOT_ENOUGH_MEMORY);
       return FALSE;
     }
   Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT;
@@ -1872,6 +2008,7 @@ IntWriteConsoleOutput(HANDLE           hConsoleOutput,
   Status = CsrClientCallServer(Request, &Reply, 
                               sizeof(CSRSS_API_REQUEST), 
                               sizeof(CSRSS_API_REPLY));
+
   if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
     {
       CsrReleaseParameterBuffer(BufferBase);
@@ -1880,9 +2017,11 @@ IntWriteConsoleOutput(HANDLE           hConsoleOutput,
       return FALSE;
     }
       
-  *lpWriteRegion = Reply.Data.WriteConsoleOutputReply.WriteRegion;
   RtlFreeHeap(GetProcessHeap(), 0, Request);
   CsrReleaseParameterBuffer(BufferBase);
+  
+  *lpWriteRegion = Reply.Data.WriteConsoleOutputReply.WriteRegion;
+  
   return(TRUE);
 }
 
@@ -1923,78 +2062,103 @@ WriteConsoleOutputW(
 }
 
 
-/*--------------------------------------------------------------
- *     ReadConsoleOutputCharacterA
- *
- * @implemented
- */
-BOOL
-WINAPI
-ReadConsoleOutputCharacterA(
-       HANDLE          hConsoleOutput,
-       LPSTR           lpCharacter,
-       DWORD           nLength,
-       COORD           dwReadCoord,
-       LPDWORD         lpNumberOfCharsRead
-       )
+static BOOL
+IntReadConsoleOutputCharacter(HANDLE hConsoleOutput,
+                              PVOID lpCharacter,
+                              DWORD nLength,
+                              COORD dwReadCoord,
+                              LPDWORD lpNumberOfCharsRead,
+                              BOOL bUnicode)
 {
   CSRSS_API_REQUEST Request;
   PCSRSS_API_REPLY Reply;
   NTSTATUS Status;
-  DWORD Size;
+  ULONG nChars, SizeBytes, CharSize;
+  DWORD CharsRead = 0;
+  
+  CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+  
+  nChars = min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR / CharSize);
+  SizeBytes = nChars * CharSize;
 
   Reply = RtlAllocateHeap(GetProcessHeap(), 0,
-                         sizeof(CSRSS_API_REPLY) +
-                         min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR));
-  if (Reply == NULL)
-    {
-      SetLastError(ERROR_OUTOFMEMORY);
-      return(FALSE);
-    }
+                         sizeof(CSRSS_API_REPLY) + SizeBytes);
+  if(Reply == NULL)
+  {
+    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    return FALSE;
+  }
 
-  if (lpNumberOfCharsRead != NULL)
-    *lpNumberOfCharsRead = nLength;
 
   Request.Type = CSRSS_READ_CONSOLE_OUTPUT_CHAR;
   Request.Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
+  Request.Data.ReadConsoleOutputCharRequest.Unicode = bUnicode;
   Request.Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
 
-  while (nLength != 0)
+  while(nLength > 0)
+  {
+    DWORD BytesRead;
+    
+    Request.Data.ReadConsoleOutputCharRequest.NumCharsToRead = min(nLength, nChars);
+
+    Status = CsrClientCallServer(&Request,
+                                 Reply,
+                                 sizeof(CSRSS_API_REQUEST),
+                                 sizeof(CSRSS_API_REPLY) + SizeBytes);
+    if(!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
     {
-      if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR)
-       Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR;
-      else
-       Size = nLength;
+      SetLastErrorByStatus(Status);
+      break;
+    }
 
-      Request.Data.ReadConsoleOutputCharRequest.NumCharsToRead = Size;
+    BytesRead = Reply->Data.ReadConsoleOutputCharReply.CharsRead * CharSize;
+    memcpy(lpCharacter, &Reply->Data.ReadConsoleOutputCharReply.String[0], BytesRead);
+    lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)BytesRead);
+    CharsRead += Reply->Data.ReadConsoleOutputCharReply.CharsRead;
+    nLength -= Reply->Data.ReadConsoleOutputCharReply.CharsRead;
+    
+    Request.Data.ReadConsoleOutputCharRequest.ReadCoord = Reply->Data.ReadConsoleOutputCharReply.EndCoord;
+  }
 
-      Status = CsrClientCallServer(&Request,
-                                  Reply,
-                                  sizeof(CSRSS_API_REQUEST),
-                                  sizeof(CSRSS_API_REPLY) + Size);
-      if (!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
-       {
-         RtlFreeHeap(GetProcessHeap(), 0, Reply);
-         SetLastErrorByStatus(Status);
-         return(FALSE);
-       }
+  RtlFreeHeap(GetProcessHeap(), 0, Reply);
+  
+  if(lpNumberOfCharsRead != NULL)
+  {
+    *lpNumberOfCharsRead = CharsRead;
+  }
 
-      memcpy(lpCharacter, &Reply->Data.ReadConsoleOutputCharReply.String[0], Size);
-      lpCharacter += Size;
-      nLength -= Size;
-      Request.Data.ReadConsoleOutputCharRequest.ReadCoord = Reply->Data.ReadConsoleOutputCharReply.EndCoord;
-    }
+  return TRUE;
+}
 
-  RtlFreeHeap(GetProcessHeap(), 0, Reply);
 
-  return(TRUE);
+/*--------------------------------------------------------------
+ *     ReadConsoleOutputCharacterA
+ *
+ * @implemented
+ */
+BOOL
+WINAPI
+ReadConsoleOutputCharacterA(
+       HANDLE          hConsoleOutput,
+       LPSTR           lpCharacter,
+       DWORD           nLength,
+       COORD           dwReadCoord,
+       LPDWORD         lpNumberOfCharsRead
+       )
+{
+  return IntReadConsoleOutputCharacter(hConsoleOutput,
+                                       (PVOID)lpCharacter,
+                                       nLength,
+                                       dwReadCoord,
+                                       lpNumberOfCharsRead,
+                                       FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *      ReadConsoleOutputCharacterW
  *
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
@@ -2006,9 +2170,12 @@ ReadConsoleOutputCharacterW(
        LPDWORD         lpNumberOfCharsRead
        )
 {
-/* TO DO */
-       DbgPrint("%s unimplemented\n", __FUNCTION__);
-       return FALSE;
+  return IntReadConsoleOutputCharacter(hConsoleOutput,
+                                       (PVOID)lpCharacter,
+                                       nLength,
+                                       dwReadCoord,
+                                       lpNumberOfCharsRead,
+                                       TRUE);
 }
 
 
@@ -2033,8 +2200,7 @@ ReadConsoleOutputAttribute(
   DWORD Size, i;
   
   Reply = RtlAllocateHeap(GetProcessHeap(), 0,
-                         sizeof(CSRSS_API_REPLY) +
-                         min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB));
+                         sizeof(CSRSS_API_REPLY) + min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB));
   if (Reply == NULL)
     {
       SetLastError(ERROR_OUTOFMEMORY);
@@ -2082,60 +2248,97 @@ ReadConsoleOutputAttribute(
 }
 
 
-/*--------------------------------------------------------------
- *     WriteConsoleOutputCharacterA
- *
- * @implemented
- */
-BOOL WINAPI
-WriteConsoleOutputCharacterA(HANDLE            hConsoleOutput,
-                            LPCSTR             lpCharacter,
-                            DWORD              nLength,
-                            COORD              dwWriteCoord,
-                            LPDWORD            lpNumberOfCharsWritten)
+static BOOL
+IntWriteConsoleOutputCharacter(HANDLE hConsoleOutput,
+                               PVOID lpCharacter,
+                               DWORD nLength,
+                               COORD dwWriteCoord,
+                               LPDWORD lpNumberOfCharsWritten,
+                               BOOL bUnicode)
 {
   PCSRSS_API_REQUEST Request;
   CSRSS_API_REPLY Reply;
   NTSTATUS Status;
-  WORD Size;
+  ULONG SizeBytes, CharSize, nChars;
+  DWORD Written = 0;
+  
+  CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+  
+  nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_REQUEST / CharSize);
+  SizeBytes = nChars * CharSize;
 
   Request = RtlAllocateHeap(GetProcessHeap(), 0,
-                           sizeof(CSRSS_API_REQUEST) +
-                           min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR));
-  if( !Request )
-    {
-      SetLastError( ERROR_OUTOFMEMORY );
-      return FALSE;
-    }
+                            sizeof(CSRSS_API_REQUEST) + (nChars * CharSize));
+  if(Request == NULL)
+  {
+    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    return FALSE;
+  }
+
   Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR;
   Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
+  Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode;
   Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
-  if( lpNumberOfCharsWritten )
-    *lpNumberOfCharsWritten = nLength;
-  while( nLength )
+
+  while(nLength > 0)
+  {
+    DWORD BytesWrite;
+    
+    Request->Data.WriteConsoleOutputCharRequest.Length = min(nLength, nChars);
+    BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize;
+
+    memcpy(&Request->Data.WriteConsoleOutputCharRequest.String[0], lpCharacter, BytesWrite);
+
+    Status = CsrClientCallServer(Request, &Reply,
+                                 sizeof(CSRSS_API_REQUEST) + BytesWrite,
+                                 sizeof(CSRSS_API_REPLY));
+
+    if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
     {
-      Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength;
-      Request->Data.WriteConsoleOutputCharRequest.Length = Size;
-      memcpy( &Request->Data.WriteConsoleOutputCharRequest.String[0],
-             lpCharacter,
-             Size );
-      Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
-      if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
-       {
-         RtlFreeHeap( GetProcessHeap(), 0, Request );
-         SetLastErrorByStatus ( Status );
-         return FALSE;
-       }
-      nLength -= Size;
-      lpCharacter += Size;
-      Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
+      RtlFreeHeap(GetProcessHeap(), 0, Request);
+      SetLastErrorByStatus(Status);
+      return FALSE;
     }
+
+    nLength -= Reply.Data.WriteConsoleOutputCharReply.NrCharactersWritten;
+    lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)(Reply.Data.WriteConsoleOutputCharReply.NrCharactersWritten * CharSize));
+    Written += Reply.Data.WriteConsoleOutputCharReply.NrCharactersWritten;
+
+    Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
+  }
+
+  RtlFreeHeap(GetProcessHeap(), 0, Request);
   
-  RtlFreeHeap( GetProcessHeap(), 0, Request ); 
+  if(lpNumberOfCharsWritten != NULL)
+  {
+    *lpNumberOfCharsWritten = Written;
+  }
+
   return TRUE;
 }
 
 
+/*--------------------------------------------------------------
+ *     WriteConsoleOutputCharacterA
+ *
+ * @implemented
+ */
+BOOL WINAPI
+WriteConsoleOutputCharacterA(HANDLE            hConsoleOutput,
+                            LPCSTR             lpCharacter,
+                            DWORD              nLength,
+                            COORD              dwWriteCoord,
+                            LPDWORD            lpNumberOfCharsWritten)
+{
+  return IntWriteConsoleOutputCharacter(hConsoleOutput,
+                                        (PVOID)lpCharacter,
+                                        nLength,
+                                        dwWriteCoord,
+                                        lpNumberOfCharsWritten,
+                                        FALSE);
+}
+
+
 /*--------------------------------------------------------------
  *     WriteConsoleOutputCharacterW
  *
@@ -2148,54 +2351,12 @@ WriteConsoleOutputCharacterW(HANDLE             hConsoleOutput,
                             COORD              dwWriteCoord,
                             LPDWORD            lpNumberOfCharsWritten)
 {
-  PCSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
-  NTSTATUS Status;
-  WORD Size;
-  
-  Request = RtlAllocateHeap(GetProcessHeap(), 0,
-                           sizeof(CSRSS_API_REQUEST) +
-                           min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR));
-  if( !Request )
-    {
-      SetLastError( ERROR_OUTOFMEMORY );
-      return FALSE;
-    }
-  Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR;
-  Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
-  Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
-  if( lpNumberOfCharsWritten )
-    *lpNumberOfCharsWritten = nLength;
-  while( nLength )
-    {
-      Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength;
-      Request->Data.WriteConsoleOutputCharRequest.Length = Size;
-      Status = RtlUnicodeToOemN (&Request->Data.WriteConsoleOutputCharRequest.String[0],
-                                Size,
-                                NULL,
-                                (PWCHAR)lpCharacter,
-                                Size * sizeof(WCHAR));
-      if (!NT_SUCCESS(Status))
-       {
-         RtlFreeHeap (GetProcessHeap(), 0, Request);
-         SetLastErrorByStatus (Status);
-         return FALSE;
-       }
-
-      Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
-      if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
-       {
-         RtlFreeHeap( GetProcessHeap(), 0, Request );
-         SetLastErrorByStatus ( Status );
-         return FALSE;
-       }
-      nLength -= Size;
-      lpCharacter += Size;
-      Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
-    }
-  
-  RtlFreeHeap( GetProcessHeap(), 0, Request );
-  return TRUE;
+  return IntWriteConsoleOutputCharacter(hConsoleOutput,
+                                        (PVOID)lpCharacter,
+                                        nLength,
+                                        dwWriteCoord,
+                                        lpNumberOfCharsWritten,
+                                        TRUE);
 }
 
 
@@ -2369,12 +2530,10 @@ GetLargestConsoleWindowSize(
        HANDLE          hConsoleOutput
        )
 {
-#if 1  /* FIXME: */
-       COORD Coord = {80,25};
-
-/* TO DO */
-       return Coord;
-#endif
+  COORD Coord = {80,25};
+  DPRINT1("GetLargestConsoleWindowSize(0x%x) UNIMPLEMENTED!\n", hConsoleOutput);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return Coord;
 }
 
 
@@ -2419,8 +2578,9 @@ GetNumberOfConsoleMouseButtons(
        LPDWORD         lpNumberOfMouseButtons
        )
 {
-/* TO DO */
-       return FALSE;
+  DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
@@ -2519,9 +2679,9 @@ SetConsoleScreenBufferSize(
        COORD           dwSize
        )
 {
-/* TO DO */
-       DbgPrint("%s unimplemented\n", __FUNCTION__);
-       return FALSE;
+  DPRINT1("SetConsoleScreenBufferSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, dwSize);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /*--------------------------------------------------------------
@@ -2554,20 +2714,13 @@ SetConsoleCursorInfo(
 }
 
 
-/*--------------------------------------------------------------
- *     ScrollConsoleScreenBufferA
- *
- * @implemented
- */
-BOOL
-WINAPI
-ScrollConsoleScreenBufferA(
-       HANDLE                   hConsoleOutput,
-       CONST SMALL_RECT        *lpScrollRectangle,
-       CONST SMALL_RECT        *lpClipRectangle,
-       COORD                    dwDestinationOrigin,
-       CONST CHAR_INFO         *lpFill
-       )
+static BOOL
+IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
+                             PSMALL_RECT lpScrollRectangle,
+                             PSMALL_RECT lpClipRectangle,
+                             COORD dwDestinationOrigin,
+                             PCHAR_INFO lpFill,
+                             BOOL bUnicode)
 {
   CSRSS_API_REQUEST Request;
   CSRSS_API_REPLY Reply;
@@ -2575,35 +2728,63 @@ ScrollConsoleScreenBufferA(
 
   Request.Type = CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER;
   Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
+  Request.Data.ScrollConsoleScreenBufferRequest.Unicode = bUnicode;
   Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
 
-  if (lpClipRectangle != NULL)
-    {
-  Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
-  Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
-    }
+  if(lpClipRectangle != NULL)
+  {
+    Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
+    Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
+  }
   else
-    {
-  Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
-    }
+  {
+    Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
+  }
 
   Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
   Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
-  Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+  Status = CsrClientCallServer(&Request, &Reply,
+                               sizeof(CSRSS_API_REQUEST),
+                               sizeof(CSRSS_API_REPLY));
+
+  if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
 
-  if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
-    {
-      SetLastErrorByStatus ( Status );
-      return FALSE;
-    }
   return TRUE;
 }
 
 
+/*--------------------------------------------------------------
+ *     ScrollConsoleScreenBufferA
+ *
+ * @implemented
+ */
+BOOL
+WINAPI
+ScrollConsoleScreenBufferA(
+       HANDLE                   hConsoleOutput,
+       CONST SMALL_RECT        *lpScrollRectangle,
+       CONST SMALL_RECT        *lpClipRectangle,
+       COORD                    dwDestinationOrigin,
+       CONST CHAR_INFO         *lpFill
+       )
+{
+  return IntScrollConsoleScreenBuffer(hConsoleOutput,
+                                      (PSMALL_RECT)lpScrollRectangle,
+                                      (PSMALL_RECT)lpClipRectangle,
+                                      dwDestinationOrigin,
+                                      (PCHAR_INFO)lpFill,
+                                      FALSE);
+}
+
+
 /*--------------------------------------------------------------
  *     ScrollConsoleScreenBufferW
  *
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
@@ -2615,9 +2796,12 @@ ScrollConsoleScreenBufferW(
        CONST CHAR_INFO         *lpFill
        )
 {
-/* TO DO */
-       DbgPrint("%s unimplemented\n", __FUNCTION__);
-       return FALSE;
+  return IntScrollConsoleScreenBuffer(hConsoleOutput,
+                                      (PSMALL_RECT)lpScrollRectangle,
+                                      (PSMALL_RECT)lpClipRectangle,
+                                      dwDestinationOrigin,
+                                      (PCHAR_INFO)lpFill,
+                                      TRUE);
 }
 
 
@@ -2634,9 +2818,9 @@ SetConsoleWindowInfo(
        CONST SMALL_RECT        *lpConsoleWindow
        )
 {
-/* TO DO */
-       DbgPrint("%s unimplemented\n", __FUNCTION__);
-       return FALSE;
+  DPRINT1("SetConsoleWindowInfo(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bAbsolute, lpConsoleWindow);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
@@ -2769,7 +2953,8 @@ GenerateConsoleCtrlEvent(
        DWORD           dwProcessGroupId
        )
 {
-  /* TO DO */
+  DPRINT1("GenerateConsoleCtrlEvent(0x%x, 0x%x) UNIMPLEMENTED!\n", dwCtrlEvent, dwProcessGroupId);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
 
@@ -2993,93 +3178,6 @@ SetConsoleTitleA(
 }
 
 
-/*--------------------------------------------------------------
- *     ReadConsoleW
- *
- * @unimplemented
- */
-BOOL
-WINAPI
-ReadConsoleW(
-       HANDLE          hConsoleInput,
-       LPVOID          lpBuffer,
-       DWORD           nNumberOfCharsToRead,
-       LPDWORD         lpNumberOfCharsRead,
-       LPVOID          lpReserved
-       )
-{
-/* --- TO DO --- */
-       DbgPrint("%s unimplemented\n", __FUNCTION__);
-       return FALSE;
-}
-
-
-/*--------------------------------------------------------------
- *     WriteConsoleW
- *
- * @unimplemented
- */
-BOOL
-WINAPI
-WriteConsoleW(
-       HANDLE           hConsoleOutput,
-       CONST VOID      *lpBuffer,
-       DWORD            nNumberOfCharsToWrite,
-       LPDWORD          lpNumberOfCharsWritten,
-       LPVOID           lpReserved
-       )
-{
-       DbgPrint("%s unimplemented\n", __FUNCTION__);
-#if 0
-  PCSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
-  NTSTATUS Status;
-
-  Request = RtlAllocateHeap(GetProcessHeap(),
-                           HEAP_ZERO_MEMORY,
-                           sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite * sizeof(WCHAR));
-  if (Request == NULL)
-    {
-      SetLastError(ERROR_OUTOFMEMORY);
-      return(FALSE);
-    }
-
-  Request->Type = CSRSS_WRITE_CONSOLE;
-  Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
-  Request->Data.WriteConsoleRequest.NrCharactersToWrite =
-    nNumberOfCharsToWrite;
-//  DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite);
-//  DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer);
-  memcpy(Request->Data.WriteConsoleRequest.Buffer,
-        lpBuffer,
-        nNumberOfCharsToWrite * sizeof(WCHAR));
-
-  Status = CsrClientCallServer(Request,
-                              &Reply,
-                              sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite,
-                              sizeof(CSRSS_API_REPLY));
-
-  RtlFreeHeap(GetProcessHeap(),
-             0,
-             Request);
-
-  if (!NT_SUCCESS(Status))
-    {
-      return(FALSE);
-    }
-
-  if (lpNumberOfCharsWritten != NULL)
-    {
-      *lpNumberOfCharsWritten = 
-         Reply.Data.WriteConsoleReply.NrCharactersWritten;
-    }
-
-  return(TRUE);
-#endif
-  return(FALSE);
-}
-
-
 /*--------------------------------------------------------------
  *     CreateConsoleScreenBuffer
  *
@@ -3224,8 +3322,9 @@ DWORD STDCALL
 GetConsoleProcessList(LPDWORD lpdwProcessList,
                   DWORD dwProcessCount)
 {
-   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-   return 0;
+  DPRINT1("GetConsoleProcessList(0x%x, 0x%x) UNIMPLEMENTED!\n", lpdwProcessList, dwProcessCount);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
@@ -3238,8 +3337,9 @@ GetConsoleProcessList(LPDWORD lpdwProcessList,
 BOOL STDCALL
 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
 {
-   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-   return FALSE;
+  DPRINT1("GetConsoleSelectionInfo(0x%x) UNIMPLEMENTED!\n", lpConsoleSelectionInfo);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
@@ -3252,8 +3352,9 @@ GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
 BOOL STDCALL 
 AttachConsole(DWORD dwProcessId)
 {
-   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-   return FALSE;
+  DPRINT1("AttachConsole(0x%x) UNIMPLEMENTED!\n", dwProcessId);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /*--------------------------------------------------------------
index fa4f278..b532288 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: thread.c,v 1.54 2004/10/24 12:16:54 weiden Exp $
+/* $Id: thread.c,v 1.55 2004/11/02 20:42:06 weiden Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -714,4 +714,13 @@ SetThreadIdealProcessor(HANDLE hThread,
   return dwIdealProcessor;
 }
 
+/*
+ * @unimplemented
+ */
+VOID STDCALL
+SetThreadUILanguage(DWORD Unknown1)
+{
+  DPRINT1("SetThreadUILanguage(0x%x) unimplemented!\n", Unknown1);
+}
+
 /* EOF */
index eed400b..c50f1ed 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: conio.c,v 1.15 2004/09/10 22:14:52 gvg Exp $
+/* $Id: conio.c,v 1.16 2004/11/02 20:42:06 weiden Exp $
  *
  * reactos/subsys/csrss/win32csr/conio.c
  *
@@ -46,6 +46,15 @@ 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)
+
+#define ConsoleUnicodeToAnsiN(Console, dChar, sWChar, nChars) \
+  WideCharToMultiByte((Console)->CodePage, 0, (sWChar), (nChars), (dChar), (nChars) * sizeof(WCHAR), NULL, NULL)
+
 /* FUNCTIONS *****************************************************************/
 
 STATIC NTSTATUS FASTCALL
@@ -522,19 +531,23 @@ CSR_API(CsrReadConsole)
   PLIST_ENTRY CurrentEntry;
   ConsoleInput *Input;
   PCHAR Buffer;
+  PWCHAR UnicodeBuffer;
   int i;
-  ULONG nNumberOfCharsToRead;
+  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;
+  nNumberOfCharsToRead = min(Request->Data.ReadConsoleRequest.NrCharactersToRead, CSRSS_MAX_READ_CONSOLE_REQUEST / CharSize);
   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
   Reply->Header.DataSize = Reply->Header.MessageSize - LPC_MESSAGE_BASE_SIZE;
 
   Buffer = Reply->Data.ReadConsoleReply.Buffer;
+  UnicodeBuffer = (PWCHAR)Buffer;
   Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle,
                                &Console);
   if (! NT_SUCCESS(Status))
@@ -551,7 +564,7 @@ CSR_API(CsrReadConsole)
       /* 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 +574,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 +582,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);
+                  Reply->Data.ReadConsoleReply.NrCharactersRead = 0;
+                  Reply->Status = STATUS_NOTIFY_CLEANUP;
                   return STATUS_NOTIFY_CLEANUP;
                 }
               Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--;
@@ -582,7 +595,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)
@@ -607,7 +623,8 @@ CSR_API(CsrReadConsole)
     }
   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 */
         }
@@ -630,7 +647,7 @@ CSR_API(CsrReadConsole)
     {
       Console->EchoCount = 0;             /* if the client is no longer waiting on input, do not echo */
     }
-  Reply->Header.MessageSize += i;
+  Reply->Header.MessageSize += i * CharSize;
 
   ConioUnlockConsole(Console);
   return Reply->Status;
@@ -817,14 +834,22 @@ ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
 }
 
 STATIC VOID FASTCALL
-ConioFillRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
+ConioFillRegion(PCSRSS_CONSOLE Console,
+                PCSRSS_SCREEN_BUFFER ScreenBuffer,
                 RECT *Region,
-                CHAR_INFO CharInfo)
+                CHAR_INFO *CharInfo,
+                BOOL bUnicode)
 {
   SHORT X, Y;
   DWORD Offset;
   DWORD Delta;
   ULONG i;
+  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 +859,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)
         {
@@ -853,10 +878,9 @@ 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);
+      ConsoleUnicodeCharToAnsiChar(Console,
+                                   &InputEvent->Event.KeyEvent.uChar.AsciiChar,
+                                   &InputEvent->Event.KeyEvent.uChar.UnicodeChar);
     }
 }
 
@@ -866,6 +890,7 @@ CSR_API(CsrWriteConsole)
   BYTE *Buffer = Request->Data.WriteConsoleRequest.Buffer;
   PCSRSS_SCREEN_BUFFER Buff;
   PCSRSS_CONSOLE Console;
+  ULONG CharSize = (Request->Data.WriteConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
 
   DPRINT("CsrWriteConsole\n");
    
@@ -874,7 +899,7 @@ CSR_API(CsrWriteConsole)
 
   if (Request->Header.DataSize
       < sizeof(CSRSS_WRITE_CONSOLE_REQUEST) - 1
-        + Request->Data.WriteConsoleRequest.NrCharactersToWrite)
+        + (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize))
     {
       DPRINT1("Invalid request size\n");
       return Reply->Status = STATUS_INVALID_PARAMETER;
@@ -885,6 +910,11 @@ CSR_API(CsrWriteConsole)
       return Reply->Status = Status;
     }
 
+  if(Request->Data.WriteConsoleRequest.Unicode)
+  {
+    ConsoleUnicodeToAnsiN(Console, Buffer, (PWCHAR)Buffer, Request->Data.WriteConsoleRequest.NrCharactersToWrite);
+  }
+
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
     {
@@ -895,14 +925,23 @@ CSR_API(CsrWriteConsole)
       return Reply->Status = Status;
     }
 
-  ConioWriteConsole(Console, Buff, Buffer,
-                    Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
+  Reply->Status = ConioWriteConsole(Console, Buff, Buffer,
+                                    Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
   ConioUnlockScreenBuffer(Buff);
   if (NULL != Console)
     {
       ConioUnlockConsole(Console);
     }
 
+  if(NT_SUCCESS(Reply->Status))
+  {
+    Reply->Data.WriteConsoleReply.NrCharactersWritten = Request->Data.WriteConsoleRequest.NrCharactersToWrite;
+  }
+  else
+  {
+    Reply->Data.WriteConsoleReply.NrCharactersWritten = 0; /* FIXME - return the actual number of characters written! */
+  }
+
   return Reply->Status = STATUS_SUCCESS;
 }
 
@@ -967,7 +1006,7 @@ CsrInitConsoleSupport(VOID)
 
 STATIC VOID FASTCALL
 ConioProcessChar(PCSRSS_CONSOLE Console,
-                            ConsoleInput *KeyEventRecord)
+                 ConsoleInput *KeyEventRecord)
 {
   BOOL updown;
   BOOL bClientWake = FALSE;
@@ -1114,7 +1153,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);
@@ -1296,6 +1335,7 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
     
   if (! ConInRec->Fake || ! ConInRec->NotChar)
     {
+      /* FIXME - convert to ascii */
       ConioProcessChar(Console, ConInRec);
     }
   else
@@ -1461,17 +1501,19 @@ CSR_API(CsrWriteConsoleOutputChar)
   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)
+        + (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize))
     {
       DPRINT1("Invalid request size\n");
       return Reply->Status = STATUS_INVALID_PARAMETER;
@@ -1483,6 +1525,11 @@ CSR_API(CsrWriteConsoleOutputChar)
       return Reply->Status = Status;
     }
 
+  if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
+  {
+    ConsoleUnicodeToAnsiN(Console, String, (PWCHAR)String, Request->Data.WriteConsoleOutputCharRequest.Length);
+  }
+
   Status = ConioLockScreenBuffer(ProcessData,
                                  Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
                                  &Buff);
@@ -1502,6 +1549,7 @@ CSR_API(CsrWriteConsoleOutputChar)
   while (Length--)
     {
       *Buffer = *String++;
+      Written++;
       Buffer += 2;
       if (++X == Buff->MaxX)
         {
@@ -1530,6 +1578,7 @@ CSR_API(CsrWriteConsoleOutputChar)
       ConioUnlockConsole(Console);
     }
 
+  Reply->Data.WriteConsoleOutputCharReply.NrCharactersWritten = Written;
   return Reply->Status = STATUS_SUCCESS;
 }
 
@@ -1538,7 +1587,7 @@ CSR_API(CsrFillOutputChar)
   NTSTATUS Status;
   PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
-  DWORD X, Y, Length;
+  DWORD X, Y, Length, Written = 0;
   BYTE Char;
   PBYTE Buffer;
   RECT UpdateRect;
@@ -1567,12 +1616,16 @@ CSR_API(CsrFillOutputChar)
   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)
@@ -1597,6 +1650,7 @@ CSR_API(CsrFillOutputChar)
       ConioUnlockConsole(Console);
     }
 
+  Reply->Data.FillOutputReply.NrCharactersWritten = Written;
   return Reply->Status;
 }
 
@@ -1630,7 +1684,7 @@ CSR_API(CsrReadInputEvent)
 
       if (Request->Data.ReadInputRequest.Unicode == FALSE)
         {
-          ConioInputEventToAnsi(Console, &Reply->Data.ReadInputReply.Input);
+          ConioInputEventToAnsi(Console, &Reply->Data.ReadInputReply.Input); /* FIXME */
         }
 
       if (Input->InputEvent.EventType == KEY_EVENT)
@@ -2265,9 +2319,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
@@ -2416,7 +2468,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;
     }
 
@@ -2444,16 +2496,27 @@ CSR_API(CsrScrollConsoleScreenBuffer)
 CSR_API(CsrReadConsoleOutputChar)
 {
   NTSTATUS Status;
+  PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
   DWORD Xpos, Ypos;
   BYTE* 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;
+  
+  CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
+  
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+    {
+      return Reply->Status = Status;
+    }
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
@@ -2466,9 +2529,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)
@@ -2491,6 +2561,12 @@ CSR_API(CsrReadConsoleOutputChar)
   Reply->Header.DataSize += Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead;
 
   ConioUnlockScreenBuffer(Buff);
+  if (NULL != Console)
+    {
+      ConioUnlockConsole(Console);
+    }
+  
+  Reply->Data.ReadConsoleOutputCharReply.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Reply->Data.ReadConsoleOutputCharReply.String) / CharSize;
 
   return Reply->Status;
 }
@@ -2809,6 +2885,7 @@ CSR_API(CsrWriteConsoleInput)
       Record->InputEvent = *InputRecord++;
       if (KEY_EVENT == Record->InputEvent.EventType)
         {
+          /* FIXME - convert from unicode to ascii!! */
           ConioProcessChar(Console, Record);
         }
     }