From 7afc9ed20072bd0dfa766ca42c5843db0f02b72f Mon Sep 17 00:00:00 2001 From: winesync Date: Thu, 14 Sep 2023 21:00:49 +0200 Subject: [PATCH] [WINESYNC] setupapi/tests: Add some tests for COM self-registration. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard wine commit id e0b5da7b34e9f38990939bd20cf4b2fa749c3f6e by Zebediah Figura [WINESYNC] setupapi: Initialize COM if necessary when registering DLLs. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard wine commit id e75d5b8dc7e4751ddce84a379306a5deb89ca29b by Zebediah Figura --- .../winetests/setupapi/CMakeLists.txt | 15 +++- modules/rostests/winetests/setupapi/install.c | 90 +++++++++++++++++++ modules/rostests/winetests/setupapi/selfreg.c | 50 +++++++++++ .../rostests/winetests/setupapi/selfreg.spec | 2 + .../rostests/winetests/setupapi/setupapi.rc | 1 + sdk/tools/winesync/setupapi.cfg | 2 +- 6 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 modules/rostests/winetests/setupapi/selfreg.c create mode 100644 modules/rostests/winetests/setupapi/selfreg.spec diff --git a/modules/rostests/winetests/setupapi/CMakeLists.txt b/modules/rostests/winetests/setupapi/CMakeLists.txt index 380f0cc365a..01607910bb3 100644 --- a/modules/rostests/winetests/setupapi/CMakeLists.txt +++ b/modules/rostests/winetests/setupapi/CMakeLists.txt @@ -13,6 +13,13 @@ set_target_properties(setupapi_coinst PROPERTIES OUTPUT_NAME "coinst") set_module_type(setupapi_coinst win32dll) add_importlibs(setupapi_coinst msvcrt kernel32) +spec2def(selfreg.dll selfreg.spec) +add_library(setupapi_selfreg MODULE selfreg.c ${CMAKE_CURRENT_BINARY_DIR}/selfreg.def) +set_target_properties(setupapi_selfreg PROPERTIES OUTPUT_NAME "selfreg") +set_module_type(setupapi_selfreg win32dll) +target_link_libraries(setupapi_selfreg uuid) +add_importlibs(setupapi_selfreg advapi32 ole32 msvcrt kernel32) + list(APPEND SOURCE devinst.c dialog.c @@ -29,11 +36,13 @@ add_executable(setupapi_winetest ${SOURCE} setupapi.rc) # CMake 3.9 and higher requires to specify this dependency manually # see https://gitlab.kitware.com/cmake/cmake/issues/19933 -set_property(SOURCE setupapi.rc PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/coinst.dll) +set_property(SOURCE setupapi.rc PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/coinst.dll ${CMAKE_CURRENT_BINARY_DIR}/selfreg.dll) # setupapi.rc: let rc.exe find the dlls in their subdirectory, i.e. Debug. if (MSVC_IDE) - target_include_directories(setupapi_winetest PRIVATE $<$:$>) + target_include_directories(setupapi_winetest PRIVATE + $<$:$> + $<$:$>) endif() if(CMAKE_C_COMPILER_ID STREQUAL "GNU") @@ -42,5 +51,5 @@ endif() set_module_type(setupapi_winetest win32cui) target_link_libraries(setupapi_winetest uuid) -add_importlibs(setupapi_winetest advapi32 cabinet setupapi user32 shell32 msvcrt kernel32 ntdll) +add_importlibs(setupapi_winetest advapi32 cabinet ole32 setupapi user32 shell32 msvcrt kernel32 ntdll) add_rostests_file(TARGET setupapi_winetest) diff --git a/modules/rostests/winetests/setupapi/install.c b/modules/rostests/winetests/setupapi/install.c index fd10fd91332..8a2f9eec351 100644 --- a/modules/rostests/winetests/setupapi/install.c +++ b/modules/rostests/winetests/setupapi/install.c @@ -54,6 +54,24 @@ static char CURR_DIR[MAX_PATH]; * Helpers */ +static void load_resource(const char *name, const char *filename) +{ + DWORD written; + HANDLE file; + HRSRC res; + void *ptr; + + file = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", filename, GetLastError()); + + res = FindResourceA(NULL, name, "TESTDLL"); + ok( res != 0, "couldn't find resource\n" ); + ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res )); + WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL ); + ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" ); + CloseHandle( file ); +} + static void create_inf_file(LPCSTR filename, const char *data) { DWORD res; @@ -2040,6 +2058,77 @@ static void test_start_copy(void) delete_file("dst/"); } +static void test_register_dlls(void) +{ + static const char inf_data[] = "[Version]\n" + "Signature=\"$Chicago$\"\n" + "[DefaultInstall]\n" + "RegisterDlls=register_section\n" + "UnregisterDlls=register_section\n" + "[register_section]\n" + "40000,,winetest_selfreg.dll,1\n"; + + void *context = SetupInitDefaultQueueCallbackEx(NULL, INVALID_HANDLE_VALUE, 0, 0, 0); + char path[MAX_PATH]; + HRESULT hr; + HINF hinf; + BOOL ret; + HKEY key; + LONG l; + + create_inf_file("test.inf", inf_data); + sprintf(path, "%s\\test.inf", CURR_DIR); + hinf = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL); + ok(hinf != INVALID_HANDLE_VALUE, "Failed to open INF file, error %#x.\n", GetLastError()); + + load_resource("selfreg.dll", "winetest_selfreg.dll"); + ret = SetupSetDirectoryIdA(hinf, 40000, CURR_DIR); + ok(ret, "Failed to set directory ID, error %u.\n", GetLastError()); + + RegDeleteKeyA(HKEY_CURRENT_USER, "winetest_setupapi_selfreg"); + + ret = SetupInstallFromInfSectionA(NULL, hinf, "DefaultInstall", SPINST_REGSVR, + NULL, "C:\\", 0, SetupDefaultQueueCallbackA, context, NULL, NULL); + ok(ret, "Failed to install, error %#x.\n", GetLastError()); + + l = RegOpenKeyA(HKEY_CURRENT_USER, "winetest_setupapi_selfreg", &key); + ok(!l, "Got error %u.\n", l); + RegCloseKey(key); + + ret = SetupInstallFromInfSectionA(NULL, hinf, "DefaultInstall", SPINST_UNREGSVR, + NULL, "C:\\", 0, SetupDefaultQueueCallbackA, context, NULL, NULL); + ok(ret, "Failed to install, error %#x.\n", GetLastError()); + + l = RegOpenKeyA(HKEY_CURRENT_USER, "winetest_setupapi_selfreg", &key); + ok(l == ERROR_FILE_NOT_FOUND, "Got error %u.\n", l); + + hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + ret = SetupInstallFromInfSectionA(NULL, hinf, "DefaultInstall", SPINST_REGSVR, + NULL, "C:\\", 0, SetupDefaultQueueCallbackA, context, NULL, NULL); + ok(ret, "Failed to install, error %#x.\n", GetLastError()); + + l = RegOpenKeyA(HKEY_CURRENT_USER, "winetest_setupapi_selfreg", &key); + ok(!l, "Got error %u.\n", l); + RegCloseKey(key); + + ret = SetupInstallFromInfSectionA(NULL, hinf, "DefaultInstall", SPINST_UNREGSVR, + NULL, "C:\\", 0, SetupDefaultQueueCallbackA, context, NULL, NULL); + ok(ret, "Failed to install, error %#x.\n", GetLastError()); + + l = RegOpenKeyA(HKEY_CURRENT_USER, "winetest_setupapi_selfreg", &key); + ok(l == ERROR_FILE_NOT_FOUND, "Got error %u.\n", l); + + CoUninitialize(); + + SetupCloseInfFile(hinf); + ret = DeleteFileA("test.inf"); + ok(ret, "Failed to delete INF file, error %u.\n", GetLastError()); + ret = DeleteFileA("winetest_selfreg.dll"); + ok(ret, "Failed to delete test DLL, error %u.\n", GetLastError()); +} + START_TEST(install) { char temp_path[MAX_PATH], prev_path[MAX_PATH]; @@ -2069,6 +2158,7 @@ START_TEST(install) test_close_queue(); test_install_file(); test_start_copy(); + test_register_dlls(); UnhookWindowsHookEx(hhook); diff --git a/modules/rostests/winetests/setupapi/selfreg.c b/modules/rostests/winetests/setupapi/selfreg.c new file mode 100644 index 00000000000..f687990f3bc --- /dev/null +++ b/modules/rostests/winetests/setupapi/selfreg.c @@ -0,0 +1,50 @@ +/* + * DLL for testing COM self-registration + * + * Copyright 2020 Zebediah Figura 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 "msxml.h" + +HRESULT WINAPI DllRegisterServer(void) +{ + IUnknown *unk; + HKEY key; + + if (CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, + &IID_IUnknown, (void **)&unk) == S_OK) + { + RegCreateKeyA(HKEY_CURRENT_USER, "winetest_setupapi_selfreg", &key); + RegCloseKey(key); + IUnknown_Release(unk); + } + return S_OK; +} + +HRESULT WINAPI DllUnregisterServer(void) +{ + IUnknown *unk; + + if (CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, + &IID_IUnknown, (void **)&unk) == S_OK) + { + RegDeleteKeyA(HKEY_CURRENT_USER, "winetest_setupapi_selfreg"); + IUnknown_Release(unk); + } + return S_OK; +} diff --git a/modules/rostests/winetests/setupapi/selfreg.spec b/modules/rostests/winetests/setupapi/selfreg.spec new file mode 100644 index 00000000000..0f9b07355f7 --- /dev/null +++ b/modules/rostests/winetests/setupapi/selfreg.spec @@ -0,0 +1,2 @@ +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/modules/rostests/winetests/setupapi/setupapi.rc b/modules/rostests/winetests/setupapi/setupapi.rc index 246ace2ff72..be572d660c4 100644 --- a/modules/rostests/winetests/setupapi/setupapi.rc +++ b/modules/rostests/winetests/setupapi/setupapi.rc @@ -25,3 +25,4 @@ 1 RT_MANIFEST setupapi.manifest COINST.DLL TESTDLL "coinst.dll" +SELFREG.DLL TESTDLL "selfreg.dll" diff --git a/sdk/tools/winesync/setupapi.cfg b/sdk/tools/winesync/setupapi.cfg index 109ac92b7a2..acca5eb3717 100644 --- a/sdk/tools/winesync/setupapi.cfg +++ b/sdk/tools/winesync/setupapi.cfg @@ -10,4 +10,4 @@ files: dlls/setupapi/setupcab.c: dll/win32/setupapi/setupcab.c dlls/setupapi/stringtable.c: dll/win32/setupapi/stringtable_wine.c tags: - wine: d580d2c2fdad7f6f00dd12923e475298c019b660 + wine: e75d5b8dc7e4751ddce84a379306a5deb89ca29b