[ros-diffs] [ion] 25482: - Large cleanup of exported callback implementation. It was my first code to ReactOS and quite messy. - Make code use standard NT structures. - Fix object type initialization. - Fix calls to ExCreatecallback during system initalization which were randomly overwriting memory. - Fix ExREgisterCallback which was allocating only a pointer inside of the entire structure, also over-writing system memory.

ion at svn.reactos.org ion at svn.reactos.org
Tue Jan 16 05:16:32 CET 2007


Author: ion
Date: Tue Jan 16 07:16:31 2007
New Revision: 25482

URL: http://svn.reactos.org/svn/reactos?rev=25482&view=rev
Log:
- Large cleanup of exported callback implementation. It was my first code to ReactOS and quite messy.
- Make code use standard NT structures.
- Fix object type initialization.
- Fix calls to ExCreatecallback during system initalization which were randomly overwriting memory.
- Fix ExREgisterCallback which was allocating only a pointer inside of the entire structure, also over-writing system memory.

Modified:
    trunk/reactos/include/ndk/extypes.h
    trunk/reactos/ntoskrnl/ex/callback.c
    trunk/reactos/ntoskrnl/include/internal/ex.h

Modified: trunk/reactos/include/ndk/extypes.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/extypes.h?rev=25482&r1=25481&r2=25482&view=diff
==============================================================================
--- trunk/reactos/include/ndk/extypes.h (original)
+++ trunk/reactos/include/ndk/extypes.h Tue Jan 16 07:16:31 2007
@@ -488,11 +488,25 @@
 //
 typedef struct _CALLBACK_OBJECT
 {
-    ULONG Name;
+    ULONG Signature;
     KSPIN_LOCK Lock;
     LIST_ENTRY RegisteredCallbacks;
-    ULONG AllowMultipleCallbacks;
-} CALLBACK_OBJECT , *PCALLBACK_OBJECT;
+    BOOLEAN AllowMultipleCallbacks;
+    UCHAR reserved[3];
+} CALLBACK_OBJECT, *PCALLBACK_OBJECT;
+
+//
+// Callback Handle
+//
+typedef struct _CALLBACK_REGISTRATION
+{
+    LIST_ENTRY Link;
+    PCALLBACK_OBJECT CallbackObject;
+    PCALLBACK_FUNCTION CallbackFunction;
+    PVOID CallbackContext;
+    ULONG Busy;
+    BOOLEAN UnregisterWaiting;
+} CALLBACK_REGISTRATION, *PCALLBACK_REGISTRATION;
 
 //
 // Internal Callback Object

Modified: trunk/reactos/ntoskrnl/ex/callback.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/callback.c?rev=25482&r1=25481&r2=25482&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ex/callback.c (original)
+++ trunk/reactos/ntoskrnl/ex/callback.c Tue Jan 16 07:16:31 2007
@@ -3,54 +3,30 @@
  * LICENSE:         GPL - See COPYING in the top level directory
  * FILE:            ntoskrnl/ex/callback.c
  * PURPOSE:         Executive callbacks
- * PROGRAMMERS:     Filip Navara
- *                  Alex Ionescu (alex at relsoft.net)
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu at reactos.org)
  */
 
-/* INCLUDES *****************************************************************/
+/* INCLUDES ******************************************************************/
 
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <internal/debug.h>
 
-#if defined (ALLOC_PRAGMA)
-#pragma alloc_text(INIT, ExpInitializeCallbacks)
-#endif
-
-
-/* TYPES ********************************************************************/
+/* TYPES *********************************************************************/
 
 /* Mapping for Callback Object */
 GENERIC_MAPPING ExpCallbackMapping =
 {
-   CALLBACK_READ,
-   CALLBACK_WRITE,
-   CALLBACK_EXECUTE,
-   CALLBACK_ALL_ACCESS
+    CALLBACK_READ,
+    CALLBACK_WRITE,
+    CALLBACK_EXECUTE,
+    CALLBACK_ALL_ACCESS
 };
-
-/* Structure used to hold Callbacks */
-typedef struct _CALLBACK_REGISTRATION
-{
-   LIST_ENTRY RegisteredCallbacks;
-   PCALLBACK_OBJECT CallbackObject;
-   PCALLBACK_FUNCTION CallbackFunction;
-   PVOID CallbackContext;
-   ULONG InUse;
-   BOOLEAN PendingDeletion;
-} CALLBACK_REGISTRATION, *PCALLBACK_REGISTRATION;
-
-typedef struct
-{
-    PCALLBACK_OBJECT *CallbackObject;
-    PWSTR Name;
-} SYSTEM_CALLBACKS;
 
 /* Kernel Default Callbacks */
 PCALLBACK_OBJECT SetSystemTimeCallback;
 PCALLBACK_OBJECT SetSystemStateCallback;
 PCALLBACK_OBJECT PowerStateCallback;
-
 SYSTEM_CALLBACKS ExpInitializeCallback[] =
 {
    {&SetSystemTimeCallback, L"\\Callback\\SetSystemTime"},
@@ -62,7 +38,15 @@
 POBJECT_TYPE ExCallbackObjectType;
 KEVENT ExpCallbackEvent;
 
-/* FUNCTIONS *****************************************************************/
+/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID
+NTAPI
+ExpDeleteCallback(IN PVOID Object)
+{
+    /* Sanity check */
+    ASSERT(IsListEmpty(&((PCALLBACK_OBJECT)Object)->RegisteredCallbacks));
+}
 
 /*++
  * @name ExpInitializeCallbacks
@@ -75,7 +59,7 @@
  * @remarks None
  *
  *--*/
-VOID
+BOOLEAN
 INIT_FUNCTION
 NTAPI
 ExpInitializeCallbacks(VOID)
@@ -89,43 +73,33 @@
     HANDLE DirectoryHandle;
     ULONG i;
 
-    /*  Initialize the Callback Object type  */
+    /* Initialize the Callback Object type  */
     RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
     RtlInitUnicodeString(&Name, L"Callback");
     ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
-    ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(CALLBACK_OBJECT);
+    ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
     ObjectTypeInitializer.GenericMapping = ExpCallbackMapping;
     ObjectTypeInitializer.PoolType = NonPagedPool;
-
-    Status = ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ExCallbackObjectType);
-
-    /* Fail if it wasn't created successfully */
-    if (!NT_SUCCESS(Status))
-    {
-        return;
-    }
+    ObjectTypeInitializer.DeleteProcedure = ExpDeleteCallback;
+    ObjectTypeInitializer.ValidAccessMask = CALLBACK_ALL_ACCESS;
+    Status = ObCreateObjectType(&Name,
+                                &ObjectTypeInitializer,
+                                NULL,
+                                &ExCallbackObjectType);
+    if (!NT_SUCCESS(Status)) return FALSE;
 
     /* Initialize the Object */
-    InitializeObjectAttributes(
-        &ObjectAttributes,
-        &DirName,
-        OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
-        NULL,
-        NULL
-        );
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &DirName,
+                               OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
+                               NULL,
+                               SePublicDefaultSd);
 
     /* Create the Object Directory */
-    Status = NtCreateDirectoryObject(
-        &DirectoryHandle,
-        DIRECTORY_ALL_ACCESS,
-        &ObjectAttributes
-        );
-
-    /* Fail if couldn't create */
-    if (!NT_SUCCESS(Status))
-    {
-        return;
-    }
+    Status = NtCreateDirectoryObject(&DirectoryHandle,
+                                     DIRECTORY_ALL_ACCESS,
+                                     &ObjectAttributes);
+    if (!NT_SUCCESS(Status)) return FALSE;
 
     /* Close Handle... */
     NtClose(DirectoryHandle);
@@ -134,36 +108,31 @@
     KeInitializeEvent(&ExpCallbackEvent, NotificationEvent, 0);
 
     /* Default NT Kernel Callbacks. */
-    for (i=0; ExpInitializeCallback[i].CallbackObject; i++)
+    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
-            );
+        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;
-        }
-    }
+        Status = ExCreateCallback(ExpInitializeCallback[i].CallbackObject,
+                                  &ObjectAttributes,
+                                  TRUE,
+                                  TRUE);
+        if (!NT_SUCCESS(Status)) return FALSE;
+    }
+
     /* Everything successful */
