ac3596c3b54fdde6f4a0678c25791b8a41f2bad5
[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 static volatile LONG RtlpVectoredExceptionsInstalled;
19
20 typedef struct _RTL_VECTORED_EXCEPTION_HANDLER
21 {
22 LIST_ENTRY ListEntry;
23 PVECTORED_EXCEPTION_HANDLER VectoredHandler;
24 ULONG Refs;
25 BOOLEAN Deleted;
26 } RTL_VECTORED_EXCEPTION_HANDLER, *PRTL_VECTORED_EXCEPTION_HANDLER;
27
28 /* FUNCTIONS ***************************************************************/
29
30 BOOLEAN
31 NTAPI
32 RtlCallVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord,
33 IN PCONTEXT Context)
34 {
35 PLIST_ENTRY CurrentEntry;
36 PRTL_VECTORED_EXCEPTION_HANDLER veh = NULL;
37 PVECTORED_EXCEPTION_HANDLER VectoredHandler;
38 EXCEPTION_POINTERS ExceptionInfo;
39 BOOLEAN Remove = FALSE;
40 BOOLEAN Ret = FALSE;
41
42 ExceptionInfo.ExceptionRecord = ExceptionRecord;
43 ExceptionInfo.ContextRecord = Context;
44
45 if(RtlpVectoredExceptionsInstalled)
46 {
47 RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
48 CurrentEntry = RtlpVectoredExceptionHead.Flink;
49 while (CurrentEntry != &RtlpVectoredExceptionHead)
50 {
51 veh = CONTAINING_RECORD(CurrentEntry,
52 RTL_VECTORED_EXCEPTION_HANDLER,
53 ListEntry);
54 veh->Refs++;
55 RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
56
57 VectoredHandler = RtlDecodePointer(veh->VectoredHandler);
58 if(VectoredHandler(&ExceptionInfo) == EXCEPTION_CONTINUE_EXECUTION)
59 {
60 RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
61 if (--veh->Refs == 0)
62 {
63 RemoveEntryList (&veh->ListEntry);
64 InterlockedDecrement (&RtlpVectoredExceptionsInstalled);
65 Remove = TRUE;
66 }
67 Ret = TRUE;
68 break;
69 }
70
71 RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
72
73 if (--veh->Refs == 0)
74 {
75 CurrentEntry = veh->ListEntry.Flink;
76 RemoveEntryList (&veh->ListEntry);
77 InterlockedDecrement (&RtlpVectoredExceptionsInstalled);
78 RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
79
80 RtlFreeHeap(RtlGetProcessHeap(),
81 0,
82 veh);
83 RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
84 }
85 else
86 CurrentEntry = CurrentEntry->Flink;
87 }
88
89 RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
90 }
91
92 if (Remove)
93 {
94 RtlFreeHeap(RtlGetProcessHeap(),
95 0,
96 veh);
97 }
98
99 return Ret;
100 }
101
102 VOID
103 RtlpInitializeVectoredExceptionHandling(VOID)
104 {
105 InitializeListHead(&RtlpVectoredExceptionHead);
106 RtlInitializeCriticalSection(&RtlpVectoredExceptionLock);
107 RtlpVectoredExceptionsInstalled = 0;
108 }
109
110
111 /*
112 * @implemented
113 */
114 PVOID NTAPI DECLSPEC_HOTPATCH
115 RtlAddVectoredExceptionHandler(IN ULONG FirstHandler,
116 IN PVECTORED_EXCEPTION_HANDLER VectoredHandler)
117 {
118 PRTL_VECTORED_EXCEPTION_HANDLER veh;
119
120 veh = RtlAllocateHeap(RtlGetProcessHeap(),
121 0,
122 sizeof(RTL_VECTORED_EXCEPTION_HANDLER));
123 if(veh != NULL)
124 {
125 veh->VectoredHandler = RtlEncodePointer(VectoredHandler);
126 veh->Refs = 1;
127 veh->Deleted = FALSE;
128 RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
129 if(FirstHandler != 0)
130 {
131 InsertHeadList(&RtlpVectoredExceptionHead,
132 &veh->ListEntry);
133 }
134 else
135 {
136 InsertTailList(&RtlpVectoredExceptionHead,
137 &veh->ListEntry);
138 }
139 InterlockedIncrement (&RtlpVectoredExceptionsInstalled);
140 RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
141 }
142
143 return veh;
144 }
145
146
147 /*
148 * @implemented
149 */
150 ULONG NTAPI
151 RtlRemoveVectoredExceptionHandler(IN PVOID VectoredHandlerHandle)
152 {
153 PLIST_ENTRY CurrentEntry;
154 PRTL_VECTORED_EXCEPTION_HANDLER veh = NULL;
155 BOOLEAN Remove = FALSE;
156 ULONG Ret = FALSE;
157
158 RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
159 for(CurrentEntry = RtlpVectoredExceptionHead.Flink;
160 CurrentEntry != &RtlpVectoredExceptionHead;
161 CurrentEntry = CurrentEntry->Flink)
162 {
163 veh = CONTAINING_RECORD(CurrentEntry,
164 RTL_VECTORED_EXCEPTION_HANDLER,
165 ListEntry);
166 if(veh == VectoredHandlerHandle)
167 {
168 if (!veh->Deleted)
169 {
170 if (--veh->Refs == 0)
171 {
172 RemoveEntryList (&veh->ListEntry);
173 Remove = TRUE;
174 }
175 veh->Deleted = TRUE;
176 Ret = TRUE;
177 break;
178 }
179 }
180 }
181 RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
182
183 if(Remove)
184 {
185 RtlFreeHeap(RtlGetProcessHeap(),
186 0,
187 veh);
188 }
189
190 return Ret;
191 }
192
193 PVOID
194 NTAPI
195 DECLSPEC_HOTPATCH
196 RtlAddVectoredContinueHandler(
197 IN ULONG FirstHandler,
198 IN PVECTORED_EXCEPTION_HANDLER VectoredHandler)
199 {
200 UNIMPLEMENTED;
201 return NULL;
202 }
203
204 ULONG
205 NTAPI
206 RtlRemoveVectoredContinueHandler(
207 IN PVOID VectoredHandlerHandle)
208 {
209 UNIMPLEMENTED;
210 return FALSE;
211 }
212
213 /* EOF */