阅读:1235回复:0
过滤驱动为什么要单独处理Pnp和Power请求
摘自Walter Oney《Programming the Microsoft Windows Diver Model》第一版第9章
NTSTATUS DispatchPnp(PDEVICE_OBJECT fido, PIRP Irp) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension; NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS(status)) return CompleteRequest(Irp, status, 0); PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); ULONG fcn = stack->MinorFunction; IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pdx->LowerDeviceObject, Irp); if (fcn == IRP_MN_REMOVE_DEVICE) { IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp); IoDetachDevice(pdx->LowerDeviceObject); IoDeleteDevice(fido); } else IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return status; } //上个例程中蓝色部分是关键所在吧,但下面这个例程我就不知道它的必要性了, 它不就是向下传递了IRP吗? NTSTATUS DispatchPower(PDEVICE_OBJECT fido, PIRP Irp) { PoStartNextPowerIrp(Irp); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension; NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS(status)) return CompleteRequest(Irp, status, 0); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pdx->LowerDeviceObject, Irp); IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return status; } 是不是为了防止在设备消失后而继续有IRP到来导致系统崩溃呢?不过微软的技术文章上写了: http://www.microsoft.com/china/whdc/Driver/tips/remlock.mspx ...... 如果驱动程序在其删除设备处理完成之后,但是 I/O 管理器删除设备对象之前接收到另一个 I/O 请求,那么就会发生问题。当驱动程序处理请求时,它可能试图从设备扩展取消对一个无效指针的引用,这会导致系统崩溃。 要防止这种问题,驱动程序应该为所有类型的 I/O 请求获取删除锁,而不仅仅是即插即用和电源请求。 ....... 看来Walter Oney 做的也不是十分完善啊 |
|