[PATCH 3/4] setupapi: Implement SetupDiRemoveDevice().

Zebediah Figura z.figura12 at gmail.com
Fri Nov 30 16:42:12 CST 2018


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/setupapi/devinst.c       | 63 +++++++++++++++++++++++++++----------------
 dlls/setupapi/tests/devinst.c |  6 -----
 2 files changed, 40 insertions(+), 29 deletions(-)

diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index f2f4256365..7c551aab6f 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -118,6 +118,7 @@ struct device
     GUID                  class;
     DEVINST               devnode;
     struct list           entry;
+    BOOL                  removed;
 };
 
 struct device_iface
@@ -167,6 +168,12 @@ static struct device *get_device(HDEVINFO devinfo, const SP_DEVINFO_DATA *data)
         return NULL;
     }
 
+    if (device->removed)
+    {
+        SetLastError(ERROR_NO_SUCH_DEVINST);
+        return NULL;
+    }
+
     return device;
 }
 
@@ -569,32 +576,36 @@ static void remove_device_iface(struct device_iface *iface)
     iface->flags |= SPINT_REMOVED;
 }
 
-static void SETUPDI_RemoveDevice(struct device *device)
+static void remove_device(struct device *device)
+{
+    struct device_iface *iface;
+
+    LIST_FOR_EACH_ENTRY(iface, &device->interfaces, struct device_iface, entry)
+    {
+        remove_device_iface(iface);
+    }
+
+    RegDeleteTreeW(device->key, NULL);
+    RegDeleteKeyW(device->key, emptyW);
+    RegCloseKey(device->key);
+    device->key = NULL;
+    device->removed = TRUE;
+}
+
+static void delete_device(struct device *device)
 {
     struct device_iface *iface, *next;
 
-    if (device->key != INVALID_HANDLE_VALUE)
-        RegCloseKey(device->key);
     if (device->phantom)
-    {
-        HKEY enumKey;
-        LONG l;
+        remove_device(device);
 
-        l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, Enum, 0, NULL, 0,
-                KEY_ALL_ACCESS, NULL, &enumKey, NULL);
-        if (!l)
-        {
-            RegDeleteTreeW(enumKey, device->instanceId);
-            RegCloseKey(enumKey);
-        }
-    }
+    RegCloseKey(device->key);
     heap_free(device->instanceId);
+
     LIST_FOR_EACH_ENTRY_SAFE(iface, next, &device->interfaces,
             struct device_iface, entry)
     {
         list_remove(&iface->entry);
-        if (device->phantom)
-            remove_device_iface(iface);
         RegCloseKey(iface->refstr_key);
         RegCloseKey(iface->class_key);
         heap_free(iface->refstr);
@@ -635,6 +646,7 @@ static struct device *SETUPDI_CreateDeviceInfo(struct DeviceInfoSet *set,
     list_init(&device->interfaces);
     device->class = *class;
     device->devnode = alloc_devnode(device);
+    device->removed = FALSE;
     list_add_tail(&set->devices, &device->entry);
     set->cDevices++;
 
@@ -1538,13 +1550,18 @@ BOOL WINAPI SetupDiRegisterDeviceInfo(HDEVINFO devinfo, SP_DEVINFO_DATA *device_
 /***********************************************************************
  *              SetupDiRemoveDevice (SETUPAPI.@)
  */
-BOOL WINAPI SetupDiRemoveDevice(
-        HDEVINFO devinfo,
-        PSP_DEVINFO_DATA info)
+BOOL WINAPI SetupDiRemoveDevice(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data)
 {
-    FIXME("(%p, %p): stub\n", devinfo, info);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    struct device *device;
+
+    TRACE("devinfo %p, device_data %p.\n", devinfo, device_data);
+
+    if (!(device = get_device(devinfo, device_data)))
+        return FALSE;
+
+    remove_device(device);
+
+    return TRUE;
 }
 
 /***********************************************************************
@@ -2616,7 +2633,7 @@ BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
 
     LIST_FOR_EACH_ENTRY_SAFE(device, device2, &set->devices, struct device, entry)
     {
-        SETUPDI_RemoveDevice(device);
+        delete_device(device);
     }
     heap_free(set);
 
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c
index 45d145d14c..07e082b2e1 100644
--- a/dlls/setupapi/tests/devinst.c
+++ b/dlls/setupapi/tests/devinst.c
@@ -338,7 +338,6 @@ static void test_device_info(void)
     check_device_info(set, 3, &guid, NULL);
 
     ret = SetupDiRemoveDevice(set, &device);
-todo_wine
     ok(ret, "Got unexpected error %#x.\n", GetLastError());
 
     check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\0000");
@@ -349,10 +348,8 @@ todo_wine
     ok(IsEqualGUID(&ret_device.ClassGuid, &guid), "Got unexpected class %s.\n",
             wine_dbgstr_guid(&ret_device.ClassGuid));
     ret = SetupDiGetDeviceInstanceIdA(set, &ret_device, id, sizeof(id), NULL);
-todo_wine {
     ok(!ret, "Expected failure.\n");
     ok(GetLastError() == ERROR_NO_SUCH_DEVINST, "Got unexpected error %#x.\n", GetLastError());
-}
     ok(ret_device.DevInst == device.DevInst, "Expected device node %#x, got %#x.\n",
             device.DevInst, ret_device.DevInst);
 
@@ -522,7 +519,6 @@ static void test_register_device_info(void)
     ok(!strcasecmp(id, "Root\\LEGACY_BOGUS\\0000"), "Got unexpected id %s.\n", id);
 
     ret = SetupDiRemoveDevice(set, &device);
-todo_wine
     ok(ret, "Failed to remove device, error %#x.\n", GetLastError());
 
     ret = SetupDiEnumDeviceInfo(set, 1, &device);
@@ -849,7 +845,6 @@ todo_wine {
     }
 
     ret = SetupDiRemoveDevice(set, &device);
-todo_wine
     ok(ret, "Failed to remove device, error %#x.\n", GetLastError());
     SetupDiDestroyDeviceInfoList(set);
 
@@ -891,7 +886,6 @@ static void test_register_device_iface(void)
     check_device_iface(set2, NULL, &guid, 1, 0, NULL);
 
     ret = SetupDiRemoveDevice(set, &device);
-todo_wine
     ok(ret, "Failed to remove device, error %#x.\n", GetLastError());
 
     SetupDiDestroyDeviceInfoList(set);
-- 
2.14.1




More information about the wine-devel mailing list