1/* 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) 7 */ 8 9/* INCLUDES ******************************************************************/ 10 11#include <asm.inc> 12#include <ks386.inc> 13 14EXTERN _LdrpInit@12:PROC 15EXTERN _NtTestAlert@0:PROC 16EXTERN _RtlDispatchException@8:PROC 17EXTERN _RtlRaiseException@4:PROC 18EXTERN _RtlRaiseStatus@4:PROC 19EXTERN _ZwCallbackReturn@12:PROC 20EXTERN _ZwContinue@8:PROC 21EXTERN _ZwRaiseException@12:PROC 22 23/* FUNCTIONS ****************************************************************/ 24.code 25 26PUBLIC _LdrInitializeThunk@16 27_LdrInitializeThunk@16: 28 29 /* Get the APC Context */ 30 lea eax, [esp+16] 31 32 /* Send it as the first parameter */ 33 mov [esp+4], eax 34 35 /* Terminate the frame list */ 36 xor ebp, ebp 37 38 /* Jump into the C initialization routine */ 39 jmp _LdrpInit@12 40 41 42_KiUserApcExceptionHandler: 43 44 /* Put the exception record in ECX and check the Flags */ 45 mov ecx, [esp+4] 46 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING 47 jz .return 48 49 /* Test alert the thread */ 50 call _NtTestAlert@0 51 52.return: 53 /* We'll execute handler */ 54 mov eax, EXCEPTION_EXECUTE_HANDLER 55 ret 16 56 57 58PUBLIC _KiUserApcDispatcher@16 59_KiUserApcDispatcher@16: 60 61 /* Setup SEH stack */ 62 lea eax, [esp+CONTEXT_ALIGNED_SIZE+16] 63 mov ecx, fs:[TEB_EXCEPTION_LIST] 64 mov edx, offset _KiUserApcExceptionHandler 65 mov [eax], ecx 66 mov [eax+4], edx 67 68 /* Enable SEH */ 69 mov fs:[TEB_EXCEPTION_LIST], eax 70 71 /* Put the Context in EDI */ 72 pop eax 73 lea edi, [esp+12] 74 75 /* Call the APC Routine */ 76 call eax 77 78 /* Restore exception list */ 79 mov ecx, [edi+CONTEXT_ALIGNED_SIZE] 80 mov fs:[TEB_EXCEPTION_LIST], ecx 81 82 /* Switch back to the context */ 83 push 1 84 push edi 85 call _ZwContinue@8 86 87 /* Save callback return value */ 88 mov esi, eax 89 90 /* Raise status */ 91StatusRaiseApc: 92 push esi 93 call _RtlRaiseStatus@4 94 jmp StatusRaiseApc 95 ret 16 96 97 98_KiUserCallbackExceptionHandler: 99 100 /* Put the exception record in ECX and check the Flags */ 101 mov ecx, [esp+4] 102 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING 103 jz return 104 105 /* Tell the kernel to invalidate the stack */ 106 push STATUS_CALLBACK_POP_STACK 107 push 0 108 push 0 109 call _ZwCallbackReturn@12 110 111return: 112 /* We'll execute the handler */ 113 mov eax, EXCEPTION_EXECUTE_HANDLER 114 ret 16 115 116 117PUBLIC _KiUserCallbackDispatcher@12 118_KiUserCallbackDispatcher@12: 119 120 /* Setup SEH stack */ 121 mov ecx, fs:[TEB_EXCEPTION_LIST] 122 mov edx, offset _KiUserCallbackExceptionHandler 123 lea eax, [esp+16] 124 mov [esp+16], ecx 125 mov [esp+20], edx 126 127 /* Enable SEH */ 128 mov fs:[TEB_EXCEPTION_LIST], eax 129 130 /* Get the callback Index */ 131 add esp, 4 132 pop edx 133 134 /* Get the callback table */ 135 mov eax, [fs:TEB_PEB] 136 mov eax, [eax+PEB_KERNEL_CALLBACK_TABLE] 137 138 /* Call the routine */ 139 call dword ptr [eax+edx*4] 140 141 /* Return from callback */ 142 push eax 143 push 0 144 push 0 145 call _ZwCallbackReturn@12 146 147 /* Save callback return value */ 148 mov esi, eax 149 150 /* Raise status */ 151StatusRaise: 152 push esi 153 call _RtlRaiseStatus@4 154 jmp StatusRaise 155 ret 12 156 157 158PUBLIC _KiRaiseUserExceptionDispatcher@0 159_KiRaiseUserExceptionDispatcher@0: 160 161 /* Setup stack for EXCEPTION_RECORD */ 162 push ebp 163 mov ebp, esp 164 sub esp, EXCEPTION_RECORD_LENGTH 165 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 174 175 /* Raise the exception */ 176 push esp 177 call _RtlRaiseException@4 178 179 /* Return exception code */ 180 mov eax, [esp+EXCEPTION_RECORD_EXCEPTION_CODE] 181 mov esp, ebp 182 pop ebp 183 ret 184 185 186PUBLIC _KiUserExceptionDispatcher@8 187.PROC _KiUserExceptionDispatcher@8 188 FPO 0, 0, 0, 0, 0, FRAME_FPO 189 190 /* Clear direction flag */ 191 cld 192 193 /* Save the Context and Exception Records */ 194 mov ecx, [esp+4] 195 mov ebx, [esp] 196 197 /* Dispatch the exception */ 198 push ecx 199 push ebx 200 call _RtlDispatchException@8 201 202 /* Check for success */ 203 or al, al 204 jz RaiseException 205 206 /* Pop off the records */ 207 pop ebx 208 pop ecx 209 210 /* We're fine, continue execution */ 211 push 0 212 push ecx 213 call _ZwContinue@8 214 215 /* Exit */ 216 jmp Exit 217 218RaiseException: 219 /* Pop off the records */ 220 pop ebx 221 pop ecx 222 223 /* Raise the exception */ 224 push 0 225 push ecx 226 push ebx 227 call _ZwRaiseException@12 228 229Exit: 230 /* Allocate space for the nested exception record */ 231 add esp, -SIZEOF_EXCEPTION_RECORD 232 233 /* Set it up */ 234 mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax 235 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_NONCONTINUABLE 236 mov [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], ebx 237 mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0 238 239 /* Raise the exception */ 240 push esp 241 call _RtlRaiseException@4 242 ret 8 243 244.ENDP 245 246PUBLIC _KiIntSystemCall@0 247.PROC _KiIntSystemCall@0 248 FPO 0, 0, 0, 0, 0, FRAME_FPO 249 250 /* Set stack in EDX and do the interrupt */ 251 lea edx, [esp+8] 252 int HEX(2E) 253 254 /* Return to caller */ 255 ret 256 257.ENDP 258 259PUBLIC _KiFastSystemCall@0 260.PROC _KiFastSystemCall@0 261 FPO 0, 0, 0, 0, 0, FRAME_FPO 262 263 /* Put ESP in EDX and do the SYSENTER */ 264 mov edx, esp 265 sysenter 266 267.ENDP 268 269PUBLIC _KiFastSystemCallRet@0 270.PROC _KiFastSystemCallRet@0 271 FPO 0, 0, 0, 0, 0, FRAME_FPO 272 273 /* Just return to caller */ 274 ret 275 276.ENDP 277 278END 279