15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_INSTALLER_UTIL_WORK_ITEM_LIST_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_INSTALLER_UTIL_WORK_ITEM_LIST_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_forward.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/work_item.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FilePath;
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A WorkItem subclass that recursively contains a list of WorkItems. Thus it
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// provides functionalities to carry out or roll back the sequence of actions
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// defined by the list of WorkItems it contains.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The WorkItems are executed in the same order as they are added to the list.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WorkItemList : public WorkItem {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WorkItemList();
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Execute the WorkItems in the same order as they are added to the list.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It aborts as soon as one WorkItem fails.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Do();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Rollback the WorkItems in the reverse order as they are executed.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Rollback();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a WorkItem to the list.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A WorkItem can only be added to the list before the list's DO() is called.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Once a WorkItem is added to the list. The list owns the WorkItem.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AddWorkItem(WorkItem* work_item);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a CallbackWorkItem that invokes a callback.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WorkItem* AddCallbackWorkItem(
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Callback<bool(const CallbackWorkItem&)> callback);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a CopyTreeWorkItem to the list of work items.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See the NOTE in the documentation for the CopyTreeWorkItem class for
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // special considerations regarding |temp_dir|.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WorkItem* AddCopyTreeWorkItem(
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::wstring& source_path,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::wstring& dest_path,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::wstring& temp_dir,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CopyOverWriteOption overwrite_option,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::wstring& alternative_path = L"");
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a CreateDirWorkItem that creates a directory at the given path.
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual WorkItem* AddCreateDirWorkItem(const base::FilePath& path);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a CreateRegKeyWorkItem that creates a registry key at the given
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // path.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WorkItem* AddCreateRegKeyWorkItem(HKEY predefined_root,
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                            const std::wstring& path,
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                            REGSAM wow64_access);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a DeleteRegKeyWorkItem that deletes a registry key from the given
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // path.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WorkItem* AddDeleteRegKeyWorkItem(HKEY predefined_root,
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                            const std::wstring& path,
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                            REGSAM wow64_access);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a DeleteRegValueWorkItem that deletes registry value of type REG_SZ
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or REG_DWORD.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WorkItem* AddDeleteRegValueWorkItem(HKEY predefined_root,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              const std::wstring& key_path,
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                              REGSAM wow64_access,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              const std::wstring& value_name);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a DeleteTreeWorkItem that recursively deletes a file system
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // hierarchy at the given root path. A key file can be optionally specified
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by key_path.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WorkItem* AddDeleteTreeWorkItem(
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::FilePath& root_path,
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::FilePath& temp_path,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::vector<base::FilePath>& key_paths);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Same as above but without support for key files.
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual WorkItem* AddDeleteTreeWorkItem(const base::FilePath& root_path,
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          const base::FilePath& temp_path);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a MoveTreeWorkItem to the list of work items.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WorkItem* AddMoveTreeWorkItem(const std::wstring& source_path,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const std::wstring& dest_path,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const std::wstring& temp_dir,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        MoveTreeOption duplicate_option);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a SetRegValueWorkItem that sets a registry value with REG_SZ type
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // at the key with specified path.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WorkItem* AddSetRegValueWorkItem(HKEY predefined_root,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const std::wstring& key_path,
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           REGSAM wow64_access,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const std::wstring& value_name,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const std::wstring& value_data,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           bool overwrite);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a SetRegValueWorkItem that sets a registry value with REG_DWORD type
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // at the key with specified path.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WorkItem* AddSetRegValueWorkItem(HKEY predefined_root,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const std::wstring& key_path,
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           REGSAM wow64_access,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const std::wstring& value_name,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           DWORD value_data,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           bool overwrite);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a SetRegValueWorkItem that sets a registry value with REG_QWORD type
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // at the key with specified path.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WorkItem* AddSetRegValueWorkItem(HKEY predefined_root,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const std::wstring& key_path,
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           REGSAM wow64_access,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const std::wstring& value_name,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           int64 value_data,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           bool overwrite);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a SelfRegWorkItem that registers or unregisters a DLL at the
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // specified path. If user_level_registration is true, then alternate
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // registration and unregistration entry point names will be used.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WorkItem* AddSelfRegWorkItem(const std::wstring& dll_path,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       bool do_register,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       bool user_level_registration);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class WorkItem;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::list<WorkItem*> WorkItems;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef WorkItems::iterator WorkItemIterator;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ListStatus {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // List has not been executed. Ok to add new WorkItem.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_ITEM,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // List has been executed. Can not add new WorkItem.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LIST_EXECUTED,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // List has been executed and rolled back. No further action is acceptable.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LIST_ROLLED_BACK
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WorkItemList();
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListStatus status_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The list of WorkItems, in the order of them being added.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WorkItems list_;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The list of executed WorkItems, in the reverse order of them being
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // executed.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WorkItems executed_list_;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A specialization of WorkItemList that executes items in the list on a
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// best-effort basis.  Failure of individual items to execute does not prevent
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// subsequent items from being executed.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Also, as the class name suggests, Rollback is not possible.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NoRollbackWorkItemList : public WorkItemList {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~NoRollbackWorkItemList();
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Execute the WorkItems in the same order as they are added to the list.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If a WorkItem fails, the function will return failure but all other
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WorkItems will still be executed.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Do();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // No-op.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Rollback();
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_INSTALLER_UTIL_WORK_ITEM_LIST_H_
175