Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 34 ++++++++++++++++++++++++++++------ dlls/setupapi/setupapi.spec | 2 +- dlls/setupapi/tests/devinst.c | 25 ++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 8 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 82a45b4470..7638a8bd5b 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -576,6 +576,16 @@ static void remove_device_iface(struct device_iface *iface) iface->flags |= SPINT_REMOVED; }
+static void delete_device_iface(struct device_iface *iface) +{ + list_remove(&iface->entry); + RegCloseKey(iface->refstr_key); + RegCloseKey(iface->class_key); + heap_free(iface->refstr); + heap_free(iface->symlink); + heap_free(iface); +} + static void remove_device(struct device *device) { WCHAR id[MAX_DEVICE_ID_LEN], *p; @@ -622,12 +632,7 @@ static void delete_device(struct device *device) LIST_FOR_EACH_ENTRY_SAFE(iface, next, &device->interfaces, struct device_iface, entry) { - list_remove(&iface->entry); - RegCloseKey(iface->refstr_key); - RegCloseKey(iface->class_key); - heap_free(iface->refstr); - heap_free(iface->symlink); - heap_free(iface); + delete_device_iface(iface); } free_devnode(device->devnode); list_remove(&device->entry); @@ -1598,6 +1603,23 @@ BOOL WINAPI SetupDiRemoveDeviceInterface(HDEVINFO devinfo, SP_DEVICE_INTERFACE_D return TRUE; }
+/*********************************************************************** + * SetupDiDeleteDeviceInterfaceData (SETUPAPI.@) + */ +BOOL WINAPI SetupDiDeleteDeviceInterfaceData(HDEVINFO devinfo, SP_DEVICE_INTERFACE_DATA *iface_data) +{ + struct device_iface *iface; + + TRACE("devinfo %p, iface_data %p.\n", devinfo, iface_data); + + if (!(iface = get_device_iface(devinfo, iface_data))) + return FALSE; + + delete_device_iface(iface); + + return TRUE; +} + /*********************************************************************** * SetupDiEnumDeviceInfo (SETUPAPI.@) */ diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index 99509e1bbf..0b44e184fc 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -302,7 +302,7 @@ @ stdcall SetupDiCreateDeviceInterfaceRegKeyW(ptr ptr long long ptr wstr) @ stdcall SetupDiDeleteDevRegKey(ptr ptr long long long) @ stdcall SetupDiDeleteDeviceInfo(ptr ptr) -@ stub SetupDiDeleteDeviceInterfaceData +@ stdcall SetupDiDeleteDeviceInterfaceData(ptr ptr) @ stdcall SetupDiDeleteDeviceInterfaceRegKey(ptr ptr long) @ stub SetupDiDeleteDeviceRegKey @ stdcall SetupDiDestroyClassImageList(ptr) diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index 29f12c3f53..edb660e106 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -650,6 +650,15 @@ static void test_device_iface(void) check_device_iface(set, &device, &guid2, 0, SPINT_REMOVED, "\\?\ROOT#LEGACY_BOGUS#0000#{6A55B5A5-3F65-11DB-B704-0011955C2BDB}"); check_device_iface(set, &device, &guid2, 1, 0, NULL);
+ ret = SetupDiEnumDeviceInterfaces(set, &device, &guid, 0, &iface); + ok(ret, "Failed to enumerate interfaces, error %#x.\n", GetLastError()); + ret = SetupDiDeleteDeviceInterfaceData(set, &iface); + ok(ret, "Failed to delete interface, error %#x.\n", GetLastError()); + + check_device_iface(set, &device, &guid, 0, 0, "\\?\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\Oogah"); + check_device_iface(set, &device, &guid, 1, 0, "\\?\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\test"); + check_device_iface(set, &device, &guid, 2, 0, NULL); + ret = SetupDiDestroyDeviceInfoList(set); ok(ret, "Failed to destroy device list, error %#x.\n", GetLastError()); } @@ -862,14 +871,28 @@ static void test_register_device_iface(void) ok(ret, "Failed to create device, error %#x.\n", GetLastError()); ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, NULL, 0, &iface); ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, "removed", 0, &iface); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, "deleted", 0, &iface); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL); ok(ret, "Failed to register device, error %#x.\n", GetLastError());
+ ret = SetupDiEnumDeviceInterfaces(set, &device, &guid, 1, &iface); + ok(ret, "Failed to enumerate interfaces, error %#x.\n", GetLastError()); + ret = SetupDiRemoveDeviceInterface(set, &iface); + ok(ret, "Failed to delete interface, error %#x.\n", GetLastError()); + ret = SetupDiEnumDeviceInterfaces(set, &device, &guid, 2, &iface); + ok(ret, "Failed to enumerate interfaces, error %#x.\n", GetLastError()); + ret = SetupDiDeleteDeviceInterfaceData(set, &iface); + ok(ret, "Failed to delete interface, error %#x.\n", GetLastError()); + set2 = SetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE); ok(set2 != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
check_device_iface(set2, NULL, &guid, 0, 0, "\\?\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}"); - check_device_iface(set2, NULL, &guid, 1, 0, NULL); + check_device_iface(set2, NULL, &guid, 1, 0, "\\?\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}\deleted"); + check_device_iface(set2, NULL, &guid, 2, 0, NULL);
ret = SetupDiRemoveDevice(set, &device); ok(ret, "Failed to remove device, error %#x.\n", GetLastError());
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 47 +++++++++++++++-------------------------------- 1 file changed, 15 insertions(+), 32 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 7638a8bd5b..db0b72fcb5 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -104,7 +104,6 @@ struct DeviceInfoSet DWORD magic; /* if is equal to SETUP_DEVICE_INFO_SET_MAGIC struct is okay */ GUID ClassGuid; HWND hwndParent; - DWORD cDevices; struct list devices; };
@@ -670,7 +669,6 @@ static struct device *SETUPDI_CreateDeviceInfo(struct DeviceInfoSet *set, device->devnode = alloc_devnode(device); device->removed = FALSE; list_add_tail(&set->devices, &device->entry); - set->cDevices++;
SETUPDI_GuidToString(class, guidstr); SETUPDI_SetDeviceRegistryPropertyW(device, SPDRP_CLASSGUID, @@ -1289,7 +1287,6 @@ SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid, memcpy(&list->ClassGuid, ClassGuid ? ClassGuid : &GUID_NULL, sizeof(list->ClassGuid)); - list->cDevices = 0; list_init(&list->devices);
return list; @@ -1475,7 +1472,7 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO devinfo, const WCHAR *name, const if ((flags & DICD_GENERATE_ID)) { static const WCHAR formatW[] = {'R','O','O','T','\','%','s','\','%','0','4','d',0}; - DWORD devId; + int instance_id, highest_id = -1;
if (strchrW(name, '\')) { @@ -1483,29 +1480,20 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO devinfo, const WCHAR *name, const return FALSE; }
- if (set->cDevices) + LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry) { - DWORD highestDevID = 0; - - LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry) - { - const WCHAR *devName = strrchrW(device->instanceId, '\'); - DWORD id; - - if (devName) - devName++; - else - devName = device->instanceId; - id = SETUPDI_DevNameToDevID(devName); - if (id != 0xffffffff && id > highestDevID) - highestDevID = id; - } - devId = highestDevID + 1; + const WCHAR *instance_str = strrchrW(device->instanceId, '\'); + + if (instance_str) + instance_str++; + else + instance_str = device->instanceId; + instance_id = SETUPDI_DevNameToDevID(instance_str); + if (instance_id != 0xffffffff && instance_id > highest_id) + highest_id = instance_id; } - else - devId = 0;
- if (snprintfW(id, ARRAY_SIZE(id), formatW, name, devId) == -1) + if (snprintfW(id, ARRAY_SIZE(id), formatW, name, highest_id + 1) == -1) { SetLastError(ERROR_INVALID_DEVINST_NAME); return FALSE; @@ -1646,22 +1634,17 @@ BOOL WINAPI SetupDiEnumDeviceInfo(HDEVINFO devinfo, DWORD index, SP_DEVINFO_DATA return FALSE; }
- if (index >= set->cDevices) - { - SetLastError(ERROR_NO_MORE_ITEMS); - return FALSE; - } - LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry) { if (i++ == index) { copy_device_data(device_data, device); - break; + return TRUE; } }
- return TRUE; + SetLastError(ERROR_NO_MORE_ITEMS); + return FALSE; }
/***********************************************************************
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43211 Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 17 ++++++++++++++ dlls/setupapi/stubs.c | 12 ---------- dlls/setupapi/tests/devinst.c | 52 +++++++++++++++++++++++++++++-------------- 3 files changed, 52 insertions(+), 29 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index db0b72fcb5..5685dc3bff 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -1574,6 +1574,23 @@ BOOL WINAPI SetupDiRemoveDevice(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data) return TRUE; }
+/*********************************************************************** + * SetupDiDeleteDeviceInfo (SETUPAPI.@) + */ +BOOL WINAPI SetupDiDeleteDeviceInfo(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data) +{ + struct device *device; + + TRACE("devinfo %p, device_data %p.\n", devinfo, device_data); + + if (!(device = get_device(devinfo, device_data))) + return FALSE; + + delete_device(device); + + return TRUE; +} + /*********************************************************************** * SetupDiRemoveDeviceInterface (SETUPAPI.@) */ diff --git a/dlls/setupapi/stubs.c b/dlls/setupapi/stubs.c index 7c3413a7cc..61ce005212 100644 --- a/dlls/setupapi/stubs.c +++ b/dlls/setupapi/stubs.c @@ -611,18 +611,6 @@ BOOL WINAPI SetupDiDestroyDriverInfoList(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DAT return FALSE; }
-/*********************************************************************** - * SetupDiDeleteDeviceInfo (SETUPAPI.@) - */ - -BOOL WINAPI SetupDiDeleteDeviceInfo(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData) - { - FIXME(": stub %p, %p\n", DeviceInfoSet, DeviceInfoData); - - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; - } - /*********************************************************************** * SetupDiDrawMiniIcon (SETUPAPI.@) */ diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index edb660e106..55fe104b9b 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -337,13 +337,21 @@ static void test_device_info(void) check_device_info(set, 2, &guid, "ROOT\LEGACY_BOGUS\0002"); check_device_info(set, 3, &guid, NULL);
+ ret = SetupDiEnumDeviceInfo(set, 0, &ret_device); + ok(ret, "Failed to enumerate devices, error %#x.\n", GetLastError()); + ret = SetupDiDeleteDeviceInfo(set, &ret_device); + ok(ret, "Failed to delete device, error %#x.\n", GetLastError()); + + check_device_info(set, 0, &guid, "ROOT\LEGACY_BOGUS\0001"); + check_device_info(set, 1, &guid, "ROOT\LEGACY_BOGUS\0002"); + check_device_info(set, 2, &guid, NULL); + ret = SetupDiRemoveDevice(set, &device); ok(ret, "Got unexpected error %#x.\n", GetLastError());
- check_device_info(set, 0, &guid, "ROOT\LEGACY_BOGUS\0000"); - check_device_info(set, 1, &guid, "ROOT\LEGACY_BOGUS\0001"); + check_device_info(set, 0, &guid, "ROOT\LEGACY_BOGUS\0001");
- ret = SetupDiEnumDeviceInfo(set, 2, &ret_device); + ret = SetupDiEnumDeviceInfo(set, 1, &ret_device); ok(ret, "Got unexpected error %#x.\n", GetLastError()); ok(IsEqualGUID(&ret_device.ClassGuid, &guid), "Got unexpected class %s.\n", wine_dbgstr_guid(&ret_device.ClassGuid)); @@ -353,7 +361,7 @@ static void test_device_info(void) ok(ret_device.DevInst == device.DevInst, "Expected device node %#x, got %#x.\n", device.DevInst, ret_device.DevInst);
- check_device_info(set, 3, &guid, NULL); + check_device_info(set, 2, &guid, NULL);
SetupDiDestroyDeviceInfoList(set);
@@ -469,7 +477,7 @@ static void test_register_device_info(void) SP_DEVINFO_DATA device = {0}; BOOL ret; HDEVINFO set; - char id[30]; + int i = 0;
SetLastError(0xdeadbeef); ret = SetupDiRegisterDeviceInfo(NULL, NULL, 0, NULL, NULL, NULL); @@ -497,30 +505,40 @@ static void test_register_device_info(void)
ret = SetupDiCreateDeviceInfoA(set, "Root\LEGACY_BOGUS\0000", &guid, NULL, NULL, 0, &device); ok(ret, "Failed to create device, error %#x.\n", GetLastError()); - ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL); ok(ret, "Failed to register device, error %#x.\n", GetLastError());
ret = SetupDiCreateDeviceInfoA(set, "Root\LEGACY_BOGUS\0001", &guid, NULL, NULL, 0, &device); ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL); + ok(ret, "Failed to register device, error %#x.\n", GetLastError()); + ret = SetupDiRemoveDevice(set, &device); + ok(ret, "Failed to remove device, error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "Root\LEGACY_BOGUS\0002", &guid, NULL, NULL, 0, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL); + ok(ret, "Failed to register device, error %#x.\n", GetLastError()); + ret = SetupDiDeleteDeviceInfo(set, &device); + ok(ret, "Failed to remove device, error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "Root\LEGACY_BOGUS\0003", &guid, NULL, NULL, 0, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError());
SetupDiDestroyDeviceInfoList(set);
set = SetupDiGetClassDevsA(&guid, NULL, NULL, 0); ok(set != NULL, "Failed to create device list, error %#x.\n", GetLastError());
- ret = SetupDiEnumDeviceInfo(set, 0, &device); - ok(ret, "Failed to enumerate devices, error %#x.\n", GetLastError()); - ret = SetupDiGetDeviceInstanceIdA(set, &device, id, sizeof(id), NULL); - ok(ret, "Failed to get device id, error %#x.\n", GetLastError()); - ok(!strcasecmp(id, "Root\LEGACY_BOGUS\0000"), "Got unexpected id %s.\n", id); - - ret = SetupDiRemoveDevice(set, &device); - ok(ret, "Failed to remove device, error %#x.\n", GetLastError()); + check_device_info(set, 0, &guid, "Root\LEGACY_BOGUS\0000"); + check_device_info(set, 1, &guid, "Root\LEGACY_BOGUS\0002"); + check_device_info(set, 2, &guid, NULL);
- ret = SetupDiEnumDeviceInfo(set, 1, &device); - ok(!ret, "Expected failure.\n"); - ok(GetLastError() == ERROR_NO_MORE_ITEMS, "Got unexpected error %#x.\n", GetLastError()); + while (SetupDiEnumDeviceInfo(set, i++, &device)) + { + ret = SetupDiRemoveDevice(set, &device); + ok(ret, "Failed to remove device, error %#x.\n", GetLastError()); + }
SetupDiDestroyDeviceInfoList(set); }