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());