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 // 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"", | |
|
gab
2012/09/25 14:58:32
nit: Indent 1 more space here and below.
grt (UTC plus 2)
2012/09/25 15:56:21
it's currently indented four spaces from the 'I' a
gab
2012/09/25 17:09:00
I can't count...
| |
| 646 prog_id_pred) == InstallUtil::DELETED) { | |
| 647 cleared_assocs.push_back(*filetype); | |
|
gab
2012/09/25 14:58:32
Do we want to do the replacement in HKCU as well o
grt (UTC plus 2)
2012/09/25 15:56:21
only in HKLM. in HKCU we delete Chrome's value bu
gab
2012/09/25 17:09:00
Right, hmmm well looks to me like this code popula
grt (UTC plus 2)
2012/09/25 18:44:35
Correct.
gab
2012/09/25 18:48:57
Indeed, my bad, read passed the "if (root == HKEY_
| |
| 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 we have a replacement ProgID, see if it exists on this computer. | |
| 671 if (replacement_prog_id && | |
| 672 key.Open(HKEY_LOCAL_MACHINE, | |
| 673 (classes_path + replacement_prog_id).c_str(), | |
| 674 KEY_QUERY_VALUE) == ERROR_SUCCESS) { | |
| 675 // Replace the absence of Chrome's ProgID with the Windows default. | |
| 676 if (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) { | |
|
gab
2012/09/25 14:58:32
Here you use NULL and above (:645) you use L"" to
grt (UTC plus 2)
2012/09/25 15:56:21
addressing by fixing DeleteRegistryValueIf in a se
| |
| 679 LOG(ERROR) << "Failed to restore system-level filetype association " | |
| 680 << assoc << " = " << replacement_prog_id; | |
| 681 } | |
| 682 } else if (replacement_prog_id) { | |
|
gab
2012/09/25 14:58:32
I don't like to have to recheck this condition her
grt (UTC plus 2)
2012/09/25 15:56:21
rejiggered.
| |
| 683 LOG(WARNING) << "No known replacement ProgID for " << assoc | |
| 684 << " files."; | |
| 685 } | |
| 686 } | |
| 687 } | |
| 688 } | |
| 689 | |
| 620 bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, | 690 bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, |
| 621 BrowserDistribution* dist, | 691 BrowserDistribution* dist, |
| 622 HKEY root, | 692 HKEY root, |
| 623 const string16& browser_entry_suffix, | 693 const string16& browser_entry_suffix, |
| 624 InstallStatus* exit_code) { | 694 InstallStatus* exit_code) { |
| 625 DCHECK(exit_code); | 695 DCHECK(exit_code); |
| 626 if (!dist->CanSetAsDefault()) { | 696 if (!dist->CanSetAsDefault()) { |
| 627 // We should have never set those keys. | 697 // We should have never set those keys. |
| 628 return true; | 698 return true; |
| 629 } | 699 } |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 743 &ShellUtil::kPotentialProtocolAssociations[0]; | 813 &ShellUtil::kPotentialProtocolAssociations[0]; |
| 744 *proto != NULL; | 814 *proto != NULL; |
| 745 ++proto) { | 815 ++proto) { |
| 746 parent_key.resize(base_length); | 816 parent_key.resize(base_length); |
| 747 parent_key.append(*proto); | 817 parent_key.append(*proto); |
| 748 child_key.assign(parent_key).append(ShellUtil::kRegShellOpen); | 818 child_key.assign(parent_key).append(ShellUtil::kRegShellOpen); |
| 749 InstallUtil::DeleteRegistryKeyIf(root, parent_key, child_key, L"", | 819 InstallUtil::DeleteRegistryKeyIf(root, parent_key, child_key, L"", |
| 750 open_command_pred); | 820 open_command_pred); |
| 751 } | 821 } |
| 752 | 822 |
| 753 // Delete each filetype association if it references this Chrome. Take care | 823 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 | 824 |
| 775 *exit_code = installer::UNINSTALL_SUCCESSFUL; | 825 *exit_code = installer::UNINSTALL_SUCCESSFUL; |
| 776 return true; | 826 return true; |
| 777 } | 827 } |
| 778 | 828 |
| 779 void RemoveChromeLegacyRegistryKeys(BrowserDistribution* dist, | 829 void RemoveChromeLegacyRegistryKeys(BrowserDistribution* dist, |
| 780 const string16& chrome_exe) { | 830 const string16& chrome_exe) { |
| 781 // We used to register Chrome to handle crx files, but this turned out | 831 // 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 | 832 // to be not worth the hassle. Remove these old registry entries if |
| 783 // they exist. See: http://codereview.chromium.org/210007 | 833 // they exist. See: http://codereview.chromium.org/210007 |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1227 | 1277 |
| 1228 // Try and delete the preserved local state once the post-install | 1278 // Try and delete the preserved local state once the post-install |
| 1229 // operations are complete. | 1279 // operations are complete. |
| 1230 if (!backup_state_file.empty()) | 1280 if (!backup_state_file.empty()) |
| 1231 file_util::Delete(backup_state_file, false); | 1281 file_util::Delete(backup_state_file, false); |
| 1232 | 1282 |
| 1233 return ret; | 1283 return ret; |
| 1234 } | 1284 } |
| 1235 | 1285 |
| 1236 } // namespace installer | 1286 } // namespace installer |
| OLD | NEW |