Click here to Skip to main content
15,896,063 members
Articles / Programming Languages / C++

Writing a Sensor Driver for the Wiimote on Windows 7

Rate me:
Please Sign up or sign in to vote.
4.93/5 (61 votes)
16 Feb 2010CPOL30 min read 276.5K   16.7K   106  
How to write a Sensor driver that provides access to the 3-axis accelerometer on a Nintendo Wiimote on Windows 7
/*++

Module Name:

    Queue.cpp

Abstract:

    This module contains the implementation of the Sensor Skeleton Sample
    queue callback object.

--*/

#include "internal.h"
#include "Device.h"
#include "Queue.h"

#include "queue.tmh"

/////////////////////////////////////////////////////////////////////////
//
// CWiimoteQueue::CWiimoteQueue
//
// Object constructor function
//
// Initialize member variables
//
/////////////////////////////////////////////////////////////////////////
CWiimoteQueue::CWiimoteQueue() :
    m_pParentDevice(NULL)
{
}

/////////////////////////////////////////////////////////////////////////
//
// CWiimoteQueue::~CWiimoteQueue
//
// Object destructor function
//
//
/////////////////////////////////////////////////////////////////////////
CWiimoteQueue::~CWiimoteQueue()
{
    // Release the reference that was incremented in CreateInstance()
    SAFE_RELEASE(m_pParentDevice);   
}

/////////////////////////////////////////////////////////////////////////
//
// CWiimoteQueue::CreateInstance
//
// This function supports the COM factory creation system
//
// Parameters:
//      parentDevice    - A pointer to the CWSSDevice object
//      ppUkwn          - pointer to a pointer to the queue to be returned
//
// Return Values:
//      S_OK: The queue was created successfully
//
/////////////////////////////////////////////////////////////////////////
HRESULT CWiimoteQueue::CreateInstance(__in IWDFDevice*  pWdfDevice, CWiimoteDevice* pMyDevice)
{
    CComObject<CWiimoteQueue>* pMyQueue = NULL;

    if(NULL == pMyDevice)
    {
        return E_INVALIDARG;
    }

    HRESULT hr = CComObject<CWiimoteQueue>::CreateInstance(&pMyQueue);

    if(SUCCEEDED(hr))
    {
        // AddRef the object
        pMyQueue->AddRef();

        // Store the parent device object
        pMyQueue->m_pParentDevice = pMyDevice;

        // Increment the reference for the lifetime of the CWiimoteDevice object.
        pMyQueue->m_pParentDevice->AddRef();

        CComPtr<IUnknown> spIUnknown;
        hr = pMyQueue->QueryInterface(IID_IUnknown, (void**)&spIUnknown);

        if(SUCCEEDED(hr))
        {
            // Create the framework queue
            CComPtr<IWDFIoQueue> spDefaultQueue;
            hr = pWdfDevice->CreateIoQueue( spIUnknown,
                                            TRUE,                        // DefaultQueue
                                            WdfIoQueueDispatchParallel,  // Parallel queue handling 
                                            FALSE,                       // PowerManaged
                                            TRUE,                        // AllowZeroLengthRequests
                                            &spDefaultQueue 
                                            );
            if (FAILED(hr))
            {
                Trace( TRACE_LEVEL_ERROR, "%!FUNC!: Could not create default I/O queue, %!hresult!", hr);
            }
        }

    }

    return hr;
}
/////////////////////////////////////////////////////////////////////////
//
// CWiimoteQueue::OnDeviceIoControl
//
// This method is called when an IOCTL is sent to the device
//
// Parameters:
//      pQueue            - pointer to an IO queue
//      pRequest          - pointer to an IO request
//      ControlCode       - The IOCTL to process
//      InputBufferSizeInBytes - the size of the input buffer
//      OutputBufferSizeInBytes - the size of the output buffer
//
/////////////////////////////////////////////////////////////////////////
STDMETHODIMP_ (void) CWiimoteQueue::OnDeviceIoControl(
    __in IWDFIoQueue*     pQueue,
    __in IWDFIoRequest*   pRequest,
    __in ULONG            ControlCode,
         SIZE_T           InputBufferSizeInBytes,
         SIZE_T           OutputBufferSizeInBytes
    )
{
    UNREFERENCED_PARAMETER(pQueue);
    UNREFERENCED_PARAMETER(InputBufferSizeInBytes);
    UNREFERENCED_PARAMETER(OutputBufferSizeInBytes);
    
    DWORD dwWritten = 0;

    if( IS_WPD_IOCTL( ControlCode ) )
    {
        m_pParentDevice->ProcessIoControl(  pQueue,
                                            pRequest,
                                            ControlCode,
                                            InputBufferSizeInBytes,
                                            OutputBufferSizeInBytes,
                                            &dwWritten);
    }
    else
    {
        // Unsupported request
        pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0);
    }

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Microsoft
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions