work_item_list.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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 22WorkItemList::~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 32WorkItemList::WorkItemList() 33 : status_(ADD_ITEM) { 34} 35 36bool 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 59void 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 72void WorkItemList::AddWorkItem(WorkItem* work_item) { 73 DCHECK(status_ == ADD_ITEM); 74 list_.push_back(work_item); 75} 76 77WorkItem* WorkItemList::AddCallbackWorkItem( 78 base::Callback<bool(const CallbackWorkItem&)> callback) { 79 WorkItem* item = WorkItem::CreateCallbackWorkItem(callback); 80 AddWorkItem(item); 81 return item; 82} 83 84WorkItem* 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 95WorkItem* 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 111WorkItem* WorkItemList::AddCreateDirWorkItem(const base::FilePath& path) { 112 WorkItem* item = WorkItem::CreateCreateDirWorkItem(path); 113 AddWorkItem(item); 114 return item; 115} 116 117WorkItem* 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 124WorkItem* 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 131WorkItem* 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 141WorkItem* 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 151WorkItem* 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 157WorkItem* 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 169WorkItem* 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 184WorkItem* 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 198WorkItem* 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 210WorkItem* 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//////////////////////////////////////////////////////////////////////////////// 220NoRollbackWorkItemList::~NoRollbackWorkItemList() { 221} 222 223bool 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 247void NoRollbackWorkItemList::Rollback() { 248 // Ignore rollback. 249} 250