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

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: 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
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 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 // corresponding BrowserDistribution implementations do not publish 679 // corresponding BrowserDistribution implementations do not publish
677 // DelegateExecute data via an implementation of GetDelegateExecuteHandlerData. 680 // DelegateExecute data via an implementation of GetDelegateExecuteHandlerData.
678 bool ProcessDelegateExecuteWorkItems(const InstallerState& installer_state, 681 bool ProcessDelegateExecuteWorkItems(const InstallerState& installer_state,
679 const Product& product) { 682 const Product& product) {
680 scoped_ptr<WorkItemList> item_list(WorkItem::CreateNoRollbackWorkItemList()); 683 scoped_ptr<WorkItemList> item_list(WorkItem::CreateNoRollbackWorkItemList());
681 AddDelegateExecuteWorkItems(installer_state, FilePath(), Version(), product, 684 AddDelegateExecuteWorkItems(installer_state, FilePath(), Version(), product,
682 item_list.get()); 685 item_list.get());
683 return item_list->Do(); 686 return item_list->Do();
684 } 687 }
685 688
689 // Removes Active Setup entries from the registry. This cannot be done through
690 // a work items list as usual because of different paths based on conditionals,
691 // but otherwise respects the no rollback/best effort uninstall mentality.
692 // This will only apply for system-level installs of Chrome/Chromium and will be
693 // a no-op for all other types of installs.
694 void UninstallActiveSetupEntries(const InstallerState& installer_state,
695 const Product& product) {
696 VLOG(1) << "Uninstalling registry entries for ActiveSetup.";
697 BrowserDistribution* distribution = product.distribution();
698
699 if (!product.is_chrome() || !installer_state.system_install()) {
700 const char* install_level =
701 installer_state.system_install() ? "system" : "user";
702 VLOG(1) << "No Active Setup processing to do for " << install_level
703 << "-level " << distribution->GetAppShortCutName();
704 return;
705 }
706
707 const string16 active_setup_path(GetActiveSetupPath(distribution));
708 InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, active_setup_path);
709
710 // Windows leaves keys behind in HKCU\\Software\\(Wow6432Node\\)?Microsoft\\
711 // Active Setup\\Installed Components\\{guid}
712 // for every user that logged in since system-level Chrome was installed.
713 // This is a problem because Windows compares the value of the Version subkey
714 // in there with the value of the Version subkey in the matching HKLM entries
715 // before running Chrome's Active Setup so if Chrome was to be reinstalled
716 // with a lesser version (e.g. switching back to a more stable channel), the
717 // affected users would not have Chrome's Active Setup called until Chrome
718 // eventually updated passed that user's registered Version.
719 //
720 // It is however very hard to delete those values as the registry hives for
721 // other users are not loaded by default under HKEY_USERS (unless a user is
722 // logged on or has a process impersonating him).
723 //
724 // Following our best effort uninstall practices, try to delete the value in
725 // all users hives. If a given user's hive is not loaded, try to load it to
726 // proceed with the deletion (failure to do so is ignored).
727
728 static const wchar_t* kProfileList =
tommi (sloooow) - chröme 2012/07/20 09:59:25 []
gab 2012/07/20 14:45:47 Done.
729 L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\";
730
731 // Windows automatically adds Wow6432Node when creating/deleting the HKLM key,
732 // but doesn't seem to do so when manually deleting the user-level keys it
733 // created.
734 string16 alternate_active_setup_path(active_setup_path);
735 alternate_active_setup_path.insert(arraysize("Software\\") - 1,
736 L"Wow6432Node\\");
737
738 // These two privileges are required by RegLoadKey() and RegUnloadKey() below.
739 ScopedTokenPrivilege se_restore_name_privilege(SE_RESTORE_NAME);
tommi (sloooow) - chröme 2012/07/20 09:59:25 for these two privileges, should we LOG_IF(ERROR,
gab 2012/07/20 14:45:47 Good catch, I intended to do this and forgot :S!
740 ScopedTokenPrivilege se_backup_name_privilege(SE_BACKUP_NAME);
741 for (base::win::RegistryKeyIterator it(HKEY_LOCAL_MACHINE, kProfileList);
742 it.Valid(); ++it) {
743 const wchar_t* profile_sid = it.Name();
744
745 // First check if this user's registry hive needs to be loaded in
746 // HKEY_USERS.
747 base::win::RegKey user_reg_root_probe(
748 HKEY_USERS, profile_sid, KEY_READ);
749 bool loaded_hive = false;
750 if (!user_reg_root_probe.Valid()) {
751 VLOG(1) << "Attempting to load registry hive for " << profile_sid;
752
753 string16 reg_profile_info_path(kProfileList);
754 reg_profile_info_path.append(profile_sid);
755 base::win::RegKey reg_profile_info_key(
756 HKEY_LOCAL_MACHINE, reg_profile_info_path.c_str(), KEY_READ);
757
758 string16 profile_path;
759 LONG result = reg_profile_info_key.ReadValue(L"ProfileImagePath",
760 &profile_path);
761 if (result != ERROR_SUCCESS) {
762 LOG(ERROR) << "Error reading ProfileImagePath: " << result;
763 continue;
764 }
765 FilePath registry_hive_file(profile_path);
766 registry_hive_file = registry_hive_file.AppendASCII("NTUSER.DAT");
767
768 result = RegLoadKey(HKEY_USERS, profile_sid,
769 registry_hive_file.value().c_str());
770 if (result != ERROR_SUCCESS) {
771 LOG(ERROR) << "Error loading registry hive: " << result;
772 continue;
773 }
774
775 VLOG(1) << "Loaded registry hive for " << profile_sid;
776 loaded_hive = true;
777 }
778
779 base::win::RegKey user_reg_root(
780 HKEY_USERS, profile_sid, KEY_ALL_ACCESS);
781
782 LONG result = user_reg_root.DeleteKey(active_setup_path.c_str());
783 if (result != ERROR_SUCCESS) {
784 result = user_reg_root.DeleteKey(alternate_active_setup_path.c_str());
785 if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
786 LOG(ERROR) << "Failed to delete key at " << active_setup_path
787 << " and at " << alternate_active_setup_path
788 << ", result: " << result;
789 }
790 }
791
792 if (loaded_hive) {
793 user_reg_root.Close();
794 if (RegUnLoadKey(HKEY_USERS, profile_sid) == ERROR_SUCCESS)
795 VLOG(1) << "Unloaded registry hive for " << profile_sid;
796 else
797 LOG(ERROR) << "Error unloading registry hive for " << profile_sid;
798 }
799 }
800 }
801
686 bool ProcessChromeFrameWorkItems(const InstallationState& original_state, 802 bool ProcessChromeFrameWorkItems(const InstallationState& original_state,
687 const InstallerState& installer_state, 803 const InstallerState& installer_state,
688 const FilePath& setup_path, 804 const FilePath& setup_path,
689 const Product& product) { 805 const Product& product) {
690 if (!product.is_chrome_frame()) 806 if (!product.is_chrome_frame())
691 return false; 807 return false;
692 808
693 scoped_ptr<WorkItemList> item_list(WorkItem::CreateNoRollbackWorkItemList()); 809 scoped_ptr<WorkItemList> item_list(WorkItem::CreateNoRollbackWorkItemList());
694 AddChromeFrameWorkItems(original_state, installer_state, setup_path, 810 AddChromeFrameWorkItems(original_state, installer_state, setup_path,
695 Version(), product, item_list.get()); 811 Version(), product, item_list.get());
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 if (installer_state.system_install() || 949 if (installer_state.system_install() ||
834 (remove_all && 950 (remove_all &&
835 ShellUtil::QuickIsChromeRegisteredInHKLM( 951 ShellUtil::QuickIsChromeRegisteredInHKLM(
836 browser_dist, chrome_exe, suffix))) { 952 browser_dist, chrome_exe, suffix))) {
837 DeleteChromeRegistrationKeys(browser_dist, HKEY_LOCAL_MACHINE, suffix, 953 DeleteChromeRegistrationKeys(browser_dist, HKEY_LOCAL_MACHINE, suffix,
838 installer_state.target_path(), &ret); 954 installer_state.target_path(), &ret);
839 } 955 }
840 956
841 ProcessDelegateExecuteWorkItems(installer_state, product); 957 ProcessDelegateExecuteWorkItems(installer_state, product);
842 958
959 UninstallActiveSetupEntries(installer_state, product);
960
843 if (!is_chrome) { 961 if (!is_chrome) {
844 ProcessChromeFrameWorkItems(original_state, installer_state, setup_path, 962 ProcessChromeFrameWorkItems(original_state, installer_state, setup_path,
845 product); 963 product);
846 } 964 }
847 965
848 if (installer_state.is_multi_install()) 966 if (installer_state.is_multi_install())
849 ProcessGoogleUpdateItems(original_state, installer_state, product); 967 ProcessGoogleUpdateItems(original_state, installer_state, product);
850 968
851 ProcessQuickEnableWorkItems(installer_state, original_state); 969 ProcessQuickEnableWorkItems(installer_state, original_state);
852 970
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 1080
963 // Try and delete the preserved local state once the post-install 1081 // Try and delete the preserved local state once the post-install
964 // operations are complete. 1082 // operations are complete.
965 if (!backup_state_file.empty()) 1083 if (!backup_state_file.empty())
966 file_util::Delete(backup_state_file, false); 1084 file_util::Delete(backup_state_file, false);
967 1085
968 return ret; 1086 return ret;
969 } 1087 }
970 1088
971 } // namespace installer 1089 } // namespace installer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698