Exemplo n.º 1
0
static PHISTORY_BUFFER
HistoryCurrentBuffer(PCONSOLE Console)
{
    /* TODO: use actual EXE name sent from process that called ReadConsole */
    UNICODE_STRING ExeName = { 14, 14, L"cmd.exe" };
    PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
    PHISTORY_BUFFER Hist;

    for (; Entry != &Console->HistoryBuffers; Entry = Entry->Flink)
    {
        Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
        if (RtlEqualUnicodeString(&ExeName, &Hist->ExeName, FALSE))
            return Hist;
    }

    /* Couldn't find the buffer, create a new one */
    Hist = ConsoleAllocHeap(0, sizeof(HISTORY_BUFFER) + ExeName.Length);
    if (!Hist) return NULL;
    Hist->MaxEntries = Console->HistoryBufferSize;
    Hist->NumEntries = 0;
    Hist->Entries = ConsoleAllocHeap(0, Hist->MaxEntries * sizeof(UNICODE_STRING));
    if (!Hist->Entries)
    {
        ConsoleFreeHeap(Hist);
        return NULL;
    }
    Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName.Length;
    Hist->ExeName.Buffer = (PWCHAR)(Hist + 1);
    memcpy(Hist->ExeName.Buffer, ExeName.Buffer, ExeName.Length);
    InsertHeadList(&Console->HistoryBuffers, &Hist->ListEntry);
    return Hist;
}
Exemplo n.º 2
0
BOOLEAN
ConvertInputAnsiToUnicode(PCONSRV_CONSOLE Console,
                          PVOID    Source,
                          USHORT   SourceLength,
                          // BOOLEAN  IsUnicode,
                          PWCHAR*  Target,
                          PUSHORT  TargetLength)
{
    ASSERT(Source && Target && TargetLength);

    /* Use the console input CP for the conversion */
    *TargetLength = MultiByteToWideChar(Console->InputCodePage, 0,
                                        Source, SourceLength,
                                        NULL, 0);
    *Target = ConsoleAllocHeap(0, *TargetLength * sizeof(WCHAR));
    if (*Target == NULL) return FALSE;

    MultiByteToWideChar(Console->InputCodePage, 0,
                        Source, SourceLength,
                        *Target, *TargetLength);

    /* The returned Length was in number of WCHARs, convert it in bytes */
    *TargetLength *= sizeof(WCHAR);

    return TRUE;
}
Exemplo n.º 3
0
Arquivo: text.c Projeto: GYGit/reactos
NTSTATUS
TEXTMODE_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
                           IN PCONSOLE Console,
                           IN HANDLE ProcessHandle,
                           IN PTEXTMODE_BUFFER_INFO TextModeInfo)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PTEXTMODE_SCREEN_BUFFER NewBuffer = NULL;

    UNREFERENCED_PARAMETER(ProcessHandle);

    if (Console == NULL || Buffer == NULL || TextModeInfo == NULL)
        return STATUS_INVALID_PARAMETER;

    *Buffer = NULL;

    Status = CONSOLE_SCREEN_BUFFER_Initialize((PCONSOLE_SCREEN_BUFFER*)&NewBuffer,
                                              Console,
                                              &TextVtbl,
                                              sizeof(TEXTMODE_SCREEN_BUFFER));
    if (!NT_SUCCESS(Status)) return Status;
    NewBuffer->Header.Type = TEXTMODE_BUFFER;

    NewBuffer->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
                                         TextModeInfo->ScreenBufferSize.X *
                                         TextModeInfo->ScreenBufferSize.Y *
                                            sizeof(CHAR_INFO));
    if (NewBuffer->Buffer == NULL)
    {
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    NewBuffer->ScreenBufferSize = NewBuffer->OldScreenBufferSize
                                = TextModeInfo->ScreenBufferSize;
    NewBuffer->ViewSize = NewBuffer->OldViewSize
                        = Console->ConsoleSize;

    NewBuffer->ViewOrigin.X = NewBuffer->ViewOrigin.Y = 0;
    NewBuffer->VirtualY = 0;

    NewBuffer->CursorBlinkOn = NewBuffer->ForceCursorOff = FALSE;
    NewBuffer->CursorInfo.bVisible = (TextModeInfo->IsCursorVisible && (TextModeInfo->CursorSize != 0));
    NewBuffer->CursorInfo.dwSize   = min(max(TextModeInfo->CursorSize, 0), 100);

    NewBuffer->ScreenDefaultAttrib = TextModeInfo->ScreenAttrib;
    NewBuffer->PopupDefaultAttrib  = TextModeInfo->PopupAttrib;

    /* Initialize buffer to be empty with default attributes */
    for (NewBuffer->CursorPosition.Y = 0 ; NewBuffer->CursorPosition.Y < NewBuffer->ScreenBufferSize.Y; NewBuffer->CursorPosition.Y++)
    {
        ClearLineBuffer(NewBuffer);
    }
    NewBuffer->CursorPosition.X = NewBuffer->CursorPosition.Y = 0;

    NewBuffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;

    *Buffer = (PCONSOLE_SCREEN_BUFFER)NewBuffer;
    return STATUS_SUCCESS;
}
Exemplo n.º 4
0
static NTSTATUS
WaitBeforeReading(IN PGET_INPUT_INFO InputInfo,
                  IN PCSR_API_MESSAGE ApiMessage,
                  IN CSR_WAIT_FUNCTION WaitFunction OPTIONAL,
                  IN BOOL CreateWaitBlock OPTIONAL)
{
    if (CreateWaitBlock)
    {
        PGET_INPUT_INFO CapturedInputInfo;

        CapturedInputInfo = ConsoleAllocHeap(0, sizeof(GET_INPUT_INFO));
        if (!CapturedInputInfo) return STATUS_NO_MEMORY;

        RtlMoveMemory(CapturedInputInfo, InputInfo, sizeof(GET_INPUT_INFO));

        if (!CsrCreateWait(&InputInfo->InputBuffer->ReadWaitQueue,
                           WaitFunction,
                           InputInfo->CallingThread,
                           ApiMessage,
                           CapturedInputInfo,
                           NULL))
        {
            ConsoleFreeHeap(CapturedInputInfo);
            return STATUS_NO_MEMORY;
        }
    }

    /* Wait for input */
    return STATUS_PENDING;
}
Exemplo n.º 5
0
NTSTATUS NTAPI
ConSrvInitTerminal(IN OUT PTERMINAL Terminal,
                   IN OUT PCONSOLE_INFO ConsoleInfo,
                   IN OUT PVOID ExtraConsoleInfo,
                   IN ULONG ProcessId)
{
    NTSTATUS Status;
    PFRONTEND FrontEnd;

    /* Load a suitable frontend for the ConSrv terminal */
    FrontEnd = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(*FrontEnd));
    if (!FrontEnd) return STATUS_NO_MEMORY;

    Status = ConSrvLoadFrontEnd(FrontEnd,
                                ConsoleInfo,
                                ExtraConsoleInfo,
                                ProcessId);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CONSRV: Failed to initialize a frontend, Status = 0x%08lx\n", Status);
        ConsoleFreeHeap(FrontEnd);
        return Status;
    }
    DPRINT("CONSRV: Frontend initialized\n");

    /* Initialize the ConSrv terminal */
    Terminal->Vtbl = &ConSrvTermVtbl;
    // Terminal->Console will be initialized by ConDrvRegisterTerminal
    Terminal->Context = FrontEnd; /* We store the frontend pointer in the terminal private context */

    return STATUS_SUCCESS;
}
Exemplo n.º 6
0
NTSTATUS FASTCALL
ConioProcessInputEvent(PCONSOLE Console,
                       PINPUT_RECORD InputEvent)
{
    ConsoleInput *ConInRec;

    /* Check for pause or unpause */
    if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown)
    {
        WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode;
        if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD))
        {
            DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState;
            if (Console->InputBuffer.Mode & ENABLE_LINE_INPUT &&
                (vk == VK_PAUSE || (vk == 'S' &&
                                    (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) &&
                                   !(cks & (LEFT_ALT_PRESSED  | RIGHT_ALT_PRESSED)))))
            {
                ConioPause(Console, PAUSED_FROM_KEYBOARD);
                return STATUS_SUCCESS;
            }
        }
        else
        {
            if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN &&
                vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL)
            {
                ConioUnpause(Console, PAUSED_FROM_KEYBOARD);
                return STATUS_SUCCESS;
            }
        }
    }

    /* Add event to the queue */
    ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput));
    if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES;

    ConInRec->InputEvent = *InputEvent;
    InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);

    SetEvent(Console->InputBuffer.ActiveEvent);
    CsrNotifyWait(&Console->InputBuffer.ReadWaitQueue,
                  WaitAny,
                  NULL,
                  NULL);
    if (!IsListEmpty(&Console->InputBuffer.ReadWaitQueue))
    {
        CsrDereferenceWait(&Console->InputBuffer.ReadWaitQueue);
    }

    return STATUS_SUCCESS;
}
Exemplo n.º 7
0
NTSTATUS
ConSrvInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
                          IN PCONSOLE_PROCESS_DATA TargetProcessData)
{
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG i, j;

    RtlEnterCriticalSection(&SourceProcessData->HandleTableLock);

    /* Inherit a handles table only if there is no already */
    if (TargetProcessData->HandleTable != NULL /* || TargetProcessData->HandleTableSize != 0 */)
    {
        Status = STATUS_UNSUCCESSFUL;
        goto Quit;
    }

    /* Allocate a new handle table for the child process */
    TargetProcessData->HandleTable = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
                                                      SourceProcessData->HandleTableSize
                                                        * sizeof(CONSOLE_IO_HANDLE));
    if (TargetProcessData->HandleTable == NULL)
    {
        Status = STATUS_NO_MEMORY;
        goto Quit;
    }

    TargetProcessData->HandleTableSize = SourceProcessData->HandleTableSize;

    /*
     * Parse the parent process' handles table and, for each handle,
     * do a copy of it and reference it, if the handle is inheritable.
     */
    for (i = 0, j = 0; i < SourceProcessData->HandleTableSize; i++)
    {
        if (SourceProcessData->HandleTable[i].Object != NULL &&
            SourceProcessData->HandleTable[i].Inheritable)
        {
            /*
             * Copy the handle data and increment the reference count of the
             * pointed object (via the call to ConSrvCreateHandleEntry == AdjustHandleCounts).
             */
            TargetProcessData->HandleTable[j] = SourceProcessData->HandleTable[i];
            AdjustHandleCounts(&TargetProcessData->HandleTable[j], +1);
            ++j;
        }
    }

