Ejemplo n.º 1
0
void
CQueue::OnDeviceIoControl(
    __in IWDFIoQueue*    pQueue,
    __in IWDFIoRequest*  pRequest,
    __in ULONG           ControlCode,   
    __in SIZE_T         /*InputBufferSizeInBytes*/,
    __in SIZE_T         /*OutputBufferSizeInBytes*/        
    )
/*++

Routine Description:

    The framework calls this function when somone has called
    DeviceIoControl on the device.

Arguments:

Return Value:
    None

--*/
{
    HRESULT     hr = S_OK;
    IWDFDevice  *pDevice = NULL;

    Trace(TRACE_LEVEL_INFORMATION,"%!FUNC!");

    //
    // Retrieve the queue's parent device object
    //
    pQueue->GetDevice(&pDevice);
    
    WUDF_TEST_DRIVER_ASSERT(pDevice);
    
    switch (ControlCode)
    {
       case IOCTL_TOASTER_DONT_DISPLAY_IN_UI_DEVICE:
   
           //
           // This is just an example on how to hide your device in the 
           // device manager. Please remove your code when you adapt this 
           // sample for your hardware.
           //
             pDevice->SetPnpState(WdfPnpStateDontDisplayInUI, WdfTrue);
             pDevice->CommitPnpState();
             
             break;
   
       default:
            hr = E_FAIL; //invalid request

            Trace(TRACE_LEVEL_ERROR,"%!FUNC! Invalid IOCTL %!hresult!",hr);
    }
    pRequest->Complete(hr);
    
    return;
}
Ejemplo n.º 2
0
CMyQueue::~CMyQueue(
    VOID
    )
/*++

Routine Description:


    IUnknown implementation of Release

Arguments:


Return Value:

--*/
{
        WUDF_TEST_DRIVER_ASSERT(m_Device);

        m_Device->Release();
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
HRESULT
CMyDevice::Initialize(
    __in IWDFDriver           * FxDriver,
    __in IWDFDeviceInitialize * FxDeviceInit
    )
/*++
 
  Routine Description:

    This method initializes the device callback object and creates the
    partner device object.

    The method should perform any device-specific configuration that:
        *  could fail (these can't be done in the constructor)
        *  must be done before the partner object is created -or-
        *  can be done after the partner object is created and which aren't 
           influenced by any device-level parameters the parent (the driver
           in this case) might set.

  Arguments:

    FxDeviceInit - the settings for this device.

  Return Value:

    status.

--*/
{
    IWDFDevice *fxDevice = NULL;

    HRESULT hr = S_OK;

    
    //
    // TODO: If you're writing a filter driver then indicate that here. 
    //
    // FxDeviceInit->SetFilter();
    //

    //
    // Set no locking unless you need an automatic callbacks synchronization
    //

    FxDeviceInit->SetLockingConstraint(None);

    //
    // Only one driver in the stack can be the Power policy owner (PPO).
    //
    // NOTE: If we want UMDF to be the PPO we also ask WinUsb.sys 
    // to not set itself as the PPO by setting the
    // WinUsbPowerPolicyOwnershipDisabled key through 
    // an AddReg in the INF.
    //     
#if defined(_NOT_POWER_POLICY_OWNER_)
    FxDeviceInit->SetPowerPolicyOwnership(FALSE);        
#else
    FxDeviceInit->SetPowerPolicyOwnership(TRUE);        
#endif
    
    //
    // TODO: Any per-device initialization which must be done before 
    //       creating the partner object.
    //

    //
    // Create a new FX device object and assign the new callback object to 
    // handle any device level events that occur.
    //

    //
    // QueryIUnknown references the IUnknown interface that it returns
    // (which is the same as referencing the device).  We pass that to 
    // CreateDevice, which takes its own reference if everything works.
    //

    if (SUCCEEDED(hr)) 
    {
        IUnknown *unknown = this->QueryIUnknown();

        hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &fxDevice);

        unknown->Release();
    }

    //
    // If that succeeded then set our FxDevice member variable.
    //

    if (SUCCEEDED(hr)) 
    {
        //
        // Drop the reference we got from CreateDevice.  Since this object
        // is partnered with the framework object they have the same 
        // lifespan - there is no need for an additional reference.
        //
        
        fxDevice->Release();

        IWDFDevice2 *fxDevice2 = NULL;
        
        HRESULT hrQI = fxDevice->QueryInterface(__uuidof(IWDFDevice2), (void**) &fxDevice2);  
        
        WUDF_TEST_DRIVER_ASSERT(SUCCEEDED(hrQI) && fxDevice2);

        m_FxDevice = fxDevice2;
        
        //
        // Drop the reference we got from QueryInterface(). Since this object
        // is partnered with the framework object they have the same 
        // lifespan - there is no need for an additional reference.
        //
        
        fxDevice2->Release();        
    }

    return hr;
}
Ejemplo n.º 5
0
HRESULT
CMyDevice::CreateUsbIoTargets(
    )
