ReactOS  0.4.14-dev-77-gd9e7c48
callback.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for callback.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NTAPI ExInitializeCallBack (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 CallbackBlock)
 
VOID NTAPI ExWaitForCallBacks (IN PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock)
 
PEX_CALLBACK_FUNCTION NTAPI ExGetCallBackBlockRoutine (IN PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock)
 
PVOID NTAPI ExGetCallBackBlockContext (IN PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock)
 
VOID NTAPI ExDereferenceCallBackBlock (IN OUT PEX_CALLBACK CallBack, IN PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock)
 
PEX_CALLBACK_ROUTINE_BLOCK NTAPI ExReferenceCallBackBlock (IN OUT PEX_CALLBACK CallBack)
 
BOOLEAN NTAPI ExCompareExchangeCallBack (IN OUT PEX_CALLBACK CallBack, IN PEX_CALLBACK_ROUTINE_BLOCK NewBlock, IN PEX_CALLBACK_ROUTINE_BLOCK OldBlock)
 
VOID NTAPI ExpDeleteCallback (IN PVOID Object)
 
BOOLEAN INIT_FUNCTION NTAPI ExpInitializeCallbacks (VOID)
 
NTSTATUS NTAPI ExCreateCallback (OUT PCALLBACK_OBJECT *CallbackObject, IN POBJECT_ATTRIBUTES ObjectAttributes, IN BOOLEAN Create, IN BOOLEAN AllowMultipleCallbacks)
 
VOID NTAPI ExNotifyCallback (IN PCALLBACK_OBJECT CallbackObject, IN PVOID Argument1, IN PVOID Argument2)
 
PVOID NTAPI ExRegisterCallback (IN PCALLBACK_OBJECT CallbackObject, IN PCALLBACK_FUNCTION CallbackFunction, IN PVOID CallbackContext)
 
VOID NTAPI ExUnregisterCallback (IN PVOID CallbackRegistrationHandle)
 

Variables

GENERIC_MAPPING ExpCallbackMapping
 
PCALLBACK_OBJECT SetSystemTimeCallback
 
PCALLBACK_OBJECT SetSystemStateCallback
 
PCALLBACK_OBJECT PowerStateCallback
 
SYSTEM_CALLBACKS ExpInitializeCallback []
 
POBJECT_TYPE ExCallbackObjectType
 
KEVENT ExpCallbackEvent
 
EX_PUSH_LOCK ExpCallBackFlush
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file callback.c.

Function Documentation

◆ ExAllocateCallBack()

PEX_CALLBACK_ROUTINE_BLOCK NTAPI ExAllocateCallBack ( IN PEX_CALLBACK_FUNCTION  Function,
IN PVOID  Context 
)

Definition at line 54 of file callback.c.

56 {
57  PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock;
58 
59  /* Allocate a callback */
60  CallbackBlock = ExAllocatePoolWithTag(PagedPool,
63  if (CallbackBlock)
64  {
65  /* Initialize it */
66  CallbackBlock->Function = Function;
67  CallbackBlock->Context = Context;
69  }
70 
71  /* Return it */
72  return CallbackBlock;
73 }
NTKERNELAPI VOID FASTCALL ExInitializeRundownProtection(_Out_ PEX_RUNDOWN_REF RunRef)
PEX_CALLBACK_FUNCTION Function
Definition: extypes.h:538
static LPOVERLAPPED_COMPLETION_ROUTINE Function
Definition: sync.c:684
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
EX_RUNDOWN_REF RundownProtect
Definition: extypes.h:537
struct tagContext Context
Definition: acpixf.h:1024
#define TAG_CALLBACK_ROUTINE_BLOCK
Definition: tag.h:11

Referenced by PsSetCreateProcessNotifyRoutine(), PsSetCreateThreadNotifyRoutine(), PsSetLoadImageNotifyRoutine(), and TestPrivateFunctions().

◆ ExCompareExchangeCallBack()

BOOLEAN NTAPI ExCompareExchangeCallBack ( IN OUT PEX_CALLBACK  CallBack,
IN PEX_CALLBACK_ROUTINE_BLOCK  NewBlock,
IN PEX_CALLBACK_ROUTINE_BLOCK  OldBlock 
)

Definition at line 170 of file callback.c.

173 {
174  EX_FAST_REF OldValue;
175  PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock;
176  ULONG Count;
177 
178  /* Check that we have a new block */
179  if (NewBlock)
180  {
181  /* Acquire rundown */
182  if (!ExfAcquireRundownProtectionEx(&NewBlock->RundownProtect,
183  MAX_FAST_REFS + 1))
184  {
185  /* This should never happen */
186  ASSERTMSG("Callback block is already undergoing rundown\n", FALSE);
187  return FALSE;
188  }
189  }
190 
191  /* Do the swap */
192  OldValue = ExCompareSwapFastReference(&CallBack->RoutineBlock,
193  NewBlock,
194  OldBlock);
195 
196  /* Get the routine block */
197  CallbackBlock = ExGetObjectFastReference(OldValue);
198  Count = ExGetCountFastReference(OldValue);
199 
200  /* Make sure the swap worked */
201  if (CallbackBlock == OldBlock)
202  {
203  /* Make sure we replaced a valid pointer */
204  if (CallbackBlock)
205  {
206  /* Acquire the flush lock and immediately release it */
209 
210  /* Release rundown protection */
213  Count + 1);
214  }
215 
216  /* Compare worked */
217  return TRUE;
218  }
219  else
220  {
221  /* It failed, check if we had a block */
222  if (NewBlock)
223  {
224  /* We did, remove the references that we had added */
225  ExfReleaseRundownProtectionEx(&NewBlock->RundownProtect,
226  MAX_FAST_REFS + 1);
227  }
228 
229  /* Return failure */
230  return FALSE;
231  }
232 }
FORCEINLINE PVOID ExGetObjectFastReference(IN EX_FAST_REF FastRef)
Definition: ex.h:566
#define TRUE
Definition: types.h:120
FORCEINLINE VOID ExWaitOnPushLock(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1164
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
EX_PUSH_LOCK ExpCallBackFlush
Definition: callback.c:40
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
FORCEINLINE ULONG ExGetCountFastReference(IN EX_FAST_REF FastRef)
Definition: ex.h:574
VOID FASTCALL ExfReleaseRundownProtectionEx(IN PEX_RUNDOWN_REF RunRef, IN ULONG Count)
Definition: rundown.c:260
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
FORCEINLINE EX_FAST_REF ExCompareSwapFastReference(IN PEX_FAST_REF FastRef, IN PVOID Object, IN PVOID OldObject)
Definition: ex.h:733
BOOLEAN FASTCALL ExfAcquireRundownProtectionEx(IN PEX_RUNDOWN_REF RunRef, IN ULONG Count)
Definition: rundown.c:78
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
EX_RUNDOWN_REF RundownProtect
Definition: extypes.h:537
unsigned int ULONG
Definition: retypes.h:1
#define MAX_FAST_REFS
Definition: ex.h:128

Referenced by PsRemoveCreateThreadNotifyRoutine(), PsRemoveLoadImageNotifyRoutine(), PsSetCreateProcessNotifyRoutine(), PsSetCreateThreadNotifyRoutine(), and PsSetLoadImageNotifyRoutine().

◆ ExCreateCallback()

NTSTATUS NTAPI ExCreateCallback ( OUT PCALLBACK_OBJECT CallbackObject,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN BOOLEAN  Create,
IN BOOLEAN  AllowMultipleCallbacks 
)

Definition at line 361 of file callback.c.

365 {
368  HANDLE Handle = NULL;
369  PAGED_CODE();
370 
371  /* Open a handle to the callback if it exists */
372  if (ObjectAttributes->ObjectName)
373  {
374  /* Open the handle */
377  KernelMode,
378  NULL,
379  0,
380  NULL,
381  &Handle);
382  }
383  else
384  {
385  /* Otherwise, fail */
387  }
388 
389  /* We weren't able to open it...should we create it? */
390  if (!(NT_SUCCESS(Status)) && (Create))
391  {
392  /* Create the object */
396  KernelMode,
397  NULL,
398  sizeof(CALLBACK_OBJECT),
399  0,
400  0,
401  (PVOID *)&Callback);
402  if (NT_SUCCESS(Status))
403  {
404  /* Set it up */
405  Callback->Signature = 'llaC';
407  InitializeListHead(&Callback->RegisteredCallbacks);
408  Callback->AllowMultipleCallbacks = AllowMultipleCallbacks;
409 
410  /* Insert the object into the object namespace */
412  NULL,
414  0,
415  NULL,
416  &Handle);
417  }
418  }
419 
420  /* Check if we have success until here */
421  if (NT_SUCCESS(Status))
422  {
423  /* Get a pointer to the new object from the handle we just got */
425  0,
427  KernelMode,
428  (PVOID *)&Callback,
429  NULL);
430 
431  /* Close the Handle, since we now have the pointer */
432  ZwClose(Handle);
433  }
434 
435  /* Everything went fine, so return a pointer to the Object */
436  if (NT_SUCCESS(Status))
437  {
438  *CallbackObject = Callback;
439  }
440  return Status;
441 }
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2529
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_In_ BOOLEAN Create
Definition: pstypes.h:511
POBJECT_TYPE ExCallbackObjectType
Definition: callback.c:38
LONG NTSTATUS
Definition: precomp.h:26
#define PAGED_CODE()
Definition: video.h:57
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
#define FILE_READ_DATA
Definition: nt_native.h:628
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
_In_ POBJECT_ATTRIBUTES _In_ BOOLEAN _In_ BOOLEAN AllowMultipleCallbacks
Definition: exfuncs.h:590
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
_In_ HANDLE Handle
Definition: extypes.h:390
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2932
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
LPFNPSPCALLBACK Callback
Definition: desk.c:111

Referenced by DriverEntry(), ExpInitializeCallbacks(), and START_TEST().

◆ ExDereferenceCallBackBlock()

VOID NTAPI ExDereferenceCallBackBlock ( IN OUT PEX_CALLBACK  CallBack,
IN PEX_CALLBACK_ROUTINE_BLOCK  CallbackBlock 
)

Definition at line 109 of file callback.c.

111 {
112  /* Release a fast reference */
113  if (!ExReleaseFastReference(&CallBack->RoutineBlock, CallbackBlock))
114  {
115  /* Take slow path */
116  ExReleaseRundownProtection(&CallbackBlock->RundownProtect);
117  }
118 }
NTKERNELAPI VOID FASTCALL ExReleaseRundownProtection(_Inout_ PEX_RUNDOWN_REF RunRef)
FORCEINLINE BOOLEAN ExReleaseFastReference(IN PEX_FAST_REF FastRef, IN PVOID Object)
Definition: ex.h:671

Referenced by ExDoCallBack(), PsRemoveCreateThreadNotifyRoutine(), PsRemoveLoadImageNotifyRoutine(), and PsSetCreateProcessNotifyRoutine().

◆ ExFreeCallBack()

VOID NTAPI ExFreeCallBack ( IN PEX_CALLBACK_ROUTINE_BLOCK  CallbackBlock)

Definition at line 77 of file callback.c.

78 {
79  /* Just free it from memory */
81 }
#define TAG_CALLBACK_ROUTINE_BLOCK
Definition: tag.h:11
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by PsRemoveCreateThreadNotifyRoutine(), PsRemoveLoadImageNotifyRoutine(), PsSetCreateProcessNotifyRoutine(), PsSetCreateThreadNotifyRoutine(), PsSetLoadImageNotifyRoutine(), and TestPrivateFunctions().

◆ ExGetCallBackBlockContext()

PVOID NTAPI ExGetCallBackBlockContext ( IN PEX_CALLBACK_ROUTINE_BLOCK  CallbackBlock)

Definition at line 101 of file callback.c.

102 {
103  /* Return the context */
104  return CallbackBlock->Context;
105 }

◆ ExGetCallBackBlockRoutine()

PEX_CALLBACK_FUNCTION NTAPI ExGetCallBackBlockRoutine ( IN PEX_CALLBACK_ROUTINE_BLOCK  CallbackBlock)

Definition at line 93 of file callback.c.

94 {
95  /* Return the function */
96  return CallbackBlock->Function;
97 }

Referenced by ExDoCallBack(), PsRemoveCreateThreadNotifyRoutine(), PsRemoveLoadImageNotifyRoutine(), and PsSetCreateProcessNotifyRoutine().

◆ ExInitializeCallBack()

VOID NTAPI ExInitializeCallBack ( IN OUT PEX_CALLBACK  Callback)

Definition at line 46 of file callback.c.

47 {
48  /* Initialize the fast reference */
49  ExInitializeFastReference(&Callback->RoutineBlock, NULL);
50 }
FORCEINLINE VOID ExInitializeFastReference(OUT PEX_FAST_REF FastRef, IN OPTIONAL PVOID Object)
Definition: ex.h:582
smooth NULL
Definition: ftsmooth.c:416
LPFNPSPCALLBACK Callback
Definition: desk.c:111

Referenced by CmpInitCallback(), and PspInitPhase0().

◆ ExNotifyCallback()

VOID NTAPI ExNotifyCallback ( IN PCALLBACK_OBJECT  CallbackObject,
IN PVOID  Argument1,
IN PVOID  Argument2 
)

Definition at line 467 of file callback.c.

470 {
471  PLIST_ENTRY RegisteredCallbacks;
472  PCALLBACK_REGISTRATION CallbackRegistration;
473  KIRQL OldIrql;
474 
475  /* Check if we don't have an object or registrations */
476  if (!(CallbackObject) ||
477  (IsListEmpty(&CallbackObject->RegisteredCallbacks)))
478  {
479  /* Don't notify */
480  return;
481  }
482 
483  /* Acquire the Lock */
484  KeAcquireSpinLock(&CallbackObject->Lock, &OldIrql);
485 
486  /* Enumerate through all the registered functions */
487  for (RegisteredCallbacks = CallbackObject->RegisteredCallbacks.Flink;
488  RegisteredCallbacks != &CallbackObject->RegisteredCallbacks;
489  RegisteredCallbacks = RegisteredCallbacks->Flink)
490  {
491  /* Get a pointer to a Callback Registration from the List Entries */
492  CallbackRegistration = CONTAINING_RECORD(RegisteredCallbacks,
494  Link);
495 
496  /* Don't bother doing notification if it's pending to be deleted */
497  if (!CallbackRegistration->UnregisterWaiting)
498  {
499  /* Mark the Callback in use, so it won't get deleted */
500  CallbackRegistration->Busy += 1;
501 
502  /* Release the Spinlock before making the call */
503  KeReleaseSpinLock(&CallbackObject->Lock, OldIrql);
504 
505  /* Call the Registered Function */
506  CallbackRegistration->CallbackFunction(CallbackRegistration->
508  Argument1,
509  Argument2);
510 
511  /* Get SpinLock back */
512  KeAcquireSpinLock(&CallbackObject->Lock, &OldIrql);
513 
514  /* We are not in use anymore */
515  CallbackRegistration->Busy -= 1;
516 
517  /* Check if removal is pending and we're not active */
518  if ((CallbackRegistration->UnregisterWaiting) &&
519  !(CallbackRegistration->Busy))
520  {
521  /* Signal the callback event */
523  }
524  }
525  }
526 
527  /* Release the Callback Object */
528  KeReleaseSpinLock(&CallbackObject->Lock, OldIrql);
529 }
BOOLEAN UnregisterWaiting
Definition: extypes.h:529
PCALLBACK_FUNCTION CallbackFunction
Definition: extypes.h:526
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG _In_opt_ PEVENT_FILTER_DESCRIPTOR _Inout_opt_ PVOID CallbackContext
Definition: wmitypes.h:55
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:694
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
static int Link(const char **args)
Definition: vfdcmd.c:2414
KEVENT ExpCallbackEvent
Definition: callback.c:39
UCHAR KIRQL
Definition: env_spec_w32.h:591
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_In_ PVOID Argument2
Definition: classpnp.h:680
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: typedefs.h:117
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627

