| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 << " is somehow already set to the desired new value of " | 95 << " is somehow already set to the desired new value of " |
| 96 << channel_info.value(); | 96 << channel_info.value(); |
| 97 } | 97 } |
| 98 } | 98 } |
| 99 | 99 |
| 100 bool success = update_list->Do(); | 100 bool success = update_list->Do(); |
| 101 LOG_IF(ERROR, !success) << "Failed updating channel values."; | 101 LOG_IF(ERROR, !success) << "Failed updating channel values."; |
| 102 } | 102 } |
| 103 } | 103 } |
| 104 | 104 |
| 105 // Adds or removes the quick-enable-cf command to the binaries' version key in |
| 106 // the registry as needed. |
| 107 void ProcessQuickEnableWorkItems( |
| 108 const installer::InstallerState& installer_state, |
| 109 const installer::InstallationState& machine_state) { |
| 110 scoped_ptr<WorkItemList> work_item_list( |
| 111 WorkItem::CreateNoRollbackWorkItemList()); |
| 112 |
| 113 AddQuickEnableWorkItems(installer_state, machine_state, NULL, NULL, |
| 114 work_item_list.get()); |
| 115 if (!work_item_list->Do()) |
| 116 LOG(ERROR) << "Failed to update quick-enable-cf command."; |
| 117 } |
| 118 |
| 105 } // namespace | 119 } // namespace |
| 106 | 120 |
| 107 namespace installer { | 121 namespace installer { |
| 108 | 122 |
| 109 // This functions checks for any Chrome instances that are | 123 // This functions checks for any Chrome instances that are |
| 110 // running and first asks them to close politely by sending a Windows message. | 124 // running and first asks them to close politely by sending a Windows message. |
| 111 // If there is an error while sending message or if there are still Chrome | 125 // If there is an error while sending message or if there are still Chrome |
| 112 // procesess active after the message has been sent, this function will try | 126 // procesess active after the message has been sent, this function will try |
| 113 // to kill them. | 127 // to kill them. |
| 114 void CloseAllChromeProcesses() { | 128 void CloseAllChromeProcesses() { |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 } else { | 365 } else { |
| 352 VLOG(1) << "Attempting to move setup to: " << temp_file.value(); | 366 VLOG(1) << "Attempting to move setup to: " << temp_file.value(); |
| 353 ret = file_util::Move(setup_exe, temp_file); | 367 ret = file_util::Move(setup_exe, temp_file); |
| 354 LOG_IF(ERROR, !ret) << "Failed to move setup to " << temp_file.value(); | 368 LOG_IF(ERROR, !ret) << "Failed to move setup to " << temp_file.value(); |
| 355 } | 369 } |
| 356 return ret; | 370 return ret; |
| 357 } | 371 } |
| 358 | 372 |
| 359 DeleteResult DeleteFilesAndFolders(const InstallerState& installer_state, | 373 DeleteResult DeleteFilesAndFolders(const InstallerState& installer_state, |
| 360 const Version& installed_version) { | 374 const Version& installed_version) { |
| 361 VLOG(1) << "DeleteFilesAndFolders: " << installer_state.target_path().value(); | 375 const FilePath& target_path = installer_state.target_path(); |
| 362 if (installer_state.target_path().empty()) { | 376 if (target_path.empty()) { |
| 363 LOG(ERROR) << "Could not get installation destination path."; | 377 LOG(ERROR) << "DeleteFilesAndFolders: no installation destination path."; |
| 364 return DELETE_FAILED; // Nothing else we can do to uninstall, so we return. | 378 return DELETE_FAILED; // Nothing else we can do to uninstall, so we return. |
| 365 } | 379 } |
| 366 | 380 |
| 367 DeleteResult result = DELETE_SUCCEEDED; | 381 DeleteResult result = DELETE_SUCCEEDED; |
| 368 | 382 |
| 369 // Avoid leaving behind a Temp dir. If one exists, ask SelfCleaningTempDir to | 383 // Avoid leaving behind a Temp dir. If one exists, ask SelfCleaningTempDir to |
| 370 // clean it up for us. This may involve scheduling it for deletion after | 384 // clean it up for us. This may involve scheduling it for deletion after |
| 371 // reboot. Don't report that a reboot is required in this case, however. | 385 // reboot. Don't report that a reboot is required in this case, however. |
| 372 FilePath temp_path( | 386 FilePath temp_path(target_path.DirName().Append(kInstallTempDir)); |
| 373 installer_state.target_path().DirName().Append(kInstallTempDir)); | |
| 374 if (file_util::DirectoryExists(temp_path)) { | 387 if (file_util::DirectoryExists(temp_path)) { |
| 375 installer::SelfCleaningTempDir temp_dir; | 388 installer::SelfCleaningTempDir temp_dir; |
| 376 if (!temp_dir.Initialize(installer_state.target_path().DirName(), | 389 if (!temp_dir.Initialize(target_path.DirName(), kInstallTempDir) || |
| 377 kInstallTempDir) || !temp_dir.Delete()) | 390 !temp_dir.Delete()) { |
| 378 LOG(ERROR) << "Failed to delete temp dir " << temp_path.value(); | 391 LOG(ERROR) << "Failed to delete temp dir " << temp_path.value(); |
| 392 } |
| 379 } | 393 } |
| 380 | 394 |
| 381 VLOG(1) << "Deleting install path " << installer_state.target_path().value(); | 395 VLOG(1) << "Deleting install path " << target_path.value(); |
| 382 if (!file_util::Delete(installer_state.target_path(), true)) { | 396 if (!file_util::Delete(target_path, true)) { |
| 383 LOG(ERROR) << "Failed to delete folder (1st try): " | 397 LOG(ERROR) << "Failed to delete folder (1st try): " << target_path.value(); |
| 384 << installer_state.target_path().value(); | |
| 385 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) { | 398 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) { |
| 386 // We don't try killing Chrome processes for Chrome Frame builds since | 399 // We don't try killing Chrome processes for Chrome Frame builds since |
| 387 // that is unlikely to help. Instead, schedule files for deletion and | 400 // that is unlikely to help. Instead, schedule files for deletion and |
| 388 // return a value that will trigger a reboot prompt. | 401 // return a value that will trigger a reboot prompt. |
| 389 ScheduleDirectoryForDeletion( | 402 ScheduleDirectoryForDeletion(target_path.value().c_str()); |
| 390 installer_state.target_path().value().c_str()); | |
| 391 result = DELETE_REQUIRES_REBOOT; | 403 result = DELETE_REQUIRES_REBOOT; |
| 392 } else { | 404 } else { |
| 393 // Try closing any running chrome processes and deleting files once again. | 405 // Try closing any running chrome processes and deleting files once again. |
| 394 CloseAllChromeProcesses(); | 406 CloseAllChromeProcesses(); |
| 395 if (!file_util::Delete(installer_state.target_path(), true)) { | 407 if (!file_util::Delete(target_path, true)) { |
| 396 LOG(ERROR) << "Failed to delete folder (2nd try): " | 408 LOG(ERROR) << "Failed to delete folder (2nd try): " |
| 397 << installer_state.target_path().value(); | 409 << target_path.value(); |
| 398 result = DELETE_FAILED; | 410 result = DELETE_FAILED; |
| 399 } | 411 } |
| 400 } | 412 } |
| 401 } | 413 } |
| 402 | 414 |
| 403 if (result == DELETE_REQUIRES_REBOOT) { | 415 if (result == DELETE_REQUIRES_REBOOT) { |
| 404 // If we need a reboot to continue, schedule the parent directories for | 416 // If we need a reboot to continue, schedule the parent directories for |
| 405 // deletion unconditionally. If they are not empty, the session manager | 417 // deletion unconditionally. If they are not empty, the session manager |
| 406 // will not delete them on reboot. | 418 // will not delete them on reboot. |
| 407 ScheduleParentAndGrandparentForDeletion(installer_state.target_path()); | 419 ScheduleParentAndGrandparentForDeletion(target_path); |
| 408 } else { | 420 } else { |
| 409 // Now check and delete if the parent directories are empty | 421 // Now check and delete if the parent directories are empty |
| 410 // For example Google\Chrome or Chromium | 422 // For example Google\Chrome or Chromium |
| 411 DeleteEmptyParentDir(installer_state.target_path()); | 423 DeleteEmptyParentDir(target_path); |
| 412 } | 424 } |
| 413 return result; | 425 return result; |
| 414 } | 426 } |
| 415 | 427 |
| 416 // This method checks if Chrome is currently running or if the user has | 428 // This method checks if Chrome is currently running or if the user has |
| 417 // cancelled the uninstall operation by clicking Cancel on the confirmation | 429 // cancelled the uninstall operation by clicking Cancel on the confirmation |
| 418 // box that Chrome pops up. | 430 // box that Chrome pops up. |
| 419 InstallStatus IsChromeActiveOrUserCancelled( | 431 InstallStatus IsChromeActiveOrUserCancelled( |
| 420 const InstallerState& installer_state, | 432 const InstallerState& installer_state, |
| 421 const Product& product) { | 433 const Product& product) { |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 | 687 |
| 676 // For user level install also we end up creating some keys in HKLM if user | 688 // For user level install also we end up creating some keys in HKLM if user |
| 677 // sets Chrome as default browser. So delete those as well (needs admin). | 689 // sets Chrome as default browser. So delete those as well (needs admin). |
| 678 if (remove_all && !installer_state.system_install() && | 690 if (remove_all && !installer_state.system_install() && |
| 679 (!suffix.empty() || CurrentUserHasDefaultBrowser(installer_state, | 691 (!suffix.empty() || CurrentUserHasDefaultBrowser(installer_state, |
| 680 product))) { | 692 product))) { |
| 681 DeleteChromeRegistrationKeys(product.distribution(), HKEY_LOCAL_MACHINE, | 693 DeleteChromeRegistrationKeys(product.distribution(), HKEY_LOCAL_MACHINE, |
| 682 suffix, ret); | 694 suffix, ret); |
| 683 } | 695 } |
| 684 | 696 |
| 697 ProcessQuickEnableWorkItems(installer_state, original_state); |
| 698 |
| 685 // Get the state of the installed product (if any) | 699 // Get the state of the installed product (if any) |
| 686 const ProductState* product_state = | 700 const ProductState* product_state = |
| 687 original_state.GetProductState(installer_state.system_install(), | 701 original_state.GetProductState(installer_state.system_install(), |
| 688 browser_dist->GetType()); | 702 browser_dist->GetType()); |
| 689 | 703 |
| 690 // Delete shared registry keys as well (these require admin rights) if | 704 // Delete shared registry keys as well (these require admin rights) if |
| 691 // remove_all option is specified. | 705 // remove_all option is specified. |
| 692 if (remove_all) { | 706 if (remove_all) { |
| 693 if (!InstallUtil::IsChromeSxSProcess() && is_chrome) { | 707 if (!InstallUtil::IsChromeSxSProcess() && is_chrome) { |
| 694 // Delete media player registry key that exists only in HKLM. | 708 // Delete media player registry key that exists only in HKLM. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 | 820 |
| 807 // Try and delete the preserved local state once the post-install | 821 // Try and delete the preserved local state once the post-install |
| 808 // operations are complete. | 822 // operations are complete. |
| 809 if (!backup_state_file.empty()) | 823 if (!backup_state_file.empty()) |
| 810 file_util::Delete(backup_state_file, false); | 824 file_util::Delete(backup_state_file, false); |
| 811 | 825 |
| 812 return ret; | 826 return ret; |
| 813 } | 827 } |
| 814 | 828 |
| 815 } // namespace installer | 829 } // namespace installer |
| OLD | NEW |