2014-01-15 143 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

這很有效,非常感謝! –

相關問題