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 <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
213 } | 213 } |
214 } | 214 } |
215 | 215 |
216 if (kill) { | 216 if (kill) { |
217 VLOG(1) << installer::kChromeFrameHelperExe << " hung. Killing."; | 217 VLOG(1) << installer::kChromeFrameHelperExe << " hung. Killing."; |
218 base::CleanupProcesses(installer::kChromeFrameHelperExe, 0, | 218 base::CleanupProcesses(installer::kChromeFrameHelperExe, 0, |
219 content::RESULT_CODE_HUNG, NULL); | 219 content::RESULT_CODE_HUNG, NULL); |
220 } | 220 } |
221 } | 221 } |
222 | 222 |
223 // This method tries to figure out if current user has registered Chrome. | |
224 // It returns true iff there is a registered browser that will launch the | |
225 // same chrome.exe as the current installation. | |
226 bool CurrentUserHasDefaultBrowser(const InstallerState& installer_state) { | |
227 using base::win::RegistryKeyIterator; | |
228 const HKEY root = HKEY_LOCAL_MACHINE; | |
229 ProgramCompare open_command_pred( | |
230 installer_state.target_path().Append(kChromeExe)); | |
231 string16 client_open_path; | |
232 RegKey client_open_key; | |
233 string16 reg_exe; | |
234 for (RegistryKeyIterator iter(root, ShellUtil::kRegStartMenuInternet); | |
235 iter.Valid(); ++iter) { | |
236 client_open_path.assign(ShellUtil::kRegStartMenuInternet) | |
237 .append(1, L'\\') | |
238 .append(iter.Name()) | |
239 .append(ShellUtil::kRegShellOpen); | |
240 if (client_open_key.Open(root, client_open_path.c_str(), | |
241 KEY_QUERY_VALUE) == ERROR_SUCCESS && | |
242 client_open_key.ReadValue(L"", ®_exe) == ERROR_SUCCESS && | |
243 open_command_pred.Evaluate(reg_exe)) { | |
244 return true; | |
245 } | |
246 } | |
247 return false; | |
248 } | |
249 | |
250 // This method deletes Chrome shortcut folder from Windows Start menu. It | 223 // This method deletes Chrome shortcut folder from Windows Start menu. It |
251 // checks system_uninstall to see if the shortcut is in all users start menu | 224 // checks system_uninstall to see if the shortcut is in all users start menu |
252 // or current user start menu. | 225 // or current user start menu. |
253 // We try to remove the standard desktop shortcut but if that fails we try | 226 // We try to remove the standard desktop shortcut but if that fails we try |
254 // to remove the alternate desktop shortcut. Only one of them should be | 227 // to remove the alternate desktop shortcut. Only one of them should be |
255 // present in a given install but at this point we don't know which one. | 228 // present in a given install but at this point we don't know which one. |
256 void DeleteChromeShortcuts(const InstallerState& installer_state, | 229 void DeleteChromeShortcuts(const InstallerState& installer_state, |
257 const Product& product) { | 230 const Product& product) { |
258 if (!product.is_chrome()) { | 231 if (!product.is_chrome()) { |
259 VLOG(1) << __FUNCTION__ " called for non-CHROME distribution"; | 232 VLOG(1) << __FUNCTION__ " called for non-CHROME distribution"; |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
668 // We used to register Chrome to handle crx files, but this turned out | 641 // We used to register Chrome to handle crx files, but this turned out |
669 // to be not worth the hassle. Remove these old registry entries if | 642 // to be not worth the hassle. Remove these old registry entries if |
670 // they exist. See: http://codereview.chromium.org/210007 | 643 // they exist. See: http://codereview.chromium.org/210007 |
671 | 644 |
672 #if defined(GOOGLE_CHROME_BUILD) | 645 #if defined(GOOGLE_CHROME_BUILD) |
673 const wchar_t kChromeExtProgId[] = L"ChromeExt"; | 646 const wchar_t kChromeExtProgId[] = L"ChromeExt"; |
674 #else | 647 #else |
675 const wchar_t kChromeExtProgId[] = L"ChromiumExt"; | 648 const wchar_t kChromeExtProgId[] = L"ChromiumExt"; |
676 #endif | 649 #endif |
677 | 650 |
651 const string16 suffix(ShellUtil::GetCurrentInstallationSuffix()); | |
652 | |
678 HKEY roots[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; | 653 HKEY roots[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; |
679 for (size_t i = 0; i < arraysize(roots); ++i) { | 654 for (size_t i = 0; i < arraysize(roots); ++i) { |
680 string16 suffix; | |
681 if (roots[i] == HKEY_LOCAL_MACHINE && | |
gab
2012/05/30 00:06:24
This was introduced in 2009 in http://src.chromium
gab
2012/05/30 02:45:31
Ok, thanks aa@, I'll remove it: https://chromiumco
gab
2012/05/30 03:16:42
Actually, as discussed with grt@, we won't remove
| |
682 !ShellUtil::GetUserSpecificDefaultBrowserSuffix(dist, &suffix)) | |
683 suffix = L""; | |
684 | |
685 // Delete Software\Classes\ChromeExt, | 655 // Delete Software\Classes\ChromeExt, |
686 string16 ext_prog_id(ShellUtil::kRegClasses); | 656 string16 ext_prog_id(ShellUtil::kRegClasses); |
687 ext_prog_id.push_back(FilePath::kSeparators[0]); | 657 ext_prog_id.push_back(FilePath::kSeparators[0]); |
688 ext_prog_id.append(kChromeExtProgId); | 658 ext_prog_id.append(kChromeExtProgId); |
689 ext_prog_id.append(suffix); | 659 ext_prog_id.append(suffix); |
690 InstallUtil::DeleteRegistryKey(roots[i], ext_prog_id); | 660 InstallUtil::DeleteRegistryKey(roots[i], ext_prog_id); |
691 | 661 |
692 // Delete Software\Classes\.crx, | 662 // Delete Software\Classes\.crx, |
693 string16 ext_association(ShellUtil::kRegClasses); | 663 string16 ext_association(ShellUtil::kRegClasses); |
694 ext_association.append(L"\\"); | 664 ext_association.append(L"\\"); |
(...skipping 28 matching lines...) Expand all Loading... | |
723 } | 693 } |
724 | 694 |
725 InstallStatus UninstallProduct(const InstallationState& original_state, | 695 InstallStatus UninstallProduct(const InstallationState& original_state, |
726 const InstallerState& installer_state, | 696 const InstallerState& installer_state, |
727 const FilePath& setup_path, | 697 const FilePath& setup_path, |
728 const Product& product, | 698 const Product& product, |
729 bool remove_all, | 699 bool remove_all, |
730 bool force_uninstall, | 700 bool force_uninstall, |
731 const CommandLine& cmd_line) { | 701 const CommandLine& cmd_line) { |
732 InstallStatus status = installer::UNINSTALL_CONFIRMED; | 702 InstallStatus status = installer::UNINSTALL_CONFIRMED; |
733 string16 suffix; | 703 BrowserDistribution* browser_dist = product.distribution(); |
734 if (!ShellUtil::GetUserSpecificDefaultBrowserSuffix(product.distribution(), | 704 const string16 chrome_exe( |
735 &suffix)) | 705 installer_state.target_path().Append(installer::kChromeExe).value()); |
736 suffix = L""; | |
737 | 706 |
738 BrowserDistribution* browser_dist = product.distribution(); | 707 const string16 suffix(ShellUtil::GetCurrentInstallationSuffix()); |
708 | |
739 bool is_chrome = product.is_chrome(); | 709 bool is_chrome = product.is_chrome(); |
740 | 710 |
741 VLOG(1) << "UninstallProduct: " << browser_dist->GetApplicationName(); | 711 VLOG(1) << "UninstallProduct: " << browser_dist->GetApplicationName(); |
742 | 712 |
743 if (force_uninstall) { | 713 if (force_uninstall) { |
744 // Since --force-uninstall command line option is used, we are going to | 714 // Since --force-uninstall command line option is used, we are going to |
745 // do silent uninstall. Try to close all running Chrome instances. | 715 // do silent uninstall. Try to close all running Chrome instances. |
746 // NOTE: We don't do this for Chrome Frame. | 716 // NOTE: We don't do this for Chrome Frame. |
747 if (is_chrome) | 717 if (is_chrome) |
748 CloseAllChromeProcesses(); | 718 CloseAllChromeProcesses(); |
749 } else if (is_chrome) { | 719 } else if (is_chrome) { |
750 // no --force-uninstall so lets show some UI dialog boxes. | 720 // no --force-uninstall so lets show some UI dialog boxes. |
751 status = IsChromeActiveOrUserCancelled(installer_state, product); | 721 status = IsChromeActiveOrUserCancelled(installer_state, product); |
752 if (status != installer::UNINSTALL_CONFIRMED && | 722 if (status != installer::UNINSTALL_CONFIRMED && |
753 status != installer::UNINSTALL_DELETE_PROFILE) | 723 status != installer::UNINSTALL_DELETE_PROFILE) |
754 return status; | 724 return status; |
755 | 725 |
756 // Check if we need admin rights to cleanup HKLM. If we do, try to launch | 726 // Check if we need admin rights to cleanup HKLM. If we do, try to launch |
757 // another uninstaller (silent) in elevated mode to do HKLM cleanup. | 727 // another uninstaller (silent) in elevated mode to do HKLM cleanup. |
758 // And continue uninstalling in the current process also to do HKCU cleanup. | 728 // And continue uninstalling in the current process also to do HKCU cleanup. |
759 if (remove_all && | 729 if (ShellUtil::IsInstallationPresentInHKLM(browser_dist, chrome_exe, |
760 (!suffix.empty() || CurrentUserHasDefaultBrowser(installer_state)) && | 730 suffix) && |
731 (!suffix.empty() || remove_all) && | |
761 !::IsUserAnAdmin() && | 732 !::IsUserAnAdmin() && |
762 base::win::GetVersion() >= base::win::VERSION_VISTA && | 733 base::win::GetVersion() >= base::win::VERSION_VISTA && |
763 !cmd_line.HasSwitch(installer::switches::kRunAsAdmin)) { | 734 !cmd_line.HasSwitch(installer::switches::kRunAsAdmin)) { |
764 CommandLine new_cmd(CommandLine::NO_PROGRAM); | 735 CommandLine new_cmd(CommandLine::NO_PROGRAM); |
765 new_cmd.AppendArguments(cmd_line, true); | 736 new_cmd.AppendArguments(cmd_line, true); |
766 // Append --run-as-admin flag to let the new instance of setup.exe know | 737 // Append --run-as-admin flag to let the new instance of setup.exe know |
767 // that we already tried to launch ourselves as admin. | 738 // that we already tried to launch ourselves as admin. |
768 new_cmd.AppendSwitch(installer::switches::kRunAsAdmin); | 739 new_cmd.AppendSwitch(installer::switches::kRunAsAdmin); |
769 // Append --remove-chrome-registration to remove registry keys only. | 740 // Append --remove-chrome-registration to remove registry keys only. |
770 new_cmd.AppendSwitch(installer::switches::kRemoveChromeRegistration); | 741 new_cmd.AppendSwitch(installer::switches::kRemoveChromeRegistration); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
804 // Also try to delete the MSI value in the ClientState key (it might not be | 775 // Also try to delete the MSI value in the ClientState key (it might not be |
805 // there). This is due to a Google Update behaviour where an uninstall and a | 776 // there). This is due to a Google Update behaviour where an uninstall and a |
806 // rapid reinstall might result in stale values from the old ClientState key | 777 // rapid reinstall might result in stale values from the old ClientState key |
807 // being picked up on reinstall. | 778 // being picked up on reinstall. |
808 product.SetMsiMarker(installer_state.system_install(), false); | 779 product.SetMsiMarker(installer_state.system_install(), false); |
809 | 780 |
810 // Remove all Chrome registration keys. | 781 // Remove all Chrome registration keys. |
811 // Registration data is put in HKCU for both system level and user level | 782 // Registration data is put in HKCU for both system level and user level |
812 // installs. | 783 // installs. |
813 InstallStatus ret = installer::UNKNOWN_STATUS; | 784 InstallStatus ret = installer::UNKNOWN_STATUS; |
814 DeleteChromeRegistrationKeys(product.distribution(), HKEY_CURRENT_USER, | 785 DeleteChromeRegistrationKeys(browser_dist, HKEY_CURRENT_USER, suffix, |
815 suffix, installer_state.target_path(), &ret); | 786 installer_state.target_path(), &ret); |
787 | |
788 // If the user's Chrome is registered with a suffix: it is possible that old | |
789 // unsuffixed registrations were left in HKCU (e.g. if this install was | |
790 // previously installed with no suffix in HKCU (old suffix rules) and later | |
791 // had to be suffixed when fully registered in HKLM). | |
792 // Remove remaining HKCU entries with no suffix if any. | |
793 if (!suffix.empty()) { | |
794 DeleteChromeRegistrationKeys(browser_dist, HKEY_CURRENT_USER, L"", | |
795 installer_state.target_path(), &ret); | |
796 } | |
816 | 797 |
817 // Chrome is registered in HKLM for all system-level installs and for | 798 // Chrome is registered in HKLM for all system-level installs and for |
818 // user-level installs for which Chrome has been made the default browser. | 799 // user-level installs for which Chrome has been made the default browser. |
819 // Always remove the HKLM registration for system-level installs. For | 800 // Always remove the HKLM registration for system-level installs. For |
820 // user-level installs, only remove it if both: 1) this uninstall isn't a | 801 // user-level installs, only remove it if either: 1) The registration has a |
821 // self-destruct following the installation of system-level Chrome (because | 802 // suffix, or 2) |remove_all| is true which means this is not a self-destruct |
822 // the system-level Chrome owns the HKLM registration now), and 2) this user | 803 // following a system-level Chrome install (which would otherwise need the |
823 // had made Chrome their default browser. | 804 // same HKLM registrations). |
824 if (installer_state.system_install() || | 805 if (installer_state.system_install() || !suffix.empty() || remove_all) { |
825 (remove_all && | 806 DeleteChromeRegistrationKeys(browser_dist, HKEY_LOCAL_MACHINE, suffix, |
826 (!suffix.empty() || CurrentUserHasDefaultBrowser(installer_state)))) { | 807 installer_state.target_path(), &ret); |
827 DeleteChromeRegistrationKeys(product.distribution(), HKEY_LOCAL_MACHINE, | |
828 suffix, installer_state.target_path(), &ret); | |
829 } | 808 } |
830 | 809 |
831 ProcessDelegateExecuteWorkItems(installer_state, product); | 810 ProcessDelegateExecuteWorkItems(installer_state, product); |
832 | 811 |
833 if (!is_chrome) { | 812 if (!is_chrome) { |
834 ProcessChromeFrameWorkItems(original_state, installer_state, setup_path, | 813 ProcessChromeFrameWorkItems(original_state, installer_state, setup_path, |
835 product); | 814 product); |
836 } | 815 } |
837 | 816 |
838 if (installer_state.is_multi_install()) | 817 if (installer_state.is_multi_install()) |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
952 | 931 |
953 // Try and delete the preserved local state once the post-install | 932 // Try and delete the preserved local state once the post-install |
954 // operations are complete. | 933 // operations are complete. |
955 if (!backup_state_file.empty()) | 934 if (!backup_state_file.empty()) |
956 file_util::Delete(backup_state_file, false); | 935 file_util::Delete(backup_state_file, false); |
957 | 936 |
958 return ret; | 937 return ret; |
959 } | 938 } |
960 | 939 |
961 } // namespace installer | 940 } // namespace installer |
OLD | NEW |