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 // Base class for managing an action of a sequence of actions to be carried 6 // out during install/update/uninstall. Supports rollback of actions if this 7 // process fails. 8 9 #ifndef CHROME_INSTALLER_UTIL_WORK_ITEM_H_ 10 #define CHROME_INSTALLER_UTIL_WORK_ITEM_H_ 11 12 #include <windows.h> 13 14 #include <string> 15 #include <vector> 16 17 #include "base/basictypes.h" 18 #include "base/callback_forward.h" 19 20 class CallbackWorkItem; 21 class CopyRegKeyWorkItem; 22 class CopyTreeWorkItem; 23 class CreateDirWorkItem; 24 class CreateRegKeyWorkItem; 25 class DeleteTreeWorkItem; 26 class DeleteRegKeyWorkItem; 27 class DeleteRegValueWorkItem; 28 class MoveTreeWorkItem; 29 class SelfRegWorkItem; 30 class SetRegValueWorkItem; 31 class WorkItemList; 32 33 namespace base { 34 class FilePath; 35 } 36 37 // A base class that defines APIs to perform/rollback an action or a 38 // sequence of actions during install/update/uninstall. 39 class WorkItem { 40 public: 41 // Possible states 42 enum CopyOverWriteOption { 43 ALWAYS, // Always overwrite regardless of what existed before. 44 NEVER, // Not used currently. 45 IF_DIFFERENT, // Overwrite if different. Currently only applies to file. 46 IF_NOT_PRESENT, // Copy only if file/directory do not exist already. 47 NEW_NAME_IF_IN_USE // Copy to a new path if dest is in use(only files). 48 }; 49 50 // Options for the MoveTree work item. 51 enum MoveTreeOption { 52 ALWAYS_MOVE, // Always attempt to do a move operation. 53 CHECK_DUPLICATES // Only move if the move target is different. 54 }; 55 56 // Abstract base class for the conditions used by ConditionWorkItemList. 57 // TODO(robertshield): Move this out of WorkItem. 58 class Condition { 59 public: 60 virtual ~Condition() {} 61 virtual bool ShouldRun() const = 0; 62 }; 63 64 virtual ~WorkItem(); 65 66 // Create a CallbackWorkItem that invokes a callback. 67 static CallbackWorkItem* CreateCallbackWorkItem( 68 base::Callback<bool(const CallbackWorkItem&)> callback); 69 70 // Create a CopyRegKeyWorkItem that recursively copies a given registry key. 71 static CopyRegKeyWorkItem* CreateCopyRegKeyWorkItem( 72 HKEY predefined_root, 73 const std::wstring& source_key_path, 74 const std::wstring& dest_key_path, 75 CopyOverWriteOption overwrite_option); 76 77 // Create a CopyTreeWorkItem that recursively copies a file system hierarchy 78 // from source path to destination path. 79 // * If overwrite_option is ALWAYS, the created CopyTreeWorkItem always 80 // overwrites files. 81 // * If overwrite_option is NEW_NAME_IF_IN_USE, file is copied with an 82 // alternate name specified by alternative_path. 83 static CopyTreeWorkItem* CreateCopyTreeWorkItem( 84 const base::FilePath& source_path, 85 const base::FilePath& dest_path, 86 const base::FilePath& temp_dir, 87 CopyOverWriteOption overwrite_option, 88 const base::FilePath& alternative_path); 89 90 // Create a CreateDirWorkItem that creates a directory at the given path. 91 static CreateDirWorkItem* CreateCreateDirWorkItem(const base::FilePath& path); 92 93 // Create a CreateRegKeyWorkItem that creates a registry key at the given 94 // path. 95 static CreateRegKeyWorkItem* CreateCreateRegKeyWorkItem( 96 HKEY predefined_root, const std::wstring& path); 97 98 // Create a DeleteRegKeyWorkItem that deletes a registry key at the given 99 // path. 100 static DeleteRegKeyWorkItem* CreateDeleteRegKeyWorkItem( 101 HKEY predefined_root, const std::wstring& path); 102 103 // Create a DeleteRegValueWorkItem that deletes a registry value 104 static DeleteRegValueWorkItem* CreateDeleteRegValueWorkItem( 105 HKEY predefined_root, 106 const std::wstring& key_path, 107 const std::wstring& value_name); 108 109 // Create a DeleteTreeWorkItem that recursively deletes a file system 110 // hierarchy at the given root path. A key file can be optionally specified 111 // by key_path. 112 static DeleteTreeWorkItem* CreateDeleteTreeWorkItem( 113 const base::FilePath& root_path, 114 const base::FilePath& temp_path, 115 const std::vector<base::FilePath>& key_paths); 116 117 // Create a MoveTreeWorkItem that recursively moves a file system hierarchy 118 // from source path to destination path. 119 static MoveTreeWorkItem* CreateMoveTreeWorkItem( 120 const base::FilePath& source_path, 121 const base::FilePath& dest_path, 122 const base::FilePath& temp_dir, 123 MoveTreeOption duplicate_option); 124 125 // Create a SetRegValueWorkItem that sets a registry value with REG_SZ type 126 // at the key with specified path. 127 static SetRegValueWorkItem* CreateSetRegValueWorkItem( 128 HKEY predefined_root, 129 const std::wstring& key_path, 130 const std::wstring& value_name, 131 const std::wstring& value_data, 132 bool overwrite); 133 134 // Create a SetRegValueWorkItem that sets a registry value with REG_DWORD type 135 // at the key with specified path. 136 static SetRegValueWorkItem* CreateSetRegValueWorkItem( 137 HKEY predefined_root, 138 const std::wstring& key_path, 139 const std::wstring& value_name, 140 DWORD value_data, bool overwrite); 141 142 // Create a SetRegValueWorkItem that sets a registry value with REG_QWORD type 143 // at the key with specified path. 144 static SetRegValueWorkItem* CreateSetRegValueWorkItem( 145 HKEY predefined_root, 146 const std::wstring& key_path, 147 const std::wstring& value_name, 148 int64 value_data, bool overwrite); 149 150 // Add a SelfRegWorkItem that registers or unregisters a DLL at the 151 // specified path. 152 static SelfRegWorkItem* CreateSelfRegWorkItem(const std::wstring& dll_path, 153 bool do_register, 154 bool user_level_registration); 155 156 // Create an empty WorkItemList. A WorkItemList can recursively contains 157 // a list of WorkItems. 158 static WorkItemList* CreateWorkItemList(); 159 160 // Create an empty WorkItemList that cannot be rolled back. 161 // Such a work item list executes all items on a best effort basis and does 162 // not abort execution if an item in the list fails. 163 static WorkItemList* CreateNoRollbackWorkItemList(); 164 165 // Create a conditional work item list that will execute only if 166 // condition->ShouldRun() returns true. The WorkItemList instance 167 // assumes ownership of condition. 168 static WorkItemList* CreateConditionalWorkItemList(Condition* condition); 169 170 // Perform the actions of WorkItem. Returns true if success, returns false 171 // otherwise. 172 // If the WorkItem is transactional, then Do() is done as a transaction. 173 // If it returns false, there will be no change on the system. 174 virtual bool Do() = 0; 175 176 // Rollback any actions previously carried out by this WorkItem. If the 177 // WorkItem is transactional, then the previous actions can be fully 178 // rolled back. If the WorkItem is non-transactional, the rollback is a 179 // best effort. 180 virtual void Rollback() = 0; 181 182 // If called with true, this WorkItem may return true from its Do() method 183 // even on failure and Rollback will have no effect. 184 void set_ignore_failure(bool ignore_failure) { 185 ignore_failure_ = ignore_failure; 186 } 187 188 // Returns true if this WorkItem should ignore failures. 189 bool ignore_failure() const { 190 return ignore_failure_; 191 } 192 193 // Sets an optional log message that a work item may use to print additional 194 // instance-specific information. 195 void set_log_message(const std::string& log_message) { 196 log_message_ = log_message; 197 } 198 199 // Retrieves the optional log message. The retrieved string may be empty. 200 const std::string& log_message() const { return log_message_; } 201 202 protected: 203 WorkItem(); 204 205 // Specifies whether this work item my fail to complete and yet still 206 // return true from Do(). 207 bool ignore_failure_; 208 209 std::string log_message_; 210 }; 211 212 #endif // CHROME_INSTALLER_UTIL_WORK_ITEM_H_ 213