- Remove deprecated CHECKPOINT/CHECKPOINT1 macros which basically translated into...
[reactos.git] / reactos / lib / rtl / vectoreh.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS sysem libraries
4 * PURPOSE: Vectored Exception Handling
5 * FILE: lib/rtl/vectoreh.c
6 * PROGRAMERS: Thomas Weidenmueller
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include <rtl.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 static RTL_CRITICAL_SECTION RtlpVectoredExceptionLock;
17 static LIST_ENTRY RtlpVectoredExceptionHead;
18
19 typedef struct _RTL_VECTORED_EXCEPTION_HANDLER
20 {
21 LIST_ENTRY ListEntry;
22 PVECTORED_EXCEPTION_HANDLER VectoredHandler;
23 } RTL_VECTORED_EXCEPTION_HANDLER, *PRTL_VECTORED_EXCEPTION_HANDLER;
24
25 /* FIXME - stupid ld won't resolve RtlDecodePointer! Since their implementation
26 is the same just use RtlEncodePointer for now! */
27 #define RtlDecodePointer RtlEncodePointer
28
29 /* FUNCTIONS ***************************************************************/
30
31 EXCEPTION_DISPOSITION NTAPI
32 RtlpExecuteVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord,
33 IN PCONTEXT Context)
34 {
35 PLIST_ENTRY CurrentEntry;
36 PRTL_VECTORED_EXCEPTION_HANDLER veh;
37 PVECTORED_EXCEPTION_HANDLER VectoredHandler;
38 EXCEPTION_POINTERS ExceptionInfo;
39
40 ExceptionInfo.ExceptionRecord = ExceptionRecord;
41 ExceptionInfo.ContextRecord = Context;
42
43 if(RtlpVectoredExceptionHead.Flink != &RtlpVectoredExceptionHead)
44 {
45 RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
46 for(CurrentEntry = RtlpVectoredExceptionHead.Flink;
47 CurrentEntry != &RtlpVectoredExceptionHead;
48 CurrentEntry = CurrentEntry->Flink)
49 {
50 veh = CONTAINING_RECORD(CurrentEntry,
51 RTL_VECTORED_EXCEPTION_HANDLER,
52 ListEntry);
53 VectoredHandler = RtlDecodePointer(veh->VectoredHandler);
54 RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
55
56 if(VectoredHandler(&ExceptionInfo) == EXCEPTION_CONTINUE_EXECUTION)
57 {
58 return ExceptionContinueSearch;
59 }
60
61 RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
62 }
63 RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
64 }
65
66 return ExceptionContinueExecution;
67 }
68
69 VOID
70 RtlpInitializeVectoredExceptionHandling(VOID)
71 {
72 InitializeListHead(&RtlpVectoredExceptionHead);
73 RtlInitializeCriticalSection(&RtlpVectoredExceptionLock);
74 }
75
76
77 /*
78 * @implemented
79 */
80 PVOID NTAPI
81 RtlAddVectoredExceptionHandler(IN ULONG FirstHandler,
82 IN PVECTORED_EXCEPTION_HANDLER VectoredHandler)
83 {
84 PRTL_VECTORED_EXCEPTION_HANDLER veh;
85
86 veh = RtlAllocateHeap(RtlGetProcessHeap(),
87 0,
88 sizeof(RTL_VECTORED_EXCEPTION_HANDLER));
89 if(veh != NULL)
90 {
91 veh->VectoredHandler = RtlEncodePointer(VectoredHandler);
92 RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
93 if(FirstHandler != 0)
94 {
95 InsertHeadList(&RtlpVectoredExceptionHead,
96 &veh->ListEntry);
97 }
98 else
99 {
100 InsertTailList(&RtlpVectoredExceptionHead,
101 &veh->ListEntry);
102 }
103 RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
104 }
105
106 return veh;
107 }
108
109
110 /*
111 * @implemented
112 */
113 ULONG NTAPI
114 RtlRemoveVectoredExceptionHandler(IN PVOID VectoredHandlerHandle)
115 {
116 PLIST_ENTRY CurrentEntry;
117 PRTL_VECTORED_EXCEPTION_HANDLER veh = NULL;
118 ULONG Removed = FALSE;
119
120 RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
121 for(CurrentEntry = RtlpVectoredExceptionHead.Flink;
122 CurrentEntry != &RtlpVectoredExceptionHead;
123 CurrentEntry = CurrentEntry->Flink)
124 {
125 veh = CONTAINING_RECORD(CurrentEntry,
126 RTL_VECTORED_EXCEPTION_HANDLER,
127 ListEntry);
128 if(veh == VectoredHandlerHandle)
129 {
130 RemoveEntryList(&veh->ListEntry);
131 Removed = TRUE;
132 break;
133 }
134 }
135 RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
136
137 if(Removed)
138 {
139 RtlFreeHeap(RtlGetProcessHeap(),
140 0,
141 veh);
142 }
143
144 return Removed;
145 }
146
147 /* EOF */