Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2428)

Unified Diff: chrome/installer/setup/setup_main.cc

Issue 1271893003: Add options to write version number to registry. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: change DisplayVersion in Uninstall, too Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/installer/setup/setup_main.cc
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc
index 29cdf06f0c723e32b61f32c47e91c349d2c39730..50d89ca51ed887d5de5dea24a2d6596a592cb6ae 100644
--- a/chrome/installer/setup/setup_main.cc
+++ b/chrome/installer/setup/setup_main.cc
@@ -82,6 +82,15 @@ using installer::Products;
const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\";
grt (UTC plus 2) 2015/09/11 18:14:26 please move all of these constants that are only u
bcwhite 2015/09/11 19:24:44 Done.
const wchar_t kSystemPrincipalSid[] = L"S-1-5-18";
+const wchar_t kDisplayVersion[] = L"DisplayVersion";
+const wchar_t kMsiInstallRegistryPrefix[] =
+ L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\"
+ L"S-1-5-18\\Products\\";
+const wchar_t kMsiInstallRegistryPostfix[] = L"\\InstallProperties";
+const wchar_t kMsiUninstallRegistryPrefix[] =
+ L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\";
+const wchar_t kMsiUninstallRegistryPostfix[] = L"";
+const wchar_t kMsiDisplayVersionOverwriteDelay[] = L"10"; // seconds as string
const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>(
MiniDumpWithProcessThreadData | // Get PEB and TEB.
@@ -90,6 +99,81 @@ const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>(
namespace {
+// Overwrite an existing DisplayVersion as written by the MSI installer
+// with the real version number of Chrome.
+LONG OverwriteDisplayVersion(const base::string16& path,
+ const base::string16& value) {
+ base::win::RegKey key;
+ LONG result = 0;
+ base::string16 existing;
+ if ((result = key.Open(HKEY_LOCAL_MACHINE, path.c_str(),
+ KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_WOW64_64KEY))
+ != ERROR_SUCCESS) {
+ LOG(ERROR) << "Failed to set DisplayVersion: " << path << " not found";
+ return result;
+ }
+ if ((result = key.ReadValue(kDisplayVersion, &existing)) != ERROR_SUCCESS) {
+ LOG(ERROR) << "Failed to set DisplayVersion: " << kDisplayVersion
+ << " not found under " << path;
+ return result;
+ }
+ if ((result = key.WriteValue(kDisplayVersion, value.c_str()))
+ != ERROR_SUCCESS) {
+ LOG(ERROR) << "Failed to set DisplayVersion: " << kDisplayVersion
+ << " could not be written under " << path;
+ return result;
+ }
+ VLOG(1) << "Set DisplayVersion at " << path << " to " << value
+ << " from " << existing;
+ return ERROR_SUCCESS;
+}
+
+LONG OverwriteDisplayVersions(const base::string16& product,
+ const base::string16& value) {
+ // The version is held in two places. Frist change it in the MSI Installer
+ // registry entry. It is held under a "squashed guid" key.
+ base::string16 reg_path(kMsiInstallRegistryPrefix);
+ reg_path += base::ASCIIToUTF16(
grt (UTC plus 2) 2015/09/11 18:14:26 can GuidToSquid operate on base::string16 so we do
bcwhite 2015/09/11 19:24:44 Done.
+ installer::GuidToSquid(base::UTF16ToASCII(product)));
+ reg_path += kMsiInstallRegistryPostfix;
+ LONG result1 = OverwriteDisplayVersion(reg_path, value);
+
+ // The display version also exists under the Unininstall registry key with
+ // the original guid.
+ reg_path = kMsiUninstallRegistryPrefix;
grt (UTC plus 2) 2015/09/11 18:14:26 i think it's more clear to use base::StringPrintf
bcwhite 2015/09/11 19:24:45 Done.
+ reg_path += L"{";
+ reg_path += product;
+ reg_path += L"}";
+ reg_path += kMsiUninstallRegistryPostfix;
+ LONG result2 = OverwriteDisplayVersion(reg_path, value);
+
+ return result1 != ERROR_SUCCESS ? result1 : result2;
+}
+
+void DelayedOverwriteDisplayVersions(const base::FilePath& setup_exe,
+ const base::string16& id,
+ const Version& version) {
+ // This process has to be able to exit so we launch ourselves with
+ // instructions on what to do and then return.
+ base::CommandLine command_line(setup_exe);
+ command_line.AppendSwitchNative(
+ installer::switches::kSetDisplayVersionProduct, id);
+ command_line.AppendSwitchNative(installer::switches::kSetDisplayVersionValue,
grt (UTC plus 2) 2015/09/11 18:14:26 nit: use AppendSwitchASCII and remove the ASCIIToU
bcwhite 2015/09/11 19:24:44 Done.
+ base::ASCIIToUTF16(version.GetString()));
+ command_line.AppendSwitchNative(installer::switches::kDelay,
+ kMsiDisplayVersionOverwriteDelay);
+
+ base::LaunchOptions launch_options;
+ launch_options.force_breakaway_from_job_ = true;
+ base::Process writer = base::LaunchProcess(command_line, launch_options);
+ if (!writer.IsValid()) {
+ LOG(ERROR) << "Failed to set DisplayVersion: "
grt (UTC plus 2) 2015/09/11 18:14:26 tip: PLOG(ERROR) and remove the GetLastError() tid
bcwhite 2015/09/11 19:24:45 Done.
+ << "could not launch subprocess to make desired changes."
+ << " (error=" << ::GetLastError() << ")\n"
grt (UTC plus 2) 2015/09/11 18:14:26 i think it's best not to put newlines in log messa
bcwhite 2015/09/11 19:24:44 Done.
+ << command_line.GetCommandLineString();
+ }
+}
+
// Returns NULL if no compressed archive is available for processing, otherwise
// returns a patch helper configured to uncompress and patch.
scoped_ptr<installer::ArchivePatchHelper> CreateChromeArchiveHelper(
@@ -920,6 +1004,18 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state,
const base::CommandLine& cmd_line,
InstallerState* installer_state,
int* exit_code) {
+ // This option is independent of all others so doesn't belong in the if/else
+ // block below.
+ if (cmd_line.HasSwitch(installer::switches::kDelay)) {
+ const std::string delay_seconds_string(
+ cmd_line.GetSwitchValueASCII(installer::switches::kDelay));
+ int delay_seconds;
+ if (base::StringToInt(delay_seconds_string, &delay_seconds) &&
+ delay_seconds > 0) {
+ base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(delay_seconds));
+ }
+ }
+
// TODO(gab): Add a local |status| variable which each block below sets;
// only determine the |exit_code| from |status| at the end (this will allow
// this method to validate that
@@ -1163,6 +1259,15 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state,
bool updates_enabled = GoogleUpdateSettings::ReenableAutoupdates();
*exit_code = updates_enabled ? installer::REENABLE_UPDATES_SUCCEEDED :
installer::REENABLE_UPDATES_FAILED;
+ } else if (cmd_line.HasSwitch(
+ installer::switches::kSetDisplayVersionProduct)) {
+ const base::string16 registry_product(
+ cmd_line.GetSwitchValueNative(
+ installer::switches::kSetDisplayVersionProduct));
+ const base::string16 registry_value(
+ cmd_line.GetSwitchValueNative(
+ installer::switches::kSetDisplayVersionValue));
+ *exit_code = OverwriteDisplayVersions(registry_product, registry_value);
} else {
handled = false;
}
@@ -1553,13 +1658,24 @@ InstallStatus InstallProductsHelper(const InstallationState& original_state,
}
}
- // If installation completed successfully, return the path to the directory
- // containing the newly installed setup.exe and uncompressed archive if the
- // caller requested it.
- if (installer_directory &&
- InstallUtil::GetInstallReturnCode(install_status) == 0) {
- *installer_directory =
- installer_state.GetInstallerDirectory(*installer_version);
+ // If the installation completed successfully...
+ if (InstallUtil::GetInstallReturnCode(install_status) == 0) {
+ // Update the DisplayVersion created by an MSI-based install.
+ std::string install_id;
+ if (prefs.GetString(installer::master_preferences::kMsiProductId,
+ &install_id)) {
+ base::FilePath new_setup =
+ installer_state.GetInstallerDirectory(*installer_version)
+ .Append(kSetupExe);
+ DelayedOverwriteDisplayVersions(
+ new_setup, base::ASCIIToUTF16(install_id), *installer_version);
grt (UTC plus 2) 2015/09/11 18:14:26 nit: pass install_id directly and use AppendSwitch
bcwhite 2015/09/11 19:24:44 Done.
grt (UTC plus 2) 2015/09/11 20:07:01 Not done?
bcwhite 2015/09/12 03:49:23 Weird. I absolutely did change that; no idea how
+ }
+ // Return the path to the directory containing the newly installed
+ // setup.exe and uncompressed archive if the caller requested it.
+ if (installer_directory) {
+ *installer_directory =
+ installer_state.GetInstallerDirectory(*installer_version);
+ }
}
// temp_path's dtor will take care of deleting or scheduling itself for

Powered by Google App Engine
This is Rietveld 408576698