none
Can't get enough data from USB device. RRS feed

  • Question

  • I'd like to get data from my USB device by following interfaces:

    #define IOCTL_OREXSCANNER_GET_IMAGE_BLOCK	CTL_CODE(OREXSCANNER_DEVICE_TYPE, 0x803, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
    
    res = DeviceIoControl(m_hDevice, IOCTL_OREXSCANNER_GET_IMAGE_BLOCK,
    			NULL, 0, m_pNextFreeBlock, blockSize, NULL, &m_Requests[i]);
    
    DWORD err = GetLastError();
    		if (res || err != ERROR_IO_PENDING)
    		{
    			WriteToLogFile("GetLogThread 1. WM_DEVICE_EVENT_DETACHED (DeviceIoControl - IOCTL_OREXSCANNER_GET_IMAGE_BLOCK failed), Error Code: %d", err);
    			return -1;
    		}
    
    HANDLE events[1];
    	events[0] = m_Requests[i].hEvent;
    
    ret = WaitForMultipleObjects(1, events, FALSE, dwdWait);
    
    if (ret != WAIT_OBJECT_0)
    	{
    		WriteToLogFile("Get log loop: ERROR !!!: ret != WAIT_OBJECT_0 !!! Total received %d, Next free block %d END_OF_GETLOG",
    			m_dwTotalReceived,
    			m_pNextFreeBlock
    		);
    		if (ret == (WAIT_OBJECT_0 + 1))
    		{
    			iFlagBreak = 100;
    		}
    		else if (ret == WAIT_TIMEOUT)
    		{
    			iFlagBreak = 201;
    		}
    		else
    		{
    			iFlagBreak = 300;
    		}
    	}
    	else if (iFlagBreak == 0)
    	{
    		if (!GetOverlappedResult(m_hDevice, &m_Requests[index], &ret, FALSE))
    		{
    			WriteToLogFile("GetLogThread 2. WM_DEVICE_EVENT_DETACHED (GetOverlappedResult failed)");
    			iFlagBreak = 400;
    		}
    	}
    	if (iFlagBreak == 0 && ret)
    	{
    		WriteToLogFile("Saving data, count: %d", count);
    		pwdTempBuffer = m_pImageBuf;
    		pwdTempBuffer += (m_dwTotalReceived >> 1);
    		AddBufferToLogFile(pwdTempBuffer, (ret >> 1), m_strLogFile);		
    	}
    	m_dwTotalReceived += ret;
    	WriteToLogFile("Saving data, received: %d, total received: %d", ret, m_dwTotalReceived);
    	if (ret != blockSize)
    	{
    		iFlagBreak = 200; 
    }

    the BlockSize i want to get is 128 KB but sometimes the returned size of GetOverlappedResult is less than 128 KB which cause

    iFlagBreak is set to 200.

    but all the associated functions such as DeviceIoControl/WaitForMultipleObjects/GetOverlappedResult don't report any error .

     in which case GetOverlappedResult will not return expected size but donn't report error?

    i have no idea. 

    please help me for this issue.

    i appriciate for your kindly help....

    Tuesday, October 29, 2019 7:51 AM

Answers

  • It is acceptable for a driver to complete the request with success with a smaller number of bytes (your "expected size").  The right behavior (return success or error when fewer bytes than buffer size are written/read) is really defined by the driver IO contract itself, IOW you need to talk to the driver vendor to know what to expect in this scenario, the Windows APIs that send the IO requests are not where the issue is.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Tuesday, October 29, 2019 8:16 PM

All replies

  • It is acceptable for a driver to complete the request with success with a smaller number of bytes (your "expected size").  The right behavior (return success or error when fewer bytes than buffer size are written/read) is really defined by the driver IO contract itself, IOW you need to talk to the driver vendor to know what to expect in this scenario, the Windows APIs that send the IO requests are not where the issue is.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Tuesday, October 29, 2019 8:16 PM
  • thanks for your information and it is very useful.

    as your suggestion i checked the source code of driver.

    and foud the parameter bShortOK is true as below:

    PURB USBBuildBulkTransferMdl(PUSB_PIPE pUsbPipe,
                                 PMDL pMdl,
                                 ULONG Length,
                                 BOOLEAN bIn,
                                 PURB Link,
                                 BOOLEAN bShortOk,
                                 PURB pUrb)
    {
        ULONG Flags;
        PURB p = NULL;
    
        if(pUrb == NULL)
        {
            p = (PURB)ExAllocatePool(NonPagedPool, sizeof(*p));
            if (p == NULL)
            {
                return NULL;
            }
        }
        else
        {
            p = pUrb;
        }
    
        if(bIn)
        {
            Flags = USBD_TRANSFER_DIRECTION_IN;
    
            if (bShortOk)
            {
                Flags |= USBD_SHORT_TRANSFER_OK;
            }
        }
        else
        {
            Flags = 0;
        }
    
        UsbBuildInterruptOrBulkTransferRequest(p,
    		                                   (USHORT)sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
    		                                   pUsbPipe ->Information ->PipeHandle,
                                               NULL,
                                               pMdl,
                                               Length,
                                               Flags,
                                               Link);
    

    according to the instruction of transferFlags of function UsbBuildInterruptOrBulkTransferRequest:

    USBD_SHORT_TRANSFER_OK

    Can be used if USBD_TRANSFER_DIRECTION_IN is set. If set, directs the HCD not to return an error if a packet is received from the device that is shorter than the maximum packet size for the endpoint. Otherwise, a short request returns an error condition.

    which indicates if get smaller data number this functin will not report error

    i think this should be the cause.

    thanks again for your help.

    Wednesday, October 30, 2019 6:12 AM