Author: ion Date: Tue Jan 16 18:09:53 2007 New Revision: 25486
URL: http://svn.reactos.org/svn/reactos?rev=25486&view=rev Log: - Reimplement Process/Thread/Image notification callbacks by using the new executive lightweight callback implementation. - Remove corresponding entry from kernel fun.
Modified: trunk/reactos/ntoskrnl/KrnlFun.c trunk/reactos/ntoskrnl/ex/callback.c trunk/reactos/ntoskrnl/include/internal/ex.h trunk/reactos/ntoskrnl/include/internal/ps.h trunk/reactos/ntoskrnl/include/internal/ps_x.h trunk/reactos/ntoskrnl/ps/notify.c
Modified: trunk/reactos/ntoskrnl/KrnlFun.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/KrnlFun.c?rev=2548... ============================================================================== --- trunk/reactos/ntoskrnl/KrnlFun.c (original) +++ trunk/reactos/ntoskrnl/KrnlFun.c Tue Jan 16 18:09:53 2007 @@ -9,7 +9,6 @@ // Failure to respect this will *ACHIEVE NOTHING*. // // Ex: -// - Implement Generic Callback mechanism. // - Use pushlocks for handle implementation. // // Ke1:
Modified: trunk/reactos/ntoskrnl/ex/callback.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/callback.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ex/callback.c (original) +++ trunk/reactos/ntoskrnl/ex/callback.c Tue Jan 16 18:09:53 2007 @@ -230,31 +230,6 @@ return CallbackRoutineBlock; }
-VOID -NTAPI // FIXME: FORCEINLINE AFTER TESTING! -ExDoCallBack(IN OUT PEX_CALLBACK Callback, - IN PVOID Context, - IN PVOID Argument1, - IN PVOID Argument2) -{ - PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock; - PEX_CALLBACK_FUNCTION Function; - - /* Reference the block */ - CallbackRoutineBlock = ExReferenceCallBackBlock(Callback); - if (CallbackRoutineBlock) - { - /* Get the function */ - Function = ExGetCallBackBlockRoutine(CallbackRoutineBlock); - - /* Do the callback */ - Function(Context, Argument1, Argument2); - - /* Now dereference it */ - ExDereferenceCallBackBlock(Callback, CallbackRoutineBlock); - } -} - BOOLEAN NTAPI ExCompareExchangeCallBack(IN OUT PEX_CALLBACK CallBack,
Modified: trunk/reactos/ntoskrnl/include/internal/ex.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/e... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ex.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ex.h Tue Jan 16 18:09:53 2007 @@ -169,7 +169,59 @@ VOID NTAPI ExInitializeCallBack( - IN PEX_CALLBACK Callback + IN OUT PEX_CALLBACK Callback +); + +PEX_CALLBACK_ROUTINE_BLOCK +NTAPI +ExAllocateCallBack( + IN PEX_CALLBACK_FUNCTION Function, + IN PVOID Context +); + +VOID +NTAPI +ExFreeCallBack( + IN PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock +); + +BOOLEAN +NTAPI +ExCompareExchangeCallBack ( + IN OUT PEX_CALLBACK CallBack, + IN PEX_CALLBACK_ROUTINE_BLOCK NewBlock, + IN PEX_CALLBACK_ROUTINE_BLOCK OldBlock +); + +PEX_CALLBACK_ROUTINE_BLOCK +NTAPI +ExReferenceCallBackBlock( + IN OUT PEX_CALLBACK CallBack +); + +VOID +NTAPI +ExDereferenceCallBackBlock( + IN OUT PEX_CALLBACK CallBack, + IN PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock +); + +PEX_CALLBACK_FUNCTION +NTAPI +ExGetCallBackBlockRoutine( + IN PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock +); + +PVOID +NTAPI +ExGetCallBackBlockContext( + IN PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock +); + +VOID +NTAPI +ExWaitForCallBacks( + IN PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock );
/* Rundown Functions ********************************************************/ @@ -336,6 +388,33 @@ static __inline _SEH_FILTER(_SEH_ExSystemExceptionFilter) { return ExSystemExceptionFilter(); +} + +/* CALLBACKS *****************************************************************/ + +VOID +FORCEINLINE +ExDoCallBack(IN OUT PEX_CALLBACK Callback, + IN PVOID Context, + IN PVOID Argument1, + IN PVOID Argument2) +{ + PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock; + PEX_CALLBACK_FUNCTION Function; + + /* Reference the block */ + CallbackRoutineBlock = ExReferenceCallBackBlock(Callback); + if (CallbackRoutineBlock) + { + /* Get the function */ + Function = ExGetCallBackBlockRoutine(CallbackRoutineBlock); + + /* Do the callback */ + Function(Context, Argument1, Argument2); + + /* Now dereference it */ + ExDereferenceCallBackBlock(Callback, CallbackRoutineBlock); + } }
/* RUNDOWN *******************************************************************/
Modified: trunk/reactos/ntoskrnl/include/internal/ps.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/p... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ps.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ps.h Tue Jan 16 18:09:53 2007 @@ -365,14 +365,11 @@ extern LARGE_INTEGER ShortPsLockDelay; extern EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock; extern PHANDLE_TABLE PspCidTable; -extern PCREATE_THREAD_NOTIFY_ROUTINE -PspThreadNotifyRoutine[PSP_MAX_CREATE_THREAD_NOTIFY]; -extern PCREATE_PROCESS_NOTIFY_ROUTINE -PspProcessNotifyRoutine[PSP_MAX_CREATE_PROCESS_NOTIFY]; -extern PLOAD_IMAGE_NOTIFY_ROUTINE -PspLoadImageNotifyRoutine[PSP_MAX_LOAD_IMAGE_NOTIFY]; +extern EX_CALLBACK PspThreadNotifyRoutine[PSP_MAX_CREATE_THREAD_NOTIFY]; +extern EX_CALLBACK PspProcessNotifyRoutine[PSP_MAX_CREATE_PROCESS_NOTIFY]; +extern EX_CALLBACK PspLoadImageNotifyRoutine[PSP_MAX_LOAD_IMAGE_NOTIFY]; extern PLEGO_NOTIFY_ROUTINE PspLegoNotifyRoutine; -extern ULONG PspThreadNotifyRoutineCount; +extern ULONG PspThreadNotifyRoutineCount, PspProcessNotifyRoutineCount; extern BOOLEAN PsImageNotifyEnabled; extern PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout; extern PKWIN32_THREAD_CALLOUT PspW32ThreadCallout;
Modified: trunk/reactos/ntoskrnl/include/internal/ps_x.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/p... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ps_x.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ps_x.h Tue Jan 16 18:09:53 2007 @@ -33,13 +33,19 @@ IN BOOLEAN Create) { ULONG i; - CLIENT_ID Cid = CurrentThread->Cid;
- /* Loop the notify routines */ - for (i = 0; i < PspThreadNotifyRoutineCount; i++) + /* Check if we have registered routines */ + if (PspThreadNotifyRoutineCount) { - /* Call it */ - PspThreadNotifyRoutine[i](Cid.UniqueProcess, Cid.UniqueThread, Create); + /* Loop callbacks */ + for (i = 0; i < PSP_MAX_CREATE_THREAD_NOTIFY; i++) + { + /* Do the callback */ + ExDoCallBack(&PspThreadNotifyRoutine[i], + CurrentThread->Cid.UniqueProcess, + CurrentThread->Cid.UniqueThread, + (PVOID)(ULONG_PTR)Create); + } } }
@@ -49,17 +55,18 @@ IN BOOLEAN Create) { ULONG i; - HANDLE ProcessId = (HANDLE)CurrentProcess->UniqueProcessId; - HANDLE ParentId = CurrentProcess->InheritedFromUniqueProcessId;
- /* Loop the notify routines */ - for(i = 0; i < PSP_MAX_CREATE_PROCESS_NOTIFY; ++i) + /* Check if we have registered routines */ + if (PspProcessNotifyRoutineCount) { - /* Make sure it exists */ - if(PspProcessNotifyRoutine[i]) + /* Loop callbacks */ + for (i = 0; i < PSP_MAX_CREATE_PROCESS_NOTIFY; i++) { - /* Call it */ - PspProcessNotifyRoutine[i](ParentId, ProcessId, Create); + /* Do the callback */ + ExDoCallBack(&PspProcessNotifyRoutine[i], + CurrentProcess->InheritedFromUniqueProcessId, + (PVOID)(ULONG_PTR)Create, + NULL); } } } @@ -75,12 +82,11 @@ /* Loop the notify routines */ for (i = 0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; ++ i) { - /* Make sure it exists */ - if (PspLoadImageNotifyRoutine[i]) - { - /* Call it */ - PspLoadImageNotifyRoutine[i](FullImageName, ProcessId, ImageInfo); - } + /* Do the callback */ + ExDoCallBack(&PspLoadImageNotifyRoutine[i], + FullImageName, + ProcessId, + ImageInfo); } }
Modified: trunk/reactos/ntoskrnl/ps/notify.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/notify.c?rev=25... ============================================================================== --- trunk/reactos/ntoskrnl/ps/notify.c (original) +++ trunk/reactos/ntoskrnl/ps/notify.c Tue Jan 16 18:09:53 2007 @@ -15,14 +15,12 @@
/* GLOBALS *******************************************************************/
-BOOLEAN PsImageNotifyEnabled = TRUE; -ULONG PspThreadNotifyRoutineCount; -PCREATE_THREAD_NOTIFY_ROUTINE -PspThreadNotifyRoutine[PSP_MAX_CREATE_THREAD_NOTIFY]; -PCREATE_PROCESS_NOTIFY_ROUTINE -PspProcessNotifyRoutine[PSP_MAX_CREATE_PROCESS_NOTIFY]; -PLOAD_IMAGE_NOTIFY_ROUTINE -PspLoadImageNotifyRoutine[PSP_MAX_LOAD_IMAGE_NOTIFY]; +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 **********************************************************/ @@ -36,39 +34,78 @@ IN BOOLEAN Remove) { ULONG i; - - /* Check if it's a removal or addition */ + PEX_CALLBACK_ROUTINE_BLOCK CallBack; + PAGED_CODE(); + + /* Check if we're removing */ if (Remove) { - /* Loop the routines */ - for(i = 0; i < PSP_MAX_CREATE_PROCESS_NOTIFY; i++) - { - /* Check for a match */ - if (PspProcessNotifyRoutine[i] == NotifyRoutine) - { - /* Remove and return */ - PspProcessNotifyRoutine[i] = NULL; + /* 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) + { + /* It's not, try the next one */ + continue; + } + + /* It is, clear the current routine */ + if (ExCompareExchangeCallBack(&PspProcessNotifyRoutine[i], + NULL, + CallBack)) + { + /* Decrement the number of routines */ + InterlockedDecrement(&PspProcessNotifyRoutineCount); + + /* Dereference the block */ + ExDereferenceCallBackBlock(&PspProcessNotifyRoutine[i], + CallBack); + + /* Wait for actice 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 { - /* Loop the routines */ - for(i = 0; i < PSP_MAX_CREATE_PROCESS_NOTIFY; i++) - { - /* Find an empty one */ - if (!PspProcessNotifyRoutine[i]) - { - /* Add it */ - PspProcessNotifyRoutine[i] = NotifyRoutine; + /* 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(&PspProcessNotifyRoutineCount); return STATUS_SUCCESS; } } - } - - /* Nothing found */ - return Remove ? STATUS_PROCEDURE_NOT_FOUND : STATUS_INVALID_PARAMETER; + + /* We didn't find a free slot, free the callback and fail */ + ExFreeCallBack(CallBack); + return STATUS_INVALID_PARAMETER; + } }
/* @@ -93,90 +130,163 @@ PsRemoveLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine) { ULONG i; - - /* Loop the routines */ - for(i = 0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++) - { - /* Check for a match */ - if (PspLoadImageNotifyRoutine[i] == NotifyRoutine) - { - /* Remove and return */ - PspLoadImageNotifyRoutine[i] = NULL; + 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(&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 + */ +NTSTATUS +NTAPI +PsSetLoadImageNotifyRoutine(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(&PspLoadImageNotifyRoutineCount); + PsImageNotifyEnabled = TRUE; return STATUS_SUCCESS; } }
- /* Nothing found */ - return STATUS_INVALID_PARAMETER; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -PsSetLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine) -{ - ULONG i; - - /* Loop the routines */ - for (i = 0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++) - { - /* Find an empty one */ - if (!PspLoadImageNotifyRoutine[i]) - { - /* Add it */ - PspLoadImageNotifyRoutine[i] = NotifyRoutine; + /* No free space found, fail */ + ExFreeCallBack(CallBack); + return STATUS_INSUFFICIENT_RESOURCES; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +PsRemoveCreateThreadNotifyRoutine(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(&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 + */ +NTSTATUS +NTAPI +PsSetCreateThreadNotifyRoutine(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(&PspThreadNotifyRoutineCount); return STATUS_SUCCESS; } }
- /* Nothing found */ - return STATUS_INVALID_PARAMETER; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -PsRemoveCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine) -{ - ULONG i; - - /* Loop the routines */ - for(i = 0; i < PSP_MAX_CREATE_THREAD_NOTIFY; i++) - { - /* Check for a match */ - if (PspThreadNotifyRoutine[i] == NotifyRoutine) - { - /* Remove and return */ - PspThreadNotifyRoutine[i] = NULL; - return STATUS_SUCCESS; - } - } - - /* Nothing found */ - return STATUS_INVALID_PARAMETER; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -PsSetCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine) -{ - /* Make sure we didn't register too many */ - if (PspThreadNotifyRoutineCount >= PSP_MAX_CREATE_THREAD_NOTIFY) - { - /* Fail */ - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* Register this one */ - PspThreadNotifyRoutine[PspThreadNotifyRoutineCount++] = NotifyRoutine; - return STATUS_SUCCESS; + /* No free space found, fail */ + ExFreeCallBack(CallBack); + return STATUS_INSUFFICIENT_RESOURCES; }
/* EOF */