ULONG Descriptor type, ULONG Descriptor size | Read the specified descriptor into the given sized buffer | ||
Output | Received descriptor | ||
IOCTL_USBKBD_GET_STATUSES | Output | 6-byte buffer for status values | Read the device, first interface and first endpoint status values (16 bits each) |
IOCTL_USBKBD_GET_FRAME_INFO | Output | 12-byte buffer for frame information | Read the ULONG current frame length (in bits), the ULONG current frame number and the ULONG frame number for the next frame whose length can be altered |
For your USB client driver, you will use a standard installation INF file. In the Version section, make sure that you include the following lines.
Class=USB
ClassGUID={36FC9E60-C465-11CF-8056-444553540000}
As described in Chapter 11, your driver will be loaded if it has the right Hardware ID. A Hardware ID is constructed using the vendor and product IDs in the device descriptor (e.g., USB VID_046A&PID_0001).
However, for USB keyboards, this approach does not work. Windows 98 and Windows 2000 have built in support for USB keyboards. In both cases, they load the Human Input Device (HID) class drivers. The standard keyboard driver then gets key input through HID client drivers.
I tried fiddling with the USB keyboard installation INF files for Windows 98 and Windows 2000. However, I could not persuade Windows to load UsbKbd in place of the standard drivers. I can only assume that the standard driver names are hard-coded into the kernel and that the Windows INF files are not really used.
My brutal solution to this problem was to replace the HID USB minidriver HidUsb.sys with the UsbKbd.sys driver executable. Windows uses HidUsb.sys to process HID USB devices. Replacing HidUsb.sys seems to work. Needless to say, this approach stops you from using the USB keyboard for normal typing. In addition, it stops you from using any other USB HID devices. Therefore, you will need to have a standard PCBIOS keyboard connected to the system, as well. Do not forget to save a copy of the HidUsb.sys file (or delete it and reinstall it from the Windows CD). You need a dual-boot PC if you are going to change HidUsb.sys in W2000.
If you do not have a HID USB keyboard at hand, you obviously cannot run these tests. However, I show some of the
While developing the UsbKbd driver, I altered makefile.inc so that it copied the final executable, UsbKbd.sys, to overwrite HidUsb.sys. However, this command line has now been commented out, so you will have to do the copy yourself.
Trying out each new version of the UsbKbd driver was very easy. Simply unplugging and plugging in the USB cable caused the old driver to be unloaded and new one loaded. Windows 2000 displays a bugcheck on shutdown when HidUsb.sys is replaced by UsbKbd.sys. The simple solution is to unplug the USB keyboard before you shutdown.
The USB header files that you might need to include are in the DDK.
usb100.h | Various USB constants and structures |
usbioctl.h | IOCTL definitions |
usbdlib.h | URB building and assorted routines |
usbdi.h | USBDI routines, including URB structures |
These header files generate two annoying compiler warnings which you can ignore. I also found that I needed to specifically mention the USB library in the SOURCES file.
TARGETLIBS=C:NTDDKLIBI386FREEUsbd.Lib
USBDI IOCTLs
The USB class drivers are primarily used through the USB Device Interface (USBDI) Internal IOCTLs shown in Table 21.2. As these are Internal IOCTLs, they are only available to other parts of the kernel, such as device drivers, and are not available to user mode applications.
A few ordinary IOCTLs are also available to Win32 programs. These are intended for use by diagnostic utilities, so I shall not cover them here. The DDK
Table 21.2 USBDI internal IOCTLs
IOCTL_INTERNAL_USB_SUBMIT_URB | Submit URBBlock awaiting result |
IOCTL_INTERNAL_USB_RESET_PORT | Reset and reenable a port |
IOCTL_INTERNAL_USB_GET_PORT_STATUS | Get port status bits: USBD_PORT_ENABLED USBD_PORT_CONNECTED |
IOCTL_INTERNAL_USB_ENABLE_PORT | Reenable a disabled port |
IOCTL_INTERNAL_USB_GET_HUB_COUNT | Used internally by hub driver |
IOCTL_INTERNAL_USB_CYCLE_PORT | Simulates a device unplug and replug |