Beispiel #1
0
__inline static PUSER_HANDLE_ENTRY alloc_user_entry(PUSER_HANDLE_TABLE ht)
{
   PUSER_HANDLE_ENTRY entry;
   PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
   TRACE("handles used %lu\n", gpsi->cHandleEntries);

   if (ht->freelist)
   {
      entry = ht->freelist;
      ht->freelist = entry->ptr;

      gpsi->cHandleEntries++;
      ppi->UserHandleCount++;
      return entry;
   }

   if (ht->nb_handles >= ht->allocated_handles)  /* Need to grow the array */
   {
       ERR("Out of user handles! Used -> %lu, NM_Handle -> %d\n", gpsi->cHandleEntries, ht->nb_handles);

#if DBG
       DbgUserDumpHandleTable();
#endif

      return NULL;
#if 0
      PUSER_HANDLE_ENTRY new_handles;
      /* Grow array by 50% (but at minimum 32 entries) */
      int growth = max( 32, ht->allocated_handles / 2 );
      int new_size = min( ht->allocated_handles + growth, (LAST_USER_HANDLE-FIRST_USER_HANDLE+1) >> 1 );
      if (new_size <= ht->allocated_handles)
         return NULL;
      if (!(new_handles = UserHeapReAlloc( ht->handles, new_size * sizeof(*ht->handles) )))
         return NULL;
      ht->handles = new_handles;
      ht->allocated_handles = new_size;
#endif
   }
Beispiel #2
0
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;
}