// Copyright Leon Freist // Author Leon Freist #if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) #pragma once #define _WIN32_DCOM #include #include #include #include #include #include #pragma comment(lib, "wbemuuid.lib") namespace hwinfo { namespace wmi { template inline bool queryWMI(const std::string& WMIClass, std::string field, std::vector& value, const std::string& serverName = "ROOT\\CIMV2") { std::string query("SELECT " + field + " FROM " + WMIClass); HRESULT hres; hres = CoInitializeEx(nullptr, COINIT_MULTITHREADED); if (FAILED(hres)) { return false; } hres = CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE, nullptr); if (FAILED(hres)) { // CoUninitialize(); // return false; } IWbemLocator* pLoc = nullptr; hres = CoCreateInstance(CLSID_WbemLocator, nullptr, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc); if (FAILED(hres)) { CoUninitialize(); return false; } IWbemServices* pSvc = nullptr; hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), nullptr, nullptr, nullptr, 0, nullptr, nullptr, &pSvc); if (FAILED(hres)) { pLoc->Release(); CoUninitialize(); return false; } hres = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE); if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return false; } IEnumWbemClassObject* pEnumerator = nullptr; hres = pSvc->ExecQuery(bstr_t(L"WQL"), bstr_t(std::wstring(query.begin(), query.end()).c_str()), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, &pEnumerator); if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return false; } IWbemClassObject* pclsObj = nullptr; ULONG uReturn = 0; while (pEnumerator) { pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if (!uReturn) { break; } VARIANT vtProp; pclsObj->Get(std::wstring(field.begin(), field.end()).c_str(), 0, &vtProp, nullptr, nullptr); if (std::is_same::value || std::is_same::value) { value.push_back((T)vtProp.intVal); } else if (std::is_same::value) { value.push_back((T)vtProp.boolVal); } else if (std::is_same::value) { value.push_back((T)vtProp.uintVal); } else if (std::is_same::value) { value.push_back((T)vtProp.uiVal); } else if (std::is_same::value) { value.push_back((T)vtProp.llVal); } else if (std::is_same::value) { value.push_back((T)vtProp.ullVal); } else { // TODO: this might cause issues with MinGW. fix this in another way than using the macros #if defined(__MINGW32__) || defined(__MINGW64__) ; #else value.push_back((T)((bstr_t)vtProp.bstrVal).copy()); // BSTR val = SysAllocString(vtProp.bstrVal); // value.push_back((bstr_t)val); #endif } VariantClear(&vtProp); pclsObj->Release(); } if (value.empty()) { value.resize(1); } pSvc->Release(); pLoc->Release(); if (pEnumerator) pEnumerator->Release(); CoUninitialize(); return true; } } // namespace wmi } // namespace hwinfo #endif