mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-19 17:06:04 -07:00
setupapi: Implement SetupDiGetDevicePropertyKeys.
This commit is contained in:
parent
b6d427cae7
commit
044527c671
Notes:
Alexandre Julliard
2024-11-19 23:24:29 +01:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/wine/merge_requests/6744
2 changed files with 120 additions and 16 deletions
|
@ -4499,10 +4499,114 @@ BOOL WINAPI SetupDiGetDevicePropertyKeys( HDEVINFO devinfo, PSP_DEVINFO_DATA dev
|
|||
DEVPROPKEY *prop_keys, DWORD prop_keys_len,
|
||||
DWORD *required_prop_keys, DWORD flags )
|
||||
{
|
||||
FIXME( "%p, %p, %p, %lu, %p, %#lx stub!\n", devinfo, device_data, prop_keys, prop_keys_len,
|
||||
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);
|
||||
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -1200,61 +1200,61 @@ static void test_device_property(void)
|
|||
ret = pSetupDiGetDevicePropertyKeys(NULL, NULL, NULL, 0, NULL, 0);
|
||||
ok(!ret, "Expect failure\n");
|
||||
err = GetLastError();
|
||||
todo_wine ok(err == ERROR_INVALID_HANDLE, "Expect last error %#x, got %#lx\n",
|
||||
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();
|
||||
todo_wine ok(err == ERROR_INVALID_PARAMETER, "Expect last error %#x, got %#lx\n",
|
||||
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();
|
||||
todo_wine ok(err == ERROR_INVALID_USER_BUFFER, "Expect last error %#x, got %#lx\n",
|
||||
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();
|
||||
todo_wine ok(err == ERROR_INSUFFICIENT_BUFFER, "Expect last error %#x, got %#lx\n",
|
||||
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();
|
||||
todo_wine ok(err == ERROR_INVALID_FLAGS, "Expect last error %#x, got %#lx\n",
|
||||
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();
|
||||
todo_wine ok(err == ERROR_INSUFFICIENT_BUFFER, "Expect last error %#x, got %#lx\n",
|
||||
ok(err == ERROR_INSUFFICIENT_BUFFER, "Expect last error %#x, got %#lx\n",
|
||||
ERROR_INSUFFICIENT_BUFFER, err);
|
||||
|
||||
keys = calloc(keys_len, sizeof(*keys));
|
||||
todo_wine ok(keys_len && !!keys, "Failed to allocate buffer\n");
|
||||
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();
|
||||
todo_wine ok(err == ERROR_INVALID_FLAGS, "Expect last error %#x, got %#lx\n",
|
||||
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);
|
||||
todo_wine ok(ret, "Expect success\n");
|
||||
ok(ret, "Expect success\n");
|
||||
err = GetLastError();
|
||||
todo_wine ok(!err, "Expect last error %#x, got %#lx\n", ERROR_SUCCESS, err);
|
||||
todo_wine ok(keys_len == required_len, "%lu != %lu\n", keys_len, required_len);
|
||||
todo_wine ok(keys_len >= expected_keys, "Expected %lu >= %lu\n", keys_len, expected_keys);
|
||||
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)
|
||||
|
@ -1266,7 +1266,7 @@ static void test_device_property(void)
|
|||
}
|
||||
|
||||
}
|
||||
todo_wine ok(keys_len == expected_keys, "%lu != %lu\n", keys_len, expected_keys);
|
||||
ok(keys_len == expected_keys, "%lu != %lu\n", keys_len, expected_keys);
|
||||
free(keys);
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue