-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS NT Library\r
- * FILE: dl/ntdll/dispatch/i386/dispatch.S\r
- * PURPOSE: User-Mode NT Dispatchers\r
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)\r
- */\r
-\r
-/* INCLUDES ******************************************************************/\r
-\r
-#include <ndk/asm.h>\r
-.intel_syntax noprefix\r
-\r
-/* FUNCTIONS ****************************************************************/\r
-\r
-.func LdrInitializeThunk@16\r
-.globl _LdrInitializeThunk@16\r
-_LdrInitializeThunk@16:\r
-\r
- /* Get the APC Context */\r
- lea eax, [esp+16]\r
-\r
- /* Send it as the first parameter */\r
- mov [esp+4], eax\r
-\r
- /* Terminate the frame list */\r
- xor ebp, ebp\r
-\r
- /* Jump into the C initialization routine */\r
- jmp _LdrpInit@12\r
-.endfunc\r
-\r
-.func KiUserApcExceptionHandler\r
-_KiUserApcExceptionHandler:\r
-\r
- /* Put the exception record in ECX and check the Flags */\r
- mov ecx, [esp+4]\r
- test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING\r
- jz .return\r
-\r
- /* Test alert the thread */\r
- call _NtTestAlert@0\r
-\r
-.return:\r
- /* We'll execute handler */\r
- mov eax, EXCEPTION_EXECUTE_HANDLER\r
- ret 16\r
-.endfunc\r
-\r
-.func KiUserApcDispatcher@16\r
-.globl _KiUserApcDispatcher@16\r
-_KiUserApcDispatcher@16:\r
-\r
- /* Setup SEH stack */\r
- lea eax, [esp+CONTEXT_ALIGNED_SIZE+16]\r
- mov ecx, fs:[TEB_EXCEPTION_LIST]\r
- mov edx, offset _KiUserApcExceptionHandler\r
- mov [eax], ecx\r
- mov [eax+4], edx\r
-\r
- /* Enable SEH */\r
- mov fs:[TEB_EXCEPTION_LIST], eax\r
-\r
- /* Put the Context in EDI */\r
- pop eax\r
- lea edi, [esp+12]\r
-\r
- /* Call the APC Routine */\r
- call eax\r
-\r
- /* Restore exception list */\r
- mov ecx, [edi+CONTEXT_ALIGNED_SIZE]\r
- mov fs:[TEB_EXCEPTION_LIST], ecx\r
-\r
- /* Switch back to the context */\r
- push 1\r
- push edi\r
- call _ZwContinue@8\r
-\r
- /* Save callback return value */\r
- mov esi, eax\r
-\r
- /* Raise status */\r
-StatusRaiseApc:\r
- push esi\r
- call _RtlRaiseStatus@4\r
- jmp StatusRaiseApc\r
- ret 16\r
-.endfunc\r
-\r
-.func KiUserCallbackExceptionHandler\r
-_KiUserCallbackExceptionHandler:\r
-\r
- /* Put the exception record in ECX and check the Flags */\r
- mov ecx, [esp+4]\r
- test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING\r
- jz return\r
-\r
- /* Tell the kernel to invalidate the stack */\r
- push STATUS_CALLBACK_POP_STACK\r
- push 0\r
- push 0\r
- call _ZwCallbackReturn@12\r
-\r
-return:\r
- /* We'll execute the handler */\r
- mov eax, EXCEPTION_EXECUTE_HANDLER\r
- ret 16\r
-.endfunc\r
-\r
-.func KiUserCallbackDispatcher@12\r
-.globl _KiUserCallbackDispatcher@12\r
-_KiUserCallbackDispatcher@12:\r
-\r
- /* Setup SEH stack */\r
- mov ecx, fs:[TEB_EXCEPTION_LIST]\r
- mov edx, offset _KiUserCallbackExceptionHandler\r
- lea eax, [esp+16]\r
- mov [esp+16], ecx\r
- mov [esp+20], edx\r
-\r
- /* Enable SEH */\r
- mov fs:[TEB_EXCEPTION_LIST], eax\r
-\r
- /* Get the callback Index */\r
- add esp, 4\r
- pop edx\r
-\r
- /* Get the callback table */\r
- mov eax, [fs:TEB_PEB]\r
- mov eax, [eax+PEB_KERNEL_CALLBACK_TABLE]\r
-\r
- /* Call the routine */\r
- call [eax+edx*4]\r
-\r
- /* Return from callback */\r
- push eax\r
- push 0\r
- push 0\r
- call _ZwCallbackReturn@12\r
-\r
- /* Save callback return value */\r
- mov esi, eax\r
-\r
- /* Raise status */\r
-StatusRaise:\r
- push esi\r
- call _RtlRaiseStatus@4\r
- jmp StatusRaise\r
- ret 12\r
-.endfunc\r
-\r
-.func KiRaiseUserExceptionDispatcher@0\r
-.globl _KiRaiseUserExceptionDispatcher@0\r
-_KiRaiseUserExceptionDispatcher@0:\r
-\r
- /* Setup stack for EXCEPTION_RECORD */\r
- push ebp\r
- mov ebp, esp\r
- sub esp, EXCEPTION_RECORD_LENGTH\r
-\r
- /* Fill out the record */\r
- mov [esp+EXCEPTION_RECORD_EXCEPTION_ADDRESS], eax\r
- mov eax, [fs:KPCR_TEB]\r
- mov eax, [eax+TEB_EXCEPTION_CODE]\r
- mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax\r
- mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], 0\r
- mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], 0\r
- mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0\r
-\r
- /* Raise the exception */\r
- push esp\r
- call _RtlRaiseException@4\r
-\r
- /* Return exception code */\r
- mov eax, [esp+EXCEPTION_RECORD_EXCEPTION_CODE]\r
- mov esp, ebp\r
- pop ebp\r
- ret\r
-.endfunc\r
-\r
-.func KiUserExceptionDispatcher@8\r
-.globl _KiUserExceptionDispatcher@8\r
-_KiUserExceptionDispatcher@8:\r
-\r
- /* Clear direction flag */\r
- cld\r
-\r
- /* Save the Context and Exception Records */\r
- mov ecx, [esp+4]\r
- mov ebx, [esp]\r
-\r
- /* Dispatch the exception */\r
- push ecx\r
- push ebx\r
- call _RtlDispatchException@8\r
-\r
- /* Check for success */\r
- or al, al\r
- jz RaiseException\r
-\r
- /* Pop off the records */\r
- pop ebx\r
- pop ecx\r
-\r
- /* We're fine, continue execution */\r
- push 0\r
- push ecx\r
- call _ZwContinue@8\r
-\r
- /* Exit */\r
- jmp Exit\r
-\r
-RaiseException:\r
- /* Pop off the records */\r
- pop ebx\r
- pop ecx\r
-\r
- /* Raise the exception */\r
- push 0\r
- push ecx\r
- push ebx\r
- call _ZwRaiseException@12\r
-\r
-Exit:\r
- /* Allocate space for the nested exception record */\r
- add esp, -SIZEOF_EXCEPTION_RECORD\r
-\r
- /* Set it up */\r
- mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax\r
- mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_NONCONTINUABLE\r
- mov [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], ebx\r
- mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0\r
-\r
- /* Raise the exception */\r
- push esp\r
- call _RtlRaiseException@4\r
- ret 8\r
-.endfunc\r
-\r
-.func KiIntSystemCall@0\r
-.globl _KiIntSystemCall@0\r
-_KiIntSystemCall@0:\r
-\r
- /* Set stack in EDX and do the interrupt */\r
- lea edx, [esp+8]\r
- int 0x2E\r
-\r
- /* Return to caller */\r
- ret\r
-.endfunc\r
-\r
-.func KiFastSystemCall@0\r
-.globl _KiFastSystemCall@0\r
-_KiFastSystemCall@0:\r
-\r
- /* Put ESP in EDX and do the SYSENTER */\r
- mov edx, esp\r
- sysenter\r
-.endfunc\r
-\r
-.func KiFastSystemCallRet@0\r
-.globl _KiFastSystemCallRet@0\r
-_KiFastSystemCallRet@0:\r
-\r
- /* Just return to caller */\r
- ret\r
-.endfunc\r
-\r
-.func RtlpGetStackLimits@8\r
-.globl _RtlpGetStackLimits@8\r
-_RtlpGetStackLimits@8:\r
-\r
- /* Get the stack limits */\r
- mov eax, [fs:TEB_STACK_LIMIT]\r
- mov ecx, [fs:TEB_STACK_BASE]\r
-\r
- /* Return them */\r
- mov edx, [esp+4]\r
- mov [edx], eax\r
- mov edx, [esp+8]\r
- mov [edx], ecx\r
-\r
- /* return */\r
- ret 8\r
-.endfunc\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS NT Library
+ * FILE: dl/ntdll/dispatch/i386/dispatch.S
+ * PURPOSE: User-Mode NT Dispatchers
+ * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ndk/asm.h>
+.intel_syntax noprefix
+
+/* FUNCTIONS ****************************************************************/
+
+.func LdrInitializeThunk@16
+.globl _LdrInitializeThunk@16
+_LdrInitializeThunk@16:
+
+ /* Get the APC Context */
+ lea eax, [esp+16]
+
+ /* Send it as the first parameter */
+ mov [esp+4], eax
+
+ /* Terminate the frame list */
+ xor ebp, ebp
+
+ /* Jump into the C initialization routine */
+ jmp _LdrpInit@12
+.endfunc
+
+.func KiUserApcExceptionHandler
+_KiUserApcExceptionHandler:
+
+ /* Put the exception record in ECX and check the Flags */
+ mov ecx, [esp+4]
+ test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
+ jz .return
+
+ /* Test alert the thread */
+ call _NtTestAlert@0
+
+.return:
+ /* We'll execute handler */
+ mov eax, EXCEPTION_EXECUTE_HANDLER
+ ret 16
+.endfunc
+
+.func KiUserApcDispatcher@16
+.globl _KiUserApcDispatcher@16
+_KiUserApcDispatcher@16:
+
+ /* Setup SEH stack */
+ lea eax, [esp+CONTEXT_ALIGNED_SIZE+16]
+ mov ecx, fs:[TEB_EXCEPTION_LIST]
+ mov edx, offset _KiUserApcExceptionHandler
+ mov [eax], ecx
+ mov [eax+4], edx
+
+ /* Enable SEH */
+ mov fs:[TEB_EXCEPTION_LIST], eax
+
+ /* Put the Context in EDI */
+ pop eax
+ lea edi, [esp+12]
+
+ /* Call the APC Routine */
+ call eax
+
+ /* Restore exception list */
+ mov ecx, [edi+CONTEXT_ALIGNED_SIZE]
+ mov fs:[TEB_EXCEPTION_LIST], ecx
+
+ /* Switch back to the context */
+ push 1
+ push edi
+ call _ZwContinue@8
+
+ /* Save callback return value */
+ mov esi, eax
+
+ /* Raise status */
+StatusRaiseApc:
+ push esi
+ call _RtlRaiseStatus@4
+ jmp StatusRaiseApc
+ ret 16
+.endfunc
+
+.func KiUserCallbackExceptionHandler
+_KiUserCallbackExceptionHandler:
+
+ /* Put the exception record in ECX and check the Flags */
+ mov ecx, [esp+4]
+ test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
+ jz return
+
+ /* Tell the kernel to invalidate the stack */
+ push STATUS_CALLBACK_POP_STACK
+ push 0
+ push 0
+ call _ZwCallbackReturn@12
+
+return:
+ /* We'll execute the handler */
+ mov eax, EXCEPTION_EXECUTE_HANDLER
+ ret 16
+.endfunc
+
+.func KiUserCallbackDispatcher@12
+.globl _KiUserCallbackDispatcher@12
+_KiUserCallbackDispatcher@12:
+
+ /* Setup SEH stack */
+ mov ecx, fs:[TEB_EXCEPTION_LIST]
+ mov edx, offset _KiUserCallbackExceptionHandler
+ lea eax, [esp+16]
+ mov [esp+16], ecx
+ mov [esp+20], edx
+
+ /* Enable SEH */
+ mov fs:[TEB_EXCEPTION_LIST], eax
+
+ /* Get the callback Index */
+ add esp, 4
+ pop edx
+
+ /* Get the callback table */
+ mov eax, [fs:TEB_PEB]
+ mov eax, [eax+PEB_KERNEL_CALLBACK_TABLE]
+
+ /* Call the routine */
+ call [eax+edx*4]
+
+ /* Return from callback */
+ push eax
+ push 0
+ push 0
+ call _ZwCallbackReturn@12
+
+ /* Save callback return value */
+ mov esi, eax
+
+ /* Raise status */
+StatusRaise:
+ push esi
+ call _RtlRaiseStatus@4
+ jmp StatusRaise
+ ret 12
+.endfunc
+
+.func KiRaiseUserExceptionDispatcher@0
+.globl _KiRaiseUserExceptionDispatcher@0
+_KiRaiseUserExceptionDispatcher@0:
+
+ /* Setup stack for EXCEPTION_RECORD */
+ push ebp
+ mov ebp, esp
+ sub esp, EXCEPTION_RECORD_LENGTH
+
+ /* Fill out the record */
+ mov [esp+EXCEPTION_RECORD_EXCEPTION_ADDRESS], eax
+ mov eax, [fs:KPCR_TEB]
+ mov eax, [eax+TEB_EXCEPTION_CODE]
+ mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
+ mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], 0
+ mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], 0
+ mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
+
+ /* Raise the exception */
+ push esp
+ call _RtlRaiseException@4
+
+ /* Return exception code */
+ mov eax, [esp+EXCEPTION_RECORD_EXCEPTION_CODE]
+ mov esp, ebp
+ pop ebp
+ ret
+.endfunc
+
+.func KiUserExceptionDispatcher@8
+.globl _KiUserExceptionDispatcher@8
+_KiUserExceptionDispatcher@8:
+
+ /* Clear direction flag */
+ cld
+
+ /* Save the Context and Exception Records */
+ mov ecx, [esp+4]
+ mov ebx, [esp]
+
+ /* Dispatch the exception */
+ push ecx
+ push ebx
+ call _RtlDispatchException@8
+
+ /* Check for success */
+ or al, al
+ jz RaiseException
+
+ /* Pop off the records */
+ pop ebx
+ pop ecx
+
+ /* We're fine, continue execution */
+ push 0
+ push ecx
+ call _ZwContinue@8
+
+ /* Exit */
+ jmp Exit
+
+RaiseException:
+ /* Pop off the records */
+ pop ebx
+ pop ecx
+
+ /* Raise the exception */
+ push 0
+ push ecx
+ push ebx
+ call _ZwRaiseException@12
+
+Exit:
+ /* Allocate space for the nested exception record */
+ add esp, -SIZEOF_EXCEPTION_RECORD
+
+ /* Set it up */
+ mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
+ mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_NONCONTINUABLE
+ mov [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], ebx
+ mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
+
+ /* Raise the exception */
+ push esp
+ call _RtlRaiseException@4
+ ret 8
+.endfunc
+
+.func KiIntSystemCall@0
+.globl _KiIntSystemCall@0
+_KiIntSystemCall@0:
+
+ /* Set stack in EDX and do the interrupt */
+ lea edx, [esp+8]
+ int 0x2E
+
+ /* Return to caller */
+ ret
+.endfunc
+
+.func KiFastSystemCall@0
+.globl _KiFastSystemCall@0
+_KiFastSystemCall@0:
+
+ /* Put ESP in EDX and do the SYSENTER */
+ mov edx, esp
+ sysenter
+.endfunc
+
+.func KiFastSystemCallRet@0
+.globl _KiFastSystemCallRet@0
+_KiFastSystemCallRet@0:
+
+ /* Just return to caller */
+ ret
+.endfunc
+
+.func RtlpGetStackLimits@8
+.globl _RtlpGetStackLimits@8
+_RtlpGetStackLimits@8:
+
+ /* Get the stack limits */
+ mov eax, [fs:TEB_STACK_LIMIT]
+ mov ecx, [fs:TEB_STACK_BASE]
+
+ /* Return them */
+ mov edx, [esp+4]
+ mov [edx], eax
+ mov edx, [esp+8]
+ mov [edx], ecx
+
+ /* return */
+ ret 8
+.endfunc