From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/private.h | 2 + dlls/vccorlib140/tests/vccorlib.c | 31 ++++++------ dlls/vccorlib140/vccorlib.c | 81 ++++++++++++++++++++++++++++--- 3 files changed, 92 insertions(+), 22 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 a19f6f86d2a..973335dcaaf 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -1164,8 +1164,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); @@ -1353,12 +1352,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); } WindowsDeleteString(name); @@ -1452,12 +1451,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); @@ -1658,8 +1657,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. */ @@ -1820,8 +1819,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); @@ -2080,11 +2079,11 @@ static void test___abi_ObjectToString(void) impl.have_inspectable = TRUE; str = p__abi_ObjectToString(&impl.IStringable_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.IStringable_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 @@ -2092,11 +2091,11 @@ static void test___abi_ObjectToString(void) impl.have_stringable = TRUE; str = p__abi_ObjectToString(&impl.IStringable_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.IStringable_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. */ @@ -2104,11 +2103,11 @@ static void test___abi_ObjectToString(void) impl.have_printable = TRUE; str = p__abi_ObjectToString(&impl.IStringable_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.IStringable_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 85ec1a2ef27..2e3cbbd74ea 100644 --- a/dlls/vccorlib140/vccorlib.c +++ b/dlls/vccorlib140/vccorlib.c @@ -611,12 +611,6 @@ 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; -} - static HRESULT hstring_sprintf(HSTRING *out, const WCHAR *fmt, ...) { WCHAR buf[100]; @@ -790,6 +784,81 @@ HSTRING __cdecl uint8_ToString(const UINT8 *this) return str; }
+HSTRING WINAPI __abi_ObjectToString(IUnknown *obj, bool try_stringable) +{ + 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; + + if (SUCCEEDED((hr = IPropertyValue_get_Type(propval, &type)))) + { +#define PROPVAL_SIMPLE(prop_type, pfx, c_type) \ + case PropertyType_##prop_type: \ + { \ + c_type prop_type_##val; \ + if (SUCCEEDED(hr = IPropertyValue_Get##prop_type(propval, &prop_type_##val))) \ + { \ + IPropertyValue_Release(propval); \ + return pfx##_ToString(&prop_type_##val); \ + } \ + break; \ + } + switch (type) + { + PROPVAL_SIMPLE(Char16, char16, WCHAR) + PROPVAL_SIMPLE(UInt8, uint8, UINT8) + PROPVAL_SIMPLE(Int16, int16, INT16) + PROPVAL_SIMPLE(UInt16, uint16, UINT16) + PROPVAL_SIMPLE(Int32, int32, INT32) + PROPVAL_SIMPLE(UInt32, uint32, UINT32) + PROPVAL_SIMPLE(Int64, int64, INT64) + PROPVAL_SIMPLE(UInt64, uint64, UINT64) + PROPVAL_SIMPLE(Single, float32, FLOAT) + PROPVAL_SIMPLE(Double, float64, DOUBLE) + PROPVAL_SIMPLE(Boolean, Boolean, boolean) + PROPVAL_SIMPLE(Guid, Guid, GUID) + case PropertyType_String: + hr = IPropertyValue_GetString(propval, &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; +} + BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { if (reason == DLL_PROCESS_ATTACH)