diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index ce788e22084..880383a945c 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -932,6 +932,16 @@ KiEndUnexpectedRange( VOID ); +NTSTATUS +NTAPI +KiRaiseException( + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PKTRAP_FRAME TrapFrame, + IN BOOLEAN SearchFrames +); + NTSTATUS NTAPI KiContinue( diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 43d59084ccd..9103fefe593 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -476,49 +476,11 @@ GENERATE_TRAP_HANDLER KiDebugService, 1 .func NtRaiseException@12 _NtRaiseException@12: - - /* NOTE: We -must- be called by Zw* to have the right frame! */ - /* Push the stack frame */ - push ebp - - /* Get the current thread and restore its trap frame */ - mov ebx, PCR[KPCR_CURRENT_THREAD] - mov edx, [ebp+KTRAP_FRAME_EDX] - mov [ebx+KTHREAD_TRAP_FRAME], edx - - /* Set up stack frame */ - mov ebp, esp - - /* Get the Trap Frame in EBX */ - mov ebx, [ebp+0] - - /* Get the exception list and restore */ - mov eax, [ebx+KTRAP_FRAME_EXCEPTION_LIST] - mov PCR[KPCR_EXCEPTION_LIST], eax - - /* Get the parameters */ - mov edx, [ebp+16] /* Search frames */ - mov ecx, [ebp+12] /* Context */ - mov eax, [ebp+8] /* Exception Record */ - - /* Raise the exception */ - push edx - push ebx - push 0 - push ecx - push eax - call _KiRaiseException@20 - - /* Restore trap frame in EBP */ - pop ebp - mov esp, ebp - - /* Check the result */ - or eax, eax - jz _KiServiceExit2 - - /* Restore debug registers too */ - jmp _KiServiceExit + /* Call C code */ + mov ecx, [esp+4] + mov edx, [esp+8] + or edx, [esp+12] + jmp @NtRaiseExceptionHandler@8 .endfunc .func NtContinue@8 diff --git a/reactos/ntoskrnl/ke/i386/traphdlr.c b/reactos/ntoskrnl/ke/i386/traphdlr.c index edba2507b2f..74670c02ce3 100644 --- a/reactos/ntoskrnl/ke/i386/traphdlr.c +++ b/reactos/ntoskrnl/ke/i386/traphdlr.c @@ -1691,6 +1691,46 @@ KiDebugServiceHandler(IN PKTRAP_FRAME TrapFrame) KiDebugHandler(TrapFrame, TrapFrame->Eax, TrapFrame->Ecx, TrapFrame->Edx); } +VOID +FASTCALL +NtRaiseExceptionHandler(IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context) +{ + BOOLEAN FirstChance; + NTSTATUS Status; + PKTHREAD Thread; + PKTRAP_FRAME TrapFrame; + + /* Fixup parameters */ + FirstChance = (ULONG_PTR)Context & 1; + Context = (PVOID)((ULONG_PTR)Context & ~1); + + /* Get trap frame and link previous one*/ + Thread = KeGetCurrentThread(); + TrapFrame = Thread->TrapFrame; + Thread->TrapFrame = (PKTRAP_FRAME)TrapFrame->Edx; + + /* Set exception list */ + KeGetPcr()->Tib.ExceptionList = TrapFrame->ExceptionList; + + /* Raise the exception */ + Status = KiRaiseException(ExceptionRecord, + Context, + NULL, + TrapFrame, + FirstChance); + if (NT_SUCCESS(Status)) + { + /* It was handled, so exit restoring all state */ + KiServiceExit2(TrapFrame); + } + else + { + /* Exit with error */ + KiServiceExit(TrapFrame, Status); + } +} + VOID FASTCALL NtContinueHandler(IN PCONTEXT Context,