Juan Lang : setupapi: Implement SetupDiEnumDeviceInterfaces.
Alexandre Julliard
julliard at winehq.org
Mon Sep 24 08:08:01 CDT 2007
Module: wine
Branch: master
Commit: be863b07ff157556beed1d3a66a60942d86a9cba
URL: http://source.winehq.org/git/wine.git/?a=commit;h=be863b07ff157556beed1d3a66a60942d86a9cba
Author: Juan Lang <juan.lang at gmail.com>
Date: Fri Sep 21 11:36:37 2007 -0700
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 b00e901..c249d14 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 54a4b77..cecd231 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);
}
}
More information about the wine-cvs
mailing list