Winapi 原始PDO将IOCTL发送到上层过滤器驱动程序(KBFilter/MOUFilter)以启用/禁用设备

Winapi 原始PDO将IOCTL发送到上层过滤器驱动程序(KBFilter/MOUFilter)以启用/禁用设备,winapi,driver,device-driver,wdk,kmdf,Winapi,Driver,Device Driver,Wdk,Kmdf,我对驱动程序开发非常陌生,并试图编写一个简单的过滤器驱动程序来启用或禁用键盘或鼠标设备。如果我能让它工作,我想用它在鼠标插入时禁用笔记本电脑上的触摸板。我意识到可能有软件已经做到了这一点,但我真的对设备驱动程序感兴趣,并想自己学习如何做到这一点 我正在使用WDK附带的kbfilter和moufilter示例,这些示例安装为上层过滤器驱动程序。KBFilter示例创建了一个pdo,可以通过usermode程序枚举并连接到该pdo。这允许我将IOCTL发送到PDO,该PDO由KbFilter\u E

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

我正在使用WDK附带的kbfiltermoufilter示例,这些示例安装为上层过滤器驱动程序。KBFilter示例创建了一个pdo,可以通过usermode程序枚举并连接到该pdo。这允许我将IOCTL发送到PDO,该PDO由KbFilter\u EvtIoDeviceControlForRawPdo处理。但是,当我尝试执行任何与筛选器驱动程序相关的操作时,比如调用KbFilter\u 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。这不是上面的代码,在普通的示例中,设置为null被注释掉,只是调用Kbfilter会导致BSOD。我曾尝试直接在PDO中设置设备扩展,但这也会导致BSOD,可能是因为它是PDO devExt,而不是KBFilter

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

我无法将IOCTL_INTERNAL_KEYBOARD_DISCONNECT直接发送到驱动程序堆栈(我知道输入设备一次只接受一个连接?),因此需要原始PDO。我真的只需要发送两个ioctl(启用和禁用),我想我只需要使用键盘disconnect和connect,因为它们已经定义好了


如果我对这些假设中的任何一个有错误,请让我知道,我知道我在这方面确实是个傻瓜,但我还没有找到很多关于通过PDO进行这种通信的文档。

首先:在用户模式下,你可以做你想做的事情(当鼠标插入时,禁用笔记本电脑上的触摸板)。这将更加简单和安全。看和

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


玩得开心

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

KMDF过滤器驱动程序的实现

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

我认为我的主要问题是试图在KBFilter中重用内部IOCTL。就我而言,这只是一个糟糕的设计想法,因为我不理解内部IOCTL和其他IOCTL之间的区别-内部IOCTL(如IOCTL_internal_KEYBOARD_DISCONNECT)具有受限的访问条件,只能由其他驱动程序或内核发送。这也是一个使用相同控制设备结构的示例,但它是WDM

无论如何,在整个周末与KBFilter示例斗争之后,我终于放弃了,开始重新使用。这是一个更简单的KMDF过滤器驱动程序,我不得不使用KBFilter和Moufilter来填补很多空白。烤面包机过滤器驱动程序的操作类似于KBFilter,但它创建了一个控制设备,而不是PDO。它还为控制设备设置一个dos设备名,这样您就可以从用户模式与它通信,而无需Pinvoke执行该步骤。控制设备允许您通过迭代集合来控制加载了筛选器驱动程序的所有设备。waitlock用于同步对集合的访问


我还可以修改INF文件(使用鼠标类而不是Toaster类),直接在我的测试机器上应用它,而不需要修改驱动程序代码从有效的东西开始要容易得多。提供了为适应示例而应更改的内容的综合列表。

查看WINDDK中的devcon.exe源代码(WINDDK\6000\tools\devcon\i386\devcon.exe,WINDDK\6000\src\setup\devcon\)。它可以启用/禁用设备,并使用SetupAPI执行许多其他操作。我的第一个,也可能是最后一个,+1注释!为我节省了几个小时…感谢大家花时间格式化您的答案…太好了!我想知道你是否可以分享你的键盘过滤器驱动程序代码。我正在尝试启用/禁用USB键盘(从我为特殊目的连接到电脑的许多键盘中),但我一直很难弄清楚如何做到这一点。尝试开发过滤器驱动程序,但进展缓慢。也许你可以分享你的资料,看看你是如何做到的。当然,安迪,这没问题,我已经做到了,并且使用了一个带有WMI的windows服务来打开或关闭触摸板(如果插入了外部鼠标)。你要我怎么寄给你?我很困惑。为什么不简单地从用户模式通过cfgmgr32/setupapi禁用它,类似于通过设备管理器禁用它?原始驱动程序不支持通过设备管理器禁用