VOID
FxInterrupt::ReportInactive(
    _In_ BOOLEAN Internal
    )
{
    IO_REPORT_INTERRUPT_ACTIVE_STATE_PARAMETERS parameters;
    FxPkgPnp* fxPkgPnp;

    fxPkgPnp = m_Device->m_PkgPnp;

    if (Internal == FALSE) {
        //
        // if the interrupt is not connected, you can't report active or inactive
        //
        if(m_Connected == FALSE || m_Interrupt == NULL) {
            DoTraceLevelMessage(
                GetDriverGlobals(), TRACE_LEVEL_WARNING, TRACINGPNP,
                "Driver is reporting WDFINTERRUPT %p as being inactive even though"
                " it is not connected.",  GetHandle());
            FxVerifierDbgBreakPoint(GetDriverGlobals());
            return;
        }
        
        if (fxPkgPnp->m_IoReportInterruptInactive == NULL) {
            DoTraceLevelMessage(
                GetDriverGlobals(), TRACE_LEVEL_WARNING, TRACINGPNP,
                "Driver is calling DDI WdfInterruptReportInactive() on an OS that "
                "doesn't support the DDI.");
            FxVerifierDbgBreakPoint(GetDriverGlobals());
            return;
        }
    }
    
    //
    // No need to report Inactive if interrupt is already Inactive
    //
    if (m_Active == FALSE) {
        return;
    }

    RtlZeroMemory(&parameters, sizeof(parameters));

    if (FxIsProcessorGroupSupported()) {
        parameters.Version = CONNECT_FULLY_SPECIFIED_GROUP;
    }
    else {
        parameters.Version = CONNECT_FULLY_SPECIFIED;
    }

    parameters.ConnectionContext.InterruptObject = m_Interrupt;

    fxPkgPnp->m_IoReportInterruptInactive(&parameters);
    m_Active = FALSE;

    return;
}
VOID
FxPkgPnp::RemoveDmaEnabler(
    __in FxDmaEnabler* Enabler
    )
{
    DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP,
                        "Removing DmaEnabler %p, WDFDMAENABLER %p",
                        Enabler, Enabler->GetObjectHandle());

    m_DmaEnablerList->Remove(GetDriverGlobals(), &Enabler->m_TransactionLink);
}
HRESULT
FxInterruptWaitblock::Initialize(
    __in FxInterruptThreadpool* Threadpool,
    __in FxInterrupt* Interrupt,
    __in PTP_WAIT_CALLBACK WaitCallback
    ) 
{
    HRESULT hr = S_OK;
    DWORD error;
   
    //
    // create a per-interrupt auto-reset event, non-signalled to begin with.
    //
    m_Event = CreateEvent(
                          NULL,  // LPSECURITY_ATTRIBUTES lpEventAttributes,
                          FALSE, // BOOL bManualReset,
                          FALSE, // BOOL bInitialState,
                          NULL   // LPCTSTR lpName
                          );
    
    if (m_Event == NULL) {
        error = GetLastError();
        hr = HRESULT_FROM_WIN32(error);
        DoTraceLevelMessage(GetDriverGlobals(), 
                    TRACE_LEVEL_ERROR, TRACINGPNP,
                    "Event creation failed for FxInterrupt object"
                    " %!winerr!", error);           
        goto exit;
    }
    
    //
    // create a per-interrupt thread pool wait structure. This wait structure is
    // needed to associate an event-based wait callback with threadpool. 
    //
    m_Wait = Threadpool->CreateThreadpoolWait(WaitCallback, 
                                              Interrupt);
    if (m_Wait == NULL) {
        error = GetLastError();
        hr = HRESULT_FROM_WIN32(error);
        DoTraceLevelMessage(GetDriverGlobals(), 
                    TRACE_LEVEL_ERROR, TRACINGPNP,
                    "Event creation failed for FxInterrupt object"
                    " %!winerr!", error);           
        goto exit;
    }

exit:

    return hr;
}
FxDpc::~FxDpc()
{
    //
    // If this hits, its because someone destroyed the DPC by
    // removing too many references by mistake without calling WdfObjectDelete
    //
    if (m_Object != NULL) {
        DoTraceLevelMessage(
            GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGDEVICE,
            "Destroy WDFDPC %p destroyed without calling WdfObjectDelete, or by"
            " Framework processing DeviceRemove.  Possible reference count "
            "problem?", GetObjectHandleUnchecked());
        FxVerifierDbgBreakPoint(GetDriverGlobals());
    }
}
FxDriver::~FxDriver()
{
    // Make it always present right now even on free builds
    if (IsDisposed() == FALSE) {
        DoTraceLevelMessage(
            GetDriverGlobals(), TRACE_LEVEL_FATAL, TRACINGDRIVER,
            "FxDriver 0x%p not disposed: this maybe a driver reference count "
            "problem with WDFDRIVER 0x%p", this, GetObjectHandleUnchecked());

        FxVerifierBugCheck(GetDriverGlobals(),
                           WDF_OBJECT_ERROR,
                           (ULONG_PTR) GetObjectHandleUnchecked(),
                           (ULONG_PTR) this);
    }

    //
    // Free the memory for the registry path if required.
    //
    if (m_RegistryPath.Buffer) {
        FxPoolFree(m_RegistryPath.Buffer);
    }

    if (m_DisposeList != NULL) {
        m_DisposeList->DeleteObject();
    }

#if FX_IS_USER_MODE
    //
    // Close the R/W handle to the driver's service parameters key
    // that we opened during Initialize.
    //
    if (m_DriverParametersKey != NULL) {
        NTSTATUS status = FxRegKey::_Close(m_DriverParametersKey);
        if (!NT_SUCCESS(status)) {
            DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGDRIVER,
                                "Cannot close Driver Parameters key %!STATUS!",
                                status);
        }
        m_DriverParametersKey = NULL;
    }

    //
    // The host-created driver object holds a reference to this
    // FxDriver object. Clear it, since this object was deleted.
    //
    ClearDriverObjectFxDriver();
#endif
}
FxRequestMemory::~FxRequestMemory(
    VOID
)
/*++

Routine Description:
    Destructor for this object.  Does nothing with the client memory since
    the client owns it.

Arguments:
    None

Return Value:
    None

  --*/
{
    //
    // Non-embedded case releases resources in the destructor
    // rather than Dispose to ensure all outstanding device driver
    // references are gone.
    //
#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
    if( m_Mdl != NULL ) {
        Mx::MxUnlockPages(m_Mdl);
        FxMdlFree(GetDriverGlobals(), m_Mdl);
        m_Mdl = NULL;
    }
#endif

    if( m_Request != NULL ) {
        m_Request->ReleaseIrpReference();
        m_Request = NULL;
    }
}
 BOOLEAN
 Add(
     __in FxObject *Item
     )
 {
     return FxCollectionInternal::Add(GetDriverGlobals(), Item);
 }
VOID
FxInterrupt::DpcHandler(
    __in_opt PVOID SystemArgument1,
    __in_opt PVOID SystemArgument2
    )
{
    UNREFERENCED_PARAMETER(SystemArgument1);
    UNREFERENCED_PARAMETER(SystemArgument2);

    ASSERT(m_EvtInterruptDpc != NULL);
    
    FX_TRACK_DRIVER(GetDriverGlobals());

    //
    // Call the drivers registered DpcForIsr event callback
    //
    if (m_CallbackLock != NULL) {
        KIRQL irql = 0;

        m_CallbackLock->Lock(&irql);
        m_EvtInterruptDpc(GetHandle(), m_Device->GetHandle());
        m_CallbackLock->Unlock(irql);
    }
    else {
        m_EvtInterruptDpc(GetHandle(), m_Device->GetHandle());
    }

    return;
}
VOID
FxInterrupt::WorkItemHandler(
    VOID
    )
{
    ASSERT(m_EvtInterruptWorkItem != NULL );
    
    FX_TRACK_DRIVER(GetDriverGlobals());

    //
    // Call the drivers registered WorkItemForIsr event callback
    //
    if (m_CallbackLock != NULL) {
        KIRQL irql = 0;

        m_CallbackLock->Lock(&irql);
        
        FxPerfTraceWorkItem(&m_EvtInterruptWorkItem);
        m_EvtInterruptWorkItem(GetHandle(), m_Device->GetHandle());
        m_CallbackLock->Unlock(irql);
    }
    else {
        FxPerfTraceWorkItem(&m_EvtInterruptWorkItem);
        m_EvtInterruptWorkItem(GetHandle(), m_Device->GetHandle());
    }

    return;
}
VOID
FxDpc::DpcHandler(
    __in PKDPC Dpc,
    __in PVOID SystemArgument1,
    __in PVOID SystemArgument2
    )
{
    UNREFERENCED_PARAMETER(Dpc);
    UNREFERENCED_PARAMETER(SystemArgument1);
    UNREFERENCED_PARAMETER(SystemArgument2);

    FX_TRACK_DRIVER(GetDriverGlobals());
    
    if (m_Callback != NULL) {

        FxPerfTraceDpc(&m_Callback);

        if (m_CallbackLock != NULL) {
            KIRQL irql = 0;

            m_CallbackLock->Lock(&irql);
            m_Callback((WDFDPC)(this->GetObjectHandle()));
            m_CallbackLock->Unlock(irql);
        }
        else {
           m_Callback((WDFDPC)(this->GetObjectHandle()));
        }
    }
}
VOID
FxWorkItem::FlushAndWait()
{
    PFX_DRIVER_GLOBALS pFxDriverGlobals;

    pFxDriverGlobals = GetDriverGlobals();

    if (m_WorkItemThread == Mx::MxGetCurrentThread()) {
        DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
                        "Calling WdfWorkItemFlush from within the WDFWORKITEM "
                        "%p callback will lead to deadlock, PRKTHREAD %p", 
                        GetHandle(), m_WorkItemThread);
        FxVerifierDbgBreakPoint(pFxDriverGlobals);
        return;
    }

    //
    // Wait for any outstanding workitem to complete.
    // The event is only set upon return from the callback
    // into the driver *and* the driver did not re-queue
    // the workitem. See similar comment in WorkItemHandler().
    //
    WaitForSignal();
    return;
}
Exemple #12
0
VOID
FxPkgIo::ResetStateForRestart(
    VOID
)
/*++

Routine Description:
    This is called on a device which has been restarted from the removed
    state.  It will reset purged queues so that they can accept new requests
    when ResumeProcessingForPower is called afterwards.

Arguments:
    None

Return Value:
    None

  --*/
{
    KIRQL irql;
    FxIoQueue* queue;
    SINGLE_LIST_ENTRY queueList, *ple;

    DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGIO,
                        "Restart queues from purged state for WDFDEVICE 0x%p due to "
                        "device restart", m_Device->GetHandle());

    queueList.Next = NULL;

    Lock(&irql);

    GetIoQueueListLocked(&queueList, FxIoQueueIteratorListPowerOn);

    Unlock(irql);

    for (ple = PopEntryList(&queueList);
            ple != NULL;
            ple = PopEntryList(&queueList)) {

        queue = FxIoQueue::_FromPowerSListEntry(ple);

        queue->ResetStateForRestart();

        ple->Next = NULL;

        queue->RELEASE(IO_ITERATOR_POWER_TAG);
    }

    Lock(&irql);

    m_PowerStateOn = TRUE;

    m_QueuesAreShuttingDown = FALSE;

    Unlock(irql);

    return;

}
Exemple #13
0
NTSTATUS
FxPkgIo::DispathToInCallerContextCallback(
    __in    FxIoInCallerContext *InCallerContextInfo,
    __in    FxRequest *Request,
    __inout MdIrp      Irp
)
{
    PFX_DRIVER_GLOBALS pFxDriverGlobals;
    FxRequestCompletionState oldState;
    FxIrp fxIrp(Irp);

    pFxDriverGlobals = GetDriverGlobals();

    //
    // Mark the IRP pending since we are going
    // to return STATUS_PENDING regardless of whether
    // the driver completes the request right away
    // or not
    //
    fxIrp.MarkIrpPending();

    if (pFxDriverGlobals->FxVerifierOn) {
        Request->SetVerifierFlags(FXREQUEST_FLAG_DRIVER_INPROCESS_CONTEXT |
                                  FXREQUEST_FLAG_DRIVER_OWNED);
    }

    //
    // Set a completion callback to manage the reference
    // count on the request
    //
    oldState = Request->SetCompletionState(FxRequestCompletionStateIoPkg);

    ASSERT(oldState == FxRequestCompletionStateNone);
    UNREFERENCED_PARAMETER(oldState);

    //
    // Release the reference count on the request since
    // the callback will hold the only one that gets
    // decremented when the request is completed
    //
    Request->RELEASE(FXREQUEST_STATE_TAG);

    Request->SetPresented();

    //
    // Drivers that use this API are responsible for handling
    // all locking, threading, and IRQL level issues...
    //
    InCallerContextInfo->Invoke(m_Device->GetHandle(),
                                Request->GetHandle());
    //
    // The driver is responsible for calling WdfDeviceEnqueueRequest to insert
    // it back into the I/O processing pipeline, or completing it.
    //

    return STATUS_PENDING;
}
Exemple #14
0
_Must_inspect_result_
NTSTATUS
FxPkgIo::FlushAllQueuesByFileObject(
    __in MdFileObject FileObject
)

/*++

    Routine Description:

        Enumerate all the queues and cancel the requests that have
        the same fileobject as the Cleanup IRP.

        We are making an assumption that cleanup irps are sent only
        at passive-level.

    Return Value:

    NTSTATUS

--*/
{
    FxIoQueue* queue = NULL;
    PFX_DRIVER_GLOBALS pFxDriverGlobals = GetDriverGlobals();
    FxIoQueueNode flushBookmark(FxIoQueueNodeTypeBookmark);
    KIRQL irql;

    if(Mx::MxGetCurrentIrql() != PASSIVE_LEVEL) {

        DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO,
                            "Currently framework allow flushing of queues "
                            "by fileobject on cleanup only at PASSIVE_LEVEL");

        FxVerifierDbgBreakPoint(pFxDriverGlobals);
        return STATUS_SUCCESS;
    }

    //
    // Iterate through the queue list and flush each one.
    //
    Lock(&irql);
    queue = GetFirstIoQueueLocked(&flushBookmark, IO_ITERATOR_FLUSH_TAG);
    Unlock(irql);

    while(queue != NULL) {

        queue->FlushByFileObject(FileObject);

        queue->RELEASE(IO_ITERATOR_FLUSH_TAG);

        Lock(&irql);
        queue = GetNextIoQueueLocked(&flushBookmark, IO_ITERATOR_FLUSH_TAG);
        Unlock(irql);
    }

    return STATUS_SUCCESS;
}
Exemple #15
0
_Must_inspect_result_
NTSTATUS
FxPkgIo::Dispatch(
    __inout MdIrp Irp
)
{
    FxIrp fxIrp(Irp);
    FX_TRACK_DRIVER(GetDriverGlobals());

    DoTraceLevelMessage(
        GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGIO,
        "WDFDEVICE 0x%p !devobj 0x%p %!IRPMJ!, IRP_MN %x, IRP 0x%p",
        m_Device->GetHandle(), m_Device->GetDeviceObject(),
        fxIrp.GetMajorFunction(),
        fxIrp.GetMinorFunction(), Irp);

    return DispatchStep1(Irp, m_DynamicDispatchInfoListHead.Flink);
}
_Must_inspect_result_
NTSTATUS
FxString::Assign(
    __in const UNICODE_STRING* UnicodeString
    )
{
    return FxDuplicateUnicodeString(GetDriverGlobals(),
                                    UnicodeString,
                                    &m_UnicodeString);
}
VOID
FxWorkItem::WorkItemHandler(
    VOID
    )
{
    KIRQL irql;
    
    FX_TRACK_DRIVER(GetDriverGlobals());

    Lock(&irql);

    //
    // Mark the workitem as no longer enqueued and completed
    //
    // The handler is allowed to re-enqueue, so mark it before the callback
    //
    m_Enqueued = FALSE;

    m_WorkItemRunningCount++;
    
    Unlock(irql);

    if (m_CallbackLock != NULL) {
        m_CallbackLock->Lock(&irql);
#if FX_IS_KERNEL_MODE
        FxPerfTraceWorkItem(&m_Callback);
#endif
        m_Callback(GetHandle());
        m_CallbackLock->Unlock(irql);
    }
    else {
#if FX_IS_KERNEL_MODE
        FxPerfTraceWorkItem(&m_Callback);
#endif
        m_Callback(GetHandle());
    }

    Lock(&irql);

    m_WorkItemRunningCount--;

    //
    // The workitem can be re-enqueued by the drivers
    // work item handler routine. We can't set the work
    // item completed event until we are sure there are
    // no outstanding work items.
    //

    if (m_WorkItemRunningCount == 0L && m_Enqueued == FALSE) {
        m_WorkItemCompleted.Set();
    }

    Unlock(irql);
}
Exemple #18
0
_Must_inspect_result_
NTSTATUS
FxPkgIo::InitializeDefaultQueue(
    __in    CfxDevice               * Device,
    __inout FxIoQueue               * Queue
)

/*++

    Routine Description:

    Make the input queue as the default queue. There can be
    only one queue as the default queue.

    The default queue is the place all requests go to
    automatically if a specific queue was not configured
    for them.

Arguments:


Return Value:

    NTSTATUS

--*/
{
    PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
    ULONG index;

    if (m_DefaultQueue != NULL) {
        DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO,
                            "Default Queue Already Configured for "
                            "FxPkgIo 0x%p, WDFDEVICE 0x%p %!STATUS!",this,
                            Device->GetHandle(), STATUS_UNSUCCESSFUL);
        return STATUS_UNSUCCESSFUL;
    }

    for (index=0; index <= IRP_MJ_MAXIMUM_FUNCTION; index++) {
        if (m_DispatchTable[index] == NULL) {
            m_DispatchTable[index] = Queue;
        }
    }

    m_DefaultQueue = Queue;

    //
    // Default queue can't be deleted. So mark the object to fail WdfObjectDelete on
    // the default queue.
    //
    Queue->MarkNoDeleteDDI();
    return STATUS_SUCCESS;
}
Exemple #19
0
_Must_inspect_result_
NTSTATUS
FxUsbDevice::SendSyncUmUrb(
    __inout PUMURB Urb,
    __in ULONGLONG Time,
    __in_opt WDFREQUEST Request,
    __in_opt PWDF_REQUEST_SEND_OPTIONS Options
    )
{
    NTSTATUS status;
    WDF_REQUEST_SEND_OPTIONS options;
    FxSyncRequest request(GetDriverGlobals(), NULL, Request);

    status = request.Initialize();
    if (!NT_SUCCESS(status)) {
        DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
                            "Failed to initialize FxSyncRequest");
        return status;
    }

    if (NULL == Options) {
        Options = &options;
    }
    
    WDF_REQUEST_SEND_OPTIONS_INIT(Options, 0);
    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(Options, WDF_REL_TIMEOUT_IN_SEC(Time));
    
    status = request.m_TrueRequest->ValidateTarget(this);
    if (NT_SUCCESS(status)) {
        FxUsbUmFormatRequest(request.m_TrueRequest, &Urb->UmUrbHeader, m_pHostTargetFile);
        status = SubmitSync(request.m_TrueRequest, Options);
        if (!NT_SUCCESS(status)) {
            DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
                                "FxUsbDevice SubmitSync failed");
            return status;
        }
    }

    return status;
}
VOID
FxWorkItem::Enqueue(
    VOID
    )
{
    PFX_DRIVER_GLOBALS pFxDriverGlobals;
    KIRQL irql;
    BOOLEAN enqueue;

    pFxDriverGlobals = GetDriverGlobals();
    enqueue = FALSE;

    Lock(&irql);

    if (m_Enqueued) {
        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGDEVICE,
            "Previously queued WDFWORKITEM 0x%p is already pending. "
            "Ignoring the request to queue again", GetHandle());
    }
    else if (m_RunningDown) {
        DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
                "WDFWORKITEM 0x%p is already deleted", GetHandle());
        FxVerifierDbgBreakPoint(pFxDriverGlobals);
    }
    else {
        m_WorkItemCompleted.Clear();

        m_Enqueued = TRUE;

        //
        // We are going to enqueue the work item. Reference this FxWorkItem 
        // object and Globals while they are outstanding.
        // These will be released when the workitem completes.
        //
        ADDREF(WorkItemThunk);
        pFxDriverGlobals->ADDREF(WorkItemThunk);

        enqueue = TRUE;
    }

    Unlock(irql);

    if (enqueue) {
        m_WorkItem. Enqueue(FxWorkItem::WorkItemThunk, this);
    }

    return;
}
_Must_inspect_result_
NTSTATUS
FxIoTarget::InitModeSpecific(
    __in CfxDeviceBase* Device
    )
{
    NTSTATUS status;

    //
    // FxCREvent can fail in UMDF so it is initialized outside of constuctor 
    // for UMDF. It always succeeds for KMDF so it gets initialized in 
    // event's constructor.
    //
    
    status = m_SentIoEvent.Initialize(SynchronizationEvent, FALSE);
    if (!NT_SUCCESS(status)) {
        DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR,
                            TRACINGIOTARGET,
                            "Could not initialize m_SentIoEvent event for "
                            "WFIOTARGET %p, %!STATUS!", 
                            GetObjectHandle(), status);
        return status;
    }

    status = m_DisposeEventUm.Initialize();
    if (!NT_SUCCESS(status)) {
        DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR,
                            TRACINGIOTARGET,
                            "Could not initialize m_DisposeEventUm event for "
                            "WFIOTARGET %p, %!STATUS!", 
                            GetObjectHandle(), status);
        return status;
    }

    return STATUS_SUCCESS;
}
_Must_inspect_result_
FxString *
FxDriver::GetRegistryPath(
    VOID
    )
{
    FxString *pString;

    pString = new(GetDriverGlobals(), WDF_NO_OBJECT_ATTRIBUTES)
        FxString(GetDriverGlobals());

    if (pString != NULL) {
        NTSTATUS status;

        status = pString->Assign(m_RegistryPath.Buffer);

        if (!NT_SUCCESS(status)) {
            pString->Release();
            pString = NULL;
        }
    }

    return pString;
}
Exemple #23
0
    FxTagTracker(
        __in        PFX_DRIVER_GLOBALS FxDriverGlobals,
        __in        FxTagTrackerType Type,
        __in        BOOLEAN CaptureStack,
        __in        FxObject* Owner,
        __in_opt    PVOID CreateTag = NULL
        ) :
        FxGlobalsStump(FxDriverGlobals),
        m_TrackerType(Type),
        m_CaptureStack(CaptureStack),
        m_Next(NULL),
        m_FailedCount(0),
        m_CurRefHistory(0),
        m_OwningObject(Owner)
    {
        RtlZeroMemory(m_TagHistory, sizeof(m_TagHistory));

        //
        // We keep handle reference trackers in a list,
        // which wdfkd uses to identify potential handle leaks.
        //
        if (m_TrackerType == FxTagTrackerTypeHandle) {
            FxDriverGlobalsDebugExtension* pExtension;
            KIRQL irql;
            
            pExtension = GetDriverGlobals()->DebugExtension;
            ASSERT(pExtension != NULL);

            //
            // Insert the tag tracker into the list of allocated trackers
            //
            pExtension->AllocatedTagTrackersLock.Acquire(&irql);
            InsertTailList(&pExtension->AllocatedTagTrackersListHead,
                           &m_TrackerEntry);
            pExtension->AllocatedTagTrackersLock.Release(irql);

            //
            // Handle references default to 1 outstanding ref (the object creation ref)
            //
            m_Next = new(FxDriverGlobals) FxTagTrackingBlock(CreateTag, 0, NULL, TRUE);
            if (m_Next == NULL) {
                m_FailedCount = 1;
            }
        }
        else {
            ASSERT(m_TrackerType == FxTagTrackerTypePower);
        }
    }
    virtual
    void
    Lock(
        __out PKIRQL PreviousIrql
        )
    {
        MxThread cur = Mx::MxGetCurrentThread();

        if (m_OwnerThread == cur) {
            PFX_DRIVER_GLOBALS fxDriverGlobals;

            fxDriverGlobals = GetDriverGlobals();
            m_RecursionCount++;

            //
            // For now we have decided not to allow this.
            //





            //
            DoTraceLevelMessage(fxDriverGlobals, TRACE_LEVEL_FATAL, TRACINGDEVICE,
                                "Recursive acquire of callback lock! 0x%p", this);

            FxVerifierBugCheck(fxDriverGlobals,
                               WDF_RECURSIVE_LOCK,
                               (ULONG_PTR) this);
            return;
        }
        else {
            if (m_Verifier != NULL) {
                m_Verifier->Lock(PreviousIrql, FALSE);
            }
            else {
                m_Lock.Acquire(PreviousIrql);
            }

            m_OwnerThread = cur;
            return;
        }
    }
NTSTATUS
FxDriver::OpenParametersKey(
    VOID
    )
{
    HRESULT hr;
    NTSTATUS status;
    
    PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
    PDRIVER_OBJECT_UM pDrvObj = GetDriverObject();
    IWudfDeviceStack* pDevStack = (IWudfDeviceStack*)pDrvObj->WudfDevStack;

    UMINT::WDF_PROPERTY_STORE_ROOT rootSpecifier;
    UMINT::WDF_PROPERTY_STORE_RETRIEVE_FLAGS flags;
    CANSI_STRING serviceNameA;
    DECLARE_UNICODE_STRING_SIZE(serviceNameW, WDF_DRIVER_GLOBALS_NAME_LEN);
    HKEY hKey;

    RtlInitAnsiString(&serviceNameA, FxDriverGlobals->Public.DriverName);
    status = RtlAnsiStringToUnicodeString(&serviceNameW,
                                          &serviceNameA,
                                          FALSE);
    if (NT_SUCCESS(status)) {
        rootSpecifier.LengthCb = sizeof(UMINT::WDF_PROPERTY_STORE_ROOT);
        rootSpecifier.RootClass = UMINT::WdfPropertyStoreRootDriverParametersKey;
        rootSpecifier.Qualifier.ParametersKey.ServiceName = serviceNameW.Buffer;
        
        flags = UMINT::WdfPropertyStoreCreateIfMissing;

        hr = pDevStack->CreateRegistryEntry(&rootSpecifier,
                                            flags,
                                            GENERIC_ALL & ~(GENERIC_WRITE | KEY_CREATE_SUB_KEY | WRITE_DAC),
                                            NULL,
                                            &hKey,
                                            NULL);
        status = FxDevice::NtStatusFromHr(pDevStack, hr);
        if (NT_SUCCESS(status)) {
            m_DriverParametersKey = hKey;
        }
    }

    return status;
}
Exemple #26
0
FxPkgIo::~FxPkgIo()
{
    PLIST_ENTRY next;

    m_DefaultQueue = NULL;

    m_Device = NULL;

    while (!IsListEmpty(&m_DynamicDispatchInfoListHead)) {
        next = RemoveHeadList(&m_DynamicDispatchInfoListHead);
        FxIrpDynamicDispatchInfo* info;
        info = CONTAINING_RECORD(next, FxIrpDynamicDispatchInfo, ListEntry);
        InitializeListHead(next);
        delete info;
    }

    ASSERT(IsListEmpty(&m_IoQueueListHead));

    DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGIO,
                        "Destroyed FxPkgIo 0x%p",this);
}
Exemple #27
0
_Must_inspect_result_
NTSTATUS
FxPkgIo::SetFilter(
    __in BOOLEAN Value
)
{
    PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();

    if (m_DefaultQueue != NULL) {
        DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO,
                            "I/O Package already has a default queue. "
                            "SetFilter must be called before creating "
                            "a default queue %!STATUS!",
                            STATUS_INVALID_DEVICE_REQUEST);
        FxVerifierDbgBreakPoint(FxDriverGlobals);
        return STATUS_INVALID_DEVICE_REQUEST;
    }

    m_Filter = Value;

    return STATUS_SUCCESS;
}
Exemple #28
0
_Must_inspect_result_
NTSTATUS
FxPkgIo::VerifierFreeRequestToTestForwardProgess(
    __in FxRequest* Request
)
{
    BOOLEAN failAllocation;
    PFX_DRIVER_GLOBALS pFxDriverGlobals;

    pFxDriverGlobals = GetDriverGlobals();
    failAllocation = FALSE;
    //
    // forwardProgressTestFailAll takes precedence over forwardProgressTestFailRandom
    //
    if (IsFxVerifierTestForwardProgressFailAll(pFxDriverGlobals)) {
        failAllocation = TRUE;
    }
    else if (IsFxVerifierTestForwardProgressFailRandom(pFxDriverGlobals)) {
        //
        // Modulo 17 makes the probability of failure ~6% just like verifier.exe
        //
        failAllocation = (FxRandom(&m_RandomSeed) % 17 == 0);
    }

    if (failAllocation) {
        //
        // Don't use DeleteObject() here as the Request wasn't presented to the
        // driver and the cleanup /dispose callback can be invoked unless
        // we use FreeRequest() which clears the cleanup /dispose callbacks
        //
        Request->FreeRequest();

        return STATUS_INSUFFICIENT_RESOURCES;
    }
    else {
        return STATUS_SUCCESS;
    }
}
VOID
FxIoTargetRemote::ClearTargetPointers(
    VOID
    )
{
    DoTraceLevelMessage(
        GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGIOTARGET,
        "WDFIOTARGET %p cleared pointers %p state %!WDF_IO_TARGET_STATE!,"
        " open state %d, pdo %p, fileobj %p, handle %p",
        GetObjectHandle(), m_ClearedPointers, m_State, m_OpenState, m_TargetPdo,
        m_TargetFileObject, m_TargetHandle);

    //
    // Check to see if the caller who is changing state wants these pointer
    // values before they being cleared out.
    //
    if (m_ClearedPointers != NULL) {
        m_ClearedPointers->TargetPdo = m_TargetPdo;
        m_ClearedPointers->TargetFileObject = m_TargetFileObject;
        m_ClearedPointers->TargetHandle = m_TargetHandle;
        m_ClearedPointers = NULL;
    }

    //
    // m_TargetHandle is only an FxIoTargetRemote field, clear it now
    //
    m_TargetHandle = NULL;

    //
    // m_TargetPdo and m_TargetFileObject will be cleared in the following call.
    //
    // m_TargetNotifyHandle is not cleared in the following call and is left
    // valid because we want to receive the notification about query remove being
    // canceled or completing.  When we receive either of those notifications,
    // m_TargetNotifyHandle will be freed then.
    //
    __super::ClearTargetPointers();
}
FxWorkItem::~FxWorkItem(
    VOID
    )
{
    PFX_DRIVER_GLOBALS pFxDriverGlobals;

    pFxDriverGlobals = GetDriverGlobals();

    //
    // If this hits, it's because someone destroyed the WORKITEM by
    // removing too many references by mistake without calling WdfObjectDelete
    //
    if (m_RunningDown == FALSE && m_Callback != NULL) {
        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
            "WDFWORKITEM %p destroyed without calling WdfObjectDelete, or by "
            "Framework processing DeviceRemove.  Possible reference count "
            "problem?", GetObjectHandleUnchecked());
        FxVerifierDbgBreakPoint(pFxDriverGlobals);
    }

    // Release our parent object reference
    if (m_Object != NULL) {
        m_Object->RELEASE(this);
        m_Object = NULL;
    }

    // Free the workitem
    if (m_WorkItem.GetWorkItem() != NULL) {
        m_WorkItem.Free();
        //m_WorkItem = NULL;
    }

    ASSERT(m_Enqueued == FALSE);
    ASSERT(m_WorkItemRunningCount == 0L);

    return;
}