20

我对驱动程序开发很陌生,并试图编写一个简单的过滤器驱动程序来启用或禁用键盘或鼠标设备。如果我能让它工作,我想在插入鼠标时使用它来禁用笔记本电脑上的触摸板。我意识到可能已经有软件可以做到这一点,但我对设备驱动程序真的很感兴趣并想要自己学习如何做到这一点。

我正在使用 WDK 附带的kbfiltrmoufiltr示例,它们作为上层过滤器驱动程序安装。kbfiltr 示例创建了一个可以由用户模式程序枚举和连接的 pdo。这允许我将 IOCTL 发送到由KbFilter_EvtIoDeviceControlForRawPdo处理的 PDO 。但是,当我尝试做任何与过滤器驱动程序相关的事情时,比如调用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;
    ...
    }

我得到一个蓝屏死机。不是上面的代码,在 vanilla 示例中,设置为 null 被注释掉,只是调用 Kbfilter 会导致 BSOD。我试图直接在 PDO 中设置设备扩展,但这也会导致 BSOD,大概是因为它是 PDO devExt,而不是 kbfiltr 的?

(相关:从 BSOD 获取堆栈跟踪的好方法是什么?我使用 Virtual PC 作为我的测试环境和未经检查的 XPSP3 构建)

我不能将 IOCTL_INTERNAL_KEYBOARD_DISCONNECT 直接发送到驱动程序堆栈(我知道输入设备一次只接受一个连接?)因此需要原始 PDO。我真的只需要发送两个 IOCTL(启用和禁用),我想我只需使用键盘断开和连接,因为这些已经定义。

如果我对这些假设中的任何一个有误,请告诉我,我知道我对此确实是个菜鸟,但我还没有找到很多关于通过 PDO 进行这种通信的文档。

4

2 回答 2

17

好的,我终于解决了这个问题,我的司机正在工作。

KMDF过滤器驱动的实现

感谢 Sergius 提出了 COM 端口方法,因为这帮助我设置了WinDbg。 这篇很棒的博客文章解释了如何快速设置它,基本上你让 VPC 设置一个 com 端口作为命名管道,在虚拟化操作系统上启用内核调试模式,并在它启动时连接到它。然后,您可以在驱动程序加载时获取所有 DbgPrint 消息并执行更多操作,但仅在启动过程中的跟踪消息对我有很大帮助。

我认为我的主要问题是尝试在 KbFiltr 中重用内部 IOCTL。这只是我的一个糟糕的设计理念,因为我不了解内部 IOCTL 和其他 IOCTL 之间的区别 - 内部 IOCTLS,例如 IOCTL_INTERNAL_KEYBOARD_DISCONNECT 具有受限的访问条件,只能由其他驱动程序或内核发送。此外,这篇知识库文章“如何将 IOCTL 发送到过滤器驱动程序”是使用相同控制设备结构的示例,但它是 WDM。

无论如何,在与 KbFiltr 示例斗争了整个周末之后,我终于放弃并重新开始使用WDF Toaster/filtr 示例。这是一个更准系统的 KMDF 过滤器驱动程序,我不得不使用 KbFiltr 和 MouFiltr 填充很多空白。Toaster 过滤器驱动程序操作类似于 KbFiltr,但它创建一个控制设备而不是 PDO。它还为控制设备设置了一个 dos 设备名称,因此您可以从用户模式与其通信,而无需 Pinvoke 执行该步骤。控制设备允许您通过迭代集合来控制所有加载了您的过滤器驱动程序的设备。等待锁用于同步对集合的访问。

我还能够只修改 INF 文件(使用 Mouse 类而不是 Toaster 类)并直接在我的测试机器上应用它,而无需修改驱动程序代码!从有效的东西开始要容易得多。此页面提供了一个完整的列表,列出了您应该更改以适应示例的内容。

于 2009-09-24T12:37:01.707 回答
4

首先:你可以在用户模式下做你想做的事(当插入鼠标时禁用我的笔记本电脑上的触摸板)。它将更加简单和安全。看看使用设备安装函数WM_DEVICECHANGE

要调试代码中的问题:从 BSOD 获取内存转储或设置内核调试器连接(使用重定向到管道的虚拟 PC 上的 COM 端口)。请参阅Windows 调试工具

玩得开心!

于 2009-09-16T05:59:25.133 回答