Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/combase/tests/Makefile.in | 7 +- dlls/combase/tests/combase.manifest | 15 ++ dlls/combase/tests/combase.rc | 22 +++ dlls/combase/tests/roapi.c | 52 +++++++ dlls/combase/tests/wine.combase.test.c | 159 ++++++++++++++++++++++ dlls/combase/tests/wine.combase.test.spec | 3 + 6 files changed, 256 insertions(+), 2 deletions(-) create mode 100644 dlls/combase/tests/combase.manifest create mode 100644 dlls/combase/tests/combase.rc create mode 100644 dlls/combase/tests/wine.combase.test.c create mode 100644 dlls/combase/tests/wine.combase.test.spec
diff --git a/dlls/combase/tests/Makefile.in b/dlls/combase/tests/Makefile.in index 1c3d77725b3..99c036b78d9 100644 --- a/dlls/combase/tests/Makefile.in +++ b/dlls/combase/tests/Makefile.in @@ -1,6 +1,9 @@ TESTDLL = combase.dll IMPORTS = combase
-C_SRCS = \ +SOURCES = \ roapi.c \ - string.c + string.c \ + combase.rc \ + wine.combase.test.c \ + wine.combase.test.spec diff --git a/dlls/combase/tests/combase.manifest b/dlls/combase/tests/combase.manifest new file mode 100644 index 00000000000..72f3ac915e0 --- /dev/null +++ b/dlls/combase/tests/combase.manifest @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity + type="win32" + name="wine.combase.test" + version="1.0.0.0" + processorArchitecture="*" + /> +<description>Wine combase test suite</description> +<file name="wine.combase.test.dll"> + <activatableClass name="Wine.Test.Missing" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"/> + <activatableClass name="Wine.Test.Class" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"/> + <activatableClass name="Wine.Test.Trusted" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"/> +</file> +</assembly> diff --git a/dlls/combase/tests/combase.rc b/dlls/combase/tests/combase.rc new file mode 100644 index 00000000000..865bf703d5c --- /dev/null +++ b/dlls/combase/tests/combase.rc @@ -0,0 +1,22 @@ +/* + * Copyright 2022 Rémi Bernon 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 + */ + +#include "winuser.h" + +/* @makedep: combase.manifest */ +1 RT_MANIFEST combase.manifest diff --git a/dlls/combase/tests/roapi.c b/dlls/combase/tests/roapi.c index b1ac15a08cb..1fb8e3e5dc0 100644 --- a/dlls/combase/tests/roapi.c +++ b/dlls/combase/tests/roapi.c @@ -28,12 +28,31 @@
#include "wine/test.h"
+static void load_resource(const WCHAR *filename) +{ + DWORD written; + HANDLE file; + HRSRC res; + void *ptr; + + file = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "failed to create %s, error %lu\n", debugstr_w(filename), GetLastError()); + + res = FindResourceW(NULL, filename, L"TESTDLL"); + ok(res != 0, "couldn't find resource\n"); + ptr = LockResource(LoadResource(GetModuleHandleW(NULL), res)); + WriteFile(file, ptr, SizeofResource(GetModuleHandleW(NULL), res), &written, NULL); + ok(written == SizeofResource(GetModuleHandleW(NULL), res), "couldn't write resource\n"); + CloseHandle(file); +} + static void test_ActivationFactories(void) { HRESULT hr; HSTRING str, str2; IActivationFactory *factory = NULL; IInspectable *inspect = NULL; + ULONG ref;
hr = WindowsCreateString(L"Windows.Data.Xml.Dom.XmlDocument", ARRAY_SIZE(L"Windows.Data.Xml.Dom.XmlDocument") - 1, &str); @@ -63,10 +82,43 @@ static void test_ActivationFactories(void)
WindowsDeleteString(str2); WindowsDeleteString(str); + + hr = WindowsCreateString(L"Wine.Test.Missing", ARRAY_SIZE(L"Wine.Test.Missing") - 1, &str); + ok(hr == S_OK, "WindowsCreateString returned %#lx.\n", hr); + hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory); + ok(hr == REGDB_E_CLASSNOTREG, "RoGetActivationFactory returned %#lx.\n", hr); + ok(factory == NULL, "got factory %p.\n", factory); + WindowsDeleteString(str); + hr = WindowsCreateString(L"Wine.Test.Class", ARRAY_SIZE(L"Wine.Test.Class") - 1, &str); + ok(hr == S_OK, "WindowsCreateString returned %#lx.\n", hr); + hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory); + todo_wine + ok(hr == E_NOTIMPL, "RoGetActivationFactory returned %#lx.\n", hr); + ok(factory == NULL, "got factory %p.\n", factory); + WindowsDeleteString(str); + hr = WindowsCreateString(L"Wine.Test.Trusted", ARRAY_SIZE(L"Wine.Test.Trusted") - 1, &str); + ok(hr == S_OK, "WindowsCreateString returned %#lx.\n", hr); + hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory); + todo_wine + ok(hr == S_OK, "RoGetActivationFactory returned %#lx.\n", hr); + todo_wine + ok(!!factory, "got factory %p.\n", factory); + if (!factory) ref = 0; + else ref = IActivationFactory_Release(factory); + ok(ref == 0, "Release returned %lu\n", ref); + WindowsDeleteString(str); + RoUninitialize(); }
START_TEST(roapi) { + BOOL ret; + + load_resource(L"wine.combase.test.dll"); + test_ActivationFactories(); + + ret = DeleteFileW(L"wine.combase.test.dll"); + ok(ret, "Failed to delete file, error %lu\n", GetLastError()); } diff --git a/dlls/combase/tests/wine.combase.test.c b/dlls/combase/tests/wine.combase.test.c new file mode 100644 index 00000000000..e6171c6c6e7 --- /dev/null +++ b/dlls/combase/tests/wine.combase.test.c @@ -0,0 +1,159 @@ +/* + * Copyright 2022 Rémi Bernon 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 + */ + +#include <stdarg.h> +#include <stddef.h> + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" + +#include "initguid.h" +#include "inspectable.h" +#include "roapi.h" +#include "winstring.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(combase); + +struct factory +{ + IActivationFactory IActivationFactory_iface; + LONG ref; + BOOL trusted; +}; + +static inline struct factory *impl_from_IActivationFactory(IActivationFactory *iface) +{ + return CONTAINING_RECORD(iface, struct factory, IActivationFactory_iface); +} + +static HRESULT WINAPI factory_QueryInterface(IActivationFactory *iface, REFIID iid, void **out) +{ + struct factory *impl = impl_from_IActivationFactory(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_IInspectable) + || IsEqualGUID(iid, &IID_IAgileObject) + || IsEqualGUID(iid, &IID_IActivationFactory)) + { + IInspectable_AddRef((*out = &impl->IActivationFactory_iface)); + return S_OK; + } + + FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef(IActivationFactory *iface) +{ + struct factory *impl = impl_from_IActivationFactory(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + TRACE("iface %p increasing refcount to %lu.\n", iface, ref); + return ref; +} + +static ULONG WINAPI factory_Release(IActivationFactory *iface) +{ + struct factory *impl = impl_from_IActivationFactory(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + TRACE("iface %p decreasing refcount to %lu.\n", iface, ref); + return ref; +} + +static HRESULT WINAPI factory_GetIids(IActivationFactory *iface, ULONG *iid_count, IID **iids) +{ + FIXME("iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetRuntimeClassName(IActivationFactory *iface, HSTRING *class_name) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetTrustLevel(IActivationFactory *iface, TrustLevel *trust_level) +{ + struct factory *impl = impl_from_IActivationFactory(iface); + + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + + if (!impl->trusted) return E_NOTIMPL; + + *trust_level = BaseTrust; + return S_OK; +} + +static HRESULT WINAPI factory_ActivateInstance(IActivationFactory *iface, IInspectable **instance) +{ + FIXME("iface %p, instance %p stub!\n", iface, instance); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl factory_vtbl = +{ + factory_QueryInterface, + factory_AddRef, + factory_Release, + /* IInspectable methods */ + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, + /* IActivationFactory methods */ + factory_ActivateInstance, +}; + +static struct factory class_factory = {{&factory_vtbl}, 0}; +static struct factory trusted_factory = {{&factory_vtbl}, 0, TRUE}; + +HRESULT WINAPI DllCanUnloadNow(void) +{ + FIXME("stub!\n"); + return S_OK; +} + +HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **factory) +{ + const WCHAR *buffer = WindowsGetStringRawBuffer(classid, NULL); + + FIXME("class %s, factory %p stub!\n", debugstr_w(buffer), factory); + + if (!wcscmp(buffer, L"Wine.Test.Class")) + { + IActivationFactory_AddRef((*factory = &class_factory.IActivationFactory_iface)); + return S_OK; + } + if (!wcscmp(buffer, L"Wine.Test.Trusted")) + { + IActivationFactory_AddRef((*factory = &trusted_factory.IActivationFactory_iface)); + return S_OK; + } + + return REGDB_E_CLASSNOTREG; +} + +HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **out) +{ + FIXME("clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid), debugstr_guid(riid), out); + return CLASS_E_CLASSNOTAVAILABLE; +} diff --git a/dlls/combase/tests/wine.combase.test.spec b/dlls/combase/tests/wine.combase.test.spec new file mode 100644 index 00000000000..20a8bfa98ea --- /dev/null +++ b/dlls/combase/tests/wine.combase.test.spec @@ -0,0 +1,3 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetActivationFactory(ptr ptr) +@ stdcall -private DllGetClassObject(ptr ptr ptr)