This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
A version of this page is also available for
Windows Mobile Supported Windows Embedded CE Supported

Keyboard drivers are divided into components. This facilitates developing keyboard drivers for any keyboard layout. A keyboard layoutis the key arrangement used for a particular keyboard, including such factors as the number of keys and the configuration of the keys. Some proprietary keyboards use custom layouts, and many keyboards allow a user to map keys to characters according to personal preference.

For All Platforms

Some keyboard drivers must handle keys that generate multiple virtual keys. This is useful on smaller hardware platforms that do not have all of the physical keys normally present on keyboards used with desktop workstations. Some of the keys have multiple functions, modified functions, or both. The driver generates virtual keys based on the state of particular physical keys and modifier keys, such as SHIFT and ALT.

Generally, you should implement the keyboard driver as a layered driver. The upper layer, or model device driver (MDD), maps scan codes to virtual-key codes, generates character data associated with virtual-key codes, and then packages keyboard messages and puts them in a system-wide message queue. The lower layer, or platform-dependent driver (PDD), retrieves scan codes from hardware.

The following illustration shows a keyboard driver stack that is hardware-platform independent.

The keyboard driver is different from other device drivers because it is language dependent. The scan code to virtual-key code and virtual-key code to Unicode character translations are both dependent only on the keyboard layout for the language. The PFN_KEYBD_DRIVER_VKEY_TO_UNICODEfunction is responsible for generating the correct Unicode character based on the state of the virtual keys. This function is dependent only on the keyboard layout for the language. Both of these conversions are based on translation tables; also known as, keyboard mappings, which you can customize for different languages. You can create your own keyboard mappings or customize the existing keyboard mappings, if necessary.

The Graphics, Windowing, and Events Subsystem (GWES) loads the keyboard driver at boot time. When GWES starts, it retrieves the name of the keyboard driver dynamic-link library (DLL) from the HKEY_LOCAL_MACHINE\Hardware\DeviceMap\KEYBD\Drivernameregistry key. If no entry is found, GWES uses the default name, Keybddr.dll. It then loads the DLL and verifies that all required entry points exist. Then, GWES calls the PFN_KEYBD_DRIVER_INITIALIZEfunction to perform a one-time initialization. In this function, the driver saves a local copy of the GWES callback function and initializes the hardware and interrupt service thread (IST) to handle keyboard interrupts. When an interrupt is signaled, the keyboard driver is responsible for converting the hardware scan code into a virtual-key code and passing both to GWES through either the callback passed to PFN_KEYBD_DRIVER_INITIALIZE_EXor the keybd_eventAPI. Later, GWES pulls the keyboard event from the queue and calls back to the driver's PFN_KEYBD_DRIVER_VKEY_TO_UNICODEroutine. The driver analyzes the specified key event and the virtual-key state and generates the corresponding characters. GWES then sends the virtual-key code and the characters to the appropriate application. The keyboard driver must add the flags KEYBD_DEVICE_SILENT or KEYBD_DEVICE_SILENT_REPEAT to the virtual-key codes or pass KEYEVENTF_SILENT to keybd_eventin order to suppress audible key clicks.

The PFN_KEYBD_DRIVER_GET_INFOand PFN_KEYBD_DRIVER_SET_MODEfunctions get and set information about the keyboard. When the main input thread processes a keyboard-connection event through the callback function passed to PFN_KEYBD_DRIVER_INITIALIZE_EX, the thread calls the PFN_KEYBD_DRIVER_GET_INFOfunction to get the virtual-key code to Unicode data supplied by the driver. The thread also allocates the required memory for the virtual-key state data and any extra data required by the driver.

The PFN_KEYBD_DRIVER_INITIALIZE_EXand PFN_KEYBD_EVENT_CALLBACK_EXfunctions replace the non-Ex versions of these functions. The Ex functions provide support for Terminal Server Client by handling extra scan code information that the Terminal Server Protocol requires. The sample keyboard drivers on all hardware platforms use the Ex versions.

Required and Optional Keyboard Driver Functionality

Keyboard drivers must call keybd_eventto notify GWES of any keyboard activity.

The following list shows the optional keyboard driver functionality:

  • Updating keyboard drivers to work with Layout Manager. For more information, see Layout Manager.

  • Implementing MapVirtualKey ( uCode , 0)to enable Remote Desktop Protocol (RDP). MapVirtualKey( uCode , 0)must perform virtual key code to XT scan code conversions. For more information, see Remote Desktop Protocol Support.

  • Implementing MapVirtualKey( uCode , 3)to enable USB keyboards. MapVirtualKey( x , 3)must perform AT scan code to virtual key code conversions.

  • Enabling USB keyboard LEDs

For Windows Embedded CE, for more information, see Adding Keyboard LED Support to the HID Keyboard Driver.


It is recommended that the backlight driver does not forward softkey presses to the OS when the backlight is off.

For Windows Mobile


Device drivers that launch applications should use the State and Notifications Brokerto check the device lock state prior to launching applications that present a User Interfaceto the user. This action will prevent applications from coming up over the lock screen and potentially exposing sensitive information.

To check the locked state the following code may be used.

Copy Code
DWORD dwLockState = 0;
   //device is locked
   //device is key locked
   //device is SIM locked

The SN_LOCK_* values are defined in the snapi.h header file and the function RegistryGetDWORDis defined in the regext.h header file.

See Also