Beispiel #1
0
/******************************************************************************
 * This method gets the WpdBaseDriver associated with the UMDF device object.
 * The caller should Release *ppWpdBaseDriver when it is done.
 *
 * When this device was created, we assigned the WpdBaseDriver as the context.
 * So, in order to retrieve the correct WpdBaseDriver for this device, we simply
 * get the device context.
 *****************************************************************************/
HRESULT CQueue::GetWpdBaseDriver(
    IWDFDevice*     pDevice,
    WpdBaseDriver** ppWpdBaseDriver)
{
    HRESULT         hr          = S_OK;
    WpdBaseDriver*  pContext    = NULL;

    if((pDevice == NULL) || (ppWpdBaseDriver == NULL))
    {
        hr = E_POINTER;
        CHECK_HR(hr, "Cannot have NULL parameter for pDevice or ppWpdBaseDriver");
    }

    if(hr == S_OK)
    {
        hr = pDevice->RetrieveContext((void**)&pContext);
        if(hr == S_OK)
        {
            if(pContext != NULL)
            {
                pContext->AddRef();
                *ppWpdBaseDriver = pContext;
            }
            else
            {
                hr = E_UNEXPECTED;
                CHECK_HR(hr, "Device context is NULL");
            }
        }
    }

    return hr;
}
/******************************************************************************
 * This method gets the WpdBaseDriver associated with the UMDF device object.
 * The caller should Release *ppWpdBaseDriver when it is done.
 *
 * When this device was created, we assigned the WpdBaseDriver as the context.
 * So, in order to retrieve the correct WpdBaseDriver for this device, we simply
 * get the device context.
 *****************************************************************************/
HRESULT GetWpdBaseDriver(
    _In_                          IWDFDevice*     pDevice,
    _Outptr_result_nullonfailure_ WpdBaseDriver** ppWpdBaseDriver)
{
    HRESULT         hr          = S_OK;
    WpdBaseDriver*  pContext    = NULL;

    if((pDevice == NULL) || (ppWpdBaseDriver == NULL))
    {
        hr = E_POINTER;
        CHECK_HR(hr, "Cannot have NULL parameter for pDevice or ppWpdBaseDriver");
    }

    *ppWpdBaseDriver = NULL;

    if(SUCCEEDED(hr))
    {
        hr = pDevice->RetrieveContext((void**)&pContext);
        if(SUCCEEDED(hr))
        {
            if(pContext != NULL)
            {
                pContext->AddRef();
                *ppWpdBaseDriver = pContext;
            }
            else
            {
                hr = E_UNEXPECTED;
                CHECK_HR(hr, "Device context is NULL");
            }
        }
    }

    return hr;
}
HRESULT
CDriver::OnDeviceAdd(
    _In_ IWDFDriver* pDriver,
    _In_ IWDFDeviceInitialize* pDeviceInit
    )
/*++

Routine Description:

    The framework calls this function when a device is being added to
    the driver stack.

Arguments:

    IWDFDriver           - Framework interface.  The driver uses this
                           interface to create device objects.
    IWDFDeviceInitialize - Framework interface.  The driver uses this
                           interface to set device parameters before
                           creating the device obeject.

Return Value:

   HRESULT S_OK - Device added successfully

--*/
{
    HRESULT hr = S_OK;
    CComPtr<IUnknown> pDeviceCallback;

    if (hr == S_OK)
    {
        WpdBaseDriver *pWpdBaseDriver = NULL;

        //
        // Create the WPD driver object that handles all WPD messages for this device
        //
        pWpdBaseDriver = new WpdBaseDriver();
        if(pWpdBaseDriver == NULL)
        {
            hr = E_OUTOFMEMORY;
        }

        if(SUCCEEDED(hr))
        {
            //
            // Create device callback object
            //
            hr = CDevice::CreateInstance(pDeviceInit, pWpdBaseDriver, &pDeviceCallback);
        }

        //
        // This driver has no special power management requirements and so
        // we set power policy ownership to UMDF to indicate that UMDF should
        // handle powermanagement for us.
        //
        pDeviceInit->SetPowerPolicyOwnership(FALSE);

        //
        // Create WDFDevice.
        //
        CComPtr<IWDFDevice> pIWDFDevice;
        if(SUCCEEDED(hr))
        {
            hr = pDriver->CreateDevice(
                    pDeviceInit,
                    pDeviceCallback,
                    &pIWDFDevice);
        }

        //
        // Assign pWpdBaseDriver to the device object.  Each UMDF device requires its own instance of
        // a WpdBaseDriver to handle WPD messages.
        //
        if(SUCCEEDED(hr))
        {
            hr = pIWDFDevice->AssignContext(this, (void*)pWpdBaseDriver);
            if(SUCCEEDED(hr))
            {
                //  AddRef the WpdBaseDriver object since it is not stored with the
                //  device context.
                pWpdBaseDriver->AddRef();
            }
        }

        //
        // Create queue callback object
        //
        CComPtr<IUnknown> pIUnknown;
        if(S_OK == hr)
        {
            hr = CQueue::CreateInstance(&pIUnknown);
        }

        //
        // Configure the default queue.
        //
        if(S_OK == hr)
        {
            CComPtr<IWDFIoQueue> pDefaultQueue;
            hr = pIWDFDevice->CreateIoQueue(
                              pIUnknown,
                              TRUE,                         // bDefaultQueue
                              WdfIoQueueDispatchSequential,
                              TRUE,                         // bPowerManaged
                              FALSE,                        // bAllowZeroLengthRequests
                              &pDefaultQueue);
        }

        pDeviceCallback = NULL;
        pIWDFDevice = NULL;

        //
        // It is fine to release the interface on the callback object.
        // The framework has its own refcount on this object and will
        // provide an interface when calling into the driver.
        //
        pIUnknown = NULL;

        // Release the WpdBaseDriver object.  If it was successfully added to the device context,
        // it was already addref'd above. Releasing it here ensures it will be destroyed if
        // an error occured and it could not be added to the device context.
        SAFE_RELEASE(pWpdBaseDriver);
    }

    return hr;
}