From be863b07ff157556beed1d3a66a60942d86a9cba Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Fri, 21 Sep 2007 11:36:37 -0700 Subject: [PATCH] setupapi: Implement SetupDiEnumDeviceInterfaces. --- dlls/setupapi/devinst.c | 102 +++++++++++++++++++++++++++++++--- dlls/setupapi/tests/devinst.c | 9 ++- 2 files changed, 102 insertions(+), 9 deletions(-) diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index b00e9015792..c249d14ce0c 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -2084,29 +2084,115 @@ BOOL WINAPI SetupDiCreateDeviceInterfaceW( /*********************************************************************** * SetupDiEnumDeviceInterfaces (SETUPAPI.@) + * + * PARAMS + * DeviceInfoSet [I] Set of devices from which to enumerate + * interfaces + * DeviceInfoData [I] (Optional) If specified, a specific device + * instance from which to enumerate interfaces. + * If it isn't specified, all interfaces for all + * devices in the set are enumerated. + * InterfaceClassGuid [I] The interface class to enumerate. + * MemberIndex [I] An index of the interface instance to enumerate. + * A caller should start with MemberIndex set to 0, + * and continue until the function fails with + * ERROR_NO_MORE_ITEMS. + * DeviceInterfaceData [I/O] Returns an enumerated interface. Its cbSize + * member must be set to + * sizeof(SP_DEVICE_INTERFACE_DATA). + * + * RETURNS + * Success: non-zero value. + * Failure: FALSE. Call GetLastError() for more info. */ BOOL WINAPI SetupDiEnumDeviceInterfaces( - HDEVINFO devinfo, + HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, CONST GUID * InterfaceClassGuid, DWORD MemberIndex, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) { + struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet; BOOL ret = FALSE; - FIXME("%p, %p, %s, 0x%08x, %p\n", devinfo, DeviceInfoData, + TRACE("%p, %p, %s, %d, %p\n", DeviceInfoSet, DeviceInfoData, debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData); - if (devinfo && devinfo != (HDEVINFO)INVALID_HANDLE_VALUE) + if (!DeviceInfoSet || DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE || + set->magic != SETUP_DEVICE_INFO_SET_MAGIC) { - struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo; - if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC) - SetLastError(ERROR_NO_MORE_ITEMS); + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (DeviceInfoData && (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA) || + !DeviceInfoData->Reserved)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (!DeviceInterfaceData || + DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (DeviceInfoData) + { + struct DeviceInfo *devInfo = + (struct DeviceInfo *)DeviceInfoData->Reserved; + DWORD i; + + if ((ret = SETUPDI_FindInterface(devInfo, InterfaceClassGuid, &i))) + { + if (MemberIndex < devInfo->interfaces[i].cInstances) + memcpy(DeviceInterfaceData, + &devInfo->interfaces[i].instances[MemberIndex], + sizeof(SP_DEVICE_INTERFACE_DATA)); + else + { + SetLastError(ERROR_NO_MORE_ITEMS); + ret = FALSE; + } + } else - SetLastError(ERROR_INVALID_HANDLE); + SetLastError(ERROR_NO_MORE_ITEMS); } else - SetLastError(ERROR_INVALID_HANDLE); + { + DWORD i, cEnumerated = 0; + BOOL found = FALSE; + + for (i = 0; !found && cEnumerated < MemberIndex + 1 && + i < set->cDevices; i++) + { + struct DeviceInfo *devInfo = + (struct DeviceInfo *)set->devices[i].Reserved; + DWORD interfaceIndex; + + if (SETUPDI_FindInterface(devInfo, InterfaceClassGuid, + &interfaceIndex)) + { + struct InterfaceInstances *interface = + &devInfo->interfaces[interfaceIndex]; + + if (cEnumerated + interface->cInstances < MemberIndex + 1) + cEnumerated += interface->cInstances; + else + { + DWORD instanceIndex = MemberIndex - cEnumerated; + + memcpy(DeviceInterfaceData, + &interface->instances[instanceIndex], + sizeof(SP_DEVICE_INTERFACE_DATA)); + cEnumerated += instanceIndex + 1; + found = TRUE; + ret = TRUE; + } + } + } + if (!found) + SetLastError(ERROR_NO_MORE_ITEMS); + } return ret; } diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index 54a4b77eac7..cecd231702a 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -364,6 +364,7 @@ static void testCreateDeviceInterface(void) SP_DEVINFO_DATA devInfo = { 0 }; SP_DEVICE_INTERFACE_DATA interfaceData = { sizeof(interfaceData), { 0 } }; + DWORD i; SetLastError(0xdeadbeef); ret = pSetupDiCreateDeviceInterfaceA(set, NULL, NULL, NULL, 0, NULL); @@ -395,8 +396,14 @@ static void testCreateDeviceInterface(void) ok(ret, "SetupDiCreateDeviceInterfaceA failed: %08x\n", GetLastError()); ret = pSetupDiEnumDeviceInterfaces(set, &devInfo, &guid, 0, &interfaceData); - todo_wine ok(ret, "SetupDiEnumDeviceInterfaces failed: %d\n", GetLastError()); + i = 0; + while (pSetupDiEnumDeviceInterfaces(set, &devInfo, &guid, i, + &interfaceData)) + i++; + ok(i == 2, "expected 2 interfaces, got %d\n", i); + ok(GetLastError() == ERROR_NO_MORE_ITEMS, + "SetupDiEnumDeviceInterfaces failed: %08x\n", GetLastError()); pSetupDiDestroyDeviceInfoList(set); } }