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,
|
DEVPROPKEY *prop_keys, DWORD prop_keys_len,
|
||||||
DWORD *required_prop_keys, DWORD flags )
|
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);
|
required_prop_keys, flags);
|
||||||
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
|
|
||||||
return FALSE;
|
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);
|
ret = pSetupDiGetDevicePropertyKeys(NULL, NULL, NULL, 0, NULL, 0);
|
||||||
ok(!ret, "Expect failure\n");
|
ok(!ret, "Expect failure\n");
|
||||||
err = GetLastError();
|
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);
|
ERROR_INVALID_HANDLE, err);
|
||||||
|
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = pSetupDiGetDevicePropertyKeys(set, NULL, NULL, 0, NULL, 0);
|
ret = pSetupDiGetDevicePropertyKeys(set, NULL, NULL, 0, NULL, 0);
|
||||||
ok(!ret, "Expect failure\n");
|
ok(!ret, "Expect failure\n");
|
||||||
err = GetLastError();
|
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);
|
ERROR_INVALID_PARAMETER, err);
|
||||||
|
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, NULL, 10, NULL, 0);
|
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, NULL, 10, NULL, 0);
|
||||||
ok(!ret, "Expect failure\n");
|
ok(!ret, "Expect failure\n");
|
||||||
err = GetLastError();
|
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);
|
ERROR_INVALID_USER_BUFFER, err);
|
||||||
|
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, NULL, 0, NULL, 0);
|
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, NULL, 0, NULL, 0);
|
||||||
ok(!ret, "Expect failure\n");
|
ok(!ret, "Expect failure\n");
|
||||||
err = GetLastError();
|
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);
|
ERROR_INSUFFICIENT_BUFFER, err);
|
||||||
|
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, NULL, 0, &keys_len, 0xdeadbeef);
|
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, NULL, 0, &keys_len, 0xdeadbeef);
|
||||||
ok(!ret, "Expect failure\n");
|
ok(!ret, "Expect failure\n");
|
||||||
err = GetLastError();
|
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);
|
ERROR_INVALID_FLAGS, err);
|
||||||
|
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, NULL, 0, &keys_len, 0);
|
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, NULL, 0, &keys_len, 0);
|
||||||
ok(!ret, "Expect failure\n");
|
ok(!ret, "Expect failure\n");
|
||||||
err = GetLastError();
|
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);
|
ERROR_INSUFFICIENT_BUFFER, err);
|
||||||
|
|
||||||
keys = calloc(keys_len, sizeof(*keys));
|
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);
|
SetLastError(0xdeadbeef);
|
||||||
|
|
||||||
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, keys, keys_len, &keys_len, 0xdeadbeef);
|
ret = pSetupDiGetDevicePropertyKeys(set, &device_data, keys, keys_len, &keys_len, 0xdeadbeef);
|
||||||
ok(!ret, "Expect failure\n");
|
ok(!ret, "Expect failure\n");
|
||||||
err = GetLastError();
|
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);
|
ERROR_INVALID_FLAGS, err);
|
||||||
|
|
||||||
required_len = 0xdeadbeef;
|
required_len = 0xdeadbeef;
|
||||||
ret = SetupDiGetDevicePropertyKeys(set, &device_data, keys, keys_len, &required_len, 0);
|
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();
|
err = GetLastError();
|
||||||
todo_wine ok(!err, "Expect last error %#x, got %#lx\n", ERROR_SUCCESS, err);
|
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);
|
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(keys_len >= expected_keys, "Expected %lu >= %lu\n", keys_len, expected_keys);
|
||||||
|
|
||||||
keys_len = 0;
|
keys_len = 0;
|
||||||
if (keys)
|
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);
|
free(keys);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue