OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |