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::OnDeviceRequestComplete
Send comments about this topic to Microsoft
Build date: 9/21/2010