- Allocate the csrss request buffer from heap if the necessary length is larger than...
[reactos.git] / reactos / lib / kernel32 / misc / console.c
index ec0a66c..cfa9ec1 100644 (file)
@@ -1,10 +1,11 @@
-/* $Id: console.c,v 1.31 2001/03/31 01:17:29 dwelch 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:      ???
+ * PROGRAMMER:      James Tabor
+ *                     <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
  * UPDATE HISTORY:
  *     199901?? ??     Created
  *     19990204 EA     SetConsoleTitleA
 
 /* INCLUDES ******************************************************************/
 
-#include <ddk/ntddk.h>
-#include <ddk/ntddblue.h>
-#include <windows.h>
-#include <assert.h>
-#include <wchar.h>
-
-#include <csrss/csrss.h>
-#include <ntdll/csr.h>
+#include <k32.h>
 
 #define NDEBUG
-#include <kernel32/kernel32.h>
-#include <kernel32/error.h>
+#include "../include/debug.h"
+
+extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);
+extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag);
+extern RTL_CRITICAL_SECTION ConsoleLock;
+extern BOOL WINAPI IsDebuggerPresent(VOID);
+
+
+/* GLOBALS *******************************************************************/
+
+static BOOL IgnoreCtrlEvents = FALSE;
+
+static PHANDLER_ROUTINE* CtrlHandlers = NULL;
+static ULONG NrCtrlHandlers = 0;
+static WCHAR InputExeName[MAX_PATH + 1] = L"";
+
+/* Default Console Control Handler *******************************************/
+
+BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event)
+{
+       switch(Event)
+       {
+       case CTRL_C_EVENT:
+               DPRINT("Ctrl-C Event\n");
+               break;
+
+       case CTRL_BREAK_EVENT:
+               DPRINT("Ctrl-Break Event\n");
+               break;
+
+       case CTRL_SHUTDOWN_EVENT:
+               DPRINT("Ctrl Shutdown Event\n");
+               break;
+
+       case CTRL_CLOSE_EVENT:
+               DPRINT("Ctrl Close Event\n");
+               break;
+
+       case CTRL_LOGOFF_EVENT:
+               DPRINT("Ctrl Logoff Event\n");
+               break;
+       }
+       ExitProcess(0);
+       return TRUE;
+}
+
+
+__declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag)
+{
+DWORD nExitCode = 0;
+DWORD nCode = CodeAndFlag & MAXLONG;
+UINT i;
+
+SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
+
+       switch(nCode)
+       {
+       case CTRL_C_EVENT:
+       case CTRL_BREAK_EVENT:
+       {
+               if(IsDebuggerPresent())
+               {
+                       EXCEPTION_RECORD erException;
+                       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->ConsoleFlags & 1))
+               {
+                       for(i = NrCtrlHandlers; i > 0; -- i)
+                               if(CtrlHandlers[i - 1](nCode)) break;
+               }
+               RtlLeaveCriticalSection(&ConsoleLock);
+               ExitThread(0);
+       }
+       case CTRL_CLOSE_EVENT:
+       case CTRL_LOGOFF_EVENT:
+       case CTRL_SHUTDOWN_EVENT:
+               break;
+
+       default: ExitThread(0);
+       }
+
+       RtlEnterCriticalSection(&ConsoleLock);
+
+       if(!(nCode == CTRL_C_EVENT &&
+               NtCurrentPeb()->ProcessParameters->ConsoleFlags & 1))
+       {
+       i = NrCtrlHandlers;
+       while(i > 0)
+               {
+               if (i == 1 && (CodeAndFlag & MINLONG) &&
+                       (nCode == CTRL_LOGOFF_EVENT || nCode == CTRL_SHUTDOWN_EVENT))
+                               break;
+
+                       if(CtrlHandlers[i - 1](nCode))
+                       {
+                               switch(nCode)
+                               {
+                                       case CTRL_CLOSE_EVENT:
+                                       case CTRL_LOGOFF_EVENT:
+                                       case CTRL_SHUTDOWN_EVENT:
+                                               nExitCode = CodeAndFlag;
+                               }
+                               break;
+                       }
+                       --i;
+               }
+       }
+       RtlLeaveCriticalSection(&ConsoleLock);
+       ExitThread(nExitCode);
+}
+
 
 /* FUNCTIONS *****************************************************************/
 
+/*
+ * @unimplemented
+ */
 BOOL STDCALL
-AddConsoleAliasA (DWORD a0,
-                 DWORD a1,
-                 DWORD a2)
+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;
 }
 
+
+/*
+ * @unimplemented
+ */
 BOOL STDCALL
-AddConsoleAliasW (DWORD a0,
-                 DWORD a1,
-                 DWORD a2)
+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;
 }
 
+
+/*
+ * @unimplemented
+ */
 BOOL STDCALL
 ConsoleMenuControl (HANDLE     hConsole,
                    DWORD       Unknown1,
                    DWORD       Unknown2)
+     /*
+      * Undocumented
+      */
 {
+  DPRINT1("ConsoleMenuControl(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsole, Unknown1, Unknown2);
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
   return FALSE;
 }
 
-BOOL
-STDCALL
-DuplicateConsoleHandle (
-       HANDLE  hConsole,
-       DWORD   Unknown1,
-       DWORD   Unknown2,
-       DWORD   Unknown3
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
-}
 
-DWORD
-STDCALL
-ExpungeConsoleCommandHistoryW (
-       DWORD   Unknown0
-       )
+/*
+ * @implemented
+ */
+HANDLE STDCALL
+DuplicateConsoleHandle (HANDLE hConsole,
+                       DWORD   dwDesiredAccess,
+                       BOOL    bInheritHandle,
+                       DWORD   dwOptions)
+{
+  CSR_API_MESSAGE Request;
+  ULONG CsrRequest;
+  NTSTATUS Status;
+
+  if (IsConsoleHandle (hConsole) == FALSE)
+    {
+      SetLastError (ERROR_INVALID_PARAMETER);
+      return INVALID_HANDLE_VALUE;
+    }
+
+  CsrRequest = MAKE_CSR_API(DUPLICATE_HANDLE, CSR_NATIVE);
+  Request.Data.DuplicateHandleRequest.Handle = hConsole;
+  Request.Data.DuplicateHandleRequest.ProcessId = GetTeb()->Cid.UniqueProcess;
+  Status = CsrClientCallServer(&Request,
+                              NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Request.Status))
+    {
+      SetLastErrorByStatus(Status);
+      return INVALID_HANDLE_VALUE;
+    }
+  return Request.Data.DuplicateHandleRequest.Handle;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+ExpungeConsoleCommandHistoryW (DWORD   Unknown0)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-DWORD
-STDCALL
-ExpungeConsoleCommandHistoryA (
-       DWORD   Unknown0
-       )
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+ExpungeConsoleCommandHistoryA (DWORD   Unknown0)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
-}
 
-DWORD
-STDCALL
-GetConsoleAliasW (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2,
-       DWORD   Unknown3
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-DWORD
-STDCALL
-GetConsoleAliasA (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2,
-       DWORD   Unknown3
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+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;
 }
 
 
-
-DWORD
-STDCALL
-GetConsoleAliasExesW (
-       DWORD   Unknown0,
-       DWORD   Unknown1
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasA (LPSTR        lpSource,
+                 LPSTR lpTargetBuffer,
+                 DWORD TargetBufferLength,
+                 LPSTR lpExeName)
+     /*
+      * Undocumented
+      */
+{
+  DPRINT1("GetConsoleAliasA(0x%p, 0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", lpSource, lpTargetBuffer, TargetBufferLength, lpExeName);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-
-DWORD
-STDCALL
-GetConsoleAliasExesA (
-       DWORD   Unknown0,
-       DWORD   Unknown1
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasExesW (LPWSTR   lpExeNameBuffer,
+                     DWORD     ExeNameBufferLength)
+     /*
+      * Undocumented
+      */
+{
+  DPRINT1("GetConsoleAliasExesW(0x%p, 0x%x) UNIMPLEMENTED!\n", lpExeNameBuffer, ExeNameBufferLength);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasExesA (LPSTR    lpExeNameBuffer,
+                     DWORD     ExeNameBufferLength)
+     /*
+      * Undocumented
+      */
+{
+  DPRINT1("GetConsoleAliasExesA(0x%p, 0x%x) UNIMPLEMENTED!\n", lpExeNameBuffer, ExeNameBufferLength);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
 
-DWORD
-STDCALL
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
 GetConsoleAliasExesLengthA (VOID)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetConsoleAliasExesLengthA() UNIMPLEMENTED!\n");
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-
-DWORD
-STDCALL
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
 GetConsoleAliasExesLengthW (VOID)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetConsoleAliasExesLengthW() UNIMPLEMENTED!\n");
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-
-DWORD
-STDCALL
-GetConsoleAliasesW (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2
-       )
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasesW (DWORD      Unknown0,
+                   DWORD       Unknown1,
+                   DWORD       Unknown2)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetConsoleAliasesW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-
-DWORD
-STDCALL
-GetConsoleAliasesA (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2
-       )
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasesA (DWORD      Unknown0,
+                   DWORD       Unknown1,
+                   DWORD       Unknown2)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetConsoleAliasesA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-
-DWORD
-STDCALL
-GetConsoleAliasesLengthW (
-       DWORD Unknown0
-       )
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasesLengthW (LPWSTR lpExeName)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetConsoleAliasesLengthW(0x%p) UNIMPLEMENTED!\n", lpExeName);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-
-DWORD
-STDCALL
-GetConsoleAliasesLengthA (
-       DWORD Unknown0
-       )
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasesLengthA (LPSTR lpExeName)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetConsoleAliasesLengthA(0x%p) UNIMPLEMENTED!\n", lpExeName);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-DWORD
-STDCALL
-GetConsoleCommandHistoryW (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleCommandHistoryW (DWORD       Unknown0,
+                          DWORD        Unknown1,
+                          DWORD        Unknown2)
+     /*
+      * Undocumented
+      */
+{
+  DPRINT1("GetConsoleCommandHistoryW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-DWORD
-STDCALL
-GetConsoleCommandHistoryA (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleCommandHistoryA (DWORD       Unknown0,
+                          DWORD        Unknown1,
+                          DWORD        Unknown2)
+     /*
+      * Undocumented
+      */
+{
+  DPRINT1("GetConsoleCommandHistoryA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-DWORD
-STDCALL
-GetConsoleCommandHistoryLengthW (
-       DWORD   Unknown0
-       )
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleCommandHistoryLengthW (DWORD Unknown0)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetConsoleCommandHistoryLengthW(0x%x) UNIMPLEMENTED!\n", Unknown0);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-DWORD
-STDCALL
-GetConsoleCommandHistoryLengthA (
-       DWORD   Unknown0
-       )
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleCommandHistoryLengthA (DWORD Unknown0)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetConsoleCommandHistoryLengthA(0x%x) UNIMPLEMENTED!\n", Unknown0);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
-
-DWORD
-STDCALL
-GetConsoleDisplayMode (
-       DWORD   Unknown0
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleDisplayMode (LPDWORD lpdwMode)
+     /*
+      * FUNCTION: Get the console display mode
+      * ARGUMENTS:
+      *      lpdwMode - Address of variable that receives the current value
+      *                 of display mode
+      * STATUS: Undocumented
+      */
+{
+  DPRINT1("GetConsoleDisplayMode(0x%x) UNIMPLEMENTED!\n", lpdwMode);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-DWORD
-STDCALL
-GetConsoleFontInfo (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2,
-       DWORD   Unknown3
-       )
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleFontInfo (DWORD      Unknown0,
+                   DWORD       Unknown1,
+                   DWORD       Unknown2,
+                   DWORD       Unknown3)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetConsoleFontInfo(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-DWORD
-STDCALL
-GetConsoleFontSize (
-       DWORD   Unknown0,
-       DWORD   Unknown1
-       )
+/*
+ * @unimplemented
+ */
+COORD STDCALL
+GetConsoleFontSize(HANDLE hConsoleOutput,
+                  DWORD nFont)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  COORD Empty = {0, 0};
+  DPRINT1("GetConsoleFontSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return Empty ;
 }
 
 
-DWORD
-STDCALL
-GetConsoleHardwareState (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetConsoleHardwareState (HANDLE        hConsole,
+                        DWORD  Flags,
+                        PDWORD State)
+     /*
+      * Undocumented
+      */
+{
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  NTSTATUS          Status;
+
+  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,
+                              NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+  *State = Request.Data.ConsoleHardwareStateRequest.State;
+  return TRUE;
 }
 
 
-DWORD
-STDCALL
+/*
+ * @implemented
+ */
+DWORD STDCALL
 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;
 }
 
-DWORD
-STDCALL
-GetCurrentConsoleFont (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2
-       )
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetCurrentConsoleFont(HANDLE hConsoleOutput,
+                     BOOL bMaximumWindow,
+                     PCONSOLE_FONT_INFO lpConsoleCurrentFont)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  DPRINT1("GetCurrentConsoleFont(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFont);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
-int
-STDCALL
+
+/*
+ * @unimplemented
+ */
+ULONG STDCALL
 GetNumberOfConsoleFonts (VOID)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 1; /* FIXME: call csrss.exe */
+  DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 1; /* FIXME: call csrss.exe */
 }
 
-DWORD
-STDCALL
-InvalidateConsoleDIBits (
-       DWORD   Unknown0,
-       DWORD   Unknown1
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
-}
 
-DWORD
-STDCALL
-OpenConsoleW (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2,
-       DWORD   Unknown3
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+InvalidateConsoleDIBits (DWORD Unknown0,
+                        DWORD  Unknown1)
+     /*
+      * Undocumented
+      */
+{
+  DPRINT1("InvalidateConsoleDIBits(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
-WINBOOL
-STDCALL
-SetConsoleCommandHistoryMode (
-       DWORD   dwMode
-       )
+
+/*
+ * @unimplemented
+ */
+HANDLE STDCALL
+OpenConsoleW (LPWSTR  wsName,
+             DWORD   dwDesiredAccess,
+             BOOL    bInheritHandle,
+             DWORD   dwCreationDistribution)
+     /*
+      * Undocumented
+      */
+{
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  PHANDLE           phConsole = NULL;
+  NTSTATUS          Status = STATUS_SUCCESS;
+
+  if(0 == _wcsicmp(wsName, L"CONIN$"))
+  {
+    CsrRequest = MAKE_CSR_API(GET_INPUT_HANDLE, CSR_NATIVE);
+    phConsole = & Request.Data.GetInputHandleRequest.InputHandle;
+  }
+  else if (0 == _wcsicmp(wsName, L"CONOUT$"))
+  {
+    CsrRequest = MAKE_CSR_API(GET_OUTPUT_HANDLE, CSR_NATIVE);
+    phConsole = & Request.Data.GetOutputHandleRequest.OutputHandle;
+  }
+  else
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return(INVALID_HANDLE_VALUE);
+  }
+  if ((GENERIC_READ|GENERIC_WRITE) != dwDesiredAccess)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return(INVALID_HANDLE_VALUE);
+  }
+  if (OPEN_EXISTING != dwCreationDistribution)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return(INVALID_HANDLE_VALUE);
+  }
+  Status = CsrClientCallServer(& Request,
+                              NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+  {
+    SetLastErrorByStatus(Status);
+    return INVALID_HANDLE_VALUE;
+  }
+  return(*phConsole);
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleCommandHistoryMode (DWORD    dwMode)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+  DPRINT1("SetConsoleCommandHistoryMode(0x%x) UNIMPLEMENTED!\n", dwMode);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
-WINBOOL
-STDCALL
-SetConsoleCursor (
-       DWORD   Unknown0,
-       DWORD   Unknown1
-       )
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleCursor (DWORD        Unknown0,
+                 DWORD Unknown1)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+  DPRINT1("SetConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
-WINBOOL
-STDCALL
-SetConsoleDisplayMode (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleDisplayMode (HANDLE hOut,
+                      DWORD dwNewMode,
+                      LPDWORD lpdwOldMode)
+     /*
+      * FUNCTION: Set the console display mode.
+      * ARGUMENTS:
+      *       hOut - Standard output handle.
+      *       dwNewMode - New mode.
+      *       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;
 }
 
 
-WINBOOL
-STDCALL
-SetConsoleFont (
-       DWORD   Unknown0,
-       DWORD   Unknown1
-       )
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleFont (DWORD  Unknown0,
+               DWORD   Unknown1)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+  DPRINT1("SetConsoleFont(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
-WINBOOL
-STDCALL
-SetConsoleHardwareState (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetConsoleHardwareState (HANDLE        hConsole,
+                        DWORD  Flags,
+                        DWORD  State)
+     /*
+      * Undocumented
+      */
+{
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  NTSTATUS          Status;
+
+  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,
+                              NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+  return TRUE;
 }
 
 
-WINBOOL
-STDCALL
-SetConsoleKeyShortcuts (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2,
-       DWORD   Unknown3
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleKeyShortcuts (DWORD  Unknown0,
+                       DWORD   Unknown1,
+                       DWORD   Unknown2,
+                       DWORD   Unknown3)
+     /*
+      * Undocumented
+      */
+{
+  DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
-WINBOOL
-STDCALL
-SetConsoleMaximumWindowSize (
-       DWORD   Unknown0,
-       DWORD   Unknown1
-       )
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleMaximumWindowSize (DWORD     Unknown0,
+                            DWORD      Unknown1)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+  DPRINT1("SetConsoleMaximumWindowSize(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
-WINBOOL
-STDCALL
-SetConsoleMenuClose (
-       DWORD   Unknown0
-       )
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleMenuClose (DWORD     Unknown0)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+  DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
-WINBOOL
-STDCALL
-SetConsoleNumberOfCommandsA (
-       DWORD   Unknown0,
-       DWORD   Unknown1
-       )
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleNumberOfCommandsA (DWORD     Unknown0,
+                            DWORD      Unknown1)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+  DPRINT1("SetConsoleNumberOfCommandsA(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
-WINBOOL
-STDCALL
-SetConsoleNumberOfCommandsW (
-       DWORD   Unknown0,
-       DWORD   Unknown1
-       )
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleNumberOfCommandsW (DWORD     Unknown0,
+                            DWORD      Unknown1)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+  DPRINT1("SetConsoleNumberOfCommandsW(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
-WINBOOL
-STDCALL
-SetConsolePalette (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsolePalette (DWORD       Unknown0,
+                  DWORD        Unknown1,
+                  DWORD        Unknown2)
+     /*
+      * Undocumented
+      */
+{
+  DPRINT1("SetConsolePalette(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
-WINBOOL
-STDCALL
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
 SetLastConsoleEventActive (VOID)
+     /*
+      * Undocumented
+      */
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+  DPRINT1("SetLastConsoleEventActive() UNIMPLEMENTED!\n");
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
-DWORD
-STDCALL
-ShowConsoleCursor (
-       DWORD   Unknown0,
-       DWORD   Unknown1
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
-}
 
-DWORD
-STDCALL
-VerifyConsoleIoHandle (
-       DWORD   Unknown0
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+ShowConsoleCursor (DWORD       Unknown0,
+                  DWORD        Unknown1)
+     /*
+      * Undocumented
+      */
+{
+  DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
-DWORD
-STDCALL
-WriteConsoleInputVDMA (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2,
-       DWORD   Unknown3
-       )
+
+/*
+ * FUNCTION: Checks whether the given handle is a valid console handle.
+ * ARGUMENTS:
+ *      Handle - Handle to be checked
+ * RETURNS:
+ *      TRUE: Handle is a valid console handle
+ *      FALSE: Handle is not a valid console handle.
+ * STATUS: Officially undocumented
+ *
+ * @implemented
+ */
+BOOL STDCALL
+VerifyConsoleIoHandle(HANDLE Handle)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
-}
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  NTSTATUS Status;
 
+  CsrRequest = MAKE_CSR_API(VERIFY_HANDLE, CSR_NATIVE);
+  Request.Data.VerifyHandleRequest.Handle = Handle;
+  Status = CsrClientCallServer(&Request,
+                              NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return FALSE;
+    }
 
-DWORD
-STDCALL
-WriteConsoleInputVDMW (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2,
-       DWORD   Unknown3
-       )
-{
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  return (BOOL)NT_SUCCESS(Request.Status);
 }
 
-/*--------------------------------------------------------------
- *     CloseConsoleHandle
+
+/*
+ * @unimplemented
  */
-WINBOOL STDCALL CloseConsoleHandle(HANDLE Handle)
+DWORD STDCALL
+WriteConsoleInputVDMA (DWORD   Unknown0,
+                      DWORD    Unknown1,
+                      DWORD    Unknown2,
+                      DWORD    Unknown3)
 {
-       if (FALSE == IsConsoleHandle (Handle))
-       {
-               SetLastError (ERROR_INVALID_PARAMETER);
-               return FALSE;
-       }
-       /* FIXME: call CSRSS */
-       return FALSE;
+  DPRINT1("WriteConsoleInputVDMA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
-/*--------------------------------------------------------------
- *     IsConsoleHandle
+
+/*
+ * @unimplemented
  */
-BOOLEAN STDCALL IsConsoleHandle(HANDLE Handle)
+DWORD STDCALL
+WriteConsoleInputVDMW (DWORD   Unknown0,
+                      DWORD    Unknown1,
+                      DWORD    Unknown2,
+                      DWORD    Unknown3)
 {
-   if ((((ULONG)Handle) & 0x10000003) == 0x3)
-     {
-       return(TRUE);
-     }
-   return(FALSE);
+  DPRINT1("WriteConsoleInputVDMW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
 }
 
 
-/*--------------------------------------------------------------
- *     GetStdHandle
+/*
+ * @implemented
  */
-HANDLE STDCALL GetStdHandle(DWORD nStdHandle)
+BOOL STDCALL
+CloseConsoleHandle(HANDLE Handle)
+     /*
+      * Undocumented
+      */
 {
-   PRTL_USER_PROCESS_PARAMETERS Ppb;
-   
-   Ppb = NtCurrentPeb()->ProcessParameters;  
-   switch (nStdHandle)
-     {
-      case STD_INPUT_HANDLE:   return Ppb->InputHandle;
-      case STD_OUTPUT_HANDLE:  return Ppb->OutputHandle;
-      case STD_ERROR_HANDLE:   return Ppb->ErrorHandle;
-     }
-   SetLastError( ERROR_INVALID_PARAMETER );
-   return INVALID_HANDLE_VALUE;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  NTSTATUS Status;
+
+  if (IsConsoleHandle (Handle) == FALSE)
+    {
+      SetLastError (ERROR_INVALID_PARAMETER);
+      return FALSE;
+    }
+
+  CsrRequest = MAKE_CSR_API(CLOSE_HANDLE, CSR_NATIVE);
+  Request.Data.CloseHandleRequest.Handle = Handle;
+  Status = CsrClientCallServer(&Request,
+                              NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
+  if (!NT_SUCCESS(Status))
+    {
+       SetLastErrorByStatus(Status);
+       return FALSE;
+    }
+
+  return TRUE;
 }
 
+/*
+ * @implemented
+ */
+HANDLE STDCALL
+GetStdHandle(DWORD nStdHandle)
+     /*
+      * FUNCTION: Get a handle for the standard input, standard output
+      * and a standard error device.
+      * ARGUMENTS:
+      *       nStdHandle - Specifies the device for which to return the handle.
+      * RETURNS: If the function succeeds, the return value is the handle
+      * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
+      */
+{
+  PRTL_USER_PROCESS_PARAMETERS Ppb;
+
+  Ppb = NtCurrentPeb()->ProcessParameters;
+  switch (nStdHandle)
+    {
+      case STD_INPUT_HANDLE:
+       return Ppb->StandardInput;
 
-/*--------------------------------------------------------------
- *     SetStdHandle
+      case STD_OUTPUT_HANDLE:
+       return Ppb->StandardOutput;
+
+      case STD_ERROR_HANDLE:
+       return Ppb->StandardError;
+    }
+
+  SetLastError (ERROR_INVALID_PARAMETER);
+  return INVALID_HANDLE_VALUE;
+}
+
+
+/*
+ * @implemented
  */
-WINBASEAPI BOOL WINAPI SetStdHandle(DWORD nStdHandle,
-                                   HANDLE hHandle)
-{
-   PRTL_USER_PROCESS_PARAMETERS Ppb;
-   
-   Ppb = NtCurrentPeb()->ProcessParameters;
-   
-   /* More checking needed? */
-   if (hHandle == INVALID_HANDLE_VALUE)
-     {
-       SetLastError( ERROR_INVALID_HANDLE );
-       return FALSE;
-     }
-   
-   SetLastError(ERROR_SUCCESS); /* OK */
-   switch (nStdHandle)
-     {
+BOOL WINAPI
+SetStdHandle(DWORD nStdHandle,
+            HANDLE hHandle)
+     /*
+      * FUNCTION: Set the handle for the standard input, standard output or
+      * the standard error device.
+      * ARGUMENTS:
+      *        nStdHandle - Specifies the handle to be set.
+      *        hHandle - The handle to set.
+      * RETURNS: TRUE if the function succeeds, FALSE otherwise.
+      */
+{
+  PRTL_USER_PROCESS_PARAMETERS Ppb;
+
+  /* no need to check if hHandle == INVALID_HANDLE_VALUE */
+
+  Ppb = NtCurrentPeb()->ProcessParameters;
+
+  switch (nStdHandle)
+    {
       case STD_INPUT_HANDLE:
-       Ppb->InputHandle = hHandle;
+       Ppb->StandardInput = hHandle;
        return TRUE;
+
       case STD_OUTPUT_HANDLE:
-       Ppb->OutputHandle = hHandle;
+       Ppb->StandardOutput = hHandle;
        return TRUE;
+
       case STD_ERROR_HANDLE:
-       Ppb->ErrorHandle = hHandle;
+       Ppb->StandardError = hHandle;
        return TRUE;
-     }
-   SetLastError( ERROR_INVALID_PARAMETER );
-   return FALSE;
+    }
+
+  /* windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
+  SetLastError (ERROR_INVALID_HANDLE);
+  return FALSE;
+}
+
+
+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
  */
-WINBOOL STDCALL WriteConsoleA(HANDLE hConsoleOutput,
-                             CONST VOID *lpBuffer,
-                             DWORD nNumberOfCharsToWrite,
-                             LPDWORD lpNumberOfCharsWritten,
-                             LPVOID lpReserved)
+BOOL STDCALL
+WriteConsoleA(HANDLE hConsoleOutput,
+             CONST VOID *lpBuffer,
+             DWORD nNumberOfCharsToWrite,
+             LPDWORD lpNumberOfCharsWritten,
+             LPVOID lpReserved)
 {
-   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_REQUEST);
-   if (Request == NULL)
-     {
-       return(FALSE);
-     }
-
-   Request->Type = CSRSS_WRITE_CONSOLE;
-   Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
-   if (lpNumberOfCharsWritten != NULL)
-      *lpNumberOfCharsWritten = nNumberOfCharsToWrite;
-   while( nNumberOfCharsToWrite )
-      {
-        Size = nNumberOfCharsToWrite > CSRSS_MAX_WRITE_CONSOLE_REQUEST ? CSRSS_MAX_WRITE_CONSOLE_REQUEST : nNumberOfCharsToWrite;
+  return IntWriteConsole(hConsoleOutput,
+                         (PVOID)lpBuffer,
+                         nNumberOfCharsToWrite,
+                         lpNumberOfCharsWritten,
+                         lpReserved,
+                         FALSE);
+}
 
-        Request->Data.WriteConsoleRequest.NrCharactersToWrite = Size;
 
-        //   DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite);
-        //   DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer);
-        
-        memcpy( Request->Data.WriteConsoleRequest.Buffer, lpBuffer, Size );
-   
-        Status = CsrClientCallServer(Request,
-                                     &Reply,
-                                     sizeof(CSRSS_WRITE_CONSOLE_REQUEST) + 
-                                     Size,
-                                     sizeof(CSRSS_API_REPLY));
-        
-        if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
-           {
-              RtlFreeHeap( GetProcessHeap(), 0, Request );
-              SetLastErrorByStatus (Status);
-              return(FALSE);
-           }
-        nNumberOfCharsToWrite -= Size;
-        lpBuffer += Size;
+/*--------------------------------------------------------------
+ *     WriteConsoleW
+ *
+ * @implemented
+ */
+BOOL STDCALL
+WriteConsoleW(
+       HANDLE           hConsoleOutput,
+       CONST VOID      *lpBuffer,
+       DWORD            nNumberOfCharsToWrite,
+       LPDWORD          lpNumberOfCharsWritten,
+       LPVOID           lpReserved
+       )
+{
+  return IntWriteConsole(hConsoleOutput,
+                         (PVOID)lpBuffer,
+                         nNumberOfCharsToWrite,
+                         lpNumberOfCharsWritten,
+                         lpReserved,
+                         TRUE);
+}
+
+
+static BOOL
+IntReadConsole(HANDLE hConsoleInput,
+               PVOID lpBuffer,
+               DWORD nNumberOfCharsToRead,
+               LPDWORD lpNumberOfCharsRead,
+               LPVOID lpReserved,
+               BOOL bUnicode)
+{
+  PCSR_API_MESSAGE Request; 
+  ULONG CsrRequest;
+  NTSTATUS Status;
+  ULONG CharSize, CharsRead = 0;
+
+  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)
+    {
+      Status = NtWaitForSingleObject(Request->Data.ReadConsoleRequest.EventHandle, FALSE, 0);
+      if(!NT_SUCCESS(Status))
+      {
+        DPRINT1("Wait for console input failed!\n");
+        break;
       }
-   RtlFreeHeap( GetProcessHeap(), 0, Request );
-   return TRUE;
+    }
+
+    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))
+    {
+      DPRINT1("CSR returned error in ReadConsole\n");
+      RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+      SetLastErrorByStatus(Status);
+      return FALSE;
+    }
+
+    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(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(RtlGetProcessHeap(), 0, Request);
+
+  return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     ReadConsoleA
+ *
+ * @implemented
  */
-WINBOOL 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)
-     {
-       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);
 }
 
 
 /*--------------------------------------------------------------
  *     AllocConsole
+ *
+ * @implemented
  */
-WINBOOL STDCALL AllocConsole(VOID)
+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->ConsoleHandle)
+   {
+       DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
+       SetLastErrorByStatus (STATUS_OBJECT_NAME_EXISTS);
+       return FALSE;
+   }
+
+   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;
       }
-   SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle );
-   SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
-   SetStdHandle( STD_ERROR_HANDLE, 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);
+   SetStdHandle( STD_ERROR_HANDLE, hStdError );
    return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     FreeConsole
+ *
+ * @implemented
  */
-WINBOOL STDCALL FreeConsole(VOID)
+BOOL STDCALL FreeConsole(VOID)
 {
-   DbgPrint("FreeConsole() is unimplemented");
-   return FALSE;
+    // AG: I'm not sure if this is correct (what happens to std handles?)
+    // but I just tried to reverse what AllocConsole() does...
+
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
+   NTSTATUS 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;
+      }
+
+   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     GetConsoleScreenBufferInfo
+ *
+ * @implemented
  */
-WINBOOL
+BOOL
 STDCALL
 GetConsoleScreenBufferInfo(
     HANDLE hConsoleOutput,
     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;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleCursorPosition
+ *
+ * @implemented
  */
-WINBOOL
+BOOL
 STDCALL
 SetConsoleCursorPosition(
     HANDLE hConsoleOutput,
     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;
@@ -872,11 +1452,51 @@ 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
+ *
+ * @implemented
  */
-WINBOOL
-STDCALL
+BOOL STDCALL
 FillConsoleOutputCharacterA(
        HANDLE          hConsoleOutput,
        CHAR            cCharacter,
@@ -885,30 +1505,21 @@ 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;
-      }
-   *lpNumberOfCharsWritten = nLength;
-   return TRUE;
+  return IntFillConsoleOutputCharacter(hConsoleOutput,
+                                       &cCharacter,
+                                       nLength,
+                                       dwWriteCoord,
+                                       lpNumberOfCharsWritten,
+                                       FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     FillConsoleOutputCharacterW
+ *
+ * @implemented
  */
-WINBOOL
+BOOL
 STDCALL
 FillConsoleOutputCharacterW(
        HANDLE          hConsoleOutput,
@@ -918,15 +1529,77 @@ FillConsoleOutputCharacterW(
        LPDWORD         lpNumberOfCharsWritten
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntFillConsoleOutputCharacter(hConsoleOutput,
+                                       &cCharacter,
+                                       nLength,
+                                       dwWriteCoord,
+                                       lpNumberOfCharsWritten,
+                                       TRUE);
 }
 
 
+static BOOL
+IntPeekConsoleInput(HANDLE hConsoleInput,
+                    PINPUT_RECORD lpBuffer,
+                    DWORD nLength,
+                    LPDWORD lpNumberOfEventsRead,
+                    BOOL bUnicode)
+{
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  NTSTATUS Status;
+  PVOID BufferBase;
+  PVOID BufferTargetBase;
+  ULONG Size;
+
+  if(lpBuffer == NULL)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return FALSE;
+  }
+
+  Size = nLength * sizeof(INPUT_RECORD);
+
+  Status = CsrCaptureParameterBuffer(NULL, Size, &BufferBase, &BufferTargetBase);
+  if(!NT_SUCCESS(Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+
+  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))
+  {
+    CsrReleaseParameterBuffer(BufferBase);
+    return FALSE;
+  }
+
+  memcpy(lpBuffer, BufferBase, sizeof(INPUT_RECORD) * Request.Data.PeekConsoleInputRequest.Length);
+
+  CsrReleaseParameterBuffer(BufferBase);
+
+  if(lpNumberOfEventsRead != NULL)
+  {
+    *lpNumberOfEventsRead = Request.Data.PeekConsoleInputRequest.Length;
+  }
+
+  return TRUE;
+}
+
 /*--------------------------------------------------------------
  *     PeekConsoleInputA
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 PeekConsoleInputA(
@@ -936,15 +1609,16 @@ PeekConsoleInputA(
        LPDWORD                 lpNumberOfEventsRead
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     PeekConsoleInputW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 PeekConsoleInputW(
@@ -952,63 +1626,109 @@ PeekConsoleInputW(
        PINPUT_RECORD           lpBuffer,
        DWORD                   nLength,
        LPDWORD                 lpNumberOfEventsRead
-       )    
+       )
 {
-/* TO DO */
-       return FALSE;
+  return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, TRUE);
 }
 
 
-/*--------------------------------------------------------------
- *     ReadConsoleInputA
- */
-WINBASEAPI
-BOOL
-WINAPI
-ReadConsoleInputA(
-       HANDLE                  hConsoleInput,
-       PINPUT_RECORD           lpBuffer,
-       DWORD                   nLength,
-       LPDWORD                 lpNumberOfEventsRead
-       )
+static BOOL
+IntReadConsoleInput(HANDLE hConsoleInput,
+                    PINPUT_RECORD lpBuffer,
+                    DWORD nLength,
+                    LPDWORD lpNumberOfEventsRead,
+                    BOOL bUnicode)
 {
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
-   NTSTATUS Status;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  ULONG Read;
+  NTSTATUS Status;
 
-   Request.Type = CSRSS_READ_INPUT;
-   Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
-   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
-   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+  CsrRequest = MAKE_CSR_API(READ_INPUT, CSR_CONSOLE);
+  Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
+  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))
+    {
+      if(Read == 0)
       {
-        SetLastErrorByStatus ( Status );
-        return FALSE;
+        /* we couldn't read a single record, fail */
+        SetLastErrorByStatus(Status);
+        return FALSE;
       }
-   while( Status == STATUS_PENDING )
+      else
       {
-        Status = NtWaitForSingleObject( Reply.Data.ReadInputReply.Event, FALSE, 0 );
-        if( !NT_SUCCESS( Status ) )
-           {
-              SetLastErrorByStatus ( Status );
-              return FALSE;
-           }
-        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;
-           }
+        /* FIXME - fail gracefully in case we already read at least one record? */
+        break;
       }
-   *lpNumberOfEventsRead = 1;
-   *lpBuffer = Reply.Data.ReadInputReply.Input;
-   return TRUE;
+    }
+    else if(Status == STATUS_PENDING)
+    {
+      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;
+      }
+    }
+    else
+    {
+      lpBuffer[Read++] = Request.Data.ReadInputRequest.Input;
+      nLength--;
+
+      if(!Request.Data.ReadInputRequest.MoreEvents)
+      {
+        /* nothing more to read, bail */
+        break;
+      }
+    }
+  }
+
+  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
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleInputW(
@@ -1018,15 +1738,71 @@ ReadConsoleInputW(
        LPDWORD                 lpNumberOfEventsRead
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntReadConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, TRUE);
+}
+
+
+static BOOL
+IntWriteConsoleInput(HANDLE hConsoleInput,
+                     PINPUT_RECORD lpBuffer,
+                     DWORD nLength,
+                     LPDWORD lpNumberOfEventsWritten,
+                     BOOL bUnicode)
+{
+  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);
+  if(!NT_SUCCESS(Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+
+  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))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+
+  if(lpNumberOfEventsWritten != NULL)
+  {
+    *lpNumberOfEventsWritten = Request.Data.WriteConsoleInputRequest.Length;
+  }
+
+  return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     WriteConsoleInputA
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleInputA(
@@ -1036,15 +1812,19 @@ WriteConsoleInputA(
        LPDWORD                  lpNumberOfEventsWritten
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntWriteConsoleInput(hConsoleInput,
+                              (PINPUT_RECORD)lpBuffer,
+                              nLength,
+                              lpNumberOfEventsWritten,
+                              FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     WriteConsoleInputW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleInputW(
@@ -1054,15 +1834,81 @@ WriteConsoleInputW(
        LPDWORD                  lpNumberOfEventsWritten
        )
 {
-/* TO DO */
-       return FALSE;
+  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(NULL, Size, &BufferBase, &BufferTargetBase);
+  if(!NT_SUCCESS(Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+
+  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);
+    CsrReleaseParameterBuffer(BufferBase);
+    return FALSE;
+  }
+
+  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);
+
+  CsrReleaseParameterBuffer(BufferBase);
+
+  *lpReadRegion = Request.Data.ReadConsoleOutputRequest.ReadRegion;
+
+  return TRUE;
+}
+
 /*--------------------------------------------------------------
  *     ReadConsoleOutputA
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputA(
@@ -1073,15 +1919,16 @@ ReadConsoleOutputA(
        PSMALL_RECT     lpReadRegion
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntReadConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
+                             dwBufferCoord, lpReadRegion, FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     ReadConsoleOutputW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputW(
@@ -1092,33 +1939,87 @@ ReadConsoleOutputW(
        PSMALL_RECT     lpReadRegion
        )
 {
-/* TO DO */
-       return FALSE;
+  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)
+{
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  NTSTATUS Status;
+  ULONG Size;
+  PVOID BufferBase;
+  PVOID BufferTargetBase;
+
+  Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
+
+  Status = CsrCaptureParameterBuffer((PVOID)lpBuffer,
+                                    Size,
+                                    &BufferBase,
+                                    &BufferTargetBase);
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return(FALSE);
+    }
+
+  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, 
+                               NULL,
+                              CsrRequest,
+                              sizeof(CSR_API_MESSAGE));
+
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+    {
+      CsrReleaseParameterBuffer(BufferBase);
+      SetLastErrorByStatus(Status);
+      return FALSE;
+    }
+
+  CsrReleaseParameterBuffer(BufferBase);
+
+  *lpWriteRegion = Request.Data.WriteConsoleOutputRequest.WriteRegion;
+
+  return(TRUE);
 }
 
 /*--------------------------------------------------------------
  *     WriteConsoleOutputA
+ *
+ * @implemented
  */
-WINBASEAPI
-BOOL
-WINAPI
-WriteConsoleOutputA(
-       HANDLE           hConsoleOutput,
-       CONST CHAR_INFO *lpBuffer,
-       COORD            dwBufferSize,
-       COORD            dwBufferCoord,
-       PSMALL_RECT      lpWriteRegion
-       )
+BOOL WINAPI
+WriteConsoleOutputA(HANDLE              hConsoleOutput,
+                   CONST CHAR_INFO     *lpBuffer,
+                   COORD                dwBufferSize,
+                   COORD                dwBufferCoord,
+                   PSMALL_RECT  lpWriteRegion)
 {
-/* TO DO */
-       return FALSE;
+  return IntWriteConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
+                               dwBufferCoord, lpWriteRegion, FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     WriteConsoleOutputW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleOutputW(
@@ -1129,15 +2030,88 @@ 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;
 }
 
 
 /*--------------------------------------------------------------
  *     ReadConsoleOutputCharacterA
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputCharacterA(
@@ -1148,15 +2122,20 @@ ReadConsoleOutputCharacterA(
        LPDWORD         lpNumberOfCharsRead
        )
 {
-   SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
-   return FALSE;
+  return IntReadConsoleOutputCharacter(hConsoleOutput,
+                                       (PVOID)lpCharacter,
+                                       nLength,
+                                       dwReadCoord,
+                                       lpNumberOfCharsRead,
+                                       FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *      ReadConsoleOutputCharacterW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputCharacterW(
@@ -1167,15 +2146,20 @@ ReadConsoleOutputCharacterW(
        LPDWORD         lpNumberOfCharsRead
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntReadConsoleOutputCharacter(hConsoleOutput,
+                                       (PVOID)lpCharacter,
+                                       nLength,
+                                       dwReadCoord,
+                                       lpNumberOfCharsRead,
+                                       TRUE);
 }
 
 
 /*--------------------------------------------------------------
  *     ReadConsoleOutputAttribute
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputAttribute(
@@ -1186,88 +2170,180 @@ ReadConsoleOutputAttribute(
        LPDWORD         lpNumberOfAttrsRead
        )
 {
-   SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
-   return FALSE;
+  PCSR_API_MESSAGE Request; ULONG CsrRequest;
+  NTSTATUS Status;
+  DWORD Size;
+
+  if (lpNumberOfAttrsRead != NULL)
+    *lpNumberOfAttrsRead = nLength;
+
+  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 / sizeof(WORD))
+       Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WCHAR);
+      else
+       Size = nLength;
+
+      Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
+
+      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(RtlGetProcessHeap(), 0, Request);
+         SetLastErrorByStatus(Status);
+         return(FALSE);
+       }
+
+      memcpy(lpAttribute, Request->Data.ReadConsoleOutputAttribRequest.Attribute, Size * sizeof(WORD));
+      lpAttribute += Size;
+      nLength -= Size;
+      Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = Request->Data.ReadConsoleOutputAttribRequest.EndCoord;
+    }
+
+  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
-WriteConsoleOutputCharacterA(
-       HANDLE          hConsoleOutput,
-       LPCSTR          lpCharacter,
-       DWORD           nLength,
-       COORD           dwWriteCoord,
-       LPDWORD         lpNumberOfCharsWritten
-       )
+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 ) )
-           {
-              SetLastErrorByStatus ( Status );
-              return FALSE;
-           }
-        nLength -= Size;
-        lpCharacter += Size;
-        Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
-      }
-   return TRUE;
+  return IntWriteConsoleOutputCharacter(hConsoleOutput,
+                                        (PVOID)lpCharacter,
+                                        nLength,
+                                        dwWriteCoord,
+                                        lpNumberOfCharsWritten,
+                                        FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     WriteConsoleOutputCharacterW
+ *
+ * @implemented
  */
-WINBASEAPI
-BOOL
-WINAPI
-WriteConsoleOutputCharacterW(
-       HANDLE          hConsoleOutput,
-       LPCWSTR         lpCharacter,
-       DWORD           nLength,
-       COORD           dwWriteCoord,
-       LPDWORD         lpNumberOfCharsWritten
-       )
+BOOL WINAPI
+WriteConsoleOutputCharacterW(HANDLE            hConsoleOutput,
+                            LPCWSTR            lpCharacter,
+                            DWORD              nLength,
+                            COORD              dwWriteCoord,
+                            LPDWORD            lpNumberOfCharsWritten)
 {
-/* TO DO */
-       return FALSE;
+  return IntWriteConsoleOutputCharacter(hConsoleOutput,
+                                        (PVOID)lpCharacter,
+                                        nLength,
+                                        dwWriteCoord,
+                                        lpNumberOfCharsWritten,
+                                        TRUE);
 }
 
 
-
 /*--------------------------------------------------------------
  *     WriteConsoleOutputAttribute
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleOutputAttribute(
@@ -1278,49 +2354,59 @@ 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(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(RtlGetProcessHeap(), 0, Request);
+
    return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     FillConsoleOutputAttribute
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 FillConsoleOutputAttribute(
@@ -1331,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;
@@ -1354,8 +2440,9 @@ FillConsoleOutputAttribute(
 
 /*--------------------------------------------------------------
  *     GetConsoleMode
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetConsoleMode(
@@ -1363,27 +2450,28 @@ GetConsoleMode(
        LPDWORD         lpMode
        )
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
-  NTSTATUS Status;
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
   
-  Request.Type = CSRSS_GET_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;
 }
 
 
 /*--------------------------------------------------------------
  *     GetNumberOfConsoleInputEvents
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetNumberOfConsoleInputEvents(
@@ -1391,34 +2479,54 @@ GetNumberOfConsoleInputEvents(
        LPDWORD         lpNumberOfEvents
        )
 {
-/* TO DO */
-       return FALSE;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
+   NTSTATUS Status;
+
+   if(lpNumberOfEvents == NULL)
+   {
+      SetLastError(ERROR_INVALID_PARAMETER);
+      return FALSE;
+   }
+
+   CsrRequest = MAKE_CSR_API(GET_NUM_INPUT_EVENTS, CSR_CONSOLE);
+   Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
+   Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
+   if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+   {
+      SetLastErrorByStatus(Status);
+      return FALSE;
+   }
+
+   *lpNumberOfEvents = Request.Data.GetNumInputEventsRequest.NumInputEvents;
+
+       return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     GetLargestConsoleWindowSize
+ *
+ * @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;
 }
 
 
 /*--------------------------------------------------------------
  *     GetConsoleCursorInfo
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetConsoleCursorInfo(
@@ -1426,42 +2534,46 @@ 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 ) );
-   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;
       }
-   *lpConsoleCursorInfo = Reply.Data.GetCursorInfoReply.Info;
+   *lpConsoleCursorInfo = Request.Data.GetCursorInfoRequest.Info;
    return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     GetNumberOfConsoleMouseButtons
+ *
+ * @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;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleMode
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleMode(
@@ -1469,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_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;
@@ -1488,22 +2608,23 @@ SetConsoleMode(
 
 /*--------------------------------------------------------------
  *     SetConsoleActiveScreenBuffer
+ *
+ * @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;
-   Request.Data.SetActiveScreenBufferRequest.OutputHandle = hConsoleOutput;
-   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(SET_SCREEN_BUFFER, CSR_CONSOLE);
+   Request.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
+   Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
       {
         SetLastErrorByStatus ( Status );
         return FALSE;
@@ -1514,23 +2635,36 @@ SetConsoleActiveScreenBuffer(
 
 /*--------------------------------------------------------------
  *     FlushConsoleInputBuffer
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 FlushConsoleInputBuffer(
        HANDLE          hConsoleInput
        )
 {
-/* TO DO */
-       return FALSE;
+   CSR_API_MESSAGE Request; ULONG CsrRequest;
+   
+   NTSTATUS Status;
+
+   CsrRequest = MAKE_CSR_API(FLUSH_INPUT_BUFFER, CSR_CONSOLE);
+   Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
+   Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
+      {
+        SetLastErrorByStatus ( Status );
+        return FALSE;
+      }
+   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleScreenBufferSize
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleScreenBufferSize(
@@ -1538,14 +2672,16 @@ SetConsoleScreenBufferSize(
        COORD           dwSize
        )
 {
-/* TO DO */
-       return FALSE;
+  DPRINT1("SetConsoleScreenBufferSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, dwSize);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /*--------------------------------------------------------------
  *     SetConsoleCursorInfo
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleCursorInfo(
@@ -1553,15 +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 ) );
-   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;
@@ -1570,10 +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(
@@ -1584,15 +2765,20 @@ ScrollConsoleScreenBufferA(
        CONST CHAR_INFO         *lpFill
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntScrollConsoleScreenBuffer(hConsoleOutput,
+                                      (PSMALL_RECT)lpScrollRectangle,
+                                      (PSMALL_RECT)lpClipRectangle,
+                                      dwDestinationOrigin,
+                                      (PCHAR_INFO)lpFill,
+                                      FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     ScrollConsoleScreenBufferW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ScrollConsoleScreenBufferW(
@@ -1603,15 +2789,20 @@ ScrollConsoleScreenBufferW(
        CONST CHAR_INFO         *lpFill
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntScrollConsoleScreenBuffer(hConsoleOutput,
+                                      (PSMALL_RECT)lpScrollRectangle,
+                                      (PSMALL_RECT)lpClipRectangle,
+                                      dwDestinationOrigin,
+                                      (PCHAR_INFO)lpFill,
+                                      TRUE);
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleWindowInfo
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleWindowInfo(
@@ -1620,31 +2811,33 @@ 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;
 }
 
 
 /*--------------------------------------------------------------
  *      SetConsoleTextAttribute
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleTextAttribute(
-       HANDLE          hConsoleOutput,
+        HANDLE         hConsoleOutput,
         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;
@@ -1653,44 +2846,117 @@ SetConsoleTextAttribute(
 }
 
 
-/*--------------------------------------------------------------
- *     SetConsoleCtrlHandler
+BOOL STATIC
+AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
+{
+  if (HandlerRoutine == NULL)
+    {
+      IgnoreCtrlEvents = TRUE;
+      return(TRUE);
+    }
+  else
+    {
+      NrCtrlHandlers++;
+      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;
+         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+         return(FALSE);
+       }
+      CtrlHandlers[NrCtrlHandlers - 1] = HandlerRoutine;
+      return(TRUE);
+    }
+}
+
+
+BOOL STATIC
+RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
+{
+  ULONG i;
+
+  if (HandlerRoutine == NULL)
+    {
+      IgnoreCtrlEvents = FALSE;
+      return(TRUE);
+    }
+  else
+    {
+      for (i = 0; i < NrCtrlHandlers; i++)
+       {
+         if ( ((void*)(CtrlHandlers[i])) == (void*)HandlerRoutine)
+           {
+             NrCtrlHandlers--;
+             memmove(CtrlHandlers + i, CtrlHandlers + i + 1,
+                     (NrCtrlHandlers - i) * sizeof(PHANDLER_ROUTINE));
+             CtrlHandlers =
+               RtlReAllocateHeap(RtlGetProcessHeap(),
+                                 HEAP_ZERO_MEMORY,
+                                 (PVOID)CtrlHandlers,
+                                 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
+             return(TRUE);
+           }
+       }
+    }
+  return(FALSE);
+}
+
+
+/*
+ * @implemented
  */
-WINBASEAPI
-BOOL
-WINAPI
-SetConsoleCtrlHandler(
-       PHANDLER_ROUTINE        HandlerRoutine,
-       BOOL                    Add
-       )
+BOOL WINAPI
+SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
+                     BOOL Add)
 {
-/* TO DO */
-       return FALSE;
+  BOOLEAN Ret;
+
+  RtlEnterCriticalSection(&DllLock);
+  if (Add)
+    {
+      Ret = AddConsoleCtrlHandler(HandlerRoutine);
+    }
+  else
+    {
+      Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
+    }
+  RtlLeaveCriticalSection(&DllLock);
+  return(Ret);
 }
 
 
 /*--------------------------------------------------------------
  *     GenerateConsoleCtrlEvent
+ *
+ * @unimplemented
  */
-WINBASEAPI
-BOOL
-WINAPI
+BOOL WINAPI
 GenerateConsoleCtrlEvent(
        DWORD           dwCtrlEvent,
        DWORD           dwProcessGroupId
        )
 {
-/* TO DO */
-       return FALSE;
+  DPRINT1("GenerateConsoleCtrlEvent(0x%x, 0x%x) UNIMPLEMENTED!\n", dwCtrlEvent, dwProcessGroupId);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
 /*--------------------------------------------------------------
  *     GetConsoleTitleW
+ *
+ * @implemented
  */
-#define MAX_CONSOLE_TITLE_LENGTH 80
-
-WINBASEAPI
 DWORD
 WINAPI
 GetConsoleTitleW(
@@ -1698,8 +2964,54 @@ GetConsoleTitleW(
        DWORD           nSize
        )
 {
-/* TO DO */
-       return 0;
+   PCSR_API_MESSAGE Request; ULONG CsrRequest;
+   NTSTATUS Status;
+   HANDLE hConsole;
+
+   hConsole = CreateFileW(L"CONIN$", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+   if (hConsole == INVALID_HANDLE_VALUE)
+   {
+      return 0;
+   }
+
+   Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+                             CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
+   if (Request == NULL)
+   {
+      SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+      return FALSE;
+   }
+
+   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 = Request->Status)))
+   {
+      RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+      SetLastErrorByStatus(Status);
+      return 0;
+   }
+
+   if(nSize * sizeof(WCHAR) < Request->Data.GetTitleRequest.Length)
+   {
+      wcsncpy(lpConsoleTitle, Request->Data.GetTitleRequest.Title, nSize - 1);
+      lpConsoleTitle[nSize--] = L'\0';
+   }
+   else
+   {
+      nSize = Request->Data.GetTitleRequest.Length / sizeof (WCHAR);
+      wcscpy(lpConsoleTitle, Request->Data.GetTitleRequest.Title);
+      lpConsoleTitle[nSize] = L'\0';
+   }
+
+   RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+
+   return nSize;
 }
 
 
@@ -1707,8 +3019,9 @@ GetConsoleTitleW(
  *     GetConsoleTitleA
  *
  *     19990306 EA
+ *
+ * @implemented
  */
-WINBASEAPI
 DWORD
 WINAPI
 GetConsoleTitleA(
@@ -1716,21 +3029,21 @@ GetConsoleTitleA(
        DWORD           nSize
        )
 {
-       wchar_t WideTitle [MAX_CONSOLE_TITLE_LENGTH];
+       wchar_t WideTitle [CSRSS_MAX_TITLE_LENGTH];
        DWORD   nWideTitle = sizeof WideTitle;
-//     DWORD   nWritten;
-       
+       DWORD   nWritten;
+
        if (!lpConsoleTitle || !nSize) return 0;
        nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle );
        if (!nWideTitle) return 0;
-#if 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
                )))
@@ -1738,158 +3051,130 @@ GetConsoleTitleA(
                lpConsoleTitle[nWritten] = '\0';
                return nWritten;
        }
-#endif
+
        return 0;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleTitleW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleTitleW(
        LPCWSTR         lpConsoleTitle
        )
 {
-/* --- TO DO --- */
-       return FALSE;
+  PCSR_API_MESSAGE Request; ULONG CsrRequest;
+  NTSTATUS Status;
+  unsigned int c;
+  HANDLE hConsole;
+
+  hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+  if (hConsole == INVALID_HANDLE_VALUE)
+  {
+     return FALSE;
+  }
+
+  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)
+  {
+     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];
+  Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR);
+  Status = CsrClientCallServer(Request,
+                              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 = Request->Status ) )
+    {
+      RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+      SetLastErrorByStatus (Status);
+      return(FALSE);
+    }
+
+  RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+
+  return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleTitleA
- *     
+ *
  *     19990204 EA     Added
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleTitleA(
        LPCSTR          lpConsoleTitle
        )
 {
-       wchar_t WideTitle [MAX_CONSOLE_TITLE_LENGTH];
-       char    AnsiTitle [MAX_CONSOLE_TITLE_LENGTH];
-       INT     nWideTitle;
-       
-       if (!lpConsoleTitle) return FALSE;
-       ZeroMemory( WideTitle, sizeof WideTitle );
-       nWideTitle = lstrlenA(lpConsoleTitle);
-       if (!lstrcpynA(
-               AnsiTitle,
-               lpConsoleTitle,
-               nWideTitle
-               )) 
-       {
-               return FALSE;
-       }
-       AnsiTitle[nWideTitle] = '\0';
-#if 0
-       if ( MultiByteToWideChar(
-               CP_ACP,                 // ANSI code page 
-               MB_PRECOMPOSED,         // character-type options 
-               AnsiTitle,              // address of string to map 
-               nWideTitle,             // number of characters in string 
-               (LPWSTR) WideTitle,     // address of wide-character buffer 
-               (-1)                    // size of buffer: -1=...\0
-               ))
-       {
-               return SetConsoleTitleW( (LPWSTR) WideTitle ); 
-       }
-#endif
-       return FALSE;
-}
-
-
-/*--------------------------------------------------------------
- *     ReadConsoleW
- */
-WINBASEAPI
-BOOL
-WINAPI
-ReadConsoleW(
-       HANDLE          hConsoleInput,
-       LPVOID          lpBuffer,
-       DWORD           nNumberOfCharsToRead,
-       LPDWORD         lpNumberOfCharsRead,
-       LPVOID          lpReserved
-       )
-{
-/* --- TO DO --- */
-       return FALSE;
-}
-
-
-/*--------------------------------------------------------------
- *     WriteConsoleW
- */
-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)
-     {
-       return(FALSE);
-     }
-
-   Request->Type = CSRSS_WRITE_CONSOLE;
-   Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
-   Request->Data.WriteConsoleRequest.NrCharactersToWrite =
-     nNumberOfCharsToWrite;
-//   DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite);
-//   DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer);
-   memcpy(Request->Data.WriteConsoleRequest.Buffer,
-         lpBuffer,
-         nNumberOfCharsToWrite * sizeof(WCHAR));
-
-   Status = CsrClientCallServer(Request,
-                               &Reply,
-                               sizeof(CSRSS_API_REQUEST) +
-                               nNumberOfCharsToWrite,
-                               sizeof(CSRSS_API_REPLY));
-
-   RtlFreeHeap(GetProcessHeap(),
-           0,
-           Request);
-
-   if (!NT_SUCCESS(Status))
-     {
-       return(FALSE);
-     }
-
-   if (lpNumberOfCharsWritten != NULL)
-     {
-       *lpNumberOfCharsWritten = 
-         Reply.Data.WriteConsoleReply.NrCharactersWritten;
-     }
+  PCSR_API_MESSAGE Request; ULONG CsrRequest;
+  NTSTATUS Status;
+  unsigned int c;
+  HANDLE hConsole;
+
+  hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+  if (hConsole == INVALID_HANDLE_VALUE)
+  {
+     return FALSE;
+  }
+
+  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)
+  {
+     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];
+  Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR);
+  Status = CsrClientCallServer(Request,
+                              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 = Request->Status ) )
+    {
+      RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+      SetLastErrorByStatus (Status);
+      return(FALSE);
+    }
+
+  RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
 
-   return(TRUE);
-#endif
-   return FALSE;
+  return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     CreateConsoleScreenBuffer
+ *
+ * @implemented
  */
-WINBASEAPI
 HANDLE
 WINAPI
 CreateConsoleScreenBuffer(
@@ -1901,75 +3186,531 @@ 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
+ *
+ * @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
+ *
+ * @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
+ *
+ * @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
+ *
+ * @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
+ *
+ * @implemented
+ */
+DWORD STDCALL
+GetConsoleProcessList(LPDWORD lpdwProcessList,
+                      DWORD dwProcessCount)
+{
+  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;
+}
+
+
+
+/*--------------------------------------------------------------
+ *     GetConsoleSelectionInfo
+ *
+ * @unimplemented
+ */
+BOOL STDCALL
+GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
+{
+  DPRINT1("GetConsoleSelectionInfo(0x%x) UNIMPLEMENTED!\n", lpConsoleSelectionInfo);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+
+/*--------------------------------------------------------------
+ *     AttachConsole
+ *
+ * @unimplemented
+ */
+BOOL STDCALL
+AttachConsole(DWORD dwProcessId)
+{
+  DPRINT1("AttachConsole(0x%x) UNIMPLEMENTED!\n", dwProcessId);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/*--------------------------------------------------------------
+ *     GetConsoleWindow
+ *
+ * @implemented
+ */
+HWND STDCALL
+GetConsoleWindow (VOID)
+{
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  NTSTATUS          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 Request.Data.GetConsoleWindowRequest.WindowHandle;
+}
+
+
+/*--------------------------------------------------------------
+ *     SetConsoleIcon
+ *
+ * @implemented
+ */
+BOOL STDCALL SetConsoleIcon(HICON hicon)
+{
+  CSR_API_MESSAGE Request; ULONG CsrRequest;
+  
+  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;
+  }
+
+  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
+  {
+    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;
+  }
+
+  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 */