win32fan
驱动牛犊
驱动牛犊
  • 注册日期2008-03-30
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望39点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
阅读:1187回复:0

过滤驱动为什么要单独处理Pnp和Power请求

楼主#
更多 发布于:2008-08-12 10:25
摘自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 做的也不是十分完善啊
游客

返回顶部