示例#1
0
VOID
ToastMon_EvtIoTargetRemoveComplete(
    WDFIOTARGET IoTarget
)
/*++

Routine Description:

    Called when the Target device is removed ( either the target
    received IRP_MN_REMOVE_DEVICE or IRP_MN_SURPRISE_REMOVAL)

Arguments:

    IoTarget -

Return Value:


--*/
{
    PDEVICE_EXTENSION      deviceExtension;
    PTARGET_DEVICE_INFO    targetDeviceInfo = NULL;

    KdPrint((("Device Removal (remove complete) Notification\n")));

    PAGED_CODE();

    targetDeviceInfo = GetTargetDeviceInfo(IoTarget);
    deviceExtension = targetDeviceInfo->DeviceExtension;

    //
    // Stop the timer 
    //
    WdfTimerStop(targetDeviceInfo->TimerForPostingRequests, TRUE);

    //
    // Remove the target device from the collection and set Opened to FALSE to match
    // the state change (in the case of a surprise removal of the target, 
    // ToastMon_EvtIoTargetQueryRemove is not called so Opened is still TRUE).
    //
    WdfWaitLockAcquire(deviceExtension->TargetDeviceCollectionLock, NULL);

    WdfCollectionRemove(deviceExtension->TargetDeviceCollection, IoTarget);
    targetDeviceInfo->Opened = FALSE;
     
    WdfWaitLockRelease(deviceExtension->TargetDeviceCollectionLock);

    //
    // Finally delete the target.
    //
    WdfObjectDelete(IoTarget);

    return;

}
示例#2
0
NTSTATUS
ToastMon_EvtIoTargetQueryRemove(
    WDFIOTARGET IoTarget
)
/*++

Routine Description:

    Called when the Target device receives IRP_MN_QUERY_REMOVE.
    This happens when somebody disables, ejects or uninstalls the target
    device driver in usermode. Here close the handle to the
    target device. If the system fails to remove the device for
    some reason, you will get RemoveCancelled callback where
    you can reopen and continue to interact with the target device.

Arguments:

    IoTarget -

Return Value:


--*/
{
    PTARGET_DEVICE_INFO         targetDeviceInfo = NULL;
    WDFWAITLOCK                 targetDeviceCollectionLock;

    PAGED_CODE();

    targetDeviceInfo = GetTargetDeviceInfo(IoTarget);

    KdPrint((("Device Removal (query remove) Notification\n")));

    //
    // Stop the timer 
    //

    WdfTimerStop(targetDeviceInfo->TimerForPostingRequests, TRUE);

    targetDeviceCollectionLock = targetDeviceInfo->DeviceExtension->TargetDeviceCollectionLock;

    //
    // The target is being query removed, set Opened to FALSE to match this state change.
    //
    WdfWaitLockAcquire(targetDeviceCollectionLock, NULL);
    targetDeviceInfo->Opened = FALSE;
    WdfWaitLockRelease(targetDeviceCollectionLock);

    WdfIoTargetCloseForQueryRemove(IoTarget);

    return STATUS_SUCCESS;

}
示例#3
0
NTSTATUS
EchoEvtDeviceSelfManagedIoSuspend(
    IN  WDFDEVICE Device
    )
