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; +}