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