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 #include "chrome/installer/util/work_item_list.h" 6 7 #include "base/files/file_path.h" 8 #include "base/logging.h" 9 #include "chrome/installer/util/callback_work_item.h" 10 #include "chrome/installer/util/copy_reg_key_work_item.h" 11 #include "chrome/installer/util/copy_tree_work_item.h" 12 #include "chrome/installer/util/create_dir_work_item.h" 13 #include "chrome/installer/util/create_reg_key_work_item.h" 14 #include "chrome/installer/util/delete_reg_key_work_item.h" 15 #include "chrome/installer/util/delete_reg_value_work_item.h" 16 #include "chrome/installer/util/delete_tree_work_item.h" 17 #include "chrome/installer/util/logging_installer.h" 18 #include "chrome/installer/util/move_tree_work_item.h" 19 #include "chrome/installer/util/self_reg_work_item.h" 20 #include "chrome/installer/util/set_reg_value_work_item.h" 21 22 WorkItemList::~WorkItemList() { 23 for (WorkItemIterator itr = list_.begin(); itr != list_.end(); ++itr) { 24 delete (*itr); 25 } 26 for (WorkItemIterator itr = executed_list_.begin(); 27 itr != executed_list_.end(); ++itr) { 28 delete (*itr); 29 } 30 } 31 32 WorkItemList::WorkItemList() 33 : status_(ADD_ITEM) { 34 } 35 36 bool WorkItemList::Do() { 37 if (status_ != ADD_ITEM) 38 return false; 39 40 bool result = true; 41 while (!list_.empty()) { 42 WorkItem* work_item = list_.front(); 43 list_.pop_front(); 44 executed_list_.push_front(work_item); 45 if (!work_item->Do()) { 46 LOG(ERROR) << "item execution failed " << work_item->log_message(); 47 result = false; 48 break; 49 } 50 } 51 52 if (result) 53 VLOG(1) << "list execution succeeded"; 54 55 status_ = LIST_EXECUTED; 56 return result; 57 } 58 59 void WorkItemList::Rollback() { 60 if (status_ != LIST_EXECUTED) 61 return; 62 63 for (WorkItemIterator itr = executed_list_.begin(); 64 itr != executed_list_.end(); ++itr) { 65 (*itr)->Rollback(); 66 } 67 68 status_ = LIST_ROLLED_BACK; 69 return; 70 } 71 72 void WorkItemList::AddWorkItem(WorkItem* work_item) { 73 DCHECK(status_ == ADD_ITEM); 74 list_.push_back(work_item); 75 } 76 77 WorkItem* WorkItemList::AddCallbackWorkItem( 78 base::Callback<bool(const CallbackWorkItem&)> callback) { 79 WorkItem* item = WorkItem::CreateCallbackWorkItem(callback); 80 AddWorkItem(item); 81 return item; 82 } 83 84 WorkItem* WorkItemList::AddCopyRegKeyWorkItem( 85 HKEY predefined_root, 86 const std::wstring& source_key_path, 87 const std::wstring& dest_key_path, 88 CopyOverWriteOption overwrite_option) { 89 WorkItem* item = WorkItem::CreateCopyRegKeyWorkItem( 90 predefined_root, source_key_path, dest_key_path, overwrite_option); 91 AddWorkItem(item); 92 return item; 93 } 94 95 WorkItem* WorkItemList::AddCopyTreeWorkItem( 96 const std::wstring& source_path, 97 const std::wstring& dest_path, 98 const std::wstring& temp_dir, 99 CopyOverWriteOption overwrite_option, 100 const std::wstring& alternative_path) { 101 WorkItem* item = WorkItem::CreateCopyTreeWorkItem( 102 base::FilePath(source_path), 103 base::FilePath(dest_path), 104 base::FilePath(temp_dir), 105 overwrite_option, 106 base::FilePath(alternative_path)); 107 AddWorkItem(item); 108 return item; 109 } 110 111 WorkItem* WorkItemList::AddCreateDirWorkItem(const base::FilePath& path) { 112 WorkItem* item = WorkItem::CreateCreateDirWorkItem(path); 113 AddWorkItem(item); 114 return item; 115 } 116 117 WorkItem* WorkItemList::AddCreateRegKeyWorkItem(HKEY predefined_root, 118 const std::wstring& path) { 119 WorkItem* item = WorkItem::CreateCreateRegKeyWorkItem(predefined_root, path); 120 AddWorkItem(item); 121 return item; 122 } 123 124 WorkItem* WorkItemList::AddDeleteRegKeyWorkItem(HKEY predefined_root, 125 const std::wstring& path) { 126 WorkItem* item = WorkItem::CreateDeleteRegKeyWorkItem(predefined_root, path); 127 AddWorkItem(item); 128 return item; 129 } 130 131 WorkItem* WorkItemList::AddDeleteRegValueWorkItem( 132 HKEY predefined_root, 133 const std::wstring& key_path, 134 const std::wstring& value_name) { 135 WorkItem* item = WorkItem::CreateDeleteRegValueWorkItem(predefined_root, 136 key_path, value_name); 137 AddWorkItem(item); 138 return item; 139 } 140 141 WorkItem* WorkItemList::AddDeleteTreeWorkItem( 142 const base::FilePath& root_path, 143 const base::FilePath& temp_path, 144 const std::vector<base::FilePath>& key_paths) { 145 WorkItem* item = WorkItem::CreateDeleteTreeWorkItem(root_path, temp_path, 146 key_paths); 147 AddWorkItem(item); 148 return item; 149 } 150 151 WorkItem* WorkItemList::AddDeleteTreeWorkItem(const base::FilePath& root_path, 152 const base::FilePath& temp_path) { 153 std::vector<base::FilePath> no_key_files; 154 return AddDeleteTreeWorkItem(root_path, temp_path, no_key_files); 155 } 156 157 WorkItem* WorkItemList::AddMoveTreeWorkItem(const std::wstring& source_path, 158 const std::wstring& dest_path, 159 const std::wstring& temp_dir, 160 MoveTreeOption duplicate_option) { 161 WorkItem* item = WorkItem::CreateMoveTreeWorkItem(base::FilePath(source_path), 162 base::FilePath(dest_path), 163 base::FilePath(temp_dir), 164 duplicate_option); 165 AddWorkItem(item); 166 return item; 167 } 168 169 WorkItem* WorkItemList::AddSetRegValueWorkItem( 170 HKEY predefined_root, 171 const std::wstring& key_path, 172 const std::wstring& value_name, 173 const std::wstring& value_data, 174 bool overwrite) { 175 WorkItem* item = WorkItem::CreateSetRegValueWorkItem(predefined_root, 176 key_path, 177 value_name, 178 value_data, 179 overwrite); 180 AddWorkItem(item); 181 return item; 182 } 183 184 WorkItem* WorkItemList::AddSetRegValueWorkItem(HKEY predefined_root, 185 const std::wstring& key_path, 186 const std::wstring& value_name, 187 DWORD value_data, 188 bool overwrite) { 189 WorkItem* item = WorkItem::CreateSetRegValueWorkItem(predefined_root, 190 key_path, 191 value_name, 192 value_data, 193 overwrite); 194 AddWorkItem(item); 195 return item; 196 } 197 198 WorkItem* WorkItemList::AddSetRegValueWorkItem(HKEY predefined_root, 199 const std::wstring& key_path, 200 const std::wstring& value_name, 201 int64 value_data, 202 bool overwrite) { 203 WorkItem* item = reinterpret_cast<WorkItem*>( 204 WorkItem::CreateSetRegValueWorkItem(predefined_root, key_path, value_name, 205 value_data, overwrite)); 206 AddWorkItem(item); 207 return item; 208 } 209 210 WorkItem* WorkItemList::AddSelfRegWorkItem(const std::wstring& dll_path, 211 bool do_register, 212 bool user_level_registration) { 213 WorkItem* item = WorkItem::CreateSelfRegWorkItem(dll_path, do_register, 214 user_level_registration); 215 AddWorkItem(item); 216 return item; 217 } 218 219 //////////////////////////////////////////////////////////////////////////////// 220 NoRollbackWorkItemList::~NoRollbackWorkItemList() { 221 } 222 223 bool NoRollbackWorkItemList::Do() { 224 if (status_ != ADD_ITEM) 225 return false; 226 227 bool result = true; 228 while (!list_.empty()) { 229 WorkItem* work_item = list_.front(); 230 list_.pop_front(); 231 executed_list_.push_front(work_item); 232 work_item->set_ignore_failure(true); 233 if (!work_item->Do()) { 234 LOG(ERROR) << "NoRollbackWorkItemList: item execution failed " 235 << work_item->log_message(); 236 result = false; 237 } 238 } 239 240 if (result) 241 VLOG(1) << "NoRollbackWorkItemList: list execution succeeded"; 242 243 status_ = LIST_EXECUTED; 244 return result; 245 } 246 247 void NoRollbackWorkItemList::Rollback() { 248 // Ignore rollback. 249 } 250