Устранение неполадок с отчетами HID

В этой статье описаны наиболее распространенные проблемы, с которыми могут столкнуться приложения пользовательского режима и драйверы режима ядра при попытке извлечь или задать использование HID.

Ошибки идентификатора отчета HID

Когда приложение или драйвер получает отчет HID из коллекции HID, это может быть любой отчет, содержащийся в коллекции (так как коллекция может возвращать отчеты в любом порядке). Подпрограммы HidP_GetXxx возвращают следующие значения состояния, которые указывают на ошибки идентификатора отчета:

HIDP_STATUS_INCOMPATIBLE_REPORT_ID
Запрошенное использование находится в отчете, поддерживаемом коллекцией HID, но не в отчете, указанном приложением или драйвером.

HIDP_STATUS_USAGE_NOT_FOUND
Запрошенное использование отсутствует ни в одном отчете, поддерживаемом коллекцией верхнего уровня.

Например, на следующем рисунке показана коллекция HID, содержащая два отчета.

Схема, иллюстрирующая коллекцию hid, содержащую два отчета.

На основе этого примера предположим, что приложение или драйвер получили отчет из коллекции и вызывают HidP_GetUsageValue для извлечения текущего значения "Значение X". Если идентификатор отчета равен 7, подпрограмма возвращает HIDP_STATUS_INCOMPATIBLE_REPORT_ID, что указывает, что устройство поддерживает значение X, но значение X отсутствует в отчете. С другой стороны, если приложение или драйвер запрашивает значение "Значение Z", подпрограмма возвращает HIDP_STATUS_USAGE_NOT_FOUND, что указывает, что значение Z отсутствует ни в одном отчете, поддерживаемом коллекцией.

Если приложение или драйвер используют HidP_Set подпрограмм Xxx для задания использования в отчете, подпрограммы также могут возвращать те же два значения состояния. Смысл HIDP_STATUS_USAGE_NOT_FOUND совпадает с HidP_Get подпрограмм xxx. Однако смысл HIDP_STATUS_INCOMPATIBLE_REPORT_ID отличается. Это значение состояния указывает, что отчет был ранее настроен с идентификатором отчета, и использование, указанное вызывающим объектом, не относится к этому идентификатору отчета. На предыдущем рисунке в качестве примера после того, как приложение или драйвер использует HidP_SetUsages для установки кнопки 2 в отчете с нулевой инициализацией, отчет настраивается с идентификатором 7. Если впоследствии приложение или драйвер попытается использовать HidP_SetUsageValue для задания значения X в том же отчете, подпрограмма вернет HIDP_STATUS_INCOMPATIBLE_REPORT_ID.

Если подпрограмма **HidP_**Xxx возвращает HIDP_STATUS_INCOMPATIBLE_REPORT_ID, вызывающий объект должен выполнить одно из следующих действий:

  • Если вызывающий объект задает параметры использования, он должен выделить новый отчет правильной длины, инициализировать его с нуля, а затем снова вызвать подпрограмму. Вызывающий объект может отправить отчет в коллекцию после успешной настройки всех способов использования в отчете.

  • Если вызывающий объект извлекает данные об использовании, он должен вызвать подпрограмму с другим отчетом, полученным из коллекции.

Удаленные отчеты HID

Когда драйверы клиента HID получают входные отчеты из коллекции HID, отчеты хранятся в кольцевом буфере, поддерживаемом драйвером класса HID. Этот механизм снижает вероятность того, что приложение или драйвер будут пропускать входные отчеты, необходимые ему.

По умолчанию драйвер класса HID поддерживает кольцевой буфер входных отчетов, содержащий 32 отчета. Если коллекция передает данные драйверу класса HID быстрее, чем приложение в пользовательском режиме или драйвер режима ядра извлекает их из буфера, входные отчеты теряются из-за переполнения буфера. Чтобы уменьшить вероятность переполнения буфера, приложение или драйвер может перенастроить размер буфера в количестве отчетов. Драйверы извлекают и изменяют размер буфера с помощью запроса IOCTL_GET_NUM_DEVICE_INPUT_BUFFERS и запроса IOCTL_SET_NUM_DEVICE_INPUT_BUFFERS . Приложения выполняют ту же операцию, вызывая HidD_GetNumInputBuffers и HidD_SetNumInputBuffers.