summaryrefslogtreecommitdiffstats
path: root/chrome/installer
diff options
context:
space:
mode:
authorkuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-06 16:20:18 +0000
committerkuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-06 16:20:18 +0000
commit09a988dd76797e19acd4702b96aa6c283d66a1e5 (patch)
treea03bee69be2f6be1eddea21545951ec991b5abeb /chrome/installer
parent91c1719fd596d7381e359d294314b24abd02597c (diff)
downloadchromium_src-09a988dd76797e19acd4702b96aa6c283d66a1e5.zip
chromium_src-09a988dd76797e19acd4702b96aa6c283d66a1e5.tar.gz
chromium_src-09a988dd76797e19acd4702b96aa6c283d66a1e5.tar.bz2
Re-re-write the logic to elevate uninstaller.
BUG=7178 TEST=Test install/uninstall in various combinations as described below and make sure that files or registry keys are not left behind: Distribution: {Chromium|Google Chrome} Install Level: {system|user} Delete Profile Option: {Selected|Not selected} Default Browser: {set|not set} Review URL: http://codereview.chromium.org/109037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15412 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer')
-rw-r--r--chrome/installer/setup/main.cc92
-rw-r--r--chrome/installer/setup/uninstall.cc148
-rw-r--r--chrome/installer/setup/uninstall.h10
-rw-r--r--chrome/installer/util/util_constants.cc5
-rw-r--r--chrome/installer/util/util_constants.h3
5 files changed, 140 insertions, 118 deletions
diff --git a/chrome/installer/setup/main.cc b/chrome/installer/setup/main.cc
index 20fb65c..2795edd 100644
--- a/chrome/installer/setup/main.cc
+++ b/chrome/installer/setup/main.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -278,22 +278,6 @@ void CopyPreferenceFileForFirstRun(int options, const CommandLine& cmd_line) {
}
}
-// This method is temporary and only called by UpdateChromeOpenCmd() below.
-void ReplaceRegistryValue(const std::wstring& reg_key,
- const std::wstring& old_val,
- const std::wstring& new_val) {
- RegKey key;
- std::wstring value;
- if (key.Open(HKEY_CLASSES_ROOT, reg_key.c_str(), KEY_READ) &&
- key.ReadValue(NULL, &value) && (old_val == value)) {
- std::wstring key_path = L"Software\\Classes\\" + reg_key;
- if (key.Open(HKEY_CURRENT_USER, key_path.c_str(), KEY_WRITE))
- key.WriteValue(NULL, new_val.c_str());
- if (key.Open(HKEY_LOCAL_MACHINE, key_path.c_str(), KEY_WRITE))
- key.WriteValue(NULL, new_val.c_str());
- }
-}
-
bool CheckPreInstallConditions(const installer::Version* installed_version,
int options,
installer_util::InstallStatus& status) {
@@ -501,6 +485,49 @@ installer_util::InstallStatus ShowEULADialog(const std::wstring& inner_frame) {
return installer_util::EULA_ACCEPTED;
}
+// This method processes any command line options that make setup.exe do
+// various tasks other than installation (renaming chrome.exe, showing eula
+// among others). This function returns true if any such command line option
+// has been found and processed (so setup.exe should exit at that point).
+bool HandleNonInstallCmdLineOptions(const CommandLine& cmd_line,
+ bool system_install,
+ int& exit_code) {
+ if (cmd_line.HasSwitch(installer_util::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 =
+ cmd_line.GetSwitchValue(installer_util::switches::kShowEula);
+ exit_code = ShowEULADialog(inner_frame);
+ if (installer_util::EULA_REJECTED != exit_code)
+ GoogleUpdateSettings::SetEULAConsent(true);
+ return true;;
+ } else if (cmd_line.HasSwitch(
+ installer_util::switches::kRegisterChromeBrowser)) {
+ // If --register-chrome-browser option is specified, register all
+ // Chrome protocol/file associations as well as register it as a valid
+ // browser for Start Menu->Internet shortcut. 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 chrome_exe(cmd_line.GetSwitchValue(
+ installer_util::switches::kRegisterChromeBrowser));
+ exit_code = ShellUtil::AddChromeToSetAccessDefaults(chrome_exe, true);
+ return true;
+ } else if (cmd_line.HasSwitch(installer_util::switches::kRenameChromeExe)) {
+ // If --rename-chrome-exe is specified, we want to rename the executables
+ // and exit.
+ exit_code = RenameChromeExecutables(system_install);
+ return true;
+ } else if (cmd_line.HasSwitch(
+ installer_util::switches::kRemoveChromeRegistration)) {
+ installer_util::InstallStatus tmp = installer_util::UNKNOWN_STATUS;
+ installer_setup::DeleteChromeRegistrationKeys(HKEY_LOCAL_MACHINE, tmp);
+ exit_code = tmp;
+ return true;
+ }
+
+ return false;
+}
+
} // namespace
int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance,
@@ -536,33 +563,10 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance,
return installer_util::OS_ERROR;
}
- // 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.
- if (parsed_command_line.HasSwitch(installer_util::switches::kShowEula)) {
- std::wstring inner_frame =
- parsed_command_line.GetSwitchValue(installer_util::switches::kShowEula);
- installer_util::InstallStatus eula = ShowEULADialog(inner_frame);
- if (installer_util::EULA_REJECTED != eula)
- GoogleUpdateSettings::SetEULAConsent(true);
- return eula;
- }
-
- // If --register-chrome-browser option is specified, register all
- // Chrome protocol/file associations as well as register it as a valid
- // browser for Start Menu->Internet shortcut. 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.
- if (parsed_command_line.HasSwitch(
- installer_util::switches::kRegisterChromeBrowser)) {
- std::wstring chrome_exe(parsed_command_line.GetSwitchValue(
- installer_util::switches::kRegisterChromeBrowser));
- return ShellUtil::AddChromeToSetAccessDefaults(chrome_exe, true);
- // If --rename-chrome-exe is specified, we want to rename the executables
- // and exit.
- } else if (parsed_command_line.HasSwitch(
- installer_util::switches::kRenameChromeExe)) {
- return RenameChromeExecutables(system_install);
- }
+ int exit_code = 0;
+ if (HandleNonInstallCmdLineOptions(parsed_command_line, system_install,
+ exit_code))
+ return exit_code;
if (system_install && !IsUserAnAdmin()) {
if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA &&
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc
index 1203125..ef04da4 100644
--- a/chrome/installer/setup/uninstall.cc
+++ b/chrome/installer/setup/uninstall.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -6,8 +6,6 @@
#include "chrome/installer/setup/uninstall.h"
-#include <shlobj.h>
-
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/registry.h"
@@ -66,7 +64,7 @@ void CloseAllChromeProcesses() {
// We try to remove the standard desktop shortcut but if that fails we try
// to remove the alternate desktop shortcut. Only one of them should be
// present in a given install but at this point we don't know which one.
-void DeleteChromeShortcut(bool system_uninstall) {
+void DeleteChromeShortcuts(bool system_uninstall) {
FilePath shortcut_path;
if (system_uninstall) {
PathService::Get(base::DIR_COMMON_START_MENU, &shortcut_path);
@@ -226,6 +224,67 @@ installer_util::InstallStatus IsChromeActiveOrUserCancelled(
} // namespace
+bool installer_setup::DeleteChromeRegistrationKeys(HKEY root,
+ installer_util::InstallStatus& exit_code) {
+ RegKey key(root, L"", KEY_ALL_ACCESS);
+
+ // Delete Software\Classes\ChromeHTML,
+ std::wstring html_prog_id(ShellUtil::kRegClasses);
+ file_util::AppendToPath(&html_prog_id, ShellUtil::kChromeHTMLProgId);
+ DeleteRegistryKey(key, html_prog_id);
+
+ // Delete Software\Classes\ChromeExt,
+ std::wstring ext_prog_id(ShellUtil::kRegClasses);
+ file_util::AppendToPath(&ext_prog_id, ShellUtil::kChromeExtProgId);
+ DeleteRegistryKey(key, ext_prog_id);
+
+ // Delete Software\Classes\.crx,
+ std::wstring ext_association(ShellUtil::kRegClasses);
+ ext_association.append(L"\\.");
+ ext_association.append(chrome::kExtensionFileExtension);
+ DeleteRegistryKey(key, ext_association);
+
+ // Delete Software\Clients\StartMenuInternet\chrome.exe
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+ std::wstring set_access_key(ShellUtil::kRegStartMenuInternet);
+ file_util::AppendToPath(&set_access_key, dist->GetApplicationName());
+ DeleteRegistryKey(key, set_access_key);
+ // We have renamed the StartMenuInternet\chrome.exe to
+ // StartMenuInternet\Chromium so for old users we still need to delete
+ // the old key.
+ std::wstring old_set_access_key(ShellUtil::kRegStartMenuInternet);
+ file_util::AppendToPath(&old_set_access_key, installer_util::kChromeExe);
+ DeleteRegistryKey(key, old_set_access_key);
+
+ // Delete Software\RegisteredApplications\Chrome
+ DeleteRegistryValue(root, ShellUtil::kRegRegisteredApplications,
+ dist->GetApplicationName());
+
+ // Delete Software\Classes\Applications\chrome.exe
+ std::wstring app_key(ShellUtil::kRegClasses);
+ file_util::AppendToPath(&app_key, L"Applications");
+ file_util::AppendToPath(&app_key, installer_util::kChromeExe);
+ DeleteRegistryKey(key, app_key);
+
+ // Delete the App Paths key that lets explorer find Chrome.
+ std::wstring app_path_key(ShellUtil::kAppPathsRegistryKey);
+ file_util::AppendToPath(&app_path_key, installer_util::kChromeExe);
+ DeleteRegistryKey(key, app_path_key);
+
+ //Cleanup OpenWithList
+ for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) {
+ std::wstring open_with_key(ShellUtil::kRegClasses);
+ file_util::AppendToPath(&open_with_key, ShellUtil::kFileAssociations[i]);
+ file_util::AppendToPath(&open_with_key, L"OpenWithList");
+ file_util::AppendToPath(&open_with_key, installer_util::kChromeExe);
+ DeleteRegistryKey(key, open_with_key);
+ }
+
+ key.Close();
+ exit_code = installer_util::UNINSTALL_SUCCESSFUL;
+ return true;
+}
+
installer_util::InstallStatus installer_setup::UninstallChrome(
const std::wstring& exe_path, bool system_uninstall,
bool remove_all, bool force_uninstall,
@@ -255,13 +314,9 @@ installer_util::InstallStatus installer_setup::UninstallChrome(
// that we already tried to launch ourselves as admin.
params.append(L" --");
params.append(installer_util::switches::kRunAsAdmin);
- // Append --force-uninstall to keep it silent.
+ // Append --remove-chrome-registration to remove registry keys only.
params.append(L" --");
- params.append(installer_util::switches::kForceUninstall);
- if (status == installer_util::UNINSTALL_DELETE_PROFILE) {
- params.append(L" --");
- params.append(installer_util::switches::kDeleteProfile);
- }
+ params.append(installer_util::switches::kRemoveChromeRegistration);
DWORD exit_code = installer_util::UNKNOWN_STATUS;
InstallUtil::ExecuteExeAsAdmin(exe, params, &exit_code);
}
@@ -274,8 +329,9 @@ installer_util::InstallStatus installer_setup::UninstallChrome(
// Chrome is not in use so lets uninstall Chrome by deleting various files
// and registry entries. Here we will just make best effort and keep going
// in case of errors.
+
// First delete shortcuts from Start->Programs, Desktop & Quick Launch.
- DeleteChromeShortcut(system_uninstall);
+ DeleteChromeShortcuts(system_uninstall);
// Delete the registry keys (Uninstall key and Version key).
HKEY reg_root = system_uninstall ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
@@ -286,74 +342,24 @@ installer_util::InstallStatus installer_setup::UninstallChrome(
// dist->GetVersionKey().
std::wstring distribution_data(dist->GetDistributionData(&key));
+ // Remove Control Panel uninstall link and Omaha product key.
DeleteRegistryKey(key, dist->GetUninstallRegPath());
DeleteRegistryKey(key, dist->GetVersionKey());
- // Delete Software\Classes\ChromeHTML,
- // Delete Software\Classes\ChromeExt,
- // Delete Software\Classes\.crx,
- // Software\Clients\StartMenuInternet\chrome.exe and
- // Software\RegisteredApplications\Chrome
- std::wstring html_prog_id(ShellUtil::kRegClasses);
- file_util::AppendToPath(&html_prog_id, ShellUtil::kChromeHTMLProgId);
- DeleteRegistryKey(key, html_prog_id);
- std::wstring ext_prog_id(ShellUtil::kRegClasses);
- file_util::AppendToPath(&ext_prog_id, ShellUtil::kChromeExtProgId);
- DeleteRegistryKey(key, ext_prog_id);
- std::wstring ext_association(ShellUtil::kRegClasses);
- ext_association.append(L"\\.");
- ext_association.append(chrome::kExtensionFileExtension);
- DeleteRegistryKey(key, ext_association);
-
- std::wstring set_access_key(ShellUtil::kRegStartMenuInternet);
- file_util::AppendToPath(&set_access_key, dist->GetApplicationName());
- DeleteRegistryKey(key, set_access_key);
- // We have renamed the StartMenuInternet\chrome.exe to
- // StartMenuInternet\Chromium so for old users we still need to delete
- // the old key.
- std::wstring old_set_access_key(ShellUtil::kRegStartMenuInternet);
- file_util::AppendToPath(&old_set_access_key, installer_util::kChromeExe);
- DeleteRegistryKey(key, old_set_access_key);
-
- DeleteRegistryValue(reg_root, ShellUtil::kRegRegisteredApplications,
- dist->GetApplicationName());
+ // Remove all Chrome registration keys.
+ installer_util::InstallStatus ret = installer_util::UNKNOWN_STATUS;
+ DeleteChromeRegistrationKeys(reg_root, ret);
- // Cleanup Software\Classes\Applications\chrome.exe and OpenWithList
- RegKey hklm_key(HKEY_LOCAL_MACHINE, L"", KEY_ALL_ACCESS);
- std::wstring app_key(ShellUtil::kRegClasses);
- file_util::AppendToPath(&app_key, L"Applications");
- file_util::AppendToPath(&app_key, installer_util::kChromeExe);
- DeleteRegistryKey(key, app_key);
- if (remove_all)
- DeleteRegistryKey(hklm_key, app_key);
- for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) {
- std::wstring open_with_key(ShellUtil::kRegClasses);
- file_util::AppendToPath(&open_with_key, ShellUtil::kFileAssociations[i]);
- file_util::AppendToPath(&open_with_key, L"OpenWithList");
- file_util::AppendToPath(&open_with_key, installer_util::kChromeExe);
- DeleteRegistryKey(key, open_with_key);
- if (remove_all)
- DeleteRegistryKey(hklm_key, open_with_key);
- }
- key.Close();
+ // For user level install also we end up creating some keys in HKLM if user
+ // sets Chrome as default browser. So delete those as well (needs admin).
+ if (remove_all && !system_uninstall)
+ DeleteChromeRegistrationKeys(HKEY_LOCAL_MACHINE, ret);
// Delete shared registry keys as well (these require admin rights) if
// remove_all option is specified.
if (remove_all) {
- DeleteRegistryKey(hklm_key, set_access_key);
- DeleteRegistryKey(hklm_key, html_prog_id);
- DeleteRegistryKey(hklm_key, ext_prog_id);
- DeleteRegistryKey(hklm_key, ext_association);
- DeleteRegistryValue(HKEY_LOCAL_MACHINE,
- ShellUtil::kRegRegisteredApplications,
- dist->GetApplicationName());
-
- // Delete the App Paths key that lets explorer find Chrome.
- std::wstring app_path_key(ShellUtil::kAppPathsRegistryKey);
- file_util::AppendToPath(&app_path_key, installer_util::kChromeExe);
- DeleteRegistryKey(hklm_key, app_path_key);
-
// Delete media player registry key that exists only in HKLM.
+ RegKey hklm_key(HKEY_LOCAL_MACHINE, L"", KEY_ALL_ACCESS);
std::wstring reg_path(installer::kMediaPlayerRegPath);
file_util::AppendToPath(&reg_path, installer_util::kChromeExe);
DeleteRegistryKey(hklm_key, reg_path);
@@ -381,7 +387,7 @@ installer_util::InstallStatus installer_setup::UninstallChrome(
bool delete_profile = (status == installer_util::UNINSTALL_DELETE_PROFILE) ||
(cmd_line.HasSwitch(installer_util::switches::kDeleteProfile));
std::wstring local_state_path;
- installer_util::InstallStatus ret = installer_util::UNINSTALL_SUCCESSFUL;
+ ret = installer_util::UNINSTALL_SUCCESSFUL;
if (!DeleteFilesAndFolders(exe_path, system_uninstall, *installed_version,
&local_state_path, delete_profile))
ret = installer_util::UNINSTALL_FAILED;
diff --git a/chrome/installer/setup/uninstall.h b/chrome/installer/setup/uninstall.h
index b8478b7..2f44f80 100644
--- a/chrome/installer/setup/uninstall.h
+++ b/chrome/installer/setup/uninstall.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -9,11 +9,19 @@
#include <string>
+#include <shlobj.h>
+
#include "base/command_line.h"
#include "chrome/installer/util/util_constants.h"
#include "chrome/installer/util/version.h"
namespace installer_setup {
+// This function removes all Chrome registration related keys. It returns true
+// if successful, otherwise false. The error code is set in |exit_code|.
+// |root| is the registry root (HKLM|HKCU)
+bool DeleteChromeRegistrationKeys(HKEY root,
+ installer_util::InstallStatus& exit_code);
+
// This function uninstalls Chrome.
//
// exe_path: Path to the executable (setup.exe) as it will be copied
diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc
index 223ae2e..1a29688 100644
--- a/chrome/installer/util/util_constants.cc
+++ b/chrome/installer/util/util_constants.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -57,6 +57,9 @@ const wchar_t kRegisterChromeBrowser[] = L"register-chrome-browser";
// to support in-use updates. Also deletes opv key.
const wchar_t kRenameChromeExe[] = L"rename-chrome-exe";
+// Removes Chrome registration from current machine. Requires admin rights.
+const wchar_t kRemoveChromeRegistration[] = L"remove-chrome-registration";
+
// When we try to relaunch setup.exe as admin on Vista, we append this command
// line flag so that we try the launch only once.
const wchar_t kRunAsAdmin[] = L"run-as-admin";
diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h
index 2c1d674..625b253 100644
--- a/chrome/installer/util/util_constants.h
+++ b/chrome/installer/util/util_constants.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -80,6 +80,7 @@ extern const wchar_t kLogFile[];
extern const wchar_t kMakeChromeDefault[];
extern const wchar_t kRegisterChromeBrowser[];
extern const wchar_t kRenameChromeExe[];
+extern const wchar_t kRemoveChromeRegistration[];
extern const wchar_t kRunAsAdmin[];
extern const wchar_t kSystemLevel[];
extern const wchar_t kUninstall[];