ReactOS 0.4.15-dev-7931-gfd331f1
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 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}
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
#define ExInitializeRundownProtection
Definition: ex.h:137
PEX_CALLBACK_FUNCTION Function
Definition: extypes.h:538
EX_RUNDOWN_REF RundownProtect
Definition: extypes.h:537
#define TAG_CALLBACK_ROUTINE_BLOCK
Definition: tag.h:21

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}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define MAX_FAST_REFS
Definition: ex.h:133
FORCEINLINE ULONG ExGetCountFastReference(IN EX_FAST_REF FastRef)
Definition: ex.h:588
FORCEINLINE EX_FAST_REF ExCompareSwapFastReference(IN PEX_FAST_REF FastRef, IN PVOID Object, IN PVOID OldObject)
Definition: ex.h:747
FORCEINLINE PVOID ExGetObjectFastReference(IN EX_FAST_REF FastRef)
Definition: ex.h:580
FORCEINLINE VOID ExWaitOnPushLock(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1178
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
int Count
Definition: noreturn.cpp:7
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
EX_PUSH_LOCK ExpCallBackFlush
Definition: callback.c:40
BOOLEAN FASTCALL ExfAcquireRundownProtectionEx(IN PEX_RUNDOWN_REF RunRef, IN ULONG Count)
Definition: rundown.c:78
VOID FASTCALL ExfReleaseRundownProtectionEx(IN PEX_RUNDOWN_REF RunRef, IN ULONG Count)
Definition: rundown.c:260
uint32_t ULONG
Definition: typedefs.h:59

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{
369 PAGED_CODE();
370
371 /* Open a handle to the callback if it exists */
372 if (ObjectAttributes->ObjectName)
373 {
374 /* Open the handle */
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 */
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,
428 (PVOID *)&Callback,
429 NULL);
430
431 /* Close the Handle, since we now have the pointer */
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}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
@ Create
Definition: registry.c:563
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define FILE_READ_DATA
Definition: nt_native.h:628
POBJECT_TYPE ExCallbackObjectType
Definition: callback.c:38
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:2935
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:2532
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:1039
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:494
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
_In_ POBJECT_ATTRIBUTES _In_ BOOLEAN _In_ BOOLEAN AllowMultipleCallbacks
Definition: exfuncs.h:750

Referenced by Mx::CreateCallback(), 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}
FORCEINLINE BOOLEAN ExReleaseFastReference(IN PEX_FAST_REF FastRef, IN PVOID Object)
Definition: ex.h:685
#define ExReleaseRundownProtection
Definition: ex.h:136

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

◆ ExFreeCallBack()

VOID NTAPI ExFreeCallBack ( IN PEX_CALLBACK_ROUTINE_BLOCK  CallbackBlock)

◆ 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 */
50}
FORCEINLINE VOID ExInitializeFastReference(OUT PEX_FAST_REF FastRef, IN OPTIONAL PVOID Object)
Definition: ex.h:596

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;
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}
_In_ PVOID Argument2
Definition: classpnp.h:721
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
KEVENT ExpCallbackEvent
Definition: callback.c:39
PCALLBACK_FUNCTION CallbackFunction
Definition: extypes.h:526
BOOLEAN UnregisterWaiting
Definition: extypes.h:529
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
static int Link(const char **args)
Definition: vfdcmd.c:2414
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG _In_opt_ PEVENT_FILTER_DESCRIPTOR _Inout_opt_ PVOID CallbackContext
Definition: wmitypes.h:60
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:696
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

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}
#define ASSERT(a)
Definition: mode.c:44
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object

Referenced by ExpInitializeCallbacks().

◆ ExpInitializeCallbacks()

BOOLEAN 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. */
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}
static HANDLE DirectoryHandle
Definition: ObType.c:48
struct NameRec_ * Name
Definition: cdprocs.h:460
_In_ PFCB _In_ PCD_NAME DirName
Definition: cdprocs.h:737
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define NonPagedPool
Definition: env_spec_w32.h:307
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
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_OPENLINK
Definition: winternl.h:230
#define OBJ_PERMANENT
Definition: winternl.h:226
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define CALLBACK_ALL_ACCESS
Definition: extypes.h:90
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
@ NotificationEvent
VOID NTAPI ExpDeleteCallback(IN PVOID Object)
Definition: callback.c:236
GENERIC_MAPPING ExpCallbackMapping
Definition: callback.c:18
NTSTATUS NTAPI ExCreateCallback(OUT PCALLBACK_OBJECT *CallbackObject, IN POBJECT_ATTRIBUTES ObjectAttributes, IN BOOLEAN Create, IN BOOLEAN AllowMultipleCallbacks)
Definition: callback.c:361
SYSTEM_CALLBACKS ExpInitializeCallback[]
Definition: callback.c:30
PSECURITY_DESCRIPTOR SePublicDefaultSd
Definition: sd.c:16
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:765
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1136
PCALLBACK_OBJECT * CallbackObject
Definition: ex.h:122
ULONG_PTR Value
Definition: extypes.h:465
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

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 */
153 {
154 /* Insert references */
155 if (!ExInsertFastReference(&CallBack->RoutineBlock, CallbackBlock))
156 {
157 /* Backdown the rundown acquire */
160 }
161 }
162 }
163
164 /* Return the callback block */
165 return CallbackBlock;
166}
#define DPRINT1
Definition: precomp.h:8
FORCEINLINE BOOLEAN ExInsertFastReference(IN OUT PEX_FAST_REF FastRef, IN PVOID Object)
Definition: ex.h:646
FORCEINLINE EX_FAST_REF ExAcquireFastReference(IN OUT PEX_FAST_REF FastRef)
Definition: ex.h:617
uint32_t ULONG_PTR
Definition: typedefs.h:65

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;
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}
#define InsertTailList(ListHead, Entry)
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
PCALLBACK_OBJECT CallbackObject
Definition: extypes.h:525
#define TAG_CALLBACK_REGISTRATION
Definition: tag.h:22
_In_ PCALLBACK_FUNCTION CallbackFunction
Definition: exfuncs.h:1034
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by DriverEntry(), Mx::RegisterCallback(), 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;
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,
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}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
struct _CALLBACK_REGISTRATION * PCALLBACK_REGISTRATION
KSPIN_LOCK Lock
Definition: extypes.h:513
@ Executive
Definition: ketypes.h:415

Referenced by CmBattUnload(), START_TEST(), and Mx::UnregisterCallback().

◆ 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}
#define ExWaitForRundownProtectionRelease
Definition: ex.h:138

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_MODIFY_STATE
Definition: extypes.h:89
#define SYNCHRONIZE
Definition: nt_native.h:61
#define STANDARD_RIGHTS_READ
Definition: nt_native.h:65
#define STANDARD_RIGHTS_WRITE
Definition: nt_native.h:66
#define STANDARD_RIGHTS_EXECUTE
Definition: nt_native.h:67

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 SetSystemStateCallback
Definition: callback.c:28
PCALLBACK_OBJECT PowerStateCallback
Definition: callback.c:29
PCALLBACK_OBJECT SetSystemTimeCallback
Definition: callback.c:27

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().