Custom Joystick Driver

Hi,

Synopsis:

I am writting a custom joystick driver. In a sense, what I have is a USB device that uses the standad windows drivers that come with the OS but it does not look like a joystick!
The hardware provides API so I can detect the axis/button values - and would like to make these be passed as joystick input to the OS (ie. make it look like a joystick)

After research, here’s what I found:

  1. Use KMDF (I can probably use UMDF but I perfer for performance reasons it to be a kernel driver)
  2. Since DInput looks at the VjoyD or HID stack I have the following options:
    a. Using VJoyD, write mini driver, handle the 4 defined callbacks:
  • Poll routine
  • Configuration Manager callback
  • Hardware capabilities callback
  • Joystick identification callback

b. Use HID and write HID function driver or even HID mini driver

  • Use the API that comes with the hardware, read the axis/button values and write it to a global buffer.
  • Then handle the IO READ event and convert the joystick value to a HID report

What I would like ask you guys is if my 2 options are sound or should I pursue another option?
Anyone has experience with HID class devices? I looked at the samples in WDM and generating the HID report descriptor and the HID report is a mess - quite few values that you have to know to set and they have to be correct so the hardware looks like an joystick input device.
Any other input, suggestions is very much appreciated. Thanks in advance.

Btw, this will by my first driver. I have read quite a bit in WDF docs on joysticks and HID, looked at briefly at the USB spec and also reading currently Developing Drivers with the Microsoft Windows Driver Foundation. I have very basic understanding of WDM and the OS related aspects.

You want to write a HID miniport driver using KMDF, see src\hid\hidusbfx2\sys as a starting point. You will have to understand hid report descriptors, no other way about it. Vjoyd is dead, that is windows 9x stuff, not used in 10+ years. I don’t understand what you mean by
use the API" that comes with the hardware. Do you mean specific URBs you send? Or user mode function calls that give you this information?

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Sunday, May 29, 2011 3:31 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Custom Joystick Driver

Hi,

Synopsis:

I am writting a custom joystick driver. In a sense, what I have is a USB device that uses the standad windows drivers that come with the OS but it does not look like a joystick!
The hardware provides API so I can detect the axis/button values - and would like to make these be passed as joystick input to the OS (ie. make it look like a joystick)

After research, here’s what I found:

  1. Use KMDF (I can probably use UMDF but I perfer for performance reasons it to be a kernel driver) 2. Since DInput looks at the VjoyD or HID stack I have the following options:
    a. Using VJoyD, write mini driver, handle the 4 defined callbacks:
  • Poll routine
  • Configuration Manager callback
  • Hardware capabilities callback
  • Joystick identification callback

b. Use HID and write HID function driver or even HID mini driver

  • Use the API that comes with the hardware, read the axis/button values and write it to a global buffer.
  • Then handle the IO READ event and convert the joystick value to a HID report

What I would like ask you guys is if my 2 options are sound or should I pursue another option?
Anyone has experience with HID class devices? I looked at the samples in WDM and generating the HID report descriptor and the HID report is a mess - quite few values that you have to know to set and they have to be correct so the hardware looks like an joystick input device.
Any other input, suggestions is very much appreciated. Thanks in advance.

Btw, this will by my first driver. I have read quite a bit in WDF docs on joysticks and HID, looked at briefly at the USB spec and also reading currently Developing Drivers with the Microsoft Windows Driver Foundation. I have very basic understanding of WDM and the OS related aspects.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Thank you for quick response.

What I meant by custom API that comes with the hardware is that the hardware (Phidget I/O board - http://www.phidgets.com/) comes with WIN32 DLL that contains API calls to read the values from the board.

You mentioned VJoyD is dead but I found following references in the new WDF (URL when you open help file: ms-help://MS.WDK.v10.7600.091209.01/HID_d/hh/HID_d/di_4a6d7425-64f3-4d3e-bbb0-c19ba70d910e.xml.htm). Why would they advocate to use VJoyd ? Here`s some info WDF docs:

In DirectX 5.0, DirectInput starts and offers an alternative, COM-based API. Dinput.dll uses VJoyD and, if available, the Human Interface Device (HID) stack, to provide polling services. HID devices are also reported through VJoyD so that applications that use the older API are still able to read the new devices. A driver supplied by the OEM, which can be either a DLL loaded by Dinput.dll, or an extended VJoyD minidriver, handles the force-feedback.

Joystick hardware that is not polled or that has nonstandard polling requirements can implement a minidriver (which must be a VxD) that VJoyD loads when a device of that type is in use. VJoyD also calls the minidriver to access position and button information. Joystick minidrivers are not required to provide any interfaces other than to process the standard SYS_DYNAMIC_DEVICE_INIT and SYS_DYNAMIC_DEVICE_EXIT messages when the device is loaded and unloaded, and to define and register four joystick-specific callbacks.

The hardware API is like you said user mode functions sitting in Win32 DLL.

User mode APIs are not good for your project, makes life way too complicated. What device class is your hardware ? You will be much better off if you can get the endpoint interface for the hw itself, no need for user mode DLLs. As for vjoyd, VXDs died with windows millenium. DirectX is now on v10 or 11, v5 is no longer supported.

d

debt from my phone

-----Original Message-----
From: xxxxx@hotmail.com
Sent: Sunday, May 29, 2011 4:11 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Custom Joystick Driver

The hardware API is like you said user mode functions sitting in Win32 DLL.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

If I understand your question correctly, HID class (system32/hidclass.sys).

I misunderstood the documentation I guess, when I saw DirectX5 I thought it was DirectX5 and up, up to current version.

Since I am really new to writing device drivers can you explain a bit more how to get the hw interface endpoint so I can read the values from connected i/o USB board.

Another option I have is - I could write a virtual joystick driver that listens for custom IOCTLs send from user app and translates these to HID reports so it looks like a joystick but I perfer to not to do that if I can read the hardware itself.

Thanks again for great support.

Here’s more information about the USB (USB Analyzer dump).
If you need more, like the interface descriptor or interface report descriptor I can send that to ya.

Device Descriptor PhidgetInterfaceKit

Offset Field Size Value Description
0 bLength 1 12h
1 bDescriptorType 1 01h Device
2 bcdUSB 2 0110h USB Spec 1.1
4 bDeviceClass 1 00h Class info in Ifc Descriptors
5 bDeviceSubClass 1 00h
6 bDeviceProtocol 1 00h
7 bMaxPacketSize0 1 08h 8 bytes
8 idVendor 2 06C2h Phidgets Inc. (formerly GLAB)
10 idProduct 2 0045h
12 bcdDevice 2 0817h 8.17
14 iManufacturer 1 01h “Phidgets Inc.”
15 iProduct 1 02h “PhidgetInterfaceKit”
16 iSerialNumber 1 03h “31495”
17 bNumConfigurations 1 01h

You need to look at the descriptors to figure it out. Since you already have an analyzer, you could easily start calling APIs in a test app and then capturing what transactions on the wire result from those API calls. Or ask phidgets for the wire protocol spec

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Sunday, May 29, 2011 8:06 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Custom Joystick Driver

Here’s more information about the USB (USB Analyzer dump).
If you need more, like the interface descriptor or interface report descriptor I can send that to ya.

Device Descriptor PhidgetInterfaceKit

Offset Field Size Value Description
0 bLength 1 12h
1 bDescriptorType 1 01h Device
2 bcdUSB 2 0110h USB Spec 1.1
4 bDeviceClass 1 00h Class info in Ifc Descriptors
5 bDeviceSubClass 1 00h
6 bDeviceProtocol 1 00h
7 bMaxPacketSize0 1 08h 8 bytes
8 idVendor 2 06C2h Phidgets Inc. (formerly GLAB)
10 idProduct 2 0045h
12 bcdDevice 2 0817h 8.17
14 iManufacturer 1 01h “Phidgets Inc.”
15 iProduct 1 02h “PhidgetInterfaceKit”
16 iSerialNumber 1 03h “31495”
17 bNumConfigurations 1 01h


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

When you say “you could easily start calling APIs in a test app and then capturing
what transactions on the wire result from those API calls …”

Those APIs, what exactly do you mean by that? The Phidget API shiped by the hardware dudes that are the user mode functions in the Win32 DLL? Or are these WDM APIs to access the hw endpoints? Or something else?

I apoligize but I am new to device drivers so I need a bit more explanation.

  1. hook up the analyzer
  2. write a user mode test app
  3. call user mode phidget API
  4. look at the analyzer’s output for what happened on the wire
  5. go back to 2), call a different phidget API
  6. when done, figure out how to send the same traffic in a KMDF driver using WdfUsbPipe APIs

OR

Call phidget and ask if they will send you a spec for the device protocol, eliminating 0)-4)

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Monday, May 30, 2011 7:48 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Custom Joystick Driver

When you say “you could easily start calling APIs in a test app and then capturing what transactions on the wire result from those API calls …”

Those APIs, what exactly do you mean by that? The Phidget API shiped by the hardware dudes that are the user mode functions in the Win32 DLL? Or are these WDM APIs to access the hw endpoints? Or something else?

I apoligize but I am new to device drivers so I need a bit more explanation.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Aaaaaah, I understand. Thanks for those simple steps.

Because you said you are newby in device driver development, I would suggest
you to go with a user mode UMDF device driver. This way we could use the
user mode DLL Phiget provides and you could debug the driver almost as a
normal application. If you already know COM technologies, developing a UMDF
driver would be very easy.

I know you was concerned about performance, but I would not worry about that
for a device as a joystick except if this joystick have an embedded high
definition video or other very special feature. This is even more true if
you want to run the driver on a modern computer with more core than really
needed.

You can find an example of UMDF driver on my web site at www.kms-quebec.com.
Badly, the site and the example is in French.

Martin

-----Message d’origine-----
De?: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] De la part de Doron Holan
Envoy??: May-30-11 10:52 AM
??: Windows System Software Devs Interest List
Objet?: RE: RE:[ntdev] Custom Joystick Driver

  1. hook up the analyzer
  2. write a user mode test app
  3. call user mode phidget API
  4. look at the analyzer’s output for what happened on the wire
  5. go back to 2), call a different phidget API
  6. when done, figure out how to send the same traffic in a KMDF driver using
    WdfUsbPipe APIs

OR

Call phidget and ask if they will send you a spec for the device protocol,
eliminating 0)-4)

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Monday, May 30, 2011 7:48 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Custom Joystick Driver

When you say “you could easily start calling APIs in a test app and then
capturing what transactions on the wire result from those API calls …”

Those APIs, what exactly do you mean by that? The Phidget API shiped by the
hardware dudes that are the user mode functions in the Win32 DLL? Or are
these WDM APIs to access the hw endpoints? Or something else?

I apoligize but I am new to device drivers so I need a bit more explanation.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

you currently cannot write a HID minidriver in UMDF.

d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Martin Dubois
Sent: Tuesday, May 31, 2011 2:41 PM
To: Windows System Software Devs Interest List
Subject: RE: RE:[ntdev] Custom Joystick Driver

Because you said you are newby in device driver development, I would suggest you to go with a user mode UMDF device driver. This way we could use the user mode DLL Phiget provides and you could debug the driver almost as a normal application. If you already know COM technologies, developing a UMDF driver would be very easy.

I know you was concerned about performance, but I would not worry about that for a device as a joystick except if this joystick have an embedded high definition video or other very special feature. This is even more true if you want to run the driver on a modern computer with more core than really needed.

You can find an example of UMDF driver on my web site at www.kms-quebec.com.
Badly, the site and the example is in French.

Martin

-----Message d’origine-----
De?: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] De la part de Doron Holan Envoy??: May-30-11 10:52 AM ??: Windows System Software Devs Interest List Objet?: RE: RE:[ntdev] Custom Joystick Driver

  1. hook up the analyzer
  2. write a user mode test app
  3. call user mode phidget API
  4. look at the analyzer’s output for what happened on the wire
  5. go back to 2), call a different phidget API
  6. when done, figure out how to send the same traffic in a KMDF driver using WdfUsbPipe APIs

OR

Call phidget and ask if they will send you a spec for the device protocol, eliminating 0)-4)

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Monday, May 30, 2011 7:48 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Custom Joystick Driver

When you say “you could easily start calling APIs in a test app and then capturing what transactions on the wire result from those API calls …”

Those APIs, what exactly do you mean by that? The Phidget API shiped by the hardware dudes that are the user mode functions in the Win32 DLL? Or are these WDM APIs to access the hw endpoints? Or something else?

I apoligize but I am new to device drivers so I need a bit more explanation.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

No worries! I am a noob but got skillz :slight_smile:
For me reading about kernel device drivers is fascinating is the only thing that is inspiring me to write this driver.

You are absolutely right about performance, I will not notice the difference but somehow I feel like I would be cheating writing a UMDF driver, - just my conscience, don’t worry about it.

The COM thing in UMDF imho is just plain wrong. I do know COM very well but (sorry MS folks) this COM thing is totally unneccessary and yes we could argue about this day and night but COM truly doesn’t simplify much, - you just trade one thing for another. I rather use WIN32 API (you don’t have to learn COM and all the fun rules that come with it like marshaling, memor allocation rules, thread apartments, etc.

Obviously OOP using C++ is the nicest.

To be clear, COM in UMDF is “COM lite”. No marshaling. No allocator rules. No apartments. All it is is the IUknown binary contract.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Tuesday, May 31, 2011 2:54 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Custom Joystick Driver

No worries! I am a noob but got skillz :slight_smile: For me reading about kernel device drivers is fascinating is the only thing that is inspiring me to write this driver.

You are absolutely right about performance, I will not notice the difference but somehow I feel like I would be cheating writing a UMDF driver, - just my conscience, don’t worry about it.

The COM thing in UMDF imho is just plain wrong. I do know COM very well but (sorry MS folks) this COM thing is totally unneccessary and yes we could argue about this day and night but COM truly doesn’t simplify much, - you just trade one thing for another. I rather use WIN32 API (you don’t have to learn COM and all the fun rules that come with it like marshaling, memor allocation rules, thread apartments, etc.

Obviously OOP using C++ is the nicest.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Absolutely true, but learning COM on a diet without learning its common facets (I say common because certain things you should know about COM to use it effectively,- I dont mean by this learning how to write ActiveX, OLE, etc. - just things COM developer should know) is really not going to be much of use for professional developer. That’s just my opinion.

xxxxx@hotmail.com wrote:

Absolutely true, but learning COM on a diet without learning its common facets (I say common because certain things you should know about COM to use it effectively,- I dont mean by this learning how to write ActiveX, OLE, etc. - just things COM developer should know) is really not going to be much of use for professional developer.

“COM on a diet” is nothing more than pure virtual C++ base classes.

Most developers are way too afraid of COM. It’s not that complicated,
and it’s certainly not that heavyweight. It’s a much better way of
handling callbacks, because the object can carry state as well as the
function address.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Yes, COM is very lightweigh - not disagreeing with that and it is not complicated if you have been doing it for few years but the learning curve is rather steep when you consider learning simple concepts such as aggregation, and COM specific concepts such as connection points, threading, etc, etc, also it is easy to forget about AddRef, Release in your code and the smart ptrs only help you so much. COM also suffers from DLL hell.

COM interprocess communication protocol is slow compared to UNIX systems but then it is more about the OS not the technology.

I rather stick to basics and concentrate on my business requirements by using OOP without magic and it does the trick for me, - COM is not worth the price and clearly we can see that right now - .net just like MFC was not worth the price for WIN32.
Both have their places but in common world I got around with using these technologies sparingly.

>come with it like marshaling, memor allocation rules, thread apartments, etc.

You do not need any marshalling for UMDF, also the thread apartment stuff belongs to WUDFHost and not you so you again do not need to bother.

As about allocation - the same rules apply to all allocations made in a DLL. Nothing prevents you from using malloc() in COM, unless you will handle the object to the caller which will free it.

Most COM objects are allocated using ::operator new which is a wrapper around malloc().


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

>things you should know about COM to use it effectively,- I dont mean by this learning how to write ActiveX

OCX controls are by far harder then UMDF drivers.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com