Virtual Keyboard Driver: Where to start?

Hello,

I’d like to write a virtual keyboard driver, but don’t know where to start.

The driver should create one virtual keyboard device (without correspondence to any physical one), kbdclass should attach to its device stack and it should be “plug-and-playable” (installation & uninstallation without restart).

Of course, I don’t want you to do the work for me, but if you could point me in the right direction, I’d be truly grateful.

Thanks.

I’m no driver expert, but since no one else answered I’ll give it a shot.
It seems to me that if you want to build a keyboard device that kbdclass
attaches to then you are going to need to write a virtual usb port driver to
use in place of the normal keyboard port driver (usbhid.sys) probably. You
write an INF file to detect your fake PNP ID and install a keyboard stack
for that device like keyboard.inf does for normal PS2 and USB keyboards
except with your port driver at the bottom.

I think there’s a sample in the version 6000 WDK in src\hid\vhidmini that
may be a good starting point to help you enumerate and simulate a basic
virtual USB device, but I don’t think that will get you anywhere near the
finish line. That helps with some basic usb protocol, but not keyboard
logic I think. You’d probably need to go to www.usb.org to get some
documentation to understand what packets your virtual keyboard should be
sending and how it should be responding to what it receives according to the
specification, then program all that logic into vhidmini. Instead of having
your device stack installed with hidusb.sys and kbdclass.sys on top of that
you would have vhidmini.sys with kbdclass.sys on top of it.

I think you may be in for a lot of work that you aren’t ready for if you
don’t really even have any idea where to begin.

I’d like to write a virtual keyboard driver, but don’t know where to
start.

The driver should create one virtual keyboard device (without
correspondence to any physical one), kbdclass should attach to its device
stack and it should be “plug-and-playable” (installation & uninstallation
without restart).

You had the right idea for the answer, but the details are not quite
right. HID is not USB. HID is a transport independent protocol (it
just describes how bytes are interpreted, not how they get to the PC).
You should probably write a hid miniport, vhidmini or better yet, the
KMDF HID miniport driver in the 6001 WDK are good places to start. You
don’t need to emulate usb at all, you just need to understand HID
descriptors and HID reports and how to format your data. Matt is
correct that you will need an INF and a cooked up hardware ID for the
HID device in the HID device class, not the keyboard device class. The
device stack looks like this

Kbclass
|
Kbdhid
|
HIDclass PDO
|
±–+
|
HIDclass+your hid minidriver
|
Root PDO

The bigger question you have to answer is how are you going to get the
data to feed into the virtual keyboard to report to the OS? As a HID
miniport, you cannot be opened directly by user mode. Your HID miniport
can open up other devices though and read from them. How you get your
data might change the design, so please let me know and I can point you
in the right direction

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Matthew Carter
Sent: Saturday, June 30, 2007 7:53 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Virtual Keyboard Driver: Where to start?

I’m no driver expert, but since no one else answered I’ll give it a
shot.
It seems to me that if you want to build a keyboard device that kbdclass

attaches to then you are going to need to write a virtual usb port
driver to
use in place of the normal keyboard port driver (usbhid.sys) probably.
You
write an INF file to detect your fake PNP ID and install a keyboard
stack
for that device like keyboard.inf does for normal PS2 and USB keyboards
except with your port driver at the bottom.

I think there’s a sample in the version 6000 WDK in src\hid\vhidmini
that
may be a good starting point to help you enumerate and simulate a basic
virtual USB device, but I don’t think that will get you anywhere near
the
finish line. That helps with some basic usb protocol, but not keyboard
logic I think. You’d probably need to go to www.usb.org to get some
documentation to understand what packets your virtual keyboard should be

sending and how it should be responding to what it receives according to
the
specification, then program all that logic into vhidmini. Instead of
having
your device stack installed with hidusb.sys and kbdclass.sys on top of
that
you would have vhidmini.sys with kbdclass.sys on top of it.

I think you may be in for a lot of work that you aren’t ready for if you

don’t really even have any idea where to begin.

I’d like to write a virtual keyboard driver, but don’t know where to
start.

The driver should create one virtual keyboard device (without
correspondence to any physical one), kbdclass should attach to its
device
stack and it should be “plug-and-playable” (installation &
uninstallation
without restart).


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

Thanks for your replies.

I have already taken a look at vhidmini, but wasn’t sure if this could be the right starting point.

The virtual device driver I want to write will not communicate with user-mode programs, it’s all going to be inter-driver communication.

I have had two other ideas, too:

  1. Create device object, open kbdclass DO, call its AddDevice routine pointing to my DO

  2. Create device object, register device interface with GUID_CLASS_KEYBOARD, directly talk to the Win32 subsystem

I like the second idea, but have yet to test its feasibility.

Doron Holan wrote:

The bigger question you have to answer is how are you going to get the
data to feed into the virtual keyboard to report to the OS?

The virtual keyboard device wouldn’t actually be fed with data itself.

It would only serve two purposes and otherwise stay idle:

  1. Receive IOCTL_INTERNAL_KEYBOARD_CONNECT from kbdclass and save (not replace) CONNECT_DATA
  2. Ensure that at least one keyboard is present

I was a bit mixed up in my understanding of kbdhid.sys, so my reply actually
was a mash of two methods of simulating a keyboard. One method consists of
creating a HID device like vhidmini and installing it as a device recognized
and controlled by the HID class. HID class gets your device identifier,
then Windows detects that device is plugged in and looks for a driver for
that identifier. It gets installed exactly like any HID keyboard (such as
USB) would with kbdclass.sys on top of kbdhid.sys. In this case I don’t
think you would have the address of the keyboard class service callback that
is sent to kbdhid.sys in an IOCTL_INTERNAL_KEYBOARD_CONNECT IRP, so when you
want to send input you would report it to hidclass in the normal way that
any HID device reports input it has received.

The other method consists of creating an entirely new functional device for
the keyboard class upper filter driver to sit upon. That device is
kbdhid.sys for HID devices or i8042prt.sys for PS2 devices, but it could be
anything you want it to be since it is installed in keyboard.inf in response
to the particular device identifier a device reports to the PnP manager. In
that case you would not use vhidmini. You could provide a legacy bus driver
that you can talk to with your application to tell it when to detect or
unplug of your PnP device. When the bus driver reports the device to
Windows then Windows will look for a driver for it. In this case you would
have your keyboard.inf install it as kbdclass.sys on top of your
fakekbd.sys. You would build a standard PnP function driver (perhaps
starting with something from the toaster sample) that would have to respond
to any requests that keyboard class filter normally sends down to a keyboard
function driver, including IOCTL_INTERNAL_KEYBOARD_CONNECT and you could
call the keyboard class service callback any time you have input you want to
send. I don’t know what other requests there are, but there are certainly
more than just IOCTL_INTERNAL_KEYBOARD_CONNECT because the system has to be
able to talk to the keyboard to do things like toggle caps lock, set the
keyboard’s reporting mode, etc.

Of these two I imagine the first is the easier for you to implement since a
lot of the work is going to be done already by vhidmini as far as the
detection of your fake device and even how to talk to your fake device is
concerned. There’s probably better documentation in the WDK about
interfacing with HID devices than there is for the interface between
kbdclass and the keyboard function driver as well.

Write the driver based on i8042 sample, and set the Class in the INF file
to Keyboard. This will do the job of loading KbdClass above you.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntdev…
> Hello,
>
> I’d like to write a virtual keyboard driver, but don’t know where to start.
>
> The driver should create one virtual keyboard device (without correspondence
to any physical one), kbdclass should attach to its device stack and it should
be “plug-and-playable” (installation & uninstallation without restart).
>
> Of course, I don’t want you to do the work for me, but if you could point me
in the right direction, I’d be truly grateful.
>
> Thanks.
>

Please don’t forgo kbdclass and talk to the RIT directly, kbdclass does
a lot of work for you and you should be able to write a keyboard port
driver very easily to accomplish 1 and 2. Writing a keboard port driver
is the way to go instead of a virtual HID miniport in this case if your
requirements are so simple.

Why do you need to guarantee a keyboard is present?

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@hushmail.com
Sent: Sunday, July 01, 2007 2:08 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Virtual Keyboard Driver: Where to start?

Doron Holan wrote:

The bigger question you have to answer is how are you going to get the
data to feed into the virtual keyboard to report to the OS?

The virtual keyboard device wouldn’t actually be fed with data itself.

It would only serve two purposes and otherwise stay idle:

  1. Receive IOCTL_INTERNAL_KEYBOARD_CONNECT from kbdclass and save (not
    replace) CONNECT_DATA
  2. Ensure that at least one keyboard is present

Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

Doron Holan wrote:

Why do you need to guarantee a keyboard is present?

I want to map mouse buttons to keyboard keys and therefore need to insert keystrokes.

If I use a keyboard filter to retrieve KeyboardClassServiceCallback, it will only work as long as at least one keyboard device is present.
(I know Windows * Professional has the virtual Terminal Server Keyboard)

Granted, it’s unlikely you will use a mouse, but no keyboard, but it’s still possible.