master ohmu/fastfetch-openbsd / src / detection / bootmgr / bootmgr_windows.c
ohmu  ·  2026-10-15
 1#include "bootmgr.h"
 2#include "common/debug.h"
 3#include "efi_helper.h"
 4#include "common/io.h"
 5#include "common/windows/nt.h"
 6
 7#include <ntstatus.h>
 8#include <windows.h>
 9
10const char* enablePrivilege(const wchar_t* privilege) {
11    FF_AUTO_CLOSE_FD HANDLE token = nullptr;
12    NTSTATUS status = NtOpenProcessToken(NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token);
13    if (!NT_SUCCESS(status)) {
14        FF_DEBUG("NtOpenProcessToken() failed: %s", ffDebugNtStatus(status));
15        return "NtOpenProcessToken() failed";
16    }
17
18    TOKEN_PRIVILEGES tp = {
19        .PrivilegeCount = 1,
20        .Privileges = {
21            (LUID_AND_ATTRIBUTES) { .Attributes = SE_PRIVILEGE_ENABLED } },
22    };
23    if (!LookupPrivilegeValueW(nullptr, privilege, &tp.Privileges[0].Luid)) {
24        FF_DEBUG("LookupPrivilegeValue() failed: %s", ffDebugWin32Error(GetLastError()));
25        return "LookupPrivilegeValue() failed";
26    }
27
28    status = NtAdjustPrivilegesToken(token, false, &tp, sizeof(tp), nullptr, nullptr);
29    if (!NT_SUCCESS(status)) {
30        FF_DEBUG("NtAdjustPrivilegesToken() failed: %s", ffDebugNtStatus(status));
31        return "NtAdjustPrivilegesToken() failed";
32    }
33
34    if (status == STATUS_NOT_ALL_ASSIGNED) {
35        FF_DEBUG("NtAdjustPrivilegesToken() did not assign the privilege: %s", ffDebugNtStatus(status));
36        return "The token does not have the specified privilege; try sudo please";
37    }
38
39    return nullptr;
40}
41
42const char* ffDetectBootmgr(FFBootmgrResult* result) {
43    const char* err = enablePrivilege(L"SeSystemEnvironmentPrivilege");
44    if (err != nullptr) {
45        return err;
46    }
47
48    GUID efiGlobalGuid = {
49        .Data1 = 0x8be4df61,
50        .Data2 = 0x93ca,
51        .Data3 = 0x11d2,
52        .Data4 = { 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c },
53    };
54
55    ULONG size = sizeof(result->order);
56    NTSTATUS status = NtQuerySystemEnvironmentValueEx(&(UNICODE_STRING) RTL_CONSTANT_STRING(L"BootCurrent"), &efiGlobalGuid, &result->order, &size, nullptr);
57    if (!NT_SUCCESS(status)) {
58        FF_DEBUG("NtQuerySystemEnvironmentValueEx(BootCurrent) failed: %s", ffDebugNtStatus(status));
59        return "NtQuerySystemEnvironmentValueEx(BootCurrent) failed";
60    }
61    if (size != sizeof(result->order)) {
62        FF_DEBUG("NtQuerySystemEnvironmentValueEx(BootCurrent) returned unexpected size");
63        return "NtQuerySystemEnvironmentValueEx(BootCurrent) returned unexpected size";
64    }
65
66    uint8_t buffer[2048];
67    wchar_t key[9];
68    swprintf(key, ARRAY_SIZE(key), L"Boot%04X", result->order);
69    size = sizeof(buffer);
70    status = NtQuerySystemEnvironmentValueEx(&(UNICODE_STRING) RTL_CONSTANT_STRING(key), &efiGlobalGuid, buffer, &size, nullptr);
71    if (!NT_SUCCESS(status)) {
72        FF_DEBUG("NtQuerySystemEnvironmentValueEx(Boot####) failed: %s", ffDebugNtStatus(status));
73        return "NtQuerySystemEnvironmentValueEx(Boot####) failed";
74    }
75    if (size < sizeof(FFEfiLoadOption) || size == ARRAY_SIZE(buffer)) {
76        FF_DEBUG("NtQuerySystemEnvironmentValueEx(Boot####) returned unexpected size");
77        return "NtQuerySystemEnvironmentValueEx(Boot####) returned unexpected size";
78    }
79
80    ffEfiFillLoadOption((FFEfiLoadOption*) buffer, result);
81
82    SYSTEM_SECUREBOOT_INFORMATION ssi;
83    if (NT_SUCCESS(NtQuerySystemInformation(SystemSecureBootInformation, &ssi, sizeof(ssi), nullptr))) {
84        result->secureBoot = ssi.SecureBootEnabled;
85    }
86
87    return nullptr;
88}