diff options
author | kuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-15 21:37:46 +0000 |
---|---|---|
committer | kuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-15 21:37:46 +0000 |
commit | 68c921f8b5d6454307645d4017a3cbf2646904bc (patch) | |
tree | fdd0d0138a4ce706e052de4bab66fa3c4b28b8d4 /chrome | |
parent | 9c6c3065723227dee6bca91df24bb6863ac123f9 (diff) | |
download | chromium_src-68c921f8b5d6454307645d4017a3cbf2646904bc.zip chromium_src-68c921f8b5d6454307645d4017a3cbf2646904bc.tar.gz chromium_src-68c921f8b5d6454307645d4017a3cbf2646904bc.tar.bz2 |
Add a check in Chrome to not run user level mode if machine level Chrome
is already installed.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3423 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/app/chromium_strings.grd | 3 | ||||
-rw-r--r-- | chrome/app/google_chrome_strings.grd | 3 | ||||
-rw-r--r-- | chrome/app/result_codes.h | 1 | ||||
-rw-r--r-- | chrome/browser/browser_main.cc | 46 | ||||
-rw-r--r-- | chrome/browser/google_update.cc | 18 | ||||
-rw-r--r-- | chrome/installer/setup/install.cc | 2 | ||||
-rw-r--r-- | chrome/installer/setup/main.cc | 14 | ||||
-rw-r--r-- | chrome/installer/setup/setup.cc | 2 | ||||
-rw-r--r-- | chrome/installer/setup/uninstall.cc | 23 | ||||
-rw-r--r-- | chrome/installer/setup/uninstall.h | 5 | ||||
-rw-r--r-- | chrome/installer/util/install_util.cc | 9 | ||||
-rw-r--r-- | chrome/installer/util/install_util.h | 7 | ||||
-rw-r--r-- | chrome/installer/util/util_constants.cc | 6 | ||||
-rw-r--r-- | chrome/installer/util/util_constants.h | 3 |
14 files changed, 115 insertions, 27 deletions
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index c0f7818..f948d6b 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd @@ -211,6 +211,9 @@ be available for now. --> <message name="IDS_CANT_WRITE_USER_DIRECTORY_EXIT_BUTTON" desc="Text on button of dialog that closes Chrome if we can't create a directory for this user."> Exit Chromium </message> + <message name="IDS_MACHINE_LEVEL_INSTALL_CONFLICT" desc="Error message to display when user tries to run user level Chromium even though machine level Chromium is already installed."> + System level Chromium is already installed on this computer. We will replace your user level Chromium with the system level installation. + </message> </messages> </release> </grit> diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index 95035dd..70d27f2 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd @@ -250,6 +250,9 @@ Chrome supports. --> <message name="IDS_CANT_WRITE_USER_DIRECTORY_EXIT_BUTTON" desc="Text on button of dialog that closes Chrome if we can't create a directory for this user."> Exit Chrome </message> + <message name="IDS_MACHINE_LEVEL_INSTALL_CONFLICT" desc="Error message to display when user tries to run user level Chromium even though machine level Chromium is already installed."> + System level Google Chrome is already installed on this computer. We will replace your user level Google Chrome with the system level installation. + </message> </messages> </release> </grit> diff --git a/chrome/app/result_codes.h b/chrome/app/result_codes.h index d0e6a9b..e03a8bc 100644 --- a/chrome/app/result_codes.h +++ b/chrome/app/result_codes.h @@ -27,6 +27,7 @@ class ResultCodes { MISSING_PATH, // An critical chrome path is missing. MISSING_DATA, // A critical chrome file is missing. SHELL_INTEGRATION_FAILED, // Failed to make Chrome default browser. + MACHINE_LEVEL_INSTALL_EXISTS, // Machine level install exists UNINSTALL_DELETE_FILE_ERROR,// Error while deleting shortcuts. UNINSTALL_CHROME_ALIVE, // Uninstall detected another chrome instance. UNINSTALL_NO_SURVEY, // Do not launch survey after uninstall. diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index 758d261..049a402 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -49,6 +49,9 @@ #include "chrome/common/pref_service.h" #include "chrome/common/win_util.h" #include "chrome/installer/util/google_update_settings.h" +#include "chrome/installer/util/helper.h" +#include "chrome/installer/util/install_util.h" +#include "chrome/installer/util/version.h" #include "chrome/views/accelerator_handler.h" #include "net/base/net_module.h" #include "net/base/net_resources.h" @@ -221,6 +224,39 @@ bool CreateUniqueChromeEvent() { return already_running; } +// Check if there is any machine level Chrome installed on the current +// machine. If yes and the current Chrome process is user level, we do not +// allow the user level Chrome to run. So we notify the user and uninstall +// user level Chrome. +bool CheckMachineLevelInstall() { + scoped_ptr<installer::Version> version(InstallUtil::GetChromeVersion(true)); + if (version.get()) { + std::wstring exe; + PathService::Get(base::DIR_EXE, &exe); + std::transform(exe.begin(), exe.end(), exe.begin(), tolower); + std::wstring user_exe_path = installer::GetChromeInstallPath(false); + std::transform(user_exe_path.begin(), user_exe_path.end(), + user_exe_path.begin(), tolower); + if (exe == user_exe_path) { + const std::wstring text = + l10n_util::GetString(IDS_MACHINE_LEVEL_INSTALL_CONFLICT); + const std::wstring caption = l10n_util::GetString(IDS_PRODUCT_NAME); + const UINT flags = MB_OK | MB_ICONERROR | MB_TOPMOST; + win_util::MessageBox(NULL, text, caption, flags); + std::wstring uninstall_cmd = InstallUtil::GetChromeUninstallCmd(false); + if (!uninstall_cmd.empty()) { + uninstall_cmd.append(L" --"); + uninstall_cmd.append(installer_util::switches::kForceUninstall); + uninstall_cmd.append(L" --"); + uninstall_cmd.append(installer_util::switches::kDoNotRemoveSharedItems); + process_util::LaunchApp(uninstall_cmd, false, false, NULL); + } + return true; + } + } + return false; +} + // We record in UMA the conditions that can prevent breakpad from generating // and sending crash reports. Namely that the crash reporting registration // failed and that the process is being debugged. @@ -400,6 +436,16 @@ int BrowserMain(CommandLine &parsed_command_line, int show_command, return ResultCodes::NORMAL_EXIT; } + // Check if there is any machine level Chrome installed on the current + // machine. If yes and the current Chrome process is user level, we do not + // allow the user level Chrome to run. So we notify the user and uninstall + // user level Chrome. + // Note this check should only happen here, after all the checks above + // (uninstall, resource bundle initialization, other chrome browser + // processes etc). + if (CheckMachineLevelInstall()) + return ResultCodes::MACHINE_LEVEL_INSTALL_EXISTS; + message_window.Create(); // Show the First Run UI if this is the first time Chrome has been run on diff --git a/chrome/browser/google_update.cc b/chrome/browser/google_update.cc index da56359..71e22e5 100644 --- a/chrome/browser/google_update.cc +++ b/chrome/browser/google_update.cc @@ -12,8 +12,8 @@ #include "base/task.h" #include "base/thread.h" #include "chrome/browser/browser_process.h" -#include "chrome/installer/util/helper.h" #include "chrome/installer/util/google_update_constants.h" +#include "chrome/installer/util/helper.h" #include "google_update_idl_i.c" namespace { @@ -23,16 +23,20 @@ namespace { bool CanUpdateCurrentChrome() { std::wstring current_exe_path; if (PathService::Get(base::DIR_EXE, ¤t_exe_path)) { - std::wstring standard_exe_path = installer::GetChromeInstallPath(false); + std::wstring user_exe_path = installer::GetChromeInstallPath(false); + std::wstring machine_exe_path = installer::GetChromeInstallPath(true); std::transform(current_exe_path.begin(), current_exe_path.end(), current_exe_path.begin(), tolower); - std::transform(standard_exe_path.begin(), standard_exe_path.end(), - standard_exe_path.begin(), tolower); - if (current_exe_path != standard_exe_path) { + std::transform(user_exe_path.begin(), user_exe_path.end(), + user_exe_path.begin(), tolower); + std::transform(machine_exe_path.begin(), machine_exe_path.end(), + machine_exe_path.begin(), tolower); + if (current_exe_path != user_exe_path && + current_exe_path != machine_exe_path ) { LOG(ERROR) << L"Google Update cannot update Chrome installed in a " << L"non-standard location: " << current_exe_path.c_str() - << L". The standard location is: " << standard_exe_path.c_str() - << L"."; + << L". The standard location is: " << user_exe_path.c_str() + << L" or " << machine_exe_path.c_str() << L"."; return false; } } diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc index 5d65dbf..7a0a2dd 100644 --- a/chrome/installer/setup/install.cc +++ b/chrome/installer/setup/install.cc @@ -52,7 +52,7 @@ void AddUninstallShortcutWorkItems(HKEY reg_root, uninstall_cmd.append(installer_util::switches::kUninstall); if (reg_root == HKEY_LOCAL_MACHINE) { uninstall_cmd.append(L" --"); - uninstall_cmd.append(installer_util::switches::kSystemInstall); + uninstall_cmd.append(installer_util::switches::kSystemLevel); } // Create DisplayName, UninstallString and InstallLocation keys diff --git a/chrome/installer/setup/main.cc b/chrome/installer/setup/main.cc index d9b4bc6..cf08d34 100644 --- a/chrome/installer/setup/main.cc +++ b/chrome/installer/setup/main.cc @@ -253,17 +253,17 @@ installer_util::InstallStatus InstallChrome(const CommandLine& cmd_line, installer_util::InstallStatus UninstallChrome(const CommandLine& cmd_line, const installer::Version* version, bool system_install) { - bool remove_all = true; - if (cmd_line.HasSwitch(installer_util::switches::kDoNotRemoveSharedItems)) - remove_all = false; LOG(INFO) << "Uninstalling Chome"; if (!version) { LOG(ERROR) << "No Chrome installation found for uninstall."; return installer_util::CHROME_NOT_INSTALLED; - } else { - return installer_setup::UninstallChrome(cmd_line.program(), system_install, - *version, remove_all); } + + bool remove_all = !cmd_line.HasSwitch( + installer_util::switches::kDoNotRemoveSharedItems); + bool force = cmd_line.HasSwitch(installer_util::switches::kForceUninstall); + return installer_setup::UninstallChrome(cmd_line.program(), system_install, + *version, remove_all, force); } } // namespace @@ -290,7 +290,7 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, } bool system_install = - parsed_command_line.HasSwitch(installer_util::switches::kSystemInstall); + parsed_command_line.HasSwitch(installer_util::switches::kSystemLevel); LOG(INFO) << "system install is " << system_install; // Check to avoid simultaneous per-user and per-machine installs. diff --git a/chrome/installer/setup/setup.cc b/chrome/installer/setup/setup.cc index e3edf19..0f5b629 100644 --- a/chrome/installer/setup/setup.cc +++ b/chrome/installer/setup/setup.cc @@ -132,7 +132,7 @@ bool CreateOrUpdateChromeShortcuts(const std::wstring& exe_path, arguments.append(installer_util::switches::kUninstall); if (system_install) { arguments.append(L" --"); - arguments.append(installer_util::switches::kSystemInstall); + arguments.append(installer_util::switches::kSystemLevel); } LOG(INFO) << "Creating/updating uninstall link at " << uninstall_link; diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc index 4988e54..dfaafb0 100644 --- a/chrome/installer/setup/uninstall.cc +++ b/chrome/installer/setup/uninstall.cc @@ -81,8 +81,14 @@ bool DeleteFilesAndFolders(const std::wstring& exe_path, bool system_uninstall, file_util::Move(setup_exe, temp_file); LOG(INFO) << "Deleting install path " << install_path; - if (!file_util::Delete(install_path, true)) - LOG(ERROR) << "Failed to delete folder: " << install_path; + if (!file_util::Delete(install_path, true)) { + LOG(ERROR) << "Failed to delete folder (1st try): " << install_path; + // This is to let any closing chrome.exe die before trying delete one + // more time. + Sleep(10000); + if (!file_util::Delete(install_path, true)) + LOG(ERROR) << "Failed to delete folder (2nd try): " << install_path; + } // Now check and delete if the parent directories are empty // For example Google\Chrome or Chromium @@ -163,11 +169,14 @@ 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) { - installer_util::InstallStatus status = - IsChromeActiveOrUserCancelled(system_uninstall); - if (status != installer_util::UNINSTALL_CONFIRMED) - return status; + const installer::Version& installed_version, + bool remove_all, bool force_uninstall) { + if (!force_uninstall) { + installer_util::InstallStatus status = + IsChromeActiveOrUserCancelled(system_uninstall); + if (status != installer_util::UNINSTALL_CONFIRMED) + return status; + } #if defined(GOOGLE_CHROME_BUILD) // TODO(rahulk): This should be done by DoPreUninstallOperations call above diff --git a/chrome/installer/setup/uninstall.h b/chrome/installer/setup/uninstall.h index eda077e..9004636 100644 --- a/chrome/installer/setup/uninstall.h +++ b/chrome/installer/setup/uninstall.h @@ -22,9 +22,12 @@ namespace installer_setup { // 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. installer_util::InstallStatus UninstallChrome( const std::wstring& exe_path, bool system_uninstall, - const installer::Version& installed_version, bool remove_all); + const installer::Version& installed_version, + bool remove_all, bool force_uninstall); } // namespace installer_setup diff --git a/chrome/installer/util/install_util.cc b/chrome/installer/util/install_util.cc index 290a60a..032e5e8 100644 --- a/chrome/installer/util/install_util.cc +++ b/chrome/installer/util/install_util.cc @@ -17,6 +17,15 @@ #include "chrome/installer/util/google_update_constants.h" +std::wstring InstallUtil::GetChromeUninstallCmd(bool system_install) { + HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; + BrowserDistribution* dist = BrowserDistribution::GetDistribution(); + RegKey key(root, dist->GetUninstallRegPath().c_str()); + std::wstring uninstall_cmd; + key.ReadValue(installer_util::kUninstallStringField, &uninstall_cmd); + return uninstall_cmd; +} + installer::Version* InstallUtil::GetChromeVersion(bool system_install) { RegKey key; std::wstring version_str; diff --git a/chrome/installer/util/install_util.h b/chrome/installer/util/install_util.h index 6e6d6da..b8ca5c3 100644 --- a/chrome/installer/util/install_util.h +++ b/chrome/installer/util/install_util.h @@ -20,12 +20,17 @@ // independently. class InstallUtil { public: + // Reads the uninstall command for Chromium from registry and returns it. + // If system_install is true the command is read from HKLM, otherwise + // from HKCU. + static std::wstring GetChromeUninstallCmd(bool system_install); + // Find the version of Chrome installed on the system by checking the // Google Update registry key. Returns the version or NULL if no version is // found. // system_install: if true, looks for version number under the HKLM root, // otherwise looks under the HKCU. - static installer::Version * GetChromeVersion(bool system_install); + static installer::Version* GetChromeVersion(bool system_install); // This function checks if the current OS is supported for Chromium. static bool IsOSSupported(); diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc index b3ac19f..19934f69 100644 --- a/chrome/installer/util/util_constants.cc +++ b/chrome/installer/util/util_constants.cc @@ -31,11 +31,15 @@ const wchar_t kRegisterChromeBrowser[] = L"register-chrome-browser"; const wchar_t kDoNotRemoveSharedItems[] = L"do-not-remove-shared-items"; // Install Chrome to system wise location. The default is per user install. -const wchar_t kSystemInstall[] = L"system-install"; +const wchar_t kSystemLevel[] = L"system-level"; // If present, setup will uninstall chrome. const wchar_t kUninstall[] = L"uninstall"; +// If present, setup will uninstall chrome without asking for any +// confirmation from user. +const wchar_t kForceUninstall[] = L"force-uninstall"; + // Enable verbose logging (info level). const wchar_t kVerboseLogging[] = L"verbose-logging"; diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h index e115787..5994ef0 100644 --- a/chrome/installer/util/util_constants.h +++ b/chrome/installer/util/util_constants.h @@ -40,8 +40,9 @@ extern const wchar_t kInstallArchive[]; extern const wchar_t kLogFile[]; extern const wchar_t kRegisterChromeBrowser[]; extern const wchar_t kDoNotRemoveSharedItems[]; -extern const wchar_t kSystemInstall[]; +extern const wchar_t kSystemLevel[]; extern const wchar_t kUninstall[]; +extern const wchar_t kForceUninstall[]; extern const wchar_t kVerboseLogging[]; } // namespace switches |