阅读:1813回复:11
清斑竹和大虾们关注(50分):
一个值得讨论的问题:
请问下面三段代码在上层驱动程序看来有什么不同? Code 1: Read() { ... IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(dx->LowerDeviceObject, Irp); } Code 2: Read() { ... IoCopyCurrentIrpStackLocationIrpToNext(Irp); IoSetCompletionRoutine(ReadCompletion, ...); return IoCallDriver(dx->LowerDeviceObject, Irp); } ReadCompletion() { return STATUS_SUCCESS; } Code 3: Read() { ... EVENT event; KeInitializeEvent(&event); IoCopyCurrentIrpStackLocationIrpToNext(Irp); IoSetCompletionRoutine(ReadCompletion,&event, ...); Status = IoCallDriver(dx->LowerDeviceObject, Irp); if (Status == STATUS_PENDING){ KeWaitForSingleObject(event, ...); } } ReadCompletion(PVOID pContext) { PKEVENT pevent = (PKEVENT)(pContext); KeSetEvent(pevent, 1, FALSE); return STATUS_SUCCESS; } 我的手柄过滤驱动程序,在游戏控制器中测试。 使用Code 1没有问题。 使用Code 2游戏控制器中所有的值全部为0 使用Code 3在突然拔出设备时死机。 请大虾们帮忙想想,我已经被这个问题困扰了两个星期了。 |
|
|
沙发#
发布于:2002-07-22 14:30
第二个问题应该是完成例程处理有问题, Code 2返回值用STATUS_MORE_PROCESSING_REQUIRED,结果是系统速度变得奇慢无比,只有将设备拔掉。 修改后的Code 3的代码如下: Read() { ... InterlockedIncrement(&dx->PendingIoCount); EVENT event; KeInitializeEvent(&event); IoCopyCurrentIrpStackLocationIrpToNext(Irp); IoSetCompletionRoutine(ReadCompletion,&event, ...); Status = IoCallDriver(dx->LowerDeviceObject, Irp); if (Status == STATUS_PENDING){ KeWaitForSingleObject(event, ...); } InterlockedDecrement(&dx->PendingIoCount); if (dx->PendingIoCount < 0){ KeSetEvent(&dx->IoCompletionEvent); } return Irp->IoStatus.Status; } IRP_MJ_PNP [IRP_MN_REMOVE_DEVICE]: IoCallDriver(dx->LowerDeviceObject, Irp); --- (1) if (dx->PendingIoCount > 0){ InterlockedDecrement(&dx->PendingIoCount); KeWaitForSingleObject(dx->IoCompletionEvent); } // Free Memory ... IoDetachDevice(dx->LowerDeviceObject); IoDeleteObject(fdo); return STATUS_SUCCESS; } 在执行完语句(1)之后,马上跳到ReadCompletionRoutine中 然后Read函数返回STATUS_DEVICE_NOT_CONNECTED,接着是 IRP_MJ_CLEANUP, IRP_MJ_CLOSE,然后系统在_VWIN32_CloseVxDHandle + 0121处出错。 如果Read函数返回STATUS_SUCCESS,则系统不会出错,但是在游戏控制器中的设备列表中设备不会消除,还是显示连接。再一次插入设备时,再也没有调用Read函数。 |
|
|
板凳#
发布于:2002-07-22 20:00
我也是这样想的。不过我实在是按DDK的Filter的例子来的。
也罢,明天再试了之后还有问题再说。不过我还是想不通 Code 1和Code 2有什么不同。 |
|
|
地板#
发布于:2002-07-23 11:01
按DDK的介绍来说,问题不在这里。
但我重试了好多次,只要一装上CompletionRoutine,就会有问题, 哪怕是在CompletionRoutine中什么也不做。不装就没有问题。 真是搞不懂!再说了,我翻遍了DDK的Help文档也只看到在IoSetCompletionRoutine函数中有提到CompletionRoutine的原型。 对于怎样写CompletionRoutine只字不提。 BTW:哪位好心人可以帮忙试试。 我的FilterDriver安装位置在Enum\\Hid\\VID_XXXX&PID_XXXX\\LowerFilters : \"LowHid.sys\"。 |
|
|
地下室#
发布于:2002-07-25 14:42
第二个问题应该是完成例程处理有问题, Code3改为return STATUS_MORE_PROCESSING_REQUIRED;问题解决了。 前两天试的时候程序太大了,还有其他的一些Bug,所以不成功。 今天将程序提炼了一下,只留下关键代码,问题不再出现。 |
|
|