summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/installer/setup/setup_main.cc10
-rw-r--r--chrome/installer/setup/uninstall.cc98
-rw-r--r--chrome/installer/setup/uninstall.h2
-rw-r--r--chrome/installer/util/browser_distribution.h3
-rw-r--r--chrome/installer/util/chrome_frame_distribution.cc4
-rw-r--r--chrome/installer/util/chrome_frame_distribution.h2
-rw-r--r--chrome/installer/util/chromium_binaries_distribution.cc24
-rw-r--r--chrome/installer/util/google_chrome_distribution.cc7
-rw-r--r--chrome/installer/util/google_chrome_sxs_distribution.cc4
-rw-r--r--chrome/installer/util/google_chrome_sxs_distribution.h15
-rw-r--r--chrome/installer/util/install_util.cc16
-rw-r--r--chrome/installer/util/install_util.h33
-rw-r--r--chrome/installer/util/install_util_unittest.cc55
-rw-r--r--chrome/installer/util/shell_util.cc153
14 files changed, 260 insertions, 166 deletions
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc
index 702893f..be33736 100644
--- a/chrome/installer/setup/setup_main.cc
+++ b/chrome/installer/setup/setup_main.cc
@@ -717,10 +717,10 @@ installer::InstallStatus InstallProductsHelper(
}
} else if ((install_status == installer::NEW_VERSION_UPDATED) ||
(install_status == installer::IN_USE_UPDATED)) {
- for (size_t i = 0; i < products.size(); ++i) {
- installer::RemoveLegacyRegistryKeys(
- products[i]->distribution());
- }
+ const Product* chrome = installer_state.FindProduct(
+ BrowserDistribution::CHROME_BROWSER);
+ if (chrome != NULL)
+ installer::RemoveChromeLegacyRegistryKeys(chrome->distribution());
}
}
}
@@ -1323,7 +1323,7 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance,
::MessageBoxW(NULL,
installer::GetLocalizedString(
IDS_UNINSTALL_COMPLETE_BASE).c_str(),
- cf_install->distribution()->GetApplicationName().c_str(),
+ cf_install->distribution()->GetAppShortCutName().c_str(),
MB_OK);
}
}
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc
index 883c208..b25b03c 100644
--- a/chrome/installer/setup/uninstall.cc
+++ b/chrome/installer/setup/uninstall.cc
@@ -217,26 +217,29 @@ void CloseChromeFrameHelperProcess() {
}
// This method tries to figure out if current user has registered Chrome.
-// It returns true iff:
-// - Software\Clients\StartMenuInternet\Chromium\"" key has a valid value.
-// - The value is same as chrome.exe path for the current installation.
-bool CurrentUserHasDefaultBrowser(const InstallerState& installer_state,
- const Product& product) {
- std::wstring reg_key(ShellUtil::kRegStartMenuInternet);
- reg_key.append(1, L'\\')
- .append(product.distribution()->GetApplicationName())
- .append(ShellUtil::kRegShellOpen);
- RegKey key(HKEY_LOCAL_MACHINE, reg_key.c_str(), KEY_READ);
+// It returns true iff there is a registered browser that will launch the
+// same chrome.exe as the current installation.
+bool CurrentUserHasDefaultBrowser(const InstallerState& installer_state) {
+ using base::win::RegistryKeyIterator;
+ const HKEY root = HKEY_LOCAL_MACHINE;
+ ProgramCompare open_command_pred(
+ installer_state.target_path().Append(kChromeExe));
+ std::wstring client_open_path;
+ RegKey client_open_key;
std::wstring reg_exe;
- if (key.ReadValue(L"", &reg_exe) == ERROR_SUCCESS && reg_exe.length() > 2) {
- FilePath chrome_exe(installer_state.target_path()
- .Append(installer::kChromeExe));
- // The path in the registry will always have quotes.
- reg_exe = reg_exe.substr(1, reg_exe.length() - 2);
- if (FilePath::CompareEqualIgnoreCase(reg_exe, chrome_exe.value()))
+ for (RegistryKeyIterator iter(root, ShellUtil::kRegStartMenuInternet);
+ iter.Valid(); ++iter) {
+ client_open_path.assign(ShellUtil::kRegStartMenuInternet)
+ .append(1, L'\\')
+ .append(iter.Name())
+ .append(ShellUtil::kRegShellOpen);
+ if (client_open_key.Open(root, client_open_path.c_str(),
+ KEY_QUERY_VALUE) == ERROR_SUCCESS &&
+ client_open_key.ReadValue(L"", &reg_exe) == ERROR_SUCCESS &&
+ open_command_pred.Evaluate(reg_exe)) {
return true;
+ }
}
-
return false;
}
@@ -526,24 +529,47 @@ bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root,
return true;
}
+ FilePath chrome_exe(target_path.Append(kChromeExe));
+
// Delete Software\Classes\ChromeHTML,
std::wstring html_prog_id(ShellUtil::kRegClasses);
file_util::AppendToPath(&html_prog_id, ShellUtil::kChromeHTMLProgId);
html_prog_id.append(browser_entry_suffix);
InstallUtil::DeleteRegistryKey(root, html_prog_id);
- // Delete Software\Clients\StartMenuInternet\Chromium
- std::wstring set_access_key(ShellUtil::kRegStartMenuInternet);
- file_util::AppendToPath(&set_access_key, dist->GetApplicationName());
- set_access_key.append(browser_entry_suffix);
- InstallUtil::DeleteRegistryKey(root, 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::kChromeExe);
- InstallUtil::DeleteRegistryKey(root, old_set_access_key);
+ // Delete all Start Menu Internet registrations that refer to this Chrome.
+ {
+ using base::win::RegistryKeyIterator;
+ ProgramCompare open_command_pred(chrome_exe);
+ std::wstring client_name;
+ std::wstring client_key;
+ std::wstring open_key;
+ for (RegistryKeyIterator iter(root, ShellUtil::kRegStartMenuInternet);
+ iter.Valid(); ++iter) {
+ client_name.assign(iter.Name());
+ client_key.assign(ShellUtil::kRegStartMenuInternet)
+ .append(1, L'\\')
+ .append(client_name);
+ open_key.assign(client_key).append(ShellUtil::kRegShellOpen);
+ if (InstallUtil::DeleteRegistryKeyIf(root, client_key, open_key, L"",
+ open_command_pred) != InstallUtil::NOT_FOUND) {
+ // Delete the default value of SOFTWARE\Clients\StartMenuInternet if it
+ // references this Chrome (i.e., if it was made the default browser).
+ InstallUtil::DeleteRegistryValueIf(
+ root, ShellUtil::kRegStartMenuInternet, L"",
+ InstallUtil::ValueEquals(client_name));
+ // Also delete the value for the default user if we're operating in
+ // HKLM.
+ if (root == HKEY_LOCAL_MACHINE) {
+ InstallUtil::DeleteRegistryValueIf(
+ HKEY_USERS,
+ std::wstring(L".DEFAULT\\").append(
+ ShellUtil::kRegStartMenuInternet).c_str(),
+ L"", InstallUtil::ValueEquals(client_name));
+ }
+ }
+ }
+ }
// Delete Software\RegisteredApplications\Chromium
InstallUtil::DeleteRegistryValue(root, ShellUtil::kRegRegisteredApplications,
@@ -573,14 +599,16 @@ bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root,
// Cleanup in case Chrome had been made the default browser.
// Delete the default value of SOFTWARE\Clients\StartMenuInternet if it
- // references this Chrome.
+ // references this Chrome. Do this explicitly here for the case where HKCU is
+ // being processed; the iteration above will have no hits since registration
+ // lives in HKLM.
InstallUtil::DeleteRegistryValueIf(
root, ShellUtil::kRegStartMenuInternet, L"",
InstallUtil::ValueEquals(dist->GetApplicationName() +
browser_entry_suffix));
// Delete each protocol association if it references this Chrome.
- ProgramCompare open_command_pred(target_path.Append(kChromeExe));
+ ProgramCompare open_command_pred(chrome_exe);
std::wstring parent_key(ShellUtil::kRegClasses);
const std::wstring::size_type base_length = parent_key.size();
std::wstring child_key;
@@ -610,7 +638,7 @@ bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root,
return true;
}
-void RemoveLegacyRegistryKeys(BrowserDistribution* dist) {
+void RemoveChromeLegacyRegistryKeys(BrowserDistribution* dist) {
// We used to register Chrome to handle crx files, but this turned out
// to be not worth the hassle. Remove these old registry entries if
// they exist. See: http://codereview.chromium.org/210007
@@ -690,8 +718,7 @@ InstallStatus UninstallProduct(const InstallationState& original_state,
// 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 &&
- (!suffix.empty() ||
- CurrentUserHasDefaultBrowser(installer_state, product)) &&
+ (!suffix.empty() || CurrentUserHasDefaultBrowser(installer_state)) &&
!::IsUserAnAdmin() &&
base::win::GetVersion() >= base::win::VERSION_VISTA &&
!cmd_line.HasSwitch(installer::switches::kRunAsAdmin)) {
@@ -747,8 +774,7 @@ InstallStatus UninstallProduct(const InstallationState& original_state,
// Registration data is put in HKLM for system level and possibly user level
// installs (when Chrome is made the default browser at install-time).
if (installer_state.system_install() || remove_all &&
- (!suffix.empty() || CurrentUserHasDefaultBrowser(installer_state,
- product))) {
+ (!suffix.empty() || CurrentUserHasDefaultBrowser(installer_state))) {
DeleteChromeRegistrationKeys(product.distribution(), HKEY_LOCAL_MACHINE,
suffix, installer_state.target_path(), &ret);
}
diff --git a/chrome/installer/setup/uninstall.h b/chrome/installer/setup/uninstall.h
index 49fd352..ef5c4ef 100644
--- a/chrome/installer/setup/uninstall.h
+++ b/chrome/installer/setup/uninstall.h
@@ -37,7 +37,7 @@ bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root,
// Removes any legacy registry keys from earlier versions of Chrome that are no
// longer needed. This is used during autoupdate since we don't do full
// uninstalls/reinstalls to update.
-void RemoveLegacyRegistryKeys(BrowserDistribution* dist);
+void RemoveChromeLegacyRegistryKeys(BrowserDistribution* dist);
// This function uninstalls a product. Hence we came up with this awesome
// name for it.
diff --git a/chrome/installer/util/browser_distribution.h b/chrome/installer/util/browser_distribution.h
index 6d92501..58ab51c 100644
--- a/chrome/installer/util/browser_distribution.h
+++ b/chrome/installer/util/browser_distribution.h
@@ -70,8 +70,11 @@ class BrowserDistribution {
virtual std::wstring GetAppGuid();
+ // Returns the name by which the program is registered with Default Programs.
+ // This is not a localized string suitable for presenting to a user.
virtual std::wstring GetApplicationName();
+ // Returns the localized name of the program.
virtual std::wstring GetAppShortCutName();
virtual std::wstring GetAlternateApplicationName();
diff --git a/chrome/installer/util/chrome_frame_distribution.cc b/chrome/installer/util/chrome_frame_distribution.cc
index 7305fdc..f4fa099 100644
--- a/chrome/installer/util/chrome_frame_distribution.cc
+++ b/chrome/installer/util/chrome_frame_distribution.cc
@@ -34,6 +34,10 @@ std::wstring ChromeFrameDistribution::GetAppGuid() {
}
std::wstring ChromeFrameDistribution::GetApplicationName() {
+ return L"Google Chrome Frame";
+}
+
+std::wstring ChromeFrameDistribution::GetAppShortCutName() {
const std::wstring& product_name =
installer::GetLocalizedString(IDS_PRODUCT_FRAME_NAME_BASE);
return product_name;
diff --git a/chrome/installer/util/chrome_frame_distribution.h b/chrome/installer/util/chrome_frame_distribution.h
index f8078d4..e5124a8 100644
--- a/chrome/installer/util/chrome_frame_distribution.h
+++ b/chrome/installer/util/chrome_frame_distribution.h
@@ -25,6 +25,8 @@ class ChromeFrameDistribution : public BrowserDistribution {
virtual std::wstring GetApplicationName() OVERRIDE;
+ virtual std::wstring GetAppShortCutName() OVERRIDE;
+
virtual std::wstring GetAlternateApplicationName() OVERRIDE;
virtual std::wstring GetInstallSubDir() OVERRIDE;
diff --git a/chrome/installer/util/chromium_binaries_distribution.cc b/chrome/installer/util/chromium_binaries_distribution.cc
index 8e39ffb..de57e0d 100644
--- a/chrome/installer/util/chromium_binaries_distribution.cc
+++ b/chrome/installer/util/chromium_binaries_distribution.cc
@@ -25,7 +25,7 @@ std::wstring ChromiumBinariesDistribution::GetAppGuid() {
}
std::wstring ChromiumBinariesDistribution::GetApplicationName() {
- NOTREACHED() << "GetApplicationName unsupported";
+ NOTREACHED();
return std::wstring();
}
@@ -34,12 +34,12 @@ std::wstring ChromiumBinariesDistribution::GetAppShortCutName() {
}
std::wstring ChromiumBinariesDistribution::GetAlternateApplicationName() {
- NOTREACHED() << "GetApplicationName unsupported";
+ NOTREACHED();
return std::wstring();
}
std::wstring ChromiumBinariesDistribution::GetBrowserAppId() {
- NOTREACHED() << "GetApplicationName unsupported";
+ NOTREACHED();
return std::wstring();
}
@@ -48,22 +48,22 @@ std::wstring ChromiumBinariesDistribution::GetInstallSubDir() {
}
std::wstring ChromiumBinariesDistribution::GetPublisherName() {
- NOTREACHED() << "GetApplicationName unsupported";
+ NOTREACHED();
return std::wstring();
}
std::wstring ChromiumBinariesDistribution::GetAppDescription() {
- NOTREACHED() << "GetApplicationName unsupported";
+ NOTREACHED();
return std::wstring();
}
std::wstring ChromiumBinariesDistribution::GetLongAppDescription() {
- NOTREACHED() << "GetApplicationName unsupported";
+ NOTREACHED();
return std::wstring();
}
std::string ChromiumBinariesDistribution::GetSafeBrowsingName() {
- NOTREACHED() << "GetApplicationName unsupported";
+ NOTREACHED();
return std::string();
}
@@ -76,12 +76,12 @@ std::wstring ChromiumBinariesDistribution::GetStateMediumKey() {
}
std::wstring ChromiumBinariesDistribution::GetUninstallLinkName() {
- NOTREACHED() << "GetApplicationName unsupported";
+ NOTREACHED();
return std::wstring();
}
std::wstring ChromiumBinariesDistribution::GetUninstallRegPath() {
- NOTREACHED() << "GetApplicationName unsupported";
+ NOTREACHED();
return std::wstring();
}
@@ -90,16 +90,16 @@ std::wstring ChromiumBinariesDistribution::GetVersionKey() {
}
bool ChromiumBinariesDistribution::CanSetAsDefault() {
- NOTREACHED() << "GetApplicationName unsupported";
+ NOTREACHED();
return false;
}
int ChromiumBinariesDistribution::GetIconIndex() {
- NOTREACHED() << "GetApplicationName unsupported";
+ NOTREACHED();
return 0;
}
bool ChromiumBinariesDistribution::GetChromeChannel(std::wstring* channel) {
- NOTREACHED() << "GetApplicationName unsupported";
+ NOTREACHED();
return false;
}
diff --git a/chrome/installer/util/google_chrome_distribution.cc b/chrome/installer/util/google_chrome_distribution.cc
index 3f9b7db..7a0e89d 100644
--- a/chrome/installer/util/google_chrome_distribution.cc
+++ b/chrome/installer/util/google_chrome_distribution.cc
@@ -403,9 +403,10 @@ std::wstring GoogleChromeDistribution::GetAppGuid() {
}
std::wstring GoogleChromeDistribution::GetApplicationName() {
- const std::wstring& product_name =
- installer::GetLocalizedString(IDS_PRODUCT_NAME_BASE);
- return product_name;
+ // I'd really like to return L ## PRODUCT_FULLNAME_STRING; but that's no good
+ // since it'd be "Chromium" in a non-Chrome build, which isn't at all what I
+ // want. Sigh.
+ return L"Google Chrome";
}
std::wstring GoogleChromeDistribution::GetAlternateApplicationName() {
diff --git a/chrome/installer/util/google_chrome_sxs_distribution.cc b/chrome/installer/util/google_chrome_sxs_distribution.cc
index 416bc67..883994d 100644
--- a/chrome/installer/util/google_chrome_sxs_distribution.cc
+++ b/chrome/installer/util/google_chrome_sxs_distribution.cc
@@ -25,6 +25,10 @@ GoogleChromeSxSDistribution::GoogleChromeSxSDistribution()
GoogleChromeDistribution::set_product_guid(kChromeSxSGuid);
}
+std::wstring GoogleChromeSxSDistribution::GetApplicationName() {
+ return L"Google Chrome Canary";
+}
+
std::wstring GoogleChromeSxSDistribution::GetAppShortCutName() {
const std::wstring& shortcut_name =
installer::GetLocalizedString(IDS_SXS_SHORTCUT_NAME_BASE);
diff --git a/chrome/installer/util/google_chrome_sxs_distribution.h b/chrome/installer/util/google_chrome_sxs_distribution.h
index 10df80a..1e6a6174 100644
--- a/chrome/installer/util/google_chrome_sxs_distribution.h
+++ b/chrome/installer/util/google_chrome_sxs_distribution.h
@@ -23,13 +23,14 @@ class MasterPreferences;
// system level install and setting as default browser.
class GoogleChromeSxSDistribution : public GoogleChromeDistribution {
public:
- virtual std::wstring GetAppShortCutName();
- virtual std::wstring GetBrowserAppId();
- virtual std::wstring GetInstallSubDir();
- virtual std::wstring GetUninstallRegPath();
- virtual bool CanSetAsDefault();
- virtual int GetIconIndex();
- virtual bool GetChromeChannel(std::wstring* channel);
+ virtual std::wstring GetApplicationName() OVERRIDE;
+ virtual std::wstring GetAppShortCutName() OVERRIDE;
+ virtual std::wstring GetBrowserAppId() OVERRIDE;
+ virtual std::wstring GetInstallSubDir() OVERRIDE;
+ virtual std::wstring GetUninstallRegPath() OVERRIDE;
+ virtual bool CanSetAsDefault() OVERRIDE;
+ virtual int GetIconIndex() OVERRIDE;
+ virtual bool GetChromeChannel(std::wstring* channel) OVERRIDE;
// returns the channel name for GoogleChromeSxSDistribution
static std::wstring ChannelName();
private:
diff --git a/chrome/installer/util/install_util.cc b/chrome/installer/util/install_util.cc
index acd3863..a15ac4e 100644
--- a/chrome/installer/util/install_util.cc
+++ b/chrome/installer/util/install_util.cc
@@ -387,7 +387,7 @@ bool InstallUtil::DeleteRegistryValue(HKEY reg_root,
}
// static
-bool InstallUtil::DeleteRegistryKeyIf(
+InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryKeyIf(
HKEY root_key,
const std::wstring& key_to_delete_path,
const std::wstring& key_to_test_path,
@@ -395,6 +395,7 @@ bool InstallUtil::DeleteRegistryKeyIf(
const RegistryValuePredicate& predicate) {
DCHECK(root_key);
DCHECK(value_name);
+ ConditionalDeleteResult delete_result = NOT_FOUND;
RegKey key;
std::wstring actual_value;
if (key.Open(root_key, key_to_test_path.c_str(),
@@ -402,13 +403,14 @@ bool InstallUtil::DeleteRegistryKeyIf(
key.ReadValue(value_name, &actual_value) == ERROR_SUCCESS &&
predicate.Evaluate(actual_value)) {
key.Close();
- return DeleteRegistryKey(root_key, key_to_delete_path);
+ delete_result = DeleteRegistryKey(root_key, key_to_delete_path)
+ ? DELETED : DELETE_FAILED;
}
- return true;
+ return delete_result;
}
// static
-bool InstallUtil::DeleteRegistryValueIf(
+InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryValueIf(
HKEY root_key,
const wchar_t* key_path,
const wchar_t* value_name,
@@ -416,6 +418,7 @@ bool InstallUtil::DeleteRegistryValueIf(
DCHECK(root_key);
DCHECK(key_path);
DCHECK(value_name);
+ ConditionalDeleteResult delete_result = NOT_FOUND;
RegKey key;
std::wstring actual_value;
if (key.Open(root_key, key_path,
@@ -426,10 +429,11 @@ bool InstallUtil::DeleteRegistryValueIf(
if (result != ERROR_SUCCESS) {
LOG(ERROR) << "Failed to delete registry value: " << value_name
<< " error: " << result;
- return false;
+ delete_result = DELETE_FAILED;
}
+ delete_result = DELETED;
}
- return true;
+ return delete_result;
}
bool InstallUtil::ValueEquals::Evaluate(const std::wstring& value) const {
diff --git a/chrome/installer/util/install_util.h b/chrome/installer/util/install_util.h
index b730cc4..1e47522 100644
--- a/chrome/installer/util/install_util.h
+++ b/chrome/installer/util/install_util.h
@@ -123,25 +123,32 @@ class InstallUtil {
virtual bool Evaluate(const std::wstring& value) const = 0;
};
+ // The result of a conditional delete operation (i.e., DeleteFOOIf).
+ enum ConditionalDeleteResult {
+ NOT_FOUND, // The condition was not satisfied.
+ DELETED, // The condition was satisfied and the delete succeeded.
+ DELETE_FAILED // The condition was satisfied but the delete failed.
+ };
+
// Deletes the key |key_to_delete_path| under |root_key| iff the value
// |value_name| in the key |key_to_test_path| under |root_key| satisfies
// |predicate|. |value_name| must be an empty string to test the key's
- // default value. Returns false if the value satisfied the predicate but
- // could not be deleted, otherwise returns true.
- static bool DeleteRegistryKeyIf(HKEY root_key,
- const std::wstring& key_to_delete_path,
- const std::wstring& key_to_test_path,
- const wchar_t* value_name,
- const RegistryValuePredicate& predicate);
+ // default value.
+ static ConditionalDeleteResult DeleteRegistryKeyIf(
+ HKEY root_key,
+ const std::wstring& key_to_delete_path,
+ const std::wstring& key_to_test_path,
+ const wchar_t* value_name,
+ const RegistryValuePredicate& predicate);
// Deletes the value |value_name| in the key |key_path| under |root_key| iff
// its current value satisfies |predicate|. |value_name| must be an empty
- // string to test the key's default value. Returns false if the value
- // satisfied the predicate but could not be deleted, otherwise returns true.
- static bool DeleteRegistryValueIf(HKEY root_key,
- const wchar_t* key_path,
- const wchar_t* value_name,
- const RegistryValuePredicate& predicate);
+ // string to test the key's default value.
+ static ConditionalDeleteResult DeleteRegistryValueIf(
+ HKEY root_key,
+ const wchar_t* key_path,
+ const wchar_t* value_name,
+ const RegistryValuePredicate& predicate);
// A predicate that performs a case-sensitive string comparison.
class ValueEquals : public RegistryValuePredicate {
diff --git a/chrome/installer/util/install_util_unittest.cc b/chrome/installer/util/install_util_unittest.cc
index 9d5341d..ef0c39b 100644
--- a/chrome/installer/util/install_util_unittest.cc
+++ b/chrome/installer/util/install_util_unittest.cc
@@ -190,8 +190,10 @@ TEST_F(InstallUtilTest, DeleteRegistryKeyIf) {
EXPECT_CALL(pred, Evaluate(_)).Times(0);
ASSERT_FALSE(RegKey(root, parent_key_path.c_str(),
KEY_QUERY_VALUE).Valid());
- EXPECT_TRUE(InstallUtil::DeleteRegistryKeyIf(
- root, parent_key_path, child_key_path, value_name, pred));
+ EXPECT_EQ(InstallUtil::NOT_FOUND,
+ InstallUtil::DeleteRegistryKeyIf(root, parent_key_path,
+ child_key_path, value_name,
+ pred));
EXPECT_FALSE(RegKey(root, parent_key_path.c_str(),
KEY_QUERY_VALUE).Valid());
}
@@ -202,8 +204,10 @@ TEST_F(InstallUtilTest, DeleteRegistryKeyIf) {
EXPECT_CALL(pred, Evaluate(_)).Times(0);
ASSERT_TRUE(RegKey(root, parent_key_path.c_str(), KEY_SET_VALUE).Valid());
- EXPECT_TRUE(InstallUtil::DeleteRegistryKeyIf(
- root, parent_key_path, child_key_path, value_name, pred));
+ EXPECT_EQ(InstallUtil::NOT_FOUND,
+ InstallUtil::DeleteRegistryKeyIf(root, parent_key_path,
+ child_key_path, value_name,
+ pred));
EXPECT_TRUE(RegKey(root, parent_key_path.c_str(),
KEY_QUERY_VALUE).Valid());
}
@@ -214,8 +218,10 @@ TEST_F(InstallUtilTest, DeleteRegistryKeyIf) {
EXPECT_CALL(pred, Evaluate(_)).Times(0);
ASSERT_TRUE(RegKey(root, child_key_path.c_str(), KEY_SET_VALUE).Valid());
- EXPECT_TRUE(InstallUtil::DeleteRegistryKeyIf(
- root, parent_key_path, child_key_path, value_name, pred));
+ EXPECT_EQ(InstallUtil::NOT_FOUND,
+ InstallUtil::DeleteRegistryKeyIf(root, parent_key_path,
+ child_key_path, value_name,
+ pred));
EXPECT_TRUE(RegKey(root, parent_key_path.c_str(),
KEY_QUERY_VALUE).Valid());
}
@@ -228,8 +234,10 @@ TEST_F(InstallUtilTest, DeleteRegistryKeyIf) {
ASSERT_EQ(ERROR_SUCCESS,
RegKey(root, child_key_path.c_str(),
KEY_SET_VALUE).WriteValue(value_name, L"foosball!"));
- EXPECT_TRUE(InstallUtil::DeleteRegistryKeyIf(
- root, parent_key_path, child_key_path, value_name, pred));
+ EXPECT_EQ(InstallUtil::NOT_FOUND,
+ InstallUtil::DeleteRegistryKeyIf(root, parent_key_path,
+ child_key_path, value_name,
+ pred));
EXPECT_TRUE(RegKey(root, parent_key_path.c_str(),
KEY_QUERY_VALUE).Valid());
}
@@ -242,8 +250,10 @@ TEST_F(InstallUtilTest, DeleteRegistryKeyIf) {
ASSERT_EQ(ERROR_SUCCESS,
RegKey(root, child_key_path.c_str(),
KEY_SET_VALUE).WriteValue(value_name, value));
- EXPECT_TRUE(InstallUtil::DeleteRegistryKeyIf(
- root, parent_key_path, child_key_path, value_name, pred));
+ EXPECT_EQ(InstallUtil::DELETED,
+ InstallUtil::DeleteRegistryKeyIf(root, parent_key_path,
+ child_key_path, value_name,
+ pred));
EXPECT_FALSE(RegKey(root, parent_key_path.c_str(),
KEY_QUERY_VALUE).Valid());
}
@@ -265,8 +275,9 @@ TEST_F(InstallUtilTest, DeleteRegistryValueIf) {
EXPECT_CALL(pred, Evaluate(_)).Times(0);
ASSERT_FALSE(RegKey(root, key_path.c_str(), KEY_QUERY_VALUE).Valid());
- EXPECT_TRUE(InstallUtil::DeleteRegistryValueIf(
- root, key_path.c_str(), value_name, pred));
+ EXPECT_EQ(InstallUtil::NOT_FOUND,
+ InstallUtil::DeleteRegistryValueIf(root, key_path.c_str(),
+ value_name, pred));
EXPECT_FALSE(RegKey(root, key_path.c_str(), KEY_QUERY_VALUE).Valid());
}
@@ -276,8 +287,9 @@ TEST_F(InstallUtilTest, DeleteRegistryValueIf) {
EXPECT_CALL(pred, Evaluate(_)).Times(0);
ASSERT_TRUE(RegKey(root, key_path.c_str(), KEY_SET_VALUE).Valid());
- EXPECT_TRUE(InstallUtil::DeleteRegistryValueIf(
- root, key_path.c_str(), value_name, pred));
+ EXPECT_EQ(InstallUtil::NOT_FOUND,
+ InstallUtil::DeleteRegistryValueIf(root, key_path.c_str(),
+ value_name, pred));
EXPECT_TRUE(RegKey(root, key_path.c_str(), KEY_QUERY_VALUE).Valid());
}
@@ -289,8 +301,9 @@ TEST_F(InstallUtilTest, DeleteRegistryValueIf) {
ASSERT_EQ(ERROR_SUCCESS,
RegKey(root, key_path.c_str(),
KEY_SET_VALUE).WriteValue(value_name, L"foosball!"));
- EXPECT_TRUE(InstallUtil::DeleteRegistryValueIf(
- root, key_path.c_str(), value_name, pred));
+ EXPECT_EQ(InstallUtil::NOT_FOUND,
+ InstallUtil::DeleteRegistryValueIf(root, key_path.c_str(),
+ value_name, pred));
EXPECT_TRUE(RegKey(root, key_path.c_str(), KEY_QUERY_VALUE).Valid());
EXPECT_TRUE(RegKey(root, key_path.c_str(),
KEY_QUERY_VALUE).HasValue(value_name));
@@ -304,8 +317,9 @@ TEST_F(InstallUtilTest, DeleteRegistryValueIf) {
ASSERT_EQ(ERROR_SUCCESS,
RegKey(root, key_path.c_str(),
KEY_SET_VALUE).WriteValue(value_name, value));
- EXPECT_TRUE(InstallUtil::DeleteRegistryValueIf(
- root, key_path.c_str(), value_name, pred));
+ EXPECT_EQ(InstallUtil::DELETED,
+ InstallUtil::DeleteRegistryValueIf(root, key_path.c_str(),
+ value_name, pred));
EXPECT_TRUE(RegKey(root, key_path.c_str(), KEY_QUERY_VALUE).Valid());
EXPECT_FALSE(RegKey(root, key_path.c_str(),
KEY_QUERY_VALUE).HasValue(value_name));
@@ -323,8 +337,9 @@ TEST_F(InstallUtilTest, DeleteRegistryValueIf) {
ASSERT_EQ(ERROR_SUCCESS,
RegKey(root, key_path.c_str(),
KEY_SET_VALUE).WriteValue(L"", value));
- EXPECT_TRUE(InstallUtil::DeleteRegistryValueIf(
- root, key_path.c_str(), L"", pred));
+ EXPECT_EQ(InstallUtil::DELETED,
+ InstallUtil::DeleteRegistryValueIf(root, key_path.c_str(), L"",
+ pred));
EXPECT_TRUE(RegKey(root, key_path.c_str(), KEY_QUERY_VALUE).Valid());
EXPECT_FALSE(RegKey(root, key_path.c_str(),
KEY_QUERY_VALUE).HasValue(L""));
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
index 7af6a9a..3b56f82 100644
--- a/chrome/installer/util/shell_util.cc
+++ b/chrome/installer/util/shell_util.cc
@@ -39,6 +39,8 @@ using base::win::RegKey;
namespace {
+const wchar_t kReinstallCommand[] = L"ReinstallCommand";
+
// This class represents a single registry entry. The objective is to
// encapsulate all the registry entries required for registering Chrome at one
// place. This class can not be instantiated outside the class and the objects
@@ -46,6 +48,30 @@ namespace {
// class.
class RegistryEntry {
public:
+ // Returns the Windows browser client registration key for Chrome. For
+ // example: "Software\Clients\StartMenuInternet\Chromium[.user]". Strictly
+ // speaking, we should use the name of the executable (e.g., "chrome.exe"),
+ // but that ship has sailed. The cost of switching now is re-prompting users
+ // to make Chrome their default browser, which isn't polite. |suffix| is the
+ // user-specific registration suffix; see GetUserSpecificDefaultBrowserSuffix
+ // in shell_util.h for details.
+ static std::wstring GetBrowserClientKey(BrowserDistribution* dist,
+ const std::wstring& suffix) {
+ DCHECK(suffix.empty() || suffix[0] == L'.');
+ return std::wstring(ShellUtil::kRegStartMenuInternet)
+ .append(1, L'\\')
+ .append(dist->GetApplicationName())
+ .append(suffix);
+ }
+
+ // Returns the Windows Default Programs capabilities key for Chrome. For
+ // example:
+ // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities".
+ static std::wstring GetCapabilitiesKey(BrowserDistribution* dist,
+ const std::wstring& suffix) {
+ return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities");
+ }
+
// This method returns a list of all the registry entries that
// are needed to register Chromium ProgIds.
static bool GetProgIdEntries(BrowserDistribution* dist,
@@ -74,23 +100,14 @@ class RegistryEntry {
// This method returns a list of the system level registry entries
// needed to declare a capability of handling a protocol.
static bool GetProtocolCapabilityEntries(BrowserDistribution* dist,
- const std::wstring& chrome_exe,
const std::wstring& suffix,
const std::wstring& protocol,
std::list<RegistryEntry*>* entries) {
- std::wstring app_name = dist->GetApplicationName() + suffix;
- std::wstring start_menu_entry(ShellUtil::kRegStartMenuInternet);
- start_menu_entry.append(L"\\" + app_name);
-
- std::wstring capabilities(start_menu_entry + L"\\Capabilities");
-
- std::wstring html_prog_id(ShellUtil::kChromeHTMLProgId);
- html_prog_id.append(suffix);
- entries->push_front(new RegistryEntry(capabilities + L"\\URLAssociations",
- protocol, html_prog_id));
+ entries->push_front(new RegistryEntry(
+ GetCapabilitiesKey(dist, suffix).append(L"\\URLAssociations"),
+ protocol, std::wstring(ShellUtil::kChromeHTMLProgId).append(suffix)));
return true;
-}
-
+ }
// This method returns a list of all the system level registry entries that
// are needed to register Chromium on the machine.
@@ -101,18 +118,25 @@ class RegistryEntry {
std::wstring icon_path = ShellUtil::GetChromeIcon(dist, chrome_exe);
std::wstring quoted_exe_path = L"\"" + chrome_exe + L"\"";
- std::wstring app_name = dist->GetApplicationName() + suffix;
- std::wstring start_menu_entry(ShellUtil::kRegStartMenuInternet);
- start_menu_entry.append(L"\\" + app_name);
- entries->push_front(new RegistryEntry(start_menu_entry, app_name));
+ // Register for the Start Menu "Internet" link (pre-Win7).
+ const std::wstring start_menu_entry(GetBrowserClientKey(dist, suffix));
+ // Register Chrome's display name.
+ // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85).aspx#registering_the_display_name
+ entries->push_front(new RegistryEntry(
+ start_menu_entry, dist->GetApplicationName()));
+ // Register the "open" verb for launching Chrome via the "Internet" link.
entries->push_front(new RegistryEntry(
start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path));
+ // Register Chrome's icon for the Start Menu "Internet" link.
entries->push_front(new RegistryEntry(
start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path));
+ // Register installation information.
std::wstring install_info(start_menu_entry + L"\\InstallInfo");
- // TODO: use CommandLine API instead of constructing command lines.
- entries->push_front(new RegistryEntry(install_info, L"ReinstallCommand",
+ // Note: not using CommandLine since it has ambiguous rules for quoting
+ // strings.
+ entries->push_front(new RegistryEntry(install_info, kReinstallCommand,
quoted_exe_path + L" --" + ASCIIToWide(switches::kMakeDefaultBrowser)));
entries->push_front(new RegistryEntry(install_info, L"HideIconsCommand",
quoted_exe_path + L" --" + ASCIIToWide(switches::kHideIcons)));
@@ -120,9 +144,15 @@ class RegistryEntry {
quoted_exe_path + L" --" + ASCIIToWide(switches::kShowIcons)));
entries->push_front(new RegistryEntry(install_info, L"IconsVisible", 1));
- std::wstring capabilities(start_menu_entry + L"\\Capabilities");
+ // Register with Default Programs.
+ std::wstring app_name(dist->GetApplicationName().append(suffix));
+ // Tell Windows where to find Chrome's Default Programs info.
+ std::wstring capabilities(GetCapabilitiesKey(dist, suffix));
entries->push_front(new RegistryEntry(ShellUtil::kRegRegisteredApplications,
app_name, capabilities));
+ // Write out Chrome's Default Programs info.
+ // TODO(grt): http://crbug.com/75152 Write a reference to a localized
+ // resource rather than this.
entries->push_front(new RegistryEntry(
capabilities, L"ApplicationDescription",
dist->GetLongAppDescription()));
@@ -131,7 +161,7 @@ class RegistryEntry {
entries->push_front(new RegistryEntry(
capabilities, L"ApplicationName", app_name));
- entries->push_front(new RegistryEntry(capabilities + L"\\StartMenu",
+ entries->push_front(new RegistryEntry(capabilities + L"\\Startmenu",
L"StartMenuInternet", app_name));
std::wstring html_prog_id(ShellUtil::kChromeHTMLProgId);
@@ -148,6 +178,7 @@ class RegistryEntry {
ShellUtil::kPotentialProtocolAssociations[i], html_prog_id));
}
+ // Application Registration.
FilePath chrome_path(chrome_exe);
std::wstring app_path_key(ShellUtil::kAppPathsRegistryKey);
file_util::AppendToPath(&app_path_key, chrome_path.BaseName().value());
@@ -161,10 +192,7 @@ class RegistryEntry {
// This method returns a list of all the user level registry entries that
// are needed to make Chromium the default handler for a protocol.
- static bool GetUserProtocolEntries(BrowserDistribution* dist,
- const std::wstring& chrome_exe,
- const std::wstring& suffix,
- const std::wstring& protocol,
+ static bool GetUserProtocolEntries(const std::wstring& protocol,
const std::wstring& chrome_icon,
const std::wstring& chrome_open,
std::list<RegistryEntry*>* entries) {
@@ -216,8 +244,7 @@ class RegistryEntry {
std::wstring chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe);
std::wstring chrome_icon = ShellUtil::GetChromeIcon(dist, chrome_exe);
for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) {
- GetUserProtocolEntries(dist, chrome_exe, suffix,
- ShellUtil::kBrowserProtocolAssociations[i],
+ GetUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i],
chrome_icon, chrome_open, entries);
}
@@ -346,14 +373,12 @@ bool IsChromeRegistered(BrowserDistribution* dist,
// This method checks if Chrome is already registered on the local machine
// for the requested protocol. It just checks the one value required for this.
bool IsChromeRegisteredForProtocol(BrowserDistribution* dist,
- const std::wstring& chrome_exe,
const std::wstring& suffix,
const std::wstring& protocol) {
bool registered = true;
std::list<RegistryEntry*> entries;
STLElementDeleter<std::list<RegistryEntry*>> entries_deleter(&entries);
- RegistryEntry::GetProtocolCapabilityEntries(dist, chrome_exe, suffix,
- protocol, &entries);
+ RegistryEntry::GetProtocolCapabilityEntries(dist, suffix, protocol, &entries);
for (std::list<RegistryEntry*>::const_iterator itr = entries.begin();
itr != entries.end() && registered; ++itr) {
// We do not need registered = registered && ... since the loop condition
@@ -426,8 +451,9 @@ bool ElevateAndRegisterChrome(BrowserDistribution* dist,
// of the above key should differ from |chrome_exe| only in user name.
bool AnotherUserHasDefaultBrowser(BrowserDistribution* dist,
const std::wstring& chrome_exe) {
- std::wstring reg_key(ShellUtil::kRegStartMenuInternet);
- reg_key.append(L"\\" + dist->GetApplicationName() + ShellUtil::kRegShellOpen);
+ const std::wstring reg_key(
+ RegistryEntry::GetBrowserClientKey(dist, std::wstring())
+ .append(ShellUtil::kRegShellOpen));
RegKey key(HKEY_LOCAL_MACHINE, reg_key.c_str(), KEY_READ);
std::wstring registry_chrome_exe;
if ((key.ReadValue(L"", &registry_chrome_exe) != ERROR_SUCCESS) ||
@@ -655,28 +681,29 @@ bool ShellUtil::GetQuickLaunchPath(bool system_level, std::wstring* path) {
return true;
}
-void ShellUtil::GetRegisteredBrowsers(BrowserDistribution* dist,
- std::map<std::wstring,
- std::wstring>* browsers) {
- std::wstring base_key(ShellUtil::kRegStartMenuInternet);
- HKEY root = HKEY_LOCAL_MACHINE;
+void ShellUtil::GetRegisteredBrowsers(
+ BrowserDistribution* dist,
+ std::map<std::wstring, std::wstring>* browsers) {
+ const HKEY root = HKEY_LOCAL_MACHINE;
+ const std::wstring base_key(ShellUtil::kRegStartMenuInternet);
+ std::wstring client_path;
+ RegKey key;
+ std::wstring name;
+ std::wstring command;
for (base::win::RegistryKeyIterator iter(root, base_key.c_str());
iter.Valid(); ++iter) {
- std::wstring key = base_key + L"\\" + iter.Name();
- RegKey capabilities(root, (key + L"\\Capabilities").c_str(), KEY_READ);
- std::wstring name;
- if (!capabilities.Valid() ||
- capabilities.ReadValue(L"ApplicationName", &name) != ERROR_SUCCESS) {
- RegKey base_key(root, key.c_str(), KEY_READ);
- if (base_key.ReadValue(L"", &name) != ERROR_SUCCESS)
- continue;
+ client_path.assign(base_key).append(1, L'\\').append(iter.Name());
+ // Read the browser's name (localized according to install language).
+ if (key.Open(root, client_path.c_str(), KEY_QUERY_VALUE) != ERROR_SUCCESS ||
+ key.ReadValue(NULL, &name) != ERROR_SUCCESS) {
+ continue;
}
- RegKey install_info(root, (key + L"\\InstallInfo").c_str(), KEY_READ);
- std::wstring command;
- if (!install_info.Valid() ||
- (install_info.ReadValue(L"ReinstallCommand",
- &command) != ERROR_SUCCESS))
+ // Read the browser's reinstall command.
+ if (key.Open(root, (client_path + L"\\InstallInfo").c_str(),
+ KEY_QUERY_VALUE) != ERROR_SUCCESS ||
+ key.ReadValue(kReinstallCommand, &command) != ERROR_SUCCESS) {
continue;
+ }
if (!name.empty() && !command.empty() &&
name.find(dist->GetApplicationName()) == std::wstring::npos)
(*browsers)[name] = command;
@@ -686,16 +713,16 @@ void ShellUtil::GetRegisteredBrowsers(BrowserDistribution* dist,
bool ShellUtil::GetUserSpecificDefaultBrowserSuffix(BrowserDistribution* dist,
std::wstring* entry) {
wchar_t user_name[256];
- DWORD size = _countof(user_name);
- if (::GetUserName(user_name, &size) == 0)
+ DWORD size = arraysize(user_name);
+ if (::GetUserName(user_name, &size) == 0 || size < 1)
return false;
- entry->assign(L".");
- entry->append(user_name);
+ entry->reserve(size);
+ entry->assign(1, L'.');
+ entry->append(user_name, size - 1);
- std::wstring start_menu_entry(ShellUtil::kRegStartMenuInternet);
- start_menu_entry.append(L"\\" + dist->GetApplicationName() + *entry);
- RegKey key(HKEY_LOCAL_MACHINE, start_menu_entry.c_str(), KEY_READ);
- return key.Valid();
+ return RegKey(HKEY_LOCAL_MACHINE,
+ RegistryEntry::GetBrowserClientKey(dist, *entry).c_str(),
+ KEY_READ).Valid();
}
bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist,
@@ -819,8 +846,8 @@ bool ShellUtil::MakeChromeDefaultProtocolClient(BrowserDistribution* dist,
suffix = L"";
std::wstring chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe);
std::wstring chrome_icon = ShellUtil::GetChromeIcon(dist, chrome_exe);
- RegistryEntry::GetUserProtocolEntries(dist, chrome_exe, suffix, protocol,
- chrome_icon, chrome_open, &entries);
+ RegistryEntry::GetUserProtocolEntries(protocol, chrome_icon, chrome_open,
+ &entries);
// Change the default protocol handler for current user.
if (!AddRegistryEntries(HKEY_CURRENT_USER, entries)) {
ret = false;
@@ -895,7 +922,7 @@ bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist,
}
// Check if Chromium is already registered with this suffix.
- if (IsChromeRegisteredForProtocol(dist, chrome_exe, suffix, protocol))
+ if (IsChromeRegisteredForProtocol(dist, suffix, protocol))
return true;
if (IsUserAnAdmin()) {
@@ -910,8 +937,8 @@ bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist,
// Write in the capabillity for the protocol.
std::list<RegistryEntry*> entries;
STLElementDeleter<std::list<RegistryEntry*>> entries_deleter(&entries);
- RegistryEntry::GetProtocolCapabilityEntries(dist, chrome_exe, suffix,
- protocol, &entries);
+ RegistryEntry::GetProtocolCapabilityEntries(dist, suffix, protocol,
+ &entries);
return AddRegistryEntries(HKEY_LOCAL_MACHINE, entries);
} else if (elevate_if_not_admin &&
base::win::GetVersion() >= base::win::VERSION_VISTA) {