Пример #1
0
static int
merge_zip(struct zip *za, const char *tname, const char *sname,
	  struct zip **zsp)
{
    struct zip *zs;
    struct zip_source *source;
    int i, idx, err;
    char errstr[1024];
    const char *fname;
    
    if ((zs=zip_open(sname, 0, &err)) == NULL) {
	zip_error_to_str(errstr, sizeof(errstr), err, errno);
	fprintf(stderr, "%s: cannot open zip archive `%s': %s\n",
		prg, sname, errstr);
	return -1;
    }

    for (i=0; i<zip_get_num_files(zs); i++) {
	fname = zip_get_name(zs, i, 0);

	if ((idx=zip_name_locate(za, fname, name_flags)) != -1) {
	    switch (confirm_replace(za, tname, idx, zs, sname, i)) {
	    case 0:
		break;
		
	    case 1:
		if ((source=zip_source_zip(za, zs, i, 0, 0, 0)) == NULL
		    || zip_replace(za, idx, source) < 0) {
		    zip_source_free(source);
		    fprintf(stderr,
			    "%s: cannot replace `%s' in `%s': %s\n",
			    prg, fname, tname, zip_strerror(za));
		    return -1;
		}
		break;

	    case -1:
		zip_close(zs);
		return -1;
		
	    default:
		fprintf(stderr,	"%s: internal error: "
			"unexpected return code from confirm (%d)\n",
			prg, err);
		zip_close(zs);
		return -1;
	    }
	}
	else {
	    if ((source=zip_source_zip(za, zs, i, 0, 0, 0)) == NULL
		|| zip_add(za, fname, source) < 0) {
		zip_source_free(source);
		fprintf(stderr,
			"%s: cannot add `%s' to `%s': %s\n",
			prg, fname, tname, zip_strerror(za));
		zip_close(zs);
		return -1;
	    }
	}
    }

    *zsp = zs;
    return 0;
}
Пример #2
0
void GameList::CompressISO(bool decompress)
{
  auto files = GetSelectedGames();
  const auto game = GetSelectedGame();

  if (files.empty() || !game)
    return;

  bool wii_warning_given = false;
  for (QMutableListIterator<std::shared_ptr<const UICommon::GameFile>> it(files); it.hasNext();)
  {
    auto file = it.next();

    if ((file->GetPlatform() != DiscIO::Platform::GameCubeDisc &&
         file->GetPlatform() != DiscIO::Platform::WiiDisc) ||
        (decompress && file->GetBlobType() != DiscIO::BlobType::GCZ) ||
        (!decompress && file->GetBlobType() != DiscIO::BlobType::PLAIN))
    {
      it.remove();
      continue;
    }

    if (!wii_warning_given && !decompress && file->GetPlatform() == DiscIO::Platform::WiiDisc)
    {
      ModalMessageBox wii_warning(this);
      wii_warning.setIcon(QMessageBox::Warning);
      wii_warning.setWindowTitle(tr("Confirm"));
      wii_warning.setText(tr("Are you sure?"));
      wii_warning.setInformativeText(tr(
          "Compressing a Wii disc image will irreversibly change the compressed copy by removing "
          "padding data. Your disc image will still work. Continue?"));
      wii_warning.setStandardButtons(QMessageBox::Yes | QMessageBox::No);

      if (wii_warning.exec() == QMessageBox::No)
        return;

      wii_warning_given = true;
    }
  }

  QString dst_dir;
  QString dst_path;

  if (files.size() > 1)
  {
    dst_dir = QFileDialog::getExistingDirectory(
        this,
        decompress ? tr("Select where you want to save the decompressed images") :
                     tr("Select where you want to save the compressed images"),
        QFileInfo(QString::fromStdString(game->GetFilePath())).dir().absolutePath());

    if (dst_dir.isEmpty())
      return;
  }
  else
  {
    dst_path = QFileDialog::getSaveFileName(
        this,
        decompress ? tr("Select where you want to save the decompressed image") :
                     tr("Select where you want to save the compressed image"),
        QFileInfo(QString::fromStdString(game->GetFilePath()))
            .dir()
            .absoluteFilePath(
                QFileInfo(QString::fromStdString(files[0]->GetFilePath())).completeBaseName())
            .append(decompress ? QStringLiteral(".gcm") : QStringLiteral(".gcz")),
        decompress ? tr("Uncompressed GC/Wii images (*.iso *.gcm)") :
                     tr("Compressed GC/Wii images (*.gcz)"));

    if (dst_path.isEmpty())
      return;
  }

  for (const auto& file : files)
  {
    const auto original_path = file->GetFilePath();
    if (files.size() > 1)
    {
      dst_path =
          QDir(dst_dir)
              .absoluteFilePath(QFileInfo(QString::fromStdString(original_path)).completeBaseName())
              .append(decompress ? QStringLiteral(".gcm") : QStringLiteral(".gcz"));
      QFileInfo dst_info = QFileInfo(dst_path);
      if (dst_info.exists())
      {
        ModalMessageBox confirm_replace(this);
        confirm_replace.setIcon(QMessageBox::Warning);
        confirm_replace.setWindowTitle(tr("Confirm"));
        confirm_replace.setText(tr("The file %1 already exists.\n"
                                   "Do you wish to replace it?")
                                    .arg(dst_info.fileName()));
        confirm_replace.setStandardButtons(QMessageBox::Yes | QMessageBox::No);

        if (confirm_replace.exec() == QMessageBox::No)
          continue;
      }
    }

    QProgressDialog progress_dialog(decompress ? tr("Decompressing...") : tr("Compressing..."),
                                    tr("Abort"), 0, 100, this);
    progress_dialog.setWindowModality(Qt::WindowModal);
    progress_dialog.setWindowFlags(progress_dialog.windowFlags() &
                                   ~Qt::WindowContextHelpButtonHint);
    progress_dialog.setWindowTitle(tr("Progress"));

    bool good;

    if (decompress)
    {
      if (files.size() > 1)
        progress_dialog.setLabelText(tr("Decompressing...") + QStringLiteral("\n") +
                                     QFileInfo(QString::fromStdString(original_path)).fileName());
      good = DiscIO::DecompressBlobToFile(original_path, dst_path.toStdString(), &CompressCB,
                                          &progress_dialog);
    }
    else
    {
      if (files.size() > 1)
        progress_dialog.setLabelText(tr("Compressing...") + QStringLiteral("\n") +
                                     QFileInfo(QString::fromStdString(original_path)).fileName());
      good = DiscIO::CompressFileToBlob(original_path, dst_path.toStdString(),
                                        file->GetPlatform() == DiscIO::Platform::WiiDisc ? 1 : 0,
                                        16384, &CompressCB, &progress_dialog);
    }

    if (!good)
    {
      QErrorMessage(this).showMessage(tr("Dolphin failed to complete the requested action."));
      return;
    }
  }

  ModalMessageBox::information(this, tr("Success"),
                               decompress ?
                                   tr("Successfully decompressed %n image(s).", "", files.size()) :
                                   tr("Successfully compressed %n image(s).", "", files.size()));
}