阅读:3255回复:1
替换分发函数指针的问题#define KBD_DRIVER_NAME L"\\Driver\\Kbdclass" //这个数组用来保存所有有的旧指针 PDRIVER_DISPATCH OldDispatchFunctions[IRP_MJ_MAXIMUM_FUNCTION+1]; NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath) { NTSTATUS status; //HANDLE hMyThread; //线程句柄 PDRIVER_OBJECT kbddriverobj; //保存键盘驱动对象的变量 UNICODE_STRING kbddrivername; //键盘驱动对象的名称 ULONG i; //for循环变量 RtlInitUnicodeString(&kbddrivername,KBD_DRIVER_NAME); //通过驱动名字获取驱动对象 这个只适合获取驱动对象,获取设备对象最好不要用这个,第七个参数会很麻烦. status = ObReferenceObjectByName(&kbddrivername,OBJ_CASE_INSENSITIVE,NULL,0,IoDriverObjectType,KernelMode,NULL,&kbddriverobj); if(!NT_SUCCESS(status)) { //如果获取失败 输出信息 返回 DbgPrint("%w驱动对象获取失败!",&kbddrivername); return STATUS_UNSUCCESSFUL; } else { //只要调用过Reference系列的函数就都要通过ObDereferenceObject来解除引用 ObDereferenceObject(kbddriverobj); } //转发所有分发函数 for(i=0;i<=IRP_MJ_MAXIMUM_FUNCTION;++i) { OldDispatchFunctions=kbddriverobj->MajorFunction;//先保存旧指针 //使用原子交互的函数 来替换分发函数的指针 InterlockedExchangePointer(kbddriverobj->MajorFunction,myfilterdispatch); } DriverObject->DriverUnload=UnLoad; //设置驱动卸载函数 return STATUS_SUCCESS; //返回值 } 在for循环第四次执行InterlockedExchangePointer(kbddriverobj->MajorFunction,myfilterdispatch); 的时候蓝屏这不是个原子操作吗?原子操作是不是特别快速基本不会因为其他程序干扰他的执行? 寒江独钓中针对这个代码的说明是 作者没有测试 理论上可行 除非正在for循环的过程中 有新的几个IRP要 处理 但是还没完全设置完...他们之间本身有关联 这样就破坏了关联性...我还是不知道执行起来最终是个什么流程.. 感觉至少应该执行完FOR循环 但是跳到IRP分发函数的时候才蓝屏啊...还是说这里设置IRP 分发函数 并不影响IRP 的处理?设置过程就一边在处理? 那之前用绑定的方式也是循环设置IRP 分发函数啊....为什么那时候不出错呢? 寒江独钓说出错的概率非常小...但是我每次都是到第四次循环就蓝屏....应该是其他的问题吗? 求大牛指点... 我再给出我的分发函数吧不知道是不是函数指针的使用上出错了? NTSTATUS myfilterdispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { /*此段代码是针对绑定过滤设备的情况下 分发函数下发给被绑定的设备 // 通用的分发函数,直接skip然后用IoCallDriver把IRP发送到真实设备 // 的设备对象。 KdPrint(("Other Diapatch!")); IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(((PC2P_DEV_EXT) DeviceObject->DeviceExtension)->LowerDeviceObject, Irp); 此段代码是针对绑定过滤设备的情况下 分发函数下发给被绑定的设备*/ //而我们是事先保存了指针的,而且没有绑定设备所以,直接调用原来的分发函数就行了. //其实我们只需要修改读操作IRP分发函数的指针,没必要多此一举,这样也就是试试行不行吧. PC2P_DEV_EXT devExt; PIO_STACK_LOCATION irpStack; NTSTATUS status = STATUS_SUCCESS; KIRQL oldIrql; KEVENT event; // 获得真实设备。 //devExt = (PC2P_DEV_EXT)(DeviceObject->DeviceExtension); //从IRP栈获取当前IRP信息 irpStack = IoGetCurrentIrpStackLocation(Irp); switch (irpStack->MajorFunction) { case IRP_MJ_READ: #if DBG _asm int 3 #endif KdPrint(("IRP_MJ_READ\n")); (*OldDispatchFunctions[irpStack->MajorFunction])(DeviceObject,Irp); default: #if DBG _asm int 3 #endif KdPrint(("other\n")); (*OldDispatchFunctions[irpStack->MajorFunction]) (DeviceObject,Irp); } /* switch (irpStack->MinorFunction)//这里是选择小类 我们替换指针 直接选择大类 { case IRP_MN_REMOVE_DEVICE: KdPrint(("IRP_MN_REMOVE_DEVICE\n")); // 首先把请求发下去 IoSkipCurrentIrpStackLocation(Irp); IoCallDriver(devExt->LowerDeviceObject, Irp); // 然后解除绑定。 IoDetachDevice(devExt->LowerDeviceObject); // 删除我们自己生成的虚拟设备。 IoDeleteDevice(DeviceObject); status = STATUS_SUCCESS; break; default: // 对于其他类型的IRP,全部都直接下发即可。 IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(devExt->LowerDeviceObject, Irp); } */ return status; } |
|
沙发#
发布于:2010-12-13 23:29
这是个完整的驱动程序吗?
|
|