// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_INSTALLER_SETUP_ARCHIVE_PATCH_HELPER_H_ #define CHROME_INSTALLER_SETUP_ARCHIVE_PATCH_HELPER_H_ #include "base/basictypes.h" #include "base/files/file_path.h" namespace installer { // A helper class that facilitates uncompressing and patching the chrome archive // and installer. // // Chrome's installer is deployed along with a compressed archive containing // either 1) an uncompressd archive of the product binaries or 2) a patch file // to be applied to the uncompressed archive of the version being updated. To // obtain the uncompressed archive, the contents of the compressed archive are // uncompressed and extracted. Installation proceeds directly if the // uncompressed archive is found after this step. Otherwise, the patch is // applied to the previous version's uncompressed archive using either // Courgette's ensemble patching or bspatch. // // Chrome's installer itself may also be deployed as a patch against the // previous version's saved installer binary. The same process is followed to // obtain the new installer. The compressed archive unconditionally contains a // patch file in this case. class ArchivePatchHelper { public: // Constructs an instance that can uncompress |compressed_archive| into // |working_directory| and optionally apply the extracted patch file to // |patch_source|, writing the result to |target|. ArchivePatchHelper(const base::FilePath& working_directory, const base::FilePath& compressed_archive, const base::FilePath& patch_source, const base::FilePath& target); ~ArchivePatchHelper(); // Uncompresses |compressed_archive| in |working_directory| then applies the // extracted patch file to |patch_source|, writing the result to |target|. // Ensemble patching via Courgette is attempted first. If that fails, bspatch // is attempted. Returns false if uncompression or both patching steps fail. static bool UncompressAndPatch(const base::FilePath& working_directory, const base::FilePath& compressed_archive, const base::FilePath& patch_source, const base::FilePath& target); // Uncompresses compressed_archive() into the working directory. On success, // last_uncompressed_file (if not NULL) is populated with the path to the last // file extracted from the archive. bool Uncompress(base::FilePath* last_uncompressed_file); // Attempts to use courgette to apply last_uncompressed_file() to // patch_source() to generate target(). Returns false if patching fails. bool EnsemblePatch(); // Attempts to use bspatch to apply last_uncompressed_file() to patch_source() // to generate target(). Returns false if patching fails. bool BinaryPatch(); const base::FilePath& compressed_archive() const { return compressed_archive_; } void set_patch_source(const base::FilePath& patch_source) { patch_source_ = patch_source; } const base::FilePath& patch_source() const { return patch_source_; } const base::FilePath& target() const { return target_; } // Returns the path of the last file extracted by Uncompress(). const base::FilePath& last_uncompressed_file() const { return last_uncompressed_file_; } void set_last_uncompressed_file( const base::FilePath& last_uncompressed_file) { last_uncompressed_file_ = last_uncompressed_file; } private: base::FilePath working_directory_; base::FilePath compressed_archive_; base::FilePath patch_source_; base::FilePath target_; base::FilePath last_uncompressed_file_; DISALLOW_COPY_AND_ASSIGN(ArchivePatchHelper); }; } // namespace installer #endif // CHROME_INSTALLER_SETUP_ARCHIVE_PATCH_HELPER_H_