diff --git a/rpcs3/Crypto/unpkg.cpp b/rpcs3/Crypto/unpkg.cpp index de3a00db84..668d2bdcd3 100644 --- a/rpcs3/Crypto/unpkg.cpp +++ b/rpcs3/Crypto/unpkg.cpp @@ -295,6 +295,8 @@ bool pkg_install(const std::string& path, atomic_t& sync) decrypt(0, header.file_count * sizeof(PKGEntry), header.pkg_platform == PKG_PLATFORM_TYPE_PSP ? PKG_AES_KEY2 : dec_key.data()); } + size_t num_failures = 0; + std::vector entries(header.file_count); std::memcpy(entries.data(), buf.get(), entries.size() * sizeof(PKGEntry)); @@ -305,6 +307,7 @@ bool pkg_install(const std::string& path, atomic_t& sync) if (entry.name_size > 256) { + num_failures++; LOG_ERROR(LOADER, "PKG name size is too big (0x%x)", entry.name_size); continue; } @@ -341,18 +344,21 @@ bool pkg_install(const std::string& path, atomic_t& sync) if (fs::file out{path, fs::rewrite}) { + bool extract_success = true; for (u64 pos = 0; pos < entry.file_size; pos += BUF_SIZE) { const u64 block_size = std::min(BUF_SIZE, entry.file_size - pos); if (decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : dec_key.data()) != block_size) { + extract_success = false; LOG_ERROR(LOADER, "Failed to extract file %s", path); break; } if (out.write(buf.get(), block_size) != block_size) { + extract_success = false; LOG_ERROR(LOADER, "Failed to write file %s", path); break; } @@ -372,17 +378,25 @@ bool pkg_install(const std::string& path, atomic_t& sync) } } - if (did_overwrite) - { - LOG_WARNING(LOADER, "Overwritten file %s", name); + if (extract_success) + { + if (did_overwrite) + { + LOG_WARNING(LOADER, "Overwritten file %s", name); + } + else + { + LOG_NOTICE(LOADER, "Created file %s", name); + } } else { - LOG_NOTICE(LOADER, "Created file %s", name); + num_failures++; } } else { + num_failures++; LOG_ERROR(LOADER, "Failed to create file %s", path); } @@ -404,6 +418,7 @@ bool pkg_install(const std::string& path, atomic_t& sync) } else { + num_failures++; LOG_ERROR(LOADER, "Failed to create directory %s", path); } @@ -412,11 +427,20 @@ bool pkg_install(const std::string& path, atomic_t& sync) default: { + num_failures++; LOG_ERROR(LOADER, "Unknown PKG entry type (0x%x) %s", entry.type, name); } } } - LOG_SUCCESS(LOADER, "Package successfully installed to %s", dir); - return true; + if (num_failures == 0) + { + LOG_SUCCESS(LOADER, "Package successfully installed to %s", dir); + } + else + { + fs::remove_all(dir, true); + LOG_ERROR(LOADER, "Package installation failed: %s", dir); + } + return num_failures == 0; } diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index 90a5c79508..fa3ac7f68b 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -437,6 +437,8 @@ void main_window::InstallPkg(const QString& dropPath, bool is_bulk) // Synchronization variable atomic_t progress(0.); + bool cancelled = false; + // Run PKG unpacking asynchronously named_thread worker("PKG Installer", [&] { @@ -449,6 +451,7 @@ void main_window::InstallPkg(const QString& dropPath, bool is_bulk) { if (pdlg.wasCanceled()) { + cancelled = true; progress -= 1.; break; } @@ -465,6 +468,11 @@ void main_window::InstallPkg(const QString& dropPath, bool is_bulk) pdlg.SetValue(pdlg.maximum()); std::this_thread::sleep_for(100ms); } + else + { + pdlg.setHidden(true); + pdlg.SignalFailure(); + } } if (worker()) @@ -473,6 +481,11 @@ void main_window::InstallPkg(const QString& dropPath, bool is_bulk) LOG_SUCCESS(GENERAL, "Successfully installed %s.", fileName); guiSettings->ShowInfoBox(tr("Success!"), tr("Successfully installed software from package!"), gui::ib_pkg_success, this); } + else if (!cancelled) + { + LOG_ERROR(GENERAL, "Failed to install %s.", fileName); + QMessageBox::critical(this, tr("Failure!"), tr("Failed to install software from package %1!").arg(filePath)); + } } void main_window::InstallPup(const QString& dropPath)