[KERNEL32], [WIN32CSR] More fixes for console winetest
[reactos.git] / reactos / subsystems / win32 / csrss / win32csr / conio.c
index ff65c58..579e4fe 100644 (file)
@@ -8,9 +8,8 @@
 
 /* INCLUDES ******************************************************************/
 
-#include "w32csr.h"
-
 #define NDEBUG
+#include "w32csr.h"
 #include <debug.h>
 
 /* GLOBALS *******************************************************************/
 #define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
   WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
 
+#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
+  MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1)
+
 #define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
   WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
 
-#define ConsoleAnsiCharToUnicodeChar(Console, sWChar, dChar) \
-  MultiByteToWideChar((Console)->OutputCodePage, 0, (dChar), 1, (sWChar), 1)
+#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \
+  MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
 
 
 /* FUNCTIONS *****************************************************************/
 NTSTATUS FASTCALL
 ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console)
 {
-  PCSRSS_CONSOLE ProcessConsole = ProcessData->Console;
+  PCSRSS_CONSOLE ProcessConsole;
+
+  RtlEnterCriticalSection(&ProcessData->HandleTableLock);
+  ProcessConsole = ProcessData->Console;
 
   if (!ProcessConsole)
     {
       *Console = NULL;
+      RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
       return STATUS_INVALID_HANDLE;
     }
 
-  InterlockedIncrement(&ProcessConsole->Header.ReferenceCount);
-  EnterCriticalSection(&(ProcessConsole->Header.Lock));
+  InterlockedIncrement(&ProcessConsole->ReferenceCount);
+  RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+  EnterCriticalSection(&(ProcessConsole->Lock));
   *Console = ProcessConsole;
 
   return STATUS_SUCCESS;
@@ -66,7 +73,7 @@ ConioConsoleCtrlEventTimeout(DWORD Event, PCSRSS_PROCESS_DATA ProcessData, DWORD
 
       Thread = CreateRemoteThread(ProcessData->Process, NULL, 0,
                                   (LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher,
-                                  (PVOID) Event, 0, NULL);
+                                  UlongToPtr(Event), 0, NULL);
       if (NULL == Thread)
         {
           DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
@@ -110,7 +117,8 @@ CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
   DPRINT("CsrInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY);
 
   Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC;
-  Buffer->Header.ReferenceCount = 0;
+  Buffer->Header.Console = Console;
+  Buffer->Header.HandleCount = 0;
   Buffer->ShowX = 0;
   Buffer->ShowY = 0;
   Buffer->VirtualY = 0;
@@ -119,7 +127,6 @@ CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
     {
       return STATUS_INSUFFICIENT_RESOURCES;
     }
-  InitializeCriticalSection(&Buffer->Header.Lock);
   ConioInitScreenBuffer(Console, Buffer);
   /* initialize buffer to be empty with default attributes */
   for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++)
@@ -130,11 +137,12 @@ CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
   Buffer->CurrentX = 0;
   Buffer->CurrentY = 0;
 
+  InsertHeadList(&Console->BufferList, &Buffer->ListEntry);
   return STATUS_SUCCESS;
 }
 
-static NTSTATUS STDCALL
-CsrInitConsole(PCSRSS_CONSOLE Console)
+static NTSTATUS WINAPI
+CsrInitConsole(PCSRSS_CONSOLE Console, BOOL Visible)
 {
   NTSTATUS Status;
   SECURITY_ATTRIBUTES SecurityAttributes;
@@ -147,13 +155,15 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
   //FIXME
   RtlCreateUnicodeString(&Console->Title, L"Command Prompt");
 
-  Console->Header.ReferenceCount = 0;
+  Console->ReferenceCount = 0;
   Console->WaitingChars = 0;
   Console->WaitingLines = 0;
   Console->EchoCount = 0;
   Console->Header.Type = CONIO_CONSOLE_MAGIC;
+  Console->Header.Console = Console;
   Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
   Console->EarlyReturn = FALSE;
+  InitializeListHead(&Console->BufferList);
   Console->ActiveBuffer = NULL;
   InitializeListHead(&Console->InputEvents);
   Console->CodePage = GetOEMCP();
@@ -170,7 +180,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
       return STATUS_UNSUCCESSFUL;
     }
   Console->PrivateData = NULL;
-  InitializeCriticalSection(&Console->Header.Lock);
+  InitializeCriticalSection(&Console->Lock);
 
   GuiMode = DtbgIsDesktopVisible();
 
@@ -179,13 +189,13 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
   if (NULL == NewBuffer)
     {
       RtlFreeUnicodeString(&Console->Title);
-      DeleteCriticalSection(&Console->Header.Lock);
+      DeleteCriticalSection(&Console->Lock);
       CloseHandle(Console->ActiveEvent);
       return STATUS_INSUFFICIENT_RESOURCES;
     }
   /* init screen buffer with defaults */
   NewBuffer->CursorInfo.bVisible = TRUE;
-  NewBuffer->CursorInfo.dwSize = 5;
+  NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
   /* make console active, and insert into console list */
   Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer;
 
@@ -200,12 +210,12 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
     }
   if (GuiMode)
     {
-      Status = GuiInitConsole(Console);
+      Status = GuiInitConsole(Console, Visible);
       if (! NT_SUCCESS(Status))
         {
           HeapFree(Win32CsrApiHeap,0, NewBuffer);
           RtlFreeUnicodeString(&Console->Title);
-          DeleteCriticalSection(&Console->Header.Lock);
+          DeleteCriticalSection(&Console->Lock);
           CloseHandle(Console->ActiveEvent);
           DPRINT1("GuiInitConsole: failed\n");
           return Status;
@@ -217,16 +227,13 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
     {
       ConioCleanupConsole(Console);
       RtlFreeUnicodeString(&Console->Title);
-      DeleteCriticalSection(&Console->Header.Lock);
+      DeleteCriticalSection(&Console->Lock);
       CloseHandle(Console->ActiveEvent);
       HeapFree(Win32CsrApiHeap, 0, NewBuffer);
       DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
       return Status;
     }
 
-  /* add a reference count because the buffer is tied to the console */
-  InterlockedIncrement(&Console->ActiveBuffer->Header.ReferenceCount);
-
   /* copy buffer contents to screen */
   ConioDrawConsole(Console);
 
@@ -245,26 +252,19 @@ CSR_API(CsrAllocConsole)
     Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
     Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
-    if (ProcessData == NULL)
-    {
-        DPRINT1("No process data\n");
-        return Request->Status = STATUS_INVALID_PARAMETER;
-    }
-
+    RtlEnterCriticalSection(&ProcessData->HandleTableLock);
     if (ProcessData->Console)
     {
         DPRINT1("Process already has a console\n");
-        Request->Status = STATUS_INVALID_PARAMETER;
+        RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
         return STATUS_INVALID_PARAMETER;
     }
 
-    /* Assume success */
-    Request->Status = STATUS_SUCCESS;
-
     /* If we don't need a console, then get out of here */
     if (!Request->Data.AllocConsoleRequest.ConsoleNeeded)
     {
         DPRINT("No console needed\n");
+        RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
         return STATUS_SUCCESS;
     }
 
@@ -278,7 +278,7 @@ CSR_API(CsrAllocConsole)
         if (NULL == Console)
         {
             DPRINT1("Not enough memory for console\n");
-            Request->Status = STATUS_NO_MEMORY;
+            RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
             return STATUS_NO_MEMORY;
         }
         /* initialize list head */
@@ -286,12 +286,13 @@ CSR_API(CsrAllocConsole)
         /* insert process data required for GUI initialization */
         InsertHeadList(&Console->ProcessList, &ProcessData->ProcessEntry);
         /* Initialize the Console */
-        Request->Status = CsrInitConsole(Console);
-        if (!NT_SUCCESS(Request->Status))
+        Status = CsrInitConsole(Console, Request->Data.AllocConsoleRequest.Visible);
+        if (!NT_SUCCESS(Status))
         {
             DPRINT1("Console init failed\n");
             HeapFree(Win32CsrApiHeap, 0, Console);
-            return Request->Status;
+            RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+            return Status;
         }
     }
     else
@@ -307,7 +308,7 @@ CSR_API(CsrAllocConsole)
     Request->Data.AllocConsoleRequest.Console = Console;
 
     /* Add a reference count because the process is tied to the console */
-    Console->Header.ReferenceCount++;
+    _InterlockedIncrement(&Console->ReferenceCount);
 
     if (NewConsole || !ProcessData->bInheritHandles)
     {
@@ -316,20 +317,23 @@ CSR_API(CsrAllocConsole)
                                       &Request->Data.AllocConsoleRequest.InputHandle,
                                       &Console->Header,
                                       GENERIC_READ | GENERIC_WRITE,
-                                      TRUE);
+                                      TRUE,
+                                      FILE_SHARE_READ | FILE_SHARE_WRITE);
         if (! NT_SUCCESS(Status))
         {
             DPRINT1("Failed to insert object\n");
             ConioDeleteConsole((Object_t *) Console);
             ProcessData->Console = 0;
-            return Request->Status = Status;
+            RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+            return Status;
         }
 
         Status = Win32CsrInsertObject(ProcessData,
                                       &Request->Data.AllocConsoleRequest.OutputHandle,
                                       &Console->ActiveBuffer->Header,
                                       GENERIC_READ | GENERIC_WRITE,
-                                      TRUE);
+                                      TRUE,
+                                      FILE_SHARE_READ | FILE_SHARE_WRITE);
         if (!NT_SUCCESS(Status))
         {
             DPRINT1("Failed to insert object\n");
@@ -337,7 +341,8 @@ CSR_API(CsrAllocConsole)
             Win32CsrReleaseObject(ProcessData,
                                   Request->Data.AllocConsoleRequest.InputHandle);
             ProcessData->Console = 0;
-            return Request->Status = Status;
+            RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+            return Status;
         }
     }
 
@@ -360,7 +365,8 @@ CSR_API(CsrAllocConsole)
                                   Request->Data.AllocConsoleRequest.InputHandle);
         }
         ProcessData->Console = 0;
-        return Request->Status = Status;
+        RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+        return Status;
     }
 
     /* Set the Ctrl Dispatcher */
@@ -373,30 +379,16 @@ CSR_API(CsrAllocConsole)
         InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry);
     }
 
+    RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
     return STATUS_SUCCESS;
 }
 
 CSR_API(CsrFreeConsole)
 {
-  PCSRSS_CONSOLE Console;
-
-
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
-  if (ProcessData == NULL || ProcessData->Console == NULL)
-    {
-      return Request->Status = STATUS_INVALID_PARAMETER;
-    }
-
-  Console = ProcessData->Console;
-  ProcessData->Console = NULL;
-  RemoveEntryList(&ProcessData->ProcessEntry);
-  if (0 == InterlockedDecrement(&Console->Header.ReferenceCount))
-    {
-      ConioDeleteConsole((Object_t *) Console);
-    }
-  return STATUS_SUCCESS;
+  return Win32CsrReleaseConsole(ProcessData);
 }
 
 static VOID FASTCALL
@@ -576,7 +568,7 @@ CSR_API(CsrReadConsole)
                                &Console, GENERIC_READ);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
   Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent;
   for (i = 0; i < nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++)
@@ -585,7 +577,6 @@ CSR_API(CsrReadConsole)
       CurrentEntry = RemoveHeadList(&Console->InputEvents);
       if (IsListEmpty(&Console->InputEvents))
       {
-         CHECKPOINT;
          ResetEvent(Console->ActiveEvent);
       }
       Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
@@ -619,7 +610,6 @@ CSR_API(CsrReadConsole)
                   ConioUnlockConsole(Console);
                   HeapFree(Win32CsrApiHeap, 0, Input);
                   Request->Data.ReadConsoleRequest.NrCharactersRead = 0;
-                  Request->Status = STATUS_NOTIFY_CLEANUP;
                   return STATUS_NOTIFY_CLEANUP;
 
                 }
@@ -630,7 +620,7 @@ CSR_API(CsrReadConsole)
           else
             {
               if(Request->Data.ReadConsoleRequest.Unicode)
-                UnicodeBuffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar; /* FIXME */
+                ConsoleInputAnsiCharToUnicodeChar(Console, &UnicodeBuffer[i], &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar);
               else
                 Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar;
             }
@@ -653,27 +643,27 @@ CSR_API(CsrReadConsole)
   Request->Data.ReadConsoleRequest.NrCharactersRead = i;
   if (0 == i)
     {
-      Request->Status = STATUS_PENDING;    /* we didn't read anything */
+      Status = STATUS_PENDING;    /* we didn't read anything */
     }
   else if (0 != (Console->Mode & ENABLE_LINE_INPUT))
     {
       if (0 == Console->WaitingLines ||
           (Request->Data.ReadConsoleRequest.Unicode ? (L'\n' != UnicodeBuffer[i - 1]) : ('\n' != Buffer[i - 1])))
         {
-          Request->Status = STATUS_PENDING; /* line buffered, didn't get a complete line */
+          Status = STATUS_PENDING; /* line buffered, didn't get a complete line */
         }
       else
         {
           Console->WaitingLines--;
-          Request->Status = STATUS_SUCCESS; /* line buffered, did get a complete line */
+          Status = STATUS_SUCCESS; /* line buffered, did get a complete line */
         }
     }
   else
     {
-      Request->Status = STATUS_SUCCESS;  /* not line buffered, did read something */
+      Status = STATUS_SUCCESS;  /* not line buffered, did read something */
     }
 
-  if (Request->Status == STATUS_PENDING)
+  if (Status == STATUS_PENDING)
     {
       Console->EchoCount = nNumberOfCharsToRead - i;
     }
@@ -690,10 +680,10 @@ CSR_API(CsrReadConsole)
       Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
     }
 
-  return Request->Status;
+  return Status;
 }
 
-BOOLEAN __inline ConioGetIntersection(
+__inline BOOLEAN ConioGetIntersection(
   RECT *Intersection,
   RECT *Rect1,
   RECT *Rect2)
@@ -719,7 +709,7 @@ BOOLEAN __inline ConioGetIntersection(
   return TRUE;
 }
 
-BOOLEAN __inline ConioGetUnion(
+__inline BOOLEAN ConioGetUnion(
   RECT *Union,
   RECT *Rect1,
   RECT *Rect2)
@@ -846,17 +836,18 @@ CSR_API(CsrWriteConsole)
       DPRINT1("Invalid request size\n");
       Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
       Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
-      return Request->Status = STATUS_INVALID_PARAMETER;
+      return STATUS_INVALID_PARAMETER;
     }
-  Status = ConioConsoleFromProcessData(ProcessData, &Console);
 
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
+  Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
+  Console = Buff->Header.Console;
 
   if(Request->Data.WriteConsoleRequest.Unicode)
     {
@@ -884,36 +875,46 @@ CSR_API(CsrWriteConsole)
 
   if (Buffer)
     {
-      Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
       if (NT_SUCCESS(Status))
         {
-          Request->Status = ConioWriteConsole(Console, Buff, Buffer,
-                                              Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
+          Status = ConioWriteConsole(Console, Buff, Buffer,
+                                     Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
           if (NT_SUCCESS(Status))
             {
               Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite;
             }
-          ConioUnlockScreenBuffer(Buff);
         }
       if (Request->Data.WriteConsoleRequest.Unicode)
         {
           RtlFreeHeap(GetProcessHeap(), 0, Buffer);
         }
     }
-  ConioUnlockConsole(Console);
+  ConioUnlockScreenBuffer(Buff);
 
   Request->Data.WriteConsoleRequest.NrCharactersWritten = Written;
 
-  return Request->Status = Status;
+  return Status;
 }
 
-VOID STDCALL
-ConioDeleteScreenBuffer(Object_t *Object)
+VOID WINAPI
+ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer)
 {
-  PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object;
-  DeleteCriticalSection(&Buffer->Header.Lock);
-  HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
-  HeapFree(Win32CsrApiHeap, 0, Buffer);
+    PCSRSS_CONSOLE Console = Buffer->Header.Console;
+
+    RemoveEntryList(&Buffer->ListEntry);
+    if (Buffer == Console->ActiveBuffer)
+    {
+        /* Deleted active buffer; switch to most recently created */
+        Console->ActiveBuffer = NULL;
+        if (!IsListEmpty(&Console->BufferList))
+        {
+            Console->ActiveBuffer = CONTAINING_RECORD(Console->BufferList.Flink, CSRSS_SCREEN_BUFFER, ListEntry);
+            ConioDrawConsole(Console);
+        }
+    }
+
+    HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
+    HeapFree(Win32CsrApiHeap, 0, Buffer);
 }
 
 VOID FASTCALL
@@ -927,7 +928,7 @@ ConioDrawConsole(PCSRSS_CONSOLE Console)
 }
 
 
-VOID STDCALL
+VOID WINAPI
 ConioDeleteConsole(Object_t *Object)
 {
   PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object;
@@ -945,21 +946,20 @@ ConioDeleteConsole(Object_t *Object)
     }
 
   ConioCleanupConsole(Console);
-  if (0 == InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
+  ConioDeleteScreenBuffer(Console->ActiveBuffer);
+  if (!IsListEmpty(&Console->BufferList))
     {
-      ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
+      DPRINT1("BUG: screen buffer list not empty\n");
     }
 
-  Console->ActiveBuffer = NULL;
-
   CloseHandle(Console->ActiveEvent);
-  DeleteCriticalSection(&Console->Header.Lock);
+  DeleteCriticalSection(&Console->Lock);
   RtlFreeUnicodeString(&Console->Title);
   IntDeleteAllAliases(Console->Aliases);
   HeapFree(Win32CsrApiHeap, 0, Console);
 }
 
-VOID STDCALL
+VOID WINAPI
 CsrInitConsoleSupport(VOID)
 {
   DPRINT("CSR: CsrInitConsoleSupport()\n");
@@ -972,7 +972,6 @@ ConioProcessChar(PCSRSS_CONSOLE Console,
                  ConsoleInput *KeyEventRecord)
 {
   BOOL updown;
-  BOOL bClientWake = FALSE;
   ConsoleInput *TempInput;
 
   if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)))
@@ -1016,8 +1015,6 @@ ConioProcessChar(PCSRSS_CONSOLE Console,
         {
           Console->WaitingLines++;
         }
-      bClientWake = TRUE;
-      SetEvent(Console->ActiveEvent);
     }
   KeyEventRecord->Echoed = FALSE;
   if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT))
@@ -1049,10 +1046,7 @@ ConioProcessChar(PCSRSS_CONSOLE Console,
           RemoveEntryList(&KeyEventRecord->ListEntry);
           HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
           Console->WaitingChars -= 2;
-        }
-      else
-        {
-          SetEvent(Console->ActiveEvent);
+          return;
         }
     }
   else
@@ -1073,10 +1067,7 @@ ConioProcessChar(PCSRSS_CONSOLE Console,
     }
 
   /* Console->WaitingChars++; */
-  if (bClientWake || 0 == (Console->Mode & ENABLE_LINE_INPUT))
-    {
-      SetEvent(Console->ActiveEvent);
-    }
+  SetEvent(Console->ActiveEvent);
 }
 
 static DWORD FASTCALL
@@ -1109,7 +1100,7 @@ ConioGetShiftState(PBYTE KeyState)
   return ssOut;
 }
 
-VOID STDCALL
+VOID WINAPI
 ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
 {
   static BYTE KeyState[256] = { 0 };
@@ -1301,17 +1292,12 @@ CSR_API(CsrGetScreenBufferInfo)
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
-  Status = ConioConsoleFromProcessData(ProcessData, &Console);
-  if (! NT_SUCCESS(Status))
-    {
-      return Request->Status = Status;
-    }
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ);
   if (! NT_SUCCESS(Status))
     {
-      ConioUnlockConsole(Console);
-      return Request->Status = Status;
+      return Status;
     }
+  Console = Buff->Header.Console;
   pInfo = &Request->Data.ScreenBufferInfoRequest.Info;
   pInfo->dwSize.X = Buff->MaxX;
   pInfo->dwSize.Y = Buff->MaxY;
@@ -1325,11 +1311,8 @@ CSR_API(CsrGetScreenBufferInfo)
   pInfo->dwMaximumWindowSize.X = Buff->MaxX;
   pInfo->dwMaximumWindowSize.Y = Buff->MaxY;
   ConioUnlockScreenBuffer(Buff);
-  ConioUnlockConsole(Console);
 
-  Request->Status = STATUS_SUCCESS;
-
-  return Request->Status;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetCursor)
@@ -1342,21 +1325,15 @@ CSR_API(CsrSetCursor)
 
   DPRINT("CsrSetCursor\n");
 
-  Status = ConioConsoleFromProcessData(ProcessData, &Console);
-  if (! NT_SUCCESS(Status))
-    {
-      return Request->Status = Status;
-    }
-
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
   if (! NT_SUCCESS(Status))
     {
-      ConioUnlockConsole(Console);
-      return Request->Status = Status;
+      return Status;
     }
+  Console = Buff->Header.Console;
 
   NewCursorX = Request->Data.SetCursorRequest.Position.X;
   NewCursorY = Request->Data.SetCursorRequest.Position.Y;
@@ -1364,8 +1341,7 @@ CSR_API(CsrSetCursor)
       NewCursorY < 0 || NewCursorY >= Buff->MaxY)
     {
       ConioUnlockScreenBuffer(Buff);
-      ConioUnlockConsole(Console);
-      return Request->Status = STATUS_INVALID_PARAMETER;
+      return STATUS_INVALID_PARAMETER;
     }
   OldCursorX = Buff->CurrentX;
   OldCursorY = Buff->CurrentY;
@@ -1376,15 +1352,13 @@ CSR_API(CsrSetCursor)
       if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
         {
           ConioUnlockScreenBuffer(Buff);
-          ConioUnlockConsole(Console);
-          return Request->Status = STATUS_UNSUCCESSFUL;
+          return STATUS_UNSUCCESSFUL;
         }
     }
 
   ConioUnlockScreenBuffer(Buff);
-  ConioUnlockConsole(Console);
 
-  return Request->Status = STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 static VOID FASTCALL
@@ -1435,14 +1409,18 @@ CSR_API(CsrWriteConsoleOutputChar)
       DPRINT1("Invalid request size\n");
       Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
       Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
-      return Request->Status = STATUS_INVALID_PARAMETER;
+      return STATUS_INVALID_PARAMETER;
     }
 
-  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  Status = ConioLockScreenBuffer(ProcessData,
+                                 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
+                                 &Buff,
+                                 GENERIC_WRITE);
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   if (NT_SUCCESS(Status))
     {
+      Console = Buff->Header.Console;
       if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
         {
           Length = WideCharToMultiByte(Console->OutputCodePage, 0,
@@ -1469,10 +1447,6 @@ CSR_API(CsrWriteConsoleOutputChar)
 
       if (String)
         {
-          Status = ConioLockScreenBuffer(ProcessData,
-                                         Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
-                                         &Buff,
-                                         GENERIC_WRITE);
           if (NT_SUCCESS(Status))
             {
               X = Request->Data.WriteConsoleOutputCharRequest.Coord.X;
@@ -1504,17 +1478,16 @@ CSR_API(CsrWriteConsoleOutputChar)
                 Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X;
                 Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY;
 
-                ConioUnlockScreenBuffer(Buff);
             }
           if (Request->Data.WriteConsoleRequest.Unicode)
             {
               RtlFreeHeap(GetProcessHeap(), 0, tmpString);
             }
         }
-      ConioUnlockConsole(Console);
+      ConioUnlockScreenBuffer(Buff);
     }
   Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written;
-  return Request->Status = Status;
+  return Status;
 }
 
 CSR_API(CsrFillOutputChar)
@@ -1532,18 +1505,12 @@ CSR_API(CsrFillOutputChar)
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
-  Status = ConioConsoleFromProcessData(ProcessData, &Console);
-  if (! NT_SUCCESS(Status))
-    {
-      return Request->Status = Status;
-    }
-
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
   if (! NT_SUCCESS(Status))
     {
-      ConioUnlockConsole(Console);
-      return Request->Status = Status;
+      return Status;
     }
+  Console = Buff->Header.Console;
 
   X = Request->Data.FillOutputRequest.Position.X;
   Y = (Request->Data.FillOutputRequest.Position.Y + Buff->VirtualY) % Buff->MaxY;
@@ -1577,10 +1544,9 @@ CSR_API(CsrFillOutputChar)
     }
 
   ConioUnlockScreenBuffer(Buff);
-  ConioUnlockConsole(Console);
   Length = Request->Data.FillOutputRequest.Length;
   Request->Data.FillOutputRequest.NrCharactersWritten = Length;
-  return Request->Status;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrReadInputEvent)
@@ -1600,7 +1566,7 @@ CSR_API(CsrReadInputEvent)
   Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console, GENERIC_READ);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   /* only get input if there is any */
@@ -1659,7 +1625,7 @@ CSR_API(CsrReadInputEvent)
 
   ConioUnlockConsole(Console);
 
-  return Request->Status = Status;
+  return Status;
 }
 
 CSR_API(CsrWriteConsoleOutputAttrib)
@@ -1681,16 +1647,11 @@ CSR_API(CsrWriteConsoleOutputAttrib)
       DPRINT1("Invalid request size\n");
       Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
       Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
-      return Request->Status = STATUS_INVALID_PARAMETER;
+      return STATUS_INVALID_PARAMETER;
     }
 
-  Status = ConioConsoleFromProcessData(ProcessData, &Console);
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
-  if (! NT_SUCCESS(Status))
-    {
-      return Request->Status = Status;
-    }
 
   Status = ConioLockScreenBuffer(ProcessData,
                                  Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle,
@@ -1698,9 +1659,9 @@ CSR_API(CsrWriteConsoleOutputAttrib)
                                  GENERIC_WRITE);
   if (! NT_SUCCESS(Status))
     {
-      ConioUnlockConsole(Console);
-      return Request->Status = Status;
+      return Status;
     }
+  Console = Buff->Header.Console;
 
   X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X;
   Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY;
@@ -1729,14 +1690,12 @@ CSR_API(CsrWriteConsoleOutputAttrib)
       ConioDrawRegion(Console, &UpdateRect);
     }
 
-  ConioUnlockConsole(Console);
-
   Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = X;
   Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY;
 
   ConioUnlockScreenBuffer(Buff);
 
-  return Request->Status = STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrFillOutputAttrib)
@@ -1751,20 +1710,14 @@ CSR_API(CsrFillOutputAttrib)
 
   DPRINT("CsrFillOutputAttrib\n");
 
-  Status = ConioConsoleFromProcessData(ProcessData, &Console);
-  if (! NT_SUCCESS(Status))
-    {
-      return Request->Status = Status;
-    }
-
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
   if (! NT_SUCCESS(Status))
     {
-      ConioUnlockConsole(Console);
-      return Request->Status = Status;
+      return Status;
     }
+  Console = Buff->Header.Console;
 
   X = Request->Data.FillOutputAttribRequest.Coord.X;
   Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY;
@@ -1794,9 +1747,8 @@ CSR_API(CsrFillOutputAttrib)
     }
 
   ConioUnlockScreenBuffer(Buff);
-  ConioUnlockConsole(Console);
 
-  return Request->Status = STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 
@@ -1813,13 +1765,13 @@ CSR_API(CsrGetCursorInfo)
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_READ);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
   Request->Data.GetCursorInfoRequest.Info.bVisible = Buff->CursorInfo.bVisible;
   Request->Data.GetCursorInfoRequest.Info.dwSize = Buff->CursorInfo.dwSize;
   ConioUnlockScreenBuffer(Buff);
 
-  return Request->Status = STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetCursorInfo)
@@ -1835,18 +1787,12 @@ CSR_API(CsrSetCursorInfo)
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
-  Status = ConioConsoleFromProcessData(ProcessData, &Console);
-  if (! NT_SUCCESS(Status))
-    {
-      return Request->Status = Status;
-    }
-
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
   if (! NT_SUCCESS(Status))
     {
-      ConioUnlockConsole(Console);
-      return Request->Status = Status;
+      return Status;
     }
+  Console = Buff->Header.Console;
 
   Size = Request->Data.SetCursorInfoRequest.Info.dwSize;
   Visible = Request->Data.SetCursorInfoRequest.Info.bVisible;
@@ -1868,15 +1814,13 @@ CSR_API(CsrSetCursorInfo)
       if (! ConioSetCursorInfo(Console, Buff))
         {
           ConioUnlockScreenBuffer(Buff);
-          ConioUnlockConsole(Console);
-          return Request->Status = STATUS_UNSUCCESSFUL;
+          return STATUS_UNSUCCESSFUL;
         }
     }
 
   ConioUnlockScreenBuffer(Buff);
-  ConioUnlockConsole(Console);
 
-  return Request->Status = STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetTextAttrib)
@@ -1887,18 +1831,12 @@ CSR_API(CsrSetTextAttrib)
 
   DPRINT("CsrSetTextAttrib\n");
 
-  Status = ConioConsoleFromProcessData(ProcessData, &Console);
-  if (! NT_SUCCESS(Status))
-    {
-      return Request->Status = Status;
-    }
-
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
   if (! NT_SUCCESS(Status))
     {
-      ConioUnlockConsole(Console);
-      return Request->Status = Status;
+      return Status;
     }
+  Console = Buff->Header.Console;
 
   Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib;
   if (Buff == Console->ActiveBuffer)
@@ -1906,15 +1844,13 @@ CSR_API(CsrSetTextAttrib)
       if (! ConioUpdateScreenInfo(Console, Buff))
         {
           ConioUnlockScreenBuffer(Buff);
-          ConioUnlockConsole(Console);
-          return Request->Status = STATUS_UNSUCCESSFUL;
+          return STATUS_UNSUCCESSFUL;
         }
     }
 
   ConioUnlockScreenBuffer(Buff);
-  ConioUnlockConsole(Console);
 
-  return Request->Status = STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetConsoleMode)
@@ -1927,12 +1863,12 @@ CSR_API(CsrSetConsoleMode)
 
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
-  Status = Win32CsrGetObject(ProcessData,
-                             Request->Data.SetConsoleModeRequest.ConsoleHandle,
-                             (Object_t **) &Console, GENERIC_WRITE);
+  Status = Win32CsrLockObject(ProcessData,
+                              Request->Data.SetConsoleModeRequest.ConsoleHandle,
+                              (Object_t **) &Console, GENERIC_WRITE, 0);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   Buff = (PCSRSS_SCREEN_BUFFER)Console;
@@ -1949,9 +1885,9 @@ CSR_API(CsrSetConsoleMode)
       Status = STATUS_INVALID_HANDLE;
     }
 
-  Win32CsrReleaseObjectByPointer((Object_t *)Console);
+  Win32CsrUnlockObject((Object_t *)Console);
 
-  return Request->Status = Status;
+  return Status;
 }
 
 CSR_API(CsrGetConsoleMode)
@@ -1964,13 +1900,13 @@ CSR_API(CsrGetConsoleMode)
 
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
-  Status = Win32CsrGetObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
-                             (Object_t **) &Console, GENERIC_READ);
+  Status = Win32CsrLockObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
+                              (Object_t **) &Console, GENERIC_READ, 0);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
-  Request->Status = STATUS_SUCCESS;
+  Status = STATUS_SUCCESS;
   Buff = (PCSRSS_SCREEN_BUFFER) Console;
   if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
     {
@@ -1982,11 +1918,11 @@ CSR_API(CsrGetConsoleMode)
     }
   else
     {
-      Request->Status = STATUS_INVALID_HANDLE;
+      Status = STATUS_INVALID_HANDLE;
     }
 
-  Win32CsrReleaseObjectByPointer((Object_t *)Console);
-  return Request->Status;
+  Win32CsrUnlockObject((Object_t *)Console);
+  return Status;
 }
 
 CSR_API(CsrCreateScreenBuffer)
@@ -1997,15 +1933,11 @@ CSR_API(CsrCreateScreenBuffer)
 
   DPRINT("CsrCreateScreenBuffer\n");
 
-  if (ProcessData == NULL)
-    {
-      return Request->Status = STATUS_INVALID_PARAMETER;
-    }
-
+  RtlEnterCriticalSection(&ProcessData->HandleTableLock);
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
@@ -2025,7 +1957,7 @@ CSR_API(CsrCreateScreenBuffer)
       else
         {
           Buff->CursorInfo.bVisible = TRUE;
-          Buff->CursorInfo.dwSize = 5;
+          Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
         }
 
       if (Buff->MaxX == 0)
@@ -2039,26 +1971,24 @@ CSR_API(CsrCreateScreenBuffer)
         }
 
       Status = CsrInitConsoleScreenBuffer(Console, Buff);
-      if(! NT_SUCCESS(Status))
-        {
-          Request->Status = Status;
-        }
-      else
+      if(NT_SUCCESS(Status))
         {
-          Request->Status = Win32CsrInsertObject(ProcessData,
+          Status = Win32CsrInsertObject(ProcessData,
             &Request->Data.CreateScreenBufferRequest.OutputHandle,
             &Buff->Header,
             Request->Data.CreateScreenBufferRequest.Access,
-            Request->Data.CreateScreenBufferRequest.Inheritable);
+            Request->Data.CreateScreenBufferRequest.Inheritable,
+            Request->Data.CreateScreenBufferRequest.ShareMode);
         }
     }
   else
     {
-      Request->Status = STATUS_INSUFFICIENT_RESOURCES;
+      Status = STATUS_INSUFFICIENT_RESOURCES;
     }
 
   ConioUnlockConsole(Console);
-  return Request->Status;
+  RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+  return Status;
 }
 
 CSR_API(CsrSetScreenBuffer)
@@ -2069,45 +1999,35 @@ CSR_API(CsrSetScreenBuffer)
 
   DPRINT("CsrSetScreenBuffer\n");
 
-  Status = ConioConsoleFromProcessData(ProcessData, &Console);
-  if (! NT_SUCCESS(Status))
-    {
-      return Request->Status = Status;
-    }
-
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE);
   if (! NT_SUCCESS(Status))
     {
-      ConioUnlockConsole(Console);
-      return Request->Status = Status;
+      return Status;
     }
+  Console = Buff->Header.Console;
 
   if (Buff == Console->ActiveBuffer)
     {
       ConioUnlockScreenBuffer(Buff);
-      ConioUnlockConsole(Console);
-      return Request->Status = STATUS_SUCCESS;
+      return STATUS_SUCCESS;
     }
 
-  /* drop reference to old buffer, maybe delete */
-  if (! InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
+  /* If old buffer has no handles, it's now unreferenced */
+  if (Console->ActiveBuffer->Header.HandleCount == 0)
     {
-      ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
+      ConioDeleteScreenBuffer(Console->ActiveBuffer);
     }
   /* tie console to new buffer */
   Console->ActiveBuffer = Buff;
-  /* inc ref count on new buffer */
-  InterlockedIncrement(&Buff->Header.ReferenceCount);
   /* Redraw the console */
   ConioDrawConsole(Console);
 
   ConioUnlockScreenBuffer(Buff);
-  ConioUnlockConsole(Console);
 
-  return Request->Status = STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetTitle)
@@ -2125,17 +2045,13 @@ CSR_API(CsrSetTitle)
       DPRINT1("Invalid request size\n");
       Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
       Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
-      return Request->Status = STATUS_INVALID_PARAMETER;
+      return STATUS_INVALID_PARAMETER;
     }
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
-  if(! NT_SUCCESS(Status))
-    {
-      Request->Status = Status;
-    }
-  else
+  if(NT_SUCCESS(Status))
     {
       Buffer =  RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length);
       if (Buffer)
@@ -2147,21 +2063,21 @@ CSR_API(CsrSetTitle)
           memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length);
           if (! ConioChangeTitle(Console))
             {
-              Request->Status = STATUS_UNSUCCESSFUL;
+              Status = STATUS_UNSUCCESSFUL;
             }
           else
             {
-              Request->Status = STATUS_SUCCESS;
+              Status = STATUS_SUCCESS;
             }
         }
       else
         {
-          Request->Status = STATUS_NO_MEMORY;
+          Status = STATUS_NO_MEMORY;
         }
       ConioUnlockConsole(Console);
     }
 
-  return Request->Status;
+  return Status;
 }
 
 CSR_API(CsrGetTitle)
@@ -2178,7 +2094,7 @@ CSR_API(CsrGetTitle)
   if (! NT_SUCCESS(Status))
     {
       DPRINT1("Can't get console\n");
-      return Request->Status = Status;
+      return Status;
     }
 
   /* Copy title of the console to the user title buffer */
@@ -2195,9 +2111,7 @@ CSR_API(CsrGetTitle)
       Request->Header.u1.s1.TotalLength = Length;
       Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE);
     }
-  Request->Status = STATUS_SUCCESS;
-
-  return Request->Status;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrWriteConsoleOutput)
@@ -2217,12 +2131,6 @@ CSR_API(CsrWriteConsoleOutput)
 
   DPRINT("CsrWriteConsoleOutput\n");
 
-  Status = ConioConsoleFromProcessData(ProcessData, &Console);
-  if (! NT_SUCCESS(Status))
-    {
-      return Request->Status = Status;
-    }
-
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = ConioLockScreenBuffer(ProcessData,
@@ -2231,9 +2139,9 @@ CSR_API(CsrWriteConsoleOutput)
                                  GENERIC_WRITE);
   if (! NT_SUCCESS(Status))
     {
-      ConioUnlockConsole(Console);
-      return Request->Status = Status;
+      return Status;
     }
+  Console = Buff->Header.Console;
 
   BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize;
   PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO);
@@ -2244,8 +2152,7 @@ CSR_API(CsrWriteConsoleOutput)
        ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
     {
       ConioUnlockScreenBuffer(Buff);
-      ConioUnlockConsole(Console);
-      return Request->Status = STATUS_ACCESS_VIOLATION;
+      return STATUS_ACCESS_VIOLATION;
     }
   WriteRegion.left = Request->Data.WriteConsoleOutputRequest.WriteRegion.Left;
   WriteRegion.top = Request->Data.WriteConsoleOutputRequest.WriteRegion.Top;
@@ -2262,11 +2169,10 @@ CSR_API(CsrWriteConsoleOutput)
   if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion))
     {
       ConioUnlockScreenBuffer(Buff);
-      ConioUnlockConsole(Console);
 
       /* It is okay to have a WriteRegion completely outside the screen buffer.
          No data is written then. */
-      return Request->Status = STATUS_SUCCESS;
+      return STATUS_SUCCESS;
     }
 
   for (i = 0, Y = WriteRegion.top; Y <= WriteRegion.bottom; i++, Y++)
@@ -2293,14 +2199,13 @@ CSR_API(CsrWriteConsoleOutput)
   ConioDrawRegion(Console, &WriteRegion);
 
   ConioUnlockScreenBuffer(Buff);
-  ConioUnlockConsole(Console);
 
   Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.left + SizeX - 1;
   Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.top + SizeY - 1;
   Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.left;
   Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.top;
 
-  return Request->Status = STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrFlushInputBuffer)
@@ -2320,7 +2225,7 @@ CSR_API(CsrFlushInputBuffer)
                             GENERIC_WRITE);
   if(! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   /* Discard all entries in the input event queue */
@@ -2336,7 +2241,7 @@ CSR_API(CsrFlushInputBuffer)
 
   ConioUnlockConsole(Console);
 
-  return Request->Status = STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrScrollConsoleScreenBuffer)
@@ -2363,20 +2268,14 @@ CSR_API(CsrScrollConsoleScreenBuffer)
   DestinationOrigin = Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin;
   Fill = Request->Data.ScrollConsoleScreenBufferRequest.Fill;
 
-  Status = ConioConsoleFromProcessData(ProcessData, &Console);
-  if (! NT_SUCCESS(Status))
-    {
-      return Request->Status = Status;
-    }
-
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE);
   if (! NT_SUCCESS(Status))
     {
-      ConioUnlockConsole(Console);
-      return Request->Status = Status;
+      return Status;
     }
+  Console = Buff->Header.Console;
 
   ScrollRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Left;
   ScrollRectangle.top = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Top;
@@ -2388,8 +2287,7 @@ CSR_API(CsrScrollConsoleScreenBuffer)
   if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle))
     {
       ConioUnlockScreenBuffer(Buff);
-      ConioUnlockConsole(Console);
-      return Request->Status = STATUS_SUCCESS;
+      return STATUS_SUCCESS;
     }
 
   /* If the source was clipped on the left or top, adjust the destination accordingly */
@@ -2410,9 +2308,8 @@ CSR_API(CsrScrollConsoleScreenBuffer)
       ClipRectangle.bottom = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Bottom;
       if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer))
         {
-          ConioUnlockConsole(Console);
           ConioUnlockScreenBuffer(Buff);
-          return Request->Status = STATUS_SUCCESS;
+          return STATUS_SUCCESS;
       }
     }
   else
@@ -2444,9 +2341,8 @@ CSR_API(CsrScrollConsoleScreenBuffer)
     }
 
   ConioUnlockScreenBuffer(Buff);
-  ConioUnlockConsole(Console);
 
-  return Request->Status = STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrReadConsoleOutputChar)
@@ -2468,18 +2364,12 @@ CSR_API(CsrReadConsoleOutputChar)
 
   CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
 
-  Status = ConioConsoleFromProcessData(ProcessData, &Console);
-  if (! NT_SUCCESS(Status))
-    {
-      return Request->Status = Status;
-    }
-
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ);
   if (! NT_SUCCESS(Status))
     {
-      ConioUnlockConsole(Console);
-      return Request->Status = Status;
+      return Status;
     }
+  Console = Buff->Header.Console;
 
   Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X;
   Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY;
@@ -2511,12 +2401,10 @@ CSR_API(CsrReadConsoleOutputChar)
     }
 
   *ReadBuffer = 0;
-  Request->Status = STATUS_SUCCESS;
   Request->Data.ReadConsoleOutputCharRequest.EndCoord.X = Xpos;
   Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY;
 
   ConioUnlockScreenBuffer(Buff);
-  ConioUnlockConsole(Console);
 
   Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize;
   if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE))
@@ -2525,7 +2413,7 @@ CSR_API(CsrReadConsoleOutputChar)
       Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
     }
 
-  return Request->Status;
+  return STATUS_SUCCESS;
 }
 
 
@@ -2547,7 +2435,7 @@ CSR_API(CsrReadConsoleOutputAttrib)
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_READ);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X;
@@ -2574,7 +2462,6 @@ CSR_API(CsrReadConsoleOutputAttrib)
 
   *ReadBuffer = 0;
 
-  Request->Status = STATUS_SUCCESS;
   Request->Data.ReadConsoleOutputAttribRequest.EndCoord.X = Xpos;
   Request->Data.ReadConsoleOutputAttribRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY;
 
@@ -2588,7 +2475,7 @@ CSR_API(CsrReadConsoleOutputAttrib)
       Request->Header.u1.s1.DataLength = CurrentLength - sizeof(PORT_MESSAGE);
     }
 
-  return Request->Status;
+  return STATUS_SUCCESS;
 }
 
 
@@ -2608,7 +2495,7 @@ CSR_API(CsrGetNumberOfConsoleInputEvents)
   Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   CurrentItem = Console->InputEvents.Flink;
@@ -2627,10 +2514,9 @@ CSR_API(CsrGetNumberOfConsoleInputEvents)
 
   ConioUnlockConsole(Console);
 
-  Request->Status = STATUS_SUCCESS;
   Request->Data.GetNumInputEventsRequest.NumInputEvents = NumEvents;
 
-  return Request->Status;
+  return STATUS_SUCCESS;
 }
 
 
@@ -2653,7 +2539,7 @@ CSR_API(CsrPeekConsoleInput)
   Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
   if(! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord;
@@ -2664,8 +2550,7 @@ CSR_API(CsrPeekConsoleInput)
       || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
     {
       ConioUnlockConsole(Console);
-      Request->Status = STATUS_ACCESS_VIOLATION;
-      return Request->Status ;
+      return STATUS_ACCESS_VIOLATION;
     }
 
   NumItems = 0;
@@ -2699,10 +2584,9 @@ CSR_API(CsrPeekConsoleInput)
 
   ConioUnlockConsole(Console);
 
-  Request->Status = STATUS_SUCCESS;
   Request->Data.PeekConsoleInputRequest.Length = NumItems;
 
-  return Request->Status;
+  return STATUS_SUCCESS;
 }
 
 
@@ -2732,7 +2616,7 @@ CSR_API(CsrReadConsoleOutput)
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff, GENERIC_READ);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo;
@@ -2752,8 +2636,7 @@ CSR_API(CsrReadConsoleOutput)
       || (((ULONG_PTR)CharInfo + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
     {
       ConioUnlockScreenBuffer(Buff);
-      Request->Status = STATUS_ACCESS_VIOLATION;
-      return Request->Status ;
+      return STATUS_ACCESS_VIOLATION;
     }
 
   SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion));
@@ -2765,8 +2648,7 @@ CSR_API(CsrReadConsoleOutput)
   if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion))
     {
       ConioUnlockScreenBuffer(Buff);
-      Request->Status = STATUS_SUCCESS;
-      return Request->Status;
+      return STATUS_SUCCESS;
     }
 
   for (i = 0, Y = ReadRegion.top; Y < ReadRegion.bottom; ++i, ++Y)
@@ -2793,13 +2675,12 @@ CSR_API(CsrReadConsoleOutput)
 
   ConioUnlockScreenBuffer(Buff);
 
-  Request->Status = STATUS_SUCCESS;
   Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.left + SizeX - 1;
   Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.top + SizeY - 1;
   Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.left;
   Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.top;
 
-  return Request->Status;
+  return STATUS_SUCCESS;
 }
 
 
@@ -2821,7 +2702,7 @@ CSR_API(CsrWriteConsoleInput)
   Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console, GENERIC_WRITE);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord;
@@ -2832,8 +2713,7 @@ CSR_API(CsrWriteConsoleInput)
       || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
     {
       ConioUnlockConsole(Console);
-      Request->Status = STATUS_ACCESS_VIOLATION;
-      return Request->Status ;
+      return STATUS_ACCESS_VIOLATION;
     }
 
   for (i = 0; i < Length; i++)
@@ -2842,8 +2722,7 @@ CSR_API(CsrWriteConsoleInput)
       if (NULL == Record)
         {
           ConioUnlockConsole(Console);
-          Request->Status = STATUS_INSUFFICIENT_RESOURCES;
-          return Request->Status;
+          return STATUS_INSUFFICIENT_RESOURCES;
         }
 
       Record->Echoed = FALSE;
@@ -2859,10 +2738,9 @@ CSR_API(CsrWriteConsoleInput)
 
   ConioUnlockConsole(Console);
 
-  Request->Status = STATUS_SUCCESS;
   Request->Data.WriteConsoleInputRequest.Length = i;
 
