原始PDO将IOCTL发送到上层过滤器驱动程序(kbfiltr/moufiltr)以启用/禁用设备 [英] Raw PDO to send IOCTL to upper filter driver (kbfiltr/moufiltr) to enable/disable device

查看:317
本文介绍了原始PDO将IOCTL发送到上层过滤器驱动程序(kbfiltr/moufiltr)以启用/禁用设备的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对驱动程序开发非常陌生,它试图编写一个简单的筛选器驱动程序来启用或禁用键盘或鼠标设备.如果我能使它工作,我想在插入鼠标时使用它来禁用笔记本电脑上的触摸板.我意识到那里可能已经有软件在执行此操作,但是我对设备驱动程序确实很感兴趣,并且希望亲自学习如何做.

I am quite new to driver development and trying to write a simple filter driver that will enable or disable a keyboard or mouse device. If I can make it work, I want to use it to disable the touchpad on my laptop when a mouse is plugged in. I realize there is probably software out there that does this already, but I am really interested in device drivers and want to learn how to do this myself.

我正在使用WDK附带的 kbfiltr moufiltr 示例,这些示例作为高级筛选器驱动程序安装. kbfiltr示例创建一个pdo,该pdo可以通过用户模式程序枚举并连接到该pdo.这使我可以将由 KbFilter_EvtIoDeviceControlForRawPdo 处理的IOCTL发送到PDO.但是,当我尝试执行与过滤器驱动程序相关的所有操作时,例如调用 KbFilter_EvtIoInternalDeviceControl ,这样我就可以执行类似的操作

I am using the kbfiltr and moufiltr examples that ship with the WDK, installed as upper filter drivers. The kbfiltr example creates a pdo which can be enumerated and connected to by a usermode program. This allows me to send IOCTLs to the PDO that are handled by KbFilter_EvtIoDeviceControlForRawPdo. However, when I try and do anything at all related to the filter driver, like call into KbFilter_EvtIoInternalDeviceControl so I can do something like

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;
    ...
    }

我得到了蓝屏死机.它不是上面的代码,在原始示例中,设置为null的注释已被注释掉,仅调用Kbfilter会导致BSOD.我试图直接在PDO中设置设备扩展名,但这也会导致BSOD,大概是因为它是PDO devExt,而不是kbfiltr的问题.

I get a BSOD. It is not the above code, in the vanilla example the set to null is commented out, just calling into Kbfilter causes the BSOD. I have tried to set the device extension directly in the PDO but this also causes a BSOD, presumably because it is the PDO devExt, not kbfiltr's?

(相关:从BSOD获取堆栈跟踪的一种好方法是什么?我正在使用Virtual PC作为测试环境以及未经检查的XPSP3版本)

(related: what is a good way of getting the stack trace from a BSOD? I am using Virtual PC as my test environment and an unchecked build of XPSP3)

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

I can't send an IOCTL_INTERNAL_KEYBOARD_DISCONNECT directly to the driver stack (I understand that input devices accept only one connection at a time?) hence the need for the raw PDO. I really only need to send two IOCTLs (to enable and disable) and I figured I would just use the keyboard disconnect and connect since these were already defined.

如果我对这些假设中的任何一个都不对,请告诉我,我知道我确实是个菜鸟,但是我没有找到很多有关通过PDO进行此类交流的文档.

If I am wrong about any of these assumptions, please let me know, I know I really am a noob at this but I haven't found a lot of documentation about this kind of communication via a PDO.

推荐答案

好,我终于解决了这个问题,我的驱动程序正在工作.

Ok, I have finally solved this and my driver is working.

KMDF过滤器驱动程序的实现:

感谢Sergius提出了COM端口方法,因为这有助于我设置 WinDbg

Thanks to Sergius who suggested the COM-port approach because this helped me set up WinDbg. This awesome blog post explains how to get it set up quickly, basically you let VPC set up a com port as a named pipe, enable kernel debug mode on the virtualized OS, and connect to it while it is booting. Then you can get all the DbgPrint messages when the driver is loading and do a lot more, but just the trace messages during the startup process were a huge help for me.

我认为我的主要问题是尝试在KbFiltr中重用内部IOCTL.这对我来说只是一个糟糕的设计想法,因为我不了解内部IOCTL与其他IOCTL之间的区别-内部IOCTLS(例如IOCTL_INTERNAL_KEYBOARD_DISCONNECT)具有受限制的访问条件,并且只能由其他驱动程序或内核发送.另外,此知识库文章如何将IOCTL发送到筛选器驱动程序" 是使用相同控件的示例设备结构,但它是WDM.

I think my main problem was trying to reuse an internal IOCTL in KbFiltr. This was just a bad design idea on my part because I didn't understand the difference between internal IOCTL and other IOCTLs - Internal IOCTLS such as IOCTL_INTERNAL_KEYBOARD_DISCONNECT have restricted access conditions and should only be sent by other drivers or the kernel. Also this KB article "How to send IOCTL to filter driver" is an example using the same control device structure, but it is WDM.

无论如何,在整个周末与KbFiltr示例进行斗争之后,我终于放弃了,并开始使用

Anyway, after fighting with the KbFiltr example all weekend, I finally gave up and started over using the WDF Toaster/filtr example. This is a more barebones KMDF filter driver and I had to fill in a lot of blanks using KbFiltr and MouFiltr. The Toaster filter driver operation is similar to KbFiltr but it creates a control device instead of a PDO. It also sets a dos device name for the control device so you can communicate with it from usermode without having to Pinvoke to do that step. The control device allows you to control all devices which have your filter driver loaded just by iterating over the collection. A waitlock is used to synchronize access to the collection.

我还能够修改INF文件(使用Mouse类而不是Toaster类)并直接将其应用到我的测试机器上,而无需修改驱动程序代码!从可行的东西开始要容易得多. 此页面提供了应更改为的内容的完整列表调整样本.

I also was able to just modify the INF file (to use Mouse class instead of Toaster class) and apply it straight out of the box on my test machine with no modification to the driver code! It is so much easier to start with something that is working. This page gives a comprehensive list of things you should change to adapt the samples.

这篇关于原始PDO将IOCTL发送到上层过滤器驱动程序(kbfiltr/moufiltr)以启用/禁用设备的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