这个问题很难解释,我写了两个驱动程序,一个磁盘过滤驱动程序和一个音量过滤驱动程序,当我不打开verfier.exe来验证我的驱动程序的特殊池时。一切都很好。但是当我打开它时,窗口无法关闭,变成灰屏。仅适用于磁盘驱动程序,不适用于音量驱动程序。
我用windbg调试它,我发现当系统向我的驱动程序发送一个Irp(IRP_MN_DEVICE_USAGE_NOTIFICATION)时,我分析它,如果这个irp的Parameters.UsageNotification.Type不是DeviceUsageTypePaging,我通过它,但它没有返回,它是阻塞;IRP_MN_DEVICE_USAGE_NOTIFICATION 很有趣:
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
{
BOOLEAN setPagable;
if (pIrpStack->Parameters.UsageNotification.Type != DeviceUsageTypePaging)
{
status = pOSNDf->PassThroughIrp(pOSNDiskDevice->GetTargetDeviceObject(),
pIrp);
COSNDf::MyReleaseRemoveLock(pOSNDiskDevice->GetRemoveLock(),pIrp);
return status;
}
//
// wait on the paging path event
//
status = KeWaitForSingleObject(&pOSNDiskDevice->PagingPathCountEvent,
Executive,
KernelMode,
FALSE,
NULL);
//
// if removing last paging device, need to set DO_POWER_PAGABLE
// bit here, and possible re-set it below on failure.
//
setPagable = FALSE;
if (!pIrpStack->Parameters.UsageNotification.InPath &&
pOSNDiskDevice->PagingPathCount == 1 )
{
//
// removing the last paging file
// must have DO_POWER_PAGABLE bits set
//
if (pDeviceObject->Flags & DO_POWER_INRUSH) {
} else {
pDeviceObject->Flags |= DO_POWER_PAGABLE;
setPagable = TRUE;
}
}
//
// send the irp synchronously
//
status = pOSNDf->SynchorousSendPnPIrpDown(pOSNDiskDevice->GetTargetDeviceObject(), pIrp);
//
// now deal with the failure and success cases.
// note that we are not allowed to fail the irp
// once it is sent to the lower drivers.
//
if (NT_SUCCESS(status))
{
IoAdjustPagingPathCount(
&pOSNDiskDevice->PagingPathCount,
pIrpStack->Parameters.UsageNotification.InPath);
if (pIrpStack->Parameters.UsageNotification.InPath)
{
if (pOSNDiskDevice->PagingPathCount == 1)
{
pDeviceObject->Flags &= ~DO_POWER_PAGABLE;
}
}
}
else
{
//
// cleanup the changes done above
//
if (setPagable == TRUE)
{
pDeviceObject->Flags &= ~DO_POWER_PAGABLE;
setPagable = FALSE;
}
}
//
// set the event so the next one can occur.
//
KeSetEvent(&pOSNDiskDevice->PagingPathCountEvent,
IO_NO_INCREMENT, FALSE);
//
// and complete the irp
//
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
COSNDf::MyReleaseRemoveLock(pOSNDiskDevice->GetRemoveLock(),pIrp);
return status;
}
PassThroughIrp fun code;
NTSTATUS COSNDf::PassThroughIrp(PDEVICE_OBJECT pDeviceObject,PIRP pIrp)
{
IoSkipCurrentIrpStackLocation(pIrp);
return IoCallDriver(pDeviceObject, pIrp);
}
我调试了一下,pIrpStack->Parameters.UsageNotification.Type是DeviceUsageTypeDumpFile;当调用 iocalldriver 这个 irp 时,阻塞系统函数是 nt!ExpInterlockedPopEntrySListResume,它总是循环;有人能帮帮我吗?谢谢!