Example #1
0
/*
IntHookModuleUnloaded:
Sends a internal message to all threads of the requested desktop
and notifies them that a global hook was destroyed
and an injected module must be unloaded.
As a result, IntLoadHookModule will be called for all the threads that
will receive the special purpose internal message.
*/
BOOL
IntHookModuleUnloaded(PDESKTOP pdesk, int iHookID, HHOOK hHook)
{
    PTHREADINFO ptiCurrent;
    PLIST_ENTRY ListEntry;
    PPROCESSINFO ppiCsr;

    TRACE("IntHookModuleUnloaded: iHookID=%d\n", iHookID);

    ppiCsr = PsGetProcessWin32Process(gpepCSRSS);

    ListEntry = pdesk->PtiList.Flink;
    while(ListEntry != &pdesk->PtiList)
    {
        ptiCurrent = CONTAINING_RECORD(ListEntry, THREADINFO, PtiLink);

        /* FIXME: Do some more security checks here */

        /* FIXME: The first check is a reactos specific hack for system threads */
        if(!PsIsSystemProcess(ptiCurrent->ppi->peProcess) &&
           ptiCurrent->ppi != ppiCsr)
        {
            if(ptiCurrent->ppi->W32PF_flags & W32PF_APIHOOKLOADED)
            {
                TRACE("IntHookModuleUnloaded: sending message to PID %p, ppi=%p\n", PsGetProcessId(ptiCurrent->ppi->peProcess), ptiCurrent->ppi);
                co_MsqSendMessageAsync( ptiCurrent,
                                        0,
                                        iHookID,
                                        TRUE,
                                        (LPARAM)hHook,
                                        NULL,
                                        0,
                                        FALSE,
                                        MSQ_INJECTMODULE);
            }
        }
        ListEntry = ListEntry->Flink;
    }

    return TRUE;
}
Example #2
0
/*
  API Call
*/
BOOL FASTCALL
IntAllowSetForegroundWindow(DWORD dwProcessId)
{
   PPROCESSINFO ppi, ppiCur;
   PEPROCESS Process = NULL;

   ppi = NULL;
   if (dwProcessId != ASFW_ANY)
   {
      if (!NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)dwProcessId, &Process)))
      {
         EngSetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
      }
      ppi = PsGetProcessWin32Process(Process);
      if (!ppi)
      {
         ObDereferenceObject(Process);
         return FALSE;
      }
   }
   ppiCur = PsGetCurrentProcessWin32Process();
   if (!CanForceFG(ppiCur))
   {
      if (Process) ObDereferenceObject(Process);
      EngSetLastError(ERROR_ACCESS_DENIED);
      return FALSE;
   }
   if (dwProcessId == ASFW_ANY)
   {  // All processes will be enabled to set the foreground window.
      ptiLastInput = NULL;
   }
   else
   {  // Rule #3, last input event in force.
      ERR("Fixme: ptiLastInput is SET!!\n");
      //ptiLastInput = ppi->ptiList;
      ObDereferenceObject(Process);
   }
   return TRUE;
}
Example #3
0
File: hook.c Project: staring/RosFE
BOOL
FASTCALL
UserRegisterUserApiHook(
    PUNICODE_STRING pstrDllName,
    PUNICODE_STRING pstrFuncName)
{
    PTHREADINFO pti, ptiCurrent;
    HWND *List;
    PWND DesktopWindow, pwndCurrent;
    ULONG i;
    PPROCESSINFO ppiCsr;

    pti = PsGetCurrentThreadWin32Thread();
    ppiCsr = PsGetProcessWin32Process(gpepCSRSS);

    /* Fail if the api hook is already registered */
    if(gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
    {
        return FALSE;
    }

    TRACE("UserRegisterUserApiHook. Server PID: %p\n", PsGetProcessId(pti->ppi->peProcess));

    /* Register the api hook */
    gpsi->dwSRVIFlags |= SRVINFO_APIHOOK;

    strUahModule = *pstrDllName;
    strUahInitFunc = *pstrFuncName;
    ppiUahServer = pti->ppi;

    /* Broadcast an internal message to every top level window */
    DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
    List = IntWinListChildren(DesktopWindow);

    if (List != NULL)
    {
        for (i = 0; List[i]; i++)
        {
            pwndCurrent = UserGetWindowObject(List[i]);
            if(pwndCurrent == NULL)
            {
                continue;
            }
            ptiCurrent = pwndCurrent->head.pti;

            /* FIXME: The first check is a reactos specific hack for system threads */
            if(PsIsSystemProcess(ptiCurrent->ppi->peProcess) ||
                    ptiCurrent->ppi == ppiCsr)
            {
                continue;
            }

            co_MsqSendMessageAsync( ptiCurrent,
                                    0,
                                    WH_APIHOOK,
                                    FALSE,   /* Load the module */
                                    0,
                                    NULL,
                                    0,
                                    FALSE,
                                    MSQ_INJECTMODULE);
        }
        ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
    }

    return TRUE;
}
Example #4
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;
}