master ohmu/fastfetch-openbsd / src / detection / bootmgr / bootmgr_apple.c
ohmu  ·  2026-10-15
 1#include "bootmgr.h"
 2#include "common/io.h"
 3#include "common/debug.h"
 4#include "common/apple/cf_helpers.h"
 5
 6#include <IOKit/IOKitLib.h>
 7
 8static const char* detectSecureBoot(bool* result) {
 9#if __aarch64__
10    FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDevice = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/chosen");
11    if (!entryDevice) {
12        FF_DEBUG("IORegistryEntryFromPath(\"IODeviceTree:/chosen\") failed");
13        return "IORegistryEntryFromPath() failed";
14    }
15
16    FF_CFTYPE_AUTO_RELEASE CFTypeRef prop = IORegistryEntryCreateCFProperty(entryDevice, CFSTR("secure-boot"), kCFAllocatorDefault, kNilOptions);
17    if (!prop) {
18        FF_DEBUG("IORegistryEntryCreateCFProperty(\"secure-boot\") failed");
19        return "IORegistryEntryCreateCFProperty() failed";
20    }
21
22    if (CFGetTypeID(prop) != CFDataGetTypeID() || CFDataGetLength((CFDataRef) prop) == 0) {
23        FF_DEBUG("Invalid secure-boot property");
24        return "Invalid secure-boot property";
25    }
26
27    *result = (bool) *CFDataGetBytePtr((CFDataRef) prop);
28#else
29    FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDevice = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/options");
30    if (!entryDevice) {
31        FF_DEBUG("IORegistryEntryFromPath(\"IODeviceTree:/options\") failed");
32        return "IORegistryEntryFromPath() failed";
33    }
34
35    FF_CFTYPE_AUTO_RELEASE CFTypeRef prop = IORegistryEntryCreateCFProperty(entryDevice, CFSTR("94b73556-2197-4702-82a8-3e1337dafbfb:AppleSecureBootPolicy"), kCFAllocatorDefault, 0);
36    if (!prop) {
37        FF_DEBUG("IORegistryEntryCreateCFProperty(AppleSecureBootPolicy) failed");
38        return "IORegistryEntryCreateCFProperty() failed";
39    }
40
41    if (CFGetTypeID(prop) != CFDataGetTypeID() || CFDataGetLength((CFDataRef) prop) == 0) {
42        FF_DEBUG("Invalid secure-boot property");
43        return "Invalid secure-boot property";
44    }
45
46    *result = *CFDataGetBytePtr((CFDataRef) prop) != 0x02 /* Permissive Security */;
47#endif
48
49    return nullptr;
50}
51
52const char* ffDetectBootmgr(FFBootmgrResult* result) {
53    if (ffPathExists("/System/Library/CoreServices/boot.efi", FF_PATHTYPE_FILE)) {
54        ffStrbufSetStatic(&result->firmware, "/System/Library/CoreServices/boot.efi");
55    }
56
57    #ifdef __aarch64__
58    FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t deviceChosen = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/chosen");
59    if (deviceChosen) {
60        FF_CFTYPE_AUTO_RELEASE CFStringRef tag = IORegistryEntryCreateCFProperty(deviceChosen, CFSTR("iboot-stage-two-tag"), kCFAllocatorDefault, kNilOptions)
61            ?: IORegistryEntryCreateCFProperty(deviceChosen, CFSTR("system-firmware-version"), kCFAllocatorDefault, kNilOptions);
62        if (tag) {
63            ffCfStrGetString(tag, &result->name);
64            ffStrbufSubstrBeforeFirstC(&result->name, '-');
65        }
66    }
67    #endif
68
69    if (!result->name.length) {
70        ffStrbufSetStatic(&result->name, "iBoot");
71    }
72
73    detectSecureBoot(&result->secureBoot);
74
75    return nullptr;
76}