mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
Initial OS level SEH support.
svn path=/trunk/; revision=2256
This commit is contained in:
parent
2eb7adef67
commit
0948ab6596
19 changed files with 1424 additions and 92 deletions
|
@ -1,3 +1,442 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: include/types.h
|
||||
* PURPOSE: Types used by all the parts of the system
|
||||
* PROGRAMMER: David Welch <welch@cwcom.net>
|
||||
* DEFINES: _WIN64: 64-bit architecture
|
||||
* _WIN32: 32-bit architecture (default)
|
||||
* UPDATE HISTORY:
|
||||
* 27/06/00: Created
|
||||
* 01/05/01: Portabillity changes
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDE_ACPI_TYPES_H
|
||||
#define __INCLUDE_ACPI_TYPES_H
|
||||
|
||||
/* Fixed precision types */
|
||||
typedef signed char INT8, *PINT8;
|
||||
typedef signed short INT16, *PINT16;
|
||||
#if 0
|
||||
typedef signed int INT32, *PINT32;
|
||||
#endif
|
||||
typedef signed long long INT64, *PINT64;
|
||||
#if 0
|
||||
typedef unsigned char UINT8, *PUINT8;
|
||||
typedef unsigned short UINT16, *PUINT16;
|
||||
typedef unsigned int UINT32, *PUINT32;
|
||||
typedef unsigned long long UINT64, *PUINT64;
|
||||
#endif
|
||||
|
||||
typedef signed long int LONG32, *PLONG32;
|
||||
typedef unsigned long int ULONG32, *PULONG32;
|
||||
typedef unsigned long int DWORD32, *PDWORD32;
|
||||
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
/* 64-bit architecture */
|
||||
|
||||
typedef INT64 INT, *PINT;
|
||||
typedef LONG64 LONG, *PLONG;
|
||||
typedef DWORD64 DWORD, *PDWORD;
|
||||
typedef UINT64 UINT, *PUINT;
|
||||
typedef ULONG64 ULONG, *PULONG;
|
||||
|
||||
/* Pointer precision types */
|
||||
typedef long long INT_PTR, *PINT_PTR;
|
||||
typedef unsigned long long UINT_PTR, *PUINT_PTR;
|
||||
typedef long long LONG_PTR, *PLONG_PTR;
|
||||
typedef unsigned long long ULONG_PTR, *PULONG_PTR;
|
||||
typedef unsigned long long HANDLE_PTR;
|
||||
typedef unsigned int UHALF_PTR, *PUHALF_PTR;
|
||||
typedef int HALF_PTR, *PHALF_PTR;
|
||||
|
||||
#else /* _WIN64 */
|
||||
|
||||
/* 32-bit architecture */
|
||||
|
||||
typedef INT32 INT, *PINT;
|
||||
typedef LONG32 LONG, *PLONG;
|
||||
typedef DWORD32 DWORD, *PDWORD;
|
||||
typedef UINT32 UINT, *PUINT;
|
||||
typedef ULONG32 ULONG, *PULONG;
|
||||
|
||||
|
||||
/* Pointer precision types */
|
||||
typedef int INT_PTR, *PINT_PTR;
|
||||
typedef unsigned int UINT_PTR, *PUINT_PTR;
|
||||
typedef long LONG_PTR, *PLONG_PTR;
|
||||
typedef unsigned long ULONG_PTR, *PULONG_PTR;
|
||||
typedef unsigned short UHALF_PTR, *PUHALF_PTR;
|
||||
typedef short HALF_PTR, *PHALF_PTR;
|
||||
typedef unsigned long HANDLE_PTR;
|
||||
|
||||
#endif /* _WIN64 */
|
||||
|
||||
typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
|
||||
|
||||
typedef long long LONG64, *PLONG64;
|
||||
|
||||
typedef unsigned long long ULONG64, *PULONG64;
|
||||
typedef unsigned long long DWORD64, *PDWORD64;
|
||||
|
||||
|
||||
#if 0
|
||||
typedef unsigned char UCHAR;
|
||||
#endif
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned short WCHAR;
|
||||
typedef unsigned short WORD;
|
||||
typedef int BOOL;
|
||||
#if 0
|
||||
typedef unsigned char BOOLEAN;
|
||||
#endif
|
||||
typedef BOOLEAN* PBOOLEAN;
|
||||
typedef unsigned short *LPWSTR;
|
||||
typedef unsigned short *PWSTR;
|
||||
typedef unsigned char *PUCHAR;
|
||||
typedef unsigned short *PUSHORT;
|
||||
typedef void *PVOID;
|
||||
typedef unsigned char BYTE;
|
||||
typedef void *LPVOID;
|
||||
typedef float *PFLOAT;
|
||||
typedef unsigned short *PWCH;
|
||||
typedef unsigned short *PWORD;
|
||||
|
||||
typedef long long LONGLONG;
|
||||
typedef unsigned long long ULONGLONG;
|
||||
typedef long long *PLONGLONG;
|
||||
typedef unsigned long long *PULONGLONG;
|
||||
|
||||
/* Check VOID before defining CHAR, SHORT */
|
||||
#ifndef VOID
|
||||
#define VOID void
|
||||
typedef char CHAR;
|
||||
typedef short SHORT;
|
||||
#endif
|
||||
|
||||
typedef CHAR *PCHAR;
|
||||
typedef CHAR *PCH;
|
||||
typedef void *HANDLE;
|
||||
typedef char CCHAR;
|
||||
typedef CCHAR *PCCHAR;
|
||||
|
||||
#if 0
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#ifdef __cplusplus
|
||||
#define NULL 0
|
||||
#else
|
||||
#define NULL ((void*)0)
|
||||
#endif /* __cplusplus */
|
||||
#endif /* NULL */
|
||||
|
||||
typedef const unsigned short *PCWSTR;
|
||||
|
||||
typedef char* PCSZ;
|
||||
|
||||
typedef union _LARGE_INTEGER
|
||||
{
|
||||
struct
|
||||
{
|
||||
DWORD LowPart;
|
||||
LONG HighPart;
|
||||
} u;
|
||||
#ifdef ANONYMOUSUNIONS
|
||||
struct
|
||||
{
|
||||
DWORD LowPart;
|
||||
LONG HighPart;
|
||||
};
|
||||
#endif /* ANONYMOUSUNIONS */
|
||||
LONGLONG QuadPart;
|
||||
} LARGE_INTEGER, *PLARGE_INTEGER;
|
||||
|
||||
typedef union _ULARGE_INTEGER
|
||||
{
|
||||
struct
|
||||
{
|
||||
DWORD LowPart;
|
||||
DWORD HighPart;
|
||||
} u;
|
||||
#ifdef ANONYMOUSUNIONS
|
||||
struct
|
||||
{
|
||||
DWORD LowPart;
|
||||
DWORD HighPart;
|
||||
};
|
||||
#endif /* ANONYMOUSUNIONS */
|
||||
ULONGLONG QuadPart;
|
||||
} ULARGE_INTEGER, *PULARGE_INTEGER;
|
||||
|
||||
typedef struct _FILETIME
|
||||
{
|
||||
DWORD dwLowDateTime;
|
||||
DWORD dwHighDateTime;
|
||||
} FILETIME, *LPFILETIME, *PFILETIME;
|
||||
|
||||
#define CONST const
|
||||
|
||||
#ifdef i386
|
||||
#define STDCALL __attribute__ ((stdcall))
|
||||
#define CDECL __attribute((cdecl))
|
||||
#define CALLBACK WINAPI
|
||||
#define PASCAL WINAPI
|
||||
#else
|
||||
#define STDCALL
|
||||
#define CDECL
|
||||
#define CALLBACK
|
||||
#define PASCAL
|
||||
#endif
|
||||
|
||||
typedef struct _LIST_ENTRY {
|
||||
struct _LIST_ENTRY *Flink;
|
||||
struct _LIST_ENTRY *Blink;
|
||||
} LIST_ENTRY, *PLIST_ENTRY;
|
||||
|
||||
typedef struct _SINGLE_LIST_ENTRY {
|
||||
struct _SINGLE_LIST_ENTRY *Next;
|
||||
} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
|
||||
|
||||
typedef DWORD STDCALL (*PTHREAD_START_ROUTINE) (LPVOID);
|
||||
typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;
|
||||
|
||||
typedef unsigned short *PWCHAR;
|
||||
|
||||
#ifdef __PPC__
|
||||
#define CONTEXT_CONTROL 1L
|
||||
#define CONTEXT_FLOATING_POINT 2L
|
||||
#define CONTEXT_INTEGER 4L
|
||||
#define CONTEXT_DEBUG_REGISTERS 8L
|
||||
|
||||
#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER)
|
||||
#define CONTEXT_DEBUGGER (CONTEXT_FULL)
|
||||
|
||||
#else /* x86 */
|
||||
/* The doc refered me to winnt.h, so I had to look... */
|
||||
#define SIZE_OF_80387_REGISTERS 80
|
||||
|
||||
/* Values for contextflags */
|
||||
#define CONTEXT_i386 0x10000
|
||||
#define CONTEXT_CONTROL (CONTEXT_i386 | 1)
|
||||
#define CONTEXT_INTEGER (CONTEXT_i386 | 2)
|
||||
#define CONTEXT_SEGMENTS (CONTEXT_i386 | 4)
|
||||
#define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 8)
|
||||
#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x10)
|
||||
#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS)
|
||||
|
||||
/* our own invention */
|
||||
#define FLAG_TRACE_BIT 0x100
|
||||
#define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
typedef struct _FLOATING_SAVE_AREA {
|
||||
DWORD ControlWord;
|
||||
DWORD StatusWord;
|
||||
DWORD TagWord;
|
||||
DWORD ErrorOffset;
|
||||
DWORD ErrorSelector;
|
||||
DWORD DataOffset;
|
||||
DWORD DataSelector;
|
||||
BYTE RegisterArea[80];
|
||||
DWORD Cr0NpxState;
|
||||
} FLOATING_SAVE_AREA;
|
||||
|
||||
typedef struct _CONTEXT {
|
||||
DWORD ContextFlags;
|
||||
|
||||
DWORD Dr0;
|
||||
DWORD Dr1;
|
||||
DWORD Dr2;
|
||||
DWORD Dr3;
|
||||
DWORD Dr6;
|
||||
DWORD Dr7;
|
||||
|
||||
FLOATING_SAVE_AREA FloatSave;
|
||||
|
||||
DWORD SegGs;
|
||||
DWORD SegFs;
|
||||
DWORD SegEs;
|
||||
DWORD SegDs;
|
||||
|
||||
DWORD Edi;
|
||||
DWORD Esi;
|
||||
DWORD Ebx;
|
||||
DWORD Edx;
|
||||
DWORD Ecx;
|
||||
DWORD Eax;
|
||||
|
||||
DWORD Ebp;
|
||||
DWORD Eip;
|
||||
DWORD SegCs;
|
||||
DWORD EFlags;
|
||||
DWORD Esp;
|
||||
DWORD SegSs;
|
||||
} CONTEXT, *PCONTEXT, *LPCONTEXT;
|
||||
|
||||
#else /* __ppc__ */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Floating point registers returned when CONTEXT_FLOATING_POINT is set */
|
||||
double Fpr0;
|
||||
double Fpr1;
|
||||
double Fpr2;
|
||||
double Fpr3;
|
||||
double Fpr4;
|
||||
double Fpr5;
|
||||
double Fpr6;
|
||||
double Fpr7;
|
||||
double Fpr8;
|
||||
double Fpr9;
|
||||
double Fpr10;
|
||||
double Fpr11;
|
||||
double Fpr12;
|
||||
double Fpr13;
|
||||
double Fpr14;
|
||||
double Fpr15;
|
||||
double Fpr16;
|
||||
double Fpr17;
|
||||
double Fpr18;
|
||||
double Fpr19;
|
||||
double Fpr20;
|
||||
double Fpr21;
|
||||
double Fpr22;
|
||||
double Fpr23;
|
||||
double Fpr24;
|
||||
double Fpr25;
|
||||
double Fpr26;
|
||||
double Fpr27;
|
||||
double Fpr28;
|
||||
double Fpr29;
|
||||
double Fpr30;
|
||||
double Fpr31;
|
||||
double Fpscr;
|
||||
|
||||
/* Integer registers returned when CONTEXT_INTEGER is set. */
|
||||
DWORD Gpr0;
|
||||
DWORD Gpr1;
|
||||
DWORD Gpr2;
|
||||
DWORD Gpr3;
|
||||
DWORD Gpr4;
|
||||
DWORD Gpr5;
|
||||
DWORD Gpr6;
|
||||
DWORD Gpr7;
|
||||
DWORD Gpr8;
|
||||
DWORD Gpr9;
|
||||
DWORD Gpr10;
|
||||
DWORD Gpr11;
|
||||
DWORD Gpr12;
|
||||
DWORD Gpr13;
|
||||
DWORD Gpr14;
|
||||
DWORD Gpr15;
|
||||
DWORD Gpr16;
|
||||
DWORD Gpr17;
|
||||
DWORD Gpr18;
|
||||
DWORD Gpr19;
|
||||
DWORD Gpr20;
|
||||
DWORD Gpr21;
|
||||
DWORD Gpr22;
|
||||
DWORD Gpr23;
|
||||
DWORD Gpr24;
|
||||
DWORD Gpr25;
|
||||
DWORD Gpr26;
|
||||
DWORD Gpr27;
|
||||
DWORD Gpr28;
|
||||
DWORD Gpr29;
|
||||
DWORD Gpr30;
|
||||
DWORD Gpr31;
|
||||
|
||||
DWORD Cr; /* Condition register */
|
||||
DWORD Xer; /* Fixed point exception register */
|
||||
|
||||
/* The following are set when CONTEXT_CONTROL is set. */
|
||||
DWORD Msr; /* Machine status register */
|
||||
DWORD Iar; /* Instruction address register */
|
||||
DWORD Lr; /* Link register */
|
||||
DWORD Ctr; /* Control register */
|
||||
|
||||
/* Control which context values are returned */
|
||||
DWORD ContextFlags;
|
||||
DWORD Fill[3];
|
||||
|
||||
/* Registers returned if CONTEXT_DEBUG_REGISTERS is set. */
|
||||
DWORD Dr0; /* Breakpoint Register 1 */
|
||||
DWORD Dr1; /* Breakpoint Register 2 */
|
||||
DWORD Dr2; /* Breakpoint Register 3 */
|
||||
DWORD Dr3; /* Breakpoint Register 4 */
|
||||
DWORD Dr4; /* Breakpoint Register 5 */
|
||||
DWORD Dr5; /* Breakpoint Register 6 */
|
||||
DWORD Dr6; /* Debug Status Register */
|
||||
DWORD Dr7; /* Debug Control Register */
|
||||
} CONTEXT, *PCONTEXT, *LPCONTEXT;
|
||||
#endif
|
||||
|
||||
typedef HANDLE *PHANDLE;
|
||||
|
||||
typedef struct value_ent {
|
||||
LPWSTR ve_valuename;
|
||||
DWORD ve_valuelen;
|
||||
DWORD ve_valueptr;
|
||||
DWORD ve_type;
|
||||
} WVALENT, *PWVALENT;
|
||||
|
||||
|
||||
typedef const void *LPCVOID;
|
||||
typedef BYTE *LPBYTE, *PBYTE;
|
||||
|
||||
typedef BOOL *PBOOL;
|
||||
|
||||
typedef DWORD LCID;
|
||||
typedef DWORD *PLCID;
|
||||
|
||||
typedef const char *LPCSTR;
|
||||
|
||||
typedef char *LPSTR;
|
||||
|
||||
typedef const unsigned short *LPCWSTR;
|
||||
|
||||
typedef unsigned short RTL_ATOM;
|
||||
typedef unsigned short *PRTL_ATOM;
|
||||
typedef WORD ATOM;
|
||||
|
||||
typedef struct _COORD {
|
||||
SHORT X;
|
||||
SHORT Y;
|
||||
} COORD;
|
||||
|
||||
typedef struct _SMALL_RECT {
|
||||
SHORT Left;
|
||||
SHORT Top;
|
||||
SHORT Right;
|
||||
SHORT Bottom;
|
||||
} SMALL_RECT, *PSMALL_RECT;
|
||||
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(*PTIMERAPCROUTINE)(
|
||||
LPVOID lpArgToCompletionRoutine,
|
||||
DWORD dwTimerLowValue,
|
||||
DWORD dwTimerHighValue
|
||||
);
|
||||
|
||||
#include <ntos/except.h>
|
||||
|
||||
#endif /* __INCLUDE_ACPI_TYPES_H */
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -308,17 +747,6 @@ typedef struct value_ent {
|
|||
DWORD ve_type;
|
||||
} WVALENT, *PWVALENT;
|
||||
|
||||
#define EXCEPTION_MAXIMUM_PARAMETERS (15)
|
||||
|
||||
typedef struct _EXCEPTION_RECORD {
|
||||
DWORD ExceptionCode;
|
||||
DWORD ExceptionFlags;
|
||||
struct _EXCEPTION_RECORD *ExceptionRecord;
|
||||
PVOID ExceptionAddress;
|
||||
DWORD NumberParameters;
|
||||
DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
|
||||
} EXCEPTION_RECORD, *PEXCEPTION_RECORD, *LPEXCEPTION_RECORD;
|
||||
|
||||
typedef long *PLONG;
|
||||
|
||||
typedef const void *LPCVOID;
|
||||
|
@ -360,4 +788,8 @@ VOID
|
|||
DWORD dwTimerHighValue
|
||||
);
|
||||
|
||||
#include <ntos/except.h>
|
||||
|
||||
#endif /* __INCLUDE_ACPI_TYPES_H */
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: rtl.h,v 1.57 2001/09/01 15:36:43 chorns Exp $
|
||||
/* $Id: rtl.h,v 1.58 2001/09/24 00:51:15 chorns Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -1830,10 +1830,10 @@ RtlUnlockHeap (
|
|||
VOID
|
||||
STDCALL
|
||||
RtlUnwind (
|
||||
ULONG Unknown1,
|
||||
ULONG Unknown2,
|
||||
ULONG Unknown3,
|
||||
ULONG Unknown4
|
||||
PEXCEPTION_REGISTRATION RegistrationFrame,
|
||||
PVOID ReturnAddress,
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
DWORD EaxValue
|
||||
);
|
||||
|
||||
WCHAR
|
||||
|
|
|
@ -373,22 +373,12 @@ typedef struct
|
|||
typedef HANDLE *PHANDLE;
|
||||
|
||||
typedef struct value_ent {
|
||||
LPWSTR ve_valuename;
|
||||
DWORD ve_valuelen;
|
||||
DWORD ve_valueptr;
|
||||
DWORD ve_type;
|
||||
LPWSTR ve_valuename;
|
||||
DWORD ve_valuelen;
|
||||
DWORD ve_valueptr;
|
||||
DWORD ve_type;
|
||||
} WVALENT, *PWVALENT;
|
||||
|
||||
#define EXCEPTION_MAXIMUM_PARAMETERS (15)
|
||||
|
||||
typedef struct _EXCEPTION_RECORD {
|
||||
DWORD ExceptionCode;
|
||||
DWORD ExceptionFlags;
|
||||
struct _EXCEPTION_RECORD *ExceptionRecord;
|
||||
PVOID ExceptionAddress;
|
||||
DWORD NumberParameters;
|
||||
DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
|
||||
} EXCEPTION_RECORD, *PEXCEPTION_RECORD, *LPEXCEPTION_RECORD;
|
||||
|
||||
typedef const void *LPCVOID;
|
||||
typedef BYTE *LPBYTE, *PBYTE;
|
||||
|
@ -428,4 +418,6 @@ typedef VOID STDCALL
|
|||
DWORD dwTimerHighValue
|
||||
);
|
||||
|
||||
#include "except.h"
|
||||
|
||||
#endif /* __INCLUDE_TYPES_H */
|
||||
|
|
|
@ -1872,11 +1872,6 @@ typedef struct tagEVENTMSG {
|
|||
HWND hwnd;
|
||||
} EVENTMSG;
|
||||
|
||||
typedef struct _EXCEPTION_POINTERS {
|
||||
PEXCEPTION_RECORD ExceptionRecord;
|
||||
PCONTEXT ContextRecord;
|
||||
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS, *LPEXCEPTION_POINTERS;
|
||||
|
||||
typedef struct _EXT_BUTTON {
|
||||
WORD idCommand;
|
||||
WORD idsHelp;
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
#include <windows.h>
|
||||
|
||||
typedef enum _EXCEPTION_DISPOSITION {
|
||||
ExceptionContinueExecution,
|
||||
ExceptionContinueSearch,
|
||||
ExceptionNestedException,
|
||||
ExceptionCollidedUnwind
|
||||
} EXCEPTION_DISPOSITION;
|
||||
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
_except_handler2(
|
||||
struct _EXCEPTION_RECORD *ExceptionRecord,
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
#include <windows.h>
|
||||
|
||||
typedef enum _EXCEPTION_DISPOSITION {
|
||||
ExceptionContinueExecution,
|
||||
ExceptionContinueSearch,
|
||||
ExceptionNestedException,
|
||||
ExceptionCollidedUnwind
|
||||
} EXCEPTION_DISPOSITION;
|
||||
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
_except_handler3(
|
||||
struct _EXCEPTION_RECORD *ExceptionRecord,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: exception.c,v 1.6 2001/06/17 20:05:10 ea Exp $
|
||||
/* $Id: exception.c,v 1.7 2001/09/24 00:51:16 chorns Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -64,10 +64,10 @@ RtlRaiseStatus(NTSTATUS Status)
|
|||
|
||||
|
||||
VOID STDCALL
|
||||
RtlUnwind(ULONG Unknown1,
|
||||
ULONG Unknown2,
|
||||
ULONG Unknown3,
|
||||
ULONG Unknown4)
|
||||
RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame,
|
||||
PVOID ReturnAddress,
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
DWORD EaxValue)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile,v 1.54 2001/09/06 20:26:36 dwelch Exp $
|
||||
# $Id: Makefile,v 1.55 2001/09/24 00:51:16 chorns Exp $
|
||||
#
|
||||
# ReactOS Operating System
|
||||
#
|
||||
|
@ -94,6 +94,7 @@ OBJECTS_RTL = \
|
|||
rtl/nls.o \
|
||||
rtl/qsort.o \
|
||||
rtl/regio.o \
|
||||
rtl/seh.o \
|
||||
rtl/sprintf.o \
|
||||
rtl/stdlib.o \
|
||||
rtl/string.o \
|
||||
|
|
|
@ -183,7 +183,7 @@ NtEarlyInitVdm(VOID);
|
|||
VOID
|
||||
KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Eip);
|
||||
VOID
|
||||
KiDispatchException(PEXCEPTION_RECORD Er,
|
||||
KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||
PCONTEXT Context,
|
||||
PKTRAP_FRAME Tf,
|
||||
KPROCESSOR_MODE PreviousMode,
|
||||
|
|
|
@ -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: catch.c,v 1.15 2001/07/04 20:40:21 chorns Exp $
|
||||
/* $Id: catch.c,v 1.16 2001/09/24 00:51:16 chorns Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/catch.c
|
||||
|
@ -31,19 +31,173 @@
|
|||
#include <internal/ldr.h>
|
||||
#include <internal/ps.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
RtlpExecuteHandlerForException(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
PEXCEPTION_REGISTRATION ExceptionRegistration,
|
||||
PCONTEXT Context,
|
||||
PVOID DispatcherContext,
|
||||
PEXCEPTION_HANDLER Handler);
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
VOID RtlpDumpExceptionRegistrations(VOID)
|
||||
{
|
||||
PEXCEPTION_REGISTRATION Current;
|
||||
PKTHREAD Thread;
|
||||
|
||||
DbgPrint("Dumping exception registrations:\n");
|
||||
|
||||
Thread = KeGetCurrentThread();
|
||||
|
||||
assert(Thread);
|
||||
assert(Thread->TrapFrame);
|
||||
|
||||
Current = Thread->TrapFrame->ExceptionList;
|
||||
|
||||
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 */
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
RtlpDispatchException(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
PCONTEXT Context)
|
||||
{
|
||||
PEXCEPTION_REGISTRATION RegistrationFrame;
|
||||
DWORD DispatcherContext;
|
||||
DWORD ReturnValue;
|
||||
PKPCR KPCR;
|
||||
PKTHREAD Thread;
|
||||
|
||||
DPRINT("RtlpDispatchException() called\n");
|
||||
#ifndef NDEBUG
|
||||
RtlpDumpExceptionRegistrations();
|
||||
#endif /* NDEBUG */
|
||||
Thread = KeGetCurrentThread();
|
||||
|
||||
DPRINT("Thread is 0x%X\n", Thread);
|
||||
|
||||
KPCR = KeGetCurrentKPCR();
|
||||
|
||||
RegistrationFrame = Thread->TrapFrame->ExceptionList;
|
||||
|
||||
DPRINT("RegistrationFrame is 0x%X\n", RegistrationFrame);
|
||||
|
||||
while ((ULONG_PTR)RegistrationFrame != -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 (Thread->KernelStack > RegistrationFrameEnd)
|
||||
{
|
||||
ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
|
||||
return ExceptionDismiss;
|
||||
}
|
||||
// FIXME: Correct?
|
||||
if (Thread->StackLimit < RegistrationFrameEnd)
|
||||
{
|
||||
ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
|
||||
return ExceptionDismiss;
|
||||
}
|
||||
|
||||
// Make sure stack is DWORD aligned
|
||||
if ((ULONG_PTR)RegistrationFrame & 3)
|
||||
{
|
||||
ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
|
||||
return ExceptionDismiss;
|
||||
}
|
||||
#endif
|
||||
|
||||
DPRINT("Calling handler at 0x%X\n", RegistrationFrame->handler);
|
||||
|
||||
ReturnValue = RtlpExecuteHandlerForException(
|
||||
ExceptionRecord,
|
||||
RegistrationFrame,
|
||||
Context,
|
||||
&DispatcherContext,
|
||||
RegistrationFrame->handler);
|
||||
|
||||
if (RegistrationFrame == NULL)
|
||||
{
|
||||
ExceptionRecord->ExceptionFlags &= ~EXCEPTION_NESTED_CALL; // Turn off flag
|
||||
}
|
||||
|
||||
if (ReturnValue == ExceptionContinueExecution)
|
||||
{
|
||||
/* Copy the changed context back to the trap frame and return */
|
||||
NtContinue(Context, FALSE);
|
||||
return ExceptionContinueExecution;
|
||||
}
|
||||
else if (ReturnValue == ExceptionDismiss)
|
||||
{
|
||||
if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
|
||||
{
|
||||
ExceptionRecord2.ExceptionRecord = ExceptionRecord;
|
||||
ExceptionRecord2.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
|
||||
ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
|
||||
ExceptionRecord2.NumberParameters = 0;
|
||||
RtlRaiseException(&ExceptionRecord2);
|
||||
}
|
||||
/* Else continue search */
|
||||
}
|
||||
else if (ReturnValue == ExceptionNestedException)
|
||||
{
|
||||
ExceptionRecord->ExceptionFlags |= EXCEPTION_EXIT_UNWIND;
|
||||
if (DispatcherContext > Temp)
|
||||
Temp = DispatcherContext;
|
||||
}
|
||||
else if (ReturnValue == ExceptionCollidedUnwind)
|
||||
{
|
||||
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 */
|
||||
|
||||
return ExceptionDismiss;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
KiDispatchException(PEXCEPTION_RECORD Er,
|
||||
KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||
PCONTEXT Context,
|
||||
PKTRAP_FRAME Tf,
|
||||
KPROCESSOR_MODE PreviousMode,
|
||||
BOOLEAN SearchFrames)
|
||||
{
|
||||
EXCEPTION_DISPOSITION Value;
|
||||
CONTEXT TContext;
|
||||
|
||||
DPRINT("KiDispatchException() called \n");
|
||||
/* PCR->KeExceptionDispatchCount++; */
|
||||
|
||||
if (Context == NULL)
|
||||
|
@ -59,7 +213,7 @@ KiDispatchException(PEXCEPTION_RECORD Er,
|
|||
Context = &TContext;
|
||||
}
|
||||
|
||||
if (Er->ExceptionCode == STATUS_BREAKPOINT)
|
||||
if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT)
|
||||
{
|
||||
Context->Eip--;
|
||||
}
|
||||
|
@ -91,7 +245,7 @@ KiDispatchException(PEXCEPTION_RECORD Er,
|
|||
Stack[1] = (ULONG)&Stack[3];
|
||||
/* Pointer to CONTEXT structure */
|
||||
Stack[2] = (ULONG)&Stack[CDest];
|
||||
memcpy(&Stack[3], Er, sizeof(EXCEPTION_RECORD));
|
||||
memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD));
|
||||
memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
|
||||
|
||||
Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
|
||||
|
@ -103,14 +257,24 @@ KiDispatchException(PEXCEPTION_RECORD Er,
|
|||
/* FIXME: Forward the exception to the process exception port */
|
||||
|
||||
/* Terminate the offending thread */
|
||||
ZwTerminateThread(NtCurrentThread(), Er->ExceptionCode);
|
||||
ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
|
||||
|
||||
/* If that fails then bugcheck */
|
||||
DbgPrint("Could not terminate thread\n");
|
||||
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
|
||||
/* PreviousMode == KernelMode */
|
||||
Value = RtlpDispatchException(ExceptionRecord, Context);
|
||||
|
||||
DPRINT("RtlpDispatchException() returned with 0x%X\n", Value);
|
||||
|
||||
/* If RtlpDispatchException() does not handle the exception then bugcheck */
|
||||
if (Value != ExceptionContinueExecution)
|
||||
{
|
||||
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,10 +293,17 @@ ExRaiseDatatypeMisalignment (VOID)
|
|||
VOID STDCALL
|
||||
ExRaiseStatus (IN NTSTATUS Status)
|
||||
{
|
||||
DbgPrint("ExRaiseStatus(%x)\n",Status);
|
||||
KeBugCheck(0);
|
||||
}
|
||||
EXCEPTION_RECORD ExceptionRecord;
|
||||
|
||||
DPRINT("ExRaiseStatus(%x)\n", Status);
|
||||
|
||||
ExceptionRecord.ExceptionRecord = NULL;
|
||||
ExceptionRecord.NumberParameters = 0;
|
||||
ExceptionRecord.ExceptionCode = Status;
|
||||
ExceptionRecord.ExceptionFlags = 0;
|
||||
|
||||
RtlRaiseException(&ExceptionRecord);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
|
@ -152,17 +323,277 @@ NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord,
|
|||
VOID STDCALL
|
||||
RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
|
||||
{
|
||||
ZwRaiseException(ExceptionRecord, NULL, TRUE);
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
EXCEPTION_DISPOSITION
|
||||
RtlpExecuteHandler(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
PEXCEPTION_REGISTRATION ExceptionRegistration,
|
||||
PCONTEXT Context,
|
||||
PVOID DispatcherContext,
|
||||
PEXCEPTION_HANDLER Handler,
|
||||
PEXCEPTION_HANDLER RawHandler)
|
||||
{
|
||||
EXCEPTION_DISPOSITION Value;
|
||||
|
||||
// Set up an EXCEPTION_REGISTRATION
|
||||
__asm__ ("pushl %0;pushl %%fs:0;movl %%esp,%%fs:0;" : : "g" (RawHandler));
|
||||
|
||||
// Invoke the exception callback function
|
||||
Value = Handler(
|
||||
ExceptionRecord,
|
||||
ExceptionRegistration,
|
||||
Context,
|
||||
DispatcherContext);
|
||||
|
||||
// Remove the minimal EXCEPTION_REGISTRATION frame
|
||||
//__asm__ ("movl %fs:0,%esp; popl %fs:0");
|
||||
|
||||
__asm__ ("movl (%%esp),%%eax;movl %%eax,%%fs:0;addl $8,%%esp;" : : : "%eax");
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
RtlpExceptionHandler(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
PEXCEPTION_REGISTRATION ExceptionRegistration,
|
||||
PCONTEXT Context,
|
||||
PVOID DispatcherContext)
|
||||
{
|
||||
// If unwind flag set, return DISPOSITION_CONTINUE_SEARCH, else
|
||||
// assign DispatcherContext context and return DISPOSITION_NESTED_EXCEPTION
|
||||
|
||||
if (ExceptionRecord->ExceptionFlags & EXCEPTION_UNWINDING)
|
||||
{
|
||||
DPRINT("RtlpExceptionHandler(). Returning ExceptionContinueSearch\n");
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("RtlpExceptionHandler(). Returning ExceptionNestedException\n");
|
||||
*(PEXCEPTION_REGISTRATION*)DispatcherContext = ExceptionRegistration->prev;
|
||||
return ExceptionNestedException;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
RtlpUnwindHandler(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
PEXCEPTION_REGISTRATION ExceptionRegistration,
|
||||
PCONTEXT Context,
|
||||
PVOID DispatcherContext)
|
||||
{
|
||||
// If unwind flag set, return DISPOSITION_CONTINUE_SEARCH, else
|
||||
// assign DispatcherContext and return DISPOSITION_COLLIDED_UNWIND
|
||||
|
||||
if (ExceptionRecord->ExceptionFlags & EXCEPTION_UNWINDING)
|
||||
{
|
||||
DPRINT("RtlpUnwindHandler(). Returning ExceptionContinueSearch\n");
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("RtlpUnwindHandler(). Returning ExceptionCollidedUnwind\n");
|
||||
*(PEXCEPTION_REGISTRATION*)DispatcherContext = ExceptionRegistration->prev;
|
||||
return ExceptionCollidedUnwind;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
RtlpExecuteHandlerForException(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
PEXCEPTION_REGISTRATION ExceptionRegistration,
|
||||
PCONTEXT Context,
|
||||
PVOID DispatcherContext,
|
||||
PEXCEPTION_HANDLER Handler)
|
||||
{
|
||||
return RtlpExecuteHandler(
|
||||
ExceptionRecord,
|
||||
ExceptionRegistration,
|
||||
Context,
|
||||
DispatcherContext,
|
||||
Handler,
|
||||
RtlpExceptionHandler);
|
||||
}
|
||||
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
RtlpExecuteHandlerForUnwind(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
PEXCEPTION_REGISTRATION ExceptionRegistration,
|
||||
PCONTEXT Context,
|
||||
PVOID DispatcherContext,
|
||||
PEXCEPTION_HANDLER Handler)
|
||||
{
|
||||
return RtlpExecuteHandler(
|
||||
ExceptionRecord,
|
||||
ExceptionRegistration,
|
||||
Context,
|
||||
DispatcherContext,
|
||||
Handler,
|
||||
RtlpUnwindHandler);
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
RtlUnwind(ULONG Unknown1,
|
||||
ULONG Unknown2,
|
||||
ULONG Unknown3,
|
||||
ULONG Unknown4)
|
||||
RtlUnwind(
|
||||
PEXCEPTION_REGISTRATION RegistrationFrame,
|
||||
PVOID ReturnAddress,
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
DWORD EaxValue)
|
||||
{
|
||||
PEXCEPTION_REGISTRATION ERHead;
|
||||
PEXCEPTION_RECORD pExceptRec;
|
||||
EXCEPTION_RECORD TempER;
|
||||
CONTEXT Context;
|
||||
//PVOID Stack;
|
||||
PKTHREAD Thread;
|
||||
|
||||
DPRINT("RtlUnwind() called. RegistrationFrame 0x%X\n", RegistrationFrame);
|
||||
#ifndef NDEBUG
|
||||
RtlpDumpExceptionRegistrations();
|
||||
#endif /* NDEBUG */
|
||||
Thread = KeGetCurrentThread();
|
||||
|
||||
ERHead = Thread->TrapFrame->ExceptionList;
|
||||
|
||||
if (ExceptionRecord == NULL) // The normal case
|
||||
{
|
||||
pExceptRec = &TempER;
|
||||
|
||||
pExceptRec->ExceptionFlags = 0;
|
||||
pExceptRec->ExceptionCode = STATUS_UNWIND;
|
||||
pExceptRec->ExceptionRecord = NULL;
|
||||
// FIXME: Find out if NT retrieves the return address from the stack instead
|
||||
pExceptRec->ExceptionAddress = ReturnAddress;
|
||||
//pExceptRec->ExceptionInformation[0] = 0;
|
||||
}
|
||||
|
||||
if (RegistrationFrame)
|
||||
pExceptRec->ExceptionFlags |= EXCEPTION_UNWINDING;
|
||||
else
|
||||
pExceptRec->ExceptionFlags |= (EXCEPTION_UNWINDING|EXCEPTION_EXIT_UNWIND);
|
||||
|
||||
Context.ContextFlags =
|
||||
(CONTEXT_i386 | CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS);
|
||||
|
||||
KeTrapFrameToContext(Thread->TrapFrame, &Context);
|
||||
|
||||
Context.Esp += 0x10;
|
||||
Context.Eax = EaxValue;
|
||||
|
||||
// Begin traversing the list of EXCEPTION_REGISTRATION
|
||||
while ((ULONG_PTR)ERHead != -1)
|
||||
{
|
||||
EXCEPTION_RECORD er2;
|
||||
|
||||
DPRINT("ERHead 0x%X\n", ERHead);
|
||||
|
||||
if (ERHead == RegistrationFrame)
|
||||
{
|
||||
DPRINT("Continueing execution\n");
|
||||
NtContinue(&Context, FALSE);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there's an exception frame, but it's lower on the stack
|
||||
// then 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 ( (KPCR->StackBase <= (PVOID)ERHead ) // Make sure that ERHead
|
||||
&& (KPCR->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
|
||||
KeGetCurrentKPCR()->ExceptionList = 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 == -1)
|
||||
NtContinue(&Context, FALSE);
|
||||
else
|
||||
NtRaiseException(pExceptRec, &Context, 0);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -307,6 +307,61 @@ KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
ULONG
|
||||
KiKernelTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
|
||||
{
|
||||
EXCEPTION_RECORD Er;
|
||||
|
||||
if (ExceptionNr == 0)
|
||||
{
|
||||
Er.ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO;
|
||||
}
|
||||
else if (ExceptionNr == 1)
|
||||
{
|
||||
Er.ExceptionCode = STATUS_SINGLE_STEP;
|
||||
}
|
||||
else if (ExceptionNr == 3)
|
||||
{
|
||||
Er.ExceptionCode = STATUS_BREAKPOINT;
|
||||
}
|
||||
else if (ExceptionNr == 4)
|
||||
{
|
||||
Er.ExceptionCode = STATUS_INTEGER_OVERFLOW;
|
||||
}
|
||||
else if (ExceptionNr == 5)
|
||||
{
|
||||
Er.ExceptionCode = STATUS_ARRAY_BOUNDS_EXCEEDED;
|
||||
}
|
||||
else if (ExceptionNr == 6)
|
||||
{
|
||||
Er.ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
Er.ExceptionCode = STATUS_ACCESS_VIOLATION;
|
||||
}
|
||||
Er.ExceptionFlags = 0;
|
||||
Er.ExceptionRecord = NULL;
|
||||
Er.ExceptionAddress = (PVOID)Tf->Eip;
|
||||
if (ExceptionNr == 14)
|
||||
{
|
||||
Er.NumberParameters = 2;
|
||||
Er.ExceptionInformation[0] = Tf->ErrorCode & 0x1;
|
||||
Er.ExceptionInformation[1] = (ULONG)Cr2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Er.NumberParameters = 0;
|
||||
}
|
||||
|
||||
KiDispatchException(&Er, 0, Tf, KernelMode, TRUE);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ULONG
|
||||
KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
|
||||
{
|
||||
|
@ -544,13 +599,17 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
|||
* Complete CPU context
|
||||
*/
|
||||
{
|
||||
unsigned int cr2, cr3;
|
||||
//#define SEH
|
||||
unsigned int cr2;
|
||||
#ifndef SEH
|
||||
unsigned int cr3;
|
||||
unsigned int i;
|
||||
ULONG StackLimit;
|
||||
PULONG Frame;
|
||||
#endif
|
||||
// unsigned int j, sym;
|
||||
NTSTATUS Status;
|
||||
ULONG Esp0;
|
||||
ULONG StackLimit;
|
||||
PULONG Frame;
|
||||
|
||||
/* Use the address of the trap frame as approximation to the ring0 esp */
|
||||
Esp0 = (ULONG)&Tf->Eip;
|
||||
|
@ -592,6 +651,7 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
|||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -601,6 +661,15 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
|||
{
|
||||
return(KiUserTrapHandler(Tf, ExceptionNr, (PVOID)cr2));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef SEH
|
||||
return(KiKernelTrapHandler(Tf, ExceptionNr, (PVOID)cr2));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef SEH
|
||||
|
||||
/*
|
||||
* Print out the CPU registers
|
||||
|
@ -678,6 +747,9 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
|||
}
|
||||
|
||||
for(;;);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
|
|
|
@ -70,6 +70,9 @@ KeApplicationProcessorInit(VOID)
|
|||
KPCR->Self = KPCR;
|
||||
KPCR->Irql = HIGH_LEVEL;
|
||||
|
||||
/* Mark the end of the exception handler list */
|
||||
KPCR->ExceptionList = (PVOID)-1;
|
||||
|
||||
/*
|
||||
* Initialize the GDT
|
||||
*/
|
||||
|
@ -123,6 +126,9 @@ KeInit1(VOID)
|
|||
KiPcrInitDone = 1;
|
||||
PcrsAllocated++;
|
||||
|
||||
/* Mark the end of the exception handler list */
|
||||
KPCR->ExceptionList = (PVOID)-1;
|
||||
|
||||
Ki386InitializeLdt();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <roscfg.h>
|
||||
#include <internal/ntoskrnl.h>
|
||||
#include <internal/i386/segment.h>
|
||||
#include <internal/ps.h>
|
||||
|
||||
#define KERNEL_BASE (0xc0000000)
|
||||
|
||||
|
@ -265,7 +266,7 @@ _multiboot_entry:
|
|||
*/
|
||||
movl $PCR_SELECTOR, %eax
|
||||
movl %eax, %fs
|
||||
|
||||
|
||||
/*
|
||||
* Load the initial kernel stack
|
||||
*/
|
||||
|
|
|
@ -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: syscall.S,v 1.2 2001/03/18 19:35:13 dwelch Exp $
|
||||
/* $Id: syscall.S,v 1.3 2001/09/24 00:51:17 chorns Exp $
|
||||
*
|
||||
* FILE: ntoskrnl/hal/x86/syscall.s
|
||||
* PURPOSE: 2E trap handler
|
||||
|
@ -52,7 +52,7 @@ _interrupt_handler2e:
|
|||
/* Save the old exception list */
|
||||
movl %fs:KPCR_EXCEPTION_LIST, %ebx
|
||||
pushl %ebx
|
||||
/* Put the exception handler chain terminator */
|
||||
/* Set the exception handler chain terminator */
|
||||
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
|
||||
/* Get a pointer to the current thread */
|
||||
movl %fs:KPCR_CURRENT_THREAD, %esi
|
||||
|
|
|
@ -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.10 2001/03/28 14:24:05 dwelch Exp $
|
||||
/* $Id: trap.s,v 1.11 2001/09/24 00:51:17 chorns Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/i386/trap.s
|
||||
|
@ -139,18 +139,22 @@ _KiTrapProlog:
|
|||
pushl $0 /* XXX: DebugEIP */
|
||||
pushl $0 /* XXX: DebugEBP */
|
||||
|
||||
/* Load the segment registers */
|
||||
/* Load the segment registers */
|
||||
movl $KERNEL_DS, %ebx
|
||||
movl %ebx, %ds
|
||||
movl %ebx, %es
|
||||
movl %ebx, %gs
|
||||
|
||||
/* Set ES to kernel segment */
|
||||
movw $KERNEL_DS,%bx
|
||||
movw %bx,%es
|
||||
/* Set ES to kernel segment */
|
||||
movw $KERNEL_DS,%bx
|
||||
movw %bx,%es
|
||||
|
||||
movl %esp, %ebx
|
||||
|
||||
/* Save a pointer to the trap frame in the current KTHREAD */
|
||||
movl %ebx, %ss:KTHREAD_TRAP_FRAME(%edi)
|
||||
|
||||
/* Call the C exception handler */
|
||||
movl %esp, %ebx
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
call _KiTrapHandler
|
||||
|
|
|
@ -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: main.c,v 1.106 2001/09/16 13:19:32 chorns Exp $
|
||||
/* $Id: main.c,v 1.107 2001/09/24 00:51:16 chorns Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/main.c
|
||||
|
@ -737,6 +737,172 @@ VOID DumpBIOSMemoryMap(VOID)
|
|||
|
||||
#endif /* !NDEBUG */
|
||||
|
||||
#if 1
|
||||
// SEH Test
|
||||
|
||||
static ULONG Scratch;
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
ExpUnhandledException1(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
PEXCEPTION_REGISTRATION ExceptionRegistration,
|
||||
PCONTEXT Context,
|
||||
PVOID DispatcherContext)
|
||||
{
|
||||
DbgPrint("ExpUnhandledException1() called\n");
|
||||
DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord);
|
||||
DbgPrint(" Flags 0x%X\n", ExceptionRecord->ExceptionFlags);
|
||||
DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration);
|
||||
DbgPrint("Context 0x%X\n", Context);
|
||||
DbgPrint("DispatcherContext 0x%X\n", DispatcherContext);
|
||||
|
||||
Context->Eax = (ULONG)&Scratch;
|
||||
|
||||
return ExceptionContinueExecution;
|
||||
}
|
||||
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
ExpUnhandledException2(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
PEXCEPTION_REGISTRATION ExceptionRegistration,
|
||||
PCONTEXT Context,
|
||||
PVOID DispatcherContext)
|
||||
{
|
||||
DbgPrint("ExpUnhandledException2() called\n");
|
||||
DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord);
|
||||
DbgPrint(" Flags 0x%X\n", ExceptionRecord->ExceptionFlags);
|
||||
DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration);
|
||||
DbgPrint("Context 0x%X\n", Context);
|
||||
DbgPrint("DispatcherContext 0x%X\n", DispatcherContext);
|
||||
|
||||
#if 1
|
||||
Context->Eax = (ULONG)&Scratch;
|
||||
|
||||
return ExceptionContinueExecution;
|
||||
|
||||
#else
|
||||
|
||||
return ExceptionContinueSearch;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if 1
|
||||
// Put in mingw headers
|
||||
extern VOID
|
||||
CDECL
|
||||
_local_unwind2(
|
||||
PEXCEPTION_REGISTRATION RegistrationFrame,
|
||||
DWORD TryLevel);
|
||||
|
||||
extern VOID
|
||||
CDECL
|
||||
_global_unwind2(
|
||||
PVOID RegistrationFrame);
|
||||
|
||||
extern EXCEPTION_DISPOSITION
|
||||
CDECL
|
||||
_except_handler2(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
PEXCEPTION_REGISTRATION RegistrationFrame,
|
||||
PCONTEXT Context,
|
||||
PVOID DispatcherContext);
|
||||
|
||||
extern EXCEPTION_DISPOSITION
|
||||
CDECL
|
||||
_except_handler3(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
PEXCEPTION_REGISTRATION RegistrationFrame,
|
||||
PCONTEXT Context,
|
||||
PVOID DispatcherContext);
|
||||
|
||||
#endif
|
||||
|
||||
PRTL_EXCEPTION_REGISTRATION
|
||||
CurrentRER(VOID)
|
||||
{
|
||||
ULONG Value;
|
||||
|
||||
__asm__("movl %%ebp, %0\n\t" : "=a" (Value));
|
||||
|
||||
return((PRTL_EXCEPTION_REGISTRATION)Value) - 1;
|
||||
}
|
||||
|
||||
PULONG x;
|
||||
PRTL_EXCEPTION_REGISTRATION TestER;
|
||||
SCOPETABLE_ENTRY ScopeTable;
|
||||
PEXCEPTION_REGISTRATION OSPtr;
|
||||
|
||||
|
||||
DWORD CDECL SEHFilterRoutine(VOID)
|
||||
{
|
||||
DbgPrint("Within filter routine.\n");
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
//return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
VOID CDECL SEHHandlerRoutine(VOID)
|
||||
{
|
||||
DbgPrint("Within exception handler.\n");
|
||||
DbgPrint("System halted.\n");
|
||||
for (;;);
|
||||
}
|
||||
|
||||
|
||||
VOID SEHTest()
|
||||
{
|
||||
RTL_EXCEPTION_REGISTRATION ER;
|
||||
LPEXCEPTION_POINTERS ExceptionPointers;
|
||||
PVOID StandardESPInFrame;
|
||||
|
||||
__asm__ ("movl %%esp,%%eax;" : "=a" (StandardESPInFrame));
|
||||
DbgPrint("StandardESPInFrame: 0x%X\n", StandardESPInFrame);
|
||||
|
||||
ExceptionPointers = NULL;
|
||||
|
||||
ER.OS.handler = _except_handler3;
|
||||
__asm__ ("movl %%fs:0,%%eax;" : "=a" (ER.OS.prev));
|
||||
DbgPrint("ER.OS.prev: 0x%X\n", ER.OS.prev);
|
||||
|
||||
ER.ScopeTable = &ScopeTable;
|
||||
DbgPrint("ER.ScopeTable: 0x%X\n", ER.ScopeTable);
|
||||
ER.TryLevel = -1;
|
||||
__asm__ ("movl %%ebp,%%eax;" : "=a" (ER.Ebp));
|
||||
DbgPrint("ER.Ebp: 0x%X\n", ER.Ebp);
|
||||
|
||||
ScopeTable.PreviousTryLevel = -1;
|
||||
ScopeTable.FilterRoutine = SEHFilterRoutine;
|
||||
DbgPrint("ScopeTable.FilterRoutine: 0x%X\n", ScopeTable.FilterRoutine);
|
||||
ScopeTable.HandlerRoutine = SEHHandlerRoutine;
|
||||
DbgPrint("ScopeTable.HandlerRoutine: 0x%X\n", ScopeTable.HandlerRoutine);
|
||||
|
||||
|
||||
OSPtr = &ER.OS;
|
||||
DbgPrint("OSPtr: 0x%X\n", OSPtr);
|
||||
|
||||
__asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (OSPtr));
|
||||
|
||||
/*__try1(__except_handler3)*/ if(1) {
|
||||
ER.TryLevel = 0; // Entered first try... block
|
||||
|
||||
DbgPrint("Within guarded section.\n");
|
||||
x = (PULONG)0xf2000000; *x = 0;
|
||||
DbgPrint("After exception.\n");
|
||||
} /* __except1 */ if(0) {
|
||||
}
|
||||
|
||||
DbgPrint("After exception2.\n");
|
||||
|
||||
__asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (ER.OS.prev));
|
||||
//KeGetCurrentKPCR()->ExceptionList = ER.OS.prev;
|
||||
|
||||
DbgPrint("Exiting.\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
VOID
|
||||
ExpInitializeExecutive(VOID)
|
||||
{
|
||||
|
@ -994,6 +1160,10 @@ ExpInitializeExecutive(VOID)
|
|||
*/
|
||||
InitSystemSharedUserPage ((PUCHAR)KeLoaderBlock.CommandLine);
|
||||
|
||||
#if 0
|
||||
SEHTest();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Launch initial process
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntoskrnl.def,v 1.114 2001/09/03 20:41:52 ea Exp $
|
||||
; $Id: ntoskrnl.def,v 1.115 2001/09/24 00:51:16 chorns Exp $
|
||||
;
|
||||
; reactos/ntoskrnl/ntoskrnl.def
|
||||
;
|
||||
|
@ -936,10 +936,11 @@ ZwYieldExecution@0
|
|||
;_aulldiv
|
||||
;_aullrem
|
||||
;_aullshr
|
||||
;_except_handler2
|
||||
;_global_unwind2
|
||||
_except_handler2
|
||||
_except_handler3
|
||||
_global_unwind2
|
||||
_itoa
|
||||
;_local_unwind2
|
||||
_local_unwind2
|
||||
;_purecall
|
||||
_snprintf
|
||||
_snwprintf
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntoskrnl.edf,v 1.100 2001/09/03 20:41:52 ea Exp $
|
||||
; $Id: ntoskrnl.edf,v 1.101 2001/09/24 00:51:16 chorns Exp $
|
||||
;
|
||||
; reactos/ntoskrnl/ntoskrnl.def
|
||||
;
|
||||
|
@ -934,10 +934,11 @@ ZwYieldExecution=ZwYieldExecution@0
|
|||
;_aulldiv
|
||||
;_aullrem
|
||||
;_aullshr
|
||||
;_except_handler2
|
||||
;_global_unwind2
|
||||
_except_handler2
|
||||
_except_handler3
|
||||
_global_unwind2
|
||||
_itoa
|
||||
;_local_unwind2
|
||||
_local_unwind2
|
||||
;_purecall
|
||||
_snprintf
|
||||
_snwprintf
|
||||
|
|
242
reactos/ntoskrnl/rtl/seh.c
Normal file
242
reactos/ntoskrnl/rtl/seh.c
Normal file
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/rtl/seh.c
|
||||
* PURPOSE: Compiler level Structured Exception Handling
|
||||
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* UPDATE HISTORY:
|
||||
* 2001/10/10 CSH Created
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntddk.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
CDECL
|
||||
_local_unwind2(
|
||||
PEXCEPTION_REGISTRATION RegistrationFrame,
|
||||
DWORD TryLevel)
|
||||
{
|
||||
PSCOPETABLE_ENTRY ScopeTableHead;
|
||||
PRTL_EXCEPTION_REGISTRATION RtlRegistrationFrame =
|
||||
(PRTL_EXCEPTION_REGISTRATION)RegistrationFrame;
|
||||
|
||||
DbgPrint("RegistrationFrame (0x%X) - TryLevel (0x%X)\n",
|
||||
RegistrationFrame, TryLevel);
|
||||
return;
|
||||
|
||||
ScopeTableHead = RtlRegistrationFrame->ScopeTable;
|
||||
|
||||
/* Begin traversing the list of SCOPETABLE_ENTRY */
|
||||
while ((ULONG_PTR)ScopeTableHead != -1)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CDECL
|
||||
_global_unwind2(
|
||||
PVOID RegistrationFrame)
|
||||
{
|
||||
RtlUnwind(RegistrationFrame, &&__return_label, NULL, 0);
|
||||
__return_label:;
|
||||
}
|
||||
|
||||
#if 1
|
||||
extern DWORD CDECL SEHFilterRoutine(VOID);
|
||||
extern VOID CDECL SEHHandlerRoutine(VOID);
|
||||
#endif
|
||||
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
CDECL
|
||||
_except_handler2(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
PEXCEPTION_REGISTRATION RegistrationFrame,
|
||||
PCONTEXT Context,
|
||||
PVOID DispatcherContext)
|
||||
{
|
||||
/* FIXME: */
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
CDECL
|
||||
_except_handler3(
|
||||
PEXCEPTION_RECORD ExceptionRecord,
|
||||
PEXCEPTION_REGISTRATION RegistrationFrame,
|
||||
PCONTEXT Context,
|
||||
PVOID DispatcherContext)
|
||||
{
|
||||
DWORD FilterFuncRet;
|
||||
DWORD TryLevel;
|
||||
EXCEPTION_POINTERS ExceptionPointers;
|
||||
//PSCOPETABLE_ENTRY pScopeTable;
|
||||
PSCOPETABLE_ENTRY ScopeTable;
|
||||
EXCEPTION_DISPOSITION ReturnValue;
|
||||
PVOID Handler;
|
||||
PVOID NewEBP;
|
||||
PRTL_EXCEPTION_REGISTRATION RtlRegistrationFrame =
|
||||
(PRTL_EXCEPTION_REGISTRATION)RegistrationFrame;
|
||||
|
||||
DPRINT("__except_handler3() called\n");
|
||||
DPRINT("ExceptionRecord 0x%X\n", ExceptionRecord);
|
||||
DPRINT(" ExceptionCode 0x%X\n", ExceptionRecord->ExceptionCode);
|
||||
DPRINT(" ExceptionFlags 0x%X\n", ExceptionRecord->ExceptionFlags);
|
||||
DPRINT("RegistrationFrame 0x%X\n", RegistrationFrame);
|
||||
DPRINT("Context 0x%X\n", Context);
|
||||
DPRINT("DispatcherContext 0x%X\n", DispatcherContext);
|
||||
|
||||
// Clear the direction flag (make no assumptions!)
|
||||
__asm__ ("cld");
|
||||
|
||||
// if neither the EXCEPTION_UNWINDING nor EXCEPTION_EXIT_UNWIND bit
|
||||
// is set... This is true the first time through the handler (the
|
||||
// non-unwinding case)
|
||||
|
||||
if (!(ExceptionRecord->ExceptionFlags
|
||||
& (EXCEPTION_UNWINDING|EXCEPTION_EXIT_UNWIND)))
|
||||
{
|
||||
DPRINT("Exception caught\n");
|
||||
|
||||
// Build the EXCEPTION_POINTERS structure on the stack
|
||||
ExceptionPointers.ExceptionRecord = ExceptionRecord;
|
||||
ExceptionPointers.ContextRecord = Context;
|
||||
|
||||
// Put the pointer to the EXCEPTION_POINTERS 4 bytes below the
|
||||
// establisher frame
|
||||
*(PDWORD)((ULONG_PTR)RtlRegistrationFrame - 4) = (ULONG_PTR)&ExceptionPointers;
|
||||
|
||||
// Get a pointer to the scopetable array
|
||||
ScopeTable = RtlRegistrationFrame->ScopeTable;
|
||||
|
||||
DPRINT("ScopeTable is at 0x%X\n", ScopeTable);
|
||||
|
||||
// Get initial "try-level" value
|
||||
TryLevel = RtlRegistrationFrame->TryLevel;
|
||||
|
||||
DPRINT("TryLevel is 0x%X\n", TryLevel);
|
||||
|
||||
search_for_handler:
|
||||
|
||||
DPRINT("RtlRegistrationFrame->TryLevel: 0x%X\n",
|
||||
RtlRegistrationFrame->TryLevel);
|
||||
|
||||
if (RtlRegistrationFrame->TryLevel != TRYLEVEL_NONE)
|
||||
{
|
||||
if (ScopeTable[TryLevel].FilterRoutine)
|
||||
{
|
||||
NewEBP = (PVOID)RtlRegistrationFrame->Ebp;
|
||||
Handler = (PVOID)ScopeTable[TryLevel].FilterRoutine;
|
||||
|
||||
DPRINT("Original EBP is: 0x%X\n", NewEBP);
|
||||
|
||||
DPRINT("Calling filter routine at 0x%X\n", Handler);
|
||||
|
||||
// Save this frame EBP
|
||||
__asm__ ("pushl %ebp");
|
||||
DPRINT("\n");
|
||||
// Switch to original EBP. This is what allows all locals in the
|
||||
// frame to have the same value as before the exception occurred.
|
||||
__asm__ ("movl %0,%%eax; movl %0,%%ebp; call _SEHFilterRoutine;" : : \
|
||||
"g" (Handler), \
|
||||
"g" (NewEBP));
|
||||
DPRINT("\n");
|
||||
|
||||
// Call the filter function
|
||||
//FilterFuncRet = ScopeTable[TryLevel].FilterRoutine();
|
||||
//FilterFuncRet = SEHFilterRoutine();
|
||||
DPRINT("\n");
|
||||
// Restore this frame EBP
|
||||
__asm__ ("popl %%ebp" : "=a" (FilterFuncRet));
|
||||
|
||||
DPRINT("FilterRoutine returned: 0x%X\n", FilterFuncRet);
|
||||
|
||||
if (FilterFuncRet != EXCEPTION_CONTINUE_SEARCH)
|
||||
{
|
||||
if (FilterFuncRet < 0) // EXCEPTION_CONTINUE_EXECUTION
|
||||
return ExceptionContinueExecution;
|
||||
|
||||
DPRINT("Filter routine said: execute handler\n");
|
||||
|
||||
// If we get here, EXCEPTION_EXECUTE_HANDLER was specified
|
||||
|
||||
// Does the actual OS cleanup of registration frames
|
||||
// Causes this function to recurse
|
||||
_global_unwind2(RtlRegistrationFrame);
|
||||
|
||||
_local_unwind2(RegistrationFrame, TryLevel);
|
||||
|
||||
// NLG == "non-local-goto" (setjmp/longjmp stuff)
|
||||
//__NLG_Notify( 1 ); // EAX == scopetable->lpfnHandler
|
||||
|
||||
// Set the current trylevel to whatever SCOPETABLE entry
|
||||
// was being used when a handler was found
|
||||
RtlRegistrationFrame->TryLevel = ScopeTable->PreviousTryLevel;
|
||||
|
||||
// Once we get here, everything is all cleaned up, except
|
||||
// for the last frame, where we'll continue execution
|
||||
|
||||
NewEBP = (PVOID)RtlRegistrationFrame->Ebp;
|
||||
Handler = (PVOID)ScopeTable[TryLevel].HandlerRoutine;
|
||||
|
||||
// Switch to original EBP and call the __except block.
|
||||
// If the function returns bugcheck the system.
|
||||
__asm__ ("movl %0,%%eax; movl %0,%%ebp; call _SEHHandlerRoutine;" : : \
|
||||
"g" (Handler), \
|
||||
"g" (NewEBP));
|
||||
|
||||
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
|
||||
}
|
||||
}
|
||||
|
||||
ScopeTable = RtlRegistrationFrame->ScopeTable;
|
||||
|
||||
DPRINT("ScopeTable is at 0x%X\n", ScopeTable);
|
||||
|
||||
TryLevel = ScopeTable->PreviousTryLevel;
|
||||
|
||||
DPRINT("TryLevel is 0x%X\n", TryLevel);
|
||||
|
||||
goto search_for_handler;
|
||||
}
|
||||
else // TryLevel == TRYLEVEL_NONE
|
||||
{
|
||||
ReturnValue = ExceptionContinueSearch;
|
||||
}
|
||||
}
|
||||
else // Either EXCEPTION_UNWINDING or EXCEPTION_EXIT_UNWIND flags is set
|
||||
{
|
||||
DPRINT("Local unwind\n");
|
||||
|
||||
// Save EBP
|
||||
__asm__ ("pushl %%ebp; movl %0,%%edx;" : : \
|
||||
"m" (RtlRegistrationFrame));
|
||||
|
||||
/* FIXME: Why is "addl $0x10,%%esp" needed? We only push 2*4 bytes, so why pop 16? */
|
||||
__asm__ ("pushl $-1; pushl %%edx; movl %0,%%ebp; call __local_unwind2; addl $0x10,%%esp;" : : \
|
||||
"m" (RtlRegistrationFrame->Ebp));
|
||||
|
||||
DPRINT("Local unwind3\n");
|
||||
|
||||
// Restore EBP for this frame
|
||||
__asm__ ("popl %ebp");
|
||||
|
||||
ReturnValue = ExceptionContinueSearch;
|
||||
}
|
||||
|
||||
DPRINT("ReturnValue 0x%X\n", ReturnValue);
|
||||
|
||||
return ReturnValue;
|
||||
}
|
||||
|
||||
/* EOF */
|
Loading…
Reference in a new issue