Chromium Code Reviews| 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, |
|
gab
2016/06/01 16:17:03
StringPiece16 would avoid copies here and would be
grt (UTC plus 2)
2016/06/01 18:00:47
Used const base::string16* since c_str() is needed
|
| + alternate_active_setup_path}; |
| + VisitUserHives(base::Bind(&DeleteUserRegistryKeys, base::Unretained(&paths))); |
| } |
| // Removes the persistent blacklist state for the current user. Note: this will |