From cbf1310f87f24238f37d57ebc48f07dbd992b4a3 Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Mon, 24 Jun 2024 12:16:18 +0800 Subject: [PATCH] rometadata: Add initial dll. --- configure | 3 + configure.ac | 2 + dlls/rometadata/Makefile.in | 6 + dlls/rometadata/main.c | 194 +++++++++++++++++++++++++++++ dlls/rometadata/rometadata.spec | 1 + dlls/rometadata/tests/Makefile.in | 5 + dlls/rometadata/tests/rometadata.c | 70 +++++++++++ include/Makefile.in | 1 + include/rometadata.h | 24 ++++ 9 files changed, 306 insertions(+) create mode 100644 dlls/rometadata/Makefile.in create mode 100644 dlls/rometadata/main.c create mode 100644 dlls/rometadata/rometadata.spec create mode 100644 dlls/rometadata/tests/Makefile.in create mode 100644 dlls/rometadata/tests/rometadata.c create mode 100644 include/rometadata.h diff --git a/configure b/configure index a91ee8891e0..c506c72ad8b 100755 --- a/configure +++ b/configure @@ -1387,6 +1387,7 @@ enable_regapi enable_resutils enable_riched20 enable_riched32 +enable_rometadata enable_rpcrt4 enable_rsabase enable_rsaenh @@ -22577,6 +22578,8 @@ wine_fn_config_makefile dlls/riched20 enable_riched20 wine_fn_config_makefile dlls/riched20/tests enable_tests wine_fn_config_makefile dlls/riched32 enable_riched32 wine_fn_config_makefile dlls/riched32/tests enable_tests +wine_fn_config_makefile dlls/rometadata enable_rometadata +wine_fn_config_makefile dlls/rometadata/tests enable_tests wine_fn_config_makefile dlls/rpcrt4 enable_rpcrt4 wine_fn_config_makefile dlls/rpcrt4/tests enable_tests wine_fn_config_makefile dlls/rsabase enable_rsabase diff --git a/configure.ac b/configure.ac index 2ff2e062973..7fe5477daf7 100644 --- a/configure.ac +++ b/configure.ac @@ -3061,6 +3061,8 @@ WINE_CONFIG_MAKEFILE(dlls/riched20) WINE_CONFIG_MAKEFILE(dlls/riched20/tests) WINE_CONFIG_MAKEFILE(dlls/riched32) WINE_CONFIG_MAKEFILE(dlls/riched32/tests) +WINE_CONFIG_MAKEFILE(dlls/rometadata) +WINE_CONFIG_MAKEFILE(dlls/rometadata/tests) WINE_CONFIG_MAKEFILE(dlls/rpcrt4) WINE_CONFIG_MAKEFILE(dlls/rpcrt4/tests) WINE_CONFIG_MAKEFILE(dlls/rsabase) diff --git a/dlls/rometadata/Makefile.in b/dlls/rometadata/Makefile.in new file mode 100644 index 00000000000..7a9940a79d1 --- /dev/null +++ b/dlls/rometadata/Makefile.in @@ -0,0 +1,6 @@ +MODULE = rometadata.dll +IMPORTLIB = rometadata +IMPORTS = combase + +SOURCES = \ + main.c diff --git a/dlls/rometadata/main.c b/dlls/rometadata/main.c new file mode 100644 index 00000000000..2530cdf84e0 --- /dev/null +++ b/dlls/rometadata/main.c @@ -0,0 +1,194 @@ +/* + * Copyright 2024 Zhiyi Zhang for CodeWeavers + * + * 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 COBJMACROS +#include "initguid.h" +#include "objbase.h" +#include "cor.h" +#include "rometadata.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(rometadata); + +struct metadata_dispenser +{ + IMetaDataDispenserEx IMetaDataDispenserEx_iface; + LONG refcount; +}; + +static inline struct metadata_dispenser *impl_from_IMetaDataDispenserEx(IMetaDataDispenserEx *iface) +{ + return CONTAINING_RECORD(iface, struct metadata_dispenser, IMetaDataDispenserEx_iface); +} + +static HRESULT WINAPI MetaDataDispenser_QueryInterface(IMetaDataDispenserEx *iface, REFIID riid, void **obj) +{ + TRACE("%p %s %p\n", iface, debugstr_guid(riid), obj); + + if (IsEqualGUID(riid, &IID_IMetaDataDispenserEx) + || IsEqualGUID(riid, &IID_IMetaDataDispenser) + || IsEqualGUID(riid, &IID_IUnknown)) + { + *obj = iface; + IMetaDataDispenserEx_AddRef(iface); + return S_OK; + } + + FIXME("Unsupported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI MetaDataDispenser_AddRef(IMetaDataDispenserEx *iface) +{ + struct metadata_dispenser *this = impl_from_IMetaDataDispenserEx(iface); + ULONG ref = InterlockedIncrement(&this->refcount); + + TRACE("%p ref=%lu\n", this, ref); + + return ref; +} + +static ULONG WINAPI MetaDataDispenser_Release(IMetaDataDispenserEx *iface) +{ + struct metadata_dispenser *this = impl_from_IMetaDataDispenserEx(iface); + ULONG ref = InterlockedDecrement(&this->refcount); + + TRACE("%p ref=%lu\n", this, ref); + + if (ref == 0) + free(this); + + return ref; +} + +static HRESULT WINAPI MetaDataDispenser_DefineScope(IMetaDataDispenserEx *iface, REFCLSID rclsid, + DWORD create_flags, REFIID riid, IUnknown **obj) +{ + FIXME("%p %s %lx %s %p\n", iface, debugstr_guid(rclsid), create_flags, debugstr_guid(riid), + obj); + return E_NOTIMPL; +} + +static HRESULT WINAPI MetaDataDispenser_OpenScope(IMetaDataDispenserEx *iface, const WCHAR *scope, + DWORD open_flags, REFIID riid, IUnknown **obj) +{ + FIXME("%p %s %lx %s %p\n", iface, debugstr_w(scope), open_flags, debugstr_guid(riid), obj); + return E_NOTIMPL; +} + +static HRESULT WINAPI MetaDataDispenser_OpenScopeOnMemory(IMetaDataDispenserEx *iface, const void *data, + ULONG data_size, DWORD open_flags, REFIID riid, + IUnknown **obj) +{ + FIXME("%p %p %lu %lx %s %p\n", iface, data, data_size, open_flags, debugstr_guid(riid), obj); + return E_NOTIMPL; +} + +static HRESULT WINAPI MetaDataDispenser_SetOption(IMetaDataDispenserEx *iface, REFGUID option_id, const VARIANT *value) +{ + FIXME("%p %s %p\n", iface, debugstr_guid(option_id), debugstr_variant(value)); + return E_NOTIMPL; +} + +static HRESULT WINAPI MetaDataDispenser_GetOption(IMetaDataDispenserEx *iface, REFGUID optionid, VARIANT *value) +{ + FIXME("%p %s %s\n", iface, debugstr_guid(optionid), debugstr_variant(value)); + return E_NOTIMPL; +} + +static HRESULT WINAPI MetaDataDispenser_OpenScopeOnITypeInfo(IMetaDataDispenserEx *iface, ITypeInfo *type_info, + DWORD open_flags, REFIID riid, IUnknown **obj) +{ + FIXME("%p %p %lu %s %p\n", iface, type_info, open_flags, debugstr_guid(riid), obj); + return E_NOTIMPL; +} + +static HRESULT WINAPI MetaDataDispenser_GetCORSystemDirectory(IMetaDataDispenserEx *iface, WCHAR *buffer, + DWORD buffer_size, DWORD *return_length) +{ + FIXME("%p %p %lu %p\n", iface, buffer, buffer_size, return_length); + return E_NOTIMPL; +} + +static HRESULT WINAPI MetaDataDispenser_FindAssembly(IMetaDataDispenserEx *iface, const WCHAR *app_base, + const WCHAR *private_bin, const WCHAR *global_bin, + const WCHAR *assembly_name, WCHAR *name, ULONG name_size, + ULONG *return_length) +{ + FIXME("%p %s %s %s %s %p %lu %p\n", iface, debugstr_w(app_base), debugstr_w(private_bin), + debugstr_w(global_bin), debugstr_w(assembly_name), name, name_size, return_length); + return E_NOTIMPL; +} + +static HRESULT WINAPI MetaDataDispenser_FindAssemblyModule(IMetaDataDispenserEx *iface, const WCHAR *app_base, + const WCHAR *private_bin, const WCHAR *global_bin, + const WCHAR *assembly_name, const WCHAR *module_name, + WCHAR *name, ULONG name_size, ULONG *return_length) +{ + FIXME("%p %s %s %s %s %s %p %lu %p\n", iface, debugstr_w(app_base), debugstr_w(private_bin), + debugstr_w(global_bin), debugstr_w(assembly_name), debugstr_w(module_name), name, name_size, return_length); + return E_NOTIMPL; +} + +static const struct IMetaDataDispenserExVtbl MetaDataDispenserExVtbl = +{ + MetaDataDispenser_QueryInterface, + MetaDataDispenser_AddRef, + MetaDataDispenser_Release, + MetaDataDispenser_DefineScope, + MetaDataDispenser_OpenScope, + MetaDataDispenser_OpenScopeOnMemory, + MetaDataDispenser_SetOption, + MetaDataDispenser_GetOption, + MetaDataDispenser_OpenScopeOnITypeInfo, + MetaDataDispenser_GetCORSystemDirectory, + MetaDataDispenser_FindAssembly, + MetaDataDispenser_FindAssemblyModule +}; + +STDAPI MetaDataGetDispenser(REFCLSID rclsid, REFIID riid, void **obj) +{ + struct metadata_dispenser *dispenser; + HRESULT hr; + + TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), obj); + + if (!IsEqualGUID(rclsid, &CLSID_CorMetaDataDispenser)) + return CLASS_E_CLASSNOTAVAILABLE; + + dispenser = malloc(sizeof(*dispenser)); + if (!dispenser) + return E_OUTOFMEMORY; + + dispenser->IMetaDataDispenserEx_iface.lpVtbl = &MetaDataDispenserExVtbl; + dispenser->refcount = 1; + + hr = IMetaDataDispenserEx_QueryInterface(&dispenser->IMetaDataDispenserEx_iface, riid, obj); + IMetaDataDispenserEx_Release(&dispenser->IMetaDataDispenserEx_iface); + return hr; +} + +BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) +{ + TRACE("inst %p, reason %lu, reserved %p.\n", inst, reason, reserved); + + if (reason == DLL_PROCESS_ATTACH) + DisableThreadLibraryCalls(inst); + + return TRUE; +} diff --git a/dlls/rometadata/rometadata.spec b/dlls/rometadata/rometadata.spec new file mode 100644 index 00000000000..12dba03d4a5 --- /dev/null +++ b/dlls/rometadata/rometadata.spec @@ -0,0 +1 @@ +@ stdcall MetaDataGetDispenser(ptr ptr ptr) diff --git a/dlls/rometadata/tests/Makefile.in b/dlls/rometadata/tests/Makefile.in new file mode 100644 index 00000000000..58813aefc54 --- /dev/null +++ b/dlls/rometadata/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = rometadata.dll +IMPORTS = combase rometadata + +SOURCES = \ + rometadata.c diff --git a/dlls/rometadata/tests/rometadata.c b/dlls/rometadata/tests/rometadata.c new file mode 100644 index 00000000000..b4adcd90286 --- /dev/null +++ b/dlls/rometadata/tests/rometadata.c @@ -0,0 +1,70 @@ +/* + * Copyright 2024 Zhiyi Zhang for CodeWeavers + * + * 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 COBJMACROS +#include +#include "initguid.h" +#include "cor.h" +#include "roapi.h" +#include "rometadata.h" +#include "wine/test.h" + +DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + +static void test_MetaDataGetDispenser(void) +{ + IMetaDataDispenserEx *dispenser_ex; + IMetaDataDispenser *dispenser; + IUnknown *unknown; + HRESULT hr; + + /* Invalid parameters */ + hr = MetaDataGetDispenser(&CLSID_NULL, &IID_IMetaDataDispenser, (void **)&dispenser); + ok(hr == CLASS_E_CLASSNOTAVAILABLE, "Got unexpected hr %#lx.\n", hr); + + hr = MetaDataGetDispenser(&CLSID_CorMetaDataDispenser, &IID_NULL, (void **)&dispenser); + ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr); + + /* Normal calls */ + hr = MetaDataGetDispenser(&CLSID_CorMetaDataDispenser, &IID_IUnknown, (void **)&unknown); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + IUnknown_Release(unknown); + + hr = MetaDataGetDispenser(&CLSID_CorMetaDataDispenser, &IID_IMetaDataDispenser, (void **)&dispenser); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + IMetaDataDispenser_Release(dispenser); + + hr = MetaDataGetDispenser(&CLSID_CorMetaDataDispenser, &IID_IMetaDataDispenserEx, (void **)&dispenser_ex); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + IMetaDataDispenserEx_Release(dispenser_ex); +} + +START_TEST(rometadata) +{ + HRESULT hr; + + hr = RoInitialize(RO_INIT_MULTITHREADED); + ok(hr == S_OK, "RoInitialize failed, hr %#lx\n", hr); + + test_MetaDataGetDispenser(); + + RoUninitialize(); +} diff --git a/include/Makefile.in b/include/Makefile.in index 6b66918d564..d3548b1bedb 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -662,6 +662,7 @@ SOURCES = \ rmxftmpl.x \ roapi.h \ roerrorapi.h \ + rometadata.h \ rometadataresolution.h \ roparameterizediid.idl \ row.idl \ diff --git a/include/rometadata.h b/include/rometadata.h new file mode 100644 index 00000000000..0d528804778 --- /dev/null +++ b/include/rometadata.h @@ -0,0 +1,24 @@ +/* + * Copyright 2024 Zhiyi Zhang for CodeWeavers + * + * 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 + */ + +#ifndef _ROMETADATA_H_ +#define _ROMETADATA_H_ + +STDAPI MetaDataGetDispenser(REFCLSID rclsid, REFIID riid, VOID **obj); + +#endif /* _ROMETADATA_H_ */