Category Archives: Driver development

Adventures in driverland, pt. 1

I’m trying to figure out how to write a virtual HID (human interface device) driver for Windows. By virtual, I mean a device that I’ll be able to control from userspace; for example, by feeding it packets received from network. Since I’m rather slowish in this endeavor, and there’s very little sensible documentation on the internet on how to do this, I’ll document my exploration of the WDK (Windows Driver Kit).  This will hopefully help me understand things better.

Don’t use this as a documentation, and perhaps not even as an explanation of WDK; I’m just typing down what I currently believe about the subject.

So first of all, there are many suggestions to take a look at the sample “hidusbfx2”. This is located in /src/hid/hidusbfx2. This is a driver for a generic USB-teaching device. This device does not present itself as a HID-class USB device, or else Windows’ built in drivers would take place.

HID-class devices are mouses, keyboards, et cetera. I believe that when docs speak of “HID-class Device Driver” , they mean a generic driver for handling any sort of mouse, keyboard, et cetera. These drivers, I believe, don’t actually know how to speak with the hardware. In case of USB-based HID-class devices, the most common kind, Windows do that automatically. They use their own “HID minidriver”.

So what we need to do is implement a HID minidriver. HIDUSBFX2 is, I’m sure, a pretty good example in case you want to write a driver for something that actually connects to a USB port. I don’t have the cash to afford the board used, and I don’t want to develop a driver for an actual device, anyway. As a beginner, I don’t really know how to separate the hardware layer from the software layer. Hence, this is not such a good example for my purposes.

Luckily, one of the rarest gems I ever dug out from the Internet is vmulti by Daniel Newton. This is a virtual HID driver just like one I’m trying to write, but this one is specialized for  implementing multitouch on Windows 7. By its folder structure, it is so obviously derived from HIDUSBFX2 that comparing these two might even yield some results. I didn’t yet do this, however.

I have immediately attempted to build and install vmulti. Unfortunately, its documentation is quite scarce, and there isn’t an explanation on how to build it and install it, and not even a documentation on how to use it. There is a test program however; that’s something I’ll have to take a look later on.

vmulti is a KMDF driver (a kernel-mode driver, but higher-level compared to the old WDM model). Windows, due to architecture of  WDF (Windows Driver Foundation) do not support HID class drivers on KMDF level. That’s why Microsoft wrote a “HID mapper”; a thin layer written in WDM to allow KMDF HID-class minidrivers. This is called “hidkmdf”; for Windows 7, you don’t even need to compile it and ship it with your driver since it comes under name “mshidkmdf”. This is what WDM actually thinks the driver is; but, in reality, it’s just a stub, and we write our “filter driver” (HID minidriver) which contains the actual driver code.

So I went and tried to build vmulti, all of its components: Microsoft-provided hidmapper/ folder (containing hidkmdf), vmulti’s sys/ (containing vmulti) and vmulti’s test/ (containing a test tool). I cd’ed into its folder, and I ran command “BLD”, as recommended by Microsoft.

This is where I’m stuck: Windows XP’s Add New Hardware claims there is no information about my hardware when I go to the folder where I put vmulti.inf, and both vmulti.sys and hidkmdf.sys. The alternative I dug out is called “devcon”; it ships with WDK in /tools/devcon/devcon.exe.

Last I’ve tried is a modification of Microsoft’s example how to use devcon/ that came with “echo” example:devcon install vmulti.inf "root\vmulti"

This is where I’m stuck:

Device node created. Install is complete when drivers are installed...
Updating drivers for root\vmulti from C:\projects\vmulti\sys\objfre_wxp_x86\i386
devcon failed.

Tomorrow is another day! I want to figure this out, and Microsoft did not make it easy, that’s for sure. I’m in a documentation hell; they wrote so much of it, but so little of it is useful.