diff --git a/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec b/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec index 0edd871fb5d..af23f8dceec 100644 --- a/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec +++ b/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec @@ -34,7 +34,7 @@ @ cdecl __RTtypeid(ptr) ucrtbase.__RTtypeid @ stub __TypeMatch @ cdecl __current_exception() ucrtbase.__current_exception -@ stub __current_exception_context +@ cdecl __current_exception_context() ucrtbase.__current_exception_context @ stub __dcrt_get_wide_environment_from_os @ stub __dcrt_initial_narrow_environment @ stub __intrinsic_abnormal_termination diff --git a/dlls/msvcrt/except.c b/dlls/msvcrt/except.c index 3378283ecec..286c82fc23e 100644 --- a/dlls/msvcrt/except.c +++ b/dlls/msvcrt/except.c @@ -432,23 +432,24 @@ void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec) /********************************************************************* * __CxxRegisterExceptionObject (MSVCRT.@) */ -BOOL CDECL __CxxRegisterExceptionObject(EXCEPTION_RECORD **rec, cxx_frame_info *frame_info) +BOOL CDECL __CxxRegisterExceptionObject(EXCEPTION_POINTERS *ep, cxx_frame_info *frame_info) { thread_data_t *data = msvcrt_get_thread_data(); - TRACE("(%p, %p)\n", rec, frame_info); + TRACE("(%p, %p)\n", ep, frame_info); - if (!rec || !*rec) + if (!ep || !ep->ExceptionRecord) { frame_info->rec = (void*)-1; - frame_info->unk = (void*)-1; + frame_info->context = (void*)-1; return TRUE; } frame_info->rec = data->exc_record; - frame_info->unk = 0; - data->exc_record = *rec; - _CreateFrameInfo(&frame_info->frame_info, (void*)(*rec)->ExceptionInformation[1]); + frame_info->context = data->ctx_record; + data->exc_record = ep->ExceptionRecord; + data->ctx_record = ep->ContextRecord; + _CreateFrameInfo(&frame_info->frame_info, (void*)ep->ExceptionRecord->ExceptionInformation[1]); return TRUE; } @@ -469,6 +470,7 @@ void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_us && _IsExceptionObjectToBeDestroyed((void*)data->exc_record->ExceptionInformation[1])) __DestructExceptionObject(data->exc_record); data->exc_record = frame_info->rec; + data->ctx_record = frame_info->context; } struct __std_exception_data { @@ -517,4 +519,13 @@ void** CDECL __current_exception(void) return (void**)&msvcrt_get_thread_data()->exc_record; } +/********************************************************************* + * __current_exception_context (UCRTBASE.@) + */ +void** CDECL __current_exception_context(void) +{ + TRACE("()\n"); + return (void**)&msvcrt_get_thread_data()->ctx_record; +} + #endif /* _MSVCR_VER>=140 */ diff --git a/dlls/msvcrt/except_i386.c b/dlls/msvcrt/except_i386.c index 317a9616bb2..09dec65b714 100644 --- a/dlls/msvcrt/except_i386.c +++ b/dlls/msvcrt/except_i386.c @@ -400,7 +400,8 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG /* find and call the appropriate catch block for an exception */ /* returns the address to continue execution to after the catch block was called */ -static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame *frame, +static inline void call_catch_block( PEXCEPTION_RECORD rec, CONTEXT *context, + cxx_exception_frame *frame, const cxx_function_descr *descr, int nested_trylevel, EXCEPTION_REGISTRATION_RECORD *catch_frame, cxx_exception_type *info ) @@ -457,7 +458,9 @@ static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame data = msvcrt_get_thread_data(); nested_frame.frame_info.rec = data->exc_record; + nested_frame.frame_info.context = data->ctx_record; data->exc_record = rec; + data->ctx_record = context; /* call the catch block */ TRACE( "calling catch block %p addr %p ebp %p\n", @@ -552,7 +555,7 @@ static LONG CALLBACK se_translation_filter( EXCEPTION_POINTERS *ep, void *c ) } exc_type = (cxx_exception_type *)rec->ExceptionInformation[2]; - call_catch_block( rec, ctx->frame, ctx->descr, + call_catch_block( rec, ep->ContextRecord, ctx->frame, ctx->descr, ctx->frame->trylevel, ctx->nested_frame, exc_type ); __DestructExceptionObject( rec ); @@ -649,7 +652,8 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame } } - call_catch_block( rec, frame, descr, frame->trylevel, nested_frame, exc_type ); + call_catch_block( rec, context, frame, descr, + frame->trylevel, nested_frame, exc_type ); return ExceptionContinueSearch; } diff --git a/dlls/msvcrt/except_x86_64.c b/dlls/msvcrt/except_x86_64.c index 0820aaded86..7859a63f6a8 100644 --- a/dlls/msvcrt/except_x86_64.c +++ b/dlls/msvcrt/except_x86_64.c @@ -352,15 +352,17 @@ static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec) const cxx_function_descr *descr = (void*)rec->ExceptionInformation[2]; EXCEPTION_RECORD *prev_rec = (void*)rec->ExceptionInformation[4]; EXCEPTION_RECORD *untrans_rec = (void*)rec->ExceptionInformation[6]; + CONTEXT *context = (void*)rec->ExceptionInformation[7]; void* (__cdecl *handler)(ULONG64 unk, ULONG64 rbp) = (void*)rec->ExceptionInformation[5]; int *unwind_help = rva_to_ptr(descr->unwind_help, frame); + EXCEPTION_POINTERS ep = { prev_rec, context }; cxx_catch_ctx ctx; void *ret_addr = NULL; TRACE("calling handler %p\n", handler); ctx.rethrow = FALSE; - __CxxRegisterExceptionObject(&prev_rec, &ctx.frame_info); + __CxxRegisterExceptionObject(&ep, &ctx.frame_info); __TRY { __TRY @@ -395,11 +397,12 @@ static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec) static inline BOOL cxx_is_consolidate(const EXCEPTION_RECORD *rec) { - return rec->ExceptionCode==STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters==7 && + return rec->ExceptionCode==STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters==8 && rec->ExceptionInformation[0]==(ULONG_PTR)call_catch_block; } -static inline void find_catch_block(EXCEPTION_RECORD *rec, EXCEPTION_RECORD *untrans_rec, +static inline void find_catch_block(EXCEPTION_RECORD *rec, CONTEXT *context, + EXCEPTION_RECORD *untrans_rec, ULONG64 frame, DISPATCHER_CONTEXT *dispatch, const cxx_function_descr *descr, cxx_exception_type *info, ULONG64 orig_frame) @@ -409,7 +412,7 @@ static inline void find_catch_block(EXCEPTION_RECORD *rec, EXCEPTION_RECORD *unt descr->ipmap_count, dispatch->ControlPc-dispatch->ImageBase); const tryblock_info *in_catch; EXCEPTION_RECORD catch_record; - CONTEXT context; + CONTEXT ctx; UINT i, j; INT *unwind_help; @@ -476,7 +479,7 @@ static inline void find_catch_block(EXCEPTION_RECORD *rec, EXCEPTION_RECORD *unt memset(&catch_record, 0, sizeof(catch_record)); catch_record.ExceptionCode = STATUS_UNWIND_CONSOLIDATE; catch_record.ExceptionFlags = EXCEPTION_NONCONTINUABLE; - catch_record.NumberParameters = 7; + catch_record.NumberParameters = 8; catch_record.ExceptionInformation[0] = (ULONG_PTR)call_catch_block; catch_record.ExceptionInformation[1] = orig_frame; catch_record.ExceptionInformation[2] = (ULONG_PTR)descr; @@ -485,7 +488,8 @@ static inline void find_catch_block(EXCEPTION_RECORD *rec, EXCEPTION_RECORD *unt catch_record.ExceptionInformation[5] = (ULONG_PTR)rva_to_ptr(catchblock->handler, dispatch->ImageBase); catch_record.ExceptionInformation[6] = (ULONG_PTR)untrans_rec; - RtlUnwindEx((void*)frame, (void*)dispatch->ControlPc, &catch_record, NULL, &context, NULL); + catch_record.ExceptionInformation[7] = (ULONG_PTR)context; + RtlUnwindEx((void*)frame, (void*)dispatch->ControlPc, &catch_record, NULL, &ctx, NULL); } } @@ -505,7 +509,7 @@ static LONG CALLBACK se_translation_filter(EXCEPTION_POINTERS *ep, void *c) } exc_type = (cxx_exception_type *)rec->ExceptionInformation[2]; - find_catch_block(rec, ctx->seh_rec, ctx->dest_frame, ctx->dispatch, + find_catch_block(rec, ep->ContextRecord, ctx->seh_rec, ctx->dest_frame, ctx->dispatch, ctx->descr, exc_type, ctx->orig_frame); __DestructExceptionObject(rec); @@ -618,7 +622,7 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame, } } - find_catch_block(rec, NULL, frame, dispatch, descr, exc_type, orig_frame); + find_catch_block(rec, context, NULL, frame, dispatch, descr, exc_type, orig_frame); return ExceptionContinueSearch; } diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 65ced6d26d3..7c489174d33 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -214,11 +214,11 @@ typedef struct { frame_info frame_info; EXCEPTION_RECORD *rec; - void *unk; + CONTEXT *context; } cxx_frame_info; frame_info* __cdecl _CreateFrameInfo(frame_info *fi, void *obj); -BOOL __cdecl __CxxRegisterExceptionObject(EXCEPTION_RECORD**, cxx_frame_info*); +BOOL __cdecl __CxxRegisterExceptionObject(EXCEPTION_POINTERS*, cxx_frame_info*); void __cdecl __CxxUnregisterExceptionObject(cxx_frame_info*, BOOL); void CDECL __DestructExceptionObject(EXCEPTION_RECORD*); @@ -259,6 +259,7 @@ struct __thread_data { void *unk6[3]; int unk7; EXCEPTION_RECORD *exc_record; + CONTEXT *ctx_record; frame_info *frame_info_head; void *unk8[6]; LCID cached_lcid; diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 00d779cc59d..2d4f798058d 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -83,7 +83,7 @@ @ stub __conio_common_vcwscanf @ cdecl -arch=i386 __control87_2(long long ptr ptr) @ cdecl __current_exception() -@ stub __current_exception_context +@ cdecl __current_exception_context() @ cdecl __daylight() MSVCRT___p__daylight @ stub __dcrt_get_wide_environment_from_os @ stub __dcrt_initial_narrow_environment diff --git a/dlls/vcruntime140/vcruntime140.spec b/dlls/vcruntime140/vcruntime140.spec index 331a087b5ab..252113c8aee 100644 --- a/dlls/vcruntime140/vcruntime140.spec +++ b/dlls/vcruntime140/vcruntime140.spec @@ -31,7 +31,7 @@ @ cdecl __RTtypeid(ptr) ucrtbase.__RTtypeid @ stub __TypeMatch @ cdecl __current_exception() ucrtbase.__current_exception -@ stub __current_exception_context +@ cdecl __current_exception_context() ucrtbase.__current_exception_context @ cdecl -arch=i386,x86_64,arm,arm64 -norelay __intrinsic_setjmp(ptr) ucrtbase.__intrinsic_setjmp @ cdecl -arch=x86_64,arm64 -norelay __intrinsic_setjmpex(ptr ptr) ucrtbase.__intrinsic_setjmpex @ stub __processing_throw