From: Paul Gofman pgofman@codeweavers.com
--- include/cfgmgr32.h | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/include/cfgmgr32.h b/include/cfgmgr32.h index 0893e42b399..b22a5ed585b 100644 --- a/include/cfgmgr32.h +++ b/include/cfgmgr32.h @@ -183,6 +183,19 @@ typedef DWORD CONFIGRET; #define CM_REMOVAL_POLICY_EXPECT_ORDERLY_REMOVAL 2 #define CM_REMOVAL_POLICY_EXPECT_SURPRISE_REMOVAL 3
+#define CM_GETIDLIST_FILTER_NONE 0x00000000 +#define CM_GETIDLIST_FILTER_ENUMERATOR 0x00000001 +#define CM_GETIDLIST_FILTER_SERVICE 0x00000002 +#define CM_GETIDLIST_FILTER_EJECTRELATIONS 0x00000004 +#define CM_GETIDLIST_FILTER_REMOVALRELATIONS 0x00000008 +#define CM_GETIDLIST_FILTER_POWERRELATIONS 0x00000010 +#define CM_GETIDLIST_FILTER_BUSRELATIONS 0x00000020 +#define CM_GETIDLIST_DONOTGENERATE 0x10000040 +#define CM_GETIDLIST_FILTER_TRANSPORTRELATIONS 0x00000080 +#define CM_GETIDLIST_FILTER_PRESENT 0x00000100 +#define CM_GETIDLIST_FILTER_CLASS 0x00000200 +#define CM_GETIDLIST_FILTER_BITS 0x100003FF + typedef DWORD DEVINST, *PDEVINST; typedef DWORD DEVNODE, *PDEVNODE; typedef HANDLE HMACHINE, *PHMACHINE;
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);
From: Paul Gofman pgofman@codeweavers.com
--- dlls/cfgmgr32/cfgmgr32.spec | 4 +- dlls/cfgmgr32/tests/cfgmgr32.c | 43 ++++++++++++++++ dlls/setupapi/devinst.c | 90 ++++++++++++++++++++++++++++++++++ dlls/setupapi/setupapi.spec | 4 +- dlls/setupapi/stubs.c | 22 --------- 5 files changed, 137 insertions(+), 26 deletions(-)
diff --git a/dlls/cfgmgr32/cfgmgr32.spec b/dlls/cfgmgr32/cfgmgr32.spec index 955482a5ec8..a990b2538eb 100644 --- a/dlls/cfgmgr32/cfgmgr32.spec +++ b/dlls/cfgmgr32/cfgmgr32.spec @@ -71,11 +71,11 @@ @ stdcall CM_Get_Device_ID_ExW(ptr ptr long long ptr) setupapi.CM_Get_Device_ID_ExW @ 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 +@ stdcall CM_Get_Device_ID_List_ExA(str ptr long long ptr) setupapi.CM_Get_Device_ID_List_ExA @ 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 +@ stdcall CM_Get_Device_ID_List_Size_ExA(ptr str long ptr) setupapi.CM_Get_Device_ID_List_Size_ExA @ 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 diff --git a/dlls/cfgmgr32/tests/cfgmgr32.c b/dlls/cfgmgr32/tests/cfgmgr32.c index da9796e019c..d6c27fab539 100644 --- a/dlls/cfgmgr32/tests/cfgmgr32.c +++ b/dlls/cfgmgr32/tests/cfgmgr32.c @@ -118,12 +118,16 @@ static void test_CM_MapCrToWin32Err(void) static void test_CM_Get_Device_ID_List(void) { WCHAR wguid_str[64], *wbuf, *wp; + char guid_str[64], *buf, *p; unsigned int count; CONFIGRET ret; ULONG len;
StringFromGUID2(&GUID_DEVCLASS_DISPLAY, wguid_str, ARRAY_SIZE(wguid_str)); wp = wguid_str; + p = guid_str; + while ((*p++ = *wp++)) + ;
ret = CM_Get_Device_ID_List_SizeW(NULL, wguid_str, CM_GETIDLIST_FILTER_CLASS); ok(ret == CR_INVALID_POINTER, "got %#lx.\n", ret); @@ -136,12 +140,24 @@ static void test_CM_Get_Device_ID_List(void) ok(ret == CR_INVALID_DATA, "got %#lx.\n", ret); ok(!len, "got %#lx.\n", len);
+ ret = CM_Get_Device_ID_List_SizeA(NULL, guid_str, CM_GETIDLIST_FILTER_CLASS); + ok(ret == CR_INVALID_POINTER, "got %#lx.\n", ret); + len = 0xdeadbeef; + ret = CM_Get_Device_ID_List_SizeA(&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_SizeA(&len, "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)); + buf = malloc(len);
ret = CM_Get_Device_ID_ListW(NULL, wbuf, len, 0); ok(!ret, "got %#lx.\n", ret); @@ -159,6 +175,19 @@ static void test_CM_Get_Device_ID_List(void) ok(ret == CR_BUFFER_SMALL, "got %#lx.\n", ret); ok(!wbuf[0], "got %#x.\n", wbuf[0]);
+ len = 0xdeadbeef; + ret = CM_Get_Device_ID_List_SizeA(&len, guid_str, CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT); + ok(!ret, "got %#lx.\n", ret); + ok(len > 2, "got %lu.\n", len); + memset(buf, 0x7c, len); + ret = CM_Get_Device_ID_ListA(guid_str, buf, 0, CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT); + ok(ret == CR_INVALID_POINTER, "got %#lx.\n", ret); + ok(buf[0] == 0x7c, "got %#x.\n", buf[0]); + memset(buf, 0x7c, len); + ret = CM_Get_Device_ID_ListA(guid_str, buf, 1, CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT); + ok(ret == CR_BUFFER_SMALL, "got %#lx.\n", ret); + ok(buf[0] == 0x7c, "got %#x.\n", buf[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); @@ -172,7 +201,21 @@ static void test_CM_Get_Device_ID_List(void) } ok(count, "got 0.\n");
+ memset(buf, 0xcc, len * sizeof(*buf)); + ret = CM_Get_Device_ID_ListA(guid_str, buf, len, CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT); + ok(!ret, "got %#lx.\n", ret); + count = 0; + p = buf; + while (*p) + { + ++count; + ok(!strnicmp(p, "PCI\", 4) || !strnicmp(p, "VMBUS\", 6), "got %s.\n", debugstr_a(p)); + p += strlen(p) + 1; + } + ok(count, "got 0.\n"); + free(wbuf); + free(buf); }
START_TEST(cfgmgr32) diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 4de7d5c9b14..139f167a2f2 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -4403,6 +4403,96 @@ CONFIGRET WINAPI CM_Get_Device_ID_List_SizeW(ULONG *len, const WCHAR *filter, UL return get_device_id_list(filter, NULL, len, flags); }
+/*********************************************************************** + * CM_Get_Device_ID_List_ExA (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_ID_List_ExA(const char *filter, char *buffer, ULONG len, ULONG flags, HMACHINE machine) +{ + WCHAR *wbuffer, *wfilter = NULL, *p; + unsigned int slen; + CONFIGRET ret; + + TRACE("%s %p %ld %#lx.\n", debugstr_a(filter), buffer, len, flags); + + if (machine) + FIXME("machine %p.\n", machine); + + if (!buffer || !len) + return CR_INVALID_POINTER; + + if (!(wbuffer = malloc(len * sizeof(*wbuffer)))) + return CR_OUT_OF_MEMORY; + + if (filter) + { + slen = strlen(filter) + 1; + if (!(wfilter = malloc(slen * sizeof(*wfilter)))) + { + free(wbuffer); + return CR_OUT_OF_MEMORY; + } + MultiByteToWideChar(CP_ACP, 0, filter, slen, wfilter, slen); + } + + if (!(ret = CM_Get_Device_ID_ListW(wfilter, wbuffer, len, flags))) + { + p = wbuffer; + while (*p) + { + slen = wcslen(p) + 1; + WideCharToMultiByte(CP_ACP, 0, p, slen, buffer, slen, NULL, NULL); + p += slen; + buffer += slen; + } + *buffer = 0; + } + free(wfilter); + free(wbuffer); + return ret; +} + +/*********************************************************************** + * CM_Get_Device_ID_ListA (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_ID_ListA(const char *filter, char *buffer, ULONG len, ULONG flags) +{ + return CM_Get_Device_ID_List_ExA(filter, buffer, len, flags, NULL); +} + +/*********************************************************************** + * CM_Get_Device_ID_List_Size_ExA (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExA(ULONG *len, const char *filter, ULONG flags, HMACHINE machine) +{ + WCHAR *wfilter = NULL; + unsigned int slen; + CONFIGRET ret; + + TRACE("%p %s %#lx.\n", len, debugstr_a(filter), flags); + + if (machine) + FIXME("machine %p.\n", machine); + + if (filter) + { + slen = strlen(filter) + 1; + if (!(wfilter = malloc(slen * sizeof(*wfilter)))) + return CR_OUT_OF_MEMORY; + MultiByteToWideChar(CP_ACP, 0, filter, slen, wfilter, slen); + } + ret = CM_Get_Device_ID_List_SizeW(len, wfilter, flags); + free(wfilter); + return ret; +} + +/*********************************************************************** + * CM_Get_Device_ID_List_SizeA (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA(ULONG *len, const char *filter, ULONG flags) +{ + return CM_Get_Device_ID_List_Size_ExA(len, filter, flags, NULL); +} + /*********************************************************************** * SetupDiGetINFClassA (SETUPAPI.@) */ diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index 088466ce537..f77cb301dfe 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -81,11 +81,11 @@ @ stdcall CM_Get_Device_ID_ExW(ptr ptr long long ptr) @ 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 +@ stdcall CM_Get_Device_ID_List_ExA(str ptr long long ptr) @ 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 +@ stdcall CM_Get_Device_ID_List_Size_ExA(ptr str long ptr) @ 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 diff --git a/dlls/setupapi/stubs.c b/dlls/setupapi/stubs.c index f031afb48e3..419168d0f1e 100644 --- a/dlls/setupapi/stubs.c +++ b/dlls/setupapi/stubs.c @@ -130,28 +130,6 @@ DWORD WINAPI CM_Get_Device_ID_ExW( return CR_SUCCESS; }
-/*********************************************************************** - * CM_Get_Device_ID_ListA (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_Device_ID_ListA( - PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags ) -{ - FIXME("%s %p %ld 0x%08lx: stub\n", debugstr_a(pszFilter), Buffer, BufferLen, ulFlags); - - if (BufferLen >= 2) Buffer[0] = Buffer[1] = 0; - return CR_SUCCESS; -} - -/*********************************************************************** - * CM_Get_Device_ID_List_SizeA (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA( PULONG pulLen, PCSTR pszFilter, ULONG ulFlags ) -{ - FIXME("%p %s 0x%08lx: stub\n", pulLen, debugstr_a(pszFilter), ulFlags); - - return CR_SUCCESS; -} - /*********************************************************************** * CM_Get_Parent (SETUPAPI.@) */
From: Paul Gofman pgofman@codeweavers.com
--- dlls/cfgmgr32/tests/Makefile.in | 2 +- dlls/cfgmgr32/tests/cfgmgr32.c | 45 ++++++++++++-- dlls/setupapi/devinst.c | 106 ++++++++++++++++++-------------- include/cfgmgr32.h | 2 + 4 files changed, 103 insertions(+), 52 deletions(-)
diff --git a/dlls/cfgmgr32/tests/Makefile.in b/dlls/cfgmgr32/tests/Makefile.in index 03b5e5f8fb0..64a01ccf492 100644 --- a/dlls/cfgmgr32/tests/Makefile.in +++ b/dlls/cfgmgr32/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = cfgmgr32.dll -IMPORTS = cfgmgr32 ole32 uuid +IMPORTS = cfgmgr32 setupapi ole32 uuid
SOURCES = \ cfgmgr32.c diff --git a/dlls/cfgmgr32/tests/cfgmgr32.c b/dlls/cfgmgr32/tests/cfgmgr32.c index d6c27fab539..f811410a6fd 100644 --- a/dlls/cfgmgr32/tests/cfgmgr32.c +++ b/dlls/cfgmgr32/tests/cfgmgr32.c @@ -115,12 +115,22 @@ static void test_CM_MapCrToWin32Err(void) } }
+DEFINE_DEVPROPKEY(DEVPROPKEY_GPU_LUID, 0x60b193cb, 0x5276, 0x4d0f, 0x96, 0xfc, 0xf1, 0x73, 0xab, 0xad, 0x3e, 0xc6, 2); + static void test_CM_Get_Device_ID_List(void) { - WCHAR wguid_str[64], *wbuf, *wp; + struct + { + WCHAR id[128]; + DEVINST inst; + } + instances[128]; + SP_DEVINFO_DATA device = { sizeof(device) }; + unsigned int i, count, expected_count; + WCHAR wguid_str[64], id[128], *wbuf, *wp; char guid_str[64], *buf, *p; - unsigned int count; CONFIGRET ret; + HDEVINFO set; ULONG len;
StringFromGUID2(&GUID_DEVCLASS_DISPLAY, wguid_str, ARRAY_SIZE(wguid_str)); @@ -188,6 +198,33 @@ static void test_CM_Get_Device_ID_List(void) ok(ret == CR_BUFFER_SMALL, "got %#lx.\n", ret); ok(buf[0] == 0x7c, "got %#x.\n", buf[0]);
+ set = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY, NULL, NULL, DIGCF_PRESENT); + ok(set != &GUID_DEVCLASS_DISPLAY, "got error %#lx.\n", GetLastError()); + for (i = 0; SetupDiEnumDeviceInfo(set, i, &device); ++i) + { + ok(i < ARRAY_SIZE(instances), "got %u.\n", i); + ret = SetupDiGetDeviceInstanceIdW(set, &device, instances[i].id, sizeof(instances[i].id), NULL); + ok(ret, "got error %#lx.\n", GetLastError()); + instances[i].inst = device.DevInst; + } + SetupDiDestroyDeviceInfoList(set); + expected_count = i; + for (i = 0; i < expected_count; ++i) + { + DEVPROPTYPE type; + ULONG size; + + *id = 0; + ret = CM_Get_Device_IDW(instances[i].inst, id, ARRAY_SIZE(id), 0); + ok(!ret, "got %#lx.\n", ret); + ok(!wcscmp(id, instances[i].id), "got %s, expected %s.\n", debugstr_w(id), debugstr_w(instances[i].id)); + size = len; + ret = CM_Get_DevNode_PropertyW(instances[i].inst, &DEVPROPKEY_GPU_LUID, &type, wbuf, &size, 0); + ok(!ret || ret == CR_NO_SUCH_VALUE, "got %#lx.\n", ret); + if (!ret) + ok(type == DEVPROP_TYPE_UINT64, "got %#lx.\n", type); + } + 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); @@ -199,7 +236,7 @@ static void test_CM_Get_Device_ID_List(void) 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"); + ok(count == expected_count, "got %u, expected %u.\n", count, expected_count);
memset(buf, 0xcc, len * sizeof(*buf)); ret = CM_Get_Device_ID_ListA(guid_str, buf, len, CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT); @@ -212,7 +249,7 @@ static void test_CM_Get_Device_ID_List(void) ok(!strnicmp(p, "PCI\", 4) || !strnicmp(p, "VMBUS\", 6), "got %s.\n", debugstr_a(p)); p += strlen(p) + 1; } - ok(count, "got 0.\n"); + ok(count == expected_count, "got %u, expected %u.\n", count, expected_count);
free(wbuf); free(buf); diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 139f167a2f2..4947d664583 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -286,50 +286,45 @@ static inline void copy_device_iface_data(SP_DEVICE_INTERFACE_DATA *data, data->Reserved = (ULONG_PTR)iface; }
-static struct device **devnode_table; -static unsigned int devnode_table_size; +static WCHAR **devinst_table; +static unsigned int devinst_table_size;
-static DEVINST alloc_devnode(struct device *device) +static DEVINST get_devinst_for_device_id(const WCHAR *id) { unsigned int i;
- for (i = 0; i < devnode_table_size; ++i) + for (i = 0; i < devinst_table_size; ++i) { - if (!devnode_table[i]) + if (!devinst_table[i]) break; + if (!wcsicmp(devinst_table[i], id)) + return i; } + return i; +}
- if (i == devnode_table_size) +static DEVINST alloc_devinst_for_device_id(const WCHAR *id) +{ + DEVINST ret; + + ret = get_devinst_for_device_id(id); + if (ret == devinst_table_size) { - if (devnode_table) + if (devinst_table) { - devnode_table = realloc(devnode_table, devnode_table_size * 2 * sizeof(*devnode_table)); - memset(devnode_table + devnode_table_size, 0, devnode_table_size * sizeof(*devnode_table)); - devnode_table_size *= 2; + devinst_table = realloc(devinst_table, devinst_table_size * 2 * sizeof(*devinst_table)); + memset(devinst_table + devinst_table_size, 0, devinst_table_size * sizeof(*devinst_table)); + devinst_table_size *= 2; } else { - devnode_table_size = 256; - devnode_table = calloc(devnode_table_size, sizeof(*devnode_table)); + devinst_table_size = 256; + devinst_table = calloc(devinst_table_size, sizeof(*devinst_table)); } } - - devnode_table[i] = device; - return i; -} - -static void free_devnode(DEVINST devnode) -{ - devnode_table[devnode] = NULL; -} - -static struct device *get_devnode_device(DEVINST devnode) -{ - if (devnode < devnode_table_size) - return devnode_table[devnode]; - - WARN("device node %lu not found\n", devnode); - return NULL; + if (!devinst_table[ret]) + devinst_table[ret] = wcsdup(id); + return ret; }
static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr) @@ -884,7 +879,6 @@ static void delete_device(struct device *device) { delete_device_iface(iface); } - free_devnode(device->devnode); list_remove(&device->entry); free(device); } @@ -930,7 +924,7 @@ static struct device *create_device(struct DeviceInfoSet *set, device->phantom = phantom; list_init(&device->interfaces); device->class = *class; - device->devnode = alloc_devnode(device); + device->devnode = alloc_devinst_for_device_id(device->instanceId); device->removed = FALSE; list_add_tail(&set->devices, &device->entry); device->params.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W); @@ -952,6 +946,28 @@ static struct device *create_device(struct DeviceInfoSet *set, return device; }
+static struct device *get_devnode_device(DEVINST devnode, HDEVINFO *set) +{ + SP_DEVINFO_DATA data = { sizeof(data) }; + + *set = NULL; + if (devnode >= devinst_table_size || !devinst_table[devnode]) + { + WARN("device node %lu not found\n", devnode); + return NULL; + } + + *set = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL); + if (*set == INVALID_HANDLE_VALUE) return NULL; + if (!SetupDiOpenDeviceInfoW(*set, devinst_table[devnode], NULL, 0, &data)) + { + SetupDiDestroyDeviceInfoList(*set); + *set = NULL; + return NULL; + } + return get_device(*set, &data); +} + /*********************************************************************** * SetupDiBuildClassInfoList (SETUPAPI.@) * @@ -4234,14 +4250,12 @@ BOOL WINAPI SetupDiDeleteDevRegKey(HDEVINFO devinfo, SP_DEVINFO_DATA *device_dat */ CONFIGRET WINAPI CM_Get_Device_IDA(DEVINST devnode, char *buffer, ULONG len, ULONG flags) { - struct device *device = get_devnode_device(devnode); - TRACE("%lu, %p, %lu, %#lx\n", devnode, buffer, len, flags);
- if (!device) + if (devnode >= devinst_table_size || !devinst_table[devnode]) return CR_NO_SUCH_DEVINST;
- WideCharToMultiByte(CP_ACP, 0, device->instanceId, -1, buffer, len, 0, 0); + WideCharToMultiByte(CP_ACP, 0, devinst_table[devnode], -1, buffer, len, 0, 0); TRACE("Returning %s\n", debugstr_a(buffer)); return CR_SUCCESS; } @@ -4251,14 +4265,12 @@ CONFIGRET WINAPI CM_Get_Device_IDA(DEVINST devnode, char *buffer, ULONG len, ULO */ CONFIGRET WINAPI CM_Get_Device_IDW(DEVINST devnode, WCHAR *buffer, ULONG len, ULONG flags) { - struct device *device = get_devnode_device(devnode); - TRACE("%lu, %p, %lu, %#lx\n", devnode, buffer, len, flags);
- if (!device) + if (devnode >= devinst_table_size || !devinst_table[devnode]) return CR_NO_SUCH_DEVINST;
- lstrcpynW(buffer, device->instanceId, len); + lstrcpynW(buffer, devinst_table[devnode], len); TRACE("Returning %s\n", debugstr_w(buffer)); return CR_SUCCESS; } @@ -4268,14 +4280,12 @@ CONFIGRET WINAPI CM_Get_Device_IDW(DEVINST devnode, WCHAR *buffer, ULONG len, UL */ CONFIGRET WINAPI CM_Get_Device_ID_Size(ULONG *len, DEVINST devnode, ULONG flags) { - struct device *device = get_devnode_device(devnode); - TRACE("%p, %lu, %#lx\n", len, devnode, flags);
- if (!device) + if (devnode >= devinst_table_size || !devinst_table[devnode]) return CR_NO_SUCH_DEVINST;
- *len = lstrlenW(device->instanceId); + *len = lstrlenW(devinst_table[devnode]); return CR_SUCCESS; }
@@ -4851,7 +4861,8 @@ BOOL WINAPI SetupDiGetDevicePropertyW(HDEVINFO devinfo, PSP_DEVINFO_DATA device_ CONFIGRET WINAPI CM_Get_DevNode_Property_ExW(DEVINST devnode, const DEVPROPKEY *prop_key, DEVPROPTYPE *prop_type, BYTE *prop_buff, ULONG *prop_buff_size, ULONG flags, HMACHINE machine) { - struct device *device = get_devnode_device(devnode); + HDEVINFO set; + struct device *device; LSTATUS ls;
TRACE("%lu, %p, %p, %p, %p, %#lx, %p\n", devnode, prop_key, prop_type, prop_buff, prop_buff_size, @@ -4860,13 +4871,14 @@ CONFIGRET WINAPI CM_Get_DevNode_Property_ExW(DEVINST devnode, const DEVPROPKEY * if (machine) return CR_MACHINE_UNAVAILABLE;
- if (!device) - return CR_NO_SUCH_DEVINST; - if (!prop_buff_size) return CR_INVALID_POINTER;
+ if (!(device = get_devnode_device(devnode, &set))) + return CR_NO_SUCH_DEVINST; + ls = get_device_property(device, prop_key, prop_type, prop_buff, *prop_buff_size, prop_buff_size, flags); + SetupDiDestroyDeviceInfoList(set); switch (ls) { case NO_ERROR: diff --git a/include/cfgmgr32.h b/include/cfgmgr32.h index 31e93290b49..90e25aac4f5 100644 --- a/include/cfgmgr32.h +++ b/include/cfgmgr32.h @@ -314,6 +314,8 @@ CMAPI CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExW(PULONG,PCWSTR,ULONG,HMACHI 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); +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); CMAPI CONFIGRET WINAPI CM_Get_DevNode_Status(PULONG,PULONG,DEVINST,ULONG); CMAPI CONFIGRET WINAPI CM_Get_DevNode_Status_Ex(PULONG,PULONG,DEVINST,ULONG,HMACHINE); CMAPI CONFIGRET WINAPI CM_Get_Sibling(PDEVINST,DEVINST,ULONG);
From: Paul Gofman pgofman@codeweavers.com
--- dlls/cfgmgr32/tests/cfgmgr32.c | 29 +++++++++++- dlls/setupapi/devinst.c | 81 ++++++++++++++++++++++++++++++++++ dlls/setupapi/stubs.c | 40 ----------------- include/cfgmgr32.h | 2 + 4 files changed, 111 insertions(+), 41 deletions(-)
diff --git a/dlls/cfgmgr32/tests/cfgmgr32.c b/dlls/cfgmgr32/tests/cfgmgr32.c index f811410a6fd..1e949093689 100644 --- a/dlls/cfgmgr32/tests/cfgmgr32.c +++ b/dlls/cfgmgr32/tests/cfgmgr32.c @@ -128,7 +128,8 @@ static void test_CM_Get_Device_ID_List(void) SP_DEVINFO_DATA device = { sizeof(device) }; unsigned int i, count, expected_count; WCHAR wguid_str[64], id[128], *wbuf, *wp; - char guid_str[64], *buf, *p; + char guid_str[64], id_a[128], *buf, *p; + DEVINST devinst; CONFIGRET ret; HDEVINFO set; ULONG len; @@ -209,6 +210,19 @@ static void test_CM_Get_Device_ID_List(void) } SetupDiDestroyDeviceInfoList(set); expected_count = i; + ok(expected_count, "got 0.\n"); + + wcscpy(id, L"q"); + devinst = 0xdeadbeef; + ret = CM_Locate_DevNodeW(&devinst, id, 0); + todo_wine_if(ret == CR_NO_SUCH_DEVNODE) ok(ret == CR_INVALID_DEVICE_ID, "got %#lx.\n", ret); + ok(!devinst, "got %#lx.\n", devinst); + + wcscpy(id, instances[0].id); + id[0] = 'Q'; + ret = CM_Locate_DevNodeW(&devinst, id, 0); + ok(ret == CR_NO_SUCH_DEVNODE, "got %#lx.\n", ret); + for (i = 0; i < expected_count; ++i) { DEVPROPTYPE type; @@ -223,6 +237,19 @@ static void test_CM_Get_Device_ID_List(void) ok(!ret || ret == CR_NO_SUCH_VALUE, "got %#lx.\n", ret); if (!ret) ok(type == DEVPROP_TYPE_UINT64, "got %#lx.\n", type); + + devinst = 0xdeadbeef; + ret = CM_Locate_DevNodeW(&devinst, instances[i].id, 0); + ok(!ret, "got %#lx, id %s.\n", ret, debugstr_w(instances[i].id)); + ok(devinst == instances[i].inst, "got %#lx, expected %#lx.\n", devinst, instances[i].inst); + p = id_a; + wp = instances[i].id; + while((*p++ = *wp++)) + ; + devinst = 0xdeadbeef; + ret = CM_Locate_DevNodeA(&devinst, id_a, 0); + ok(!ret, "got %#lx, id %s.\n", ret, debugstr_a(id_a)); + ok(devinst == instances[i].inst, "got %#lx, expected %#lx.\n", devinst, instances[i].inst); }
memset(wbuf, 0xcc, len * sizeof(*wbuf)); diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 4947d664583..596c6fcd90d 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -4289,6 +4289,87 @@ CONFIGRET WINAPI CM_Get_Device_ID_Size(ULONG *len, DEVINST devnode, ULONG flags) return CR_SUCCESS; }
+/*********************************************************************** + * CM_Locate_DevNodeA (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Locate_DevNodeA(DEVINST *devinst, DEVINSTID_A device_id, ULONG flags) +{ + TRACE("%p %s %#lx.\n", devinst, debugstr_a(device_id), flags); + + return CM_Locate_DevNode_ExA(devinst, device_id, flags, NULL); +} + +/*********************************************************************** + * CM_Locate_DevNodeW (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Locate_DevNodeW(DEVINST *devinst, DEVINSTID_W device_id, ULONG flags) +{ + TRACE("%p %s %#lx.\n", devinst, debugstr_w(device_id), flags); + + return CM_Locate_DevNode_ExW(devinst, device_id, flags, NULL); +} + +/*********************************************************************** + * CM_Locate_DevNode_ExA (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Locate_DevNode_ExA(DEVINST *devinst, DEVINSTID_A device_id, ULONG flags, HMACHINE machine) +{ + CONFIGRET ret; + DEVINSTID_W device_idw; + unsigned int slen; + + TRACE("%p %s %#lx %p.\n", devinst, debugstr_a(device_id), flags, machine); + + if (!device_id) + { + FIXME("NULL device_id unsupported.\n"); + return CR_CALL_NOT_IMPLEMENTED; + } + + slen = strlen(device_id) + 1; + if (!(device_idw = malloc(slen * sizeof(*device_idw)))) + return CR_OUT_OF_MEMORY; + + MultiByteToWideChar(CP_ACP, 0, device_id, slen, device_idw, slen); + ret = CM_Locate_DevNode_ExW(devinst, device_idw, flags, NULL); + free(device_idw); + return ret; +} + +/*********************************************************************** + * CM_Locate_DevNode_ExW (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Locate_DevNode_ExW(DEVINST *devinst, DEVINSTID_W device_id, ULONG flags, HMACHINE machine) +{ + DEVINST ret; + + TRACE("%p %s %#lx %p.\n", devinst, debugstr_w(device_id), flags, machine); + + if (!devinst) + return CR_INVALID_POINTER; + + *devinst = 0; + + if (machine) + FIXME("machine %p not supported.\n", machine); + if (flags) + FIXME("flags %#lx are not supported.\n", flags); + + if (!device_id) + { + FIXME("NULL device_id unsupported.\n"); + return CR_CALL_NOT_IMPLEMENTED; + } + + if ((ret = get_devinst_for_device_id(device_id)) < devinst_table_size && devinst_table[ret]) + { + *devinst = ret; + return CR_SUCCESS; + } + + return CR_NO_SUCH_DEVNODE; +} + 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; diff --git a/dlls/setupapi/stubs.c b/dlls/setupapi/stubs.c index 419168d0f1e..0766b1364bf 100644 --- a/dlls/setupapi/stubs.c +++ b/dlls/setupapi/stubs.c @@ -267,46 +267,6 @@ BOOL WINAPI SetupDiGetClassImageIndex(PSP_CLASSIMAGELIST_DATA ClassImageListData return FALSE; }
-/*********************************************************************** - * CM_Locate_DevNodeA (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Locate_DevNodeA(PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags) -{ - FIXME("%p %s 0x%08lx: stub\n", pdnDevInst, debugstr_a(pDeviceID), ulFlags); - - return CR_FAILURE; -} - -/*********************************************************************** - * CM_Locate_DevNodeW (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Locate_DevNodeW(PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags) -{ - FIXME("%p %s 0x%08lx: stub\n", pdnDevInst, debugstr_w(pDeviceID), ulFlags); - - return CR_FAILURE; -} - -/*********************************************************************** - * CM_Locate_DevNode_ExA (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Locate_DevNode_ExA(PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags, HMACHINE hMachine) -{ - FIXME("%p %s 0x%08lx %p: stub\n", pdnDevInst, debugstr_a(pDeviceID), ulFlags, hMachine); - - return CR_FAILURE; -} - -/*********************************************************************** - * CM_Locate_DevNode_ExW (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Locate_DevNode_ExW(PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags, HMACHINE hMachine) -{ - FIXME("%p %s 0x%08lx %p: stub\n", pdnDevInst, debugstr_w(pDeviceID), ulFlags, hMachine); - - return CR_FAILURE; -} - /*********************************************************************** * CM_Get_Device_Interface_List_SizeA (SETUPAPI.@) */ diff --git a/include/cfgmgr32.h b/include/cfgmgr32.h index 90e25aac4f5..7f1036f3510 100644 --- a/include/cfgmgr32.h +++ b/include/cfgmgr32.h @@ -322,7 +322,9 @@ CMAPI CONFIGRET WINAPI CM_Get_Sibling(PDEVINST,DEVINST,ULONG); CMAPI CONFIGRET WINAPI CM_Get_Sibling_Ex(PDEVINST pdnDevInst, DEVINST DevInst, ULONG ulFlags, HMACHINE hMachine); CMAPI WORD WINAPI CM_Get_Version(void); CMAPI CONFIGRET WINAPI CM_Locate_DevNodeA(PDEVINST,DEVINSTID_A,ULONG); +CMAPI CONFIGRET WINAPI CM_Locate_DevNode_ExA(PDEVINST,DEVINSTID_A,ULONG,HMACHINE); CMAPI CONFIGRET WINAPI CM_Locate_DevNodeW(PDEVINST,DEVINSTID_W,ULONG); +CMAPI CONFIGRET WINAPI CM_Locate_DevNode_ExW(PDEVINST,DEVINSTID_W,ULONG,HMACHINE); #define CM_Locate_DevNode WINELIB_NAME_AW(CM_Locate_DevNode) CMAPI DWORD WINAPI CM_MapCrToWin32Err(CONFIGRET,DWORD); CMAPI CONFIGRET WINAPI CM_Open_DevNode_Key(DEVINST dnDevInst, REGSAM access, ULONG ulHardwareProfile,
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=151054
Your paranoid android.
=== debian11b (64 bit WoW report) ===
mf: mf.c:6536: Test failed: Test 3: Unexpected hr 0xc00d36b2.
user32: input.c:4306: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00000000011A00E2, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
This fixes crashes in an Intell XESS library wrapper in a range of games. Which mostly happens when Intel GPU is selected but with, e. g., Marvel Rivals happens on any GPU while the wrapper enumerates devices and doesn't handle failures on the specific places of that path. I think for some versions of this wrapper it is technically a regression from introducing some functions and stubs earlier, while some of them unavailable or returning fail that could fail gracefully.
Patch 4 also fixes existing functions CM_Get_Device_ID / CM_Get_DevNode_Property which were essentially non-functional, those assumed the presence of the cached device which was only possible if something had the enumeration of the same devices open.