Chromium Code Reviews| Index: chrome/installer/setup/uninstall.cc |
| diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc |
| index 0256590c65089166730ebc4df3528c0ad9af7b53..c9f41705f1b5a22e5f644f345d81daba120a6477 100644 |
| --- a/chrome/installer/setup/uninstall.cc |
| +++ b/chrome/installer/setup/uninstall.cc |
| @@ -617,6 +617,73 @@ bool ShouldDeleteProfile(const InstallerState& installer_state, |
| return should_delete; |
| } |
| +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. MSDN tells us not to do this |
| + // (see http://msdn.microsoft.com/library/windows/desktop/cc144148.aspx), but |
| + // certain applications break following uninstallation if we don't. |
| + 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 = 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.
|
| + assoc.assign(cleared_assocs[i]); |
| + |
| + // Inelegant, but simpler than a pure data-driven approach. |
| + if (assoc == L".htm" || assoc == L".html") |
| + replacement = L"htmlfile"; |
| + else if (assoc == L".xht" || assoc == L".xhtml") |
| + replacement = L"xhtmlfile"; |
| + |
| + // If we have a replacement ProgID, see if it exists on this computer. |
| + if (replacement && |
| + key.Open(HKEY_LOCAL_MACHINE, (classes_path + replacement).c_str(), |
| + KEY_QUERY_VALUE) == ERROR_SUCCESS) { |
| + // Replace the absence of Chrome's ProgID with the Windows default. |
| + if (key.Open(HKEY_LOCAL_MACHINE, (classes_path + assoc).c_str(), |
| + KEY_SET_VALUE) != ERROR_SUCCESS || |
| + key.WriteValue(NULL, replacement) != ERROR_SUCCESS) { |
| + LOG(ERROR) << "Failed to restore system-level filetype association " |
| + << assoc << " = " << replacement; |
| + } |
| + } else if (replacement) { |
| + LOG(WARNING) << "No known replacement ProgID for " << assoc |
| + << " files."; |
| + } |
| + } |
| + } |
| +} |
| + |
| bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, |
| BrowserDistribution* dist, |
| HKEY root, |
| @@ -750,27 +817,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; |