From: Vibhav Pant vibhavp@gmail.com
--- dlls/setupapi/devinst.c | 74 +++++++++++++++++++++++++++++++++-- dlls/setupapi/tests/devinst.c | 32 +++++++-------- 2 files changed, 87 insertions(+), 19 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index ccbc4a321f3..dc8579a8810 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -3112,10 +3112,78 @@ BOOL WINAPI SetupDiGetDeviceInterfacePropertyW( HDEVINFO devinfo, SP_DEVICE_INTE 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", + WCHAR prop_path[55] = L"Properties\"; + struct device_iface *iface; + HKEY property; + DWORD size, val_type; + 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; + size = sizeof( DEVPROP_BOOLEAN ); + ret = ERROR_SUCCESS; + if (buf_size >= size) + *buf = is_linked( iface->class_key ) ? DEVPROP_TRUE : DEVPROP_FALSE; + else + ret = ERROR_INSUFFICIENT_BUFFER; + } + else + { + SETUPDI_GuidToString( &key->fmtid, prop_path + 11 ); + swprintf( prop_path + 49, ARRAY_SIZE( prop_path ) - 49, L"\%04X", key->pid ); + if (!(ret = RegOpenKeyExW( iface->refstr_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: + *type = val_type & 0xffff; + ret = (ret == ERROR_MORE_DATA || !buf) ? ERROR_INSUFFICIENT_BUFFER : ERROR_SUCCESS; + break; + case ERROR_FILE_NOT_FOUND: + *type = DEVPROP_TYPE_EMPTY; + size = 0; + ret = ERROR_NOT_FOUND; + break; + default: + *type = DEVPROP_TYPE_EMPTY; + size = 0; + FIXME( "Unhandled error: %lu\n", ret ); + break; + } + } + + if (size) + *req_size = size; + SetLastError( ret ); + return !ret; }
BOOL WINAPI SetupDiSetDeviceInterfacePropertyW( HDEVINFO devinfo, SP_DEVICE_INTERFACE_DATA *iface_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. */