/*++

Routine Description:

    This routine creates Usb device, interface and pipe objects

Arguments:

    None

Return Value:

    HRESULT
--*/
{
    HRESULT                 hr;
    UCHAR                   NumEndPoints = 0;
    IWDFUsbTargetFactory *  pIUsbTargetFactory = NULL;
    IWDFUsbTargetDevice *   pIUsbTargetDevice = NULL;
    IWDFUsbInterface *      pIUsbInterface = NULL;
    IWDFUsbTargetPipe *     pIUsbPipe = NULL;
    
    hr = m_FxDevice->QueryInterface(IID_PPV_ARGS(&pIUsbTargetFactory));

    if (FAILED(hr))
    {
        TraceEvents(TRACE_LEVEL_ERROR, 
                    TEST_TRACE_DEVICE, 
                    "%!FUNC! Cannot get usb target factory %!HRESULT!",
                    hr
                    );        
    }

    if (SUCCEEDED(hr)) 
    {
        hr = pIUsbTargetFactory->CreateUsbTargetDevice(
                                                  &pIUsbTargetDevice);
        if (FAILED(hr))
        {
            TraceEvents(TRACE_LEVEL_ERROR, 
                        TEST_TRACE_DEVICE, 
                        "%!FUNC! Unable to create USB Device I/O Target %!HRESULT!",
                        hr
                        );        
        }
        else
        {
            m_pIUsbTargetDevice = pIUsbTargetDevice;

            //
            // Release the creation reference as object tree will maintain a reference
            //
            
            pIUsbTargetDevice->Release();            
        }
    }

    if (SUCCEEDED(hr)) 
    {
        UCHAR NumInterfaces = pIUsbTargetDevice->GetNumInterfaces();

        WUDF_TEST_DRIVER_ASSERT(1 == NumInterfaces);
        
        hr = pIUsbTargetDevice->RetrieveUsbInterface(0, &pIUsbInterface);
        if (FAILED(hr))
        {
            TraceEvents(TRACE_LEVEL_ERROR, 
                        TEST_TRACE_DEVICE, 
                        "%!FUNC! Unable to retrieve USB interface from USB Device I/O Target %!HRESULT!",
                        hr
                        );        
        }
        else
        {
            m_pIUsbInterface = pIUsbInterface;

            pIUsbInterface->Release(); //release creation reference                        
        }
    }

    if (SUCCEEDED(hr)) 
    {
        NumEndPoints = pIUsbInterface->GetNumEndPoints();

        if (NumEndPoints != NUM_OSRUSB_ENDPOINTS) {
            hr = E_UNEXPECTED;
            TraceEvents(TRACE_LEVEL_ERROR, 
                        TEST_TRACE_DEVICE, 
                        "%!FUNC! Has %d endpoints, expected %d, returning %!HRESULT! ", 
                        NumEndPoints,
                        NUM_OSRUSB_ENDPOINTS,
                        hr
                        );
        }
    }

    if (SUCCEEDED(hr)) 
    {
        for (UCHAR PipeIndex = 0; PipeIndex < NumEndPoints; PipeIndex++)
        {
            hr = pIUsbInterface->RetrieveUsbPipeObject(PipeIndex, 
                                                  &pIUsbPipe);

            if (FAILED(hr))
            {
                TraceEvents(TRACE_LEVEL_ERROR, 
                            TEST_TRACE_DEVICE, 
                            "%!FUNC! Unable to retrieve USB Pipe for PipeIndex %d, %!HRESULT!",
                            PipeIndex,
                            hr
                            );        
            }
            else
            {
                if ( pIUsbPipe->IsInEndPoint() )
                {
                    if ( UsbdPipeTypeInterrupt == pIUsbPipe->GetType() )
                    {
                        m_pIUsbInterruptPipe = pIUsbPipe;

                        WUDF_TEST_DRIVER_ASSERT(m_pIoTargetInterruptPipeStateMgmt == NULL);

                        hr = m_pIUsbInterruptPipe->QueryInterface(__uuidof(
                                                   IWDFIoTargetStateManagement),
                                                   reinterpret_cast<void**>(&m_pIoTargetInterruptPipeStateMgmt)
                                                   );
                        if (FAILED(hr))
                        {
                            m_pIoTargetInterruptPipeStateMgmt = NULL;
                        }                        
                    }
                    else if ( UsbdPipeTypeBulk == pIUsbPipe->GetType() )
                    {
                        m_pIUsbInputPipe = pIUsbPipe;
                    }
                    else
                    {
                        pIUsbPipe->DeleteWdfObject();
                    }                      
                }
                else if ( pIUsbPipe->IsOutEndPoint() && (UsbdPipeTypeBulk == pIUsbPipe->GetType()) )
                {
                    m_pIUsbOutputPipe = pIUsbPipe;
                }
                else
                {
                    pIUsbPipe->DeleteWdfObject();
                }
    
                SAFE_RELEASE(pIUsbPipe); //release creation reference
            }
        }

        if (NULL == m_pIUsbInputPipe || NULL == m_pIUsbOutputPipe)
        {
            hr = E_UNEXPECTED;
            TraceEvents(TRACE_LEVEL_ERROR, 
                        TEST_TRACE_DEVICE, 
                        "%!FUNC! Input or output pipe not found, returning %!HRESULT!",
                        hr
                        );        
        }
    }

    SAFE_RELEASE(pIUsbTargetFactory);

    return hr;
}
Ejemplo n.º 6
0
VOID
STDMETHODCALLTYPE
CMyQueue::OnDeviceIoControl(
    _In_ IWDFIoQueue *pWdfQueue,
    _In_ IWDFIoRequest *pWdfRequest,
    _In_ ULONG ControlCode,
    _In_ SIZE_T InputBufferSizeInBytes,
    _In_ SIZE_T OutputBufferSizeInBytes
    )
