The strange thing is, that my DeviceIoControl request from the application to the driver allways works (the callback will always called). Not so the ReadFile and WriteFile requests. Maybe I was mistaken that its not WinUSB what I call - but anyway, when using DeviceIoControl from my application, OnDeviceIoControl is called, the request will be forwarded and OnCompletion appears.
The difference between the UMDF USB FX2 sample is, that I?m using just one queue in contrary to using a second queue for DeviceIoControl.
HRESULT CMyDriver::OnDeviceAdd(
IWDFDriver* pWdfDriver,
IWDFDeviceInitialize* pWdfDeviceInit)
{
HRESULT hr;
PCMyDevice pMyDevice;
// Allocate a new instance of the device class.
pMyDevice = new CMyDevice();
if (NULL == pMyDevice)
return E_OUTOFMEMORY;
// Initialize the instance.
hr = pMyDevice->Initialize(pWdfDriver, pWdfDeviceInit);
if (SUCCEEDED(hr))
{
//Configure the device and release the reference
hr = pMyDevice->Configure();
pMyDevice->Release();
}
return hr;
}
HRESULT CMyDevice::Configure(VOID)
{
PCMyQueue pMyQueue;
HRESULT hr;
//Create new queue class
pMyQueue = new CMyQueue(this);
if (pMyQueue == NULL)
return E_OUTOFMEMORY;
//Initialize queue
hr = pMyQueue->Initialize(m_pWdfDevice);
if (SUCCEEDED(hr))
{
hr = pMyQueue->Configure();
pMyQueue->Release();
}
//Create device interface
if (SUCCEEDED(hr))
hr = m_pWdfDevice->CreateDeviceInterface(&GUID_DEVINTERFACE, NULL);
//Activate device interface
if (SUCCEEDED(hr))
hr = m_pWdfDevice->AssignDeviceInterfaceState(&GUID_DEVINTERFACE, NULL, TRUE);
return hr;
}
HRESULT CMyQueue::Initialize(IWDFDevice* pWdfDevice)
{
IUnknown* pUnknown;
IWDFIoQueue* pWdfQueue;
HRESULT hr;
//First initialize the base class. This will create the IoQueue
//object and setup automatic forwarding of I/O controls.
AddRef();
pUnknown = static_cast((CUnknown*)this);
hr = pWdfDevice->CreateIoQueue(
pUnknown,
TRUE,
WdfIoQueueDispatchParallel,
TRUE,
FALSE,
&pWdfQueue);
pUnknown->Release();
// If that succeeded then set our member variable.
if (SUCCEEDED(hr))
{
//Save queue element
m_pWdfQueue = pWdfQueue;
//Release interface
pWdfQueue->Release();
}
return hr;
}
VOID STDMETHODCALLTYPE CMyQueue::OnDeviceIoControl(
IWDFIoQueue* pWdfQueue,
IWDFIoRequest* pWdfRequest,
ULONG ControlCode,
SIZE_T InputBufferSize,
SIZE_T OutputBufferSize)
{
//Check the control code
switch (ControlCode)
{
case IOCTL_READ_PIPE :
//Read the pipe
OnRead(pWdfQueue, pWdfRequest, 8);
return;
case IOCTL_WRITE_PIPE :
//Write the pipe
OnWrite(pWdfQueue, pWdfRequest, 8);
return;
}
//Complete request
pWdfRequest->CompleteWithInformation(S_OK, 0);
return;
}
VOID STDMETHODCALLTYPE CMyQueue::OnRead(
IWDFIoQueue* pWdfQueue,
IWDFIoRequest* pWdfRequest,
SIZE_T BytesToRead)
{
IWDFMemory* pWdfMemory;
HRESULT hr;
//Get memory object
pWdfRequest->GetOutputMemory(&pWdfMemory);
//The FormatRequestForRead method formats an
//I/O request object for a read operation
hr = m_pMyDevice->m_pWdfUsbReadPipe->FormatRequestForRead(
pWdfRequest,
NULL, //pFile
pWdfMemory,
NULL, //Memory offset
NULL); //DeviceOffset
if (FAILED(hr)) { pWdfRequest->Complete(hr); }
else { ForwardRequest(pWdfRequest, m_pMyDevice->m_pWdfUsbReadPipe); }
//Release Interface
pWdfMemory->Release();
}
VOID STDMETHODCALLTYPE CMyQueue::OnWrite(
IWDFIoQueue* pWdfQueue,
IWDFIoRequest* pWdfRequest,
SIZE_T BytesToWrite)
{
IWDFMemory* pWdfMemory;
HRESULT hr;
//Get memory objects
pWdfRequest->GetInputMemory(&pWdfMemory);
//The FormatRequestForRead method formats an
//I/O request object for a read operation
hr = m_pMyDevice->m_pWdfUsbWritePipe->FormatRequestForWrite(
pWdfRequest,
NULL, //pFile
pWdfMemory,
NULL, //Memory offset
NULL); //DeviceOffset
if (FAILED(hr)) { pWdfRequest->Complete(hr); }
else { ForwardRequest(pWdfRequest, m_pMyDevice->m_pWdfUsbWritePipe); }
//Release Interface
pWdfMemory->Release();
}
void CMyQueue::ForwardRequest(
IWDFIoRequest* pWdfRequest,
IWDFIoTarget* pWdfTarget)
{
//Set the completion callback
IRequestCallbackRequestCompletion* pCallbackRequestCompletion = NULL;
HRESULT hr = this->QueryInterface(IID_PPV_ARGS(&pCallbackRequestCompletion));
pWdfRequest->SetCompletionCallback(pCallbackRequestCompletion, NULL);
pCallbackRequestCompletion->Release();
//Send down the request with no timeout
hr = pWdfRequest->Send(pWdfTarget, 0, 0);
if (FAILED(hr))
{
//If send failed we need to complete the request with failure
pWdfRequest->CompleteWithInformation(hr, 0);
}
}
VOID CMyQueue::OnCompletion(
IWDFIoRequest* pWdfRequest,
IWDFIoTarget* pWdfIoTarget,
IWDFRequestCompletionParams* pWdfParams,
PVOID pContext)
{
//Complete the request
pWdfRequest->CompleteWithInformation(
pWdfParams->GetCompletionStatus(),
pWdfParams->GetInformation());
}