ISoftUSBEndpointEvents::OnDeviceRequest Method

The OnDeviceRequest event enables the device simulator to respond directly to a request. This event is fired for control endpoints when a device request is received from the host.

Syntax

HRESULT OnDeviceRequest(
  [in]   USBSETUPREQUEST *pSetupRequest,
  [out]  ULONG *RequestHandle,
  [in]   BYTE *pbRequestData,
  [in]   ULONG cbRequestData,
  [out]  BYTE **ppbResponseData,
  [out]  ULONG *pcbResponseData,
  [out]  BYTE *pbSetupStatus
);

Parameters

  • pSetupRequest [in]
    A pointer to the setup request from the host controller that needs to be handled.

  • RequestHandle [out]
    A pointer to the setup request data that the device is handling.

  • pbRequestData [in]
    A pointer to the data that is associated with the setup request.

  • cbRequestData [in]
    The size of the setup request data buffer.

  • ppbResponseData [out]
    Caller-allocated space to hold any response data to the setup request.

  • pcbResponseData [out]
    The size of the response data buffer that **ppbResponseData specifies.

  • pbSetupStatus [out]
    The status that this request should send to the host.

Return Value

OnDeviceRequest returns an HRESULT value.

Remarks

The OnDeviceRequest event is fired from an endpoint when it receives a SETUP_PID request.

The OnDeviceRequestComplete event is fired to complete the request.

The following C++ code example shows how to handle a device setup request from the host controller.

STDMETHODIMP CSoftUSBEndpointEvent::OnDeviceRequest(__in USBSETUPREQUEST *pSetupRequest,
                                __out ULONG_PTR  *RequestHandle,
                                __in_bcount_opt(cbHostData) BYTE *pbHostData,
                                __in ULONG cbHostData,
                                __deref_out_bcount(*pcbResponseData) BYTE **ppbResponseData,
                                __out ULONG *pcbResponseData,
                                __out BYTE  *pbSetupStatus)
{
    HRESULT hr = E_NOINTERFACE;
    ULONG  cbData = 0;
    USBDEVICEDESC *pbData = NULL;

    // Validate the parameters
    if ( NULL == ppbResponseData || NULL == pcbResponseData ||
          NULL == RequestHandle      || NULL == pbSetupStatus)
    {
            hr = E_POINTER;
            goto Exit;
    }

    // Initialize the variables
    *RequestHandle = 0;
    *ppbResponseData = NULL;
    *pcbResponseData = 0;
    *pbSetupStatus = USB_STALL;


    if (GET_DESCRIPTOR == pSetupRequest->bRequest)
    {

        // The request is handled
        // Allocate space to hold the return data
        cbData = sizeof(USBDEVICEDESC);
        pbData = (USBDEVICEDESC*)CoTaskMemAlloc(cbData);
        if (NULL ==pbData)
        {
               hr = E_OUTOFMEMORY;
               goto Exit;
         }

        // Clear the allocated memory
        ::ZeroMemory(pbData, cbData);

        // Assign values to the device descriptor
        pbData->bLength = (BYTE)cbData;
        pbData->bDescriptorType = DEVICE_DESCRIPTOR;
        pbData->bDeviceClass = 123;
        pbData->bDeviceSubClass = 5;
        pbData->bManufacturer = 1;
        pbData->bMaxPacket0 = 8;
        pbData->sDeviceNumber = 255;
        pbData->sVendor = 512;

        // Assign the outgoing data values
        *ppbResponseData = (BYTE*)pbData;
        pbData = NULL;
        *pcbResponseData = (ULONG)cbData;
        m_ulDescriptorHandle = 1;
        *RequestHandle = m_ulDescriptorHandle;
        *pbSetupStatus = USB_ACK;
        hr = S_OK;
 
    }
    else if (DIR_HOST_TO_DEVICE == pSetupRequest->bmRequestType.Bits.Direction)
    {
        // This transfer is an OUT transfer with data
        if (NULL == pbHostData)
        {
            // The host failed to send data
            *pbSetupStatus = USB_STALL;
            hr = E_FAIL;
            goto Exit;
        }
 
        // The host controller is expected to send 28 bytes of data
        BYTE bStartData = pbHostData[0];
        //Check the incoming data
        for (int i = 0; i < 28; i++)
        {
             if (pbHostData[i] != (bStartData + i))
            {
                   *pbSetupStatus = USB_STALL;
                    hr = E_FAIL;
                    goto Exit;
             }
       }

       // Set the returning data correctly
       // No data is sent with this request as it is host to device
       *ppbResponseData = NULL;
       *pcbResponseData = 0;
        m_ulDescriptorHandle = 2;
       *RequestHandle = m_ulDescriptorHandle;
       *pbSetupStatus = USB_ACK;
        hr = S_OK;
    }

Exit:
    if (FAILED(hr) && NULL != pbData)
    {
        CoTaskMemFree(pbData);
    }
    return hr;
}    

Requirements

Header

SoftUSBif.h

See Also

ISoftUSBEndpointEvents

ISoftUSBEndpointEvents::OnDeviceRequestComplete

 

 

Send comments about this topic to Microsoft

Build date: 9/21/2010