[CSRSRV]
[reactos.git] / win32ss / user / consrv / handle.c
index 6d321a9..339dbb3 100644 (file)
@@ -35,22 +35,49 @@ AdjustHandleCounts(PCONSOLE_IO_HANDLE Entry, INT Change)
 }
 
 static VOID
-Win32CsrCreateHandleEntry(PCONSOLE_IO_HANDLE Entry)
+ConSrvCreateHandleEntry(PCONSOLE_IO_HANDLE Entry)
 {
-    Object_t *Object = Entry->Object;
-    EnterCriticalSection(&Object->Console->Lock);
+    /// LOCK /// Object_t *Object = Entry->Object;
+    /// LOCK /// EnterCriticalSection(&Object->Console->Lock);
     AdjustHandleCounts(Entry, +1);
-    LeaveCriticalSection(&Object->Console->Lock);
+    /// LOCK /// LeaveCriticalSection(&Object->Console->Lock);
 }
 
 static VOID
-Win32CsrCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
+ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
 {
     Object_t *Object = Entry->Object;
     if (Object != NULL)
     {
-        PCONSOLE Console = Object->Console;
-        EnterCriticalSection(&Console->Lock);
+        /// LOCK /// PCONSOLE Console = Object->Console;
+        /// LOCK /// EnterCriticalSection(&Console->Lock);
+
+        /*
+         * If this is a input handle, notify and dereference
+         * all the waits related to this handle.
+         */
+        if (Object->Type == CONIO_INPUT_BUFFER_MAGIC)
+        {
+            PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object;
+
+            /*
+             * Wake up all the writing waiters related to this handle for this
+             * input buffer, if any, then dereference them and purge them all
+             * from the list.
+             * To select them amongst all the waiters for this input buffer,
+             * pass the handle pointer to the waiters, then they will check
+             * whether or not they are related to this handle and if so, they
+             * return.
+             */
+            CsrNotifyWait(&InputBuffer->ReadWaitQueue,
+                          WaitAll,
+                          NULL,
+                          (PVOID)Entry);
+            if (!IsListEmpty(&InputBuffer->ReadWaitQueue))
+            {
+                CsrDereferenceWait(&InputBuffer->ReadWaitQueue);
+            }
+        }
 
         /* If the last handle to a screen buffer is closed, delete it... */
         if (AdjustHandleCounts(Entry, -1) == 0)
@@ -70,7 +97,7 @@ Win32CsrCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
             }
         }
 
-        LeaveCriticalSection(&Console->Lock);
+        /// LOCK /// LeaveCriticalSection(&Console->Lock);
         Entry->Object = NULL;
     }
 }
@@ -80,10 +107,10 @@ Win32CsrCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
 
 /* static */ NTSTATUS
 FASTCALL
-Win32CsrInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData,
-                         OUT PHANDLE pInputHandle,
-                         OUT PHANDLE pOutputHandle,
-                         OUT PHANDLE pErrorHandle)
+ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData,
+                       OUT PHANDLE pInputHandle,
+                       OUT PHANDLE pOutputHandle,
+                       OUT PHANDLE pErrorHandle)
 {
     NTSTATUS Status;
     HANDLE InputHandle  = INVALID_HANDLE_VALUE,
@@ -101,47 +128,47 @@ Win32CsrInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData,
     RtlEnterCriticalSection(&ProcessData->HandleTableLock);
 
     /* Insert the Input handle */
-    Status = Win32CsrInsertObject(ProcessData,
-                                  &InputHandle,
-                                  &ProcessData->Console->InputBuffer.Header,
-                                  GENERIC_READ | GENERIC_WRITE,
-                                  TRUE,
-                                  FILE_SHARE_READ | FILE_SHARE_WRITE);
+    Status = ConSrvInsertObject(ProcessData,
+                                &InputHandle,
+                                &ProcessData->Console->InputBuffer.Header,
+                                GENERIC_READ | GENERIC_WRITE,
+                                TRUE,
+                                FILE_SHARE_READ | FILE_SHARE_WRITE);
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Failed to insert the input handle\n");
         RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-        Win32CsrFreeHandlesTable(ProcessData);
+        ConSrvFreeHandlesTable(ProcessData);
         return Status;
     }
 
     /* Insert the Output handle */
