Another dependency for !9209.
When C++/CX applications manually throw exceptions (i.e, by calling `_CxxThrowException` and not `__abi_WinRTraise*`), msvcrt/ucrt will still use the `cxx_exception_type` RTTI data from `vccorlib`, and not the one passed by the user. It also invokes a callback inside `exception_info`, which likely performs the necessary RoOriginateError/RoOriginateLanguageException bookkeeping and sets the `IRestrictedErrorInfo` field.
-- v2: msvcrt: Use the correct arguments when a WinRT exception is thrown with _CxxThrowException.
From: Vibhav Pant vibhavp@gmail.com
--- dlls/msvcrt/cpp.c | 9 +++++++++ dlls/msvcrt/cppexcept.h | 14 ++++++++++++++ 2 files changed, 23 insertions(+)
diff --git a/dlls/msvcrt/cpp.c b/dlls/msvcrt/cpp.c index c30fd4994a6..c5dec95c373 100644 --- a/dlls/msvcrt/cpp.c +++ b/dlls/msvcrt/cpp.c @@ -905,6 +905,15 @@ void WINAPI _CxxThrowException( void *object, const cxx_exception_type *type )
args[0] = CXX_FRAME_MAGIC_VC6; args[1] = (ULONG_PTR)object; + if (type && type->flags & TYPE_FLAG_IUNKNOWN) + { + /* This is a COM/WinRT exception, which contains a pointer to com_exception_info just before the object. + * We use the exception_type field inside that struct as the actual value for args[2]. */ + com_exception_info **info = (com_exception_info **)((char *)*(void **)object - sizeof(void *)); + + type = (*info)->exception_type; + (*info)->set_exception_info( info ); + } args[2] = (ULONG_PTR)type; if (CXX_EXCEPTION_PARAMS == 4) args[3] = cxx_rva_base( type ); for (;;) RaiseException( CXX_EXCEPTION, EXCEPTION_NONCONTINUABLE, CXX_EXCEPTION_PARAMS, args ); diff --git a/dlls/msvcrt/cppexcept.h b/dlls/msvcrt/cppexcept.h index 21a7e6a8009..98e26da6f11 100644 --- a/dlls/msvcrt/cppexcept.h +++ b/dlls/msvcrt/cppexcept.h @@ -142,6 +142,20 @@ typedef struct #define TYPE_FLAG_REFERENCE 8 #define TYPE_FLAG_IUNKNOWN 16
+typedef struct +{ + BSTR message1; + BSTR message2; + void *unknown1; + void *unknown2; + HRESULT hr; + void *error_info; /* IRestrictedErrorInfo */ + const cxx_exception_type *exception_type; + UINT32 unknown3; + /* Sets message1, message2, error_info. */ + void (*WINAPI set_exception_info)(void *); +} com_exception_info; + void WINAPI DECLSPEC_NORETURN _CxxThrowException(void*,const cxx_exception_type*);
static inline BOOL is_cxx_exception( EXCEPTION_RECORD *rec )