WDFOBJECT
WDFEXPORT(WdfDpcGetParentObject)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDPC Dpc
    )

/*++

Routine Description:

    Return the parent parent object supplied to WdfDpcCreate.

Arguments:

    WDFDPC - Handle to WDFDPC object created with WdfDpcCreate.

Returns:

--*/

{
    FxDpc* pFxDpc;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         Dpc,
                         FX_TYPE_DPC,
                         (PVOID*)&pFxDpc);

    return pFxDpc->GetObject();
}
KDPC*
WDFEXPORT(WdfDpcWdmGetDpc)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDPC Dpc
    )
/*++

Routine Description:

    Return the KDPC* object pointer so that it may be linked into
    a DPC list.

Arguments:

    WDFDPC - Handle to WDFDPC object created with WdfDpcCreate.

Returns:

    KDPC*

--*/

{
    FxDpc* pFxDpc;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         Dpc,
                         FX_TYPE_DPC,
                         (PVOID*)&pFxDpc);

    return pFxDpc->GetDpcPtr();
}
BOOLEAN
WDFEXPORT(WdfDpcEnqueue)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDPC Dpc
    )

/*++

Routine Description:

    Enqueue the DPC to run at a system determined time

Arguments:

    WDFDPC - Handle to WDFDPC object created with WdfDpcCreate.

Returns:

--*/

{
    FxDpc* pFxDpc;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         Dpc,
                         FX_TYPE_DPC,
                         (PVOID*)&pFxDpc);

    return KeInsertQueueDpc(pFxDpc->GetDpcPtr(), NULL, NULL);
}
WDFOBJECT
WDFEXPORT(WdfCollectionGetLastItem)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFCOLLECTION Collection
    )
{
    DDI_ENTRY();

    FxCollection *pCollection;
    FxObject* pObject;
    KIRQL irql;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         Collection,
                         FX_TYPE_COLLECTION,
                         (PVOID*) &pCollection);

    pCollection->Lock(&irql);
    pObject = pCollection->GetLastItem();
    pCollection->Unlock(irql);

    if (pObject != NULL) {
        return pObject->GetObjectHandle();
    }
    else {
        return NULL;
    }
}
ULONG
WDFEXPORT(WdfCollectionGetCount)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFCOLLECTION Collection
    )
{
    DDI_ENTRY();

    FxCollection *pCollection;
    KIRQL irql;
    ULONG count;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         Collection,
                         FX_TYPE_COLLECTION,
                         (PVOID *)&pCollection);

    pCollection->Lock(&irql);
    count = pCollection->Count();
    pCollection->Unlock(irql);

    return count;
}
NTSTATUS
WDFEXPORT(WdfCollectionAdd)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFCOLLECTION Collection,
    __in
    WDFOBJECT Object
    )
{
    DDI_ENTRY();

    PFX_DRIVER_GLOBALS pFxDriverGlobals;
    FxCollection *pCollection;
    FxObject *pObject;
    NTSTATUS status;
    KIRQL irql;

    FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
                                   Collection,
                                   FX_TYPE_COLLECTION,
                                   (PVOID*) &pCollection,
                                   &pFxDriverGlobals);

    FxObjectHandleGetPtr(pFxDriverGlobals,
                         Object,
                         FX_TYPE_OBJECT,
                         (PVOID*) &pObject);

    pCollection->Lock(&irql);
    status = pCollection->Add(pObject) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
    pCollection->Unlock(irql);

    return status;
}
示例#7
0
VOID
WDFEXPORT(WdfDeviceClearRemovalRelationsDevices)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDEVICE Device
    )
/*++

Routine Description:
    Deregisters all PDOs to not be reported as also requiring removal when this
    PDO is removed.

Arguments:
    Device - this driver's PDO

Return Value:
    None

  --*/
{
    FxDevice* pDevice;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         Device,
                         FX_TYPE_DEVICE,
                         (PVOID*) &pDevice);

    pDevice->m_PkgPnp->ClearRemovalDevicesList();
}
NTSTATUS
WDFEXPORT(WdfWmiProviderCreate)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDEVICE Device,
    __in
    PWDF_WMI_PROVIDER_CONFIG WmiProviderConfig,
    __in_opt
    PWDF_OBJECT_ATTRIBUTES ProviderAttributes,
    __out
    WDFWMIPROVIDER* WmiProvider
    )
{
    FxDevice* pDevice;
    FxPowerPolicyOwnerSettings* ownerSettings;
    FxWmiProvider* pProvider;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         Device,
                         FX_TYPE_DEVICE,
                         (PVOID*) &pDevice);

    FxPointerNotNull(GetFxDriverGlobals(DriverGlobals), WmiProviderConfig);
    FxPointerNotNull(GetFxDriverGlobals(DriverGlobals), WmiProvider);

    //
    // If the Device is a power policy owner then do not allow client drivers
    // to register for GUID_POWER_DEVICE_ENABLE or GUID_POWER_DEVICE_WAKE_ENABLE
    // if the framework has already register a provider for those guids.
    //
    if (pDevice->m_PkgPnp->IsPowerPolicyOwner()) {
        ownerSettings = pDevice->m_PkgPnp->m_PowerPolicyMachine.m_Owner;

        if ((FxIsEqualGuid(&WmiProviderConfig->Guid,
                           &GUID_POWER_DEVICE_ENABLE) &&
             ownerSettings->m_IdleSettings.WmiInstance != NULL) ||

            (FxIsEqualGuid(&WmiProviderConfig->Guid,
                           &GUID_POWER_DEVICE_WAKE_ENABLE) &&
             ownerSettings->m_WakeSettings.WmiInstance != NULL)) {

            DoTraceLevelMessage(GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_ERROR,
                                TRACINGDEVICE, "WMI Guid already registered by "
                                "framework");
            return STATUS_WMI_GUID_DISCONNECTED;
        }
    }

    return FxWmiProvider::_Create(GetFxDriverGlobals(DriverGlobals),
                                  Device,
                                  ProviderAttributes,
                                  WmiProviderConfig,
                                  WmiProvider,
                                  &pProvider);
}
VOID
WDFEXPORT(WdfCollectionRemove)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFCOLLECTION Collection,
    __in
    WDFOBJECT Item
    )
{
    DDI_ENTRY();

    PFX_DRIVER_GLOBALS pFxDriverGlobals;
    FxCollection *pCollection;
    FxCollectionEntry *pEntry;
    FxObject* pObject;
    NTSTATUS status;
    KIRQL irql;

    FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
                                   Collection,
                                   FX_TYPE_COLLECTION,
                                   (PVOID*) &pCollection,
                                   &pFxDriverGlobals);

    FxObjectHandleGetPtr(pFxDriverGlobals,
                         Item,
                         FX_TYPE_OBJECT,
                         (PVOID*) &pObject);

    pCollection->Lock(&irql);

    pEntry = pCollection->FindEntryByObject(pObject);

    if (pEntry != NULL) {
        pCollection->CleanupEntry(pEntry);
        status = STATUS_SUCCESS;
    }
    else {
        pObject = NULL;
        status = STATUS_NOT_FOUND;
    }

    pCollection->Unlock(irql);

    if (pObject != NULL) {
        pCollection->CleanupEntryObject(pObject);
    }

    if (!NT_SUCCESS(status)) {
        DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
                            "WDFOBJECT %p not in WDFCOLLECTION %p, %!STATUS!",
                            Item, Collection, status);
        FxVerifierDbgBreakPoint(pFxDriverGlobals);
    }
}
ULONGLONG
WDFEXPORT(WdfWmiProviderGetTracingHandle)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFWMIPROVIDER WmiProvider
    )
{
    FxWmiProvider *pProvider;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         WmiProvider,
                         FX_TYPE_WMI_PROVIDER,
                         (PVOID*) &pProvider);

    return pProvider->GetTracingHandle();
}
示例#11
0
PDEVICE_OBJECT
WDFEXPORT(WdfDeviceWdmGetAttachedDevice)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDEVICE Device
    )
{
    FxDeviceBase *pDevice;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         Device,
                         FX_TYPE_DEVICE_BASE,
                         (PVOID*) &pDevice);

    return pDevice->GetAttachedDevice();
}
WDFWMIPROVIDER
WDFEXPORT(WdfWmiInstanceGetProvider)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFWMIINSTANCE WmiInstance
    )
{
    FxWmiInstanceExternal *pInstance;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         WmiInstance,
                         FX_TYPE_WMI_INSTANCE,
                         (PVOID*) &pInstance);

    return pInstance->GetProvider()->GetHandle();
}
VOID
WDFEXPORT(WdfWmiInstanceDeregister)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFWMIINSTANCE WmiInstance
    )
{
    FxWmiInstanceExternal* pInstance;
    FxWmiProvider* pProvider;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         WmiInstance,
                         FX_TYPE_WMI_INSTANCE,
                         (PVOID*) &pInstance);

    pProvider = pInstance->GetProvider();
    pProvider->RemoveInstance(pInstance);
}
BOOLEAN
WDFEXPORT(WdfWmiProviderIsEnabled)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFWMIPROVIDER WmiProvider,
    __in
    WDF_WMI_PROVIDER_CONTROL ProviderControl
    )
{
    FxWmiProvider *pProvider;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         WmiProvider,
                         FX_TYPE_WMI_PROVIDER,
                         (PVOID*) &pProvider);

    return pProvider->IsEnabled(ProviderControl);
}
BOOLEAN
WDFAPI
WDFEXPORT(WdfUsbTargetPipeIsOutEndpoint)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFUSBPIPE Pipe
    )
{
    DDI_ENTRY();

    FxUsbPipe* pUsbPipe;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         Pipe,
                         FX_TYPE_IO_TARGET_USB_PIPE,
                         (PVOID*) &pUsbPipe);

    return pUsbPipe->IsOutEndpoint();
}
示例#16
0
VOID
WDFEXPORT(WdfDeviceSetBusInformationForChildren)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDEVICE Device,
    __in
    PPNP_BUS_INFORMATION BusInformation
    )
{
    FxDevice* pDevice;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         Device,
                         FX_TYPE_DEVICE,
                         (PVOID*) &pDevice);

    FxPointerNotNull(pDevice->GetDriverGlobals(), BusInformation);

    pDevice->m_PkgPnp->SetChildBusInformation(BusInformation);
}
NTSTATUS
WDFAPI
WDFEXPORT(WdfUsbTargetPipeFormatRequestForReset)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFUSBPIPE Pipe,
    __in
    WDFREQUEST Request
    )
{
    DDI_ENTRY();

    PFX_DRIVER_GLOBALS pFxDriverGlobals;
    FxRequest* pRequest;
    FxUsbPipe* pUsbPipe;
    NTSTATUS status;

    FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
                                   Pipe,
                                   FX_TYPE_IO_TARGET_USB_PIPE,
                                   (PVOID*) &pUsbPipe,
                                   &pFxDriverGlobals);

    DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
                        "Pipe %p, Request %p", Pipe, Request);

    FxObjectHandleGetPtr(pFxDriverGlobals,
                         Request,
                         FX_TYPE_REQUEST,
                         (PVOID*) &pRequest);

    status = pUsbPipe->FormatResetRequest(pRequest);

    DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
                        "Pipe %p, Request %p = 0x%x",
                        Pipe, Request, status);

    return status;
}
示例#18
0
VOID
WDFEXPORT(WdfDeviceRemoveRemovalRelationsPhysicalDevice)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDEVICE Device,
    __in
    PDEVICE_OBJECT PhysicalDevice
    )
