setupapi: Implement SetupDiGetDevicePropertyW.
Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
afac1c405d
commit
307812c30d
|
@ -3815,13 +3815,74 @@ BOOL WINAPI SetupDiGetINFClassW(PCWSTR inf, LPGUID class_guid, PWSTR class_name,
|
|||
/***********************************************************************
|
||||
* SetupDiGetDevicePropertyW (SETUPAPI.@)
|
||||
*/
|
||||
BOOL WINAPI SetupDiGetDevicePropertyW(HDEVINFO info_set, PSP_DEVINFO_DATA info_data,
|
||||
BOOL WINAPI SetupDiGetDevicePropertyW(HDEVINFO devinfo, PSP_DEVINFO_DATA device_data,
|
||||
const DEVPROPKEY *prop_key, DEVPROPTYPE *prop_type, BYTE *prop_buff,
|
||||
DWORD prop_buff_size, DWORD *required_size, DWORD flags)
|
||||
{
|
||||
FIXME("%p, %p, %p, %p, %p, %d, %p, 0x%08x stub\n", info_set, info_data, prop_key,
|
||||
prop_type, prop_buff, prop_buff_size, required_size, flags);
|
||||
static const WCHAR formatW[] = {'\\', '%', '0', '4', 'X', 0};
|
||||
WCHAR key_path[55] = {'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's', '\\'};
|
||||
HKEY hkey;
|
||||
DWORD value_type;
|
||||
DWORD value_size = 0;
|
||||
LSTATUS ls;
|
||||
struct device *device;
|
||||
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
return FALSE;
|
||||
TRACE("%p, %p, %p, %p, %p, %d, %p, %#x\n", devinfo, device_data, prop_key, prop_type, prop_buff, prop_buff_size,
|
||||
required_size, flags);
|
||||
|
||||
if (!(device = get_device(devinfo, device_data)))
|
||||
return FALSE;
|
||||
|
||||
if (!prop_key)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!prop_type || (!prop_buff && prop_buff_size))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_USER_BUFFER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (flags)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FLAGS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SETUPDI_GuidToString(&prop_key->fmtid, key_path + 11);
|
||||
sprintfW(key_path + 49, formatW, prop_key->pid);
|
||||
|
||||
ls = RegOpenKeyExW(device->key, key_path, 0, KEY_QUERY_VALUE, &hkey);
|
||||
if (!ls)
|
||||
{
|
||||
value_size = prop_buff_size;
|
||||
ls = RegQueryValueExW(hkey, NULL, NULL, &value_type, prop_buff, &value_size);
|
||||
}
|
||||
|
||||
switch (ls)
|
||||
{
|
||||
case NO_ERROR:
|
||||
case ERROR_MORE_DATA:
|
||||
*prop_type = 0xffff & value_type;
|
||||
ls = (ls == ERROR_MORE_DATA || !prop_buff) ? ERROR_INSUFFICIENT_BUFFER : NO_ERROR;
|
||||
break;
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
*prop_type = DEVPROP_TYPE_EMPTY;
|
||||
value_size = 0;
|
||||
ls = ERROR_NOT_FOUND;
|
||||
break;
|
||||
default:
|
||||
*prop_type = DEVPROP_TYPE_EMPTY;
|
||||
value_size = 0;
|
||||
FIXME("Unhandled error %#x\n", ls);
|
||||
break;
|
||||
}
|
||||
|
||||
if (required_size)
|
||||
*required_size = value_size;
|
||||
|
||||
SetLastError(ls);
|
||||
return !ls;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ static GUID guid = {0x6a55b5a4, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0
|
|||
static GUID guid2 = {0x6a55b5a5, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0x2b,0xdb}};
|
||||
|
||||
BOOL (WINAPI *pSetupDiSetDevicePropertyW)(HDEVINFO, PSP_DEVINFO_DATA, const DEVPROPKEY *, DEVPROPTYPE, const BYTE *, DWORD, DWORD);
|
||||
BOOL (WINAPI *pSetupDiGetDevicePropertyW)(HDEVINFO, PSP_DEVINFO_DATA, const DEVPROPKEY *, DEVPROPTYPE *, BYTE *, DWORD, DWORD *, DWORD);
|
||||
|
||||
static void test_create_device_list_ex(void)
|
||||
{
|
||||
|
@ -351,15 +352,19 @@ static void test_device_property(void)
|
|||
SP_DEVINFO_DATA device_data = {sizeof(device_data)};
|
||||
HMODULE hmod;
|
||||
HDEVINFO set;
|
||||
DEVPROPTYPE type;
|
||||
DWORD size;
|
||||
BYTE buffer[256];
|
||||
DWORD err;
|
||||
BOOL ret;
|
||||
|
||||
hmod = LoadLibraryA("setupapi.dll");
|
||||
pSetupDiSetDevicePropertyW = (void *)GetProcAddress(hmod, "SetupDiSetDevicePropertyW");
|
||||
pSetupDiGetDevicePropertyW = (void *)GetProcAddress(hmod, "SetupDiGetDevicePropertyW");
|
||||
|
||||
if (!pSetupDiSetDevicePropertyW)
|
||||
if (!pSetupDiSetDevicePropertyW || !pSetupDiGetDevicePropertyW)
|
||||
{
|
||||
win_skip("SetupDiSetDevicePropertyW() are only available on vista+, skipping tests.\n");
|
||||
win_skip("SetupDi{Set,Get}DevicePropertyW() are only available on vista+, skipping tests.\n");
|
||||
FreeLibrary(hmod);
|
||||
return;
|
||||
}
|
||||
|
@ -495,6 +500,172 @@ static void test_device_property(void)
|
|||
ok(!ret, "Expect failure\n");
|
||||
ok(err == ERROR_NOT_FOUND, "Expect last error %#x, got %#x\n", ERROR_NOT_FOUND, err);
|
||||
|
||||
|
||||
/* SetupDiGetDevicePropertyW */
|
||||
ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
|
||||
ok(ret, "Expect success\n");
|
||||
|
||||
/* #1 Null device info list */
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_STRING;
|
||||
size = 0;
|
||||
ret = pSetupDiGetDevicePropertyW(NULL, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), &size, 0);
|
||||
err = GetLastError();
|
||||
ok(!ret, "Expect failure\n");
|
||||
ok(err == ERROR_INVALID_HANDLE, "Expect last error %#x, got %#x\n", ERROR_INVALID_HANDLE, err);
|
||||
ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
|
||||
ok(size == 0, "Expect size %d, got %d\n", 0, size);
|
||||
|
||||
/* #2 Null device */
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_STRING;
|
||||
size = 0;
|
||||
ret = pSetupDiGetDevicePropertyW(set, NULL, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), &size, 0);
|
||||
err = GetLastError();
|
||||
ok(!ret, "Expect failure\n");
|
||||
ok(err == ERROR_INVALID_PARAMETER, "Expect last error %#x, got %#x\n", ERROR_INVALID_PARAMETER, err);
|
||||
ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
|
||||
ok(size == 0, "Expect size %d, got %d\n", 0, size);
|
||||
|
||||
/* #3 Null property key */
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_STRING;
|
||||
size = 0;
|
||||
ret = pSetupDiGetDevicePropertyW(set, &device_data, NULL, &type, buffer, sizeof(buffer), &size, 0);
|
||||
err = GetLastError();
|
||||
ok(!ret, "Expect failure\n");
|
||||
ok(err == ERROR_INVALID_DATA, "Expect last error %#x, got %#x\n", ERROR_INVALID_DATA, err);
|
||||
ok(size == 0, "Expect size %d, got %d\n", 0, size);
|
||||
|
||||
/* #4 Null property type */
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_STRING;
|
||||
size = 0;
|
||||
ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, NULL, buffer, sizeof(buffer), &size, 0);
|
||||
err = GetLastError();
|
||||
ok(!ret, "Expect failure\n");
|
||||
ok(err == ERROR_INVALID_USER_BUFFER, "Expect last error %#x, got %#x\n", ERROR_INVALID_USER_BUFFER, err);
|
||||
ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
|
||||
ok(size == 0, "Expect size %d, got %d\n", 0, size);
|
||||
|
||||
/* #5 Null buffer */
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_STRING;
|
||||
size = 0;
|
||||
ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, NULL, sizeof(buffer), &size, 0);
|
||||
err = GetLastError();
|
||||
ok(!ret, "Expect failure\n");
|
||||
ok(err == ERROR_INVALID_USER_BUFFER, "Expect last error %#x, got %#x\n", ERROR_INVALID_USER_BUFFER, err);
|
||||
ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
|
||||
ok(size == 0, "Expect size %d, got %d\n", 0, size);
|
||||
|
||||
/* #6 Null buffer with zero size and wrong type */
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_UINT64;
|
||||
size = 0;
|
||||
ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, NULL, 0, &size, 0);
|
||||
err = GetLastError();
|
||||
ok(!ret, "Expect failure\n");
|
||||
ok(err == ERROR_INSUFFICIENT_BUFFER, "Expect last error %#x, got %#x\n", ERROR_INSUFFICIENT_BUFFER, err);
|
||||
ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
|
||||
ok(size == sizeof(valueW), "Expect size %d, got %d\n", sizeof(valueW), size);
|
||||
|
||||
/* #7 Zero buffer size */
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_STRING;
|
||||
size = 0;
|
||||
ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, 0, &size, 0);
|
||||
err = GetLastError();
|
||||
ok(!ret, "Expect failure\n");
|
||||
ok(err == ERROR_INSUFFICIENT_BUFFER, "Expect last error %#x, got %#x\n", ERROR_INSUFFICIENT_BUFFER, err);
|
||||
ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
|
||||
ok(size == sizeof(valueW), "Expect size %d, got %d\n", sizeof(valueW), size);
|
||||
|
||||
/* #8 Null required size */
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_STRING;
|
||||
ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), NULL, 0);
|
||||
err = GetLastError();
|
||||
ok(ret, "Expect success\n");
|
||||
ok(err == NO_ERROR, "Expect last error %#x, got %#x\n", NO_ERROR, err);
|
||||
ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
|
||||
|
||||
/* #9 Flags not zero */
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_STRING;
|
||||
size = 0;
|
||||
ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), &size, 1);
|
||||
err = GetLastError();
|
||||
ok(!ret, "Expect failure\n");
|
||||
ok(err == ERROR_INVALID_FLAGS, "Expect last error %#x, got %#x\n", ERROR_INVALID_FLAGS, err);
|
||||
ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
|
||||
ok(size == 0, "Expect size %d, got %d\n", 0, size);
|
||||
|
||||
/* #10 Non-existent property key */
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_STRING;
|
||||
size = 0;
|
||||
ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_HardwareIds, &type, buffer, sizeof(buffer), &size, 0);
|
||||
err = GetLastError();
|
||||
ok(!ret, "Expect failure\n");
|
||||
ok(err == ERROR_NOT_FOUND, "Expect last error %#x, got %#x\n", ERROR_NOT_FOUND, err);
|
||||
ok(size == 0, "Expect size %d, got %d\n", 0, size);
|
||||
|
||||
/* #11 Wrong property key type */
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_UINT64;
|
||||
size = 0;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), &size, 0);
|
||||
err = GetLastError();
|
||||
ok(ret, "Expect success\n");
|
||||
ok(err == NO_ERROR, "Expect last error %#x, got %#x\n", NO_ERROR, err);
|
||||
ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
|
||||
ok(size == sizeof(valueW), "Expect size %d, got %d\n", sizeof(valueW), size);
|
||||
ok(!lstrcmpW((WCHAR *)buffer, valueW), "Expect buffer %s, got %s\n", wine_dbgstr_w(valueW), wine_dbgstr_w((WCHAR *)buffer));
|
||||
|
||||
/* #12 Get null property value */
|
||||
ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
|
||||
ok(ret, "Expect success\n");
|
||||
ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_NULL, NULL, 0, 0);
|
||||
ok(ret, "Expect success\n");
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_STRING;
|
||||
size = 0;
|
||||
ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), &size, 0);
|
||||
err = GetLastError();
|
||||
ok(!ret, "Expect failure\n");
|
||||
ok(err == ERROR_NOT_FOUND, "Expect last error %#x, got %#x\n", ERROR_NOT_FOUND, err);
|
||||
ok(size == 0, "Expect size %d, got %d\n", 0, size);
|
||||
|
||||
/* #13 Insufficient buffer size */
|
||||
ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
|
||||
ok(ret, "Expect success\n");
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_STRING;
|
||||
size = 0;
|
||||
ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(valueW) - 1, &size, 0);
|
||||
err = GetLastError();
|
||||
ok(!ret, "Expect failure\n");
|
||||
ok(err == ERROR_INSUFFICIENT_BUFFER, "Expect last error %#x, got %#x\n", ERROR_INSUFFICIENT_BUFFER, err);
|
||||
ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
|
||||
ok(size == sizeof(valueW), "Expect size %d, got %d\n", sizeof(valueW), size);
|
||||
|
||||
/* #14 Normal */
|
||||
ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
|
||||
ok(ret, "Expect success\n");
|
||||
SetLastError(0xdeadbeef);
|
||||
type = DEVPROP_TYPE_STRING;
|
||||
size = 0;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), &size, 0);
|
||||
err = GetLastError();
|
||||
ok(ret, "Expect success\n");
|
||||
ok(err == NO_ERROR, "Expect last error %#x, got %#x\n", NO_ERROR, err);
|
||||
ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
|
||||
ok(size == sizeof(valueW), "Expect size %d, got %d\n", sizeof(valueW), size);
|
||||
ok(!lstrcmpW((WCHAR *)buffer, valueW), "Expect buffer %s, got %s\n", wine_dbgstr_w(valueW), wine_dbgstr_w((WCHAR *)buffer));
|
||||
|
||||
ret = SetupDiRemoveDevice(set, &device_data);
|
||||
ok(ret, "Got unexpected error %#x.\n", GetLastError());
|
||||
|
||||
|
|
Loading…
Reference in New Issue