Follow up to https://gitlab.winehq.org/wine/wine/-/merge_requests/9209#note_120396
-- v2: msvcrt: Call Release instead of AddRef for WinRT exceptions in copy_exception helper. msvcp90: Call Release instead of AddRef for WinRT exceptions in copy_exception helper.
From: Vibhav Pant vibhavp@gmail.com
--- dlls/vcruntime140/Makefile.in | 6 +- dlls/vcruntime140/signal_arm.c | 34 ++++ dlls/vcruntime140/signal_arm64.c | 54 ++++++ dlls/vcruntime140/signal_arm64ec.c | 57 ++++++ dlls/vcruntime140/unwind.c | 284 ++++++++++++++++++++++++++++ dlls/vcruntime140/vcruntime140.spec | 2 +- 6 files changed, 435 insertions(+), 2 deletions(-) create mode 100644 dlls/vcruntime140/signal_arm.c create mode 100644 dlls/vcruntime140/signal_arm64.c create mode 100644 dlls/vcruntime140/signal_arm64ec.c create mode 100644 dlls/vcruntime140/unwind.c
diff --git a/dlls/vcruntime140/Makefile.in b/dlls/vcruntime140/Makefile.in index 1f99225ffe8..3fffd0e25b6 100644 --- a/dlls/vcruntime140/Makefile.in +++ b/dlls/vcruntime140/Makefile.in @@ -2,4 +2,8 @@ MODULE = vcruntime140.dll IMPORTLIB = vcruntime140
SOURCES = \ - misc.c + misc.c \ + signal_arm64.c \ + signal_arm.c \ + signal_arm64ec.c \ + unwind.c diff --git a/dlls/vcruntime140/signal_arm.c b/dlls/vcruntime140/signal_arm.c new file mode 100644 index 00000000000..aca6a8b4697 --- /dev/null +++ b/dlls/vcruntime140/signal_arm.c @@ -0,0 +1,34 @@ +/* + * ARM signal handling routines + * + * Copyright 2002 Marcus Meissner, SuSE Linux AG + * Copyright 2010-2013, 2015 André Hentschel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef __arm__ + +#include <wine/asm.h> + +__ASM_GLOBAL_FUNC( __C_ExecuteExceptionFilter, + "push {r3-r11,lr}\n\t" + ".seh_save_regs_w {r3-r11,lr}\n\t" + ".seh_endprologue\n\t" + "ldm r3, {r4-r11}\n\t" + "blx r2\n\t" + "pop {r3-r11,pc}\n\t" ); + +#endif diff --git a/dlls/vcruntime140/signal_arm64.c b/dlls/vcruntime140/signal_arm64.c new file mode 100644 index 00000000000..e1aa3965cc3 --- /dev/null +++ b/dlls/vcruntime140/signal_arm64.c @@ -0,0 +1,54 @@ +/* + * ARM64 signal handling routines + * + * Copyright 2010-2013 André Hentschel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef __aarch64__ + +#include "wine/asm.h" + +__ASM_GLOBAL_FUNC( __C_ExecuteExceptionFilter, + "stp x29, x30, [sp, #-96]!\n\t" + ".seh_save_fplr_x 96\n\t" + "stp x19, x20, [sp, #16]\n\t" + ".seh_save_regp x19, 16\n\t" + "stp x21, x22, [sp, #32]\n\t" + ".seh_save_regp x21, 32\n\t" + "stp x23, x24, [sp, #48]\n\t" + ".seh_save_regp x23, 48\n\t" + "stp x25, x26, [sp, #64]\n\t" + ".seh_save_regp x25, 64\n\t" + "stp x27, x28, [sp, #80]\n\t" + ".seh_save_regp x27, 80\n\t" + ".seh_endprologue\n\t" + "ldp x19, x20, [x3, #0]\n\t" /* nonvolatile regs */ + "ldp x21, x22, [x3, #16]\n\t" + "ldp x23, x24, [x3, #32]\n\t" + "ldp x25, x26, [x3, #48]\n\t" + "ldp x27, x28, [x3, #64]\n\t" + "ldr x1, [x3, #80]\n\t" /* x29 = frame */ + "blr x2\n\t" /* filter */ + "ldp x19, x20, [sp, #16]\n\t" + "ldp x21, x22, [sp, #32]\n\t" + "ldp x23, x24, [sp, #48]\n\t" + "ldp x25, x26, [sp, #64]\n\t" + "ldp x27, x28, [sp, #80]\n\t" + "ldp x29, x30, [sp], #96\n\t" + "ret"); + +#endif diff --git a/dlls/vcruntime140/signal_arm64ec.c b/dlls/vcruntime140/signal_arm64ec.c new file mode 100644 index 00000000000..3ff6169699e --- /dev/null +++ b/dlls/vcruntime140/signal_arm64ec.c @@ -0,0 +1,57 @@ +/* + * ARM64EC signal handling routines + * + * Copyright 1999, 2005, 2023 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef __arm64ec__ + +#include <windef.h> + +#include <wine/asm.h> + +LONG __attribute__((naked)) __C_ExecuteExceptionFilter( EXCEPTION_POINTERS *ptrs, void *frame, + PEXCEPTION_FILTER filter, BYTE *nonvolatile ) +{ + asm( ".seh_proc _C_ExecuteExceptionFilter\n\t" + "stp x29, x30, [sp, #-80]!\n\t" + ".seh_save_fplr_x 80\n\t" + "stp x19, x20, [sp, #16]\n\t" + ".seh_save_regp x19, 16\n\t" + "stp x21, x22, [sp, #32]\n\t" + ".seh_save_regp x21, 32\n\t" + "stp x25, x26, [sp, #48]\n\t" + ".seh_save_regp x25, 48\n\t" + "str x27, [sp, #64]\n\t" + ".seh_save_reg x27, 64\n\t" + ".seh_endprologue\n\t" + "ldp x19, x20, [x3, #0]\n\t" /* nonvolatile regs */ + "ldp x21, x22, [x3, #16]\n\t" + "ldp x25, x26, [x3, #48]\n\t" + "ldr x27, [x3, #64]\n\t" + "ldr x1, [x3, #80]\n\t" /* x29 = frame */ + "blr x2\n\t" /* filter */ + "ldp x19, x20, [sp, #16]\n\t" + "ldp x21, x22, [sp, #32]\n\t" + "ldp x25, x26, [sp, #48]\n\t" + "ldr x27, [sp, #64]\n\t" + "ldp x29, x30, [sp], #80\n\t" + "ret\n\t" + ".seh_endproc" ); +} + +#endif diff --git a/dlls/vcruntime140/unwind.c b/dlls/vcruntime140/unwind.c new file mode 100644 index 00000000000..c847cee5d46 --- /dev/null +++ b/dlls/vcruntime140/unwind.c @@ -0,0 +1,284 @@ +/* + * Exception unwinding + * + * Copyright 1999, 2005, 2019, 2024 Alexandre Julliard + * Copyright 2021 Martin Storsjö + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> + +#include <ntstatus.h> +#define WIN32_NO_STATUS +#include <windef.h> +#include <winternl.h> + +#include <wine/exception.h> +#include <wine/debug.h> + +#ifndef __i386__ + +WINE_DEFAULT_DEBUG_CHANNEL(vcruntime140); +WINE_DECLARE_DEBUG_CHANNEL(unwind); + +#define DUMP_SCOPE_TABLE(base,table) do { \ + for (unsigned int i = 0; i < table->Count; i++) \ + TRACE( " %u: %p-%p handler %p target %p\n", i, \ + (char *)base + table->ScopeRecord[i].BeginAddress, \ + (char *)base + table->ScopeRecord[i].EndAddress, \ + (char *)base + table->ScopeRecord[i].HandlerAddress, \ + (char *)base + table->ScopeRecord[i].JumpTarget ); \ +} while(0) + +#define CXX_EXCEPTION 0xe06d7363 + +extern LONG __C_ExecuteExceptionFilter( EXCEPTION_POINTERS *ptrs, void *frame, PEXCEPTION_FILTER filter, + BYTE *nonvolatile ); + +extern void CDECL __DestructExceptionObject( EXCEPTION_RECORD *rec ); + +/* The __C_specific_handler in vcruntime calls the destructor for the exception object if: + * The current exception is a C++ exception. + * A matching SEH handler was found. + */ + +#if defined(__aarch64__) || defined(__arm64ec__) +#ifdef __arm64ec__ +#define __C_specific_handler __C_specific_handler_arm64 +#endif + +EXCEPTION_DISPOSITION WINAPI __C_specific_handler( EXCEPTION_RECORD *rec, void *frame, + ARM64_NT_CONTEXT *context, + DISPATCHER_CONTEXT_ARM64 *dispatch ) +{ + const SCOPE_TABLE *table = dispatch->HandlerData; + ULONG_PTR base = dispatch->ImageBase; + ULONG_PTR pc = dispatch->ControlPc; + unsigned int i; + void *handler; + + TRACE( "%p %p %p %p pc %Ix\n", rec, frame, context, dispatch, pc ); + if (TRACE_ON(unwind)) DUMP_SCOPE_TABLE( base, table ); + + if (dispatch->ControlPcIsUnwound) pc -= 4; + + if (rec->ExceptionFlags & (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)) + { + for (i = dispatch->ScopeIndex; i < table->Count; i++) + { + if (pc < base + table->ScopeRecord[i].BeginAddress) continue; + if (pc >= base + table->ScopeRecord[i].EndAddress) continue; + if (table->ScopeRecord[i].JumpTarget) continue; + + if (rec->ExceptionFlags & EXCEPTION_TARGET_UNWIND && + dispatch->TargetPc >= base + table->ScopeRecord[i].BeginAddress && + dispatch->TargetPc < base + table->ScopeRecord[i].EndAddress) + { + break; + } + handler = (void *)(base + table->ScopeRecord[i].HandlerAddress); + dispatch->ScopeIndex = i + 1; + TRACE( "scope %u calling __finally %p frame %p\n", i, handler, frame ); + __C_ExecuteExceptionFilter( ULongToPtr(TRUE), frame, handler, dispatch->NonVolatileRegisters ); + } + } + else + { + for (i = dispatch->ScopeIndex; i < table->Count; i++) + { + if (pc < base + table->ScopeRecord[i].BeginAddress) continue; + if (pc >= base + table->ScopeRecord[i].EndAddress) continue; + if (!table->ScopeRecord[i].JumpTarget) continue; + + if (table->ScopeRecord[i].HandlerAddress != EXCEPTION_EXECUTE_HANDLER) + { + EXCEPTION_POINTERS ptrs = { rec, (CONTEXT *)context }; + + handler = (void *)(base + table->ScopeRecord[i].HandlerAddress); + TRACE( "scope %u calling filter %p ptrs %p frame %p\n", i, handler, &ptrs, frame ); + switch (__C_ExecuteExceptionFilter( &ptrs, frame, handler, dispatch->NonVolatileRegisters )) + { + case EXCEPTION_EXECUTE_HANDLER: + break; + case EXCEPTION_CONTINUE_SEARCH: + continue; + case EXCEPTION_CONTINUE_EXECUTION: + return ExceptionContinueExecution; + } + } + if (rec->ExceptionCode == CXX_EXCEPTION) __DestructExceptionObject( rec ); + + TRACE( "unwinding to target %Ix\n", base + table->ScopeRecord[i].JumpTarget ); + RtlUnwindEx( frame, (char *)base + table->ScopeRecord[i].JumpTarget, + rec, ULongToPtr(rec->ExceptionCode), (CONTEXT *)dispatch->ContextRecord, + dispatch->HistoryTable ); + } + } + return ExceptionContinueSearch; +} +#ifdef __arm64ec__ +#undef __C_specific_handler +#endif +#endif /* __aarch64__ || __arm64ec__ */ + +#ifdef __arm__ +EXCEPTION_DISPOSITION WINAPI __C_specific_handler( EXCEPTION_RECORD *rec, void *frame, + CONTEXT *context, DISPATCHER_CONTEXT *dispatch ) +{ + const SCOPE_TABLE *table = dispatch->HandlerData; + ULONG_PTR base = dispatch->ImageBase; + ULONG_PTR pc = dispatch->ControlPc; + unsigned int i; + void *handler; + + TRACE( "%p %p %p %p pc %Ix\n", rec, frame, context, dispatch, pc ); + if (TRACE_ON(unwind)) DUMP_SCOPE_TABLE( base, table ); + + if (dispatch->ControlPcIsUnwound) pc -= 2; + + if (rec->ExceptionFlags & (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)) + { + for (i = dispatch->ScopeIndex; i < table->Count; i++) + { + if (pc < base + table->ScopeRecord[i].BeginAddress) continue; + if (pc >= base + table->ScopeRecord[i].EndAddress) continue; + if (table->ScopeRecord[i].JumpTarget) continue; + + if (rec->ExceptionFlags & EXCEPTION_TARGET_UNWIND && + dispatch->TargetPc >= base + table->ScopeRecord[i].BeginAddress && + dispatch->TargetPc < base + table->ScopeRecord[i].EndAddress) + { + break; + } + handler = (void *)(base + table->ScopeRecord[i].HandlerAddress); + dispatch->ScopeIndex = i + 1; + TRACE( "scope %u calling __finally %p frame %p\n", i, handler, frame ); + __C_ExecuteExceptionFilter( ULongToPtr(TRUE), frame, handler, dispatch->NonVolatileRegisters ); + } + } + else + { + for (i = dispatch->ScopeIndex; i < table->Count; i++) + { + if (pc < base + table->ScopeRecord[i].BeginAddress) continue; + if (pc >= base + table->ScopeRecord[i].EndAddress) continue; + if (!table->ScopeRecord[i].JumpTarget) continue; + + if (table->ScopeRecord[i].HandlerAddress != EXCEPTION_EXECUTE_HANDLER) + { + EXCEPTION_POINTERS ptrs = { rec, context }; + + handler = (void *)(base + table->ScopeRecord[i].HandlerAddress); + TRACE( "scope %u calling filter %p ptrs %p frame %p\n", i, handler, &ptrs, frame ); + switch (__C_ExecuteExceptionFilter( &ptrs, frame, handler, dispatch->NonVolatileRegisters )) + { + case EXCEPTION_EXECUTE_HANDLER: + break; + case EXCEPTION_CONTINUE_SEARCH: + continue; + case EXCEPTION_CONTINUE_EXECUTION: + return ExceptionContinueExecution; + } + } + if (rec->ExceptionCode == CXX_EXCEPTION) __DestructExceptionObject( rec ); + + TRACE( "unwinding to target %lx\n", base + table->ScopeRecord[i].JumpTarget ); + RtlUnwindEx( frame, (char *)base + table->ScopeRecord[i].JumpTarget, + rec, ULongToPtr(rec->ExceptionCode), dispatch->ContextRecord, + dispatch->HistoryTable ); + } + } + return ExceptionContinueSearch; +} +#endif /* __arm__ */ + +#ifdef __x86_64__ +EXCEPTION_DISPOSITION WINAPI __C_specific_handler( EXCEPTION_RECORD *rec, void *frame, CONTEXT *context, + DISPATCHER_CONTEXT *dispatch ) +{ + const SCOPE_TABLE *table = dispatch->HandlerData; + ULONG_PTR base = dispatch->ImageBase; + ULONG_PTR pc = dispatch->ControlPc; + unsigned int i; + +#ifdef __arm64ec__ + if (RtlIsEcCode( pc )) + return __C_specific_handler_arm64( rec, frame, (ARM64_NT_CONTEXT *)context, + (DISPATCHER_CONTEXT_ARM64 *)dispatch ); +#endif + + TRACE( "%p %p %p %p pc %Ix\n", rec, frame, context, dispatch, pc ); + if (TRACE_ON(unwind)) DUMP_SCOPE_TABLE( base, table ); + + if (rec->ExceptionFlags & (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)) + { + for (i = dispatch->ScopeIndex; i < table->Count; i++) + { + if (pc < base + table->ScopeRecord[i].BeginAddress) continue; + if (pc >= base + table->ScopeRecord[i].EndAddress) continue; + if (table->ScopeRecord[i].JumpTarget) continue; + + if (rec->ExceptionFlags & EXCEPTION_TARGET_UNWIND && + dispatch->TargetIp >= base + table->ScopeRecord[i].BeginAddress && + dispatch->TargetIp < base + table->ScopeRecord[i].EndAddress) + { + break; + } + else + { + PTERMINATION_HANDLER handler = (void *)(base + table->ScopeRecord[i].HandlerAddress); + dispatch->ScopeIndex = i + 1; + TRACE( "scope %u calling __finally %p frame %p\n", i, handler, frame ); + handler( TRUE, frame ); + } + } + } + else + { + for (i = dispatch->ScopeIndex; i < table->Count; i++) + { + if (pc < base + table->ScopeRecord[i].BeginAddress) continue; + if (pc >= base + table->ScopeRecord[i].EndAddress) continue; + if (!table->ScopeRecord[i].JumpTarget) continue; + + if (table->ScopeRecord[i].HandlerAddress != EXCEPTION_EXECUTE_HANDLER) + { + EXCEPTION_POINTERS ptrs = { rec, context }; + PEXCEPTION_FILTER filter = (void *)(base + table->ScopeRecord[i].HandlerAddress); + + TRACE( "scope %u calling filter %p ptrs %p frame %p\n", i, filter, &ptrs, frame ); + switch (filter( &ptrs, frame )) + { + case EXCEPTION_EXECUTE_HANDLER: + break; + case EXCEPTION_CONTINUE_SEARCH: + continue; + case EXCEPTION_CONTINUE_EXECUTION: + return ExceptionContinueExecution; + } + } + if (rec->ExceptionCode == CXX_EXCEPTION) __DestructExceptionObject( rec ); + + TRACE( "unwinding to target %Ix\n", base + table->ScopeRecord[i].JumpTarget ); + RtlUnwindEx( frame, (char *)base + table->ScopeRecord[i].JumpTarget, + rec, ULongToPtr(rec->ExceptionCode), dispatch->ContextRecord, + dispatch->HistoryTable ); + } + } + return ExceptionContinueSearch; +} +#endif /* __x86_64__ */ +#endif /* !i386 */ \ No newline at end of file diff --git a/dlls/vcruntime140/vcruntime140.spec b/dlls/vcruntime140/vcruntime140.spec index 6a04f162b54..d4587f9ba1f 100644 --- a/dlls/vcruntime140/vcruntime140.spec +++ b/dlls/vcruntime140/vcruntime140.spec @@ -10,7 +10,7 @@ @ cdecl __AdjustPointer(ptr ptr) ucrtbase.__AdjustPointer @ stub __BuildCatchObject @ stub __BuildCatchObjectHelper -@ stdcall -arch=!i386 __C_specific_handler(ptr long ptr ptr) ucrtbase.__C_specific_handler +@ stdcall -arch=!i386 __C_specific_handler(ptr long ptr ptr) @ stub __C_specific_handler_noexcept @ cdecl __CxxDetectRethrow(ptr) ucrtbase.__CxxDetectRethrow @ cdecl __CxxExceptionFilter(ptr ptr long ptr) ucrtbase.__CxxExceptionFilter
From: Vibhav Pant vibhavp@gmail.com
--- dlls/msvcp90/exception.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/dlls/msvcp90/exception.c b/dlls/msvcp90/exception.c index aef1268068c..df2f52c0755 100644 --- a/dlls/msvcp90/exception.c +++ b/dlls/msvcp90/exception.c @@ -43,7 +43,7 @@ CREATE_TYPE_INFO_VTABLE
#define CLASS_IS_SIMPLE_TYPE 1 #define CLASS_HAS_VIRTUAL_BASE_CLASS 4 -#define CLASS_IS_IUNKNOWN 8 +#define CLASS_IS_WINRT 8
int* __cdecl __processing_throw(void);
@@ -1200,8 +1200,10 @@ static inline void copy_exception( void *object, void **dest, UINT catch_flags, { if (type->flags & CLASS_IS_SIMPLE_TYPE) { - if (type->flags & CLASS_IS_IUNKNOWN && *(IUnknown**)object) - IUnknown_AddRef(*(IUnknown**)object); + /* WinRT exceptions are thrown with a reference count of 2, the refcount is decreased before it's handed off to a + * matching catch block. */ + if (type->flags & CLASS_IS_WINRT && *(IUnknown**)object) + IUnknown_Release(*(IUnknown**)object); memmove( dest, object, type->size ); /* if it is a pointer, adjust it */ if (type->size == sizeof(void*)) *dest = get_this_pointer( &type->offsets, *dest ); @@ -1216,8 +1218,8 @@ static inline void copy_exception( void *object, void **dest, UINT catch_flags, } else { - if (type->flags & CLASS_IS_IUNKNOWN && *(IUnknown**)object) - IUnknown_AddRef(*(IUnknown**)object); + if (type->flags & CLASS_IS_WINRT && *(IUnknown**)object) + IUnknown_Release(*(IUnknown**)object); memmove( dest, get_this_pointer( &type->offsets, object ), type->size ); } }
From: Vibhav Pant vibhavp@gmail.com
--- dlls/msvcrt/cppexcept.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/cppexcept.h b/dlls/msvcrt/cppexcept.h index 0f64f97dd20..9abdcc0569b 100644 --- a/dlls/msvcrt/cppexcept.h +++ b/dlls/msvcrt/cppexcept.h @@ -261,8 +261,10 @@ static inline void copy_exception( void *object, void **dest, UINT catch_flags, } else if (type->flags & CLASS_IS_SIMPLE_TYPE) { + /* WinRT exceptions are thrown with a reference count of 2, the refcount is decreased before it's handed off to a + * matching catch block. */ if (type->flags & CLASS_IS_WINRT && *(IUnknown**)object) - IUnknown_AddRef(*(IUnknown**)object); + IUnknown_Release(*(IUnknown**)object); memmove( dest, object, type->size ); /* if it is a pointer, adjust it */ if (type->size == sizeof(void*)) *dest = get_this_pointer( &type->offsets, *dest ); @@ -278,7 +280,7 @@ static inline void copy_exception( void *object, void **dest, UINT catch_flags, else { if (type->flags & CLASS_IS_WINRT && *(IUnknown**)object) - IUnknown_AddRef(*(IUnknown**)object); + IUnknown_Release(*(IUnknown**)object); memmove( dest, get_this_pointer( &type->offsets, object ), type->size ); } }
First patch is conceptually good. Please add the code to existing dlls/msvcrt/except_ARCH.c files instead of adding new ones. I'm also expecting that the change should be added to all C-runtime versions.
2nd and 3rd patch is wrong. It's vccorlib140 job to release the extra reference and there's no way of doing it correctly from vcruntime140.dll. It looks like there are still some more problems that we didn't debug yet but patches 2 and 3 are not going in good direction.