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)
9 /* INCLUDES ******************************************************************/
12 #include <ndk/i386/segment.h>
13 .intel_syntax noprefix
15 #define EXCEPTION_NONCONTINUABLE 1
16 #define EXCEPTION_UNWINDING 2
17 #define EXCEPTION_EXIT_UNWIND 4
18 #define EXCEPTION_UNWIND (EXCEPTION_UNWINDING + EXCEPTION_EXIT_UNWIND)
20 #define STATUS_CALLBACK_POP_STACK 0xC0000423
22 #define ExceptionContinueSearch 1
24 /* FUNCTIONS ****************************************************************/
26 .globl _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 */
41 .globl _KiUserExceptionApcHandler@16
42 _KiUserApcExceptionHandler@16:
44 /* Put the exception record in ECX and check the Flags */
46 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND
49 /* Test alert the thread */
54 mov eax, ExceptionContinueSearch
57 .globl _KiUserApcDispatcher@16
58 _KiUserApcDispatcher@16:
60 /* Put the Context in EDI */
63 /* Get the ApcRoutine and call it */
67 /* Switch back to the context */
72 .globl _KiUserCallbackExceptionHandler@16
73 _KiUserCallbackExceptionHandler@16:
75 /* Put the exception record in ECX and check the Flags */
77 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND
80 /* Tell the kernel to invalidate the stack */
81 push STATUS_CALLBACK_POP_STACK
84 call _ZwCallbackReturn@12
88 mov eax, ExceptionContinueSearch
91 .globl _KiUserCallbackDispatcher@12
92 _KiUserCallbackDispatcher@12:
94 /* Get the callback Index */
98 /* Get the callback table */
100 mov eax, [eax+PEB_KERNEL_CALLBACK_TABLE]
102 /* Call the routine */
105 /* Return from callback */
109 call _ZwCallbackReturn@12
111 .globl _KiRaiseUserExceptionDispatcher@0
112 _KiRaiseUserExceptionDispatcher@0:
114 /* Setup stack for EXCEPTION_RECORD */
117 sub esp, SIZEOF_EXCEPTION_RECORD
119 /* Fill out the record */
120 mov eax, [fs:TEB_SELECTOR]
121 mov eax, [eax+TEB_EXCEPTION_CODE]
122 mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
123 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], 0
124 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], 0
125 mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
127 /* Raise the exception */
129 call _RtlRaiseException@4
131 /* Return exception code */
132 mov eax, [esp+EXCEPTION_RECORD_EXCEPTION_CODE]
137 .globl _KiUserExceptionDispatcher@8
138 _KiUserExceptionDispatcher@8:
140 /* Save the Context and Exception Records */
144 /* Dispatch the exception */
147 call _RtlDispatchException@8
149 /* Check for success */
153 /* Pop off the records */
157 /* We're fine, continue execution */
166 /* Pop off the records */
170 /* Raise the exception */
174 call _ZwRaiseException@12
177 /* Allocate space for the nested exception record */
178 add esp, -SIZEOF_EXCEPTION_RECORD
181 mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
182 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_NONCONTINUABLE
183 mov [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], ebx
184 mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
186 /* Raise the exception */
188 call _RtlRaiseException@4
191 .globl _RtlpGetStackLimits@8
192 _RtlpGetStackLimits@8:
194 /* Get the stack limits */
195 mov eax, [fs:TEB_STACK_LIMIT]
196 mov ecx, [fs:TEB_STACK_BASE]