| 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 // This file contains the definitions of the installer functions that build | 5 // This file contains the definitions of the installer functions that build |
| 6 // the WorkItemList used to install the application. | 6 // the WorkItemList used to install the application. |
| 7 | 7 |
| 8 #include "chrome/installer/setup/install_worker.h" | 8 #include "chrome/installer/setup/install_worker.h" |
| 9 | 9 |
| 10 #include <shlobj.h> | 10 #include <shlobj.h> |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 // Then, if we got some, attempt to unregister the DLLs from the old | 72 // Then, if we got some, attempt to unregister the DLLs from the old |
| 73 // version directory and then re-register them in the new one. | 73 // version directory and then re-register them in the new one. |
| 74 // Note that if we are migrating the install directory then we will not | 74 // Note that if we are migrating the install directory then we will not |
| 75 // successfully unregister the old DLLs. | 75 // successfully unregister the old DLLs. |
| 76 // TODO(robertshield): See whether we need to fix the migration case. | 76 // TODO(robertshield): See whether we need to fix the migration case. |
| 77 // TODO(robertshield): If we ever remove a DLL from a product, this will | 77 // TODO(robertshield): If we ever remove a DLL from a product, this will |
| 78 // not unregister it on update. We should build the unregistration list from | 78 // not unregister it on update. We should build the unregistration list from |
| 79 // saved state instead of assuming it is the same as the registration list. | 79 // saved state instead of assuming it is the same as the registration list. |
| 80 if (!com_dll_list.empty()) { | 80 if (!com_dll_list.empty()) { |
| 81 if (old_version) { | 81 if (old_version) { |
| 82 FilePath old_dll_path(installer_state.target_path().Append( | 82 FilePath old_dll_path(installer_state.target_path().AppendASCII( |
| 83 UTF8ToWide(old_version->GetString()))); | 83 old_version->GetString())); |
| 84 | 84 |
| 85 installer::AddRegisterComDllWorkItems(old_dll_path, | 85 installer::AddRegisterComDllWorkItems(old_dll_path, |
| 86 com_dll_list, | 86 com_dll_list, |
| 87 installer_state.system_install(), | 87 installer_state.system_install(), |
| 88 false, // Unregister | 88 false, // Unregister |
| 89 true, // May fail | 89 true, // May fail |
| 90 work_item_list); | 90 work_item_list); |
| 91 } | 91 } |
| 92 | 92 |
| 93 FilePath dll_path(installer_state.target_path().Append( | 93 FilePath dll_path(installer_state.target_path().AppendASCII( |
| 94 UTF8ToWide(new_version.GetString()))); | 94 new_version.GetString())); |
| 95 installer::AddRegisterComDllWorkItems(dll_path, | 95 installer::AddRegisterComDllWorkItems(dll_path, |
| 96 com_dll_list, | 96 com_dll_list, |
| 97 installer_state.system_install(), | 97 installer_state.system_install(), |
| 98 true, // Register | 98 true, // Register |
| 99 false, // Must succeed. | 99 false, // Must succeed. |
| 100 work_item_list); | 100 work_item_list); |
| 101 } | 101 } |
| 102 } | 102 } |
| 103 | 103 |
| 104 void AddInstallerCopyTasks(const InstallerState& installer_state, | 104 void AddInstallerCopyTasks(const InstallerState& installer_state, |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 } | 356 } |
| 357 | 357 |
| 358 // This is called when an MSI installation is run. It may be that a user is | 358 // This is called when an MSI installation is run. It may be that a user is |
| 359 // attempting to install the MSI on top of a non-MSI managed installation. | 359 // attempting to install the MSI on top of a non-MSI managed installation. |
| 360 // If so, try and remove any existing uninstallation shortcuts, as we want the | 360 // If so, try and remove any existing uninstallation shortcuts, as we want the |
| 361 // uninstall to be managed entirely by the MSI machinery (accessible via the | 361 // uninstall to be managed entirely by the MSI machinery (accessible via the |
| 362 // Add/Remove programs dialog). | 362 // Add/Remove programs dialog). |
| 363 void AddDeleteUninstallShortcutsForMSIWorkItems( | 363 void AddDeleteUninstallShortcutsForMSIWorkItems( |
| 364 const InstallerState& installer_state, | 364 const InstallerState& installer_state, |
| 365 const Product& product, | 365 const Product& product, |
| 366 const FilePath& temp_path, |
| 366 WorkItemList* work_item_list) { | 367 WorkItemList* work_item_list) { |
| 367 DCHECK(installer_state.is_msi()) | 368 DCHECK(installer_state.is_msi()) |
| 368 << "This must only be called for MSI installations!"; | 369 << "This must only be called for MSI installations!"; |
| 369 | 370 |
| 370 // First attempt to delete the old installation's ARP dialog entry. | 371 // First attempt to delete the old installation's ARP dialog entry. |
| 371 HKEY reg_root = installer_state.root_key(); | 372 HKEY reg_root = installer_state.root_key(); |
| 372 std::wstring uninstall_reg(product.distribution()->GetUninstallRegPath()); | 373 std::wstring uninstall_reg(product.distribution()->GetUninstallRegPath()); |
| 373 | 374 |
| 374 WorkItem* delete_reg_key = work_item_list->AddDeleteRegKeyWorkItem( | 375 WorkItem* delete_reg_key = work_item_list->AddDeleteRegKeyWorkItem( |
| 375 reg_root, uninstall_reg); | 376 reg_root, uninstall_reg); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 386 if (uninstall_link.empty()) { | 387 if (uninstall_link.empty()) { |
| 387 LOG(ERROR) << "Failed to get location for shortcut."; | 388 LOG(ERROR) << "Failed to get location for shortcut."; |
| 388 } else { | 389 } else { |
| 389 uninstall_link = uninstall_link.Append( | 390 uninstall_link = uninstall_link.Append( |
| 390 product.distribution()->GetAppShortCutName()); | 391 product.distribution()->GetAppShortCutName()); |
| 391 uninstall_link = uninstall_link.Append( | 392 uninstall_link = uninstall_link.Append( |
| 392 product.distribution()->GetUninstallLinkName() + L".lnk"); | 393 product.distribution()->GetUninstallLinkName() + L".lnk"); |
| 393 VLOG(1) << "Deleting old uninstall shortcut (if present): " | 394 VLOG(1) << "Deleting old uninstall shortcut (if present): " |
| 394 << uninstall_link.value(); | 395 << uninstall_link.value(); |
| 395 WorkItem* delete_link = work_item_list->AddDeleteTreeWorkItem( | 396 WorkItem* delete_link = work_item_list->AddDeleteTreeWorkItem( |
| 396 uninstall_link); | 397 uninstall_link, temp_path); |
| 397 delete_link->set_ignore_failure(true); | 398 delete_link->set_ignore_failure(true); |
| 398 delete_link->set_log_message( | 399 delete_link->set_log_message( |
| 399 "Failed to delete old uninstall shortcut."); | 400 "Failed to delete old uninstall shortcut."); |
| 400 } | 401 } |
| 401 } | 402 } |
| 402 | 403 |
| 403 // After a successful copying of all the files, this function is called to | 404 // After a successful copying of all the files, this function is called to |
| 404 // do a few post install tasks: | 405 // do a few post install tasks: |
| 405 // - Handle the case of in-use-update by updating "opv" (old version) key or | 406 // - Handle the case of in-use-update by updating "opv" (old version) key or |
| 406 // deleting it if not required. | 407 // deleting it if not required. |
| 407 // - Register any new dlls and unregister old dlls. | 408 // - Register any new dlls and unregister old dlls. |
| 408 // - If this is an MSI install, ensures that the MSI marker is set, and sets | 409 // - If this is an MSI install, ensures that the MSI marker is set, and sets |
| 409 // it if not. | 410 // it if not. |
| 410 // If these operations are successful, the function returns true, otherwise | 411 // If these operations are successful, the function returns true, otherwise |
| 411 // false. | 412 // false. |
| 412 bool AppendPostInstallTasks(const InstallerState& installer_state, | 413 bool AppendPostInstallTasks(const InstallerState& installer_state, |
| 413 const FilePath& setup_path, | 414 const FilePath& setup_path, |
| 414 const FilePath& new_chrome_exe, | 415 const FilePath& new_chrome_exe, |
| 415 const Version* current_version, | 416 const Version* current_version, |
| 416 const Version& new_version, | 417 const Version& new_version, |
| 418 const FilePath& temp_path, |
| 417 WorkItemList* post_install_task_list) { | 419 WorkItemList* post_install_task_list) { |
| 418 DCHECK(post_install_task_list); | 420 DCHECK(post_install_task_list); |
| 419 | 421 |
| 420 HKEY root = installer_state.root_key(); | 422 HKEY root = installer_state.root_key(); |
| 421 const Products& products = installer_state.products(); | 423 const Products& products = installer_state.products(); |
| 422 | 424 |
| 423 // Append work items that will only be executed if this was an update. | 425 // Append work items that will only be executed if this was an update. |
| 424 // We update the 'opv' key with the current version that is active and 'cmd' | 426 // We update the 'opv' key with the current version that is active and 'cmd' |
| 425 // key with the rename command to run. | 427 // key with the rename command to run. |
| 426 { | 428 { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 for (size_t i = 0; i < products.size(); ++i) { | 514 for (size_t i = 0; i < products.size(); ++i) { |
| 513 const Product* product = products[i]; | 515 const Product* product = products[i]; |
| 514 AddSetMsiMarkerWorkItem(installer_state, product->distribution(), true, | 516 AddSetMsiMarkerWorkItem(installer_state, product->distribution(), true, |
| 515 post_install_task_list); | 517 post_install_task_list); |
| 516 | 518 |
| 517 // We want MSI installs to take over the Add/Remove Programs shortcut. | 519 // We want MSI installs to take over the Add/Remove Programs shortcut. |
| 518 // Make a best-effort attempt to delete any shortcuts left over from | 520 // Make a best-effort attempt to delete any shortcuts left over from |
| 519 // previous non-MSI installations for the same type of install (system or | 521 // previous non-MSI installations for the same type of install (system or |
| 520 // per user). | 522 // per user). |
| 521 AddDeleteUninstallShortcutsForMSIWorkItems(installer_state, *product, | 523 AddDeleteUninstallShortcutsForMSIWorkItems(installer_state, *product, |
| 524 temp_path, |
| 522 post_install_task_list); | 525 post_install_task_list); |
| 523 } | 526 } |
| 524 if (installer_state.is_multi_install()) { | 527 if (installer_state.is_multi_install()) { |
| 525 AddSetMsiMarkerWorkItem(installer_state, | 528 AddSetMsiMarkerWorkItem(installer_state, |
| 526 installer_state.multi_package_binaries_distribution(), true, | 529 installer_state.multi_package_binaries_distribution(), true, |
| 527 post_install_task_list); | 530 post_install_task_list); |
| 528 } | 531 } |
| 529 } | 532 } |
| 530 | 533 |
| 531 return true; | 534 return true; |
| 532 } | 535 } |
| 533 | 536 |
| 534 void AddInstallWorkItems(const InstallationState& original_state, | 537 void AddInstallWorkItems(const InstallationState& original_state, |
| 535 const InstallerState& installer_state, | 538 const InstallerState& installer_state, |
| 536 const FilePath& setup_path, | 539 const FilePath& setup_path, |
| 537 const FilePath& archive_path, | 540 const FilePath& archive_path, |
| 538 const FilePath& src_path, | 541 const FilePath& src_path, |
| 539 const FilePath& temp_dir, | 542 const FilePath& temp_path, |
| 540 const Version& new_version, | 543 const Version& new_version, |
| 541 scoped_ptr<Version>* current_version, | 544 scoped_ptr<Version>* current_version, |
| 542 WorkItemList* install_list) { | 545 WorkItemList* install_list) { |
| 543 DCHECK(install_list); | 546 DCHECK(install_list); |
| 544 | 547 |
| 545 const FilePath& target_path = installer_state.target_path(); | 548 const FilePath& target_path = installer_state.target_path(); |
| 546 | 549 |
| 547 // A temp directory that work items need and the actual install directory. | 550 // A temp directory that work items need and the actual install directory. |
| 548 install_list->AddCreateDirWorkItem(temp_dir); | 551 install_list->AddCreateDirWorkItem(temp_path); |
| 549 install_list->AddCreateDirWorkItem(target_path); | 552 install_list->AddCreateDirWorkItem(target_path); |
| 550 | 553 |
| 551 // Delete any new_chrome.exe if present (we will end up creating a new one | 554 // Delete any new_chrome.exe if present (we will end up creating a new one |
| 552 // if required) and then copy chrome.exe | 555 // if required) and then copy chrome.exe |
| 553 FilePath new_chrome_exe( | 556 FilePath new_chrome_exe( |
| 554 target_path.Append(installer::kChromeNewExe)); | 557 target_path.Append(installer::kChromeNewExe)); |
| 555 | 558 |
| 556 install_list->AddDeleteTreeWorkItem(new_chrome_exe); | 559 install_list->AddDeleteTreeWorkItem(new_chrome_exe, temp_path); |
| 557 install_list->AddCopyTreeWorkItem( | 560 install_list->AddCopyTreeWorkItem( |
| 558 src_path.Append(installer::kChromeExe).value(), | 561 src_path.Append(installer::kChromeExe).value(), |
| 559 target_path.Append(installer::kChromeExe).value(), | 562 target_path.Append(installer::kChromeExe).value(), |
| 560 temp_dir.value(), WorkItem::NEW_NAME_IF_IN_USE, new_chrome_exe.value()); | 563 temp_path.value(), WorkItem::NEW_NAME_IF_IN_USE, new_chrome_exe.value()); |
| 561 | 564 |
| 562 // Extra executable for 64 bit systems. | 565 // Extra executable for 64 bit systems. |
| 563 if (Is64bit()) { | 566 if (Is64bit()) { |
| 564 install_list->AddCopyTreeWorkItem( | 567 install_list->AddCopyTreeWorkItem( |
| 565 src_path.Append(installer::kWowHelperExe).value(), | 568 src_path.Append(installer::kWowHelperExe).value(), |
| 566 target_path.Append(installer::kWowHelperExe).value(), | 569 target_path.Append(installer::kWowHelperExe).value(), |
| 567 temp_dir.value(), WorkItem::ALWAYS); | 570 temp_path.value(), WorkItem::ALWAYS); |
| 568 } | 571 } |
| 569 | 572 |
| 570 // If it is system level install copy the version folder (since we want to | 573 // If it is system level install copy the version folder (since we want to |
| 571 // take the permissions of %ProgramFiles% folder) otherwise just move it. | 574 // take the permissions of %ProgramFiles% folder) otherwise just move it. |
| 572 if (installer_state.system_install()) { | 575 if (installer_state.system_install()) { |
| 573 install_list->AddCopyTreeWorkItem( | 576 install_list->AddCopyTreeWorkItem( |
| 574 src_path.Append(UTF8ToWide(new_version.GetString())).value(), | 577 src_path.AppendASCII(new_version.GetString()).value(), |
| 575 target_path.Append(UTF8ToWide(new_version.GetString())).value(), | 578 target_path.AppendASCII(new_version.GetString()).value(), |
| 576 temp_dir.value(), WorkItem::ALWAYS); | 579 temp_path.value(), WorkItem::ALWAYS); |
| 577 } else { | 580 } else { |
| 578 install_list->AddMoveTreeWorkItem( | 581 install_list->AddMoveTreeWorkItem( |
| 579 src_path.Append(UTF8ToWide(new_version.GetString())).value(), | 582 src_path.AppendASCII(new_version.GetString()).value(), |
| 580 target_path.Append(UTF8ToWide(new_version.GetString())).value(), | 583 target_path.AppendASCII(new_version.GetString()).value(), |
| 581 temp_dir.value()); | 584 temp_path.value()); |
| 582 } | 585 } |
| 583 | 586 |
| 584 // Copy the default Dictionaries only if the folder doesn't exist already. | 587 // Copy the default Dictionaries only if the folder doesn't exist already. |
| 585 install_list->AddCopyTreeWorkItem( | 588 install_list->AddCopyTreeWorkItem( |
| 586 src_path.Append(installer::kDictionaries).value(), | 589 src_path.Append(installer::kDictionaries).value(), |
| 587 target_path.Append(installer::kDictionaries).value(), | 590 target_path.Append(installer::kDictionaries).value(), |
| 588 temp_dir.value(), WorkItem::IF_NOT_PRESENT); | 591 temp_path.value(), WorkItem::IF_NOT_PRESENT); |
| 589 | 592 |
| 590 // Delete any old_chrome.exe if present. | 593 // Delete any old_chrome.exe if present. |
| 591 install_list->AddDeleteTreeWorkItem( | 594 install_list->AddDeleteTreeWorkItem( |
| 592 target_path.Append(installer::kChromeOldExe)); | 595 target_path.Append(installer::kChromeOldExe), temp_path); |
| 593 | 596 |
| 594 // Copy installer in install directory and | 597 // Copy installer in install directory and |
| 595 // add shortcut in Control Panel->Add/Remove Programs. | 598 // add shortcut in Control Panel->Add/Remove Programs. |
| 596 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_dir, | 599 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_path, |
| 597 new_version, install_list); | 600 new_version, install_list); |
| 598 | 601 |
| 599 const HKEY root = installer_state.root_key(); | 602 const HKEY root = installer_state.root_key(); |
| 600 | 603 |
| 601 const Products& products = installer_state.products(); | 604 const Products& products = installer_state.products(); |
| 602 for (size_t i = 0; i < products.size(); ++i) { | 605 for (size_t i = 0; i < products.size(); ++i) { |
| 603 const Product* product = products[i]; | 606 const Product* product = products[i]; |
| 604 | 607 |
| 605 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version, | 608 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version, |
| 606 install_list, *product); | 609 install_list, *product); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 621 new_version, install_list); | 624 new_version, install_list); |
| 622 | 625 |
| 623 AddGoogleUpdateWorkItems(installer_state, install_list); | 626 AddGoogleUpdateWorkItems(installer_state, install_list); |
| 624 | 627 |
| 625 // Append the tasks that run after the installation. | 628 // Append the tasks that run after the installation. |
| 626 AppendPostInstallTasks(installer_state, | 629 AppendPostInstallTasks(installer_state, |
| 627 setup_path, | 630 setup_path, |
| 628 new_chrome_exe, | 631 new_chrome_exe, |
| 629 current_version->get(), | 632 current_version->get(), |
| 630 new_version, | 633 new_version, |
| 634 temp_path, |
| 631 install_list); | 635 install_list); |
| 632 } | 636 } |
| 633 | 637 |
| 634 void AddRegisterComDllWorkItems(const FilePath& dll_folder, | 638 void AddRegisterComDllWorkItems(const FilePath& dll_folder, |
| 635 const std::vector<FilePath>& dll_list, | 639 const std::vector<FilePath>& dll_list, |
| 636 bool system_level, | 640 bool system_level, |
| 637 bool do_register, | 641 bool do_register, |
| 638 bool ignore_failures, | 642 bool ignore_failures, |
| 639 WorkItemList* work_item_list) { | 643 WorkItemList* work_item_list) { |
| 640 DCHECK(work_item_list); | 644 DCHECK(work_item_list); |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 VLOG(1) << kIERefreshPolicy << " not supported."; | 905 VLOG(1) << kIERefreshPolicy << " not supported."; |
| 902 } | 906 } |
| 903 | 907 |
| 904 FreeLibrary(ieframe); | 908 FreeLibrary(ieframe); |
| 905 } else { | 909 } else { |
| 906 VLOG(1) << "Cannot load " << kIEFrameDll; | 910 VLOG(1) << "Cannot load " << kIEFrameDll; |
| 907 } | 911 } |
| 908 } | 912 } |
| 909 | 913 |
| 910 } // namespace installer | 914 } // namespace installer |
| OLD | NEW |