#include "bios.h" #include "common/smbios.h" #ifdef _WIN32 #include "common/windows/registry.h" #include #include "common/windows/nt.h" #elif __OpenBSD__ #include "common/io.h" #include #include #elif __sun #include #include #elif __APPLE__ #include "common/apple/cf_helpers.h" #include #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; }