Exemplo n.º 1
0
HWINSTA APIENTRY
NtUserCreateWindowStation(
    POBJECT_ATTRIBUTES ObjectAttributes,
    ACCESS_MASK dwDesiredAccess,
    DWORD Unknown2,
    DWORD Unknown3,
    DWORD Unknown4,
    DWORD Unknown5,
    DWORD Unknown6)
{
    UNICODE_STRING WindowStationName;
    PWINSTATION_OBJECT WindowStationObject;
    HWINSTA WindowStation;
    NTSTATUS Status;

    TRACE("NtUserCreateWindowStation called\n");

    Status = ObOpenObjectByName(ObjectAttributes,
                                ExWindowStationObjectType,
                                UserMode,
                                NULL,
                                dwDesiredAccess,
                                NULL,
                                (PVOID*)&WindowStation);

    if (NT_SUCCESS(Status))
    {
        TRACE("NtUserCreateWindowStation opened window station %wZ\n", ObjectAttributes->ObjectName);
        return (HWINSTA)WindowStation;
    }

    /*
     * No existing window station found, try to create new one
     */

    /* Capture window station name */
    _SEH2_TRY
    {
        ProbeForRead( ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), 1);
        Status = IntSafeCopyUnicodeStringTerminateNULL(&WindowStationName, ObjectAttributes->ObjectName);
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status =_SEH2_GetExceptionCode();
    }
    _SEH2_END

    if (! NT_SUCCESS(Status))
    {
        ERR("Failed reading capturing window station name\n");
        SetLastNtError(Status);
        return NULL;
    }

    /* Create the window station object */
    Status = ObCreateObject(UserMode,
                            ExWindowStationObjectType,
                            ObjectAttributes,
                            UserMode,
                            NULL,
                            sizeof(WINSTATION_OBJECT),
                            0,
                            0,
                            (PVOID*)&WindowStationObject);

    if (!NT_SUCCESS(Status))
    {
        ERR("ObCreateObject failed with %lx for window station %wZ\n", Status, &WindowStationName);
        ExFreePoolWithTag(WindowStationName.Buffer, TAG_STRING);
        SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
        return 0;
    }

    /* Initialize the window station */
    RtlZeroMemory(WindowStationObject, sizeof(WINSTATION_OBJECT));

    InitializeListHead(&WindowStationObject->DesktopListHead);
    WindowStationObject->Name = WindowStationName;
    WindowStationObject->dwSessionId = NtCurrentPeb()->SessionId;
    Status = RtlCreateAtomTable(37, &WindowStationObject->AtomTable);
    if (!NT_SUCCESS(Status))
    {
        ERR("RtlCreateAtomTable failed with %lx for window station %wZ\n", Status, &WindowStationName);
        ObDereferenceObject(WindowStationObject);
        SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
        return 0;
    }

    Status = ObInsertObject((PVOID)WindowStationObject,
                            NULL,
                            dwDesiredAccess,
                            0,
                            NULL,
                            (PVOID*)&WindowStation);

    if (!NT_SUCCESS(Status))
    {
        ERR("ObInsertObject failed with %lx for window station\n", Status);
        SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
        return 0;
    }

    if (InputWindowStation == NULL)
    {
        ERR("Initializing input window station\n");
        InputWindowStation = WindowStationObject;

        WindowStationObject->Flags &= ~WSS_NOIO;

        InitCursorImpl();
    }
    else
    {
        WindowStationObject->Flags |= WSS_NOIO;
    }

    TRACE("NtUserCreateWindowStation created object %p with name %wZ handle %p\n",
          WindowStation, &WindowStationObject->Name, WindowStation);
    return WindowStation;
}
Exemplo n.º 2
0
NTSTATUS NTAPI
UserCreateThreadInfo(struct _ETHREAD *Thread)
{
    struct _EPROCESS *Process;
    PCLIENTINFO pci;
    PTHREADINFO ptiCurrent;
    int i;
    NTSTATUS Status = STATUS_SUCCESS;
    PTEB pTeb;
    LARGE_INTEGER LargeTickCount;

    Process = Thread->ThreadsProcess;

    pTeb = NtCurrentTeb();

    ASSERT(pTeb);

    ptiCurrent = ExAllocatePoolWithTag(NonPagedPool,
                                       sizeof(THREADINFO),
                                       USERTAG_THREADINFO);
    if (ptiCurrent == NULL)
    {
        ERR_CH(UserThread, "Failed to allocate pti for TID %p\n", Thread->Cid.UniqueThread);
        return STATUS_NO_MEMORY;
    }

    TRACE_CH(UserThread,"Create pti 0x%p eThread 0x%p\n", ptiCurrent, Thread);

    RtlZeroMemory(ptiCurrent, sizeof(THREADINFO));

    /* Initialize the THREADINFO */

    PsSetThreadWin32Thread(Thread, ptiCurrent, NULL);
    IntReferenceThreadInfo(ptiCurrent);
    ptiCurrent->pEThread = Thread;
    ptiCurrent->ppi = PsGetCurrentProcessWin32Process();
    pTeb->Win32ThreadInfo = ptiCurrent;
    ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;

    TRACE_CH(UserThread, "Allocated pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread);

    InitializeListHead(&ptiCurrent->WindowListHead);
    InitializeListHead(&ptiCurrent->W32CallbackListHead);
    InitializeListHead(&ptiCurrent->PostedMessagesListHead);
    InitializeListHead(&ptiCurrent->SentMessagesListHead);
    InitializeListHead(&ptiCurrent->DispatchingMessagesHead);
    InitializeListHead(&ptiCurrent->LocalDispatchingMessagesHead);
    InitializeListHead(&ptiCurrent->PtiLink);
    for (i = 0; i < NB_HOOKS; i++)
    {
        InitializeListHead(&ptiCurrent->aphkStart[i]);
    }
    ptiCurrent->ptiSibling = ptiCurrent->ppi->ptiList;
    ptiCurrent->ppi->ptiList = ptiCurrent;
    ptiCurrent->ppi->cThreads++;

    ptiCurrent->hEventQueueClient = NULL;
    Status = ZwCreateEvent(&ptiCurrent->hEventQueueClient, EVENT_ALL_ACCESS,
                           NULL, SynchronizationEvent, FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto error;
    }
    Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0,
                                       *ExEventObjectType, KernelMode,
                                       (PVOID*)&ptiCurrent->pEventQueueServer, NULL);
    if (!NT_SUCCESS(Status))
    {
        ZwClose(ptiCurrent->hEventQueueClient);
        ptiCurrent->hEventQueueClient = NULL;
        goto error;
    }

    KeQueryTickCount(&LargeTickCount);
    ptiCurrent->timeLast = LargeTickCount.u.LowPart;

    ptiCurrent->MessageQueue = MsqCreateMessageQueue(ptiCurrent);
    if(ptiCurrent->MessageQueue == NULL)
    {
        ERR_CH(UserThread,"Failed to allocate message loop\n");
        Status = STATUS_NO_MEMORY;
        goto error;
    }
    ptiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout();
    if (ptiCurrent->KeyboardLayout)
        UserReferenceObject(ptiCurrent->KeyboardLayout);
    ptiCurrent->TIF_flags &= ~TIF_INCLEANUP;
    if (Process == gpepCSRSS) /* If this thread is owned by CSRSS, mark it as such */
        ptiCurrent->TIF_flags |= TIF_CSRSSTHREAD;
    ptiCurrent->pcti = &ptiCurrent->cti;

    /* Initialize the CLIENTINFO */
    pci = (PCLIENTINFO)pTeb->Win32ClientInfo;
    RtlZeroMemory(pci, sizeof(CLIENTINFO));
    pci->ppi = ptiCurrent->ppi;
    pci->fsHooks = ptiCurrent->fsHooks;
    pci->dwTIFlags = ptiCurrent->TIF_flags;
    if (ptiCurrent->KeyboardLayout)
    {
        pci->hKL = ptiCurrent->KeyboardLayout->hkl;
        pci->CodePage = ptiCurrent->KeyboardLayout->CodePage;
    }

    /* Assign a default window station and desktop to the process */
    /* Do not try to open a desktop or window station before winlogon initializes */
    if(ptiCurrent->ppi->hdeskStartup == NULL && LogonProcess != NULL)
    {
        HWINSTA hWinSta = NULL;
        HDESK hDesk = NULL;
        UNICODE_STRING DesktopPath;
        PDESKTOP pdesk;
        PRTL_USER_PROCESS_PARAMETERS ProcessParams;

        /*
         * inherit the thread desktop and process window station (if not yet inherited) from the process startup
         * info structure. See documentation of CreateProcess()
         */
        ProcessParams = pTeb->ProcessEnvironmentBlock->ProcessParameters;

        Status = STATUS_UNSUCCESSFUL;
        if(ProcessParams && ProcessParams->DesktopInfo.Length > 0)
        {
            Status = IntSafeCopyUnicodeStringTerminateNULL(&DesktopPath, &ProcessParams->DesktopInfo);
        }
        if(!NT_SUCCESS(Status))
        {
            RtlInitUnicodeString(&DesktopPath, NULL);
        }

        Status = IntParseDesktopPath(Process,
                                     &DesktopPath,
                                     &hWinSta,
                                     &hDesk);

        if (DesktopPath.Buffer)
            ExFreePoolWithTag(DesktopPath.Buffer, TAG_STRING);

        if(!NT_SUCCESS(Status))
        {
            ERR_CH(UserThread, "Failed to assign default dekstop and winsta to process\n");
            goto error;
        }

        if(!UserSetProcessWindowStation(hWinSta))
        {
            Status = STATUS_UNSUCCESSFUL;
            ERR_CH(UserThread,"Failed to set initial process winsta\n");
            goto error;
        }

        /* Validate the new desktop. */
        Status = IntValidateDesktopHandle(hDesk, UserMode, 0, &pdesk);
        if(!NT_SUCCESS(Status))
        {
            ERR_CH(UserThread,"Failed to validate initial desktop handle\n");
            goto error;
        }

        /* Store the parsed desktop as the initial desktop */
        ptiCurrent->ppi->hdeskStartup = hDesk;
        ptiCurrent->ppi->rpdeskStartup = pdesk;
    }

    if (ptiCurrent->ppi->hdeskStartup != NULL)
    {
        if (!IntSetThreadDesktop(ptiCurrent->ppi->hdeskStartup, FALSE))
        {
            ERR_CH(UserThread,"Failed to set thread desktop\n");
            Status = STATUS_UNSUCCESSFUL;
            goto error;
        }
    }

    /* mark the thread as fully initialized */
    ptiCurrent->TIF_flags |= TIF_GUITHREADINITIALIZED;

    if (!(ptiCurrent->ppi->W32PF_flags & (W32PF_ALLOWFOREGROUNDACTIVATE | W32PF_APPSTARTING)) &&
            (gptiForeground && gptiForeground->ppi == ptiCurrent->ppi ))
    {
        ptiCurrent->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
    }
    ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
    TRACE_CH(UserThread,"UserCreateW32Thread pti 0x%p\n",ptiCurrent);
    return STATUS_SUCCESS;

error:
    ERR_CH(UserThread,"UserCreateThreadInfo failed! Freeing pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread);
    UserDestroyThreadInfo(Thread);
    return Status;
}