コード例 #1
0
ファイル: winsta.c プロジェクト: reactos/reactos
BOOL APIENTRY
NtUserSetProcessWindowStation(HWINSTA hWindowStation)
{
    BOOL ret;

    UserEnterExclusive();

    ret = UserSetProcessWindowStation(hWindowStation);

    UserLeave();

    return ret;
}
コード例 #2
0
ファイル: main.c プロジェクト: hackbunny/reactos
NTSTATUS
APIENTRY
Win32kProcessCallback(struct _EPROCESS *Process,
                      BOOLEAN Create)
{
    PPROCESSINFO ppiCurrent, *pppi;
    NTSTATUS Status;

    ASSERT(Process->Peb);

    UserEnterExclusive();

    if (Create)
    {
        SIZE_T ViewSize = 0;
        LARGE_INTEGER Offset;
        PVOID UserBase = NULL;
        PRTL_USER_PROCESS_PARAMETERS pParams = Process->Peb->ProcessParameters;

        /* We might be called with an already allocated win32 process */
        ppiCurrent = PsGetProcessWin32Process(Process);
        if (ppiCurrent != NULL)
        {
            /* There is no more to do for us (this is a success code!) */
            Status = STATUS_ALREADY_WIN32;
            goto Leave;
        }

        /* Allocate a new win32 process */
        ppiCurrent = ExAllocatePoolWithTag(NonPagedPool,
                                           sizeof(PROCESSINFO),
                                           USERTAG_PROCESSINFO);
        if (ppiCurrent == NULL)
        {
            ERR_CH(UserProcess, "Failed to allocate ppi for PID:0x%lx\n",
                   HandleToUlong(Process->UniqueProcessId));
            Status = STATUS_NO_MEMORY;
            goto Leave;
        }

        RtlZeroMemory(ppiCurrent, sizeof(PROCESSINFO));

        PsSetProcessWin32Process(Process, ppiCurrent, NULL);

#if DBG
        DbgInitDebugChannels();
#if KDBG
        KdRosRegisterCliCallback(DbgGdiKdbgCliCallback);
#endif
#endif

        TRACE_CH(UserProcess,"Allocated ppi 0x%p for PID:0x%lx\n", ppiCurrent, HandleToUlong(Process->UniqueProcessId));

        /* map the global heap into the process */
        Offset.QuadPart = 0;
        Status = MmMapViewOfSection(GlobalUserHeapSection,
                                    PsGetCurrentProcess(),
                                    &UserBase,
                                    0,
                                    0,
                                    &Offset,
                                    &ViewSize,
                                    ViewUnmap,
                                    SEC_NO_CHANGE,
                                    PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but thanks to RTL heaps... */
        if (!NT_SUCCESS(Status))
        {
            TRACE_CH(UserProcess,"Failed to map the global heap! 0x%x\n", Status);
            goto Leave;
        }
        ppiCurrent->HeapMappings.Next = NULL;
        ppiCurrent->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap;
        ppiCurrent->HeapMappings.UserMapping = UserBase;
        ppiCurrent->HeapMappings.Count = 1;

        InitializeListHead(&ppiCurrent->MenuListHead);

        InitializeListHead(&ppiCurrent->GDIBrushAttrFreeList);
        InitializeListHead(&ppiCurrent->GDIDcAttrFreeList);

        InitializeListHead(&ppiCurrent->PrivateFontListHead);
        ExInitializeFastMutex(&ppiCurrent->PrivateFontListLock);

        InitializeListHead(&ppiCurrent->DriverObjListHead);
        ExInitializeFastMutex(&ppiCurrent->DriverObjListLock);

        ppiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout();
        if (!EngCreateEvent((PEVENT *)&ppiCurrent->InputIdleEvent))
        {
            KeBugCheck(0);
        }

        KeInitializeEvent(ppiCurrent->InputIdleEvent, NotificationEvent, FALSE);


        /* map the gdi handle table to user land */
        Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(Process);
        Process->Peb->GdiDCAttributeList = GDI_BATCH_LIMIT;
        pParams = Process->Peb->ProcessParameters;

        ppiCurrent->peProcess = Process;
        /* setup process flags */
        ppiCurrent->W32PF_flags = W32PF_THREADCONNECTED;

        if ( pParams &&
                pParams->WindowFlags & STARTF_SCRNSAVER )
        {
            ppiScrnSaver = ppiCurrent;
            ppiCurrent->W32PF_flags |= W32PF_SCREENSAVER;
        }

        // Fixme check if this process is allowed.
        ppiCurrent->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; // Starting application it will get toggled off.

        /* Create pools for GDI object attributes */
        ppiCurrent->pPoolDcAttr = GdiPoolCreate(sizeof(DC_ATTR), 'acdG');
        ppiCurrent->pPoolBrushAttr = GdiPoolCreate(sizeof(BRUSH_ATTR), 'arbG');
        ppiCurrent->pPoolRgnAttr = GdiPoolCreate(sizeof(RGN_ATTR), 'agrG');
        ASSERT(ppiCurrent->pPoolDcAttr);
        ASSERT(ppiCurrent->pPoolBrushAttr);
        ASSERT(ppiCurrent->pPoolRgnAttr);

        /* Add the process to the global list */
        ppiCurrent->ppiNext = gppiList;
        gppiList = ppiCurrent;
    }
    else
    {
        /* Get the Win32 Process */
        ppiCurrent = PsGetProcessWin32Process(Process);

        ASSERT(ppiCurrent);

        TRACE_CH(UserProcess, "Destroying ppi 0x%p\n", ppiCurrent);
        ppiCurrent->W32PF_flags |= W32PF_TERMINATED;

        if (ppiScrnSaver == ppiCurrent)
            ppiScrnSaver = NULL;

        if (ppiCurrent->InputIdleEvent)
        {
            EngFreeMem(ppiCurrent->InputIdleEvent);
            ppiCurrent->InputIdleEvent = NULL;
        }

        IntCleanupMenus(Process, ppiCurrent);
        IntCleanupCurIcons(Process, ppiCurrent);


        GDI_CleanupForProcess(Process);

        co_IntGraphicsCheck(FALSE);

        /*
         * Deregister logon application automatically
         */
        if(LogonProcess == ppiCurrent)
        {
            LogonProcess = NULL;
        }

        /* Close the startup desktop */
        if(ppiCurrent->rpdeskStartup)
            ObDereferenceObject(ppiCurrent->rpdeskStartup);
        if(ppiCurrent->hdeskStartup)
            ZwClose(ppiCurrent->hdeskStartup);

        /* Close the current window station */
        UserSetProcessWindowStation(NULL);

        /* Destroy GDI pools */
        GdiPoolDestroy(ppiCurrent->pPoolDcAttr);
        GdiPoolDestroy(ppiCurrent->pPoolBrushAttr);
        GdiPoolDestroy(ppiCurrent->pPoolRgnAttr);

        if (gppiInputProvider == ppiCurrent) gppiInputProvider = NULL;

        pppi = &gppiList;
        while (*pppi != NULL && *pppi != ppiCurrent)
            pppi = &(*pppi)->ppiNext;

        ASSERT(*pppi == ppiCurrent);

        *pppi = ppiCurrent->ppiNext;

        TRACE_CH(UserProcess,"Freeing ppi 0x%p\n", ppiCurrent);
#if DBG
        if (DBG_IS_CHANNEL_ENABLED(ppiCurrent, DbgChUserObj, WARN_LEVEL))
        {
            DbgUserDumpHandleTable();
        }
#endif

        /* Free the PROCESSINFO */
        PsSetProcessWin32Process(Process, NULL, ppiCurrent);
        ExFreePoolWithTag(ppiCurrent, USERTAG_PROCESSINFO);
    }

    Status = STATUS_SUCCESS;

Leave:
    UserLeave();
    return Status;
}
コード例 #3
0
ファイル: main.c プロジェクト: hackbunny/reactos
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;
}