From 54b1d87daff4f649cf5c532e89c3e5f93b9ec611 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 28 Oct 2003 21:22:50 +0000 Subject: [PATCH] Implemented Add/RemoveVectoredExceptionHandler. --- dlls/kernel/kernel32.spec | 2 + dlls/ntdll/exception.c | 88 +++++++++++++++++++++++++++++++++++++++ dlls/ntdll/ntdll.spec | 2 + include/winbase.h | 4 +- include/winnt.h | 1 + include/winternl.h | 2 + 6 files changed, 97 insertions(+), 2 deletions(-) diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec index f1d5a696ccc..ae6b1f906e0 100644 --- a/dlls/kernel/kernel32.spec +++ b/dlls/kernel/kernel32.spec @@ -135,6 +135,7 @@ @ stdcall AddAtomA(str) @ stdcall AddAtomW(wstr) +@ stdcall AddVectoredExceptionHandler(long ptr) ntdll.RtlAddVectoredExceptionHandler @ stdcall AllocConsole() @ stub AllocLSCallback @ stdcall AllocSLCallback(ptr ptr) @@ -690,6 +691,7 @@ @ stdcall ReplaceFileW(wstr wstr wstr long ptr ptr) @ stdcall RemoveDirectoryA(str) @ stdcall RemoveDirectoryW(wstr) +@ stdcall RemoveVectoredExceptionHandler(ptr) ntdll.RtlRemoveVectoredExceptionHandler @ stub RequestDeviceWakeup @ stdcall RequestWakeupLatency(long) @ stdcall ResetEvent(long) diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c index 22e57857ff7..b54ff71d38b 100644 --- a/dlls/ntdll/exception.c +++ b/dlls/ntdll/exception.c @@ -33,6 +33,7 @@ #include "winternl.h" #include "wine/exception.h" #include "wine/server.h" +#include "wine/list.h" #include "wine/debug.h" #include "excpt.h" @@ -45,6 +46,23 @@ typedef struct EXCEPTION_REGISTRATION_RECORD *prevFrame; } EXC_NESTED_FRAME; +typedef struct +{ + struct list entry; + PVECTORED_EXCEPTION_HANDLER func; +} VECTORED_HANDLER; + +static struct list vectored_handlers = LIST_INIT(vectored_handlers); + +static CRITICAL_SECTION vectored_handlers_section; +static CRITICAL_SECTION_DEBUG critsect_debug = +{ + 0, 0, &vectored_handlers_section, + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, + 0, 0, { 0, (DWORD)(__FILE__ ": vectored_handlers_section") } +}; +static CRITICAL_SECTION vectored_handlers_section = { &critsect_debug, -1, 0, 0, 0, 0 }; + #ifdef __i386__ # define GET_IP(context) ((LPVOID)(context)->Eip) #elif defined(__sparc__) @@ -159,6 +177,32 @@ static int send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *c } +/********************************************************************** + * call_vectored_handlers + * + * Call the vectored handlers chain. + */ +static LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) +{ + struct list *ptr; + LONG ret = EXCEPTION_CONTINUE_SEARCH; + EXCEPTION_POINTERS except_ptrs; + + except_ptrs.ExceptionRecord = rec; + except_ptrs.ContextRecord = context; + + RtlEnterCriticalSection( &vectored_handlers_section ); + LIST_FOR_EACH( ptr, &vectored_handlers ) + { + VECTORED_HANDLER *handler = LIST_ENTRY( ptr, VECTORED_HANDLER, entry ); + ret = handler->func( &except_ptrs ); + if (ret == EXCEPTION_CONTINUE_EXECUTION) break; + } + RtlLeaveCriticalSection( &vectored_handlers_section ); + return ret; +} + + /******************************************************************* * EXC_DefaultHandling * @@ -199,6 +243,8 @@ void WINAPI EXC_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context ) SIGNAL_Unblock(); /* we may be in a signal handler, and exception handlers may jump out */ + if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION) return; + frame = NtCurrentTeb()->Tib.ExceptionList; nested_frame = NULL; while (frame != (PEXCEPTION_REGISTRATION_RECORD)~0UL) @@ -358,6 +404,48 @@ void WINAPI RtlRaiseStatus( NTSTATUS status ) } +/******************************************************************* + * RtlAddVectoredExceptionHandler (NTDLL.@) + */ +PVOID WINAPI RtlAddVectoredExceptionHandler( ULONG first, PVECTORED_EXCEPTION_HANDLER func ) +{ + VECTORED_HANDLER *handler = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*handler) ); + if (handler) + { + handler->func = func; + RtlEnterCriticalSection( &vectored_handlers_section ); + if (first) list_add_head( &vectored_handlers, &handler->entry ); + else list_add_tail( &vectored_handlers, &handler->entry ); + RtlLeaveCriticalSection( &vectored_handlers_section ); + } + return handler; +} + + +/******************************************************************* + * RtlRemoveVectoredExceptionHandler (NTDLL.@) + */ +ULONG WINAPI RtlRemoveVectoredExceptionHandler( PVOID handler ) +{ + struct list *ptr; + ULONG ret = FALSE; + + RtlEnterCriticalSection( &vectored_handlers_section ); + LIST_FOR_EACH( ptr, &vectored_handlers ) + { + if (ptr == &((VECTORED_HANDLER *)handler)->entry) + { + list_remove( ptr ); + ret = TRUE; + break; + } + } + RtlLeaveCriticalSection( &vectored_handlers_section ); + if (ret) RtlFreeHeap( GetProcessHeap(), 0, handler ); + return ret; +} + + /************************************************************* * __wine_exception_handler (NTDLL.@) * diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index a605a4dda1a..c8b94923d65 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -276,6 +276,7 @@ @ stub RtlAddActionToRXact @ stub RtlAddAttributeActionToRXact @ stub RtlAddAuditAccessAce +@ stdcall RtlAddVectoredExceptionHandler(long ptr) @ stdcall RtlAdjustPrivilege(long long long long) @ stdcall RtlAllocateAndInitializeSid (ptr long long long long long long long long long ptr) @ stdcall RtlAllocateHeap(long long long) @@ -505,6 +506,7 @@ @ stdcall RtlReleasePebLock() @ stdcall RtlReleaseResource(ptr) @ stub RtlRemoteCall +@ stdcall RtlRemoveVectoredExceptionHandler(ptr) @ stub RtlResetRtlTranslations @ stub RtlRunDecodeUnicodeString @ stub RtlRunEncodeUnicodeString diff --git a/include/winbase.h b/include/winbase.h index a617d933373..2f6c2f4f8cd 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -1089,9 +1089,8 @@ BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType ); BOOL WINAPI GetBinaryTypeW( LPCWSTR lpApplicationName, LPDWORD lpBinaryType ); #define GetBinaryType WINELIB_NAME_AW(GetBinaryType) -/* Declarations for functions that exist only in Win32 */ - BOOL WINAPI AddAccessAllowedAce(PACL,DWORD,DWORD,PSID); +PVOID WINAPI AddVectoredExceptionHandler(ULONG,PVECTORED_EXCEPTION_HANDLER); BOOL WINAPI AttachThreadInput(DWORD,DWORD,BOOL); BOOL WINAPI AccessCheck(PSECURITY_DESCRIPTOR,HANDLE,DWORD,PGENERIC_MAPPING,PPRIVILEGE_SET,LPDWORD,LPDWORD,LPBOOL); BOOL WINAPI AdjustTokenPrivileges(HANDLE,BOOL,LPVOID,DWORD,LPVOID,LPDWORD); @@ -1409,6 +1408,7 @@ HANDLE WINAPI RegisterEventSourceW(LPCWSTR,LPCWSTR); #define RegisterEventSource WINELIB_NAME_AW(RegisterEventSource) BOOL WINAPI ReleaseMutex(HANDLE); BOOL WINAPI ReleaseSemaphore(HANDLE,LONG,LPLONG); +ULONG WINAPI RemoveVectoredExceptionHandler(PVOID); BOOL WINAPI ReportEventA(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCSTR *,LPVOID); BOOL WINAPI ReportEventW(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCWSTR *,LPVOID); BOOL WINAPI RequestWakeupLatency(LATENCY_TIME latency); diff --git a/include/winnt.h b/include/winnt.h index c8da36e8c14..9f3950b0593 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -1633,6 +1633,7 @@ typedef struct _EXCEPTION_REGISTRATION_RECORD * function pointer to a exception filter */ +typedef LONG (CALLBACK *PVECTORED_EXCEPTION_HANDLER)(PEXCEPTION_POINTERS ExceptionInfo); typedef LONG (CALLBACK *PTOP_LEVEL_EXCEPTION_FILTER)(PEXCEPTION_POINTERS ExceptionInfo); typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER; diff --git a/include/winternl.h b/include/winternl.h index e7d976cd462..37ede273cd9 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1054,6 +1054,7 @@ NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL,DWORD,DWORD,PSID); NTSTATUS WINAPI RtlAddAccessAllowedAceEx(PACL,DWORD,DWORD,DWORD,PSID); NTSTATUS WINAPI RtlAddAccessDeniedAce(PACL,DWORD,DWORD,PSID); NTSTATUS WINAPI RtlAddAccessDeniedAceEx(PACL,DWORD,DWORD,DWORD,PSID); +PVOID WINAPI RtlAddVectoredExceptionHandler(ULONG,PVECTORED_EXCEPTION_HANDLER); DWORD WINAPI RtlAdjustPrivilege(DWORD,DWORD,DWORD,DWORD); BOOLEAN WINAPI RtlAllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY,BYTE,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,PSID *); PVOID WINAPI RtlAllocateHeap(HANDLE,ULONG,ULONG); @@ -1231,6 +1232,7 @@ ULONG WINAPI RtlRandom(PULONG); PVOID WINAPI RtlReAllocateHeap(HANDLE,ULONG,PVOID,ULONG); void WINAPI RtlReleasePebLock(void); void WINAPI RtlReleaseResource(LPRTL_RWLOCK); +ULONG WINAPI RtlRemoveVectoredExceptionHandler(PVOID); void WINAPI RtlSecondsSince1970ToTime(DWORD,LARGE_INTEGER *); void WINAPI RtlSecondsSince1980ToTime(DWORD,LARGE_INTEGER *);