master ohmu/fastfetch-openbsd / src / detection / bios / bios_windows.c
ohmu  ·  2026-10-15
  1#include "bios.h"
  2#include "common/debug.h"
  3#include "common/smbios.h"
  4
  5#ifdef _WIN32
  6    #include "common/windows/registry.h"
  7
  8    #include <ntstatus.h>
  9    #include "common/windows/nt.h"
 10#elif __OpenBSD__
 11    #include "common/io.h"
 12
 13    #include <fcntl.h>
 14    #include <unistd.h>
 15#elif __sun
 16    #include <libdevinfo.h>
 17    #include <sys/sunddi.h>
 18#elif __APPLE__
 19    #include "common/apple/cf_helpers.h"
 20    #include <IOKit/IOKitLib.h>
 21#endif
 22
 23typedef struct [[gnu::packed]] FFSmbiosBios {
 24    FFSmbiosHeader Header;
 25
 26    uint8_t Vendor;                      // string
 27    uint8_t BiosVersion;                 // string
 28    uint16_t BiosStartingAddressSegment; // varies
 29    uint8_t BiosReleaseDate;             // string
 30    uint8_t BiosRomSize;                 // string
 31    uint64_t BiosCharacteristics;        // bit field
 32
 33    // 2.4+
 34    uint8_t BiosCharacteristicsExtensionBytes[2];   // bit field
 35    uint8_t SystemBiosMajorRelease;                 // varies
 36    uint8_t SystemBiosMinorRelease;                 // varies
 37    uint8_t EmbeddedControllerFirmwareMajorRelease; // varies
 38    uint8_t EmbeddedControllerFirmwareMinorRelease; // varies
 39
 40    // 3.1+
 41    uint16_t ExtendedBiosRomSize; // bit field
 42} FFSmbiosBios;
 43
 44static_assert(offsetof(FFSmbiosBios, ExtendedBiosRomSize) == 0x18,
 45    "FFSmbiosBios: Wrong struct alignment");
 46
 47const char* ffDetectBios(FFBiosResult* bios) {
 48    const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
 49    if (!smbiosTable) {
 50        FF_DEBUG("BIOS: failed to get SMBIOS data");
 51        return "Failed to get SMBIOS data";
 52    }
 53
 54    const FFSmbiosBios* data = (const FFSmbiosBios*) (*smbiosTable)[FF_SMBIOS_TYPE_BIOS];
 55    if (!data) {
 56        FF_DEBUG("BIOS: section is not found in SMBIOS data");
 57        return "BIOS section is not found in SMBIOS data";
 58    }
 59
 60    const char* strings = (const char*) data + data->Header.Length;
 61
 62    ffStrbufSetStatic(&bios->version, ffSmbiosLocateString(strings, data->BiosVersion));
 63    ffCleanUpSmbiosValue(&bios->version);
 64    ffStrbufSetStatic(&bios->vendor, ffSmbiosLocateString(strings, data->Vendor));
 65    ffCleanUpSmbiosValue(&bios->vendor);
 66    ffStrbufSetStatic(&bios->date, ffSmbiosLocateString(strings, data->BiosReleaseDate));
 67    ffCleanUpSmbiosValue(&bios->date);
 68
 69    if (data->Header.Length > offsetof(FFSmbiosBios, SystemBiosMajorRelease)) {
 70        ffStrbufSetF(&bios->release, "%u.%u", data->SystemBiosMajorRelease, data->SystemBiosMinorRelease);
 71    }
 72
 73#ifdef _WIN32
 74    // Same as GetFirmwareType, but support (?) Windows 7
 75    // https://ntdoc.m417z.com/system_information_class
 76    SYSTEM_BOOT_ENVIRONMENT_INFORMATION sbei;
 77    if (NT_SUCCESS(NtQuerySystemInformation(SystemBootEnvironmentInformation, &sbei, sizeof(sbei), nullptr))) {
 78        switch (sbei.FirmwareType) {
 79            case FirmwareTypeBios:
 80                ffStrbufSetStatic(&bios->type, "BIOS");
 81                break;
 82            case FirmwareTypeUefi:
 83                ffStrbufSetStatic(&bios->type, "UEFI");
 84                break;
 85            default:
 86                break;
 87        }
 88    }
 89#elif __sun
 90    di_node_t rootNode = di_init("/", DINFOPROP);
 91    if (rootNode != DI_NODE_NIL) {
 92        char* efiVersion = nullptr;
 93        if (di_prop_lookup_strings(DDI_DEV_T_ANY, rootNode, "efi-version", &efiVersion) > 0) {
 94            ffStrbufSetStatic(&bios->type, "UEFI");
 95        } else {
 96            ffStrbufSetStatic(&bios->type, "BIOS");
 97        }
 98    }
 99    di_fini(rootNode);
100#elif __HAIKU__ || __OpenBSD__
101    // Currently SMBIOS detection is supported in legacy BIOS only
102    ffStrbufSetStatic(&bios->type, "BIOS");
103#elif __APPLE__
104    // Intel Macs use UEFI from day one
105    FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t deviceEfi = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/efi");
106    ffStrbufSetStatic(&bios->type, deviceEfi ? "UEFI" : "BIOS");
107#endif
108
109    return nullptr;
110}