Merge branch 'vibhavp/setupapi-SetupDiGetDevicePropertyKeys' into 'master'

dlls/setupapi: Implement SetupDiGetDevicePropertyKeys

See merge request wine/wine!6744
This commit is contained in:
Vibhav Pant 2024-11-19 22:24:27 +00:00
commit 7bc568ff01
4 changed files with 198 additions and 0 deletions

View file

@ -4495,6 +4495,120 @@ static LSTATUS get_device_property(struct device *device, const DEVPROPKEY *prop
return ls;
}
BOOL WINAPI SetupDiGetDevicePropertyKeys( HDEVINFO devinfo, PSP_DEVINFO_DATA device_data,
DEVPROPKEY *prop_keys, DWORD prop_keys_len,
DWORD *required_prop_keys, DWORD flags )
{
struct device *device;
DWORD count = 0, i;
HKEY hkey;
LSTATUS ls;
DEVPROPKEY *keys_buf = NULL;
TRACE( "%p, %p, %p, %lu, %p, %#lx\n", devinfo, device_data, prop_keys, prop_keys_len,
required_prop_keys, flags);
if (flags)
{
SetLastError( ERROR_INVALID_FLAGS );
return FALSE;
}
if (!prop_keys && prop_keys_len)
{
SetLastError( ERROR_INVALID_USER_BUFFER );
return FALSE;
}
device = get_device( devinfo, device_data );
if (!device)
return FALSE;
ls = RegOpenKeyExW( device->key, L"Properties", 0, KEY_ENUMERATE_SUB_KEYS, &hkey );
if (ls)
{
SetLastError( ls );
return FALSE;
}
keys_buf = malloc( sizeof( *keys_buf ) * prop_keys_len );
if (!keys_buf && prop_keys_len)
{
RegCloseKey( hkey );
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE;
}
for (i = 0; ;i++)
{
WCHAR guid_str[39];
HKEY propkey;
DWORD len, j;
GUID prop_guid;
len = ARRAY_SIZE( guid_str );
ls = RegEnumKeyExW( hkey, i, guid_str, &len, NULL, NULL, NULL, NULL );
if (ls)
{
if (ls == ERROR_NO_MORE_ITEMS)
ls = ERROR_SUCCESS;
else
ERR( "Could not enumerate subkeys for device %s: %lu\n",
debugstr_w( device->instanceId ), ls );
break;
}
ls = RegOpenKeyExW( hkey, guid_str, 0, KEY_ENUMERATE_SUB_KEYS, &propkey );
if (ls)
break;
guid_str[37] = 0;
if (UuidFromStringW( &guid_str[1], &prop_guid ))
{
ERR( "Could not parse propkey GUID string %s\n", debugstr_w( &guid_str[1] ) );
RegCloseKey( propkey );
continue;
}
for (j = 0; ;j++)
{
DEVPROPID pid;
WCHAR key_name[6];
len = 5;
ls = RegEnumKeyExW( propkey, j, key_name, &len, NULL, NULL, NULL, NULL );
if (ls)
{
if (ls != ERROR_NO_MORE_ITEMS)
ERR( "Could not enumerate subkeys for device %s under %s: %lu\n", debugstr_w( device->instanceId ),
debugstr_guid( &prop_guid ), ls );
break;
}
swscanf( key_name, L"%04X", &pid );
if (++count <= prop_keys_len)
{
keys_buf[count-1].fmtid = prop_guid;
keys_buf[count-1].pid = pid;
}
}
RegCloseKey( propkey );
}
RegCloseKey( hkey );
if (!ls)
{
if (required_prop_keys)
*required_prop_keys = count;
if (prop_keys_len < count)
{
free( keys_buf );
SetLastError( ERROR_INSUFFICIENT_BUFFER );
return FALSE;
}
memcpy( prop_keys, keys_buf, count * sizeof( *keys_buf ) );
}
free( keys_buf );
SetLastError( ls );
return !ls;
}
/***********************************************************************
* SetupDiGetDevicePropertyW (SETUPAPI.@)
*/