-  return Request->Status;
+  return STATUS_SUCCESS;
 }
 
 /**********************************************************************
@@ -2917,7 +2795,7 @@ CSR_API(CsrHardwareStateProperty)
   if (! NT_SUCCESS(Status))
     {
       DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
-      return Request->Status = Status;
+      return Status;
     }
 
   switch (Request->Data.ConsoleHardwareStateRequest.SetGet)
@@ -2928,17 +2806,17 @@ CSR_API(CsrHardwareStateProperty)
 
       case CONSOLE_HARDWARE_STATE_SET:
         DPRINT("Setting console hardware state.\n");
-        Request->Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State);
+        Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State);
         break;
 
       default:
-        Request->Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */
+        Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */
         break;
     }
 
   ConioUnlockConsole(Console);
 
-  return Request->Status;
+  return Status;
 }
 
 CSR_API(CsrGetConsoleWindow)
@@ -2954,13 +2832,13 @@ CSR_API(CsrGetConsoleWindow)
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow;
   ConioUnlockConsole(Console);
 
-  return Request->Status = STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetConsoleIcon)
@@ -2976,14 +2854,14 @@ CSR_API(CsrSetConsoleIcon)
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
-  Request->Status = (ConioChangeIcon(Console, Request->Data.SetConsoleIconRequest.WindowIcon)
-                     ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
+  Status = (ConioChangeIcon(Console, Request->Data.SetConsoleIconRequest.WindowIcon)
+            ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
   ConioUnlockConsole(Console);
 
-  return Request->Status;
+  return Status;
 }
 
 CSR_API(CsrGetConsoleCodePage)
@@ -2996,14 +2874,14 @@ CSR_API(CsrGetConsoleCodePage)
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Request->Data.GetConsoleCodePage.CodePage = Console->CodePage;
   ConioUnlockConsole(Console);
-  return Request->Status = STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetConsoleCodePage)
@@ -3016,19 +2894,21 @@ CSR_API(CsrSetConsoleCodePage)
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
   if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage))
     {
       Console->CodePage = Request->Data.SetConsoleCodePage.CodePage;
       ConioUnlockConsole(Console);
-      return Request->Status = STATUS_SUCCESS;
+      return STATUS_SUCCESS;
     }
+
   ConioUnlockConsole(Console);
-  return Request->Status = STATUS_UNSUCCESSFUL;
+  return STATUS_INVALID_PARAMETER;
 }
 
 CSR_API(CsrGetConsoleOutputCodePage)
@@ -3041,14 +2921,14 @@ CSR_API(CsrGetConsoleOutputCodePage)
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage;
   ConioUnlockConsole(Console);
-  return Request->Status = STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 CSR_API(CsrSetConsoleOutputCodePage)
@@ -3061,72 +2941,126 @@ CSR_API(CsrSetConsoleOutputCodePage)
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
+      return Status;
     }
 
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
   if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage))
     {
       Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage;
       ConioUnlockConsole(Console);
-      return Request->Status = STATUS_SUCCESS;
+      return STATUS_SUCCESS;
     }
+
   ConioUnlockConsole(Console);
-  return Request->Status = STATUS_UNSUCCESSFUL;
+  return STATUS_INVALID_PARAMETER;
 }
 
 CSR_API(CsrGetProcessList)
 {
-  PHANDLE Buffer;
+  PDWORD Buffer;
   PCSRSS_CONSOLE Console;
   PCSRSS_PROCESS_DATA current;
   PLIST_ENTRY current_entry;
-  ULONG nItems, nCopied, Length;
+  ULONG nItems = 0;
   NTSTATUS Status;
+  ULONG_PTR Offset;
 
   DPRINT("CsrGetProcessList\n");
 
-  Buffer = Request->Data.GetProcessListRequest.ProcessId;
   Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
   Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
-  nItems = nCopied = 0;
-  Request->Data.GetProcessListRequest.nProcessIdsCopied = 0;
-  Request->Data.GetProcessListRequest.nProcessIdsTotal = 0;
+  Buffer = Request->Data.GetProcessListRequest.ProcessId;
+  Offset = (PBYTE)Buffer - (PBYTE)ProcessData->CsrSectionViewBase;
+  if (Offset >= ProcessData->CsrSectionViewSize
+      || (Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)) > (ProcessData->CsrSectionViewSize - Offset)
+      || Offset & (sizeof(DWORD) - 1))
+  {
+    return STATUS_ACCESS_VIOLATION;
+  }
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
   {
-    return Request->Status = Status;
+    return Status;
   }
 
-  DPRINT1("Console_Api Ctrl-C\n");
-
   for(current_entry = Console->ProcessList.Flink;
       current_entry != &Console->ProcessList;
       current_entry = current_entry->Flink)
   {
     current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
-    if(++nItems < Request->Data.GetProcessListRequest.nMaxIds)
+    if(++nItems <= Request->Data.GetProcessListRequest.nMaxIds)
     {
-      *(Buffer++) = current->ProcessId;
-      nCopied++;
+      *Buffer++ = (DWORD)current->ProcessId;
     }
   }
 
   ConioUnlockConsole(Console);
 
-  Request->Data.GetProcessListRequest.nProcessIdsCopied = nCopied;
   Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems;
+  return STATUS_SUCCESS;
+}
 
-  Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST) + nCopied * sizeof(HANDLE);
-  if (Length > sizeof(CSR_API_MESSAGE))
+CSR_API(CsrGenerateCtrlEvent)
+{
+  PCSRSS_CONSOLE Console;
+  PCSRSS_PROCESS_DATA current;
+  PLIST_ENTRY current_entry;
+  DWORD Group;
+  NTSTATUS Status;
+
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
+  Status = ConioConsoleFromProcessData(ProcessData, &Console);
+  if (! NT_SUCCESS(Status))
+  {
+    return Status;
+  }
+
+  Group = Request->Data.GenerateCtrlEvent.ProcessGroup;
+  Status = STATUS_INVALID_PARAMETER;
+  for (current_entry = Console->ProcessList.Flink;
+       current_entry != &Console->ProcessList;
+       current_entry = current_entry->Flink)
   {
-     Request->Header.u1.s1.TotalLength = Length;
-     Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE);
+    current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
+    if (Group == 0 || current->ProcessGroup == Group)
+    {
+      ConioConsoleCtrlEvent(Request->Data.GenerateCtrlEvent.Event, current);
+      Status = STATUS_SUCCESS;
+    }
   }
-  return Request->Status = STATUS_SUCCESS;
+
+  ConioUnlockConsole(Console);
+
+  return Status;
+}
+
+CSR_API(CsrSetScreenBufferSize)
+{
+    NTSTATUS Status;
+    PCSRSS_CONSOLE Console;
+    PCSRSS_SCREEN_BUFFER Buff;
+
+    Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+    Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
+    Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferSize.OutputHandle, &Buff, GENERIC_WRITE);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+    Console = Buff->Header.Console;
+
+    Status = ConioResizeBuffer(Console, Buff, Request->Data.SetScreenBufferSize.Size);
+    ConioUnlockScreenBuffer(Buff);
+
+    return Status;
 }
 
 /* EOF */