-    Status = Win32CsrInsertObject(ProcessData,
-                                  &OutputHandle,
-                                  &ProcessData->Console->ActiveBuffer->Header,
-                                  GENERIC_READ | GENERIC_WRITE,
-                                  TRUE,
-                                  FILE_SHARE_READ | FILE_SHARE_WRITE);
+    Status = ConSrvInsertObject(ProcessData,
+                                &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");
         RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-        Win32CsrFreeHandlesTable(ProcessData);
+        ConSrvFreeHandlesTable(ProcessData);
         return Status;
     }
 
     /* Insert the Error handle */
-    Status = Win32CsrInsertObject(ProcessData,
-                                  &ErrorHandle,
-                                  &ProcessData->Console->ActiveBuffer->Header,
-                                  GENERIC_READ | GENERIC_WRITE,
-                                  TRUE,
-                                  FILE_SHARE_READ | FILE_SHARE_WRITE);
+    Status = ConSrvInsertObject(ProcessData,
+                                &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");
         RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-        Win32CsrFreeHandlesTable(ProcessData);
+        ConSrvFreeHandlesTable(ProcessData);
         return Status;
     }
 
@@ -156,8 +183,8 @@ Win32CsrInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData,
 
 NTSTATUS
 FASTCALL
-Win32CsrInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
-                            IN PCONSOLE_PROCESS_DATA TargetProcessData)
+ConSrvInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
+                          IN PCONSOLE_PROCESS_DATA TargetProcessData)
 {
     NTSTATUS Status = STATUS_SUCCESS;
     ULONG i;
@@ -195,10 +222,10 @@ Win32CsrInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
         {
             /*
              * Copy the handle data and increment the reference count of the
-             * pointed object (via the call to Win32CsrCreateHandleEntry).
+             * pointed object (via the call to ConSrvCreateHandleEntry).
              */
             TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i];
-            Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i]);
+            ConSrvCreateHandleEntry(&TargetProcessData->HandleTable[i]);
         }
     }
 
@@ -209,9 +236,9 @@ Quit:
 
 VOID
 FASTCALL
-Win32CsrFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
+ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
 {
-    DPRINT1("Win32CsrFreeHandlesTable\n");
+    DPRINT1("ConSrvFreeHandlesTable\n");
 
     RtlEnterCriticalSection(&ProcessData->HandleTableLock);
 
@@ -222,7 +249,7 @@ Win32CsrFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
         /* Close all console handles and free the handle table memory */
         for (i = 0; i < ProcessData->HandleTableSize; i++)
         {
-            Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
+            ConSrvCloseHandleEntry(&ProcessData->HandleTable[i]);
         }
         RtlFreeHeap(ConSrvHeap, 0, ProcessData->HandleTable);
         ProcessData->HandleTable = NULL;
@@ -235,12 +262,12 @@ Win32CsrFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
 
 NTSTATUS
 FASTCALL
-Win32CsrInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
-                     PHANDLE Handle,
-                     Object_t *Object,
-                     DWORD Access,
-                     BOOL Inheritable,
-                     DWORD ShareMode)
+ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
+                   PHANDLE Handle,
+                   Object_t *Object,
+                   DWORD Access,
+                   BOOL Inheritable,
+                   DWORD ShareMode)
 {
 #define IO_HANDLES_INCREMENT    2*3
 
@@ -279,7 +306,7 @@ Win32CsrInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
     ProcessData->HandleTable[i].Access      = Access;
     ProcessData->HandleTable[i].Inheritable = Inheritable;
     ProcessData->HandleTable[i].ShareMode   = ShareMode;
-    Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i]);
+    ConSrvCreateHandleEntry(&ProcessData->HandleTable[i]);
     *Handle = ULongToHandle((i << 2) | 0x3);
 
     RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
