Home | History | Annotate | Download | only in util
      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