Commit 24736edf authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

setupapi: Implement SetupDiRemoveDevice().

parent fa823476
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment