Index: chrome/installer/setup/uninstall.cc |
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc |
index d0dc8deef666d7e888ab5b468a20538f54ec435a..765561a15c7781102dab4b5f6eec2c19ae076d13 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); |
} |