Files
fastfetch/src/util/windows/wmi.hpp
T

197 lines
5.8 KiB
C++
Raw Normal View History

#pragma once
#ifndef FF_INCLUDED_util_windows_wmi
#define FF_INCLUDED_util_windows_wmi
#ifdef __cplusplus
extern "C" {
#include "util/FFstrbuf.h"
}
2023-01-25 15:49:31 +08:00
#include <initguid.h>
#include <Wbemidl.h>
#include <utility>
#include <string_view>
#include <cassert>
enum class FFWmiNamespace {
CIMV2,
WMI,
LAST,
};
2023-01-29 10:10:31 +08:00
enum {
FF_WMI_QUERY_TIMEOUT = 5000
};
2022-10-16 23:58:13 +08:00
struct FFWmiRecord
{
2022-10-16 23:58:13 +08:00
IWbemClassObject* obj;
2022-10-16 23:58:13 +08:00
explicit FFWmiRecord(IEnumWbemClassObject* pEnumerator): obj(nullptr) {
if(!pEnumerator) return;
2022-10-16 23:58:13 +08:00
ULONG ret;
2023-01-29 10:10:31 +08:00
bool ok = SUCCEEDED(pEnumerator->Next(FF_WMI_QUERY_TIMEOUT, 1, &obj, &ret)) && ret;
2022-10-16 23:58:13 +08:00
if(!ok) obj = nullptr;
}
2022-10-16 23:58:13 +08:00
FFWmiRecord(const FFWmiRecord&) = delete;
2022-11-06 17:04:34 +08:00
FFWmiRecord(FFWmiRecord&& other) { *this = (FFWmiRecord&&)other; }
~FFWmiRecord() { if(obj) obj->Release(); }
explicit operator bool() { return !!obj; }
FFWmiRecord& operator =(FFWmiRecord&& other) {
if(obj) obj->Release();
2022-10-16 23:58:13 +08:00
obj = other.obj;
other.obj = nullptr;
2022-11-06 17:04:34 +08:00
return *this;
}
2022-10-16 23:58:13 +08:00
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);
};
2022-10-16 23:58:13 +08:00
struct FFWmiQuery
{
IEnumWbemClassObject* pEnumerator = nullptr;
FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error = nullptr, FFWmiNamespace wmiNs = FFWmiNamespace::CIMV2);
2022-10-16 23:58:13 +08:00
explicit FFWmiQuery(IEnumWbemClassObject* pEnumerator): pEnumerator(pEnumerator) {}
FFWmiQuery(const FFWmiQuery& other) = delete;
2022-11-06 17:04:34 +08:00
FFWmiQuery(FFWmiQuery&& other) { *this = (FFWmiQuery&&)other; }
2022-10-16 23:58:13 +08:00
~FFWmiQuery() { if(pEnumerator) pEnumerator->Release(); }
2022-10-16 23:58:13 +08:00
explicit operator bool() { return !!pEnumerator; }
2022-11-06 17:04:34 +08:00
FFWmiQuery& operator =(FFWmiQuery&& other) {
if(pEnumerator) pEnumerator->Release();
pEnumerator = other.pEnumerator;
other.pEnumerator = nullptr;
return *this;
}
2022-10-16 23:58:13 +08:00
FFWmiRecord next() {
FFWmiRecord result(pEnumerator);
return result;
}
};
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
#endif //__cplusplus
#endif //FF_INCLUDED_util_windows_wmi