[CONSRV]
[reactos.git] / win32ss / user / consrv / console.c
index ee0fe44..4eabc9d 100644 (file)
@@ -12,7 +12,7 @@
 #include "guiconsole.h"
 #include "tuiconsole.h"
 
-#define NDEBUG
+//#define NDEBUG
 #include <debug.h>
 
 /* FUNCTIONS *****************************************************************/
@@ -33,9 +33,9 @@ DtbgIsDesktopVisible(VOID)
 
 NTSTATUS FASTCALL
 ConioConsoleFromProcessData(PCONSOLE_PROCESS_DATA ProcessData,
-                            PCSRSS_CONSOLE *Console)
+                            PCONSOLE *Console)
 {
-    PCSRSS_CONSOLE ProcessConsole;
+    PCONSOLE ProcessConsole;
 
     RtlEnterCriticalSection(&ProcessData->HandleTableLock);
     ProcessConsole = ProcessData->Console;
@@ -75,6 +75,7 @@ ConioConsoleCtrlEventTimeout(DWORD Event,
             return;
         }
 
+        DPRINT1("We succeeded at creating ProcessData->CtrlDispatcher remote thread, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
         WaitForSingleObject(Thread, Timeout);
         CloseHandle(Thread);
     }
@@ -86,15 +87,29 @@ ConioConsoleCtrlEvent(DWORD Event, PCONSOLE_PROCESS_DATA ProcessData)
     ConioConsoleCtrlEventTimeout(Event, ProcessData, 0);
 }
 
-static NTSTATUS WINAPI
-CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
+NTSTATUS WINAPI
+CsrInitConsole(PCONSOLE* NewConsole, int ShowCmd, PCSR_PROCESS ConsoleLeaderProcess)
 {
     NTSTATUS Status;
     SECURITY_ATTRIBUTES SecurityAttributes;
-    PCSRSS_SCREEN_BUFFER NewBuffer;
+    PCONSOLE Console;
+    PCONSOLE_SCREEN_BUFFER NewBuffer;
     BOOL GuiMode;
     WCHAR Title[255];
 
+    if (NewConsole == NULL) return STATUS_INVALID_PARAMETER;
+
+    *NewConsole = NULL;
+
+    /* Allocate a console structure */
+    Console = HeapAlloc(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CONSOLE));
+    if (NULL == Console)
+    {
+        DPRINT1("Not enough memory for console creation.\n");
+        return STATUS_NO_MEMORY;
+    }
+
+    /* Initialize the console */
     Console->Title.MaximumLength = Console->Title.Length = 0;
     Console->Title.Buffer = NULL;
 
@@ -112,8 +127,12 @@ CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
     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->ConsoleLeaderCID = ConsoleLeaderProcess->ClientId;
+    InitializeListHead(&Console->ProcessList);
     InitializeListHead(&Console->BufferList);
     Console->ActiveBuffer = NULL;
+    InitializeListHead(&Console->ReadWaitQueue);
+    InitializeListHead(&Console->WriteWaitQueue);
     InitializeListHead(&Console->InputEvents);
     InitializeListHead(&Console->HistoryBuffers);
     Console->CodePage = GetOEMCP();
@@ -127,6 +146,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
     if (NULL == Console->ActiveEvent)
     {
         RtlFreeUnicodeString(&Console->Title);
+        HeapFree(ConSrvHeap, 0, Console);
         return STATUS_UNSUCCESSFUL;
     }
     Console->PrivateData = NULL;
@@ -135,31 +155,48 @@ CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
     GuiMode = DtbgIsDesktopVisible();
 
     /* allocate console screen buffer */
-    NewBuffer = HeapAlloc(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER));
+    NewBuffer = HeapAlloc(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CONSOLE_SCREEN_BUFFER));
     if (NULL == NewBuffer)
     {
         RtlFreeUnicodeString(&Console->Title);
         DeleteCriticalSection(&Console->Lock);
         CloseHandle(Console->ActiveEvent);
+        HeapFree(ConSrvHeap, 0, Console);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
     /* init screen buffer with defaults */
     NewBuffer->CursorInfo.bVisible = TRUE;
     NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
     /* make console active, and insert into console list */
-    Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer;
+    Console->ActiveBuffer = (PCONSOLE_SCREEN_BUFFER) NewBuffer;
 
+    /*
+     * If we are not in GUI-mode, start the text-mode console. If we fail,
+     * try to start the GUI-mode console (win32k will automatically switch
+     * to graphical mode, therefore no additional code is needed).
+     */
     if (!GuiMode)
     {
+        DPRINT1("CONSRV: Opening text-mode console\n");
         Status = TuiInitConsole(Console);
         if (!NT_SUCCESS(Status))
         {
-            DPRINT1("Failed to open text-mode console, switching to gui-mode\n");
+            DPRINT1("Failed to open text-mode console, switching to gui-mode, Status = 0x%08lx\n", Status);
             GuiMode = TRUE;
         }
     }
-    else /* GuiMode */
+
+    /*
+     * Try to open the GUI-mode console. Two cases are possible:
+     * - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case
+     *   failed and we start GUI-mode console.
+     * - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
+     *   succeeded BUT we failed at starting text-mode console. Then GuiMode
+     *   was switched to TRUE in order to try to open the console in GUI-mode.
+     */
+    if (GuiMode)
     {
+        DPRINT1("CONSRV: Opening GUI-mode console\n");
         Status = GuiInitConsole(Console, ShowCmd);
         if (!NT_SUCCESS(Status))
         {
@@ -167,13 +204,14 @@ CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
             RtlFreeUnicodeString(&Console->Title);
             DeleteCriticalSection(&Console->Lock);
             CloseHandle(Console->ActiveEvent);
-            DPRINT1("GuiInitConsole: failed\n");
+            DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status);
+            HeapFree(ConSrvHeap, 0, Console);
             return Status;
         }
     }
 
     Status = CsrInitConsoleScreenBuffer(Console, NewBuffer);
-    if (! NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
         ConioCleanupConsole(Console);
         RtlFreeUnicodeString(&Console->Title);
@@ -181,24 +219,27 @@ CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
         CloseHandle(Console->ActiveEvent);
         HeapFree(ConSrvHeap, 0, NewBuffer);
         DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
+        HeapFree(ConSrvHeap, 0, Console);
         return Status;
     }
 
-    /* copy buffer contents to screen */
+    /* Copy buffer contents to screen */
     ConioDrawConsole(Console);
 
+    *NewConsole = Console;
+
     return STATUS_SUCCESS;
 }
 
 CSR_API(SrvOpenConsole)
 {
     NTSTATUS Status = STATUS_SUCCESS;
-    PCSRSS_OPEN_CONSOLE OpenConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.OpenConsoleRequest;
+    PCONSOLE_OPENCONSOLE OpenConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.OpenConsoleRequest;
     PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
 
     DPRINT("SrvOpenConsole\n");
 
-    OpenConsoleRequest->Handle = INVALID_HANDLE_VALUE;
+    OpenConsoleRequest->ConsoleHandle = INVALID_HANDLE_VALUE;
 
     RtlEnterCriticalSection(&ProcessData->HandleTableLock);
 
@@ -210,7 +251,7 @@ CSR_API(SrvOpenConsole)
         DWORD DesiredAccess = OpenConsoleRequest->Access;
         DWORD ShareMode = OpenConsoleRequest->ShareMode;
 
-        PCSRSS_CONSOLE Console = ProcessData->Console;
+        PCONSOLE Console = ProcessData->Console;
         Object_t *Object;
 
         DPRINT1("SrvOpenConsole - Checkpoint 2\n");
@@ -233,7 +274,7 @@ CSR_API(SrvOpenConsole)
         else
         {
             Status = Win32CsrInsertObject(ProcessData,
-                                          &OpenConsoleRequest->Handle,
+                                          &OpenConsoleRequest->ConsoleHandle,
                                           Object,
                                           DesiredAccess,
                                           OpenConsoleRequest->Inheritable,
@@ -250,140 +291,151 @@ CSR_API(SrvOpenConsole)
 
 CSR_API(SrvAllocConsole)
 {
-    PCSRSS_ALLOC_CONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest;
-    PCSR_PROCESS ProcessData = CsrGetClientThread()->Process;
-    PCSRSS_CONSOLE Console;
     NTSTATUS Status = STATUS_SUCCESS;
-    BOOLEAN NewConsole = FALSE;
+    PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest;
+    PCSR_PROCESS ConsoleLeader = CsrGetClientThread()->Process;
+    PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(ConsoleLeader);
 
     DPRINT("SrvAllocConsole\n");
 
-    RtlEnterCriticalSection(&ProcessData->HandleTableLock);
-    if (ProcessData->Console)
+    if (ProcessData->Console != NULL)
     {
         DPRINT1("Process already has a console\n");
-        RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
         return STATUS_INVALID_PARAMETER;
     }
 
-    /* If we don't need a console, then get out of here */
-    if (!AllocConsoleRequest->ConsoleNeeded)
-    {
-        DPRINT("No console needed\n");
-        RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-        return STATUS_SUCCESS;
-    }
+    RtlEnterCriticalSection(&ProcessData->HandleTableLock);
 
-    /* If we already have one, then don't create a new one... */
-    if (!AllocConsoleRequest->Console ||
-            AllocConsoleRequest->Console != ProcessData->ParentConsole)
-    {
-        /* Allocate a console structure */
-        NewConsole = TRUE;
-        Console = HeapAlloc(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_CONSOLE));
-        if (NULL == Console)
-        {
-            DPRINT1("Not enough memory for console\n");
-            RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-            return STATUS_NO_MEMORY;
-        }
-        /* initialize list head */
-        InitializeListHead(&Console->ProcessList);
-        /* insert process data required for GUI initialization */
-        InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink);
-        /* Initialize the Console */
-        Status = CsrInitConsole(Console, AllocConsoleRequest->ShowCmd);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("Console init failed\n");
-            HeapFree(ConSrvHeap, 0, Console);
-            RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-            return Status;
-        }
-    }
-    else
+    DPRINT1("SrvAllocConsole - Checkpoint 1\n");
+
+    /* Initialize a new Console owned by the Console Leader Process */
+    Status = CsrInitConsole(&ProcessData->Console, AllocConsoleRequest->ShowCmd, ConsoleLeader);
+    if (!NT_SUCCESS(Status))
     {
-        /* Reuse our current console */
-        Console = AllocConsoleRequest->Console;
+        DPRINT1("Console initialization failed\n");
+        RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+        return Status;
     }
 
-    /* Set the Process Console */
-    ProcessData->Console = Console;
+    /* Insert the process into the processes list of the console */
+    InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
 
     /* Return it to the caller */
-    AllocConsoleRequest->Console = Console;
+    AllocConsoleRequest->Console = ProcessData->Console;
 
     /* Add a reference count because the process is tied to the console */
-    _InterlockedIncrement(&Console->ReferenceCount);
-
-    if (NewConsole || !ProcessData->bInheritHandles)
-    {
-        /* Insert the Objects */
-        Status = Win32CsrInsertObject(ProcessData,
-                                      &AllocConsoleRequest->InputHandle,
-                                      &Console->Header,
-                                      GENERIC_READ | GENERIC_WRITE,
-                                      TRUE,
-                                      FILE_SHARE_READ | FILE_SHARE_WRITE);
-        if (! NT_SUCCESS(Status))
-        {
-            DPRINT1("Failed to insert object\n");
-            ConioDeleteConsole((Object_t *) Console);
-            ProcessData->Console = 0;
-            RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-            return Status;
-        }
+    _InterlockedIncrement(&ProcessData->Console->ReferenceCount);
+
+#if 0000
+    /*
+     * We've just created a new console. However when ConsoleNewProcess was
+     * called, we didn't know that we wanted to create a new console and
+     * therefore, we by default inherited the handles table from our parent
+     * process. It's only now that we notice that in fact we do not need
+     * them, because we've created a new console and thus we must use it.
+     *
+     * Therefore, free our handles table and recreate a new one.
+     */
+
+    ULONG i;
+
+    /* Close all console handles and free the handle table memory */
+    for (i = 0; i < ProcessData->HandleTableSize; i++)
+    {
+        Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
+    }
+    ProcessData->HandleTableSize = 0;
+    RtlFreeHeap(ConSrvHeap, 0, ProcessData->HandleTable);
+    ProcessData->HandleTable = NULL;
+#endif
+
+    /*
+     * Create a new handle table - Insert the IO handles
+     */
+
+    /* Insert the Input handle */
+    Status = Win32CsrInsertObject(ProcessData,
+                                  &AllocConsoleRequest->InputHandle,
+                                  &ProcessData->Console->Header,
+                                  GENERIC_READ | GENERIC_WRITE,
+                                  TRUE,
+                                  FILE_SHARE_READ | FILE_SHARE_WRITE);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to insert the input handle\n");
+        ConioDeleteConsole(ProcessData->Console);
+        ProcessData->Console = NULL;
+        RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+        return Status;
+    }
 
-        Status = Win32CsrInsertObject(ProcessData,
-                                      &AllocConsoleRequest->OutputHandle,
-                                      &Console->ActiveBuffer->Header,
-                                      GENERIC_READ | GENERIC_WRITE,
-                                      TRUE,
-                                      FILE_SHARE_READ | FILE_SHARE_WRITE);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("Failed to insert object\n");
-            ConioDeleteConsole((Object_t *) Console);
-            Win32CsrReleaseObject(ProcessData,
-                                  AllocConsoleRequest->InputHandle);
-            ProcessData->Console = 0;
-            RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-            return Status;
-        }
+    /* Insert the Output handle */
+    Status = Win32CsrInsertObject(ProcessData,
+                                  &AllocConsoleRequest->OutputHandle,
+                                  &ProcessData->Console->ActiveBuffer->Header,
+                                  GENERIC_READ | GENERIC_WRITE,
+                                  TRUE,
+                                  FILE_SHARE_READ | FILE_SHARE_WRITE);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to insert the output handle\n");
+        ConioDeleteConsole(ProcessData->Console);
+        Win32CsrReleaseObject(ProcessData,
+                              AllocConsoleRequest->InputHandle);
+        ProcessData->Console = NULL;
+        RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+        return Status;
+    }
+
+    /* Insert the Error handle */
+    Status = Win32CsrInsertObject(ProcessData,
+                                  &AllocConsoleRequest->ErrorHandle,
+                                  &ProcessData->Console->ActiveBuffer->Header,
+                                  GENERIC_READ | GENERIC_WRITE,
+                                  TRUE,
+                                  FILE_SHARE_READ | FILE_SHARE_WRITE);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to insert the error handle\n");
+        ConioDeleteConsole(ProcessData->Console);
+        Win32CsrReleaseObject(ProcessData,
+                              AllocConsoleRequest->OutputHandle);
+        Win32CsrReleaseObject(ProcessData,
+                              AllocConsoleRequest->InputHandle);
+        ProcessData->Console = NULL;
+        RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+        return Status;
     }
 
     /* Duplicate the Event */
