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

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

Issue 7976045: Fix in-use updates for Chrome Frame. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Hey, it compiles! Created 9 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 | Annotate | Revision Log
OLDNEW
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
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
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
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.
210 if (installer_state->FindProduct(BrowserDistribution::CHROME_FRAME)) {
211 installer::AddDeleteOldIELowRightsPolicyWorkItems(*installer_state,
212 install_list.get());
213 }
205 // old_chrome.exe is still in use in most cases, so ignore failures here. 214 // old_chrome.exe is still in use in most cases, so ignore failures here.
206 install_list->AddDeleteTreeWorkItem(chrome_old_exe, temp_path.path()) 215 install_list->AddDeleteTreeWorkItem(chrome_old_exe, temp_path.path())
207 ->set_ignore_failure(true); 216 ->set_ignore_failure(true);
208 217
209 // Collect the set of distributions we need to update, which is the 218 // 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 219 // multi-install binaries (if this is a multi-install operation) and all
211 // products we're operating on. 220 // products we're operating on.
212 BrowserDistribution* dists[BrowserDistribution::NUM_TYPES]; 221 BrowserDistribution* dists[BrowserDistribution::NUM_TYPES];
213 int num_dists = 0; 222 int num_dists = 0;
214 // First, add the multi-install binaries, if relevant. 223 // First, add the multi-install binaries, if relevant.
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 VLOG(1) << "unpacked to " << unpack_path.value(); 592 VLOG(1) << "unpacked to " << unpack_path.value();
584 FilePath src_path(unpack_path.Append(installer::kInstallSourceChromeDir)); 593 FilePath src_path(unpack_path.Append(installer::kInstallSourceChromeDir));
585 scoped_ptr<Version> 594 scoped_ptr<Version>
586 installer_version(installer::GetMaxVersionFromArchiveDir(src_path)); 595 installer_version(installer::GetMaxVersionFromArchiveDir(src_path));
587 if (!installer_version.get()) { 596 if (!installer_version.get()) {
588 LOG(ERROR) << "Did not find any valid version in installer."; 597 LOG(ERROR) << "Did not find any valid version in installer.";
589 install_status = installer::INVALID_ARCHIVE; 598 install_status = installer::INVALID_ARCHIVE;
590 installer_state.WriteInstallerResult(install_status, 599 installer_state.WriteInstallerResult(install_status,
591 IDS_INSTALL_INVALID_ARCHIVE_BASE, NULL); 600 IDS_INSTALL_INVALID_ARCHIVE_BASE, NULL);
592 } else { 601 } 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(); 602 VLOG(1) << "version to install: " << installer_version->GetString();
599 bool proceed_with_installation = true; 603 bool proceed_with_installation = true;
600 uint32 higher_products = 0; 604 uint32 higher_products = 0;
601 COMPILE_ASSERT( 605 COMPILE_ASSERT(
602 sizeof(higher_products) * 8 > BrowserDistribution::NUM_TYPES, 606 sizeof(higher_products) * 8 > BrowserDistribution::NUM_TYPES,
603 too_many_distribution_types_); 607 too_many_distribution_types_);
604 for (size_t i = 0; i < installer_state.products().size(); ++i) { 608 for (size_t i = 0; i < installer_state.products().size(); ++i) {
605 const Product* product = installer_state.products()[i]; 609 const Product* product = installer_state.products()[i];
606 const ProductState* product_state = 610 const ProductState* product_state =
607 original_state.GetProductState(system_install, 611 original_state.GetProductState(system_install,
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 } 803 }
800 804
801 installer_state->UpdateStage(installer::NO_STAGE); 805 installer_state->UpdateStage(installer::NO_STAGE);
802 return install_status; 806 return install_status;
803 } 807 }
804 808
805 installer::InstallStatus UninstallProduct( 809 installer::InstallStatus UninstallProduct(
806 const InstallationState& original_state, 810 const InstallationState& original_state,
807 const InstallerState& installer_state, 811 const InstallerState& installer_state,
808 const CommandLine& cmd_line, 812 const CommandLine& cmd_line,
813 bool remove_all,
814 bool force_uninstall,
809 const Product& product) { 815 const Product& product) {
810 bool force = cmd_line.HasSwitch(installer::switches::kForceUninstall);
811 const ProductState* product_state = 816 const ProductState* product_state =
812 original_state.GetProductState(installer_state.system_install(), 817 original_state.GetProductState(installer_state.system_install(),
813 product.distribution()->GetType()); 818 product.distribution()->GetType());
814 if (product_state != NULL) { 819 if (product_state != NULL) {
815 VLOG(1) << "version on the system: " 820 VLOG(1) << "version on the system: "
816 << product_state->version().GetString(); 821 << product_state->version().GetString();
817 } else if (!force) { 822 } else if (!force_uninstall) {
818 LOG(ERROR) << "No Chrome installation found for uninstall."; 823 LOG(ERROR) << product.distribution()->GetAppShortCutName()
824 << " not found for uninstall.";
819 return installer::CHROME_NOT_INSTALLED; 825 return installer::CHROME_NOT_INSTALLED;
820 } 826 }
821 827
822 bool remove_all = !cmd_line.HasSwitch( 828 return installer::UninstallProduct(original_state, installer_state,
829 cmd_line.GetProgram(), product, remove_all, force_uninstall, cmd_line);
830 }
831
832 installer::InstallStatus UninstallProducts(
833 const InstallationState& original_state,
834 const InstallerState& installer_state,
835 const CommandLine& cmd_line) {
836 const Products& products = installer_state.products();
837 // InstallerState::Initialize always puts Chrome first, and we rely on that
838 // here for this reason: if Chrome is in-use, the user will be prompted to
839 // confirm uninstallation. Upon cancel, we should not continue with the
840 // other products.
841 DCHECK(products.size() < 2 || products[0]->is_chrome());
842 installer::InstallStatus install_status = installer::UNINSTALL_SUCCESSFUL;
843 installer::InstallStatus prod_status = installer::UNKNOWN_STATUS;
844 const bool force = cmd_line.HasSwitch(installer::switches::kForceUninstall);
845 const bool remove_all = !cmd_line.HasSwitch(
823 installer::switches::kDoNotRemoveSharedItems); 846 installer::switches::kDoNotRemoveSharedItems);
824 847
825 return installer::UninstallProduct(original_state, installer_state, 848 for (size_t i = 0;
826 cmd_line.GetProgram(), product, remove_all, force, cmd_line); 849 install_status != installer::UNINSTALL_CANCELLED &&
850 i < products.size();
851 ++i) {
852 prod_status = UninstallProduct(original_state, installer_state,
853 cmd_line, remove_all, force, *products[i]);
854 if (prod_status != installer::UNINSTALL_SUCCESSFUL)
855 install_status = prod_status;
856 }
857
858 return install_status;
827 } 859 }
828 860
829 installer::InstallStatus ShowEULADialog(const std::wstring& inner_frame) { 861 installer::InstallStatus ShowEULADialog(const std::wstring& inner_frame) {
830 VLOG(1) << "About to show EULA"; 862 VLOG(1) << "About to show EULA";
831 std::wstring eula_path = installer::GetLocalizedEulaResource(); 863 std::wstring eula_path = installer::GetLocalizedEulaResource();
832 if (eula_path.empty()) { 864 if (eula_path.empty()) {
833 LOG(ERROR) << "No EULA path available"; 865 LOG(ERROR) << "No EULA path available";
834 return installer::EULA_REJECTED; 866 return installer::EULA_REJECTED;
835 } 867 }
836 // Newer versions of the caller pass an inner frame parameter that must 868 // Newer versions of the caller pass an inner frame parameter that must
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 LOG(ERROR) << "Non admin user can not install system level Chrome."; 1285 LOG(ERROR) << "Non admin user can not install system level Chrome.";
1254 installer_state.WriteInstallerResult(installer::INSUFFICIENT_RIGHTS, 1286 installer_state.WriteInstallerResult(installer::INSUFFICIENT_RIGHTS,
1255 IDS_INSTALL_INSUFFICIENT_RIGHTS_BASE, NULL); 1287 IDS_INSTALL_INSUFFICIENT_RIGHTS_BASE, NULL);
1256 return installer::INSUFFICIENT_RIGHTS; 1288 return installer::INSUFFICIENT_RIGHTS;
1257 } 1289 }
1258 } 1290 }
1259 1291
1260 installer::InstallStatus install_status = installer::UNKNOWN_STATUS; 1292 installer::InstallStatus install_status = installer::UNKNOWN_STATUS;
1261 // If --uninstall option is given, uninstall the identified product(s) 1293 // If --uninstall option is given, uninstall the identified product(s)
1262 if (is_uninstall) { 1294 if (is_uninstall) {
1263 const Products& products = installer_state.products(); 1295 install_status = UninstallProducts(original_state, installer_state,
1264 // InstallerState::Initialize always puts Chrome first, and we rely on that 1296 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 { 1297 } else {
1281 // If --uninstall option is not specified, we assume it is install case. 1298 // If --uninstall option is not specified, we assume it is install case.
1282 install_status = InstallProducts(original_state, cmd_line, prefs, 1299 install_status = InstallProducts(original_state, cmd_line, prefs,
1283 &installer_state); 1300 &installer_state);
1284 } 1301 }
1285 1302
1286 // Validate that the machine is now in a good state following the operation. 1303 // 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 1304 // TODO(grt): change this to log at DFATAL once we're convinced that the
1288 // validator handles all cases properly. 1305 // validator handles all cases properly.
1289 InstallationValidator::InstallationType installation_type = 1306 InstallationValidator::InstallationType installation_type =
(...skipping 29 matching lines...) Expand all
1319 if (!(installer_state.is_msi() && is_uninstall)) 1336 if (!(installer_state.is_msi() && is_uninstall))
1320 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT 1337 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT
1321 // to pass through, since this is only returned on uninstall which is 1338 // to pass through, since this is only returned on uninstall which is
1322 // never invoked directly by Google Update. 1339 // never invoked directly by Google Update.
1323 return_code = InstallUtil::GetInstallReturnCode(install_status); 1340 return_code = InstallUtil::GetInstallReturnCode(install_status);
1324 1341
1325 VLOG(1) << "Installation complete, returning: " << return_code; 1342 VLOG(1) << "Installation complete, returning: " << return_code;
1326 1343
1327 return return_code; 1344 return return_code;
1328 } 1345 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698