mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
Merging the KJKHyperion-RtlUnwind branch back into HEAD
svn path=/trunk/; revision=9956
This commit is contained in:
+2
-2
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
*.d
|
||||
*.o
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,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 */
|
||||
|
||||
Reference in New Issue
Block a user