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