Esempio n. 1
0
static LRESULT CALLBACK
TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
/*
    PTUI_CONSOLE_DATA TuiData = NULL;
    PCONSOLE Console = NULL;

    TuiData = TuiGetGuiData(hWnd);
    if (TuiData == NULL) return 0;
*/

    switch (msg)
    {
        case WM_CHAR:
        case WM_SYSCHAR:
        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
        case WM_KEYUP:
        case WM_SYSKEYUP:
        {
            if (ConDrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE))
            {
                MSG Message;
                Message.hwnd = hWnd;
                Message.message = msg;
                Message.wParam = wParam;
                Message.lParam = lParam;

                ConioProcessKey(ActiveConsole->Console, &Message);
                LeaveCriticalSection(&ActiveConsole->Console->Lock);
            }
            break;
        }

        case WM_ACTIVATE:
        {
            if (ConDrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE))
            {
                if (LOWORD(wParam) != WA_INACTIVE)
                {
                    SetFocus(hWnd);
                    ConioDrawConsole(ActiveConsole->Console);
                }
                LeaveCriticalSection(&ActiveConsole->Console->Lock);
            }
            break;
        }

        default:
            break;
    }

    return DefWindowProcW(hWnd, msg, wParam, lParam);
}
Esempio n. 2
0
VOID
GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
                     HANDLE hClientSection,
                     BOOL SaveSettings)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PCONSRV_CONSOLE Console = GuiData->Console;
    PCONSOLE_PROCESS_DATA ProcessData;
    HANDLE hSection = NULL;
    ULONG ViewSize = 0;
    PCONSOLE_PROPS pConInfo = NULL;
    PCONSOLE_INFO  ConInfo  = NULL;
    PTERMINAL_INFO TermInfo = NULL;
    PGUI_CONSOLE_INFO GuiInfo = NULL;

    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;

    /* Get the console leader process, our client */
    ProcessData = ConSrvGetConsoleLeaderProcess(Console);

    /* Duplicate the section handle for ourselves */
    Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
                               hClientSection,
                               NtCurrentProcess(),
                               &hSection,
                               0, 0, DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error when mapping client handle, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    /* Get a view of the shared section */
    Status = NtMapViewOfSection(hSection,
                                NtCurrentProcess(),
                                (PVOID*)&pConInfo,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error when mapping view of file, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    _SEH2_TRY
    {
        /* Check that the section is well-sized */
        if ( (ViewSize < sizeof(CONSOLE_PROPS)) ||
             (pConInfo->TerminalInfo.Size != sizeof(GUI_CONSOLE_INFO)) ||
             (ViewSize < sizeof(CONSOLE_PROPS) + pConInfo->TerminalInfo.Size) )
        {
            DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_PROPS) + sizeof(Terminal_specific_info)\n");
            Status = STATUS_INVALID_VIEW_SIZE;
            _SEH2_YIELD(goto Quit);
        }

        // TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow

        /* Retrieve terminal informations */
        ConInfo  = &pConInfo->ci;
        TermInfo = &pConInfo->TerminalInfo;
        GuiInfo  = TermInfo->TermInfo = (PVOID)((ULONG_PTR)pConInfo + (ULONG_PTR)TermInfo->TermInfo);

        /*
         * If we don't set the default parameters,
         * apply them, otherwise just save them.
         */
        if (pConInfo->ShowDefaultParams == FALSE)
        {
            /* Set the console informations */
            ConSrvApplyUserSettings(Console, ConInfo);

            /* Set the terminal informations */

            // memcpy(&GuiData->GuiInfo, GuiInfo, sizeof(GUI_CONSOLE_INFO));

            /* Change the font */
            InitFonts(GuiData,
                      GuiInfo->FaceName,
                      GuiInfo->FontFamily,
                      GuiInfo->FontSize,
                      GuiInfo->FontWeight);
           // HACK, needed because changing font may change the size of the window
           /**/TermResizeTerminal(Console);/**/

            /* Move the window to the user's values */
            GuiData->GuiInfo.AutoPosition = GuiInfo->AutoPosition;
            GuiData->GuiInfo.WindowOrigin = GuiInfo->WindowOrigin;
            GuiConsoleMoveWindow(GuiData);

            InvalidateRect(GuiData->hWindow, NULL, TRUE);

            /*
             * Apply full-screen mode.
             */
            if (GuiInfo->FullScreen != GuiData->GuiInfo.FullScreen)
            {
                SwitchFullScreen(GuiData, GuiInfo->FullScreen);
            }
        }

        /*
         * Save settings if needed
         */
        // FIXME: Do it in the console properties applet ??
        if (SaveSettings)
        {
            DWORD ProcessId = HandleToUlong(ProcessData->Process->ClientId.UniqueProcess);
            ConSrvWriteUserSettings(ConInfo, ProcessId);
            GuiConsoleWriteUserSettings(GuiInfo, ConInfo->ConsoleTitle, ProcessId);
        }

        Status = STATUS_SUCCESS;
    }
