[CONSRV] Use NtClearEvent() and NtClose() instead of the Win32 functions.
[reactos.git] / win32ss / user / winsrv / consrv / condrv / console.c
index 47c1e2a..e763a81 100644 (file)
@@ -6,26 +6,24 @@
  * PROGRAMMERS:     Gé van Geldorp
  *                  Jeffrey Morlan
  *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
+ *                  Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
  */
 
 /* INCLUDES *******************************************************************/
 
 #include <consrv.h>
-
-#include <alias.h>
 #include <coninput.h>
+#include "../../concfg/font.h"
 
 #define NDEBUG
 #include <debug.h>
 
-// FIXME: Add this prototype to winternl.h / rtlfuncs.h / ...
-NTSTATUS NTAPI RtlGetLastNtStatus(VOID);
-
-
 /* GLOBALS ********************************************************************/
 
-static ULONG ConsoleListSize;
-static PCONSOLE* ConsoleList;   /* The list of all the allocated consoles */
+static ULONG CurrentConsoleID = 0;
+
+/* Linked list of consoles */
+static LIST_ENTRY ConDrvConsoleList;
 static RTL_RESOURCE ListLock;
 
 #define ConDrvLockConsoleListExclusive()    \
@@ -37,249 +35,68 @@ static RTL_RESOURCE ListLock;
 #define ConDrvUnlockConsoleList()           \
     RtlReleaseResource(&ListLock)
 
-// Adapted from reactos/lib/rtl/unicode.c, RtlCreateUnicodeString line 2180
-static BOOLEAN
-ConsoleCreateUnicodeString(IN OUT PUNICODE_STRING UniDest,
-                           IN PCWSTR Source)
-{
-    SIZE_T Size = (wcslen(Source) + 1) * sizeof(WCHAR);
-    if (Size > MAXUSHORT) return FALSE;
-
-    UniDest->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size);
-    if (UniDest->Buffer == NULL) return FALSE;
-
-    RtlCopyMemory(UniDest->Buffer, Source, Size);
-    UniDest->MaximumLength = (USHORT)Size;
-    UniDest->Length = (USHORT)Size - sizeof(WCHAR);
-
-    return TRUE;
-}
-
-// Adapted from reactos/lib/rtl/unicode.c, RtlFreeUnicodeString line 431
-static VOID
-ConsoleFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
-{
-    if (UnicodeString->Buffer)
-    {
-        ConsoleFreeHeap(UnicodeString->Buffer);
-        RtlZeroMemory(UnicodeString, sizeof(UNICODE_STRING));
-    }
-}
-
 
 static NTSTATUS
-InsertConsole(OUT PHANDLE Handle,
-              IN PCONSOLE Console)
+ConDrvInsertConsole(IN PCONSOLE Console)
 {
-#define CONSOLE_HANDLES_INCREMENT   2 * 3
-
-    NTSTATUS Status = STATUS_SUCCESS;
-    ULONG i = 0;
-    PCONSOLE* Block;
-
-    ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
-            (ConsoleList != NULL && ConsoleListSize != 0) );
+    ASSERT(Console);
 
     /* All went right, so add the console to the list */
     ConDrvLockConsoleListExclusive();
-    DPRINT1("Insert in the list\n");
-
-    if (ConsoleList)
-    {
-        for (i = 0; i < ConsoleListSize; i++)
-        {
-            if (ConsoleList[i] == NULL) break;
-        }
-    }
-
-    if (i >= ConsoleListSize)
-    {
-        DPRINT1("Creation of a new handles table\n");
-        /* Allocate a new handles table */
-        Block = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
-                                 (ConsoleListSize +
-                                    CONSOLE_HANDLES_INCREMENT) * sizeof(PCONSOLE));
-        if (Block == NULL)
-        {
-            Status = STATUS_UNSUCCESSFUL;
-            goto Quit;
-        }
-
-        /* If we previously had a handles table, free it and use the new one */
-        if (ConsoleList)
-        {
-            /* Copy the handles from the old table to the new one */
-            RtlCopyMemory(Block,
-                          ConsoleList,
-                          ConsoleListSize * sizeof(PCONSOLE));
-            ConsoleFreeHeap(ConsoleList);
-        }
-        ConsoleList = Block;
-        ConsoleListSize += CONSOLE_HANDLES_INCREMENT;
-    }
-
-    ConsoleList[i] = Console;
-    *Handle = ULongToHandle((i << 2) | 0x3);
-
-Quit:
-    /* Unlock the console list and return status */
-    ConDrvUnlockConsoleList();
-    return Status;
-}
-
-/* Unused */
-#if 0
-static NTSTATUS
-RemoveConsoleByHandle(IN HANDLE Handle)
-{
-    NTSTATUS Status = STATUS_SUCCESS;
-    PCONSOLE Console;
-
-    BOOLEAN ValidHandle = ((HandleToULong(Handle) & 0x3) == 0x3);
-    ULONG Index = HandleToULong(Handle) >> 2;
-
-    if (!ValidHandle) return STATUS_INVALID_HANDLE;
-
-    ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
-            (ConsoleList != NULL && ConsoleListSize != 0) );
-
-    /* Remove the console from the list */
-    ConDrvLockConsoleListExclusive();
 
-    if (Index >= ConsoleListSize ||
-        (Console = ConsoleList[Index]) == NULL)
-    {
-        Status = STATUS_INVALID_HANDLE;
-        goto Quit;
-    }
+    DPRINT("Insert in the list\n");
+    InsertTailList(&ConDrvConsoleList, &Console->ListEntry);
 
-    ConsoleList[Index] = NULL;
+    // FIXME: Move this code to the caller function!!
+    /* Get a new console ID */
+    _InterlockedExchange((PLONG)&Console->ConsoleID, CurrentConsoleID);
+    _InterlockedIncrement((PLONG)&CurrentConsoleID);
 
-Quit:
-    /* Unlock the console list and return status */
+    /* Unlock the console list and return success */
     ConDrvUnlockConsoleList();
-    return Status;
+    return STATUS_SUCCESS;
 }
-#endif
 
 static NTSTATUS
-RemoveConsoleByPointer(IN PCONSOLE Console)
+RemoveConsole(IN PCONSOLE Console)
 {
-    ULONG i = 0;
-
+    // ASSERT(Console);
     if (!Console) return STATUS_INVALID_PARAMETER;
 
-    ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
-            (ConsoleList != NULL && ConsoleListSize != 0) );
-
     /* Remove the console from the list */
     ConDrvLockConsoleListExclusive();
 
-    if (ConsoleList)
-    {
-        for (i = 0; i < ConsoleListSize; i++)
-        {
-            if (ConsoleList[i] == Console) ConsoleList[i] = NULL;
-        }
-    }
+    RemoveEntryList(&Console->ListEntry);
 
-    /* Unlock the console list */
+    /* Unlock the console list and return success */
     ConDrvUnlockConsoleList();
-
     return STATUS_SUCCESS;
 }
 
 
-/* For resetting the frontend - defined in dummyfrontend.c */
-VOID ResetFrontEnd(IN PCONSOLE Console);
-
-
 /* PRIVATE FUNCTIONS **********************************************************/
 
-static NTSTATUS
-ConDrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
-                              IN PCONSOLE_PROCESS_DATA ProcessData,
-                              IN ULONG Timeout)
-{
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    DPRINT("ConDrvConsoleCtrlEventTimeout Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
-
-    if (ProcessData->CtrlDispatcher)
-    {
-        _SEH2_TRY
-        {
-            HANDLE Thread = NULL;
-
-            _SEH2_TRY
-            {
-                Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
-                                            ProcessData->CtrlDispatcher,
-                                            UlongToPtr(CtrlEvent), 0, NULL);
-                if (NULL == Thread)
-                {
-                    Status = RtlGetLastNtStatus();
-                    DPRINT1("Failed thread creation, Status = 0x%08lx\n", Status);
-                }
-                else
-                {
-                    DPRINT("ProcessData->CtrlDispatcher remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
-                    WaitForSingleObject(Thread, Timeout);
-                }
-            }
-            _SEH2_FINALLY
-            {
-                CloseHandle(Thread);
-            }
-            _SEH2_END;
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            Status = _SEH2_GetExceptionCode();
-            DPRINT1("ConDrvConsoleCtrlEventTimeout - Caught an exception, Status = 0x%08lx\n", Status);
-        }
-        _SEH2_END;
-    }
-
-    return Status;
-}
-
-NTSTATUS
-ConDrvConsoleCtrlEvent(IN ULONG CtrlEvent,
-                       IN PCONSOLE_PROCESS_DATA ProcessData)
+VOID NTAPI
+ConDrvPause(PCONSOLE Console)
 {
-    return ConDrvConsoleCtrlEventTimeout(CtrlEvent, ProcessData, 0);
-}
+    /* In case we already have a pause event, just exit... */
+    if (Console->UnpauseEvent) return;
 
-VOID FASTCALL
-ConioPause(PCONSOLE Console, UINT Flags)
-{
-    Console->PauseFlags |= Flags;
-    if (!Console->UnpauseEvent)
-        Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+    /* ... otherwise create it */
+    NtCreateEvent(&Console->UnpauseEvent, EVENT_ALL_ACCESS,
+                  NULL, NotificationEvent, FALSE);
 }
 
-VOID FASTCALL
-ConioUnpause(PCONSOLE Console, UINT Flags)
+VOID NTAPI
+ConDrvUnpause(PCONSOLE Console)
 {
-    Console->PauseFlags &= ~Flags;
+    /* In case we already freed the event, just exit... */
+    if (!Console->UnpauseEvent) return;
 
-    // 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,
-                      TRUE,
-                      NULL,
-                      NULL);
-        if (!IsListEmpty(&Console->WriteWaitQueue))
-        {
-            CsrDereferenceWait(&Console->WriteWaitQueue);
-        }
-    }
+    /* ... otherwise set and free it */
+    NtSetEvent(Console->UnpauseEvent, NULL);
+    NtClose(Console->UnpauseEvent);
+    Console->UnpauseEvent = NULL;
 }
 
 
@@ -326,103 +143,6 @@ ConDrvValidateConsoleUnsafe(IN PCONSOLE Console,
     return TRUE;
 }
 
-BOOLEAN NTAPI
-ConDrvValidateConsole(OUT PCONSOLE* Console,
-                      IN HANDLE ConsoleHandle,
-                      IN CONSOLE_STATE ExpectedState,
-                      IN BOOLEAN LockConsole)
-{
-    BOOLEAN RetVal = FALSE;
-    PCONSOLE ValidatedConsole;
-
-    BOOLEAN ValidHandle = ((HandleToULong(ConsoleHandle) & 0x3) == 0x3);
-    ULONG Index = HandleToULong(ConsoleHandle) >> 2;
-
-    if (!ValidHandle) return FALSE;
-
-    if (!Console) return FALSE;
-    *Console = NULL;
-
-    /*
-     * Forbid creation or deletion of consoles when
-     * checking for the existence of a console.
-     */
-    ConDrvLockConsoleListShared();
-
-    if (Index >= ConsoleListSize ||
-        (ValidatedConsole = ConsoleList[Index]) == NULL)
-    {
-        /* Unlock the console list */
-        ConDrvUnlockConsoleList();
-
-        return FALSE;
-    }
-
-    ValidatedConsole = ConsoleList[Index];
-
-    /* Unlock the console list and return */
-    ConDrvUnlockConsoleList();
-
-    RetVal = ConDrvValidateConsoleUnsafe(ValidatedConsole,
-                                         ExpectedState,
-                                         LockConsole);
-    if (RetVal) *Console = ValidatedConsole;
-
-    return RetVal;
-}
-
-NTSTATUS NTAPI
-ConDrvGetConsole(OUT PCONSOLE* Console,
-                 IN HANDLE ConsoleHandle,
-                 IN BOOLEAN LockConsole)
-{
-    NTSTATUS Status = STATUS_INVALID_HANDLE;
-    PCONSOLE GrabConsole;
-
-    if (Console == NULL) return STATUS_INVALID_PARAMETER;
-    *Console = NULL;
-
-    if (ConDrvValidateConsole(&GrabConsole,
-                              ConsoleHandle,
-                              CONSOLE_RUNNING,
-                              LockConsole))
-    {
-        InterlockedIncrement(&GrabConsole->ReferenceCount);
-        *Console = GrabConsole;
-        Status = STATUS_SUCCESS;
-    }
-
-    return Status;
-}
-
-VOID NTAPI
-ConDrvReleaseConsole(IN PCONSOLE Console,
-                     IN BOOLEAN WasConsoleLocked)
-{
-    LONG RefCount = 0;
-
-    if (!Console) return;
-    // if (Console->ReferenceCount == 0) return; // This shouldn't happen
-    ASSERT(Console->ReferenceCount > 0);
-
-    /* The console must be locked */
-    // ASSERT(Console_locked);
-
-    /*
-     * Decrement the reference count. Save the new value too,
-     * because Console->ReferenceCount might be modified after
-     * the console gets unlocked but before we check whether we
-     * can destroy it.
-     */
-    RefCount = _InterlockedDecrement(&Console->ReferenceCount);
-
-    /* Unlock the console if needed */
-    if (WasConsoleLocked) LeaveCriticalSection(&Console->Lock);
-
-    /* Delete the console if needed */
-    if (RefCount <= 0) ConDrvDeleteConsole(Console);
-}
-
 
 /* CONSOLE INITIALIZATION FUNCTIONS *******************************************/
 
@@ -432,38 +152,32 @@ ConDrvInitConsoleSupport(VOID)
     DPRINT("CONSRV: ConDrvInitConsoleSupport()\n");
 
     /* Initialize the console list and its lock */
-    ConsoleListSize = 0;
-    ConsoleList = NULL;
+    InitializeListHead(&ConDrvConsoleList);
     RtlInitializeResource(&ListLock);
-
-    /* Should call LoadKeyboardLayout */
 }
 
+/* For resetting the terminal - defined in dummyterm.c */
+VOID ResetTerminal(IN PCONSOLE Console);
+
 NTSTATUS NTAPI
-ConDrvInitConsole(OUT PHANDLE NewConsoleHandle,
-                  OUT PCONSOLE* NewConsole,
-                  IN PCONSOLE_INFO ConsoleInfo,
-                  IN ULONG ConsoleLeaderProcessId)
+ConDrvInitConsole(OUT PCONSOLE* NewConsole,
+                  IN PCONSOLE_INFO ConsoleInfo)
 {
     NTSTATUS Status;
-    SECURITY_ATTRIBUTES SecurityAttributes;
     // CONSOLE_INFO CapturedConsoleInfo;
     TEXTMODE_BUFFER_INFO ScreenBufferInfo;
-    HANDLE ConsoleHandle;
     PCONSOLE Console;
     PCONSOLE_SCREEN_BUFFER NewBuffer;
-    // WCHAR DefaultTitle[128];
 
-    if (NewConsoleHandle == NULL || NewConsole == NULL || ConsoleInfo == NULL)
+    if (NewConsole == NULL || ConsoleInfo == NULL)
         return STATUS_INVALID_PARAMETER;
 
-    *NewConsoleHandle = NULL;
     *NewConsole = NULL;
 
     /*
-     * Allocate a console structure
+     * Allocate a new console
      */
-    Console = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(CONSOLE));
+    Console = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(*Console));
     if (NULL == Console)
     {
         DPRINT1("Not enough memory for console creation.\n");
@@ -471,58 +185,11 @@ ConDrvInitConsole(OUT PHANDLE NewConsoleHandle,
     }
 
     /*
-     * Load the console settings
-     */
-
-    /* 1. Load the default settings */
-    // ConSrvGetDefaultSettings(ConsoleInfo, ProcessId);
-
-    // /* 2. Get the title of the console (initialize ConsoleInfo.ConsoleTitle) */
-    // Length = min(wcslen(ConsoleStartInfo->ConsoleTitle),
-                 // sizeof(ConsoleInfo.ConsoleTitle) / sizeof(ConsoleInfo.ConsoleTitle[0]) - 1);
-    // wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleStartInfo->ConsoleTitle, Length);
-    // ConsoleInfo.ConsoleTitle[Length] = L'\0';
-
-    /*
-     * 4. Load the remaining console settings via the registry.
-     */
-#if 0
-    if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
-    {
-        /*
-         * Either we weren't created by an app launched via a shell-link,
-         * or we failed to load shell-link console properties.
-         * Therefore, load the console infos for the application from the registry.
-         */
-        ConSrvReadUserSettings(ConsoleInfo, ProcessId);
-
-        /*
-         * Now, update them with the properties the user might gave to us
-         * via the STARTUPINFO structure before calling CreateProcess
-         * (and which was transmitted via the ConsoleStartInfo structure).
-         * We therefore overwrite the values read in the registry.
-         */
-        if (ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE)
-        {
-            ConsoleInfo->ScreenAttrib = (USHORT)ConsoleStartInfo->FillAttribute;
-        }
-        if (ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS)
-        {
-            ConsoleInfo->ScreenBufferSize = ConsoleStartInfo->ScreenBufferSize;
-        }
-        if (ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE)
-        {
-            // ConsoleInfo->ConsoleSize = ConsoleStartInfo->ConsoleWindowSize;
-            ConsoleInfo->ConsoleSize.X = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cx;
-            ConsoleInfo->ConsoleSize.Y = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cy;
-        }
-    }
-#endif
-
-    /*
-     * Fix the screen buffer size if needed. The rule is:
-     * ScreenBufferSize >= ConsoleSize
+     * Set and fix the screen buffer size if needed.
+     * The rule is: ScreenBufferSize >= ConsoleSize
      */
+    if (ConsoleInfo->ScreenBufferSize.X == 0) ConsoleInfo->ScreenBufferSize.X = 1;
+    if (ConsoleInfo->ScreenBufferSize.Y == 0) ConsoleInfo->ScreenBufferSize.Y = 1;
     if (ConsoleInfo->ScreenBufferSize.X < ConsoleInfo->ConsoleSize.X)
         ConsoleInfo->ScreenBufferSize.X = ConsoleInfo->ConsoleSize.X;
     if (ConsoleInfo->ScreenBufferSize.Y < ConsoleInfo->ConsoleSize.Y)
@@ -534,110 +201,59 @@ ConDrvInitConsole(OUT PHANDLE NewConsoleHandle,
     Console->State = CONSOLE_INITIALIZING;
     Console->ReferenceCount = 0;
     InitializeCriticalSection(&Console->Lock);
-    InitializeListHead(&Console->ProcessList);
-    Console->NotifiedLastCloseProcess = NULL;
-    Console->NotifyLastClose = FALSE;
 
-    /* Initialize the frontend interface */
-    ResetFrontEnd(Console);
+    /* Initialize the terminal interface */
+    ResetTerminal(Console);
 
-    memcpy(Console->Colors, ConsoleInfo->Colors, sizeof(ConsoleInfo->Colors));
     Console->ConsoleSize = ConsoleInfo->ConsoleSize;
-    Console->FixedSize   = FALSE; // Value by default; is reseted by the front-ends if needed.
-
-    /*
-     * Initialize the input buffer
-     */
-    ConSrvInitObject(&Console->InputBuffer.Header, INPUT_BUFFER, Console);
+    Console->FixedSize   = FALSE; // Value by default; is reseted by the terminals if needed.
 
-    SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
-    SecurityAttributes.lpSecurityDescriptor = NULL;
-    SecurityAttributes.bInheritHandle = TRUE;
-    Console->InputBuffer.ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL);
-    if (NULL == Console->InputBuffer.ActiveEvent)
+    /* Initialize the input buffer */
+    Status = ConDrvInitInputBuffer(Console, 0 /* ConsoleInfo->InputBufferSize */);
+    if (!NT_SUCCESS(Status))
     {
+        DPRINT1("ConDrvInitInputBuffer: failed, Status = 0x%08lx\n", Status);
         DeleteCriticalSection(&Console->Lock);
         ConsoleFreeHeap(Console);
-        return STATUS_UNSUCCESSFUL;
+        return Status;
     }
 
-    Console->InputBuffer.InputBufferSize = 0; // FIXME!
-    InitializeListHead(&Console->InputBuffer.InputEvents);
-    InitializeListHead(&Console->InputBuffer.ReadWaitQueue);
-    Console->InputBuffer.Mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
-                                ENABLE_ECHO_INPUT      | ENABLE_MOUSE_INPUT;
-
-    Console->QuickEdit  = ConsoleInfo->QuickEdit;
-    Console->InsertMode = ConsoleInfo->InsertMode;
-    Console->LineBuffer = NULL;
-    Console->LineMaxSize = Console->LineSize = Console->LinePos = 0;
-    Console->LineComplete = Console->LineUpPressed = FALSE;
-    Console->LineInsertToggle = Console->InsertMode;
-    // LineWakeupMask
-
     /* Set-up the code page */
-    Console->CodePage = Console->OutputCodePage = ConsoleInfo->CodePage;
+    if (IsValidCodePage(ConsoleInfo->CodePage))
+        Console->InputCodePage = Console->OutputCodePage = ConsoleInfo->CodePage;
+
+    Console->IsCJK = IsCJKCodePage(Console->OutputCodePage);
 
     /* Initialize a new text-mode screen buffer with default settings */
     ScreenBufferInfo.ScreenBufferSize = ConsoleInfo->ScreenBufferSize;
+    ScreenBufferInfo.ViewSize         = ConsoleInfo->ConsoleSize;
     ScreenBufferInfo.ScreenAttrib     = ConsoleInfo->ScreenAttrib;
     ScreenBufferInfo.PopupAttrib      = ConsoleInfo->PopupAttrib;
-    ScreenBufferInfo.IsCursorVisible  = TRUE;
     ScreenBufferInfo.CursorSize       = ConsoleInfo->CursorSize;
+    ScreenBufferInfo.IsCursorVisible  = TRUE;
 
     InitializeListHead(&Console->BufferList);
     Status = ConDrvCreateScreenBuffer(&NewBuffer,
                                       Console,
+                                      NULL,
                                       CONSOLE_TEXTMODE_BUFFER,
                                       &ScreenBufferInfo);
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("ConDrvCreateScreenBuffer: failed, Status = 0x%08lx\n", Status);
-        CloseHandle(Console->InputBuffer.ActiveEvent);
+        ConDrvDeinitInputBuffer(Console);
         DeleteCriticalSection(&Console->Lock);
         ConsoleFreeHeap(Console);
         return Status;
     }
     /* Make the new screen buffer active */
     Console->ActiveBuffer = NewBuffer;
