Skip to content

Commit acb38fa

Browse files
committed
Bluetooth (Windows): detect battery (WIP)
1 parent 7396208 commit acb38fa

File tree

4 files changed

+55
-38
lines changed

4 files changed

+55
-38
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,7 @@ elseif(WIN32)
915915
src/detection/battery/battery_windows.c
916916
src/detection/bios/bios_windows.c
917917
src/detection/bluetooth/bluetooth_windows.c
918+
src/detection/bluetooth/bluetooth_windows.cpp
918919
src/detection/bluetoothradio/bluetoothradio_windows.c
919920
src/detection/board/board_windows.c
920921
src/detection/bootmgr/bootmgr_windows.c
@@ -1428,6 +1429,7 @@ elseif(WIN32)
14281429
PRIVATE "imagehlp"
14291430
PRIVATE "cfgmgr32"
14301431
PRIVATE "winbrand"
1432+
PRIVATE "propsys"
14311433
)
14321434
elseif(FreeBSD)
14331435
target_link_libraries(libfastfetch
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
extern "C"
2+
{
3+
#include "bluetooth.h"
4+
}
5+
#include "util/windows/wmi.hpp"
6+
#include "util/windows/unicode.hpp"
7+
8+
#include <propvarutil.h>
9+
10+
STDAPI InitVariantFromStringArray(_In_reads_(cElems) PCWSTR *prgsz, _In_ ULONG cElems, _Out_ VARIANT *pvar);
11+
12+
static const char* detectWithWmi(FFlist* result)
13+
{
14+
FFWmiQuery query(L"SELECT __PATH FROM Win32_PnPEntity WHERE Service = 'BthHFEnum'", nullptr, FFWmiNamespace::CIMV2);
15+
if(!query)
16+
return "Query WMI service failed";
17+
18+
while(FFWmiRecord record = query.next())
19+
{
20+
IWbemClassObject* pInParams = nullptr;
21+
PCWSTR props[] = { L"{104EA319-6EE2-4701-BD47-8DDBF425BBE5} 2" };
22+
VARIANT devicePropertyKeys;
23+
InitVariantFromStringArray(props, ARRAY_SIZE(props), &devicePropertyKeys);
24+
record.obj->GetMethod(bstr_t(L"GetDeviceProperties"), 0, &pInParams, NULL);
25+
pInParams->Put(L"devicePropertyKeys", 0, &devicePropertyKeys, CIM_FLAG_ARRAY | CIM_STRING);
26+
IWbemCallResult* pResult = nullptr;
27+
query.pService->ExecMethod(bstr_t(record.get(L"__PATH").bstrVal), bstr_t(L"GetDeviceProperties"), 0, nullptr, pInParams, nullptr, &pResult);
28+
// TODO: parse result
29+
}
30+
return NULL;
31+
}

src/util/windows/wmi.cpp

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,6 @@
66
#include <wchar.h>
77
#include <math.h>
88

9-
namespace
10-
{
11-
// Provide our bstr_t to avoid libstdc++ dependency
12-
struct bstr_t
13-
{
14-
explicit bstr_t(const wchar_t* str) noexcept: _bstr(SysAllocString(str)) {}
15-
~bstr_t(void) noexcept { SysFreeString(_bstr); }
16-
explicit operator const wchar_t*(void) const noexcept { return _bstr; }
17-
operator BSTR(void) const noexcept { return _bstr; }
18-
19-
private:
20-
BSTR _bstr;
21-
};
22-
}
23-
249
static const char* doInitService(const wchar_t* networkResource, IWbemServices** result)
2510
{
2611
HRESULT hres;
@@ -59,30 +44,11 @@ static const char* doInitService(const wchar_t* networkResource, IWbemServices**
5944
if (FAILED(hres))
6045
return "Could not connect WMI server";
6146

62-
// Set security levels on the proxy -------------------------
63-
hres = CoSetProxyBlanket(
64-
pSvc, // Indicates the proxy to set
65-
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
66-
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
67-
nullptr, // Server principal name
68-
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
69-
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
70-
nullptr, // client identity
71-
EOAC_NONE // proxy capabilities
72-
);
73-
74-
if (FAILED(hres))
75-
{
76-
pSvc->Release();
77-
return "Could not set proxy blanket";
78-
}
79-
8047
*result = pSvc;
8148
return NULL;
8249
}
8350

8451
FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace wmiNs)
85-
: pEnumerator(nullptr)
8652
{
8753
const char* errStr;
8854
if ((errStr = ffInitCom()))
@@ -95,7 +61,7 @@ FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace
9561
static IWbemServices* contexts[(int) FFWmiNamespace::LAST];
9662

9763
IWbemServices* context = contexts[(int)wmiNs];
98-
if (!contexts[(int)wmiNs])
64+
if (!context)
9965
{
10066
if ((errStr = doInitService(wmiNs == FFWmiNamespace::CIMV2 ? L"ROOT\\CIMV2" : L"ROOT\\WMI", &context)))
10167
{
@@ -106,13 +72,15 @@ FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace
10672
contexts[(int)wmiNs] = context;
10773
}
10874

75+
this->pService = context;
76+
10977
// Use the IWbemServices pointer to make requests of WMI
11078
HRESULT hres = context->ExecQuery(
11179
bstr_t(L"WQL"),
11280
bstr_t(queryStr),
11381
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
11482
nullptr,
115-
&pEnumerator);
83+
&this->pEnumerator);
11684

11785
if (FAILED(hres))
11886
{

src/util/windows/wmi.hpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ enum class FFWmiNamespace {
2020

2121
struct FFWmiRecord
2222
{
23-
IWbemClassObject* obj;
23+
IWbemClassObject* obj = nullptr;
2424

25-
explicit FFWmiRecord(IEnumWbemClassObject* pEnumerator): obj(nullptr) {
25+
explicit FFWmiRecord(IEnumWbemClassObject* pEnumerator) {
2626
if(!pEnumerator) return;
2727

2828
ULONG ret;
@@ -53,6 +53,7 @@ struct FFWmiRecord
5353

5454
struct FFWmiQuery
5555
{
56+
IWbemServices* pService = nullptr;
5657
IEnumWbemClassObject* pEnumerator = nullptr;
5758

5859
FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error = nullptr, FFWmiNamespace wmiNs = FFWmiNamespace::CIMV2);
@@ -75,6 +76,21 @@ struct FFWmiQuery
7576
}
7677
};
7778

79+
namespace
80+
{
81+
// Provide our bstr_t to avoid libstdc++ dependency
82+
struct bstr_t
83+
{
84+
explicit bstr_t(const wchar_t* str) noexcept: _bstr(SysAllocString(str)) {}
85+
~bstr_t(void) noexcept { SysFreeString(_bstr); }
86+
explicit operator const wchar_t*(void) const noexcept { return _bstr; }
87+
operator BSTR(void) const noexcept { return _bstr; }
88+
89+
private:
90+
BSTR _bstr;
91+
};
92+
}
93+
7894
#else
7995
// Win32 COM headers requires C++ compiler
8096
#error Must be included in C++ source file

0 commit comments

Comments
 (0)