/*++

Routine Description:

    This event is called by the Framework when the device is stopped
    for resource rebalance or suspended when the system is entering
    Sx state.


Arguments:

    Device - Handle to a framework device object.

Return Value:

    NTSTATUS - The driver is not allowed to fail this function.  If it does, the
    device stack will be torn down.

--*/
{
    PQUEUE_CONTEXT queueContext = QueueGetContext(WdfDeviceGetDefaultQueue(Device));

    PAGED_CODE();

    KdPrint(("--> EchoEvtDeviceSelfManagedIoSuspend\n"));

    //
    // Before we stop the timer we should make sure there are no outstanding
    // i/o. We need to do that because framework cannot suspend the device
    // if there are requests owned by the driver. There are two ways to solve
    // this issue: 1) We can wait for the outstanding I/O to be complete by the
    // periodic timer 2) Register EvtIoStop callback on the queue and acknowledge
    // the request to inform the framework that it's okay to suspend the device
    // with outstanding I/O. In this sample we will use the 1st approach
    // because it's pretty easy to do. We will restart the queue when the
    // device is restarted.
    //
    WdfIoQueueStopSynchronously(WdfDeviceGetDefaultQueue(Device));

    //
    // Stop the watchdog timer and wait for DPC to run to completion if it's already fired.
    //
    WdfTimerStop(queueContext->Timer, TRUE);

    KdPrint(( "<-- EchoEvtDeviceSelfManagedIoSuspend\n"));

    return STATUS_SUCCESS;
}
// This routine stops the simulator
// Returns an NTSTATUS code
NTSTATUS HardwareSimulator::Stop()
{
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    if (SimulatorState_Started == m_State)
    {
        WdfTimerStop(m_Timer, TRUE);
        m_State = SimulatorState_Initialized;
    }

    SENSOR_FunctionExit(status);

    return status;
}
示例#5
0
// Called by Sensor CLX to stop continously sampling the sensor.
NTSTATUS
CustomSensorDevice::OnStop(
    _In_ SENSOROBJECT SensorInstance // sensor device object
    )
{
    PHardwareSimulator pSimulator = nullptr;
    PCustomSensorDevice pDevice = GetCustomSensorContextFromSensorInstance(SensorInstance);
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();
    
    if (nullptr == pDevice)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("CSTM %!FUNC! Sensor(%08X) parameter is invalid. Failed %!STATUS!", (INT) SensorInstance, Status);
    }

    if (NT_SUCCESS(Status))
    {
        // Stop polling

        pDevice->m_Started = FALSE;

        // Waiting for the callback to complete, then stopping the timer
        WdfTimerStop(pDevice->m_Timer, TRUE);

        InitPropVariantFromUInt32(SensorState_Idle,
            &(pDevice->m_pProperties->List[SENSOR_PROPERTY_STATE].Value));

        // Stop the simulator
        pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance);
        if (nullptr == pSimulator)
        {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            TraceError("CSTM %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status);
            goto Exit;
        }

        pSimulator->Stop();
    }

Exit:
    SENSOR_FunctionExit(Status);

    return Status;
}
示例#6
0
文件: Device.cpp 项目: OpenXT/xc-vusb
/**
 * @brief Transition out of fully powered state.
 * This callback is invoked on unplug after FdoEvtDeviceSurpriseRemoval() or
 * on resource rebalance or device disable or shutdown.
 *
 * Plus take advantage of this opportunity to dump a bunch of stats on this device.
 * 
 * @param[in] Device handle to the WDFDEVICE created by FdoEvtDeviceAdd().
 * 
 * @returns NTSTATUS value indicating success or failure. 
 * 
 */
