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