From eb712d32c2a8761c97140a07558f72eceddd0017 Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Tue, 2 Aug 2016 23:52:12 -0700 Subject: [PATCH] ntdll: Call __finally blocks in __C_specific_handler Signed-off-by: Daniel Lehman --- dlls/ntdll/signal_x86_64.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index decae5c..25d4032 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -81,6 +81,7 @@ typedef EXCEPTION_DISPOSITION (WINAPI *PEXCEPTION_ROUTINE)( EXCEPTION_RECORD *re ULONG64 frame, CONTEXT *context, struct _DISPATCHER_CONTEXT *dispatch ); +typedef void (WINAPI *TERMINATION_HANDLER)( ULONG flags, ULONG64 frame ); typedef struct _DISPATCHER_CONTEXT { @@ -3733,8 +3734,31 @@ EXCEPTION_DISPOSITION WINAPI __C_specific_handler( EXCEPTION_RECORD *rec, TRACE( "%p %lx %p %p\n", rec, frame, context, dispatch ); if (TRACE_ON(seh)) dump_scope_table( dispatch->ImageBase, table ); - if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) /* FIXME */ + if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) + { + for (i = 0; i < table->Count; i++) + { + if (context->Rip >= dispatch->ImageBase + table->ScopeRecord[i].BeginAddress && + context->Rip < dispatch->ImageBase + table->ScopeRecord[i].EndAddress) + { + TERMINATION_HANDLER handler; + + if (table->ScopeRecord[i].JumpTarget) continue; + + if (rec->ExceptionFlags & EH_TARGET_UNWIND && + dispatch->TargetIp < dispatch->ImageBase + table->ScopeRecord[i].EndAddress) + { + break; + } + + handler = (TERMINATION_HANDLER)(dispatch->ImageBase + table->ScopeRecord[i].HandlerAddress); + + TRACE( "calling __finally %p frame %lx\n", handler, frame ); + handler( 1, frame ); + } + } return ExceptionContinueSearch; + } for (i = 0; i < table->Count; i++) { -- 1.9.5