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=254…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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=2…
==============================================================================
--- 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 */