/*++

Routine Description:


    DeviceIoControl dispatch routine

Arguments:

    pWdfQueue - Framework Queue instance
    pWdfRequest - Framework Request  instance
    ControlCode - IO Control Code
    InputBufferSizeInBytes - Length of input buffer
    OutputBufferSizeInBytes - Length of output buffer

    Always succeeds DeviceIoIoctl
Return Value:

    VOID

--*/
{
    UNREFERENCED_PARAMETER(OutputBufferSizeInBytes);
    UNREFERENCED_PARAMETER(InputBufferSizeInBytes);
    UNREFERENCED_PARAMETER(pWdfQueue);

    HRESULT hr = S_OK;
    SIZE_T reqCompletionInfo = 0;
    IWDFMemory *inputMemory = NULL;
    IWDFMemory *outputMemory = NULL;
    UINT i;

    WUDF_TEST_DRIVER_ASSERT(pWdfRequest);
    WUDF_TEST_DRIVER_ASSERT(m_Device);

    switch (ControlCode)
    {
        case IOCTL_SERIAL_SET_BAUD_RATE:
        {
            //
            // This is a driver for a virtual serial port. Since there is no
            // actual hardware, we just store the baud rate and don't do
            // anything with it.
            //
            SERIAL_BAUD_RATE baudRateBuffer = {0};

            pWdfRequest->GetInputMemory(&inputMemory);
            if (NULL == inputMemory)
            {
                hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
            }

            if (SUCCEEDED(hr))
            {
                hr = inputMemory->CopyToBuffer(0,
                                               (void*) &baudRateBuffer,
                                               sizeof(SERIAL_BAUD_RATE));
            }

            if (SUCCEEDED(hr))
            {
                m_Device->SetBaudRate(baudRateBuffer.BaudRate);
            }

            break;
        }
        case IOCTL_SERIAL_GET_BAUD_RATE:
        {
            SERIAL_BAUD_RATE baudRateBuffer = {0};

            baudRateBuffer.BaudRate = m_Device->GetBaudRate();

            pWdfRequest->GetOutputMemory(&outputMemory);
            if (NULL == outputMemory)
            {
                hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
            }

            if (SUCCEEDED(hr))
            {
                hr = outputMemory->CopyFromBuffer(0,
                                                  (void*) &baudRateBuffer,
                                                  sizeof(SERIAL_BAUD_RATE));
            }

            if (SUCCEEDED(hr))
            {
                reqCompletionInfo = sizeof(SERIAL_BAUD_RATE);
            }

            break;
        }
        case IOCTL_SERIAL_SET_MODEM_CONTROL:
        {
            //
            // This is a driver for a virtual serial port. Since there is no
            // actual hardware, we just store the modem control register
            // configuration and don't do anything with it.
            //
            ULONG *pModemControlRegister = NULL;

            pWdfRequest->GetInputMemory(&inputMemory);
            if (NULL == inputMemory)
            {
                hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
            }

            if (SUCCEEDED(hr))
            {
                pModemControlRegister = m_Device->GetModemControlRegisterPtr();
                WUDF_TEST_DRIVER_ASSERT(pModemControlRegister);

                hr = inputMemory->CopyToBuffer(0,
                                               (void*) pModemControlRegister,
                                               sizeof(ULONG));
            }

            break;
        }
        case IOCTL_SERIAL_GET_MODEM_CONTROL:
        {
            ULONG *pModemControlRegister = NULL;

            pWdfRequest->GetOutputMemory(&outputMemory);
            if (NULL == outputMemory)
            {
                hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
            }

            if (SUCCEEDED(hr))
            {
                pModemControlRegister = m_Device->GetModemControlRegisterPtr();
                WUDF_TEST_DRIVER_ASSERT(pModemControlRegister);

                hr = outputMemory->CopyFromBuffer(0,
                                                  (void*) pModemControlRegister,
                                                  sizeof(ULONG));
            }

            if (SUCCEEDED(hr))
            {
                reqCompletionInfo = sizeof(ULONG);
            }

            break;
        }
        case IOCTL_SERIAL_SET_FIFO_CONTROL:
        {
            //
            // This is a driver for a virtual serial port. Since there is no
            // actual hardware, we just store the FIFO control register
            // configuration and don't do anything with it.
            //
            ULONG *pFifoControlRegister = NULL;

            pWdfRequest->GetInputMemory(&inputMemory);
            if (NULL == inputMemory)
            {
                hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
            }

            if (SUCCEEDED(hr))
            {
                pFifoControlRegister = m_Device->GetFifoControlRegisterPtr();

                hr = inputMemory->CopyToBuffer(0,
                                               (void*) pFifoControlRegister,
                                               sizeof(ULONG));
            }

            break;
        }
        case IOCTL_SERIAL_GET_LINE_CONTROL:
        {
            ULONG *pLineControlRegister = NULL;
            SERIAL_LINE_CONTROL lineControl = {0};
            ULONG lineControlSnapshot;

            pLineControlRegister = m_Device->GetLineControlRegisterPtr();
            WUDF_TEST_DRIVER_ASSERT(pLineControlRegister);

            //
            // Take a snapshot of the line control register variable
            //
            lineControlSnapshot = *pLineControlRegister;

            //
            // Decode the word length
            //
            if ((lineControlSnapshot & SERIAL_DATA_MASK) == SERIAL_5_DATA)
            {
                lineControl.WordLength = 5;
            }
            else if ((lineControlSnapshot & SERIAL_DATA_MASK) == SERIAL_6_DATA)
            {
                lineControl.WordLength = 6;
            }
            else if ((lineControlSnapshot & SERIAL_DATA_MASK) == SERIAL_7_DATA)
            {
                lineControl.WordLength = 7;
            }
            else if ((lineControlSnapshot & SERIAL_DATA_MASK) == SERIAL_8_DATA)
            {
                lineControl.WordLength = 8;
            }

            //
            // Decode the parity
            //
            if ((lineControlSnapshot & SERIAL_PARITY_MASK) == SERIAL_NONE_PARITY)
            {
                lineControl.Parity = NO_PARITY;
            }
            else if ((lineControlSnapshot & SERIAL_PARITY_MASK) == SERIAL_ODD_PARITY)
            {
                lineControl.Parity = ODD_PARITY;
            }
            else if ((lineControlSnapshot & SERIAL_PARITY_MASK) == SERIAL_EVEN_PARITY)
            {
                lineControl.Parity = EVEN_PARITY;
            }
            else if ((lineControlSnapshot & SERIAL_PARITY_MASK) == SERIAL_MARK_PARITY)
            {
                lineControl.Parity = MARK_PARITY;
            }
            else if ((lineControlSnapshot & SERIAL_PARITY_MASK) == SERIAL_SPACE_PARITY)
            {
                lineControl.Parity = SPACE_PARITY;
            }

            //
            // Decode the length of the stop bit
            //
            if (lineControlSnapshot & SERIAL_2_STOP)
            {
                if (lineControl.WordLength == 5)
                {
                    lineControl.StopBits = STOP_BITS_1_5;
                }
                else
                {
                    lineControl.StopBits = STOP_BITS_2;
                }
            }
            else
            {
                lineControl.StopBits = STOP_BIT_1;
            }

            //
            // Copy the information that was decoded to the caller's buffer
            //
            pWdfRequest->GetOutputMemory(&outputMemory);
            if (NULL == outputMemory)
            {
                hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
            }

            if (SUCCEEDED(hr))
            {
                hr = outputMemory->CopyFromBuffer(0,
                                                  (void*) &lineControl,
                                                  sizeof(SERIAL_LINE_CONTROL));
            }

            if (SUCCEEDED(hr))
            {
                reqCompletionInfo = sizeof(SERIAL_LINE_CONTROL);
            }

            break;
        }
        case IOCTL_SERIAL_SET_LINE_CONTROL:
        {
            ULONG *pLineControlRegister = NULL;
            SERIAL_LINE_CONTROL lineControl = {0};
            UCHAR lineControlData = 0;
            UCHAR lineControlStop = 0;
            UCHAR lineControlParity = 0;
            ULONG lineControlSnapshot;
            ULONG lineControlNew;
            ULONG lineControlPrevious;

            pLineControlRegister = m_Device->GetLineControlRegisterPtr();
            WUDF_TEST_DRIVER_ASSERT(pLineControlRegister);

            //
            // This is a driver for a virtual serial port. Since there is no
            // actual hardware, we just store the line control register
            // configuration and don't do anything with it.
            //
            pWdfRequest->GetInputMemory(&inputMemory);
            if (NULL == inputMemory)
            {
                hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
            }

            if (SUCCEEDED(hr))
            {
                hr = inputMemory->CopyToBuffer(0,
                                               (void*) &lineControl,
                                               sizeof(SERIAL_LINE_CONTROL));
            }

            //
            // Bits 0 and 1 of the line control register
            //
            if (SUCCEEDED(hr))
            {
                switch (lineControl.WordLength)
                {
                    case 5:
                        lineControlData = SERIAL_5_DATA;
                        m_Device->SetValidDataMask(0x1f);
                        break;

                    case 6:
                        lineControlData = SERIAL_6_DATA;
                        m_Device->SetValidDataMask(0x3f);
                        break;

                    case 7:
                        lineControlData = SERIAL_7_DATA;
                        m_Device->SetValidDataMask(0x7f);
                        break;

                    case 8:
                        lineControlData = SERIAL_8_DATA;
                        m_Device->SetValidDataMask(0xff);
                        break;

                    default:
                        hr = E_INVALIDARG;
                }
            }

            //
            // Bit 2 of the line control register
            //
            if (SUCCEEDED(hr))
            {
                switch (lineControl.StopBits)
                {
                    case STOP_BIT_1:
                        lineControlStop = SERIAL_1_STOP;
                        break;

                    case STOP_BITS_1_5:
                        if (lineControlData != SERIAL_5_DATA)
                        {
                            hr = E_INVALIDARG;
                            break;
                        }
                        lineControlStop = SERIAL_1_5_STOP;
                        break;

                    case STOP_BITS_2:
                        if (lineControlData == SERIAL_5_DATA)
                        {
                            hr = E_INVALIDARG;
                            break;
                        }
                        lineControlStop = SERIAL_2_STOP;
                        break;

                    default:
                        hr = E_INVALIDARG;
                }
            }

            //
            // Bits 3, 4 and 5 of the line control register
            //
            if (SUCCEEDED(hr))
            {
                switch (lineControl.Parity)
                {
                    case NO_PARITY:
                        lineControlParity = SERIAL_NONE_PARITY;
                        break;

                    case EVEN_PARITY:
                        lineControlParity = SERIAL_EVEN_PARITY;
                        break;

                    case ODD_PARITY:
                        lineControlParity = SERIAL_ODD_PARITY;
                        break;

                    case SPACE_PARITY:
                        lineControlParity = SERIAL_SPACE_PARITY;
                        break;

                    case MARK_PARITY:
                        lineControlParity = SERIAL_MARK_PARITY;
                        break;

                    default:
                        hr = E_INVALIDARG;
                }
            }

            //
            // Update our line control register variable atomically
            //
            i=0;
            do
            {
                i++;
                if ((i & 0xf) == 0)
                {
                    //
                    // We've been spinning in a loop for a while trying to
                    // update the line control register variable atomically.
                    // Yield the CPU for other threads for a while.
                    //
                    SwitchToThread();
                }

                lineControlSnapshot = *pLineControlRegister;

                lineControlNew = (lineControlSnapshot & SERIAL_LCR_BREAK) |
                                    (lineControlData |
                                     lineControlParity |
                                     lineControlStop);

                lineControlPrevious = InterlockedCompareExchange((LONG *) pLineControlRegister,
                                                                 lineControlNew,
                                                                 lineControlSnapshot);

            } while (lineControlPrevious != lineControlSnapshot);

            break;
        }
        case IOCTL_SERIAL_GET_TIMEOUTS:
        {
            SERIAL_TIMEOUTS timeoutValues = {0};

            pWdfRequest->GetOutputMemory(&outputMemory);
            if (NULL == outputMemory)
            {
                hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
            }

            if (SUCCEEDED(hr))
            {
                m_Device->GetTimeouts(&timeoutValues);

                hr = outputMemory->CopyFromBuffer(0,
                                                  (void*) &timeoutValues,
                                                  sizeof(timeoutValues));
            }

            if (SUCCEEDED(hr))
            {
                reqCompletionInfo = sizeof(SERIAL_TIMEOUTS);
            }

            break;
        }
        case IOCTL_SERIAL_SET_TIMEOUTS:
        {
            SERIAL_TIMEOUTS timeoutValues = {0};

            pWdfRequest->GetInputMemory(&inputMemory);
            if (NULL == inputMemory)
            {
                hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
            }

            if (SUCCEEDED(hr))
            {
                hr = inputMemory->CopyToBuffer(0,
                                               (void*) &timeoutValues,
                                               sizeof(timeoutValues));
            }

            if (SUCCEEDED(hr))
            {
                if ((timeoutValues.ReadIntervalTimeout == MAXULONG) &&
                    (timeoutValues.ReadTotalTimeoutMultiplier == MAXULONG) &&
                    (timeoutValues.ReadTotalTimeoutConstant == MAXULONG))
                {
                    hr = E_INVALIDARG;
                }
            }

            if (SUCCEEDED(hr))
            {
                m_Device->SetTimeouts(timeoutValues);
            }

            break;
        }
        
        case IOCTL_SERIAL_SET_QUEUE_SIZE:
        case IOCTL_SERIAL_SET_DTR:
        case IOCTL_SERIAL_SET_WAIT_MASK:
        case IOCTL_SERIAL_SET_RTS:
        case IOCTL_SERIAL_CLR_RTS:
        case IOCTL_SERIAL_SET_XON:
        case IOCTL_SERIAL_SET_XOFF:
        case IOCTL_SERIAL_SET_CHARS:
        case IOCTL_SERIAL_GET_CHARS:
        case IOCTL_SERIAL_GET_HANDFLOW:
        case IOCTL_SERIAL_SET_HANDFLOW:
        case IOCTL_SERIAL_RESET_DEVICE: 
        {
            //
            // NOTE: The application expects STATUS_SUCCESS for these IOCTLs.
            //  so don't merge this with default.
            //
            break;
        }
        
        default:
        {
            hr = E_INVALIDARG;
        }
    }

    //
    // clean up
    //
    if (inputMemory)
    {
        inputMemory->Release();
    }

    if (outputMemory)
    {
        outputMemory->Release();
    }

    //
    // complete the request
    //
    pWdfRequest->CompleteWithInformation(hr, reqCompletionInfo);

    return;
}
Ejemplo n.º 7
0
HRESULT
CMyDevice::OnPrepareHardware(
	_In_ IWDFDevice * /* FxDevice */
	)
