mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
WMI (Windows): code refactor
This commit is contained in:
@@ -3,6 +3,7 @@ extern "C"
|
||||
#include "brightness.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
#include "util/windows/unicode.hpp"
|
||||
|
||||
extern "C"
|
||||
const char* ffDetectBrightness(FFlist* result)
|
||||
@@ -13,15 +14,19 @@ const char* ffDetectBrightness(FFlist* result)
|
||||
|
||||
while(FFWmiRecord record = query.next())
|
||||
{
|
||||
FFBrightnessResult* display = (FFBrightnessResult*) ffListAdd(result);
|
||||
ffStrbufInit(&display->name);
|
||||
record.getString(L"InstanceName", &display->name);
|
||||
ffStrbufSubstrAfterFirstC(&display->name, '\\');
|
||||
ffStrbufSubstrBeforeFirstC(&display->name, '\\');
|
||||
if(FFWmiVariant vtValue = record.get(L"CurrentBrightness"))
|
||||
{
|
||||
FFBrightnessResult* display = (FFBrightnessResult*) ffListAdd(result);
|
||||
display->value = vtValue.get<uint8_t>();
|
||||
|
||||
uint64_t brightness;
|
||||
record.getUnsigned(L"CurrentBrightness", &brightness);
|
||||
display->value = (float) brightness;
|
||||
ffStrbufInit(&display->name);
|
||||
if (FFWmiVariant vtName = record.get(L"InstanceName"))
|
||||
{
|
||||
ffStrbufSetWSV(&display->name, vtName.get<std::wstring_view>());
|
||||
ffStrbufSubstrAfterFirstC(&display->name, '\\');
|
||||
ffStrbufSubstrBeforeFirstC(&display->name, '\\');
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ extern "C" {
|
||||
#include "util/windows/registry.h"
|
||||
#include "util/smbiosHelper.h"
|
||||
}
|
||||
#include "util/windows/unicode.hpp"
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
static const char* detectWithRegistry(FFChassisResult* result)
|
||||
@@ -31,26 +32,33 @@ FF_MAYBE_UNUSED static const char* detectWithWmi(FFChassisResult* result)
|
||||
|
||||
if (FFWmiRecord record = query.next())
|
||||
{
|
||||
FFWmiVariant vtProp;
|
||||
if(FAILED(record.obj->Get(L"ChassisTypes", 0, &vtProp, nullptr, nullptr)))
|
||||
if (auto vtProp = record.get(L"ChassisTypes"))
|
||||
{
|
||||
auto [arr, len] = vtProp.get<std::pair<const int32_t*, uint32_t>>();
|
||||
if(len == 0)
|
||||
return "ChassisTypes contain no data failed";
|
||||
for (uint32_t i = 0; i < len; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
ffStrbufAppendS(&result->type, ", ");
|
||||
ffStrbufAppendS(&result->type, ffChassisTypeToString((uint32_t) arr[i]));
|
||||
}
|
||||
}
|
||||
else
|
||||
return "Get ChassisTypes failed";
|
||||
|
||||
auto [arr, len] = (std::pair<const int32_t*, uint32_t>) vtProp;
|
||||
|
||||
if(len == 0)
|
||||
return "ChassisTypes contain no data failed";
|
||||
|
||||
for (uint32_t i = 0; i < len; ++i)
|
||||
if (auto vtProp = record.get(L"Version"))
|
||||
{
|
||||
if (i > 0)
|
||||
ffStrbufAppendS(&result->type, ", ");
|
||||
ffStrbufAppendS(&result->type, ffChassisTypeToString((uint32_t) arr[i]));
|
||||
ffStrbufSetWSV(&result->version, vtProp.get<std::wstring_view>());
|
||||
ffCleanUpSmbiosValue(&result->version);
|
||||
}
|
||||
|
||||
if (auto vtProp = record.get(L"Manufacturer"))
|
||||
{
|
||||
ffStrbufSetWSV(&result->vendor, vtProp.get<std::wstring_view>());
|
||||
ffCleanUpSmbiosValue(&result->vendor);
|
||||
}
|
||||
|
||||
record.getString(L"Version", &result->version);
|
||||
ffCleanUpSmbiosValue(&result->version);
|
||||
record.getString(L"Manufacturer", &result->vendor);
|
||||
ffCleanUpSmbiosValue(&result->vendor);
|
||||
return NULL;
|
||||
}
|
||||
return "No WMI result returned";
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
extern "C" {
|
||||
#include "os.h"
|
||||
#include "util/windows/unicode.h"
|
||||
#include "common/library.h"
|
||||
}
|
||||
#include "util/windows/unicode.hpp"
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
static const char* getOsNameByWmi(FFstrbuf* osName)
|
||||
@@ -12,9 +13,13 @@ static const char* getOsNameByWmi(FFstrbuf* osName)
|
||||
|
||||
if(FFWmiRecord record = query.next())
|
||||
{
|
||||
record.getString(L"Caption", osName);
|
||||
ffStrbufTrimRight(osName, ' ');
|
||||
return NULL;
|
||||
if(auto vtCaption = record.get(L"Caption"))
|
||||
{
|
||||
ffStrbufSetWSV(osName, vtCaption.get<std::wstring_view>());
|
||||
ffStrbufTrimRight(osName, ' ');
|
||||
return NULL;
|
||||
}
|
||||
return "Get Caption failed";
|
||||
}
|
||||
|
||||
return "No WMI result returned";
|
||||
@@ -29,9 +34,9 @@ static const char* getOsNameByWinbrand(FFstrbuf* osName)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(winbrand, BrandingFormatString);
|
||||
|
||||
const wchar_t* rawName = ffBrandingFormatString(L"%WINDOWS_LONG%");
|
||||
ffStrbufSetWS(osName, rawName);
|
||||
GlobalFree((HGLOBAL)rawName);
|
||||
return NULL;
|
||||
ffStrbufSetWS(osName, rawName);
|
||||
GlobalFree((HGLOBAL)rawName);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
|
||||
@@ -15,10 +15,21 @@ const char* ffDetectSmbiosTemp(double* current, double* critical)
|
||||
|
||||
if(FFWmiRecord record = query.next())
|
||||
{
|
||||
if (current && record.getReal(L"CurrentTemperature", current)) // In tenth of degrees Kelvin
|
||||
*current = *current / 10 - 273.15;
|
||||
if (critical && record.getReal(L"CriticalTripPoint", critical)) // In tenth of degrees Kelvin
|
||||
*critical = *critical / 10 - 273.15;
|
||||
if (current)
|
||||
{
|
||||
if(auto vtCurrent = record.get(L"CurrentTemperature"))
|
||||
*current = vtCurrent.get<int32_t>() / 10 - 273.15; // In tenth of degrees Kelvin
|
||||
else
|
||||
*current = 0.0/0.0;
|
||||
}
|
||||
|
||||
if (critical)
|
||||
{
|
||||
if(auto vtCritical = record.get(L"CriticalTripPoint"))
|
||||
*critical = vtCritical.get<int32_t>() / 10 - 273.15; // In tenth of degrees Kelvin
|
||||
else
|
||||
*critical = 0.0/0.0;
|
||||
}
|
||||
}
|
||||
|
||||
return "No WMI result returned";
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FASTFETCH_INCLUDED_UNICODE_HPP
|
||||
#define FASTFETCH_INCLUDED_UNICODE_HPP
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
extern "C" {
|
||||
#include "unicode.h"
|
||||
}
|
||||
|
||||
#include <string_view>
|
||||
|
||||
static inline void ffStrbufSetWSV(FFstrbuf* result, const std::wstring_view source)
|
||||
{
|
||||
return ffStrbufSetNWS(result, (uint32_t) source.size(), source.data());
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error Must be included in C++ source file
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,9 +1,6 @@
|
||||
#include "wmi.hpp"
|
||||
#include "util/windows/com.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "util/windows/unicode.h"
|
||||
}
|
||||
#include "util/windows/unicode.hpp"
|
||||
|
||||
#include <synchapi.h>
|
||||
#include <wchar.h>
|
||||
@@ -129,21 +126,6 @@ FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace
|
||||
}
|
||||
}
|
||||
|
||||
static void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf)
|
||||
{
|
||||
int len = (int)SysStringLen(bstr);
|
||||
if(len <= 0)
|
||||
{
|
||||
ffStrbufClear(strbuf);
|
||||
return;
|
||||
}
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, bstr, len, nullptr, 0, nullptr, nullptr);
|
||||
ffStrbufEnsureFree(strbuf, (uint32_t)size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, bstr, len, strbuf->chars, size_needed, nullptr, nullptr);
|
||||
strbuf->length = (uint32_t)size_needed;
|
||||
strbuf->chars[size_needed] = '\0';
|
||||
}
|
||||
|
||||
bool FFWmiRecord::getString(const wchar_t* key, FFstrbuf* strbuf)
|
||||
{
|
||||
bool result = true;
|
||||
@@ -171,11 +153,11 @@ bool FFWmiRecord::getString(const wchar_t* key, FFstrbuf* strbuf)
|
||||
else if(FAILED(pDateTime->GetFileTime(VARIANT_TRUE, &dateStr)))
|
||||
result = false;
|
||||
else
|
||||
ffBstrToStrbuf(dateStr, strbuf);
|
||||
ffStrbufSetNWS(strbuf, SysStringLen(dateStr), dateStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffBstrToStrbuf(vtProp.bstrVal, strbuf);
|
||||
ffStrbufSetWS(strbuf, SysStringLen(vtProp.bstrVal), vtProp.bstrVal);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+132
-111
@@ -25,6 +25,133 @@ enum {
|
||||
FF_WMI_QUERY_TIMEOUT = 5000
|
||||
};
|
||||
|
||||
struct FFWmiVariant: VARIANT {
|
||||
explicit FFWmiVariant() { VariantInit(this); }
|
||||
~FFWmiVariant() { VariantClear(this); }
|
||||
|
||||
FFWmiVariant(const FFWmiVariant&) = delete;
|
||||
FFWmiVariant(FFWmiVariant&&); // don't define it to enforce NRVO optimization
|
||||
|
||||
bool hasValue() {
|
||||
return this->vt != VT_EMPTY;
|
||||
}
|
||||
|
||||
explicit operator bool() {
|
||||
return this->hasValue();
|
||||
}
|
||||
|
||||
template <typename T> T get();
|
||||
|
||||
// boolean
|
||||
template <> bool get<bool>() {
|
||||
assert(this->vt == VT_BOOL);
|
||||
return this->boolVal != VARIANT_FALSE;
|
||||
}
|
||||
|
||||
// signed
|
||||
template <> int8_t get() {
|
||||
assert(this->vt == VT_I1);
|
||||
return this->cVal;
|
||||
}
|
||||
template <> int16_t get() {
|
||||
assert(vt == VT_I2);
|
||||
return this->iVal;
|
||||
}
|
||||
template <> int32_t get() {
|
||||
assert(this->vt == VT_I4 || vt == VT_INT);
|
||||
return this->intVal;
|
||||
}
|
||||
template <> int64_t get() {
|
||||
assert(this->vt == VT_I8);
|
||||
return this->llVal;
|
||||
}
|
||||
|
||||
// unsigned
|
||||
template <> uint8_t get() {
|
||||
assert(this->vt == VT_UI1);
|
||||
return this->bVal;
|
||||
}
|
||||
template <> uint16_t get() {
|
||||
assert(this->vt == VT_UI2);
|
||||
return this->uiVal;
|
||||
}
|
||||
template <> uint32_t get() {
|
||||
assert(this->vt == VT_UI4 || vt == VT_UINT);
|
||||
return this->uintVal;
|
||||
}
|
||||
template <> uint64_t get() {
|
||||
assert(this->vt == VT_UI8);
|
||||
return this->ullVal;
|
||||
}
|
||||
|
||||
// decimal
|
||||
template <> float get() {
|
||||
assert(this->vt == VT_R4);
|
||||
return this->fltVal;
|
||||
}
|
||||
template <> double get() {
|
||||
assert(this->vt == VT_R8);
|
||||
return this->dblVal;
|
||||
}
|
||||
|
||||
// string
|
||||
template <> std::string_view get() {
|
||||
assert(this->vt == VT_LPSTR);
|
||||
return this->pcVal;
|
||||
}
|
||||
template <> std::wstring_view get() {
|
||||
assert(this->vt == VT_BSTR || this->vt == VT_LPWSTR);
|
||||
if (this->vt == VT_LPWSTR)
|
||||
return this->bstrVal;
|
||||
else
|
||||
return { this->bstrVal, SysStringLen(this->bstrVal) };
|
||||
}
|
||||
|
||||
// array signed
|
||||
template <> std::pair<const int8_t*, uint32_t> get() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_I1);
|
||||
return std::make_pair((int8_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
template <> std::pair<const int16_t*, uint32_t> get() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_I2);
|
||||
return std::make_pair((int16_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
template <> std::pair<const int32_t*, uint32_t> get() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_I4);
|
||||
return std::make_pair((int32_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
template <> std::pair<const int64_t*, uint32_t> get() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_I8);
|
||||
return std::make_pair((int64_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
|
||||
// array unsigned
|
||||
template <> std::pair<const uint8_t*, uint32_t> get() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_UI1);
|
||||
return std::make_pair((uint8_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
template <> std::pair<const uint16_t*, uint32_t> get() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_UI2);
|
||||
return std::make_pair((uint16_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
template <> std::pair<const uint32_t*, uint32_t> get() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_UI4);
|
||||
return std::make_pair((uint32_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
template <> std::pair<const uint64_t*, uint32_t> get() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_UI8);
|
||||
return std::make_pair((uint64_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
};
|
||||
|
||||
struct FFWmiRecord
|
||||
{
|
||||
IWbemClassObject* obj;
|
||||
@@ -51,6 +178,11 @@ struct FFWmiRecord
|
||||
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);
|
||||
FFWmiVariant get(const wchar_t* key) {
|
||||
FFWmiVariant result;
|
||||
obj->Get(key, 0, &result, nullptr, nullptr);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
struct FFWmiQuery
|
||||
@@ -77,117 +209,6 @@ struct FFWmiQuery
|
||||
}
|
||||
};
|
||||
|
||||
struct FFWmiVariant: VARIANT {
|
||||
explicit FFWmiVariant() { VariantInit(this); }
|
||||
~FFWmiVariant() { VariantClear(this); }
|
||||
|
||||
FFWmiVariant(const FFWmiVariant&) = delete;
|
||||
|
||||
// boolean
|
||||
explicit operator bool() {
|
||||
assert(this->vt == VT_BOOL);
|
||||
return this->boolVal != VARIANT_FALSE;
|
||||
}
|
||||
|
||||
// signed
|
||||
explicit operator int8_t() {
|
||||
assert(this->vt == VT_I1);
|
||||
return this->cVal;
|
||||
}
|
||||
explicit operator int16_t() {
|
||||
assert(vt == VT_I2);
|
||||
return this->iVal;
|
||||
}
|
||||
explicit operator int32_t() {
|
||||
assert(this->vt == VT_I4 || vt == VT_INT);
|
||||
return this->intVal;
|
||||
}
|
||||
explicit operator int64_t() {
|
||||
assert(this->vt == VT_I8);
|
||||
return this->llVal;
|
||||
}
|
||||
|
||||
// unsigned
|
||||
explicit operator uint8_t() {
|
||||
assert(this->vt == VT_I1);
|
||||
return this->bVal;
|
||||
}
|
||||
explicit operator uint16_t() {
|
||||
assert(this->vt == VT_I2);
|
||||
return this->uiVal;
|
||||
}
|
||||
explicit operator uint32_t() {
|
||||
assert(this->vt == VT_UI4 || vt == VT_UINT);
|
||||
return this->uintVal;
|
||||
}
|
||||
explicit operator uint64_t() {
|
||||
assert(this->vt == VT_UI8);
|
||||
return this->ullVal;
|
||||
}
|
||||
explicit operator float() {
|
||||
assert(this->vt == VT_R4);
|
||||
return this->fltVal;
|
||||
}
|
||||
explicit operator double() {
|
||||
assert(this->vt == VT_R8);
|
||||
return this->dblVal;
|
||||
}
|
||||
|
||||
// string
|
||||
explicit operator const std::string_view() {
|
||||
assert(this->vt == VT_LPSTR);
|
||||
return this->pcVal;
|
||||
}
|
||||
explicit operator const std::wstring_view() {
|
||||
assert(this->vt == VT_BSTR || this->vt == VT_LPWSTR);
|
||||
return this->bstrVal;
|
||||
}
|
||||
|
||||
// array signed
|
||||
explicit operator std::pair<const int8_t*, uint32_t>() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_I1);
|
||||
return std::make_pair((int8_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
explicit operator std::pair<const int16_t*, uint32_t>() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_I2);
|
||||
return std::make_pair((int16_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
explicit operator std::pair<const int32_t*, uint32_t>() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_I4);
|
||||
return std::make_pair((int32_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
explicit operator std::pair<const int64_t*, uint32_t>() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_I8);
|
||||
return std::make_pair((int64_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
|
||||
// array unsigned
|
||||
explicit operator std::pair<const uint8_t*, uint32_t>() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_UI1);
|
||||
return std::make_pair((uint8_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
explicit operator std::pair<const uint16_t*, uint32_t>() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_UI2);
|
||||
return std::make_pair((uint16_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
explicit operator std::pair<const uint32_t*, uint32_t>() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_UI4);
|
||||
return std::make_pair((uint32_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
explicit operator std::pair<const uint64_t*, uint32_t>() {
|
||||
assert(this->vt & VT_ARRAY);
|
||||
assert((this->vt & ~VT_ARRAY) == VT_UI8);
|
||||
return std::make_pair((uint64_t*)this->parray->pvData, this->parray->cDims);
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
// Win32 COM headers requires C++ compiler
|
||||
#error Must be included in C++ source file
|
||||
|
||||
Reference in New Issue
Block a user