Merge pull request #154 from kevinmehall/windows-interface-info
windows: Always use interface descriptors rather than child device nodes for InterfaceInfo
This commit is contained in:
commit
c1492ae441
4 changed files with 22 additions and 49 deletions
|
|
@ -26,7 +26,7 @@ rustix = { version = "1.0.1", features = ["fs", "event", "net", "time", "mm"] }
|
|||
linux-raw-sys = { version = "0.9.2", features = ["ioctl"] }
|
||||
|
||||
[target.'cfg(target_os="windows")'.dependencies]
|
||||
windows-sys = { version = "0.59.0", features = ["Win32_Devices_Usb", "Win32_Devices_DeviceAndDriverInstallation", "Win32_Foundation", "Win32_Devices_Properties", "Win32_Storage_FileSystem", "Win32_Security", "Win32_System_IO", "Win32_System_Registry", "Win32_System_Com"] }
|
||||
windows-sys = { version = "0.60.2", features = ["Win32_Devices_Usb", "Win32_Devices_DeviceAndDriverInstallation", "Win32_Foundation", "Win32_Devices_Properties", "Win32_Storage_FileSystem", "Win32_Security", "Win32_System_IO", "Win32_System_Registry", "Win32_System_Com"] }
|
||||
|
||||
[target.'cfg(target_os="macos")'.dependencies]
|
||||
core-foundation = "0.10.1"
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ use windows_sys::{
|
|||
CM_LOCATE_DEVNODE_PHANTOM, CM_REGISTRY_HARDWARE, CR_BUFFER_SMALL, CR_SUCCESS,
|
||||
},
|
||||
Properties::{
|
||||
DEVPKEY_Device_InstanceId, DEVPROPKEY, DEVPROPTYPE, DEVPROP_TYPE_STRING,
|
||||
DEVPKEY_Device_InstanceId, DEVPROPTYPE, DEVPROP_TYPE_STRING,
|
||||
DEVPROP_TYPE_STRING_LIST, DEVPROP_TYPE_UINT32,
|
||||
},
|
||||
},
|
||||
Foundation::INVALID_HANDLE_VALUE,
|
||||
Foundation::{DEVPROPKEY, INVALID_HANDLE_VALUE},
|
||||
System::Registry::KEY_READ,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -89,33 +89,28 @@ pub fn probe_device(devinst: DevInst) -> Option<DeviceInfo> {
|
|||
|
||||
let driver = get_driver_name(devinst);
|
||||
|
||||
let mut interfaces = if driver.eq_ignore_ascii_case("usbccgp") {
|
||||
let mut interfaces =
|
||||
list_interfaces_from_desc(&hub_port, info.active_config).unwrap_or_default();
|
||||
|
||||
if driver.eq_ignore_ascii_case("usbccgp") {
|
||||
// Populate interface descriptor strings when available from child device nodes.
|
||||
devinst
|
||||
.children()
|
||||
.flat_map(|intf| {
|
||||
let interface_number = get_interface_number(intf)?;
|
||||
let (class, subclass, protocol) = intf
|
||||
.get_property::<Vec<OsString>>(DEVPKEY_Device_CompatibleIds)?
|
||||
.iter()
|
||||
.find_map(|s| parse_compatible_id(s))?;
|
||||
let interface_string = intf
|
||||
.get_property::<OsString>(DEVPKEY_Device_BusReportedDeviceDesc)
|
||||
.and_then(|s| s.into_string().ok());
|
||||
|
||||
Some(InterfaceInfo {
|
||||
interface_number,
|
||||
class,
|
||||
subclass,
|
||||
protocol,
|
||||
interface_string,
|
||||
let interface_string =
|
||||
intf.get_property::<OsString>(DEVPKEY_Device_BusReportedDeviceDesc)?;
|
||||
Some((interface_number, interface_string))
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
list_interfaces_from_desc(&hub_port, info.active_config).unwrap_or_default()
|
||||
};
|
||||
|
||||
interfaces.sort_unstable_by_key(|i| i.interface_number);
|
||||
.for_each(|(intf_num, interface_string)| {
|
||||
if let Some(interface_info) = interfaces
|
||||
.iter_mut()
|
||||
.find(|i| i.interface_number == intf_num)
|
||||
{
|
||||
interface_info.interface_string = interface_string.into_string().ok();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let location_paths = devinst
|
||||
.get_property::<Vec<OsString>>(DEVPKEY_Device_LocationPaths)
|
||||
|
|
@ -342,28 +337,6 @@ fn test_parse_hardware_id() {
|
|||
);
|
||||
}
|
||||
|
||||
/// Parse class, subclass, protocol from a Compatible ID value
|
||||
fn parse_compatible_id(s: &OsStr) -> Option<(u8, u8, u8)> {
|
||||
let s = s.to_str()?;
|
||||
let s = s.strip_prefix("USB\\Class_")?;
|
||||
let class = u8::from_str_radix(s.get(0..2)?, 16).ok()?;
|
||||
let s = s.get(2..)?.strip_prefix("&SubClass_")?;
|
||||
let subclass = u8::from_str_radix(s.get(0..2)?, 16).ok()?;
|
||||
let s = s.get(2..)?.strip_prefix("&Prot_")?;
|
||||
let protocol = u8::from_str_radix(s.get(0..2)?, 16).ok()?;
|
||||
Some((class, subclass, protocol))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_compatible_id() {
|
||||
assert_eq!(parse_compatible_id(OsStr::new("")), None);
|
||||
assert_eq!(parse_compatible_id(OsStr::new("USB\\Class_03")), None);
|
||||
assert_eq!(
|
||||
parse_compatible_id(OsStr::new("USB\\Class_03&SubClass_11&Prot_22")),
|
||||
Some((3, 17, 34))
|
||||
);
|
||||
}
|
||||
|
||||
fn parse_location_path(s: &OsStr) -> Option<(String, Vec<u8>)> {
|
||||
let s = s.to_str()?;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use windows_sys::Win32::{
|
|||
DeviceAndDriverInstallation::{
|
||||
CM_Register_Notification, CM_Unregister_Notification, CM_NOTIFY_ACTION,
|
||||
CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL, CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL,
|
||||
CM_NOTIFY_EVENT_DATA, CM_NOTIFY_FILTER, CM_NOTIFY_FILTER_0, CM_NOTIFY_FILTER_0_2,
|
||||
CM_NOTIFY_EVENT_DATA, CM_NOTIFY_FILTER, CM_NOTIFY_FILTER_0, CM_NOTIFY_FILTER_0_0,
|
||||
CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE, CR_SUCCESS, HCMNOTIFICATION,
|
||||
},
|
||||
Properties::DEVPKEY_Device_InstanceId,
|
||||
|
|
@ -62,7 +62,7 @@ impl WindowsHotplugWatch {
|
|||
FilterType: CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE,
|
||||
Reserved: 0,
|
||||
u: CM_NOTIFY_FILTER_0 {
|
||||
DeviceInterface: CM_NOTIFY_FILTER_0_2 {
|
||||
DeviceInterface: CM_NOTIFY_FILTER_0_0 {
|
||||
ClassGuid: GUID_DEVINTERFACE_USB_DEVICE,
|
||||
},
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue