- Allocate the csrss request buffer from heap if the necessary length is larger than...
[reactos.git] / reactos / lib / kernel32 / misc / console.c
index a4f53f5..cfa9ec1 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: console.c,v 1.75 2004/05/28 13:17:32 weiden Exp $
+/* $Id$
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
  * FILE:            lib/kernel32/misc/console.c
  * PURPOSE:         Win32 server console functions
- * PROGRAMMER:      James Tabor 
+ * PROGRAMMER:      James Tabor
  *                     <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
  * UPDATE HISTORY:
  *     199901?? ??     Created
 #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;
+extern RTL_CRITICAL_SECTION ConsoleLock;
 extern BOOL WINAPI IsDebuggerPresent(VOID);
 
 
@@ -32,6 +31,7 @@ static BOOL IgnoreCtrlEvents = FALSE;
 
 static PHANDLER_ROUTINE* CtrlHandlers = NULL;
 static ULONG NrCtrlHandlers = 0;
+static WCHAR InputExeName[MAX_PATH + 1] = L"";
 
 /* Default Console Control Handler *******************************************/
 
@@ -41,12 +41,10 @@ BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event)
        {
        case CTRL_C_EVENT:
                DPRINT("Ctrl-C Event\n");
-               ExitProcess(0);
                break;
-               
+
        case CTRL_BREAK_EVENT:
                DPRINT("Ctrl-Break Event\n");
-               ExitProcess(0);
                break;
 
        case CTRL_SHUTDOWN_EVENT:
@@ -57,11 +55,11 @@ BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event)
                DPRINT("Ctrl Close Event\n");
                break;
 
-       case CTRL_LOGOFF_EVENT:         
+       case CTRL_LOGOFF_EVENT:
                DPRINT("Ctrl Logoff Event\n");
                break;
        }
-//     ExitProcess((UINT)&ExitCode);
+       ExitProcess(0);
        return TRUE;
 }
 
@@ -82,18 +80,18 @@ SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
                if(IsDebuggerPresent())
                {
                        EXCEPTION_RECORD erException;
-                       erException.ExceptionCode = 
+                       erException.ExceptionCode =
                        (nCode == CTRL_C_EVENT ? DBG_CONTROL_C : DBG_CONTROL_BREAK);
                        erException.ExceptionFlags = 0;
                        erException.ExceptionRecord = NULL;
                        erException.ExceptionAddress = &DefaultConsoleCtrlHandler;
                        erException.NumberParameters = 0;
                        RtlRaiseException(&erException);
-               }               
+               }
                RtlEnterCriticalSection(&ConsoleLock);
 
                if(!(nCode == CTRL_C_EVENT &&
-                       NtCurrentPeb()->ProcessParameters->ProcessGroup & 1))
+                       NtCurrentPeb()->ProcessParameters->ConsoleFlags & 1))
                {
                        for(i = NrCtrlHandlers; i > 0; -- i)
                                if(CtrlHandlers[i - 1](nCode)) break;
@@ -112,12 +110,12 @@ SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
        RtlEnterCriticalSection(&ConsoleLock);
 
        if(!(nCode == CTRL_C_EVENT &&
-               NtCurrentPeb()->ProcessParameters->ProcessGroup & 1))
+               NtCurrentPeb()->ProcessParameters->ConsoleFlags & 1))
        {
        i = NrCtrlHandlers;
        while(i > 0)
                {
-               if (i == 1 && (CodeAndFlag & MINLONG) && 
+               if (i == 1 && (CodeAndFlag & MINLONG) &&
                        (nCode == CTRL_LOGOFF_EVENT || nCode == CTRL_SHUTDOWN_EVENT))
                                break;
 
@@ -150,6 +148,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;
 }
@@ -163,6 +162,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;
 }
@@ -179,6 +179,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;
 }
@@ -193,8 +194,8 @@ DuplicateConsoleHandle (HANDLE      hConsole,
                        BOOL    bInheritHandle,
                        DWORD   dwOptions)
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
+  CSR_API_MESSAGE Request;
+  ULONG CsrRequest;
   NTSTATUS Status;
 
   if (IsConsoleHandle (hConsole) == FALSE)
@@ -202,20 +203,20 @@ DuplicateConsoleHandle (HANDLE    hConsole,
       SetLastError (ERROR_INVALID_PARAMETER);
       return INVALID_HANDLE_VALUE;
     }
-  
-  Request.Type = CSRSS_DUPLICATE_HANDLE;
+
+  CsrRequest = MAKE_CSR_API(DUPLICATE_HANDLE, CSR_NATIVE);
   Request.Data.DuplicateHandleRequest.Handle = hConsole;
-  Request.Data.DuplicateHandleRequest.ProcessId = GetCurrentProcessId();
+  Request.Data.DuplicateHandleRequest.ProcessId = GetTeb()->Cid.UniqueProcess;
   Status = CsrClientCallServer(&Request,
-                              &Reply,
-                              sizeof(CSRSS_API_REQUEST),
-                              sizeof(CSRSS_API_REPLY));
-  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Reply.Status))
+                              NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Request.Status))
     {
       SetLastErrorByStatus(Status);
       return INVALID_HANDLE_VALUE;
     }
-  return Reply.Data.DuplicateHandleReply.Handle;
+  return Request.Data.DuplicateHandleRequest.Handle;
 }
 
 
@@ -228,6 +229,7 @@ ExpungeConsoleCommandHistoryW (DWORD        Unknown0)
       * Undocumented
       */
 {
+  DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -242,6 +244,8 @@ ExpungeConsoleCommandHistoryA (DWORD        Unknown0)
       * Undocumented
       */
 {
+
+  DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -251,14 +255,15 @@ ExpungeConsoleCommandHistoryA (DWORD      Unknown0)
  * @unimplemented
  */
 DWORD STDCALL
-GetConsoleAliasW (DWORD        Unknown0,
-                 DWORD Unknown1,
-                 DWORD Unknown2,
-                 DWORD Unknown3)
+GetConsoleAliasW (LPWSTR       lpSource,
+                 LPWSTR        lpTargetBuffer,
+                 DWORD         TargetBufferLength,
+                 LPWSTR        lpExeName)
      /*
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasW(0x%p, 0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", lpSource, lpTargetBuffer, TargetBufferLength, lpExeName);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -268,16 +273,17 @@ GetConsoleAliasW (DWORD   Unknown0,
  * @unimplemented
  */
 DWORD STDCALL
-GetConsoleAliasA (DWORD        Unknown0,
-                 DWORD Unknown1,
-                 DWORD Unknown2,
-                 DWORD Unknown3)
+GetConsoleAliasA (LPSTR        lpSource,
+                 LPSTR lpTargetBuffer,
+                 DWORD TargetBufferLength,
+                 LPSTR lpExeName)
      /*
       * Undocumented
       */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetConsoleAliasA(0x%p, 0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", lpSource, lpTargetBuffer, TargetBufferLength, lpExeName);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
@@ -285,12 +291,13 @@ GetConsoleAliasA (DWORD   Unknown0,
  * @unimplemented
  */
 DWORD STDCALL
-GetConsoleAliasExesW (DWORD    Unknown0,
-                     DWORD     Unknown1)
+GetConsoleAliasExesW (LPWSTR   lpExeNameBuffer,
+                     DWORD     ExeNameBufferLength)
      /*
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasExesW(0x%p, 0x%x) UNIMPLEMENTED!\n", lpExeNameBuffer, ExeNameBufferLength);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -300,14 +307,15 @@ GetConsoleAliasExesW (DWORD       Unknown0,
  * @unimplemented
  */
 DWORD STDCALL
-GetConsoleAliasExesA (DWORD    Unknown0,
-                     DWORD     Unknown1)
+GetConsoleAliasExesA (LPSTR    lpExeNameBuffer,
+                     DWORD     ExeNameBufferLength)
      /*
       * Undocumented
       */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetConsoleAliasExesA(0x%p, 0x%x) UNIMPLEMENTED!\n", lpExeNameBuffer, ExeNameBufferLength);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
@@ -320,6 +328,7 @@ GetConsoleAliasExesLengthA (VOID)
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasExesLengthA() UNIMPLEMENTED!\n");
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -334,6 +343,7 @@ GetConsoleAliasExesLengthW (VOID)
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasExesLengthW() UNIMPLEMENTED!\n");
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -350,10 +360,11 @@ GetConsoleAliasesW (DWORD Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasesW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
+
 
 /*
  * @unimplemented
@@ -366,6 +377,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;
 }
@@ -375,11 +387,12 @@ GetConsoleAliasesA (DWORD Unknown0,
  * @unimplemented
  */
 DWORD STDCALL
-GetConsoleAliasesLengthW (DWORD Unknown0)
+GetConsoleAliasesLengthW (LPWSTR lpExeName)
      /*
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasesLengthW(0x%p) UNIMPLEMENTED!\n", lpExeName);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -389,11 +402,12 @@ GetConsoleAliasesLengthW (DWORD Unknown0)
  * @unimplemented
  */
 DWORD STDCALL
-GetConsoleAliasesLengthA (DWORD Unknown0)
+GetConsoleAliasesLengthA (LPSTR lpExeName)
      /*
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleAliasesLengthA(0x%p) UNIMPLEMENTED!\n", lpExeName);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -410,6 +424,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;
 }
@@ -426,6 +441,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;
 }
@@ -440,6 +456,7 @@ GetConsoleCommandHistoryLengthW (DWORD      Unknown0)
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleCommandHistoryLengthW(0x%x) UNIMPLEMENTED!\n", Unknown0);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -454,6 +471,7 @@ GetConsoleCommandHistoryLengthA (DWORD      Unknown0)
       * Undocumented
       */
 {
+  DPRINT1("GetConsoleCommandHistoryLengthA(0x%x) UNIMPLEMENTED!\n", Unknown0);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -471,6 +489,7 @@ GetConsoleDisplayMode (LPDWORD lpdwMode)
       * STATUS: Undocumented
       */
 {
+  DPRINT1("GetConsoleDisplayMode(0x%x) UNIMPLEMENTED!\n", lpdwMode);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -488,6 +507,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;
 }
@@ -496,12 +516,14 @@ GetConsoleFontInfo (DWORD Unknown0,
 /*
  * @unimplemented
  */
-DWORD STDCALL
+COORD STDCALL
 GetConsoleFontSize(HANDLE hConsoleOutput,
                   DWORD nFont)
 {
+  COORD Empty = {0, 0};
+  DPRINT1("GetConsoleFontSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return 0;
+  return Empty ;
 }
 
 
@@ -516,30 +538,30 @@ GetConsoleHardwareState (HANDLE   hConsole,
       * Undocumented
       */
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY   Reply;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
   NTSTATUS          Status;
 
-  Request.Type = CSRSS_SETGET_CONSOLE_HW_STATE;
+  CsrRequest = MAKE_CSR_API(SETGET_CONSOLE_HW_STATE, CSR_CONSOLE);
   Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
   Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_GET;
 
   Status = CsrClientCallServer(& Request,
-                              & Reply,
-                              sizeof(CSRSS_API_REQUEST),
-                              sizeof(CSRSS_API_REPLY));
-  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+                              NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
   {
     SetLastErrorByStatus(Status);
     return FALSE;
   }
-  *State = Reply.Data.ConsoleHardwareStateReply.State;
-  return TRUE;  
+  *State = Request.Data.ConsoleHardwareStateRequest.State;
+  return TRUE;
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 DWORD STDCALL
 GetConsoleInputWaitHandle (VOID)
@@ -547,8 +569,19 @@ GetConsoleInputWaitHandle (VOID)
       * Undocumented
       */
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  NTSTATUS Status;
+
+  CsrRequest = MAKE_CSR_API(GET_INPUT_WAIT_HANDLE, CSR_CONSOLE);
+  Status = CsrClientCallServer(&Request, NULL, CsrRequest,
+                               sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+    {
+      SetLastErrorByStatus(Status);
+      return 0;
+    }
+  return (DWORD) Request.Data.GetConsoleInputWaitHandle.InputWaitHandle;
 }
 
 
@@ -560,6 +593,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;
 }
@@ -574,6 +608,7 @@ GetNumberOfConsoleFonts (VOID)
       * Undocumented
       */
 {
+  DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 1; /* FIXME: call csrss.exe */
 }
@@ -589,6 +624,7 @@ InvalidateConsoleDIBits (DWORD      Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("InvalidateConsoleDIBits(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -606,21 +642,20 @@ OpenConsoleW (LPWSTR  wsName,
       * Undocumented
       */
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY   Reply;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
   PHANDLE           phConsole = NULL;
   NTSTATUS          Status = STATUS_SUCCESS;
-  
-  
+
   if(0 == _wcsicmp(wsName, L"CONIN$"))
   {
-    Request.Type = CSRSS_GET_INPUT_HANDLE;
-    phConsole = & Reply.Data.GetInputHandleReply.InputHandle;
+    CsrRequest = MAKE_CSR_API(GET_INPUT_HANDLE, CSR_NATIVE);
+    phConsole = & Request.Data.GetInputHandleRequest.InputHandle;
   }
   else if (0 == _wcsicmp(wsName, L"CONOUT$"))
   {
-    Request.Type = CSRSS_GET_OUTPUT_HANDLE;
-    phConsole = & Reply.Data.GetOutputHandleReply.OutputHandle;
+    CsrRequest = MAKE_CSR_API(GET_OUTPUT_HANDLE, CSR_NATIVE);
+    phConsole = & Request.Data.GetOutputHandleRequest.OutputHandle;
   }
   else
   {
@@ -638,10 +673,10 @@ OpenConsoleW (LPWSTR  wsName,
     return(INVALID_HANDLE_VALUE);
   }
   Status = CsrClientCallServer(& Request,
-                              & Reply,
-                              sizeof(CSRSS_API_REQUEST),
-                              sizeof(CSRSS_API_REPLY));
-  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+                              NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
   {
     SetLastErrorByStatus(Status);
     return INVALID_HANDLE_VALUE;
@@ -659,6 +694,7 @@ SetConsoleCommandHistoryMode (DWORD dwMode)
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleCommandHistoryMode(0x%x) UNIMPLEMENTED!\n", dwMode);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -674,6 +710,7 @@ SetConsoleCursor (DWORD     Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -694,6 +731,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;
 }
@@ -709,6 +747,7 @@ SetConsoleFont (DWORD       Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleFont(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -725,25 +764,25 @@ SetConsoleHardwareState (HANDLE   hConsole,
       * Undocumented
       */
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY   Reply;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
   NTSTATUS          Status;
 
-  Request.Type = CSRSS_SETGET_CONSOLE_HW_STATE;
+  CsrRequest = MAKE_CSR_API(SETGET_CONSOLE_HW_STATE, CSR_CONSOLE);
   Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
   Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_SET;
   Request.Data.ConsoleHardwareStateRequest.State = State;
 
   Status = CsrClientCallServer(& Request,
-                              & Reply,
-                              sizeof(CSRSS_API_REQUEST),
-                              sizeof(CSRSS_API_REPLY));
-  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+                              NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
   {
     SetLastErrorByStatus(Status);
     return FALSE;
   }
-  return TRUE;  
+  return TRUE;
 }
 
 
@@ -759,6 +798,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;
 }
@@ -774,6 +814,7 @@ SetConsoleMaximumWindowSize (DWORD  Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleMaximumWindowSize(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -788,6 +829,7 @@ SetConsoleMenuClose (DWORD  Unknown0)
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -803,6 +845,7 @@ SetConsoleNumberOfCommandsA (DWORD  Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleNumberOfCommandsA(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -818,6 +861,7 @@ SetConsoleNumberOfCommandsW (DWORD  Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("SetConsoleNumberOfCommandsW(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -834,6 +878,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;
 }
@@ -848,6 +893,7 @@ SetLastConsoleEventActive (VOID)
       * Undocumented
       */
 {
+  DPRINT1("SetLastConsoleEventActive() UNIMPLEMENTED!\n");
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
@@ -863,6 +909,7 @@ ShowConsoleCursor (DWORD    Unknown0,
       * Undocumented
       */
 {
+  DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return 0;
 }
@@ -882,23 +929,23 @@ ShowConsoleCursor (DWORD  Unknown0,
 BOOL STDCALL
 VerifyConsoleIoHandle(HANDLE Handle)
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
   NTSTATUS Status;
 
-  Request.Type = CSRSS_VERIFY_HANDLE;
+  CsrRequest = MAKE_CSR_API(VERIFY_HANDLE, CSR_NATIVE);
   Request.Data.VerifyHandleRequest.Handle = Handle;
   Status = CsrClientCallServer(&Request,
-                              &Reply,
-                              sizeof(CSRSS_API_REQUEST),
-                              sizeof(CSRSS_API_REPLY));
+                              NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
   if (!NT_SUCCESS(Status))
     {
       SetLastErrorByStatus(Status);
       return FALSE;
     }
 
-  return (BOOL)NT_SUCCESS(Reply.Status);
+  return (BOOL)NT_SUCCESS(Request.Status);
 }
 
 
@@ -911,6 +958,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;
 }
@@ -925,6 +973,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;
 }
@@ -939,8 +988,8 @@ CloseConsoleHandle(HANDLE Handle)
       * Undocumented
       */
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
   NTSTATUS Status;
 
   if (IsConsoleHandle (Handle) == FALSE)
@@ -949,12 +998,12 @@ CloseConsoleHandle(HANDLE Handle)
       return FALSE;
     }
 
-  Request.Type = CSRSS_CLOSE_HANDLE;
+  CsrRequest = MAKE_CSR_API(CLOSE_HANDLE, CSR_NATIVE);
   Request.Data.CloseHandleRequest.Handle = Handle;
   Status = CsrClientCallServer(&Request,
-                              &Reply,
-                              sizeof(CSRSS_API_REQUEST),
-                              sizeof(CSRSS_API_REPLY));
+                              NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
   if (!NT_SUCCESS(Status))
     {
        SetLastErrorByStatus(Status);
@@ -964,21 +1013,6 @@ CloseConsoleHandle(HANDLE Handle)
   return TRUE;
 }
 
-
-/*
- * internal function
- */
-BOOL STDCALL
-IsConsoleHandle(HANDLE Handle)
-{
-  if ((((ULONG)Handle) & 0x10000003) == 0x3)
-    {
-      return(TRUE);
-    }
-  return(FALSE);
-}
-
-
 /*
  * @implemented
  */
@@ -999,13 +1033,13 @@ GetStdHandle(DWORD nStdHandle)
   switch (nStdHandle)
     {
       case STD_INPUT_HANDLE:
-       return Ppb->hStdInput;
+       return Ppb->StandardInput;
 
       case STD_OUTPUT_HANDLE:
-       return Ppb->hStdOutput;
+       return Ppb->StandardOutput;
 
       case STD_ERROR_HANDLE:
-       return Ppb->hStdError;
+       return Ppb->StandardError;
     }
 
   SetLastError (ERROR_INVALID_PARAMETER);
@@ -1016,7 +1050,7 @@ GetStdHandle(DWORD nStdHandle)
 /*
  * @implemented
  */
-WINBASEAPI BOOL WINAPI
+BOOL WINAPI
 SetStdHandle(DWORD nStdHandle,
             HANDLE hHandle)
      /*
@@ -1037,15 +1071,15 @@ SetStdHandle(DWORD nStdHandle,
   switch (nStdHandle)
     {
       case STD_INPUT_HANDLE:
-       Ppb->hStdInput = hHandle;
+       Ppb->StandardInput = hHandle;
        return TRUE;
 
       case STD_OUTPUT_HANDLE:
-       Ppb->hStdOutput = hHandle;
+       Ppb->StandardOutput = hHandle;
        return TRUE;
 
       case STD_ERROR_HANDLE:
-       Ppb->hStdError = hHandle;
+       Ppb->StandardError = hHandle;
        return TRUE;
     }
 
@@ -1055,70 +1089,197 @@ SetStdHandle(DWORD nStdHandle,
 }
 
 
+static BOOL
+IntWriteConsole(HANDLE hConsoleOutput,
+                PVOID lpBuffer,
+                DWORD nNumberOfCharsToWrite,
+                LPDWORD lpNumberOfCharsWritten,
+                LPVOID lpReserved,
+                BOOL bUnicode)
+{
+  PCSR_API_MESSAGE Request; 
+  ULONG CsrRequest;
+  NTSTATUS Status;
+  USHORT nChars;
+  ULONG SizeBytes, CharSize;
+  DWORD Written = 0;
+
+  CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+  Request = RtlAllocateHeap(RtlGetProcessHeap(), 0, 
+                            max(sizeof(CSR_API_MESSAGE), 
+                                CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) 
+                                  + min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize) * CharSize));
+  if (Request == NULL)
+  {
+    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    return FALSE;
+  }
+
+  CsrRequest = MAKE_CSR_API(WRITE_CONSOLE, CSR_CONSOLE);
+  Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
+  Request->Data.WriteConsoleRequest.Unicode = bUnicode;
+
+  while(nNumberOfCharsToWrite > 0)
+  {
+    nChars = min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize);
+    Request->Data.WriteConsoleRequest.NrCharactersToWrite = nChars;
+
+    SizeBytes = nChars * CharSize;
+
+    memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, SizeBytes);
+
+    Status = CsrClientCallServer(Request,
+                                 NULL,
+                                 CsrRequest,
+                                 max(sizeof(CSR_API_MESSAGE), CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes));
+
+    if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
+    {
+      RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+      SetLastErrorByStatus(Status);
+      return FALSE;
+    }
+
+    nNumberOfCharsToWrite -= nChars;
+    lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
+    Written += Request->Data.WriteConsoleRequest.NrCharactersWritten;
+  }
+
+  if(lpNumberOfCharsWritten != NULL)
+  {
+    *lpNumberOfCharsWritten = Written;
+  }
+  RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+
+  return TRUE;
+}
+
+
 /*--------------------------------------------------------------
  *     WriteConsoleA
  *
  * @implemented
  */
-BOOL STDCALL 
+BOOL STDCALL
 WriteConsoleA(HANDLE hConsoleOutput,
              CONST VOID *lpBuffer,
              DWORD nNumberOfCharsToWrite,
              LPDWORD lpNumberOfCharsWritten,
              LPVOID lpReserved)
 {
-  PCSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
+  return IntWriteConsole(hConsoleOutput,
+                         (PVOID)lpBuffer,
+                         nNumberOfCharsToWrite,
+                         lpNumberOfCharsWritten,
+                         lpReserved,
+                         FALSE);
+}
+
+
+/*--------------------------------------------------------------
+ *     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);
+}
+
+
+static BOOL
+IntReadConsole(HANDLE hConsoleInput,
+               PVOID lpBuffer,
+               DWORD nNumberOfCharsToRead,
+               LPDWORD lpNumberOfCharsRead,
+               LPVOID lpReserved,
+               BOOL bUnicode)
+{
+  PCSR_API_MESSAGE Request; 
+  ULONG CsrRequest;
   NTSTATUS Status;
-  USHORT Size;
-  ULONG MessageSize;
+  ULONG CharSize, CharsRead = 0;
 
-  Request = RtlAllocateHeap(GetProcessHeap(),
-                           HEAP_ZERO_MEMORY,
-                           sizeof(CSRSS_API_REQUEST) + 
-                           CSRSS_MAX_WRITE_CONSOLE_REQUEST);
+  CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+  Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+                            max(sizeof(CSR_API_MESSAGE),
+                                CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) 
+                                  + min(nNumberOfCharsToRead, CSRSS_MAX_READ_CONSOLE / CharSize) * CharSize));
   if (Request == NULL)
+  {
+    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    return FALSE;
+  }
+
+  Request->Status = STATUS_SUCCESS;
+
+  do
+  {
+    if(Request->Status == STATUS_PENDING)
     {
-      SetLastError(ERROR_OUTOFMEMORY);
-      return(FALSE);
+      Status = NtWaitForSingleObject(Request->Data.ReadConsoleRequest.EventHandle, FALSE, 0);
+      if(!NT_SUCCESS(Status))
+      {
+        DPRINT1("Wait for console input failed!\n");
+        break;
+      }
     }
 
-  Request->Type = CSRSS_WRITE_CONSOLE;
-  Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
-  if (lpNumberOfCharsWritten != NULL)
-    *lpNumberOfCharsWritten = nNumberOfCharsToWrite;
-  while (nNumberOfCharsToWrite)
+    CsrRequest = MAKE_CSR_API(READ_CONSOLE, CSR_CONSOLE);
+    Request->Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
+    Request->Data.ReadConsoleRequest.Unicode = bUnicode;
+    Request->Data.ReadConsoleRequest.NrCharactersToRead = min(nNumberOfCharsToRead, CSRSS_MAX_READ_CONSOLE / CharSize);
+    Request->Data.ReadConsoleRequest.nCharsCanBeDeleted = CharsRead;
+    Status = CsrClientCallServer(Request,
+                                 NULL,
+                                 CsrRequest,
+                                 max(sizeof(CSR_API_MESSAGE), 
+                                     CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) 
+                                       + Request->Data.ReadConsoleRequest.NrCharactersToRead * CharSize));
+
+    if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
     {
-      if (nNumberOfCharsToWrite > CSRSS_MAX_WRITE_CONSOLE_REQUEST)
-       {
-         Size = CSRSS_MAX_WRITE_CONSOLE_REQUEST;
-       }
-      else
-       {
-         Size = nNumberOfCharsToWrite;
-       }
-      Request->Data.WriteConsoleRequest.NrCharactersToWrite = Size;
-
-      memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, Size);
+      DPRINT1("CSR returned error in ReadConsole\n");
+      RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+      SetLastErrorByStatus(Status);
+      return FALSE;
+    }
 
-      MessageSize = CSRSS_REQUEST_HEADER_SIZE + 
-       sizeof(CSRSS_WRITE_CONSOLE_REQUEST) + Size;
-      Status = CsrClientCallServer(Request,
-                                  &Reply,
-                                  MessageSize,
-                                  sizeof(CSRSS_API_REPLY));
+    nNumberOfCharsToRead -= Request->Data.ReadConsoleRequest.NrCharactersRead;
+    memcpy((PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)(CharsRead * CharSize)),
+           Request->Data.ReadConsoleRequest.Buffer,
+           Request->Data.ReadConsoleRequest.NrCharactersRead * CharSize);
+    CharsRead += Request->Data.ReadConsoleRequest.NrCharactersRead;
 
-      if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
-       {
-         RtlFreeHeap(GetProcessHeap(), 0, Request);
-         SetLastErrorByStatus(Status);
-         return(FALSE);
-       }
-      nNumberOfCharsToWrite -= Size;
-      lpBuffer += Size;
+    if(Request->Status == STATUS_NOTIFY_CLEANUP)
+    {
+      if(CharsRead > 0)
+      {
+        CharsRead--;
+        nNumberOfCharsToRead++;
+      }
+      Request->Status = STATUS_PENDING;
     }
+  } while(Request->Status == STATUS_PENDING && nNumberOfCharsToRead > 0);
+
+  if(lpNumberOfCharsRead != NULL)
+  {
+    *lpNumberOfCharsRead = CharsRead;
+  }
 
-  RtlFreeHeap(GetProcessHeap(), 0, Request);
+  RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
 
   return TRUE;
 }
@@ -1129,93 +1290,40 @@ WriteConsoleA(HANDLE hConsoleOutput,
  *
  * @implemented
  */
-BOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
-                            LPVOID lpBuffer,
-                            DWORD nNumberOfCharsToRead,
-                            LPDWORD lpNumberOfCharsRead,
-                            LPVOID lpReserved)
+BOOL STDCALL
+ReadConsoleA(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(),
-                    HEAP_ZERO_MEMORY,
-                    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,
+                        FALSE);
+}
+
+
+/*--------------------------------------------------------------
+ *     ReadConsoleW
+ *
+ * @implemented
+ */
+BOOL STDCALL
+ReadConsoleW(HANDLE hConsoleInput,
+             LPVOID lpBuffer,
+             DWORD nNumberOfCharsToRead,
+             LPDWORD lpNumberOfCharsRead,
+             LPVOID lpReserved)
+{
+  return IntReadConsole(hConsoleInput,
+                        lpBuffer,
+                        nNumberOfCharsToRead,
+                        lpNumberOfCharsRead,
+                        lpReserved,
+                        TRUE);
 }
 
 
@@ -1226,31 +1334,32 @@ BOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
  */
 BOOL STDCALL AllocConsole(VOID)
 {
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
    NTSTATUS Status;
    HANDLE hStdError;
 
-   if(NtCurrentPeb()->ProcessParameters->hConsole)
+   if(NtCurrentPeb()->ProcessParameters->ConsoleHandle)
    {
        DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
-       SetLastErrorByStatus (STATUS_OBJECT_EXISTS); 
-       return FALSE;    
+       SetLastErrorByStatus (STATUS_OBJECT_NAME_EXISTS);
+       return FALSE;
    }
 
-   Request.Data.AllocConsoleRequest.CtrlDispatcher = (PCONTROLDISPATCHER) &ConsoleControlDispatcher;
+   Request.Data.AllocConsoleRequest.CtrlDispatcher = ConsoleControlDispatcher;
+   Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE;
 
-   Request.Type = CSRSS_ALLOC_CONSOLE;
-   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+   CsrRequest = MAKE_CSR_API(ALLOC_CONSOLE, CSR_CONSOLE);
+   Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
         SetLastErrorByStatus ( Status );
         return FALSE;
       }
-   NtCurrentPeb()->ProcessParameters->hConsole = Reply.Data.AllocConsoleReply.Console;
-   SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle );
-   SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
-   hStdError = DuplicateConsoleHandle(Reply.Data.AllocConsoleReply.OutputHandle,
+   NtCurrentPeb()->ProcessParameters->ConsoleHandle = Request.Data.AllocConsoleRequest.Console;
+   SetStdHandle( STD_INPUT_HANDLE, Request.Data.AllocConsoleRequest.InputHandle );
+   SetStdHandle( STD_OUTPUT_HANDLE, Request.Data.AllocConsoleRequest.OutputHandle );
+   hStdError = DuplicateConsoleHandle(Request.Data.AllocConsoleRequest.OutputHandle,
                                       0,
                                      TRUE,
                                      DUPLICATE_SAME_ACCESS);
@@ -1269,13 +1378,13 @@ BOOL STDCALL FreeConsole(VOID)
     // AG: I'm not sure if this is correct (what happens to std handles?)
     // but I just tried to reverse what AllocConsole() does...
 
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
    NTSTATUS Status;
 
-   Request.Type = CSRSS_FREE_CONSOLE;
-   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+   CsrRequest = MAKE_CSR_API(FREE_CONSOLE, CSR_CONSOLE);
+   Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
         SetLastErrorByStatus ( Status );
         return FALSE;
@@ -1297,19 +1406,19 @@ GetConsoleScreenBufferInfo(
     PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
     )
 {
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
    NTSTATUS Status;
 
-   Request.Type = CSRSS_SCREEN_BUFFER_INFO;
+   CsrRequest = MAKE_CSR_API(SCREEN_BUFFER_INFO, CSR_CONSOLE);
    Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
-   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+   Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
         SetLastErrorByStatus ( Status );
         return FALSE;
       }
-   *lpConsoleScreenBufferInfo = Reply.Data.ScreenBufferInfoReply.Info;
+   *lpConsoleScreenBufferInfo = Request.Data.ScreenBufferInfoRequest.Info;
    return TRUE;
 }
 
@@ -1326,15 +1435,15 @@ SetConsoleCursorPosition(
     COORD dwCursorPosition
     )
 {
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
    NTSTATUS Status;
 
-   Request.Type = CSRSS_SET_CURSOR;
+   CsrRequest = MAKE_CSR_API(SET_CURSOR, CSR_CONSOLE);
    Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
    Request.Data.SetCursorRequest.Position = dwCursorPosition;
-   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+   Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
         SetLastErrorByStatus ( Status );
         return FALSE;
@@ -1343,6 +1452,45 @@ SetConsoleCursorPosition(
 }
 
 
+static BOOL
+IntFillConsoleOutputCharacter(HANDLE hConsoleOutput,
+                              PVOID cCharacter,
+                              DWORD nLength,
+                              COORD dwWriteCoord,
+                              LPDWORD lpNumberOfCharsWritten,
+                              BOOL bUnicode)
+{
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  NTSTATUS Status;
+
+  CsrRequest = MAKE_CSR_API(FILL_OUTPUT, CSR_CONSOLE);
+  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, NULL,
+                               CsrRequest,
+                               sizeof(CSR_API_MESSAGE));
+
+  if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+
+  if(lpNumberOfCharsWritten != NULL)
+  {
+    *lpNumberOfCharsWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
+  }
+
+  return TRUE;
+}
+
 /*--------------------------------------------------------------
  *     FillConsoleOutputCharacterA
  *
@@ -1357,31 +1505,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
@@ -1393,186 +1529,206 @@ FillConsoleOutputCharacterW(
        LPDWORD         lpNumberOfCharsWritten
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntFillConsoleOutputCharacter(hConsoleOutput,
+                                       &cCharacter,
+                                       nLength,
+                                       dwWriteCoord,
+                                       lpNumberOfCharsWritten,
+                                       TRUE);
 }
 
 
-/*--------------------------------------------------------------
- *     PeekConsoleInputA
- *
- * @implemented
- */
-WINBASEAPI
-BOOL
-WINAPI
-PeekConsoleInputA(
-       HANDLE                  hConsoleInput,
-       PINPUT_RECORD           lpBuffer,
-       DWORD                   nLength,
-       LPDWORD                 lpNumberOfEventsRead
-       )
+static BOOL
+IntPeekConsoleInput(HANDLE hConsoleInput,
+                    PINPUT_RECORD lpBuffer,
+                    DWORD nLength,
+                    LPDWORD lpNumberOfEventsRead,
+                    BOOL bUnicode)
 {
-  PCSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
   NTSTATUS Status;
   PVOID BufferBase;
   PVOID BufferTargetBase;
-  DWORD Size;
-  
+  ULONG Size;
+
   if(lpBuffer == NULL)
   {
     SetLastError(ERROR_INVALID_PARAMETER);
     return FALSE;
   }
-  
+
   Size = nLength * sizeof(INPUT_RECORD);
 
-  Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
+  Status = CsrCaptureParameterBuffer(NULL, Size, &BufferBase, &BufferTargetBase);
   if(!NT_SUCCESS(Status))
   {
     SetLastErrorByStatus(Status);
     return FALSE;
   }
-  
-  Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
-  if(Request == NULL)
-  {
-    CsrReleaseParameterBuffer(BufferBase);
-    SetLastError(ERROR_OUTOFMEMORY);
-    return FALSE;
-  }
-  
-  Request->Type = CSRSS_PEEK_CONSOLE_INPUT;
-  Request->Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
-  Request->Data.PeekConsoleInputRequest.Length = nLength;
-  Request->Data.PeekConsoleInputRequest.InputRecord = (INPUT_RECORD*)BufferTargetBase;
-  
-  Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
-  
-  if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+
+  CsrRequest = MAKE_CSR_API(PEEK_CONSOLE_INPUT, CSR_CONSOLE);
+  Request.Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
+  Request.Data.PeekConsoleInputRequest.Unicode = bUnicode;
+  Request.Data.PeekConsoleInputRequest.Length = nLength;
+  Request.Data.PeekConsoleInputRequest.InputRecord = (INPUT_RECORD*)BufferTargetBase;
+
+  Status = CsrClientCallServer(&Request, 
+                               NULL,
+                               CsrRequest,
+                               sizeof(CSR_API_MESSAGE));
+
+  if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
   {
-    RtlFreeHeap(GetProcessHeap(), 0, Request);
     CsrReleaseParameterBuffer(BufferBase);
     return FALSE;
   }
 
-  memcpy(lpBuffer, BufferBase, sizeof(INPUT_RECORD) * Reply.Data.PeekConsoleInputReply.Length);
+  memcpy(lpBuffer, BufferBase, sizeof(INPUT_RECORD) * Request.Data.PeekConsoleInputRequest.Length);
+
+  CsrReleaseParameterBuffer(BufferBase);
 
   if(lpNumberOfEventsRead != NULL)
-    *lpNumberOfEventsRead = Reply.Data.PeekConsoleInputReply.Length;
+  {
+    *lpNumberOfEventsRead = Request.Data.PeekConsoleInputRequest.Length;
+  }
 
-  RtlFreeHeap(GetProcessHeap(), 0, Request);
-  CsrReleaseParameterBuffer(BufferBase);  
-  
-       return TRUE;
+  return TRUE;
 }
 
-
 /*--------------------------------------------------------------
- *     PeekConsoleInputW
+ *     PeekConsoleInputA
  *
- * @unimplemented
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
-PeekConsoleInputW(
+PeekConsoleInputA(
        HANDLE                  hConsoleInput,
        PINPUT_RECORD           lpBuffer,
        DWORD                   nLength,
        LPDWORD                 lpNumberOfEventsRead
-       )    
+       )
 {
-/* TO DO */
-       return FALSE;
+  return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, FALSE);
 }
 
 
 /*--------------------------------------------------------------
- *     ReadConsoleInputA
+ *     PeekConsoleInputW
  *
  * @implemented
  */
-WINBASEAPI BOOL WINAPI
-ReadConsoleInputA(HANDLE hConsoleInput,
-                 PINPUT_RECORD lpBuffer,
-                 DWORD nLength,
-                 LPDWORD lpNumberOfEventsRead)
+BOOL
+WINAPI
+PeekConsoleInputW(
+       HANDLE                  hConsoleInput,
+       PINPUT_RECORD           lpBuffer,
+       DWORD                   nLength,
+       LPDWORD                 lpNumberOfEventsRead
+       )
+{
+  return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, TRUE);
+}
+
+
+static BOOL
+IntReadConsoleInput(HANDLE hConsoleInput,
+                    PINPUT_RECORD lpBuffer,
+                    DWORD nLength,
+                    LPDWORD lpNumberOfEventsRead,
+                    BOOL bUnicode)
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
-  DWORD NumEventsRead;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  ULONG Read;
   NTSTATUS Status;
 
-  Request.Type = CSRSS_READ_INPUT;
+  CsrRequest = MAKE_CSR_API(READ_INPUT, CSR_CONSOLE);
   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, NULL,
+                                 CsrRequest,
+                                 sizeof(CSR_API_MESSAGE));
+    if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
     {
-      SetLastErrorByStatus(Status);
-      return(FALSE);
-    }
-  
-  while (Status == STATUS_PENDING)
+      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;
+      }
+    }
+    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;
-      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(Request.Data.ReadInputRequest.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 = 0;
-  *lpBuffer = Reply.Data.ReadInputReply.Input;
-  lpBuffer++;
-  NumEventsRead++;
-  
-  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++] = Request.Data.ReadInputRequest.Input;
+      nLength--;
+
+      if(!Request.Data.ReadInputRequest.MoreEvents)
+      {
+        /* nothing more to read, bail */
+        break;
+      }
     }
-  *lpNumberOfEventsRead = NumEventsRead;
-  
-  return TRUE;
+  }
+
+  if(lpNumberOfEventsRead != NULL)
+  {
+    *lpNumberOfEventsRead = Read;
+  }
+
+  return (Read > 0);
+}
+
+
+/*--------------------------------------------------------------
+ *     ReadConsoleInputA
+ *
+ * @implemented
+ */
+BOOL WINAPI
+ReadConsoleInputA(HANDLE hConsoleInput,
+                 PINPUT_RECORD lpBuffer,
+                 DWORD nLength,
+                 LPDWORD lpNumberOfEventsRead)
+{
+  return IntReadConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     ReadConsoleInputW
  *
- * @unimplemented
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleInputW(
@@ -1582,38 +1738,30 @@ ReadConsoleInputW(
        LPDWORD                 lpNumberOfEventsRead
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntReadConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, TRUE);
 }
 
 
-/*--------------------------------------------------------------
- *     WriteConsoleInputA
- *
- * @implemented
- */
-WINBASEAPI
-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_REPLY Reply;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
   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);
@@ -1622,142 +1770,148 @@ WriteConsoleInputA(
     SetLastErrorByStatus(Status);
     return FALSE;
   }
-  
-  Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
-  if(Request == NULL)
+
+  CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_INPUT, CSR_CONSOLE);
+  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, NULL,
+                               CsrRequest,
+                               sizeof(CSR_API_MESSAGE));
+
+  CsrReleaseParameterBuffer(BufferBase);
+
+  if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
   {
-    SetLastError(ERROR_OUTOFMEMORY);
-    CsrReleaseParameterBuffer(BufferBase);
+    SetLastErrorByStatus(Status);
     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;
-  
-  Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
-  if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  if(lpNumberOfEventsWritten != NULL)
   {
-    RtlFreeHeap(GetProcessHeap(), 0, Request);
-    CsrReleaseParameterBuffer(BufferBase);
-    return FALSE;
+    *lpNumberOfEventsWritten = Request.Data.WriteConsoleInputRequest.Length;
   }
-  
-  if(lpNumberOfEventsWritten != NULL)
-    *lpNumberOfEventsWritten = Reply.Data.WriteConsoleInputReply.Length;
-  
-  RtlFreeHeap(GetProcessHeap(), 0, Request);
-  CsrReleaseParameterBuffer(BufferBase);
-  
+
   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
- *     WriteConsoleInputW
+ *     WriteConsoleInputA
  *
- * @unimplemented
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
-WriteConsoleInputW(
+WriteConsoleInputA(
        HANDLE                   hConsoleInput,
        CONST INPUT_RECORD      *lpBuffer,
        DWORD                    nLength,
        LPDWORD                  lpNumberOfEventsWritten
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntWriteConsoleInput(hConsoleInput,
+                              (PINPUT_RECORD)lpBuffer,
+                              nLength,
+                              lpNumberOfEventsWritten,
+                              FALSE);
 }
 
 
 /*--------------------------------------------------------------
- *     ReadConsoleOutputA
+ *     WriteConsoleInputW
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
-ReadConsoleOutputA(
-       HANDLE          hConsoleOutput,
-       PCHAR_INFO      lpBuffer,
-       COORD           dwBufferSize,
-       COORD           dwBufferCoord,
-       PSMALL_RECT     lpReadRegion
+WriteConsoleInputW(
+       HANDLE                   hConsoleInput,
+       CONST INPUT_RECORD      *lpBuffer,
+       DWORD                    nLength,
+       LPDWORD                  lpNumberOfEventsWritten
        )
 {
-  PCSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
+  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)
+{
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
   PVOID BufferBase;
   PVOID BufferTargetBase;
   NTSTATUS Status;
   DWORD Size, SizeX, SizeY;
-  
+
   if(lpBuffer == NULL)
   {
     SetLastError(ERROR_INVALID_PARAMETER);
     return FALSE;
   }
-  
+
   Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
 
-  Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
+  Status = CsrCaptureParameterBuffer(NULL, Size, &BufferBase, &BufferTargetBase);
   if(!NT_SUCCESS(Status))
   {
     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_READ_CONSOLE_OUTPUT;
-  Request->Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
-  Request->Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
-  Request->Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
-  Request->Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
-  Request->Data.ReadConsoleOutputRequest.CharInfo = (PCHAR_INFO)BufferTargetBase;
-  
-  Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
-  if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+
+  CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT, CSR_CONSOLE);
+  Request.Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
+  Request.Data.ReadConsoleOutputRequest.Unicode = bUnicode;
+  Request.Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
+  Request.Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
+  Request.Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
+  Request.Data.ReadConsoleOutputRequest.CharInfo = (PCHAR_INFO)BufferTargetBase;
+
+  Status = CsrClientCallServer(&Request, 
+                               NULL,
+                               CsrRequest,
+                               sizeof(CSR_API_MESSAGE));
+
+  if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
   {
     SetLastErrorByStatus(Status);
-    RtlFreeHeap(GetProcessHeap(), 0, Request);
     CsrReleaseParameterBuffer(BufferBase);
     return FALSE;
   }
-  
-  SizeX = Reply.Data.ReadConsoleOutputReply.ReadRegion.Right - Reply.Data.ReadConsoleOutputReply.ReadRegion.Left + 1;
-  SizeY = Reply.Data.ReadConsoleOutputReply.ReadRegion.Bottom - Reply.Data.ReadConsoleOutputReply.ReadRegion.Top + 1;
-  
+
+  SizeX = Request.Data.ReadConsoleOutputRequest.ReadRegion.Right - Request.Data.ReadConsoleOutputRequest.ReadRegion.Left + 1;
+  SizeY = Request.Data.ReadConsoleOutputRequest.ReadRegion.Bottom - Request.Data.ReadConsoleOutputRequest.ReadRegion.Top + 1;
+
   memcpy(lpBuffer, BufferBase, sizeof(CHAR_INFO) * SizeX * SizeY);
-  *lpReadRegion = Reply.Data.ReadConsoleOutputReply.ReadRegion;
-  
-  RtlFreeHeap(GetProcessHeap(), 0, Request);
+
   CsrReleaseParameterBuffer(BufferBase);
-  
+
+  *lpReadRegion = Request.Data.ReadConsoleOutputRequest.ReadRegion;
+
   return TRUE;
 }
 
-
 /*--------------------------------------------------------------
- *     ReadConsoleOutputW
+ *     ReadConsoleOutputA
  *
- * @unimplemented
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
-ReadConsoleOutputW(
+ReadConsoleOutputA(
        HANDLE          hConsoleOutput,
        PCHAR_INFO      lpBuffer,
        COORD           dwBufferSize,
@@ -1765,24 +1919,40 @@ ReadConsoleOutputW(
        PSMALL_RECT     lpReadRegion
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntReadConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
+                             dwBufferCoord, lpReadRegion, FALSE);
 }
 
+
 /*--------------------------------------------------------------
- *     WriteConsoleOutputA
+ *     ReadConsoleOutputW
  *
  * @implemented
  */
-WINBASEAPI BOOL WINAPI
-WriteConsoleOutputA(HANDLE              hConsoleOutput,
-                   CONST CHAR_INFO     *lpBuffer,
-                   COORD                dwBufferSize,
-                   COORD                dwBufferCoord,
-                   PSMALL_RECT  lpWriteRegion)
+BOOL
+WINAPI
+ReadConsoleOutputW(
+       HANDLE          hConsoleOutput,
+       PCHAR_INFO      lpBuffer,
+       COORD           dwBufferSize,
+       COORD           dwBufferCoord,
+       PSMALL_RECT     lpReadRegion
+       )
+{
+  return IntReadConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
+                             dwBufferCoord, lpReadRegion, TRUE);
+}
+
+
+static BOOL
+IntWriteConsoleOutput(HANDLE hConsoleOutput,
+                      CONST CHAR_INFO *lpBuffer,
+                      COORD dwBufferSize,
+                      COORD dwBufferCoord,
+                      PSMALL_RECT lpWriteRegion,
+                      BOOL bUnicode)
 {
-  PCSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
   NTSTATUS Status;
   ULONG Size;
   PVOID BufferBase;
@@ -1799,47 +1969,57 @@ WriteConsoleOutputA(HANDLE               hConsoleOutput,
       SetLastErrorByStatus(Status);
       return(FALSE);
     }
-  
-  Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, 
-                           sizeof(CSRSS_API_REQUEST));
-  if (Request == NULL)
-    {
-      CsrReleaseParameterBuffer(BufferBase);
-      SetLastError(ERROR_OUTOFMEMORY);
-      return FALSE;
-    }
-  Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT;
-  Request->Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
-  Request->Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
-  Request->Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
-  Request->Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
-  Request->Data.WriteConsoleOutputRequest.CharInfo = 
+
+  CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT, CSR_CONSOLE);
+  Request.Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
+  Request.Data.WriteConsoleOutputRequest.Unicode = bUnicode;
+  Request.Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
+  Request.Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
+  Request.Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
+  Request.Data.WriteConsoleOutputRequest.CharInfo =
     (CHAR_INFO*)BufferTargetBase;
-  
-  Status = CsrClientCallServer(Request, &Reply, 
-                              sizeof(CSRSS_API_REQUEST), 
-                              sizeof(CSRSS_API_REPLY));
-  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+
+  Status = CsrClientCallServer(&Request, 
+                               NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
+
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
     {
       CsrReleaseParameterBuffer(BufferBase);
-      RtlFreeHeap(GetProcessHeap(), 0, Request);
       SetLastErrorByStatus(Status);
       return FALSE;
     }
-      
-  *lpWriteRegion = Reply.Data.WriteConsoleOutputReply.WriteRegion;
-  RtlFreeHeap(GetProcessHeap(), 0, Request);
+
   CsrReleaseParameterBuffer(BufferBase);
+
+  *lpWriteRegion = Request.Data.WriteConsoleOutputRequest.WriteRegion;
+
   return(TRUE);
 }
 
+/*--------------------------------------------------------------
+ *     WriteConsoleOutputA
+ *
+ * @implemented
+ */
+BOOL WINAPI
+WriteConsoleOutputA(HANDLE              hConsoleOutput,
+                   CONST CHAR_INFO     *lpBuffer,
+                   COORD                dwBufferSize,
+                   COORD                dwBufferCoord,
+                   PSMALL_RECT  lpWriteRegion)
+{
+  return IntWriteConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
+                               dwBufferCoord, lpWriteRegion, FALSE);
+}
+
 
 /*--------------------------------------------------------------
  *     WriteConsoleOutputW
  *
- * @unimplemented
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleOutputW(
@@ -1850,8 +2030,80 @@ WriteConsoleOutputW(
        PSMALL_RECT      lpWriteRegion
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntWriteConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
+                               dwBufferCoord, lpWriteRegion, TRUE);
+}
+
+
+static BOOL
+IntReadConsoleOutputCharacter(HANDLE hConsoleOutput,
+                              PVOID lpCharacter,
+                              DWORD nLength,
+                              COORD dwReadCoord,
+                              LPDWORD lpNumberOfCharsRead,
+                              BOOL bUnicode)
+{
+  PCSR_API_MESSAGE Request; ULONG CsrRequest;
+  NTSTATUS Status;
+  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;
+
+  Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+                            max(sizeof(CSR_API_MESSAGE),
+                                CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) 
+                                  + min (nChars, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
+  if (Request == NULL)
+  {
+    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    return FALSE;
+  }
+
+  CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
+  Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
+  Request->Data.ReadConsoleOutputCharRequest.Unicode = bUnicode;
+  Request->Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
+
+  while(nLength > 0)
+  {
+    DWORD BytesRead;
+
+    Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead = min(nLength, nChars);
+    SizeBytes = Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead * CharSize;
+
+    Status = CsrClientCallServer(Request,
+                                 NULL,
+                                 CsrRequest,
+                                 max (sizeof(CSR_API_MESSAGE), 
+                                      CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) + SizeBytes));
+    if(!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
+    {
+      RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+      SetLastErrorByStatus(Status);
+      break;
+    }
+
+    BytesRead = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize;
+    memcpy(lpCharacter, Request->Data.ReadConsoleOutputCharRequest.String, BytesRead);
+    lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)BytesRead);
+    CharsRead += Request->Data.ReadConsoleOutputCharRequest.CharsRead;
+    nLength -= Request->Data.ReadConsoleOutputCharRequest.CharsRead;
+
+    Request->Data.ReadConsoleOutputCharRequest.ReadCoord = Request->Data.ReadConsoleOutputCharRequest.EndCoord;
+  }
+
+  if(lpNumberOfCharsRead != NULL)
+  {
+    *lpNumberOfCharsRead = CharsRead;
+  }
+
+  RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+
+  return TRUE;
 }
 
 
@@ -1860,7 +2112,6 @@ WriteConsoleOutputW(
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputCharacterA(
@@ -1871,65 +2122,20 @@ ReadConsoleOutputCharacterA(
        LPDWORD         lpNumberOfCharsRead
        )
 {
-  CSRSS_API_REQUEST Request;
-  PCSRSS_API_REPLY Reply;
-  NTSTATUS Status;
-  DWORD Size;
-
-  Reply = RtlAllocateHeap(GetProcessHeap(),
-                         HEAP_ZERO_MEMORY,
-                         sizeof(CSRSS_API_REPLY) + CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR);
-  if (Reply == NULL)
-    {
-      SetLastError(ERROR_OUTOFMEMORY);
-      return(FALSE);
-    }
-
-  if (lpNumberOfCharsRead != NULL)
-    *lpNumberOfCharsRead = nLength;
-
-  Request.Type = CSRSS_READ_CONSOLE_OUTPUT_CHAR;
-  Request.Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
-  Request.Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
-
-  while (nLength != 0)
-    {
-      if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR)
-       Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR;
-      else
-       Size = nLength;
-
-      Request.Data.ReadConsoleOutputCharRequest.NumCharsToRead = Size;
-
-      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);
-       }
-
-      memcpy(lpCharacter, &Reply->Data.ReadConsoleOutputCharReply.String[0], Size);
-      lpCharacter += Size;
-      nLength -= Size;
-      Request.Data.ReadConsoleOutputCharRequest.ReadCoord = Reply->Data.ReadConsoleOutputCharReply.EndCoord;
-    }
-
-  RtlFreeHeap(GetProcessHeap(), 0, Reply);
-
-  return(TRUE);
+  return IntReadConsoleOutputCharacter(hConsoleOutput,
+                                       (PVOID)lpCharacter,
+                                       nLength,
+                                       dwReadCoord,
+                                       lpNumberOfCharsRead,
+                                       FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *      ReadConsoleOutputCharacterW
  *
- * @unimplemented
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputCharacterW(
@@ -1940,8 +2146,12 @@ ReadConsoleOutputCharacterW(
        LPDWORD         lpNumberOfCharsRead
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntReadConsoleOutputCharacter(hConsoleOutput,
+                                       (PVOID)lpCharacter,
+                                       nLength,
+                                       dwReadCoord,
+                                       lpNumberOfCharsRead,
+                                       TRUE);
 }
 
 
@@ -1950,7 +2160,6 @@ ReadConsoleOutputCharacterW(
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputAttribute(
@@ -1961,112 +2170,151 @@ ReadConsoleOutputAttribute(
        LPDWORD         lpNumberOfAttrsRead
        )
 {
-  CSRSS_API_REQUEST Request;
-  PCSRSS_API_REPLY Reply;
+  PCSR_API_MESSAGE Request; ULONG CsrRequest;
   NTSTATUS Status;
-  DWORD Size, i;
-  
-  Reply = RtlAllocateHeap(GetProcessHeap(),
-                         HEAP_ZERO_MEMORY,
-                         sizeof(CSRSS_API_REPLY) + CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB);
-  if (Reply == NULL)
-    {
-      SetLastError(ERROR_OUTOFMEMORY);
-      return(FALSE);
-    }
+  DWORD Size;
 
   if (lpNumberOfAttrsRead != NULL)
     *lpNumberOfAttrsRead = nLength;
 
-  Request.Type = CSRSS_READ_CONSOLE_OUTPUT_ATTRIB;
-  Request.Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
-  Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
+  Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+                            max(sizeof(CSR_API_MESSAGE),
+                                CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
+                                  + min (nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
+  if (Request == NULL)
+  {
+    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    return FALSE;
+  }
+
+  CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
+  Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
+  Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
 
   while (nLength != 0)
     {
-      if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB)
-       Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB;
+      if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD))
+       Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WCHAR);
       else
        Size = nLength;
 
-      Request.Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
+      Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
 
-      Status = CsrClientCallServer(&Request,
-                                  Reply,
-                                  sizeof(CSRSS_API_REQUEST),
-                                  sizeof(CSRSS_API_REPLY) + Size);
-      if (!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
+      Status = CsrClientCallServer(Request,
+                                  NULL,
+                                  CsrRequest,
+                                   max (sizeof(CSR_API_MESSAGE),
+                                        CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
+      if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
        {
-         RtlFreeHeap(GetProcessHeap(), 0, Reply);
+          RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
          SetLastErrorByStatus(Status);
          return(FALSE);
        }
 
-      // Convert CHARs to WORDs
-      for(i = 0; i < Size; ++i)
-        *lpAttribute++ = Reply->Data.ReadConsoleOutputAttribReply.String[i];
-      
+      memcpy(lpAttribute, Request->Data.ReadConsoleOutputAttribRequest.Attribute, Size * sizeof(WORD));
+      lpAttribute += Size;
       nLength -= Size;
-      Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = Reply->Data.ReadConsoleOutputAttribReply.EndCoord;
+      Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = Request->Data.ReadConsoleOutputAttribRequest.EndCoord;
     }
 
-  RtlFreeHeap(GetProcessHeap(), 0, Reply);
+  RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
 
   return(TRUE);
 }
 
 
+static BOOL
+IntWriteConsoleOutputCharacter(HANDLE hConsoleOutput,
+                               PVOID lpCharacter,
+                               DWORD nLength,
+                               COORD dwWriteCoord,
+                               LPDWORD lpNumberOfCharsWritten,
+                               BOOL bUnicode)
+{
+  PCSR_API_MESSAGE Request; ULONG CsrRequest;
+  NTSTATUS Status;
+  ULONG SizeBytes, CharSize, nChars;
+  DWORD Written = 0;
+
+  CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+
+  nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize);
+  SizeBytes = nChars * CharSize;
+
+  Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+                            max (sizeof(CSR_API_MESSAGE),
+                                 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) 
+                                   + min (nChars, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
+  if (Request == NULL)
+  {
+    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    return FALSE;
+  }
+
+  CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
+  Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
+  Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode;
+  Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
+
+  while(nLength > 0)
+  {
+    DWORD BytesWrite;
+
+    Request->Data.WriteConsoleOutputCharRequest.Length = min(nLength, nChars);
+    BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize;
+
+    memcpy(Request->Data.WriteConsoleOutputCharRequest.String, lpCharacter, BytesWrite);
+
+    Status = CsrClientCallServer(Request, 
+                                 NULL,
+                                 CsrRequest,
+                                 max (sizeof(CSR_API_MESSAGE),
+                                      CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + BytesWrite));
+
+    if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
+    {
+      RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+      SetLastErrorByStatus(Status);
+      return FALSE;
+    }
+
+    nLength -= Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
+    lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)(Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten * CharSize));
+    Written += Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
+
+    Request->Data.WriteConsoleOutputCharRequest.Coord = Request->Data.WriteConsoleOutputCharRequest.EndCoord;
+  }
+
+  if(lpNumberOfCharsWritten != NULL)
+  {
+    *lpNumberOfCharsWritten = Written;
+  }
+
+  RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+
+  return TRUE;
+}
+
+
 /*--------------------------------------------------------------
  *     WriteConsoleOutputCharacterA
  *
  * @implemented
  */
-WINBASEAPI BOOL WINAPI
+BOOL WINAPI
 WriteConsoleOutputCharacterA(HANDLE            hConsoleOutput,
                             LPCSTR             lpCharacter,
                             DWORD              nLength,
                             COORD              dwWriteCoord,
                             LPDWORD            lpNumberOfCharsWritten)
 {
-  PCSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
-  NTSTATUS Status;
-  WORD Size;
-  
-  Request = RtlAllocateHeap(GetProcessHeap(),
-                           HEAP_ZERO_MEMORY,
-                           sizeof(CSRSS_API_REQUEST) + 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;
-      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 ); 
-  return TRUE;
+  return IntWriteConsoleOutputCharacter(hConsoleOutput,
+                                        (PVOID)lpCharacter,
+                                        nLength,
+                                        dwWriteCoord,
+                                        lpNumberOfCharsWritten,
+                                        FALSE);
 }
 
 
@@ -2075,61 +2323,19 @@ WriteConsoleOutputCharacterA(HANDLE             hConsoleOutput,
  *
  * @implemented
  */
-WINBASEAPI BOOL WINAPI
+BOOL WINAPI
 WriteConsoleOutputCharacterW(HANDLE            hConsoleOutput,
                             LPCWSTR            lpCharacter,
                             DWORD              nLength,
                             COORD              dwWriteCoord,
                             LPDWORD            lpNumberOfCharsWritten)
 {
-  PCSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
-  NTSTATUS Status;
-  WORD Size;
-  
-  Request = RtlAllocateHeap(GetProcessHeap(),
-                           HEAP_ZERO_MEMORY,
-                           sizeof(CSRSS_API_REQUEST) + 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);
 }
 
 
@@ -2138,7 +2344,6 @@ WriteConsoleOutputCharacterW(HANDLE               hConsoleOutput,
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleOutputAttribute(
@@ -2149,44 +2354,50 @@ WriteConsoleOutputAttribute(
        LPDWORD          lpNumberOfAttrsWritten
        )
 {
-   PCSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
+   PCSR_API_MESSAGE Request; ULONG CsrRequest;
    NTSTATUS Status;
    WORD Size;
-   int c;
-
-   Request = RtlAllocateHeap(GetProcessHeap(),
-                      HEAP_ZERO_MEMORY,
-                      sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB);
-   if( !Request )
-     {
-       SetLastError( ERROR_OUTOFMEMORY );
-       return FALSE;
-     }
-   Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB;
+
+   Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+                             max (sizeof(CSR_API_MESSAGE),
+                                  CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
+                                    + min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
+   if (Request == NULL)
+   {
+      SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+      return FALSE;
+   }
+
+   CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
    Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
    Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
    if( lpNumberOfAttrsWritten )
       *lpNumberOfAttrsWritten = nLength;
    while( nLength )
       {
-        Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB : nLength;
+        Size = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD));
         Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
-        for( c = 0; c < ( Size * 2 ); c++ )
-          Request->Data.WriteConsoleOutputAttribRequest.String[c] = (char)lpAttribute[c];
-        Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + (Size * 2), sizeof( CSRSS_API_REPLY ) );
-        if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+         memcpy(Request->Data.WriteConsoleOutputAttribRequest.Attribute, lpAttribute, Size * sizeof(WORD));
+
+        Status = CsrClientCallServer( Request, 
+                                       NULL, 
+                                       CsrRequest, 
+                                       max (sizeof(CSR_API_MESSAGE),
+                                            CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
+                                            
+        if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request->Status ) )
            {
-              RtlFreeHeap( GetProcessHeap(), 0, Request );
+               RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
               SetLastErrorByStatus ( Status );
               return FALSE;
            }
         nLength -= Size;
         lpAttribute += Size;
-        Request->Data.WriteConsoleOutputAttribRequest.Coord = Reply.Data.WriteConsoleOutputAttribReply.EndCoord;
+        Request->Data.WriteConsoleOutputAttribRequest.Coord = Request->Data.WriteConsoleOutputAttribRequest.EndCoord;
       }
-   
-   RtlFreeHeap( GetProcessHeap(), 0, Request );
+
+   RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+
    return TRUE;
 }
 
@@ -2196,7 +2407,6 @@ WriteConsoleOutputAttribute(
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 FillConsoleOutputAttribute(
@@ -2207,17 +2417,17 @@ FillConsoleOutputAttribute(
        LPDWORD         lpNumberOfAttrsWritten
        )
 {
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
    NTSTATUS Status;
 
-   Request.Type = CSRSS_FILL_OUTPUT_ATTRIB;
+   CsrRequest = MAKE_CSR_API(FILL_OUTPUT_ATTRIB, CSR_CONSOLE);
    Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
    Request.Data.FillOutputAttribRequest.Attribute = wAttribute;
    Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
    Request.Data.FillOutputAttribRequest.Length = nLength;
-   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+   Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
         SetLastErrorByStatus ( Status );
         return FALSE;
@@ -2233,7 +2443,6 @@ FillConsoleOutputAttribute(
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetConsoleMode(
@@ -2241,19 +2450,19 @@ GetConsoleMode(
        LPDWORD         lpMode
        )
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
-  NTSTATUS Status;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
   
-  Request.Type = CSRSS_GET_CONSOLE_MODE;
+  NTSTATUS Status;
+
+  CsrRequest = MAKE_CSR_API(GET_CONSOLE_MODE, CSR_CONSOLE);
   Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
-  Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-  if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+  Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+  if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
        SetLastErrorByStatus ( Status );
        return FALSE;
       }
-  *lpMode = Reply.Data.GetConsoleModeReply.ConsoleMode;
+  *lpMode = Request.Data.GetConsoleModeRequest.ConsoleMode;
   return TRUE;
 }
 
@@ -2263,7 +2472,6 @@ GetConsoleMode(
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetNumberOfConsoleInputEvents(
@@ -2271,27 +2479,27 @@ GetNumberOfConsoleInputEvents(
        LPDWORD         lpNumberOfEvents
        )
 {
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
    NTSTATUS Status;
+
    if(lpNumberOfEvents == NULL)
    {
       SetLastError(ERROR_INVALID_PARAMETER);
       return FALSE;
    }
-   
-   Request.Type = CSRSS_GET_NUM_INPUT_EVENTS;
+
+   CsrRequest = MAKE_CSR_API(GET_NUM_INPUT_EVENTS, CSR_CONSOLE);
    Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
-   Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
-   if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+   Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
+   if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
    {
       SetLastErrorByStatus(Status);
       return FALSE;
    }
-   
-   *lpNumberOfEvents = Reply.Data.GetNumInputEventsReply.NumInputEvents;
-   
+
+   *lpNumberOfEvents = Request.Data.GetNumInputEventsRequest.NumInputEvents;
+
        return TRUE;
 }
 
@@ -2301,19 +2509,16 @@ GetNumberOfConsoleInputEvents(
  *
  * @unimplemented
  */
-WINBASEAPI
 COORD
 WINAPI
 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;
 }
 
 
@@ -2322,7 +2527,6 @@ GetLargestConsoleWindowSize(
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetConsoleCursorInfo(
@@ -2330,20 +2534,20 @@ GetConsoleCursorInfo(
        PCONSOLE_CURSOR_INFO    lpConsoleCursorInfo
        )
 {
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
    NTSTATUS Status;
 
-   Request.Type = CSRSS_GET_CURSOR_INFO;
+   CsrRequest = MAKE_CSR_API(GET_CURSOR_INFO, CSR_CONSOLE);
    Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
-   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+   Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
 
-   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
         SetLastErrorByStatus ( Status );
         return FALSE;
       }
-   *lpConsoleCursorInfo = Reply.Data.GetCursorInfoReply.Info;
+   *lpConsoleCursorInfo = Request.Data.GetCursorInfoRequest.Info;
    return TRUE;
 }
 
@@ -2353,15 +2557,15 @@ GetConsoleCursorInfo(
  *
  * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetNumberOfConsoleMouseButtons(
        LPDWORD         lpNumberOfMouseButtons
        )
 {
-/* TO DO */
-       return FALSE;
+  DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
@@ -2370,7 +2574,6 @@ GetNumberOfConsoleMouseButtons(
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleMode(
@@ -2378,15 +2581,23 @@ SetConsoleMode(
        DWORD           dwMode
        )
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
-  NTSTATUS Status;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
   
-  Request.Type = CSRSS_SET_CONSOLE_MODE;
+  NTSTATUS Status;
+
+  if (!IsConsoleHandle (hConsoleHandle))
+  {
+    DPRINT("SetConsoleMode was called with a non console handle\n");
+    SetLastError (ERROR_INVALID_PARAMETER);
+    return FALSE;
+  }
+
+
+  CsrRequest = MAKE_CSR_API(SET_CONSOLE_MODE, CSR_CONSOLE);
   Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
   Request.Data.SetConsoleModeRequest.Mode = dwMode;
-  Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-  if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+  Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+  if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
        SetLastErrorByStatus ( Status );
        return FALSE;
@@ -2400,21 +2611,20 @@ SetConsoleMode(
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleActiveScreenBuffer(
        HANDLE          hConsoleOutput
        )
 {
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
    NTSTATUS Status;
 
-   Request.Type = CSRSS_SET_SCREEN_BUFFER;
+   CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER, CSR_CONSOLE);
    Request.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
-   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+   Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
         SetLastErrorByStatus ( Status );
         return FALSE;
@@ -2428,21 +2638,20 @@ SetConsoleActiveScreenBuffer(
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 FlushConsoleInputBuffer(
        HANDLE          hConsoleInput
        )
 {
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
    NTSTATUS Status;
 
-   Request.Type = CSRSS_FLUSH_INPUT_BUFFER;
+   CsrRequest = MAKE_CSR_API(FLUSH_INPUT_BUFFER, CSR_CONSOLE);
    Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
-   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+   Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
         SetLastErrorByStatus ( Status );
         return FALSE;
@@ -2456,7 +2665,6 @@ FlushConsoleInputBuffer(
  *
  * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleScreenBufferSize(
@@ -2464,8 +2672,9 @@ SetConsoleScreenBufferSize(
        COORD           dwSize
        )
 {
-/* TO DO */
-       return FALSE;
+  DPRINT1("SetConsoleScreenBufferSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, dwSize);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /*--------------------------------------------------------------
@@ -2473,7 +2682,6 @@ SetConsoleScreenBufferSize(
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleCursorInfo(
@@ -2481,16 +2689,16 @@ SetConsoleCursorInfo(
        CONST CONSOLE_CURSOR_INFO       *lpConsoleCursorInfo
        )
 {
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
    NTSTATUS Status;
 
-   Request.Type = CSRSS_SET_CURSOR_INFO;
+   CsrRequest = MAKE_CSR_API(SET_CURSOR_INFO, CSR_CONSOLE);
    Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
    Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
-   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+   Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
 
-   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
         SetLastErrorByStatus ( Status );
         return FALSE;
@@ -2499,12 +2707,54 @@ SetConsoleCursorInfo(
 }
 
 
+static BOOL
+IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
+                             PSMALL_RECT lpScrollRectangle,
+                             PSMALL_RECT lpClipRectangle,
+                             COORD dwDestinationOrigin,
+                             PCHAR_INFO lpFill,
+                             BOOL bUnicode)
+{
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  NTSTATUS Status;
+
+  CsrRequest = MAKE_CSR_API(SCROLL_CONSOLE_SCREEN_BUFFER, CSR_CONSOLE);
+  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;
+  }
+  else
+  {
+    Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
+  }
+
+  Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
+  Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
+  Status = CsrClientCallServer(&Request, NULL,
+                               CsrRequest,
+                               sizeof(CSR_API_MESSAGE));
+
+  if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+
 /*--------------------------------------------------------------
  *     ScrollConsoleScreenBufferA
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ScrollConsoleScreenBufferA(
@@ -2515,43 +2765,20 @@ ScrollConsoleScreenBufferA(
        CONST CHAR_INFO         *lpFill
        )
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
-  NTSTATUS Status;
-
-  Request.Type = CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER;
-  Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
-  Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
-
-  if (lpClipRectangle != NULL)
-    {
-  Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
-  Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
-    }
-  else
-    {
-  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 ) );
-
-  if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
-    {
-      SetLastErrorByStatus ( Status );
-      return FALSE;
-    }
-  return TRUE;
+  return IntScrollConsoleScreenBuffer(hConsoleOutput,
+                                      (PSMALL_RECT)lpScrollRectangle,
+                                      (PSMALL_RECT)lpClipRectangle,
+                                      dwDestinationOrigin,
+                                      (PCHAR_INFO)lpFill,
+                                      FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     ScrollConsoleScreenBufferW
  *
- * @unimplemented
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ScrollConsoleScreenBufferW(
@@ -2562,8 +2789,12 @@ ScrollConsoleScreenBufferW(
        CONST CHAR_INFO         *lpFill
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntScrollConsoleScreenBuffer(hConsoleOutput,
+                                      (PSMALL_RECT)lpScrollRectangle,
+                                      (PSMALL_RECT)lpClipRectangle,
+                                      dwDestinationOrigin,
+                                      (PCHAR_INFO)lpFill,
+                                      TRUE);
 }
 
 
@@ -2572,7 +2803,6 @@ ScrollConsoleScreenBufferW(
  *
  * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleWindowInfo(
@@ -2581,8 +2811,9 @@ SetConsoleWindowInfo(
        CONST SMALL_RECT        *lpConsoleWindow
        )
 {
-/* TO DO */
-       return FALSE;
+  DPRINT1("SetConsoleWindowInfo(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bAbsolute, lpConsoleWindow);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
@@ -2591,7 +2822,6 @@ SetConsoleWindowInfo(
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleTextAttribute(
@@ -2599,15 +2829,15 @@ SetConsoleTextAttribute(
         WORD            wAttributes
         )
 {
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
    NTSTATUS Status;
 
-   Request.Type = CSRSS_SET_ATTRIB;
+   CsrRequest = MAKE_CSR_API(SET_ATTRIB, CSR_CONSOLE);
    Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
    Request.Data.SetAttribRequest.Attrib = wAttributes;
-   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+   Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
         SetLastErrorByStatus ( Status );
         return FALSE;
@@ -2627,11 +2857,17 @@ AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
   else
     {
       NrCtrlHandlers++;
-      CtrlHandlers = 
-       RtlReAllocateHeap(RtlGetProcessHeap(),
-                          HEAP_ZERO_MEMORY,
-                          (PVOID)CtrlHandlers,
-                          NrCtrlHandlers * sizeof(PHANDLER_ROUTINE)); 
+      if (CtrlHandlers == NULL)
+        {
+          CtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
+                                         NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
+        }
+      else
+        {
+          CtrlHandlers = RtlReAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
+                                           (PVOID)CtrlHandlers,
+                                           NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
+        }
       if (CtrlHandlers == NULL)
        {
          NrCtrlHandlers = 0;
@@ -2661,9 +2897,9 @@ RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
          if ( ((void*)(CtrlHandlers[i])) == (void*)HandlerRoutine)
            {
              NrCtrlHandlers--;
-             memmove(CtrlHandlers + i, CtrlHandlers + i + 1, 
+             memmove(CtrlHandlers + i, CtrlHandlers + i + 1,
                      (NrCtrlHandlers - i) * sizeof(PHANDLER_ROUTINE));
-             CtrlHandlers = 
+             CtrlHandlers =
                RtlReAllocateHeap(RtlGetProcessHeap(),
                                  HEAP_ZERO_MEMORY,
                                  (PVOID)CtrlHandlers,
@@ -2679,7 +2915,7 @@ RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
 /*
  * @implemented
  */
-WINBASEAPI BOOL WINAPI
+BOOL WINAPI
 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
                      BOOL Add)
 {
@@ -2704,13 +2940,14 @@ SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
  *
  * @unimplemented
  */
-WINBASEAPI BOOL WINAPI
+BOOL WINAPI
 GenerateConsoleCtrlEvent(
        DWORD           dwCtrlEvent,
        DWORD           dwProcessGroupId
        )
 {
-  /* TO DO */
+  DPRINT1("GenerateConsoleCtrlEvent(0x%x, 0x%x) UNIMPLEMENTED!\n", dwCtrlEvent, dwProcessGroupId);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
 
@@ -2720,7 +2957,6 @@ GenerateConsoleCtrlEvent(
  *
  * @implemented
  */
-WINBASEAPI
 DWORD
 WINAPI
 GetConsoleTitleW(
@@ -2728,8 +2964,7 @@ GetConsoleTitleW(
        DWORD           nSize
        )
 {
-   CSRSS_API_REQUEST Request;
-   PCSRSS_API_REPLY Reply;
+   PCSR_API_MESSAGE Request; ULONG CsrRequest;
    NTSTATUS Status;
    HANDLE hConsole;
 
@@ -2739,39 +2974,43 @@ GetConsoleTitleW(
       return 0;
    }
 
-   Reply = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
-   if(Reply == NULL)
+   Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+                             CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
+   if (Request == NULL)
    {
-      CloseHandle(hConsole);   
-      SetLastError(ERROR_OUTOFMEMORY);
-      return 0;
+      SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+      return FALSE;
    }
 
-   Request.Type = CSRSS_GET_TITLE;
-   Request.Data.GetTitleRequest.ConsoleHandle = hConsole;
-   
-   Status = CsrClientCallServer(&Request, Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
+   CsrRequest = MAKE_CSR_API(GET_TITLE, CSR_CONSOLE);
+   Request->Data.GetTitleRequest.ConsoleHandle = hConsole;
+
+   Status = CsrClientCallServer(Request, 
+                                NULL, 
+                                CsrRequest, 
+                                CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
    CloseHandle(hConsole);
-   if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Reply->Status)))
+   if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request->Status)))
    {
+      RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
       SetLastErrorByStatus(Status);
-      RtlFreeHeap(GetProcessHeap(), 0, Reply);
       return 0;
    }
-   
-   if(nSize * sizeof(WCHAR) < Reply->Data.GetTitleReply.Length)
+
+   if(nSize * sizeof(WCHAR) < Request->Data.GetTitleRequest.Length)
    {
-      wcsncpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title, nSize - 1);
+      wcsncpy(lpConsoleTitle, Request->Data.GetTitleRequest.Title, nSize - 1);
       lpConsoleTitle[nSize--] = L'\0';
    }
    else
-   {  
-      nSize = Reply->Data.GetTitleReply.Length / sizeof (WCHAR);
-      wcscpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title);
+   {
+      nSize = Request->Data.GetTitleRequest.Length / sizeof (WCHAR);
+      wcscpy(lpConsoleTitle, Request->Data.GetTitleRequest.Title);
       lpConsoleTitle[nSize] = L'\0';
    }
-   
-   RtlFreeHeap(GetProcessHeap(), 0, Reply);
+
+   RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+
    return nSize;
 }
 
@@ -2783,7 +3022,6 @@ GetConsoleTitleW(
  *
  * @implemented
  */
-WINBASEAPI
 DWORD
 WINAPI
 GetConsoleTitleA(
@@ -2794,18 +3032,18 @@ GetConsoleTitleA(
        wchar_t WideTitle [CSRSS_MAX_TITLE_LENGTH];
        DWORD   nWideTitle = sizeof WideTitle;
        DWORD   nWritten;
-       
+
        if (!lpConsoleTitle || !nSize) return 0;
        nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle );
        if (!nWideTitle) return 0;
 
        if ( (nWritten = WideCharToMultiByte(
-               CP_ACP,                 // ANSI code page 
-               0,                      // performance and mapping flags 
-               (LPWSTR) WideTitle,     // address of wide-character string 
-               nWideTitle,             // number of characters in string 
-               lpConsoleTitle,         // address of buffer for new string 
-               nSize,                  // size of buffer 
+               CP_ACP,                 // ANSI code page
+               0,                      // performance and mapping flags
+               (LPWSTR) WideTitle,     // address of wide-character string
+               nWideTitle,             // number of characters in string
+               lpConsoleTitle,         // address of buffer for new string
+               nSize,                  // size of buffer
                NULL,                   // FAST
                NULL                    // FAST
                )))
@@ -2823,15 +3061,13 @@ GetConsoleTitleA(
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleTitleW(
        LPCWSTR         lpConsoleTitle
        )
 {
-  PCSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
+  PCSR_API_MESSAGE Request; ULONG CsrRequest;
   NTSTATUS Status;
   unsigned int c;
   HANDLE hConsole;
@@ -2841,58 +3077,55 @@ SetConsoleTitleW(
   {
      return FALSE;
   }
-  
-  Request = RtlAllocateHeap(GetProcessHeap(),
-                           HEAP_ZERO_MEMORY,
-                           sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
+
+  Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+                            max (sizeof(CSR_API_MESSAGE),
+                                 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + 
+                                 min (wcslen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR)));
   if (Request == NULL)
-    {
-      CloseHandle(hConsole);
-      SetLastError(ERROR_OUTOFMEMORY);
-      return(FALSE);
-    }
-  
-  Request->Type = CSRSS_SET_TITLE;
+  {
+     SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+     return FALSE;
+  }
+
+  CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE);
   Request->Data.SetTitleRequest.Console = hConsole;
-  
+
   for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
     Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
-  // add null
-  Request->Data.SetTitleRequest.Title[c] = 0;
-  Request->Data.SetTitleRequest.Length = c;  
+  Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR);
   Status = CsrClientCallServer(Request,
-                              &Reply,
-                              sizeof(CSRSS_API_REQUEST) + 
-                              c * sizeof(WCHAR),
-                              sizeof(CSRSS_API_REPLY));
+                              NULL,
+                               CsrRequest,
+                              max (sizeof(CSR_API_MESSAGE), CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR)));
   CloseHandle(hConsole);
-  if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Request->Status ) )
     {
-      RtlFreeHeap( GetProcessHeap(), 0, Request );
+      RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
       SetLastErrorByStatus (Status);
       return(FALSE);
     }
-  RtlFreeHeap( GetProcessHeap(), 0, Request );
+
+  RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+
   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleTitleA
- *     
+ *
  *     19990204 EA     Added
  *
  * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleTitleA(
        LPCSTR          lpConsoleTitle
        )
 {
-  PCSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
+  PCSR_API_MESSAGE Request; ULONG CsrRequest;
   NTSTATUS Status;
   unsigned int c;
   HANDLE hConsole;
@@ -2902,126 +3135,38 @@ SetConsoleTitleA(
   {
      return FALSE;
   }
-  
-  Request = RtlAllocateHeap(GetProcessHeap(),
-                           HEAP_ZERO_MEMORY,
-                           sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
+
+  Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+                            max (sizeof(CSR_API_MESSAGE),
+                                 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + 
+                                   min (strlen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR)));
   if (Request == NULL)
-    {
-      CloseHandle(hConsole);
-      SetLastError(ERROR_OUTOFMEMORY);
-      return(FALSE);
-    }
-  
-  Request->Type = CSRSS_SET_TITLE;
+  {
+     SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+     return FALSE;
+  }
+
+  CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE);
   Request->Data.SetTitleRequest.Console = hConsole;
-  
+
   for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
     Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
-  // add null
-  Request->Data.SetTitleRequest.Title[c] = 0;
-  Request->Data.SetTitleRequest.Length = c;
+  Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR);
   Status = CsrClientCallServer(Request,
-                              &Reply,
-                              sizeof(CSRSS_API_REQUEST) + 
-                              c * sizeof(WCHAR),
-                              sizeof(CSRSS_API_REPLY));
+                              NULL,
+                               CsrRequest,
+                              max (sizeof(CSR_API_MESSAGE), CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR)));
   CloseHandle(hConsole);
-  if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Request->Status ) )
     {
-      RtlFreeHeap( GetProcessHeap(), 0, Request );
+      RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
       SetLastErrorByStatus (Status);
       return(FALSE);
     }
-  RtlFreeHeap( GetProcessHeap(), 0, Request );
-  return TRUE;
-}
-
-
-/*--------------------------------------------------------------
- *     ReadConsoleW
- *
- * @unimplemented
- */
-WINBASEAPI
-BOOL
-WINAPI
-ReadConsoleW(
-       HANDLE          hConsoleInput,
-       LPVOID          lpBuffer,
-       DWORD           nNumberOfCharsToRead,
-       LPDWORD         lpNumberOfCharsRead,
-       LPVOID          lpReserved
-       )
-{
-/* --- TO DO --- */
-       return FALSE;
-}
-
-
-/*--------------------------------------------------------------
- *     WriteConsoleW
- *
- * @unimplemented
- */
-WINBASEAPI
-BOOL
-WINAPI
-WriteConsoleW(
-       HANDLE           hConsoleOutput,
-       CONST VOID      *lpBuffer,
-       DWORD            nNumberOfCharsToWrite,
-       LPDWORD          lpNumberOfCharsWritten,
-       LPVOID           lpReserved
-       )
-{
-#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(RtlGetProcessHeap(), 0, Request);
 
-  RtlFreeHeap(GetProcessHeap(),
-             0,
-             Request);
-
-  if (!NT_SUCCESS(Status))
-    {
-      return(FALSE);
-    }
-
-  if (lpNumberOfCharsWritten != NULL)
-    {
-      *lpNumberOfCharsWritten = 
-         Reply.Data.WriteConsoleReply.NrCharactersWritten;
-    }
-
-  return(TRUE);
-#endif
-  return(FALSE);
+  return TRUE;
 }
 
 
@@ -3030,7 +3175,6 @@ WriteConsoleW(
  *
  * @implemented
  */
-WINBASEAPI
 HANDLE
 WINAPI
 CreateConsoleScreenBuffer(
@@ -3042,96 +3186,181 @@ CreateConsoleScreenBuffer(
        )
 {
    // FIXME: don't ignore access, share mode, and security
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
    NTSTATUS Status;
 
-   Request.Type = CSRSS_CREATE_SCREEN_BUFFER;
-   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+   CsrRequest = MAKE_CSR_API(CREATE_SCREEN_BUFFER, CSR_CONSOLE);
+   Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
         SetLastErrorByStatus ( Status );
         return FALSE;
       }
-   return Reply.Data.CreateScreenBufferReply.OutputHandle;
+   return Request.Data.CreateScreenBufferRequest.OutputHandle;
 }
 
 
 /*--------------------------------------------------------------
  *     GetConsoleCP
  *
- * @unimplemented
+ * @implemented
  */
-WINBASEAPI
 UINT
 WINAPI
 GetConsoleCP( VOID )
 {
-/* --- TO DO --- */
-       return CP_OEMCP; /* FIXME */
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  NTSTATUS          Status;
+
+  CsrRequest = MAKE_CSR_API(GET_CONSOLE_CP, CSR_CONSOLE);
+  Status = CsrClientCallServer(&Request, NULL, CsrRequest,
+                               sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+  {
+    SetLastErrorByStatus (Status);
+    return 0;
+  }
+  return Request.Data.GetConsoleCodePage.CodePage;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleCP
  *
- * @unimplemented
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleCP(
        UINT            wCodePageID
        )
 {
-/* --- TO DO --- */
-       return FALSE;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  NTSTATUS          Status;
+
+  CsrRequest = MAKE_CSR_API(SET_CONSOLE_CP, CSR_CONSOLE);
+  Request.Data.SetConsoleCodePage.CodePage = wCodePageID;
+  Status = CsrClientCallServer(&Request, NULL, CsrRequest,
+                               sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+  {
+    SetLastErrorByStatus (Status);
+  }
+  return NT_SUCCESS(Status);
 }
 
 
 /*--------------------------------------------------------------
  *     GetConsoleOutputCP
  *
- * @unimplemented
+ * @implemented
  */
-WINBASEAPI
 UINT
 WINAPI
 GetConsoleOutputCP( VOID )
 {
-/* --- TO DO --- */
-       return 0; /* FIXME */
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  NTSTATUS          Status;
+
+  CsrRequest = MAKE_CSR_API(GET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
+  Status = CsrClientCallServer(&Request, NULL, CsrRequest,
+                               sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+  {
+    SetLastErrorByStatus (Status);
+    return 0;
+  }
+  return Request.Data.GetConsoleOutputCodePage.CodePage;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleOutputCP
  *
- * @unimplemented
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleOutputCP(
        UINT            wCodePageID
        )
 {
-/* --- TO DO --- */
-       return FALSE;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  NTSTATUS          Status;
+
+  CsrRequest = MAKE_CSR_API(SET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
+  Request.Data.SetConsoleOutputCodePage.CodePage = wCodePageID;
+  Status = CsrClientCallServer(&Request, NULL, CsrRequest,
+                               sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+  {
+    SetLastErrorByStatus (Status);
+  }
+  return NT_SUCCESS(Status);
 }
 
 
 /*--------------------------------------------------------------
  *     GetConsoleProcessList
  *
- * @unimplemented
+ * @implemented
  */
 DWORD STDCALL
 GetConsoleProcessList(LPDWORD lpdwProcessList,
-                  DWORD dwProcessCount)
+                      DWORD dwProcessCount)
 {
-   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-   return 0;
+  PCSR_API_MESSAGE Request; ULONG CsrRequest;
+  ULONG nProcesses;
+  NTSTATUS Status;
+
+  if(lpdwProcessList == NULL || dwProcessCount == 0)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return 0;
+  }
+
+  Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+                            max (sizeof(CSR_API_MESSAGE),
+                                 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)
+                                   + min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD)) * sizeof(DWORD)));
+  if (Request == NULL)
+  {
+     SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+     return FALSE;
+  }
+                                   
+  CsrRequest = MAKE_CSR_API(GET_PROCESS_LIST, CSR_CONSOLE);
+  Request->Data.GetProcessListRequest.nMaxIds = min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD));
+
+  Status = CsrClientCallServer(Request, 
+                               NULL,
+                               CsrRequest,
+                               max (sizeof(CSR_API_MESSAGE),
+                                    CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST) 
+                                      + Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
+  {
+    RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+    SetLastErrorByStatus (Status);
+    nProcesses = 0;
+  }
+  else
+  {
+    nProcesses = Request->Data.GetProcessListRequest.nProcessIdsCopied;
+    if(dwProcessCount >= nProcesses)
+    {
+      memcpy(lpdwProcessList, Request->Data.GetProcessListRequest.ProcessId, nProcesses * sizeof(DWORD));
+    }
+  }
+
+  RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+
+  return nProcesses;
 }
 
 
@@ -3144,8 +3373,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;
 }
 
 
@@ -3155,11 +3385,12 @@ GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
  *
  * @unimplemented
  */
-BOOL STDCALL 
+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;
 }
 
 /*--------------------------------------------------------------
@@ -3170,52 +3401,316 @@ AttachConsole(DWORD dwProcessId)
 HWND STDCALL
 GetConsoleWindow (VOID)
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY   Reply;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
   NTSTATUS          Status;
-   
-  Request.Data.ConsoleWindowRequest.ConsoleHandle =
-    OpenConsoleW (L"CONOUT$", (GENERIC_READ|GENERIC_WRITE), FALSE, OPEN_EXISTING);
-  if (INVALID_HANDLE_VALUE == Request.Data.ConsoleWindowRequest.ConsoleHandle)
-  {
-    return (HWND) NULL;
-  }
-  Request.Type = CSRSS_GET_CONSOLE_WINDOW;
-  Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-  if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Reply.Status))
+
+  CsrRequest = MAKE_CSR_API(GET_CONSOLE_WINDOW, CSR_CONSOLE);
+  Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+  if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Request.Status))
   {
     SetLastErrorByStatus (Status);
     return (HWND) NULL;
   }
-  return Reply.Data.ConsoleWindowReply.WindowHandle;
+  return Request.Data.GetConsoleWindowRequest.WindowHandle;
 }
 
 
 /*--------------------------------------------------------------
- *     GetConsoleWindow
+ *     SetConsoleIcon
+ *
  * @implemented
  */
 BOOL STDCALL SetConsoleIcon(HICON hicon)
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY   Reply;
-  NTSTATUS          Status;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
   
-  Request.Data.ConsoleSetWindowIconRequest.ConsoleHandle =
-    OpenConsoleW (L"CONOUT$", (GENERIC_READ|GENERIC_WRITE), FALSE, OPEN_EXISTING);
-  if (INVALID_HANDLE_VALUE == Request.Data.ConsoleSetWindowIconRequest.ConsoleHandle)
+  NTSTATUS          Status;
+
+  CsrRequest = MAKE_CSR_API(SET_CONSOLE_ICON, CSR_CONSOLE);
+  Request.Data.SetConsoleIconRequest.WindowIcon = hicon;
+  Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+  {
+    SetLastErrorByStatus (Status);
+    return FALSE;
+  }
+  return NT_SUCCESS(Status);
+}
+
+
+/*--------------------------------------------------------------
+ *     SetConsoleInputExeNameW
+ *
+ * @implemented
+ */
+BOOL STDCALL
+SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
+{
+  BOOL Ret = FALSE;
+  int lenName = lstrlenW(lpInputExeName);
+
+  if(lenName < 1 ||
+     lenName > (int)(sizeof(InputExeName) / sizeof(InputExeName[0])) - 1)
   {
+    /* Fail if string is empty or too long */
+    SetLastError(ERROR_INVALID_PARAMETER);
     return FALSE;
   }
-  Request.Type = CSRSS_SET_CONSOLE_ICON;
-  Request.Data.ConsoleSetWindowIconRequest.WindowIcon = hicon;
-  Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+
+  RtlEnterCriticalSection(&ConsoleLock);
+  /* wrap copying into SEH as we may copy from invalid buffer and in case of an
+     exception the console lock would've never been released, which would cause
+     further calls (if the exception was handled by the caller) to recursively
+     acquire the lock... */
+  _SEH_TRY
   {
-    SetLastErrorByStatus (Status);
+    RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
+    InputExeName[lenName] = L'\0';
+    Ret = TRUE;
+  }
+  _SEH_HANDLE
+  {
+    lenName = 0;
+    SetLastErrorByStatus(_SEH_GetExceptionCode());
+  }
+  _SEH_END;
+  RtlLeaveCriticalSection(&ConsoleLock);
+
+  return Ret;
+}
+
+
+/*--------------------------------------------------------------
+ *     SetConsoleInputExeNameA
+ *
+ * @implemented
+ */
+BOOL STDCALL
+SetConsoleInputExeNameA(LPCSTR lpInputExeName)
+{
+  ANSI_STRING InputExeNameA;
+  UNICODE_STRING InputExeNameU;
+  NTSTATUS Status;
+  BOOL Ret;
+
+  RtlInitAnsiString(&InputExeNameA, lpInputExeName);
+
+  if(InputExeNameA.Length < sizeof(InputExeNameA.Buffer[0]) ||
+     InputExeNameA.Length >= (sizeof(InputExeName) / sizeof(InputExeName[0])) - 1)
+  {
+    /* Fail if string is empty or too long */
+    SetLastError(ERROR_INVALID_PARAMETER);
     return FALSE;
   }
-  return NT_SUCCESS(Status);
+
+  Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, TRUE);
+  if(NT_SUCCESS(Status))
+  {
+    Ret = SetConsoleInputExeNameW(InputExeNameU.Buffer);
+    RtlFreeUnicodeString(&InputExeNameU);
+  }
+  else
+  {
+    SetLastErrorByStatus(Status);
+    Ret = FALSE;
+  }
+
+  return Ret;
+}
+
+
+/*--------------------------------------------------------------
+ *     GetConsoleInputExeNameW
+ *
+ * @implemented
+ */
+DWORD STDCALL
+GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
+{
+  int lenName;
+
+  RtlEnterCriticalSection(&ConsoleLock);
+
+  lenName = lstrlenW(InputExeName);
+  if(lenName >= (int)nBufferLength)
+  {
+    /* buffer is not large enough, return the required size */
+    RtlLeaveCriticalSection(&ConsoleLock);
+    return lenName + 1;
+  }
+
+  /* wrap copying into SEH as we may copy to invalid buffer and in case of an
+     exception the console lock would've never been released, which would cause
+     further calls (if the exception was handled by the caller) to recursively
+     acquire the lock... */
+  _SEH_TRY
+  {
+    RtlCopyMemory(lpBuffer, InputExeName, (lenName + 1) * sizeof(WCHAR));
+  }
+  _SEH_HANDLE
+  {
+    lenName = 0;
+    SetLastErrorByStatus(_SEH_GetExceptionCode());
+  }
+  _SEH_END;
+
+  RtlLeaveCriticalSection(&ConsoleLock);
+
+  return lenName;
+}
+
+
+/*--------------------------------------------------------------
+ *     GetConsoleInputExeNameA
+ *
+ * @implemented
+ */
+DWORD STDCALL
+GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
+{
+  WCHAR *Buffer;
+  DWORD Ret;
+
+  if(nBufferLength > 0)
+  {
+    Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nBufferLength * sizeof(WCHAR));
+    if(Buffer == NULL)
+    {
+      SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+      return 0;
+    }
+  }
+  else
+  {
+    Buffer = NULL;
+  }
+
+  Ret = GetConsoleInputExeNameW(nBufferLength, Buffer);
+  if(nBufferLength > 0)
+  {
+    if(Ret > 0)
+    {
+      UNICODE_STRING BufferU;
+      ANSI_STRING BufferA;
+
+      RtlInitUnicodeString(&BufferU, Buffer);
+
+      BufferA.Length = 0;
+      BufferA.MaximumLength = nBufferLength;
+      BufferA.Buffer = lpBuffer;
+
+      RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
+    }
+
+    RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+  }
+
+  return Ret;
+}
+
+
+/*--------------------------------------------------------------
+ *  GetConsoleHistoryInfo
+ *
+ * @unimplemented
+ */
+BOOL STDCALL
+GetConsoleHistoryInfo(PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
+{
+    DPRINT1("GetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+
+/*--------------------------------------------------------------
+ *  SetConsoleHistoryInfo
+ *
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleHistoryInfo(IN PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
+{
+    DPRINT1("SetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+
+/*--------------------------------------------------------------
+ *  GetConsoleOriginalTitleW
+ *
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleOriginalTitleW(OUT LPWSTR lpConsoleTitle,
+                         IN DWORD nSize)
+{
+    DPRINT1("GetConsoleOriginalTitleW(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle, nSize);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return 0;
+}
+
+
+/*--------------------------------------------------------------
+ *  GetConsoleOriginalTitleA
+ *
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleOriginalTitleA(OUT LPSTR lpConsoleTitle,
+                         IN DWORD nSize)
+{
+    DPRINT1("GetConsoleOriginalTitleA(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle, nSize);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return 0;
+}
+
+
+/*--------------------------------------------------------------
+ *  GetConsoleScreenBufferInfoEx
+ *
+ * @unimplemented
+ */
+BOOL STDCALL
+GetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
+                             OUT PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx)
+{
+    DPRINT1("GetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, lpConsoleScreenBufferInfoEx);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+
+/*--------------------------------------------------------------
+ *  SetConsoleScreenBufferInfoEx
+ *
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
+                             IN PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx)
+{
+    DPRINT1("SetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, lpConsoleScreenBufferInfoEx);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+
+/*--------------------------------------------------------------
+ *  GetCurrentConsoleFontEx
+ *
+ * @unimplemented
+ */
+BOOL STDCALL
+GetCurrentConsoleFontEx(IN HANDLE hConsoleOutput,
+                        IN BOOL bMaximumWindow,
+                        OUT PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx)
+{
+    DPRINT1("GetCurrentConsoleFontEx(0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFontEx);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 /* EOF */