/*++

Routine Description:
    Deregisters a PDO from another non descendant (not verifiable though) pnp
    stack to not be reported as also requiring removal when this PDO is removed.

    The PDO could be another device enumerated by this driver.

Arguments:
    Device - this driver's PDO

    PhysicalDevice - PDO for another stack

Return Value:
    None

  --*/
{
    FxDevice* pDevice;

    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         Device,
                         FX_TYPE_DEVICE,
                         (PVOID*) &pDevice);

    FxPointerNotNull(pDevice->GetDriverGlobals(), PhysicalDevice);

    pDevice->m_PkgPnp->RemoveRemovalDevice(PhysicalDevice);
}
示例#19
0
VOID
WDFEXPORT(WdfDeviceSetSpecialFileSupport)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDEVICE Device,
    __in
    WDF_SPECIAL_FILE_TYPE FileType,
    __in
    BOOLEAN Supported
    )
{
    FxDevice* pDevice;
    PFX_DRIVER_GLOBALS pFxDriverGlobals;

    FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
                                   Device,
                                   FX_TYPE_DEVICE,
                                   (PVOID *) &pDevice,
                                   &pFxDriverGlobals);

    if (FileType < WdfSpecialFilePaging  || FileType >= WdfSpecialFileMax) {
        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
            "WDFDEVICE 0x%p FileType %d specified is not in valid range",
            Device, FileType);
        FxVerifierDbgBreakPoint(pFxDriverGlobals);
        return;
    }

    FxObjectHandleGetPtr(pFxDriverGlobals,
                         Device,
                         FX_TYPE_DEVICE,
                         (PVOID*) &pDevice);

    pDevice->m_PkgPnp->SetSpecialFileSupport(FileType, Supported);
}
示例#20
0
NTSTATUS
WDFEXPORT(WdfDeviceWdmDispatchIrpToIoQueue)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDEVICE Device,
    __in
    MdIrp Irp,
    __in
    WDFQUEUE Queue,
    __in
    ULONG Flags
    )
{
    FxIoQueue           *queue;
    FxDevice            *device;
    PFX_DRIVER_GLOBALS  fxDriverGlobals;
    PIO_STACK_LOCATION  stack;
    NTSTATUS            status;
    FxIoInCallerContext* ioInCallerCtx;
    
    queue = NULL;
    ioInCallerCtx = NULL;
    
    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         Device,
                         FX_TYPE_DEVICE,
                         (PVOID*) &device);

    fxDriverGlobals = device->GetDriverGlobals();    
    FX_TRACK_DRIVER(fxDriverGlobals);
    
    FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                         Queue,
                         FX_TYPE_QUEUE,
                         (PVOID*)&queue);
    
    FxPointerNotNull(fxDriverGlobals, Irp);

    //
    // If the caller is a preprocess routine, the contract for this DDI is just like IoCallDriver.  
    // The caller sets up their stack location and then the DDI advances to the next stack
    // location. This means that the caller either has to call IoSkipCurrentIrpStackLocation
    // or IoCopyCurrentIrpStackLocationToNext before calling this DDI.
    //
    if (Flags & WDF_DISPATCH_IRP_TO_IO_QUEUE_PREPROCESSED_IRP) {
        IoSetNextIrpStackLocation(Irp);
    }

    //
    // Verifier checks.
    //
    status = VerifyWdfDeviceWdmDispatchIrpToIoQueue(fxDriverGlobals, 
                                                    device, 
                                                    Irp, 
                                                    queue, 
                                                    Flags);
    if(!NT_SUCCESS(status)) {
        Irp->IoStatus.Status = status;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return status;
    }
    
    //
    // Adjust stack if IRP needs to be forwarded to parent device.
    //
    if (device->m_ParentDevice == queue->GetDevice()) {
        IoCopyCurrentIrpStackLocationToNext(Irp);   
        IoSetNextIrpStackLocation(Irp);    

        //
        // From now on use new device. 
        //
        device = device->m_ParentDevice;
        
        //
        // Save a pointer to the device object for this request so that it can
        // be used later in completion.
        //
        stack = IoGetCurrentIrpStackLocation(Irp);
        stack->DeviceObject = device->GetDeviceObject();
    }
    
    //
    // Get in-context caller callback if required.
    //
    if (Flags & WDF_DISPATCH_IRP_TO_IO_QUEUE_INVOKE_INCALLERCTX_CALLBACK) {
        ioInCallerCtx = device->m_PkgIo->GetIoInCallerContextCallback(
                                                queue->GetCxDeviceInfo());
    }
    
    //
    // DispatchStep2 will convert the IRP into a WDFREQUEST, queue it and if 
    // possible dispatch the request to the driver.
    //
    return device->m_PkgIo->DispatchStep2(Irp, ioInCallerCtx, queue);    
}
示例#21
0
NTSTATUS
WDFEXPORT(WdfDeviceWdmDispatchIrp)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDEVICE Device,
    __in
    MdIrp Irp,
    __in
    WDFCONTEXT DispatchContext
    )
    
/*++

Routine Description:

    Client driver calls this API from its dispatch callback when it decides to hand the IRP 
    back to framework.

    Cx calls this API from (a) its pre-process callback or (b) its dispatch callback when 
    it decides to hand the IRP back to the framework.

Arguments:
    Device - WDF Device handle.

    IRP - WDM request.

    DispatchContext - WDF's context (input arg to callback).

Returns:
    IRP's status.

--*/
    
{
    FxDevice *device;
    NTSTATUS status;

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

    FxPointerNotNull(device->GetDriverGlobals(), Irp);
    FxPointerNotNull(device->GetDriverGlobals(), DispatchContext);

    if ((UCHAR)DispatchContext & FX_IN_DISPATCH_CALLBACK) {
        //
        // Called from a dispach irp callback.
        //
        DispatchContext = 
            (WDFCONTEXT)((ULONG_PTR)DispatchContext & ~FX_IN_DISPATCH_CALLBACK);

        //
        // DispatchContext is validated by DispatchStep1.
        //
        status = device->m_PkgIo->DispatchStep1(Irp, DispatchContext);
    }
    else {
        //
        // Called from a pre-process irp callback.
        //
        
        //
        // Verifier checks.
        //
        VerifyWdfDeviceWdmDispatchIrp(device->GetDriverGlobals(), 
                                      DriverGlobals,
                                      device, 
                                      DispatchContext);
        
        status = device->DispatchPreprocessedIrp(Irp, DispatchContext);
    }
    
    return status;
}
示例#22
0
WDFFILEOBJECT
WDFEXPORT(WdfDeviceGetFileObject)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDEVICE Device,
    __in
    MdFileObject FileObject
    )
/*++

Routine Description:

    This functions returns the WDFFILEOBJECT corresponding to the WDM fileobject.

Arguments:

    Device - Handle to the device to which the WDM fileobject is related to.

    FileObject - WDM FILE_OBJECT structure.

Return Value:

--*/

{
    PFX_DRIVER_GLOBALS pFxDriverGlobals;
    NTSTATUS status;
    FxFileObject* pFxFO;
    FxDevice *pDevice;

    pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
    




    
    pFxFO = NULL;

    //
    // Validate the Device object handle, and get its FxDevice*
    //
    FxObjectHandleGetPtr(pFxDriverGlobals,
                         Device,
                         FX_TYPE_DEVICE,
                         (PVOID*)&pDevice);

    //
    // Call the static GetFileObjectFromWdm function. This will return an error if the
    // WDM fileObject is NULL and the device is not exclusive or the device is
    // configured to have a WDFFILEOBJECT for every open handle.
    //
    status = FxFileObject::_GetFileObjectFromWdm(
        pDevice,
        pDevice->GetFileObjectClass(),
        FileObject,
        &pFxFO
        );

    if (!NT_SUCCESS(status)) {
         DoTraceLevelMessage(
             pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
             "FxFileObject::_GetFileObjectFromWdm returned an error %!STATUS!",
             status);
         return NULL;
    }

    //
    // pFxFO can be NULL if the device is configured with FileObjectClass WdfFileObjectNotRequired.
    //
    return pFxFO != NULL ? pFxFO->GetHandle() : NULL;
}
NTSTATUS
WDFEXPORT(WdfDmaTransactionInitializeUsingRequest)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDMATRANSACTION DmaTransaction,
    __in
    WDFREQUEST Request,
    __in
    PFN_WDF_PROGRAM_DMA EvtProgramDmaFunction,
    __in
    WDF_DMA_DIRECTION DmaDirection
    )
{
    NTSTATUS status;
    FxDmaTransactionBase* pDmaTrans;
    FxRequest* pReqObj;
    MDL* mdl = NULL;
    PIO_STACK_LOCATION stack;
    ULONG reqLength;
    PFX_DRIVER_GLOBALS  pFxDriverGlobals;

    FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
                                   DmaTransaction,
                                   FX_TYPE_DMA_TRANSACTION,
                                   (PVOID *) &pDmaTrans,
                                   &pFxDriverGlobals);

    FxPointerNotNull(pFxDriverGlobals, EvtProgramDmaFunction);

    if (DmaDirection != WdfDmaDirectionReadFromDevice &&
        DmaDirection != WdfDmaDirectionWriteToDevice) {
        status = STATUS_INVALID_PARAMETER;
        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA,
            "Initialization of WDFDMATRANSACTION 0x%p using WDFREQUEST %p, "
            "DmaDirection 0x%x is an invalid value, %!STATUS!",
            DmaTransaction, Request, DmaDirection, status);
        return status;
    }

    FxObjectHandleGetPtr(pFxDriverGlobals,
                         Request,
                         FX_TYPE_REQUEST,
                         (PVOID *) &pReqObj);

    reqLength = 0;

    stack = pReqObj->GetFxIrp()->GetCurrentIrpStackLocation();

    //
    // Get the MDL and Length from the request.
    //
    switch (stack->MajorFunction) {

    case IRP_MJ_READ:

        if (DmaDirection != WdfDmaDirectionReadFromDevice) {
            status = STATUS_INVALID_DEVICE_REQUEST;

            DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA,
                                "Dma direction %!WDF_DMA_DIRECTION! of WDFTRANSACTION "
                                "0x%p doesn't match with the WDFREQUEST 0x%p type "
                                "%!WDF_REQUEST_TYPE! %!STATUS!",
                                DmaDirection, DmaTransaction, Request,
                                stack->MajorFunction, status);

            return status;
        }

        reqLength = stack->Parameters.Read.Length;

        status = pReqObj->GetMdl(&mdl);
        break;

    case IRP_MJ_WRITE:

        if (DmaDirection != WdfDmaDirectionWriteToDevice) {
            status = STATUS_INVALID_DEVICE_REQUEST;

            DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA,
                                "Dma direction %!WDF_DMA_DIRECTION! of WDFTRANSACTION "
                                "0x%p doesn't match with the WDFREQUEST 0x%p type "
                                "%!WDF_REQUEST_TYPE! %!STATUS!",
                                DmaDirection, DmaTransaction, Request,
                                stack->MajorFunction, status);

            return status;
        }

        reqLength = stack->Parameters.Write.Length;

        status = pReqObj->GetMdl(&mdl);
        break;

    case IRP_MJ_DEVICE_CONTROL:
    case IRP_MJ_INTERNAL_DEVICE_CONTROL:

        switch (METHOD_FROM_CTL_CODE(stack->Parameters.DeviceIoControl.IoControlCode)) {
            case METHOD_BUFFERED:

                if (DmaDirection == WdfDmaDirectionWriteToDevice) {
                    reqLength = stack->Parameters.DeviceIoControl.InputBufferLength;
                } else {
                    reqLength = stack->Parameters.DeviceIoControl.OutputBufferLength;
                }

                //
                // In this case both input buffer and output buffer map
                // to the same MDL and it's probed for read & write access.
                // So it's okay for DMA transfer in either direction.
                //
                status = pReqObj->GetMdl(&mdl);
                break;

            case METHOD_IN_DIRECT:
                //
                // For this type, the output buffer is probed for read access.
                // So the direction of DMA transfer is WdfDmaDirectionWriteToDevice.
                //
                if (DmaDirection != WdfDmaDirectionWriteToDevice) {

                    status = STATUS_INVALID_DEVICE_REQUEST;

                    DoTraceLevelMessage(pFxDriverGlobals,
                                        TRACE_LEVEL_ERROR, TRACINGDMA,
                                        "Dma direction %!WDF_DMA_DIRECTION! of WDFTRANSACTION "
                                        "0x%p doesn't match with WDFREQUEST 0x%p ioctl type "
                                        "METHOD_IN_DIRECT %!STATUS!",
                                        DmaDirection, DmaTransaction, Request, status);
                    return status;
                }

                reqLength = stack->Parameters.DeviceIoControl.OutputBufferLength;

                status = pReqObj->GetDeviceControlOutputMdl(&mdl);

                break;

            case METHOD_OUT_DIRECT:
                //
                // For this type, the output buffer is probed for write access.
                // So the direction of DMA transfer is WdfDmaDirectionReadFromDevice.
                //
                if (DmaDirection != WdfDmaDirectionReadFromDevice) {

                    status = STATUS_INVALID_DEVICE_REQUEST;

                    DoTraceLevelMessage(pFxDriverGlobals,
                                        TRACE_LEVEL_ERROR, TRACINGDMA,
                                        "Dma direction %!WDF_DMA_DIRECTION! of WDFTRANSACTION "
                                        "0x%p doesn't match with WDFREQUEST 0x%p ioctl type "
                                        "METHOD_OUT_DIRECT %!STATUS!",
                                        DmaDirection, DmaTransaction, Request, status);

                    return status;
                }

                reqLength = stack->Parameters.DeviceIoControl.OutputBufferLength;

                status = pReqObj->GetDeviceControlOutputMdl(&mdl);

                break;
            default:

                status = STATUS_INVALID_DEVICE_REQUEST;

                DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA,
                                    "Invalid ioctl code in WDFREQUEST 0x%p %!STATUS!",
                                    Request, status);

                FxVerifierDbgBreakPoint(pFxDriverGlobals);
                break;

        }// End of switch(ioctType)
        break;

    default:
        status = STATUS_INVALID_DEVICE_REQUEST;
        break;

    }

    if (!NT_SUCCESS(status)) {
        DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA,
                            "Couldn't retrieve mdl from WDFREQUEST 0x%p for "
                            "WDFTRANSACTION 0x%p %!STATUS!",
                            Request, DmaTransaction, status);
        return status;
    }

    if (reqLength == 0) {
        status = STATUS_INVALID_DEVICE_REQUEST;
        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA,
            "Zero length request, %!STATUS!", status);
        return status;
    }

    //
    // If the DMA enabler is packet based, make sure the virtual address and
    // the length of transfer are within bounds. Basically, we are checking
    // to see if the length of data to be transferred doesn't span multiple
    // MDLs, because packet based DMA doesn't support chained MDLs.
    //
    if (pDmaTrans->GetDmaEnabler()->SupportsChainedMdls() == FALSE) {
        ULONG  length;

        length = MmGetMdlByteCount(mdl);

        if (reqLength > length) {
            status = STATUS_INVALID_PARAMETER;
            DoTraceLevelMessage(
                pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA,
                "WDFREQUEST %p transfer length (%d) is out of bounds of MDL "
                "Byte count (%d), %!STATUS!",
                Request, reqLength, length, status);

            return status;
        }
    }

    //
    // Parms appear OK, so initialize this instance.
    //
    status = pDmaTrans->Initialize(EvtProgramDmaFunction,
                                   DmaDirection,
                                   mdl,
                                   0,
                                   reqLength);

    if (!NT_SUCCESS(status)) {
        DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA,
                            "WDFTANSACTION 0x%p initialization failed: "
                            "%!STATUS!", DmaTransaction, status);
        return status;
    }

    //
    // Set this Request in the new DmaTransaction.  The request will 
    // take a reference on this request when it starts executing.
    //
    pDmaTrans->SetRequest(pReqObj);

    return STATUS_SUCCESS;
}
NTSTATUS
WDFEXPORT(WdfWmiInstanceCreate)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDEVICE Device,
    __in
    PWDF_WMI_INSTANCE_CONFIG InstanceConfig,
    __in_opt
    PWDF_OBJECT_ATTRIBUTES InstanceAttributes,
    __out_opt
    WDFWMIINSTANCE* Instance
    )
{
    PFX_DRIVER_GLOBALS pFxDriverGlobals;
    FxWmiProvider* pProvider;
    FxWmiInstanceExternal* pInstance;
    WDFWMIINSTANCE hInstance;
    NTSTATUS status;

    pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
    pInstance = NULL;

    FxPointerNotNull(pFxDriverGlobals, InstanceConfig);

    if (InstanceConfig->Size != sizeof(WDF_WMI_INSTANCE_CONFIG)) {
        status = STATUS_INFO_LENGTH_MISMATCH;
        DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
                            "Expected InstanceConfig Size %d, got %d, %!STATUS!",
                            InstanceConfig->Size, sizeof(*InstanceConfig),
                            status);
        return status;
    }

    if (InstanceConfig->Provider == NULL &&
                                    InstanceConfig->ProviderConfig == NULL) {
        status = STATUS_INVALID_PARAMETER;

        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
            "InstanceConfig %p Provider and ProviderConfig are both NULL, only "
            "one can be, %!STATUS!", InstanceConfig, status);

        return status;
    }
    else if (InstanceConfig->Provider != NULL &&
                                    InstanceConfig->ProviderConfig != NULL) {
        status = STATUS_INVALID_PARAMETER;

        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
            "InstanceConfig %p Provider %p and ProviderConfig %p are both not "
            "NULL, only one can be, %!STATUS!", InstanceConfig,
            InstanceConfig->Provider, InstanceConfig->ProviderConfig, status);

        return status;
    }

    if (InstanceConfig->Provider != NULL) {
        FxObjectHandleGetPtrAndGlobals(pFxDriverGlobals,
                                       InstanceConfig->Provider,
                                       FX_TYPE_WMI_PROVIDER,
                                       (PVOID*) &pProvider,
                                       &pFxDriverGlobals);
    }
    else {
        FxDevice* pDevice;
        FxPowerPolicyOwnerSettings* ownerSettings;
        WDFWMIPROVIDER hProvider;

        hProvider = NULL;
        FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
                             Device,
                             FX_TYPE_DEVICE,
                             (PVOID*) &pDevice);

        //
        // If the Device is a power policy owner then do not allow client drivers
        // to register for GUID_POWER_DEVICE_ENABLE or GUID_POWER_DEVICE_WAKE_ENABLE
        // if the framework has already register a provider for those guids.
        //
        if (pDevice->m_PkgPnp->IsPowerPolicyOwner()) {
            ownerSettings = pDevice->m_PkgPnp->m_PowerPolicyMachine.m_Owner;

            if ((FxIsEqualGuid(&InstanceConfig->ProviderConfig->Guid,
                               &GUID_POWER_DEVICE_ENABLE) &&
                 ownerSettings->m_IdleSettings.WmiInstance != NULL) ||

                (FxIsEqualGuid(&InstanceConfig->ProviderConfig->Guid,
                               &GUID_POWER_DEVICE_WAKE_ENABLE) &&
                 ownerSettings->m_WakeSettings.WmiInstance != NULL)) {

                status = STATUS_WMI_GUID_DISCONNECTED;
                DoTraceLevelMessage(GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_ERROR,
                                    TRACINGDEVICE, "WMI Guid already registered by "
                                    "framework");
                return status;
            }
        }

        status = FxWmiProvider::_Create(pFxDriverGlobals,
                                        Device,
                                        NULL,
                                        InstanceConfig->ProviderConfig,
                                        &hProvider,
                                        &pProvider);

        if (!NT_SUCCESS(status)) {
            return status;
        }

        //
        // Use the object's globals and not the caller's
        //
        pFxDriverGlobals = pProvider->GetDriverGlobals();
    }

    status = FxWmiInstanceExternal::_Create(pFxDriverGlobals,
                                            pProvider,
                                            InstanceConfig,
                                            InstanceAttributes,
                                            &hInstance,
                                            &pInstance);

    if (NT_SUCCESS(status) && InstanceConfig->Register) {
        status = pProvider->AddInstance(pInstance);
    }

    if (NT_SUCCESS(status)) {
        if (Instance != NULL) {
            *Instance = hInstance;
        }
    }
    else {
        //
        // Something went wrong, cleanup
        //
        if (pInstance != NULL) {
            //
            // This will remove the instance from the provider's list as well.
            //
            pInstance->DeleteFromFailedCreate();
        }

        //
        // Only remove the provider if we created it in this function
        //
        if (InstanceConfig->ProviderConfig != NULL) {
            pProvider->DeleteFromFailedCreate();
        }
    }

    return status;
}
_Must_inspect_result_
NTSTATUS
FxIoTargetRemote::_Create(
    __in PFX_DRIVER_GLOBALS FxDriverGlobals,
    __in PWDF_OBJECT_ATTRIBUTES Attributes,
    __in CfxDeviceBase* Device,
    __out FxIoTargetRemote** Target
    )
{
    FxIoTargetRemote* pTarget;
    FxObject* pParent;
    WDFOBJECT hTarget;
    NTSTATUS status;

    *Target = NULL;

    if (Attributes == NULL || Attributes->ParentObject == NULL) {
        pParent = Device;
    }
    else {
        CfxDeviceBase* pSearchDevice;

        FxObjectHandleGetPtr(FxDriverGlobals,
                             Attributes->ParentObject,
                             FX_TYPE_OBJECT,
                             (PVOID*) &pParent);

        pSearchDevice = FxDeviceBase::_SearchForDevice(pParent, NULL);

        if (pSearchDevice == NULL) {
            status = STATUS_INVALID_DEVICE_REQUEST;

            DoTraceLevelMessage(
                FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
                "Attributes->ParentObject 0x%p must have WDFDEVICE as an "
                "eventual ancestor, %!STATUS!",
                Attributes->ParentObject, status);

            return status;
        }
        else if (pSearchDevice != Device) {
            status = STATUS_INVALID_DEVICE_REQUEST;

            DoTraceLevelMessage(
                FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
                "Attributes->ParentObject 0x%p ancestor is WDFDEVICE %p, but "
                "not the same WDFDEVICE 0x%p passed to WdfIoTargetCreate, "
                "%!STATUS!",
                Attributes->ParentObject, pSearchDevice->GetHandle(),
                Device->GetHandle(), status);

            return status;
        }
    }

    pTarget = new (FxDriverGlobals, Attributes)
        FxIoTargetRemote(FxDriverGlobals);

    if (pTarget == NULL) {
        status =  STATUS_INSUFFICIENT_RESOURCES;
        DoTraceLevelMessage(
            FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
            "Could not allocate memory for target, %!STATUS!", status);
        return status;
    }

    //
    // initialize the new target
    //
    status = pTarget->InitRemote(Device);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Commit and apply the attributes
    //
    status = pTarget->Commit(Attributes, &hTarget, pParent);

    if (NT_SUCCESS(status)) {
        *Target = pTarget;
    }
    else {
        //
        // This will properly clean up the target's state and free it
        //
        DoTraceLevelMessage(
            FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
            "Commit failed for target, %!STATUS!", status);
        pTarget->DeleteFromFailedCreate();
    }

    return status;
}
示例#26
0
WDFAPI
NTSTATUS
WDFEXPORT(WdfDeviceConfigureWdmIrpDispatchCallback)(
    __in
    PWDF_DRIVER_GLOBALS DriverGlobals,
    __in
    WDFDEVICE Device,
    __in_opt
    WDFDRIVER Driver,
    __in
    UCHAR MajorFunction,
    __in
    PFN_WDFDEVICE_WDM_IRP_DISPATCH EvtDeviceWdmIrpDispatch,
    __in_opt
    WDFCONTEXT DriverContext
    )
    
/*++
    
    Routine Description:
    
        Configure callbacks for read, write, ctrl and  internal_ctrl.   By default the I/O package 
        sends all requests to  the  devices default queue or to the queues configured with 
        WdfDeviceConfigureRequestDispatching.
        This API allows a driver specified callback to select the target queue dynamically.
 
    Arguments:
    
        Device      - The device which is handling the IO.

        Driver      - Optional Driver, used to associate callback with a specific class extension. 
    
        RequestType - WDF Request type to be forwarded to the callback

        EvtDeviceWdmIrpDispatch - Driver's callback.

        DriverContext - Callback's context.
    
    Returns:
    
        NTSTATUS
    
 --*/
{
    PFX_DRIVER_GLOBALS  fxDriverGlobals;
    NTSTATUS            status;
    FxDevice*           device;
    FxCxDeviceInfo*     cxDeviceInfo;

    device = NULL;
    cxDeviceInfo = NULL;

    FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
                                   Device,
                                   FX_TYPE_DEVICE,
                                   (PVOID *) &device,
                                   &fxDriverGlobals);
    //
    // Validate the driver handle and get (if present) the associated cx info.
    //
    if (Driver != NULL) {
        FxDriver*   driver;
        
        FxObjectHandleGetPtr(fxDriverGlobals,
                             Driver,
                             FX_TYPE_DRIVER,
                             (PVOID*)&driver);

        //
        // Find the driver's cx info if it's not the main driver for this device.
        // cx struct info can be NULL if cx acts as client driver.
        //
        cxDeviceInfo = device->GetCxDeviceInfo(driver);
    }

    //
    // Make sure callback is not null.
    //
    FxPointerNotNull(fxDriverGlobals, EvtDeviceWdmIrpDispatch);

    //
    // This callback can only be called during initialization.
    //
    if (device->IsLegacy()) {
        //
        // This is a controldevice. Make sure the create is called after the device
        // is initialized and ready to accept I/O.
        //
        if ((device->GetDeviceObject()->Flags & DO_DEVICE_INITIALIZING) == 0x0) {
            status = STATUS_INVALID_DEVICE_STATE;
            DoTraceLevelMessage(
                fxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
                "Driver cannot set IRP dispatch callback "
                "after WdfControlDeviceFinishInitializing "
                "is called on the WDFDEVICE %p, %!STATUS!",
                device, status);
            goto Done;
        }
    }
    else {
        //
        // This is either FDO or PDO. Make sure it's not started yet.
        //
        if (device->GetDevicePnpState() != WdfDevStatePnpInit) {
            status = STATUS_INVALID_DEVICE_STATE;
            DoTraceLevelMessage(
                fxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
                "Driver cannot set IRP dispatch callback "
                "after the WDFDEVICE %p is started, %!STATUS!",
                device, status);
            goto Done;
        }
    }

    //
    // Let I/O package do the rest.
    //
    status = device->m_PkgIo->ConfigureDynamicDispatching(MajorFunction,
                                                          cxDeviceInfo,
                                                          EvtDeviceWdmIrpDispatch,
                                                          DriverContext);
Done:
    return status;
}
示例#27
0
文件: fxpkgio.cpp 项目: AntejaVM/WDF
_Must_inspect_result_
NTSTATUS
FxPkgIo::CreateQueue(
    __in  PWDF_IO_QUEUE_CONFIG     Config,
    __in  PWDF_OBJECT_ATTRIBUTES   QueueAttributes,
    __in_opt FxDriver*             Caller,
    __deref_out FxIoQueue**        ppQueue
)
{
    PFX_DRIVER_GLOBALS pFxDriverGlobals;
    FxObject* pParent;
    FxIoQueue* pQueue;
    NTSTATUS status;
    FxDriver* pDriver;

    pParent = NULL;
    pQueue = NULL;
    pDriver = NULL;
    pFxDriverGlobals = GetDriverGlobals();

    if (QueueAttributes != NULL && QueueAttributes->ParentObject != NULL) {
        CfxDeviceBase* pSearchDevice;

        FxObjectHandleGetPtr(pFxDriverGlobals,
                             QueueAttributes->ParentObject,
                             FX_TYPE_OBJECT,
                             (PVOID*)&pParent);

        pSearchDevice = FxDeviceBase::_SearchForDevice(pParent, NULL);

        if (pSearchDevice == NULL) {
            status = STATUS_INVALID_DEVICE_REQUEST;

            DoTraceLevelMessage(
                pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO,
                "QueueAttributes->ParentObject 0x%p must have WDFDEVICE as an "
                "eventual ancestor, %!STATUS!",
                QueueAttributes->ParentObject, status);

            return status;
        }
        else if (pSearchDevice != m_DeviceBase) {
            status = STATUS_INVALID_DEVICE_REQUEST;

            DoTraceLevelMessage(
                pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO,
                "Attributes->ParentObject 0x%p ancestor is WDFDEVICE %p, but "
                "not the same WDFDEVICE 0x%p passed to WdfIoQueueCreate, "
                "%!STATUS!",
                QueueAttributes->ParentObject, pSearchDevice->GetHandle(),
                m_Device->GetHandle(), status);

            return status;
        }
    }
    else {
        //
        // By default, use the package as the parent
        //
        pParent = this;
    }

    //
    // v1.11 and up: get driver object if driver handle is specified.
    // Client driver can also specify a driver handle, the end result in this case is
    // a PkgIoContext that is NULL (see below), i.e., the same as if driver handle
    // was NULL.
    //
    if (Config->Size > sizeof(WDF_IO_QUEUE_CONFIG_V1_9) &&
            Config->Driver != NULL) {

        FxObjectHandleGetPtr(GetDriverGlobals(),
                             Config->Driver,
                             FX_TYPE_DRIVER,
                             (PVOID*)&pDriver);
    }

    status = FxIoQueue::_Create(pFxDriverGlobals,
                                QueueAttributes,
                                Config,
                                Caller,
                                this,
                                m_PowerStateOn,
                                &pQueue
                               );

    if (!NT_SUCCESS(status)) {
        ASSERT(pQueue == NULL);
        return status;
    }

    //
    // Class extension support: associate queue with a specific cx layer.
    //
    if (pDriver != NULL) {
        pQueue->SetCxDeviceInfo(m_Device->GetCxDeviceInfo(pDriver));
    }

    status = pQueue->Commit(QueueAttributes, NULL, pParent);
    if (!NT_SUCCESS(status)) {
        pQueue->DeleteFromFailedCreate();
        return status;
    }

    AddIoQueue(pQueue);
    *ppQueue = pQueue;

    return status;
}