阅读:1435回复:3
学习键盘过滤驱动遇到的几个概念性问题
我下载了网上的支持卸载的键盘过滤驱动,它的实现方法是Attach到低层键盘驱动上,用IoSetCompleteRoutine来设置完成例程以实现过滤。
根据我的理解,以及调试输出信息,设置好完成例程后,是下一次Irp到来时,完成例程回调才会被调用。 这样一来,加载驱动以后,第一次的按键信息就无法取得了。 这里我有一个疑问,低层的驱动得到按键信息以后,会回调完成例程回调函数,完成例程回调函数结束以后,会调用我们自己设备的IRP_MJ_READ回调,那么在IRP_MJ_READ回调里面我们能不能取得按键信息呢?如果可以的话,怎么取得?如果不行的话,这次的按键信息是被其他设备读走了,还是我们无法简单地访问到它呢? |
|
沙发#
发布于:2009-03-20 15:39
经过多次调试,似乎与我原来理解的完全不同,这个的实现原理是不是这样的:
键盘过滤驱动挂载的时候,已经有一个低层的键盘驱动的Irp处于PENDING状态,而这个Irp没有完成例程,按键以后,这个Irp在低层驱动就完成了,根本不会回调我们挂载的驱动。 但是这个Irp完成后,就会有一个新的Irp生成,这个新的Irp调用了触发了我们的IRP_MJ_READ,而我们把它设置了完成例程后向下传递。 所以调试信息看起来虽然是先完成例程后紧接着IRP_MJ_READ,但是实际上完全不是这样? 那么如果我可以将等待中的Irp设置完成例程,那么问题应该可以解决,是这样么? 我先试试,如果我想错了,希望各位高手可以指点一下…… |
|
板凳#
发布于:2009-03-20 16:42
…… ntStatus = IoGetDeviceObjectPointer( DeviceName, FILE_ALL_ACCESS, &FileObject, &DeviceObject ); //这个DeviceObject是被Attach的设备,应该就是等待中的Irp所在的设备吧? …… if (DeviceObject->CurrentIrp != NULL) { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(DeviceObject->CurrentIrp); if (IrpSp->CompletionRoutine == NULL) { IrpSp->CompletionRoutine = KeyReadCompletion; IrpSp->Context = FilterDeviceObject; IrpSp->Control = (SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR | SL_INVOKE_ON_CANCEL); DbgPrint("CompletionRoutine Succeed!\r\n"); } else { DbgPrint("CompletionRoutine Failed!\r\n"); } } 按键后,直接蓝屏 ![]() 我又想错了么? |
|
地板#
发布于:2009-03-21 11:03
蓝屏原因知道了,是因为对那个等待中的Irp设置后,在完成例程回调里面参数DeviceObject的值是NULL,访问了一下成员变量,结果就蓝了。
注释掉这个访问后,蓝屏是解决了,问题是我的IRP_MJ_READ函数就执行不到了?不知道这是怎么回事? ********************************************************************************************************************************** 似乎不只是IRP_MJ_READ函数不执行,而是按任何键都没有反应。可以肯定的是完成例程是执行过了,难道是新的Irp没有生成,所以IRP_MJ_READ函数执行不到,并且也没有Irp等待接收按键内容? |
|