- RtlReAllocateHeap shouldn't allocate memory if ptr == NULL.
[reactos.git] / reactos / lib / kernel32 / misc / console.c
index 09eb7a4..b93f0c8 100644 (file)
+/* $Id: console.c,v 1.79 2004/08/28 22:14:08 navaraf Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS system libraries
+ * FILE:            lib/kernel32/misc/console.c
+ * PURPOSE:         Win32 server console functions
+ * PROGRAMMER:      James Tabor 
+ *                     <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
+ * UPDATE HISTORY:
+ *     199901?? ??     Created
+ *     19990204 EA     SetConsoleTitleA
+ *      19990306 EA    Stubs
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <k32.h>
+
+#define NDEBUG
+#include "../include/debug.h"
+
+#define _NOACHS(__X) (sizeof(__X) / sizeof((__X)[0]))
+extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);
+extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag);
+extern CRITICAL_SECTION ConsoleLock;
+extern BOOL WINAPI IsDebuggerPresent(VOID);
+
+
+/* GLOBALS *******************************************************************/
+
+static BOOL IgnoreCtrlEvents = FALSE;
+
+static PHANDLER_ROUTINE* CtrlHandlers = NULL;
+static ULONG NrCtrlHandlers = 0;
+
+/* Default Console Control Handler *******************************************/
+
+BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event)
+{
+       switch(Event)
+       {
+       case CTRL_C_EVENT:
+               DPRINT("Ctrl-C Event\n");
+               ExitProcess(0);
+               break;
+               
+       case CTRL_BREAK_EVENT:
+               DPRINT("Ctrl-Break Event\n");
+               ExitProcess(0);
+               break;
+
+       case CTRL_SHUTDOWN_EVENT:
+               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((UINT)&ExitCode);
+       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->ProcessGroup & 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->ProcessGroup & 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 (LPSTR Source,
+                 LPSTR Target,
+                 LPSTR ExeName)
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+AddConsoleAliasW (LPWSTR Source,
+                 LPWSTR Target,
+                 LPWSTR ExeName)
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+ConsoleMenuControl (HANDLE     hConsole,
+                   DWORD       Unknown1,
+                   DWORD       Unknown2)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @implemented
+ */
+HANDLE STDCALL
+DuplicateConsoleHandle (HANDLE hConsole,
+                       DWORD   dwDesiredAccess,
+                       BOOL    bInheritHandle,
+                       DWORD   dwOptions)
+{
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+
+  if (IsConsoleHandle (hConsole) == FALSE)
+    {
+      SetLastError (ERROR_INVALID_PARAMETER);
+      return INVALID_HANDLE_VALUE;
+    }
+  
+  Request.Type = CSRSS_DUPLICATE_HANDLE;
+  Request.Data.DuplicateHandleRequest.Handle = hConsole;
+  Request.Data.DuplicateHandleRequest.ProcessId = GetCurrentProcessId();
+  Status = CsrClientCallServer(&Request,
+                              &Reply,
+                              sizeof(CSRSS_API_REQUEST),
+                              sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Reply.Status))
+    {
+      SetLastErrorByStatus(Status);
+      return INVALID_HANDLE_VALUE;
+    }
+  return Reply.Data.DuplicateHandleReply.Handle;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+ExpungeConsoleCommandHistoryW (DWORD   Unknown0)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+ExpungeConsoleCommandHistoryA (DWORD   Unknown0)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasW (DWORD        Unknown0,
+                 DWORD Unknown1,
+                 DWORD Unknown2,
+                 DWORD Unknown3)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasA (DWORD        Unknown0,
+                 DWORD Unknown1,
+                 DWORD Unknown2,
+                 DWORD Unknown3)
+     /*
+      * Undocumented
+      */
+{
+       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+       return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasExesW (DWORD    Unknown0,
+                     DWORD     Unknown1)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasExesA (DWORD    Unknown0,
+                     DWORD     Unknown1)
+     /*
+      * Undocumented
+      */
+{
+       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+       return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasExesLengthA (VOID)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasExesLengthW (VOID)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasesW (DWORD      Unknown0,
+                   DWORD       Unknown1,
+                   DWORD       Unknown2)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasesA (DWORD      Unknown0,
+                   DWORD       Unknown1,
+                   DWORD       Unknown2)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasesLengthW (DWORD Unknown0)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleAliasesLengthA (DWORD Unknown0)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleCommandHistoryW (DWORD       Unknown0,
+                          DWORD        Unknown1,
+                          DWORD        Unknown2)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleCommandHistoryA (DWORD       Unknown0,
+                          DWORD        Unknown1,
+                          DWORD        Unknown2)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleCommandHistoryLengthW (DWORD Unknown0)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleCommandHistoryLengthA (DWORD Unknown0)
+     /*
+      * Undocumented
+      */
+{
+  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
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleFontInfo (DWORD      Unknown0,
+                   DWORD       Unknown1,
+                   DWORD       Unknown2,
+                   DWORD       Unknown3)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleFontSize(HANDLE hConsoleOutput,
+                  DWORD nFont)
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetConsoleHardwareState (HANDLE        hConsole,
+                        DWORD  Flags,
+                        PDWORD State)
+     /*
+      * Undocumented
+      */
+{
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY   Reply;
+  NTSTATUS          Status;
+
+  Request.Type = CSRSS_SETGET_CONSOLE_HW_STATE;
+  Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
+  Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_GET;
+
+  Status = CsrClientCallServer(& Request,
+                              & Reply,
+                              sizeof(CSRSS_API_REQUEST),
+                              sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+  *State = Reply.Data.ConsoleHardwareStateReply.State;
+  return TRUE;  
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleInputWaitHandle (VOID)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+GetCurrentConsoleFont(HANDLE hConsoleOutput,
+                     BOOL bMaximumWindow,
+                     PCONSOLE_FONT_INFO lpConsoleCurrentFont)
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+ULONG STDCALL
+GetNumberOfConsoleFonts (VOID)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 1; /* FIXME: call csrss.exe */
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+InvalidateConsoleDIBits (DWORD Unknown0,
+                        DWORD  Unknown1)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+HANDLE STDCALL
+OpenConsoleW (LPWSTR  wsName,
+             DWORD   dwDesiredAccess,
+             BOOL    bInheritHandle,
+             DWORD   dwCreationDistribution)
+     /*
+      * Undocumented
+      */
+{
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY   Reply;
+  PHANDLE           phConsole = NULL;
+  NTSTATUS          Status = STATUS_SUCCESS;
+  
+  
+  if(0 == _wcsicmp(wsName, L"CONIN$"))
+  {
+    Request.Type = CSRSS_GET_INPUT_HANDLE;
+    phConsole = & Reply.Data.GetInputHandleReply.InputHandle;
+  }
+  else if (0 == _wcsicmp(wsName, L"CONOUT$"))
+  {
+    Request.Type = CSRSS_GET_OUTPUT_HANDLE;
+    phConsole = & Reply.Data.GetOutputHandleReply.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,
+                              & Reply,
+                              sizeof(CSRSS_API_REQUEST),
+                              sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus(Status);
+    return INVALID_HANDLE_VALUE;
+  }
+  return(*phConsole);
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleCommandHistoryMode (DWORD    dwMode)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleCursor (DWORD        Unknown0,
+                 DWORD Unknown1)
+     /*
+      * Undocumented
+      */
+{
+  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.
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleFont (DWORD  Unknown0,
+               DWORD   Unknown1)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetConsoleHardwareState (HANDLE        hConsole,
+                        DWORD  Flags,
+                        DWORD  State)
+     /*
+      * Undocumented
+      */
+{
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY   Reply;
+  NTSTATUS          Status;
+
+  Request.Type = CSRSS_SETGET_CONSOLE_HW_STATE;
+  Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
+  Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_SET;
+  Request.Data.ConsoleHardwareStateRequest.State = State;
+
+  Status = CsrClientCallServer(& Request,
+                              & Reply,
+                              sizeof(CSRSS_API_REQUEST),
+                              sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+  return TRUE;  
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleKeyShortcuts (DWORD  Unknown0,
+                       DWORD   Unknown1,
+                       DWORD   Unknown2,
+                       DWORD   Unknown3)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleMaximumWindowSize (DWORD     Unknown0,
+                            DWORD      Unknown1)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleMenuClose (DWORD     Unknown0)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleNumberOfCommandsA (DWORD     Unknown0,
+                            DWORD      Unknown1)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsoleNumberOfCommandsW (DWORD     Unknown0,
+                            DWORD      Unknown1)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetConsolePalette (DWORD       Unknown0,
+                  DWORD        Unknown1,
+                  DWORD        Unknown2)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+SetLastConsoleEventActive (VOID)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+ShowConsoleCursor (DWORD       Unknown0,
+                  DWORD        Unknown1)
+     /*
+      * Undocumented
+      */
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * 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)
+{
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+
+  Request.Type = CSRSS_VERIFY_HANDLE;
+  Request.Data.VerifyHandleRequest.Handle = Handle;
+  Status = CsrClientCallServer(&Request,
+                              &Reply,
+                              sizeof(CSRSS_API_REQUEST),
+                              sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return FALSE;
+    }
+
+  return (BOOL)NT_SUCCESS(Reply.Status);
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+WriteConsoleInputVDMA (DWORD   Unknown0,
+                      DWORD    Unknown1,
+                      DWORD    Unknown2,
+                      DWORD    Unknown3)
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+WriteConsoleInputVDMW (DWORD   Unknown0,
+                      DWORD    Unknown1,
+                      DWORD    Unknown2,
+                      DWORD    Unknown3)
+{
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS system libraries
- * FILE:            lib/kernel32/misc/console.c
- * PURPOSE:         Win32 server console functions
- * PROGRAMMER:      ???
- * UPDATE HISTORY:
- *     199901?? ??     Created
- *     19990204 EA     SetConsoleTitleA
- *      19990306 EA    Stubs
+ * @implemented
  */
-#include <ddk/ntddk.h>
-#include <ddk/ntddblue.h>
-#include <windows.h>
-#include <assert.h>
-#include <wchar.h>
+BOOL STDCALL
+CloseConsoleHandle(HANDLE Handle)
+     /*
+      * Undocumented
+      */
+{
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  NTSTATUS Status;
 
-#define NDEBUG
-#include <kernel32/kernel32.h>
+  if (IsConsoleHandle (Handle) == FALSE)
+    {
+      SetLastError (ERROR_INVALID_PARAMETER);
+      return FALSE;
+    }
+
+  Request.Type = CSRSS_CLOSE_HANDLE;
+  Request.Data.CloseHandleRequest.Handle = Handle;
+  Status = CsrClientCallServer(&Request,
+                              &Reply,
+                              sizeof(CSRSS_API_REQUEST),
+                              sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status))
+    {
+       SetLastErrorByStatus(Status);
+       return FALSE;
+    }
 
+  return TRUE;
+}
 
-/* What is this?
-#define EXTENDED_CONSOLE */
 
-HANDLE StdInput  = INVALID_HANDLE_VALUE;
-HANDLE StdOutput = INVALID_HANDLE_VALUE;
-HANDLE StdError  = INVALID_HANDLE_VALUE;
-#ifdef EXTENDED_CONSOLE
-HANDLE StdAux    = INVALID_HANDLE_VALUE;
-HANDLE StdPrint  = INVALID_HANDLE_VALUE;
-#endif
+/*
+ * internal function
+ */
+BOOL STDCALL
+IsConsoleHandle(HANDLE Handle)
+{
+  if ((((ULONG)Handle) & 0x10000003) == 0x3)
+    {
+      return(TRUE);
+    }
+  return(FALSE);
+}
+
 
+/*
+ * @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->hStdInput;
 
+      case STD_OUTPUT_HANDLE:
+       return Ppb->hStdOutput;
 
+      case STD_ERROR_HANDLE:
+       return Ppb->hStdError;
+    }
 
-/*--------------------------------------------------------------
- *     GetStdHandle
+  SetLastError (ERROR_INVALID_PARAMETER);
+  return INVALID_HANDLE_VALUE;
+}
+
+
+/*
+ * @implemented
  */
-HANDLE STDCALL GetStdHandle(DWORD 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.
+      */
 {
-   DPRINT("GetStdHandle(nStdHandle %d)\n",nStdHandle);
-   
-   SetLastError(ERROR_SUCCESS); /* OK */
-   switch (nStdHandle)
-     {
-      case STD_INPUT_HANDLE:   return StdInput;
-      case STD_OUTPUT_HANDLE:  return StdOutput;
-      case STD_ERROR_HANDLE:   return StdError;
-#ifdef EXTENDED_CONSOLE
-      case STD_AUX_HANDLE:     return StdError;
-      case STD_PRINT_HANDLE:   return StdError;
-#endif
-     }
-   SetLastError(0); /* FIXME: What error code? */
-   return INVALID_HANDLE_VALUE;
+  PRTL_USER_PROCESS_PARAMETERS Ppb;
+
+  /* no need to check if hHandle == INVALID_HANDLE_VALUE */
+
+  Ppb = NtCurrentPeb()->ProcessParameters;
+
+  switch (nStdHandle)
+    {
+      case STD_INPUT_HANDLE:
+       Ppb->hStdInput = hHandle;
+       return TRUE;
+
+      case STD_OUTPUT_HANDLE:
+       Ppb->hStdOutput = hHandle;
+       return TRUE;
+
+      case STD_ERROR_HANDLE:
+       Ppb->hStdError = hHandle;
+       return TRUE;
+    }
+
+  /* windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
+  SetLastError (ERROR_INVALID_HANDLE);
+  return FALSE;
 }
 
 
 /*--------------------------------------------------------------
- *     SetStdHandle
+ *     WriteConsoleA
+ *
+ * @implemented
  */
-WINBASEAPI
-BOOL
-WINAPI
-SetStdHandle(
-       DWORD   nStdHandle,
-       HANDLE  hHandle
-       )
+BOOL STDCALL 
+WriteConsoleA(HANDLE hConsoleOutput,
+             CONST VOID *lpBuffer,
+             DWORD nNumberOfCharsToWrite,
+             LPDWORD lpNumberOfCharsWritten,
+             LPVOID lpReserved)
 {
-       /* More checking needed? */
-       if (hHandle == INVALID_HANDLE_VALUE)
+  PCSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+  USHORT Size;
+  ULONG MessageSize;
+
+  Request = RtlAllocateHeap(GetProcessHeap(), 0,
+                           sizeof(CSRSS_API_REQUEST) +
+                           min(nNumberOfCharsToWrite,
+                           CSRSS_MAX_WRITE_CONSOLE_REQUEST));
+  if (Request == NULL)
+    {
+      SetLastError(ERROR_OUTOFMEMORY);
+      return(FALSE);
+    }
+
+  Request->Type = CSRSS_WRITE_CONSOLE;
+  Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
+  if (lpNumberOfCharsWritten != NULL)
+    *lpNumberOfCharsWritten = nNumberOfCharsToWrite;
+  while (nNumberOfCharsToWrite)
+    {
+      if (nNumberOfCharsToWrite > CSRSS_MAX_WRITE_CONSOLE_REQUEST)
        {
-               SetLastError(0);        /* FIXME: What error code? */
-               return FALSE;
+         Size = CSRSS_MAX_WRITE_CONSOLE_REQUEST;
        }
-       SetLastError(ERROR_SUCCESS); /* OK */
-       switch (nStdHandle)
+      else
        {
-               case STD_INPUT_HANDLE:
-                       StdInput = hHandle;
-                       return TRUE;
-               case STD_OUTPUT_HANDLE:
-                       StdOutput = hHandle;
-                       return TRUE;
-               case STD_ERROR_HANDLE:
-                       StdError = hHandle;
-                       return TRUE;
-#ifdef EXTENDED_CONSOLE
-               case STD_AUX_HANDLE:
-                       StdError = hHandle;
-                       return TRUE;
-               case STD_PRINT_HANDLE:
-                       StdError = hHandle;
-                       return TRUE;
-#endif
+         Size = nNumberOfCharsToWrite;
        }
-       SetLastError(0); /* FIXME: What error code? */
-       return FALSE;
-}
+      Request->Data.WriteConsoleRequest.NrCharactersToWrite = Size;
 
+      memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, Size);
 
-/*--------------------------------------------------------------
- *     WriteConsoleA
- */
-WINBOOL
-STDCALL
-WriteConsoleA(
-    HANDLE hConsoleOutput,
-    CONST VOID *lpBuffer,
-    DWORD nNumberOfCharsToWrite,
-    LPDWORD lpNumberOfCharsWritten,
-    LPVOID lpReserved
-    )
-{
-       return WriteFile(hConsoleOutput, lpBuffer, nNumberOfCharsToWrite,lpNumberOfCharsWritten, lpReserved);
+      MessageSize = CSRSS_REQUEST_HEADER_SIZE + 
+       sizeof(CSRSS_WRITE_CONSOLE_REQUEST) + Size;
+      Status = CsrClientCallServer(Request,
+                                  &Reply,
+                                  MessageSize,
+                                  sizeof(CSRSS_API_REPLY));
+
+      if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+       {
+         RtlFreeHeap(GetProcessHeap(), 0, Request);
+         SetLastErrorByStatus(Status);
+         return(FALSE);
+       }
+      nNumberOfCharsToWrite -= Size;
+      lpBuffer += Size;
+    }
+
+  RtlFreeHeap(GetProcessHeap(), 0, Request);
+
+  return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     ReadConsoleA
+ *
+ * @implemented
  */
-WINBOOL
-STDCALL
-ReadConsoleA(HANDLE hConsoleInput,
+BOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
                             LPVOID lpBuffer,
                             DWORD nNumberOfCharsToRead,
                             LPDWORD lpNumberOfCharsRead,
                             LPVOID lpReserved)
 {
-   KEY_EVENT_RECORD KeyEventRecord;
-   BOOL  stat = TRUE;
-   PCHAR Buffer = (PCHAR)lpBuffer;
-   DWORD Result;
-   int   i;
+   CSRSS_API_REQUEST Request;
+   PCSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+   ULONG CharsRead = 0;
+   
+   Reply = RtlAllocateHeap(GetProcessHeap(), 0,
+                           sizeof(CSRSS_API_REPLY) + nNumberOfCharsToRead);
+   if (Reply == NULL)
+     {
+       SetLastError(ERROR_OUTOFMEMORY);
+       return(FALSE);
+     }
    
-   for (i=0; (stat && i<nNumberOfCharsToRead);)     
+   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 )
      {
-       stat = ReadFile(hConsoleInput,
-                       &KeyEventRecord,
-                        sizeof(KEY_EVENT_RECORD),
-                       &Result,
-                       NULL);
-        if (stat && KeyEventRecord.bKeyDown && KeyEventRecord.uChar.AsciiChar != 0)
+       /* 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 )
          {
-             Buffer[i] = KeyEventRecord.uChar.AsciiChar;
-            i++;
+            // 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 = i;
-     }
-   return(stat);
+     *lpNumberOfCharsRead = CharsRead;
+   RtlFreeHeap(GetProcessHeap(),
+           0,
+           Reply);
+   
+   return(TRUE);
 }
 
 
 /*--------------------------------------------------------------
  *     AllocConsole
+ *
+ * @implemented
  */
-WINBOOL
-STDCALL
-AllocConsole( VOID )
-{
-       /* FIXME: add CreateFile error checking */
-       StdInput = CreateFile("\\\\.\\Keyboard",
-                              FILE_GENERIC_READ,
-                              0,
-                              NULL,
-                              OPEN_EXISTING,
-                              0,
-                              NULL);
-   
-       StdOutput = CreateFile("\\\\.\\BlueScreen",
-                              FILE_GENERIC_WRITE|FILE_GENERIC_READ,
-                              0,
-                              NULL,
-                              OPEN_EXISTING,
-                              0,
-                              NULL);
-
-       StdError = StdOutput;
-
-       return TRUE;
+BOOL STDCALL AllocConsole(VOID)
+{
+   CSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+   HANDLE hStdError;
+
+   if(NtCurrentPeb()->ProcessParameters->hConsole)
+   {
+       DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
+       SetLastErrorByStatus (STATUS_OBJECT_NAME_EXISTS); 
+       return FALSE;    
+   }
+
+   Request.Data.AllocConsoleRequest.CtrlDispatcher = (PCONTROLDISPATCHER) &ConsoleControlDispatcher;
+
+   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 ) )
+      {
+        SetLastErrorByStatus ( Status );
+        return FALSE;
+      }
+   NtCurrentPeb()->ProcessParameters->hConsole = Reply.Data.AllocConsoleReply.Console;
+   SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle );
+   SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
+   hStdError = DuplicateConsoleHandle(Reply.Data.AllocConsoleReply.OutputHandle,
+                                      0,
+                                     TRUE,
+                                     DUPLICATE_SAME_ACCESS);
+   SetStdHandle( STD_ERROR_HANDLE, hStdError );
+   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     FreeConsole
+ *
+ * @implemented
  */
-WINBOOL
-STDCALL
-FreeConsole( VOID )
+BOOL STDCALL FreeConsole(VOID)
 {
-       if (StdInput == INVALID_HANDLE_VALUE)
-       {
-               SetLastError(0); /* FIXME: What error code? */
-               return FALSE;
-       }
-       SetLastError(ERROR_SUCCESS);
-       CloseHandle(StdInput);
-
-       if (StdError != INVALID_HANDLE_VALUE)
-       {
-               if (StdError != StdOutput)
-                       CloseHandle(StdError);
-               StdError = INVALID_HANDLE_VALUE;
-       }
-
-       CloseHandle(StdOutput);
-
-#ifdef EXTENDED_CONSOLE
-       CloseHandle(StdAux);
-       CloseHandle(StdPrint);
-#endif
-       return TRUE; /* FIXME: error check needed? */
+    // AG: I'm not sure if this is correct (what happens to std handles?)
+    // but I just tried to reverse what AllocConsole() does...
+
+   CSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+
+   Request.Type = CSRSS_FREE_CONSOLE;
+   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+      {
+        SetLastErrorByStatus ( Status );
+        return FALSE;
+      }
+
+   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     GetConsoleScreenBufferInfo
+ *
+ * @implemented
  */
-WINBOOL
+BOOL
 STDCALL
 GetConsoleScreenBufferInfo(
     HANDLE hConsoleOutput,
     PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
     )
 {
-       DWORD   dwBytesReturned;
-       
-       if ( !DeviceIoControl(
-               hConsoleOutput,
-                IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
-               NULL,
-               0,
-               lpConsoleScreenBufferInfo,
-               sizeof(CONSOLE_SCREEN_BUFFER_INFO),
-               & dwBytesReturned,
-               NULL
-               )
-       )
-       {
-               SetLastError(0); /* FIXME: What error code? */
-               return FALSE;
-       }
-       SetLastError(ERROR_SUCCESS); /* OK */
-       return TRUE;
+   CSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+
+   Request.Type = CSRSS_SCREEN_BUFFER_INFO;
+   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 ) )
+      {
+        SetLastErrorByStatus ( Status );
+        return FALSE;
+      }
+   *lpConsoleScreenBufferInfo = Reply.Data.ScreenBufferInfoReply.Info;
+   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleCursorPosition
+ *
+ * @implemented
  */
-WINBOOL
+BOOL
 STDCALL
 SetConsoleCursorPosition(
     HANDLE hConsoleOutput,
     COORD dwCursorPosition
     )
 {
-       DWORD dwBytesReturned;
-       CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
-
-       if( !GetConsoleScreenBufferInfo(hConsoleOutput,&ConsoleScreenBufferInfo) )
-       {
-               SetLastError(0); /* FIXME: What error code? */
-               return FALSE;
-       }
-       ConsoleScreenBufferInfo.dwCursorPosition.X = dwCursorPosition.X;
-       ConsoleScreenBufferInfo.dwCursorPosition.Y = dwCursorPosition.Y;
-       
-       if( !DeviceIoControl(
-                       hConsoleOutput,
-                       IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
-                       &ConsoleScreenBufferInfo,
-                       sizeof(CONSOLE_SCREEN_BUFFER_INFO),
-                       NULL,
-                       0,
-                       &dwBytesReturned,
-                       NULL ))
-               return FALSE;
-
-       return TRUE;
+   CSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+
+   Request.Type = CSRSS_SET_CURSOR;
+   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 ) )
+      {
+        SetLastErrorByStatus ( Status );
+        return FALSE;
+      }
+   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     FillConsoleOutputCharacterA
+ *
+ * @implemented
  */
-WINBOOL
-STDCALL
+BOOL STDCALL
 FillConsoleOutputCharacterA(
        HANDLE          hConsoleOutput,
        CHAR            cCharacter,
@@ -298,35 +1356,33 @@ FillConsoleOutputCharacterA(
        LPDWORD         lpNumberOfCharsWritten
        )
 {
-    DWORD dwBytesReturned;
-    OUTPUT_CHARACTER Buffer;
-
-    Buffer.cCharacter = cCharacter;
-    Buffer.nLength    = nLength;
-    Buffer.dwCoord    = dwWriteCoord;
-
-    if (DeviceIoControl (hConsoleOutput,
-                         IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER,
-                         &Buffer,
-                         sizeof(OUTPUT_CHARACTER),
-                         &Buffer,
-                         sizeof(OUTPUT_CHARACTER),
-                         &dwBytesReturned,
-                         NULL))
+  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 ) )
     {
-        *lpNumberOfCharsWritten = Buffer.dwTransfered;
-        return TRUE;
+      SetLastErrorByStatus(Status);
+      return(FALSE);
     }
-
-    *lpNumberOfCharsWritten = 0;
-    return FALSE;
+  if (lpNumberOfCharsWritten != NULL)
+     *lpNumberOfCharsWritten = nLength;
+  return(TRUE);
 }
 
 
 /*--------------------------------------------------------------
  *     FillConsoleOutputCharacterW
+ *
+ * @unimplemented
  */
-WINBOOL
+BOOL
 STDCALL
 FillConsoleOutputCharacterW(
        HANDLE          hConsoleOutput,
@@ -337,14 +1393,87 @@ FillConsoleOutputCharacterW(
        )
 {
 /* TO DO */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 
+/*--------------------------------------------------------------
+ *     IntPeekConsoleInput
+ *
+ * INTERNAL
+ */
+BOOL
+WINAPI
+IntPeekConsoleInput(
+       HANDLE                  hConsoleInput,
+       PINPUT_RECORD           lpBuffer,
+       DWORD                   nLength,
+       LPDWORD                 lpNumberOfEventsRead,
+       BOOL                    bUnicode
+       )
+{
+  PCSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+  PVOID BufferBase;
+  PVOID BufferTargetBase;
+  DWORD Size;
+  
+  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;
+  }
+  
+  Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
+  if(Request == NULL)
+  {
+    CsrReleaseParameterBuffer(BufferBase);
+    SetLastError(ERROR_OUTOFMEMORY);
+    return FALSE;
+  }
+  
+  Request->Type = CSRSS_PEEK_CONSOLE_INPUT;
+  Request->Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
+  Request->Data.PeekConsoleInputRequest.Unicode = bUnicode;
+  Request->Data.PeekConsoleInputRequest.Length = nLength;
+  Request->Data.PeekConsoleInputRequest.InputRecord = (INPUT_RECORD*)BufferTargetBase;
+  
+  Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
+  
+  if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    RtlFreeHeap(GetProcessHeap(), 0, Request);
+    CsrReleaseParameterBuffer(BufferBase);
+    return FALSE;
+  }
+
+  memcpy(lpBuffer, BufferBase, sizeof(INPUT_RECORD) * Reply.Data.PeekConsoleInputReply.Length);
+
+  if(lpNumberOfEventsRead != NULL)
+    *lpNumberOfEventsRead = Reply.Data.PeekConsoleInputReply.Length;
+
+  RtlFreeHeap(GetProcessHeap(), 0, Request);
+  CsrReleaseParameterBuffer(BufferBase);  
+  
+  return TRUE;
+}
+
 /*--------------------------------------------------------------
  *     PeekConsoleInputA
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 PeekConsoleInputA(
@@ -354,15 +1483,16 @@ PeekConsoleInputA(
        LPDWORD                 lpNumberOfEventsRead
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     PeekConsoleInputW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 PeekConsoleInputW(
@@ -372,53 +1502,111 @@ PeekConsoleInputW(
        LPDWORD                 lpNumberOfEventsRead
        )    
 {
-/* TO DO */
-       return FALSE;
+  return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, TRUE);
+}
+
+
+/*--------------------------------------------------------------
+ *     IntReadConsoleInput
+ *
+ * INTERNAL
+ */
+BOOL WINAPI
+IntReadConsoleInput(HANDLE hConsoleInput,
+                    PINPUT_RECORD lpBuffer,
+                    DWORD nLength,
+                    LPDWORD lpNumberOfEventsRead,
+                    BOOL bUnicode)
+{
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  DWORD NumEventsRead;
+  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))
+    {
+      SetLastErrorByStatus(Status);
+      return(FALSE);
+    }
+  
+  while (Status == STATUS_PENDING)
+    {
+      Status = NtWaitForSingleObject(Reply.Data.ReadInputReply.Event, FALSE, 
+                                    0);
+      if(!NT_SUCCESS(Status))
+       {
+         SetLastErrorByStatus(Status);
+         return FALSE;
+       }
+      
+      Request.Type = CSRSS_READ_INPUT;
+      Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
+      Request.Data.ReadInputRequest.Unicode = bUnicode;
+      Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
+                                  sizeof(CSRSS_API_REPLY));
+      if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+       {
+         SetLastErrorByStatus(Status);
+         return(FALSE);
+       }
+    }
+  
+  NumEventsRead = 1;
+  *lpBuffer = Reply.Data.ReadInputReply.Input;
+  lpBuffer++;
+  
+  while ((NumEventsRead < nLength) && (Reply.Data.ReadInputReply.MoreEvents))
+    {
+      Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
+                                  sizeof(CSRSS_API_REPLY));
+      if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+       {
+         SetLastErrorByStatus(Status);
+         return(FALSE);
+       }
+      
+      if (Status == STATUS_PENDING)
+       {
+         break;
+       }
+      
+      *lpBuffer = Reply.Data.ReadInputReply.Input;
+      lpBuffer++;
+      NumEventsRead++;
+      
+    }
+  *lpNumberOfEventsRead = NumEventsRead;
+  
+  return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     ReadConsoleInputA
+ *
+ * @implemented
  */
-WINBASEAPI
-BOOL
-WINAPI
-ReadConsoleInputA(
-       HANDLE                  hConsoleInput,
-       PINPUT_RECORD           lpBuffer,
-       DWORD                   nLength,
-       LPDWORD                 lpNumberOfEventsRead
-       )
+BOOL WINAPI
+ReadConsoleInputA(HANDLE hConsoleInput,
+                 PINPUT_RECORD lpBuffer,
+                 DWORD nLength,
+                 LPDWORD lpNumberOfEventsRead)
 {
-   BOOL  stat = TRUE;
-   DWORD Result;
-   int i;
-   
-   for (i=0; (stat && i < nLength);)     
-     {
-       stat = ReadFile(hConsoleInput,
-                        &lpBuffer[i].Event.KeyEvent,
-                        sizeof(KEY_EVENT_RECORD),
-                       &Result,
-                       NULL);
-        if (stat)
-         {
-             lpBuffer[i].EventType = KEY_EVENT;
-            i++;
-         }
-     }
-   if (lpNumberOfEventsRead != NULL)
-     {
-        *lpNumberOfEventsRead = i;
-     }
-   return(stat);
+  return IntReadConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     ReadConsoleInputW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleInputW(
@@ -428,15 +1616,16 @@ ReadConsoleInputW(
        LPDWORD                 lpNumberOfEventsRead
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntReadConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, TRUE);
 }
 
 
 /*--------------------------------------------------------------
  *     WriteConsoleInputA
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleInputA(
@@ -446,15 +1635,63 @@ WriteConsoleInputA(
        LPDWORD                  lpNumberOfEventsWritten
        )
 {
-/* TO DO */
-       return FALSE;
+  PCSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  PVOID BufferBase, BufferTargetBase;
+  NTSTATUS Status;
+  DWORD Size;
+  
+  if(lpBuffer == NULL)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return FALSE;
+  }
+  
+  Size = nLength * sizeof(INPUT_RECORD);
+
+  Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
+  if(!NT_SUCCESS(Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+  
+  Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
+  if(Request == NULL)
+  {
+    SetLastError(ERROR_OUTOFMEMORY);
+    CsrReleaseParameterBuffer(BufferBase);
+    return FALSE;
+  }
+
+  Request->Type = CSRSS_WRITE_CONSOLE_INPUT;
+  Request->Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
+  Request->Data.WriteConsoleInputRequest.Length = nLength;
+  Request->Data.WriteConsoleInputRequest.InputRecord = (PINPUT_RECORD)BufferTargetBase;
+  
+  Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
+  if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    RtlFreeHeap(GetProcessHeap(), 0, Request);
+    CsrReleaseParameterBuffer(BufferBase);
+    return FALSE;
+  }
+  
+  if(lpNumberOfEventsWritten != NULL)
+    *lpNumberOfEventsWritten = Reply.Data.WriteConsoleInputReply.Length;
+  
+  RtlFreeHeap(GetProcessHeap(), 0, Request);
+  CsrReleaseParameterBuffer(BufferBase);
+  
+  return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     WriteConsoleInputW
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleInputW(
@@ -465,14 +1702,91 @@ WriteConsoleInputW(
        )
 {
 /* TO DO */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 
+/*--------------------------------------------------------------
+ *     IntReadConsoleOutput
+ *
+ * INTERNAL
+ */
+BOOL
+WINAPI
+IntReadConsoleOutput(
+       HANDLE          hConsoleOutput,
+       PCHAR_INFO      lpBuffer,
+       COORD           dwBufferSize,
+       COORD           dwBufferCoord,
+       PSMALL_RECT     lpReadRegion,
+       BOOL            bUnicode
+       )
+{
+  PCSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  PVOID BufferBase;
+  PVOID BufferTargetBase;
+  NTSTATUS Status;
+  DWORD Size, SizeX, SizeY;
+  
+  if(lpBuffer == NULL)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return FALSE;
+  }
+  
+  Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
+
+  Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
+  if(!NT_SUCCESS(Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+  
+  Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
+  if(Request == NULL)
+  {
+    SetLastError(ERROR_OUTOFMEMORY);
+    CsrReleaseParameterBuffer(BufferBase);
+    return FALSE;
+  }
+   
+  Request->Type = CSRSS_READ_CONSOLE_OUTPUT;
+  Request->Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
+  Request->Data.ReadConsoleOutputRequest.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, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
+  if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus(Status);
+    RtlFreeHeap(GetProcessHeap(), 0, Request);
+    CsrReleaseParameterBuffer(BufferBase);
+    return FALSE;
+  }
+  
+  SizeX = Reply.Data.ReadConsoleOutputReply.ReadRegion.Right - Reply.Data.ReadConsoleOutputReply.ReadRegion.Left + 1;
+  SizeY = Reply.Data.ReadConsoleOutputReply.ReadRegion.Bottom - Reply.Data.ReadConsoleOutputReply.ReadRegion.Top + 1;
+  
+  memcpy(lpBuffer, BufferBase, sizeof(CHAR_INFO) * SizeX * SizeY);
+  *lpReadRegion = Reply.Data.ReadConsoleOutputReply.ReadRegion;
+  
+  RtlFreeHeap(GetProcessHeap(), 0, Request);
+  CsrReleaseParameterBuffer(BufferBase);
+  
+  return TRUE;
+}
+
 /*--------------------------------------------------------------
  *     ReadConsoleOutputA
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputA(
@@ -483,15 +1797,16 @@ ReadConsoleOutputA(
        PSMALL_RECT     lpReadRegion
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntReadConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
+                             dwBufferCoord, lpReadRegion, FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     ReadConsoleOutputW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputW(
@@ -502,33 +1817,99 @@ ReadConsoleOutputW(
        PSMALL_RECT     lpReadRegion
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntReadConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
+                             dwBufferCoord, lpReadRegion, TRUE);
+}
+
+
+/*--------------------------------------------------------------
+ *     IntWriteConsoleOutput
+ *
+ * INTERNAL
+ */
+BOOL WINAPI
+IntWriteConsoleOutput(HANDLE           hConsoleOutput,
+                      CONST CHAR_INFO *lpBuffer,
+                      COORD            dwBufferSize,
+                      COORD            dwBufferCoord,
+                      PSMALL_RECT      lpWriteRegion,
+                      BOOL             bUnicode)
+{
+  PCSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  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);
+    }
+  
+  Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, 
+                           sizeof(CSRSS_API_REQUEST));
+  if (Request == NULL)
+    {
+      CsrReleaseParameterBuffer(BufferBase);
+      SetLastError(ERROR_OUTOFMEMORY);
+      return FALSE;
+    }
+  Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT;
+  Request->Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
+  Request->Data.WriteConsoleOutputRequest.Unicode = bUnicode;
+  Request->Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
+  Request->Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
+  Request->Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
+  Request->Data.WriteConsoleOutputRequest.CharInfo = 
+    (CHAR_INFO*)BufferTargetBase;
+  
+  Status = CsrClientCallServer(Request, &Reply, 
+                              sizeof(CSRSS_API_REQUEST), 
+                              sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+    {
+      CsrReleaseParameterBuffer(BufferBase);
+      RtlFreeHeap(GetProcessHeap(), 0, Request);
+      SetLastErrorByStatus(Status);
+      return FALSE;
+    }
+      
+  *lpWriteRegion = Reply.Data.WriteConsoleOutputReply.WriteRegion;
+  RtlFreeHeap(GetProcessHeap(), 0, Request);
+  CsrReleaseParameterBuffer(BufferBase);
+  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(
@@ -539,15 +1920,16 @@ WriteConsoleOutputW(
        PSMALL_RECT      lpWriteRegion
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntWriteConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
+                               dwBufferCoord, lpWriteRegion, TRUE);
 }
 
 
 /*--------------------------------------------------------------
  *     ReadConsoleOutputCharacterA
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputCharacterA(
@@ -558,33 +1940,64 @@ ReadConsoleOutputCharacterA(
        LPDWORD         lpNumberOfCharsRead
        )
 {
-    DWORD dwBytesReturned;
-    OUTPUT_CHARACTER Buffer;
+  CSRSS_API_REQUEST Request;
+  PCSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+  DWORD Size;
+
+  Reply = RtlAllocateHeap(GetProcessHeap(), 0,
+                         sizeof(CSRSS_API_REPLY) +
+                         min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR));
+  if (Reply == NULL)
+    {
+      SetLastError(ERROR_OUTOFMEMORY);
+      return(FALSE);
+    }
 
-    Buffer.dwCoord    = dwReadCoord;
+  if (lpNumberOfCharsRead != NULL)
+    *lpNumberOfCharsRead = nLength;
 
-    if (DeviceIoControl (hConsoleOutput,
-                         IOCTL_CONSOLE_READ_OUTPUT_CHARACTER,
-                         &Buffer,
-                         sizeof(OUTPUT_CHARACTER),
-                         lpCharacter,
-                         nLength,
-                         &dwBytesReturned,
-                         NULL))
+  Request.Type = CSRSS_READ_CONSOLE_OUTPUT_CHAR;
+  Request.Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
+  Request.Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
+
+  while (nLength != 0)
     {
-        *lpNumberOfCharsRead = Buffer.dwTransfered;
-        return TRUE;
+      if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR)
+       Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR;
+      else
+       Size = nLength;
+
+      Request.Data.ReadConsoleOutputCharRequest.NumCharsToRead = Size;
+
+      Status = CsrClientCallServer(&Request,
+                                  Reply,
+                                  sizeof(CSRSS_API_REQUEST),
+                                  sizeof(CSRSS_API_REPLY) + Size);
+      if (!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
+       {
+         RtlFreeHeap(GetProcessHeap(), 0, Reply);
+         SetLastErrorByStatus(Status);
+         return(FALSE);
+       }
+
+      memcpy(lpCharacter, &Reply->Data.ReadConsoleOutputCharReply.String[0], Size);
+      lpCharacter += Size;
+      nLength -= Size;
+      Request.Data.ReadConsoleOutputCharRequest.ReadCoord = Reply->Data.ReadConsoleOutputCharReply.EndCoord;
     }
 
-    *lpNumberOfCharsRead = 0;
-    return FALSE;
+  RtlFreeHeap(GetProcessHeap(), 0, Reply);
+
+  return(TRUE);
 }
 
 
 /*--------------------------------------------------------------
  *      ReadConsoleOutputCharacterW
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputCharacterW(
@@ -596,14 +2009,16 @@ ReadConsoleOutputCharacterW(
        )
 {
 /* TO DO */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 
 /*--------------------------------------------------------------
  *     ReadConsoleOutputAttribute
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputAttribute(
@@ -614,91 +2029,183 @@ ReadConsoleOutputAttribute(
        LPDWORD         lpNumberOfAttrsRead
        )
 {
-    DWORD dwBytesReturned;
-    OUTPUT_ATTRIBUTE Buffer;
+  CSRSS_API_REQUEST Request;
+  PCSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+  DWORD Size, i;
+  
+  Reply = RtlAllocateHeap(GetProcessHeap(), 0,
+                         sizeof(CSRSS_API_REPLY) +
+                         min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB));
+  if (Reply == NULL)
+    {
+      SetLastError(ERROR_OUTOFMEMORY);
+      return(FALSE);
+    }
 
-    Buffer.dwCoord = dwReadCoord;
+  if (lpNumberOfAttrsRead != NULL)
+    *lpNumberOfAttrsRead = nLength;
 
-    if (DeviceIoControl (hConsoleOutput,
-                         IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE,
-                         &Buffer,
-                         sizeof(OUTPUT_ATTRIBUTE),
-                         (PVOID)lpAttribute,
-                         nLength,
-                         &dwBytesReturned,
-                         NULL))
+  Request.Type = CSRSS_READ_CONSOLE_OUTPUT_ATTRIB;
+  Request.Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
+  Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
+
+  while (nLength != 0)
     {
-        *lpNumberOfAttrsRead = Buffer.dwTransfered;
-        return TRUE;
+      if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB)
+       Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB;
+      else
+       Size = nLength;
+
+      Request.Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
+
+      Status = CsrClientCallServer(&Request,
+                                  Reply,
+                                  sizeof(CSRSS_API_REQUEST),
+                                  sizeof(CSRSS_API_REPLY) + Size);
+      if (!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
+       {
+         RtlFreeHeap(GetProcessHeap(), 0, Reply);
+         SetLastErrorByStatus(Status);
+         return(FALSE);
+       }
+
+      // Convert CHARs to WORDs
+      for(i = 0; i < Size; ++i)
+        *lpAttribute++ = Reply->Data.ReadConsoleOutputAttribReply.String[i];
+      
+      nLength -= Size;
+      Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = Reply->Data.ReadConsoleOutputAttribReply.EndCoord;
     }
 
-    *lpNumberOfAttrsRead = 0;
+  RtlFreeHeap(GetProcessHeap(), 0, Reply);
 
-    return FALSE;
+  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)
 {
-    DWORD dwBytesReturned;
-    OUTPUT_CHARACTER Buffer;
-
-    Buffer.dwCoord    = dwWriteCoord;
-
-    if (DeviceIoControl (hConsoleOutput,
-                         IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
-                         &Buffer,
-                         sizeof(OUTPUT_CHARACTER),
-                         (LPSTR)lpCharacter,
-                         nLength,
-                         &dwBytesReturned,
-                         NULL))
+  PCSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+  WORD Size;
+
+  Request = RtlAllocateHeap(GetProcessHeap(), 0,
+                           sizeof(CSRSS_API_REQUEST) +
+                           min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR));
+  if( !Request )
     {
-        *lpNumberOfCharsWritten = Buffer.dwTransfered;
-        return TRUE;
+      SetLastError( ERROR_OUTOFMEMORY );
+      return FALSE;
     }
-
-    *lpNumberOfCharsWritten = 0;
-    return FALSE;
+  Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR;
+  Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
+  Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
+  if( lpNumberOfCharsWritten )
+    *lpNumberOfCharsWritten = nLength;
+  while( nLength )
+    {
+      Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength;
+      Request->Data.WriteConsoleOutputCharRequest.Length = Size;
+      memcpy( &Request->Data.WriteConsoleOutputCharRequest.String[0],
+             lpCharacter,
+             Size );
+      Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
+      if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+       {
+         RtlFreeHeap( GetProcessHeap(), 0, Request );
+         SetLastErrorByStatus ( Status );
+         return FALSE;
+       }
+      nLength -= Size;
+      lpCharacter += Size;
+      Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
+    }
+  
+  RtlFreeHeap( GetProcessHeap(), 0, Request ); 
+  return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     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;
-}
+  PCSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+  WORD Size;
+  
+  Request = RtlAllocateHeap(GetProcessHeap(), 0,
+                           sizeof(CSRSS_API_REQUEST) +
+                           min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR));
+  if( !Request )
+    {
+      SetLastError( ERROR_OUTOFMEMORY );
+      return FALSE;
+    }
+  Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR;
+  Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
+  Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
+  if( lpNumberOfCharsWritten )
+    *lpNumberOfCharsWritten = nLength;
+  while( nLength )
+    {
+      Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength;
+      Request->Data.WriteConsoleOutputCharRequest.Length = Size;
+      Status = RtlUnicodeToOemN (&Request->Data.WriteConsoleOutputCharRequest.String[0],
+                                Size,
+                                NULL,
+                                (PWCHAR)lpCharacter,
+                                Size * sizeof(WCHAR));
+      if (!NT_SUCCESS(Status))
+       {
+         RtlFreeHeap (GetProcessHeap(), 0, Request);
+         SetLastErrorByStatus (Status);
+         return FALSE;
+       }
 
+      Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
+      if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+       {
+         RtlFreeHeap( GetProcessHeap(), 0, Request );
+         SetLastErrorByStatus ( Status );
+         return FALSE;
+       }
+      nLength -= Size;
+      lpCharacter += Size;
+      Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
+    }
+  
+  RtlFreeHeap( GetProcessHeap(), 0, Request );
+  return TRUE;
+}
 
 
 /*--------------------------------------------------------------
  *     WriteConsoleOutputAttribute
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleOutputAttribute(
@@ -709,34 +2216,53 @@ WriteConsoleOutputAttribute(
        LPDWORD          lpNumberOfAttrsWritten
        )
 {
-    DWORD dwBytesReturned;
-    OUTPUT_ATTRIBUTE Buffer;
-
-    Buffer.dwCoord = dwWriteCoord;
-
-    if (DeviceIoControl (hConsoleOutput,
-                         IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE,
-                         &Buffer,
-                         sizeof(OUTPUT_ATTRIBUTE),
-                         (PVOID)lpAttribute,
-                         nLength,
-                         &dwBytesReturned,
-                         NULL))
-    {
-        *lpNumberOfAttrsWritten = Buffer.dwTransfered;
-        return TRUE;
-    }
-
-    *lpNumberOfAttrsWritten = 0;
-
-    return FALSE;
+   PCSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+   WORD Size;
+   int c;
+
+   Request = RtlAllocateHeap(GetProcessHeap(), 0,
+                            sizeof(CSRSS_API_REQUEST) +
+                            min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB));
+   if( !Request )
+     {
+       SetLastError( ERROR_OUTOFMEMORY );
+       return FALSE;
+     }
+   Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB;
+   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;
+        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 ) )
+           {
+              RtlFreeHeap( GetProcessHeap(), 0, Request );
+              SetLastErrorByStatus ( Status );
+              return FALSE;
+           }
+        nLength -= Size;
+        lpAttribute += Size;
+        Request->Data.WriteConsoleOutputAttribRequest.Coord = Reply.Data.WriteConsoleOutputAttribReply.EndCoord;
+      }
+   
+   RtlFreeHeap( GetProcessHeap(), 0, Request );
+   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     FillConsoleOutputAttribute
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 FillConsoleOutputAttribute(
@@ -747,36 +2273,32 @@ FillConsoleOutputAttribute(
        LPDWORD         lpNumberOfAttrsWritten
        )
 {
-    DWORD dwBytesReturned;
-    OUTPUT_ATTRIBUTE Buffer;
-
-    Buffer.wAttribute = wAttribute;
-    Buffer.nLength    = nLength;
-    Buffer.dwCoord    = dwWriteCoord;
-
-    if (DeviceIoControl (hConsoleOutput,
-                         IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE,
-                         &Buffer,
-                         sizeof(OUTPUT_ATTRIBUTE),
-                         &Buffer,
-                         sizeof(OUTPUT_ATTRIBUTE),
-                         &dwBytesReturned,
-                         NULL))
-    {
-        *lpNumberOfAttrsWritten = Buffer.dwTransfered;
-        return TRUE;
-    }
-
-    *lpNumberOfAttrsWritten = 0;
-
-    return FALSE;
+   CSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+
+   Request.Type = CSRSS_FILL_OUTPUT_ATTRIB;
+   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 ) )
+      {
+        SetLastErrorByStatus ( Status );
+        return FALSE;
+      }
+   if( lpNumberOfAttrsWritten )
+      *lpNumberOfAttrsWritten = nLength;
+   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     GetConsoleMode
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetConsoleMode(
@@ -784,32 +2306,28 @@ GetConsoleMode(
        LPDWORD         lpMode
        )
 {
-    CONSOLE_MODE Buffer;
-    DWORD   dwBytesReturned;
-       
-    if (DeviceIoControl (hConsoleHandle,
-                         IOCTL_CONSOLE_GET_MODE,
-                         NULL,
-                         0,
-                         &Buffer,
-                         sizeof(CONSOLE_MODE),
-                         &dwBytesReturned,
-                         NULL))
-    {
-        *lpMode = Buffer.dwMode;
-        SetLastError (ERROR_SUCCESS);
-        return TRUE;
-    }
-
-    SetLastError(0); /* FIXME: What error code? */
-    return FALSE;
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+  
+  Request.Type = CSRSS_GET_CONSOLE_MODE;
+  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 ) )
+      {
+       SetLastErrorByStatus ( Status );
+       return FALSE;
+      }
+  *lpMode = Reply.Data.GetConsoleModeReply.ConsoleMode;
+  return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     GetNumberOfConsoleInputEvents
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetNumberOfConsoleInputEvents(
@@ -817,15 +2335,36 @@ GetNumberOfConsoleInputEvents(
        LPDWORD         lpNumberOfEvents
        )
 {
-/* TO DO */
-       return FALSE;
+   CSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+   if(lpNumberOfEvents == NULL)
+   {
+      SetLastError(ERROR_INVALID_PARAMETER);
+      return FALSE;
+   }
+   
+   Request.Type = CSRSS_GET_NUM_INPUT_EVENTS;
+   Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
+   Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
+   if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+   {
+      SetLastErrorByStatus(Status);
+      return FALSE;
+   }
+   
+   *lpNumberOfEvents = Reply.Data.GetNumInputEventsReply.NumInputEvents;
+   
+       return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     GetLargestConsoleWindowSize
+ *
+ * @unimplemented
  */
-WINBASEAPI
 COORD
 WINAPI
 GetLargestConsoleWindowSize(
@@ -843,8 +2382,9 @@ GetLargestConsoleWindowSize(
 
 /*--------------------------------------------------------------
  *     GetConsoleCursorInfo
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetConsoleCursorInfo(
@@ -852,26 +2392,29 @@ GetConsoleCursorInfo(
        PCONSOLE_CURSOR_INFO    lpConsoleCursorInfo
        )
 {
-    DWORD   dwBytesReturned;
-       
-    if (DeviceIoControl (hConsoleOutput,
-                         IOCTL_CONSOLE_GET_CURSOR_INFO,
-                         NULL,
-                         0,
-                         lpConsoleCursorInfo,
-                         sizeof(CONSOLE_CURSOR_INFO),
-                         &dwBytesReturned,
-                         NULL))
-        return TRUE;
-
-    return FALSE;
+   CSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+
+   Request.Type = CSRSS_GET_CURSOR_INFO;
+   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 ) )
+      {
+        SetLastErrorByStatus ( Status );
+        return FALSE;
+      }
+   *lpConsoleCursorInfo = Reply.Data.GetCursorInfoReply.Info;
+   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     GetNumberOfConsoleMouseButtons
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetNumberOfConsoleMouseButtons(
@@ -885,8 +2428,9 @@ GetNumberOfConsoleMouseButtons(
 
 /*--------------------------------------------------------------
  *     SetConsoleMode
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleMode(
@@ -894,63 +2438,82 @@ SetConsoleMode(
        DWORD           dwMode
        )
 {
-    CONSOLE_MODE Buffer;
-    DWORD   dwBytesReturned;
-
-    Buffer.dwMode = dwMode;
-       
-    if (DeviceIoControl (hConsoleHandle,
-                         IOCTL_CONSOLE_SET_MODE,
-                         &Buffer,
-                         sizeof(CONSOLE_MODE),
-                         NULL,
-                         0,
-                         &dwBytesReturned,
-                         NULL))
-    {
-        SetLastError (ERROR_SUCCESS);
-        return TRUE;
-    }
-
-    SetLastError(0); /* FIXME: What error code? */
-    return FALSE;
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+  
+  Request.Type = CSRSS_SET_CONSOLE_MODE;
+  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 ) )
+      {
+       SetLastErrorByStatus ( Status );
+       return FALSE;
+      }
+  return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleActiveScreenBuffer
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleActiveScreenBuffer(
        HANDLE          hConsoleOutput
        )
 {
-/* TO DO */
-       return FALSE;
+   CSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+
+   Request.Type = CSRSS_SET_SCREEN_BUFFER;
+   Request.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
+   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+      {
+        SetLastErrorByStatus ( Status );
+        return FALSE;
+      }
+   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     FlushConsoleInputBuffer
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 FlushConsoleInputBuffer(
        HANDLE          hConsoleInput
        )
 {
-/* TO DO */
-       return FALSE;
+   CSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+
+   Request.Type = CSRSS_FLUSH_INPUT_BUFFER;
+   Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
+   Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+   if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+      {
+        SetLastErrorByStatus ( Status );
+        return FALSE;
+      }
+   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleScreenBufferSize
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleScreenBufferSize(
@@ -959,13 +2522,15 @@ SetConsoleScreenBufferSize(
        )
 {
 /* TO DO */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 /*--------------------------------------------------------------
  *     SetConsoleCursorInfo
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleCursorInfo(
@@ -973,26 +2538,29 @@ SetConsoleCursorInfo(
        CONST CONSOLE_CURSOR_INFO       *lpConsoleCursorInfo
        )
 {
-    DWORD   dwBytesReturned;
-       
-    if (DeviceIoControl (hConsoleOutput,
-                         IOCTL_CONSOLE_SET_CURSOR_INFO,
-                         (PCONSOLE_CURSOR_INFO)lpConsoleCursorInfo,
-                         sizeof(CONSOLE_CURSOR_INFO),
-                         NULL,
-                         0,
-                         &dwBytesReturned,
-                         NULL))
-        return TRUE;
-
-    return FALSE;
+   CSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+
+   Request.Type = CSRSS_SET_CURSOR_INFO;
+   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 ) )
+      {
+        SetLastErrorByStatus ( Status );
+        return FALSE;
+      }
+   return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     ScrollConsoleScreenBufferA
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ScrollConsoleScreenBufferA(
@@ -1003,15 +2571,42 @@ ScrollConsoleScreenBufferA(
        CONST CHAR_INFO         *lpFill
        )
 {
-/* TO DO */
-       return FALSE;
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+
+  Request.Type = CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER;
+  Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
+  Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
+
+  if (lpClipRectangle != NULL)
+    {
+  Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
+  Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
+    }
+  else
+    {
+  Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
+    }
+
+  Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
+  Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
+  Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+
+  if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+    {
+      SetLastErrorByStatus ( Status );
+      return FALSE;
+    }
+  return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     ScrollConsoleScreenBufferW
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ScrollConsoleScreenBufferW(
@@ -1023,14 +2618,16 @@ ScrollConsoleScreenBufferW(
        )
 {
 /* TO DO */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleWindowInfo
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleWindowInfo(
@@ -1040,74 +2637,150 @@ SetConsoleWindowInfo(
        )
 {
 /* TO DO */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 
 /*--------------------------------------------------------------
  *      SetConsoleTextAttribute
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleTextAttribute(
-       HANDLE          hConsoleOutput,
+        HANDLE         hConsoleOutput,
         WORD            wAttributes
         )
 {
-    DWORD dwBytesReturned;
+   CSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+
+   Request.Type = CSRSS_SET_ATTRIB;
+   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 ) )
+      {
+        SetLastErrorByStatus ( Status );
+        return FALSE;
+      }
+   return TRUE;
+}
+
 
-    if (!DeviceIoControl (hConsoleOutput,
-                          IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
-                          &wAttributes,
-                          sizeof(WORD),
-                          NULL,
-                          0,
-                          &dwBytesReturned,
-                          NULL))
-        return FALSE;
-    return TRUE;
+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);
+    }
 }
 
 
-/*--------------------------------------------------------------
- *     SetConsoleCtrlHandler
+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;
+  /* TO DO */
+  return FALSE;
 }
 
 
 /*--------------------------------------------------------------
  *     GetConsoleTitleW
+ *
+ * @implemented
  */
-#define MAX_CONSOLE_TITLE_LENGTH 80
-
-WINBASEAPI
 DWORD
 WINAPI
 GetConsoleTitleW(
@@ -1115,8 +2788,51 @@ GetConsoleTitleW(
        DWORD           nSize
        )
 {
-/* TO DO */
-       return 0;
+   CSRSS_API_REQUEST Request;
+   PCSRSS_API_REPLY Reply;
+   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;
+   }
+
+   Reply = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
+   if(Reply == NULL)
+   {
+      CloseHandle(hConsole);   
+      SetLastError(ERROR_OUTOFMEMORY);
+      return 0;
+   }
+
+   Request.Type = CSRSS_GET_TITLE;
+   Request.Data.GetTitleRequest.ConsoleHandle = hConsole;
+   
+   Status = CsrClientCallServer(&Request, Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
+   CloseHandle(hConsole);
+   if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Reply->Status)))
+   {
+      SetLastErrorByStatus(Status);
+      RtlFreeHeap(GetProcessHeap(), 0, Reply);
+      return 0;
+   }
+   
+   if(nSize * sizeof(WCHAR) < Reply->Data.GetTitleReply.Length)
+   {
+      wcsncpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title, nSize - 1);
+      lpConsoleTitle[nSize--] = L'\0';
+   }
+   else
+   {  
+      nSize = Reply->Data.GetTitleReply.Length / sizeof (WCHAR);
+      wcscpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title);
+      lpConsoleTitle[nSize] = L'\0';
+   }
+   
+   RtlFreeHeap(GetProcessHeap(), 0, Reply);
+   return nSize;
 }
 
 
@@ -1124,8 +2840,9 @@ GetConsoleTitleW(
  *     GetConsoleTitleA
  *
  *     19990306 EA
+ *
+ * @implemented
  */
-WINBASEAPI
 DWORD
 WINAPI
 GetConsoleTitleA(
@@ -1133,14 +2850,14 @@ 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 
@@ -1155,23 +2872,66 @@ GetConsoleTitleA(
                lpConsoleTitle[nWritten] = '\0';
                return nWritten;
        }
-#endif
+
        return 0;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleTitleW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleTitleW(
        LPCWSTR         lpConsoleTitle
        )
 {
-/* --- TO DO --- */
-       return FALSE;
+  PCSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  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(GetProcessHeap(),
+                           HEAP_ZERO_MEMORY,
+                           sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
+  if (Request == NULL)
+    {
+      CloseHandle(hConsole);
+      SetLastError(ERROR_OUTOFMEMORY);
+      return(FALSE);
+    }
+  
+  Request->Type = CSRSS_SET_TITLE;
+  Request->Data.SetTitleRequest.Console = hConsole;
+  
+  for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
+    Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
+  // add null
+  Request->Data.SetTitleRequest.Title[c] = 0;
+  Request->Data.SetTitleRequest.Length = c;  
+  Status = CsrClientCallServer(Request,
+                              &Reply,
+                              sizeof(CSRSS_API_REQUEST) + 
+                              c * sizeof(WCHAR),
+                              sizeof(CSRSS_API_REPLY));
+  CloseHandle(hConsole);
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
+    {
+      RtlFreeHeap( GetProcessHeap(), 0, Request );
+      SetLastErrorByStatus (Status);
+      return(FALSE);
+    }
+  RtlFreeHeap( GetProcessHeap(), 0, Request );
+  return TRUE;
 }
 
 
@@ -1179,51 +2939,67 @@ SetConsoleTitleW(
  *     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;
+  PCSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  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(GetProcessHeap(),
+                           HEAP_ZERO_MEMORY,
+                           sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
+  if (Request == NULL)
+    {
+      CloseHandle(hConsole);
+      SetLastError(ERROR_OUTOFMEMORY);
+      return(FALSE);
+    }
+  
+  Request->Type = CSRSS_SET_TITLE;
+  Request->Data.SetTitleRequest.Console = hConsole;
+  
+  for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
+    Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
+  // add null
+  Request->Data.SetTitleRequest.Title[c] = 0;
+  Request->Data.SetTitleRequest.Length = c;
+  Status = CsrClientCallServer(Request,
+                              &Reply,
+                              sizeof(CSRSS_API_REQUEST) + 
+                              c * sizeof(WCHAR),
+                              sizeof(CSRSS_API_REPLY));
+  CloseHandle(hConsole);
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
+    {
+      RtlFreeHeap( GetProcessHeap(), 0, Request );
+      SetLastErrorByStatus (Status);
+      return(FALSE);
+    }
+  RtlFreeHeap( GetProcessHeap(), 0, Request );
+  return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *     ReadConsoleW
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleW(
@@ -1235,14 +3011,16 @@ ReadConsoleW(
        )
 {
 /* --- TO DO --- */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 
 /*--------------------------------------------------------------
  *     WriteConsoleW
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleW(
@@ -1253,15 +3031,62 @@ WriteConsoleW(
        LPVOID           lpReserved
        )
 {
-/* --- TO DO --- */
-       return FALSE;
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
+#if 0
+  PCSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY Reply;
+  NTSTATUS Status;
+
+  Request = RtlAllocateHeap(GetProcessHeap(),
+                           HEAP_ZERO_MEMORY,
+                           sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite * sizeof(WCHAR));
+  if (Request == NULL)
+    {
+      SetLastError(ERROR_OUTOFMEMORY);
+      return(FALSE);
+    }
+
+  Request->Type = CSRSS_WRITE_CONSOLE;
+  Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
+  Request->Data.WriteConsoleRequest.NrCharactersToWrite =
+    nNumberOfCharsToWrite;
+//  DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite);
+//  DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer);
+  memcpy(Request->Data.WriteConsoleRequest.Buffer,
+        lpBuffer,
+        nNumberOfCharsToWrite * sizeof(WCHAR));
+
+  Status = CsrClientCallServer(Request,
+                              &Reply,
+                              sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite,
+                              sizeof(CSRSS_API_REPLY));
+
+  RtlFreeHeap(GetProcessHeap(),
+             0,
+             Request);
+
+  if (!NT_SUCCESS(Status))
+    {
+      return(FALSE);
+    }
+
+  if (lpNumberOfCharsWritten != NULL)
+    {
+      *lpNumberOfCharsWritten = 
+         Reply.Data.WriteConsoleReply.NrCharactersWritten;
+    }
+
+  return(TRUE);
+#endif
+  return(FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     CreateConsoleScreenBuffer
+ *
+ * @implemented
  */
-WINBASEAPI
 HANDLE
 WINAPI
 CreateConsoleScreenBuffer(
@@ -1272,66 +3097,210 @@ CreateConsoleScreenBuffer(
        LPVOID                           lpScreenBufferData
        )
 {
-/* --- TO DO --- */
-       return FALSE;
+   // FIXME: don't ignore access, share mode, and security
+   CSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
+   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 ) )
+      {
+        SetLastErrorByStatus ( Status );
+        return FALSE;
+      }
+   return Reply.Data.CreateScreenBufferReply.OutputHandle;
 }
 
 
 /*--------------------------------------------------------------
  *     GetConsoleCP
+ *
+ * @implemented
  */
-WINBASEAPI
 UINT
 WINAPI
 GetConsoleCP( VOID )
 {
-/* --- TO DO --- */
-       return CP_OEMCP; /* FIXME */
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY   Reply;
+  NTSTATUS          Status;
+   
+  Request.Type = CSRSS_GET_CONSOLE_CP;
+  Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
+                               sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus (Status);
+    return 0;
+  }
+  return Reply.Data.GetConsoleCodePage.CodePage;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleCP
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleCP(
        UINT            wCodePageID
        )
 {
-/* --- TO DO --- */
-       return FALSE;
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY   Reply;
+  NTSTATUS          Status;
+   
+  Request.Type = CSRSS_SET_CONSOLE_CP;
+  Request.Data.SetConsoleCodePage.CodePage = wCodePageID;
+  Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
+                               sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus (Status);
+  }
+  return NT_SUCCESS(Status);
 }
 
 
 /*--------------------------------------------------------------
  *     GetConsoleOutputCP
+ *
+ * @implemented
  */
-WINBASEAPI
 UINT
 WINAPI
 GetConsoleOutputCP( VOID )
 {
-/* --- TO DO --- */
-       return 0; /* FIXME */
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY   Reply;
+  NTSTATUS          Status;
+   
+  Request.Type = CSRSS_GET_CONSOLE_OUTPUT_CP;
+  Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
+                               sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus (Status);
+    return 0;
+  }
+  return Reply.Data.GetConsoleOutputCodePage.CodePage;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleOutputCP
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleOutputCP(
        UINT            wCodePageID
        )
 {
-/* --- TO DO --- */
-       return FALSE;
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY   Reply;
+  NTSTATUS          Status;
+   
+  Request.Type = CSRSS_SET_CONSOLE_OUTPUT_CP;
+  Request.Data.SetConsoleOutputCodePage.CodePage = wCodePageID;
+  Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
+                               sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus (Status);
+  }
+  return NT_SUCCESS(Status);
 }
 
 
-/* EOF */
+/*--------------------------------------------------------------
+ *     GetConsoleProcessList
+ *
+ * @unimplemented
+ */
+DWORD STDCALL
+GetConsoleProcessList(LPDWORD lpdwProcessList,
+                  DWORD dwProcessCount)
+{
+   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+   return 0;
+}
 
+
+
+/*--------------------------------------------------------------
+ *     GetConsoleSelectionInfo
+ *
+ * @unimplemented
+ */
+BOOL STDCALL
+GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
+{
+   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+   return FALSE;
+}
+
+
+
+/*--------------------------------------------------------------
+ *     AttachConsole
+ *
+ * @unimplemented
+ */
+BOOL STDCALL 
+AttachConsole(DWORD dwProcessId)
+{
+   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+   return FALSE;
+}
+
+/*--------------------------------------------------------------
+ *     GetConsoleWindow
+ *
+ * @implemented
+ */
+HWND STDCALL
+GetConsoleWindow (VOID)
+{
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY   Reply;
+  NTSTATUS          Status;
+   
+  Request.Type = CSRSS_GET_CONSOLE_WINDOW;
+  Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+  if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus (Status);
+    return (HWND) NULL;
+  }
+  return Reply.Data.GetConsoleWindowReply.WindowHandle;
+}
+
+
+/*--------------------------------------------------------------
+ *     SetConsoleIcon
+ *
+ * @implemented
+ */
+BOOL STDCALL SetConsoleIcon(HICON hicon)
+{
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY   Reply;
+  NTSTATUS          Status;
+  
+  Request.Type = CSRSS_SET_CONSOLE_ICON;
+  Request.Data.SetConsoleIconRequest.WindowIcon = hicon;
+  Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus (Status);
+    return FALSE;
+  }
+  return NT_SUCCESS(Status);
+}
+
+/* EOF */