I am curious if it is possible to write joystick driver for Direct Input.
I know DInput uses HID but is there an alternative not to use HID?
I found in WDK following file dinputd.h - DirectInput include file for device driver implementors.
Is that what you use as an alternative API to write joystick driver for DInput?
As far as I know, directinput has standardized on HID. In the wild west days before HID was common place and before USB connected joysticks were prevalent, there was a driver model to plug in a joystick and configure it that was not HID. Now it is all HID. I don’t see why you are fighting this so much. Just accept you have to write a HID minidriver and stop wasting energy looking for other ways to accomplish this
I am curious if it is possible to write joystick driver for Direct Input.
I know DInput uses HID but is there an alternative not to use HID?
I found in WDK following file dinputd.h - DirectInput include file for device driver implementors.
Is that what you use as an alternative API to write joystick driver for DInput?
Its not too bad to make a HID minidriver… I have a KMDF virtual HID driver
sample at http://code.google.com/p/vmulti/ which includes a joystick if that
helps.
I think the key elements are:
use mshidkmdf (inbox win7) or the hidmapper WDK sample as an upper
filter, this will call HidRegisterMinidriver (which KMDF cannot do directly)
and basically pass down all requests to you
remember that HIDClass is now the power policy owner of your stack
Once you have implemented all the HID mini ioctls correctly HIDClass will be
happy and enumerate the HIDs for each top level collection in your
descriptor and if you have a joystick or something then most probably some
system service will start throwing read requests
(IOCTL_HID_READ_REPORT/IOCTL_HID_GET_INPUT_REPORT) at it. Shove them in a
manual queue and simply complete them (with data that matches your TLC
report descriptor) whenever you get data from your actual device.
On Wed, Jun 1, 2011 at 5:52 AM, wrote:
> Hehe, OK I admit I was looking around … but that’s just my curiosity > and lack of knowledge in this area. > > I am planning to use HID since this the current way of doing this. > > I read the USB spec 1.1 and my head is spinning, I will sleep over it and > read it once more and I should be just dandy. > > Thanks again for your reply, > > — > 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 >
Dan, I have a question about VMultiWriteReport in that example:
In that example you defer all reads until you get a write request. I am puzzled why?
Is that so you can report data as you receive it from the client otherwise queue up the reads since this is a virtual device (ie. not real physical device)?
If that is true, what if you get more reads then writes? Aren’t you going to be filling up the request queue faster without emptying it?
I am also not 100% sure about the HID class driver and when does it ask for input report when it is not using polling or is it?
Final question: I heard that you cannot send custom IOCTLs using DeviceIoControl to HID mini-drivers, is that true?
Correct, you cannot set an IOCTL to a HID mini driver. For a KMDF HID minidriver, you have two options
enumerate your own raw PDO from the HID mini driver. The io interface for this raw PDO does not have to be HID, it can whatever you want
or
create a custom top level collection that you look for in the HID minidriver and treat it “like IOCTLs”. This is by definition a HID io interface and is limiting, but can be simpler than 1)
If you are thinking of using a user mode app to call the user mode APIs to read from the device in user mode and then send that data down with a custom IOCTL, it will get complicated quickly. It is doable, but if you don’t like COM, I think you will feel this is worse once you get all of the corner cases ironed out
Dan, I have a question about VMultiWriteReport in that example:
In that example you defer all reads until you get a write request. I am puzzled why?
Is that so you can report data as you receive it from the client otherwise queue up the reads since this is a virtual device (ie. not real physical device)?
If that is true, what if you get more reads then writes? Aren’t you going to be filling up the request queue faster without emptying it?
I am also not 100% sure about the HID class driver and when does it ask for input report when it is not using polling or is it?
Final question: I heard that you cannot send custom IOCTLs using DeviceIoControl to HID mini-drivers, is that true?
Yeah thats right I forward the reads to a manual queue and then complete
them when I receive some new “device” data. I would do the same thing if it
was a physical device. Most of the time devices are sitting idle anyhow.
You should not get too many more reads then writes. Either the caller is
using blocking io in which case they will not send you a new read until you
complete the first, or they are using async io and they should take care
have a reasonable number of pending reads at one time (you dont just fire
off 1000 async reads to a file or socket right? Same for a device)… In my
experience the input service that is interested in mouse/keyboard/joystick
etc has about two pending reads at one time.
Also, the only two options you have really are to complete the read
(pointless if you dont have any data as they will just keep sending you more
requests one after another) or put it in a queue for later (which keeps the
request cancelable too).
Final question: I heard that you cannot send custom IOCTLs using
DeviceIoControl to HID mini-drivers, is that true?
See Dorons reply, I use option 2) (see the top level collection where the
report id = REPORTID_VENDOR_01)
On Wed, Jun 1, 2011 at 2:17 PM, wrote:
> Dan, I have a question about VMultiWriteReport in that example: > > In that example you defer all reads until you get a write request. I am > puzzled why? > Is that so you can report data as you receive it from the client otherwise > queue up the reads since this is a virtual device (ie. not real physical > device)? > If that is true, what if you get more reads then writes? Aren’t you going > to be filling up the request queue faster without emptying it? > I am also not 100% sure about the HID class driver and when does it ask for > input report when it is not using polling or is it? > Final question: I heard that you cannot send custom IOCTLs using > DeviceIoControl to HID mini-drivers, is that true? > > — > 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 >
Hidclass.sys is the one continuously sending the 2 reads. Hidclass then takes the data you complete and manages the read irp queue of anyone who has an open handle to the top level collection (ie either puts the data into a ring buffer or completes the client’s pended read)
d
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Daniel Newton
Sent: Tuesday, May 31, 2011 9:30 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Joy Driver for Direct Input
Yeah thats right I forward the reads to a manual queue and then complete them when I receive some new “device” data. I would do the same thing if it was a physical device. Most of the time devices are sitting idle anyhow.
You should not get too many more reads then writes. Either the caller is using blocking io in which case they will not send you a new read until you complete the first, or they are using async io and they should take care have a reasonable number of pending reads at one time (you dont just fire off 1000 async reads to a file or socket right? Same for a device)… In my experience the input service that is interested in mouse/keyboard/joystick etc has about two pending reads at one time.
Also, the only two options you have really are to complete the read (pointless if you dont have any data as they will just keep sending you more requests one after another) or put it in a queue for later (which keeps the request cancelable too).
Final question: I heard that you cannot send custom IOCTLs using DeviceIoControl to HID mini-drivers, is that true?
See Dorons reply, I use option 2) (see the top level collection where the report id = REPORTID_VENDOR_01)
On Wed, Jun 1, 2011 at 2:17 PM, > wrote: Dan, I have a question about VMultiWriteReport in that example:
In that example you defer all reads until you get a write request. I am puzzled why? Is that so you can report data as you receive it from the client otherwise queue up the reads since this is a virtual device (ie. not real physical device)? If that is true, what if you get more reads then writes? Aren’t you going to be filling up the request queue faster without emptying it? I am also not 100% sure about the HID class driver and when does it ask for input report when it is not using polling or is it? Final question: I heard that you cannot send custom IOCTLs using DeviceIoControl to HID mini-drivers, is that true?
I have noticed that hidclass will complete multiple clients reads with the
same data (i guess it has a ring buffer for each client)
On Wed, Jun 1, 2011 at 6:49 PM, Doron Holan wrote:
> Hidclass.sys is the one continuously sending the 2 reads. Hidclass then > takes the data you complete and manages the read irp queue of anyone who has > an open handle to the top level collection (ie either puts the data into a > ring buffer or completes the client?s pended read) > > > > d > > > > From:xxxxx@lists.osr.com [mailto: > xxxxx@lists.osr.com] *On Behalf Of *Daniel Newton > Sent: Tuesday, May 31, 2011 9:30 PM > > To: Windows System Software Devs Interest List > Subject: Re: [ntdev] Joy Driver for Direct Input > > > > Yeah thats right I forward the reads to a manual queue and then complete > them when I receive some new “device” data. I would do the same thing if it > was a physical device. Most of the time devices are sitting idle anyhow. > > You should not get too many more reads then writes. Either the caller is > using blocking io in which case they will not send you a new read until you > complete the first, or they are using async io and they should take care > have a reasonable number of pending reads at one time (you dont just fire > off 1000 async reads to a file or socket right? Same for a device)… In my > experience the input service that is interested in mouse/keyboard/joystick > etc has about two pending reads at one time. > > Also, the only two options you have really are to complete the read > (pointless if you dont have any data as they will just keep sending you more > requests one after another) or put it in a queue for later (which keeps the > request cancelable too). > > > > Final question: I heard that you cannot send custom IOCTLs using > DeviceIoControl to HID mini-drivers, is that true? > > See Dorons reply, I use option 2) (see the top level collection where the > report id = REPORTID_VENDOR_01) > > On Wed, Jun 1, 2011 at 2:17 PM, wrote: > > Dan, I have a question about VMultiWriteReport in that example: > > In that example you defer all reads until you get a write request. I am > puzzled why? > Is that so you can report data as you receive it from the client otherwise > queue up the reads since this is a virtual device (ie. not real physical > device)? > If that is true, what if you get more reads then writes? Aren’t you going > to be filling up the request queue faster without emptying it? > I am also not 100% sure about the HID class driver and when does it ask for > input report when it is not using polling or is it? > Final question: I heard that you cannot send custom IOCTLs using > DeviceIoControl to HID mini-drivers, is that true? > > > — > 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 >
Correct. Hidclass takes care of making sure each client of the TLC gets its own copy of the data (within reason)
d
From: xxxxx@lists.osr.com [xxxxx@lists.osr.com] on behalf of Daniel Newton [xxxxx@gmail.com]
Sent: Wednesday, June 01, 2011 1:54 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Joy Driver for Direct Input
Interesting,
I have noticed that hidclass will complete multiple clients reads with the same data (i guess it has a ring buffer for each client)
On Wed, Jun 1, 2011 at 6:49 PM, Doron Holan > wrote: Hidclass.sys is the one continuously sending the 2 reads. Hidclass then takes the data you complete and manages the read irp queue of anyone who has an open handle to the top level collection (ie either puts the data into a ring buffer or completes the client?s pended read)
To: Windows System Software Devs Interest List Subject: Re: [ntdev] Joy Driver for Direct Input
Yeah thats right I forward the reads to a manual queue and then complete them when I receive some new “device” data. I would do the same thing if it was a physical device. Most of the time devices are sitting idle anyhow.
You should not get too many more reads then writes. Either the caller is using blocking io in which case they will not send you a new read until you complete the first, or they are using async io and they should take care have a reasonable number of pending reads at one time (you dont just fire off 1000 async reads to a file or socket right? Same for a device)… In my experience the input service that is interested in mouse/keyboard/joystick etc has about two pending reads at one time.
Also, the only two options you have really are to complete the read (pointless if you dont have any data as they will just keep sending you more requests one after another) or put it in a queue for later (which keeps the request cancelable too).
> Final question: I heard that you cannot send custom IOCTLs using DeviceIoControl to HID mini-drivers, is that true?
See Dorons reply, I use option 2) (see the top level collection where the report id = REPORTID_VENDOR_01) On Wed, Jun 1, 2011 at 2:17 PM, > wrote: Dan, I have a question about VMultiWriteReport in that example:
In that example you defer all reads until you get a write request. I am puzzled why? Is that so you can report data as you receive it from the client otherwise queue up the reads since this is a virtual device (ie. not real physical device)? If that is true, what if you get more reads then writes? Aren’t you going to be filling up the request queue faster without emptying it? I am also not 100% sure about the HID class driver and when does it ask for input report when it is not using polling or is it? Final question: I heard that you cannot send custom IOCTLs using DeviceIoControl to HID mini-drivers, is that true?
Sorry guys one more question, what do you think of this (I am just trying tap into your knowledge not trying to avoid anything, just learning):
This is for virtual joystick (not a real device):
Write function driver that receives custom IOCTLs via DeviceIoControl and converts these to HID input reports. The only thing I am not certain is once I have the HID input report how would I pass that to the HID class driver explicitly as response to my custom IOCTL?
Enumerate your own raw PDO to get the custom IOCTLs. You can then process this data in the parent. You complete one of HIDClass’s always pending reads with the data (ie the reads that you shoved into the manual queue)
Sorry guys one more question, what do you think of this (I am just trying tap into your knowledge not trying to avoid anything, just learning):
This is for virtual joystick (not a real device):
Write function driver that receives custom IOCTLs via DeviceIoControl and converts these to HID input reports. The only thing I am not certain is once I have the HID input report how would I pass that to the HID class driver explicitly as response to my custom IOCTL?
It sounds like a great idea, I just want to clear up few things.
When you say PDO - the PDO is at the bottom of the device stack, correct?
Do I write a driver to create the PDO at the bottom of the device stack? Any examples I can take a look at for this?
Can I sent custom IOCTLs to the PDO by opening the device using CreateFile API call and calling DeviceIoControl?
A PDO is the root of any device stack. Your driver will be loaded on a PDO (assuming a root PDO since you are not talking to the usb hardware directly in the driver). Your driver can then enumerate a raw PDO as a child of your stack (open device manager, view by connection and each child in the tree is a PDO enumerated by the parent above it). Look at the kbfiltr example for how to enumerate a raw PDO. Yes, your app can then open the raw PDO via CreateFile
It sounds like a great idea, I just want to clear up few things.
When you say PDO - the PDO is at the bottom of the device stack, correct?
Do I write a driver to create the PDO at the bottom of the device stack? Any examples I can take a look at for this?
Can I sent custom IOCTLs to the PDO by opening the device using CreateFile API call and calling DeviceIoControl?
I have reviewed the kbfiltr example and I would like to ask about the RAW PDO:
The method, KbFiltr_CreateRawPdo, that creates the RAW PDO can be pretty much reused without changes but I can remove the following line: WdfDeviceInitAssignSDDLString (since my device is OK to be controlled by user app). Correct?
Do I really also need to provide a description about the device(RtlUnicodeStringPrintf/WdfPdoInitAddDeviceText)?
Also in that example you specify some PDOs caps (WDF_DEVICE_PNP_CAPABILITIES_INIT), can I just use defaults without specifying any?
I see a call to create device interface (WdfDeviceCreateDeviceInterface) using GUID, is that what I would use in CreateFile to open my PDO from user app?
I have reviewed the kbfiltr example and I would like to ask about the RAW PDO:
The method, KbFiltr_CreateRawPdo, that creates the RAW PDO can be pretty much reused without changes but I can remove the following line: WdfDeviceInitAssignSDDLString (since my device is OK to be controlled by user app). Correct?
Do I really also need to provide a description about the device(RtlUnicodeStringPrintf/WdfPdoInitAddDeviceText)?
Also in that example you specify some PDOs caps (WDF_DEVICE_PNP_CAPABILITIES_INIT), can I just use defaults without specifying any?
I see a call to create device interface (WdfDeviceCreateDeviceInterface) using GUID, is that what I would use in CreateFile to open my PDO from user app?
I have developed a virtual device device driver based on the above sample. Problem: When I use touchscreen and mouse simultaneously, touchscreen does not work. I need to disable touchscreen driver in device manager and then enable it again to make it work. If I use touch screen, wait for a second, then If i use a mouse will not cause problem. Touchscreen works properly. Any help or pointer would be highly appreciated, Thanks,
After creating the raw PDO using WdfDeviceCreate() is it OK if I just get rid off the call to WdfDeviceCreateDeviceInterface() but instead call WdfDeviceCreateSymbolicLink and use the symbolic name in my user app that will sent custom IOCTLs to my created raw PDO?
This way it is easier in my user app to get handle to the device. I am all about simplicity for this.