| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // This file defines the methods useful for uninstalling Chrome. | 5 // This file defines the methods useful for uninstalling Chrome. |
| 6 | 6 |
| 7 #include "chrome/installer/setup/uninstall.h" | 7 #include "chrome/installer/setup/uninstall.h" |
| 8 | 8 |
| 9 #include <windows.h> | 9 #include <windows.h> |
| 10 #include <stddef.h> | 10 #include <stddef.h> |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 ShellUtil::kRegStartMenuInternet).c_str(), | 675 ShellUtil::kRegStartMenuInternet).c_str(), |
| 676 WorkItem::kWow64Default, NULL, | 676 WorkItem::kWow64Default, NULL, |
| 677 InstallUtil::ValueEquals(client_name)); | 677 InstallUtil::ValueEquals(client_name)); |
| 678 } | 678 } |
| 679 } | 679 } |
| 680 } | 680 } |
| 681 } | 681 } |
| 682 | 682 |
| 683 // Delete Software\RegisteredApplications\Chromium | 683 // Delete Software\RegisteredApplications\Chromium |
| 684 InstallUtil::DeleteRegistryValue( | 684 InstallUtil::DeleteRegistryValue( |
| 685 root, ShellUtil::kRegRegisteredApplications, | 685 root, ShellUtil::kRegRegisteredApplications, WorkItem::kWow64Default, |
| 686 WorkItem::kWow64Default, | 686 install_static::GetBaseAppName().append(browser_entry_suffix)); |
| 687 dist->GetBaseAppName() + browser_entry_suffix); | |
| 688 | 687 |
| 689 // Delete the App Paths and Applications keys that let Explorer find Chrome: | 688 // Delete the App Paths and Applications keys that let Explorer find Chrome: |
| 690 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121 | 689 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121 |
| 691 base::string16 app_key(ShellUtil::kRegClasses); | 690 base::string16 app_key(ShellUtil::kRegClasses); |
| 692 app_key.push_back(base::FilePath::kSeparators[0]); | 691 app_key.push_back(base::FilePath::kSeparators[0]); |
| 693 app_key.append(L"Applications"); | 692 app_key.append(L"Applications"); |
| 694 app_key.push_back(base::FilePath::kSeparators[0]); | 693 app_key.push_back(base::FilePath::kSeparators[0]); |
| 695 app_key.append(installer::kChromeExe); | 694 app_key.append(installer::kChromeExe); |
| 696 InstallUtil::DeleteRegistryKey(root, app_key, WorkItem::kWow64Default); | 695 InstallUtil::DeleteRegistryKey(root, app_key, WorkItem::kWow64Default); |
| 697 | 696 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 725 } | 724 } |
| 726 | 725 |
| 727 // Cleanup in case Chrome had been made the default browser. | 726 // Cleanup in case Chrome had been made the default browser. |
| 728 | 727 |
| 729 // Delete the default value of SOFTWARE\Clients\StartMenuInternet if it | 728 // Delete the default value of SOFTWARE\Clients\StartMenuInternet if it |
| 730 // references this Chrome. Do this explicitly here for the case where HKCU is | 729 // references this Chrome. Do this explicitly here for the case where HKCU is |
| 731 // being processed; the iteration above will have no hits since registration | 730 // being processed; the iteration above will have no hits since registration |
| 732 // lives in HKLM. | 731 // lives in HKLM. |
| 733 InstallUtil::DeleteRegistryValueIf( | 732 InstallUtil::DeleteRegistryValueIf( |
| 734 root, ShellUtil::kRegStartMenuInternet, WorkItem::kWow64Default, NULL, | 733 root, ShellUtil::kRegStartMenuInternet, WorkItem::kWow64Default, NULL, |
| 735 InstallUtil::ValueEquals(dist->GetBaseAppName() + browser_entry_suffix)); | 734 InstallUtil::ValueEquals( |
| 735 install_static::GetBaseAppName().append(browser_entry_suffix))); |
| 736 | 736 |
| 737 // Delete each protocol association if it references this Chrome. | 737 // Delete each protocol association if it references this Chrome. |
| 738 InstallUtil::ProgramCompare open_command_pred(chrome_exe); | 738 InstallUtil::ProgramCompare open_command_pred(chrome_exe); |
| 739 base::string16 parent_key(ShellUtil::kRegClasses); | 739 base::string16 parent_key(ShellUtil::kRegClasses); |
| 740 parent_key.push_back(base::FilePath::kSeparators[0]); | 740 parent_key.push_back(base::FilePath::kSeparators[0]); |
| 741 const base::string16::size_type base_length = parent_key.size(); | 741 const base::string16::size_type base_length = parent_key.size(); |
| 742 base::string16 child_key; | 742 base::string16 child_key; |
| 743 for (const wchar_t* const* proto = | 743 for (const wchar_t* const* proto = |
| 744 &ShellUtil::kPotentialProtocolAssociations[0]; | 744 &ShellUtil::kPotentialProtocolAssociations[0]; |
| 745 *proto != NULL; | 745 *proto != NULL; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 767 #if defined(GOOGLE_CHROME_BUILD) | 767 #if defined(GOOGLE_CHROME_BUILD) |
| 768 const wchar_t kChromeExtProgId[] = L"ChromeExt"; | 768 const wchar_t kChromeExtProgId[] = L"ChromeExt"; |
| 769 #else | 769 #else |
| 770 const wchar_t kChromeExtProgId[] = L"ChromiumExt"; | 770 const wchar_t kChromeExtProgId[] = L"ChromiumExt"; |
| 771 #endif | 771 #endif |
| 772 | 772 |
| 773 HKEY roots[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; | 773 HKEY roots[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; |
| 774 for (size_t i = 0; i < arraysize(roots); ++i) { | 774 for (size_t i = 0; i < arraysize(roots); ++i) { |
| 775 base::string16 suffix; | 775 base::string16 suffix; |
| 776 if (roots[i] == HKEY_LOCAL_MACHINE) | 776 if (roots[i] == HKEY_LOCAL_MACHINE) |
| 777 suffix = ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe); | 777 suffix = ShellUtil::GetCurrentInstallationSuffix(chrome_exe); |
| 778 | 778 |
| 779 // Delete Software\Classes\ChromeExt, | 779 // Delete Software\Classes\ChromeExt, |
| 780 base::string16 ext_prog_id(ShellUtil::kRegClasses); | 780 base::string16 ext_prog_id(ShellUtil::kRegClasses); |
| 781 ext_prog_id.push_back(base::FilePath::kSeparators[0]); | 781 ext_prog_id.push_back(base::FilePath::kSeparators[0]); |
| 782 ext_prog_id.append(kChromeExtProgId); | 782 ext_prog_id.append(kChromeExtProgId); |
| 783 ext_prog_id.append(suffix); | 783 ext_prog_id.append(suffix); |
| 784 InstallUtil::DeleteRegistryKey(roots[i], ext_prog_id, | 784 InstallUtil::DeleteRegistryKey(roots[i], ext_prog_id, |
| 785 WorkItem::kWow64Default); | 785 WorkItem::kWow64Default); |
| 786 | 786 |
| 787 // Delete Software\Classes\.crx, | 787 // Delete Software\Classes\.crx, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 803 | 803 |
| 804 InstallStatus UninstallProduct(const InstallationState& original_state, | 804 InstallStatus UninstallProduct(const InstallationState& original_state, |
| 805 const InstallerState& installer_state, | 805 const InstallerState& installer_state, |
| 806 const base::FilePath& setup_exe, | 806 const base::FilePath& setup_exe, |
| 807 const Product& product, | 807 const Product& product, |
| 808 bool remove_all, | 808 bool remove_all, |
| 809 bool force_uninstall, | 809 bool force_uninstall, |
| 810 const base::CommandLine& cmd_line) { | 810 const base::CommandLine& cmd_line) { |
| 811 InstallStatus status = installer::UNINSTALL_CONFIRMED; | 811 InstallStatus status = installer::UNINSTALL_CONFIRMED; |
| 812 BrowserDistribution* browser_dist = product.distribution(); | 812 BrowserDistribution* browser_dist = product.distribution(); |
| 813 DCHECK_EQ(BrowserDistribution::GetDistribution(), browser_dist); | |
| 814 const base::FilePath chrome_exe( | 813 const base::FilePath chrome_exe( |
| 815 installer_state.target_path().Append(installer::kChromeExe)); | 814 installer_state.target_path().Append(installer::kChromeExe)); |
| 816 | 815 |
| 817 VLOG(1) << "UninstallProduct: " << browser_dist->GetDisplayName(); | 816 VLOG(1) << "UninstallProduct: " << browser_dist->GetDisplayName(); |
| 818 | 817 |
| 819 if (force_uninstall) { | 818 if (force_uninstall) { |
| 820 // Since --force-uninstall command line option is used, we are going to | 819 // Since --force-uninstall command line option is used, we are going to |
| 821 // do silent uninstall. Try to close all running Chrome instances. | 820 // do silent uninstall. Try to close all running Chrome instances. |
| 822 CloseAllChromeProcesses(); | 821 CloseAllChromeProcesses(); |
| 823 } else { | 822 } else { |
| 824 // no --force-uninstall so lets show some UI dialog boxes. | 823 // no --force-uninstall so lets show some UI dialog boxes. |
| 825 status = IsChromeActiveOrUserCancelled(installer_state, product); | 824 status = IsChromeActiveOrUserCancelled(installer_state, product); |
| 826 if (status != installer::UNINSTALL_CONFIRMED && | 825 if (status != installer::UNINSTALL_CONFIRMED && |
| 827 status != installer::UNINSTALL_DELETE_PROFILE) | 826 status != installer::UNINSTALL_DELETE_PROFILE) |
| 828 return status; | 827 return status; |
| 829 | 828 |
| 830 const base::string16 suffix( | 829 const base::string16 suffix( |
| 831 ShellUtil::GetCurrentInstallationSuffix(browser_dist, chrome_exe)); | 830 ShellUtil::GetCurrentInstallationSuffix(chrome_exe)); |
| 832 | 831 |
| 833 // Check if we need admin rights to cleanup HKLM (the conditions for | 832 // Check if we need admin rights to cleanup HKLM (the conditions for |
| 834 // requiring a cleanup are the same as the conditions to do the actual | 833 // requiring a cleanup are the same as the conditions to do the actual |
| 835 // cleanup where DeleteChromeRegistrationKeys() is invoked for | 834 // cleanup where DeleteChromeRegistrationKeys() is invoked for |
| 836 // HKEY_LOCAL_MACHINE below). If we do, try to launch another uninstaller | 835 // HKEY_LOCAL_MACHINE below). If we do, try to launch another uninstaller |
| 837 // (silent) in elevated mode to do HKLM cleanup. | 836 // (silent) in elevated mode to do HKLM cleanup. |
| 838 // And continue uninstalling in the current process also to do HKCU cleanup. | 837 // And continue uninstalling in the current process also to do HKCU cleanup. |
| 839 if (remove_all && | 838 if (remove_all && |
| 840 ShellUtil::QuickIsChromeRegisteredInHKLM( | 839 ShellUtil::QuickIsChromeRegisteredInHKLM(chrome_exe, suffix) && |
| 841 browser_dist, chrome_exe, suffix) && | |
| 842 !::IsUserAnAdmin() && | 840 !::IsUserAnAdmin() && |
| 843 base::win::GetVersion() >= base::win::VERSION_VISTA && | 841 base::win::GetVersion() >= base::win::VERSION_VISTA && |
| 844 !cmd_line.HasSwitch(installer::switches::kRunAsAdmin)) { | 842 !cmd_line.HasSwitch(installer::switches::kRunAsAdmin)) { |
| 845 base::CommandLine new_cmd(base::CommandLine::NO_PROGRAM); | 843 base::CommandLine new_cmd(base::CommandLine::NO_PROGRAM); |
| 846 new_cmd.AppendArguments(cmd_line, true); | 844 new_cmd.AppendArguments(cmd_line, true); |
| 847 // Append --run-as-admin flag to let the new instance of setup.exe know | 845 // Append --run-as-admin flag to let the new instance of setup.exe know |
| 848 // that we already tried to launch ourselves as admin. | 846 // that we already tried to launch ourselves as admin. |
| 849 new_cmd.AppendSwitch(installer::switches::kRunAsAdmin); | 847 new_cmd.AppendSwitch(installer::switches::kRunAsAdmin); |
| 850 // Append --remove-chrome-registration to remove registry keys only. | 848 // Append --remove-chrome-registration to remove registry keys only. |
| 851 new_cmd.AppendSwitch(installer::switches::kRemoveChromeRegistration); | 849 new_cmd.AppendSwitch(installer::switches::kRemoveChromeRegistration); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 | 901 |
| 904 // Also try to delete the MSI value in the ClientState key (it might not be | 902 // Also try to delete the MSI value in the ClientState key (it might not be |
| 905 // there). This is due to a Google Update behaviour where an uninstall and a | 903 // there). This is due to a Google Update behaviour where an uninstall and a |
| 906 // rapid reinstall might result in stale values from the old ClientState key | 904 // rapid reinstall might result in stale values from the old ClientState key |
| 907 // being picked up on reinstall. | 905 // being picked up on reinstall. |
| 908 product.SetMsiMarker(installer_state.system_install(), false); | 906 product.SetMsiMarker(installer_state.system_install(), false); |
| 909 | 907 |
| 910 InstallStatus ret = installer::UNKNOWN_STATUS; | 908 InstallStatus ret = installer::UNKNOWN_STATUS; |
| 911 | 909 |
| 912 const base::string16 suffix( | 910 const base::string16 suffix( |
| 913 ShellUtil::GetCurrentInstallationSuffix(browser_dist, chrome_exe)); | 911 ShellUtil::GetCurrentInstallationSuffix(chrome_exe)); |
| 914 | 912 |
| 915 // Remove all Chrome registration keys. | 913 // Remove all Chrome registration keys. |
| 916 // Registration data is put in HKCU for both system level and user level | 914 // Registration data is put in HKCU for both system level and user level |
| 917 // installs. | 915 // installs. |
| 918 DeleteChromeRegistrationKeys(installer_state, browser_dist, HKEY_CURRENT_USER, | 916 DeleteChromeRegistrationKeys(installer_state, browser_dist, HKEY_CURRENT_USER, |
| 919 suffix, &ret); | 917 suffix, &ret); |
| 920 | 918 |
| 921 // If the user's Chrome is registered with a suffix: it is possible that old | 919 // If the user's Chrome is registered with a suffix: it is possible that old |
| 922 // unsuffixed registrations were left in HKCU (e.g. if this install was | 920 // unsuffixed registrations were left in HKCU (e.g. if this install was |
| 923 // previously installed with no suffix in HKCU (old suffix rules if the user | 921 // previously installed with no suffix in HKCU (old suffix rules if the user |
| (...skipping 25 matching lines...) Expand all Loading... |
| 949 // integration entries registered with |suffix| (note: |suffix| will be the | 947 // integration entries registered with |suffix| (note: |suffix| will be the |
| 950 // empty string if required as it is obtained by | 948 // empty string if required as it is obtained by |
| 951 // GetCurrentInstallationSuffix() above)). | 949 // GetCurrentInstallationSuffix() above)). |
| 952 // TODO(gab): This can still leave parts of a suffixed install behind. To be | 950 // TODO(gab): This can still leave parts of a suffixed install behind. To be |
| 953 // able to remove them we would need to be able to remove only suffixed | 951 // able to remove them we would need to be able to remove only suffixed |
| 954 // entries (as it is now some of the registry entries (e.g. App Paths) are | 952 // entries (as it is now some of the registry entries (e.g. App Paths) are |
| 955 // unsuffixed; thus removing suffixed installs is prohibited in HKLM if | 953 // unsuffixed; thus removing suffixed installs is prohibited in HKLM if |
| 956 // !|remove_all| for now). | 954 // !|remove_all| for now). |
| 957 if (installer_state.system_install() || | 955 if (installer_state.system_install() || |
| 958 (remove_all && | 956 (remove_all && |
| 959 ShellUtil::QuickIsChromeRegisteredInHKLM( | 957 ShellUtil::QuickIsChromeRegisteredInHKLM(chrome_exe, suffix))) { |
| 960 browser_dist, chrome_exe, suffix))) { | |
| 961 DeleteChromeRegistrationKeys(installer_state, browser_dist, | 958 DeleteChromeRegistrationKeys(installer_state, browser_dist, |
| 962 HKEY_LOCAL_MACHINE, suffix, &ret); | 959 HKEY_LOCAL_MACHINE, suffix, &ret); |
| 963 } | 960 } |
| 964 | 961 |
| 965 ProcessChromeWorkItems(installer_state, product); | 962 ProcessChromeWorkItems(installer_state, product); |
| 966 | 963 |
| 967 UninstallActiveSetupEntries(installer_state); | 964 UninstallActiveSetupEntries(installer_state); |
| 968 | 965 |
| 969 UninstallFirewallRules(browser_dist, chrome_exe); | 966 UninstallFirewallRules(browser_dist, chrome_exe); |
| 970 | 967 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 // If we need a reboot to continue, schedule the parent directories for | 1092 // If we need a reboot to continue, schedule the parent directories for |
| 1096 // deletion unconditionally. If they are not empty, the session manager | 1093 // deletion unconditionally. If they are not empty, the session manager |
| 1097 // will not delete them on reboot. | 1094 // will not delete them on reboot. |
| 1098 ScheduleParentAndGrandparentForDeletion(target_path); | 1095 ScheduleParentAndGrandparentForDeletion(target_path); |
| 1099 } else if (DeleteChromeDirectoriesIfEmpty(target_path) == DELETE_FAILED) { | 1096 } else if (DeleteChromeDirectoriesIfEmpty(target_path) == DELETE_FAILED) { |
| 1100 *uninstall_status = UNINSTALL_FAILED; | 1097 *uninstall_status = UNINSTALL_FAILED; |
| 1101 } | 1098 } |
| 1102 } | 1099 } |
| 1103 | 1100 |
| 1104 } // namespace installer | 1101 } // namespace installer |
| OLD | NEW |