Bluetooth (Windows): detect battery (WIP)

This commit is contained in:
李通洲
2024-11-06 00:16:05 +08:00
parent 7396208809
commit acb38fa3ee
4 changed files with 55 additions and 38 deletions
+2
View File
@@ -915,6 +915,7 @@ elseif(WIN32)
src/detection/battery/battery_windows.c
src/detection/bios/bios_windows.c
src/detection/bluetooth/bluetooth_windows.c
src/detection/bluetooth/bluetooth_windows.cpp
src/detection/bluetoothradio/bluetoothradio_windows.c
src/detection/board/board_windows.c
src/detection/bootmgr/bootmgr_windows.c
@@ -1428,6 +1429,7 @@ elseif(WIN32)
PRIVATE "imagehlp"
PRIVATE "cfgmgr32"
PRIVATE "winbrand"
PRIVATE "propsys"
)
elseif(FreeBSD)
target_link_libraries(libfastfetch
@@ -0,0 +1,31 @@
extern "C"
{
#include "bluetooth.h"
}
#include "util/windows/wmi.hpp"
#include "util/windows/unicode.hpp"
#include <propvarutil.h>
STDAPI InitVariantFromStringArray(_In_reads_(cElems) PCWSTR *prgsz, _In_ ULONG cElems, _Out_ VARIANT *pvar);
static const char* detectWithWmi(FFlist* result)
{
FFWmiQuery query(L"SELECT __PATH FROM Win32_PnPEntity WHERE Service = 'BthHFEnum'", nullptr, FFWmiNamespace::CIMV2);
if(!query)
return "Query WMI service failed";
while(FFWmiRecord record = query.next())
{
IWbemClassObject* pInParams = nullptr;
PCWSTR props[] = { L"{104EA319-6EE2-4701-BD47-8DDBF425BBE5} 2" };
VARIANT devicePropertyKeys;
InitVariantFromStringArray(props, ARRAY_SIZE(props), &devicePropertyKeys);
record.obj->GetMethod(bstr_t(L"GetDeviceProperties"), 0, &pInParams, NULL);
pInParams->Put(L"devicePropertyKeys", 0, &devicePropertyKeys, CIM_FLAG_ARRAY | CIM_STRING);
IWbemCallResult* pResult = nullptr;
query.pService->ExecMethod(bstr_t(record.get(L"__PATH").bstrVal), bstr_t(L"GetDeviceProperties"), 0, nullptr, pInParams, nullptr, &pResult);
// TODO: parse result
}
return NULL;
}
+4 -36
View File
@@ -6,21 +6,6 @@
#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(void) noexcept { SysFreeString(_bstr); }
explicit operator const wchar_t*(void) const noexcept { return _bstr; }
operator BSTR(void) const noexcept { return _bstr; }
private:
BSTR _bstr;
};
}
static const char* doInitService(const wchar_t* networkResource, IWbemServices** result)
{
HRESULT hres;
@@ -59,30 +44,11 @@ static const char* doInitService(const wchar_t* networkResource, IWbemServices**
if (FAILED(hres))
return "Could not connect WMI server";
// Set security levels on the proxy -------------------------
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
nullptr, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
nullptr, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
pSvc->Release();
return "Could not set proxy blanket";
}
*result = pSvc;
return NULL;
}
FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace wmiNs)
: pEnumerator(nullptr)
{
const char* errStr;
if ((errStr = ffInitCom()))
@@ -95,7 +61,7 @@ FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace
static IWbemServices* contexts[(int) FFWmiNamespace::LAST];
IWbemServices* context = contexts[(int)wmiNs];
if (!contexts[(int)wmiNs])
if (!context)
{
if ((errStr = doInitService(wmiNs == FFWmiNamespace::CIMV2 ? L"ROOT\\CIMV2" : L"ROOT\\WMI", &context)))
{
@@ -106,13 +72,15 @@ FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace
contexts[(int)wmiNs] = context;
}
this->pService = context;
// Use the IWbemServices pointer to make requests of WMI
HRESULT hres = context->ExecQuery(
bstr_t(L"WQL"),
bstr_t(queryStr),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
nullptr,
&pEnumerator);
&this->pEnumerator);
if (FAILED(hres))
{
+18 -2
View File
@@ -20,9 +20,9 @@ enum class FFWmiNamespace {
struct FFWmiRecord
{
IWbemClassObject* obj;
IWbemClassObject* obj = nullptr;
explicit FFWmiRecord(IEnumWbemClassObject* pEnumerator): obj(nullptr) {
explicit FFWmiRecord(IEnumWbemClassObject* pEnumerator) {
if(!pEnumerator) return;
ULONG ret;
@@ -53,6 +53,7 @@ struct FFWmiRecord
struct FFWmiQuery
{
IWbemServices* pService = nullptr;
IEnumWbemClassObject* pEnumerator = nullptr;
FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error = nullptr, FFWmiNamespace wmiNs = FFWmiNamespace::CIMV2);
@@ -75,6 +76,21 @@ struct FFWmiQuery
}
};
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(void) noexcept { SysFreeString(_bstr); }
explicit operator const wchar_t*(void) const noexcept { return _bstr; }
operator BSTR(void) const noexcept { return _bstr; }
private:
BSTR _bstr;
};
}
#else
// Win32 COM headers requires C++ compiler
#error Must be included in C++ source file