BluetoothRadio (Windows): new module

This commit is contained in:
李通洲
2024-07-28 00:05:07 +08:00
parent ce648e9e44
commit 8a3af14d22
15 changed files with 445 additions and 1 deletions
+7
View File
@@ -326,6 +326,7 @@ set(LIBFASTFETCH_SRC
src/modules/battery/battery.c
src/modules/bios/bios.c
src/modules/bluetooth/bluetooth.c
src/modules/bluetoothradio/bluetoothradio.c
src/modules/board/board.c
src/modules/bootmgr/bootmgr.c
src/modules/brightness/brightness.c
@@ -421,6 +422,7 @@ if(LINUX)
src/detection/cpuusage/cpuusage_linux.c
src/detection/cursor/cursor_linux.c
src/detection/bluetooth/bluetooth_linux.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/disk/disk_linux.c
src/detection/dns/dns_linux.c
src/detection/physicaldisk/physicaldisk_linux.c
@@ -488,6 +490,7 @@ elseif(ANDROID)
src/detection/battery/battery_android.c
src/detection/bios/bios_android.c
src/detection/bluetooth/bluetooth_nosupport.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/board/board_android.c
src/detection/bootmgr/bootmgr_nosupport.c
src/detection/brightness/brightness_nosupport.c
@@ -550,6 +553,7 @@ elseif(BSD)
src/detection/battery/battery_bsd.c
src/detection/bios/bios_bsd.c
src/detection/bluetooth/bluetooth_linux.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/board/board_bsd.c
src/detection/bootmgr/bootmgr_bsd.c
src/detection/brightness/brightness_bsd.c
@@ -626,6 +630,7 @@ elseif(APPLE)
src/detection/battery/battery_apple.c
src/detection/bios/bios_apple.c
src/detection/bluetooth/bluetooth_apple.m
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/board/board_apple.c
src/detection/bootmgr/bootmgr_apple.c
src/detection/brightness/brightness_apple.c
@@ -689,6 +694,7 @@ elseif(WIN32)
src/detection/battery/battery_windows.c
src/detection/bios/bios_windows.c
src/detection/bluetooth/bluetooth_windows.c
src/detection/bluetoothradio/bluetoothradio_windows.c
src/detection/board/board_windows.c
src/detection/bootmgr/bootmgr_windows.c
src/detection/brightness/brightness_windows.cpp
@@ -763,6 +769,7 @@ elseif(SunOS)
src/detection/cpuusage/cpuusage_sunos.c
src/detection/cursor/cursor_linux.c
src/detection/bluetooth/bluetooth_nosupport.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/disk/disk_sunos.c
src/detection/dns/dns_linux.c
src/detection/physicaldisk/physicaldisk_nosupport.c
+31 -1
View File
@@ -745,6 +745,7 @@
"battery",
"bios",
"bluetooth",
"bluetoothradio",
"board",
"bootmgr",
"break",
@@ -1049,7 +1050,7 @@
"additionalProperties": false,
"properties": {
"type": {
"description": "List bluetooth devices",
"description": "List (connected) bluetooth devices",
"const": "bluetooth"
},
"showDisconnected": {
@@ -1080,6 +1081,35 @@
}
}
},
{
"title": "Bluetooth Radio",
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"description": "List bluetooth radios width supported version and vendor",
"const": "bluetoothradio"
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
}
},
{
"title": "Brightness",
"type": "object",
+1
View File
@@ -73,6 +73,7 @@
"opencl",
"users",
"bluetooth",
"bluetoothradio",
"sound",
"camera",
"gamepad",
+1
View File
@@ -75,6 +75,7 @@
"opencl",
"users",
"bluetooth",
"bluetoothradio",
"sound",
"camera",
"gamepad",
+1
View File
@@ -8,6 +8,7 @@ static FFModuleBaseInfo* B[] = {
(void*) &instance.config.modules.battery,
(void*) &instance.config.modules.bios,
(void*) &instance.config.modules.bluetooth,
(void*) &instance.config.modules.bluetoothRadio,
(void*) &instance.config.modules.board,
(void*) &instance.config.modules.bootmgr,
(void*) &instance.config.modules.break_,
@@ -0,0 +1,17 @@
#pragma once
#include "fastfetch.h"
typedef struct FFBluetoothRadioResult
{
FFstrbuf name;
FFstrbuf address;
uint8_t lmpVersion;
uint8_t hciVersion;
uint16_t lmpSubversion;
uint16_t hciRevision;
const char* vendor;
bool leSupported;
} FFBluetoothRadioResult;
const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */);
@@ -0,0 +1,6 @@
#include "bluetoothradio.h"
const char* ffDetectBluetoothRadio(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothRadioResult */)
{
return "Not supported on this platform";
}
@@ -0,0 +1,157 @@
#include "bluetoothradio.h"
#include "common/library.h"
#include "common/io/io.h"
#include "util/windows/unicode.h"
#include <windows.h>
#include <bluetoothapis.h>
#include <winioctl.h>
// #include <bthioctl.h>
#define BTH_IOCTL_BASE 0
#define BTH_CTL(id) CTL_CODE(FILE_DEVICE_BLUETOOTH, (id), METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_BTH_GET_LOCAL_INFO BTH_CTL(BTH_IOCTL_BASE+0x00)
#define LMP_LE_SUPPORTED(x) ((x >> 38) & 1)
typedef struct _BTH_RADIO_INFO
{
// Supported LMP features of the radio. Use LMP_XXX() to extract
// the desired bits.
ULONGLONG lmpSupportedFeatures;
// Manufacturer ID (possibly BTH_MFG_XXX)
USHORT mfg;
// LMP subversion
USHORT lmpSubversion;
// LMP version
UCHAR lmpVersion;
} __attribute__((__packed__)) BTH_RADIO_INFO;
typedef struct _BTH_LOCAL_RADIO_INFO
{
// Local BTH_ADDR, class of defice, and radio name
BTH_DEVICE_INFO localInfo;
// Combo of LOCAL_RADIO_XXX values
ULONG flags;
// HCI revision, see core spec
USHORT hciRevision;
// HCI version, see core spec
UCHAR hciVersion;
// More information about the local radio (LMP, MFG)
BTH_RADIO_INFO radioInfo;
} __attribute__((__packed__)) BTH_LOCAL_RADIO_INFO;
static_assert(sizeof(BTH_LOCAL_RADIO_INFO) == 292, "BTH_LOCAL_RADIO_INFO should be 292 bytes");
#pragma GCC diagnostic ignored "-Wpointer-sign"
const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
{
// Actually bluetoothapis.dll, but it's missing on Windows 7
FF_LIBRARY_LOAD(bluetoothapis, NULL, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindFirstRadio)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindNextRadio)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindRadioClose)
HANDLE hRadio = NULL;
HBLUETOOTH_DEVICE_FIND hFind = ffBluetoothFindFirstRadio(&(BLUETOOTH_FIND_RADIO_PARAMS) {
.dwSize = sizeof(BLUETOOTH_FIND_RADIO_PARAMS)
}, &hRadio);
if(!hFind)
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
return "No Bluetooth radios found";
else
return "BluetoothFindFirstRadio() failed";
}
do {
BTH_LOCAL_RADIO_INFO blri;
DWORD returned;
if (!DeviceIoControl(hRadio, IOCTL_BTH_GET_LOCAL_INFO, NULL, 0, &blri, sizeof(blri), &returned, NULL))
continue;
FFBluetoothRadioResult* device = ffListAdd(devices);
ffStrbufInitS(&device->name, blri.localInfo.name);
BLUETOOTH_ADDRESS_STRUCT addr = { .ullLong = blri.localInfo.address };
ffStrbufInitF(&device->address, "%02x:%02x:%02x:%02x:%02x:%02x",
addr.rgBytes[0],
addr.rgBytes[1],
addr.rgBytes[2],
addr.rgBytes[3],
addr.rgBytes[4],
addr.rgBytes[5]);
device->lmpVersion = blri.radioInfo.lmpVersion;
device->lmpSubversion = blri.radioInfo.lmpSubversion;
device->hciVersion = blri.hciVersion;
device->hciRevision = blri.hciRevision;
device->leSupported = LMP_LE_SUPPORTED(blri.radioInfo.lmpSupportedFeatures);
switch (blri.radioInfo.mfg)
{
case BTH_MFG_ERICSSON: device->vendor = "Ericsson"; break;
case BTH_MFG_NOKIA: device->vendor = "Nokia"; break;
case BTH_MFG_INTEL: device->vendor = "Intel"; break;
case BTH_MFG_IBM: device->vendor = "IBM"; break;
case BTH_MFG_TOSHIBA: device->vendor = "Toshiba"; break;
case BTH_MFG_3COM: device->vendor = "3Com"; break;
case BTH_MFG_MICROSOFT: device->vendor = "Microsoft"; break;
case BTH_MFG_LUCENT: device->vendor = "Lucent"; break;
case BTH_MFG_MOTOROLA: device->vendor = "Motorola"; break;
case BTH_MFG_INFINEON: device->vendor = "Infineon"; break;
case BTH_MFG_CSR: device->vendor = "CSR"; break;
case BTH_MFG_SILICONWAVE: device->vendor = "Silicon-Wave"; break;
case BTH_MFG_DIGIANSWER: device->vendor = "Digi-Answer"; break;
case BTH_MFG_TI: device->vendor = "Ti"; break;
case BTH_MFG_PARTHUS: device->vendor = "Parthus"; break;
case BTH_MFG_BROADCOM: device->vendor = "Broadcom"; break;
case BTH_MFG_MITEL: device->vendor = "Mitel"; break;
case BTH_MFG_WIDCOMM: device->vendor = "Widcomm"; break;
case BTH_MFG_ZEEVO: device->vendor = "Zeevo"; break;
case BTH_MFG_ATMEL: device->vendor = "Atmel"; break;
case BTH_MFG_MITSIBUSHI: device->vendor = "Mitsubishi"; break;
case BTH_MFG_RTX_TELECOM: device->vendor = "RTX Telecom"; break;
case BTH_MFG_KC_TECHNOLOGY: device->vendor = "KC Technology"; break;
case BTH_MFG_NEWLOGIC: device->vendor = "Newlogic"; break;
case BTH_MFG_TRANSILICA: device->vendor = "Transilica"; break;
case BTH_MFG_ROHDE_SCHWARZ: device->vendor = "Rohde-Schwarz"; break;
case BTH_MFG_TTPCOM: device->vendor = "TTPCom"; break;
case BTH_MFG_SIGNIA: device->vendor = "Signia"; break;
case BTH_MFG_CONEXANT: device->vendor = "Conexant"; break;
case BTH_MFG_QUALCOMM: device->vendor = "Qualcomm"; break;
case BTH_MFG_INVENTEL: device->vendor = "Inventel"; break;
case BTH_MFG_AVM_BERLIN: device->vendor = "AVM Berlin"; break;
case BTH_MFG_BANDSPEED: device->vendor = "Bandspeed"; break;
case BTH_MFG_MANSELLA: device->vendor = "Mansella"; break;
case BTH_MFG_NEC: device->vendor = "NEC"; break;
case BTH_MFG_WAVEPLUS_TECHNOLOGY_CO: device->vendor = "Waveplus"; break;
case BTH_MFG_ALCATEL: device->vendor = "Alcatel"; break;
case BTH_MFG_PHILIPS_SEMICONDUCTOR: device->vendor = "Philips Semiconductors"; break;
case BTH_MFG_C_TECHNOLOGIES: device->vendor = "C Technologies"; break;
case BTH_MFG_OPEN_INTERFACE: device->vendor = "Open Interface"; break;
case BTH_MFG_RF_MICRO_DEVICES: device->vendor = "RF Micro Devices"; break;
case BTH_MFG_HITACHI: device->vendor = "Hitachi"; break;
case BTH_MFG_SYMBOL_TECHNOLOGIES: device->vendor = "Symbol Technologies"; break;
case BTH_MFG_TENOVIS: device->vendor = "Tenovis"; break;
case BTH_MFG_MACRONIX_INTERNATIONAL: device->vendor = "Macronix International"; break;
case BTH_MFG_MARVELL: device->vendor = "Marvell"; break;
case BTH_MFG_APPLE: device->vendor = "Apple"; break;
case BTH_MFG_NORDIC_SEMICONDUCTORS_ASA: device->vendor = "Nordic Semiconductor ASA"; break;
case BTH_MFG_ARUBA_NETWORKS: device->vendor = "Aruba Networks"; break;
case BTH_MFG_INTERNAL_USE: device->vendor = "Internal Use"; break;
default: device->vendor = "Unknown"; break;
}
} while (ffBluetoothFindNextRadio(hFind, &hRadio));
ffBluetoothFindRadioClose(hFind);
return NULL;
}
+198
View File
@@ -0,0 +1,198 @@
#include "common/percent.h"
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "detection/bluetoothradio/bluetoothradio.h"
#include "modules/bluetoothradio/bluetoothradio.h"
#include "util/stringUtils.h"
#define FF_BLUETOOTHRADIO_NUM_FORMAT_ARGS 7
#define FF_BLUETOOTHRADIO_DISPLAY_NAME "Bluetooth Radio"
static void printDevice(FFBluetoothRadioOptions* options, const FFBluetoothRadioResult* radio, uint8_t index)
{
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
if (options->moduleArgs.key.length == 0)
{
ffStrbufAppendF(&key, "%s (%s)", FF_BLUETOOTHRADIO_DISPLAY_NAME, radio->name.chars);
}
else
{
FF_PARSE_FORMAT_STRING_CHECKED(&key, &options->moduleArgs.key, 3, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT, &index, "index"},
{FF_FORMAT_ARG_TYPE_STRING, radio->name.chars, "name"},
{FF_FORMAT_ARG_TYPE_STRBUF, &options->moduleArgs.keyIcon, "icon"},
}));
}
const char* version = NULL;
switch (radio->lmpVersion)
{
case 0: version = "1.0b"; break;
case 1: version = "1.1"; break;
case 2: version = "1.2"; break;
case 3: version = "2.0 + EDR"; break;
case 4: version = "2.1 + EDR"; break;
case 5: version = "3.0 + HS"; break;
case 6: version = "4.0"; break;
case 7: version = "4.1"; break;
case 8: version = "4.2"; break;
case 9: version = "5.0"; break;
case 10: version = "5.1"; break;
case 11: version = "5.2"; break;
case 12: version = "5.3"; break;
case 13: version = "5.4"; break;
}
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(key.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
if (version)
printf("Bluetooth %s (%s)\n", version, radio->vendor);
else
fputs(radio->vendor, stdout);
}
else
{
FF_STRBUF_AUTO_DESTROY lmpVersion = ffStrbufCreateF("%u.%u", radio->lmpVersion, radio->lmpSubversion);
FF_STRBUF_AUTO_DESTROY hciVersion = ffStrbufCreateF("%u.%u", radio->hciVersion, radio->hciRevision);
FF_PRINT_FORMAT_CHECKED(key.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BLUETOOTHRADIO_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &radio->name, "name"},
{FF_FORMAT_ARG_TYPE_STRBUF, &radio->address, "address"},
{FF_FORMAT_ARG_TYPE_STRBUF, &lmpVersion, "lmp-version"},
{FF_FORMAT_ARG_TYPE_STRBUF, &hciVersion, "hci-version"},
{FF_FORMAT_ARG_TYPE_STRING, version, "version"},
{FF_FORMAT_ARG_TYPE_STRING, radio->vendor, "vendor"},
{FF_FORMAT_ARG_TYPE_BOOL, &radio->leSupported, "le-supported"},
}));
}
}
void ffPrintBluetoothRadio(FFBluetoothRadioOptions* options)
{
FF_LIST_AUTO_DESTROY radios = ffListCreate(sizeof (FFBluetoothRadioResult));
const char* error = ffDetectBluetoothRadio(&radios);
if(error)
{
ffPrintError(FF_BLUETOOTHRADIO_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
}
else
{
for(uint32_t i = 0; i < radios.length; i++)
{
uint8_t index = (uint8_t) (radios.length == 1 ? 0 : i + 1);
printDevice(options, FF_LIST_GET(FFBluetoothRadioResult, radios, i), index);
}
}
FF_LIST_FOR_EACH(FFBluetoothRadioResult, radio, radios)
{
ffStrbufDestroy(&radio->name);
ffStrbufDestroy(&radio->address);
}
}
bool ffParseBluetoothRadioCommandOptions(FFBluetoothRadioOptions* options, const char* key, const char* value)
{
const char* subKey = ffOptionTestPrefix(key, FF_BLUETOOTHRADIO_MODULE_NAME);
if (!subKey) return false;
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
return false;
}
void ffParseBluetoothRadioJsonObject(FFBluetoothRadioOptions* options, yyjson_val* module)
{
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(module, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if(ffStrEqualsIgnCase(key, "type"))
continue;
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
ffPrintError(FF_BLUETOOTHRADIO_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key);
}
}
void ffGenerateBluetoothRadioJsonConfig(FFBluetoothRadioOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
__attribute__((__cleanup__(ffDestroyBluetoothRadioOptions))) FFBluetoothRadioOptions defaultOptions;
ffInitBluetoothRadioOptions(&defaultOptions);
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
}
void ffGenerateBluetoothRadioJsonResult(FF_MAYBE_UNUSED FFBluetoothRadioOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
FF_LIST_AUTO_DESTROY results = ffListCreate(sizeof(FFBluetoothRadioResult));
const char* error = ffDetectBluetoothRadio(&results);
if (error)
{
yyjson_mut_obj_add_str(doc, module, "error", error);
return;
}
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
FF_LIST_FOR_EACH(FFBluetoothRadioResult, item, results)
{
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
yyjson_mut_obj_add_strbuf(doc, obj, "name", &item->name);
yyjson_mut_obj_add_strbuf(doc, obj, "address", &item->address);
yyjson_mut_obj_add_uint(doc, obj, "lmpVersion", item->lmpVersion);
yyjson_mut_obj_add_uint(doc, obj, "lmpSubversion", item->lmpSubversion);
yyjson_mut_obj_add_uint(doc, obj, "hciVersion", item->hciVersion);
yyjson_mut_obj_add_uint(doc, obj, "hciRevision", item->hciRevision);
yyjson_mut_obj_add_str(doc, obj, "vendor", item->vendor);
yyjson_mut_obj_add_bool(doc, obj, "leSupported", item->leSupported);
}
FF_LIST_FOR_EACH(FFBluetoothRadioResult, radio, results)
{
ffStrbufDestroy(&radio->name);
ffStrbufDestroy(&radio->address);
}
}
void ffPrintBluetoothRadioHelpFormat(void)
{
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_BLUETOOTHRADIO_MODULE_NAME, "{1} ({4})", FF_BLUETOOTHRADIO_NUM_FORMAT_ARGS, ((const char* []) {
"Radio name for discovering - name",
"Address - local radio address",
"LMP version - lmp-version",
"HCI version - hci-version",
"Bluetooth version - version",
"Vendor - vendor",
"Is Bluetooth Low Energy (LE) supported - le-supported"
}));
}
void ffInitBluetoothRadioOptions(FFBluetoothRadioOptions* options)
{
ffOptionInitModuleBaseInfo(
&options->moduleInfo,
FF_BLUETOOTHRADIO_MODULE_NAME,
"List bluetooth radios width supported version and vendor",
ffParseBluetoothRadioCommandOptions,
ffParseBluetoothRadioJsonObject,
ffPrintBluetoothRadio,
ffGenerateBluetoothRadioJsonResult,
ffPrintBluetoothRadioHelpFormat,
ffGenerateBluetoothRadioJsonConfig
);
ffOptionInitModuleArg(&options->moduleArgs, "󰐻");
}
void ffDestroyBluetoothRadioOptions(FFBluetoothRadioOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
}
@@ -0,0 +1,9 @@
#pragma once
#include "fastfetch.h"
#define FF_BLUETOOTHRADIO_MODULE_NAME "BluetoothRadio"
void ffPrintBluetoothRadio(FFBluetoothRadioOptions* options);
void ffInitBluetoothRadioOptions(FFBluetoothRadioOptions* options);
void ffDestroyBluetoothRadioOptions(FFBluetoothRadioOptions* options);
+12
View File
@@ -0,0 +1,12 @@
#pragma once
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
#include "common/option.h"
#include "common/percent.h"
typedef struct FFBluetoothRadioOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
} FFBluetoothRadioOptions;
+1
View File
@@ -5,6 +5,7 @@
#include "modules/battery/battery.h"
#include "modules/bios/bios.h"
#include "modules/bluetooth/bluetooth.h"
#include "modules/bluetoothradio/bluetoothradio.h"
#include "modules/brightness/brightness.h"
#include "modules/board/board.h"
#include "modules/bootmgr/bootmgr.h"
+1
View File
@@ -5,6 +5,7 @@
#include "modules/battery/option.h"
#include "modules/bios/option.h"
#include "modules/bluetooth/option.h"
#include "modules/bluetoothradio/option.h"
#include "modules/board/option.h"
#include "modules/bootmgr/option.h"
#include "modules/break/option.h"
+2
View File
@@ -6,6 +6,7 @@ void ffOptionsInitModules(FFOptionsModules* options)
ffInitBatteryOptions(&options->battery);
ffInitBiosOptions(&options->bios);
ffInitBluetoothOptions(&options->bluetooth);
ffInitBluetoothRadioOptions(&options->bluetoothRadio);
ffInitBoardOptions(&options->board);
ffInitBootmgrOptions(&options->bootmgr);
ffInitBreakOptions(&options->break_);
@@ -77,6 +78,7 @@ void ffOptionsDestroyModules(FFOptionsModules* options)
ffDestroyBatteryOptions(&options->battery);
ffDestroyBiosOptions(&options->bios);
ffDestroyBluetoothOptions(&options->bluetooth);
ffDestroyBluetoothRadioOptions(&options->bluetoothRadio);
ffDestroyBoardOptions(&options->board);
ffDestroyBootmgrOptions(&options->bootmgr);
ffDestroyBreakOptions(&options->break_);
+1
View File
@@ -7,6 +7,7 @@ typedef struct FFOptionsModules
FFBatteryOptions battery;
FFBiosOptions bios;
FFBluetoothOptions bluetooth;
FFBluetoothRadioOptions bluetoothRadio;
FFBoardOptions board;
FFBootmgrOptions bootmgr;
FFBreakOptions break_;