|
阅读:3557回复: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
这是个完整的驱动程序吗?
|
|