/* $Id: exceptions.h,v 1.5 2000-03-16 19:16:35 sandervl Exp $ */

#ifndef __EXCEPTIONS_H__
#define __EXCEPTIONS_H__

#include "win32type.h"
#include "misc.h"

#pragma pack(1)

//SetErrorMode flags
#define SEM_FAILCRITICALERRORS      0x0001
#define SEM_NOGPFAULTERRORBOX       0x0002
#define SEM_NOALIGNMENTFAULTEXCEPT  0x0004
#define SEM_NOOPENFILEERRORBOX      0x8000

/*
 * Exception codes
 */
 
#define STATUS_SUCCESS                   0x00000000
#define STATUS_WAIT_0                    0x00000000
#define STATUS_ABANDONED_WAIT_0          0x00000080
#define STATUS_USER_APC                  0x000000C0
#define STATUS_TIMEOUT                   0x00000102
#define STATUS_PENDING                   0x00000103
#define STATUS_GUARD_PAGE_VIOLATION      0x80000001    
#define STATUS_DATATYPE_MISALIGNMENT     0x80000002
#define STATUS_BREAKPOINT                0x80000003
#define STATUS_SINGLE_STEP               0x80000004
#define	STATUS_BUFFER_OVERFLOW           0x80000005
#define STATUS_UNSUCCESSFUL              0xC0000001
#define STATUS_ACCESS_VIOLATION          0xC0000005
#define STATUS_IN_PAGE_ERROR             0xC0000006
#define STATUS_INVALID_PARAMETER         0xC000000D
#define STATUS_NO_MEMORY                 0xC0000017
#define STATUS_CONFLICTING_ADDRESSES     0xC0000018
#define STATUS_ILLEGAL_INSTRUCTION       0xC000001D
#define	STATUS_BUFFER_TOO_SMALL          0xC0000023
#define STATUS_NONCONTINUABLE_EXCEPTION  0xC0000025
#define STATUS_INVALID_DISPOSITION       0xC0000026
#define STATUS_UNWIND                    0xC0000027
#define STATUS_BAD_STACK                 0xC0000028
#define STATUS_INVALID_UNWIND_TARGET     0xC0000029
#define	STATUS_UNKNOWN_REVISION          0xC0000058
#define	STATUS_INVALID_SECURITY_DESCR    0xC0000079
#define STATUS_ARRAY_BOUNDS_EXCEEDED     0xC000008C
#define STATUS_FLOAT_DENORMAL_OPERAND    0xC000008D
#define STATUS_FLOAT_DIVIDE_BY_ZERO      0xC000008E
#define STATUS_FLOAT_INEXACT_RESULT      0xC000008F
#define STATUS_FLOAT_INVALID_OPERATION   0xC0000090
#define STATUS_FLOAT_OVERFLOW            0xC0000091
#define STATUS_FLOAT_STACK_CHECK         0xC0000092
#define STATUS_FLOAT_UNDERFLOW           0xC0000093
#define STATUS_INTEGER_DIVIDE_BY_ZERO    0xC0000094
#define STATUS_INTEGER_OVERFLOW          0xC0000095
#define STATUS_PRIVILEGED_INSTRUCTION    0xC0000096
#define	STATUS_INVALID_PARAMETER_2       0xC00000F0
#define STATUS_STACK_OVERFLOW            0xC00000FD
#define STATUS_CONTROL_C_EXIT            0xC000013A

#define EXCEPTION_ACCESS_VIOLATION          	STATUS_ACCESS_VIOLATION
#define EXCEPTION_DATATYPE_MISALIGNMENT     	STATUS_DATATYPE_MISALIGNMENT
#define EXCEPTION_BREAKPOINT                	STATUS_BREAKPOINT
#define EXCEPTION_SINGLE_STEP               	STATUS_SINGLE_STEP
#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED     	STATUS_ARRAY_BOUNDS_EXCEEDED
#define EXCEPTION_FLT_DENORMAL_OPERAND      	STATUS_FLOAT_DENORMAL_OPERAND
#define EXCEPTION_FLT_DIVIDE_BY_ZERO        	STATUS_FLOAT_DIVIDE_BY_ZERO
#define EXCEPTION_FLT_INEXACT_RESULT        	STATUS_FLOAT_INEXACT_RESULT
#define EXCEPTION_FLT_INVALID_OPERATION     	STATUS_FLOAT_INVALID_OPERATION
#define EXCEPTION_FLT_OVERFLOW              	STATUS_FLOAT_OVERFLOW
#define EXCEPTION_FLT_STACK_CHECK           	STATUS_FLOAT_STACK_CHECK
#define EXCEPTION_FLT_UNDERFLOW             	STATUS_FLOAT_UNDERFLOW
#define EXCEPTION_INT_DIVIDE_BY_ZERO        	STATUS_INTEGER_DIVIDE_BY_ZERO
#define EXCEPTION_INT_OVERFLOW              	STATUS_INTEGER_OVERFLOW
#define EXCEPTION_PRIV_INSTRUCTION          	STATUS_PRIVILEGED_INSTRUCTION
#define EXCEPTION_IN_PAGE_ERROR             	STATUS_IN_PAGE_ERROR
#define EXCEPTION_ILLEGAL_INSTRUCTION       	STATUS_ILLEGAL_INSTRUCTION
#define EXCEPTION_NONCONTINUABLE_EXCEPTION  	STATUS_NONCONTINUABLE_EXCEPTION
#define EXCEPTION_STACK_OVERFLOW            	STATUS_STACK_OVERFLOW
#define EXCEPTION_INVALID_DISPOSITION       	STATUS_INVALID_DISPOSITION
#define EXCEPTION_GUARD_PAGE                	STATUS_GUARD_PAGE_VIOLATION
#define EXCEPTION_INVALID_HANDLE            	STATUS_INVALID_HANDLE
#define CONTROL_C_EXIT                      	STATUS_CONTROL_C_EXIT

#define MAXIMUM_WAIT_OBJECTS 			64
#define MAXIMUM_SUSPEND_COUNT 			127

#define WINCONTEXT_i386      0x00010000
#define WINCONTEXT_i486      WINCONTEXT_i386
#define WINCONTEXT_CONTROL   (WINCONTEXT_i386 | 0x0001) 
#define WINCONTEXT_INTEGER   (WINCONTEXT_i386 | 0x0002) 
#define WINCONTEXT_SEGMENTS  (WINCONTEXT_i386 | 0x0004) 
#define WINCONTEXT_FLOATING_POINT  (WINCONTEXT_i386 | 0x0008L) 
#define WINCONTEXT_DEBUG_REGISTERS (WINCONTEXT_i386 | 0x0010L) 
#define WINCONTEXT_FULL (WINCONTEXT_CONTROL | WINCONTEXT_INTEGER | WINCONTEXT_SEGMENTS)

#define SIZE_OF_80387_REGISTERS      80

typedef struct
{
    DWORD   ControlWord;
    DWORD   StatusWord;
    DWORD   TagWord;
    DWORD   ErrorOffset;
    DWORD   ErrorSelector;
    DWORD   DataOffset;
    DWORD   DataSelector;
    BYTE    RegisterArea[SIZE_OF_80387_REGISTERS];
    DWORD   Cr0NpxState;
} FLOATING_SAVE_AREA_WIN;

typedef struct
{
    DWORD   ContextFlags;

    DWORD   Dr0;
    DWORD   Dr1;
    DWORD   Dr2;
    DWORD   Dr3;
    DWORD   Dr6;
    DWORD   Dr7;

    FLOATING_SAVE_AREA_WIN 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;
} WINCONTEXT, *PWINCONTEXT;


#define WINEXCEPTION_NONCONTINUABLE     0x1    
#define WINEXCEPTION_MAXIMUM_PARAMETERS 15     

typedef struct _WINEXCEPTION_RECORD {
    DWORD    ExceptionCode;
    DWORD ExceptionFlags;
    struct _WINEXCEPTION_RECORD *ExceptionRecord;
    PVOID ExceptionAddress;
    DWORD NumberParameters;
    DWORD ExceptionInformation[WINEXCEPTION_MAXIMUM_PARAMETERS];
} WINEXCEPTION_RECORD;
typedef WINEXCEPTION_RECORD *PWINEXCEPTION_RECORD;

typedef struct _WINEXCEPTION_POINTERS {
    PWINEXCEPTION_RECORD ExceptionRecord;
    PWINCONTEXT          ContextRecord;
} WINEXCEPTION_POINTERS, *PWINEXCEPTION_POINTERS;

//forward declaration
struct __EXCEPTION_FRAME;

typedef DWORD (* WIN32API PEXCEPTION_HANDLER)(PWINEXCEPTION_RECORD,
                                              struct _WINEXCEPTION_FRAME *,
                                          PWINCONTEXT, LPVOID);

typedef struct _WINEXCEPTION_FRAME
{
  struct _WINEXCEPTION_FRAME *Prev;
  PEXCEPTION_HANDLER          Handler;
} WINEXCEPTION_FRAME, *PWINEXCEPTION_FRAME;

/*
 * Return values from the actual exception handlers
 */

#define ExceptionContinueExecution 0
#define ExceptionContinueSearch    1
#define ExceptionNestedException   2
#define ExceptionCollidedUnwind    3

typedef PWINCONTEXT            LPWINCONTEXT;
typedef PWINEXCEPTION_RECORD   LPWINEXCEPTION_RECORD;
typedef PWINEXCEPTION_POINTERS LPWINEXCEPTION_POINTERS;

typedef LONG (* WIN32API PTOP_LEVEL_EXCEPTION_FILTER)(struct _WINEXCEPTION_POINTERS *ExceptionInfo);

typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;


/*
 * Return values from filters in except() and from UnhandledExceptionFilter
 */
 
#define WINEXCEPTION_EXECUTE_HANDLER        1
#define WINEXCEPTION_CONTINUE_SEARCH        0
#define WINEXCEPTION_CONTINUE_EXECUTION    -1

#define STATUS_INVALID_DISPOSITION       0xC0000026

#pragma pack()

DWORD RtlDispatchException(WINEXCEPTION_RECORD *pRecord, WINCONTEXT *pContext);

#endif