-}
+    return TRUE;
+}
+
+/* PUBLIC FUNCTIONS **********************************************************/
 
 /*++
  * @name ExCreateCallback
@@ -200,15 +169,15 @@
                  IN BOOLEAN Create,
                  IN BOOLEAN AllowMultipleCallbacks)
 {
-    PCALLBACK_OBJECT Callback;
-    NTSTATUS    Status;
-    HANDLE     Handle;
-
+    PCALLBACK_OBJECT Callback = NULL;
+    NTSTATUS Status;
+    HANDLE Handle = NULL;
     PAGED_CODE();
 
     /* Open a handle to the callback if it exists */
     if (ObjectAttributes->ObjectName)
     {
+        /* Open the handle */
         Status = ObOpenObjectByName(ObjectAttributes,
                                     ExCallbackObjectType,
                                     KernelMode,
@@ -219,12 +188,14 @@
     }
     else
     {
+        /* Otherwise, fail */
         Status = STATUS_UNSUCCESSFUL;
     }
 
     /* We weren't able to open it...should we create it? */
-    if(!NT_SUCCESS(Status) && Create )
-    {
+    if (!(NT_SUCCESS(Status)) && (Create))
+    {
+        /* Create the object */
         Status = ObCreateObject(KernelMode,
                                 ExCallbackObjectType,
                                 ObjectAttributes,
@@ -233,25 +204,27 @@
                                 sizeof(CALLBACK_OBJECT),
                                 0,
                                 0,
-                                (PVOID *)&Callback );
-
-        /* We Created it...let's initialize the structure now */
-        if(NT_SUCCESS(Status))
+                                (PVOID *)&Callback);
+        if (NT_SUCCESS(Status))
         {
-            KeInitializeSpinLock(&Callback->Lock);      /*  SpinLock   */
-            InitializeListHead(&Callback->RegisteredCallbacks);   /*  Callback Entries */
-            Callback->AllowMultipleCallbacks = AllowMultipleCallbacks; /*  Multiple Callbacks */
-            /*  Create the object */
+            /* Set it up */
+            Callback->Signature = TAG('C', 'a', 'l', 'l');
+            KeInitializeSpinLock(&Callback->Lock);
+            InitializeListHead(&Callback->RegisteredCallbacks);
+            Callback->AllowMultipleCallbacks = AllowMultipleCallbacks;
+
+            /* Insert the object into the object namespace */
             Status = ObInsertObject(Callback,
                                     NULL,
                                     FILE_READ_DATA,
                                     0,
                                     NULL,
-                                    &Handle );
+                                    &Handle);
         }
     }
 
-    if(NT_SUCCESS(Status))
+    /* Check if we have success until here */
+    if (NT_SUCCESS(Status))
     {
         /* Get a pointer to the new object from the handle we just got */
         Status = ObReferenceObjectByHandle(Handle,
@@ -260,15 +233,13 @@
                                            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;
-    }
+    if (NT_SUCCESS(Status)) *CallbackObject = Callback;
     return Status;
 }
 
@@ -278,7 +249,6 @@
  *
  * 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
@@ -297,17 +267,24 @@
  *--*/
 VOID
 NTAPI
