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.
-- v3: msvcrt: Update WinRT exception type info in _CxxThrowException. msvcrt: Rename exception *IUNKNOWN flags to *WINRT.
From: Piotr Caban piotr@codeweavers.com
It's only used for WinRT exceptions (not for other COM objects). --- dlls/msvcrt/cppexcept.h | 8 ++++---- dlls/msvcrt/except.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/msvcrt/cppexcept.h b/dlls/msvcrt/cppexcept.h index 21a7e6a8009..61267add740 100644 --- a/dlls/msvcrt/cppexcept.h +++ b/dlls/msvcrt/cppexcept.h @@ -135,12 +135,12 @@ typedef struct
#define CLASS_IS_SIMPLE_TYPE 1 #define CLASS_HAS_VIRTUAL_BASE_CLASS 4 -#define CLASS_IS_IUNKNOWN 8 +#define CLASS_IS_WINRT 8
#define TYPE_FLAG_CONST 1 #define TYPE_FLAG_VOLATILE 2 #define TYPE_FLAG_REFERENCE 8 -#define TYPE_FLAG_IUNKNOWN 16 +#define TYPE_FLAG_WINRT 16
void WINAPI DECLSPEC_NORETURN _CxxThrowException(void*,const cxx_exception_type*);
@@ -248,7 +248,7 @@ static inline void copy_exception( void *object, void **dest, UINT catch_flags, } else if (type->flags & CLASS_IS_SIMPLE_TYPE) { - if (type->flags & CLASS_IS_IUNKNOWN && *(IUnknown**)object) + if (type->flags & CLASS_IS_WINRT && *(IUnknown**)object) IUnknown_AddRef(*(IUnknown**)object); memmove( dest, object, type->size ); /* if it is a pointer, adjust it */ @@ -264,7 +264,7 @@ static inline void copy_exception( void *object, void **dest, UINT catch_flags, } else { - if (type->flags & CLASS_IS_IUNKNOWN && *(IUnknown**)object) + if (type->flags & CLASS_IS_WINRT && *(IUnknown**)object) IUnknown_AddRef(*(IUnknown**)object); memmove( dest, get_this_pointer( &type->offsets, object ), type->size ); } diff --git a/dlls/msvcrt/except.c b/dlls/msvcrt/except.c index bed1df0276e..383c67f7437 100644 --- a/dlls/msvcrt/except.c +++ b/dlls/msvcrt/except.c @@ -964,7 +964,7 @@ void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
if (info->destructor) call_dtor( cxx_rva( info->destructor, rec->ExceptionInformation[3] ), object ); - else if (info->flags & TYPE_FLAG_IUNKNOWN && *(IUnknown**)object) + else if (info->flags & TYPE_FLAG_WINRT && *(IUnknown**)object) IUnknown_Release( *(IUnknown**)object ); }
From: Vibhav Pant vibhavp@gmail.com
--- dlls/msvcrt/cpp.c | 10 ++++++++++ dlls/msvcrt/cppexcept.h | 13 +++++++++++++ 2 files changed, 23 insertions(+)
diff --git a/dlls/msvcrt/cpp.c b/dlls/msvcrt/cpp.c index c30fd4994a6..c8537bda8f4 100644 --- a/dlls/msvcrt/cpp.c +++ b/dlls/msvcrt/cpp.c @@ -903,6 +903,16 @@ void WINAPI _CxxThrowException( void *object, const cxx_exception_type *type ) { ULONG_PTR args[CXX_EXCEPTION_PARAMS];
+ if (type && type->flags & TYPE_FLAG_WINRT) + { + /* This is a WinRT exception, which contains a pointer to winrt_exception_info just before the object. + * We use the exception_type field inside that struct as the actual value for exception type. */ + winrt_exception_info **info = *(winrt_exception_info ***)object - 1; + + type = (*info)->exception_type; + (*info)->set_exception_info( info ); + } + args[0] = CXX_FRAME_MAGIC_VC6; args[1] = (ULONG_PTR)object; args[2] = (ULONG_PTR)type; diff --git a/dlls/msvcrt/cppexcept.h b/dlls/msvcrt/cppexcept.h index 61267add740..0f64f97dd20 100644 --- a/dlls/msvcrt/cppexcept.h +++ b/dlls/msvcrt/cppexcept.h @@ -142,6 +142,19 @@ typedef struct #define TYPE_FLAG_REFERENCE 8 #define TYPE_FLAG_WINRT 16
+typedef struct winrt_exception_info +{ + BSTR description; + BSTR restricted_desc; + void *unknown1; + void *unknown2; + HRESULT hr; + void *error_info; /* IRestrictedErrorInfo */ + const cxx_exception_type *exception_type; + UINT32 unknown3; + void (*WINAPI set_exception_info)(struct winrt_exception_info **); +} winrt_exception_info; + void WINAPI DECLSPEC_NORETURN _CxxThrowException(void*,const cxx_exception_type*);
static inline BOOL is_cxx_exception( EXCEPTION_RECORD *rec )
I've pushed a version with some minor style changes. Thank you.
On Wed Oct 29 14:40:07 2025 +0000, Piotr Caban wrote:
I've pushed a version with some minor style changes. Thank you.
Thanks.
This merge request was approved by Piotr Caban.