-    if (!DuplicateHandle(GetCurrentProcess(),
-                         ProcessData->Console->ActiveEvent,
-                         ProcessData->ProcessHandle,
-                         &ProcessData->ConsoleEvent,
-                         EVENT_ALL_ACCESS,
-                         FALSE,
-                         0))
-    {
-        DPRINT1("DuplicateHandle() failed: %lu\n", GetLastError());
-        ConioDeleteConsole((Object_t *) Console);
-        if (NewConsole || !ProcessData->bInheritHandles)
+    Status = NtDuplicateObject(NtCurrentProcess(),
+                               ProcessData->Console->ActiveEvent,
+                               ProcessData->Process->ProcessHandle,
+                               &ProcessData->ConsoleEvent,
+                               EVENT_ALL_ACCESS, 0, 0);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
+        ConioDeleteConsole(ProcessData->Console);
+        // if (NewConsole /* || !ProcessData->bInheritHandles */)
         {
+            Win32CsrReleaseObject(ProcessData,
+                                  AllocConsoleRequest->ErrorHandle);
             Win32CsrReleaseObject(ProcessData,
                                   AllocConsoleRequest->OutputHandle);
             Win32CsrReleaseObject(ProcessData,
                                   AllocConsoleRequest->InputHandle);
         }
-        ProcessData->Console = 0;
+        ProcessData->Console = NULL;
         RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
         return Status;
     }
