Windows drivers - communicate with user process - device

I have written a application in Qt and what is the best way to communicate with a custom USB device (does not belong to any class - need to write custom drivers for it) under Windows. In Linux I could just share the data with user space from the /dev or /sys filesystems. What are the equivalent alternative in Windows ?

There are a couple of user-space USB libraries for Windows. While Microsoft do provide WinUSB directly, I'd recommend using either libusbx or libusb and installing the driver for your device with zadig.
Using libusbx rather than the Microsoft driver directly has the advantage of being easier to port to other operating systems, which might be a consideration for you as you are using Qt.

Related

linux cdc_ecm driver vs rndis driver

How is linux cdc_ecm driver related to rndis protocol? Is cdc_ecm based on rndis specification from microsoft in any way?
From this wiki page https://en.wikipedia.org/wiki/RNDIS
The USB Implementers Forum (USB-IF) defines at least three non-proprietary USB communications device class (USB CDC) protocols with comparable "virtual Ethernet" functionality; one of them (CDC-ECM) predates RNDIS and is widely used for interoperability with non-Microsoft operating systems, but does not work with Windows.
seems cdc_ecm to be based on microsoft rndis.
CDC-ECM is a standard that was created by USB-IF. It's not related to RNDIS at all. As your quote says, it predates RNDIS. This means it was created before RNDIS existed, so it couldn't be based on RNDIS unless a time machine enters the picture. And if you look at the protocol, it's clearly different.
CDC-ECM works out of the box on Linux hosts, MacOS, ChromeOS, and certain (mainly Samsung) Android phones.
Microsoft decided to create a new Ethernet on USB protocol instead of using the standard that already existed (CDC-ECM). That's just how Microsoft is. So they created RNDIS which isn't a standard and wasn't published. It's a hack based on NDIS, which is an old DOS and Windows 3.11 era network protocol from Microsoft. That's also just how Microsoft is. They like to base stuff on top of older MS software, which is based on even older MS software, going all the way back to DOS. That makes it really complex and hard for anyone else to be compatible with.
Microsoft doesn't include CDC-ECM drivers in Windows, but does have RNDIS drivers.
One can't get Windows to load the included RNDIS drivers, without a INF file, using just the vendor and product ID, device class, etc. There is a non-standard USB device identification descriptor that Microsoft created (see the pattern here) that must be used to identify a RNDIS device to Windows so it will load the generic driver.
Linux has a CDC-ECM / RNDIS combo gadget that is useful for wider compatibility. This appears as a two function USB device. One function is RNDIS and Windows will use this. The other function is CDC-ECM and everyone else will use that. It's not "ECM with RNDIS support". It's two different functions, only one of which can be used at once, that are both created by the same gadget.

Porting a Linux kernel driver to libusb

So I was wondering: Since libusb provides userspace access to USB, is it possible to port already existing kernel drivers to libusb?
I do understand it might need rewriting of the driver, but do you think it is possible to write a "virtual kernel" that relies on libusb for access to devices and link already existing drivers to that? Essentially writing a layer between libusb and kernel modules that translates kernel USB commands to libusb commands.
Why bother? If you want to run a kernel driver on Android for example, you need to make sure it was compiled for a particular kernel version/device model. So an app will not be able to run on all devices. On the other hand libusb is fully compatible with most of the latest Android devcices.
AFAIK, libusb is a library that communicates with the higher level of the USB layer of the kernel. The lowest parts of the USB subsystem have to be written in kernel space, because they need to have access to the physical address space of the USB host controller and uses interrupts, and other low-level functions that are not possible to implement in user space.
So I don't think that it is possible to port low-level parts of the USB subsystem in user-space.

Virtual USB device for Windows?

I'm investigating options available for creating a virtual USB device (say, a keyboard or a mass storage device), so to emulate its function as needed and to allow a userspace app to emulate its insertion/removal at will.
What I am not clear about is how to go about the emulation of insertion/removal. It seems that one option is to emulate a (virtual) USB hub and have it fake the device arrival/departure events (and I would also supply the device driver for my virtual USB device and that's where my device logic will reside).
I know my way around Windows kernel (having written NDIS miniport drivers), not afraid of SoftICE, but USB is not my domain, just starting out with it.
Am I on the right track with the virtual hub approach? If so, is developing virtual hub drivers supported by WDK (it doesn't seem to be)?
Any other options?
--
(Edit) Forgot to mention - I am aware of DSF, but it is not supported on W8.
Am I on the right track with the virtual hub approach?
In short - yes, I was right.
That's how USBIP does it and it's a relatively simple way to go. Also, see this comment by Eugen.
I don't know if you are aware, but Microsoft released to Win10 the UDE (USB device emulation).
In the section Write a UDE client driver they describe exactly what you want.

How can I make a custom USB device show up in Windows as a COM Port?

I have developed a USB device that communicates with linux over a simple but proprietary interface and some custom Linux drivers. My goal is to port this to Windows without writing windows drivers. What I would like to do is find an open source or inbuilt class driver for windows that would look like a COM port in Windows. Then I would tailor the embedded software to match what ever protocol and descriptors the virtual COM port expects to see.
The idea would be that I could plug my device in to a Windows machine and a relatively high speed COM port would appear with out me having to develop Windows drivers for it.
I have been looking at the USB CDC (Communications Device Class) documentation and it looks promising, but I don't know which sub interface would be best to use so that it would show up as a COM port.
Has anyone here done any work like this before or could provide some insight?
Specifically:
Are there virtual COM drivers "built in" to windows or would I need a 3rd party driver.
Which CDC sub class should I use for simple RS232 emulation (No need for modem AT commands, etc)
Is there a better option to do what I am trying to do.
Thanks
There is a USB-to-serial driver built in to Windows that will do what you want. It is called usbser.sys:
http://support.microsoft.com/kb/837637
You will have to write an INF file and distribute that to your users, but that will not be too hard because it is only a few kilobytes of text and you can find examples online.
I'm not aware of any great documentation for this driver by Microsoft, so my advice would be to find some other device that uses it, such as Pololu Wixel, and copy what they did.
Here are the device descriptors we used and the special control tranfers we had to implement:
https://github.com/pololu/wixel-sdk/blob/master/libraries/src/usb_cdc_acm/usb_cdc_acm.c
You can see our INF file, wixel_serial.inf, by downloading the software and looking in the drivers folder:
http://www.pololu.com/docs/0J46/3.a
(There are other files in there that are not necessary for you.)
You can also look at the Arduino Uno because they use the same driver.
Whatever you do, please don't use our USB Vendor ID in your product! You need to get your own.
Update: In Windows 10, you don't need an INF file anymore because of the new usbser.inf driver that comes with Windows.
If you are using a UART you can easily interface it to a FTDI USB chip like http://www.ftdichip.com/Products/ICs/FT232R.htm or a Prolific like http://www.prolific.com.tw/eng/products.asp?id=59
For development, prototype and testing I have half dozen of these laying around http://www.pololu.com/catalog/product/391
I connect it directly to the UART pins on AVR and 8051 micros.

Custom USB Driver for Windows? Mac?

I'd like to modify a USB driver to send and receive USB data over a network.
Take for example, an iMac and a PC. I have an iPod plugged in to my PC (in NY). I want my iMac (in LA) to recognize the iPod as plugged in to a local USB port and be able to communicate with the iPod.
Forget my qualifications, or lack thereof (I have background in web, iOS apps, I've toyed with Java and C).
Where can I get source code for a USB driver for Windows that I can modify? Mac OS?
Any tips or pointers towards accomplishing my goal would be appreciated as well.
It looks like folks are coming up with something close to what you want. If you do decide to roll your own, the USB driver source you asked for is libusb.
On the Mac OS X end, drivers are built up in a stack. What you want to do should be relatively simple (nothing is really simple in kernel land). You need to create a driver that can communicate over ethernet with the PC and looks like a USB device to the driver matching software. Then everything else will happen automatically.
The source code is available for Apple's USB stack. You should also read about the IOKit API and IOKit device driver guidelines and IOKit fundamentals.
Oh yes and you say you have toyed with Java and C. To write device drivers on OS X, you'll need to learn some C++.
I suggest you to go see USBIP project. This is available on Linux and Windows, but not clear for MAC. If you can get a VHCI-Controller driver installed for MAC, we can kick start USBIP for MAC.
Sounds quite like this product, a bit unsure if theirs works over wide-area networks though.
I have a general idea of how I'd go about it, but not any specifics. Basically, I'd use the platform's driver development kit to write a USB device emulator on the client machine. I'd then add a virtual device to that system called "Networked USB Host", or something similar that maintains an open port to listen for communication from the server and passes it on to your virtual USB device. IIRC, the Windows DDK comes with a USB simulation framework that might be able to help you with this.
On the server, you'd have to hook into the USB subsystem to send raw USB packets to the client machine. libpcap and wireshark have USB capturing facilities for that, but I'm not sure if this works with winpcap and the Windows version of wireshark as well.
EDIT: Look at this for cross-platform USB capture alternatives.
You can buy OSR USB learning kit: https://www.osronline.com/custom.cfm?name=index_fullframeset.cfm&pageURL=https://www.osronline.com/store/index.cfm
This is actually small USB device with known interface. Windows Driver Kit (WDK) contains sample KMDF driver for this device: http://www.microsoft.com/whdc/driver/wdk/
This is good starting point to learn Windows Drivers development, and USB drivers development specifically. However, it is still far away from your problem solution.
Can't you use some sort of Remote Desktop?

Resources