diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index d13e79f..1880a54 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -10,6 +10,7 @@ add_library(common STATIC logging/log.cpp logging/log.h misc.cpp + progress_callback.h scope_exit.h string_util.cpp string_util.h diff --git a/src/common/progress_callback.h b/src/common/progress_callback.h new file mode 100644 index 0000000..67026e4 --- /dev/null +++ b/src/common/progress_callback.h @@ -0,0 +1,14 @@ +// Copyright 2021 threeSD Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +namespace Common { + +// (current_size, total_size) +using ProgressCallback = std::function; + +} // namespace Common diff --git a/src/core/decryptor.cpp b/src/core/decryptor.cpp index 0ae746d..6c8781f 100644 --- a/src/core/decryptor.cpp +++ b/src/core/decryptor.cpp @@ -53,7 +53,7 @@ void SDMCDecryptor::Reset(std::size_t total_size) { } bool SDMCDecryptor::DecryptAndWriteFile(const std::string& source, const std::string& destination, - const ProgressCallback& callback) { + const Common::ProgressCallback& callback) { if (!FileUtil::CreateFullPath(destination)) { LOG_ERROR(Core, "Could not create path {}", destination); return false; diff --git a/src/core/decryptor.h b/src/core/decryptor.h index a9a0286..807cf66 100644 --- a/src/core/decryptor.h +++ b/src/core/decryptor.h @@ -33,7 +33,7 @@ public: */ bool DecryptAndWriteFile( const std::string& source, const std::string& destination, - const ProgressCallback& callback = [](std::size_t, std::size_t) {}); + const Common::ProgressCallback& callback = [](std::size_t, std::size_t) {}); void Abort(); diff --git a/src/core/importer.cpp b/src/core/importer.cpp index 5a685f3..b58f7ef 100644 --- a/src/core/importer.cpp +++ b/src/core/importer.cpp @@ -69,7 +69,7 @@ void SDMCImporter::AbortImporting() { } bool SDMCImporter::ImportContent(const ContentSpecifier& specifier, - const ProgressCallback& callback) { + const Common::ProgressCallback& callback) { switch (specifier.type) { case ContentType::Application: case ContentType::Update: @@ -130,7 +130,7 @@ bool ImportTitleGeneric(Dec& decryptor, const std::string& base_path, } // namespace bool SDMCImporter::ImportTitle(const ContentSpecifier& specifier, - const ProgressCallback& callback) { + const Common::ProgressCallback& callback) { return ImportTitleGeneric( *decryptor, config.sdmc_path, specifier, [this, &callback](const std::string& filepath) { return decryptor->DecryptAndWriteFile( @@ -144,7 +144,7 @@ bool SDMCImporter::ImportTitle(const ContentSpecifier& specifier, } bool SDMCImporter::ImportNandTitle(const ContentSpecifier& specifier, - const ProgressCallback& callback) { + const Common::ProgressCallback& callback) { const auto base_path = config.system_titles_path.substr(0, config.system_titles_path.size() - 6); @@ -167,7 +167,8 @@ bool SDMCImporter::ImportNandTitle(const ContentSpecifier& specifier, }); } -bool SDMCImporter::ImportSavegame(u64 id, [[maybe_unused]] const ProgressCallback& callback) { +bool SDMCImporter::ImportSavegame(u64 id, + [[maybe_unused]] const Common::ProgressCallback& callback) { const auto path = fmt::format("title/{:08x}/{:08x}/data/", (id >> 32), (id & 0xFFFFFFFF)); DataContainer container(decryptor->DecryptFile(fmt::format("/{}00000001.sav", path))); @@ -190,7 +191,8 @@ bool SDMCImporter::ImportSavegame(u64 id, [[maybe_unused]] const ProgressCallbac "Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000/" + path); } -bool SDMCImporter::ImportNandSavegame(u64 id, [[maybe_unused]] const ProgressCallback& callback) { +bool SDMCImporter::ImportNandSavegame(u64 id, + [[maybe_unused]] const Common::ProgressCallback& callback) { const auto path = fmt::format("sysdata/{:08x}/00000000", (id & 0xFFFFFFFF)); FileUtil::IOFile file(config.nand_data_path + path, "rb"); @@ -216,7 +218,8 @@ bool SDMCImporter::ImportNandSavegame(u64 id, [[maybe_unused]] const ProgressCal 1); } -bool SDMCImporter::ImportExtdata(u64 id, [[maybe_unused]] const ProgressCallback& callback) { +bool SDMCImporter::ImportExtdata(u64 id, + [[maybe_unused]] const Common::ProgressCallback& callback) { const auto path = fmt::format("extdata/{:08x}/{:08x}/", (id >> 32), (id & 0xFFFFFFFF)); SDExtdata extdata("/" + path, *decryptor); if (!extdata.IsGood()) { @@ -228,7 +231,8 @@ bool SDMCImporter::ImportExtdata(u64 id, [[maybe_unused]] const ProgressCallback "Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000/" + path); } -bool SDMCImporter::ImportNandExtdata(u64 id, [[maybe_unused]] const ProgressCallback& callback) { +bool SDMCImporter::ImportNandExtdata(u64 id, + [[maybe_unused]] const Common::ProgressCallback& callback) { const auto path = fmt::format("extdata/{:08x}/{:08x}/", (id >> 32), (id & 0xFFFFFFFF)); SDExtdata extdata(config.nand_data_path + path); if (!extdata.IsGood()) { @@ -239,7 +243,8 @@ bool SDMCImporter::ImportNandExtdata(u64 id, [[maybe_unused]] const ProgressCall "data/00000000000000000000000000000000/" + path); } -bool SDMCImporter::ImportSystemArchive(u64 id, [[maybe_unused]] const ProgressCallback& callback) { +bool SDMCImporter::ImportSystemArchive(u64 id, + [[maybe_unused]] const Common::ProgressCallback& callback) { const auto path = fmt::format("{}{:08x}/{:08x}.app", config.system_archives_path, (id >> 32), (id & 0xFFFFFFFF)); FileUtil::IOFile file(path, "rb"); @@ -273,7 +278,8 @@ bool SDMCImporter::ImportSystemArchive(u64 id, [[maybe_unused]] const ProgressCa return true; } -bool SDMCImporter::ImportSysdata(u64 id, [[maybe_unused]] const ProgressCallback& callback) { +bool SDMCImporter::ImportSysdata(u64 id, + [[maybe_unused]] const Common::ProgressCallback& callback) { switch (id) { case 0: { // boot9.bin const auto target_path = FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir) + BOOTROM9; @@ -500,7 +506,7 @@ TitleData LoadTitleData(NCCHContainer& ncch) { } bool SDMCImporter::DumpCXI(const ContentSpecifier& specifier, const std::string& destination, - const ProgressCallback& callback) { + const Common::ProgressCallback& callback) { if (specifier.type != ContentType::Application) { LOG_ERROR(Core, "Unsupported specifier type {}", static_cast(specifier.type)); @@ -534,7 +540,7 @@ void SDMCImporter::AbortDumpCXI() { } bool SDMCImporter::BuildCIA(const ContentSpecifier& specifier, const std::string& destination, - const ProgressCallback& callback) { + const Common::ProgressCallback& callback) { if (config.certs_db_path.empty()) { LOG_ERROR(Core, "Missing certs.db"); diff --git a/src/core/importer.h b/src/core/importer.h index 9026809..e2f3db2 100644 --- a/src/core/importer.h +++ b/src/core/importer.h @@ -9,6 +9,7 @@ #include #include #include "common/common_types.h" +#include "common/progress_callback.h" namespace Core { @@ -96,9 +97,6 @@ class NCCHContainer; class SDMCImporter { public: - /// (current_size, total_size) - using ProgressCallback = std::function; - /** * Initializes the importer. * @param root_folder Path to the "Nintendo 3DS//" folder. @@ -114,7 +112,7 @@ public: */ bool ImportContent( const ContentSpecifier& specifier, - const ProgressCallback& callback = [](std::size_t, std::size_t) {}); + const Common::ProgressCallback& callback = [](std::size_t, std::size_t) {}); /** * Aborts current importing. @@ -128,7 +126,7 @@ public: */ bool DumpCXI( const ContentSpecifier& specifier, const std::string& destination, - const ProgressCallback& callback = [](std::size_t, std::size_t) {}); + const Common::ProgressCallback& callback = [](std::size_t, std::size_t) {}); /** * Aborts current CXI dumping. @@ -142,7 +140,7 @@ public: */ bool BuildCIA( const ContentSpecifier& specifier, const std::string& destination, - const ProgressCallback& callback = [](std::size_t, std::size_t) {}); + const Common::ProgressCallback& callback = [](std::size_t, std::size_t) {}); /** * Aborts current CIA building @@ -168,14 +166,15 @@ public: private: bool Init(); - bool ImportTitle(const ContentSpecifier& specifier, const ProgressCallback& callback); - bool ImportNandTitle(const ContentSpecifier& specifier, const ProgressCallback& callback); - bool ImportSavegame(u64 id, const ProgressCallback& callback); - bool ImportNandSavegame(u64 id, const ProgressCallback& callback); - bool ImportExtdata(u64 id, const ProgressCallback& callback); - bool ImportNandExtdata(u64 id, const ProgressCallback& callback); - bool ImportSystemArchive(u64 id, const ProgressCallback& callback); - bool ImportSysdata(u64 id, const ProgressCallback& callback); + bool ImportTitle(const ContentSpecifier& specifier, const Common::ProgressCallback& callback); + bool ImportNandTitle(const ContentSpecifier& specifier, + const Common::ProgressCallback& callback); + bool ImportSavegame(u64 id, const Common::ProgressCallback& callback); + bool ImportNandSavegame(u64 id, const Common::ProgressCallback& callback); + bool ImportExtdata(u64 id, const Common::ProgressCallback& callback); + bool ImportNandExtdata(u64 id, const Common::ProgressCallback& callback); + bool ImportSystemArchive(u64 id, const Common::ProgressCallback& callback); + bool ImportSysdata(u64 id, const Common::ProgressCallback& callback); void ListTitle(std::vector& out) const; void ListNandTitle(std::vector& out) const; diff --git a/src/core/ncch/cia_builder.cpp b/src/core/ncch/cia_builder.cpp index 4001471..98f4860 100644 --- a/src/core/ncch/cia_builder.cpp +++ b/src/core/ncch/cia_builder.cpp @@ -45,7 +45,7 @@ CIABuilder::~CIABuilder() = default; bool CIABuilder::Init(const std::string& destination, TitleMetadata tmd_, const std::string& certs_db_path, std::size_t total_size_, - const ProgressCallback& callback_) { + const Common::ProgressCallback& callback_) { header = {}; meta = {}; diff --git a/src/core/ncch/cia_builder.h b/src/core/ncch/cia_builder.h index cab742f..923ee97 100644 --- a/src/core/ncch/cia_builder.h +++ b/src/core/ncch/cia_builder.h @@ -8,6 +8,7 @@ #include #include #include "common/file_util.h" +#include "common/progress_callback.h" #include "common/swap.h" #include "core/ncch/ncch_container.h" #include "core/ncch/title_metadata.h" @@ -33,7 +34,7 @@ public: * @return true on success, false otherwise */ bool Init(const std::string& destination, TitleMetadata tmd, const std::string& certs_db_path, - std::size_t total_size, const ProgressCallback& callback); + std::size_t total_size, const Common::ProgressCallback& callback); /** * Adds an NCCH content to the CIA. @@ -103,7 +104,7 @@ private: std::shared_ptr file; std::size_t written{}; // size written (with alignment) std::size_t total_size{}; - ProgressCallback callback; + Common::ProgressCallback callback; // The NCCH to abort on std::mutex abort_ncch_mutex; diff --git a/src/core/ncch/ncch_container.cpp b/src/core/ncch/ncch_container.cpp index 322568e..9773151 100644 --- a/src/core/ncch/ncch_container.cpp +++ b/src/core/ncch/ncch_container.cpp @@ -423,7 +423,7 @@ ResultStatus NCCHContainer::ReadSeedCrypto(bool& used) { } ResultStatus NCCHContainer::DecryptToFile(std::shared_ptr dest_file, - const ProgressCallback& callback) { + const Common::ProgressCallback& callback) { ResultStatus result = Load(); if (result != ResultStatus::Success) return result; diff --git a/src/core/ncch/ncch_container.h b/src/core/ncch/ncch_container.h index 851fc11..b145c0a 100644 --- a/src/core/ncch/ncch_container.h +++ b/src/core/ncch/ncch_container.h @@ -11,6 +11,7 @@ #include "common/bit_field.h" #include "common/common_types.h" #include "common/file_util.h" +#include "common/progress_callback.h" #include "common/swap.h" #include "core/decryptor.h" #include "core/result_status.h" @@ -274,7 +275,7 @@ public: */ ResultStatus DecryptToFile( std::shared_ptr dest_file, - const ProgressCallback& callback = [](std::size_t, std::size_t) {}); + const Common::ProgressCallback& callback = [](std::size_t, std::size_t) {}); /** * Aborts DecryptToFile. Simply aborts the decryptor. diff --git a/src/core/quick_decryptor.cpp b/src/core/quick_decryptor.cpp index 758b015..4683fed 100644 --- a/src/core/quick_decryptor.cpp +++ b/src/core/quick_decryptor.cpp @@ -23,7 +23,7 @@ QuickDecryptor::~QuickDecryptor() = default; bool QuickDecryptor::DecryptAndWriteFile(std::shared_ptr source_, std::size_t size, std::shared_ptr destination_, - const ProgressCallback& callback_, bool decrypt_, + const Common::ProgressCallback& callback_, bool decrypt_, Core::Key::AESKey key_, Core::Key::AESKey ctr_, std::size_t aes_seek_pos_) { if (is_running) { diff --git a/src/core/quick_decryptor.h b/src/core/quick_decryptor.h index 125be6d..009bae0 100644 --- a/src/core/quick_decryptor.h +++ b/src/core/quick_decryptor.h @@ -9,14 +9,12 @@ #include #include #include "common/common_types.h" +#include "common/progress_callback.h" #include "common/thread.h" #include "core/key/key.h" namespace Core { -/// (current_size, total_size) -using ProgressCallback = std::function; - /** * Helper that reads, decrypts and writes data. This uses three threads to process the data * and call progress callbacks occasionally. @@ -41,8 +39,9 @@ public: bool DecryptAndWriteFile( std::shared_ptr source, std::size_t size, std::shared_ptr destination, - const ProgressCallback& callback = [](std::size_t, std::size_t) {}, bool decrypt = false, - Core::Key::AESKey key = {}, Core::Key::AESKey ctr = {}, std::size_t aes_seek_pos = 0); + const Common::ProgressCallback& callback = [](std::size_t, std::size_t) {}, + bool decrypt = false, Core::Key::AESKey key = {}, Core::Key::AESKey ctr = {}, + std::size_t aes_seek_pos = 0); void DataReadLoop(); void DataDecryptLoop(); @@ -79,7 +78,7 @@ private: std::unique_ptr decrypt_thread; std::unique_ptr write_thread; - ProgressCallback callback; + Common::ProgressCallback callback; Common::Event completion_event; bool is_good{true}; diff --git a/src/frontend/helpers/multi_job.h b/src/frontend/helpers/multi_job.h index 24c0546..e9257dc 100644 --- a/src/frontend/helpers/multi_job.h +++ b/src/frontend/helpers/multi_job.h @@ -7,6 +7,7 @@ #include #include #include +#include "common/progress_callback.h" #include "core/importer.h" class MultiJob : public QThread { @@ -14,7 +15,7 @@ class MultiJob : public QThread { public: using ExecuteFunc = std::function; + const Common::ProgressCallback&)>; using DeleteFunc = std::function; using AbortFunc = std::function; diff --git a/src/frontend/helpers/simple_job.h b/src/frontend/helpers/simple_job.h index 42931e6..47f77b8 100644 --- a/src/frontend/helpers/simple_job.h +++ b/src/frontend/helpers/simple_job.h @@ -7,6 +7,7 @@ #include #include #include "common/common_types.h" +#include "common/progress_callback.h" /** * Lightweight wrapper around QThread, for easy use with progressive jobs. @@ -15,8 +16,7 @@ class SimpleJob : public QThread { Q_OBJECT public: - using ProgressCallback = std::function; - using ExecuteFunc = std::function; + using ExecuteFunc = std::function; using AbortFunc = std::function; explicit SimpleJob(QObject* parent, ExecuteFunc execute, AbortFunc abort); diff --git a/src/frontend/import_dialog.cpp b/src/frontend/import_dialog.cpp index 943c998..05af983 100644 --- a/src/frontend/import_dialog.cpp +++ b/src/frontend/import_dialog.cpp @@ -21,6 +21,7 @@ #include #include "common/assert.h" #include "common/logging/log.h" +#include "common/progress_callback.h" #include "common/scope_exit.h" #include "frontend/helpers/multi_job.h" #include "frontend/helpers/simple_job.h" @@ -726,7 +727,7 @@ void ImportDialog::StartDumpingCXISingle(const Core::ContentSpecifier& specifier auto* job = new SimpleJob( this, - [this, specifier, path](const SimpleJob::ProgressCallback& callback) { + [this, specifier, path](const Common::ProgressCallback& callback) { if (!importer.DumpCXI(specifier, path.toStdString(), callback)) { FileUtil::Delete(path.toStdString()); return false; @@ -789,7 +790,7 @@ void ImportDialog::StartBatchDumpingCXI() { auto* job = new MultiJob( this, importer, std::move(to_import), [path](Core::SDMCImporter& importer, const Core::ContentSpecifier& specifier, - const Core::SDMCImporter::ProgressCallback& callback) { + const Common::ProgressCallback& callback) { return importer.DumpCXI(specifier, path.toStdString() + GetCXIFileName(specifier), callback); }, @@ -812,7 +813,7 @@ void ImportDialog::StartBuildingCIASingle(const Core::ContentSpecifier& specifie auto* job = new SimpleJob( this, - [this, specifier, path](const SimpleJob::ProgressCallback& callback) { + [this, specifier, path](const Common::ProgressCallback& callback) { if (!importer.BuildCIA(specifier, path.toStdString(), callback)) { FileUtil::Delete(path.toStdString()); return false; @@ -878,7 +879,7 @@ void ImportDialog::StartBatchBuildingCIA() { auto* job = new MultiJob( this, importer, std::move(to_import), [path](Core::SDMCImporter& importer, const Core::ContentSpecifier& specifier, - const Core::SDMCImporter::ProgressCallback& callback) { + const Common::ProgressCallback& callback) { return importer.BuildCIA(specifier, path.toStdString() + GetCIAFileName(specifier), callback); },