Ring Buffer

The HID class driver has a buffer for each device for input reports. This holds input reports until a client reads them. This is a 'ring buffer', so if the reports are not read quickly enough, new reports may overwrite the old reports (i.e., data may get lost).

A kernel mode client can get and set the ring buffer size using two IOCTLs.

Multiple Open Handles

In Windows 98, more than one program can access a single HID device at the same time. For example, if a HID keyboard is attached then a Windows kernel mode driver will be loaded to talk to it. This driver ensures that any key presses are routed into the normal keyboard driver. You can also open up another handle to the device object in the HID class driver that represents the HID keyboard. Therefore, in W98 at least, any input reports are received on all open handles.

However in Windows 2000, the HID keyboard driver opens a HID keyboard for exclusive access. Therefore the HidKbdUser user mode program and the HidKbd driver are unable to talk to the keyboard. I was able to develop this code in the Beta 2 version of W2000, when the keyboard was not opened for exclusive access.

Windows HID Clients

Windows 98 and Windows 2000 have built in support for various types of common HID device (e.g., keyboards, mice, game ports, audio controls, and the DirectInput system). The standard installation INF files load the required drivers automatically. If you plug in a HID USB keyboard, for example, the relevant system drivers are loaded and you should be able to start typing straightaway[56].

Figure 23.1 shows the Windows 2000 drivers that are loaded to service a 'legacy' keyboard and a HID USB keyboard. The situation is identical in Windows 98, apart from the driver filenames. For mouse input and game ports, the driver diagrams are almost identical. However, in Windows 2000, all the game port input is now done using HID with a HID joystick minidriver.

The Win32 subsystem still uses the standard keyboard driver, KbdClass.sys in W2000, to get all its keyboard input. This interrogates the 8042 legacy keyboard in the same way as NT 4 and earlier. However, the keyboard driver can also get its input from a HID keyboard. An intermediate driver, KbdHid.sys in W2000, is used. I assume that KbdHid.sys does all the hard work of interrogating the HID class driver, and it simply returns 8042 equivalent scan codes to the main keyboard driver.

The keyboard auto-repeat feature is not usually present in a HID keyboard. Either the KbdClass.sys or the KbdHid.sys driver must implement auto-repeat. Similarly, the Ctrl+Alt+Del key combination must be detected by one of these drivers. Quite correctly, it is not a feature of HID class driver.

I understand that KbdHid.sys driver always tries to keep two outstanding read requests for a keyboard: one to detect a key being depressed and one to detect a key being released. Combined with the HID class driver ring buffer, this technique should ensure that no key presses are lost.

In the future, it would be neater if Microsoft rearranged this keyboard driver layout. They would have to write a HID minidriver for the legacy 8042 port. All keyboard input would then come through the HID class driver. Although this approach might be slower, it should not matter for such a relatively slow device as a keyboard.

In addition, the figure shows that a user mode client can also access the HID keyboard as a HID device. It will receive regular HID input reports, as shown later. It will not receive 8042 equivalent scan codes. As I mentioned previously, all input reports are received by both KbdHid.sys and the user mode client.

Figure 23.1 Windows and a user mode client using a HID keyboard

Header Files

Table 23.1 shows the HID header files that you need to include. In the Windows 98 DDK, these files are in the srchidinc directory. In the Windows 2000 DDK, most headers are in the standard inc directory, while the others are in srcwdmhidinc.

Table 23.1 HID header files

hidсlass.h IOCTL codes
hidpddi.h Other parsing library routines
hidpi.h Parsing routines (i.e., HidP… functions and structures)
hidport.h Minidriver header
hidsdi.h User-mode HidD… functions
hidtoken.h Report descriptor item constants
hidusage.h Standard usage values
HID USB Minidriver

HID evolved from the USB specification, but is now a general purpose input device model. Nonetheless, HID fits neatly into the USB model. The HID class is one of the classes defined in the USB Specifications.

At present, the USB bus is one of the few places where HID devices can be found. The HID class driver talks to the USB device stack through the HidUsb.sys driver.

A HID USB device has the standard USB device, configuration, interface, and endpoint descriptors. In addition, it has the class-specific HID, Report, and Physical descriptors described in the previous chapter.

The standard USB device descriptor has zeroes for its class, subclass, and protocol. The standard interface descriptor has constant USB_DEVICE_CLASS_HUMAN_INTERFACE (0x03) in its bInterfaceClass field, iInterfaceSubClass is set to 1 if the device supports a boot protocol, described in the following text. In this case, bInterfaceProtocol is 1 for a keyboard and 2 for a mouse.

A USB request for the Configuration descriptor usually returns the HID descriptor before the endpoint descriptors[57]. The report and physical descriptors must be specifically asked for, using the following codes.

HID Descriptor HID_HID_DESCRIPTOR_TYPE 0x21
Report descriptor HID_REPORT_DESCRIPTOR_TYPE 0x22
Physical Descriptor HID_PHYSICAL_DESCRIPTOR_TYPE 0x23

A HID USB device uses the default control pipe endpoint 0 and one interrupt pipe. The control pipe is used for standard USB purposes and for sending and receiving reports, etc. The interrupt pipe is used to return new input reports.

USB HID devices support the notion of an idle rate. Whenever an interrupt request is received from the host, the USB HID device can either return a report or a NAK to indicate that nothing has changed. In the former case, no input state may have changed and so host processing of the report will waste time. The idle rate determines how often the HID USB device returns a report. If at any time during the idle rate period, an input report changes, the HID USB device does return an input report at the next interrupt. The recommended idle rate for keyboards is 500ms and infinity for

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату