Sample Code

Windows Driver Samples/ Sample UMDF Filter above UMDF Function Driver for OSR USB-FX2 (UMDF Version 1)/ C++/ umdf_driver/ ReadWriteQueue.cpp/

/*++

Copyright (c) Microsoft Corporation, All Rights Reserved

Module Name:

    queue.cpp

Abstract:

    This file implements the I/O queue interface and performs
    the read/write/ioctl operations.

Environment:

    Windows User-Mode Driver Framework (WUDF)

--*/

#include "internal.h"
#include "ReadWriteQueue.tmh"

VOID
CMyReadWriteQueue::OnCompletion(
    _In_ IWDFIoRequest*                 pWdfRequest,
    _In_ IWDFIoTarget*                  pIoTarget,
    _In_ IWDFRequestCompletionParams*   pParams,
    _In_ PVOID                          pContext
    )
{
    UNREFERENCED_PARAMETER(pIoTarget);
    UNREFERENCED_PARAMETER(pContext);

    pWdfRequest->CompleteWithInformation(
        pParams->GetCompletionStatus(),
        pParams->GetInformation()
        );
}

void
CMyReadWriteQueue::ForwardFormattedRequest(
    _In_ IWDFIoRequest*                         pRequest,
    _In_ IWDFIoTarget*                          pIoTarget
    )
{
    //
    //First set the completion callback
    //

    IRequestCallbackRequestCompletion * pCompletionCallback = NULL;
    HRESULT hrQI = this->QueryInterface(IID_PPV_ARGS(&pCompletionCallback));
    WUDF_TEST_DRIVER_ASSERT(SUCCEEDED(hrQI) && (NULL != pCompletionCallback));

    pRequest->SetCompletionCallback(
        pCompletionCallback,
        NULL
        );

    pCompletionCallback->Release();
    pCompletionCallback = NULL;

    //
    //Send down the request
    //

    HRESULT hrSend = S_OK;
    hrSend = pRequest->Send(pIoTarget,
                            0,  //flags
                            0); //timeout

    if (FAILED(hrSend))
    {
        pRequest->CompleteWithInformation(hrSend, 0);
    }

    return;
}


CMyReadWriteQueue::CMyReadWriteQueue(
    _In_ PCMyDevice Device
    ) :
    CMyQueue(Device)
{
}

//
// Queue destructor.
// Free up the buffer, wait for thread to terminate and
//

CMyReadWriteQueue::~CMyReadWriteQueue(
    VOID
    )
/*++

Routine Description:


    IUnknown implementation of Release

Aruments:


Return Value:

    ULONG (reference count after Release)

--*/
{
    TraceEvents(TRACE_LEVEL_INFORMATION,
                TEST_TRACE_QUEUE,
                "%!FUNC! Entry"
                );

}


HRESULT
STDMETHODCALLTYPE
CMyReadWriteQueue::QueryInterface(
    _In_ REFIID InterfaceId,
    _Outptr_ PVOID *Object
    )
/*++

Routine Description:


    Query Interface

Aruments:

    Follows COM specifications

Return Value:

    HRESULT indicatin success or failure

--*/
{
    HRESULT hr;


    if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackWrite)))
    {
        hr = S_OK;
        *Object = QueryIQueueCallbackWrite();
    }
    else if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackRead)))
    {
        hr = S_OK;
        *Object = QueryIQueueCallbackRead();
    }
    else if (IsEqualIID(InterfaceId, __uuidof(IRequestCallbackRequestCompletion)))
    {
        hr = S_OK;
        *Object = QueryIRequestCallbackRequestCompletion();
    }
    else if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackIoStop)))
    {
        hr = S_OK;
        *Object = QueryIQueueCallbackIoStop();
    }
    else
    {
        hr = CMyQueue::QueryInterface(InterfaceId, Object);
    }

    return hr;
}

//
// Initialize
//

HRESULT
CMyReadWriteQueue::CreateInstance(
    _In_ PCMyDevice Device,
    _Out_ PCMyReadWriteQueue *Queue
    )
/*++

Routine Description:


    CreateInstance creates an instance of the queue object.

Aruments:

    ppUkwn - OUT parameter is an IUnknown interface to the queue object

Return Value:

    HRESULT indicatin success or failure

--*/
{
    PCMyReadWriteQueue queue;
    HRESULT hr = S_OK;

    queue = new CMyReadWriteQueue(Device);

    if (NULL == queue)
    {
        hr = E_OUTOFMEMORY;
    }

    //
    // Call the queue callback object to initialize itself.  This will create
    // its partner queue framework object.
    //

    if (SUCCEEDED(hr))
    {
        hr = queue->Initialize();
    }

    if (SUCCEEDED(hr))
    {
        *Queue = queue;
    }
    else
    {
        SAFE_RELEASE(queue);
    }

    return hr;
}

HRESULT
CMyReadWriteQueue::Initialize(
    )
{
    HRESULT hr;

    //
    // First initialize the base class.  This will create the partner FxIoQueue
    // object and setup automatic forwarding of I/O controls.
    //

    hr = __super::Initialize(WdfIoQueueDispatchParallel,
                             true,
                             true);

    //
    // return the status.
    //

    return hr;
}

STDMETHODIMP_ (void)
CMyReadWriteQueue::OnWrite(
    _In_ IWDFIoQueue *pWdfQueue,
    _In_ IWDFIoRequest *pWdfRequest,
    _In_ SIZE_T BytesToWrite
     )
/*++

Routine Description:


    Write dispatch routine
    IQueueCallbackWrite

Aruments:

    pWdfQueue - Framework Queue instance
    pWdfRequest - Framework Request  instance
    BytesToWrite - Lenth of bytes in the write buffer

    Allocate and copy data to local buffer
Return Value:

    VOID

--*/
{
    UNREFERENCED_PARAMETER(pWdfQueue);

    TraceEvents(TRACE_LEVEL_INFORMATION,
                TEST_TRACE_QUEUE,
                "%!FUNC!: Queue %p Request %p BytesToTransfer %d\n",
                this,
                pWdfRequest,
                (ULONG)(ULONG_PTR)BytesToWrite
                );

    HRESULT hr = S_OK;
    IWDFMemory * pInputMemory = NULL;
    IWDFUsbTargetPipe * pOutputPipe = m_Device->GetOutputPipe();

    pWdfRequest->GetInputMemory(&pInputMemory);

    hr = pOutputPipe->FormatRequestForWrite(
                                pWdfRequest,
                                NULL, //pFile
                                pInputMemory,
                                NULL, //Memory offset
                                NULL  //DeviceOffset
                                );

    if (FAILED(hr))
    {
        pWdfRequest->Complete(hr);
    }
    else
    {
        ForwardFormattedRequest(pWdfRequest, pOutputPipe);
    }

    SAFE_RELEASE(pInputMemory);

    return;
}

STDMETHODIMP_ (void)
CMyReadWriteQueue::OnRead(
    _In_ IWDFIoQueue *pWdfQueue,
    _In_ IWDFIoRequest *pWdfRequest,
    _In_ SIZE_T BytesToRead
    )
/*++

Routine Description:


    Read dispatch routine
    IQueueCallbackRead

Aruments:

    pWdfQueue - Framework Queue instance
    pWdfRequest - Framework Request  instance
    BytesToRead - Lenth of bytes in the read buffer

    Copy available data into the read buffer
Return Value:

    VOID

--*/
{
    UNREFERENCED_PARAMETER(pWdfQueue);

    TraceEvents(TRACE_LEVEL_INFORMATION,
                TEST_TRACE_QUEUE,
                "%!FUNC!: Queue %p Request %p BytesToTransfer %d\n",
                this,
                pWdfRequest,
                (ULONG)(ULONG_PTR)BytesToRead
                );

    HRESULT hr = S_OK;
    IWDFMemory * pOutputMemory = NULL;

    pWdfRequest->GetOutputMemory(&pOutputMemory);

    hr = m_Device->GetInputPipe()->FormatRequestForRead(
                                pWdfRequest,
                                NULL, //pFile
                                pOutputMemory,
                                NULL, //Memory offset
                                NULL  //DeviceOffset
                                );

    if (FAILED(hr))
    {
        pWdfRequest->Complete(hr);
    }
    else
    {
        ForwardFormattedRequest(pWdfRequest, m_Device->GetInputPipe());
    }

    SAFE_RELEASE(pOutputMemory);

    return;
}

STDMETHODIMP_ (void)
CMyReadWriteQueue::OnIoStop(
    _In_ IWDFIoQueue *   pWdfQueue,
    _In_ IWDFIoRequest * pWdfRequest,
    _In_ ULONG           ActionFlags
    )
{   
    UNREFERENCED_PARAMETER(pWdfQueue);


    //
    // The driver owns the request and no locking constraint is safe for 
    // the queue callbacks
    //        
    if (ActionFlags == WdfRequestStopActionSuspend )
    {
        IWDFIoRequest2 * request2 = NULL;
        HRESULT                 hr;

        hr = pWdfRequest->QueryInterface(IID_PPV_ARGS(&request2));
        if (FAILED(hr))
        {
            TraceEvents(TRACE_LEVEL_INFORMATION,
                        TEST_TRACE_QUEUE,
                        "%!FUNC!: Failed to QI for IWDFIoRequest2: %!hresult!", 
                        hr);
            return;
        }

        request2->StopAcknowledge(FALSE); //don't requeue
        SAFE_RELEASE(request2);
    }
    else if(ActionFlags == WdfRequestStopActionPurge)
    {
        //
        // Cancel the sent request since we are asked to purge the request
        //

        pWdfRequest->CancelSentRequest();
    }

    return;
}

Our Services

  • What our customers say about us?

© 2011-2024 All Rights Reserved. Joya Systems. 4425 South Mopac Building II Suite 101 Austin, TX 78735 Tel: 800-DEV-KERNEL

Privacy Policy. Terms of use. Valid XHTML & CSS