Quit:
    RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
    return Status;
}
Exemplo n.º 8
0
/* Code taken and adapted from base/system/services/driver.c */
static DWORD
ScmLoadDriver(LPCWSTR lpServiceName)
{
    NTSTATUS Status = STATUS_SUCCESS;
    BOOLEAN WasPrivilegeEnabled = FALSE;
    PWSTR pszDriverPath;
    UNICODE_STRING DriverPath;

    /* Build the driver path */
    /* 52 = wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") */
    pszDriverPath = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
                                     (52 + wcslen(lpServiceName) + 1) * sizeof(WCHAR));
    if (pszDriverPath == NULL)
        return ERROR_NOT_ENOUGH_MEMORY;

    wcscpy(pszDriverPath,
           L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
    wcscat(pszDriverPath,
           lpServiceName);

    RtlInitUnicodeString(&DriverPath,
                         pszDriverPath);

    DPRINT("  Path: %wZ\n", &DriverPath);

    /* Acquire driver-loading privilege */
    Status = RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE,
                                TRUE,
                                FALSE,
                                &WasPrivilegeEnabled);
    if (!NT_SUCCESS(Status))
    {
        /* We encountered a failure, exit properly */
        DPRINT1("CONSRV: Cannot acquire driver-loading privilege, Status = 0x%08lx\n", Status);
        goto done;
    }

    Status = NtLoadDriver(&DriverPath);

    /* Release driver-loading privilege */
    RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE,
                       WasPrivilegeEnabled,
                       FALSE,
                       &WasPrivilegeEnabled);

done:
    ConsoleFreeHeap(pszDriverPath);
    return RtlNtStatusToDosError(Status);
}
Exemplo n.º 9
0
PALIAS_HEADER
IntCreateAliasHeader(LPCWSTR lpExeName)
{
    PALIAS_HEADER Entry;
    UINT dwLength = wcslen(lpExeName) + 1;

    Entry = ConsoleAllocHeap(0, sizeof(ALIAS_HEADER) + sizeof(WCHAR) * dwLength);
    if (!Entry) return Entry;

    Entry->lpExeName = (LPCWSTR)(Entry + 1);
    wcscpy((PWCHAR)Entry->lpExeName, lpExeName);
    Entry->Data = NULL;
    Entry->Next = NULL;
    return Entry;
}
Exemplo n.º 10
0
NTSTATUS
CONSOLE_SCREEN_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
                                 IN OUT PCONSOLE Console,
                                 IN SIZE_T Size)
{
    if (Buffer == NULL || Console == NULL)
        return STATUS_INVALID_PARAMETER;

    *Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, max(sizeof(CONSOLE_SCREEN_BUFFER), Size));
    if (*Buffer == NULL) return STATUS_INSUFFICIENT_RESOURCES;

    /* Initialize the header with the default type */
    ConSrvInitObject(&(*Buffer)->Header, SCREEN_BUFFER, Console);
    (*Buffer)->Vtbl = NULL;
    return STATUS_SUCCESS;
}
Exemplo n.º 11
0
static PALIAS_HEADER
IntCreateAliasHeader(PCONSRV_CONSOLE Console,
                     PVOID    ExeName,
                     USHORT   ExeLength,
                     BOOLEAN  UnicodeExe)
{
    UNICODE_STRING ExeNameU;

    PALIAS_HEADER Entry;

    if (ExeName == NULL) return NULL;

    if (UnicodeExe)
    {
        ExeNameU.Buffer = ExeName;
        /* Length is in bytes */
        ExeNameU.MaximumLength = ExeLength;
    }
    else
    {
        if (!ConvertInputAnsiToUnicode(Console,
                                       ExeName, ExeLength,
                                       &ExeNameU.Buffer, &ExeNameU.MaximumLength))
        {
            return NULL;
        }
    }
    ExeNameU.Length = ExeNameU.MaximumLength;

    Entry = ConsoleAllocHeap(0, sizeof(ALIAS_HEADER) + ExeNameU.Length);
    if (!Entry)
    {
        if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
        return Entry;
    }

    Entry->ExeName.Buffer = (PWSTR)(Entry + 1);
    Entry->ExeName.Length = 0;
    Entry->ExeName.MaximumLength = ExeNameU.Length;
    RtlCopyUnicodeString(&Entry->ExeName, &ExeNameU);

    Entry->Data = NULL;
    Entry->Next = NULL;

    if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
    return Entry;
}
Exemplo n.º 12
0
PALIAS_ENTRY
IntCreateAliasEntry(LPCWSTR lpSource, LPCWSTR lpTarget)
{
    UINT dwSource;
    UINT dwTarget;
    PALIAS_ENTRY Entry;

    dwSource = wcslen(lpSource) + 1;
    dwTarget = wcslen(lpTarget) + 1;

    Entry = ConsoleAllocHeap(0, sizeof(ALIAS_ENTRY) + sizeof(WCHAR) * (dwSource + dwTarget));
    if (!Entry) return Entry;

    Entry->lpSource = (LPCWSTR)(Entry + 1);
    wcscpy((LPWSTR)Entry->lpSource, lpSource);
    Entry->lpTarget = Entry->lpSource + dwSource;
    wcscpy((LPWSTR)Entry->lpTarget, lpTarget);
    Entry->Next = NULL;

    return Entry;
}
Exemplo n.º 13
0
static VOID WINAPI
TuiDrawRegion(IN OUT PFRONTEND This,
              SMALL_RECT* Region)
{
    DWORD BytesReturned;
    PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
    PCONSOLE_DRAW ConsoleDraw;
    UINT ConsoleDrawSize;

    if (ActiveConsole->Console != Console || GetType(Buff) != TEXTMODE_BUFFER) return;

    ConsoleDrawSize = sizeof(CONSOLE_DRAW) +
                      (ConioRectWidth(Region) * ConioRectHeight(Region)) * 2;
    ConsoleDraw = ConsoleAllocHeap(0, ConsoleDrawSize);
    if (NULL == ConsoleDraw)
    {
        DPRINT1("ConsoleAllocHeap failed\n");
        return;
    }
    ConsoleDraw->X = Region->Left;
    ConsoleDraw->Y = Region->Top;
    ConsoleDraw->SizeX = ConioRectWidth(Region);
    ConsoleDraw->SizeY = ConioRectHeight(Region);
    ConsoleDraw->CursorX = Buff->CursorPosition.X;
    ConsoleDraw->CursorY = Buff->CursorPosition.Y;

    TuiCopyRect((PCHAR)(ConsoleDraw + 1), (PTEXTMODE_SCREEN_BUFFER)Buff, Region);

    if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW,
                         NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL))
    {
        DPRINT1("Failed to draw console\n");
        ConsoleFreeHeap(ConsoleDraw);
        return;
    }

    ConsoleFreeHeap(ConsoleDraw);
}
Exemplo n.º 14
0
NTSTATUS NTAPI
TuiInitFrontEnd(IN OUT PFRONTEND This,
                IN PCONSOLE Console)
{
    PTUI_CONSOLE_DATA TuiData;
    HANDLE ThreadHandle;

    if (This == NULL || Console == NULL)
        return STATUS_INVALID_PARAMETER;

    // if (GetType(Console->ActiveBuffer) != TEXTMODE_BUFFER)
        // return STATUS_INVALID_PARAMETER;

    // /* Initialize the console */
    // Console->TermIFace.Vtbl = &TuiVtbl;

    TuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(TUI_CONSOLE_DATA));
    if (!TuiData)
    {
        DPRINT1("CONSRV: Failed to create TUI_CONSOLE_DATA\n");
        return STATUS_UNSUCCESSFUL;
    }
    // Console->TermIFace.Data = (PVOID)TuiData;
    TuiData->Console = Console;
    TuiData->hWindow = NULL;

    InitializeCriticalSection(&TuiData->Lock);

    /*
     * HACK: Resize the console since we don't support for now changing
     * the console size when we display it with the hardware.
     */
    // Console->ConsoleSize = PhysicalConsoleSize;
    // ConioResizeBuffer(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), PhysicalConsoleSize);

    // /* The console cannot be resized anymore */
    // Console->FixedSize = TRUE; // MUST be placed AFTER the call to ConioResizeBuffer !!
    // // ConioResizeTerminal(Console);

    /*
     * Contrary to what we do in the GUI front-end, here we create
     * an input thread for each console. It will dispatch all the
     * input messages to the proper console (on the GUI it is done
     * via the default GUI dispatch thread).
     */
    ThreadHandle = CreateThread(NULL,
                                0,
                                TuiConsoleThread,
                                (PVOID)TuiData,
                                0,
                                NULL);
    if (NULL == ThreadHandle)
    {
        DPRINT1("CONSRV: Unable to create console thread\n");
        // TuiDeinitFrontEnd(Console);
        TuiDeinitFrontEnd(This);
        return STATUS_UNSUCCESSFUL;
    }
    CloseHandle(ThreadHandle);

    /*
     * Insert the newly created console in the list of virtual consoles
     * and activate it (give it the focus).
     */
    EnterCriticalSection(&ActiveVirtConsLock);
    InsertTailList(&VirtConsList, &TuiData->Entry);
    ActiveConsole = TuiData;
    LeaveCriticalSection(&ActiveVirtConsLock);

    /* Finally, initialize the frontend structure */
    This->Data = TuiData;
    This->OldData = NULL;

    return STATUS_SUCCESS;
}
Exemplo n.º 15
0
static BOOL FASTCALL
TuiSwapConsole(INT Next)
{
    static PTUI_CONSOLE_DATA SwapConsole = NULL; /* Console we are thinking about swapping with */
    DWORD BytesReturned;
    ANSI_STRING Title;
    PVOID Buffer;
    PCOORD pos;

    if (0 != Next)
    {
        /*
         * Alt-Tab, swap consoles.
         * move SwapConsole to next console, and print its title.
         */
        EnterCriticalSection(&ActiveVirtConsLock);
        if (!SwapConsole) SwapConsole = ActiveConsole;

        SwapConsole = (0 < Next ? GetNextConsole(SwapConsole) : GetPrevConsole(SwapConsole));
        Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Console->Title);
        Title.Length = 0;
        Buffer = ConsoleAllocHeap(0, sizeof(COORD) + Title.MaximumLength);
        pos = (PCOORD)Buffer;
        Title.Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof(COORD));

        RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Console->Title, FALSE);
        pos->X = (PhysicalConsoleSize.X - Title.Length) / 2;
        pos->Y = PhysicalConsoleSize.Y / 2;
        /* Redraw the console to clear off old title */
        ConioDrawConsole(ActiveConsole->Console);
        if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
                             NULL, 0, Buffer, sizeof(COORD) + Title.Length,
                             &BytesReturned, NULL))
        {
            DPRINT1( "Error writing to console\n" );
        }
        ConsoleFreeHeap(Buffer);
        LeaveCriticalSection(&ActiveVirtConsLock);

        return TRUE;
    }
    else if (NULL != SwapConsole)
    {
        EnterCriticalSection(&ActiveVirtConsLock);
        if (SwapConsole != ActiveConsole)
        {
            /* First remove swapconsole from the list */
            SwapConsole->Entry.Blink->Flink = SwapConsole->Entry.Flink;
            SwapConsole->Entry.Flink->Blink = SwapConsole->Entry.Blink;
            /* Now insert before activeconsole */
            SwapConsole->Entry.Flink = &ActiveConsole->Entry;
            SwapConsole->Entry.Blink = ActiveConsole->Entry.Blink;
            ActiveConsole->Entry.Blink->Flink = &SwapConsole->Entry;
            ActiveConsole->Entry.Blink = &SwapConsole->Entry;
        }
        ActiveConsole = SwapConsole;
        SwapConsole = NULL;
        ConioDrawConsole(ActiveConsole->Console);
        LeaveCriticalSection(&ActiveVirtConsLock);
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
Exemplo n.º 16
0
Arquivo: text.c Projeto: GYGit/reactos
NTSTATUS
ConioResizeBuffer(PCONSOLE Console,
                  PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
                  COORD Size)
{
    PCHAR_INFO Buffer;
    DWORD Offset = 0;
    PCHAR_INFO ptr;
    WORD CurrentAttribute;
    USHORT CurrentY;
    PCHAR_INFO OldBuffer;
    DWORD i;
    DWORD diff;

    /* Buffer size is not allowed to be smaller than the view size */
    if (Size.X < ScreenBuffer->ViewSize.X || Size.Y < ScreenBuffer->ViewSize.Y)
        return STATUS_INVALID_PARAMETER;

    if (Size.X == ScreenBuffer->ScreenBufferSize.X && Size.Y == ScreenBuffer->ScreenBufferSize.Y)
    {
        // FIXME: Trigger a buffer resize event ??
        return STATUS_SUCCESS;
    }

    if (Console->FixedSize)
    {
        /*
         * The console is in fixed-size mode, so we cannot resize anything
         * at the moment. However, keep those settings somewhere so that
         * we can try to set them up when we will be allowed to do so.
         */
        ScreenBuffer->OldScreenBufferSize = Size;
        return STATUS_NOT_SUPPORTED; // STATUS_SUCCESS
    }

    Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size.X * Size.Y * sizeof(CHAR_INFO));
    if (!Buffer) return STATUS_NO_MEMORY;

    DPRINT("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->ScreenBufferSize.X, ScreenBuffer->ScreenBufferSize.Y, Size.X, Size.Y);
    OldBuffer = ScreenBuffer->Buffer;

    for (CurrentY = 0; CurrentY < ScreenBuffer->ScreenBufferSize.Y && CurrentY < Size.Y; CurrentY++)
    {
        ptr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY);
        if (Size.X <= ScreenBuffer->ScreenBufferSize.X)
        {
            /* Reduce size */
            RtlCopyMemory(Buffer + Offset, ptr, Size.X * sizeof(CHAR_INFO));
            Offset += Size.X;
        }
        else
        {
            /* Enlarge size */
            RtlCopyMemory(Buffer + Offset, ptr, ScreenBuffer->ScreenBufferSize.X * sizeof(CHAR_INFO));
            Offset += ScreenBuffer->ScreenBufferSize.X;

            /* The attribute to be used is the one of the last cell of the current line */
            CurrentAttribute = ConioCoordToPointer(ScreenBuffer,
                                                   ScreenBuffer->ScreenBufferSize.X - 1,
                                                   CurrentY)->Attributes;

            diff = Size.X - ScreenBuffer->ScreenBufferSize.X;

            /* Zero-out the new part of the buffer */
            for (i = 0; i < diff; i++)
            {
                ptr = Buffer + Offset;
                ptr->Char.UnicodeChar = L' ';
                ptr->Attributes = CurrentAttribute;
                ++Offset;
            }
        }
    }

    if (Size.Y > ScreenBuffer->ScreenBufferSize.Y)
    {
        diff = Size.X * (Size.Y - ScreenBuffer->ScreenBufferSize.Y);

        /* Zero-out the new part of the buffer */
        for (i = 0; i < diff; i++)
        {
            ptr = Buffer + Offset;
            ptr->Char.UnicodeChar = L' ';
            ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib;
            ++Offset;
        }
    }

    (void)InterlockedExchangePointer((PVOID volatile*)&ScreenBuffer->Buffer, Buffer);
    ConsoleFreeHeap(OldBuffer);
    ScreenBuffer->ScreenBufferSize = ScreenBuffer->OldScreenBufferSize = Size;
    ScreenBuffer->VirtualY = 0;

    /* Ensure cursor and window are within buffer */
    if (ScreenBuffer->CursorPosition.X >= Size.X)
        ScreenBuffer->CursorPosition.X = Size.X - 1;
    if (ScreenBuffer->CursorPosition.Y >= Size.Y)
        ScreenBuffer->CursorPosition.Y = Size.Y - 1;
    if (ScreenBuffer->ViewOrigin.X > Size.X - ScreenBuffer->ViewSize.X)
        ScreenBuffer->ViewOrigin.X = Size.X - ScreenBuffer->ViewSize.X;
    if (ScreenBuffer->ViewOrigin.Y > Size.Y - ScreenBuffer->ViewSize.Y)
        ScreenBuffer->ViewOrigin.Y = Size.Y - ScreenBuffer->ViewSize.Y;

    /*
     * Trigger a buffer resize event
     */
    if (Console->InputBuffer.Mode & ENABLE_WINDOW_INPUT)
    {
        ULONG NumEventsWritten;
        INPUT_RECORD er;

        er.EventType = WINDOW_BUFFER_SIZE_EVENT;
        er.Event.WindowBufferSizeEvent.dwSize = ScreenBuffer->ScreenBufferSize;

        // ConioProcessInputEvent(Console, &er);
        ConDrvWriteConsoleInput(Console,
                                &Console->InputBuffer,
                                TRUE,
                                &er,
                                1,
                                &NumEventsWritten);
    }

    return STATUS_SUCCESS;
}
Exemplo n.º 17
0
NTSTATUS
ConSrvInsertObject(IN PCONSOLE_PROCESS_DATA ProcessData,
                   OUT PHANDLE Handle,
                   IN PCONSOLE_IO_OBJECT Object,
                   IN ULONG Access,
                   IN BOOLEAN Inheritable,
                   IN ULONG ShareMode)
{
#define IO_HANDLES_INCREMENT    2 * 3

    ULONG i = 0;
    PCONSOLE_IO_HANDLE Block;

    // NOTE: Commented out because calling code always lock HandleTableLock before.
    // RtlEnterCriticalSection(&ProcessData->HandleTableLock);

    ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) ||
            (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) );

    if (ProcessData->HandleTable)
    {
        for (i = 0; i < ProcessData->HandleTableSize; i++)
        {
            if (ProcessData->HandleTable[i].Object == NULL)
                break;
        }
    }

    if (i >= ProcessData->HandleTableSize)
    {
        /* Allocate a new handles table */
        Block = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
                                 (ProcessData->HandleTableSize +
                                    IO_HANDLES_INCREMENT) * sizeof(CONSOLE_IO_HANDLE));
        if (Block == NULL)
        {
            // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
            return STATUS_UNSUCCESSFUL;
        }

        /* If we previously had a handles table, free it and use the new one */
        if (ProcessData->HandleTable)
        {
            /* Copy the handles from the old table to the new one */
            RtlCopyMemory(Block,
                          ProcessData->HandleTable,
                          ProcessData->HandleTableSize * sizeof(CONSOLE_IO_HANDLE));
            ConsoleFreeHeap(ProcessData->HandleTable);
        }
        ProcessData->HandleTable = Block;
        ProcessData->HandleTableSize += IO_HANDLES_INCREMENT;
    }

    ProcessData->HandleTable[i].Object      = Object;
    ProcessData->HandleTable[i].Access      = Access;
    ProcessData->HandleTable[i].Inheritable = Inheritable;
    ProcessData->HandleTable[i].ShareMode   = ShareMode;
    AdjustHandleCounts(&ProcessData->HandleTable[i], +1);
    *Handle = ULongToHandle((i << 2) | 0x3);

    // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);

    return STATUS_SUCCESS;
}
Exemplo n.º 18
0
NTSTATUS
ConDrvAddInputEvents(PCONSOLE Console,
                     PINPUT_RECORD InputRecords, // InputEvent
                     ULONG NumEventsToWrite,
                     PULONG NumEventsWritten,
                     BOOLEAN AppendToEnd)
{
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG i = 0;
    BOOLEAN SetWaitEvent = FALSE;

    if (NumEventsWritten) *NumEventsWritten = 0;

    /*
     * When adding many single events, in the case of repeated mouse move or
     * key down events, we try to coalesce them so that we do not saturate
     * too quickly the input buffer.
     */
    if (NumEventsToWrite == 1 && !IsListEmpty(&Console->InputBuffer.InputEvents))
    {
        PINPUT_RECORD InputRecord = InputRecords; // Only one element
        PINPUT_RECORD LastInputRecord;
        ConsoleInput* ConInRec; // Input

        /* Get the "next" event of the input buffer */
        if (AppendToEnd)
        {
            /* Get the tail element */
            ConInRec = CONTAINING_RECORD(Console->InputBuffer.InputEvents.Blink,
                                         ConsoleInput, ListEntry);
        }
        else
        {
            /* Get the head element */
            ConInRec = CONTAINING_RECORD(Console->InputBuffer.InputEvents.Flink,
                                         ConsoleInput, ListEntry);
        }
        LastInputRecord = &ConInRec->InputEvent;

        if (InputRecord->EventType == MOUSE_EVENT &&
            InputRecord->Event.MouseEvent.dwEventFlags == MOUSE_MOVED)
        {
            if (LastInputRecord->EventType == MOUSE_EVENT &&
                LastInputRecord->Event.MouseEvent.dwEventFlags == MOUSE_MOVED)
            {
                /* Update the mouse position */
                LastInputRecord->Event.MouseEvent.dwMousePosition.X =
                    InputRecord->Event.MouseEvent.dwMousePosition.X;
                LastInputRecord->Event.MouseEvent.dwMousePosition.Y =
                    InputRecord->Event.MouseEvent.dwMousePosition.Y;

                i = 1;
                // return STATUS_SUCCESS;
                Status = STATUS_SUCCESS;
            }
        }
        else if (InputRecord->EventType == KEY_EVENT &&
                 InputRecord->Event.KeyEvent.bKeyDown)
        {
            if (LastInputRecord->EventType == KEY_EVENT &&
                LastInputRecord->Event.KeyEvent.bKeyDown &&
                (LastInputRecord->Event.KeyEvent.wVirtualScanCode ==    // Same scancode
                     InputRecord->Event.KeyEvent.wVirtualScanCode) &&
                (LastInputRecord->Event.KeyEvent.uChar.UnicodeChar ==   // Same character
                     InputRecord->Event.KeyEvent.uChar.UnicodeChar) &&
                (LastInputRecord->Event.KeyEvent.dwControlKeyState ==   // Same Ctrl/Alt/Shift state
                     InputRecord->Event.KeyEvent.dwControlKeyState) )
            {
                /* Update the repeat count */
                LastInputRecord->Event.KeyEvent.wRepeatCount +=
                    InputRecord->Event.KeyEvent.wRepeatCount;

                i = 1;
                // return STATUS_SUCCESS;
                Status = STATUS_SUCCESS;
            }
        }
    }

    /* If we coalesced the only one element, we can quit */
    if (i == 1 && Status == STATUS_SUCCESS /* && NumEventsToWrite == 1 */)
        goto Done;

    /*
     * No event coalesced, add them in the usual way.
     */

    if (AppendToEnd)
    {
        /* Go to the beginning of the list */
        // InputRecords = InputRecords;
    }
    else
    {
        /* Go to the end of the list */
        InputRecords = &InputRecords[NumEventsToWrite - 1];
    }

    /* Set the event if the list is going to be non-empty */
    if (IsListEmpty(&Console->InputBuffer.InputEvents))
        SetWaitEvent = TRUE;

    for (i = 0; i < NumEventsToWrite && NT_SUCCESS(Status); ++i)
    {
        PINPUT_RECORD InputRecord;
        ConsoleInput* ConInRec;

        if (AppendToEnd)
        {
            /* Select the event and go to the next one */
            InputRecord = InputRecords++;
        }
        else
        {
            /* Select the event and go to the previous one */
            InputRecord = InputRecords--;
        }

        /* Add event to the queue */
        ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput));
        if (ConInRec == NULL)
        {
            // return STATUS_INSUFFICIENT_RESOURCES;
            Status = STATUS_INSUFFICIENT_RESOURCES;
            continue;
        }

        ConInRec->InputEvent = *InputRecord;

        if (AppendToEnd)
        {
            /* Append the event to the end of the queue */
            InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
        }
        else
        {
            /* Append the event to the beginning of the queue */
            InsertHeadList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
        }

        // return STATUS_SUCCESS;
        Status = STATUS_SUCCESS;
    }

    if (SetWaitEvent) SetEvent(Console->InputBuffer.ActiveEvent);

Done:
    if (NumEventsWritten) *NumEventsWritten = i;

    return Status;
}
Exemplo n.º 19
0
NTSTATUS NTAPI
ConDrvReadConsole(IN PCONSOLE Console,
                  IN PCONSOLE_INPUT_BUFFER InputBuffer,
                  IN BOOLEAN Unicode,
                  OUT PVOID Buffer,
                  IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
                  IN ULONG NumCharsToRead,
                  OUT PULONG NumCharsRead OPTIONAL)
{
    // STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait.
    NTSTATUS Status = STATUS_PENDING;
    PLIST_ENTRY CurrentEntry;
    ConsoleInput *Input;
    ULONG i = ReadControl->nInitialChars;

    if (Console == NULL || InputBuffer == NULL || /* Buffer == NULL  || */
        ReadControl == NULL || ReadControl->nLength != sizeof(CONSOLE_READCONSOLE_CONTROL))
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Validity checks */
    ASSERT(Console == InputBuffer->Header.Console);
    ASSERT( (Buffer != NULL && NumCharsToRead >= 0) ||
            (Buffer == NULL && NumCharsToRead == 0) );

    /* We haven't read anything (yet) */

    if (InputBuffer->Mode & ENABLE_LINE_INPUT)
    {
        if (Console->LineBuffer == NULL)
        {
            /* Starting a new line */
            Console->LineMaxSize = (WORD)max(256, NumCharsToRead);

            Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * sizeof(WCHAR));
            if (Console->LineBuffer == NULL) return STATUS_NO_MEMORY;

            Console->LineComplete = FALSE;
            Console->LineUpPressed = FALSE;
            Console->LineInsertToggle = 0;
            Console->LineWakeupMask = ReadControl->dwCtrlWakeupMask;
            Console->LineSize = ReadControl->nInitialChars;
            Console->LinePos = Console->LineSize;

            /*
             * Pre-filling the buffer is only allowed in the Unicode API,
             * so we don't need to worry about ANSI <-> Unicode conversion.
             */
            memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR));
            if (Console->LineSize == Console->LineMaxSize)
            {
                Console->LineComplete = TRUE;
                Console->LinePos = 0;
            }
        }

        /* If we don't have a complete line yet, process the pending input */
        while (!Console->LineComplete && !IsListEmpty(&InputBuffer->InputEvents))
        {
            /* Remove input event from queue */
            CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
            if (IsListEmpty(&InputBuffer->InputEvents))
            {
                ResetEvent(InputBuffer->ActiveEvent);
            }
            Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);

            /* Only pay attention to key down */
            if (Input->InputEvent.EventType == KEY_EVENT &&
                Input->InputEvent.Event.KeyEvent.bKeyDown)
            {
                LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent);
                ReadControl->dwControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState;
            }
            ConsoleFreeHeap(Input);
        }

        /* Check if we have a complete line to read from */
        if (Console->LineComplete)
        {
            while (i < NumCharsToRead && Console->LinePos != Console->LineSize)
            {
                WCHAR Char = Console->LineBuffer[Console->LinePos++];

                if (Unicode)
                {
                    ((PWCHAR)Buffer)[i] = Char;
                }
                else
                {
                    ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
                }
                ++i;
            }

            if (Console->LinePos == Console->LineSize)
            {
                /* Entire line has been read */
                ConsoleFreeHeap(Console->LineBuffer);
                Console->LineBuffer = NULL;
            }

            Status = STATUS_SUCCESS;
        }
    }
    else
    {
        /* Character input */
        while (i < NumCharsToRead && !IsListEmpty(&InputBuffer->InputEvents))
        {
            /* Remove input event from queue */
            CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
            if (IsListEmpty(&InputBuffer->InputEvents))
            {
                ResetEvent(InputBuffer->ActiveEvent);
            }
            Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);

            /* Only pay attention to valid ASCII chars, on key down */
            if (Input->InputEvent.EventType == KEY_EVENT  &&
                Input->InputEvent.Event.KeyEvent.bKeyDown &&
                Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0')
            {
                WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;

                if (Unicode)
                {
                    ((PWCHAR)Buffer)[i] = Char;
                }
                else
                {
                    ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
                }
                ++i;

                /* Did read something */
                Status = STATUS_SUCCESS;
            }
            ConsoleFreeHeap(Input);
        }
    }

    if (NumCharsRead) *NumCharsRead = i;

    return Status;
}
Exemplo n.º 20
0
static NTSTATUS NTAPI
ConSrvTermReadStream(IN OUT PTERMINAL This,
                     IN BOOLEAN Unicode,
                     /**PWCHAR Buffer,**/
                     OUT PVOID Buffer,
                     IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
                     IN PVOID Parameter OPTIONAL,
                     IN ULONG NumCharsToRead,
                     OUT PULONG NumCharsRead OPTIONAL)
{
    PFRONTEND FrontEnd = This->Context;
    PCONSRV_CONSOLE Console = FrontEnd->Console;
    PCONSOLE_INPUT_BUFFER InputBuffer = &Console->InputBuffer;
    PUNICODE_STRING ExeName = Parameter;

    // STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait.
    NTSTATUS Status = STATUS_PENDING;

    PLIST_ENTRY CurrentEntry;
    ConsoleInput *Input;
    ULONG i;

    /* Validity checks */
    // ASSERT(Console == InputBuffer->Header.Console);
    ASSERT((Buffer != NULL) || (Buffer == NULL && NumCharsToRead == 0));

    /* We haven't read anything (yet) */
    i = ReadControl->nInitialChars;

    if (InputBuffer->Mode & ENABLE_LINE_INPUT)
    {
        /* COOKED mode, call the line discipline */

        if (Console->LineBuffer == NULL)
        {
            /* Starting a new line */
            Console->LineMaxSize = max(256, NumCharsToRead);

            Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * sizeof(WCHAR));
            if (Console->LineBuffer == NULL) return STATUS_NO_MEMORY;

            Console->LinePos = Console->LineSize = ReadControl->nInitialChars;
            Console->LineComplete = Console->LineUpPressed = FALSE;
            Console->LineInsertToggle = Console->InsertMode;
            Console->LineWakeupMask = ReadControl->dwCtrlWakeupMask;

            /*
             * Pre-filling the buffer is only allowed in the Unicode API,
             * so we don't need to worry about ANSI <-> Unicode conversion.
             */
            memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR));
            if (Console->LineSize == Console->LineMaxSize)
            {
                Console->LineComplete = TRUE;
                Console->LinePos = 0;
            }
        }

        /* If we don't have a complete line yet, process the pending input */
        while (!Console->LineComplete && !IsListEmpty(&InputBuffer->InputEvents))
        {
            /* Remove input event from queue */
            CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
            if (IsListEmpty(&InputBuffer->InputEvents))
            {
                ResetEvent(InputBuffer->ActiveEvent);
            }
            Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);

            /* Only pay attention to key down */
            if (Input->InputEvent.EventType == KEY_EVENT &&
                    Input->InputEvent.Event.KeyEvent.bKeyDown)
            {
                LineInputKeyDown(Console, ExeName,
                                 &Input->InputEvent.Event.KeyEvent);
                ReadControl->dwControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState;
            }
            ConsoleFreeHeap(Input);
        }

        /* Check if we have a complete line to read from */
        if (Console->LineComplete)
        {
            while (i < NumCharsToRead && Console->LinePos != Console->LineSize)
            {
                WCHAR Char = Console->LineBuffer[Console->LinePos++];

                if (Unicode)
                {
                    ((PWCHAR)Buffer)[i] = Char;
                }
                else
                {
                    ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
                }
                ++i;
            }

            if (Console->LinePos == Console->LineSize)
            {
                /* Entire line has been read */
                ConsoleFreeHeap(Console->LineBuffer);
                Console->LineBuffer = NULL;
            }

            Status = STATUS_SUCCESS;
        }
    }
    else
    {
        /* RAW mode */

        /* Character input */
        while (i < NumCharsToRead && !IsListEmpty(&InputBuffer->InputEvents))
        {
            /* Remove input event from queue */
            CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
            if (IsListEmpty(&InputBuffer->InputEvents))
            {
                ResetEvent(InputBuffer->ActiveEvent);
            }
            Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);

            /* Only pay attention to valid characters, on key down */
            if (Input->InputEvent.EventType == KEY_EVENT  &&
                    Input->InputEvent.Event.KeyEvent.bKeyDown &&
                    Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0')
            {
                WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;

                if (Unicode)
                {
                    ((PWCHAR)Buffer)[i] = Char;
                }
                else
                {
                    ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
                }
                ++i;

                /* Did read something */
                Status = STATUS_SUCCESS;
            }
            ConsoleFreeHeap(Input);
        }
    }

    // FIXME: Only set if Status == STATUS_SUCCESS ???
    if (NumCharsRead) *NumCharsRead = i;

    return Status;
}
Exemplo n.º 21
0
NTSTATUS
GRAPHICS_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
                           IN OUT PCONSOLE Console,
                           IN PGRAPHICS_BUFFER_INFO GraphicsInfo)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PGRAPHICS_SCREEN_BUFFER NewBuffer = NULL;

    LARGE_INTEGER SectionSize;
    ULONG ViewSize = 0;
    HANDLE ProcessHandle;

    if (Buffer == NULL || Console == NULL || GraphicsInfo == NULL)
        return STATUS_INVALID_PARAMETER;

    *Buffer = NULL;

    Status = CONSOLE_SCREEN_BUFFER_Initialize((PCONSOLE_SCREEN_BUFFER*)&NewBuffer,
                                              Console,
                                              sizeof(GRAPHICS_SCREEN_BUFFER));
    if (!NT_SUCCESS(Status)) return Status;
    NewBuffer->Header.Type = GRAPHICS_BUFFER;
    NewBuffer->Vtbl = &GraphicsVtbl;

    /*
     * Remember the handle to the process so that we can close or unmap
     * correctly the allocated resources when the client releases the
     * screen buffer.
     */
    ProcessHandle = CsrGetClientThread()->Process->ProcessHandle;
    NewBuffer->ClientProcess = ProcessHandle;

    /* Get infos from the graphics buffer information structure */
    NewBuffer->BitMapInfoLength = GraphicsInfo->Info.dwBitMapInfoLength;

    NewBuffer->BitMapInfo = ConsoleAllocHeap(HEAP_ZERO_MEMORY, NewBuffer->BitMapInfoLength);
    if (NewBuffer->BitMapInfo == NULL)
    {
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Adjust the bitmap height if needed (bottom-top vs. top-bottom). Use always bottom-up. */
    if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight > 0)
        GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight = -GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight;

    /* We do not use anything else than uncompressed bitmaps */
    if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression != BI_RGB)
    {
        DPRINT1("biCompression == %d != BI_RGB, correct that!\n", GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression);
        GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression = BI_RGB;
    }

    RtlCopyMemory(NewBuffer->BitMapInfo,
                  GraphicsInfo->Info.lpBitMapInfo,
                  GraphicsInfo->Info.dwBitMapInfoLength);

    NewBuffer->BitMapUsage = GraphicsInfo->Info.dwUsage;

    /* Set the screen buffer size. Fight against overflows. */
    if ( GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biWidth  <= 0xFFFF &&
        -GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight <= 0xFFFF )
    {
        /* Be careful about the sign of biHeight */
        NewBuffer->ScreenBufferSize.X =  (SHORT)GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biWidth ;
        NewBuffer->ScreenBufferSize.Y = (SHORT)-GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight;

        NewBuffer->OldViewSize = NewBuffer->ViewSize = 
            NewBuffer->OldScreenBufferSize = NewBuffer->ScreenBufferSize;
    }
    else
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Create a mutex to synchronize bitmap memory access
     * between ourselves and the client.
     */
    Status = NtCreateMutant(&NewBuffer->Mutex, MUTANT_ALL_ACCESS, NULL, FALSE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtCreateMutant() failed: %lu\n", Status);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Duplicate the Mutex for the client. We must keep a trace of it
     * so that we can close it when the client releases the screen buffer.
     */
    Status = NtDuplicateObject(NtCurrentProcess(),
                               NewBuffer->Mutex,
                               ProcessHandle,
                               &NewBuffer->ClientMutex,
                               0, 0, DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
        NtClose(NewBuffer->Mutex);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Create a memory section for the bitmap area, to share with the client.
     */
    SectionSize.QuadPart = NewBuffer->BitMapInfo->bmiHeader.biSizeImage;
    Status = NtCreateSection(&NewBuffer->hSection,
                             SECTION_ALL_ACCESS,
                             NULL,
                             &SectionSize,
                             PAGE_READWRITE,
                             SEC_COMMIT,
                             NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to create a shared section ; Status = %lu\n", Status);
        NtClose(NewBuffer->ClientMutex);
        NtClose(NewBuffer->Mutex);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Create a view for our needs.
     */
    ViewSize = 0;
    NewBuffer->BitMap = NULL;
    Status = NtMapViewOfSection(NewBuffer->hSection,
                                NtCurrentProcess(),
                                (PVOID*)&NewBuffer->BitMap,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status);
        NtClose(NewBuffer->hSection);
        NtClose(NewBuffer->ClientMutex);
        NtClose(NewBuffer->Mutex);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Create a view for the client. We must keep a trace of it so that
     * we can unmap it when the client releases the screen buffer.
     */
    ViewSize = 0;
    NewBuffer->ClientBitMap = NULL;
    Status = NtMapViewOfSection(NewBuffer->hSection,
                                ProcessHandle,
                                (PVOID*)&NewBuffer->ClientBitMap,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status);
        NtUnmapViewOfSection(NtCurrentProcess(), NewBuffer->BitMap);
        NtClose(NewBuffer->hSection);
        NtClose(NewBuffer->ClientMutex);
        NtClose(NewBuffer->Mutex);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    NewBuffer->ViewOrigin.X = NewBuffer->ViewOrigin.Y = 0;
    NewBuffer->VirtualY = 0;

    NewBuffer->CursorBlinkOn  = FALSE;
    NewBuffer->ForceCursorOff = TRUE;
    NewBuffer->CursorInfo.bVisible = FALSE;
    NewBuffer->CursorInfo.dwSize   = 0;
    NewBuffer->CursorPosition.X = NewBuffer->CursorPosition.Y = 0;

    NewBuffer->Mode = 0;

    *Buffer = (PCONSOLE_SCREEN_BUFFER)NewBuffer;
    Status = STATUS_SUCCESS;

Quit:
    return Status;
}
Exemplo n.º 22
0
static NTSTATUS NTAPI
GuiInitFrontEnd(IN OUT PFRONTEND This,
                IN PCONSRV_CONSOLE Console)
{
    PGUI_INIT_INFO GuiInitInfo;
    PGUI_CONSOLE_DATA GuiData;

    if (This == NULL || Console == NULL || This->Context2 == NULL)
        return STATUS_INVALID_PARAMETER;

    ASSERT(This->Console == Console);

    GuiInitInfo = This->Context2;

    /* Terminal data allocation */
    GuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(*GuiData));
    if (!GuiData)
    {
        DPRINT1("CONSRV: Failed to create GUI_CONSOLE_DATA\n");
        return STATUS_UNSUCCESSFUL;
    }
    /// /* HACK */ Console->FrontEndIFace.Context = (PVOID)GuiData; /* HACK */
    GuiData->Console      = Console;
    GuiData->ActiveBuffer = Console->ActiveBuffer;
    GuiData->hWindow = NULL;
    GuiData->IsWindowVisible = GuiInitInfo->IsWindowVisible;

    /* The console can be resized */
    Console->FixedSize = FALSE;

    InitializeCriticalSection(&GuiData->Lock);

    /*
     * Set up GUI data
     */
    RtlCopyMemory(&GuiData->GuiInfo, &GuiInitInfo->TermInfo, sizeof(GuiInitInfo->TermInfo));

    /* Initialize the icon handles */
    if (GuiInitInfo->hIcon != NULL)
        GuiData->hIcon = GuiInitInfo->hIcon;
    else
        GuiData->hIcon = ghDefaultIcon;

    if (GuiInitInfo->hIconSm != NULL)
        GuiData->hIconSm = GuiInitInfo->hIconSm;
    else
        GuiData->hIconSm = ghDefaultIconSm;

    ASSERT(GuiData->hIcon && GuiData->hIconSm);

    /* Mouse is shown by default with its default cursor shape */
    GuiData->hCursor = ghDefaultCursor;
    GuiData->MouseCursorRefCount = 0;

    /* A priori don't ignore mouse signals */
    GuiData->IgnoreNextMouseSignal = FALSE;
    /* Initialize HACK FOR CORE-8394. See conwnd.c!OnMouse for more details. */
    GuiData->HackCORE8394IgnoreNextMove = FALSE;

    /* Close button and the corresponding system menu item are enabled by default */
    GuiData->IsCloseButtonEnabled = TRUE;

    /* There is no user-reserved menu id range by default */
    GuiData->CmdIdLow = GuiData->CmdIdHigh = 0;

    /* Initialize the selection */
    RtlZeroMemory(&GuiData->Selection, sizeof(GuiData->Selection));
    GuiData->Selection.dwFlags = CONSOLE_NO_SELECTION;
    RtlZeroMemory(&GuiData->dwSelectionCursor, sizeof(GuiData->dwSelectionCursor));
    GuiData->LineSelection = FALSE; // Default to block selection
    // TODO: Retrieve the selection mode via the registry.

    GuiData->InputThreadId = GuiInitInfo->InputThreadId;
    GuiData->WinSta  = GuiInitInfo->WinSta;
    GuiData->Desktop = GuiInitInfo->Desktop;

    /* Finally, finish to initialize the frontend structure */
    This->Context  = GuiData;
    ConsoleFreeHeap(This->Context2);
    This->Context2 = NULL;

    /*
     * We need to wait until the GUI has been fully initialized
     * to retrieve custom settings i.e. WindowSize etc...
     * Ideally we could use SendNotifyMessage for this but its not
     * yet implemented.
     */
    NtCreateEvent(&GuiData->hGuiInitEvent, EVENT_ALL_ACCESS,
                  NULL, SynchronizationEvent, FALSE);
    NtCreateEvent(&GuiData->hGuiTermEvent, EVENT_ALL_ACCESS,
                  NULL, SynchronizationEvent, FALSE);

    DPRINT("GUI - Checkpoint\n");

    /* Create the terminal window */
    PostThreadMessageW(GuiData->InputThreadId, PM_CREATE_CONSOLE, 0, (LPARAM)GuiData);

    /* Wait until initialization has finished */
    NtWaitForSingleObject(GuiData->hGuiInitEvent, FALSE, NULL);
    DPRINT("OK we created the console window\n");
    NtClose(GuiData->hGuiInitEvent);
    GuiData->hGuiInitEvent = NULL;

    /* Check whether we really succeeded in initializing the terminal window */
    if (GuiData->hWindow == NULL)
    {
        DPRINT("GuiInitConsole - We failed at creating a new terminal window\n");
        GuiDeinitFrontEnd(This);
        return STATUS_UNSUCCESSFUL;
    }

    return STATUS_SUCCESS;
}
Exemplo n.º 23
0
static PALIAS_ENTRY
IntCreateAliasEntry(PCONSRV_CONSOLE Console,
                    PVOID    Source,
                    USHORT   SourceLength,
                    PVOID    Target,
                    USHORT   TargetLength,
                    BOOLEAN  Unicode)
{
    UNICODE_STRING SourceU;
    UNICODE_STRING TargetU;

    PALIAS_ENTRY Entry;

    if (Unicode)
    {
        SourceU.Buffer = Source;
        TargetU.Buffer = Target;
        /* Length is in bytes */
        SourceU.MaximumLength = SourceLength;
        TargetU.MaximumLength = TargetLength;
    }
    else
    {
        if (!ConvertInputAnsiToUnicode(Console,
                                       Source, SourceLength,
                                       &SourceU.Buffer, &SourceU.MaximumLength))
        {
            return NULL;
        }

        if (!ConvertInputAnsiToUnicode(Console,
                                       Target, TargetLength,
                                       &TargetU.Buffer, &TargetU.MaximumLength))
        {
            ConsoleFreeHeap(SourceU.Buffer);
            return NULL;
        }
    }
    SourceU.Length = SourceU.MaximumLength;
    TargetU.Length = TargetU.MaximumLength;

    Entry = ConsoleAllocHeap(0, sizeof(ALIAS_ENTRY) +
                                SourceU.Length + TargetU.Length);
    if (!Entry)
    {
        if (!Unicode)
        {
            ConsoleFreeHeap(TargetU.Buffer);
            ConsoleFreeHeap(SourceU.Buffer);
        }
        return Entry;
    }

    Entry->Source.Buffer = (PWSTR)(Entry + 1);
    Entry->Source.Length = 0;
    Entry->Source.MaximumLength = SourceU.Length;
    RtlCopyUnicodeString(&Entry->Source, &SourceU);

    Entry->Target.Buffer = (PWSTR)((ULONG_PTR)Entry->Source.Buffer + Entry->Source.MaximumLength);
    Entry->Target.Length = 0;
    Entry->Target.MaximumLength = TargetU.Length;
    RtlCopyUnicodeString(&Entry->Target, &TargetU);

    Entry->Next = NULL;

    if (!Unicode)
    {
        ConsoleFreeHeap(TargetU.Buffer);
        ConsoleFreeHeap(SourceU.Buffer);
    }
    return Entry;
}
Exemplo n.º 24
0
NTSTATUS NTAPI
ConDrvInitConsole(OUT PCONSOLE* NewConsole,
                  IN PCONSOLE_INFO ConsoleInfo)
{
    NTSTATUS Status;
    // CONSOLE_INFO CapturedConsoleInfo;
    TEXTMODE_BUFFER_INFO ScreenBufferInfo;
    PCONSOLE Console;
    PCONSOLE_SCREEN_BUFFER NewBuffer;

    if (NewConsole == NULL || ConsoleInfo == NULL)
        return STATUS_INVALID_PARAMETER;

    *NewConsole = NULL;

    /*
     * Allocate a new console
     */
    Console = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(*Console));
    if (NULL == Console)
    {
        DPRINT1("Not enough memory for console creation.\n");
        return STATUS_NO_MEMORY;
    }

    /*
     * Fix the screen buffer size if needed. The rule is:
     * ScreenBufferSize >= ConsoleSize
     */
    if (ConsoleInfo->ScreenBufferSize.X < ConsoleInfo->ConsoleSize.X)
        ConsoleInfo->ScreenBufferSize.X = ConsoleInfo->ConsoleSize.X;
    if (ConsoleInfo->ScreenBufferSize.Y < ConsoleInfo->ConsoleSize.Y)
        ConsoleInfo->ScreenBufferSize.Y = ConsoleInfo->ConsoleSize.Y;

    /*
     * Initialize the console
     */
    Console->State = CONSOLE_INITIALIZING;
    Console->ReferenceCount = 0;
    InitializeCriticalSection(&Console->Lock);

    /* Initialize the terminal interface */
    ResetTerminal(Console);

    Console->ConsoleSize = ConsoleInfo->ConsoleSize;
    Console->FixedSize   = FALSE; // Value by default; is reseted by the terminals if needed.

    /* 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;
    }

    /* Set-up the code page */
    Console->InputCodePage = Console->OutputCodePage = ConsoleInfo->CodePage;

    /* Initialize a new text-mode screen buffer with default settings */
    ScreenBufferInfo.ScreenBufferSize = ConsoleInfo->ScreenBufferSize;
    ScreenBufferInfo.ScreenAttrib     = ConsoleInfo->ScreenAttrib;
    ScreenBufferInfo.PopupAttrib      = ConsoleInfo->PopupAttrib;
    ScreenBufferInfo.IsCursorVisible  = TRUE;
    ScreenBufferInfo.CursorSize       = ConsoleInfo->CursorSize;

    InitializeListHead(&Console->BufferList);
    Status = ConDrvCreateScreenBuffer(&NewBuffer,
                                      Console,
                                      NULL,
                                      CONSOLE_TEXTMODE_BUFFER,
                                      &ScreenBufferInfo);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("ConDrvCreateScreenBuffer: failed, Status = 0x%08lx\n", Status);
        ConDrvDeinitInputBuffer(Console);
        DeleteCriticalSection(&Console->Lock);
        ConsoleFreeHeap(Console);
        return Status;
    }
    /* Make the new screen buffer active */
    Console->ActiveBuffer = NewBuffer;
    Console->UnpauseEvent = NULL;

    DPRINT("Console initialized\n");

    /* All went right, so add the console to the list */
    Status = InsertConsole(Console);
    if (!NT_SUCCESS(Status))
    {
        /* Fail */
        ConDrvDeleteConsole(Console);
        return Status;
    }

    /* The initialization is finished */
    DPRINT("Change state\n");
    Console->State = CONSOLE_RUNNING;

    /* Return the newly created console to the caller and a success code too */
    *NewConsole = Console;
    return STATUS_SUCCESS;
}
Exemplo n.º 25
0
Arquivo: init.c Projeto: GYGit/reactos
NTSTATUS
NTAPI
ConSrvConnect(IN PCSR_PROCESS CsrProcess,
              IN OUT PVOID ConnectionInfo,
              IN OUT PULONG ConnectionInfoLength)
{
    /**************************************************************************
     * This function is called whenever a CUI new process is created.
     **************************************************************************/

    NTSTATUS Status = STATUS_SUCCESS;
    PCONSRV_API_CONNECTINFO ConnectInfo = (PCONSRV_API_CONNECTINFO)ConnectionInfo;
    PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);

    if ( ConnectionInfo       == NULL ||
         ConnectionInfoLength == NULL ||
        *ConnectionInfoLength != sizeof(*ConnectInfo) )
    {
        DPRINT1("CONSRV: Connection failed - ConnectionInfo = 0x%p ; ConnectionInfoLength = 0x%p (%lu), expected %lu\n",
                ConnectionInfo,
                ConnectionInfoLength,
                ConnectionInfoLength ? *ConnectionInfoLength : (ULONG)-1,
                sizeof(*ConnectInfo));

        return STATUS_UNSUCCESSFUL;
    }

    /* If we don't need a console, then get out of here */
    DPRINT("ConnectInfo->IsConsoleApp = %s\n", ConnectInfo->IsConsoleApp ? "True" : "False");
    if (!ConnectInfo->IsConsoleApp) return STATUS_SUCCESS;

    /* If we don't inherit from an existing console, then create a new one... */
    if (ConnectInfo->ConsoleStartInfo.ConsoleHandle == NULL)
    {
        CONSOLE_INIT_INFO ConsoleInitInfo;

        DPRINT("ConSrvConnect - Allocate a new console\n");

        /* Initialize the console initialization info structure */
        ConsoleInitInfo.ConsoleStartInfo = &ConnectInfo->ConsoleStartInfo;
        ConsoleInitInfo.IsWindowVisible  = ConnectInfo->IsWindowVisible;
        ConsoleInitInfo.TitleLength      = ConnectInfo->TitleLength;
        ConsoleInitInfo.ConsoleTitle     = ConnectInfo->ConsoleTitle;
        ConsoleInitInfo.DesktopLength    = 0;
        ConsoleInitInfo.Desktop          = NULL;
        ConsoleInitInfo.AppNameLength    = ConnectInfo->AppNameLength;
        ConsoleInitInfo.AppName          = ConnectInfo->AppName;
        ConsoleInitInfo.CurDirLength     = ConnectInfo->CurDirLength;
        ConsoleInitInfo.CurDir           = ConnectInfo->CurDir;

        /*
         * Contrary to the case of SrvAllocConsole, the desktop string is
         * allocated in the process' heap, so we need to retrieve it by
         * using NtReadVirtualMemory.
         */
        if (ConnectInfo->DesktopLength)
        {
            ConsoleInitInfo.DesktopLength = ConnectInfo->DesktopLength;

            ConsoleInitInfo.Desktop = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
                                                       ConsoleInitInfo.DesktopLength);
            if (ConsoleInitInfo.Desktop == NULL)
                return STATUS_NO_MEMORY;

            Status = NtReadVirtualMemory(ProcessData->Process->ProcessHandle,
                                         ConnectInfo->Desktop,
                                         ConsoleInitInfo.Desktop,
                                         ConsoleInitInfo.DesktopLength,
                                         NULL);
            if (!NT_SUCCESS(Status))
            {
                ConsoleFreeHeap(ConsoleInitInfo.Desktop);
                return Status;
            }
        }

        /*
         * 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
         * them, because we've created a new console and thus we must use it.
         *
         * ConSrvAllocateConsole will free our old handles table
         * and recreate a new valid one.
         */

        /* Initialize a new Console owned by the Console Leader Process */
        Status = ConSrvAllocateConsole(ProcessData,
                                       &ConnectInfo->ConsoleStartInfo.InputHandle,
                                       &ConnectInfo->ConsoleStartInfo.OutputHandle,
                                       &ConnectInfo->ConsoleStartInfo.ErrorHandle,
                                       &ConsoleInitInfo);

        /* Free our local desktop string if any */
        if (ConsoleInitInfo.DesktopLength)
            ConsoleFreeHeap(ConsoleInitInfo.Desktop);

        /* Check for success */
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Console allocation failed\n");
            return Status;
        }
    }
    else /* We inherit it from the parent */
    {
        DPRINT("ConSrvConnect - Reuse current (parent's) console\n");

        /* Reuse our current console */
        Status = ConSrvInheritConsole(ProcessData,
                                      ConnectInfo->ConsoleStartInfo.ConsoleHandle,
                                      FALSE,
                                      NULL, // &ConnectInfo->ConsoleStartInfo.InputHandle,
                                      NULL, // &ConnectInfo->ConsoleStartInfo.OutputHandle,
                                      NULL, // &ConnectInfo->ConsoleStartInfo.ErrorHandle,
                                      &ConnectInfo->ConsoleStartInfo);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Console inheritance failed\n");
            return Status;
        }
    }

    /* Set the Property-Dialog and Control-Dispatcher handlers */
    ProcessData->PropRoutine = ConnectInfo->PropRoutine;
    ProcessData->CtrlRoutine = ConnectInfo->CtrlRoutine;

    return STATUS_SUCCESS;
}
Exemplo n.º 26
0
NTSTATUS NTAPI
GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
                IN OUT PCONSOLE_STATE_INFO ConsoleInfo,
                IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
                IN HANDLE ConsoleLeaderProcessHandle)
{
    PCONSOLE_START_INFO ConsoleStartInfo;
    PGUI_INIT_INFO GuiInitInfo;

    if (FrontEnd == NULL || ConsoleInfo == NULL || ConsoleInitInfo == NULL)
        return STATUS_INVALID_PARAMETER;

    ConsoleStartInfo = ConsoleInitInfo->ConsoleStartInfo;

    /*
     * Initialize a private initialization info structure for later use.
     * It must be freed by a call to GuiUnloadFrontEnd or GuiInitFrontEnd.
     */
    GuiInitInfo = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(*GuiInitInfo));
    if (GuiInitInfo == NULL) return STATUS_NO_MEMORY;

    /* Initialize GUI terminal emulator common functionalities */
    if (!GuiInit(ConsoleInitInfo, ConsoleLeaderProcessHandle, GuiInitInfo))
    {
        ConsoleFreeHeap(GuiInitInfo);
        return STATUS_UNSUCCESSFUL;
    }

    /*
     * Load terminal settings
     */