NTSTATUS
FdoEvtDeviceD0Exit(
    IN  WDFDEVICE device,
    IN  WDF_POWER_DEVICE_STATE)
{  
    PUSB_FDO_CONTEXT fdoContext = DeviceGetFdoContext(device);
    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE,
        __FUNCTION__": %s Device %p\n",
        fdoContext->FrontEndPath, 
        fdoContext->WdfDevice);

    WdfTimerStop(fdoContext->WatchdogTimer, TRUE);
    XenDeconfigure(fdoContext);

    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE,
        __FUNCTION__": %s\n"
        "    Direct Transfers: %I64d errors: %I64d largest: %d\n"
        "    Indirect Transfers: %I64d errors: %I64d largest: %d\n",
        fdoContext->FrontEndPath, 
        fdoContext->totalDirectTransfers,
        fdoContext->totalDirectErrors,
        fdoContext->largestDirectTransfer,
        fdoContext->totalIndirectTransfers,
        fdoContext->totalIndirectErrors,
        fdoContext->largestIndirectTransfer);


    //
    // --XT-- Removed tracing of 2 interrupt related values.
    //
    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE,
        __FUNCTION__": %s\n"
        "    DPC overlap %I64d DPC requeue %I64d\n"
        "    DPC max passes %d DPC max processed %d DPC drain queue requests %d\n",
        fdoContext->FrontEndPath, 
        fdoContext->totalDpcOverLapCount,
        fdoContext->totalDpcReQueueCount,
        fdoContext->maxDpcPasses,
        fdoContext->maxRequestsProcessed,
        fdoContext->maxRequeuedRequestsProcessed);

    // @todo anything else that needs undoing?
    return STATUS_SUCCESS;
}
示例#7
0
void CyapaBootTimer(_In_ WDFTIMER hTimer) {
	WDFDEVICE Device = (WDFDEVICE)WdfTimerGetParentObject(hTimer);
	PDEVICE_CONTEXT pDevice = GetDeviceContext(Device);

	WDF_OBJECT_ATTRIBUTES attributes;
	WDF_WORKITEM_CONFIG workitemConfig;
	WDFWORKITEM hWorkItem;

	WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
	WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);
	attributes.ParentObject = Device;
	WDF_WORKITEM_CONFIG_INIT(&workitemConfig, CyapaBootWorkItem);

	WdfWorkItemCreate(&workitemConfig,
		&attributes,
		&hWorkItem);

	WdfWorkItemEnqueue(hWorkItem);
	WdfTimerStop(hTimer, FALSE);
}
示例#8
0
文件: utils.c 项目: MHesham/bsp
VOID
SerialDrainTimersAndDpcs(
    IN PSERIAL_DEVICE_EXTENSION PDevExt
    )
/*++

Routine Description:

   This function cancels all the timers and Dpcs and waits for them
   to run to completion if they are already fired.

Arguments:

   PDevExt - Pointer to the device extension for the device that needs to
             set a timer

Return Value:

--*/
{
    WdfTimerStop(PDevExt->ReadRequestTotalTimer, TRUE);

    WdfTimerStop(PDevExt->ReadRequestIntervalTimer, TRUE);

    WdfTimerStop(PDevExt->WriteRequestTotalTimer, TRUE);

    WdfTimerStop(PDevExt->ImmediateTotalTimer, TRUE);

    WdfTimerStop(PDevExt->XoffCountTimer, TRUE);

    WdfTimerStop(PDevExt->LowerRTSTimer, TRUE);

    WdfDpcCancel(PDevExt->CompleteWriteDpc, TRUE);

    WdfDpcCancel(PDevExt->CompleteReadDpc, TRUE);

    WdfDpcCancel(PDevExt->CommErrorDpc, TRUE);

    WdfDpcCancel(PDevExt->CompleteImmediateDpc, TRUE);

    WdfDpcCancel(PDevExt->CommWaitDpc, TRUE);

    WdfDpcCancel(PDevExt->XoffCountCompleteDpc, TRUE);

    WdfDpcCancel(PDevExt->StartTimerLowerRTSDpc, TRUE);

    return;
}
示例#9
0
// Called by Sensor CLX to stop keeping history.
NTSTATUS ActivityDevice::OnStopHistory(_In_ SENSOROBJECT sensorInstance)
{ 
    NTSTATUS status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    PActivityDevice pDevice = GetActivityContextFromSensorInstance(sensorInstance);
    if (nullptr == pDevice)
    {
        status = STATUS_INVALID_PARAMETER;
        TraceError("ACT %!FUNC! Sensor parameter is invalid. Failed %!STATUS!", status);
    }
    else
    {
        // Stop keeping history
        pDevice->m_HistoryStarted = FALSE;
        WdfTimerStop(pDevice->m_HistoryTimer, TRUE);
    }

    SENSOR_FunctionExit(status);
    return status;
}
示例#10
0
NTSTATUS
OnD0Exit(
    _In_  WDFDEVICE               FxDevice,
    _In_  WDF_POWER_DEVICE_STATE  FxPreviousState
    )
/*++
 
  Routine Description:

    This routine destroys objects needed by the driver.

  Arguments:

    FxDevice - a handle to the framework device object
    FxPreviousState - previous power state

  Return Value:

    Status

--*/
{
    FuncEntry(TRACE_FLAG_WDFLOADING);
    
    UNREFERENCED_PARAMETER(FxPreviousState);

    PDEVICE_CONTEXT pDevice = GetDeviceContext(FxDevice);

	WdfTimerStop(pDevice->Timer, TRUE);

	pDevice->ConnectInterrupt = false;

    FuncExit(TRACE_FLAG_WDFLOADING);

    return STATUS_SUCCESS;
}
示例#11
0
文件: st_assoc.c 项目: kcrazy/winekit
VOID 
StaReceiveAssociationResponse(
                             __in  PSTATION                        pStation,
                             __in  PNIC_RX_FRAGMENT                pNicFragment,
                             __in  ULONG                           TotalLength
                             )
{
    NDIS_STATUS         ndisStatus = NDIS_STATUS_SUCCESS;
    PUCHAR              pPacketBuffer;
    PDOT11_MGMT_HEADER  pMgmtHeader;
    PDOT11_ASSOC_RESPONSE_FRAME   pDot11AssocFrame;
    USHORT              StatusCode;
    USHORT              AID = 0;
    PSTA_BSS_ENTRY      pAPEntry = pStation->ConnectContext.ActiveAP;
    BOOLEAN             bTimerCancelled, bSetTxDataRate = FALSE;
    DOT11_RATE_SET      rateSet;

    pPacketBuffer = Hw11GetFragmentDataStart(pNicFragment);

    //
    // Ref to make sure reset/halt does not leave while we are still working
    //
    STA_INCREMENT_REF(pStation->ConnectContext.AsyncFuncCount);

    NdisDprAcquireSpinLock(&(pStation->ConnectContext.Lock));
    if (pStation->ConnectContext.AssociateState == ASSOC_STATE_WAITING_FOR_ASSOCIATE) {
        if (pStation->ConnectContext.ConnectState < CONN_STATE_READY_TO_CONNECT) {
            MpTrace(COMP_ASSOC, DBG_LOUD, ("Reset/Disconnect before association completed\n"));

            //
            // Reset/disconnect, etc. We dont process this associate packet. Eventually, timeout
            // will happen and cleanup
            //
            NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock));
            STA_DECREMENT_REF(pStation->ConnectContext.AsyncFuncCount);
            return;
        }

        do {
            if (TotalLength < (sizeof(DOT11_MGMT_HEADER) + sizeof(DOT11_ASSOC_RESPONSE_FRAME))) {
                ndisStatus = NDIS_STATUS_NOT_ACCEPTED;
                MpTrace(COMP_ASSOC, DBG_LOUD, ("Association response packet too short\n"));
                break;
            }

            pMgmtHeader = (PDOT11_MGMT_HEADER)pPacketBuffer;

            //
            // Check that is a packet from the AP we are interested in
            //
            if (!MP_COMPARE_MAC_ADDRESS(pMgmtHeader->SA, pAPEntry->MacAddress) ||
                !MP_COMPARE_MAC_ADDRESS(pMgmtHeader->BSSID, pAPEntry->Dot11BSSID) ||
                !MP_COMPARE_MAC_ADDRESS(pMgmtHeader->DA, Hw11GetMACAddress(pStation->pNic))) {
                ndisStatus = NDIS_STATUS_NOT_ACCEPTED;
                MpTrace(COMP_ASSOC, DBG_LOUD, ("Association response packet not for me\n"));
                break;
            }

        } while (FALSE);

        if (ndisStatus != NDIS_STATUS_NOT_ACCEPTED) {
            //
            // This was a valid response to our association request
            // Complete the association with appropriate status
            //        
            pDot11AssocFrame = (PDOT11_ASSOC_RESPONSE_FRAME)(pPacketBuffer + sizeof(DOT11_MGMT_HEADER));

            //
            // Get association status code from the packet
            //
            StatusCode = pDot11AssocFrame->usStatusCode;

            if (StatusCode == DOT11_FRAME_STATUS_SUCCESSFUL) {
                //
                // Association attempt succeeded
                //
                ndisStatus = NDIS_STATUS_SUCCESS;
                MpTrace(COMP_ASSOC, DBG_NORMAL, ("Association response status SUCCESS\n"));

                //
                // Validate AID
                //
                AID = pDot11AssocFrame->usAID;
                if ((AID & 0xc000) != 0xc000) 
                {
                    // Invalid AID. 
                    pStation->Config.ValidAID = FALSE;
                    
                    // Connecting to a non-conformant AP. Continue with association instead of bailing out.
                    MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Association response contains invalid AID %d\n", AID));
                 }
                 else
                 {
                    pStation->Config.ValidAID = TRUE;
                 }
                 
                 AID  &= ~(0xc000);
                 if (AID > 2007) {
                    // AID too big
                    ndisStatus = NDIS_STATUS_FAILURE;
                    MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Association response contains invalid AID %d\n", AID));
                 }

                if (ndisStatus == NDIS_STATUS_SUCCESS) {
                    //
                    // Get data rate
                    //
                    ndisStatus = StaGetRateSetFromInfoEle(
                                                         Add2Ptr(pDot11AssocFrame, sizeof(DOT11_ASSOC_RESPONSE_FRAME)),
                                                         TotalLength - sizeof(DOT11_MGMT_HEADER) - sizeof(DOT11_ASSOC_RESPONSE_FRAME),
                                                         FALSE,
                                                         &rateSet);
                }

                if (ndisStatus == NDIS_STATUS_SUCCESS) {
                    // Association has succeeded
                    MpTrace(COMP_ASSOC, DBG_NORMAL, ("Association ID %d\n", AID));

                    pStation->ConnectContext.AssociateState = ASSOC_STATE_RECEIVED_ASSOCIATE;                
                    pStation->Config.AID = AID;

                    //
                    // Clear non-static WEP keys.
                    //
                    Hw11DeleteNonPersistentKey(pStation->pNic);

                    bSetTxDataRate = TRUE;

                    //
                    // Set active PhyId
                    //
                    pStation->Config.ActivePhyId = pAPEntry->PhyId;

                    //
                    // Set multicast cipher algorithm if the exact algorithm was not selected.
                    //
                    if (pStation->Config.MulticastCipherAlgorithmCount > 1) {
                        Hw11SetEncryption(pStation->pNic, FALSE, pStation->Config.MulticastCipherAlgorithm);
                    }
                }
                else {
                    pStation->ConnectContext.AssociateState = ASSOC_STATE_STARTED_ASSOCIATION;
                    StatusCode = DOT11_FRAME_STATUS_FAILURE;         // Unspecified failure
                }
            }
            else {
                // The association attempt failed
                MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Association failed by the access point with status %d\n", StatusCode));
                pStation->ConnectContext.AssociateState = ASSOC_STATE_STARTED_ASSOCIATION;
            }

            //
            // Copy the association response buffer into the AP Entry for completion indication
            //
            NdisDprAcquireSpinLock(&(pAPEntry->Lock));
            pAPEntry->AssocResponseLength = (USHORT)TotalLength;
            MP_ALLOCATE_MEMORY(pStation->MiniportAdapterHandle, &(pAPEntry->pAssocResponse), TotalLength, STA11_MEMORY_TAG);
            if (pAPEntry->pAssocResponse == NULL) {
                MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Unable to save association request packet\n"));
                //
                // We still maintain the association
                //
                pAPEntry->AssocResponseLength = 0;
            }
            else
            {
                //
                // Copy the association response into the packet
                //
                NdisMoveMemory(pAPEntry->pAssocResponse, pPacketBuffer, TotalLength);
            }


            // Save association ID, time, etc
            pAPEntry->AssocID = AID;
            NdisGetCurrentSystemTime(&(pAPEntry->AssociationUpTime));
            pAPEntry->AssocState = dot11_assoc_state_auth_assoc;
            NdisDprReleaseSpinLock(&(pAPEntry->Lock));

            NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock));

            if (bSetTxDataRate == TRUE)
            {
                //
                // Set data TX rate
                //
                Hw11SetTXDataRate(pStation->pNic, 
                    &rateSet, 
                    Hw11GetCalibratedRSSI(pStation->pNic, pNicFragment)
                    );
            }

            //
            // Attempt to cancel the timer
            //
            /*NdisMCancelTimer(&(pStation->ConnectContext.Timer_AssociateTimeout), &bTimerCancelled); */
            bTimerCancelled = WdfTimerStop(pStation->ConnectContext.Timer_AssociateTimeout, FALSE);
            if (bTimerCancelled) {
                STA_DECREMENT_REF(pStation->ConnectContext.AsyncFuncCount);
            }

            if (StatusCode) {
                StaAssociateComplete(pStation, StatusCode | DOT11_ASSOC_STATUS_ASSOCIATION_RESPONSE_START);
            }
            else {
                StaAssociateComplete(pStation, DOT11_ASSOC_STATUS_SUCCESS);
            }
        }
        else {
            NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock));
        }        
    }
    else {
        NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock));
        MpTrace(COMP_ASSOC, DBG_LOUD, ("Association already timed out\n"));
    }

    STA_DECREMENT_REF(pStation->ConnectContext.AsyncFuncCount);    
}
示例#12
0
文件: Device.cpp 项目: OpenXT/xc-vusb
VOID
CleanupDisconnectedDevice(
    PUSB_FDO_CONTEXT fdoContext)
{    
    AcquireFdoLock(fdoContext);
    if (fdoContext->CtlrDisconnected)
    {
        ReleaseFdoLock(fdoContext);
        return;
    }
    fdoContext->CtlrDisconnected = TRUE; 
    
    ReleaseFdoLock(fdoContext);
    WdfTimerStop(fdoContext->WatchdogTimer, TRUE);
    // --XT-- WdfDpcCancel(fdoContext->WdfDpc, TRUE);
    //
    // --XT-- This also looks like a reasonable place to turn off the event channel.
    //
    XenDisconnectDPC(fdoContext->Xen);

    AcquireFdoLock(fdoContext);

    FdoUnplugDevice(fdoContext);

    BOOLEAN completeRequest = TRUE;

    if (fdoContext->IdleRequest)
    {
        if (RequestGetRequestContext(fdoContext->IdleRequest)->RequestCompleted)
        {
            // should never happen if fdoContext->IdleRequest is not NULL.

            TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
                __FUNCTION__": Device %p Request %p marked completed\n",
                fdoContext->WdfDevice,
                fdoContext->IdleRequest);
            completeRequest = FALSE;
        }
        else if (RequestGetRequestContext(fdoContext->IdleRequest)->CancelSet)
        {
            NTSTATUS Status = WdfRequestUnmarkCancelable(fdoContext->IdleRequest);
            if (!NT_SUCCESS(Status))
            {
                if (Status == STATUS_CANCELLED)
                {
                    //
                    // don't complete the request here it is owned by the
                    // cancel routine.
                    XXX_TODO("Trace level probably too high");

                    TraceEvents(TRACE_LEVEL_WARNING, TRACE_DEVICE,
                        __FUNCTION__": Device %p Request %p Cancelled\n",
                        fdoContext->WdfDevice,
                        fdoContext->IdleRequest);
                    completeRequest = FALSE;
                }
                else
                {
                    //
                    // note but ignore. 
                    //
                    TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
                        __FUNCTION__": Device %p Request %p WdfRequestUnmarkCancelable error %x\n",
                        fdoContext->WdfDevice,
                        fdoContext->IdleRequest,
                        Status);
                }
            }
        }
        WDFREQUEST idleRequest = fdoContext->IdleRequest;
        fdoContext->IdleRequest = NULL;
        if (completeRequest)
        {
            RequestGetRequestContext(idleRequest)->RequestCompleted = 0;
            ReleaseFdoLock(fdoContext);
            WdfRequestComplete(idleRequest, STATUS_CANCELLED);
            AcquireFdoLock(fdoContext);
        }
    }
    ReleaseFdoLock(fdoContext);
    if (fdoContext->XenConfigured)
    {
        CompleteRequestsFromShadow(fdoContext);
    }
}