Open sirhcel opened 1 month ago
Repeating the above test with interface number information enabled, gives no interface number for the FTDI composite device while this info is present for another composite device COM13:
>cargo run --features usbportinfo-interface --example list_ports
[...]
COM11
Type: USB
VID:0403 PID:6010
Serial Number: 6
Manufacturer: FTDI
Product: USB Serial Port (COM11)
Interface:
COM12
Type: USB
VID:0403 PID:6010
Serial Number: 6
Manufacturer: FTDI
Product: USB Serial Port (COM12)
Interface:
COM13
Type: USB
VID:1366 PID:0105
Serial Number: 000123456789
Manufacturer: Microsoft
Product: Serielles USB-Gerät (COM13)
Interface: 00
I have some ideas for possibly improving the situation w.r.t. getting device information but won't be able to work on it for a bit. The idea is basically seeing if the HID API can be used instead.
Thank you for chiming in @RossSmyth! No hurry.
I finally found some time to look further into it and it looks to me that there is still room for improving FTDI device enumeration on Windows just by a more educated look at the device identification string and the whole parent stack.
Instrumenting this for list_ports
a bit more in test/parent-device-iteration as of 0da2c19 shows the first interesting things:
Device identification stings starting with FTDIBUS
don't seem to provide any interface information at all but it is provided by the parent device identification string just starting with USB
"0: Some(\"FTDIBUS\\\\VID_0403+PID_6010+6&119857B6&0&4&2\\\\0000\")",
"1: Some(\"USB\\\\VID_0403&PID_6010&MI_01\\\\7&19792F3E&0&0001\")",
The serial number without a suffix (see #178) for a multi-port FTDI device is also reported deeper down the parent chain:
"0: Some(\"FTDIBUS\\\\VID_0403+PID_6010+FT73U3C5A\\\\0000\")",
"1: Some(\"USB\\\\VID_0403&PID_6010&MI_00\\\\6&26310911&0&0000\")",
"2: Some(\"USB\\\\VID_0403&PID_6010\\\\FT73U3C5\")",
[...]
"0: Some(\"FTDIBUS\\\\VID_0403+PID_6010+FT73U3C5B\\\\0000\")",
"1: Some(\"USB\\\\VID_0403&PID_6010&MI_01\\\\6&26310911&0&0001\")",
"2: Some(\"USB\\\\VID_0403&PID_6010\\\\FT73U3C5\")",
Which leads me to the following things to think about:
We likely need to look deeper into the parent device chain than just one step (like for example pySerial does)
When looking deeper into the parent device chain we should limit the depth of inspection and are likely safe to stop when VID and PID no longer match as for example
"0: Some(\"FTDIBUS\\\\VID_0403+PID_6010+6&119857B6&0&4&2\\\\0000\")",
"1: Some(\"USB\\\\VID_0403&PID_6010&MI_01\\\\7&19792F3E&0&0001\")",
"2: Some(\"USB\\\\VID_0403&PID_6010\\\\6&119857B6&0&4\")",
"3: Some(\"USB\\\\VID_1A40&PID_0101\\\\5&3B109A5C&0&1\")",
"4: Some(\"USB\\\\ROOT_HUB30\\\\4&DC91CFA&0&0\")",
May be we should just skip FTDIBUS
device identification strings and just look into USB
ones for the information we are interested in (as we do for non-FTDI devices)
May be we should add logging support to facilitate diagnosing issues with enumeration in the field when needed
We should likely ignore serial number strings containing ampersands
We should look at how other multi-port devices report serial numbers
If we are going to report FTDI serial numbers without a suffix, we should postpone this until the next mayor release
I'm trying to see if there's a more structured way of retrieving the info we would like rather than parsing the string that in the win32 docs say specifically not to parse. Here's just a dump of things I have found so far:
I tried this, but the example lshid
does not show my FTDI device in the list.
WMI is a large API that lets you query Windows things like a database. The incantation needed is:
Get-WmiObject -Query "SELECT * FROM Win32_PnPEntity WHERE ClassGuid=`"{4d36e978-e325-11ce-bfc1-08002be10318}`""
Which can be translated to Rust. But it does not have the fields seperated.
This struct has the fields idVendor
, idProduct
, iManufacturer
, & iSerialNumber
. I've not tested this yet.
One issue is that the serial number field is a nebulous index that I'm not sure where it indexes.
This you can just view with RegEdit. The path is Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\FTDIBUS
or something else if not FTDI.
This has the same issue of WMI in that the VID & other fields are not seperated out from the HWID.
A C++ file that shows 10 different ways to get a list of serial ports. Not specific to my goal, but could have inspiration for what to look at.
While looking into #201, I found a wrong serial number '5' reported for a FTDI 2232D which does not have a serial number (due to not having an external EEPROM fitted):
The same serial number is also reported by pySerial:
Listing the ports on macOS gives the espected result of no serial number at all: