I am a newbie learning how to write WDM device drivers for USB devices and found that the materials available are all too hard to comprehend (the DDK online doc is one of the most difficult to read, and the WDM Device driver book by Oney isn't anything better).
Today we will see how to list USB devices in Linux and their properties such as speed, BUS, class, type details etc. This is part of our on going hardware detection series. We already covered following stuff. Get BIOS, Firmware, Hardware And Drivers Details in Linux/Unix What is dmesg command and how to use it.
So, I've got a simple question. Where do I start if I want to create a virtual USB device (for example, a virtual USB mouse which looks like a real USB mouse attached to a USB port) for testing/learning.
So far what I understand is the HIDClass driver (hidclass.sys) has a minidriver for the usb bus (hidusb.sys) that carries out the enumeration of attached USB hardware. So, if I want to hijack the hardware enumeration process and creates my own virtual hardware, should I include a filter driver somewhere to intercept some IRPs related to the hardware enumeration process?
Sorry if the above does not make sense at all since I am still in the learning stage and this is actually one of the exercise I think could help me learn about writing USB device drivers better.
4 Answers
Windows uses a Plug and Play Architecture. When you insert a USB device, It sends low level USB request to the device and then based on the response from a device decides what driver to load. Matching is done by comparing vendor id, product id and etc to inf files sections. Drivers come in the form of a compiled xxx.sys with xxx.inf file and is loaded to kernel space. Windows decides which xxx.sys to load based on the *.inf file that comes with the device's driver.
These files have sections like this:
(a more detailed description on what's in inf
files can be found over on https://docs.microsoft.com/en-us/windows-hardware/drivers/install/inf-manufacturer-section)
A detailed look at the USB enumeration process (Use USB Logger):
- USB Device Plugged
- USB Bus Driver Request
- GetDescriptor(Device)
- GetDescriptor(Configuration)
- GetDescriptor(String iSerialNumber), used as Device Instance ID
- GetDescriptor(String iProduct), used in the 'new Hardware been identified' popups
- The PNP (Plug and Play) manager is informed that a device was added by the bus drivers.
- The PNP manager then asks the bus driver for device information by using a PNP request, asking for:
- DeviceID string, representing the USB Vendor and Product ID,
- HardwareIDs string,
- CompatibleIDs string, representing USB device' Interface Class, Subclass and Protocol, and
- InstanceID string, representing the uid for this particular device within the set of all instances with the same compatible id hooked up to the computer.
For any connected USB device you can see these strings using the Device Manager:
- Open the Device Manager (windows menu -> 'device manager', or control panel -> 'System' -> 'Hardware' -> 'Device Manager')
- then use the 'view' menu to switch to 'Device by Connection'
- open 'ACPI [...]' -> 'PCI bus'/'PCI Express Root Complex' -> '[...] USB [...] Host Controller'
- expand any of the entries under the host controller, and for any of the devices listed, right click to get their properties, open the 'details' tab, and then use the property pulldown menu to find 'Hardware Ids', 'Compatible Ids', 'Device Instance ID', 'Matching Device Id', 'Service', etc.
For example, I have a USB storage device with Device Id = usbclass_08&subclass_06&prot_50
hooked up, and this string can be matched to an .inf
file that was added to the list of known devices after first enumeration. This file has a string Service = USBSTOR
, and so we know that usbstor.sys
is used to interface with this USB Mass Storage Device.
Let's continue with matching process.
- The PNP Manager tries to determine whether Device was already 'installed':
- It search the registry for a key matching the 'DeviceInstance ID' to see which service handles interfacing with this device. Specifically, it searches for this in
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetEnumUSB
- It search the registry for a key matching the 'DeviceInstance ID' to see which service handles interfacing with this device. Specifically, it searches for this in
For disk on key, you can see something like:
- The PNP Manager then loads the associated driver based on a match between the strings in PNP requests and data from the .inf database:
- inf database located under: C:WINDOWSinf
- drivers .sys files located: C:WINDOWSsystem32drivers
- If PNP can't find matching string, you will get prompt to show a path to xxx.sys and xxx.inf
For writing drivers my advice is:
- Don't start with implementing HID (human interface device) devices, because you can cause windows to use your custom driver for you mouse or keyboard instead of original driver, this will disable your mouse or keyboard, very dangerous.
- Don't load drivers into your dev machine:
- use a virtual machine and install your drivers there. Set up a kernel debugger for your virtual machine: http://www.codeproject.com/KB/winsdk/KernelModeDebuggerSetup.asp
- or load drivers on other test machine.
- Good learning platform for USB drivers is 'OSR USB-FX2 Learning Kit'
![Usb vendor and product id security issues free Usb vendor and product id security issues free](https://media.digikey.com/datasheets/prod/ffe1b6e3-7c97-4182-b700-6f609c950aa9/bg2.jpg)
Use Device Simulation Framework (DSF).
You can use the USB/IP project to emulate any device that you want. In my blog I demonstrated how to emulate USB Mouse device in python using the USB/IP project:http://breaking-the-system.blogspot.com/2014/08/emulating-usb-devices-in-python-with-no.html
It wont help you to understand how to create the virtual USB device (the process is done in the USB/IP driver, you could read the code), but it will create the virtual USB HID device and you could play with the HID arguments sent to the USB driver.
Wouldn't it make more sense to provide your own bus type and enumerator?
Not the answer you're looking for? Browse other questions tagged usbdevicedrivers or ask your own question.
I have a problem with Huawei modem. Ubuntu 16 does not detect it as a mobile broadband modem. I cannot choose it in my Network Connections.
Have you got any idea what could I do?
I get the following error:
The output of lsusb | grep Huawei
is:
4 Answers
I have had the same problem and I have fix it. You need to install the Huawei driver for Ubuntu.
Configuration
With the result oflsusb
in the terminal (for me, the pid of my Huawei was12d1:15d2
, for example) See hereDownload the drivers :
HUAWEI Data Cards Linux (click on Download file).See hereInstallation
See here
From your lsusb
output I figure you are talking about a Huawei E352 USB 3G/4G modem, provided by T-Mobile NL. Most likely this is a Windows-induced problem. Windows first needs to install USB modem drivers to be able to mount the device as such. Instead of delivering a mini CD with drivers along with the USB modem, Huawei (and others) install some flash storage on their devices. So the device will be initially mounted as flash storage. Then, on a Windows machine, the installer will install the modem drivers and finally change the devices settings so it will be recognised as a modem next time.
For Linux users this is confusing, since their systems too will first recognise the flash storage, but not the modem. And the flash storage is not needed since the Linux kernel already has all necessary drivers onboard. I do not think you need to install any drivers.
What you need is the usb_modeswitch
tool. Install it from the Ubuntu repositories:
The following commands need to be run as root. So pay proper attention to what you are doing!
Connect your modem and find the vendor ID and product ID for your Huawei:
You will find what you already knew:
The vendor ID is '12d1' and the product ID is '14fe'.usb_modeswitch
has a lot of ready configuration files in a tar-archive. First find your device's configuration file in the archive:
Then extract your configuration file from the archive:
And bring it up:
It wil probably say:
Finally change the setting on your Huawei device:
Now the flash storage driver will be detached and the modem driver activated. To check if everything went well run lsusb
once more:
If all is well, you should see another product ID. A minor change with huge usability consequences...
After this you can set up your 3G/4G internet connection as usual with Network Manager. Make sure you switch off your WiFi, since WiFi and GSM will not run alongside each other.
If you want to keep track of your data use, install the vnstat
package. It is text based, but gives all the information. Might you prefer a GUI, also add the vnstati
package.
(Many thanks to Filip Vervloesem who covers this topic in length in the Dutch Linux Magazine 09/2017 issue.)
I tried with a new Ubuntu 16.04 UEFI and updated my BIOS to latest version, now it works like plug'n play. I had a too old installation with too many fixes and changes, now it just works. Thanks!
I have same problem after upgrade to Debian Stretch (9.0).
Fixed it like:
extract modeswitch config:
add line to file /lib/udev/rules.d/40-usb_modeswitch.rules:
and to file /lib/udev/rules.d/77-mm-usb-device-blacklist.rules:
reboot and dongle0 detected by asterisk