X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fchrome%2Finstaller%2Fsetup%2Funinstall.cc;h=353e3900539c46ef194c31c59db507ddbe22c1f6;hb=004985e17e624662a4c85c76a7654039dc83f028;hp=d1b67ffbc83fffd74410a75255d97e338d86a55c;hpb=2f108dbacb161091e42a3479f4e171339b7e7623;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/chrome/installer/setup/uninstall.cc b/src/chrome/installer/setup/uninstall.cc index d1b67ff..353e390 100644 --- a/src/chrome/installer/setup/uninstall.cc +++ b/src/chrome/installer/setup/uninstall.cc @@ -24,7 +24,7 @@ #include "base/win/shortcut.h" #include "base/win/windows_version.h" #include "chrome/common/chrome_constants.h" -#include "chrome/common/chrome_paths_internal.h" +#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_result_codes.h" #include "chrome/installer/launcher_support/chrome_launcher_support.h" #include "chrome/installer/setup/install.h" @@ -35,6 +35,7 @@ #include "chrome/installer/util/browser_distribution.h" #include "chrome/installer/util/channel_info.h" #include "chrome/installer/util/delete_after_reboot_helper.h" +#include "chrome/installer/util/firewall_manager_win.h" #include "chrome/installer/util/google_update_constants.h" #include "chrome/installer/util/google_update_settings.h" #include "chrome/installer/util/helper.h" @@ -46,12 +47,11 @@ #include "chrome/installer/util/shell_util.h" #include "chrome/installer/util/util_constants.h" #include "content/public/common/result_codes.h" -#include "extensions/common/constants.h" #include "rlz/lib/rlz_lib.h" using base::win::RegKey; -using installer::InstallStatus; -using installer::MasterPreferences; + +namespace installer { namespace { @@ -64,7 +64,7 @@ void DeleteInstallTempDir(const base::FilePath& target_path) { base::FilePath temp_path(target_path.DirName().Append( installer::kInstallTempDir)); if (base::DirectoryExists(temp_path)) { - installer::SelfCleaningTempDir temp_dir; + SelfCleaningTempDir temp_dir; if (!temp_dir.Initialize(target_path.DirName(), installer::kInstallTempDir) || !temp_dir.Delete()) { @@ -77,16 +77,16 @@ void DeleteInstallTempDir(const base::FilePath& target_path) { // adds to |update_list| the work item to update the corresponding "ap" // registry value specified in |channel_info|. void AddChannelValueUpdateWorkItems( - const installer::InstallationState& original_state, - const installer::InstallerState& installer_state, - const installer::ChannelInfo& channel_info, + const InstallationState& original_state, + const InstallerState& installer_state, + const ChannelInfo& channel_info, const std::vector& dist_types, WorkItemList* update_list) { const bool system_level = installer_state.system_install(); const HKEY reg_root = installer_state.root_key(); for (size_t i = 0; i < dist_types.size(); ++i) { BrowserDistribution::Type dist_type = dist_types[i]; - const installer::ProductState* product_state = + const ProductState* product_state = original_state.GetProductState(system_level, dist_type); // Only modify other products if they're installed and multi. if (product_state != NULL && @@ -112,17 +112,16 @@ void AddChannelValueUpdateWorkItems( // Specifically, removes the flags associated with this product ("-chrome" or // "-chromeframe") from the "ap" values for all other installed products and for // the multi-installer package. -void ProcessGoogleUpdateItems( - const installer::InstallationState& original_state, - const installer::InstallerState& installer_state, - const installer::Product& product) { +void ProcessGoogleUpdateItems(const InstallationState& original_state, + const InstallerState& installer_state, + const Product& product) { DCHECK(installer_state.is_multi_install()); const bool system_level = installer_state.system_install(); BrowserDistribution* distribution = product.distribution(); - const installer::ProductState* product_state = + const ProductState* product_state = original_state.GetProductState(system_level, distribution->GetType()); DCHECK(product_state != NULL); - installer::ChannelInfo channel_info; + ChannelInfo channel_info; // Remove product's flags from the channel value. channel_info.set_value(product_state->channel().value()); @@ -147,9 +146,8 @@ void ProcessGoogleUpdateItems( } } -void ProcessOnOsUpgradeWorkItems( - const installer::InstallerState& installer_state, - const installer::Product& product) { +void ProcessOnOsUpgradeWorkItems(const InstallerState& installer_state, + const Product& product) { scoped_ptr work_item_list( WorkItem::CreateNoRollbackWorkItemList()); AddOsUpgradeWorkItems(installer_state, base::FilePath(), Version(), product, @@ -158,17 +156,17 @@ void ProcessOnOsUpgradeWorkItems( LOG(ERROR) << "Failed to remove on-os-upgrade command."; } -void ProcessIELowRightsPolicyWorkItems( - const installer::InstallerState& installer_state) { +void ProcessIELowRightsPolicyWorkItems(const InstallerState& installer_state) { scoped_ptr work_items(WorkItem::CreateNoRollbackWorkItemList()); AddDeleteOldIELowRightsPolicyWorkItems(installer_state, work_items.get()); work_items->Do(); - installer::RefreshElevationPolicy(); + RefreshElevationPolicy(); } void ClearRlzProductState() { const rlz_lib::AccessPoint points[] = {rlz_lib::CHROME_OMNIBOX, rlz_lib::CHROME_HOME_PAGE, + rlz_lib::CHROME_APP_LIST, rlz_lib::NO_ACCESS_POINT}; rlz_lib::ClearProductState(rlz_lib::CHROME, points); @@ -187,11 +185,10 @@ void ClearRlzProductState() { // * non-multi product being uninstalled: remove both // * any multi product left besides App Host: keep both // * only App Host left: keep setup.exe -void CheckShouldRemoveSetupAndArchive( - const installer::InstallationState& original_state, - const installer::InstallerState& installer_state, - bool* remove_setup, - bool* remove_archive) { +void CheckShouldRemoveSetupAndArchive(const InstallationState& original_state, + const InstallerState& installer_state, + bool* remove_setup, + bool* remove_archive) { *remove_setup = true; *remove_archive = true; @@ -204,9 +201,8 @@ void CheckShouldRemoveSetupAndArchive( for (size_t i = 0; i < BrowserDistribution::NUM_TYPES; ++i) { BrowserDistribution::Type dist_type = static_cast(i); - const installer::ProductState* product_state = - original_state.GetProductState( - installer_state.system_install(), dist_type); + const ProductState* product_state = original_state.GetProductState( + installer_state.system_install(), dist_type); // If the product is installed, in multi mode, and is not part of the // active uninstallation... if (product_state && product_state->is_multi_install() && @@ -260,10 +256,6 @@ bool RemoveInstallerFiles(const base::FilePath& installer_directory, return success; } -} // namespace - -namespace installer { - // Kills all Chrome processes, immediately. void CloseAllChromeProcesses() { base::CleanupProcesses(installer::kChromeExe, base::TimeDelta(), @@ -395,62 +387,56 @@ DeleteResult DeleteEmptyDir(const base::FilePath& path) { return DELETE_FAILED; } -void GetLocalStateFolders(const Product& product, - std::vector* paths) { - // Obtain the location of the user profile data. - product.GetUserDataPaths(paths); - LOG_IF(ERROR, paths->empty()) - << "Could not retrieve user's profile directory."; +// Get the user data directory, which is *not* DIR_USER_DATA for Chrome Frame. +// TODO(grt): Remove Chrome Frame uninstall support when usage is low enough. +base::FilePath GetUserDataDir(const Product& product) { + base::FilePath path; + bool is_chrome_frame = product.is_chrome_frame(); + int key = is_chrome_frame ? base::DIR_LOCAL_APP_DATA : chrome::DIR_USER_DATA; + if (!PathService::Get(key, &path)) + return base::FilePath(); + if (is_chrome_frame) { + path = path.Append(product.distribution()->GetInstallSubDir()); + path = path.Append(chrome::kUserDataDirname); + } + return path; } // Creates a copy of the local state file and returns a path to the copy. -base::FilePath BackupLocalStateFile( - const std::vector& local_state_folders) { +base::FilePath BackupLocalStateFile(const base::FilePath& user_data_dir) { base::FilePath backup; - - // Copy the first local state file that is found. - for (size_t i = 0; i < local_state_folders.size(); ++i) { - const base::FilePath& local_state_folder = local_state_folders[i]; - base::FilePath state_file( - local_state_folder.Append(chrome::kLocalStateFilename)); - if (!base::PathExists(state_file)) - continue; - if (!base::CreateTemporaryFile(&backup)) - LOG(ERROR) << "Failed to create temporary file for Local State."; - else - base::CopyFile(state_file, backup); - break; - } + base::FilePath state_file(user_data_dir.Append(chrome::kLocalStateFilename)); + if (!base::CreateTemporaryFile(&backup)) + LOG(ERROR) << "Failed to create temporary file for Local State."; + else + base::CopyFile(state_file, backup); return backup; } -// Deletes all user data directories for a product. -DeleteResult DeleteLocalState( - const std::vector& local_state_folders, - bool schedule_on_failure) { - if (local_state_folders.empty()) +// Deletes a given user data directory as well as the containing product +// directories if they are empty (e.g., "Google\Chrome"). +DeleteResult DeleteUserDataDir(const base::FilePath& user_data_dir, + bool schedule_on_failure) { + if (user_data_dir.empty()) return DELETE_SUCCEEDED; DeleteResult result = DELETE_SUCCEEDED; - for (size_t i = 0; i < local_state_folders.size(); ++i) { - const base::FilePath& user_local_state = local_state_folders[i]; - VLOG(1) << "Deleting user profile " << user_local_state.value(); - if (!base::DeleteFile(user_local_state, true)) { - LOG(ERROR) << "Failed to delete user profile dir: " - << user_local_state.value(); - if (schedule_on_failure) { - ScheduleDirectoryForDeletion(user_local_state); - result = DELETE_REQUIRES_REBOOT; - } else { - result = DELETE_FAILED; - } + VLOG(1) << "Deleting user profile " << user_data_dir.value(); + if (!base::DeleteFile(user_data_dir, true)) { + LOG(ERROR) << "Failed to delete user profile dir: " + << user_data_dir.value(); + if (schedule_on_failure) { + ScheduleDirectoryForDeletion(user_data_dir); + result = DELETE_REQUIRES_REBOOT; + } else { + result = DELETE_FAILED; } } if (result == DELETE_REQUIRES_REBOOT) { - ScheduleParentAndGrandparentForDeletion(local_state_folders[0]); + ScheduleParentAndGrandparentForDeletion(user_data_dir); } else { - const base::FilePath user_data_dir(local_state_folders[0].DirName()); + const base::FilePath user_data_dir(user_data_dir.DirName()); if (!user_data_dir.empty() && DeleteEmptyDir(user_data_dir) == DELETE_SUCCEEDED) { const base::FilePath product_dir(user_data_dir.DirName()); @@ -522,27 +508,6 @@ bool MoveSetupOutOfInstallFolder(const InstallerState& installer_state, return true; } -DeleteResult DeleteChromeDirectoriesIfEmpty( - const base::FilePath& application_directory) { - DeleteResult result(DeleteEmptyDir(application_directory)); - if (result == DELETE_SUCCEEDED) { - // Now check and delete if the parent directories are empty - // For example Google\Chrome or Chromium - const base::FilePath product_directory(application_directory.DirName()); - if (!product_directory.empty()) { - result = DeleteEmptyDir(product_directory); - if (result == DELETE_SUCCEEDED) { - const base::FilePath vendor_directory(product_directory.DirName()); - if (!vendor_directory.empty()) - result = DeleteEmptyDir(vendor_directory); - } - } - } - if (result == DELETE_NOT_EMPTY) - result = DELETE_SUCCEEDED; - return result; -} - DeleteResult DeleteAppHostFilesAndFolders(const InstallerState& installer_state, const Version& installed_version) { const base::FilePath& target_path = installer_state.target_path(); @@ -758,6 +723,164 @@ void RemoveFiletypeRegistration(const InstallerState& installer_state, } } +// Builds and executes a work item list to remove DelegateExecute verb handler +// work items for |product|. This will be a noop for products whose +// corresponding BrowserDistribution implementations do not publish a CLSID via +// GetCommandExecuteImplClsid. +bool ProcessDelegateExecuteWorkItems(const InstallerState& installer_state, + const Product& product) { + scoped_ptr item_list(WorkItem::CreateNoRollbackWorkItemList()); + AddDelegateExecuteWorkItems(installer_state, base::FilePath(), Version(), + product, item_list.get()); + return item_list->Do(); +} + +// 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. +// This will only apply for system-level installs of Chrome/Chromium and will be +// a no-op for all other types of installs. +void UninstallActiveSetupEntries(const InstallerState& installer_state, + const Product& product) { + VLOG(1) << "Uninstalling registry entries for ActiveSetup."; + BrowserDistribution* distribution = product.distribution(); + + if (!product.is_chrome() || !installer_state.system_install()) { + const char* install_level = + installer_state.system_install() ? "system" : "user"; + VLOG(1) << "No Active Setup processing to do for " << install_level + << "-level " << distribution->GetDisplayName(); + return; + } + + const base::string16 active_setup_path( + InstallUtil::GetActiveSetupPath(distribution)); + InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, active_setup_path); + + // Windows leaves keys behind in HKCU\\Software\\(Wow6432Node\\)?Microsoft\\ + // Active Setup\\Installed Components\\{guid} + // for every user that logged in since system-level Chrome was installed. + // This is a problem because Windows compares the value of the Version subkey + // in there with the value of the Version subkey in the matching HKLM entries + // before running Chrome's Active Setup so if Chrome was to be reinstalled + // with a lesser version (e.g. switching back to a more stable channel), the + // affected users would not have Chrome's Active Setup called until Chrome + // eventually updated passed that user's registered Version. + // + // It is however very hard to delete those values as the registry hives for + // other users are not loaded by default under HKEY_USERS (unless a user is + // logged on or has a process impersonating him). + // + // Following our best effort uninstall practices, try to delete the value in + // 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). + + 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. + base::string16 alternate_active_setup_path(active_setup_path); + 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(); + + // 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) << "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; + } + } + + 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; + } + } +} + +} // namespace + +DeleteResult DeleteChromeDirectoriesIfEmpty( + const base::FilePath& application_directory) { + DeleteResult result(DeleteEmptyDir(application_directory)); + if (result == DELETE_SUCCEEDED) { + // Now check and delete if the parent directories are empty + // For example Google\Chrome or Chromium + const base::FilePath product_directory(application_directory.DirName()); + if (!product_directory.empty()) { + result = DeleteEmptyDir(product_directory); + if (result == DELETE_SUCCEEDED) { + const base::FilePath vendor_directory(product_directory.DirName()); + if (!vendor_directory.empty()) + result = DeleteEmptyDir(vendor_directory); + } + } + } + if (result == DELETE_NOT_EMPTY) + result = DELETE_SUCCEEDED; + return result; +} + bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, BrowserDistribution* dist, HKEY root, @@ -924,144 +1047,17 @@ const wchar_t kChromeExtProgId[] = L"ChromiumExt"; // Delete Software\Classes\.crx, base::string16 ext_association(ShellUtil::kRegClasses); ext_association.append(L"\\"); - ext_association.append(extensions::kExtensionFileExtension); + ext_association.append(L".crx"); InstallUtil::DeleteRegistryKey(roots[i], ext_association); } } -// Builds and executes a work item list to remove DelegateExecute verb handler -// work items for |product|. This will be a noop for products whose -// corresponding BrowserDistribution implementations do not publish a CLSID via -// GetCommandExecuteImplClsid. -bool ProcessDelegateExecuteWorkItems(const InstallerState& installer_state, - const Product& product) { - scoped_ptr item_list(WorkItem::CreateNoRollbackWorkItemList()); - AddDelegateExecuteWorkItems(installer_state, base::FilePath(), Version(), - product, item_list.get()); - return item_list->Do(); -} - -// 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. -// This will only apply for system-level installs of Chrome/Chromium and will be -// a no-op for all other types of installs. -void UninstallActiveSetupEntries(const InstallerState& installer_state, - const Product& product) { - VLOG(1) << "Uninstalling registry entries for ActiveSetup."; - BrowserDistribution* distribution = product.distribution(); - - if (!product.is_chrome() || !installer_state.system_install()) { - const char* install_level = - installer_state.system_install() ? "system" : "user"; - VLOG(1) << "No Active Setup processing to do for " << install_level - << "-level " << distribution->GetDisplayName(); - return; - } - - const base::string16 active_setup_path( - InstallUtil::GetActiveSetupPath(distribution)); - InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, active_setup_path); - - // Windows leaves keys behind in HKCU\\Software\\(Wow6432Node\\)?Microsoft\\ - // Active Setup\\Installed Components\\{guid} - // for every user that logged in since system-level Chrome was installed. - // This is a problem because Windows compares the value of the Version subkey - // in there with the value of the Version subkey in the matching HKLM entries - // before running Chrome's Active Setup so if Chrome was to be reinstalled - // with a lesser version (e.g. switching back to a more stable channel), the - // affected users would not have Chrome's Active Setup called until Chrome - // eventually updated passed that user's registered Version. - // - // It is however very hard to delete those values as the registry hives for - // other users are not loaded by default under HKEY_USERS (unless a user is - // logged on or has a process impersonating him). - // - // Following our best effort uninstall practices, try to delete the value in - // 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). - - 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. - base::string16 alternate_active_setup_path(active_setup_path); - 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(); - - // 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) << "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; - } - } - - 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; - } - } +void UninstallFirewallRules(BrowserDistribution* dist, + const base::FilePath& chrome_exe) { + scoped_ptr manager = + FirewallManager::Create(dist, chrome_exe); + if (manager) + manager->RemoveFirewallRules(); } InstallStatus UninstallProduct(const InstallationState& original_state, @@ -1244,6 +1240,8 @@ InstallStatus UninstallProduct(const InstallationState& original_state, UninstallActiveSetupEntries(installer_state, product); + UninstallFirewallRules(browser_dist, base::FilePath(chrome_exe)); + // Notify the shell that associations have changed since Chrome was likely // unregistered. SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); @@ -1332,9 +1330,15 @@ InstallStatus UninstallProduct(const InstallationState& original_state, // When deleting files, we must make sure that we're either a "single" // (aka non-multi) installation or we are the Chrome Binaries. - std::vector local_state_folders; - GetLocalStateFolders(product, &local_state_folders); - base::FilePath backup_state_file(BackupLocalStateFile(local_state_folders)); + base::FilePath user_data_dir(GetUserDataDir(product)); + base::FilePath backup_state_file; + if (!user_data_dir.empty()) { + backup_state_file = BackupLocalStateFile(user_data_dir); + } else { + LOG(ERROR) << "Could not retrieve the user's profile directory."; + ret = installer::UNINSTALL_FAILED; + delete_profile = false; + } if (product.is_chrome_app_host()) { DeleteAppHostFilesAndFolders(installer_state, product_state->version()); @@ -1350,7 +1354,7 @@ InstallStatus UninstallProduct(const InstallationState& original_state, } if (delete_profile) - DeleteLocalState(local_state_folders, product.is_chrome_frame()); + DeleteUserDataDir(user_data_dir, product.is_chrome_frame()); if (!force_uninstall) { VLOG(1) << "Uninstallation complete. Launching post-uninstall operations.";