Windows HID Drivers Documentation PDF

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 156

Contents

HID drivers
HID drivers
What's New in HID
Introduction to HID Concepts
HID Architecture
HID Clients Supported in Windows
HID Transports Supported in Windows
HID Clients
HID Clients
HID Usages
HID Collections
HID Collections
Top-Level Collections
Top-Level Collections Opened by Windows for System Use
Preparsed Data
Link Collections
Collection Capability
Button Capability Arrays
Value Capability Arrays
Data Indices
Opening HID collections
Opening HID collections
Finding and Opening a HID Collection
HID client drivers
Enforcing a Secure Read For a HID Collection
Obtaining Preparsed Data
Obtaining Collection Information
Handling HID Reports
Handling HID Reports
Initializing HID Reports
Obtaining HID Reports
Sending HID Reports
Interpreting HID Reports
Troubleshooting HID Reports
Freeing Resources
Installing HID clients
HIDClass Hardware IDs for Top-Level Collections
Keyboard and mouse HID client drivers
Sensor HID class driver
Airplane mode radio management
Display brightness control
HID Transports
HID Transports
ACPI button device
HID button drivers
Virtual HID Framework (VHF)
Transport Minidrivers
Transport Minidrivers
Binding minidrivers to the HID class
Minidrivers and the HID class driver
Minidriver requirements for tablet PCs
HID over USB
HID over USB
Architecture of HID over USB
Plug and play support
Power management
Selective suspend for HID over USB devices
Resources for HID over USB
HID over I2C
HID over I2C
Architecture and overview
Plug and play support and power management
Power management for I²C transport
Troubleshooting common errors
Event tracing
Resources for HID over I2C
Non-HID legacy devices
Non-HID legacy devices
Keyboard and mouse class drivers
PS/2 (i8042prt) driver
3rd party filter drivers
OS Driver installation
OS Driver installation
INF DDInstall.MigrateToDevNode Section
INF SharedDriver Entry
INF PS2_Inst.NoInterruptInit.Bioses Section
INF PS2_Inst.NoInterruptInit Section
DirectInput
DirectInput
Joystick Support
Joystick Support
Joystick Driver Model
Minidriver-Supplied Callbacks
Original Interface
DirectX 5.0 Interface
Creating an INF File
Registry Settings
VJoyD Minidriver Override
Axis Selection
Force Feedback Device Driver Interface
Extending the DirectInput Game Controller Control Panel
Hdpi.h Macros
HID drivers
4/3/2019 • 2 minutes to read • Edit Online

This section introduces Human Interface Devices (or HID ). For more information about HID concepts, see the
official HID specification.

In this section
TOPIC DESCRIPTION

What's New in HID

Introduction to HID Concepts This section introduces Human Interface Devices (or HID).
Typically, these are devices that humans use to directly
control the operation of computer systems.

HID Architecture The architecture of the HID driver stack in Windows is


built on the class driver named hidclass.sys.

HID Clients Supported in Windows Windows supports the following top-level collections:

HID Transports Supported in Windows Windows supports the following transports.

HID Clients The HID Clients are drivers, services or applications that
communicate using the HID API and often represent a
specific type of device (for example: a sensor, a keyboard,
or a mouse). They identify the device via a hardware ID or
a specific HID Collection and communicate with the HID
Collection via HID API.

HID Transports Descriptions of HID transports supported in current and


previous versions of Windows.

Non-HID legacy devices This section describes drivers, transports, and filter-drivers
for non-HID keyboards and mice. These devices primarily
run on the PS/2 transport.
What's New in HID
12/5/2018 • 2 minutes to read • Edit Online

This topic summarizes the new features and improvements for Human Interface Devices (HID ) in Windows 10.

HID WinRT API


The Windows.Devices.HumanInterfaceDevice API lets a UWP app access devices that support the Human
Interface Device (HID ) protocol.
The following short video describes an end-to-end sample solution for HID that's available for download on the
MSDN samples gallery. (This solution includes a sample app created using the new HID WinRT API.)

Design Guide
The Design Guide has been updated to include some new topics. And also, existing content has been revised where
relevant, to show improved HID support in Windows 10. Here are some of the new, and updated topics:
New topic
ACPI button device
Updated topics
HID Transports
HID button drivers
HID Clients Supported in Windows

HID Over I²C


The HID protocol originally targeted human interface devices like: keyboards, mice, and joysticks. It was originally
developed to run over USB. For Windows 8, Microsoft created a new HID miniport driver that allows devices to
communicate over an Inter-Integrated Circuit (I²C ) bus.

Related topics
Design Guide
HID Over I2C
Introduction to HID Concepts
12/5/2018 • 4 minutes to read • Edit Online

This section introduces Human Interface Devices (or HID ). Typically, these are devices that humans use to directly
control the operation of computer systems.

History of HID
The definition of HID started as a device class over USB. The goal at that time was to define a replacement to PS/2
and create an interface over USB, allowing the creation of a generic driver for HID devices like keyboards, mice,
and game controllers. Prior to HID, devices had to conform to strictly defined protocols for mice and keyboards.
All hardware innovations necessitated overloading the use of data in an existing protocol, or the creation of non-
standard hardware that needed its own drivers. The vision of HID started with finding a way for providing basic
support for these “boot mode” devices in the operating system, but still allowing hardware vendors to provide
differentiation with extensible, standardized and easily programmable interfaces.
Today, HID devices include: alphanumeric displays, barcode readers, volume controls on speakers/headsets,
auxiliary displays, sensors, and MRI’s (yes, in hospitals). In addition, many hardware vendors use HID for their
proprietary devices.
HID started over USB but was designed in a bus agnostic fashion from the very beginning. It was originally
designed for low latency, low bandwidth devices but is flexible, and the rate is specified by the underlying
transport. The specification for HID over USB was ratified in the late 1990s, and support over additional
transports started soon after that. Today, HID has a standard protocol over multiple transports, and the following
transports are supported natively in Windows 8 for HID:
USB
Bluetooth
Bluetooth LE
I²C
Vendor specific transports are also allowed via 3rd party vendor-specific transport drivers. More details will be
provided in later sections.

HID Concepts
HID is built on a couple of fundamental concepts, a Report Descriptor, and reports. Reports are the actual data
blobs that are exchanged between a device and a software client. The Report Descriptor describes the format and
meaning of each data blob that it supports.
Reports
When applications and HID devices exchange data, this is done through Reports. There are three report types:
Input Reports, Output Reports, and Feature Reports.

REPORT TYPE DESCRIPTION

Input Report Data blobs that are sent from the HID device to the
application, typically when the state of a control changes.
REPORT TYPE DESCRIPTION

Output Report Data blobs that are sent from the application to the HID
device, for example to the LEDs on a keyboard.

Feature Report Data blobs that can be manually read and/or written, and are
typically related to configuration information.

Each Top Level Collection defined in a Report Descriptor can contain zero (0) or more reports of each type.
Usage Tables
The HID working group publishes a set of documents that make up the HID Usage Tables. This is effectively the
dictionary that describes what HID devices are allowed to do. These HID Usage Tables contain a list with
descriptions of the Usages. A Usage provides information to an application developer about the intended meaning
and use of a particular item described in the Report Descriptor. For example, there is a Usage defined for the left
button of a mouse. The Report Descriptor can define where in a report an application can find the current state of
the mouse’s left button. The Usage Tables are broken up into several name spaces, called Usage Pages. Each
Usage Page describes a set of related Usages to help organize the document. The combination of a Usage Page
and Usage defines the Usage ID that uniquely identifies a specific Usage in the Usage Tables.

The HID Application Programming Interface (API)


There are three categories of HID APIs: device discovery and setup, data movement, and report
creation/interpretation.
Device Discovery and Setup
The following list identifies the HID API that an application can use to: identify the properties of a HID device, and
to establish communication with that device. In addition, an application can use some of these API to identify a Top
Level Collection.
HidD_GetAttributes
HidD_GetHidGuid
HidD_GetIndexedString
HidD_GetManufacturerString
HidD_GetPhysicalDescriptor
HidD_GetPreparsedData
HidD_GetProductString
HidD_GetSerialNumberString
HidD_GetNumInputBuffers
HidD_SetNumInputBuffers
Data Movement
The following list identifies the HID API that an application can use to move data back and forth between the app
and a selected device.
HidD_GetInputReport
HidD_SetFeature
HidD_SetOutputReport
ReadFile
WriteFile
Report Creation and Interpretation
If you are writing a HID app for your own hardware, you have existing knowledge of the size and format of each
report issued by your device. In this case, your app can cast the input and output report buffers to structs and
consume the data.
If, however, you are writing a HID app that communicates with all devices that expose common functionality (for
example, a music app that needs to detect when a play button is pressed), you may not know the size and format
of the HID reports. This category of application understands certain Top Level Collections and certain usages.
In order to interpret the reports received from a device, or to create reports to be sent, the application needs to
leverage the Report Descriptor in order to determine if and where a particular usage is located in the reports, and
(potentially) the units of values in the reports. This is where HID parsing is required. Windows provides a HID
parser for use by drivers and applications. This parser exposes a set of APIs (HidP_*) that can be used to discover
the types of usages supported by a device, determine the state of such usages in a report, or to build a report to
change the state of a usage in the device.
The following list identifies the HID parser APIs.
HidP_GetButtonCaps
HidP_GetButtons
HidP_GetButtonsEx
HidP_GetCaps
HidP_GetData
HidP_GetExtendedAttributes
HidP_GetLinkCollectionNodes
HidP_GetScaledUsageValue
HidP_GetSpecificButtonCaps
HidP_GetSpecificValueCaps
HidP_GetUsages
HidP_GetUsagesEx
HidP_GetUsageValue
HidP_GetUsageValueArray
HidP_GetValueCaps
HidP_InitializeReportForID
HidP_IsSameUsageAndPage
HidP_MaxDataListLength
HidP_MaxUsageListLength
HidP_SetButtons
HidP_SetData
HidP_SetScaledUsageValue
HidP_SetUsages
HidP_SetUsageValue
HidP_SetUsageValueArray
HidP_UnsetButtons
HidP_UnsetUsages
HidP_UsageAndPageListDifference
HidP_UsageListDifference
HID Architecture
12/5/2018 • 2 minutes to read • Edit Online

The architecture of the HID driver stack in Windows is built on the class driver named hidclass.sys. Clients and
transport minidrivers access the class driver from user-mode or kernel-mode.

The HID Class Driver


The system-supplied HID class driver is the WDM function driver and bus driver for the HID device setup class
(HIDClass). The executable component of the HID class driver is hidclass.sys. The HID Class driver is the glue
between HID clients and various transports. This allows a HID Client to be written in an independent way from
transports. This level of abstraction allows clients to continue to work (with little to no modifications) when a new
standard, or a 3rd party transport is introduced.
The following is an architectural representation.

The preceding diagram includes the following:


HID Clients – Identifies the Windows and 3rd party clients and their interfaces.
HID Class driver - The hidclass.sys executable.
HID Transport Minidriver - Identifies the Windows and 3rd party transports and their interfaces.
Here is the device stack diagram of a generic HID client and transport.
Here is another device stack diagram showing HID keyboard and mouse collections over USB.

HID Clients
The HID Clients are drivers, services or applications that communicate with HIDClass.sys and often represent a
specific type of device (E.g. sensor, keyboard, mouse, etc). They identify the device via a hardware ID or a specific
HID Collection and communicate with the HID Collection via the following guidance.
User-mode drivers and applications, and kernel-mode drivers, do the following to operate HID collections:
User-mode drivers and applications use HIDClass support routines (HidD_Xxx) to obtain information about a
HID collection.
Kernel-mode drivers, user-mode drivers and applications use HID parsing support routines (HidP_Xxx), and
kernel-mode drivers use HID class driver IOCTLs to handle HID reports.
The following table is a simplification of the information listed above.

DRIVERS APPLICATIONS

User Mode HidD_Xxx HidP_Xxx

Kernel Mode HidD_Xxx OR IOCTL_HID_xxx N/A

For more information, see Opening HID collections.


For a list of all supported HID Clients, see HID Clients Supported in Windows.

The HID Transport Driver


The HID class driver is designed to use HID minidrivers to access a hardware input device. A HID minidriver
abstracts the device-specific operation of the input devices that it supports. The HID minidriver binds its operation
to the HID class driver by registering with the HID class driver. The HID class driver communicates with a HID
minidriver by calling the minidriver's support routines. The HID minidriver, in turn, sends communications down
the driver stack to an underlying bus or port driver.
For a list of the HID Transports provided in Windows, see HID Transports Supported in Windows.
HID Clients Supported in Windows
12/5/2018 • 2 minutes to read • Edit Online

Windows supports the following top-level collections:

USAGE PAGE USAGE WINDOWS 7 WINDOWS 8 WINDOWS 10 NOTES ACCESS MODE

0x0001 0x0001 - Yes Yes Yes Mouse class Exclusive


0x0002 driver and
mapper driver

0x0001 0x0004 - Yes Yes Yes Game Shared


0x0005 Controllers

0x0001 0x0006 - Yes Yes Yes Keyboard / Exclusive


0x0007 Keypad class
driver and
mapper driver

0x0001 0x000C No Yes Yes Flight Mode Shared


Switch

0x0001 0x0080 Yes Yes Yes System Shared


Controls
(Power)

0x000C 0x0001 Yes Yes Yes(For both Consumer Shared(For


Windows 10 Controls both Windows
and Windows 10 and
10 Mobile) Windows 10
Mobile)

0x000D 0x0001 Yes Yes Yes External Pen Exclusive


Device

0x000D 0x0002 Yes Yes Yes Integrated Exclusive


Pen Device

0x000D 0x0004 Yes Yes Yes Touchscreen Exclusive

0x000D 0x0005 No Yes Yes Precision Exclusive


Touchpad
(PTP)

0x0020 *Multiple No Yes Yes Sensors Shared

0x0084 0x004 Yes Yes Yes HID UPS Shared


Battery

0x008C 0x0002 No Yes(Windows Yes Barcode Shared


8.1 and later) Scanner
(hidscanner.dll
)
In the preceding table, the access mode for input HID clients is Exclusive to prevent other HID clients from
intercepting or receiving global input state when they are not the target recipient of that input. Therefore, for
security reasons RIM (Raw Input Manager) opens all such devices exclusively.
Sharing mode allows multiple applications to access the device. For example, multiple applications can access a
barcode scanner to inquire about device capabilities and retrieve statistics. However, retrieving decoded data from
a barcode scanner is done in Exclusive mode. Usages are defined by the USB HID POS Scanner standard
specification.
*Multiple: Sensors usages from 0x00 – 0xFF are segmented for different purposes. For example 0x10 indicates a
Biometric sensor; 0x40 indicates a Light sensor. Those allocations are not contiguous. For the list of sensor usages,
see Review Request 39:HID Usage Table Sensor Page. For information about sensors usages that are supported in
Windows, HID Sensors Usages.
HID Transports Supported in Windows
12/5/2018 • 2 minutes to read • Edit Online

Windows supports the following transports.

TRANSPORT WINDOWS 7 WINDOWS 8 NOTES

USB Yes Yes Support for USB HID 1.11+


is provided on Windows
operating systems dating
back to Windows 2000.

Bluetooth Yes Yes Support for Bluetooth HID


1.1+ is provided on
Windows operating systems
dating back to Windows
Vista.

Bluetooth LE No Yes Windows 8 introduces


support for HID over
Bluetooth LE.

I2C No Yes Windows 8 introduces


support for HID over I2C

Previous versions of Windows (prior to Windows 7) also included support for the following.
HidGame.sys - HID minidriver for game port (I/O port 201) devices. The HID class driver creates a functional
device object (FDO ) for a game port device, and creates a physical device object (PDO ) for each HID collection
that the game port device supports.
Gameenum.sys – The gameport bus driver. The game port bus driver creates a PDO for each game port device
that is daisy-chained to a game port.
They are now considered legacy as the hardware is not found on modern machines (replaced by USB and other
modern transports).

Recommended transports for keyboards, mice, and touchpads


The following table shows the recommended transports for keyboards, mice, and touchpad devices on portable
(such as laptops and slates) and non-portable systems (such as all-in-one and desktops).

SYSTEM TYPE PORTABLE NON-PORTABLE

Legacy systems Internal: PS/2, External: USB, Bluetooth Internal: N/A, External: USB, Bluetooth

System on Chip (SoC) systems Internal: I2C, External: USB, Bluetooth Internal: I2C, USB External: USB,
Bluetooth

USB Generic HID Test in the Windows Hardware Lab Kit (HLK) covers HidUsb and HidClass drivers. There is no
HLK test for third-party HID mini drivers.
HID Clients
12/5/2018 • 2 minutes to read • Edit Online

The HID Clients are drivers, services or applications that communicate using the HID API and often represent a
specific type of device (for example: a sensor, a keyboard, or a mouse). They identify the device via a hardware ID
or a specific HID Collection and communicate with the HID Collection via HID API.

In this section
TOPIC DESCRIPTION

HID Usages HID usages identify the intended use of HID controls and
what the controls actually measure.

HID Collections A HID collection is a meaningful grouping of HID controls


and their respective HID usages.

Opening HID collections This section describes how a HID Client can communicate
with the HID Class driver (HIDClass) to operate the
device’s HID collections.

Handling HID Reports This section describes the mechanisms that user-mode
applications and kernel-mode drivers use for handling HID
reports.

Freeing Resources User-mode applications and kernel-mode drivers that are


HID clients should always free any resources that are no
longer required.

Installing HID clients This section describes the following requirements for
installing HIDClass devices in Microsoft Windows.

HIDClass Hardware IDs for Top-Level Collections This section specifies the hardware IDs that the HID class
driver generates for top-level collections.

Keyboard and mouse HID client drivers This topic discusses keyboard and mouse HID client
drivers. Keyboards and mice represent the first set of HID
clients that were standardized in the HID Usage tables
and implemented in Windows operating systems.

Sensor HID class driver Starting with Windows 8, the Windows operating system
includes an in-box sensor HID Class driver
(SensorsHIDClassDriver.dll), that supports eleven types of
sensors that communicate using the HID transport.
TOPIC DESCRIPTION

Airplane mode radio management Starting with Windows 8, the Windows operating system
provides support via HID, for airplane mode radio
management controls.

Display brightness control Starting with Windows 8, a standardized solution has


been added to allow keyboards (external or embedded on
laptops), to control a laptop’s or tablet’s screen brightness
through HID.
HID Usages
12/5/2018 • 2 minutes to read • Edit Online

HID usages identify the intended use of HID controls and what the controls actually measure.
The following concepts and terminology are used throughout the HID documentation in the WDK:
Usage Page
Usage ID
Extended Usage
Usage Range
Aliased Usages
For specific examples of usages that Windows components access, see Top-Level Collections Opened by
Windows for System Use.
For more information about how to determine the usages that a HIDClass device supports, see:
Collection Capability
Button Capability Arrays
Value Capability Arrays
Interpreting HID Reports
For detailed information about industry standard HID usage, see the Universal Serial Bus (USB ) specification
HID Usage Tables that is located at the USB Implementers Forum website. (This resource may not be available in
some languages and countries.)
Usage Page
HID usages are organized into usage pages of related controls. A specific control usage is defined by its usage
page, a usage ID, a name, and a description. Examples of usage pages include Generic Desktop Controls, Game
Controls, LEDs, Button, and so on. Examples of controls that are listed on the Generic Desktop Controls usage
page include pointers, mouse and keyboard devices, joysticks, and so on. A usage page value is a 16-bit unsigned
value.
Usage ID
In the context of a usage page, a valid usage identifier, or usage ID, indicates a usage in a usage page. A usage ID
of zero is reserved. A usage ID value is an unsigned 16-bit value.
Extended Usage
An extended usage is a 32-bit value that specifies a 16-bit usage page value in the most-significant two bytes
and a 16-bit usage ID in the least significant two bytes of the extended usage value.
Usage Range
A usage range is an inclusive, consecutive range of usage IDs, all of which are on the same usage page. A usage
range is specified by usage minimum and usage maximum items in a report descriptor.
Aliased Usages
More than one usage can be specified for a link collection or a HID control. For a given collection or control, a
group of such usages are aliases of one another, and are referred to as aliased usages. Delimiter items are used
to specify aliased usages. Usage ranges cannot be aliased.
For information about how aliased usages are specified in a top-level collection's capability arrays, see Button
Capability Arrays and Value Capability Arrays.
HID Collections
12/5/2018 • 2 minutes to read • Edit Online

A HID collection is a meaningful grouping of HID controls and their respective HID usages.
Controls should be grouped together if they are logically related or are functionally dependent on one another.
For instance, a SHIFT key and a letter key on a keyboard should not belong to separate collections. Collections
can have nested subcollections, also referred to as link collections. Report descriptors define one or more top-level
collections, and the report items, associated with each collection, define one or more HID reports.
Windows extends the concept of a HID collection to include the following:
Top-level collections
Top-level collections opened by Windows for system use
Preparsed data
Link collections
Collection capability
Button capability arrays
Value capability arrays
Data indices
Top-Level Collections
1/11/2019 • 2 minutes to read • Edit Online

A Top Level Collection is a grouping of functionality that targets a particular software consumer (or type of
consumer) of the functionality. For example, a Top Level Collection may be described as Keyboard, Mouse,
Consumer Control, Sensor, Display, etc. In the HID spec, these Top Level Collections are also referred to as
Application Collections. The HID device describes the purpose of each Top Level Collection, in order to allow the
consumers of HID functionality to identify Top Level Collections in which they might be interested. In Windows,
the HID device setup class (HIDClass) generates a unique physical device object (PDO ) for each Top Level
Collection described by the Report Descriptor. Microsoft defines a top -level collection as a HID collection that is
not nested within another collection. An unnested collection is always a top-level collection, regardless of its HID
type. In particular, a top-level collection does not have to be an Application collection, as defined by the USB
HID Standard.
A report descriptor can include more than one top-level collection. The HID class driver enumerates the top-level
collections of an input device and creates a physical device object (PDO ) for each top-level collection. User-mode
applications or kernel-mode drivers can access a top-level collection by opening its PDO and using the HIDClass
support routines and the HID class driver IOCTLs.
The internal structure and capability of a top-level collection is described by the following:
A HIDP_CAPS structure summarizes a top-level collection's capability.
Link collections describe the organization of the nested subcollections contained within a top-level
collection.
Button capability arrays and value capability arrays describe the capability of the controls supported by the
top-level collection.
Top-Level Collections Opened by Windows for
System Use
12/5/2018 • 2 minutes to read • Edit Online

Windows opens the following top-level collections for system use:

DEVICE TYPE USAGE PAGE USAGE ID WINDOWS CLIENT ACCESS MODE

Pointer 0x01 0x01 Win32 subsystem Exclusive

Mouse 0x01 0x02 Win32 subsystem Exclusive

Joystick 0x01 0x04 DirectInput Shared

Game pad 0x01 0x05 DirectInput Shared

Keyboard 0x01 0x06 Win32 subsystem Exclusive

Keypad 0x01 0x07 Win32 subsystem Exclusive

System Control 0x01 0x80 Win32 subsystem Shared

Consumer Audio 0x0C 0x01 hidserv.exe in Shared


Control Windows 2000
and hidserv.dll
(one of the SVC
host services) in
Microsoft
Windows XP
Preparsed Data
12/5/2018 • 2 minutes to read • Edit Online

Preparsed data is report descriptor data associated with a top-level collection. User-mode applications or kernel-
mode drivers use preparsed data to extract information about specific HID controls without having to obtain and
interpret a device's entire report descriptor. A user-mode application obtains a collection's preparsed data by using
HidD_GetPreparsedData and a kernel-mode driver uses an IOCTL_HID_GET_COLLECTION_DESCRIPTOR
request.
The following HIDClass support routines support extracting and setting button and value data:
HidP_GetButtons
HidP_SetButtons
HidP_UnsetButtons
HidP_GetUsageValue
HidP_SetUsageValue
HidP_GetScaledUsageValue
HidP_SetScaledUsageValue
HidP_GetUsageValueArray
HidP_SetUsageValueArray
Link Collections
12/5/2018 • 3 minutes to read • Edit Online

A link collection as a nested subcollection within a top-level collection. A top-level collection can have zero or
more link collections.
HidP_GetLinkCollectionNodes returns a top-level collection's link collection array that contains information
about a top-level collection's link collections.
Link Collection Array
A link collection array describes all the link collections contained within a top-level collection. Each link collection
is represented by a HIDP_LINK_COLLECTION_NODE structure. The array's link nodes are linked in a manner
that identifies their sequential and hierarchical order within a top-level collection. The first element of a link
collection array represents a top-level collection and the remaining members represent the top-level collection's
link collections.
By tracing through the nodes in the link connection array, a user-mode application or kernel-mode driver can
determine the organization and usage of all the link collections in a top-level collection. In addition, the
application or driver can organize controls by their link collection. This is possible because a top-level collection's
button capability arrays and value capability arrays identify the link collection that contains each HID usage
described by the capability arrays.
The following figure shows an example of a top-level collection that contains four link collections.

As indicated in the previous figure, link collections are linked together in a top-to-bottom and left-to-right order
(ABCD ). The following table indicates, for each link collection in the example, the links between the top-level
collection and its link collections.

LINK NODE PARENT CHILDREN FIRST CHILD NEX T SIBLING

A Top-level B, C B None
Collection

B A D D C

C A None None None

D B None None None


In a link collection array, the following definitions hold:
Parent
A link collection's parent is the collection immediately above it in the top-to-bottom hierarchy of collections. Link
collections have one parent. The Parent member of a link node specifies the index of its parent in the link
collection array.
Children
A link collection is a child of its parent. A parent can have zero or more children. The NumberOfChildren
member of a link node specifies the number of children that a parent has.
Sibling
A parent's children are siblings.
Next Sibling
Siblings are ordered left-to-right. A sibling's next sibling is the sibling immediately to its right, if any, in a set of
siblings. The NextSibling member of a link collection node specifies the index to its next sibling in the link
collection array. If a link collection node does not have a next sibling, NextSibling is set to zero.
First Child
The first child is the left-most sibling in a set of siblings. The FirstChild member of a link collection node specifies
the index to its first child in the link collection array. If a link collection node has no children, FirstChild is set to
zero.
An application or driver can determine all a parent collection's children by, starting with the parent's first child,
sequencing through the siblings of the first child until the NextSibling member of a sibling node is zero.
The following code shows how to use a link collection node index to find the first child of link collection seven:

HIDP_LINK_COLLECTION_NODE Collection[10] ;
HIDP_LINK_COLLECTION_NODE Node1 ;

Node1 = Collection[Collection[7].FirstChild]] ;

Aliased Collections
Delimiter items can be used in a report descriptor to delimit a set of aliased collections. Each aliased collection is
represented by an aliased link collection node. A complete and unique set of n, n >=2, aliased nodes is linked
together in the following way:
The aliased nodes are in consecutive order in the link collection array.
The first n-1 nodes have their IsAlias member set to TRUE. The nth node immediately following such a
sequence has its IsAlias member set to FALSE. This node terminates the sequence of aliased nodes. The
usage associated with this node is the preferred usage.
An application or driver can determine which collections are aliased by repeatedly incrementing the array index of
a link collection array to find such sequences.
Button capability arrays and value capability arrays identify, for each usage they describe, the link collection that
contains the usage. If a link collection is aliased, the capability arrays specify the preferred usage.
Collection Capability
12/5/2018 • 2 minutes to read • Edit Online

The capability of a collection is defined by its usage, reports, link collections, and controls. To obtain a summary of
a collection's capability, a user-mode application or kernel-mode driver calls HidP_GetCaps to obtain a
HIDP_CAPS structure. This structure contains the following information about a collection's link collections,
button capability arrays, and value capability arrays:
The collection's usage page and usage ID
The size, in bytes, of the collection's input, output, and feature reports (see Introduction to HID Concepts)
The number of HIDP_LINK_COLLECTION_NODE structures in the collection's link collection array
For each report type, the number of HIDP_BUTTON_CAPS structures in the button capability array
returned by HidP_GetButtonCaps
For each report type, the number of HIDP_VALUE_CAPSstructures in the value capability array returned
by HidP_GetValueCaps
For each report type, the number of buttons and values supported by the collection, as specified by the
NumberXxxDataIndices member.
Button Capability Arrays
12/5/2018 • 3 minutes to read • Edit Online

A button capability array contains information about the button usages supported by a top-level collection for a
specific type of HID report. Information about a collection's capability is contained in its HIDP_CAPS structure.
A user-mode application or kernel-mode driver uses one of the following HIDClass support routines to obtain
button capability information:
HidP_GetButtonCaps returns a button capability array describing all the button usages contained in a
specified report type.
HidP_GetSpecificButtonCaps filters the button capability information it returns by a caller-specified
usage page, usage ID, and link collection.
A button capability array contains HIDP_BUTTON_CAPS structures, each one of which contains the following
information about a HID usage or usage range:
The usage page for the usage or usage range
The report ID of the report that contains the button data
The usage ID or usage range
A flag that indicates whether a usage is an aliased usage
The link collection that contains the usage or usage range
The string descriptors and designators associated with the usage or usage range (see Designator Index
item and String Index item)
The data indices that the HID parser assigned to the usage or usage range
In general, the following conditions hold for all the usages described by a button capability array:
Each capability structure represents a single usage or usage range that is associated with a variable main
item or an array main item.
Aliased usages can be used with a variable main item. A usage that is associated with an array item cannot
be aliased. A usage range cannot be aliased.
The HID parser uses only the minimum required number of usages to assign a usage to each button. The
parser assigns usages in the order in which they are specified in a report descriptor. Usages in a report
descriptor that are not required, are discarded. The button capability array does not contain any
information about discarded usages.
If the number of usages specified for a variable item is less than the number of buttons in the item, the
capability array contains only one capability structure that describes one button usage (the last usage
specified in the report descriptor for the variable main item). However, see Usage Value Array for
information about usage values that have a report count greater than one.
The HID parser assigns a unique data index to each usage described in the capability array.
The following topics discuss how the capability structures are organized and set in a button capability array:
Button Usages in a Variable Main Item
Button Usages in an Array Main Item
Button Usages in a Variable Main Item
Each usage or usage range that is specified in a report descriptor is described by its own capability structure in a
button capability array.
The IsAlias member of capability structures is used to specify a set of n aliased usages as follows:
IsAlias is set to TRUE in the first n-1 capability structures added to the capability array. IsAlias set to FALSE
in the nth capability structure. The preferred usage is the last aliased usage in the sequence.
An application or driver can determine which button usages are aliased by scanning for such sequences.
The following table summarizes an example for three aliased usages.

ALIASED USAGE ORDER IN A REPORT


DESCRIPTOR USAGE ORDER IN A CAPABILITY ARRAY ISALIAS MEMBER VALUE

usage 1 usage 3 TRUE

usage 2 usage 2 TRUE

usage 3 usage 1 FALSE

For information about how usages and data indices are cross-referenced, see Data Indices.
Button Usages in an Array Main Item
Each usage or usage range for a button array main item specified in a report descriptor is described by its own
capability structure in a button capability array. The order in which the capability structures are added to a
capability array is the reverse of the order in which the usages are specified for a main item.
The HID parser assigns a data index to each usage associated with the array item in the order in which the
usages are specified in a report descriptor. For example, the following table shows the correspondence between a
set of usages, as specified in a report descriptor, and the usages and data indices, as specified in the capability
array. (In this table, n is the first data index that the parser assigns to the first usage associated with the array
item.)

DATAINDEX OR FROM DATAINDEXMIN TO


USAGE ORDER IN REPORT DESCRIPTOR USAGE ORDER IN CAPABILITY ARRAY DATATINDEXMAX

usage 1 usage range 2 from n+7 to n+8

usage range 1 (with 4 usages) usage 2 n+5

usage 2 usage range 1 from n+1 to n+4

usage range 2 (with 2 usages) usage 1 n


Value Capability Arrays
12/5/2018 • 2 minutes to read • Edit Online

A value capability array contains information about the value usages supported by a top-level collection for a
specific type of HID report. Information about a collection's value capability arrays is contained in its
HIDP_CAPS structure.
A user-mode application or kernel-mode driver uses one of the following HIDClass support routines to obtain
button capability information:
HidP_GetValueCaps returns a value capability array describing all the values that are contained in a
caller-specified report type.
HidP_GetSpecificValueCaps filters the value capability information it returns by a caller-specified usage
page, usage, link collection, and report type.
A value capability array contains HIDP_VALUE_CAPS structures, each one of which describes the following
information about a HID usage or usage range:
The usage page for a usage or usage range
The report ID of the report that contains the value
A usage ID or a usage range
Indicates whether a usage is an aliased usage
Information about the link collection that contains the usage or usage range
The size, in bits, of a value, and the report count (which is the number of individual values described by the
structure)
Attributes of each value, including: whether it has a null value, its units and exponent, and its logical and
physical ranges
Information about string descriptors and designators associated with the usage or usage range
Information about the data indices that the HID parser assigns a usage or usage range
In general, the following conditions hold for all the usages described by a value capability array:
Each capability structure represents a usage, a usage range, or a usage value array that is associated with a
variable main item. Array main items are not supported for values.
Aliased usages can be used. A usage range cannot be aliased. Aliased values are linked together in a value
capability array in the same way as aliased buttons as linked together in a button capability array. See
Button Usages in a Variable Main Item.
The HID parser uses only the minimum required usages to assign a usage to each value. The parser
assigns usages in the order in which they are specified in a report descriptor. Usages in a report descriptor
that are not required, are discarded. The value capability array does not contain any information about
discarded usages.
The HID parser assigns a unique data index to each usage described in the capability array.
For a description of how data indices are assigned to values, see Data Indices.
Usage Value Array
A usage value array is a consecutive set of values specified in a main item, all of which are assigned the same
usage. This occurs if only one usage is specified for a main item whose report count is greater than one.
The following figure shows an example of a usage value array that contains five data items, each six bits long.

In the previous example, the value capability structure for such a usage value array would have its IsRange
member set to FALSE, its NotRange.Usage member set to 17, its ReportCount member set to 5, and its
BitSize member set to 6.
If the report count for a usage is 1, use HidP_GetUsageValue to extract the usage value. If the usage's report
count is greater than 1, HidP_GetUsageValue only returns the first data item in a usage value array. To extract
all the data items in a usage value array, use HidP_GetUsageValueArray.
Data Indices
12/5/2018 • 2 minutes to read • Edit Online

The HID parser assigns a data index that uniquely identifies each usage described in a top-level collection's
button capability arrays and value capability arrays. Conceptually, a data index is a zero-based array index that a
user-mode application or kernel-mode driver can use to access individual control data in a report. The parser
assigns a unique set of data indices to each report type supported by each top-level collection.
Capability structures cross-reference usages and data indices in the following way:
Each capability structure that describes a usage has its NotRange.Usage member set to identify the
usage and its NotRange.DataIndex member set to the usage's corresponding data index.
Each capability structure that describes a usage range has its Range.UsageMin and Range.UsageMax
members set to identify the usage range and its Range.DataIndexMin and Range.DataIndexMax
members set to identify the usage range's corresponding data index range. (Data index range specifies a
consecutive sequence of data indices; and the number of data indices in a data index range is equal to the
number of usages in a corresponding usage range.)
For more information about how to use data indices, see Extracting and Setting Control Data by Data Indices.
Opening HID collections
12/5/2018 • 2 minutes to read • Edit Online

This section describes how a HID Client can communicate with the HID Class driver (HIDClass) to operate the
device’s HID collections.
HID Clients can operate in the following modes:
Use- Mode Application/Driver
Kernel-Mode Driver
The following sections identify how the HID Client can communicate with HIDClass using either mode in the
preceding list.
This section describes how user-mode applications and kernel-mode drivers operate HID collections.
In general, a user-mode application does the following:
Calls device installation functions (SetupDiXxx functions) to find and identify a HID collection.
Calls CreateFile to open a file on a HID collection.
Calls HidD_Xxx HID support routines to obtain a HID collection's preparsed data and information about
the HID collection.
Calls ReadFile to read input reports and WriteFile to send output reports.
Calls HidP_Xxx HID support routines to interpret HID reports.
In general, a kernel-mode driver does the following:
Finds and identifies a HID collection
If the driver is a function or filter driver, it is already attached to the collection's device stack. However, if the
driver is not attached to the collection's device stack, the driver can use Plug and Play notification.
Uses an IRP_MJ_CREATE request to open the HID collection
Uses IOCTL_HID_Xxx requests to obtain the HID collection's preparsed data and information about the
HID collection
Uses IRP_MJ_READ requests to read input reports and IRP_MJ_WRITE requests to send output reports
Calls HidP_Xxx HID support routines to interpret HID reports
For more information about operating a HID collection, see:
Finding and Opening a HID Collection
Enforcing a Secure Read For a HID Collection
Obtaining Preparsed Data
Obtaining Collection Information
Handling HID Reports
Freeing Resources
Finding and Opening a HID Collection
12/5/2018 • 2 minutes to read • Edit Online

This section describes how user-mode applications and kernel-mode drivers find and open a top-level HID
collection.
User-Mode Application
Microsoft Windows provides device installation routines (SetupDiXxx functions) to find and identify the HIDClass
devices. Windows provides other Win32 functions to initialize and connect to a HID collection.
After a user-mode application is loaded, it does the following sequence of operations:
Calls HidD_GetHidGuid to obtain the system-defined GUID for HIDClass devices.
Calls SetupDiGetClassDevs to obtain a handle to an opaque device information set that describes the
device interfaces supported by all the HID collections currently installed in the system. The application
should specify DIGCF_PRESENT and DIGCF_DEVICEINTERFACE in the Flags parameter that is passed to
SetupDiGetClassDevs.
Calls SetupDiEnumDeviceInterfaces repeatedly to retrieve all the available interface information.
Calls SetupDiGetDeviceInterfaceDetail to format interface information for each collection as a
SP_INTERFACE_DEVICE_DETAIL_DATA structure. The DevicePath member of this structure contains the
user-mode name that the application uses with the Win32 function CreateFile to obtain a file handle to a
HID collection.
Calls CreateFile to obtain a file handle to a HID collection.
Kernel-Mode Driver
If a kernel-mode driver is a function or filter driver, it has attached a device object to the HID collection's device
stack. The driver has to only use a create request to open the device.
If the driver is not a function or filter driver, it typically uses Plug and Play notification to find a collection. After
finding a collection, the driver uses a create request to open the collection.
HID client drivers
12/5/2018 • 2 minutes to read • Edit Online

If a system-supplied HID minidriver does not support a device's port or bus, a vendor supplied minidriver is
required.
The following figure illustrates a driver stack for a generic HIDClass device (which might use optional and required
vendor-supplied components).

Windows builds the driver stack as follows:


The transport stack creates a physical device object (PDO ) for each HID device attached and loads the
appropriate HID transport driver which in turn loads the HID Class Driver.
The HID class driver creates a PDO for the TLC . For complex devices with multiple TLC, HID Class driver
creates a PDO for each TLC and ensures that the hardware ID associated with the TLC includes an identifier to
represent each device object.
A vendor-supplied function or filter driver creates an FDO or a filter DO for a HID collection.
Alternatively a vendor-supplied application can open the device using SetupDI* APIs to identify the device and
then HID supported routines to communicate with the device. Such devices are said to be opened in RAW
mode.
If the system-supplied Minidriver Operations do not support a device, a vendor-supplied HID minidriver is
required. You can implement this minidriver in two ways:
HID client driver
Application accesses HID directly
If a vendor supplies a driver (other than a minidriver), that driver:
Must comply with the minimum requirements on Windows driver. Ideally, this should be based on the user-
mode driver framework (UMDF ) or the kernel-mode driver framework (KMDF ). A less ideal solution is to
create a WDM function driver, as described in Windows Driver Model.
Typically supports a vendor-defined device interface -- see Device Interface Classes. Upper-level drivers or
user-mode applications use the custom interface to access the devices that the vendor driver operates. The
custom interface might add functionality or, perhaps, simplify the interface to the HID class driver.
If the driver is not a function driver or filter driver, it can use Plug and Play notification to find HID collections. After
finding a collection, the driver opens the collection and operates it in the same manner as a function or filter driver.
Important note:
If a vendor-supplied function driver creates an FDO or filter DO for a HID collection, it should not use the
FsContext field of FILE_OBJECT to store file object-specific data. The FsContext field is reserved for the HID
class driver. If another driver in the stack needs to store file object-specific context data, it should use the
FsContext2 field instead.
If there are multiple devices attached to the PDO, there is no built-in mechanism to determine which device can
use the FsContext2 field.
Enforcing a Secure Read For a HID Collection
12/5/2018 • 2 minutes to read • Edit Online

This section describes how a user-mode application or kernel-mode driver can enforce a secure read for a top-level
HID collection.
If a secure read is enabled for a collection, only "trusted" clients (those with SeTcbPrivilege privileges) can obtain
input from an open file of a collection. Kernel-mode drivers have SeTcbPrivilege privileges by default, but user-
mode applications do not. For information about how to obtain system privileges in user mode, see the
information about authorization in the Microsoft Windows SDK documentation.
This mechanism is provided primarily so that "trusted" user-mode system components can prevent user-mode
applications without SeTcbPrivilege privileges from obtaining input from a collection during critical system
operations. For example, a "trusted" user-mode system component can prevent a user-mode application without
SeTcbPrivilege privileges from obtaining confidential information that a user supplies during a logon operation.
"Trusted" clients use IOCTL_HID_ENABLE_SECURE_READ and IOCTL_HID_DISABLE_SECURE_READ
requests to enable and disable a secure read for a collection. If a client without SeTcbPrivilege privileges uses these
requests, the request does not change the secure read state of a collection, and the HID class driver returns a status
value of STATUS_PRIVILEGE_NOT_HELD.
Enabling and disabling a secure read for a collection works in the following way:
The HID class driver maintains a file-specific secure read count for each open file of a collection. The HID
class driver also maintains a secure read count for the collection, which is the sum of the file-specific secure
read counts. The secure read count for the collection is initialized to zero when the collection is created, and
a secure read count for a file is initialized to zero when a file is opened.
When the HID class driver receives an enable request for a file, it increments by 1 the secure read count for
the file (and increments by 1 the secure read count for the collection).
When the HID class driver receives a disable request for a file:
If the secure read count for the file is greater than zero, the driver decrements by 1 the secure read count
for the file (and decrements by 1 the secure read count for the collection).
If the secure read count for the file is equal to zero, the driver does not change the secure read counts.
If the secure read count for a collection is greater than zero, the HID class driver enforces a secure read for
the collection. Otherwise, the driver does not enforce a secure read for the collection.
A client should use a disable request to cancel a corresponding enable request. However, if the client does
not do this, the HID class driver appropriately decrements the secure read count for a collection when it
processes an IRP_MJ_CLOSE request for a file. When the driver processes the close request, it decrements
the secure read count for the collection by the secure read count for the file being closed.
Obtaining Preparsed Data
12/5/2018 • 2 minutes to read • Edit Online

This section describes how user-mode applications and kernel-mode drivers obtain a HID collection's preparsed
data, which is an opaque structure that describes a collection's HID reports.
User-Mode Application
A user-mode application must obtain a collection's preparsed data before calling any of the HIDClass support
routines that require the preparsed data. An application should retain access to a collection's preparsed data as
long as it has an open file on the device.
After opening a file on a HID collection, an application calls HidD_GetPreparsedData to return a collection's
preparsed data in a routine-allocated buffer.
Applications should call HidD_FreePreparsedData when the application no longer requires access to a collection.
Kernel-Mode Driver
After a kernel-mode driver opens a HID collection, the driver obtains a collection's preparsed data in the following
way:
Obtains the length of the collection's preparsed data
Obtains the collection's preparsed data
To determine the length of the preparsed data, the driver uses an
IOCTL_HID_GET_COLLECTION_INFORMATION request. This request returns a
HID_COLLECTION_INFORMATION structure. The DescriptorSize member of this structure specifies the size,
in bytes, of a collection's preparsed data. The driver must allocate a buffer from nonpaged pool of at least this size
to hold the preparsed data.
After allocating the buffer for the preparsed data, the driver uses an
IOCTL_HID_GET_COLLECTION_DESCRIPTOR request to obtain the preparsed data.
After obtaining the preparsed data, the driver can use it with the HidP_Xxx HID support routines to obtain
information about the capabilities of the HID collection and to extract control data from HID reports.
Obtaining Collection Information
12/5/2018 • 2 minutes to read • Edit Online

This section addresses obtaining information that user-mode applications and kernel-mode drivers use to operate
a HID collection.
After an application or driver has connected to a HID collection, it can obtain the following information:
Collection's capabilities.
Button capability arrays and value capability arrays, which describe the capabilities of buttons and values
supported by the collection.
Link collection array, which describes the internal organization of its link collections.
This information includes the HID usage of the collection and all the controls supported by the collection. If an
application or driver does not use these controls, it should immediately close its connection to the collection.
After obtaining this information, an application or driver has the information it requires to access control data in
HID reports.
Handling HID Reports
12/5/2018 • 2 minutes to read • Edit Online

This section describes the mechanisms that user-mode applications and kernel-mode drivers use for handling HID
reports.
After an application or driver has connected to a HID collection, it can obtain HID reports from, or send reports to,
the collection. For more information about how to handle HID reports, see the following topics:
Initializing HID Reports
Obtaining HID Reports
Sending HID Reports
Interpreting HID Reports
Troubleshooting HID Reports
Initializing HID Reports
12/5/2018 • 2 minutes to read • Edit Online

This section describes how user-mode applications and kernel-mode drivers initialize a HID report before using
the HIDClass support routines or the HID class driver IOCTLs.
To initialize a report buffer, an application or driver creates a zero-initialized buffer of the required size, in bytes, for
the report type. The XxxReportByteLength members of a HID collection's HIDP_CAPS structure specify the
required size of input, output, and feature reports. After initializing a report buffer, an application or driver can use
HidP_SetXxx routines to set control data in the report. On the first use of a report, the HidP_SetXxx routines set
the report ID to the one associated with a specified HID usage. If the application or driver subsequently attempts
to set a usage that is incompatible with the report ID, the HidP_SetXxx routines return a status of
HIDP_STATUS_INCOMPATIBLE_REPORT_ID.
Obtaining HID Reports
12/5/2018 • 2 minutes to read • Edit Online

This section describes how user-mode applications and kernel-mode drivers obtain HID reports from a HID
collection.
This section includes the following topics:
Obtaining HID Reports by User-Mode Applications
Obtaining HID Reports by Kernel-Mode Drivers
Sending HID Reports
12/5/2018 • 2 minutes to read • Edit Online

This section describes how user-mode applications and kernel-mode drivers send HID reports to a HID collection.
This section includes the following topics:
Sending HID Reports by User-Mode Applications
Sending HID Reports by Kernel-Mode Drivers
Interpreting HID Reports
12/5/2018 • 2 minutes to read • Edit Online

This section describes how user-mode applications and kernel-mode drivers use the HidP_Xxx HIDClass support
routines to interpret control data in a HID report.
For information about extracting control data from a report, see the following:
Extracting Value Data by Specifying Its Usage
Extracting Button Usages That Are Set to ON
Extracting and Setting Control Data by Data Indices
For information about how to set control data in a report, see the following:
Setting Value Data by Specifying Its Usage
Setting Button State by Specifying Its Usage
Extracting and Setting Control Data by Data Indices
Troubleshooting HID Reports
12/5/2018 • 2 minutes to read • Edit Online

This section describes the following most common problems that user-mode applications and kernel-mode drivers
might encounter when attempting to extract or set HID usages:
HID Report ID Errors
Dropped HID Reports
HID Report ID Errors
When an application or driver receives a HID report from a HID collection, it can be any report that the collection
contains (because a collection can return reports in any order). The HidP_GetXxx routines return the following
status values, which indicate report ID errors:
HIDP_STATUS_INCOMPATIBLE_REPORT_ID
A requested usage is in a report supported by the HID collection, but not in the report that the application or
driver specified.
HIDP_STATUS_USAGE_NOT_FOUND
A requested usage is not in any report supported by the top-level collection.
For example, the following figure shows a HID collection that contains two reports.

Based on this example, assume an application or driver received a report from a collection and calls
HidP_GetUsageValue to extract the current value of "Value X." If the report's ID is seven, the routine returns
HIDP_STATUS_INCOMPATIBLE_REPORT_ID, which indicates that the device supports Value X, but that Value X is
not present in the report. On the other hand, if the application or driver requests the value of "Value Z," the routine
returns HIDP_STATUS_USAGE_NOT_FOUND, which indicates that Value Z is not in any report supported by the
collection.
When an application or driver uses HidP_SetXxx routines to set usages in a report, the routines can also return
the same two status values. The meaning of HIDP_STATUS_USAGE_NOT_FOUND is the same as with the
HidP_GetXxx routines. However, the meaning of HIDP_STATUS_INCOMPATIBLE_REPORT_ID is different. This
status value indicates that the report was previously configured with a report ID, and the usage specified by the
caller does not belong to that report ID. Using the previous figure as an example, after an application or driver uses
HidP_SetUsages to set "Button 2" in a zero-initialized report, the report is configured with a report ID of seven. If
the application or driver subsequently attempts to use HidP_SetUsageValue to set "Value X" in the same report,
the routine will return HIDP_STATUS_INCOMPATIBLE_REPORT_ID.
If a HidP_Xxx routine returns HIDP_STATUS_INCOMPATIBLE_REPORT_ID, the caller should take one of the
following actions:
If the caller is setting usages, it should allocate a new report of the correct length, zero-initialize it, and then
call the routine again. The caller can send the report to the collection after successfully setting all usages in
the report.
If the caller is extracting usages, it should call the routine with a different report obtained from the
collection.
Dropped HID Reports
When the HID Client Drivers obtains input reports from a HID collection, the reports are stored in a ring buffer
maintained by the HID class driver. This mechanism reduces the possibility that an application or driver will miss
input reports that it requires.
By default, the HID class driver maintains an input report ring buffer that holds 32 reports. If a collection transmits
data to the HID class driver faster than a user-mode application or kernel-mode driver retrieves it from the buffer,
input reports are lost because of buffer overflow. To reduce the possibility of buffer overflow, an application or
driver can reconfigure the size, in number of reports, of the buffer. Drivers retrieve and change the size of the
buffer by using an IOCTL_GET_NUM_DEVICE_INPUT_BUFFERS request and an
IOCTL_SET_NUM_DEVICE_INPUT_BUFFERS request. Applications do the same operation by calling
HidD_GetNumInputBuffers and HidD_SetNumInputBuffers.
Freeing Resources
12/5/2018 • 2 minutes to read • Edit Online

User-mode applications and kernel-mode drivers that are HID clients should always free any resources that are no
longer required.
For example, a user-mode application must call SetupDiDestroyDeviceInfoList with the handle to the device list
that it obtained from SetupDiGetClassDevs after completing its initialization and connection operations for a
HIDClass device. Failure to call SetupDiDestroyDeviceInfoList causes a memory leak.
Installing HID clients
12/5/2018 • 2 minutes to read • Edit Online

This section describes the following requirements for installing HIDClass devices in Microsoft Windows.
Vendors must use the hardware IDs for top-level collections that are designated as vendor hardware ID
formats in HIDClass Hardware IDs for Top-Level Collections.
Vendor-supplied drivers for parent input devices (installed below the HID class driver in driver stacks for
HIDClass devices) must supply the hardware information that the HID class driver uses to generate
hardware IDs for top-level collections. (Note that the system-provided drivers for HIDClass devices do this
automatically.)
In Windows Vista and later versions of Windows, vendors can enable the selective suspend feature for USB
HID devices. This feature is defined in Revision 2.0 of the Universal Serial Bus Specification. For more
information about how Windows supports the USB selective suspend feature, see USB selective suspend.
There are no other HIDClass-specific requirements for installing HIDClass devices. For more information about
how to install devices, see Device Installation Overview.
HIDClass Hardware IDs for Top-Level Collections
1/11/2019 • 2 minutes to read • Edit Online

This section specifies the hardware IDs that the HID class driver generates for top-level collections.
Vendors must use the formats that are designated as vendor hardware ID formats to identify top-level collections.
All other device ID formats are reserved for internal use only.
The hardware IDs that the HID class driver generates for a devnode depends on the following:
1. Number of functions supported by the underlying transport
2. Number of Top Level Collections in the Report Descriptor
Based on these factors, there are 4 categories of hardware IDs

SINGLE TLC MULTIPLE TLC

Single-Function Case 1 Case 2

Multi-Function Case 3 Case 4

Case 1: Single-function device with single TLC


Condition under which this Hardware ID format is used:
1. Number of functions supported by the underlying transport = 1 &&
2. Number of TLC = 1
Hardware ID Format:
HID\Vid_v(4)&Pid_d(4)&Rev_r(4)
HID\Vid_v(4)&Pid_d(4)
HID_DEVICE_UP:p(4)_U:u(4)
HID_DEVICE

Case 2: Single-function device with multiple TLC


Condition under which this Hardware ID format is used:
1. Number of functions supported by the underlying transport = 1 &&
2. Number of TLC > 1
Hardware ID Format:
HID\Vid_v(4)&Pid_d(4)&Rev_r(4)&Colb(2)
HID\Vid_v(4)&Pid_d(4)&Colb(2)
HID_DEVICE_UP:p(4)_U:u(4) [RESERVED FOR WINDOWS INFs ONLY ]
HID_DEVICE [RESERVED FOR WINDOWS INFs ONLY ]

Case 3: Multi-function device with single TLC


Condition under which this Hardware ID format is used:
1. Number of functions supported by the underlying transport > 1 &&
2. Number of TLC = 1
Hardware ID Format:
HID\Vid_v(4)&Pid_d(4)&Rev_r(4)&MI_z(2)
HID\Vid_v(4)&Pid_d(4)&MI_z(2)
HID_DEVICE_UP:p(4)_U:u(4) [RESERVED FOR WINDOWS INFs ONLY ]
HID_DEVICE [RESERVED FOR WINDOWS INFs ONLY ]

Case 4: Multi-function device with multiple TLC


Condition under which this Hardware ID format is used:
1. Number of functions supported by the underlying transport > 1 &&
2. Number of TLC > 1
Hardware ID Format:
HID\Vid_v(4)&Pid_d(4)&Rev_r(4)&MI_z(2)&Colb(2)
HID\Vid_v(4)&Pid_d(4)&MI_z(2)&Colb(2)
HID_DEVICE_UP:p(4)_U:u(4) [RESERVED FOR WINDOWS INFs ONLY ]
HID_DEVICE [RESERVED FOR WINDOWS INFs ONLY ]

Special purpose hardware ID


The following are hardware IDs (for internal use only) that Windows uses to provide default system functionality.

DEVICE TYPE USAGE PAGE USAGE HARDWARE ID

Pointer 0x01 0x01 HID_DEVICE_SYSTEM_M


OUSE

Mouse 0x01 0x02 HID_DEVICE_SYSTEM_M


OUSE

Joystick 0x01 0x04 HID_DEVICE_SYSTEM_G


AME

Game pad 0x01 0x05 HID_DEVICE_SYSTEM_G


AME

Keyboard 0x01 0x06 HID_DEVICE_SYSTEM_K


EYBOARD

Keypad 0x01 0x07 HID_DEVICE_SYSTEM_K


EYBOARD

System control 0x01 0x80 HID_DEVICE_SYSTEM_C


ONTROL
DEVICE TYPE USAGE PAGE USAGE HARDWARE ID

Consumer audio control 0x0C 0x01 HID_DEVICE_SYSTEM_C


ONSUMER

Important notes:
There are no compatible IDs generated by HIDClass
Vendor 3rd party INFs must only match against the hardware IDs
Hardware IDs that contain HID_DEVICE_SYSTEM_* are “special” devices that the operating system opens for
its use. Vendor provided INF must not match on these special hardware IDs.
Vendor provided 3rd party HID transport minidrivers must provided the fields listed below to ensure that
HIDClass can generate the appropriate hardware IDs.
Legend:

Field Contains Hexadecimal Value Meaning

v(4) four hex digits 0x0000-0xFFFF Vendor ID

d(4) four hex digits 0x0000-0xFFFF Product ID

r(4) four hex digits 0x0000-0xFFFF Revision Number

z(2) two hex digits 0x00-0xFF Interface number (only used


with composite USB devices.)

b(2) two hex digits 0x00-0xFF Collection number (only


used with multiple-TLC
devices.)

p(4) four hex digits 0x0000-0xFFFF Usage Page Number for TLC

u(4) four hex digits 0x0000-0xFFFF Usage Number of TLC


Keyboard and mouse HID client drivers
3/22/2019 • 15 minutes to read • Edit Online

NOTE
This topic is for developers who are creating drivers for keyboard and mouse HID clients. If you are looking to fix a mouse or
keyboard, see:
Mouse, touchpad, and keyboard problems in Windows
Troubleshoot a wireless mouse that does not function correctly

This topic discusses keyboard and mouse HID client drivers. Keyboards and mice represent the first set of HID
clients that were standardized in the HID Usage tables and implemented in Windows operating systems.
Keyboard and mouse HID client drivers are implemented in the form of HID Mapper Drivers. A HID mapper driver
is a kernel-mode WDM filter driver that provides a bidirectional interface for I/O requests between a non-HID
Class driver and the HID class driver. The mapper driver maps the I/O requests and data protocols of one to the
other.
Windows provides system-supplied HID mapper drivers for HID keyboard, and HID mice devices.

Architecture and overview


The following figure illustrates the system-supplied driver stacks for USB keyboard and mouse/touchpad devices.

The figure above includes the following components:


KBDHID.sys – HID client mapper driver for keyboards. Converts HID usages into scancodes to interface with
the existing keyboard class driver.
MOUHID.sys – HID client mapper driver for mice/touchpads. Converts HID usages into mouse commands
(X/Y, buttons, wheel) to interface with the existing keyboard class driver.
KBDCLASS.sys – The keyboard class driver maintains functionality for all keyboards and keypads on the
system in a secure manner.
MOUCLASS.sys – The mouse class driver maintains functionality for all mice / touchpads on the system. The
driver does support both absolute and relative pointing devices. This is not the driver for touchscreens as that is
managed by a different driver in Windows.
The system builds the driver stack as follows:
The transport stack creates a physical device object (PDO ) for each HID device attached and loads the
appropriate HID transport driver which in turn loads the HID Class Driver.
The HID class driver creates a PDO for each keyboard or mouse TLC. Complex HID devices (more than 1 TLC )
are exposed as multiple PDOs created by HID class driver. For example, a keyboard with an integrated mouse
might have one collection for the standard keyboard controls and a different collection for the mouse.
The keyboard or mouse hid client mapper drivers are loaded on the appropriate FDO.
The HID mapper drivers create FDOs for keyboard and mouse, and load the class drivers.
Important notes:
Vendor drivers are not required for keyboards and mice that are compliant with the supported HID Usages and
top level collections.
Vendors may optionally provide filter drivers in the HID stack to alter/enhance the functionality of these specific
TLC.
Vendors should create separate TLCs, that are vendor specific, to exchange vendor proprietary data between
their hid client and the device. Avoid using filter drivers unless critical.
The system opens all keyboard and mouse collections for its exclusive use.
The system prevents disable/enabling a keyboard.
The system provides support for horizontal/vertical wheels with smooth scrolling capabilities.

Driver Guidance
Microsoft provides the following guidance for IHVs writing drivers:
1. Driver developers are allowed to add additional drivers in the form of a filter driver or a new HID Client
driver. The criteria are described below:
a. Filters Drivers: Driver developers should ensure that their value-add driver is a filter driver and does
not replace (or be used in place of) existing Windows HID drivers in the input stack.
Filter drivers are allowed in the following scenarios:
As an upper filter to kbdhid/mouhid
As an upper filter to kbdclass/mouclass
Filter drivers are not recommended as a filter between HIDCLASS and HID Transport minidriver
b. Function Drivers: Alternatively vendors can create a function driver (instead of a filter driver) but only
for vendor specific HID PDOs (with a user mode service if necessary).
Function drivers are allowed in the following scenarios:
Only load on the specific vendor’s hardware
c. Transport Drivers: Windows team does not recommend creating additional HID Transport minidriver
as they are complex drivers to write/maintain. If a partner is creating a new HID Transport minidriver,
especially on SoC systems, we recommend a detailed architectural review to understand the
reasoning and ensure that the driver is developed correctly.
2. Driver developers should leverage driver Frameworks (KMDF or UMDF ) and not rely on WDM for their
filter drivers.
3. Driver developers should reduce the number of kernel-user transitions between their service and the driver
stack.
4. Driver developers should ensure ability to wake the system via both keyboard and touchpad functionality
(adjustable by the end user (device manager) or the PC manufacturer). In addition on SoC systems, these
devices must be able to wake themselves from a lower powered state while the system is in a working S0
state.
5. Driver developers should ensure that their hardware is power managed efficiently.
Device can go into its lowest power state when the device is idle.
Device is in the lowest power state when the system is in a low power state (for example, standby (S3) or
connected standby).

Keyboard layout
A keyboard layout fully describes a keyboard's input characteristics for Microsoft Windows 2000 and later
versions. For example, a keyboard layout specifies the language, keyboard type and version, modifiers, scan codes,
and so on.
See the following for information about keyboard layouts:
Keyboard header file, kdb.h, in the Windows Driver Development Kit (DDK), which documents general
information about keyboard layouts.
Sample keyboard layouts.
To visualize the layout of a specific keyboard, see Windows Keyboard Layouts.
For additional details around the keyboard layout, visit Control Panel\Clock, Language, and Region\Language.

Supported buttons and wheels on mice


The following table identifies the features supported across different client versions of the Windows operating
system.

WINDOWS 8 AND
FEATURE WINDOWS XP WINDOWS VISTA WINDOWS 7 LATER

Buttons 1-5 Supported (P/2 & Supported (PS/2 & Supported (PS/2 & Supported (PS/2 &
HID) HID) HID) HID)

Vertical Scroll Wheel Supported (PS/2 & Supported (PS/2 & Supported (PS/2 & Supported (PS/2 &
HID) HID) HID) HID)

Horizontal Scroll Not Supported Supported(HID only) Supported(HID only) Supported(HID only)
Wheel

Smooth Scroll Wheel Not Supported Partly Supported Supported (HID only) Supported (HID only)
Support (Horizontal
and Vertical)
Activating buttons 4-5 and wheel on PS/2 mice
The method used by Windows to activate the new 4&5-button + wheel mode is an extension of the method used
to activate the third button and the wheel in IntelliMouse-compatible mice:
First, the mouse is set to the 3-button wheel mode, which is accomplished by setting the report rate
consecutively to 200 reports/second, then to 100 reports/second, then to 80 reports/second, and then reading
the ID from the mouse. The mouse should report an ID of 3 when this sequence is completed.
Next, the mouse is set to the 5-button wheel mode, which is accomplished by setting the report rate
consecutively to 200 reports/second, then to 200 reports/second again, then to 80 reports/second, and then
reading the ID from the mouse. Once this sequence is completed, a 5-button wheel mouse should report an ID
of 4 (whereas an IntelliMouse-compatible 3-button wheel mouse would still report an ID of 3).
Note that this is applicable to PS/2 mice only and is not applicable to HID mice (HID mice must report accurate
usages in their report descriptor).
Standard PS/2-compatible mouse data packet format (2 Buttons )

COMMEN
BYTE D7 D6 D5 D4 D3 D2 D1 D0 T

1 Yover Xover Ysign Xsign Tag M R L X/Y


overvlo
ws and
signs,
buttons

2 X7 X6 X5 X4 X3 X2 X1 X0 X data
byte

3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 Y data
bytes

NOTE
Windows mouse drivers do not check the overflow bits. In case of overflow, the mouse should simply send the maximal
signed displacement value.

Standard PS/2-compatible mouse data packet format (3 Buttons + VerticalWheel)

COMMEN
BYTE D7 D6 D5 D4 D3 D2 D1 D0 T

1 0 0 Ysign Xsign 1 M R L X/Y


signs
and
R/L/M
buttons

2 X7 X6 X5 X4 X3 X2 X1 X0 X data
byte

3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 Y data
bytes

4 Z7 Z6 Z5 Z4 Z3 Z2 Z1 Z0 Z/wheel
data
byte
Standard PS/2-compatible mouse data packet format (5 Buttons + VerticalWheel)

COMMEN
BYTE D7 D6 D5 D4 D3 D2 D1 D0 T

1 0 0 Ysign Xsign 1 M R L X/Y


signs
and
R/L/M
buttons

2 X7 X6 X5 X4 X3 X2 X1 X0 X data
byte

3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 Y data
bytes

4 0 0 B5 B4 Z3 Z2 Z1 Z0 Z/wheel
data and
buttons
4 and 5

Important note:
Notice that the Z/wheel data for a 5-button wheel mouse has been reduced to four bits instead of the 8 bits
used in the IntelliMouse-compatible 3-button wheel mode. This reduction is made possible by the fact that the
wheel typically cannot generate values beyond the range +7/-8 during any given interrupt period. Windows
mouse drivers will sign extend the four Z/wheel data bits when the mouse is in the 5-button wheel mode, and
the full Z/wheel data byte when the mouse operates in the 3-button wheel mode.
Buttons 4 & 5 on are mapped to WM_APPCOMMAND messages and correspond to App_Back and
App_Forward.
Devices not requiring vendor drivers
Vendor drivers are not required for the following devices:
Devices that comply with the HID Standard.
Keyboard, mouse, or game port devices operated by the system-supplied non-HIDClass drivers.

Kbfiltr sample
Kbfiltr is designed to be used with Kbdclass, the system class driver for keyboard devices and I8042prt, the
function driver for a PS/2-style keyboard. Kbfiltr demonstrates how to filter I/O requests and how to add callback
routines that modify the operation of Kbdclass and I8042prt.
For more information about Kbfiltr operation, see the following:
The ntddkbd.h WDK header file.
The sample Kbfiltr source code.
Kbfiltr IOCTLs
CONTROL CODE DESCRIPTION
<MSHelp:link tabindex="0" The IOCTL_INTERNAL_I8042_HOOK_KEYBOARD request
keywords="hid.ioctl_internal_i8042_hook_keyboard">IOC does the following:
TL_INTERNAL_I8042_HOOK_KEYBOARD</MSHelp:link>
Adds an initialization callback routine to the
I8042prt keyboard initialization routine
Adds an ISR callback routine to the I8042prt
keyboard ISR
The initialization and ISR callbacks are optional and are
provided by an upper-level filter driver for a PS/2-style
keyboard device.
After I8042prt receives an <MSHelp:link tabindex="0"
keywords="hid.ioctl_internal_keyboard_connect2">IOCTL_
INTERNAL_KEYBOARD_CONNECT</MSHelp:link>
request, it sends a synchronous
IOCTL_INTERNAL_I8042_HOOK_KEYBOARD request to
the top of the keyboard device stack.
After Kbfiltr receives the hook keyboard request, Kbfiltr
filters the request in the following way:
Saves the upper-level information passed to Kbfiltr,
which includes the context of an upper-level device
object, a pointer to an initialization callback, and a
pointer to an ISR callback
Replaces the upper-level information with its own
Saves the context of I8042prt and pointers to
callbacks that the Kbfiltr ISR callback can use

<MSHelp:link tabindex="0" The IOCTL_INTERNAL_KEYBOARD_CONNECT request


keywords="hid.ioctl_internal_keyboard_connect">IOCTL_I connects the Kbdclass service to the keyboard device.
NTERNAL_KEYBOARD_CONNECT</MSHelp:link> Kbdclass sends this request down the keyboard device
stack before it opens the keyboard device.
After Kbfiltr received the keyboard connect request, Kbfiltr
filters the connect request in the following way:
Saves a copy of Kbdclass's <MSHelp:link
tabindex="0"
keywords="hid.connect_data__kbdclass_">CONNE
CT_DATA (Kbdclass)</MSHelp:link> structure
that is passed to the filter driver by Kbdclass
Substitutes its own connect information for the
class driver connect information
Sends the
IOCTL_INTERNAL_KEYBOARD_CONNECT request
down the device stack
If the request is not successful, Kbfiltr completes the
request with an appropriate error status.
Kbfiltr provides a template for a filter service callback
routine that can supplement the operation of
<MSHelp:link tabindex="0"
keywords="hid.keyboardclassservicecallback">Keyboard
ClassServiceCallback</MSHelp:link>, the Kbdclass class
service callback routine. The filter service callback can filter
the input data that is transferred from the device input
buffer to the class data queue.
<MSHelp:link tabindex="0" The IOCTL_INTERNAL_KEYBOARD_DISCONNECT request
keywords="hid.ioctl_internal_keyboard_disconnect">IOCT is completed with a status of
L_INTERNAL_KEYBOARD_DISCONNECT</MSHelp:link> STATUS_NOT_IMPLEMENTED. Note that a Plug and Play
keyboard can be added or removed by the Plug and Play
manager.

For all other device control requests, Kbfiltr skips the current IRP stack and sends the request down the device
stack without further processing.
Callback routines implemented by Kbfiltr
KbFilter_InitializationRoutine

(see &lt;MSHelp:link tabindex="0" keywords="hid.pi8042_keyboard_initialization_routine"&gt;


<b>PI8042_KEYBOARD_INITIALIZATION_ROUTINE</b>&lt;/MSHelp:link&gt;)<p><b>
KbFilter_InitializationRoutine</b> is not needed if I8042prt's default initialization of a
keyboard is sufficient.</p>

I8042prt calls KbFilter_InitializationRoutine when it initializes the keyboard. Default keyboard


initialization includes the following operations: reset the keyboard, set the typematic rate and delay, and set
the light-emitting diodes (LED ).

/*
Parameters
DeviceObject [in]
Pointer to the device object that is the context for this callback.
SynchFuncContext [in]
Pointer to the context for the routines pointed to by ReadPort and Writeport.

ReadPort [in]
Pointer to the system-supplied PI8042_SYNCH_READ_PORT callback that reads from the port.

WritePort [in]
Pointer to the system-supplied PI8042_SYNCH_WRITE_PORT callback that writes to the port.

TurnTranslationOn [out]
Specifies, if TRUE, to turn translation on. Otherwise, translation is turned off.

Return value
KbFilter_InitializationRoutine returns an appropriate NTSTATUS code.

NTSTATUS KbFilter_InitializationRoutine(
In PDEVICE_OBJECT DeviceObject,
In PVOID SynchFuncContext,
In PI8042_SYNCH_READ_PORT ReadPort,
In PI8042_SYNCH_WRITE_PORT WritePort,
Out PBOOLEAN TurnTranslationOn
);

KbFilter_IsrHook
(see &lt;MSHelp:link tabindex="0" keywords="hid.pi8042_keyboard_isr"&gt;
<i>PI8042_KEYBOARD_ISR</i>&lt;/MSHelp:link&gt;)<p>This callback is not needed if the default operation
of I8042prt is sufficient.</p>

The I8042prt keyboard ISR calls KbFilter_IsrHook after it validates the interrupt and reads the scan code.
KbFilter_IsrHook runs in kernel mode at the IRQL of the I8042prt keyboard ISR.

/
Parameters
DeviceObject [in]
Pointer to the filter device object of the driver that supplies this callback.
CurrentInput [in]
Pointer to the input KEYBOARD_INPUT_DATA structure that is being constructed by the ISR.

CurrentOutput [in]
Pointer to an OUTPUT_PACKET structure that specifies the bytes that are being written to the
hardware device.

StatusByte [in, out]


Specifies the status byte that is read from I/O port 60 when an interrupt occurs.

DataByte [in]
Specifies the data byte that is read from I/O port 64 when an interrupt occurs.

ContinueProcessing [out]
Specifies, if TRUE, to continue processing in the I8042prt keyboard ISR after this callback returns;
otherwise, processing is not continued.

ScanState [in]
Pointer to a KEYBOARD_SCAN_STATE structure that specifies the keyboard scan state.

Return value
KbFilter_IsrHook returns TRUE if the interrupt service routine should continue; otherwise it returns
FALSE.

KbFilter_IsrHook KbFilter_IsrHook(
In PDEVICE_OBJECT DeviceObject,
In PKEYBOARD_INPUT_DATA CurrentInput,
In POUTPUT_PACKET CurrentOutput,
Inout UCHAR StatusByte,
In PUCHAR DataByte,
Out PBOOLEAN ContinueProcessing,
In PKEYBOARD_SCAN_STATE ScanState
);

);

KbFilter_ServiceCallback (see <MSHelp:link tabindex="0"


keywords="hid.kbdclass_class_service_callback_routine">PSERVICE_CALLBACK_ROUTINE</MSHelp:link>)
The ISR dispatch completion routine of the function driver calls KbFilter_ServiceCallback, which then
calls the keyboard class driver's implementation of <MSHelp:link tabindex="0"
keywords="hid.kbdclass_class_service_callback_routine">PSERVICE_CALLBACK_ROUTINE</MSHelp:link>. A
vendor can implement a filter service callback to modify the input data that is transferred from the device's
input buffer to the class data queue. For example, the callback can delete, transform, or insert data.

/
Parameters
DeviceObject [in]
Pointer to the class device object.
InputDataStart [in]
Pointer to the first keyboard input data packet in the input data buffer of the port device.

InputDataEnd [in]
Pointer to the keyboard input data packet that immediately follows the last data packet in the input
data buffer of the port device.

InputDataConsumed [in, out]


Pointer to the number of keyboard input data packets that are transferred by the routine.

Return value
None

*/

VOID KbFilter_ServiceCallback(
In PDEVICE_OBJECT DeviceObject,
In PKEYBOARD_INPUT_DATA InputDataStart,
In PKEYBOARD_INPUT_DATA InputDataEnd,
Inout PULONG InputDataConsumed
);

);

Moufiltr sample
Moufiltr is designed to be used with Mouclass, the system class driver for mouse devices used with
Windows 2000 and later versions, and I8042prt, the function driver for a PS/2-style mouse used with
Windows 2000 and later. Moufiltr demonstrates how to filter I/O requests and add callback routines that
modify the operation of Mouclass and I8042prt.

CONTROL CODE DESCRIPTION


<MSHelp:link tabindex="0" The IOCTL_INTERNAL_I8042_HOOK_MOUSE request
keywords="hid.ioctl_internal_i8042_hook_mouse">IO adds an ISR callback routine to the I8042prt mouse
CTL_INTERNAL_I8042_HOOK_MOUSE</MSHelp:link ISR. The ISR callback is optional and is provided by an
> upper-level mouse filter driver.
I8042prt sends this request after it receives an
<MSHelp:link tabindex="0"
keywords="hid.ioctl_internal_mouse_connect2">IOCT
L_INTERNAL_MOUSE_CONNECT</MSHelp:link>
request. I8042prt sends a synchronous
IOCTL_INTERNAL_I8042_HOOK_MOUSE request to
the top of the mouse device stack.
After Moufiltr receives the hook mouse request, it
filters the request in the following way:
Saves the upper-level information passed to
Moufiltr, which includes the context of an
upper-level device object and a pointer to an
ISR callback
Replaces the upper-level information with its
own
Saves the context of I8042prt and pointers to
callbacks that the Moufiltr ISR callbacks can use
For more information about this request and the
callbacks, see the following topics:

<MSHelp:link tabindex="0"
keywords="hid.i8042prt_callback_routines">I8042prt
Callback Routines</MSHelp:link>
<MSHelp:link tabindex="0"
keywords="hid.moufiltr_callback_routines">Moufiltr
Callback Routines</MSHelp:link>

<MSHelp:link tabindex="0" The IOCTL_INTERNAL_MOUSE_CONNECT request


keywords="hid.ioctl_internal_mouse_connect">IOCTL_ connects Mouclass service to a mouse device.
INTERNAL_MOUSE_CONNECT</MSHelp:link>

<MSHelp:link tabindex="0" The IOCTL_INTERNAL_MOUSE_DISCONNECT request


keywords="hid.ioctl_internal_mouse_disconnect">IOC is completed by Moufiltr with an error status of
TL_INTERNAL_MOUSE_DISCONNECT</MSHelp:link STATUS_NOT_IMPLEMENTED.
>

For all other requests, Moufiltr skips the current IRP stack and sends the request down the device stack
without further processing.
Callback routines implemented by Kbfiltr
MouFilter_IsrHook (See <MSHelp:link tabindex="0" keywords="hid.pi8042_mouse_isr">
PI8042_MOUSE_ISR</MSHelp:link>)
/*
Parameters
DeviceObject
Pointer to the filter device object of the driver that supplies this callback.
CurrentInput
Pointer to the input MOUSE_INPUT_DATA structure being constructed by the ISR.

CurrentOutput
Pointer to the OUTPUT_PACKET structure that specifies the bytes being written to the hardware
device.

StatusByte
Specifies a status byte that is read from I/O port 60 when the interrupt occurs.

DataByte
Specifies a data byte that is read from I/O port 64 when the interrupt occurs.

ContinueProcessing
Specifies, if TRUE, that the I8042prt mouse ISR continues processing after this callback
returns. Otherwise, processing is not continued.

MouseState
Pointer to a MOUSE_STATE enumeration value, which identifies the state of mouse input.

ResetSubState
Pointer to MOUSE_RESET_SUBSTATE enumeration value, which identifies the mouse reset substate.
See the Remarks section.

Return value
MouFilter_IsrHook returns TRUE if the interrupt service routine should continue; otherwise it
returns FALSE.

*/

BOOLEAN MouFilter_IsrHook(
PDEVICE_OBJECT DeviceObject,
PMOUSE_INPUT_DATA CurrentInput,
POUTPUT_PACKET CurrentOutput,
UCHAR StatusByte,
PUCHAR DataByte,
PBOOLEAN ContinueProcessing,
PMOUSE_STATE MouseState,
PMOUSE_RESET_SUBSTATE ResetSubState
);

A MouFilter_IsrHook callback is not needed if the default operation of I8042prt is sufficient.


The I8042prt mouse ISR calls MouFilter_IsrHook after it validates the interrupt.
To reset a mouse, I8042prt goes through a sequence of operational substates, each one of which is
identified by an MOUSE_RESET_SUBSTATE enumeration value. For more information about how
I8042prt resets a mouse and the corresponding mouse reset substates, see the documentation of
MOUSE_RESET_SUBSTATE in ntdd8042.h.
MouFilter_IsrHook runs in kernel mode at the IRQL of the I8042prt mouse ISR.
MouFilter_ServiceCallback (See <MSHelp:link tabindex="0"
keywords="hid.kbdclass_class_service_callback_routine">PSERVICE_CALLBACK_ROUTINE
</MSHelp:link>)

/*
Parameters
DeviceObject [in]
Pointer to the class device object.
InputDataStart [in]
Pointer to the first mouse input data packet in the input data buffer of the port device.

InputDataEnd [in]
Pointer to the mouse input data packet immediately following the last data packet in the port
device's input data buffer.

InputDataConsumed [in, out]


Pointer to the number of mouse input data packets that are transferred by the routine.

Return value
None

*/

VOID MouFilter_ServiceCallback(
In PDEVICE_OBJECT DeviceObject,
In PMOUSE_INPUT_DATA InputDataStart,
In PMOUSE_INPUT_DATA InputDataEnd,
Inout PULONG InputDataConsumed
);

The ISR DPC of I8042prt calls MouFilter_ServiceCallback, which then calls


MouseClassServiceCallback. A filter service callback can be configured to modify the input data that is
transferred from the device's input buffer to the class data queue. For example, the callback can delete,
transform, or insert data.
Sensor HID class driver
12/5/2018 • 2 minutes to read • Edit Online

Starting with Windows 8, the Windows operating system includes an in-box sensor HID Class driver
(SensorsHIDClassDriver.dll), that supports eleven types of sensors that communicate using the HID transport.
Here is a list of the supported sensors:
Accelerometer 3D
Ambient Light
Ambient Temperature
Atmospheric Pressure
Compass 3D
Device Orientation
Gyroscope 3D
Humidity
Inclinometer 3D
Presence
Proximity
The following illustration depicts the flow of data back and forth from two sensor applications down through the
driver stack and, finally, to the hardware itself.

Support for custom sensors


In addition to the eleven sensors covered in the previous lists, the class driver also supports a Custom class. This
class allows a sensor manufacturer to integrate a device not found in the previous list: For example, a carbon
monoxide sensor. The custom sensor presents itself to the sensor API as a custom device with unique properties.

Architecture and overview


If you are creating the firmware for a compatible sensor, you’ll need a basic understanding of the I/O model
supported by the class driver.
The sensor sends either a feature report or an input report to the HID class driver. A feature report is sent in
response to a request from the driver. This report contains property data including the sensor’s change-
sensitivity setting, its report interval, and its reporting state. An input report is sent either upon request, or
asynchronously in response to an event. This report contains the actual sensor data. For example, for an
accelerometer, the report contains the G -forces along the x-, y-, and z-axes).
The HID class driver sends feature reports to the sensor. For example, when the application requests a new
change sensitivity or report interval, the driver packages these values into a feature report and uses this report
to send the request to the sensor’s firmware.
The following diagram illustrates the I/O model:

Sample Report Descriptor


If your sensor supports one of the seven categories native to the class driver, its firmware will need to support
specific feature and input reports. The feature reports include a sensor’s current reporting state, its status, change
sensitivity, and reporting interval (in addition to other possible properties). The input reports contain sensor
readings: True or False for a switch, G -force values for an accelerometer or LUX for an ambient light sensor.
Sample accelerometer feature report
The following code example shows the HID feature report for the accelerometer. Note the self-descriptive nature
of this report. It includes minimum and maximum values and the count and size of individual fields.

//feature reports (xmit/receive)


HID_USAGE_PAGE_SENSOR,
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
HID_LOGICAL_MIN_8(0x00), //LOGICAL_MINIMUM (0)
HID_LOGICAL_MAX_8(0xFF), //LOGICAL_MAXIMUM (255)
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(1),
HID_FEATURE(Data_Var_Abs),

HID_USAGE_SENSOR_PROPERTY_SENSOR_STATUS,
HID_LOGICAL_MIN_8(0x00), //LOGICAL_MINIMUM (0)
HID_LOGICAL_MAX_8(0xFF), //LOGICAL_MAXIMUM (255)
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(1),
HID_FEATURE(Data_Var_Abs),

HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_ABS,
HID_LOGICAL_MIN_8(0x00), //LOGICAL_MINIMUM (0)
HID_LOGICAL_MAX_16(0xFF,0xFF), //LOGICAL_MAXIMUM (65535)
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(1),
HID_USAGE_SENSOR_UNITS_G,
HID_UNIT_EXPONENT(0xE),
HID_FEATURE(Data_Var_Abs),

HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
HID_LOGICAL_MIN_8(0x00), //LOGICAL_MINIMUM (0)
HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF), //LOGICAL_MAXIMUM (4294967295)
HID_REPORT_SIZE(32),
HID_REPORT_COUNT(1),
HID_USAGE_SENSOR_UNITS_MILLISECOND,
HID_UNIT_EXPONENT(0),
HID_FEATURE(Data_Var_Abs),

Sample accelerometer input report


The following code example shows the HID input report for the same device. Again, note the self-descriptive
nature of the fields in this report.
//input reports (transmit)
HID_USAGE_PAGE_SENSOR,
HID_USAGE_SENSOR_STATE,
HID_LOGICAL_MIN_8(0x00), //LOGICAL_MINIMUM (0)
HID_LOGICAL_MAX_8(0xFF), //LOGICAL_MAXIMUM (255)
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(1),
HID_INPUT(Data_Var_Abs),

HID_USAGE_SENSOR_EVENT,
HID_LOGICAL_MIN_8(0x00), //LOGICAL_MINIMUM (0)
HID_LOGICAL_MAX_8(0xFF), //LOGICAL_MAXIMUM (255)
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(1),
HID_INPUT(Data_Var_Abs),

HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_X_AXIS,
HID_LOGICAL_MIN_16(0x01,0x80), // LOGICAL_MINIMUM (-32767)
HID_LOGICAL_MAX_16(0xFF,0x7F), // LOGICAL_MAXIMUM (32767)
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(1),
HID_USAGE_SENSOR_UNITS_G,
HID_UNIT_EXPONENT(0xE),
HID_INPUT(Data_Var_Abs),

HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Y_AXIS,
HID_LOGICAL_MIN_16(0x01,0x80), // LOGICAL_MINIMUM (-32767)
HID_LOGICAL_MAX_16(0xFF,0x7F), // LOGICAL_MAXIMUM (32767)
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(1),
HID_USAGE_SENSOR_UNITS_G,
HID_UNIT_EXPONENT(0xE),
HID_INPUT(Data_Var_Abs),

HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Z_AXIS,
HID_LOGICAL_MIN_16(0x01,0x80), // LOGICAL_MINIMUM (-32767)
HID_LOGICAL_MAX_16(0xFF,0x7F), // LOGICAL_MAXIMUM (32767)
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(3),
HID_USAGE_SENSOR_UNITS_G,
HID_UNIT_EXPONENT(0xE),
HID_INPUT(Data_Var_Abs),

HID_USAGE_SENSOR_DATA_MOTION_INTENSITY,
HID_LOGICAL_MIN_8(0x00), //LOGICAL_MINIMUM (0)
HID_LOGICAL_MAX_8(0xFF), //LOGICAL_MAXIMUM (255)
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(1),
HID_INPUT(Data_Var_Abs),
Airplane mode radio management
12/5/2018 • 4 minutes to read • Edit Online

Starting with Windows 8, the Windows operating system provides support via HID, for airplane mode radio
management controls.

Architecture and overview


The objective of airplane mode is to allow the PC manufacturer to provide a button or switch (and potentially an
LED to indicate status) that enables an end user to turn on/off all wireless controls in one shot. This primarily
empowers a user who need to turn airplane mode on/off to do to so in a programmatic way allowing the operating
system to (a) identify the status of switch and (b) control the various wireless radios via software.
Windows provides support for the following HID Usages on the Generic Desktop usage page.

USAGE ID USAGE NAME USAGE TYPE

0x000C Wireless Radio Controlls CollectionApplication (CA)

0x00C6 Wireless Radio Button On/Off Control (OOC)

0x00C7 Wireless Radio LED On/Off Control (OOC)

0x00C8 Wireless Radio Slider Switch On/Off Control (OOC)

The following is an architectural diagram of the HID Client that provides support for Radio Management /
Airplane Mode.

ShellHW Detection service (SHSVCD.dll) is the HID Client Driver/Service that runs in user mode and provides
support for the Radio Management device. It monitors for the presence of a HID Top Level Collection of type
USAGE_PAGE (Generic Desktop) 05 01
USAGE (Wireless Radio Controls) 09 0C
Sample report descriptor
The following section provides sample report descriptors that PC Manufacturers must leverage. Please note that if
the Top Level Collection is part of a report descriptor that already has another Top Level Collection, a Report ID
MUST be included (not shown in samples below ).
The following section provides additional information for PC manufacturers and identifies which report descriptor
sample is most appropriate for their system design:
The stateless button is often use on keyboard consumer control buttons (either standalone or in conjunction
with the Function button on many mobile systems (e.g. Fn+F5)).
The slider switch is often used on mobile systems with a physical slider on/off switch (e.g. laptops with an on
airplane mode on/off switch).
The LED is often used as stand alone airplane more indicator or in conjunction with the either stateless button
or slider switch. Window users do not need the use of this LED on mobile form factor systems as there is visual
indication in the UI around airplane mode.
Stateless Button without LED

USAGE_PAGE (Generic Desktop) 05 01


USAGE (Wireless Radio Controls) 09 0C
COLLECTION (Application) A1 01
LOGICAL_MINIMUM (0) 15 00
LOGICAL_MAXIMUM (1) 25 01
USAGE (Wireless Radio Button) 09 C6
REPORT_COUNT (1) 95 01
REPORT_SIZE (1) 75 01
INPUT (Data,Var,Rel) 81 06
REPORT_SIZE (7) 75 07
INPUT (Cnst,Var,Abs) 81 03
END_COLLECTION C0

Stateless Button with LED

USAGE_PAGE (Generic Desktop) 05 01


USAGE (Wireless Radio Controls) 09 0C
COLLECTION (Application) A1 01
LOGICAL_MINIMUM (0) 15 00
LOGICAL_MAXIMUM (1) 25 01
USAGE (Wireless Radio Button) 09 C6
REPORT_COUNT (1) 95 01
REPORT_SIZE (1) 75 01
INPUT (Data,Var,Rel) 81 06
REPORT_SIZE (7) 75 07
INPUT (Cnst,Var,Abs) 81 03
USAGE (Wireless Radio LED) 09 C7
REPORT_SIZE (1) 75 01
OUTPUT (Data,Var,Rel) 91 02
REPORT_SIZE (7) 75 07
OUTPUT (Cnst,Var,Abs) 91 03
END_COLLECTION C0

Slider Switch (without LED )


USAGE_PAGE (Generic Desktop) 05 01
USAGE (Wireless Radio Controls) 09 0C
COLLECTION (Application) A1 01
LOGICAL_MINIMUM (0) 15 00
LOGICAL_MAXIMUM (1) 25 01
USAGE (Wireless Radio Slider Switch) 09 C8
REPORT_COUNT (1) 95 01
REPORT_SIZE (1) 75 01
INPUT (Data,Var,Abs) 81 02
REPORT_SIZE (7) 75 07
INPUT (Cnst,Var,Abs) 81 03
END_COLLECTION C0

Slider Switch with LED

USAGE_PAGE (Generic Desktop) 05 01


USAGE (Wireless Radio Controls) 09 0C
COLLECTION (Application) A1 01
LOGICAL_MINIMUM (0) 15 00
LOGICAL_MAXIMUM (1) 25 01
USAGE (Wireless Radio Slider Switch) 09 C8
REPORT_COUNT (1) 95 01
REPORT_SIZE (1) 75 01
INPUT (Data,Var,Abs) 81 02
REPORT_SIZE (7) 75 07
INPUT (Cnst,Var,Abs) 81 03
USAGE (Wireless Radio LED) 09 C7
REPORT_SIZE (1) 75 01
OUTPUT (Data,Var,Rel) 91 02
REPORT_SIZE (7) 75 07
OUTPUT (Cnst,Var,Abs) 91 03
END_COLLECTION C0

LED Only (No button or slider )

USAGE_PAGE (Generic Desktop) 05 01


USAGE (Wireless Radio Controls) 09 0C
COLLECTION (Application) A1 01
LOGICAL_MINIMUM (0) 15 00
LOGICAL_MAXIMUM (1) 25 01
USAGE (Wireless Radio LED) 09 C7
REPORT_COUNT (1) 95 01
REPORT_SIZE (1) 75 01
OUTPUT (Data,Var,Rel) 91 02
REPORT_SIZE (7) 75 07
OUTPUT (Cnst,Var,Abs) 91 03
END_COLLECTION C0

Troubleshooting common errors


Tip #1: When using a radio manager BUTTON, the PC manufacturer should send one HID report when the button
is released and not when the button is pressed. This is because the toggle button is generally a relative input and
not an absolute one.
Tip #2: Airplane Mode radio management HID usages only operate on Mobile systems (battery powered) and
require Windows 8 or later versions of Windows.
Tip #3: For more information on the Airplane Mode radio management button, see the Keyboard Enhancements to
Windows 8 whitepaper.
Tip #4: For more information regarding the buttons, and to ensure that you are implementing the correct
hardware, please review the Windows 8 System Logo Requirements.
Display brightness control
12/5/2018 • 2 minutes to read • Edit Online

Starting with Windows 8, a standardized solution has been added to allow keyboards (external or embedded on
laptops), to control a laptop’s or tablet’s screen brightness through HID.
This solution is described in the HID committee's recently approved HID Review Request 41.

Architecture and overview


Windows 8 provides support for screen brightness increase/decrease as part of the consumer controls top level
collection. Windows 8 supports the HID usages listed in the following table:

USAGE ID USAGE NAME USAGE TYPE

0x006F Brightness Increment Re-trigger Control (RTC)

0x0070 Brightness Decrement Re-trigger Control (RTC)

Note These HID usages operate only on mobile systems (battery powered) and require Windows 8.

Sample report descriptor


The following section provides sample report descriptors that PC Manufacturers must leverage. Please note that if
the Top Level Collection is part of a report descriptor that already has another Top Level Collection, a Report ID
MUST be included (not shown in samples below ).

Usage Page (Consumer)


Usage (Consumer Control)
Collection (Application)
Logical Minimum (0x00)
Logical Maximum (0x3FF)
Usage Minimum (0x00)
Usage Maximum (0x3FF)
Report Size (16)
Report Count (1)
Input (Data, Array, Absolute)
End Collection

Important Notes
When a user presses a key, an input report is generated to identify the key. When the key is released an input
report with usage value=0 is issued.
Only one usage is active and sent at a time. Consumer controls do not allow multiple buttons to be pressed
simultaneously. When a new usage is sent, it is assumed that the usage for the previous key is released.
Brightness up/down are retriggering keys and their rate of repeat is handled by Windows. Hardware should not
keep resending the usage when these keys are kept depressed by user. Hardware should only send an input
report when button is pressed down and another when the key is released.

Troubleshooting common errors


Tip #1: Brightness increment/decrement HID usages only operate only on Mobile systems (battery powered) and
require Windows 8.
Tip #2: If the system is attached to an external monitor, the brightness increment/decrement will not function as
legacy monitor transports do not support the ability to channel HID messages to them / from them.
HID Transports
12/5/2018 • 2 minutes to read • Edit Online

HID transports supported in current and previous versions of Windows.

TRANSPORT IN-BOX MINIDRIVER VERSION NOTES

USB Hidusb.sys Windows 7 and later. Support for USB HID 1.11+
is provided on Windows
operating systems dating
back to Windows 2000.

Bluetooth Hidbth.sys Windows 7 and later. Support for Bluetooth HID


1.1+ is provided on
Windows operating systems
dating back to Windows
Vista.

Bluetooth LE HidBthLE.dll Windows 8 and later. Windows 8 introduces


support for HID over
Bluetooth LE.

I²C Hidi2c.sys Windows 8 and later. Windows 8 introduces


support for HID over I2C.

GPIO Hidinterrupt.sys Windows 10 and later. Windows Windows 10


introduces support for
general-purpose I/O (GPIO)
buttons.

Microsoft recommends that whenever possible, you use in-box drivers for the transports listed in the preceding
table.
If your device requires a transport other than USB, Bluetooth, Bluetooth LE, or I²C, you can develop a miniport
driver which is described in the Transport Minidrivers topic

HID transport limits


Report Descriptor Length
A transport minidriver submits report descriptors to Hidclass in a HID_DESCRIPTOR structure.
Regardless of the size defined by the transport protocol for transferring HID report descriptor with their
devices, the actual report descriptor size is limited during the communication between Hidclass and HID
minidrivers.
TLCs in a Report Descriptor
The Hidclass/Hidparse driver pair is aware of the number of TLCs in a Report Descriptor. HID miniport
drivers do not know that information. Each TLC has at least 2 bytes to start a collection and 1 byte to end
the collection.
Input/Output/Feature Report Length
The Hidclass/Hidparse driver pair defines lengths of HID Input, Output, and Feature Reports. The limit is 8
KB (minus 1 bit). Even if a HID minidriver can request a transfer of more than 8 KB for a report, only
reports smaller than 8 KB are successfully transferred.

TLCS IN ONE REPORT INPUT/OUTPUT/FEATURE


IN-BOX MINIDRIVER REPORT DESCRIPTOR LENGTH DESCRIPTOR REPORT LENGTH

Hidclass/Hidparse 65535 bytes 21845 8 KB - 1 bit

Hidusb 65535 bytes N/A 64 KB

Hidbth 65535 bytes N/A 64 KB

HidBthLE 65535 bytes N/A 64 KB

Hidi2c 65535 bytes N/A 64 KB


ACPI button device
12/5/2018 • 12 minutes to read • Edit Online

The generic button device is a standard device for reporting button events through hardware interrupts, and
mapping those interrupts to specific usages defined in the Human Interface Device (HID ) specification.
In order to express the functionality of a button to the operating system, two pieces of information are required:
Usage of the HID Control
Usage of the HID Collection in which the Control belongs
A Usage is a combination of a Usage Page and Usage ID. For example, the Volume Up button is identified as the
Volume Up Usage (Usage Page 0x0C, Usage Id 0xE9) in the Consumer Control Collection (Usage Page 0x0C,
Usage Id 0x01).
ACPI device Id of a generic button device is ACPI0011. Windows loads the Microsoft-provided in-box driver,
Hidinterrupt.sys for that device.
For more information about the generic button device, visit the Unified Extensible Firmware Interface
specifications web site, and download the ACPI Specification Version 6.0 PDF document. Then use the left-hand
pane to navigate to Section 9.19.

Sample buttons ACPI for phone/tablet


Example for describing buttons in ACPI for phone/tablet device running Windows 10 Mobile.

// Sample Buttons ACPI for Phone/Tablet device running Windows 10 Mobile.

Device(BTNS)
{
Name(_HID, "ACPI0011")
Name(_CRS, ResourceTemplate() {
GpioInt(Edge, ActiveBoth,...) {pin} // Index 0: Power Button
GpioInt(Edge, ActiveBoth,...) {pin} // Index 1: Volume Up Button
GpioInt(Edge, ActiveBoth,...) {pin} // Index 2: Volume Down Button
GpioInt(Edge, ActiveHigh,...) {pin} // Index 3: Camera Auto-focus Button
GpioInt(Edge, ActiveLow,...) {pin} // Index 4: Camera Shutter Button
GpioInt(Edge, ActiveBoth,...) {pin} // Index 5: Back Button
GpioInt(Edge, ActiveBoth,...) {pin} // Index 6: Windows/Home Button
GpioInt(Edge, ActiveBoth,...) {pin} // Index 7: Search Button
})
Name(_DSD, Package(2) {
//UUID for HID Button Descriptors:
ToUUID("FA6BD625-9CE8-470D-A2C7-B3CA36C4282E"),
//Data structure for this UUID:
Package(9) {
Package(5) {
0, // This is a Collection
1, // Unique ID for this Collection
0, // This is a Top-Level Collection
0x01, // Usage Page ("Generic Desktop Page")
0x0D // Usage ("Portable Device Control")
},
Package(5) {
1, // This is a Control
0, // Interrupt index in _CRS for Power Button
1, // Unique ID of Parent Collection
0x01, // Usage Page ("Generic Desktop Page")
0x81 // Usage ("System Power Down")
0x81 // Usage ("System Power Down")
},
Package(5) {
1, // This is a Control
1, // Interrupt index in _CRS for Volume Up Button
1, // Unique ID of Parent Collection
0x0C, // Usage Page ("Consumer Page")
0xE9 // Usage ("Volume Increment")
},
Package(5) {
1, // This is a Control
2, // Interrupt index in _CRS for Volume Down Button
1, // Unique ID of Parent Collection
0x0C, // Usage Page ("Consumer Page")
0xEA // Usage ("Volume Decrement")
},
Package(5) {
1, // This is a Control
3, // Interrupt index in _CRS for Camera Auto-focus Button
1, // Unique ID of Parent Collection
0x90, // Usage Page ("Camera Control Page")
0x20 // Usage ("Camera Auto-focus")
},
Package(5) {
1, // This is a Control
4, // Interrupt index in _CRS for Camera Shutter Button
1, // Unique ID of Parent Collection
0x90, // Usage Page ("Camera Control Page")
0x21 // Usage ("Camera Shutter")
},
Package(5) {
1, // This is a Control
5, // Interrupt index in _CRS for Back Button
1, // Unique ID of Parent Collection
0x0C, // Usage Page ("Consumer Page")
0x224 // Usage ("AC Back")
},
Package(5) {
1, // This is a Control
6, // Interrupt index in _CRS for Windows/Home Button
1, // Unique ID of Parent Collection
0x07, // Usage Page ("Keyboard Page")
0xE3 // Usage ("Keyboard Left GUI")
},
Package(5) {
1, // This is a Control
7, // Interrupt index in _CRS for Search Button
1, // Unique ID of Parent Collection
0x0C, // Usage Page ("Consumer Page")
0x221 // Usage ("AC Search")
}
}
})
}

//
// This HID Report Descriptor describes a 1-byte input report for the 8
// buttons supported on Windows 10 Mobile. Following are the buttons and
// their bit positions in the input report:
// Bit 0: Power Button
// Bit 1: Volume Up Button
// Bit 2: Volume Down Button
// Bit 3: Camera Auto-focus Button
// Bit 4: Camera Shutter Button
// Bit 5: Back Button
// Bit 6: Windows/Home Button
// Bit 7: Search Button
//
// The Report Descriptor also defines a 1-byte Control Enable/Disable
// feature report of the same size and bit positions as the Input Report.
// feature report of the same size and bit positions as the Input Report.
// For a Get Feature Report, each bit in the report conveys whether the
// corresponding Control (i.e. button) is currently Enabled (1) or
// Disabled (0). For a Set Feature Report, each bit in the report conveys
// whether the corresponding Control (i.e. button) should be Enabled (1)
// or Disabled (0).
//

UCHAR ReportDescriptor[] = {

15, 00, // LOGICAL_MINIMUM (0)


25, 01, // LOGICAL_MAXIMUM (1)
75, 01, // REPORT_SIZE (1)

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 01, // COLLECTION (Application)
85, 01, // REPORT_ID (1) (For Input Report & Feature Report)

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 02, // COLLECTION (Logical)
06, 01, // USAGE_PAGE (Generic Desktop)
0A, 81, // USAGE (System Power Down) // Power Button
95, 01, // REPORT_COUNT (1)
81, 02, // INPUT (Data,Var,Abs)
05, 01, // USAGE_PAGE (Generic Desktop)
09, CB, // USAGE (Control Enable)
95, 01, // REPORT_COUNT (1)
B1, 02, // FEATURE (Data,Var,Abs)
C0, // END_COLLECTION

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 02, // COLLECTION (Logical)
06, 0C, // USAGE_PAGE (Consumer Devices)
0A, E9, // USAGE (Volume Increment) // Volume Up Button
95, 01, // REPORT_COUNT (1)
81, 02, // INPUT (Data,Var,Abs)
05, 01, // USAGE_PAGE (Generic Desktop)
09, CB, // USAGE (Control Enable)
95, 01, // REPORT_COUNT (1)
B1, 02, // FEATURE (Data,Var,Abs)
C0, // END_COLLECTION

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 02, // COLLECTION (Logical)
06, 0C, // USAGE_PAGE (Consumer Devices)
0A, EA, // USAGE (Volume Decrement) // Volume Down Button
95, 01, // REPORT_COUNT (1)
81, 02, // INPUT (Data,Var,Abs)
05, 01, // USAGE_PAGE (Generic Desktop)
09, CB, // USAGE (Control Enable)
95, 01, // REPORT_COUNT (1)
B1, 02, // FEATURE (Data,Var,Abs)
C0, // END_COLLECTION

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 02, // COLLECTION (Logical)
06, 90, // USAGE_PAGE (Camera Control)
0A, 20, // USAGE (Camera Auto-focus) // Camera Auto-focus Button
95, 01, // REPORT_COUNT (1)
81, 02, // INPUT (Data,Var,Abs)
05, 01, // USAGE_PAGE (Generic Desktop)
09, CB, // USAGE (Control Enable)
95, 01, // REPORT_COUNT (1)
B1, 02, // FEATURE (Data,Var,Abs)
C0, // END_COLLECTION

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 02, // COLLECTION (Logical)
06, 90, // USAGE_PAGE (Camera Control)
0A, 21, // USAGE (Camera Shutter) // Camera Shutter Button
95, 01, // REPORT_COUNT (1)
81, 02, // INPUT (Data,Var,Abs)
05, 01, // USAGE_PAGE (Generic Desktop)
09, CB, // USAGE (Control Enable)
95, 01, // REPORT_COUNT (1)
B1, 02, // FEATURE (Data,Var,Abs)
C0, // END_COLLECTION

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 02, // COLLECTION (Logical)
06, 0C, // USAGE_PAGE (Consumer Page)
0A, 224, // USAGE (AC Back) // Back Button
95, 01, // REPORT_COUNT (1)
81, 02, // INPUT (Data,Var,Abs)
05, 01, // USAGE_PAGE (Generic Desktop)
09, CB, // USAGE (Control Enable)
95, 01, // REPORT_COUNT (1)
B1, 02, // FEATURE (Data,Var,Abs)
C0, // END_COLLECTION

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 02, // COLLECTION (Logical)
06, 07, // USAGE_PAGE (Keyboard)
0A, E3, // USAGE (Keyboard Left GUI) // Windows/Home Button
95, 01, // REPORT_COUNT (1)
81, 02, // INPUT (Data,Var,Abs)
05, 01, // USAGE_PAGE (Generic Desktop)
09, CB, // USAGE (Control Enable)
95, 01, // REPORT_COUNT (1)
B1, 02, // FEATURE (Data,Var,Abs)
C0, // END_COLLECTION

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 02, // COLLECTION (Logical)
06, 0C, // USAGE_PAGE (Consumer)
0A, 221, // USAGE (AC Search) // Search Button
95, 01, // REPORT_COUNT (1)
81, 02, // INPUT (Data,Var,Abs)
05, 01, // USAGE_PAGE (Generic Desktop)
09, CB, // USAGE (Control Enable)
95, 01, // REPORT_COUNT (1)
B1, 02, // FEATURE (Data,Var,Abs)
C0, // END_COLLECTION

C0 // END_COLLECTION
};

//
// This HID Report Descriptor describes a 1-byte Input Report for the 3
// Headset buttons supported on Windows 10 Mobile. Following are the
// buttons and their bit positions in the Input Report:
// Bit 0: HeadSet : Middle Button
// Bit 1: HeadSet : Volume Up Button
// Bit 2: HeadSet : Volume Down Button
// Bit 3: Unused
// Bit 4: Unused
// Bit 5: Unused
// Bit 6: Unused
// Bit 7: Unused
//

UCHAR ReportDescriptor[] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop Controls)
0x09, 0x0D, // USAGE (Portable Device Buttons)
0xA1, 0x01, // COLLECTION (Application)
0x85, 0x01, // REPORT_ID (1)
0x05, 0x09, // USAGE_PAGE (Button Page)
0x09, 0x01, // USAGE (Button 1 - HeadSet : Middle Button)
0x09, 0x02, // USAGE (Button 2 - HeadSet : Volume Up Button)
0x09, 0x03, // USAGE (Button 3 - HeadSet : Volume Down Button)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x09, // REPORT_COUNT (3)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x07, // REPORT_COUNT (5) // 5 unused bits in 8-bit Input Report.
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0xC0, // END_COLLECTION
};

Sample buttons ACPI for desktop


Example for describing buttons in ACPI for phone/tablet device running Windows 10 for desktop editions (Home,
Pro, Enterprise, and Education).

Device(BTNS)
{
Name(_HID, "ACPI0011")
Name(_CRS, ResourceTemplate() {
GpioInt(Edge, ActiveBoth,...) {pin} // Index 0: Power Button
GpioInt(Edge, ActiveBoth,...) {pin} // Index 1: Volume Up Button
GpioInt(Edge, ActiveBoth,...) {pin} // Index 2: Volume Down Button
GpioInt(Edge, ActiveBoth,...) {pin} // Index 3: Windows/Home Button
GpioInt(Edge, ActiveBoth,...) {pin} // Index 4: Rotation Lock Button
})
Name(_DSD, Package(2) {
//UUID for HID Button Descriptors:
ToUUID("FA6BD625-9CE8-470D-A2C7-B3CA36C4282E"),
//Data structure for this UUID:
Package(6) {
Package(5) {
0, // This is a Collection
1, // Unique ID for this Collection
0, // This is a Top-Level Collection
0x01, // Usage Page ("Generic Desktop Page")
0x0D // Usage ("Portable Device Control")
},
Package(5) {
1, // This is a Control
0, // Interrupt index in _CRS for Power Button
1, // Unique ID of Parent Collection
0x01, // Usage Page ("Generic Desktop Page")
0x81 // Usage ("System Power Down")
},
Package(5) {
1, // This is a Control
1, // Interrupt index in _CRS for Volume Up Button
1, // Unique ID of Parent Collection
0x0C, // Usage Page ("Consumer Page")
0xE9 // Usage ("Volume Increment")
},
Package(5) {
1, // This is a Control
2, // Interrupt index in _CRS for Volume Down Button
2, // Interrupt index in _CRS for Volume Down Button
1, // Unique ID of Parent Collection
0x0C, // Usage Page ("Consumer Page")
0xEA // Usage ("Volume Decrement")
},
Package(5) {
1, // This is a Control
3, // Interrupt index in _CRS for Windows/Home Button
1, // Unique ID of Parent Collection
0x07, // Usage Page ("Keyboard Page")
0xE3 // Usage ("Keyboard Left GUI")
},
Package(5) {
1, // This is a Control
4, // Interrupt index in _CRS for Rotation Lock Button
1, // Unique ID of Parent Collection
0x01, // Usage Page ("Generic Desktop Page")
0xCA // Usage ("System Display Rotation Lock Slider Switch")
}
}
})
}

//
// This HID Report Descriptor describes a 1-byte input report for the 5
// buttons supported on Windows 10 for desktop editions (Home, Pro, and Enterprise). Following are the buttons
and
// their bit positions in the input report:
// Bit 0 - Windows/Home Button
// Bit 1 - Power Button
// Bit 2 - Volume Up Button
// Bit 3 - Volume Down Button
// Bit 4 - Rotation Lock Slider switch
// Bit 5 - Unused
// Bit 6 - Unused
// Bit 7 - Unused
//
// The Report Descriptor also defines a 1-byte Control Enable/Disable
// feature report of the same size and bit positions as the Input Report.
// For a Get Feature Report, each bit in the report conveys whether the
// corresponding Control (i.e. button) is currently Enabled (1) or
// Disabled (0). For a Set Feature Report, each bit in the report conveys
// whether the corresponding Control (i.e. button) should be Enabled (1)
// or Disabled (0).
//

UCHAR ReportDescriptor[] = {

15, 00, // LOGICAL_MINIMUM (0)


25, 01, // LOGICAL_MAXIMUM (1)
75, 01, // REPORT_SIZE (1)

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 01, // COLLECTION (Application)
85, 01, // REPORT_ID (1) (For Input Report & Feature Report)

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 02, // COLLECTION (Logical)
06, 07, // USAGE_PAGE (Keyboard)
0A, E3, // USAGE (Keyboard LGUI) // Windows/Home Button
95, 01, // REPORT_COUNT (1)
81, 02, // INPUT (Data,Var,Abs)
05, 01, // USAGE_PAGE (Generic Desktop)
09, CB, // USAGE (Control Enable)
95, 01, // REPORT_COUNT (1)
B1, 02, // FEATURE (Data,Var,Abs)
C0, // END_COLLECTION
06, 01, // USAGE_PAGE (Generic Desktop)
0A, 0D, // USAGE (Portable Device Control)
A1, 02, // COLLECTION (Logical)
06, 01, // USAGE_PAGE (Generic Desktop)
0A, 81, // USAGE (System Power Down) // Power Button
95, 01, // REPORT_COUNT (1)
81, 02, // INPUT (Data,Var,Abs)
05, 01, // USAGE_PAGE (Generic Desktop)
09, CB, // USAGE (Control Enable)
95, 01, // REPORT_COUNT (1)
B1, 02, // FEATURE (Data,Var,Abs)
C0, // END_COLLECTION

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 02, // COLLECTION (Logical)
06, 0C, // USAGE_PAGE (Consumer Devices)
0A, E9, // USAGE (Volume Increment) // Volume Up Button
95, 01, // REPORT_COUNT (1)
81, 02, // INPUT (Data,Var,Abs)
05, 01, // USAGE_PAGE (Generic Desktop)
09, CB, // USAGE (Control Enable)
95, 01, // REPORT_COUNT (1)
B1, 02, // FEATURE (Data,Var,Abs)
C0, // END_COLLECTION

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 02, // COLLECTION (Logical)
06, 0C, // USAGE_PAGE (Consumer Devices)
0A, EA, // USAGE (Volume Decrement) // Volume Down Button
95, 01, // REPORT_COUNT (1)
81, 02, // INPUT (Data,Var,Abs)
05, 01, // USAGE_PAGE (Generic Desktop)
09, CB, // USAGE (Control Enable)
95, 01, // REPORT_COUNT (1)
B1, 02, // FEATURE (Data,Var,Abs)
C0, // END_COLLECTION

06, 01, // USAGE_PAGE (Generic Desktop)


0A, 0D, // USAGE (Portable Device Control)
A1, 02, // COLLECTION (Logical)
06, 01, // USAGE_PAGE (Generic Desktop)
0A, CA, // USAGE (System Display Rotation Lock Slider Switch) // Rotation Lock Button
95, 01, // REPORT_COUNT (1)
81, 02, // INPUT (Data,Var,Abs)
95, 06, // REPORT_COUNT (3) // 3 unused bits in 8-bit Input Report
81, 03, // INPUT (Cnst,Var,Abs)
05, 01, // USAGE_PAGE (Generic Desktop)
09, CB, // USAGE (Control Enable)
95, 01, // REPORT_COUNT (1)
B1, 02, // FEATURE (Data,Var,Abs)
95, 06, // REPORT_COUNT (3) // 3 unused bits in 8-bit Feature Report
B1, 03, // FEATURE (Cnst,Var,Abs)
C0, // END_COLLECTION

C0 // END_COLLECTION
};
HID button drivers
12/5/2018 • 3 minutes to read • Edit Online