-ExNotifyCallback(IN PCALLBACK_OBJECT OpaqueCallbackObject,
+ExNotifyCallback(IN PCALLBACK_OBJECT CallbackObject,
                  IN PVOID Argument1,
                  IN PVOID Argument2)
 {
-    PCALLBACK_OBJECT   CallbackObject = (PCALLBACK_OBJECT)OpaqueCallbackObject;
-    PLIST_ENTRY             RegisteredCallbacks;
-    PCALLBACK_REGISTRATION  CallbackRegistration;
-    KIRQL                   OldIrql;
+    PLIST_ENTRY RegisteredCallbacks;
+    PCALLBACK_REGISTRATION CallbackRegistration;
+    KIRQL OldIrql;
+
+    /* Check if we don't have an object or registrations */
+    if (!(CallbackObject) ||
+        (IsListEmpty(&CallbackObject->RegisteredCallbacks)))
+    {
+        /* Don't notify */
+        return;
+    }
 
     /* Acquire the Lock */
-    OldIrql = KfAcquireSpinLock(&CallbackObject->Lock);
+    KeAcquireSpinLock(&CallbackObject->Lock, &OldIrql);
 
     /* Enumerate through all the registered functions */
     for (RegisteredCallbacks = CallbackObject->RegisteredCallbacks.Flink;
@@ -317,39 +294,41 @@
         /* 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)
+                                                 Link);
+
+        /* Don't bother doing notification if it's pending to be deleted */
+        if (!CallbackRegistration->UnregisterWaiting)
         {
-            /* Mark the Callback in use, so it won't get deleted while we are calling it */
-            CallbackRegistration->InUse += 1;
+            /* Mark the Callback in use, so it won't get deleted */
+            CallbackRegistration->Busy += 1;
 
             /* Release the Spinlock before making the call */
-            KfReleaseSpinLock(&CallbackObject->Lock, OldIrql);
+            KeReleaseSpinLock(&CallbackObject->Lock, OldIrql);
 
             /* Call the Registered Function */
-            CallbackRegistration->CallbackFunction(
-                CallbackRegistration->CallbackContext,
-                Argument1,
-                Argument2
-                );
+            CallbackRegistration->CallbackFunction(CallbackRegistration->
+                                                   CallbackContext,
+                                                   Argument1,
+                                                   Argument2);
 
             /* Get SpinLock back */
-            OldIrql = KfAcquireSpinLock(&CallbackObject->Lock);
+            KeAcquireSpinLock(&CallbackObject->Lock, &OldIrql);
 
             /* 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)
+            CallbackRegistration->Busy -= 1;
+
+            /* Check if removal is pending and we're not active */
+            if ((CallbackRegistration->UnregisterWaiting) &&
+                !(CallbackRegistration->Busy))
             {
+                /* Signal the callback event */
                 KeSetEvent(&ExpCallbackEvent, 0, FALSE);
             }
         }
     }
-    /* Unsynchronize and release the Callback Object */
-    KfReleaseSpinLock(&CallbackObject->Lock, OldIrql);
+
+    /* Release the Callback Object */
+    KeReleaseSpinLock(&CallbackObject->Lock, OldIrql);
 }
 
 /*++
@@ -377,53 +356,64 @@
  *--*/
 PVOID
 NTAPI
-ExRegisterCallback(IN PCALLBACK_OBJECT OpaqueCallbackObject,
+ExRegisterCallback(IN PCALLBACK_OBJECT CallbackObject,
                    IN PCALLBACK_FUNCTION CallbackFunction,
                    IN PVOID CallbackContext)
 {
-    PCALLBACK_OBJECT CallbackObject = (PCALLBACK_OBJECT)OpaqueCallbackObject;
-    PCALLBACK_REGISTRATION  CallbackRegistration = NULL;
-    KIRQL     OldIrql;
-
-    PAGED_CODE();
+    PCALLBACK_REGISTRATION CallbackRegistration = NULL;
+    KIRQL OldIrql;
+
+    /* Sanity checks */
+    ASSERT(CallbackFunction);
+    ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
 
     /* Create reference to Callback Object */
-    ObReferenceObject (CallbackObject);
+    ObReferenceObject(CallbackObject);
 
     /* Allocate memory for the structure */
-    CallbackRegistration = ExAllocatePoolWithTag(
-                               NonPagedPool,
-                               sizeof(CallbackRegistration),
-                               CALLBACK_TAG
-                               );
-    /* Fail if memory allocation failed */
-    if(!CallbackRegistration)
-    {
+    CallbackRegistration = ExAllocatePoolWithTag(NonPagedPool,
+                                                 sizeof(CALLBACK_REGISTRATION),
+                                                 CALLBACK_TAG);
+    if (!CallbackRegistration)
+    {
+        /* Dereference and fail */
         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 */
+    CallbackRegistration->CallbackObject = CallbackObject;
+    CallbackRegistration->CallbackFunction = CallbackFunction;
+    CallbackRegistration->CallbackContext = CallbackContext;
+    CallbackRegistration->Busy = 0;
+    CallbackRegistration->UnregisterWaiting = FALSE;
 
     /* 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);
+    KeAcquireSpinLock(&CallbackObject->Lock, &OldIrql);
+
+    /* Check if 1) No Callbacks registered or 2) Multiple Callbacks allowed */
+    if ((CallbackObject->AllowMultipleCallbacks) ||
+        (IsListEmpty(&CallbackObject->RegisteredCallbacks)))
+    {
+        /* Register the callback */
+        InsertTailList(&CallbackObject->RegisteredCallbacks,
+                       &CallbackRegistration->Link);
+
+        /* Release SpinLock */
+        KeReleaseSpinLock(&CallbackObject->Lock, OldIrql);
     }
     else
     {
+        /* Release SpinLock */
+        KeReleaseSpinLock(&CallbackObject->Lock, OldIrql);
+
+        /* Free the registration */
         ExFreePool(CallbackRegistration);
         CallbackRegistration = NULL;
-    }
-
-    /* Release SpinLock */
-    KfReleaseSpinLock(&CallbackObject->Lock, OldIrql);
+
+        /* Dereference the object */
+        ObDereferenceObject(CallbackObject);
+    }
 
     /* Return handle to Registration Object */
     return (PVOID)CallbackRegistration;
@@ -448,51 +438,48 @@
 NTAPI
 ExUnregisterCallback(IN PVOID CallbackRegistrationHandle)
 {
-    PCALLBACK_REGISTRATION  CallbackRegistration;
-    PCALLBACK_OBJECT    CallbackObject;
-    KIRQL                   OldIrql;
-
-    PAGED_CODE();
+    PCALLBACK_REGISTRATION CallbackRegistration;
+    PCALLBACK_OBJECT CallbackObject;
+    KIRQL OldIrql;
+    ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
 
     /* Convert Handle to valid Structure Pointer */
-    CallbackRegistration = (PCALLBACK_REGISTRATION) CallbackRegistrationHandle;
+    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;
+    KeAcquireSpinLock (&CallbackObject->Lock, &OldIrql);
+
+    /* We can't Delete the Callback if it's in use */
+    while (CallbackRegistration->Busy)
+    {
+        /* Let everyone else know we're unregistering */
+        CallbackRegistration->UnregisterWaiting = TRUE;
 
         /* We are going to wait for the event, so the Lock isn't necessary */
-        KfReleaseSpinLock (&CallbackObject->Lock, OldIrql);
+        KeReleaseSpinLock(&CallbackObject->Lock, OldIrql);
 
         /* Make sure the event is cleared */
-        KeClearEvent (&ExpCallbackEvent);
+        KeClearEvent(&ExpCallbackEvent);
 
         /* Wait for the Event */
-        KeWaitForSingleObject (
-            &ExpCallbackEvent,
-            Executive,
-            KernelMode,
-            FALSE,
-            NULL
-            );
+        KeWaitForSingleObject(&ExpCallbackEvent,
+                              Executive,
+                              KernelMode,
+                              FALSE,
+                              NULL);
 
         /* We need the Lock again */
-        OldIrql = KfAcquireSpinLock(&CallbackObject->Lock);
+        KeAcquireSpinLock(&CallbackObject->Lock, &OldIrql);
     }
 
     /* Remove the Callback */
-    RemoveEntryList(&CallbackRegistration->RegisteredCallbacks);
+    RemoveEntryList(&CallbackRegistration->Link);
 
     /* It's now safe to release the lock */
-    KfReleaseSpinLock(&CallbackObject->Lock, OldIrql);
+    KeReleaseSpinLock(&CallbackObject->Lock, OldIrql);
 
     /* Delete this registration */
     ExFreePool(CallbackRegistration);

Modified: trunk/reactos/ntoskrnl/include/internal/ex.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ex.h?rev=25482&r1=25481&r2=25482&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ex.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ex.h Tue Jan 16 07:16:31 2007
@@ -34,6 +34,12 @@
     LIST_ENTRY WakeTimerListEntry;
 } ETIMER, *PETIMER;
 
+typedef struct
+{
+    PCALLBACK_OBJECT *CallbackObject;
+    PWSTR Name;
+} SYSTEM_CALLBACKS;
+
 #define MAX_FAST_REFS           7
 
 #define EX_OBJ_TO_HDR(eob) ((POBJECT_HEADER)((ULONG_PTR)(eob) &                \
@@ -107,7 +113,7 @@
     IN PLIST_ENTRY ListHead
 );
 
-VOID
+BOOLEAN
 NTAPI
 ExpInitializeCallbacks(VOID);
 




More information about the Ros-diffs mailing list