-    InitializeListHead(&Console->WriteWaitQueue);
-    Console->PauseFlags = 0;
     Console->UnpauseEvent = NULL;
 
-    /*
-     * Initialize the alias and history buffers
-     */
-    Console->Aliases = NULL;
-    InitializeListHead(&Console->HistoryBuffers);
-    Console->HistoryBufferSize      = ConsoleInfo->HistoryBufferSize;
-    Console->NumberOfHistoryBuffers = ConsoleInfo->NumberOfHistoryBuffers;
-    Console->HistoryNoDup           = ConsoleInfo->HistoryNoDup;
-
-    /* Initialize the console title */
-    ConsoleCreateUnicodeString(&Console->OriginalTitle, ConsoleInfo->ConsoleTitle);
-    // if (ConsoleInfo.ConsoleTitle[0] == L'\0')
-    // {
-        // if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, DefaultTitle, sizeof(DefaultTitle) / sizeof(DefaultTitle[0])))
-        // {
-            // ConsoleCreateUnicodeString(&Console->Title, DefaultTitle);
-        // }
-        // else
-        // {
-            // ConsoleCreateUnicodeString(&Console->Title, L"ReactOS Console");
-        // }
-    // }
-    // else
-    // {
-        ConsoleCreateUnicodeString(&Console->Title, ConsoleInfo->ConsoleTitle);
-    // }
-
-    /* Lock the console until its initialization is finished */
-    // EnterCriticalSection(&Console->Lock);
-
     DPRINT("Console initialized\n");
 
     /* All went right, so add the console to the list */
-    Status = InsertConsole(&ConsoleHandle, Console);
+    Status = ConDrvInsertConsole(Console);
     if (!NT_SUCCESS(Status))
     {
         /* Fail */
@@ -649,73 +265,66 @@ ConDrvInitConsole(OUT PHANDLE NewConsoleHandle,
     DPRINT("Change state\n");
     Console->State = CONSOLE_RUNNING;
 
-    /* Unlock the console */
-    // LeaveCriticalSection(&Console->Lock);
-
     /* Return the newly created console to the caller and a success code too */
-    *NewConsoleHandle = ConsoleHandle;
-    *NewConsole       = Console;
+    *NewConsole = Console;
     return STATUS_SUCCESS;
 }
 
 NTSTATUS NTAPI
-ConDrvRegisterFrontEnd(IN PCONSOLE Console,
-                       IN PFRONTEND FrontEnd)
+ConDrvAttachTerminal(IN PCONSOLE Console,
+                     IN PTERMINAL Terminal)
 {
     NTSTATUS Status;
 
-    if (Console == NULL || FrontEnd == NULL)
+    if (Console == NULL || Terminal == NULL)
         return STATUS_INVALID_PARAMETER;
 
     /* FIXME: Lock the console before ?? */
 
     /*
-     * Attach the frontend to the console. Use now the TermIFace of the console,
-     * and not the user-defined temporary FrontEnd pointer.
+     * Attach the terminal to the console. Use now the TermIFace of the console,
+     * and not the user-defined temporary Terminal pointer.
      */
-    Console->TermIFace = *FrontEnd;
+    Console->TermIFace = *Terminal;
     Console->TermIFace.Console = Console;
 
-    /* Initialize the frontend AFTER having attached it to the console */
-    DPRINT("Finish initialization of frontend\n");
-    Status = Console->TermIFace.Vtbl->InitFrontEnd(&Console->TermIFace, Console);
+    /* Initialize the terminal AFTER having attached it to the console */
+    DPRINT("Finish initialization of terminal\n");
+    Status = Console->TermIFace.Vtbl->InitTerminal(&Console->TermIFace, Console);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("FrontEnd initialization failed, Status = 0x%08lx\n", Status);
-
-        /* We failed, detach the frontend from the console */
-        FrontEnd->Console = NULL; // For the caller
-        ResetFrontEnd(Console);
+        DPRINT1("Terminal initialization failed, Status = 0x%08lx\n", Status);
 
+        /* We failed, detach the terminal from the console */
+        Terminal->Console = NULL; // For the caller
+        ResetTerminal(Console);
         return Status;
     }
 
     /* Copy buffer contents to screen */
-    // FrontEnd.Draw();
-    // ConioDrawConsole(Console);
-    DPRINT("Console drawn\n");
+    // Terminal.Draw();
 
-    DPRINT("Terminal FrontEnd initialization done\n");
+    DPRINT("Terminal initialization done\n");
     return STATUS_SUCCESS;
 }
 
 NTSTATUS NTAPI
-ConDrvDeregisterFrontEnd(IN PCONSOLE Console)
+ConDrvDetachTerminal(IN PCONSOLE Console)
 {
     if (Console == NULL) return STATUS_INVALID_PARAMETER;
 
     /* FIXME: Lock the console before ?? */
 
-    /* Deinitialize the frontend BEFORE detaching it from the console */
-    Console->TermIFace.Vtbl->DeinitFrontEnd(&Console->TermIFace/*, Console*/);
+    /* Deinitialize the terminal BEFORE detaching it from the console */
+    Console->TermIFace.Vtbl->DeinitTerminal(&Console->TermIFace/*, Console*/);
 
     /*
-     * Detach the frontend from the console:
-     * reinitialize the frontend interface.
+     * Detach the terminal from the console:
+     * reinitialize the terminal interface.
      */
-    ResetFrontEnd(Console);
+    ResetTerminal(Console);
 
-    DPRINT("Terminal FrontEnd unregistered\n");
+    DPRINT("Terminal unregistered\n");
     return STATUS_SUCCESS;
 }
 
@@ -752,7 +361,7 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
     /*
      * Allow other threads to finish their job: basically, unlock
      * all other calls to EnterCriticalSection(&Console->Lock); by
-     * ConDrvValidateConsole(Unsafe) functions so that they just see
+     * ConDrvValidateConsoleUnsafe functions so that they just see
      * that we are not in CONSOLE_RUNNING state anymore, or unlock
      * other concurrent calls to ConDrvDeleteConsole so that they
      * can see that we are in fact already deleting the console.
@@ -760,12 +369,10 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
     LeaveCriticalSection(&Console->Lock);
     ConDrvUnlockConsoleList();
 
-    /* FIXME: Send a terminate message to all the processes owning this console */
-
-    /* Cleanup the UI-oriented part */
-    DPRINT("Deregister console\n");
-    ConDrvDeregisterFrontEnd(Console);
-    DPRINT("Console deregistered\n");
+    /* Deregister the terminal */
+    DPRINT("Deregister terminal\n");
+    ConDrvDetachTerminal(Console);
+    DPRINT("Terminal deregistered\n");
 
     /***
      * Check that the console is in terminating state before continuing
@@ -788,29 +395,21 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
     Console->ReferenceCount = 0;
 
     /* Remove the console from the list */
-    RemoveConsoleByPointer(Console);
-
-    /* Discard all entries in the input event queue */
-    PurgeInputBuffer(Console);
-
-    if (Console->LineBuffer) ConsoleFreeHeap(Console->LineBuffer);
-
-    IntDeleteAllAliases(Console);
-    HistoryDeleteBuffers(Console);
+    RemoveConsole(Console);
 
-    ConioDeleteScreenBuffer(Console->ActiveBuffer);
+    /* Delete the last screen buffer */
+    ConDrvDeleteScreenBuffer(Console->ActiveBuffer);
     Console->ActiveBuffer = NULL;
     if (!IsListEmpty(&Console->BufferList))
     {
-        DPRINT1("BUG: screen buffer list not empty\n");
-        ASSERT(FALSE);
+        /***ConDrvUnlockConsoleList();***/
+        ASSERTMSG("BUGBUGBUG!! screen buffer list not empty\n", FALSE);
     }
 
-    /**/ CloseHandle(Console->InputBuffer.ActiveEvent); /**/
-    if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
+    /* Deinitialize the input buffer */
+    ConDrvDeinitInputBuffer(Console);
 
-    ConsoleFreeUnicodeString(&Console->OriginalTitle);
-    ConsoleFreeUnicodeString(&Console->Title);
+    if (Console->UnpauseEvent) NtClose(Console->UnpauseEvent);
 
     DPRINT("ConDrvDeleteConsole - Unlocking\n");
     LeaveCriticalSection(&Console->Lock);