Referenced by NtSetSystemPowerState(), PoNotifySystemTimeSet(), and START_TEST().

◆ ExpDeleteCallback()

VOID NTAPI ExpDeleteCallback ( IN PVOID  Object)

Definition at line 236 of file callback.c.

237 {
238  /* Sanity check */
239  ASSERT(IsListEmpty(&((PCALLBACK_OBJECT)Object)->RegisteredCallbacks));
240 }
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
static IUnknown Object
Definition: main.c:512
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

Referenced by ExpInitializeCallbacks().

◆ ExpInitializeCallbacks()

BOOLEAN INIT_FUNCTION NTAPI ExpInitializeCallbacks ( VOID  )

Definition at line 256 of file callback.c.

257 {
261  UNICODE_STRING CallbackName;
263  OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
265  ULONG i;
266 
267  /* Setup lightweight callback lock */
269 
270  /* Initialize the Callback Object type */
271  RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
272  RtlInitUnicodeString(&Name, L"Callback");
273  ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
274  ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
275  ObjectTypeInitializer.GenericMapping = ExpCallbackMapping;
276  ObjectTypeInitializer.PoolType = NonPagedPool;
277  ObjectTypeInitializer.DeleteProcedure = ExpDeleteCallback;
278  ObjectTypeInitializer.ValidAccessMask = CALLBACK_ALL_ACCESS;
280  &ObjectTypeInitializer,
281  NULL,
283  if (!NT_SUCCESS(Status)) return FALSE;
284 
285  /* Initialize the Object */
287  &DirName,
289  NULL,
291 
292  /* Create the Object Directory */
296  if (!NT_SUCCESS(Status)) return FALSE;
297 
298  /* Close Handle... */
300 
301  /* Initialize Event used when unregistering */
303 
304  /* Default NT Kernel Callbacks. */
305  for (i = 0; ExpInitializeCallback[i].CallbackObject; i++)
306  {
307  /* Create the name from the structure */
309 
310  /* Initialize the Object Attributes Structure */
312  &CallbackName,
314  NULL,
315  NULL);
316 
317  /* Create the Callback Object */
320  TRUE,
321  TRUE);
322  if (!NT_SUCCESS(Status)) return FALSE;
323  }
324 
325  /* Everything successful */
326  return TRUE;
327 }
ULONG_PTR Value
Definition: extypes.h:465
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define CALLBACK_ALL_ACCESS
Definition: extypes.h:90
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1048
#define TRUE
Definition: types.h:120
POBJECT_TYPE ExCallbackObjectType
Definition: callback.c:38
LONG NTSTATUS
Definition: precomp.h:26
static HANDLE DirectoryHandle
Definition: ObType.c:48
#define OBJ_OPENLINK
Definition: winternl.h:230
NTSTATUS NTAPI ExCreateCallback(OUT PCALLBACK_OBJECT *CallbackObject, IN POBJECT_ATTRIBUTES ObjectAttributes, IN BOOLEAN Create, IN BOOLEAN AllowMultipleCallbacks)
Definition: callback.c:361
#define OBJ_PERMANENT
Definition: winternl.h:226
KEVENT ExpCallbackEvent
Definition: callback.c:39
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
EX_PUSH_LOCK ExpCallBackFlush
Definition: callback.c:40
PSECURITY_DESCRIPTOR SePublicDefaultSd
Definition: sd.c:22
struct NameRec_ * Name
Definition: cdprocs.h:464
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
VOID NTAPI ExpDeleteCallback(IN PVOID Object)
Definition: callback.c:236
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:773
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
SYSTEM_CALLBACKS ExpInitializeCallback[]
Definition: callback.c:30
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
PCALLBACK_OBJECT * CallbackObject
Definition: ex.h:117
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PFCB _In_ PCD_NAME DirName
Definition: cdprocs.h:741
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369
GENERIC_MAPPING ExpCallbackMapping
Definition: callback.c:18
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by ExpInitSystemPhase1().

◆ ExReferenceCallBackBlock()

PEX_CALLBACK_ROUTINE_BLOCK NTAPI ExReferenceCallBackBlock ( IN OUT PEX_CALLBACK  CallBack)

Definition at line 122 of file callback.c.

123 {
124  EX_FAST_REF OldValue;
126  PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock;
127 
128  /* Acquire a reference */
129  OldValue = ExAcquireFastReference(&CallBack->RoutineBlock);
130  Count = ExGetCountFastReference(OldValue);
131 
132  /* Fail if there isn't any object */
133  if (!ExGetObjectFastReference(OldValue)) return NULL;
134 
135  /* Check if we don't have a reference */
136  if (!Count)
137  {
138  /* FIXME: Race */
139  DPRINT1("Unhandled callback race condition\n");
140  ASSERT(FALSE);
141  return NULL;
142  }
143 
144  /* Get the callback block */
145  CallbackBlock = ExGetObjectFastReference(OldValue);
146 
147  /* Check if this is the last reference */
148  if (Count == 1)
149  {
150  /* Acquire rundown protection */
151  if (ExfAcquireRundownProtectionEx(&CallbackBlock->RundownProtect,
152  MAX_FAST_REFS))
153  {
154  /* Insert references */
155  if (!ExInsertFastReference(&CallBack->RoutineBlock, CallbackBlock))
156  {
157  /* Backdown the rundown acquire */
159  MAX_FAST_REFS);
160  }
161  }
162  }
163 
164  /* Return the callback block */
165  return CallbackBlock;
166 }
FORCEINLINE PVOID ExGetObjectFastReference(IN EX_FAST_REF FastRef)
Definition: ex.h:566
FORCEINLINE BOOLEAN ExInsertFastReference(IN OUT PEX_FAST_REF FastRef, IN PVOID Object)
Definition: ex.h:632
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE EX_FAST_REF ExAcquireFastReference(IN OUT PEX_FAST_REF FastRef)
Definition: ex.h:603
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE ULONG ExGetCountFastReference(IN EX_FAST_REF FastRef)
Definition: ex.h:574
VOID FASTCALL ExfReleaseRundownProtectionEx(IN PEX_RUNDOWN_REF RunRef, IN ULONG Count)
Definition: rundown.c:260
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOLEAN FASTCALL ExfAcquireRundownProtectionEx(IN PEX_RUNDOWN_REF RunRef, IN ULONG Count)
Definition: rundown.c:78
EX_RUNDOWN_REF RundownProtect
Definition: extypes.h:537
#define DPRINT1
Definition: precomp.h:8
#define MAX_FAST_REFS
Definition: ex.h:128

Referenced by ExDoCallBack(), PsRemoveCreateThreadNotifyRoutine(), PsRemoveLoadImageNotifyRoutine(), and PsSetCreateProcessNotifyRoutine().

◆ ExRegisterCallback()

PVOID NTAPI ExRegisterCallback ( IN PCALLBACK_OBJECT  CallbackObject,
IN PCALLBACK_FUNCTION  CallbackFunction,
IN PVOID  CallbackContext 
)

Definition at line 556 of file callback.c.

559 {
560  PCALLBACK_REGISTRATION CallbackRegistration = NULL;
561  KIRQL OldIrql;
562 
563  /* Sanity checks */
566 
567  /* Create reference to Callback Object */
568  ObReferenceObject(CallbackObject);
569 
570  /* Allocate memory for the structure */
571  CallbackRegistration = ExAllocatePoolWithTag(NonPagedPool,
572  sizeof(CALLBACK_REGISTRATION),
574  if (!CallbackRegistration)
575  {
576  /* Dereference and fail */
577  ObDereferenceObject (CallbackObject);
578  return NULL;
579  }
580 
581  /* Create Callback Registration */
582  CallbackRegistration->CallbackObject = CallbackObject;
583  CallbackRegistration->CallbackFunction = CallbackFunction;
584  CallbackRegistration->CallbackContext = CallbackContext;
585  CallbackRegistration->Busy = 0;
586  CallbackRegistration->UnregisterWaiting = FALSE;
587 
588  /* Acquire SpinLock */
589  KeAcquireSpinLock(&CallbackObject->Lock, &OldIrql);
590 
591  /* Check if 1) No Callbacks registered or 2) Multiple Callbacks allowed */
592  if ((CallbackObject->AllowMultipleCallbacks) ||
593  (IsListEmpty(&CallbackObject->RegisteredCallbacks)))
594  {
595  /* Register the callback */
596  InsertTailList(&CallbackObject->RegisteredCallbacks,
597  &CallbackRegistration->Link);
598 
599  /* Release SpinLock */
600  KeReleaseSpinLock(&CallbackObject->Lock, OldIrql);
601  }
602  else
603  {
604  /* Release SpinLock */
605  KeReleaseSpinLock(&CallbackObject->Lock, OldIrql);
606 
607  /* Free the registration */
608  ExFreePoolWithTag(CallbackRegistration, TAG_CALLBACK_REGISTRATION);
609  CallbackRegistration = NULL;
610 
611  /* Dereference the object */
612  ObDereferenceObject(CallbackObject);
613  }
614 
615  /* Return handle to Registration Object */
616  return (PVOID)CallbackRegistration;
617 }
BOOLEAN UnregisterWaiting
Definition: extypes.h:529
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
PCALLBACK_FUNCTION CallbackFunction
Definition: extypes.h:526
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG _In_opt_ PEVENT_FILTER_DESCRIPTOR _Inout_opt_ PVOID CallbackContext
Definition: wmitypes.h:55
#define TAG_CALLBACK_REGISTRATION
Definition: tag.h:12
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define InsertTailList(ListHead, Entry)
PCALLBACK_OBJECT CallbackObject
Definition: extypes.h:525
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
_In_ PCALLBACK_FUNCTION CallbackFunction
Definition: exfuncs.h:826
UCHAR KIRQL
Definition: env_spec_w32.h:591
smooth NULL
Definition: ftsmooth.c:416
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define ObReferenceObject
Definition: obfuncs.h:204
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by DriverEntry(), and START_TEST().

◆ ExUnregisterCallback()

VOID NTAPI ExUnregisterCallback ( IN PVOID  CallbackRegistrationHandle)

Definition at line 636 of file callback.c.

637 {
638  PCALLBACK_REGISTRATION CallbackRegistration;
639  PCALLBACK_OBJECT CallbackObject;
640  KIRQL OldIrql;
642 
643  /* Convert Handle to valid Structure Pointer */
644  CallbackRegistration = (PCALLBACK_REGISTRATION)CallbackRegistrationHandle;
645 
646  /* Get the Callback Object */
647  CallbackObject = CallbackRegistration->CallbackObject;
648 
649  /* Lock the Object */
650  KeAcquireSpinLock (&CallbackObject->Lock, &OldIrql);
651 
652  /* We can't Delete the Callback if it's in use */
653  while (CallbackRegistration->Busy)
654  {
655  /* Let everyone else know we're unregistering */
656  CallbackRegistration->UnregisterWaiting = TRUE;
657 
658  /* We are going to wait for the event, so the Lock isn't necessary */
659  KeReleaseSpinLock(&CallbackObject->Lock, OldIrql);
660 
661  /* Make sure the event is cleared */
663 
664  /* Wait for the Event */
666  Executive,
667  KernelMode,
668  FALSE,
669  NULL);
670 
671  /* We need the Lock again */
672  KeAcquireSpinLock(&CallbackObject->Lock, &OldIrql);
673  }
674 
675  /* Remove the Callback */
676  RemoveEntryList(&CallbackRegistration->Link);
677 
678  /* It's now safe to release the lock */
679  KeReleaseSpinLock(&CallbackObject->Lock, OldIrql);
680 
681  /* Delete this registration */
682  ExFreePoolWithTag(CallbackRegistration, TAG_CALLBACK_REGISTRATION);
683 
684  /* Remove the reference */
685  ObDereferenceObject(CallbackObject);
686 }
BOOLEAN UnregisterWaiting
Definition: extypes.h:529
KSPIN_LOCK Lock
Definition: extypes.h:513
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
#define TRUE
Definition: types.h:120
#define TAG_CALLBACK_REGISTRATION
Definition: tag.h:12
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
PCALLBACK_OBJECT CallbackObject
Definition: extypes.h:525
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
KEVENT ExpCallbackEvent
Definition: callback.c:39
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _CALLBACK_REGISTRATION * PCALLBACK_REGISTRATION
smooth NULL
Definition: ftsmooth.c:416
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22

