Beispiel #1
0
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
  std::optional<Options> maybe_opts = ParseCommandLine(pCmdLine);
  if (!maybe_opts)
    return 1;
  Options opts = std::move(*maybe_opts);

  if (opts.log_file)
  {
    log_fp = _wfopen(UTF8ToUTF16(*opts.log_file).c_str(), L"w");
    if (!log_fp)
      log_fp = stderr;
    else
      atexit(FlushLog);
  }

  fprintf(log_fp, "Updating from: %s\n", opts.this_manifest_url.c_str());
  fprintf(log_fp, "Updating to:   %s\n", opts.next_manifest_url.c_str());
  fprintf(log_fp, "Install path:  %s\n", opts.install_base_path.c_str());

  if (!File::IsDirectory(opts.install_base_path))
  {
    fprintf(log_fp, "Cannot find install base path, or not a directory.\n");
    return 1;
  }

  if (opts.parent_pid)
  {
    fprintf(log_fp, "Waiting for parent PID %d to complete...\n", *opts.parent_pid);
    HANDLE parent_handle = OpenProcess(SYNCHRONIZE, FALSE, *opts.parent_pid);
    WaitForSingleObject(parent_handle, INFINITE);
    CloseHandle(parent_handle);
    fprintf(log_fp, "Completed! Proceeding with update.\n");
  }

  Manifest this_manifest, next_manifest;
  {
    std::optional<Manifest> maybe_manifest = FetchAndParseManifest(opts.this_manifest_url);
    if (!maybe_manifest)
    {
      fprintf(log_fp, "Could not fetch current manifest. Aborting.\n");
      return 1;
    }
    this_manifest = std::move(*maybe_manifest);

    maybe_manifest = FetchAndParseManifest(opts.next_manifest_url);
    if (!maybe_manifest)
    {
      fprintf(log_fp, "Could not fetch next manifest. Aborting.\n");
      return 1;
    }
    next_manifest = std::move(*maybe_manifest);
  }

  TodoList todo = ComputeActionsToDo(this_manifest, next_manifest);
  todo.Log();

  std::optional<std::string> maybe_temp_dir = FindOrCreateTempDir(opts.install_base_path);
  if (!maybe_temp_dir)
    return 1;
  std::string temp_dir = std::move(*maybe_temp_dir);

  bool ok = PerformUpdate(todo, opts.install_base_path, opts.content_store_url, temp_dir);
  if (!ok)
    fprintf(log_fp, "Failed to apply the update.\n");

  CleanUpTempDir(temp_dir, todo);
  return !ok;
}
bool RunUpdater(std::vector<std::string> args)
{
  std::optional<Options> maybe_opts = ParseCommandLine(args);

  if (!maybe_opts)
  {
    return false;
  }

  UI::Init();

  Options opts = std::move(*maybe_opts);

  if (opts.log_file)
  {
    log_fp = fopen(opts.log_file.value().c_str(), "w");
    if (!log_fp)
      log_fp = stderr;
    else
      atexit(FlushLog);
  }

  fprintf(log_fp, "Updating from: %s\n", opts.this_manifest_url.c_str());
  fprintf(log_fp, "Updating to:   %s\n", opts.next_manifest_url.c_str());
  fprintf(log_fp, "Install path:  %s\n", opts.install_base_path.c_str());

  if (!File::IsDirectory(opts.install_base_path))
  {
    FatalError("Cannot find install base path, or not a directory.");
    return false;
  }

  if (opts.parent_pid)
  {
    UI::SetDescription("Waiting for Dolphin to quit...");

    fprintf(log_fp, "Waiting for parent PID %d to complete...\n", *opts.parent_pid);

    auto pid = opts.parent_pid.value();

    UI::WaitForPID(static_cast<u32>(pid));

    fprintf(log_fp, "Completed! Proceeding with update.\n");
  }

  UI::SetVisible(true);

  UI::SetDescription("Fetching and parsing manifests...");

  Manifest this_manifest, next_manifest;
  {
    std::optional<Manifest> maybe_manifest = FetchAndParseManifest(opts.this_manifest_url);
    if (!maybe_manifest)
    {
      FatalError("Could not fetch current manifest. Aborting.");
      return false;
    }
    this_manifest = std::move(*maybe_manifest);

    maybe_manifest = FetchAndParseManifest(opts.next_manifest_url);
    if (!maybe_manifest)
    {
      FatalError("Could not fetch next manifest. Aborting.");
      return false;
    }
    next_manifest = std::move(*maybe_manifest);
  }

  UI::SetDescription("Computing what to do...");

  TodoList todo = ComputeActionsToDo(this_manifest, next_manifest);
  todo.Log();

  std::optional<std::string> maybe_temp_dir = FindOrCreateTempDir(opts.install_base_path);
  if (!maybe_temp_dir)
    return false;
  std::string temp_dir = std::move(*maybe_temp_dir);

  UI::SetDescription("Performing Update...");

  bool ok = PerformUpdate(todo, opts.install_base_path, opts.content_store_url, temp_dir);
  if (!ok)
  {
    FatalError("Failed to apply the update.");
    CleanUpTempDir(temp_dir, todo);
    return false;
  }

  UI::ResetCurrentProgress();
  UI::ResetTotalProgress();
  UI::SetCurrentMarquee(false);
  UI::SetTotalMarquee(false);
  UI::SetCurrentProgress(1, 1);
  UI::SetTotalProgress(1, 1);
  UI::SetDescription("Done!");

  // Let the user process that we are done.
  UI::Sleep(1);

  if (opts.binary_to_restart)
  {
    UI::LaunchApplication(opts.binary_to_restart.value());
  }

  UI::Stop();

  return true;
}