diff options
author | gab@chromium.org <gab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-17 07:54:24 +0000 |
---|---|---|
committer | gab@chromium.org <gab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-17 07:54:24 +0000 |
commit | 0cb3b25055494db705ffca1df181afbcaf64d6fb (patch) | |
tree | 57ea3c21e1489e5b3cd992d38a5e001e8d6baf81 /chrome/installer/setup | |
parent | 9b10059674ad8b44d93ff9e9cfb43235272cdd52 (diff) | |
download | chromium_src-0cb3b25055494db705ffca1df181afbcaf64d6fb.zip chromium_src-0cb3b25055494db705ffca1df181afbcaf64d6fb.tar.gz chromium_src-0cb3b25055494db705ffca1df181afbcaf64d6fb.tar.bz2 |
Always suffix ChromeHTML entries on Windows for user-level installs.
This also adds the same suffixing to Chrome's appname for Default Programs registration (this suffix is not user-facing though as we don't suffix the actual string representing Chrome in the UI... obviously!)
Design doc: https://docs.google.com/a/chromium.org/document/d/1qmcV3uYBh3JwvXhYkI7asg0nN7KfVMWVOzND4p0jQ3E/edit
BUG=125362,124013,133173
TEST=http://goo.gl/ZZ7gE
Review URL: https://chromiumcodereview.appspot.com/10451074
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142634 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer/setup')
-rw-r--r-- | chrome/installer/setup/setup_main.cc | 47 | ||||
-rw-r--r-- | chrome/installer/setup/uninstall.cc | 93 | ||||
-rw-r--r-- | chrome/installer/setup/uninstall.h | 3 |
3 files changed, 72 insertions, 71 deletions
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index ad881c2..4e709f6 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc @@ -7,8 +7,6 @@ #include <shellapi.h> #include <shlobj.h> -#include <string> - #include "base/at_exit.h" #include "base/basictypes.h" #include "base/command_line.h" @@ -17,6 +15,7 @@ #include "base/path_service.h" #include "base/process_util.h" #include "base/scoped_temp_dir.h" +#include "base/string16.h" #include "base/string_number_conversions.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" @@ -99,7 +98,7 @@ DWORD UnPackArchive(const FilePath& archive, // First uncompress the payload. This could be a differential // update (patch.7z) or full archive (chrome.7z). If this uncompress fails // return with error. - std::wstring unpacked_file; + string16 unpacked_file; int32 ret = LzmaUtil::UnPackArchive(archive.value(), temp_path.value(), &unpacked_file); if (ret != NO_ERROR) @@ -234,7 +233,7 @@ installer::InstallStatus RenameChromeExecutables( // Add work items to delete the "opv", "cpv", and "cmd" values from all // distributions. HKEY reg_root = installer_state->root_key(); - std::wstring version_key; + string16 version_key; for (int i = 0; i < num_dists; ++i) { version_key = dists[i]->GetVersionKey(); install_list->AddDeleteRegValueWorkItem( @@ -663,7 +662,8 @@ installer::InstallStatus InstallProductsHelper( temp_path.path(), prefs_source_path, prefs, *installer_version); int install_msg_base = IDS_INSTALL_FAILED_BASE; - std::wstring chrome_exe; + string16 chrome_exe; + string16 quoted_chrome_exe; if (install_status == installer::SAME_VERSION_REPAIR_FAILED) { if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) { install_msg_base = IDS_SAME_VERSION_REPAIR_FAILED_CF_BASE; @@ -679,7 +679,7 @@ installer::InstallStatus InstallProductsHelper( } else { chrome_exe = installer_state.target_path() .Append(installer::kChromeExe).value(); - chrome_exe = L"\"" + chrome_exe + L"\""; + quoted_chrome_exe = L"\"" + chrome_exe + L"\""; install_msg_base = 0; } } @@ -707,7 +707,7 @@ installer::InstallStatus InstallProductsHelper( install_status != installer::IN_USE_UPDATED); installer_state.WriteInstallerResult(install_status, install_msg_base, - write_chrome_launch_string ? &chrome_exe : NULL); + write_chrome_launch_string ? "ed_chrome_exe : NULL); if (install_status == installer::FIRST_INSTALL_SUCCESS) { VLOG(1) << "First install successful."; @@ -724,8 +724,11 @@ installer::InstallStatus InstallProductsHelper( (install_status == installer::IN_USE_UPDATED)) { const Product* chrome = installer_state.FindProduct( BrowserDistribution::CHROME_BROWSER); - if (chrome != NULL) - installer::RemoveChromeLegacyRegistryKeys(chrome->distribution()); + if (chrome != NULL) { + DCHECK_NE(chrome_exe, string16()); + installer::RemoveChromeLegacyRegistryKeys(chrome->distribution(), + chrome_exe); + } } } } @@ -901,9 +904,9 @@ installer::InstallStatus UninstallProducts( return install_status; } -installer::InstallStatus ShowEULADialog(const std::wstring& inner_frame) { +installer::InstallStatus ShowEULADialog(const string16& inner_frame) { VLOG(1) << "About to show EULA"; - std::wstring eula_path = installer::GetLocalizedEulaResource(); + string16 eula_path = installer::GetLocalizedEulaResource(); if (eula_path.empty()) { LOG(ERROR) << "No EULA path available"; return installer::EULA_REJECTED; @@ -945,10 +948,10 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, if (!temp_path.CreateUniqueTempDir()) { PLOG(ERROR) << "Could not create temporary path."; } else { - std::wstring setup_patch = cmd_line.GetSwitchValueNative( + string16 setup_patch = cmd_line.GetSwitchValueNative( installer::switches::kUpdateSetupExe); VLOG(1) << "Opening archive " << setup_patch; - std::wstring uncompressed_patch; + string16 uncompressed_patch; if (LzmaUtil::UnPackArchive(setup_patch, temp_path.path().value(), &uncompressed_patch) == NO_ERROR) { FilePath old_setup_exe = cmd_line.GetProgram(); @@ -980,7 +983,7 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, } else if (cmd_line.HasSwitch(installer::switches::kShowEula)) { // Check if we need to show the EULA. If it is passed as a command line // then the dialog is shown and regardless of the outcome setup exits here. - std::wstring inner_frame = + string16 inner_frame = cmd_line.GetSwitchValueNative(installer::switches::kShowEula); *exit_code = ShowEULADialog(inner_frame); if (installer::EULA_REJECTED != *exit_code) { @@ -1009,9 +1012,9 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, // These options should only be used when setup.exe is launched with admin // rights. We do not make any user specific changes with this option. DCHECK(IsUserAnAdmin()); - std::wstring chrome_exe(cmd_line.GetSwitchValueNative( + string16 chrome_exe(cmd_line.GetSwitchValueNative( installer::switches::kRegisterChromeBrowser)); - std::wstring suffix; + string16 suffix; if (cmd_line.HasSwitch( installer::switches::kRegisterChromeBrowserSuffix)) { suffix = cmd_line.GetSwitchValueNative( @@ -1019,7 +1022,7 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, } if (cmd_line.HasSwitch( installer::switches::kRegisterURLProtocol)) { - std::wstring protocol = cmd_line.GetSwitchValueNative( + string16 protocol = cmd_line.GetSwitchValueNative( installer::switches::kRegisterURLProtocol); // ShellUtil::RegisterChromeForProtocol performs all registration // done by ShellUtil::RegisterChromeBrowser, as well as registering @@ -1046,7 +1049,7 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, // Here we delete Chrome browser registration. This option should only // be used when setup.exe is launched with admin rights. We do not // make any user specific changes in this option. - std::wstring suffix; + string16 suffix; if (cmd_line.HasSwitch( installer::switches::kRegisterChromeBrowserSuffix)) { suffix = cmd_line.GetSwitchValueNative( @@ -1181,8 +1184,8 @@ class AutoCom { // Returns the Custom information for the client identified by the exe path // passed in. This information is used for crash reporting. google_breakpad::CustomClientInfo* GetCustomInfo(const wchar_t* exe_path) { - std::wstring product; - std::wstring version; + string16 product; + string16 version; scoped_ptr<FileVersionInfo> version_info(FileVersionInfo::CreateFileVersionInfo(FilePath(exe_path))); if (version_info.get()) { @@ -1227,7 +1230,7 @@ google_breakpad::ExceptionHandler* InitializeCrashReporting( // Build the pipe name. It can be either: // System-wide install: "NamedPipe\GoogleCrashServices\S-1-5-18" // Per-user install: "NamedPipe\GoogleCrashServices\<user SID>" - std::wstring user_sid = kSystemPrincipalSid; + string16 user_sid = kSystemPrincipalSid; if (!system_install) { if (!base::win::GetUserSidString(&user_sid)) { @@ -1235,7 +1238,7 @@ google_breakpad::ExceptionHandler* InitializeCrashReporting( } } - std::wstring pipe_name = kGoogleUpdatePipeName; + string16 pipe_name = kGoogleUpdatePipeName; pipe_name += user_sid; google_breakpad::ExceptionHandler* breakpad = diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc index 8a56753..33cc700 100644 --- a/chrome/installer/setup/uninstall.cc +++ b/chrome/installer/setup/uninstall.cc @@ -220,33 +220,6 @@ void CloseChromeFrameHelperProcess() { } } -// This method tries to figure out if current user has registered Chrome. -// It returns true iff there is a registered browser that will launch the -// same chrome.exe as the current installation. -bool CurrentUserHasDefaultBrowser(const InstallerState& installer_state) { - using base::win::RegistryKeyIterator; - const HKEY root = HKEY_LOCAL_MACHINE; - InstallUtil::ProgramCompare open_command_pred( - installer_state.target_path().Append(kChromeExe)); - string16 client_open_path; - RegKey client_open_key; - string16 reg_exe; - for (RegistryKeyIterator iter(root, ShellUtil::kRegStartMenuInternet); - iter.Valid(); ++iter) { - client_open_path.assign(ShellUtil::kRegStartMenuInternet) - .append(1, L'\\') - .append(iter.Name()) - .append(ShellUtil::kRegShellOpen); - if (client_open_key.Open(root, client_open_path.c_str(), - KEY_QUERY_VALUE) == ERROR_SUCCESS && - client_open_key.ReadValue(L"", ®_exe) == ERROR_SUCCESS && - open_command_pred.Evaluate(reg_exe)) { - return true; - } - } - return false; -} - // This method deletes Chrome shortcut folder from Windows Start menu. It // checks system_uninstall to see if the shortcut is in all users start menu // or current user start menu. @@ -664,7 +637,8 @@ bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root, return true; } -void RemoveChromeLegacyRegistryKeys(BrowserDistribution* dist) { +void RemoveChromeLegacyRegistryKeys(BrowserDistribution* dist, + const string16& chrome_exe) { // We used to register Chrome to handle crx files, but this turned out // to be not worth the hassle. Remove these old registry entries if // they exist. See: http://codereview.chromium.org/210007 @@ -678,9 +652,8 @@ const wchar_t kChromeExtProgId[] = L"ChromiumExt"; HKEY roots[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; for (size_t i = 0; i < arraysize(roots); ++i) { string16 suffix; - if (roots[i] == HKEY_LOCAL_MACHINE && - !ShellUtil::GetUserSpecificDefaultBrowserSuffix(dist, &suffix)) - suffix = L""; + if (roots[i] == HKEY_LOCAL_MACHINE) + suffix = ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe); // Delete Software\Classes\ChromeExt, string16 ext_prog_id(ShellUtil::kRegClasses); @@ -730,12 +703,13 @@ InstallStatus UninstallProduct(const InstallationState& original_state, bool force_uninstall, const CommandLine& cmd_line) { InstallStatus status = installer::UNINSTALL_CONFIRMED; - string16 suffix; - if (!ShellUtil::GetUserSpecificDefaultBrowserSuffix(product.distribution(), - &suffix)) - suffix = L""; - BrowserDistribution* browser_dist = product.distribution(); + const string16 chrome_exe( + installer_state.target_path().Append(installer::kChromeExe).value()); + + const string16 suffix(ShellUtil::GetCurrentInstallationSuffix(browser_dist, + chrome_exe)); + bool is_chrome = product.is_chrome(); VLOG(1) << "UninstallProduct: " << browser_dist->GetApplicationName(); @@ -753,11 +727,15 @@ InstallStatus UninstallProduct(const InstallationState& original_state, status != installer::UNINSTALL_DELETE_PROFILE) return status; - // Check if we need admin rights to cleanup HKLM. If we do, try to launch - // another uninstaller (silent) in elevated mode to do HKLM cleanup. + // Check if we need admin rights to cleanup HKLM (the conditions for + // requiring a cleanup are the same as the conditions to do the actual + // cleanup where DeleteChromeRegistrationKeys() is invoked for + // HKEY_LOCAL_MACHINE below). If we do, try to launch another uninstaller + // (silent) in elevated mode to do HKLM cleanup. // And continue uninstalling in the current process also to do HKCU cleanup. if (remove_all && - (!suffix.empty() || CurrentUserHasDefaultBrowser(installer_state)) && + ShellUtil::QuickIsChromeRegisteredInHKLM( + browser_dist, chrome_exe, suffix) && !::IsUserAnAdmin() && base::win::GetVersion() >= base::win::VERSION_VISTA && !cmd_line.HasSwitch(installer::switches::kRunAsAdmin)) { @@ -811,21 +789,40 @@ InstallStatus UninstallProduct(const InstallationState& original_state, // Registration data is put in HKCU for both system level and user level // installs. InstallStatus ret = installer::UNKNOWN_STATUS; - DeleteChromeRegistrationKeys(product.distribution(), HKEY_CURRENT_USER, - suffix, installer_state.target_path(), &ret); + DeleteChromeRegistrationKeys(browser_dist, HKEY_CURRENT_USER, suffix, + installer_state.target_path(), &ret); + + // If the user's Chrome is registered with a suffix: it is possible that old + // unsuffixed registrations were left in HKCU (e.g. if this install was + // previously installed with no suffix in HKCU (old suffix rules if the user + // is not an admin (or declined UAC at first run)) and later had to be + // suffixed when fully registered in HKLM (e.g. when later making Chrome + // default through the UI)). + // Remove remaining HKCU entries with no suffix if any. + if (!suffix.empty()) { + DeleteChromeRegistrationKeys(browser_dist, HKEY_CURRENT_USER, string16(), + installer_state.target_path(), &ret); + } // Chrome is registered in HKLM for all system-level installs and for // user-level installs for which Chrome has been made the default browser. // Always remove the HKLM registration for system-level installs. For - // user-level installs, only remove it if both: 1) this uninstall isn't a - // self-destruct following the installation of system-level Chrome (because - // the system-level Chrome owns the HKLM registration now), and 2) this user - // had made Chrome their default browser. + // user-level installs, only remove it if both: 1) this uninstall isn't a self + // destruct following the installation of a system-level Chrome (because the + // system-level Chrome owns the HKLM registration now), and 2) this user has + // made Chrome their default browser (i.e. has system entries registered with + // |suffix| (note: |suffix| will be the empty string if required as it is + // obtained by GetCurrentInstallationSuffix() above)). + // TODO(gab): This can still leave parts of a suffixed install behind. To be + // able to remove them we would need to be able to remove only suffixed + // entries (as it is now some of the system entries are unsuffixed; thus + // removing suffixed installs is prohibited in HKLM if !|remove_all| for now). if (installer_state.system_install() || (remove_all && - (!suffix.empty() || CurrentUserHasDefaultBrowser(installer_state)))) { - DeleteChromeRegistrationKeys(product.distribution(), HKEY_LOCAL_MACHINE, - suffix, installer_state.target_path(), &ret); + ShellUtil::QuickIsChromeRegisteredInHKLM( + browser_dist, chrome_exe, suffix))) { + DeleteChromeRegistrationKeys(browser_dist, HKEY_LOCAL_MACHINE, suffix, + installer_state.target_path(), &ret); } ProcessDelegateExecuteWorkItems(installer_state, product); diff --git a/chrome/installer/setup/uninstall.h b/chrome/installer/setup/uninstall.h index a11ec024..7867bb4 100644 --- a/chrome/installer/setup/uninstall.h +++ b/chrome/installer/setup/uninstall.h @@ -35,7 +35,8 @@ bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root, // Removes any legacy registry keys from earlier versions of Chrome that are no // longer needed. This is used during autoupdate since we don't do full // uninstalls/reinstalls to update. -void RemoveChromeLegacyRegistryKeys(BrowserDistribution* dist); +void RemoveChromeLegacyRegistryKeys(BrowserDistribution* dist, + const string16& chrome_exe); // This function uninstalls a product. Hence we came up with this awesome // name for it. |