views:

247

answers:

1

I have code to detect the connection of USB Flash Drives as volumes. The code has been working very well for awhile, but recently a fellow engineer's machine started to fail and didn't work right again until it was restarted.

The project uses Qt 4.5.0, but that shouldn't be very relevant to this question.

I register for the notification as follows

// Register for device connect notification
DEV_BROADCAST_DEVICEINTERFACE devInt;
ZeroMemory( &devInt, sizeof(devInt) );
devInt.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
devInt.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
devInt.dbcc_classguid = GUID_DEVINTERFACE_VOLUME;

m_hDeviceNotify =
    RegisterDeviceNotification( winId(), &devInt, DEVICE_NOTIFY_WINDOW_HANDLE );

The handler then filters for the WM_DEVICECHANGE messages.

if (message->message == WM_DEVICECHANGE)
{
    switch (message->wParam)
    {
    case DBT_DEVICEARRIVAL:
        HandleVolumeArrival( message );
        break;

    case DBT_DEVICEREMOVECOMPLETE:
        HandleVolumeRemoval( message );
        break;

    default:
        break;
    }

    *result = TRUE;
} // end if

The arrival message handler then handles the message as such:

void HandleVolumeArrival( MSG *message ) { if(message->lParam == 0) { qDebug() << "lParam is 0 on Device Arrival"; return; } // end if

PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR) message->lParam;
if(pHdr->dbch_devicetype == DBT_DEVTYP_VOLUME)
{
    PDEV_BROADCAST_VOLUME pVol = (PDEV_BROADCAST_VOLUME) pHdr;

    // Handling of the volume is performed here
} // end if

} // end HandleVolumeArrival

The problem came when checking the device type for a volume type:

pHdr->dbch_devicetype == DBT_DEVTYP_VOLUME

When it was failing, the device type was being reported as DBT_DEVTYP_DEVICEINTERFACE.

Multiple USB drives were tried and all had the same problem.

Has anyone seen anything like this before? Do you know what could cause it or why the problem would go away on a system restart?

+1  A: 

My guess would be that you would see the DBT_DEVTYP_DEVICEINTERFACE normally anyway. USB devices are self-describing. A USB device can have any "interfaces" where each interface is a feature of the device. My guess is that when a USB is connected you get a "DBT_DEVTYP_DEVICEINTERFACE" per USB device interface so that a USB device driver can say that they can handle that USB interface. I would assume that the USB device driver for USB mass storage driver would would handle this messages by mounting the volume and then you would get the DBT_DEVTYP_VOLUME message.

I would guess that the mass storage interface driver is not working correctly (or has crashed) and is not handling the DBT_DEVTYP_DEVICEINTERFACE. Unless you starting seeing it a lot I don't think it is a situation that you should bother to handle.

Shane Powell
The idea that the DBT_DEVTYP_DEVICEINTERFACE message is sent always crossed my mind, though I haven't confirmed it. The rest of this makes sense and I'm willing to live with that unless, as you say, we start seeing it a lot. Thanks!
brader