鼠标过滤器驱动程序的问题



我试图通过附加"DevicePointerClass0"来实现鼠标过滤器驱动程序。使用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)
如何重新启动驱动程序堆栈?

实际上,您可以在不重新启动设备的情况下注入自己,但这样做非常不愉快。您可以在设备的堆栈中找到一个驱动程序,然后将其MajorFunction IRP处理程序的所有(或部分)复制到您拥有的数组中,然后用您自己的处理程序替换所有(或部分)这些处理程序,确保"透明地"将IRP传递给您"中间人"的处理程序。但是,这意味着您没有自己的IO_STACK_LOCATION可以使用。这个策略非常糟糕,所以除非万不得已,我不会推荐它。(读作"千万不要这样做")

最好是按照通常安装过滤器驱动程序的方式安装过滤器驱动程序,然后重新启动设备。您可以使用用户模式的PnP设备管理函数来完成此操作,这可以从您编写的某种安装程序实用程序中实现,或者简单地为用户记录安装过程,让他们自己完成。

最新更新