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 |