我正在尝试通过附加“\Device\PointerClass0”来实现鼠标过滤驱动程序。使用 IoAttachDevice 将设备附加到堆栈成功。
IRP_MJ_READ 的调度例程设置完成例程,然后将 IRP 传递给较低的驱动程序。
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,CompletionRoutine,DeviceObject,TRUE,TRUE,TRUE);
return IoCallDriver(TopMostDriver,Irp);
然后当调用完成例程时,它反转 Y 轴:
NTSTATUS CompletionRoutine(PDEVICE_OBJECT DeviceObject,PIRP Irp,PVOID Context){
PMOUSE_INPUT_DATA MouseData;
if(Irp->IoStatus.Status == STATUS_SUCCESS){
MouseData = (PMOUSE_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
MouseData->LastY *= -1;
}
if(Irp->PendingReturned){
IoMarkIrpPending(Irp);
}
return STATUS_SUCCESS;
}
其他主要功能的默认调度例程只是将 IRP 传递给较低的驱动程序。
问题是在加载我的驱动程序时,默认调度例程仅在附加驱动程序后被调用 1 次,之后它不会被调用,IRP_MJ_READ 的调度例程也不会被调用。我使用 DeviceTree 检查我的设备是否已附加,如果不是,则不会调用调度例程。
编辑:我实际上在 osronline 上找到了这个声明:
the mouse input stacks are pnp and there is no way for you to put yourself
into the stack after it has started running (you could install yourself as a filter and then restart the stack)
我怎样才能真正重新启动驱动程序堆栈?
最佳答案
实际上,您可以在不重启设备的情况下注入(inject)自己,但这样做很不愉快。您可以在设备堆栈中找到一个驱动程序,然后将其所有(或部分)MajorFunction IRP 处理程序复制到您拥有的数组中,然后将所有(或部分)这些处理程序替换为您的自己,确保“透明地”将 IRP 传递给您“中间人”的处理程序。但是,这意味着您将没有自己的 IO_STACK_LOCATION 可以使用。这种策略非常糟糕,所以我不会推荐它,除非你必须这样做。 (读作“永远不要这样做。”)
更好的方法是按照通常安装过滤器驱动程序的方式安装过滤器驱动程序,然后重新启动设备。您可以使用用户模式 PnP 设备管理功能来完成此操作,通过您编写的某种安装程序实用程序,或者简单地为用户记录安装过程并让他们执行。
关于c++ - 鼠标过滤器驱动程序的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24966527/