diff options
Diffstat (limited to 'src/detection/bios')
| -rw-r--r-- | src/detection/bios/bios.h | 14 | ||||
| -rw-r--r-- | src/detection/bios/bios_android.c | 16 | ||||
| -rw-r--r-- | src/detection/bios/bios_apple.c | 58 | ||||
| -rw-r--r-- | src/detection/bios/bios_bsd.c | 31 | ||||
| -rw-r--r-- | src/detection/bios/bios_linux.c | 21 | ||||
| -rw-r--r-- | src/detection/bios/bios_nbsd.c | 20 | ||||
| -rw-r--r-- | src/detection/bios/bios_nosupport.c | 5 | ||||
| -rw-r--r-- | src/detection/bios/bios_windows.c | 107 |
8 files changed, 272 insertions, 0 deletions
diff --git a/src/detection/bios/bios.h b/src/detection/bios/bios.h new file mode 100644 index 0000000..cdb48c2 --- /dev/null +++ b/src/detection/bios/bios.h @@ -0,0 +1,14 @@ +#pragma once + +#include "fastfetch.h" +#include "modules/bios/option.h" + +typedef struct FFBiosResult { + FFstrbuf date; + FFstrbuf release; + FFstrbuf vendor; + FFstrbuf version; + FFstrbuf type; +} FFBiosResult; + +const char* ffDetectBios(FFBiosResult* bios); diff --git a/src/detection/bios/bios_android.c b/src/detection/bios/bios_android.c new file mode 100644 index 0000000..a53db0d --- /dev/null +++ b/src/detection/bios/bios_android.c @@ -0,0 +1,16 @@ +#include "bios.h" +#include "common/settings.h" + +const char* ffDetectBios(FFBiosResult* bios) { + if (!ffSettingsGetAndroidProperty("ro.bootloader", &bios->version)) { + ffSettingsGetAndroidProperty("ro.boot.bootloader", &bios->version); + } + + if (ffStrbufIgnCaseEqualS(&bios->version, "unknown")) { + ffStrbufClear(&bios->version); + } + + ffStrbufSetStatic(&bios->type, "Bootloader"); + + return NULL; +} diff --git a/src/detection/bios/bios_apple.c b/src/detection/bios/bios_apple.c new file mode 100644 index 0000000..6b046d2 --- /dev/null +++ b/src/detection/bios/bios_apple.c @@ -0,0 +1,58 @@ +#include "bios.h" +#include "common/apple/cf_helpers.h" + +#include <IOKit/IOKitLib.h> + +const char* ffDetectBios(FFBiosResult* bios) { +#ifndef __aarch64__ + + // https://github.com/osquery/osquery/blob/master/osquery/tables/system/darwin/smbios_tables.cpp + // For Intel + FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t deviceRom = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/rom"); + if (!deviceRom) { + return "IODeviceTree:/rom not found"; + } + + FF_CFTYPE_AUTO_RELEASE CFMutableDictionaryRef deviceRomProps = NULL; + if (IORegistryEntryCreateCFProperties(deviceRom, &deviceRomProps, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) { + return "IORegistryEntryCreateCFProperties(deviceRom) failed"; + } + + ffCfDictGetString(deviceRomProps, CFSTR("vendor"), &bios->vendor); + ffCfDictGetString(deviceRomProps, CFSTR("version"), &bios->version); + ffCfDictGetString(deviceRomProps, CFSTR("release-date"), &bios->date); + ffStrbufSetStatic(&bios->type, "UEFI"); + +#else + + // For arm64 + FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t device = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/"); + if (!device) { + return "IODeviceTree:/ not found"; + } + + FF_CFTYPE_AUTO_RELEASE CFDataRef manufacturer = IORegistryEntryCreateCFProperty(device, CFSTR("manufacturer"), kCFAllocatorDefault, kNilOptions); + ffCfStrGetString(manufacturer, &bios->vendor); + FF_CFTYPE_AUTO_RELEASE CFDataRef timeStamp = IORegistryEntryCreateCFProperty(device, CFSTR("time-stamp"), kCFAllocatorDefault, kNilOptions); + ffCfStrGetString(timeStamp, &bios->date); + + FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t deviceChosen = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/chosen"); + if (deviceChosen) { + FF_CFTYPE_AUTO_RELEASE CFStringRef tag = IORegistryEntryCreateCFProperty(deviceChosen, CFSTR("iboot-stage-one-tag"), kCFAllocatorDefault, kNilOptions) + ?: IORegistryEntryCreateCFProperty(deviceChosen, CFSTR("system-firmware-version"), kCFAllocatorDefault, kNilOptions); + if (tag) { + ffCfStrGetString(tag, &bios->version); + uint32_t index = ffStrbufFirstIndexC(&bios->version, '-'); + if (index != bios->version.length) { + ffStrbufAppendNS(&bios->type, index, bios->version.chars); + ffStrbufRemoveSubstr(&bios->version, 0, index + 1); + } + } + } + if (!bios->type.length) { + ffStrbufSetStatic(&bios->type, "iBoot"); + } +#endif + + return NULL; +} diff --git a/src/detection/bios/bios_bsd.c b/src/detection/bios/bios_bsd.c new file mode 100644 index 0000000..66e50ea --- /dev/null +++ b/src/detection/bios/bios_bsd.c @@ -0,0 +1,31 @@ +#include "bios.h" + +#include "common/settings.h" +#include "common/sysctl.h" +#include "common/io.h" +#include "common/smbios.h" + +const char* ffDetectBios(FFBiosResult* result) { + ffSettingsGetFreeBSDKenv("smbios.bios.reldate", &result->date); + ffCleanUpSmbiosValue(&result->date); + ffSettingsGetFreeBSDKenv("smbios.bios.revision", &result->release); + ffCleanUpSmbiosValue(&result->release); + ffSettingsGetFreeBSDKenv("smbios.bios.vendor", &result->vendor); + ffCleanUpSmbiosValue(&result->vendor); + ffSettingsGetFreeBSDKenv("smbios.bios.version", &result->version); + ffCleanUpSmbiosValue(&result->version); + ffSysctlGetString("machdep.bootmethod", &result->type); + + if (result->type.length == 0) { + if (ffSettingsGetFreeBSDKenv("loader.efi", &result->type)) { + ffStrbufSetStatic(&result->type, ffStrbufEqualS(&result->type, "1") ? "UEFI" : "BIOS"); + } else { + ffStrbufSetStatic(&result->type, + ffPathExists("/dev/efi" /*efidev*/, FF_PATHTYPE_FILE) || + ffPathExists("/boot/efi/efi/" /*efi partition. Note /boot/efi exists on BIOS system*/, FF_PATHTYPE_DIRECTORY) + ? "UEFI" + : "BIOS"); + } + } + return NULL; +} diff --git a/src/detection/bios/bios_linux.c b/src/detection/bios/bios_linux.c new file mode 100644 index 0000000..8776631 --- /dev/null +++ b/src/detection/bios/bios_linux.c @@ -0,0 +1,21 @@ +#include "bios.h" +#include "common/io.h" +#include "common/smbios.h" + +const char* ffDetectBios(FFBiosResult* bios) { + if (ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &bios->date)) { + ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->release); + ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &bios->vendor); + ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &bios->version); + } else if (ffReadFileBuffer("/proc/device-tree/chosen/u-boot,version", &bios->version)) { + ffStrbufTrimRight(&bios->version, '\0'); + ffStrbufSetStatic(&bios->vendor, "U-Boot"); + } + + if (ffPathExists("/sys/firmware/efi/", FF_PATHTYPE_DIRECTORY) || ffPathExists("/sys/firmware/acpi/tables/UEFI", FF_PATHTYPE_FILE)) { + ffStrbufSetStatic(&bios->type, "UEFI"); + } else { + ffStrbufSetStatic(&bios->type, "BIOS"); + } + return NULL; +} diff --git a/src/detection/bios/bios_nbsd.c b/src/detection/bios/bios_nbsd.c new file mode 100644 index 0000000..3ab43ed --- /dev/null +++ b/src/detection/bios/bios_nbsd.c @@ -0,0 +1,20 @@ +#include "bios.h" +#include "common/sysctl.h" +#include "common/smbios.h" +#include "common/io.h" + +const char* ffDetectBios(FFBiosResult* bios) { + if (ffSysctlGetString("machdep.dmi.bios-date", &bios->date) == NULL) { + ffCleanUpSmbiosValue(&bios->date); + } + if (ffSysctlGetString("machdep.dmi.bios-version", &bios->version) == NULL) { + ffCleanUpSmbiosValue(&bios->version); + } + if (ffSysctlGetString("machdep.dmi.bios-vendor", &bios->vendor) == NULL) { + ffCleanUpSmbiosValue(&bios->vendor); + } + if (ffSysctlGetString("machdep.bootmethod", &bios->type) != NULL) { + ffStrbufSetStatic(&bios->type, ffPathExists("/dev/efi", FF_PATHTYPE_FILE) ? "UEFI" : "BIOS"); + } + return NULL; +} diff --git a/src/detection/bios/bios_nosupport.c b/src/detection/bios/bios_nosupport.c new file mode 100644 index 0000000..e044835 --- /dev/null +++ b/src/detection/bios/bios_nosupport.c @@ -0,0 +1,5 @@ +#include "bios.h" + +const char* ffDetectBios(FF_A_UNUSED FFBiosResult* bios) { + return "Not supported on this platform"; +} diff --git a/src/detection/bios/bios_windows.c b/src/detection/bios/bios_windows.c new file mode 100644 index 0000000..42b7674 --- /dev/null +++ b/src/detection/bios/bios_windows.c @@ -0,0 +1,107 @@ +#include "bios.h" +#include "common/smbios.h" + +#ifdef _WIN32 + #include "common/windows/registry.h" + + #include <ntstatus.h> + #include "common/windows/nt.h" +#elif __OpenBSD__ + #include "common/io.h" + + #include <fcntl.h> + #include <unistd.h> +#elif __sun + #include <libdevinfo.h> + #include <sys/sunddi.h> +#elif __APPLE__ + #include "common/apple/cf_helpers.h" + #include <IOKit/IOKitLib.h> +#endif + +typedef struct FFSmbiosBios { + FFSmbiosHeader Header; + + uint8_t Vendor; // string + uint8_t BiosVersion; // string + uint16_t BiosStartingAddressSegment; // varies + uint8_t BiosReleaseDate; // string + uint8_t BiosRomSize; // string + uint64_t BiosCharacteristics; // bit field + + // 2.4+ + uint8_t BiosCharacteristicsExtensionBytes[2]; // bit field + uint8_t SystemBiosMajorRelease; // varies + uint8_t SystemBiosMinorRelease; // varies + uint8_t EmbeddedControllerFirmwareMajorRelease; // varies + uint8_t EmbeddedControllerFirmwareMinorRelease; // varies + + // 3.1+ + uint16_t ExtendedBiosRomSize; // bit field +} FF_A_PACKED FFSmbiosBios; + +static_assert(offsetof(FFSmbiosBios, ExtendedBiosRomSize) == 0x18, + "FFSmbiosBios: Wrong struct alignment"); + +const char* ffDetectBios(FFBiosResult* bios) { + const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable(); + if (!smbiosTable) { + return "Failed to get SMBIOS data"; + } + + const FFSmbiosBios* data = (const FFSmbiosBios*) (*smbiosTable)[FF_SMBIOS_TYPE_BIOS]; + if (!data) { + return "BIOS section is not found in SMBIOS data"; + } + + const char* strings = (const char*) data + data->Header.Length; + + ffStrbufSetStatic(&bios->version, ffSmbiosLocateString(strings, data->BiosVersion)); + ffCleanUpSmbiosValue(&bios->version); + ffStrbufSetStatic(&bios->vendor, ffSmbiosLocateString(strings, data->Vendor)); + ffCleanUpSmbiosValue(&bios->vendor); + ffStrbufSetStatic(&bios->date, ffSmbiosLocateString(strings, data->BiosReleaseDate)); + ffCleanUpSmbiosValue(&bios->date); + + if (data->Header.Length > offsetof(FFSmbiosBios, SystemBiosMajorRelease)) { + ffStrbufSetF(&bios->release, "%u.%u", data->SystemBiosMajorRelease, data->SystemBiosMinorRelease); + } + +#ifdef _WIN32 + // Same as GetFirmwareType, but support (?) Windows 7 + // https://ntdoc.m417z.com/system_information_class + SYSTEM_BOOT_ENVIRONMENT_INFORMATION sbei; + if (NT_SUCCESS(NtQuerySystemInformation(SystemBootEnvironmentInformation, &sbei, sizeof(sbei), NULL))) { + switch (sbei.FirmwareType) { + case FirmwareTypeBios: + ffStrbufSetStatic(&bios->type, "BIOS"); + break; + case FirmwareTypeUefi: + ffStrbufSetStatic(&bios->type, "UEFI"); + break; + default: + break; + } + } +#elif __sun + di_node_t rootNode = di_init("/", DINFOPROP); + if (rootNode != DI_NODE_NIL) { + char* efiVersion = NULL; + if (di_prop_lookup_strings(DDI_DEV_T_ANY, rootNode, "efi-version", &efiVersion) > 0) { + ffStrbufSetStatic(&bios->type, "UEFI"); + } else { + ffStrbufSetStatic(&bios->type, "BIOS"); + } + } + di_fini(rootNode); +#elif __HAIKU__ || __OpenBSD__ + // Currently SMBIOS detection is supported in legacy BIOS only + ffStrbufSetStatic(&bios->type, "BIOS"); +#elif __APPLE__ + // Intel Macs use UEFI from day one + FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t deviceEfi = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/efi"); + ffStrbufSetStatic(&bios->type, deviceEfi ? "UEFI" : "BIOS"); +#endif + + return NULL; +} |