From: Vibhav Pant vibhavp@gmail.com
--- dlls/setupapi/devinst.c | 109 +++++++++++++++++++++++++++++++++- dlls/setupapi/tests/devinst.c | 26 ++++---- 2 files changed, 119 insertions(+), 16 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 4334e9e5cf3..544d4ae62a7 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -4499,10 +4499,113 @@ 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, %ld, %p, %#lx) stub!\n", devinfo, device_data, prop_keys, prop_keys_len, + WCHAR props_path[] = L"Properties\"; + struct device *device; + DWORD count = 0, i; + HKEY hkey; + LSTATUS ls; + DEVPROPKEY *keys_buf = NULL; + + TRACE( "(%p, %p, %p, %ld, %p, %#lx)\n", devinfo, device_data, prop_keys, prop_keys_len, 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, props_path, 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], key_name[55]; + HKEY propkey; + DWORD len, j; + GUID prop_guid; + + len = 39; + 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; + } + swprintf( key_name, ARRAY_SIZE( key_name ), L"Properties\%s", guid_str ); + ls = RegOpenKeyExW( device->key, key_name, 0, KEY_ENUMERATE_SUB_KEYS, &propkey ); + if (ls) + break; + if (FAILED( CLSIDFromString( guid_str, &prop_guid ) )) + { + ERR( "Could not parse propkey GUID string %s\n", debugstr_w( guid_str ) ); + RegCloseKey( propkey ); + continue; + } + for (j = 0; ;j++) + { + DEVPROPID pid; + + len = 5; + ls = RegEnumKeyExW( propkey, j, key_name, &len, NULL, NULL, NULL, NULL ); + if (ls) + { + ERR( "Could not enumerate subkeys for device %s under %s: %lu\n", debugstr_w( key_name ), + debugstr_w( key_name ), 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; }
/*********************************************************************** diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index 5f33c7af6e8..25a39870bc0 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -1200,62 +1200,62 @@ static void test_device_property(void) ret = SetupDiGetDevicePropertyKeys(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 = SetupDiGetDevicePropertyKeys(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 = SetupDiGetDevicePropertyKeys(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 = SetupDiGetDevicePropertyKeys(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 = SetupDiGetDevicePropertyKeys(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 = SetupDiGetDevicePropertyKeys(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 = malloc(sizeof(*keys) * keys_len); - todo_wine ok(keys_len && !!keys, "Failed to allocate buffer\n"); + ok(keys_len && !!keys, "Failed to allocate buffer\n"); SetLastError(0xdeadbeef);
ret = SetupDiGetDevicePropertyKeys(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);
n = keys_len; keys_len = 0xdeadbeef; ret = SetupDiGetDevicePropertyKeys(set, &device_data, keys, keys_len, &keys_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(n == keys_len, "%ld != %ld\n", n, keys_len); - todo_wine ok(n >= expected_keys, "Expected %ld >= %ld\n", n, expected_keys); + ok(!err, "Expect last error %#x, got %#lx\n", ERROR_SUCCESS, err); + ok(n == keys_len, "%ld != %ld\n", n, keys_len); + ok(n >= expected_keys, "Expected %ld >= %ld\n", n, expected_keys);
keys_len = 0; if (keys) @@ -1267,7 +1267,7 @@ static void test_device_property(void) }
} - todo_wine ok(keys_len == expected_keys, "%ld != %ld\n", keys_len, expected_keys); + ok(keys_len == expected_keys, "%ld != %ld\n", keys_len, expected_keys); free(keys); } else