Esempio n. 3
0
/*
 * Function for dealing with the undocumented message and structure used by
 * Windows' console.dll for setting console info.
 * See http://www.catch22.net/sites/default/source/files/setconsoleinfo.c
 * and http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf
 * for more information.
 */
VOID
GuiApplyWindowsConsoleSettings(PGUI_CONSOLE_DATA GuiData,
                               HANDLE hClientSection)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PCONSRV_CONSOLE Console = GuiData->Console;
    PCONSOLE_PROCESS_DATA ProcessData;
    HANDLE hSection = NULL;
    ULONG ViewSize = 0;
    PCONSOLE_STATE_INFO pConInfo = NULL;
    CONSOLE_INFO     ConInfo;
    GUI_CONSOLE_INFO GuiInfo;
#if 0
    SIZE_T Length;
#endif

    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;

    /* Get the console leader process, our client */
    ProcessData = ConSrvGetConsoleLeaderProcess(Console);

    /* Duplicate the section handle for ourselves */
    Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
                               hClientSection,
                               NtCurrentProcess(),
                               &hSection,
                               0, 0, DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error when mapping client handle, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    /* Get a view of the shared section */
    Status = NtMapViewOfSection(hSection,
                                NtCurrentProcess(),
                                (PVOID*)&pConInfo,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error when mapping view of file, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    _SEH2_TRY
    {
        /* Check that the section is well-sized */
        if ( (ViewSize < sizeof(CONSOLE_STATE_INFO)) ||
             (pConInfo->cbSize != sizeof(CONSOLE_STATE_INFO)) )
        {
            DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_STATE_INFO)\n");
            Status = STATUS_INVALID_VIEW_SIZE;
            _SEH2_YIELD(goto Quit);
        }

        // TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow

        /* Retrieve terminal informations */

        // Console information
        ConInfo.HistoryBufferSize = pConInfo->HistoryBufferSize;
        ConInfo.NumberOfHistoryBuffers = pConInfo->NumberOfHistoryBuffers;
        ConInfo.HistoryNoDup = !!pConInfo->HistoryNoDup;
        ConInfo.QuickEdit = !!pConInfo->QuickEdit;
        ConInfo.InsertMode = !!pConInfo->InsertMode;
        ConInfo.ScreenBufferSize = pConInfo->ScreenBufferSize;
        ConInfo.ConsoleSize = pConInfo->WindowSize;
        ConInfo.CursorSize = pConInfo->CursorSize;
        ConInfo.ScreenAttrib = pConInfo->ScreenColors;
        ConInfo.PopupAttrib = pConInfo->PopupColors;
        memcpy(&ConInfo.Colors, pConInfo->ColorTable, sizeof(ConInfo.Colors));
        ConInfo.CodePage = pConInfo->CodePage;
        /**ConInfo.ConsoleTitle[MAX_PATH + 1] = pConInfo->ConsoleTitle; // FIXME: memcpy**/
#if 0
        /* Title of the console, original one corresponding to the one set by the console leader */
        Length = min(sizeof(pConInfo->ConsoleTitle) / sizeof(pConInfo->ConsoleTitle[0]) - 1,
               Console->OriginalTitle.Length / sizeof(WCHAR));
        wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length);
#endif
        // BOOLEAN ConInfo.CursorBlinkOn = pConInfo->
        // BOOLEAN ConInfo.ForceCursorOff = pConInfo->


        // Terminal information
        wcsncpy(GuiInfo.FaceName, pConInfo->FaceName, LF_FACESIZE);
        GuiInfo.FaceName[LF_FACESIZE - 1] = UNICODE_NULL;

        GuiInfo.FontFamily = pConInfo->FontFamily;
        GuiInfo.FontSize = pConInfo->FontSize;
        GuiInfo.FontWeight = pConInfo->FontWeight;
        GuiInfo.FullScreen = !!pConInfo->FullScreen;
        GuiInfo.AutoPosition = !!pConInfo->AutoPosition;
        GuiInfo.WindowOrigin = pConInfo->WindowPosition;
        // WORD  GuiInfo.ShowWindow = pConInfo->



        /*
         * If we don't set the default parameters,
         * apply them, otherwise just save them.
         */
#if 0
        if (pConInfo->ShowDefaultParams == FALSE)
#endif
        {
            /* Set the console informations */
            ConSrvApplyUserSettings(Console, &ConInfo);

            /* Set the terminal informations */

            // memcpy(&GuiData->GuiInfo, &GuiInfo, sizeof(GUI_CONSOLE_INFO));

            /* Change the font */
            InitFonts(GuiData,
                      GuiInfo.FaceName,
                      GuiInfo.FontFamily,
                      GuiInfo.FontSize,
                      GuiInfo.FontWeight);
           // HACK, needed because changing font may change the size of the window
           /**/TermResizeTerminal(Console);/**/

            /* Move the window to the user's values */
            GuiData->GuiInfo.AutoPosition = GuiInfo.AutoPosition;
            GuiData->GuiInfo.WindowOrigin = GuiInfo.WindowOrigin;
            GuiConsoleMoveWindow(GuiData);

            InvalidateRect(GuiData->hWindow, NULL, TRUE);

            /*
             * Apply full-screen mode.
             */
            if (GuiInfo.FullScreen != GuiData->GuiInfo.FullScreen)
            {
                SwitchFullScreen(GuiData, GuiInfo.FullScreen);
            }
        }

#if 0
        /*
         * Save settings if needed
         */
        // FIXME: Do it in the console properties applet ??
        if (SaveSettings)
        {
            DWORD ProcessId = HandleToUlong(ProcessData->Process->ClientId.UniqueProcess);
            ConSrvWriteUserSettings(&ConInfo, ProcessId);
            GuiConsoleWriteUserSettings(&GuiInfo, ConInfo.ConsoleTitle, ProcessId);
        }
#endif

        Status = STATUS_SUCCESS;
    }
Esempio n. 4
0
VOID
GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
                                BOOL Defaults)
{
    NTSTATUS Status;
    PCONSRV_CONSOLE Console = GuiData->Console;
    PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
    PCONSOLE_PROCESS_DATA ProcessData;
    HANDLE hSection = NULL, hClientSection = NULL;
    LARGE_INTEGER SectionSize;
    ULONG ViewSize = 0;
    SIZE_T Length = 0;
    PCONSOLE_PROPS pSharedInfo = NULL;
    PGUI_CONSOLE_INFO GuiInfo = NULL;

    DPRINT("GuiConsoleShowConsoleProperties entered\n");

    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;

    /*
     * Create a memory section to share with the applet, and map it.
     */
    /* Holds data for console.dll + console info + terminal-specific info */
    SectionSize.QuadPart = sizeof(CONSOLE_PROPS) + sizeof(GUI_CONSOLE_INFO);
    Status = NtCreateSection(&hSection,
                             SECTION_ALL_ACCESS,
                             NULL,
                             &SectionSize,
                             PAGE_READWRITE,
                             SEC_COMMIT,
                             NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to create a shared section, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    Status = NtMapViewOfSection(hSection,
                                NtCurrentProcess(),
                                (PVOID*)&pSharedInfo,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to map the shared section, Status = 0x%08lx\n", Status);
        goto Quit;
    }


    /*
     * Setup the shared console properties structure.
     */

    /* Header */
    pSharedInfo->hConsoleWindow = GuiData->hWindow;
    pSharedInfo->ShowDefaultParams = Defaults;

    /*
     * We fill-in the fields only if we display
     * our properties, not the default ones.
     */
    if (!Defaults)
    {
        /* Console information */
        pSharedInfo->ci.HistoryBufferSize = Console->HistoryBufferSize;
        pSharedInfo->ci.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
        pSharedInfo->ci.HistoryNoDup = Console->HistoryNoDup;
        pSharedInfo->ci.QuickEdit = Console->QuickEdit;
        pSharedInfo->ci.InsertMode = Console->InsertMode;
        /////////////pSharedInfo->ci.InputBufferSize = 0;
        pSharedInfo->ci.ScreenBufferSize = ActiveBuffer->ScreenBufferSize;
        pSharedInfo->ci.ConsoleSize = ActiveBuffer->ViewSize;
        pSharedInfo->ci.CursorBlinkOn;
        pSharedInfo->ci.ForceCursorOff;
        pSharedInfo->ci.CursorSize = ActiveBuffer->CursorInfo.dwSize;
        if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
        {
            PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;

            pSharedInfo->ci.ScreenAttrib = Buffer->ScreenDefaultAttrib;
            pSharedInfo->ci.PopupAttrib  = Buffer->PopupDefaultAttrib;
        }
        else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
        {
            // PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)ActiveBuffer;
            DPRINT1("GuiConsoleShowConsoleProperties - Graphics buffer\n");

            // FIXME: Gather defaults from the registry ?
            pSharedInfo->ci.ScreenAttrib = DEFAULT_SCREEN_ATTRIB;
            pSharedInfo->ci.PopupAttrib  = DEFAULT_POPUP_ATTRIB ;
        }
        pSharedInfo->ci.CodePage;

        /* GUI Information */
        pSharedInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO);
        GuiInfo = pSharedInfo->TerminalInfo.TermInfo = (PGUI_CONSOLE_INFO)(pSharedInfo + 1);
        wcsncpy(GuiInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE);
        GuiInfo->FaceName[LF_FACESIZE - 1] = UNICODE_NULL;
        GuiInfo->FontFamily = GuiData->GuiInfo.FontFamily;
        GuiInfo->FontSize   = GuiData->GuiInfo.FontSize;
        GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight;
        GuiInfo->FullScreen = GuiData->GuiInfo.FullScreen;
        GuiInfo->AutoPosition = GuiData->GuiInfo.AutoPosition;
        GuiInfo->WindowOrigin = GuiData->GuiInfo.WindowOrigin;
        /* Offsetize */
        pSharedInfo->TerminalInfo.TermInfo = (PVOID)((ULONG_PTR)GuiInfo - (ULONG_PTR)pSharedInfo);

        /* Palette */
        memcpy(pSharedInfo->ci.Colors, Console->Colors, sizeof(Console->Colors));

        /* Title of the console, original one corresponding to the one set by the console leader */
        Length = min(sizeof(pSharedInfo->ci.ConsoleTitle) / sizeof(pSharedInfo->ci.ConsoleTitle[0]) - 1,
                     Console->OriginalTitle.Length / sizeof(WCHAR));
        wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length);
    }
    else
    {
        Length = 0;
        // FIXME: Load the default parameters from the registry.
    }

    /* Null-terminate the title */
    pSharedInfo->ci.ConsoleTitle[Length] = L'\0';


    /* Unmap the view */
    NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo);

    /* Get the console leader process, our client */
    ProcessData = ConSrvGetConsoleLeaderProcess(Console);

    /* Duplicate the section handle for the client */
    Status = NtDuplicateObject(NtCurrentProcess(),
                               hSection,
                               ProcessData->Process->ProcessHandle,
                               &hClientSection,
                               0, 0, DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to duplicate section handle for client, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    /* Start the properties dialog */
    if (ProcessData->PropRoutine)
    {
        _SEH2_TRY
        {
            HANDLE Thread = NULL;

            _SEH2_TRY
            {
                Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
                                            ProcessData->PropRoutine,
                                            (PVOID)hClientSection, 0, NULL);
                if (NULL == Thread)
                {
                    DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
                }
                else
                {
                    DPRINT("ProcessData->PropRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
                           ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
                    /// WaitForSingleObject(Thread, INFINITE);
                }
            }
            _SEH2_FINALLY
            {
                CloseHandle(Thread);
            }
            _SEH2_END;
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            Status = _SEH2_GetExceptionCode();
            DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = 0x%08lx\n", Status);
        }
        _SEH2_END;
    }
Esempio n. 5
0
VOID
GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
                       PGUI_CONSOLE_DATA GuiData,
                       PRECT rcView,
                       PRECT rcFramebuffer)
{
    PCONSRV_CONSOLE Console = Buffer->Header.Console;
    // ASSERT(Console == GuiData->Console);

    ULONG TopLine, BottomLine, LeftChar, RightChar;
    ULONG Line, Char, Start;
    PCHAR_INFO From;
    PWCHAR To;
    WORD LastAttribute, Attribute;
    ULONG CursorX, CursorY, CursorHeight;
    HBRUSH CursorBrush, OldBrush;
    HFONT OldFont, NewFont;
    BOOLEAN IsUnderline;

    if (Buffer->Buffer == NULL) return;

    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;

    rcFramebuffer->left   = Buffer->ViewOrigin.X * GuiData->CharWidth  + rcView->left;
    rcFramebuffer->top    = Buffer->ViewOrigin.Y * GuiData->CharHeight + rcView->top;
    rcFramebuffer->right  = Buffer->ViewOrigin.X * GuiData->CharWidth  + rcView->right;
    rcFramebuffer->bottom = Buffer->ViewOrigin.Y * GuiData->CharHeight + rcView->bottom;

    LeftChar   = rcFramebuffer->left   / GuiData->CharWidth;
    TopLine    = rcFramebuffer->top    / GuiData->CharHeight;
    RightChar  = rcFramebuffer->right  / GuiData->CharWidth;
    BottomLine = rcFramebuffer->bottom / GuiData->CharHeight;

    if (RightChar  >= (ULONG)Buffer->ScreenBufferSize.X) RightChar  = Buffer->ScreenBufferSize.X - 1;
    if (BottomLine >= (ULONG)Buffer->ScreenBufferSize.Y) BottomLine = Buffer->ScreenBufferSize.Y - 1;

    LastAttribute = ConioCoordToPointer(Buffer, LeftChar, TopLine)->Attributes;

    SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute)));
    SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute)));

    /* We use the underscore flag as a underline flag */
    IsUnderline = !!(LastAttribute & COMMON_LVB_UNDERSCORE);
    /* Select the new font */
    NewFont = GuiData->Font[IsUnderline ? FONT_BOLD : FONT_NORMAL];
    OldFont = SelectObject(GuiData->hMemDC, NewFont);

    for (Line = TopLine; Line <= BottomLine; Line++)
    {
        WCHAR LineBuffer[80];   // Buffer containing a part or all the line to be displayed
        From  = ConioCoordToPointer(Buffer, LeftChar, Line);    // Get the first code of the line
        Start = LeftChar;
        To    = LineBuffer;

        for (Char = LeftChar; Char <= RightChar; Char++)
        {
            /*
             * We flush the buffer if the new attribute is different
             * from the current one, or if the buffer is full.
             */
            if (From->Attributes != LastAttribute || (Char - Start == sizeof(LineBuffer) / sizeof(WCHAR)))
            {
                TextOutW(GuiData->hMemDC,
                         Start * GuiData->CharWidth,
                         Line  * GuiData->CharHeight,
                         LineBuffer,
                         Char - Start);
                Start = Char;
                To    = LineBuffer;
                Attribute = From->Attributes;
                if (Attribute != LastAttribute)
                {
                    LastAttribute = Attribute;
                    SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute)));
                    SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute)));

                    /* Change underline state if needed */
                    if (!!(LastAttribute & COMMON_LVB_UNDERSCORE) != IsUnderline)
                    {
                        IsUnderline = !!(LastAttribute & COMMON_LVB_UNDERSCORE);
                        /* Select the new font */
                        NewFont = GuiData->Font[IsUnderline ? FONT_BOLD : FONT_NORMAL];
                        /* OldFont = */ SelectObject(GuiData->hMemDC, NewFont);
                    }
                }
            }

            *(To++) = (From++)->Char.UnicodeChar;
        }

        TextOutW(GuiData->hMemDC,
                 Start * GuiData->CharWidth,
                 Line  * GuiData->CharHeight,
                 LineBuffer,
                 RightChar - Start + 1);
    }

    /* Restore the old font */
    SelectObject(GuiData->hMemDC, OldFont);

    /*
     * Draw the caret
     */
    if (Buffer->CursorInfo.bVisible &&
        Buffer->CursorBlinkOn &&
        !Buffer->ForceCursorOff)
    {
        CursorX = Buffer->CursorPosition.X;
        CursorY = Buffer->CursorPosition.Y;
        if (LeftChar <= CursorX && CursorX <= RightChar &&
            TopLine  <= CursorY && CursorY <= BottomLine)
        {
            CursorHeight = ConioEffectiveCursorSize(Console, GuiData->CharHeight);

            Attribute = ConioCoordToPointer(Buffer, Buffer->CursorPosition.X, Buffer->CursorPosition.Y)->Attributes;
            if (Attribute == DEFAULT_SCREEN_ATTRIB) Attribute = Buffer->ScreenDefaultAttrib;

            CursorBrush = CreateSolidBrush(PaletteRGBFromAttrib(Console, TextAttribFromAttrib(Attribute)));
            OldBrush    = SelectObject(GuiData->hMemDC, CursorBrush);

            PatBlt(GuiData->hMemDC,
                   CursorX * GuiData->CharWidth,
                   CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
                   GuiData->CharWidth,
                   CursorHeight,
                   PATCOPY);

            SelectObject(GuiData->hMemDC, OldBrush);
            DeleteObject(CursorBrush);
        }
    }

    LeaveCriticalSection(&Console->Lock);
}
Esempio n. 6
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();
}
Esempio n. 7
0
VOID
GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
                                BOOL Defaults)
{
    NTSTATUS Status;
    PCONSRV_CONSOLE Console = GuiData->Console;
    PCONSOLE_PROCESS_DATA ProcessData;
    HANDLE hSection = NULL, hClientSection = NULL;
    PVOID ThreadParameter = NULL; // Is either hClientSection or the console window handle,
                                  // depending on whether we display the default settings or
                                  // the settings of a particular console.

    DPRINT("GuiConsoleShowConsoleProperties entered\n");

    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;

    /* Get the console leader process, our client */
    ProcessData = ConSrvGetConsoleLeaderProcess(Console);

    /*
     * Be sure we effectively have a properties dialog routine (that launches
     * the console control panel applet). It resides in kernel32.dll (client).
     */
    if (ProcessData->PropRoutine == NULL) goto Quit;

    /*
     * Create a memory section to be shared with the console control panel applet
     * in the case we are displaying the settings of a particular console.
     * In that case the ThreadParameter is the hClientSection handle.
     * In the case we display the default console parameters, we don't need to
     * create a memory section. We just need to open the applet, and in this case
     * the ThreadParameter is the parent window handle of the applet's window,
     * that is, the console window.
     */
    if (!Defaults)
    {
        PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
        LARGE_INTEGER SectionSize;
        ULONG ViewSize = 0;
        PCONSOLE_STATE_INFO pSharedInfo = NULL;

        /*
         * Create a memory section to share with the applet, and map it.
         */
        SectionSize.QuadPart  = sizeof(CONSOLE_STATE_INFO);    // Standard size
        SectionSize.QuadPart += Console->OriginalTitle.Length; // Add the length in bytes of the console title string

        Status = NtCreateSection(&hSection,
                                 SECTION_ALL_ACCESS,
                                 NULL,
                                 &SectionSize,
                                 PAGE_READWRITE,
                                 SEC_COMMIT,
                                 NULL);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Error: Impossible to create a shared section, Status = 0x%08lx\n", Status);
            goto Quit;
        }

        Status = NtMapViewOfSection(hSection,
                                    NtCurrentProcess(),
                                    (PVOID*)&pSharedInfo,
                                    0,
                                    0,
                                    NULL,
                                    &ViewSize,
                                    ViewUnmap,
                                    0,
                                    PAGE_READWRITE);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Error: Impossible to map the shared section, Status = 0x%08lx\n", Status);
            goto Quit;
        }


        /*
         * Setup the shared console properties structure.
         */

        /* Store the real size of the structure */
        pSharedInfo->cbSize = SectionSize.QuadPart;

        /*
         * When we setup the settings of a particular console, the parent window
         * of the applet's window is the console window, and it is given via the
         * hWnd member of the shared console info structure.
         */
        pSharedInfo->hWnd = GuiData->hWindow;

        /* Console information */
        pSharedInfo->HistoryBufferSize = Console->HistoryBufferSize;
        pSharedInfo->NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
        pSharedInfo->HistoryNoDup = Console->HistoryNoDup;
        pSharedInfo->QuickEdit = Console->QuickEdit;
        pSharedInfo->InsertMode = Console->InsertMode;
        /// pSharedInfo->InputBufferSize = 0;
        pSharedInfo->ScreenBufferSize = ActiveBuffer->ScreenBufferSize;
        pSharedInfo->WindowSize = ActiveBuffer->ViewSize;
        pSharedInfo->CursorSize = ActiveBuffer->CursorInfo.dwSize;
        if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
        {
            PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;

            pSharedInfo->ScreenAttributes = Buffer->ScreenDefaultAttrib;
            pSharedInfo->PopupAttributes  = Buffer->PopupDefaultAttrib;
        }
        else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
        {
            // PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)ActiveBuffer;
            DPRINT1("GuiConsoleShowConsoleProperties - Graphics buffer\n");

            // FIXME: Gather defaults from the registry ?
            pSharedInfo->ScreenAttributes = DEFAULT_SCREEN_ATTRIB;
            pSharedInfo->PopupAttributes  = DEFAULT_POPUP_ATTRIB ;
        }
        /// pSharedInfo->CodePage;

        /* GUI Information */
        wcsncpy(pSharedInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE);
        pSharedInfo->FaceName[LF_FACESIZE - 1] = UNICODE_NULL;
        pSharedInfo->FontFamily = GuiData->GuiInfo.FontFamily;
        pSharedInfo->FontSize   = GuiData->GuiInfo.FontSize;
        pSharedInfo->FontWeight = GuiData->GuiInfo.FontWeight;
        pSharedInfo->FullScreen = GuiData->GuiInfo.FullScreen;
        pSharedInfo->AutoPosition   = GuiData->GuiInfo.AutoPosition;
        pSharedInfo->WindowPosition = GuiData->GuiInfo.WindowOrigin;

        /* Palette */
        RtlCopyMemory(pSharedInfo->ColorTable,
                      Console->Colors, sizeof(Console->Colors));

        /* Copy the original title of the console and null-terminate it */
        RtlCopyMemory(pSharedInfo->ConsoleTitle,
                      Console->OriginalTitle.Buffer,
                      Console->OriginalTitle.Length);

        pSharedInfo->ConsoleTitle[Console->OriginalTitle.Length / sizeof(WCHAR)] = UNICODE_NULL;


        /* Unmap the view */
        NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo);

        /* Duplicate the section handle for the client */
        Status = NtDuplicateObject(NtCurrentProcess(),
                                   hSection,
                                   ProcessData->Process->ProcessHandle,
                                   &hClientSection,
                                   0, 0, DUPLICATE_SAME_ACCESS);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Error: Impossible to duplicate section handle for client, Status = 0x%08lx\n", Status);
            goto Quit;
        }

        /* For the settings of a particular console, use the shared client section handle as the thread parameter */
        ThreadParameter = (PVOID)hClientSection;
    }
    else
    {
        /* For the default settings, use the console window handle as the thread parameter */
        ThreadParameter = (PVOID)GuiData->hWindow;
    }

    /* Start the console control panel applet */
    _SEH2_TRY
    {
        HANDLE Thread = NULL;

        _SEH2_TRY
        {
            Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
                                        ProcessData->PropRoutine,
                                        ThreadParameter, 0, NULL);
            if (NULL == Thread)
            {
                DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
            }
            else
            {
                DPRINT("ProcessData->PropRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
                       ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
            }
        }
        _SEH2_FINALLY
        {
            CloseHandle(Thread);
        }
        _SEH2_END;
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
        DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = 0x%08lx\n", Status);
    }
    _SEH2_END;

Quit:
    /* We have finished, close the section handle if any */
    if (hSection) NtClose(hSection);

    LeaveCriticalSection(&Console->Lock);
    return;
}
Esempio n. 8
0
/*
 * Function for dealing with the undocumented message and structure used by
 * Windows' console.dll for setting console info.
 * See http://www.catch22.net/sites/default/source/files/setconsoleinfo.c
 * and http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf
 * for more information.
 */
VOID
GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
                     HANDLE hClientSection)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PCONSRV_CONSOLE Console = GuiData->Console;
    PCONSOLE_PROCESS_DATA ProcessData;
    HANDLE hSection = NULL;
    ULONG ViewSize = 0;
    PCONSOLE_STATE_INFO pConInfo = NULL;

    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;

    /* Get the console leader process, our client */
    ProcessData = ConSrvGetConsoleLeaderProcess(Console);

    /* Duplicate the section handle for ourselves */
    Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
                               hClientSection,
                               NtCurrentProcess(),
                               &hSection,
                               0, 0, DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error when mapping client handle, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    /* Get a view of the shared section */
    Status = NtMapViewOfSection(hSection,
                                NtCurrentProcess(),
                                (PVOID*)&pConInfo,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error when mapping view of file, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    _SEH2_TRY
    {
        /* Check that the section is well-sized */
        if ( (ViewSize < sizeof(CONSOLE_STATE_INFO)) ||
             (pConInfo->cbSize < sizeof(CONSOLE_STATE_INFO)) )
        {
            DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_STATE_INFO)\n");
            Status = STATUS_INVALID_VIEW_SIZE;
            _SEH2_YIELD(goto Quit);
        }

        // TODO: Check that GuiData->hWindow == pConInfo->hWnd

        /* Retrieve terminal informations */

        /* Console information */
#if 0 // FIXME: Things not set
        ConInfo.HistoryBufferSize = pConInfo->HistoryBufferSize;
        ConInfo.NumberOfHistoryBuffers = pConInfo->NumberOfHistoryBuffers;
        ConInfo.HistoryNoDup = !!pConInfo->HistoryNoDup;
        ConInfo.CodePage = pConInfo->CodePage;
#endif

        /*
         * Apply the settings
         */

        /* Set the console informations */
        ConSrvApplyUserSettings(Console, pConInfo);

        /* Set the terminal informations */

        /* Change the font */
        InitFonts(GuiData,
                  pConInfo->FaceName,
                  pConInfo->FontFamily,
                  pConInfo->FontSize,
                  pConInfo->FontWeight);
       // HACK, needed because changing font may change the size of the window
       /**/TermResizeTerminal(Console);/**/

        /* Move the window to the user's values */
        GuiData->GuiInfo.AutoPosition = !!pConInfo->AutoPosition;
        GuiData->GuiInfo.WindowOrigin = pConInfo->WindowPosition;
        GuiConsoleMoveWindow(GuiData);

        InvalidateRect(GuiData->hWindow, NULL, TRUE);

        /*
         * Apply full-screen mode.
         */
        if (!!pConInfo->FullScreen != GuiData->GuiInfo.FullScreen)
        {
            SwitchFullScreen(GuiData, !!pConInfo->FullScreen);
        }

        /*
         * The settings are saved in the registry by console.dll itself, if needed.
         */
        // if (SaveSettings)
        // {
            // GuiConsoleWriteUserSettings(GuiInfo);
        // }

        Status = STATUS_SUCCESS;
    }