mirror of
https://github.com/reactos/reactos.git
synced 2025-06-02 07:56:16 +00:00
- Callbacks implementation. A little modified patch by Alex Ionescu (alex@relsoft.net).
svn path=/trunk/; revision=9723
This commit is contained in:
parent
bb2c3e3a72
commit
e19a20e71e
4 changed files with 517 additions and 37 deletions
|
@ -16,84 +16,468 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: callback.c,v 1.10 2003/07/10 06:27:13 royce Exp $
|
/* $Id: callback.c,v 1.11 2004/06/19 08:48:00 navaraf Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ex/callback.c
|
* FILE: ntoskrnl/ex/callback.c
|
||||||
* PURPOSE: Executive callbacks
|
* PURPOSE: Executive callbacks
|
||||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
|
* Alex Ionescu (alex@relsoft.net)
|
||||||
* PORTABILITY: Checked.
|
* PORTABILITY: Checked.
|
||||||
* UPDATE HISTORY:
|
* UPDATE HISTORY:
|
||||||
|
* Added all functions 30/05/04
|
||||||
* Created 22/05/98
|
* Created 22/05/98
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* These funtions are not implemented in NT4.
|
* These funtions are not implemented in NT4, but
|
||||||
* They are implemented in Win2k.
|
* they are implemented in Win2k.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
#include <rosrtl/string.h>
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
#include <internal/ob.h>
|
||||||
|
#include <internal/callbacks.h>
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* ExpInitializeCallbacks
|
||||||
|
*
|
||||||
|
* FUNCTION:
|
||||||
|
* Creates the Callback Object as a valid Object Type in the Kernel.
|
||||||
|
*
|
||||||
|
* ARGUMENTS:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* TRUE if the Callback Object Type was successfully created.
|
||||||
|
*/
|
||||||
|
BOOLEAN
|
||||||
|
ExpInitializeCallbacks(VOID)
|
||||||
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
NTSTATUS Status;
|
||||||
|
UNICODE_STRING DirName;
|
||||||
|
UNICODE_STRING CallbackName;
|
||||||
|
HANDLE DirectoryHandle;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
/* Allocate memory for Object */
|
||||||
|
ExCallbackObjectType = ExAllocatePoolWithTag(NonPagedPool, sizeof(OBJECT_TYPE), CALLBACK_TAG);
|
||||||
|
|
||||||
|
/* Initialize name */
|
||||||
|
RtlRosInitUnicodeStringFromLiteral(&ExCallbackObjectType->TypeName,L"Callback");
|
||||||
|
|
||||||
|
/* Create the Object Type */
|
||||||
|
ExCallbackObjectType->Tag = CALLBACK_TAG;
|
||||||
|
ExCallbackObjectType->TotalObjects = 0;
|
||||||
|
ExCallbackObjectType->TotalHandles = 0;
|
||||||
|
ExCallbackObjectType->MaxObjects = 0xFFFFFFFF;
|
||||||
|
ExCallbackObjectType->MaxHandles = 0xFFFFFFFF;
|
||||||
|
ExCallbackObjectType->PagedPoolCharge = 0;
|
||||||
|
ExCallbackObjectType->Dump = NULL;
|
||||||
|
ExCallbackObjectType->Open = NULL;
|
||||||
|
ExCallbackObjectType->Close = NULL;
|
||||||
|
ExCallbackObjectType->Delete = NULL;
|
||||||
|
ExCallbackObjectType->Parse = NULL;
|
||||||
|
ExCallbackObjectType->Security = NULL;
|
||||||
|
ExCallbackObjectType->QueryName = NULL;
|
||||||
|
ExCallbackObjectType->DuplicationNotify = NULL;
|
||||||
|
ExCallbackObjectType->OkayToClose = NULL;
|
||||||
|
ExCallbackObjectType->Create = NULL;
|
||||||
|
ExCallbackObjectType->Mapping = &ExpCallbackMapping;
|
||||||
|
ExCallbackObjectType->NonpagedPoolCharge = sizeof(_INT_CALLBACK_OBJECT);
|
||||||
|
Status = ObpCreateTypeObject(ExCallbackObjectType);
|
||||||
|
|
||||||
|
/* Fail if it wasn't created successfully */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the Object */
|
||||||
|
RtlRosInitUnicodeStringFromLiteral(&DirName, L"\\Callback" );
|
||||||
|
InitializeObjectAttributes(
|
||||||
|
&ObjectAttributes,
|
||||||
|
&DirName,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Create the Object Directory */
|
||||||
|
Status = NtCreateDirectoryObject(
|
||||||
|
&DirectoryHandle,
|
||||||
|
DIRECTORY_ALL_ACCESS,
|
||||||
|
&ObjectAttributes
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Fail if couldn't create */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close Handle... */
|
||||||
|
NtClose(DirectoryHandle);
|
||||||
|
|
||||||
|
/* Initialize Event used when unregistering */
|
||||||
|
KeInitializeEvent(&ExpCallbackEvent, NotificationEvent, 0);
|
||||||
|
|
||||||
|
/* Default NT Kernel Callbacks. */
|
||||||
|
for (i=0; ExpInitializeCallback[i].CallbackObject; i++)
|
||||||
|
{
|
||||||
|
/* Create the name from the structure */
|
||||||
|
RtlInitUnicodeString(&CallbackName, ExpInitializeCallback[i].Name);
|
||||||
|
|
||||||
|
/* Initialize the Object Attributes Structure */
|
||||||
|
InitializeObjectAttributes(
|
||||||
|
&ObjectAttributes,
|
||||||
|
&CallbackName,
|
||||||
|
OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Create the Callback Object */
|
||||||
|
Status = ExCreateCallback(
|
||||||
|
(PCALLBACK_OBJECT*)&(ExpInitializeCallback[i].CallbackObject),
|
||||||
|
&ObjectAttributes,
|
||||||
|
TRUE,
|
||||||
|
TRUE
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Make sure Global Callbacks have been created */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Everything successful */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ExCreateCallback
|
||||||
|
*
|
||||||
|
* FUNCTION:
|
||||||
|
* Opens or creates a Callback Object. Creates only if Create is true.
|
||||||
|
* Allows multiple Callback Functions to be registred only if AllowMultipleCallbacks
|
||||||
|
* is true.
|
||||||
|
*
|
||||||
|
* ARGUMENTS:
|
||||||
|
* CallbackObject = Pointer that will receive the Callback Object.
|
||||||
|
* CallbackName = Name of Callback
|
||||||
|
* Create = Determines if the object will be created if it doesn't exit
|
||||||
|
* AllowMultipleCallbacks = Determines if more then one registered callback function
|
||||||
|
* can be attached to this Callback Object.
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* STATUS_SUCESS if not failed.
|
||||||
|
*
|
||||||
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
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
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
PINT_CALLBACK_OBJECT Callback;
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE Handle;
|
||||||
|
|
||||||
|
/* Open a handle to the callback if it exists */
|
||||||
|
if (ObjectAttributes->ObjectName)
|
||||||
|
{
|
||||||
|
Status = ObOpenObjectByName(ObjectAttributes,
|
||||||
|
ExCallbackObjectType,
|
||||||
|
NULL,
|
||||||
|
KernelMode,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&Handle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We weren't able to open it...should we create it? */
|
||||||
|
if(!NT_SUCCESS(Status) && Create )
|
||||||
|
{
|
||||||
|
Status = ObCreateObject(KernelMode,
|
||||||
|
ExCallbackObjectType,
|
||||||
|
ObjectAttributes,
|
||||||
|
KernelMode,
|
||||||
|
NULL,
|
||||||
|
sizeof(_INT_CALLBACK_OBJECT),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
(PVOID *)&Callback );
|
||||||
|
|
||||||
|
/* We Created it...let's initialize the structure now */
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KeInitializeSpinLock (&Callback->Lock); /* SpinLock */
|
||||||
|
InitializeListHead(&Callback->RegisteredCallbacks); /* Callback Entries */
|
||||||
|
Callback->AllowMultipleCallbacks = AllowMultipleCallbacks; /* Multiple Callbacks */
|
||||||
|
Status = ObInsertObject ( /* Create the object */
|
||||||
|
Callback,
|
||||||
|
NULL,
|
||||||
|
FILE_READ_DATA,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&Handle );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Get a pointer to the new object from the handle we just got */
|
||||||
|
Status = ObReferenceObjectByHandle (
|
||||||
|
Handle,
|
||||||
|
0,
|
||||||
|
ExCallbackObjectType,
|
||||||
|
KernelMode,
|
||||||
|
(PVOID)&Callback,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
/* Close the Handle, since we now have the pointer */
|
||||||
|
ZwClose(Handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Everything went fine, so return a pointer to the Object */
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
*CallbackObject = (PCALLBACK_OBJECT)Callback;
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* 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
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
STDCALL
|
||||||
ExNotifyCallback (
|
ExNotifyCallback(
|
||||||
IN PCALLBACK_OBJECT CallbackObject,
|
IN PCALLBACK_OBJECT OpaqueCallbackObject,
|
||||||
IN PVOID Argument1,
|
IN PVOID Argument1,
|
||||||
IN PVOID Argument2
|
IN PVOID Argument2
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return;
|
PINT_CALLBACK_OBJECT CallbackObject = (PINT_CALLBACK_OBJECT)OpaqueCallbackObject;
|
||||||
|
PLIST_ENTRY RegisteredCallbacks;
|
||||||
|
PCALLBACK_REGISTRATION CallbackRegistration;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
/* Acquire the Lock */
|
||||||
|
OldIrql = KfAcquireSpinLock(&CallbackObject->Lock);
|
||||||
|
|
||||||
|
/* Enumerate through all the registered functions */
|
||||||
|
for (RegisteredCallbacks = CallbackObject->RegisteredCallbacks.Flink;
|
||||||
|
RegisteredCallbacks != &CallbackObject->RegisteredCallbacks;
|
||||||
|
RegisteredCallbacks = RegisteredCallbacks->Flink)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Get a pointer to a Callback Registration from the List Entries */
|
||||||
|
CallbackRegistration = CONTAINING_RECORD ( RegisteredCallbacks,
|
||||||
|
CALLBACK_REGISTRATION,
|
||||||
|
RegisteredCallbacks);
|
||||||
|
|
||||||
|
/* Don't bother doing Callback Notification if it's pending to be deleted */
|
||||||
|
if (!CallbackRegistration->PendingDeletion)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Mark the Callback in use, so it won't get deleted while we are calling it */
|
||||||
|
CallbackRegistration->InUse += 1;
|
||||||
|
|
||||||
|
/* Release the Spinlock before making the call */
|
||||||
|
KfReleaseSpinLock(&CallbackObject->Lock, OldIrql);
|
||||||
|
|
||||||
|
/* Call the Registered Function */
|
||||||
|
CallbackRegistration->CallbackFunction (
|
||||||
|
CallbackRegistration->CallbackContext,
|
||||||
|
Argument1,
|
||||||
|
Argument2
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Get SpinLock back */
|
||||||
|
OldIrql = KfAcquireSpinLock(&CallbackObject->Lock);
|
||||||
|
|
||||||
|
/* We are not in use anymore */
|
||||||
|
CallbackRegistration->InUse -= 1;
|
||||||
|
|
||||||
|
/* If another instance of this function isn't running and deletion is pending, signal the event */
|
||||||
|
if (CallbackRegistration->PendingDeletion && CallbackRegistration->InUse == 0)
|
||||||
|
{
|
||||||
|
KeSetEvent(&ExpCallbackEvent, 0, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Unsynchronize and release the Callback Object */
|
||||||
|
KfReleaseSpinLock(&CallbackObject->Lock, OldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* 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
|
||||||
*/
|
*/
|
||||||
PVOID
|
PVOID
|
||||||
STDCALL
|
STDCALL
|
||||||
ExRegisterCallback (
|
ExRegisterCallback(
|
||||||
IN PCALLBACK_OBJECT CallbackObject,
|
IN PCALLBACK_OBJECT OpaqueCallbackObject,
|
||||||
IN PCALLBACK_FUNCTION CallbackFunction,
|
IN PCALLBACK_FUNCTION CallbackFunction,
|
||||||
IN PVOID CallbackContext
|
IN PVOID CallbackContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return NULL;
|
PINT_CALLBACK_OBJECT CallbackObject = (PINT_CALLBACK_OBJECT)OpaqueCallbackObject;
|
||||||
|
PCALLBACK_REGISTRATION CallbackRegistration = NULL;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
/* Create reference to Callback Object */
|
||||||
|
ObReferenceObject (CallbackObject);
|
||||||
|
|
||||||
|
/* Allocate memory for the structure */
|
||||||
|
CallbackRegistration = ExAllocatePoolWithTag(
|
||||||
|
NonPagedPool,
|
||||||
|
sizeof(CallbackRegistration),
|
||||||
|
CALLBACK_TAG
|
||||||
|
);
|
||||||
|
/* Fail if memory allocation failed */
|
||||||
|
if(!CallbackRegistration)
|
||||||
|
{
|
||||||
|
ObDereferenceObject (CallbackObject);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create Callback Registration */
|
||||||
|
CallbackRegistration->CallbackObject = CallbackObject; /* When unregistering, drivers send a handle to the Registration, not the object... */
|
||||||
|
CallbackRegistration->CallbackFunction = CallbackFunction; /* NotifyCallback uses Objects, so this needs to be here in order to call the registered functions */
|
||||||
|
CallbackRegistration->CallbackContext = CallbackContext; /* The documented NotifyCallback returns the Context, so we must save this somewhere */
|
||||||
|
|
||||||
|
/* Acquire SpinLock */
|
||||||
|
OldIrql = KfAcquireSpinLock (&CallbackObject->Lock);
|
||||||
|
|
||||||
|
/* Add Callback if 1) No Callbacks registered or 2) Multiple Callbacks allowed */
|
||||||
|
if(CallbackObject->AllowMultipleCallbacks || IsListEmpty(&CallbackObject->RegisteredCallbacks))
|
||||||
|
{
|
||||||
|
InsertTailList(&CallbackObject->RegisteredCallbacks,&CallbackRegistration->RegisteredCallbacks)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExFreePool(CallbackRegistration);
|
||||||
|
CallbackRegistration = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release SpinLock */
|
||||||
|
KfReleaseSpinLock(&CallbackObject->Lock, OldIrql);
|
||||||
|
|
||||||
|
/* Return handle to Registration Object */
|
||||||
|
return (PVOID) CallbackRegistration;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* ExUnregisterCallback
|
||||||
|
*
|
||||||
|
* FUNCTION:
|
||||||
|
* Deregisters a CallBack
|
||||||
|
*
|
||||||
|
* ARGUMENTS:
|
||||||
|
* CallbackRegistration = Callback Registration Handle
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* Nothing
|
||||||
|
*
|
||||||
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID STDCALL
|
||||||
STDCALL
|
ExUnregisterCallback(
|
||||||
ExUnregisterCallback (
|
IN PVOID CallbackRegistrationHandle
|
||||||
IN PVOID CallbackRegistration
|
)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return;
|
PCALLBACK_REGISTRATION CallbackRegistration;
|
||||||
|
PINT_CALLBACK_OBJECT CallbackObject;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
/* Convert Handle to valid Structure Pointer */
|
||||||
|
CallbackRegistration = (PCALLBACK_REGISTRATION) CallbackRegistrationHandle;
|
||||||
|
|
||||||
|
/* Get the Callback Object */
|
||||||
|
CallbackObject = CallbackRegistration->CallbackObject;
|
||||||
|
|
||||||
|
/* Lock the Object */
|
||||||
|
OldIrql = KfAcquireSpinLock (&CallbackObject->Lock);
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Similarly, we also don't want to wait ages for all pending callbacks to be called */
|
||||||
|
CallbackRegistration->PendingDeletion = TRUE;
|
||||||
|
|
||||||
|
/* We are going to wait for the event, so the Lock isn't necessary */
|
||||||
|
KfReleaseSpinLock (&CallbackObject->Lock, OldIrql);
|
||||||
|
|
||||||
|
/* Make sure the event is cleared */
|
||||||
|
KeClearEvent (&ExpCallbackEvent);
|
||||||
|
|
||||||
|
/* Wait for the Event */
|
||||||
|
KeWaitForSingleObject (
|
||||||
|
&ExpCallbackEvent,
|
||||||
|
Executive,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
/* We need the Lock again */
|
||||||
|
OldIrql = KfAcquireSpinLock(&CallbackObject->Lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the Callback */
|
||||||
|
RemoveEntryList(&CallbackRegistration->RegisteredCallbacks);
|
||||||
|
|
||||||
|
/* It's now safe to release the lock */
|
||||||
|
KfReleaseSpinLock(&CallbackObject->Lock, OldIrql);
|
||||||
|
|
||||||
|
/* Delete this registration */
|
||||||
|
ExFreePool(CallbackRegistration);
|
||||||
|
|
||||||
|
/* Remove the reference */
|
||||||
|
ObDereferenceObject(CallbackObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
91
reactos/ntoskrnl/include/internal/callbacks.h
Normal file
91
reactos/ntoskrnl/include/internal/callbacks.h
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* ReactOS kernel
|
||||||
|
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: ntoskrnl/ex/callback.h
|
||||||
|
* PURPOSE: Executive callbacks Header
|
||||||
|
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
||||||
|
* PORTABILITY: Checked.
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* Created 30/05/04
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __INCLUDE_INTERNAL_CALLBACKS_H
|
||||||
|
#define __INCLUDE_INTERNAL_CALLBACKS_H
|
||||||
|
|
||||||
|
/* Tag */
|
||||||
|
#define CALLBACK_TAG TAG('C','L','B','K')
|
||||||
|
|
||||||
|
/* ROS Callback Object */
|
||||||
|
typedef struct _INT_CALLBACK_OBJECT {
|
||||||
|
KSPIN_LOCK Lock;
|
||||||
|
LIST_ENTRY RegisteredCallbacks;
|
||||||
|
ULONG AllowMultipleCallbacks;
|
||||||
|
} _INT_CALLBACK_OBJECT , *PINT_CALLBACK_OBJECT;
|
||||||
|
|
||||||
|
/* Structure used to hold Callbacks */
|
||||||
|
typedef struct _CALLBACK_REGISTRATION {
|
||||||
|
LIST_ENTRY RegisteredCallbacks;
|
||||||
|
PINT_CALLBACK_OBJECT CallbackObject;
|
||||||
|
PCALLBACK_FUNCTION CallbackFunction;
|
||||||
|
PVOID CallbackContext;
|
||||||
|
ULONG InUse;
|
||||||
|
BOOLEAN PendingDeletion;
|
||||||
|
} CALLBACK_REGISTRATION, *PCALLBACK_REGISTRATION;
|
||||||
|
|
||||||
|
/* Add 0x1 flag to differentiate */
|
||||||
|
#define CALLBACK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x0001)
|
||||||
|
#define CALLBACK_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE|0x0001)
|
||||||
|
#define CALLBACK_WRITE (STANDARD_RIGHTS_WRITE|SYNCHRONIZE|0x0001)
|
||||||
|
#define CALLBACK_READ (STANDARD_RIGHTS_READ|SYNCHRONIZE|0x0001)
|
||||||
|
|
||||||
|
/* Mapping for Callback Object */
|
||||||
|
GENERIC_MAPPING ExpCallbackMapping =
|
||||||
|
{
|
||||||
|
CALLBACK_READ,
|
||||||
|
CALLBACK_WRITE,
|
||||||
|
CALLBACK_EXECUTE,
|
||||||
|
CALLBACK_ALL_ACCESS
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Kernel Default Callbacks */
|
||||||
|
PINT_CALLBACK_OBJECT SetSystemTimeCallback;
|
||||||
|
PINT_CALLBACK_OBJECT SetSystemStateCallback;
|
||||||
|
PINT_CALLBACK_OBJECT PowerStateCallback;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PINT_CALLBACK_OBJECT *CallbackObject;
|
||||||
|
PWSTR Name;
|
||||||
|
} SYSTEM_CALLBACKS;
|
||||||
|
|
||||||
|
SYSTEM_CALLBACKS ExpInitializeCallback[] = {
|
||||||
|
{&SetSystemTimeCallback, L"\\Callback\\SetSystemTime"},
|
||||||
|
{&SetSystemStateCallback, L"\\Callback\\SetSystemState"},
|
||||||
|
{&PowerStateCallback, L"\\Callback\\PowerState"},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Callback Event */
|
||||||
|
KEVENT ExpCallbackEvent;
|
||||||
|
|
||||||
|
/* Callback Object */
|
||||||
|
POBJECT_TYPE ExCallbackObjectType;
|
||||||
|
|
||||||
|
#endif /* __INCLUDE_INTERNAL_CALLBACKS_H */
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -81,6 +81,8 @@ VOID
|
||||||
ExInitializeWorkerThreads(VOID);
|
ExInitializeWorkerThreads(VOID);
|
||||||
VOID
|
VOID
|
||||||
ExpInitLookasideLists(VOID);
|
ExpInitLookasideLists(VOID);
|
||||||
|
VOID
|
||||||
|
ExpInitializeCallbacks(VOID);
|
||||||
|
|
||||||
/* OTHER FUNCTIONS **********************************************************/
|
/* OTHER FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: main.c,v 1.187 2004/05/29 22:10:05 hbirr Exp $
|
/* $Id: main.c,v 1.188 2004/06/19 08:48:01 navaraf Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ke/main.c
|
* FILE: ntoskrnl/ke/main.c
|
||||||
|
@ -664,6 +664,9 @@ ExpInitializeExecutive(VOID)
|
||||||
|
|
||||||
IoInit2();
|
IoInit2();
|
||||||
|
|
||||||
|
/* Initialize Callbacks before drivers */
|
||||||
|
ExpInitializeCallbacks();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load boot start drivers
|
* Load boot start drivers
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue