diff --git a/configure b/configure index 7236d8bf13d..d405d6741a4 100755 --- a/configure +++ b/configure @@ -19792,6 +19792,7 @@ wine_fn_config_makefile dlls/setupx.dll16 enable_win16 wine_fn_config_makefile dlls/sfc enable_sfc wine_fn_config_makefile dlls/sfc_os enable_sfc_os wine_fn_config_makefile dlls/shcore enable_shcore +wine_fn_config_makefile dlls/shcore/tests enable_tests wine_fn_config_makefile dlls/shdoclc enable_shdoclc wine_fn_config_makefile dlls/shdocvw enable_shdocvw wine_fn_config_makefile dlls/shdocvw/tests enable_tests diff --git a/configure.ac b/configure.ac index 5d0205830c5..cd1bf44ab44 100644 --- a/configure.ac +++ b/configure.ac @@ -3655,6 +3655,7 @@ WINE_CONFIG_MAKEFILE(dlls/setupx.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/sfc) WINE_CONFIG_MAKEFILE(dlls/sfc_os) WINE_CONFIG_MAKEFILE(dlls/shcore) +WINE_CONFIG_MAKEFILE(dlls/shcore/tests) WINE_CONFIG_MAKEFILE(dlls/shdoclc) WINE_CONFIG_MAKEFILE(dlls/shdocvw) WINE_CONFIG_MAKEFILE(dlls/shdocvw/tests) diff --git a/dlls/api-ms-win-shcore-thread-l1-1-0/api-ms-win-shcore-thread-l1-1-0.spec b/dlls/api-ms-win-shcore-thread-l1-1-0/api-ms-win-shcore-thread-l1-1-0.spec index 15330050ded..0cbacc850aa 100644 --- a/dlls/api-ms-win-shcore-thread-l1-1-0/api-ms-win-shcore-thread-l1-1-0.spec +++ b/dlls/api-ms-win-shcore-thread-l1-1-0/api-ms-win-shcore-thread-l1-1-0.spec @@ -1,8 +1,8 @@ -@ stub GetProcessReference +@ stdcall GetProcessReference(ptr) shcore.GetProcessReference @ stdcall SHCreateThread(ptr ptr long ptr) shcore.SHCreateThread @ stdcall SHCreateThreadRef(ptr ptr) shcore.SHCreateThreadRef @ stub SHCreateThreadWithHandle @ stdcall SHGetThreadRef(ptr) shcore.SHGetThreadRef @ stdcall SHReleaseThreadRef() shcore.SHReleaseThreadRef @ stdcall SHSetThreadRef(ptr) shcore.SHSetThreadRef -@ stub SetProcessReference +@ stdcall SetProcessReference(ptr) shcore.SetProcessReference diff --git a/dlls/shcore/main.c b/dlls/shcore/main.c index 7f423c1edd5..488e78eb865 100644 --- a/dlls/shcore/main.c +++ b/dlls/shcore/main.c @@ -36,6 +36,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(shcore); static DWORD shcore_tls; +static IUnknown *process_ref; BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) { @@ -1261,3 +1262,31 @@ HRESULT WINAPI SHReleaseThreadRef(void) FIXME("() - stub!\n"); return S_OK; } + +/************************************************************************* + * GetProcessReference [SHCORE.@] + */ +HRESULT WINAPI GetProcessReference(IUnknown **obj) +{ + TRACE("(%p)\n", obj); + + *obj = process_ref; + + if (!process_ref) + return E_FAIL; + + if (*obj) + IUnknown_AddRef(*obj); + + return S_OK; +} + +/************************************************************************* + * SetProcessReference [SHCORE.@] + */ +void WINAPI SetProcessReference(IUnknown *obj) +{ + TRACE("(%p)\n", obj); + + process_ref = obj; +} diff --git a/dlls/shcore/shcore.spec b/dlls/shcore/shcore.spec index 568cb205971..c98f2db54a0 100644 --- a/dlls/shcore/shcore.spec +++ b/dlls/shcore/shcore.spec @@ -10,7 +10,7 @@ @ stdcall GetDpiForMonitor(long long ptr ptr) @ stub GetDpiForShellUIComponent @ stdcall GetProcessDpiAwareness(long ptr) -@ stub GetProcessReference +@ stdcall GetProcessReference(ptr) @ stub GetScaleFactorForDevice @ stub GetScaleFactorForMonitor @ stub IStream_Copy @@ -79,7 +79,7 @@ @ stdcall SHUnicodeToUnicode(wstr ptr long) shlwapi.SHUnicodeToUnicode @ stdcall SetCurrentProcessExplicitAppUserModelID(wstr) @ stdcall SetProcessDpiAwareness(long) -@ stub SetProcessReference +@ stdcall SetProcessReference(ptr) @ stub UnregisterScaleChangeEvent 100 stub @ diff --git a/dlls/shcore/tests/Makefile.in b/dlls/shcore/tests/Makefile.in new file mode 100644 index 00000000000..0ea769a348d --- /dev/null +++ b/dlls/shcore/tests/Makefile.in @@ -0,0 +1,4 @@ +TESTDLL = shcore.dll + +C_SRCS = \ + shcore.c diff --git a/dlls/shcore/tests/shcore.c b/dlls/shcore/tests/shcore.c new file mode 100644 index 00000000000..de6a921fc24 --- /dev/null +++ b/dlls/shcore/tests/shcore.c @@ -0,0 +1,140 @@ +/* + * Copyright 2018 Nikolay Sivov 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 +#include "initguid.h" +#include "objidl.h" + +#include "wine/test.h" + +static HRESULT (WINAPI *pGetProcessReference)(IUnknown **); +static void (WINAPI *pSetProcessReference)(IUnknown *); +static HRESULT (WINAPI *pSHGetInstanceExplorer)(IUnknown **); + +static void init(HMODULE hshcore) +{ +#define X(f) p##f = (void*)GetProcAddress(hshcore, #f) + X(GetProcessReference); + X(SetProcessReference); +#undef X +} + +static HRESULT WINAPI unk_QI(IUnknown *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IUnknown_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +struct test_unk +{ + IUnknown IUnknown_iface; + LONG refcount; +}; + +static struct test_unk *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct test_unk, IUnknown_iface); +} + +static ULONG WINAPI unk_AddRef(IUnknown *iface) +{ + struct test_unk *obj = impl_from_IUnknown(iface); + return InterlockedIncrement(&obj->refcount); +} + +static ULONG WINAPI unk_Release(IUnknown *iface) +{ + struct test_unk *obj = impl_from_IUnknown(iface); + return InterlockedDecrement(&obj->refcount); +} + +static const IUnknownVtbl testunkvtbl = +{ + unk_QI, + unk_AddRef, + unk_Release, +}; + +static void test_unk_init(struct test_unk *testunk) +{ + testunk->IUnknown_iface.lpVtbl = &testunkvtbl; + testunk->refcount = 1; +} + +static void test_process_reference(void) +{ + struct test_unk test_unk, test_unk2; + IUnknown *obj; + HMODULE hmod; + HRESULT hr; + + obj = (void *)0xdeadbeef; + hr = pGetProcessReference(&obj); + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + ok(obj == NULL, "Unexpected pointer.\n"); + + test_unk_init(&test_unk); + test_unk_init(&test_unk2); + + pSetProcessReference(&test_unk.IUnknown_iface); + ok(test_unk.refcount == 1, "Unexpected refcount %u.\n", test_unk.refcount); + pSetProcessReference(&test_unk2.IUnknown_iface); + ok(test_unk.refcount == 1, "Unexpected refcount %u.\n", test_unk.refcount); + ok(test_unk2.refcount == 1, "Unexpected refcount %u.\n", test_unk2.refcount); + + hr = pGetProcessReference(&obj); + ok(hr == S_OK, "Failed to get reference, hr %#x.\n", hr); + ok(obj == &test_unk2.IUnknown_iface, "Unexpected pointer.\n"); + ok(test_unk2.refcount == 2, "Unexpected refcount %u.\n", test_unk2.refcount); + + hmod = LoadLibraryA("shell32.dll"); + + pSHGetInstanceExplorer = (void *)GetProcAddress(hmod, "SHGetInstanceExplorer"); + hr = pSHGetInstanceExplorer(&obj); +todo_wine { + ok(hr == S_OK, "Failed to get reference, hr %#x.\n", hr); + ok(obj == &test_unk2.IUnknown_iface, "Unexpected pointer.\n"); + ok(test_unk2.refcount == 3, "Unexpected refcount %u.\n", test_unk2.refcount); +} +} + +START_TEST(shcore) +{ + HMODULE hshcore = LoadLibraryA("shcore.dll"); + + if (!hshcore) + { + win_skip("Shcore.dll is not available.\n"); + return; + } + + init(hshcore); + + test_process_reference(); +}