| 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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 << " is somehow already set to the desired new value of " | 94 << " is somehow already set to the desired new value of " |
| 95 << channel_info.value(); | 95 << channel_info.value(); |
| 96 } | 96 } |
| 97 } | 97 } |
| 98 | 98 |
| 99 bool success = update_list->Do(); | 99 bool success = update_list->Do(); |
| 100 LOG_IF(ERROR, !success) << "Failed updating channel values."; | 100 LOG_IF(ERROR, !success) << "Failed updating channel values."; |
| 101 } | 101 } |
| 102 } | 102 } |
| 103 | 103 |
| 104 // Adds or removes the quick-enable-cf command to the binaries' version key in |
| 105 // the registry as needed. |
| 106 void ProcessQuickEnableWorkItems( |
| 107 const installer::InstallerState& installer_state, |
| 108 const installer::InstallationState& machine_state) { |
| 109 scoped_ptr<WorkItemList> work_item_list( |
| 110 WorkItem::CreateNoRollbackWorkItemList()); |
| 111 |
| 112 AddQuickEnableWorkItems(installer_state, machine_state, NULL, NULL, |
| 113 work_item_list.get()); |
| 114 if (!work_item_list->Do()) |
| 115 LOG(ERROR) << "Failed to update quick-enable-cf command."; |
| 116 } |
| 117 |
| 104 } // namespace | 118 } // namespace |
| 105 | 119 |
| 106 namespace installer { | 120 namespace installer { |
| 107 | 121 |
| 108 // This functions checks for any Chrome instances that are | 122 // This functions checks for any Chrome instances that are |
| 109 // running and first asks them to close politely by sending a Windows message. | 123 // running and first asks them to close politely by sending a Windows message. |
| 110 // If there is an error while sending message or if there are still Chrome | 124 // If there is an error while sending message or if there are still Chrome |
| 111 // procesess active after the message has been sent, this function will try | 125 // procesess active after the message has been sent, this function will try |
| 112 // to kill them. | 126 // to kill them. |
| 113 void CloseAllChromeProcesses() { | 127 void CloseAllChromeProcesses() { |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 } else { | 364 } else { |
| 351 VLOG(1) << "Attempting to move setup to: " << temp_file.value(); | 365 VLOG(1) << "Attempting to move setup to: " << temp_file.value(); |
| 352 ret = file_util::Move(setup_exe, temp_file); | 366 ret = file_util::Move(setup_exe, temp_file); |
| 353 LOG_IF(ERROR, !ret) << "Failed to move setup to " << temp_file.value(); | 367 LOG_IF(ERROR, !ret) << "Failed to move setup to " << temp_file.value(); |
| 354 } | 368 } |
| 355 return ret; | 369 return ret; |
| 356 } | 370 } |
| 357 | 371 |
| 358 DeleteResult DeleteFilesAndFolders(const InstallerState& installer_state, | 372 DeleteResult DeleteFilesAndFolders(const InstallerState& installer_state, |
| 359 const Version& installed_version) { | 373 const Version& installed_version) { |
| 360 VLOG(1) << "DeleteFilesAndFolders: " << installer_state.target_path().value(); | 374 const FilePath& target_path = installer_state.target_path(); |
| 361 if (installer_state.target_path().empty()) { | 375 if (target_path.empty()) { |
| 362 LOG(ERROR) << "Could not get installation destination path."; | 376 LOG(ERROR) << "DeleteFilesAndFolders: no installation destination path."; |
| 363 return DELETE_FAILED; // Nothing else we can do to uninstall, so we return. | 377 return DELETE_FAILED; // Nothing else we can do to uninstall, so we return. |
| 364 } | 378 } |
| 365 | 379 |
| 366 DeleteResult result = DELETE_SUCCEEDED; | 380 DeleteResult result = DELETE_SUCCEEDED; |
| 367 | 381 |
| 368 VLOG(1) << "Deleting install path " << installer_state.target_path().value(); | 382 VLOG(1) << "Deleting install path " << target_path.value(); |
| 369 if (!file_util::Delete(installer_state.target_path(), true)) { | 383 if (!file_util::Delete(target_path, true)) { |
| 370 LOG(ERROR) << "Failed to delete folder (1st try): " | 384 LOG(ERROR) << "Failed to delete folder (1st try): " << target_path.value(); |
| 371 << installer_state.target_path().value(); | |
| 372 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) { | 385 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) { |
| 373 // We don't try killing Chrome processes for Chrome Frame builds since | 386 // We don't try killing Chrome processes for Chrome Frame builds since |
| 374 // that is unlikely to help. Instead, schedule files for deletion and | 387 // that is unlikely to help. Instead, schedule files for deletion and |
| 375 // return a value that will trigger a reboot prompt. | 388 // return a value that will trigger a reboot prompt. |
| 376 ScheduleDirectoryForDeletion( | 389 ScheduleDirectoryForDeletion(target_path.value().c_str()); |
| 377 installer_state.target_path().value().c_str()); | |
| 378 result = DELETE_REQUIRES_REBOOT; | 390 result = DELETE_REQUIRES_REBOOT; |
| 379 } else { | 391 } else { |
| 380 // Try closing any running chrome processes and deleting files once again. | 392 // Try closing any running chrome processes and deleting files once again. |
| 381 CloseAllChromeProcesses(); | 393 CloseAllChromeProcesses(); |
| 382 if (!file_util::Delete(installer_state.target_path(), true)) { | 394 if (!file_util::Delete(target_path, true)) { |
| 383 LOG(ERROR) << "Failed to delete folder (2nd try): " | 395 LOG(ERROR) << "Failed to delete folder (2nd try): " |
| 384 << installer_state.target_path().value(); | 396 << target_path.value(); |
| 385 result = DELETE_FAILED; | 397 result = DELETE_FAILED; |
| 386 } | 398 } |
| 387 } | 399 } |
| 388 } | 400 } |
| 389 | 401 |
| 390 if (result == DELETE_REQUIRES_REBOOT) { | 402 if (result == DELETE_REQUIRES_REBOOT) { |
| 391 // If we need a reboot to continue, schedule the parent directories for | 403 // If we need a reboot to continue, schedule the parent directories for |
| 392 // deletion unconditionally. If they are not empty, the session manager | 404 // deletion unconditionally. If they are not empty, the session manager |
| 393 // will not delete them on reboot. | 405 // will not delete them on reboot. |
| 394 ScheduleParentAndGrandparentForDeletion(installer_state.target_path()); | 406 ScheduleParentAndGrandparentForDeletion(target_path); |
| 395 } else { | 407 } else { |
| 396 // Now check and delete if the parent directories are empty | 408 // Now check and delete if the parent directories are empty |
| 397 // For example Google\Chrome or Chromium | 409 // For example Google\Chrome or Chromium |
| 398 DeleteEmptyParentDir(installer_state.target_path()); | 410 DeleteEmptyParentDir(target_path); |
| 399 } | 411 } |
| 400 return result; | 412 return result; |
| 401 } | 413 } |
| 402 | 414 |
| 403 // This method checks if Chrome is currently running or if the user has | 415 // This method checks if Chrome is currently running or if the user has |
| 404 // cancelled the uninstall operation by clicking Cancel on the confirmation | 416 // cancelled the uninstall operation by clicking Cancel on the confirmation |
| 405 // box that Chrome pops up. | 417 // box that Chrome pops up. |
| 406 InstallStatus IsChromeActiveOrUserCancelled( | 418 InstallStatus IsChromeActiveOrUserCancelled( |
| 407 const InstallerState& installer_state, | 419 const InstallerState& installer_state, |
| 408 const Product& product) { | 420 const Product& product) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 } | 470 } |
| 459 | 471 |
| 460 bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root, | 472 bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root, |
| 461 const std::wstring& browser_entry_suffix, | 473 const std::wstring& browser_entry_suffix, |
| 462 InstallStatus& exit_code) { | 474 InstallStatus& exit_code) { |
| 463 if (!dist->CanSetAsDefault()) { | 475 if (!dist->CanSetAsDefault()) { |
| 464 // We should have never set those keys. | 476 // We should have never set those keys. |
| 465 return true; | 477 return true; |
| 466 } | 478 } |
| 467 | 479 |
| 468 RegKey key(root, L"", KEY_ALL_ACCESS); | 480 RegKey key; |
| 469 if (!key.Valid()) { | 481 LONG result = key.Open(root, L"", KEY_ALL_ACCESS); |
| 470 PLOG(ERROR) << "DeleteChromeRegistrationKeys: failed to open root key"; | 482 if (result != ERROR_SUCCESS) { |
| 483 LOG(ERROR) << "DeleteChromeRegistrationKeys: failed to open root key (lec: " |
| 484 << result << ")."; |
| 471 } | 485 } |
| 472 | 486 |
| 473 // Delete Software\Classes\ChromeHTML, | 487 // Delete Software\Classes\ChromeHTML, |
| 474 std::wstring html_prog_id(ShellUtil::kRegClasses); | 488 std::wstring html_prog_id(ShellUtil::kRegClasses); |
| 475 file_util::AppendToPath(&html_prog_id, ShellUtil::kChromeHTMLProgId); | 489 file_util::AppendToPath(&html_prog_id, ShellUtil::kChromeHTMLProgId); |
| 476 html_prog_id.append(browser_entry_suffix); | 490 html_prog_id.append(browser_entry_suffix); |
| 477 InstallUtil::DeleteRegistryKey(key, html_prog_id); | 491 InstallUtil::DeleteRegistryKey(key, html_prog_id); |
| 478 | 492 |
| 479 // Delete Software\Clients\StartMenuInternet\Chromium | 493 // Delete Software\Clients\StartMenuInternet\Chromium |
| 480 std::wstring set_access_key(ShellUtil::kRegStartMenuInternet); | 494 std::wstring set_access_key(ShellUtil::kRegStartMenuInternet); |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 | 674 |
| 661 // For user level install also we end up creating some keys in HKLM if user | 675 // For user level install also we end up creating some keys in HKLM if user |
| 662 // sets Chrome as default browser. So delete those as well (needs admin). | 676 // sets Chrome as default browser. So delete those as well (needs admin). |
| 663 if (remove_all && !installer_state.system_install() && | 677 if (remove_all && !installer_state.system_install() && |
| 664 (!suffix.empty() || CurrentUserHasDefaultBrowser(installer_state, | 678 (!suffix.empty() || CurrentUserHasDefaultBrowser(installer_state, |
| 665 product))) { | 679 product))) { |
| 666 DeleteChromeRegistrationKeys(product.distribution(), HKEY_LOCAL_MACHINE, | 680 DeleteChromeRegistrationKeys(product.distribution(), HKEY_LOCAL_MACHINE, |
| 667 suffix, ret); | 681 suffix, ret); |
| 668 } | 682 } |
| 669 | 683 |
| 684 ProcessQuickEnableWorkItems(installer_state, original_state); |
| 685 |
| 670 // Get the state of the installed product (if any) | 686 // Get the state of the installed product (if any) |
| 671 const ProductState* product_state = | 687 const ProductState* product_state = |
| 672 original_state.GetProductState(installer_state.system_install(), | 688 original_state.GetProductState(installer_state.system_install(), |
| 673 browser_dist->GetType()); | 689 browser_dist->GetType()); |
| 674 | 690 |
| 675 // Delete shared registry keys as well (these require admin rights) if | 691 // Delete shared registry keys as well (these require admin rights) if |
| 676 // remove_all option is specified. | 692 // remove_all option is specified. |
| 677 if (remove_all) { | 693 if (remove_all) { |
| 678 if (!InstallUtil::IsChromeSxSProcess() && is_chrome) { | 694 if (!InstallUtil::IsChromeSxSProcess() && is_chrome) { |
| 679 // Delete media player registry key that exists only in HKLM. | 695 // Delete media player registry key that exists only in HKLM. |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 | 803 |
| 788 // Try and delete the preserved local state once the post-install | 804 // Try and delete the preserved local state once the post-install |
| 789 // operations are complete. | 805 // operations are complete. |
| 790 if (!backup_state_file.empty()) | 806 if (!backup_state_file.empty()) |
| 791 file_util::Delete(backup_state_file, false); | 807 file_util::Delete(backup_state_file, false); |
| 792 | 808 |
| 793 return ret; | 809 return ret; |
| 794 } | 810 } |
| 795 | 811 |
| 796 } // namespace installer | 812 } // namespace installer |
| OLD | NEW |