#if 0
    /* Impersonate the caller in order to retrieve settings in its context */
    // if (!CsrImpersonateClient(NULL))
    // return STATUS_UNSUCCESSFUL;
    CsrImpersonateClient(NULL);

    /* 1. Load the default settings */
    GuiConsoleGetDefaultSettings(&GuiInitInfo->TermInfo);
#endif

    GuiInitInfo->TermInfo.ShowWindow = SW_SHOWNORMAL;

    if (ConsoleInitInfo->IsWindowVisible)
    {
        /* 2. Load the remaining console settings via the registry */
        if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
        {
#if 0
            /* Load the terminal infos from the registry */
            GuiConsoleReadUserSettings(&GuiInitInfo->TermInfo);
#endif

            /*
             * 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_USESHOWWINDOW)
            {
                GuiInitInfo->TermInfo.ShowWindow = ConsoleStartInfo->wShowWindow;
            }
            if (ConsoleStartInfo->dwStartupFlags & STARTF_USEPOSITION)
            {
                ConsoleInfo->AutoPosition = FALSE;
                ConsoleInfo->WindowPosition.x = ConsoleStartInfo->dwWindowOrigin.X;
                ConsoleInfo->WindowPosition.y = ConsoleStartInfo->dwWindowOrigin.Y;
            }
            if (ConsoleStartInfo->dwStartupFlags & STARTF_RUNFULLSCREEN)
            {
                ConsoleInfo->FullScreen = TRUE;
            }
        }
    }

#if 0
    /* Revert impersonation */
    CsrRevertToSelf();
#endif

    // Font data
    wcsncpy(GuiInitInfo->TermInfo.FaceName, ConsoleInfo->FaceName, LF_FACESIZE);
    GuiInitInfo->TermInfo.FaceName[LF_FACESIZE - 1] = UNICODE_NULL;
    GuiInitInfo->TermInfo.FontFamily = ConsoleInfo->FontFamily;
    GuiInitInfo->TermInfo.FontSize   = ConsoleInfo->FontSize;
    GuiInitInfo->TermInfo.FontWeight = ConsoleInfo->FontWeight;

    // Display
    GuiInitInfo->TermInfo.FullScreen   = ConsoleInfo->FullScreen;
    // GuiInitInfo->TermInfo.ShowWindow;
    GuiInitInfo->TermInfo.AutoPosition = ConsoleInfo->AutoPosition;
    GuiInitInfo->TermInfo.WindowOrigin = ConsoleInfo->WindowPosition;

    /* Initialize the icon handles */
    // if (ConsoleStartInfo->hIcon != NULL)
    GuiInitInfo->hIcon = ConsoleStartInfo->hIcon;
    // else
    // GuiInitInfo->hIcon = ghDefaultIcon;

    // if (ConsoleStartInfo->hIconSm != NULL)
    GuiInitInfo->hIconSm = ConsoleStartInfo->hIconSm;
    // else
    // GuiInitInfo->hIconSm = ghDefaultIconSm;

    // ASSERT(GuiInitInfo->hIcon && GuiInitInfo->hIconSm);

    GuiInitInfo->IsWindowVisible = ConsoleInitInfo->IsWindowVisible;

    /* Finally, initialize the frontend structure */
    FrontEnd->Vtbl     = &GuiVtbl;
    FrontEnd->Context  = NULL;
    FrontEnd->Context2 = GuiInitInfo;

    return STATUS_SUCCESS;
}