Merging the KJKHyperion-RtlUnwind branch back into HEAD

svn path=/trunk/; revision=9956
This commit is contained in:
KJK::Hyperion
2004-07-01 02:40:23 +00:00
parent 209e1d7692
commit fdd518ddac
13 changed files with 96 additions and 530 deletions
+2 -2
View File
@@ -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
+5 -5
View File
@@ -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
+34 -14
View File
@@ -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 <ddk/ntddk.h>
#include <ntddk.h>
#include <rosrtl/string.h>
#include <pseh.h>
#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 */
+1 -3
View File
@@ -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
+3 -23
View File
@@ -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 <[email protected]>
* Skywing <[email protected]>
* KJK::Hyperion <[email protected]>
* 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
+34 -31
View File
@@ -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;
+4 -4
View File
@@ -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
+2
View File
@@ -0,0 +1,2 @@
*.d
*.o
+4 -1
View File
@@ -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
-1
View File
@@ -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
+1 -4
View File
@@ -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
+5 -1
View File
@@ -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);
}
+1 -441
View File
@@ -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 */