Index: chrome/installer/util/shell_util.cc |
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc |
index 42a9c6bf12137ca71368525250a3a123853e503d..c3519273adc04c8b26e01f2d7389e718ccc56f95 100644 |
--- a/chrome/installer/util/shell_util.cc |
+++ b/chrome/installer/util/shell_util.cc |
@@ -51,6 +51,7 @@ |
#include "chrome/installer/util/l10n_string_util.h" |
#include "chrome/installer/util/master_preferences.h" |
#include "chrome/installer/util/master_preferences_constants.h" |
+#include "chrome/installer/util/registry_entry.h" |
#include "chrome/installer/util/util_constants.h" |
#include "chrome/installer/util/work_item.h" |
@@ -188,207 +189,6 @@ struct ApplicationInfo { |
base::string16 delegate_clsid; |
}; |
-// This class represents a single registry entry (a key and its value). A |
-// collection of registry entries should be collected into a list and written |
-// transactionally using a WorkItemList. This is preferred to writing to the |
-// registry directly, because if anything goes wrong, they can be rolled back. |
-class RegistryEntry { |
- public: |
- // A bit-field enum of places to look for this key in the Windows registry. |
- enum LookForIn { |
- LOOK_IN_HKCU = 1 << 0, |
- LOOK_IN_HKLM = 1 << 1, |
- LOOK_IN_HKCU_THEN_HKLM = LOOK_IN_HKCU | LOOK_IN_HKLM, |
- }; |
- |
- // Identifies the type of removal this RegistryEntry is flagged for, if any. |
- enum class RemovalFlag { |
- // Default case: install the key/value. |
- NONE, |
- // Registry value under |key_path_|\|name_| is flagged for deletion. |
- VALUE, |
- // Registry key under |key_path_| is flag for deletion. |
- KEY, |
- }; |
- |
- // Create an object that represent default value of a key. |
- RegistryEntry(const base::string16& key_path, const base::string16& value); |
- |
- // Create an object that represent a key of type REG_SZ. |
- RegistryEntry(const base::string16& key_path, |
- const base::string16& name, |
- const base::string16& value); |
- |
- // Create an object that represent a key of integer type. |
- RegistryEntry(const base::string16& key_path, |
- const base::string16& name, |
- DWORD value); |
- |
- // Flags this RegistryKey with |removal_flag|, indicating that it should be |
- // removed rather than created. Note that this will not result in cleaning up |
- // the entire registry hierarchy below RegistryEntry even if it is left empty |
- // by this operation (this should thus not be used for uninstall, but only to |
- // unregister keys that should explicitly no longer be active in the current |
- // configuration). |
- void set_removal_flag(RemovalFlag removal_flag) { |
- removal_flag_ = removal_flag; |
- } |
- |
- // Generates work_item tasks required to create (or potentially delete based |
- // on |removal_flag_|) the current RegistryEntry and add them to the given |
- // work item list. |
- void AddToWorkItemList(HKEY root, WorkItemList* items) const; |
- |
- // Returns true if this key is flagged for removal. |
- bool IsFlaggedForRemoval() const { |
- return removal_flag_ != RemovalFlag::NONE; |
- } |
- |
- // Checks if the current registry entry exists in HKCU\|key_path_|\|name_| |
- // and value is |value_|. If the key does NOT exist in HKCU, checks for |
- // the correct name and value in HKLM. |
- // |look_for_in| specifies roots (HKCU and/or HKLM) in which to look for the |
- // key, unspecified roots are not looked into (i.e. the the key is assumed not |
- // to exist in them). |
- // |look_for_in| must at least specify one root to look into. |
- // If |look_for_in| is LOOK_IN_HKCU_THEN_HKLM, this method mimics Windows' |
- // behavior when searching in HKCR (HKCU takes precedence over HKLM). For |
- // registrations outside of HKCR on versions of Windows prior to Win8, |
- // Chrome's values go in HKLM. This function will make unnecessary (but |
- // harmless) queries into HKCU in that case. |
- bool ExistsInRegistry(uint32 look_for_in) const; |
- |
- // Checks if the current registry entry exists in \|key_path_|\|name_|, |
- // regardless of value. Same lookup rules as ExistsInRegistry. |
- // Unlike ExistsInRegistry, this returns true if some other value is present |
- // with the same key. |
- bool KeyExistsInRegistry(uint32 look_for_in) const; |
- |
- private: |
- // States this RegistryKey can be in compared to the registry. |
- enum RegistryStatus { |
- // |name_| does not exist in the registry |
- DOES_NOT_EXIST, |
- // |name_| exists, but its value != |value_| |
- DIFFERENT_VALUE, |
- // |name_| exists and its value is |value_| |
- SAME_VALUE, |
- }; |
- |
- base::string16 key_path_; // key path for the registry entry |
- base::string16 name_; // name of the registry entry |
- bool is_string_; // true if current registry entry is of type REG_SZ |
- base::string16 value_; // string value (useful if is_string_ = true) |
- DWORD int_value_; // integer value (useful if is_string_ = false) |
- |
- // Identifies whether this RegistryEntry is flagged for removal (i.e. no |
- // longer relevant on the configuration it was created under). |
- RemovalFlag removal_flag_; |
- |
- // Helper function for ExistsInRegistry(). |
- // Returns the RegistryStatus of the current registry entry in |
- // |root|\|key_path_|\|name_|. |
- RegistryStatus StatusInRegistryUnderRoot(HKEY root) const; |
- |
- DISALLOW_COPY_AND_ASSIGN(RegistryEntry); |
-}; // class RegistryEntry |
- |
-RegistryEntry::RegistryEntry(const base::string16& key_path, |
- const base::string16& value) |
- : key_path_(key_path), |
- name_(), |
- is_string_(true), |
- value_(value), |
- int_value_(0), |
- removal_flag_(RemovalFlag::NONE) {} |
- |
-RegistryEntry::RegistryEntry(const base::string16& key_path, |
- const base::string16& name, |
- const base::string16& value) |
- : key_path_(key_path), |
- name_(name), |
- is_string_(true), |
- value_(value), |
- int_value_(0), |
- removal_flag_(RemovalFlag::NONE) {} |
- |
-RegistryEntry::RegistryEntry(const base::string16& key_path, |
- const base::string16& name, |
- DWORD value) |
- : key_path_(key_path), |
- name_(name), |
- is_string_(false), |
- value_(), |
- int_value_(value), |
- removal_flag_(RemovalFlag::NONE) {} |
- |
-void RegistryEntry::AddToWorkItemList(HKEY root, WorkItemList* items) const { |
- if (removal_flag_ == RemovalFlag::VALUE) { |
- items->AddDeleteRegValueWorkItem(root, key_path_, WorkItem::kWow64Default, |
- name_); |
- } else if (removal_flag_ == RemovalFlag::KEY) { |
- items->AddDeleteRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default); |
- } else { |
- DCHECK(removal_flag_ == RemovalFlag::NONE); |
- items->AddCreateRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default); |
- if (is_string_) { |
- items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default, |
- name_, value_, true); |
- } else { |
- items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default, |
- name_, int_value_, true); |
- } |
- } |
-} |
- |
-bool RegistryEntry::ExistsInRegistry(uint32 look_for_in) const { |
- DCHECK(look_for_in); |
- |
- RegistryStatus status = DOES_NOT_EXIST; |
- if (look_for_in & LOOK_IN_HKCU) |
- status = StatusInRegistryUnderRoot(HKEY_CURRENT_USER); |
- if (status == DOES_NOT_EXIST && (look_for_in & LOOK_IN_HKLM)) |
- status = StatusInRegistryUnderRoot(HKEY_LOCAL_MACHINE); |
- return status == SAME_VALUE; |
-} |
- |
-bool RegistryEntry::KeyExistsInRegistry(uint32 look_for_in) const { |
- DCHECK(look_for_in); |
- |
- RegistryStatus status = DOES_NOT_EXIST; |
- if (look_for_in & LOOK_IN_HKCU) |
- status = StatusInRegistryUnderRoot(HKEY_CURRENT_USER); |
- if (status == DOES_NOT_EXIST && (look_for_in & LOOK_IN_HKLM)) |
- status = StatusInRegistryUnderRoot(HKEY_LOCAL_MACHINE); |
- return status != DOES_NOT_EXIST; |
-} |
- |
-RegistryEntry::RegistryStatus RegistryEntry::StatusInRegistryUnderRoot( |
- HKEY root) const { |
- RegKey key(root, key_path_.c_str(), KEY_QUERY_VALUE); |
- bool found = false; |
- bool correct_value = false; |
- if (is_string_) { |
- base::string16 read_value; |
- found = key.ReadValue(name_.c_str(), &read_value) == ERROR_SUCCESS; |
- if (found) { |
- correct_value = |
- read_value.size() == value_.size() && |
- ::CompareString( |
- LOCALE_USER_DEFAULT, NORM_IGNORECASE, read_value.data(), |
- base::saturated_cast<int>(read_value.size()), value_.data(), |
- base::saturated_cast<int>(value_.size())) == CSTR_EQUAL; |
- } |
- } else { |
- DWORD read_value; |
- found = key.ReadValueDW(name_.c_str(), &read_value) == ERROR_SUCCESS; |
- if (found) |
- correct_value = read_value == int_value_; |
- } |
- return found ? (correct_value ? SAME_VALUE : DIFFERENT_VALUE) |
- : DOES_NOT_EXIST; |
-} |
- |
// Returns the Windows browser client registration key for Chrome. For example: |
// "Software\Clients\StartMenuInternet\Chromium[.user]". Strictly speaking, we |
// should use the name of the executable (e.g., "chrome.exe"), but that ship has |