summaryrefslogtreecommitdiffstats
path: root/chrome/installer/setup
diff options
context:
space:
mode:
authorgab@chromium.org <gab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-17 07:54:24 +0000
committergab@chromium.org <gab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-17 07:54:24 +0000
commit0cb3b25055494db705ffca1df181afbcaf64d6fb (patch)
tree57ea3c21e1489e5b3cd992d38a5e001e8d6baf81 /chrome/installer/setup
parent9b10059674ad8b44d93ff9e9cfb43235272cdd52 (diff)
downloadchromium_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.cc47
-rw-r--r--chrome/installer/setup/uninstall.cc93
-rw-r--r--chrome/installer/setup/uninstall.h3
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 ? &quoted_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"", &reg_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.