From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/tests/vccorlib.c | 75 ++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-)
diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index 7750794d93e..3c09de93bcc 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -72,6 +72,7 @@ struct thiscall_thunk #pragma pack( pop )
static ULONG_PTR (WINAPI *call_thiscall_func1)(void *func, void *this); +static ULONG_PTR (WINAPI *call_thiscall_func2)(void *func, void *this, void *arg1);
static void init_thiscall_thunk(void) { @@ -82,16 +83,19 @@ static void init_thiscall_thunk(void) thunk->push_eax = 0x50; /* pushl %eax */ thunk->jmp_edx = 0xe2ff; /* jmp *%edx */ call_thiscall_func1 = (void *)thunk; + call_thiscall_func2 = (void *)thunk; }
#define __thiscall __stdcall #define call_func1(func,_this) call_thiscall_func1(func,_this) +#define call_func2(func,_this,arg1) call_thiscall_func2(func, _this, arg1)
#else
#define init_thiscall_thunk() #define __thiscall __cdecl #define call_func1(func,_this) func(_this) +#define call_func2(func,_this,arg1) func(_this,arg1)
#endif /* __i386__ */
@@ -127,9 +131,17 @@ static HSTRING (__cdecl *p_platform_type_ToString)(void *); static HSTRING (__cdecl *p_platform_type_get_FullName)(void *); static void *(WINAPI *pCreateValue)(int type, const void *);
+static void *(__cdecl *p__RTtypeid)(const void *); +static const char *(__thiscall *p_type_info_name)(void *); +static const char *(__thiscall *p_type_info_raw_name)(void *); +static void (__thiscall *p_type_info_dtor)(void *); +static int (__thiscall *p_type_info_opequals_equals)(void *, void *); +static int (__thiscall *p_type_info_opnot_equals)(void *, void *); + static BOOL init(void) { HMODULE hmod = LoadLibraryA("vccorlib140.dll"); + HMODULE msvcrt = LoadLibraryA("msvcrt.dll");
if (!hmod) { @@ -160,6 +172,12 @@ static BOOL init(void) p_platform_type_ToString = (void *)GetProcAddress(hmod, "?ToString@Type@Platform@@U$AAAP$AAVString@2@XZ"); p_platform_type_get_FullName = (void *)GetProcAddress(hmod, "?get@FullName@Type@Platform@@Q$AAAP$AAVString@3@XZ"); pCreateValue = (void *)GetProcAddress(hmod, "?CreateValue@Details@Platform@@YAP$AAVObject@2@W4TypeCode@2@PBX@Z"); + p__RTtypeid = (void *)GetProcAddress(msvcrt, "__RTtypeid"); + p_type_info_name = (void *)GetProcAddress(msvcrt, "?name@type_info@@QBAPBDXZ"); + p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name@type_info@@QBAPBDXZ"); + p_type_info_dtor = (void *)GetProcAddress(msvcrt, "??1type_info@@UAA@XZ"); + p_type_info_opequals_equals = (void *)GetProcAddress(msvcrt, "??8type_info@@QBAHABV0@@Z"); + p_type_info_opnot_equals = (void *)GetProcAddress(msvcrt, "??9type_info@@QBAHABV0@@Z"); #else if (sizeof(void *) == 8) { @@ -181,6 +199,12 @@ static BOOL init(void) "?get@FullName@Type@Platform@@QE$AAAPE$AAVString@3@XZ"); pCreateValue = (void *)GetProcAddress(hmod, "?CreateValue@Details@Platform@@YAPE$AAVObject@2@W4TypeCode@2@PEBX@Z"); + p__RTtypeid = (void *)GetProcAddress(msvcrt, "__RTtypeid"); + 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_dtor = (void *)GetProcAddress(msvcrt, "??1type_info@@UEAA@XZ"); + p_type_info_opequals_equals = (void *)GetProcAddress(msvcrt, "??8type_info@@QEBAHAEBV0@@Z"); + p_type_info_opnot_equals = (void *)GetProcAddress(msvcrt, "??9type_info@@QEBAHAEBV0@@Z"); } else { @@ -201,6 +225,12 @@ static BOOL init(void) "?get@FullName@Type@Platform@@Q$AAAP$AAVString@3@XZ"); pCreateValue = (void *)GetProcAddress(hmod, "?CreateValue@Details@Platform@@YGP$AAVObject@2@W4TypeCode@2@PBX@Z"); + p__RTtypeid = (void *)GetProcAddress(msvcrt, "__RTtypeid"); + p_type_info_name = (void *)GetProcAddress(msvcrt, "?name@type_info@@QBEPBDXZ"); + p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name@type_info@@QBEPBDXZ"); + p_type_info_dtor = (void *)GetProcAddress(msvcrt, "??1type_info@@UAE@XZ"); + p_type_info_opequals_equals = (void *)GetProcAddress(msvcrt, "??8type_info@@QBEHABV0@@Z"); + p_type_info_opnot_equals = (void *)GetProcAddress(msvcrt, "??9type_info@@QBEHABV0@@Z"); } #endif ok(pGetActivationFactoryByPCWSTR != NULL, "GetActivationFactoryByPCWSTR not available\n"); @@ -216,6 +246,13 @@ static BOOL init(void) ok(p_platform_type_get_FullName != NULL, "Platform::Type::FullName not available\n"); ok(pCreateValue != NULL, "CreateValue not available\n");
+ ok(p__RTtypeid != NULL, "__RTtypeid 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"); + ok(p_type_info_dtor != NULL, "type_info::~type_info not available\n"); + ok(p_type_info_opequals_equals != NULL, "type_info::operator== not available\n"); + ok(p_type_info_opnot_equals != NULL, "type_info::operator!= not available\n"); + init_thiscall_thunk();
return TRUE; @@ -678,9 +715,11 @@ DEFINE_GUID(IID_IPrintable,0xde0cbaeb,0x8065,0x4a45,0x96,0xb1,0xc9,0xd4,0x43,0xf static void test___abi_make_type_id(void) { const struct __abi_type_descriptor desc = {L"foo", 0xdeadbeef}, desc2 = {L"foo", 0xdeadbeef}, desc3 = {NULL, 1}; - void *type_obj, *type_obj2; + void *type_obj, *type_obj2, *type_info, *type_info2; + const char *name, *raw_name; + IClosable *closable; + int typecode, ret; const WCHAR *buf; - int typecode; HSTRING str; ULONG count; bool equals; @@ -730,6 +769,38 @@ static void test___abi_make_type_id(void) ok(type_obj2 != NULL, "got type_obj %p\n", type_obj); ok(type_obj2 != type_obj, "got type_obj2 %p\n", type_obj2);
+ type_info = p__RTtypeid(type_obj); + todo_wine ok(type_info != NULL, "got type_info %p\n", type_info); + if (type_info) + { + name = (char *)call_func1(p_type_info_name, type_info); + ok(!strcmp(name, "class Platform::Type"), "got name %s\n", debugstr_a(name)); + raw_name = (char *)call_func1(p_type_info_raw_name, type_info); + ok(!strcmp(raw_name, ".?AVType@Platform@@"), "got raw_name %s\n", debugstr_a(raw_name)); + } + + hr = IInspectable_QueryInterface(type_obj, &IID_IClosable, (void **)&closable); + ok(hr == S_OK, "got hr %#lx\n", hr); + type_info2 = p__RTtypeid(closable); + todo_wine ok(type_info2 != NULL, "got type_info %p\n", type_info2); + if (type_info2) + { + name = (char *)call_func1(p_type_info_name, type_info2); + ok(!strcmp(name, "class Platform::Type"), "got name %s\n", debugstr_a(name)); + + raw_name = (char *)call_func1(p_type_info_raw_name, type_info2); + ok(!strcmp(raw_name, ".?AVType@Platform@@"), "got raw_name %s\n", debugstr_a(raw_name)); + + ret = call_func2(p_type_info_opequals_equals, type_info, type_info2); + ok(ret, "got ret %d\n", ret); + ret = call_func2(p_type_info_opnot_equals, type_info, type_info2); + ok(!ret, "got ret %d\n", ret); + + call_func1(p_type_info_dtor, type_info); + call_func1(p_type_info_dtor, type_info2); + } + IClosable_Release(closable); + check_interface(type_obj2, &IID_IInspectable); check_interface(type_obj2, &IID_IClosable); check_interface(type_obj2, &IID_IMarshal);
From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/Makefile.in | 1 + dlls/vccorlib140/private.h | 64 ++++++++++++++++++++++ dlls/vccorlib140/tests/vccorlib.c | 4 +- dlls/vccorlib140/vccorlib.c | 88 +++++++++++++++++++++---------- 4 files changed, 126 insertions(+), 31 deletions(-) create mode 100644 dlls/vccorlib140/private.h
diff --git a/dlls/vccorlib140/Makefile.in b/dlls/vccorlib140/Makefile.in index 13d54aa369e..f75bad3e9d0 100644 --- a/dlls/vccorlib140/Makefile.in +++ b/dlls/vccorlib140/Makefile.in @@ -1,5 +1,6 @@ MODULE = vccorlib140.dll IMPORTS = combase +PARENTSRC = ../msvcrt
SOURCES = \ vccorlib.c diff --git a/dlls/vccorlib140/private.h b/dlls/vccorlib140/private.h new file mode 100644 index 00000000000..03f6b29fad7 --- /dev/null +++ b/dlls/vccorlib140/private.h @@ -0,0 +1,64 @@ +/* + * Copyright 2025 Vibhav Pant + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COM_VTABLE_RTTI_START(iface, type) \ + extern const rtti_object_locator type##_rtti; \ + static const struct \ + { \ + const rtti_object_locator *locator; \ + iface##Vtbl vtable; \ + } type##_vtable = {&(type##_rtti), { +#define COM_VTABLE_ENTRY(func) (func), +#define COM_VTABLE_RTTI_END }} + +#define DEFINE_IINSPECTABLE_(pfx, iface_type, impl_type, impl_from, iface_mem, expr) \ + static inline impl_type *impl_from(iface_type *iface) { return CONTAINING_RECORD(iface, impl_type, iface_mem); } \ + static HRESULT WINAPI pfx##_QueryInterface(iface_type *iface, const GUID *iid, void **out) \ + { \ + impl_type *impl = impl_from(iface); \ + return IInspectable_QueryInterface((IInspectable *)(expr), iid, out); \ + } \ + static ULONG WINAPI pfx##_AddRef(iface_type *iface) \ + { \ + impl_type *impl = impl_from(iface); \ + return IInspectable_AddRef((IInspectable *)(expr)); \ + } \ + static ULONG WINAPI pfx##_Release(iface_type *iface) \ + { \ + impl_type *impl = impl_from(iface); \ + return IInspectable_Release((IInspectable *)(expr)); \ + } \ + static HRESULT WINAPI pfx##_GetIids(iface_type *iface, ULONG *iid_count, IID **iids) \ + { \ + impl_type *impl = impl_from(iface); \ + return IInspectable_GetIids((IInspectable *)(expr), iid_count, iids); \ + } \ + static HRESULT WINAPI pfx##_GetRuntimeClassName(iface_type *iface, HSTRING *class_name) \ + { \ + impl_type *impl = impl_from(iface); \ + return IInspectable_GetRuntimeClassName((IInspectable *)(expr), class_name); \ + } \ + static HRESULT WINAPI pfx##_GetTrustLevel(iface_type *iface, TrustLevel *trust_level) \ + { \ + impl_type *impl = impl_from(iface); \ + return IInspectable_GetTrustLevel((IInspectable *)(expr), trust_level); \ + } +#define DEFINE_IINSPECTABLE(pfx, iface_type, impl_type, base_iface) \ + 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) diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index 3c09de93bcc..8b7d40674c0 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -770,7 +770,7 @@ static void test___abi_make_type_id(void) ok(type_obj2 != type_obj, "got type_obj2 %p\n", type_obj2);
type_info = p__RTtypeid(type_obj); - todo_wine ok(type_info != NULL, "got type_info %p\n", type_info); + ok(type_info != NULL, "got type_info %p\n", type_info); if (type_info) { name = (char *)call_func1(p_type_info_name, type_info); @@ -782,7 +782,7 @@ static void test___abi_make_type_id(void) hr = IInspectable_QueryInterface(type_obj, &IID_IClosable, (void **)&closable); ok(hr == S_OK, "got hr %#lx\n", hr); type_info2 = p__RTtypeid(closable); - todo_wine ok(type_info2 != NULL, "got type_info %p\n", type_info2); + ok(type_info2 != NULL, "got type_info %p\n", type_info2); if (type_info2) { name = (char *)call_func1(p_type_info_name, type_info2); diff --git a/dlls/vccorlib140/vccorlib.c b/dlls/vccorlib140/vccorlib.c index 39877f407bb..a4535486f84 100644 --- a/dlls/vccorlib140/vccorlib.c +++ b/dlls/vccorlib140/vccorlib.c @@ -30,8 +30,13 @@ #include "wine/asm.h" #include "wine/debug.h"
+#include "cxx.h" +#include "private.h" + WINE_DEFAULT_DEBUG_CHANNEL(vccorlib);
+CREATE_TYPE_INFO_VTABLE + HRESULT __cdecl InitializeData(int type) { HRESULT hres; @@ -236,20 +241,21 @@ struct __abi_type_descriptor
struct platform_type { + IInspectable IInspectable_iface; IClosable IClosable_iface; IUnknown *marshal; const struct __abi_type_descriptor *desc; LONG ref; };
-static inline struct platform_type *impl_from_IClosable(IClosable *iface) +static inline struct platform_type *impl_from_IInspectable(IInspectable *iface) { - return CONTAINING_RECORD(iface, struct platform_type, IClosable_iface); + return CONTAINING_RECORD(iface, struct platform_type, IInspectable_iface); }
-static HRESULT WINAPI platform_type_QueryInterface(IClosable *iface, const GUID *iid, void **out) +HRESULT WINAPI platform_type_QueryInterface(IInspectable *iface, const GUID *iid, void **out) { - struct platform_type *impl = impl_from_IClosable(iface); + struct platform_type *impl = impl_from_IInspectable(iface);
TRACE("(%p, %s, %p)\n", iface, debugstr_guid(iid), out);
@@ -258,7 +264,7 @@ static HRESULT WINAPI platform_type_QueryInterface(IClosable *iface, const GUID IsEqualGUID(iid, &IID_IClosable) || IsEqualGUID(iid, &IID_IAgileObject)) { - IClosable_AddRef((*out = &impl->IClosable_iface)); + IInspectable_AddRef((*out = &impl->IInspectable_iface)); return S_OK; } if (IsEqualGUID(iid, &IID_IMarshal)) @@ -269,16 +275,16 @@ static HRESULT WINAPI platform_type_QueryInterface(IClosable *iface, const GUID return E_NOINTERFACE; }
-static ULONG WINAPI platform_type_AddRef(IClosable *iface) +static ULONG WINAPI platform_type_AddRef(IInspectable *iface) { - struct platform_type *impl = impl_from_IClosable(iface); + struct platform_type *impl = impl_from_IInspectable(iface); TRACE("(%p)\n", iface); return InterlockedIncrement(&impl->ref); }
-static ULONG WINAPI platform_type_Release(IClosable *iface) +static ULONG WINAPI platform_type_Release(IInspectable *iface) { - struct platform_type *impl = impl_from_IClosable(iface); + struct platform_type *impl = impl_from_IInspectable(iface); ULONG ref = InterlockedDecrement(&impl->ref);
TRACE("(%p)\n", iface); @@ -291,13 +297,13 @@ static ULONG WINAPI platform_type_Release(IClosable *iface) return ref; }
-static HRESULT WINAPI platform_type_GetIids(IClosable *iface, ULONG *count, GUID **iids) +static HRESULT WINAPI platform_type_GetIids(IInspectable *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 HRESULT WINAPI platform_type_GetRuntimeClassName(IInspectable *iface, HSTRING *name) { static const WCHAR *str = L"Platform.Type";
@@ -305,31 +311,47 @@ static HRESULT WINAPI platform_type_GetRuntimeClassName(IClosable *iface, HSTRIN return WindowsCreateString(str, wcslen(str), name); }
-static HRESULT WINAPI platform_type_GetTrustLevel(IClosable *iface, TrustLevel *level) +static HRESULT WINAPI platform_type_GetTrustLevel(IInspectable *iface, TrustLevel *level) { FIXME("(%p, %p) stub\n", iface, level); return E_NOTIMPL; }
-static HRESULT WINAPI platform_type_Close(IClosable *iface) +DEFINE_RTTI_DATA(platform_type, 0, ".?AVType@Platform@@"); +COM_VTABLE_RTTI_START(IInspectable, platform_type) +COM_VTABLE_ENTRY(platform_type_QueryInterface) +COM_VTABLE_ENTRY(platform_type_AddRef) +COM_VTABLE_ENTRY(platform_type_Release) +COM_VTABLE_ENTRY(platform_type_GetIids) +COM_VTABLE_ENTRY(platform_type_GetRuntimeClassName) +COM_VTABLE_ENTRY(platform_type_GetTrustLevel) +COM_VTABLE_RTTI_END; + +DEFINE_IINSPECTABLE(platform_type_closable, IClosable, struct platform_type, IInspectable_iface); + +static HRESULT WINAPI platform_type_closable_Close(IClosable *iface) { FIXME("(%p) stub\n", iface); return E_NOTIMPL; }
-static const IClosableVtbl platform_type_closable_vtbl = -{ - /* IUnknown */ - platform_type_QueryInterface, - platform_type_AddRef, - platform_type_Release, - /* IInspectable */ - platform_type_GetIids, - platform_type_GetRuntimeClassName, - platform_type_GetTrustLevel, - /* ICloseable */ - platform_type_Close -}; +DEFINE_RTTI_DATA(platform_type_closable, sizeof(IInspectable), ".?AVType@Platform@@", platform_type_rtti_base_descriptor); +COM_VTABLE_RTTI_START(IClosable, platform_type_closable) +COM_VTABLE_ENTRY(platform_type_closable_QueryInterface) +COM_VTABLE_ENTRY(platform_type_closable_AddRef) +COM_VTABLE_ENTRY(platform_type_closable_Release) +COM_VTABLE_ENTRY(platform_type_closable_GetIids) +COM_VTABLE_ENTRY(platform_type_closable_GetRuntimeClassName) +COM_VTABLE_ENTRY(platform_type_closable_GetTrustLevel) +COM_VTABLE_ENTRY(platform_type_closable_Close) +COM_VTABLE_RTTI_END; + +static void init_platform_type(void *base) +{ + INIT_RTTI(type_info, base); + INIT_RTTI(platform_type, base); + INIT_RTTI(platform_type_closable, base); +}
static const char *debugstr_abi_type_descriptor(const struct __abi_type_descriptor *desc) { @@ -350,17 +372,18 @@ void *WINAPI __abi_make_type_id(const struct __abi_type_descriptor *desc) TRACE("(%s)\n", debugstr_abi_type_descriptor(desc));
obj = Allocate(sizeof(*obj)); - obj->IClosable_iface.lpVtbl = &platform_type_closable_vtbl; + obj->IInspectable_iface.lpVtbl = &platform_type_vtable.vtable; + obj->IClosable_iface.lpVtbl = &platform_type_closable_vtable.vtable; obj->desc = desc; obj->ref = 1; - hr = CoCreateFreeThreadedMarshaler((IUnknown *)&obj->IClosable_iface, &obj->marshal); + hr = CoCreateFreeThreadedMarshaler((IUnknown *)&obj->IInspectable_iface, &obj->marshal); if (FAILED(hr)) { FIXME("CoCreateFreeThreadedMarshaler failed: %#lx\n", hr); Free(obj); return NULL; } - return &obj->IClosable_iface; + return &obj->IInspectable_iface; }
bool __cdecl platform_type_Equals_Object(struct platform_type *this, struct platform_type *object) @@ -530,3 +553,10 @@ void *WINAPI CreateValue(int typecode, const void *val) } return obj; } + +BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) +{ + if (reason == DLL_PROCESS_ATTACH) + init_platform_type(inst); + return TRUE; +}
Piotr Caban (@piotr) commented about dlls/vccorlib140/tests/vccorlib.c:
p_platform_type_ToString = (void *)GetProcAddress(hmod, "?ToString@Type@Platform@@U$AAAP$AAVString@2@XZ"); p_platform_type_get_FullName = (void *)GetProcAddress(hmod, "?get@FullName@Type@Platform@@Q$AAAP$AAVString@3@XZ"); pCreateValue = (void *)GetProcAddress(hmod, "?CreateValue@Details@Platform@@YAP$AAVObject@2@W4TypeCode@2@PBX@Z");
- p__RTtypeid = (void *)GetProcAddress(msvcrt, "__RTtypeid");
Please move `p__RTtypeid` initialization out of architecture specific cases - function uses the same name on all architectures.
Piotr Caban (@piotr) commented about dlls/vccorlib140/tests/vccorlib.c:
ok(type_obj2 != type_obj, "got type_obj2 %p\n", type_obj2); type_info = p__RTtypeid(type_obj);
- todo_wine ok(type_info != NULL, "got type_info %p\n", type_info);
- ok(type_info != NULL, "got type_info %p\n", type_info); if (type_info)
`type_info` is not NULL now, you can remove the `if` check.
Piotr Caban (@piotr) commented about dlls/vccorlib140/Makefile.in:
MODULE = vccorlib140.dll IMPORTS = combase +PARENTSRC = ../msvcrt
I think it's better to not use `PARENTSRC` to share just one header. It's probably best to copy it for now. Another option is to move it to shared location but I'm not sure if it's generic enough (there are currently 2 copies of cxx.h and this patch will add 3rd).
Piotr Caban (@piotr) commented about dlls/vccorlib140/vccorlib.c:
const struct __abi_type_descriptor *desc; LONG ref;
};
-static inline struct platform_type *impl_from_IClosable(IClosable *iface) +static inline struct platform_type *impl_from_IInspectable(IInspectable *iface) {
- return CONTAINING_RECORD(iface, struct platform_type, IClosable_iface);
- return CONTAINING_RECORD(iface, struct platform_type, IInspectable_iface);
}
-static HRESULT WINAPI platform_type_QueryInterface(IClosable *iface, const GUID *iid, void **out) +HRESULT WINAPI platform_type_QueryInterface(IInspectable *iface, const GUID *iid, void **out) {
- struct platform_type *impl = impl_from_IClosable(iface);
- struct platform_type *impl = impl_from_IInspectable(iface);
Please fix `IID_IClosable` case in `QueryInterface` implementation.
Piotr Caban (@piotr) commented about dlls/vccorlib140/tests/vccorlib.c:
- todo_wine ok(type_info2 != NULL, "got type_info %p\n", type_info2);
- if (type_info2)
- {
name = (char *)call_func1(p_type_info_name, type_info2);
ok(!strcmp(name, "class Platform::Type"), "got name %s\n", debugstr_a(name));
raw_name = (char *)call_func1(p_type_info_raw_name, type_info2);
ok(!strcmp(raw_name, ".?AVType@Platform@@"), "got raw_name %s\n", debugstr_a(raw_name));
ret = call_func2(p_type_info_opequals_equals, type_info, type_info2);
ok(ret, "got ret %d\n", ret);
ret = call_func2(p_type_info_opnot_equals, type_info, type_info2);
ok(!ret, "got ret %d\n", ret);
call_func1(p_type_info_dtor, type_info);
call_func1(p_type_info_dtor, type_info2);
type_info destructor should not be executed this way. I think it's best to just remove the calls.
Piotr Caban (@piotr) commented about dlls/vccorlib140/vccorlib.c:
}
-static const IClosableVtbl platform_type_closable_vtbl = -{
- /* IUnknown */
- platform_type_QueryInterface,
- platform_type_AddRef,
- platform_type_Release,
- /* IInspectable */
- platform_type_GetIids,
- platform_type_GetRuntimeClassName,
- platform_type_GetTrustLevel,
- /* ICloseable */
- platform_type_Close
-}; +DEFINE_RTTI_DATA(platform_type_closable, sizeof(IInspectable), ".?AVType@Platform@@", platform_type_rtti_base_descriptor);
```suggestion:-0+0 DEFINE_RTTI_DATA(platform_type_closable, offsetof(struct platform_type, IClosable_iface), ".?AVType@Platform@@"); ```