Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290/* * PROJECT: ReactOS Kernel * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ps/psnotify.c * PURPOSE: Process Manager: Callbacks to Registered Clients (Drivers) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * Thomas Weidenmueller (w3seek@reactos.org) */
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>#define NDEBUG#include <debug.h>
/* GLOBALS *******************************************************************/
BOOLEAN PsImageNotifyEnabled = FALSE;ULONG PspThreadNotifyRoutineCount, PspProcessNotifyRoutineCount;ULONG PspLoadImageNotifyRoutineCount;EX_CALLBACK PspThreadNotifyRoutine[PSP_MAX_CREATE_THREAD_NOTIFY];EX_CALLBACK PspProcessNotifyRoutine[PSP_MAX_CREATE_PROCESS_NOTIFY];EX_CALLBACK PspLoadImageNotifyRoutine[PSP_MAX_LOAD_IMAGE_NOTIFY];PLEGO_NOTIFY_ROUTINE PspLegoNotifyRoutine;
/* PUBLIC FUNCTIONS **********************************************************/
/* * @implemented */NTSTATUSNTAPIPsSetCreateProcessNotifyRoutine(IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, IN BOOLEAN Remove){ ULONG i; PEX_CALLBACK_ROUTINE_BLOCK CallBack; PAGED_CODE();
/* Check if we're removing */ if (Remove) { /* Loop all the routines */ for (i = 0; i < PSP_MAX_CREATE_PROCESS_NOTIFY; i++) { /* Reference the callback block */ CallBack = ExReferenceCallBackBlock(&PspProcessNotifyRoutine[i]); if (!CallBack) continue;
/* Check it this is a matching block */ if (ExGetCallBackBlockRoutine(CallBack) == (PVOID)NotifyRoutine) { /* Try removing it if it matches */ if (ExCompareExchangeCallBack(&PspProcessNotifyRoutine[i], NULL, CallBack)) { /* Decrement the number of routines */ InterlockedDecrement((PLONG)&PspProcessNotifyRoutineCount);
/* Dereference the block */ ExDereferenceCallBackBlock(&PspProcessNotifyRoutine[i], CallBack);
/* Wait for active callbacks */ ExWaitForCallBacks(CallBack);
/* Free the callback and exit */ ExFreeCallBack(CallBack); return STATUS_SUCCESS; }
/* Dereference the block */ ExDereferenceCallBackBlock(&PspProcessNotifyRoutine[i], CallBack); } }
/* We didn't find any matching block */ return STATUS_PROCEDURE_NOT_FOUND; } else { /* Allocate a callback */ CallBack = ExAllocateCallBack((PVOID)NotifyRoutine, NULL); if (!CallBack) return STATUS_INSUFFICIENT_RESOURCES;
/* Loop all callbacks */ for (i = 0; i < PSP_MAX_CREATE_PROCESS_NOTIFY; i++) { /* Add this routine if it's an empty slot */ if (ExCompareExchangeCallBack(&PspProcessNotifyRoutine[i], CallBack, NULL)) { /* Found and inserted into an empty slot, return */ InterlockedIncrement((PLONG)&PspProcessNotifyRoutineCount); return STATUS_SUCCESS; } }
/* We didn't find a free slot, free the callback and fail */ ExFreeCallBack(CallBack); return STATUS_INVALID_PARAMETER; }}
/* * @implemented */ULONGNTAPIPsSetLegoNotifyRoutine(PVOID LegoNotifyRoutine){ /* Set the System-Wide Lego Routine */ PspLegoNotifyRoutine = LegoNotifyRoutine;
/* Return the location to the Lego Data */ return FIELD_OFFSET(KTHREAD, LegoData);}
/* * @implemented */NTSTATUSNTAPIPsRemoveLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine){ ULONG i; PEX_CALLBACK_ROUTINE_BLOCK CallBack; PAGED_CODE();
/* Loop all callbacks */ for (i = 0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++) { /* Reference this slot */ CallBack = ExReferenceCallBackBlock(&PspLoadImageNotifyRoutine[i]); if (CallBack) { /* Check for a match */ if (ExGetCallBackBlockRoutine(CallBack) == (PVOID)NotifyRoutine) { /* Try removing it if it matches */ if (ExCompareExchangeCallBack(&PspLoadImageNotifyRoutine[i], NULL, CallBack)) { /* We removed it, now dereference the block */ InterlockedDecrement((PLONG)&PspLoadImageNotifyRoutineCount); ExDereferenceCallBackBlock(&PspLoadImageNotifyRoutine[i], CallBack);
/* Wait for active callbacks */ ExWaitForCallBacks(CallBack);
/* Free the callback and return */ ExFreeCallBack(CallBack); return STATUS_SUCCESS; } }
/* Dereference the callback */ ExDereferenceCallBackBlock(&PspLoadImageNotifyRoutine[i], CallBack); } }
/* Nothing found to remove */ return STATUS_PROCEDURE_NOT_FOUND;}
/* * @implemented */NTSTATUSNTAPIPsSetLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine){ ULONG i; PEX_CALLBACK_ROUTINE_BLOCK CallBack; PAGED_CODE();
/* Allocate a callback */ CallBack = ExAllocateCallBack((PVOID)NotifyRoutine, NULL); if (!CallBack) return STATUS_INSUFFICIENT_RESOURCES;
/* Loop callbacks */ for (i = 0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++) { /* Add this entry if the slot is empty */ if (ExCompareExchangeCallBack(&PspLoadImageNotifyRoutine[i], CallBack, NULL)) { /* Return success */ InterlockedIncrement((PLONG)&PspLoadImageNotifyRoutineCount); PsImageNotifyEnabled = TRUE; return STATUS_SUCCESS; } }
/* No free space found, fail */ ExFreeCallBack(CallBack); return STATUS_INSUFFICIENT_RESOURCES;}
/* * @implemented */NTSTATUSNTAPIPsRemoveCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine){ ULONG i; PEX_CALLBACK_ROUTINE_BLOCK CallBack; PAGED_CODE();
/* Loop all callbacks */ for (i = 0; i < PSP_MAX_CREATE_THREAD_NOTIFY; i++) { /* Reference this slot */ CallBack = ExReferenceCallBackBlock(&PspThreadNotifyRoutine[i]); if (CallBack) { /* Check for a match */ if (ExGetCallBackBlockRoutine(CallBack) == (PVOID)NotifyRoutine) { /* Try removing it if it matches */ if (ExCompareExchangeCallBack(&PspThreadNotifyRoutine[i], NULL, CallBack)) { /* We removed it, now dereference the block */ InterlockedDecrement((PLONG)&PspThreadNotifyRoutineCount); ExDereferenceCallBackBlock(&PspThreadNotifyRoutine[i], CallBack);
/* Wait for active callbacks */ ExWaitForCallBacks(CallBack);
/* Free the callback and return */ ExFreeCallBack(CallBack); return STATUS_SUCCESS; } }
/* Dereference the callback */ ExDereferenceCallBackBlock(&PspThreadNotifyRoutine[i], CallBack); } }
/* Nothing found to remove */ return STATUS_PROCEDURE_NOT_FOUND;}
/* * @implemented */NTSTATUSNTAPIPsSetCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine){ ULONG i; PEX_CALLBACK_ROUTINE_BLOCK CallBack; PAGED_CODE();
/* Allocate a callback */ CallBack = ExAllocateCallBack((PVOID)NotifyRoutine, NULL); if (!CallBack) return STATUS_INSUFFICIENT_RESOURCES;
/* Loop callbacks */ for (i = 0; i < PSP_MAX_CREATE_THREAD_NOTIFY; i++) { /* Add this entry if the slot is empty */ if (ExCompareExchangeCallBack(&PspThreadNotifyRoutine[i], CallBack, NULL)) { /* Return success */ InterlockedIncrement((PLONG)&PspThreadNotifyRoutineCount); return STATUS_SUCCESS; } }
/* No free space found, fail */ ExFreeCallBack(CallBack); return STATUS_INSUFFICIENT_RESOURCES;}
/* EOF */