master ohmu/fastfetch-openbsd / src / detection / host / host_windows.c
ohmu  ·  2026-10-15
 1#include "host.h"
 2#include "common/debug.h"
 3#include "common/endian.h"
 4#include "common/smbios.h"
 5
 6typedef struct [[gnu::packed]] FFSmbiosSystemInfo {
 7    FFSmbiosHeader Header;
 8
 9    uint8_t Manufacturer; // string
10    uint8_t ProductName;  // string
11    uint8_t Version;      // string
12    uint8_t SerialNumber; // string
13
14    // 2.1+
15    struct [[gnu::packed]] {
16        uint32_t TimeLow;
17        uint16_t TimeMid;
18        uint16_t TimeHighAndVersion;
19        uint8_t ClockSeqHiAndReserved;
20        uint8_t ClockSeqLow;
21        uint8_t Node[6];
22    } UUID; // varies
23    uint8_t WakeUpType; // enum
24
25    // 2.4+
26    uint8_t SKUNumber; // string
27    uint8_t Family;    // string
28} FFSmbiosSystemInfo;
29
30static_assert(offsetof(FFSmbiosSystemInfo, Family) == 0x1A,
31    "FFSmbiosSystemInfo: Wrong struct alignment");
32
33const char* ffDetectHost(FFHostResult* host) {
34    const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
35    if (!smbiosTable) {
36        FF_DEBUG("System information: failed to get SMBIOS data");
37        return "Failed to get SMBIOS data";
38    }
39
40    const FFSmbiosSystemInfo* data = (const FFSmbiosSystemInfo*) (*smbiosTable)[FF_SMBIOS_TYPE_SYSTEM_INFO];
41    if (!data) {
42        FF_DEBUG("System information: section is not found in SMBIOS data");
43        return "System information is not found in SMBIOS data";
44    }
45
46    const char* strings = (const char*) data + data->Header.Length;
47
48    ffStrbufSetStatic(&host->vendor, ffSmbiosLocateString(strings, data->Manufacturer));
49    ffCleanUpSmbiosValue(&host->vendor);
50    ffStrbufSetStatic(&host->name, ffSmbiosLocateString(strings, data->ProductName));
51    ffCleanUpSmbiosValue(&host->name);
52    ffStrbufSetStatic(&host->version, ffSmbiosLocateString(strings, data->Version));
53    ffCleanUpSmbiosValue(&host->version);
54    ffStrbufSetStatic(&host->serial, ffSmbiosLocateString(strings, data->SerialNumber));
55    ffCleanUpSmbiosValue(&host->serial);
56
57    static_assert(offsetof(FFSmbiosSystemInfo, UUID) == 0x08, "FFSmbiosSystemInfo.UUID offset is wrong");
58    if (data->Header.Length > offsetof(FFSmbiosSystemInfo, UUID)) {
59           ffStrbufSetF(&host->uuid, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
60              FF_READ_LE(data->UUID.TimeLow),
61              FF_READ_LE(data->UUID.TimeMid),
62              FF_READ_LE(data->UUID.TimeHighAndVersion),
63              data->UUID.ClockSeqHiAndReserved,
64              data->UUID.ClockSeqLow,
65              data->UUID.Node[0], data->UUID.Node[1], data->UUID.Node[2],
66              data->UUID.Node[3], data->UUID.Node[4], data->UUID.Node[5]);
67    }
68
69    static_assert(offsetof(FFSmbiosSystemInfo, SKUNumber) == 0x19, "FFSmbiosSystemInfo.SKUNumber offset is wrong");
70    if (data->Header.Length > offsetof(FFSmbiosSystemInfo, SKUNumber)) {
71        ffStrbufSetStatic(&host->sku, ffSmbiosLocateString(strings, data->SKUNumber));
72        ffCleanUpSmbiosValue(&host->sku);
73    }
74
75    if (data->Header.Length > offsetof(FFSmbiosSystemInfo, Family)) {
76        ffStrbufSetStatic(&host->family, ffSmbiosLocateString(strings, data->Family));
77        ffCleanUpSmbiosValue(&host->family);
78    }
79
80#if __x86_64__
81    ffHostDetectMac(host);
82#endif
83
84    return nullptr;
85}