Подтвердить что ты не робот

Raw PDO для отправки IOCTL в верхний драйвер фильтра (kbfiltr/moufiltr) для включения/выключения устройства

Я новичок в разработке драйверов и пытаюсь написать простой драйвер фильтра, который включит или отключит клавиатуру или мышь. Если я смогу заставить его работать, я хочу использовать его, чтобы отключить тачпад на моем ноутбуке, когда мышь подключена. Я понимаю, что есть, вероятно, программное обеспечение, которое делает это уже, но я действительно заинтересован в драйверах устройств и хочу узнайте, как это сделать сам.

Я использую примеры kbfiltr и moufiltr, которые поставляются с WDK, установленными как верхние драйверы фильтров. Пример kbfiltr создает pdo, который можно перечислить и связать с помощью программы usermode. Это позволяет мне отправлять IOCTLs в PDO, которые обрабатываются KbFilter_EvtIoDeviceControlForRawPdo. Тем не менее, когда я пытаюсь сделать что-либо вообще, связанное с драйвером фильтра, например, вызовите KbFilter_EvtIoInternalDeviceControl, чтобы я мог сделать что-то вроде

VOID
KbFilter_EvtIoInternalDeviceControl(
    IN WDFQUEUE      Queue,
    IN WDFREQUEST    Request,
    IN size_t        OutputBufferLength,
    IN size_t        InputBufferLength,
    IN ULONG         IoControlCode
    )
    ...
    hDevice = WdfIoQueueGetDevice(Queue);
    devExt = FilterGetData(hDevice);

    switch (IoControlCode) {      
    ...
      case IOCTL_INTERNAL_KEYBOARD_DISCONNECT:
       //
       // Clear the connection parameters in the device extension.
       //
       devExt->UpperConnectData.ClassService = NULL;
       break;
    ...
    }

Я получаю BSOD. Это не приведенный выше код, в примере с ванилью закомментирован набор с нулевым значением, просто вызов в Kbfilter вызывает BSOD. Я попытался установить расширение устройства непосредственно в PDO, но это также вызывает BSOD, предположительно потому, что это PDO devExt, а не kbfiltr?

(связанный: что такое хороший способ получить трассировку стека из BSOD? Я использую Virtual PC в качестве тестовой среды и неконтролируемой сборки XPSP3)

Я не могу отправить IOCTL_INTERNAL_KEYBOARD_DISCONNECT непосредственно в стек драйвера (я понимаю, что устройства ввода принимают только одно соединение за раз?), следовательно, потребность в необработанном PDO. Мне действительно нужно только отправить два IOCTL (чтобы включить или отключить), и я решил, что просто буду использовать клавиатуру для разъединения и подключения, поскольку они уже определены.

Если я ошибаюсь в отношении какого-либо из этих предположений, сообщите мне, я знаю, что на самом деле я это noob, но я не нашел много документации об этом виде общения через PDO.

4b9b3361

Ответ 1

Хорошо, я наконец решил это, и мой драйвер работает.

Реализация драйвера фильтра KMDF:

Спасибо Сергию, который предложил подход COM-порта, потому что это помогло мне настроить WinDbg. Это удивительное сообщение в блоге объясняет, как быстро настроить его, в основном вы позволяете VPC настраивать COM-порт как именованный канал, разрешать режим отладки ядра на виртуализированной ОС и подключаться к нему в то время как он загружается. Затем вы можете получить все сообщения DbgPrint, когда драйвер загружается и выполняет намного больше, но просто сообщения трассировки во время процесса запуска были огромной помощью для меня.

Я думаю, что моя главная проблема заключалась в попытке повторно использовать внутренний IOCTL в KbFiltr. Это была всего лишь плохая идея дизайна с моей стороны, потому что я не понимал разницы между внутренними IOCTL и другими IOCTL. - Внутренние IOCTLS, такие как IOCTL_INTERNAL_KEYBOARD_DISCONNECT, имеют ограниченные условия доступа и могут быть отправлены только другими драйверами или ядром. Кроме того, эта статья в KB "Как отправить IOCTL для фильтрации драйвера" является примером, использующим ту же структуру управляющего устройства, но это WDM.

В любом случае, после битвы с примером KbFiltr на всех выходных, я, наконец, сдался и начал использовать пример WDF Toaster/filtr. Это более бастоподобный драйвер фильтра KMDF, и мне пришлось заполнить множество пробелов, используя KbFiltr и MouFiltr. Операция драйвера фильтра Toaster похожа на KbFiltr, но она создает устройство управления вместо PDO. Он также устанавливает имя устройства dos для устройства управления, чтобы вы могли общаться с ним из usermode без необходимости использовать Pinvoke для этого шага. Управляющее устройство позволяет вам управлять всеми устройствами, на которых загружен драйвер фильтра, итерации по коллекции. Функция waitlock используется для синхронизации доступа к коллекции.

Я также смог просто изменить INF файл (использовать класс Mouse вместо класса Toaster) и применить его прямо из коробки на моей тестовой машине без изменений кода драйвера! Гораздо легче начать с того, что работает. Эта страница дает полный список вещей, которые вы должны изменить, чтобы адаптировать образцы.

Ответ 2

Прежде всего: вы можете делать то, что хотите (отключите тачпад на моем ноутбуке, когда мышь подключена) в пользовательском режиме. Это будет намного проще и безопаснее. Посмотрите Использование функций установки устройства и WM_DEVICECHANGE

Чтобы отладить проблемы в вашем коде: получите дамп памяти из BSOD или настройте соединение отладчика ядра (используя COM-порт на вашем виртуальном ПК, перенаправленный на канал). См. Инструменты отладки для Windows

Удачи!