mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Windows: simplify WMI query code
by making C++ code more C++
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user