質問を説明するのは難しいですが、ディスク フィルター ドライバーとボリューム フィルター ドライバーの 2 つのドライバーを作成します。ウィンドウがシャットダウンできず、灰色の画面になります。これはボリューム ドライバーではなく、ディスク ドライバーの場合のみです。
私はそれを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 になり、常にループします。誰か助けてもらえますか? ありがとう!