lfreist / hwinfo

cross platform C++ library for hardware information (CPU, RAM, GPU, ...)
MIT License
487 stars 88 forks source link

Windows: Incorrect handling IEnumWbemClassObject::Next calls #90

Open ruifig opened 5 months ago

ruifig commented 5 months ago

I'm hitting crashes/exceptions due to what seems to be incorrect handling of IEnumWbemClassObject::Next

  ULONG u_return = 0;
  IWbemClassObject* obj = nullptr;
  int cpu_id = 0;
  while (wmi.enumerator) {
    wmi.enumerator->Next(WBEM_INFINITE, 1, &obj, &u_return);
    if (!u_return) {
      break;
    }
    ...

That pattern above seems to be used in several places, and I believe it has a few bugs

I can't reproduce the issue on my machine, but several other developers are encountering this problem. To be fair, I didn't read the entire documentation for Next (https://learn.microsoft.com/en-us/windows/win32/api/wbemcli/nf-wbemcli-ienumwbemclassobject-next) , but the easiest fix seems to be to simply move u_return and obj to inside the loop to avoid side effects from the previous iteration, and thus we can rely on that for the checks. E.g:

  int cpu_id = 0;
  while (wmi.enumerator) {
    ULONG u_return = 0;
    IWbemClassObject* obj = nullptr;
    wmi.enumerator->Next(WBEM_INFINITE, 1, &obj, &u_return);
    if (!u_return) {
      break;
    }
    ...