Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support reading boot manager capabilities #95

Merged
merged 1 commit into from
Jul 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/bootentryform.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class BootEntryForm: public QWidget
~BootEntryForm() override;

void setReadOnly(bool readonly);
void showCategory(bool visible);

void setBootEntryListModel(BootEntryListModel &model);
void setItem(const QModelIndex &index, const BootEntry *item);
Expand Down
3 changes: 3 additions & 0 deletions include/efibootdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class EFIBootData: public QObject
bool setup_mode{false};
bool audit_mode{false};
bool deployed_mode{false};
uint32_t boot_option_support{0};

uint64_t supported_indications{0};
uint64_t indications{0};
Expand Down Expand Up @@ -67,6 +68,7 @@ public slots:
void setupModeChanged(bool enabled);
void auditModeChanged(bool enabled);
void deployedModeChanged(bool enabled);
void bootOptionSupportChanged(uint32_t flags);
void appleBootArgsChanged(const QString &text);
void osIndicationsSupportedChanged(uint64_t value);
void osIndicationsChanged(const uint64_t &value);
Expand All @@ -77,6 +79,7 @@ public slots:
void setSetupMode(bool enabled);
void setAuditMode(bool enabled);
void setDeployedMode(bool enabled);
void setBootOptionSupport(uint32_t flags);
void setOsIndicationsSupported(uint64_t value);
void importJSONEFIData(const QJsonObject &input);
void importRawEFIData(const QJsonObject &input);
Expand Down
2 changes: 2 additions & 0 deletions include/efibooteditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ public slots:

void setOsIndication(bool checked);

void updateBootOptionSupport(uint32_t flags);

void undoViewChanged(const QModelIndex &index);

signals:
Expand Down
5 changes: 5 additions & 0 deletions include/efivar-lite/efivar.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@
static const uint64_t EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY = 0x0000000000000040;
static const uint64_t EFI_OS_INDICATIONS_JSON_CONFIG_DATA_REFRESH = 0x0000000000000080;

static const uint32_t EFI_BOOT_OPTION_SUPPORT_KEY = 0x00000001;
Dismissed Show dismissed Hide dismissed
static const uint32_t EFI_BOOT_OPTION_SUPPORT_APP = 0x00000002;
Dismissed Show dismissed Hide dismissed
static const uint32_t EFI_BOOT_OPTION_SUPPORT_SYSPREP = 0x00000010;
Dismissed Show dismissed Hide dismissed
static const uint32_t EFI_BOOT_OPTION_SUPPORT_COUNT = 0x00000300;
Dismissed Show dismissed Hide dismissed

extern const efi_guid_t efi_guid_global;
extern const efi_guid_t efi_guid_apple;

Expand Down
6 changes: 6 additions & 0 deletions src/bootentryform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ void BootEntryForm::setReadOnly(bool readonly)
ui->error_text->setDisabled(readonly);
}

void BootEntryForm::showCategory(bool visible)
{
ui->category_label->setVisible(visible);
ui->category_combo->setVisible(visible);
}

void BootEntryForm::setBootEntryListModel(BootEntryListModel &model)
{
entries_list_model = &model;
Expand Down
81 changes: 80 additions & 1 deletion src/efibootdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ void EFIBootData::clear()
setSetupMode(false);
setAuditMode(false);
setDeployedMode(false);
setBootOptionSupport(0);
setOsIndicationsSupported(0);
setOsIndications(0);
setAppleBootArgs("");
Expand Down Expand Up @@ -159,6 +160,12 @@ void EFIBootData::reload()
save_error,
true);

process_entry(
"BootOptionSupport", EFIBoot::get_variable<uint32_t>, [&](const uint32_t &value, const auto &)
{ setBootOptionSupport(value); },
save_error,
true);

process_entry(
"OsIndicationsSupported", EFIBoot::get_variable<uint64_t>, [&](const uint64_t &value, const auto &)
{ setOsIndicationsSupported(value); },
Expand Down Expand Up @@ -517,6 +524,25 @@ void EFIBootData::export_(const QString &file_name)
output["AuditMode"] = audit_mode != 0;
output["DeployedMode"] = deployed_mode != 0;

if(boot_option_support)
{
QJsonObject obj;
QJsonArray caps;

if(boot_option_support & EFIBoot::EFI_BOOT_OPTION_SUPPORT_KEY)
caps.push_back("KEY");

if(boot_option_support & EFIBoot::EFI_BOOT_OPTION_SUPPORT_APP)
caps.push_back("APP");

if(boot_option_support & EFIBoot::EFI_BOOT_OPTION_SUPPORT_SYSPREP)
caps.push_back("SYSPREP");

obj["capabilities"] = caps;
obj["key_count"] = static_cast<int>((boot_option_support & EFIBoot::EFI_BOOT_OPTION_SUPPORT_COUNT) >> 8);
output["BootOptionSupport"] = obj;
}

{
QJsonArray arr;
if(supported_indications & EFIBoot::EFI_OS_INDICATIONS_BOOT_TO_FW_UI)
Expand Down Expand Up @@ -661,7 +687,7 @@ void EFIBootData::dump(const QString &file_name)
output[prefix] = entries;
}

for(const auto &key: std::vector<const char *>{"Timeout", "BootCurrent", "BootNext", "SecureBoot", "VendorKeys", "SetupMode", "AuditMode", "DeployedMode", "OsIndicationsSupported", "OsIndications"})
for(const auto &key: std::vector<const char *>{"Timeout", "BootCurrent", "BootNext", "SecureBoot", "VendorKeys", "SetupMode", "AuditMode", "DeployedMode", "BootOptionSupport", "OsIndicationsSupported", "OsIndications"})
process_entry(output, key, _T(""), true);

// Apple
Expand Down Expand Up @@ -784,6 +810,15 @@ void EFIBootData::setDeployedMode(bool enabled)
emit deployedModeChanged(deployed_mode);
}

void EFIBootData::setBootOptionSupport(uint32_t flags)
{
if(boot_option_support == flags)
return;

boot_option_support = flags;
emit bootOptionSupportChanged(boot_option_support);
}

void EFIBootData::setOsIndicationsSupported(uint64_t value)
{
if(supported_indications == value)
Expand Down Expand Up @@ -864,6 +899,45 @@ void EFIBootData::importJSONEFIData(const QJsonObject &input)
{ setDeployedMode(value.toBool()); },
"", true);

process_entry(
input, "BootOptionSupport", &QJsonValue::isObject, tr("object"), [&](const QJsonValue &value)
{
uint32_t val = 0;
const auto obj = value.toObject();
if(obj["capabilities"].isArray())
{
const auto caps = obj["capabilities"].toArray();
int i = -1;
for(const auto cap: caps)
{
++i;
const auto qname = QString("BootOptionSupport/capabilities[%1]").arg(i);
if(!cap.isString())
{
errors.push_back(tr("%1: %2 expected").arg(qname, tr("string")));
continue;
}

if(cap == "KEY")
val |= EFIBoot::EFI_BOOT_OPTION_SUPPORT_KEY;
else if(cap == "APP")
val |= EFIBoot::EFI_BOOT_OPTION_SUPPORT_APP;
else if(cap == "SYSPREP")
val |= EFIBoot::EFI_BOOT_OPTION_SUPPORT_SYSPREP;
else
{
errors.push_back(tr("%1: unknown boot manager capability").arg(qname));
continue;
}
}
}

if(obj["key_count"].isDouble())
val |= (static_cast<uint32_t>(obj["key_count"].toInt()) << 8) & EFIBoot::EFI_BOOT_OPTION_SUPPORT_COUNT;

setBootOptionSupport(val); },
"", true);

process_entry(
input, "OsIndicationsSupported", &QJsonValue::isArray, tr("array"),
[&](const QJsonValue &value)
Expand Down Expand Up @@ -1137,6 +1211,11 @@ void EFIBootData::importRawEFIData(const QJsonObject &input)
{ setDeployedMode(value); },
"", true);

process_entry(
input, "BootOptionSupport", EFIBoot::deserialize<uint32_t>, [&](const uint32_t &value, const auto &)
{ setBootOptionSupport(value); },
"", true);

process_entry(
input, "OsIndicationsSupported", EFIBoot::deserialize<uint64_t>, [&](const uint64_t &value, const auto &)
{ setOsIndicationsSupported(value); },
Expand Down
10 changes: 10 additions & 0 deletions src/efibooteditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ EFIBootEditor::EFIBootEditor(QWidget *parent)
QObject::connect(&data, &EFIBootData::setupModeChanged, ui->setup_mode, &QRadioButton::setChecked);
QObject::connect(&data, &EFIBootData::auditModeChanged, ui->audit_mode, &QRadioButton::setChecked);
QObject::connect(&data, &EFIBootData::deployedModeChanged, ui->deployed_mode, &QRadioButton::setChecked);
QObject::connect(&data, &EFIBootData::bootOptionSupportChanged, this, &EFIBootEditor::updateBootOptionSupport);

QObject::connect(&data, &EFIBootData::appleBootArgsChanged, ui->boot_args_text, &QLineEdit::setText);
QObject::connect(ui->boot_args_text, &QLineEdit::textEdited, &data, &EFIBootData::setAppleBootArgs);
Expand Down Expand Up @@ -92,6 +93,8 @@ EFIBootEditor::EFIBootEditor(QWidget *parent)

ui->entries->setCurrentIndex(0);
ui->settings->setCurrentIndex(0);

updateBootOptionSupport(0);
}

EFIBootEditor::~EFIBootEditor()
Expand Down Expand Up @@ -284,6 +287,13 @@ void EFIBootEditor::setOsIndication(bool)
emit osIndicationsChanged(getOsIndications());
}

void EFIBootEditor::updateBootOptionSupport(uint32_t flags)
{
// TODO: (flags & EFIBoot::EFI_BOOT_OPTION_SUPPORT_KEY)
ui->entry_form->showCategory(flags & EFIBoot::EFI_BOOT_OPTION_SUPPORT_APP);
ui->entries->setTabVisible(ui->entries->indexOf(ui->sysprep_tab), flags & EFIBoot::EFI_BOOT_OPTION_SUPPORT_SYSPREP);
}

void EFIBootEditor::undoViewChanged(const QModelIndex &)
{
refreshBootEntryEditor();
Expand Down
Loading