2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NT Library
4 * FILE: dl/ntdll/dispatch/i386/dispatch.S
5 * PURPOSE: User-Mode NT Dispatchers
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
9 /* INCLUDES ******************************************************************/
14 EXTERN _LdrpInit@12:PROC
15 EXTERN _NtTestAlert@0:PROC
16 EXTERN _RtlDispatchException@8:PROC
17 EXTERN _RtlRaiseException@4:PROC
18 EXTERN _RtlRaiseStatus@4:PROC
19 EXTERN _ZwCallbackReturn@12:PROC
20 EXTERN _ZwContinue@8:PROC
21 EXTERN _ZwRaiseException@12:PROC
23 /* FUNCTIONS ****************************************************************/
26 PUBLIC _LdrInitializeThunk@16
27 _LdrInitializeThunk@16:
29 /* Get the APC Context */
32 /* Send it as the first parameter */
35 /* Terminate the frame list */
38 /* Jump into the C initialization routine */
42 _KiUserApcExceptionHandler:
44 /* Put the exception record in ECX and check the Flags */
46 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
49 /* Test alert the thread */
53 /* We'll execute handler */
54 mov eax, EXCEPTION_EXECUTE_HANDLER
58 PUBLIC _KiUserApcDispatcher@16
59 _KiUserApcDispatcher@16:
62 lea eax, [esp+CONTEXT_ALIGNED_SIZE+16]
63 mov ecx, fs:[TEB_EXCEPTION_LIST]
64 mov edx, offset _KiUserApcExceptionHandler
69 mov fs:[TEB_EXCEPTION_LIST], eax
71 /* Put the Context in EDI */
75 /* Call the APC Routine */
78 /* Restore exception list */
79 mov ecx, [edi+CONTEXT_ALIGNED_SIZE]
80 mov fs:[TEB_EXCEPTION_LIST], ecx
82 /* Switch back to the context */
87 /* Save callback return value */
93 call _RtlRaiseStatus@4
98 _KiUserCallbackExceptionHandler:
100 /* Put the exception record in ECX and check the Flags */
102 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
105 /* Tell the kernel to invalidate the stack */
106 push STATUS_CALLBACK_POP_STACK
109 call _ZwCallbackReturn@12
112 /* We'll execute the handler */
113 mov eax, EXCEPTION_EXECUTE_HANDLER
117 PUBLIC _KiUserCallbackDispatcher@12
118 _KiUserCallbackDispatcher@12:
120 /* Setup SEH stack */
121 mov ecx, fs:[TEB_EXCEPTION_LIST]
122 mov edx, offset _KiUserCallbackExceptionHandler
128 mov fs:[TEB_EXCEPTION_LIST], eax
130 /* Get the callback Index */
134 /* Get the callback table */
135 mov eax, [fs:TEB_PEB]
136 mov eax, [eax+PEB_KERNEL_CALLBACK_TABLE]
138 /* Call the routine */
139 call dword ptr [eax+edx*4]
141 /* Return from callback */
145 call _ZwCallbackReturn@12
147 /* Save callback return value */
153 call _RtlRaiseStatus@4
158 PUBLIC _KiRaiseUserExceptionDispatcher@0
159 _KiRaiseUserExceptionDispatcher@0:
161 /* Setup stack for EXCEPTION_RECORD */
164 sub esp, EXCEPTION_RECORD_LENGTH
166 /* Fill out the record */
167 mov [esp+EXCEPTION_RECORD_EXCEPTION_ADDRESS], eax
168 mov eax, [fs:KPCR_TEB]
169 mov eax, [eax+TEB_EXCEPTION_CODE]
170 mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
171 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], 0
172 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], 0
173 mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
175 /* Raise the exception */
177 call _RtlRaiseException@4
179 /* Return exception code */
180 mov eax, [esp+EXCEPTION_RECORD_EXCEPTION_CODE]
186 PUBLIC _KiUserExceptionDispatcher@8
187 _KiUserExceptionDispatcher@8:
189 /* Clear direction flag */
192 /* Save the Context and Exception Records */
196 /* Dispatch the exception */
199 call _RtlDispatchException@8
201 /* Check for success */
205 /* Pop off the records */
209 /* We're fine, continue execution */
218 /* Pop off the records */
222 /* Raise the exception */
226 call _ZwRaiseException@12
229 /* Allocate space for the nested exception record */
230 add esp, -SIZEOF_EXCEPTION_RECORD
233 mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
234 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_NONCONTINUABLE
235 mov [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], ebx
236 mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
238 /* Raise the exception */
240 call _RtlRaiseException@4
244 PUBLIC _KiIntSystemCall@0
247 /* Set stack in EDX and do the interrupt */
251 /* Return to caller */
255 PUBLIC _KiFastSystemCall@0
258 /* Put ESP in EDX and do the SYSENTER */
263 PUBLIC _KiFastSystemCallRet@0
264 _KiFastSystemCallRet@0:
266 /* Just return to caller */
270 PUBLIC _RtlpGetStackLimits@8
271 _RtlpGetStackLimits@8:
273 /* Get the stack limits */
274 mov eax, [fs:TEB_STACK_LIMIT]
275 mov ecx, [fs:TEB_STACK_BASE]