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_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