The `IPrintable` interface seems to just be an alias around `IStringable` with a different IID.
From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/tests/vccorlib.c | 341 ++++++++++++++++++++++++++++-- dlls/vccorlib140/vccorlib.c | 6 + dlls/vccorlib140/vccorlib140.spec | 6 +- 3 files changed, 338 insertions(+), 15 deletions(-)
diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index a9ab0e9c1f4..53fd574dcc9 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -165,6 +165,7 @@ WINRT_EXCEPTIONS #undef WINRT_EXCEPTION static IWeakReference *(WINAPI *p_GetWeakReference)(IUnknown *); static IUnknown *(WINAPI *p_ResolveWeakReference)(const GUID *, IWeakReference **); +static void *(WINAPI *p__abi_ObjectToString)(void *, bool stringable);
static void *(__cdecl *p__RTtypeid)(const void *); static const char *(__thiscall *p_type_info_name)(void *); @@ -236,6 +237,8 @@ static BOOL init(void) "?GetWeakReference@Details@Platform@@YAPAU__abi_IUnknown@@Q$ADVObject@2@@Z"); p_ResolveWeakReference = (void *)GetProcAddress(hmod, "?ResolveWeakReference@Details@Platform@@YAP$AAVObject@2@ABU_GUID@@PAPAU__abi_IUnknown@@@Z"); + p__abi_ObjectToString = (void *)GetProcAddress(hmod, + "?__abi_ObjectToString@__abi_details@@YAP$AAVString@Platform@@P$AAVObject@3@_N@Z");
p_type_info_name = (void *)GetProcAddress(msvcrt, "?name@type_info@@QBAPBDXZ"); p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name@type_info@@QBAPBDXZ"); @@ -290,6 +293,8 @@ static BOOL init(void) "?GetWeakReference@Details@Platform@@YAPEAU__abi_IUnknown@@QE$ADVObject@2@@Z"); p_ResolveWeakReference = (void *)GetProcAddress(hmod, "?ResolveWeakReference@Details@Platform@@YAPE$AAVObject@2@AEBU_GUID@@PEAPEAU__abi_IUnknown@@@Z"); + p__abi_ObjectToString = (void *)GetProcAddress(hmod, + "?__abi_ObjectToString@__abi_details@@YAPE$AAVString@Platform@@PE$AAVObject@3@_N@Z");
p_type_info_name = (void *)GetProcAddress(msvcrt, "?name@type_info@@QEBAPEBDXZ"); p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name@type_info@@QEBAPEBDXZ"); @@ -343,6 +348,8 @@ static BOOL init(void) "?GetWeakReference@Details@Platform@@YGPAU__abi_IUnknown@@Q$ADVObject@2@@Z"); p_ResolveWeakReference = (void *)GetProcAddress(hmod, "?ResolveWeakReference@Details@Platform@@YGP$AAVObject@2@ABU_GUID@@PAPAU__abi_IUnknown@@@Z"); + p__abi_ObjectToString = (void *)GetProcAddress(hmod, + "?__abi_ObjectToString@__abi_details@@YGP$AAVString@Platform@@P$AAVObject@3@_N@Z");
p_type_info_name = (void *)GetProcAddress(msvcrt, "?name@type_info@@QBEPBDXZ"); p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name@type_info@@QBEPBDXZ"); @@ -380,6 +387,7 @@ static BOOL init(void) #undef WINRT_EXCEPTION ok(p_GetWeakReference != NULL, "GetWeakReference not available.\n"); ok(p_ResolveWeakReference != NULL, "ResolveWeakReference is not available.\n"); + ok(p__abi_ObjectToString != NULL, "__abi_ObjectToString not available.\n");
ok(p_type_info_name != NULL, "type_info::name not available\n"); ok(p_type_info_raw_name != NULL, "type_info::raw_name not available\n"); @@ -1081,6 +1089,17 @@ static void test___abi_make_type_id(void) ok(buf && !wcscmp(buf, L"foo"), "got buf %s != %s\n", debugstr_w(buf), debugstr_w(L"foo")); WindowsDeleteString(str);
+ str = p__abi_ObjectToString(type_obj, FALSE); + buf = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(buf && !wcscmp(buf, L"Platform.Type"), "got buf %s != %s\n", debugstr_w(buf), + debugstr_w(L"Platform.Type")); + WindowsDeleteString(str); + + str = p__abi_ObjectToString(type_obj, TRUE); + buf = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(buf && !wcscmp(buf, L"foo"), "got buf %s != %s\n", debugstr_w(buf), debugstr_w(L"foo")); + WindowsDeleteString(str); + type_obj2 = p___abi_make_type_id(&desc); ok(type_obj2 != NULL, "got type_obj %p\n", type_obj); ok(type_obj2 != type_obj, "got type_obj2 %p\n", type_obj2); @@ -1201,24 +1220,26 @@ static void test_CreateValue(void) union value value; PropertyType exp_winrt_type; SIZE_T size; + const WCHAR *exp_str; } test_cases[] = { - {TYPECODE_BOOLEAN, {.boolean = true}, PropertyType_Boolean, sizeof(boolean)}, - {TYPECODE_CHAR16, {.uint16 = 0xbeef}, PropertyType_Char16, sizeof(UINT16)}, - {TYPECODE_UINT8, {.uint8 = 0xbe}, PropertyType_UInt8, sizeof(UINT8)}, - {TYPECODE_INT16, {.uint16 = 0xbeef}, PropertyType_Int16, sizeof(INT16)}, - {TYPECODE_UINT16, {.uint16 = 0xbeef}, PropertyType_UInt16, sizeof(UINT16)}, - {TYPECODE_INT32, {.uint32 = 0xdeadbeef}, PropertyType_Int32, sizeof(INT32)}, - {TYPECODE_UINT32, {.uint32 = 0xdeadbeef}, PropertyType_UInt32, sizeof(UINT32)}, - {TYPECODE_INT64, {.uint64 = 0xdeadbeefdeadbeef}, PropertyType_Int64, sizeof(INT64)}, - {TYPECODE_UINT64, {.uint64 = 0xdeadbeefdeadbeef}, PropertyType_UInt64, sizeof(UINT64)}, - {TYPECODE_SINGLE, {.single = 2.71828}, PropertyType_Single, sizeof(FLOAT)}, - {TYPECODE_DOUBLE, {.dbl = 2.7182818284}, PropertyType_Double, sizeof(DOUBLE)}, + {TYPECODE_BOOLEAN, {.boolean = true}, PropertyType_Boolean, sizeof(boolean), L"true"}, + {TYPECODE_CHAR16, {.uint16 = 0xbeef}, PropertyType_Char16, sizeof(UINT16), L"\xbeef"}, + {TYPECODE_UINT8, {.uint8 = 0xbe}, PropertyType_UInt8, sizeof(UINT8), L"190"}, + {TYPECODE_INT16, {.uint16 = 0xbeef}, PropertyType_Int16, sizeof(INT16), L"-16657"}, + {TYPECODE_UINT16, {.uint16 = 0xbeef}, PropertyType_UInt16, sizeof(UINT16), L"48879"}, + {TYPECODE_INT32, {.uint32 = 0xdeadbeef}, PropertyType_Int32, sizeof(INT32), L"-559038737"}, + {TYPECODE_UINT32, {.uint32 = 0xdeadbeef}, PropertyType_UInt32, sizeof(UINT32), L"3735928559"}, + {TYPECODE_INT64, {.uint64 = 0xdeadbeefdeadbeef}, PropertyType_Int64, sizeof(INT64), L"-2401053088876216593"}, + {TYPECODE_UINT64, {.uint64 = 0xdeadbeefdeadbeef}, PropertyType_UInt64, sizeof(UINT64), L"16045690984833335023"}, + {TYPECODE_SINGLE, {.single = 2.71828}, PropertyType_Single, sizeof(FLOAT), L"2.71828"}, + {TYPECODE_SINGLE, {.single = 2.71828182}, PropertyType_Single, sizeof(FLOAT), L"2.71828"}, + {TYPECODE_DOUBLE, {.dbl = 2.7182818284}, PropertyType_Double, sizeof(DOUBLE), L"2.71828"}, {TYPECODE_DATETIME, {.time = {0xdeadbeefdeadbeef}}, PropertyType_DateTime, sizeof(DateTime)}, {TYPECODE_TIMESPAN, {.span = {0xdeadbeefdeadbeef}}, PropertyType_TimeSpan, sizeof(TimeSpan)}, {TYPECODE_POINT, {.point = {2.71828, 3.14159}}, PropertyType_Point, sizeof(Point)}, {TYPECODE_SIZE, {.size = {2.71828, 3.14159}}, PropertyType_Size, sizeof(Size)}, {TYPECODE_RECT, {.rect = {2.71828, 3.14159, 23.140692, 0.20787}}, PropertyType_Rect, sizeof(Rect)}, - {TYPECODE_GUID, {.guid = IID_IInspectable}, PropertyType_Guid, sizeof(GUID)}, + {TYPECODE_GUID, {.guid = IID_IInspectable}, PropertyType_Guid, sizeof(GUID), L"{af86e2e0-b12d-4c6a-9c5a-d7aa65101e90}"}, }; static const int null_typecodes[] = {0, 1, 2, 5,15, 17}; PropertyType type; @@ -1234,6 +1255,9 @@ static void test_CreateValue(void) for (i = 0; i < ARRAY_SIZE(test_cases); i++) { union value value = {0}; + const WCHAR *exp_str; + HSTRING name = NULL; + type = PropertyType_Empty;
winetest_push_context("test_cases[%lu]", i); @@ -1244,6 +1268,28 @@ static void test_CreateValue(void) check_interface(obj, &IID_IInspectable); check_interface(obj, &IID_IPropertyValue);
+ if (!(exp_str = test_cases[i].exp_str)) + { + /* For record-like values, __abi_ObjectToString returns the string from GetRuntimeClassName. */ + hr = IPropertyValue_GetRuntimeClassName(obj, &name); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + exp_str = WindowsGetStringRawBuffer(name, NULL); + } + + if (wcslen(exp_str)) + { + str = p__abi_ObjectToString(obj, FALSE); + buf = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(buf, exp_str), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(exp_str)); + WindowsDeleteString(str); + + str = p__abi_ObjectToString(obj, TRUE); + buf = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(buf, exp_str), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(exp_str)); + WindowsDeleteString(str); + } + if (name) WindowsDeleteString(name); + hr = IPropertyValue_get_Type(obj, &type); ok(hr == S_OK, "got hr %#lx\n", hr); ok(type == test_cases[i].exp_winrt_type, "got type %d != %d\n", type, test_cases[i].exp_winrt_type); @@ -1330,6 +1376,17 @@ static void test_CreateValue(void) buf = WindowsGetStringRawBuffer(str, NULL); ok(buf && !wcscmp(buf, L"foo"), "got buf %s\n", debugstr_w(buf)); WindowsDeleteString(str); + + str = p__abi_ObjectToString(obj, TRUE); + buf = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(buf, L"foo"), "got buf %s\n", debugstr_w(buf)); + WindowsDeleteString(str); + + str = p__abi_ObjectToString(obj, FALSE); + buf = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(buf, L"foo"), "got buf %s\n", debugstr_w(buf)); + WindowsDeleteString(str); + count = IPropertyValue_Release(obj); ok(count == 0, "got count %lu\n", count); } @@ -1525,6 +1582,13 @@ static void test_exceptions(void) debugstr_w(cur_test->exp_winrt_name)); WindowsDeleteString(str);
+ str = p__abi_ObjectToString(obj, FALSE); + ok(hr == S_OK, "got hr %#lx\n", hr); + bufW = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(cur_test->exp_winrt_name, bufW), "got str %s != %s\n", debugstr_hstring(str), + debugstr_w(cur_test->exp_winrt_name)); + WindowsDeleteString(str); + /* Verify control block fields. */ ok(!obj->control_block->is_inline, "got is_inline %d\n", obj->control_block->is_inline); ok(obj->control_block->ref_strong == 1, "got ref_strong %lu\n", obj->control_block->ref_strong); @@ -1580,6 +1644,10 @@ static void test_exceptions(void) { bufW = WindowsGetStringRawBuffer(str, NULL); ok(!wcscmp(bufW, buf), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(buf)); + + str = p__abi_ObjectToString(obj, TRUE); + bufW = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(bufW, buf), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(buf)); } WindowsDeleteString(str);
@@ -1672,6 +1740,18 @@ static void test_exceptions(void) ok(!ret, "got str %s != %s\n", debugstr_hstring(str), debugstr_hstring(msg)); WindowsDeleteString(str);
+ str = p__abi_ObjectToString(inspectable, FALSE); + bufW = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(cur_test->exp_winrt_name, bufW), "got str %s != %s\n", debugstr_hstring(str), + debugstr_w(cur_test->exp_winrt_name)); + WindowsDeleteString(str); + + str = p__abi_ObjectToString(inspectable, TRUE); + hr = WindowsCompareStringOrdinal(str, msg, &ret); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(!ret, "got str %s != %s\n", debugstr_hstring(str), debugstr_hstring(msg)); + WindowsDeleteString(str); + inner = (const struct exception_inner *)*(ULONG_PTR *)((ULONG_PTR)inspectable - sizeof(ULONG_PTR)); ok(inner->description == NULL, "got description %p\n", inner->description); ok(inner->restricted_desc != NULL, "got restricted_desc %p\n", inner->restricted_desc); @@ -1810,6 +1890,242 @@ static void test_exceptions(void) } }
+struct tostring_impl +{ + IUnknown IUnknown_iface; + IInspectable IInspectable_iface; + IStringable IStringable_iface; + bool have_inspectable; + bool have_stringable; + bool have_printable; + LONG ref; +}; + +static inline struct tostring_impl *impl_tostring_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct tostring_impl, IUnknown_iface); +} + +static HRESULT WINAPI tostring_QueryInterface(IUnknown *iface, const GUID *iid, void **out) +{ + struct tostring_impl *impl = impl_tostring_from_IUnknown(iface); + + if (IsEqualGUID(iid, &IID_IUnknown)) + { + *out = &impl->IUnknown_iface; + IUnknown_AddRef(iface); + return S_OK; + } + if (impl->have_inspectable && IsEqualGUID(iid, &IID_IInspectable)) + { + IInspectable_AddRef((*out = &impl->IInspectable_iface)); + return S_OK; + } + if (impl->have_stringable && IsEqualGUID(iid, &IID_IStringable)) + { + IStringable_AddRef((*out = &impl->IStringable_iface)); + return S_OK; + } + if (impl->have_printable && IsEqualGUID(iid, &IID_IPrintable)) + { + IStringable_AddRef((*out = &impl->IStringable_iface)); + return S_OK; + } + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI tostring_AddRef(IUnknown *iface) +{ + struct tostring_impl *impl = impl_tostring_from_IUnknown(iface); + + return InterlockedIncrement(&impl->ref); +} + +static ULONG WINAPI tostring_Release(IUnknown *iface) +{ + struct tostring_impl *impl = impl_tostring_from_IUnknown(iface); + + return InterlockedDecrement(&impl->ref); +} + +static const IUnknownVtbl tostring_unk_vtbl = +{ + tostring_QueryInterface, + tostring_AddRef, + tostring_Release +}; + +static inline struct tostring_impl *impl_tostring_from_IInspectable(IInspectable *iface) +{ + return CONTAINING_RECORD(iface, struct tostring_impl, IInspectable_iface); +} + +static HRESULT WINAPI tostring_inspectable_QueryInterface(IInspectable *iface, const GUID *iid, void **out) +{ + struct tostring_impl *impl = impl_tostring_from_IInspectable(iface); + return IUnknown_QueryInterface(&impl->IUnknown_iface, iid, out); +} + +static ULONG WINAPI tostring_inspectable_AddRef(IInspectable *iface) +{ + struct tostring_impl *impl = impl_tostring_from_IInspectable(iface); + return IUnknown_AddRef(&impl->IUnknown_iface); +} + +static ULONG WINAPI tostring_inspectable_Release(IInspectable *iface) +{ + struct tostring_impl *impl = impl_tostring_from_IInspectable(iface); + return IUnknown_Release(&impl->IUnknown_iface); +} + +static HRESULT WINAPI tostring_GetIIds(IInspectable *iface, ULONG *count, GUID **iids) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI tostring_GetRuntimeClassName(IInspectable *iface, HSTRING *name) +{ + const WCHAR *buf = L"ClassName.Foo"; + return WindowsCreateString(buf, wcslen(buf), name); +} + +static HRESULT WINAPI tostring_GetTrustLevel(IInspectable *iface, TrustLevel *level) +{ + return E_NOTIMPL; +} + +static const IInspectableVtbl tostring_inspectable_vtbl = +{ + /* IUnknown */ + tostring_inspectable_QueryInterface, + tostring_inspectable_AddRef, + tostring_inspectable_Release, + /* IInspectable */ + tostring_GetIIds, + tostring_GetRuntimeClassName, + tostring_GetTrustLevel +}; + +static inline struct tostring_impl *impl_tostring_from_IStringable(IStringable *iface) +{ + return CONTAINING_RECORD(iface, struct tostring_impl, IStringable_iface); +} + +static HRESULT WINAPI tostring_stringable_QueryInterface(IStringable *iface, const GUID *iid, void **out) +{ + struct tostring_impl *impl = impl_tostring_from_IStringable(iface); + return IUnknown_QueryInterface(&impl->IUnknown_iface, iid, out); +} + +static ULONG WINAPI tostring_stringable_AddRef(IStringable *iface) +{ + struct tostring_impl *impl = impl_tostring_from_IStringable(iface); + return IUnknown_AddRef(&impl->IUnknown_iface); +} + +static ULONG WINAPI tostring_stringable_Release(IStringable *iface) +{ + struct tostring_impl *impl = impl_tostring_from_IStringable(iface); + return IUnknown_Release(&impl->IUnknown_iface); +} + +static HRESULT WINAPI tostring_stringable_GetIIds(IStringable *iface, ULONG *count, GUID **iids) +{ + struct tostring_impl *impl = impl_tostring_from_IStringable(iface); + return IInspectable_GetIids(&impl->IInspectable_iface, count, iids); +} + +static HRESULT WINAPI tostring_stringable_GetRuntimeClassName(IStringable *iface, HSTRING *name) +{ + struct tostring_impl *impl = impl_tostring_from_IStringable(iface); + return IInspectable_GetRuntimeClassName(&impl->IInspectable_iface, name); +} + +static HRESULT WINAPI tostring_stringable_GetTrustLevel(IStringable *iface, TrustLevel *level) +{ + struct tostring_impl *impl = impl_tostring_from_IStringable(iface); + return IInspectable_GetTrustLevel(&impl->IInspectable_iface, level); +} + +static HRESULT WINAPI tostring_ToString(IStringable *iface, HSTRING *out) +{ + const WCHAR *buf = L"ToString.Foo"; + return WindowsCreateString(buf, wcslen(buf), out); +} + +static const IStringableVtbl tostring_stringable_vtbl = +{ + /* IUnknown */ + tostring_stringable_QueryInterface, + tostring_stringable_AddRef, + tostring_stringable_Release, + /* IInspectable */ + tostring_stringable_GetIIds, + tostring_stringable_GetRuntimeClassName, + tostring_stringable_GetTrustLevel, + /* IStringable */ + tostring_ToString, +}; + +static void test___abi_ObjectToString(void) +{ + static const WCHAR *class_name = L"ClassName.Foo", *stringable_val = L"ToString.Foo"; + struct tostring_impl impl = {{&tostring_unk_vtbl}, {&tostring_inspectable_vtbl}, {&tostring_stringable_vtbl}}; + const WCHAR *buf; + HSTRING str; + + str = p__abi_ObjectToString(NULL, TRUE); + ok(str == NULL, "got str %p\n", str); + str = p__abi_ObjectToString(NULL, FALSE); + ok(str == NULL, "got str %p\n", str); + + impl.ref = 1; + impl.have_inspectable = impl.have_stringable = impl.have_printable = FALSE; + str = p__abi_ObjectToString(&impl.IUnknown_iface, TRUE); + ok(str == NULL, "got str %p\n", str); + str = p__abi_ObjectToString(&impl.IUnknown_iface, FALSE); + ok(str == NULL, "got str %p\n", str); + + /* If only IInspectable is available, ObjectToString uses the value returned by GetRuntimeClassName. */ + impl.have_inspectable = TRUE; + str = p__abi_ObjectToString(&impl.IUnknown_iface, TRUE); + buf = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(buf, class_name), "Got str %s\n", debugstr_hstring(str)); + WindowsDeleteString(str); + str = p__abi_ObjectToString(&impl.IUnknown_iface, FALSE); + buf = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(buf, class_name), "Got str %s\n", debugstr_hstring(str)); + WindowsDeleteString(str); + + /* The second parameter controls whether the IStringable/IPrintable interfaces should be used for getting the string + * value. */ + impl.have_stringable = TRUE; + str = p__abi_ObjectToString(&impl.IUnknown_iface, TRUE); + buf = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(buf, stringable_val), "Got str %s\n", debugstr_hstring(str)); + WindowsDeleteString(str); + str = p__abi_ObjectToString(&impl.IUnknown_iface, FALSE); + buf = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(buf, class_name), "Got str %s\n", debugstr_hstring(str)); + WindowsDeleteString(str); + + /* IPrintable seems to be a C++/CX specific alias for IStringable. */ + impl.have_stringable = FALSE; + impl.have_printable = TRUE; + str = p__abi_ObjectToString(&impl.IUnknown_iface, TRUE); + buf = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(buf, stringable_val), "Got str %s\n", debugstr_hstring(str)); + WindowsDeleteString(str); + str = p__abi_ObjectToString(&impl.IUnknown_iface, FALSE); + buf = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(buf, class_name), "Got str %s\n", debugstr_hstring(str)); + WindowsDeleteString(str); + + ok(impl.ref == 1, "got ref %lu\n", impl.ref); +} + START_TEST(vccorlib) { if(!init()) @@ -1825,4 +2141,5 @@ START_TEST(vccorlib) test_CreateValue(); test_exceptions(); test_GetWeakReference(); + test___abi_ObjectToString(); } diff --git a/dlls/vccorlib140/vccorlib.c b/dlls/vccorlib140/vccorlib.c index baa825ef186..34b7e858b36 100644 --- a/dlls/vccorlib140/vccorlib.c +++ b/dlls/vccorlib140/vccorlib.c @@ -611,6 +611,12 @@ void *WINAPI CreateValue(int typecode, const void *val) return obj; }
+HSTRING WINAPI __abi_ObjectToString(IUnknown *obj, bool try_stringable) +{ + FIXME("(%p, %d): stub!\n", obj, try_stringable); + return NULL; +} + BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { if (reason == DLL_PROCESS_ATTACH) diff --git a/dlls/vccorlib140/vccorlib140.spec b/dlls/vccorlib140/vccorlib140.spec index a34054a7994..b380e21a23b 100644 --- a/dlls/vccorlib140/vccorlib140.spec +++ b/dlls/vccorlib140/vccorlib140.spec @@ -290,9 +290,9 @@ @ stub -arch=win64 ?__abi_FailFast@@YAXXZ @ stub -arch=win32 ??0GridLength@Xaml@UI@Windows@@QAA@NW4GridUnitType@123@@Z @ stub -arch=win64 ??0GridLength@Xaml@UI@Windows@@QEAA@NW4GridUnitType@123@@Z -@ stub -arch=i386 ?__abi_ObjectToString@__abi_details@@YGP$AAVString@Platform@@P$AAVObject@3@_N@Z -@ stub -arch=arm ?__abi_ObjectToString@__abi_details@@YAP$AAVString@Platform@@P$AAVObject@3@_N@Z -@ stub -arch=win64 ?__abi_ObjectToString@__abi_details@@YAPE$AAVString@Platform@@PE$AAVObject@3@_N@Z +@ stdcall -arch=i386 ?__abi_ObjectToString@__abi_details@@YGP$AAVString@Platform@@P$AAVObject@3@_N@Z(ptr long) __abi_ObjectToString +@ stdcall -arch=arm ?__abi_ObjectToString@__abi_details@@YAP$AAVString@Platform@@P$AAVObject@3@_N@Z(ptr long) __abi_ObjectToString +@ stdcall -arch=win64 ?__abi_ObjectToString@__abi_details@@YAPE$AAVString@Platform@@PE$AAVObject@3@_N@Z(ptr long) __abi_ObjectToString @ stub -arch=win32 ?__abi_Resolve@ControlBlock@Details@Platform@@UAGJAAVGuid@3@PAPAU__abi_IInspectable@@@Z @ stub -arch=win64 ?__abi_Resolve@ControlBlock@Details@Platform@@UEAAJAEAVGuid@3@PEAPEAU__abi_IInspectable@@@Z @ stdcall -arch=i386 ?__abi_WinRTraiseAccessDeniedException@@YGXXZ() __abi_WinRTraiseAccessDeniedException
From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/except.c | 6 ++ dlls/vccorlib140/tests/vccorlib.c | 124 +++++++++++++++++++++++++++++- dlls/vccorlib140/vccorlib.c | 78 +++++++++++++++++++ dlls/vccorlib140/vccorlib140.spec | 56 +++++++------- 4 files changed, 233 insertions(+), 31 deletions(-)
diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index e8b65d47237..c3cff729be5 100644 --- a/dlls/vccorlib140/except.c +++ b/dlls/vccorlib140/except.c @@ -562,6 +562,12 @@ HSTRING __cdecl Exception_get_Message(struct Exception *this) return msg; }
+HSTRING __cdecl Exception_ToString(struct Exception *this) +{ + FIXME("(%p): stub!\n", this); + return NULL; +} + void init_exception(void *base) { INIT_CXX_BASE(Exception_void_ref, base); diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index 53fd574dcc9..85f487a7002 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -151,6 +151,7 @@ static void *(WINAPI *pCreateValue)(int type, const void *); static void *(__cdecl *pCreateException)(HRESULT); static void *(__cdecl *pCreateExceptionWithMessage)(HRESULT, HSTRING); static HSTRING (__cdecl *p_platform_exception_get_Message)(void *); +static HSTRING (__cdecl *p_platform_exception_ToString)(void *); static void *(__cdecl *pAllocateException)(size_t); static void *(__cdecl *pAllocateExceptionWithWeakRef)(ptrdiff_t, size_t); static void (__cdecl *pFreeException)(void *); @@ -166,6 +167,23 @@ WINRT_EXCEPTIONS static IWeakReference *(WINAPI *p_GetWeakReference)(IUnknown *); static IUnknown *(WINAPI *p_ResolveWeakReference)(const GUID *, IWeakReference **); static void *(WINAPI *p__abi_ObjectToString)(void *, bool stringable); +static HSTRING (*__cdecl p_Boolean_ToString)(const boolean *); +static HSTRING (*__cdecl p_Guid_ToString)(const GUID *); +#define SIMPLE_TOSTRING_FUNC(name, type) static HSTRING (__cdecl *p_##name##_ToString)(const type *); +#define SIMPLE_TOSTRING_FUNCS \ + SIMPLE_TOSTRING_FUNC(char16, WCHAR) \ + SIMPLE_TOSTRING_FUNC(float32, FLOAT) \ + SIMPLE_TOSTRING_FUNC(float64, DOUBLE) \ + SIMPLE_TOSTRING_FUNC(int16, INT16) \ + SIMPLE_TOSTRING_FUNC(int32, INT32) \ + SIMPLE_TOSTRING_FUNC(int64, INT64) \ + SIMPLE_TOSTRING_FUNC(int8, INT8) \ + SIMPLE_TOSTRING_FUNC(uint16, UINT16) \ + SIMPLE_TOSTRING_FUNC(uint32, UINT32) \ + SIMPLE_TOSTRING_FUNC(uint64, UINT64) \ + SIMPLE_TOSTRING_FUNC(uint8, UINT8) +SIMPLE_TOSTRING_FUNCS +#undef SIMPLE_TOSTRING_FUNC
static void *(__cdecl *p__RTtypeid)(const void *); static const char *(__thiscall *p_type_info_name)(void *); @@ -216,6 +234,8 @@ static BOOL init(void) "?CreateException@Exception@Platform@@SAP$AAV12@HP$AAVString@2@@Z"); p_platform_exception_get_Message = (void *)GetProcAddress(hmod, "?get@Message@Exception@Platform@@Q$AAAP$AAVString@3@XZ"); + p_platform_exception_ToString = (void *)GetProcAddress(hmod, + "?ToString@Exception@Platform@@U$AAAP$AAVString@2@XZ"); pAllocateException = (void *)GetProcAddress(hmod, "?AllocateException@Heap@Details@Platform@@SAPAXI@Z"); pAllocateExceptionWithWeakRef = (void *)GetProcAddress(hmod, "?AllocateException@Heap@Details@Platform@@SAPAXII@Z"); @@ -239,6 +259,12 @@ static BOOL init(void) "?ResolveWeakReference@Details@Platform@@YAP$AAVObject@2@ABU_GUID@@PAPAU__abi_IUnknown@@@Z"); p__abi_ObjectToString = (void *)GetProcAddress(hmod, "?__abi_ObjectToString@__abi_details@@YAP$AAVString@Platform@@P$AAVObject@3@_N@Z"); + p_Boolean_ToString = (void *)GetProcAddress(hmod, "?ToString@Boolean@Platform@@QAAP$AAVString@2@XZ"); + p_Guid_ToString = (void *)GetProcAddress(hmod, "?ToString@Guid@Platform@@QAAP$AAVString@2@XZ"); +#define SIMPLE_TOSTRING_FUNC(name, type) \ + p_##name##_ToString = (void *)GetProcAddress(hmod, "?ToString@" #name "@default@@QAAP$AAVString@Platform@@XZ"); + SIMPLE_TOSTRING_FUNCS +#undef SIMPLE_TOSTRING_FUNC
p_type_info_name = (void *)GetProcAddress(msvcrt, "?name@type_info@@QBAPBDXZ"); p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name@type_info@@QBAPBDXZ"); @@ -271,6 +297,8 @@ static BOOL init(void) "?CreateException@Exception@Platform@@SAPE$AAV12@HPE$AAVString@2@@Z"); p_platform_exception_get_Message = (void *)GetProcAddress(hmod, "?get@Message@Exception@Platform@@QE$AAAPE$AAVString@3@XZ"); + p_platform_exception_ToString = (void *)GetProcAddress(hmod, + "?ToString@Exception@Platform@@UE$AAAPE$AAVString@2@XZ"); pAllocateException = (void *)GetProcAddress(hmod, "?AllocateException@Heap@Details@Platform@@SAPEAX_K@Z"); pAllocateExceptionWithWeakRef = (void *)GetProcAddress(hmod, "?AllocateException@Heap@Details@Platform@@SAPEAX_K0@Z"); @@ -295,7 +323,12 @@ static BOOL init(void) "?ResolveWeakReference@Details@Platform@@YAPE$AAVObject@2@AEBU_GUID@@PEAPEAU__abi_IUnknown@@@Z"); p__abi_ObjectToString = (void *)GetProcAddress(hmod, "?__abi_ObjectToString@__abi_details@@YAPE$AAVString@Platform@@PE$AAVObject@3@_N@Z"); - + p_Boolean_ToString = (void *)GetProcAddress(hmod, "?ToString@Boolean@Platform@@QEAAPE$AAVString@2@XZ"); + p_Guid_ToString = (void *)GetProcAddress(hmod, "?ToString@Guid@Platform@@QEAAPE$AAVString@2@XZ"); +#define SIMPLE_TOSTRING_FUNC(name, type) \ + p_##name##_ToString = (void *)GetProcAddress(hmod, "?ToString@" #name "@default@@QEAAPE$AAVString@Platform@@XZ"); + SIMPLE_TOSTRING_FUNCS +#undef SIMPLE_TOSTRING_FUNC p_type_info_name = (void *)GetProcAddress(msvcrt, "?name@type_info@@QEBAPEBDXZ"); p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name@type_info@@QEBAPEBDXZ"); p_type_info_opequals_equals = (void *)GetProcAddress(msvcrt, "??8type_info@@QEBAHAEBV0@@Z"); @@ -326,6 +359,8 @@ static BOOL init(void) "?CreateException@Exception@Platform@@SAP$AAV12@HP$AAVString@2@@Z"); p_platform_exception_get_Message = (void *)GetProcAddress(hmod, "?get@Message@Exception@Platform@@Q$AAAP$AAVString@3@XZ"); + p_platform_exception_ToString = (void *)GetProcAddress(hmod, + "?ToString@Exception@Platform@@U$AAAP$AAVString@2@XZ"); pAllocateException = (void *)GetProcAddress(hmod, "?AllocateException@Heap@Details@Platform@@SAPAXI@Z"); pAllocateExceptionWithWeakRef = (void *)GetProcAddress(hmod, "?AllocateException@Heap@Details@Platform@@SAPAXII@Z"); @@ -350,6 +385,12 @@ static BOOL init(void) "?ResolveWeakReference@Details@Platform@@YGP$AAVObject@2@ABU_GUID@@PAPAU__abi_IUnknown@@@Z"); p__abi_ObjectToString = (void *)GetProcAddress(hmod, "?__abi_ObjectToString@__abi_details@@YGP$AAVString@Platform@@P$AAVObject@3@_N@Z"); + p_Boolean_ToString = (void *)GetProcAddress(hmod, "?ToString@Boolean@Platform@@QAAP$AAVString@2@XZ"); + p_Guid_ToString = (void *)GetProcAddress(hmod, "?ToString@Guid@Platform@@QAAP$AAVString@2@XZ"); +#define SIMPLE_TOSTRING_FUNC(name, type) \ + p_##name##_ToString = (void *)GetProcAddress(hmod, "?ToString@" #name "@default@@QAAP$AAVString@Platform@@XZ"); + SIMPLE_TOSTRING_FUNCS +#undef SIMPLE_TOSTRING_FUNC
p_type_info_name = (void *)GetProcAddress(msvcrt, "?name@type_info@@QBEPBDXZ"); p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name@type_info@@QBEPBDXZ"); @@ -372,6 +413,7 @@ static BOOL init(void) ok(pCreateException != NULL, "CreateException not available\n"); ok(pCreateExceptionWithMessage != NULL, "CreateExceptionWithMessage not available\n"); ok(p_platform_exception_get_Message != NULL, "Platform::Exception::Message::get not available\n"); + ok(p_platform_exception_ToString != NULL, "Platform::Exception::ToString not available\n"); ok(pAllocateException != NULL, "AllocateException not available\n"); ok(pAllocateExceptionWithWeakRef != NULL, "AllocateExceptionWithWeakRef not available.\n"); ok(pFreeException != NULL, "FreeException not available\n"); @@ -388,7 +430,12 @@ static BOOL init(void) ok(p_GetWeakReference != NULL, "GetWeakReference not available.\n"); ok(p_ResolveWeakReference != NULL, "ResolveWeakReference is not available.\n"); ok(p__abi_ObjectToString != NULL, "__abi_ObjectToString not available.\n"); - + ok(p_Boolean_ToString != NULL, "Platform::Boolean::ToString not available.\n"); + ok(p_Guid_ToString != NULL, "Platform::Guid::ToString not available.\n"); +#define SIMPLE_TOSTRING_FUNC(name, type) \ + ok(p_##name##_ToString != NULL, "default::" #name "::ToString not available.\n"); + SIMPLE_TOSTRING_FUNCS +#undef SIMPLE_TOSTRING_FUNC ok(p_type_info_name != NULL, "type_info::name not available\n"); ok(p_type_info_raw_name != NULL, "type_info::raw_name not available\n"); ok(p_type_info_opequals_equals != NULL, "type_info::operator== not available\n"); @@ -1644,12 +1691,17 @@ static void test_exceptions(void) { bufW = WindowsGetStringRawBuffer(str, NULL); ok(!wcscmp(bufW, buf), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(buf)); + WindowsDeleteString(str);
str = p__abi_ObjectToString(obj, TRUE); bufW = WindowsGetStringRawBuffer(str, NULL); todo_wine ok(!wcscmp(bufW, buf), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(buf)); + WindowsDeleteString(str); + + str = p_platform_exception_ToString(obj); + bufW = WindowsGetStringRawBuffer(str, NULL); + todo_wine ok(!wcscmp(bufW, buf), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(buf)); } - WindowsDeleteString(str);
inner = *(const struct exception_inner **)((ULONG_PTR)obj - sizeof(ULONG_PTR)); ok(inner == &obj->inner, "got inner %p != %p\n", inner, &obj->inner); @@ -1752,6 +1804,12 @@ static void test_exceptions(void) todo_wine ok(!ret, "got str %s != %s\n", debugstr_hstring(str), debugstr_hstring(msg)); WindowsDeleteString(str);
+ str = p_platform_exception_ToString(inspectable); + hr = WindowsCompareStringOrdinal(str, msg, &ret); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(!ret, "got str %s != %s\n", debugstr_hstring(str), debugstr_hstring(msg)); + WindowsDeleteString(str); + inner = (const struct exception_inner *)*(ULONG_PTR *)((ULONG_PTR)inspectable - sizeof(ULONG_PTR)); ok(inner->description == NULL, "got description %p\n", inner->description); ok(inner->restricted_desc != NULL, "got restricted_desc %p\n", inner->restricted_desc); @@ -2126,6 +2184,65 @@ static void test___abi_ObjectToString(void) ok(impl.ref == 1, "got ref %lu\n", impl.ref); }
+#define test_hstring(str, exp_str) test_hstring_(__LINE__, str, (exp_str)) +static void test_hstring_(int line, HSTRING str, const WCHAR *exp_str) +{ + const WCHAR *buf; + buf = WindowsGetStringRawBuffer(str, NULL); + ok_(__FILE__, line)(!wcscmp(buf, exp_str), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(exp_str)); + WindowsDeleteString(str); +} + +static void test_ToString(void) +{ + static const UINT64 uint64 = 0xdeadbeefdeadbeef; + static const INT64 int64 = 0xdeadbeefdeadbeef; + static const GUID guid = IID_IInspectable; + static const DOUBLE float64 = 2.71828182; + static const FLOAT float32 = 2.71828182; + static const UINT32 uint32 = 0xdeadbeef; + static const INT32 int32 = 0xdeadbeef; + static const UINT16 uint16 = 0xbeef; + static const INT16 int16 = 0xbeef; + static const WCHAR char16 = L'a'; + static const UINT8 uint8 = 0xff; + static const INT8 int8 = 0xff; + boolean bool_val = true; + HSTRING str; + + str = p_uint64_ToString(&uint64); + todo_wine test_hstring(str, L"16045690984833335023"); + str = p_int64_ToString(&int64); + todo_wine test_hstring(str, L"-2401053088876216593"); + str = p_float64_ToString(&float64); + todo_wine test_hstring(str, L"2.71828"); + str = p_float32_ToString(&float32); + todo_wine test_hstring(str, L"2.71828"); + str = p_uint32_ToString(&uint32); + todo_wine test_hstring(str, L"3735928559"); + str = p_int32_ToString(&int32); + todo_wine test_hstring(str, L"-559038737"); + str = p_uint16_ToString(&uint16); + todo_wine test_hstring(str, L"48879"); + str = p_int16_ToString(&int16); + todo_wine test_hstring(str, L"-16657"); + str = p_int8_ToString(&int8); + todo_wine test_hstring(str, L"-1"); + str = p_uint8_ToString(&uint8); + todo_wine test_hstring(str, L"255"); + str = p_char16_ToString(&char16); + todo_wine test_hstring(str, L"a"); + + str = p_Boolean_ToString(&bool_val); + todo_wine test_hstring(str, L"true"); + bool_val = false; + str = p_Boolean_ToString(&bool_val); + todo_wine test_hstring(str, L"false"); + + str = p_Guid_ToString(&guid); + todo_wine test_hstring(str, L"{af86e2e0-b12d-4c6a-9c5a-d7aa65101e90}"); +} + START_TEST(vccorlib) { if(!init()) @@ -2142,4 +2259,5 @@ START_TEST(vccorlib) test_exceptions(); test_GetWeakReference(); test___abi_ObjectToString(); + test_ToString(); } diff --git a/dlls/vccorlib140/vccorlib.c b/dlls/vccorlib140/vccorlib.c index 34b7e858b36..b875801176b 100644 --- a/dlls/vccorlib140/vccorlib.c +++ b/dlls/vccorlib140/vccorlib.c @@ -617,6 +617,84 @@ HSTRING WINAPI __abi_ObjectToString(IUnknown *obj, bool try_stringable) return NULL; }
+HSTRING __cdecl Guid_ToString(const GUID *this) +{ + FIXME("(%s): stub!\n", debugstr_guid(this)); + return NULL; +} + +HSTRING __cdecl Boolean_ToString(const boolean *this) +{ + FIXME("(%p): stub!\n", this); + return NULL; +} + +HSTRING __cdecl char16_ToString(const WCHAR *this) +{ + FIXME("(%p): stub!\n", this); + return NULL; +} + +HSTRING __cdecl float32_ToString(const FLOAT *this) +{ + FIXME("(%p): stub!\n", this); + return NULL; +} + +HSTRING __cdecl float64_ToString(const DOUBLE *this) +{ + FIXME("(%p): stub!\n", this); + return NULL; +} + +HSTRING __cdecl int16_ToString(const INT16 *this) +{ + FIXME("(%p): stub!\n", this); + return NULL; +} + +HSTRING __cdecl int32_ToString(const INT32 *this) +{ + FIXME("(%p): stub\n", this); + return NULL; +} + +HSTRING __cdecl int64_ToString(const INT64 *this) +{ + FIXME("(%p): stub!\n", this); + return NULL; +} + +HSTRING __cdecl int8_ToString(const INT8 *this) +{ + FIXME("(%p): stub!\n", this); + return NULL; +} + +HSTRING __cdecl uint16_ToString(const UINT16 *this) +{ + FIXME("(%p): stub!\n", this); + return NULL; +} + +HSTRING __cdecl uint32_ToString(const UINT32 *this) +{ + FIXME("(%p): stub!\n", this); + return NULL; +} + +HSTRING __cdecl uint64_ToString(const UINT64 *this) +{ + FIXME("(%p): stub!\n", this); + return NULL; +} + +HSTRING __cdecl uint8_ToString(const UINT8 *this) +{ + FIXME("(%p): stub!\n", this); + return NULL; +} + BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { if (reason == DLL_PROCESS_ATTACH) diff --git a/dlls/vccorlib140/vccorlib140.spec b/dlls/vccorlib140/vccorlib140.spec index b380e21a23b..6b1632e2a3c 100644 --- a/dlls/vccorlib140/vccorlib140.spec +++ b/dlls/vccorlib140/vccorlib140.spec @@ -227,16 +227,16 @@ @ stub -arch=win64 ?ToInt32@IntPtr@Platform@@QEAAHXZ @ stub -arch=win32 ?ToString@Attribute@Metadata@Platform@@Q$AAAP$AAVString@3@XZ @ stub -arch=win64 ?ToString@Attribute@Metadata@Platform@@QE$AAAPE$AAVString@3@XZ -@ stub -arch=win32 ?ToString@Boolean@Platform@@QAAP$AAVString@2@XZ -@ stub -arch=win64 ?ToString@Boolean@Platform@@QEAAPE$AAVString@2@XZ +@ cdecl -arch=win32 ?ToString@Boolean@Platform@@QAAP$AAVString@2@XZ(ptr) Boolean_ToString +@ cdecl -arch=win64 ?ToString@Boolean@Platform@@QEAAPE$AAVString@2@XZ(ptr) Boolean_ToString @ stub -arch=win32 ?ToString@Delegate@Platform@@Q$AAAP$AAVString@2@XZ @ stub -arch=win64 ?ToString@Delegate@Platform@@QE$AAAPE$AAVString@2@XZ @ stub -arch=win32 ?ToString@Enum@Platform@@Q$AAAP$AAVString@2@XZ @ stub -arch=win64 ?ToString@Enum@Platform@@QE$AAAPE$AAVString@2@XZ -@ stub -arch=win32 ?ToString@Exception@Platform@@U$AAAP$AAVString@2@XZ -@ stub -arch=win64 ?ToString@Exception@Platform@@UE$AAAPE$AAVString@2@XZ -@ stub -arch=win32 ?ToString@Guid@Platform@@QAAP$AAVString@2@XZ -@ stub -arch=win64 ?ToString@Guid@Platform@@QEAAPE$AAVString@2@XZ +@ cdecl -arch=win32 ?ToString@Exception@Platform@@U$AAAP$AAVString@2@XZ(ptr) Exception_ToString +@ cdecl -arch=win64 ?ToString@Exception@Platform@@UE$AAAPE$AAVString@2@XZ(ptr) Exception_ToString +@ cdecl -arch=win32 ?ToString@Guid@Platform@@QAAP$AAVString@2@XZ(ptr) Guid_ToString +@ cdecl -arch=win64 ?ToString@Guid@Platform@@QEAAPE$AAVString@2@XZ(ptr) Guid_ToString @ stub -arch=win32 ?ToString@MTAThreadAttribute@Platform@@Q$AAAP$AAVString@2@XZ @ stub -arch=win64 ?ToString@MTAThreadAttribute@Platform@@QE$AAAPE$AAVString@2@XZ @ stub -arch=win32 ?ToString@OnePhaseConstructedAttribute@CompilerServices@Runtime@Platform@@Q$AAAP$AAVString@4@XZ @@ -251,30 +251,30 @@ @ 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 @ stub -arch=win64 ?ToString@ValueType@Platform@@QE$AAAPE$AAVString@2@XZ -@ stub -arch=win32 ?ToString@char16@default@@QAAP$AAVString@Platform@@XZ -@ stub -arch=win64 ?ToString@char16@default@@QEAAPE$AAVString@Platform@@XZ -@ stub -arch=win32 ?ToString@float32@default@@QAAP$AAVString@Platform@@XZ -@ stub -arch=win64 ?ToString@float32@default@@QEAAPE$AAVString@Platform@@XZ -@ stub -arch=win32 ?ToString@float64@default@@QAAP$AAVString@Platform@@XZ -@ stub -arch=win64 ?ToString@float64@default@@QEAAPE$AAVString@Platform@@XZ -@ stub -arch=win32 ?ToString@int16@default@@QAAP$AAVString@Platform@@XZ -@ stub -arch=win64 ?ToString@int16@default@@QEAAPE$AAVString@Platform@@XZ -@ stub -arch=win32 ?ToString@int32@default@@QAAP$AAVString@Platform@@XZ -@ stub -arch=win64 ?ToString@int32@default@@QEAAPE$AAVString@Platform@@XZ -@ stub -arch=win32 ?ToString@int64@default@@QAAP$AAVString@Platform@@XZ -@ stub -arch=win64 ?ToString@int64@default@@QEAAPE$AAVString@Platform@@XZ -@ stub -arch=win32 ?ToString@int8@default@@QAAP$AAVString@Platform@@XZ -@ 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 ?ToString@char16@default@@QAAP$AAVString@Platform@@XZ(ptr) char16_ToString +@ cdecl -arch=win64 ?ToString@char16@default@@QEAAPE$AAVString@Platform@@XZ(ptr) char16_ToString +@ cdecl -arch=win32 ?ToString@float32@default@@QAAP$AAVString@Platform@@XZ(ptr) float32_ToString +@ cdecl -arch=win64 ?ToString@float32@default@@QEAAPE$AAVString@Platform@@XZ(ptr) float32_ToString +@ cdecl -arch=win32 ?ToString@float64@default@@QAAP$AAVString@Platform@@XZ(ptr) float64_ToString +@ cdecl -arch=win64 ?ToString@float64@default@@QEAAPE$AAVString@Platform@@XZ(ptr) float64_ToString +@ cdecl -arch=win32 ?ToString@int16@default@@QAAP$AAVString@Platform@@XZ(ptr) int16_ToString +@ cdecl -arch=win64 ?ToString@int16@default@@QEAAPE$AAVString@Platform@@XZ(ptr) int16_ToString +@ cdecl -arch=win32 ?ToString@int32@default@@QAAP$AAVString@Platform@@XZ(ptr) int32_ToString +@ cdecl -arch=win64 ?ToString@int32@default@@QEAAPE$AAVString@Platform@@XZ(ptr) int32_ToString +@ cdecl -arch=win32 ?ToString@int64@default@@QAAP$AAVString@Platform@@XZ(ptr) int64_ToString +@ cdecl -arch=win64 ?ToString@int64@default@@QEAAPE$AAVString@Platform@@XZ(ptr) int64_ToString +@ cdecl -arch=win32 ?ToString@int8@default@@QAAP$AAVString@Platform@@XZ(ptr) int8_ToString +@ cdecl -arch=win64 ?ToString@int8@default@@QEAAPE$AAVString@Platform@@XZ(ptr) int8_ToString +@ cdecl -arch=win32 ?ToString@uint16@default@@QAAP$AAVString@Platform@@XZ(ptr) uint16_ToString +@ cdecl -arch=win64 ?ToString@uint16@default@@QEAAPE$AAVString@Platform@@XZ(ptr) uint16_ToString @ 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 -@ stub -arch=win64 ?ToString@uint64@default@@QEAAPE$AAVString@Platform@@XZ -@ stub -arch=win32 ?ToString@uint8@default@@QAAP$AAVString@Platform@@XZ -@ stub -arch=win64 ?ToString@uint8@default@@QEAAPE$AAVString@Platform@@XZ +@ cdecl -arch=win32 ?ToString@uint32@default@@QAAP$AAVString@Platform@@XZ(ptr) uint32_ToString +@ cdecl -arch=win64 ?ToString@uint32@default@@QEAAPE$AAVString@Platform@@XZ(ptr) uint32_ToString +@ cdecl -arch=win32 ?ToString@uint64@default@@QAAP$AAVString@Platform@@XZ(ptr) uint64_ToString +@ cdecl -arch=win64 ?ToString@uint64@default@@QEAAPE$AAVString@Platform@@XZ(ptr) uint64_ToString +@ cdecl -arch=win32 ?ToString@uint8@default@@QAAP$AAVString@Platform@@XZ(ptr) uint8_ToString +@ cdecl -arch=win64 ?ToString@uint8@default@@QEAAPE$AAVString@Platform@@XZ(ptr) uint8_ToString @ cdecl ?UninitializeData@Details@Platform@@YAXH@Z(long) UninitializeData @ stub -arch=win32 ?Union@Rect@Foundation@Windows@@QAAXV123@@Z @ stub -arch=win64 ?Union@Rect@Foundation@Windows@@QEAAXV123@@Z
From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/private.h | 2 + dlls/vccorlib140/tests/vccorlib.c | 31 +++++----- dlls/vccorlib140/vccorlib.c | 97 ++++++++++++++++++++++++++++++- 3 files changed, 112 insertions(+), 18 deletions(-)
diff --git a/dlls/vccorlib140/private.h b/dlls/vccorlib140/private.h index f5cb3fc69fb..e71abcc56f3 100644 --- a/dlls/vccorlib140/private.h +++ b/dlls/vccorlib140/private.h @@ -94,3 +94,5 @@ void WINAPI DECLSPEC_NORETURN __abi_WinRTraiseOutOfMemoryException(void); DEFINE_IINSPECTABLE_(pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, &impl->base_iface) #define DEFINE_IINSPECTABLE_OUTER(pfx, iface_type, impl_type, outer_iface) \ DEFINE_IINSPECTABLE_(pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, impl->outer_iface) + +DEFINE_GUID(IID_IPrintable,0xde0cbaeb,0x8065,0x4a45,0x96,0xb1,0xc9,0xd4,0x43,0xf9,0xba,0xb3); diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index 85f487a7002..14370e56f74 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -1138,8 +1138,7 @@ static void test___abi_make_type_id(void)
str = p__abi_ObjectToString(type_obj, FALSE); buf = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(buf && !wcscmp(buf, L"Platform.Type"), "got buf %s != %s\n", debugstr_w(buf), - debugstr_w(L"Platform.Type")); + ok(buf && !wcscmp(buf, L"Platform.Type"), "got buf %s != %s\n", debugstr_w(buf), debugstr_w(L"Platform.Type")); WindowsDeleteString(str);
str = p__abi_ObjectToString(type_obj, TRUE); @@ -1327,12 +1326,12 @@ static void test_CreateValue(void) { str = p__abi_ObjectToString(obj, FALSE); buf = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(!wcscmp(buf, exp_str), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(exp_str)); + ok(!wcscmp(buf, exp_str), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(exp_str)); WindowsDeleteString(str);
str = p__abi_ObjectToString(obj, TRUE); buf = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(!wcscmp(buf, exp_str), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(exp_str)); + ok(!wcscmp(buf, exp_str), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(exp_str)); WindowsDeleteString(str); } if (name) WindowsDeleteString(name); @@ -1426,12 +1425,12 @@ static void test_CreateValue(void)
str = p__abi_ObjectToString(obj, TRUE); buf = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(!wcscmp(buf, L"foo"), "got buf %s\n", debugstr_w(buf)); + ok(!wcscmp(buf, L"foo"), "got buf %s\n", debugstr_w(buf)); WindowsDeleteString(str);
str = p__abi_ObjectToString(obj, FALSE); buf = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(!wcscmp(buf, L"foo"), "got buf %s\n", debugstr_w(buf)); + ok(!wcscmp(buf, L"foo"), "got buf %s\n", debugstr_w(buf)); WindowsDeleteString(str);
count = IPropertyValue_Release(obj); @@ -1632,8 +1631,8 @@ static void test_exceptions(void) str = p__abi_ObjectToString(obj, FALSE); ok(hr == S_OK, "got hr %#lx\n", hr); bufW = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(!wcscmp(cur_test->exp_winrt_name, bufW), "got str %s != %s\n", debugstr_hstring(str), - debugstr_w(cur_test->exp_winrt_name)); + ok(!wcscmp(cur_test->exp_winrt_name, bufW), "got str %s != %s\n", debugstr_hstring(str), + debugstr_w(cur_test->exp_winrt_name)); WindowsDeleteString(str);
/* Verify control block fields. */ @@ -1794,8 +1793,8 @@ static void test_exceptions(void)
str = p__abi_ObjectToString(inspectable, FALSE); bufW = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(!wcscmp(cur_test->exp_winrt_name, bufW), "got str %s != %s\n", debugstr_hstring(str), - debugstr_w(cur_test->exp_winrt_name)); + ok(!wcscmp(cur_test->exp_winrt_name, bufW), "got str %s != %s\n", debugstr_hstring(str), + debugstr_w(cur_test->exp_winrt_name)); WindowsDeleteString(str);
str = p__abi_ObjectToString(inspectable, TRUE); @@ -2150,11 +2149,11 @@ static void test___abi_ObjectToString(void) impl.have_inspectable = TRUE; str = p__abi_ObjectToString(&impl.IUnknown_iface, TRUE); buf = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(!wcscmp(buf, class_name), "Got str %s\n", debugstr_hstring(str)); + ok(!wcscmp(buf, class_name), "Got str %s\n", debugstr_hstring(str)); WindowsDeleteString(str); str = p__abi_ObjectToString(&impl.IUnknown_iface, FALSE); buf = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(!wcscmp(buf, class_name), "Got str %s\n", debugstr_hstring(str)); + ok(!wcscmp(buf, class_name), "Got str %s\n", debugstr_hstring(str)); WindowsDeleteString(str);
/* The second parameter controls whether the IStringable/IPrintable interfaces should be used for getting the string @@ -2162,11 +2161,11 @@ static void test___abi_ObjectToString(void) impl.have_stringable = TRUE; str = p__abi_ObjectToString(&impl.IUnknown_iface, TRUE); buf = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(!wcscmp(buf, stringable_val), "Got str %s\n", debugstr_hstring(str)); + ok(!wcscmp(buf, stringable_val), "Got str %s\n", debugstr_hstring(str)); WindowsDeleteString(str); str = p__abi_ObjectToString(&impl.IUnknown_iface, FALSE); buf = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(!wcscmp(buf, class_name), "Got str %s\n", debugstr_hstring(str)); + ok(!wcscmp(buf, class_name), "Got str %s\n", debugstr_hstring(str)); WindowsDeleteString(str);
/* IPrintable seems to be a C++/CX specific alias for IStringable. */ @@ -2174,11 +2173,11 @@ static void test___abi_ObjectToString(void) impl.have_printable = TRUE; str = p__abi_ObjectToString(&impl.IUnknown_iface, TRUE); buf = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(!wcscmp(buf, stringable_val), "Got str %s\n", debugstr_hstring(str)); + ok(!wcscmp(buf, stringable_val), "Got str %s\n", debugstr_hstring(str)); WindowsDeleteString(str); str = p__abi_ObjectToString(&impl.IUnknown_iface, FALSE); buf = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(!wcscmp(buf, class_name), "Got str %s\n", debugstr_hstring(str)); + ok(!wcscmp(buf, class_name), "Got str %s\n", debugstr_hstring(str)); WindowsDeleteString(str);
ok(impl.ref == 1, "got ref %lu\n", impl.ref); diff --git a/dlls/vccorlib140/vccorlib.c b/dlls/vccorlib140/vccorlib.c index b875801176b..a437c5f590c 100644 --- a/dlls/vccorlib140/vccorlib.c +++ b/dlls/vccorlib140/vccorlib.c @@ -613,8 +613,101 @@ void *WINAPI CreateValue(int typecode, const void *val)
HSTRING WINAPI __abi_ObjectToString(IUnknown *obj, bool try_stringable) { - FIXME("(%p, %d): stub!\n", obj, try_stringable); - return NULL; + IInspectable *inspectable; + IPropertyValue *propval; + IStringable *stringable; + HSTRING val = NULL; + HRESULT hr = S_OK; + + TRACE("(%p, %d)\n", obj, try_stringable); + + if (!obj) return NULL; + /* If try_stringable is true, native will first query for IStringable, and then IPrintable (which is just an alias + * for IStringable). */ + if (try_stringable && (SUCCEEDED(IUnknown_QueryInterface(obj, &IID_IStringable, (void **)&stringable)) || + SUCCEEDED(IUnknown_QueryInterface(obj, &IID_IPrintable, (void **)&stringable)))) + { + hr = IStringable_ToString(stringable, &val); + IStringable_Release(stringable); + } + /* Next, native checks if this is an boxed type (IPropertyValue) storing a numeric-like or string value. */ + else if (SUCCEEDED(IUnknown_QueryInterface(obj, &IID_IPropertyValue, (void **)&propval))) + { + PropertyType type; + WCHAR buf[100]; + int len; + + if (SUCCEEDED((hr = IPropertyValue_get_Type(propval, &type)))) + { +#define PROPVAL_SIMPLE(prop_type, c_type, fmt) \ + case PropertyType_##prop_type: \ + { \ + c_type prop_type_##val; \ + if (SUCCEEDED(hr = IPropertyValue_Get##prop_type(propval, &prop_type_##val))) \ + { \ + len = swprintf(buf, ARRAY_SIZE(buf), (fmt), prop_type_##val); \ + hr = WindowsCreateString(buf, len, &val); \ + } \ + break; \ + } + switch (type) + { + PROPVAL_SIMPLE(Char16, WCHAR, L"%c") + PROPVAL_SIMPLE(UInt8, UINT8, L"%hhu") + PROPVAL_SIMPLE(Int16, INT16, L"%hd") + PROPVAL_SIMPLE(UInt16, UINT16, L"%hu") + PROPVAL_SIMPLE(Int32, INT32, L"%I32d") + PROPVAL_SIMPLE(UInt32, UINT32, L"%I32u") + PROPVAL_SIMPLE(Int64, INT64, L"%I64d") + PROPVAL_SIMPLE(UInt64, UINT64, L"%I64u") + PROPVAL_SIMPLE(Single, FLOAT, L"%g") + PROPVAL_SIMPLE(Double, DOUBLE, L"%g") + case PropertyType_Boolean: + { + boolean bool_val; + + if (SUCCEEDED(hr = IPropertyValue_GetBoolean(propval, &bool_val))) + { + len = swprintf(buf, ARRAY_SIZE(buf), bool_val ? L"true" : L"false"); + hr = WindowsCreateString(buf, len, &val); + } + break; + } + case PropertyType_String: + hr = IPropertyValue_GetString(propval, &val); + break; + case PropertyType_Guid: + { + GUID guid; + + if (SUCCEEDED(hr = IPropertyValue_GetGuid(propval, &guid))) + { + len = swprintf(buf, ARRAY_SIZE(buf), L"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], + guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + hr = WindowsCreateString(buf, len, &val); + } + break; + } + default: + /* For other types, use the WinRT class name. */ + hr = IPropertyValue_GetRuntimeClassName(propval, &val); + } +#undef PROPVAL_SIMPLE + } + IPropertyValue_Release(propval); + } + /* Finally, if this is an IInspectable, use the WinRT class name. Otherwise, return NULL. */ + else if (SUCCEEDED(IUnknown_QueryInterface(obj, &IID_IInspectable, (void **)&inspectable))) + { + hr = IInspectable_GetRuntimeClassName(inspectable, &val); + IInspectable_Release(inspectable); + } + + if (FAILED(hr)) + __abi_WinRTraiseCOMException(hr); + + return val; }
HSTRING __cdecl Guid_ToString(const GUID *this)
From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/tests/vccorlib.c | 28 +++---- dlls/vccorlib140/vccorlib.c | 118 +++++++++++++++++++++++------- 2 files changed, 106 insertions(+), 40 deletions(-)
diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index 14370e56f74..92e6150ac04 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -2210,36 +2210,36 @@ static void test_ToString(void) HSTRING str;
str = p_uint64_ToString(&uint64); - todo_wine test_hstring(str, L"16045690984833335023"); + test_hstring(str, L"16045690984833335023"); str = p_int64_ToString(&int64); - todo_wine test_hstring(str, L"-2401053088876216593"); + test_hstring(str, L"-2401053088876216593"); str = p_float64_ToString(&float64); - todo_wine test_hstring(str, L"2.71828"); + test_hstring(str, L"2.71828"); str = p_float32_ToString(&float32); - todo_wine test_hstring(str, L"2.71828"); + test_hstring(str, L"2.71828"); str = p_uint32_ToString(&uint32); - todo_wine test_hstring(str, L"3735928559"); + test_hstring(str, L"3735928559"); str = p_int32_ToString(&int32); - todo_wine test_hstring(str, L"-559038737"); + test_hstring(str, L"-559038737"); str = p_uint16_ToString(&uint16); - todo_wine test_hstring(str, L"48879"); + test_hstring(str, L"48879"); str = p_int16_ToString(&int16); - todo_wine test_hstring(str, L"-16657"); + test_hstring(str, L"-16657"); str = p_int8_ToString(&int8); - todo_wine test_hstring(str, L"-1"); + test_hstring(str, L"-1"); str = p_uint8_ToString(&uint8); - todo_wine test_hstring(str, L"255"); + test_hstring(str, L"255"); str = p_char16_ToString(&char16); - todo_wine test_hstring(str, L"a"); + test_hstring(str, L"a");
str = p_Boolean_ToString(&bool_val); - todo_wine test_hstring(str, L"true"); + test_hstring(str, L"true"); bool_val = false; str = p_Boolean_ToString(&bool_val); - todo_wine test_hstring(str, L"false"); + test_hstring(str, L"false");
str = p_Guid_ToString(&guid); - todo_wine test_hstring(str, L"{af86e2e0-b12d-4c6a-9c5a-d7aa65101e90}"); + test_hstring(str, L"{af86e2e0-b12d-4c6a-9c5a-d7aa65101e90}"); }
START_TEST(vccorlib) diff --git a/dlls/vccorlib140/vccorlib.c b/dlls/vccorlib140/vccorlib.c index a437c5f590c..e1652502e74 100644 --- a/dlls/vccorlib140/vccorlib.c +++ b/dlls/vccorlib140/vccorlib.c @@ -710,82 +710,148 @@ HSTRING WINAPI __abi_ObjectToString(IUnknown *obj, bool try_stringable) return val; }
+#define HSTRING_SPRINTF(out, fmt, ...) do { \ + WCHAR buf[100]; \ + HRESULT hr; \ + int len; \ + len = swprintf(buf, ARRAY_SIZE(buf), (fmt), __VA_ARGS__); \ + if (FAILED(hr = WindowsCreateString(buf, len, (out)))) __abi_WinRTraiseCOMException(hr); \ +} while(0) + HSTRING __cdecl Guid_ToString(const GUID *this) { - FIXME("(%s): stub!\n", debugstr_guid(this)); - return NULL; + HSTRING str; + + TRACE("(%s)\n", debugstr_guid(this)); + + HSTRING_SPRINTF(&str, L"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", this->Data1, this->Data2, this->Data3, + this->Data4[0], this->Data4[1], this->Data4[2], this->Data4[3], this->Data4[4], this->Data4[5], + this->Data4[6], this->Data4[7]); + return str; }
HSTRING __cdecl Boolean_ToString(const boolean *this) { - FIXME("(%p): stub!\n", this); - return NULL; + const WCHAR *strW; + HSTRING str; + HRESULT hr; + + TRACE("(%p)\n", this); + + strW = *this ? L"true" : L"false"; + if (FAILED(hr = WindowsCreateString(strW, wcslen(strW), &str))) + __abi_WinRTraiseCOMException(hr); + return str; }
HSTRING __cdecl char16_ToString(const WCHAR *this) { - FIXME("(%p): stub!\n", this); - return NULL; + HSTRING str; + + TRACE("(%p): stub!\n", this); + + HSTRING_SPRINTF(&str, L"%c", *this); + return str; }
HSTRING __cdecl float32_ToString(const FLOAT *this) { - FIXME("(%p): stub!\n", this); - return NULL; + HSTRING str; + + TRACE("(%p)\n", this); + + HSTRING_SPRINTF(&str, L"%g", *this); + return str; }
HSTRING __cdecl float64_ToString(const DOUBLE *this) { - FIXME("(%p): stub!\n", this); - return NULL; + HSTRING str; + + TRACE("(%p)\n", this); + + HSTRING_SPRINTF(&str, L"%g", *this); + return str; }
HSTRING __cdecl int16_ToString(const INT16 *this) { - FIXME("(%p): stub!\n", this); - return NULL; + HSTRING str; + + TRACE("(%p)\n", this); + + HSTRING_SPRINTF(&str, L"%d", *this); + return str; }
HSTRING __cdecl int32_ToString(const INT32 *this) { - FIXME("(%p): stub\n", this); - return NULL; + HSTRING str; + + TRACE("(%p)\n", this); + + HSTRING_SPRINTF(&str, L"%d", *this); + return str; }
HSTRING __cdecl int64_ToString(const INT64 *this) { - FIXME("(%p): stub!\n", this); - return NULL; + HSTRING str; + + TRACE("(%p)\n", this); + + HSTRING_SPRINTF(&str, L"%I64d", *this); + return str; }
HSTRING __cdecl int8_ToString(const INT8 *this) { - FIXME("(%p): stub!\n", this); - return NULL; + HSTRING str; + + TRACE("(%p)\n", this); + + HSTRING_SPRINTF(&str, L"%d", *this); + return str; }
HSTRING __cdecl uint16_ToString(const UINT16 *this) { - FIXME("(%p): stub!\n", this); - return NULL; + HSTRING str; + + TRACE("(%p)\n", this); + + HSTRING_SPRINTF(&str, L"%u", *this); + return str; }
HSTRING __cdecl uint32_ToString(const UINT32 *this) { - FIXME("(%p): stub!\n", this); - return NULL; + HSTRING str; + + TRACE("(%p)\n", this); + + HSTRING_SPRINTF(&str, L"%u", *this); + return str; }
HSTRING __cdecl uint64_ToString(const UINT64 *this) { - FIXME("(%p): stub!\n", this); - return NULL; + HSTRING str; + + TRACE("(%p)\n", this); + + HSTRING_SPRINTF(&str, L"%I64u", *this); + return str; }
HSTRING __cdecl uint8_ToString(const UINT8 *this) { - FIXME("(%p): stub!\n", this); - return NULL; + HSTRING str; + + TRACE("(%p)\n", this); + + HSTRING_SPRINTF(&str, L"%u", *this); + return str; }
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/except.c | 106 +++++++++++++++++++++++++----- dlls/vccorlib140/tests/vccorlib.c | 10 +-- 2 files changed, 94 insertions(+), 22 deletions(-)
diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index c3cff729be5..29ffbbed79f 100644 --- a/dlls/vccorlib140/except.c +++ b/dlls/vccorlib140/except.c @@ -72,7 +72,7 @@ struct exception_inner struct Exception { IInspectable IInspectable_iface; - const void *IPrintable_iface; + IStringable IPrintable_iface; const void *IEquatable_iface; IClosable IClosable_iface; struct exception_inner inner; @@ -118,6 +118,11 @@ static HRESULT WINAPI Exception_QueryInterface(IInspectable *iface, const GUID * IInspectable_AddRef((*out = &impl->IInspectable_iface)); return S_OK; } + if (IsEqualGUID(iid, &IID_IPrintable)) + { + IStringable_AddRef((*out = &impl->IPrintable_iface)); + return S_OK; + } if (IsEqualGUID(iid, &IID_IClosable)) { IClosable_AddRef((*out = &impl->IClosable_iface)); @@ -244,6 +249,42 @@ COM_VTABLE_ENTRY(Exception_GetRuntimeClassName) COM_VTABLE_ENTRY(Exception_GetTrustLevel) COM_VTABLE_RTTI_END;
+DEFINE_IINSPECTABLE_(Exception_Printable, IStringable, struct Exception, + impl_Exception_from_IStringable, IPrintable_iface, &impl->IInspectable_iface); + +static HRESULT WINAPI Exception_Printable_ToString(IStringable *iface, HSTRING *str) +{ + struct Exception *impl = impl_Exception_from_IStringable(iface); + WCHAR buf[256]; + + TRACE("(%p, %p)\n", iface, str); + + if (impl->inner.restricted_desc) + return WindowsCreateString(impl->inner.restricted_desc, wcslen(impl->inner.restricted_desc), str); + if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, impl->inner.hr, 0, buf, ARRAY_SIZE(buf), NULL)) + return WindowsCreateString(buf, wcslen(buf), str); + else + ERR("FormatMessageW failed: %lu\n", GetLastError()); + *str = NULL; + return S_OK; +} + +DEFINE_RTTI_DATA(Exception_Printable, offsetof(struct Exception, IPrintable_iface), + "?.AVException@Platform@@", + Exception_Object_rtti_base_descriptor, + Exception_IPrintable_rtti_base_descriptor, + Exception_IEquatable_rtti_base_descriptor, + Exception_IClosable_rtti_base_descriptor); +COM_VTABLE_RTTI_START(IStringable, Exception_Printable) +COM_VTABLE_ENTRY(Exception_Printable_QueryInterface) +COM_VTABLE_ENTRY(Exception_Printable_AddRef) +COM_VTABLE_ENTRY(Exception_Printable_Release) +COM_VTABLE_ENTRY(Exception_Printable_GetIids) +COM_VTABLE_ENTRY(Exception_Printable_GetRuntimeClassName) +COM_VTABLE_ENTRY(Exception_Printable_GetTrustLevel) +COM_VTABLE_ENTRY(Exception_Printable_ToString) +COM_VTABLE_RTTI_END; + DEFINE_IINSPECTABLE_(Exception_Closable, IClosable, struct Exception, impl_Exception_from_IClosable, IClosable_iface, &impl->IInspectable_iface);
@@ -293,7 +334,8 @@ struct Exception *__cdecl Exception_ctor(struct Exception *this, HRESULT hr)
this->IInspectable_iface.lpVtbl = &Exception_vtable.vtable; this->IClosable_iface.lpVtbl = &Exception_Closable_vtable.vtable; - this->IEquatable_iface = this->IPrintable_iface = NULL; + this->IPrintable_iface.lpVtbl = &Exception_Printable_vtable.vtable; + this->IEquatable_iface = NULL;
memset(&this->inner, 0, sizeof(this->inner)); base->exception_inner = &this->inner; @@ -357,6 +399,23 @@ COM_VTABLE_ENTRY(Exception_GetRuntimeClassName) COM_VTABLE_ENTRY(Exception_GetTrustLevel) COM_VTABLE_RTTI_END;
+DEFINE_RTTI_DATA(COMException_Printable, offsetof(struct Exception, IPrintable_iface), + "?.AVException@Platform@@", + Exception_rtti_base_descriptor, + Exception_Object_rtti_base_descriptor, + Exception_IPrintable_rtti_base_descriptor, + Exception_IEquatable_rtti_base_descriptor, + Exception_IClosable_rtti_base_descriptor); +COM_VTABLE_RTTI_START(IStringable, COMException_Printable) +COM_VTABLE_ENTRY(Exception_Printable_QueryInterface) +COM_VTABLE_ENTRY(Exception_Printable_AddRef) +COM_VTABLE_ENTRY(Exception_Printable_Release) +COM_VTABLE_ENTRY(Exception_Printable_GetIids) +COM_VTABLE_ENTRY(Exception_Printable_GetRuntimeClassName) +COM_VTABLE_ENTRY(Exception_Printable_GetTrustLevel) +COM_VTABLE_ENTRY(Exception_Printable_ToString) +COM_VTABLE_RTTI_END; + DEFINE_RTTI_DATA(COMException_Closable, offsetof(struct Exception, IClosable_iface), ".?AVCOMException@Platform@@", Exception_rtti_base_descriptor, @@ -381,6 +440,7 @@ struct Exception *__cdecl COMException_ctor(struct Exception *this, HRESULT hr) Exception_ctor(this, hr);
this->IInspectable_iface.lpVtbl = &COMException_vtable.vtable; + this->IPrintable_iface.lpVtbl = &COMException_Printable_vtable.vtable; this->IClosable_iface.lpVtbl = &COMException_Closable_vtable.vtable; this->inner.exception_type = &COMException_ref_exception_type; return this; @@ -393,6 +453,7 @@ struct Exception *__cdecl COMException_hstring_ctor(struct Exception *this, HRES Exception_hstring_ctor(this, hr, msg);
this->IInspectable_iface.lpVtbl = &COMException_vtable.vtable; + this->IPrintable_iface.lpVtbl = &COMException_Printable_vtable.vtable; this->IClosable_iface.lpVtbl = &COMException_Closable_vtable.vtable; this->inner.exception_type = &COMException_ref_exception_type; return this; @@ -425,6 +486,24 @@ struct Exception *__cdecl COMException_hstring_ctor(struct Exception *this, HRES COM_VTABLE_ENTRY(Exception_GetIids) \ COM_VTABLE_ENTRY(Exception_GetRuntimeClassName) \ COM_VTABLE_ENTRY(Exception_GetTrustLevel) \ + COM_VTABLE_RTTI_END; \ + \ + DEFINE_RTTI_DATA(name##Exception_Printable, offsetof(struct Exception, IPrintable_iface), \ + "?.AV" #name "Exception@Platform@@", \ + COMException_rtti_base_descriptor, \ + Exception_rtti_base_descriptor, \ + Exception_Object_rtti_base_descriptor, \ + Exception_IPrintable_rtti_base_descriptor, \ + Exception_IEquatable_rtti_base_descriptor, \ + Exception_IClosable_rtti_base_descriptor); \ + COM_VTABLE_RTTI_START(IStringable, name##Exception_Printable) \ + COM_VTABLE_ENTRY(Exception_Printable_QueryInterface) \ + COM_VTABLE_ENTRY(Exception_Printable_AddRef) \ + COM_VTABLE_ENTRY(Exception_Printable_Release) \ + COM_VTABLE_ENTRY(Exception_Printable_GetIids) \ + COM_VTABLE_ENTRY(Exception_Printable_GetRuntimeClassName) \ + COM_VTABLE_ENTRY(Exception_Printable_GetTrustLevel) \ + COM_VTABLE_ENTRY(Exception_Printable_ToString) \ COM_VTABLE_RTTI_END; \ \ DEFINE_RTTI_DATA(name##Exception_Closable, offsetof(struct Exception, IClosable_iface), \ @@ -450,6 +529,7 @@ struct Exception *__cdecl COMException_hstring_ctor(struct Exception *this, HRES TRACE("(%p)\n", this); \ Exception_ctor(this, hr); \ this->IInspectable_iface.lpVtbl = &name##Exception_vtable.vtable; \ + this->IPrintable_iface.lpVtbl = &name##Exception_Printable_vtable.vtable; \ this->IClosable_iface.lpVtbl = &name##Exception_Closable_vtable.vtable; \ this->inner.exception_type = &name##Exception_ref_exception_type; \ return this; \ @@ -460,6 +540,7 @@ struct Exception *__cdecl COMException_hstring_ctor(struct Exception *this, HRES TRACE("(%p, %s)\n", this, debugstr_hstring(msg)); \ Exception_hstring_ctor(this, hr, msg); \ this->IInspectable_iface.lpVtbl = &name##Exception_vtable.vtable; \ + this->IPrintable_iface.lpVtbl = &name##Exception_Printable_vtable.vtable; \ this->IClosable_iface.lpVtbl = &name##Exception_Closable_vtable.vtable; \ this->inner.exception_type = &name##Exception_ref_exception_type; \ return this; \ @@ -540,24 +621,12 @@ void WINAPI DECLSPEC_NORETURN __abi_WinRTraiseCOMException(HRESULT hr)
HSTRING __cdecl Exception_get_Message(struct Exception *this) { - HSTRING msg = NULL; - HRESULT hr = S_OK; + HSTRING msg; + HRESULT hr;
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)) + if (FAILED((hr = IStringable_ToString(&this->IPrintable_iface, &msg)))) __abi_WinRTraiseCOMException(hr); return msg; } @@ -582,14 +651,17 @@ void init_exception(void *base) INIT_RTTI_BASE(Exception_Object, base); INIT_RTTI(Exception, base); INIT_RTTI(Exception_Closable, base); + INIT_RTTI(Exception_Printable, base);
INIT_CXX_TYPE(COMException_ref, base); INIT_RTTI(COMException, base); + INIT_RTTI(COMException_Printable, base); INIT_RTTI(COMException_Closable, base);
#define WINRT_EXCEPTION(name, hr) \ INIT_CXX_TYPE(name##Exception_ref, base); \ INIT_RTTI(name##Exception, base); \ + INIT_RTTI(name##Exception_Printable, base); \ INIT_RTTI(name##Exception_Closable, base); WINRT_EXCEPTIONS #undef WINRT_EXCEPTION diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index 92e6150ac04..3862c9ca0ff 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -1617,7 +1617,7 @@ static void test_exceptions(void) test_interface_layout(obj, &IID_IUnknown, &obj->IInspectable_iface); test_interface_layout(obj, &IID_IInspectable, &obj->IInspectable_iface); test_interface_layout(obj, &IID_IAgileObject, &obj->IInspectable_iface); - todo_wine test_interface_layout(obj, &IID_IPrintable, &obj->IPrintable_iface); + test_interface_layout(obj, &IID_IPrintable, &obj->IPrintable_iface); todo_wine test_interface_layout(obj, &IID_IEquatable, &obj->IEquatable_iface); test_interface_layout(obj, &IID_IClosable, &obj->IClosable_iface);
@@ -1694,7 +1694,7 @@ static void test_exceptions(void)
str = p__abi_ObjectToString(obj, TRUE); bufW = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(!wcscmp(bufW, buf), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(buf)); + ok(!wcscmp(bufW, buf), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(buf)); WindowsDeleteString(str);
str = p_platform_exception_ToString(obj); @@ -1800,7 +1800,7 @@ static void test_exceptions(void) str = p__abi_ObjectToString(inspectable, TRUE); hr = WindowsCompareStringOrdinal(str, msg, &ret); ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(!ret, "got str %s != %s\n", debugstr_hstring(str), debugstr_hstring(msg)); + ok(!ret, "got str %s != %s\n", debugstr_hstring(str), debugstr_hstring(msg)); WindowsDeleteString(str);
str = p_platform_exception_ToString(inspectable); @@ -1836,7 +1836,7 @@ static void test_exceptions(void) test_interface_layout(obj, &IID_IUnknown, &obj->IInspectable_iface); test_interface_layout(obj, &IID_IInspectable, &obj->IInspectable_iface); test_interface_layout(obj, &IID_IAgileObject, &obj->IInspectable_iface); - todo_wine test_interface_layout(obj, &IID_IPrintable, &obj->IPrintable_iface); + test_interface_layout(obj, &IID_IPrintable, &obj->IPrintable_iface); todo_wine test_interface_layout(obj, &IID_IEquatable, &obj->IEquatable_iface); test_interface_layout(obj, &IID_IClosable, &obj->IClosable_iface); ok((ULONG_PTR)obj->marshal == UINTPTR_MAX, "got marshal %p\n", obj->marshal); @@ -1892,7 +1892,7 @@ static void test_exceptions(void) test_interface_layout(obj, &IID_IUnknown, &obj->IInspectable_iface); test_interface_layout(obj, &IID_IInspectable, &obj->IInspectable_iface); test_interface_layout(obj, &IID_IAgileObject, &obj->IInspectable_iface); - todo_wine test_interface_layout(obj, &IID_IPrintable, &obj->IPrintable_iface); + test_interface_layout(obj, &IID_IPrintable, &obj->IPrintable_iface); todo_wine test_interface_layout(obj, &IID_IEquatable, &obj->IEquatable_iface); test_interface_layout(obj, &IID_IClosable, &obj->IClosable_iface); ok((ULONG_PTR)obj->marshal == UINTPTR_MAX, "got marshal %p\n", obj->marshal);
From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/tests/vccorlib.c | 6 +++--- dlls/vccorlib140/vccorlib.c | 36 ++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index 3862c9ca0ff..64a99e06151 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -1109,7 +1109,7 @@ static void test___abi_make_type_id(void) check_interface(type_obj, &IID_IMarshal); check_interface(type_obj, &IID_IAgileObject); todo_wine check_interface(type_obj, &IID_IEquatable); - todo_wine check_interface(type_obj, &IID_IPrintable); + check_interface(type_obj, &IID_IPrintable);
hr = IInspectable_GetRuntimeClassName(type_obj, &str); ok(hr == S_OK, "got hr %#lx\n", hr); @@ -1143,7 +1143,7 @@ static void test___abi_make_type_id(void)
str = p__abi_ObjectToString(type_obj, TRUE); buf = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(buf && !wcscmp(buf, L"foo"), "got buf %s != %s\n", debugstr_w(buf), debugstr_w(L"foo")); + ok(buf && !wcscmp(buf, L"foo"), "got buf %s != %s\n", debugstr_w(buf), debugstr_w(L"foo")); WindowsDeleteString(str);
type_obj2 = p___abi_make_type_id(&desc); @@ -1179,7 +1179,7 @@ static void test___abi_make_type_id(void) check_interface(type_obj2, &IID_IMarshal); check_interface(type_obj2, &IID_IAgileObject); todo_wine check_interface(type_obj2, &IID_IEquatable); - todo_wine check_interface(type_obj2, &IID_IPrintable); + check_interface(type_obj2, &IID_IPrintable);
equals = p_platform_type_Equals_Object(type_obj2, type_obj); ok(equals, "got equals %d\n", equals); diff --git a/dlls/vccorlib140/vccorlib.c b/dlls/vccorlib140/vccorlib.c index e1652502e74..7704716eb97 100644 --- a/dlls/vccorlib140/vccorlib.c +++ b/dlls/vccorlib140/vccorlib.c @@ -305,6 +305,7 @@ struct __abi_type_descriptor struct platform_type { IInspectable IInspectable_iface; + IStringable IPrintable_iface; IClosable IClosable_iface; IUnknown *marshal; const struct __abi_type_descriptor *desc; @@ -329,6 +330,11 @@ HRESULT WINAPI platform_type_QueryInterface(IInspectable *iface, const GUID *iid IInspectable_AddRef((*out = &impl->IInspectable_iface)); return S_OK; } + if (IsEqualGUID(iid, &IID_IPrintable)) + { + IStringable_AddRef((*out = &impl->IPrintable_iface)); + return S_OK; + } if (IsEqualGUID(iid, &IID_IClosable)) { IClosable_AddRef((*out = &impl->IClosable_iface)); @@ -394,6 +400,29 @@ COM_VTABLE_ENTRY(platform_type_GetRuntimeClassName) COM_VTABLE_ENTRY(platform_type_GetTrustLevel) COM_VTABLE_RTTI_END;
+DEFINE_IINSPECTABLE_(platform_type_printable, IStringable, struct platform_type, + impl_platform_type_from_IStringable, IPrintable_iface, &impl->IInspectable_iface); + +static HRESULT WINAPI platform_type_printable_ToString(IStringable *iface, HSTRING *str) +{ + struct platform_type *impl = impl_platform_type_from_IStringable(iface); + + TRACE("(%p, %p)\n", iface, str); + + return WindowsCreateString(impl->desc->name, impl->desc->name ? wcslen(impl->desc->name ) : 0, str); +} + +DEFINE_RTTI_DATA(platform_type_printable, offsetof(struct platform_type, IPrintable_iface), ".?AVType@Platform@@"); +COM_VTABLE_RTTI_START(IStringable, platform_type_printable) +COM_VTABLE_ENTRY(platform_type_printable_QueryInterface) +COM_VTABLE_ENTRY(platform_type_printable_AddRef) +COM_VTABLE_ENTRY(platform_type_printable_Release) +COM_VTABLE_ENTRY(platform_type_printable_GetIids) +COM_VTABLE_ENTRY(platform_type_printable_GetRuntimeClassName) +COM_VTABLE_ENTRY(platform_type_printable_GetTrustLevel) +COM_VTABLE_ENTRY(platform_type_printable_ToString) +COM_VTABLE_RTTI_END; + DEFINE_IINSPECTABLE(platform_type_closable, IClosable, struct platform_type, IInspectable_iface);
static HRESULT WINAPI platform_type_closable_Close(IClosable *iface) @@ -417,6 +446,7 @@ static void init_platform_type(void *base) { INIT_RTTI(type_info, base); INIT_RTTI(platform_type, base); + INIT_RTTI(platform_type_printable, base); INIT_RTTI(platform_type_closable, base); }
@@ -430,7 +460,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. */ + * Implement IEquatable. */ struct platform_type *obj; HRESULT hr;
@@ -438,6 +468,7 @@ void *WINAPI __abi_make_type_id(const struct __abi_type_descriptor *desc)
obj = Allocate(sizeof(*obj)); obj->IInspectable_iface.lpVtbl = &platform_type_vtable.vtable; + obj->IPrintable_iface.lpVtbl = &platform_type_printable_vtable.vtable; obj->IClosable_iface.lpVtbl = &platform_type_closable_vtable.vtable; obj->desc = desc; obj->ref = 1; @@ -471,8 +502,7 @@ HSTRING __cdecl platform_type_ToString(struct platform_type *this)
TRACE("(%p)\n", this);
- hr = WindowsCreateString(this->desc->name, this->desc->name ? wcslen(this->desc->name) : 0, &str); - if (FAILED(hr)) + if (FAILED(hr = IStringable_ToString(&this->IPrintable_iface, &str))) __abi_WinRTraiseCOMException(hr); return str; }
Piotr Caban (@piotr) commented about dlls/vccorlib140/tests/vccorlib.c:
}}
+struct tostring_impl +{
- IUnknown IUnknown_iface;
- IInspectable IInspectable_iface;
- IStringable IStringable_iface;
Threre's no need to add all of these interfaces separately (please add only IStringtable and hide some interfaces in QueryInterface implementation).
Piotr Caban (@piotr) commented about dlls/vccorlib140/tests/vccorlib.c:
check_interface(obj, &IID_IInspectable); check_interface(obj, &IID_IPropertyValue);
if (!(exp_str = test_cases[i].exp_str)){/* For record-like values, __abi_ObjectToString returns the string from GetRuntimeClassName. */hr = IPropertyValue_GetRuntimeClassName(obj, &name);todo_wine ok(hr == S_OK, "got hr %#lx\n", hr);exp_str = WindowsGetStringRawBuffer(name, NULL);
It's probably not safe to call WindowsGetStringRawBuffer if IPropertyValue::GetRuntimeClassName() fails.
Piotr Caban (@piotr) commented about dlls/vccorlib140/tests/vccorlib.c:
+static HSTRING (*__cdecl p_Guid_ToString)(const GUID *); +#define SIMPLE_TOSTRING_FUNC(name, type) static HSTRING (__cdecl *p_##name##_ToString)(const type *); +#define SIMPLE_TOSTRING_FUNCS \
- SIMPLE_TOSTRING_FUNC(char16, WCHAR) \
- SIMPLE_TOSTRING_FUNC(float32, FLOAT) \
- SIMPLE_TOSTRING_FUNC(float64, DOUBLE) \
- SIMPLE_TOSTRING_FUNC(int16, INT16) \
- SIMPLE_TOSTRING_FUNC(int32, INT32) \
- SIMPLE_TOSTRING_FUNC(int64, INT64) \
- SIMPLE_TOSTRING_FUNC(int8, INT8) \
- SIMPLE_TOSTRING_FUNC(uint16, UINT16) \
- SIMPLE_TOSTRING_FUNC(uint32, UINT32) \
- SIMPLE_TOSTRING_FUNC(uint64, UINT64) \
- SIMPLE_TOSTRING_FUNC(uint8, UINT8)
+SIMPLE_TOSTRING_FUNCS +#undef SIMPLE_TOSTRING_FUNC
I prefer to avoid using too many `define`s since it makes the code much harder to read.
Piotr Caban (@piotr) commented about dlls/vccorlib140/vccorlib.c:
hr = WindowsCreateString(buf, len, &val); \} \break; \- }
switch (type){PROPVAL_SIMPLE(Char16, WCHAR, L"%c")PROPVAL_SIMPLE(UInt8, UINT8, L"%hhu")PROPVAL_SIMPLE(Int16, INT16, L"%hd")PROPVAL_SIMPLE(UInt16, UINT16, L"%hu")PROPVAL_SIMPLE(Int32, INT32, L"%I32d")PROPVAL_SIMPLE(UInt32, UINT32, L"%I32u")PROPVAL_SIMPLE(Int64, INT64, L"%I64d")PROPVAL_SIMPLE(UInt64, UINT64, L"%I64u")PROPVAL_SIMPLE(Single, FLOAT, L"%g")PROPVAL_SIMPLE(Double, DOUBLE, L"%g")
Can we use `*_ToString()` functions here?
Piotr Caban (@piotr) commented about dlls/vccorlib140/vccorlib.c:
return val;}
+#define HSTRING_SPRINTF(out, fmt, ...) do { \
Please use a function instead:
`static HRESULT hstring_sprintf(HSTRING *hstr, const WCHAR *fmt, ...)`
Piotr Caban (@piotr) commented about dlls/vccorlib140/vccorlib.c:
{
- FIXME("(%p, %d): stub!\n", obj, try_stringable);
- return NULL;
- IInspectable *inspectable;
- IPropertyValue *propval;
- IStringable *stringable;
- HSTRING val = NULL;
- HRESULT hr = S_OK;
- TRACE("(%p, %d)\n", obj, try_stringable);
- if (!obj) return NULL;
- /* If try_stringable is true, native will first query for IStringable, and then IPrintable (which is just an alias
* for IStringable). */- if (try_stringable && (SUCCEEDED(IUnknown_QueryInterface(obj, &IID_IStringable, (void **)&stringable)) ||
SUCCEEDED(IUnknown_QueryInterface(obj, &IID_IPrintable, (void **)&stringable))))
Did you check what happens if QueryInterface succeeds and sets stringable to NULL?
On Mon Nov 10 11:44:40 2025 +0000, Piotr Caban wrote:
It's probably not safe to call WindowsGetStringRawBuffer if IPropertyValue::GetRuntimeClassName() fails.
`NULL` is a valid `HSTRING`, so WindowsGetStringRawBuffer returns an empty wide string in that case.
On Mon Nov 10 11:44:41 2025 +0000, Piotr Caban wrote:
Can we use `*_ToString()` functions here?
Yes, I have rewritten this to use them in the latest revision, thanks.
On Mon Nov 10 11:44:41 2025 +0000, Piotr Caban wrote:
I prefer to avoid using too many `define`s since it makes the code much harder to read.
Sure, I have removed them.
On Mon Nov 10 11:44:40 2025 +0000, Piotr Caban wrote:
Threre's no need to add all of these interfaces separately (please add only IStringtable and hide some interfaces in QueryInterface implementation).
Sure, thanks.
On Mon Nov 10 11:44:42 2025 +0000, Piotr Caban wrote:
Please use a function instead: `static HRESULT hstring_sprintf(HSTRING *hstr, const WCHAR *fmt, ...)`
Rewritten, thanks.
On Mon Nov 10 11:44:42 2025 +0000, Piotr Caban wrote:
Did you check what happens if QueryInterface succeeds and sets stringable to NULL?
I hadn't, but it crashes with an access violation. Wouldn't returning a NULL and S_OK be invalid behavior in COM, are there other functions in native that do check for this?