@@ -289,8 +316,8 @@ Win32CsrInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
 
 NTSTATUS
 FASTCALL
-Win32CsrReleaseObject(PCONSOLE_PROCESS_DATA ProcessData,
-                      HANDLE Handle)
+ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData,
+                   HANDLE Handle)
 {
     ULONG_PTR h = (ULONG_PTR)Handle >> 2;
     Object_t *Object;
@@ -304,8 +331,8 @@ Win32CsrReleaseObject(PCONSOLE_PROCESS_DATA ProcessData,
         return STATUS_INVALID_HANDLE;
     }
 
-    DPRINT1("Win32CsrReleaseObject - Process 0x%p, Release 0x%p\n", ProcessData->Process, &ProcessData->HandleTable[h]);
-    Win32CsrCloseHandleEntry(&ProcessData->HandleTable[h]);
+    DPRINT1("ConSrvRemoveObject - Process 0x%p, Release 0x%p\n", ProcessData->Process, &ProcessData->HandleTable[h]);
+    ConSrvCloseHandleEntry(&ProcessData->HandleTable[h]);
 
     RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
 
@@ -314,67 +341,76 @@ Win32CsrReleaseObject(PCONSOLE_PROCESS_DATA ProcessData,
 
 NTSTATUS
 FASTCALL
-Win32CsrLockObject(PCONSOLE_PROCESS_DATA ProcessData,
-                   HANDLE Handle,
-                   Object_t **Object,
-                   DWORD Access,
-                   ULONG Type)
+ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
+                HANDLE Handle,
+                Object_t** Object,
+                PCONSOLE_IO_HANDLE* Entry OPTIONAL,
+                DWORD Access,
+                BOOL LockConsole,
+                ULONG Type)
 {
     ULONG_PTR h = (ULONG_PTR)Handle >> 2;
+    PCONSOLE_IO_HANDLE HandleEntry = NULL;
+    Object_t* ObjectEntry = NULL;
+
+    ASSERT(Object);
+    if (Entry) *Entry = NULL;
 
-    // DPRINT("Win32CsrLockObject, Object: %x, %x, %x\n",
+    // DPRINT("ConSrvGetObject, Object: %x, %x, %x\n",
            // Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0);
 
     RtlEnterCriticalSection(&ProcessData->HandleTableLock);
 
-    if ( !IsConsoleHandle(Handle) ||
-         h >= ProcessData->HandleTableSize  ||
-         (*Object = ProcessData->HandleTable[h].Object) == NULL ||
-         ~ProcessData->HandleTable[h].Access & Access           ||
-         (Type != 0 && (*Object)->Type != Type) )
+    if ( IsConsoleHandle(Handle) &&
+         h < ProcessData->HandleTableSize )
     {
-        DPRINT1("CsrGetObject returning invalid handle (%x) of type %lu with access %lu\n", Handle, Type, Access);
+        HandleEntry = &ProcessData->HandleTable[h];
+        ObjectEntry = HandleEntry->Object;
+    }
+
+    if ( HandleEntry == NULL ||
+         ObjectEntry == NULL ||
+         (HandleEntry->Access & Access) == 0 ||
+         (Type != 0 && ObjectEntry->Type != Type) )
+    {
+        DPRINT1("ConSrvGetObject returning invalid handle (%x) of type %lu with access %lu\n", Handle, Type, Access);
         RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
         return STATUS_INVALID_HANDLE;
     }
 
-    _InterlockedIncrement(&(*Object)->Console->ReferenceCount);
+    _InterlockedIncrement(&ObjectEntry->Console->ReferenceCount);
     RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
 
-    EnterCriticalSection(&(*Object)->Console->Lock);
-    return STATUS_SUCCESS;
-}
+    if (LockConsole) EnterCriticalSection(&ObjectEntry->Console->Lock);
 
-VOID FASTCALL
-Win32CsrUnlockConsole(PCONSOLE Console)
-{
-    LeaveCriticalSection(&Console->Lock);
+    /* Return the objects to the caller */
+    *Object = ObjectEntry;
+    if (Entry) *Entry = HandleEntry;
 
-    /* Decrement reference count */
-    if (_InterlockedDecrement(&Console->ReferenceCount) == 0)
-        ConioDeleteConsole(Console);
+    return STATUS_SUCCESS;
 }
 
 VOID
 FASTCALL
-Win32CsrUnlockObject(Object_t *Object)
+ConSrvReleaseObject(Object_t *Object,
+                    BOOL IsConsoleLocked)
 {
-    Win32CsrUnlockConsole(Object->Console);
+    ConSrvReleaseConsole(Object->Console, IsConsoleLocked);
 }
 
 NTSTATUS
 FASTCALL
-Win32CsrAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
-                        PHANDLE pInputHandle,
-                        PHANDLE pOutputHandle,
-                        PHANDLE pErrorHandle,
-                        int ShowCmd,
-                        PCSR_PROCESS CsrProcess)
+ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
+                      LPCWSTR AppPath,
+                      PHANDLE pInputHandle,
+                      PHANDLE pOutputHandle,
+                      PHANDLE pErrorHandle,
+                      PCONSOLE_START_INFO ConsoleStartInfo)
 {
     NTSTATUS Status = STATUS_SUCCESS;
 
-    /* Initialize a new Console owned by the Console Leader Process */
-    Status = CsrInitConsole(&ProcessData->Console, ShowCmd, CsrProcess);
+    /* Initialize a new Console owned by this process */
+    Status = ConSrvInitConsole(&ProcessData->Console, AppPath, ConsoleStartInfo, ProcessData->Process);
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Console initialization failed\n");
@@ -382,44 +418,123 @@ Win32CsrAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
     }
 
     /* Initialize the handles table */
-    Status = Win32CsrInitHandlesTable(ProcessData,
-                                      pInputHandle,
-                                      pOutputHandle,
-                                      pErrorHandle);
+    Status = ConSrvInitHandlesTable(ProcessData,
+                                    pInputHandle,
+                                    pOutputHandle,
+                                    pErrorHandle);
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Failed to initialize the handles table\n");
+        ConSrvDeleteConsole(ProcessData->Console);
+        ProcessData->Console = NULL;
+        return Status;
+    }
 
-        // Win32CsrReleaseConsole(ProcessData);
-        ConioDeleteConsole(ProcessData->Console);
+    /* Duplicate the Input Event */
+    Status = NtDuplicateObject(NtCurrentProcess(),
+                               ProcessData->Console->InputBuffer.ActiveEvent,
+                               ProcessData->Process->ProcessHandle,
+                               &ProcessData->ConsoleEvent,
+                               EVENT_ALL_ACCESS, 0, 0);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
+        ConSrvFreeHandlesTable(ProcessData);
+        ConSrvDeleteConsole(ProcessData->Console);
         ProcessData->Console = NULL;
+        return Status;
+    }
+
+    /* Insert the process into the processes list of the console */
+    InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
+
+    /* Add a reference count because the process is tied to the console */
+    _InterlockedIncrement(&ProcessData->Console->ReferenceCount);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+FASTCALL
+ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
+                     PCONSOLE Console,
+                     BOOL CreateNewHandlesTable,
+                     PHANDLE pInputHandle,
+                     PHANDLE pOutputHandle,
+                     PHANDLE pErrorHandle)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    /* Inherit the console */
+    ProcessData->Console = Console;
+
+    if (CreateNewHandlesTable)
+    {
+        /* Initialize the handles table */
+        Status = ConSrvInitHandlesTable(ProcessData,
+                                        pInputHandle,
+                                        pOutputHandle,
+                                        pErrorHandle);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to initialize the handles table\n");
+            ProcessData->Console = NULL;
+            return Status;
+        }
+    }
 
