2014-01-15 129 views
2

我有使用SETUPAPI在Windows XP上枚举USB设备代码:SetupDiGetDeviceRegistryProperty:“传递给系统调用的数据区域太小,”错误

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; 
     } 
    } 

它曾经工作多年,但现在我从SetupDiGetDeviceRegistryProperty得到FALSE,最后一个错误是“传递给系统调用的数据区太小”。 似乎我的通话参数对应于此功能的文档:http://msdn.microsoft.com/en-us/library/windows/hardware/ff551967(v=vs.85).aspx

任何想法有什么问题?

回答

2

问题是在你的原始代码:如果所需的属性不存在(或当它的数据是无效的,是的,他们已经懒得挑一个合适的错误SetupDiGetDeviceRegistryProperty函数可能返回FALSE(并设置一个错误来ERROR_INSUFFICIENT_BUFFER)代码),所以你应该经常检查ERROR_INSUFFICIENT_BUFFER作为一个(不那么)特殊情况:

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 
    } 
} 

通常你可以简单地忽略,当你阅读房产大小此错误(如果devClassPropRequiredSize仍然是零,您可以在默认适用于最大允许长度的常数)。如果财产不能被读取,那么下一次调用SetupDiGetDeviceRegistryProperty将失败(并且您将在那里管理错误),但是您经常可以读取值并且您的代码将顺利运行。

+1

这很有效,非常感谢! –

相关问题