[PATCH v14 0/11] MR9209: vccorlib140: Implement Platform::Exceptions.
-- v14: vccorlib140: Implement __abi_translateCurrentException. vccorlib140: Throw exceptions on error paths. vccorlib140: Add Platform::Exception::CreateException() implementation. vccorlib140: Add Platform::Exception::Message::get() implementation. vccorlib140: Add Platform::COMException constructor implementation. vccorlib140: Add Platform::Exception(HSTRING) constructor implementation. msvcrt: Sync cxx.h file with msvcp90 and vccorlib140. vccorlib140: Add Platform::Exception constructor implementation. vccorlib140: Remove platform_ prefix from exception function names. vccorlib140: Move exception functions to new file. vccorlib140/tests: Add additional tests for exception objects. https://gitlab.winehq.org/wine/wine/-/merge_requests/9209
From: Vibhav Pant <vibhavp(a)gmail.com> --- dlls/vccorlib140/tests/vccorlib.c | 121 ++++++++++++++++++++++++++---- 1 file changed, 105 insertions(+), 16 deletions(-) diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index 95ce908d49d..826a55a76e8 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -1255,9 +1255,9 @@ typedef struct struct exception_inner { /* This only gets set when the exception is thrown. */ - BSTR message1; + BSTR description; /* Likewise, but can also be set by CreateExceptionWithMessage. */ - BSTR message2; + BSTR restricted_desc; void *unknown1; void *unknown2; HRESULT hr; @@ -1265,7 +1265,8 @@ struct exception_inner IRestrictedErrorInfo *error_info; const cxx_exception_type *exception_type; UINT32 unknown3; - void *unknown4; + /* Called before the exception is thrown by _CxxThrowException. */ + void (*WINAPI set_exception_info)(struct exception_inner **); }; struct platform_exception @@ -1351,6 +1352,7 @@ static void test_exceptions(void) const cxx_type_info_table *type_info_table; const char *rtti_name, *rtti_raw_name; const struct exception_inner *inner; + IRestrictedErrorInfo *error_info; const rtti_type_info *rtti_info; const cxx_exception_type *type; struct platform_exception *obj; @@ -1360,6 +1362,7 @@ static void test_exceptions(void) INT32 j, ret = 0; void *type_info; WCHAR buf[256]; + BOOL desc_todo; IUnknown *out; HSTRING str; ULONG count; @@ -1447,6 +1450,7 @@ static void test_exceptions(void) str = p_platform_exception_get_Message(obj); ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, cur_test->hr, 0, buf, ARRAY_SIZE(buf), NULL); ok(!!str == !!ret, "got str %s\n", debugstr_hstring(str)); + desc_todo = !ret; if(ret) { bufW = WindowsGetStringRawBuffer(str, NULL); @@ -1456,8 +1460,8 @@ static void test_exceptions(void) inner = *(const struct exception_inner **)((ULONG_PTR)obj - sizeof(ULONG_PTR)); ok(inner == &obj->inner, "got inner %p != %p\n", inner, &obj->inner); - ok(inner->message1 == NULL, "got message1 %p\n", inner->message1); - ok(inner->message2 == NULL, "got message2 %p\n", inner->message2); + ok(inner->description == NULL, "got description %p\n", inner->description); + ok(inner->restricted_desc == NULL, "got restricted_desc %p\n", inner->restricted_desc); ok(inner->unknown1 == NULL, "got unknown1 %p\n", inner->unknown1); ok(inner->unknown2 == NULL, "got unknown2 %p\n", inner->unknown2); ok(inner->hr == cur_test->hr, "got hr %#lx != %#lx\n", inner->hr, cur_test->hr); @@ -1467,6 +1471,32 @@ static void test_exceptions(void) ok(inner->unknown3 == 64, "got unknown3 %u\n", inner->unknown3); else ok(inner->unknown3 == 32, "got unknown3 %u \n", inner->unknown3); + ok(obj->inner.set_exception_info != NULL, "got inner.set_exception_info %p\n", + obj->inner.set_exception_info); + obj->inner.set_exception_info((struct exception_inner **)((ULONG_PTR)obj - sizeof(ULONG_PTR))); + todo_wine_if(desc_todo) + ok(inner->description != NULL, "got description %p\n", inner->description); + todo_wine_if(desc_todo) + ok(inner->restricted_desc != NULL, "got restricted_desc %p\n", inner->restricted_desc); + todo_wine ok(inner->error_info != NULL, "got error_info %p\n", inner->error_info); + if ((error_info = inner->error_info)) + { + BSTR desc, restricted_desc, sid; + HRESULT code; + + IRestrictedErrorInfo_AddRef(error_info); + test_refcount(error_info, 2); + + hr = IRestrictedErrorInfo_GetErrorDetails(error_info, &desc, &code, &restricted_desc, &sid); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(!wcscmp(desc, inner->description), "got desc %s != %s\n", debugstr_w(desc), debugstr_w(inner->description)); + ok(!wcscmp(restricted_desc, inner->restricted_desc), "got restricted_desc %s != %s\n", + debugstr_w(restricted_desc), debugstr_w(inner->restricted_desc)); + ok(code == inner->hr, "got code %#lx != %#lx\n", code, inner->hr); + SysFreeString(desc); + SysFreeString(restricted_desc); + SysFreeString(sid); + } type = inner->exception_type; ok(type->flags == TYPE_FLAG_IUNKNOWN, "got flags %#x\n", type->flags); @@ -1502,6 +1532,12 @@ static void test_exceptions(void) count = IInspectable_Release(inspectable); ok(count == 0, "got count %lu\n", count); + if (error_info) + { + count = IRestrictedErrorInfo_Release(error_info); + ok(count == 0, "got count %lu\n", count); + } + /* Create an Exception object with a custom message. */ inspectable = pCreateExceptionWithMessage(cur_test->hr, msg); ok(inspectable != NULL, "got excp %p\n", inspectable); @@ -1512,13 +1548,13 @@ static void test_exceptions(void) WindowsDeleteString(str); inner = (const struct exception_inner *)*(ULONG_PTR *)((ULONG_PTR)inspectable - sizeof(ULONG_PTR)); - ok(inner->message1 == NULL, "got message1 %p\n", inner->message1); - ok(inner->message2 != NULL, "got message2 %p\n", inner->message2); + ok(inner->description == NULL, "got description %p\n", inner->description); + ok(inner->restricted_desc != NULL, "got restricted_desc %p\n", inner->restricted_desc); ok(inner->unknown1 == NULL, "got unknown3 %p\n", inner->unknown1); ok(inner->unknown2 == NULL, "got unknown4 %p\n", inner->unknown2); - ok(!wcscmp(inner->message2, msg_bufW), "got message2 %s != %s\n", debugstr_w(inner->message2), + ok(!wcscmp(inner->restricted_desc, msg_bufW), "got restricted_desc %s != %s\n", debugstr_w(inner->restricted_desc), debugstr_w(msg_bufW)); - ret = SysStringLen(inner->message2); /* Verify that message2 is a BSTR. */ + ret = SysStringLen(inner->restricted_desc); /* Verify that restricted_desc is a BSTR. */ ok(ret == wcslen(msg_bufW), "got ret %u != %Iu\n", ret, wcslen(msg_bufW)); count = IInspectable_Release(inspectable); @@ -1545,13 +1581,38 @@ static void test_exceptions(void) inner = *(const struct exception_inner **)((ULONG_PTR)obj - sizeof(ULONG_PTR)); ok(inner == &obj->inner, "got inner %p != %p\n", inner, &obj->inner); - ok(inner->message1 == NULL, "got message1 %p\n", inner->message1); - ok(inner->message2 == NULL, "got message2 %p\n", inner->message2); + ok(inner->description == NULL, "got description %p\n", inner->description); + ok(inner->restricted_desc == NULL, "got restricted_desc %p\n", inner->restricted_desc); ok(inner->unknown1 == NULL, "got unknown1 %p\n", inner->unknown1); ok(inner->unknown2 == NULL, "got unknown2 %p\n", inner->unknown2); + ok(inner->error_info == NULL, "got error_info %p\n", inner->error_info); ok(obj->inner.exception_type == type, "got inner.exception_type %p != %p\n", obj->inner.exception_type, type); ok(obj->inner.hr == cur_test->hr, "got inner.hr %#lx != %#lx", obj->inner.hr, cur_test->hr); + ok(obj->inner.set_exception_info != NULL, "got inner.set_exception_info %p\n", + obj->inner.set_exception_info); + + obj->inner.set_exception_info((struct exception_inner **)((ULONG_PTR)obj - sizeof(ULONG_PTR))); + todo_wine_if(desc_todo) + ok(inner->description != NULL, "got description %p\n", inner->description); + todo_wine_if(desc_todo) + ok(inner->restricted_desc != NULL, "got restricted_desc %p\n", inner->restricted_desc); + todo_wine ok(inner->error_info != NULL, "got error_info %p\n", inner->error_info); + if (inner->error_info) + { + BSTR desc, restricted_desc, sid; + HRESULT code; + + hr = IRestrictedErrorInfo_GetErrorDetails(inner->error_info, &desc, &code, &restricted_desc, &sid); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(!wcscmp(desc, inner->description), "got desc %s != %s\n", debugstr_w(desc), debugstr_w(inner->description)); + ok(!wcscmp(restricted_desc, inner->restricted_desc), "got restricted_desc %s != %s\n", + debugstr_w(restricted_desc), debugstr_w(inner->restricted_desc)); + ok(code == inner->hr, "got code %#lx != %#lx\n", code, inner->hr); + SysFreeString(desc); + SysFreeString(restricted_desc); + SysFreeString(sid); + } count = IInspectable_Release(inspectable); ok(count == 0, "got count %lu\n", count); @@ -1576,17 +1637,45 @@ static void test_exceptions(void) inner = *(const struct exception_inner **)((ULONG_PTR)obj - sizeof(ULONG_PTR)); ok(inner == &obj->inner, "got inner %p != %p\n", inner, &obj->inner); - ok(inner->message1 == NULL, "got message1 %p\n", inner->message1); - ok(inner->message2 != NULL, "got message2 %p\n", inner->message2); - ok(!wcscmp(inner->message2, msg_bufW), "got message2 %s != %s\n", debugstr_w(inner->message2), - debugstr_w(msg_bufW)); - ret = SysStringLen(inner->message2); /* Verify that message2 is a BSTR. */ + ok(inner->description == NULL, "got description %p\n", inner->description); + ok(inner->restricted_desc != NULL, "got restricted_desc %p\n", inner->restricted_desc); + ok(!wcscmp(inner->restricted_desc, msg_bufW), "got restricted_desc %s != %s\n", + debugstr_w(inner->restricted_desc), debugstr_w(msg_bufW)); + ret = SysStringLen(inner->restricted_desc); /* Verify that restricted_desc is a BSTR. */ ok(ret == wcslen(msg_bufW), "got ret %u != %Iu\n", ret, wcslen(msg_bufW)); ok(inner->unknown1 == NULL, "got unknown1 %p\n", inner->unknown1); ok(inner->unknown2 == NULL, "got unknown2 %p\n", inner->unknown2); + ok(inner->error_info == NULL, "got error_info %p\n", inner->error_info); ok(obj->inner.exception_type == type, "got inner.exception_type %p != %p\n", obj->inner.exception_type, type); ok(obj->inner.hr == cur_test->hr, "got inner.hr %#lx != %#lx", obj->inner.hr, cur_test->hr); + ok(obj->inner.set_exception_info != NULL, "got inner.set_exception_info %p\n", + obj->inner.set_exception_info); + + obj->inner.set_exception_info((struct exception_inner **)((ULONG_PTR)obj - sizeof(ULONG_PTR))); + todo_wine_if(desc_todo) + ok(inner->description != NULL, "got description %p\n", inner->description); + ok(inner->restricted_desc != NULL, "got restricted_desc %p\n", inner->restricted_desc); + /* restricted_desc should not change. */ + ok(!wcscmp(inner->restricted_desc, msg_bufW), "got restricted_desc %s != %s\n", + debugstr_w(inner->restricted_desc), debugstr_w(msg_bufW)); + todo_wine ok(inner->error_info != NULL, "got error_info %p\n", inner->error_info); + if (inner->error_info) + { + BSTR desc, restricted_desc, sid; + HRESULT code; + + hr = IRestrictedErrorInfo_GetErrorDetails(inner->error_info, &desc, &code, &restricted_desc, &sid); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(!wcscmp(desc, inner->description), "got desc %s != %s\n", debugstr_w(desc), + debugstr_w(inner->description)); + ok(!wcscmp(restricted_desc, inner->restricted_desc), "got restricted_desc %s != %s\n", + debugstr_w(restricted_desc), debugstr_w(inner->restricted_desc)); + ok(code == inner->hr, "got code %#lx != %#lx\n", code, inner->hr); + SysFreeString(desc); + SysFreeString(restricted_desc); + SysFreeString(sid); + } count = IInspectable_Release(inspectable); ok(count == 0, "got count %lu\n", count); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9209
From: Piotr Caban <piotr(a)codeweavers.com> --- dlls/vccorlib140/Makefile.in | 1 + dlls/vccorlib140/except.c | 105 +++++++++++++++++++++++++++++++++++ dlls/vccorlib140/vccorlib.c | 82 --------------------------- 3 files changed, 106 insertions(+), 82 deletions(-) create mode 100644 dlls/vccorlib140/except.c diff --git a/dlls/vccorlib140/Makefile.in b/dlls/vccorlib140/Makefile.in index 13d54aa369e..988d761efda 100644 --- a/dlls/vccorlib140/Makefile.in +++ b/dlls/vccorlib140/Makefile.in @@ -2,4 +2,5 @@ MODULE = vccorlib140.dll IMPORTS = combase SOURCES = \ + except.c \ vccorlib.c diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c new file mode 100644 index 00000000000..3a65cbebbf7 --- /dev/null +++ b/dlls/vccorlib140/except.c @@ -0,0 +1,105 @@ +/* + * Copyright 2025 Vibhav Pant + * + * 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 "roapi.h" +#include "winstring.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(vccorlib); + +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) \ + WINRT_EXCEPTION(ClassNotRegistered, REGDB_E_CLASSNOTREG) \ + WINRT_EXCEPTION(Disconnected, RPC_E_DISCONNECTED) \ + WINRT_EXCEPTION(Failure, E_FAIL) \ + WINRT_EXCEPTION(InvalidArgument, E_INVALIDARG) \ + WINRT_EXCEPTION(InvalidCast, E_NOINTERFACE) \ + WINRT_EXCEPTION(NotImplemented, E_NOTIMPL) \ + WINRT_EXCEPTION(NullReference, E_POINTER) \ + WINRT_EXCEPTION(ObjectDisposed, RO_E_CLOSED) \ + WINRT_EXCEPTION(OperationCanceled, E_ABORT) \ + WINRT_EXCEPTION(OutOfBounds, E_BOUNDS) \ + WINRT_EXCEPTION(OutOfMemory, E_OUTOFMEMORY) \ + WINRT_EXCEPTION(WrongThread, RPC_E_WRONG_THREAD) + +#define WINRT_EXCEPTION(name, hr) \ + void WINAPI __abi_WinRTraise##name##Exception(void) \ + { \ + FIXME("(): stub!\n"); \ + } \ + void *__cdecl platform_##name##Exception_ctor(void *this) \ + { \ + FIXME("(%p): stub!\n", this); \ + return this; \ + } \ + void *__cdecl platform_##name##Exception_hstring_ctor(void *this, HSTRING msg) \ + { \ + FIXME("(%p, %s): stub!\n", this, debugstr_hstring(msg)); \ + return this; \ + } + +WINRT_EXCEPTIONS +#undef WINRT_EXCEPTION + +void *__cdecl platform_Exception_ctor(void *this, HRESULT hr) +{ + FIXME("(%p, %#lx): stub!\n", this, hr); + return this; +} + +void *__cdecl platform_Exception_hstring_ctor(void *this, HRESULT hr, HSTRING msg) +{ + FIXME("(%p, %#lx, %s): stub!\n", this, hr, debugstr_hstring(msg)); + return this; +} + +void *__cdecl platform_COMException_ctor(void *this, HRESULT hr) +{ + FIXME("(%p, %#lx): stub!\n", this, hr); + return this; +} + +void *__cdecl platform_COMException_hstring_ctor(void *this, HRESULT hr, HSTRING msg) +{ + FIXME("(%p, %#lx, %s): stub!\n", this, hr, debugstr_hstring(msg)); + return this; +} + +HSTRING __cdecl platform_exception_get_Message(void *excp) +{ + FIXME("(%p): stub!\n", excp); + return NULL; +} diff --git a/dlls/vccorlib140/vccorlib.c b/dlls/vccorlib140/vccorlib.c index 68100ac7291..869d40aea10 100644 --- a/dlls/vccorlib140/vccorlib.c +++ b/dlls/vccorlib140/vccorlib.c @@ -611,88 +611,6 @@ void *WINAPI CreateValue(int typecode, const void *val) return obj; } -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) \ - WINRT_EXCEPTION(ClassNotRegistered, REGDB_E_CLASSNOTREG) \ - WINRT_EXCEPTION(Disconnected, RPC_E_DISCONNECTED) \ - WINRT_EXCEPTION(Failure, E_FAIL) \ - WINRT_EXCEPTION(InvalidArgument, E_INVALIDARG) \ - WINRT_EXCEPTION(InvalidCast, E_NOINTERFACE) \ - WINRT_EXCEPTION(NotImplemented, E_NOTIMPL) \ - WINRT_EXCEPTION(NullReference, E_POINTER) \ - WINRT_EXCEPTION(ObjectDisposed, RO_E_CLOSED) \ - WINRT_EXCEPTION(OperationCanceled, E_ABORT) \ - WINRT_EXCEPTION(OutOfBounds, E_BOUNDS) \ - WINRT_EXCEPTION(OutOfMemory, E_OUTOFMEMORY) \ - WINRT_EXCEPTION(WrongThread, RPC_E_WRONG_THREAD) - -#define WINRT_EXCEPTION(name, hr) \ - void WINAPI __abi_WinRTraise##name##Exception(void) \ - { \ - FIXME("(): stub!\n"); \ - } \ - void *__cdecl platform_##name##Exception_ctor(void *this) \ - { \ - FIXME("(%p): stub!\n", this); \ - return this; \ - } \ - void *__cdecl platform_##name##Exception_hstring_ctor(void *this, HSTRING msg) \ - { \ - FIXME("(%p, %s): stub!\n", this, debugstr_hstring(msg)); \ - return this; \ - } - -WINRT_EXCEPTIONS -#undef WINRT_EXCEPTION - -void *__cdecl platform_Exception_ctor(void *this, HRESULT hr) -{ - FIXME("(%p, %#lx): stub!\n", this, hr); - return this; -} - -void *__cdecl platform_Exception_hstring_ctor(void *this, HRESULT hr, HSTRING msg) -{ - FIXME("(%p, %#lx, %s): stub!\n", this, hr, debugstr_hstring(msg)); - return this; -} - -void *__cdecl platform_COMException_ctor(void *this, HRESULT hr) -{ - FIXME("(%p, %#lx): stub!\n", this, hr); - return this; -} - -void *__cdecl platform_COMException_hstring_ctor(void *this, HRESULT hr, HSTRING msg) -{ - FIXME("(%p, %#lx, %s): stub!\n", this, hr, debugstr_hstring(msg)); - return this; -} - -HSTRING __cdecl platform_exception_get_Message(void *excp) -{ - FIXME("(%p): stub!\n", excp); - return NULL; -} - BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { if (reason == DLL_PROCESS_ATTACH) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9209
From: Piotr Caban <piotr(a)codeweavers.com> --- dlls/vccorlib140/except.c | 14 ++-- dlls/vccorlib140/vccorlib140.spec | 132 +++++++++++++++--------------- 2 files changed, 73 insertions(+), 73 deletions(-) diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index 3a65cbebbf7..0165fe8878f 100644 --- a/dlls/vccorlib140/except.c +++ b/dlls/vccorlib140/except.c @@ -60,12 +60,12 @@ void WINAPI __abi_WinRTraiseCOMException(HRESULT hr) { \ FIXME("(): stub!\n"); \ } \ - void *__cdecl platform_##name##Exception_ctor(void *this) \ + void *__cdecl name##Exception_ctor(void *this) \ { \ FIXME("(%p): stub!\n", this); \ return this; \ } \ - void *__cdecl platform_##name##Exception_hstring_ctor(void *this, HSTRING msg) \ + void *__cdecl name##Exception_hstring_ctor(void *this, HSTRING msg) \ { \ FIXME("(%p, %s): stub!\n", this, debugstr_hstring(msg)); \ return this; \ @@ -74,31 +74,31 @@ void WINAPI __abi_WinRTraiseCOMException(HRESULT hr) WINRT_EXCEPTIONS #undef WINRT_EXCEPTION -void *__cdecl platform_Exception_ctor(void *this, HRESULT hr) +void *__cdecl Exception_ctor(void *this, HRESULT hr) { FIXME("(%p, %#lx): stub!\n", this, hr); return this; } -void *__cdecl platform_Exception_hstring_ctor(void *this, HRESULT hr, HSTRING msg) +void *__cdecl Exception_hstring_ctor(void *this, HRESULT hr, HSTRING msg) { FIXME("(%p, %#lx, %s): stub!\n", this, hr, debugstr_hstring(msg)); return this; } -void *__cdecl platform_COMException_ctor(void *this, HRESULT hr) +void *__cdecl COMException_ctor(void *this, HRESULT hr) { FIXME("(%p, %#lx): stub!\n", this, hr); return this; } -void *__cdecl platform_COMException_hstring_ctor(void *this, HRESULT hr, HSTRING msg) +void *__cdecl COMException_hstring_ctor(void *this, HRESULT hr, HSTRING msg) { FIXME("(%p, %#lx, %s): stub!\n", this, hr, debugstr_hstring(msg)); return this; } -HSTRING __cdecl platform_exception_get_Message(void *excp) +HSTRING __cdecl Exception_get_Message(void *excp) { FIXME("(%p): stub!\n", excp); return NULL; diff --git a/dlls/vccorlib140/vccorlib140.spec b/dlls/vccorlib140/vccorlib140.spec index b6c1f985c0c..64b01047337 100644 --- a/dlls/vccorlib140/vccorlib140.spec +++ b/dlls/vccorlib140/vccorlib140.spec @@ -1,7 +1,7 @@ @ stub -arch=win32 ?<Dispose>@Exception(a)Platform@@U$AAAXXZ @ stub -arch=win64 ?<Dispose>@Exception(a)Platform@@UE$AAAXXZ -@ cdecl -arch=win32 ??0ChangedStateException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_ChangedStateException_hstring_ctor -@ cdecl -arch=win64 ??0ChangedStateException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_ChangedStateException_hstring_ctor +@ cdecl -arch=win32 ??0ChangedStateException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) ChangedStateException_hstring_ctor +@ cdecl -arch=win64 ??0ChangedStateException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) ChangedStateException_hstring_ctor @ stub -arch=win32 ?Equals(a)Exception@Platform@@U$AAA_NP$AAVObject(a)2@@Z @ stub -arch=win64 ?Equals(a)Exception@Platform@@UE$AAA_NPE$AAVObject(a)2@@Z @ stub -arch=win32 ?Equals(a)MTAThreadAttribute@Platform@@Q$AAA_NP$AAVObject(a)2@@Z @@ -22,8 +22,8 @@ @ stub -arch=win64 ?Equals(a)float32@default@@QEAA_NPE$AAVObject(a)Platform@@@Z @ stub -arch=win32 ?Equals(a)float64@default@@QAA_NP$AAVObject(a)Platform@@@Z @ stub -arch=win64 ?Equals(a)float64@default@@QEAA_NPE$AAVObject(a)Platform@@@Z -@ cdecl -arch=win32 ??0ChangedStateException(a)Platform@@Q$AAA(a)XZ(ptr) platform_ChangedStateException_ctor -@ cdecl -arch=win64 ??0ChangedStateException(a)Platform@@QE$AAA(a)XZ(ptr) platform_ChangedStateException_ctor +@ cdecl -arch=win32 ??0ChangedStateException(a)Platform@@Q$AAA(a)XZ(ptr) ChangedStateException_ctor +@ cdecl -arch=win64 ??0ChangedStateException(a)Platform@@QE$AAA(a)XZ(ptr) ChangedStateException_ctor @ stub -arch=win32 ?Equals(a)int16@default@@QAA_NP$AAVObject(a)Platform@@@Z @ stub -arch=win64 ?Equals(a)int16@default@@QEAA_NPE$AAVObject(a)Platform@@@Z @ stub -arch=win32 ?Equals(a)int32@default@@QAA_NP$AAVObject(a)Platform@@@Z @@ -46,8 +46,8 @@ @ stub -arch=i386 ?EventSourceGetTargetArray(a)Details@Platform@@YGPAXPAXPAUEventLock(a)12@@Z @ stub -arch=arm ?EventSourceGetTargetArray(a)Details@Platform@@YAPAXPAXPAUEventLock(a)12@@Z @ stub -arch=win64 ?EventSourceGetTargetArray(a)Details@Platform@@YAPEAXPEAXPEAUEventLock(a)12@@Z -@ cdecl -arch=win32 ??0ClassNotRegisteredException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_ClassNotRegisteredException_hstring_ctor -@ cdecl -arch=win64 ??0ClassNotRegisteredException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_ClassNotRegisteredException_hstring_ctor +@ cdecl -arch=win32 ??0ClassNotRegisteredException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) ClassNotRegisteredException_hstring_ctor +@ cdecl -arch=win64 ??0ClassNotRegisteredException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) ClassNotRegisteredException_hstring_ctor @ stub -arch=i386 ?EventSourceGetTargetArrayEvent(a)Details@Platform@@YGPAXPAXIPBXPA_J(a)Z @ stub -arch=arm ?EventSourceGetTargetArrayEvent(a)Details@Platform@@YAPAXPAXIPBXPA_J(a)Z @ stub -arch=win64 ?EventSourceGetTargetArrayEvent(a)Details@Platform@@YAPEAXPEAXIPEBXPEA_J(a)Z @@ -76,8 +76,8 @@ @ stdcall -arch=i386 ?GetActivationFactoryByPCWSTR@@YGJPAXAAVGuid(a)Platform@@PAPAX(a)Z(wstr ptr ptr) GetActivationFactoryByPCWSTR @ stdcall -arch=arm ?GetActivationFactoryByPCWSTR@@YAJPAXAAVGuid(a)Platform@@PAPAX(a)Z(wstr ptr ptr) GetActivationFactoryByPCWSTR @ stdcall -arch=win64 ?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid(a)Platform@@PEAPEAX(a)Z(wstr ptr ptr) GetActivationFactoryByPCWSTR -@ cdecl -arch=win32 ??0ClassNotRegisteredException(a)Platform@@Q$AAA(a)XZ(ptr) platform_ClassNotRegisteredException_ctor -@ cdecl -arch=win64 ??0ClassNotRegisteredException(a)Platform@@QE$AAA(a)XZ(ptr) platform_ClassNotRegisteredException_ctor +@ cdecl -arch=win32 ??0ClassNotRegisteredException(a)Platform@@Q$AAA(a)XZ(ptr) ClassNotRegisteredException_ctor +@ cdecl -arch=win64 ??0ClassNotRegisteredException(a)Platform@@QE$AAA(a)XZ(ptr) ClassNotRegisteredException_ctor @ stub -arch=win32 ?GetCmdArguments(a)Details@Platform@@YAPAPA_WPAH(a)Z @ stub -arch=win64 ?GetCmdArguments(a)Details@Platform@@YAPEAPEA_WPEAH(a)Z @ stub -arch=win32 ?GetHashCode(a)Attribute@Metadata(a)Platform@@Q$AAAHXZ @@ -120,8 +120,8 @@ @ stub -arch=win64 ?GetHashCode(a)int64@default@@QEAAHXZ @ stub -arch=win32 ?GetHashCode(a)int8@default@@QAAHXZ @ stub -arch=win64 ?GetHashCode(a)int8@default@@QEAAHXZ -@ cdecl -arch=win32 ??0DisconnectedException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_DisconnectedException_hstring_ctor -@ cdecl -arch=win64 ??0DisconnectedException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_DisconnectedException_hstring_ctor +@ cdecl -arch=win32 ??0DisconnectedException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) DisconnectedException_hstring_ctor +@ cdecl -arch=win64 ??0DisconnectedException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) DisconnectedException_hstring_ctor @ stub -arch=win32 ?GetHashCode(a)uint16@default@@QAAHXZ @ stub -arch=win64 ?GetHashCode(a)uint16@default@@QEAAHXZ @ stub -arch=win32 ?GetHashCode(a)uint32@default@@QAAHXZ @@ -147,8 +147,8 @@ @ stub -arch=win64 ?GetProxyImpl(a)Details@Platform@@YAJPEAUIUnknown@@AEBU_GUID@@0PEAPEAU3@@Z @ stub -arch=win32 ?GetType(a)Boolean@Platform@@QAAP$AAVType(a)2@XZ @ stub -arch=win64 ?GetType(a)Boolean@Platform@@QEAAPE$AAVType(a)2@XZ -@ cdecl -arch=win32 ??0DisconnectedException(a)Platform@@Q$AAA(a)XZ(ptr) platform_DisconnectedException_ctor -@ cdecl -arch=win64 ??0DisconnectedException(a)Platform@@QE$AAA(a)XZ(ptr) platform_DisconnectedException_ctor +@ cdecl -arch=win32 ??0DisconnectedException(a)Platform@@Q$AAA(a)XZ(ptr) DisconnectedException_ctor +@ cdecl -arch=win64 ??0DisconnectedException(a)Platform@@QE$AAA(a)XZ(ptr) DisconnectedException_ctor @ stub -arch=win32 ?GetType(a)Guid@Platform@@QAAP$AAVType(a)2@XZ @ stub -arch=win64 ?GetType(a)Guid@Platform@@QEAAPE$AAVType(a)2@XZ @ stub -arch=win32 ?GetType(a)Object@Platform@@Q$AAAP$AAVType(a)2@XZ @@ -192,8 +192,8 @@ @ stub -arch=win64 ?IntersectsWith(a)Rect@Foundation(a)Windows@@QEAA_NV123@@Z @ stub -arch=win32 ?Invert(a)Matrix3D@Media3D(a)Media@Xaml(a)UI@Windows@@QAAXXZ @ stub -arch=win64 ?Invert(a)Matrix3D@Media3D(a)Media@Xaml(a)UI@Windows@@QEAAXXZ -@ cdecl -arch=win32 ??0Exception(a)Platform@@Q$AAA(a)H@Z(ptr long) platform_Exception_ctor -@ cdecl -arch=win64 ??0Exception(a)Platform@@QE$AAA(a)H@Z(ptr long) platform_Exception_ctor +@ cdecl -arch=win32 ??0Exception(a)Platform@@Q$AAA(a)H@Z(ptr long) Exception_ctor +@ cdecl -arch=win64 ??0Exception(a)Platform@@QE$AAA(a)H@Z(ptr long) Exception_ctor @ stub -arch=win32 ?ReCreateException(a)Exception@Platform@@SAP$AAV12(a)H@Z @ stub -arch=win64 ?ReCreateException(a)Exception@Platform@@SAPE$AAV12(a)H@Z @ stub -arch=win32 ?ReferenceEquals(a)Object@Platform@@SA_NP$AAV12(a)0@Z @@ -221,8 +221,8 @@ @ stub -arch=i386 ?TerminateModule(a)Details@Platform@@YG_NPAVModuleBase(a)1WRL@Microsoft@@@Z @ stub -arch=arm ?TerminateModule(a)Details@Platform@@YA_NPAVModuleBase(a)1WRL@Microsoft@@@Z @ stub -arch=win64 ?TerminateModule(a)Details@Platform@@YA_NPEAVModuleBase(a)1WRL@Microsoft@@@Z -@ cdecl -arch=win32 ??0Exception(a)Platform@@Q$AAA(a)HP$AAVString(a)1@@Z(ptr long ptr) platform_Exception_hstring_ctor -@ cdecl -arch=win64 ??0Exception(a)Platform@@QE$AAA(a)HPE$AAVString(a)1@@Z(ptr long ptr) platform_Exception_hstring_ctor +@ cdecl -arch=win32 ??0Exception(a)Platform@@Q$AAA(a)HP$AAVString(a)1@@Z(ptr long ptr) Exception_hstring_ctor +@ cdecl -arch=win64 ??0Exception(a)Platform@@QE$AAA(a)HPE$AAVString(a)1@@Z(ptr long ptr) Exception_hstring_ctor @ stub -arch=win32 ?ToInt32(a)IntPtr@Platform@@QAAHXZ @ stub -arch=win64 ?ToInt32(a)IntPtr@Platform@@QEAAHXZ @ stub -arch=win32 ?ToString(a)Attribute@Metadata(a)Platform@@Q$AAAP$AAVString(a)3@XZ @@ -245,8 +245,8 @@ @ stub -arch=win64 ?ToString(a)STAThreadAttribute@Platform@@QE$AAAPE$AAVString(a)2@XZ @ stub -arch=win32 ?<Dispose>@String(a)Platform@@U$AAAXXZ @ stub -arch=win64 ?<Dispose>@String(a)Platform@@UE$AAAXXZ -@ cdecl -arch=win32 ??0FailureException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_FailureException_hstring_ctor -@ cdecl -arch=win64 ??0FailureException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_FailureException_hstring_ctor +@ cdecl -arch=win32 ??0FailureException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) FailureException_hstring_ctor +@ cdecl -arch=win64 ??0FailureException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) FailureException_hstring_ctor @ cdecl -arch=win32 ?ToString(a)Type@Platform@@U$AAAP$AAVString(a)2@XZ(ptr) platform_type_ToString @ cdecl -arch=win64 ?ToString(a)Type@Platform@@UE$AAAPE$AAVString(a)2@XZ(ptr) platform_type_ToString @ stub -arch=win32 ?ToString(a)ValueType@Platform@@Q$AAAP$AAVString(a)2@XZ @@ -267,8 +267,8 @@ @ stub -arch=win64 ?ToString(a)int8@default@@QEAAPE$AAVString(a)Platform@@XZ @ stub -arch=win32 ?ToString(a)uint16@default@@QAAP$AAVString(a)Platform@@XZ @ stub -arch=win64 ?ToString(a)uint16@default@@QEAAPE$AAVString(a)Platform@@XZ -@ cdecl -arch=win32 ??0FailureException(a)Platform@@Q$AAA(a)XZ(ptr) platform_FailureException_ctor -@ cdecl -arch=win64 ??0FailureException(a)Platform@@QE$AAA(a)XZ(ptr) platform_FailureException_ctor +@ cdecl -arch=win32 ??0FailureException(a)Platform@@Q$AAA(a)XZ(ptr) FailureException_ctor +@ cdecl -arch=win64 ??0FailureException(a)Platform@@QE$AAA(a)XZ(ptr) FailureException_ctor @ stub -arch=win32 ?ToString(a)uint32@default@@QAAP$AAVString(a)Platform@@XZ @ stub -arch=win64 ?ToString(a)uint32@default@@QEAAPE$AAVString(a)Platform@@XZ @ stub -arch=win32 ?ToString(a)uint64@default@@QAAP$AAVString(a)Platform@@XZ @@ -355,10 +355,10 @@ @ cdecl -arch=win64 ?get(a)FullName@Type(a)Platform@@QE$AAAPE$AAVString(a)3@XZ(ptr) platform_type_get_FullName @ stub -arch=win32 ?get(a)HasInverse@Matrix3D(a)Media3D@Media(a)Xaml@UI(a)Windows@@QAA_NXZ @ stub -arch=win64 ?get(a)HasInverse@Matrix3D(a)Media3D@Media(a)Xaml@UI(a)Windows@@QEAA_NXZ -@ cdecl -arch=win32 ??0InvalidArgumentException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_InvalidArgumentException_hstring_ctor -@ cdecl -arch=win64 ??0InvalidArgumentException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_InvalidArgumentException_hstring_ctor -@ cdecl -arch=win32 ?get(a)Message@Exception(a)Platform@@Q$AAAP$AAVString(a)3@XZ(ptr) platform_exception_get_Message -@ cdecl -arch=win64 ?get(a)Message@Exception(a)Platform@@QE$AAAPE$AAVString(a)3@XZ(ptr) platform_exception_get_Message +@ cdecl -arch=win32 ??0InvalidArgumentException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) InvalidArgumentException_hstring_ctor +@ cdecl -arch=win64 ??0InvalidArgumentException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) InvalidArgumentException_hstring_ctor +@ cdecl -arch=win32 ?get(a)Message@Exception(a)Platform@@Q$AAAP$AAVString(a)3@XZ(ptr) Exception_get_Message +@ cdecl -arch=win64 ?get(a)Message@Exception(a)Platform@@QE$AAAPE$AAVString(a)3@XZ(ptr) Exception_get_Message @ stub ?get(a)ObjectCount@Heap(a)Details@Platform@@SAHXZ @ stub -arch=win32 ?get(a)Right@Rect(a)Foundation@Windows@@QAAMXZ @ stub -arch=win64 ?get(a)Right@Rect(a)Foundation@Windows@@QEAAMXZ @@ -366,46 +366,46 @@ @ stub ?set(a)BreakOnAllocationId@Heap(a)Details@Platform@@SAXH(a)Z @ stub ?set(a)BreakOnFreeId@Heap(a)Details@Platform@@SAXH(a)Z @ stub ?set(a)TrackingLevel@Heap(a)Details@Platform@@SAXW4HeapAllocationTrackingLevel(a)34@@Z -@ cdecl -arch=win32 ??0InvalidArgumentException(a)Platform@@Q$AAA(a)XZ(ptr) platform_InvalidArgumentException_ctor -@ cdecl -arch=win64 ??0InvalidArgumentException(a)Platform@@QE$AAA(a)XZ(ptr) platform_InvalidArgumentException_ctor -@ cdecl -arch=win32 ??0InvalidCastException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_InvalidCastException_hstring_ctor -@ cdecl -arch=win64 ??0InvalidCastException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_InvalidCastException_hstring_ctor -@ cdecl -arch=win32 ??0InvalidCastException(a)Platform@@Q$AAA(a)XZ(ptr) platform_InvalidCastException_ctor -@ cdecl -arch=win64 ??0InvalidCastException(a)Platform@@QE$AAA(a)XZ(ptr) platform_InvalidCastException_ctor +@ cdecl -arch=win32 ??0InvalidArgumentException(a)Platform@@Q$AAA(a)XZ(ptr) InvalidArgumentException_ctor +@ cdecl -arch=win64 ??0InvalidArgumentException(a)Platform@@QE$AAA(a)XZ(ptr) InvalidArgumentException_ctor +@ cdecl -arch=win32 ??0InvalidCastException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) InvalidCastException_hstring_ctor +@ cdecl -arch=win64 ??0InvalidCastException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) InvalidCastException_hstring_ctor +@ cdecl -arch=win32 ??0InvalidCastException(a)Platform@@Q$AAA(a)XZ(ptr) InvalidCastException_ctor +@ cdecl -arch=win64 ??0InvalidCastException(a)Platform@@QE$AAA(a)XZ(ptr) InvalidCastException_ctor @ stub -arch=win32 ??0MTAThreadAttribute(a)Platform@@Q$AAA(a)XZ @ stub -arch=win64 ??0MTAThreadAttribute(a)Platform@@QE$AAA(a)XZ @ stub -arch=win32 ?<Dispose>@Type(a)Platform@@U$AAAXXZ @ stub -arch=win64 ?<Dispose>@Type(a)Platform@@UE$AAAXXZ -@ cdecl -arch=win32 ??0NotImplementedException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_NotImplementedException_hstring_ctor -@ cdecl -arch=win64 ??0NotImplementedException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_NotImplementedException_hstring_ctor -@ cdecl -arch=win32 ??0NotImplementedException(a)Platform@@Q$AAA(a)XZ(ptr) platform_NotImplementedException_ctor -@ cdecl -arch=win64 ??0NotImplementedException(a)Platform@@QE$AAA(a)XZ(ptr) platform_NotImplementedException_ctor -@ cdecl -arch=win32 ??0NullReferenceException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_NullReferenceException_hstring_ctor -@ cdecl -arch=win64 ??0NullReferenceException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_NullReferenceException_hstring_ctor -@ cdecl -arch=win32 ??0NullReferenceException(a)Platform@@Q$AAA(a)XZ(ptr) platform_NullReferenceException_ctor -@ cdecl -arch=win64 ??0NullReferenceException(a)Platform@@QE$AAA(a)XZ(ptr) platform_NullReferenceException_ctor +@ cdecl -arch=win32 ??0NotImplementedException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) NotImplementedException_hstring_ctor +@ cdecl -arch=win64 ??0NotImplementedException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) NotImplementedException_hstring_ctor +@ cdecl -arch=win32 ??0NotImplementedException(a)Platform@@Q$AAA(a)XZ(ptr) NotImplementedException_ctor +@ cdecl -arch=win64 ??0NotImplementedException(a)Platform@@QE$AAA(a)XZ(ptr) NotImplementedException_ctor +@ cdecl -arch=win32 ??0NullReferenceException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) NullReferenceException_hstring_ctor +@ cdecl -arch=win64 ??0NullReferenceException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) NullReferenceException_hstring_ctor +@ cdecl -arch=win32 ??0NullReferenceException(a)Platform@@Q$AAA(a)XZ(ptr) NullReferenceException_ctor +@ cdecl -arch=win64 ??0NullReferenceException(a)Platform@@QE$AAA(a)XZ(ptr) NullReferenceException_ctor @ stub -arch=win32 ??0Object(a)Platform@@Q$AAA(a)XZ @ stub -arch=win64 ??0Object(a)Platform@@QE$AAA(a)XZ -@ cdecl -arch=win32 ??0ObjectDisposedException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_ObjectDisposedException_hstring_ctor -@ cdecl -arch=win64 ??0ObjectDisposedException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_ObjectDisposedException_hstring_ctor -@ cdecl -arch=win32 ??0ObjectDisposedException(a)Platform@@Q$AAA(a)XZ(ptr) platform_ObjectDisposedException_ctor -@ cdecl -arch=win64 ??0ObjectDisposedException(a)Platform@@QE$AAA(a)XZ(ptr) platform_ObjectDisposedException_ctor +@ cdecl -arch=win32 ??0ObjectDisposedException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) ObjectDisposedException_hstring_ctor +@ cdecl -arch=win64 ??0ObjectDisposedException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) ObjectDisposedException_hstring_ctor +@ cdecl -arch=win32 ??0ObjectDisposedException(a)Platform@@Q$AAA(a)XZ(ptr) ObjectDisposedException_ctor +@ cdecl -arch=win64 ??0ObjectDisposedException(a)Platform@@QE$AAA(a)XZ(ptr) ObjectDisposedException_ctor @ stub -arch=win32 ??0OnePhaseConstructedAttribute(a)CompilerServices@Runtime(a)Platform@@Q$AAA(a)XZ @ stub -arch=win64 ??0OnePhaseConstructedAttribute(a)CompilerServices@Runtime(a)Platform@@QE$AAA(a)XZ -@ cdecl -arch=win32 ??0OperationCanceledException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_OperationCanceledException_hstring_ctor -@ cdecl -arch=win64 ??0OperationCanceledException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_OperationCanceledException_hstring_ctor -@ cdecl -arch=win32 ??0OperationCanceledException(a)Platform@@Q$AAA(a)XZ(ptr) platform_OperationCanceledException_ctor -@ cdecl -arch=win64 ??0OperationCanceledException(a)Platform@@QE$AAA(a)XZ(ptr) platform_OperationCanceledException_ctor -@ cdecl -arch=win32 ??0AccessDeniedException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_AccessDeniedException_hstring_ctor -@ cdecl -arch=win64 ??0AccessDeniedException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_AccessDeniedException_hstring_ctor -@ cdecl -arch=win32 ??0OutOfBoundsException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_OutOfBoundsException_hstring_ctor -@ cdecl -arch=win64 ??0OutOfBoundsException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_OutOfBoundsException_hstring_ctor -@ cdecl -arch=win32 ??0OutOfBoundsException(a)Platform@@Q$AAA(a)XZ(ptr) platform_OutOfBoundsException_ctor -@ cdecl -arch=win64 ??0OutOfBoundsException(a)Platform@@QE$AAA(a)XZ(ptr) platform_OutOfBoundsException_ctor -@ cdecl -arch=win32 ??0OutOfMemoryException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_OutOfMemoryException_hstring_ctor -@ cdecl -arch=win64 ??0OutOfMemoryException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_OutOfMemoryException_hstring_ctor -@ cdecl -arch=win32 ??0OutOfMemoryException(a)Platform@@Q$AAA(a)XZ(ptr) platform_OutOfMemoryException_ctor -@ cdecl -arch=win64 ??0OutOfMemoryException(a)Platform@@QE$AAA(a)XZ(ptr) platform_OutOfMemoryException_ctor +@ cdecl -arch=win32 ??0OperationCanceledException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) OperationCanceledException_hstring_ctor +@ cdecl -arch=win64 ??0OperationCanceledException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) OperationCanceledException_hstring_ctor +@ cdecl -arch=win32 ??0OperationCanceledException(a)Platform@@Q$AAA(a)XZ(ptr) OperationCanceledException_ctor +@ cdecl -arch=win64 ??0OperationCanceledException(a)Platform@@QE$AAA(a)XZ(ptr) OperationCanceledException_ctor +@ cdecl -arch=win32 ??0AccessDeniedException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) AccessDeniedException_hstring_ctor +@ cdecl -arch=win64 ??0AccessDeniedException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) AccessDeniedException_hstring_ctor +@ cdecl -arch=win32 ??0OutOfBoundsException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) OutOfBoundsException_hstring_ctor +@ cdecl -arch=win64 ??0OutOfBoundsException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) OutOfBoundsException_hstring_ctor +@ cdecl -arch=win32 ??0OutOfBoundsException(a)Platform@@Q$AAA(a)XZ(ptr) OutOfBoundsException_ctor +@ cdecl -arch=win64 ??0OutOfBoundsException(a)Platform@@QE$AAA(a)XZ(ptr) OutOfBoundsException_ctor +@ cdecl -arch=win32 ??0OutOfMemoryException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) OutOfMemoryException_hstring_ctor +@ cdecl -arch=win64 ??0OutOfMemoryException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) OutOfMemoryException_hstring_ctor +@ cdecl -arch=win32 ??0OutOfMemoryException(a)Platform@@Q$AAA(a)XZ(ptr) OutOfMemoryException_ctor +@ cdecl -arch=win64 ??0OutOfMemoryException(a)Platform@@QE$AAA(a)XZ(ptr) OutOfMemoryException_ctor @ stub -arch=win32 ??0Rect(a)Foundation@Windows@@QAA(a)VPoint@12(a)0@Z @ stub -arch=win64 ??0Rect(a)Foundation@Windows@@QEAA(a)VPoint@12(a)0@Z @ stub -arch=win32 ??0Rect(a)Foundation@Windows@@QAA(a)VPoint@12(a)VSize@12@@Z @@ -418,8 +418,8 @@ @ stub -arch=win64 ??0SizeT(a)Platform@@QEAA(a)H@Z @ stub -arch=win32 ??0SizeT(a)Platform@@QAA(a)PAX@Z @ stub -arch=win64 ??0SizeT(a)Platform@@QEAA(a)PEAX@Z -@ cdecl -arch=win32 ??0AccessDeniedException(a)Platform@@Q$AAA(a)XZ(ptr) platform_AccessDeniedException_ctor -@ cdecl -arch=win64 ??0AccessDeniedException(a)Platform@@QE$AAA(a)XZ(ptr) platform_AccessDeniedException_ctor +@ cdecl -arch=win32 ??0AccessDeniedException(a)Platform@@Q$AAA(a)XZ(ptr) AccessDeniedException_ctor +@ cdecl -arch=win64 ??0AccessDeniedException(a)Platform@@QE$AAA(a)XZ(ptr) AccessDeniedException_ctor @ stub -arch=win32 ??0Type(a)Platform@@Q$AAA(a)P$AAVObject(a)1@@Z @ stub -arch=win64 ??0Type(a)Platform@@QE$AAA(a)PE$AAVObject(a)1@@Z @ stub -arch=win32 ??0Type(a)Platform@@Q$AAA(a)VIntPtr@1@@Z @@ -428,10 +428,10 @@ @ stub -arch=win64 ??0Type(a)Platform@@QE$AAA(a)VTypeName@Interop(a)Xaml@UI(a)Windows@@@Z @ stub -arch=win32 ??0ValueType(a)Platform@@Q$AAA(a)XZ @ stub -arch=win64 ??0ValueType(a)Platform@@QE$AAA(a)XZ -@ cdecl -arch=win32 ??0WrongThreadException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) platform_WrongThreadException_hstring_ctor -@ cdecl -arch=win64 ??0WrongThreadException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) platform_WrongThreadException_hstring_ctor -@ cdecl -arch=win32 ??0WrongThreadException(a)Platform@@Q$AAA(a)XZ(ptr) platform_WrongThreadException_ctor -@ cdecl -arch=win64 ??0WrongThreadException(a)Platform@@QE$AAA(a)XZ(ptr) platform_WrongThreadException_ctor +@ cdecl -arch=win32 ??0WrongThreadException(a)Platform@@Q$AAA(a)P$AAVString(a)1@@Z(ptr ptr) WrongThreadException_hstring_ctor +@ cdecl -arch=win64 ??0WrongThreadException(a)Platform@@QE$AAA(a)PE$AAVString(a)1@@Z(ptr ptr) WrongThreadException_hstring_ctor +@ cdecl -arch=win32 ??0WrongThreadException(a)Platform@@Q$AAA(a)XZ(ptr) WrongThreadException_ctor +@ cdecl -arch=win64 ??0WrongThreadException(a)Platform@@QE$AAA(a)XZ(ptr) WrongThreadException_ctor @ stub -arch=win32 ??0char16(a)default@@QAA(a)_W@Z @ stub -arch=win64 ??0char16(a)default@@QEAA(a)_W@Z @ stub -arch=win32 ??0float32(a)default@@QAA(a)M@Z @@ -476,8 +476,8 @@ @ stub ??PDuration(a)Xaml@UI(a)Windows@@SA_NV0123(a)0@Z @ stub -arch=win32 ?AlignedAllocate(a)Heap@Details(a)Platform@@SAPAXII(a)Z @ stub -arch=win64 ?AlignedAllocate(a)Heap@Details(a)Platform@@SAPEAX_K00(a)Z -@ cdecl -arch=win32 ??0COMException(a)Platform@@Q$AAA(a)H@Z(ptr long) platform_COMException_ctor -@ cdecl -arch=win64 ??0COMException(a)Platform@@QE$AAA(a)H@Z(ptr long) platform_COMException_ctor +@ cdecl -arch=win32 ??0COMException(a)Platform@@Q$AAA(a)H@Z(ptr long) COMException_ctor +@ cdecl -arch=win64 ??0COMException(a)Platform@@QE$AAA(a)H@Z(ptr long) COMException_ctor @ stub -arch=win32 ?AlignedAllocate(a)Heap@Details(a)Platform@@SAPAXIII(a)Z @ stub -arch=win64 ?AlignedAllocate(a)Heap@Details(a)Platform@@SAPEAX_K0(a)Z @ stub -arch=win32 ?AlignedAllocateException(a)Heap@Details(a)Platform@@SAPAXII(a)Z @@ -497,8 +497,8 @@ @ cdecl -arch=win32 ?AllocateException(a)Heap@Details(a)Platform@@SAPAXII(a)Z(long long) AllocateExceptionWithWeakRef @ cdecl -arch=win64 ?AllocateException(a)Heap@Details(a)Platform@@SAPEAX_K(a)Z(long) AllocateException @ stub ?Compare(a)Duration@Xaml(a)UI@Windows@@SAHV1234(a)0@Z -@ cdecl -arch=win32 ??0COMException(a)Platform@@Q$AAA(a)HP$AAVString(a)1@@Z(ptr long ptr) platform_COMException_hstring_ctor -@ cdecl -arch=win64 ??0COMException(a)Platform@@QE$AAA(a)HPE$AAVString(a)1@@Z(ptr long ptr) platform_COMException_hstring_ctor +@ cdecl -arch=win32 ??0COMException(a)Platform@@Q$AAA(a)HP$AAVString(a)1@@Z(ptr long ptr) COMException_hstring_ctor +@ cdecl -arch=win64 ??0COMException(a)Platform@@QE$AAA(a)HPE$AAVString(a)1@@Z(ptr long ptr) COMException_hstring_ctor @ stub -arch=win32 ?Contains(a)Rect@Foundation(a)Windows@@QAA_NVPoint(a)23@@Z @ stub -arch=win64 ?Contains(a)Rect@Foundation(a)Windows@@QEAA_NVPoint(a)23@@Z @ cdecl -arch=win32 ?CreateException(a)Exception@Platform@@SAP$AAV12(a)H@Z(long) CreateException -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9209
From: Vibhav Pant <vibhavp(a)gmail.com> --- dlls/vccorlib140/Makefile.in | 2 +- dlls/vccorlib140/cxx.h | 64 +++++++--- dlls/vccorlib140/except.c | 238 ++++++++++++++++++++++++++++++++++- dlls/vccorlib140/private.h | 29 +++++ dlls/vccorlib140/vccorlib.c | 27 +--- 5 files changed, 313 insertions(+), 47 deletions(-) diff --git a/dlls/vccorlib140/Makefile.in b/dlls/vccorlib140/Makefile.in index 988d761efda..bad509dbdf5 100644 --- a/dlls/vccorlib140/Makefile.in +++ b/dlls/vccorlib140/Makefile.in @@ -1,5 +1,5 @@ MODULE = vccorlib140.dll -IMPORTS = combase +IMPORTS = combase oleaut32 SOURCES = \ except.c \ diff --git a/dlls/vccorlib140/cxx.h b/dlls/vccorlib140/cxx.h index b803d35a283..64776822d9e 100644 --- a/dlls/vccorlib140/cxx.h +++ b/dlls/vccorlib140/cxx.h @@ -21,6 +21,15 @@ #include "rtlsupportapi.h" #include "wine/asm.h" +#define CLASS_IS_SIMPLE_TYPE 1 +#define CLASS_HAS_VIRTUAL_BASE_CLASS 4 +#define CLASS_IS_WINRT 8 + +#define TYPE_FLAG_CONST 1 +#define TYPE_FLAG_VOLATILE 2 +#define TYPE_FLAG_REFERENCE 8 +#define TYPE_FLAG_WINRT 16 + #ifdef __i386__ #undef CXX_USE_RVA #else @@ -139,63 +148,70 @@ static void init_ ## name ## _rtti(char *base) \ #ifndef CXX_USE_RVA -#define DEFINE_CXX_TYPE(type, dtor, ...) \ +#define CXX_FUNC(func) THISCALL(func) +#define CXX_NULL NULL + +#define DEFINE_CXX_TYPE2(type, flags, ti_flags, dtor, copyctor, ...) \ static const cxx_type_info type ## _cxx_type_info[1] = \ - { { 0, &type ##_type_info, { 0, -1, 0 }, sizeof(type), THISCALL(type ##_copy_ctor) } }; \ + { { ti_flags, &type ##_type_info, { 0, -1, 0 }, sizeof(type), copyctor } }; \ \ static const cxx_type_info_table type ## _cxx_type_table = \ - { ARRAY_SIZE(((const void *[]){ NULL, __VA_ARGS__ })), { type ## _cxx_type_info, __VA_ARGS__ } }; \ + { ARRAY_SIZE(((const void *[]){ __VA_ARGS__ })), { __VA_ARGS__ } }; \ \ static const cxx_exception_type type ## _exception_type = \ - { 0, THISCALL(dtor), NULL, & type ## _cxx_type_table }; + { flags, dtor, NULL, & type ## _cxx_type_table }; #define INIT_CXX_TYPE(name,base) (void)name ## _exception_type #elif defined __WINE_PE_BUILD -#define DEFINE_CXX_TYPE2(type, dtor, ...) \ +#define CXX_FUNC(func) ".rva " #func +#define CXX_NULL ".long 0" + +#define DEFINE_CXX_TYPE2(type, flags, ti_flags, dtor, copyctor, ...) \ extern const cxx_type_info type ## _cxx_type_info[1]; \ extern const cxx_exception_type type ## _exception_type; \ void __asm_dummy_ ## type ## _exception_type(void) \ { \ asm( ".balign 4\n\t" \ __ASM_GLOBL(#type "_cxx_type_info") "\n\t" \ - ".long 0\n\t" \ + ".long %c0\n\t" \ ".rva " #type "_type_info\n\t" \ - ".long 0, -1, 0, %c0\n\t" \ - ".rva " #type "_copy_ctor\n" \ + ".long 0, -1, 0, %c1\n\t" \ + copyctor "\n\t" \ #type "_type_table:\n\t" \ - ".long %c1\n\t" \ + ".long %c2\n\t" \ ".rva " #__VA_ARGS__ "\n\t" \ __ASM_GLOBL(#type "_exception_type") "\n\t" \ - ".long 0\n\t" \ - ".rva " #dtor "\n\t" \ + ".long %c3\n\t" \ + dtor "\n\t" \ ".long 0\n\t" \ ".rva " #type "_type_table\n\t" \ - :: "i"(sizeof(type)), "i"(ARRAY_SIZE(((const void *[]){ &__VA_ARGS__ }))) ); \ + :: "i"(ti_flags), "i"(sizeof(type)), "i"(ARRAY_SIZE(((const void *[]){ &__VA_ARGS__ }))), "i"(flags) ); \ } -#define DEFINE_CXX_TYPE(type, dtor, ...) \ - DEFINE_CXX_TYPE2(type, dtor, type ## _cxx_type_info, ##__VA_ARGS__) #define INIT_CXX_TYPE(name,base) /* nothing to do */ #else /* CXX_USE_RVA */ -#define DEFINE_CXX_TYPE(type, dtor, ...) \ +#define CXX_FUNC(func) func +#define CXX_NULL NULL + +#define DEFINE_CXX_TYPE2(type, flags, ti_flags, dtor, copyctor, ...) \ static cxx_type_info type ## _cxx_type_info[1] = \ - { { 0, 0xdeadbeef, { 0, -1, 0 }, sizeof(type), 0xdeadbeef } }; \ + { { ti_flags, 0xdeadbeef, { 0, -1, 0 }, sizeof(type), 0xdeadbeef } }; \ \ -static const void * const type ## _cxx_type_classes[] = { type ## _cxx_type_info, __VA_ARGS__ }; \ +static const void * const type ## _cxx_type_classes[] = { __VA_ARGS__ }; \ static cxx_type_info_table type ## _cxx_type_table = { ARRAY_SIZE(type ## _cxx_type_classes) }; \ -static cxx_exception_type type ##_exception_type; \ +static cxx_exception_type type ##_exception_type = {flags}; \ \ static void init_ ## type ## _cxx(char *base) \ { \ type ## _cxx_type_info[0].type_info = (char *)&type ## _type_info - base; \ - type ## _cxx_type_info[0].copy_ctor = (char *)type ## _copy_ctor - base; \ + type ## _cxx_type_info[0].copy_ctor = (copyctor) ? (char *)(copyctor) - base : 0; \ for (unsigned int i = 0; i < ARRAY_SIZE(type ## _cxx_type_classes); i++) \ type ## _cxx_type_table.info[i] = (char *)type ## _cxx_type_classes[i] - base; \ - type ## _exception_type.destructor = (char *)dtor - base; \ + type ## _exception_type.destructor = (dtor) ? (char *)(dtor) - base : 0; \ type ## _exception_type.type_info_table = (char *)&type ## _cxx_type_table - base; \ } @@ -203,6 +219,14 @@ static void init_ ## type ## _cxx(char *base) \ #endif /* CXX_USE_RVA */ +#define DEFINE_CXX_TYPE(type, dtor, ...) \ + DEFINE_CXX_TYPE2(type, 0, 0, CXX_FUNC(dtor), CXX_FUNC(type ##_copy_ctor), \ + type ## _cxx_type_info, ##__VA_ARGS__) + +#define DEFINE_WINRT_CXX_TYPE(type, ...) \ + DEFINE_CXX_TYPE2(type, TYPE_FLAG_WINRT, CLASS_IS_SIMPLE_TYPE | CLASS_IS_WINRT, \ + CXX_NULL, CXX_NULL, type ## _cxx_type_info, ##__VA_ARGS__) + #ifdef __ASM_USE_THISCALL_WRAPPER #define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (WINAPI*)type)&vtbl_wrapper_##off)args diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index 0165fe8878f..b5c4254b6fc 100644 --- a/dlls/vccorlib140/except.c +++ b/dlls/vccorlib140/except.c @@ -16,12 +16,67 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS + +#include <stdint.h> + #include "roapi.h" #include "winstring.h" +#include "roerrorapi.h" +#define WIDL_using_Windows_Foundation +#include "windows.foundation.h" #include "wine/debug.h" +#include "cxx.h" +#include "private.h" + WINE_DEFAULT_DEBUG_CHANNEL(vccorlib); +#ifdef _WIN64 +#define EXCEPTION_REF_NAME(name) ".PE$AAV" #name "Exception(a)Platform@@" +#else +#define EXCEPTION_REF_NAME(name) ".P$AAV" #name "Exception(a)Platform@@" +#endif + +/* Data members of the "Exception" C++/CX class. + * A back-pointer to this struct is stored just before the IInspectable vtable of an Exception object. + * TODO: The message fields are likely obtained from IRestrictedErrorInfo::GetErrorDetails, so we + * should use that once it has been implemented. */ +struct exception_inner +{ + /* This only gets set when the exception is thrown. */ + BSTR description; + /* Likewise, but can also be set by CreateExceptionWithMessage. */ + BSTR restricted_desc; + void *unknown1; + void *unknown2; + HRESULT hr; + /* Only gets set when the exception is thrown. */ + IRestrictedErrorInfo *error_info; + const cxx_exception_type *exception_type; + /* Set to 32 and 64 on 32 and 64-bit platforms respectively, not sure what the purpose is. */ + UINT32 unknown3; + /* Called before the exception is thrown by _CxxThrowException. + * This sets the description and error_info fields, and probably originates a WinRT error + * with RoOriginateError/RoOriginateLanguageException. */ + void (*WINAPI set_exception_info)(struct exception_inner **); +}; + +struct Exception +{ + IInspectable IInspectable_iface; + const void *IPrintable_iface; + const void *IEquatable_iface; + IClosable IClosable_iface; + struct exception_inner inner; + /* Exceptions use the weakref control block for reference counting, even though they don't implement + * IWeakReferenceSource. */ + struct control_block *control_block; + /* This is lazily initialized, i.e, only when QueryInterface(IID_IMarshal) gets called. The default value is + * UINTPTR_MAX/-1 */ + IUnknown *marshal; +}; + void *__cdecl CreateExceptionWithMessage(HRESULT hr, HSTRING msg) { FIXME("(%#lx, %s): stub!\n", hr, debugstr_hstring(msg)); @@ -74,9 +129,180 @@ void WINAPI __abi_WinRTraiseCOMException(HRESULT hr) WINRT_EXCEPTIONS #undef WINRT_EXCEPTION -void *__cdecl Exception_ctor(void *this, HRESULT hr) +static inline struct Exception *impl_Exception_from_IInspectable(IInspectable *iface) { - FIXME("(%p, %#lx): stub!\n", this, hr); + return CONTAINING_RECORD(iface, struct Exception, IInspectable_iface); +} + +static HRESULT WINAPI Exception_QueryInterface(IInspectable *iface, const GUID *iid, void **out) +{ + struct Exception *impl = impl_Exception_from_IInspectable(iface); + + TRACE("(%p, %s, %p)\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IInspectable) || + IsEqualGUID(iid, &IID_IAgileObject)) + { + IInspectable_AddRef((*out = &impl->IInspectable_iface)); + return S_OK; + } + if (IsEqualGUID(iid, &IID_IClosable)) + { + IClosable_AddRef((*out = &impl->IClosable_iface)); + return S_OK; + } + if (IsEqualGUID(iid, &IID_IMarshal)) + { + IUnknown *marshal, *old; + HRESULT hr; + + if ((ULONG_PTR)impl->marshal != UINTPTR_MAX) + return IUnknown_QueryInterface(impl->marshal, iid, out); + /* Try initializing impl->marshal. */ + if (FAILED(hr = CoCreateFreeThreadedMarshaler((IUnknown *)&impl->IInspectable_iface, &marshal))) + return hr; + old = InterlockedCompareExchangePointer((void *)&impl->marshal, marshal, (void *)UINTPTR_MAX); + if ((ULONG_PTR)old != UINTPTR_MAX) /* Someone else has already set impl->marshal, use it. */ + IUnknown_Release(marshal); + return IUnknown_QueryInterface(impl->marshal, iid, out); + } + + ERR("%s not implemented, returning E_NOTINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI Exception_AddRef(IInspectable *iface) +{ + struct Exception *impl = impl_Exception_from_IInspectable(iface); + TRACE("(%p)\n", iface); + return InterlockedIncrement(&impl->control_block->ref_strong); +} + +static ULONG WINAPI Exception_Release(IInspectable *iface) +{ + struct Exception *impl = impl_Exception_from_IInspectable(iface); + ULONG ref = InterlockedDecrement(&impl->control_block->ref_strong); + + TRACE("(%p)\n", iface); + + if (!ref) + { + SysFreeString(impl->inner.description); + SysFreeString(impl->inner.restricted_desc); + if ((ULONG_PTR)impl->marshal != UINTPTR_MAX) + IUnknown_Release((IUnknown *)impl->marshal); + /* Because Exception objects are never allocated inline, we don't need to use ReleaseTarget. */ + IWeakReference_Release(&impl->control_block->IWeakReference_iface); + FreeException(impl); + } + return ref; +} + +static HRESULT WINAPI Exception_GetRuntimeClassName(IInspectable *iface, HSTRING *class_name) +{ + struct Exception *impl = impl_Exception_from_IInspectable(iface); + const WCHAR *buf; + + TRACE("(%p, %p)\n", iface, class_name); + +#define WINRT_EXCEPTION(name, hr) case (hr): buf = L"Platform." #name "Exception"; break; + switch (impl->inner.hr) + { + WINRT_EXCEPTIONS +#undef WINRT_EXCEPTION + default: + buf = L"Platform.COMException"; + break; + } + return WindowsCreateString(buf, wcslen(buf), class_name); +} + +static HRESULT WINAPI Exception_GetIids(IInspectable *iface, ULONG *count, IID **iids) +{ + TRACE("(%p, %p, %p)\n", iface, count, iids); + + *count = 0; + *iids = NULL; + return S_OK; +} + +static HRESULT WINAPI Exception_GetTrustLevel(IInspectable *iface, TrustLevel *level) +{ + FIXME("(%p, %p)\n", iface, level); + return E_NOTIMPL; +} + +DEFINE_RTTI_DATA(Exception_ref, 0, EXCEPTION_REF_NAME()); +typedef struct Exception *Exception_ref; +DEFINE_WINRT_CXX_TYPE(Exception_ref); + +DEFINE_RTTI_DATA(Exception, 0, "?.AVException(a)Platform@@"); +COM_VTABLE_RTTI_START(IInspectable, Exception) +COM_VTABLE_ENTRY(Exception_QueryInterface) +COM_VTABLE_ENTRY(Exception_AddRef) +COM_VTABLE_ENTRY(Exception_Release) +COM_VTABLE_ENTRY(Exception_GetIids) +COM_VTABLE_ENTRY(Exception_GetRuntimeClassName) +COM_VTABLE_ENTRY(Exception_GetTrustLevel) +COM_VTABLE_RTTI_END; + +DEFINE_IINSPECTABLE_(Exception_Closable, IClosable, struct Exception, + impl_Exception_from_IClosable, IClosable_iface, &impl->IInspectable_iface); + +static HRESULT WINAPI Exception_Closable_Close(IClosable *iface) +{ + FIXME("(%p)\n", iface); + return E_NOTIMPL; +} + +DEFINE_RTTI_DATA(Exception_Closable, offsetof(struct Exception, IClosable_iface), + "?.AVException(a)Platform@@") +COM_VTABLE_RTTI_START(IClosable, Exception_Closable) +COM_VTABLE_ENTRY(Exception_Closable_QueryInterface) +COM_VTABLE_ENTRY(Exception_Closable_AddRef) +COM_VTABLE_ENTRY(Exception_Closable_Release) +COM_VTABLE_ENTRY(Exception_Closable_GetIids) +COM_VTABLE_ENTRY(Exception_Closable_GetRuntimeClassName) +COM_VTABLE_ENTRY(Exception_Closable_GetTrustLevel) +COM_VTABLE_ENTRY(Exception_Closable_Close) +COM_VTABLE_RTTI_END; + +static void WINAPI set_exception_info(struct exception_inner **inner) +{ + struct exception_inner *info = *inner; + WCHAR buf[256]; + + FIXME("(%p): semi-stub!\n", inner); + + if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, info->hr, 0, buf, ARRAY_SIZE(buf), NULL)) + info->description = SysAllocString(buf); + if (!info->restricted_desc) + info->restricted_desc = SysAllocString(info->description); + info->error_info = NULL; +} + +struct Exception *__cdecl Exception_ctor(struct Exception *this, HRESULT hr) +{ + struct exception_alloc *base = CONTAINING_RECORD(this, struct exception_alloc, data); + + TRACE("(%p, %#lx)\n", this, hr); + + this->IInspectable_iface.lpVtbl = &Exception_vtable.vtable; + this->IClosable_iface.lpVtbl = &Exception_Closable_vtable.vtable; + this->IEquatable_iface = this->IPrintable_iface = NULL; + + memset(&this->inner, 0, sizeof(this->inner)); + base->exception_inner = &this->inner; + this->inner.exception_type = &Exception_ref_exception_type; + this->inner.hr = hr; + this->inner.unknown3 = sizeof(void *) == 8 ? 64 : 32; + this->inner.set_exception_info = set_exception_info; + + this->marshal = (IUnknown *)UINTPTR_MAX; + + if (SUCCEEDED(hr)) + __abi_WinRTraiseInvalidArgumentException(); return this; } @@ -103,3 +329,11 @@ HSTRING __cdecl Exception_get_Message(void *excp) FIXME("(%p): stub!\n", excp); return NULL; } + +void init_exception(void *base) +{ + INIT_RTTI(Exception_ref, base); + INIT_CXX_TYPE(Exception_ref, base); + INIT_RTTI(Exception, base); + INIT_RTTI(Exception_Closable, base); +} diff --git a/dlls/vccorlib140/private.h b/dlls/vccorlib140/private.h index 1b30dbcb867..384cb6bfd40 100644 --- a/dlls/vccorlib140/private.h +++ b/dlls/vccorlib140/private.h @@ -16,6 +16,35 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdbool.h> + +#include "weakreference.h" + +struct exception_alloc +{ + void *unknown; + void *exception_inner; + char data[0]; +}; + +struct control_block +{ + IWeakReference IWeakReference_iface; + LONG ref_weak; + LONG ref_strong; + IUnknown *object; + bool is_inline; + bool unknown; + bool is_exception; +#ifdef _WIN32 + char _padding[5]; +#endif +}; + +void __cdecl FreeException(void *); + +void init_exception(void *); + #define COM_VTABLE_RTTI_START(iface, type) \ static const struct \ { \ diff --git a/dlls/vccorlib140/vccorlib.c b/dlls/vccorlib140/vccorlib.c index 869d40aea10..49b730a2914 100644 --- a/dlls/vccorlib140/vccorlib.c +++ b/dlls/vccorlib140/vccorlib.c @@ -19,11 +19,8 @@ #define COBJMACROS -#include <stdbool.h> - #include "initguid.h" #include "roapi.h" -#include "weakreference.h" #include "winstring.h" #define WIDL_using_Windows_Foundation #include "windows.foundation.h" @@ -101,13 +98,6 @@ void *__cdecl Allocate(size_t size) return addr; } -struct exception_alloc -{ - void *unknown; - void *exception_inner; - char data[0]; -}; - void *__cdecl AllocateException(size_t size) { struct exception_alloc *base; @@ -134,20 +124,6 @@ void __cdecl FreeException(void *addr) Free(base); } -struct control_block -{ - IWeakReference IWeakReference_iface; - LONG ref_weak; - LONG ref_strong; - IUnknown *object; - bool is_inline; - bool unknown; - bool is_exception; -#ifdef _WIN32 - char _padding[5]; -#endif -}; - static inline struct control_block *impl_from_IWeakReference(IWeakReference *iface) { return CONTAINING_RECORD(iface, struct control_block, IWeakReference_iface); @@ -614,6 +590,9 @@ void *WINAPI CreateValue(int typecode, const void *val) BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { if (reason == DLL_PROCESS_ATTACH) + { + init_exception(inst); init_platform_type(inst); + } return TRUE; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9209
From: Piotr Caban <piotr(a)codeweavers.com> --- dlls/msvcp90/cxx.h | 64 +++++++++++++++++++++++++++------------- dlls/msvcp90/exception.c | 8 ++--- dlls/msvcrt/cppexcept.h | 9 ------ dlls/msvcrt/cxx.h | 64 +++++++++++++++++++++++++++------------- 4 files changed, 90 insertions(+), 55 deletions(-) diff --git a/dlls/msvcp90/cxx.h b/dlls/msvcp90/cxx.h index b803d35a283..64776822d9e 100644 --- a/dlls/msvcp90/cxx.h +++ b/dlls/msvcp90/cxx.h @@ -21,6 +21,15 @@ #include "rtlsupportapi.h" #include "wine/asm.h" +#define CLASS_IS_SIMPLE_TYPE 1 +#define CLASS_HAS_VIRTUAL_BASE_CLASS 4 +#define CLASS_IS_WINRT 8 + +#define TYPE_FLAG_CONST 1 +#define TYPE_FLAG_VOLATILE 2 +#define TYPE_FLAG_REFERENCE 8 +#define TYPE_FLAG_WINRT 16 + #ifdef __i386__ #undef CXX_USE_RVA #else @@ -139,63 +148,70 @@ static void init_ ## name ## _rtti(char *base) \ #ifndef CXX_USE_RVA -#define DEFINE_CXX_TYPE(type, dtor, ...) \ +#define CXX_FUNC(func) THISCALL(func) +#define CXX_NULL NULL + +#define DEFINE_CXX_TYPE2(type, flags, ti_flags, dtor, copyctor, ...) \ static const cxx_type_info type ## _cxx_type_info[1] = \ - { { 0, &type ##_type_info, { 0, -1, 0 }, sizeof(type), THISCALL(type ##_copy_ctor) } }; \ + { { ti_flags, &type ##_type_info, { 0, -1, 0 }, sizeof(type), copyctor } }; \ \ static const cxx_type_info_table type ## _cxx_type_table = \ - { ARRAY_SIZE(((const void *[]){ NULL, __VA_ARGS__ })), { type ## _cxx_type_info, __VA_ARGS__ } }; \ + { ARRAY_SIZE(((const void *[]){ __VA_ARGS__ })), { __VA_ARGS__ } }; \ \ static const cxx_exception_type type ## _exception_type = \ - { 0, THISCALL(dtor), NULL, & type ## _cxx_type_table }; + { flags, dtor, NULL, & type ## _cxx_type_table }; #define INIT_CXX_TYPE(name,base) (void)name ## _exception_type #elif defined __WINE_PE_BUILD -#define DEFINE_CXX_TYPE2(type, dtor, ...) \ +#define CXX_FUNC(func) ".rva " #func +#define CXX_NULL ".long 0" + +#define DEFINE_CXX_TYPE2(type, flags, ti_flags, dtor, copyctor, ...) \ extern const cxx_type_info type ## _cxx_type_info[1]; \ extern const cxx_exception_type type ## _exception_type; \ void __asm_dummy_ ## type ## _exception_type(void) \ { \ asm( ".balign 4\n\t" \ __ASM_GLOBL(#type "_cxx_type_info") "\n\t" \ - ".long 0\n\t" \ + ".long %c0\n\t" \ ".rva " #type "_type_info\n\t" \ - ".long 0, -1, 0, %c0\n\t" \ - ".rva " #type "_copy_ctor\n" \ + ".long 0, -1, 0, %c1\n\t" \ + copyctor "\n\t" \ #type "_type_table:\n\t" \ - ".long %c1\n\t" \ + ".long %c2\n\t" \ ".rva " #__VA_ARGS__ "\n\t" \ __ASM_GLOBL(#type "_exception_type") "\n\t" \ - ".long 0\n\t" \ - ".rva " #dtor "\n\t" \ + ".long %c3\n\t" \ + dtor "\n\t" \ ".long 0\n\t" \ ".rva " #type "_type_table\n\t" \ - :: "i"(sizeof(type)), "i"(ARRAY_SIZE(((const void *[]){ &__VA_ARGS__ }))) ); \ + :: "i"(ti_flags), "i"(sizeof(type)), "i"(ARRAY_SIZE(((const void *[]){ &__VA_ARGS__ }))), "i"(flags) ); \ } -#define DEFINE_CXX_TYPE(type, dtor, ...) \ - DEFINE_CXX_TYPE2(type, dtor, type ## _cxx_type_info, ##__VA_ARGS__) #define INIT_CXX_TYPE(name,base) /* nothing to do */ #else /* CXX_USE_RVA */ -#define DEFINE_CXX_TYPE(type, dtor, ...) \ +#define CXX_FUNC(func) func +#define CXX_NULL NULL + +#define DEFINE_CXX_TYPE2(type, flags, ti_flags, dtor, copyctor, ...) \ static cxx_type_info type ## _cxx_type_info[1] = \ - { { 0, 0xdeadbeef, { 0, -1, 0 }, sizeof(type), 0xdeadbeef } }; \ + { { ti_flags, 0xdeadbeef, { 0, -1, 0 }, sizeof(type), 0xdeadbeef } }; \ \ -static const void * const type ## _cxx_type_classes[] = { type ## _cxx_type_info, __VA_ARGS__ }; \ +static const void * const type ## _cxx_type_classes[] = { __VA_ARGS__ }; \ static cxx_type_info_table type ## _cxx_type_table = { ARRAY_SIZE(type ## _cxx_type_classes) }; \ -static cxx_exception_type type ##_exception_type; \ +static cxx_exception_type type ##_exception_type = {flags}; \ \ static void init_ ## type ## _cxx(char *base) \ { \ type ## _cxx_type_info[0].type_info = (char *)&type ## _type_info - base; \ - type ## _cxx_type_info[0].copy_ctor = (char *)type ## _copy_ctor - base; \ + type ## _cxx_type_info[0].copy_ctor = (copyctor) ? (char *)(copyctor) - base : 0; \ for (unsigned int i = 0; i < ARRAY_SIZE(type ## _cxx_type_classes); i++) \ type ## _cxx_type_table.info[i] = (char *)type ## _cxx_type_classes[i] - base; \ - type ## _exception_type.destructor = (char *)dtor - base; \ + type ## _exception_type.destructor = (dtor) ? (char *)(dtor) - base : 0; \ type ## _exception_type.type_info_table = (char *)&type ## _cxx_type_table - base; \ } @@ -203,6 +219,14 @@ static void init_ ## type ## _cxx(char *base) \ #endif /* CXX_USE_RVA */ +#define DEFINE_CXX_TYPE(type, dtor, ...) \ + DEFINE_CXX_TYPE2(type, 0, 0, CXX_FUNC(dtor), CXX_FUNC(type ##_copy_ctor), \ + type ## _cxx_type_info, ##__VA_ARGS__) + +#define DEFINE_WINRT_CXX_TYPE(type, ...) \ + DEFINE_CXX_TYPE2(type, TYPE_FLAG_WINRT, CLASS_IS_SIMPLE_TYPE | CLASS_IS_WINRT, \ + CXX_NULL, CXX_NULL, type ## _cxx_type_info, ##__VA_ARGS__) + #ifdef __ASM_USE_THISCALL_WRAPPER #define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (WINAPI*)type)&vtbl_wrapper_##off)args diff --git a/dlls/msvcp90/exception.c b/dlls/msvcp90/exception.c index aef1268068c..ab8de5de782 100644 --- a/dlls/msvcp90/exception.c +++ b/dlls/msvcp90/exception.c @@ -41,10 +41,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcp); CREATE_TYPE_INFO_VTABLE -#define CLASS_IS_SIMPLE_TYPE 1 -#define CLASS_HAS_VIRTUAL_BASE_CLASS 4 -#define CLASS_IS_IUNKNOWN 8 - int* __cdecl __processing_throw(void); #if _MSVCP_VER >= 70 || defined(_MSVCIRT) @@ -1200,7 +1196,7 @@ 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) + if (type->flags & CLASS_IS_WINRT && *(IUnknown**)object) IUnknown_AddRef(*(IUnknown**)object); memmove( dest, object, type->size ); /* if it is a pointer, adjust it */ @@ -1216,7 +1212,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/cppexcept.h b/dlls/msvcrt/cppexcept.h index 0f64f97dd20..cf9e7a25cbc 100644 --- a/dlls/msvcrt/cppexcept.h +++ b/dlls/msvcrt/cppexcept.h @@ -133,15 +133,6 @@ typedef struct #define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs and /EHsc) */ #define FUNC_DESCR_NOEXCEPT 4 /* noexcept function */ -#define CLASS_IS_SIMPLE_TYPE 1 -#define CLASS_HAS_VIRTUAL_BASE_CLASS 4 -#define CLASS_IS_WINRT 8 - -#define TYPE_FLAG_CONST 1 -#define TYPE_FLAG_VOLATILE 2 -#define TYPE_FLAG_REFERENCE 8 -#define TYPE_FLAG_WINRT 16 - typedef struct winrt_exception_info { BSTR description; diff --git a/dlls/msvcrt/cxx.h b/dlls/msvcrt/cxx.h index b803d35a283..64776822d9e 100644 --- a/dlls/msvcrt/cxx.h +++ b/dlls/msvcrt/cxx.h @@ -21,6 +21,15 @@ #include "rtlsupportapi.h" #include "wine/asm.h" +#define CLASS_IS_SIMPLE_TYPE 1 +#define CLASS_HAS_VIRTUAL_BASE_CLASS 4 +#define CLASS_IS_WINRT 8 + +#define TYPE_FLAG_CONST 1 +#define TYPE_FLAG_VOLATILE 2 +#define TYPE_FLAG_REFERENCE 8 +#define TYPE_FLAG_WINRT 16 + #ifdef __i386__ #undef CXX_USE_RVA #else @@ -139,63 +148,70 @@ static void init_ ## name ## _rtti(char *base) \ #ifndef CXX_USE_RVA -#define DEFINE_CXX_TYPE(type, dtor, ...) \ +#define CXX_FUNC(func) THISCALL(func) +#define CXX_NULL NULL + +#define DEFINE_CXX_TYPE2(type, flags, ti_flags, dtor, copyctor, ...) \ static const cxx_type_info type ## _cxx_type_info[1] = \ - { { 0, &type ##_type_info, { 0, -1, 0 }, sizeof(type), THISCALL(type ##_copy_ctor) } }; \ + { { ti_flags, &type ##_type_info, { 0, -1, 0 }, sizeof(type), copyctor } }; \ \ static const cxx_type_info_table type ## _cxx_type_table = \ - { ARRAY_SIZE(((const void *[]){ NULL, __VA_ARGS__ })), { type ## _cxx_type_info, __VA_ARGS__ } }; \ + { ARRAY_SIZE(((const void *[]){ __VA_ARGS__ })), { __VA_ARGS__ } }; \ \ static const cxx_exception_type type ## _exception_type = \ - { 0, THISCALL(dtor), NULL, & type ## _cxx_type_table }; + { flags, dtor, NULL, & type ## _cxx_type_table }; #define INIT_CXX_TYPE(name,base) (void)name ## _exception_type #elif defined __WINE_PE_BUILD -#define DEFINE_CXX_TYPE2(type, dtor, ...) \ +#define CXX_FUNC(func) ".rva " #func +#define CXX_NULL ".long 0" + +#define DEFINE_CXX_TYPE2(type, flags, ti_flags, dtor, copyctor, ...) \ extern const cxx_type_info type ## _cxx_type_info[1]; \ extern const cxx_exception_type type ## _exception_type; \ void __asm_dummy_ ## type ## _exception_type(void) \ { \ asm( ".balign 4\n\t" \ __ASM_GLOBL(#type "_cxx_type_info") "\n\t" \ - ".long 0\n\t" \ + ".long %c0\n\t" \ ".rva " #type "_type_info\n\t" \ - ".long 0, -1, 0, %c0\n\t" \ - ".rva " #type "_copy_ctor\n" \ + ".long 0, -1, 0, %c1\n\t" \ + copyctor "\n\t" \ #type "_type_table:\n\t" \ - ".long %c1\n\t" \ + ".long %c2\n\t" \ ".rva " #__VA_ARGS__ "\n\t" \ __ASM_GLOBL(#type "_exception_type") "\n\t" \ - ".long 0\n\t" \ - ".rva " #dtor "\n\t" \ + ".long %c3\n\t" \ + dtor "\n\t" \ ".long 0\n\t" \ ".rva " #type "_type_table\n\t" \ - :: "i"(sizeof(type)), "i"(ARRAY_SIZE(((const void *[]){ &__VA_ARGS__ }))) ); \ + :: "i"(ti_flags), "i"(sizeof(type)), "i"(ARRAY_SIZE(((const void *[]){ &__VA_ARGS__ }))), "i"(flags) ); \ } -#define DEFINE_CXX_TYPE(type, dtor, ...) \ - DEFINE_CXX_TYPE2(type, dtor, type ## _cxx_type_info, ##__VA_ARGS__) #define INIT_CXX_TYPE(name,base) /* nothing to do */ #else /* CXX_USE_RVA */ -#define DEFINE_CXX_TYPE(type, dtor, ...) \ +#define CXX_FUNC(func) func +#define CXX_NULL NULL + +#define DEFINE_CXX_TYPE2(type, flags, ti_flags, dtor, copyctor, ...) \ static cxx_type_info type ## _cxx_type_info[1] = \ - { { 0, 0xdeadbeef, { 0, -1, 0 }, sizeof(type), 0xdeadbeef } }; \ + { { ti_flags, 0xdeadbeef, { 0, -1, 0 }, sizeof(type), 0xdeadbeef } }; \ \ -static const void * const type ## _cxx_type_classes[] = { type ## _cxx_type_info, __VA_ARGS__ }; \ +static const void * const type ## _cxx_type_classes[] = { __VA_ARGS__ }; \ static cxx_type_info_table type ## _cxx_type_table = { ARRAY_SIZE(type ## _cxx_type_classes) }; \ -static cxx_exception_type type ##_exception_type; \ +static cxx_exception_type type ##_exception_type = {flags}; \ \ static void init_ ## type ## _cxx(char *base) \ { \ type ## _cxx_type_info[0].type_info = (char *)&type ## _type_info - base; \ - type ## _cxx_type_info[0].copy_ctor = (char *)type ## _copy_ctor - base; \ + type ## _cxx_type_info[0].copy_ctor = (copyctor) ? (char *)(copyctor) - base : 0; \ for (unsigned int i = 0; i < ARRAY_SIZE(type ## _cxx_type_classes); i++) \ type ## _cxx_type_table.info[i] = (char *)type ## _cxx_type_classes[i] - base; \ - type ## _exception_type.destructor = (char *)dtor - base; \ + type ## _exception_type.destructor = (dtor) ? (char *)(dtor) - base : 0; \ type ## _exception_type.type_info_table = (char *)&type ## _cxx_type_table - base; \ } @@ -203,6 +219,14 @@ static void init_ ## type ## _cxx(char *base) \ #endif /* CXX_USE_RVA */ +#define DEFINE_CXX_TYPE(type, dtor, ...) \ + DEFINE_CXX_TYPE2(type, 0, 0, CXX_FUNC(dtor), CXX_FUNC(type ##_copy_ctor), \ + type ## _cxx_type_info, ##__VA_ARGS__) + +#define DEFINE_WINRT_CXX_TYPE(type, ...) \ + DEFINE_CXX_TYPE2(type, TYPE_FLAG_WINRT, CLASS_IS_SIMPLE_TYPE | CLASS_IS_WINRT, \ + CXX_NULL, CXX_NULL, type ## _cxx_type_info, ##__VA_ARGS__) + #ifdef __ASM_USE_THISCALL_WRAPPER #define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (WINAPI*)type)&vtbl_wrapper_##off)args -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9209
From: Vibhav Pant <vibhavp(a)gmail.com> --- dlls/vccorlib140/except.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index b5c4254b6fc..40d55b65930 100644 --- a/dlls/vccorlib140/except.c +++ b/dlls/vccorlib140/except.c @@ -306,9 +306,26 @@ struct Exception *__cdecl Exception_ctor(struct Exception *this, HRESULT hr) return this; } -void *__cdecl Exception_hstring_ctor(void *this, HRESULT hr, HSTRING msg) +struct Exception *__cdecl Exception_hstring_ctor(struct Exception *this, HRESULT hr, HSTRING msg) { - FIXME("(%p, %#lx, %s): stub!\n", this, hr, debugstr_hstring(msg)); + const WCHAR *buf; + BOOL has_null; + UINT32 len; + + TRACE("(%p, %#lx, %s)\n", this, hr, debugstr_hstring(msg)); + + Exception_ctor(this, hr); + if (WindowsIsStringEmpty(msg)) return this; + + /* Native throws InvalidArgumentException if msg has an embedded NUL byte. */ + if (FAILED(hr = WindowsStringHasEmbeddedNull(msg, &has_null))) + __abi_WinRTraiseCOMException(hr); + else if (has_null) + __abi_WinRTraiseInvalidArgumentException(); + + buf = WindowsGetStringRawBuffer(msg, &len); + if (len && !(this->inner.restricted_desc = SysAllocStringLen(buf, len))) + __abi_WinRTraiseOutOfMemoryException(); return this; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9209
From: Vibhav Pant <vibhavp(a)gmail.com> --- dlls/vccorlib140/except.c | 51 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index 40d55b65930..cd059f73e11 100644 --- a/dlls/vccorlib140/except.c +++ b/dlls/vccorlib140/except.c @@ -329,15 +329,53 @@ struct Exception *__cdecl Exception_hstring_ctor(struct Exception *this, HRESULT return this; } -void *__cdecl COMException_ctor(void *this, HRESULT hr) +DEFINE_RTTI_DATA(COMException_ref, 0, EXCEPTION_REF_NAME(COM), Exception_ref_rtti_base_descriptor); +typedef struct Exception *COMException_ref; +DEFINE_WINRT_CXX_TYPE(COMException_ref, Exception_ref_cxx_type_info); + +DEFINE_RTTI_DATA(COMException, 0, ".?AVCOMException(a)Platform@@"); +COM_VTABLE_RTTI_START(IInspectable, COMException) +COM_VTABLE_ENTRY(Exception_QueryInterface) +COM_VTABLE_ENTRY(Exception_AddRef) +COM_VTABLE_ENTRY(Exception_Release) +COM_VTABLE_ENTRY(Exception_GetIids) +COM_VTABLE_ENTRY(Exception_GetRuntimeClassName) +COM_VTABLE_ENTRY(Exception_GetTrustLevel) +COM_VTABLE_RTTI_END; + +DEFINE_RTTI_DATA(COMException_Closable, offsetof(struct Exception, IClosable_iface), + ".?AVCOMException(a)Platform@@") +COM_VTABLE_RTTI_START(IClosable, COMException_Closable) +COM_VTABLE_ENTRY(Exception_Closable_QueryInterface) +COM_VTABLE_ENTRY(Exception_Closable_AddRef) +COM_VTABLE_ENTRY(Exception_Closable_Release) +COM_VTABLE_ENTRY(Exception_Closable_GetIids) +COM_VTABLE_ENTRY(Exception_Closable_GetRuntimeClassName) +COM_VTABLE_ENTRY(Exception_Closable_GetTrustLevel) +COM_VTABLE_ENTRY(Exception_Closable_Close) +COM_VTABLE_RTTI_END; + +struct Exception *__cdecl COMException_ctor(struct Exception *this, HRESULT hr) { - FIXME("(%p, %#lx): stub!\n", this, hr); + TRACE("(%p, %#lx)\n", this, hr); + + Exception_ctor(this, hr); + + this->IInspectable_iface.lpVtbl = &COMException_vtable.vtable; + this->IClosable_iface.lpVtbl = &COMException_Closable_vtable.vtable; + this->inner.exception_type = &COMException_ref_exception_type; return this; } -void *__cdecl COMException_hstring_ctor(void *this, HRESULT hr, HSTRING msg) +struct Exception *__cdecl COMException_hstring_ctor(struct Exception *this, HRESULT hr, HSTRING msg) { - FIXME("(%p, %#lx, %s): stub!\n", this, hr, debugstr_hstring(msg)); + TRACE("(%p, %#lx, %s)\n", this, hr, debugstr_hstring(msg)); + + Exception_hstring_ctor(this, hr, msg); + + this->IInspectable_iface.lpVtbl = &COMException_vtable.vtable; + this->IClosable_iface.lpVtbl = &COMException_Closable_vtable.vtable; + this->inner.exception_type = &COMException_ref_exception_type; return this; } @@ -353,4 +391,9 @@ void init_exception(void *base) INIT_CXX_TYPE(Exception_ref, base); INIT_RTTI(Exception, base); INIT_RTTI(Exception_Closable, base); + + INIT_RTTI(COMException_ref, base); + INIT_CXX_TYPE(COMException_ref, base); + INIT_RTTI(COMException, base); + INIT_RTTI(COMException_Closable, base); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9209
From: Vibhav Pant <vibhavp(a)gmail.com> --- dlls/vccorlib140/except.c | 107 +++++++++++++++++++++++++++++-------- dlls/vccorlib140/private.h | 2 + 2 files changed, 87 insertions(+), 22 deletions(-) diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index cd059f73e11..e57b37bad32 100644 --- a/dlls/vccorlib140/except.c +++ b/dlls/vccorlib140/except.c @@ -110,25 +110,6 @@ void WINAPI __abi_WinRTraiseCOMException(HRESULT hr) WINRT_EXCEPTION(OutOfMemory, E_OUTOFMEMORY) \ WINRT_EXCEPTION(WrongThread, RPC_E_WRONG_THREAD) -#define WINRT_EXCEPTION(name, hr) \ - void WINAPI __abi_WinRTraise##name##Exception(void) \ - { \ - FIXME("(): stub!\n"); \ - } \ - void *__cdecl name##Exception_ctor(void *this) \ - { \ - FIXME("(%p): stub!\n", this); \ - return this; \ - } \ - void *__cdecl name##Exception_hstring_ctor(void *this, HSTRING msg) \ - { \ - FIXME("(%p, %s): stub!\n", this, debugstr_hstring(msg)); \ - return this; \ - } - -WINRT_EXCEPTIONS -#undef WINRT_EXCEPTION - static inline struct Exception *impl_Exception_from_IInspectable(IInspectable *iface) { return CONTAINING_RECORD(iface, struct Exception, IInspectable_iface); @@ -379,10 +360,84 @@ struct Exception *__cdecl COMException_hstring_ctor(struct Exception *this, HRES return this; } -HSTRING __cdecl Exception_get_Message(void *excp) +#define WINRT_EXCEPTION(name, hr) \ + DEFINE_RTTI_DATA(name##Exception_ref, 0, EXCEPTION_REF_NAME(name), \ + COMException_ref_rtti_base_descriptor, Exception_ref_rtti_base_descriptor); \ + typedef COMException_ref name##Exception_ref; \ + DEFINE_WINRT_CXX_TYPE(name##Exception_ref, COMException_ref_cxx_type_info, \ + Exception_ref_cxx_type_info); \ + \ + DEFINE_RTTI_DATA(name##Exception, 0, ".?AV" #name "Exception(a)Platform@@"); \ + COM_VTABLE_RTTI_START(IInspectable, name##Exception) \ + COM_VTABLE_ENTRY(Exception_QueryInterface) \ + COM_VTABLE_ENTRY(Exception_AddRef) \ + COM_VTABLE_ENTRY(Exception_Release) \ + COM_VTABLE_ENTRY(Exception_GetIids) \ + COM_VTABLE_ENTRY(Exception_GetRuntimeClassName) \ + COM_VTABLE_ENTRY(Exception_GetTrustLevel) \ + COM_VTABLE_RTTI_END; \ + \ + DEFINE_RTTI_DATA(name##Exception_Closable, offsetof(struct Exception, IClosable_iface), \ + ".?AV" #name "Exception(a)Platform@@"); \ + COM_VTABLE_RTTI_START(IClosable, name##Exception_Closable) \ + COM_VTABLE_ENTRY(Exception_Closable_QueryInterface) \ + COM_VTABLE_ENTRY(Exception_Closable_AddRef) \ + COM_VTABLE_ENTRY(Exception_Closable_Release) \ + COM_VTABLE_ENTRY(Exception_Closable_GetIids) \ + COM_VTABLE_ENTRY(Exception_Closable_GetRuntimeClassName) \ + COM_VTABLE_ENTRY(Exception_Closable_GetTrustLevel) \ + COM_VTABLE_ENTRY(Exception_Closable_Close) \ + COM_VTABLE_RTTI_END; \ + \ + struct Exception *__cdecl name##Exception_ctor(struct Exception *this) \ + { \ + TRACE("(%p)\n", this); \ + Exception_ctor(this, hr); \ + this->IInspectable_iface.lpVtbl = &name##Exception_vtable.vtable; \ + this->IClosable_iface.lpVtbl = &name##Exception_Closable_vtable.vtable; \ + this->inner.exception_type = &name##Exception_ref_exception_type; \ + return this; \ + } \ + \ + struct Exception *__cdecl name##Exception_hstring_ctor(struct Exception *this, HSTRING msg) \ + { \ + TRACE("(%p, %s)\n", this, debugstr_hstring(msg)); \ + Exception_hstring_ctor(this, hr, msg); \ + this->IInspectable_iface.lpVtbl = &name##Exception_vtable.vtable; \ + 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 + +HSTRING __cdecl Exception_get_Message(struct Exception *this) { - FIXME("(%p): stub!\n", excp); - return NULL; + HSTRING msg = NULL; + HRESULT hr = S_OK; + + TRACE("(%p)\n", this); + + if (this->inner.restricted_desc) + hr = WindowsCreateString(this->inner.restricted_desc, wcslen(this->inner.restricted_desc), &msg); + else + { + WCHAR buf[256]; + + if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, this->inner.hr, 0, buf, ARRAY_SIZE(buf), NULL)) + hr = WindowsCreateString(buf, wcslen(buf), &msg); + else + ERR("FormatMessageW failed: %lu\n", GetLastError()); + } + + if (FAILED(hr)) + __abi_WinRTraiseCOMException(hr); + return msg; } void init_exception(void *base) @@ -396,4 +451,12 @@ void init_exception(void *base) INIT_CXX_TYPE(COMException_ref, base); INIT_RTTI(COMException, base); INIT_RTTI(COMException_Closable, base); + +#define WINRT_EXCEPTION(name, hr) \ + INIT_RTTI(name##Exception_ref, base); \ + INIT_CXX_TYPE(name##Exception_ref, base); \ + INIT_RTTI(name##Exception, base); \ + INIT_RTTI(name##Exception_Closable, base); + WINRT_EXCEPTIONS +#undef WINRT_EXCEPTION } diff --git a/dlls/vccorlib140/private.h b/dlls/vccorlib140/private.h index 384cb6bfd40..18410955f05 100644 --- a/dlls/vccorlib140/private.h +++ b/dlls/vccorlib140/private.h @@ -44,6 +44,8 @@ struct control_block void __cdecl FreeException(void *); void init_exception(void *); +void WINAPI __abi_WinRTraiseInvalidArgumentException(void); +void WINAPI __abi_WinRTraiseOutOfMemoryException(void); #define COM_VTABLE_RTTI_START(iface, type) \ static const struct \ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9209
From: Vibhav Pant <vibhavp(a)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(a)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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9209
From: Vibhav Pant <vibhavp(a)gmail.com> --- dlls/vccorlib140/vccorlib.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/dlls/vccorlib140/vccorlib.c b/dlls/vccorlib140/vccorlib.c index 49b730a2914..b7a4fb1cd29 100644 --- a/dlls/vccorlib140/vccorlib.c +++ b/dlls/vccorlib140/vccorlib.c @@ -92,9 +92,8 @@ void *__cdecl Allocate(size_t size) TRACE("(%Iu)\n", size); addr = malloc(size); - /* TODO: Throw a COMException on allocation failure. */ if (!addr) - FIXME("allocation failure\n"); + __abi_WinRTraiseOutOfMemoryException(); return addr; } @@ -397,8 +396,7 @@ static const char *debugstr_abi_type_descriptor(const struct __abi_type_descript void *WINAPI __abi_make_type_id(const struct __abi_type_descriptor *desc) { /* TODO: - * Implement IEquatable and IPrintable. - * Throw a COMException if CoCreateFreeThreadedMarshaler fails. */ + * Implement IEquatable and IPrintable. */ struct platform_type *obj; HRESULT hr; @@ -412,9 +410,8 @@ void *WINAPI __abi_make_type_id(const struct __abi_type_descriptor *desc) hr = CoCreateFreeThreadedMarshaler((IUnknown *)&obj->IInspectable_iface, &obj->marshal); if (FAILED(hr)) { - FIXME("CoCreateFreeThreadedMarshaler failed: %#lx\n", hr); Free(obj); - return NULL; + __abi_WinRTraiseCOMException(hr); } return &obj->IInspectable_iface; } @@ -440,10 +437,9 @@ HSTRING __cdecl platform_type_ToString(struct platform_type *this) TRACE("(%p)\n", this); - /* TODO: Throw a COMException if this fails */ hr = WindowsCreateString(this->desc->name, this->desc->name ? wcslen(this->desc->name) : 0, &str); if (FAILED(hr)) - FIXME("WindowsCreateString failed: %#lx\n", hr); + __abi_WinRTraiseCOMException(hr); return str; } @@ -580,10 +576,7 @@ void *WINAPI CreateValue(int typecode, const void *val) IPropertyValueStatics_Release(statics); if (FAILED(hr)) - { - FIXME("Failed to create IPropertyValue object: %#lx\n", hr); - return NULL; - } + __abi_WinRTraiseCOMException(hr); return obj; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9209
From: Vibhav Pant <vibhavp(a)gmail.com> --- dlls/vccorlib140/except.c | 24 ++++++++++++++++++++++++ dlls/vccorlib140/vccorlib140.spec | 5 ++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index d00f35c71f1..c771554e72f 100644 --- a/dlls/vccorlib140/except.c +++ b/dlls/vccorlib140/except.c @@ -33,6 +33,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(vccorlib); extern void WINAPI DECLSPEC_NORETURN _CxxThrowException(void *, const cxx_exception_type *); +extern const void **__cdecl __current_exception(void); #ifdef _WIN64 #define EXCEPTION_REF_NAME(name) ".PE$AAV" #name "Exception(a)Platform@@" @@ -501,3 +502,26 @@ void init_exception(void *base) WINRT_EXCEPTIONS #undef WINRT_EXCEPTION } + +HRESULT WINAPI __abi_translateCurrentException(bool unknown) +{ + const struct Exception *excp; + const EXCEPTION_RECORD *record; + const cxx_exception_type *type; + + FIXME("(%d): semi-stub!\n", unknown); + + record = *__current_exception(); + /* Native aborts if: + * There is no exception being currently handled. + * There is no associated exception object (_CxxThrowException(NULL, ...) was called). + * There is no associated cxx_exception_type param (_CxxThrowException(..., NULL) was called). + * A non C++/CX exception has been thrown. */ + if (!record || !record->ExceptionInformation[1] || + !(excp = *(struct Exception **)record->ExceptionInformation[1]) || + !(type = (cxx_exception_type *)record->ExceptionInformation[2]) || + !(type->flags & TYPE_FLAG_WINRT)) + abort(); + return excp->inner.hr; +} + diff --git a/dlls/vccorlib140/vccorlib140.spec b/dlls/vccorlib140/vccorlib140.spec index 64b01047337..99b32fd1571 100644 --- a/dlls/vccorlib140/vccorlib140.spec +++ b/dlls/vccorlib140/vccorlib140.spec @@ -338,9 +338,8 @@ @ stdcall -arch=win64 ?__abi_make_type_id@@YAPE$AAVType(a)Platform@@AEBU__abi_type_descriptor@@@Z(ptr) __abi_make_type_id @ stub -arch=win32 ??0IntPtr(a)Platform@@QAA(a)PAX@Z @ stub -arch=win64 ??0IntPtr(a)Platform@@QEAA(a)PEAX@Z -@ stub -arch=i386 ?__abi_translateCurrentException@@YGJ_N(a)Z -@ stub -arch=arm ?__abi_translateCurrentException@@YAJ_N(a)Z -@ stub -arch=win64 ?__abi_translateCurrentException@@YAJ_N(a)Z +@ stdcall -arch=i386 ?__abi_translateCurrentException@@YGJ_N(a)Z(long) __abi_translateCurrentException +@ stdcall -arch=arm,win64 ?__abi_translateCurrentException@@YAJ_N(a)Z(long) __abi_translateCurrentException @ stub -arch=i386 ?__getActivationFactoryByHSTRING@@YGJPAUHSTRING__@@AAVGuid(a)Platform@@PAPAX(a)Z @ stub -arch=arm ?__getActivationFactoryByHSTRING@@YAJPAUHSTRING__@@AAVGuid(a)Platform@@PAPAX(a)Z @ stub -arch=win64 ?__getActivationFactoryByHSTRING@@YAJPEAUHSTRING__@@AEAVGuid(a)Platform@@PEAPEAX(a)Z -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9209
I've pushed a new version with a lot of changes - please approve the MR (or comment) if it looks good to you. Increasing exception object reference on throw looks strange. Do you know what's the rationale behind it? I see that it matches with Windows, I don't understand why it's needed. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9209#note_120375
On Sun Nov 2 15:41:53 2025 +0000, Piotr Caban wrote:
I've pushed a new version with a lot of changes - please approve the MR (or comment) if it looks good to you. Increasing exception object reference on throw looks strange. Do you know what's the rationale behind it? I see that it matches with Windows, I don't understand why it's needed. Everything looks good, thank you!
Increasing exception object reference on throw looks strange. Do you know what's the rationale behind it? I see that it matches with Windows, I don't understand why it's needed.
My initial hypothesis was that it expects the `catch` block to call `Release` on the exception object, but I don't see such a call in disassembled C++/CX code. I can't imagine `__DestructExceptionObject` will call `Release` twice, so a `Release` is happening somewhere between the two points, hopefully it's the app's responsibility (and codegen'd by MSVC) and not the runtime, otherwise we're probably leaking exceptions :/ -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9209#note_120391
This merge request was approved by Vibhav Pant. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9209
On Sun Nov 2 15:41:53 2025 +0000, Vibhav Pant wrote:
Everything looks good, thank you!
Increasing exception object reference on throw looks strange. Do you know what's the rationale behind it? I see that it matches with Windows, I don't understand why it's needed. My initial hypothesis was that it expects the `catch` block to call `Release` on the exception object, but I don't see such a call in disassembled C++/CX code. I can't imagine `__DestructExceptionObject` will call `Release` twice, so a `Release` is happening somewhere between the two points, hopefully it's the app's responsibility (and codegen'd by MSVC) and not the runtime, otherwise we're probably leaking exceptions :/ I've done some more tests looking into WinRT exception leaks. In the tests I have written we're leaking 2 references if builtin vccorlib140 and vcruntime140 is used. We're getting down to 1 reference being leaked when one of the dlls is native. There's no leak if both dlls are native. I think we need to understand it better before the change can get into wine.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9209#note_120396
On Sun Nov 2 17:39:19 2025 +0000, Piotr Caban wrote:
I've done some more tests looking into WinRT exception leaks. In the tests I have written we're leaking 2 references if builtin vccorlib140 and vcruntime140 is used. We're getting down to 1 reference being leaked when one of the dlls is native. There's no leak if both dlls are native. I think we need to understand it better before the change can get into wine. It looks like on vccorlib140 side there's something along these lines:
```c static void DECLSPEC_NORETURN throw_exception(struct Exception *excp, const cxx_exception_type *type) { /* Thrown exceptions have a refcount of 2. */ __TRY { IInspectable_AddRef(&excp->IInspectable_iface); _CxxThrowException(&excp, type); } __FINALLY_CTX(throw_exception_finally, &excp->IInspectable_iface); } ``` I guess it tries to workaround some kind of refcounting error in older C-runtime/some kind of app. I'm not sure if it makes sense to replicate it as long as there's no application that depends on it. How about removing AddRef call from throw_exception helper? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9209#note_120399
On Sun Nov 2 18:45:06 2025 +0000, Piotr Caban wrote:
It looks like on vccorlib140 side there's something along these lines: ```c static void DECLSPEC_NORETURN throw_exception(struct Exception *excp, const cxx_exception_type *type) { /* Thrown exceptions have a refcount of 2. */ __TRY { IInspectable_AddRef(&excp->IInspectable_iface); _CxxThrowException(&excp, type); } __FINALLY_CTX(throw_exception_finally, &excp->IInspectable_iface); } ``` I guess it tries to workaround some kind of refcounting error in older C-runtime/some kind of app. I'm not sure if it makes sense to replicate it as long as there's no application that depends on it. How about removing AddRef call from throw_exception helper? The bug in vcruntime140 is caused by difference in \__C_specific_handler (between ntdll and C-runtime). It looks like native is sometimes destroying the exception object there. It's not specific to WinRT exceptions.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9209#note_120400
On Sun Nov 2 18:55:31 2025 +0000, Piotr Caban wrote:
The bug in vcruntime140 is caused by difference in \__C_specific_handler (between ntdll and C-runtime). It looks like native is sometimes destroying the exception object there. It's not specific to WinRT exceptions. Sorry, I didn't paste throw_exception_finally function body - it calls `IInspectable_Release.`
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9209#note_120401
How about removing AddRef call from throw_exception helper?
C++/CX code that manually throws exceptions is still compiled with a call to `AddRef` before `_CxxThrowException`. This just seems to be the code generated by MSVC for throwing exceptions in `C++/CX`, rather than something specific to the `__abi_WinRTraise*` functions. So even if we don't remove the AddRef call here, exceptions thrown from C++/CX code would still leak, I think. The [test code here](https://gitlab.winehq.org/wine/wine/-/snippets/31) suggests that not only there is a `__FINALLY` terminating handler that does call Release, but also that `__CxxFrameHandler(4)` calls `Release` before it dispatches the object to a matching `catch`. We could probably replace `IUnknown_Release` with `IUnknown_AddRef` in `copy_exception` to get the same results. That way, with the additional `Release` in `_C_specific_handler`, the exception should be correctly freed. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9209#note_120402
On Sun Nov 2 21:14:03 2025 +0000, Vibhav Pant wrote:
How about removing AddRef call from throw_exception helper? C++/CX code that manually throws exceptions is still compiled with a call to `AddRef` before `_CxxThrowException`. This just seems to be the code generated by MSVC for throwing exceptions in `C++/CX`, rather than something specific to the `__abi_WinRTraise*` functions. So even if we don't remove the AddRef call here, exceptions thrown from C++/CX code would still leak, I think. The [test code here](https://gitlab.winehq.org/wine/wine/-/snippets/31) suggests that not only there is a `__FINALLY` terminating handler that does call Release, but also that `__CxxFrameHandler(4)` calls `Release` before it dispatches the object to a matching `catch`. We could probably replace `IUnknown_Release` with `IUnknown_AddRef` in `copy_exception` to get the same results. That way, with the additional `Release/__DestructExceptionObject` in `_C_specific_handler`, the exception should be correctly freed. I create a draft !9351 which tries to call the exception destructor in `__C_specific_handler`, and call `Release` for WinRT exceptions in `copy_exception`. It's likely not what all native is doing for C++/WinRT exceptions, but it does resolve the leaks.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9209#note_120473
On Mon Nov 3 10:59:14 2025 +0000, Vibhav Pant wrote:
I create a draft !9351 which tries to call the exception destructor in `__C_specific_handler`, and call `Release` for WinRT exceptions in `copy_exception`. It's likely not what all native is doing for C++/WinRT exceptions, but it does resolve the leaks. I think it would be best to go with first patch from !9351 and removing AddRef from throw for now.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9209#note_120476
participants (4)
-
Piotr Caban -
Piotr Caban (@piotr) -
Vibhav Pant -
Vibhav Pant (@vibhavp)