* The preview only shows a few pages of manuals at random. You can get the complete content by filling out the form below.
Description
Contents Introduction to Human Interface Devices (HID) HID Architecture HID Application Programming Interface (API) HID Clients HID Clients Overview HID Usages HID Collections HID Collections Overview 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 and Reading 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 Topics 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 Transport Overview ACPI button device HID button drivers Virtual HID Framework (VHF) Transport Minidrivers Transport Minidriver Overview Binding minidrivers to the HID class Minidrivers and the HID class driver Minidriver requirements for tablet PCs HID over USB HID over USB Overview Architecture of HID over USB Plug and play support Power management Selective suspend for HID over USB devices HID over I2C Introduction to HID over I2C Architecture and overview Plug and play support and power management Power management for I²C transport Troubleshooting common errors Event tracing Non-HID legacy devices and drivers Non-HID legacy devices
Non-HID legacy devices Keyboard and mouse class drivers PS/2 (i8042prt) driver 3rd party filter drivers Installing OS Drivers OS Driver installation INF DDInstall.MigrateToDevNode Section INF SharedDriver Entry INF PS2_Inst.NoInterruptInit.Bioses Section INF PS2_Inst.NoInterruptInit Section DirectInput DirectInput Overview Joystick Support Joystick Support Overview 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
Introduction to Human Interface Devices (HID) 9/23/2020 • 2 minutes to read • Edit Online
Human Interface Devices (HID) is a device class definition to replace PS/2-style connectors with a generic USB driver to support HID devices such as keyboards, mice, game controllers, etc. Prior to HID, devices could only utilize strictly-defined protocols for mice and keyboards. Hardware innovation required either overloading data in an existing protocol or creating non-standard hardware with its own specialized driver. HID provided support for these “boot mode” devices while adding support for hardware innovation through extensible, standardized and easilyprogrammable interfaces. HID devices today include a broad range of devices such as alphanumeric displays, bar code readers, volume controls on speakers/headsets, auxiliary displays, sensors and many others. Many hardware vendors also use HID for their proprietary devices. HID began with USB but was designed to be bus-agnostic. It was designed for low latency, low bandwidth devices but with flexibility to specify the rate in the underlying transport. The specification for HID over USB was ratified by the USB-IF in 1996 and support over additional transports followed soon after. Details on currently supported transports can be found in HID Transports Supported in Windows. 3rd-party, vendor-specific transports are also allowed via custom transport drivers.
HID Concepts HID consists of two fundamental concepts, a Report Descriptor, and Reports. Reports are the actual data that is exchanged between a device and a software client. The Report Descriptor describes the format and meaning the data that the device supports. Reports Applications and HID devices exchange data through Reports. There are three Report types: Input Reports, Output Reports, and Feature Reports. REP O RT T Y P E
DESC RIP T IO N
Input Report
Data sent from the HID device to the application, typically when the state of a control changes.
Output Report
Data sent from the application to the HID device, for example to the LEDs on a keyboard.
Feature Report
Data 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 USB-IF working group publishes HID Usage Tables that are part of the Report Descriptors that describe what HID devices are allowed to do. These HID Usage Tables contain a list with descriptions of Usages , which describe the intended meaning and use of a particular item described in the Report Descriptor. For example, a Usage is 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 define the Usage ID that uniquely identifies a specific Usage in the Usage Tables.
See also USB-IF HID Specifications.
HID Architecture 9/23/2020 • 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. M O DE
DRIVERS
A P P L IC AT IO N S
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 Application Programming Interface (API) 9/23/2020 • 2 minutes to read • Edit Online
There are three categories of HID APIs: device discovery and setup, data movement, and report creation/interpretation.
Device Discovery and Setup These HID APIs are used to identify the properties of a HID device and to establish communication with that device. Applications use these APIs 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 These HID APIs are used to move data between an application and a selected device. HidD_GetInputReport HidD_SetFeature HidD_SetOutputReport ReadFile WriteFile
Report Creation and Interpretation Developers of custom hardware know the size and format of each Report issued by their device. In this case the application can cast the input and output Report buffers to structs and consume the data. Developers of HID applications intended to communicate with all devices that expose common functionality (for example a music application that must detect when a play button is pressed) may not know the size and format of the HID Reports. This category of application understands certain Top Level Collections and certain usages. To interpret the Reports received from a device or to create Reports to be sent the application must leverage the Report Descriptor to determine if and where a particular Usage is located in the Reports and (potentially) the units of values in the Reports. In these cases HID parsing is required. Windows provides a HID parser for use by drivers and applications via 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. These are 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 Clients Overview 9/23/2020 • 2 minutes to read • Edit Online
Human Interface Devices (HID) clients are drivers, services or applications that communicate using the HID API and often represent a specific type of device such as a sensor, keyboard, or mouse. Devices are identified by a hardware ID or a specific HID Collection and communicate via the HID API. TO P IC
DESC RIP T IO N
HID usages
HID usages identify the intended use of HID controls and what the controls actually measure.
HID Collections
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.
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 4/15/2020 • 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. 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. A usage page value is a 16-bit unsigned value. Examples of usage pages include: PA GE ID
PA GE N A M E
H IDUSA GE. H C O N STA N T
0x01
Generic Desktop Controls
HID_USAGE_PAGE_GENERIC
0x05
Game Controls
HID_USAGE_PAGE_GAME
0x08
LEDs
HID_USAGE_PAGE_LED
0x09
Button
HID_USAGE_PAGE_BUTTON
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. Examples of controls that are listed on the Generic Desktop Controls usage page:
USA GE ID
USA GE N A M E
H IDUSA GE. H C O N STA N T
0x01
Pointer
HID_USAGE_GENERIC_POINTER
0x02
Mouse
HID_USAGE_GENERIC_MOUSE
0x04
Joystick
HID_USAGE_GENERIC_JOYSTICK
0x05
Game Pad
HID_USAGE_GENERIC_GAMEPAD
0x06
Keyboard
HID_USAGE_GENERIC_KEYBOARD
0x07
Keypad
HID_USAGE_GENERIC_KEYPAD
0x08
Multi-axis Controller
HID_USAGE_GENERIC_MULTI_AXIS_CO NTROLLER
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 Overview 8/17/2019 • 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 9/23/2020 • 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 4/15/2020 • 2 minutes to read • Edit Online
Windows opens the following top-level collections for system use: DEVIC E T Y P E
USA GE PA GE
USA GE ID
W IN DO W S C L IEN T
A C C ESS M O DE
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 Control
0x0C
0x01
hidserv.exe in Windows 2000 and hidserv.dll (one of the SVC host services) in Microsoft Windows XP
Shared
Preparsed Data 9/23/2020 • 2 minutes to read • Edit Online
Preparsed data is report descriptor data associated with a top-level collection. User-mode applications or kernelmode 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 9/23/2020 • 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. L IN K N O DE
PA REN T
C H IL DREN
F IRST C H IL D
N EXT SIB L IN G
A
Top-level Collection
B, C
B
None
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 9/23/2020 • 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_CAPS structures 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 Number XxxDataIndices member.
Button Capability Arrays 9/23/2020 • 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. A L IA SED USA GE O RDER IN A REP O RT DESC RIP TO R
USA GE O RDER IN A C A PA B IL IT Y A RRAY
ISA L IA S M EM B ER VA L UE
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.) USA GE O RDER IN REP O RT DESC RIP TO R
USA GE O RDER IN C A PA B IL IT Y A RRAY
DATA IN DEX O R F RO M DATA IN DEXM IN TO DATAT IN DEXM A X
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 9/23/2020 • 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 Repor tCount 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 9/23/2020 • 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 usermode 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 9/23/2020 • 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 (SetupDi Xxx 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 9/23/2020 • 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 (SetupDi Xxx 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 usermode 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 usermode 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 usermode 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 9/23/2020 • 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 usermode 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 9/23/2020 • 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 Topics 8/17/2019 • 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 9/23/2020 • 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_Set Xxx routines to set control data in the report. On the first use of a report, the HidP_Set Xxx 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_Set Xxx routines return a status of HIDP_STATUS_INCOMPATIBLE_REPORT_ID.
Obtaining HID Reports 9/23/2020 • 4 minutes to read • Edit Online
This section describes how user-mode applications and kernel-mode drivers obtain HID reports from a HID collection.
Obtaining HID Reports by user-mode applications This topic discusses the obtaining of HID input reports or HID feature reports, by user-mode applications using ReadFile or the HidD_Get Xxx routines. However, an application should only use the HidD_Get Xxx routines to obtain the current state of a device. If an application attempts to use HidD_GetInputReport to continuously obtain input reports, the reports can be lost. In addition, some devices might not support HidD_GetInputRepor t , and will become unresponsive if this routine is used. Using ReadFile An application uses the open file handle it obtained by using CreateFile to open a file on the collection. When the application calls ReadFile , it does not have to specify overlapped I/O because the HID Client Drivers buffers reports in a ring buffer. However, an application can use overlapped I/O to have more than one outstanding read request. Using HidD_GetXxx Routines An application can use the following HIDClass support routines to obtain the most current input reports and feature reports from a HID collection: HidD_GetInputReport Returns an input report from a HID collection (Windows XP and later versions). HidD_GetFeature Returns a feature report from a HID collection. An application can request the return of a specific report. To retrieve a specific report using these routines, the application allocates the report output buffer, zero-initializes the buffer, and sets the first byte in the buffer to the specific report ID. For more information, see Initializing HID Reports.
Obtaining HID Reports by kernel-mode drivers This topic discusses how a kernel-mode driver should use IRP_MJ_READ requests as its main approach for continuously obtaining HID input reports. Consecutive read requests return input reports in the order in which they were received from the collection. The driver can also use IOCTL_HID_GET_Xxx requests to obtain input and feature reports. However, a driver should only use these I/O requests to obtain the current state of a device. If the driver attempts to use IOCTL_HID_GET_INPUT_REPORT to continuously obtain input reports, reports can be lost. In addition, some devices might not support IOCTL_HID_GET_INPUT_REPORT , and will become unresponsive if this request is used. Using IRP_MJ_READ Requests Non-WDM Windows 2000 drivers, and drivers for Windows XP and later versions, can use a single IRP for all read requests to a device. However, Windows 2000 WDM drivers must allocate a new IRP for each read request. For general information about how to use and reuse IRPs, see Handling IRPs and Reusing IRPs. If a driver reuses an IRP, the IRP's IoCompletion routine should complete the request with a status of STATUS_MORE_PROCESSING_REQUIRED (and not free the IRP). When the driver no longer requires the IRP, it
should complete and free the IRP by calling IoCompleteRequest and IoFreeIrp. For example, a driver might typically complete and free the IRP in its Unload routine, or after a device is removed. If a driver uses an IRP for only one read request, the IRP's IoCompletion routine should complete and free the IRP, and return STATUS_SUCCESS . Before a driver can request an input report, it must first allocate a zero-initialized input report buffer from nonpaged memory pool. The size, in bytes, of the buffer is specified by the InputRepor tByteLength member of a HID collection's HIDP_CAPS structure. A driver must then use an MDL to map the input report buffer for a read request. The driver calls IoAllocateMdl to allocate the MDL for an input report buffer, and sets the read IRP's Irp>MdlAddress member to the MDL address of the input report buffer. The driver should free the report buffer and the MDL when they are no longer required. In addition to setting the read IRP's MDL address, the driver must also set the I/O stack location of the next lowerlevel driver. A driver obtains access to the I/O stack location of the next lower-level driver by calling IoGetNextIrpStackLocation. The driver sets the following members of the I/O stack location: Parameters.Read.Length Set to the size, in bytes, of the read buffer. This must be greater than or equal to the value specified by the InputReportByteLength member of a HID collection's HIDP_CAPS structure. Parameters.Read.Key Set to zero. Parameters.Read.ByteOffset.QuadPar t Set to zero. MajorFunction Set to IRP_MJ_READ. FileObject Set to the file object pointer that represents the open file on the HID collection. After the driver has obtained an input report, it can access control data, as described in Interpreting HID Reports. Using IOCTL_HID_GET_Xxx Requests A driver can use the following I/O requests to obtain the most current input and feature reports from a HID collection: IOCTL_HID_GET_INPUT_REPORT Returns an input report from a HID collection (Windows XP and later versions). IOCTL_HID_GET_FEATURE Returns a feature report from a HID collection. A driver can request the return of a specific report. To retrieve a specific report using these I/O requests, the driver first allocates the output report buffer, then zero-initializes the buffer, and sets the first byte in the buffer to the specific report ID. For more information, see Interpreting HID Reports.
Sending HID Reports 9/23/2020 • 3 minutes to read • Edit Online
This section describes how user-mode applications and kernel-mode drivers send HID reports to a HID collection.
Sending HID Reports by User-Mode Applications A user-mode application should use WriteFile as its main approach to continuously send output reports to a HID collection. An application can also use HidD_SetXxx routines to send output reports and feature reports to a collection. However, an application should only use these routines to set the current state of a collection. Some devices might not support HidD_SetOutputReport and will become unresponsive if this routine is used.
Using WriteFile An application should use write requests to send output reports to a HID collection. After a user-mode application has created an output report, it can send an output report to a collection using WriteFile.
Using HidD_SetXxx Routines An application can use the following HIDClass support routines to send HID reports to a HID collection: HidD_SetOutputReport Sends an output report to a HID collection (Windows XP and later versions). HidD_SetFeature Sends a feature report to a HID collection.
Sending HID Reports by Kernel-Mode Drivers A kernel-mode driver should use IRP_MJ_WRITE requests as its main approach to continuously send output report to a HID collection. Drivers can also use IOCTL_HID_SET_Xxx requests to send output reports and feature reports to a collection. However, a driver should only use these I/O requests to set the current state of a collection. Some devices might not support IOCTL_HID_SET_OUTPUT_REPORT and will become unresponsive if this request is used.
Using IRP_MJ_WRITE Requests Non-WDM Windows 2000 drivers, and drivers for Windows XP and later versions, can use a single IRP for all write requests sent to a collection. However, Windows 2000 WDM drivers must allocate a new IRP for each write request. For more information about how to use and reuse IRPs, see Handling IRPs and Reusing IRPs. If the driver reuses a write IRP, the IRP's IoCompletion routine should complete the request with a status of STATUS_MORE_PROCESSING_REQUIRED (and not free the IRP). When the driver no longer requires the IRP, it should complete and free the IRP by calling IoCompleteRequest and IoFreeIrp. For example, a driver might typically complete and free the IRP in its Unload routine, or after a device is removed. If a driver uses an IRP for only one write request, the IRP's IoCompletion routine should complete and free the IRP, and return STATUS_SUCCESS . Before sending an output report, a driver must first initialize and set an output report buffer, as described in Initializing HID Reports. The driver must then use an MDL to map the output report buffer for a write request. A driver calls IoAllocateMdl to allocate the MDL for an output report, and sets a write IRP's Irp->MdlAddress member to the MDL address of the output report buffer. The driver must free the report buffer and the MDL when they are no longer required.
In addition to setting the write IRP's MDL address, the driver must also set the I/O stack location of the next lowerlevel driver. A driver obtains access to the I/O stack location of the next lower-level driver by calling IoGetNextIrpStackLocation. The driver sets the following members of the I/O stack location: Parameters.Write.Length Set to the length, in bytes, of an output report. This should be set to the length of a HID collection's output reports, as specified by the OutputReportByteLength member of a collection's HIDP_CAPS structure. Parameters.Write.Key Set to zero. Parameters.Write.ByteOffset.QuadPar t Set to zero. MajorFunction Set to IRP_MJ_WRITE. FileObject Set to the file object pointer that represents the open file on the HID collection.
Using IOCTL_HID_SET_Xxx Requests A driver can also use the following I/O requests to send output and feature reports to a HID collection: IOCTL_HID_SET_OUTPUT_REPORT Sends an output report to a collection (Windows XP and later versions). IOCTL_HID_SET_FEATURE Sends a feature report to a collection.
Interpreting HID Reports 9/23/2020 • 4 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.
Extracting Value Data by Specifying Its Usage To extract value data from a HID report, an application or driver can use one of the following HID support routines: HidP_GetScaledUsageValue Returns a signed and scaled value. HidP_GetUsageValue Returns a nonscaled value in an unsigned format or a scaled value that is out of its Normal range. HidP_GetUsageValueArray Returns a usage value array. To use HidP_GetUsageValueArray applications and drivers must allocate a zero-initialized buffer, which is large enough to hold the usage value array. The required size in bytes is the product of the BitSize and Repor tCount members of the usage value array's HIDP_VALUE_CAPS structure, rounded up to the nearest byte.
Extracting Button Usages That Are Set to ON To extract the HID usages of buttons that are set to ON (1), applications and drivers call one of the following HID support routines: HidP_GetButtons (or HidP_GetUsages) Returns the usage ID of all buttons on a specified usage page that are set to ON. HidP_GetButtonsEx (or HidP_GetUsagesEx) Returns the usage page and usage ID of all buttons that are set to ON. These routines return an array of all usage information for all buttons that are currently set to ON. Implicitly, buttons whose usage is not returned by these routines are set to OFF (zero). To call these routines, applications and drivers must first allocate and zero-initialize the buffer used to return the array of button usages. An application or driver calls HidP_MaxUsageListLength to determine the number of button usages in a specified usage page in the report. If the application or driver specifies a usage page of zero, the routine returns the number of all the button usages in the report. The required buffer size, in bytes, is the following: (For HidP_GetButtons) The value returned by HidP_MaxUsageListLength times sizeof(USAGE) (For HidP_GetButtonsEx) The value returned by HidP_MaxUsageListLength times sizeof(USAGE_AND_PAGE) After an application or driver has used these routines to obtain information about which buttons are currently set to ON, it can determine the difference between the current state and the previous state of the buttons by calling one of the following HIDClass support routines. These routines return the difference between two arrays of usage information: HidP_UsageListDifference HidP_UsageAndPageListDifference
Extracting and Setting Control Data by Data Indices To use data indices to extract and set control data in a HID report, an application or driver can use the following HIDClass support routines: HidP_GetData HidP_SetData These routines are particularly useful to an application or driver that provides a "value-added" service. For example, one that provides a custom interface to all the controls supported by a HIDClass device. Microsoft DirectInput is one example. By calling these routines, an application or driver can most efficiently obtain and set all values in a report. For example, to obtain all value data by their HID usages it has to call HidP_GetUsageValue for each usage. However, to obtain all value data by data index, it only has to call HidP_GetData once. An application or driver uses the data indices specified in a collection's Button Capability Arrays and Value Capability Arrays to identify HID usages.
Setting Value Data by Specifying Its Usage An application or driver can set a value in a properly-initialized HID report by calling one of the following HID support routines: HidP_SetScaledUsageValue Sets a signed and scaled value in a report. HidP_SetUsageValue Sets a value in a report. HidP_SetUsageValueArray Sets a usage value array in a report.
Setting Button State by Specifying Its Usage An application or driver can set the state of buttons in a properly-initialized HID report by calling one of the following HIDClass support routines: HidP_SetButtons (or HidP_SetUsages) Sets a specified set of buttons to ON (1). HidP_UnsetButtons (or HidP_UnsetUsages) Sets a specified set of buttons to OFF (zero).
Extracting and Setting HID Control Data by Data Indices To use data indices to extract and set control data in a HID report, an application or driver can use the following HIDClass support routines: HidP_GetData HidP_SetData These routines are particularly useful to an application or driver that provides a "value-added" service. For example, one that provides a custom interface to all the controls supported by a HIDClass device. Microsoft DirectInput is one example. By calling these routines, an application or driver can most efficiently obtain and set all values in a report. For example, to obtain all value data by their HID usages, it has to call HidP_GetUsageValue for each usage. However, to obtain all value data by data index, it only has to call HidP_GetData once. An application or driver uses the data indices specified in a collection's Button Capability Arrays and Value Capability Arrays to identify HID usages.
See also Initializing HID Reports
Troubleshooting HID Reports 9/23/2020 • 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_Get Xxx 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_Set Xxx 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_Get Xxx 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 9/23/2020 • 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 9/23/2020 • 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 9/23/2020 • 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 TYPE
SIN GL E T L C
M ULT IP L E T L C
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. DEVIC E T Y P E
USA GE PA GE
USA GE
H A RDWA RE ID
Pointer
0x01
0x01
HID_DEVICE_SYSTEM_MOU SE
Mouse
0x01
0x02
HID_DEVICE_SYSTEM_MOU SE
Joystick
0x01
0x04
HID_DEVICE_SYSTEM_GAME
Game pad
0x01
0x05
HID_DEVICE_SYSTEM_GAME
Keyboard
0x01
0x06
HID_DEVICE_SYSTEM_KEYB OARD
Keypad
0x01
0x07
HID_DEVICE_SYSTEM_KEYB OARD
System control
0x01
0x80
HID_DEVICE_SYSTEM_CONT ROL
Consumer audio control
0x0C
0x01
HID_DEVICE_SYSTEM_CONS UMER
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: F IEL D
C O N TA IN S
H EXA DEC IM A L VA L UE
M EA N IN G
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 9/23/2020 • 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. F EAT URE
W IN DO W S XP
W IN DO W S VISTA
W IN DO W S 7
W IN DO W S 8 A N D L AT ER
Buttons 1-5
Supported (P/2 & HID)
Supported (PS/2 & HID)
Supported (PS/2 & HID)
Supported (PS/2 & HID)
Vertical Scroll Wheel
Supported (PS/2 & HID)
Supported (PS/2 & HID)
Supported (PS/2 & HID)
Supported (PS/2 & HID)
Horizontal Scroll Wheel
Not Supported
Supported(HID only)
Supported(HID only)
Supported(HID only)
Smooth Scroll Wheel Support (Horizontal and Vertical)
Not Supported
Partly Supported
Supported (HID only)
Supported (HID only)
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 ) C OMME NT
BYT E
D7
D6
D5
D4
D3
D2
D1
D0
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) C OMME NT
BYT E
D7
D6
D5
D4
D3
D2
D1
D0
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)
C OMME NT
BYT E
D7
D6
D5
D4
D3
D2
D1
D0
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 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 IOCTL_INTERNAL_I8042_HOOK_KEYBOARD
The IOCTL_INTERNAL_I8042_HOOK_KEYBOARD request does the following: 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 IOCTL_INTERNAL_KEYBOARD_CONNECT 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. IOCTL_INTERNAL_KEYBOARD_CONNECT
The IOCTL_INTERNAL_KEYBOARD_CONNECT request connects the Kbdclass service to the keyboard device. 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 CONNECT_DATA (Kbdclass) 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 KeyboardClassSer viceCallback , 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. IOCTL_INTERNAL_KEYBOARD_DISCONNECT
The IOCTL_INTERNAL_KEYBOARD_DISCONNECT request is completed with a status of 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 PI8042_KEYBOARD_INITIALIZATION_ROUTINE The KbFilter_InitializationRoutine is not needed if the I8042prt default initialization of a keyboard is sufficient. 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 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 PI8042_KEYBOARD_ISR . This callback is not needed if the default operation of I8042prt is sufficient. 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.
/* 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 PSERVICE_CALLBACK_ROUTINE . The ISR dispatch completion routine of the function driver calls KbFilter_Ser viceCallback , which then calls the keyboard class driver's implementation of PSERVICE_CALLBACK_ROUTINE. 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. Moufiltr control codes IOCTL_INTERNAL_I8042_HOOK_MOUSE
The IOCTL_INTERNAL_I8042_HOOK_MOUSE request adds an ISR callback routine to the I8042prt mouse ISR. The ISR callback is optional and is provided by an upper-level mouse filter driver. I8042prt sends this request after it receives an IOCTL_INTERNAL_MOUSE_CONNECT 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. Moufiltr Callback Routines IOCTL_INTERNAL_MOUSE_CONNECT
The IOCTL_INTERNAL_MOUSE_CONNECT request connects Mouclass service to a mouse device. IOCTL_INTERNAL_MOUSE_DISCONNECT
The IOCTL_INTERNAL_MOUSE_DISCONNECT request is completed by Moufiltr with an error status of 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
MouFilter_IsrHook
See PI8042_MOUSE_ISR . /* 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 PSERVICE_CALLBACK_ROUTINE
/* 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 changesensitivity 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), HID_LOGICAL_MAX_8(0xFF), HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_EVENT, HID_LOGICAL_MIN_8(0x00), HID_LOGICAL_MAX_8(0xFF), HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs),
//LOGICAL_MINIMUM (0) //LOGICAL_MAXIMUM (255)
//LOGICAL_MINIMUM (0) //LOGICAL_MAXIMUM (255)
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 9/23/2020 • 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. USA GE ID
USA GE N A M E
USA GE T Y P E
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) USAGE (Wireless Radio Controls) COLLECTION (Application) LOGICAL_MINIMUM (0) LOGICAL_MAXIMUM (1) USAGE (Wireless Radio Button) REPORT_COUNT (1) REPORT_SIZE (1) INPUT (Data,Var,Rel) REPORT_SIZE (7) INPUT (Cnst,Var,Abs) END_COLLECTION
05 09 A1 15 25 09 95 75 81 75 81 C0
01 0C 01 00 01 C6 01 01 06 07 03
Stateless Button with LED USAGE_PAGE (Generic Desktop) USAGE (Wireless Radio Controls) COLLECTION (Application) LOGICAL_MINIMUM (0) LOGICAL_MAXIMUM (1) USAGE (Wireless Radio Button) REPORT_COUNT (1) REPORT_SIZE (1) INPUT (Data,Var,Rel) REPORT_SIZE (7) INPUT (Cnst,Var,Abs) USAGE (Wireless Radio LED) REPORT_SIZE (1) OUTPUT (Data,Var,Rel) REPORT_SIZE (7) OUTPUT (Cnst,Var,Abs) END_COLLECTION
Slider Switch (without LED)
05 09 A1 15 25 09 95 75 81 75 81 09 75 91 75 91 C0
01 0C 01 00 01 C6 01 01 06 07 03 C7 01 02 07 03
USAGE_PAGE (Generic Desktop) USAGE (Wireless Radio Controls) COLLECTION (Application) LOGICAL_MINIMUM (0) LOGICAL_MAXIMUM (1) USAGE (Wireless Radio Slider Switch) REPORT_COUNT (1) REPORT_SIZE (1) INPUT (Data,Var,Abs) REPORT_SIZE (7) INPUT (Cnst,Var,Abs) END_COLLECTION
05 09 A1 15 25 09 95 75 81 75 81 C0
01 0C 01 00 01 C8 01 01 02 07 03
05 09 A1 15 25 09 95 75 81 75 81 09 75 91 75 91 C0
01 0C 01 00 01 C8 01 01 02 07 03 C7 01 02 07 03
Slider Switch with LED USAGE_PAGE (Generic Desktop) USAGE (Wireless Radio Controls) COLLECTION (Application) LOGICAL_MINIMUM (0) LOGICAL_MAXIMUM (1) USAGE (Wireless Radio Slider Switch) REPORT_COUNT (1) REPORT_SIZE (1) INPUT (Data,Var,Abs) REPORT_SIZE (7) INPUT (Cnst,Var,Abs) USAGE (Wireless Radio LED) REPORT_SIZE (1) OUTPUT (Data,Var,Rel) REPORT_SIZE (7) OUTPUT (Cnst,Var,Abs) END_COLLECTION
LED Only (No button or slider) USAGE_PAGE (Generic Desktop) USAGE (Wireless Radio Controls) COLLECTION (Application) LOGICAL_MINIMUM (0) LOGICAL_MAXIMUM (1) USAGE (Wireless Radio LED) REPORT_COUNT (1) REPORT_SIZE (1) OUTPUT (Data,Var,Rel) REPORT_SIZE (7) OUTPUT (Cnst,Var,Abs) END_COLLECTION
05 09 A1 15 25 09 95 75 91 75 91 C0
01 0C 01 00 01 C7 01 01 02 07 03
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 6/25/2019 • 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: USA GE ID
USA GE N A M E
USA GE T Y P E
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 Transport Overview 9/23/2020 • 2 minutes to read • Edit Online
HID transports supported in Windows T RA N SP O RT
IN - B O X M IN IDRIVER
VERSIO N
N OT ES
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 using the included drivers for transports listed in the preceding table. If a device requires a transport other than USB, Bluetooth, Bluetooth LE, or I²C, a miniport driver as described in Transport Minidrivers is recommended.
HID transport limits Repor t 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 Repor t Descriptor The Hidclass/Hidparse driver pair is aware of the number of TLCs in a Report Descriptor. HID miniport drivers do not have that information. Each TLC has at least 2 bytes to start a collection and 1 byte to end the collection. Input/Output/Feature Repor t 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.
IN - B O X M IN IDRIVER
REP O RT DESC RIP TO R L EN GT H
T L C S IN O N E REP O RT DESC RIP TO R
IN P UT / O UT P UT / F EAT URE REP O RT L EN GT H
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
See Also 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.
ACPI button device 9/23/2020 • 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 // }, Package(5) { 1, // 1, // 1, // 0x0C, // 0xE9 // }, Package(5) { 1, // 2, // 1, // 0x0C, // 0xEA // }, Package(5) { 1, // 3, // 1, // 0x90, // 0x20 // }, Package(5) { 1, // 4, // 1, // 0x90, // 0x21 // }, Package(5) { 1, // 5, // 1, // 0x0C, // 0x224 // }, Package(5) { 1, // 6, // 1, // 0x07, // 0xE3 // }, Package(5) { 1, // 7, // 1, // 0x0C, // 0x221 // }
Usage ("System Power Down")
This is a Control Interrupt index in _CRS for Volume Up Button Unique ID of Parent Collection Usage Page ("Consumer Page") Usage ("Volume Increment")
This is a Control Interrupt index in _CRS for Volume Down Button Unique ID of Parent Collection Usage Page ("Consumer Page") Usage ("Volume Decrement")
This is a Control Interrupt index in _CRS for Camera Auto-focus Button Unique ID of Parent Collection Usage Page ("Camera Control Page") Usage ("Camera Auto-focus")
This is a Control Interrupt index in _CRS for Camera Shutter Button Unique ID of Parent Collection Usage Page ("Camera Control Page") Usage ("Camera Shutter")
This is a Control Interrupt index in _CRS for Back Button Unique ID of Parent Collection Usage Page ("Consumer Page") Usage ("AC Back")
This is a Control Interrupt index in _CRS for Windows/Home Button Unique ID of Parent Collection Usage Page ("Keyboard Page") Usage ("Keyboard Left GUI")
This is a Control Interrupt index in _CRS for Search Button Unique ID of Parent Collection Usage Page ("Consumer Page") 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, 25, 01, 75, 01,
// LOGICAL_MINIMUM (0) // LOGICAL_MAXIMUM (1) // REPORT_SIZE (1)
06, 0A, A1, 85,
01, 0D, 01, 01,
// USAGE_PAGE (Generic Desktop) // USAGE (Portable Device Control) // COLLECTION (Application) // REPORT_ID (1) (For Input Report & Feature Report)
06, 0A, A1, 06, 0A, 95, 81, 05, 09, 95, B1, C0,
01, 0D, 02, 01, 81, 01, 02, 01, CB, 01, 02,
// // // // // // // // // // // //
USAGE_PAGE (Generic Desktop) USAGE (Portable Device Control) COLLECTION (Logical) USAGE_PAGE (Generic Desktop) USAGE (System Power Down) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Control Enable) REPORT_COUNT (1) FEATURE (Data,Var,Abs) END_COLLECTION
06, 0A, A1, 06, 0A, 95, 81, 05, 09, 95, B1, C0,
01, 0D, 02, 0C, E9, 01, 02, 01, CB, 01, 02,
// // // // // // // // // // // //
USAGE_PAGE (Generic Desktop) USAGE (Portable Device Control) COLLECTION (Logical) USAGE_PAGE (Consumer Devices) USAGE (Volume Increment) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Control Enable) REPORT_COUNT (1) FEATURE (Data,Var,Abs) END_COLLECTION
06, 0A, A1, 06, 0A, 95, 81, 05, 09, 95, B1, C0,
01, 0D, 02, 0C, EA, 01, 02, 01, CB, 01, 02,
// // // // // // // // // // // //
USAGE_PAGE (Generic Desktop) USAGE (Portable Device Control) COLLECTION (Logical) USAGE_PAGE (Consumer Devices) USAGE (Volume Decrement) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Control Enable) REPORT_COUNT (1) FEATURE (Data,Var,Abs) END_COLLECTION
06, 0A, A1, 06, 0A, 95, 81, 05, 09, 95, B1,
01, 0D, 02, 90, 20, 01, 02, 01, CB, 01, 02,
// // // // // // // // // // //
USAGE_PAGE (Generic Desktop) USAGE (Portable Device Control) COLLECTION (Logical) USAGE_PAGE (Camera Control) USAGE (Camera Auto-focus) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Control Enable) REPORT_COUNT (1) FEATURE (Data,Var,Abs)
// Power Button
// Volume Up Button
// Volume Down Button
// Camera Auto-focus Button
C0,
//
END_COLLECTION
06, 0A, A1, 06, 0A, 95, 81, 05, 09, 95, B1, C0,
01, 0D, 02, 90, 21, 01, 02, 01, CB, 01, 02,
// // // // // // // // // // // //
USAGE_PAGE (Generic Desktop) USAGE (Portable Device Control) COLLECTION (Logical) USAGE_PAGE (Camera Control) USAGE (Camera Shutter) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Control Enable) REPORT_COUNT (1) FEATURE (Data,Var,Abs) END_COLLECTION
06, 0A, A1, 06, 0A, 95, 81, 05, 09, 95, B1, C0,
01, 0D, 02, 0C, 224, 01, 02, 01, CB, 01, 02,
// // // // // // // // // // // //
USAGE_PAGE (Generic Desktop) USAGE (Portable Device Control) COLLECTION (Logical) USAGE_PAGE (Consumer Page) USAGE (AC Back) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Control Enable) REPORT_COUNT (1) FEATURE (Data,Var,Abs) END_COLLECTION
06, 0A, A1, 06, 0A, 95, 81, 05, 09, 95, B1, C0,
01, 0D, 02, 07, E3, 01, 02, 01, CB, 01, 02,
// // // // // // // // // // // //
USAGE_PAGE (Generic Desktop) USAGE (Portable Device Control) COLLECTION (Logical) USAGE_PAGE (Keyboard) USAGE (Keyboard Left GUI) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Control Enable) REPORT_COUNT (1) FEATURE (Data,Var,Abs) END_COLLECTION
06, 0A, A1, 06, 0A, 95, 81, 05, 09, 95, B1, C0,
01, 0D, 02, 0C, 221, 01, 02, 01, CB, 01, 02,
// // // // // // // // // // // //
USAGE_PAGE (Generic Desktop) USAGE (Portable Device Control) COLLECTION (Logical) USAGE_PAGE (Consumer) USAGE (AC Search) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Control Enable) REPORT_COUNT (1) FEATURE (Data,Var,Abs) END_COLLECTION
C0
// Camera Shutter Button
// Back Button
// Windows/Home Button
// Search Button
// 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, // 0x09, 0x0D, // 0xA1, 0x01, // 0x85, 0x01, // 0x05, 0x09, // 0x09, 0x01, // 0x09, 0x02, // 0x09, 0x03, // 0x15, 0x00, // 0x25, 0x01, // 0x75, 0x01, // 0x95, 0x09, // 0x81, 0x02, // 0x95, 0x07, // 0x81, 0x03, // 0xC0, // };
{ USAGE_PAGE (Generic Desktop Controls) USAGE (Portable Device Buttons) COLLECTION (Application) REPORT_ID (1) USAGE_PAGE (Button Page) USAGE (Button 1 - HeadSet : Middle Button) USAGE (Button 2 - HeadSet : Volume Up Button) USAGE (Button 3 - HeadSet : Volume Down Button) LOGICAL_MINIMUM (0) LOGICAL_MAXIMUM (1) REPORT_SIZE (1) REPORT_COUNT (3) INPUT (Data,Var,Abs) REPORT_COUNT (5) // 5 unused bits in 8-bit Input Report. INPUT (Cnst,Var,Abs) 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, 1, 0x0C, 0xEA
// // // //
}, Package(5) { 1, // 3, // 1, // 0x07, // 0xE3 // }, Package(5) { 1, // 4, // 1, // 0x01, // 0xCA // }
Interrupt index in _CRS for Volume Down Button Unique ID of Parent Collection Usage Page ("Consumer Page") Usage ("Volume Decrement")
This is a Control Interrupt index in _CRS for Windows/Home Button Unique ID of Parent Collection Usage Page ("Keyboard Page") Usage ("Keyboard Left GUI")
This is a Control Interrupt index in _CRS for Rotation Lock Button Unique ID of Parent Collection Usage Page ("Generic Desktop Page") 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, 25, 01, 75, 01,
// LOGICAL_MINIMUM (0) // LOGICAL_MAXIMUM (1) // REPORT_SIZE (1)
06, 0A, A1, 85,
01, 0D, 01, 01,
// USAGE_PAGE (Generic Desktop) // USAGE (Portable Device Control) // COLLECTION (Application) // REPORT_ID (1) (For Input Report & Feature Report)
06, 0A, A1, 06, 0A, 95, 81, 05, 09, 95, B1, C0,
01, 0D, 02, 07, E3, 01, 02, 01, CB, 01, 02,
// // // // // // // // // // // //
USAGE_PAGE (Generic Desktop) USAGE (Portable Device Control) COLLECTION (Logical) USAGE_PAGE (Keyboard) USAGE (Keyboard LGUI) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Control Enable) REPORT_COUNT (1) FEATURE (Data,Var,Abs) END_COLLECTION
// Windows/Home Button
06, 0A, A1, 06, 0A, 95, 81, 05, 09, 95, B1, C0,
01, 0D, 02, 01, 81, 01, 02, 01, CB, 01, 02,
// // // // // // // // // // // //
USAGE_PAGE (Generic Desktop) USAGE (Portable Device Control) COLLECTION (Logical) USAGE_PAGE (Generic Desktop) USAGE (System Power Down) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Control Enable) REPORT_COUNT (1) FEATURE (Data,Var,Abs) END_COLLECTION
06, 0A, A1, 06, 0A, 95, 81, 05, 09, 95, B1, C0,
01, 0D, 02, 0C, E9, 01, 02, 01, CB, 01, 02,
// // // // // // // // // // // //
USAGE_PAGE (Generic Desktop) USAGE (Portable Device Control) COLLECTION (Logical) USAGE_PAGE (Consumer Devices) USAGE (Volume Increment) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Control Enable) REPORT_COUNT (1) FEATURE (Data,Var,Abs) END_COLLECTION
06, 0A, A1, 06, 0A, 95, 81, 05, 09, 95, B1, C0,
01, 0D, 02, 0C, EA, 01, 02, 01, CB, 01, 02,
// // // // // // // // // // // //
USAGE_PAGE (Generic Desktop) USAGE (Portable Device Control) COLLECTION (Logical) USAGE_PAGE (Consumer Devices) USAGE (Volume Decrement) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Control Enable) REPORT_COUNT (1) FEATURE (Data,Var,Abs) END_COLLECTION
06, 0A, A1, 06, 0A, 95, 81, 95, 81, 05, 09, 95, B1, 95, B1, C0,
01, 0D, 02, 01, CA, 01, 02, 06, 03, 01, CB, 01, 02, 06, 03,
// // // // // // // // // // // // // // // //
USAGE_PAGE (Generic Desktop) USAGE (Portable Device Control) COLLECTION (Logical) USAGE_PAGE (Generic Desktop) USAGE (System Display Rotation Lock Slider Switch) // Rotation Lock Button REPORT_COUNT (1) INPUT (Data,Var,Abs) REPORT_COUNT (3) // 3 unused bits in 8-bit Input Report INPUT (Cnst,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Control Enable) REPORT_COUNT (1) FEATURE (Data,Var,Abs) REPORT_COUNT (3) // 3 unused bits in 8-bit Feature Report FEATURE (Cnst,Var,Abs) END_COLLECTION
C0 };
// END_COLLECTION
// Power Button
// Volume Up Button
// Volume Down Button
HID button drivers 9/23/2020 • 2 minutes to read • Edit Online
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 (Microsoftprovided). 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 transportminidrivers 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) 9/23/2020 • 10 minutes to read • Edit Online
Summar y 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 Impor tant 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 librar y (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 , WriteRepor t , or GetInputRepor t , 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 EvtVhfAsyncOperationGetInputRepor t 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 EvtVhfAsyncOperationGetInputRepor t 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 EvtVhfAsyncOperationWriteRepor t 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 VhfReadRepor tSubmit . 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 VhfReadRepor tSubmit to submit a report. It must wait for EvtVhfReadyForNextReadReport to get invoked before
it can call VhfReadRepor tSubmit 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. 2. 3. 4. 5.
HID source driver stops initiating calls into VHF. HID source calls VhfDelete with Wait set to FALSE. VHF stops invoking callback functions implemented by the HID source driver. VHF starts reporting the device as missing to PnP Manager. At this point, the VhfDelete call might return. 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 Minidriver Overview 9/23/2020 • 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 Transpor ts . 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. With regard to HID Transport minidrivers, the KMDF model has the following caveats: Advantage: KMDF support is available in all Windows platforms that supports WDF. Required for all keyboard and mouse filter drivers. Challenge: Poorly written KMDF HID transport minidrivers can crash the system. Here are HID-specific caveats for the UMDF model: Advantage: UMDF is easier to develop and recommended for most vertical device classes. Errors in this driver do not bug check the whole system. For more information, see Advantages of Writing UMDF Drivers . Challenge: UMDF HID transport minidrivers are not supported on 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 Star ted with UMDF
Binding minidrivers to the HID class 9/23/2020 • 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 9/23/2020 • 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 DriverEntr y 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 DriverEntr y 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 DriverEntr y 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 9/23/2020 • 3 minutes to read • Edit Online
This section pertains to operating systems prior to Windows 8 and describes the general requirements for vendorsupplied 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 systemsupplied 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 Overview 2/28/2020 • 2 minutes to read • Edit Online
USB was the first supported HID transport in Windows. The corresponding in-box driver was introduced in Windows 2000 and has been available in all operating systems since then. This driver 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.
See also HID USB homepage HID USB specification HID Usage Tables
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 9/23/2020 • 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
HID power management over USB 9/23/2020 • 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. NOTE: 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. 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.
Selective suspend for HID over USB devices 9/23/2020 • 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 Class ClassGuid Provider DriverVer CatalogFile
="$WINDOWS NT$" =HIDClass ={745a17a0-74d3-11d0-b6fe-00a0c90f57da} =%VendorName% =09/19/2008,6.0.0.0 =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 CL ASSGUID and DriverVer directives set as follows: The CL ASSGUID 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.
Introduction to HID over I2C 8/17/2019 • 2 minutes to read • Edit Online
For Windows 8, Microsoft created a new HID miniport driver that allows devices to communicate over an InterIntegrated 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 9/23/2020 • 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 subordinate 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 9/23/2020 • 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. F IEL D
VA L UE
A C P I O B JEC T
F O RM AT
C O M M EN T S
Compatible ID
PNP0C50
_CID
String in the format of ACPI0C50 or PNP0C50
CompatibleID
Hardware ID
Vendor Specific
_HID
String in the format of VVVVdddd (e.g NVDA0001)
VendorID + DeviceID
Subsystem
Vendor Specific
_SUB
String in the format of VVVVssss (e.g INTL1234)
SubVendorID + SubSystemID
Hardware Revision
Vendor Specific
_HRV
0xRRRR (2byte revision)
RevisionID
Current Resource Settings
Vendor Specific
_CRS
Byte stream
Must include I2CSerialBus and GPIO_INT for I2C controller and GPIO interrupts resp.
Device Specific Method
GUID {3CDFF6F74267-4555-AD05B30A3D8938DE}
_DSM
Package
Defines a structure that contains the HID 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: C OMMAND
H O W IT 'S USED
W H EN IT 'S USED
Reset
Windows supports the Host Initiated Reset.
Windows will issue this command during the following scenarios - device initialization - disable/enable uninstall/reinstall
Get/Set_Report
Windows supports the Get/Set_Report commands.
Windows will issue this command 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 command
Windows will issue this command during the following scenarios - when the system transitions to a low power S3 / connected standby state - when the system is shut off.
HID power management over the I2C 9/23/2020 • 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.
IN P UT SO URC E
IN DIC AT ES USER P RESEN C E IN C O N N EC T ED STA N DB Y
P RO C ESSED W H IL E IN C O N N EC T ED STA N DB Y
DEVIC E STAT E W H EN SY ST EM T RA N SIT IO N S TO C O N N EC T ED STA N DB Y
Digitizer
No
Must not process
D3
Mouse
Yes
Must process, will exit connected standby
D0
Keyboard
Yes
Must process, will exit connected standby
D0
Rotation Lock
No
Must not process
D3
Generic Desktop Controls Volume Up - Volume Down - Channel Down - Channel Up - Fast Forward - Track Forward - Track Back - Play Pause - Record - Track Stop
No
Must process
D0
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 9/23/2020 • 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 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 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).
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 nonHID Transport supported on Windows 8 is PS2.
Keyboard and mouse class drivers 9/23/2020 • 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 I8042pr t , 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 I8042pr t , 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 ConnectMultiplePor ts is set to 0x00 (under the key HKLM\Ser vices\CurrentControlSet\ \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 KeyboardClassSer viceCallback , and Mouclass provides the class service callback MouseClassSer viceCallback . A vendor can modify the operation of a class service callback by installing an upper-level filter driver for a device. The sample keyboard filter driver Kbfiltr defines the KbFilter_Ser viceCallback callback, and the sample mouse filter driver Moufiltr defines the MouFilter_Ser viceCallback 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_TRANSL ATION 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 Human Interface Devices Reference.
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. STA RT O F F SET ( IN B Y T ES)
SIZ E ( IN B Y T ES)
DATA
0
4
Header: Version Information
4
4
Header: Flags
8
4
Header: Number of Mappings
12
4
Individual Mapping
...
...
...
STA RT O F F SET ( IN B Y T ES)
SIZ E ( IN B Y T ES)
DATA
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 Human Interface Devices Reference.
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] MaximumPor tsSer viced – 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 ConnectMultiplePor ts – 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.
Absolute pointing devices For devices of type GUID_CL ASS_MOUSE , a device's function driver: Handles device-specific input. Creates the MOUSE_INPUT_DATA structures required by MouseClassSer viceCallback .
Transfers MOUSE_INPUT_DATA structures to the Mouclass data queue by calling MouseClassSer viceCallback 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 MouseClassSer viceCallback . 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 MouseClassSer viceCallback . 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 MouseClassSer viceCallback . 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 MouseClassSer viceCallback .
PS/2 (i8042prt) driver 9/23/2020 • 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 9/23/2020 • 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_Ser viceCallback 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_Ser viceCallback 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 Microsoftsupplied 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 9/23/2020 • 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\Ser vices\ 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, i8042pr t , sermouse , and so on).
value-name Specifies an entry value under the registry key HKLM\System\CurrentControlSet\Ser vices\ 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 9/23/2020 • 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 Overview 8/17/2019 • 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 Overview 9/23/2020 • 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: Original Interface Joysti Mi nidrivcer-Suppl k Driver iedModel Callbacks
DirectX 5.0 Interface INF File Creation Registry Settings VJoyD Minidriver Override Axis Selection
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 9/23/2020 • 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, 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 JoyHIDcompliant 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
VA L UE
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 9/23/2020 • 2 minutes to read • Edit Online
This section contains information about how DirectInput maps axes for use by DirectInput and Windows multimedia applications.
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: USA GE PA GE
USA GE
DIREC T IN P UT A XIS
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 G
GUID_XAxis
HID_USAGE_PAGE_SIMULATION
HID_USAGE_SIMULATION_ACCELE RATOR
GUID_YAxis
HID_USAGE_PAGE_SIMULATION
HID_USAGE_SIMULATION_BRAKE
GUID_RzAxis
USA GE PA GE
USA GE
DIREC T IN P UT A XIS
HID_USAGE_PAGE_SIMULATION
HID_USAGE_SIMULATION_RUDDER
GUID_RzAxis
HID_USAGE_PAGE_SIMULATION
HID_USAGE_SIMULATION_THROTT LE
GUID_Slider
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: W IN M M A XIS
DIREC T IN P UT A SSIGN M EN T
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:
W IN M M A XIS
DIREC T IN P UT A SSIGN M EN T
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 9/23/2020 • 2 minutes to read • Edit Online
The Hdpi.h header file contains 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 hidpi.h HidP_GetUsages HidP_GetUsagesEx
HidP_SetUsages HidP_UnsetUsages