@@ -846,17 +445,7 @@ ConDrvGetConsoleMode(IN PCONSOLE Console,
     if (INPUT_BUFFER == Object->Type)
     {
         PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object;
-
         *ConsoleMode = InputBuffer->Mode;
-
-        if (Console->QuickEdit || Console->InsertMode)
-        {
-            // Windows does this, even if it's not documented on MSDN
-            *ConsoleMode |= ENABLE_EXTENDED_FLAGS;
-
-            if (Console->QuickEdit ) *ConsoleMode |= ENABLE_QUICK_EDIT_MODE;
-            if (Console->InsertMode) *ConsoleMode |= ENABLE_INSERT_MODE;
-        }
     }
     else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
     {
@@ -876,8 +465,6 @@ ConDrvSetConsoleMode(IN PCONSOLE Console,
                      IN PCONSOLE_IO_OBJECT Object,
                      IN ULONG ConsoleMode)
 {
-#define CONSOLE_VALID_CONTROL_MODES ( ENABLE_EXTENDED_FLAGS   | \
-                                      ENABLE_INSERT_MODE      | ENABLE_QUICK_EDIT_MODE )
 #define CONSOLE_VALID_INPUT_MODES   ( ENABLE_PROCESSED_INPUT  | ENABLE_LINE_INPUT   | \
                                       ENABLE_ECHO_INPUT       | ENABLE_WINDOW_INPUT | \
                                       ENABLE_MOUSE_INPUT )
@@ -895,45 +482,21 @@ ConDrvSetConsoleMode(IN PCONSOLE Console,
     {
         PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object;
 
-        DPRINT("SetConsoleMode(Input, %d)\n", ConsoleMode);
-
-        /*
-         * 1. Only the presence of valid mode flags is allowed.
-         */
-        if (ConsoleMode & ~(CONSOLE_VALID_INPUT_MODES | CONSOLE_VALID_CONTROL_MODES))
-        {
-            Status = STATUS_INVALID_PARAMETER;
-            goto Quit;
-        }
-
-        /*
-         * 2. If we use control mode flags without ENABLE_EXTENDED_FLAGS,
-         *    then consider the flags invalid.
-         *
-        if ( (ConsoleMode & CONSOLE_VALID_CONTROL_MODES) &&
-             (ConsoleMode & ENABLE_EXTENDED_FLAGS) == 0 )
+        /* Only the presence of valid mode flags is allowed */
+        if (ConsoleMode & ~CONSOLE_VALID_INPUT_MODES)
         {
             Status = STATUS_INVALID_PARAMETER;
-            goto Quit;
         }
-        */
-
-        /*
-         * 3. Now we can continue.
-         */
-        if (ConsoleMode & CONSOLE_VALID_CONTROL_MODES)
+        else
         {
-            Console->QuickEdit  = !!(ConsoleMode & ENABLE_QUICK_EDIT_MODE);
-            Console->InsertMode = !!(ConsoleMode & ENABLE_INSERT_MODE);
+            InputBuffer->Mode = (ConsoleMode & CONSOLE_VALID_INPUT_MODES);
         }
-        InputBuffer->Mode = (ConsoleMode & CONSOLE_VALID_INPUT_MODES);
     }
     else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
     {
         PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object;
 
-        DPRINT("SetConsoleMode(Output, %d)\n", ConsoleMode);
-
+        /* Only the presence of valid mode flags is allowed */
         if (ConsoleMode & ~CONSOLE_VALID_OUTPUT_MODES)
         {
             Status = STATUS_INVALID_PARAMETER;
@@ -948,115 +511,9 @@ ConDrvSetConsoleMode(IN PCONSOLE Console,
         Status = STATUS_INVALID_HANDLE;
     }
 
-Quit:
     return Status;
 }
 
-NTSTATUS NTAPI
-ConDrvGetConsoleTitle(IN PCONSOLE Console,
-                      IN BOOLEAN Unicode,
-                      IN OUT PVOID TitleBuffer,
-                      IN OUT PULONG BufLength)
-{
-    ULONG Length;
-
-    if (Console == NULL || TitleBuffer == NULL || BufLength == NULL)
-        return STATUS_INVALID_PARAMETER;
-
-    /* Copy title of the console to the user title buffer */
-    if (Unicode)
-    {
-        if (*BufLength >= sizeof(WCHAR))
-        {
-            Length = min(*BufLength - sizeof(WCHAR), Console->Title.Length);
-            RtlCopyMemory(TitleBuffer, Console->Title.Buffer, Length);
-            ((PWCHAR)TitleBuffer)[Length / sizeof(WCHAR)] = L'\0';
-            *BufLength = Length;
-        }
-        else
-        {
-            *BufLength = Console->Title.Length;
-        }
-    }
-    else
-    {
-        if (*BufLength >= sizeof(CHAR))
-        {
-            Length = min(*BufLength - sizeof(CHAR), Console->Title.Length / sizeof(WCHAR));
-            Length = WideCharToMultiByte(Console->CodePage, 0,
-                                         Console->Title.Buffer, Length,
-                                         TitleBuffer, Length,
-                                         NULL, NULL);
-            ((PCHAR)TitleBuffer)[Length] = '\0';
-            *BufLength = Length;
-        }
-        else
-        {
-            *BufLength = Console->Title.Length / sizeof(WCHAR);
-        }
-    }
-
-    return STATUS_SUCCESS;
-}
-
-NTSTATUS NTAPI
-ConDrvSetConsoleTitle(IN PCONSOLE Console,
-                      IN BOOLEAN Unicode,
-                      IN PVOID TitleBuffer,
-                      IN ULONG BufLength)
-{
-    PWCHAR Buffer;
-    ULONG  Length;
-
-    if (Console == NULL || TitleBuffer == NULL)
-        return STATUS_INVALID_PARAMETER;
-
-    if (Unicode)
-    {
-        /* Length is in bytes */
-        Length = BufLength;
-    }
-    else
-    {
-        /* Use the console input CP for the conversion */
-        Length = MultiByteToWideChar(Console->CodePage, 0,
-                                     TitleBuffer, BufLength,
-                                     NULL, 0);
-        /* The returned Length was in number of wchars, convert it in bytes */
-        Length *= sizeof(WCHAR);
-    }
-
-    /* Allocate a new buffer to hold the new title (NULL-terminated) */
-    Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Length + sizeof(WCHAR));
-    if (!Buffer) return STATUS_NO_MEMORY;
-
-    /* Free the old title */
-    ConsoleFreeUnicodeString(&Console->Title);
-
-    /* Copy title to console */
-    Console->Title.Buffer = Buffer;
-    Console->Title.Length = Length;
-    Console->Title.MaximumLength = Console->Title.Length + sizeof(WCHAR);
-
-    if (Unicode)
-    {
-        RtlCopyMemory(Console->Title.Buffer, TitleBuffer, Console->Title.Length);
-    }
-    else
-    {
-        MultiByteToWideChar(Console->CodePage, 0,
-                            TitleBuffer, BufLength,
-                            Console->Title.Buffer,
-                            Console->Title.Length / sizeof(WCHAR));
-    }
-
-    /* NULL-terminate */
-    Console->Title.Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
-
-    // TermChangeTitle(Console);
-    return STATUS_SUCCESS;
-}
-
 NTSTATUS NTAPI
 ConDrvGetConsoleCP(IN PCONSOLE Console,
                    OUT PUINT CodePage,
@@ -1065,7 +522,7 @@ ConDrvGetConsoleCP(IN PCONSOLE Console,
     if (Console == NULL || CodePage == NULL)
         return STATUS_INVALID_PARAMETER;
 
-    *CodePage = (OutputCP ? Console->OutputCodePage : Console->CodePage);
+    *CodePage = (OutputCP ? Console->OutputCodePage : Console->InputCodePage);
 
     return STATUS_SUCCESS;
 }
@@ -1079,88 +536,16 @@ ConDrvSetConsoleCP(IN PCONSOLE Console,
         return STATUS_INVALID_PARAMETER;
 
     if (OutputCP)
+    {
         Console->OutputCodePage = CodePage;
+        Console->IsCJK = IsCJKCodePage(CodePage);
+    }
     else
-        Console->CodePage = CodePage;
-
-    return STATUS_SUCCESS;
-}
-
-PCONSOLE_PROCESS_DATA NTAPI
-ConDrvGetConsoleLeaderProcess(IN PCONSOLE Console)
-{
-    if (Console == NULL) return NULL;
-
-    return CONTAINING_RECORD(Console->ProcessList.Blink,
-                             CONSOLE_PROCESS_DATA,
-                             ConsoleLink);
-}
-
-NTSTATUS NTAPI
-ConDrvGetConsoleProcessList(IN PCONSOLE Console,
-                            IN OUT PULONG ProcessIdsList,
-                            IN ULONG MaxIdListItems,
-                            OUT PULONG ProcessIdsTotal)
-{
-    PCONSOLE_PROCESS_DATA current;
-    PLIST_ENTRY current_entry;
-
-    if (Console == NULL || ProcessIdsList == NULL || ProcessIdsTotal == NULL)
-        return STATUS_INVALID_PARAMETER;
-
-    *ProcessIdsTotal = 0;
-
-    for (current_entry = Console->ProcessList.Flink;
-         current_entry != &Console->ProcessList;
-         current_entry = current_entry->Flink)
     {
-        current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
-        if (++(*ProcessIdsTotal) <= MaxIdListItems)
-        {
-            *ProcessIdsList++ = HandleToUlong(current->Process->ClientId.UniqueProcess);
-        }
+        Console->InputCodePage = CodePage;
     }
 
     return STATUS_SUCCESS;
 }
 
-// ConDrvGenerateConsoleCtrlEvent
-NTSTATUS NTAPI
-ConDrvConsoleProcessCtrlEvent(IN PCONSOLE Console,
-                              IN ULONG ProcessGroupId,
-                              IN ULONG CtrlEvent)
-{
-    NTSTATUS Status = STATUS_SUCCESS;
-    PLIST_ENTRY current_entry;
-    PCONSOLE_PROCESS_DATA current;
-
-    /* If the console is already being destroyed, just return */
-    if (!ConDrvValidateConsoleState(Console, CONSOLE_RUNNING))
-        return STATUS_UNSUCCESSFUL;
-
-    /*
-     * Loop through the process list, from the most recent process
-     * (the active one) to the oldest one (the first created, i.e.
-     * the console leader process), and for each, send an event
-     * (new processes are inserted at the head of the console process list).
-     */
-    current_entry = Console->ProcessList.Flink;
-    while (current_entry != &Console->ProcessList)
-    {
-        current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
-        current_entry = current_entry->Flink;
-
-        /*
-         * Only processes belonging to the same process group are signaled.
-         * If the process group ID is zero, then all the processes are signaled.
-         */
-        if (ProcessGroupId == 0 || current->Process->ProcessGroupId == ProcessGroupId)
-        {
-            Status = ConDrvConsoleCtrlEvent(CtrlEvent, current);
-        }
-    }
-
-    return Status;
-}
-
 /* EOF */