1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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;
}
|