ReactOS  r76032
callback.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/ex/callback.c
5  * PURPOSE: Executive callbacks
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* TYPES *********************************************************************/
16 
17 /* Mapping for Callback Object */
19 {
24 };
25 
26 /* Kernel Default Callbacks */
31 {
32  {&SetSystemTimeCallback, L"\\Callback\\SetSystemTime"},
33  {&SetSystemStateCallback, L"\\Callback\\SetSystemState"},
34  {&PowerStateCallback, L"\\Callback\\PowerState"},
35  {NULL, NULL}
36 };
37 
41 
42 /* PRIVATE FUNCTIONS *********************************************************/
43 
44 VOID
45 NTAPI
47 {
48  /* Initialize the fast reference */
49  ExInitializeFastReference(&Callback->RoutineBlock, NULL);
50 }
51 
53 NTAPI
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 }
74 
75 VOID
76 NTAPI
78 {
79  /* Just free it from memory */
81 }
82 
83 VOID
84 NTAPI
86 {
87  /* Wait on the rundown */
88  ExWaitForRundownProtectionRelease(&CallbackBlock->RundownProtect);
89 }
90 
92 NTAPI
94 {
95  /* Return the function */
96  return CallbackBlock->Function;
97 }
98 
99 PVOID
100 NTAPI
102 {
103  /* Return the context */
104  return CallbackBlock->Context;
105 }
106 
107 VOID
108 NTAPI
110  IN PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock)
111 {
112  /* Release a fast reference */
113  if (!ExReleaseFastReference(&CallBack->RoutineBlock, CallbackBlock))
114  {
115  /* Take slow path */
116  ExReleaseRundownProtection(&CallbackBlock->RundownProtect);
117  }
118 }
119 
121 NTAPI
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 }
167 
168 BOOLEAN
169 NTAPI
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", 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 */
208  ExWaitOnPushLock(&ExpCallBackFlush);
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 }
233 
234 VOID
235 NTAPI
237 {
238  /* Sanity check */
239  ASSERT(IsListEmpty(&((PCALLBACK_OBJECT)Object)->RegisteredCallbacks));
240 }
241 
242 /*++
243  * @name ExpInitializeCallbacks
244  *
245  * Creates the Callback Object as a valid Object Type in the Kernel.
246  * Internal function, subject to further review
247  *
248  * @return TRUE if the Callback Object Type was successfully created.
249  *
250  * @remarks None
251  *
252  *--*/
253 BOOLEAN
255 NTAPI
257 {
260  UNICODE_STRING DirName = RTL_CONSTANT_STRING(L"\\Callback");
261  UNICODE_STRING CallbackName;
263  OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
265  ULONG i;
266 
267  /* Setup lightweight callback lock */
268  ExpCallBackFlush.Value = 0;
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;
279  Status = ObCreateObjectType(&Name,
280  &ObjectTypeInitializer,
281  NULL,
282  &ExCallbackObjectType);
283  if (!NT_SUCCESS(Status)) return FALSE;
284 
285  /* Initialize the Object */
286  InitializeObjectAttributes(&ObjectAttributes,
287  &DirName,
289  NULL,
291 
292  /* Create the Object Directory */
293  Status = NtCreateDirectoryObject(&DirectoryHandle,
295  &ObjectAttributes);
296  if (!NT_SUCCESS(Status)) return FALSE;
297 
298  /* Close Handle... */
299  NtClose(DirectoryHandle);
300 
301  /* Initialize Event used when unregistering */
302  KeInitializeEvent(&ExpCallbackEvent, NotificationEvent, 0);
303 
304  /* Default NT Kernel Callbacks. */
305  for (i = 0; ExpInitializeCallback[i].CallbackObject; i++)
306  {
307  /* Create the name from the structure */
308  RtlInitUnicodeString(&CallbackName, ExpInitializeCallback[i].Name);
309 
310  /* Initialize the Object Attributes Structure */
311  InitializeObjectAttributes(&ObjectAttributes,
312  &CallbackName,
314  NULL,
315  NULL);
316 
317  /* Create the Callback Object */
318  Status = ExCreateCallback(ExpInitializeCallback[i].CallbackObject,
319  &ObjectAttributes,
320  TRUE,
321  TRUE);
322  if (!NT_SUCCESS(Status)) return FALSE;
323  }
324 
325  /* Everything successful */
326  return TRUE;
327 }
328 
329 /* PUBLIC FUNCTIONS **********************************************************/
330 
331 /*++
332  * @name ExCreateCallback
333  * @implemented
334  *
335  * Opens or creates a Callback Object. Creates only if Create is true.
336  * Allows multiple Callback Functions to be registered only if
337  * AllowMultipleCallbacks is true.
338  * See: http://www.osronline.com/ddkx/kmarch/k102_967m.htm
339  * http://www.osronline.com/article.cfm?id=24
340  *
341  * @param CallbackObject
342  * Pointer that will receive the Callback Object.
343  *
344  * @param CallbackName
345  * Name of Callback
346  *
347  * @param Create
348  * Determines if the object will be created if it doesn't exit
349  *
350  * @param AllowMultipleCallbacks
351  * Determines if more then one registered callback function
352  * can be attached to this Callback Object.
353  *
354  * @return STATUS_SUCESS if not failed.
355  *
356  * @remarks Must be called at IRQL = PASSIVE_LEVEL
357  *
358  *--*/
359 NTSTATUS
360 NTAPI
363  IN BOOLEAN Create,
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 */
375  Status = ObOpenObjectByName(ObjectAttributes,
376  ExCallbackObjectType,
377  KernelMode,
378  NULL,
379  0,
380  NULL,
381  &Handle);
382  }
383  else
384  {
385  /* Otherwise, fail */
386  Status = STATUS_UNSUCCESSFUL;
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 */
393  Status = ObCreateObject(KernelMode,
394  ExCallbackObjectType,
395  ObjectAttributes,
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';
406  KeInitializeSpinLock(&Callback->Lock);
409 
410  /* Insert the object into the object namespace */
411  Status = ObInsertObject(Callback,
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 */
424  Status = ObReferenceObjectByHandle(Handle,
425  0,
426  ExCallbackObjectType,
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 }
442 
443 /*++
444  * @name ExNotifyCallback
445  * @implemented
446  *
447  * Calls a function pointer (a registered callback)
448  * See: http://www.osronline.com/ddkx/kmarch/k102_2f5e.htm
449  * http://vmsone.com/~decuslib/vmssig/vmslt99b/nt/wdm-callback.txt
450  *
451  * @param CallbackObject
452  * Which callback to call
453  *
454  * @param Argument1
455  * Pointer/data to send to callback function
456  *
457  * @param Argument2
458  * Pointer/data to send to callback function
459  *
460  * @return None
461  *
462  * @remarks None
463  *
464  *--*/
465 VOID
466 NTAPI
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 */
522  KeSetEvent(&ExpCallbackEvent, 0, FALSE);
523  }
524  }
525  }
526 
527  /* Release the Callback Object */
528  KeReleaseSpinLock(&CallbackObject->Lock, OldIrql);
529 }
530 
531 /*++
532  * @name ExRegisterCallback
533  * @implemented
534  *
535  * Allows a function to associate a callback pointer (Function) to
536  * a created Callback object
537  * See: DDK, OSR, links in ExNotifyCallback
538  *
539  * @param CallbackObject
540  * The Object Created with ExCreateCallBack
541  *
542  * @param CallBackFunction
543  * Pointer to the function to be called back
544  *
545  * @param CallBackContext
546  * Block of memory that can contain user-data which will be
547  * passed on to the callback
548  *
549  * @return A handle to a Callback Registration Structure (MSDN Documentation)
550  *
551  * @remarks None
552  *
553  *--*/
554 PVOID
555 NTAPI
559 {
560  PCALLBACK_REGISTRATION CallbackRegistration = NULL;
561  KIRQL OldIrql;
562 
563  /* Sanity checks */
564  ASSERT(CallbackFunction);
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 }
618 
619 /*++
620  * @name ExUnregisterCallback
621  * @implemented
622  *
623  * Deregisters a CallBack
624  * See: DDK, OSR, links in ExNotifyCallback
625  *
626  * @param CallbackRegistration
627  * Callback Registration Handle
628  *
629  * @return None
630  *
631  * @remarks None
632  *
633  *--*/
634 VOID
635 NTAPI
636 ExUnregisterCallback(IN PVOID CallbackRegistrationHandle)
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 */
662  KeClearEvent(&ExpCallbackEvent);
663 
664  /* Wait for the Event */
665  KeWaitForSingleObject(&ExpCallbackEvent,
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 }
687 
688 /* EOF */
ULONG_PTR Value
Definition: extypes.h:465
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:2522
DWORD *typedef PVOID
Definition: winlogon.h:52
BOOLEAN UnregisterWaiting
Definition: extypes.h:529
KSPIN_LOCK Lock
Definition: extypes.h:513
PEX_CALLBACK_ROUTINE_BLOCK NTAPI ExAllocateCallBack(IN PEX_CALLBACK_FUNCTION Function, IN PVOID Context)
Definition: callback.c:54
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define CALLBACK_ALL_ACCESS
Definition: extypes.h:90
PCALLBACK_OBJECT PowerStateCallback
Definition: callback.c:29
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:250
FORCEINLINE PVOID ExGetObjectFastReference(IN EX_FAST_REF FastRef)
Definition: ex.h:520
#define IN
Definition: typedefs.h:38
PCALLBACK_FUNCTION CallbackFunction
Definition: extypes.h:526
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1034
LIST_ENTRY RegisteredCallbacks
Definition: extypes.h:514
PCALLBACK_OBJECT SetSystemStateCallback
Definition: callback.c:28
FORCEINLINE VOID ExInitializeFastReference(OUT PEX_FAST_REF FastRef, IN OPTIONAL PVOID Object)
Definition: ex.h:536
PCALLBACK_OBJECT SetSystemTimeCallback
Definition: callback.c:27
#define TRUE
Definition: types.h:120
FORCEINLINE BOOLEAN ExInsertFastReference(IN OUT PEX_FAST_REF FastRef, IN PVOID Object)
Definition: ex.h:586
_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
#define STANDARD_RIGHTS_WRITE
Definition: nt_native.h:66
Definition: bidi.c:75
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
NTKERNELAPI VOID FASTCALL ExReleaseRundownProtection(_Inout_ PEX_RUNDOWN_REF RunRef)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
IN OUT PIRP IN ULONG IN WMIENABLEDISABLECONTROL Function
Definition: wmilib.h:37
POBJECT_TYPE ExCallbackObjectType
Definition: callback.c:38
VOID NTAPI ExInitializeCallBack(IN OUT PEX_CALLBACK Callback)
Definition: callback.c:46
FORCEINLINE VOID ExWaitOnPushLock(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1108
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
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define OBJ_PERMANENT
Definition: winternl.h:226
#define TAG_CALLBACK_REGISTRATION
Definition: tag.h:12
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:267
#define InsertTailList(ListHead, Entry)
#define STANDARD_RIGHTS_EXECUTE
Definition: nt_native.h:67
NTKERNELAPI VOID FASTCALL ExInitializeRundownProtection(_Out_ PEX_RUNDOWN_REF RunRef)
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
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
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
_In_ PCALLBACK_FUNCTION CallbackFunction
Definition: exfuncs.h:826
PEX_CALLBACK_FUNCTION Function
Definition: extypes.h:538
_In_ BOOLEAN Create
Definition: pstypes.h:512
VOID NTAPI ExUnregisterCallback(IN PVOID CallbackRegistrationHandle)
Definition: callback.c:636
uint32_t ULONG_PTR
Definition: typedefs.h:63
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
FORCEINLINE EX_FAST_REF ExAcquireFastReference(IN OUT PEX_FAST_REF FastRef)
Definition: ex.h:557
GLenum GLclampf GLint i
Definition: glfuncs.h:14
EX_PUSH_LOCK ExpCallBackFlush
Definition: callback.c:40
PEX_CALLBACK_ROUTINE_BLOCK NTAPI ExReferenceCallBackBlock(IN OUT PEX_CALLBACK CallBack)
Definition: callback.c:122
PSECURITY_DESCRIPTOR SePublicDefaultSd
Definition: sd.c:22
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:388
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
PVOID NTAPI ExGetCallBackBlockContext(IN PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock)
Definition: callback.c:101
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define FILE_READ_DATA
Definition: nt_native.h:628
struct _CALLBACK_REGISTRATION * PCALLBACK_REGISTRATION
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:557
BOOLEAN NTAPI ExCompareExchangeCallBack(IN OUT PEX_CALLBACK CallBack, IN PEX_CALLBACK_ROUTINE_BLOCK NewBlock, IN PEX_CALLBACK_ROUTINE_BLOCK OldBlock)
Definition: callback.c:170
NTKERNELAPI VOID FASTCALL ExWaitForRundownProtectionRelease(_Inout_ PEX_RUNDOWN_REF RunRef)
ULONG Signature
Definition: extypes.h:512
_In_ PVOID Argument2
Definition: classpnp.h:680
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:938
BOOLEAN INIT_FUNCTION NTAPI ExpInitializeCallbacks(VOID)
Definition: callback.c:256
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_In_ HANDLE Handle
Definition: extypes.h:390
VOID NTAPI ExNotifyCallback(IN PCALLBACK_OBJECT CallbackObject, IN PVOID Argument1, IN PVOID Argument2)
Definition: callback.c:467
unsigned char BOOLEAN
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
FORCEINLINE ULONG ExGetCountFastReference(IN EX_FAST_REF FastRef)
Definition: ex.h:528
#define PAGED_CODE()
Definition: video.h:57
VOID FASTCALL ExfReleaseRundownProtectionEx(IN PEX_RUNDOWN_REF RunRef, IN ULONG Count)
Definition: rundown.c:259
static IUnknown Object
Definition: main.c:512
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3392
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_In_ PUNICODE_STRING Name
Definition: mrx.h:218
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
FORCEINLINE BOOLEAN ExReleaseFastReference(IN PEX_FAST_REF FastRef, IN PVOID Object)
Definition: ex.h:625
BOOLEAN AllowMultipleCallbacks
Definition: extypes.h:515
PEX_CALLBACK_FUNCTION NTAPI ExGetCallBackBlockRoutine(IN PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock)
Definition: callback.c:93
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: typedefs.h:117
#define STANDARD_RIGHTS_READ
Definition: nt_native.h:65
#define SYNCHRONIZE
Definition: nt_native.h:61
FORCEINLINE EX_FAST_REF ExCompareSwapFastReference(IN PEX_FAST_REF FastRef, IN PVOID Object, IN PVOID OldObject)
Definition: ex.h:687
Status
Definition: gdiplustypes.h:24
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
VOID NTAPI ExDereferenceCallBackBlock(IN OUT PEX_CALLBACK CallBack, IN PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock)
Definition: callback.c:109
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:731
DWORD *typedef HANDLE
Definition: winlogon.h:52
BOOLEAN FASTCALL ExfAcquireRundownProtectionEx(IN PEX_RUNDOWN_REF RunRef, IN ULONG Count)
Definition: rundown.c:77
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:2925
LONG NTSTATUS
Definition: DriverTester.h:11
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#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 CALLBACK_MODIFY_STATE
Definition: extypes.h:89
CALLBACK_FUNCTION * PCALLBACK_FUNCTION
Definition: extypes.h:96
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
VOID NTAPI ExWaitForCallBacks(IN PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock)
Definition: callback.c:85
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
VOID NTAPI ExFreeCallBack(IN PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock)
Definition: callback.c:77
EX_RUNDOWN_REF RundownProtect
Definition: extypes.h:537
#define DPRINT1
Definition: precomp.h:8
EX_CALLBACK_FUNCTION * PEX_CALLBACK_FUNCTION
Definition: cmtypes.h:696
PVOID NTAPI ExRegisterCallback(IN PCALLBACK_OBJECT CallbackObject, IN PCALLBACK_FUNCTION CallbackFunction, IN PVOID CallbackContext)
Definition: callback.c:556
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
PCALLBACK_OBJECT * CallbackObject
Definition: ex.h:107
struct tagContext Context
Definition: acpixf.h:1014
unsigned int ULONG
Definition: retypes.h:1
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:259
#define TAG_CALLBACK_ROUTINE_BLOCK
Definition: tag.h:11
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define MAX_FAST_REFS
Definition: ex.h:118
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1097
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369
GENERIC_MAPPING ExpCallbackMapping
Definition: callback.c:18
LPFNPSPCALLBACK Callback
Definition: desk.c:111
#define INIT_FUNCTION
Definition: ntoskrnl.h:11
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14