1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_INSTALLER_UTIL_COPY_TREE_WORK_ITEM_H_ 6 #define CHROME_INSTALLER_UTIL_COPY_TREE_WORK_ITEM_H_ 7 8 #include "base/files/file_path.h" 9 #include "base/files/scoped_temp_dir.h" 10 #include "base/gtest_prod_util.h" 11 #include "chrome/installer/util/work_item.h" 12 13 // A WorkItem subclass that recursively copies a file system hierarchy from 14 // source path to destination path. It also creates all necessary intermediate 15 // paths of the destination path if they do not exist. The file system 16 // hierarchy could be a single file, or a directory. 17 // Under the cover CopyTreeWorkItem moves the destination path, if existing, 18 // to the temporary directory passed in, and then copies the source hierarchy 19 // to the destination location. During rollback the original destination 20 // hierarchy is moved back. 21 // NOTE: It is a best practice to ensure that the temporary directory is on the 22 // same volume as the destination path. If this is not the case, the existing 23 // destination path is not moved, but rather copied, to the destination path. 24 // This will result in in-use files being left behind, as well as potentially 25 // losing ACLs or other metadata in the case of a rollback. 26 class CopyTreeWorkItem : public WorkItem { 27 public: 28 virtual ~CopyTreeWorkItem(); 29 30 virtual bool Do(); 31 32 virtual void Rollback(); 33 34 private: 35 friend class WorkItem; 36 37 // See comments on corresponding member variables for the semantics of 38 // arguments. 39 // Notes on temp_path: to facilitate rollback, the caller needs to supply 40 // a temporary directory to save the original files if they exist under 41 // dest_path. 42 CopyTreeWorkItem(const base::FilePath& source_path, 43 const base::FilePath& dest_path, 44 const base::FilePath& temp_dir, 45 CopyOverWriteOption overwrite_option, 46 const base::FilePath& alternative_path); 47 48 // Checks if the path specified is in use (and hence can not be deleted) 49 bool IsFileInUse(const base::FilePath& path); 50 51 // Source path to copy files from. 52 base::FilePath source_path_; 53 54 // Destination path to copy files to. 55 base::FilePath dest_path_; 56 57 // Temporary directory that can be used. 58 base::FilePath temp_dir_; 59 60 // Controls the behavior for overwriting. 61 CopyOverWriteOption overwrite_option_; 62 63 // If overwrite_option_ = NEW_NAME_IF_IN_USE, this variables stores the path 64 // to be used if the file is in use and hence we want to copy it to a 65 // different path. 66 base::FilePath alternative_path_; 67 68 // Whether the source was copied to dest_path_ 69 bool copied_to_dest_path_; 70 71 // Whether the original files have been moved to backup path under 72 // temporary directory. If true, moving back is needed during rollback. 73 bool moved_to_backup_; 74 75 // Whether the source was copied to alternative_path_ because dest_path_ 76 // existed and was in use. Needed during rollback. 77 bool copied_to_alternate_path_; 78 79 // The temporary directory into which the original dest_path_ has been moved. 80 base::ScopedTempDir backup_path_; 81 82 FRIEND_TEST_ALL_PREFIXES(CopyTreeWorkItemTest, CopyFileSameContent); 83 FRIEND_TEST_ALL_PREFIXES(CopyTreeWorkItemTest, CopyFileInUse); 84 FRIEND_TEST_ALL_PREFIXES(CopyTreeWorkItemTest, CopyFileAndCleanup); 85 FRIEND_TEST_ALL_PREFIXES(CopyTreeWorkItemTest, NewNameAndCopyTest); 86 FRIEND_TEST_ALL_PREFIXES(CopyTreeWorkItemTest, CopyFileInUseAndCleanup); 87 }; 88 89 #endif // CHROME_INSTALLER_UTIL_COPY_TREE_WORK_ITEM_H_ 90