lfreist/hwinfo

Windows: Incorrect handling IEnumWbemClassObject::Next calls

Opened this issue · 0 comments

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

  • u_return can have 1 set from the previous loop iteration and not that last Next call
  • obj can be set from the previous loop iteration, instead of the current Next call, causing Object is not connected to server error when trying to use it (since that was already release)

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