Chromium Code Reviews| 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 <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 "base/at_exit.h" | 10 #include "base/at_exit.h" |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 // Delete an elevation policy associated with the old version, should one | 210 // Delete an elevation policy associated with the old version, should one |
| 211 // exist. | 211 // exist. |
| 212 if (installer_state->FindProduct(BrowserDistribution::CHROME_FRAME)) { | 212 if (installer_state->FindProduct(BrowserDistribution::CHROME_FRAME)) { |
| 213 installer::AddDeleteOldIELowRightsPolicyWorkItems(*installer_state, | 213 installer::AddDeleteOldIELowRightsPolicyWorkItems(*installer_state, |
| 214 install_list.get()); | 214 install_list.get()); |
| 215 } | 215 } |
| 216 // old_chrome.exe is still in use in most cases, so ignore failures here. | 216 // old_chrome.exe is still in use in most cases, so ignore failures here. |
| 217 install_list->AddDeleteTreeWorkItem(chrome_old_exe, temp_path.path()) | 217 install_list->AddDeleteTreeWorkItem(chrome_old_exe, temp_path.path()) |
| 218 ->set_ignore_failure(true); | 218 ->set_ignore_failure(true); |
| 219 | 219 |
| 220 // Collect the set of distributions we need to update, which is the | 220 // Collect the set of distributions we need to update, which is all |
| 221 // multi-install binaries (if this is a multi-install operation) and all | 221 // products we're operating on (this includes the multi-install binaries). |
| 222 // products we're operating on. | |
| 223 BrowserDistribution* dists[BrowserDistribution::NUM_TYPES]; | 222 BrowserDistribution* dists[BrowserDistribution::NUM_TYPES]; |
| 224 int num_dists = 0; | 223 int num_dists = 0; |
| 225 // First, add the multi-install binaries, if relevant. | 224 // std::transform can handily do this for us, but this is discouraged as |
| 226 if (installer_state->is_multi_install()) | 225 // being too tricky. |
|
robertshield
2012/07/24 17:16:50
Grumbling noted, but the above comment doesn't mak
grt (UTC plus 2)
2012/07/24 20:31:29
I briefly changed the comment to "I hate robertshi
robertshield
2012/07/24 21:03:14
concise != readable
grt (UTC plus 2)
2012/07/24 21:06:00
LOL, BFF
| |
| 227 dists[num_dists++] = installer_state->multi_package_binaries_distribution(); | |
| 228 // Next, add all products we're operating on. std::transform can handily do | |
| 229 // this for us, but this is discouraged as being too tricky. | |
| 230 const Products& products = installer_state->products(); | 226 const Products& products = installer_state->products(); |
| 231 for (Products::size_type i = 0; i < products.size(); ++i) { | 227 CHECK_LE(products.size(), arraysize(dists)); |
| 228 for (size_t i = 0; i < products.size(); ++i) | |
| 232 dists[num_dists++] = products[i]->distribution(); | 229 dists[num_dists++] = products[i]->distribution(); |
|
robertshield
2012/07/24 17:16:50
nit: It seems to me that num_dists could be done a
grt (UTC plus 2)
2012/07/24 20:31:29
What?!?? There's a forest around these trees? D
| |
| 233 } | |
| 234 | 230 |
| 235 // Add work items to delete the "opv", "cpv", and "cmd" values from all | 231 // Add work items to delete the "opv", "cpv", and "cmd" values from all |
| 236 // distributions. | 232 // distributions. |
| 237 HKEY reg_root = installer_state->root_key(); | 233 HKEY reg_root = installer_state->root_key(); |
| 238 string16 version_key; | 234 string16 version_key; |
| 239 for (int i = 0; i < num_dists; ++i) { | 235 for (int i = 0; i < num_dists; ++i) { |
| 240 version_key = dists[i]->GetVersionKey(); | 236 version_key = dists[i]->GetVersionKey(); |
| 241 install_list->AddDeleteRegValueWorkItem( | 237 install_list->AddDeleteRegValueWorkItem( |
| 242 reg_root, version_key, google_update::kRegOldVersionField); | 238 reg_root, version_key, google_update::kRegOldVersionField); |
| 243 install_list->AddDeleteRegValueWorkItem( | 239 install_list->AddDeleteRegValueWorkItem( |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 const ProductState* chrome_state = | 368 const ProductState* chrome_state = |
| 373 original_state.GetProductState(system_level, | 369 original_state.GetProductState(system_level, |
| 374 BrowserDistribution::CHROME_BROWSER); | 370 BrowserDistribution::CHROME_BROWSER); |
| 375 | 371 |
| 376 if (!binaries) { | 372 if (!binaries) { |
| 377 if (app_host && !chrome && !chrome_frame && !cf_state && !chrome_state) { | 373 if (app_host && !chrome && !chrome_frame && !cf_state && !chrome_state) { |
| 378 DCHECK(!system_level); | 374 DCHECK(!system_level); |
| 379 // App Host may use Chrome/Chrome binaries at system-level. | 375 // App Host may use Chrome/Chrome binaries at system-level. |
| 380 if (original_state.GetProductState( | 376 if (original_state.GetProductState( |
| 381 true, // system | 377 true, // system |
| 382 BrowserDistribution::CHROME_BROWSER) || | 378 BrowserDistribution::CHROME_BROWSER) || |
|
robertshield
2012/07/24 17:16:50
Shouldn't this only be checking for the "Chrome bi
grt (UTC plus 2)
2012/07/24 20:31:29
I discussed this with Erik, and I believe that thi
| |
| 383 original_state.GetProductState( | 379 original_state.GetProductState( |
| 384 true, // system | 380 true, // system |
| 385 BrowserDistribution::CHROME_BINARIES)) { | 381 BrowserDistribution::CHROME_BINARIES)) { |
| 382 VLOG(1) << "Installing/updating Application Host without binaries."; | |
| 386 return true; | 383 return true; |
| 387 } else { | 384 } else { |
| 385 // Somehow the binaries were present when the quick-enable app host | |
| 386 // command was run, but now they appear to be missing. | |
| 387 // TODO(erikwright): should the binaries be implicitly added? | |
| 388 LOG(ERROR) << "Cannot install Application Host without binaries."; | |
| 389 *status = installer::APP_HOST_REQUIRES_BINARIES; | |
| 390 installer_state->WriteInstallerResult(*status, 0, NULL); | |
| 388 return false; | 391 return false; |
| 389 } | 392 } |
| 390 } else { | 393 } else { |
| 391 // Every other scenario requires the binaries to be installed/updated | 394 // Every other scenario requires the binaries to be installed/updated |
| 392 // simultaneous to the main product. | 395 // simultaneous to the main product. This will only be hit if |
| 393 return false; | 396 // --multi-install is given with no products. see |
|
robertshield
2012/07/24 17:16:50
nit: simultaneous -> simultaneously, see -> See
grt (UTC plus 2)
2012/07/24 20:31:29
Done.
| |
| 397 // CheckPreInstallConditions for handling of this case. | |
| 398 return true; | |
| 394 } | 399 } |
| 395 } | 400 } |
| 396 | 401 |
| 397 if (chrome) { | 402 if (chrome) { |
| 398 if (chrome_frame && | 403 if (chrome_frame && |
| 399 chrome_frame->HasOption(installer::kOptionReadyMode)) { | 404 chrome_frame->HasOption(installer::kOptionReadyMode)) { |
| 400 // We're being asked to install Chrome with Chrome Frame in ready-mode. | 405 // We're being asked to install Chrome with Chrome Frame in ready-mode. |
| 401 // This is an optimistic operation: if a SxS install of Chrome Frame | 406 // This is an optimistic operation: if a SxS install of Chrome Frame |
| 402 // is already present, don't touch it; if a multi-install of Chrome | 407 // is already present, don't touch it; if a multi-install of Chrome |
| 403 // Frame is present, preserve its settings (ready-mode). | 408 // Frame is present, preserve its settings (ready-mode). |
| 404 if (cf_state != NULL) { | 409 if (cf_state != NULL) { |
| 405 installer_state->RemoveProduct(chrome_frame); | 410 installer_state->RemoveProduct(chrome_frame); |
| 406 chrome_frame = NULL; | 411 chrome_frame = NULL; |
| 407 if (cf_state->is_multi_install()) { | 412 if (cf_state->is_multi_install()) { |
| 408 chrome_frame = installer_state->AddProductFromState( | 413 chrome_frame = installer_state->AddProductFromState( |
| 409 BrowserDistribution::CHROME_FRAME, *cf_state); | 414 BrowserDistribution::CHROME_FRAME, *cf_state); |
| 410 VLOG(1) << "Upgrading existing multi-install Chrome Frame rather " | 415 VLOG(1) << "Upgrading existing multi-install Chrome Frame rather " |
| 411 "than installing in ready-mode."; | 416 "than installing in ready-mode."; |
| 412 } else { | 417 } else { |
| 413 VLOG(1) << "Skipping upgrade of single-install Chrome Frame rather " | 418 VLOG(1) << "Skipping upgrade of single-install Chrome Frame rather " |
| 414 "than installing in ready-mode."; | 419 "than installing in ready-mode."; |
| 415 } | 420 } |
| 416 } else { | 421 } else { |
| 417 VLOG(1) << "Performing initial install of Chrome Frame ready-mode."; | 422 VLOG(1) << "Performing initial install of Chrome Frame ready-mode."; |
| 418 } | 423 } |
| 419 } | 424 } |
| 420 } else if (chrome_state != NULL) { | 425 } else if (chrome_state) { |
| 421 // Chrome Frame is being installed in multi-install mode, and Chrome is | 426 // Chrome Frame or the Application Host is being installed in |
|
robertshield
2012/07/24 17:16:50
"Chrome Frame or the Application Host" -> "A produ
grt (UTC plus 2)
2012/07/24 20:31:29
Done.
| |
| 422 // already present. Add Chrome to the set of products (making it | 427 // multi-install mode, and Chrome is already present. Add Chrome to the |
| 423 // multi-install in the process) so that it is updated, too. | 428 // set of products (making it multi-install in the process) so that it is |
| 429 // updated, too. | |
| 424 scoped_ptr<Product> multi_chrome(new Product( | 430 scoped_ptr<Product> multi_chrome(new Product( |
| 425 BrowserDistribution::GetSpecificDistribution( | 431 BrowserDistribution::GetSpecificDistribution( |
| 426 BrowserDistribution::CHROME_BROWSER))); | 432 BrowserDistribution::CHROME_BROWSER))); |
| 427 multi_chrome->SetOption(installer::kOptionMultiInstall, true); | 433 multi_chrome->SetOption(installer::kOptionMultiInstall, true); |
| 428 chrome = installer_state->AddProduct(&multi_chrome); | 434 chrome = installer_state->AddProduct(&multi_chrome); |
| 429 VLOG(1) << "Upgrading existing Chrome browser in multi-install mode."; | 435 VLOG(1) << "Upgrading existing Chrome browser in multi-install mode."; |
| 430 } else if (chrome_frame && | 436 } else if (chrome_frame && |
| 431 chrome_frame->HasOption(installer::kOptionReadyMode)) { | 437 chrome_frame->HasOption(installer::kOptionReadyMode)) { |
| 432 // Chrome Frame with ready-mode is to be installed, yet Chrome is | 438 // Chrome Frame with ready-mode is to be installed, yet Chrome is |
| 433 // neither installed nor being installed. Fail. | 439 // neither installed nor being installed. Fail. |
| 434 LOG(ERROR) << "Cannot install Chrome Frame in ready mode without Chrome."; | 440 LOG(ERROR) << "Cannot install Chrome Frame in ready mode without Chrome."; |
| 435 *status = installer::READY_MODE_REQUIRES_CHROME; | 441 *status = installer::READY_MODE_REQUIRES_CHROME; |
| 436 installer_state->WriteInstallerResult( | 442 installer_state->WriteInstallerResult( |
| 437 *status, IDS_INSTALL_READY_MODE_REQUIRES_CHROME_BASE, NULL); | 443 *status, IDS_INSTALL_READY_MODE_REQUIRES_CHROME_BASE, NULL); |
| 438 return false; | 444 return false; |
| 439 } | 445 } |
| 440 | 446 |
| 441 // Fail if we're installing Chrome Frame when a single-install of it is | 447 // Fail if we're installing Chrome Frame when a single-install of it is |
| 442 // already installed. | 448 // already installed. |
| 443 // TODO(grt): Add support for migration of Chrome Frame from single- to | |
|
grt (UTC plus 2)
2012/07/24 15:02:03
we've decided not to do this, i believe.
| |
| 444 // multi-install. | |
| 445 if (chrome_frame && cf_state && !cf_state->is_multi_install()) { | 449 if (chrome_frame && cf_state && !cf_state->is_multi_install()) { |
| 446 LOG(ERROR) << "Cannot migrate existing Chrome Frame installation to " | 450 LOG(ERROR) << "Cannot migrate existing Chrome Frame installation to " |
| 447 << "multi-install."; | 451 << "multi-install."; |
| 448 *status = installer::NON_MULTI_INSTALLATION_EXISTS; | 452 *status = installer::NON_MULTI_INSTALLATION_EXISTS; |
| 449 installer_state->WriteInstallerResult(*status, | 453 installer_state->WriteInstallerResult(*status, |
| 450 IDS_INSTALL_NON_MULTI_INSTALLATION_EXISTS_BASE, NULL); | 454 IDS_INSTALL_NON_MULTI_INSTALLATION_EXISTS_BASE, NULL); |
| 451 return false; | 455 return false; |
| 452 } | 456 } |
| 453 } else { | 457 } else { |
| 454 // This is a non-multi installation. | 458 // This is a non-multi installation. |
| 455 | 459 |
| 456 // It isn't possible to stuff two products into a single-install | 460 // It isn't possible to stuff two products into a single-install |
| 457 // InstallerState. Abort the process here in debug builds just in case | 461 // InstallerState. Abort the process here in debug builds just in case |
| 458 // someone finds a way. | 462 // someone finds a way. |
| 459 DCHECK_EQ(1U, products.size()); | 463 DCHECK_EQ(1U, products.size()); |
| 460 if (products.size() != 1) | |
|
grt (UTC plus 2)
2012/07/24 15:02:03
erik added this, but i don't think it's necessary.
robertshield
2012/07/24 17:16:50
I believe you, but that isn't obvious from reading
grt (UTC plus 2)
2012/07/24 20:31:29
What part of "It isn't possible" do you not unders
robertshield
2012/07/24 21:03:14
I typically come across comments stating that "X i
grt (UTC plus 2)
2012/07/24 21:06:00
remind me to work on shutdown next.
| |
| 461 return false; | |
| 462 | 464 |
| 463 // Check for an existing installation of the product. | 465 // Check for an existing installation of the product. |
| 464 const ProductState* product_state = original_state.GetProductState( | 466 const ProductState* product_state = original_state.GetProductState( |
| 465 system_level, products[0]->distribution()->GetType()); | 467 system_level, products[0]->distribution()->GetType()); |
| 466 if (product_state != NULL) { | 468 if (product_state != NULL) { |
| 467 // Block downgrades from multi-install to single-install. | 469 // Block downgrades from multi-install to single-install. |
| 468 if (product_state->is_multi_install()) { | 470 if (product_state->is_multi_install()) { |
| 469 LOG(ERROR) << "Multi-install " | 471 LOG(ERROR) << "Multi-install " |
| 470 << products[0]->distribution()->GetAppShortCutName() | 472 << products[0]->distribution()->GetAppShortCutName() |
| 471 << " exists; aborting single install."; | 473 << " exists; aborting single install."; |
| 472 *status = installer::MULTI_INSTALLATION_EXISTS; | 474 *status = installer::MULTI_INSTALLATION_EXISTS; |
| 473 installer_state->WriteInstallerResult(*status, | 475 installer_state->WriteInstallerResult(*status, |
| 474 IDS_INSTALL_MULTI_INSTALLATION_EXISTS_BASE, NULL); | 476 IDS_INSTALL_MULTI_INSTALLATION_EXISTS_BASE, NULL); |
| 475 return false; | 477 return false; |
| 476 } | 478 } |
| 477 } | 479 } |
| 480 } | |
| 481 | |
| 482 return true; | |
| 483 } | |
| 484 | |
| 485 // Checks app host pre-install conditions, specifically that this is a | |
| 486 // user-level multi-install. When the pre-install conditions are not | |
| 487 // satisfied, the result is written to the registry (via WriteInstallerResult), | |
| 488 // |status| is set appropriately, and false is returned. | |
| 489 bool CheckAppHostPreconditions(const InstallationState& original_state, | |
| 490 InstallerState* installer_state, | |
| 491 installer::InstallStatus* status) { | |
| 492 if (installer_state->FindProduct(BrowserDistribution::CHROME_APP_HOST)) { | |
| 493 | |
| 494 if (!installer_state->is_multi_install()) { | |
| 495 LOG(DFATAL) << "Application Host requires multi install"; | |
|
grt (UTC plus 2)
2012/07/24 15:02:03
this means we're invoking ourselves wrong, which i
| |
| 496 *status = installer::APP_HOST_REQUIRES_MULTI_INSTALL; | |
| 497 // No message string since there is nothing a user can do. | |
| 498 installer_state->WriteInstallerResult(*status, 0, NULL); | |
| 499 return false; | |
| 500 } | |
| 501 | |
| 502 if (installer_state->system_install()) { | |
| 503 LOG(DFATAL) << "Application Host may only be installed at user-level."; | |
| 504 *status = installer::APP_HOST_REQUIRES_USER_LEVEL; | |
| 505 // No message string since there is nothing a user can do. | |
| 506 installer_state->WriteInstallerResult(*status, 0, NULL); | |
| 507 return false; | |
| 508 } | |
| 478 | 509 |
| 479 } | 510 } |
| 480 | 511 |
| 481 return true; | 512 return true; |
| 482 } | |
| 483 | |
| 484 bool CheckAppHostPreconditions(const InstallationState& original_state, | |
| 485 InstallerState* installer_state) { | |
| 486 if (!installer_state->FindProduct(BrowserDistribution::CHROME_APP_HOST)) | |
| 487 return true; | |
| 488 | |
| 489 if (!installer_state->is_multi_install()) { | |
| 490 VLOG(1) << "Application Host may only be installed in multi-install mode."; | |
| 491 return false; | |
| 492 } | |
| 493 | |
| 494 if (installer_state->system_install()) { | |
| 495 VLOG(1) << "Application Host may only be installed at user-level."; | |
| 496 return false; | |
| 497 } | |
| 498 | |
| 499 return true; | |
| 500 } | 513 } |
| 501 | 514 |
| 502 // Checks for compatibility between the current state of the system and the | 515 // Checks for compatibility between the current state of the system and the |
| 503 // desired operation. Also applies policy that mutates the desired operation; | 516 // desired operation. Also applies policy that mutates the desired operation; |
| 504 // specifically, the |installer_state| object. | 517 // specifically, the |installer_state| object. |
| 505 // Also blocks simultaneous user-level and system-level installs. In the case | 518 // Also blocks simultaneous user-level and system-level installs. In the case |
| 506 // of trying to install user-level Chrome when system-level exists, the | 519 // of trying to install user-level Chrome when system-level exists, the |
| 507 // existing system-level Chrome is launched. | 520 // existing system-level Chrome is launched. |
| 508 // When the pre-install conditions are not satisfied, the result is written to | 521 // When the pre-install conditions are not satisfied, the result is written to |
| 509 // the registry (via WriteInstallerResult), |status| is set appropriately, and | 522 // the registry (via WriteInstallerResult), |status| is set appropriately, and |
| 510 // false is returned. | 523 // false is returned. |
| 511 bool CheckPreInstallConditions(const InstallationState& original_state, | 524 bool CheckPreInstallConditions(const InstallationState& original_state, |
| 512 InstallerState* installer_state, | 525 InstallerState* installer_state, |
| 513 installer::InstallStatus* status) { | 526 installer::InstallStatus* status) { |
| 514 if (!CheckAppHostPreconditions(original_state, installer_state)) | 527 if (!CheckAppHostPreconditions(original_state, installer_state, status)) { |
| 528 DCHECK_NE(*status, installer::UNKNOWN_STATUS); | |
| 515 return false; | 529 return false; |
| 530 } | |
| 516 | 531 |
| 517 if (!CheckMultiInstallConditions(original_state, installer_state, status)) | 532 // See what products are already installed in multi mode. When we do multi |
| 533 // installs, we must upgrade all installations since they share the binaries. | |
| 534 AddExistingMultiInstalls(original_state, installer_state); | |
|
robertshield
2012/07/24 17:16:50
Out of curiosity, how did this work before with Ch
grt (UTC plus 2)
2012/07/24 20:31:29
It didn't -- this was the change that broke dev ch
| |
| 535 | |
| 536 if (!CheckMultiInstallConditions(original_state, installer_state, status)) { | |
| 537 DCHECK_NE(*status, installer::UNKNOWN_STATUS); | |
| 518 return false; | 538 return false; |
| 539 } | |
| 519 | 540 |
| 520 const Products& products = installer_state->products(); | 541 const Products& products = installer_state->products(); |
| 521 if (products.empty()) { | 542 if (products.empty()) { |
| 522 // We haven't been given any products on which to operate. | 543 // We haven't been given any products on which to operate. |
| 523 LOG(ERROR) | 544 LOG(ERROR) |
| 524 << "Not given any products to install and no products found to update."; | 545 << "Not given any products to install and no products found to update."; |
| 525 *status = installer::CHROME_NOT_INSTALLED; | 546 *status = installer::CHROME_NOT_INSTALLED; |
| 526 installer_state->WriteInstallerResult(*status, | 547 installer_state->WriteInstallerResult(*status, |
| 527 IDS_INSTALL_NO_PRODUCTS_TO_UPDATE_BASE, NULL); | 548 IDS_INSTALL_NO_PRODUCTS_TO_UPDATE_BASE, NULL); |
| 528 return false; | 549 return false; |
| 529 } | 550 } |
| 530 | 551 |
| 531 // See what products are already installed in multi mode. When we do multi | |
| 532 // installs, we must upgrade all installations since they share the binaries. | |
| 533 AddExistingMultiInstalls(original_state, installer_state); | |
| 534 | |
| 535 if (!installer_state->system_install()) { | 552 if (!installer_state->system_install()) { |
| 536 // This is a user-level installation. Make sure that we are not installing | 553 // This is a user-level installation. Make sure that we are not installing |
| 537 // on top of an existing system-level installation. | 554 // on top of an existing system-level installation. |
| 538 for (size_t i = 0; i < products.size(); ++i) { | 555 for (size_t i = 0; i < products.size(); ++i) { |
| 539 const Product* product = products[i]; | 556 const Product* product = products[i]; |
| 540 BrowserDistribution* browser_dist = product->distribution(); | 557 BrowserDistribution* browser_dist = product->distribution(); |
| 558 | |
| 559 // Skip over the binaries, as it's okay for them to be at both levels | |
| 560 // for different products. | |
| 561 if (browser_dist->GetType() == BrowserDistribution::CHROME_BINARIES) | |
| 562 continue; | |
| 563 | |
| 541 const ProductState* user_level_product_state = | 564 const ProductState* user_level_product_state = |
| 542 original_state.GetProductState(false, browser_dist->GetType()); | 565 original_state.GetProductState(false, browser_dist->GetType()); |
| 543 const ProductState* system_level_product_state = | 566 const ProductState* system_level_product_state = |
| 544 original_state.GetProductState(true, browser_dist->GetType()); | 567 original_state.GetProductState(true, browser_dist->GetType()); |
| 545 | 568 |
| 546 // Allow upgrades to proceed so that out-of-date versions are not left | 569 // Allow upgrades to proceed so that out-of-date versions are not left |
| 547 // around. | 570 // around. |
| 548 if (user_level_product_state) | 571 if (user_level_product_state) |
| 549 continue; | 572 continue; |
| 550 | 573 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 866 installer_state->UpdateStage(installer::PRECONDITIONS); | 889 installer_state->UpdateStage(installer::PRECONDITIONS); |
| 867 // The stage provides more fine-grained information than -multifail, so remove | 890 // The stage provides more fine-grained information than -multifail, so remove |
| 868 // the -multifail suffix from the Google Update "ap" value. | 891 // the -multifail suffix from the Google Update "ap" value. |
| 869 BrowserDistribution::GetSpecificDistribution(installer_state->state_type()) | 892 BrowserDistribution::GetSpecificDistribution(installer_state->state_type()) |
| 870 ->UpdateInstallStatus(system_install, archive_type, install_status); | 893 ->UpdateInstallStatus(system_install, archive_type, install_status); |
| 871 if (CheckPreInstallConditions(original_state, installer_state, | 894 if (CheckPreInstallConditions(original_state, installer_state, |
| 872 &install_status)) { | 895 &install_status)) { |
| 873 VLOG(1) << "Installing to " << installer_state->target_path().value(); | 896 VLOG(1) << "Installing to " << installer_state->target_path().value(); |
| 874 install_status = InstallProductsHelper( | 897 install_status = InstallProductsHelper( |
| 875 original_state, cmd_line, prefs, *installer_state, &archive_type); | 898 original_state, cmd_line, prefs, *installer_state, &archive_type); |
| 899 } else { | |
| 900 // CheckPreInstallConditions must set the status on failure. | |
| 901 DCHECK_NE(install_status, installer::UNKNOWN_STATUS); | |
| 876 } | 902 } |
| 877 | 903 |
| 878 const Products& products = installer_state->products(); | 904 const Products& products = installer_state->products(); |
| 879 | 905 |
| 880 for (size_t i = 0; i < products.size(); ++i) { | 906 for (size_t i = 0; i < products.size(); ++i) { |
| 881 const Product* product = products[i]; | 907 const Product* product = products[i]; |
| 882 product->distribution()->UpdateInstallStatus( | 908 product->distribution()->UpdateInstallStatus( |
| 883 system_install, archive_type, install_status); | 909 system_install, archive_type, install_status); |
| 884 } | 910 } |
| 885 if (installer_state->is_multi_install()) { | |
|
grt (UTC plus 2)
2012/07/24 15:02:03
this isn't needed anymore
| |
| 886 installer_state->multi_package_binaries_distribution()->UpdateInstallStatus( | |
| 887 system_install, archive_type, install_status); | |
| 888 } | |
| 889 | 911 |
| 890 installer_state->UpdateStage(installer::NO_STAGE); | 912 installer_state->UpdateStage(installer::NO_STAGE); |
| 891 return install_status; | 913 return install_status; |
| 892 } | 914 } |
| 893 | 915 |
| 894 installer::InstallStatus UninstallProduct( | 916 installer::InstallStatus UninstallProduct( |
| 895 const InstallationState& original_state, | 917 const InstallationState& original_state, |
| 896 const InstallerState& installer_state, | 918 const InstallerState& installer_state, |
| 897 const CommandLine& cmd_line, | 919 const CommandLine& cmd_line, |
| 898 bool remove_all, | 920 bool remove_all, |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1457 const Product* cf_install = | 1479 const Product* cf_install = |
| 1458 installer_state.FindProduct(BrowserDistribution::CHROME_FRAME); | 1480 installer_state.FindProduct(BrowserDistribution::CHROME_FRAME); |
| 1459 | 1481 |
| 1460 if (cf_install && | 1482 if (cf_install && |
| 1461 !cmd_line.HasSwitch(installer::switches::kForceUninstall)) { | 1483 !cmd_line.HasSwitch(installer::switches::kForceUninstall)) { |
| 1462 if (install_status == installer::UNINSTALL_REQUIRES_REBOOT) { | 1484 if (install_status == installer::UNINSTALL_REQUIRES_REBOOT) { |
| 1463 ShowRebootDialog(); | 1485 ShowRebootDialog(); |
| 1464 } else if (is_uninstall) { | 1486 } else if (is_uninstall) { |
| 1465 // Only show the message box if Chrome Frame was the only product being | 1487 // Only show the message box if Chrome Frame was the only product being |
| 1466 // uninstalled. | 1488 // uninstalled. |
| 1467 if (installer_state.products().size() == 1U) { | 1489 const Products& products = installer_state.products(); |
| 1490 int num_products = 0; | |
| 1491 for (size_t i = 0; i < products.size(); ++i) { | |
|
grt (UTC plus 2)
2012/07/24 15:02:03
this counting is needed now since the binaries may
| |
| 1492 if (!products[i]->is_chrome_binaries()) | |
| 1493 ++num_products; | |
| 1494 } | |
| 1495 if (num_products == 1U) { | |
| 1468 ::MessageBoxW(NULL, | 1496 ::MessageBoxW(NULL, |
| 1469 installer::GetLocalizedString( | 1497 installer::GetLocalizedString( |
| 1470 IDS_UNINSTALL_COMPLETE_BASE).c_str(), | 1498 IDS_UNINSTALL_COMPLETE_BASE).c_str(), |
| 1471 cf_install->distribution()->GetAppShortCutName().c_str(), | 1499 cf_install->distribution()->GetAppShortCutName().c_str(), |
| 1472 MB_OK); | 1500 MB_OK); |
| 1473 } | 1501 } |
| 1474 } | 1502 } |
| 1475 } | 1503 } |
| 1476 | 1504 |
| 1477 int return_code = 0; | 1505 int return_code = 0; |
| 1478 // MSI demands that custom actions always return 0 (ERROR_SUCCESS) or it will | 1506 // MSI demands that custom actions always return 0 (ERROR_SUCCESS) or it will |
| 1479 // rollback the action. If we're uninstalling we want to avoid this, so always | 1507 // rollback the action. If we're uninstalling we want to avoid this, so always |
| 1480 // report success, squashing any more informative return codes. | 1508 // report success, squashing any more informative return codes. |
| 1481 if (!(installer_state.is_msi() && is_uninstall)) | 1509 if (!(installer_state.is_msi() && is_uninstall)) |
| 1482 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT | 1510 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT |
| 1483 // to pass through, since this is only returned on uninstall which is | 1511 // to pass through, since this is only returned on uninstall which is |
| 1484 // never invoked directly by Google Update. | 1512 // never invoked directly by Google Update. |
| 1485 return_code = InstallUtil::GetInstallReturnCode(install_status); | 1513 return_code = InstallUtil::GetInstallReturnCode(install_status); |
| 1486 | 1514 |
| 1487 VLOG(1) << "Installation complete, returning: " << return_code; | 1515 VLOG(1) << "Installation complete, returning: " << return_code; |
| 1488 | 1516 |
| 1489 return return_code; | 1517 return return_code; |
| 1490 } | 1518 } |
| OLD | NEW |