diff options
author | kuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-30 20:46:38 +0000 |
---|---|---|
committer | kuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-30 20:46:38 +0000 |
commit | 93df28b5ee54e974e2f7de6ccddf18b8dca57e92 (patch) | |
tree | 94d6eec6b62a2bb9b915fdde49a63c7627c363c3 /chrome/installer | |
parent | 6b2ee92785ecfd9a28333190925ea9d6fb5709ea (diff) | |
download | chromium_src-93df28b5ee54e974e2f7de6ccddf18b8dca57e92.zip chromium_src-93df28b5ee54e974e2f7de6ccddf18b8dca57e92.tar.gz chromium_src-93df28b5ee54e974e2f7de6ccddf18b8dca57e92.tar.bz2 |
Fix the uninstall failures caused by elevated uninstaller.
BUG=7178
Review URL: http://codereview.chromium.org/99229
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14986 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer')
-rw-r--r-- | chrome/installer/setup/main.cc | 27 | ||||
-rw-r--r-- | chrome/installer/setup/uninstall.cc | 74 | ||||
-rw-r--r-- | chrome/installer/setup/uninstall.h | 9 | ||||
-rw-r--r-- | chrome/installer/util/util_constants.cc | 4 | ||||
-rw-r--r-- | chrome/installer/util/util_constants.h | 1 |
5 files changed, 71 insertions, 44 deletions
diff --git a/chrome/installer/setup/main.cc b/chrome/installer/setup/main.cc index 4731b2f..20fb65c 100644 --- a/chrome/installer/setup/main.cc +++ b/chrome/installer/setup/main.cc @@ -458,7 +458,8 @@ installer_util::InstallStatus UninstallChrome(const CommandLine& cmd_line, const installer::Version* version, bool system_install) { LOG(INFO) << "Uninstalling Chome"; - if (!version) { + bool force = cmd_line.HasSwitch(installer_util::switches::kForceUninstall); + if (!version && !force) { LOG(ERROR) << "No Chrome installation found for uninstall."; InstallUtil::WriteInstallerResult(system_install, installer_util::CHROME_NOT_INSTALLED, @@ -468,29 +469,9 @@ installer_util::InstallStatus UninstallChrome(const CommandLine& cmd_line, bool remove_all = !cmd_line.HasSwitch( installer_util::switches::kDoNotRemoveSharedItems); - bool force = cmd_line.HasSwitch(installer_util::switches::kForceUninstall); - - // Check if we need admin rights to cleanup HKLM. Try to elevate - if it works - // exit from this process, if not just continue uninstalling in the current - // process itself. - if (remove_all && - ShellUtil::AdminNeededForRegistryCleanup() && - !IsUserAnAdmin() && - (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) && - !cmd_line.HasSwitch(installer_util::switches::kRunAsAdmin)) { - std::wstring exe = cmd_line.program(); - std::wstring params(cmd_params); - // Append --run-as-admin flag to let the new instance of setup.exe know - // that we already tried to launch ourselves as admin. - params.append(L" --"); - params.append(installer_util::switches::kRunAsAdmin); - DWORD exit_code = installer_util::UNKNOWN_STATUS; - if (InstallUtil::ExecuteExeAsAdmin(exe, params, &exit_code)) - return static_cast<installer_util::InstallStatus>(exit_code); - } - return installer_setup::UninstallChrome(cmd_line.program(), system_install, - *version, remove_all, force); + remove_all, force, + cmd_line, cmd_params); } installer_util::InstallStatus ShowEULADialog(const std::wstring& inner_frame) { diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc index d0dc8de..765561a 100644 --- a/chrome/installer/setup/uninstall.cc +++ b/chrome/installer/setup/uninstall.cc @@ -6,10 +6,13 @@ #include "chrome/installer/setup/uninstall.h" +#include <shlobj.h> + #include "base/file_util.h" #include "base/path_service.h" #include "base/registry.h" #include "base/string_util.h" +#include "base/win_util.h" #include "chrome/common/result_codes.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths_internal.h" @@ -225,20 +228,49 @@ installer_util::InstallStatus IsChromeActiveOrUserCancelled( installer_util::InstallStatus installer_setup::UninstallChrome( const std::wstring& exe_path, bool system_uninstall, - const installer::Version& installed_version, - bool remove_all, bool force_uninstall) { + bool remove_all, bool force_uninstall, + const CommandLine& cmd_line, const wchar_t* cmd_params) { installer_util::InstallStatus status = installer_util::UNINSTALL_CONFIRMED; - if (!force_uninstall) { + if (force_uninstall) { + // Since --force-uninstall command line option is used, we are going to + // do silent uninstall. Try to close all running Chrome instances. + CloseAllChromeProcesses(); + } else { // no --force-uninstall so lets show some UI dialog boxes. status = IsChromeActiveOrUserCancelled(system_uninstall); if (status != installer_util::UNINSTALL_CONFIRMED && status != installer_util::UNINSTALL_DELETE_PROFILE) return status; - } else { - // Since --force-uninstall command line option is used, we are going to - // do silent uninstall. Try to close all running Chrome instances. - CloseAllChromeProcesses(); + + // 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. + // And continue uninstalling in the current process also to do HKCU cleanup. + if (remove_all && + ShellUtil::AdminNeededForRegistryCleanup() && + !::IsUserAnAdmin() && + (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) && + !cmd_line.HasSwitch(installer_util::switches::kRunAsAdmin)) { + std::wstring exe = cmd_line.program(); + std::wstring params(cmd_params); + // Append --run-as-admin flag to let the new instance of setup.exe know + // 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. + 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); + } + DWORD exit_code = installer_util::UNKNOWN_STATUS; + InstallUtil::ExecuteExeAsAdmin(exe, params, &exit_code); + } } + // Get the version of installed Chrome (if any) + scoped_ptr<installer::Version> + installed_version(InstallUtil::GetChromeVersion(system_uninstall)); + // 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. @@ -327,30 +359,36 @@ installer_util::InstallStatus installer_setup::UninstallChrome( DeleteRegistryKey(hklm_key, reg_path); hklm_key.Close(); - // Unregister any dll servers that we may have registered. - std::wstring dll_path(installer::GetChromeInstallPath(system_uninstall)); - file_util::AppendToPath(&dll_path, installed_version.GetString()); + if (installed_version.get()) { + // Unregister any dll servers that we may have registered. + std::wstring dll_path(installer::GetChromeInstallPath(system_uninstall)); + file_util::AppendToPath(&dll_path, installed_version->GetString()); - scoped_ptr<WorkItemList> dll_list(WorkItem::CreateWorkItemList()); - if (InstallUtil::BuildDLLRegistrationList(dll_path, kDllsToRegister, - kNumDllsToRegister, false, - dll_list.get())) { - dll_list->Do(); + scoped_ptr<WorkItemList> dll_list(WorkItem::CreateWorkItemList()); + if (InstallUtil::BuildDLLRegistrationList(dll_path, kDllsToRegister, + kNumDllsToRegister, false, + dll_list.get())) { + dll_list->Do(); + } } } + if (!installed_version.get()) + return installer_util::UNINSTALL_SUCCESSFUL; + // Finally delete all the files from Chrome folder after moving setup.exe // and the user's Local State to a temp location. - bool delete_profile = (status == installer_util::UNINSTALL_DELETE_PROFILE); + 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; - if (!DeleteFilesAndFolders(exe_path, system_uninstall, installed_version, + if (!DeleteFilesAndFolders(exe_path, system_uninstall, *installed_version, &local_state_path, delete_profile)) ret = installer_util::UNINSTALL_FAILED; if (!force_uninstall) { LOG(INFO) << "Uninstallation complete. Launching Uninstall survey."; - dist->DoPostUninstallOperations(installed_version, local_state_path, + dist->DoPostUninstallOperations(*installed_version, local_state_path, distribution_data); } diff --git a/chrome/installer/setup/uninstall.h b/chrome/installer/setup/uninstall.h index dc2241d..b8478b7 100644 --- a/chrome/installer/setup/uninstall.h +++ b/chrome/installer/setup/uninstall.h @@ -9,6 +9,7 @@ #include <string> +#include "base/command_line.h" #include "chrome/installer/util/util_constants.h" #include "chrome/installer/util/version.h" @@ -20,14 +21,16 @@ namespace installer_setup { // system_uninstall: if true, the function uninstalls Chrome installed system // wise. otherwise, it uninstalls Chrome installed for the // current user. -// installed_version: currently installed version of Chrome. // remove_all: Remove all shared files, registry entries as well. // force_uninstall: Uninstall without prompting for user confirmation or // any checks for Chrome running. +// cmd_line: CommandLine that contains information about the command that +// was used to launch current uninstaller. +// cmd_params: Command line parameters passed to the uninstaller. installer_util::InstallStatus UninstallChrome( const std::wstring& exe_path, bool system_uninstall, - const installer::Version& installed_version, - bool remove_all, bool force_uninstall); + bool remove_all, bool force_uninstall, + const CommandLine& cmd_line, const wchar_t* cmd_params); } // namespace installer_setup diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc index d667cbb..223ae2e 100644 --- a/chrome/installer/util/util_constants.cc +++ b/chrome/installer/util/util_constants.cc @@ -11,6 +11,10 @@ namespace switches { // Create Desktop and QuickLaunch shortcuts const wchar_t kCreateAllShortcuts[] = L"create-all-shortcuts"; +// Delete user profile also. This param is useful only when specified with +// kUninstall && kForceUninstall, otherwise it is silently ignored. +const wchar_t kDeleteProfile[] = L"delete-profile"; + // Disable logging const wchar_t kDisableLogging[] = L"disable-logging"; diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h index f2ca6dc..2c1d674 100644 --- a/chrome/installer/util/util_constants.h +++ b/chrome/installer/util/util_constants.h @@ -68,6 +68,7 @@ enum InstallOption { namespace switches { extern const wchar_t kCreateAllShortcuts[]; +extern const wchar_t kDeleteProfile[]; extern const wchar_t kDisableLogging[]; extern const wchar_t kDoNotLaunchChrome[]; extern const wchar_t kDoNotRemoveSharedItems[]; |