/*++

Routine Description:

	This routine is invoked to ready the driver
	to talk to hardware. It opens the handle to the 
	device and talks to it using the HID interface.

Arguments:

	FxDevice  : Pointer to the WDF device interface

Return Value:

	HRESULT 

--*/
{
	PWSTR instanceId = NULL;
	DWORD instanceIdCch = 0;
	HRESULT hr = S_OK;

	m_SwitchState.SwitchesAsUChar = 0;

	if (SUCCEEDED(hr))
	{	
		//
		// Find out the instance id buffer size.
		//
		hr = m_FxDevice->RetrieveDeviceInstanceId(NULL, &instanceIdCch);
	}

	if (SUCCEEDED(hr))
	{
		//
		// Allocate the buffer.
		//
		instanceId = new WCHAR[instanceIdCch];
		if (instanceId == NULL)
		{
			hr = E_OUTOFMEMORY;

			TraceEvents(TRACE_LEVEL_ERROR, 
						TEST_TRACE_DEVICE, 
						"%!FUNC! Out of memory"
						);
		}
	}

	if (SUCCEEDED(hr))
	{	
		//
		// Get the instance id.
		//
		hr = m_FxDevice->RetrieveDeviceInstanceId(instanceId, &instanceIdCch);
	}

	if (SUCCEEDED(hr))
	{
		TraceEvents(TRACE_LEVEL_INFORMATION, 
					TEST_TRACE_DEVICE, 
					"%!FUNC! Device instance id %S",
					instanceId
					);
	}
	else
	{
		TraceEvents(TRACE_LEVEL_ERROR, 
					TEST_TRACE_DEVICE, 
					"%!FUNC! Cannot get device instance id %!HRESULT!",
					hr
					);
	}

	if(SUCCEEDED(hr))
	{
		//
		// Create a file object.
		//
		hr = m_FxDevice->CreateWdfFile( NULL, &m_WdfFile );

		if (SUCCEEDED(hr) && nullptr != m_WdfFile)
		{
			//
			// Get our parent driver object.
			//
			m_FxDevice->GetDriver( &m_WdfDriver );

			//
			// Get the default I/O target.  This allows us to send IOCTLs
			// to the HID collection below us in the stack.
			//
			if (nullptr != m_WdfDriver)
			{
				m_FxDevice->GetDefaultIoTarget( &m_WdfIoTarget );
			}
			else
			{
				hr = E_UNEXPECTED;
				Trace(TRACE_LEVEL_ERROR, "Failed during GetDriver(), hr = %!HRESULT!", hr); 
			}

			if (nullptr == m_WdfIoTarget)
			{
				hr = E_UNEXPECTED;
				Trace(TRACE_LEVEL_ERROR, "Failed during GetDefaultIoTarget(), hr = %!HRESULT!", hr); 
			}
		}
		else
		{
			Trace(TRACE_LEVEL_ERROR, "m_WdfFile is NULL, hr = %!HRESULT!", hr); 
		}
	}
	else
	{
		Trace(TRACE_LEVEL_ERROR, "Failed during CreateWdfFile(), hr = %!HRESULT!", hr); 
	}
	
	if (SUCCEEDED(hr))
	{
		//
		// Get the HID capabilities and attributes.
		//
		hr = GetHidCapabilities();
	}

	if (SUCCEEDED(hr))
	{
		//
		// Queue up a pending read for input reports.
		//
		WUDF_TEST_DRIVER_ASSERT(m_Caps.InputReportByteLength == sizeof (m_SwitchStateReport));
		IWDFIoRequest *pWdfRequest;
		//
		// Create child request for the default I/O target
		//
		hr = m_FxDevice->CreateRequest(NULL, m_WdfIoTarget, &pWdfRequest);
		if (SUCCEEDED(hr))
		{
			hr = SendReadRequest(pWdfRequest);
			pWdfRequest->Release();
		}
		else
		{
			Trace(TRACE_LEVEL_ERROR, "Failed to create a request, hr = %!HRESULT!", hr); 
		}
	}

	if (SUCCEEDED(hr))
	{
		//
		// Set the seven segement display and bar graph to indicate that we're done with 
		// prepare hardware.
		//
		hr = IndicateDeviceReady();
	}

	if (FAILED(hr))
	{
		TraceEvents(TRACE_LEVEL_ERROR, 
					TEST_TRACE_DEVICE, 
					"%!FUNC! failed %!HRESULT!",
					hr
					);
	}

	delete[] instanceId;

	return hr;
}
Ejemplo n.º 8
0
HRESULT
CMyDevice::Configure(
	VOID
	)
