ReactOS  0.4.14-dev-52-g6116262
cmhook.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/config/cmhook.c
5  * PURPOSE: Configuration Manager - Registry Notifications/Callbacks
6  * PROGRAMMERS: Thomas Weidenmueller (w3seek@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include "ntoskrnl.h"
12 #define NDEBUG
13 #include "debug.h"
14 
15 /* GLOBALS *******************************************************************/
16 
19 
22 
23 typedef struct _REGISTRY_CALLBACK
24 {
32 
33 /* PRIVATE FUNCTIONS *********************************************************/
34 
35 INIT_FUNCTION
36 VOID
37 NTAPI
39 {
40  ULONG i;
41  PAGED_CODE();
42 
43  /* Reset counter */
44  CmpCallBackCount = 0;
45 
46  /* Loop all the callbacks */
47  for (i = 0; i < CMP_MAX_CALLBACKS; i++)
48  {
49  /* Initialize this one */
51  }
52 
53  /* ROS: Initialize old-style callbacks for now */
56 }
57 
61 {
62  PLIST_ENTRY CurrentEntry;
64  PREGISTRY_CALLBACK CurrentCallback;
65  PAGED_CODE();
66 
68 
69  for (CurrentEntry = CmiCallbackHead.Flink;
70  CurrentEntry != &CmiCallbackHead;
71  CurrentEntry = CurrentEntry->Flink)
72  {
73  CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
74  if (!CurrentCallback->PendingDelete &&
75  ExAcquireRundownProtection(&CurrentCallback->RundownRef))
76  {
77  /* don't hold locks during the callbacks! */
79 
80  Status = CurrentCallback->Function(CurrentCallback->Context,
82  Argument2);
83 
85 
86  /* don't release the rundown protection before holding the callback lock
87  so the pointer to the next callback isn't cleared in case this callback
88  get's deleted */
89  ExReleaseRundownProtection(&CurrentCallback->RundownRef);
90  if(!NT_SUCCESS(Status))
91  {
92  /* one callback returned failure, don't call any more callbacks */
93  break;
94  }
95  }
96  }
97 
99 
100  return Status;
101 }
102 
103 /* PUBLIC FUNCTIONS **********************************************************/
104 
105 /*
106  * @implemented
107  */
108 NTSTATUS
109 NTAPI
111  IN PVOID Context,
113 {
115  PAGED_CODE();
116  ASSERT(Function && Cookie);
117 
119  sizeof(REGISTRY_CALLBACK),
120  'bcMC');
121  if (Callback == NULL)
122  {
124  }
125 
126  /* initialize the callback */
128  Callback->Function = Function;
129  Callback->Context = Context;
130  Callback->PendingDelete = FALSE;
131 
132  /* add it to the callback list and receive a cookie for the callback */
134 
135  /* FIXME - to receive a unique cookie we'll just return the pointer to the
136  callback object */
137  Callback->Cookie.QuadPart = (ULONG_PTR)Callback;
138  InsertTailList(&CmiCallbackHead, &Callback->ListEntry);
139 
141 
142  *Cookie = Callback->Cookie;
143  return STATUS_SUCCESS;
144 }
145 
146 /*
147  * @implemented
148  */
149 NTSTATUS
150 NTAPI
152 {
153  PLIST_ENTRY CurrentEntry;
154  PREGISTRY_CALLBACK CurrentCallback;
155  PAGED_CODE();
156 
158 
159  for (CurrentEntry = CmiCallbackHead.Flink;
160  CurrentEntry != &CmiCallbackHead;
161  CurrentEntry = CurrentEntry->Flink)
162  {
163  CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
164  if (CurrentCallback->Cookie.QuadPart == Cookie.QuadPart)
165  {
166  if (!CurrentCallback->PendingDelete)
167  {
168  /* found the callback, don't unlink it from the list yet so we don't screw
169  the calling loop */
170  CurrentCallback->PendingDelete = TRUE;
172 
173  /* if the callback is currently executing, wait until it finished */
175 
176  /* time to unlink it. It's now safe because every attempt to acquire a
177  runtime protection on this callback will fail */
179  RemoveEntryList(&CurrentCallback->ListEntry);
181 
182  /* free the callback */
183  ExFreePoolWithTag(CurrentCallback, 'bcMC');
184  return STATUS_SUCCESS;
185  }
186  else
187  {
188  /* pending delete, pretend like it already is deleted */
190  return STATUS_UNSUCCESSFUL;
191  }
192  }
193  }
194 
196 
197  return STATUS_UNSUCCESSFUL;
198 }
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:694
NTKERNELAPI VOID FASTCALL ExReleaseRundownProtection(_Inout_ PEX_RUNDOWN_REF RunRef)
VOID NTAPI ExInitializeCallBack(IN OUT PEX_CALLBACK Callback)
Definition: callback.c:46
LONG NTSTATUS
Definition: precomp.h:26
#define ExAcquireRundownProtection
Definition: ex.h:130
#define CMP_MAX_CALLBACKS
Definition: cm.h:79
NTSTATUS NTAPI CmUnRegisterCallback(IN LARGE_INTEGER Cookie)
Definition: cmhook.c:151
#define InsertTailList(ListHead, Entry)
BOOLEAN PendingDelete
Definition: cmhook.c:30
NTKERNELAPI VOID FASTCALL ExInitializeRundownProtection(_Out_ PEX_RUNDOWN_REF RunRef)
LARGE_INTEGER Cookie
Definition: cmhook.c:29
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define PAGED_CODE()
Definition: video.h:57
EX_RUNDOWN_REF RundownRef
Definition: cmhook.c:26
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
static LPOVERLAPPED_COMPLETION_ROUTINE Function
Definition: sync.c:684
struct _REGISTRY_CALLBACK REGISTRY_CALLBACK
NTSTATUS NTAPI CmRegisterCallback(IN PEX_CALLBACK_FUNCTION Function, IN PVOID Context, IN OUT PLARGE_INTEGER Cookie)
Definition: cmhook.c:110
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
LIST_ENTRY CmiCallbackHead
Definition: cmhook.c:20
NTKERNELAPI VOID FASTCALL ExWaitForRundownProtectionRelease(_Inout_ PEX_RUNDOWN_REF RunRef)
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
EX_CALLBACK CmpCallBackVector[100]
Definition: cmhook.c:18
_In_ PVOID Argument2
Definition: classpnp.h:680
FAST_MUTEX
Definition: extypes.h:17
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
LIST_ENTRY ListEntry
Definition: cmhook.c:25
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FAST_MUTEX CmiCallbackLock
Definition: cmhook.c:21
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:13
struct _REGISTRY_CALLBACK * PREGISTRY_CALLBACK
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
enum _REG_NOTIFY_CLASS REG_NOTIFY_CLASS
Definition: typedefs.h:117
ULONG CmpCallBackCount
Definition: cmhook.c:17
Status
Definition: gdiplustypes.h:24
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
INIT_FUNCTION VOID NTAPI CmpInitCallback(VOID)
Definition: cmhook.c:38
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
EX_CALLBACK_FUNCTION * PEX_CALLBACK_FUNCTION
Definition: cmtypes.h:696
#define OUT
Definition: typedefs.h:39
struct tagContext Context
Definition: acpixf.h:1024
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
NTSTATUS CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, IN PVOID Argument2)
Definition: cmhook.c:59
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2966
LPFNPSPCALLBACK Callback
Definition: desk.c:111
LONGLONG QuadPart
Definition: typedefs.h:112
PEX_CALLBACK_FUNCTION Function
Definition: cmhook.c:27