From 90a968438d6a2141d4a8749d0e34b3cf9e1575b3 Mon Sep 17 00:00:00 2001 From: Maciej Szeptuch <765629+Neverous@users.noreply.github.com> Date: Sun, 27 Aug 2023 21:10:44 +0200 Subject: [PATCH] Address some previously silenced compiler warnings (#99) --- .github/workflows/build.yml | 2 +- .gitignore | 2 +- CMakeLists.txt | 165 ++++++++------- include/bootentry.h | 106 ++++------ include/bootentrylistmodel.h | 4 +- include/commands.h | 349 ++++---------------------------- include/compat.h | 44 +++- include/driveinfo.h | 14 +- include/efiboot.h | 121 +++++------ include/efibootdata.h | 27 +-- include/efivar-lite/efivar-dp.h | 13 +- include/efivar-lite/efivar.h | 7 +- include/filepathdialog.h | 40 +--- src/bootentry.cpp | 27 ++- src/commands.cpp | 331 ++++++++++++++++++++++++++++++ src/driveinfo.darwin.cpp | 12 +- src/driveinfo.win32.cpp | 19 +- src/efibooteditor.cpp | 1 - src/efivar-lite.c | 8 +- src/efivar-lite.common.h | 8 +- src/efivar-lite.darwin.c | 2 +- src/efivar-lite.win32.c | 2 +- src/filepathdialog.cpp | 29 +++ 23 files changed, 687 insertions(+), 646 deletions(-) create mode 100644 src/commands.cpp diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 33312a26..c9ae1e7a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -133,7 +133,7 @@ jobs: continue-on-error: true - name: Perform MSVC Code Analysis - uses: microsoft/msvc-code-analysis-action@v0.1.1 + uses: microsoft/msvc-code-analysis-action@96315324a485db21449515180214ecb78c16a1c5 id: msvc-analysis with: cmakeBuildDirectory: ${{ github.workspace }}/build diff --git a/.gitignore b/.gitignore index 4fbe562b..1121cb6b 100644 --- a/.gitignore +++ b/.gitignore @@ -50,7 +50,7 @@ Thumbs.db *.sln *.suo *.vcproj -*.user +*.user* *.ncb *.sdf *.opensdf diff --git a/CMakeLists.txt b/CMakeLists.txt index 42ff3f54..fa4c56c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,88 +114,6 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE QT_DISABLE_DEPRECATED_BEFORE=0xFFFFFF ) -# GCC -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - target_compile_options(${PROJECT_NAME} PRIVATE - -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) - - # Disable compatibility warnings - target_compile_options(${PROJECT_NAME} PRIVATE - -Wno-c++20-compat - -Wno-c++98-compat - -Wno-c++98-compat-pedantic - -Wno-cast-qual - -Wno-declaration-after-statement - -Wno-deprecated-dynamic-exception-spec - -Wno-exit-time-destructors - -Wno-extra-semi-stmt - -Wno-global-constructors - -Wno-old-style-cast - -Wno-redundant-parens - -Wno-reserved-identifier - -Wno-return-std-move-in-c++11 - -Wno-unknown-warning-option - -Wno-zero-as-null-pointer-constant - ) - else() # Standard - target_compile_options(${PROJECT_NAME} PRIVATE - -Wall -Wpedantic -Werror -pedantic -Wshadow -Wextra -Wconversion $<$:-Weffc++> - ) - endif() -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} PRIVATE - # Ignore warnings in external includes - /experimental:external - ) -endif() - -if(WIN32) - target_compile_options(${PROJECT_NAME} PRIVATE - $<$:/std:c++latest> - # Ignore warnings in external includes - /external:anglebrackets /external:W0 - # Enable all warnings in application code - /Wall /permissive- /WX - # Disable some warnings - # C4371: 'classname': layout of class may have changed from a previous version of the compiler due to better packing of member 'member' - /wd4371 - # C4464: relative include path contains '.. - /wd4464 - # C4702: unreachable code - /wd4702 - # C4710: 'function' : function not inlined - /wd4710 - # C4711: function 'function' selected for inline expansion - /wd4711 - # 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 - # C5045: Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified - /wd5045 - # C5262: implicit fall-through occurs here; are you missing a break statement? Use [[fallthrough]] when a break statement is intentionally omitted between cases // supposedly fixed in VS 2022 17.5 Preview 2 - https://developercommunity.visualstudio.com/t/10163250#T-N10180326 - /wd5262 - # C5264: 'variable-name': 'const' variable is not used - /wd5264 - ) -endif() - # Sources: target_sources(${PROJECT_NAME} PRIVATE src/bootentry.cpp @@ -204,6 +122,7 @@ target_sources(${PROJECT_NAME} PRIVATE src/bootentrylistmodel.cpp src/bootentrylistview.cpp src/bootentrywidget.cpp + src/commands.cpp src/devicepathproxymodel.cpp src/devicepathview.cpp src/driveinfo.cpp @@ -227,7 +146,6 @@ if(WIN32) src/efivar-lite.c src/efivar-lite.common.h src/efivar-lite.win32.c - windows.rc ) endif() @@ -269,6 +187,79 @@ target_sources(${PROJECT_NAME} PRIVATE include/qwidgetitemdelegate.h ) +# Compile options +get_target_property(SOURCES ${PROJECT_NAME} 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} PRIVATE + -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-unknown-warning-option + -Wno-unsafe-buffer-usage + ) +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} PRIVATE + # Ignore warnings in external includes + /experimental:external + ) +endif() + +if(WIN32) + target_compile_options(${PROJECT_NAME} PRIVATE + $<$:/std:c++latest> + # Ignore warnings in external includes + /external:anglebrackets /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} PRIVATE + # C4371: 'classname': layout of class may have changed from a previous version of the compiler due to better packing of member 'member' + /wd4371 + # 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} PRIVATE src/form/bootentryform.ui @@ -281,6 +272,12 @@ target_sources(${PROJECT_NAME} PRIVATE 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 @@ -291,6 +288,7 @@ qt_add_translations(${PROJECT_NAME} INCLUDE_DIRECTORIES "include" LUPDATE_OPTIONS "-no-obsolete") +# Libraries if(APPLE) target_link_libraries(${PROJECT_NAME} PRIVATE "-framework CoreFoundation" @@ -315,6 +313,7 @@ if(("${CMAKE_BUILD_TYPE}" STREQUAL "Release") AND UNIX) set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_RELEASE -s) endif() +# Packaging if(WIN32) install(TARGETS ${PROJECT_NAME} RUNTIME diff --git a/include/bootentry.h b/include/bootentry.h index b8832bc9..e162dc60 100644 --- a/include/bootentry.h +++ b/include/bootentry.h @@ -13,16 +13,6 @@ namespace File_path { -template -inline bool registerJSONReader(); -#define REGISTER_JSON_READER(type) static const bool is_##type##_json_reader_registered = registerJSONReader() - -#if defined(_MSC_VER) -#pragma warning(push) -// C4820: 'bytes' bytes padding added after construct 'member_name' -#pragma warning(disable : 4820) -#endif - class PCI { public: @@ -46,7 +36,6 @@ class PCI QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(PCI); class HID { @@ -71,7 +60,6 @@ class HID QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(HID); class USB { @@ -96,7 +84,6 @@ class USB QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(USB); class Vendor { @@ -108,9 +95,9 @@ class Vendor mutable QString string = ""; public: - uint8_t _type = 0; - QUuid guid = {}; QByteArray data = {}; + QUuid guid = {}; + uint8_t _type = 0; public: Vendor() = default; @@ -124,7 +111,6 @@ class Vendor QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(Vendor); class MACAddress { @@ -149,7 +135,6 @@ class MACAddress QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(MACAddress); class IPv4 { @@ -163,12 +148,12 @@ class IPv4 public: QHostAddress local_ip_address = {}; QHostAddress remote_ip_address = {}; + QHostAddress gateway_ip_address = {}; + QHostAddress subnet_mask = {}; uint16_t local_port = 0; uint16_t remote_port = 0; uint16_t protocol = 0; bool static_ip_address = false; - QHostAddress gateway_ip_address = {}; - QHostAddress subnet_mask = {}; public: IPv4() = default; @@ -180,7 +165,6 @@ class IPv4 QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(IPv4); class IPv6 { @@ -211,7 +195,6 @@ class IPv6 QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(IPv6); class SATA { @@ -237,7 +220,6 @@ class SATA QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(SATA); class HD { @@ -266,7 +248,6 @@ class HD QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(HD); class File { @@ -290,7 +271,6 @@ class File QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(File); class FirmwareFile { @@ -314,7 +294,6 @@ class FirmwareFile QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(FirmwareFile); class FirmwareVolume { @@ -338,7 +317,6 @@ class FirmwareVolume QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(FirmwareVolume); class BIOSBootSpecification { @@ -346,13 +324,13 @@ class BIOSBootSpecification static constexpr auto TYPE = "BIOS"; static constexpr auto SUBTYPE = "BIOS_BOOT_SPECIFICATION"; +private: + mutable QString string = ""; + public: + QString description = ""; uint16_t device_type = 0; uint16_t status_flag = 0; - QString description = ""; - -private: - mutable QString string = ""; public: BIOSBootSpecification() = default; @@ -364,7 +342,6 @@ class BIOSBootSpecification QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(BIOSBootSpecification); class End { @@ -409,7 +386,6 @@ class End QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(End); class Unknown { @@ -421,9 +397,9 @@ class Unknown mutable QString string = ""; public: + QByteArray data = {}; uint8_t _type = 0; uint8_t _subtype = 0; - QByteArray data = {}; public: Unknown() = default; @@ -435,7 +411,6 @@ class Unknown QString toString(bool refresh = true) const; }; -REGISTER_JSON_READER(Unknown); typedef std::variant< PCI, @@ -455,35 +430,42 @@ typedef std::variant< Unknown> ANY; -extern std::unique_ptr(const QJsonObject &)>>> JSON_readers__instance; - -inline auto &JSON_readers() -{ - if(!JSON_readers__instance) - JSON_readers__instance = std::make_unique(); - - return *JSON_readers__instance; -} - -template -inline bool registerJSONReader() +inline std::unordered_map(const QJsonObject &)>> JSON_readers() { - auto key = QString("%1/%2").arg(Type::TYPE).arg(Type::SUBTYPE); - if(JSON_readers().find(key) != JSON_readers().end()) - return true; - - JSON_readers()[key] = [](const auto &obj) -> std::optional - { return Type::fromJSON(obj); }; - return true; +#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(HID), + reader(USB), + reader(Vendor), + reader(MACAddress), + reader(IPv4), + reader(IPv6), + reader(SATA), + reader(HD), + reader(File), + reader(FirmwareFile), + reader(FirmwareVolume), + reader(BIOSBootSpecification), + reader(End), + reader(Unknown), + }; +#undef reader } -#undef REGISTER_JSON_READER } // namespace File_path Q_DECLARE_METATYPE(const File_path::ANY *) class BootEntry { +private: + mutable QString device_path_str = ""; + public: enum class OptionalDataFormat : uint8_t { @@ -493,22 +475,18 @@ class BootEntry Hex = 3, }; - uint16_t index = 0; - QString description = "New entry"; QVector device_path = {}; + QString description = "New entry"; + QString error = ""; QString optional_data = ""; uint32_t attributes = EFIBoot::Load_option_attribute::EMPTY; uint32_t efi_attributes = EFIBoot::EFI_VARIABLE_ATTRIBUTE_DEFAULTS; + uint16_t index = 0; + OptionalDataFormat optional_data_format = OptionalDataFormat::Base64; bool is_current_boot = false; bool is_next_boot = false; bool is_error = false; - QString error = ""; - - OptionalDataFormat optional_data_format = OptionalDataFormat::Base64; - -private: - mutable QString device_path_str = ""; public: static BootEntry fromEFIBootLoadOption(const EFIBoot::Load_option &load_option); @@ -527,8 +505,4 @@ class BootEntry QByteArray getRawOptionalData() const; }; -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - Q_DECLARE_METATYPE(const BootEntry *) diff --git a/include/bootentrylistmodel.h b/include/bootentrylistmodel.h index eac70428..0b16d9a6 100644 --- a/include/bootentrylistmodel.h +++ b/include/bootentrylistmodel.h @@ -37,13 +37,15 @@ class BootEntryListModel: public QAbstractListModel Q_DECLARE_FLAGS(Options, Option) const QString name; - const Options options; 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; diff --git a/include/commands.h b/include/commands.h index 4f84301d..30b02ff8 100644 --- a/include/commands.h +++ b/include/commands.h @@ -73,80 +73,40 @@ class InsertRemoveBootEntryCommand: public QUndoCommand protected: BootEntryListModel &model; QModelIndex index_parent; - int index; BootEntry entry; + int index; public: - InsertRemoveBootEntryCommand(BootEntryListModel &model_, const QString &description, const QModelIndex &index_parent_, int index_, const BootEntry &entry_, QUndoCommand *parent = nullptr) - : QUndoCommand(description, parent) - , model{model_} - , index_parent{index_parent_} - , index{index_} - , entry{entry_} - { - } - + 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: - void insert() - { - model.beginInsertRows(index_parent, index, index); - model.entries.insert(index, entry); - model.endInsertRows(); - } - - void remove() - { - model.beginRemoveRows(index_parent, index, index); - model.entries.removeAt(index); - model.endRemoveRows(); - } + 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) - : InsertRemoveBootEntryCommand(model_, QObject::tr("Insert %1 entry \"%2\" at position %3").arg(model_.name, entry_.getTitle()).arg(index_), index_parent_, index_, entry_, parent) - { - } - + 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 - { - remove(); - } - - void redo() override - { - insert(); - } + void undo() override; + void redo() override; }; class RemoveBootEntryCommand: public InsertRemoveBootEntryCommand { public: - RemoveBootEntryCommand(BootEntryListModel &model_, const QModelIndex &index_parent_, int index_, QUndoCommand *parent = nullptr) - : InsertRemoveBootEntryCommand(model_, QObject::tr("Removing %1 entry \"%2\" from position %3").arg(model_.name, model_.entries.at(index_).getTitle()).arg(index_), index_parent_, index_, model_.entries.at(index_), parent) - { - } - + RemoveBootEntryCommand(BootEntryListModel &model_, const QModelIndex &index_parent_, int index_, QUndoCommand *parent = nullptr); RemoveBootEntryCommand(const RemoveBootEntryCommand &) = delete; RemoveBootEntryCommand &operator=(const RemoveBootEntryCommand &) = delete; - void undo() override - { - insert(); - } - - void redo() override - { - remove(); - } + void undo() override; + void redo() override; }; class MoveBootEntryCommand: public QUndoCommand @@ -159,63 +119,14 @@ class MoveBootEntryCommand: public QUndoCommand int destination_index; public: - MoveBootEntryCommand(BootEntryListModel &model_, const QModelIndex &source_parent_, int source_index_, const QModelIndex &destination_parent_, int destination_index_, QUndoCommand *parent = nullptr) - : QUndoCommand("", parent) - , model{model_} - , title{model_.entries.at(source_index_).getTitle()} - , source_parent{source_parent_} - , destination_parent{destination_parent_} - , source_index{source_index_} - , destination_index{destination_index_} - { - setText(QObject::tr("Move %1 entry \"%2\" from position %3 to %4").arg(model.name, title).arg(source_index).arg(destination_index)); - } - + 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 - { - return 2; - } - - void undo() override - { - model.beginMoveRows(destination_parent, destination_index, destination_index + 1, source_parent, source_index); - model.entries.move(destination_index, source_index); - model.endMoveRows(); - } - - void redo() override - { - model.beginMoveRows(source_parent, source_index, source_index + 1, destination_parent, destination_index); - model.entries.move(source_index, destination_index); - model.endMoveRows(); - } - - bool mergeWith(const QUndoCommand *command) override - { - if(command->id() != id()) - return false; - - auto cmd = static_cast(command); - if(&cmd->model != &model) - return false; - - if(cmd->source_parent != destination_parent) - return false; - - if(cmd->source_index != destination_index) - return false; - - destination_parent = cmd->destination_parent; - destination_index = cmd->destination_index; - setText(QObject::tr("Move %1 entry \"%2\" from position %3 to %4").arg(model.name, title).arg(source_index).arg(destination_index)); - if(source_index == destination_index) - setObsolete(true); - - return true; - } + int id() const override; + void undo() override; + void redo() override; + bool mergeWith(const QUndoCommand *command) override; }; template @@ -294,162 +205,56 @@ class ChangeOptionalDataFormatCommand: public QUndoCommand BootEntry::OptionalDataFormat value; public: - ChangeOptionalDataFormatCommand(BootEntryListModel &model_, const QModelIndex &index_, const BootEntry::OptionalDataFormat &value_, QUndoCommand *parent = nullptr) - : QUndoCommand{"", parent} - , model{model_} - , title{model_.entries.at(index_.row()).getTitle()} - , index{index_} - , value{value_} - { - updateTitle(value); - } - + 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 - { - return 4; - } - - void undo() override - { - redo(); - } - - void redo() override - { - auto &entry = model.entries[index.row()]; - auto old_value = entry.optional_data_format; - entry.changeOptionalDataFormat(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; - - const auto &entry = model.entries.at(index.row()); - if(value == entry.optional_data_format) - setObsolete(true); - - updateTitle(entry.optional_data_format); - return true; - } - - void updateTitle(BootEntry::OptionalDataFormat val) - { - QString format{}; - switch(val) - { - case BootEntry::OptionalDataFormat::Base64: - format = "Base64"; - break; - - case BootEntry::OptionalDataFormat::Hex: - format = "Hex"; - break; - - case BootEntry::OptionalDataFormat::Utf16: - format = "UTF-16"; - break; - - case BootEntry::OptionalDataFormat::Utf8: - format = "UTF-8"; - break; - } - - setText(QObject::tr("Change %1 entry \"%2\" %3 to \"%4\"").arg(model.name, title, QObject::tr("Optional data"), format)); - } + 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 { protected: BootEntryListModel &model; + File_path::ANY file_path; const QModelIndex index; int row; - File_path::ANY file_path; public: - InsertRemoveBootEntryFilePathCommand(BootEntryListModel &model_, const QString &description, const QModelIndex &index_, int row_, const File_path::ANY &file_path_, QUndoCommand *parent = nullptr) - : QUndoCommand(description, parent) - , model{model_} - , index{index_} - , row{row_} - , file_path{file_path_} - { - } - + InsertRemoveBootEntryFilePathCommand(BootEntryListModel &model_, const QString &description, const QModelIndex &index_, int row_, const File_path::ANY &file_path_, QUndoCommand *parent = nullptr); InsertRemoveBootEntryFilePathCommand(const InsertRemoveBootEntryFilePathCommand &) = delete; InsertRemoveBootEntryFilePathCommand &operator=(const InsertRemoveBootEntryFilePathCommand &) = delete; protected: - void insert() - { - auto &entry = model.entries[index.row()]; - entry.device_path.insert(row, file_path); - entry.formatDevicePath(); - emit model.dataChanged(index, index, {Qt::EditRole}); - } - - void remove() - { - auto &entry = model.entries[index.row()]; - entry.device_path.removeAt(row); - entry.formatDevicePath(); - emit model.dataChanged(index, index, {Qt::EditRole}); - } + int id() const override; + void insert(); + void remove(); }; class InsertBootEntryFilePathCommand: public InsertRemoveBootEntryFilePathCommand { public: - InsertBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int row_, const File_path::ANY &file_path_, QUndoCommand *parent = nullptr) - : InsertRemoveBootEntryFilePathCommand(model_, QObject::tr("Insert %1 entry \"%2\" file path at position %3").arg(model_.name, model_.entries.at(index_.row()).getTitle()).arg(row_), index_, row_, file_path_, parent) - { - } - + InsertBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int row_, const File_path::ANY &file_path_, QUndoCommand *parent = nullptr); InsertBootEntryFilePathCommand(const InsertBootEntryFilePathCommand &) = delete; InsertBootEntryFilePathCommand &operator=(const InsertBootEntryFilePathCommand &) = delete; - void undo() override - { - remove(); - } - - void redo() override - { - insert(); - } + void undo() override; + void redo() override; }; class RemoveBootEntryFilePathCommand: public InsertRemoveBootEntryFilePathCommand { public: - RemoveBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int row_, QUndoCommand *parent = nullptr) - : InsertRemoveBootEntryFilePathCommand(model_, QObject::tr("Removing %1 entry \"%2\" file path from position %3").arg(model_.name, model_.entries.at(index_.row()).getTitle()).arg(row_), index_, row_, model_.entries.at(index_.row()).device_path.at(row_), parent) - { - } - + RemoveBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int row_, QUndoCommand *parent = nullptr); RemoveBootEntryFilePathCommand(const RemoveBootEntryFilePathCommand &) = delete; RemoveBootEntryFilePathCommand &operator=(const RemoveBootEntryFilePathCommand &) = delete; - void undo() override - { - insert(); - } - - void redo() override - { - remove(); - } + void undo() override; + void redo() override; }; class SetBootEntryFilePathCommand: public QUndoCommand @@ -457,36 +262,17 @@ class SetBootEntryFilePathCommand: public QUndoCommand protected: BootEntryListModel &model; QModelIndex index; - int row; File_path::ANY value; + int row; public: - SetBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int row_, const File_path::ANY &value_, QUndoCommand *parent = nullptr) - : QUndoCommand(QObject::tr("Setting %1 entry \"%2\" file path at position %3").arg(model_.name, model_.entries.at(index_.row()).getTitle()).arg(row_), parent) - , model{model_} - , index{index_} - , row{row_} - , value{value_} - { - } - + SetBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int row_, const File_path::ANY &value_, QUndoCommand *parent = nullptr); SetBootEntryFilePathCommand(const SetBootEntryFilePathCommand &) = delete; SetBootEntryFilePathCommand &operator=(const SetBootEntryFilePathCommand &) = delete; - void undo() override - { - redo(); - } - - void redo() override - { - auto &entry = model.entries[index.row()]; - auto old_value = entry.device_path[row]; - entry.device_path[row] = value; - value = old_value; - entry.formatDevicePath(); - emit model.dataChanged(index, index, {Qt::EditRole}); - } + int id() const override; + void undo() override; + void redo() override; }; class MoveBootEntryFilePathCommand: public QUndoCommand @@ -498,61 +284,12 @@ class MoveBootEntryFilePathCommand: public QUndoCommand int destination_row; public: - MoveBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int source_row_, int destination_row_, QUndoCommand *parent = nullptr) - : QUndoCommand("", parent) - , model{model_} - , title{model_.entries.at(index_.row()).getTitle()} - , index{index_} - , source_row{source_row_} - , destination_row{destination_row_} - { - setText(QObject::tr("Move %1 entry \"%2\" file path from position %3 to %4").arg(model.name, title).arg(source_row).arg(destination_row)); - } - + 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 - { - return 5; - } - - void undo() override - { - auto &entry = model.entries[index.row()]; - entry.device_path.move(destination_row, source_row); - entry.formatDevicePath(); - emit model.dataChanged(index, index, {Qt::EditRole}); - } - - void redo() override - { - auto &entry = model.entries[index.row()]; - entry.device_path.move(source_row, destination_row); - entry.formatDevicePath(); - emit model.dataChanged(index, index, {Qt::EditRole}); - } - - bool mergeWith(const QUndoCommand *command) override - { - if(command->id() != id()) - return false; - - auto cmd = static_cast(command); - if(&cmd->model != &model) - return false; - - if(cmd->index != index) - return false; - - if(cmd->source_row != destination_row) - return false; - - destination_row = cmd->destination_row; - setText(QObject::tr("Move %1 entry \"%2\" file path from position %3 to %4").arg(model.name, title).arg(source_row).arg(destination_row)); - if(source_row == destination_row) - setObsolete(true); - - return true; - } + int id() const override; + void undo() override; + void redo() override; + bool mergeWith(const QUndoCommand *command) override; }; diff --git a/include/compat.h b/include/compat.h index 14615b9b..05a58c29 100644 --- a/include/compat.h +++ b/include/compat.h @@ -2,6 +2,19 @@ #pragma once #include +#include +#include + +/* casts */ +#if defined(__cplusplus) +#define STATIC_CAST(type) static_cast +#if defined(NULL) +#undef NULL +#endif +#define NULL nullptr +#else +#define STATIC_CAST(type) (type) +#endif /* attributes */ #if defined(__GNUC__) && !defined(__clang__) @@ -10,6 +23,7 @@ #define ATTR_ARTIFICIAL #endif +/* MSVC compatibility */ #if defined(_MSC_VER) #include #define ATTR_ALIGN(X) __declspec(align(X)) @@ -28,9 +42,9 @@ typedef SSIZE_T ssize_t; #define ATTR_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) #endif -#ifdef _WIN32 +/* Windows compatibility */ +#if defined(_WIN32) #include -#include #include #include #undef interface @@ -41,20 +55,29 @@ typedef uint32_t mode_t; #include #include typedef char TCHAR; +#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 inline int _tcserror_s(TCHAR *buffer, size_t size, int errnum) { -#if defined(__APPLE__) || ((_POSIX_C_SOURCE >= 200112L) && !_GNU_SOURCE) +#if defined(__APPLE__) || ((_POSIX_C_SOURCE >= 200112L) && !defined(_GNU_SOURCE)) return strerror_r(errnum, buffer, size); #else return strerror_r(errnum, buffer, size) == NULL; #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 -#ifdef __cplusplus +#if defined(__cplusplus) #include #include #include @@ -68,6 +91,7 @@ inline int _tcserror_s(TCHAR *buffer, size_t size, int errnum) #include #endif +/* string types */ namespace std { typedef basic_string tstring; @@ -127,6 +151,7 @@ inline QString QStringFromStdTString(const std::tstring &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(); @@ -179,5 +204,16 @@ inline QByteArray fromUnicode(const QString &input, const char *codec_name = "UT return encoder->fromUnicode(input); #endif } +#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 diff --git a/include/driveinfo.h b/include/driveinfo.h index 09d063f8..0e8aff15 100644 --- a/include/driveinfo.h +++ b/include/driveinfo.h @@ -5,12 +5,6 @@ #include #include -#if defined(_MSC_VER) -#pragma warning(push) -// C4820: 'bytes' bytes padding added after construct 'member_name' -#pragma warning(disable : 4820) -#endif - class DriveInfo { static QVector all; @@ -25,11 +19,11 @@ class DriveInfo public: QString name = ""; - uint32_t partition = 0; - SIGNATURE signature_type = SIGNATURE::NONE; 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); @@ -37,8 +31,4 @@ class DriveInfo bool operator<(const DriveInfo &info) const { return name < info.name; } }; -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - Q_DECLARE_METATYPE(DriveInfo) diff --git a/include/efiboot.h b/include/efiboot.h index 0e85f803..a14446d4 100644 --- a/include/efiboot.h +++ b/include/efiboot.h @@ -39,16 +39,6 @@ std::optional deserialize(const void *data, size_t data_size); namespace File_path { -template -inline bool register_deserializer(); -#define REGISTER_DESERIALIZER(type) static const bool is_##type##_deserializer_registered = register_deserializer() - -#if defined(_MSC_VER) -#pragma warning(push) -// C4820: 'bytes' bytes padding added after construct 'member_name' -#pragma warning(disable : 4820) -#endif - enum TYPE { HW = EFIDP_TYPE_HW, @@ -67,7 +57,6 @@ struct PCI uint8_t function = 0; uint8_t device = 0; }; -REGISTER_DESERIALIZER(PCI); struct HWVendor { @@ -77,7 +66,6 @@ struct HWVendor std::array guid = {}; Raw_data data = {}; }; -REGISTER_DESERIALIZER(HWVendor); struct HID { @@ -87,7 +75,6 @@ struct HID uint32_t hid = 0; uint32_t uid = 0; }; -REGISTER_DESERIALIZER(HID); struct USB { @@ -97,7 +84,6 @@ struct USB uint8_t parent_port_number = 0; uint8_t interface = 0; }; -REGISTER_DESERIALIZER(USB); struct MSGVendor { @@ -107,7 +93,6 @@ struct MSGVendor std::array guid = {}; Raw_data data = {}; }; -REGISTER_DESERIALIZER(MSGVendor); struct MAC_address { @@ -117,7 +102,6 @@ struct MAC_address std::array address = {}; uint8_t if_type = 0; }; -REGISTER_DESERIALIZER(MAC_address); struct IPv4 { @@ -133,7 +117,6 @@ struct IPv4 std::array gateway_ip_address = {}; std::array subnet_mask = {}; }; -REGISTER_DESERIALIZER(IPv4); struct IPv6 { @@ -149,7 +132,6 @@ struct IPv6 uint8_t prefix_length = 0; std::array gateway_ip_address = {}; }; -REGISTER_DESERIALIZER(IPv6); struct SATA { @@ -160,7 +142,6 @@ struct SATA uint16_t port_multiplier_port = 0; uint16_t lun = 0; }; -REGISTER_DESERIALIZER(SATA); enum SIGNATURE { @@ -181,7 +162,6 @@ struct HD std::array partition_signature = {}; uint8_t signature_type = 0; }; -REGISTER_DESERIALIZER(HD); struct MEDIAVendor { @@ -191,7 +171,6 @@ struct MEDIAVendor std::array guid = {}; Raw_data data = {}; }; -REGISTER_DESERIALIZER(MEDIAVendor); struct File { @@ -200,7 +179,6 @@ struct File std::u16string name = u""; }; -REGISTER_DESERIALIZER(File); struct Firmware_file { @@ -209,7 +187,6 @@ struct Firmware_file std::array name = {}; }; -REGISTER_DESERIALIZER(Firmware_file); struct Firmware_volume { @@ -218,38 +195,34 @@ struct Firmware_volume std::array name = {}; }; -REGISTER_DESERIALIZER(Firmware_volume); struct BIOS_boot_specification { static const uint8_t TYPE = BIOS; static const uint8_t SUBTYPE = EFIDP_BIOS_BOOT_SPECIFICATION; + std::string description = ""; uint16_t device_type = 0; uint16_t status_flag = 0; - std::string description = ""; }; -REGISTER_DESERIALIZER(BIOS_boot_specification); struct End_instance { static const uint8_t TYPE = END; static const uint8_t SUBTYPE = EFIDP_END_INSTANCE; }; -REGISTER_DESERIALIZER(End_instance); struct End_entire { static const uint8_t TYPE = END; static const uint8_t SUBTYPE = EFIDP_END_ENTIRE; }; -REGISTER_DESERIALIZER(End_entire); struct Unknown { + Raw_data data = {}; uint8_t TYPE = 0; uint8_t SUBTYPE = 0; - Raw_data data = {}; }; typedef std::variant< @@ -273,32 +246,6 @@ typedef std::variant< Unknown> ANY; -extern std::unique_ptr(const void *, size_t)>>> deserializers__instance; - -inline auto &deserializers() -{ - if(!deserializers__instance) - deserializers__instance = std::make_unique(); - - return *deserializers__instance; -} - -template -inline bool register_deserializer() -{ - efidp_data dp; - dp.header.type = Type::TYPE; - dp.header.subtype = Type::SUBTYPE; - - if(deserializers().find(dp._type_subtype) != deserializers().end()) - return true; - - deserializers()[dp._type_subtype] = [](const void *data, size_t data_size) -> std::optional - { return deserialize(data, data_size); }; - return true; -} - -#undef REGISTER_DESERIALIZER } // namespace File_path enum Load_option_attribute @@ -322,10 +269,6 @@ struct Load_option uint32_t attributes = Load_option_attribute::EMPTY; }; -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - typedef std::function Filter_fn; typedef std::function Advance_fn; typedef std::function Size_fn; @@ -396,8 +339,7 @@ inline size_t serialize(Raw_data &output, const Type &value) template <> inline std::optional deserialize(const void *data, size_t data_size) { - const uint8_t *ptr = static_cast(data); - return {Raw_data{ptr, ptr + data_size}}; + return {Raw_data{static_cast(data), static_cast(advance_bytes(data, data_size))}}; } template <> @@ -468,7 +410,7 @@ template inline std::optional> deserialize_list_ex(const void *data, size_t data_size, Size_fn get_element_size, Advance_fn get_next_element) { std::vector values; - const void *data_end = static_cast(static_cast(data) + data_size); + const void *data_end = advance_bytes(data, data_size); while(data && data < data_end) { auto element_size = get_element_size(data); @@ -479,7 +421,7 @@ inline std::optional> deserialize_list_ex(const void *data, si values.push_back(*value); data = get_next_element(data, data_size); auto bytes_left = static_cast(data_end) - static_cast(data); - data_size = reinterpret_cast(bytes_left); + data_size = static_cast(bytes_left); } if(data != data_end) @@ -499,7 +441,7 @@ inline std::optional> deserialize_list(const void *data, size_ }, [](const void *ptr, size_t) -> const void * { - return static_cast(static_cast(ptr) + 1); + return advance_bytes(ptr, sizeof(const Type)); }); } @@ -577,11 +519,18 @@ template <> inline std::optional deserialize(const void *data, size_t data_size) { Load_option value; - ssize_t ssize = reinterpret_cast(data_size); + ssize_t ssize = static_cast(data_size); efi_load_option *load_option = const_cast(static_cast(data)); +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" +#endif for(size_t d = 0; load_option->description[d]; ++d) value.description.push_back(load_option->description[d]); +#if defined(__clang__) +#pragma clang diagnostic pop +#endif uint16_t device_path_size = efi_loadopt_pathlen(load_option, ssize); efidp device_path = efi_loadopt_path(load_option, ssize); @@ -591,16 +540,16 @@ inline std::optional deserialize(const void *data, size_t data_size [](const void *ptr) -> size_t { auto size = efidp_node_size(static_cast(ptr)); - return reinterpret_cast(size); + return static_cast(size); }, [](const void *ptr, size_t bytes_left) -> const void * { const_efidp dp = static_cast(ptr); ssize_t size = efidp_node_size(dp); - if(reinterpret_cast(size) > bytes_left) + if(size < 0 || static_cast(size) > bytes_left) return nullptr; - return static_cast(ptr) + size; + return advance_bytes(ptr, static_cast(size)); }); if(!file_paths || file_paths->empty()) @@ -1261,7 +1210,7 @@ inline std::optional deserialize(const void *data, size_t da size_t data_length = data_size - sizeof(*dp); value.data.resize(data_length); - memcpy(&value.data[0], dp + 1, data_length); + memcpy(&value.data[0], static_cast(advance_bytes(data, sizeof(const efidp_header))), data_length); return {value}; } @@ -1287,7 +1236,37 @@ inline std::optional deserialize(const void *data, size_t data_s if(dp->header.length != data_size) return std::nullopt; - return get_default(File_path::deserializers(), dp->_type_subtype, deserialize)(dp, data_size); +#define TYPE_SUBTYPE(type, subtype) (((type) << 8) | (subtype)) +#define casefp(Type) \ + case TYPE_SUBTYPE(File_path::Type::TYPE, File_path::Type::SUBTYPE): \ + return deserialize(dp, data_size) + + switch(TYPE_SUBTYPE(dp->header.type, dp->header.subtype)) + { + casefp(PCI); + casefp(HWVendor); + casefp(HID); + casefp(USB); + casefp(MSGVendor); + casefp(MAC_address); + casefp(IPv4); + casefp(IPv6); + casefp(SATA); + casefp(HD); + casefp(MEDIAVendor); + casefp(File); + casefp(Firmware_file); + casefp(Firmware_volume); + casefp(BIOS_boot_specification); + casefp(End_instance); + casefp(End_entire); + + default: + return deserialize(dp, data_size); + } + +#undef casefp +#undef TYPE_SUBTYPE } template <> @@ -1298,7 +1277,7 @@ inline size_t serialize(Raw_data &output, const File_path::ANY &file_path) file_path); } -inline Progress_fn _get_variables_progress_fn = nullptr; +extern Progress_fn _get_variables_progress_fn; inline std::unordered_map get_variables(Filter_fn filter_fn, Progress_fn progress_fn) { diff --git a/include/efibootdata.h b/include/efibootdata.h index 3f94d52d..52b07848 100644 --- a/include/efibootdata.h +++ b/include/efibootdata.h @@ -15,27 +15,28 @@ class EFIBootData: public QObject BootEntryListModel driver_entries_list_model{tr("Driver"), {}, this}; BootEntryListModel sysprep_entries_list_model{tr("System Preparation"), {}, this}; BootEntryListModel platform_recovery_entries_list_model{tr("Platform Recovery"), BootEntryListModel::ReadOnly, this}; + + const std::vector> BOOT_ENTRIES{ + {"Boot", boot_entries_list_model}, + {"Driver", driver_entries_list_model}, + {"SysPrep", sysprep_entries_list_model}, + {"PlatformRecovery", platform_recovery_entries_list_model}, + }; + + QString apple_boot_args{}; QUndoStack *undo_stack{nullptr}; + uint64_t supported_indications{0}; + uint64_t indications{0}; + + uint32_t boot_option_support{0}; + uint16_t timeout{0}; bool secure_boot{false}; bool vendor_keys{false}; bool setup_mode{false}; bool audit_mode{false}; bool deployed_mode{false}; - uint32_t boot_option_support{0}; - - uint64_t supported_indications{0}; - uint64_t indications{0}; - - QString apple_boot_args{}; - - const std::vector> BOOT_ENTRIES{ - {"Boot", boot_entries_list_model}, - {"Driver", driver_entries_list_model}, - {"SysPrep", sysprep_entries_list_model}, - {"PlatformRecovery", platform_recovery_entries_list_model}, - }; public: explicit EFIBootData(QObject *parent = nullptr); diff --git a/include/efivar-lite/efivar-dp.h b/include/efivar-lite/efivar-dp.h index 11ee469b..4d014d14 100644 --- a/include/efivar-lite/efivar-dp.h +++ b/include/efivar-lite/efivar-dp.h @@ -14,8 +14,6 @@ typedef struct uint16_t length; } efidp_header; -typedef uint16_t efidp_type_subtype; - typedef uint8_t efidp_boolean; enum EFIDP_TYPE @@ -141,7 +139,7 @@ typedef struct uint8_t partition_signature[16]; uint8_t partition_format; uint8_t signature_type; -#ifdef __ia64 +#if defined(__ia64) uint8_t _padding[6]; /* Empirically needed */ #endif } efidp_hd; @@ -195,7 +193,6 @@ enum EFIDP_END typedef union { efidp_header header; - efidp_type_subtype _type_subtype; efidp_pci pci; efidp_hid hid; efidp_usb usb; @@ -242,7 +239,7 @@ static inline int16_t } static inline ssize_t - ATTR_ARTIFICIAL ATTR_NONNULL(1) ATTR_UNUSED ATTR_WARN_UNUSED_RESULT + ATTR_ARTIFICIAL ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT efidp_node_size(const_efidp dn) { if(ATTR_NONNULL_IS_NULL(dn) || dn->header.length < 4) @@ -265,7 +262,7 @@ static inline int if(sz < 0) return -1; - *out = (const_efidp)((const uint8_t *)in + sz); + *out = STATIC_CAST(const_efidp)(advance_bytes(in, STATIC_CAST(size_t)(sz))); if(*out < in) { errno = EINVAL; @@ -289,7 +286,7 @@ static inline int if(sz < 0) return -1; - *out = (const_efidp)((const uint8_t *)in + sz); + *out = STATIC_CAST(const_efidp)(advance_bytes(in, STATIC_CAST(size_t)(sz))); if(*out < in) { errno = EINVAL; @@ -342,7 +339,7 @@ static inline int if(sz < 0) break; - const_efidp next = (const_efidp)((const uint8_t *)in + sz); + const_efidp next = STATIC_CAST(const_efidp)(advance_bytes(in, STATIC_CAST(size_t)(sz))); if(next < in) { errno = EINVAL; diff --git a/include/efivar-lite/efivar.h b/include/efivar-lite/efivar.h index bbef39f2..52e613a2 100644 --- a/include/efivar-lite/efivar.h +++ b/include/efivar-lite/efivar.h @@ -6,7 +6,6 @@ #pragma once #include -#include #include #include "compat.h" @@ -36,7 +35,7 @@ static const uint32_t EFI_VARIABLE_ATTRIBUTE_AUTHENTICATED_WRITE_ACCESS = 0x0000 static const uint32_t EFI_VARIABLE_ATTRIBUTE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS = 0x00000020; static const uint32_t EFI_VARIABLE_ATTRIBUTE_APPEND_WRITE = 0x00000040; static const uint32_t EFI_VARIABLE_ATTRIBUTE_DEFAULTS = -#ifdef __APPLE__ +#if defined(__APPLE__) // macOS doesn't support attributes for variables 0 #else @@ -45,9 +44,9 @@ static const uint32_t EFI_VARIABLE_ATTRIBUTE_DEFAULTS = ; static const mode_t EFI_VARIABLE_MODE_DEFAULTS = -#ifdef _WIN32 +#if defined(_WIN32) // Windows doesn't support file mode setting for variables - (mode_t)0 + STATIC_CAST(mode_t)(0) #else S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH #endif diff --git a/include/filepathdialog.h b/include/filepathdialog.h index 12ab6d99..b3f129c4 100644 --- a/include/filepathdialog.h +++ b/include/filepathdialog.h @@ -20,42 +20,10 @@ class HorizontalTabStyle: public QProxyStyle HorizontalTabStyle(const HorizontalTabStyle &) = delete; HorizontalTabStyle &operator=(const HorizontalTabStyle &) = delete; - QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const override - { - QSize s = QProxyStyle::sizeFromContents(type, option, size, widget); - if(type == QStyle::CT_TabBarTab) - s.transpose(); - - return s; - } - - void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override - { - if(element != CE_TabBarTabLabel) - { - QProxyStyle::drawControl(element, option, painter, widget); - return; - } - - const QStyleOptionTab *tab = qstyleoption_cast(option); - if(!tab) - { - QProxyStyle::drawControl(element, option, painter, widget); - return; - } - - QStyleOptionTab opt(*tab); - opt.shape = QTabBar::RoundedNorth; - QProxyStyle::drawControl(element, &opt, painter, widget); - } + QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const override; + void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override; }; -#if defined(_MSC_VER) -#pragma warning(push) -// C4820: 'bytes' bytes padding added after construct 'member_name' -#pragma warning(disable : 4820) -#endif - class FilePathDialog: public QDialog { Q_OBJECT @@ -158,7 +126,3 @@ private slots: void vendorDataFormatChanged(int index); void unknownDataFormatChanged(int index); }; - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif diff --git a/src/bootentry.cpp b/src/bootentry.cpp index a10c9f05..f2cae492 100644 --- a/src/bootentry.cpp +++ b/src/bootentry.cpp @@ -6,8 +6,7 @@ #include #include -std::unique_ptr(const QJsonObject &)>>> File_path::JSON_readers__instance; -std::unique_ptr(const void *, size_t)>>> EFIBoot::File_path::deserializers__instance; +EFIBoot::Progress_fn EFIBoot::_get_variables_progress_fn = nullptr; #define check_obj() \ if(obj["type"] != TYPE || obj["subtype"] != SUBTYPE) \ @@ -353,8 +352,8 @@ static_assert(sizeof(File_path::Vendor::guid) == sizeof(EFIBoot::File_path::MSGV static_assert(sizeof(File_path::Vendor::guid) == sizeof(EFIBoot::File_path::MEDIAVendor::guid)); File_path::Vendor::Vendor(const EFIBoot::File_path::HWVendor &vendor) - : _type{vendor.TYPE} - , data{QByteArray::fromRawData(reinterpret_cast(vendor.data.data()), static_cast(vendor.data.size()))} + : data{QByteArray::fromRawData(reinterpret_cast(vendor.data.data()), static_cast(vendor.data.size()))} + , _type{vendor.TYPE} { data.detach(); static_assert(sizeof(vendor.guid) == sizeof(guid)); @@ -362,8 +361,8 @@ File_path::Vendor::Vendor(const EFIBoot::File_path::HWVendor &vendor) } File_path::Vendor::Vendor(const EFIBoot::File_path::MSGVendor &vendor) - : _type{vendor.TYPE} - , data{QByteArray::fromRawData(reinterpret_cast(vendor.data.data()), static_cast(vendor.data.size()))} + : data{QByteArray::fromRawData(reinterpret_cast(vendor.data.data()), static_cast(vendor.data.size()))} + , _type{vendor.TYPE} { data.detach(); static_assert(sizeof(vendor.guid) == sizeof(guid)); @@ -371,8 +370,8 @@ File_path::Vendor::Vendor(const EFIBoot::File_path::MSGVendor &vendor) } File_path::Vendor::Vendor(const EFIBoot::File_path::MEDIAVendor &vendor) - : _type{vendor.TYPE} - , data{QByteArray::fromRawData(reinterpret_cast(vendor.data.data()), static_cast(vendor.data.size()))} + : data{QByteArray::fromRawData(reinterpret_cast(vendor.data.data()), static_cast(vendor.data.size()))} + , _type{vendor.TYPE} { data.detach(); static_assert(sizeof(vendor.guid) == sizeof(guid)); @@ -514,12 +513,12 @@ static_assert(sizeof(File_path::IPv4::subnet_mask.toIPv4Address()) == sizeof(EFI File_path::IPv4::IPv4(const EFIBoot::File_path::IPv4 &ipv4) : local_ip_address{*reinterpret_cast(ipv4.local_ip_address.data())} , remote_ip_address{*reinterpret_cast(ipv4.remote_ip_address.data())} + , gateway_ip_address{*reinterpret_cast(ipv4.gateway_ip_address.data())} + , subnet_mask{*reinterpret_cast(ipv4.subnet_mask.data())} , local_port{ipv4.local_port} , remote_port{ipv4.remote_port} , protocol{ipv4.protocol} , static_ip_address{ipv4.static_ip_address} - , gateway_ip_address{*reinterpret_cast(ipv4.gateway_ip_address.data())} - , subnet_mask{*reinterpret_cast(ipv4.subnet_mask.data())} { } @@ -925,9 +924,9 @@ auto File_path::FirmwareVolume::toString(bool refresh) const -> QString } File_path::BIOSBootSpecification::BIOSBootSpecification(const EFIBoot::File_path::BIOS_boot_specification &bios_boot_specification) - : device_type{bios_boot_specification.device_type} + : description{QString::fromStdString(bios_boot_specification.description)} + , device_type{bios_boot_specification.device_type} , status_flag{bios_boot_specification.status_flag} - , description{QString::fromStdString(bios_boot_specification.description)} { } @@ -1007,9 +1006,9 @@ auto File_path::End::toString(bool refresh) const -> QString } File_path::Unknown::Unknown(const EFIBoot::File_path::Unknown &unknown) - : _type{unknown.TYPE} + : data{QByteArray::fromRawData(reinterpret_cast(unknown.data.data()), static_cast(unknown.data.size()))} + , _type{unknown.TYPE} , _subtype{unknown.SUBTYPE} - , data{QByteArray::fromRawData(reinterpret_cast(unknown.data.data()), static_cast(unknown.data.size()))} { data.detach(); } diff --git a/src/commands.cpp b/src/commands.cpp new file mode 100644 index 00000000..675a1ae1 --- /dev/null +++ b/src/commands.cpp @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "commands.h" + +InsertRemoveBootEntryCommand::InsertRemoveBootEntryCommand(BootEntryListModel &model_, const QString &description, const QModelIndex &index_parent_, int index_, const BootEntry &entry_, QUndoCommand *parent) + : QUndoCommand(description, parent) + , model{model_} + , index_parent{index_parent_} + , entry{entry_} + , index{index_} +{ +} + +int InsertRemoveBootEntryCommand::id() const +{ + return -1; +} + +void InsertRemoveBootEntryCommand::insert() +{ + model.beginInsertRows(index_parent, index, index); + model.entries.insert(index, entry); + model.endInsertRows(); +} + +void InsertRemoveBootEntryCommand::remove() +{ + model.beginRemoveRows(index_parent, index, index); + model.entries.removeAt(index); + model.endRemoveRows(); +} + +InsertBootEntryCommand::InsertBootEntryCommand(BootEntryListModel &model_, const QModelIndex &index_parent_, int index_, const BootEntry &entry_, QUndoCommand *parent) + : InsertRemoveBootEntryCommand(model_, QObject::tr("Insert %1 entry \"%2\" at position %3").arg(model_.name, entry_.getTitle()).arg(index_), index_parent_, index_, entry_, parent) +{ +} + +void InsertBootEntryCommand::undo() +{ + remove(); +} + +void InsertBootEntryCommand::redo() +{ + insert(); +} + +RemoveBootEntryCommand::RemoveBootEntryCommand(BootEntryListModel &model_, const QModelIndex &index_parent_, int index_, QUndoCommand *parent) + : InsertRemoveBootEntryCommand(model_, QObject::tr("Removing %1 entry \"%2\" from position %3").arg(model_.name, model_.entries.at(index_).getTitle()).arg(index_), index_parent_, index_, model_.entries.at(index_), parent) +{ +} + +void RemoveBootEntryCommand::undo() +{ + insert(); +} + +void RemoveBootEntryCommand::redo() +{ + remove(); +} + +MoveBootEntryCommand::MoveBootEntryCommand(BootEntryListModel &model_, const QModelIndex &source_parent_, int source_index_, const QModelIndex &destination_parent_, int destination_index_, QUndoCommand *parent) + : QUndoCommand("", parent) + , model{model_} + , title{model_.entries.at(source_index_).getTitle()} + , source_parent{source_parent_} + , destination_parent{destination_parent_} + , source_index{source_index_} + , destination_index{destination_index_} +{ + setText(QObject::tr("Move %1 entry \"%2\" from position %3 to %4").arg(model.name, title).arg(source_index).arg(destination_index)); +} + +int MoveBootEntryCommand::id() const +{ + return 2; +} + +void MoveBootEntryCommand::undo() +{ + model.beginMoveRows(destination_parent, destination_index, destination_index + 1, source_parent, source_index); + model.entries.move(destination_index, source_index); + model.endMoveRows(); +} + +void MoveBootEntryCommand::redo() +{ + model.beginMoveRows(source_parent, source_index, source_index + 1, destination_parent, destination_index); + model.entries.move(source_index, destination_index); + model.endMoveRows(); +} + +bool MoveBootEntryCommand::mergeWith(const QUndoCommand *command) +{ + if(command->id() != id()) + return false; + + auto cmd = static_cast(command); + if(&cmd->model != &model) + return false; + + if(cmd->source_parent != destination_parent) + return false; + + if(cmd->source_index != destination_index) + return false; + + destination_parent = cmd->destination_parent; + destination_index = cmd->destination_index; + setText(QObject::tr("Move %1 entry \"%2\" from position %3 to %4").arg(model.name, title).arg(source_index).arg(destination_index)); + if(source_index == destination_index) + setObsolete(true); + + return true; +} + +ChangeOptionalDataFormatCommand::ChangeOptionalDataFormatCommand(BootEntryListModel &model_, const QModelIndex &index_, const BootEntry::OptionalDataFormat &value_, QUndoCommand *parent) + : QUndoCommand{"", parent} + , model{model_} + , title{model_.entries.at(index_.row()).getTitle()} + , index{index_} + , value{value_} +{ + updateTitle(value); +} + +int ChangeOptionalDataFormatCommand::id() const +{ + return 4; +} + +void ChangeOptionalDataFormatCommand::undo() +{ + redo(); +} + +void ChangeOptionalDataFormatCommand::redo() +{ + auto &entry = model.entries[index.row()]; + auto old_value = entry.optional_data_format; + entry.changeOptionalDataFormat(value); + value = old_value; + emit model.dataChanged(index, index, {Qt::EditRole}); +} + +bool ChangeOptionalDataFormatCommand::mergeWith(const QUndoCommand *command) +{ + auto cmd = static_cast(command); + if(&cmd->model != &model) + return false; + + if(cmd->index != index) + return false; + + const auto &entry = model.entries.at(index.row()); + if(value == entry.optional_data_format) + setObsolete(true); + + updateTitle(entry.optional_data_format); + return true; +} + +void ChangeOptionalDataFormatCommand::updateTitle(BootEntry::OptionalDataFormat val) +{ + QString format{}; + switch(val) + { + case BootEntry::OptionalDataFormat::Base64: + format = "Base64"; + break; + + case BootEntry::OptionalDataFormat::Hex: + format = "Hex"; + break; + + case BootEntry::OptionalDataFormat::Utf16: + format = "UTF-16"; + break; + + case BootEntry::OptionalDataFormat::Utf8: + format = "UTF-8"; + break; + } + + setText(QObject::tr("Change %1 entry \"%2\" %3 to \"%4\"").arg(model.name, title, QObject::tr("Optional data"), format)); +} + +InsertRemoveBootEntryFilePathCommand::InsertRemoveBootEntryFilePathCommand(BootEntryListModel &model_, const QString &description, const QModelIndex &index_, int row_, const File_path::ANY &file_path_, QUndoCommand *parent) + : QUndoCommand(description, parent) + , model{model_} + , file_path{file_path_} + , index{index_} + , row{row_} +{ +} + +int InsertRemoveBootEntryFilePathCommand::id() const +{ + return -1; +} + +void InsertRemoveBootEntryFilePathCommand::insert() +{ + auto &entry = model.entries[index.row()]; + entry.device_path.insert(row, file_path); + entry.formatDevicePath(); + emit model.dataChanged(index, index, {Qt::EditRole}); +} + +void InsertRemoveBootEntryFilePathCommand::remove() +{ + auto &entry = model.entries[index.row()]; + entry.device_path.removeAt(row); + entry.formatDevicePath(); + emit model.dataChanged(index, index, {Qt::EditRole}); +} + +InsertBootEntryFilePathCommand::InsertBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int row_, const File_path::ANY &file_path_, QUndoCommand *parent) + : InsertRemoveBootEntryFilePathCommand(model_, QObject::tr("Insert %1 entry \"%2\" file path at position %3").arg(model_.name, model_.entries.at(index_.row()).getTitle()).arg(row_), index_, row_, file_path_, parent) +{ +} + +void InsertBootEntryFilePathCommand::undo() +{ + remove(); +} + +void InsertBootEntryFilePathCommand::redo() +{ + insert(); +} + +RemoveBootEntryFilePathCommand::RemoveBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int row_, QUndoCommand *parent) + : InsertRemoveBootEntryFilePathCommand(model_, QObject::tr("Removing %1 entry \"%2\" file path from position %3").arg(model_.name, model_.entries.at(index_.row()).getTitle()).arg(row_), index_, row_, model_.entries.at(index_.row()).device_path.at(row_), parent) +{ +} + +void RemoveBootEntryFilePathCommand::undo() +{ + insert(); +} + +void RemoveBootEntryFilePathCommand::redo() +{ + remove(); +} + +SetBootEntryFilePathCommand::SetBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int row_, const File_path::ANY &value_, QUndoCommand *parent) + : QUndoCommand(QObject::tr("Setting %1 entry \"%2\" file path at position %3").arg(model_.name, model_.entries.at(index_.row()).getTitle()).arg(row_), parent) + , model{model_} + , index{index_} + , value{value_} + , row{row_} +{ +} + +int SetBootEntryFilePathCommand::id() const +{ + return -1; +} + +void SetBootEntryFilePathCommand::undo() +{ + redo(); +} + +void SetBootEntryFilePathCommand::redo() +{ + auto &entry = model.entries[index.row()]; + auto old_value = entry.device_path[row]; + entry.device_path[row] = value; + value = old_value; + entry.formatDevicePath(); + emit model.dataChanged(index, index, {Qt::EditRole}); +} + +MoveBootEntryFilePathCommand::MoveBootEntryFilePathCommand(BootEntryListModel &model_, const QModelIndex &index_, int source_row_, int destination_row_, QUndoCommand *parent) + : QUndoCommand("", parent) + , model{model_} + , title{model_.entries.at(index_.row()).getTitle()} + , index{index_} + , source_row{source_row_} + , destination_row{destination_row_} +{ + setText(QObject::tr("Move %1 entry \"%2\" file path from position %3 to %4").arg(model.name, title).arg(source_row).arg(destination_row)); +} + +int MoveBootEntryFilePathCommand::id() const +{ + return 5; +} + +void MoveBootEntryFilePathCommand::undo() +{ + auto &entry = model.entries[index.row()]; + entry.device_path.move(destination_row, source_row); + entry.formatDevicePath(); + emit model.dataChanged(index, index, {Qt::EditRole}); +} + +void MoveBootEntryFilePathCommand::redo() +{ + auto &entry = model.entries[index.row()]; + entry.device_path.move(source_row, destination_row); + entry.formatDevicePath(); + emit model.dataChanged(index, index, {Qt::EditRole}); +} + +bool MoveBootEntryFilePathCommand::mergeWith(const QUndoCommand *command) +{ + if(command->id() != id()) + return false; + + auto cmd = static_cast(command); + if(&cmd->model != &model) + return false; + + if(cmd->index != index) + return false; + + if(cmd->source_row != destination_row) + return false; + + destination_row = cmd->destination_row; + setText(QObject::tr("Move %1 entry \"%2\" file path from position %3 to %4").arg(model.name, title).arg(source_row).arg(destination_row)); + if(source_row == destination_row) + setObsolete(true); + + return true; +} diff --git a/src/driveinfo.darwin.cpp b/src/driveinfo.darwin.cpp index 096b01ae..a6887a1d 100644 --- a/src/driveinfo.darwin.cpp +++ b/src/driveinfo.darwin.cpp @@ -50,7 +50,7 @@ auto DriveInfo::getAll(bool refresh) -> QVector CFRelease(disk_cf); CFTypeRef value_cf = CFDictionaryGetValue(disk_info_cf, kDADiskDescriptionVolumeNameKey); if(value_cf != nullptr) - driveinfo.name = QString::fromCFString((CFStringRef)value_cf); + driveinfo.name = QString::fromCFString(static_cast(value_cf)); value_cf = CFDictionaryGetValue(disk_info_cf, kDADiskDescriptionVolumeUUIDKey); if(value_cf == nullptr) @@ -60,13 +60,13 @@ auto DriveInfo::getAll(bool refresh) -> QVector { // Assume GPT driveinfo.signature_type = DriveInfo::SIGNATURE::GUID; - driveinfo.signature = QUuid::fromCFUUID((CFUUIDRef)value_cf); + driveinfo.signature = QUuid::fromCFUUID(static_cast(value_cf)); } value_cf = IORegistryEntryCreateCFProperty(disk_service_io, CFSTR(kIOMediaPartitionIDKey), kCFAllocatorDefault, 0); if(value_cf != nullptr) { - CFNumberGetValue((CFNumberRef)value_cf, CFNumberGetType((CFNumberRef)value_cf), static_cast(&driveinfo.partition)); + CFNumberGetValue(static_cast(value_cf), CFNumberGetType(static_cast(value_cf)), static_cast(&driveinfo.partition)); CFRelease(value_cf); } @@ -74,14 +74,14 @@ auto DriveInfo::getAll(bool refresh) -> QVector value_cf = IORegistryEntryCreateCFProperty(disk_service_io, CFSTR(kIOMediaPreferredBlockSizeKey), kCFAllocatorDefault, 0); if(value_cf != nullptr) { - CFNumberGetValue((CFNumberRef)value_cf, CFNumberGetType((CFNumberRef)value_cf), static_cast(&block_size)); + CFNumberGetValue(static_cast(value_cf), CFNumberGetType(static_cast(value_cf)), static_cast(&block_size)); CFRelease(value_cf); } value_cf = IORegistryEntryCreateCFProperty(disk_service_io, CFSTR(kIOMediaBaseKey), kCFAllocatorDefault, 0); if(value_cf != nullptr) { - CFNumberGetValue((CFNumberRef)value_cf, CFNumberGetType((CFNumberRef)value_cf), static_cast(&driveinfo.start)); + CFNumberGetValue(static_cast(value_cf), CFNumberGetType(static_cast(value_cf)), static_cast(&driveinfo.start)); CFRelease(value_cf); } @@ -90,7 +90,7 @@ auto DriveInfo::getAll(bool refresh) -> QVector value_cf = CFDictionaryGetValue(disk_info_cf, kDADiskDescriptionMediaSizeKey); if(value_cf != nullptr) - CFNumberGetValue((CFNumberRef)value_cf, kCFNumberIntType, &driveinfo.size); + CFNumberGetValue(static_cast(value_cf), kCFNumberIntType, &driveinfo.size); IOObjectRelease(disk_service_io); CFRelease(disk_info_cf); diff --git a/src/driveinfo.win32.cpp b/src/driveinfo.win32.cpp index 80ab2a65..f6b99692 100644 --- a/src/driveinfo.win32.cpp +++ b/src/driveinfo.win32.cpp @@ -1,5 +1,6 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include +#include #include "compat.h" #include "driveinfo.h" @@ -11,22 +12,22 @@ QVector DriveInfo::getAll(bool refresh) all.clear(); - TCHAR volume_name[MAX_PATH]; - HANDLE volume_handle = FindFirstVolume(volume_name, ARRAYSIZE(volume_name)); + std::array volume_name; + HANDLE volume_handle = FindFirstVolume(volume_name.data(), static_cast(volume_name.size())); if(volume_handle == INVALID_HANDLE_VALUE) return all; - for(BOOL volume_found = true; volume_found; volume_found = FindNextVolume(volume_handle, volume_name, ARRAYSIZE(volume_name))) + for(BOOL volume_found = true; volume_found; volume_found = FindNextVolume(volume_handle, volume_name.data(), static_cast(volume_name.size()))) { DriveInfo driveinfo{}; - TCHAR device_name[MAX_PATH]; - size_t length = _tcslen(volume_name); + std::array device_name; + size_t length = _tcsnccnt(volume_name.data(), volume_name.size()); if(length != 49u) continue; volume_name[length - 1u] = _T('\0'); - if(!QueryDosDevice(&volume_name[4], device_name, ARRAYSIZE(device_name))) + if(!QueryDosDevice(&volume_name[4], device_name.data(), static_cast(device_name.size()))) continue; volume_name[length - 1u] = _T('\\'); @@ -36,21 +37,21 @@ QVector DriveInfo::getAll(bool refresh) device_name[4] = _T('\\'); device_name[5] = _T('\\'); device_name[6] = _T('.'); - HANDLE device_handle = CreateFile(device_name + 4, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); + HANDLE device_handle = CreateFile(&device_name[4], 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); device_name[4] = _T('i'); device_name[5] = _T('c'); device_name[6] = _T('e'); if(device_handle == INVALID_HANDLE_VALUE) continue; - if(!DeviceIoControl(device_handle, IOCTL_DISK_GET_PARTITION_INFO_EX, nullptr, 0, &partition_information, sizeof(partition_information), nullptr, 0)) + if(!DeviceIoControl(device_handle, IOCTL_DISK_GET_PARTITION_INFO_EX, nullptr, 0, &partition_information, sizeof(partition_information), nullptr, nullptr)) { CloseHandle(device_handle); continue; } CloseHandle(device_handle); - driveinfo.name = QStringFromTCharArray(device_name + 8); + driveinfo.name = QStringFromTCharArray(&device_name[8]); switch(partition_information.PartitionStyle) { case PARTITION_STYLE_GPT: diff --git a/src/efibooteditor.cpp b/src/efibooteditor.cpp index 5e490b51..ca44c2df 100644 --- a/src/efibooteditor.cpp +++ b/src/efibooteditor.cpp @@ -400,7 +400,6 @@ std::tuple EFIBootEditor::ge } Q_UNREACHABLE(); - return {tr("Boot"), *ui->boot_entries_list, data.boot_entries_list_model}; } std::tuple EFIBootEditor::currentBootEntryList() diff --git a/src/efivar-lite.c b/src/efivar-lite.c index 32eb47f1..384e8a6e 100644 --- a/src/efivar-lite.c +++ b/src/efivar-lite.c @@ -1,6 +1,4 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -#include - #include "compat.h" #include "efivar-lite.common.h" #include "efivar-lite/efiboot-loadopt.h" @@ -99,12 +97,12 @@ efidp efi_loadopt_path(efi_load_option *opt, ssize_t limit) if((size_t)limit <= offsetof(efi_load_option, description)) return NULL; - limit -= offsetof(efi_load_option, description); + limit -= (ssize_t)offsetof(efi_load_option, description); ptr += offsetof(efi_load_option, description); - for(size_t d = 0; limit > 0 && opt->description[d]; ++d, limit -= sizeof(opt->description[0]), ptr += sizeof(opt->description[0])) + for(size_t d = 0; limit > 0 && opt->description[d]; ++d, limit -= (ssize_t)sizeof(opt->description[0]), ptr += sizeof(opt->description[0])) ; // \0 - limit -= sizeof(opt->description[0]); + limit -= (ssize_t)sizeof(opt->description[0]); ptr += sizeof(opt->description[0]); if(limit == 0) return NULL; diff --git a/src/efivar-lite.common.h b/src/efivar-lite.common.h index ce41ae62..f4ba37de 100644 --- a/src/efivar-lite.common.h +++ b/src/efivar-lite.common.h @@ -2,11 +2,17 @@ #pragma once #include -#include #include #include "compat.h" #include "efivar-lite/efivar.h" extern const size_t EFI_MAX_VARIABLES; +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-identifier" +#endif int _efi_get_next_variable_name(efi_guid_t **guid, TCHAR **name); +#if defined(__clang__) +#pragma clang diagnostic pop +#endif diff --git a/src/efivar-lite.darwin.c b/src/efivar-lite.darwin.c index 933a6511..78281a61 100644 --- a/src/efivar-lite.darwin.c +++ b/src/efivar-lite.darwin.c @@ -15,7 +15,7 @@ const efi_guid_t efi_guid_apple = {"7C436110-AB2A-4BBB-A880-FE41995C9F82"}; static io_registry_entry_t options_entry; static kern_return_t err; -static const char *last_iokit_function = NULL; +static char *last_iokit_function = NULL; int efi_variables_supported(void) { diff --git a/src/efivar-lite.win32.c b/src/efivar-lite.win32.c index f47fda41..fd6ab089 100644 --- a/src/efivar-lite.win32.c +++ b/src/efivar-lite.win32.c @@ -13,7 +13,7 @@ const efi_guid_t efi_guid_global = {_T("{8be4df61-93ca-11d2-aa0d-00e098032b8c}")}; const efi_guid_t efi_guid_apple = {_T("{7c436110-ab2a-4bbb-a880-fe41995c9f82}")}; -static const TCHAR *last_winapi_function = NULL; +static TCHAR *last_winapi_function = NULL; int efi_variables_supported(void) { diff --git a/src/filepathdialog.cpp b/src/filepathdialog.cpp index c21419ea..c66422d6 100644 --- a/src/filepathdialog.cpp +++ b/src/filepathdialog.cpp @@ -7,6 +7,35 @@ #include +QSize HorizontalTabStyle::sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const +{ + QSize s = QProxyStyle::sizeFromContents(type, option, size, widget); + if(type == QStyle::CT_TabBarTab) + s.transpose(); + + return s; +} + +void HorizontalTabStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const +{ + if(element != CE_TabBarTabLabel) + { + QProxyStyle::drawControl(element, option, painter, widget); + return; + } + + const QStyleOptionTab *tab = qstyleoption_cast(option); + if(!tab) + { + QProxyStyle::drawControl(element, option, painter, widget); + return; + } + + QStyleOptionTab opt(*tab); + opt.shape = QTabBar::RoundedNorth; + QProxyStyle::drawControl(element, &opt, painter, widget); +} + FilePathDialog::FilePathDialog(QWidget *parent) : QDialog(parent) , horizontal_tab_style{}