| Index: chrome/installer/setup/uninstall.cc
|
| diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc
|
| index 0256590c65089166730ebc4df3528c0ad9af7b53..7b10923f80ae2ad55e0d555a01626a8f07f19207 100644
|
| --- a/chrome/installer/setup/uninstall.cc
|
| +++ b/chrome/installer/setup/uninstall.cc
|
| @@ -617,6 +617,74 @@ bool ShouldDeleteProfile(const InstallerState& installer_state,
|
| return should_delete;
|
| }
|
|
|
| +// Removes XP-era filetype registration making Chrome the default browser.
|
| +// MSDN (see http://msdn.microsoft.com/library/windows/desktop/cc144148.aspx)
|
| +// tells us not to do this, but certain applications break following
|
| +// uninstallation if we don't.
|
| +void RemoveFiletypeRegistration(const InstallerState& installer_state,
|
| + HKEY root,
|
| + const string16& browser_entry_suffix) {
|
| + string16 classes_path(ShellUtil::kRegClasses);
|
| + classes_path.push_back(FilePath::kSeparators[0]);
|
| +
|
| + const string16 prog_id(ShellUtil::kChromeHTMLProgId + browser_entry_suffix);
|
| +
|
| + // Delete each filetype association if it references this Chrome. Take care
|
| + // not to delete the association if it references a system-level install of
|
| + // Chrome (only a risk if the suffix is empty). Don't delete the whole key
|
| + // since other apps may have stored data there.
|
| + std::vector<const wchar_t*> cleared_assocs;
|
| + if (installer_state.system_install() ||
|
| + !browser_entry_suffix.empty() ||
|
| + !base::win::RegKey(HKEY_LOCAL_MACHINE, (classes_path + prog_id).c_str(),
|
| + KEY_QUERY_VALUE).Valid()) {
|
| + InstallUtil::ValueEquals prog_id_pred(prog_id);
|
| + for (const wchar_t* const* filetype = &ShellUtil::kFileAssociations[0];
|
| + *filetype != NULL; ++filetype) {
|
| + if (InstallUtil::DeleteRegistryValueIf(
|
| + root, (classes_path + *filetype).c_str(), L"",
|
| + prog_id_pred) == InstallUtil::DELETED) {
|
| + cleared_assocs.push_back(*filetype);
|
| + }
|
| + }
|
| + }
|
| +
|
| + // For all filetype associations in HKLM that have just been removed, attempt
|
| + // to restore some reasonable value. We have no definitive way of knowing
|
| + // what handlers are the most appropriate, so we use a fixed mapping based on
|
| + // the default values for a fresh install of Windows.
|
| + if (root == HKEY_LOCAL_MACHINE) {
|
| + string16 assoc;
|
| + base::win::RegKey key;
|
| +
|
| + for (size_t i = 0; i < cleared_assocs.size(); ++i) {
|
| + const wchar_t* replacement_prog_id = NULL;
|
| + assoc.assign(cleared_assocs[i]);
|
| +
|
| + // Inelegant, but simpler than a pure data-driven approach.
|
| + if (assoc == L".htm" || assoc == L".html")
|
| + replacement_prog_id = L"htmlfile";
|
| + else if (assoc == L".xht" || assoc == L".xhtml")
|
| + replacement_prog_id = L"xhtmlfile";
|
| +
|
| + if (!replacement_prog_id) {
|
| + LOG(WARNING) << "No known replacement ProgID for " << assoc
|
| + << " files.";
|
| + } else if (key.Open(HKEY_LOCAL_MACHINE,
|
| + (classes_path + replacement_prog_id).c_str(),
|
| + KEY_QUERY_VALUE) == ERROR_SUCCESS &&
|
| + (key.Open(HKEY_LOCAL_MACHINE, (classes_path + assoc).c_str(),
|
| + KEY_SET_VALUE) != ERROR_SUCCESS ||
|
| + key.WriteValue(NULL, replacement_prog_id) != ERROR_SUCCESS)) {
|
| + // The replacement ProgID is registered on the computer but the attempt
|
| + // to set it for the filetype failed.
|
| + LOG(ERROR) << "Failed to restore system-level filetype association "
|
| + << assoc << " = " << replacement_prog_id;
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| bool DeleteChromeRegistrationKeys(const InstallerState& installer_state,
|
| BrowserDistribution* dist,
|
| HKEY root,
|
| @@ -750,27 +818,7 @@ bool DeleteChromeRegistrationKeys(const InstallerState& installer_state,
|
| open_command_pred);
|
| }
|
|
|
| - // Delete each filetype association if it references this Chrome. Take care
|
| - // not to delete the association if it references a system-level install of
|
| - // Chrome (only a risk if the suffix is empty). Don't delete the whole key
|
| - // since other apps may have stored data there.
|
| - if (!browser_entry_suffix.empty() ||
|
| - (!installer_state.system_install() &&
|
| - !base::win::RegKey(HKEY_LOCAL_MACHINE, reg_prog_id.c_str(),
|
| - KEY_QUERY_VALUE).Valid())) {
|
| - InstallUtil::ValueEquals prog_id_pred(prog_id);
|
| - for (const wchar_t* const* filetype = &ShellUtil::kFileAssociations[0];
|
| - *filetype != NULL; ++filetype) {
|
| - parent_key.resize(base_length);
|
| - parent_key.append(*filetype);
|
| - InstallUtil::DeleteRegistryValueIf(root, parent_key.c_str(), L"",
|
| - prog_id_pred);
|
| - }
|
| - }
|
| -
|
| - // Note that we do not attempt to delete filetype associations since MSDN
|
| - // says "Windows respects the Default value only if the ProgID found there is
|
| - // a registered ProgID. If the ProgID is unregistered, it is ignored."
|
| + RemoveFiletypeRegistration(installer_state, root, browser_entry_suffix);
|
|
|
| *exit_code = installer::UNINSTALL_SUCCESSFUL;
|
| return true;
|
|
|