Index: chrome/installer/setup/uninstall.cc |
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc |
index 4eb2347d8c157cd5587def8324cc83674f1f0e4a..f310526badd96f370e60f8c4d8b2c14ad5a1fa21 100644 |
--- a/chrome/installer/setup/uninstall.cc |
+++ b/chrome/installer/setup/uninstall.cc |
@@ -13,6 +13,7 @@ |
#include <vector> |
#include "base/base_paths.h" |
+#include "base/bind.h" |
#include "base/files/file_enumerator.h" |
#include "base/files/file_util.h" |
#include "base/macros.h" |
@@ -34,6 +35,7 @@ |
#include "chrome/installer/setup/install_worker.h" |
#include "chrome/installer/setup/setup_constants.h" |
#include "chrome/installer/setup/setup_util.h" |
+#include "chrome/installer/setup/user_hive_visitor.h" |
#include "chrome/installer/util/auto_launch_util.h" |
#include "chrome/installer/util/browser_distribution.h" |
#include "chrome/installer/util/channel_info.h" |
@@ -707,6 +709,21 @@ void RemoveFiletypeRegistration(const InstallerState& installer_state, |
} |
} |
+bool DeleteUserRegistryKeys(const std::vector<base::string16>* key_paths, |
+ const wchar_t* user_sid, |
+ base::win::RegKey* key) { |
+ for (const auto& key_path : *key_paths) { |
+ LONG result = key->DeleteKey(key_path.c_str()); |
+ if (result == ERROR_SUCCESS) { |
+ VLOG(1) << "Deleted " << user_sid << "\\" << key_path; |
+ } else if (result != ERROR_FILE_NOT_FOUND) { |
+ ::SetLastError(result); |
+ PLOG(ERROR) << "Failed deleting " << user_sid << "\\" << key_path; |
+ } |
+ } |
+ return true; |
+} |
+ |
// Removes Active Setup entries from the registry. This cannot be done through |
// a work items list as usual because of different paths based on conditionals, |
// but otherwise respects the no rollback/best effort uninstall mentality. |
@@ -747,11 +764,6 @@ void UninstallActiveSetupEntries(const InstallerState& installer_state, |
// all users hives. If a given user's hive is not loaded, try to load it to |
// proceed with the deletion (failure to do so is ignored). |
- VLOG(1) << "Uninstall per-user Active Setup keys."; |
- |
- static const wchar_t kProfileList[] = |
- L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\"; |
- |
// Windows automatically adds Wow6432Node when creating/deleting the HKLM key, |
// but doesn't seem to do so when manually deleting the user-level keys it |
// created. |
@@ -759,85 +771,10 @@ void UninstallActiveSetupEntries(const InstallerState& installer_state, |
alternate_active_setup_path.insert(arraysize("Software\\") - 1, |
L"Wow6432Node\\"); |
- // These two privileges are required by RegLoadKey() and RegUnloadKey() below. |
- ScopedTokenPrivilege se_restore_name_privilege(SE_RESTORE_NAME); |
- ScopedTokenPrivilege se_backup_name_privilege(SE_BACKUP_NAME); |
- if (!se_restore_name_privilege.is_enabled() || |
- !se_backup_name_privilege.is_enabled()) { |
- // This is not a critical failure as those privileges aren't required to |
- // clean hives that are already loaded, but attempts to LoadRegKey() below |
- // will fail. |
- LOG(WARNING) << "Failed to enable privileges required to load registry " |
- "hives."; |
- } |
- |
- for (base::win::RegistryKeyIterator it(HKEY_LOCAL_MACHINE, kProfileList); |
- it.Valid(); ++it) { |
- const wchar_t* profile_sid = it.Name(); |
- |
- VLOG(1) << "Uninstalling Active Setup key for " << profile_sid; |
- |
- // First check if this user's registry hive needs to be loaded in |
- // HKEY_USERS. |
- base::win::RegKey user_reg_root_probe( |
- HKEY_USERS, profile_sid, KEY_READ); |
- bool loaded_hive = false; |
- if (user_reg_root_probe.Valid()) { |
- VLOG(1) << "Registry hive already loaded for " << profile_sid; |
- } else { |
- VLOG(1) << "Attempting to load registry hive for " << profile_sid; |
- |
- base::string16 reg_profile_info_path(kProfileList); |
- reg_profile_info_path.append(profile_sid); |
- base::win::RegKey reg_profile_info_key( |
- HKEY_LOCAL_MACHINE, reg_profile_info_path.c_str(), KEY_READ); |
- |
- base::string16 profile_path; |
- LONG result = reg_profile_info_key.ReadValue(L"ProfileImagePath", |
- &profile_path); |
- if (result != ERROR_SUCCESS) { |
- LOG(ERROR) << "Error reading ProfileImagePath: " << result; |
- continue; |
- } |
- base::FilePath registry_hive_file(profile_path); |
- registry_hive_file = registry_hive_file.AppendASCII("NTUSER.DAT"); |
- |
- result = RegLoadKey(HKEY_USERS, profile_sid, |
- registry_hive_file.value().c_str()); |
- if (result != ERROR_SUCCESS) { |
- LOG(ERROR) << "Error loading registry hive: " << result; |
- continue; |
- } |
- |
- VLOG(1) << "Loaded registry hive for " << profile_sid; |
- loaded_hive = true; |
- } |
- |
- base::win::RegKey user_reg_root( |
- HKEY_USERS, profile_sid, KEY_ALL_ACCESS); |
- |
- LONG result = user_reg_root.DeleteKey(active_setup_path.c_str()); |
- if (result != ERROR_SUCCESS) { |
- result = user_reg_root.DeleteKey(alternate_active_setup_path.c_str()); |
- if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { |
- LOG(ERROR) << "Failed to delete key at " << active_setup_path |
- << " and at " << alternate_active_setup_path |
- << ", result: " << result; |
- } |
- } |
- VLOG_IF(1, result == ERROR_SUCCESS) |
- << "Deleted Active Setup entry for " << profile_sid; |
- VLOG_IF(1, result == ERROR_FILE_NOT_FOUND) |
- << "No Active Setup entry to delete for " << profile_sid; |
- |
- if (loaded_hive) { |
- user_reg_root.Close(); |
- if (RegUnLoadKey(HKEY_USERS, profile_sid) == ERROR_SUCCESS) |
- VLOG(1) << "Unloaded registry hive for " << profile_sid; |
- else |
- LOG(ERROR) << "Error unloading registry hive for " << profile_sid; |
- } |
- } |
+ VLOG(1) << "Uninstall per-user Active Setup keys."; |
+ std::vector<base::string16> paths = {active_setup_path, |
+ alternate_active_setup_path}; |
+ VisitUserHives(base::Bind(&DeleteUserRegistryKeys, base::Unretained(&paths))); |
} |
// Removes the persistent blacklist state for the current user. Note: this will |