Summary
Describe a GPIO button in ACPI and load Microsoft-provided driver
Write a HID source driver in kernel mode for non-GPIO button
Write a UMDF HID Minidriver for a non-GPIO button
Applies to
Windows 10
Driver developers of HID button devices
Important APIs
Virtual HID Framework Reference
UMDF HID Minidriver IOCTLs
Use the Microsoft-provided button driver for GPIO buttons; otherwise, implement your driver that injects HID
data to the operating system.
Buttons (Power, Windows, volume and rotation lock) are typically used for tasks that occur while the physical
keyboard is not available to the user, on form factors such as convertibles or slates. Buttons declare themselves to
the operating system as HID devices by supplying HID button report descriptors. This allows the system to
interpret the purpose and events of those buttons in a standardized way. When a button state changes, that event
is mapped to a HID Usages. A HID transport minidriver reports those events to upper-level drivers that then send
details to HID clients in user mode or kernel mode.
For physical general-purpose I/O (GPIO ) buttons, the HID transport minidriver is a Microsoft-provided in-box
driver that reports the events based on the interrupts that are received on the defined GPIO hardware resources.
The in-box driver cannot service a button that is not wired to an interrupt line. For such buttons, you need to write
a driver that exposes the button as a HID button and reports state changes to the HID class driver (Microsoft-
provided). Your driver could be a HID source driver or a HID transport driver.

Guidance for supporting HID buttons


Here are some general pointers to help you decide which implementation you should follow if you are creating
HID buttons.
Use the Microsoft-provided in-box button driver If you are implementing a GPIO button, describe the
button in the system ACPI so that Windows can load the
in-box driver, Hidinterrupt.sys, as the button driver that
reports events to the operating system.
ACPI button device
Button Behavior
Sample buttons ACPI for phone/tablet
Sample buttons ACPI for desktop
Microsoft encourages you to use the in-box transport-
minidrivers whenever possible.
Write a HID source driver in kernel mode If you are implementing a non-GPIO button such as a
stream of data in the HID format that needs to be injected
by another software component, you can choose to write
a kernel-mode driver. Starting in Windows 10, you can
write a HID source driver by calling programming
interfaces that communicate with Virtual HID Framework
(VHF) and gets and sets HID Reports to and from the HID
class driver.
How to write a HID source driver that interacts with
Virtual HID Framework (VHF)
Virtual HID Framework Reference
Alternately, you can write a kernel-mode HID transport
minidriver as supported by the earlier versions of
Windows. However, we do not recommend this approach
because poorly written KMDF HID transport minidrivers
can crash the system.
Transport Minidrivers
HID Minidriver IOCTLs

Write a UMDF HID Minidriver If you are implementing a non-GPIO button, instead of
using preceding model of writing a HID source driver, you
can write a HID transport minidriver in user mode. These
drivers are easier to develop than kernel-mode drivers
and errors in this driver do not bug check the whole
system.
Creating UMDF HID Minidrivers
UMDF HID Minidriver IOCTLs

Universal Windows drivers for HID buttons


Starting with Windows 10, the HID driver programming interfaces are part of OneCoreUAP -based editions of
Windows. By using that common set of interfaces, you can write a button driver by using Virtual HID Framework
or Transport Minidrivers interfaces. Those drivers will run on both Windows 10 for desktop editions (Home, Pro,
Enterprise, and Education) and Windows 10 Mobile, as well as other Windows 10 versions.
For step-by-step guidance, see Getting Started with Universal Windows drivers.

Related topics
Human Interface Device
Write a HID source driver by using Virtual HID
Framework (VHF)
5/8/2019 • 10 minutes to read • Edit Online

Summary
Write a Kernel-Mode Driver Framework (KMDF )HID source driver that submits HID Read Reports to the
operating system.
Load the VHF driver as the lower filter to the HID source driver in the virtual HID device stack.
Applies to
Windows 10
Driver developers for HID devices
Important APIs
Virtual HID Framework Callback Functions
Virtual HID Framework Methods
Virtual HID Framework Structures
Learn about writing a HID source driver that reports HID data to the operating system.
A HID input device, such as – a keyboard, mouse, pen, touch, or button, sends various reports to the operating
system so that it can understand the purpose of the device and take necessary action. The reports are in the form
of HID collections and HID Usages. The device sends those reports over various transports, some of which are
supported by Windows, such as HID over I2C and HID over USB. In some cases, the transport might not be
supported by Windows, or the reports might not directly map to real hardware. It can be a stream of data in the
HID format that is sent by another software component for virtual hardware such as, for non-GPIO buttons or
sensors. For example, consider accelerometer data from a phone that is behaving as a game controller, sent
wirelessly to a PC. In another example, a computer can receive remote input from a Miracast device by using the
UIBC protocol.
In previous versions of Windows, to support new transports (real hardware or software), you had to write a HID
transport minidriver and bind it to the Microsoft-provided in-box class driver, Hidclass.sys. The class/mini driver
pair provided the HID collections, such as Top-Level Collections to upper-level drivers and user-mode applications.
In that model, the challenge was writing the minidriver, which can be a complex task.
Starting in Windows 10, the new Virtual HID Framework (VHF ) eliminates the need to write a transport
minidriver. Instead you can write a HID source driver by using KMDF or WDM programming interfaces. The
framework consists of a Microsoft-provided static library that exposes programming elements used by your driver.
It also includes a Microsoft-provided in-box driver that enumerates one or more child devices and proceeds to
build and manage a virtual HID tree.
Note In this release, VHF supports a HID source driver only in kernel mode.
This topic describes the architecture of the framework, the virtual HID device tree, and the configuration scenarios.

Virtual HID device tree


In this image, the device tree shows the drivers and their associated device objects.
HID source driver (your driver)
The HID source driver links to Vhfkm.lib and includes Vhf.h in its build project. The driver can be written by using
either Windows Driver Model (WDM ) or Kernel-Mode Driver Framework (KMDF ) that is part of the Windows
Driver Frameworks (WDF ). The driver can be loaded as a filter driver or a function driver in the device stack.
VHF static library (vhfkm.lib)
The static library is included in the Windows Driver Kit (WDK) for Windows 10. The library exposes programming
interfaces such as routines and callback functions that are used by your HID source driver. When your driver calls a
function, the static library forwards the request to the VHF driver that handles the request.
VHF driver (Vhf.sys)
A Microsoft-provided in-box driver. This driver must be loaded as a lower filter driver below your driver in the HID
source device stack. The VHF driver dynamically enumerates child devices and creates physical device objects
(PDO ) for one or more HID devices that are specified by your HID source driver. It also implements the HID
Transport mini-driver functionality of the enumerated child devices.
HID class driver pair (Hidclass.sys, Mshidkmdf.sys)
The Hidclass/Mshidkmdf pair enumerates Top-Level Collections (TLC ) similar to how it enumerates those
collections for a real HID device. A HID client can continue to request and consume the TLCs just like a real HID
device. This driver pair is installed as the function driver in the device stack.
Note In some scenarios, a HID client might need to identify the source of HID data. For example, a system has a
built-in sensor and receives data from a remote sensor of the same type. The system might want to choose one
sensor to be more reliable. To differentiate between the two sensors connected to the system, the HID client
queries for the container ID of the TLC. In this case, a HID source driver can provide the container ID, which is
reported as the container ID of the virtual HID device by VHF.
HID client (application)
Queries and consumes the TLCs that are reported by the HID device stack.

Header and library requirements


This procedure describes how to write a simple HID source driver that reports headset buttons to the operating
system. In this case, the driver that implements this code can be an existing KMDF audio driver that has been
modified to act as a HID source reporting headset buttons by using VHF.
1. Include Vhf.h, included in the WDK for Windows 10.
2. Link to vhfkm.lib, included in the WDK.
3. Create a HID Report Descriptor that your device wants to report to the operating system. In this example, the
HID Report Descriptor describes the headset buttons. The report specifies a HID Input Report, size 8 bits (1
byte). The first three bits are for the headset middle, volume-up, and volume-down buttons. The remaining bits
are unused.

UCHAR HeadSetReportDescriptor[] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop Controls)
0x09, 0x0D, // USAGE (Portable Device Buttons)
0xA1, 0x01, // COLLECTION (Application)
0x85, 0x01, // REPORT_ID (1)
0x05, 0x09, // USAGE_PAGE (Button Page)
0x09, 0x01, // USAGE (Button 1 - HeadSet : middle button)
0x09, 0x02, // USAGE (Button 2 - HeadSet : volume up button)
0x09, 0x03, // USAGE (Button 3 - HeadSet : volume down button)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x05, // REPORT_COUNT (5)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0xC0, // END_COLLECTION
};

Create a virtual HID device


Initialize a VHF_CONFIG structure by calling the VHF_CONFIG_INIT macro and then call the VhfCreate
method. The driver must call VhfCreate at PASSIVE_LEVEL after the WdfDeviceCreate call, typically, in the
driver's EvtDriverDeviceAdd callback function.
In the VhfCreate call, the driver can specify certain configuration options, such as operations that must be
processed asynchronously or setting device information (vendor/product IDs).
For example, an application requests a TLC. When the HID class driver pair receives that request, the pair
determines the type of request and creates an appropriate HID Minidriver IOCTL request and forwards it to VHF.
Upon getting the IOCTL request, VHF can handle the request, rely on the HID source driver to process it, or
complete the request with STATUS_NOT_SUPPORTED.
VHF handles these IOCTLs:
IOCTL_HID_GET_STRING
IOCTL_HID_GET_DEVICE_ATTRIBUTES
IOCTL_HID_GET_DEVICE_DESCRIPTOR
IOCTL_HID_GET_REPORT_DESCRIPTOR
If the request is GetFeature, SetFeature, WriteReport, or GetInputReport, and the HID source driver
registered a corresponding callback function, VHF invokes the callback function. Within that function, the HID
source driver can get or set HID data for the HID virtual device. If the driver doesn't register a callback, VHF
completes the request with status STATUS_NOT_SUPPORTED.
VHF invokes HID source driver-implemented event callback functions for these IOCTLs:
IOCTL_HID_READ_REPORT
If the driver wants to handle the buffering policy while submitting a buffer to obtain HID Input Report, it
must implement the EvtVhfReadyForNextReadReport and specify a pointer in the
EvtVhfAsyncOperationGetInputReport member. For more information, see Submit the HID Input
Report.
IOCTL_HID_GET_FEATURE or IOCTL_HID_SET_FEATURE
If the driver wants to get or set a HID Feature Report asynchronously, the driver must implement the
EvtVhfAsyncOperation function and specify a pointer to the get or set implementation function in the
EvtVhfAsyncOperationGetFeature or EvtVhfAsyncOperationSetFeature member of VHF_CONFIG.
IOCTL_HID_GET_INPUT_REPORT
If the driver wants to get a HID Input Report asynchronously, the driver must implement the
EvtVhfAsyncOperation function and specify a pointer to the function in the
EvtVhfAsyncOperationGetInputReport member of VHF_CONFIG.
IOCTL_HID_WRITE_REPORT
If the driver wants to get a write a HID Input Report asynchronously, the driver must implement the
EvtVhfAsyncOperation function and specify a pointer to the function in the
EvtVhfAsyncOperationWriteReport member of VHF_CONFIG.
For any other HID Minidriver IOCTL, VHF completes the request with STATUS_NOT_SUPPORTED.
The virtual HID device is deleted by calling the VhfDelete. The EvtVhfCleanup callback is required if the driver
allocated resources for the virtual HID device. The driver must implement the EvtVhfCleanup function and specify
a pointer to that function in the EvtVhfCleanup member of VHF_CONFIG. EvtVhfCleanup is invoked before the
VhfDelete call completes. For more information, see Delete the virtual HID device.
Note After an asynchronous operation completes, the driver must call VhfAsyncOperationComplete to set the
results of the operation. You can call the method from the event callback or at a later time after returning from the
callback.
NTSTATUS
VhfSourceCreateDevice(
_Inout_ PWDFDEVICE_INIT DeviceInit
)

{
WDF_OBJECT_ATTRIBUTES deviceAttributes;
PDEVICE_CONTEXT deviceContext;
VHF_CONFIG vhfConfig;
WDFDEVICE device;
NTSTATUS status;

PAGED_CODE();

WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);
deviceAttributes.EvtCleanupCallback = VhfSourceDeviceCleanup;

status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);

if (NT_SUCCESS(status))
{
deviceContext = DeviceGetContext(device);

VHF_CONFIG_INIT(&vhfConfig,
WdfDeviceWdmGetDeviceObject(device),
sizeof(VhfHeadSetReportDescriptor),
VhfHeadSetReportDescriptor);

status = VhfCreate(&vhfConfig, &deviceContext->VhfHandle);

if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "VhfCreate failed %!STATUS!", status);
goto Error;
}

status = VhfStart(deviceContext->VhfHandle);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "VhfStart failed %!STATUS!", status);
goto Error;
}

Error:
return status;
}

Submit the HID input report


Submit the HID input report by calling VhfReadReportSubmit.
Typically, a HID device sends information about state changes by sending input reports through interrupts. For
example, the headset device might send a report when the state of a button changes. In such an event, the driver's
interrupt service routine (ISR ) is invoked. In that routine, the driver might schedule a deferred procedure call
(DPC ) that processes the input report and submits it to VHF, which sends the information to the operating system.
By default, VHF buffers the report and the HID source driver can start submitting HID Input Reports as they come
in. This and eliminates the need for the HID source driver to implement complex synchronization.
The HID source driver can submit input reports by implementing the buffering policy for pending reports. To
avoid duplicate buffering, the HID source driver can implement the EvtVhfReadyForNextReadReport callback
function and keep track of whether VHF invoked this callback. If it was previously invoked, the HID source driver
can call VhfReadReportSubmit to submit a report. It must wait for EvtVhfReadyForNextReadReport to get
invoked before it can call VhfReadReportSubmit again.

VOID
MY_SubmitReadReport(
PMY_CONTEXT Context,
BUTTON_TYPE ButtonType,
BUTTON_STATE ButtonState
)
{
PDEVICE_CONTEXT deviceContext = (PDEVICE_CONTEXT)(Context);

if (ButtonState == ButtonStateUp) {
deviceContext->VhfHidReport.ReportBuffer[0] &= ~(0x01 << ButtonType);
} else {
deviceContext->VhfHidReport.ReportBuffer[0] |= (0x01 << ButtonType);
}

status = VhfSubmitReadReport(deviceContext->VhfHandle, &deviceContext->VhfHidReport);

if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,"VhfSubmitReadReport failed %!STATUS!", status);
}
}

Delete the virtual HID device


Delete the virtual HID device by calling VhfDelete.
VhfDelete can be called synchronous or asynchronously by specifying the Wait parameter. For a synchronous
call, the method must be called at PASSIVE_LEVEL, such as from EvtCleanupCallback of the device object.
VhfDelete returns after deleting the virtual HID device. If the driver calls VhfDelete asynchronously, it returns
immediately and VHF invokes EvtVhfCleanup after the delete operation is complete. The method can be called at
maximum DISPATCH_LEVEL. In this case, the driver must have registered and implemented an EvtVhfCleanup
callback function when it previously called VhfCreate. Here is the sequence of events when HID source driver
wants to delete the virtual HID device:
1. HID source driver stops initiating calls into VHF.
2. HID source calls VhfDelete with Wait set to FALSE.
3. VHF stops invoking callback functions implemented by the HID source driver.
4. VHF starts reporting the device as missing to PnP Manager. At this point, the VhfDelete call might return.
5. When the device is reported as a missing device, VHF invokes EvtVhfCleanup if the HID source driver
registered its implementation.
6. After EvtVhfCleanup returns, VHF performs its cleanup.
VOID
VhfSourceDeviceCleanup(
_In_ WDFOBJECT DeviceObject
)
{
PDEVICE_CONTEXT deviceContext;

PAGED_CODE();

TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Entry");

deviceContext = DeviceGetContext(DeviceObject);

if (deviceContext->VhfHandle != WDF_NO_HANDLE)
{
VhfDelete(deviceContext->VhfHandle, TRUE);
}

Install the HID source driver


In the INF file that installs the HID source driver, make sure that you declare Vhf.sys as a lower filter driver to your
HID source driver by using the AddReg Directive.

[HIDVHF_Inst.NT.HW]
AddReg = HIDVHF_Inst.NT.AddReg

[HIDVHF_Inst.NT.AddReg]
HKR,,"LowerFilters",0x00010000,"vhf"

Related topics
Human Interface Device
Transport minidrivers
12/5/2018 • 2 minutes to read • Edit Online

This section contains details for vendors who need to create their own HID minidrivers. If your device requires
USB, Bluetooth, Bluetooth LE, I²C, GPIO as the transport, use the Microsoft-provided in-box driver. To see the list
of in-box transport minidrivers, see HID Transports.
For other transports, you will need to write transport minidrivers.
HID minidrivers can be written by using one of the following frameworks:
1. UMDF – User Mode Driver Framework
2. KMDF – Kernel Mode Driver Framework
3. WDM – Legacy Windows Driver Model
Note Microsoft encourages hardware vendors to use the in-box transport-minidrivers whenever possible.
However, if your device requires an unsupported transport, Microsoft recommends using the Windows Driver
Framework (UMDF or KMDF ) as the driver model for your minidriver. You should only create a WDM minidriver
if a specific transport is not supported by the Windows Driver Framework.
Microsoft recommends that developers use the UMDF framework as a starting point. Only if a functionality is not
available to UMDF, consider writing a KMDF driver. For information about functionality comparison in the two
driver frameworks, see Comparing UMDF 2 Functionality to KMDF.
The following table captures the key advantages and challenges associated with the two WDF models as they
pertain to HID Transport minidrivers.

KMDF UMDF

Advantages Support available in all Windows Easier to develop and recommended for
platforms that supports WDF Required most vertical device classes Errors in
for all keyboard and mouse filter this driver do not bug check the whole
drivers. system. For more information, see
Advantages of Writing UMDF
Drivers.

Challenges Poorly written KDMF HID transport UMDF HID transport minidrivers are
minidrivers can crash the system. not supported versions of Windows
prior to Windows 8. A UMDF driver can
receive I/O requests from a kernel-
mode driver. Those transitions can have
a slight performance impact.

See Also
Getting Started with UMDF
Binding minidrivers to the HID class
12/5/2018 • 2 minutes to read • Edit Online

This section describes the operation of the system-supplied HID class driver and HID minidrivers, which support
devices in the HIDClass device setup class.
The HID class driver provides the interface that upper-level drivers and user-mode applications use to access the
HID collections supported by an input device. The HID class driver uses HID minidrivers to access the hardware of
an input device. HID minidrivers abstract the operation of the port of bus to which the input device is attached. The
HID class driver is an export driver that is linked to HID minidrivers. HID minidrivers bind their operation to the
HID class driver by calling HidRegisterMinidriver to register themselves with the HID class driver.
The combined operation of the HID class driver and a HID minidriver acts as a WDM function driver for an input
device and a bus driver for the child devices (HID collections) that the input device supports. This design makes it
possible for the HID class driver to operate USB HID devices and non-USB input devices that are attached to ports
or buses other than a USB bus. The operational detail of the underlying parent device is transparent to upper-level
drivers or user-mode applications.
Minidrivers and the HID class driver
1/11/2019 • 9 minutes to read • Edit Online

The section includes the following topics about the operation of the HID class driver:
Operational features of the HID class driver
Binding the operation of the HID class driver to a HID minidriver
Communicating with a HID minidriver
See Creating WDF HID minidrivers for more information.
Operational features of the HID class driver
The HID class driver does the following:
Provides and manages the upper-level interface that kernel-mode drivers and user-mode applications use
to access the HID collections that an input device supports.
The HID class driver transparently manages and routes all communication between upper-level drivers and
applications and the underlying input devices that support HID collections. It manages the different data
protocols that are used by different input devices and input queues that support more than one open file on
the same HID collection.
The upper-level interface to HID collections consists of the HID class driver IOCTLs, the HIDClass support
routines, and the HIDClass structures.
Communicates with a HID minidriver by calling the minidriver's standard driver routines.
Creates a functional device object (FDO ) for HIDClass input devices enumerated by a lower-level bus or
port driver.
For example, the HID class driver creates and manages the operations of an FDO that represents a USB
HID device enumerated by the system-supplied USB driver stack.
Provides the functionality of a bus driver for the child devices (HID collections) supported by an underlying
input device.
The HID class driver creates a physical device object (PDO ) for each HID collection supported by an input
device and manages the collection's operation.
Binding a minidriver to HIDClass
A HID minidriver binds its operation to the HID class driver by calling HidRegisterMinidriver to register itself
with the HID class driver. The registration operation does the following:
Saves a copy of the entry points (pointers) to the HID minidriver's standard driver routines in the HID class
driver's device extension.
A HID minidriver sets its entry points in the driver object that the minidriver receives as input to its
DriverEntry routine. The HID minidriver sets these entry points before it registers with the HID class driver.
Resets the entry points in the minidriver's driver object to the entry points for the standard driver routines
supplied by the HID class driver.
The HID class driver supplies the following standard driver routines:
AddDevice and Unload routines
Dispatch routines for the following I/O requests:
IRP_MJ_CREATE
IRP_MJ_CLOSE
IRP_MJ_DEVICE_CONTROL
IRP_MJ_INTERNAL_DEVICE_CONTROL
IRP_MJ_PNP
IRP_MJ_SYSTEM_CONTROL
The registration process also allocates memory for the HID mindriver device extension. Although the memory is
allocated by the HID class driver, only the HID minidriver uses this device extension.
Communicating with a HID minidriver
The HID class driver communicates with a HID minidriver by calling the HID minidriver's AddDevice, Unload, and
dispatch routines as follows:
Calling the AddDevice Routine
When the HID class driver's AddDevice routine is called to create a functional device object (FDO ), the HID class
driver creates the FDO, initializes it, and calls the HID minidriver AddDevice routine. The HID minidriver
AddDevice routine does internal device-specific initialization and, if successful, returns STATUS_SUCCESS. If the
HID minidriver AddDevice routine is not successful, the HID class driver deletes the FDO and returns the status
returned by the HID minidriver AddDevice routine.
Calling the Unload Routine
When the HID class driver Unload routine is called, the HID class driver completes releasing all resources
associated with FDO and calls the HID minidriver's Unload routine.
Calling the Dispatch Routines
To operate a device, the HID class driver primarily calls the HID minidriver dispatch routine for internal device
control requests.
In addition, when the I/O manager sends Plug and Play, power, or system control requests to the HID class driver
for an FDO, the HID class driver processes the request, and calls the HID minidriver's corresponding dispatch
routine.
The HID class driver does not send the following requests to the HID minidriver: create, close, or device control.
Operation of a HID minidriver
A HID transport minidriver abstracts the operation of a hardware bus or port that your input device attaches to.
HID minidrivers can be built using one of the following frameworks:
UMDF – User Mode Driver Framework
KDMF – Kernel Mode Driver Framework
WDM – Legacy Windows Driver Model
Microsoft recommends using a Frameworks based solution (KMDF or UMDF (on Windows 8 only)). For more
information on each of the driver models, please visit the following sections:
KMDF -based HID minidriver, see Creating Framework-based HID Minidrivers
UMDF -based HID minidriver, see Creating UMDF -based HID Minidrivers
The following section talks about registering a WDM based HID Minidriver but much of it is pertinent to a KMDF
based Frameworks driver also. All HID minidriver must register with the HID class driver, and the HID class driver
communicates with the minidriver by calling the minidriver's standard driver routines.
For more information about the functionality that a HID minidriver must support in its standard driver routines,
see the following topics:
Registering a HID Minidriver
HID Minidriver Driver Extension
Using the HID_DEVICE_EXTENSION Structure
Standard Driver Routines Provided by a HID Minidriver
For more information about the HID class driver, see Operation of the HID Class Driver
Registering a HID minidriver
After a HID minidriver completes all other driver initialization in its DriverEntry routine, the HID minidriver binds
its operation to the HID class driver by calling HidRegisterMinidriver.
When the HID minidriver registers with the HID class driver, it uses a HID_MINIDRIVER_REGISTRATION
structure to specify the following: HID revision, the HID minidriver driver object, the size of a HID minidriver
device extension, and whether devices are polled or not.
HID minidriver extension
A HID minidriver device extension is device-specific, and is only used by a HID minidriver. The HID class driver
allocates the memory for the minidriver device extension when the class driver creates its device extension for a
functional device object (FDO ). The HID minidriver specifies the size of its device extension when it registers the
minidriver with the HID class driver. The size is specified by the DeviceExtensionSize member of a
HID_MINIDRIVER_REGISTRATION structure.
Using the HID_DEVICE_EXTENSION structure
A HID minidriver must use a HID_DEVICE_EXTENSION ). The HID class driver sets the members of this
structure when it initializes the FDO. A HID minidriver must not change the information in this structure.
A HID_DEVICE_EXTENSION structure contains the following members:
PhysicalDeviceObject is a pointer to the physical device object (PDO ) that represents the underlying
input device.
NextDeviceObject is a pointer to the top of the device stack beneath the FDO.
MiniDeviceExtension is a pointer to the HID minidriver device extension.
Given a pointer to the FDO of an input device, the following GET_MINIDRIVER_DEVICE_EXTENSION macro
returns a pointer to a HID minidriver extension:

#define GET_MINIDRIVER_DEVICE_EXTENSION(DO) ((PDEVICE_EXTENSION) (((PHID_DEVICE_EXTENSION)(DO)-


>DeviceExtension)->MiniDeviceExtension))

PDEVICE_EXTENSION is a pointer to a device-specific device extension declared by a HID minidriver.


Similarly, a HID minidriver can obtain a pointer to the input device's PDO and the top of the device stack beneath
the input device's FDO.
When a HID minidriver sends an IRP down the device stack, it should use NextDeviceObject as the target device
object.
Standard minidriver routines
A HID minidriver must provide the following standard driver support routines:
HID Minidriver DriverEntry Routine
HID Minidriver AddDevice Routine
HID Minidriver Unload Routine
A HID minidriver must also support the dispatch routines described in Dispatch Routines Provided by a HID
Minidriver.
DriverEntry routine
The DriverEntry routine in a HID minidriver does the following:
Creates a driver object for the linked pair of drivers (HID class driver and a HID minidriver).
Sets the required driver entry points in the HID minidriver driver object.
Calls HidRegisterMinidriver to register the HID minidriver with the HID class driver.
Does device-specific configurations that are only used by the HID minidriver.
AddDevice routine
The HID class driver handles creating and initializing the functional device object (FDO ) for an underlying input
device. The HID class driver also operates the FDO from the perspective of the upper-level interface to the
underlying device and its child devices (HID collections).
The HID class driver AddDevice routine calls the HID minidriver AddDevice routine so that the minidriver can do
internal device-specific initialization.
The parameters that are passed to the HID minidriver AddDevice routine are the minidriver driver object and the
FDO. (Note that the HID class driver passes the FDO to the minidriver AddDevice routine, not to the physical
device object for the underlying input device.)
The HID minidriver AddDevice routine obtains a pointer to the minidriver device extension from the FDO.
Typically, the HID minidriver AddDevice routine does the following:
Initializes the minidriver device extension. The device extension is only used by the minidriver.
Returns STATUS_SUCCESS. If the minidriver returns an error status, the HID class driver deletes the FDO
and returns the error status to the Plug and Play manager.
Unload routine
The Unload routine of the HID class driver calls the HID minidriver Unload routine. A HID minidriver releases any
internal resources allocated by the minidriver.
Dispatch routines
A HID minidriver must supply the following dispatch routines: create, close, internal device control, system control,
Plug and Play, and power management. Except for internal device control requests, most of these dispatch routines
provide minimal function. When the HID class driver calls these dispatch routines, it passes the minidriver driver
object and the functional device object (FDO ).
IRP_MJ_CREATE
In compliance with WDM requirements, the HID class driver and a HID minidriver provide a dispatch routine for
create requests. However, the FDO cannot be opened. The HID class driver returns STATUS_UNSUCCESSFUL.
A HID minidriver only needs to provide a stub. The create dispatch routine is never called.
IRP_MJ_CLOSE
In compliance with WDM requirements, the HID class driver and a HID minidriver must provide a dispatch routine
for close requests. However, the FDO cannot be opened. The HID class driver returns
STATUS_INVALID_PARAMETER_1.
A HID minidriver only needs to provide a stub. The close dispatch routine is never called.
IRP_MJ_DEVICE_CONTROL
A HID minidriver does not need a dispatch routine for device control requests. The HID class driver does not pass
device control requests to a minidriver.
IRP_MJ_INTERNAL_DEVICE_CONTROL
A HID minidriver must provide a dispatch routine for internal device control requests that supports the requests
described in HID MinidriverIOCTLs.
The HID class driver primarily uses internal device control requests to access the underlying input device.
The HID minidriver handles these requests in a device-specific way.
IRP_MJ_SYSTEM_CONTROL
A HID minidriver must provide a dispatch routine for system control requests. However, a HID minidriver is only
required to pass system control requests down the device stack as follows:
Skip the current IRP stack location
Send the request down the FDO's device stack
IRP_MJ_PNP
A HID minidriver must supply a dispatch routine for Plug and Play requests.
The HID class driver does all the Plug and Play processing associated with the FDO. When the HID class driver
processes a Plug and Play request, it calls the HID minidriver Plug and Play dispatch routine.
A HID minidriver Plug and Play dispatch routine does the following:
Handles sending the request down the FDO's device stack and completing the request on the way back up
the device stack, as appropriate for each type of request.
Does device-specific processing associated with certain requests to update information about the state of
the FDO.
For example, the minidriver might update the Plug and Play state of the FDO (in particular, whether the
FDO is started, stopped, or in the process of being removed).
IRP_MJ_POWER
The HID minidriver must supply a dispatch routine for power requests. However, the HID class driver handles the
power processing for the FDO.
In compliance with WDM requirements, a HID minidriver sends power requests down the FDO's device stack in
the following way:
Skips the current IRP stack location
Starts the next power IRP
Sends the power IRP down the FDO's device stack
Typically, the HID minidriver passes power requests down the device stack without additional processing.
Minidriver requirements for tablet PCs running on
earlier versions of Windows
12/21/2018 • 3 minutes to read • Edit Online