+    /* Input Wait Handle */
+    AllocConsoleRequest->InputWaitHandle = ProcessData->ConsoleEvent;
 
     /* Set the Ctrl Dispatcher */
     ProcessData->CtrlDispatcher = AllocConsoleRequest->CtrlDispatcher;
-    DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
-
-    if (!NewConsole)
-    {
-        /* Insert into the list if it has not been added */
-        InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
-    }
+    DPRINT("CONSRV: CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
 
     RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
     return STATUS_SUCCESS;
@@ -391,14 +443,14 @@ CSR_API(SrvAllocConsole)
 
 CSR_API(SrvFreeConsole)
 {
+    DPRINT1("SrvFreeConsole\n");
     Win32CsrReleaseConsole(CsrGetClientThread()->Process);
     return STATUS_SUCCESS;
 }
 
 VOID WINAPI
-ConioDeleteConsole(Object_t *Object)
+ConioDeleteConsole(PCONSOLE Console)
 {
-    PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object;
     ConsoleInput *Event;
 
     DPRINT("ConioDeleteConsole\n");
@@ -416,7 +468,7 @@ ConioDeleteConsole(Object_t *Object)
     if (Console->LineBuffer)
         RtlFreeHeap(ConSrvHeap, 0, Console->LineBuffer);
     while (!IsListEmpty(&Console->HistoryBuffers))
-        HistoryDeleteBuffer((struct tagHISTORY_BUFFER *)Console->HistoryBuffers.Flink);
+        HistoryDeleteBuffer((struct _HISTORY_BUFFER *)Console->HistoryBuffers.Flink);
 
     ConioDeleteScreenBuffer(Console->ActiveBuffer);
     if (!IsListEmpty(&Console->BufferList))
@@ -441,7 +493,7 @@ CsrInitConsoleSupport(VOID)
 }
 
 VOID FASTCALL
-ConioPause(PCSRSS_CONSOLE Console, UINT Flags)
+ConioPause(PCONSOLE Console, UINT Flags)
 {
     Console->PauseFlags |= Flags;
     if (!Console->UnpauseEvent)
@@ -449,23 +501,30 @@ ConioPause(PCSRSS_CONSOLE Console, UINT Flags)
 }
 
 VOID FASTCALL
-ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags)
+ConioUnpause(PCONSOLE Console, UINT Flags)
 {
     Console->PauseFlags &= ~Flags;
+
+    // if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0)
     if (Console->PauseFlags == 0 && Console->UnpauseEvent)
     {
         SetEvent(Console->UnpauseEvent);
         CloseHandle(Console->UnpauseEvent);
         Console->UnpauseEvent = NULL;
+
+        CsrNotifyWait(&Console->WriteWaitQueue,
+                      WaitAll,
+                      NULL,
+                      NULL);
     }
 }
 
 CSR_API(SrvSetConsoleMode)
 {
     NTSTATUS Status;
-    PCSRSS_CONSOLE_MODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
-    PCSRSS_CONSOLE Console;
-    PCSRSS_SCREEN_BUFFER Buff;
+    PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
+    PCONSOLE Console;
+    PCONSOLE_SCREEN_BUFFER Buff;
 
     DPRINT("SrvSetConsoleMode\n");
 
@@ -474,7 +533,7 @@ CSR_API(SrvSetConsoleMode)
                                 (Object_t **) &Console, GENERIC_WRITE, 0);
     if (!NT_SUCCESS(Status)) return Status;
 
-    Buff = (PCSRSS_SCREEN_BUFFER)Console;
+    Buff = (PCONSOLE_SCREEN_BUFFER)Console;
 
     if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
     {
@@ -497,9 +556,9 @@ CSR_API(SrvSetConsoleMode)
 CSR_API(SrvGetConsoleMode)
 {
     NTSTATUS Status;
-    PCSRSS_CONSOLE_MODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
-    PCSRSS_CONSOLE Console;
-    PCSRSS_SCREEN_BUFFER Buff;
+    PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
+    PCONSOLE Console;
+    PCONSOLE_SCREEN_BUFFER Buff;
 
     DPRINT("SrvGetConsoleMode\n");
 
@@ -509,7 +568,7 @@ CSR_API(SrvGetConsoleMode)
     if (!NT_SUCCESS(Status)) return Status;
 
     Status = STATUS_SUCCESS;
-    Buff = (PCSRSS_SCREEN_BUFFER) Console;
+    Buff = (PCONSOLE_SCREEN_BUFFER) Console;
 
     if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
     {
@@ -531,31 +590,34 @@ CSR_API(SrvGetConsoleMode)
 CSR_API(SrvSetConsoleTitle)
 {
     NTSTATUS Status;
-    PCSRSS_SET_TITLE SetTitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetTitleRequest;
-    PCSR_PROCESS ProcessData = CsrGetClientThread()->Process;
-    PCSRSS_CONSOLE Console;
+    PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
+    // PCSR_PROCESS Process = CsrGetClientThread()->Process;
+    PCONSOLE Console;
     PWCHAR Buffer;
 
     DPRINT("SrvSetConsoleTitle\n");
 
-    if (!Win32CsrValidateBuffer(ProcessData, SetTitleRequest->Title,
-                                SetTitleRequest->Length, 1))
+    if (!CsrValidateMessageBuffer(ApiMessage,
+                                  (PVOID)&TitleRequest->Title,
+                                  TitleRequest->Length,
+                                  sizeof(BYTE)))
     {
-        return STATUS_ACCESS_VIOLATION;
+        return STATUS_INVALID_PARAMETER;
     }
 
-    Status = ConioConsoleFromProcessData(ProcessData, &Console);
+    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
     if(NT_SUCCESS(Status))
     {
-        Buffer =  RtlAllocateHeap(RtlGetProcessHeap(), 0, SetTitleRequest->Length);
+        Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, TitleRequest->Length);
         if (Buffer)
         {
-            /* copy title to console */
+            /* Copy title to console */
             RtlFreeUnicodeString(&Console->Title);
             Console->Title.Buffer = Buffer;
-            Console->Title.Length = Console->Title.MaximumLength = SetTitleRequest->Length;
-            memcpy(Console->Title.Buffer, SetTitleRequest->Title, Console->Title.Length);
-            if (! ConioChangeTitle(Console))
+            Console->Title.Length = Console->Title.MaximumLength = TitleRequest->Length;
+            memcpy(Console->Title.Buffer, TitleRequest->Title, Console->Title.Length);
+
+            if (!ConioChangeTitle(Console))
             {
                 Status = STATUS_UNSUCCESSFUL;
             }
@@ -568,6 +630,7 @@ CSR_API(SrvSetConsoleTitle)
         {
             Status = STATUS_NO_MEMORY;
         }
+
         ConioUnlockConsole(Console);
     }
 
@@ -577,35 +640,37 @@ CSR_API(SrvSetConsoleTitle)
 CSR_API(SrvGetConsoleTitle)
 {
     NTSTATUS Status;
-    PCSRSS_GET_TITLE GetTitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetTitleRequest;
-    PCSR_PROCESS ProcessData = CsrGetClientThread()->Process;
-    PCSRSS_CONSOLE Console;
+    PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
+    // PCSR_PROCESS Process = CsrGetClientThread()->Process;
+    PCONSOLE Console;
     DWORD Length;
 
     DPRINT("SrvGetConsoleTitle\n");
 
-    if (!Win32CsrValidateBuffer(ProcessData, GetTitleRequest->Title,
-                                GetTitleRequest->Length, 1))
+    if (!CsrValidateMessageBuffer(ApiMessage,
+                                  (PVOID)&TitleRequest->Title,
+                                  TitleRequest->Length,
+                                  sizeof(BYTE)))
     {
-        return STATUS_ACCESS_VIOLATION;
+        return STATUS_INVALID_PARAMETER;
     }
 
-    Status = ConioConsoleFromProcessData(ProcessData, &Console);
-    if (! NT_SUCCESS(Status))
+    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
+    if (!NT_SUCCESS(Status))
     {
         DPRINT1("Can't get console\n");
         return Status;
     }
 
     /* Copy title of the console to the user title buffer */
-    if (GetTitleRequest->Length >= sizeof(WCHAR))
+    if (TitleRequest->Length >= sizeof(WCHAR))
     {
-        Length = min(GetTitleRequest->Length - sizeof(WCHAR), Console->Title.Length);
-        memcpy(GetTitleRequest->Title, Console->Title.Buffer, Length);
-        GetTitleRequest->Title[Length / sizeof(WCHAR)] = L'\0';
+        Length = min(TitleRequest->Length - sizeof(WCHAR), Console->Title.Length);
+        memcpy(TitleRequest->Title, Console->Title.Buffer, Length);
+        TitleRequest->Title[Length / sizeof(WCHAR)] = L'\0';
     }
 
-    GetTitleRequest->Length = Console->Title.Length;
+    TitleRequest->Length = Console->Title.Length;
 
     ConioUnlockConsole(Console);
     return STATUS_SUCCESS;
@@ -619,14 +684,14 @@ CSR_API(SrvGetConsoleTitle)
  *      between direct video buffer ouput and GDI windowed
  *      output.
  *  ARGUMENTS
- *      Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
- *      object. We use the same object to Request.
+ *      Client hands us a CONSOLE_GETSETHWSTATE object.
+ *      We use the same object to Request.
  *  NOTE
  *      ConsoleHwState has the correct size to be compatible
  *      with NT's, but values are not.
  */
 static NTSTATUS FASTCALL
-SetConsoleHardwareState(PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
+SetConsoleHardwareState(PCONSOLE Console, DWORD ConsoleHwState)
 {
     DPRINT1("Console Hardware State: %d\n", ConsoleHwState);
 
@@ -649,13 +714,13 @@ SetConsoleHardwareState(PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
 CSR_API(SrvGetConsoleHardwareState)
 {
     NTSTATUS Status;
-    PCSRSS_CONSOLE_HW_STATE ConsoleHardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleHardwareStateRequest;
-    PCSRSS_CONSOLE Console;
+    PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest;
+    PCONSOLE Console;
 
     DPRINT("SrvGetConsoleHardwareState\n");
 
     Status = ConioLockConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
-                              ConsoleHardwareStateRequest->ConsoleHandle,
+                              HardwareStateRequest->OutputHandle,
                               &Console,
                               GENERIC_READ);
     if (!NT_SUCCESS(Status))
@@ -664,7 +729,7 @@ CSR_API(SrvGetConsoleHardwareState)
         return Status;
     }
 
-    ConsoleHardwareStateRequest->State = Console->HardwareState;
+    HardwareStateRequest->State = Console->HardwareState;
 
     ConioUnlockConsole(Console);
 
@@ -674,13 +739,13 @@ CSR_API(SrvGetConsoleHardwareState)
 CSR_API(SrvSetConsoleHardwareState)
 {
     NTSTATUS Status;
-    PCSRSS_CONSOLE_HW_STATE ConsoleHardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleHardwareStateRequest;
-    PCSRSS_CONSOLE Console;
+    PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest;
+    PCONSOLE Console;
 
     DPRINT("SrvSetConsoleHardwareState\n");
 
     Status = ConioLockConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
-                              ConsoleHardwareStateRequest->ConsoleHandle,
+                              HardwareStateRequest->OutputHandle,
                               &Console,
                               GENERIC_READ);
     if (!NT_SUCCESS(Status))
@@ -690,7 +755,7 @@ CSR_API(SrvSetConsoleHardwareState)
     }
 
     DPRINT("Setting console hardware state.\n");
-    Status = SetConsoleHardwareState(Console, ConsoleHardwareStateRequest->State);
+    Status = SetConsoleHardwareState(Console, HardwareStateRequest->State);
 
     ConioUnlockConsole(Console);
 
@@ -699,19 +764,16 @@ CSR_API(SrvSetConsoleHardwareState)
 
 CSR_API(SrvGetConsoleWindow)
 {
-    PCSRSS_GET_CONSOLE_WINDOW GetConsoleWindowRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetConsoleWindowRequest;
-    PCSRSS_CONSOLE Console;
     NTSTATUS Status;
+    PCONSOLE_GETWINDOW GetWindowRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetWindowRequest;
+    PCONSOLE Console;
 
     DPRINT("SrvGetConsoleWindow\n");
 
-    Status = ConioConsoleFromProcessData(CsrGetClientThread()->Process, &Console);
-    if (! NT_SUCCESS(Status))
-    {
-        return Status;
-    }
+    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
+    if (!NT_SUCCESS(Status)) return Status;
 
-    GetConsoleWindowRequest->WindowHandle = Console->hWindow;
+    GetWindowRequest->WindowHandle = Console->hWindow;
     ConioUnlockConsole(Console);
 
     return STATUS_SUCCESS;
@@ -719,20 +781,19 @@ CSR_API(SrvGetConsoleWindow)
 
 CSR_API(SrvSetConsoleIcon)
 {
-    PCSRSS_SET_CONSOLE_ICON SetConsoleIconRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetConsoleIconRequest;
-    PCSRSS_CONSOLE Console;
     NTSTATUS Status;
+    PCONSOLE_SETICON SetIconRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetIconRequest;
+    PCONSOLE Console;
 
     DPRINT("SrvSetConsoleIcon\n");
 
-    Status = ConioConsoleFromProcessData(CsrGetClientThread()->Process, &Console);
-    if (! NT_SUCCESS(Status))
-    {
-        return Status;
-    }
+    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    Status = (ConioChangeIcon(Console, SetIconRequest->WindowIcon)
+                ? STATUS_SUCCESS
+                : STATUS_UNSUCCESSFUL);
 
-    Status = (ConioChangeIcon(Console, SetConsoleIconRequest->WindowIcon)
-              ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
     ConioUnlockConsole(Console);
 
     return Status;
@@ -740,84 +801,41 @@ CSR_API(SrvSetConsoleIcon)
 
 CSR_API(SrvGetConsoleCP)
 {
-    PCSRSS_GET_CONSOLE_CP GetConsoleCodePage = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetConsoleCodePage;
-    PCSRSS_CONSOLE Console;
     NTSTATUS Status;
+    PCONSOLE_GETSETINPUTOUTPUTCP ConsoleCPRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleCPRequest;
+    PCONSOLE Console;
 
-    DPRINT("SrvGetConsoleCP\n");
-
-    Status = ConioConsoleFromProcessData(CsrGetClientThread()->Process, &Console);
-    if (! NT_SUCCESS(Status))
-    {
-        return Status;
-    }
+    DPRINT("SrvGetConsoleCP, getting %s Code Page\n",
+            ConsoleCPRequest->InputCP ? "Input" : "Output");
 
-    GetConsoleCodePage->CodePage = Console->CodePage;
-    ConioUnlockConsole(Console);
-    return STATUS_SUCCESS;
-}
-
-CSR_API(CsrGetConsoleOutputCodePage) // TODO: Merge this function with the other one.
-{
-    PCSRSS_GET_CONSOLE_OUTPUT_CP GetConsoleOutputCodePage = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetConsoleOutputCodePage;
-    PCSRSS_CONSOLE Console;
-    NTSTATUS Status;
-
-    DPRINT("CsrGetConsoleOutputCodePage\n");
-
-    Status = ConioConsoleFromProcessData(CsrGetClientThread()->Process, &Console);
-    if (! NT_SUCCESS(Status))
-    {
-        return Status;
-    }
+    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
+    if (!NT_SUCCESS(Status)) return Status;
 
-    GetConsoleOutputCodePage->CodePage = Console->OutputCodePage;
+    ConsoleCPRequest->CodePage = (ConsoleCPRequest->InputCP ? Console->CodePage
+                                                            : Console->OutputCodePage);
     ConioUnlockConsole(Console);
     return STATUS_SUCCESS;
 }
 
 CSR_API(SrvSetConsoleCP)
 {
-    PCSRSS_SET_CONSOLE_CP SetConsoleCodePage = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetConsoleCodePage;
-    PCSRSS_CONSOLE Console;
     NTSTATUS Status;
+    PCONSOLE_GETSETINPUTOUTPUTCP ConsoleCPRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleCPRequest;
+    PCONSOLE Console;
 
-    DPRINT("SrvSetConsoleCP\n");
-
-    Status = ConioConsoleFromProcessData(CsrGetClientThread()->Process, &Console);
-    if (! NT_SUCCESS(Status))
-    {
-        return Status;
-    }
+    DPRINT("SrvSetConsoleCP, setting %s Code Page\n",
+            ConsoleCPRequest->InputCP ? "Input" : "Output");
 
-    if (IsValidCodePage(SetConsoleCodePage->CodePage))
-    {
-        Console->CodePage = SetConsoleCodePage->CodePage;
-        ConioUnlockConsole(Console);
-        return STATUS_SUCCESS;
-    }
-
-    ConioUnlockConsole(Console);
-    return STATUS_INVALID_PARAMETER;
-}
-
-CSR_API(CsrSetConsoleOutputCodePage) // TODO: Merge this function with the other one.
-{
-    PCSRSS_SET_CONSOLE_OUTPUT_CP SetConsoleOutputCodePage = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetConsoleOutputCodePage;
-    PCSRSS_CONSOLE Console;
-    NTSTATUS Status;
-
-    DPRINT("CsrSetConsoleOutputCodePage\n");
+    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
+    if (!NT_SUCCESS(Status)) return Status;
 
-    Status = ConioConsoleFromProcessData(CsrGetClientThread()->Process, &Console);
-    if (! NT_SUCCESS(Status))
+    if (IsValidCodePage(ConsoleCPRequest->CodePage))
     {
-        return Status;
-    }
+        if (ConsoleCPRequest->InputCP)
+            Console->CodePage = ConsoleCPRequest->CodePage;
+        else
+            Console->OutputCodePage = ConsoleCPRequest->CodePage;
 
-    if (IsValidCodePage(SetConsoleOutputCodePage->CodePage))
-    {
-        Console->OutputCodePage = SetConsoleOutputCodePage->CodePage;
         ConioUnlockConsole(Console);
         return STATUS_SUCCESS;
     }
@@ -828,35 +846,38 @@ CSR_API(CsrSetConsoleOutputCodePage) // TODO: Merge this function with the other
 
 CSR_API(SrvGetConsoleProcessList)
 {
-    PCSRSS_GET_PROCESS_LIST GetProcessListRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetProcessListRequest;
+    NTSTATUS Status;
+    PCONSOLE_GETPROCESSLIST GetProcessListRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetProcessListRequest;
     PDWORD Buffer;
-    PCSR_PROCESS ProcessData = CsrGetClientThread()->Process;
-    PCSRSS_CONSOLE Console;
-    PCSR_PROCESS current;
+    // PCSR_PROCESS Process = CsrGetClientThread()->Process;
+    PCONSOLE Console;
+    PCONSOLE_PROCESS_DATA current;
     PLIST_ENTRY current_entry;
     ULONG nItems = 0;
-    NTSTATUS Status;
 
     DPRINT("SrvGetConsoleProcessList\n");
 
-    Buffer = GetProcessListRequest->ProcessId;
-    if (!Win32CsrValidateBuffer(ProcessData, Buffer, GetProcessListRequest->nMaxIds, sizeof(DWORD)))
-        return STATUS_ACCESS_VIOLATION;
-
-    Status = ConioConsoleFromProcessData(ProcessData, &Console);
-    if (! NT_SUCCESS(Status))
+    if (!CsrValidateMessageBuffer(ApiMessage,
+                                  (PVOID)&GetProcessListRequest->pProcessIds,
+                                  GetProcessListRequest->nMaxIds,
+                                  sizeof(DWORD)))
     {
-        return Status;
+        return STATUS_INVALID_PARAMETER;
     }
 
+    Buffer = GetProcessListRequest->pProcessIds;
+
+    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
+    if (!NT_SUCCESS(Status)) return Status;
+
     for (current_entry = Console->ProcessList.Flink;
          current_entry != &Console->ProcessList;
          current_entry = current_entry->Flink)
     {
-        current = CONTAINING_RECORD(current_entry, CSR_PROCESS, ConsoleLink);
+        current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
         if (++nItems <= GetProcessListRequest->nMaxIds)
         {
-            *Buffer++ = HandleToUlong(current->ClientId.UniqueProcess);
+            *Buffer++ = HandleToUlong(current->Process->ClientId.UniqueProcess);
         }
     }
 
@@ -868,29 +889,26 @@ CSR_API(SrvGetConsoleProcessList)
 
 CSR_API(SrvGenerateConsoleCtrlEvent)
 {
-    PCSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GenerateCtrlEvent;
-    PCSRSS_CONSOLE Console;
-    PCSR_PROCESS current;
+    NTSTATUS Status;
+    PCONSOLE_GENERATECTRLEVENT GenerateCtrlEventRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GenerateCtrlEventRequest;
+    PCONSOLE Console;
+    PCONSOLE_PROCESS_DATA current;
     PLIST_ENTRY current_entry;
     DWORD Group;
-    NTSTATUS Status;
 
-    Status = ConioConsoleFromProcessData(CsrGetClientThread()->Process, &Console);
-    if (! NT_SUCCESS(Status))
-    {
-        return Status;
-    }
+    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
+    if (!NT_SUCCESS(Status)) return Status;
 
-    Group = GenerateCtrlEvent->ProcessGroup;
+    Group = GenerateCtrlEventRequest->ProcessGroup;
     Status = STATUS_INVALID_PARAMETER;
-    for (current_entry = Console->ProcessList.Flink;
-            current_entry != &Console->ProcessList;
-            current_entry = current_entry->Flink)
+    for (current_entry  = Console->ProcessList.Flink;
+         current_entry != &Console->ProcessList;
+         current_entry  = current_entry->Flink)
     {
-        current = CONTAINING_RECORD(current_entry, CSR_PROCESS, ConsoleLink);
-        if (Group == 0 || current->ProcessGroupId == Group)
+        current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
+        if (Group == 0 || current->Process->ProcessGroupId == Group)
         {
-            ConioConsoleCtrlEvent(GenerateCtrlEvent->Event, current);
+            ConioConsoleCtrlEvent(GenerateCtrlEventRequest->Event, current);
             Status = STATUS_SUCCESS;
         }
     }
@@ -903,17 +921,18 @@ CSR_API(SrvGenerateConsoleCtrlEvent)
 CSR_API(SrvGetConsoleSelectionInfo)
 {
     NTSTATUS Status;
-    PCSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetConsoleSelectionInfo;
-    PCSRSS_CONSOLE Console;
+    PCONSOLE_GETSELECTIONINFO GetSelectionInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetSelectionInfoRequest;
+    PCONSOLE Console;
 
-    Status = ConioConsoleFromProcessData(CsrGetClientThread()->Process, &Console);
+    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
     if (NT_SUCCESS(Status))
     {
-        memset(&GetConsoleSelectionInfo->Info, 0, sizeof(CONSOLE_SELECTION_INFO));
+        memset(&GetSelectionInfoRequest->Info, 0, sizeof(CONSOLE_SELECTION_INFO));
         if (Console->Selection.dwFlags != 0)
-            GetConsoleSelectionInfo->Info = Console->Selection;
+            GetSelectionInfoRequest->Info = Console->Selection;
         ConioUnlockConsole(Console);
     }
+
     return Status;
 }