From: Vibhav Pant vibhavp@gmail.com
--- dlls/setupapi/devinst.c | 124 ++++++++++++++++++++++------------ dlls/setupapi/tests/devinst.c | 32 ++++----- 2 files changed, 97 insertions(+), 59 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 9fbffb349e8..aae3efbfdf4 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -3108,14 +3108,91 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(HDEVINFO devinfo, SP_DEVICE_INTERFA return ret; }
+static DWORD get_device_reg_property( HKEY base_key, const DEVPROPKEY *prop_key, DEVPROPTYPE *prop_type, + BYTE *buf, DWORD buf_size, DWORD *req_size ) +{ + WCHAR prop_path[55] = L"Properties\"; + HKEY property; + DWORD size = 0, val_type; + LSTATUS ret; + + SETUPDI_GuidToString( &prop_key->fmtid, prop_path + 11 ); + swprintf( prop_path + 49, ARRAY_SIZE( prop_path ) - 49, L"\%04X", prop_key->pid ); + if (!(ret = RegOpenKeyExW( base_key, prop_path, 0, KEY_QUERY_VALUE, &property ))) + { + size = buf_size; + ret = RegQueryValueExW( property, NULL, NULL, &val_type, buf, &size ); + RegCloseKey( property ); + } + + switch (ret) + { + case ERROR_SUCCESS: + case ERROR_MORE_DATA: + *prop_type = val_type & 0xffff; + ret = (ret == ERROR_MORE_DATA || !buf) ? ERROR_INSUFFICIENT_BUFFER : ERROR_SUCCESS; + break; + case ERROR_FILE_NOT_FOUND: + *prop_type = DEVPROP_TYPE_EMPTY; + size = 0; + ret = ERROR_NOT_FOUND; + break; + default: + *prop_type = DEVPROP_TYPE_EMPTY; + size = 0; + FIXME( "Unhandled error: %lu\n", ret ); + break; + } + + if (req_size) + *req_size = size; + return ret; +} + BOOL WINAPI SetupDiGetDeviceInterfacePropertyW( HDEVINFO devinfo, SP_DEVICE_INTERFACE_DATA *iface_data, const DEVPROPKEY *key, DEVPROPTYPE *type, BYTE *buf, DWORD buf_size, DWORD *req_size, DWORD flags ) { - FIXME( "devinfo %p, iface_data %p, key %p, type %p, buf %p, buf_size %lu, req_size %p, flags %#lx: stub!\n", + struct device_iface *iface; + LSTATUS ret; + + TRACE( "devinfo %p, iface_data %p, key %p, type %p, buf %p, buf_size %lu, req_size %p, flags %#lx\n", devinfo, iface_data, key, type, buf, buf_size, req_size, flags ); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; + + if (!(iface = get_device_iface( devinfo, iface_data ))) + return FALSE; + if (!type || (!buf && buf_size)) + { + SetLastError( ERROR_INVALID_USER_BUFFER ); + return FALSE; + } + if (!key) + { + SetLastError( ERROR_INVALID_DATA ); + return FALSE; + } + if (flags) + { + SetLastError( ERROR_INVALID_FLAGS ); + return FALSE; + } + + if (IsEqualDevPropKey( *key, DEVPKEY_DeviceInterface_Enabled )) + { + *type = DEVPROP_TYPE_BOOLEAN; + ret = ERROR_SUCCESS; + if (buf_size >= sizeof( DEVPROP_BOOLEAN )) + *buf = (iface->flags & SPINT_ACTIVE) ? DEVPROP_TRUE : DEVPROP_FALSE; + else + ret = ERROR_INSUFFICIENT_BUFFER; + if (req_size) + *req_size = sizeof( DEVPROP_BOOLEAN ); + } + else + ret = get_device_reg_property( iface->refstr_key, key, type, buf, buf_size, req_size ); + + SetLastError( ret ); + return !ret; }
static DWORD set_device_reg_property( HKEY base_key, const DEVPROPKEY *key, DEVPROPTYPE type, const BYTE *buf, @@ -5024,12 +5101,6 @@ out: static LSTATUS get_device_property(struct device *device, const DEVPROPKEY *prop_key, DEVPROPTYPE *prop_type, BYTE *prop_buff, DWORD prop_buff_size, DWORD *required_size, DWORD flags) { - WCHAR key_path[55] = L"Properties\"; - HKEY hkey; - DWORD value_type; - DWORD value_size = 0; - LSTATUS ls; - if (!prop_key) return ERROR_INVALID_DATA;
@@ -5039,40 +5110,7 @@ static LSTATUS get_device_property(struct device *device, const DEVPROPKEY *prop if (flags) return ERROR_INVALID_FLAGS;
- SETUPDI_GuidToString(&prop_key->fmtid, key_path + 11); - swprintf(key_path + 49, ARRAY_SIZE(key_path) - 49, L"\%04X", 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); - RegCloseKey(hkey); - } - - 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 %#lx\n", ls); - break; - } - - if (required_size) - *required_size = value_size; - - return ls; + return get_device_reg_property( device->key, prop_key, prop_type, prop_buff, prop_buff_size, required_size ); }
BOOL WINAPI SetupDiGetDevicePropertyKeys( HDEVINFO devinfo, PSP_DEVINFO_DATA device_data, diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index d1a7418e29b..1ff00b1282d 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -2782,35 +2782,35 @@ static void test_device_interface_properties(void)
ret = SetupDiGetDeviceInterfacePropertyW(NULL, NULL, NULL, NULL, NULL, 0, NULL, 0); err = GetLastError(); - todo_wine ok(!ret && err == ERROR_INVALID_HANDLE, "%lu != %d\n", err, ERROR_INVALID_HANDLE); + ok(!ret && err == ERROR_INVALID_HANDLE, "%lu != %d\n", err, ERROR_INVALID_HANDLE);
ret = SetupDiGetDeviceInterfacePropertyW(set, NULL, NULL, NULL, NULL, 0, NULL, 0); err = GetLastError(); - todo_wine ok(!ret && err == ERROR_INVALID_PARAMETER, "%lu != %d\n", err, ERROR_INVALID_PARAMETER); + ok(!ret && err == ERROR_INVALID_PARAMETER, "%lu != %d\n", err, ERROR_INVALID_PARAMETER);
ret = SetupDiGetDeviceInterfacePropertyW(set, &iface, NULL, NULL, NULL, 0, NULL, 0); err = GetLastError(); - todo_wine ok(!ret && err == ERROR_INVALID_USER_BUFFER, "%lu != %d\n", err, ERROR_INVALID_USER_BUFFER); + ok(!ret && err == ERROR_INVALID_USER_BUFFER, "%lu != %d\n", err, ERROR_INVALID_USER_BUFFER);
ret = SetupDiGetDeviceInterfacePropertyW(set, &iface, &DEVPKEY_DeviceInterface_FriendlyName, NULL, NULL, 0, NULL, 0); err = GetLastError(); - todo_wine ok(!ret && err == ERROR_INVALID_USER_BUFFER, "%lu != %d\n", err, ERROR_INVALID_USER_BUFFER); + ok(!ret && err == ERROR_INVALID_USER_BUFFER, "%lu != %d\n", err, ERROR_INVALID_USER_BUFFER);
ret = SetupDiGetDeviceInterfacePropertyW(set, &iface, &DEVPKEY_DeviceInterface_FriendlyName, &type, NULL, sizeof(buf), &req, 0); err = GetLastError(); - todo_wine ok(!ret && err == ERROR_INVALID_USER_BUFFER, "%lu != %d\n", err, ERROR_INVALID_USER_BUFFER); + ok(!ret && err == ERROR_INVALID_USER_BUFFER, "%lu != %d\n", err, ERROR_INVALID_USER_BUFFER);
ret = SetupDiGetDeviceInterfacePropertyW(set, &iface, &DEVPKEY_DeviceInterface_FriendlyName, &type, (BYTE *)buf, sizeof(buf), NULL, 1); err = GetLastError(); - todo_wine ok(!ret && err == ERROR_INVALID_FLAGS, "%lu != %d\n", err, ERROR_INVALID_FLAGS); + ok(!ret && err == ERROR_INVALID_FLAGS, "%lu != %d\n", err, ERROR_INVALID_FLAGS);
ret = SetupDiGetDeviceInterfacePropertyW(set, &iface, &DEVPKEY_DeviceInterface_FriendlyName, &type, (BYTE *)buf, sizeof(buf), NULL, 0); err = GetLastError(); - todo_wine ok(!ret && err == ERROR_NOT_FOUND, "%lu != %d\n", err, ERROR_NOT_FOUND); + ok(!ret && err == ERROR_NOT_FOUND, "%lu != %d\n", err, ERROR_NOT_FOUND);
ret = SetupDiGetDeviceInterfacePropertyW(set, &iface, &DEVPKEY_DeviceInterface_FriendlyName, &type, (BYTE *)buf, sizeof(buf), &req, 0); err = GetLastError(); - todo_wine ok(!ret && err == ERROR_NOT_FOUND, "%lu != %d\n", err, ERROR_NOT_FOUND); + ok(!ret && err == ERROR_NOT_FOUND, "%lu != %d\n", err, ERROR_NOT_FOUND);
ret = SetupDiSetDeviceInterfacePropertyW(set, &iface, &DEVPKEY_DeviceInterface_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)str, sizeof(str), 0); @@ -2819,16 +2819,16 @@ static void test_device_interface_properties(void)
ret = SetupDiGetDeviceInterfacePropertyW(set, &iface, &DEVPKEY_DeviceInterface_FriendlyName, &type, NULL, 0, &req, 0); err = GetLastError(); - todo_wine ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "%lu != %d\n", err, ERROR_INSUFFICIENT_BUFFER); - todo_wine ok(type == DEVPROP_TYPE_STRING, "%#lx != %#x\n", type, DEVPROP_TYPE_STRING); - todo_wine ok(req == sizeof(str), "%lu != %lu\n", req, (DWORD)sizeof(str)); + ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "%lu != %d\n", err, ERROR_INSUFFICIENT_BUFFER); + ok(type == DEVPROP_TYPE_STRING, "%#lx != %#x\n", type, DEVPROP_TYPE_STRING); + ok(req == sizeof(str), "%lu != %lu\n", req, (DWORD)sizeof(str));
buf[0] = '\0'; ret = SetupDiGetDeviceInterfacePropertyW(set, &iface, &DEVPKEY_DeviceInterface_FriendlyName, &type, (BYTE *)buf, sizeof(buf), &req, 0); err = GetLastError(); - todo_wine ok(ret, "SetupDiGetDeviceInterfacePropertyW failed: %lu\n", err); - todo_wine ok(!wcscmp(buf, str), "%s != %s\n", debugstr_w(buf), debugstr_w(str)); + ok(ret, "SetupDiGetDeviceInterfacePropertyW failed: %lu\n", err); + ok(!wcscmp(buf, str), "%s != %s\n", debugstr_w(buf), debugstr_w(str));
ret = SetupDiSetDeviceInterfacePropertyW(set, &iface, &DEVPKEY_DeviceInterface_FriendlyName, DEVPROP_TYPE_EMPTY, NULL, 0, 0); @@ -2839,9 +2839,9 @@ static void test_device_interface_properties(void) ret = SetupDiGetDeviceInterfacePropertyW(set, &iface, &DEVPKEY_DeviceInterface_Enabled, &type, (BYTE *)&boolean, sizeof(boolean), &req, 0); err = GetLastError(); - todo_wine ok(ret, "SetupDiGetDeviceInterfacePropertyW failed: %lu\n", err); - todo_wine ok(req == sizeof(boolean), "%lu != %lu\n", req, (DWORD)sizeof(boolean)); - todo_wine ok(boolean == DEVPROP_FALSE, "%d != %d\n", boolean, DEVPROP_FALSE); + ok(ret, "SetupDiGetDeviceInterfacePropertyW failed: %lu\n", err); + ok(req == sizeof(boolean), "%lu != %lu\n", req, (DWORD)sizeof(boolean)); + ok(boolean == DEVPROP_FALSE, "%d != %d\n", boolean, DEVPROP_FALSE);
boolean = DEVPROP_TRUE; /* DEVPKEY_DeviceInterface_Enabled cannot be toggled for interfaces. */