| OLD | NEW |
| 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 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 should_delete = true; | 610 should_delete = true; |
| 611 } else { | 611 } else { |
| 612 should_delete = | 612 should_delete = |
| 613 status == installer::UNINSTALL_DELETE_PROFILE || | 613 status == installer::UNINSTALL_DELETE_PROFILE || |
| 614 cmd_line.HasSwitch(installer::switches::kDeleteProfile); | 614 cmd_line.HasSwitch(installer::switches::kDeleteProfile); |
| 615 } | 615 } |
| 616 | 616 |
| 617 return should_delete; | 617 return should_delete; |
| 618 } | 618 } |
| 619 | 619 |
| 620 // Removes XP-era filetype registration making Chrome the default browser. |
| 621 // MSDN (see http://msdn.microsoft.com/library/windows/desktop/cc144148.aspx) |
| 622 // tells us not to do this, but certain applications break following |
| 623 // uninstallation if we don't. |
| 624 void RemoveFiletypeRegistration(const InstallerState& installer_state, |
| 625 HKEY root, |
| 626 const string16& browser_entry_suffix) { |
| 627 string16 classes_path(ShellUtil::kRegClasses); |
| 628 classes_path.push_back(FilePath::kSeparators[0]); |
| 629 |
| 630 const string16 prog_id(ShellUtil::kChromeHTMLProgId + browser_entry_suffix); |
| 631 |
| 632 // Delete each filetype association if it references this Chrome. Take care |
| 633 // not to delete the association if it references a system-level install of |
| 634 // Chrome (only a risk if the suffix is empty). Don't delete the whole key |
| 635 // since other apps may have stored data there. |
| 636 std::vector<const wchar_t*> cleared_assocs; |
| 637 if (installer_state.system_install() || |
| 638 !browser_entry_suffix.empty() || |
| 639 !base::win::RegKey(HKEY_LOCAL_MACHINE, (classes_path + prog_id).c_str(), |
| 640 KEY_QUERY_VALUE).Valid()) { |
| 641 InstallUtil::ValueEquals prog_id_pred(prog_id); |
| 642 for (const wchar_t* const* filetype = &ShellUtil::kFileAssociations[0]; |
| 643 *filetype != NULL; ++filetype) { |
| 644 if (InstallUtil::DeleteRegistryValueIf( |
| 645 root, (classes_path + *filetype).c_str(), L"", |
| 646 prog_id_pred) == InstallUtil::DELETED) { |
| 647 cleared_assocs.push_back(*filetype); |
| 648 } |
| 649 } |
| 650 } |
| 651 |
| 652 // For all filetype associations in HKLM that have just been removed, attempt |
| 653 // to restore some reasonable value. We have no definitive way of knowing |
| 654 // what handlers are the most appropriate, so we use a fixed mapping based on |
| 655 // the default values for a fresh install of Windows. |
| 656 if (root == HKEY_LOCAL_MACHINE) { |
| 657 string16 assoc; |
| 658 base::win::RegKey key; |
| 659 |
| 660 for (size_t i = 0; i < cleared_assocs.size(); ++i) { |
| 661 const wchar_t* replacement_prog_id = NULL; |
| 662 assoc.assign(cleared_assocs[i]); |
| 663 |
| 664 // Inelegant, but simpler than a pure data-driven approach. |
| 665 if (assoc == L".htm" || assoc == L".html") |
| 666 replacement_prog_id = L"htmlfile"; |
| 667 else if (assoc == L".xht" || assoc == L".xhtml") |
| 668 replacement_prog_id = L"xhtmlfile"; |
| 669 |
| 670 if (!replacement_prog_id) { |
| 671 LOG(WARNING) << "No known replacement ProgID for " << assoc |
| 672 << " files."; |
| 673 } else if (key.Open(HKEY_LOCAL_MACHINE, |
| 674 (classes_path + replacement_prog_id).c_str(), |
| 675 KEY_QUERY_VALUE) == ERROR_SUCCESS && |
| 676 (key.Open(HKEY_LOCAL_MACHINE, (classes_path + assoc).c_str(), |
| 677 KEY_SET_VALUE) != ERROR_SUCCESS || |
| 678 key.WriteValue(NULL, replacement_prog_id) != ERROR_SUCCESS)) { |
| 679 // The replacement ProgID is registered on the computer but the attempt |
| 680 // to set it for the filetype failed. |
| 681 LOG(ERROR) << "Failed to restore system-level filetype association " |
| 682 << assoc << " = " << replacement_prog_id; |
| 683 } |
| 684 } |
| 685 } |
| 686 } |
| 687 |
| 620 bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, | 688 bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, |
| 621 BrowserDistribution* dist, | 689 BrowserDistribution* dist, |
| 622 HKEY root, | 690 HKEY root, |
| 623 const string16& browser_entry_suffix, | 691 const string16& browser_entry_suffix, |
| 624 InstallStatus* exit_code) { | 692 InstallStatus* exit_code) { |
| 625 DCHECK(exit_code); | 693 DCHECK(exit_code); |
| 626 if (!dist->CanSetAsDefault()) { | 694 if (!dist->CanSetAsDefault()) { |
| 627 // We should have never set those keys. | 695 // We should have never set those keys. |
| 628 return true; | 696 return true; |
| 629 } | 697 } |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 743 &ShellUtil::kPotentialProtocolAssociations[0]; | 811 &ShellUtil::kPotentialProtocolAssociations[0]; |
| 744 *proto != NULL; | 812 *proto != NULL; |
| 745 ++proto) { | 813 ++proto) { |
| 746 parent_key.resize(base_length); | 814 parent_key.resize(base_length); |
| 747 parent_key.append(*proto); | 815 parent_key.append(*proto); |
| 748 child_key.assign(parent_key).append(ShellUtil::kRegShellOpen); | 816 child_key.assign(parent_key).append(ShellUtil::kRegShellOpen); |
| 749 InstallUtil::DeleteRegistryKeyIf(root, parent_key, child_key, L"", | 817 InstallUtil::DeleteRegistryKeyIf(root, parent_key, child_key, L"", |
| 750 open_command_pred); | 818 open_command_pred); |
| 751 } | 819 } |
| 752 | 820 |
| 753 // Delete each filetype association if it references this Chrome. Take care | 821 RemoveFiletypeRegistration(installer_state, root, browser_entry_suffix); |
| 754 // not to delete the association if it references a system-level install of | |
| 755 // Chrome (only a risk if the suffix is empty). Don't delete the whole key | |
| 756 // since other apps may have stored data there. | |
| 757 if (!browser_entry_suffix.empty() || | |
| 758 (!installer_state.system_install() && | |
| 759 !base::win::RegKey(HKEY_LOCAL_MACHINE, reg_prog_id.c_str(), | |
| 760 KEY_QUERY_VALUE).Valid())) { | |
| 761 InstallUtil::ValueEquals prog_id_pred(prog_id); | |
| 762 for (const wchar_t* const* filetype = &ShellUtil::kFileAssociations[0]; | |
| 763 *filetype != NULL; ++filetype) { | |
| 764 parent_key.resize(base_length); | |
| 765 parent_key.append(*filetype); | |
| 766 InstallUtil::DeleteRegistryValueIf(root, parent_key.c_str(), L"", | |
| 767 prog_id_pred); | |
| 768 } | |
| 769 } | |
| 770 | |
| 771 // Note that we do not attempt to delete filetype associations since MSDN | |
| 772 // says "Windows respects the Default value only if the ProgID found there is | |
| 773 // a registered ProgID. If the ProgID is unregistered, it is ignored." | |
| 774 | 822 |
| 775 *exit_code = installer::UNINSTALL_SUCCESSFUL; | 823 *exit_code = installer::UNINSTALL_SUCCESSFUL; |
| 776 return true; | 824 return true; |
| 777 } | 825 } |
| 778 | 826 |
| 779 void RemoveChromeLegacyRegistryKeys(BrowserDistribution* dist, | 827 void RemoveChromeLegacyRegistryKeys(BrowserDistribution* dist, |
| 780 const string16& chrome_exe) { | 828 const string16& chrome_exe) { |
| 781 // We used to register Chrome to handle crx files, but this turned out | 829 // We used to register Chrome to handle crx files, but this turned out |
| 782 // to be not worth the hassle. Remove these old registry entries if | 830 // to be not worth the hassle. Remove these old registry entries if |
| 783 // they exist. See: http://codereview.chromium.org/210007 | 831 // they exist. See: http://codereview.chromium.org/210007 |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1227 | 1275 |
| 1228 // Try and delete the preserved local state once the post-install | 1276 // Try and delete the preserved local state once the post-install |
| 1229 // operations are complete. | 1277 // operations are complete. |
| 1230 if (!backup_state_file.empty()) | 1278 if (!backup_state_file.empty()) |
| 1231 file_util::Delete(backup_state_file, false); | 1279 file_util::Delete(backup_state_file, false); |
| 1232 | 1280 |
| 1233 return ret; | 1281 return ret; |
| 1234 } | 1282 } |
| 1235 | 1283 |
| 1236 } // namespace installer | 1284 } // namespace installer |
| OLD | NEW |