+    /* Duplicate the Input Event */
+    Status = NtDuplicateObject(NtCurrentProcess(),
+                               ProcessData->Console->InputBuffer.ActiveEvent,
+                               ProcessData->Process->ProcessHandle,
+                               &ProcessData->ConsoleEvent,
+                               EVENT_ALL_ACCESS, 0, 0);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
+        ConSrvFreeHandlesTable(ProcessData); // NOTE: Always free the handles table.
+        ProcessData->Console = NULL;
         return Status;
     }
 
-    return Status;
+    /* Insert the process into the processes list of the console */
+    InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
+
+    /* Add a reference count because the process is tied to the console */
+    _InterlockedIncrement(&ProcessData->Console->ReferenceCount);
+
+    return STATUS_SUCCESS;
 }
 
 VOID
 FASTCALL
-Win32CsrReleaseConsole(PCONSOLE_PROCESS_DATA ProcessData)
+ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
 {
     PCONSOLE Console;
 
-    DPRINT1("Win32CsrReleaseConsole\n");
+    DPRINT1("ConSrvRemoveConsole\n");
 
     /* Close all console handles and free the handle table memory */
-    Win32CsrFreeHandlesTable(ProcessData);
+    ConSrvFreeHandlesTable(ProcessData);
 
     /* Detach process from console */
     Console = ProcessData->Console;
     if (Console != NULL)
     {
-        DPRINT1("Win32CsrReleaseConsole - Console->ReferenceCount = %lu - We are going to decrement it !\n", Console->ReferenceCount);
+        DPRINT1("ConSrvRemoveConsole - Console->ReferenceCount = %lu - We are going to decrement it !\n", Console->ReferenceCount);
         ProcessData->Console = NULL;
+
         EnterCriticalSection(&Console->Lock);
+        DPRINT1("ConSrvRemoveConsole - Locking OK\n");
+
+        /* Remove ourselves from the console's list of processes */
         RemoveEntryList(&ProcessData->ConsoleLink);
-        Win32CsrUnlockConsole(Console);
+
+        /* Update the console leader process */
+        // SetConsoleWndConsoleLeaderCID(Console);
+
+        /* Release the console */
+        ConSrvReleaseConsole(Console, TRUE);
         //CloseHandle(ProcessData->ConsoleEvent);
         //ProcessData->ConsoleEvent = NULL;
     }
@@ -427,8 +542,9 @@ Win32CsrReleaseConsole(PCONSOLE_PROCESS_DATA ProcessData)
 
 NTSTATUS
 FASTCALL
-ConioConsoleFromProcessData(PCONSOLE_PROCESS_DATA ProcessData,
-                            PCONSOLE* Console)
+ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
+                 PCONSOLE* Console,
+                 BOOL LockConsole)
 {
     PCONSOLE ProcessConsole;
 
@@ -444,18 +560,29 @@ ConioConsoleFromProcessData(PCONSOLE_PROCESS_DATA ProcessData,
 
     InterlockedIncrement(&ProcessConsole->ReferenceCount);
     RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-    EnterCriticalSection(&(ProcessConsole->Lock));
+
+    if (LockConsole) EnterCriticalSection(&ProcessConsole->Lock);
+
     *Console = ProcessConsole;
 
     return STATUS_SUCCESS;
 }
 
+VOID FASTCALL
+ConSrvReleaseConsole(PCONSOLE Console,
+                     BOOL IsConsoleLocked)
+{
+    if (IsConsoleLocked) LeaveCriticalSection(&Console->Lock);
 
+    /* Decrement reference count */
+    if (_InterlockedDecrement(&Console->ReferenceCount) == 0)
+        ConSrvDeleteConsole(Console);
+}
 
 NTSTATUS
 NTAPI
-ConsoleNewProcess(PCSR_PROCESS SourceProcess,
-                  PCSR_PROCESS TargetProcess)
+ConSrvNewProcess(PCSR_PROCESS SourceProcess,
+                 PCSR_PROCESS TargetProcess)
 {
     /**************************************************************************
      * This function is called whenever a new process (GUI or CUI) is created.
@@ -463,25 +590,18 @@ ConsoleNewProcess(PCSR_PROCESS SourceProcess,
      * Copy the parent's handles table here if both the parent and the child
      * processes are CUI. If we must actually create our proper console (and
      * thus do not inherit from the console handles of the parent's), then we
-     * will clean this table in the next ConsoleConnect call. Why we are doing
+     * will clean this table in the next ConSrvConnect call. Why we are doing
      * this? It's because here, we still don't know whether or not we must create
      * a new console instead of inherit it from the parent, and, because in
-     * ConsoleConnect we don't have any reference to the parent process anymore.
+     * ConSrvConnect we don't have any reference to the parent process anymore.
      **************************************************************************/
 
     PCONSOLE_PROCESS_DATA SourceProcessData, TargetProcessData;
 
-    DPRINT1("ConsoleNewProcess inside\n");
-    DPRINT1("SourceProcess = 0x%p ; TargetProcess = 0x%p\n", SourceProcess, TargetProcess);
-
     /* An empty target process is invalid */
-    if (!TargetProcess)
-        return STATUS_INVALID_PARAMETER;
-
-    DPRINT1("ConsoleNewProcess - OK\n");
+    if (!TargetProcess) return STATUS_INVALID_PARAMETER;
 
     TargetProcessData = ConsoleGetPerProcessData(TargetProcess);
-    DPRINT1("TargetProcessData = 0x%p\n", TargetProcessData);
 
     /**** HACK !!!! ****/ RtlZeroMemory(TargetProcessData, sizeof(*TargetProcessData));
 
@@ -495,15 +615,12 @@ ConsoleNewProcess(PCSR_PROCESS SourceProcess,
     TargetProcessData->HandleTableSize = 0;
     TargetProcessData->HandleTable = NULL;
 
-    /**** HACK !!!! ****/ RtlZeroMemory(&TargetProcessData->HandleTableLock, sizeof(RTL_CRITICAL_SECTION));
     RtlInitializeCriticalSection(&TargetProcessData->HandleTableLock);
 
     /* Do nothing if the source process is NULL */
-    if (!SourceProcess)
-        return STATUS_SUCCESS;
+    if (!SourceProcess) return STATUS_SUCCESS;
 
     SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
-    DPRINT1("SourceProcessData = 0x%p\n", SourceProcessData);
 
     /*
      * If both of the processes (parent and new child) are console applications,
@@ -514,28 +631,21 @@ ConsoleNewProcess(PCSR_PROCESS SourceProcess,
     {
         NTSTATUS Status;
 
-        Status = Win32CsrInheritHandlesTable(SourceProcessData, TargetProcessData);
-        if (!NT_SUCCESS(Status))
-        {
-            return Status;
-        }
+        Status = ConSrvInheritHandlesTable(SourceProcessData, TargetProcessData);
+        if (!NT_SUCCESS(Status)) return Status;
 
-        /* Temporary "inherit" the console from the parent */
+        /* Temporary save the parent's console */
         TargetProcessData->ParentConsole = SourceProcessData->Console;
     }
-    else
-    {
-        DPRINT1("ConsoleNewProcess - We don't launch a Console process : SourceProcessData->Console = 0x%p ; TargetProcess->Flags = %lu\n", SourceProcessData->Console, TargetProcess->Flags);
-    }
 
     return STATUS_SUCCESS;
 }
 
 NTSTATUS
 NTAPI
-ConsoleConnect(IN PCSR_PROCESS CsrProcess,
-               IN OUT PVOID ConnectionInfo,
-               IN OUT PULONG ConnectionInfoLength)
+ConSrvConnect(IN PCSR_PROCESS CsrProcess,
+              IN OUT PVOID ConnectionInfo,
+              IN OUT PULONG ConnectionInfoLength)
 {
     /**************************************************************************
      * This function is called whenever a CUI new process is created.
@@ -545,8 +655,6 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
     PCONSOLE_CONNECTION_INFO ConnectInfo = (PCONSOLE_CONNECTION_INFO)ConnectionInfo;
     PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
 
-    DPRINT1("ConsoleConnect\n");
-
     if ( ConnectionInfo       == NULL ||
          ConnectionInfoLength == NULL ||
         *ConnectionInfoLength != sizeof(CONSOLE_CONNECTION_INFO) )
@@ -558,7 +666,6 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
     /* If we don't need a console, then get out of here */
     if (!ConnectInfo->ConsoleNeeded || !ProcessData->ConsoleApp) // In fact, it is for GUI apps.
     {
-        DPRINT("ConsoleConnect - No console needed\n");
         return STATUS_SUCCESS;
     }
 
@@ -566,10 +673,10 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
     if (!ConnectInfo->Console ||
          ConnectInfo->Console != ProcessData->ParentConsole)
     {
-        DPRINT1("ConsoleConnect - Allocate a new console\n");
+        DPRINT1("ConSrvConnect - Allocate a new console\n");
 
         /*
-         * We are about to create a new console. However when ConsoleNewProcess
+         * We are about to create a new console. However when ConSrvNewProcess
          * 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
@@ -578,15 +685,15 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
          * Therefore, free the console we can have and our handles table,
          * and recreate a new one later on.
          */
-        Win32CsrReleaseConsole(ProcessData);
+        ConSrvRemoveConsole(ProcessData);
 
         /* Initialize a new Console owned by the Console Leader Process */
-        Status = Win32CsrAllocateConsole(ProcessData,
-                                         &ConnectInfo->InputHandle,
-                                         &ConnectInfo->OutputHandle,
-                                         &ConnectInfo->ErrorHandle,
-                                         ConnectInfo->ShowCmd,
-                                         CsrProcess);
+        Status = ConSrvAllocateConsole(ProcessData,
+                                       ConnectInfo->AppPath,
+                                       &ConnectInfo->InputHandle,
+                                       &ConnectInfo->OutputHandle,
+                                       &ConnectInfo->ErrorHandle,
+                                       &ConnectInfo->ConsoleStartInfo);
         if (!NT_SUCCESS(Status))
         {
             DPRINT1("Console allocation failed\n");
@@ -595,30 +702,20 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
     }
     else /* We inherit it from the parent */
     {
-        DPRINT1("ConsoleConnect - Reuse current (parent's) console\n");
+        DPRINT1("ConSrvConnect - Reuse current (parent's) console\n");
 
         /* Reuse our current console */
-        ProcessData->Console = ConnectInfo->Console;
-    }
-
-    /* Add a reference count because the process is tied to the console */
-    _InterlockedIncrement(&ProcessData->Console->ReferenceCount);
-
-    /* Insert the process into the processes list of the console */
-    InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
-
-    /// TODO: Move this up ?
-    /* Duplicate the Event */
-    Status = NtDuplicateObject(NtCurrentProcess(),
-                               ProcessData->Console->InputBuffer.ActiveEvent,
-                               ProcessData->Process->ProcessHandle,
-                               &ProcessData->ConsoleEvent,
-                               EVENT_ALL_ACCESS, 0, 0);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
-        Win32CsrReleaseConsole(ProcessData);
-        return Status;
+        Status = ConSrvInheritConsole(ProcessData,
+                                      ConnectInfo->Console,
+                                      FALSE,
+                                      NULL,  // &ConnectInfo->InputHandle,
+                                      NULL,  // &ConnectInfo->OutputHandle,
+                                      NULL); // &ConnectInfo->ErrorHandle);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Console inheritance failed\n");
+            return Status;
+        }
     }
 
     /* Return it to the caller */
@@ -627,16 +724,18 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
     /* Input Wait Handle */
     ConnectInfo->InputWaitHandle = ProcessData->ConsoleEvent;
 
+    /* Set the Property Dialog Handler */
+    ProcessData->PropDispatcher = ConnectInfo->PropDispatcher;
+
     /* Set the Ctrl Dispatcher */
     ProcessData->CtrlDispatcher = ConnectInfo->CtrlDispatcher;
-    DPRINT("CONSRV: CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
 
     return STATUS_SUCCESS;
 }
 
 VOID
-WINAPI
-ConsoleDisconnect(PCSR_PROCESS Process)
+NTAPI
+ConSrvDisconnect(PCSR_PROCESS Process)
 {
     PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(Process);
 
@@ -644,12 +743,13 @@ ConsoleDisconnect(PCSR_PROCESS Process)
      * This function is called whenever a new process (GUI or CUI) is destroyed.
      **************************************************************************/
 
-    DPRINT1("ConsoleDisconnect called\n");
+    DPRINT1("ConSrvDisconnect\n");
+
     if ( ProcessData->Console     != NULL ||
          ProcessData->HandleTable != NULL )
     {
-        DPRINT1("ConsoleDisconnect - calling Win32CsrReleaseConsole\n");
-        Win32CsrReleaseConsole(ProcessData);
+        DPRINT1("ConSrvDisconnect - calling ConSrvRemoveConsole\n");
+        ConSrvRemoveConsole(ProcessData);
     }
 
     RtlDeleteCriticalSection(&ProcessData->HandleTableLock);
@@ -661,7 +761,7 @@ CSR_API(SrvCloseHandle)
 {
     PCONSOLE_CLOSEHANDLE CloseHandleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CloseHandleRequest;
 
-    return Win32CsrReleaseObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
+    return ConSrvRemoveObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
                                  CloseHandleRequest->ConsoleHandle);
 }
 
@@ -679,7 +779,7 @@ CSR_API(SrvVerifyConsoleIoHandle)
         Index >= ProcessData->HandleTableSize ||
         ProcessData->HandleTable[Index].Object == NULL)
     {
-        DPRINT("CsrVerifyObject failed\n");
+        DPRINT("SrvVerifyConsoleIoHandle failed\n");
         Status = STATUS_INVALID_HANDLE;
     }
 
@@ -716,7 +816,7 @@ CSR_API(SrvDuplicateHandle)
     {
         DesiredAccess = DuplicateHandleRequest->Access;
         /* Make sure the source handle has all the desired flags */
-        if (~Entry->Access & DesiredAccess)
+        if ((Entry->Access & DesiredAccess) == 0)
         {
             DPRINT1("Handle %p only has access %X; requested %X\n",
                 ConsoleHandle, Entry->Access, DesiredAccess);
@@ -725,32 +825,20 @@ CSR_API(SrvDuplicateHandle)
         }
     }
 
-    ApiMessage->Status = Win32CsrInsertObject(ProcessData,
-                                              &DuplicateHandleRequest->ConsoleHandle, // Use the new handle value!
-                                              Entry->Object,
-                                              DesiredAccess,
-                                              DuplicateHandleRequest->Inheritable,
-                                              Entry->ShareMode);
+    ApiMessage->Status = ConSrvInsertObject(ProcessData,
+                                            &DuplicateHandleRequest->ConsoleHandle, // Use the new handle value!
+                                            Entry->Object,
+                                            DesiredAccess,
+                                            DuplicateHandleRequest->Inheritable,
+                                            Entry->ShareMode);
     if (NT_SUCCESS(ApiMessage->Status) &&
         DuplicateHandleRequest->Options & DUPLICATE_CLOSE_SOURCE)
     {
-        Win32CsrCloseHandleEntry(Entry);
+        ConSrvCloseHandleEntry(Entry);
     }
 
     RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
     return ApiMessage->Status;
 }
 
-/**
-CSR_API(CsrGetInputWaitHandle)
-{
-    PCSRSS_GET_INPUT_WAIT_HANDLE GetConsoleInputWaitHandle = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetConsoleInputWaitHandle;
-
-    GetConsoleInputWaitHandle->InputWaitHandle =
-        ConsoleGetPerProcessData(CsrGetClientThread()->Process)->ConsoleEvent;
-
-    return STATUS_SUCCESS;
-}
-**/
-
 /* EOF */