Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(463)

Side by Side Diff: chrome/installer/setup/uninstall.cc

Issue 10810021: Register Chrome in Active Setup to be called by Windows at user login. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase onto 147656 Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/installer/setup/setup_util_unittest.cc ('k') | chrome/installer/util/util_constants.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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>
10
9 #include <vector> 11 #include <vector>
10 12
11 #include "base/file_util.h" 13 #include "base/file_util.h"
12 #include "base/path_service.h" 14 #include "base/path_service.h"
13 #include "base/process_util.h" 15 #include "base/process_util.h"
16 #include "base/string16.h"
14 #include "base/string_number_conversions.h" 17 #include "base/string_number_conversions.h"
15 #include "base/string_util.h" 18 #include "base/string_util.h"
16 #include "base/utf_string_conversions.h" 19 #include "base/utf_string_conversions.h"
17 #include "base/win/registry.h" 20 #include "base/win/registry.h"
18 #include "base/win/scoped_handle.h" 21 #include "base/win/scoped_handle.h"
19 #include "base/win/windows_version.h" 22 #include "base/win/windows_version.h"
20 #include "chrome/common/chrome_constants.h" 23 #include "chrome/common/chrome_constants.h"
21 #include "chrome/common/chrome_paths_internal.h" 24 #include "chrome/common/chrome_paths_internal.h"
22 #include "chrome/common/chrome_result_codes.h" 25 #include "chrome/common/chrome_result_codes.h"
23 #include "chrome/installer/setup/install.h" 26 #include "chrome/installer/setup/install.h"
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 // corresponding BrowserDistribution implementations do not publish 733 // corresponding BrowserDistribution implementations do not publish
731 // DelegateExecute data via an implementation of GetDelegateExecuteHandlerData. 734 // DelegateExecute data via an implementation of GetDelegateExecuteHandlerData.
732 bool ProcessDelegateExecuteWorkItems(const InstallerState& installer_state, 735 bool ProcessDelegateExecuteWorkItems(const InstallerState& installer_state,
733 const Product& product) { 736 const Product& product) {
734 scoped_ptr<WorkItemList> item_list(WorkItem::CreateNoRollbackWorkItemList()); 737 scoped_ptr<WorkItemList> item_list(WorkItem::CreateNoRollbackWorkItemList());
735 AddDelegateExecuteWorkItems(installer_state, FilePath(), Version(), product, 738 AddDelegateExecuteWorkItems(installer_state, FilePath(), Version(), product,
736 item_list.get()); 739 item_list.get());
737 return item_list->Do(); 740 return item_list->Do();
738 } 741 }
739 742
743 // Removes Active Setup entries from the registry. This cannot be done through
744 // a work items list as usual because of different paths based on conditionals,
745 // but otherwise respects the no rollback/best effort uninstall mentality.
746 // This will only apply for system-level installs of Chrome/Chromium and will be
747 // a no-op for all other types of installs.
748 void UninstallActiveSetupEntries(const InstallerState& installer_state,
749 const Product& product) {
750 VLOG(1) << "Uninstalling registry entries for ActiveSetup.";
751 BrowserDistribution* distribution = product.distribution();
752
753 if (!product.is_chrome() || !installer_state.system_install()) {
754 const char* install_level =
755 installer_state.system_install() ? "system" : "user";
756 VLOG(1) << "No Active Setup processing to do for " << install_level
757 << "-level " << distribution->GetAppShortCutName();
758 return;
759 }
760
761 const string16 active_setup_path(GetActiveSetupPath(distribution));
762 InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, active_setup_path);
763
764 // Windows leaves keys behind in HKCU\\Software\\(Wow6432Node\\)?Microsoft\\
765 // Active Setup\\Installed Components\\{guid}
766 // for every user that logged in since system-level Chrome was installed.
767 // This is a problem because Windows compares the value of the Version subkey
768 // in there with the value of the Version subkey in the matching HKLM entries
769 // before running Chrome's Active Setup so if Chrome was to be reinstalled
770 // with a lesser version (e.g. switching back to a more stable channel), the
771 // affected users would not have Chrome's Active Setup called until Chrome
772 // eventually updated passed that user's registered Version.
773 //
774 // It is however very hard to delete those values as the registry hives for
775 // other users are not loaded by default under HKEY_USERS (unless a user is
776 // logged on or has a process impersonating him).
777 //
778 // Following our best effort uninstall practices, try to delete the value in
779 // all users hives. If a given user's hive is not loaded, try to load it to
780 // proceed with the deletion (failure to do so is ignored).
781
782 static const wchar_t kProfileList[] =
783 L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\";
784
785 // Windows automatically adds Wow6432Node when creating/deleting the HKLM key,
786 // but doesn't seem to do so when manually deleting the user-level keys it
787 // created.
788 string16 alternate_active_setup_path(active_setup_path);
789 alternate_active_setup_path.insert(arraysize("Software\\") - 1,
790 L"Wow6432Node\\");
791
792 // These two privileges are required by RegLoadKey() and RegUnloadKey() below.
793 ScopedTokenPrivilege se_restore_name_privilege(SE_RESTORE_NAME);
794 ScopedTokenPrivilege se_backup_name_privilege(SE_BACKUP_NAME);
795 if (!se_restore_name_privilege.is_enabled() ||
796 !se_backup_name_privilege.is_enabled()) {
797 // This is not a critical failure as those privileges aren't required to
798 // clean hives that are already loaded, but attempts to LoadRegKey() below
799 // will fail.
800 LOG(WARNING) << "Failed to enable privileges required to load registry "
801 "hives.";
802 }
803
804 for (base::win::RegistryKeyIterator it(HKEY_LOCAL_MACHINE, kProfileList);
805 it.Valid(); ++it) {
806 const wchar_t* profile_sid = it.Name();
807
808 // First check if this user's registry hive needs to be loaded in
809 // HKEY_USERS.
810 base::win::RegKey user_reg_root_probe(
811 HKEY_USERS, profile_sid, KEY_READ);
812 bool loaded_hive = false;
813 if (!user_reg_root_probe.Valid()) {
814 VLOG(1) << "Attempting to load registry hive for " << profile_sid;
815
816 string16 reg_profile_info_path(kProfileList);
817 reg_profile_info_path.append(profile_sid);
818 base::win::RegKey reg_profile_info_key(
819 HKEY_LOCAL_MACHINE, reg_profile_info_path.c_str(), KEY_READ);
820
821 string16 profile_path;
822 LONG result = reg_profile_info_key.ReadValue(L"ProfileImagePath",
823 &profile_path);
824 if (result != ERROR_SUCCESS) {
825 LOG(ERROR) << "Error reading ProfileImagePath: " << result;
826 continue;
827 }
828 FilePath registry_hive_file(profile_path);
829 registry_hive_file = registry_hive_file.AppendASCII("NTUSER.DAT");
830
831 result = RegLoadKey(HKEY_USERS, profile_sid,
832 registry_hive_file.value().c_str());
833 if (result != ERROR_SUCCESS) {
834 LOG(ERROR) << "Error loading registry hive: " << result;
835 continue;
836 }
837
838 VLOG(1) << "Loaded registry hive for " << profile_sid;
839 loaded_hive = true;
840 }
841
842 base::win::RegKey user_reg_root(
843 HKEY_USERS, profile_sid, KEY_ALL_ACCESS);
844
845 LONG result = user_reg_root.DeleteKey(active_setup_path.c_str());
846 if (result != ERROR_SUCCESS) {
847 result = user_reg_root.DeleteKey(alternate_active_setup_path.c_str());
848 if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
849 LOG(ERROR) << "Failed to delete key at " << active_setup_path
850 << " and at " << alternate_active_setup_path
851 << ", result: " << result;
852 }
853 }
854
855 if (loaded_hive) {
856 user_reg_root.Close();
857 if (RegUnLoadKey(HKEY_USERS, profile_sid) == ERROR_SUCCESS)
858 VLOG(1) << "Unloaded registry hive for " << profile_sid;
859 else
860 LOG(ERROR) << "Error unloading registry hive for " << profile_sid;
861 }
862 }
863 }
864
740 bool ProcessChromeFrameWorkItems(const InstallationState& original_state, 865 bool ProcessChromeFrameWorkItems(const InstallationState& original_state,
741 const InstallerState& installer_state, 866 const InstallerState& installer_state,
742 const FilePath& setup_path, 867 const FilePath& setup_path,
743 const Product& product) { 868 const Product& product) {
744 if (!product.is_chrome_frame()) 869 if (!product.is_chrome_frame())
745 return false; 870 return false;
746 871
747 scoped_ptr<WorkItemList> item_list(WorkItem::CreateNoRollbackWorkItemList()); 872 scoped_ptr<WorkItemList> item_list(WorkItem::CreateNoRollbackWorkItemList());
748 AddChromeFrameWorkItems(original_state, installer_state, setup_path, 873 AddChromeFrameWorkItems(original_state, installer_state, setup_path,
749 Version(), product, item_list.get()); 874 Version(), product, item_list.get());
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 // !|remove_all| for now). 1019 // !|remove_all| for now).
895 if (installer_state.system_install() || 1020 if (installer_state.system_install() ||
896 (remove_all && 1021 (remove_all &&
897 ShellUtil::QuickIsChromeRegisteredInHKLM( 1022 ShellUtil::QuickIsChromeRegisteredInHKLM(
898 browser_dist, chrome_exe, suffix))) { 1023 browser_dist, chrome_exe, suffix))) {
899 DeleteChromeRegistrationKeys(browser_dist, HKEY_LOCAL_MACHINE, suffix, 1024 DeleteChromeRegistrationKeys(browser_dist, HKEY_LOCAL_MACHINE, suffix,
900 installer_state.target_path(), &ret); 1025 installer_state.target_path(), &ret);
901 } 1026 }
902 1027
903 ProcessDelegateExecuteWorkItems(installer_state, product); 1028 ProcessDelegateExecuteWorkItems(installer_state, product);
1029
1030 UninstallActiveSetupEntries(installer_state, product);
904 } 1031 }
905 1032
906 if (product.is_chrome_frame()) { 1033 if (product.is_chrome_frame()) {
907 ProcessChromeFrameWorkItems(original_state, installer_state, setup_path, 1034 ProcessChromeFrameWorkItems(original_state, installer_state, setup_path,
908 product); 1035 product);
909 } 1036 }
910 1037
911 if (installer_state.is_multi_install()) 1038 if (installer_state.is_multi_install())
912 ProcessGoogleUpdateItems(original_state, installer_state, product); 1039 ProcessGoogleUpdateItems(original_state, installer_state, product);
913 1040
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 1136
1010 // Try and delete the preserved local state once the post-install 1137 // Try and delete the preserved local state once the post-install
1011 // operations are complete. 1138 // operations are complete.
1012 if (!backup_state_file.empty()) 1139 if (!backup_state_file.empty())
1013 file_util::Delete(backup_state_file, false); 1140 file_util::Delete(backup_state_file, false);
1014 1141
1015 return ret; 1142 return ret;
1016 } 1143 }
1017 1144
1018 } // namespace installer 1145 } // namespace installer
OLDNEW
« no previous file with comments | « chrome/installer/setup/setup_util_unittest.cc ('k') | chrome/installer/util/util_constants.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698