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

Side by Side Diff: chrome/installer/setup/setup_main.cc

Issue 1410563002: Handle upgrade case from previous MSI install. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2526
Patch Set: Created 5 years, 2 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/installer/setup/setup_main.h" 5 #include "chrome/installer/setup/setup_main.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <msi.h> 8 #include <msi.h>
9 #include <shellapi.h> 9 #include <shellapi.h>
10 #include <shlobj.h> 10 #include <shlobj.h>
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 MiniDumpWithProcessThreadData | // Get PEB and TEB. 84 MiniDumpWithProcessThreadData | // Get PEB and TEB.
85 MiniDumpWithUnloadedModules | // Get unloaded modules when available. 85 MiniDumpWithUnloadedModules | // Get unloaded modules when available.
86 MiniDumpWithIndirectlyReferencedMemory); // Get memory referenced by stack. 86 MiniDumpWithIndirectlyReferencedMemory); // Get memory referenced by stack.
87 87
88 namespace { 88 namespace {
89 89
90 const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\"; 90 const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\";
91 const wchar_t kSystemPrincipalSid[] = L"S-1-5-18"; 91 const wchar_t kSystemPrincipalSid[] = L"S-1-5-18";
92 const wchar_t kDisplayVersion[] = L"DisplayVersion"; 92 const wchar_t kDisplayVersion[] = L"DisplayVersion";
93 const wchar_t kMsiDisplayVersionOverwriteDelay[] = L"10"; // seconds as string 93 const wchar_t kMsiDisplayVersionOverwriteDelay[] = L"10"; // seconds as string
94 const wchar_t kMsiProductIdPrefix[] = L"EnterpriseProduct";
94 95
95 // Overwrite an existing DisplayVersion as written by the MSI installer 96 // Overwrite an existing DisplayVersion as written by the MSI installer
96 // with the real version number of Chrome. 97 // with the real version number of Chrome.
97 LONG OverwriteDisplayVersion(const base::string16& path, 98 LONG OverwriteDisplayVersion(const base::string16& path,
98 const base::string16& value, 99 const base::string16& value,
99 REGSAM wowkey) { 100 REGSAM wowkey) {
100 base::win::RegKey key; 101 base::win::RegKey key;
101 LONG result = 0; 102 LONG result = 0;
102 base::string16 existing; 103 base::string16 existing;
103 if ((result = key.Open(HKEY_LOCAL_MACHINE, path.c_str(), 104 if ((result = key.Open(HKEY_LOCAL_MACHINE, path.c_str(),
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 // Specify an empty path for the patch source since it isn't yet known that 203 // Specify an empty path for the patch source since it isn't yet known that
203 // one is needed. It will be supplied in UncompressAndPatchChromeArchive if it 204 // one is needed. It will be supplied in UncompressAndPatchChromeArchive if it
204 // is. 205 // is.
205 return scoped_ptr<installer::ArchivePatchHelper>( 206 return scoped_ptr<installer::ArchivePatchHelper>(
206 new installer::ArchivePatchHelper(working_directory, 207 new installer::ArchivePatchHelper(working_directory,
207 compressed_archive, 208 compressed_archive,
208 base::FilePath(), 209 base::FilePath(),
209 target)); 210 target));
210 } 211 }
211 212
213 // Returns the MSI product ID from the ClientState key that is populated for MSI
214 // installs. This property is encoded in a value name whose format is
215 // "EnterpriseId<GUID>" where <GUID> is the MSI product id. <GUID> is in the
216 // format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. The id will be returned if
217 // found otherwise this method will return an empty string.
218 //
219 // This format is strange and its provenance is shrouded in mystery but it has
220 // the data we need, so use it.
221 base::string16 FindMsiProductId(const InstallerState& installer_state,
222 const Product* product) {
223 HKEY reg_root = installer_state.root_key();
224 BrowserDistribution* dist = product->distribution();
225 DCHECK(dist);
226
227 base::win::RegistryValueIterator value_iter(reg_root,
228 dist->GetStateKey().c_str());
229 for (; value_iter.Valid(); ++value_iter) {
230 base::string16 value_name(value_iter.Name());
231 if (base::StartsWith(value_name, kMsiProductIdPrefix,
232 base::CompareCase::INSENSITIVE_ASCII)) {
233 return value_name.substr(arraysize(kMsiProductIdPrefix) - 1);
234 }
235 }
236 return base::string16();
237 }
238
212 // Workhorse for producing an uncompressed archive (chrome.7z) given a 239 // Workhorse for producing an uncompressed archive (chrome.7z) given a
213 // chrome.packed.7z containing either a patch file based on the version of 240 // chrome.packed.7z containing either a patch file based on the version of
214 // chrome being updated or the full uncompressed archive. Returns true on 241 // chrome being updated or the full uncompressed archive. Returns true on
215 // success, in which case |archive_type| is populated based on what was found. 242 // success, in which case |archive_type| is populated based on what was found.
216 // Returns false on failure, in which case |install_status| contains the error 243 // Returns false on failure, in which case |install_status| contains the error
217 // code and the result is written to the registry (via WriteInstallerResult). 244 // code and the result is written to the registry (via WriteInstallerResult).
218 bool UncompressAndPatchChromeArchive( 245 bool UncompressAndPatchChromeArchive(
219 const installer::InstallationState& original_state, 246 const installer::InstallationState& original_state,
220 const installer::InstallerState& installer_state, 247 const installer::InstallerState& installer_state,
221 installer::ArchivePatchHelper* archive_helper, 248 installer::ArchivePatchHelper* archive_helper,
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1647 for (Products::const_iterator it = products.begin(); it < products.end(); 1674 for (Products::const_iterator it = products.begin(); it < products.end();
1648 ++it) { 1675 ++it) {
1649 const Product& product = **it; 1676 const Product& product = **it;
1650 product.LaunchUserExperiment(setup_path, install_status, system_install); 1677 product.LaunchUserExperiment(setup_path, install_status, system_install);
1651 } 1678 }
1652 } 1679 }
1653 1680
1654 // If the installation completed successfully... 1681 // If the installation completed successfully...
1655 if (InstallUtil::GetInstallReturnCode(install_status) == 0) { 1682 if (InstallUtil::GetInstallReturnCode(install_status) == 0) {
1656 // Update the DisplayVersion created by an MSI-based install. 1683 // Update the DisplayVersion created by an MSI-based install.
1684 base::FilePath master_preferences_file(
1685 installer_state.target_path().AppendASCII(
1686 installer::kDefaultMasterPrefs));
1657 std::string install_id; 1687 std::string install_id;
1658 if (prefs.GetString(installer::master_preferences::kMsiProductId, 1688 if (prefs.GetString(installer::master_preferences::kMsiProductId,
1659 &install_id)) { 1689 &install_id)) {
1690 // A currently active MSI install will have specified the master-
1691 // preferences file on the command-line that includes the product-id.
1692 // We must delay the setting of the DisplayVersion until after the
1693 // grandparent "msiexec" process has exited.
1660 base::FilePath new_setup = 1694 base::FilePath new_setup =
1661 installer_state.GetInstallerDirectory(*installer_version) 1695 installer_state.GetInstallerDirectory(*installer_version)
1662 .Append(kSetupExe); 1696 .Append(kSetupExe);
1663 DelayedOverwriteDisplayVersions( 1697 DelayedOverwriteDisplayVersions(
1664 new_setup, install_id, *installer_version); 1698 new_setup, install_id, *installer_version);
1699 } else {
1700 // Only when called by the MSI installer do we need to delay setting
1701 // the DisplayVersion. In other runs, such as those done by the auto-
1702 // update action, we set the value immediately.
1703 const Product* chrome = installer_state.FindProduct(
1704 BrowserDistribution::CHROME_BROWSER);
1705 if (chrome != NULL) {
1706 // Get the app's MSI Product-ID from an entry in ClientState.
1707 base::string16 app_guid = FindMsiProductId(installer_state, chrome);
1708 if (!app_guid.empty()) {
1709 OverwriteDisplayVersions(app_guid,
1710 base::UTF8ToUTF16(
1711 installer_version->GetString()));
1712 }
1713 }
1665 } 1714 }
1666 // Return the path to the directory containing the newly installed 1715 // Return the path to the directory containing the newly installed
1667 // setup.exe and uncompressed archive if the caller requested it. 1716 // setup.exe and uncompressed archive if the caller requested it.
1668 if (installer_directory) { 1717 if (installer_directory) {
1669 *installer_directory = 1718 *installer_directory =
1670 installer_state.GetInstallerDirectory(*installer_version); 1719 installer_state.GetInstallerDirectory(*installer_version);
1671 } 1720 }
1672 } 1721 }
1673 1722
1674 // temp_path's dtor will take care of deleting or scheduling itself for 1723 // temp_path's dtor will take care of deleting or scheduling itself for
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1826 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT 1875 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT
1827 // to pass through, since this is only returned on uninstall which is 1876 // to pass through, since this is only returned on uninstall which is
1828 // never invoked directly by Google Update. 1877 // never invoked directly by Google Update.
1829 return_code = InstallUtil::GetInstallReturnCode(install_status); 1878 return_code = InstallUtil::GetInstallReturnCode(install_status);
1830 } 1879 }
1831 1880
1832 VLOG(1) << "Installation complete, returning: " << return_code; 1881 VLOG(1) << "Installation complete, returning: " << return_code;
1833 1882
1834 return return_code; 1883 return return_code;
1835 } 1884 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698