diff --git a/reactos/Makefile b/reactos/Makefile index 547e13a4db3..da718be5d00 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.231 2004/06/15 22:33:45 gvg Exp $ +# $Id: Makefile,v 1.232 2004/07/01 02:40:21 hyperion Exp $ # # Global makefile # @@ -32,7 +32,7 @@ BUS = acpi isapnp pci LIB_FSLIB = vfatlib # Static libraries -LIB_STATIC = string rosrtl epsapi uuid libwine zlib rtl tgetopt +LIB_STATIC = string rosrtl epsapi uuid libwine zlib rtl tgetopt pseh # Keyboard layout libraries DLLS_KBD = kbddv kbdfr kbdgr kbdse kbduk kbdus diff --git a/reactos/drivers/dd/null/makefile b/reactos/drivers/dd/null/makefile index 7adb9916919..ea0518641d8 100644 --- a/reactos/drivers/dd/null/makefile +++ b/reactos/drivers/dd/null/makefile @@ -1,17 +1,17 @@ -# $Id: makefile,v 1.18 2003/11/17 20:48:22 sedwards Exp $ +# $Id: makefile,v 1.19 2004/07/01 02:40:22 hyperion Exp $ PATH_TO_TOP = ../../.. +include $(PATH_TO_TOP)/rules.mak + TARGET_TYPE = driver TARGET_NAME = null TARGET_OBJECTS = null.o -TARGET_CFLAGS = -Wall -Werror +TARGET_CFLAGS = -Wall -Werror -D__USE_W32API -#TARGET_LFLAGS = -Wl,--file-alignment,0x20 -Wl,--section-alignment,0x20 - -include $(PATH_TO_TOP)/rules.mak +TARGET_LIBS = $(SDK_PATH_LIB)/pseh.a include $(TOOLS_PATH)/helper.mk diff --git a/reactos/drivers/dd/null/null.c b/reactos/drivers/dd/null/null.c index d5575508882..b7030a8cf49 100644 --- a/reactos/drivers/dd/null/null.c +++ b/reactos/drivers/dd/null/null.c @@ -1,4 +1,4 @@ -/* $Id: null.c,v 1.13 2004/02/10 16:22:55 navaraf Exp $ +/* $Id: null.c,v 1.14 2004/07/01 02:40:22 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -8,11 +8,15 @@ * UPDATE HISTORY: * 13/08/1998: Created * 29/04/2002: Fixed bugs, added zero-stream device + * 28/06/2004: Compile against the DDK, use PSEH where necessary */ /* INCLUDES */ -#include +#include + #include +#include + #include "null.h" /* OBJECTS */ @@ -27,15 +31,24 @@ NullDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) NTSTATUS nErrCode; nErrCode = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; switch(piosStack->MajorFunction) { /* opening and closing handles to the device */ case IRP_MJ_CREATE: case IRP_MJ_CLOSE: - { + switch(NULL_DEVICE_TYPE(DeviceObject)) + { + case NullBitBucket: + case NullZeroStream: + break; + + default: + ASSERT(FALSE); + } + break; - } /* write data */ case IRP_MJ_WRITE: @@ -47,9 +60,11 @@ NullDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) break; case NullZeroStream: + nErrCode = STATUS_INVALID_DEVICE_REQUEST; + break; + default: - Irp->IoStatus.Information = 0; - nErrCode = STATUS_NOT_IMPLEMENTED; + ASSERT(FALSE); } break; @@ -61,13 +76,21 @@ NullDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) switch(NULL_DEVICE_TYPE(DeviceObject)) { case NullBitBucket: - Irp->IoStatus.Information = 0; nErrCode = STATUS_END_OF_FILE; break; case NullZeroStream: - RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, piosStack->Parameters.Read.Length); - Irp->IoStatus.Information = piosStack->Parameters.Read.Length; + _SEH_TRY + { + RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, piosStack->Parameters.Read.Length); + Irp->IoStatus.Information = piosStack->Parameters.Read.Length; + } + _SEH_HANDLE + { + nErrCode = _SEH_GetExceptionCode(); + } + _SEH_END; + break; default: @@ -78,11 +101,8 @@ NullDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) break; } - /* unsupported operations */ default: - { - nErrCode = STATUS_NOT_IMPLEMENTED; - } + ASSERT(FALSE); } Irp->IoStatus.Status = nErrCode; @@ -96,6 +116,7 @@ NullUnload(PDRIVER_OBJECT DriverObject) { } +/* TODO: \Device\Zero should be memory-mappable */ NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { @@ -109,7 +130,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) DriverObject->MajorFunction[IRP_MJ_CREATE] = NullDispatch; DriverObject->MajorFunction[IRP_MJ_WRITE] = NullDispatch; DriverObject->MajorFunction[IRP_MJ_READ] = NullDispatch; - /* DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = NullDispatch; */ DriverObject->DriverUnload = NullUnload; /* create null device */ diff --git a/reactos/lib/ntdll/makefile b/reactos/lib/ntdll/makefile index 99fb8212ff6..15fe23320bb 100644 --- a/reactos/lib/ntdll/makefile +++ b/reactos/lib/ntdll/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.103 2004/06/20 23:22:06 gdalsnes Exp $ +# $Id: makefile,v 1.104 2004/07/01 02:40:22 hyperion Exp $ PATH_TO_TOP = ../.. @@ -57,8 +57,6 @@ RTL_I386_OBJECTS = \ rtl/i386/aullrem.o \ rtl/i386/aullshr.o \ rtl/i386/chkstk.o \ - rtl/i386/exception.o \ - rtl/i386/except.o \ rtl/i386/float.o \ rtl/i386/ftol.o diff --git a/reactos/lib/ntdll/rtl/exception.c b/reactos/lib/ntdll/rtl/exception.c index 43285853751..79e5a9c610b 100644 --- a/reactos/lib/ntdll/rtl/exception.c +++ b/reactos/lib/ntdll/rtl/exception.c @@ -1,4 +1,4 @@ -/* $Id: exception.c,v 1.17 2004/04/08 21:14:18 navaraf Exp $ +/* $Id: exception.c,v 1.18 2004/07/01 02:40:22 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -6,8 +6,10 @@ * FILE: lib/ntdll/rtl/exception.c * PROGRAMERS: David Welch * Skywing + * KJK::Hyperion * UPDATES: Skywing, 09/11/2003: Implemented RtlRaiseException and * KiUserRaiseExceptionDispatcher. + * KJK::Hyperion, 22/06/2003: Moved common parts to rtl */ /* INCLUDES *****************************************************************/ @@ -57,28 +59,6 @@ KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord, RtlRaiseException(&NestedExceptionRecord); } -/* implemented in except.s */ -VOID -RtlpCaptureContext(PCONTEXT Context); - -/* - * @implemented - */ -VOID STDCALL -RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord) -{ - CONTEXT Context; - NTSTATUS Status; - - RtlpCaptureContext(&Context); - - ExceptionRecord->ExceptionAddress = (PVOID)(*(((PULONG)Context.Ebp)+1)); - Context.ContextFlags = CONTEXT_FULL; - - Status = ZwRaiseException(ExceptionRecord, &Context, TRUE); - RtlRaiseException(ExceptionRecord); - RtlRaiseStatus(Status); /* If we get to this point, something is seriously wrong... */ -} /* * @implemented diff --git a/reactos/lib/pseh/framebased.c b/reactos/lib/pseh/framebased.c index e858b21680a..8bcbbfd4e50 100644 --- a/reactos/lib/pseh/framebased.c +++ b/reactos/lib/pseh/framebased.c @@ -68,47 +68,50 @@ int __cdecl _SEHFrameHandler /* Handling */ else { + int ret; + if(ExceptionRecord->ExceptionCode) frame->SPF_Code = ExceptionRecord->ExceptionCode; else frame->SPF_Code = 0xC0000001; - if(frame->SPF_Handlers->SH_Filter) + switch((UINT_PTR)frame->SPF_Handlers->SH_Filter) { - int ret; - - switch((UINT_PTR)frame->SPF_Handlers->SH_Filter) + case _SEH_EXECUTE_HANDLER + 1: + case _SEH_CONTINUE_SEARCH + 1: + case _SEH_CONTINUE_EXECUTION + 1: { - case _SEH_EXECUTE_HANDLER + 1: - case _SEH_CONTINUE_SEARCH + 1: - case _SEH_CONTINUE_EXECUTION + 1: - { - ret = (int)((UINT_PTR)frame->SPF_Handlers->SH_Filter) - 1; - break; - } - - default: - { - EXCEPTION_POINTERS ep; - - ep.ExceptionRecord = ExceptionRecord; - ep.ContextRecord = ContextRecord; - - ret = frame->SPF_Handlers->SH_Filter(&ep, frame); - break; - } + ret = (int)((UINT_PTR)frame->SPF_Handlers->SH_Filter) - 1; + break; } - /* _SEH_CONTINUE_EXECUTION */ - if(ret < 0) - return ExceptionContinueExecution; - /* _SEH_EXECUTE_HANDLER */ - else if(ret > 0) - _SEHCallHandler(frame); - /* _SEH_CONTINUE_SEARCH */ - else - /* fall through */; + default: + { + if(frame->SPF_Handlers->SH_Filter) + { + EXCEPTION_POINTERS ep; + + ep.ExceptionRecord = ExceptionRecord; + ep.ContextRecord = ContextRecord; + + ret = frame->SPF_Handlers->SH_Filter(&ep, frame); + } + else + ret = _SEH_CONTINUE_SEARCH; + + break; + } } + + /* _SEH_CONTINUE_EXECUTION */ + if(ret < 0) + return ExceptionContinueExecution; + /* _SEH_EXECUTE_HANDLER */ + else if(ret > 0) + _SEHCallHandler(frame); + /* _SEH_CONTINUE_SEARCH */ + else + /* fall through */; } return ExceptionContinueSearch; diff --git a/reactos/lib/pseh/i386/framebased.asm b/reactos/lib/pseh/i386/framebased.asm index d4d56b20fa9..50adede06e3 100644 --- a/reactos/lib/pseh/i386/framebased.asm +++ b/reactos/lib/pseh/i386/framebased.asm @@ -54,10 +54,10 @@ __SEHUnwind: push ebx xor eax, eax - push eax - push eax - push eax - push ecx + push eax ; ReturnValue + push eax ; ExceptionRecord + push eax ; TargetIp + push ecx ; TargetFrame call [__SEHRtlUnwind] pop ebx diff --git a/reactos/lib/rtl/i386/.cvsignore b/reactos/lib/rtl/i386/.cvsignore new file mode 100644 index 00000000000..31dc3078b3a --- /dev/null +++ b/reactos/lib/rtl/i386/.cvsignore @@ -0,0 +1,2 @@ +*.d +*.o diff --git a/reactos/lib/rtl/makefile b/reactos/lib/rtl/makefile index e11603524f2..195bf17702c 100644 --- a/reactos/lib/rtl/makefile +++ b/reactos/lib/rtl/makefile @@ -33,7 +33,10 @@ TARGET_OBJECTS = \ version.o \ encode.o \ image.o \ - splaytree.o + splaytree.o \ + exception.o \ + i386/exception.o \ + i386/except.o # atom # registry diff --git a/reactos/ntoskrnl/Makefile.i386 b/reactos/ntoskrnl/Makefile.i386 index 3f86fc56066..0d8870edf2f 100644 --- a/reactos/ntoskrnl/Makefile.i386 +++ b/reactos/ntoskrnl/Makefile.i386 @@ -48,7 +48,6 @@ OBJECTS_RTL_I386 := \ rtl/i386/aulldiv.o \ rtl/i386/aullrem.o \ rtl/i386/aullshr.o \ - rtl/i386/except.o \ rtl/i386/exception.o \ rtl/i386/seh.o diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index c465bdad5c4..6a0e2bf6d34 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: trap.s,v 1.19 2004/03/13 18:21:57 dwelch Exp $ +/* $Id: trap.s,v 1.20 2004/07/01 02:40:23 hyperion Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/i386/trap.s @@ -99,9 +99,6 @@ _KiTrapProlog: movl %fs:KPCR_EXCEPTION_LIST, %ebx pushl %ebx - /* Put the exception handler chain terminator */ - movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST - /* Get a pointer to the current thread */ movl %fs:KPCR_CURRENT_THREAD, %edi diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 8ed65131e83..a8e33d9b6e8 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.124 2004/01/05 14:28:21 weiden Exp $ +/* $Id: thread.c,v 1.125 2004/07/01 02:40:23 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -739,6 +739,10 @@ NtContinue(IN PCONTEXT Context, KEBUGCHECK(0); } KeContextToTrapFrame(Context, TrapFrame); + + if(TestAlert) + KiTestAlert(); + return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/rtl/i386/exception.c b/reactos/ntoskrnl/rtl/i386/exception.c index 7e2306aed32..fc3b2bb4c25 100755 --- a/reactos/ntoskrnl/rtl/i386/exception.c +++ b/reactos/ntoskrnl/rtl/i386/exception.c @@ -1,4 +1,4 @@ -/* $Id: exception.c,v 1.10 2004/02/24 23:51:04 dwelch Exp $ +/* $Id: exception.c,v 1.11 2004/07/01 02:40:23 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -73,444 +73,4 @@ __ret_label: #endif /* _MSC_VER */ - -/* Implemented in except.s */ - -VOID -RtlpCaptureContext(PCONTEXT pContext); - -/* Macros that will help streamline the SEH implementations for - kernel mode and user mode */ - -#define SehpGetStackLimits(StackBase, StackLimit) \ -{ \ - (*(StackBase)) = KeGetCurrentKPCR()->StackBase; \ - (*(StackLimit)) = KeGetCurrentKPCR()->StackLimit; \ -} - -#define SehpGetExceptionList() \ - (PEXCEPTION_REGISTRATION)(KeGetCurrentThread()->TrapFrame ->ExceptionList) - -#define SehpSetExceptionList(NewExceptionList) \ - KeGetCurrentThread()->TrapFrame->ExceptionList = (PVOID)(NewExceptionList) - -#define SehpCaptureContext(Context) \ -{ \ - KeTrapFrameToContext(KeGetCurrentThread()->TrapFrame, (Context)); \ -} - -#define SehpContinue(Context, TestAlert) \ - ZwContinue(Context, TestAlert) - -/*** Code below this line is shared with lib/ntdll/rtl/i386/exception.c - please keep in sync ***/ - -VOID STDCALL -AsmDebug(ULONG Value) -{ - DbgPrint("Value 0x%.08x\n", Value); -} - - -/* Declare a few prototypes for the functions in except.s */ - -EXCEPTION_DISPOSITION -RtlpExecuteHandlerForException( - PEXCEPTION_RECORD ExceptionRecord, - PEXCEPTION_REGISTRATION RegistrationFrame, - PCONTEXT Context, - PVOID DispatcherContext, - PEXCEPTION_HANDLER ExceptionHandler); - -EXCEPTION_DISPOSITION -RtlpExecuteHandlerForUnwind( - PEXCEPTION_RECORD ExceptionRecord, - PEXCEPTION_REGISTRATION RegistrationFrame, - PCONTEXT Context, - PVOID DispatcherContext, - PEXCEPTION_HANDLER ExceptionHandler); - - -#ifndef NDEBUG - -VOID RtlpDumpExceptionRegistrations(VOID) -{ - PEXCEPTION_REGISTRATION Current; - - DbgPrint("Dumping exception registrations:\n"); - - Current = SehpGetExceptionList(); - - if ((ULONG_PTR)Current != -1) - { - while ((ULONG_PTR)Current != -1) - { - DbgPrint(" (0x%08X) HANDLER (0x%08X)\n", Current, Current->handler); - Current = Current->prev; - } - DbgPrint(" End-Of-List\n"); - } else { - DbgPrint(" No exception registrations exists.\n"); - } -} - -#endif /* NDEBUG */ - -ULONG -RtlpDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, - IN PCONTEXT Context) -{ - PEXCEPTION_REGISTRATION RegistrationFrame; - DWORD DispatcherContext; - DWORD ReturnValue; - - DPRINT("RtlpDispatchException()\n"); - - /* - This could be true very early in the boot process - in which case there is no point in continuing. - */ - if (KeGetCurrentThread() == NULL) - { - return ExceptionContinueExecution; - } - -#ifndef NDEBUG - RtlpDumpExceptionRegistrations(); -#endif /* NDEBUG */ - - RegistrationFrame = SehpGetExceptionList(); - - DPRINT("RegistrationFrame is 0x%X\n", RegistrationFrame); - - /* Check if there are any exception handlers at all. */ - if ((ULONG_PTR)RegistrationFrame == (ULONG_PTR)-1) - { - ExceptionRecord->ExceptionFlags |= EXCEPTION_NONCONTINUABLE; - return ExceptionContinueExecution; - } - - while ((ULONG_PTR)RegistrationFrame != (ULONG_PTR)-1) - { - EXCEPTION_RECORD ExceptionRecord2; - DWORD Temp = 0; - //PVOID RegistrationFrameEnd = (PVOID)RegistrationFrame + 8; - - // Make sure the registration frame is located within the stack - - DPRINT("Error checking\n"); -#if 0 - if (Teb->Tib.StackBase > RegistrationFrameEnd) - { - DPRINT("Teb->Tib.StackBase (0x%.08x) > RegistrationFrameEnd (0x%.08x)\n", - Teb->Tib.StackBase, RegistrationFrameEnd); - ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID; - return ExceptionContinueExecution; - } - // FIXME: Stack top, correct? - if (Teb->Tib.StackLimit < RegistrationFrameEnd) - { - DPRINT("Teb->Tib.StackLimit (0x%.08x) > RegistrationFrameEnd (0x%.08x)\n", - Teb->Tib.StackLimit, RegistrationFrameEnd); - ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID; - return ExceptionContinueExecution; - } - - // Make sure stack is DWORD aligned - if ((ULONG_PTR)RegistrationFrame & 3) - { - DPRINT("RegistrationFrameEnd (0x%.08x) is not DWORD aligned.\n", - RegistrationFrameEnd); - ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID; - return ExceptionContinueExecution; - } -#endif - -#if 0 - /* FIXME: */ - if (someFlag) - RtlpLogLastExceptionDisposition( hLog, retValue ); -#endif - - DPRINT("Calling handler at 0x%X\n", RegistrationFrame->handler); - DPRINT("ExceptionRecord 0x%X\n", ExceptionRecord); - DPRINT("RegistrationFrame 0x%X\n", RegistrationFrame); - DPRINT("Context 0x%X\n", Context); - DPRINT("&DispatcherContext 0x%X\n", &DispatcherContext); - - ReturnValue = RtlpExecuteHandlerForException( - ExceptionRecord, - RegistrationFrame, - Context, - &DispatcherContext, - RegistrationFrame->handler); - -#ifndef NDEBUG - - DPRINT("Exception handler said 0x%X\n", ReturnValue); - DPRINT("RegistrationFrame == 0x%.08x\n", RegistrationFrame); - { - PULONG sp = (PULONG)((PVOID)RegistrationFrame - 0x08); - DPRINT("StandardESP == 0x%.08x\n", sp[0]); - DPRINT("Exception Pointers == 0x%.08x\n", sp[1]); - DPRINT("PrevFrame == 0x%.08x\n", sp[2]); - DPRINT("Handler == 0x%.08x\n", sp[3]); - DPRINT("ScopeTable == 0x%.08x\n", sp[4]); - DPRINT("TryLevel == 0x%.08x\n", sp[5]); - DPRINT("EBP == 0x%.08x\n", sp[6]); - } - -#endif - - if (RegistrationFrame == NULL) - { - ExceptionRecord->ExceptionFlags &= ~EXCEPTION_NESTED_CALL; // Turn off flag - } - - if (ReturnValue == ExceptionContinueExecution) - { - DPRINT("ReturnValue == ExceptionContinueExecution\n"); - if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) - { - DPRINT("(ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) == TRUE\n"); - - ExceptionRecord2.ExceptionRecord = ExceptionRecord; - ExceptionRecord2.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; - ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE; - ExceptionRecord2.NumberParameters = 0; - RtlRaiseException(&ExceptionRecord2); - } - else - { - /* Copy the (possibly changed) context back to the trap frame and return */ - SehpContinue(Context, FALSE); - return ExceptionContinueExecution; - } - } - else if (ReturnValue == ExceptionContinueSearch) - { - DPRINT("ReturnValue == ExceptionContinueSearch\n"); - - /* Nothing to do here */ - } - else if (ReturnValue == ExceptionNestedException) - { - DPRINT("ReturnValue == ExceptionNestedException\n"); - - ExceptionRecord->ExceptionFlags |= EXCEPTION_EXIT_UNWIND; - if (DispatcherContext > Temp) - { - Temp = DispatcherContext; - } - } - else /* if (ReturnValue == ExceptionCollidedUnwind) */ - { - DPRINT("ReturnValue == ExceptionCollidedUnwind or unknown\n"); - - ExceptionRecord2.ExceptionRecord = ExceptionRecord; - ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION; - ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE; - ExceptionRecord2.NumberParameters = 0; - RtlRaiseException(&ExceptionRecord2); - } - - RegistrationFrame = RegistrationFrame->prev; // Go to previous frame - } - - /* No exception handler will handle this exception */ - - DPRINT("RtlpDispatchException(): Return ExceptionContinueExecution\n"); - - return ExceptionContinueExecution; -} - -VOID STDCALL -RtlRaiseStatus(NTSTATUS Status) -{ - EXCEPTION_RECORD ExceptionRecord; - - DPRINT("RtlRaiseStatus(Status 0x%.08x)\n", Status); - - ExceptionRecord.ExceptionCode = Status; - ExceptionRecord.ExceptionRecord = NULL; - ExceptionRecord.NumberParameters = 0; - ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; - RtlRaiseException (& ExceptionRecord); -} - -/* - * @implemented - */ -VOID STDCALL -RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame, - PVOID ReturnAddress, - PEXCEPTION_RECORD ExceptionRecord, - DWORD EaxValue) -{ - PEXCEPTION_REGISTRATION ERHead; - PEXCEPTION_RECORD pExceptRec; - EXCEPTION_RECORD TempER; - CONTEXT Context; - - DPRINT("RtlUnwind(). RegistrationFrame 0x%X\n", RegistrationFrame); - -#ifndef NDEBUG - RtlpDumpExceptionRegistrations(); -#endif /* NDEBUG */ - - ERHead = SehpGetExceptionList(); - - DPRINT("ERHead is 0x%X\n", ERHead); - - pExceptRec = &TempER; - - if (ExceptionRecord == NULL) // The normal case - { - DPRINT("ExceptionRecord == NULL (normal)\n"); - - pExceptRec->ExceptionFlags = 0; - pExceptRec->ExceptionCode = STATUS_UNWIND; - pExceptRec->ExceptionRecord = NULL; - pExceptRec->ExceptionAddress = ReturnAddress; - pExceptRec->ExceptionInformation[0] = 0; - } - - if (RegistrationFrame) - pExceptRec->ExceptionFlags |= EXCEPTION_UNWINDING; - else - pExceptRec->ExceptionFlags |= (EXCEPTION_UNWINDING|EXCEPTION_EXIT_UNWIND); - -#ifndef NDEBUG - DPRINT("ExceptionFlags == 0x%x:\n", pExceptRec->ExceptionFlags); - if (pExceptRec->ExceptionFlags & EXCEPTION_UNWINDING) - { - DPRINT(" * EXCEPTION_UNWINDING (0x%x)\n", EXCEPTION_UNWINDING); - } - if (pExceptRec->ExceptionFlags & EXCEPTION_EXIT_UNWIND) - { - DPRINT(" * EXCEPTION_EXIT_UNWIND (0x%x)\n", EXCEPTION_EXIT_UNWIND); - } -#endif /* NDEBUG */ - - Context.ContextFlags = - (CONTEXT_i386 | CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS); - - SehpCaptureContext(&Context); - - DPRINT("Context.Eip = 0x%.08x\n", Context.Eip); - DPRINT("Context.Ebp = 0x%.08x\n", Context.Ebp); - DPRINT("Context.Esp = 0x%.08x\n", Context.Esp); - - Context.Esp += 0x10; - Context.Eax = EaxValue; - - // Begin traversing the list of EXCEPTION_REGISTRATION - while ((ULONG_PTR)ERHead != (ULONG_PTR)-1) - { - EXCEPTION_RECORD er2; - - DPRINT("ERHead 0x%X\n", ERHead); - - if (ERHead == RegistrationFrame) - { - DPRINT("Continueing execution\n"); - SehpContinue(&Context, FALSE); - return; - } - else - { - // If there's an exception frame, but it's lower on the stack - // than the head of the exception list, something's wrong! - if (RegistrationFrame && (RegistrationFrame <= ERHead)) - { - DPRINT("The exception frame is bad\n"); - - // Generate an exception to bail out - er2.ExceptionRecord = pExceptRec; - er2.NumberParameters = 0; - er2.ExceptionCode = STATUS_INVALID_UNWIND_TARGET; - er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE; - - RtlRaiseException(&er2); - } - } - -#if 0 - Stack = ERHead + sizeof(EXCEPTION_REGISTRATION); - if ( (Teb->Tib.StackBase <= (PVOID)ERHead ) // Make sure that ERHead - && (Teb->Tib.->StackLimit >= (PVOID)Stack ) // is in range, and a multiple - && (0 == ((ULONG_PTR)ERHead & 3)) ) // of 4 (i.e., sane) - { -#else - if (1) { -#endif - PEXCEPTION_REGISTRATION NewERHead; - PEXCEPTION_REGISTRATION pCurrExceptReg; - EXCEPTION_DISPOSITION ReturnValue; - - DPRINT("Executing handler at 0x%X for unwind\n", ERHead->handler); - - ReturnValue = RtlpExecuteHandlerForUnwind( - pExceptRec, - ERHead, - &Context, - &NewERHead, - ERHead->handler); - - DPRINT("Handler at 0x%X returned 0x%X\n", ERHead->handler, ReturnValue); - - if (ReturnValue != ExceptionContinueSearch) - { - if (ReturnValue != ExceptionCollidedUnwind) - { - DPRINT("Bad return value\n"); - - er2.ExceptionRecord = pExceptRec; - er2.NumberParameters = 0; - er2.ExceptionCode = STATUS_INVALID_DISPOSITION; - er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE; - - RtlRaiseException(&er2); - } - else - { - ERHead = NewERHead; - } - } - - pCurrExceptReg = ERHead; - ERHead = ERHead->prev; - - DPRINT("New ERHead is 0x%X\n", ERHead); - - DPRINT("Setting exception registration at 0x%X as current\n", - RegistrationFrame->prev); - - // Unlink the exception handler - SehpSetExceptionList(RegistrationFrame->prev); - } - else // The stack looks goofy! Raise an exception to bail out - { - DPRINT("Bad stack\n"); - - er2.ExceptionRecord = pExceptRec; - er2.NumberParameters = 0; - er2.ExceptionCode = STATUS_BAD_STACK; - er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE; - - RtlRaiseException(&er2); - } - } - - // If we get here, we reached the end of the EXCEPTION_REGISTRATION list. - // This shouldn't happen normally. - - DPRINT("Ran out of exception registrations. RegistrationFrame is (0x%X)\n", - RegistrationFrame); - - if ((ULONG_PTR)RegistrationFrame == (ULONG_PTR)-1) - SehpContinue(&Context, FALSE); - else - NtRaiseException(pExceptRec, &Context, 0); -} - /* EOF */