There are various ways to retrieve the Windows "Device Name" of a HID device, GetRawInputDeviceInfo with RIDI_DEVICENAME being one way to do it.
Given the example name:
\?\HID#VID_FEED&PID_DEAD#6&3559c8ea&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}
I'm wondering if there is any documentation whatsoever on what is what in this string?
\?\HID#VID_AAAA&PID_BBBB#C&DDDDDD&E&FFFF#{GUID}
So the obvious ones are A(VID), B(PID) and the GUID on the end. What I'm wondering is what EXACTLY are C, D, E and F?
It seems that C and D are unique even if you plug in two of the exact same HID devices which is great for my problem, but I'd feel more comfortable if I could know exactly how this is determined on a per OS basis, or at least that it follows some known format.
I have been googling like a madman trying to figure this out, am I missing something obvious?
Thanks in advance
According to a similar MSDN post, the value represents a unique device instance ID:
the device instance ID is unique and constant for the physical
location the device is plugged into, but it is also opaque and should
not be parsed. that means it can be used for string comparison, but
not for interpretation.
It is actually device interface instance id (symbolic link name). And yes, its unique and persists across system restart. Some details also here.
You can use CM_Get_Device_Interface_Property or SetupDiGetDeviceInterfaceProperty on interface instance id with DEVPKEY_Device_InstanceId to get device instance id (one device can have multiple interfaces).
In your example - you have a HID device. Its device id format is described here.
Info on general USB devices id format is here.
After you have device instance id you can use CM_Get_DevNode_Property or SetupDiGetDeviceProperty with DEVPKEY_NAME to get localized friendly name of a device (which is shown in Device Manager).
To sum up:
\\?\HID#VID_203A&PID_FFFC&MI_01#7&2de99099&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd} - is device interface id (also referred as "device interface path" or "device name" in docs). This is path in virtual device file system.
{378de44c-56ef-11d1-bc8c-00a0c91405dd} - device interface class guid (GUID_DEVINTERFACE_MOUSE in this case. It determines which IOCTLs can be called on this device. IOCTL_MOUSE_QUERY_ATTRIBUTES in this case)
HID\VID_203A&PID_FFFC&MI_01\7&2de99099&0&0000 - is device instance id
NOTE: exact device interface id format is not documented, each device interface can generate file name it want. I don't recommend you to parse it - it could be changed in later Windows version, better aquire device instance id - it is documents at least.
Related
I'm on Windows and am trying to store calibration data for game controllers connected via USB and am trying to find a value which uniquely identifies them in a port independent way.
There is the HidD_GetSerialNumberString function but i've read here that it's uncommon for devices to have serial numbers and indeed when i try to read one f.e. from a PS4 controller HidD_GetSerialNumberString returns FALSE and GetLastError returns ERROR_INVALID_PARAMETER.
Is there any other data available which can be accessed to achieve this?
You can try to use instance ID for your HID device (call CM_Get_Device_Interface_Property with device interface path and DEVPKEY_Device_InstanceId property and use string after last & char). It should be unique and persistent per system restarts. But it is not guaranteed if serial number is not provided (in this case instance ID will be different if device is plugged into different usb port)...
More info on this here: https://stackoverflow.com/a/56885175/1795050
I'm trying to debug a libusb function called libusb_kernel_driver_active(). It tells if a USB device has an operating system driver attached to it. It takes an interface number as one of its arguments. I want to be able to find out which interface the operating system's driver is currently attached to. Is there a way to do this using a terminal command or IOKit?
I have tried IORegistryExplorer but it doesn't list this information.
ioreg does not appear to list USB interface information.
Maybe someone out there knows of an IOKit function that can tell us the information we want.
To find this information out, open the IORegistryExplorer program (spotlight can find it). Then select IOService from the drop down menu in the upper left corner of the window. In the search bar type the name of your device. If it is found select in on the tree below. Then delete all text from the search field to see all the available fields.
The IORegistryExplorer answer is correct, but as the question hints at, there are other ways to obtain the information, both on the Terminal and programmatically.
Terminal (ioreg)
The command
ioreg -irc IOUSBDevice
Will list all USB devices detected by the system, as well as any client objects in the I/O Registry. This means either the driver client directly (kext, dext, or user space) or the IOUSBInterface objects representing the different interfaces on a composite device, and the driver clients attached to each of those.
You can search by name instead of class type by using the -n option instead of -c but often the USB-level name doesn't match the retail name of the device, or is somehow abbreviated. It's usually easier to inspect all USB devices manually.
Programmatically
In your program, you can search for all USB devices in the system using something like this:
io_iterator_t device_iter = IO_OBJECT_NULL;
IOReturn ret = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(kIOUSBDeviceClassName), &device_iter);
if (ret == kIOReturnSuccess && device_iter != IO_OBJECT_NULL)
{
while (io_service_t device = IOIteratorNext(device_iter))
{
io_name_t device_name = "";
IORegistryEntryGetName(device, device_name);
// do something with device_nameā¦
}
}
Once you have selected your device, you can then use IORegistryEntryCreateIterator() to iterate over its child objects (possibly recursively), which should allow you to identify the driver being used or obtain any other information you require.
How does DirectInput generate the GUID for the guidProduct field in DIDEVICEINSTANCE? The documentation reads:
guidProduct
Unique identifier for the product. This identifier is established by the manufacturer of the device.
I am searching for a way to retrieve or synthesize the product GUID for a joystick without using DirectInput. I have successfully used RawInput to retrieve the device path and class GUID, but I have not yet found a way to retrieve the product GUID using RawInput and/or SetupDi* functions.
While searching, I noticed that MAKELONG(VID, PID) == guidProduct.Data1, which makes me hopeful that there is way to do what I want (DirectInput somehow does it, after all.)
Questions:
Is there an API to retrieve the product GUID for an HID (esp. joystick) device?
If not, does anyone know how DirectInput synthesizes this field? (The first fields combines VID and PID. What about the rest?)
Edit:
By hacking around the guidProduct field, I came across an interesting discovery. The product GUID for the P880 USB gamepad has the following format:
010906a3-0000-0000-0000-504944564944
The first 4 bytes are quite evidently the PID and VID for the controller. The last part of the GUID is common for all HID controllers in my possession. After a while it dawned on me - they are ASCII characters! The translation is:
010906a3-0000-0000-0000-504944564944
010906a3-0000-0000-0000- P I D V I D
PID_VID_-0000-0000-0000-'P I D"V I D'
I have verified this using the SDL2 game controller database, and it appears to hold! Of course, this does not cover bluetooth devices (such as the OUYA controller), which is only a minor issue for now.
Does anyone know how guidProduct is composed for bluetooth devices?
I wonder if the PNPDeviceID of an USB drive is unique (at least for a charge of identical devices) and if the ID does not change.
As far as I know -- No. For example, "USBSTOR\DISK&VEN_LG&PROD_USB_DRIVE&REV_1100\AA04012700014149&0" - is a device id of a usb stick. For all such given usb sticks device id will be the same. But Windows adds an instance id of device ("&0"), so it can distinguish them. If you plug two same usb sticks the device id of each of them will be different, for example: USBSTOR\DISK&VEN_LG&PROD_USB_DRIVE&REV_1100\AA04012700014149&0 USBSTOR\DISK&VEN_LG&PROD_USB_DRIVE&REV_1100\AA04012700014149&1
P.S. Sometimes Windows doesn't add instance of a device, if another same device isn't plugged. (I don't know why)
Is there a way to assign one HID device to a program and then another identical HID device to another program without each of them grabbing randomly the first HID device they enumerate? I'd need some kind of unique identifier. Is there such thing? On windows xp/vista/7.
The port is your default enumeration value. Configure your code to allow explicit specification of the port.
Depending on a uuid of a device is probably not going to give you the results you expect in the long run.