The package provides the installation files for Microsoft USB Input Device Driver version 10.0.4. If the driver is already installed on your system, updating (overwrite-installing) may. Windows 10 comes with an arsenal of drivers — software that lets Windows communicate with the gadgets you plug in to your PC. Normally, Windows automatically recognizes your new part, and it simply works. Other times, Windows heads to the Internet and fetches some automated instructions before finishing the job. But occasionally, you’ll plug in.
-->Driver package isolation is a requirement for Windows Drivers that makes drivers more resilient to external changes, easier to update, and more straightforward to install.
Note
While Driver Package Isolation is required for Windows Drivers, Windows Desktop Drivers still benefit from it through improved resiliency and serviceability.
The following table shows legacy driver practices that are no longer allowed for Windows Drivers in the left column along with the required behavior for Windows Drivers in the right column.
Non-isolated Driver | Isolated Driver |
---|---|
INF copies files to System32drivers | Driver files are run from the driver store |
Interacts with other drivers using hardcoded paths | Interacts with other drivers using system-supplied functions or device interfaces |
Hardcodes path to global registry locations | Uses HKR and system-supplied functions for relative location of registry and file state |
Runtime file writes to any location | Driver writes files to system-supplied locations |
Run From Driver Store
All isolated driver packages leave their driver package files in the driver store. This means that they specify DIRID 13 in their INF to specify the location for driver package files on install.
A WDM or KMDF driver that is running from the DriverStore on Windows 10 version 1803 and later which needs to access other files from its driver package should call IoGetDriverDirectory with DriverDirectoryImage as the directory type to get the directory path that the driver was loaded from.
Alternatively for drivers that need to support OS versions before Windows 10 version 1803, use IoQueryFullDriverPath to find the driver's path, get the directory path it was loaded from, and look for configuration files relative to that path. If the kernel mode driver is a KMDF driver, it can use WdfDriverWdmGetDriverObject to retrieve the WDM driver object to pass to IoQueryFullDriverPath. UMDF drivers can use GetModuleHandleExW and GetModuleFileNameW to determine where the driver was loaded from. For example:
For a file payloaded by an INF, the subdir listed in the SourceDisksFiles entry for the file in the INF must match the subdir listed in the DestinationDirs entry for the file in the INF.
Additionally, a CopyFiles directive cannot be used to rename a file. These restrictions are required so that the installation of an INF on a device does not result in the creation of new files in the DriverStore directory.
Since SourceDisksFiles entries cannot have multiple entries with the same filename and CopyFiles cannot be used to rename a file, every file that an INF references must have a unique file name.
Dynamically finding and loading files from the Driver Store
In some scenarios, a driver package may contain a file that is intended to be loaded by a binary in another driver package or by a user mode component.
Here are a couple of examples:
- A user mode DLL provides an interface for communicating with a driver in the driver package.
- An extension driver package contains a configuration file that is loaded by the driver in the base driver package.
In these situations, the driver package should set some state indicating the path of the file or a device interface exposed by the device.
For example, the driver package could use an HKR AddReg to set this state. For this example, it should be assumed that for ExampleFile.dll
, the driver package has a SourceDisksFiles entry with no subdir. This results in the file being at the root of the driver package directory, and the DestinationDirs for a CopyFiles directive specifies dirid 13.
Here is an INF example for setting this as device state:
An INF example for setting this as device interface state would be:
The previous examples use an empty flags value, which results in a REG_SZ registry value. This results in the %13% being turned into a fully qualified user mode file path. In many cases, it is preferable to have the path be relative to an environment variable. If a flags value of 0x20000 is used, the registry value is of type REG_EXPAND_SZ and the %13% converts to a path with appropriate environment variables to abstract the location of the path. When retrieving this registry value, call ExpandEnvironmentStrings to resolve the environment variables in the path.
If the value needs to be read by a kernel mode component, the value should be a REG_SZ value. When the kernel mode component reads that value, it should prepend ??
before passing it to APIs such as ZwOpenFile.
To access this setting when it is part of the device's state, first the application must find the identity of the device. User mode code can use CM_Get_Device_ID_List_Size and CM_Get_Device_ID_List to get a list of devices, filtered as necessary. That list of devices might contain multiple devices, so search for the appropriate device before reading state from the device. For example, call CM_Get_DevNode_Property to retrieve properties on the device when looking for a device matching specific criteria.
Once the correct device is found, call CM_Open_DevNode_Key to get a handle to the registry location where the device state was stored.
Kernel mode code should retrieve a PDO (physical device object) and call IoOpenDeviceRegistryKey.
To access this setting when it is device interface state, User mode code can call CM_Get_Device_Interface_List_Size and CM_Get_Device_Interface_List.
Additionally CM_Register_Notification can be used to be notified of arrivals and removals of device interfaces so the code gets notified when the interface is enabled and then can retrieve the state. There may be multiple device interfaces in the device interface class used in the above APIs. Examine those interfaces to determine which is the correct interface for the setting to read.
Once the correct device interface is found, call CM_Open_Device_Interface_Key.
Kernel mode code can retrieve a symbolic link name for the device interface from which to get state. To do so, call IoRegisterPlugPlayNotification to register for device interface notifications on the appropriate device interface class. Alternatively, call IoGetDeviceInterfaces to get a list of current device interfaces on the system. There may be multiple device interfaces in the device interface class used in the above APIs. Examine those interfaces to determine which is the correct interface that should have the setting to be read.
Once the appropriate symbolic link name is found, call IoOpenDeviceInterfaceRegistryKey to retrieve a handle to the registry location where the device interface state was stored.
Note
Use the CM_GETIDLIST_FILTER_PRESENT flag with CM_Get_Device_ID_List_Size and CM_Get_Device_ID_List or the CM_GET_DEVICE_INTERFACE_LIST_PRESENT flag with CM_Get_Device_Interface_List_Size and CM_Get_Device_Interface_List. This ensures that hardware is present and ready for communication.
Using Device Interfaces
When state needs to be shared between drivers, there should be a single driver that owns the shared state, and it should expose a way for other drivers to read and modify that state.
Typically, the driver that owns the state exposes a device interface in a custom device interface class. When the driver is ready for other drivers to have access to the state, it enables the interface. Other drivers can register for device interface arrival notifications. To access the state, the custom device interface class can define one of two contracts:
- An I/O contract can be associated with that device interface class that provides a mechanism for accessing the state. Other drivers use the enabled device interface to send I/O requests that conform to the contract.
- A direct-call interface that gets returned via a query interface. Other drivers could send IRP_MN_QUERY_INTERFACE to retrieve function pointers from the driver to call.
Alternatively, if the driver that owns the state allows direct access to the state, other drivers could access state by using system-supplied functions for programmatic access to device interface state.
These interfaces or state (depending on sharing method used) need to be properly versioned so the driver owning the state can be serviced independently of other drivers that access that state. Driver vendors cannot rely on both drivers being serviced at the same time and staying at the same version.
Because devices and drivers controlling interfaces come and go, drivers and applications should avoid calling IoGetDeviceInterfaces at component start-up to get a list of enabled interfaces.
Instead, the best practice is to register for notifications of device interface arrival or removal and then call the appropriate function to get the list of existing enabled interfaces on the machine.
For more information about device interfaces, see:
Reading and Writing State
Note
If your component is using device or device interface properties to store state, continue to use that method and the appropriate OS API's to store and access state. The following guidance is for other state that needs to be stored by a component.
Access to various state should be done by calling functions that provide a caller with the location of the state and then the state is read/written relative to that location. Do not use hardcoded absolute registry paths and file paths.
This section contains the following subsections:
PnP Device Registry State
Isolated driver packages and user-mode components typically use two locations to store device state in the registry. These are the hardware key (device key) for the device and the software key (driver key) for the device. To retrieve a handle to these registry locations, use one of the following options, based on the platform you are using:
- IoOpenDeviceRegistryKey (WDM)
- WdfDeviceOpenRegistryKey, WdfFdoInitOpenRegistryKey (WDF)
- CM_Open_DevNode_Key (user-mode code)
- INF AddReg directive using HKR reg-root entries in an add-registry-section referenced from an INF DDInstall section or DDInstall.HW section, as shown below:
Device Interface Registry State
Use device interfaces to share state with other drivers and components. Do not hardcode paths to global registry locations.
To read and write device interface registry state, use one of the following options, based on the platform you are using:
- IoOpenDeviceInterfaceRegistryKey (WDM)
- CM_Open_Device_Interface_Key (user-mode code)
- INF AddReg directive using HKR reg-root entries in an add-registry-section referenced from an add-interface-section section
Service Registry State
Registry values that are set by the INF for driver and Win32 services should be stored under the 'Parameters' subkey of the service by providing an HKR line in an AddReg section, and then referencing that section in the service install section in the INF. For example:
To access the location of this state, use one of these functions, based on your platform:
- IoOpenDriverRegistryKey (WDM) with a DRIVER_REGKEY_TYPE of DriverRegKeyParameters
- WdfDriverOpenParametersRegistryKey (WDF)
- GetServiceRegistryStateKey (Win32 Services) with a SERVICE_REGISTRY_STATE_TYPE of ServiceRegistryStateParameters
These registry values supplied by the INF in the “Parameters” subkey for the service should not be modified at runtime and should be treated as read only. Registry values that are written at runtime should be written under a different location. To access the location for state to be written at runtime, use one of these functions:
- IoOpenDriverRegistryKey (WDM) with a DRIVER_REGKEY_TYPE of DriverRegKeyPersistentState
- WdfDriverOpenPersistentStateRegistryKey (WDF)
- GetServiceRegistryStateKey (Win32 Services) with a SERVICE_REGISTRY_STATE_TYPE of ServiceRegistryStatePersistent
Device File State
If files related to a device need to be written, those files should be stored relative to a handle or file path provided via OS API’s. Configuration files specific to that device is one example of what types of files to be stored here.
- IoGetDeviceDirectory (WDM) with the DirectoryType parameter set to DeviceDirectoryData
- WdfDeviceRetrieveDeviceDirectoryString (WDF)
Service File State
Both Win32 and driver services read and write state about themselves.
To access its own internal state values, a service uses one of the following options:
- IoGetDriverDirectory (WDM) with the DirectoryType parameter set to DeviceDirectoryData
- IoGetDriverDirectory (KMDF) with the DirectoryType parameter set to DeviceDirectoryData
- WdfDriverRetrieveDriverDataDirectoryString (UMDF)
- GetServiceDirectory (Win32 Services) with the eDirectoryType parameter set to ServiceDirectoryPersistentState
To share internal state of the service with other components, use a controlled, versioned interface instead of direct registry or file reads.
DriverData and ProgramData
Files that are to be used as part of intermediate operations that can be shared with other components should be written to either DriverData or ProgramData locations.
These locations offer components a location to write temporary state or state that is meant to be consumed by other components and potentially collected and copied from a system to be processed by another system. For example, custom log files or crash dumps fit this description.
Avoid writing files in the root of the DriverData
or ProgramData
directories. Instead, create a subdirectory with your company name and then write files and further subdirectories within that directory.
For example, for a company name of Contoso, a kernel-mode driver could write a custom log to DriverDataContosoLogs
and a user-mode application could collect or analyze the log files from %DriverData%ContosoLogs
.
DriverData
The DriverData
directory is available in Windows 10, version 1803 and later, and is accessible to administrators and UMDF drivers.
Kernel-mode drivers access the DriverData
directory by using a system-supplied symbolic link called DriverData
.User-mode programs access the DriverData
directory by using the environment variable %DriverData%
.
ProgramData
The %ProgramData%
user-mode environment variable is available for user-mode components to use when storing data.
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:
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:
Drivers Uassoft Input Devices Using
- 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.
- HIDCLASS.sys - The HID class driver. The HID Class driver is the glue between KBDHID.sys and MOUHID.sys HID clients and various transports (USB, Bluetooth, etc).
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:
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:
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
- Filter drivers are allowed in the following scenarios:
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
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.
Driver developers should leverage driver Frameworks (KMDF or UMDF) and not rely on WDM for their filter drivers.
Driver developers should reduce the number of kernel-user transitions between their service and the driver stack.
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.
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 PanelClock, Language, and RegionLanguage.
Supported buttons and wheels on mice
The following table identifies the features supported across different client versions of the Windows operating system.
Feature | Windows XP | Windows Vista | Windows 7 | Windows 8 and later |
---|---|---|---|---|
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)
Byte | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | Comment |
---|---|---|---|---|---|---|---|---|---|
1 | Yover | Xover | Ysign | Xsign | Tag | M | R | L | X/Y overvlows 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)
Byte | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | Comment |
---|---|---|---|---|---|---|---|---|---|
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)
Byte | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | Comment |
---|---|---|---|---|---|---|---|---|---|
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
Drivers Uassoft Input Devices
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 KeyboardClassServiceCallback, 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)
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.
KbFilter_ServiceCallback
See PSERVICE_CALLBACK_ROUTINE.
The ISR dispatch completion routine of the function driver calls KbFilter_ServiceCallback, 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.
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.
For more information about Moufiltr operation, see the following:
The ntddmou.h WDK header file.
The sample Moufiltr source code.
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.
Drivers Uassoft Input Devices Definition
For all other requests, Moufiltr skips the current IRP stack and sends the request down the device stack without further processing.
Callback routines
Drivers Uassoft Input Devices Device
MouFilter_IsrHook
See PI8042_MOUSE_ISR.
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
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.