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 21WorkItemList::~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 31WorkItemList::WorkItemList() 32 : status_(ADD_ITEM) { 33} 34 35bool 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 58void 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 71void WorkItemList::AddWorkItem(WorkItem* work_item) { 72 DCHECK(status_ == ADD_ITEM); 73 list_.push_back(work_item); 74} 75 76WorkItem* WorkItemList::AddCallbackWorkItem( 77 base::Callback<bool(const CallbackWorkItem&)> callback) { 78 WorkItem* item = WorkItem::CreateCallbackWorkItem(callback); 79 AddWorkItem(item); 80 return item; 81} 82 83WorkItem* 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 99WorkItem* WorkItemList::AddCreateDirWorkItem(const base::FilePath& path) { 100 WorkItem* item = WorkItem::CreateCreateDirWorkItem(path); 101 AddWorkItem(item); 102 return item; 103} 104 105WorkItem* 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 114WorkItem* 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 123WorkItem* 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 134WorkItem* 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 144WorkItem* 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 150WorkItem* 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 162WorkItem* 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 178WorkItem* 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 194WorkItem* 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 211WorkItem* 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//////////////////////////////////////////////////////////////////////////////// 221NoRollbackWorkItemList::~NoRollbackWorkItemList() { 222} 223 224bool 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 248void NoRollbackWorkItemList::Rollback() { 249 // Ignore rollback. 250} 251