Windows: simplify WMI query code

by making C++ code more C++
This commit is contained in:
李通洲
2022-10-16 23:58:13 +08:00
parent 5d5663e2a7
commit 38b3aae1e3
16 changed files with 254 additions and 346 deletions
+8 -13
View File
@@ -8,26 +8,23 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
FF_UNUSED(instance);
//https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-battery
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT SystemName, Name, Chemistry, EstimatedChargeRemaining, BatteryStatus FROM Win32_Battery", nullptr);
FFWmiQuery query(L"SELECT SystemName, Name, Chemistry, EstimatedChargeRemaining, BatteryStatus FROM Win32_Battery");
if(!pEnumerator)
if(!query)
return "Query WMI service failed";
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0)
while(FFWmiRecord record = query.next())
{
BatteryResult* battery = (BatteryResult*)ffListAdd(results);
ffStrbufInit(&battery->manufacturer);
ffGetWmiObjString(pclsObj, L"SystemName", &battery->manufacturer);
record.getString(L"SystemName", &battery->manufacturer);
ffStrbufInit(&battery->modelName);
ffGetWmiObjString(pclsObj, L"Name", &battery->modelName);
record.getString(L"Name", &battery->modelName);
uint64_t chemistry = 0;
ffGetWmiObjUnsigned(pclsObj, L"Chemistry", &chemistry);
record.getUnsigned(L"Chemistry", &chemistry);
switch(chemistry)
{
case 1: ffStrbufInitS(&battery->technology, "Other"); break;
@@ -42,11 +39,11 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
}
uint64_t capacity;
ffGetWmiObjUnsigned(pclsObj, L"EstimatedChargeRemaining", &capacity);
record.getUnsigned(L"EstimatedChargeRemaining", &capacity);
ffStrbufInitF(&battery->capacity, "%d", (int)capacity);
uint64_t batteryStatus;
ffGetWmiObjUnsigned(pclsObj, L"BatteryStatus", &batteryStatus);
record.getUnsigned(L"BatteryStatus", &batteryStatus);
switch(batteryStatus)
{
case 1: ffStrbufInitS(&battery->status, "Discharging"); break;
@@ -66,7 +63,5 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
battery->temperature = FF_BATTERY_TEMP_UNSET;
}
if(pclsObj) pclsObj->Release();
pEnumerator->Release();
return nullptr;
}
+9 -19
View File
@@ -12,27 +12,17 @@ extern "C" void ffDetectBios(FFBiosResult* bios)
ffStrbufInit(&bios->biosVendor);
ffStrbufInit(&bios->biosVersion);
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, ReleaseDate, Version, Manufacturer FROM Win32_BIOS", &bios->error);
if(!pEnumerator)
FFWmiQuery query(L"SELECT Name, ReleaseDate, Version, Manufacturer FROM Win32_BIOS", &bios->error);
if(!query)
return;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if(uReturn == 0)
if(FFWmiRecord record = query.next())
{
ffStrbufInitS(&bios->error, "No Wmi result returned");
pEnumerator->Release();
return;
record.getString(L"Name", &bios->biosRelease);
record.getString(L"ReleaseDate", &bios->biosDate);
record.getString(L"Version", &bios->biosVersion);
record.getString(L"Manufacturer", &bios->biosVendor);
}
ffGetWmiObjString(pclsObj, L"Name", &bios->biosRelease);
ffGetWmiObjString(pclsObj, L"ReleaseDate", &bios->biosDate);
ffGetWmiObjString(pclsObj, L"Version", &bios->biosVersion);
ffGetWmiObjString(pclsObj, L"Manufacturer", &bios->biosVendor);
pclsObj->Release();
pEnumerator->Release();
else
ffStrbufInitS(&bios->error, "No Wmi result returned");
}
+8 -18
View File
@@ -11,26 +11,16 @@ extern "C" void ffDetectBoard(FFBoardResult* board)
ffStrbufInit(&board->boardVendor);
ffStrbufInit(&board->boardVersion);
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Product, Version, Manufacturer FROM Win32_BaseBoard", &board->error);
if(!pEnumerator)
FFWmiQuery query(L"SELECT Product, Version, Manufacturer FROM Win32_BaseBoard", &board->error);
if(!query)
return;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if(uReturn == 0)
if(FFWmiRecord record = query.next())
{
ffStrbufInitS(&board->error, "No Wmi result returned");
pEnumerator->Release();
return;
record.getString(L"Product", &board->boardName);
record.getString(L"Manufacturer", &board->boardVendor);
record.getString(L"Version", &board->boardVersion);
}
ffGetWmiObjString(pclsObj, L"Product", &board->boardName);
ffGetWmiObjString(pclsObj, L"Manufacturer", &board->boardVendor);
ffGetWmiObjString(pclsObj, L"Version", &board->boardVersion);
pclsObj->Release();
pEnumerator->Release();
else
ffStrbufInitS(&board->error, "No Wmi result returned");
}
+18 -27
View File
@@ -17,35 +17,26 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
ffStrbufInit(&cpu->name);
ffStrbufInit(&cpu->vendor);
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, ThreadCount, CurrentClockSpeed, MaxClockSpeed FROM Win32_Processor WHERE ProcessorType = 3", nullptr);
if(!pEnumerator)
FFWmiQuery query(L"SELECT Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, ThreadCount, CurrentClockSpeed, MaxClockSpeed FROM Win32_Processor WHERE ProcessorType = 3");
if(!query)
return;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
if(FFWmiRecord record = query.next())
{
pEnumerator->Release();
return;
record.getString(L"Name", &cpu->name);
record.getString(L"Manufacturer", &cpu->vendor);
uint64_t value;
record.getUnsigned(L"NumberOfCores", &value);
cpu->coresPhysical = (uint16_t)value;
record.getUnsigned(L"NumberOfLogicalProcessors", &value);
cpu->coresLogical = (uint16_t)value;
record.getUnsigned(L"ThreadCount", &value);
cpu->coresOnline = (uint16_t)value;
record.getUnsigned(L"CurrentClockSpeed", &value); //There's no MinClockSpeed in Win32_Processor
cpu->frequencyMin = (double)value / 1000.0;
record.getUnsigned(L"MaxClockSpeed", &value);
cpu->frequencyMax = (double)value / 1000.0;
}
ffGetWmiObjString(pclsObj, L"Name", &cpu->name);
ffGetWmiObjString(pclsObj, L"Manufacturer", &cpu->vendor);
uint64_t value;
ffGetWmiObjUnsigned(pclsObj, L"NumberOfCores", &value);
cpu->coresPhysical = (uint16_t)value;
ffGetWmiObjUnsigned(pclsObj, L"NumberOfLogicalProcessors", &value);
cpu->coresLogical = (uint16_t)value;
ffGetWmiObjUnsigned(pclsObj, L"ThreadCount", &value);
cpu->coresOnline = (uint16_t)value;
ffGetWmiObjUnsigned(pclsObj, L"CurrentClockSpeed", &value); //There's no MinClockSpeed in Win32_Processor
cpu->frequencyMin = (double)value / 1000.0;
ffGetWmiObjUnsigned(pclsObj, L"MaxClockSpeed", &value);
cpu->frequencyMax = (double)value / 1000.0;
pclsObj->Release();
pEnumerator->Release();
}
@@ -5,22 +5,14 @@ extern "C" {
extern "C" const char* ffGetCpuUsageResultNoWait(double* result)
{
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT LoadPercentage FROM Win32_Processor", nullptr);
if(!pEnumerator)
FFWmiQuery query(L"SELECT LoadPercentage FROM Win32_Processor");
if(!query)
return "Query WMI service failed";
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
{
pEnumerator->Release();
if(FFWmiRecord record = query.next())
record.getReal(L"LoadPercentage", result);
else
return "No WMI result returned";
}
ffGetWmiObjReal(pclsObj, L"LoadPercentage", result);
pclsObj->Release();
pEnumerator->Release();
return NULL;
return nullptr;
}
+17 -25
View File
@@ -9,34 +9,26 @@ extern "C" {
extern "C"
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
{
wchar_t query[256] = {};
swprintf(query, 256, L"SELECT IconTitleFaceName, IconTitleSize FROM Win32_Desktop WHERE Name LIKE '%%\\\\%s'", instance->state.passwd->pw_name);
wchar_t sql[256] = {};
swprintf(sql, 256, L"SELECT IconTitleFaceName, IconTitleSize FROM Win32_Desktop WHERE Name LIKE '%%\\\\%s'", instance->state.passwd->pw_name);
IEnumWbemClassObject* pEnumerator = ffQueryWmi(query, &result->error);
if(!pEnumerator)
FFWmiQuery query(sql, &result->error);
if(!query)
return;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
if(FFWmiRecord record = query.next())
{
ffStrbufInitS(&result->error, "No WMI result returned");
pEnumerator->Release();
return;
FFstrbuf fontName;
ffStrbufInit(&fontName);
record.getString(L"IconTitleFaceName", &fontName);
uint64_t fontSize;
record.getUnsigned(L"IconTitleSize", &fontSize);
ffStrbufAppendF(&result->fonts[0], "%*s (%upt)", fontName.length, fontName.chars, (unsigned)fontSize);
ffStrbufDestroy(&fontName);
}
FFstrbuf fontName;
ffStrbufInit(&fontName);
ffGetWmiObjString(pclsObj, L"IconTitleFaceName", &fontName);
uint64_t fontSize;
ffGetWmiObjUnsigned(pclsObj, L"IconTitleSize", &fontSize);
ffStrbufAppendF(&result->fonts[0], "%*s (%upt)", fontName.length, fontName.chars, (unsigned)fontSize);
ffStrbufDestroy(&fontName);
pclsObj->Release();
pEnumerator->Release();
else
ffStrbufInitS(&result->error, "No WMI result returned");
}
+6 -12
View File
@@ -8,20 +8,16 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
{
FF_UNUSED(instance);
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, AdapterCompatibility, DriverVersion FROM Win32_VideoController", nullptr);
if(!pEnumerator)
FFWmiQuery query(L"SELECT Name, AdapterCompatibility, DriverVersion FROM Win32_VideoController", nullptr);
if(!query)
return "Query WMI service failed";
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0)
while(FFWmiRecord record = query.next())
{
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
ffStrbufInit(&gpu->vendor);
ffGetWmiObjString(pclsObj, L"AdapterCompatibility", &gpu->vendor);
record.getString(L"AdapterCompatibility", &gpu->vendor);
if(ffStrbufStartsWithS(&gpu->vendor, "Intel "))
{
//Intel returns "Intel Corporation", not sure about AMD
@@ -29,16 +25,14 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
}
ffStrbufInit(&gpu->name);
ffGetWmiObjString(pclsObj, L"Name", &gpu->name);
record.getString(L"Name", &gpu->name);
ffStrbufInit(&gpu->driver);
ffGetWmiObjString(pclsObj, L"DriverVersion", &gpu->driver);
record.getString(L"DriverVersion", &gpu->driver);
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
}
if(pclsObj) pclsObj->Release();
pEnumerator->Release();
return nullptr;
}
+9 -17
View File
@@ -16,25 +16,17 @@ extern "C" void ffDetectHostImpl(FFHostResult* host)
ffStrbufInit(&host->chassisVendor);
ffStrbufInit(&host->chassisVersion);
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, Version, SKUNumber, Vendor FROM Win32_ComputerSystemProduct", &host->error);
if(!pEnumerator)
FFWmiQuery query(L"SELECT Name, Version, SKUNumber, Vendor FROM Win32_ComputerSystemProduct", &host->error);
if(!query)
return;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
if(FFWmiRecord record = query.next())
{
ffStrbufInitS(&host->error, "No Wmi result returned");
pEnumerator->Release();
return;
record.getString(L"Name", &host->productName);
record.getString(L"Version", &host->productVersion);
record.getString(L"SKUNumber", &host->productSku);
record.getString(L"Vendor", &host->sysVendor);
}
ffGetWmiObjString(pclsObj, L"Name", &host->productName);
ffGetWmiObjString(pclsObj, L"Version", &host->productVersion);
ffGetWmiObjString(pclsObj, L"SKUNumber", &host->productSku);
ffGetWmiObjString(pclsObj, L"Vendor", &host->sysVendor);
pclsObj->Release();
pEnumerator->Release();
else
ffStrbufInitS(&host->error, "No Wmi result returned");
}
+22 -40
View File
@@ -5,58 +5,40 @@ extern "C" {
void detectRam(FFMemoryStorage* ram)
{
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT TotalVisibleMemorySize, FreePhysicalMemory FROM Win32_OperatingSystem", &ram->error);
if(!pEnumerator)
FFWmiQuery query(L"SELECT TotalVisibleMemorySize, FreePhysicalMemory FROM Win32_OperatingSystem", &ram->error);
if(!query)
return;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
if(FFWmiRecord record = query.next())
{
ffStrbufInitS(&ram->error, "No WMI result returned");
pEnumerator->Release();
return;
//KB
record.getUnsigned(L"TotalVisibleMemorySize", &ram->bytesTotal);
uint64_t bytesFree;
record.getUnsigned(L"FreePhysicalMemory", &bytesFree);
ram->bytesUsed = ram->bytesTotal - bytesFree;
ram->bytesTotal *= 1024;
ram->bytesUsed *= 1024;
}
//KB
ffGetWmiObjUnsigned(pclsObj, L"TotalVisibleMemorySize", &ram->bytesTotal);
uint64_t bytesFree;
ffGetWmiObjUnsigned(pclsObj, L"FreePhysicalMemory", &bytesFree);
ram->bytesUsed = ram->bytesTotal - bytesFree;
pclsObj->Release();
pEnumerator->Release();
ram->bytesTotal *= 1024;
ram->bytesUsed *= 1024;
else
ffStrbufInitS(&ram->error, "No Wmi result returned");
}
void detectSwap(FFMemoryStorage* swap)
{
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT AllocatedBaseSize, CurrentUsage FROM Win32_PageFileUsage", &swap->error);
if(!pEnumerator)
FFWmiQuery query(L"SELECT AllocatedBaseSize, CurrentUsage FROM Win32_PageFileUsage", &swap->error);
if(!query)
return;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
if(FFWmiRecord record = query.next())
{
ffStrbufInitS(&swap->error, "No WMI result returned");
pEnumerator->Release();
return;
//MB
record.getUnsigned(L"AllocatedBaseSize", &swap->bytesTotal);
record.getUnsigned(L"CurrentUsage", &swap->bytesUsed);
swap->bytesTotal *= 1024 * 1024;
swap->bytesUsed *= 1024 * 1024;
}
//MB
ffGetWmiObjUnsigned(pclsObj, L"AllocatedBaseSize", &swap->bytesTotal);
ffGetWmiObjUnsigned(pclsObj, L"CurrentUsage", &swap->bytesUsed);
pclsObj->Release();
pEnumerator->Release();
swap->bytesTotal *= 1024 * 1024;
swap->bytesUsed *= 1024 * 1024;
else
ffStrbufInitS(&swap->error, "No Wmi result returned");
}
extern "C"
+41 -51
View File
@@ -19,65 +19,55 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance)
ffStrbufInit(&os->systemName);
ffStrbufInit(&os->architecture);
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Caption, Version, BuildNumber, OSArchitecture FROM Win32_OperatingSystem", nullptr);
if(!pEnumerator)
FFWmiQuery query(L"SELECT Caption, Version, BuildNumber, OSArchitecture FROM Win32_OperatingSystem");
if(!query)
return;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
if(FFWmiRecord record = query.next())
{
pEnumerator->Release();
return;
}
ffGetWmiObjString(pclsObj, L"Caption", &os->variant);
if(ffStrbufStartsWithS(&os->variant, "Microsoft Windows "))
{
ffStrbufAppendS(&os->name, "Microsoft Windows");
ffStrbufAppendS(&os->prettyName, "Windows");
ffStrbufSubstrAfter(&os->variant, strlen("Microsoft Windows ") - 1);
if(ffStrbufStartsWithS(&os->variant, "Server "))
record.getString(L"Caption", &os->variant);
if(ffStrbufStartsWithS(&os->variant, "Microsoft Windows "))
{
ffStrbufAppendS(&os->name, " Server");
ffStrbufAppendS(&os->prettyName, " Server");
ffStrbufSubstrAfter(&os->variant, strlen(" Server") - 1);
}
ffStrbufAppendS(&os->name, "Microsoft Windows");
ffStrbufAppendS(&os->prettyName, "Windows");
uint32_t index = ffStrbufFirstIndexC(&os->variant, ' ');
ffStrbufAppendNS(&os->version, index, os->variant.chars);
ffStrbufSubstrAfter(&os->variant, index);
ffStrbufSubstrAfter(&os->variant, strlen("Microsoft Windows ") - 1);
// Windows Server 20xx Rx
if(ffStrbufEndsWithC(&os->prettyName, 'r'))
{
if(os->variant.chars[0] == 'R' &&
isdigit(os->variant.chars[1]) &&
(os->variant.chars[2] == '\0' || os->variant.chars[2] == ' '))
if(ffStrbufStartsWithS(&os->variant, "Server "))
{
ffStrbufAppendF(&os->version, " R%c", os->variant.chars[1]);
ffStrbufSubstrAfter(&os->variant, strlen("Rx ") - 1);
ffStrbufAppendS(&os->name, " Server");
ffStrbufAppendS(&os->prettyName, " Server");
ffStrbufSubstrAfter(&os->variant, strlen(" Server") - 1);
}
uint32_t index = ffStrbufFirstIndexC(&os->variant, ' ');
ffStrbufAppendNS(&os->version, index, os->variant.chars);
ffStrbufSubstrAfter(&os->variant, index);
// Windows Server 20xx Rx
if(ffStrbufEndsWithC(&os->prettyName, 'r'))
{
if(os->variant.chars[0] == 'R' &&
isdigit(os->variant.chars[1]) &&
(os->variant.chars[2] == '\0' || os->variant.chars[2] == ' '))
{
ffStrbufAppendF(&os->version, " R%c", os->variant.chars[1]);
ffStrbufSubstrAfter(&os->variant, strlen("Rx ") - 1);
}
}
}
else
{
// Unknown Windows name, please report this
ffStrbufAppend(&os->name, &os->variant);
ffStrbufClear(&os->variant);
}
ffStrbufAppendF(&os->id, "%*s %*s", os->prettyName.length, os->prettyName.chars, os->version.length, os->version.chars);
record.getString(L"BuildNumber", &os->buildID);
record.getString(L"OSArchitecture", &os->architecture);
ffStrbufSetS(&os->systemName, instance->state.utsname.sysname);
}
else
{
// Unknown Windows name, please report this
ffStrbufAppend(&os->name, &os->variant);
ffStrbufClear(&os->variant);
}
ffStrbufAppendF(&os->id, "%*s %*s", os->prettyName.length, os->prettyName.chars, os->version.length, os->version.chars);
ffGetWmiObjString(pclsObj, L"BuildNumber", &os->buildID);
ffGetWmiObjString(pclsObj, L"OSArchitecture", &os->architecture);
ffStrbufSetS(&os->systemName, instance->state.utsname.sysname);
pclsObj->Release();
pEnumerator->Release();
}
+9 -14
View File
@@ -7,24 +7,19 @@ uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error)
{
FF_UNUSED(instance);
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT NumberOfProcesses FROM Win32_OperatingSystem", error);
if(!pEnumerator)
FFWmiQuery query(L"SELECT NumberOfProcesses FROM Win32_OperatingSystem", error);
if(!query)
return 0;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
if(FFWmiRecord record = query.next())
{
uint64_t result = 0;
record.getUnsigned(L"NumberOfProcesses", &result);
return (uint32_t)result;
}
else
{
ffStrbufAppendS(error, "No Wmi result returned");
pEnumerator->Release();
return 0;
}
uint64_t result = 0;
ffGetWmiObjUnsigned(pclsObj, L"NumberOfProcesses", &result);
pclsObj->Release();
pEnumerator->Release();
return (uint32_t)result;
}
@@ -65,45 +65,34 @@ static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrb
if(pid == 0)
pid = GetCurrentProcessId();
wchar_t query[256] = {};
swprintf(query, 256, L"SELECT %ls %ls ParentProcessId FROM Win32_Process WHERE ProcessId = %" PRIu32,
wchar_t sql[256] = {};
swprintf(sql, 256, L"SELECT %ls %ls ParentProcessId FROM Win32_Process WHERE ProcessId = %" PRIu32,
pname ? L"Name," : L"",
pname ? L"ExecutablePath," : L"",
pid);
IEnumWbemClassObject* pEnumerator = ffQueryWmi(query, nullptr);
if(!pEnumerator)
FFWmiQuery query(sql);
if(!query)
return false;
IWbemClassObject *pclsObj = nullptr;
ULONG uReturn = 0;
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
if(FFWmiRecord record = query.next())
{
pEnumerator->Release();
return false;
if(ppid)
{
uint64_t value;
record.getUnsigned(L"ParentProcessId", &value);
*ppid = (uint32_t) value;
}
if(pname)
record.getString(L"Name", pname);
if(exe)
record.getString(L"ExecutablePath", exe);
if(exeName)
*exeName = exe->chars + ffStrbufLastIndexC(exe, '\\') + 1;
}
if(ppid)
{
uint64_t value;
ffGetWmiObjUnsigned(pclsObj, L"ParentProcessId", &value);
*ppid = (uint32_t) value;
}
if(pname)
ffGetWmiObjString(pclsObj, L"Name", pname);
if(exe)
ffGetWmiObjString(pclsObj, L"ExecutablePath", exe);
if(exeName)
{
*exeName = exe->chars + ffStrbufLastIndexC(exe, '\\') + 1;
}
pclsObj->Release();
pEnumerator->Release();
return true;
}
+4 -11
View File
@@ -5,20 +5,16 @@ extern "C" {
void ffDetectUsers(FFlist* users, FFstrbuf* error)
{
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Antecedent FROM Win32_LoggedOnUser", error);
if(!pEnumerator)
FFWmiQuery query(L"SELECT Antecedent FROM Win32_LoggedOnUser", error);
if(!query)
return;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
next:
while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0)
while(FFWmiRecord record = query.next())
{
FFstrbuf antecedent;
ffStrbufInit(&antecedent);
ffGetWmiObjString(pclsObj, L"Antecedent", &antecedent); // \\.\root\cimv2:Win32_Account.Domain="DOMAIN",Name="NAME"
record.getString(L"Antecedent", &antecedent); // \\.\root\cimv2:Win32_Account.Domain="DOMAIN",Name="NAME"
ffStrbufTrimRight(&antecedent, '"'); // \\.\root\cimv2:Win32_Account.Domain="DOMAIN",Name="NAME
ffStrbufSubstrAfterFirstC(&antecedent, '"'); // DOMAIN",Name="NAME
uint32_t index = ffStrbufFirstIndexC(&antecedent, '"');
@@ -36,7 +32,4 @@ next:
if(users->length == 0)
ffStrbufAppendS(error, "Unable to detect users");
if(pclsObj) pclsObj->Release();
pEnumerator->Release();
}
+17 -25
View File
@@ -9,35 +9,27 @@ int uname(struct utsname *name)
strncpy(name->sysname, "Windows_NT", UTSNAME_MAXLENGTH);
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Version, CSName, OSArchitecture FROM Win32_OperatingSystem", nullptr);
if(!pEnumerator)
FFWmiQuery query(L"SELECT Version, CSName, OSArchitecture FROM Win32_OperatingSystem");
if(!query)
return -1;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
if(FFWmiRecord record = query.next())
{
pEnumerator->Release();
return -1;
FFstrbuf value;
ffStrbufInit(&value);
record.getString(L"Version", &value);
strncpy(name->release, value.chars, UTSNAME_MAXLENGTH);
ffStrbufClear(&value);
record.getString(L"CSName", &value);
strncpy(name->nodename, value.chars, UTSNAME_MAXLENGTH);
ffStrbufClear(&value);
record.getString(L"OSArchitecture", &value);
strncpy(name->machine, value.chars, UTSNAME_MAXLENGTH);
ffStrbufDestroy(&value);
}
FFstrbuf value;
ffStrbufInit(&value);
ffGetWmiObjString(pclsObj, L"Version", &value);
strncpy(name->release, value.chars, UTSNAME_MAXLENGTH);
ffStrbufClear(&value);
ffGetWmiObjString(pclsObj, L"CSName", &value);
strncpy(name->nodename, value.chars, UTSNAME_MAXLENGTH);
ffStrbufClear(&value);
ffGetWmiObjString(pclsObj, L"OSArchitecture", &value);
strncpy(name->machine, value.chars, UTSNAME_MAXLENGTH);
ffStrbufDestroy(&value);
pclsObj->Release();
pEnumerator->Release();
return 0;
}
+24 -12
View File
@@ -4,6 +4,21 @@
#include <wchar.h>
#include <math.h>
namespace
{
// Provide our bstr_t to avoid libstdc++ dependency
struct bstr_t
{
explicit bstr_t(const wchar_t* str) noexcept: _bstr(SysAllocString(str)) {}
~bstr_t() noexcept { SysFreeString(_bstr); }
explicit operator const wchar_t*() const noexcept { return _bstr; }
operator BSTR() const noexcept { return _bstr; }
private:
BSTR _bstr;
};
}
//https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-the-local-computer
//https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/computer-system-hardware-classes
static void CoUninitializeWrap()
@@ -105,8 +120,8 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext)
return TRUE;
}
IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error)
FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error)
: pEnumerator(nullptr)
{
static INIT_ONCE s_InitOnce = INIT_ONCE_STATIC_INIT;
const char* context;
@@ -114,11 +129,10 @@ IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error)
{
if(error)
ffStrbufInitS(error, context);
return nullptr;
return;
}
// Use the IWbemServices pointer to make requests of WMI
IEnumWbemClassObject* pEnumerator = nullptr;
HRESULT hres;
hres = ((IWbemServices*)context)->ExecQuery(
@@ -132,13 +146,11 @@ IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error)
{
if(error)
ffStrbufAppendF(error, "Query for '%ls' failed. Error code = 0x%lX", queryStr, hres);
return nullptr;
}
return pEnumerator;
}
void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) {
static void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf)
{
int len = (int)SysStringLen(bstr);
if(len <= 0)
{
@@ -152,7 +164,7 @@ void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) {
strbuf->chars[size_needed] = '\0';
}
bool ffGetWmiObjString(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf)
bool FFWmiRecord::getString(const wchar_t* key, FFstrbuf* strbuf)
{
bool result = true;
@@ -202,7 +214,7 @@ bool ffGetWmiObjString(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strb
return result;
}
bool ffGetWmiObjSigned(IWbemClassObject* obj, const wchar_t* key, int64_t* integer)
bool FFWmiRecord::getSigned(const wchar_t* key, int64_t* integer)
{
bool result = true;
@@ -237,7 +249,7 @@ bool ffGetWmiObjSigned(IWbemClassObject* obj, const wchar_t* key, int64_t* integ
return result;
}
bool ffGetWmiObjUnsigned(IWbemClassObject* obj, const wchar_t* key, uint64_t* integer)
bool FFWmiRecord::getUnsigned(const wchar_t* key, uint64_t* integer)
{
bool result = true;
@@ -271,7 +283,7 @@ bool ffGetWmiObjUnsigned(IWbemClassObject* obj, const wchar_t* key, uint64_t* in
return result;
}
bool ffGetWmiObjReal(IWbemClassObject* obj, const wchar_t* key, double* real)
bool FFWmiRecord::getReal(const wchar_t* key, double* real)
{
bool result = true;
+36 -17
View File
@@ -11,32 +11,51 @@ extern "C" {
#include <Wbemidl.h>
//<comdef.h> is not usable in MSYS, so provide our simple bstr_t implementation
struct bstr_t
struct FFWmiRecord
{
explicit bstr_t(const wchar_t* str) noexcept: _bstr(SysAllocString(str)) {}
IWbemClassObject* obj;
~bstr_t() noexcept { SysFreeString(_bstr); }
explicit FFWmiRecord(IEnumWbemClassObject* pEnumerator): obj(nullptr) {
if(!pEnumerator) return;
explicit operator const wchar_t*() const noexcept {
return _bstr;
ULONG ret;
bool ok = SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &obj, &ret)) && ret;
if(!ok) obj = nullptr;
}
operator BSTR() const noexcept {
return _bstr;
FFWmiRecord(const FFWmiRecord&) = delete;
FFWmiRecord(FFWmiRecord&& other) {
obj = other.obj;
other.obj = nullptr;
}
~FFWmiRecord() { if(obj) obj->Release(); }
explicit operator bool() { return !!obj; }
private:
BSTR _bstr;
bool getString(const wchar_t* key, FFstrbuf* strbuf);
bool getSigned(const wchar_t* key, int64_t* integer);
bool getUnsigned(const wchar_t* key, uint64_t* integer);
bool getReal(const wchar_t* key, double* real);
};
void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf);
struct FFWmiQuery
{
IEnumWbemClassObject* pEnumerator = nullptr;
IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error);
bool ffGetWmiObjString(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf);
bool ffGetWmiObjSigned(IWbemClassObject* obj, const wchar_t* key, int64_t* integer);
bool ffGetWmiObjUnsigned(IWbemClassObject* obj, const wchar_t* key, uint64_t* integer);
bool ffGetWmiObjReal(IWbemClassObject* obj, const wchar_t* key, double* real);
FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error = nullptr);
explicit FFWmiQuery(IEnumWbemClassObject* pEnumerator): pEnumerator(pEnumerator) {}
FFWmiQuery(const FFWmiQuery& other) = delete;
FFWmiQuery(FFWmiQuery&& other) {
pEnumerator = other.pEnumerator;
other.pEnumerator = nullptr;
}
~FFWmiQuery() { if(pEnumerator) pEnumerator->Release(); }
explicit operator bool() { return !!pEnumerator; }
FFWmiRecord next() {
FFWmiRecord result(pEnumerator);
return result;
}
};
#else
// Win32 COM headers requires C++ compiler