Repository: Neverous/efibooteditor
Branch: master
Commit: abe557197229
Files: 143
Total size: 8.7 MB
Directory structure:
gitextract_xp9wzt84/
├── .clang-format
├── .codacy.yml
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── 1-bug-report.yml
│ │ └── 2-feature-request.yml
│ ├── dependabot.yml
│ ├── release-drafter.yml
│ └── workflows/
│ ├── build.yml
│ ├── debug.yml
│ ├── draft_release.yml
│ ├── format.yml
│ ├── qt_update.yml
│ └── release.yml
├── .gitignore
├── CMakeLists.txt
├── CMakePresets.json
├── INSTALL.md
├── LICENSE.txt
├── README.md
├── cmake/
│ ├── CPackLinux.cmake
│ └── FindZLIB.cmake
├── doc/
│ ├── RELEASE.md
│ └── screenshot.json
├── icons/
│ └── Tango/
│ ├── index.theme
│ └── scalable/
│ ├── places/
│ │ └── folder.icon
│ └── status/
│ ├── folder-drag-accept.icon
│ └── folder-visiting.icon
├── icons.qrc
├── include/
│ ├── bootentry.h
│ ├── bootentry.h.j2
│ ├── bootentrydelegate.h
│ ├── bootentryform.h
│ ├── bootentrylistmodel.h
│ ├── bootentrylistview.h
│ ├── bootentrywidget.h
│ ├── commands.h
│ ├── compat.h
│ ├── devicepathproxymodel.h
│ ├── devicepathview.h
│ ├── disableundoredo.h
│ ├── driveinfo.h
│ ├── efiboot.h
│ ├── efiboot.h.j2
│ ├── efibootdata.h
│ ├── efibooteditor.h
│ ├── efibooteditorcli.h
│ ├── efikeysequence.h
│ ├── efikeysequenceedit.h
│ ├── efivar-lite/
│ │ ├── device-paths.h
│ │ ├── device-paths.h.j2
│ │ ├── device-paths.yml
│ │ ├── efivar-lite.h
│ │ ├── key-option.h
│ │ └── load-option.h
│ ├── filepathdelegate.h
│ ├── filepathdialog.h
│ ├── filepathdialog.h.j2
│ ├── hotkey.h
│ ├── hotkeydelegate.h
│ ├── hotkeylistmodel.h
│ ├── hotkeysdialog.h
│ ├── hotkeysview.h
│ ├── qindicatorwidget.h
│ ├── qlabelwrapped.h
│ ├── qresizabletabwidget.h
│ └── qwidgetitemdelegate.h
├── misc/
│ ├── .gitignore
│ ├── EFIBootEditor.desktop
│ ├── EFIBootEditor.icns
│ ├── EFIBootEditor.metainfo.xml
│ ├── WIX.template.in
│ ├── codegen/
│ │ ├── gen_efidp.py
│ │ ├── pyproject.toml
│ │ └── spec_parse.py
│ ├── efibooteditor.spec
│ ├── org.x.efibooteditor.policy
│ ├── qt-updater/
│ │ ├── main.py
│ │ └── pyproject.toml
│ └── run-efibooteditor
├── src/
│ ├── bootentry.cpp
│ ├── bootentry.cpp.j2
│ ├── bootentrydelegate.cpp
│ ├── bootentryform.cpp
│ ├── bootentrylistmodel.cpp
│ ├── bootentrylistview.cpp
│ ├── bootentrywidget.cpp
│ ├── commands.cpp
│ ├── devicepathproxymodel.cpp
│ ├── devicepathview.cpp
│ ├── driveinfo.cpp
│ ├── driveinfo.darwin.cpp
│ ├── driveinfo.linux.cpp
│ ├── driveinfo.win32.cpp
│ ├── efibootdata.cpp
│ ├── efibooteditor.cpp
│ ├── efibooteditorcli.cpp
│ ├── efikeysequence.cpp
│ ├── efikeysequenceedit.cpp
│ ├── efivar-lite.c
│ ├── efivar-lite.common.h
│ ├── efivar-lite.darwin.c
│ ├── efivar-lite.linux.c
│ ├── efivar-lite.win32.c
│ ├── filepathdelegate.cpp
│ ├── filepathdialog.cpp
│ ├── filepathdialog.cpp.j2
│ ├── form/
│ │ ├── bootentryform.ui
│ │ ├── bootentrywidget.ui
│ │ ├── efibooteditor.ui
│ │ ├── filepathdialog.ui
│ │ ├── filepathdialog.ui.j2
│ │ └── hotkeysdialog.ui
│ ├── hotkey.cpp
│ ├── hotkeydelegate.cpp
│ ├── hotkeylistmodel.cpp
│ ├── hotkeysdialog.cpp
│ ├── hotkeysview.cpp
│ └── main.cpp
├── tests/
│ ├── CMakeLists.txt
│ └── testefibootdata.cpp
└── translations/
├── efibooteditor_ar.ts
├── efibooteditor_cs.ts
├── efibooteditor_de.ts
├── efibooteditor_en.ts
├── efibooteditor_es.ts
├── efibooteditor_fi.ts
├── efibooteditor_fr.ts
├── efibooteditor_hu.ts
├── efibooteditor_it.ts
├── efibooteditor_ja.ts
├── efibooteditor_ko.ts
├── efibooteditor_nb_NO.ts
├── efibooteditor_pl.ts
├── efibooteditor_pt_BR.ts
├── efibooteditor_ru.ts
├── efibooteditor_sk.ts
├── efibooteditor_sl.ts
├── efibooteditor_sv.ts
├── efibooteditor_ta.ts
├── efibooteditor_tr.ts
├── efibooteditor_uk.ts
├── efibooteditor_vi.ts
├── efibooteditor_zh_Hans.ts
└── efibooteditor_zh_Hant.ts
================================================
FILE CONTENTS
================================================
================================================
FILE: .clang-format
================================================
---
BasedOnStyle: WebKit
BreakBeforeBraces: Allman
Cpp11BracedListStyle: 'true'
NamespaceIndentation: None
PointerAlignment: Right
SpaceBeforeCpp11BracedList: 'false'
SpaceBeforeCtorInitializerColon: 'false'
SpaceBeforeInheritanceColon: 'false'
SpaceBeforeParens: Never
SpaceBeforeRangeBasedForLoopColon: 'false'
SpaceInEmptyParentheses: 'false'
SpacesInAngles: 'false'
SpacesInCStyleCastParentheses: 'false'
SpacesInContainerLiterals: 'false'
SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'
BraceWrapping:
BeforeLambdaBody: 'true'
...
================================================
FILE: .codacy.yml
================================================
---
engines:
cppcheck:
language: c++
exclude_paths:
- "doc/**"
- "icons/**"
- "misc/**"
- "translations/**"
================================================
FILE: .github/ISSUE_TEMPLATE/1-bug-report.yml
================================================
name: 🐛 Bug report
description: Provide information about a problem
labels: [bug]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: textarea
attributes:
label: Description
description: Provide a short description of the problem. What's expected and what actually happens, etc.
validations:
required: true
- type: textarea
attributes:
label: Environment
description: |
Provide environment information.
- You can grab **Application version** from `Help -> About EFI Boot Editor` or by running `efibooteditor --version`
- Exact **Operating system** version/distribution much appreciated
- Please provide information about your UEFI environment like `Motherboard: MSI PRO X670`, `BIOS version: XX 01/01/1970`, etc.
value: |
- Application version:
- Operating system:
- EFI/BIOS/Motherboard vendor:
- EFI/BIOS version:
validations:
required: true
- type: textarea
attributes:
label: Raw EFI data
description: |
Please provide raw EFI data if possible, you can generate it from `Help -> Dump raw EFI data` or by running `efibooteditor --dump raw.json`
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations:
required: false
- type: textarea
attributes:
label: Additional information
description: |
Whenever possible please also provide any additional information that might help troubleshoot the issue.
Like:
- Boot menu screenshot for comparison with EFI Boot Manager output
- on Linux: `efibootmgr` output
- on Windows: `bcdedit /enum firmware` output
validations:
required: false
- type: textarea
attributes:
label: Steps to reproduce
description: If applicable, provide list of exact steps to reproduce the problem.
placeholder: |
1. Click '...' in the GUI
2. See error...
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/2-feature-request.yml
================================================
name: 🚀 Feature request
description: Suggest an idea for this project
labels: [enhancement]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for similar feature.
options:
- label: I have searched the existing issues
required: true
- type: textarea
attributes:
label: Description
description: Provide a short description of the feature.
validations:
required: true
- type: textarea
attributes:
label: Additional information
description: Feel free to write here any additional information.
validations:
required: false
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "friday"
time: "05:00"
groups:
dependencies:
patterns:
- "*"
- package-ecosystem: "uv"
directory: "/misc/codegen"
schedule:
interval: "weekly"
day: "friday"
time: "05:00"
groups:
dependencies:
patterns:
- "*"
- package-ecosystem: "uv"
directory: "/misc/qt-updater"
schedule:
interval: "weekly"
day: "friday"
time: "05:00"
groups:
dependencies:
patterns:
- "*"
================================================
FILE: .github/release-drafter.yml
================================================
name-template: 'v$NEXT_PATCH_VERSION'
tag-template: 'v$NEXT_PATCH_VERSION'
categories:
- title: 'Features'
labels:
- 'feature'
- 'enhancement'
- title: 'Bug fixes'
labels:
- 'fix'
- 'bugfix'
- 'bug'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
template: |
## Changes
$CHANGES
================================================
FILE: .github/workflows/build.yml
================================================
name: Build EFIBootEditor
on:
workflow_call:
inputs:
os:
required: true
type: string
compiler:
required: true
type: string
build-config:
required: true
type: string
version:
required: true
type: string
env:
CMAKE_BUILD_PARALLEL_LEVEL: 4
INPUT_COMPILER: ${{ inputs.compiler }}
jobs:
build:
name: ${{ inputs.os }} Qt ${{ matrix.qt-version }} with ${{ inputs.compiler }}
runs-on: ${{ inputs.os }}
strategy:
fail-fast: false
matrix:
qt-version:
- 5.15.2 # Supported in Ubuntu Noble Numbat until 2029-05-31
- 6.2.4 # Supported in Ubuntu Jammy Jellyfish until 2027-04-01
- 6.10.3 # Supported until 2026-04-07
- 6.11.0 # Supported until 2026-09-22
exclude:
- qt-version: ${{ endsWith(inputs.os, 'arm') && '5.15.2' || 'none' }}
- qt-version: ${{ endsWith(inputs.os, 'arm') && '6.2.4' || 'none' }}
- qt-version: ${{ inputs.os == 'macos-26' && '6.2.4' || 'none' }}
- qt-version: ${{ inputs.os == 'macos-26' && '6.8.3' || 'none' }}
steps:
- name: Checkout source code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Set up ccache
uses: hendrikmuhs/ccache-action@1bbbcda0748b3e340dee71a314fa68ffcbd6df79
with:
key: ${{ inputs.os }}-${{ inputs.compiler }}-${{ inputs.build-config }}-${{ matrix.qt-version }}
restore-keys: |
${{ inputs.os }}-${{ inputs.compiler }}-${{ inputs.build-config }}
${{ inputs.os }}-${{ inputs.compiler }}
${{ inputs.os }}
- name: Initialize CodeQL
uses: github/codeql-action/init@b1bff81932f5cdfc8695c7752dcee935dcd061c8
with:
languages: cpp
queries: security-and-quality
if: inputs.build-config == 'Debug'
continue-on-error: true
- name: Set up Qt environment
uses: jurplel/install-qt-action@d325aaf2a8baeeda41ad0b5d39f84a6af9bcf005
with:
cache: true
version: ${{ matrix.qt-version }}
- name: Install CMake
run: |
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null
sudo apt-add-repository "deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main"
sudo apt-get update
sudo apt-get install cmake
mv /usr/local/bin/cmake /usr/local/bin/cmake3
mv /usr/local/bin/cpack /usr/local/bin/cpack3
cmake --version
shell: bash
if: startsWith(inputs.os, 'ubuntu')
- name: Install libfuse2
run: sudo apt-get install libfuse2
shell: bash
if: startsWith(inputs.os, 'ubuntu')
- name: Install linuxdeploy
run: |
DIR=$(mktemp -d)
echo "${DIR}" >> ${GITHUB_PATH}
ARCH=${{ endsWith(inputs.os, 'arm') && 'aarch64' || 'x86_64' }}
wget -c -nv https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${ARCH}.AppImage -O ${DIR}/linuxdeploy
wget -c -nv https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-${ARCH}.AppImage -O ${DIR}/linuxdeploy-plugin-qt
wget -c -nv https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-${{ endsWith(inputs.os, 'arm') && 'aarch64' || 'x86_64' }}.AppImage -O ${DIR}/appimagetool
chmod +x ${DIR}/*
shell: bash
if: startsWith(inputs.os, 'ubuntu')
- name: Install efivar
run: sudo apt-get install libefiboot1 libefiboot-dev libefivar-dev
shell: bash
if: startsWith(inputs.os, 'ubuntu')
- name: Install libxkbcommon-x11-0 and libxcb-cursor0 and zlib1g-dev
run: sudo apt-get install libxkbcommon-x11-0 libxcb-cursor0 zlib1g-dev
shell: bash
if: startsWith(inputs.os, 'ubuntu')
- name: Install zlib
run: vcpkg install zlib
shell: bash
if: startsWith(inputs.os, 'windows')
- name: Configure with ${{ inputs.compiler }}
run: |
cmake --preset ${{ inputs.build-config }} -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=${{ inputs.compiler == 'Clang' && 'clang' || 'gcc' }} -DCMAKE_CXX_COMPILER=${{ inputs.compiler == 'Clang' && 'clang++' || 'g++' }} ${{ startsWith(inputs.os, 'macos') && startsWith(matrix.qt-version, '5') && '-DCMAKE_OSX_ARCHITECTURES="x86_64"' || '' }}
shell: bash
env:
BUILD_VERSION: ${{ inputs.version }}
BUILD_OS: ${{ inputs.os }}
if: ${{ !startsWith(inputs.os, 'windows') }}
- name: Build
run: cmake --build --preset ${{ inputs.build-config }}
shell: bash
if: ${{ !startsWith(inputs.os, 'windows') }}
- name: Configure and build with ${{ inputs.compiler }}
run: |
call "%programfiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ endsWith(inputs.os, 'arm') && 'arm64' || 'x64' }} || exit /b
cmake --preset ${{ inputs.build-config }} -DCMAKE_TOOLCHAIN_FILE=%VCPKG_INSTALLATION_ROOT%\scripts\buildsystems\vcpkg.cmake -DCMAKE_VERBOSE_MAKEFILE=ON ${{ inputs.compiler == 'Clang' && '-DCMAKE_C_COMPILER=clang-cl.exe -DCMAKE_CXX_COMPILER=clang-cl.exe' || '' }} -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache || exit /b
cmake --build --preset ${{ inputs.build-config }}
shell: cmd
env:
BUILD_VERSION: ${{ inputs.version }}
BUILD_OS: ${{ inputs.os }}
if: startsWith(inputs.os, 'windows')
- name: Run tests
env:
TEST_ALLOW_NO_EFI_ENTRIES: ${{ startsWith(inputs.os, 'macos') && 'true' || '' }}
run: ctest --preset ${{ inputs.build-config }} -VV
shell: bash
- name: Package
run: |
for t in $(seq 1 20); do # FIXME: macOS has random hdiutil errors because of some protection mechanisms, just retry few times https://github.com/actions/runner-images/issues/7522#issuecomment-1556766641
cmake --build --preset ${{ inputs.build-config }} --target package && exit 0
rm -rf build/${{ inputs.build-config }}/dist/
done
exit 255
shell: bash
- name: Generate SBOM
uses: anchore/sbom-action@57aae528053a48a3f6235f2d9461b05fbcb7366d
with:
output-file: build/${{ inputs.build-config }}/dist/EFIBootEditor-${{ github.sha }}-${{ inputs.os }}-qt-${{ matrix.qt-version }}.spdx
upload-artifact: false
upload-release-assets: false
- name: Attest artifacts
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32
with:
subject-path: build/${{ inputs.build-config }}/dist/EFIBootEditor-*
- name: Upload artifacts
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
with:
name: EFIBootEditor-${{ github.sha }}-${{ inputs.os }}-qt-${{ matrix.qt-version }}-${{ inputs.compiler }}
if-no-files-found: error
path: build/${{ inputs.build-config }}/dist/EFIBootEditor-*
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@b1bff81932f5cdfc8695c7752dcee935dcd061c8
if: inputs.build-config == 'Debug'
continue-on-error: true
================================================
FILE: .github/workflows/debug.yml
================================================
name: Debug build
on:
push:
branches: [master]
paths:
- .github/workflows/build.yml
- .github/workflows/debug.yml
- CMakeLists.txt
- cmake/**
- icons.qrc
- icons/**
- include/**
- src/**
- windows.rc
pull_request:
branches: [master]
paths:
- .github/workflows/build.yml
- .github/workflows/debug.yml
- CMakeLists.txt
- cmake/**
- icons.qrc
- icons/**
- include/**
- src/**
- windows.rc
schedule:
- cron: 0 5 * * 5
concurrency:
group: debug-${{ github.ref }}
cancel-in-progress: true
jobs:
build-linux:
name: ${{ matrix.os }} with ${{ matrix.compiler }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, ubuntu-24.04, ubuntu-24.04-arm]
compiler:
- Clang
- GCC
permissions:
actions: read
artifact-metadata: write
attestations: write
contents: read
id-token: write
security-events: write
uses: ./.github/workflows/build.yml
with:
os: ${{ matrix.os }}
compiler: ${{ matrix.compiler }}
build-config: Debug
version: ${{ github.sha }}
build-windows:
name: ${{ matrix.os }} with ${{ matrix.compiler }}
strategy:
fail-fast: false
matrix:
os: [windows-2022, windows-2025, windows-11-arm]
compiler:
- Clang
- MSVC
permissions:
actions: read
artifact-metadata: write
attestations: write
contents: read
id-token: write
security-events: write
uses: ./.github/workflows/build.yml
with:
os: ${{ matrix.os }}
compiler: ${{ matrix.compiler }}
build-config: Debug
version: ${{ github.sha }}
build-macos:
name: ${{ matrix.os }} with ${{ matrix.compiler }}
strategy:
fail-fast: false
matrix:
os: [macos-14, macos-15, macos-26]
compiler:
- Clang
permissions:
actions: read
artifact-metadata: write
attestations: write
contents: read
id-token: write
security-events: write
uses: ./.github/workflows/build.yml
with:
os: ${{ matrix.os }}
compiler: ${{ matrix.compiler }}
build-config: Debug
version: ${{ github.sha }}
================================================
FILE: .github/workflows/draft_release.yml
================================================
name: Draft release
on:
push:
branches: [master]
jobs:
update_release_draft:
runs-on: ubuntu-slim
permissions:
contents: write
pull-requests: read
steps:
- uses: release-drafter/release-drafter@139054aeaa9adc52ab36ddf67437541f039b88e2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/format.yml
================================================
name: Clang format
on: [push]
jobs:
clang-format:
runs-on: ubuntu-slim
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- uses: cpp-linter/cpp-linter-action@24467985494bed9bfc398489b6ec12469beaf4da
id: linter
with:
version: 21
style: file
- name: Fail fast
if: steps.linter.outputs.checks-failed > 0
run: exit 1
================================================
FILE: .github/workflows/qt_update.yml
================================================
name: Check for Qt updates
on:
workflow_dispatch:
schedule:
- cron: 0 5 * * 5
concurrency:
group: qt-update-${{ github.ref }}
cancel-in-progress: true
jobs:
check-qt-updates:
name: Check Qt updates
runs-on: ubuntu-slim
permissions:
actions: read
contents: read
steps:
- name: Sync fork
env:
GITHUB_TOKEN: ${{ secrets.BOT_ACCESS_TOKEN }}
run: |
gh repo sync EFIBootEditorBot/efibooteditor \
--source ${{ github.repository }} \
--branch master \
--force
- name: Checkout source code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
token: ${{ secrets.BOT_ACCESS_TOKEN }}
repository: EFIBootEditorBot/efibooteditor
- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78
with:
enable-cache: true
- name: Install python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
with:
python-version: '3.14'
- name: Install dependencies
run: uv sync
working-directory: misc/qt-updater
- name: Run the updater
id: diff
run: |
uv run -m main ../../.github/workflows/*.yml
if git diff --exit-code ../../.github/workflows/; then
echo "changed=false" >> "${GITHUB_OUTPUT}"
else
echo "changed=true" >> "${GITHUB_OUTPUT}"
fi
working-directory: misc/qt-updater
- name: Create pull request
run: |
CURRENT_SHA=$(gh api repos/EFIBootEditorBot/efibooteditor/git/ref/heads/master --jq '.object.sha')
if ! gh api repos/EFIBootEditorBot/efibooteditor/git/refs -f ref="refs/heads/qt-update" -f sha="${CURRENT_SHA}" 2>/dev/null; then
CURRENT_SHA=$(gh api repos/EFIBootEditorBot/efibooteditor/git/ref/heads/qt-update --jq '.object.sha')
fi
gh api graphql -f query='
mutation($repo: String!, $branch: String!, $oid: GitObjectID!, $msg: String!, $files: [FileAddition!]!) {
createCommitOnBranch(input: {
branch: { repositoryNameWithOwner: $repo, branchName: $branch },
expectedHeadOid: $oid,
message: { headline: $msg },
fileChanges: { additions: $files }
}) { commit { url } }
}' \
-f repo="EFIBootEditorBot/efibooteditor" \
-f branch="qt-update" \
-f oid="${CURRENT_SHA}" \
-f msg="Update Qt dependencies" \
-f files[][path]=".github/workflows/build.yml" \
-f files[][contents]=$(base64 -w 0 .github/workflows/build.yml) \
-f files[][path]=".github/workflows/release.yml" \
-f files[][contents]=$(base64 -w 0 .github/workflows/release.yml)
gh pr create \
--repo "${{ github.repository }}" \
--title 'ci: update Qt versions in CI' \
--body 'Updates Qt versions in CI to newest ones.' \
--head "EFIBootEditorBot:qt-update" \
--base master || echo "PR already exists"
env:
GITHUB_TOKEN: ${{ secrets.BOT_ACCESS_TOKEN }}
if: steps.diff.outputs.changed == 'true'
================================================
FILE: .github/workflows/release.yml
================================================
name: Prepare release assets
on:
push:
branches: [master]
paths:
- .github/workflows/build.yml
- .github/workflows/release.yml
- CMakeLists.txt
- cmake/**
- icons.qrc
- icons/**
- include/**
- src/**
- translations/**
- windows.rc
tags: [v*]
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: true
jobs:
build-linux:
name: ${{ matrix.os }} with ${{ matrix.compiler }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, ubuntu-24.04, ubuntu-24.04-arm]
compiler:
- Clang
- GCC
permissions:
actions: read
artifact-metadata: write
attestations: write
contents: read
id-token: write
security-events: write
uses: ./.github/workflows/build.yml
with:
os: ${{ matrix.os }}
compiler: ${{ matrix.compiler }}
build-config: RelWithDebInfo
version: ${{ github.ref_type == 'tag' && github.ref_name || github.sha }}
build-windows:
name: ${{ matrix.os }} with ${{ matrix.compiler }}
strategy:
fail-fast: false
matrix:
os: [windows-2022, windows-2025, windows-11-arm]
compiler:
- Clang
- MSVC
permissions:
actions: read
artifact-metadata: write
attestations: write
contents: read
id-token: write
security-events: write
uses: ./.github/workflows/build.yml
with:
os: ${{ matrix.os }}
compiler: ${{ matrix.compiler }}
build-config: RelWithDebInfo
version: ${{ github.ref_type == 'tag' && github.ref_name || github.sha }}
build-macos:
name: ${{ matrix.os }} with ${{ matrix.compiler }}
strategy:
fail-fast: false
matrix:
os: [macos-14, macos-15, macos-26]
compiler:
- Clang
permissions:
actions: read
artifact-metadata: write
attestations: write
contents: read
id-token: write
security-events: write
uses: ./.github/workflows/build.yml
with:
os: ${{ matrix.os }}
compiler: ${{ matrix.compiler }}
build-config: RelWithDebInfo
version: ${{ github.ref_type == 'tag' && github.ref_name || github.sha }}
upload-assets:
name: Upload release assets
if: github.ref_type == 'tag'
needs: [build-linux, build-windows, build-macos]
runs-on: ubuntu-slim
permissions:
attestations: write
contents: write
id-token: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
with:
path: artifacts
- name: Prepare assets for release
id: prepare
run: |
mkdir -p dist
find artifacts -type f -name "EFIBootEditor-*" | while read -r file; do
filename=$(basename "$file")
dir_name=$(basename "$(dirname "$file")")
metadata=$(echo "$dir_name" | sed -E 's/EFIBootEditor-[^-]+-(.*)+$/\1/')
ext=$(echo "$filename" | sed -E "s/EFIBootEditor-.+[0-9]//")
new_name="EFIBootEditor-${{ github.ref_name }}-${metadata}${ext}"
echo "Renaming $filename to $new_name"
mv -v "$file" "dist/$new_name"
done
shell: bash
- name: Attest release assets
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32
with:
subject-path: dist/EFIBootEditor-*
- name: Upload assets to release
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe
with:
files: dist/EFIBootEditor-*
tag_name: ${{ github.ref_name }}
winget-update:
name: Update version in winget
if: github.ref_type == 'tag'
needs: upload-assets
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
os: [windows-2025]
qt-version:
- 6.11.0 # Supported until 2026-09-22
compiler:
- MSVC
steps:
- name: Create PR in winget-pkgs repository
run: |
iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
.\wingetcreate.exe update EFIBootEditor.EFIBootEditor -u https://github.com/Neverous/efibooteditor/releases/download/${{ github.ref_name }}/EFIBootEditor-${{ github.ref_name }}-${{ matrix.os }}-qt-${{ matrix.qt-version }}-${{ matrix.compiler }}.msi -v $Env:GITHUB_REF_NAME.Substring(1) -t ${{ secrets.BOT_ACCESS_TOKEN }} --submit
================================================
FILE: .gitignore
================================================
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*.user*
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
# Build
# -----
build*/
================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.16)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
string(REGEX REPLACE "^v" "" FULL_VERSION "$ENV{BUILD_VERSION}")
if(NOT ("${FULL_VERSION}" MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+"))
set(FULL_VERSION "0.0.0-${FULL_VERSION}")
endif()
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" VERSION ${FULL_VERSION})
set(VERSION_MAJOR ${CMAKE_MATCH_1})
set(VERSION_MINOR ${CMAKE_MATCH_2})
set(VERSION_PATCH ${CMAKE_MATCH_3})
string(TIMESTAMP VERSION_TWEAK "%s" UTC)
message(STATUS "Building version ${VERSION} (${FULL_VERSION})")
project(efibooteditor
VERSION ${VERSION}
DESCRIPTION "Boot Editor for (U)EFI based systems."
LANGUAGES C CXX
)
set(PROJECT_NAME_CAPITALIZED "EFIBootEditor")
set(PROJECT_HOMEPAGE_URL "https://github.com/Neverous/efibooteditor")
set(APPLICATION_NAME "EFI Boot Editor")
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOMOC_MOC_OPTIONS -b compat.h)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_C_STANDARD_REQUIRED TRUE)
set(CMAKE_DEBUG_POSTFIX "d")
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Program)
set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME_CAPITALIZED})
set(MACOSX_BUNDLE_BUNDLE_VERSION ${FULL_VERSION})
set(MACOSX_BUNDLE_GUI_IDENTIFIER ${PROJECT_NAME_CAPITALIZED})
# Link time optimization support check
if(("${CMAKE_BUILD_TYPE}" STREQUAL "Release") OR ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo"))
include(CheckIPOSupported)
check_ipo_supported(RESULT ipo)
if(ipo)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
if("${QT_VERSION_MAJOR}" STREQUAL "")
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
else()
find_package(QT NAMES Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)
endif()
message(STATUS "Qt: ${QT_VERSION_MAJOR}")
find_package(Qt${QT_VERSION_MAJOR}
COMPONENTS
Core
Gui
Network
Svg
Widgets
LinguistTools
REQUIRED)
find_package(ZLIB REQUIRED)
message(STATUS "ZLIB: ${ZLIB_VERSION_STRING}")
add_library(${PROJECT_NAME}-core)
target_include_directories(${PROJECT_NAME}-core PUBLIC "${CMAKE_SOURCE_DIR}/include")
target_link_libraries(${PROJECT_NAME}-core PUBLIC
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Svg
Qt${QT_VERSION_MAJOR}::Widgets
ZLIB::ZLIB
)
if(${QT_VERSION_MAJOR} LESS_EQUAL 5)
if(NOT COMMAND qt_add_translations)
function(qt_add_translations TARGET)
cmake_parse_arguments(arg "" "" "TS_FILES;RESOURCE_PREFIX;INCLUDE_DIRECTORIES;LUPDATE_OPTIONS" ${ARGN})
qt5_add_translation(QM_FILES ${arg_TS_FILES})
get_target_property(BINARY_DIR ${TARGET} BINARY_DIR)
set(QRC ${BINARY_DIR}/translations.qrc)
file(WRITE ${QRC} "\n")
foreach (QM_PATH ${QM_FILES})
file(RELATIVE_PATH QM_FILE ${BINARY_DIR} ${QM_PATH})
file(APPEND ${QRC} "${QM_FILE}\n")
endforeach ()
file(APPEND ${QRC} "")
qt_add_resources(RESOURCES ${QRC})
target_sources(${PROJECT_NAME} PRIVATE ${RESOURCES})
endfunction()
endif()
endif()
add_compile_definitions(
APPLICATION_NAME="${APPLICATION_NAME}"
VERSION="${FULL_VERSION}"
VERSION_MAJOR=${VERSION_MAJOR}
VERSION_MINOR=${VERSION_MINOR}
VERSION_PATCH=${VERSION_PATCH}
VERSION_TWEAK=${VERSION_TWEAK}
PROJECT_NAME="${PROJECT_NAME}"
PROJECT_DESCRIPTION="${PROJECT_DESCRIPTION}"
PROJECT_HOMEPAGE_URL="${PROJECT_HOMEPAGE_URL}"
APPLICATION_ICON="${CMAKE_SOURCE_DIR}/misc/${PROJECT_NAME_CAPITALIZED}.ico"
QT_DEPRECATED_WARNINGS
QT_DISABLE_DEPRECATED_BEFORE=0xFFFFFF
)
# Sources:
target_sources(${PROJECT_NAME}-core PRIVATE
src/bootentry.cpp
src/bootentrydelegate.cpp
src/bootentryform.cpp
src/bootentrylistmodel.cpp
src/bootentrylistview.cpp
src/bootentrywidget.cpp
src/commands.cpp
src/devicepathproxymodel.cpp
src/devicepathview.cpp
src/driveinfo.cpp
src/efibootdata.cpp
src/efibooteditor.cpp
src/efibooteditorcli.cpp
src/efikeysequence.cpp
src/efikeysequenceedit.cpp
src/filepathdelegate.cpp
src/filepathdialog.cpp
src/hotkey.cpp
src/hotkeydelegate.cpp
src/hotkeylistmodel.cpp
src/hotkeysdialog.cpp
src/hotkeysview.cpp
)
if(UNIX AND NOT APPLE)
target_sources(${PROJECT_NAME}-core PRIVATE
src/driveinfo.linux.cpp
src/efivar-lite.linux.c
)
endif()
if(WIN32)
target_sources(${PROJECT_NAME}-core PRIVATE
src/driveinfo.win32.cpp
src/efivar-lite.c
src/efivar-lite.common.h
src/efivar-lite.win32.c
)
endif()
if(APPLE)
target_sources(${PROJECT_NAME}-core PRIVATE
src/driveinfo.darwin.cpp
src/efivar-lite.c
src/efivar-lite.common.h
src/efivar-lite.darwin.c
)
endif()
# Headers:
target_sources(${PROJECT_NAME}-core PRIVATE
include/bootentry.h
include/bootentrydelegate.h
include/bootentryform.h
include/bootentrylistmodel.h
include/bootentrylistview.h
include/bootentrywidget.h
include/commands.h
include/compat.h
include/devicepathproxymodel.h
include/devicepathview.h
include/disableundoredo.h
include/driveinfo.h
include/efiboot.h
include/efibootdata.h
include/efibooteditor.h
include/efibooteditorcli.h
include/efikeysequence.h
include/efikeysequenceedit.h
include/efivar-lite/device-paths.h
include/efivar-lite/efivar-lite.h
include/efivar-lite/key-option.h
include/efivar-lite/load-option.h
include/filepathdelegate.h
include/filepathdialog.h
include/hotkey.h
include/hotkeydelegate.h
include/hotkeylistmodel.h
include/hotkeysdialog.h
include/hotkeysview.h
include/qindicatorwidget.h
include/qlabelwrapped.h
include/qresizabletabwidget.h
include/qwidgetitemdelegate.h
)
add_executable(${PROJECT_NAME} WIN32 MACOSX_BUNDLE
src/main.cpp
)
target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}-core)
# Compile options
get_target_property(SOURCES ${PROJECT_NAME}-core SOURCES)
## GCC
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# Enable all warnings only in application code
set_source_files_properties(${SOURCES} PROPERTIES COMPILE_OPTIONS "-Wall;-Wpedantic;-Werror;-pedantic;-Wshadow;-Wextra;-Wconversion;$<$:-Weffc++>")
endif()
## Clang
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") # MSVC compatibility mode
# Fix ignoring warnings in system includes
set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX /imsvc)
set(CMAKE_INCLUDE_SYSTEM_FLAG_C /imsvc)
else() # Standard
# Enable all warnings only in application code
set_source_files_properties(${SOURCES} PROPERTIES COMPILE_OPTIONS "-Weverything;-pedantic;-Werror")
endif()
# Disable some compatibility warnings
target_compile_options(${PROJECT_NAME}-core PUBLIC
-Wno-c++20-compat
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-cast-qual
-Wno-declaration-after-statement
-Wno-exit-time-destructors
-Wno-global-constructors
-Wno-padded
-Wno-return-std-move-in-c++11
-Wno-switch-default
-Wno-unknown-warning-option
-Wno-unsafe-buffer-usage
-Wno-poison-system-directories
)
endif()
## MSVC
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# Fix ignoring warnings in system includes
set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX /external:I)
set(CMAKE_INCLUDE_SYSTEM_FLAG_C /external:I)
target_compile_options(${PROJECT_NAME}-core PUBLIC
/Z7
# Ignore warnings in external includes
/experimental:external /external:anglebrackets
)
endif()
if(WIN32)
target_compile_options(${PROJECT_NAME}-core PUBLIC
# Ignore warnings in external includes
/external:W0
)
# Enable all warnings only in application code
set_source_files_properties(${SOURCES} PROPERTIES COMPILE_OPTIONS "/Wall;/permissive-;/WX")
# Disable some warnings
target_compile_options(${PROJECT_NAME}-core PUBLIC
# C4371: 'classname': layout of class may have changed from a previous version of the compiler due to better packing of member 'member'
/wd4371
# C4710: 'function' : function not inlined
/wd4710 # Needed for RELEASE builds
# C4711: function 'function' selected for inline expansion
/wd4711 # Needed for RELEASE builds
# C4820: 'bytes' bytes padding added after construct 'member_name'
/wd4820
# C4866: compiler may not enforce left-to-right evaluation order for call to 'C++17 operator'
/wd4866
# C4868: compiler may not enforce left-to-right evaluation order in braced initializer list
/wd4868
# C5045: Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
/wd5045
)
endif()
# Forms:
target_sources(${PROJECT_NAME}-core PRIVATE
src/form/bootentryform.ui
src/form/bootentrywidget.ui
src/form/efibooteditor.ui
src/form/filepathdialog.ui
src/form/hotkeysdialog.ui
)
# Resources:
qt_add_resources(RESOURCES icons.qrc)
target_sources(${PROJECT_NAME} PRIVATE ${RESOURCES})
if(WIN32)
target_sources(${PROJECT_NAME} PRIVATE
windows.rc
)
endif()
# Translations
FILE(GLOB TRANSLATIONS
${CMAKE_SOURCE_DIR}/translations/${PROJECT_NAME}_*.ts
)
set_source_files_properties(${TRANSLATIONS}
PROPERTIES OUTPUT_LOCATION "${CMAKE_BINARY_DIR}/translations"
)
qt_add_translations(${PROJECT_NAME}
TS_FILES ${TRANSLATIONS}
RESOURCE_PREFIX "/"
INCLUDE_DIRECTORIES "include"
LUPDATE_OPTIONS "-no-obsolete")
# Libraries
if(APPLE)
target_link_libraries(${PROJECT_NAME}-core PUBLIC
"-framework CoreFoundation"
"-framework DiskArbitration"
"-framework IOKit"
)
elseif(UNIX)
find_package(PkgConfig REQUIRED)
pkg_check_modules(EFIVAR REQUIRED efivar efiboot)
target_link_libraries(${PROJECT_NAME}-core PUBLIC ${EFIVAR_LIBRARIES})
endif()
if(WIN32)
target_link_options(${PROJECT_NAME} PRIVATE
/MANIFESTUAC:level=\'requireAdministrator\'
)
endif()
if(("${CMAKE_BUILD_TYPE}" STREQUAL "Release") AND UNIX)
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_RELEASE -s)
endif()
# Testing
enable_testing()
add_subdirectory(tests)
# Packaging
if(WIN32)
install(TARGETS ${PROJECT_NAME}
RUNTIME
DESTINATION .
LIBRARY
DESTINATION .
ARCHIVE
DESTINATION .
BUNDLE
DESTINATION dist
)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
install(FILES ${ZLIB_LIBRARY_DLL_DEBUG}
DESTINATION .
COMPONENT Runtime
)
else()
install(FILES ${ZLIB_LIBRARY_DLL_RELEASE}
DESTINATION .
COMPONENT Runtime
)
endif()
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION .)
else()
include(GNUInstallDirs)
install(TARGETS ${PROJECT_NAME}
RUNTIME
DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE
DESTINATION ${CMAKE_INSTALL_LIBDIR}
BUNDLE
DESTINATION dist
)
if(UNIX AND NOT APPLE)
install(PROGRAMS misc/run-${PROJECT_NAME}
DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT Desktop
)
install(PROGRAMS misc/run-${PROJECT_NAME}
DESTINATION .
RENAME AppRun
COMPONENT AppImage
)
install(FILES misc/${PROJECT_NAME_CAPITALIZED}.desktop
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications
COMPONENT Desktop
)
install(FILES misc/org.x.${PROJECT_NAME}.policy
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/polkit-1/actions/
COMPONENT Desktop
)
install(FILES misc/${PROJECT_NAME_CAPITALIZED}.metainfo.xml
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo
COMPONENT Desktop
)
install(FILES misc/${PROJECT_NAME_CAPITALIZED}.svg
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons
COMPONENT Desktop
)
endif()
endif()
set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
set(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT Runtime)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(CMAKE_INSTALL_DEBUG_LIBRARIES TRUE)
set(CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY TRUE)
endif()
include(InstallRequiredSystemLibraries)
# Bundle Qt Libraries
if(WIN32)
if(NOT WINDEPLOYQT_EXECUTABLE)
find_program(WINDEPLOYQT_EXECUTABLE NAMES windeployqt HINTS ${QT${QT_VERSION_MAJOR}_INSTALL_PREFIX}/bin REQUIRED)
endif()
# windeployqt in 6.5.0 has broken translations support https://codereview.qt-project.org/c/qt/qtbase/+/468903
if(${QT_VERSION} VERSION_EQUAL 6.5.0)
set(SKIP_TRANSLATIONS "--no-translations")
endif()
add_custom_command(TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND ${WINDEPLOYQT_EXECUTABLE} --dir ${CMAKE_BINARY_DIR}/qt --no-compiler-runtime --pdb "$/$" ${SKIP_TRANSLATIONS}
)
install(DIRECTORY "${CMAKE_BINARY_DIR}/qt/"
DESTINATION .
COMPONENT Runtime
PATTERN "*.pdb" EXCLUDE
)
if(("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") OR ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo"))
install(FILES "$"
DESTINATION .
COMPONENT Debug
)
install(DIRECTORY "${CMAKE_BINARY_DIR}/qt/"
DESTINATION .
COMPONENT Debug
FILES_MATCHING
PATTERN "*.pdb"
)
endif()
elseif(APPLE)
if(NOT MACDEPLOYQT_EXECUTABLE)
find_program(MACDEPLOYQT_EXECUTABLE NAMES macdeployqt HINTS ${QT${QT_VERSION_MAJOR}_INSTALL_PREFIX}/bin REQUIRED)
endif()
add_custom_command(TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND ${MACDEPLOYQT_EXECUTABLE} "$" -always-overwrite
)
else()
if(NOT LINUXDEPLOY_EXECUTABLE)
find_program(LINUXDEPLOY_EXECUTABLE NAMES linuxdeploy linuxdeploy.AppImage linuxdeploy-x86_64.AppImage linuxdeploy-aarch64.AppImage)
endif()
if(LINUXDEPLOY_EXECUTABLE)
get_target_property(QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)
add_custom_command(TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND QMAKE=${QMAKE_EXECUTABLE} ${LINUXDEPLOY_EXECUTABLE} --plugin=qt --appdir=${CMAKE_BINARY_DIR}/appdir/ --executable="$/$"
)
install(DIRECTORY "${CMAKE_BINARY_DIR}/appdir/usr/"
DESTINATION .
COMPONENT Runtime
USE_SOURCE_PERMISSIONS
)
endif()
endif()
# CPack
set(CPACK_CREATE_DESKTOP_LINKS ${PROJECT_NAME_CAPITALIZED})
set(CPACK_PACKAGE_CONTACT "Maciej Szeptuch ")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_DESCRIPTION})
set(CPACK_PACKAGE_DIRECTORY dist)
set(CPACK_PACKAGE_EXECUTABLES ${PROJECT_NAME} ${PROJECT_NAME_CAPITALIZED})
set(CPACK_PACKAGE_HOMEPAGE_URL ${PROJECT_HOMEPAGE_URL})
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${PROJECT_NAME_CAPITALIZED})
set(CPACK_PACKAGE_NAME ${APPLICATION_NAME})
set(CPACK_PACKAGE_VENDOR ${PROJECT_NAME_CAPITALIZED})
set(CPACK_PACKAGE_VERSION ${FULL_VERSION})
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt")
set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")
set(CPACK_PACKAGE_ICON ${PROJECT_NAME_CAPITALIZED}.svg)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
set(CPACK_STRIP_FILES TRUE)
endif()
if(WIN32)
set(CPACK_PACKAGE_TARGET_OS_NAME "windows")
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ARM64")
# WiX Toolset unavailable
set(CPACK_GENERATOR ZIP)
else()
set(CPACK_GENERATOR WIX ZIP)
set(CPACK_PACKAGE_VERSION ${VERSION}.${VERSION_TWEAK}) # WiX doesn't support SemVer
set(CPACK_WIX_LIGHT_EXTRA_FLAGS "-dcl:high")
set(CPACK_WIX_PRODUCT_ICON "${CMAKE_SOURCE_DIR}/misc/${PROJECT_NAME_CAPITALIZED}.ico")
set(CPACK_WIX_UI_BANNER "${CMAKE_SOURCE_DIR}/misc/wix_banner.png")
set(CPACK_WIX_UI_DIALOG "${CMAKE_SOURCE_DIR}/misc/wix_dialog.png")
set(CPACK_WIX_PROPERTY_ARPHELPLINK ${CPACK_PACKAGE_HOMEPAGE_URL})
set(CPACK_WIX_PROPERTY_ARPURLINFOABOUT ${CPACK_PACKAGE_HOMEPAGE_URL})
set(CPACK_WIX_ROOT_FEATURE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY})
set(CPACK_WIX_UPGRADE_GUID "4DC9BB3B-A552-49D8-A04B-5C13353DB826")
set(CPACK_WIX_TEMPLATE "${CMAKE_SOURCE_DIR}/misc/WIX.template.in")
endif()
elseif(APPLE)
set(CPACK_PACKAGE_TARGET_OS_NAME "macosx")
set(CPACK_GENERATOR DragNDrop TZST)
set(MACOSX_BUNDLE_ICON_FILE "${PROJECT_NAME_CAPITALIZED}.icns")
set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/misc/${MACOSX_BUNDLE_ICON_FILE}")
set(CPACK_BUNDLE_ICON ${CPACK_PACKAGE_ICON})
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY NO)
# Seems like since macOS 13 hdiutil needs elevated access to work properly
# at least in GitHub Actions https://github.com/actions/runner-images/issues/7522#issuecomment-1564467252
set(CPACK_COMMAND_HDIUTIL "/usr/bin/sudo /usr/bin/hdiutil")
else()
set(CPACK_PACKAGE_TARGET_OS_NAME "linux")
set(CPACK_GENERATOR DEB TZST AppImage)
set(CPACK_PROJECT_CONFIG_FILE "${CMAKE_SOURCE_DIR}/cmake/CPackLinux.cmake")
set(CPACK_DEBIAN_PACKAGE_NAME ${PROJECT_NAME_CAPITALIZED})
#set(CPACK_DEBIAN_COMPRESSION_TYPE "zstd") Not supported on current Debian Bullseye
set(CPACK_DEBIAN_PACKAGE_SECTION "admin")
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
#set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
set(CPACK_DEB_COMPONENT_INSTALL ON)
set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE)
# Built from GitHub actions
if(NOT ("$ENV{BUILD_OS}" STREQUAL ""))
# Because installed with aqt Qt needs to be specified manually in dependencies
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt${QT_VERSION_MAJOR}gui${QT_VERSION_MAJOR} (>= ${Qt${QT_VERSION_MAJOR}_VERSION}), libqt${QT_VERSION_MAJOR}widgets${QT_VERSION_MAJOR} (>= ${Qt${QT_VERSION_MAJOR}_VERSION}), libqt${QT_VERSION_MAJOR}network${QT_VERSION_MAJOR} (>= ${Qt${QT_VERSION_MAJOR}_VERSION})")
if(${QT_VERSION_MAJOR} GREATER 5)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt${QT_VERSION_MAJOR}core${QT_VERSION_MAJOR} (>= ${Qt${QT_VERSION_MAJOR}_VERSION}), ${CPACK_DEBIAN_PACKAGE_DEPENDS}")
else()
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt${QT_VERSION_MAJOR}core${QT_VERSION_MAJOR}a (>= ${Qt${QT_VERSION_MAJOR}_VERSION}), ${CPACK_DEBIAN_PACKAGE_DEPENDS}")
endif()
endif()
if(("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") OR ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo"))
set(CPACK_DEBIAN_DEBUGINFO_PACKAGE ON)
endif()
set(CPACK_APPIMAGE_NO_APPSTREAM ON)
endif()
# Built from GitHub actions
if(NOT ("$ENV{BUILD_OS}" STREQUAL ""))
set(CPACK_PACKAGE_TARGET_OS_NAME "$ENV{BUILD_OS}")
endif()
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME_CAPITALIZED}-v${FULL_VERSION}-${CPACK_PACKAGE_TARGET_OS_NAME}-qt-${Qt${QT_VERSION_MAJOR}_VERSION}")
include(CPackComponent)
cpack_add_component(Program
DISPLAY_NAME "EFI Boot Editor"
DESCRIPTION "Main executable"
REQUIRED
)
cpack_add_component(Desktop
DISPLAY_NAME "Desktop files"
DESCRIPTION "Useful files for running in Desktop Environment"
DEPENDS Program
)
cpack_add_component(Runtime
DISPLAY_NAME "Runtime libraries"
DESCRIPTION "Necessary runtime libraries"
DEPENDS Program
)
cpack_add_component(Debug
DISPLAY_NAME "Debug symbols"
DESCRIPTION "Debug symbols to aid troubleshooting"
DISABLED
DEPENDS Program
)
include(CPack)
================================================
FILE: CMakePresets.json
================================================
{
"version": 10,
"cmakeMinimumRequired": {
"major": 3,
"minor": 16,
"patch": 0
},
"configurePresets": [
{
"name": "base-os",
"displayName": "Base OS Config",
"description": "Shared foundation for all OS configurations.",
"hidden": true,
"binaryDir": "${sourceDir}/build/${presetName}"
},
{
"name": "Debug",
"displayName": "Debug Build",
"description": "Main config for local development and debugging. Provides full debug symbols.",
"inherits": ["base-os"],
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "RelWithDebInfo",
"displayName": "Optimized Release",
"description": "Optimized for release performance with debug info for profiling.",
"inherits": ["base-os"],
"cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
}
}
],
"buildPresets": [
{
"name": "Debug",
"displayName": "Debug",
"configurePreset": "Debug",
"configuration": "Debug"
},
{
"name": "RelWithDebInfo",
"displayName": "Optimized Release",
"configurePreset": "RelWithDebInfo",
"configuration": "RelWithDebInfo"
}
],
"testPresets": [
{
"name": "Debug",
"displayName": "Debug",
"configurePreset": "Debug",
"configuration": "Debug",
"output": {
"outputOnFailure": true
}
},
{
"name": "RelWithDebInfo",
"displayName": "Optimized Release",
"configurePreset": "RelWithDebInfo",
"configuration": "RelWithDebInfo",
"output": {
"outputOnFailure": true
}
}
]
}
================================================
FILE: INSTALL.md
================================================
# Install EFI Boot Editor
## Build from source
### Dependencies
Necessary tools:
- [CMake](//cmake.org) (>= 3.16)
- [pkg-config](//www.freedesktop.org/wiki/Software/pkg-config/)
- recent C/C++ compiler with C++17 support,
recommended [GCC](//gcc.gnu.org/) (>= 11.4.0)
or [Clang](//clang.llvm.org/) (>= 14.0.0),
or [MSVC](//learn.microsoft.com/en-us/cpp/) (>= 19.44.35219.0) on Windows
Required libraries[^1]:
[^1]: Remember to install **development** files as well. For example
`qt6-base-dev`, `libefivar-dev`, `libefiboot-dev`, `zlib1g-dev` on Ubuntu.
- [Qt5](//doc.qt.io/qt-5/gettingstarted.html) (>= 5.15)
or [Qt6](//doc.qt.io/qt-6/get-and-install-qt.html) (>= 6.2)
- [zlib](//github.com/madler/zlib) (>=1.2)
- [efivar](//github.com/rhboot/efivar) (>= 37) on Linux
### Build steps
You can list the available configure and build presets with:
```shell
cmake --list-presets
```
1. Configure:
```shell
cmake --preset \
-DCMAKE_INSTALL_PREFIX=/usr \
[-Dparameter=value ...]
-- The C compiler identification is GNU 12.2.0
-- The CXX compiler identification is GNU 12.2.0
...
-- Build files have been written to: /efibooteditor/build/
```
Choose a preset from the list (`cmake --list-presets`). For example, to
configure a debug build:
```shell
cmake --preset Debug
```
You can still pass additional CMake cache variables using the `-D` flag.
For example, to set the install prefix:
```shell
cmake --preset Debug -DCMAKE_INSTALL_PREFIX=/usr
```
Available general parameters that can be passed with `-D`:
- `CMAKE_BUILD_TYPE=Debug,Release,RelWithDebInfo,MinSizeRel` - specifies
the build type, can be used to overwrite custom/default C/C++ compiler
flags with recommended values
- `QT_VERSION_MAJOR=5,6` - force Qt5 or Qt6 build,
useful if both are installed
2. Build
You can build using the configured preset:
```shell
cmake --build --preset
```
For example, to build the `Debug` preset:
```shell
cmake --build --preset Debug
```
Alternatively, if you configured without a build preset, you can build
directly from the build directory:
```shell
cmake --build build --config Release
[ 5%] Automatic MOC and UIC for target efibooteditor
...
[100%] Built target efibooteditor
```
3. Install
```shell
cmake --install build
-- Install configuration: ""
-- Installing: /usr/bin/efibooteditor
...
```
### Other
There is also:
- a [package](//aur.archlinux.org/packages/efibooteditor) in
the AUR for Arch Linux
([-git variant](//aur.archlinux.org/packages/efibooteditor-git))
- and a [SPEC file](misc/efibooteditor.spec) for RPM based
distributions (thanks [@Justinzobel](https://github.com/Justinzobel)).
## Pre-built packages
[Releases](//github.com/Neverous/efibooteditor/releases) automatically build
a set of packages - they're mostly considered for testing purposes / making sure
that the code compiles correctly on various environments, but they should also
work just fine for normal usage. Just keep in mind they might have some specific
requirements inherited from the build environment.
### Rolling development builds (Latest master)
For the absolute latest builds, you can download automated artifacts from GitHub Actions: **[Latest successful builds](https://github.com/Neverous/efibooteditor/actions/workflows/release.yml?query=is%3Asuccess)**
**How to download:**
1. Click the link above and select the **most recent** run
2. Scroll down to the **Artifacts** section at the bottom of the page
3. Download the package specific to your operating system
*Note: You must be logged into a GitHub account to download artifacts from the Actions tab.*
### Winget
Latest releases are also available for download with
[Windows Package Manager](https://github.com/microsoft/winget-pkgs/tree/master/manifests/e/EFIBootEditor/EFIBootEditor).
### Assets
Packages follow a specific naming pattern:
EFIBootEditor-[{VERSION}](#version)-[{OS}](#os)-[{QT_VERSION}](#qt_version)-[{COMPILER}](#compiler).[{EXTENSION}](#extension).
#### VERSION
Release version.
#### OS
Operating system used during build and generally which was targeted for
the runtime. The package might work on other systems with similar versions of
system libraries.
#### QT_VERSION
Targeted Qt version, generally required to have compatible Qt version installed,
though some packages include all the necessary libraries in the bundles.
#### COMPILER
Compiler used during compilation, generally shouldn't matter but there might be
some bugs caught in one but not the other.
#### EXTENSION
Assets are delivered in various formats:
- `.dmg` - macOS App Bundle.
- `.deb` - Debian package - should also work on any Debian derivative as long
as dependencies are met.[^2]
- `.ddeb` - Debian debug symbol package - primarily useful during
troubleshooting.
- `.msi` - Windows installer.
- `.zip`, `.tar.zst` - simple archive files, should contain all necessary files,
ready to use in-place after decompression (`.zip` is for Windows
and `.tar.zst` is for macOS and Linux).
- `.AppImage` - [AppImage](https://appimage.org/) portable Linux application
format.
[^2]: Using `.deb` packages on old Ubuntu (< 21.10) or Debian (< bullseye)
releases might require manual Qt installation as versions in the official
repositories are older than the minimum requirements.
In the CI [aqtinstall](//github.com/miurahr/aqtinstall) is used for
installation, but then package install needs to be probably forced.
Quick search through the internet also reveals PPAs with pre-built packages
from [Stephan Binner](//launchpad.net/~beineri) that might be useful.
================================================
FILE: LICENSE.txt
================================================
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
================================================
FILE: README.md
================================================
# EFI Boot Editor
Boot Editor for (U)EFI based systems.



## Command-line interface
There is also a command-line interface for quick backup/restore functionality:
```shell
Usage: efibooteditor [options]
Boot Editor for (U)EFI based systems.
Options:
-h, --help Displays help on commandline options.
--help-all Displays help including Qt specific options.
-v, --version Displays version information.
-e, --export Export configuration.
-d, --dump Dump raw EFI data.
-i, --import Import configuration from JSON (either from export or
raw dump).
-f, --force Force import, don't ask for confirmation.
```
## Requirements
* [Qt](//www.qt.io/) (>=5.15)
* [zlib](//github.com/madler/zlib) (>=1.2)
* [efivar](//github.com/rhboot/efivar) (>=37) on linux
## Installation
See [INSTALL](INSTALL.md) instructions.
## Localization
You can help localize this project on [Weblate](https://hosted.weblate.org/engage/efibooteditor/).
[](//hosted.weblate.org/engage/efibooteditor/)
## License
This project is licensed under the LGPLv3 License -
see the [LICENSE](LICENSE.txt) file for details
================================================
FILE: cmake/CPackLinux.cmake
================================================
if (CPACK_GENERATOR STREQUAL "DEB")
list(REMOVE_ITEM CPACK_COMPONENTS_ALL "Runtime")
endif()
if (NOT CPACK_GENERATOR STREQUAL "AppImage")
list(REMOVE_ITEM CPACK_COMPONENTS_ALL "AppImage")
endif()
================================================
FILE: cmake/FindZLIB.cmake
================================================
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
FindZLIB
--------
Find the native ZLIB includes and library.
IMPORTED Targets
^^^^^^^^^^^^^^^^
.. versionadded:: 3.1
This module defines :prop_tgt:`IMPORTED` target ``ZLIB::ZLIB``, if
ZLIB has been found.
Result Variables
^^^^^^^^^^^^^^^^
This module defines the following variables:
``ZLIB_INCLUDE_DIRS``
where to find zlib.h, etc.
``ZLIB_LIBRARIES``
List of libraries when using zlib.
``ZLIB_LIBRARIES_DLL``
List of dynamic libraries when using zlib. (Windows only)
``ZLIB_FOUND``
True if zlib found.
``ZLIB_VERSION``
.. versionadded:: 3.26
the version of Zlib found.
See also legacy variable ``ZLIB_VERSION_STRING``.
.. versionadded:: 3.4
Debug and Release variants are found separately.
Legacy Variables
^^^^^^^^^^^^^^^^
The following variables are provided for backward compatibility:
``ZLIB_VERSION_MAJOR``
The major version of zlib.
.. versionchanged:: 3.26
Superseded by ``ZLIB_VERSION``.
``ZLIB_VERSION_MINOR``
The minor version of zlib.
.. versionchanged:: 3.26
Superseded by ``ZLIB_VERSION``.
``ZLIB_VERSION_PATCH``
The patch version of zlib.
.. versionchanged:: 3.26
Superseded by ``ZLIB_VERSION``.
``ZLIB_VERSION_TWEAK``
The tweak version of zlib.
.. versionchanged:: 3.26
Superseded by ``ZLIB_VERSION``.
``ZLIB_VERSION_STRING``
The version of zlib found (x.y.z)
.. versionchanged:: 3.26
Superseded by ``ZLIB_VERSION``.
``ZLIB_MAJOR_VERSION``
The major version of zlib. Superseded by ``ZLIB_VERSION_MAJOR``.
``ZLIB_MINOR_VERSION``
The minor version of zlib. Superseded by ``ZLIB_VERSION_MINOR``.
``ZLIB_PATCH_VERSION``
The patch version of zlib. Superseded by ``ZLIB_VERSION_PATCH``.
Hints
^^^^^
A user may set ``ZLIB_ROOT`` to a zlib installation root to tell this
module where to look.
.. versionadded:: 3.24
Set ``ZLIB_USE_STATIC_LIBS`` to ``ON`` to look for static libraries.
Default is ``OFF``.
#]=======================================================================]
if(ZLIB_FIND_COMPONENTS AND NOT ZLIB_FIND_QUIETLY)
message(AUTHOR_WARNING
"ZLIB does not provide any COMPONENTS. Calling\n"
" find_package(ZLIB COMPONENTS ...)\n"
"will always fail."
)
endif()
set(_ZLIB_SEARCHES)
# Search ZLIB_ROOT first if it is set.
if(ZLIB_ROOT)
set(_ZLIB_SEARCH_ROOT PATHS ${ZLIB_ROOT} NO_DEFAULT_PATH)
list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_ROOT)
endif()
# Normal search.
set(_ZLIB_x86 "(x86)")
set(_ZLIB_SEARCH_NORMAL
PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]"
"$ENV{ProgramFiles}/zlib"
"$ENV{ProgramFiles${_ZLIB_x86}}/zlib")
unset(_ZLIB_x86)
list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL)
if(ZLIB_USE_STATIC_LIBS)
set(ZLIB_NAMES zlibstatic zlibstat zlib z)
set(ZLIB_NAMES_DEBUG zlibstaticd zlibstatd zlibd zd)
else()
set(ZLIB_NAMES z zlib zdll zlib1 zlibstatic zlibwapi zlibvc zlibstat)
set(ZLIB_NAMES_DEBUG zd zlibd zdlld zlibd1 zlib1d zlibstaticd zlibwapid zlibvcd zlibstatd)
endif()
# Try each search configuration.
foreach(search ${_ZLIB_SEARCHES})
find_path(ZLIB_INCLUDE_DIR NAMES zlib.h ${${search}} PATH_SUFFIXES include)
endforeach()
# Allow ZLIB_LIBRARY to be set manually, as the location of the zlib library
if(NOT ZLIB_LIBRARY)
if(DEFINED CMAKE_FIND_LIBRARY_PREFIXES)
set(_zlib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
else()
set(_zlib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES)
endif()
if(DEFINED CMAKE_FIND_LIBRARY_SUFFIXES)
set(_zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES}")
else()
set(_zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES)
endif()
# Prefix/suffix of the win32/Makefile.gcc build
if(WIN32)
list(APPEND CMAKE_FIND_LIBRARY_PREFIXES "" "lib")
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a")
endif()
# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
if(ZLIB_USE_STATIC_LIBS)
if(WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
endif()
endif()
foreach(search ${_ZLIB_SEARCHES})
find_library(ZLIB_LIBRARY_RELEASE NAMES ${ZLIB_NAMES} NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib)
find_library(ZLIB_LIBRARY_DEBUG NAMES ${ZLIB_NAMES_DEBUG} NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib)
endforeach()
# Restore the original find library ordering
if(DEFINED _zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES)
set(CMAKE_FIND_LIBRARY_SUFFIXES "${_zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}")
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES)
endif()
if(DEFINED _zlib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES)
set(CMAKE_FIND_LIBRARY_PREFIXES "${_zlib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES}")
else()
set(CMAKE_FIND_LIBRARY_PREFIXES)
endif()
include(SelectLibraryConfigurations)
select_library_configurations(ZLIB)
endif()
#if(WIN32)
# Allow ZLIB_LIBRARY_DLL to be set manually, as the location of the zlib dll library
if(NOT ZLIB_LIBRARY_DLL)
set(ZLIB_NAMES_DLL "${ZLIB_NAMES}")
set(ZLIB_NAMES_DLL_DEBUG "${ZLIB_NAMES_DEBUG}")
list(TRANSFORM ZLIB_NAMES_DLL APPEND ".dll")
list(TRANSFORM ZLIB_NAMES_DLL_DEBUG APPEND ".dll")
foreach(search ${_ZLIB_SEARCHES})
find_program(ZLIB_DLL_LIBRARY_RELEASE NAMES ${ZLIB_NAMES_DLL} NAMES_PER_DIR ${${search}} PATH_SUFFIXES bin)
find_program(ZLIB_DLL_LIBRARY_DEBUG NAMES ${ZLIB_NAMES_DLL_DEBUG} NAMES_PER_DIR ${${search}} PATH_SUFFIXES bin)
endforeach()
include(SelectLibraryConfigurations)
select_library_configurations(ZLIB_DLL)
set(ZLIB_LIBRARY_DLL "${ZLIB_DLL_LIBRARY}")
set(ZLIB_LIBRARIES_DLL "${ZLIB_DLL_LIBRARIES}")
set(ZLIB_LIBRARY_DLL_RELEASE "${ZLIB_DLL_LIBRARY_RELEASE}")
set(ZLIB_LIBRARY_DLL_DEBUG "${ZLIB_DLL_LIBRARY_DEBUG}")
unset(ZLIB_DLL_LIBRARY)
unset(ZLIB_DLL_LIBRARIES)
unset(ZLIB_DLL_LIBRARY_RELEASE)
unset(ZLIB_DLL_LIBRARY_DEBUG)
unset(ZLIB_NAMES_DLL)
unset(ZLIB_NAMES_DEBUG_DLL)
endif()
#endif()
unset(ZLIB_NAMES)
unset(ZLIB_NAMES_DEBUG)
mark_as_advanced(ZLIB_INCLUDE_DIR)
if(ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
file(STRINGS "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_H REGEX "^#define ZLIB_VERSION \"[^\"]*\"$")
string(REGEX REPLACE "^.*ZLIB_VERSION \"([0-9]+).*$" "\\1" ZLIB_VERSION_MAJOR "${ZLIB_H}")
string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_MINOR "${ZLIB_H}")
string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_PATCH "${ZLIB_H}")
set(ZLIB_VERSION_STRING "${ZLIB_VERSION_MAJOR}.${ZLIB_VERSION_MINOR}.${ZLIB_VERSION_PATCH}")
# only append a TWEAK version if it exists:
set(ZLIB_VERSION_TWEAK "")
if( "${ZLIB_H}" MATCHES "ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+)")
set(ZLIB_VERSION_TWEAK "${CMAKE_MATCH_1}")
string(APPEND ZLIB_VERSION_STRING ".${ZLIB_VERSION_TWEAK}")
endif()
set(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}")
set(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}")
set(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}")
endif()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB REQUIRED_VARS ZLIB_LIBRARY ZLIB_INCLUDE_DIR
VERSION_VAR ZLIB_VERSION
HANDLE_COMPONENTS)
if(ZLIB_FOUND)
set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
if(NOT ZLIB_LIBRARIES)
set(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
endif()
if(NOT ZLIB_LIBRARIES_DLL)
set(ZLIB_LIBRARIES_DLL ${ZLIB_LIBRARY_DLL})
endif()
if(NOT TARGET ZLIB::ZLIB)
if(ZLIB_LIBRARY_DLL)
add_library(ZLIB::ZLIB SHARED IMPORTED)
else()
add_library(ZLIB::ZLIB UNKNOWN IMPORTED)
endif()
set_target_properties(ZLIB::ZLIB PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}")
if(ZLIB_LIBRARY_RELEASE)
set_property(TARGET ZLIB::ZLIB APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
if(ZLIB_LIBRARY_DLL_RELEASE)
set_target_properties(ZLIB::ZLIB PROPERTIES
IMPORTED_IMPLIB_RELEASE "${ZLIB_LIBRARY_RELEASE}"
IMPORTED_LOCATION_RELEASE "${ZLIB_LIBRARY_DLL_RELEASE}")
else()
set_target_properties(ZLIB::ZLIB PROPERTIES
IMPORTED_LOCATION_RELEASE "${ZLIB_LIBRARY_RELEASE}")
endif()
endif()
if(ZLIB_LIBRARY_DEBUG)
set_property(TARGET ZLIB::ZLIB APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
if(ZLIB_LIBRARY_DLL_DEBUG)
set_target_properties(ZLIB::ZLIB PROPERTIES
IMPORTED_IMPLIB_DEBUG "${ZLIB_LIBRARY_DEBUG}"
IMPORTED_LOCATION_DEBUG "${ZLIB_LIBRARY_DLL_DEBUG}")
else()
set_target_properties(ZLIB::ZLIB PROPERTIES
IMPORTED_LOCATION_DEBUG "${ZLIB_LIBRARY_DEBUG}")
endif()
endif()
if(NOT ZLIB_LIBRARY_RELEASE AND NOT ZLIB_LIBRARY_DEBUG)
if(ZLIB_LIBRARY_DLL)
set_property(TARGET ZLIB::ZLIB APPEND PROPERTY
IMPORTED_IMPLIB "${ZLIB_LIBRARY}"
IMPORTED_LOCATION "${ZLIB_LIBRARY_DLL}")
else()
set_property(TARGET ZLIB::ZLIB APPEND PROPERTY
IMPORTED_LOCATION "${ZLIB_LIBRARY}")
endif()
endif()
endif()
endif()
================================================
FILE: doc/RELEASE.md
================================================
# Release process
1. Draft release for new tag through [GitHub UI](https://github.com/Neverous/efibooteditor/releases)
2. Create tag for new version
```shell
git tag -s vX.Y.Z -m ""
git push tag vX.Y.Z
```
3. Monitor the asset preparation in GHA, it should publish the draft after it's done
## Update [AUR](https://aur.archlinux.org/packages/efibooteditor)
1. Bump version in PKGBUILD
2. Update b2sums: `makepkg -g`
3. Update SRCINFO: `makepkg --printsrcinfo > .SRCINFO`
4. Commit and push changes to AUR
```shell
git commit -m "Update to vX.Y.Z"
git push
```
================================================
FILE: doc/screenshot.json
================================================
{
"AuditMode": false,
"Boot": {
"0000": {
"attributes": 1,
"description": "Windows Boot Manager",
"efi_attributes": 7,
"file_path": [
{
"partition_format": 2,
"partition_number": 1,
"partition_signature": "{721c8b66-426c-4e86-8e99-3457c46ab0b9}",
"partition_size": "0x32",
"partition_start": "0x1CD6",
"signature_type": 2,
"subtype": "HD",
"type": "MEDIA"
},
{
"path_name": "\\EFI\\Microsoft\\Boot\\bootmgfw.efi",
"subtype": "FILE_PATH",
"type": "MEDIA"
},
{
"_subtype": 255,
"subtype": "MULTI",
"type": "END"
}
],
"optional_data": "V0lORE9XUwABAAAAiAAAAHgAAABCAEMARABPAEIASgBFAEMAVAA9AHsAOQBkAGUAYQA4ADYAMgBjAC0ANQBjAGQAZAAtADQAZQA3ADAALQBhAGMAYwAxAC0AZgAzADIAYgAzADQANABkADQANwA5ADUAfQAAADkAAQAAABAAAAAEAAAAf/8EAA==",
"optional_data_format": 0
},
"0001": {
"attributes": 1,
"description": "Arch Linux",
"efi_attributes": 7,
"file_path": [
{
"partition_format": 2,
"partition_number": 1,
"partition_signature": "{721c8b66-426c-4e86-8e99-3457c46ab0b9}",
"partition_size": "0x32",
"partition_start": "0x15876",
"signature_type": 2,
"subtype": "HD",
"type": "MEDIA"
},
{
"path_name": "\\vmlinuz-linux",
"subtype": "FILE_PATH",
"type": "MEDIA"
},
{
"_subtype": 255,
"subtype": "MULTI",
"type": "END"
}
],
"optional_data": "root=/dev/sda2 rw initrd=\\initramfs-linux.img init=/lib/systemd/systemd quiet logo.nologo console=tty1",
"optional_data_format": 1
},
"0010": {
"attributes": 256,
"description": "Setup",
"efi_attributes": 7,
"file_path": [
{
"name": "{721c8b66-426c-4e86-8e99-3457c46ab0b9}",
"subtype": "FIRMWARE_FILE",
"type": "MEDIA"
},
{
"_subtype": 255,
"subtype": "MULTI",
"type": "END"
}
],
"optional_data": "",
"optional_data_format": 2
},
"0011": {
"attributes": 256,
"description": "Boot Menu",
"efi_attributes": 7,
"file_path": [
{
"name": "{721c8b66-426c-4e86-8e99-3457c46ab0b9}",
"subtype": "FIRMWARE_FILE",
"type": "MEDIA"
},
{
"_subtype": 255,
"subtype": "MULTI",
"type": "END"
}
],
"optional_data": "",
"optional_data_format": 2
},
"0012": {
"attributes": 256,
"description": "Diagnostic Splash",
"efi_attributes": 7,
"file_path": [
{
"name": "{721c8b66-426c-4e86-8e99-3457c46ab0b9}",
"subtype": "FIRMWARE_FILE",
"type": "MEDIA"
},
{
"_subtype": 255,
"subtype": "MULTI",
"type": "END"
}
],
"optional_data": "",
"optional_data_format": 2
},
"0017": {
"attributes": 257,
"description": "PCI LAN: EFI Network (IPv4)",
"efi_attributes": 7,
"file_path": [
{
"hid": 167985616,
"subtype": "ACPI",
"type": "ACPI",
"uid": 0
},
{
"device": 28,
"function": 3,
"subtype": "PCI",
"type": "HW"
},
{
"device": 0,
"function": 0,
"subtype": "PCI",
"type": "HW"
},
{
"address": "54ee7562e09c0000000000000000000000000000000000000000000000000000",
"if_type": 0,
"subtype": "MAC_ADDRESS",
"type": "MSG"
},
{
"gateway_ip_address": "0.0.0.0",
"local_ip_address": "0.0.0.0",
"local_port": 0,
"protocol": 0,
"remote_ip_address": "0.0.0.0",
"remote_port": 0,
"static_ip_address": false,
"subnet_mask": "0.0.0.0",
"subtype": "IPV4",
"type": "MSG"
},
{
"_subtype": 255,
"subtype": "MULTI",
"type": "END"
}
],
"optional_data": "꽊⨫仼鲧쳵㶏̸",
"optional_data_format": 1
},
"0019": {
"attributes": 385,
"description": "PCI LAN: EFI Network (IPv6)",
"efi_attributes": 7,
"file_path": [
{
"hid": 167985616,
"subtype": "ACPI",
"type": "ACPI",
"uid": 0
},
{
"device": 28,
"function": 3,
"subtype": "PCI",
"type": "HW"
},
{
"device": 0,
"function": 0,
"subtype": "PCI",
"type": "HW"
},
{
"address": "54ee7562e09c0000000000000000000000000000000000000000000000000000",
"if_type": 0,
"subtype": "MAC_ADDRESS",
"type": "MSG"
},
{
"gateway_ip_address": "::",
"ip_address_origin": 0,
"local_ip_address": "::",
"local_port": 0,
"prefix_length": 64,
"protocol": 0,
"remote_ip_address": "::",
"remote_port": 0,
"subtype": "IPV6",
"type": "MSG"
},
{
"_subtype": 255,
"subtype": "MULTI",
"type": "END"
}
],
"optional_data": "꽊⨫仼鲧쳵㶏̸",
"optional_data_format": 1
}
},
"BootOptionSupport": {
"capabilities": [
"KEY",
"APP",
"SYSPREP"
],
"key_count": 3
},
"BootOrder": [
0,
1
],
"DeployedMode": false,
"Key": {
"0000": {
"boot_option": 17,
"keys": "F2",
"vendor_data": ""
},
"0001": {
"boot_option": 17,
"keys": "Delete",
"vendor_data": ""
},
"0002": {
"boot_option": 1,
"keys": "a",
"vendor_data": ""
},
"0003": {
"boot_option": 0,
"keys": "w",
"vendor_data": ""
},
"0004": {
"boot_option": 16,
"keys": "Shift+Alt+S",
"vendor_data": ""
}
},
"OsIndicationsSupported": [
"BOOT_TO_FW_UI",
"CAPSULE_RESULT_VAR_SUPPORTED"
],
"SecureBoot": true,
"SetupMode": false,
"Timeout": 10,
"VendorKeys": false
}
================================================
FILE: icons/Tango/index.theme
================================================
[Icon Theme]
Name=Tango
Comment=Tango Icon Theme
Inherits=gnome,crystalsvg
Example=x-directory-normal
# KDE Specific Stuff
DisplayDepth=32
LinkOverlay=link_overlay
LockOverlay=lock_overlay
ZipOverlay=zip_overlay
DesktopDefault=48
ToolbarDefault=22
MainToolbarDefault=22
SmallDefault=16
SmallSizes=16
PanelDefault=32
# Directory list
Directories=16x16/actions,16x16/apps,16x16/categories,16x16/devices,16x16/emblems,16x16/emotes,16x16/mimetypes,16x16/places,16x16/status,22x22/actions,22x22/apps,22x22/categories,22x22/devices,22x22/emblems,22x22/emotes,22x22/mimetypes,22x22/places,22x22/status,24x24/actions,24x24/apps,24x24/categories,24x24/devices,24x24/emblems,24x24/emotes,24x24/mimetypes,24x24/places,24x24/status,32x32/actions,32x32/apps,32x32/categories,32x32/devices,32x32/emblems,32x32/emotes,32x32/mimetypes,32x32/places,32x32/status,48x48/actions,48x48/apps,48x48/categories,48x48/devices,48x48/emblems,48x48/emotes,48x48/mimetypes,48x48/places,48x48/status,64x64/actions,64x64/apps,64x64/categories,64x64/devices,64x64/emblems,64x64/emotes,64x64/mimetypes,64x64/places,64x64/status,72x72/actions,72x72/apps,72x72/categories,72x72/devices,72x72/emblems,72x72/emotes,72x72/mimetypes,72x72/places,72x72/status,96x96/actions,96x96/apps,96x96/categories,96x96/devices,96x96/emblems,96x96/emotes,96x96/mimetypes,96x96/places,96x96/status,128x128/actions,128x128/apps,128x128/categories,128x128/devices,128x128/emblems,128x128/emotes,128x128/mimetypes,128x128/places,128x128/status,scalable/actions,scalable/apps,scalable/categories,scalable/devices,scalable/emblems,scalable/emotes,scalable/mimetypes,scalable/places,scalable/status
[scalable/actions]
Size=48
Context=Actions
Type=Scalable
MinSize=32
MaxSize=256
[scalable/apps]
Size=48
Context=Applications
Type=Scalable
MinSize=32
MaxSize=256
[scalable/categories]
Size=48
Context=Categories
Type=Scalable
MinSize=32
MaxSize=256
[scalable/devices]
Size=48
Context=Devices
Type=Scalable
MinSize=32
MaxSize=256
[scalable/emblems]
Size=48
Context=Emblems
Type=Scalable
MinSize=32
MaxSize=256
[scalable/emotes]
Size=48
Context=Emotes
Type=Scalable
Minsize=32
MaxSize=256
[scalable/mimetypes]
Size=48
Context=MimeTypes
Type=Scalable
MinSize=32
MaxSize=256
[scalable/places]
Size=48
Context=Places
Type=Scalable
MinSize=32
MaxSize=256
[scalable/status]
Size=48
Context=Status
Type=Scalable
MinSize=32
MaxSize=256
================================================
FILE: icons/Tango/scalable/places/folder.icon
================================================
[Icon Data]
AttachPoints=200,800|800,800|800,80|200,80
================================================
FILE: icons/Tango/scalable/status/folder-drag-accept.icon
================================================
[Icon Data]
AttachPoints=200,200|800,200|800,800|200,800
================================================
FILE: icons/Tango/scalable/status/folder-visiting.icon
================================================
[Icon Data]
AttachPoints=200,200|800,200|800,800|200,800
================================================
FILE: icons.qrc
================================================
icons/Tango/index.theme
icons/Tango/scalable/actions/application-exit.svg
icons/Tango/scalable/actions/document-open.svg
icons/Tango/scalable/actions/document-properties.svg
icons/Tango/scalable/actions/document-revert.svg
icons/Tango/scalable/actions/document-save-as.svg
icons/Tango/scalable/actions/document-save.svg
icons/Tango/scalable/actions/edit-copy.svg
icons/Tango/scalable/actions/edit-redo.svg
icons/Tango/scalable/actions/edit-undo.svg
icons/Tango/scalable/actions/format-justify-left.svg
icons/Tango/scalable/actions/go-down.svg
icons/Tango/scalable/actions/go-up.svg
icons/Tango/scalable/actions/list-add.svg
icons/Tango/scalable/actions/list-remove.svg
icons/Tango/scalable/actions/process-stop.svg
icons/Tango/scalable/actions/system-search.svg
icons/Tango/scalable/actions/view-refresh.svg
icons/Tango/scalable/apps/help-browser.svg
icons/Tango/scalable/categories/preferences-system.svg
icons/Tango/scalable/devices/audio-card.svg
icons/Tango/scalable/devices/computer.svg
icons/Tango/scalable/devices/drive-harddisk.svg
icons/Tango/scalable/devices/drive-optical.svg
icons/Tango/scalable/devices/drive-removable-media.svg
icons/Tango/scalable/devices/input-gaming.svg
icons/Tango/scalable/devices/media-flash.svg
icons/Tango/scalable/devices/media-floppy.svg
icons/Tango/scalable/devices/network-wired.svg
icons/Tango/scalable/devices/network-wireless.svg
icons/Tango/scalable/emblems/emblem-symbolic-link.svg
icons/Tango/scalable/mimetypes/text-html.svg
================================================
FILE: include/bootentry.h
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include "efiboot.h"
namespace FilePath
{
/*
Hardware
This Device Path defines how a device is attached to the resource domain of a system, where resource domain is simply the shared memory, memory mapped I/O, and I/O space of the system.
*/
/*
PCI
The Device Path for PCI defines the path to the PCI configuration space address for a PCI device.
*/
class Pci
{
public:
static constexpr auto TYPE = "HW";
static constexpr auto SUBTYPE = "PCI";
private:
mutable QString _string = {};
public:
uint8_t function = {};
uint8_t device = {};
public:
Pci() = default;
Pci(const EFIBoot::File_path::HW::Pci &pci);
EFIBoot::File_path::HW::Pci toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
PCCARD
PCCARD Settings.
*/
class Pccard
{
public:
static constexpr auto TYPE = "HW";
static constexpr auto SUBTYPE = "PCCARD";
private:
mutable QString _string = {};
public:
uint8_t function_number = {};
public:
Pccard() = default;
Pccard(const EFIBoot::File_path::HW::Pccard &pccard);
EFIBoot::File_path::HW::Pccard toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Memory Mapped
Memory Mapped Settings.
*/
class MemoryMapped
{
public:
static constexpr auto TYPE = "HW";
static constexpr auto SUBTYPE = "MEMORY_MAPPED";
private:
mutable QString _string = {};
public:
EFIBoot::File_path::HW::Memory_mapped::MEMORY_TYPE memory_type = {};
uint64_t start_address = {};
uint64_t end_address = {};
public:
MemoryMapped() = default;
MemoryMapped(const EFIBoot::File_path::HW::Memory_mapped &memory_mapped);
EFIBoot::File_path::HW::Memory_mapped toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Controller
Controller settings.
*/
class Controller
{
public:
static constexpr auto TYPE = "HW";
static constexpr auto SUBTYPE = "CONTROLLER";
private:
mutable QString _string = {};
public:
uint32_t controller_number = {};
public:
Controller() = default;
Controller(const EFIBoot::File_path::HW::Controller &controller);
EFIBoot::File_path::HW::Controller toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
BMC
The Device Path for a Baseboard Management Controller (BMC) host interface.
*/
class Bmc
{
public:
static constexpr auto TYPE = "HW";
static constexpr auto SUBTYPE = "BMC";
private:
mutable QString _string = {};
public:
EFIBoot::File_path::HW::Bmc::INTERFACE_TYPE interface_type = {};
uint64_t base_address = {};
public:
Bmc() = default;
Bmc(const EFIBoot::File_path::HW::Bmc &bmc);
EFIBoot::File_path::HW::Bmc toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
ACPI
This Device Path is used to describe devices whose enumeration is not described in an industry-standard fashion. These devices must be described using ACPI AML in the ACPI name space; this Device Path is a linkage to the ACPI name space.
*/
/*
ACPI
This Device Path contains ACPI Device IDs that represent a device’s Plug and Play Hardware ID and its corresponding unique persistent ID.
*/
class Acpi
{
public:
static constexpr auto TYPE = "ACPI";
static constexpr auto SUBTYPE = "ACPI";
private:
mutable QString _string = {};
public:
uint32_t hid = {};
uint32_t uid = {};
public:
Acpi() = default;
Acpi(const EFIBoot::File_path::ACPI::Acpi &acpi);
EFIBoot::File_path::ACPI::Acpi toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Expanded
This Device Path contains ACPI Device IDs that represent a device’s Plug and Play Hardware ID and its corresponding unique persistent ID.
*/
class Expanded
{
public:
static constexpr auto TYPE = "ACPI";
static constexpr auto SUBTYPE = "EXPANDED";
private:
mutable QString _string = {};
public:
uint32_t hid = {};
uint32_t uid = {};
uint32_t cid = {};
QString hidstr = {};
QString uidstr = {};
QString cidstr = {};
public:
Expanded() = default;
Expanded(const EFIBoot::File_path::ACPI::Expanded &expanded);
EFIBoot::File_path::ACPI::Expanded toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
ADR
The ADR device path is used to contain video output device attributes to support the Graphics Output Protocol.
*/
class Adr
{
public:
static constexpr auto TYPE = "ACPI";
static constexpr auto SUBTYPE = "ADR";
private:
mutable QString _string = {};
public:
uint32_t adr = {};
QByteArray additional_adr = {};
public:
Adr() = default;
Adr(const EFIBoot::File_path::ACPI::Adr &adr);
EFIBoot::File_path::ACPI::Adr toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
NVDIMM
This device path describes an NVDIMM device using the ACPI 6.0 specification defined NFIT Device Handle as the identifier.
*/
class Nvdimm
{
public:
static constexpr auto TYPE = "ACPI";
static constexpr auto SUBTYPE = "NVDIMM";
private:
mutable QString _string = {};
public:
uint32_t nfit_device_handle = {};
public:
Nvdimm() = default;
Nvdimm(const EFIBoot::File_path::ACPI::Nvdimm &nvdimm);
EFIBoot::File_path::ACPI::Nvdimm toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Messaging
This Device Path is used to describe the connection of devices outside the resource domain of the system. This Device Path can describe physical messaging information such as a SCSI ID, or abstract information such as networking protocol IP addresses.
*/
/*
ATAPI
ATAPI Settings.
*/
class Atapi
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "ATAPI";
private:
mutable QString _string = {};
public:
bool primary = {};
bool slave = {};
uint16_t lun = {};
public:
Atapi() = default;
Atapi(const EFIBoot::File_path::MSG::Atapi &atapi);
EFIBoot::File_path::MSG::Atapi toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
SCSI
SCSI Settings.
*/
class Scsi
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "SCSI";
private:
mutable QString _string = {};
public:
uint16_t pun = {};
uint16_t lun = {};
public:
Scsi() = default;
Scsi(const EFIBoot::File_path::MSG::Scsi &scsi);
EFIBoot::File_path::MSG::Scsi toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Fibre Channel
Fibre Channel Settings
*/
class FibreChannel
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "FIBRE_CHANNEL";
private:
mutable QString _string = {};
public:
uint32_t reserved = {};
uint64_t world_wide_name = {};
uint64_t lun = {};
public:
FibreChannel() = default;
FibreChannel(const EFIBoot::File_path::MSG::Fibre_channel &fibre_channel);
EFIBoot::File_path::MSG::Fibre_channel toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Firewire
Firewire Settings.
*/
class Firewire
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "FIREWIRE";
private:
mutable QString _string = {};
public:
uint32_t reserved = {};
uint64_t guid = {};
public:
Firewire() = default;
Firewire(const EFIBoot::File_path::MSG::Firewire &firewire);
EFIBoot::File_path::MSG::Firewire toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
USB
USB settings.
*/
class Usb
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "USB";
private:
mutable QString _string = {};
public:
uint8_t parent_port_number = {};
uint8_t interface_number = {};
public:
Usb() = default;
Usb(const EFIBoot::File_path::MSG::Usb &usb);
EFIBoot::File_path::MSG::Usb toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
I2O
I2O Settings
*/
class I2o
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "I2O";
private:
mutable QString _string = {};
public:
uint32_t tid = {};
public:
I2o() = default;
I2o(const EFIBoot::File_path::MSG::I2o &i2o);
EFIBoot::File_path::MSG::I2o toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
InfiniBand
InfiniBand Settings.
*/
class Infiniband
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "INFINIBAND";
private:
mutable QString _string = {};
public:
uint32_t resource_flags = {};
QUuid port_gid = {};
uint64_t ioc_guid_service_id = {};
uint64_t target_port_id = {};
uint64_t device_id = {};
public:
Infiniband() = default;
Infiniband(const EFIBoot::File_path::MSG::Infiniband &infiniband);
EFIBoot::File_path::MSG::Infiniband toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
MAC Address
MAC settings.
*/
class MacAddress
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "MAC_ADDRESS";
private:
mutable QString _string = {};
public:
QString address = {};
uint8_t if_type = {};
public:
MacAddress() = default;
MacAddress(const EFIBoot::File_path::MSG::Mac_address &mac_address);
EFIBoot::File_path::MSG::Mac_address toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
IPv4
IPv4 settings.
*/
class Ipv4
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "IPV4";
private:
mutable QString _string = {};
public:
QHostAddress local_ip_address = {};
QHostAddress remote_ip_address = {};
uint16_t local_port = {};
uint16_t remote_port = {};
uint16_t protocol = {};
bool static_ip_address = {};
QHostAddress gateway_ip_address = {};
QHostAddress subnet_mask = {};
public:
Ipv4() = default;
Ipv4(const EFIBoot::File_path::MSG::Ipv4 &ipv4);
EFIBoot::File_path::MSG::Ipv4 toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
IPv6
IPv6 settings.
*/
class Ipv6
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "IPV6";
private:
mutable QString _string = {};
public:
QHostAddress local_ip_address = {};
QHostAddress remote_ip_address = {};
uint16_t local_port = {};
uint16_t remote_port = {};
uint16_t protocol = {};
EFIBoot::File_path::MSG::Ipv6::IP_ADDRESS_ORIGIN ip_address_origin = {};
uint8_t prefix_length = {};
QHostAddress gateway_ip_address = {};
public:
Ipv6() = default;
Ipv6(const EFIBoot::File_path::MSG::Ipv6 &ipv6);
EFIBoot::File_path::MSG::Ipv6 toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
UART
UART Settings.
*/
class Uart
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "UART";
private:
mutable QString _string = {};
public:
uint32_t reserved = {};
uint64_t baud_rate = {};
uint8_t data_bits = {};
EFIBoot::File_path::MSG::Uart::PARITY parity = {};
EFIBoot::File_path::MSG::Uart::STOP_BITS stop_bits = {};
public:
Uart() = default;
Uart(const EFIBoot::File_path::MSG::Uart &uart);
EFIBoot::File_path::MSG::Uart toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
USB Class
USB Class Settings.
*/
class UsbClass
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "USB_CLASS";
private:
mutable QString _string = {};
public:
uint16_t vendor_id = {};
uint16_t product_id = {};
uint8_t device_class = {};
uint8_t device_subclass = {};
uint8_t device_protocol = {};
public:
UsbClass() = default;
UsbClass(const EFIBoot::File_path::MSG::Usb_class &usb_class);
EFIBoot::File_path::MSG::Usb_class toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
USB WWID
This device path describes a USB device using its serial number.
*/
class UsbWwid
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "USB_WWID";
private:
mutable QString _string = {};
public:
uint16_t interface_number = {};
uint16_t device_vendor_id = {};
uint16_t device_product_id = {};
QString serial_number = {};
public:
UsbWwid() = default;
UsbWwid(const EFIBoot::File_path::MSG::Usb_wwid &usb_wwid);
EFIBoot::File_path::MSG::Usb_wwid toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Device Logical Unit
Device Logical Unit Settings.
*/
class DeviceLogicalUnit
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "DEVICE_LOGICAL_UNIT";
private:
mutable QString _string = {};
public:
uint8_t lun = {};
public:
DeviceLogicalUnit() = default;
DeviceLogicalUnit(const EFIBoot::File_path::MSG::Device_logical_unit &device_logical_unit);
EFIBoot::File_path::MSG::Device_logical_unit toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
SATA
SATA settings.
*/
class Sata
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "SATA";
private:
mutable QString _string = {};
public:
uint16_t hba_port_number = {};
uint16_t port_multiplier_port_number = {};
uint16_t lun = {};
public:
Sata() = default;
Sata(const EFIBoot::File_path::MSG::Sata &sata);
EFIBoot::File_path::MSG::Sata toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
iSCSI
iSCSI Settings.
*/
class Iscsi
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "ISCSI";
private:
mutable QString _string = {};
public:
uint16_t protocol = {};
uint16_t options = {};
uint64_t lun = {};
uint16_t target_portal_group = {};
QString target_name = {};
public:
Iscsi() = default;
Iscsi(const EFIBoot::File_path::MSG::Iscsi &iscsi);
EFIBoot::File_path::MSG::Iscsi toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
VLAN
VLAN Settings.
*/
class Vlan
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "VLAN";
private:
mutable QString _string = {};
public:
uint16_t vlan_id = {};
public:
Vlan() = default;
Vlan(const EFIBoot::File_path::MSG::Vlan &vlan);
EFIBoot::File_path::MSG::Vlan toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Fibre Channel Ex
The Fibre Channel Ex device path clarifies the definition of the Logical Unit Number field to conform with the T-10 SCSI Architecture Model 4 specification.
*/
class FibreChannelEx
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "FIBRE_CHANNEL_EX";
private:
mutable QString _string = {};
public:
uint32_t reserved = {};
uint64_t world_wide_name = {};
uint64_t lun = {};
public:
FibreChannelEx() = default;
FibreChannelEx(const EFIBoot::File_path::MSG::Fibre_channel_ex &fibre_channel_ex);
EFIBoot::File_path::MSG::Fibre_channel_ex toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
SAS Extended Messaging
The SAS Ex device path clarifies the definition of the Logical Unit Number field to conform with the T-10 SCSI Architecture Model 4 specification.
*/
class SasExtendedMessaging
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "SAS_EXTENDED_MESSAGING";
private:
mutable QString _string = {};
public:
uint64_t sas_address = {};
uint64_t lun = {};
uint16_t device_and_topology_info = {};
uint16_t relative_target_port = {};
public:
SasExtendedMessaging() = default;
SasExtendedMessaging(const EFIBoot::File_path::MSG::Sas_extended_messaging &sas_extended_messaging);
EFIBoot::File_path::MSG::Sas_extended_messaging toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
NVM Express NS
NVM Express Namespace Settings.
*/
class NvmExpressNs
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "NVM_EXPRESS_NS";
private:
mutable QString _string = {};
public:
uint32_t namespace_identifier = {};
uint64_t ieee_extended_unique_identifier = {};
public:
NvmExpressNs() = default;
NvmExpressNs(const EFIBoot::File_path::MSG::Nvm_express_ns &nvm_express_ns);
EFIBoot::File_path::MSG::Nvm_express_ns toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
URI
Refer to RFC 3986 for details on the URI contents.
*/
class Uri
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "URI";
private:
mutable QString _string = {};
public:
QUrl uri = {};
public:
Uri() = default;
Uri(const EFIBoot::File_path::MSG::Uri &uri);
EFIBoot::File_path::MSG::Uri toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
UFS
UFS Settings.
*/
class Ufs
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "UFS";
private:
mutable QString _string = {};
public:
uint8_t pun = {};
uint8_t lun = {};
public:
Ufs() = default;
Ufs(const EFIBoot::File_path::MSG::Ufs &ufs);
EFIBoot::File_path::MSG::Ufs toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
SD
SD Settings.
*/
class Sd
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "SD";
private:
mutable QString _string = {};
public:
uint8_t slot_number = {};
public:
Sd() = default;
Sd(const EFIBoot::File_path::MSG::Sd &sd);
EFIBoot::File_path::MSG::Sd toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Bluetooth
EFI Bluetooth Settings.
*/
class Bluetooth
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "BLUETOOTH";
private:
mutable QString _string = {};
public:
QString device_address = {};
public:
Bluetooth() = default;
Bluetooth(const EFIBoot::File_path::MSG::Bluetooth &bluetooth);
EFIBoot::File_path::MSG::Bluetooth toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Wi-Fi
Wi-Fi Settings.
*/
class WiFi
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "WI_FI";
private:
mutable QString _string = {};
public:
QString ssid = {};
public:
WiFi() = default;
WiFi(const EFIBoot::File_path::MSG::Wi_fi &wi_fi);
EFIBoot::File_path::MSG::Wi_fi toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
eMMC
Embedded Multi-Media Card Settings.
*/
class Emmc
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "EMMC";
private:
mutable QString _string = {};
public:
uint8_t slot_number = {};
public:
Emmc() = default;
Emmc(const EFIBoot::File_path::MSG::Emmc &emmc);
EFIBoot::File_path::MSG::Emmc toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
BluetoothLE
EFI BluetoothLE Settings.
*/
class Bluetoothle
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "BLUETOOTHLE";
private:
mutable QString _string = {};
public:
QString device_address = {};
EFIBoot::File_path::MSG::Bluetoothle::ADDRESS_TYPE address_type = {};
public:
Bluetoothle() = default;
Bluetoothle(const EFIBoot::File_path::MSG::Bluetoothle &bluetoothle);
EFIBoot::File_path::MSG::Bluetoothle toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
DNS
DNS Settings.
*/
class Dns
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "DNS";
private:
mutable QString _string = {};
public:
bool ipv6 = {};
QByteArray data = {};
public:
Dns() = default;
Dns(const EFIBoot::File_path::MSG::Dns &dns);
EFIBoot::File_path::MSG::Dns toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
NVDIMM NS
This device path describes a bootable NVDIMM namespace that is defined by a namespace label.
*/
class NvdimmNs
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "NVDIMM_NS";
private:
mutable QString _string = {};
public:
QUuid uuid = {};
public:
NvdimmNs() = default;
NvdimmNs(const EFIBoot::File_path::MSG::Nvdimm_ns &nvdimm_ns);
EFIBoot::File_path::MSG::Nvdimm_ns toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
REST Service
REST Service Settings.
*/
class RestService
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "REST_SERVICE";
private:
mutable QString _string = {};
public:
EFIBoot::File_path::MSG::Rest_service::REST_SERVICE rest_service = {};
EFIBoot::File_path::MSG::Rest_service::ACCESS_MODE access_mode = {};
QUuid guid = {};
QByteArray data = {};
public:
RestService() = default;
RestService(const EFIBoot::File_path::MSG::Rest_service &rest_service);
EFIBoot::File_path::MSG::Rest_service toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
NVMe-oF NS
This device path describes a bootable NVMe over Fiber namespace that is defined by a unique Namespace and Subsystem NQN identity.
*/
class NvmeOfNs
{
public:
static constexpr auto TYPE = "MSG";
static constexpr auto SUBTYPE = "NVME_OF_NS";
private:
mutable QString _string = {};
public:
uint8_t nidt = {};
QUuid nid = {};
QString subsystem_nqn = {};
public:
NvmeOfNs() = default;
NvmeOfNs(const EFIBoot::File_path::MSG::Nvme_of_ns &nvme_of_ns);
EFIBoot::File_path::MSG::Nvme_of_ns toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Media
This Device Path is used to describe the portion of a medium that is being abstracted by a boot service. For example, a Media Device Path could define which partition on a hard drive was being used.
*/
/*
Hard Drive
The Hard Drive Media Device Path is used to represent a partition on a hard drive.
*/
class Hd
{
public:
static constexpr auto TYPE = "MEDIA";
static constexpr auto SUBTYPE = "HD";
private:
mutable QString _string = {};
public:
uint32_t partition_number = {};
uint64_t partition_start = {};
uint64_t partition_size = {};
QUuid partition_signature = {};
EFIBoot::File_path::MEDIA::Hd::PARTITION_FORMAT partition_format = {};
EFIBoot::File_path::MEDIA::Hd::SIGNATURE_TYPE signature_type = {};
public:
Hd() = default;
Hd(const EFIBoot::File_path::MEDIA::Hd &hd);
EFIBoot::File_path::MEDIA::Hd toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
CD-ROM
The CD-ROM Media Device Path is used to define a system partition that exists on a CD-ROM.
*/
class CdRom
{
public:
static constexpr auto TYPE = "MEDIA";
static constexpr auto SUBTYPE = "CD_ROM";
private:
mutable QString _string = {};
public:
uint32_t boot_entry = {};
uint64_t partition_start = {};
uint64_t partition_size = {};
public:
CdRom() = default;
CdRom(const EFIBoot::File_path::MEDIA::Cd_rom &cd_rom);
EFIBoot::File_path::MEDIA::Cd_rom toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
File Path
File Path settings.
*/
class FilePath
{
public:
static constexpr auto TYPE = "MEDIA";
static constexpr auto SUBTYPE = "FILE_PATH";
private:
mutable QString _string = {};
public:
QString path_name = {};
public:
FilePath() = default;
FilePath(const EFIBoot::File_path::MEDIA::File_path &file_path);
EFIBoot::File_path::MEDIA::File_path toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Protocol
The Media Protocol Device Path is used to denote the protocol that is being used in a device path at the location of the path specified.
*/
class Protocol
{
public:
static constexpr auto TYPE = "MEDIA";
static constexpr auto SUBTYPE = "PROTOCOL";
private:
mutable QString _string = {};
public:
QUuid guid = {};
public:
Protocol() = default;
Protocol(const EFIBoot::File_path::MEDIA::Protocol &protocol);
EFIBoot::File_path::MEDIA::Protocol toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Firmware File
Describes a firmware file in a firmware volume.
*/
class FirmwareFile
{
public:
static constexpr auto TYPE = "MEDIA";
static constexpr auto SUBTYPE = "FIRMWARE_FILE";
private:
mutable QString _string = {};
public:
QUuid name = {};
public:
FirmwareFile() = default;
FirmwareFile(const EFIBoot::File_path::MEDIA::Firmware_file &firmware_file);
EFIBoot::File_path::MEDIA::Firmware_file toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Firmware Volume
Describes a firmware volume.
*/
class FirmwareVolume
{
public:
static constexpr auto TYPE = "MEDIA";
static constexpr auto SUBTYPE = "FIRMWARE_VOLUME";
private:
mutable QString _string = {};
public:
QUuid name = {};
public:
FirmwareVolume() = default;
FirmwareVolume(const EFIBoot::File_path::MEDIA::Firmware_volume &firmware_volume);
EFIBoot::File_path::MEDIA::Firmware_volume toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
Relative Offset Range
This device path node specifies a range of offsets relative to the first byte available on the device.
*/
class RelativeOffsetRange
{
public:
static constexpr auto TYPE = "MEDIA";
static constexpr auto SUBTYPE = "RELATIVE_OFFSET_RANGE";
private:
mutable QString _string = {};
public:
uint32_t reserved = {};
uint64_t starting_offset = {};
uint64_t ending_offset = {};
public:
RelativeOffsetRange() = default;
RelativeOffsetRange(const EFIBoot::File_path::MEDIA::Relative_offset_range &relative_offset_range);
EFIBoot::File_path::MEDIA::Relative_offset_range toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
RAM Disk
RAM Disk Settings.
*/
class RamDisk
{
public:
static constexpr auto TYPE = "MEDIA";
static constexpr auto SUBTYPE = "RAM_DISK";
private:
mutable QString _string = {};
public:
uint64_t starting_address = {};
uint64_t ending_address = {};
QUuid guid = {};
uint16_t disk_instance = {};
public:
RamDisk() = default;
RamDisk(const EFIBoot::File_path::MEDIA::Ram_disk &ram_disk);
EFIBoot::File_path::MEDIA::Ram_disk toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
BIOS
This Device Path is used to point to boot legacy operating systems. it is based on the BIOS Boot Specification Version 1.01.
*/
/*
BIOS Boot Specification
This Device Path is used to describe the booting of non-EFI-aware operating systems.
*/
class BootSpecification
{
public:
static constexpr auto TYPE = "BIOS";
static constexpr auto SUBTYPE = "BOOT_SPECIFICATION";
private:
mutable QString _string = {};
public:
uint16_t device_type = {};
uint16_t status_flag = {};
QString description = {};
public:
BootSpecification() = default;
BootSpecification(const EFIBoot::File_path::BIOS::Boot_specification &boot_specification);
EFIBoot::File_path::BIOS::Boot_specification toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
/*
End
Depending on the Sub-Type, this Device Path node is used to indicate the end of the Device Path instance or Device Path structure.
*/
class Vendor
{
public:
static constexpr auto TYPE = "MULTI";
static constexpr auto SUBTYPE = "VENDOR";
private:
mutable QString _string = {};
public:
QByteArray data = {};
QUuid guid = {};
uint8_t _type = {};
public:
Vendor() = default;
Vendor(const EFIBoot::File_path::HW::Vendor &vendor);
Vendor(const EFIBoot::File_path::MSG::Vendor &vendor);
Vendor(const EFIBoot::File_path::MEDIA::Vendor &vendor);
EFIBoot::File_path::ANY toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
class End
{
public:
static constexpr auto TYPE = "END";
static constexpr auto SUBTYPE = "MULTI";
private:
mutable QString _string = {};
public:
uint8_t _subtype = {};
public:
End() = default;
End(const EFIBoot::File_path::END::Instance &)
: _subtype{EFIBoot::File_path::END::Instance::SUBTYPE}
{
}
End(const EFIBoot::File_path::END::Entire &)
: _subtype{EFIBoot::File_path::END::Entire::SUBTYPE}
{
}
EFIBoot::File_path::ANY toEFIBootFilePath() const
{
switch(_subtype)
{
case EFIBoot::File_path::END::Instance::SUBTYPE:
return EFIBoot::File_path::END::Instance{};
case EFIBoot::File_path::END::Entire::SUBTYPE:
return EFIBoot::File_path::END::Entire{};
default:
return {};
}
}
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
class Unknown
{
public:
static constexpr auto TYPE = "UNK";
static constexpr auto SUBTYPE = "UNKNOWN";
private:
mutable QString _string = {};
public:
QByteArray data = {};
uint8_t _type = {};
uint8_t _subtype = {};
public:
Unknown() = default;
Unknown(const EFIBoot::File_path::Unknown &unknown);
EFIBoot::File_path::Unknown toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
using ANY = std::variant<
Pci,
Pccard,
MemoryMapped,
Controller,
Bmc,
Acpi,
Expanded,
Adr,
Nvdimm,
Atapi,
Scsi,
FibreChannel,
Firewire,
Usb,
I2o,
Infiniband,
MacAddress,
Ipv4,
Ipv6,
Uart,
UsbClass,
UsbWwid,
DeviceLogicalUnit,
Sata,
Iscsi,
Vlan,
FibreChannelEx,
SasExtendedMessaging,
NvmExpressNs,
Uri,
Ufs,
Sd,
Bluetooth,
WiFi,
Emmc,
Bluetoothle,
Dns,
NvdimmNs,
RestService,
NvmeOfNs,
Hd,
CdRom,
FilePath,
Protocol,
FirmwareFile,
FirmwareVolume,
RelativeOffsetRange,
RamDisk,
BootSpecification,
Vendor,
End,
Unknown>;
inline std::unordered_map(const QJsonObject &)>> JSON_readers()
{
#define reader(Type) \
{ \
QString("%1/%2").arg(Type::TYPE).arg(Type::SUBTYPE), \
[](const auto &obj) -> std::optional { return Type::fromJSON(obj); } \
}
return {
reader(Pci),
reader(Pccard),
reader(MemoryMapped),
reader(Controller),
reader(Bmc),
reader(Acpi),
// Old ACPI subtype:
{"ACPI/HID", [](const auto &obj) -> std::optional
{ return Acpi::fromJSON(obj); }},
reader(Expanded),
reader(Adr),
reader(Nvdimm),
reader(Atapi),
reader(Scsi),
reader(FibreChannel),
reader(Firewire),
reader(Usb),
reader(I2o),
reader(Infiniband),
reader(MacAddress),
reader(Ipv4),
reader(Ipv6),
reader(Uart),
reader(UsbClass),
reader(UsbWwid),
reader(DeviceLogicalUnit),
reader(Sata),
reader(Iscsi),
reader(Vlan),
reader(FibreChannelEx),
reader(SasExtendedMessaging),
reader(NvmExpressNs),
reader(Uri),
reader(Ufs),
reader(Sd),
reader(Bluetooth),
reader(WiFi),
reader(Emmc),
reader(Bluetoothle),
reader(Dns),
reader(NvdimmNs),
reader(RestService),
reader(NvmeOfNs),
reader(Hd),
reader(CdRom),
reader(FilePath),
// Old FilePath subtype:
{"MEDIA/FILE", [](const auto &obj) -> std::optional
{ return FilePath::fromJSON(obj); }},
reader(Protocol),
reader(FirmwareFile),
reader(FirmwareVolume),
reader(RelativeOffsetRange),
reader(RamDisk),
reader(BootSpecification),
// Old BootSpecification subtype:
{"BIOS/BIOS_BOOT_SPECIFICATION", [](const auto &obj) -> std::optional
{ return BootSpecification::fromJSON(obj); }},
reader(Vendor),
reader(End),
reader(Unknown),
};
#undef reader
}
} // namespace FilePath
Q_DECLARE_METATYPE(const FilePath::ANY *)
class BootEntry
{
private:
mutable QString device_path_str = {};
public:
enum class OptionalDataFormat : uint8_t
{
Base64 = 0,
Utf16 = 1,
Utf8 = 2,
Hex = 3,
};
QVector device_path = {};
QString description = "New entry";
QString error = {};
QString optional_data = {};
EFIBoot::Load_option_attribute attributes = EFIBoot::Load_option_attribute::EMPTY;
uint32_t efi_attributes = EFIBoot::EFI_VARIABLE_ATTRIBUTE_DEFAULTS;
uint32_t crc32 = 0;
uint16_t index = 0;
OptionalDataFormat optional_data_format = OptionalDataFormat::Base64;
bool is_current_boot = false;
bool is_next_boot = false;
bool is_error = false;
public:
static BootEntry fromEFIBootLoadOption(const EFIBoot::Load_option &load_option);
static BootEntry fromError(const QString &error);
EFIBoot::Load_option toEFIBootLoadOption() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString formatDevicePath(bool refresh = true) const;
QString getTitle() const;
bool changeOptionalDataFormat(OptionalDataFormat format, bool test = false);
private:
QByteArray getRawOptionalData() const;
};
Q_DECLARE_METATYPE(const BootEntry *)
================================================
FILE: include/bootentry.h.j2
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include "efiboot.h"
namespace FilePath
{
{% for category in device_paths.values() %}
/*
{{ category.name }}
{{ category.description }}
*/
{% for node in category.nodes if node.slug not in ("vendor", "entire", "instance") %}
{% set qslug = node.slug.split("_")|map("capitalize")|join %}
/*
{{ node.name }}
{{ node.description }}
*/
class {{ qslug }}
{
public:
static constexpr auto TYPE = "{{ category.slug.upper() }}";
static constexpr auto SUBTYPE = "{{ node.slug.upper() }}";
private:
mutable QString _string = {};
public:
{% for field in node.fields %}
{%- if field.type == "guid" %}
QUuid
{%- elif field.type in ("ip4", "ip6") %}
QHostAddress
{%- elif "string" in field.type or field.type == "mac" %}
QString
{%- elif field.type == "uri" %}
QUrl
{%- elif field.type == "raw_data" %}
QByteArray
{%- elif field.type in ("int", "hex") %}
uint{{ field.size * 8 }}_t
{%- elif field.type == "enum" %}
EFIBoot::File_path::{{ category.slug.upper() }}::{{ node.slug.capitalize() }}::{{ field.slug.upper() }}
{%- else %}
{{ field.type }}
{%- endif %} {{ field.slug }} = {};
{% endfor %}
public:
{{ qslug }}() = default;
{{ qslug }}(const EFIBoot::File_path::{{ category.slug.upper() }}::{{ node.slug.capitalize() }} &{{ node.slug }});
EFIBoot::File_path::{{ category.slug.upper() }}::{{ node.slug.capitalize() }} toEFIBootFilePath() const;
static std::optional<{{ qslug }}> fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
{% endfor %}{% endfor %}
class Vendor
{
public:
static constexpr auto TYPE = "MULTI";
static constexpr auto SUBTYPE = "VENDOR";
private:
mutable QString _string = {};
public:
QByteArray data = {};
QUuid guid = {};
uint8_t _type = {};
public:
Vendor() = default;
Vendor(const EFIBoot::File_path::HW::Vendor &vendor);
Vendor(const EFIBoot::File_path::MSG::Vendor &vendor);
Vendor(const EFIBoot::File_path::MEDIA::Vendor &vendor);
EFIBoot::File_path::ANY toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
class End
{
public:
static constexpr auto TYPE = "END";
static constexpr auto SUBTYPE = "MULTI";
private:
mutable QString _string = {};
public:
uint8_t _subtype = {};
public:
End() = default;
End(const EFIBoot::File_path::END::Instance &)
: _subtype{EFIBoot::File_path::END::Instance::SUBTYPE}
{
}
End(const EFIBoot::File_path::END::Entire &)
: _subtype{EFIBoot::File_path::END::Entire::SUBTYPE}
{
}
EFIBoot::File_path::ANY toEFIBootFilePath() const
{
switch(_subtype)
{
case EFIBoot::File_path::END::Instance::SUBTYPE:
return EFIBoot::File_path::END::Instance{};
case EFIBoot::File_path::END::Entire::SUBTYPE:
return EFIBoot::File_path::END::Entire{};
default:
return {};
}
}
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
class Unknown
{
public:
static constexpr auto TYPE = "UNK";
static constexpr auto SUBTYPE = "UNKNOWN";
private:
mutable QString _string = {};
public:
QByteArray data = {};
uint8_t _type = {};
uint8_t _subtype = {};
public:
Unknown() = default;
Unknown(const EFIBoot::File_path::Unknown &unknown);
EFIBoot::File_path::Unknown toEFIBootFilePath() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString toString(bool refresh = true) const;
};
using ANY = std::variant<
{% for category in device_paths.values() %}{% for node in category.nodes if node.slug not in ("vendor", "entire", "instance") %}
{{ node.slug.split("_")|map("capitalize")|join }},
{% endfor %}{% endfor %}
Vendor,
End,
Unknown>;
inline std::unordered_map(const QJsonObject &)>> JSON_readers()
{
#define reader(Type) \
{ \
QString("%1/%2").arg(Type::TYPE).arg(Type::SUBTYPE), \
[](const auto &obj) -> std::optional { return Type::fromJSON(obj); } \
}
return {
{% for category in device_paths.values() %}{% for node in category.nodes if node.slug not in ("vendor", "entire", "instance") %}
reader({{ node.slug.split("_")|map("capitalize")|join }}),
{% endfor %}{% endfor %}
reader(Vendor),
reader(End),
reader(Unknown),
};
#undef reader
}
} // namespace FilePath
Q_DECLARE_METATYPE(const FilePath::ANY *)
class BootEntry
{
private:
mutable QString device_path_str = {};
public:
enum class OptionalDataFormat : uint8_t
{
Base64 = 0,
Utf16 = 1,
Utf8 = 2,
Hex = 3,
};
QVector device_path = {};
QString description = "New entry";
QString error = {};
QString optional_data = {};
EFIBoot::Load_option_attribute attributes = EFIBoot::Load_option_attribute::EMPTY;
uint32_t efi_attributes = EFIBoot::EFI_VARIABLE_ATTRIBUTE_DEFAULTS;
uint32_t crc32 = 0;
uint16_t index = 0;
OptionalDataFormat optional_data_format = OptionalDataFormat::Base64;
bool is_current_boot = false;
bool is_next_boot = false;
bool is_error = false;
public:
static BootEntry fromEFIBootLoadOption(const EFIBoot::Load_option &load_option);
static BootEntry fromError(const QString &error);
EFIBoot::Load_option toEFIBootLoadOption() const;
static std::optional fromJSON(const QJsonObject &obj);
QJsonObject toJSON() const;
QString formatDevicePath(bool refresh = true) const;
QString getTitle() const;
bool changeOptionalDataFormat(OptionalDataFormat format, bool test = false);
private:
QByteArray getRawOptionalData() const;
};
Q_DECLARE_METATYPE(const BootEntry *)
================================================
FILE: include/bootentrydelegate.h
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "bootentry.h"
#include "bootentrylistmodel.h"
#include "bootentrywidget.h"
#include "qwidgetitemdelegate.h"
class BootEntryDelegate: public QWidgetItemDelegate
{
private:
BootEntryListModel::Options options{};
mutable const QModelIndex *currentIndex{nullptr};
public:
BootEntryDelegate();
BootEntryDelegate(const BootEntryDelegate &) = delete;
BootEntryDelegate &operator=(const BootEntryDelegate &) = delete;
void setOptions(const BootEntryListModel::Options &options_);
protected:
void setupWidgetFromItem(Widget &widget, const Item &item, const QModelIndex &index, int role) const override;
private Q_SLOTS:
void setNextBoot(bool checked) const;
};
================================================
FILE: include/bootentryform.h
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include
#include
#include "bootentry.h"
#include "bootentrylistmodel.h"
#include "devicepathproxymodel.h"
namespace Ui
{
class BootEntryForm;
}
class BootEntryForm: public QWidget
{
Q_OBJECT
private:
std::unique_ptr ui;
BootEntryListModel *entries_list_model{nullptr};
DevicePathProxyModel device_path_proxy_model{};
QModelIndex current_index{};
const BootEntry *current_item{nullptr};
bool changing_optional_data_format{false};
public:
explicit BootEntryForm(QWidget *parent = nullptr);
BootEntryForm(const BootEntryForm &) = delete;
BootEntryForm &operator=(const BootEntryForm &) = delete;
~BootEntryForm() override;
void setReadOnly(bool readonly);
void showCategory(bool visible);
void showHotKeys(bool visible);
void setBootEntryListModel(BootEntryListModel &model);
void setItem(const QModelIndex &index, const BootEntry *item);
Q_SIGNALS:
void showHotKeysDialog(int index);
private Q_SLOTS:
void setIndex(const QString &text);
void setDescription(const QString &text);
void setOptionalDataFormat(int format);
void optionalDataEdited();
void setAttribute(int state);
void showHotKeysDialog();
private:
EFIBoot::Load_option_attribute getAttributes() const;
};
================================================
FILE: include/bootentrylistmodel.h
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "bootentry.h"
#include
#include
#include
#include
class BootEntryListModel: public QAbstractListModel
{
Q_OBJECT
friend class EFIBootData;
friend class InsertRemoveBootEntryCommand;
friend class InsertBootEntryCommand;
friend class RemoveBootEntryCommand;
friend class MoveBootEntryCommand;
template
friend class SetBootEntryValueCommand;
friend class ChangeOptionalDataFormatCommand;
friend class SetBootEntryFilePathCommand;
friend class InsertRemoveBootEntryFilePathCommand;
friend class InsertBootEntryFilePathCommand;
friend class RemoveBootEntryFilePathCommand;
friend class MoveBootEntryFilePathCommand;
public:
enum class Option : uint8_t
{
ReadOnly = 0x1,
IsBoot = 0x2,
};
Q_DECLARE_FLAGS(Options, Option)
const QString name;
private:
QVector entries{};
QModelIndex next_boot{};
QUndoStack *undo_stack{nullptr};
public:
const Options options;
public:
explicit BootEntryListModel(const QString &name_, const Options &options_ = {}, QObject *parent = nullptr);
BootEntryListModel(const BootEntryListModel &) = delete;
BootEntryListModel &operator=(const BootEntryListModel &) = delete;
void setUndoStack(QUndoStack *undo_stack_);
QUndoStack *getUndoStack() const;
// Basic functionality:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
void setNextBootEntry(const QModelIndex &index, bool value);
void setEntryFilePath(const QModelIndex &index, int row, const FilePath::ANY &file_path);
void insertEntryFilePath(const QModelIndex &index, int row, const FilePath::ANY &file_path);
void removeEntryFilePath(const QModelIndex &index, int row);
void moveEntryFilePath(const QModelIndex &index, int source_row, int destination_row);
void clearEntryDevicePath(const QModelIndex &index);
void setEntryIndex(const QModelIndex &index, uint16_t value);
void setEntryDescription(const QModelIndex &index, const QString &text);
bool changeEntryOptionalDataFormat(const QModelIndex &index, int format);
void setEntryOptionalData(const QModelIndex &index, const QString &text);
void setEntryAttributes(const QModelIndex &index, EFIBoot::Load_option_attribute value);
void setEntryNextBoot(const QModelIndex &index, bool value);
// Add data:
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
// Remove data:
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
// Move data
bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
void clear();
const QVector &getEntries() const { return entries; }
private:
bool appendRow(const BootEntry &data, const QModelIndex &parent = QModelIndex());
};
================================================
FILE: include/bootentrylistview.h
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include
#include "bootentrydelegate.h"
#include "bootentrylistmodel.h"
class BootEntryListView: public QListView
{
Q_OBJECT
private:
BootEntryDelegate delegate{};
BootEntryListModel::Options options{};
public:
explicit BootEntryListView(QWidget *parent = nullptr);
BootEntryListView(const BootEntryListView &) = delete;
BootEntryListView &operator=(const BootEntryListView &) = delete;
void setModel(QAbstractItemModel *model) override { QListView::setModel(model); }
void setModel(BootEntryListModel *model);
protected:
void selectionChanged(const QItemSelection &selection, const QItemSelection &) override;
Q_SIGNALS:
void selected(const QModelIndex &index);
public Q_SLOTS:
void insertRow();
void duplicateRow();
void removeCurrentRow();
void moveCurrentRowUp();
void moveCurrentRowDown();
void rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow);
void rowsChanged(const QModelIndex &parent, int first, int last);
};
================================================
FILE: include/bootentrywidget.h
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include
#include
class BootEntry;
class QButtonGroup;
namespace Ui
{
class BootEntryWidget;
}
class BootEntryWidget: public QWidget
{
Q_OBJECT
private:
std::unique_ptr ui;
public:
explicit BootEntryWidget(QWidget *parent = nullptr);
BootEntryWidget(const BootEntryWidget &) = delete;
BootEntryWidget &operator=(const BootEntryWidget &) = delete;
~BootEntryWidget() override;
void setReadOnly(bool readonly);
void showBootOptions(bool is_boot);
void showDevicePath(bool not_error);
void setIndex(const uint32_t index);
void setDescription(const QString &description);
void setDevicePath(const QString &device_path);
void setData(const QString &data);
bool getNextBoot() const;
void setNextBoot(bool next_boot);
bool getCurrentBoot() const;
void setCurrentBoot(bool current_boot);
Q_SIGNALS:
void nextBootClicked(bool checked);
};
================================================
FILE: include/commands.h
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "efibootdata.h"
#include
// BootEntry
template
class SetEFIBootDataValueCommand: public QUndoCommand
{
using PropertyPtr = Type EFIBootData::*;
EFIBootData &data;
const QString name;
PropertyPtr property;
SignalPtr signal;
Type value;
public:
SetEFIBootDataValueCommand(EFIBootData &data_, const QString &name_, PropertyPtr property_, SignalPtr signal_, const Type &value_, QUndoCommand *parent = nullptr)
: QUndoCommand(QObject::tr("Change %1 to \"%2\"").arg(name_).arg(value_), parent)
, data{data_}
, name{name_}
, property{property_}
, signal{signal_}
, value{value_}
{
}
SetEFIBootDataValueCommand(const SetEFIBootDataValueCommand &) = delete;
SetEFIBootDataValueCommand &operator=(const SetEFIBootDataValueCommand &) = delete;
int id() const override
{
return 1;
}
void undo() override
{
redo();
}
void redo() override
{
auto old_value = data.*property;
data.*property = value;
value = old_value;
emit(data.*signal)(data.*property);
}
bool mergeWith(const QUndoCommand *command) override
{
const auto cmd = static_cast>(command);
if(&cmd->data != &data)
return false;
if(cmd->property != property)
return false;
if(cmd->signal != signal)
return false;
if(value == data.*property)
setObsolete(true);
setText(QObject::tr("Change %1 to \"%2\"").arg(name).arg(data.*property));
return true;
}
};
template
SetEFIBootDataValueCommand(EFIBootData &data_, const QString &name_, typename SetEFIBootDataValueCommand::PropertyPtr property_, SignalPtr signal_, const Type &value_, QUndoCommand *parent) -> SetEFIBootDataValueCommand;
class InsertRemoveBootEntryCommand: public QUndoCommand
{
private:
BootEntryListModel &model;
QModelIndex index_parent;
BootEntry entry;
int index;
public:
InsertRemoveBootEntryCommand(BootEntryListModel &model_, const QString &description, const QModelIndex &index_parent_, int index_, const BootEntry &entry_, QUndoCommand *parent = nullptr);
InsertRemoveBootEntryCommand(const InsertRemoveBootEntryCommand &) = delete;
InsertRemoveBootEntryCommand &operator=(const InsertRemoveBootEntryCommand &) = delete;
protected:
int id() const override;
void insert();
void remove();
};
class InsertBootEntryCommand: public InsertRemoveBootEntryCommand
{
public:
InsertBootEntryCommand(BootEntryListModel &model_, const QModelIndex &index_parent_, int index_, const BootEntry &entry_, QUndoCommand *parent = nullptr);
InsertBootEntryCommand(const InsertBootEntryCommand &) = delete;
InsertBootEntryCommand &operator=(const InsertBootEntryCommand &) = delete;
void undo() override;
void redo() override;
};
class RemoveBootEntryCommand: public InsertRemoveBootEntryCommand
{
public:
RemoveBootEntryCommand(BootEntryListModel &model_, const QModelIndex &index_parent_, int index_, QUndoCommand *parent = nullptr);
RemoveBootEntryCommand(const RemoveBootEntryCommand &) = delete;
RemoveBootEntryCommand &operator=(const RemoveBootEntryCommand &) = delete;
void undo() override;
void redo() override;
};
class MoveBootEntryCommand: public QUndoCommand
{
BootEntryListModel &model;
const QString title;
QModelIndex source_parent;
QModelIndex destination_parent;
int source_index;
int destination_index;
public:
MoveBootEntryCommand(BootEntryListModel &model_, const QModelIndex &source_parent_, int source_index_, const QModelIndex &destination_parent_, int destination_index_, QUndoCommand *parent = nullptr);
MoveBootEntryCommand(const MoveBootEntryCommand &) = delete;
MoveBootEntryCommand &operator=(const MoveBootEntryCommand &) = delete;
int id() const override;
void undo() override;
void redo() override;
bool mergeWith(const QUndoCommand *command) override;
};
template
class SetBootEntryValueCommand: public QUndoCommand
{
using PropertyPtr = Type BootEntry::*;
BootEntryListModel &model;
const QString title;
const QModelIndex index;
const QString name;
PropertyPtr property;
Type value;
public:
SetBootEntryValueCommand(BootEntryListModel &model_, const QModelIndex &index_, const QString &name_, PropertyPtr property_, const Type &value_, QUndoCommand *parent = nullptr)
: QUndoCommand{"", parent}
, model{model_}
, title{model_.entries.at(index_.row()).getTitle()}
, index{index_}
, name{name_}
, property{property_}
, value{value_}
{
setText(QObject::tr("Change %1 entry \"%2\" %3 to \"%4\"").arg(model.name, title, name).arg(static_cast>(value)));
}
SetBootEntryValueCommand(const SetBootEntryValueCommand &) = delete;
SetBootEntryValueCommand &operator=(const SetBootEntryValueCommand &) = delete;
int id() const override
{
return 3;
}
void undo() override
{
redo();
}
void redo() override
{
auto &entry = model.entries[index.row()];
auto old_value = entry.*property;
entry.*property = value;
value = old_value;
emit model.dataChanged(index, index, {Qt::EditRole});
}
bool mergeWith(const QUndoCommand *command) override
{
auto cmd = static_cast *>(command);
if(&cmd->model != &model)
return false;
if(cmd->index != index)
return false;
if(cmd->property != property)
return false;
auto &entry = model.entries.at(index.row());
if(value == entry.*property)
setObsolete(true);
setText(QObject::tr("Change %1 entry \"%2\" %3 to \"%4\"").arg(model.name, title, name).arg(static_cast>(entry.*property)));
return true;
}
};
class ChangeOptionalDataFormatCommand: public QUndoCommand
{
BootEntryListModel &model;
const QString title;
const QModelIndex index;
BootEntry::OptionalDataFormat value;
public:
ChangeOptionalDataFormatCommand(BootEntryListModel &model_, const QModelIndex &index_, const BootEntry::OptionalDataFormat &value_, QUndoCommand *parent = nullptr);
ChangeOptionalDataFormatCommand(const ChangeOptionalDataFormatCommand &) = delete;
ChangeOptionalDataFormatCommand &operator=(const ChangeOptionalDataFormatCommand &) = delete;
int id() const override;
void undo() override;
void redo() override;
bool mergeWith(const QUndoCommand *command) override;
void updateTitle(BootEntry::OptionalDataFormat val);
};
class InsertRemoveBootEntryFilePathCommand: public QUndoCommand
{
private:
BootEntryListModel &model;
FilePath::ANY file_path;
const QModelIndex index;
int row;
public:
InsertRemoveBootEntryFilePathCommand(BootEntryListModel &model_, const QString &description, const QModelIndex &index_, int row_, const FilePath::ANY &file_path_, QUndoCommand *parent = nullptr);
InsertRemoveBootEntryFilePathCommand(const InsertRemoveBootEntryFilePathCommand &) = delete;
InsertRemoveBootEntryFilePathCommand &operator=(const InsertRemoveBootEntryFilePathCommand &) = delete;
protected:
int id() const override;
void insert();
void remove();
};
class InsertBootEntryFilePathCommand: public InsertRemoveBootEntryFilePathCommand
{
public:
InsertBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int row_, const FilePath::ANY &file_path_, QUndoCommand *parent = nullptr);
InsertBootEntryFilePathCommand(const InsertBootEntryFilePathCommand &) = delete;
InsertBootEntryFilePathCommand &operator=(const InsertBootEntryFilePathCommand &) = delete;
void undo() override;
void redo() override;
};
class RemoveBootEntryFilePathCommand: public InsertRemoveBootEntryFilePathCommand
{
public:
RemoveBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int row_, QUndoCommand *parent = nullptr);
RemoveBootEntryFilePathCommand(const RemoveBootEntryFilePathCommand &) = delete;
RemoveBootEntryFilePathCommand &operator=(const RemoveBootEntryFilePathCommand &) = delete;
void undo() override;
void redo() override;
};
class SetBootEntryFilePathCommand: public QUndoCommand
{
private:
BootEntryListModel &model;
QModelIndex index;
FilePath::ANY value;
int row;
public:
SetBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int row_, const FilePath::ANY &value_, QUndoCommand *parent = nullptr);
SetBootEntryFilePathCommand(const SetBootEntryFilePathCommand &) = delete;
SetBootEntryFilePathCommand &operator=(const SetBootEntryFilePathCommand &) = delete;
int id() const override;
void undo() override;
void redo() override;
};
class MoveBootEntryFilePathCommand: public QUndoCommand
{
BootEntryListModel &model;
const QString title;
QModelIndex index;
int source_row;
int destination_row;
public:
MoveBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int source_row_, int destination_row_, QUndoCommand *parent = nullptr);
MoveBootEntryFilePathCommand(const MoveBootEntryFilePathCommand &) = delete;
MoveBootEntryFilePathCommand &operator=(const MoveBootEntryFilePathCommand &) = delete;
int id() const override;
void undo() override;
void redo() override;
bool mergeWith(const QUndoCommand *command) override;
};
// Hot Keys
class InsertRemoveHotKeyCommand: public QUndoCommand
{
private:
HotKeyListModel &model;
QModelIndex index_parent;
HotKey entry;
int index;
public:
InsertRemoveHotKeyCommand(HotKeyListModel &model_, const QString &description, const QModelIndex &index_parent_, int index_, const HotKey &entry_, QUndoCommand *parent = nullptr);
InsertRemoveHotKeyCommand(const InsertRemoveHotKeyCommand &) = delete;
InsertRemoveHotKeyCommand &operator=(const InsertRemoveHotKeyCommand &) = delete;
protected:
int id() const override;
void insert();
void remove();
};
class InsertHotKeyCommand: public InsertRemoveHotKeyCommand
{
public:
InsertHotKeyCommand(HotKeyListModel &model_, const QModelIndex &index_parent_, int index_, const HotKey &entry_, QUndoCommand *parent = nullptr);
InsertHotKeyCommand(const InsertHotKeyCommand &) = delete;
InsertHotKeyCommand &operator=(const InsertHotKeyCommand &) = delete;
void undo() override;
void redo() override;
};
class RemoveHotKeyCommand: public InsertRemoveHotKeyCommand
{
public:
RemoveHotKeyCommand(HotKeyListModel &model_, const QModelIndex &index_parent_, int index_, QUndoCommand *parent = nullptr);
RemoveHotKeyCommand(const RemoveHotKeyCommand &) = delete;
RemoveHotKeyCommand &operator=(const RemoveHotKeyCommand &) = delete;
void undo() override;
void redo() override;
};
template
class SetHotKeyValueCommand: public QUndoCommand
{
using PropertyPtr = Type HotKey::*;
HotKeyListModel &model;
const QModelIndex index;
const QString name;
PropertyPtr property;
Type value;
public:
SetHotKeyValueCommand(HotKeyListModel &model_, const QModelIndex &index_, const QString &name_, PropertyPtr property_, const Type &value_, QUndoCommand *parent = nullptr)
: QUndoCommand{"", parent}
, model{model_}
, index{index_}
, name{name_}
, property{property_}
, value{value_}
{
setText(QObject::tr("Change %1 entry at position %2 %3 to \"%4\"").arg("Key").arg(index.row()).arg(name).arg(static_cast>(value)));
}
SetHotKeyValueCommand(const SetHotKeyValueCommand &) = delete;
SetHotKeyValueCommand &operator=(const SetHotKeyValueCommand &) = delete;
int id() const override
{
return 6;
}
void undo() override
{
redo();
}
void redo() override
{
auto &entry = model.entries[index.row()];
auto old_value = entry.*property;
entry.*property = value;
value = old_value;
emit model.dataChanged(index, index, {Qt::EditRole});
}
bool mergeWith(const QUndoCommand *command) override
{
auto cmd = static_cast *>(command);
if(&cmd->model != &model)
return false;
if(cmd->index != index)
return false;
if(cmd->property != property)
return false;
auto &entry = model.entries.at(index.row());
if(value == entry.*property)
setObsolete(true);
setText(QObject::tr("Change %1 entry at position %2 %3 to \"%4\"").arg("Key").arg(index.row()).arg(name).arg(static_cast>(entry.*property)));
return true;
}
};
class SetHotKeyKeysCommand: public QUndoCommand
{
private:
HotKeyListModel &model;
QModelIndex index;
EFIKeySequence value;
public:
SetHotKeyKeysCommand(HotKeyListModel &model_, const QModelIndex &index_, const EFIKeySequence &value_, QUndoCommand *parent = nullptr);
SetHotKeyKeysCommand(const SetHotKeyKeysCommand &) = delete;
SetHotKeyKeysCommand &operator=(const SetHotKeyKeysCommand &) = delete;
int id() const override;
void undo() override;
void redo() override;
bool mergeWith(const QUndoCommand *command) override;
};
================================================
FILE: include/compat.h
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include
#include
#include
/* casts */
#if defined(__cplusplus)
#define STATIC_CAST(type) static_cast
#else
#define STATIC_CAST(type) (type)
#define nullptr NULL
#endif
/* attributes */
#if defined(__GNUC__) && !defined(__clang__)
#define ATTR_ARTIFICIAL __attribute__((__artificial__))
#else
#define ATTR_ARTIFICIAL
#endif
/* MSVC compatibility */
#if defined(_MSC_VER)
#include
#define ATTR_ALIGN(X) __declspec(align(X))
#define ATTR_NONNULL(...)
#define ATTR_NONNULL_IS_NULL(x) !(x)
#define ATTR_UNUSED
#define ATTR_VISIBILITY(...)
#define ATTR_WARN_UNUSED_RESULT _Check_return_
typedef SSIZE_T ssize_t;
#else
#define ATTR_ALIGN(X) __attribute__((__aligned__(X)))
#define ATTR_NONNULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
#define ATTR_NONNULL_IS_NULL(x) false
#define ATTR_UNUSED __attribute__((__unused__))
#define ATTR_VISIBILITY(...) __attribute__((__visibility__(__VA_ARGS__)))
#define ATTR_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
#endif
/* Windows compatibility */
#if defined(_WIN32)
#include
#include
#include
#undef interface
typedef uint32_t mode_t;
#else
#include
#include
#include
#include
typedef char TCHAR;
#define ANYSIZE_ARRAY 1
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#pragma clang diagnostic ignored "-Wreserved-identifier"
#pragma clang diagnostic ignored "-Wreserved-macro-identifier"
#endif
#define _T
#define _TRUNCATE STATIC_CAST(size_t)(-1)
inline int _tcsncpy_s(TCHAR *buffer, size_t size, TCHAR *src, size_t _size)
{
(void)_size;
return !buffer || *strncpy(buffer, src, size - 1) == 0;
}
inline int _tcserror_s(TCHAR *buffer, size_t size, int errnum)
{
#if defined(__APPLE__) || ((_POSIX_C_SOURCE >= 200112L) && !defined(_GNU_SOURCE))
return strerror_r(errnum, buffer, size);
#else
TCHAR *msg = strerror_r(errnum, buffer, size);
if(msg == nullptr)
return 0;
return _tcsncpy_s(buffer, size, msg, _TRUNCATE);
#endif
}
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#define _sntprintf_s(buffer, buffer_size, count, format, ...) snprintf(buffer, buffer_size, format, __VA_ARGS__)
#endif
#if defined(__cplusplus)
#include
#include
#include
#include
#include
#include
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
#include
#else
#include
#endif
/* string types */
using tstring = std::basic_string;
using tstring_view = std::basic_string_view;
using tostream = std::basic_ostream;
using tistream = std::basic_istream;
using tiostream = std::basic_iostream;
using tifstream = std::basic_ifstream;
using tofstream = std::basic_ofstream;
using tfstream = std::basic_fstream;
using tstringstream = std::basic_stringstream;
template
inline tstring to_tstring(const Type &value)
{
#if defined(UNICODE) || defined(_UNICODE)
return std::to_wstring(value);
#else
return std::to_string(value);
#endif
}
const int HEX_BASE = 16;
/* QString helpers */
inline tstring QStringToStdTString(const QString &string)
{
#if defined(UNICODE) || defined(_UNICODE)
return string.toStdWString();
#else
return string.toStdString();
#endif
}
inline QString QStringFromTCharArray(const TCHAR *string)
{
#if defined(UNICODE) || defined(_UNICODE)
return QString::fromWCharArray(string);
#else
return string;
#endif
}
inline QString QStringFromStdTString(const tstring &string)
{
#if defined(UNICODE) || defined(_UNICODE)
return QString::fromStdWString(string);
#else
return QString::fromStdString(string);
#endif
}
/* additional helpers */
inline QString toHex(unsigned long long number, int min_width = 0, const QString &prefix = "0x")
{
return prefix + QString("%1").arg(number, min_width, HEX_BASE, QChar('0')).toUpper();
}
inline bool isxnumber(const tstring_view &string)
{
#if defined(UNICODE) || defined(_UNICODE)
return std::all_of(std::begin(string), std::end(string), [](char16_t chr)
{ return iswxdigit(chr); });
#else
return std::all_of(std::begin(string), std::end(string), [](unsigned char chr)
{ return isxdigit(chr); });
#endif
}
template
auto get_default(const Container &data, const typename Container::key_type &key, const typename Container::mapped_type &default_value) -> typename Container::mapped_type
{
if(auto it = data.find(key); it != data.end())
return it->second;
return default_value;
}
template
inline bool toUnicode(QString &output, const Container &input, const char *codec_name = "UTF-8")
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
QStringDecoder decoder{codec_name};
output = decoder.decode(input);
return !decoder.hasError();
#else
auto codec = QTextCodec::codecForName(codec_name);
QTextCodec::ConverterState state;
output = codec->toUnicode(reinterpret_cast(std::data(input)), static_cast(std::size(input)), &state);
return state.invalidChars == 0;
#endif
}
inline QByteArray fromUnicode(const QString &input, const char *codec_name = "UTF-8")
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
QStringEncoder encoder(codec_name);
return encoder.encode(input);
#else
std::unique_ptr encoder{QTextCodec::codecForName(codec_name)->makeEncoder(QTextCodec::IgnoreHeader)};
return encoder->fromUnicode(input);
#endif
}
template
struct type_identity
{
using type = Type;
};
// Like std::underlying_type but also works for non enums
template
using underlying_type_t = typename std::conditional_t, std::underlying_type, type_identity>::type;
// like std::add_const but forces const also for pointer types
template
using add_const_t = typename std::conditional_t, std::add_pointer_t>>, std::add_const_t>;
#endif
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
#endif
inline const void *advance_bytes(const void *ptr, size_t bytes)
{
return STATIC_CAST(const void *)(STATIC_CAST(const uint8_t *)(ptr) + bytes);
}
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
================================================
FILE: include/devicepathproxymodel.h
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "bootentry.h"
#include "bootentrylistmodel.h"
#include
class DevicePathProxyModel: public QAbstractListModel
{
Q_OBJECT
public:
explicit DevicePathProxyModel(QObject *parent = nullptr);
DevicePathProxyModel(const DevicePathProxyModel &) = delete;
DevicePathProxyModel &operator=(const DevicePathProxyModel &) = delete;
void setBootEntryListModel(BootEntryListModel &model);
void setBootEntryItem(const QModelIndex &index, const BootEntry *item);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
void clear();
private:
BootEntryListModel *boot_entry_list_model = nullptr;
QModelIndex boot_entry_index = {};
const QVector *boot_entry_device_path = nullptr;
};
================================================
FILE: include/devicepathview.h
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "filepathdelegate.h"
#include "filepathdialog.h"
#include
class DevicePathView: public QListView
{
Q_OBJECT
private:
FilePathDelegate delegate{};
std::unique_ptr dialog{nullptr};
bool readonly{false};
public:
explicit DevicePathView(QWidget *parent = nullptr);
DevicePathView(const DevicePathView &) = delete;
DevicePathView &operator=(const DevicePathView &) = delete;
void setReadOnly(bool readonly);
public Q_SLOTS:
void insertRow();
void editCurrentRow();
void removeCurrentRow() const;
void moveCurrentRowUp();
void moveCurrentRowDown();
};
================================================
FILE: include/disableundoredo.h
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include
#include
#include
class DisableUndoRedo: public QObject
{
Q_OBJECT
using QObject::QObject;
public:
DisableUndoRedo(const DisableUndoRedo &) = delete;
DisableUndoRedo &operator=(const DisableUndoRedo &) = delete;
protected:
bool eventFilter(QObject *obj, QEvent *ev) override
{
if(ev->type() == QEvent::ShortcutOverride)
{
auto keyEvent = dynamic_cast(ev);
auto isUndo = keyEvent->matches(QKeySequence::Undo);
auto isRedo = keyEvent->matches(QKeySequence::Redo);
return isUndo || isRedo;
}
return QObject::eventFilter(obj, ev);
}
};
================================================
FILE: include/driveinfo.h
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include
#include
#include
class DriveInfo
{
static QVector all;
public:
enum class SIGNATURE : uint8_t
{
NONE = 0x00,
MBR = 0x01,
GUID = 0x02,
};
public:
QString name{};
QUuid signature{};
uint64_t start{0};
uint64_t size{0};
uint32_t partition{0};
SIGNATURE signature_type{SIGNATURE::NONE};
public:
static QVector getAll(bool refresh = false);
bool operator<(const DriveInfo &info) const { return name < info.name; }
};
Q_DECLARE_METATYPE(DriveInfo)
================================================
FILE: include/efiboot.h
================================================
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace EFIBoot
{
extern "C"
{
#include "efivar-lite/device-paths.h"
#include "efivar-lite/efivar-lite.h"
#include "efivar-lite/key-option.h"
#include "efivar-lite/load-option.h"
}
inline bool operator==(const efi_guid_t &first, const efi_guid_t &second)
{
return efi_guid_cmp(&first, &second) == 0;
}
inline bool operator!=(const efi_guid_t &first, const efi_guid_t &second)
{
return efi_guid_cmp(&first, &second) != 0;
}
using Raw_data = std::vector;
template
std::optional deserialize(const void *data, size_t data_size);
namespace File_path
{
/*
Hardware
This Device Path defines how a device is attached to the resource domain of a system, where resource domain is simply the shared memory, memory mapped I/O, and I/O space of the system.
*/
namespace HW
{
/*
PCI
The Device Path for PCI defines the path to the PCI configuration space address for a PCI device.
*/
struct Pci
{
static const uint8_t TYPE = EFIDP_TYPE_HW;
static const uint8_t SUBTYPE = EFIDP_HW_PCI;
uint8_t function = {};
uint8_t device = {};
};
/*
PCCARD
PCCARD Settings.
*/
struct Pccard
{
static const uint8_t TYPE = EFIDP_TYPE_HW;
static const uint8_t SUBTYPE = EFIDP_HW_PCCARD;
uint8_t function_number = {};
};
/*
Memory Mapped
Memory Mapped Settings.
*/
struct Memory_mapped
{
enum class MEMORY_TYPE : uint32_t
{
RESERVED = 0x0,
LOADER_CODE = 0x1,
LOADER_DATA = 0x2,
BOOT_SERVICES_CODE = 0x3,
BOOT_SERVICES_DATA = 0x4,
RUNTIME_SERVICES_CODE = 0x5,
RUNTIME_SERVICES_DATA = 0x6,
CONVENTIONAL = 0x7,
UNUSABLE = 0x8,
ACPI_RECLAIM = 0x9,
ACPI_MEMORY_NVS = 0xa,
MEMORY_MAPPED_IO = 0xb,
MEMORY_MAPPD_IO_PORT_SPACE = 0xc,
PAL_CODE = 0xd,
PERSISTENT = 0xe,
UNACCEPTED = 0xf,
};
static const uint8_t TYPE = EFIDP_TYPE_HW;
static const uint8_t SUBTYPE = EFIDP_HW_MEMORY_MAPPED;
MEMORY_TYPE memory_type = {};
uint64_t start_address = {};
uint64_t end_address = {};
};
/*
Vendor-Defined Hardware
The Vendor Device Path allows the creation of vendor-defined Device Paths.
*/
struct Vendor
{
static const uint8_t TYPE = EFIDP_TYPE_HW;
static const uint8_t SUBTYPE = EFIDP_HW_VENDOR;
std::array guid = {};
Raw_data data = {};
};
/*
Controller
Controller settings.
*/
struct Controller
{
static const uint8_t TYPE = EFIDP_TYPE_HW;
static const uint8_t SUBTYPE = EFIDP_HW_CONTROLLER;
uint32_t controller_number = {};
};
/*
BMC
The Device Path for a Baseboard Management Controller (BMC) host interface.
*/
struct Bmc
{
enum class INTERFACE_TYPE : uint8_t
{
UNKNOWN = 0x0,
KCS = 0x1,
SMIC = 0x2,
BT = 0x3,
};
static const uint8_t TYPE = EFIDP_TYPE_HW;
static const uint8_t SUBTYPE = EFIDP_HW_BMC;
INTERFACE_TYPE interface_type = {};
uint64_t base_address = {};
};
} // namespace HW
/*
ACPI
This Device Path is used to describe devices whose enumeration is not described in an industry-standard fashion. These devices must be described using ACPI AML in the ACPI name space; this Device Path is a linkage to the ACPI name space.
*/
namespace ACPI
{
/*
ACPI
This Device Path contains ACPI Device IDs that represent a device’s Plug and Play Hardware ID and its corresponding unique persistent ID.
*/
struct Acpi
{
static const uint8_t TYPE = EFIDP_TYPE_ACPI;
static const uint8_t SUBTYPE = EFIDP_ACPI_ACPI;
uint32_t hid = {};
uint32_t uid = {};
};
/*
Expanded
This Device Path contains ACPI Device IDs that represent a device’s Plug and Play Hardware ID and its corresponding unique persistent ID.
*/
struct Expanded
{
static const uint8_t TYPE = EFIDP_TYPE_ACPI;
static const uint8_t SUBTYPE = EFIDP_ACPI_EXPANDED;
uint32_t hid = {};
uint32_t uid = {};
uint32_t cid = {};
std::string hidstr = {};
std::string uidstr = {};
std::string cidstr = {};
};
/*
ADR
The ADR device path is used to contain video output device attributes to support the Graphics Output Protocol.
*/
struct Adr
{
static const uint8_t TYPE = EFIDP_TYPE_ACPI;
static const uint8_t SUBTYPE = EFIDP_ACPI_ADR;
uint32_t adr = {};
Raw_data additional_adr = {};
};
/*
NVDIMM
This device path describes an NVDIMM device using the ACPI 6.0 specification defined NFIT Device Handle as the identifier.
*/
struct Nvdimm
{
static const uint8_t TYPE = EFIDP_TYPE_ACPI;
static const uint8_t SUBTYPE = EFIDP_ACPI_NVDIMM;
uint32_t nfit_device_handle = {};
};
} // namespace ACPI
/*
Messaging
This Device Path is used to describe the connection of devices outside the resource domain of the system. This Device Path can describe physical messaging information such as a SCSI ID, or abstract information such as networking protocol IP addresses.
*/
namespace MSG
{
/*
ATAPI
ATAPI Settings.
*/
struct Atapi
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_ATAPI;
bool primary = {};
bool slave = {};
uint16_t lun = {};
};
/*
SCSI
SCSI Settings.
*/
struct Scsi
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_SCSI;
uint16_t pun = {};
uint16_t lun = {};
};
/*
Fibre Channel
Fibre Channel Settings
*/
struct Fibre_channel
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_FIBRE_CHANNEL;
uint32_t reserved = {};
uint64_t world_wide_name = {};
uint64_t lun = {};
};
/*
Firewire
Firewire Settings.
*/
struct Firewire
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_FIREWIRE;
uint32_t reserved = {};
uint64_t guid = {};
};
/*
USB
USB settings.
*/
struct Usb
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_USB;
uint8_t parent_port_number = {};
uint8_t interface_number = {};
};
/*
I2O
I2O Settings
*/
struct I2o
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_I2O;
uint32_t tid = {};
};
/*
InfiniBand
InfiniBand Settings.
*/
struct Infiniband
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_INFINIBAND;
uint32_t resource_flags = {};
std::array port_gid = {};
uint64_t ioc_guid_service_id = {};
uint64_t target_port_id = {};
uint64_t device_id = {};
};
/*
Vendor-Defined Messaging
The Vendor Device Path allows the creation of vendor-defined Device Paths.
*/
struct Vendor
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_VENDOR;
std::array guid = {};
Raw_data data = {};
};
/*
MAC Address
MAC settings.
*/
struct Mac_address
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_MAC_ADDRESS;
std::array address = {};
uint8_t if_type = {};
};
/*
IPv4
IPv4 settings.
*/
struct Ipv4
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_IPV4;
std::array local_ip_address = {};
std::array remote_ip_address = {};
uint16_t local_port = {};
uint16_t remote_port = {};
uint16_t protocol = {};
bool static_ip_address = {};
std::array gateway_ip_address = {};
std::array subnet_mask = {};
};
/*
IPv6
IPv6 settings.
*/
struct Ipv6
{
enum class IP_ADDRESS_ORIGIN : uint8_t
{
STATIC = 0x0,
STATELESS = 0x1,
STATEFUL = 0x2,
};
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_IPV6;
std::array local_ip_address = {};
std::array remote_ip_address = {};
uint16_t local_port = {};
uint16_t remote_port = {};
uint16_t protocol = {};
IP_ADDRESS_ORIGIN ip_address_origin = {};
uint8_t prefix_length = {};
std::array gateway_ip_address = {};
};
/*
UART
UART Settings.
*/
struct Uart
{
enum class PARITY : uint8_t
{
DEFAULT = 0x0,
NO = 0x1,
EVEN = 0x2,
ODD = 0x3,
MARK = 0x4,
SPACE = 0x5,
};
enum class STOP_BITS : uint8_t
{
DEFAULT = 0x0,
ONE = 0x1,
ONE_AND_HALF = 0x2,
TWO = 0x3,
};
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_UART;
uint32_t reserved = {};
uint64_t baud_rate = {};
uint8_t data_bits = {};
PARITY parity = {};
STOP_BITS stop_bits = {};
};
/*
USB Class
USB Class Settings.
*/
struct Usb_class
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_USB_CLASS;
uint16_t vendor_id = {};
uint16_t product_id = {};
uint8_t device_class = {};
uint8_t device_subclass = {};
uint8_t device_protocol = {};
};
/*
USB WWID
This device path describes a USB device using its serial number.
*/
struct Usb_wwid
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_USB_WWID;
uint16_t interface_number = {};
uint16_t device_vendor_id = {};
uint16_t device_product_id = {};
std::u16string serial_number = {};
};
/*
Device Logical Unit
Device Logical Unit Settings.
*/
struct Device_logical_unit
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_DEVICE_LOGICAL_UNIT;
uint8_t lun = {};
};
/*
SATA
SATA settings.
*/
struct Sata
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_SATA;
uint16_t hba_port_number = {};
uint16_t port_multiplier_port_number = {};
uint16_t lun = {};
};
/*
iSCSI
iSCSI Settings.
*/
struct Iscsi
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_ISCSI;
uint16_t protocol = {};
uint16_t options = {};
uint64_t lun = {};
uint16_t target_portal_group = {};
std::string target_name = {};
};
/*
VLAN
VLAN Settings.
*/
struct Vlan
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_VLAN;
uint16_t vlan_id = {};
};
/*
Fibre Channel Ex
The Fibre Channel Ex device path clarifies the definition of the Logical Unit Number field to conform with the T-10 SCSI Architecture Model 4 specification.
*/
struct Fibre_channel_ex
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_FIBRE_CHANNEL_EX;
uint32_t reserved = {};
uint64_t world_wide_name = {};
uint64_t lun = {};
};
/*
SAS Extended Messaging
The SAS Ex device path clarifies the definition of the Logical Unit Number field to conform with the T-10 SCSI Architecture Model 4 specification.
*/
struct Sas_extended_messaging
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_SAS_EXTENDED_MESSAGING;
uint64_t sas_address = {};
uint64_t lun = {};
uint16_t device_and_topology_info = {};
uint16_t relative_target_port = {};
};
/*
NVM Express NS
NVM Express Namespace Settings.
*/
struct Nvm_express_ns
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_NVM_EXPRESS_NS;
uint32_t namespace_identifier = {};
uint64_t ieee_extended_unique_identifier = {};
};
/*
URI
Refer to RFC 3986 for details on the URI contents.
*/
struct Uri
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_URI;
Raw_data uri = {};
};
/*
UFS
UFS Settings.
*/
struct Ufs
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_UFS;
uint8_t pun = {};
uint8_t lun = {};
};
/*
SD
SD Settings.
*/
struct Sd
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_SD;
uint8_t slot_number = {};
};
/*
Bluetooth
EFI Bluetooth Settings.
*/
struct Bluetooth
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_BLUETOOTH;
std::array device_address = {};
};
/*
Wi-Fi
Wi-Fi Settings.
*/
struct Wi_fi
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_WI_FI;
std::string ssid = {};
};
/*
eMMC
Embedded Multi-Media Card Settings.
*/
struct Emmc
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_EMMC;
uint8_t slot_number = {};
};
/*
BluetoothLE
EFI BluetoothLE Settings.
*/
struct Bluetoothle
{
enum class ADDRESS_TYPE : uint8_t
{
PUBLIC = 0x0,
RANDOM = 0x1,
};
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_BLUETOOTHLE;
std::array device_address = {};
ADDRESS_TYPE address_type = {};
};
/*
DNS
DNS Settings.
*/
struct Dns
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_DNS;
bool ipv6 = {};
Raw_data data = {};
};
/*
NVDIMM NS
This device path describes a bootable NVDIMM namespace that is defined by a namespace label.
*/
struct Nvdimm_ns
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_NVDIMM_NS;
std::array uuid = {};
};
/*
REST Service
REST Service Settings.
*/
struct Rest_service
{
enum class REST_SERVICE : uint8_t
{
REDFISH = 0x1,
ODATA = 0x2,
VENDOR = 0xff,
};
enum class ACCESS_MODE : uint8_t
{
IN_BAND = 0x1,
OUT_OF_BAND = 0x2,
};
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_REST_SERVICE;
REST_SERVICE rest_service = {};
ACCESS_MODE access_mode = {};
std::array guid = {};
Raw_data data = {};
};
/*
NVMe-oF NS
This device path describes a bootable NVMe over Fiber namespace that is defined by a unique Namespace and Subsystem NQN identity.
*/
struct Nvme_of_ns
{
static const uint8_t TYPE = EFIDP_TYPE_MSG;
static const uint8_t SUBTYPE = EFIDP_MSG_NVME_OF_NS;
uint8_t nidt = {};
std::array nid = {};
std::string subsystem_nqn = {};
};
} // namespace MSG
/*
Media
This Device Path is used to describe the portion of a medium that is being abstracted by a boot service. For example, a Media Device Path could define which partition on a hard drive was being used.
*/
namespace MEDIA
{
/*
Hard Drive
The Hard Drive Media Device Path is used to represent a partition on a hard drive.
*/
struct Hd
{
enum class PARTITION_FORMAT : uint8_t
{
MBR = 0x1,
GUID = 0x2,
};
enum class SIGNATURE_TYPE : uint8_t
{
NONE = 0x0,
MBR = 0x1,
GUID = 0x2,
};
static const uint8_t TYPE = EFIDP_TYPE_MEDIA;
static const uint8_t SUBTYPE = EFIDP_MEDIA_HD;
uint32_t partition_number = {};
uint64_t partition_start = {};
uint64_t partition_size = {};
std::array partition_signature = {};
PARTITION_FORMAT partition_format = {};
SIGNATURE_TYPE signature_type = {};
};
/*
CD-ROM
The CD-ROM Media Device Path is used to define a system partition that exists on a CD-ROM.
*/
struct Cd_rom
{
static const uint8_t TYPE = EFIDP_TYPE_MEDIA;
static const uint8_t SUBTYPE = EFIDP_MEDIA_CD_ROM;
uint32_t boot_entry = {};
uint64_t partition_start = {};
uint64_t partition_size = {};
};
/*
Vendor-Defined Media
The Vendor Device Path allows the creation of vendor-defined Device Paths.
*/
struct Vendor
{
static const uint8_t TYPE = EFIDP_TYPE_MEDIA;
static const uint8_t SUBTYPE = EFIDP_MEDIA_VENDOR;
std::array guid = {};
Raw_data data = {};
};
/*
File Path
File Path settings.
*/
struct File_path
{
static const uint8_t TYPE = EFIDP_TYPE_MEDIA;
static const uint8_t SUBTYPE = EFIDP_MEDIA_FILE_PATH;
std::u16string path_name = {};
};
/*
Protocol
The Media Protocol Device Path is used to denote the protocol that is being used in a device path at the location of the path specified.
*/
struct Protocol
{
static const uint8_t TYPE = EFIDP_TYPE_MEDIA;
static const uint8_t SUBTYPE = EFIDP_MEDIA_PROTOCOL;
std::array guid = {};
};
/*
Firmware File
Describes a firmware file in a firmware volume.
*/
struct Firmware_file
{
static const uint8_t TYPE = EFIDP_TYPE_MEDIA;
static const uint8_t SUBTYPE = EFIDP_MEDIA_FIRMWARE_FILE;
std::array name = {};
};
/*
Firmware Volume
Describes a firmware volume.
*/
struct Firmware_volume
{
static const uint8_t TYPE = EFIDP_TYPE_MEDIA;
static const uint8_t SUBTYPE = EFIDP_MEDIA_FIRMWARE_VOLUME;
std::array name = {};
};
/*
Relative Offset Range
This device path node specifies a range of offsets relative to the first byte available on the device.
*/
struct Relative_offset_range
{
static const uint8_t TYPE = EFIDP_TYPE_MEDIA;
static const uint8_t SUBTYPE = EFIDP_MEDIA_RELATIVE_OFFSET_RANGE;
uint32_t reserved = {};
uint64_t starting_offset = {};
uint64_t ending_offset = {};
};
/*
RAM Disk
RAM Disk Settings.
*/
struct Ram_disk
{
static const uint8_t TYPE = EFIDP_TYPE_MEDIA;
static const uint8_t SUBTYPE = EFIDP_MEDIA_RAM_DISK;
uint64_t starting_address = {};
uint64_t ending_address = {};
std::array guid = {};
uint16_t disk_instance = {};
};
} // namespace MEDIA
/*
BIOS
This Device Path is used to point to boot legacy operating systems. it is based on the BIOS Boot Specification Version 1.01.
*/
namespace BIOS
{
/*
BIOS Boot Specification
This Device Path is used to describe the booting of non-EFI-aware operating systems.
*/
struct Boot_specification
{
static const uint8_t TYPE = EFIDP_TYPE_BIOS;
static const uint8_t SUBTYPE = EFIDP_BIOS_BOOT_SPECIFICATION;
uint16_t device_type = {};
uint16_t status_flag = {};
std::string description = {};
};
} // namespace BIOS
/*
End
Depending on the Sub-Type, this Device Path node is used to indicate the end of the Device Path instance or Device Path structure.
*/
namespace END
{
/*
End This Instance
This type of node terminates one Device Path instance and denotes the start of another. This is only required when an environment variable represents multiple devices.
*/
struct Instance
{
static const uint8_t TYPE = EFIDP_TYPE_END;
static const uint8_t SUBTYPE = EFIDP_END_INSTANCE;
};
/*
End Entire
This type of node terminates an entire Device Path. Software searches for this sub-type to find the end of a Device Path. All Device Paths must end with this sub-type.
*/
struct Entire
{
static const uint8_t TYPE = EFIDP_TYPE_END;
static const uint8_t SUBTYPE = EFIDP_END_ENTIRE;
};
} // namespace END
struct Unknown
{
Raw_data data = {};
uint8_t TYPE = {};
uint8_t SUBTYPE = {};
};
using ANY = std::variant<
HW::Pci,
HW::Pccard,
HW::Memory_mapped,
HW::Vendor,
HW::Controller,
HW::Bmc,
ACPI::Acpi,
ACPI::Expanded,
ACPI::Adr,
ACPI::Nvdimm,
MSG::Atapi,
MSG::Scsi,
MSG::Fibre_channel,
MSG::Firewire,
MSG::Usb,
MSG::I2o,
MSG::Infiniband,
MSG::Vendor,
MSG::Mac_address,
MSG::Ipv4,
MSG::Ipv6,
MSG::Uart,
MSG::Usb_class,
MSG::Usb_wwid,
MSG::Device_logical_unit,
MSG::Sata,
MSG::Iscsi,
MSG::Vlan,
MSG::Fibre_channel_ex,
MSG::Sas_extended_messaging,
MSG::Nvm_express_ns,
MSG::Uri,
MSG::Ufs,
MSG::Sd,
MSG::Bluetooth,
MSG::Wi_fi,
MSG::Emmc,
MSG::Bluetoothle,
MSG::Dns,
MSG::Nvdimm_ns,
MSG::Rest_service,
MSG::Nvme_of_ns,
MEDIA::Hd,
MEDIA::Cd_rom,
MEDIA::Vendor,
MEDIA::File_path,
MEDIA::Protocol,
MEDIA::Firmware_file,
MEDIA::Firmware_volume,
MEDIA::Relative_offset_range,
MEDIA::Ram_disk,
BIOS::Boot_specification,
END::Instance,
END::Entire,
Unknown>;
} // namespace File_path
enum class Load_option_attribute : uint32_t
{
EMPTY = 0x00000000,
ACTIVE = 0x00000001,
FORCE_RECONNECT = 0x00000002,
HIDDEN = 0x00000008,
CATEGORY_MASK = 0x00001F00,
CATEGORY_BOOT = 0x00000000,
CATEGORY_APP = 0x00000100,
};
inline Load_option_attribute operator|(Load_option_attribute a, Load_option_attribute b)
{
return static_cast(static_cast>(a) | static_cast>(b));
}
inline Load_option_attribute operator&(Load_option_attribute a, Load_option_attribute b)
{
return static_cast(static_cast>(a) & static_cast>(b));
}
struct Load_option
{
std::u16string description = u"";
std::vector device_path = {};
Raw_data optional_data = {};
Load_option_attribute attributes = Load_option_attribute::EMPTY;
};
struct Key_option
{
efi_boot_key_data key_data = {};
uint16_t boot_option = 0u;
uint32_t boot_option_crc = 9u;
std::vector keys = {};
Raw_data vendor_data = {};
};
using Progress_fn = std::function;
template
using Variable = std::tuple;
std::optional init();
template
std::optional> deserialize_list(const void *data, size_t data_size);
template
std::optional> deserialize_list_ex(const void *data, size_t data_size, const Size_fn &get_element_size, const Advance_fn &get_next_element);
template
size_t serialize(Raw_data &output, const Type &value);
template
size_t serialize_list(Raw_data &output, const std::vector &value);
template
std::optional> get_variables(const Filter_fn &filter, const Progress_fn &progress);
template
std::optional> get_variables(const Filter_fn &filter);
std::optional> get_variables();
template
std::optional> get_variable(const efi_guid_t &guid, const tstring &name);
template
std::optional>> get_list_variable(const efi_guid_t &guid, const tstring &name);
template
std::optional>> get_list_variable_ex(const efi_guid_t &guid, const tstring &name, const Size_fn &get_element_size, const Advance_fn &get_next_element);
template
bool set_variable_ex(const efi_guid_t &guid, const tstring &name, const Variable &variable, mode_t mode, uint32_t &crc);
template
bool set_variable(const efi_guid_t &guid, const tstring &name, const Variable &variable, mode_t mode);
template
bool set_list_variable(const efi_guid_t &guid, const tstring &name, const Variable> &variable, mode_t mode);
inline std::optional init()
{
if(!efi_variables_supported())
return {_T("UEFI variables not supported on this machine.")};
return std::nullopt;
}
template
inline std::optional deserialize(const void *data, size_t data_size)
{
if(data_size != sizeof(Type))
return std::nullopt;
return {*static_cast(data)};
}
template