USBPcap attaches as Upper Filter for all Root Hubs. It does so by adding UpperFilters entry for {36FC9E60-C465-11CF-8056-444553540000} class. Then in AddDevice function I retrieve the PDO and get list of hardware IDs. Then the list is checked for USB\ROOT_HUB and USB\ROOT_HUB20 entries. If it's in the list, the device is considered Root Hub, otherwise not.
The source code for above function is available at github: https://github.com/desowin/usbpcap/blob/master/USBPcapDriver/USBPcapHelperFunctions.c#L725
This solution doesn't play nice with USB 3.0 Root Hubs. As there are many different drivers for USB 3.0 controllers floating around there is not standard USB\ROOT_HUB30 entry. Basically every driver has its own hardware ID. I would prefer to avoid making a list of hardware IDs for all root hubs out there.
I would like to know if there is any way to reliably determine whether device is root hub without relying solely on hardware ids.
I thought about checking if device has GUID_DEVINTERFACE_USB_HUB and its parent has GUID_DEVINTERFACE_USB_HOST_CONTROLLER, but I don't know how (and if) it can be done in kernel mode inside function called in AddDevice callback.
I solved this issue by generating list of non standard (by standard Hardware ID I mean USB\ROOT_HUB and USB\ROOT_HUB20) Hardware IDs in user-space application and storing it in registry. I enumerate all GUID_DEVINTERFACE_USB_HOST_CONTROLLER instances and assume that children are Root Hubs.
Driver checks if the Hardware ID is present in registry entry generated by user-space application. If it matches, it is considered a Root Hub.
Related
I am in the progress of implementing a service which will detect usb plugin/removal using usbdi callback functions. Callback function has a parameter "usbd_device_instance_t * usbInstance" from which i can get device vendor id,product id and the device class information. But how do i get a mount point in case of a mass storage device and a device path in case of a HID device?
In QNX 6.6 and 7.0, usblauncher writes a map of detected devices, launched drivers, and their arguments such as mount point to the PPS tree. The USB Launcher Service reference manual has complete documentation on the location and formatting of these entries. You could scan them to find out what high level details you need.
That said, the usblauncher script engine also provides a place where you could add custom on-connect commands directly; that might be easier than writing a new service.
I have built a simple PCI driver for reading and writing data to a PCI device. I have also added interrupt support, so when there is a PCI interrupt an ISR is called. This all seems to work.
I would like to inform an external application of the interrupt. So far I haven't found a suitable mechanism. The interrupt could come at any time, and is dependent on Sensors connected to the PCI device.
I have found the following:-
1 Event objects which can be passed to the KMDF driver via read, write, iocontrol commands (Overlapped object)
2 Plug and Play notifications, which can be use used by (Toaster example code) the driver to inform the app of PNP events.
A notification method would be ideal, however it doesn't look like one exists for my particular use case.
There are at least 2 ways to achieve what you are looking for
Inverted call model - send IOCTL(s) to the driver which the driver will keep pending and will complete them as and when it needs to notify the user mode about the occurrence of the event that it is interested in. You can read more about this approach here.
Use shared event handles. A user mode application communicates the event handle(s) to kernel mode using an IOCTL. The kernel mode increments the reference count to ensure that the handle remains valid when it needs to use it and then signals the event when necessary. You can read more about this approach here.
The first approach is more preferred for various reasons that you will find while reading the linked articles. If your use case requires the kernel mode to not only indicate the occurrence of an event but also send some data back to user mode then the second approach is not suitable for your requirement and you should focus on the first approach alone.
Let's say I have more physical devices supporting Vulkan (dedicated + integrated GPU, or 2 dedicated, or other possibilities). The user can choose the device to use in the options screen. I need to be able to persist his choice on disk.
What field can I use to uniquely identify a physical device across different executions?
vendorID + deviceID is not enough: I could have 2 identical GPUs connected
deviceName is not enough for the same reason
deviceLUID is not guaranteed to be present, and may have the same problems as deviceUUID (below)
deviceUUID looks like the correct choice, but the spec says:
While VkPhysicalDeviceIDPropertiesKHR::deviceUUID is specified to remain consistent across driver versions and system reboots, it is not intended to be usable as a serializable persistent identifier for a device. It may change when a device is physically added to, removed from, or moved to a different connector in a system while that system is powered down.
So... what should I use?
deviceUUID is the best you're going to get.
Think it like this. If the deviceUUID matches a cached copy, then you are certain that it's the same device. And if the cached ID doesn't match any existing device, then either that hardware was removed or something radical happened. Either way, you need to pop up that dialog again to let the user decide what to do.
I've worked with WPD API for a while now, and I seem to run in to problem after problem.
Once I fix one problem, something else pops up. But hey, that's life.
I've been trying to determine if a WPD device is a storage device or a phone or whatever.
Turns out, devices such as iPhone are not set to be recognized as a phone, but instead as a generic device in terms of WPD_DEVICE_TYPE.
But, it is presented to Windows as a storage device.
When connecting external harddrives, SD memory card readers and other more conventional storage devices, they are recognized by the WPD API as well, but ehy that also get a dedicated mount point in Windows.
If I connect an external harddrive, it will have one functional category object, and the value of that object will be the path of that drive, say E:.
Nice. Great!
So my question is: How can I somehow read if the WPD device has a mountpoint?
Sure the functional object indicates that it has one, but is it possible that there could be an indicational value which states that a mount point is available?
Check the device Ids, here's an example how they differ:
\\?\swd#wpdbusenum#_??_usbstor#disk&ven_usb&prod_flash_disk&rev_1100#aa04012700007404&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}#{6ac27878-a6fa-4155-ba85-f98f491d4f33
vs.
USBSTOR\DISK&VEN_USB&PROD_FLASH_DISK&REV_1100\AA04012700007404&0
The upper one is the Id gathered from PortableDeviceManagerClass (first step to create an PortableDevice object), the lower one I've just read from the Device Manager, but it should be easily retrievable with one of these solutions:
How do I get a Unique Identifier for a Device within Windows 10 Universal?
https://sourceforge.net/projects/sharpdevelop/files/SharpUSBLib/
We make a device that can appear as a USB serial port on a variety of POSIX-compliant systems. I'm supporting an API that allows callers to retrieve a list of all the currently available (i.e. not in use, have correct privileges, etc.) instances of our device available to them. The caller can also get a list where the in-use devices are also indicated.
The simple way to do this of course is just attempt to open/close each candidate serial port and take note of which ones are open-able. I would prefer not to do this as it is possible that multiple applications using this API (which would be a library / dylib in their app) could create race conditions where they both try to query the same serial port simultaneously which would cause one app to erroneously think the device was in use.
So what I need is a way of knowing the port is open-able without actually opening it. I have seen others use lock-file schemes where there is a special file created to indicate the port is in use - the assumption being that if the file is not present the port is available. My problem is that there may be other users of the port other than my library that do not abide by such as scheme, so I cannot rely on it.
Is there perhaps some low-level POSIX functionality that lets me query a file's status in this regard without actually attempting to open it?