Signal the PnP-Manager the device is gone - windows

i'm currently developing a KMDF HID minidriver for the Nintendo Wii Remote. My
HID minidriver replaces the HidBth minidriver for the HIDClass driver (I'm using
the KMDF HID minidriver sample, where it is actually a filter driver and uses
this "kmdfhidminidriver" to forward all requests).
So my problem is, when i power off the Wii Remote (pressing the Power button or removing the batteries), the PnP-Manager won't
recognize the device is gone. Windows still shows the device in the device manager and thinks everything is fine and
running. The only hint, that the device is gone is, that the L2CAP-Channel is
closed and i get the L2CAP-Callback called with Indicator Code
"RemoteDisconnect".
My question is, how do i signal the PnP-Manager the device has disconnected? I
tried using "WdfDeviceSetDeviceState" with "Removed" set to true. But then the
Device Manager shows an driver error (Code 24). I would like to have a solution,
where the device gets removed from the Device Manager without any error, like
unplugging an USB device.
Additional information: i'm using WDK 8 and WDF 1.11; driver target systems are
Win 7 and 8.

Ok, i have to use "HidNotifyPresence". It is prototyped in "hidport.h", but unfortunately not documented yet.
It takes two arguments. The first one is a device object, which might be the FDO. The second one is a BOOLEAN. If true the device will be re-enumerated, else the device is suprise removed.
Since my driver is a filter driver, i need to provide my own PassThrough (shim) miniport driver, which will pass the FDO and "HidNotifyPresence" addresses to the filter driver.

Related

Can anyone help me with an Unrecognized device: Device descriptor request failed error on Windows 8.1?

I have a Metrologic MS1690 Barcode scanner that I'm trying to use with Windows 8.1, I get a Unrecognized Device: Device descriptor request failed error in devices and printers. The scanner gets no power from the computer when it is plugged in because of this. It usually shows up as a usb keyboard in windows 8 and 7, but with 8.1 it does not and I can't find an answer anywhere. Please help! Or even if someone could tell me how to get a generic usb keyboard driver for this thing that may help as well. Thanks.
The scanner gets no power from the computer when it is plugged in
Bit of a guess, but there was a change in Win8.1 that can affect HID devices like this. Such devices are now suspended when no application or service is accessing it. This can cause the device to misbehave if it depends on receiving timely power to operate correctly.
The workaround is to disable Enhanced Power Management for the device. The instructions are pretty elaborately spelled-out in this blog post. At break-neck speed: use Regedit.exe, locate the device in the HKEY_LOCAL_MACHINE\ SYSTEM\ CurrentControlSet\ Enum\ USB key and set the EnhancedPowerManagementEnabled value to 0.
The "solution" for me has been to add a PCI-E USB card, and use that for the scanner. I went with this one from Rosewill because it uses an NEC chipset which I have heard good things about.
After installing the provided drivers for the PCI-E card, the scanner seems to enumerate consistently (I have only been able to test it for a couple days so far).
According to the person I bought my scanner from, it's an issue with the USB chipset on the motherboard. Some are compatible and some aren't. If I had to do it over again, I would go with an RS232 cable and a power adapter instead of USB. I haven't tested that setup, but if your app needs serial data like mine does, it should be more reliable given that it's not dependent on the vagaries of integrated USB chipsets.

Applications ignore USB device's incoming data packet while using default HID driver

