ffab68b8b53e396bc1173294247b42ad520473cd
[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
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 if(VectoredHandler(&ExceptionInfo) == EXCEPTION_CONTINUE_EXECUTION)
55 {
56 RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
57 return ExceptionContinueSearch;
58 }
59 }
60 RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
61 }
62
63 return ExceptionContinueExecution;
64 }
65
66 VOID
67 RtlpInitializeVectoredExceptionHandling(VOID)
68 {
69 InitializeListHead(&RtlpVectoredExceptionHead);
70 RtlInitializeCriticalSection(&RtlpVectoredExceptionLock);
71 }
72
73
74 /*
75 * @implemented
76 */
77 PVOID STDCALL
78 RtlAddVectoredExceptionHandler(IN ULONG FirstHandler,
79 IN PVECTORED_EXCEPTION_HANDLER VectoredHandler)
80 {
81 PRTL_VECTORED_EXCEPTION_HANDLER veh;
82
83 veh = RtlAllocateHeap(RtlGetProcessHeap(),
84 0,
85 sizeof(RTL_VECTORED_EXCEPTION_HANDLER));
86 if(veh != NULL)
87 {
88 veh->VectoredHandler = RtlEncodePointer(VectoredHandler);
89 RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
90 if(FirstHandler != 0)
91 {
92 InsertHeadList(&RtlpVectoredExceptionHead,
93 &veh->ListEntry);
94 }
95 else
96 {
97 InsertTailList(&RtlpVectoredExceptionHead,
98 &veh->ListEntry);
99 }
100 RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
101 }
102
103 return veh;
104 }
105
106
107 /*
108 * @implemented
109 */
110 ULONG STDCALL
111 RtlRemoveVectoredExceptionHandler(IN PVOID VectoredHandlerHandle)
112 {
113 PLIST_ENTRY CurrentEntry;
114 PRTL_VECTORED_EXCEPTION_HANDLER veh = NULL;
115 ULONG Removed = FALSE;
116
117 RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
118 for(CurrentEntry = RtlpVectoredExceptionHead.Flink;
119 CurrentEntry != &RtlpVectoredExceptionHead;
120 CurrentEntry = CurrentEntry->Flink)
121 {
122 veh = CONTAINING_RECORD(CurrentEntry,
123 RTL_VECTORED_EXCEPTION_HANDLER,
124 ListEntry);
125 if(veh == VectoredHandlerHandle)
126 {
127 RemoveEntryList(&veh->ListEntry);
128 Removed = TRUE;
129 break;
130 }
131 }
132 RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
133
134 if(Removed)
135 {
136 RtlFreeHeap(RtlGetProcessHeap(),
137 0,
138 veh);
139 }
140
141 return Removed;
142 }
143
144 /* EOF */