예제 #1
0
BOOL CMclMailbox::GetAlertable( void *lpMsg, CMclEvent *pInterrupt, DWORD dwTimeout) {
    BOOL bStatus = FALSE;
    DWORD dwStatus = pInterrupt->WaitForTwo( *m_cPendingCountSemaphoreAPtr, FALSE, dwTimeout);
    if (CMclWaitSucceeded( dwStatus, 2)
            && (CMclWaitSucceededIndex(dwStatus) == 1)) {
        dwStatus = m_cGuardMutexAPtr->Wait(dwTimeout);
        if (CMclWaitSucceeded(dwStatus, 1) || CMclWaitAbandoned(dwStatus, 1)) {
            CopyMemory( lpMsg, GetHeadPtr(), m_pHdr->cbMsgSize);
            IncrementHead();
            m_cGuardMutexAPtr->Release();
            bStatus = TRUE;

            // Nov 7, 2001: only release semaphore if
            // we've actually place something in the mailbox.
            // Previously, the following line of code was outside
            // this if block.
            //
            // Thanks to Johan Vanslembrouck for finding and
            // reporting this bug.
            //
            m_cFreeCountSemaphoreAPtr->Release(1);
        }
    }
    return bStatus;
}
예제 #2
0
DWORD CMclMailbox::GetAlertable( void *lpMsg, const CMclWaitableCollection & rCollection, DWORD dwTimeout) {
    CMclWaitableCollection cCollection;

    cCollection.AddObject(*m_cPendingCountSemaphoreAPtr);
    cCollection.AddCollection(rCollection);
    int nObjects = cCollection.GetCount();

    DWORD dwStatus = cCollection.Wait( FALSE, dwTimeout);

    if (CMclWaitSucceeded( dwStatus, nObjects)
            && (CMclWaitSucceededIndex(dwStatus) == 0)) {
        dwStatus = m_cGuardMutexAPtr->Wait(dwTimeout);
        if (CMclWaitSucceeded(dwStatus, 1) || CMclWaitAbandoned(dwStatus, 1)) {
            CopyMemory( lpMsg, GetHeadPtr(), m_pHdr->cbMsgSize);
            IncrementHead();
            m_cGuardMutexAPtr->Release();
            dwStatus = WAIT_OBJECT_0;

            // Nov 7, 2001: only release semaphore if
            // we've actually place something in the mailbox.
            // Previously, the following line of code was outside
            // this if block.
            //
            // Thanks to Johan Vanslembrouck for finding and
            // reporting this bug.
            //
            m_cFreeCountSemaphoreAPtr->Release(1);
        }
    }

    return dwStatus;
}
예제 #3
0
BOOL CMclMailbox::Get( void *lpMsg, DWORD dwTimeout) {
    DWORD dwStatus = m_cPendingCountSemaphoreAPtr->Wait(dwTimeout);
    if (CMclWaitSucceeded(dwStatus, 1)) {
        dwStatus = m_cGuardMutexAPtr->Wait(dwTimeout);
        if (CMclWaitSucceeded(dwStatus, 1) || CMclWaitAbandoned(dwStatus, 1)) {
            CopyMemory( lpMsg, GetHeadPtr(), m_pHdr->cbMsgSize);
            IncrementHead();
            m_cGuardMutexAPtr->Release();

            // Nov 7, 2001: only release semaphore if
            // we've actually place something in the mailbox.
            // Previously, the following line of code was outside
            // this if block.
            //
            // Thanks to Johan Vanslembrouck for finding and
            // reporting this bug.
            //
            m_cFreeCountSemaphoreAPtr->Release(1);
        }
    }

    return (CMclWaitSucceeded(dwStatus, 1));
}
VOID
FxWakeInterruptMachine::ProcessEventInner(
    __inout FxPostProcessInfo* Info
    )
{
    KIRQL irql;
    FxWakeInterruptEvents event;
    const FxWakeInterruptStateTable* entry;
    FxWakeInterruptStates newState;

    //
    // Process as many events as we can
    //
    for ( ; ; ) {
        //
        // Acquire state machine *queue* lock
        //
        Lock(&irql);

        if (IsEmpty()) {
            //
            // The queue is empty.
            //
            GetFinishedState(Info);
            Unlock(irql);
            return;
        }

        //
        // Get the event from the queue
        //
        event = m_Queue[GetHead()];
        IncrementHead();

        //
        // Drop the state machine *queue* lock
        //
        Unlock(irql);

        //
        // Get the state table entry for the current state
        //
        // NOTE: Prefast complains about buffer overflow if (m_CurrentState ==
        // WakeInterruptMax), but that should never happen because WakeInterruptMax is not a real 
        // state. We just use it to represent the maximum value in the enum that
        // defines the states.
        //
        __analysis_assume(m_CurrentState < WakeInterruptMax);
        entry = &m_StateTable[m_CurrentState - WakeInterruptFailed];

        //
        // Based on the event received, figure out the next state
        //
        newState = WakeInterruptMax;
        for (ULONG i = 0; i < entry->TargetStatesCount; i++) {
            if (entry->TargetStates[i].WakeInterruptEvent == event) {
                DO_EVENT_TRAP(&entry->TargetStates[i]);
                newState = entry->TargetStates[i].WakeInterruptState;
                break;
            }
        }
        
        if (newState == WakeInterruptMax) {
            //
            // Unexpected event for this state
            //
            DoTraceLevelMessage(
                m_PkgPnp->GetDriverGlobals(), 
                TRACE_LEVEL_INFORMATION, 
                TRACINGPNP,
                "WDFDEVICE 0x%p !devobj 0x%p wake interrupt state "
                "%!FxWakeInterruptStates! dropping event "
                "%!FxWakeInterruptEvents!",
                m_PkgPnp->GetDevice()->GetHandle(),
                m_PkgPnp->GetDevice()->GetDeviceObject(),
                m_CurrentState, 
                event
                );

            COVERAGE_TRAP();
        }
        
        while (newState != WakeInterruptMax) {
            DoTraceLevelMessage(
                m_PkgPnp->GetDriverGlobals(), 
                TRACE_LEVEL_INFORMATION, 
                TRACINGPNPPOWERSTATES,
                "WDFDEVICE 0x%p !devobj 0x%p entering wake interrupt "
                "state %!FxWakeInterruptStates! from "
                "%!FxWakeInterruptStates!",
                m_PkgPnp->GetDevice()->GetHandle(),
                m_PkgPnp->GetDevice()->GetDeviceObject(),
                newState, 
                m_CurrentState
                );
        
            //
            // Update the state history array
            //
            m_States.History[IncrementHistoryIndex()] = (UCHAR) newState;
        
            //
            // Move to the new state
            //
            m_CurrentState = (BYTE) newState;
            entry = &m_StateTable[m_CurrentState-WakeInterruptFailed];
        
            //
            // Invoke the state entry function (if present) for the new state
            //
            if (entry->StateFunc != NULL) {
                newState = entry->StateFunc(this);
            }
            else {
                newState = WakeInterruptMax;
            }
        }
    }
    
    return;    
}