diff --git a/src/core/importer.cpp b/src/core/importer.cpp index bed8bad..54d3293 100644 --- a/src/core/importer.cpp +++ b/src/core/importer.cpp @@ -94,6 +94,15 @@ void SDMCImporter::AbortImporting() { bool SDMCImporter::ImportContent(const ContentSpecifier& specifier, const Common::ProgressCallback& callback) { + if (!ImportContentImpl(specifier, callback)) { + DeleteContent(specifier); + return false; + } + return true; +} + +bool SDMCImporter::ImportContentImpl(const ContentSpecifier& specifier, + const Common::ProgressCallback& callback) { switch (specifier.type) { case ContentType::Application: case ContentType::Update: @@ -623,8 +632,13 @@ bool SDMCImporter::DumpCXI(const ContentSpecifier& specifier, std::string destin return false; } - return dump_cxi_ncch->DecryptToFile(std::make_shared(destination, "wb"), - callback) == ResultStatus::Success; + if (dump_cxi_ncch->DecryptToFile(std::make_shared(destination, "wb"), + callback) == ResultStatus::Success) { + return true; + } + + FileUtil::Delete(destination); + return false; } void SDMCImporter::AbortDumpCXI() { @@ -675,9 +689,10 @@ bool SDMCImporter::BuildCIA(const ContentSpecifier& specifier, std::string desti } } - bool ret = cia_builder->Init(destination, tmd, config, - FileUtil::GetDirectoryTreeSize(physical_path), callback); + const bool ret = cia_builder->Init(destination, tmd, config, + FileUtil::GetDirectoryTreeSize(physical_path), callback); if (!ret) { + FileUtil::Delete(destination); return false; } @@ -721,11 +736,14 @@ bool SDMCImporter::BuildCIA(const ContentSpecifier& specifier, std::string desti } }; - if (!FileUtil::ForeachDirectoryEntry(nullptr, physical_path, DirectoryEntryCallback)) { - return false; + if (FileUtil::ForeachDirectoryEntry(nullptr, physical_path, DirectoryEntryCallback) && + cia_builder->Finalize()) { + + return true; } - return cia_builder->Finalize(); + FileUtil::Delete(destination); + return false; } void SDMCImporter::AbortBuildCIA() { @@ -1055,7 +1073,7 @@ void SDMCImporter::ListSysdata(std::vector& out) const { {ContentType::Sysdata, 2, exists, FileUtil::GetSize(config.seed_db_path), SEED_DB}); } -void SDMCImporter::DeleteContent(const ContentSpecifier& specifier) { +void SDMCImporter::DeleteContent(const ContentSpecifier& specifier) const { switch (specifier.type) { case ContentType::Application: case ContentType::Update: diff --git a/src/core/importer.h b/src/core/importer.h index e65449a..ea9ed32 100644 --- a/src/core/importer.h +++ b/src/core/importer.h @@ -112,7 +112,7 @@ public: ~SDMCImporter(); /** - * Imports a specific content by its specifier. + * Imports a specific content by its specifier, deleting it when failed. * Blocks, but can be aborted on another thread if needed. * @return true on success, false otherwise */ @@ -151,12 +151,6 @@ public: */ void AbortBuildCIA(); - /** - * Deletes/Cleans up a content. Used for deleting contents that have - * not been fully imported. - */ - void DeleteContent(const ContentSpecifier& specifier); - /** * Gets a list of dumpable content specifiers. */ @@ -170,6 +164,10 @@ public: private: bool Init(); + // Impl of ImportContent without deleting mechanism. + bool ImportContentImpl( + const ContentSpecifier& specifier, + const Common::ProgressCallback& callback = [](std::size_t, std::size_t) {}); bool ImportTitle(const ContentSpecifier& specifier, const Common::ProgressCallback& callback); bool ImportNandTitle(const ContentSpecifier& specifier, const Common::ProgressCallback& callback); @@ -187,6 +185,7 @@ private: void ListSystemArchive(std::vector& out) const; void ListSysdata(std::vector& out) const; + void DeleteContent(const ContentSpecifier& specifier) const; void DeleteTitle(u64 id) const; void DeleteNandTitle(u64 id) const; void DeleteSavegame(u64 id) const; diff --git a/src/frontend/helpers/multi_job.cpp b/src/frontend/helpers/multi_job.cpp index 29bb802..477c69a 100644 --- a/src/frontend/helpers/multi_job.cpp +++ b/src/frontend/helpers/multi_job.cpp @@ -7,10 +7,9 @@ MultiJob::MultiJob(QObject* parent, Core::SDMCImporter& importer_, std::vector contents_, ExecuteFunc execute_func_, - DeleteFunc delete_func_, AbortFunc abort_func_) + AbortFunc abort_func_) : QThread(parent), importer(importer_), contents(std::move(contents_)), - execute_func(std::move(execute_func_)), delete_func(std::move(delete_func_)), - abort_func(abort_func_) {} + execute_func(std::move(execute_func_)), abort_func(abort_func_) {} MultiJob::~MultiJob() = default; @@ -42,8 +41,6 @@ void MultiJob::run() { emit ProgressUpdated(size_imported + current_size, current_size, eta); }; if (!execute_func(importer, content, callback)) { - delete_func(importer, content); - importer.DeleteContent(content); if (!cancelled) { failed_contents.emplace_back(content); } diff --git a/src/frontend/helpers/multi_job.h b/src/frontend/helpers/multi_job.h index e9257dc..d4ce957 100644 --- a/src/frontend/helpers/multi_job.h +++ b/src/frontend/helpers/multi_job.h @@ -16,12 +16,11 @@ class MultiJob : public QThread { public: using ExecuteFunc = std::function; - using DeleteFunc = std::function; using AbortFunc = std::function; explicit MultiJob(QObject* parent, Core::SDMCImporter& importer, std::vector contents, ExecuteFunc execute_func, - DeleteFunc delete_func, AbortFunc abort_func); + AbortFunc abort_func); ~MultiJob() override; void run() override; @@ -50,7 +49,6 @@ private: std::vector contents; std::vector failed_contents; ExecuteFunc execute_func; - DeleteFunc delete_func; AbortFunc abort_func; }; diff --git a/src/frontend/import_dialog.cpp b/src/frontend/import_dialog.cpp index 5e29d65..09e70f5 100644 --- a/src/frontend/import_dialog.cpp +++ b/src/frontend/import_dialog.cpp @@ -710,7 +710,7 @@ void ImportDialog::StartImporting() { auto* job = new MultiJob(this, importer, std::move(to_import), &Core::SDMCImporter::ImportContent, - &Core::SDMCImporter::DeleteContent, &Core::SDMCImporter::AbortImporting); + &Core::SDMCImporter::AbortImporting); RunMultiJob(job, total_count, total_selected_size); } @@ -728,11 +728,7 @@ void ImportDialog::StartDumpingCXISingle(const Core::ContentSpecifier& specifier auto* job = new SimpleJob( this, [this, specifier, path](const Common::ProgressCallback& callback) { - if (!importer.DumpCXI(specifier, path.toStdString(), callback)) { - FileUtil::Delete(path.toStdString()); - return false; - } - return true; + return importer.DumpCXI(specifier, path.toStdString(), callback); }, [this] { importer.AbortDumpCXI(); }); RunSimpleJob(job); @@ -786,9 +782,6 @@ void ImportDialog::StartBatchDumpingCXI() { const Common::ProgressCallback& callback) { return importer.DumpCXI(specifier, path.toStdString(), callback, true); }, - [path](Core::SDMCImporter& /*importer*/, const Core::ContentSpecifier& specifier) { - // TODO: FileUtil::Delete(path.toStdString() + GetCXIFileName(specifier)); - }, &Core::SDMCImporter::AbortDumpCXI); RunMultiJob(job, total_count, total_size); } @@ -806,11 +799,7 @@ void ImportDialog::StartBuildingCIASingle(const Core::ContentSpecifier& specifie auto* job = new SimpleJob( this, [this, specifier, path](const Common::ProgressCallback& callback) { - if (!importer.BuildCIA(specifier, path.toStdString(), callback)) { - FileUtil::Delete(path.toStdString()); - return false; - } - return true; + return importer.BuildCIA(specifier, path.toStdString(), callback); }, [this] { importer.AbortBuildCIA(); }); RunSimpleJob(job); @@ -868,9 +857,6 @@ void ImportDialog::StartBatchBuildingCIA() { const Common::ProgressCallback& callback) { return importer.BuildCIA(specifier, path.toStdString(), callback, true); }, - [path](Core::SDMCImporter& /*importer*/, const Core::ContentSpecifier& specifier) { - // TODO: FileUtil::Delete(path.toStdString() + GetCIAFileName(specifier)); - }, &Core::SDMCImporter::AbortBuildCIA); RunMultiJob(job, total_count, total_size); }