Referenced by CmBattUnload(), and START_TEST().

◆ ExWaitForCallBacks()

VOID NTAPI ExWaitForCallBacks ( IN PEX_CALLBACK_ROUTINE_BLOCK  CallbackBlock)

Definition at line 85 of file callback.c.

86 {
87  /* Wait on the rundown */
88  ExWaitForRundownProtectionRelease(&CallbackBlock->RundownProtect);
89 }
NTKERNELAPI VOID FASTCALL ExWaitForRundownProtectionRelease(_Inout_ PEX_RUNDOWN_REF RunRef)

Referenced by PsRemoveCreateThreadNotifyRoutine(), PsRemoveLoadImageNotifyRoutine(), and PsSetCreateProcessNotifyRoutine().

Variable Documentation

◆ ExCallbackObjectType

POBJECT_TYPE ExCallbackObjectType

Definition at line 38 of file callback.c.

Referenced by ExCreateCallback(), and ExpInitializeCallbacks().

◆ ExpCallbackEvent

KEVENT ExpCallbackEvent

Definition at line 39 of file callback.c.

Referenced by ExNotifyCallback(), ExpInitializeCallbacks(), and ExUnregisterCallback().

◆ ExpCallBackFlush

EX_PUSH_LOCK ExpCallBackFlush

Definition at line 40 of file callback.c.

Referenced by ExCompareExchangeCallBack(), and ExpInitializeCallbacks().

◆ ExpCallbackMapping

GENERIC_MAPPING ExpCallbackMapping
Initial value:
=
{
}
#define CALLBACK_ALL_ACCESS
Definition: extypes.h:90
#define STANDARD_RIGHTS_WRITE
Definition: nt_native.h:66
#define STANDARD_RIGHTS_EXECUTE
Definition: nt_native.h:67
#define STANDARD_RIGHTS_READ
Definition: nt_native.h:65
#define SYNCHRONIZE
Definition: nt_native.h:61
#define CALLBACK_MODIFY_STATE
Definition: extypes.h:89

Definition at line 18 of file callback.c.

Referenced by ExpInitializeCallbacks().

◆ ExpInitializeCallback

SYSTEM_CALLBACKS ExpInitializeCallback[]
Initial value:
=
{
{&SetSystemTimeCallback, L"\\Callback\\SetSystemTime"},
{&SetSystemStateCallback, L"\\Callback\\SetSystemState"},
{&PowerStateCallback, L"\\Callback\\PowerState"},
}
PCALLBACK_OBJECT PowerStateCallback
Definition: callback.c:29
PCALLBACK_OBJECT SetSystemStateCallback
Definition: callback.c:28
PCALLBACK_OBJECT SetSystemTimeCallback
Definition: callback.c:27
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR L[]
Definition: oid.c:1250

Definition at line 30 of file callback.c.

Referenced by ExpInitializeCallbacks().

◆ PowerStateCallback

PCALLBACK_OBJECT PowerStateCallback

Definition at line 29 of file callback.c.

Referenced by NtSetSystemPowerState().

◆ SetSystemStateCallback

PCALLBACK_OBJECT SetSystemStateCallback

Definition at line 28 of file callback.c.

◆ SetSystemTimeCallback

PCALLBACK_OBJECT SetSystemTimeCallback

Definition at line 27 of file callback.c.

Referenced by PoNotifySystemTimeSet().