/*++
 
  Routine Description:

	This method is called after the device callback object has been initialized 
	and returned to the driver.  It would setup the device's queues and their 
	corresponding callback objects.

  Arguments:

	FxDevice - the framework device object for which we're handling events.

  Return Value:

	status

--*/
{   
	HRESULT hr = S_OK;

	hr = CMyReadWriteQueue::CreateInstance(this, &m_ReadWriteQueue);

	if (FAILED(hr))
	{
		return hr;
	}

	//
	// We use default queue for read/write
	//
	
	hr = m_ReadWriteQueue->Configure();

	m_ReadWriteQueue->Release();

	//
	// Create the control queue and configure forwarding for IOCTL requests.
	//

	if (SUCCEEDED(hr)) 
	{
		hr = CMyControlQueue::CreateInstance(this, &m_ControlQueue);

		if (SUCCEEDED(hr)) 
		{
			hr = m_ControlQueue->Configure();
			if (SUCCEEDED(hr)) 
			{
				m_FxDevice->ConfigureRequestDispatching(
								m_ControlQueue->GetFxQueue(),
								WdfRequestDeviceIoControl,
								true
								);
			}
			m_ControlQueue->Release();		 
		}
	}

	//
	// Create a manual I/O queue to hold requests for notification when
	// the switch state changes.
	//

	hr = m_FxDevice->CreateIoQueue(NULL,
								   FALSE,
								   WdfIoQueueDispatchManual,
								   FALSE,
								   FALSE,
								   &m_SwitchChangeQueue);
	

	//
	// Release creation reference as object tree will keep a reference
	//
	
	m_SwitchChangeQueue->Release();

	if (SUCCEEDED(hr)) 
	{
		// TODO:  Expose your device interface GUID here.
		hr = m_FxDevice->CreateDeviceInterface(&GUID_DEVINTERFACE_OSRUSBFX2,
											   NULL);
	}

	//
	// Mark the interface as restricted to allow access to applications bound
	// using device metadata.
	//
	if (SUCCEEDED(hr))
	{
		WDF_PROPERTY_STORE_ROOT RootSpecifier;
		IWDFUnifiedPropertyStoreFactory * pUnifiedPropertyStoreFactory = NULL;
		IWDFUnifiedPropertyStore * pUnifiedPropertyStore = NULL;
		DEVPROP_BOOLEAN isRestricted = DEVPROP_TRUE;

		hr = m_FxDevice->QueryInterface(IID_PPV_ARGS(&pUnifiedPropertyStoreFactory));

		WUDF_TEST_DRIVER_ASSERT(SUCCEEDED(hr));

		RootSpecifier.LengthCb = sizeof(RootSpecifier);
		RootSpecifier.RootClass = WdfPropertyStoreRootClassDeviceInterfaceKey;
		// TODO:  Use your device interface GUID here.
		RootSpecifier.Qualifier.DeviceInterfaceKey.InterfaceGUID = &GUID_DEVINTERFACE_OSRUSBFX2;
		RootSpecifier.Qualifier.DeviceInterfaceKey.ReferenceString = NULL;

		hr = pUnifiedPropertyStoreFactory->RetrieveUnifiedDevicePropertyStore(&RootSpecifier,
																					 &pUnifiedPropertyStore);

		if (SUCCEEDED(hr))
		{
			hr = pUnifiedPropertyStore->SetPropertyData(&DEVPKEY_DeviceInterface_Restricted,
															   0, // Lcid
															   0, // Flags
															   DEVPROP_TYPE_BOOLEAN,
															   sizeof(isRestricted),
															   &isRestricted);
		}

		if (FAILED(hr))
		{
			TraceEvents(TRACE_LEVEL_ERROR, 
						TEST_TRACE_DEVICE, 
						"%!FUNC! Could not set restricted property %!HRESULT!",
						hr
						);
		}

		SAFE_RELEASE(pUnifiedPropertyStoreFactory);
		SAFE_RELEASE(pUnifiedPropertyStore);
	}

	return hr;
}