reactos/sdk/include/wine/exception.h

146 lines
4.2 KiB
C
Raw Normal View History

#ifndef __WINE_WINE_EXCEPTION_H
#define __WINE_WINE_EXCEPTION_H
#include <setjmp.h>
#include <intrin.h>
#include <excpt.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD */
#define EH_NONCONTINUABLE 0x01
#define EH_UNWINDING 0x02
#define EH_EXIT_UNWIND 0x04
#define EH_STACK_INVALID 0x08
#define EH_NESTED_CALL 0x10
#define EH_TARGET_UNWIND 0x20
#define EH_COLLIDED_UNWIND 0x40
#define EXCEPTION_WINE_STUB 0x80000100
#define EXCEPTION_WINE_ASSERTION 0x80000101
#define EXCEPTION_VM86_INTx 0x80000110
#define EXCEPTION_VM86_STI 0x80000111
#define EXCEPTION_VM86_PICRETURN 0x80000112
#ifndef _RTLTYPES_H
struct _EXCEPTION_REGISTRATION_RECORD;
typedef
DWORD
(*PEXCEPTION_HANDLER)(
struct _EXCEPTION_RECORD*,
struct _EXCEPTION_REGISTRATION_RECORD *,
struct _CONTEXT*,
struct _EXCEPTION_REGISTRATION_RECORD**);
typedef struct _EXCEPTION_REGISTRATION_RECORD EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD;
struct _EXCEPTION_REGISTRATION_RECORD
Major refactoring of the exception handling code + misc fixes: - Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind - Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE - Add w32api excpt.h (based on mingw) with PSDK compatibility fixes - Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes - Fix KiUserExceptionDispatcher - Remove useless NTDLL entrypoint - Implement NTDLL Ki* callbacks in ASM - Implement RtlCaptureContext - Fix RtlRaiseException to handle cases when a user-mode debugger is present - Fix RtlRaiseStatus as above, plus set the exception address and capture context - Little cleanup of RTL headers - Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM - Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of Context. - Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL. - Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some optimizations to increase speed. - Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to support a PKEXCEPTION_FRAME for future PPC compatibility. - Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them. - Export ExRaiseStatus/Exception as Rtl* - Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context and parameters with SEH. - Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack. - Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the user-mode callback. - Implement KiUnexpectedInterrupt and KiCoprocessorError - Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the stack when called through System call interface. - Fix Ntcontinue to respect AlertThread paramter - Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed - Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context flags,... - Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any exceptions (the kernel-mode code to handle this isn't written yet though) svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
{
struct _EXCEPTION_REGISTRATION_RECORD * Prev;
PEXCEPTION_HANDLER Handler;
};
#else
typedef struct _WINE_EXCEPTION_REGISTRATION_RECORD
{
PVOID Prev;
PEXCEPTION_ROUTINE Handler;
} WINE_EXCEPTION_REGISTRATION_RECORD, *PWINE_EXCEPTION_REGISTRATION_RECORD;
#define _EXCEPTION_REGISTRATION_RECORD _WINE_EXCEPTION_REGISTRATION_RECORD
#define EXCEPTION_REGISTRATION_RECORD WINE_EXCEPTION_REGISTRATION_RECORD
#define PEXCEPTION_REGISTRATION_RECORD PWINE_EXCEPTION_REGISTRATION_RECORD
#endif
2025-05-07 20:00:29 +03:00
#define __TRY _SEH2_TRY {
#define __EXCEPT(func) } _SEH2_EXCEPT(func(_SEH2_GetExceptionInformation())) {
#define __EXCEPT_CTX(func, ctx) } _SEH2_EXCEPT((func)(GetExceptionInformation(), ctx)) {
#define __EXCEPT_PAGE_FAULT } _SEH2_EXCEPT(_SEH2_GetExceptionCode() == STATUS_ACCESS_VIOLATION) {
#define __EXCEPT_ALL } _SEH2_EXCEPT(1) {
#define __ENDTRY } _SEH2_END
#define __FINALLY(func) } _SEH2_FINALLY { func(!_SEH2_AbnormalTermination()); } {
#define __FINALLY_CTX(func, ctx) } _SEH2_FINALLY { func(!_SEH2_AbnormalTermination(), ctx); }; _SEH2_END
#ifndef GetExceptionCode
#define GetExceptionCode() _SEH2_GetExceptionCode()
Sync to Wine-20050524: Alexandre Julliard <julliard@winehq.org> - Free delayed import modules on PROCESS_DETACH. - Removed no longer used support for 32-bit register entry points. - Added support in winebuild for specifying import libraries directly on the command line without the -l option. - Changed the -d option to only mark the library as delayed, the actual loading is now done separately. - Generate 16-bit resources in the proper format inside the module data, and get rid of the special case for builtins in NE_DefResourceHandler. - Generate the 16-bit module header in the standard on-disk format, so that winebuild doesn't need to know about kernel internal structures. - Moved the generated code segment for 16-bit builtins inside the module structure. - Get rid of the BUILTIN16_DESCRIPTOR structure and directly register the MZ header instead. - Use RaiseException instead of RtlRaiseException in 16-bit spec files since they already depend on kernel32. - Renamed __wine_(un)register_dll_16 to __wine_dll_(un)register_16 for consistency with the 32-bit version, and also make the register function use the same prototype as the 32-bit one. - Use the exported IMAGE_OS2_HEADER to generate the module header in the spec file, and moved the NE_MODULE structure definition to kernel16_private.h. - Avoid referencing stackframe.h from outside kernel32. - Moved data structures for 16-bit relay calls to winbase16.h and removed builtin16.h. - Store the 16-bit stack pointer in the WOW32Reserved TEB field. - Use RaiseException instead of RtlRaiseException for delayed entry points load failure to avoid creating a dependency on ntdll. svn path=/trunk/; revision=15499
2005-05-26 09:44:59 +00:00
#endif
#ifndef GetExceptionInformation
#define GetExceptionInformation() _SEH2_GetExceptionInformation()
#endif
#ifndef AbnormalTermination
#define AbnormalTermination() _SEH2_AbnormalTermination()
#endif
#if defined(__MINGW32__) || defined(__CYGWIN__)
#define sigjmp_buf jmp_buf
#define sigsetjmp(buf,sigs) setjmp(buf)
#define siglongjmp(buf,val) longjmp(buf,val)
#endif
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4733)
#endif
2025-05-07 20:00:29 +03:00
#ifndef __wine_jmp_buf // Conflict with CRT hack
#ifdef __i386__
typedef struct { int reg[16]; } __wine_jmp_buf;
#elif defined(__x86_64__)
typedef struct { DECLSPEC_ALIGN(16) struct { unsigned __int64 Part[2]; } reg[16]; } __wine_jmp_buf;
#elif defined(__arm__)
typedef struct { int reg[28]; } __wine_jmp_buf;
#elif defined(__aarch64__)
typedef struct { __int64 reg[24]; } __wine_jmp_buf;
#else
typedef struct { int reg; } __wine_jmp_buf;
#endif
#endif
DECLSPEC_NORETURN extern void __cdecl __wine_longjmp( __wine_jmp_buf *buf, int retval );
DECLSPEC_NORETURN extern void __cdecl __wine_rtl_unwind( EXCEPTION_REGISTRATION_RECORD* frame, EXCEPTION_RECORD *record,
void (*target)(void) );
static inline EXCEPTION_REGISTRATION_RECORD *__wine_push_frame( EXCEPTION_REGISTRATION_RECORD *frame )
{
#ifdef __i386__
frame->Prev = (struct _EXCEPTION_REGISTRATION_RECORD *)__readfsdword(0);
__writefsdword(0, (unsigned long)frame);
return frame->Prev;
#else
NT_TIB *teb = (NT_TIB *)NtCurrentTeb();
frame->Prev = teb->ExceptionList;
teb->ExceptionList = (PVOID)frame;
return frame->Prev;
#endif
}
static inline EXCEPTION_REGISTRATION_RECORD *__wine_pop_frame( EXCEPTION_REGISTRATION_RECORD *frame )
{
#ifdef __i386__
__writefsdword(0, (unsigned long)frame->Prev);
return frame->Prev;
#else
NT_TIB *teb = (NT_TIB *)NtCurrentTeb();
frame->Prev = teb->ExceptionList;
teb->ExceptionList = (PVOID)frame;
return frame->Prev;
#endif
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
extern void __wine_enter_vm86( CONTEXT *context );
#ifdef __cplusplus
}
#endif
#endif