From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/tests/vccorlib.c | 32 ++++---- dlls/vccorlib140/vccorlib.c | 120 +++++++++++++++++++++++++++++- 2 files changed, 134 insertions(+), 18 deletions(-)
diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index bef246f2760..cafe95faf77 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -680,30 +680,30 @@ static void test___abi_make_type_id(void) HRESULT hr;
type_obj = p___abi_make_type_id(&desc); - todo_wine ok(type_obj != NULL, "got type_obj %p\n", type_obj); + ok(type_obj != NULL, "got type_obj %p\n", type_obj); if (!type_obj) { skip("__abi_make_type_id failed\n"); return; }
- todo_wine check_interface(type_obj, &IID_IInspectable); - todo_wine check_interface(type_obj, &IID_IClosable); - todo_wine check_interface(type_obj, &IID_IMarshal); - todo_wine check_interface(type_obj, &IID_IAgileObject); + check_interface(type_obj, &IID_IInspectable); + check_interface(type_obj, &IID_IClosable); + 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);
hr = IInspectable_GetRuntimeClassName(type_obj, &str); ok(hr == S_OK, "got hr %#lx\n", hr); buf = WindowsGetStringRawBuffer(str, NULL); - todo_wine ok(buf && !wcscmp(buf, L"Platform.Type"), "got buf %s\n", debugstr_w(buf)); + ok(buf && !wcscmp(buf, L"Platform.Type"), "got buf %s\n", debugstr_w(buf)); WindowsDeleteString(str);
equals = p_platform_type_Equals_Object(type_obj, type_obj); todo_wine ok(equals, "got equals %d\n", equals); equals = p_platform_type_Equals_Object(type_obj, NULL); - todo_wine ok(!equals, "got equals %d\n", equals); + ok(!equals, "got equals %d\n", equals);
typecode = p_platform_type_GetTypeCode(type_obj); todo_wine ok(typecode == 0xdeadbeef, "got typecode %d\n", typecode); @@ -720,13 +720,13 @@ static void test___abi_make_type_id(void) WindowsDeleteString(str);
type_obj2 = p___abi_make_type_id(&desc); - todo_wine ok(type_obj2 != NULL, "got type_obj %p\n", type_obj); + ok(type_obj2 != NULL, "got type_obj %p\n", type_obj); ok(type_obj2 != type_obj, "got type_obj2 %p\n", type_obj2);
- todo_wine check_interface(type_obj2, &IID_IInspectable); - todo_wine check_interface(type_obj2, &IID_IClosable); - todo_wine check_interface(type_obj2, &IID_IMarshal); - todo_wine check_interface(type_obj2, &IID_IAgileObject); + check_interface(type_obj2, &IID_IInspectable); + check_interface(type_obj2, &IID_IClosable); + 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);
@@ -740,20 +740,20 @@ static void test___abi_make_type_id(void) todo_wine ok(equals, "got equals %d\n", equals);
type_obj = p___abi_make_type_id(&desc2); - todo_wine ok(type_obj != NULL, "got type_obj %p\n", type_obj); + ok(type_obj != NULL, "got type_obj %p\n", type_obj);
/* Platform::Type::Equals only seems to compare the value of the __abi_type_descriptor pointer. */ equals = p_platform_type_Equals_Object(type_obj, type_obj2); - todo_wine ok(!equals, "got equals %d\n", equals); + ok(!equals, "got equals %d\n", equals);
count = IInspectable_Release(type_obj); ok(count == 0, "got count %lu\n", count);
type_obj = p___abi_make_type_id(&desc3); - todo_wine ok(type_obj != NULL, "got type_obj %p\n", type_obj); + ok(type_obj != NULL, "got type_obj %p\n", type_obj);
equals = p_platform_type_Equals_Object(type_obj, type_obj2); - todo_wine ok(!equals, "got equals %d\n", equals); + ok(!equals, "got equals %d\n", equals);
typecode = p_platform_type_GetTypeCode(type_obj); todo_wine ok(typecode == 1, "got typecode %d\n", typecode); diff --git a/dlls/vccorlib140/vccorlib.c b/dlls/vccorlib140/vccorlib.c index 9cccd2533d6..27ccdfe178c 100644 --- a/dlls/vccorlib140/vccorlib.c +++ b/dlls/vccorlib140/vccorlib.c @@ -25,6 +25,8 @@ #include "roapi.h" #include "weakreference.h" #include "winstring.h" +#define WIDL_using_Windows_Foundation +#include "windows.foundation.h" #include "wine/asm.h" #include "wine/debug.h"
@@ -232,6 +234,102 @@ struct __abi_type_descriptor int type_id; };
+struct platform_type +{ + IClosable IClosable_iface; + IUnknown *marshal; + const struct __abi_type_descriptor *desc; + LONG ref; +}; + +static inline struct platform_type *impl_from_IClosable(IClosable *iface) +{ + return CONTAINING_RECORD(iface, struct platform_type, IClosable_iface); +} + +static HRESULT WINAPI platform_type_QueryInterface(IClosable *iface, const GUID *iid, void **out) +{ + struct platform_type *impl = impl_from_IClosable(iface); + + TRACE("(%p, %s, %p)\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IInspectable) || + IsEqualGUID(iid, &IID_IClosable) || + IsEqualGUID(iid, &IID_IAgileObject)) + { + IClosable_AddRef((*out = &impl->IClosable_iface)); + return S_OK; + } + if (IsEqualGUID(iid, &IID_IMarshal)) + return IUnknown_QueryInterface(impl->marshal, iid, out); + + ERR("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI platform_type_AddRef(IClosable *iface) +{ + struct platform_type *impl = impl_from_IClosable(iface); + TRACE("(%p)\n", iface); + return InterlockedIncrement(&impl->ref); +} + +static ULONG WINAPI platform_type_Release(IClosable *iface) +{ + struct platform_type *impl = impl_from_IClosable(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + + TRACE("(%p)\n", iface); + + if (!ref) + { + IUnknown_Release(impl->marshal); + Free(impl); + } + return ref; +} + +static HRESULT WINAPI platform_type_GetIids(IClosable *iface, ULONG *count, GUID **iids) +{ + FIXME("(%p, %p, %p) stub\n", iface, count, iids); + return E_NOTIMPL; +} + +static HRESULT WINAPI platform_type_GetRuntimeClassName(IClosable *iface, HSTRING *name) +{ + static const WCHAR *str = L"Platform.Type"; + + TRACE("(%p, %p)\n", iface, name); + return WindowsCreateString(str, wcslen(str), name); +} + +static HRESULT WINAPI platform_type_GetTrustLevel(IClosable *iface, TrustLevel *level) +{ + FIXME("(%p, %p) stub\n", iface, level); + return E_NOTIMPL; +} + +static HRESULT WINAPI platform_type_Close(IClosable *iface) +{ + FIXME("(%p) stub\n", iface); + return E_NOTIMPL; +} + +static const IClosableVtbl platform_type_vtbl = +{ + /* IUnknown */ + platform_type_QueryInterface, + platform_type_AddRef, + platform_type_Release, + platform_type_GetIids, + platform_type_GetRuntimeClassName, + platform_type_GetTrustLevel, + platform_type_Close, + +}; + static const char *debugstr_abi_type_descriptor(const struct __abi_type_descriptor *desc) { if (!desc) return "(null)"; @@ -241,9 +339,27 @@ static const char *debugstr_abi_type_descriptor(const struct __abi_type_descript
void *WINAPI __abi_make_type_id(const struct __abi_type_descriptor *desc) { - FIXME("(%s) stub\n", debugstr_abi_type_descriptor(desc)); + /* TODO: + * Emit RTTI for Platform::Type. + * Implement IEquatable and IPrintable. + * Throw a COMException if CoCreateFreeThreadedMarshaler fails. */ + struct platform_type *obj; + HRESULT hr;
- return NULL; + TRACE("(%s)\n", debugstr_abi_type_descriptor(desc)); + + obj = Allocate(sizeof(*obj)); + obj->IClosable_iface.lpVtbl = &platform_type_vtbl; + obj->desc = desc; + obj->ref = 1; + hr = CoCreateFreeThreadedMarshaler((IUnknown *)&obj->IClosable_iface, &obj->marshal); + if (FAILED(hr)) + { + FIXME("CoCreateFreeThreadedMarshaler failed: %#lx\n", hr); + Free(obj); + return NULL; + } + return &obj->IClosable_iface; }
bool __cdecl platform_type_Equals_Object(void *this, void *object)