Получение отчетов HID
В этой статье описывается, как приложения в пользовательском режиме и драйверы в режиме ядра получают отчеты HID из коллекции HID.
Получение отчетов HID приложениями в пользовательском режиме
В этом разделе описывается получение входных отчетов HID или отчетов функций HID с помощью приложений в режиме пользователя с помощью ReadFile или подпрограмм HidD_GetXxx.
Однако приложение должно использовать только подпрограммы HidD_GetXxx для получения текущего состояния устройства. Если приложение пытается использовать HidD_GetInputReport для непрерывного получения входных отчетов, отчеты могут быть потеряны. Кроме того, некоторые устройства не поддерживают HidD_GetInputReport и не отвечают, если эта подпрограмма используется.
Использование ReadFile
Приложение использует открытый дескриптор файла, полученный с помощью CreateFile , для открытия файла в коллекции. Когда приложение вызывает ReadFile, не нужно указывать перекрывающиеся операции ввода-вывода, так как отчеты буферизации драйверов клиента HID в кольцевом буфере. Однако приложение может использовать перекрывающиеся операции ввода-вывода для выполнения нескольких невыполненных запросов на чтение.
Использование подпрограмм HidD_GetXxx
Приложение может использовать следующие подпрограммы поддержки HIDClass для получения самых текущих входных отчетов и отчетов функций из коллекции HID:
- HidD_GetInputReport. Возвращает входной отчет из коллекции HID (Windows XP и более поздних версий).
- HidD_GetFeature. Возвращает отчет о функциях из коллекции HID.
Приложение может запросить возврат определенного отчета. Чтобы получить определенный отчет с помощью подпрограмм HidD_GetXxx, приложение выделяет выходной буфер отчета, ноль инициализирует буфер и задает первый байт в буфере определенным идентификатором отчета. Дополнительные сведения см. в разделе "Инициализация отчетов HID".
Получение отчетов HID драйверами режима ядра
В этом разделе описывается, как драйвер режима ядра должен использовать IRP_MJ_READ запросы в качестве основного подхода для непрерывного получения отчетов ввода HID.
Последовательные запросы на чтение возвращают входные отчеты в том порядке, в котором они были получены из коллекции. Драйвер также может использовать IOCTL_HID_GET_Xxx запросы для получения входных и функциональных отчетов. Однако драйвер должен использовать только IOCTL_HID_GET_Xxx запросы для получения текущего состояния устройства. Если драйвер пытается использовать IOCTL_HID_GET_INPUT_REPORT для непрерывного получения входных отчетов, отчеты могут быть потеряны. Кроме того, некоторые устройства не поддерживают IOCTL_HID_GET_INPUT_REPORT и не отвечают, если этот запрос используется.
Использование запросов IRP_MJ_READ
Общие сведения об использовании и повторном использовании пакетов запросов ввода-вывода (IRPs) см. в разделе "Обработка irPs" и повторное использование пакетов IRP.
Если драйвер повторно использует IRP, подпрограмма IoCompletion IRP должна завершить запрос с состоянием STATUS_MORE_PROCESSING_REQUIRED (и не освободить IRP). Если драйвер больше не требует IRP, он должен завершить и освободить IRP путем вызова IoCompleteRequest и IoFreeIrp. Например, драйвер обычно может завершить и освободить IRP в своей подпрограмме выгрузки или после удаления устройства.
Если драйвер использует IRP только для одного запроса на чтение, подпрограмма IoCompletion IRP должна завершить и освободить IRP и вернуть STATUS_SUCCESS.
Прежде чем драйвер может запросить входной отчет, сначала необходимо выделить буфер входных отчетов без инициализации из непагрегированного пула памяти. Размер буфера в байтах задается элементом InputReportByteLength HIDP_CAPS структуры коллекции HID. Затем драйвер должен использовать MDL для сопоставления входного буфера отчета для запроса на чтение. Драйвер вызывает IoAllocateMdl, чтобы выделить MDL для буфера входного отчета, и задает элемент IRP IRP-MdlAddress > в адрес MDL входного буфера отчета. Драйвер должен освободить буфер отчета и MDL, если они больше не требуются.
Помимо задания адреса MDL чтения IRP, драйвер также должен задать расположение стека ввода-вывода следующего драйвера нижнего уровня. Драйвер получает доступ к расположению стека ввода-вывода следующего драйвера нижнего уровня путем вызова IoGetNextIrpStackLocation. Драйвер задает следующие элементы расположения стека ввода-вывода:
- Parameters.Read.Length: задайте размер буфера чтения в байтах. Размер должен быть больше или равен значению, указанному элементом InputReportByteLength HIDP_CAPS структуры коллекции HID.
- Parameters.Read.Key: задано значение нулю.
- Parameters.Read.ByteOffset.QuadPart: присвоено нулю.
- MajorFunction: задайте значение IRP_MJ_READ.
- FileObject: задайте указатель объекта файла, представляющий открытый файл в коллекции HID.
После получения входного отчета драйвер может управлять доступом, как описано в разделе "Интерпретация отчетов HID".
Использование запросов IOCTL_HID_GET_Xxx
Драйвер может использовать следующие запросы ввода-вывода для получения самых текущих входных и функциональных отчетов из коллекции HID:
- IOCTL_HID_GET_INPUT_REPORT. Возвращает входной отчет из коллекции HID (Windows XP и более поздних версий).
- IOCTL_HID_GET_FEATURE. Возвращает отчет о функциях из коллекции HID.
Драйвер может запросить возврат определенного отчета. Чтобы получить определенный отчет с помощью этих запросов ввода-вывода, драйвер сначала выделяет выходной буфер отчета, а затем ноль инициализирует буфер и задает первый байт в буфере определенным идентификатором отчета.
Дополнительные сведения см. в разделе "Интерпретация отчетов HID".