Пример #1
0
NTSTATUS
WDFEXPORT(WdfDeviceWdmDispatchPreprocessedIrp)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDEVICE Device,
    __in
    MdIrp Irp
    )
{
    FxDevice            *device;
    PFX_DRIVER_GLOBALS  fxDriverGlobals;

    FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
                                   Device,
                                   FX_TYPE_DEVICE,
                                   (PVOID*) &device,
                                   &fxDriverGlobals);

    FxPointerNotNull(fxDriverGlobals, Irp);
    
    //
    // Verifier checks. 
    // This API can only be called by the client driver, Cx must call 
    // WdfDeviceWdmDispatchIrp from its preprocess callback.
    // Also, Cx must register for a Preprocessor routine using 
    // WdfCxDeviceInitAssignWdmIrpPreprocessCallback.
    //
    if (fxDriverGlobals->IsVerificationEnabled(1, 11, OkForDownLevel)) {
        if (device->IsCxInIoPath()) {
            FxDriver* driver = GetFxDriverGlobals(DriverGlobals)->Driver;
            
            if (IsListEmpty(&device->m_PreprocessInfoListHead) ||
                device->IsCxDriverInIoPath(driver)) {

                DoTraceLevelMessage(
                        fxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO,
                        "This API can only be called by client driver from its "
                        "pre-process IRP callback, STATUS_INVALID_DEVICE_REQUEST");
                FxVerifierDbgBreakPoint(fxDriverGlobals);
            }
        }
    }

    //
    // OK, ready to dispatch IRP.
    //
    return device->DispatchPreprocessedIrp(
                        Irp, 
                        device->m_PreprocessInfoListHead.Flink->Flink);
}
VOID
FxPowerIdleMachine::IoDecrement(
    __in_opt PVOID Tag,
    __in_opt LONG Line,
    __in_opt PSTR File
    )
/*++

Routine Description:
    Public function which allows the caller decrement the pending io count on
    this state machine.  If the count goes to zero and idle is enabled, then
    the timer is started.

Arguments:
    None

Return Value:
    None

  --*/
{
    KIRQL irql;
    FxPkgPnp* pPkgPnp;
    PFX_DRIVER_GLOBALS pFxDriverGlobals;
    ULONG count;

    pPkgPnp = GetPnpPkg(this);
    pFxDriverGlobals = pPkgPnp->GetDriverGlobals();

    m_Lock.Acquire(&irql);

    if (m_IoCount == 0) {
        //
        // We can get here for the following reasons:
        // 1. Driver called WdfDevicveStopIdle/WdfDeviceResumeIdle in a mismatched
        //    manner. This is a driver bug.
        // 2. Framework did power deref without a corresponding power ref.
        //    This would be a framework bug. 
        //
        // We will break into debugger if verifier is turned on. This will allow
        // developers to catch this problem during develeopment.
        // We limit this break to version 1.11+ because otherwise older drivers 
        // may hit this, and if they cannot be fixed for some reason, then 
        // verifier would need to be turned off to avoid the break which is not 
        // desirable. 
        // 
        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
            "WDFDEVICE 0x%p !devobj 0x%p The device is being power-dereferenced"
            " without a matching power-reference. This could occur if driver"
            " incorrectly calls WdfDeviceResumeIdle without a matching call to"
            " WdfDeviceStopIdle.",
            pPkgPnp->GetDevice()->GetHandle(),
            pPkgPnp->GetDevice()->GetDeviceObject());
        
        if (pFxDriverGlobals->IsVerificationEnabled(1, 11, OkForDownLevel)) {
           FxVerifierDbgBreakPoint(pFxDriverGlobals);
        }
    }

    ASSERT(m_IoCount > 0);
    count = --m_IoCount;
    ProcessEventLocked(PowerIdleEventIoDecrement);
    m_Lock.Release(irql);

    if (m_TagTracker != NULL) {
        m_TagTracker->UpdateTagHistory(Tag, Line, File, TagRelease, count);
    }
}