mirror of
https://github.com/reactos/reactos.git
synced 2024-08-15 08:03:55 +00:00
Initial OS level SEH support.
svn path=/trunk/; revision=2256
This commit is contained in:
parent
2eb7adef67
commit
0948ab6596
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -308,17 +747,6 @@ typedef struct value_ent {
|
||||||
DWORD ve_type;
|
DWORD ve_type;
|
||||||
} WVALENT, *PWVALENT;
|
} 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 long *PLONG;
|
||||||
|
|
||||||
typedef const void *LPCVOID;
|
typedef const void *LPCVOID;
|
||||||
|
@ -360,4 +788,8 @@ VOID
|
||||||
DWORD dwTimerHighValue
|
DWORD dwTimerHighValue
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#include <ntos/except.h>
|
||||||
|
|
||||||
#endif /* __INCLUDE_ACPI_TYPES_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
|
VOID
|
||||||
STDCALL
|
STDCALL
|
||||||
RtlUnwind (
|
RtlUnwind (
|
||||||
ULONG Unknown1,
|
PEXCEPTION_REGISTRATION RegistrationFrame,
|
||||||
ULONG Unknown2,
|
PVOID ReturnAddress,
|
||||||
ULONG Unknown3,
|
PEXCEPTION_RECORD ExceptionRecord,
|
||||||
ULONG Unknown4
|
DWORD EaxValue
|
||||||
);
|
);
|
||||||
|
|
||||||
WCHAR
|
WCHAR
|
||||||
|
|
|
@ -373,22 +373,12 @@ typedef struct
|
||||||
typedef HANDLE *PHANDLE;
|
typedef HANDLE *PHANDLE;
|
||||||
|
|
||||||
typedef struct value_ent {
|
typedef struct value_ent {
|
||||||
LPWSTR ve_valuename;
|
LPWSTR ve_valuename;
|
||||||
DWORD ve_valuelen;
|
DWORD ve_valuelen;
|
||||||
DWORD ve_valueptr;
|
DWORD ve_valueptr;
|
||||||
DWORD ve_type;
|
DWORD ve_type;
|
||||||
} WVALENT, *PWVALENT;
|
} 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 const void *LPCVOID;
|
||||||
typedef BYTE *LPBYTE, *PBYTE;
|
typedef BYTE *LPBYTE, *PBYTE;
|
||||||
|
@ -428,4 +418,6 @@ typedef VOID STDCALL
|
||||||
DWORD dwTimerHighValue
|
DWORD dwTimerHighValue
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#include "except.h"
|
||||||
|
|
||||||
#endif /* __INCLUDE_TYPES_H */
|
#endif /* __INCLUDE_TYPES_H */
|
||||||
|
|
|
@ -1872,11 +1872,6 @@ typedef struct tagEVENTMSG {
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
} EVENTMSG;
|
} EVENTMSG;
|
||||||
|
|
||||||
typedef struct _EXCEPTION_POINTERS {
|
|
||||||
PEXCEPTION_RECORD ExceptionRecord;
|
|
||||||
PCONTEXT ContextRecord;
|
|
||||||
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS, *LPEXCEPTION_POINTERS;
|
|
||||||
|
|
||||||
typedef struct _EXT_BUTTON {
|
typedef struct _EXT_BUTTON {
|
||||||
WORD idCommand;
|
WORD idCommand;
|
||||||
WORD idsHelp;
|
WORD idsHelp;
|
||||||
|
|
|
@ -1,13 +1,5 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
typedef enum _EXCEPTION_DISPOSITION {
|
|
||||||
ExceptionContinueExecution,
|
|
||||||
ExceptionContinueSearch,
|
|
||||||
ExceptionNestedException,
|
|
||||||
ExceptionCollidedUnwind
|
|
||||||
} EXCEPTION_DISPOSITION;
|
|
||||||
|
|
||||||
|
|
||||||
EXCEPTION_DISPOSITION
|
EXCEPTION_DISPOSITION
|
||||||
_except_handler2(
|
_except_handler2(
|
||||||
struct _EXCEPTION_RECORD *ExceptionRecord,
|
struct _EXCEPTION_RECORD *ExceptionRecord,
|
||||||
|
|
|
@ -1,13 +1,5 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
typedef enum _EXCEPTION_DISPOSITION {
|
|
||||||
ExceptionContinueExecution,
|
|
||||||
ExceptionContinueSearch,
|
|
||||||
ExceptionNestedException,
|
|
||||||
ExceptionCollidedUnwind
|
|
||||||
} EXCEPTION_DISPOSITION;
|
|
||||||
|
|
||||||
|
|
||||||
EXCEPTION_DISPOSITION
|
EXCEPTION_DISPOSITION
|
||||||
_except_handler3(
|
_except_handler3(
|
||||||
struct _EXCEPTION_RECORD *ExceptionRecord,
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -64,10 +64,10 @@ RtlRaiseStatus(NTSTATUS Status)
|
||||||
|
|
||||||
|
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
RtlUnwind(ULONG Unknown1,
|
RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame,
|
||||||
ULONG Unknown2,
|
PVOID ReturnAddress,
|
||||||
ULONG Unknown3,
|
PEXCEPTION_RECORD ExceptionRecord,
|
||||||
ULONG Unknown4)
|
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
|
# ReactOS Operating System
|
||||||
#
|
#
|
||||||
|
@ -94,6 +94,7 @@ OBJECTS_RTL = \
|
||||||
rtl/nls.o \
|
rtl/nls.o \
|
||||||
rtl/qsort.o \
|
rtl/qsort.o \
|
||||||
rtl/regio.o \
|
rtl/regio.o \
|
||||||
|
rtl/seh.o \
|
||||||
rtl/sprintf.o \
|
rtl/sprintf.o \
|
||||||
rtl/stdlib.o \
|
rtl/stdlib.o \
|
||||||
rtl/string.o \
|
rtl/string.o \
|
||||||
|
|
|
@ -183,7 +183,7 @@ NtEarlyInitVdm(VOID);
|
||||||
VOID
|
VOID
|
||||||
KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Eip);
|
KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Eip);
|
||||||
VOID
|
VOID
|
||||||
KiDispatchException(PEXCEPTION_RECORD Er,
|
KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
PCONTEXT Context,
|
PCONTEXT Context,
|
||||||
PKTRAP_FRAME Tf,
|
PKTRAP_FRAME Tf,
|
||||||
KPROCESSOR_MODE PreviousMode,
|
KPROCESSOR_MODE PreviousMode,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ke/catch.c
|
* FILE: ntoskrnl/ke/catch.c
|
||||||
|
@ -31,19 +31,173 @@
|
||||||
#include <internal/ldr.h>
|
#include <internal/ldr.h>
|
||||||
#include <internal/ps.h>
|
#include <internal/ps.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* 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
|
VOID
|
||||||
KiDispatchException(PEXCEPTION_RECORD Er,
|
KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
PCONTEXT Context,
|
PCONTEXT Context,
|
||||||
PKTRAP_FRAME Tf,
|
PKTRAP_FRAME Tf,
|
||||||
KPROCESSOR_MODE PreviousMode,
|
KPROCESSOR_MODE PreviousMode,
|
||||||
BOOLEAN SearchFrames)
|
BOOLEAN SearchFrames)
|
||||||
{
|
{
|
||||||
|
EXCEPTION_DISPOSITION Value;
|
||||||
CONTEXT TContext;
|
CONTEXT TContext;
|
||||||
|
|
||||||
|
DPRINT("KiDispatchException() called \n");
|
||||||
/* PCR->KeExceptionDispatchCount++; */
|
/* PCR->KeExceptionDispatchCount++; */
|
||||||
|
|
||||||
if (Context == NULL)
|
if (Context == NULL)
|
||||||
|
@ -59,7 +213,7 @@ KiDispatchException(PEXCEPTION_RECORD Er,
|
||||||
Context = &TContext;
|
Context = &TContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Er->ExceptionCode == STATUS_BREAKPOINT)
|
if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT)
|
||||||
{
|
{
|
||||||
Context->Eip--;
|
Context->Eip--;
|
||||||
}
|
}
|
||||||
|
@ -91,7 +245,7 @@ KiDispatchException(PEXCEPTION_RECORD Er,
|
||||||
Stack[1] = (ULONG)&Stack[3];
|
Stack[1] = (ULONG)&Stack[3];
|
||||||
/* Pointer to CONTEXT structure */
|
/* Pointer to CONTEXT structure */
|
||||||
Stack[2] = (ULONG)&Stack[CDest];
|
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));
|
memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
|
||||||
|
|
||||||
Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
|
Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
|
||||||
|
@ -103,14 +257,24 @@ KiDispatchException(PEXCEPTION_RECORD Er,
|
||||||
/* FIXME: Forward the exception to the process exception port */
|
/* FIXME: Forward the exception to the process exception port */
|
||||||
|
|
||||||
/* Terminate the offending thread */
|
/* Terminate the offending thread */
|
||||||
ZwTerminateThread(NtCurrentThread(), Er->ExceptionCode);
|
ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
|
||||||
|
|
||||||
/* If that fails then bugcheck */
|
/* If that fails then bugcheck */
|
||||||
|
DbgPrint("Could not terminate thread\n");
|
||||||
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
|
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
|
||||||
}
|
}
|
||||||
else
|
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
|
VOID STDCALL
|
||||||
ExRaiseStatus (IN NTSTATUS Status)
|
ExRaiseStatus (IN NTSTATUS Status)
|
||||||
{
|
{
|
||||||
DbgPrint("ExRaiseStatus(%x)\n",Status);
|
EXCEPTION_RECORD ExceptionRecord;
|
||||||
KeBugCheck(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
DPRINT("ExRaiseStatus(%x)\n", Status);
|
||||||
|
|
||||||
|
ExceptionRecord.ExceptionRecord = NULL;
|
||||||
|
ExceptionRecord.NumberParameters = 0;
|
||||||
|
ExceptionRecord.ExceptionCode = Status;
|
||||||
|
ExceptionRecord.ExceptionFlags = 0;
|
||||||
|
|
||||||
|
RtlRaiseException(&ExceptionRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
|
@ -152,17 +323,277 @@ NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord,
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
|
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
|
VOID STDCALL
|
||||||
RtlUnwind(ULONG Unknown1,
|
RtlUnwind(
|
||||||
ULONG Unknown2,
|
PEXCEPTION_REGISTRATION RegistrationFrame,
|
||||||
ULONG Unknown3,
|
PVOID ReturnAddress,
|
||||||
ULONG Unknown4)
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -307,6 +307,61 @@ KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
ULONG
|
||||||
KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
|
KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
|
||||||
{
|
{
|
||||||
|
@ -544,13 +599,17 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
||||||
* Complete CPU context
|
* Complete CPU context
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned int cr2, cr3;
|
//#define SEH
|
||||||
|
unsigned int cr2;
|
||||||
|
#ifndef SEH
|
||||||
|
unsigned int cr3;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
ULONG StackLimit;
|
||||||
|
PULONG Frame;
|
||||||
|
#endif
|
||||||
// unsigned int j, sym;
|
// unsigned int j, sym;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG Esp0;
|
ULONG Esp0;
|
||||||
ULONG StackLimit;
|
|
||||||
PULONG Frame;
|
|
||||||
|
|
||||||
/* Use the address of the trap frame as approximation to the ring0 esp */
|
/* Use the address of the trap frame as approximation to the ring0 esp */
|
||||||
Esp0 = (ULONG)&Tf->Eip;
|
Esp0 = (ULONG)&Tf->Eip;
|
||||||
|
@ -592,6 +651,7 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
||||||
{
|
{
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -601,6 +661,15 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
||||||
{
|
{
|
||||||
return(KiUserTrapHandler(Tf, ExceptionNr, (PVOID)cr2));
|
return(KiUserTrapHandler(Tf, ExceptionNr, (PVOID)cr2));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef SEH
|
||||||
|
return(KiKernelTrapHandler(Tf, ExceptionNr, (PVOID)cr2));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SEH
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print out the CPU registers
|
* Print out the CPU registers
|
||||||
|
@ -678,6 +747,9 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
||||||
}
|
}
|
||||||
|
|
||||||
for(;;);
|
for(;;);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -70,6 +70,9 @@ KeApplicationProcessorInit(VOID)
|
||||||
KPCR->Self = KPCR;
|
KPCR->Self = KPCR;
|
||||||
KPCR->Irql = HIGH_LEVEL;
|
KPCR->Irql = HIGH_LEVEL;
|
||||||
|
|
||||||
|
/* Mark the end of the exception handler list */
|
||||||
|
KPCR->ExceptionList = (PVOID)-1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the GDT
|
* Initialize the GDT
|
||||||
*/
|
*/
|
||||||
|
@ -123,6 +126,9 @@ KeInit1(VOID)
|
||||||
KiPcrInitDone = 1;
|
KiPcrInitDone = 1;
|
||||||
PcrsAllocated++;
|
PcrsAllocated++;
|
||||||
|
|
||||||
|
/* Mark the end of the exception handler list */
|
||||||
|
KPCR->ExceptionList = (PVOID)-1;
|
||||||
|
|
||||||
Ki386InitializeLdt();
|
Ki386InitializeLdt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <roscfg.h>
|
#include <roscfg.h>
|
||||||
#include <internal/ntoskrnl.h>
|
#include <internal/ntoskrnl.h>
|
||||||
#include <internal/i386/segment.h>
|
#include <internal/i386/segment.h>
|
||||||
|
#include <internal/ps.h>
|
||||||
|
|
||||||
#define KERNEL_BASE (0xc0000000)
|
#define KERNEL_BASE (0xc0000000)
|
||||||
|
|
||||||
|
@ -265,7 +266,7 @@ _multiboot_entry:
|
||||||
*/
|
*/
|
||||||
movl $PCR_SELECTOR, %eax
|
movl $PCR_SELECTOR, %eax
|
||||||
movl %eax, %fs
|
movl %eax, %fs
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load the initial kernel stack
|
* Load the initial kernel stack
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* FILE: ntoskrnl/hal/x86/syscall.s
|
||||||
* PURPOSE: 2E trap handler
|
* PURPOSE: 2E trap handler
|
||||||
|
@ -52,7 +52,7 @@ _interrupt_handler2e:
|
||||||
/* Save the old exception list */
|
/* Save the old exception list */
|
||||||
movl %fs:KPCR_EXCEPTION_LIST, %ebx
|
movl %fs:KPCR_EXCEPTION_LIST, %ebx
|
||||||
pushl %ebx
|
pushl %ebx
|
||||||
/* Put the exception handler chain terminator */
|
/* Set the exception handler chain terminator */
|
||||||
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
|
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
|
||||||
/* Get a pointer to the current thread */
|
/* Get a pointer to the current thread */
|
||||||
movl %fs:KPCR_CURRENT_THREAD, %esi
|
movl %fs:KPCR_CURRENT_THREAD, %esi
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ke/i386/trap.s
|
* FILE: ntoskrnl/ke/i386/trap.s
|
||||||
|
@ -139,18 +139,22 @@ _KiTrapProlog:
|
||||||
pushl $0 /* XXX: DebugEIP */
|
pushl $0 /* XXX: DebugEIP */
|
||||||
pushl $0 /* XXX: DebugEBP */
|
pushl $0 /* XXX: DebugEBP */
|
||||||
|
|
||||||
/* Load the segment registers */
|
/* Load the segment registers */
|
||||||
movl $KERNEL_DS, %ebx
|
movl $KERNEL_DS, %ebx
|
||||||
movl %ebx, %ds
|
movl %ebx, %ds
|
||||||
movl %ebx, %es
|
movl %ebx, %es
|
||||||
movl %ebx, %gs
|
movl %ebx, %gs
|
||||||
|
|
||||||
/* Set ES to kernel segment */
|
/* Set ES to kernel segment */
|
||||||
movw $KERNEL_DS,%bx
|
movw $KERNEL_DS,%bx
|
||||||
movw %bx,%es
|
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 */
|
/* Call the C exception handler */
|
||||||
movl %esp, %ebx
|
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %ebx
|
pushl %ebx
|
||||||
call _KiTrapHandler
|
call _KiTrapHandler
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ke/main.c
|
* FILE: ntoskrnl/ke/main.c
|
||||||
|
@ -737,6 +737,172 @@ VOID DumpBIOSMemoryMap(VOID)
|
||||||
|
|
||||||
#endif /* !NDEBUG */
|
#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
|
VOID
|
||||||
ExpInitializeExecutive(VOID)
|
ExpInitializeExecutive(VOID)
|
||||||
{
|
{
|
||||||
|
@ -994,6 +1160,10 @@ ExpInitializeExecutive(VOID)
|
||||||
*/
|
*/
|
||||||
InitSystemSharedUserPage ((PUCHAR)KeLoaderBlock.CommandLine);
|
InitSystemSharedUserPage ((PUCHAR)KeLoaderBlock.CommandLine);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
SEHTest();
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Launch initial process
|
* 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
|
; reactos/ntoskrnl/ntoskrnl.def
|
||||||
;
|
;
|
||||||
|
@ -936,10 +936,11 @@ ZwYieldExecution@0
|
||||||
;_aulldiv
|
;_aulldiv
|
||||||
;_aullrem
|
;_aullrem
|
||||||
;_aullshr
|
;_aullshr
|
||||||
;_except_handler2
|
_except_handler2
|
||||||
;_global_unwind2
|
_except_handler3
|
||||||
|
_global_unwind2
|
||||||
_itoa
|
_itoa
|
||||||
;_local_unwind2
|
_local_unwind2
|
||||||
;_purecall
|
;_purecall
|
||||||
_snprintf
|
_snprintf
|
||||||
_snwprintf
|
_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
|
; reactos/ntoskrnl/ntoskrnl.def
|
||||||
;
|
;
|
||||||
|
@ -934,10 +934,11 @@ ZwYieldExecution=ZwYieldExecution@0
|
||||||
;_aulldiv
|
;_aulldiv
|
||||||
;_aullrem
|
;_aullrem
|
||||||
;_aullshr
|
;_aullshr
|
||||||
;_except_handler2
|
_except_handler2
|
||||||
;_global_unwind2
|
_except_handler3
|
||||||
|
_global_unwind2
|
||||||
_itoa
|
_itoa
|
||||||
;_local_unwind2
|
_local_unwind2
|
||||||
;_purecall
|
;_purecall
|
||||||
_snprintf
|
_snprintf
|
||||||
_snwprintf
|
_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