View file

@ -357,6 +357,7 @@
@ stub SetupDiGetDeviceInterfaceAlias
@ stdcall SetupDiGetDeviceInterfaceDetailA(long ptr ptr long ptr ptr)
@ stdcall SetupDiGetDeviceInterfaceDetailW(long ptr ptr long ptr ptr)
@ stdcall SetupDiGetDevicePropertyKeys(ptr ptr ptr long ptr long)
@ stdcall SetupDiGetDevicePropertyW(ptr ptr ptr ptr ptr long ptr long)
@ stdcall SetupDiGetDeviceRegistryPropertyA(long ptr long ptr ptr long ptr)
@ stdcall SetupDiGetDeviceRegistryPropertyW(long ptr long ptr ptr long ptr)

View file

@ -56,6 +56,7 @@ static HRESULT (WINAPI *pDriverStoreFindDriverPackageA)(const char *inf_path, vo
static BOOL (WINAPI *pSetupDiSetDevicePropertyW)(HDEVINFO, SP_DEVINFO_DATA *, const DEVPROPKEY *, DEVPROPTYPE, const BYTE *, DWORD, DWORD);
static BOOL (WINAPI *pSetupDiGetDevicePropertyW)(HDEVINFO, SP_DEVINFO_DATA *, const DEVPROPKEY *, DEVPROPTYPE *, BYTE *, DWORD, DWORD *, DWORD);
static BOOL (WINAPI *pSetupQueryInfOriginalFileInformationA)(SP_INF_INFORMATION *, UINT, SP_ALTPLATFORM_INFO *, SP_ORIGINAL_FILE_INFO_A *);
static BOOL (WINAPI *pSetupDiGetDevicePropertyKeys)(HDEVINFO, PSP_DEVINFO_DATA, DEVPROPKEY *,DWORD, DWORD *, DWORD);
static BOOL wow64;
@ -885,6 +886,7 @@ static void test_device_property(void)
hmod = LoadLibraryA("setupapi.dll");
pSetupDiSetDevicePropertyW = (void *)GetProcAddress(hmod, "SetupDiSetDevicePropertyW");
pSetupDiGetDevicePropertyW = (void *)GetProcAddress(hmod, "SetupDiGetDevicePropertyW");
pSetupDiGetDevicePropertyKeys = (void *)GetProcAddress(hmod, "SetupDiGetDevicePropertyKeys");
if (!pSetupDiSetDevicePropertyW || !pSetupDiGetDevicePropertyW)
{
@ -1190,6 +1192,86 @@ static void test_device_property(void)
ok(size == sizeof(valueW), "Got size %ld\n", size);
ok(!lstrcmpW((WCHAR *)buffer, valueW), "Expect buffer %s, got %s\n", wine_dbgstr_w(valueW), wine_dbgstr_w((WCHAR *)buffer));
if (pSetupDiGetDevicePropertyKeys)
{
DWORD keys_len = 0, n, required_len, expected_keys = 1;
DEVPROPKEY *keys;
ret = pSetupDiGetDevicePropertyKeys(NULL, NULL, NULL, 0, NULL, 0);
ok(!ret, "Expect failure\n");
err = GetLastError();
ok(err == ERROR_INVALID_HANDLE, "Expect last error %#x, got %#lx\n",
ERROR_INVALID_HANDLE, err);
SetLastError(0xdeadbeef);
ret = pSetupDiGetDevicePropertyKeys(set, NULL, NULL, 0, NULL, 0);
ok(!ret, "Expect failure\n");
err = GetLastError();
ok(err == ERROR_INVALID_PARAMETER, "Expect last error %#x, got %#lx\n",
ERROR_INVALID_PARAMETER, err);
SetLastError(0xdeadbeef);
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, NULL, 10, NULL, 0);
ok(!ret, "Expect failure\n");
err = GetLastError();
ok(err == ERROR_INVALID_USER_BUFFER, "Expect last error %#x, got %#lx\n",
ERROR_INVALID_USER_BUFFER, err);
SetLastError(0xdeadbeef);
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, NULL, 0, NULL, 0);
ok(!ret, "Expect failure\n");
err = GetLastError();
ok(err == ERROR_INSUFFICIENT_BUFFER, "Expect last error %#x, got %#lx\n",
ERROR_INSUFFICIENT_BUFFER, err);
SetLastError(0xdeadbeef);
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, NULL, 0, &keys_len, 0xdeadbeef);
ok(!ret, "Expect failure\n");
err = GetLastError();
ok(err == ERROR_INVALID_FLAGS, "Expect last error %#x, got %#lx\n",
ERROR_INVALID_FLAGS, err);
SetLastError(0xdeadbeef);
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, NULL, 0, &keys_len, 0);
ok(!ret, "Expect failure\n");
err = GetLastError();
ok(err == ERROR_INSUFFICIENT_BUFFER, "Expect last error %#x, got %#lx\n",
ERROR_INSUFFICIENT_BUFFER, err);
keys = calloc(keys_len, sizeof(*keys));
ok(keys_len && !!keys, "Failed to allocate buffer\n");
SetLastError(0xdeadbeef);
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, keys, keys_len, &keys_len, 0xdeadbeef);
ok(!ret, "Expect failure\n");
err = GetLastError();
ok(err == ERROR_INVALID_FLAGS, "Expect last error %#x, got %#lx\n",
ERROR_INVALID_FLAGS, err);
required_len = 0xdeadbeef;
ret = SetupDiGetDevicePropertyKeys(set, &device_data, keys, keys_len, &required_len, 0);
ok(ret, "Expect success\n");
err = GetLastError();
ok(!err, "Expect last error %#x, got %#lx\n", ERROR_SUCCESS, err);
ok(keys_len == required_len, "%lu != %lu\n", keys_len, required_len);
ok(keys_len >= expected_keys, "Expected %lu >= %lu\n", keys_len, expected_keys);
keys_len = 0;
if (keys)
{
for (n = 0; n < required_len; n++)
{
if (!memcmp(&keys[n], &DEVPKEY_Device_FriendlyName, sizeof(keys[n])))
keys_len++;
}
}
ok(keys_len == expected_keys, "%lu != %lu\n", keys_len, expected_keys);
free(keys);
}
else
win_skip("SetupDiGetDevicePropertyKeys not available\n");
ret = SetupDiRemoveDevice(set, &device_data);
ok(ret, "Got unexpected error %#lx.\n", GetLastError());

View file

@ -1573,6 +1573,7 @@ WINSETUPAPI BOOL WINAPI SetupDiGetDeviceInterfaceAlias(HDEVINFO, PSP_DEVICE_
WINSETUPAPI BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA);
WINSETUPAPI BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA_W, DWORD, PDWORD, PSP_DEVINFO_DATA);
#define SetupDiGetDeviceInterfaceDetail WINELIB_NAME_AW(SetupDiGetDeviceInterfaceDetail)
WINSETUPAPI BOOL WINAPI SetupDiGetDevicePropertyKeys(HDEVINFO, PSP_DEVINFO_DATA, DEVPROPKEY *, DWORD, DWORD *, DWORD);
WINSETUPAPI BOOL WINAPI SetupDiGetDevicePropertyW(HDEVINFO, PSP_DEVINFO_DATA, const DEVPROPKEY *, DEVPROPTYPE *, BYTE *, DWORD, DWORD *, DWORD);
#define SetupDiGetDeviceProperty WINELIB_NAME_AW(SetupDiGetDeviceProperty) /* note: A function doesn't exist */
WINSETUPAPI BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD);