Ejemplo n.º 1
0
NTSTATUS NTAPI
ConDrvSetConsoleActiveScreenBuffer(IN PCONSOLE Console,
                                   IN PCONSOLE_SCREEN_BUFFER Buffer)
{
    if (Console == NULL || Buffer == NULL)
        return STATUS_INVALID_PARAMETER;

    /* Validity check */
    ASSERT(Console == Buffer->Header.Console);

    if (Buffer == Console->ActiveBuffer) return STATUS_SUCCESS;

    /* If old buffer has no handles, it's now unreferenced */
    if (Console->ActiveBuffer->Header.ReferenceCount == 0)
    {
        ConDrvDeleteScreenBuffer(Console->ActiveBuffer);
    }

    /* Tie console to new buffer and signal the change to the frontend */
    ConioSetActiveScreenBuffer(Buffer);

    return STATUS_SUCCESS;
}
Ejemplo n.º 2
0
static VOID
ConSrvCloseHandle(IN PCONSOLE_IO_HANDLE Handle)
{
    PCONSOLE_IO_OBJECT Object = Handle->Object;
    if (Object != NULL)
    {
        /*
         * If this is a input handle, notify and dereference
         * all the waits related to this handle.
         */
        if (Object->Type == INPUT_BUFFER)
        {
            // PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object;
            PCONSOLE Console = Object->Console;

            /*
             * 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(&Console->ReadWaitQueue,
                          TRUE,
                          NULL,
                          (PVOID)Handle);
            if (!IsListEmpty(&Console->ReadWaitQueue))
            {
                CsrDereferenceWait(&Console->ReadWaitQueue);
            }
        }

        /* If the last handle to a screen buffer is closed, delete it... */
        if (AdjustHandleCounts(Handle, -1) == 0)
        {
            if (Object->Type == TEXTMODE_BUFFER || Object->Type == GRAPHICS_BUFFER)
            {
                PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object;
                /* ...unless it's the only buffer left. Windows allows deletion
                 * even of the last buffer, but having to deal with a lack of
                 * any active buffer might be error-prone. */
                if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink)
                    ConDrvDeleteScreenBuffer(Buffer);
            }
            else if (Object->Type == INPUT_BUFFER)
            {
                DPRINT("Closing the input buffer\n");
            }
            else
            {
                DPRINT1("Invalid object type %d\n", Object->Type);
            }
        }

        /* Invalidate (zero-out) this handle entry */
        // Handle->Object = NULL;
        // RtlZeroMemory(Handle, sizeof(*Handle));
    }
    RtlZeroMemory(Handle, sizeof(*Handle)); // Be sure the whole entry is invalidated.
}
Ejemplo n.º 3
0
VOID NTAPI
ConDrvDeleteConsole(IN PCONSOLE Console)
{
    DPRINT("ConDrvDeleteConsole(0x%p)\n", Console);

    /*
     * Forbid validation of any console by other threads
     * during the deletion of this console.
     */
    ConDrvLockConsoleListExclusive();

    /*
     * If the console is already being destroyed, i.e. not running
     * or finishing to be initialized, just return.
     */
    if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE) &&
        !ConDrvValidateConsoleUnsafe(Console, CONSOLE_INITIALIZING, TRUE))
    {
        /* Unlock the console list and return */
        ConDrvUnlockConsoleList();
        return;
    }

    /*
     * We are about to be destroyed. Signal it to other people
     * so that they can terminate what they are doing, and that
     * they cannot longer validate the console.
     */
    Console->State = CONSOLE_TERMINATING;

    /*
     * Allow other threads to finish their job: basically, unlock
     * all other calls to EnterCriticalSection(&Console->Lock); by
     * 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.
     */
    LeaveCriticalSection(&Console->Lock);
    ConDrvUnlockConsoleList();

    /* Deregister the terminal */
    DPRINT("Deregister terminal\n");
    ConDrvDetachTerminal(Console);
    DPRINT("Terminal deregistered\n");

    /***
     * Check that the console is in terminating state before continuing
     * (the cleanup code must not change the state of the console...
     * ...unless to cancel console deletion ?).
     ***/

    ConDrvLockConsoleListExclusive();

    if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_TERMINATING, TRUE))
    {
        ConDrvUnlockConsoleList();
        return;
    }

    /* We are now in destruction */
    Console->State = CONSOLE_IN_DESTRUCTION;

    /* We really delete the console. Reset the count to be sure. */
    Console->ReferenceCount = 0;

    /* Remove the console from the list */
    RemoveConsole(Console);

    /* Delete the last screen buffer */
    ConDrvDeleteScreenBuffer(Console->ActiveBuffer);
    Console->ActiveBuffer = NULL;
    if (!IsListEmpty(&Console->BufferList))
    {
        /***ConDrvUnlockConsoleList();***/
        ASSERTMSG("BUGBUGBUG!! screen buffer list not empty\n", FALSE);
    }

    /* Deinitialize the input buffer */
    ConDrvDeinitInputBuffer(Console);

    if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);

    DPRINT("ConDrvDeleteConsole - Unlocking\n");
    LeaveCriticalSection(&Console->Lock);
    DPRINT("ConDrvDeleteConsole - Destroying lock\n");
    DeleteCriticalSection(&Console->Lock);
    DPRINT("ConDrvDeleteConsole - Lock destroyed ; freeing console\n");

    ConsoleFreeHeap(Console);
    DPRINT("ConDrvDeleteConsole - Console destroyed\n");

    /* Unlock the console list and return */
    ConDrvUnlockConsoleList();
}