This section pertains to operating systems prior to Windows 8 and describes the general requirements for vendor-
supplied HID minidrivers for pen devices and button devices that are installed on a tablet PC edition system.
This section focuses on pen and button devices.
A pen device is integrated with the Tablet PC's LCD display and is used to capture the motion of a pen stylus.
A button device supplements the pen device and is used to capture button input. For more information about
the Tablet PC, see the Windows XP Tablet PC Edition website
For more information about the Tablet PC, see the Windows XP Tablet PC Edition website.
For detailed information about system-supplied software that supports the Tablet PC, see the Tablet PC
documentation in the Microsoft Windows SDK.
Pen and button devices belong to the HIDClass device setup class. These devices are operated by the system-
supplied HID Client Drivers, which is linked to a HID minidriver. In the absence of a system-supplied HID
minidriver that supports the hardware interface for a device, a vendor-supplied HID minidriver is required. The
devices are operated from user mode by using the system-supplied Tablet PC API, which is described in the
Windows SDK documentation.
Requirements for PC pen devices
A Tablet PC pen device must:
Provide a top-level collection whose usage page is Digitizer and whose usage is Pen (see HID usages).
If a Tablet PC does not include a built-in mouse, a Tablet PC pen device must provide a top-level collection
whose usage page is Generic Desktop and whose usage is Mouse. The purpose for the Mouse collection is
to enable the system mouse cursor. However, the Mouse collection must not generate input reports. Only
input from the Pen collection should be used for cursor movement. (If the Tablet PC's operating system
starts without an installed mouse device, the system does not display a mouse cursor and does not handle
the pen collection as a mouse device.)
Report raw data only. The driver must not compensate for linearity, pen tilt, display rotation, or scaling.
These transformations are handled by the Tablet PC API. However, the driver must ensure that the pen
coordinate system uses the same origin and orientation as that used by the API. For example, the driver
must ensure that the origin is at the upper-left corner of a landscape display, that the x-coordinate increases
from left to right, and that the y-coordinate increases from top to bottom.
If the device is a USB device, a Tablet PC pen device must support the USB selective suspend feature.
Requirements for PC button devices
A Tablet PC button device supplements pen input on a Tablet PC. A button device supports one or more buttons. A
button device that is installed on a Tablet PC must:
Provide one dedicated button for a Secure Attention Sequence (SAS ) (as described in the Microsoft
Windows SDK documentation).
Generate an event when a button is pressed and another event when that button is released.
Report distinct button events for each button, regardless of the number of buttons that are simultaneously
pressed or released.
Provide a top-level collection whose usage page is Generic Desktop and whose usage is Keyboard (see HID
usages). The Keyboard collection is only used to report SAS button events. When the SAS button is pressed,
the following usages must be reported: Left Control, Left Alt, and Delete.
Provide a top-level collection whose usage page is Generic Desktop and whose usage is Tablet PC System
Controls. Button events are reported by using a button array whose usage page is Button and the usage
values range from 1 to the number of buttons.
HID over USB
12/5/2018 • 2 minutes to read • Edit Online

USB was the first supported HID transport in the Windows operating system. The corresponding inbox driver was
introduced in Windows 2000 and has been available in all operating systems since then.
Windows 8 continues to support HID over USB and has been enhanced to include new classes of HID devices
from touchpads and keyboards to sensors and vendor specific device types.
HID over USB is also optimized to take advantage of selective suspend. (This feature requires a vendor provided
INF or support via Microsoft operating-system descriptors.)
Recent updates to HID over USB also include:
Support for USB 1.1, USB 2.0 and USB 3.0.
A HID over USB driver is available on all client SKUs of Windows and is included in WinPE.
Architecture and overview
12/5/2018 • 2 minutes to read • Edit Online

This section describes the driver stack for devices that support HID over the USB transport.
The HID over USB driver stack consists of the following components supplied by Microsoft. The following
illustration depicts the stack and these components.

Windows 8 provides a WDF -based HID miniport driver that implements version 1.1+ of the protocol specification
for HID over USB. This driver is named HIDUSB.SYS. Windows loads this driver based on a USB Device Class
compatible ID match.
Plug and play support
12/5/2018 • 3 minutes to read • Edit Online

This section describes the enumeration process on the Universal Serial Bus.
When a device is plugged in to a Windows-based computer, the Windows USB stack enumerates the device,
extracting details from the device including the interface descriptor (or descriptors) of the device, and then
generates a set of hardware IDs and compatible IDs for the device.
For a complete list of USB hardware IDs, see the "Device Identification Strings" section under Device Installation.
The examples in the following sections illustrate two scenarios:
USB IDs for a single interface USB device
USB IDs for a multi-interface (composite) USB device
Example 1: Single Interface HID USB Device
This example shows how the hardware IDs and compatible IDs are generated for a single-interface USB device on
a system running Windows 2000 or Windows XP.
When the device is originally enumerated by the USB stack, the USBHUB driver extracts idVendor, idProduct,
and bcdDevice from the device descriptor. These three fields are incorporated to generate a USB hardware ID.
Note that the vendor, device, and revision numbers are always stored in hexadecimal format.
The generation of the compatible ID for the device is more complicated. The class code, subclass code, and protocol
code are determined by the interface descriptor's bInterfaceClass, bInterfaceSubClass, and
bInterfaceProtocol. These values are in two-digit hexadecimal format.
Note If you are providing an INF, your hardware identifiers should match the bold identifiers in the left column of
the following table. (You should avoid using the compatible identifiers listed in the right column.)

Hardware Identifiers Compatible Identifiers

USB\Vid_xxxx&Pid_yyyy&Rev_zzzz USB\Class_aa&SubClass_bb&Prot_cc

USB\Vid_xxxx&Pid_yyyy USB\Class_aa&SubClass_bb

USB\Class_aa

Example 2: Multiple Interface/Function HID USB Device (Composite Device)


USB devices with multiple functions are called composite devices. This example shows how the hardware IDs and
compatible IDs are generated for composite USB devices on Windows. When a new USB composite device is
plugged into a computer system running Windows, the USBHUB driver creates a physical device object (PDO ) and
notifies the operating system that its set of child devices has changed. After querying the hub driver for the
hardware IDs associated with the new PDO, the system searches the appropriate INF files to find a match for the
identifiers. If a vendor chooses to load just one driver for the entire device (that is, not using the composite device
driver) and multiplex all interfaces in software with that driver, the vendor should specify a hardware ID match to
prevent the operating system from picking up the lower-ranking match (USB\COMPOSITE ).
Note If you are providing an INF, your hardware identifiers should match the bold identifiers in the left column of
the following table. (You should avoid using the compatible identifiers listed in the right column.)

Hardware Identifiers Compatible Identifiers

USB\Vid_xxxx&Pid_yyyy&Rev_zzzz USB\Class_aa&SubClass_bb&Prot_cc

USB\Vid_xxxx&Pid_yyyy USB\Class_aa&SubClass_bb

USB\Class_aa

USB\COMPOSITE

If, however, no hardware match is found, Windows Plug and Play makes use of the USB\COMPOSITE identifier to
load the USB Generic Parent driver (USBCCGP ). The Generic Parent driver then creates a separate set of PDOs
(one for every interface) with a separate set of hardware IDs for each interface of the composite device. The
following section displays the format of hardware IDs for child PDOs.
To build the set of hardware IDs for each interface’s PDO, the USBCCGP driver appends the interface number
(which is a zero-based hexadecimal value) to the end of the hardware ID.
The class code, subclass code, and protocol code are determined by the bInterfaceClass, bInterfaceSubClass,
and bInterfaceProtocol fields of the interface descriptor, respectively. These values are in two-digit hexadecimal
format.
Note If you are providing an INF, either to load your driver or to provide a friendly device name, your hardware
identifiers should match the bold identifiers in the left column of the following table. (You should avoid using the
compatible identifiers listed in the right column.)

Hardware Identifiers Compatible Identifiers

USB\Vid_xxxx&Pid_yyyy&Rev_zzzz&MI_ww USB\Class_aa&SubClass_bb&Prot_cc

USB\Vid_xxxx&Pid_yyyy&MI_ww USB\Class_aa&SubClass_bb

USB\Class_aa
Power management
12/5/2018 • 2 minutes to read • Edit Online

HID over USB employs USB suspend to power manage a device.


Power is managed primarily in the following two configurations:
1. Case #1: The system is in a power managed state (e.g. S3) but the device is armed to wake the system up. E.g. a
HID USB keyboard that is armed to wake up a desktop from S3 on key press.
2. Case #2: The system is in a running state (e.g. S0) but the device has idled out (no user interaction). E.g. selective
suspend a HID USB mouse when no one is using or touching it.
Case #1 Provisions
HID devices don't automatically wake up a system from a low - power state. Only specific HID devices (e.g. Top
level collections of keyboards and mice) do this.
If an end user wishes to disarm a device from waking up the system, the user can specify this via the
properties/power management tab in device manager.
Selective suspend for HID over USB devices
12/5/2018 • 3 minutes to read • Edit Online

Revision 2.0 of the Universal Serial Bus Specification specifies a USB selective suspend feature. By using this
feature, the Windows operating system can selectively suspend idle USB devices. This allows Windows to
efficiently manage the power requirements of the overall system. For more information about how Windows
supports the USB selective suspend feature, see USB selective suspend. (This resource may not be available in
some languages and countries.)
By default, USB selective suspend is disabled by Windows in order to provide a consistent user experience and to
avoid resume latency from selective suspend.
A HID device that supports selective suspend must be designed to:
Retain the first input, touch, movement or key press when resuming from selective suspend.
Wake from selective suspend on movement.
Maintain the wireless link (if applicable).
Maintain power to any active status LEDs, such as NUM lock or CAPS lock.
Resume from selective suspend without any perceived delay by the user.
Windows 8 supports two methods for enabling Selective Suspend for HID USB devices. They are as follows:
1. Microsoft OS Descriptor [PREFERRED ]: The Microsoft OS Descriptor’s Extended Properties descriptor can
be used to write the necessary registry key(s) to support USB HID Selective Suspend.
2. Vendor Provided INF: The Hardware manufacturer can provide an INF file (that matches on the USB
Hardware ID for the HID devnode) to install the appropriate registry keys.
Microsoft recommends that hardware vendors and PC manufacturers use the first option to enable USB HID
Selective Suspend. The advantages of this option are:
Hardware vendors and PC manufacturers do not have to install an additional INF file.
The necessary registry setting is automatically populated on new Windows 8 installations.
The necessary registry setting is preserved on an upgrade to Windows 8.
The user cannot lose (or disable) Selective Suspend functionality by uninstalling the INF.
However, hardware vendors and PC manufacturers who wish to still use the INF approach, can use the example
below. The following is a sample INF file that shows how to enable this USB feature for HID devices in Windows:
; Vendor INF File for USB HID devices
;
; A sample INF for a stand-alone USB HID device that supports
; selective suspend

[Version]
Signature ="$WINDOWS NT$"
Class =HIDClass
ClassGuid ={745a17a0-74d3-11d0-b6fe-00a0c90f57da}
Provider =%VendorName%
DriverVer =09/19/2008,6.0.0.0
CatalogFile =VendorXYZ.cat

; ================= Class section =====================


[ControlFlags]
ExcludeFromSelect=*

[SourceDisksNames]
1 = %DiskName%,,,""

;*****************************************
; Install Section
;*****************************************

[Manufacturer]
%VendorName% = VendorXYZDevice,NTx86,NTamd64,NTarm

[VendorXYZDevice.NTx86]
%VendorXYZ.DeviceDesc% = VendorXYZDevice_Install, USB\VID_045E&PID_00B4

[VendorXYZDevice.NTamd64]
%VendorXYZ.DeviceDesc% = VendorXYZDevice_Install, USB\VID_045E&PID_00B4

[VendorXYZDevice.NTarm]
%VendorXYZ.DeviceDesc% = VendorXYZDevice_Install, USB\VID_045E&PID_00B4

[VendorXYZDevice_Install.NT]
include = input.inf
needs = HID_SelSus_Inst.NT

[VendorXYZDevice_Install.NT.HW]
include = input.inf
needs = HID_SelSus_Inst.NT.HW

[VendorXYZDevice_Install.NT.Services]
include = input.inf
needs = HID_SelSus_Inst.NT.Services

[Strings]
VendorName = "Vendor XYZ"
DiskName = "Vendor XYZ Installation Disk"
VendorXYZ.DeviceDesc = "VendorXYZ Device"

Where:
1. The INF Version section should have the CLASSGUID and DriverVer directives set as follows:
The CLASSGUID directive must specify the Microsoft class GUID for HID devices. This GUID has
the value {745a17a0-74d3-11d0-b6fe-00a0c90f57da}.
The DriverVer directive must have a value that has a newer date and greater version number than
the value specified by the DriverVer directive in Input.inf.
2. b. The VendorXYZDevice* sections specify the hardware identifier (ID ) for the vendor's HID device. The
hardware ID consists of a vendor identifier (VID ) and product identifier (PID ). Each hardware ID for a
device must have VID/PID values that are unique to the vendor and device. This ensures that the same
hardware ID does not correspond to multiple names and settings
3. c. The VendorXYZDevice_Install.NT and VendorXYZDevice_Install.NT.HW sections are INF DDInstall
sections. In this example, these sections contain INF Include and Needs directives.
The Include directives reference the system-supplied Input.inf file, which contains INF sections needed to
enable the USB selective suspend feature for the vendor's HID device.
The Needs directives indicate which sections from Input.inf should be processed during device installation.
In this case, the HID_SelSus_Inst section is selected instead of the default HID_Inst section, which does not
support selective suspend.
4. d. The VendorXYZDevice_Install.NT.Services section is an INF DDInstall.HW section. In this example, the
section also contains the same values for the INF Include and Needs directives.
Resources for HID over USB
12/21/2018 • 2 minutes to read • Edit Online

The following references may prove helpful when creating your HID device:
HID USB specification
HID USB homepage
HID Usage Pages
HID over I2C
12/5/2018 • 2 minutes to read • Edit Online

For Windows 8, Microsoft created a new HID miniport driver that allows devices to communicate over an Inter-
Integrated Circuit (I²C ) bus.
The new HID miniport solution extends the HID protocol, beyond USB and Bluetooth, to support I²C devices. I²C
is a simple but efficient protocol and has been used for over a decade in phone and embedded platforms. This
protocol is supported in Windows 8 by an in-box KMDF driver named HIDI2C.sys.
This combined support for I²C over HID in the inbox driver, allows hardware manufactures to get their devices
running quickly on windows without imposing the need to create a driver.
In order to ensure correct behavior on a system with multiple ACPI resources, the following two resources must
appear first:
HID I²C connection
Device interrupt
After these resources are defined, additional ACPI resources, of other types, may follow.
Important notes:
Today, the HID I²C driver targets SoC systems that support Simple Peripheral Bus (SPB ) and GPIO. In the
future, Microsoft may support this driver on non-SoC systems.
The HID I²C driver is optimized to support all HID Clients.
The HID I²C driver enables devices and system manufacturers to reduce the total number of drivers they have
to develop to support common device types like keyboards, touchpads, touch screens, sensors, and so on.
The HID I²C driver is available on all client SKUs of Windows and is included in WinPE.
Architecture and overview for HID over the I²C
transport
12/5/2018 • 2 minutes to read • Edit Online

This section describes the driver stack for devices that support HID over the I²C transport.

Architecture and overview


The HID I²C driver stack consists of existing and new components supplied by Microsoft, as well as components
provided by the I²C silicon manufacturer. The following illustration depicts the stack and these components.

Windows 8 provides an interface for low -power, simple buses to communicate effectively with the operating
system. This interface is referred to as simple peripheral bus (SPB ), and it supports buses like Inter-Integrated
Circuit (I²C ) and Serial Peripheral Interface (SPI). For additional details about SPB, refer to the Simple Peripheral
Buses topic.
Windows 8 provides a KMDF -based HID miniport driver that implements version 1.0 of the protocol specification
for HID over I²C. This driver is named HIDI2C.sys. Windows loads this driver based on a compatible ID match,
which is exposed by the Advanced Configuration and Power Interface (ACPI). The driver ensures that apps that use
HID IOCTLs application level compatibility for software that leverages the HID IOCTLs and API set. A device will
assert the host when it requires attention or has data. However, before the assertion occurs, a GPIO connection
must exist.
Note The HIDI2C.sys device driver supports only the I²C bus. It does not support SPI, SMBUS, or other low -
power buses in Windows 8.

The I²C Controller Driver


The I²C controller driver exposes a Serial Peripheral Bus (SPB ) IOCTL interface to perform read and write
operations. This driver provides the actual controller intrinsics (for example, I²C ). The SPB Class Extension, on
behalf of the controller driver, handles all interaction with the resource hub and implements necessary queues to
manage simultaneous targets.
Note The HID I²C driver will not function on systems that do not have an I²C bus that is compatible with the SPB
platform. Contact your system manufacturer to determine whether the I²C bus on your device system is
compatible with the SPB platform.

The GPIO Controller Driver


The General Purpose Input/Output (GPIO ) controller delivers interrupts from the device over GPIO. This is often a
simple slave component that uses GPIO pins to signal Windows of new data or other events. GPIO can also
control the device by approaches other than the I²C channel.

The Resource Hub


Connections on a SoC platform are typically non-discoverable, because there are no standards for device
enumeration on the buses that are used on SoC. As a result, these devices must be statically defined in the
Advanced Configuration and Power Interface (ACPI). Furthermore, components often have multiple dependencies
spanning multiple buses, as opposed to a strict branching tree structure.
The resource hub is a proxy that manages the connections among all devices and bus controllers. The HIDI²C
driver uses the resource hub to reroute device-open requests to the appropriate controller driver. For more
information about the resource hub, refer to the Connection IDs for SPB Connected Devices topic.
Plug and play support for I2C
12/5/2018 • 3 minutes to read • Edit Online

This section describes plug and play support for devices that support HID over the I²C transport.
Driver Loading
Windows loads the HID I²C class driver based on a compatible identifier match between a hardware identifier and
the INF. The identifier is generated by the Advanced Configuration and Power Interface (ACPI). The hardware
identifier is generated for the I²C device node in ACPI. All HID I²C compatible devices must expose the
compatibility identifier, in addition to a unique hardware identifier.
The ACPI 5.0 Specification includes support for HID Class Devices. the ACPI definitions for HID I²C are as follows.

Field Value ACPI object Format Comments

Compatible ID PNP0C50 _CID String in the format of CompatibleID


ACPI0C50 or
PNP0C50

Hardware ID Vendor Specific _HID String in the format of VendorID + DeviceID


VVVVdddd (e.g
NVDA0001)

Subsystem Vendor Specific _SUB String in the format of SubVendorID +


VVVVssss (e.g SubSystemID
INTL1234)

Hardware Revision Vendor Specific _HRV 0xRRRR (2byte RevisionID


revision)

Current Resource Vendor Specific _CRS Byte stream Must include


Settings I2CSerialBus and
GPIO_INT for I2C
controller and GPIO
interrupts resp.

Device Specific GUID {3CDFF6F7- _DSM Package Defines a structure


Method 4267-4555-AD05- that contains the HID
B30A3D8938DE} Descriptor address.

Every HID I²C device must provide the following mandatory fields:
Compatible ID
Hardware ID
Hardware Revision
Current Resource Settings
Device Specific Method
Refer to the Advanced Configuration and Power Interface (ACPI) 5.0 specification for additional information.
The following provides an example of a hardware IDs and compatible IDs for a random HID I²C device. These
details are based on a sample device that reports itself as a HID with one top-level collection of class “vendor
specific”.
Advanced Configuration and Power Interface (ACPI) generates the following Hardware IDs and Compatible IDs to
load the HID I²C Transport driver:

Hardware Identifiers Compatible Identifiers

ACPI\Vid_xxxx&Pid_yyyy&Rev_zzzz; ACPI\PNP0C50

ACPI\Vid_xxxxPid_yyyy;

ACPI\xxxxyyyy;

In the previous example, the Hardware ID was generated by using the values extracted from the _HID ACPI
method for the sample device. The Compatible ID is generated by using the values extracted from the _CID ACPI
method for the sample device. The Compatible ID for a HID over I2C must always be PNP0C50 for version 1.0.
Note If you supply an INF, you should only use the hardware identifiers in the left column of the previous table.
(Do not use the compatible identifier in the right column.)
The Hardware ID for the HID Client device node generated by the HIDClass.sys component is as follows:

Hardware Identifier Compatible Identifier

HID\VEN_MSFT&DEV_0010&REV_0002&Col01; N/A

-HID\VEN_MSFT&DEV_0010&Col01 HID\MSFT0010&Col01; N/A

-HID\*MSFT0010Col01 N/A

-HID_DEVICE_UP:FF00_U:0001; N/A

-HID_DEVICE N/A

The Hardware ID is generated by HIDClass.sys and is identical for all transports. This identifier is based on values
passed to HIDClass.sys from HIDI2C.sys (extracted from ACPI).
Device enumeration sequence
Once a HID I²C device driver (HIDI2C.Sys ) is loaded, it starts to communicate with the device over the I²C bus.
The first operation the driver performs is the device enumeration sequence.
The following list gives the enumeration sequence. Note that the order of this list may change in future versions of
Windows.
1. Retrieve ACPI ASL code for HID I²C DEVICE from System BIOS.
2. Retrieve HID Descriptor from the Device.
Write HID Descriptor Address
Read HID Descriptor
3. Issue a SET_POWER to the Device.
Write SET_POWER Command
4. Issue a RESET (Host Initiated Reset) to the Device.
Write RESET Command
Device asserts GPIO interrupt
Read value (0x00 0x00) from input register
5. Retrieve report descriptor from the device.
Write report descriptor address
Read report descriptor
If the HOST fails to successfully complete any of steps 1-5 with the DEVICE, the HIDI²C driver may load with error
value of Code 10. There is no retry logic built into any of these commands.
Note Steps 4 and 5 may be done in parallel to optimize for time on I²C. Since report descriptors are (a) static and
(b) quite long, Windows 8 may issue a request for 5 while it is waiting for a response from the device on 4.
Supported HID I²C commands
HIDI2C.SYS driver supports the following commands

Command How it's used When it's used

Reset Windows supports the Host Initiated Windows will issue this command
Reset. during the following scenarios - device
initialization - disable/enable -
uninstall/reinstall

Get/Set_Report Windows supports the Get/Set_Report Windows will issue this command
commands. during the following scenarios - when a
HID client driver issues a get/set feature
report request - when a HID client
driver issues a synchronous
input/output report

Set_Power Windows supports the Set_Power Windows will issue this command
command during the following scenarios - when
the system transitions to a low power
S3 / connected standby state - when
the system is shut off.
Power management
12/21/2018 • 2 minutes to read • Edit Online

This section describes power management for devices that support HID over the I²C transport.

Power management and optimization


Windows 8 introduces a new power model labeled Always On, Always Connected. This model allows slates and
PCs to be optimized for power and performance. At the same time,Windows 8is highly optimized for power
consumption in situations when the PC is not in use. For example, it conserves power when the screen is turned off
either intentionally or as a result of no user activity.
Because HID devices are a primary device class in Windows, they must adhere to this new power model.
connected standby
Below is a short summary of how devices should behave during the connected standby power state.

Input Source Indicates User Presence in Processed while in connected Device State when System
connected standby standby transitions to connected
standby

Digitizer No Must not process D3

Mouse Yes Must process, will exit D0


connected standby

Keyboard Yes Must process, will exit D0


connected standby

Rotation Lock No Must not process D3

Generic Desktop Controls - No Must process D0


Volume Up - Volume Down
- Channel Down - Channel
Up - Fast Forward - Track
Forward - Track Back - Play -
Pause - Record - Track Stop

For more information about connected standby please refer to the Understanding Connected Standby video.
Supporting connected standby in HID I²C Devices
Devices on the I²C bus are enumerated by the Advanced Configuration and Power Interface (ACPI). As part of the
HID -I²C Protocol Specification, power management for HIDI²C devices is supported by the SET_POWER
command. This command instructs the device to transition in and out of its lower power mode.
The inbox HIDI²C miniport driver passes along the D -IRP from HIDClass. This allows ACPI to, in turn, power-
manage the device.
Troubleshooting common errors
12/5/2018 • 2 minutes to read • Edit Online

This section covers common issues that hardware vendors and driver developers may encounter when debugging
their I²C firmware or driver software.

Troubleshooting common errors


HIDI²C Driver Does not Load
If the I²C Controller driver loaded, but the device does not appear in the Windows Device Manager, refer to the
following.
The above issue typically occurs if there's an invalid ASL code for the host or the device. To determine whether the
problem was due to a failure to match the INF, refer to the setupapi.dev.log file. Another indicator that the problem
is due to a mismatch is Error Code 10 in Windows Device Manager.
To resolve this issue, ensure the following.
The _CID value must be PNP0C50.
The I²C controller and device characteristics in the BIOS must be accurate.
The HID descriptor address (for the device) in the BIOS must be accurate.
The GPIO Interrupt must be correctly identified and marked as Exclusive, Level, ActiveLow.
Refer to section 13 of the HID I2C Protocol Spec for more detail. (This specification will be available at a later date.)
Invalid report descriptor
If the host failed to retrieve the correct report descriptor from the device, ensure that the following are true.
1. The enumeration sequence must finish running before the report descriptor is retrieved.
2. The byte offsets 4 and 6 in the HID descriptor must be valid. (Pay particular attention to the length.)
If you verified that the correct report descriptor was retrieved from the device, but there still appears to be a related
issue, ensure that the following are true.
1. The wReportDescLength field is accurate.
2. The HID Report is correctly formatted. (To verify this, test an alternative bus like USB.)
FAQ
This section highlights questions frequently asked by hardware vendors and driver developers.
1. Will the Windows 8 inbox HIDI²C driver work for HID devices connected over I²C?
Yes, it will work provided the firmware is compliant with this HID I²C Protocol Specification
2. What is the data structure communicated between devices (such as Keyboards) and OS drivers?
The data structure would be in the form of an input report defined by a report descriptor, according to
HID standard. The device itself rather than HIDI²C defines the input report structure. You simply report
the keyboard usages as you would with a USB keyboard, and then provide the descriptor and
corresponding INPUT reports as per the HID I²C Specification
3. If multiple reports are being buffered at the same time, what should the device do?
If multiple reports are being buffered, the device should keep the interrupt asserted until the last report
has been read (acknowledged). As long as there is more data to report after a given read operation, the
device should keep the line asserted using a level-trigger GPIO setting.
4. Is it accurate to say that we should get the same DevicePath in the case of USB and I²C connectivity?
No, the device path will NOT be identical between USB and I²C. The differences are minor but
noteworthy. Please refer to the Hardware ID section in the Windows Driver Kit (WDK) for more details.
5. What is the required I²C transfer limit in order for HIDI²C devices to leverage the Windows inbox HIDI²C
driver?
All I²C controllers are required to support transfers up to 4 KB. The maximum HID report descriptor
length is 4 KB.
Event tracing
12/21/2018 • 2 minutes to read • Edit Online

You can use Event Tracing for Windows (ETW ) or the Windows software trace preprocessor (WPP ) to trace the
operations in your HID over I²C device driver. For more information about ETW, see the Event Tracing topic in the
Windows Development Reference. For more information about WPP, see WPP Software Tracing and Inflight Trace
Recorder (IFR ) for logging traces.

Using the Inflight Trace Recorder (IFR)


The Inflight Trace Recorder (IFR ), that is enabled by default for all drivers, lets you view trace output from the
HIDI²C driver to a kernel debugger. The following command displays WPP trace messages for HIDI²C.

!rcdrkd.rcdrlogdump hidi2c

The Inflight Trace Recorder (IFR ) stores these trace messages in a fixed-size circular buffer. As a result, the output
may not contain the entire trace log.

Using logman.exe
For more verbose and controllable traces, you can use logman.exe to capture traces. The following commands
capture WPP traces for HIDI²C:

Logman create trace -n HIDI2C_WPP -o HIDI2C_WPP.etl -nb 128 640 -bs 128
Logman update trace -n HIDI2C_WPP -p {E742C27D-29B1-4E4B-94EE-074D3AD72836} 0x7FFFFFFF 255
Logman start –n HIDI2C_WPP

<RUN your SCENARIO here>

Logman stop -n HIDI2C_WPP


Logman delete -n HIDI2C_WPP

You can parse the resulting trace log file into text using either the PDB or TMF files for HIDI²C.

Enabling ETW tracing


The HIDI²C driver logs ETW events for specific events. These events are logged in the Event Viewer logs.
You can also view these events using the following logman.exe commands:

Logman create trace -n HIDI2C_ETW -o HIDI2C_ETW.etl -nb 128 640 -bs 128
Logman update trace -n HIDI2C_ETW -p Microsoft-Windows-SPB-HIDI2C
Logman start –n HIDI2C_ETW

<RUN your SCENARIO here>

Logman stop -n HIDI2C_ETW


Logman delete -n HIDI2C_ETW

The resulting trace log can parsed with tools like Xperf or Windows Performance Analyzer (WPA).
Resources for HID over I2C
12/5/2018 • 2 minutes to read • Edit Online

For additional information, refer to the HID over I²C Protocol Specification on MSDN.
Non-HID legacy devices
12/5/2018 • 2 minutes to read • Edit Online

This section describes drivers, transports, and filter-drivers for non-HID keyboards and mice. These devices
primarily run on the PS/2 transport.
This section does not contain information about Sermouse, the Windows system function driver for a serial mouse.
Note that the operational constraints that apply to I8042prt do not apply to Sermouse. In addition, upper-level
device filter drivers are not used with Sermouse to customize the operation of a serial mouse. Instead, vendors
need to install a device-specific function driver for the device. A device-specific function driver and Sermouse can
operate at the same time, independent of one another.

Non-HID driver stack


Windows 8 uses the following driver stack for non-HID keyboard, mouse, and touchpad hardware. The only non-
HID Transport supported on Windows 8 is PS2.
Keyboard and mouse class drivers
1/11/2019 • 13 minutes to read • Edit Online

Non-HID keyboards and mice can connect over multiple legacy buses but still use the same class driver. This
section contains details on the class drivers themselves. The following sections goes into details on the controllers.
This topic describes the typical physical configuration of keyboard and mouse devices in Microsoft Windows 2000
and later.
The following figures show two common configurations that employ a single keyboard and a single mouse.

The figure on the left shows a keyboard and a mouse connected to a system bus through independent controllers.
A typical configuration consists of a PS/2-style keyboard operated through an i8042 controller, and a serial-style
mouse operated through a serial port controller.
The following additional information is important for keyboard and mice manufactures:
Keyboards are opened in exclusive mode by the operating system stack for security reasons
Windows supports the simultaneous connection of more than one keyboard and mouse device.
Windows does not support independent access by a client to each device.

Class driver features


This topic describes the features of the following Microsoft Windows 2000 and later system class drivers:
Kbdclass, the class driver for devices of GUID_CLASS_KEYBOARD device class
Mouclass, the class driver for devices of GUID_CLASS_MOUSE device class
Kbdclass implements the Kbdclass service and its executable image is kbdclass.sys.
Mouclass implements the Mouclass service and its executable image is mouclass.sys.
Kbdclass and Mouclass each feature:
Generic and hardware-independent operation of the device class.
Plug and Play, power management, and Windows Management Instrumentation (WMI).
Operation of legacy devices.
Simultaneous operation of more than one device.
Connection of a class service callback routine that a function driver uses to transfer data from the input data
buffer of the device to the data buffer of the class driver.

Configuration of device objects


The following figure shows the configuration of device objects for a Plug and Play PS/2-style keyboard and mouse
device. Each class driver creates an upper-level class filter device object (filter DO ) that is attached to a function
device object (FDO ) through an optional upper-level device filter DO. An upper-level device filter driver creates the
upper-level device filter DO. I8042prt creates the function DO and attaches it to a physical device object (PDO )
created by the root bus driver.

PS/2 Keyboard
The keyboard driver stack consists of the following.
Kbdclass, the upper-level keyboard class filter driver
One or more optional upper-level keyboard filter driver
I8042prt, the function driver
PS/2 Mouse
The mouse driver stack consists of the following.
Mouclass, the upper-level mouse class filter driver
One or more optional upper-level mouse filter driver
I8042prt, the function driver
Kbdclass and Mouclass can support more than one device in two different modes. In the one-to -one mode, each
device has an independent device stack. The class driver creates and attaches an independent class DO to each
device stack. Each device stack has its own control state and input buffer. The Microsoft Win32 subsystem accesses
input from each device through a unique file object.
In the grandmaster mode, the class driver operates all the devices in the following way:
The class driver creates both a grandmaster class DO that represents all of the devices and a subordinate
class DO for each device.
The class driver attaches a subordinate class DO to each device stack. Below the subordinate class DO, the
device stack is same as that created in the one-to-one mode.
The grandmaster class DO controls the operation of all the subordinate DOs.
The Win32 subsystem accesses all device input through the file object that represents the grandmaster class
device.
All device input is buffered in the grandmaster's data queue.
The grandmaster maintains a single global device state.
Kbdclass and Mouclass operate in the one-to-one mode if their registry entry value ConnectMultiplePorts is set
to 0x00 (under the key HKLM\Services\CurrentControlSet\<class service>\Parameters, where class service is
Kbdclass or Mouclass). Otherwise Kbdclass and Mouclass operate in grandmaster mode.

Open and close via the class driver


The Microsoft Win32 subsystem opens all keyboard and mouse devices for its exclusive use. For each device class,
the Win32 subsystem treats input from all the devices as if the input came from a single input device. An
application cannot request to receive input from only one particular device.
The Win32 subsystem dynamically opens Plug and Play input devices after it receives notification from the Plug
and Play manager that a GUID_CLASS_KEYBOARD or GUID_CLASS_MOUSE device interface is enabled. The
Win32 subsystem closes Plug and Play devices after it receives notification that an opened interface is disabled.
The Win32 subsystem also opens legacy devices by name (for example, "\Device\KeyboardLegacyClass0"). Note
that once the Win32 subsystem successfully opens a legacy device, it cannot determine if the device is later
physically removed.
After Kbdclass and Mouclass receive a create request they do the following for Plug and Play and legacy operation:
Plug and Play Operation
If the device is in the Plug and Play started state, the class driver sends the IRP_MJ_CREATE request down
the driver stack. Otherwise the class driver completes the request without sending the request down the
driver stack. The class driver sets the trusted file that has read access to the device. If there is a grandmaster
device, the class driver sends a create request to all the ports that are associated with the subordinate class
devices.
Legacy Operation
The class driver sends an internal device control request to the port driver to enable the device.

Connect a service callback to a device


The class drivers must connect their class service to a device before the device can be opened. The class drivers
connect their class service after they attach a class DO to a device stack. The function driver uses the class service
callback to transfer input data from a device to the class data queue for the device. The function driver's ISR
dispatch completion routine for a device calls the class service callback. Kbdclass provides the class service callback
KeyboardClassServiceCallback, and Mouclass provides the class service callback
MouseClassServiceCallback.
A vendor can modify the operation of a class service callback by installing an upper-level filter driver for a device.
The sample filter driver Kbfiltr defines the KbFilter_ServiceCallback callback, and the sample filter driver
Moufiltr defines the MouFilter_ServiceCallback callback. The sample filter service callbacks can be configured to
modify the input data that is transferred from the port input buffer for a device to the class data queue. For
example, the filter service callback can delete, transform, or insert data.
The class and filter service callbacks are connected in the following way:
The class driver sends an internal device connect request down the device stack
(IOCTL_INTERNAL_KEYBOARD_CONNECT or IOCTL_INTERNAL_MOUSE_CONNECT). The class
connect data is specified by a CONNECT_DATA structure that includes a pointer to the class device object,
and a pointer to the class service callback.
After the filter driver receives the connect request, it saves a copy of the class connect data, and replaces the
request's connect data with filter connect data. The filter connect data specifies a pointer to the filter device
object and a pointer to the filter driver service callback. The filter driver then sends the filtered connect
request to the function driver.
The class and filter service callbacks are called in the following way:
The function driver uses the filter connect data to make the initial callback to the filter service callback.
After filtering the input data, the filter service callback uses the class connect data that it saved to make a
callback to the class service callback.

Query and set a keyboard device


I8042prt supports the following internal device control requests to query information about a keyboard device,
and to set parameters on a keyboard device:
IOCTL_KEYBOARD_QUERY_ATTRIBUTES
IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION
IOCTL_KEYBOARD_QUERY_INDICATORS
IOCTL_KEYBOARD_QUERY_TYPEMATIC
IOCTL_KEYBOARD_SET_INDICATORS
IOCTL_KEYBOARD_SET_TYPEMATIC
For more information about all keyboard device control requests, see I8042prt Keyboard Internal Device Control
Requests.

Scan code mapper for keyboards


In Microsoft Windows operating systems, PS/2-compatible scan codes provided by an input device are converted
into virtual keys, which are propagated through the system in the form of Windows messages. If a device produces
an incorrect scan code for a certain key, the wrong virtual key message will be sent. This can be fixed by writing a
filter driver that analyzes the scan codes generated by firmware and modifies the incorrect scan code to one
understood by the system. However, this is a tedious process and can sometimes lead to severe problems, if errors
exist in the kernel-level filter driver.
Windows 2000 and Windows XP include a new Scan Code Mapper, which provides a method that allows for
mapping of scan codes. The scan code mappings for Windows are stored in the following registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout

Note There is also a Keyboard Layouts key (notice the plural form) under the Control key, but that key should
not be modified.
In the Keyboard Layout key, the Scancode Map value must be added. This value is of type REG_BINARY (little
Endian format) and has the data format specified in the following table.

Start offset (in bytes) Size (in bytes) Data

0 4 Header: Version Information


4 4 Header: Flags

8 4 Header: Number of Mappings

12 4 Individual Mapping

... ... ...

Last 4 bytes 4 Null Terminator (0x00000000)

The first and second DWORDS store header information and should be set to all zeroes for the current version of
the Scan Code Mapper. The third DWORD entry holds a count of the total number of mappings that follow,
including the null terminating mapping. The minimum count would therefore be 1 (no mappings specified). The
individual mappings follow the header. Each mapping is one DWORD in length and is divided into two WORD
length fields. Each WORD field stores the scan code for a key to be mapped.
Once the map is stored in the registry, the system must be rebooted for the mappings to take effect. Note that if
the mapping of a scan code is necessary on a keypress, the step is performed in user mode just before the scan
code is converted to a virtual key. Doing this conversion in user mode can present certain limitations, such as
mapping not working correctly when running under Terminal Services.
To remove these mappings, remove the Scancode Map registry value and reboot.
Example 1
The following presents an example. To swap the left CTRL key with the CAPS LOCK key, use a registry editor
(preferably Regedt32.exe) to modify the Scancode Map key with the following value:

00000000 00000000 03000000 3A001D00 1D003A00 00000000

The following table contains these entries broken into DWORD fields and the bytes swapped.

Value Interpretation

0x00000000 Header: Version. Set to all zeroes.

0x00000000 Header: Flags. Set to all zeroes.

0x00000003 Three entries in the map (including null entry).

0x001D003A Left CTRL key --> CAPS LOCK (0x1D --> 0x3A).

0x003A001D CAPS LOCK --> Left CTRL key (0x3A --> 0x1D).

0x00000000 Null terminator.

Example 2
It is also possible to add a key not generally available on a keyboard or to remove a key that is never used. The
following example shows the value stored in Scancode Map to remove the right CTRL key and change the
functionality of the right ALT key to work as a mute key:
00000000 00000000 03000000 00001DE0 20E038E0 00000000

The following table contains these entries broken into DWORD fields and the bytes swapped.

Value Interpretation

0x00000000 Header: Version. Set to all zeroes.

0x00000000 Header: Flags. Set to all zeroes.

0x00000003 Three entries in the map (including null entry).

0xE01D0000 Remove the right CTRL key (0xE01D --> 0x00).

0xE038E020 Right ALT key --> Mute key (0xE038 --> 0xE020).

0x00000000 Null terminator.

After the necessary data is generated, it can be inserted into the registry in several ways.
A .reg file can be generated that can be easily incorporated into the system registry using a registry editor.
An .inf file can also be created with an [AddReg] section that contains the registry information to be added.
Regedt32.exe can be used to manually add the information to the registry.
The Scan Code Mapper has several advantages and disadvantages.
The advantages include:
The Mapper can be used as an easy fix to correct firmware errors.
Frequently used keys can be added to the keyboard by modifying the map in registry. Keys that aren't often
used (for example, right CTRL key) can be mapped to null (removed) or exchanged for other keys.
Key locations can be altered easily. Users can easily customize the location of frequently used keys for their
benefit.
The following disadvantages are recognized:
Once the map is stored in the registry, a system reboot is required to activate it.
The mappings stored in the registry work at system level and apply to all users. These mappings cannot be set
to work differently depending on the current user.
The current implementation restricts the functionality of the map such that mappings always apply to all
keyboards connected to the system. It is not currently possible to create a map on a per-keyboard basis.

Query a mouse device


I8042prt supports the following internal device control request to query information about a mouse device:
IOCTL_MOUSE_QUERY_ATTRIBUTES
For more information about all mouse device control requests, see I8042prt Mouse Internal Device Control
Requests.

Registry settings associated with mouse class driver


The following is a list of registry keys associated with the mouse class driver.
[Key: HKLM\SYSTEM\CurrentControlSet\Services\Mouclass\Parameters]
MaximumPortsServiced – Not used on Windows XP and later. Only for Windows NT4.
PointerDeviceBaseName – Specifies the base name for the device objects created by the mouse class device
driver
ConnectMultiplePorts – Determines whether there is one or more than one port device object for each class
device object. This entry is used primarily by device drivers.
MouseDataQueueSize - Specifies the number of mouse events buffered by the mouse driver. It also is used in
calculating the size of the mouse driver's internal buffer in the nonpaged memory pool.
Additional details on each specific registry key are available on https://technet.microsoft.com

Absolute pointing devices


For devices of type GUID_CLASS_MOUSE, a device's function driver:
Handles device-specific input.
Creates the MOUSE_INPUT_DATA structures required by MouseClassServiceCallback.
Transfers MOUSE_INPUT_DATA structures to the Mouclass data queue by calling
MouseClassServiceCallback in its ISR dispatch completion routine.
For an absolute pointing device, the device's function driver must set the LastX, LastY, and Flags members of the
MOUSE_INPUT_DATA structures in the following way:
In addition to dividing the device input value by the maximum capability of the device, the driver scales the
device input value by 0xFFFF:

LastX = ((device input x value) * 0xFFFF ) / (Maximum x capability of the device)


LastY = ((device input y value) * 0xFFFF ) / (Maximum y capability of the device)

The driver sets the MOUSE_MOVE_ABSOLUTE flag in Flags.


If the input should be mapped by Window Manager to an entire virtual desktop, the driver sets the
MOUSE_VIRTUAL_DESKTOP flag in Flags. If the MOUSE_VIRTUAL_DESKTOP flag is not set, Window
Manager maps the input to only the primary monitor.
The following specifies, by type of device, how these special requirements for an absolute pointing device are
implemented:
HID devices:
Mouhid, the Windows function driver for HID mouse devices, implements these special requirements
automatically.
PS/2-style devices:
An upper-level filter driver is required. The filter driver supplies an IsrHook callback and a class service
callback. I8042prt calls the IsrHook to handle raw device input, and calls the filter class service callback to
filter the input. The filter class service callback, in turn, calls MouseClassServiceCallback. The combination
of the IsrHook callback and the class service callback handles device-specific input, creates the required
MOUSE_INPUT_DATA structures, scales the device input data, and sets the MOUSE_MOVE_ABSOLUTE
flag.
Plug and Play COM port devices that are enumerated by Serenum:
A Plug and Play function driver is required. The function driver creates the required MOUSE_INPUT_DATA
structures, scales the device input data, and sets the MOUSE_MOVE_ABSOLUTE flag before it calls
MouseClassServiceCallback.
Non-Plug and Play COM port devices:
A device-specific function driver is required. The function driver creates the required MOUSE_INPUT_DATA
structures, scales the device input data, and sets the MOUSE_MOVE_ABSOLUTE flag before it calls
MouseClassServiceCallback.
Device on an unsupported bus:
A device-specific function driver is required. The function driver creates the required MOUSE_INPUT_DATA
structures, scales the device input data, and sets the MOUSE_MOVE_ABSOLUTE flag before it calls
MouseClassServiceCallback.
PS/2 (i8042prt) driver
12/5/2018 • 3 minutes to read • Edit Online

This topic describes the features of I8042prt, the Microsoft Windows 2000 and later system function driver for
PS/2-style keyboard and mouse devices.
I8042prt implements the I8042prt service and its executable image is i8042prt.sys.
The features of I8042prt include:
Hardware-dependent, simultaneous operation of a PS/2-style keyboard and mouse device.
The keyboard and mouse share I/O ports, but use different interrupts, interrupt service routines (ISR ), and
ISR dispatch completion routines.
Plug and Play, power management, and WMI
Operation of legacy devices.
Connection of a keyboard class service callback routine and a mouse class service callback routine.
I8042prt uses the class service callback to transfer data from the input data buffer of I8042prt to the data
buffer of the class driver.
Addition of a vendor-supplied PI8042_KEYBOARD_INITIALIZATION_ROUTINE callback routines for a
keyboard device.
An optional upper-level device filter driver provides the callback routines.
Addition of a vendor-supplied PI8042_KEYBOARD_ISR callback routine and a custom
PI8042_MOUSE_ISR callback routine.
Optional upper-level device filter drivers provide these callbacks routines.
Keyboard write buffer request and mouse write buffer request.
An upper-level device filter driver can use write buffer requests to synchronize its writes to a device with the
ISR of the device and other reads and writes on the device.
Keyboard start information request and mouse start information request.
The start information request passes a pointer to an interrupt object of a device to an upper-level filter
driver. The filter driver can use the interrupt object to synchronize its operation with the ISR of the device.
I8042prt callback routines.
An upper-level device filter driver can use the callback routines in the context of the ISR of a device to write
to a device, and to queue data packets from the device.
Registry settings associated with the PS/2 driver
The following is a list of registry keys associated with the PS/2 port driver.

[Key: HKLM\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters]

EnableWheelDetection [REG_DWORD ] – Determines whether the driver attempts to detect and enable the
wheel on the mouse device. Some devices are equipped with a mouse wheel to provide rapid scrolling and
other control features if supported by an application.
ResendIterations [REG_DWORD ] – Specifies the maximum number of times a hardware operation is
attempted. If the number of trials exceeds the value of this entry, Windows considers the operation to have
failed.
NumberOfButtons [REG_DWORD ] – Specifies the number of buttons on the mouse-port mouse at startup. If
the number of buttons detected at startup is incorrect, you can override it by changing the value of this entry.
KeyboardDataQueueSize [REG_DWORD ] – Specifies the number of keyboard events that the keyboard driver
buffers. This entry is also used in calculating the size of the keyboard driver's internal buffer in nonpaged
memory pool. To determine the number of bytes to allocate for the buffer, the system multiplies the size of the
KEYBOARD_INPUT_DATA structure by the value of KeyboardDataQueueSize.
PollStatusIterations [REG_DWORD ] – Specifies the maximum number of times the system verifies interrupts on
the i8042 controller status register. If the interrupt cannot be verified in the number of trials specified in the
value of this entry, the interrupt is ignored.
PollingIterations [REG_DWORD ] - Specifies the maximum number of times Windows 2000 polls the hardware.
If the number of trials specified in this entry is exceeded, Windows 2000 stops polling.
SampleRate [REG_DWORD ] – Specifies how often the PS/2 driver measures the characteristics and activities of
the PS/2 mouse. The driver uses the information gathered through sampling to optimize the operation of the
mouse device.
PollingIterationsMaximum [REG_DWORD ] – Specifies the maximum number of times Windows 2000 polls the
hardware on older-style AT keyboards. If the number of trials specified in this entry is exceeded, Windows stops
polling.
MouseResendStallTime [REG_DWORD ] – Determines how long the mouse driver waits for an
acknowledgement (ACK) of a reset if a RESEND message is returned without an ACK. This entry is used when
the mouse driver interrupt service routine includes a reset.
OverrideKeyboardType [REG_DWORD ] – Specifies the keyboard type. You can add this entry to the registry to
correct an error in the keyboard type detected at startup.
OverrideKeyboardSubtype [REG_DWORD ] – Specifies the OEM -dependent keyboard subtype. You can add this
entry to the registry to correct an error in the keyboard subtype detected at startup.
For additional information, please see:
https://docs.microsoft.com/windows/desktop/sysinfo/about-the-registry
https://docs.microsoft.com/windows/desktop/sysinfo/registry-reference
3rd party filter drivers
1/11/2019 • 5 minutes to read • Edit Online

This topic describes the features of the following sample filter drivers in the Microsoft Windows Driver Kit (WDK):
Kbfiltr, an optional upper-level filter driver for a Plug and Play PS/2-style keyboard device
Moufiltr, an optional upper-level filter driver for a Plug and Play PS/2-style mouse device
Kbfiltr and Moufiltr demonstrate how to filter I/O requests and add callback routines that modify the operation of
the class service and the operation of I8042prt.
Note The design of the Terminal Server for Windows 2000 and later does not support using the sample
keyboard and mouse filter drivers to filter input from devices physically installed on a remote client. A filter driver
installed on a Terminal Server can only be used to filter the input from the devices physically installed on a Terminal
Server. This is a consequence of the way the TermDD.sys driver for the Terminal Server handles input from remote
clients.
Kbfiltr and Moufiltr support Plug and Play and power management.
Kbfiltr provides the following callback routines:
KbFilter_ServiceCallback
The keyboard filter service callback is added to the keyboard class service callback. The filter service callback can
be configured to modify the keyboard input data that is saved in the class driver's data queue.
KbFilter_IsrHook
The keyboard filter ISR hook routine is a template for the IsrRoutine callback that I8042prt supports for a
keyboard device. The callback can be configured to customize the operation of an ISR of a keyboard.
KbFilter_InitializationRoutine
The keyboard filter initialization routine is a template for the InitializationRoutine callback that I8042prt
supports for a keyboard device. This callback can be configured to customize the initialization of a keyboard device.
Moufiltr provides the following callback routines:
MouFilter_ServiceCallback
The mouse filter service callback is added to the mouse class service callback. The filter service callback can be
configured to modify the mouse input data that is saved in the class driver's data queue.
MouFilter_IsrHook
The mouse filter ISR hook routine is a template for the IsrRoutine callback that I8042prt supports for a mouse
device. The callback can be configured to customize the operation of that mouse's ISR.

Customize the initialization and ISR of a device


Vendors can supply optional upper-level device filter drivers that can add the following optional callbacks to the
operation of I8042prt:
PI8042_KEYBOARD_ISR
The keyboard interrupt service routine (ISR ) customizes the operation of the I8042prt keyboard ISR. A keyboard
ISR callback is not needed if the default operation of I8042prt is sufficient. After the I8042prt keyboard ISR
validates a keyboard interrupt, it calls the keyboard ISR callback.
PI8042_MOUSE_ISR
The mouse ISR customizes the operation of the I8042prt mouse ISR. A mouse ISR callback is not needed if the
default operation of I8042prt is sufficient. After the I8042prt mouse ISR validates a mouse interrupt, it calls the
mouse ISR callback.
PI8042_KEYBOARD_INITIALIZATION_ROUTINE
The keyboard initialization callback supplements the default initialization of a keyboard device by I8042prt.
I8042prt calls this routine when it initializes a keyboard device.
I8042prt adds the callbacks provided by an upper-level device filter driver by using an
IOCTL_INTERNAL_I8042_HOOK_KEYBOARD request for a keyboard device and an
IOCTL_INTERNAL_I8042_HOOK_MOUSE request for a mouse device. After I8042prt receives a connect
request from a device class driver, I8042prt synchronously sends the device-specific hook request to the top of the
device stack.
After a filter driver receives a hook request, it does the following:
Saves the upper-level driver hook information, if any, that is passed to the filter driver.
The hook information includes a pointer to a context, a pointer to an ISR callback, and a pointer to an
initialization callback (initialization callback for a keyboard only).
Replaces the upper-level driver hook information with the filter driver's hook information.
Saves the context of I8042prt and the pointers to callbacks that the filter driver callbacks can use.
The sample filter drivers, Kbfiltr and Moufiltr, provide the following callback routines:
KbFilter_IsrHook is a template for the PI8042_KEYBOARD_ISR callback.
KbFilter_InitializationRoutine is a template for the PI8042_KEYBOARD_INITIALIZATION_ROUTINE
callback.
MouFilter_IsrHook is a template for the PI8042_MOUSE_ISR callback.

Synchronize the operation of a filter driver with a device's ISR


I8042prt uses a start information request to pass a pointer to a device's interrupt object to the upper-level drivers
in its device stack. After a device is started, the filter driver can use the interrupt object to synchronize its operation
with the interrupt service routine. Filter drivers should only use the interrupt object in calls to
KeSynchronizeExecution.
I8042prt passes the interrupt object pointer to the top of the device stack by using an
IOCTL_INTERNAL_I8042_KEYBOARD_START_INFORMATION request for a keyboard device and an
IOCTL_INTERNAL_I8042_MOUSE_START_INFORMATION request for a mouse device. I8042prt
synchronously sends a start information request to the top of the device stack after the hardware initialization of a
device. After a filter driver receives a start information request, it saves the start information and passes the request
down the device stack. I8042prt completes the request.

Synchronize writes by a filter driver to a device


To customize the operation of a device, a filter driver needs to write control data to the device. The filter driver must
synchronize writes to a device with the device's interrupt service routine and other asynchronous reads or writes on
the device (for example, writes that are initiated by a set typematic request or a set keyboard indicator request).
I8042prt supports an IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER request and an
IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER request for this purpose. A write buffer request is
synchronized with the device's ISR and other requests that read or write the device.
I8042prt callbacks that filter drivers can use
I8042prt supports the following callbacks that an upper-level device filter driver can use in its ISR callback:
PI8042_ISR_WRITE_PORT
A write port callback for a device writes to the i8042 port at the IRQL of the device's ISR.
PI8042_QUEUE_PACKET
A queue packet callback for a device queues an input data packet for processing by the device's ISR DPC.
PI8042_SYNCH_READ_PORT
This callback can be used in a PI8042_KEYBOARD_INITIALIZATION_ROUTINE callback. I8042prt specifies
the read port callback in the ReadPort parameter that I8042prt inputs to a keyboard initialization routine.
PI8042_SYNCH_WRITE_PORT
This callback can be used in a PI8042_KEYBOARD_INITIALIZATION_ROUTINE callback. I8042prt specifies
the write port callback in the WritePort parameter that I8042prt inputs to a keyboard initialization routine.
I8042prt passes pointers to the keyboard device callbacks in a INTERNAL_I8042_HOOK_KEYBOARD structure
that I8042prt uses to input information with an IOCTL_INTERNAL_I8042_HOOK_KEYBOARD request.
I8042prt passes pointers to the mouse device callbacks in a INTERNAL_I8042_HOOK_MOUSE structure that
I8042prt uses to input information with an IOCTL_INTERNAL_I8042_HOOK_KEYBOARD request.
After a filter driver receives a hook device request, it saves the I8042prt callback pointers for use in the filter
driver's ISR callback.
OS Driver installation
12/5/2018 • 2 minutes to read • Edit Online

This section documents the following class-specific INF file entries that a vendor can use to control how the
Microsoft-supplied keyboard and mouse class installers install devices under Microsoft Windows 2000 and later
:
INF DDInstall.MigrateToDevNode Section
INF SharedDriver Entry
INF PS2_Inst.NoInterruptInit.Bioses Section
INF PS2_Inst.NoInterruptInit Section
For specific examples, see the usage of these INF file entries in keyboard.inf and msmouse.inf -- the Microsoft-
supplied INF files for the keyboard and mouse device setup classes.