I am writing a controlling software for a generic USB HID device within a team, working on Windows 7. Due to my status as an intern, my possibilities are limited:
the software must work on Windows
the software must use the default HID driver Windows supplies
My problem is that however I try to access the device while using the HidUSB driver (according to Zadig) my interrupt transfer read attempts always result with a timeout while the device actually does send data. Writing to the device works all the time, whether I use HIDAPI, whether I use libusb, only reading fails. (this is a primitive device atm and even the final packet data specification isn't done, currently it just sends an ON or an OFF string towards the host, and writing to the device changes the state of a LED between 7 colors and off state, so that one's certainly working)
I can't think of the device being faulty, because if I replace the driver on Windows to the WinUSB driver with Zadig, it works with libusb (and hidapi can't open the device thereafter) and on Linux, just by reading /dev/hidraw also returns the data fine. I have also read the HID and the USB specifications and I know that the device descriptors state that the USB packetsizes are 8, while the HID input report's size is capped at 20, tho I don't know what report ID the device uses.
Checking the Windows communications with USBPcap and Wireshark, the sole difference I can notice among the handling of the device is the host packets asking for data is filled with 00s against the HidUSB driver compared to the CCs when used with the WinUSB driver.
For the record, I have already tried libusb, hidapi, HidLibrary and noone within the team has an idea what to do now.
I have also read that Windows disables access to HID keyboards and mice but I found no actual example of a device config ending up as an USB mice. The Device Manager lists my device twice under HID tho, once as HID-compliant device or how it calls (localized Win7 here) and once as USB Input Device, but doesn't list it among the Mouse or Keyboard option.
Sorted it out a while ago, but I think I'll write it down here if someone ends up with a similar issue in the future.
The Windows HID driver invalidates any incoming packet if the report's data size does not match the length of the sent data iow the size within the report descriptor. Linux and the device itself didn't cared that's why I also ruled that out as source during the time I brought the question here. In the above example the on/off message being 4-5 byte vs the reported 20 byte length was the problem, now that the device sends 20B messages, all the solutions which could write via HidUSB can read as well.

Replace Windows USB Class Driver with a custom driver?

