| 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 | 10 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 } | 169 } |
| 170 | 170 |
| 171 void ClearRlzProductState() { | 171 void ClearRlzProductState() { |
| 172 const rlz_lib::AccessPoint points[] = {rlz_lib::CHROME_OMNIBOX, | 172 const rlz_lib::AccessPoint points[] = {rlz_lib::CHROME_OMNIBOX, |
| 173 rlz_lib::CHROME_HOME_PAGE, | 173 rlz_lib::CHROME_HOME_PAGE, |
| 174 rlz_lib::NO_ACCESS_POINT}; | 174 rlz_lib::NO_ACCESS_POINT}; |
| 175 | 175 |
| 176 rlz_lib::ClearProductState(rlz_lib::CHROME, points); | 176 rlz_lib::ClearProductState(rlz_lib::CHROME, points); |
| 177 | 177 |
| 178 // If chrome has been reactivated, clear all events for this brand as well. | 178 // If chrome has been reactivated, clear all events for this brand as well. |
| 179 string16 reactivation_brand_wide; | 179 base::string16 reactivation_brand_wide; |
| 180 if (GoogleUpdateSettings::GetReactivationBrand(&reactivation_brand_wide)) { | 180 if (GoogleUpdateSettings::GetReactivationBrand(&reactivation_brand_wide)) { |
| 181 std::string reactivation_brand(WideToASCII(reactivation_brand_wide)); | 181 std::string reactivation_brand(WideToASCII(reactivation_brand_wide)); |
| 182 rlz_lib::SupplementaryBranding branding(reactivation_brand.c_str()); | 182 rlz_lib::SupplementaryBranding branding(reactivation_brand.c_str()); |
| 183 rlz_lib::ClearProductState(rlz_lib::CHROME, points); | 183 rlz_lib::ClearProductState(rlz_lib::CHROME, points); |
| 184 } | 184 } |
| 185 } | 185 } |
| 186 | 186 |
| 187 // Decides whether setup.exe and the installer archive should be removed based | 187 // Decides whether setup.exe and the installer archive should be removed based |
| 188 // on the original and installer states: | 188 // on the original and installer states: |
| 189 // * non-multi product being uninstalled: remove both | 189 // * non-multi product being uninstalled: remove both |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 | 666 |
| 667 return should_delete; | 667 return should_delete; |
| 668 } | 668 } |
| 669 | 669 |
| 670 // Removes XP-era filetype registration making Chrome the default browser. | 670 // Removes XP-era filetype registration making Chrome the default browser. |
| 671 // MSDN (see http://msdn.microsoft.com/library/windows/desktop/cc144148.aspx) | 671 // MSDN (see http://msdn.microsoft.com/library/windows/desktop/cc144148.aspx) |
| 672 // tells us not to do this, but certain applications break following | 672 // tells us not to do this, but certain applications break following |
| 673 // uninstallation if we don't. | 673 // uninstallation if we don't. |
| 674 void RemoveFiletypeRegistration(const InstallerState& installer_state, | 674 void RemoveFiletypeRegistration(const InstallerState& installer_state, |
| 675 HKEY root, | 675 HKEY root, |
| 676 const string16& browser_entry_suffix) { | 676 const base::string16& browser_entry_suffix) { |
| 677 string16 classes_path(ShellUtil::kRegClasses); | 677 base::string16 classes_path(ShellUtil::kRegClasses); |
| 678 classes_path.push_back(base::FilePath::kSeparators[0]); | 678 classes_path.push_back(base::FilePath::kSeparators[0]); |
| 679 | 679 |
| 680 BrowserDistribution* distribution = BrowserDistribution::GetDistribution(); | 680 BrowserDistribution* distribution = BrowserDistribution::GetDistribution(); |
| 681 const string16 prog_id( | 681 const base::string16 prog_id( |
| 682 distribution->GetBrowserProgIdPrefix() + browser_entry_suffix); | 682 distribution->GetBrowserProgIdPrefix() + browser_entry_suffix); |
| 683 | 683 |
| 684 // Delete each filetype association if it references this Chrome. Take care | 684 // Delete each filetype association if it references this Chrome. Take care |
| 685 // not to delete the association if it references a system-level install of | 685 // not to delete the association if it references a system-level install of |
| 686 // Chrome (only a risk if the suffix is empty). Don't delete the whole key | 686 // Chrome (only a risk if the suffix is empty). Don't delete the whole key |
| 687 // since other apps may have stored data there. | 687 // since other apps may have stored data there. |
| 688 std::vector<const wchar_t*> cleared_assocs; | 688 std::vector<const wchar_t*> cleared_assocs; |
| 689 if (installer_state.system_install() || | 689 if (installer_state.system_install() || |
| 690 !browser_entry_suffix.empty() || | 690 !browser_entry_suffix.empty() || |
| 691 !base::win::RegKey(HKEY_LOCAL_MACHINE, (classes_path + prog_id).c_str(), | 691 !base::win::RegKey(HKEY_LOCAL_MACHINE, (classes_path + prog_id).c_str(), |
| 692 KEY_QUERY_VALUE).Valid()) { | 692 KEY_QUERY_VALUE).Valid()) { |
| 693 InstallUtil::ValueEquals prog_id_pred(prog_id); | 693 InstallUtil::ValueEquals prog_id_pred(prog_id); |
| 694 for (const wchar_t* const* filetype = | 694 for (const wchar_t* const* filetype = |
| 695 &ShellUtil::kPotentialFileAssociations[0]; *filetype != NULL; | 695 &ShellUtil::kPotentialFileAssociations[0]; *filetype != NULL; |
| 696 ++filetype) { | 696 ++filetype) { |
| 697 if (InstallUtil::DeleteRegistryValueIf( | 697 if (InstallUtil::DeleteRegistryValueIf( |
| 698 root, (classes_path + *filetype).c_str(), NULL, | 698 root, (classes_path + *filetype).c_str(), NULL, |
| 699 prog_id_pred) == InstallUtil::DELETED) { | 699 prog_id_pred) == InstallUtil::DELETED) { |
| 700 cleared_assocs.push_back(*filetype); | 700 cleared_assocs.push_back(*filetype); |
| 701 } | 701 } |
| 702 } | 702 } |
| 703 } | 703 } |
| 704 | 704 |
| 705 // For all filetype associations in HKLM that have just been removed, attempt | 705 // For all filetype associations in HKLM that have just been removed, attempt |
| 706 // to restore some reasonable value. We have no definitive way of knowing | 706 // to restore some reasonable value. We have no definitive way of knowing |
| 707 // what handlers are the most appropriate, so we use a fixed mapping based on | 707 // what handlers are the most appropriate, so we use a fixed mapping based on |
| 708 // the default values for a fresh install of Windows. | 708 // the default values for a fresh install of Windows. |
| 709 if (root == HKEY_LOCAL_MACHINE) { | 709 if (root == HKEY_LOCAL_MACHINE) { |
| 710 string16 assoc; | 710 base::string16 assoc; |
| 711 base::win::RegKey key; | 711 base::win::RegKey key; |
| 712 | 712 |
| 713 for (size_t i = 0; i < cleared_assocs.size(); ++i) { | 713 for (size_t i = 0; i < cleared_assocs.size(); ++i) { |
| 714 const wchar_t* replacement_prog_id = NULL; | 714 const wchar_t* replacement_prog_id = NULL; |
| 715 assoc.assign(cleared_assocs[i]); | 715 assoc.assign(cleared_assocs[i]); |
| 716 | 716 |
| 717 // Inelegant, but simpler than a pure data-driven approach. | 717 // Inelegant, but simpler than a pure data-driven approach. |
| 718 if (assoc == L".htm" || assoc == L".html") | 718 if (assoc == L".htm" || assoc == L".html") |
| 719 replacement_prog_id = L"htmlfile"; | 719 replacement_prog_id = L"htmlfile"; |
| 720 else if (assoc == L".xht" || assoc == L".xhtml") | 720 else if (assoc == L".xht" || assoc == L".xhtml") |
| (...skipping 13 matching lines...) Expand all Loading... |
| 734 LOG(ERROR) << "Failed to restore system-level filetype association " | 734 LOG(ERROR) << "Failed to restore system-level filetype association " |
| 735 << assoc << " = " << replacement_prog_id; | 735 << assoc << " = " << replacement_prog_id; |
| 736 } | 736 } |
| 737 } | 737 } |
| 738 } | 738 } |
| 739 } | 739 } |
| 740 | 740 |
| 741 bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, | 741 bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, |
| 742 BrowserDistribution* dist, | 742 BrowserDistribution* dist, |
| 743 HKEY root, | 743 HKEY root, |
| 744 const string16& browser_entry_suffix, | 744 const base::string16& browser_entry_suffix, |
| 745 InstallStatus* exit_code) { | 745 InstallStatus* exit_code) { |
| 746 DCHECK(exit_code); | 746 DCHECK(exit_code); |
| 747 if (dist->GetDefaultBrowserControlPolicy() == | 747 if (dist->GetDefaultBrowserControlPolicy() == |
| 748 BrowserDistribution::DEFAULT_BROWSER_UNSUPPORTED) { | 748 BrowserDistribution::DEFAULT_BROWSER_UNSUPPORTED) { |
| 749 // We should have never set those keys. | 749 // We should have never set those keys. |
| 750 return true; | 750 return true; |
| 751 } | 751 } |
| 752 | 752 |
| 753 base::FilePath chrome_exe(installer_state.target_path().Append(kChromeExe)); | 753 base::FilePath chrome_exe(installer_state.target_path().Append(kChromeExe)); |
| 754 | 754 |
| 755 // Delete Software\Classes\ChromeHTML. | 755 // Delete Software\Classes\ChromeHTML. |
| 756 const string16 prog_id( | 756 const base::string16 prog_id( |
| 757 dist->GetBrowserProgIdPrefix() + browser_entry_suffix); | 757 dist->GetBrowserProgIdPrefix() + browser_entry_suffix); |
| 758 string16 reg_prog_id(ShellUtil::kRegClasses); | 758 base::string16 reg_prog_id(ShellUtil::kRegClasses); |
| 759 reg_prog_id.push_back(base::FilePath::kSeparators[0]); | 759 reg_prog_id.push_back(base::FilePath::kSeparators[0]); |
| 760 reg_prog_id.append(prog_id); | 760 reg_prog_id.append(prog_id); |
| 761 InstallUtil::DeleteRegistryKey(root, reg_prog_id); | 761 InstallUtil::DeleteRegistryKey(root, reg_prog_id); |
| 762 | 762 |
| 763 // Delete Software\Classes\Chrome. | 763 // Delete Software\Classes\Chrome. |
| 764 string16 reg_app_id(ShellUtil::kRegClasses); | 764 base::string16 reg_app_id(ShellUtil::kRegClasses); |
| 765 reg_app_id.push_back(base::FilePath::kSeparators[0]); | 765 reg_app_id.push_back(base::FilePath::kSeparators[0]); |
| 766 // Append the requested suffix manually here (as ShellUtil::GetBrowserModelId | 766 // Append the requested suffix manually here (as ShellUtil::GetBrowserModelId |
| 767 // would otherwise try to figure out the currently installed suffix). | 767 // would otherwise try to figure out the currently installed suffix). |
| 768 reg_app_id.append(dist->GetBaseAppId() + browser_entry_suffix); | 768 reg_app_id.append(dist->GetBaseAppId() + browser_entry_suffix); |
| 769 InstallUtil::DeleteRegistryKey(root, reg_app_id); | 769 InstallUtil::DeleteRegistryKey(root, reg_app_id); |
| 770 | 770 |
| 771 // Delete all Start Menu Internet registrations that refer to this Chrome. | 771 // Delete all Start Menu Internet registrations that refer to this Chrome. |
| 772 { | 772 { |
| 773 using base::win::RegistryKeyIterator; | 773 using base::win::RegistryKeyIterator; |
| 774 InstallUtil::ProgramCompare open_command_pred(chrome_exe); | 774 InstallUtil::ProgramCompare open_command_pred(chrome_exe); |
| 775 string16 client_name; | 775 base::string16 client_name; |
| 776 string16 client_key; | 776 base::string16 client_key; |
| 777 string16 open_key; | 777 base::string16 open_key; |
| 778 for (RegistryKeyIterator iter(root, ShellUtil::kRegStartMenuInternet); | 778 for (RegistryKeyIterator iter(root, ShellUtil::kRegStartMenuInternet); |
| 779 iter.Valid(); ++iter) { | 779 iter.Valid(); ++iter) { |
| 780 client_name.assign(iter.Name()); | 780 client_name.assign(iter.Name()); |
| 781 client_key.assign(ShellUtil::kRegStartMenuInternet) | 781 client_key.assign(ShellUtil::kRegStartMenuInternet) |
| 782 .append(1, L'\\') | 782 .append(1, L'\\') |
| 783 .append(client_name); | 783 .append(client_name); |
| 784 open_key.assign(client_key).append(ShellUtil::kRegShellOpen); | 784 open_key.assign(client_key).append(ShellUtil::kRegShellOpen); |
| 785 if (InstallUtil::DeleteRegistryKeyIf(root, client_key, open_key, NULL, | 785 if (InstallUtil::DeleteRegistryKeyIf(root, client_key, open_key, NULL, |
| 786 open_command_pred) != InstallUtil::NOT_FOUND) { | 786 open_command_pred) != InstallUtil::NOT_FOUND) { |
| 787 // Delete the default value of SOFTWARE\Clients\StartMenuInternet if it | 787 // Delete the default value of SOFTWARE\Clients\StartMenuInternet if it |
| 788 // references this Chrome (i.e., if it was made the default browser). | 788 // references this Chrome (i.e., if it was made the default browser). |
| 789 InstallUtil::DeleteRegistryValueIf( | 789 InstallUtil::DeleteRegistryValueIf( |
| 790 root, ShellUtil::kRegStartMenuInternet, NULL, | 790 root, ShellUtil::kRegStartMenuInternet, NULL, |
| 791 InstallUtil::ValueEquals(client_name)); | 791 InstallUtil::ValueEquals(client_name)); |
| 792 // Also delete the value for the default user if we're operating in | 792 // Also delete the value for the default user if we're operating in |
| 793 // HKLM. | 793 // HKLM. |
| 794 if (root == HKEY_LOCAL_MACHINE) { | 794 if (root == HKEY_LOCAL_MACHINE) { |
| 795 InstallUtil::DeleteRegistryValueIf( | 795 InstallUtil::DeleteRegistryValueIf( |
| 796 HKEY_USERS, | 796 HKEY_USERS, |
| 797 string16(L".DEFAULT\\").append( | 797 base::string16(L".DEFAULT\\").append( |
| 798 ShellUtil::kRegStartMenuInternet).c_str(), | 798 ShellUtil::kRegStartMenuInternet).c_str(), |
| 799 NULL, InstallUtil::ValueEquals(client_name)); | 799 NULL, InstallUtil::ValueEquals(client_name)); |
| 800 } | 800 } |
| 801 } | 801 } |
| 802 } | 802 } |
| 803 } | 803 } |
| 804 | 804 |
| 805 // Delete Software\RegisteredApplications\Chromium | 805 // Delete Software\RegisteredApplications\Chromium |
| 806 InstallUtil::DeleteRegistryValue( | 806 InstallUtil::DeleteRegistryValue( |
| 807 root, ShellUtil::kRegRegisteredApplications, | 807 root, ShellUtil::kRegRegisteredApplications, |
| 808 dist->GetBaseAppName() + browser_entry_suffix); | 808 dist->GetBaseAppName() + browser_entry_suffix); |
| 809 | 809 |
| 810 // Delete the App Paths and Applications keys that let Explorer find Chrome: | 810 // Delete the App Paths and Applications keys that let Explorer find Chrome: |
| 811 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121 | 811 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121 |
| 812 string16 app_key(ShellUtil::kRegClasses); | 812 base::string16 app_key(ShellUtil::kRegClasses); |
| 813 app_key.push_back(base::FilePath::kSeparators[0]); | 813 app_key.push_back(base::FilePath::kSeparators[0]); |
| 814 app_key.append(L"Applications"); | 814 app_key.append(L"Applications"); |
| 815 app_key.push_back(base::FilePath::kSeparators[0]); | 815 app_key.push_back(base::FilePath::kSeparators[0]); |
| 816 app_key.append(installer::kChromeExe); | 816 app_key.append(installer::kChromeExe); |
| 817 InstallUtil::DeleteRegistryKey(root, app_key); | 817 InstallUtil::DeleteRegistryKey(root, app_key); |
| 818 | 818 |
| 819 string16 app_path_key(ShellUtil::kAppPathsRegistryKey); | 819 base::string16 app_path_key(ShellUtil::kAppPathsRegistryKey); |
| 820 app_path_key.push_back(base::FilePath::kSeparators[0]); | 820 app_path_key.push_back(base::FilePath::kSeparators[0]); |
| 821 app_path_key.append(installer::kChromeExe); | 821 app_path_key.append(installer::kChromeExe); |
| 822 InstallUtil::DeleteRegistryKey(root, app_path_key); | 822 InstallUtil::DeleteRegistryKey(root, app_path_key); |
| 823 | 823 |
| 824 // Cleanup OpenWithList and OpenWithProgids: | 824 // Cleanup OpenWithList and OpenWithProgids: |
| 825 // http://msdn.microsoft.com/en-us/library/bb166549 | 825 // http://msdn.microsoft.com/en-us/library/bb166549 |
| 826 string16 file_assoc_key; | 826 base::string16 file_assoc_key; |
| 827 string16 open_with_list_key; | 827 base::string16 open_with_list_key; |
| 828 string16 open_with_progids_key; | 828 base::string16 open_with_progids_key; |
| 829 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; ++i) { | 829 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; ++i) { |
| 830 file_assoc_key.assign(ShellUtil::kRegClasses); | 830 file_assoc_key.assign(ShellUtil::kRegClasses); |
| 831 file_assoc_key.push_back(base::FilePath::kSeparators[0]); | 831 file_assoc_key.push_back(base::FilePath::kSeparators[0]); |
| 832 file_assoc_key.append(ShellUtil::kPotentialFileAssociations[i]); | 832 file_assoc_key.append(ShellUtil::kPotentialFileAssociations[i]); |
| 833 file_assoc_key.push_back(base::FilePath::kSeparators[0]); | 833 file_assoc_key.push_back(base::FilePath::kSeparators[0]); |
| 834 | 834 |
| 835 open_with_list_key.assign(file_assoc_key); | 835 open_with_list_key.assign(file_assoc_key); |
| 836 open_with_list_key.append(L"OpenWithList"); | 836 open_with_list_key.append(L"OpenWithList"); |
| 837 open_with_list_key.push_back(base::FilePath::kSeparators[0]); | 837 open_with_list_key.push_back(base::FilePath::kSeparators[0]); |
| 838 open_with_list_key.append(installer::kChromeExe); | 838 open_with_list_key.append(installer::kChromeExe); |
| 839 InstallUtil::DeleteRegistryKey(root, open_with_list_key); | 839 InstallUtil::DeleteRegistryKey(root, open_with_list_key); |
| 840 | 840 |
| 841 open_with_progids_key.assign(file_assoc_key); | 841 open_with_progids_key.assign(file_assoc_key); |
| 842 open_with_progids_key.append(ShellUtil::kRegOpenWithProgids); | 842 open_with_progids_key.append(ShellUtil::kRegOpenWithProgids); |
| 843 InstallUtil::DeleteRegistryValue(root, open_with_progids_key, prog_id); | 843 InstallUtil::DeleteRegistryValue(root, open_with_progids_key, prog_id); |
| 844 } | 844 } |
| 845 | 845 |
| 846 // Cleanup in case Chrome had been made the default browser. | 846 // Cleanup in case Chrome had been made the default browser. |
| 847 | 847 |
| 848 // Delete the default value of SOFTWARE\Clients\StartMenuInternet if it | 848 // Delete the default value of SOFTWARE\Clients\StartMenuInternet if it |
| 849 // references this Chrome. Do this explicitly here for the case where HKCU is | 849 // references this Chrome. Do this explicitly here for the case where HKCU is |
| 850 // being processed; the iteration above will have no hits since registration | 850 // being processed; the iteration above will have no hits since registration |
| 851 // lives in HKLM. | 851 // lives in HKLM. |
| 852 InstallUtil::DeleteRegistryValueIf( | 852 InstallUtil::DeleteRegistryValueIf( |
| 853 root, ShellUtil::kRegStartMenuInternet, NULL, | 853 root, ShellUtil::kRegStartMenuInternet, NULL, |
| 854 InstallUtil::ValueEquals(dist->GetBaseAppName() + browser_entry_suffix)); | 854 InstallUtil::ValueEquals(dist->GetBaseAppName() + browser_entry_suffix)); |
| 855 | 855 |
| 856 // Delete each protocol association if it references this Chrome. | 856 // Delete each protocol association if it references this Chrome. |
| 857 InstallUtil::ProgramCompare open_command_pred(chrome_exe); | 857 InstallUtil::ProgramCompare open_command_pred(chrome_exe); |
| 858 string16 parent_key(ShellUtil::kRegClasses); | 858 base::string16 parent_key(ShellUtil::kRegClasses); |
| 859 parent_key.push_back(base::FilePath::kSeparators[0]); | 859 parent_key.push_back(base::FilePath::kSeparators[0]); |
| 860 const string16::size_type base_length = parent_key.size(); | 860 const base::string16::size_type base_length = parent_key.size(); |
| 861 string16 child_key; | 861 base::string16 child_key; |
| 862 for (const wchar_t* const* proto = | 862 for (const wchar_t* const* proto = |
| 863 &ShellUtil::kPotentialProtocolAssociations[0]; | 863 &ShellUtil::kPotentialProtocolAssociations[0]; |
| 864 *proto != NULL; | 864 *proto != NULL; |
| 865 ++proto) { | 865 ++proto) { |
| 866 parent_key.resize(base_length); | 866 parent_key.resize(base_length); |
| 867 parent_key.append(*proto); | 867 parent_key.append(*proto); |
| 868 child_key.assign(parent_key).append(ShellUtil::kRegShellOpen); | 868 child_key.assign(parent_key).append(ShellUtil::kRegShellOpen); |
| 869 InstallUtil::DeleteRegistryKeyIf(root, parent_key, child_key, NULL, | 869 InstallUtil::DeleteRegistryKeyIf(root, parent_key, child_key, NULL, |
| 870 open_command_pred); | 870 open_command_pred); |
| 871 } | 871 } |
| 872 | 872 |
| 873 RemoveFiletypeRegistration(installer_state, root, browser_entry_suffix); | 873 RemoveFiletypeRegistration(installer_state, root, browser_entry_suffix); |
| 874 | 874 |
| 875 *exit_code = installer::UNINSTALL_SUCCESSFUL; | 875 *exit_code = installer::UNINSTALL_SUCCESSFUL; |
| 876 return true; | 876 return true; |
| 877 } | 877 } |
| 878 | 878 |
| 879 void RemoveChromeLegacyRegistryKeys(BrowserDistribution* dist, | 879 void RemoveChromeLegacyRegistryKeys(BrowserDistribution* dist, |
| 880 const string16& chrome_exe) { | 880 const base::string16& chrome_exe) { |
| 881 // We used to register Chrome to handle crx files, but this turned out | 881 // We used to register Chrome to handle crx files, but this turned out |
| 882 // to be not worth the hassle. Remove these old registry entries if | 882 // to be not worth the hassle. Remove these old registry entries if |
| 883 // they exist. See: http://codereview.chromium.org/210007 | 883 // they exist. See: http://codereview.chromium.org/210007 |
| 884 | 884 |
| 885 #if defined(GOOGLE_CHROME_BUILD) | 885 #if defined(GOOGLE_CHROME_BUILD) |
| 886 const wchar_t kChromeExtProgId[] = L"ChromeExt"; | 886 const wchar_t kChromeExtProgId[] = L"ChromeExt"; |
| 887 #else | 887 #else |
| 888 const wchar_t kChromeExtProgId[] = L"ChromiumExt"; | 888 const wchar_t kChromeExtProgId[] = L"ChromiumExt"; |
| 889 #endif | 889 #endif |
| 890 | 890 |
| 891 HKEY roots[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; | 891 HKEY roots[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; |
| 892 for (size_t i = 0; i < arraysize(roots); ++i) { | 892 for (size_t i = 0; i < arraysize(roots); ++i) { |
| 893 string16 suffix; | 893 base::string16 suffix; |
| 894 if (roots[i] == HKEY_LOCAL_MACHINE) | 894 if (roots[i] == HKEY_LOCAL_MACHINE) |
| 895 suffix = ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe); | 895 suffix = ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe); |
| 896 | 896 |
| 897 // Delete Software\Classes\ChromeExt, | 897 // Delete Software\Classes\ChromeExt, |
| 898 string16 ext_prog_id(ShellUtil::kRegClasses); | 898 base::string16 ext_prog_id(ShellUtil::kRegClasses); |
| 899 ext_prog_id.push_back(base::FilePath::kSeparators[0]); | 899 ext_prog_id.push_back(base::FilePath::kSeparators[0]); |
| 900 ext_prog_id.append(kChromeExtProgId); | 900 ext_prog_id.append(kChromeExtProgId); |
| 901 ext_prog_id.append(suffix); | 901 ext_prog_id.append(suffix); |
| 902 InstallUtil::DeleteRegistryKey(roots[i], ext_prog_id); | 902 InstallUtil::DeleteRegistryKey(roots[i], ext_prog_id); |
| 903 | 903 |
| 904 // Delete Software\Classes\.crx, | 904 // Delete Software\Classes\.crx, |
| 905 string16 ext_association(ShellUtil::kRegClasses); | 905 base::string16 ext_association(ShellUtil::kRegClasses); |
| 906 ext_association.append(L"\\"); | 906 ext_association.append(L"\\"); |
| 907 ext_association.append(extensions::kExtensionFileExtension); | 907 ext_association.append(extensions::kExtensionFileExtension); |
| 908 InstallUtil::DeleteRegistryKey(roots[i], ext_association); | 908 InstallUtil::DeleteRegistryKey(roots[i], ext_association); |
| 909 } | 909 } |
| 910 } | 910 } |
| 911 | 911 |
| 912 // Builds and executes a work item list to remove DelegateExecute verb handler | 912 // Builds and executes a work item list to remove DelegateExecute verb handler |
| 913 // work items for |product|. This will be a noop for products whose | 913 // work items for |product|. This will be a noop for products whose |
| 914 // corresponding BrowserDistribution implementations do not publish a CLSID via | 914 // corresponding BrowserDistribution implementations do not publish a CLSID via |
| 915 // GetCommandExecuteImplClsid. | 915 // GetCommandExecuteImplClsid. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 932 BrowserDistribution* distribution = product.distribution(); | 932 BrowserDistribution* distribution = product.distribution(); |
| 933 | 933 |
| 934 if (!product.is_chrome() || !installer_state.system_install()) { | 934 if (!product.is_chrome() || !installer_state.system_install()) { |
| 935 const char* install_level = | 935 const char* install_level = |
| 936 installer_state.system_install() ? "system" : "user"; | 936 installer_state.system_install() ? "system" : "user"; |
| 937 VLOG(1) << "No Active Setup processing to do for " << install_level | 937 VLOG(1) << "No Active Setup processing to do for " << install_level |
| 938 << "-level " << distribution->GetDisplayName(); | 938 << "-level " << distribution->GetDisplayName(); |
| 939 return; | 939 return; |
| 940 } | 940 } |
| 941 | 941 |
| 942 const string16 active_setup_path( | 942 const base::string16 active_setup_path( |
| 943 InstallUtil::GetActiveSetupPath(distribution)); | 943 InstallUtil::GetActiveSetupPath(distribution)); |
| 944 InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, active_setup_path); | 944 InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, active_setup_path); |
| 945 | 945 |
| 946 // Windows leaves keys behind in HKCU\\Software\\(Wow6432Node\\)?Microsoft\\ | 946 // Windows leaves keys behind in HKCU\\Software\\(Wow6432Node\\)?Microsoft\\ |
| 947 // Active Setup\\Installed Components\\{guid} | 947 // Active Setup\\Installed Components\\{guid} |
| 948 // for every user that logged in since system-level Chrome was installed. | 948 // for every user that logged in since system-level Chrome was installed. |
| 949 // This is a problem because Windows compares the value of the Version subkey | 949 // This is a problem because Windows compares the value of the Version subkey |
| 950 // in there with the value of the Version subkey in the matching HKLM entries | 950 // in there with the value of the Version subkey in the matching HKLM entries |
| 951 // before running Chrome's Active Setup so if Chrome was to be reinstalled | 951 // before running Chrome's Active Setup so if Chrome was to be reinstalled |
| 952 // with a lesser version (e.g. switching back to a more stable channel), the | 952 // with a lesser version (e.g. switching back to a more stable channel), the |
| 953 // affected users would not have Chrome's Active Setup called until Chrome | 953 // affected users would not have Chrome's Active Setup called until Chrome |
| 954 // eventually updated passed that user's registered Version. | 954 // eventually updated passed that user's registered Version. |
| 955 // | 955 // |
| 956 // It is however very hard to delete those values as the registry hives for | 956 // It is however very hard to delete those values as the registry hives for |
| 957 // other users are not loaded by default under HKEY_USERS (unless a user is | 957 // other users are not loaded by default under HKEY_USERS (unless a user is |
| 958 // logged on or has a process impersonating him). | 958 // logged on or has a process impersonating him). |
| 959 // | 959 // |
| 960 // Following our best effort uninstall practices, try to delete the value in | 960 // Following our best effort uninstall practices, try to delete the value in |
| 961 // all users hives. If a given user's hive is not loaded, try to load it to | 961 // all users hives. If a given user's hive is not loaded, try to load it to |
| 962 // proceed with the deletion (failure to do so is ignored). | 962 // proceed with the deletion (failure to do so is ignored). |
| 963 | 963 |
| 964 static const wchar_t kProfileList[] = | 964 static const wchar_t kProfileList[] = |
| 965 L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\"; | 965 L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\"; |
| 966 | 966 |
| 967 // Windows automatically adds Wow6432Node when creating/deleting the HKLM key, | 967 // Windows automatically adds Wow6432Node when creating/deleting the HKLM key, |
| 968 // but doesn't seem to do so when manually deleting the user-level keys it | 968 // but doesn't seem to do so when manually deleting the user-level keys it |
| 969 // created. | 969 // created. |
| 970 string16 alternate_active_setup_path(active_setup_path); | 970 base::string16 alternate_active_setup_path(active_setup_path); |
| 971 alternate_active_setup_path.insert(arraysize("Software\\") - 1, | 971 alternate_active_setup_path.insert(arraysize("Software\\") - 1, |
| 972 L"Wow6432Node\\"); | 972 L"Wow6432Node\\"); |
| 973 | 973 |
| 974 // These two privileges are required by RegLoadKey() and RegUnloadKey() below. | 974 // These two privileges are required by RegLoadKey() and RegUnloadKey() below. |
| 975 ScopedTokenPrivilege se_restore_name_privilege(SE_RESTORE_NAME); | 975 ScopedTokenPrivilege se_restore_name_privilege(SE_RESTORE_NAME); |
| 976 ScopedTokenPrivilege se_backup_name_privilege(SE_BACKUP_NAME); | 976 ScopedTokenPrivilege se_backup_name_privilege(SE_BACKUP_NAME); |
| 977 if (!se_restore_name_privilege.is_enabled() || | 977 if (!se_restore_name_privilege.is_enabled() || |
| 978 !se_backup_name_privilege.is_enabled()) { | 978 !se_backup_name_privilege.is_enabled()) { |
| 979 // This is not a critical failure as those privileges aren't required to | 979 // This is not a critical failure as those privileges aren't required to |
| 980 // clean hives that are already loaded, but attempts to LoadRegKey() below | 980 // clean hives that are already loaded, but attempts to LoadRegKey() below |
| 981 // will fail. | 981 // will fail. |
| 982 LOG(WARNING) << "Failed to enable privileges required to load registry " | 982 LOG(WARNING) << "Failed to enable privileges required to load registry " |
| 983 "hives."; | 983 "hives."; |
| 984 } | 984 } |
| 985 | 985 |
| 986 for (base::win::RegistryKeyIterator it(HKEY_LOCAL_MACHINE, kProfileList); | 986 for (base::win::RegistryKeyIterator it(HKEY_LOCAL_MACHINE, kProfileList); |
| 987 it.Valid(); ++it) { | 987 it.Valid(); ++it) { |
| 988 const wchar_t* profile_sid = it.Name(); | 988 const wchar_t* profile_sid = it.Name(); |
| 989 | 989 |
| 990 // First check if this user's registry hive needs to be loaded in | 990 // First check if this user's registry hive needs to be loaded in |
| 991 // HKEY_USERS. | 991 // HKEY_USERS. |
| 992 base::win::RegKey user_reg_root_probe( | 992 base::win::RegKey user_reg_root_probe( |
| 993 HKEY_USERS, profile_sid, KEY_READ); | 993 HKEY_USERS, profile_sid, KEY_READ); |
| 994 bool loaded_hive = false; | 994 bool loaded_hive = false; |
| 995 if (!user_reg_root_probe.Valid()) { | 995 if (!user_reg_root_probe.Valid()) { |
| 996 VLOG(1) << "Attempting to load registry hive for " << profile_sid; | 996 VLOG(1) << "Attempting to load registry hive for " << profile_sid; |
| 997 | 997 |
| 998 string16 reg_profile_info_path(kProfileList); | 998 base::string16 reg_profile_info_path(kProfileList); |
| 999 reg_profile_info_path.append(profile_sid); | 999 reg_profile_info_path.append(profile_sid); |
| 1000 base::win::RegKey reg_profile_info_key( | 1000 base::win::RegKey reg_profile_info_key( |
| 1001 HKEY_LOCAL_MACHINE, reg_profile_info_path.c_str(), KEY_READ); | 1001 HKEY_LOCAL_MACHINE, reg_profile_info_path.c_str(), KEY_READ); |
| 1002 | 1002 |
| 1003 string16 profile_path; | 1003 base::string16 profile_path; |
| 1004 LONG result = reg_profile_info_key.ReadValue(L"ProfileImagePath", | 1004 LONG result = reg_profile_info_key.ReadValue(L"ProfileImagePath", |
| 1005 &profile_path); | 1005 &profile_path); |
| 1006 if (result != ERROR_SUCCESS) { | 1006 if (result != ERROR_SUCCESS) { |
| 1007 LOG(ERROR) << "Error reading ProfileImagePath: " << result; | 1007 LOG(ERROR) << "Error reading ProfileImagePath: " << result; |
| 1008 continue; | 1008 continue; |
| 1009 } | 1009 } |
| 1010 base::FilePath registry_hive_file(profile_path); | 1010 base::FilePath registry_hive_file(profile_path); |
| 1011 registry_hive_file = registry_hive_file.AppendASCII("NTUSER.DAT"); | 1011 registry_hive_file = registry_hive_file.AppendASCII("NTUSER.DAT"); |
| 1012 | 1012 |
| 1013 result = RegLoadKey(HKEY_USERS, profile_sid, | 1013 result = RegLoadKey(HKEY_USERS, profile_sid, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 | 1046 |
| 1047 InstallStatus UninstallProduct(const InstallationState& original_state, | 1047 InstallStatus UninstallProduct(const InstallationState& original_state, |
| 1048 const InstallerState& installer_state, | 1048 const InstallerState& installer_state, |
| 1049 const base::FilePath& setup_path, | 1049 const base::FilePath& setup_path, |
| 1050 const Product& product, | 1050 const Product& product, |
| 1051 bool remove_all, | 1051 bool remove_all, |
| 1052 bool force_uninstall, | 1052 bool force_uninstall, |
| 1053 const CommandLine& cmd_line) { | 1053 const CommandLine& cmd_line) { |
| 1054 InstallStatus status = installer::UNINSTALL_CONFIRMED; | 1054 InstallStatus status = installer::UNINSTALL_CONFIRMED; |
| 1055 BrowserDistribution* browser_dist = product.distribution(); | 1055 BrowserDistribution* browser_dist = product.distribution(); |
| 1056 const string16 chrome_exe( | 1056 const base::string16 chrome_exe( |
| 1057 installer_state.target_path().Append(installer::kChromeExe).value()); | 1057 installer_state.target_path().Append(installer::kChromeExe).value()); |
| 1058 | 1058 |
| 1059 bool is_chrome = product.is_chrome(); | 1059 bool is_chrome = product.is_chrome(); |
| 1060 | 1060 |
| 1061 VLOG(1) << "UninstallProduct: " << browser_dist->GetDisplayName(); | 1061 VLOG(1) << "UninstallProduct: " << browser_dist->GetDisplayName(); |
| 1062 | 1062 |
| 1063 if (force_uninstall) { | 1063 if (force_uninstall) { |
| 1064 // Since --force-uninstall command line option is used, we are going to | 1064 // Since --force-uninstall command line option is used, we are going to |
| 1065 // do silent uninstall. Try to close all running Chrome instances. | 1065 // do silent uninstall. Try to close all running Chrome instances. |
| 1066 // NOTE: We don't do this for Chrome Frame. | 1066 // NOTE: We don't do this for Chrome Frame. |
| 1067 if (is_chrome) | 1067 if (is_chrome) |
| 1068 CloseAllChromeProcesses(); | 1068 CloseAllChromeProcesses(); |
| 1069 } else if (is_chrome) { | 1069 } else if (is_chrome) { |
| 1070 // no --force-uninstall so lets show some UI dialog boxes. | 1070 // no --force-uninstall so lets show some UI dialog boxes. |
| 1071 status = IsChromeActiveOrUserCancelled(installer_state, product); | 1071 status = IsChromeActiveOrUserCancelled(installer_state, product); |
| 1072 if (status != installer::UNINSTALL_CONFIRMED && | 1072 if (status != installer::UNINSTALL_CONFIRMED && |
| 1073 status != installer::UNINSTALL_DELETE_PROFILE) | 1073 status != installer::UNINSTALL_DELETE_PROFILE) |
| 1074 return status; | 1074 return status; |
| 1075 | 1075 |
| 1076 const string16 suffix(ShellUtil::GetCurrentInstallationSuffix(browser_dist, | 1076 const base::string16 suffix( |
| 1077 chrome_exe)); | 1077 ShellUtil::GetCurrentInstallationSuffix(browser_dist, chrome_exe)); |
| 1078 | 1078 |
| 1079 // Check if we need admin rights to cleanup HKLM (the conditions for | 1079 // Check if we need admin rights to cleanup HKLM (the conditions for |
| 1080 // requiring a cleanup are the same as the conditions to do the actual | 1080 // requiring a cleanup are the same as the conditions to do the actual |
| 1081 // cleanup where DeleteChromeRegistrationKeys() is invoked for | 1081 // cleanup where DeleteChromeRegistrationKeys() is invoked for |
| 1082 // HKEY_LOCAL_MACHINE below). If we do, try to launch another uninstaller | 1082 // HKEY_LOCAL_MACHINE below). If we do, try to launch another uninstaller |
| 1083 // (silent) in elevated mode to do HKLM cleanup. | 1083 // (silent) in elevated mode to do HKLM cleanup. |
| 1084 // And continue uninstalling in the current process also to do HKCU cleanup. | 1084 // And continue uninstalling in the current process also to do HKCU cleanup. |
| 1085 if (remove_all && | 1085 if (remove_all && |
| 1086 ShellUtil::QuickIsChromeRegisteredInHKLM( | 1086 ShellUtil::QuickIsChromeRegisteredInHKLM( |
| 1087 browser_dist, chrome_exe, suffix) && | 1087 browser_dist, chrome_exe, suffix) && |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1137 } | 1137 } |
| 1138 | 1138 |
| 1139 DeleteShortcuts(installer_state, product, base::FilePath(chrome_exe)); | 1139 DeleteShortcuts(installer_state, product, base::FilePath(chrome_exe)); |
| 1140 } | 1140 } |
| 1141 | 1141 |
| 1142 // Delete the registry keys (Uninstall key and Version key). | 1142 // Delete the registry keys (Uninstall key and Version key). |
| 1143 HKEY reg_root = installer_state.root_key(); | 1143 HKEY reg_root = installer_state.root_key(); |
| 1144 | 1144 |
| 1145 // Note that we must retrieve the distribution-specific data before deleting | 1145 // Note that we must retrieve the distribution-specific data before deleting |
| 1146 // product.GetVersionKey(). | 1146 // product.GetVersionKey(). |
| 1147 string16 distribution_data(browser_dist->GetDistributionData(reg_root)); | 1147 base::string16 distribution_data(browser_dist->GetDistributionData(reg_root)); |
| 1148 | 1148 |
| 1149 // Remove Control Panel uninstall link. | 1149 // Remove Control Panel uninstall link. |
| 1150 if (product.ShouldCreateUninstallEntry()) { | 1150 if (product.ShouldCreateUninstallEntry()) { |
| 1151 InstallUtil::DeleteRegistryKey(reg_root, | 1151 InstallUtil::DeleteRegistryKey(reg_root, |
| 1152 browser_dist->GetUninstallRegPath()); | 1152 browser_dist->GetUninstallRegPath()); |
| 1153 } | 1153 } |
| 1154 | 1154 |
| 1155 // Remove Omaha product key. | 1155 // Remove Omaha product key. |
| 1156 InstallUtil::DeleteRegistryKey(reg_root, browser_dist->GetVersionKey()); | 1156 InstallUtil::DeleteRegistryKey(reg_root, browser_dist->GetVersionKey()); |
| 1157 | 1157 |
| 1158 // Also try to delete the MSI value in the ClientState key (it might not be | 1158 // Also try to delete the MSI value in the ClientState key (it might not be |
| 1159 // there). This is due to a Google Update behaviour where an uninstall and a | 1159 // there). This is due to a Google Update behaviour where an uninstall and a |
| 1160 // rapid reinstall might result in stale values from the old ClientState key | 1160 // rapid reinstall might result in stale values from the old ClientState key |
| 1161 // being picked up on reinstall. | 1161 // being picked up on reinstall. |
| 1162 product.SetMsiMarker(installer_state.system_install(), false); | 1162 product.SetMsiMarker(installer_state.system_install(), false); |
| 1163 | 1163 |
| 1164 InstallStatus ret = installer::UNKNOWN_STATUS; | 1164 InstallStatus ret = installer::UNKNOWN_STATUS; |
| 1165 | 1165 |
| 1166 if (is_chrome) { | 1166 if (is_chrome) { |
| 1167 const string16 suffix(ShellUtil::GetCurrentInstallationSuffix(browser_dist, | 1167 const base::string16 suffix( |
| 1168 chrome_exe)); | 1168 ShellUtil::GetCurrentInstallationSuffix(browser_dist, chrome_exe)); |
| 1169 | 1169 |
| 1170 // Remove all Chrome registration keys. | 1170 // Remove all Chrome registration keys. |
| 1171 // Registration data is put in HKCU for both system level and user level | 1171 // Registration data is put in HKCU for both system level and user level |
| 1172 // installs. | 1172 // installs. |
| 1173 DeleteChromeRegistrationKeys(installer_state, browser_dist, | 1173 DeleteChromeRegistrationKeys(installer_state, browser_dist, |
| 1174 HKEY_CURRENT_USER, suffix, &ret); | 1174 HKEY_CURRENT_USER, suffix, &ret); |
| 1175 | 1175 |
| 1176 // If the user's Chrome is registered with a suffix: it is possible that old | 1176 // If the user's Chrome is registered with a suffix: it is possible that old |
| 1177 // unsuffixed registrations were left in HKCU (e.g. if this install was | 1177 // unsuffixed registrations were left in HKCU (e.g. if this install was |
| 1178 // previously installed with no suffix in HKCU (old suffix rules if the user | 1178 // previously installed with no suffix in HKCU (old suffix rules if the user |
| 1179 // is not an admin (or declined UAC at first run)) and later had to be | 1179 // is not an admin (or declined UAC at first run)) and later had to be |
| 1180 // suffixed when fully registered in HKLM (e.g. when later making Chrome | 1180 // suffixed when fully registered in HKLM (e.g. when later making Chrome |
| 1181 // default through the UI)). | 1181 // default through the UI)). |
| 1182 // Remove remaining HKCU entries with no suffix if any. | 1182 // Remove remaining HKCU entries with no suffix if any. |
| 1183 if (!suffix.empty()) { | 1183 if (!suffix.empty()) { |
| 1184 DeleteChromeRegistrationKeys(installer_state, browser_dist, | 1184 DeleteChromeRegistrationKeys(installer_state, browser_dist, |
| 1185 HKEY_CURRENT_USER, string16(), &ret); | 1185 HKEY_CURRENT_USER, base::string16(), &ret); |
| 1186 | 1186 |
| 1187 // For similar reasons it is possible in very few installs (from | 1187 // For similar reasons it is possible in very few installs (from |
| 1188 // 21.0.1180.0 and fixed shortly after) to be installed with the new-style | 1188 // 21.0.1180.0 and fixed shortly after) to be installed with the new-style |
| 1189 // suffix, but have some old-style suffix registrations left behind. | 1189 // suffix, but have some old-style suffix registrations left behind. |
| 1190 string16 old_style_suffix; | 1190 base::string16 old_style_suffix; |
| 1191 if (ShellUtil::GetOldUserSpecificRegistrySuffix(&old_style_suffix) && | 1191 if (ShellUtil::GetOldUserSpecificRegistrySuffix(&old_style_suffix) && |
| 1192 suffix != old_style_suffix) { | 1192 suffix != old_style_suffix) { |
| 1193 DeleteChromeRegistrationKeys(installer_state, browser_dist, | 1193 DeleteChromeRegistrationKeys(installer_state, browser_dist, |
| 1194 HKEY_CURRENT_USER, old_style_suffix, &ret); | 1194 HKEY_CURRENT_USER, old_style_suffix, &ret); |
| 1195 } | 1195 } |
| 1196 } | 1196 } |
| 1197 | 1197 |
| 1198 // Chrome is registered in HKLM for all system-level installs and for | 1198 // Chrome is registered in HKLM for all system-level installs and for |
| 1199 // user-level installs for which Chrome has been made the default browser. | 1199 // user-level installs for which Chrome has been made the default browser. |
| 1200 // Always remove the HKLM registration for system-level installs. For | 1200 // Always remove the HKLM registration for system-level installs. For |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 original_state.GetProductState(installer_state.system_install(), | 1257 original_state.GetProductState(installer_state.system_install(), |
| 1258 browser_dist->GetType()); | 1258 browser_dist->GetType()); |
| 1259 | 1259 |
| 1260 // Delete shared registry keys as well (these require admin rights) if | 1260 // Delete shared registry keys as well (these require admin rights) if |
| 1261 // remove_all option is specified. | 1261 // remove_all option is specified. |
| 1262 if (remove_all) { | 1262 if (remove_all) { |
| 1263 if (!InstallUtil::IsChromeSxSProcess() && is_chrome) { | 1263 if (!InstallUtil::IsChromeSxSProcess() && is_chrome) { |
| 1264 // Delete media player registry key that exists only in HKLM. | 1264 // Delete media player registry key that exists only in HKLM. |
| 1265 // We don't delete this key in SxS uninstall or Chrome Frame uninstall | 1265 // We don't delete this key in SxS uninstall or Chrome Frame uninstall |
| 1266 // as we never set the key for those products. | 1266 // as we never set the key for those products. |
| 1267 string16 reg_path(installer::kMediaPlayerRegPath); | 1267 base::string16 reg_path(installer::kMediaPlayerRegPath); |
| 1268 reg_path.push_back(base::FilePath::kSeparators[0]); | 1268 reg_path.push_back(base::FilePath::kSeparators[0]); |
| 1269 reg_path.append(installer::kChromeExe); | 1269 reg_path.append(installer::kChromeExe); |
| 1270 InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, reg_path); | 1270 InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, reg_path); |
| 1271 } | 1271 } |
| 1272 | 1272 |
| 1273 // Unregister any dll servers that we may have registered for this | 1273 // Unregister any dll servers that we may have registered for this |
| 1274 // product. | 1274 // product. |
| 1275 if (product_state != NULL) { | 1275 if (product_state != NULL) { |
| 1276 std::vector<base::FilePath> com_dll_list; | 1276 std::vector<base::FilePath> com_dll_list; |
| 1277 product.AddComDllList(&com_dll_list); | 1277 product.AddComDllList(&com_dll_list); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1416 // If we need a reboot to continue, schedule the parent directories for | 1416 // If we need a reboot to continue, schedule the parent directories for |
| 1417 // deletion unconditionally. If they are not empty, the session manager | 1417 // deletion unconditionally. If they are not empty, the session manager |
| 1418 // will not delete them on reboot. | 1418 // will not delete them on reboot. |
| 1419 ScheduleParentAndGrandparentForDeletion(target_path); | 1419 ScheduleParentAndGrandparentForDeletion(target_path); |
| 1420 } else if (DeleteChromeDirectoriesIfEmpty(target_path) == DELETE_FAILED) { | 1420 } else if (DeleteChromeDirectoriesIfEmpty(target_path) == DELETE_FAILED) { |
| 1421 *uninstall_status = UNINSTALL_FAILED; | 1421 *uninstall_status = UNINSTALL_FAILED; |
| 1422 } | 1422 } |
| 1423 } | 1423 } |
| 1424 | 1424 |
| 1425 } // namespace installer | 1425 } // namespace installer |
| OLD | NEW |