From: Paul Gofman pgofman@codeweavers.com
--- dlls/cfgmgr32/cfgmgr32.spec | 4 +- dlls/cfgmgr32/tests/cfgmgr32.c | 54 ++++++++++++++++ dlls/setupapi/devinst.c | 113 +++++++++++++++++++++++++++++++++ dlls/setupapi/setupapi.spec | 4 +- dlls/setupapi/stubs.c | 20 ------ include/cfgmgr32.h | 16 +++++ 6 files changed, 187 insertions(+), 24 deletions(-)
diff --git a/dlls/cfgmgr32/cfgmgr32.spec b/dlls/cfgmgr32/cfgmgr32.spec index d940bb63427..99d14ee7c50 100644 --- a/dlls/cfgmgr32/cfgmgr32.spec +++ b/dlls/cfgmgr32/cfgmgr32.spec @@ -84,9 +84,9 @@ @ stub CM_Get_Device_Interface_Alias_ExA @ stub CM_Get_Device_Interface_Alias_ExW @ stub CM_Get_Device_Interface_ListA -@ stub CM_Get_Device_Interface_ListW +@ stdcall CM_Get_Device_Interface_ListW(ptr ptr ptr long long) setupapi.CM_Get_Device_Interface_ListW @ stub CM_Get_Device_Interface_List_ExA -@ stub CM_Get_Device_Interface_List_ExW +@ stdcall CM_Get_Device_Interface_List_ExW(ptr ptr ptr long long ptr) setupapi.CM_Get_Device_Interface_List_ExW @ stdcall CM_Get_Device_Interface_List_SizeA(ptr ptr str long) setupapi.CM_Get_Device_Interface_List_SizeA @ stdcall CM_Get_Device_Interface_List_SizeW(ptr ptr wstr long) setupapi.CM_Get_Device_Interface_List_SizeW @ stdcall CM_Get_Device_Interface_List_Size_ExA(ptr ptr str long ptr) setupapi.CM_Get_Device_Interface_List_Size_ExA diff --git a/dlls/cfgmgr32/tests/cfgmgr32.c b/dlls/cfgmgr32/tests/cfgmgr32.c index c28b61527a2..4c9737a7bec 100644 --- a/dlls/cfgmgr32/tests/cfgmgr32.c +++ b/dlls/cfgmgr32/tests/cfgmgr32.c @@ -363,9 +363,63 @@ static void test_CM_Register_Notification( void ) } }
+static void test_CM_Get_Device_Interface_List(void) +{ + BYTE iface_detail_buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + 256 * sizeof(WCHAR)]; + SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; + SP_DEVICE_INTERFACE_DETAIL_DATA_W *iface_data; + SP_DEVINFO_DATA device = { sizeof(device) }; + unsigned int count, count2; + WCHAR *buffer, *p; + CONFIGRET ret; + HDEVINFO set; + ULONG size; + GUID guid; + BOOL bret; + + guid = GUID_DEVINTERFACE_DISPLAY_ADAPTER; + + ret = CM_Get_Device_Interface_List_SizeW(&size, &guid, NULL, CM_GET_DEVICE_INTERFACE_LIST_PRESENT); + ok(!ret, "got %#lx.\n", ret); + + buffer = malloc(size * sizeof(*buffer)); + ret = CM_Get_Device_Interface_ListW( &guid, NULL, buffer, size, CM_GET_DEVICE_INTERFACE_LIST_PRESENT); + ok(!ret, "got %#lx.\n", ret); + + iface_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)iface_detail_buffer; + + count = 0; + p = buffer; + while (*p) + { + set = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL); + ok(set != INVALID_HANDLE_VALUE, "got %p.\n", set); + bret = SetupDiOpenDeviceInterfaceW(set, p, 0, &iface); + ok(bret, "got error %lu.\n", GetLastError()); + memset(iface_detail_buffer, 0xcc, sizeof(iface_detail_buffer)); + iface_data->cbSize = sizeof(*iface_data); + bret = SetupDiGetDeviceInterfaceDetailW(set, &iface, iface_data, sizeof(iface_detail_buffer), NULL, &device); + ok(bret, "got error %lu.\n", GetLastError()); + ok(!wcsicmp(iface_data->DevicePath, p), "got %s, expected %s.\n", debugstr_w(p), debugstr_w(iface_data->DevicePath)); + SetupDiDestroyDeviceInfoList(set); + p += wcslen(p) + 1; + ++count; + } + + free(buffer); + + set = SetupDiGetClassDevsW(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + ok(set != INVALID_HANDLE_VALUE, "got %p.\n", set); + for (count2 = 0; SetupDiEnumDeviceInterfaces(set, NULL, &guid, count2, &iface); ++count2) + ; + SetupDiDestroyDeviceInfoList(set); + ok(count == count2, "got %u, expected %u.\n", count, count2); +} + START_TEST(cfgmgr32) { test_CM_MapCrToWin32Err(); test_CM_Get_Device_ID_List(); test_CM_Register_Notification(); + test_CM_Get_Device_Interface_List(); } diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index f502bc85475..8dba81c8b49 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -4589,6 +4589,119 @@ CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA(ULONG *len, const char *filter, ULO return CM_Get_Device_ID_List_Size_ExA(len, filter, flags, NULL); }
+static CONFIGRET get_device_interface_list(const GUID *class_guid, DEVINSTID_W device_id, WCHAR *buffer, ULONG *len, + ULONG flags) +{ + const ULONG supported_flags = CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES; + + BYTE iface_detail_buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + 256 * sizeof(WCHAR)]; + SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; + SP_DEVICE_INTERFACE_DETAIL_DATA_W *iface_data; + SP_DEVINFO_DATA device = { sizeof(device) }; + ULONG query_flags = DIGCF_DEVICEINTERFACE; + CONFIGRET ret = CR_SUCCESS; + unsigned int i, id_len; + HDEVINFO set; + ULONG needed; + WCHAR *p; + + if (!len || (buffer && !*len)) + return CR_INVALID_POINTER; + + needed = 1; + + if (buffer) + *buffer = 0; + if (flags & ~supported_flags) + FIXME("Flags %#lx are not supported.\n", flags); + + if (!buffer) + *len = 0; + + if (!buffer) + *len = needed; + + if (!(flags & CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES)) query_flags |= DIGCF_PRESENT; + set = SetupDiGetClassDevsW(class_guid, device_id, NULL, query_flags); + if (set == INVALID_HANDLE_VALUE) + return CR_SUCCESS; + + iface_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)iface_detail_buffer; + iface_data->cbSize = sizeof(*iface_data); + + p = buffer; + for (i = 0; SetupDiEnumDeviceInterfaces(set, NULL, class_guid, i, &iface); ++i) + { + ret = SetupDiGetDeviceInterfaceDetailW(set, &iface, iface_data, sizeof(iface_detail_buffer), NULL, &device); + if (!ret) continue; + id_len = wcslen(iface_data->DevicePath) + 1; + needed += id_len; + if (buffer) + { + if (needed > *len) + { + SetupDiDestroyDeviceInfoList(set); + *buffer = 0; + return CR_BUFFER_SMALL; + } + memcpy(p, iface_data->DevicePath, sizeof(*p) * id_len); + p += id_len; + } + } + SetupDiDestroyDeviceInfoList(set); + *len = needed; + if (buffer) + *p = 0; + return CR_SUCCESS; +} + +/*********************************************************************** + * CM_Get_Device_Interface_List_Size_ExW (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_Interface_List_Size_ExW(PULONG len, LPGUID class, DEVINSTID_W id, + ULONG flags, HMACHINE machine) +{ + TRACE("%p %s %s 0x%08lx %p\n", len, debugstr_guid(class), debugstr_w(id), flags, machine); + + if (machine) + FIXME("machine %p.\n", machine); + + return get_device_interface_list(class, id, NULL, len, flags); +} + +/*********************************************************************** + * CM_Get_Device_Interface_List_SizeW (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_Interface_List_SizeW(PULONG len, LPGUID class, DEVINSTID_W id, ULONG flags) +{ + TRACE("%p %s %s 0x%08lx\n", len, debugstr_guid(class), debugstr_w(id), flags); + return get_device_interface_list(class, id, NULL, len, flags); +} + +/*********************************************************************** + * CM_Get_Device_Interface_List_W (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_Interface_List_ExW(LPGUID class, DEVINSTID_W id, PZZWSTR buffer, ULONG len, ULONG flags, + HMACHINE machine) +{ + TRACE("%s %s %p %lu %#lx\n", debugstr_guid(class), debugstr_w(id), buffer, len, flags); + + if (machine) + FIXME("machine %p.\n", machine); + + return get_device_interface_list(class, id, buffer, &len, flags); +} + +/*********************************************************************** + * CM_Get_Device_Interface_List_W (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_Interface_ListW(LPGUID class, DEVINSTID_W id, PZZWSTR buffer, ULONG len, ULONG flags) +{ + TRACE("%s %s %p %lu %#lx\n", debugstr_guid(class), debugstr_w(id), buffer, len, flags); + + return get_device_interface_list(class, id, buffer, &len, flags); +} + /*********************************************************************** * SetupDiGetINFClassA (SETUPAPI.@) */ diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index f77cb301dfe..e38946587c2 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -94,9 +94,9 @@ @ stub CM_Get_Device_Interface_Alias_ExA @ stub CM_Get_Device_Interface_Alias_ExW @ stub CM_Get_Device_Interface_ListA -@ stub CM_Get_Device_Interface_ListW +@ stdcall CM_Get_Device_Interface_ListW(ptr ptr ptr long long) @ stub CM_Get_Device_Interface_List_ExA -@ stub CM_Get_Device_Interface_List_ExW +@ stdcall CM_Get_Device_Interface_List_ExW(ptr ptr ptr long long ptr) @ stdcall CM_Get_Device_Interface_List_SizeA(ptr ptr str long) @ stdcall CM_Get_Device_Interface_List_SizeW(ptr ptr wstr long) @ stdcall CM_Get_Device_Interface_List_Size_ExA(ptr ptr str long ptr) diff --git a/dlls/setupapi/stubs.c b/dlls/setupapi/stubs.c index 0766b1364bf..96ecc778a9d 100644 --- a/dlls/setupapi/stubs.c +++ b/dlls/setupapi/stubs.c @@ -277,16 +277,6 @@ CONFIGRET WINAPI CM_Get_Device_Interface_List_SizeA(PULONG len, LPGUID class, DE return CR_FAILURE; }
-/*********************************************************************** - * CM_Get_Device_Interface_List_SizeW (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_Device_Interface_List_SizeW(PULONG len, LPGUID class, DEVINSTID_W id, - ULONG flags) -{ - FIXME("%p %p %s 0x%08lx: stub\n", len, class, debugstr_w(id), flags); - return CR_FAILURE; -} - /*********************************************************************** * CM_Get_Device_Interface_List_Size_ExA (SETUPAPI.@) */ @@ -297,16 +287,6 @@ CONFIGRET WINAPI CM_Get_Device_Interface_List_Size_ExA(PULONG len, LPGUID class, return CR_FAILURE; }
-/*********************************************************************** - * CM_Get_Device_Interface_List_Size_ExW (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_Device_Interface_List_Size_ExW(PULONG len, LPGUID class, DEVINSTID_W id, - ULONG flags, HMACHINE machine) -{ - FIXME("%p %p %s 0x%08lx %p: stub\n", len, class, debugstr_w(id), flags, machine); - return CR_FAILURE; -} - /*********************************************************************** * CM_Get_Device_Interface_AliasA (SETUPAPI.@) */ diff --git a/include/cfgmgr32.h b/include/cfgmgr32.h index 3e814757e2b..ee84533a2d0 100644 --- a/include/cfgmgr32.h +++ b/include/cfgmgr32.h @@ -196,6 +196,10 @@ typedef DWORD CONFIGRET; #define CM_GETIDLIST_FILTER_CLASS 0x00000200 #define CM_GETIDLIST_FILTER_BITS 0x100003FF
+#define CM_GET_DEVICE_INTERFACE_LIST_PRESENT 0x00000000 +#define CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES 0x00000001 +#define CM_GET_DEVICE_INTERFACE_LIST_BITS 0x00000001 + typedef DWORD DEVINST, *PDEVINST; typedef DWORD DEVNODE, *PDEVNODE; typedef HANDLE HMACHINE, *PHMACHINE; @@ -314,6 +318,18 @@ CMAPI CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExW(PULONG,PCWSTR,ULONG,HMACHI #define CM_Get_Device_ID_List_Size_Ex WINELIB_NAME_AW(CM_Get_Device_ID_List_Size_Ex) CMAPI CONFIGRET WINAPI CM_Get_Device_ID_Size(PULONG,DEVINST,ULONG); CMAPI CONFIGRET WINAPI CM_Get_Device_ID_Size_Ex(PULONG,DEVINST,ULONG,HMACHINE); +CMAPI CONFIGRET WINAPI CM_Get_Device_Interface_ListW(LPGUID,DEVINSTID_W,PZZWSTR,ULONG,ULONG); +CMAPI CONFIGRET WINAPI CM_Get_Device_Interface_ListA(LPGUID,DEVINSTID_A,PZZSTR,ULONG,ULONG); +#define CM_Get_Device_Interface_List WINELIB_NAME_AW(CM_Get_Device_Interface_List) +CMAPI CONFIGRET WINAPI CM_Get_Device_Interface_List_SizeW(PULONG,LPGUID,DEVINSTID_W,ULONG); +CMAPI CONFIGRET WINAPI CM_Get_Device_Interface_List_SizeA(PULONG,LPGUID,DEVINSTID_A,ULONG); +#define CM_Get_Device_Interface_List_Size WINELIB_NAME_AW(CM_Get_Device_Interface_List_Size) +CMAPI CONFIGRET WINAPI CM_Get_Device_Interface_List_ExW(LPGUID,DEVINSTID_W,PZZWSTR,ULONG,ULONG,HMACHINE); +CMAPI CONFIGRET WINAPI CM_Get_Device_Interface_List_ExA(LPGUID,DEVINSTID_A,PZZSTR,ULONG,ULONG,HMACHINE); +#define CM_Get_Device_Interface_List_Ex WINELIB_NAME_AW(CM_Get_Device_Interface_List_Ex) +CMAPI CONFIGRET WINAPI CM_Get_Device_Interface_List_Size_ExW(PULONG,LPGUID,DEVINSTID_W,ULONG,HMACHINE); +CMAPI CONFIGRET WINAPI CM_Get_Device_Interface_List_Size_ExA(PULONG,LPGUID,DEVINSTID_A,ULONG,HMACHINE); +#define CM_Get_Device_Interface_List_Size_Ex WINELIB_NAME_AW(CM_Get_Device_Interface_List_Size_Ex) CMAPI CONFIGRET WINAPI CM_Get_Device_Interface_PropertyW(LPCWSTR,const DEVPROPKEY*,DEVPROPTYPE*,PBYTE,PULONG,ULONG); CMAPI CONFIGRET WINAPI CM_Get_DevNode_PropertyW(DEVINST,const DEVPROPKEY *,DEVPROPTYPE *type,PVOID,PULONG,ULONG); CMAPI CONFIGRET WINAPI CM_Get_DevNode_PropertyExW(DEVINST,const DEVPROPKEY *,DEVPROPTYPE *type,PVOID,PULONG,ULONG,HMACHINE);