[PATCH 2/6] setupapi: Add a basic implementation of SetupDiCallClassInstaller().

Zebediah Figura z.figura12 at gmail.com
Wed May 22 00:10:06 CDT 2019


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/setupapi/devinst.c       | 33 +++++++++++++++++++-----
 dlls/setupapi/tests/devinst.c | 48 +++++++++++++++++++++++++++++++++++
 include/setupapi.h            |  1 +
 3 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index d2921bcf44..a3d7336067 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -3561,15 +3561,34 @@ BOOL WINAPI SetupDiSetClassInstallParamsW(
 }
 
 /***********************************************************************
- *		SetupDiCallClassInstaller (SETUPAPI.@)
+ *              SetupDiCallClassInstaller (SETUPAPI.@)
  */
-BOOL WINAPI SetupDiCallClassInstaller(
-       DI_FUNCTION InstallFunction,
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData)
+BOOL WINAPI SetupDiCallClassInstaller(DI_FUNCTION function, HDEVINFO devinfo, SP_DEVINFO_DATA *device_data)
 {
-    FIXME("%d %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
-    return FALSE;
+    TRACE("function %#x, devinfo %p, device_data %p.\n", function, devinfo, device_data);
+
+    switch (function)
+    {
+    case DIF_REGISTERDEVICE:
+        return SetupDiRegisterDeviceInfo(devinfo, device_data, 0, NULL, NULL, NULL);
+    case DIF_REMOVE:
+        return SetupDiRemoveDevice(devinfo, device_data);
+    case DIF_SELECTBESTCOMPATDRV:
+        return SetupDiSelectBestCompatDrv(devinfo, device_data);
+    case DIF_REGISTER_COINSTALLERS:
+        return SetupDiRegisterCoDeviceInstallers(devinfo, device_data);
+    case DIF_FINISHINSTALL_ACTION:
+    case DIF_INSTALLDEVICE:
+    case DIF_INSTALLDEVICEFILES:
+    case DIF_INSTALLINTERFACES:
+    case DIF_PROPERTYCHANGE:
+    case DIF_SELECTDEVICE:
+    case DIF_UNREMOVE:
+        FIXME("Unhandled function %#x.\n", function);
+    default:
+        SetLastError(ERROR_DI_DO_DEFAULT);
+        return FALSE;
+    }
 }
 
 /***********************************************************************
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c
index a717bc08c6..880129756c 100644
--- a/dlls/setupapi/tests/devinst.c
+++ b/dlls/setupapi/tests/devinst.c
@@ -2344,6 +2344,53 @@ static void test_driver_list(void)
     DeleteFileA("C:/windows/inf/wine_test2.pnf");
 }
 
+static BOOL device_is_registered(HDEVINFO set, SP_DEVINFO_DATA *device)
+{
+    HKEY key = SetupDiOpenDevRegKey(set, device, DICS_FLAG_GLOBAL, 0, DIREG_DRV, 0);
+    ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n");
+    RegCloseKey(key);
+    return GetLastError() == ERROR_KEY_DOES_NOT_EXIST;
+}
+
+static void test_call_class_installer(void)
+{
+    SP_DEVINFO_DATA device = {sizeof(device)};
+    HDEVINFO set;
+    BOOL ret;
+
+    if (wow64)
+    {
+        win_skip("SetupDiCallClassInstaller() does not work on WoW64.\n");
+        return;
+    }
+
+    set = SetupDiCreateDeviceInfoList(&guid, NULL);
+    ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
+    ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device);
+    ok(ret, "Failed to create device, error %#x.\n", GetLastError());
+
+    ok(!device_is_registered(set, &device), "Expected device not to be registered.\n");
+    ret = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, set, &device);
+    ok(ret, "Failed to call class installer, error %#x.\n", GetLastError());
+    ok(device_is_registered(set, &device), "Expected device to be registered.\n");
+
+    /* This is probably not failure per se, but rather an indication that no
+     * class installer was called and no default handler exists. */
+    ret = SetupDiCallClassInstaller(DIF_ALLOW_INSTALL, set, &device);
+    ok(!ret, "Expected failure.\n");
+    ok(GetLastError() == ERROR_DI_DO_DEFAULT, "Got unexpected error %#x.\n", GetLastError());
+
+    ret = SetupDiCallClassInstaller(0xdeadbeef, set, &device);
+    ok(!ret, "Expected failure.\n");
+    ok(GetLastError() == ERROR_DI_DO_DEFAULT, "Got unexpected error %#x.\n", GetLastError());
+
+    ret = SetupDiCallClassInstaller(DIF_REMOVE, set, &device);
+    ok(ret, "Failed to call class installer, error %#x.\n", GetLastError());
+    ok(!device_is_registered(set, &device), "Expected device not to be registered.\n");
+
+    SetupDiDestroyDeviceInfoList(set);
+}
+
 START_TEST(devinst)
 {
     static BOOL (WINAPI *pIsWow64Process)(HANDLE, BOOL *);
@@ -2380,4 +2427,5 @@ START_TEST(devinst)
     test_device_interface_key();
     test_device_install_params();
     test_driver_list();
+    test_call_class_installer();
 }
diff --git a/include/setupapi.h b/include/setupapi.h
index 45f830ef5a..49a696c2a8 100644
--- a/include/setupapi.h
+++ b/include/setupapi.h
@@ -1106,6 +1106,7 @@ DECL_WINELIB_SETUPAPI_TYPE_AW(PSP_INF_SIGNER_INFO)
 #define DIF_POWERMESSAGEWAKE                0x27
 #define DIF_ADDREMOTEPROPERTYPAGE_ADVANCED  0x28
 #define DIF_UPDATEDRIVER_UI                 0x29
+#define DIF_FINISHINSTALL_ACTION            0x2a
 #define DIF_RESERVED2                       0x30
 
 /* Directory ids */
-- 
2.21.0




More information about the wine-devel mailing list