Files

210 lines
4.6 KiB
C
Raw Permalink Normal View History

2026-03-28 16:54:11 +11:00
#pragma once
#define _WIN32_DCOM
#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>
#include <list>
#include <string>
#include "uniconv.h"
#pragma comment(lib, "wbemuuid.lib")
using namespace std;
class WmiHelper
{
public:
WmiHelper()
{
HRESULT hres;
wbemServices = NULL;
wbemLocator = NULL;
ownCoInitialize = false;
// Initialize COM.
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (hres == S_OK)
{
ownCoInitialize = true;
}
// Initialize
hres = CoInitializeSecurity(
NULL,
-1, // COM negotiates service
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &wbemLocator);
if (FAILED(hres))
{
if (ownCoInitialize)
CoUninitialize();
throw new exception("failed to create IWbemLocator", hres);
}
// Connect to the root\cimv2 namespace with the
// current user and obtain pointer pSvc
// to make IWbemServices calls.
hres = wbemLocator->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"), // WMI namespace
NULL, // User name
NULL, // User password
0, // Locale
NULL, // Security flags
0, // Authority
0, // Context object
&wbemServices // IWbemServices proxy
);
if (FAILED(hres))
{
wbemLocator->Release();
if (ownCoInitialize)
CoUninitialize();
throw new exception("could not connect to WMI", hres);
}
// Set the IWbemServices proxy so that impersonation
// of the user (client) occurs.
hres = CoSetProxyBlanket(
wbemServices, // the proxy to set
RPC_C_AUTHN_WINNT, // authentication service
RPC_C_AUTHZ_NONE, // authorization service
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // authentication level
RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
wbemServices->Release();
wbemLocator->Release();
if (ownCoInitialize) CoUninitialize();
throw new exception("could not connecto to WMI", hres);
}
}
~WmiHelper()
{
if (wbemServices) wbemServices->Release();
if (wbemLocator) wbemLocator->Release();
if (ownCoInitialize) CoUninitialize();
}
void GetPropertyList(const char * wqlQuery, const char * propertyName, list<string> * propList, int maxElements = 0x7FFFFFFF)
{
HRESULT hres;
// For example, query for all the running processes
IEnumWbemClassObject* pEnumerator = NULL;
hres = wbemServices->ExecQuery(
bstr_t("WQL"),
bstr_t(wqlQuery),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
if (FAILED(hres))
{
throw new exception("WMI query failed");
}
else
{
IWbemClassObject *pclsObj;
ULONG uReturn = 0;
int numElements = 0;
while (1)
{
hres = pEnumerator->Next(WBEM_INFINITE, 1,
&pclsObj, &uReturn);
if(0 == uReturn)
{
break;
}
VARIANT vtProp;
VariantInit(&vtProp);
// Get the value of the Name property
hres = pclsObj->Get(_bstr_t(propertyName), 0, &vtProp, 0, 0);
//
if (SUCCEEDED(hres))
{
switch (vtProp.vt)
{
case VT_BSTR:
propList->push_back(w2s(vtProp.bstrVal).c_str());
numElements++;
break;
case VT_I1:
case VT_UI1:
case VT_I2:
case VT_UI2:
case VT_I4:
case VT_UI4:
{
char strVal[32];
_itoa(vtProp.intVal, strVal, 10);
propList->push_back(strVal);
numElements++;
}
break;
case VT_I8:
case VT_UI8:
{
char strVal[32];
_i64toa(vtProp.llVal, strVal, 10);
propList->push_back(strVal);
numElements++;
}
break;
default:
break;
}
VariantClear(&vtProp);
}
pclsObj->Release();
if (numElements >= maxElements)
break;
}
pEnumerator->Release();
}
}
private:
bool ownCoInitialize;
IWbemServices * wbemServices;
IWbemLocator * wbemLocator;
};