ReactOS  0.4.15-dev-439-g292f67a
vectoreh.c File Reference
#include <rtl.h>
#include <debug.h>
Include dependency graph for vectoreh.c:

Go to the source code of this file.

Classes

struct  _RTL_VECTORED_HANDLER_ENTRY
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _RTL_VECTORED_HANDLER_ENTRY RTL_VECTORED_HANDLER_ENTRY
 
typedef struct _RTL_VECTORED_HANDLER_ENTRYPRTL_VECTORED_HANDLER_ENTRY
 

Functions

VOID NTAPI RtlpInitializeVectoredExceptionHandling (VOID)
 
BOOLEAN NTAPI RtlpCallVectoredHandlers (IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN PLIST_ENTRY VectoredHandlerList)
 
PVOID NTAPI RtlpAddVectoredHandler (IN ULONG FirstHandler, IN PVECTORED_EXCEPTION_HANDLER VectoredHandler, IN PLIST_ENTRY VectoredHandlerList)
 
ULONG NTAPI RtlpRemoveVectoredHandler (IN PVOID VectoredHandlerHandle, IN PLIST_ENTRY VectoredHandlerList)
 
BOOLEAN NTAPI RtlCallVectoredExceptionHandlers (IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context)
 
VOID NTAPI RtlCallVectoredContinueHandlers (IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context)
 
DECLSPEC_HOTPATCH PVOID NTAPI RtlAddVectoredExceptionHandler (IN ULONG FirstHandler, IN PVECTORED_EXCEPTION_HANDLER VectoredHandler)
 
DECLSPEC_HOTPATCH PVOID NTAPI RtlAddVectoredContinueHandler (IN ULONG FirstHandler, IN PVECTORED_EXCEPTION_HANDLER VectoredHandler)
 
ULONG NTAPI RtlRemoveVectoredExceptionHandler (IN PVOID VectoredHandlerHandle)
 
ULONG NTAPI RtlRemoveVectoredContinueHandler (IN PVOID VectoredHandlerHandle)
 

Variables

RTL_CRITICAL_SECTION RtlpVectoredHandlerLock
 
LIST_ENTRY RtlpVectoredExceptionList
 
LIST_ENTRY RtlpVectoredContinueList
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file vectoreh.c.

Typedef Documentation

◆ PRTL_VECTORED_HANDLER_ENTRY

◆ RTL_VECTORED_HANDLER_ENTRY

Function Documentation

◆ RtlAddVectoredContinueHandler()

DECLSPEC_HOTPATCH PVOID NTAPI RtlAddVectoredContinueHandler ( IN ULONG  FirstHandler,
IN PVECTORED_EXCEPTION_HANDLER  VectoredHandler 
)

Definition at line 311 of file vectoreh.c.

