Question

I have a code that enumerates USB devices on Windows XP using SetupAPI:

    HDEVINFO hDevInfo = SetupDiGetClassDevs( &_DEVINTERFACE_USB_DEVICE, 0, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);

    for (DWORD i = 0; ; ++i)
    {
        SP_DEVINFO_DATA devInfo;
        devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
        BOOL succ = SetupDiEnumDeviceInfo(hDevInfo, i, &devInfo);
        if (GetLastError() == ERROR_NO_MORE_ITEMS)
            break;
        if (!succ) continue;

        DWORD devClassPropRequiredSize = 0;
        succ = SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfo, SPDRP_COMPATIBLEIDS, NULL, NULL, 0, &devClassPropRequiredSize);
        if (!succ)
        {
           // This shouldn't happen!
           continue;
        }
    }

It used to work for years, but now I get FALSE from SetupDiGetDeviceRegistryProperty, last error is "The data area passed to a system call is too small". It seems that my call parameters correspond to the documentation for this function: http://msdn.microsoft.com/en-us/library/windows/hardware/ff551967(v=vs.85).aspx

Any ideas what's wrong?

Was it helpful?

Solution

Problem was in your original code: SetupDiGetDeviceRegistryProperty function may return FALSE (and set last error to ERROR_INSUFFICIENT_BUFFER) when required property doesn't exist (or when its data is not valid, yes they have been lazy to pick a proper error code) so you should always check for ERROR_INSUFFICIENT_BUFFER as a (not so) special case:

DWORD devClassPropRequiredSize = 0;
succ = SetupDiGetDeviceRegistryProperty(
    hDevInfo,
    &devInfo,
    SPDRP_COMPATIBLEIDS,
    NULL, 
    NULL, 
    0,
    &devClassPropRequiredSize);

if (!succ) {
    if (ERROR_INSUFFICIENT_BUFFER == GetLastError() {
        // I may ignore this property or I may simply
        // go on, required size has been set in devClassPropRequiredSize
        // so next call should work as expected (or fail in a managed way).
    } else {
        continue; // Cannot read property size
    }
}

Usually you may simply ignore this error when you're reading property size (if devClassPropRequiredSize is still zero you can default it to proper constant for maximum allowed length). If property can't be read then next call SetupDiGetDeviceRegistryProperty will fail (and you'll manage error there) but often you're able to read value and your code will work smoothly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top