Hey guys,
Sorry for what might be a trivial question for some of you. I’m using a coworkers USB library to write and read from a composite HID that I have written a custom driver for. In my driver I have a continuous reader set up to read incoming touch data from the device which I package into mouse and keyboard reports that are sent to the OS. Up until this point I hadn’t supported user I/O with the device but I am now trying to implement it. I’ve succeeded in adding support for write requests - I receive a IOCTL_HID_WRITE_REPORT code in my EvtInternalDeviceControl function and use WdfUsbTargetPipeWriteSynchronously to copy the user data over to the device (I tried some other methods to write the data to the device but nothing worked until I used that method). Writing works just fine, the problem I’m having occurs when I try and read.
So, in order to perform a read on this chip I need to write a read request packet to the device and then the device will respond with the data requested. When a user calls our write function from user space I receive the read request packet successfully from user space (in the user buffer of the IRP passed to EvtInternalDeviceControl) and copy the packet to the device. Once I do this, I do receive the response from the device in my continuous reader completion routine. The problem is that when I call the read function from our usb library (just a wrapper for readfile) to try and get the actual data back to user space, I never receive any IOCTL_HID_READ_REPORT code in my driver or anything and readfile always returns ERROR_IO_PENDING. Since I never get a read request in my driver I am unsure how to copy the data received from the device back to user space or support read requests at all. The problem has to do with the overlapped read but I can’t do anything if I never receive the request in my driver. I call GetLastError() when the read routine fails and it returns ERROR_IO_INCOMPLETE. Can anyone point me in the right direction here? I’d really appreciate it. Here’s the code for our read function:
BOOL ReadFromDevice(MY_DEVICE *pDevice, DWORD dwCollIndex, LPVOID pMessage, DWORD dwNumBytes, DWORD *pdwBytesRead)
{
BOOL bReadSuccess = FALSE;
BOOL bOverlapped = FALSE;
if(dwCollIndex >= pDevice->bCollectionNum)
{//collection does not exist for this device
return FALSE;
}
if(dwNumBytes < pDevice->Collection[dwCollIndex].dwInReportByteLength)
{//not enough space in buffer
return FALSE;
}
if(!ReadFile(pDevice->Collection[dwCollIndex].hHidDevice,
pMessage,
dwNumBytes,
pdwBytesRead,
&pDevice->Collection[dwCollIndex].OverlappedRead))
{//ReadFile returned FALSE
DWORD dwLastError = ::GetLastError();
if(dwLastError == ERROR_IO_PENDING)
{
WaitForSingleObject(pGhMtDevice->Collection[dwCollIndex].OverlappedRead.hEvent, TIMEOUT_READ);
BOOL bSuccess = GetOverlappedResult(pDevice->Collection[dwCollIndex].hHidDevice,
&pDevice->Collection[dwCollIndex].OverlappedRead,
pdwBytesRead,
FALSE);
if(bSuccess)
{
//GetOverlappedResult does not appear to be returning the correct number
// of bytes received (rather: wMaxPacketSize?).
if(*pdwBytesRead != pDevice->Collection[dwCollIndex].dwInReportByteLength)
{
*pdwBytesRead = pDevice->Collection[dwCollIndex].dwInReportByteLength;
}
bReadSuccess = TRUE;
}
}
}
else
{//read returned immediately
bReadSuccess = TRUE;
}
ResetEvent(pDevice->Collection[dwCollIndex].OverlappedRead.hEvent);
return(bReadSuccess);
}