summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-24 20:58:35 +0000
committertommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-24 20:58:35 +0000
commitcd9a8e7e38c98a91d86c92084b3f7dd59c9bfa67 (patch)
tree9ee73b0107de33999df45c83c5e3a2d99d76516e
parent9b444619c6a49b3798a85ee95eb93cd5eca65694 (diff)
downloadchromium_src-cd9a8e7e38c98a91d86c92084b3f7dd59c9bfa67.zip
chromium_src-cd9a8e7e38c98a91d86c92084b3f7dd59c9bfa67.tar.gz
chromium_src-cd9a8e7e38c98a91d86c92084b3f7dd59c9bfa67.tar.bz2
Add a new type of WorkItemList: NoRollbackWorkItemList.
This list does a best-effort execution of the items in the work list and always executes all items even if one of the items fails. Because of this, the list does also not support Rollback. The usage for this list is intended for uninstallation actions such as when unregistering a COM dll fails and we cannot "rollback" from it since we don't know what went wrong, what is the current state, etc and rolling back would really mean to re-register the DLL. Same applies for registry keys and files that might have been removed by the user. I also added a basic implementation of the Dump() method to all WorkItem derived classes for better diagnostics in the future. BUG=61609 TEST=The class is only used in a pending change list, so there should be no change in current behavior. Review URL: http://codereview.chromium.org/5260002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67309 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/installer/util/copy_tree_work_item.h5
-rw-r--r--chrome/installer/util/create_reg_key_work_item.h4
-rw-r--r--chrome/installer/util/delete_reg_value_work_item.h4
-rw-r--r--chrome/installer/util/delete_tree_work_item.h3
-rw-r--r--chrome/installer/util/self_reg_work_item.cc31
-rw-r--r--chrome/installer/util/set_reg_value_work_item.h4
-rw-r--r--chrome/installer/util/work_item.cc5
-rw-r--r--chrome/installer/util/work_item.h8
-rw-r--r--chrome/installer/util/work_item_list.cc32
-rw-r--r--chrome/installer/util/work_item_list.h19
10 files changed, 89 insertions, 26 deletions
diff --git a/chrome/installer/util/copy_tree_work_item.h b/chrome/installer/util/copy_tree_work_item.h
index 4d9a984..2c77237 100644
--- a/chrome/installer/util/copy_tree_work_item.h
+++ b/chrome/installer/util/copy_tree_work_item.h
@@ -6,9 +6,10 @@
#define CHROME_INSTALLER_UTIL_COPY_TREE_WORK_ITEM_H_
#pragma once
-#include <string>
#include <windows.h>
+#include <string>
+
#include "base/file_path.h"
#include "chrome/installer/util/work_item.h"
@@ -31,7 +32,7 @@ class CopyTreeWorkItem : public WorkItem {
private:
friend class WorkItem;
- // See comments on corresponding member varibles for the semantics of
+ // See comments on corresponding member variables for the semantics of
// arguments.
// Notes on temp_path: to facilitate rollback, the caller needs to supply
// a temporary directory to save the original files if they exist under
diff --git a/chrome/installer/util/create_reg_key_work_item.h b/chrome/installer/util/create_reg_key_work_item.h
index 2cd5115..66afce8 100644
--- a/chrome/installer/util/create_reg_key_work_item.h
+++ b/chrome/installer/util/create_reg_key_work_item.h
@@ -6,11 +6,11 @@
#define CHROME_INSTALLER_UTIL_CREATE_REG_KEY_WORK_ITEM_H__
#pragma once
+#include <windows.h>
+
#include <string>
#include <vector>
-#include <windows.h>
-
#include "chrome/installer/util/work_item.h"
// A WorkItem subclass that creates a registry key at the given path.
diff --git a/chrome/installer/util/delete_reg_value_work_item.h b/chrome/installer/util/delete_reg_value_work_item.h
index e04d4e4..0c0c228 100644
--- a/chrome/installer/util/delete_reg_value_work_item.h
+++ b/chrome/installer/util/delete_reg_value_work_item.h
@@ -6,8 +6,10 @@
#define CHROME_INSTALLER_UTIL_DELETE_REG_VALUE_WORK_ITEM_H_
#pragma once
-#include <string>
#include <windows.h>
+
+#include <string>
+
#include "chrome/installer/util/work_item.h"
// A WorkItem subclass that sets a registry value with REG_SZ or REG_DWORD
diff --git a/chrome/installer/util/delete_tree_work_item.h b/chrome/installer/util/delete_tree_work_item.h
index 30ab328..e7cc4c9b 100644
--- a/chrome/installer/util/delete_tree_work_item.h
+++ b/chrome/installer/util/delete_tree_work_item.h
@@ -6,9 +6,10 @@
#define CHROME_INSTALLER_UTIL_DELETE_TREE_WORK_ITEM_H_
#pragma once
-#include <string>
#include <windows.h>
+#include <string>
+
#include "base/file_path.h"
#include "chrome/installer/util/work_item.h"
diff --git a/chrome/installer/util/self_reg_work_item.cc b/chrome/installer/util/self_reg_work_item.cc
index 65832dc..831d2cd 100644
--- a/chrome/installer/util/self_reg_work_item.cc
+++ b/chrome/installer/util/self_reg_work_item.cc
@@ -5,6 +5,7 @@
#include "chrome/installer/util/self_reg_work_item.h"
#include "base/logging.h"
+#include "base/string_util.h"
#include "chrome/installer/util/logging_installer.h"
// Default registration export names.
@@ -27,33 +28,39 @@ SelfRegWorkItem::~SelfRegWorkItem() {
bool SelfRegWorkItem::RegisterDll(bool do_register) {
VLOG(1) << "COM " << (do_register ? "registration of " : "unregistration of ")
- << dll_path_;
+ << dll_path_;
HMODULE dll_module = ::LoadLibraryEx(dll_path_.c_str(), NULL,
LOAD_WITH_ALTERED_SEARCH_PATH);
bool success = false;
if (NULL != dll_module) {
- PROC register_server_func = NULL;
+ typedef HRESULT (WINAPI* RegisterFunc)();
+ RegisterFunc register_server_func = NULL;
if (do_register) {
- register_server_func = ::GetProcAddress(dll_module,
- user_level_registration_ ? kUserRegistrationEntryPoint :
- kDefaultRegistrationEntryPoint);
+ register_server_func = reinterpret_cast<RegisterFunc>(
+ ::GetProcAddress(dll_module, user_level_registration_ ?
+ kUserRegistrationEntryPoint : kDefaultRegistrationEntryPoint));
} else {
- register_server_func = ::GetProcAddress(dll_module,
- user_level_registration_ ? kUserUnregistrationEntryPoint :
- kDefaultUnregistrationEntryPoint);
+ register_server_func = reinterpret_cast<RegisterFunc>(
+ ::GetProcAddress(dll_module, user_level_registration_ ?
+ kUserUnregistrationEntryPoint :
+ kDefaultUnregistrationEntryPoint));
}
if (NULL != register_server_func) {
- success = SUCCEEDED(register_server_func());
+ HRESULT hr = register_server_func();
+ success = SUCCEEDED(hr);
if (!success) {
- LOG(ERROR) << "Failed to " << (do_register ? "register" : "unregister")
- << " DLL at " << dll_path_.c_str();
+ PLOG(ERROR) << "Failed to " << (do_register ? "register" : "unregister")
+ << " DLL at " << dll_path_.c_str() <<
+ StringPrintf(" 0x%08X", hr);
}
+ } else {
+ LOG(ERROR) << "COM registration export function not found";
}
::FreeLibrary(dll_module);
} else {
- LOG(WARNING) << "Failed to load: " << dll_path_;
+ PLOG(WARNING) << "Failed to load: " << dll_path_;
}
return success;
}
diff --git a/chrome/installer/util/set_reg_value_work_item.h b/chrome/installer/util/set_reg_value_work_item.h
index dc88991..1527784 100644
--- a/chrome/installer/util/set_reg_value_work_item.h
+++ b/chrome/installer/util/set_reg_value_work_item.h
@@ -6,8 +6,10 @@
#define CHROME_INSTALLER_UTIL_SET_REG_VALUE_WORK_ITEM_H__
#pragma once
-#include <string>
#include <windows.h>
+
+#include <string>
+
#include "chrome/installer/util/work_item.h"
// A WorkItem subclass that sets a registry value with REG_SZ or REG_DWORD
diff --git a/chrome/installer/util/work_item.cc b/chrome/installer/util/work_item.cc
index 06b5663..0af9060 100644
--- a/chrome/installer/util/work_item.cc
+++ b/chrome/installer/util/work_item.cc
@@ -89,6 +89,7 @@ WorkItemList* WorkItem::CreateWorkItemList() {
return new WorkItemList();
}
-std::wstring WorkItem::Dump() {
- return std::wstring(L"Work Item");
+// static
+WorkItemList* WorkItem::CreateNoRollbackWorkItemList() {
+ return new NoRollbackWorkItemList();
}
diff --git a/chrome/installer/util/work_item.h b/chrome/installer/util/work_item.h
index bf85b4d..3294746 100644
--- a/chrome/installer/util/work_item.h
+++ b/chrome/installer/util/work_item.h
@@ -107,6 +107,11 @@ class WorkItem {
// a list of WorkItems.
static WorkItemList* CreateWorkItemList();
+ // Create an empty WorkItemList that cannot be rolled back.
+ // Such a work item list executes all items on a best effort basis and does
+ // not abort execution if an item in the list fails.
+ static WorkItemList* CreateNoRollbackWorkItemList();
+
// Perform the actions of WorkItem. Returns true if success, returns false
// otherwise.
// If the WorkItem is transactional, then Do() is done as a transaction.
@@ -123,9 +128,6 @@ class WorkItem {
// non-transactional.
virtual bool IsTransactional() { return false; }
- // For diagnostics.
- virtual std::wstring Dump();
-
protected:
WorkItem();
};
diff --git a/chrome/installer/util/work_item_list.cc b/chrome/installer/util/work_item_list.cc
index 012bb7e..9020957 100644
--- a/chrome/installer/util/work_item_list.cc
+++ b/chrome/installer/util/work_item_list.cc
@@ -31,7 +31,7 @@ bool WorkItemList::Do() {
list_.pop_front();
executed_list_.push_front(work_item);
if (!work_item->Do()) {
- LOG(ERROR) << "list execution failed";
+ LOG(ERROR) << "item execution failed";
result = false;
break;
}
@@ -144,3 +144,33 @@ bool WorkItemList::AddSelfRegWorkItem(const std::wstring& dll_path,
user_level_registration));
return AddWorkItem(item);
}
+
+////////////////////////////////////////////////////////////////////////////////
+NoRollbackWorkItemList::~NoRollbackWorkItemList() {
+}
+
+void NoRollbackWorkItemList::Rollback() {
+ NOTREACHED() << "Can't rollback a NoRollbackWorkItemList";
+}
+
+bool NoRollbackWorkItemList::Do() {
+ if (status_ != ADD_ITEM)
+ return false;
+
+ bool result = true;
+ while (!list_.empty()) {
+ WorkItem* work_item = list_.front();
+ list_.pop_front();
+ executed_list_.push_front(work_item);
+ if (!work_item->Do()) {
+ LOG(ERROR) << "NoRollbackWorkItemList: item execution failed.";
+ result = false;
+ }
+ }
+
+ if (result)
+ VLOG(1) << "NoRollbackWorkItemList: list execution succeeded";
+
+ status_ = LIST_EXECUTED;
+ return result;
+}
diff --git a/chrome/installer/util/work_item_list.h b/chrome/installer/util/work_item_list.h
index e8b4238..cd16f52 100644
--- a/chrome/installer/util/work_item_list.h
+++ b/chrome/installer/util/work_item_list.h
@@ -91,7 +91,7 @@ class WorkItemList : public WorkItem {
bool do_register,
bool user_level_registration);
- private:
+ protected:
friend class WorkItem;
typedef std::list<WorkItem*> WorkItems;
@@ -118,4 +118,21 @@ class WorkItemList : public WorkItem {
WorkItems executed_list_;
};
+// A specialization of WorkItemList that executes items in the list on a
+// best-effort basis. Failure of individual items to execute does not prevent
+// subsequent items from being executed.
+// Also, as the class name suggests, Rollback is not possible.
+class NoRollbackWorkItemList : public WorkItemList {
+ public:
+ virtual ~NoRollbackWorkItemList();
+
+ // Execute the WorkItems in the same order as they are added to the list.
+ // If a WorkItem fails, the function will return failure but all other
+ // WorkItems will still be executed.
+ virtual bool Do();
+
+ // Just does a NOTREACHED.
+ virtual void Rollback();
+};
+
#endif // CHROME_INSTALLER_UTIL_WORK_ITEM_LIST_H_