Fail pkg_install if any files fail to be created

This could happen if eg. paths are too long or some files
could not be overwritten. Until now, installation happily
reported success regardless.
This commit is contained in:
Silent 2019-10-06 12:30:48 +02:00 committed by Ivan
parent 9e66f36942
commit b591633cb9
2 changed files with 43 additions and 6 deletions

View File

@ -295,6 +295,8 @@ bool pkg_install(const std::string& path, atomic_t<double>& 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<PKGEntry> 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<double>& 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<double>& 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<u64>(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<double>& 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<double>& 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<double>& 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;
}

View File

@ -437,6 +437,8 @@ void main_window::InstallPkg(const QString& dropPath, bool is_bulk)
// Synchronization variable
atomic_t<double> 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)