I wonder if anyone can help at all, a bit of a specialist problem this.
I have an application that needs to read and analyse a number of USB devices (not simultaneously, they are each run in seperate tests and could in theory be run on different machines).
Each of the USB devices is based on the USB HID class, and are manufactured by different companies, none of these USB devices are designed to be run on PC, but are meant for a different platform, however for the purposes of testing the devices the client has requested that the test application is run from a PC.
Some of the devices will start up, be recognised by windows which will initialise and start them correctly using the generic HID class driver built into windows, the devices will then start sending correct data packets of the data to be tested.
Some of the devices will start up, be recognised by windows which will try to start them but fail to fully to initialise them leaving them in a half initialised state. This is fine, as I can use my beagle protocol analyser to capture the initialisation packets from the genuine platform and then use the LibUSBDotNet library to replicate the remaining packets in the initialisation sequence and get them to start sending the packets correctly.
The problem I have is with one particular device (though there are some more I haven't tested yet so it's quite possible one of those may also exhibit the same problem). The issue is the the Windows HID class driver recognises the device and trys to initialise and start it, this works after a fashion and the device starts sending data.
The problem is that the data being sent is different to that which is sent to the genuine platform (containing only a subset of the full data). It's as though windows has initialised the device into a different mode.
When I capture the initialisation packets from both the PC and the genuine platform using my USB protocol analyser I see that Windows is sending some slightly different initialisation packets. Using LibUSBDotNet to resend the correct packets once Windows has already started the device seems to have no effect.
My problem is that I need to stop windows from trying to initialise the device using the standard HID class driver, I've tried removing the driver in Device Manager but it still initialises it (and the driver is magically reassigned in device manager). I've done some investigation and there are possible alternatives:
Create a specific driver which windows will assign to the particular VID/PID of the device but that does nothing, then I can use LibUSBDotNet to send the correct initialisation sequence to the device from within my own code.
Use something like WinUSB to create a proper driver for the device (or possibly to create a "dead" driver like 1.
Will a driver with a specific VID/PID defined be used by windows in preference to it's inbuilt USB HID class driver? If not then I would be wasting my time going down this route?
Note, my mac initialises the problem device correctly, and I've asked the question of the client whether the application can be developed for Mac and their answer was frustrating Windows only.
I've no experience in writing proper Windows drivers, though I have experience in talking to USB at a relatively low level (so that part doesn't worry too much). Can anyone suggest a good course of action (before I potentially waste weeks investigating how to write drivers for the PC only to find my selected course of action can't deliver what I required).
Any help or suggest much appreciated.
Thanks,
Rich
Added after trying suggestions below:
I tried using the LibUsbDotNet inf wizard to create the necessary files and install them and this appeared to work - certainly the device was now appearing in Device Manager as a libusb-win32 device - not HID device and the associated driver was libusb driver. Even after doing this the device still seems to become initialised and start sending the wrong type of data packets although now those packets are no longer handled by the class driver and are just lost.
I also came across Zadig which has a similar inf creation wizard for WinUSB and this had exactly the same result.
A colleague has suggested that it might not be windows itself that is switching the device into this mode, rather the device identifying that it is connected to a windows machine and switching itself into this mode. I suspect this is the case, in which case I am stuck - time to have another conversation with the client.
Many thanks for the help.
You're using libusb-win32 as a filter driver; that is, the HidUsb device driver is assigned and loaded for your device, but then the libusb-win32 driver is loaded on top and gives you unobstructed access to the hardware.
If you don't want a HidUsb (or any other class driver) to perform any communication "on your behalf", simply associate libusb-win32 as a device driver with your hardware. For this, you'd have to create an .INF file associating it with the VID/PID/Revision of each USB device. If I recall correctly, libusb-win32 even comes with a utility to generate such .INF files.
If you install this .INF file e.g. with PnpUtil.exe (available on Vista or higher), you might still run into issues where, although you're a better match than the generic HID driver, the HID driver is still selected.
The generic HID driver matches devices by their Compatible IDs (i.e. by a USB interface class) while you'd be matching by Hardware IDs (which have higher priority). However, Windows might give priority to other aspects, such as your driver being unsigned. Read: How Windows Selects Drivers
Luckily, even in that scenario, signing drivers with a self-generated certificate (use CertUtil.exe, MakeCat.exe and SignTool.exe) is not too difficult.

How to read from USB without any driver?

We are creating small system which has GPS receiver and PC. We want to test my GPS receiver, We do not want to go for a driver on the first go. First I would like to test my circuit works or nor. GPS IC has been set to output NMEA sentence. We want a program which just reads data from USB port and print it on the screen.
Can we write something like this easily ? Do we have any open source tool which will achieve this purpose ?
Platform : Windows 7
All devices need a driver, so I'm going to interpret your question as "how can I read NMEA data from my GPS using only drivers provided by the OS, so I don't have to write my own?"
If the GPS chip has a USB interface, then you should have gotten a driver with it. But most GPS chips have a UART interface which in your case sounds like it is connected to a separate USB-UART conversion chip. That conversion chip most likely came with a driver as well, but if not, you could jumper the reset pin of the converter chip, disabling it, and then attach a TTL/RS-232 level converter (available off-the-shelf) to the UART traces and then to your computer's serial port.
Unless you suspect that the driver for the USB-UART converter is causing problems, I wouldn't bother.
Anything connected via USB is a device. Devices require a device driver, period.
You might be able to get away with an existing driver built into Windows. This is how USB memory keys work for example - they present a generic device that looks like a removable disk, and Windows already includes the drivers for generic removable disks.
You would need to check the documentation for your device to see if it can emulate a device which already has drivers. Otherwise you must install the company's drivers, or you're out of luck.
Have a look at libusb. You should be able to read the data with that and a little code. (Yes, it's a driver. I take the question to mean "without writing a driver".)
You need a device driver for your device. Unless Windows already have a class driver for the device.
For USB devices on Windows 7 you can write a user-mode driver, see UMDF.

IWDFDevice::CreateWdfFile returns ERROR_INVALID_FUNCTION?

I am writing a UMDF sensor driver for a device that connects to the system via Bluetooth and is accessible as an HID input device. I saw the "Sensor Development Kit" sample driver and noticed that it works with the Freescale hardware via HID also though it connects to the system via USB. Is there any difference in the way the UMDF driver communicates with the device in case it connects to the system via Bluetooth? For some reason, I find that the call to CreateWdfFile returns ERROR_INVALID_FUNCTION even when I have the device paired with the system. I am able to access the device directly via HID just fine.
In the INF for the driver I have specified the hardware ID like so - HID\VID_1234&PID_5678 (haven't used the actual IDs here). Is this sufficient for the UMDF framework to determine which driver it should use further down the stack? Or is there something else that one needs to do?
I managed to resolve this one myself. Turns out I wasn't using the correct hardware ID. On a whim I looked up what hardware IDs the bluetooth device had been registered with under HKLM\SYSTEM\CurrentControlSet\Enum\HID and used another ID that had been given there and voila! - IWDFDevice::CreateWdfFile worked! :) And sure enough, this is described quite clearly on MSDN here. So, all's good!

Resources