- RtlReAllocateHeap shouldn't allocate memory if ptr == NULL.
[reactos.git] / reactos / lib / kernel32 / misc / console.c
index d6205b4..b93f0c8 100644 (file)
@@ -1,10 +1,11 @@
-/* $Id: console.c,v 1.52 2003/02/24 23:24:55 hbirr Exp $
+/* $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:      ???
+ * PROGRAMMER:      James Tabor 
+ *                     <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
  * UPDATE HISTORY:
  *     199901?? ??     Created
  *     19990204 EA     SetConsoleTitleA
 #include <k32.h>
 
 #define NDEBUG
-#include <kernel32/kernel32.h>
+#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 ULONG NrCtrlHandlers = 0;
+
 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,
@@ -35,6 +154,10 @@ AddConsoleAliasA (LPSTR Source,
   return FALSE;
 }
 
+
+/*
+ * @unimplemented
+ */
 BOOL STDCALL
 AddConsoleAliasW (LPWSTR Source,
                  LPWSTR Target,
@@ -44,6 +167,10 @@ AddConsoleAliasW (LPWSTR Source,
   return FALSE;
 }
 
+
+/*
+ * @unimplemented
+ */
 BOOL STDCALL
 ConsoleMenuControl (HANDLE     hConsole,
                    DWORD       Unknown1,
@@ -56,19 +183,45 @@ ConsoleMenuControl (HANDLE hConsole,
   return FALSE;
 }
 
-BOOL STDCALL
+
+/*
+ * @implemented
+ */
+HANDLE STDCALL
 DuplicateConsoleHandle (HANDLE hConsole,
-                       DWORD   Unknown1,
-                       DWORD   Unknown2,
-                       DWORD   Unknown3)
-     /*
-      * Undocumented
-      */
+                       DWORD   dwDesiredAccess,
+                       BOOL    bInheritHandle,
+                       DWORD   dwOptions)
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+  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)
      /*
@@ -80,6 +233,9 @@ ExpungeConsoleCommandHistoryW (DWORD Unknown0)
 }
 
 
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 ExpungeConsoleCommandHistoryA (DWORD   Unknown0)
      /*
@@ -90,6 +246,10 @@ ExpungeConsoleCommandHistoryA (DWORD        Unknown0)
   return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleAliasW (DWORD        Unknown0,
                  DWORD Unknown1,
@@ -104,6 +264,9 @@ GetConsoleAliasW (DWORD     Unknown0,
 }
 
 
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleAliasA (DWORD        Unknown0,
                  DWORD Unknown1,
@@ -117,6 +280,10 @@ GetConsoleAliasA (DWORD    Unknown0,
        return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleAliasExesW (DWORD    Unknown0,
                      DWORD     Unknown1)
@@ -129,7 +296,9 @@ GetConsoleAliasExesW (DWORD Unknown0,
 }
 
 
-
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleAliasExesA (DWORD    Unknown0,
                      DWORD     Unknown1)
@@ -142,7 +311,9 @@ GetConsoleAliasExesA (DWORD Unknown0,
 }
 
 
-
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleAliasExesLengthA (VOID)
      /*
@@ -153,6 +324,10 @@ GetConsoleAliasExesLengthA (VOID)
   return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleAliasExesLengthW (VOID)
      /*
@@ -163,6 +338,10 @@ GetConsoleAliasExesLengthW (VOID)
   return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleAliasesW (DWORD      Unknown0,
                    DWORD       Unknown1,
@@ -175,6 +354,10 @@ GetConsoleAliasesW (DWORD  Unknown0,
   return 0;
 }
  
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleAliasesA (DWORD      Unknown0,
                    DWORD       Unknown1,
@@ -187,6 +370,10 @@ GetConsoleAliasesA (DWORD  Unknown0,
   return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleAliasesLengthW (DWORD Unknown0)
      /*
@@ -197,6 +384,10 @@ GetConsoleAliasesLengthW (DWORD Unknown0)
   return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleAliasesLengthA (DWORD Unknown0)
      /*
@@ -207,6 +398,10 @@ GetConsoleAliasesLengthA (DWORD Unknown0)
   return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleCommandHistoryW (DWORD       Unknown0,
                           DWORD        Unknown1,
@@ -219,6 +414,10 @@ GetConsoleCommandHistoryW (DWORD   Unknown0,
   return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleCommandHistoryA (DWORD       Unknown0,
                           DWORD        Unknown1,
@@ -231,6 +430,10 @@ GetConsoleCommandHistoryA (DWORD   Unknown0,
   return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleCommandHistoryLengthW (DWORD Unknown0)
      /*
@@ -241,6 +444,10 @@ GetConsoleCommandHistoryLengthW (DWORD     Unknown0)
   return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleCommandHistoryLengthA (DWORD Unknown0)
      /*
@@ -251,6 +458,9 @@ GetConsoleCommandHistoryLengthA (DWORD      Unknown0)
   return 0;
 }
 
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleDisplayMode (LPDWORD lpdwMode)
      /*
@@ -265,6 +475,10 @@ GetConsoleDisplayMode (LPDWORD lpdwMode)
   return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleFontInfo (DWORD      Unknown0,
                    DWORD       Unknown1,
@@ -278,6 +492,10 @@ GetConsoleFontInfo (DWORD  Unknown0,
   return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetConsoleFontSize(HANDLE hConsoleOutput,
                   DWORD nFont)
@@ -286,18 +504,43 @@ GetConsoleFontSize(HANDLE hConsoleOutput,
   return 0;
 }
 
+
+/*
+ * @implemented
+ */
 DWORD STDCALL
-GetConsoleHardwareState (DWORD Unknown0,
-                        DWORD  Unknown1,
-                        DWORD  Unknown2)
+GetConsoleHardwareState (HANDLE        hConsole,
+                        DWORD  Flags,
+                        PDWORD State)
      /*
       * Undocumented
       */
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return 0;
+  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)
      /*
@@ -308,6 +551,10 @@ GetConsoleInputWaitHandle (VOID)
   return FALSE;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 GetCurrentConsoleFont(HANDLE hConsoleOutput,
                      BOOL bMaximumWindow,
@@ -317,6 +564,10 @@ GetCurrentConsoleFont(HANDLE hConsoleOutput,
   return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 ULONG STDCALL
 GetNumberOfConsoleFonts (VOID)
      /*
@@ -327,6 +578,10 @@ GetNumberOfConsoleFonts (VOID)
   return 1; /* FIXME: call csrss.exe */
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 InvalidateConsoleDIBits (DWORD Unknown0,
                         DWORD  Unknown1)
@@ -338,20 +593,67 @@ InvalidateConsoleDIBits (DWORD    Unknown0,
   return 0;
 }
 
-DWORD STDCALL
-OpenConsoleW (DWORD    Unknown0,
-             DWORD     Unknown1,
-             DWORD     Unknown2,
-             DWORD     Unknown3)
+
+/*
+ * @unimplemented
+ */
+HANDLE STDCALL
+OpenConsoleW (LPWSTR  wsName,
+             DWORD   dwDesiredAccess,
+             BOOL    bInheritHandle,
+             DWORD   dwCreationDistribution)
      /*
       * Undocumented
       */
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return 0;
+  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);
 }
 
-WINBOOL STDCALL
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
 SetConsoleCommandHistoryMode (DWORD    dwMode)
      /*
       * Undocumented
@@ -361,7 +663,11 @@ SetConsoleCommandHistoryMode (DWORD        dwMode)
   return FALSE;
 }
 
-WINBOOL STDCALL
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
 SetConsoleCursor (DWORD        Unknown0,
                  DWORD Unknown1)
      /*
@@ -372,7 +678,11 @@ SetConsoleCursor (DWORD    Unknown0,
   return FALSE;
 }
 
-WINBOOL STDCALL
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
 SetConsoleDisplayMode (HANDLE hOut,
                       DWORD dwNewMode,
                       LPDWORD lpdwOldMode)
@@ -388,7 +698,11 @@ SetConsoleDisplayMode (HANDLE hOut,
   return FALSE;
 }
 
-WINBOOL STDCALL
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
 SetConsoleFont (DWORD  Unknown0,
                DWORD   Unknown1)
      /*
@@ -399,19 +713,44 @@ SetConsoleFont (DWORD     Unknown0,
   return FALSE;
 }
 
-WINBOOL STDCALL
-SetConsoleHardwareState (DWORD Unknown0,
-                        DWORD  Unknown1,
-                        DWORD  Unknown2)
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetConsoleHardwareState (HANDLE        hConsole,
+                        DWORD  Flags,
+                        DWORD  State)
      /*
       * Undocumented
       */
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+  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;  
 }
 
-WINBOOL STDCALL
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
 SetConsoleKeyShortcuts (DWORD  Unknown0,
                        DWORD   Unknown1,
                        DWORD   Unknown2,
@@ -424,7 +763,11 @@ SetConsoleKeyShortcuts (DWORD      Unknown0,
   return FALSE;
 }
 
-WINBOOL STDCALL
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
 SetConsoleMaximumWindowSize (DWORD     Unknown0,
                             DWORD      Unknown1)
      /*
@@ -435,7 +778,11 @@ SetConsoleMaximumWindowSize (DWORD Unknown0,
   return FALSE;
 }
 
-WINBOOL STDCALL
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
 SetConsoleMenuClose (DWORD     Unknown0)
      /*
       * Undocumented
@@ -445,7 +792,11 @@ SetConsoleMenuClose (DWORD Unknown0)
   return FALSE;
 }
 
-WINBOOL STDCALL
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
 SetConsoleNumberOfCommandsA (DWORD     Unknown0,
                             DWORD      Unknown1)
      /*
@@ -456,7 +807,11 @@ SetConsoleNumberOfCommandsA (DWORD Unknown0,
   return FALSE;
 }
 
-WINBOOL STDCALL
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
 SetConsoleNumberOfCommandsW (DWORD     Unknown0,
                             DWORD      Unknown1)
      /*
@@ -467,7 +822,11 @@ SetConsoleNumberOfCommandsW (DWORD Unknown0,
   return FALSE;
 }
 
-WINBOOL STDCALL
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
 SetConsolePalette (DWORD       Unknown0,
                   DWORD        Unknown1,
                   DWORD        Unknown2)
@@ -479,7 +838,11 @@ SetConsolePalette (DWORD   Unknown0,
   return FALSE;
 }
 
-WINBOOL STDCALL
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
 SetLastConsoleEventActive (VOID)
      /*
       * Undocumented
@@ -489,6 +852,10 @@ SetLastConsoleEventActive (VOID)
   return FALSE;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 ShowConsoleCursor (DWORD       Unknown0,
                   DWORD        Unknown1)
@@ -500,16 +867,44 @@ ShowConsoleCursor (DWORD  Unknown0,
   return 0;
 }
 
-DWORD STDCALL
-VerifyConsoleIoHandle (DWORD   Unknown0)
-     /*
-      * Undocumented
-      */
+
+/*
+ * FUNCTION: Checks whether the given handle is a valid console handle.
+ * ARGUMENTS:
+ *      Handle - Handle to be checked
+ * RETURNS:
+ *      TRUE: Handle is a valid console handle
+ *      FALSE: Handle is not a valid console handle.
+ * STATUS: Officially undocumented
+ *
+ * @implemented
+ */
+BOOL STDCALL
+VerifyConsoleIoHandle(HANDLE Handle)
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return 0;
+  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,
@@ -520,6 +915,10 @@ WriteConsoleInputVDMA (DWORD       Unknown0,
   return 0;
 }
 
+
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 WriteConsoleInputVDMW (DWORD   Unknown0,
                       DWORD    Unknown1,
@@ -530,7 +929,11 @@ WriteConsoleInputVDMW (DWORD       Unknown0,
   return 0;
 }
 
-WINBOOL STDCALL 
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
 CloseConsoleHandle(HANDLE Handle)
      /*
       * Undocumented
@@ -552,19 +955,20 @@ CloseConsoleHandle(HANDLE Handle)
                               &Reply,
                               sizeof(CSRSS_API_REQUEST),
                               sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status))
+    {
+       SetLastErrorByStatus(Status);
+       return FALSE;
+    }
 
-  if (NT_SUCCESS(Status))
-  {
-     return TRUE;
-  }
-  else
-  {
-     SetLastErrorByStatus(Status);
-     return FALSE;
-  }
+  return TRUE;
 }
 
-BOOLEAN STDCALL 
+
+/*
+ * internal function
+ */
+BOOL STDCALL
 IsConsoleHandle(HANDLE Handle)
 {
   if ((((ULONG)Handle) & 0x10000003) == 0x3)
@@ -574,7 +978,11 @@ IsConsoleHandle(HANDLE Handle)
   return(FALSE);
 }
 
-HANDLE STDCALL 
+
+/*
+ * @implemented
+ */
+HANDLE STDCALL
 GetStdHandle(DWORD nStdHandle)
      /*
       * FUNCTION: Get a handle for the standard input, standard output
@@ -586,19 +994,29 @@ GetStdHandle(DWORD nStdHandle)
       */
 {
   PRTL_USER_PROCESS_PARAMETERS Ppb;
-  
-  Ppb = NtCurrentPeb()->ProcessParameters;  
+
+  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;
+      case STD_INPUT_HANDLE:
+       return Ppb->hStdInput;
+
+      case STD_OUTPUT_HANDLE:
+       return Ppb->hStdOutput;
+
+      case STD_ERROR_HANDLE:
+       return Ppb->hStdError;
     }
+
   SetLastError (ERROR_INVALID_PARAMETER);
   return INVALID_HANDLE_VALUE;
 }
 
-WINBASEAPI BOOL WINAPI 
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
 SetStdHandle(DWORD nStdHandle,
             HANDLE hHandle)
      /*
@@ -611,38 +1029,38 @@ SetStdHandle(DWORD nStdHandle,
       */
 {
   PRTL_USER_PROCESS_PARAMETERS Ppb;
-   
+
+  /* no need to check if hHandle == INVALID_HANDLE_VALUE */
+
   Ppb = NtCurrentPeb()->ProcessParameters;
-  
-  /* More checking needed? */
-  if (hHandle == INVALID_HANDLE_VALUE)
-    {
-      SetLastError (ERROR_INVALID_HANDLE);
-      return FALSE;
-    }
-   
-  SetLastError(ERROR_SUCCESS); /* OK */
+
   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;
+      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;
     }
-  SetLastError (ERROR_INVALID_PARAMETER);
+
+  /* windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
+  SetLastError (ERROR_INVALID_HANDLE);
   return FALSE;
 }
 
 
 /*--------------------------------------------------------------
  *     WriteConsoleA
+ *
+ * @implemented
  */
-WINBOOL STDCALL 
+BOOL STDCALL 
 WriteConsoleA(HANDLE hConsoleOutput,
              CONST VOID *lpBuffer,
              DWORD nNumberOfCharsToWrite,
@@ -654,17 +1072,17 @@ WriteConsoleA(HANDLE hConsoleOutput,
   NTSTATUS Status;
   USHORT Size;
   ULONG MessageSize;
-  
-  Request = RtlAllocateHeap(GetProcessHeap(),
-                           HEAP_ZERO_MEMORY,
-                           sizeof(CSRSS_API_REQUEST) + 
-                           CSRSS_MAX_WRITE_CONSOLE_REQUEST);
+
+  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)
@@ -680,7 +1098,7 @@ WriteConsoleA(HANDLE hConsoleOutput,
          Size = nNumberOfCharsToWrite;
        }
       Request->Data.WriteConsoleRequest.NrCharactersToWrite = Size;
-      
+
       memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, Size);
 
       MessageSize = CSRSS_REQUEST_HEADER_SIZE + 
@@ -689,7 +1107,7 @@ WriteConsoleA(HANDLE hConsoleOutput,
                                   &Reply,
                                   MessageSize,
                                   sizeof(CSRSS_API_REPLY));
-      
+
       if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
        {
          RtlFreeHeap(GetProcessHeap(), 0, Request);
@@ -699,15 +1117,19 @@ WriteConsoleA(HANDLE hConsoleOutput,
       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,
@@ -718,9 +1140,8 @@ WINBOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
    NTSTATUS Status;
    ULONG CharsRead = 0;
    
-   Reply = RtlAllocateHeap(GetProcessHeap(),
-                    HEAP_ZERO_MEMORY,
-                    sizeof(CSRSS_API_REPLY) + nNumberOfCharsToRead);
+   Reply = RtlAllocateHeap(GetProcessHeap(), 0,
+                           sizeof(CSRSS_API_REPLY) + nNumberOfCharsToRead);
    if (Reply == NULL)
      {
        SetLastError(ERROR_OUTOFMEMORY);
@@ -799,12 +1220,24 @@ WINBOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
 
 /*--------------------------------------------------------------
  *     AllocConsole
+ *
+ * @implemented
  */
-WINBOOL STDCALL AllocConsole(VOID)
+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 ) );
@@ -813,27 +1246,50 @@ WINBOOL STDCALL AllocConsole(VOID)
         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 );
-   SetStdHandle( STD_ERROR_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)
 {
-   DbgPrint("FreeConsole() is unimplemented\n");
-   return FALSE;
+    // AG: I'm not sure if this is correct (what happens to std handles?)
+    // but I just tried to reverse what AllocConsole() does...
+
+   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,
@@ -859,8 +1315,10 @@ GetConsoleScreenBufferInfo(
 
 /*--------------------------------------------------------------
  *     SetConsoleCursorPosition
+ *
+ * @implemented
  */
-WINBOOL
+BOOL
 STDCALL
 SetConsoleCursorPosition(
     HANDLE hConsoleOutput,
@@ -886,8 +1344,10 @@ SetConsoleCursorPosition(
 
 /*--------------------------------------------------------------
  *     FillConsoleOutputCharacterA
+ *
+ * @implemented
  */
-WINBOOL STDCALL
+BOOL STDCALL
 FillConsoleOutputCharacterA(
        HANDLE          hConsoleOutput,
        CHAR            cCharacter,
@@ -919,8 +1379,10 @@ FillConsoleOutputCharacterA(
 
 /*--------------------------------------------------------------
  *     FillConsoleOutputCharacterW
+ *
+ * @unimplemented
  */
-WINBOOL
+BOOL
 STDCALL
 FillConsoleOutputCharacterW(
        HANDLE          hConsoleOutput,
@@ -931,21 +1393,24 @@ FillConsoleOutputCharacterW(
        )
 {
 /* TO DO */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 
 /*--------------------------------------------------------------
- *     PeekConsoleInputA
+ *     IntPeekConsoleInput
+ *
+ * INTERNAL
  */
-WINBASEAPI
 BOOL
 WINAPI
-PeekConsoleInputA(
+IntPeekConsoleInput(
        HANDLE                  hConsoleInput,
        PINPUT_RECORD           lpBuffer,
        DWORD                   nLength,
-       LPDWORD                 lpNumberOfEventsRead
+       LPDWORD                 lpNumberOfEventsRead,
+       BOOL                    bUnicode
        )
 {
   PCSRSS_API_REQUEST Request;
@@ -980,6 +1445,7 @@ PeekConsoleInputA(
   
   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;
   
@@ -1000,14 +1466,33 @@ PeekConsoleInputA(
   RtlFreeHeap(GetProcessHeap(), 0, Request);
   CsrReleaseParameterBuffer(BufferBase);  
   
-       return TRUE;
+  return TRUE;
+}
+
+/*--------------------------------------------------------------
+ *     PeekConsoleInputA
+ *
+ * @implemented
+ */
+BOOL
+WINAPI
+PeekConsoleInputA(
+       HANDLE                  hConsoleInput,
+       PINPUT_RECORD           lpBuffer,
+       DWORD                   nLength,
+       LPDWORD                 lpNumberOfEventsRead
+       )
+{
+  return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, FALSE);
 }
 
 
 /*--------------------------------------------------------------
  *     PeekConsoleInputW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 PeekConsoleInputW(
@@ -1017,19 +1502,22 @@ PeekConsoleInputW(
        LPDWORD                 lpNumberOfEventsRead
        )    
 {
-/* TO DO */
-       return FALSE;
+  return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, TRUE);
 }
 
 
 /*--------------------------------------------------------------
- *     ReadConsoleInputA
+ *     IntReadConsoleInput
+ *
+ * INTERNAL
  */
-WINBASEAPI BOOL WINAPI
-ReadConsoleInputA(HANDLE hConsoleInput,
-                 PINPUT_RECORD lpBuffer,
-                 DWORD nLength,
-                 LPDWORD lpNumberOfEventsRead)
+BOOL WINAPI
+IntReadConsoleInput(HANDLE hConsoleInput,
+                    PINPUT_RECORD lpBuffer,
+                    DWORD nLength,
+                    LPDWORD lpNumberOfEventsRead,
+                    BOOL bUnicode)
 {
   CSRSS_API_REQUEST Request;
   CSRSS_API_REPLY Reply;
@@ -1058,6 +1546,7 @@ ReadConsoleInputA(HANDLE hConsoleInput,
       
       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))
@@ -1067,10 +1556,9 @@ ReadConsoleInputA(HANDLE hConsoleInput,
        }
     }
   
-  NumEventsRead = 0;
+  NumEventsRead = 1;
   *lpBuffer = Reply.Data.ReadInputReply.Input;
   lpBuffer++;
-  NumEventsRead++;
   
   while ((NumEventsRead < nLength) && (Reply.Data.ReadInputReply.MoreEvents))
     {
@@ -1098,10 +1586,27 @@ ReadConsoleInputA(HANDLE hConsoleInput,
 }
 
 
+/*--------------------------------------------------------------
+ *     ReadConsoleInputA
+ *
+ * @implemented
+ */
+BOOL WINAPI
+ReadConsoleInputA(HANDLE hConsoleInput,
+                 PINPUT_RECORD lpBuffer,
+                 DWORD nLength,
+                 LPDWORD lpNumberOfEventsRead)
+{
+  return IntReadConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, FALSE);
+}
+
+
 /*--------------------------------------------------------------
  *     ReadConsoleInputW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleInputW(
@@ -1111,15 +1616,16 @@ ReadConsoleInputW(
        LPDWORD                 lpNumberOfEventsRead
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntReadConsoleInput(hConsoleInput, lpBuffer, nLength,
+                             lpNumberOfEventsRead, TRUE);
 }
 
 
 /*--------------------------------------------------------------
  *     WriteConsoleInputA
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleInputA(
@@ -1183,8 +1689,9 @@ WriteConsoleInputA(
 
 /*--------------------------------------------------------------
  *     WriteConsoleInputW
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleInputW(
@@ -1195,22 +1702,25 @@ WriteConsoleInputW(
        )
 {
 /* TO DO */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 
 /*--------------------------------------------------------------
- *     ReadConsoleOutputA
+ *     IntReadConsoleOutput
+ *
+ * INTERNAL
  */
-WINBASEAPI
 BOOL
 WINAPI
-ReadConsoleOutputA(
-       HANDLE          hConsoleOutput,
-       PCHAR_INFO      lpBuffer,
-       COORD           dwBufferSize,
-       COORD           dwBufferCoord,
-       PSMALL_RECT     lpReadRegion
+IntReadConsoleOutput(
+       HANDLE          hConsoleOutput,
+       PCHAR_INFO      lpBuffer,
+       COORD           dwBufferSize,
+       COORD           dwBufferCoord,
+       PSMALL_RECT     lpReadRegion,
+       BOOL            bUnicode
        )
 {
   PCSRSS_API_REQUEST Request;
@@ -1245,6 +1755,7 @@ ReadConsoleOutputA(
    
   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;
@@ -1271,11 +1782,31 @@ ReadConsoleOutputA(
   return TRUE;
 }
 
+/*--------------------------------------------------------------
+ *     ReadConsoleOutputA
+ *
+ * @implemented
+ */
+BOOL
+WINAPI
+ReadConsoleOutputA(
+       HANDLE          hConsoleOutput,
+       PCHAR_INFO      lpBuffer,
+       COORD           dwBufferSize,
+       COORD           dwBufferCoord,
+       PSMALL_RECT     lpReadRegion
+       )
+{
+  return IntReadConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
+                             dwBufferCoord, lpReadRegion, FALSE);
+}
+
 
 /*--------------------------------------------------------------
  *     ReadConsoleOutputW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputW(
@@ -1286,26 +1817,28 @@ ReadConsoleOutputW(
        PSMALL_RECT     lpReadRegion
        )
 {
-/* TO DO */
-       return FALSE;
+  return IntReadConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
+                             dwBufferCoord, lpReadRegion, TRUE);
 }
 
+
 /*--------------------------------------------------------------
- *     WriteConsoleOutputA
+ *     IntWriteConsoleOutput
+ *
+ * INTERNAL
  */
-WINBASEAPI BOOL WINAPI
-WriteConsoleOutputA(HANDLE              hConsoleOutput,
-                   CONST CHAR_INFO     *lpBuffer,
-                   COORD                dwBufferSize,
-                   COORD                dwBufferCoord,
-                   PSMALL_RECT  lpWriteRegion)
+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;
-  BOOLEAN Result;
-  ULONG i, j;
   PVOID BufferBase;
   PVOID BufferTargetBase;
 
@@ -1331,6 +1864,7 @@ WriteConsoleOutputA(HANDLE                 hConsoleOutput,
     }
   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;
@@ -1354,11 +1888,28 @@ WriteConsoleOutputA(HANDLE               hConsoleOutput,
   return(TRUE);
 }
 
+/*--------------------------------------------------------------
+ *     WriteConsoleOutputA
+ *
+ * @implemented
+ */
+BOOL WINAPI
+WriteConsoleOutputA(HANDLE              hConsoleOutput,
+                   CONST CHAR_INFO     *lpBuffer,
+                   COORD                dwBufferSize,
+                   COORD                dwBufferCoord,
+                   PSMALL_RECT  lpWriteRegion)
+{
+  return IntWriteConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
+                               dwBufferCoord, lpWriteRegion, FALSE);
+}
+
 
 /*--------------------------------------------------------------
  *     WriteConsoleOutputW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleOutputW(
@@ -1369,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(
@@ -1393,9 +1945,9 @@ ReadConsoleOutputCharacterA(
   NTSTATUS Status;
   DWORD Size;
 
-  Reply = RtlAllocateHeap(GetProcessHeap(),
-                         HEAP_ZERO_MEMORY,
-                         sizeof(CSRSS_API_REPLY) + CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR);
+  Reply = RtlAllocateHeap(GetProcessHeap(), 0,
+                         sizeof(CSRSS_API_REPLY) +
+                         min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR));
   if (Reply == NULL)
     {
       SetLastError(ERROR_OUTOFMEMORY);
@@ -1443,8 +1995,9 @@ ReadConsoleOutputCharacterA(
 
 /*--------------------------------------------------------------
  *      ReadConsoleOutputCharacterW
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputCharacterW(
@@ -1456,14 +2009,16 @@ ReadConsoleOutputCharacterW(
        )
 {
 /* TO DO */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 
 /*--------------------------------------------------------------
  *     ReadConsoleOutputAttribute
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleOutputAttribute(
@@ -1479,9 +2034,9 @@ ReadConsoleOutputAttribute(
   NTSTATUS Status;
   DWORD Size, i;
   
-  Reply = RtlAllocateHeap(GetProcessHeap(),
-                         HEAP_ZERO_MEMORY,
-                         sizeof(CSRSS_API_REPLY) + CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB);
+  Reply = RtlAllocateHeap(GetProcessHeap(), 0,
+                         sizeof(CSRSS_API_REPLY) +
+                         min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB));
   if (Reply == NULL)
     {
       SetLastError(ERROR_OUTOFMEMORY);
@@ -1531,8 +2086,10 @@ ReadConsoleOutputAttribute(
 
 /*--------------------------------------------------------------
  *     WriteConsoleOutputCharacterA
+ *
+ * @implemented
  */
-WINBASEAPI BOOL WINAPI
+BOOL WINAPI
 WriteConsoleOutputCharacterA(HANDLE            hConsoleOutput,
                             LPCSTR             lpCharacter,
                             DWORD              nLength,
@@ -1543,10 +2100,10 @@ WriteConsoleOutputCharacterA(HANDLE             hConsoleOutput,
   CSRSS_API_REPLY Reply;
   NTSTATUS Status;
   WORD Size;
-  
-  Request = RtlAllocateHeap(GetProcessHeap(),
-                           HEAP_ZERO_MEMORY,
-                           sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR);
+
+  Request = RtlAllocateHeap(GetProcessHeap(), 0,
+                           sizeof(CSRSS_API_REQUEST) +
+                           min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR));
   if( !Request )
     {
       SetLastError( ERROR_OUTOFMEMORY );
@@ -1583,28 +2140,72 @@ WriteConsoleOutputCharacterA(HANDLE             hConsoleOutput,
 
 /*--------------------------------------------------------------
  *     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(
@@ -1621,9 +2222,9 @@ WriteConsoleOutputAttribute(
    WORD Size;
    int c;
 
-   Request = RtlAllocateHeap(GetProcessHeap(),
-                      HEAP_ZERO_MEMORY,
-                      sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB);
+   Request = RtlAllocateHeap(GetProcessHeap(), 0,
+                            sizeof(CSRSS_API_REQUEST) +
+                            min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB));
    if( !Request )
      {
        SetLastError( ERROR_OUTOFMEMORY );
@@ -1659,8 +2260,9 @@ WriteConsoleOutputAttribute(
 
 /*--------------------------------------------------------------
  *     FillConsoleOutputAttribute
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 FillConsoleOutputAttribute(
@@ -1694,8 +2296,9 @@ FillConsoleOutputAttribute(
 
 /*--------------------------------------------------------------
  *     GetConsoleMode
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetConsoleMode(
@@ -1707,7 +2310,7 @@ GetConsoleMode(
   CSRSS_API_REPLY Reply;
   NTSTATUS Status;
   
-  Request.Type = CSRSS_GET_MODE;
+  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 ) )
@@ -1722,8 +2325,9 @@ GetConsoleMode(
 
 /*--------------------------------------------------------------
  *     GetNumberOfConsoleInputEvents
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetNumberOfConsoleInputEvents(
@@ -1758,8 +2362,9 @@ GetNumberOfConsoleInputEvents(
 
 /*--------------------------------------------------------------
  *     GetLargestConsoleWindowSize
+ *
+ * @unimplemented
  */
-WINBASEAPI
 COORD
 WINAPI
 GetLargestConsoleWindowSize(
@@ -1777,8 +2382,9 @@ GetLargestConsoleWindowSize(
 
 /*--------------------------------------------------------------
  *     GetConsoleCursorInfo
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetConsoleCursorInfo(
@@ -1806,8 +2412,9 @@ GetConsoleCursorInfo(
 
 /*--------------------------------------------------------------
  *     GetNumberOfConsoleMouseButtons
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 GetNumberOfConsoleMouseButtons(
@@ -1821,8 +2428,9 @@ GetNumberOfConsoleMouseButtons(
 
 /*--------------------------------------------------------------
  *     SetConsoleMode
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleMode(
@@ -1834,7 +2442,7 @@ SetConsoleMode(
   CSRSS_API_REPLY Reply;
   NTSTATUS Status;
   
-  Request.Type = CSRSS_SET_MODE;
+  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 ) );
@@ -1849,8 +2457,9 @@ SetConsoleMode(
 
 /*--------------------------------------------------------------
  *     SetConsoleActiveScreenBuffer
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleActiveScreenBuffer(
@@ -1862,7 +2471,7 @@ SetConsoleActiveScreenBuffer(
    NTSTATUS Status;
 
    Request.Type = CSRSS_SET_SCREEN_BUFFER;
-   Request.Data.SetActiveScreenBufferRequest.OutputHandle = hConsoleOutput;
+   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 ) )
       {
@@ -1875,8 +2484,9 @@ SetConsoleActiveScreenBuffer(
 
 /*--------------------------------------------------------------
  *     FlushConsoleInputBuffer
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 FlushConsoleInputBuffer(
@@ -1901,8 +2511,9 @@ FlushConsoleInputBuffer(
 
 /*--------------------------------------------------------------
  *     SetConsoleScreenBufferSize
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleScreenBufferSize(
@@ -1911,13 +2522,15 @@ SetConsoleScreenBufferSize(
        )
 {
 /* TO DO */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 /*--------------------------------------------------------------
  *     SetConsoleCursorInfo
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleCursorInfo(
@@ -1945,8 +2558,9 @@ SetConsoleCursorInfo(
 
 /*--------------------------------------------------------------
  *     ScrollConsoleScreenBufferA
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ScrollConsoleScreenBufferA(
@@ -1990,8 +2604,9 @@ ScrollConsoleScreenBufferA(
 
 /*--------------------------------------------------------------
  *     ScrollConsoleScreenBufferW
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ScrollConsoleScreenBufferW(
@@ -2003,14 +2618,16 @@ ScrollConsoleScreenBufferW(
        )
 {
 /* TO DO */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleWindowInfo
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleWindowInfo(
@@ -2020,14 +2637,16 @@ SetConsoleWindowInfo(
        )
 {
 /* TO DO */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 
 /*--------------------------------------------------------------
  *      SetConsoleTextAttribute
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleTextAttribute(
@@ -2051,6 +2670,7 @@ SetConsoleTextAttribute(
    return TRUE;
 }
 
+
 BOOL STATIC
 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
 {
@@ -2062,13 +2682,20 @@ AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
   else
     {
       NrCtrlHandlers++;
-      CtrlHandlers = 
-       RtlReAllocateHeap(RtlGetProcessHeap(),
-                          HEAP_ZERO_MEMORY,
-                          (PVOID)CtrlHandlers,
-                          NrCtrlHandlers * sizeof(PHANDLER_ROUTINE)); 
+      if (CtrlHandlers == NULL)
+        {
+          CtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
+                                         NrCtrlHandlers * sizeof(PHANDLER_ROUTINE)); 
+        }
+      else
+        {
+          CtrlHandlers = RtlReAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
+                                           (PVOID)CtrlHandlers,
+                                           NrCtrlHandlers * sizeof(PHANDLER_ROUTINE)); 
+        }
       if (CtrlHandlers == NULL)
        {
+         NrCtrlHandlers = 0;
          SetLastError(ERROR_NOT_ENOUGH_MEMORY);
          return(FALSE);
        }
@@ -2077,6 +2704,7 @@ AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
     }
 }
 
+
 BOOL STATIC
 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
 {
@@ -2091,10 +2719,11 @@ RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
     {
       for (i = 0; i < NrCtrlHandlers; i++)
        {
-         if (CtrlHandlers[i] == HandlerRoutine)
+         if ( ((void*)(CtrlHandlers[i])) == (void*)HandlerRoutine)
            {
-             CtrlHandlers[i] = CtrlHandlers[NrCtrlHandlers - 1];
              NrCtrlHandlers--;
+             memmove(CtrlHandlers + i, CtrlHandlers + i + 1, 
+                     (NrCtrlHandlers - i) * sizeof(PHANDLER_ROUTINE));
              CtrlHandlers = 
                RtlReAllocateHeap(RtlGetProcessHeap(),
                                  HEAP_ZERO_MEMORY,
@@ -2107,8 +2736,12 @@ RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
   return(FALSE);
 }
 
-WINBASEAPI BOOL WINAPI
-SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
+SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
                      BOOL Add)
 {
   BOOLEAN Ret;
@@ -2129,8 +2762,10 @@ SetConsoleCtrlHandler(PHANDLER_ROUTINE   HandlerRoutine,
 
 /*--------------------------------------------------------------
  *     GenerateConsoleCtrlEvent
+ *
+ * @unimplemented
  */
-WINBASEAPI BOOL WINAPI
+BOOL WINAPI
 GenerateConsoleCtrlEvent(
        DWORD           dwCtrlEvent,
        DWORD           dwProcessGroupId
@@ -2143,10 +2778,9 @@ GenerateConsoleCtrlEvent(
 
 /*--------------------------------------------------------------
  *     GetConsoleTitleW
+ *
+ * @implemented
  */
-#define MAX_CONSOLE_TITLE_LENGTH 80
-
-WINBASEAPI
 DWORD
 WINAPI
 GetConsoleTitleW(
@@ -2154,60 +2788,51 @@ GetConsoleTitleW(
        DWORD           nSize
        )
 {
-       union {
-       CSRSS_API_REQUEST       quest;
-       CSRSS_API_REPLY         ply;
-       } Re;
-       NTSTATUS                Status;
-
-       /* Marshall data */
-       Re.quest.Type = CSRSS_GET_TITLE;
-       Re.quest.Data.GetTitleRequest.ConsoleHandle =
-               GetStdHandle (STD_INPUT_HANDLE);
-
-       /* Call CSRSS */
-       Status = CsrClientCallServer (
-                       & Re.quest,
-                       & Re.ply,
-                       (sizeof (CSRSS_GET_TITLE_REQUEST) +
-                       sizeof (LPC_MESSAGE) +
-                       sizeof (ULONG)),
-                       sizeof (CSRSS_API_REPLY)
-                       );
-       if (    !NT_SUCCESS(Status)
-               || !NT_SUCCESS (Status = Re.ply.Status)
-               )
-       {
-               SetLastErrorByStatus (Status);
-               return (0);
-       }
+   CSRSS_API_REQUEST Request;
+   PCSRSS_API_REPLY Reply;
+   NTSTATUS Status;
+   HANDLE hConsole;
 
-       /* Convert size in characters to size in bytes */
-       nSize = sizeof (WCHAR) * nSize;
+   hConsole = CreateFileW(L"CONIN$", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+   if (hConsole == INVALID_HANDLE_VALUE)
+   {
+      return 0;
+   }
 
-       /* Unmarshall data */
-       if (nSize < Re.ply.Data.GetTitleReply.Length)
-       {
-               DbgPrint ("%s: ret=%d\n", __FUNCTION__, Re.ply.Data.GetTitleReply.Length);
-               nSize /= sizeof (WCHAR);
-               if (nSize > 1)
-               {
-                       wcsncpy (
-                               lpConsoleTitle,
-                               Re.ply.Data.GetTitleReply.Title,
-                               (nSize - 1)
-                               );
-                       /* Add null */
-                       lpConsoleTitle [nSize --] = L'\0';
-               }
-       }
-       else
-       {
-               nSize = Re.ply.Data.GetTitleReply.Length / sizeof (WCHAR);
-               wcscpy (lpConsoleTitle, Re.ply.Data.GetTitleReply.Title);
-       }
+   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;
+   }
 
-       return nSize;
+   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;
 }
 
 
@@ -2215,8 +2840,9 @@ GetConsoleTitleW(
  *     GetConsoleTitleA
  *
  *     19990306 EA
+ *
+ * @implemented
  */
-WINBASEAPI
 DWORD
 WINAPI
 GetConsoleTitleA(
@@ -2224,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 
@@ -2246,15 +2872,16 @@ GetConsoleTitleA(
                lpConsoleTitle[nWritten] = '\0';
                return nWritten;
        }
-#endif
+
        return 0;
 }
 
 
 /*--------------------------------------------------------------
  *     SetConsoleTitleW
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleTitleW(
@@ -2265,18 +2892,26 @@ SetConsoleTitleW(
   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 = GetStdHandle( STD_INPUT_HANDLE );
+  Request->Data.SetTitleRequest.Console = hConsole;
   
   for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
     Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
@@ -2285,12 +2920,10 @@ SetConsoleTitleW(
   Request->Data.SetTitleRequest.Length = c;  
   Status = CsrClientCallServer(Request,
                               &Reply,
-                              sizeof(CSRSS_SET_TITLE_REQUEST) +
-                              c +
-                              sizeof( LPC_MESSAGE ) +
-                              sizeof( ULONG ),
+                              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 );
@@ -2306,8 +2939,9 @@ SetConsoleTitleW(
  *     SetConsoleTitleA
  *     
  *     19990204 EA     Added
+ *
+ * @implemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 SetConsoleTitleA(
@@ -2318,18 +2952,26 @@ SetConsoleTitleA(
   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 = GetStdHandle( STD_INPUT_HANDLE );
+  Request->Data.SetTitleRequest.Console = hConsole;
   
   for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
     Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
@@ -2338,12 +2980,10 @@ SetConsoleTitleA(
   Request->Data.SetTitleRequest.Length = c;
   Status = CsrClientCallServer(Request,
                               &Reply,
-                              sizeof(CSRSS_SET_TITLE_REQUEST) +
-                              c +
-                              sizeof( LPC_MESSAGE ) +
-                              sizeof( ULONG ),
+                              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 );
@@ -2357,8 +2997,9 @@ SetConsoleTitleA(
 
 /*--------------------------------------------------------------
  *     ReadConsoleW
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 ReadConsoleW(
@@ -2370,14 +3011,16 @@ ReadConsoleW(
        )
 {
 /* --- TO DO --- */
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
        return FALSE;
 }
 
 
 /*--------------------------------------------------------------
  *     WriteConsoleW
+ *
+ * @unimplemented
  */
-WINBASEAPI
 BOOL
 WINAPI
 WriteConsoleW(
@@ -2388,6 +3031,7 @@ WriteConsoleW(
        LPVOID           lpReserved
        )
 {
+       DbgPrint("%s unimplemented\n", __FUNCTION__);
 #if 0
   PCSRSS_API_REQUEST Request;
   CSRSS_API_REPLY Reply;
@@ -2440,8 +3084,9 @@ WriteConsoleW(
 
 /*--------------------------------------------------------------
  *     CreateConsoleScreenBuffer
+ *
+ * @implemented
  */
-WINBASEAPI
 HANDLE
 WINAPI
 CreateConsoleScreenBuffer(
@@ -2470,62 +3115,112 @@ CreateConsoleScreenBuffer(
 
 /*--------------------------------------------------------------
  *     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);
 }
 
 
 /*--------------------------------------------------------------
  *     GetConsoleProcessList
+ *
+ * @unimplemented
  */
 DWORD STDCALL
 GetConsoleProcessList(LPDWORD lpdwProcessList,
@@ -2539,6 +3234,8 @@ GetConsoleProcessList(LPDWORD lpdwProcessList,
 
 /*--------------------------------------------------------------
  *     GetConsoleSelectionInfo
+ *
+ * @unimplemented
  */
 BOOL STDCALL
 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
@@ -2551,6 +3248,8 @@ GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
 
 /*--------------------------------------------------------------
  *     AttachConsole
+ *
+ * @unimplemented
  */
 BOOL STDCALL 
 AttachConsole(DWORD dwProcessId)
@@ -2559,4 +3258,49 @@ AttachConsole(DWORD dwProcessId)
    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 */