ee46d0d77c3d2866940060d59edd9ee394cfb2cd
[reactos.git] / reactos / lib / ntdll / main / i386 / dispatch.S
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NT Library
4 * FILE: lib/ntdll/main/i386/dispatch.S
5 * PURPOSE: User-Mode NT Dispatchers
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ndk/asm.h>
12 .intel_syntax noprefix
13
14 #define EXCEPTION_NONCONTINUABLE 1
15 #define EXCEPTION_UNWINDING 2
16 #define EXCEPTION_EXIT_UNWIND 4
17 #define EXCEPTION_UNWIND (EXCEPTION_UNWINDING + EXCEPTION_EXIT_UNWIND)
18
19 #define STATUS_CALLBACK_POP_STACK 0xC0000423
20
21 #define ExceptionContinueSearch 1
22
23 /* FUNCTIONS ****************************************************************/
24
25 .globl _LdrInitializeThunk@16
26 _LdrInitializeThunk@16:
27
28 /* Get the APC Context */
29 lea eax, [esp+16]
30
31 /* Send it as the first parameter */
32 mov [esp+4], eax
33
34 /* Terminate the frame list */
35 xor ebp, ebp
36
37 /* Jump into the C initialization routine */
38 jmp _LdrpInit@12
39
40 .globl _KiUserExceptionApcHandler@16
41 _KiUserApcExceptionHandler@16:
42
43 /* Put the exception record in ECX and check the Flags */
44 mov ecx, [esp+4]
45 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND
46 jz .return
47
48 /* Test alert the thread */
49 call _NtTestAlert@0
50
51 .return:
52 /* We'll continue */
53 mov eax, ExceptionContinueSearch
54 ret 16
55
56 .globl _KiUserApcDispatcher@16
57 _KiUserApcDispatcher@16:
58
59 /* Put the Context in EDI */
60 lea edi, [esp+16]
61
62 /* Get the ApcRoutine and call it */
63 pop eax
64 call eax
65
66 /* Switch back to the context */
67 push 1
68 push edi
69 call _ZwContinue@8
70
71 .globl _KiUserCallbackExceptionHandler@16
72 _KiUserCallbackExceptionHandler@16:
73
74 /* Put the exception record in ECX and check the Flags */
75 mov ecx, [esp+4]
76 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND
77 jz return
78
79 /* Tell the kernel to invalidate the stack */
80 push STATUS_CALLBACK_POP_STACK
81 push 0
82 push 0
83 call _ZwCallbackReturn@12
84
85 return:
86 /* We'll continue */
87 mov eax, ExceptionContinueSearch
88 ret 16
89
90 .globl _KiUserCallbackDispatcher@12
91 _KiUserCallbackDispatcher@12:
92
93 /* Get the callback Index */
94 add esp, 4
95 pop edx
96
97 /* Get the callback table */
98 mov eax, [fs:TEB_PEB]
99 mov eax, [eax+PEB_KERNEL_CALLBACK_TABLE]
100
101 /* Call the routine */
102 call [eax+edx*4]
103
104 /* Return from callback */
105 push eax
106 push 0
107 push 0
108 call _ZwCallbackReturn@12
109
110 .globl _KiRaiseUserExceptionDispatcher@0
111 _KiRaiseUserExceptionDispatcher@0:
112
113 /* Setup stack for EXCEPTION_RECORD */
114 push ebp
115 mov ebp, esp
116 sub esp, SIZEOF_EXCEPTION_RECORD
117
118 /* Fill out the record */
119 mov eax, [fs:TEB_SELECTOR]
120 mov eax, [eax+TEB_EXCEPTION_CODE]
121 mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
122 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], 0
123 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], 0
124 mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
125
126 /* Raise the exception */
127 push esp
128 call _RtlRaiseException@4
129
130 /* Return exception code */
131 mov eax, [esp+EXCEPTION_RECORD_EXCEPTION_CODE]
132 mov esp, ebp
133 pop ebp
134 ret
135
136 .globl _KiUserExceptionDispatcher@8
137 _KiUserExceptionDispatcher@8:
138
139 /* Save the Context and Exception Records */
140 mov ecx, [esp+4]
141 mov ebx, [esp]
142
143 /* Call the vectored exception handler */
144 push ecx
145 push ebx
146 call _RtlpExecuteVectoredExceptionHandlers@8
147
148 /* Check for success */
149 or al, al
150 jnz ContinueExecution
151
152 /* Dispatch the exception */
153 sub esp, 8
154 call _RtlDispatchException@8
155
156 /* Check for success */
157 or al, al
158 jz RaiseException
159
160 ContinueExecution:
161 /* Pop off the records */
162 pop ebx
163 pop ecx
164
165 /* We're fine, continue execution */
166 push 0
167 push ecx
168 call _ZwContinue@8
169
170 /* Exit */
171 jmp Exit
172
173 RaiseException:
174 /* Pop off the records */
175 pop ebx
176 pop ecx
177
178 /* Raise the exception */
179 push 0
180 push ecx
181 push ebx
182 call _ZwRaiseException@12
183
184 Exit:
185 /* Allocate space for the nested exception record */
186 add esp, -SIZEOF_EXCEPTION_RECORD
187
188 /* Set it up */
189 mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
190 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_NONCONTINUABLE
191 mov [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], ebx
192 mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
193
194 /* Raise the exception */
195 push esp
196 call _RtlRaiseException@4
197 ret 8
198
199 .globl _RtlpGetStackLimits@8
200 _RtlpGetStackLimits@8:
201
202 /* Get the stack limits */
203 mov eax, [fs:TEB_STACK_LIMIT]
204 mov ecx, [fs:TEB_STACK_BASE]
205
206 /* Return them */
207 mov edx, [esp+4]
208 mov [edx], eax
209 mov edx, [esp+8]
210 mov [edx], ecx
211
212 /* return */
213 ret 8
214