313 {
314  /* Call the shared routine */
315  return RtlpAddVectoredHandler(FirstHandler,
316  VectoredHandler,
318 }
LIST_ENTRY RtlpVectoredContinueList
Definition: vectoreh.c:17
PVOID NTAPI RtlpAddVectoredHandler(IN ULONG FirstHandler, IN PVECTORED_EXCEPTION_HANDLER VectoredHandler, IN PLIST_ENTRY VectoredHandlerList)
Definition: vectoreh.c:154

◆ RtlAddVectoredExceptionHandler()

DECLSPEC_HOTPATCH PVOID NTAPI RtlAddVectoredExceptionHandler ( IN ULONG  FirstHandler,
IN PVECTORED_EXCEPTION_HANDLER  VectoredHandler 
)

Definition at line 299 of file vectoreh.c.

301 {
302  /* Call the shared routine */
303  return RtlpAddVectoredHandler(FirstHandler,
304  VectoredHandler,
306 }
PVOID NTAPI RtlpAddVectoredHandler(IN ULONG FirstHandler, IN PVECTORED_EXCEPTION_HANDLER VectoredHandler, IN PLIST_ENTRY VectoredHandlerList)
Definition: vectoreh.c:154
LIST_ENTRY RtlpVectoredExceptionList
Definition: vectoreh.c:17

◆ RtlCallVectoredContinueHandlers()

VOID NTAPI RtlCallVectoredContinueHandlers ( IN PEXCEPTION_RECORD  ExceptionRecord,
IN PCONTEXT  Context 
)

Definition at line 284 of file vectoreh.c.

286 {
287  /*
288  * Call the shared routine (ignoring result,
289  * execution always continues at this point)
290  */
291  (VOID)RtlpCallVectoredHandlers(ExceptionRecord,
292  Context,
294 }
BOOLEAN NTAPI RtlpCallVectoredHandlers(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN PLIST_ENTRY VectoredHandlerList)
Definition: vectoreh.c:40
LIST_ENTRY RtlpVectoredContinueList
Definition: vectoreh.c:17
#define VOID
Definition: acefi.h:82

◆ RtlCallVectoredExceptionHandlers()

BOOLEAN NTAPI RtlCallVectoredExceptionHandlers ( IN PEXCEPTION_RECORD  ExceptionRecord,
IN PCONTEXT  Context 
)

Definition at line 273 of file vectoreh.c.

275 {
276  /* Call the shared routine */
277  return RtlpCallVectoredHandlers(ExceptionRecord,
278  Context,
280 }
BOOLEAN NTAPI RtlpCallVectoredHandlers(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN PLIST_ENTRY VectoredHandlerList)
Definition: vectoreh.c:40
LIST_ENTRY RtlpVectoredExceptionList
Definition: vectoreh.c:17

◆ RtlpAddVectoredHandler()

PVOID NTAPI RtlpAddVectoredHandler ( IN ULONG  FirstHandler,
IN PVECTORED_EXCEPTION_HANDLER  VectoredHandler,
IN PLIST_ENTRY  VectoredHandlerList 
)

Definition at line 154 of file vectoreh.c.

157 {
158  PRTL_VECTORED_HANDLER_ENTRY VectoredHandlerEntry;
159 
160  /* Allocate our structure */
161  VectoredHandlerEntry = RtlAllocateHeap(RtlGetProcessHeap(),
162  0,
164  if (!VectoredHandlerEntry) return NULL;
165 
166  /* Set it up, encoding the pointer for security */
167  VectoredHandlerEntry->VectoredHandler = RtlEncodePointer(VectoredHandler);
168  VectoredHandlerEntry->Refs = 1;
169 
170  /* Lock the list before modifying it */
172 
173  /*
174  * While holding the list lock, insert the handler
175  * at beginning or end of list according to caller.
176  */
177  if (FirstHandler)
178  {
179  InsertHeadList(VectoredHandlerList,
180  &VectoredHandlerEntry->ListEntry);
181  }
182  else
183  {
184  InsertTailList(VectoredHandlerList,
185  &VectoredHandlerEntry->ListEntry);
186  }
187 
188  /* Done with the list, unlock it */
190 
191  /* Return pointer to the structure as the handle */
192  return VectoredHandlerEntry;
193 }
PVECTORED_EXCEPTION_HANDLER VectoredHandler
Definition: vectoreh.c:22
NTSYSAPI PVOID WINAPI RtlEncodePointer(PVOID)
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
LIST_ENTRY ListEntry
Definition: vectoreh.c:21
Definition: vectoreh.c:19
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define InsertTailList(ListHead, Entry)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
RTL_CRITICAL_SECTION RtlpVectoredHandlerLock
Definition: vectoreh.c:16
smooth NULL
Definition: ftsmooth.c:416
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
ULONG Refs
Definition: vectoreh.c:23

Referenced by RtlAddVectoredContinueHandler(), and RtlAddVectoredExceptionHandler().

◆ RtlpCallVectoredHandlers()

BOOLEAN NTAPI RtlpCallVectoredHandlers ( IN PEXCEPTION_RECORD  ExceptionRecord,
IN PCONTEXT  Context,
IN PLIST_ENTRY  VectoredHandlerList 
)

Definition at line 40 of file vectoreh.c.

43 {
44  PLIST_ENTRY CurrentEntry;
45  PRTL_VECTORED_HANDLER_ENTRY VectoredExceptionHandler;
46  PVECTORED_EXCEPTION_HANDLER VectoredHandler;
47  EXCEPTION_POINTERS ExceptionInfo;
48  BOOLEAN HandlerRemoved;
49  LONG HandlerReturn;
50 
51  /*
52  * Initialize these in case there are no entries,
53  * or if no one handled the exception
54  */
55  HandlerRemoved = FALSE;
56  HandlerReturn = EXCEPTION_CONTINUE_SEARCH;
57 
58  /* Set up the data to pass to the handler */
59  ExceptionInfo.ExceptionRecord = ExceptionRecord;
60  ExceptionInfo.ContextRecord = Context;
61 
62  /* Grab the lock */
64 
65  /* Loop entries */
66  CurrentEntry = VectoredHandlerList->Flink;
67  while (CurrentEntry != VectoredHandlerList)
68  {
69  /* Get the struct */
70  VectoredExceptionHandler = CONTAINING_RECORD(CurrentEntry,
72  ListEntry);
73 
74  /* Reference it so it doesn't go away while we are using it */
75  VectoredExceptionHandler->Refs++;
76 
77  /* Drop the lock before calling the handler */
79 
80  /*
81  * Get the function pointer, decoding it so we will crash
82  * if malicious code has altered it. That is, if something has
83  * set VectoredHandler to a non-encoded pointer
84  */
85  VectoredHandler = RtlDecodePointer(VectoredExceptionHandler->VectoredHandler);
86 
87  /* Call the handler */
88  HandlerReturn = VectoredHandler(&ExceptionInfo);
89 
90  /* Handler called -- grab the lock to dereference */
92 
93  /* Dereference and see if it got deleted */
94  VectoredExceptionHandler->Refs--;
95  if (VectoredExceptionHandler->Refs == 0)
96  {
97  /* It did -- do we have to free it now? */
98  if (HandlerReturn == EXCEPTION_CONTINUE_EXECUTION)
99  {
100  /* We don't, just remove it from the list and break out */
101  RemoveEntryList(&VectoredExceptionHandler->ListEntry);
102  HandlerRemoved = TRUE;
103  break;
104  }
105 
106  /*
107  * Get the next entry before freeing,
108  * and remove the current one from the list
109  */
110  CurrentEntry = VectoredExceptionHandler->ListEntry.Flink;
111  RemoveEntryList(&VectoredExceptionHandler->ListEntry);
112 
113  /* Free the entry outside of the lock, then reacquire it */
115  RtlFreeHeap(RtlGetProcessHeap(),
116  0,
117  VectoredExceptionHandler);
119  }
120  else
121  {
122  /* No delete -- should we continue execution? */
123  if (HandlerReturn == EXCEPTION_CONTINUE_EXECUTION)
124  {
125  /* Break out */
126  break;
127  }
128  else
129  {
130  /* Continue searching the list */
131  CurrentEntry = CurrentEntry->Flink;
132  }
133  }
134  }
135 
136  /* Let go of the lock now */
138 
139  /* Anything to free? */
140  if (HandlerRemoved)
141  {
142  /* Get rid of it */
143  RtlFreeHeap(RtlGetProcessHeap(),
144  0,
145  VectoredExceptionHandler);
146  }
147 
148  /* Return whether to continue execution (ignored for continue handlers) */
149  return (HandlerReturn == EXCEPTION_CONTINUE_EXECUTION) ? TRUE : FALSE;
150 }
#define TRUE
Definition: types.h:120
PVECTORED_EXCEPTION_HANDLER VectoredHandler
Definition: vectoreh.c:22
LONG(NTAPI * PVECTORED_EXCEPTION_HANDLER)(PEXCEPTION_POINTERS ExceptionPointers)
Definition: rtltypes.h:503
LIST_ENTRY ListEntry
Definition: vectoreh.c:21
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
Definition: vectoreh.c:19
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
long LONG
Definition: pedump.c:60
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
RTL_CRITICAL_SECTION RtlpVectoredHandlerLock
Definition: vectoreh.c:16
unsigned char BOOLEAN
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
PCONTEXT ContextRecord
Definition: rtltypes.h:197
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
Definition: typedefs.h:118
ULONG Refs
Definition: vectoreh.c:23
struct tagContext Context
Definition: acpixf.h:1034
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:196
NTSYSAPI PVOID WINAPI RtlDecodePointer(PVOID)
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:87

Referenced by RtlCallVectoredContinueHandlers(), and RtlCallVectoredExceptionHandlers().

◆ RtlpInitializeVectoredExceptionHandling()

VOID NTAPI RtlpInitializeVectoredExceptionHandling ( VOID  )

Definition at line 30 of file vectoreh.c.

31 {
32  /* Initialize our two lists and the common lock */
36 }
RTL_CRITICAL_SECTION RtlpVectoredHandlerLock
Definition: vectoreh.c:16
LIST_ENTRY RtlpVectoredContinueList
Definition: vectoreh.c:17
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
LIST_ENTRY RtlpVectoredExceptionList
Definition: vectoreh.c:17

Referenced by LdrpInitializeProcess().

◆ RtlpRemoveVectoredHandler()

ULONG NTAPI RtlpRemoveVectoredHandler ( IN PVOID  VectoredHandlerHandle,
IN PLIST_ENTRY  VectoredHandlerList 
)

Definition at line 197 of file vectoreh.c.

199 {
200  PLIST_ENTRY CurrentEntry;
201  PRTL_VECTORED_HANDLER_ENTRY VectoredExceptionHandler;
202  BOOLEAN HandlerRemoved;
203  BOOLEAN HandlerFound;
204 
205  /* Initialize these in case we don't find anything */
206  HandlerRemoved = FALSE;
207  HandlerFound = FALSE;
208 
209  /* Acquire list lock */
211 
212  /* Loop the list */
213  CurrentEntry = VectoredHandlerList->Flink;
214  while (CurrentEntry != VectoredHandlerList)
215  {
216  /* Get the struct */
217  VectoredExceptionHandler = CONTAINING_RECORD(CurrentEntry,
219  ListEntry);
220 
221  /* Does it match? */
222  if (VectoredExceptionHandler == VectoredHandlerHandle)
223  {
224  /*
225  * Great, this means it is a valid entry.
226  * However, it may be in use by the exception
227  * dispatcher, so we have a ref count to respect.
228  * If we can't remove it now then it will be done
229  * right after it is not in use anymore.
230  *
231  * Caller is supposed to keep track of if it has deleted the
232  * entry and should not call us twice for the same entry.
233  * We could maybe throw in some kind of ASSERT to detect this
234  * if this was to become a problem.
235  */
236  VectoredExceptionHandler->Refs--;
237  if (VectoredExceptionHandler->Refs == 0)
238  {
239  /* Not in use, ok to remove and free */
240  RemoveEntryList(&VectoredExceptionHandler->ListEntry);
241  HandlerRemoved = TRUE;
242  }
243 
244  /* Found what we are looking for, stop searching */
245  HandlerFound = TRUE;
246  break;
247  }
248  else
249  {
250  /* Get the next entry */
251  CurrentEntry = CurrentEntry->Flink;
252  }
253  }
254 
255  /* Done with the list, let go of the lock */
257 
258  /* Can we free what we found? */
259  if (HandlerRemoved)
260  {
261  /* Do it */
262  RtlFreeHeap(RtlGetProcessHeap(),
263  0,
264  VectoredExceptionHandler);
265  }
266 
267  /* Return whether we found it */
268  return (ULONG)HandlerFound;
269 }
#define TRUE
Definition: types.h:120
LIST_ENTRY ListEntry
Definition: vectoreh.c:21
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
Definition: vectoreh.c:19
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
RTL_CRITICAL_SECTION RtlpVectoredHandlerLock
Definition: vectoreh.c:16
unsigned char BOOLEAN
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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
Definition: typedefs.h:118
ULONG Refs
Definition: vectoreh.c:23
unsigned int ULONG
Definition: retypes.h:1

Referenced by RtlRemoveVectoredContinueHandler(), and RtlRemoveVectoredExceptionHandler().

◆ RtlRemoveVectoredContinueHandler()

ULONG NTAPI RtlRemoveVectoredContinueHandler ( IN PVOID  VectoredHandlerHandle)

Definition at line 333 of file vectoreh.c.

334 {
335  /* Call the shared routine */
336  return RtlpRemoveVectoredHandler(VectoredHandlerHandle,
338 }
ULONG NTAPI RtlpRemoveVectoredHandler(IN PVOID VectoredHandlerHandle, IN PLIST_ENTRY VectoredHandlerList)
Definition: vectoreh.c:197
LIST_ENTRY RtlpVectoredContinueList
Definition: vectoreh.c:17

◆ RtlRemoveVectoredExceptionHandler()

ULONG NTAPI RtlRemoveVectoredExceptionHandler ( IN PVOID  VectoredHandlerHandle)

Definition at line 323 of file vectoreh.c.

324 {
325  /* Call the shared routine */
326  return RtlpRemoveVectoredHandler(VectoredHandlerHandle,
328 }
ULONG NTAPI RtlpRemoveVectoredHandler(IN PVOID VectoredHandlerHandle, IN PLIST_ENTRY VectoredHandlerList)
Definition: vectoreh.c:197
LIST_ENTRY RtlpVectoredExceptionList
Definition: vectoreh.c:17

Variable Documentation

◆ RtlpVectoredContinueList

◆ RtlpVectoredExceptionList

◆ RtlpVectoredHandlerLock