Thomas-Sparber / wmi

Very simple C++ library to query WMI (even for MinGW)
Other
91 stars 24 forks source link

After the exception is caught here, does the program loop call, as in the example, cause a handle or memory leak #34

Open jijieming opened 4 months ago

jijieming commented 4 months ago

After the exception is caught here, does the program loop call, as in the example, cause a handle or memory leak:
int main(int /argc/, char /args*/[]) { try { Win32_ComputerSystem computer = retrieveWmi(); Win32_ComputerSystemProduct product = retrieveWmi(); SoftwareLicensingService liscense = retrieveWmi(); Win32_OperatingSystem os_info = retrieveWmi();

        cout<<"Computername: "<<computer.Name<<" Domaind:"<<computer.Domain<<endl;
        cout<<"Product: "<<product.Name<<" UUID:"<<product.UUID<<endl;
        cout<<"Architecture: "<<os_info.OSArchitecture<<std::endl;
        cout<<"Roles: "<<endl;
        for(const string role : computer.Roles)
        {
            cout<<" - "<<role<<std::endl;
        }
        cout<<endl;
        cout<<"Installed services:"<<endl;
        for(const Win32_Service &service : retrieveAllWmi<Win32_Service>())
        {
            cout<<service.Caption<<endl;
        }
    } catch (const WmiException &ex) {
        cerr<<"Wmi error: "<<ex.errorMessage<<", Code: "<<ex.hexErrorCode()<<endl;
        return 1;
    }

    return 0;
}
Thomas-Sparber commented 4 months ago

Thanks for reporting the issue!

Do you know where the exception is thrown?

Thomas-Sparber commented 4 months ago

I did a quick analysis, maybe line 421 in wmi.cpp needs to be copied to line 415 in wmi.cpp, so this:

....
try {
    std::size_t index = 0;

    foreachObject(pClassObject, [&out,&index](IWbemClassObject *object)
    {
        foreachProperty(object, [&out,index](const wstring &name, const std::wstring &value)
        {
            out.set(index,name, value);
            return true;
        });
        index++;
        return true;
    });
} catch (const WmiException &) {
    pServices->Release();
    pLocator->Release(); 
    CoUninitialize();
    throw;
}

pClassObject->Release();

pServices->Release();
pLocator->Release(); 
CoUninitialize();
...

becomes this:

...
try {
    std::size_t index = 0;

    foreachObject(pClassObject, [&out,&index](IWbemClassObject *object)
    {
        foreachProperty(object, [&out,index](const wstring &name, const std::wstring &value)
        {
            out.set(index,name, value);
            return true;
        });
        index++;
        return true;
    });
} catch (const WmiException &) {
    pClassObject->Release(); /* this line was added */
    pServices->Release();
    pLocator->Release(); 
    CoUninitialize();
    throw;
}

pClassObject->Release();

pServices->Release();
pLocator->Release(); 
CoUninitialize();
...

Can you please test and check if this fixes the issue?