From: Paul Gofman pgofman@codeweavers.com
--- dlls/cfgmgr32/cfgmgr32.spec | 4 +- dlls/cfgmgr32/tests/Makefile.in | 2 +- dlls/cfgmgr32/tests/cfgmgr32.c | 70 ++++++++++++++++++ dlls/setupapi/devinst.c | 124 ++++++++++++++++++++++++++++++++ dlls/setupapi/setupapi.spec | 4 +- dlls/setupapi/stubs.c | 22 ------ include/cfgmgr32.h | 6 ++ 7 files changed, 205 insertions(+), 27 deletions(-)
diff --git a/dlls/cfgmgr32/cfgmgr32.spec b/dlls/cfgmgr32/cfgmgr32.spec index 29de7bbdc55..955482a5ec8 100644 --- a/dlls/cfgmgr32/cfgmgr32.spec +++ b/dlls/cfgmgr32/cfgmgr32.spec @@ -72,11 +72,11 @@ @ stdcall CM_Get_Device_ID_ListA(str ptr long long) setupapi.CM_Get_Device_ID_ListA @ stdcall CM_Get_Device_ID_ListW(wstr ptr long long) setupapi.CM_Get_Device_ID_ListW @ stub CM_Get_Device_ID_List_ExA -@ stub CM_Get_Device_ID_List_ExW +@ stdcall CM_Get_Device_ID_List_ExW(wstr ptr long long) setupapi.CM_Get_Device_ID_List_ExW @ stdcall CM_Get_Device_ID_List_SizeA(ptr str long) setupapi.CM_Get_Device_ID_List_SizeA @ stdcall CM_Get_Device_ID_List_SizeW(ptr wstr long) setupapi.CM_Get_Device_ID_List_SizeW @ stub CM_Get_Device_ID_List_Size_ExA -@ stub CM_Get_Device_ID_List_Size_ExW +@ stdcall CM_Get_Device_ID_List_Size_ExW(ptr wstr long ptr) setupapi.CM_Get_Device_ID_List_Size_ExW @ stdcall CM_Get_Device_ID_Size(ptr ptr long) setupapi.CM_Get_Device_ID_Size @ stub CM_Get_Device_ID_Size_Ex @ stdcall CM_Get_Device_Interface_AliasA(str ptr ptr ptr long) setupapi.CM_Get_Device_Interface_AliasA diff --git a/dlls/cfgmgr32/tests/Makefile.in b/dlls/cfgmgr32/tests/Makefile.in index 8b836ba3b76..03b5e5f8fb0 100644 --- a/dlls/cfgmgr32/tests/Makefile.in +++ b/dlls/cfgmgr32/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = cfgmgr32.dll -IMPORTS = cfgmgr32 +IMPORTS = cfgmgr32 ole32 uuid
SOURCES = \ cfgmgr32.c diff --git a/dlls/cfgmgr32/tests/cfgmgr32.c b/dlls/cfgmgr32/tests/cfgmgr32.c index 22344c45afc..da9796e019c 100644 --- a/dlls/cfgmgr32/tests/cfgmgr32.c +++ b/dlls/cfgmgr32/tests/cfgmgr32.c @@ -18,7 +18,16 @@
#include "wine/test.h" #include "winreg.h" +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "objbase.h" +#include "devguid.h" +#include "initguid.h" +#include "devpkey.h" +#include "setupapi.h" #include "cfgmgr32.h" +#include "ntddvdeo.h"
static void test_CM_MapCrToWin32Err(void) { @@ -106,7 +115,68 @@ static void test_CM_MapCrToWin32Err(void) } }
+static void test_CM_Get_Device_ID_List(void) +{ + WCHAR wguid_str[64], *wbuf, *wp; + unsigned int count; + CONFIGRET ret; + ULONG len; + + StringFromGUID2(&GUID_DEVCLASS_DISPLAY, wguid_str, ARRAY_SIZE(wguid_str)); + wp = wguid_str; + + ret = CM_Get_Device_ID_List_SizeW(NULL, wguid_str, CM_GETIDLIST_FILTER_CLASS); + ok(ret == CR_INVALID_POINTER, "got %#lx.\n", ret); + len = 0xdeadbeef; + ret = CM_Get_Device_ID_List_SizeW(&len, NULL, CM_GETIDLIST_FILTER_CLASS); + ok(ret == CR_INVALID_POINTER, "got %#lx.\n", ret); + ok(!len, "got %#lx.\n", len); + len = 0xdeadbeef; + ret = CM_Get_Device_ID_List_SizeW(&len, L"q", CM_GETIDLIST_FILTER_CLASS); + ok(ret == CR_INVALID_DATA, "got %#lx.\n", ret); + ok(!len, "got %#lx.\n", len); + + len = 0xdeadbeef; + ret = CM_Get_Device_ID_List_SizeW(&len, NULL, 0); + ok(!ret, "got %#lx.\n", ret); + ok(len > 2, "got %#lx.\n", len); + + wbuf = malloc(len * sizeof(*wbuf)); + + ret = CM_Get_Device_ID_ListW(NULL, wbuf, len, 0); + ok(!ret, "got %#lx.\n", ret); + + len = 0xdeadbeef; + ret = CM_Get_Device_ID_List_SizeW(&len, wguid_str, CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT); + ok(!ret, "got %#lx.\n", ret); + ok(len > 2, "got %lu.\n", len); + memset(wbuf, 0xcc, len * sizeof(*wbuf)); + ret = CM_Get_Device_ID_ListW(wguid_str, wbuf, 0, CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT); + ok(ret == CR_INVALID_POINTER, "got %#lx.\n", ret); + ok(wbuf[0] == 0xcccc, "got %#x.\n", wbuf[0]); + memset(wbuf, 0xcc, len * sizeof(*wbuf)); + ret = CM_Get_Device_ID_ListW(wguid_str, wbuf, 1, CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT); + ok(ret == CR_BUFFER_SMALL, "got %#lx.\n", ret); + ok(!wbuf[0], "got %#x.\n", wbuf[0]); + + memset(wbuf, 0xcc, len * sizeof(*wbuf)); + ret = CM_Get_Device_ID_ListW(wguid_str, wbuf, len, CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT); + ok(!ret, "got %#lx.\n", ret); + count = 0; + wp = wbuf; + while (*wp) + { + ++count; + ok(!wcsnicmp(wp, L"PCI\", 4) || !wcsnicmp(wp, L"VMBUS\", 6), "got %s.\n", debugstr_w(wp)); + wp += wcslen(wp) + 1; + } + ok(count, "got 0.\n"); + + free(wbuf); +} + START_TEST(cfgmgr32) { test_CM_MapCrToWin32Err(); + test_CM_Get_Device_ID_List(); } diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 4e406fe700e..4de7d5c9b14 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -4279,6 +4279,130 @@ CONFIGRET WINAPI CM_Get_Device_ID_Size(ULONG *len, DEVINST devnode, ULONG flags) return CR_SUCCESS; }
+static CONFIGRET get_device_id_list(const WCHAR *filter, WCHAR *buffer, ULONG *len, ULONG flags) +{ + const ULONG supported_flags = CM_GETIDLIST_FILTER_NONE | CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT; + SP_DEVINFO_DATA device = { sizeof(device) }; + CONFIGRET ret = CR_SUCCESS; + GUID guid, *pguid = NULL; + unsigned int i, id_len; + ULONG query_flags = 0; + HDEVINFO set; + WCHAR id[64]; + 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); + *len = needed; + return CR_SUCCESS; + } + + if (!buffer) + *len = 0; + + if (flags & CM_GETIDLIST_FILTER_CLASS) + { + if (!filter) + return CR_INVALID_POINTER; + if (IIDFromString((WCHAR *)filter, &guid)) + return CR_INVALID_DATA; + pguid = &guid; + } + + if (!buffer) + *len = needed; + + if (!pguid) + query_flags |= DIGCF_ALLCLASSES; + if (flags & CM_GETIDLIST_FILTER_PRESENT) + query_flags |= DIGCF_PRESENT; + + set = SetupDiGetClassDevsW(pguid, NULL, NULL, query_flags); + if (set == INVALID_HANDLE_VALUE) + return CR_SUCCESS; + + p = buffer; + for (i = 0; SetupDiEnumDeviceInfo(set, i, &device); ++i) + { + ret = SetupDiGetDeviceInstanceIdW(set, &device, id, sizeof(id), NULL); + if (!ret) continue; + id_len = wcslen(id) + 1; + needed += id_len; + if (buffer) + { + if (needed > *len) + { + SetupDiDestroyDeviceInfoList(set); + *buffer = 0; + return CR_BUFFER_SMALL; + } + memcpy(p, id, sizeof(*p) * id_len); + p += id_len; + } + } + SetupDiDestroyDeviceInfoList(set); + *len = needed; + if (buffer) + *p = 0; + return CR_SUCCESS; +} + +/*********************************************************************** + * CM_Get_Device_ID_List_ExW (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_ID_List_ExW(const WCHAR *filter, WCHAR *buffer, ULONG len, ULONG flags, HMACHINE machine) +{ + TRACE("%s %p %ld %#lx %p.\n", debugstr_w(filter), buffer, len, flags, machine); + + if (machine) + FIXME("machine %p.\n", machine); + + if (!buffer) + return CR_INVALID_POINTER; + + return get_device_id_list(filter, buffer, &len, flags); +} + +/*********************************************************************** + * CM_Get_Device_ID_ListW (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_ID_ListW(const WCHAR *filter, WCHAR *buffer, ULONG len, ULONG flags) +{ + return CM_Get_Device_ID_List_ExW(filter, buffer, len, flags, NULL); +} + +/*********************************************************************** + * CM_Get_Device_ID_List_Size_ExW (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExW(ULONG *len, const WCHAR *filter, ULONG flags, HMACHINE machine) +{ + TRACE("%p %s %#lx, machine %p.\n", len, debugstr_w(filter), flags, machine); + + if (machine) + FIXME("machine %p.\n", machine); + + return get_device_id_list(filter, NULL, len, flags); +} + +/*********************************************************************** + * CM_Get_Device_ID_List_SizeW (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_ID_List_SizeW(ULONG *len, const WCHAR *filter, ULONG flags) +{ + TRACE("%p %s %#lx.\n", len, debugstr_w(filter), flags); + + return get_device_id_list(filter, NULL, len, flags); +} + /*********************************************************************** * SetupDiGetINFClassA (SETUPAPI.@) */ diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index 958e26235ea..088466ce537 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -82,11 +82,11 @@ @ stdcall CM_Get_Device_ID_ListA(str ptr long long) @ stdcall CM_Get_Device_ID_ListW(wstr ptr long long) @ stub CM_Get_Device_ID_List_ExA -@ stub CM_Get_Device_ID_List_ExW +@ stdcall CM_Get_Device_ID_List_ExW(wstr ptr long long ptr) @ stdcall CM_Get_Device_ID_List_SizeA(ptr str long) @ stdcall CM_Get_Device_ID_List_SizeW(ptr wstr long) @ stub CM_Get_Device_ID_List_Size_ExA -@ stub CM_Get_Device_ID_List_Size_ExW +@ stdcall CM_Get_Device_ID_List_Size_ExW(ptr wstr long ptr) @ stdcall CM_Get_Device_ID_Size(ptr ptr long) @ stub CM_Get_Device_ID_Size_Ex @ stdcall CM_Get_Device_Interface_AliasA(str ptr ptr ptr long) diff --git a/dlls/setupapi/stubs.c b/dlls/setupapi/stubs.c index 75185de047c..f031afb48e3 100644 --- a/dlls/setupapi/stubs.c +++ b/dlls/setupapi/stubs.c @@ -142,18 +142,6 @@ CONFIGRET WINAPI CM_Get_Device_ID_ListA( return CR_SUCCESS; }
-/*********************************************************************** - * CM_Get_Device_ID_ListW (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_Device_ID_ListW( - PCWSTR pszFilter, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags ) -{ - FIXME("%s %p %ld 0x%08lx: stub\n", debugstr_w(pszFilter), Buffer, BufferLen, ulFlags); - - if (BufferLen >= 2) Buffer[0] = Buffer[1] = 0; - return CR_SUCCESS; -} - /*********************************************************************** * CM_Get_Device_ID_List_SizeA (SETUPAPI.@) */ @@ -164,16 +152,6 @@ CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA( PULONG pulLen, PCSTR pszFilter, return CR_SUCCESS; }
-/*********************************************************************** - * CM_Get_Device_ID_List_SizeW (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_Device_ID_List_SizeW( PULONG pulLen, PCWSTR pszFilter, ULONG ulFlags ) -{ - FIXME("%p %s 0x%08lx: stub\n", pulLen, debugstr_w(pszFilter), ulFlags); - - return CR_SUCCESS; -} - /*********************************************************************** * CM_Get_Parent (SETUPAPI.@) */ diff --git a/include/cfgmgr32.h b/include/cfgmgr32.h index b22a5ed585b..31e93290b49 100644 --- a/include/cfgmgr32.h +++ b/include/cfgmgr32.h @@ -302,9 +302,15 @@ CMAPI CONFIGRET WINAPI CM_Get_Device_ID_ExW(DEVINST,PWSTR,ULONG,ULONG,HMACHINE); CMAPI CONFIGRET WINAPI CM_Get_Device_ID_ListA(PCSTR,PCHAR,ULONG,ULONG); CMAPI CONFIGRET WINAPI CM_Get_Device_ID_ListW(PCWSTR,PWCHAR,ULONG,ULONG); #define CM_Get_Device_ID_List WINELIB_NAME_AW(CM_Get_Device_ID_List) +CMAPI CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA(PULONG,PCSTR,ULONG); +CMAPI CONFIGRET WINAPI CM_Get_Device_ID_List_SizeW(PULONG,PCWSTR,ULONG); +#define CM_Get_Device_ID_List_Size WINELIB_NAME_AW(CM_Get_Device_ID_List_Size) CMAPI CONFIGRET WINAPI CM_Get_Device_ID_List_ExA(PCSTR,PCHAR,ULONG,ULONG,HMACHINE); CMAPI CONFIGRET WINAPI CM_Get_Device_ID_List_ExW(PCWSTR,PWCHAR,ULONG,ULONG,HMACHINE); #define CM_Get_Device_ID_List_Ex WINELIB_NAME_AW(CM_Get_Device_ID_List_Ex) +CMAPI CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExA(PULONG,PCSTR,ULONG,HMACHINE); +CMAPI CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExW(PULONG,PCWSTR,ULONG,HMACHINE); +#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_PropertyW(LPCWSTR,const DEVPROPKEY*,DEVPROPTYPE*,PBYTE,PULONG,ULONG);