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

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

Issue 10818021: Revert 147650 - Implement installation of the Chrome App Host. (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1215/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
« no previous file with comments | « chrome/installer/setup/setup_main.cc ('k') | chrome/installer/util/browser_distribution.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> 9 #include <windows.h>
10 10
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 45
46 // Build-time generated include file. 46 // Build-time generated include file.
47 #include "registered_dlls.h" // NOLINT 47 #include "registered_dlls.h" // NOLINT
48 48
49 using base::win::RegKey; 49 using base::win::RegKey;
50 using installer::InstallStatus; 50 using installer::InstallStatus;
51 using installer::MasterPreferences; 51 using installer::MasterPreferences;
52 52
53 namespace { 53 namespace {
54 54
55 // Avoid leaving behind a Temp dir. If one exists, ask SelfCleaningTempDir to
56 // clean it up for us. This may involve scheduling it for deletion after
57 // reboot. Don't report that a reboot is required in this case, however.
58 // TODO(erikwright): Shouldn't this still lead to
59 // ScheduleParentAndGrandparentForDeletion?
60 void DeleteInstallTempDir(const FilePath& target_path) {
61 FilePath temp_path(target_path.DirName().Append(installer::kInstallTempDir));
62 if (file_util::DirectoryExists(temp_path)) {
63 installer::SelfCleaningTempDir temp_dir;
64 if (!temp_dir.Initialize(target_path.DirName(),
65 installer::kInstallTempDir) ||
66 !temp_dir.Delete()) {
67 LOG(ERROR) << "Failed to delete temp dir " << temp_path.value();
68 }
69 }
70 }
71
72 // Makes appropriate changes to the Google Update "ap" value in the registry. 55 // Makes appropriate changes to the Google Update "ap" value in the registry.
73 // Specifically, removes the flags associated with this product ("-chrome" or 56 // Specifically, removes the flags associated with this product ("-chrome" or
74 // "-chromeframe[-readymode]") from the "ap" values for all other 57 // "-chromeframe[-readymode]") from the "ap" values for all other
75 // installed products and for the multi-installer package. 58 // installed products and for the multi-installer package.
76 void ProcessGoogleUpdateItems( 59 void ProcessGoogleUpdateItems(
77 const installer::InstallationState& original_state, 60 const installer::InstallationState& original_state,
78 const installer::InstallerState& installer_state, 61 const installer::InstallerState& installer_state,
79 const installer::Product& product) { 62 const installer::Product& product) {
80 DCHECK(installer_state.is_multi_install()); 63 DCHECK(installer_state.is_multi_install());
81 const bool system_level = installer_state.system_install(); 64 const bool system_level = installer_state.system_install();
82 BrowserDistribution* distribution = product.distribution(); 65 BrowserDistribution* distribution = product.distribution();
83 const HKEY reg_root = installer_state.root_key(); 66 const HKEY reg_root = installer_state.root_key();
84 const installer::ProductState* product_state = 67 const installer::ProductState* product_state =
85 original_state.GetProductState(system_level, distribution->GetType()); 68 original_state.GetProductState(system_level, distribution->GetType());
86 DCHECK(product_state != NULL); 69 DCHECK(product_state != NULL);
87 installer::ChannelInfo channel_info; 70 installer::ChannelInfo channel_info;
88 71
89 // Remove product's flags from the channel value. 72 // Remove product's flags from the channel value.
90 channel_info.set_value(product_state->channel().value()); 73 channel_info.set_value(product_state->channel().value());
91 const bool modified = product.SetChannelFlags(false, &channel_info); 74 const bool modified = product.SetChannelFlags(false, &channel_info);
92 75
93 // Apply the new channel value to all other products and to the multi package. 76 // Apply the new channel value to all other products and to the multi package.
94 if (modified) { 77 if (modified) {
78 BrowserDistribution::Type other_dist_types[] = {
79 (distribution->GetType() == BrowserDistribution::CHROME_BROWSER) ?
80 BrowserDistribution::CHROME_FRAME :
81 BrowserDistribution::CHROME_BROWSER,
82 BrowserDistribution::CHROME_BINARIES
83 };
95 scoped_ptr<WorkItemList> 84 scoped_ptr<WorkItemList>
96 update_list(WorkItem::CreateNoRollbackWorkItemList()); 85 update_list(WorkItem::CreateNoRollbackWorkItemList());
97 86
98 for (size_t i = 0; i < BrowserDistribution::NUM_TYPES; ++i) { 87 for (int i = 0; i < arraysize(other_dist_types); ++i) {
99 BrowserDistribution::Type other_dist_type = 88 BrowserDistribution::Type other_dist_type = other_dist_types[i];
100 static_cast<BrowserDistribution::Type>(i);
101 if (distribution->GetType() == other_dist_type)
102 continue;
103
104 product_state = 89 product_state =
105 original_state.GetProductState(system_level, other_dist_type); 90 original_state.GetProductState(system_level, other_dist_type);
106 // Only modify other products if they're installed and multi. 91 // Only modify other products if they're installed and multi.
107 if (product_state != NULL && 92 if (product_state != NULL &&
108 product_state->is_multi_install() && 93 product_state->is_multi_install() &&
109 !product_state->channel().Equals(channel_info)) { 94 !product_state->channel().Equals(channel_info)) {
110 BrowserDistribution* other_dist = 95 BrowserDistribution* other_dist =
111 BrowserDistribution::GetSpecificDistribution(other_dist_type); 96 BrowserDistribution::GetSpecificDistribution(other_dist_type);
112 update_list->AddSetRegValueWorkItem(reg_root, other_dist->GetStateKey(), 97 update_list->AddSetRegValueWorkItem(reg_root, other_dist->GetStateKey(),
113 google_update::kRegApField, channel_info.value(), true); 98 google_update::kRegApField, channel_info.value(), true);
(...skipping 14 matching lines...) Expand all
128 } 113 }
129 114
130 // Adds or removes the quick-enable-cf command to the binaries' version key in 115 // Adds or removes the quick-enable-cf command to the binaries' version key in
131 // the registry as needed. 116 // the registry as needed.
132 void ProcessQuickEnableWorkItems( 117 void ProcessQuickEnableWorkItems(
133 const installer::InstallerState& installer_state, 118 const installer::InstallerState& installer_state,
134 const installer::InstallationState& machine_state) { 119 const installer::InstallationState& machine_state) {
135 scoped_ptr<WorkItemList> work_item_list( 120 scoped_ptr<WorkItemList> work_item_list(
136 WorkItem::CreateNoRollbackWorkItemList()); 121 WorkItem::CreateNoRollbackWorkItemList());
137 122
138 AddQuickEnableChromeFrameWorkItems(installer_state, machine_state, NULL, NULL, 123 AddQuickEnableWorkItems(installer_state, machine_state, NULL, NULL,
139 work_item_list.get()); 124 work_item_list.get());
140
141 AddQuickEnableApplicationHostWorkItems(installer_state, machine_state, NULL,
142 NULL, work_item_list.get());
143 if (!work_item_list->Do()) 125 if (!work_item_list->Do())
144 LOG(ERROR) << "Failed to update quick-enable-cf command."; 126 LOG(ERROR) << "Failed to update quick-enable-cf command.";
145 } 127 }
146 128
147 void ProcessIELowRightsPolicyWorkItems( 129 void ProcessIELowRightsPolicyWorkItems(
148 const installer::InstallerState& installer_state) { 130 const installer::InstallerState& installer_state) {
149 scoped_ptr<WorkItemList> work_items(WorkItem::CreateNoRollbackWorkItemList()); 131 scoped_ptr<WorkItemList> work_items(WorkItem::CreateNoRollbackWorkItemList());
150 AddDeleteOldIELowRightsPolicyWorkItems(installer_state, work_items.get()); 132 AddDeleteOldIELowRightsPolicyWorkItems(installer_state, work_items.get());
151 work_items->Do(); 133 work_items->Do();
152 installer::RefreshElevationPolicy(); 134 installer::RefreshElevationPolicy();
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 // We cannot delete the file right away, but try to delete it some other 392 // We cannot delete the file right away, but try to delete it some other
411 // way. Either with the help of a different process or the system. 393 // way. Either with the help of a different process or the system.
412 if (ret && !file_util::DeleteAfterReboot(temp_file)) { 394 if (ret && !file_util::DeleteAfterReboot(temp_file)) {
413 static const uint32 kDeleteAfterMs = 10 * 1000; 395 static const uint32 kDeleteAfterMs = 10 * 1000;
414 installer::DeleteFileFromTempProcess(temp_file, kDeleteAfterMs); 396 installer::DeleteFileFromTempProcess(temp_file, kDeleteAfterMs);
415 } 397 }
416 } 398 }
417 return ret; 399 return ret;
418 } 400 }
419 401
420 DeleteResult DeleteAppHostFilesAndFolders(const InstallerState& installer_state, 402 DeleteResult DeleteFilesAndFolders(const InstallerState& installer_state,
421 const Version& installed_version) { 403 const Version& installed_version) {
422 const FilePath& target_path = installer_state.target_path(); 404 const FilePath& target_path = installer_state.target_path();
423 if (target_path.empty()) { 405 if (target_path.empty()) {
424 LOG(ERROR) << "DeleteAppHostFilesAndFolders: no installation destination " 406 LOG(ERROR) << "DeleteFilesAndFolders: no installation destination path.";
425 << "path.";
426 return DELETE_FAILED; // Nothing else we can do to uninstall, so we return. 407 return DELETE_FAILED; // Nothing else we can do to uninstall, so we return.
427 } 408 }
428 409
429 DeleteInstallTempDir(target_path);
430
431 DeleteResult result = DELETE_SUCCEEDED; 410 DeleteResult result = DELETE_SUCCEEDED;
432 411
433 FilePath app_host_exe(target_path.Append(installer::kChromeAppHostExe)); 412 // Avoid leaving behind a Temp dir. If one exists, ask SelfCleaningTempDir to
434 if (!file_util::Delete(app_host_exe, false)) { 413 // clean it up for us. This may involve scheduling it for deletion after
435 result = DELETE_FAILED; 414 // reboot. Don't report that a reboot is required in this case, however.
436 LOG(ERROR) << "Failed to delete path: " << app_host_exe.value(); 415 FilePath temp_path(target_path.DirName().Append(kInstallTempDir));
437 } else { 416 if (file_util::DirectoryExists(temp_path)) {
438 DeleteEmptyParentDir(target_path); 417 installer::SelfCleaningTempDir temp_dir;
418 if (!temp_dir.Initialize(target_path.DirName(), kInstallTempDir) ||
419 !temp_dir.Delete()) {
420 LOG(ERROR) << "Failed to delete temp dir " << temp_path.value();
421 }
439 } 422 }
440 423
441 return result; 424 VLOG(1) << "Deleting install path " << target_path.value();
442 } 425 if (!file_util::Delete(target_path, true)) {
443 426 LOG(ERROR) << "Failed to delete folder (1st try): " << target_path.value();
444 DeleteResult DeleteChromeFilesAndFolders(const InstallerState& installer_state, 427 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) {
445 const Version& installed_version) { 428 // We don't try killing Chrome processes for Chrome Frame builds since
446 const FilePath& target_path = installer_state.target_path(); 429 // that is unlikely to help. Instead, schedule files for deletion and
447 if (target_path.empty()) { 430 // return a value that will trigger a reboot prompt.
448 LOG(ERROR) << "DeleteChromeFilesAndFolders: no installation destination " 431 ScheduleDirectoryForDeletion(target_path.value().c_str());
449 << "path."; 432 result = DELETE_REQUIRES_REBOOT;
450 return DELETE_FAILED; // Nothing else we can do to uninstall, so we return. 433 } else {
451 } 434 // Try closing any running chrome processes and deleting files once again.
452 435 CloseAllChromeProcesses();
453 DeleteInstallTempDir(target_path); 436 if (!file_util::Delete(target_path, true)) {
454 437 LOG(ERROR) << "Failed to delete folder (2nd try): "
455 DeleteResult result = DELETE_SUCCEEDED; 438 << target_path.value();
456 439 result = DELETE_FAILED;
457 using file_util::FileEnumerator;
458 FileEnumerator file_enumerator(
459 target_path,
460 false,
461 static_cast<FileEnumerator::FileType>(FileEnumerator::FILES |
462 FileEnumerator::DIRECTORIES));
463 while (true) {
464 FilePath to_delete(file_enumerator.Next());
465 if (to_delete.empty())
466 break;
467 if (to_delete.BaseName().value() == installer::kChromeAppHostExe)
468 continue;
469
470 VLOG(1) << "Deleting install path " << target_path.value();
471 if (!file_util::Delete(to_delete, true)) {
472 LOG(ERROR) << "Failed to delete path (1st try): " << to_delete.value();
473 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) {
474 // We don't try killing Chrome processes for Chrome Frame builds since
475 // that is unlikely to help. Instead, schedule files for deletion and
476 // return a value that will trigger a reboot prompt.
477 FileEnumerator::FindInfo find_info;
478 file_enumerator.GetFindInfo(&find_info);
479 if (FileEnumerator::IsDirectory(find_info))
480 ScheduleDirectoryForDeletion(to_delete.value().c_str());
481 else
482 ScheduleFileSystemEntityForDeletion(to_delete.value().c_str());
483 result = DELETE_REQUIRES_REBOOT;
484 } else {
485 // Try closing any running Chrome processes and deleting files once
486 // again.
487 CloseAllChromeProcesses();
488 if (!file_util::Delete(to_delete, true)) {
489 LOG(ERROR) << "Failed to delete path (2nd try): "
490 << to_delete.value();
491 result = DELETE_FAILED;
492 break;
493 }
494 } 440 }
495 } 441 }
496 } 442 }
497 443
498 if (result == DELETE_REQUIRES_REBOOT) { 444 if (result == DELETE_REQUIRES_REBOOT) {
499 // If we need a reboot to continue, schedule the parent directories for 445 // If we need a reboot to continue, schedule the parent directories for
500 // deletion unconditionally. If they are not empty, the session manager 446 // deletion unconditionally. If they are not empty, the session manager
501 // will not delete them on reboot. 447 // will not delete them on reboot.
502 ScheduleParentAndGrandparentForDeletion(target_path); 448 ScheduleParentAndGrandparentForDeletion(target_path);
503 } else { 449 } else {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 493
548 bool ShouldDeleteProfile(const InstallerState& installer_state, 494 bool ShouldDeleteProfile(const InstallerState& installer_state,
549 const CommandLine& cmd_line, InstallStatus status, 495 const CommandLine& cmd_line, InstallStatus status,
550 const Product& product) { 496 const Product& product) {
551 bool should_delete = false; 497 bool should_delete = false;
552 498
553 // Chrome Frame uninstallations always want to delete the profile (we have no 499 // Chrome Frame uninstallations always want to delete the profile (we have no
554 // UI to prompt otherwise and the profile stores no useful data anyway) 500 // UI to prompt otherwise and the profile stores no useful data anyway)
555 // unless they are managed by MSI. MSI uninstalls will explicitly include 501 // unless they are managed by MSI. MSI uninstalls will explicitly include
556 // the --delete-profile flag to distinguish them from MSI upgrades. 502 // the --delete-profile flag to distinguish them from MSI upgrades.
557 if (product.is_chrome_frame() && !installer_state.is_msi()) { 503 if (!product.is_chrome() && !installer_state.is_msi()) {
558 should_delete = true; 504 should_delete = true;
559 } else { 505 } else {
560 should_delete = 506 should_delete =
561 status == installer::UNINSTALL_DELETE_PROFILE || 507 status == installer::UNINSTALL_DELETE_PROFILE ||
562 cmd_line.HasSwitch(installer::switches::kDeleteProfile); 508 cmd_line.HasSwitch(installer::switches::kDeleteProfile);
563 } 509 }
564 510
565 return should_delete; 511 return should_delete;
566 } 512 }
567 513
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 } 882 }
937 883
938 // Chrome is not in use so lets uninstall Chrome by deleting various files 884 // Chrome is not in use so lets uninstall Chrome by deleting various files
939 // and registry entries. Here we will just make best effort and keep going 885 // and registry entries. Here we will just make best effort and keep going
940 // in case of errors. 886 // in case of errors.
941 if (is_chrome) { 887 if (is_chrome) {
942 ClearRlzProductState(); 888 ClearRlzProductState();
943 889
944 auto_launch_util::DisableAllAutoStartFeatures( 890 auto_launch_util::DisableAllAutoStartFeatures(
945 ASCIIToUTF16(chrome::kInitialProfile)); 891 ASCIIToUTF16(chrome::kInitialProfile));
892 }
946 893
947 // First delete shortcuts from Start->Programs, Desktop & Quick Launch. 894 // First delete shortcuts from Start->Programs, Desktop & Quick Launch.
948 DeleteChromeShortcuts(installer_state, product); 895 DeleteChromeShortcuts(installer_state, product);
949 }
950 896
951 // Delete the registry keys (Uninstall key and Version key). 897 // Delete the registry keys (Uninstall key and Version key).
952 HKEY reg_root = installer_state.root_key(); 898 HKEY reg_root = installer_state.root_key();
953 899
954 // Note that we must retrieve the distribution-specific data before deleting 900 // Note that we must retrieve the distribution-specific data before deleting
955 // product.GetVersionKey(). 901 // product.GetVersionKey().
956 string16 distribution_data(browser_dist->GetDistributionData(reg_root)); 902 string16 distribution_data(browser_dist->GetDistributionData(reg_root));
957 903
958 // Remove Control Panel uninstall link. 904 // Remove Control Panel uninstall link and Omaha product key.
959 if (product.ShouldCreateUninstallEntry()) { 905 InstallUtil::DeleteRegistryKey(reg_root, browser_dist->GetUninstallRegPath());
960 InstallUtil::DeleteRegistryKey(reg_root,
961 browser_dist->GetUninstallRegPath());
962 }
963
964 // Remove Omaha product key.
965 InstallUtil::DeleteRegistryKey(reg_root, browser_dist->GetVersionKey()); 906 InstallUtil::DeleteRegistryKey(reg_root, browser_dist->GetVersionKey());
966 907
967 // Also try to delete the MSI value in the ClientState key (it might not be 908 // Also try to delete the MSI value in the ClientState key (it might not be
968 // there). This is due to a Google Update behaviour where an uninstall and a 909 // there). This is due to a Google Update behaviour where an uninstall and a
969 // rapid reinstall might result in stale values from the old ClientState key 910 // rapid reinstall might result in stale values from the old ClientState key
970 // being picked up on reinstall. 911 // being picked up on reinstall.
971 product.SetMsiMarker(installer_state.system_install(), false); 912 product.SetMsiMarker(installer_state.system_install(), false);
972 913
914 // Remove all Chrome registration keys.
915 // Registration data is put in HKCU for both system level and user level
916 // installs.
973 InstallStatus ret = installer::UNKNOWN_STATUS; 917 InstallStatus ret = installer::UNKNOWN_STATUS;
918 DeleteChromeRegistrationKeys(browser_dist, HKEY_CURRENT_USER, suffix,
919 installer_state.target_path(), &ret);
974 920
975 if (is_chrome) { 921 // If the user's Chrome is registered with a suffix: it is possible that old
976 // Remove all Chrome registration keys. 922 // unsuffixed registrations were left in HKCU (e.g. if this install was
977 // Registration data is put in HKCU for both system level and user level 923 // previously installed with no suffix in HKCU (old suffix rules if the user
978 // installs. 924 // is not an admin (or declined UAC at first run)) and later had to be
979 DeleteChromeRegistrationKeys(browser_dist, HKEY_CURRENT_USER, suffix, 925 // suffixed when fully registered in HKLM (e.g. when later making Chrome
926 // default through the UI)).
927 // Remove remaining HKCU entries with no suffix if any.
928 if (!suffix.empty()) {
929 DeleteChromeRegistrationKeys(browser_dist, HKEY_CURRENT_USER, string16(),
980 installer_state.target_path(), &ret); 930 installer_state.target_path(), &ret);
981 931
982 // If the user's Chrome is registered with a suffix: it is possible that old 932 // For similar reasons it is possible in very few installs (from 21.0.1180.0
983 // unsuffixed registrations were left in HKCU (e.g. if this install was 933 // and fixed shortly after) to be installed with the new-style suffix, but
984 // previously installed with no suffix in HKCU (old suffix rules if the user 934 // have some old-style suffix registrations left behind.
985 // is not an admin (or declined UAC at first run)) and later had to be 935 string16 old_style_suffix;
986 // suffixed when fully registered in HKLM (e.g. when later making Chrome 936 if (ShellUtil::GetOldUserSpecificRegistrySuffix(&old_style_suffix) &&
987 // default through the UI)). 937 suffix != old_style_suffix) {
988 // Remove remaining HKCU entries with no suffix if any. 938 DeleteChromeRegistrationKeys(browser_dist, HKEY_CURRENT_USER,
989 if (!suffix.empty()) { 939 old_style_suffix,
990 DeleteChromeRegistrationKeys(browser_dist, HKEY_CURRENT_USER, string16(),
991 installer_state.target_path(), &ret);
992
993 // For similar reasons it is possible in very few installs (from
994 // 21.0.1180.0 and fixed shortly after) to be installed with the new-style
995 // suffix, but have some old-style suffix registrations left behind.
996 string16 old_style_suffix;
997 if (ShellUtil::GetOldUserSpecificRegistrySuffix(&old_style_suffix) &&
998 suffix != old_style_suffix) {
999 DeleteChromeRegistrationKeys(browser_dist, HKEY_CURRENT_USER,
1000 old_style_suffix,
1001 installer_state.target_path(), &ret);
1002 }
1003 }
1004
1005 // Chrome is registered in HKLM for all system-level installs and for
1006 // user-level installs for which Chrome has been made the default browser.
1007 // Always remove the HKLM registration for system-level installs. For
1008 // user-level installs, only remove it if both: 1) this uninstall isn't a
1009 // self destruct following the installation of a system-level Chrome
1010 // (because the system-level Chrome owns the HKLM registration now), and 2)
1011 // this user has made Chrome their default browser (i.e. has shell
1012 // integration entries registered with |suffix| (note: |suffix| will be the
1013 // empty string if required as it is obtained by
1014 // GetCurrentInstallationSuffix() above)).
1015 // TODO(gab): This can still leave parts of a suffixed install behind. To be
1016 // able to remove them we would need to be able to remove only suffixed
1017 // entries (as it is now some of the shell integration entries are
1018 // unsuffixed; thus removing suffixed installs is prohibited in HKLM if
1019 // !|remove_all| for now).
1020 if (installer_state.system_install() ||
1021 (remove_all &&
1022 ShellUtil::QuickIsChromeRegisteredInHKLM(
1023 browser_dist, chrome_exe, suffix))) {
1024 DeleteChromeRegistrationKeys(browser_dist, HKEY_LOCAL_MACHINE, suffix,
1025 installer_state.target_path(), &ret); 940 installer_state.target_path(), &ret);
1026 } 941 }
942 }
1027 943
1028 ProcessDelegateExecuteWorkItems(installer_state, product); 944 // Chrome is registered in HKLM for all system-level installs and for
945 // user-level installs for which Chrome has been made the default browser.
946 // Always remove the HKLM registration for system-level installs. For
947 // user-level installs, only remove it if both: 1) this uninstall isn't a self
948 // destruct following the installation of a system-level Chrome (because the
949 // system-level Chrome owns the HKLM registration now), and 2) this user has
950 // made Chrome their default browser (i.e. has shell integration entries
951 // registered with |suffix| (note: |suffix| will be the empty string if
952 // required as it is obtained by GetCurrentInstallationSuffix() above)).
953 // TODO(gab): This can still leave parts of a suffixed install behind. To be
954 // able to remove them we would need to be able to remove only suffixed
955 // entries (as it is now some of the shell integration entries are unsuffixed;
956 // thus removing suffixed installs is prohibited in HKLM if !|remove_all| for
957 // now).
958 if (installer_state.system_install() ||
959 (remove_all &&
960 ShellUtil::QuickIsChromeRegisteredInHKLM(
961 browser_dist, chrome_exe, suffix))) {
962 DeleteChromeRegistrationKeys(browser_dist, HKEY_LOCAL_MACHINE, suffix,
963 installer_state.target_path(), &ret);
1029 UninstallActiveSetupEntries(installer_state, product); 964 UninstallActiveSetupEntries(installer_state, product);
1030 } 965 }
1031 966
1032 if (product.is_chrome_frame()) { 967 ProcessDelegateExecuteWorkItems(installer_state, product);
968
969 if (!is_chrome) {
1033 ProcessChromeFrameWorkItems(original_state, installer_state, setup_path, 970 ProcessChromeFrameWorkItems(original_state, installer_state, setup_path,
1034 product); 971 product);
1035 } 972 }
1036 973
1037 if (installer_state.is_multi_install()) 974 if (installer_state.is_multi_install())
1038 ProcessGoogleUpdateItems(original_state, installer_state, product); 975 ProcessGoogleUpdateItems(original_state, installer_state, product);
1039 976
1040 ProcessQuickEnableWorkItems(installer_state, original_state); 977 ProcessQuickEnableWorkItems(installer_state, original_state);
1041 978
1042 // Get the state of the installed product (if any) 979 // Get the state of the installed product (if any)
(...skipping 27 matching lines...) Expand all
1070 1007
1071 AddRegisterComDllWorkItems(dll_folder, 1008 AddRegisterComDllWorkItems(dll_folder,
1072 com_dll_list, 1009 com_dll_list,
1073 installer_state.system_install(), 1010 installer_state.system_install(),
1074 false, // Unregister 1011 false, // Unregister
1075 true, // May fail 1012 true, // May fail
1076 unreg_work_item_list.get()); 1013 unreg_work_item_list.get());
1077 unreg_work_item_list->Do(); 1014 unreg_work_item_list->Do();
1078 } 1015 }
1079 1016
1080 if (product.is_chrome_frame()) 1017 if (!is_chrome)
1081 ProcessIELowRightsPolicyWorkItems(installer_state); 1018 ProcessIELowRightsPolicyWorkItems(installer_state);
1082 } 1019 }
1083 1020
1084 // Close any Chrome Frame helper processes that may be running. 1021 // Close any Chrome Frame helper processes that may be running.
1085 if (product.is_chrome_frame()) { 1022 if (product.is_chrome_frame()) {
1086 VLOG(1) << "Closing the Chrome Frame helper process"; 1023 VLOG(1) << "Closing the Chrome Frame helper process";
1087 CloseChromeFrameHelperProcess(); 1024 CloseChromeFrameHelperProcess();
1088 } 1025 }
1089 1026
1090 if (product_state == NULL) 1027 if (product_state == NULL)
1091 return installer::UNINSTALL_SUCCESSFUL; 1028 return installer::UNINSTALL_SUCCESSFUL;
1092 1029
1093 // Finally delete all the files from Chrome folder after moving setup.exe 1030 // Finally delete all the files from Chrome folder after moving setup.exe
1094 // and the user's Local State to a temp location. 1031 // and the user's Local State to a temp location.
1095 bool delete_profile = ShouldDeleteProfile(installer_state, cmd_line, status, 1032 bool delete_profile = ShouldDeleteProfile(installer_state, cmd_line, status,
1096 product); 1033 product);
1097 ret = installer::UNINSTALL_SUCCESSFUL; 1034 ret = installer::UNINSTALL_SUCCESSFUL;
1098 1035
1099 // When deleting files, we must make sure that we're either a "single" 1036 // When deleting files, we must make sure that we're either a "single"
1100 // (aka non-multi) installation or we are the Chrome Binaries. 1037 // (aka non-multi) installation or, in the case of multi, that no other
1038 // "multi" products share the binaries we are about to delete.
1101 1039
1102 FilePath backup_state_file( 1040 bool can_delete_files = true;
1103 BackupLocalStateFile(GetLocalStateFolder(product))); 1041 if (installer_state.is_multi_install()) {
1042 ProductState prod_state;
1043 for (size_t i = 0; i < BrowserDistribution::kNumProductTypes; ++i) {
1044 if (prod_state.Initialize(installer_state.system_install(),
1045 BrowserDistribution::kProductTypes[i]) &&
1046 prod_state.is_multi_install()) {
1047 can_delete_files = false;
1048 break;
1049 }
1050 }
1051 LOG(INFO) << (can_delete_files ? "Shared binaries will be deleted." :
1052 "Shared binaries still in use.");
1053 if (can_delete_files) {
1054 BrowserDistribution* multi_dist =
1055 installer_state.multi_package_binaries_distribution();
1056 InstallUtil::DeleteRegistryKey(reg_root, multi_dist->GetVersionKey());
1057 }
1058 }
1059
1060 FilePath backup_state_file(BackupLocalStateFile(
1061 GetLocalStateFolder(product)));
1104 1062
1105 DeleteResult delete_result = DELETE_SUCCEEDED; 1063 DeleteResult delete_result = DELETE_SUCCEEDED;
1106 1064 if (can_delete_files) {
1107 if (product.is_chrome_app_host()) {
1108 DeleteAppHostFilesAndFolders(installer_state, product_state->version());
1109 } else if (!installer_state.is_multi_install() ||
1110 product.is_chrome_binaries()) {
1111
1112 // In order to be able to remove the folder in which we're running, we 1065 // In order to be able to remove the folder in which we're running, we
1113 // need to move setup.exe out of the install folder. 1066 // need to move setup.exe out of the install folder.
1114 // TODO(tommi): What if the temp folder is on a different volume? 1067 // TODO(tommi): What if the temp folder is on a different volume?
1115 MoveSetupOutOfInstallFolder(installer_state, setup_path, 1068 MoveSetupOutOfInstallFolder(installer_state, setup_path,
1116 product_state->version()); 1069 product_state->version());
1117 delete_result = DeleteChromeFilesAndFolders(installer_state, 1070 delete_result = DeleteFilesAndFolders(installer_state,
1118 product_state->version()); 1071 product_state->version());
1119 } 1072 }
1120 1073
1121 if (delete_profile) 1074 if (delete_profile)
1122 DeleteLocalState(product); 1075 DeleteLocalState(product);
1123 1076
1124 if (delete_result == DELETE_FAILED) { 1077 if (delete_result == DELETE_FAILED) {
1125 ret = installer::UNINSTALL_FAILED; 1078 ret = installer::UNINSTALL_FAILED;
1126 } else if (delete_result == DELETE_REQUIRES_REBOOT) { 1079 } else if (delete_result == DELETE_REQUIRES_REBOOT) {
1127 ret = installer::UNINSTALL_REQUIRES_REBOOT; 1080 ret = installer::UNINSTALL_REQUIRES_REBOOT;
1128 } 1081 }
1129 1082
1130 if (!force_uninstall) { 1083 if (!force_uninstall) {
1131 VLOG(1) << "Uninstallation complete. Launching post-uninstall operations."; 1084 VLOG(1) << "Uninstallation complete. Launching Uninstall survey.";
1132 browser_dist->DoPostUninstallOperations(product_state->version(), 1085 browser_dist->DoPostUninstallOperations(product_state->version(),
1133 backup_state_file, distribution_data); 1086 backup_state_file, distribution_data);
1134 } 1087 }
1135 1088
1136 // Try and delete the preserved local state once the post-install 1089 // Try and delete the preserved local state once the post-install
1137 // operations are complete. 1090 // operations are complete.
1138 if (!backup_state_file.empty()) 1091 if (!backup_state_file.empty())
1139 file_util::Delete(backup_state_file, false); 1092 file_util::Delete(backup_state_file, false);
1140 1093
1141 return ret; 1094 return ret;
1142 } 1095 }
1143 1096
1144 } // namespace installer 1097 } // namespace installer
OLDNEW
« no previous file with comments | « chrome/installer/setup/setup_main.cc ('k') | chrome/installer/util/browser_distribution.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698