- Add proper function headers, including links to publically-available documentation
- One internal function is subject to further review/audit

svn path=/trunk/; revision=22672
This commit is contained in:
Aleksey Bragin 2006-06-28 13:53:30 +00:00
parent 6ef4e4d9d4
commit 981fde0f9f

View file

@ -1,9 +1,10 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel
* PROJECT: ReactOS kernel * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ex/callback.c * FILE: ntoskrnl/ex/callback.c
* PURPOSE: Executive callbacks * PURPOSE: Executive callbacks
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) * PROGRAMMERS: Filip Navara
* Alex Ionescu (alex@relsoft.net)
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
@ -63,21 +64,20 @@ KEVENT ExpCallbackEvent;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
/* /*++
* ExpInitializeCallbacks * @name ExpInitializeCallbacks
* *
* FUNCTION:
* Creates the Callback Object as a valid Object Type in the Kernel. * Creates the Callback Object as a valid Object Type in the Kernel.
* Internal function, subject to further review
* *
* ARGUMENTS: * @return TRUE if the Callback Object Type was successfully created.
* None
* *
* RETURNS: * @remarks None
* TRUE if the Callback Object Type was successfully created. *
*/ *--*/
VOID VOID
INIT_FUNCTION INIT_FUNCTION
STDCALL NTAPI
ExpInitializeCallbacks(VOID) ExpInitializeCallbacks(VOID)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
@ -165,34 +165,40 @@ ExpInitializeCallbacks(VOID)
/* Everything successful */ /* Everything successful */
} }
/* /*++
* ExCreateCallback * @name ExCreateCallback
* @implemented
* *
* FUNCTION:
* Opens or creates a Callback Object. Creates only if Create is true. * Opens or creates a Callback Object. Creates only if Create is true.
* Allows multiple Callback Functions to be registred only if AllowMultipleCallbacks * Allows multiple Callback Functions to be registred only if
* is true. * AllowMultipleCallbacks is true.
* See: http://www.osronline.com/ddkx/kmarch/k102_967m.htm
* http://www.osronline.com/article.cfm?id=24
* *
* ARGUMENTS: * @param CallbackObject
* CallbackObject = Pointer that will receive the Callback Object. * Pointer that will receive the Callback Object.
* CallbackName = Name of Callback *
* Create = Determines if the object will be created if it doesn't exit * @param CallbackName
* AllowMultipleCallbacks = Determines if more then one registered callback function * Name of Callback
*
* @param Create
* Determines if the object will be created if it doesn't exit
*
* @param AllowMultipleCallbacks
* Determines if more then one registered callback function
* can be attached to this Callback Object. * can be attached to this Callback Object.
* *
* RETURNS: * @return STATUS_SUCESS if not failed.
* STATUS_SUCESS if not failed.
* *
* @implemented * @remarks Must be called at IRQL = PASSIVE_LEVEL
*/ *
*--*/
NTSTATUS NTSTATUS
STDCALL NTAPI
ExCreateCallback( ExCreateCallback(OUT PCALLBACK_OBJECT *CallbackObject,
OUT PCALLBACK_OBJECT *CallbackObject,
IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_ATTRIBUTES ObjectAttributes,
IN BOOLEAN Create, IN BOOLEAN Create,
IN BOOLEAN AllowMultipleCallbacks IN BOOLEAN AllowMultipleCallbacks)
)
{ {
PCALLBACK_OBJECT Callback; PCALLBACK_OBJECT Callback;
NTSTATUS Status; NTSTATUS Status;
@ -232,11 +238,11 @@ ExCreateCallback(
/* We Created it...let's initialize the structure now */ /* We Created it...let's initialize the structure now */
if(NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{ {
KeInitializeSpinLock (&Callback->Lock); /* SpinLock */ KeInitializeSpinLock(&Callback->Lock); /* SpinLock */
InitializeListHead(&Callback->RegisteredCallbacks); /* Callback Entries */ InitializeListHead(&Callback->RegisteredCallbacks); /* Callback Entries */
Callback->AllowMultipleCallbacks = AllowMultipleCallbacks; /* Multiple Callbacks */ Callback->AllowMultipleCallbacks = AllowMultipleCallbacks; /* Multiple Callbacks */
Status = ObInsertObject ( /* Create the object */ /* Create the object */
Callback, Status = ObInsertObject(Callback,
NULL, NULL,
FILE_READ_DATA, FILE_READ_DATA,
0, 0,
@ -244,18 +250,16 @@ ExCreateCallback(
&Handle ); &Handle );
} }
} }
if(NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{ {
/* Get a pointer to the new object from the handle we just got */ /* Get a pointer to the new object from the handle we just got */
Status = ObReferenceObjectByHandle ( Status = ObReferenceObjectByHandle(Handle,
Handle,
0, 0,
ExCallbackObjectType, ExCallbackObjectType,
KernelMode, KernelMode,
(PVOID)&Callback, (PVOID)&Callback,
NULL NULL);
);
/* Close the Handle, since we now have the pointer */ /* Close the Handle, since we now have the pointer */
ZwClose(Handle); ZwClose(Handle);
} }
@ -268,29 +272,34 @@ ExCreateCallback(
return Status; return Status;
} }
/* /*++
* ExNotifyCallback * @name ExNotifyCallback
*
* FUNCTION:
* Calls a function pointer (a registered callback)
*
* ARGUMENTS:
* CallbackObject - Which callback to call
* Argument1 - Pointer/data to send to callback function
* Argument2 - Pointer/data to send to callback function
*
* RETURNS:
* Nothing
*
* @implemented * @implemented
*/ *
* Calls a function pointer (a registered callback)
* See: http://www.osronline.com/ddkx/kmarch/k102_2f5e.htm
* http://msdn.microsoft.com/library/en-us/Kernel_d/hh/Kernel_d/Synchro_e954f515-e536-4e12-8419-e7e54c4a963b.xml.asp?frame=true
* http://vmsone.com/~decuslib/vmssig/vmslt99b/nt/wdm-callback.txt
*
* @param CallbackObject
* Which callback to call
*
* @param Argument1
* Pointer/data to send to callback function
*
* @param Argument2
* Pointer/data to send to callback function
*
* @return None
*
* @remarks None
*
*--*/
VOID VOID
STDCALL NTAPI
ExNotifyCallback( ExNotifyCallback(IN PCALLBACK_OBJECT OpaqueCallbackObject,
IN PCALLBACK_OBJECT OpaqueCallbackObject,
IN PVOID Argument1, IN PVOID Argument1,
IN PVOID Argument2 IN PVOID Argument2)
)
{ {
PCALLBACK_OBJECT CallbackObject = (PCALLBACK_OBJECT)OpaqueCallbackObject; PCALLBACK_OBJECT CallbackObject = (PCALLBACK_OBJECT)OpaqueCallbackObject;
PLIST_ENTRY RegisteredCallbacks; PLIST_ENTRY RegisteredCallbacks;
@ -305,16 +314,14 @@ ExNotifyCallback(
RegisteredCallbacks != &CallbackObject->RegisteredCallbacks; RegisteredCallbacks != &CallbackObject->RegisteredCallbacks;
RegisteredCallbacks = RegisteredCallbacks->Flink) RegisteredCallbacks = RegisteredCallbacks->Flink)
{ {
/* Get a pointer to a Callback Registration from the List Entries */ /* Get a pointer to a Callback Registration from the List Entries */
CallbackRegistration = CONTAINING_RECORD ( RegisteredCallbacks, CallbackRegistration = CONTAINING_RECORD(RegisteredCallbacks,
CALLBACK_REGISTRATION, CALLBACK_REGISTRATION,
RegisteredCallbacks); RegisteredCallbacks);
/* Don't bother doing Callback Notification if it's pending to be deleted */ /* Don't bother doing Callback Notification if it's pending to be deleted */
if (!CallbackRegistration->PendingDeletion) if (!CallbackRegistration->PendingDeletion)
{ {
/* Mark the Callback in use, so it won't get deleted while we are calling it */ /* Mark the Callback in use, so it won't get deleted while we are calling it */
CallbackRegistration->InUse += 1; CallbackRegistration->InUse += 1;
@ -322,7 +329,7 @@ ExNotifyCallback(
KfReleaseSpinLock(&CallbackObject->Lock, OldIrql); KfReleaseSpinLock(&CallbackObject->Lock, OldIrql);
/* Call the Registered Function */ /* Call the Registered Function */
CallbackRegistration->CallbackFunction ( CallbackRegistration->CallbackFunction(
CallbackRegistration->CallbackContext, CallbackRegistration->CallbackContext,
Argument1, Argument1,
Argument2 Argument2
@ -345,31 +352,34 @@ ExNotifyCallback(
KfReleaseSpinLock(&CallbackObject->Lock, OldIrql); KfReleaseSpinLock(&CallbackObject->Lock, OldIrql);
} }
/* /*++
* ExRegisterCallback * @name ExRegisterCallback
*
* FUNCTION:
* Allows a function to associate a callback pointer (Function)
* to a created Callback object
*
* ARGUMENTS:
* CallbackObject = The Object Created with ExCreateCallBack
* CallBackFunction = Pointer to the function to be called back
* CallBackContext = Block of memory that can contain user-data
* which will be passed on to the callback
*
* RETURNS:
* A handle to a Callback Registration Structure (MSDN Documentation)
*
* @implemented * @implemented
*/ *
* Allows a function to associate a callback pointer (Function) to
* a created Callback object
* See: DDK, OSR, links in ExNotifyCallback
*
* @param CallbackObject
* The Object Created with ExCreateCallBack
*
* @param CallBackFunction
* Pointer to the function to be called back
*
* @param CallBackContext
* Block of memory that can contain user-data which will be
* passed on to the callback
*
* @return A handle to a Callback Registration Structure (MSDN Documentation)
*
* @remarks None
*
*--*/
PVOID PVOID
STDCALL NTAPI
ExRegisterCallback( ExRegisterCallback(IN PCALLBACK_OBJECT OpaqueCallbackObject,
IN PCALLBACK_OBJECT OpaqueCallbackObject,
IN PCALLBACK_FUNCTION CallbackFunction, IN PCALLBACK_FUNCTION CallbackFunction,
IN PVOID CallbackContext IN PVOID CallbackContext)
)
{ {
PCALLBACK_OBJECT CallbackObject = (PCALLBACK_OBJECT)OpaqueCallbackObject; PCALLBACK_OBJECT CallbackObject = (PCALLBACK_OBJECT)OpaqueCallbackObject;
PCALLBACK_REGISTRATION CallbackRegistration = NULL; PCALLBACK_REGISTRATION CallbackRegistration = NULL;
@ -416,27 +426,27 @@ ExRegisterCallback(
KfReleaseSpinLock(&CallbackObject->Lock, OldIrql); KfReleaseSpinLock(&CallbackObject->Lock, OldIrql);
/* Return handle to Registration Object */ /* Return handle to Registration Object */
return (PVOID) CallbackRegistration; return (PVOID)CallbackRegistration;
} }
/* /*++
* ExUnregisterCallback * @name ExUnregisterCallback
*
* FUNCTION:
* Deregisters a CallBack
*
* ARGUMENTS:
* CallbackRegistration = Callback Registration Handle
*
* RETURNS:
* Nothing
*
* @implemented * @implemented
*/ *
VOID STDCALL * Deregisters a CallBack
ExUnregisterCallback( * See: DDK, OSR, links in ExNotifyCallback
IN PVOID CallbackRegistrationHandle *
) * @param CallbackRegistration
* Callback Registration Handle
*
* @return None
*
* @remarks None
*
*--*/
VOID
NTAPI
ExUnregisterCallback(IN PVOID CallbackRegistrationHandle)
{ {
PCALLBACK_REGISTRATION CallbackRegistration; PCALLBACK_REGISTRATION CallbackRegistration;
PCALLBACK_OBJECT CallbackObject; PCALLBACK_OBJECT CallbackObject;
@ -456,7 +466,6 @@ ExUnregisterCallback(
/* We can't Delete the Callback if it's in use, because this would create a call towards a null pointer => crash */ /* We can't Delete the Callback if it's in use, because this would create a call towards a null pointer => crash */
while (CallbackRegistration->InUse) while (CallbackRegistration->InUse)
{ {
/* Similarly, we also don't want to wait ages for all pending callbacks to be called */ /* Similarly, we also don't want to wait ages for all pending callbacks to be called */
CallbackRegistration->PendingDeletion = TRUE; CallbackRegistration->PendingDeletion = TRUE;