From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/except.c | 85 +++++++++++++++++++++++-------- dlls/vccorlib140/private.h | 6 ++- dlls/vccorlib140/tests/vccorlib.c | 11 ++-- 3 files changed, 70 insertions(+), 32 deletions(-)
diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index e57b37bad32..d00f35c71f1 100644 --- a/dlls/vccorlib140/except.c +++ b/dlls/vccorlib140/except.c @@ -32,6 +32,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(vccorlib);
+extern void WINAPI DECLSPEC_NORETURN _CxxThrowException(void *, const cxx_exception_type *); + #ifdef _WIN64 #define EXCEPTION_REF_NAME(name) ".PE$AAV" #name "Exception@Platform@@" #else @@ -77,23 +79,6 @@ struct Exception IUnknown *marshal; };
-void *__cdecl CreateExceptionWithMessage(HRESULT hr, HSTRING msg) -{ - FIXME("(%#lx, %s): stub!\n", hr, debugstr_hstring(msg)); - return NULL; -} - -void *__cdecl CreateException(HRESULT hr) -{ - FIXME("(%#lx): stub!\n", hr); - return NULL; -} - -void WINAPI __abi_WinRTraiseCOMException(HRESULT hr) -{ - FIXME("(%#lx): stub!\n", hr); -} - #define WINRT_EXCEPTIONS \ WINRT_EXCEPTION(AccessDenied, E_ACCESSDENIED) \ WINRT_EXCEPTION(ChangedState, E_CHANGED_STATE) \ @@ -407,15 +392,71 @@ struct Exception *__cdecl COMException_hstring_ctor(struct Exception *this, HRES this->IClosable_iface.lpVtbl = &name##Exception_Closable_vtable.vtable; \ this->inner.exception_type = &name##Exception_ref_exception_type; \ return this; \ - } \ - \ - void WINAPI __abi_WinRTraise##name##Exception(void) \ - { \ - FIXME("(): stub!\n"); \ } WINRT_EXCEPTIONS #undef WINRT_EXCEPTION
+struct Exception *__cdecl CreateExceptionWithMessage(HRESULT code, HSTRING msg) +{ + struct Exception *ret; + + TRACE("(%#lx, %s)\n", code, debugstr_hstring(msg)); + + ret = AllocateExceptionWithWeakRef(offsetof(struct Exception, control_block), sizeof(*ret)); + +#define WINRT_EXCEPTION(name, h) \ + case (h): \ + name##Exception_hstring_ctor(ret, msg); \ + break; + + switch (code) + { + WINRT_EXCEPTIONS; +#undef WINRT_EXCEPTION + default: + COMException_hstring_ctor(ret, code, msg); + break; + } + + return ret; +} + +struct Exception *__cdecl CreateException(HRESULT hr) +{ + TRACE("(%#lx)\n", hr); + return CreateExceptionWithMessage(hr, NULL); +} + +static void DECLSPEC_NORETURN throw_exception(struct Exception *excp, const cxx_exception_type *type) + { + /* Thrown exceptions have a refcount of 2. */ + IInspectable_AddRef(&excp->IInspectable_iface); + _CxxThrowException(&excp, type); +} + +#define WINRT_EXCEPTION(name, hr) \ + void WINAPI DECLSPEC_NORETURN __abi_WinRTraise##name##Exception(void) \ + { \ + FIXME("(): semi-stub!\n"); \ + throw_exception(CreateException(hr), &name##Exception_ref_exception_type); \ + } +WINRT_EXCEPTIONS +#undef WINRT_EXCEPTION + +void WINAPI DECLSPEC_NORETURN __abi_WinRTraiseCOMException(HRESULT hr) +{ + FIXME("(%#lx): semi-stub!\n", hr); + + switch (hr) + { +#define WINRT_EXCEPTION(name, code) case (code): __abi_WinRTraise##name##Exception(); + WINRT_EXCEPTIONS; +#undef WINRT_EXCEPTION + default: + throw_exception(CreateException(hr), &COMException_ref_exception_type); + } +} + HSTRING __cdecl Exception_get_Message(struct Exception *this) { HSTRING msg = NULL; diff --git a/dlls/vccorlib140/private.h b/dlls/vccorlib140/private.h index 18410955f05..f5cb3fc69fb 100644 --- a/dlls/vccorlib140/private.h +++ b/dlls/vccorlib140/private.h @@ -41,11 +41,13 @@ struct control_block #endif };
+void *__cdecl AllocateExceptionWithWeakRef(ptrdiff_t, size_t); void __cdecl FreeException(void *);
void init_exception(void *); -void WINAPI __abi_WinRTraiseInvalidArgumentException(void); -void WINAPI __abi_WinRTraiseOutOfMemoryException(void); +void WINAPI DECLSPEC_NORETURN __abi_WinRTraiseCOMException(HRESULT); +void WINAPI DECLSPEC_NORETURN __abi_WinRTraiseInvalidArgumentException(void); +void WINAPI DECLSPEC_NORETURN __abi_WinRTraiseOutOfMemoryException(void);
#define COM_VTABLE_RTTI_START(iface, type) \ static const struct \ diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index 826a55a76e8..c4f669d8190 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -1373,17 +1373,12 @@ static void test_exceptions(void)
cur_test = &test_cases[i]; obj = pCreateException(cur_test->hr); - todo_wine ok(obj != NULL, "got obj %p\n", obj); - if (!obj) - { - winetest_pop_context(); - continue; - } + ok(obj != NULL, "got obj %p\n", obj);
inspectable = (IInspectable *)obj; /* Verify that the IMarshal field is lazily-initialized. */ ok((ULONG_PTR)obj->marshal == UINTPTR_MAX, "got marshal %p\n", obj->marshal); - todo_wine check_interface(inspectable, &IID_IMarshal); + check_interface(inspectable, &IID_IMarshal); ok(obj->marshal != NULL && (ULONG_PTR)obj->marshal != UINTPTR_MAX, "got marshal %p\n", obj->marshal);
test_interface_layout(obj, &IID_IUnknown, &obj->IInspectable_iface); @@ -1514,7 +1509,7 @@ static void test_exceptions(void)
cxx_info = (cxx_type_info *)(base + type_info_table->info[j]); if (j == type_info_table->count - 1) - ok(cxx_info->flags == CLASS_IS_SIMPLE_TYPE, "got flags %u\n", cxx_info->flags); + todo_wine ok(cxx_info->flags == CLASS_IS_SIMPLE_TYPE, "got flags %u\n", cxx_info->flags); else ok(cxx_info->flags == (CLASS_IS_SIMPLE_TYPE | CLASS_IS_IUNKNOWN), "got flags %u\n", cxx_info->flags); ok(cxx_info->size == sizeof(void *), "got size %u\n", cxx_info->size);