diff options
Diffstat (limited to 'chrome/installer/launcher_support')
-rw-r--r-- | chrome/installer/launcher_support/chrome_launcher_support.cc | 106 | ||||
-rw-r--r-- | chrome/installer/launcher_support/chrome_launcher_support.h | 14 |
2 files changed, 73 insertions, 47 deletions
diff --git a/chrome/installer/launcher_support/chrome_launcher_support.cc b/chrome/installer/launcher_support/chrome_launcher_support.cc index c92f771..103c488 100644 --- a/chrome/installer/launcher_support/chrome_launcher_support.cc +++ b/chrome/installer/launcher_support/chrome_launcher_support.cc @@ -8,22 +8,29 @@ #include <tchar.h> #include "base/file_path.h" #include "base/file_util.h" +#include "base/logging.h" #ifndef OFFICIAL_BUILD #include "base/path_service.h" #endif #include "base/string16.h" #include "base/win/registry.h" +namespace chrome_launcher_support { + namespace { -// TODO(erikwright): These constants are duplicated all over the place. -// Consolidate them somehow. -const wchar_t kChromeRegClientStateKey[] = - L"Software\\Google\\Update\\ClientState\\" - L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; +// TODO(huangs) Refactor the constants: http://crbug.com/148538 +const wchar_t kGoogleRegClientStateKey[] = + L"Software\\Google\\Update\\ClientState\\"; -const wchar_t kUninstallStringField[] = L"UninstallString"; +// Copied from chrome_appid.cc. +const wchar_t kBinariesAppGuid[] = L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}"; +// Copied from google_chrome_distribution.cc. +const wchar_t kBrowserAppGuid[] = L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; + +// Copied from util_constants.cc. +const wchar_t kUninstallStringField[] = L"UninstallString"; const wchar_t kChromeExe[] = L"chrome.exe"; #ifndef OFFICIAL_BUILD @@ -38,9 +45,58 @@ FilePath GetDevelopmentChrome() { } #endif +// Reads the path to setup.exe from the value "UninstallString" within the +// specified product's "ClientState" registry key. Returns an empty FilePath if +// an error occurs or the product is not installed at the specified level. +FilePath GetSetupExeFromRegistry(InstallationLevel level, + const wchar_t* app_guid) { + HKEY root_key = (level == USER_LEVEL_INSTALLATION) ? + HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; + string16 subkey(kGoogleRegClientStateKey); + subkey.append(app_guid); + base::win::RegKey reg_key; + if (reg_key.Open(root_key, subkey.c_str(), + KEY_QUERY_VALUE) == ERROR_SUCCESS) { + string16 uninstall; + if (reg_key.ReadValue(kUninstallStringField, &uninstall) == ERROR_SUCCESS) { + FilePath setup_exe_path(uninstall); + if (file_util::PathExists(setup_exe_path)) + return setup_exe_path; + } + } + return FilePath(); +} + } // namespace -namespace chrome_launcher_support { +FilePath GetSetupExeForInstallationLevel(InstallationLevel level) { + // Look in the registry for Chrome Binaries first. + FilePath setup_exe_path(GetSetupExeFromRegistry(level, kBinariesAppGuid)); + // If the above fails, look in the registry for Chrome next. + if (setup_exe_path.empty()) + setup_exe_path = GetSetupExeFromRegistry(level, kBrowserAppGuid); + // If we fail again, then setup_exe_path would be empty. + return setup_exe_path; +} + +FilePath GetChromePathForInstallationLevel(InstallationLevel level) { + FilePath setup_exe_path(GetSetupExeForInstallationLevel(level)); + if (!setup_exe_path.empty()) { + // The uninstall path contains the path to setup.exe which is two levels + // down from chrome.exe. Move up two levels (plus one to drop the file + // name) and look for chrome.exe from there. + FilePath chrome_exe_path( + setup_exe_path.DirName().DirName().DirName().Append(kChromeExe)); + if (!file_util::PathExists(chrome_exe_path)) { + // By way of mild future proofing, look up one to see if there's a + // chrome.exe in the version directory + chrome_exe_path = chrome_exe_path.DirName().DirName().Append(kChromeExe); + } + if (file_util::PathExists(chrome_exe_path)) + return chrome_exe_path; + } + return FilePath(); +} FilePath GetAnyChromePath() { FilePath chrome_path; @@ -52,43 +108,7 @@ FilePath GetAnyChromePath() { chrome_path = GetChromePathForInstallationLevel(SYSTEM_LEVEL_INSTALLATION); if (chrome_path.empty()) chrome_path = GetChromePathForInstallationLevel(USER_LEVEL_INSTALLATION); - return chrome_path; } -FilePath GetChromePathForInstallationLevel(InstallationLevel level) { - using base::win::RegKey; - HKEY root_key = (level == USER_LEVEL_INSTALLATION ? - HKEY_CURRENT_USER : - HKEY_LOCAL_MACHINE); - RegKey reg_key(root_key, kChromeRegClientStateKey, KEY_QUERY_VALUE); - - FilePath chrome_exe_path; - - if (reg_key.Valid()) { - // Now grab the uninstall string from the appropriate ClientState key - // and use that as the base for a path to chrome.exe. - string16 uninstall; - if (reg_key.ReadValue(kUninstallStringField, &uninstall) == ERROR_SUCCESS) { - // The uninstall path contains the path to setup.exe which is two levels - // down from chrome.exe. Move up two levels (plus one to drop the file - // name) and look for chrome.exe from there. - FilePath uninstall_path(uninstall); - chrome_exe_path = - uninstall_path.DirName().DirName().DirName().Append(kChromeExe); - if (!file_util::PathExists(chrome_exe_path)) { - // By way of mild future proofing, look up one to see if there's a - // chrome.exe in the version directory - chrome_exe_path = - uninstall_path.DirName().DirName().Append(kChromeExe); - } - } - } - - if (file_util::PathExists(chrome_exe_path)) - return chrome_exe_path; - - return FilePath(); -} - } // namespace chrome_launcher_support diff --git a/chrome/installer/launcher_support/chrome_launcher_support.h b/chrome/installer/launcher_support/chrome_launcher_support.h index a67e533..1051a24 100644 --- a/chrome/installer/launcher_support/chrome_launcher_support.h +++ b/chrome/installer/launcher_support/chrome_launcher_support.h @@ -14,6 +14,16 @@ enum InstallationLevel { SYSTEM_LEVEL_INSTALLATION }; +// Returns the path to an existing setup.exe at the specified level, if it can +// be found via Omaha client state. +FilePath GetSetupExeForInstallationLevel(InstallationLevel level); + +// Returns the path to an installed chrome.exe at the specified level, if it can +// be found via Omaha client state. Prefers the installer from a multi-install, +// but may also return that of a single-install of Chrome if no multi-install +// exists. +FilePath GetChromePathForInstallationLevel(InstallationLevel level); + // Returns the path to an installed chrome.exe, or an empty path. Prefers a // system-level installation to a user-level installation. Uses Omaha client // state to identify a Chrome installation location. @@ -22,10 +32,6 @@ enum InstallationLevel { // The file path returned (if any) is guaranteed to exist. FilePath GetAnyChromePath(); -// Returns the path to an installed chrome.exe at the specified level, if it can -// be found via Omaha client state. -FilePath GetChromePathForInstallationLevel(InstallationLevel level); - } // namespace chrome_launcher_support #endif // CHROME_INSTALLER_LAUNCHER_SUPPORT_CHROME_LAUNCHER_SUPPORT_H_ |