mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-19 17:06:04 -07:00
Merge branch 'vibhavp/setupapi-SetupDiGetDevicePropertyKeys' into 'master'
dlls/setupapi: Implement SetupDiGetDevicePropertyKeys See merge request wine/wine!6744
This commit is contained in:
commit
7bc568ff01
4 changed files with 198 additions and 0 deletions
|
@ -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.@)
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue