VOID
FxInterrupt::FlushQueuedDpcs(
    VOID
    )
{
    KeFlushQueuedDpcs();
}
Beispiel #2
0
NTSTATUS
	EventLogStart(PEVENT_LOG EventLog)
{
	LARGE_INTEGER TimerDueTime;
	NTSTATUS Status;

	RtlZeroMemory(EventLog, sizeof(EVENT_LOG));
	InitializeListHead(&EventLog->EventListHead);
	KeInitializeSpinLock(&EventLog->EventListLock);
	KeInitializeTimer(&EventLog->Timer);
	KeInitializeDpc(&EventLog->TimerDpc, EventLogTimerDpcRoutine, EventLog);
	SysWorkerInit(&EventLog->Worker);

	Status = SysWorkerStart(&EventLog->Worker);
	if (!NT_SUCCESS(Status)) {
		goto start_failed;
	}

	TimerDueTime.QuadPart = 0;
	KeSetTimerEx(&EventLog->Timer, TimerDueTime, 500, &EventLog->TimerDpc);
	return STATUS_SUCCESS;

start_failed:
	EventLog->Stopping = 1;
	KeCancelTimer(&EventLog->Timer);
	KeFlushQueuedDpcs();
	SysWorkerStop(&EventLog->Worker);
	EventLogFlush(EventLog);

	return Status;
}
Beispiel #3
0
VOID
NTAPI
ExpDeleteTimer(IN PVOID ObjectBody)
{
    KIRQL OldIrql;
    PETIMER Timer = ObjectBody;

    /* Check if it has a Wait List */
    if (Timer->WakeTimerListEntry.Flink)
    {
        /* Lock the Wake List */
        KeAcquireSpinLock(&ExpWakeListLock, &OldIrql);

        /* Check again, since it might've changed before we locked */
        if (Timer->WakeTimerListEntry.Flink)
        {
            /* Remove it from the Wait List */
            RemoveEntryList(&Timer->WakeTimerListEntry);
            Timer->WakeTimerListEntry.Flink = NULL;
        }

        /* Release the Wake List */
        KeReleaseSpinLock(&ExpWakeListLock, OldIrql);
    }

    /* Tell the Kernel to cancel the Timer and flush all queued DPCs */
    KeCancelTimer(&Timer->KeTimer);
    KeFlushQueuedDpcs();
}
//
// Called by the system work item to finish the rundown
//
VOID
FxDpc::FlushAndRundown()
{
    FxObject* pObject;

    //
    // If we have the KeFlushQueuedDpcs function call it
    // to ensure the DPC routine is no longer running before
    // we release the final reference and memory to the framework objects
    //
    KeFlushQueuedDpcs();

    //
    // Release our reference count to the associated parent object if present
    //
    if (m_Object != NULL) {
        pObject = m_Object;
        m_Object = NULL;

        pObject->RELEASE(this);
    }

    //
    // Perform our final release to ourselves, destroying the FxDpc
    //
    RELEASE(this);
}
BOOLEAN
FxDpc::Cancel(
    __in BOOLEAN Wait
    )
{
    BOOLEAN result;

    result = KeRemoveQueueDpc(GetDpcPtr());

    //
    // If result == FALSE, then the DPC could already be running.
    //
    // If the caller supplies Wait == TRUE, they want to wait and
    // ensure on return the DPC has finished running.
    //
    // The trick here is to implement this without adding execessive
    // overhead to the "normal" path, such as tracking reference counts,
    // locking, signaling events to waiting threads, etc.
    //
    // So we take the expensive approach for the Cancel call in the
    // case the caller wants to wait, and misses the DPC window. In
    // this case we will just do the system wide FlushQueuedDpc's to
    // ensure the DPC has finished running before return.
    //
    if( Wait && !result ) {

        ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

        KeFlushQueuedDpcs();
    }

    return result;
}
Beispiel #6
0
VOID
XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTION function0, PXENPCI_HIGHSYNC_FUNCTION functionN, PVOID context)
{
  ULONG ActiveProcessorCount;
  ULONG i;
  highsync_info_t *highsync_info;
  KIRQL old_irql;

  UNREFERENCED_PARAMETER(context);
  FUNCTION_ENTER();

  highsync_info = ExAllocatePoolWithTag(NonPagedPool, sizeof(highsync_info_t), XENPCI_POOL_TAG);
  RtlZeroMemory(highsync_info, sizeof(highsync_info_t));
  KeInitializeEvent(&highsync_info->highsync_complete_event, SynchronizationEvent, FALSE);
  highsync_info->function0 = function0;
  highsync_info->functionN = functionN;
  highsync_info->context = context;
  highsync_info->sync_level = HIGH_LEVEL;

#if (NTDDI_VERSION >= NTDDI_WINXP)
  ActiveProcessorCount = (ULONG)KeNumberProcessors;
#else
  ActiveProcessorCount = (ULONG)*KeNumberProcessors;
#endif

  /* Go to HIGH_LEVEL to prevent any races with Dpc's on the current processor */
  KeRaiseIrql(highsync_info->sync_level, &old_irql);

  highsync_info->do_spin = TRUE;
  for (i = 0; i < ActiveProcessorCount; i++)
  {
    if (i == 0)
      KeInitializeDpc(&highsync_info->dpcs[i], XenPci_HighSyncCallFunction0, highsync_info);
    else
      KeInitializeDpc(&highsync_info->dpcs[i], XenPci_HighSyncCallFunctionN, highsync_info);
    KeSetTargetProcessorDpc(&highsync_info->dpcs[i], (CCHAR)i);
    KeSetImportanceDpc(&highsync_info->dpcs[i], HighImportance);
    KdPrint((__DRIVER_NAME "     queuing Dpc for CPU %d\n", i));
    KeInsertQueueDpc(&highsync_info->dpcs[i], NULL, NULL);
  }
  KdPrint((__DRIVER_NAME "     All Dpc's queued\n"));

  KeMemoryBarrier();
  KeLowerIrql(old_irql);

  KdPrint((__DRIVER_NAME "     Waiting for highsync_complete_event\n"));
  KeWaitForSingleObject(&highsync_info->highsync_complete_event, Executive, KernelMode, FALSE, NULL);
#if (NTDDI_VERSION >= NTDDI_WINXP)
  KeFlushQueuedDpcs();
#else
  {
    /* just wait 1 second until all DPC's finish - not ideal but it's only for W2K */
    LARGE_INTEGER interval;
    interval.QuadPart = -1 * 1000 * 1000 * 10; /* 1 second */
    KeDelayExecutionThread(KernelMode, FALSE, &interval);
  }
#endif
  ExFreePoolWithTag(highsync_info, XENPCI_POOL_TAG);
  FUNCTION_EXIT();
}
Beispiel #7
0
void BackupRegistersDeInit(HANDLE_DEV dev)
{
    WriteBackupRegistersToRegistry(dev);
#ifdef ENABLE_TIMER_DPC
    KeCancelTimer(timer);
    KeFlushQueuedDpcs(); //wait for dpc complete
    SAFE_FREE_POOL(dpc, IVH_BACKUP_POOL_TAG);
    SAFE_FREE_POOL(timer, IVH_BACKUP_POOL_TAG);
#endif
}
Beispiel #8
0
VOID
	EventLogStop(PEVENT_LOG EventLog)
{
	PSYS_WRK_ITEM WrkItem = NULL;

	EventLog->Stopping = 1;
	KeCancelTimer(&EventLog->Timer);
	KeFlushQueuedDpcs();
	SysWorkerStop(&EventLog->Worker);
	EventLogFlush(EventLog);
}
Beispiel #9
0
VOID
NotifierTeardown(
    IN  PXENVIF_NOTIFIER    Notifier
    )
{
    KeFlushQueuedDpcs();

    Notifier->Dpcs = 0;
    Notifier->Frontend = NULL;

    RtlZeroMemory(&Notifier->Dpc, sizeof (KDPC));
    RtlZeroMemory(&Notifier->Lock, sizeof (KSPIN_LOCK));

    ASSERT(IsZeroMemory(Notifier, sizeof (XENVIF_NOTIFIER)));

    __NotifierFree(Notifier);
}
NTSTATUS
XenUsb_Disconnect(PVOID context, BOOLEAN suspend) {
  PXENUSB_DEVICE_DATA xudd = (PXENUSB_DEVICE_DATA)context;
  //PFN_NUMBER pfn;
  NTSTATUS status;

  if (xudd->device_state != DEVICE_STATE_ACTIVE && xudd->device_state != DEVICE_STATE_INACTIVE) {
    FUNCTION_MSG("state not DEVICE_STATE_(IN)ACTIVE, is %d instead\n", xudd->device_state);
    FUNCTION_EXIT();
    return STATUS_SUCCESS;
  }
  if (xudd->device_state != DEVICE_STATE_INACTIVE) {
    xudd->device_state = DEVICE_STATE_DISCONNECTING;
    status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "state", XenbusStateClosing);
    while (xudd->backend_state != XenbusStateClosing && xudd->backend_state != XenbusStateClosed) {
      FUNCTION_MSG("Waiting for XenbusStateClosing/Closed\n");
      KeWaitForSingleObject(&xudd->backend_event, Executive, KernelMode, FALSE, NULL);
    }
    status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "state", XenbusStateClosed);
    while (xudd->backend_state != XenbusStateClosed) {
      FUNCTION_MSG("Waiting for XenbusStateClosed\n");
      KeWaitForSingleObject(&xudd->backend_event, Executive, KernelMode, FALSE, NULL);
    }
    XnUnbindEvent(xudd->handle, xudd->event_channel);
    
  #if NTDDI_VERSION < WINXP
    KeFlushQueuedDpcs();
  #endif
    XnEndAccess(xudd->handle, xudd->conn_sring_gref, FALSE, XENUSB_POOL_TAG);
    ExFreePoolWithTag(xudd->conn_sring, XENUSB_POOL_TAG);
    XnEndAccess(xudd->handle, xudd->urb_sring_gref, FALSE, XENUSB_POOL_TAG);
    ExFreePoolWithTag(xudd->urb_sring, XENUSB_POOL_TAG);
  }
  if (!suspend) {
    XnCloseDevice(xudd->handle);
  }
  xudd->device_state = DEVICE_STATE_DISCONNECTED;
  return STATUS_SUCCESS;
}
VOID
EvtchnFree(
    __in     PXENIFACE_FDO Fdo,
    __inout  PXENIFACE_EVTCHN_CONTEXT Context
    )
{
    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

    XenIfaceDebugPrint(TRACE, "Context %p, LocalPort %d, FO %p\n",
                       Context, Context->LocalPort, Context->FileObject);

    XENBUS_EVTCHN(Close,
                  &Fdo->EvtchnInterface,
                  Context->Channel);

    // There may still be a pending event at this time.
    // Wait for our DPCs to complete.
    KeFlushQueuedDpcs();

    ObDereferenceObject(Context->Event);
    RtlZeroMemory(Context, sizeof(XENIFACE_EVTCHN_CONTEXT));
    ExFreePoolWithTag(Context, XENIFACE_POOL_TAG);
}
Beispiel #12
0
static void set_timer(unsigned long delta)
{
	if (delta == LKL_TIMER_INIT)
		return;

	if (delta == LKL_TIMER_SHUTDOWN) {
		/* should not deliver timer shutdown twice */
		if(timer_done) {
			DbgPrint("*** LKL_TIMER_SHUTDOWN called when timer_done ***");
			while(1)
				;
		}

		/* deque the timer so it won't be put in signaled state */
		KeCancelTimer(&timer);
		/* timers run on DPCs. This returns after all active
		 * DPCs have executed, which means the timer is
		 * certainly not running nor being schduled after this
		 * point. */
		KeFlushQueuedDpcs();


		/* signal the timer interrupt we're done */
		timer_done = 1;
		/* the memory barrier is needed because it may be
		 * possible for the compiler/cpu to call
		 * KeReleaseSemaphore before assigning
		 * timer_done. That would make the timer_thread wake
		 * from the wait-for-multiple-objs without noticing
		 * out signalling */
		KeMemoryBarrier();
		KeReleaseSemaphore(&timer_killer_sem, 0, 1, 0);
		return;
	}

	KeSetTimer(&timer, RtlConvertLongToLargeInteger((unsigned long)(-(delta/100))), NULL);
}
Beispiel #13
0
NTSTATUS CMiniportWaveRTStream::SetState
(
    _In_    KSSTATE State_
)
{
    PAGED_CODE();

    NTSTATUS        ntStatus        = STATUS_SUCCESS;
    PADAPTERCOMMON  pAdapterComm    = m_pMiniport->GetAdapterCommObj();

    // Spew an event for a pin state change request from portcls
    //Event type: eMINIPORT_PIN_STATE
    //Parameter 1: Current linear buffer position	
    //Parameter 2: Current WaveRtBufferWritePosition	
    //Parameter 3: Pin State 0->KS_STOP, 1->KS_ACQUIRE, 2->KS_PAUSE, 3->KS_RUN 
    //Parameter 4:0
    pAdapterComm->WriteEtwEvent(eMINIPORT_PIN_STATE, 
                                100, // replace with the correct "Current linear buffer position"	
                                m_ulCurrentWritePosition, // replace with the previous WaveRtBufferWritePosition that the drive received	
                                State_, // repalce with the correct "Data length completed"
                                0);  // always zero

    switch (State_)
    {
        case KSSTATE_STOP:
            // Reset DMA
            m_ullPlayPosition = 0;
            m_ullWritePosition = 0;
            m_ullLinearPosition = 0;
            
            // Wait until all work items are completed.
            if (!m_bCapture && !g_DoNotCreateDataFiles)
            {
                m_SaveData.WaitAllWorkItems();
            }

#ifdef SYSVAD_BTH_BYPASS
            if (m_ScoOpen)
            {
                PBTHHFPDEVICECOMMON bthHfpDevice;
                
                ASSERT(m_pMiniport->IsBthHfpDevice());
                bthHfpDevice = m_pMiniport->GetBthHfpDevice(); // weak ref.
                ASSERT(bthHfpDevice != NULL);

                //
                // Close the SCO connection.
                //
                ntStatus = bthHfpDevice->StreamClose();
                if (!NT_SUCCESS(ntStatus))
                {
                    DPF(D_ERROR, ("SetState: KSSTATE_STOP, StreamClose failed, 0x%x", ntStatus));
                }
                
                m_ScoOpen = FALSE;
            }
#endif // SYSVAD_BTH_BYPASS
            break;

        case KSSTATE_ACQUIRE:
#ifdef SYSVAD_BTH_BYPASS
            if (m_pMiniport->IsBthHfpDevice())
            {
                if(m_ScoOpen == FALSE)
                {
                    PBTHHFPDEVICECOMMON bthHfpDevice;

                    bthHfpDevice = m_pMiniport->GetBthHfpDevice(); // weak ref.
                    ASSERT(bthHfpDevice != NULL);

                    //
                    // Open the SCO connection.
                    //
                    ntStatus = bthHfpDevice->StreamOpen();
                    IF_FAILED_ACTION_JUMP(
                        ntStatus,
                        DPF(D_ERROR, ("SetState: KSSTATE_ACQUIRE, StreamOpen failed, 0x%x", ntStatus)),
                        Done);

                    m_ScoOpen = TRUE;
                }
            }
#endif // SYSVAD_BTH_BYPASS
            break;

        case KSSTATE_PAUSE:
            ULONGLONG ullPositionTemp;
            
            // Pause DMA
            if (m_ulNotificationIntervalMs > 0)
            {
                KeCancelTimer(m_pNotificationTimer);
                KeFlushQueuedDpcs(); 
            }

            // This call updates the linear buffer position.
            GetLinearBufferPosition(&ullPositionTemp, NULL);
            break;

        case KSSTATE_RUN:
            // Start DMA
            LARGE_INTEGER ullPerfCounterTemp;
            ullPerfCounterTemp = KeQueryPerformanceCounter(&m_ullPerformanceCounterFrequency);
            m_ullDmaTimeStamp = KSCONVERT_PERFORMANCE_TIME(m_ullPerformanceCounterFrequency.QuadPart, ullPerfCounterTemp);
            m_hnsElapsedTimeCarryForward  = 0;

            if (m_ulNotificationIntervalMs > 0)
            {
                LARGE_INTEGER   delay;
                delay.HighPart  = 0;
                delay.LowPart   = m_ulNotificationIntervalMs * HNSTIME_PER_MILLISECOND * -1;

                KeSetTimerEx
                (
                    m_pNotificationTimer,
                    delay,
                    m_ulNotificationIntervalMs,
                    m_pNotificationDpc
                );
            }

            break;
    }

    m_KsState = State_;

#ifdef SYSVAD_BTH_BYPASS
Done:
#endif  // SYSVAD_BTH_BYPASS
    return ntStatus;
}
Beispiel #14
0
CMiniportWaveRTStream::~CMiniportWaveRTStream
( 
    void 
)
/*++

Routine Description:

  Destructor for wavertstream 

Arguments:

Return Value:

  NT status code.

--*/
{
    PAGED_CODE();
    if (NULL != m_pMiniport)
    {
        if (m_bUnregisterStream)
        {
            m_pMiniport->StreamClosed(m_ulPin, this);
            m_bUnregisterStream = FALSE;
        }
        
        m_pMiniport->Release();
        m_pMiniport = NULL;
    }

    if (m_pDpc)
    {
        ExFreePoolWithTag( m_pDpc, MINWAVERTSTREAM_POOLTAG );
        m_pDpc = NULL;
    }

    if (m_pTimer)
    {
        ExFreePoolWithTag( m_pTimer, MINWAVERTSTREAM_POOLTAG );
        m_pTimer = NULL;
    }

    if (m_pbMuted)
    {
        ExFreePoolWithTag( m_pbMuted, MINWAVERTSTREAM_POOLTAG );
        m_pbMuted = NULL;
    }

    if (m_plVolumeLevel)
    {
        ExFreePoolWithTag( m_plVolumeLevel, MINWAVERTSTREAM_POOLTAG );
        m_plVolumeLevel = NULL;
    }

    if (m_plPeakMeter)
    {
        ExFreePoolWithTag( m_plPeakMeter, MINWAVERTSTREAM_POOLTAG );
        m_plPeakMeter = NULL;
    }

    if (m_pWfExt)
    {
        ExFreePoolWithTag( m_pWfExt, MINWAVERTSTREAM_POOLTAG );
        m_pWfExt = NULL;
    }
    if (m_pNotificationTimer)
    {
        KeCancelTimer(m_pNotificationTimer);
        ExFreePoolWithTag(m_pNotificationTimer, MINWAVERTSTREAM_POOLTAG);
    }

    // Since we just cancelled the notification timer, wait for all queued 
    // DPCs to complete before we free the notification DPC.
    //
    KeFlushQueuedDpcs();

    if (m_pNotificationDpc)
    {
        ExFreePoolWithTag( m_pNotificationDpc, MINWAVERTSTREAM_POOLTAG );
    }
    
#ifdef SYSVAD_BTH_BYPASS
    ASSERT(m_ScoOpen == FALSE);
#endif  // SYSVAD_BTH_BYPASS

    DPF_ENTER(("[CMiniportWaveRTStream::~CMiniportWaveRTStream]"));
} // ~CMiniportWaveRTStream
Beispiel #15
0
VOID 
	natDeinitFwSession()
{
	KeCancelTimer(&g_FwSessionTimer);
	KeFlushQueuedDpcs();
}
VOID
NICStopTheDatapath(
    _In_  PMP_ADAPTER  Adapter)
/*++

Routine Description:

    This function prevents future sends and receives on the data path, then
    prepares the adapter to reach an idle state.

    Although the adapter is entering an idle state, there may still be
    outstanding NBLs that haven't been returned by a protocol.  Call NICIsBusy
    to check if NBLs are still outstanding.

    Runs at IRQL == PASSIVE_LEVEL.

Arguments:

    Adapter                     Pointer to our adapter

Return Value:

    None.

--*/
{
    BOOLEAN fResetCancelled, fSendCancelled;
    PLIST_ENTRY ReceiveListEntry;

    DEBUGP(MP_TRACE, "[%p] ---> NICStopTheDatapath.\n", Adapter);

    PAGED_CODE();

    //
    // Remove this adapter from consideration for future receives.
    //
    MPDetachAdapter(Adapter);

    //
    // Free any queued send operations
    //
    TXFlushSendQueue(Adapter, NDIS_STATUS_FAILURE);

    //
    // Prevent new calls to NICAsyncResetOrPauseDpc
    //
    fResetCancelled = NdisCancelTimerObject(Adapter->AsyncBusyCheckTimer);

    //
    // Prevent new calls to RXReceiveIndicateDpc.
    //

    for(ReceiveListEntry = Adapter->RecvDpcList.Flink;
         ReceiveListEntry != &Adapter->RecvDpcList;
         ReceiveListEntry = ReceiveListEntry->Flink)
    {
        PMP_ADAPTER_RECEIVE_DPC ReceiveDpc = CONTAINING_RECORD(ReceiveListEntry, MP_ADAPTER_RECEIVE_DPC, Entry);
        KeRemoveQueueDpc(&ReceiveDpc->Dpc);
    }

    //
    // Prevent new calls to TXSendCompleteDpc.
    //
    fSendCancelled = NdisCancelTimerObject(Adapter->SendCompleteTimer);

    //
    // Wait for any DPCs (like our reset and recv timers) that were in-progress
    // to run to completion.  This is slightly expensive to call, but we don't
    // mind calling it during MiniportHaltEx, since it's not a performance-
    // sensitive path.
    //
    KeFlushQueuedDpcs();

    if (fSendCancelled)
    {
        // Free resources associated with a pending (but cancelled) send
    }

    if (fResetCancelled)
    {
        // Free resources associated with a pending (but cancelled) reset
    }

    //
    // Double-check that there are still no queued receive operations
    //
    for(ReceiveListEntry = Adapter->RecvDpcList.Flink;
         ReceiveListEntry != &Adapter->RecvDpcList;
         ReceiveListEntry = ReceiveListEntry->Flink)
    {
        RXFlushReceiveQueue(Adapter, CONTAINING_RECORD(ReceiveListEntry, MP_ADAPTER_RECEIVE_DPC, Entry));
    }

    //
    // Double-check that there are still no queued send operations
    //
    TXFlushSendQueue(Adapter, NDIS_STATUS_FAILURE);


    DEBUGP(MP_TRACE, "[%p] <--- NICStopTheDatapath.\n", Adapter);
}