Host: split Bios module; init support for Windows

This commit is contained in:
李通洲
2022-10-05 00:41:43 +08:00
parent db88d413c3
commit c7e6e45078
21 changed files with 559 additions and 44 deletions
+40 -7
View File
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs
project(fastfetch
VERSION 1.7.2
LANGUAGES C
LANGUAGES C CXX # Windows part requires C++ compiler
DESCRIPTION "Fast system information tool"
HOMEPAGE_URL "https://github.com/LinusDierheimer/fastfetch"
)
@@ -11,8 +11,10 @@ project(fastfetch
# Target Platform #
###################
if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*|MSYS")
if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*")
set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "MSYS")
set(WIN_MSYS TRUE CACHE BOOL "..." FORCE) # Windows on msys2
elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*")
set(BSD TRUE CACHE BOOL "..." FORCE)
elseif(NOT APPLE AND NOT ANDROID)
@@ -26,7 +28,7 @@ endif()
include(CMakeDependentOption)
cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD" OFF)
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR WIN_MSYS" OFF)
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR BSD" OFF)
@@ -46,7 +48,7 @@ cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR WIN_MSYS" OFF)
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
@@ -76,6 +78,11 @@ message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion")
if(WIN_MSYS)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion")
endif()
# Used for dlopen finding dylibs installed by homebrew
# `/opt/homebrew/lib` is not on in dlopen search path by default
if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX})
@@ -83,7 +90,7 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX})
endif()
set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer")
if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "MSYS")
if(NOT WIN_MSYS)
set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined")
endif()
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}")
@@ -216,6 +223,7 @@ set(LIBFASTFETCH_SRC
src/modules/separator.c
src/modules/os.c
src/modules/host.c
src/modules/bios.c
src/modules/kernel.c
src/modules/uptime.c
src/modules/processes.c
@@ -260,14 +268,14 @@ if(BSD OR APPLE)
)
endif()
if(LINUX OR ANDROID)
if(LINUX OR ANDROID OR WIN_MSYS)
list(APPEND LIBFASTFETCH_SRC
src/detection/cpu/cpu_linux.c
src/detection/memory/memory_linux.c
)
endif()
if(LINUX OR ANDROID OR BSD)
if(LINUX OR ANDROID OR BSD OR WIN_MSYS)
list(APPEND LIBFASTFETCH_SRC
src/detection/cpuUsage/cpuUsage_linux.c
src/detection/disk/disk_linux.c
@@ -279,6 +287,7 @@ endif()
if(LINUX OR BSD)
list(APPEND LIBFASTFETCH_SRC
src/detection/host/host_linux.c
src/detection/bios/bios_linux.c
src/detection/os/os_linux.c
src/detection/gpu/gpu_linux.c
src/detection/battery/battery_linux.c
@@ -294,12 +303,29 @@ if(LINUX OR BSD)
)
endif()
if(WIN_MSYS)
list(APPEND LIBFASTFETCH_SRC
src/detection/host/host_windows.cpp
src/detection/bios/bios_windows.cpp
src/detection/os/os_linux.c
src/detection/gpu/gpu_linux.c
src/detection/battery/battery_linux.c
src/detection/displayserver/displayserver_windows.c
src/detection/terminalfont/terminalfont_linux.c
src/detection/media/media_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/font/font_linux.c
src/util/windows/wmi.cpp
)
endif()
if(APPLE)
list(APPEND LIBFASTFETCH_SRC
src/detection/cpuUsage/cpuUsage_apple.c
src/util/apple/cf_helpers.c
src/util/apple/osascript.m
src/detection/host/host_apple.c
src/detection/bios/bios_apple.c
src/detection/os/os_apple.m
src/detection/cpu/cpu_apple.c
src/detection/gpu/gpu_apple.c
@@ -326,6 +352,7 @@ endif()
if(ANDROID)
list(APPEND LIBFASTFETCH_SRC
src/detection/host/host_android.c
src/detection/bios/bios_android.c
src/detection/os/os_android.c
src/detection/gpu/gpu_android.c
src/detection/battery/battery_android.c
@@ -411,6 +438,12 @@ if(APPLE)
PRIVATE "-framework Cocoa"
PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks"
)
elseif(WIN_MSYS)
target_link_libraries(libfastfetch
PRIVATE "-lwbemuuid"
PRIVATE "-lole32"
PRIVATE "-loleaut32"
)
endif()
target_include_directories(libfastfetch
+1
View File
@@ -162,6 +162,7 @@ static void defaultConfig(FFinstance* instance)
initModuleArg(&instance->config.os);
initModuleArg(&instance->config.host);
initModuleArg(&instance->config.bios);
initModuleArg(&instance->config.kernel);
initModuleArg(&instance->config.uptime);
initModuleArg(&instance->config.processes);
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#ifndef FF_INCLUDED_detection_bios_bios
#define FF_INCLUDED_detection_bios_bios
#include "fastfetch.h"
typedef struct FFBiosResult
{
FFstrbuf biosDate;
FFstrbuf biosRelease;
FFstrbuf biosVendor;
FFstrbuf biosVersion;
FFstrbuf error;
} FFBiosResult;
void ffDetectBios(FFBiosResult* bios);
#endif
+11
View File
@@ -0,0 +1,11 @@
#include "bios.h"
void ffDetectBios(FFBiosResult* bios)
{
ffStrbufInitS(&bios->error, "Not supported on Android");
ffStrbufInit(&bios->biosDate);
ffStrbufInit(&bios->biosRelease);
ffStrbufInit(&bios->biosVendor);
ffStrbufInit(&bios->biosVersion);
}
+11
View File
@@ -0,0 +1,11 @@
#include "bios.h"
void ffDetectBios(FFBiosResult* bios)
{
ffStrbufInitS(&bios->error, "Not supported on macOS");
ffStrbufInit(&bios->biosDate);
ffStrbufInit(&bios->biosRelease);
ffStrbufInit(&bios->biosVendor);
ffStrbufInit(&bios->biosVersion);
}
+58
View File
@@ -0,0 +1,58 @@
#include "bios.h"
#include "common/io.h"
#include <stdlib.h>
static bool hostValueSet(FFstrbuf* value)
{
return
value->length > 0 &&
ffStrbufStartsWithIgnCaseS(value, "To be filled") != true &&
ffStrbufStartsWithIgnCaseS(value, "To be set") != true &&
ffStrbufStartsWithIgnCaseS(value, "OEM") != true &&
ffStrbufStartsWithIgnCaseS(value, "O.E.M.") != true &&
ffStrbufIgnCaseCompS(value, "None") != 0 &&
ffStrbufIgnCaseCompS(value, "System Product") != 0 &&
ffStrbufIgnCaseCompS(value, "System Product Name") != 0 &&
ffStrbufIgnCaseCompS(value, "System Product Version") != 0 &&
ffStrbufIgnCaseCompS(value, "System Name") != 0 &&
ffStrbufIgnCaseCompS(value, "System Version") != 0 &&
ffStrbufIgnCaseCompS(value, "Default string") != 0 &&
ffStrbufIgnCaseCompS(value, "Undefined") != 0 &&
ffStrbufIgnCaseCompS(value, "Not Specified") != 0 &&
ffStrbufIgnCaseCompS(value, "Not Applicable") != 0 &&
ffStrbufIgnCaseCompS(value, "INVALID") != 0 &&
ffStrbufIgnCaseCompS(value, "Type1ProductConfigId") != 0 &&
ffStrbufIgnCaseCompS(value, "All Series") != 0
;
}
static void getHostValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer)
{
ffReadFileBuffer(devicesPath, buffer);
if(hostValueSet(buffer))
return;
ffReadFileBuffer(classPath, buffer);
if(hostValueSet(buffer))
return;
ffStrbufClear(buffer);
}
void ffDetectBios(FFBiosResult* bios)
{
ffStrbufInit(&bios->error);
ffStrbufInit(&bios->biosDate);
getHostValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &bios->biosDate);
ffStrbufInit(&bios->biosRelease);
getHostValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->biosRelease);
ffStrbufInit(&bios->biosVendor);
getHostValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &bios->biosVendor);
ffStrbufInit(&bios->biosVersion);
getHostValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &bios->biosVersion);
}
+38
View File
@@ -0,0 +1,38 @@
extern "C" {
#include "bios.h"
}
#include "util/windows/wmi.hpp"
extern "C" void ffDetectBios(FFBiosResult* bios)
{
ffStrbufInit(&bios->error);
ffStrbufInit(&bios->biosDate);
ffStrbufInit(&bios->biosRelease);
ffStrbufInit(&bios->biosVendor);
ffStrbufInit(&bios->biosVersion);
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, ReleaseDate, Version, Manufacturer FROM Win32_BIOS", &bios->error);
if(!pEnumerator)
return;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if(uReturn == 0)
{
ffStrbufInitS(&bios->error, "No Wmi result returned");
pEnumerator->Release();
return;
}
ffGetWmiObjValue(pclsObj, L"Name", &bios->biosRelease);
ffGetWmiObjValue(pclsObj, L"ReleaseDate", &bios->biosDate);
ffGetWmiObjValue(pclsObj, L"Version", &bios->biosVersion);
ffGetWmiObjValue(pclsObj, L"Manufacturer", &bios->biosVendor);
pclsObj->Release();
pEnumerator->Release();
}
@@ -0,0 +1,14 @@
#include "displayserver.h"
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance)
{
FF_UNUSED(instance);
ffStrbufInitA(&ds->wmProcessName, 0);
ffStrbufInitA(&ds->wmPrettyName, 0);
ffStrbufInitA(&ds->wmProtocolName, 0);
ffStrbufInitA(&ds->deProcessName, 0);
ffStrbufInitA(&ds->dePrettyName, 0);
ffStrbufInitA(&ds->deVersion, 0);
ffListInitA(&ds->resolutions, sizeof(FFResolutionResult), 0);
}
+1 -4
View File
@@ -14,10 +14,6 @@ typedef struct FFHostResult
FFstrbuf productName;
FFstrbuf productVersion;
FFstrbuf productSku;
FFstrbuf biosDate;
FFstrbuf biosRelease;
FFstrbuf biosVendor;
FFstrbuf biosVersion;
FFstrbuf boardName;
FFstrbuf boardVendor;
FFstrbuf boardVersion;
@@ -25,6 +21,7 @@ typedef struct FFHostResult
FFstrbuf chassisVendor;
FFstrbuf chassisVersion;
FFstrbuf sysVendor;
FFstrbuf error;
} FFHostResult;
const FFHostResult* ffDetectHost();
+2 -4
View File
@@ -4,6 +4,8 @@
void ffDetectHostImpl(FFHostResult* host)
{
ffStrbufInit(&host->error);
//Family
ffStrbufInit(&host->productFamily);
@@ -32,10 +34,6 @@ void ffDetectHostImpl(FFHostResult* host)
ffStrbufInitA(&host->productVersion, 0);
ffStrbufInitA(&host->productSku, 0);
ffStrbufInitA(&host->biosDate, 0);
ffStrbufInitA(&host->biosRelease, 0);
ffStrbufInitA(&host->biosVendor, 0);
ffStrbufInitA(&host->biosVersion, 0);
ffStrbufInitA(&host->boardName, 0);
ffStrbufInitA(&host->boardVendor, 0);
ffStrbufInitA(&host->boardVersion, 0);
+4 -6
View File
@@ -112,16 +112,14 @@ static const char* getProductName(const FFstrbuf* hwModel)
void ffDetectHostImpl(FFHostResult* host)
{
ffStrbufInit(&host->error);
ffStrbufInit(&host->productName);
ffStrbufInit(&host->productFamily);
ffStrbufInit(&host->productVersion);
ffStrbufInit(&host->productSku);
ffStrbufInitA(&host->sysVendor, 0);
ffStrbufInitA(&host->productVersion, 0);
ffStrbufInitA(&host->productSku, 0);
ffStrbufInitA(&host->biosDate, 0);
ffStrbufInitA(&host->biosRelease, 0);
ffStrbufInitA(&host->biosVendor, 0);
ffStrbufInitA(&host->biosVersion, 0);
ffStrbufInitA(&host->boardName, 0);
ffStrbufInitA(&host->boardVendor, 0);
ffStrbufInitA(&host->boardVersion, 0);
+2 -12
View File
@@ -60,6 +60,8 @@ static void getHostProductName(FFstrbuf* name)
void ffDetectHostImpl(FFHostResult* host)
{
ffStrbufInit(&host->error);
ffStrbufInit(&host->productFamily);
getHostValue("/sys/devices/virtual/dmi/id/product_family", "/sys/class/dmi/id/product_family", &host->productFamily);
@@ -72,18 +74,6 @@ void ffDetectHostImpl(FFHostResult* host)
ffStrbufInit(&host->productSku);
getHostValue("/sys/devices/virtual/dmi/id/product_sku", "/sys/class/dmi/id/product_sku", &host->productSku);
ffStrbufInit(&host->biosDate);
getHostValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &host->biosDate);
ffStrbufInit(&host->biosRelease);
getHostValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &host->biosRelease);
ffStrbufInit(&host->biosVendor);
getHostValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &host->biosVendor);
ffStrbufInit(&host->biosVersion);
getHostValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &host->biosVersion);
ffStrbufInit(&host->boardName);
getHostValue("/sys/devices/virtual/dmi/id/board_name", "/sys/class/dmi/id/board_name", &host->boardName);
+45
View File
@@ -0,0 +1,45 @@
extern "C" {
#include "host.h"
}
#include "util/windows/wmi.hpp"
extern "C" void ffDetectHostImpl(FFHostResult* host)
{
ffStrbufInit(&host->error);
ffStrbufInit(&host->productName);
ffStrbufInit(&host->productFamily);
ffStrbufInit(&host->productVersion);
ffStrbufInit(&host->productSku);
ffStrbufInit(&host->sysVendor);
ffStrbufInit(&host->boardName);
ffStrbufInit(&host->boardVendor);
ffStrbufInit(&host->boardVersion);
ffStrbufInit(&host->chassisType);
ffStrbufInit(&host->chassisVendor);
ffStrbufInit(&host->chassisVersion);
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, Version, SKUNumber, Vendor FROM Win32_ComputerSystemProduct", &host->error);
if(!pEnumerator)
return;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if(uReturn == 0)
{
ffStrbufInitS(&host->error, "No Wmi result returned");
pEnumerator->Release();
return;
}
ffGetWmiObjValue(pclsObj, L"Name", &host->productName);
ffGetWmiObjValue(pclsObj, L"Version", &host->productVersion);
ffGetWmiObjValue(pclsObj, L"SKUNumber", &host->productSku);
ffGetWmiObjValue(pclsObj, L"Vendor", &host->sysVendor);
pclsObj->Release();
pEnumerator->Release();
}
+1 -1
View File
@@ -159,7 +159,7 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
{
const FFHostResult* host = ffDetectHost();
if(ffStrbufCompS(&host->productName, FF_HOST_PRODUCT_NAME_WSL) == 0 ||
ffStrbufCompS(&host->productName, FF_HOST_PRODUCT_NAME_MSYS) == 0)
ffStrbufCompS(&host->productName, FF_HOST_PRODUCT_NAME_MSYS) == 0) //TODO better WSL or MSYS detection
term = "conhost";
}
+18 -5
View File
@@ -71,15 +71,11 @@ static inline void printCommandHelp(const char* command)
}
else if(strcasecmp(command, "host-format") == 0)
{
constructAndPrintCommandHelpFormat("host", "{2} {3}", 15,
constructAndPrintCommandHelpFormat("host", "{2} {3}", 11,
"product family",
"product name",
"product version",
"product sku",
"bios date",
"bios release",
"bios vendor",
"bios version",
"board name",
"board vendor",
"board version",
@@ -89,6 +85,15 @@ static inline void printCommandHelp(const char* command)
"sys vendor"
);
}
else if(strcasecmp(command, "bios-format") == 0)
{
constructAndPrintCommandHelpFormat("bios", "{2} {3}", 4,
"bios date",
"bios release",
"bios vendor",
"bios version"
);
}
else if(strcasecmp(command, "kernel-format") == 0)
{
constructAndPrintCommandHelpFormat("kernel", "{2}", 3,
@@ -978,6 +983,12 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con
optionParseString(key, value, &instance->config.host.outputFormat);
else if(strcasecmp(key, "--host-error") == 0)
optionParseString(key, value, &instance->config.host.errorFormat);
else if(strcasecmp(key, "--bios-key") == 0)
optionParseString(key, value, &instance->config.bios.key);
else if(strcasecmp(key, "--bios-format") == 0)
optionParseString(key, value, &instance->config.bios.outputFormat);
else if(strcasecmp(key, "--bios-error") == 0)
optionParseString(key, value, &instance->config.bios.errorFormat);
else if(strcasecmp(key, "--kernel-key") == 0)
optionParseString(key, value, &instance->config.kernel.key);
else if(strcasecmp(key, "--kernel-format") == 0)
@@ -1367,6 +1378,8 @@ static void parseStructureCommand(FFinstance* instance, FFdata* data, const char
ffPrintOS(instance);
else if(strcasecmp(line, "host") == 0)
ffPrintHost(instance);
else if(strcasecmp(line, "bios") == 0)
ffPrintBios(instance);
else if(strcasecmp(line, "kernel") == 0)
ffPrintKernel(instance);
else if(strcasecmp(line, "uptime") == 0)
+2
View File
@@ -94,6 +94,7 @@ typedef struct FFconfig
FFModuleArgs os;
FFModuleArgs host;
FFModuleArgs bios;
FFModuleArgs kernel;
FFModuleArgs uptime;
FFModuleArgs processes;
@@ -249,6 +250,7 @@ void ffPrintTitle(FFinstance* instance);
void ffPrintSeparator(FFinstance* instance);
void ffPrintOS(FFinstance* instance);
void ffPrintHost(FFinstance* instance);
void ffPrintBios(FFinstance* instance);
void ffPrintKernel(FFinstance* instance);
void ffPrintUptime(FFinstance* instance);
void ffPrintProcesses(FFinstance* instance);
+1
View File
@@ -22,6 +22,7 @@ int main(int argc, char** argv)
ffPrintSeparator(&instance);
ffPrintOS(&instance);
ffPrintHost(&instance);
//ffPrintBios(&instance);
ffPrintKernel(&instance);
ffPrintUptime(&instance);
//ffPrintProcesses(&instance);
+42
View File
@@ -0,0 +1,42 @@
#include "fastfetch.h"
#include "common/printing.h"
#include "common/caching.h"
#include "detection/bios/bios.h"
#define FF_BIOS_MODULE_NAME "Bios"
#define FF_BIOS_NUM_FORMAT_ARGS 4
void ffPrintBios(FFinstance* instance)
{
if(ffPrintFromCache(instance, FF_BIOS_MODULE_NAME, &instance->config.bios, FF_BIOS_NUM_FORMAT_ARGS))
return;
FFBiosResult result;
ffDetectBios(&result);
if(result.error.length > 0)
{
ffPrintError(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios, "%*s", result.error.length, result.error.chars);
goto exit;
}
if(result.biosRelease.length == 0)
{
ffPrintError(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios, "bios_release is not set.");
goto exit;
}
ffPrintAndWriteToCache(instance, FF_BIOS_MODULE_NAME, &instance->config.bios, &result.biosRelease, FF_BIOS_NUM_FORMAT_ARGS, (FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &result.biosDate},
{FF_FORMAT_ARG_TYPE_STRBUF, &result.biosRelease},
{FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVendor},
{FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVersion},
});
exit:
ffStrbufDestroy(&result.biosDate);
ffStrbufDestroy(&result.biosRelease);
ffStrbufDestroy(&result.biosVendor);
ffStrbufDestroy(&result.biosVersion);
ffStrbufDestroy(&result.error);
}
+7 -5
View File
@@ -4,7 +4,7 @@
#include "detection/host/host.h"
#define FF_HOST_MODULE_NAME "Host"
#define FF_HOST_NUM_FORMAT_ARGS 15
#define FF_HOST_NUM_FORMAT_ARGS 11
void ffPrintHost(FFinstance* instance)
{
@@ -13,6 +13,12 @@ void ffPrintHost(FFinstance* instance)
const FFHostResult* host = ffDetectHost();
if(host->error.length > 0)
{
ffPrintError(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host, "%*s", host->error.length, host->error.chars);
return;
}
if(host->productFamily.length == 0 && host->productName.length == 0)
{
ffPrintError(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host, "neither product_family nor product_name is set by O.E.M.");
@@ -38,10 +44,6 @@ void ffPrintHost(FFinstance* instance)
{FF_FORMAT_ARG_TYPE_STRBUF, &host->productName},
{FF_FORMAT_ARG_TYPE_STRBUF, &host->productVersion},
{FF_FORMAT_ARG_TYPE_STRBUF, &host->productSku},
{FF_FORMAT_ARG_TYPE_STRBUF, &host->biosDate},
{FF_FORMAT_ARG_TYPE_STRBUF, &host->biosRelease},
{FF_FORMAT_ARG_TYPE_STRBUF, &host->biosVendor},
{FF_FORMAT_ARG_TYPE_STRBUF, &host->biosVersion},
{FF_FORMAT_ARG_TYPE_STRBUF, &host->boardName},
{FF_FORMAT_ARG_TYPE_STRBUF, &host->boardVendor},
{FF_FORMAT_ARG_TYPE_STRBUF, &host->boardVersion},
+199
View File
@@ -0,0 +1,199 @@
#include "wmi.hpp"
#include <synchapi.h>
//https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-the-local-computer
//https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/computer-system-hardware-classes
static void CoUninitializeWrap()
{
CoUninitialize();
}
static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext)
{
static char error[128];
*((char**)lpContext) = error;
HRESULT hres;
// Initialize COM
hres = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
// Set general COM security levels
hres = CoInitializeSecurity(
nullptr,
-1, // COM authentication
nullptr, // Authentication services
nullptr, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
nullptr, // Authentication info
EOAC_NONE, // Additional capabilities
nullptr // Reserved
);
if (FAILED(hres))
{
CoUninitialize();
snprintf(error, sizeof(error), "Failed to initialize security. Error code = 0x%X", hres);
return FALSE;
}
// Obtain the initial locator to WMI
IWbemLocator* pLoc = nullptr;
hres = CoCreateInstance(
CLSID_WbemLocator,
nullptr,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(LPVOID*) &pLoc);
if (FAILED(hres))
{
CoUninitialize();
snprintf(error, sizeof(error), "Failed to create IWbemLocator object. Error code = 0x%X", hres);
return FALSE;
}
// Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServices* pSvc = nullptr;
// Connect to the root\cimv2 namespace with
// the current user and obtain pointer pSvc
// to make IWbemServices calls.
hres = pLoc->ConnectServer(
bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
nullptr, // User name. nullptr = current user
nullptr, // User password. nullptr = current
0, // Locale. nullptr indicates current
0, // Security flags.
0, // Authority (for example, Kerberos)
0, // Context object
&pSvc // pointer to IWbemServices proxy
);
pLoc->Release();
pLoc = nullptr;
if (FAILED(hres))
{
CoUninitialize();
snprintf(error, sizeof(error), "Could not connect WMI server. Error code = 0x%X", hres);
return FALSE;
}
// 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();
CoUninitialize();
snprintf(error, sizeof(error), "Could not set proxy blanket. Error code = 0x%X", hres);
return FALSE;
}
*((IWbemServices**)lpContext) = pSvc;
atexit(CoUninitializeWrap);
return TRUE;
}
IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error)
{
static INIT_ONCE s_InitOnce = INIT_ONCE_STATIC_INIT;
const char* context;
if (InitOnceExecuteOnce(&s_InitOnce, &InitHandleFunction, nullptr, (void**)&context) == FALSE)
{
if(error)
ffStrbufInitS(error, context);
return nullptr;
}
// Use the IWbemServices pointer to make requests of WMI
IEnumWbemClassObject* pEnumerator = nullptr;
HRESULT hres;
hres = ((IWbemServices*)context)->ExecQuery(
bstr_t(L"WQL"),
bstr_t(queryStr),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
nullptr,
&pEnumerator);
if (FAILED(hres))
{
if(error)
ffStrbufAppendF(error, "Query for '%ls' failed. Error code = 0x%X", queryStr, hres);
return nullptr;
}
return pEnumerator;
}
void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) {
int len = (int)SysStringLen(bstr);
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;
}
bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf)
{
bool result = true;
VARIANT vtProp;
VariantInit(&vtProp);
CIMTYPE type;
if(FAILED(obj->Get(key, 0, &vtProp, &type, nullptr)) || vtProp.vt == VT_EMPTY || vtProp.vt == VT_NULL)
{
result = false;
}
else
{
switch(type)
{
case CIM_ILLEGAL:
case CIM_EMPTY: result = false; break;
case CIM_SINT8: ffStrbufAppendF(strbuf, "%d", (int)vtProp.cVal); break;
case CIM_SINT16: ffStrbufAppendF(strbuf, "%d", (int)vtProp.iVal); break;
case CIM_SINT32: ffStrbufAppendF(strbuf, "%d", (int)vtProp.intVal); break;
case CIM_SINT64: ffStrbufAppendF(strbuf, "%lld", vtProp.llVal); break;
case CIM_UINT8: ffStrbufAppendF(strbuf, "%u", (unsigned)vtProp.bVal); break;
case CIM_UINT16: ffStrbufAppendF(strbuf, "%u", (unsigned)vtProp.uiVal); break;
case CIM_UINT32: ffStrbufAppendF(strbuf, "%u", (unsigned)vtProp.uintVal); break;
case CIM_UINT64: ffStrbufAppendF(strbuf, "%llu", vtProp.ullVal); break;
case CIM_REAL32: ffStrbufAppendF(strbuf, "%f", vtProp.fltVal); break;
case CIM_REAL64: ffStrbufAppendF(strbuf, "%f", vtProp.dblVal); break;
case CIM_BOOLEAN: ffStrbufAppendF(strbuf, "%s", vtProp.boolVal ? "True" : "False"); break;
case CIM_STRING: ffBstrToStrbuf(vtProp.bstrVal, strbuf); break;
case CIM_DATETIME: {
ISWbemDateTime *pDateTime;
BSTR dateStr;
if(FAILED(CoCreateInstance(__uuidof(SWbemDateTime), 0, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDateTime))))
result = false;
else if(FAILED(pDateTime->put_Value(vtProp.bstrVal)))
result = false;
else if(FAILED(pDateTime->GetFileTime(VARIANT_TRUE, &dateStr)))
result = false;
else
ffBstrToStrbuf(dateStr, strbuf);
break;
};
default: result = false; break;
}
}
VariantClear(&vtProp);
return result;
}
+43
View File
@@ -0,0 +1,43 @@
#pragma once
#ifndef FF_INCLUDED_util_windows_wmi
#define FF_INCLUDED_util_windows_wmi
#ifdef __cplusplus
extern "C" {
#include "util/FFstrbuf.h"
}
#include <Wbemidl.h>
//<comdef.h> is not usable in MSYS, so provide our simple bstr_t implementation
struct bstr_t
{
explicit bstr_t(const wchar_t* str) noexcept: _bstr(SysAllocString(str)) {}
~bstr_t() noexcept { SysFreeString(_bstr); }
explicit operator const wchar_t*() const noexcept {
return _bstr;
}
operator BSTR() const noexcept {
return _bstr;
}
private:
BSTR _bstr;
};
void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf);
IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error);
bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf);
#else
// Win32 COM headers requires C++ compiler
#error Must be included in C++ source file
#endif //__cplusplus
#endif //FF_INCLUDED_util_windows_wmi