1

質問を説明するのは難しいですが、ディスク フィルター ドライバーとボリューム フィルター ドライバーの 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 になり、常にループします。誰か助けてもらえますか? ありがとう!

4

0 に答える 0