General rules for PS/2 keyboards and mice


For every internal / integrated device connected via a PS/2-compatible controller, the Microsoft Windows
operating system uses ACPI to construct a list of device identification strings for the device. The Plug and Play
Manager uses these device identification strings to match a device to an INF file. Plug and Play device strings are
divided into the following types:
A single unique Device ID (often just the first ID in the list of Hardware IDs)
An ordered list of Hardware IDs
An ordered list of Compatible IDs
The Plug and Play Manager always uses all the identifiers in the list when it tries to match a device to an INF file,
but it tries to use the most specific identifier first. This allows the setup software to give preference to drivers in the
order of their suitability, with those drivers supplied by the vendor being at the top of the priority list.
To locate a driver match, Setup compares the device's Hardware IDs and Compatible IDs (as reported by the
device's parent bus driver) to the Hardware IDs and Compatible IDs listed in the INF files on the machine. If Setup
finds more than one match, it assigns a "rank" to each possible driver match. The lower the rank number, the better
match the driver is for the device.
To achieve the scenario described above, ACPI should report the following:
One or more Hardware IDs to identify the firmware and/or hardware model. Format of the HWID (as defined in
ACPI specification V5.0) is as follows:
ACPI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss&REV_rrrr
ACPI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss
ACPI\VEN_vvvv&DEV_dddd&REV_rrrr
ACPI\VEN_vvvv&DEV_dddd&CLS_cccc&SUBCLS_nnnn&PI_pp
ACPI\VEN_vvvv&DEV_dddd
ACPI\vvvdddd
ACPI\vvvvdddd
One Compatible ID to allow the operating system to load a generic class driver. These Generic IDs are already
listed in the keyboard and mouse INFs.
An example of a system with a correctly formatted PS/2 keyboard hardware ID is as follows:
Hardware ID: ACPI\MSF0001;
Compatible ID: *PNP0303
Notes:
Windows allows legacy (e.g. ACPI 4.0) style ACPI hardware IDs but prefers that they always identify a unique
keyboard or mouse device.
The Windows Hardware Certification Kit includes the following requirement
(System.Fundamentals.Input.PS2UniqueHWID ). System manufacturers embedding keyboards and mice over
PS/2 on mobile computing elements must ensure a unique hardware ID. The unique Hardware ID must be in a
format that allows Windows Update (WU ) to identify the device and load the correct drivers for it. This
Windows 8 logo requirement applies to x86/64 mobile systems (no support for PS/2 on ARM systems)
For additional details, please refer to the MSDN whitepaper titled “Hardware IDs for PS/2 Input Devices on
Laptops ”.
INF DDInstall.MigrateToDevNode Section
12/5/2018 • 2 minutes to read • Edit Online

[install-section-name.MigrateToDevNode] | [install-section-name.nt.MigrateToDevNode] | [install-section-


name.ntx86.MigrateToDevNode] | [install-section-name.ntia64.MigrateToDevNode]
ServiceName=value-name[,value-name],... The keyboard and mouse class installers copy the entry values
specified by the list of value-name strings from the registry key
HKLM\System\CurrentControlSet\Services\ServiceName\Parameters to the device node of the device being
installed.
Entries and Values
ServiceName
Specifies the service name associated with a device port (for example, i8042prt, sermouse, and so on).
value-name
Specifies an entry value under the registry key
HKLM\System\CurrentControlSet\Services\ServiceName\Parameters.
Remarks
Microsoft supports INF DDinstall.MigratetoDevNode sections primarily to facilitate porting Windows NT 4.0
legacy devices to Windows 2000 and later.
The keyboard and mouse class installers copy all the value-name entry values before the system starts the device
stack. The specified entry values can be any valid registry entry values. The value-name entry values are not
deleted from the ...\ServiceName\Parameters registry key.
INF SharedDriver Entry
12/5/2018 • 2 minutes to read • Edit Online

[ControlFlags]
SharedDriver=install-section-name,warning -text-string Before the keyboard or mouse class installer installs a
PS/2 device, it checks for a SharedDriver entry in the INF ControlFlags section for the device. If such an entry
value exists, the class installer notifies the user by displaying the warning text string, and provides the user the
option to cancel changing the PS/2 port driver.
Entries and Values
SharedDriver
Specifies that the device driver is shared by both a PS/2 keyboard and mouse device.
install-section-name
Specifies a device's DDInstall section.
warning -text-string
Specifies a string the class installer uses to warn a user before changing the PS/2 port driver.
INF PS2_Inst.NoInterruptInit.Bioses Section
12/5/2018 • 2 minutes to read • Edit Online

[PS2_Inst.NoInterruptInit.Bioses]
Disable=disable-string The mouse class installer checks if disable-string is a substring of the string value of
HKLM\Hardware\Description\System\SystemBiosVersion. If it is, the class installer executes the INF
directives specified in an INF PS2_Inst.NoInterruptInit section.
Entries and Values
Disable
Set to the disable-string value.
disable-string
Specifies a substring in HKLM\Hardware\Description\System\SystemBiosVersion that uniquely identifies
the system BIOS.
Remarks
This section is used only with PS/2 mouse devices and only in combination with an INF
PS2_Inst.NoInterruptInit section.
INF PS2_Inst.NoInterruptInit Section
12/5/2018 • 2 minutes to read • Edit Online

[PS2_Inst.NoInterruptInit] AddReg = add -reg -section.AddReg The mouse class installer executes the
directives in this section if the Disable entry in an INF PS2_Inst.NoInterruptInit.Bios section matches the
system BIOS version.
Entries and Values
add -reg -section
Specifies an AddReg section that the mouse class installer uses to set registry values in a device's hardware key.
The registry values determine whether the system initializes a mouse device by using interrupts or by polling.
Remarks
This section is only used in combination with an INF PS2_Inst.NoInterruptInit.Bioses section. The primary
purpose of this section is to specify an AddReg section that adds registry values to a mouse device's hardware
key.
add-reg section Entries
HKR,,"DisableInitializePolledUI",0x00010001,1 HKR,,"MouseInitializePolled",0x00010001,1
DisableInitializePolledUI
Specifies a REG_DWORD flag that indicates whether the Fast Initialization check box on the property page will
be available. If DisableInitializePolledUI is set to a nonzero value, the check box is unavailable; otherwise, the
check box is available.
MouseInitializedPolled
Specifies a REG_DWORD flag that indicates whether the system must poll the device to initialize it. If
MouseInitializedPolled is set to one, the system polls the mouse device; otherwise the system uses interrupts.
DirectInput
12/5/2018 • 2 minutes to read • Edit Online

The Microsoft DirectInput documentation describes how to write drivers for the input components of Microsoft
DirectX versions 1.0, 2.0, 3.0, 5.0, 6.0, 7.0, 7.0a, and 8.0. DirectX versions 1.0 and 2.0 included the same joystick
support as the original Microsoft Windows 95, while DirectX 3.0 added Component Object Model (COM )
interfaces for mouse and keyboard access and improved the implementation of some joystick support without
changing the driver model. DirectX 5.0 and later added a COM interface for joystick access, force feedback, and for
simplified access to joystick configuration information.
This documentation includes the following topics:
Joystick Support
Force Feedback Device Driver Interface
Extending the DirectInput Game Controller Control Panel
Joystick Support
12/5/2018 • 2 minutes to read • Edit Online

There are differences from version to version in the type of joystick support that Microsoft DirectX offers. In
Windows 95/98/Me, DirectX supports two methods to customize joystick capabilities: through custom entries in
the Windows registry and through a virtual device driver (VxD ) creation, which is called as joystick minidriver. The
minidrivers that are used in DirectX versions 1.0, 2.0, and 3.0 support the original minidriver interface, with minor
differences in the DirectX 3.0 interface. In addition to the original minidriver model, DirectX versions 5.0, and later,
include an alternative driver interface that is generally described separately.
Windows 95/98/Me joystick driver and configuration programs support analog joysticks that plug into the IBM
standard game port. Joystick makers can make the joystick configuration programs customizable and provide
explicit directions to the end user on how to customize the joystick. Joysticks can signal Windows 95/98/Me about
their capabilities through the registry. These capabilities can include the use of throttle, point-of-view (POV ) hats,
rudders, and the number of joystick buttons.
All non-IBM standard joysticks, such as digital joysticks, MIDI joysticks, and analog joysticks driven by joystick
accelerators must provide a joystick minidriver in addition to custom registry information. A joystick OEM can
write a minidriver that provides access to nonstandard joystick hardware. This provides a mechanism for digital
joysticks to work with any Windows-based game that uses the joystick application programming interface (API).
The driver model can deal with up to six axes, a POV hat, and a double word of buttons, so that an OEM can easily
create a minidriver for new hardware with a higher degree of freedom than the current game port allows. The
joystick minidriver provides complete flexibility to hardware vendors and allows game creators to use the installed
base with their titles. In DirectX 5.0 and later, analog joystick support is also separated into a minidriver that uses a
new interface. This new interface is loaded only when an analog game port is configured. The polling is extended
with three extra POV hats, three more double words that contains button data, and a method to specify that it
returns the velocity, acceleration, and/or force data for each axis.
The current virtual joystick driver (VJoyD ) allows the configuration of up to 16 devices, any number of which can
be driven by minidrivers. The configuration of minidrivers to devices can be one to one or one to many.
This section includes:
Joystick Driver Model
Minidriver-Supplied Callbacks
Original Interface
DirectX 5.0 Interface
INF File Creation
Registry Settings
VJoyD Minidriver Override
Axis Selection
Joystick Driver Model
12/5/2018 • 2 minutes to read • Edit Online

One of the most critical goals of the joystick driver model is to provide timely access to joystick information. Two
drivers provide the Windows 95/98/Me joystick services: a 16-bit ring 3 driver (Msjstick.drv), and a 32-bit ring 0
driver (Vjoyd.vxd). The Msjstick.drv driver provides basic services such as registry update and caps information;
Vjoyd.vxd provides polling services.
The API for the joystick is provided through the Mmsystem.dll dynamic-link library (DLL ) for 16-bit applications
on Windows 95/98/Me, and through the Winmm.dll DLL for 32-bit applications. Mmsystem.dll communicates
with Msjstick.drv for all joystick services (Msjstick.drv communicates with Vjoyd.vxd to supply polling services).
Winmm.dll communicates directly with Vjoyd.vxd for the polling services, and thunks to Mmsystem.dll for the
basic services that are not time-critical.
In DirectX 5.0, DirectInput starts and offers an alternative, COM -based API. Dinput.dll uses VJoyD and, if available,
the Human Interface Device (HID ) stack, to provide polling services. HID devices are also reported through VJoyD
so that applications that use the older API are still able to read the new devices. A driver supplied by the OEM,
which can be either a DLL loaded by Dinput.dll, or an extended VJoyD minidriver, handles the force-feedback.
Minidriver-Supplied Callbacks
12/5/2018 • 2 minutes to read • Edit Online

Joystick hardware that is not polled or that has nonstandard polling requirements can implement a minidriver
(which must be a VxD ) that VJoyD loads when a device of that type is in use. VJoyD also calls the minidriver to
access position and button information. Joystick minidrivers are not required to provide any interfaces other than
to process the standard SYS_DYNAMIC_DEVICE_INIT and SYS_DYNAMIC_DEVICE_EXIT messages when the
device is loaded and unloaded, and to define and register four joystick-specific callbacks. In addition to provide
support for this original interface, the DirectX 5.0 and later VJoyD also support an extended interface. The
extended interface allows registration of new callbacks to support polling, force-feedback, and hot plugging of
joysticks.
On request from Msjstick.drv, VJoyD checks for the minidrivers that should be loaded and unloaded. Msjstick.drv
makes the request for each device it handles and whenever joyConfigChanged receives a call. Msjstick.drv is
initialized for each device it handles during the Normal boot sequence, which means that some devices and
services may be unavailable to the minidriver at the time it is loaded. Because VJoyD loads minidrivers when they
are assigned to a joystick number; not when an application needs to use the device, you should keep the
processing to a minimum. You should not start any background processing, shared resource usage, or large-scale
memory allocations just because the VxD is loaded. VJoyD starts with DirectX 5.0, and does its initial loading of
minidrivers at a later stage in the boot process than the original.
Original Interface
12/5/2018 • 2 minutes to read • Edit Online

The following joystick minidriver callbacks are specific to the original interface:
A Polling Callback to return the joystick position and button information.
A Configuration Manager Callback to handle the configuration manager messages in Windows 95.
A Hardware Capabilities Callback to handle requests for joystick capabilities.
A Joystick Identification Callback used by VJoyD to inform a minidriver of the joysticks, which it should
respond to.
The four joystick-specific callbacks must be registered with the VJoyD VJOYD_Register_Device_Driver service
before returning from processing the SYS_DYNAMIC_DEVICE_INIT message. EAX must point to the polling
routine, EBX (the configuration handler), ECX (the capabilities callback), and EDX (the identification routine). An
example of a joystick minidriver registration sequence is as follows:

Mov eax, offset32 _PollRoutine@8

Mov ebx, offset32 _CfgRoutine

Mov ecx, offset32 _HWCapsRoutine@8

Mov edx, offset32 _JoyIdRoutine@8

VxDcall VJOYD_Register_Device_Driver

In addition to the registration, a minidriver can perform any other initialization at this time. The joystick minidriver
model does not require any specific actions in response to SYS_DYNAMIC_DEVICE_EXIT, though the VxD may
still use it for final internal clean up.
DirectX 5.0 Interface
12/5/2018 • 4 minutes to read • Edit Online

VJoyD and any of its previous versions cannot recognize the DirectX 5.0, and later interfaces. So, it is imperative
that a minidriver checks the version of VJoyD before it attempts to register. VJoyD does not support the standard
version message. So, you must get the device descriptor block (DDB ) for VJoyD to implement this manually, and
then check the version marked in the DDB. For more information on how this can be implemented, see the sample
driver for an example. Notice that the version marked in the DDB is not the same as the version marked in the
version resource.
The process by which a minidriver registers its callbacks is extended significantly and it starts in DirectX 5.0.
Either VJoyD, as before, or an external owner (such as the HID stack) can load Minidrivers. When VJoyD loads a
device, it requires the minidriver to register itself using the VJoyD VJOYD_Register_Device_Driver service.
However, the minidriver may receive three system control messages, which should prompt it to register. The first is
the SYS_DYNAMIC_DEVICE_INIT message, which the minidriver receives if the VxD is not loaded before VJoyD
loads it. This uses the same mechanism as the original interface used for registration. Because it is a fresh load of
the VxD, any defined INIT sections are available. On receipt of this message, the VxD performs internal
initialization and then registers with VJoyD.
If an application has already loaded minidriver (for example, if an application has loaded it to use a private IOCTL
interface), it does not receive this message again when VJoyD loads it. In these circumstances, Windows 98 issues
the SYS_DYNAMIC_DEVICE_REINIT message and a minidriver, in response, should register with VJoyD. Because
this is not a fresh load of the VxD, the INIT sections are no longer available. For minidrivers that does not run
under Windows 98, VJoyD takes the lack of response to load a minidriver as that the VxD is already loaded. VJoyD
issues the directed system control message BEGIN_RESERVED_PRIVATE_SYSTEM_CONTROL, to which the
minidriver should register in response.
In addition to the load-time registration, VJoyD now accepts new types of registration when a driver detects a
change in state of a device that it drives. Besides the callbacks, the DirectX 5.0 interface allows various control
parameters and device descriptions to be set on registration. This includes the full description of the device
(complete with the calibration information), which it can change to fit any other device that it detects.
The joystick minidriver callbacks for the DirectX 5.0 and later interface consist of control callbacks, a polling
callback, and force feedback callbacks. To accommodate these changes, the VJoyD VJOYD_Register_Device_Driver
service is overloaded so that EAX holds 0xFFFFFFFF to signal that the new registration is in use, and ECX holds a
pointer to a structure that holds the parameters. The values of EBX and EDX are undefined and driver may assume
that EBX returns from the call uncorrupted.
The following example shows a joystick minidriver registration sequence:

mov eax, 0ffffffffh

mov ecx, offset32 RegData

VxDcall VJOYD_Register_Device_Driver

The VJREGDRVINFO structure is passed to the new registration.


The dwFunction member of the VJREGDRVINFO structure must be VJRT_LOADED; all other values are
reserved. VJRT_LOADED is used in the new interface in the same way that the registration is used in the original
interface, that is, to pass the callbacks to VJoyD in response to the minidriver being loaded.
The control callbacks and the poll callback are merged into a single table because all drivers must supply the
control callbacks and very few devices are output only (and therefore do not need a poll callback). These callbacks
are registered using the VJPOLLREG structure.
The lpCfg member of the VJPOLLREG structure points to a standard configuration manager callback, exactly like
the CfgRoutine in the original interface. The major difference is that VJoyD calls the configuration manager
callback as appropriate. VJoyD links drivers to the installed device nodes and calls this callback to inform the driver
of configuration manager activity. Whereas the previous interface called all loaded drivers for each configuration
manager callback, the DirectX 5.0 and later interface only calls the one driver it has linked to the device node which
has changed. Also, because configuration manager activity may happen while the driver is not loaded, VJoyD
implements a primitive caching system so that if a device node has been started, the driver is informed of this
device node when it is loaded.
Because drivers are always called for their resource allocations, they should not check default ports to find the
resources they need. Unfortunately, drivers that had to find some way to work with the previous interface still work
in the old way. This means that while VJoyD only allocates a set of resources to a single driver, any old drivers that
are loaded can still use ports that have not been allocated to them. When resources have been allocated, the driver
should perform any handshaking required with the device to determine the device state.
The Initialize callback (pointed to by the fpInitialize member of the VJPOLLREG structure) replaces the JoyId
callback in the previous interface. The main difference is that VJoyD passes back to the driver any device instance
identification that the device passed to VJoyD during registration so the instances can be distinguished if the driver
supports more than one device.
Note If you need to open registry keys, you should use the VJOYD_OpenConfigKey_Service and
VJOYD_OpenTypeKey_Service macros instead of opening the registry keys directly. Using these service macros
ensures that the correct registry branch is opened. In addition, the service macros will be supported in future
versions of DirectInput when the underlying registry data may be structured differently.
Creating an INF File
12/5/2018 • 2 minutes to read • Edit Online

All minidrivers and OEM -defined joysticks should be installed using an INF file to provide all the necessary
information to the system. An INF file describes a device installation in terms of the class of the device, the files
that need to be copied, any compatible devices, any system resources the device requires, and changes to the
registry. INF files for customizing the standard analog driver do not need to copy any files, state compatible
devices, or specify system resources. The INF file can specify other actions, such as modifying the Autoexec.bat file,
but this is not usually necessary for a joystick minidriver.
The INF file contains the elements described in the following topics:
Setting the Device Class
Selecting Source Files
Setting the Manufacturer-Specific Data
Setting Up LogConfig Entries
Setting Up AddReg Entries
Registry Settings
12/5/2018 • 2 minutes to read • Edit Online

The registry is used by the joystick interface to store configuration, calibration, and user preference information. It
is also used to store customized text for the calibration program. The Windows 95/98/Me joystick calibration
program can be customized through the registry to provide instructions to the user during calibration that are
specific to the joystick.
The values fall into five groups:
Original data supplied by the OEM and installed from an INF file (described above).
User Values that specify how data is interpreted.
Current Settings reflecting which devices are currently configured.
Saved Settings that allow different configurations to be recalled.
Driver Settings that are set up by the configuration manager as a device is set up.
The user values, current settings, and saved settings are all stored in the registry under the path belonging to the
"current" joystick driver. Each of the joystick devices for which a driver is installed has a key under the path
REGSTR_PATH_JOYCONFIG that has the form Msjstick.drv<xxxx>, where the xxxx is a four-digit number used to
keep the key name unique. The number relates to the number of multimedia (sound, video and game controller)
drivers that have been installed. At boot time, Msjstick.drv is initialized to the configuration for each of the game
controller drivers. Since it can only deal with one configuration at a time, each one replaces the last and the
"current" driver is the last one to be initialized. This means that the user is likely to lose all the current settings
when a new driver is installed, and a minidriver cannot be structured on the assumption that the path to these
registry values will always be the same.
VJoyD Minidriver Override
3/6/2019 • 2 minutes to read • Edit Online

USB/HID devices that do not load the JoyHID.VxD device driver can sometimes display duplicate device entries
present in the Gaming Options control panel when used with other USB/HID devices. This occurs when a JoyHID -
compliant device is attached to the system at the same time as a non-JoyHID device.
If your device uses a VJoyD minidriver other than JoyHID --presumably developed by the device manufacturer or
an affiliate--you can prevent these issues by properly setting up your device type key and related named values in
the registry. The features described in this topic are available only to devices with type keys in the form
"VID_vvvv&PID_pppp", where the letters v and p are zero-padded vendor and product ID values for the product.
Given a properly formatted type key, the following steps prevent JoyHID from attempting to retrieve data from the
device or displaying unnecessary device entries in Control Panel/add list.
Set OEMData to JOY_HWS_AUTOLOAD. This prevents the device name from being displayed in the add
list for devices.
Set OEMCallout to the driver that should be loaded for the device. This prevents JoyHID.VxD from being
loaded for the device.
Set OEMName to the name appropriate for the device.
If needed, you can set registry values to arbitrary values to prevent JoyHID from reading data from the device. For
example, you might use the following values:

NAME VALUE

OEMName "Unused entry for IHV device X, do not remove"

OEMData OEMData is a binary registry field containing two


DWORDs. The first is a set of JOY_HWS_* flags, the
second is the number of buttons on the device. The value
of the flag JOY_HWS_AUTOLOAD is defined in dinput.h to
be 0x10000000. Since the number of buttons in this case
is irrelevant, the eight bytes (in hex) should be
00,00,00,10,00,00,00,00.

OEMCallout "unused"

Note that values like these merely prevent JoyHID from attempting to read data from the device. If your device
uses a VJoyD minidriver, you should set the preceding values to properly reflect the device name and driver to be
loaded.
Axis Selection
12/5/2018 • 2 minutes to read • Edit Online

This section contains information about how DirectInput maps axes for use by DirectInput and Windows
multimedia applications.
This section includes:
Axis Selection Overrides
Special Case Mappings
Windows 2000, Legacy Interfaces
When using the DirectX 7.0 API on Windows 2000, axis assignments are made in the order in which the axes are
exposed by the device driver, shown in the following table:

USAGE PAGE USAGE DIRECTINPUT AXIS

HID_USAGE_PAGE_GENERIC HID_USAGE_GENERIC_X GUID_XAxis

HID_USAGE_PAGE_GENERIC HID_USAGE_GENERIC_Y GUID_YAxis

HID_USAGE_PAGE_GENERIC HID_USAGE_GENERIC_Z GUID_ZAxis

HID_USAGE_PAGE_GENERIC HID_USAGE_GENERIC_WHEEL GUID_ZAxis

HID_USAGE_PAGE_GENERIC HID_USAGE_GENERIC_RX GUID_RxAxis

HID_USAGE_PAGE_GENERIC HID_USAGE_GENERIC_RY GUID_RyAxis

HID_USAGE_PAGE_GENERIC HID_USAGE_GENERIC_RZ GUID_RzAxis

HID_USAGE_PAGE_GENERIC HID_USAGE_GENERIC_HATSWITCH GUID_POV

HID_USAGE_PAGE_GENERIC HID_USAGE_GENERIC_SLIDER GUID_Slider

HID_USAGE_PAGE_GENERIC HID_USAGE_GENERIC_DIAL GUID_Slider

HID_USAGE_PAGE_SIMULATION HID_USAGE_SIMULATION_STEERIN GUID_XAxis


G

HID_USAGE_PAGE_SIMULATION HID_USAGE_SIMULATION_ACCELE GUID_YAxis


RATOR
USAGE PAGE USAGE DIRECTINPUT AXIS

HID_USAGE_PAGE_SIMULATION HID_USAGE_SIMULATION_BRAKE GUID_RzAxis

HID_USAGE_PAGE_SIMULATION HID_USAGE_SIMULATION_RUDDER GUID_RzAxis

HID_USAGE_PAGE_SIMULATION HID_USAGE_SIMULATION_THROTT GUID_Slider


LE

HID_USAGE_PAGE_GAME HID_USAGE_ SIMULATION_POV GUID_POV

These GUIDs are used by SetDataFormat to match the requested data format to the device objects. For
applications that are compiled with DIRECTINPUT_VERSION < 0x0600, if the data format specifies a GUID_ZAxis
before a GUID_Slider (as the default joystick data format does) and a Slider is found on the device before a Z -axis,
then the Slider will be matched as a Z -axis. This is intended to give better compatibility with HID.
Windows 9x Platforms
Through the DirectX 7.0 interfaces on Windows 95/98/Me, the mapping of a WinMM axis to a DirectInput axis is
one-dimensional:

WINMM AXIS DIRECTINPUT ASSIGNMENT

X GUID_XAxis

Y GUID_YAxis

Z GUID_ZAxis

R GUID_RzAxis

U GUID_Slider

V GUID_Slider

WinMM axes are mapped differently through DirectX 8.0 interfaces, as described below.
Note Although JoyHID.VxD does not yet map the vehicle control usages for steering, accelerate and brake, it
does check for a steering usage and if one is found it treats the device as a WinMM car controller. Also, the DirectX
8.0 version of JoyHID.VxD copies any IHV supplied WinMM controller type flags (JOY_HWS_ISYOKE,
JOY_HWS_ISGAMEPAD, JOY_HWS_ISCARCTRL or JOY_HWS_ISHEADTRACKER ) and button counts, so these
types can be set by the IHV in the OEMData registry value.
The mappings made by the DirectX 8.0 interfaces are different from those made by the legacy interfaces. The
following table describes mappings in the DirectX 8.0 interfaces.
For data retrieved through WinMM, the default mapping is:
WINMM AXIS DIRECTINPUT ASSIGNMENT

X GUID_XAxis

Y GUID_YAxis

Z GUID_Slider

R GUID_RzAxis

U GUID_Slider

V GUID_Slider

Because the third axis on a gaming device is rarely a Z -axis, these mappings help provide better compatibility with
Windows 2000, Windows XP and Windows 95/98/Me HID.
Force Feedback Device Driver Interface
12/5/2018 • 2 minutes to read • Edit Online

This section covers the interface between DirectInput and the device-specific force feedback driver. The following
topics are covered:
OEMForceFeedback Registry Settings
Driver Interface
User-Mode Functions
Extending the DirectInput Game Controller Control
Panel
12/5/2018 • 2 minutes to read • Edit Online

This section provides information about creating property sheets for the Microsoft DirectInput game controller
control panel. The information is divided into the following topics:
About the DirectInput Control Panel
DirectInput Control Panel Architecture
DirectInput Control Panel Essentials
Hdpi.h Macros
5/24/2019 • 2 minutes to read • Edit Online

The Hdpi.h header file contains several macros. This topic documents the following macros:
HidP_GetButtons
HidP_GetButtonsEx
HidP_SetButtons
HidP_UnsetButtons

HidP_GetButtons
The HidP_GetButtons macro is a mnemonic alias for the HidP_GetUsages routine.

#define HidP_GetButtons(Rty, UPa, LCo, ULi, ULe, Ppd, Rep, RLe) \


HidP_GetUsages(Rty, UPa, LCo, ULi, ULe, Ppd, Rep, RLe)

HidP_GetButtonsEx
The HidP_GetButtonsEx macro is an mnemonic alias for the HidP_GetUsagesEx routine.

#define HidP_GetButtonsEx(Rty, LCo, BLi, ULe, Ppd, Rep, RLe) \


HidP_GetUsagesEx(Rty, LCo, BLi, ULe, Ppd, Rep, RLe)

HidP_SetButtons
The HidP_SetButtons macro is a mnemonic alias for the HidP_SetUsages routine.

#define HidP_SetButtons(Rty, Up, Lco, ULi, ULe, Ppd, Rep, Rle) \


HidP_SetUsages(Rty, Up, Lco, ULi, ULe, Ppd, Rep, Rle)

HidP_UnsetButtons
The HidP_UnsetButtons macro is a mnemonic alias for the HidP_UnsetUsages routine.

#define HidP_UnsetButtons(Rty, Up, Lco, ULi, ULe, Ppd, Rep, Rle) \


HidP_UnsetUsages(Rty, Up, Lco, ULi, ULe, Ppd, Rep, Rle)

Requirements
Header Hidpi.h (include Hidpi.h)

See also
HidP_GetUsages
HidP_GetUsagesEx
HidP_SetUsages
HidP_UnsetUsages

You might also like