From 49921f5ed19e65d40c8cb7ecec243f6b99e135e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 6 Oct 2022 22:56:56 +0800 Subject: [PATCH] Disk: add support for Windows Also major refactoring of util/windows/wmi --- CMakeLists.txt | 4 +- src/detection/battery/battery_windows.cpp | 16 +- src/detection/bios/bios_windows.cpp | 8 +- src/detection/board/board_windows.cpp | 6 +- src/detection/disk/disk.c | 55 +++++++ src/detection/disk/disk.h | 10 ++ src/detection/disk/disk_apple.m | 4 +- src/detection/disk/disk_linux.c | 6 +- src/detection/disk/disk_windows.cpp | 48 ++++++ src/detection/gpu/gpu_windows.cpp | 6 +- src/detection/host/host_windows.cpp | 8 +- src/detection/os/os_windows.cpp | 6 +- src/detection/processes/processes_windows.cpp | 4 +- src/detection/users/users_windows.cpp | 2 +- src/modules/disk.c | 97 ++++------- src/util/windows/wmi.cpp | 153 +++++++++++++----- src/util/windows/wmi.hpp | 6 +- 17 files changed, 300 insertions(+), 139 deletions(-) create mode 100644 src/detection/disk/disk.c create mode 100644 src/detection/disk/disk_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bb2f1604..6b0060dff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -280,6 +280,7 @@ if(LINUX OR ANDROID OR BSD) list(APPEND LIBFASTFETCH_SRC src/detection/cpuUsage/cpuUsage_linux.c src/detection/disk/disk_linux.c + src/detection/disk/disk.c src/detection/poweradapter/poweradapter_linux.c src/detection/temps/temps_linux.c src/detection/users/users_linux.c @@ -321,6 +322,7 @@ if(WIN_MSYS) src/detection/users/users_windows.cpp src/detection/os/os_windows.cpp src/detection/processes/processes_windows.cpp + src/detection/disk/disk_windows.cpp src/util/windows/wmi.cpp # Shared @@ -333,7 +335,6 @@ if(WIN_MSYS) src/detection/cpu/cpu_linux.c src/detection/memory/memory_linux.c src/detection/cpuUsage/cpuUsage_linux.c - src/detection/disk/disk_linux.c src/detection/temps/temps_linux.c ) endif() @@ -356,6 +357,7 @@ if(APPLE) src/detection/terminalfont/terminalfont_apple.m src/detection/media/media_apple.m src/detection/disk/disk_apple.m + src/detection/disk/disk.c src/detection/wmtheme/wmtheme_apple.m src/detection/temps/temps_apple.c src/detection/font/font_apple.m diff --git a/src/detection/battery/battery_windows.cpp b/src/detection/battery/battery_windows.cpp index 9c84a3bf7..48084720a 100644 --- a/src/detection/battery/battery_windows.cpp +++ b/src/detection/battery/battery_windows.cpp @@ -21,13 +21,13 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) BatteryResult* battery = (BatteryResult*)ffListAdd(results); ffStrbufInit(&battery->manufacturer); - ffGetWmiObjValue(pclsObj, L"SystemName", &battery->manufacturer); + ffGetWmiObjString(pclsObj, L"SystemName", &battery->manufacturer); ffStrbufInit(&battery->modelName); - ffGetWmiObjValue(pclsObj, L"Name", &battery->modelName); + ffGetWmiObjString(pclsObj, L"Name", &battery->modelName); - int64_t chemistry; - ffGetWmiObjInteger(pclsObj, L"Chemistry", &chemistry); + uint64_t chemistry; + ffGetWmiObjUnsigned(pclsObj, L"Chemistry", &chemistry); switch(chemistry) { case 1: ffStrbufInitS(&battery->technology, "Other"); break; @@ -40,12 +40,12 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) case 8: ffStrbufInitS(&battery->technology, "Lithium Polymer"); break; } - int64_t capacity; - ffGetWmiObjInteger(pclsObj, L"EstimatedChargeRemaining", &capacity); + uint64_t capacity; + ffGetWmiObjUnsigned(pclsObj, L"EstimatedChargeRemaining", &capacity); ffStrbufInitF(&battery->capacity, "%d", (int)capacity); - int64_t batteryStatus; - ffGetWmiObjInteger(pclsObj, L"BatteryStatus", &batteryStatus); + uint64_t batteryStatus; + ffGetWmiObjUnsigned(pclsObj, L"BatteryStatus", &batteryStatus); switch(batteryStatus) { case 1: ffStrbufInitS(&battery->status, "Discharging"); break; diff --git a/src/detection/bios/bios_windows.cpp b/src/detection/bios/bios_windows.cpp index 6f1dedbb8..d04726ebb 100644 --- a/src/detection/bios/bios_windows.cpp +++ b/src/detection/bios/bios_windows.cpp @@ -28,10 +28,10 @@ extern "C" void ffDetectBios(FFBiosResult* bios) return; } - ffGetWmiObjValue(pclsObj, L"Name", &bios->biosRelease); - ffGetWmiObjValue(pclsObj, L"ReleaseDate", &bios->biosDate); - ffGetWmiObjValue(pclsObj, L"Version", &bios->biosVersion); - ffGetWmiObjValue(pclsObj, 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(); diff --git a/src/detection/board/board_windows.cpp b/src/detection/board/board_windows.cpp index 5709a4eb1..895d6f8ed 100644 --- a/src/detection/board/board_windows.cpp +++ b/src/detection/board/board_windows.cpp @@ -27,9 +27,9 @@ extern "C" void ffDetectBoard(FFBoardResult* board) return; } - ffGetWmiObjValue(pclsObj, L"Product", &board->boardName); - ffGetWmiObjValue(pclsObj, L"Manufacturer", &board->boardVendor); - ffGetWmiObjValue(pclsObj, 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(); diff --git a/src/detection/disk/disk.c b/src/detection/disk/disk.c new file mode 100644 index 000000000..325eab362 --- /dev/null +++ b/src/detection/disk/disk.c @@ -0,0 +1,55 @@ +#include "fastfetch.h" +#include "disk.h" + +#include + +void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result) +{ + ffStrbufInitS(&result->path, folderPath); + result->used = result->total = 0; + ffStrbufInit(&result->error); + + struct statvfs newFs; + + if(fs == NULL) + { + fs = &newFs; + int ret = statvfs(folderPath, fs); + if(ret != 0) + { + ffStrbufAppendF(&result->error, "statvfs(\"%s\", &fs) != 0 (%i)", folderPath, ret); + return; + } + } + + result->total = fs->f_blocks * fs->f_frsize; + + if(result->total == 0) + { + ffStrbufAppendF(&result->error, "statvfs for %s returned size 0", folderPath); + return; + } + + result->used = result->total - (fs->f_bavail * fs->f_frsize); + result->files = (uint32_t) (fs->f_files - fs->f_ffree); +} + +bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders) +{ + ffStrbufTrim(&instance->config.diskFolders, ':'); + if(instance->config.diskFolders.length == 0) + return false; + + uint32_t startIndex = 0; + while(startIndex < instance->config.diskFolders.length) + { + uint32_t colonIndex = ffStrbufNextIndexC(&instance->config.diskFolders, startIndex, ':'); + instance->config.diskFolders.chars[colonIndex] = '\0'; + + ffDetectDiskWithStatvfs(instance->config.diskFolders.chars + startIndex, NULL, (FFDiskResult*)ffListAdd(folders)); + + startIndex = colonIndex + 1; + } + + return true; +} diff --git a/src/detection/disk/disk.h b/src/detection/disk/disk.h index aaf34a608..06b00b666 100644 --- a/src/detection/disk/disk.h +++ b/src/detection/disk/disk.h @@ -5,6 +5,16 @@ #include "fastfetch.h" +typedef struct FFDiskResult +{ + FFstrbuf path; + uint64_t used; + uint64_t total; + uint32_t files; + FFstrbuf error; +} FFDiskResult; + const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders); +bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders); #endif diff --git a/src/detection/disk/disk_apple.m b/src/detection/disk/disk_apple.m index 95d5fd8ec..391ec457f 100644 --- a/src/detection/disk/disk_apple.m +++ b/src/detection/disk/disk_apple.m @@ -2,6 +2,8 @@ #import +void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result); + const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) { NSArray *keys = [NSArray arrayWithObjects:NSURLVolumeNameKey, nil]; @@ -18,7 +20,7 @@ const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) if(removable.boolValue && !instance->config.diskRemovable) continue; - ffStrbufInitS((FFstrbuf *)ffListAdd(folders), [url.relativePath cStringUsingEncoding:NSUTF8StringEncoding]); + ffDetectDiskWithStatvfs([url.relativePath cStringUsingEncoding:NSUTF8StringEncoding], NULL, (FFDiskResult*)ffListAdd(folders)); } return NULL; diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index 80d5808c4..eb8ceb0f3 100644 --- a/src/detection/disk/disk_linux.c +++ b/src/detection/disk/disk_linux.c @@ -2,6 +2,8 @@ #include +void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result); + const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) { FF_UNUSED(instance); @@ -11,12 +13,12 @@ const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) if(rootRet != 0) return "statvfs(\"/\") failed"; - ffStrbufInitS((FFstrbuf *)ffListAdd(folders), FASTFETCH_TARGET_DIR_ROOT"/"); + ffDetectDiskWithStatvfs(FASTFETCH_TARGET_DIR_ROOT"/", &fsRoot, (FFDiskResult*)ffListAdd(folders)); struct statvfs fsHome; int homeRet = statvfs(FASTFETCH_TARGET_DIR_HOME, &fsHome); if(homeRet == 0 && (fsRoot.f_fsid != fsHome.f_fsid)) - ffStrbufInitS((FFstrbuf *)ffListAdd(folders), FASTFETCH_TARGET_DIR_HOME); + ffDetectDiskWithStatvfs(FASTFETCH_TARGET_DIR_HOME, &fsHome, (FFDiskResult*)ffListAdd(folders)); return NULL; } diff --git a/src/detection/disk/disk_windows.cpp b/src/detection/disk/disk_windows.cpp new file mode 100644 index 000000000..3a7fb20a0 --- /dev/null +++ b/src/detection/disk/disk_windows.cpp @@ -0,0 +1,48 @@ +extern "C" { +#include "disk.h" +} +#include "util/windows/wmi.hpp" + +const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) +{ + FF_UNUSED(instance); + + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, DriveType, FreeSpace, Size FROM Win32_LogicalDisk", nullptr); + + if(!pEnumerator) + return "Query WMI service failed"; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0) + { + uint64_t driveType; + ffGetWmiObjUnsigned(pclsObj, L"DriveType", &driveType); + if(driveType == 2 && !instance->config.diskRemovable) + continue; + + FFDiskResult* folder = (FFDiskResult*)ffListAdd(folders); + + ffStrbufInit(&folder->path); + ffGetWmiObjString(pclsObj, L"Name", &folder->path); + + uint64_t free; + ffGetWmiObjUnsigned(pclsObj, L"Size", &folder->total); + ffGetWmiObjUnsigned(pclsObj, L"FreeSpace", &free); + folder->used = folder->total - free; + + folder->files = 0; //Unsupported + + ffStrbufInit(&folder->error); + } + + pclsObj->Release(); + pEnumerator->Release(); + return nullptr; +} + +bool ffDiskDetectDiskFolders(FFinstance*, FFlist*) +{ + return false; // Unsupported +} diff --git a/src/detection/gpu/gpu_windows.cpp b/src/detection/gpu/gpu_windows.cpp index 90a6fd264..443ad422e 100644 --- a/src/detection/gpu/gpu_windows.cpp +++ b/src/detection/gpu/gpu_windows.cpp @@ -21,7 +21,7 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus); ffStrbufInit(&gpu->vendor); - ffGetWmiObjValue(pclsObj, L"AdapterCompatibility", &gpu->vendor); + ffGetWmiObjString(pclsObj, L"AdapterCompatibility", &gpu->vendor); if(ffStrbufStartsWithS(&gpu->vendor, "Intel ")) { //Intel returns "Intel Corporation", not sure about AMD @@ -29,10 +29,10 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) } ffStrbufInit(&gpu->name); - ffGetWmiObjValue(pclsObj, L"Name", &gpu->name); + ffGetWmiObjString(pclsObj, L"Name", &gpu->name); ffStrbufInit(&gpu->driver); - ffGetWmiObjValue(pclsObj, L"DriverVersion", &gpu->driver); + ffGetWmiObjString(pclsObj, L"DriverVersion", &gpu->driver); gpu->temperature = FF_GPU_TEMP_UNSET; gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; diff --git a/src/detection/host/host_windows.cpp b/src/detection/host/host_windows.cpp index 3af7dadf1..34141cf72 100644 --- a/src/detection/host/host_windows.cpp +++ b/src/detection/host/host_windows.cpp @@ -32,10 +32,10 @@ extern "C" void ffDetectHostImpl(FFHostResult* host) return; } - ffGetWmiObjValue(pclsObj, L"Name", &host->productName); - ffGetWmiObjValue(pclsObj, L"Version", &host->productVersion); - ffGetWmiObjValue(pclsObj, L"SKUNumber", &host->productSku); - ffGetWmiObjValue(pclsObj, 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(); diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index 5a20cbf2b..77f6644bf 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -33,7 +33,7 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) return; } - ffGetWmiObjValue(pclsObj, L"Caption", &os->variant); // Microsoft Windows 11 家庭中文版 + ffGetWmiObjString(pclsObj, L"Caption", &os->variant); // Microsoft Windows 11 家庭中文版 if(ffStrbufStartsWithS(&os->variant, "Microsoft Windows ")) { ffStrbufAppendS(&os->name, "Microsoft Windows"); @@ -58,8 +58,8 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufAppendF(&os->id, "Windows %*s", &os->version.length, &os->version.chars); #endif - ffGetWmiObjValue(pclsObj, L"BuildNumber", &os->buildID); - ffGetWmiObjValue(pclsObj, L"OSArchitecture", &os->architecture); + ffGetWmiObjString(pclsObj, L"BuildNumber", &os->buildID); + ffGetWmiObjString(pclsObj, L"OSArchitecture", &os->architecture); #ifdef __CYGWIN__ ffStrbufSetS(&os->systemName, instance->state.utsname.sysname); diff --git a/src/detection/processes/processes_windows.cpp b/src/detection/processes/processes_windows.cpp index e6539f370..5d491d16e 100644 --- a/src/detection/processes/processes_windows.cpp +++ b/src/detection/processes/processes_windows.cpp @@ -22,8 +22,8 @@ uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) return 0; } - int64_t result = 0; - ffGetWmiObjInteger(pclsObj, L"NumberOfProcesses", &result); + uint64_t result = 0; + ffGetWmiObjUnsigned(pclsObj, L"NumberOfProcesses", &result); pclsObj->Release(); pEnumerator->Release(); return (uint32_t)result; diff --git a/src/detection/users/users_windows.cpp b/src/detection/users/users_windows.cpp index 7728c1ff3..43a6fb3d2 100644 --- a/src/detection/users/users_windows.cpp +++ b/src/detection/users/users_windows.cpp @@ -18,7 +18,7 @@ next: { FFstrbuf antecedent; ffStrbufInit(&antecedent); - ffGetWmiObjValue(pclsObj, L"Antecedent", &antecedent); // \\.\root\cimv2:Win32_Account.Domain="DOMAIN",Name="NAME" + ffGetWmiObjString(pclsObj, 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, '"'); diff --git a/src/modules/disk.c b/src/modules/disk.c index ea92f7e89..22751e097 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -8,111 +8,76 @@ #define FF_DISK_MODULE_NAME "Disk" #define FF_DISK_NUM_FORMAT_ARGS 4 -static void createKey(FFinstance* instance, const char* folderPath, FFstrbuf* key) +static void printFolder(FFinstance* instance, FFDiskResult* folder) { + FFstrbuf key; + ffStrbufInit(&key); + if(instance->config.disk.key.length == 0) { - ffStrbufAppendS(key, FF_DISK_MODULE_NAME); - if(folderPath != NULL) - ffStrbufAppendF(key, " (%s)", folderPath); + ffStrbufAppendF(&key, "%s (%*s)", FF_DISK_MODULE_NAME, folder->path.length, folder->path.chars); } else { - ffParseFormatString(key, &instance->config.disk.key, 1, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRING, folderPath} + ffParseFormatString(&key, &instance->config.disk.key, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &folder->path} }); } -} -static void printStatvfs(FFinstance* instance, const FFstrbuf* key, const char* folderPath, struct statvfs* fs) -{ - uint64_t total = fs->f_blocks * fs->f_frsize; - - if(total == 0) - { - ffPrintErrorString(instance, key->chars, 0, NULL, &instance->config.disk.errorFormat, "statvfs for %s returned size 0", folderPath); - return; - } - - uint64_t used = total - (fs->f_bavail * fs->f_frsize); - uint32_t files = (uint32_t) (fs->f_files - fs->f_ffree); - uint8_t percentage = (uint8_t) ((used / (long double) total) * 100.0); + uint8_t percentage = (uint8_t) ((folder->used / (long double) folder->total) * 100.0); FFstrbuf usedPretty; ffStrbufInit(&usedPretty); - ffParseSize(used, instance->config.binaryPrefixType, &usedPretty); + ffParseSize(folder->used, instance->config.binaryPrefixType, &usedPretty); FFstrbuf totalPretty; ffStrbufInit(&totalPretty); - ffParseSize(total, instance->config.binaryPrefixType, &totalPretty); + ffParseSize(folder->total, instance->config.binaryPrefixType, &totalPretty); if(instance->config.disk.outputFormat.length == 0) { - ffPrintLogoAndKey(instance, key->chars, 0, NULL); + ffPrintLogoAndKey(instance, key.chars, 0, NULL); printf("%s / %s (%u%%)\n", usedPretty.chars, totalPretty.chars, percentage); } else { - ffPrintFormatString(instance, key->chars, 0, NULL, &instance->config.disk.outputFormat, FF_DISK_NUM_FORMAT_ARGS, (FFformatarg[]){ + ffPrintFormatString(instance, key.chars, 0, NULL, &instance->config.disk.outputFormat, FF_DISK_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, {FF_FORMAT_ARG_TYPE_UINT8, &percentage}, - {FF_FORMAT_ARG_TYPE_UINT, &files}, + {FF_FORMAT_ARG_TYPE_UINT, &folder->files}, }); } + ffStrbufDestroy(&key); ffStrbufDestroy(&totalPretty); ffStrbufDestroy(&usedPretty); } -static void printFolder(FFinstance* instance, const char* folderPath) -{ - FFstrbuf key; - ffStrbufInit(&key); - createKey(instance, folderPath, &key); - - struct statvfs fs; - int ret = statvfs(folderPath, &fs); - if(ret != 0) - { - ffPrintErrorString(instance, key.chars, 0, NULL, &instance->config.disk.errorFormat, "statvfs(\"%s\", &fs) != 0 (%i)", folderPath, ret); - ffStrbufDestroy(&key); - return; - } - - printStatvfs(instance, &key, folderPath, &fs); - ffStrbufDestroy(&key); -} - void ffPrintDisk(FFinstance* instance) { - ffStrbufTrim(&instance->config.diskFolders, ':'); + FFlist folders; + ffListInit(&folders, sizeof(FFDiskResult)); - if(instance->config.diskFolders.length == 0) + const char* error = NULL; + + if(!ffDiskDetectDiskFolders(instance, &folders)) + error = ffDiskAutodetectFolders(instance, &folders); + + if(error) + { + ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "%s", error); + } + else { - FFlist folders; - ffListInit(&folders, sizeof(FFstrbuf)); - const char* error = ffDiskAutodetectFolders(instance, &folders); - if(error) - ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "%s", error); for(uint32_t i = 0; i < folders.length; ++i) { - FFstrbuf* folder = (FFstrbuf*)ffListGet(&folders, i); - printFolder(instance, folder->chars); - ffStrbufDestroy(folder); + FFDiskResult* folder = (FFDiskResult*)ffListGet(&folders, i); + printFolder(instance, folder); + ffStrbufDestroy(&folder->path); + ffStrbufDestroy(&folder->error); } - ffListDestroy(&folders); - return; } - uint32_t startIndex = 0; - while(startIndex < instance->config.diskFolders.length) - { - uint32_t colonIndex = ffStrbufNextIndexC(&instance->config.diskFolders, startIndex, ':'); - instance->config.diskFolders.chars[colonIndex] = '\0'; - - printFolder(instance, instance->config.diskFolders.chars + startIndex); - - startIndex = colonIndex + 1; - } + ffListDestroy(&folders); } diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index b79fb33a4..845a3dda4 100644 --- a/src/util/windows/wmi.cpp +++ b/src/util/windows/wmi.cpp @@ -1,6 +1,7 @@ #include "wmi.hpp" #include +#include //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 @@ -148,7 +149,7 @@ void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) { strbuf->chars[size_needed] = '\0'; } -bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf) +bool ffGetWmiObjString(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf) { bool result = true; @@ -156,49 +157,49 @@ bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbu VariantInit(&vtProp); CIMTYPE type; - if(FAILED(obj->Get(key, 0, &vtProp, &type, nullptr)) || vtProp.vt == VT_EMPTY || vtProp.vt == VT_NULL) + if(FAILED(obj->Get(key, 0, &vtProp, &type, nullptr)) || vtProp.vt != VT_BSTR) { result = false; } else { - switch(type) + switch(vtProp.vt) { - case CIM_ILLEGAL: - case CIM_EMPTY: result = false; break; - case CIM_SINT8: ffStrbufAppendF(strbuf, "%d", (int)vtProp.cVal); break; - case CIM_SINT16: ffStrbufAppendF(strbuf, "%d", (int)vtProp.iVal); break; - case CIM_SINT32: ffStrbufAppendF(strbuf, "%d", (int)vtProp.intVal); break; - case CIM_SINT64: ffStrbufAppendF(strbuf, "%lld", vtProp.llVal); break; - case CIM_UINT8: ffStrbufAppendF(strbuf, "%u", (unsigned)vtProp.bVal); break; - case CIM_UINT16: ffStrbufAppendF(strbuf, "%u", (unsigned)vtProp.uiVal); break; - case CIM_UINT32: ffStrbufAppendF(strbuf, "%u", (unsigned)vtProp.uintVal); break; - case CIM_UINT64: ffStrbufAppendF(strbuf, "%llu", vtProp.ullVal); break; - case CIM_REAL32: ffStrbufAppendF(strbuf, "%f", vtProp.fltVal); break; - case CIM_REAL64: ffStrbufAppendF(strbuf, "%f", vtProp.dblVal); break; - case CIM_BOOLEAN: ffStrbufAppendF(strbuf, "%s", vtProp.boolVal ? "True" : "False"); break; - case CIM_DATETIME: { - ISWbemDateTime *pDateTime; - BSTR dateStr; - if(FAILED(CoCreateInstance(__uuidof(SWbemDateTime), 0, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDateTime)))) - result = false; - else if(FAILED(pDateTime->put_Value(vtProp.bstrVal))) - result = false; - else if(FAILED(pDateTime->GetFileTime(VARIANT_TRUE, &dateStr))) - result = false; + case VT_BSTR: + if(type == CIM_DATETIME) + { + ISWbemDateTime *pDateTime; + BSTR dateStr; + if(FAILED(CoCreateInstance(__uuidof(SWbemDateTime), 0, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDateTime)))) + result = false; + else if(FAILED(pDateTime->put_Value(vtProp.bstrVal))) + result = false; + else if(FAILED(pDateTime->GetFileTime(VARIANT_TRUE, &dateStr))) + result = false; + else + ffBstrToStrbuf(dateStr, strbuf); + } else - ffBstrToStrbuf(dateStr, strbuf); + { + ffBstrToStrbuf(vtProp.bstrVal, strbuf); + } + break; + + case VT_LPSTR: + ffStrbufAppendS(strbuf, vtProp.pcVal); + break; + + case VT_LPWSTR: // TODO + default: + result = false; break; - }; - case CIM_STRING: - default: ffBstrToStrbuf(vtProp.bstrVal, strbuf); break; } } VariantClear(&vtProp); return result; } -bool ffGetWmiObjInteger(IWbemClassObject* obj, const wchar_t* key, int64_t* integer) +bool ffGetWmiObjSigned(IWbemClassObject* obj, const wchar_t* key, int64_t* integer) { bool result = true; @@ -212,16 +213,90 @@ bool ffGetWmiObjInteger(IWbemClassObject* obj, const wchar_t* key, int64_t* inte } else { - switch(type) + switch(vtProp.vt) { - case CIM_SINT8: *integer = vtProp.cVal; break; - case CIM_SINT16: *integer = vtProp.iVal; break; - case CIM_SINT32: *integer = vtProp.intVal; break; - case CIM_SINT64: *integer = vtProp.llVal; break; - case CIM_UINT8: *integer = (int64_t)vtProp.bVal; break; - case CIM_UINT16: *integer = (int64_t)vtProp.uiVal; break; - case CIM_UINT32: *integer = (int64_t)vtProp.uintVal; break; - case CIM_UINT64: *integer = (int64_t)vtProp.ullVal; break; + case VT_BSTR: *integer = wcstoll(vtProp.bstrVal, nullptr, 10); break; + case VT_I1: *integer = vtProp.cVal; break; + case VT_I2: *integer = vtProp.iVal; break; + case VT_INT: + case VT_I4: *integer = vtProp.intVal; break; + case VT_I8: *integer = vtProp.llVal; break; + case VT_UI1: *integer = (int64_t)vtProp.bVal; break; + case VT_UI2: *integer = (int64_t)vtProp.uiVal; break; + case VT_UINT: + case VT_UI4: *integer = (int64_t)vtProp.uintVal; break; + case VT_UI8: *integer = (int64_t)vtProp.ullVal; break; + case VT_BOOL: *integer = vtProp.boolVal != VARIANT_FALSE; break; + default: result = false; + } + } + VariantClear(&vtProp); + return result; +} + +bool ffGetWmiObjUnsigned(IWbemClassObject* obj, const wchar_t* key, uint64_t* integer) +{ + bool result = true; + + VARIANT vtProp; + VariantInit(&vtProp); + + if(FAILED(obj->Get(key, 0, &vtProp, nullptr, nullptr))) + { + result = false; + } + else + { + switch(vtProp.vt) + { + case VT_BSTR: *integer = wcstoull(vtProp.bstrVal, nullptr, 10); break; + case VT_I1: *integer = (uint64_t)vtProp.cVal; break; + case VT_I2: *integer = (uint64_t)vtProp.iVal; break; + case VT_INT: + case VT_I4: *integer = (uint64_t)vtProp.intVal; break; + case VT_I8: *integer = (uint64_t)vtProp.llVal; break; + case VT_UI1: *integer = vtProp.bVal; break; + case VT_UI2: *integer = vtProp.uiVal; break; + case VT_UINT: + case VT_UI4: *integer = vtProp.uintVal; break; + case VT_UI8: *integer = vtProp.ullVal; break; + case VT_BOOL: *integer = vtProp.boolVal != VARIANT_FALSE; break; + default: result = false; + } + } + VariantClear(&vtProp); + return result; +} + +bool ffGetWmiObjReal(IWbemClassObject* obj, const wchar_t* key, double* real) +{ + bool result = true; + + VARIANT vtProp; + VariantInit(&vtProp); + + if(FAILED(obj->Get(key, 0, &vtProp, nullptr, nullptr))) + { + result = false; + } + else + { + switch(vtProp.vt) + { + case VT_BSTR: *real = wcstod(vtProp.bstrVal, nullptr); break; + case VT_I1: *real = vtProp.cVal; break; + case VT_I2: *real = vtProp.iVal; break; + case VT_INT: + case VT_I4: *real = vtProp.intVal; break; + case VT_I8: *real = (double)vtProp.llVal; break; + case VT_UI1: *real = vtProp.bVal; break; + case VT_UI2: *real = vtProp.uiVal; break; + case VT_UINT: + case VT_UI4: *real = vtProp.uintVal; break; + case VT_UI8: *real = (double)vtProp.ullVal; break; + case VT_R4: *real = vtProp.fltVal; break; + case VT_R8: *real = vtProp.dblVal; break; + case VT_BOOL: *real = vtProp.boolVal != VARIANT_FALSE; break; default: result = false; } } diff --git a/src/util/windows/wmi.hpp b/src/util/windows/wmi.hpp index 827fc88c6..53122dfa2 100644 --- a/src/util/windows/wmi.hpp +++ b/src/util/windows/wmi.hpp @@ -33,8 +33,10 @@ private: void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf); IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error); -bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf); -bool ffGetWmiObjInteger(IWbemClassObject* obj, const wchar_t* key, int64_t* result); +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); #else // Win32 COM headers requires C++ compiler