-- v15: vccorlib140: Implement __abi_translateCurrentException. vccorlib140: Throw exceptions on error paths.
From: Vibhav Pant vibhavp@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);
From: Piotr Caban piotr@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)
From: Piotr Caban piotr@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@Platform@@U$AAAXXZ @ stub -arch=win64 ?<Dispose>@Exception@Platform@@UE$AAAXXZ -@ cdecl -arch=win32 ??0ChangedStateException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_ChangedStateException_hstring_ctor -@ cdecl -arch=win64 ??0ChangedStateException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_ChangedStateException_hstring_ctor +@ cdecl -arch=win32 ??0ChangedStateException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) ChangedStateException_hstring_ctor +@ cdecl -arch=win64 ??0ChangedStateException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) ChangedStateException_hstring_ctor @ stub -arch=win32 ?Equals@Exception@Platform@@U$AAA_NP$AAVObject@2@@Z @ stub -arch=win64 ?Equals@Exception@Platform@@UE$AAA_NPE$AAVObject@2@@Z @ stub -arch=win32 ?Equals@MTAThreadAttribute@Platform@@Q$AAA_NP$AAVObject@2@@Z @@ -22,8 +22,8 @@ @ stub -arch=win64 ?Equals@float32@default@@QEAA_NPE$AAVObject@Platform@@@Z @ stub -arch=win32 ?Equals@float64@default@@QAA_NP$AAVObject@Platform@@@Z @ stub -arch=win64 ?Equals@float64@default@@QEAA_NPE$AAVObject@Platform@@@Z -@ cdecl -arch=win32 ??0ChangedStateException@Platform@@Q$AAA@XZ(ptr) platform_ChangedStateException_ctor -@ cdecl -arch=win64 ??0ChangedStateException@Platform@@QE$AAA@XZ(ptr) platform_ChangedStateException_ctor +@ cdecl -arch=win32 ??0ChangedStateException@Platform@@Q$AAA@XZ(ptr) ChangedStateException_ctor +@ cdecl -arch=win64 ??0ChangedStateException@Platform@@QE$AAA@XZ(ptr) ChangedStateException_ctor @ stub -arch=win32 ?Equals@int16@default@@QAA_NP$AAVObject@Platform@@@Z @ stub -arch=win64 ?Equals@int16@default@@QEAA_NPE$AAVObject@Platform@@@Z @ stub -arch=win32 ?Equals@int32@default@@QAA_NP$AAVObject@Platform@@@Z @@ -46,8 +46,8 @@ @ stub -arch=i386 ?EventSourceGetTargetArray@Details@Platform@@YGPAXPAXPAUEventLock@12@@Z @ stub -arch=arm ?EventSourceGetTargetArray@Details@Platform@@YAPAXPAXPAUEventLock@12@@Z @ stub -arch=win64 ?EventSourceGetTargetArray@Details@Platform@@YAPEAXPEAXPEAUEventLock@12@@Z -@ cdecl -arch=win32 ??0ClassNotRegisteredException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_ClassNotRegisteredException_hstring_ctor -@ cdecl -arch=win64 ??0ClassNotRegisteredException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_ClassNotRegisteredException_hstring_ctor +@ cdecl -arch=win32 ??0ClassNotRegisteredException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) ClassNotRegisteredException_hstring_ctor +@ cdecl -arch=win64 ??0ClassNotRegisteredException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) ClassNotRegisteredException_hstring_ctor @ stub -arch=i386 ?EventSourceGetTargetArrayEvent@Details@Platform@@YGPAXPAXIPBXPA_J@Z @ stub -arch=arm ?EventSourceGetTargetArrayEvent@Details@Platform@@YAPAXPAXIPBXPA_J@Z @ stub -arch=win64 ?EventSourceGetTargetArrayEvent@Details@Platform@@YAPEAXPEAXIPEBXPEA_J@Z @@ -76,8 +76,8 @@ @ stdcall -arch=i386 ?GetActivationFactoryByPCWSTR@@YGJPAXAAVGuid@Platform@@PAPAX@Z(wstr ptr ptr) GetActivationFactoryByPCWSTR @ stdcall -arch=arm ?GetActivationFactoryByPCWSTR@@YAJPAXAAVGuid@Platform@@PAPAX@Z(wstr ptr ptr) GetActivationFactoryByPCWSTR @ stdcall -arch=win64 ?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z(wstr ptr ptr) GetActivationFactoryByPCWSTR -@ cdecl -arch=win32 ??0ClassNotRegisteredException@Platform@@Q$AAA@XZ(ptr) platform_ClassNotRegisteredException_ctor -@ cdecl -arch=win64 ??0ClassNotRegisteredException@Platform@@QE$AAA@XZ(ptr) platform_ClassNotRegisteredException_ctor +@ cdecl -arch=win32 ??0ClassNotRegisteredException@Platform@@Q$AAA@XZ(ptr) ClassNotRegisteredException_ctor +@ cdecl -arch=win64 ??0ClassNotRegisteredException@Platform@@QE$AAA@XZ(ptr) ClassNotRegisteredException_ctor @ stub -arch=win32 ?GetCmdArguments@Details@Platform@@YAPAPA_WPAH@Z @ stub -arch=win64 ?GetCmdArguments@Details@Platform@@YAPEAPEA_WPEAH@Z @ stub -arch=win32 ?GetHashCode@Attribute@Metadata@Platform@@Q$AAAHXZ @@ -120,8 +120,8 @@ @ stub -arch=win64 ?GetHashCode@int64@default@@QEAAHXZ @ stub -arch=win32 ?GetHashCode@int8@default@@QAAHXZ @ stub -arch=win64 ?GetHashCode@int8@default@@QEAAHXZ -@ cdecl -arch=win32 ??0DisconnectedException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_DisconnectedException_hstring_ctor -@ cdecl -arch=win64 ??0DisconnectedException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_DisconnectedException_hstring_ctor +@ cdecl -arch=win32 ??0DisconnectedException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) DisconnectedException_hstring_ctor +@ cdecl -arch=win64 ??0DisconnectedException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) DisconnectedException_hstring_ctor @ stub -arch=win32 ?GetHashCode@uint16@default@@QAAHXZ @ stub -arch=win64 ?GetHashCode@uint16@default@@QEAAHXZ @ stub -arch=win32 ?GetHashCode@uint32@default@@QAAHXZ @@ -147,8 +147,8 @@ @ stub -arch=win64 ?GetProxyImpl@Details@Platform@@YAJPEAUIUnknown@@AEBU_GUID@@0PEAPEAU3@@Z @ stub -arch=win32 ?GetType@Boolean@Platform@@QAAP$AAVType@2@XZ @ stub -arch=win64 ?GetType@Boolean@Platform@@QEAAPE$AAVType@2@XZ -@ cdecl -arch=win32 ??0DisconnectedException@Platform@@Q$AAA@XZ(ptr) platform_DisconnectedException_ctor -@ cdecl -arch=win64 ??0DisconnectedException@Platform@@QE$AAA@XZ(ptr) platform_DisconnectedException_ctor +@ cdecl -arch=win32 ??0DisconnectedException@Platform@@Q$AAA@XZ(ptr) DisconnectedException_ctor +@ cdecl -arch=win64 ??0DisconnectedException@Platform@@QE$AAA@XZ(ptr) DisconnectedException_ctor @ stub -arch=win32 ?GetType@Guid@Platform@@QAAP$AAVType@2@XZ @ stub -arch=win64 ?GetType@Guid@Platform@@QEAAPE$AAVType@2@XZ @ stub -arch=win32 ?GetType@Object@Platform@@Q$AAAP$AAVType@2@XZ @@ -192,8 +192,8 @@ @ stub -arch=win64 ?IntersectsWith@Rect@Foundation@Windows@@QEAA_NV123@@Z @ stub -arch=win32 ?Invert@Matrix3D@Media3D@Media@Xaml@UI@Windows@@QAAXXZ @ stub -arch=win64 ?Invert@Matrix3D@Media3D@Media@Xaml@UI@Windows@@QEAAXXZ -@ cdecl -arch=win32 ??0Exception@Platform@@Q$AAA@H@Z(ptr long) platform_Exception_ctor -@ cdecl -arch=win64 ??0Exception@Platform@@QE$AAA@H@Z(ptr long) platform_Exception_ctor +@ cdecl -arch=win32 ??0Exception@Platform@@Q$AAA@H@Z(ptr long) Exception_ctor +@ cdecl -arch=win64 ??0Exception@Platform@@QE$AAA@H@Z(ptr long) Exception_ctor @ stub -arch=win32 ?ReCreateException@Exception@Platform@@SAP$AAV12@H@Z @ stub -arch=win64 ?ReCreateException@Exception@Platform@@SAPE$AAV12@H@Z @ stub -arch=win32 ?ReferenceEquals@Object@Platform@@SA_NP$AAV12@0@Z @@ -221,8 +221,8 @@ @ stub -arch=i386 ?TerminateModule@Details@Platform@@YG_NPAVModuleBase@1WRL@Microsoft@@@Z @ stub -arch=arm ?TerminateModule@Details@Platform@@YA_NPAVModuleBase@1WRL@Microsoft@@@Z @ stub -arch=win64 ?TerminateModule@Details@Platform@@YA_NPEAVModuleBase@1WRL@Microsoft@@@Z -@ cdecl -arch=win32 ??0Exception@Platform@@Q$AAA@HP$AAVString@1@@Z(ptr long ptr) platform_Exception_hstring_ctor -@ cdecl -arch=win64 ??0Exception@Platform@@QE$AAA@HPE$AAVString@1@@Z(ptr long ptr) platform_Exception_hstring_ctor +@ cdecl -arch=win32 ??0Exception@Platform@@Q$AAA@HP$AAVString@1@@Z(ptr long ptr) Exception_hstring_ctor +@ cdecl -arch=win64 ??0Exception@Platform@@QE$AAA@HPE$AAVString@1@@Z(ptr long ptr) Exception_hstring_ctor @ stub -arch=win32 ?ToInt32@IntPtr@Platform@@QAAHXZ @ stub -arch=win64 ?ToInt32@IntPtr@Platform@@QEAAHXZ @ stub -arch=win32 ?ToString@Attribute@Metadata@Platform@@Q$AAAP$AAVString@3@XZ @@ -245,8 +245,8 @@ @ stub -arch=win64 ?ToString@STAThreadAttribute@Platform@@QE$AAAPE$AAVString@2@XZ @ stub -arch=win32 ?<Dispose>@String@Platform@@U$AAAXXZ @ stub -arch=win64 ?<Dispose>@String@Platform@@UE$AAAXXZ -@ cdecl -arch=win32 ??0FailureException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_FailureException_hstring_ctor -@ cdecl -arch=win64 ??0FailureException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_FailureException_hstring_ctor +@ cdecl -arch=win32 ??0FailureException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) FailureException_hstring_ctor +@ cdecl -arch=win64 ??0FailureException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) FailureException_hstring_ctor @ cdecl -arch=win32 ?ToString@Type@Platform@@U$AAAP$AAVString@2@XZ(ptr) platform_type_ToString @ cdecl -arch=win64 ?ToString@Type@Platform@@UE$AAAPE$AAVString@2@XZ(ptr) platform_type_ToString @ stub -arch=win32 ?ToString@ValueType@Platform@@Q$AAAP$AAVString@2@XZ @@ -267,8 +267,8 @@ @ stub -arch=win64 ?ToString@int8@default@@QEAAPE$AAVString@Platform@@XZ @ stub -arch=win32 ?ToString@uint16@default@@QAAP$AAVString@Platform@@XZ @ stub -arch=win64 ?ToString@uint16@default@@QEAAPE$AAVString@Platform@@XZ -@ cdecl -arch=win32 ??0FailureException@Platform@@Q$AAA@XZ(ptr) platform_FailureException_ctor -@ cdecl -arch=win64 ??0FailureException@Platform@@QE$AAA@XZ(ptr) platform_FailureException_ctor +@ cdecl -arch=win32 ??0FailureException@Platform@@Q$AAA@XZ(ptr) FailureException_ctor +@ cdecl -arch=win64 ??0FailureException@Platform@@QE$AAA@XZ(ptr) FailureException_ctor @ stub -arch=win32 ?ToString@uint32@default@@QAAP$AAVString@Platform@@XZ @ stub -arch=win64 ?ToString@uint32@default@@QEAAPE$AAVString@Platform@@XZ @ stub -arch=win32 ?ToString@uint64@default@@QAAP$AAVString@Platform@@XZ @@ -355,10 +355,10 @@ @ cdecl -arch=win64 ?get@FullName@Type@Platform@@QE$AAAPE$AAVString@3@XZ(ptr) platform_type_get_FullName @ stub -arch=win32 ?get@HasInverse@Matrix3D@Media3D@Media@Xaml@UI@Windows@@QAA_NXZ @ stub -arch=win64 ?get@HasInverse@Matrix3D@Media3D@Media@Xaml@UI@Windows@@QEAA_NXZ -@ cdecl -arch=win32 ??0InvalidArgumentException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_InvalidArgumentException_hstring_ctor -@ cdecl -arch=win64 ??0InvalidArgumentException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_InvalidArgumentException_hstring_ctor -@ cdecl -arch=win32 ?get@Message@Exception@Platform@@Q$AAAP$AAVString@3@XZ(ptr) platform_exception_get_Message -@ cdecl -arch=win64 ?get@Message@Exception@Platform@@QE$AAAPE$AAVString@3@XZ(ptr) platform_exception_get_Message +@ cdecl -arch=win32 ??0InvalidArgumentException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) InvalidArgumentException_hstring_ctor +@ cdecl -arch=win64 ??0InvalidArgumentException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) InvalidArgumentException_hstring_ctor +@ cdecl -arch=win32 ?get@Message@Exception@Platform@@Q$AAAP$AAVString@3@XZ(ptr) Exception_get_Message +@ cdecl -arch=win64 ?get@Message@Exception@Platform@@QE$AAAPE$AAVString@3@XZ(ptr) Exception_get_Message @ stub ?get@ObjectCount@Heap@Details@Platform@@SAHXZ @ stub -arch=win32 ?get@Right@Rect@Foundation@Windows@@QAAMXZ @ stub -arch=win64 ?get@Right@Rect@Foundation@Windows@@QEAAMXZ @@ -366,46 +366,46 @@ @ stub ?set@BreakOnAllocationId@Heap@Details@Platform@@SAXH@Z @ stub ?set@BreakOnFreeId@Heap@Details@Platform@@SAXH@Z @ stub ?set@TrackingLevel@Heap@Details@Platform@@SAXW4HeapAllocationTrackingLevel@34@@Z -@ cdecl -arch=win32 ??0InvalidArgumentException@Platform@@Q$AAA@XZ(ptr) platform_InvalidArgumentException_ctor -@ cdecl -arch=win64 ??0InvalidArgumentException@Platform@@QE$AAA@XZ(ptr) platform_InvalidArgumentException_ctor -@ cdecl -arch=win32 ??0InvalidCastException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_InvalidCastException_hstring_ctor -@ cdecl -arch=win64 ??0InvalidCastException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_InvalidCastException_hstring_ctor -@ cdecl -arch=win32 ??0InvalidCastException@Platform@@Q$AAA@XZ(ptr) platform_InvalidCastException_ctor -@ cdecl -arch=win64 ??0InvalidCastException@Platform@@QE$AAA@XZ(ptr) platform_InvalidCastException_ctor +@ cdecl -arch=win32 ??0InvalidArgumentException@Platform@@Q$AAA@XZ(ptr) InvalidArgumentException_ctor +@ cdecl -arch=win64 ??0InvalidArgumentException@Platform@@QE$AAA@XZ(ptr) InvalidArgumentException_ctor +@ cdecl -arch=win32 ??0InvalidCastException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) InvalidCastException_hstring_ctor +@ cdecl -arch=win64 ??0InvalidCastException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) InvalidCastException_hstring_ctor +@ cdecl -arch=win32 ??0InvalidCastException@Platform@@Q$AAA@XZ(ptr) InvalidCastException_ctor +@ cdecl -arch=win64 ??0InvalidCastException@Platform@@QE$AAA@XZ(ptr) InvalidCastException_ctor @ stub -arch=win32 ??0MTAThreadAttribute@Platform@@Q$AAA@XZ @ stub -arch=win64 ??0MTAThreadAttribute@Platform@@QE$AAA@XZ @ stub -arch=win32 ?<Dispose>@Type@Platform@@U$AAAXXZ @ stub -arch=win64 ?<Dispose>@Type@Platform@@UE$AAAXXZ -@ cdecl -arch=win32 ??0NotImplementedException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_NotImplementedException_hstring_ctor -@ cdecl -arch=win64 ??0NotImplementedException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_NotImplementedException_hstring_ctor -@ cdecl -arch=win32 ??0NotImplementedException@Platform@@Q$AAA@XZ(ptr) platform_NotImplementedException_ctor -@ cdecl -arch=win64 ??0NotImplementedException@Platform@@QE$AAA@XZ(ptr) platform_NotImplementedException_ctor -@ cdecl -arch=win32 ??0NullReferenceException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_NullReferenceException_hstring_ctor -@ cdecl -arch=win64 ??0NullReferenceException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_NullReferenceException_hstring_ctor -@ cdecl -arch=win32 ??0NullReferenceException@Platform@@Q$AAA@XZ(ptr) platform_NullReferenceException_ctor -@ cdecl -arch=win64 ??0NullReferenceException@Platform@@QE$AAA@XZ(ptr) platform_NullReferenceException_ctor +@ cdecl -arch=win32 ??0NotImplementedException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) NotImplementedException_hstring_ctor +@ cdecl -arch=win64 ??0NotImplementedException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) NotImplementedException_hstring_ctor +@ cdecl -arch=win32 ??0NotImplementedException@Platform@@Q$AAA@XZ(ptr) NotImplementedException_ctor +@ cdecl -arch=win64 ??0NotImplementedException@Platform@@QE$AAA@XZ(ptr) NotImplementedException_ctor +@ cdecl -arch=win32 ??0NullReferenceException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) NullReferenceException_hstring_ctor +@ cdecl -arch=win64 ??0NullReferenceException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) NullReferenceException_hstring_ctor +@ cdecl -arch=win32 ??0NullReferenceException@Platform@@Q$AAA@XZ(ptr) NullReferenceException_ctor +@ cdecl -arch=win64 ??0NullReferenceException@Platform@@QE$AAA@XZ(ptr) NullReferenceException_ctor @ stub -arch=win32 ??0Object@Platform@@Q$AAA@XZ @ stub -arch=win64 ??0Object@Platform@@QE$AAA@XZ -@ cdecl -arch=win32 ??0ObjectDisposedException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_ObjectDisposedException_hstring_ctor -@ cdecl -arch=win64 ??0ObjectDisposedException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_ObjectDisposedException_hstring_ctor -@ cdecl -arch=win32 ??0ObjectDisposedException@Platform@@Q$AAA@XZ(ptr) platform_ObjectDisposedException_ctor -@ cdecl -arch=win64 ??0ObjectDisposedException@Platform@@QE$AAA@XZ(ptr) platform_ObjectDisposedException_ctor +@ cdecl -arch=win32 ??0ObjectDisposedException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) ObjectDisposedException_hstring_ctor +@ cdecl -arch=win64 ??0ObjectDisposedException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) ObjectDisposedException_hstring_ctor +@ cdecl -arch=win32 ??0ObjectDisposedException@Platform@@Q$AAA@XZ(ptr) ObjectDisposedException_ctor +@ cdecl -arch=win64 ??0ObjectDisposedException@Platform@@QE$AAA@XZ(ptr) ObjectDisposedException_ctor @ stub -arch=win32 ??0OnePhaseConstructedAttribute@CompilerServices@Runtime@Platform@@Q$AAA@XZ @ stub -arch=win64 ??0OnePhaseConstructedAttribute@CompilerServices@Runtime@Platform@@QE$AAA@XZ -@ cdecl -arch=win32 ??0OperationCanceledException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_OperationCanceledException_hstring_ctor -@ cdecl -arch=win64 ??0OperationCanceledException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_OperationCanceledException_hstring_ctor -@ cdecl -arch=win32 ??0OperationCanceledException@Platform@@Q$AAA@XZ(ptr) platform_OperationCanceledException_ctor -@ cdecl -arch=win64 ??0OperationCanceledException@Platform@@QE$AAA@XZ(ptr) platform_OperationCanceledException_ctor -@ cdecl -arch=win32 ??0AccessDeniedException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_AccessDeniedException_hstring_ctor -@ cdecl -arch=win64 ??0AccessDeniedException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_AccessDeniedException_hstring_ctor -@ cdecl -arch=win32 ??0OutOfBoundsException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_OutOfBoundsException_hstring_ctor -@ cdecl -arch=win64 ??0OutOfBoundsException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_OutOfBoundsException_hstring_ctor -@ cdecl -arch=win32 ??0OutOfBoundsException@Platform@@Q$AAA@XZ(ptr) platform_OutOfBoundsException_ctor -@ cdecl -arch=win64 ??0OutOfBoundsException@Platform@@QE$AAA@XZ(ptr) platform_OutOfBoundsException_ctor -@ cdecl -arch=win32 ??0OutOfMemoryException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_OutOfMemoryException_hstring_ctor -@ cdecl -arch=win64 ??0OutOfMemoryException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_OutOfMemoryException_hstring_ctor -@ cdecl -arch=win32 ??0OutOfMemoryException@Platform@@Q$AAA@XZ(ptr) platform_OutOfMemoryException_ctor -@ cdecl -arch=win64 ??0OutOfMemoryException@Platform@@QE$AAA@XZ(ptr) platform_OutOfMemoryException_ctor +@ cdecl -arch=win32 ??0OperationCanceledException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) OperationCanceledException_hstring_ctor +@ cdecl -arch=win64 ??0OperationCanceledException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) OperationCanceledException_hstring_ctor +@ cdecl -arch=win32 ??0OperationCanceledException@Platform@@Q$AAA@XZ(ptr) OperationCanceledException_ctor +@ cdecl -arch=win64 ??0OperationCanceledException@Platform@@QE$AAA@XZ(ptr) OperationCanceledException_ctor +@ cdecl -arch=win32 ??0AccessDeniedException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) AccessDeniedException_hstring_ctor +@ cdecl -arch=win64 ??0AccessDeniedException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) AccessDeniedException_hstring_ctor +@ cdecl -arch=win32 ??0OutOfBoundsException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) OutOfBoundsException_hstring_ctor +@ cdecl -arch=win64 ??0OutOfBoundsException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) OutOfBoundsException_hstring_ctor +@ cdecl -arch=win32 ??0OutOfBoundsException@Platform@@Q$AAA@XZ(ptr) OutOfBoundsException_ctor +@ cdecl -arch=win64 ??0OutOfBoundsException@Platform@@QE$AAA@XZ(ptr) OutOfBoundsException_ctor +@ cdecl -arch=win32 ??0OutOfMemoryException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) OutOfMemoryException_hstring_ctor +@ cdecl -arch=win64 ??0OutOfMemoryException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) OutOfMemoryException_hstring_ctor +@ cdecl -arch=win32 ??0OutOfMemoryException@Platform@@Q$AAA@XZ(ptr) OutOfMemoryException_ctor +@ cdecl -arch=win64 ??0OutOfMemoryException@Platform@@QE$AAA@XZ(ptr) OutOfMemoryException_ctor @ stub -arch=win32 ??0Rect@Foundation@Windows@@QAA@VPoint@12@0@Z @ stub -arch=win64 ??0Rect@Foundation@Windows@@QEAA@VPoint@12@0@Z @ stub -arch=win32 ??0Rect@Foundation@Windows@@QAA@VPoint@12@VSize@12@@Z @@ -418,8 +418,8 @@ @ stub -arch=win64 ??0SizeT@Platform@@QEAA@H@Z @ stub -arch=win32 ??0SizeT@Platform@@QAA@PAX@Z @ stub -arch=win64 ??0SizeT@Platform@@QEAA@PEAX@Z -@ cdecl -arch=win32 ??0AccessDeniedException@Platform@@Q$AAA@XZ(ptr) platform_AccessDeniedException_ctor -@ cdecl -arch=win64 ??0AccessDeniedException@Platform@@QE$AAA@XZ(ptr) platform_AccessDeniedException_ctor +@ cdecl -arch=win32 ??0AccessDeniedException@Platform@@Q$AAA@XZ(ptr) AccessDeniedException_ctor +@ cdecl -arch=win64 ??0AccessDeniedException@Platform@@QE$AAA@XZ(ptr) AccessDeniedException_ctor @ stub -arch=win32 ??0Type@Platform@@Q$AAA@P$AAVObject@1@@Z @ stub -arch=win64 ??0Type@Platform@@QE$AAA@PE$AAVObject@1@@Z @ stub -arch=win32 ??0Type@Platform@@Q$AAA@VIntPtr@1@@Z @@ -428,10 +428,10 @@ @ stub -arch=win64 ??0Type@Platform@@QE$AAA@VTypeName@Interop@Xaml@UI@Windows@@@Z @ stub -arch=win32 ??0ValueType@Platform@@Q$AAA@XZ @ stub -arch=win64 ??0ValueType@Platform@@QE$AAA@XZ -@ cdecl -arch=win32 ??0WrongThreadException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) platform_WrongThreadException_hstring_ctor -@ cdecl -arch=win64 ??0WrongThreadException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) platform_WrongThreadException_hstring_ctor -@ cdecl -arch=win32 ??0WrongThreadException@Platform@@Q$AAA@XZ(ptr) platform_WrongThreadException_ctor -@ cdecl -arch=win64 ??0WrongThreadException@Platform@@QE$AAA@XZ(ptr) platform_WrongThreadException_ctor +@ cdecl -arch=win32 ??0WrongThreadException@Platform@@Q$AAA@P$AAVString@1@@Z(ptr ptr) WrongThreadException_hstring_ctor +@ cdecl -arch=win64 ??0WrongThreadException@Platform@@QE$AAA@PE$AAVString@1@@Z(ptr ptr) WrongThreadException_hstring_ctor +@ cdecl -arch=win32 ??0WrongThreadException@Platform@@Q$AAA@XZ(ptr) WrongThreadException_ctor +@ cdecl -arch=win64 ??0WrongThreadException@Platform@@QE$AAA@XZ(ptr) WrongThreadException_ctor @ stub -arch=win32 ??0char16@default@@QAA@_W@Z @ stub -arch=win64 ??0char16@default@@QEAA@_W@Z @ stub -arch=win32 ??0float32@default@@QAA@M@Z @@ -476,8 +476,8 @@ @ stub ??PDuration@Xaml@UI@Windows@@SA_NV0123@0@Z @ stub -arch=win32 ?AlignedAllocate@Heap@Details@Platform@@SAPAXII@Z @ stub -arch=win64 ?AlignedAllocate@Heap@Details@Platform@@SAPEAX_K00@Z -@ cdecl -arch=win32 ??0COMException@Platform@@Q$AAA@H@Z(ptr long) platform_COMException_ctor -@ cdecl -arch=win64 ??0COMException@Platform@@QE$AAA@H@Z(ptr long) platform_COMException_ctor +@ cdecl -arch=win32 ??0COMException@Platform@@Q$AAA@H@Z(ptr long) COMException_ctor +@ cdecl -arch=win64 ??0COMException@Platform@@QE$AAA@H@Z(ptr long) COMException_ctor @ stub -arch=win32 ?AlignedAllocate@Heap@Details@Platform@@SAPAXIII@Z @ stub -arch=win64 ?AlignedAllocate@Heap@Details@Platform@@SAPEAX_K0@Z @ stub -arch=win32 ?AlignedAllocateException@Heap@Details@Platform@@SAPAXII@Z @@ -497,8 +497,8 @@ @ cdecl -arch=win32 ?AllocateException@Heap@Details@Platform@@SAPAXII@Z(long long) AllocateExceptionWithWeakRef @ cdecl -arch=win64 ?AllocateException@Heap@Details@Platform@@SAPEAX_K@Z(long) AllocateException @ stub ?Compare@Duration@Xaml@UI@Windows@@SAHV1234@0@Z -@ cdecl -arch=win32 ??0COMException@Platform@@Q$AAA@HP$AAVString@1@@Z(ptr long ptr) platform_COMException_hstring_ctor -@ cdecl -arch=win64 ??0COMException@Platform@@QE$AAA@HPE$AAVString@1@@Z(ptr long ptr) platform_COMException_hstring_ctor +@ cdecl -arch=win32 ??0COMException@Platform@@Q$AAA@HP$AAVString@1@@Z(ptr long ptr) COMException_hstring_ctor +@ cdecl -arch=win64 ??0COMException@Platform@@QE$AAA@HPE$AAVString@1@@Z(ptr long ptr) COMException_hstring_ctor @ stub -arch=win32 ?Contains@Rect@Foundation@Windows@@QAA_NVPoint@23@@Z @ stub -arch=win64 ?Contains@Rect@Foundation@Windows@@QEAA_NVPoint@23@@Z @ cdecl -arch=win32 ?CreateException@Exception@Platform@@SAP$AAV12@H@Z(long) CreateException
From: Vibhav Pant vibhavp@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@Platform@@" +#else +#define EXCEPTION_REF_NAME(name) ".P$AAV" #name "Exception@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@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@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; }
From: Piotr Caban piotr@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
From: Vibhav Pant vibhavp@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; }
From: Vibhav Pant vibhavp@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@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@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); }
From: Vibhav Pant vibhavp@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@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@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 \
From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/except.c | 85 +++++++++++++++++++++++-------- dlls/vccorlib140/private.h | 6 ++- dlls/vccorlib140/tests/vccorlib.c | 11 ++-- 3 files changed, 70 insertions(+), 32 deletions(-)
diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index e57b37bad32..d00f35c71f1 100644 --- a/dlls/vccorlib140/except.c +++ b/dlls/vccorlib140/except.c @@ -32,6 +32,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(vccorlib);
+extern void WINAPI DECLSPEC_NORETURN _CxxThrowException(void *, const cxx_exception_type *); + #ifdef _WIN64 #define EXCEPTION_REF_NAME(name) ".PE$AAV" #name "Exception@Platform@@" #else @@ -77,23 +79,6 @@ struct Exception IUnknown *marshal; };
-void *__cdecl CreateExceptionWithMessage(HRESULT hr, HSTRING msg) -{ - FIXME("(%#lx, %s): stub!\n", hr, debugstr_hstring(msg)); - return NULL; -} - -void *__cdecl CreateException(HRESULT hr) -{ - FIXME("(%#lx): stub!\n", hr); - return NULL; -} - -void WINAPI __abi_WinRTraiseCOMException(HRESULT hr) -{ - FIXME("(%#lx): stub!\n", hr); -} - #define WINRT_EXCEPTIONS \ WINRT_EXCEPTION(AccessDenied, E_ACCESSDENIED) \ WINRT_EXCEPTION(ChangedState, E_CHANGED_STATE) \ @@ -407,15 +392,71 @@ struct Exception *__cdecl COMException_hstring_ctor(struct Exception *this, HRES this->IClosable_iface.lpVtbl = &name##Exception_Closable_vtable.vtable; \ this->inner.exception_type = &name##Exception_ref_exception_type; \ return this; \ - } \ - \ - void WINAPI __abi_WinRTraise##name##Exception(void) \ - { \ - FIXME("(): stub!\n"); \ } WINRT_EXCEPTIONS #undef WINRT_EXCEPTION
+struct Exception *__cdecl CreateExceptionWithMessage(HRESULT code, HSTRING msg) +{ + struct Exception *ret; + + TRACE("(%#lx, %s)\n", code, debugstr_hstring(msg)); + + ret = AllocateExceptionWithWeakRef(offsetof(struct Exception, control_block), sizeof(*ret)); + +#define WINRT_EXCEPTION(name, h) \ + case (h): \ + name##Exception_hstring_ctor(ret, msg); \ + break; + + switch (code) + { + WINRT_EXCEPTIONS; +#undef WINRT_EXCEPTION + default: + COMException_hstring_ctor(ret, code, msg); + break; + } + + return ret; +} + +struct Exception *__cdecl CreateException(HRESULT hr) +{ + TRACE("(%#lx)\n", hr); + return CreateExceptionWithMessage(hr, NULL); +} + +static void DECLSPEC_NORETURN throw_exception(struct Exception *excp, const cxx_exception_type *type) + { + /* Thrown exceptions have a refcount of 2. */ + IInspectable_AddRef(&excp->IInspectable_iface); + _CxxThrowException(&excp, type); +} + +#define WINRT_EXCEPTION(name, hr) \ + void WINAPI DECLSPEC_NORETURN __abi_WinRTraise##name##Exception(void) \ + { \ + FIXME("(): semi-stub!\n"); \ + throw_exception(CreateException(hr), &name##Exception_ref_exception_type); \ + } +WINRT_EXCEPTIONS +#undef WINRT_EXCEPTION + +void WINAPI DECLSPEC_NORETURN __abi_WinRTraiseCOMException(HRESULT hr) +{ + FIXME("(%#lx): semi-stub!\n", hr); + + switch (hr) + { +#define WINRT_EXCEPTION(name, code) case (code): __abi_WinRTraise##name##Exception(); + WINRT_EXCEPTIONS; +#undef WINRT_EXCEPTION + default: + throw_exception(CreateException(hr), &COMException_ref_exception_type); + } +} + HSTRING __cdecl Exception_get_Message(struct Exception *this) { HSTRING msg = NULL; diff --git a/dlls/vccorlib140/private.h b/dlls/vccorlib140/private.h index 18410955f05..f5cb3fc69fb 100644 --- a/dlls/vccorlib140/private.h +++ b/dlls/vccorlib140/private.h @@ -41,11 +41,13 @@ struct control_block #endif };
+void *__cdecl AllocateExceptionWithWeakRef(ptrdiff_t, size_t); void __cdecl FreeException(void *);
void init_exception(void *); -void WINAPI __abi_WinRTraiseInvalidArgumentException(void); -void WINAPI __abi_WinRTraiseOutOfMemoryException(void); +void WINAPI DECLSPEC_NORETURN __abi_WinRTraiseCOMException(HRESULT); +void WINAPI DECLSPEC_NORETURN __abi_WinRTraiseInvalidArgumentException(void); +void WINAPI DECLSPEC_NORETURN __abi_WinRTraiseOutOfMemoryException(void);
#define COM_VTABLE_RTTI_START(iface, type) \ static const struct \ diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index 826a55a76e8..c4f669d8190 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -1373,17 +1373,12 @@ static void test_exceptions(void)
cur_test = &test_cases[i]; obj = pCreateException(cur_test->hr); - todo_wine ok(obj != NULL, "got obj %p\n", obj); - if (!obj) - { - winetest_pop_context(); - continue; - } + ok(obj != NULL, "got obj %p\n", obj);
inspectable = (IInspectable *)obj; /* Verify that the IMarshal field is lazily-initialized. */ ok((ULONG_PTR)obj->marshal == UINTPTR_MAX, "got marshal %p\n", obj->marshal); - todo_wine check_interface(inspectable, &IID_IMarshal); + check_interface(inspectable, &IID_IMarshal); ok(obj->marshal != NULL && (ULONG_PTR)obj->marshal != UINTPTR_MAX, "got marshal %p\n", obj->marshal);
test_interface_layout(obj, &IID_IUnknown, &obj->IInspectable_iface); @@ -1514,7 +1509,7 @@ static void test_exceptions(void)
cxx_info = (cxx_type_info *)(base + type_info_table->info[j]); if (j == type_info_table->count - 1) - ok(cxx_info->flags == CLASS_IS_SIMPLE_TYPE, "got flags %u\n", cxx_info->flags); + todo_wine ok(cxx_info->flags == CLASS_IS_SIMPLE_TYPE, "got flags %u\n", cxx_info->flags); else ok(cxx_info->flags == (CLASS_IS_SIMPLE_TYPE | CLASS_IS_IUNKNOWN), "got flags %u\n", cxx_info->flags); ok(cxx_info->size == sizeof(void *), "got size %u\n", cxx_info->size);
From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/except.c | 5 ++--- dlls/vccorlib140/vccorlib.c | 17 +++++------------ 2 files changed, 7 insertions(+), 15 deletions(-)
diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index d00f35c71f1..f9b8ea7bbd5 100644 --- a/dlls/vccorlib140/except.c +++ b/dlls/vccorlib140/except.c @@ -428,9 +428,8 @@ struct Exception *__cdecl CreateException(HRESULT hr) }
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); +{ + /* TODO: figure out what native does with refcount */ _CxxThrowException(&excp, type); }
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; }
From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/except.c | 23 +++++++++++++++++++++++ dlls/vccorlib140/vccorlib140.spec | 5 ++--- 2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index f9b8ea7bbd5..9ed092b86a4 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@Platform@@" @@ -500,3 +501,25 @@ 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@Platform@@AEBU__abi_type_descriptor@@@Z(ptr) __abi_make_type_id @ stub -arch=win32 ??0IntPtr@Platform@@QAA@PAX@Z @ stub -arch=win64 ??0IntPtr@Platform@@QEAA@PEAX@Z -@ stub -arch=i386 ?__abi_translateCurrentException@@YGJ_N@Z -@ stub -arch=arm ?__abi_translateCurrentException@@YAJ_N@Z -@ stub -arch=win64 ?__abi_translateCurrentException@@YAJ_N@Z +@ stdcall -arch=i386 ?__abi_translateCurrentException@@YGJ_N@Z(long) __abi_translateCurrentException +@ stdcall -arch=arm,win64 ?__abi_translateCurrentException@@YAJ_N@Z(long) __abi_translateCurrentException @ stub -arch=i386 ?__getActivationFactoryByHSTRING@@YGJPAUHSTRING__@@AAVGuid@Platform@@PAPAX@Z @ stub -arch=arm ?__getActivationFactoryByHSTRING@@YAJPAUHSTRING__@@AAVGuid@Platform@@PAPAX@Z @ stub -arch=win64 ?__getActivationFactoryByHSTRING@@YAJPEAUHSTRING__@@AEAVGuid@Platform@@PEAPEAX@Z
I've pushed a version that removes additional AddRef and adds TODO comment in the code. While object refcount is different in seh filter there should be no leaks with this approach.
This merge request was approved by Piotr Caban.
Vibhav Pant (@vibhavp) commented about dlls/vccorlib140/except.c:
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)
Do we not need to wrap this and `CreateExceptionWithMessage` inside a `__FINALLY_CTX` to clean up any partial allocations in case of an exception being thrown? For instance, `CreateExcception(S_OK)` throws an `InvalidArgumentException` from the constructor, wouldn't that leak the allocation from `AllocateExceptionWithWeakRef`?
On Mon Nov 3 13:14:16 2025 +0000, Vibhav Pant wrote:
Do we not need to wrap this and `CreateExceptionWithMessage` inside a `__FINALLY_CTX` to clean up any partial allocations in case of an exception being thrown? For instance, `CreateExcception(S_OK)` throws an `InvalidArgumentException` inside the constructor, wouldn't that leak the allocation from `AllocateExceptionWithWeakRef`?
Yes, it's leaking on error paths. It's better to release the buffers before throwing exception instead of using __FINALLY_CTX. Could you please update the code?
On Mon Nov 3 13:26:07 2025 +0000, Piotr Caban wrote:
Yes, it's leaking on error paths. It's better to release the buffers before throwing exception instead of using __FINALLY_CTX. Could you please update the code?
Sorry, you will need to use __FINALLY_CTX to avoid leaks in this case.
On Mon Nov 3 11:24:04 2025 +0000, Piotr Caban wrote:
I think it would be best to go with first patch from !9351 and removing AddRef from throw for now.
I have also created !9352 related to WinRT exception leaks.