OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <windows.h> | 5 #include <windows.h> |
6 #include <msi.h> | 6 #include <msi.h> |
7 #include <shellapi.h> | 7 #include <shellapi.h> |
8 #include <shlobj.h> | 8 #include <shlobj.h> |
9 | 9 |
10 #include <string> | 10 #include <string> |
(...skipping 12 matching lines...) Expand all Loading... | |
23 #include "base/values.h" | 23 #include "base/values.h" |
24 #include "base/win/registry.h" | 24 #include "base/win/registry.h" |
25 #include "base/win/scoped_handle.h" | 25 #include "base/win/scoped_handle.h" |
26 #include "base/win/win_util.h" | 26 #include "base/win/win_util.h" |
27 #include "base/win/windows_version.h" | 27 #include "base/win/windows_version.h" |
28 #include "breakpad/src/client/windows/handler/exception_handler.h" | 28 #include "breakpad/src/client/windows/handler/exception_handler.h" |
29 #include "chrome/common/chrome_switches.h" | 29 #include "chrome/common/chrome_switches.h" |
30 #include "chrome/installer/setup/chrome_frame_quick_enable.h" | 30 #include "chrome/installer/setup/chrome_frame_quick_enable.h" |
31 #include "chrome/installer/setup/chrome_frame_ready_mode.h" | 31 #include "chrome/installer/setup/chrome_frame_ready_mode.h" |
32 #include "chrome/installer/setup/install.h" | 32 #include "chrome/installer/setup/install.h" |
33 #include "chrome/installer/setup/install_worker.h" | |
33 #include "chrome/installer/setup/setup_constants.h" | 34 #include "chrome/installer/setup/setup_constants.h" |
34 #include "chrome/installer/setup/setup_util.h" | 35 #include "chrome/installer/setup/setup_util.h" |
35 #include "chrome/installer/setup/uninstall.h" | 36 #include "chrome/installer/setup/uninstall.h" |
36 #include "chrome/installer/util/browser_distribution.h" | 37 #include "chrome/installer/util/browser_distribution.h" |
37 #include "chrome/installer/util/channel_info.h" | 38 #include "chrome/installer/util/channel_info.h" |
38 #include "chrome/installer/util/delete_after_reboot_helper.h" | 39 #include "chrome/installer/util/delete_after_reboot_helper.h" |
39 #include "chrome/installer/util/delete_tree_work_item.h" | 40 #include "chrome/installer/util/delete_tree_work_item.h" |
40 #include "chrome/installer/util/google_update_constants.h" | 41 #include "chrome/installer/util/google_update_constants.h" |
41 #include "chrome/installer/util/google_update_settings.h" | 42 #include "chrome/installer/util/google_update_settings.h" |
42 #include "chrome/installer/util/helper.h" | 43 #include "chrome/installer/util/helper.h" |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
162 } | 163 } |
163 } | 164 } |
164 } | 165 } |
165 } | 166 } |
166 | 167 |
167 // This function is called when --rename-chrome-exe option is specified on | 168 // This function is called when --rename-chrome-exe option is specified on |
168 // setup.exe command line. This function assumes an in-use update has happened | 169 // setup.exe command line. This function assumes an in-use update has happened |
169 // for Chrome so there should be a file called new_chrome.exe on the file | 170 // for Chrome so there should be a file called new_chrome.exe on the file |
170 // system and a key called 'opv' in the registry. This function will move | 171 // system and a key called 'opv' in the registry. This function will move |
171 // new_chrome.exe to chrome.exe and delete 'opv' key in one atomic operation. | 172 // new_chrome.exe to chrome.exe and delete 'opv' key in one atomic operation. |
173 // This function also deletes elevation policies associated with the old version | |
174 // if they exist. | |
172 installer::InstallStatus RenameChromeExecutables( | 175 installer::InstallStatus RenameChromeExecutables( |
173 const InstallationState& original_state, | 176 const InstallationState& original_state, |
174 InstallerState* installer_state) { | 177 InstallerState* installer_state) { |
175 // See what products are already installed in multi mode. When we do the | 178 // See what products are already installed in multi mode. When we do the |
176 // rename for multi installs, we must update all installations since they | 179 // rename for multi installs, we must update all installations since they |
177 // share the binaries. | 180 // share the binaries. |
178 AddExistingMultiInstalls(original_state, installer_state); | 181 AddExistingMultiInstalls(original_state, installer_state); |
179 const FilePath &target_path = installer_state->target_path(); | 182 const FilePath &target_path = installer_state->target_path(); |
180 FilePath chrome_exe(target_path.Append(installer::kChromeExe)); | 183 FilePath chrome_exe(target_path.Append(installer::kChromeExe)); |
181 FilePath chrome_new_exe(target_path.Append(installer::kChromeNewExe)); | 184 FilePath chrome_new_exe(target_path.Append(installer::kChromeNewExe)); |
(...skipping 13 matching lines...) Expand all Loading... | |
195 // Move chrome.exe to old_chrome.exe, then move new_chrome.exe to chrome.exe. | 198 // Move chrome.exe to old_chrome.exe, then move new_chrome.exe to chrome.exe. |
196 install_list->AddMoveTreeWorkItem(chrome_exe.value(), | 199 install_list->AddMoveTreeWorkItem(chrome_exe.value(), |
197 chrome_old_exe.value(), | 200 chrome_old_exe.value(), |
198 temp_path.path().value(), | 201 temp_path.path().value(), |
199 WorkItem::ALWAYS_MOVE); | 202 WorkItem::ALWAYS_MOVE); |
200 install_list->AddMoveTreeWorkItem(chrome_new_exe.value(), | 203 install_list->AddMoveTreeWorkItem(chrome_new_exe.value(), |
201 chrome_exe.value(), | 204 chrome_exe.value(), |
202 temp_path.path().value(), | 205 temp_path.path().value(), |
203 WorkItem::ALWAYS_MOVE); | 206 WorkItem::ALWAYS_MOVE); |
204 install_list->AddDeleteTreeWorkItem(chrome_new_exe, temp_path.path()); | 207 install_list->AddDeleteTreeWorkItem(chrome_new_exe, temp_path.path()); |
208 // Delete an elevation policy associated with the old version, should one | |
209 // exist. | |
robertshield
2011/09/22 20:34:10
Drop the Maybe, wrap this in an "if we're doing CF
grt (UTC plus 2)
2011/09/23 18:21:07
Done.
| |
210 installer::MaybeAddDeleteOldIELowRightsPolicyWorkItems(*installer_state, | |
211 install_list.get()); | |
205 // old_chrome.exe is still in use in most cases, so ignore failures here. | 212 // old_chrome.exe is still in use in most cases, so ignore failures here. |
206 install_list->AddDeleteTreeWorkItem(chrome_old_exe, temp_path.path()) | 213 install_list->AddDeleteTreeWorkItem(chrome_old_exe, temp_path.path()) |
207 ->set_ignore_failure(true); | 214 ->set_ignore_failure(true); |
208 | 215 |
209 // Collect the set of distributions we need to update, which is the | 216 // Collect the set of distributions we need to update, which is the |
210 // multi-install binaries (if this is a multi-install operation) and all | 217 // multi-install binaries (if this is a multi-install operation) and all |
211 // products we're operating on. | 218 // products we're operating on. |
212 BrowserDistribution* dists[BrowserDistribution::NUM_TYPES]; | 219 BrowserDistribution* dists[BrowserDistribution::NUM_TYPES]; |
213 int num_dists = 0; | 220 int num_dists = 0; |
214 // First, add the multi-install binaries, if relevant. | 221 // First, add the multi-install binaries, if relevant. |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
583 VLOG(1) << "unpacked to " << unpack_path.value(); | 590 VLOG(1) << "unpacked to " << unpack_path.value(); |
584 FilePath src_path(unpack_path.Append(installer::kInstallSourceChromeDir)); | 591 FilePath src_path(unpack_path.Append(installer::kInstallSourceChromeDir)); |
585 scoped_ptr<Version> | 592 scoped_ptr<Version> |
586 installer_version(installer::GetMaxVersionFromArchiveDir(src_path)); | 593 installer_version(installer::GetMaxVersionFromArchiveDir(src_path)); |
587 if (!installer_version.get()) { | 594 if (!installer_version.get()) { |
588 LOG(ERROR) << "Did not find any valid version in installer."; | 595 LOG(ERROR) << "Did not find any valid version in installer."; |
589 install_status = installer::INVALID_ARCHIVE; | 596 install_status = installer::INVALID_ARCHIVE; |
590 installer_state.WriteInstallerResult(install_status, | 597 installer_state.WriteInstallerResult(install_status, |
591 IDS_INSTALL_INVALID_ARCHIVE_BASE, NULL); | 598 IDS_INSTALL_INVALID_ARCHIVE_BASE, NULL); |
592 } else { | 599 } else { |
593 // TODO(tommi): Move towards having only a single version that is common | |
594 // to all products. Only the package should have a version since it | |
595 // represents all the binaries. When a single product is upgraded, all | |
596 // currently installed product for the shared binary installation, should | |
597 // (or rather must) be upgraded. | |
598 VLOG(1) << "version to install: " << installer_version->GetString(); | 600 VLOG(1) << "version to install: " << installer_version->GetString(); |
599 bool proceed_with_installation = true; | 601 bool proceed_with_installation = true; |
600 uint32 higher_products = 0; | 602 uint32 higher_products = 0; |
601 COMPILE_ASSERT( | 603 COMPILE_ASSERT( |
602 sizeof(higher_products) * 8 > BrowserDistribution::NUM_TYPES, | 604 sizeof(higher_products) * 8 > BrowserDistribution::NUM_TYPES, |
603 too_many_distribution_types_); | 605 too_many_distribution_types_); |
604 for (size_t i = 0; i < installer_state.products().size(); ++i) { | 606 for (size_t i = 0; i < installer_state.products().size(); ++i) { |
605 const Product* product = installer_state.products()[i]; | 607 const Product* product = installer_state.products()[i]; |
606 const ProductState* product_state = | 608 const ProductState* product_state = |
607 original_state.GetProductState(system_install, | 609 original_state.GetProductState(system_install, |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
799 } | 801 } |
800 | 802 |
801 installer_state->UpdateStage(installer::NO_STAGE); | 803 installer_state->UpdateStage(installer::NO_STAGE); |
802 return install_status; | 804 return install_status; |
803 } | 805 } |
804 | 806 |
805 installer::InstallStatus UninstallProduct( | 807 installer::InstallStatus UninstallProduct( |
806 const InstallationState& original_state, | 808 const InstallationState& original_state, |
807 const InstallerState& installer_state, | 809 const InstallerState& installer_state, |
808 const CommandLine& cmd_line, | 810 const CommandLine& cmd_line, |
811 bool remove_all, | |
812 bool force_uninstall, | |
809 const Product& product) { | 813 const Product& product) { |
810 bool force = cmd_line.HasSwitch(installer::switches::kForceUninstall); | |
811 const ProductState* product_state = | 814 const ProductState* product_state = |
812 original_state.GetProductState(installer_state.system_install(), | 815 original_state.GetProductState(installer_state.system_install(), |
813 product.distribution()->GetType()); | 816 product.distribution()->GetType()); |
814 if (product_state != NULL) { | 817 if (product_state != NULL) { |
815 VLOG(1) << "version on the system: " | 818 VLOG(1) << "version on the system: " |
816 << product_state->version().GetString(); | 819 << product_state->version().GetString(); |
817 } else if (!force) { | 820 } else if (!force_uninstall) { |
818 LOG(ERROR) << "No Chrome installation found for uninstall."; | 821 LOG(ERROR) << product.distribution()->GetAppShortCutName() |
822 << " not found for uninstall."; | |
819 return installer::CHROME_NOT_INSTALLED; | 823 return installer::CHROME_NOT_INSTALLED; |
820 } | 824 } |
821 | 825 |
822 bool remove_all = !cmd_line.HasSwitch( | 826 return installer::UninstallProduct(original_state, installer_state, |
827 cmd_line.GetProgram(), product, remove_all, force_uninstall, cmd_line); | |
828 } | |
829 | |
830 installer::InstallStatus UninstallProducts( | |
831 const InstallationState& original_state, | |
832 const InstallerState& installer_state, | |
833 const CommandLine& cmd_line) { | |
834 const Products& products = installer_state.products(); | |
835 // InstallerState::Initialize always puts Chrome first, and we rely on that | |
836 // here for this reason: if Chrome is in-use, the user will be prompted to | |
837 // confirm uninstallation. Upon cancel, we should not continue with the | |
838 // other products. | |
839 DCHECK(products.size() < 2 || products[0]->is_chrome()); | |
840 installer::InstallStatus install_status = installer::UNINSTALL_SUCCESSFUL; | |
841 installer::InstallStatus prod_status = installer::UNKNOWN_STATUS; | |
842 const bool force = cmd_line.HasSwitch(installer::switches::kForceUninstall); | |
843 const bool remove_all = !cmd_line.HasSwitch( | |
823 installer::switches::kDoNotRemoveSharedItems); | 844 installer::switches::kDoNotRemoveSharedItems); |
824 | 845 |
825 return installer::UninstallProduct(original_state, installer_state, | 846 for (size_t i = 0; |
826 cmd_line.GetProgram(), product, remove_all, force, cmd_line); | 847 install_status != installer::UNINSTALL_CANCELLED && |
848 i < products.size(); | |
849 ++i) { | |
850 prod_status = UninstallProduct(original_state, installer_state, | |
851 cmd_line, remove_all, force, *products[i]); | |
852 if (prod_status != installer::UNINSTALL_SUCCESSFUL) | |
853 install_status = prod_status; | |
854 } | |
855 | |
856 return install_status; | |
827 } | 857 } |
828 | 858 |
829 installer::InstallStatus ShowEULADialog(const std::wstring& inner_frame) { | 859 installer::InstallStatus ShowEULADialog(const std::wstring& inner_frame) { |
830 VLOG(1) << "About to show EULA"; | 860 VLOG(1) << "About to show EULA"; |
831 std::wstring eula_path = installer::GetLocalizedEulaResource(); | 861 std::wstring eula_path = installer::GetLocalizedEulaResource(); |
832 if (eula_path.empty()) { | 862 if (eula_path.empty()) { |
833 LOG(ERROR) << "No EULA path available"; | 863 LOG(ERROR) << "No EULA path available"; |
834 return installer::EULA_REJECTED; | 864 return installer::EULA_REJECTED; |
835 } | 865 } |
836 // Newer versions of the caller pass an inner frame parameter that must | 866 // Newer versions of the caller pass an inner frame parameter that must |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1253 LOG(ERROR) << "Non admin user can not install system level Chrome."; | 1283 LOG(ERROR) << "Non admin user can not install system level Chrome."; |
1254 installer_state.WriteInstallerResult(installer::INSUFFICIENT_RIGHTS, | 1284 installer_state.WriteInstallerResult(installer::INSUFFICIENT_RIGHTS, |
1255 IDS_INSTALL_INSUFFICIENT_RIGHTS_BASE, NULL); | 1285 IDS_INSTALL_INSUFFICIENT_RIGHTS_BASE, NULL); |
1256 return installer::INSUFFICIENT_RIGHTS; | 1286 return installer::INSUFFICIENT_RIGHTS; |
1257 } | 1287 } |
1258 } | 1288 } |
1259 | 1289 |
1260 installer::InstallStatus install_status = installer::UNKNOWN_STATUS; | 1290 installer::InstallStatus install_status = installer::UNKNOWN_STATUS; |
1261 // If --uninstall option is given, uninstall the identified product(s) | 1291 // If --uninstall option is given, uninstall the identified product(s) |
1262 if (is_uninstall) { | 1292 if (is_uninstall) { |
1263 const Products& products = installer_state.products(); | 1293 install_status = UninstallProducts(original_state, installer_state, |
grt (UTC plus 2)
2011/09/22 19:28:35
note: i pulled this out into its own function sinc
robertshield
2011/09/22 20:34:10
bene
| |
1264 // InstallerState::Initialize always puts Chrome first, and we rely on that | 1294 cmd_line); |
1265 // here for this reason: if Chrome is in-use, the user will be prompted to | |
1266 // confirm uninstallation. Upon cancel, we should not continue with the | |
1267 // other products. | |
1268 DCHECK(products.size() < 2 || products[0]->is_chrome()); | |
1269 install_status = installer::UNINSTALL_SUCCESSFUL; // I'm an optimist. | |
1270 installer::InstallStatus prod_status = installer::UNKNOWN_STATUS; | |
1271 for (size_t i = 0; | |
1272 install_status != installer::UNINSTALL_CANCELLED && | |
1273 i < products.size(); | |
1274 ++i) { | |
1275 prod_status = UninstallProduct(original_state, installer_state, | |
1276 cmd_line, *products[i]); | |
1277 if (prod_status != installer::UNINSTALL_SUCCESSFUL) | |
1278 install_status = prod_status; | |
1279 } | |
1280 } else { | 1295 } else { |
1281 // If --uninstall option is not specified, we assume it is install case. | 1296 // If --uninstall option is not specified, we assume it is install case. |
1282 install_status = InstallProducts(original_state, cmd_line, prefs, | 1297 install_status = InstallProducts(original_state, cmd_line, prefs, |
1283 &installer_state); | 1298 &installer_state); |
1284 } | 1299 } |
1285 | 1300 |
1286 // Validate that the machine is now in a good state following the operation. | 1301 // Validate that the machine is now in a good state following the operation. |
1287 // TODO(grt): change this to log at DFATAL once we're convinced that the | 1302 // TODO(grt): change this to log at DFATAL once we're convinced that the |
1288 // validator handles all cases properly. | 1303 // validator handles all cases properly. |
1289 InstallationValidator::InstallationType installation_type = | 1304 InstallationValidator::InstallationType installation_type = |
(...skipping 29 matching lines...) Expand all Loading... | |
1319 if (!(installer_state.is_msi() && is_uninstall)) | 1334 if (!(installer_state.is_msi() && is_uninstall)) |
1320 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT | 1335 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT |
1321 // to pass through, since this is only returned on uninstall which is | 1336 // to pass through, since this is only returned on uninstall which is |
1322 // never invoked directly by Google Update. | 1337 // never invoked directly by Google Update. |
1323 return_code = InstallUtil::GetInstallReturnCode(install_status); | 1338 return_code = InstallUtil::GetInstallReturnCode(install_status); |
1324 | 1339 |
1325 VLOG(1) << "Installation complete, returning: " << return_code; | 1340 VLOG(1) << "Installation complete, returning: " << return_code; |
1326 | 1341 |
1327 return return_code; | 1342 return return_code; |
1328 } | 1343 } |
OLD | NEW |