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 21 matching lines...) Expand all Loading... | |
32 #include "chrome/installer/setup/install_worker.h" | 32 #include "chrome/installer/setup/install_worker.h" |
33 #include "chrome/installer/setup/setup_constants.h" | 33 #include "chrome/installer/setup/setup_constants.h" |
34 #include "chrome/installer/setup/setup_util.h" | 34 #include "chrome/installer/setup/setup_util.h" |
35 #include "chrome/installer/setup/uninstall.h" | 35 #include "chrome/installer/setup/uninstall.h" |
36 #include "chrome/installer/util/browser_distribution.h" | 36 #include "chrome/installer/util/browser_distribution.h" |
37 #include "chrome/installer/util/channel_info.h" | 37 #include "chrome/installer/util/channel_info.h" |
38 #include "chrome/installer/util/delete_after_reboot_helper.h" | 38 #include "chrome/installer/util/delete_after_reboot_helper.h" |
39 #include "chrome/installer/util/delete_tree_work_item.h" | 39 #include "chrome/installer/util/delete_tree_work_item.h" |
40 #include "chrome/installer/util/google_update_constants.h" | 40 #include "chrome/installer/util/google_update_constants.h" |
41 #include "chrome/installer/util/google_update_settings.h" | 41 #include "chrome/installer/util/google_update_settings.h" |
42 #include "chrome/installer/util/google_update_util.h" | |
42 #include "chrome/installer/util/helper.h" | 43 #include "chrome/installer/util/helper.h" |
43 #include "chrome/installer/util/html_dialog.h" | 44 #include "chrome/installer/util/html_dialog.h" |
44 #include "chrome/installer/util/install_util.h" | 45 #include "chrome/installer/util/install_util.h" |
45 #include "chrome/installer/util/installation_state.h" | 46 #include "chrome/installer/util/installation_state.h" |
46 #include "chrome/installer/util/installation_validator.h" | 47 #include "chrome/installer/util/installation_validator.h" |
47 #include "chrome/installer/util/installer_state.h" | 48 #include "chrome/installer/util/installer_state.h" |
48 #include "chrome/installer/util/l10n_string_util.h" | 49 #include "chrome/installer/util/l10n_string_util.h" |
49 #include "chrome/installer/util/logging_installer.h" | 50 #include "chrome/installer/util/logging_installer.h" |
50 #include "chrome/installer/util/lzma_util.h" | 51 #include "chrome/installer/util/lzma_util.h" |
51 #include "chrome/installer/util/master_preferences.h" | 52 #include "chrome/installer/util/master_preferences.h" |
52 #include "chrome/installer/util/master_preferences_constants.h" | 53 #include "chrome/installer/util/master_preferences_constants.h" |
53 #include "chrome/installer/util/self_cleaning_temp_dir.h" | 54 #include "chrome/installer/util/self_cleaning_temp_dir.h" |
54 #include "chrome/installer/util/shell_util.h" | 55 #include "chrome/installer/util/shell_util.h" |
55 #include "chrome/installer/util/util_constants.h" | 56 #include "chrome/installer/util/util_constants.h" |
56 | 57 |
57 #include "installer_util_strings.h" // NOLINT | 58 #include "installer_util_strings.h" // NOLINT |
58 | 59 |
59 using installer::InstallerState; | 60 using installer::InstallerState; |
60 using installer::InstallationState; | 61 using installer::InstallationState; |
61 using installer::InstallationValidator; | 62 using installer::InstallationValidator; |
62 using installer::Product; | 63 using installer::Product; |
63 using installer::ProductState; | 64 using installer::ProductState; |
64 using installer::Products; | 65 using installer::Products; |
65 using installer::MasterPreferences; | 66 using installer::MasterPreferences; |
66 | 67 |
67 const wchar_t kChromePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices"; | 68 const wchar_t kChromePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices"; |
68 const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\"; | 69 const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\"; |
69 const wchar_t kSystemPrincipalSid[] = L"S-1-5-18"; | 70 const wchar_t kSystemPrincipalSid[] = L"S-1-5-18"; |
70 const int kGoogleUpdateTimeoutMs = 20 * 1000; | |
71 | 71 |
72 const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>( | 72 const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>( |
73 MiniDumpWithProcessThreadData | // Get PEB and TEB. | 73 MiniDumpWithProcessThreadData | // Get PEB and TEB. |
74 MiniDumpWithUnloadedModules | // Get unloaded modules when available. | 74 MiniDumpWithUnloadedModules | // Get unloaded modules when available. |
75 MiniDumpWithIndirectlyReferencedMemory); // Get memory referenced by stack. | 75 MiniDumpWithIndirectlyReferencedMemory); // Get memory referenced by stack. |
76 | 76 |
77 namespace { | 77 namespace { |
78 | 78 |
79 // This method unpacks and uncompresses the given archive file. For Chrome | 79 // This method unpacks and uncompresses the given archive file. For Chrome |
80 // install we are creating a uncompressed archive that contains all the files | 80 // install we are creating a uncompressed archive that contains all the files |
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
592 } | 592 } |
593 } else { | 593 } else { |
594 // Display an error message for other products. | 594 // Display an error message for other products. |
595 *status = installer::SYSTEM_LEVEL_INSTALL_EXISTS; | 595 *status = installer::SYSTEM_LEVEL_INSTALL_EXISTS; |
596 installer_state->WriteInstallerResult( | 596 installer_state->WriteInstallerResult( |
597 *status, IDS_INSTALL_SYSTEM_LEVEL_EXISTS_BASE, NULL); | 597 *status, IDS_INSTALL_SYSTEM_LEVEL_EXISTS_BASE, NULL); |
598 } | 598 } |
599 return false; | 599 return false; |
600 } | 600 } |
601 } | 601 } |
602 | |
603 } else { // System-level install. | |
604 // --ensure-google-update-present is supported for user-level only. | |
605 // The flag is generic, but its primary use case involves App Host. | |
606 if (installer_state->ensure_google_update_present()) { | |
607 LOG(DFATAL) << "--" << installer::switches::kEnsureGoogleUpdatePresent | |
608 << " is supported for user-level only."; | |
609 *status = installer::APP_HOST_REQUIRES_USER_LEVEL; | |
610 // No message string since there is nothing a user can do. | |
611 installer_state->WriteInstallerResult(*status, 0, NULL); | |
612 return false; | |
613 } | |
602 } | 614 } |
603 | 615 |
604 return true; | 616 return true; |
605 } | 617 } |
606 | 618 |
607 installer::InstallStatus InstallProductsHelper( | 619 installer::InstallStatus InstallProductsHelper( |
608 const InstallationState& original_state, | 620 const InstallationState& original_state, |
609 const CommandLine& cmd_line, | 621 const CommandLine& cmd_line, |
610 const MasterPreferences& prefs, | 622 const MasterPreferences& prefs, |
611 const InstallerState& installer_state, | 623 const InstallerState& installer_state, |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
741 | 753 |
742 installer_state.WriteInstallerResult(install_status, message_id, NULL); | 754 installer_state.WriteInstallerResult(install_status, message_id, NULL); |
743 } | 755 } |
744 | 756 |
745 proceed_with_installation = | 757 proceed_with_installation = |
746 proceed_with_installation && | 758 proceed_with_installation && |
747 CheckGroupPolicySettings(original_state, installer_state, | 759 CheckGroupPolicySettings(original_state, installer_state, |
748 *installer_version, &install_status); | 760 *installer_version, &install_status); |
749 | 761 |
750 if (proceed_with_installation) { | 762 if (proceed_with_installation) { |
763 // If Google Update is absent at user-level, install it using the | |
764 // Google Update installer from an existing system-level installation. | |
765 // This is for quick-enable App Host install from a system-level | |
766 // Chrome Binaries installation. | |
767 if (installer_state.ensure_google_update_present()) { | |
erikwright (departed)
2012/09/21 19:10:06
Skip this if system level. i.e., add the following
huangs
2012/09/21 19:45:17
Done.
| |
768 if (!google_update::EnsureUserLevelGoogleUpdatePresent()) { | |
769 LOG(ERROR) << "Failed to install Google Update"; | |
770 proceed_with_installation = false; | |
771 install_status = installer::INSTALL_OF_GOOGLE_UPDATE_FAILED; | |
772 installer_state.WriteInstallerResult(install_status, 0, NULL); | |
773 } | |
774 } | |
775 } | |
776 | |
777 if (proceed_with_installation) { | |
751 FilePath prefs_source_path(cmd_line.GetSwitchValueNative( | 778 FilePath prefs_source_path(cmd_line.GetSwitchValueNative( |
752 installer::switches::kInstallerData)); | 779 installer::switches::kInstallerData)); |
753 install_status = installer::InstallOrUpdateProduct( | 780 install_status = installer::InstallOrUpdateProduct( |
754 original_state, installer_state, cmd_line.GetProgram(), | 781 original_state, installer_state, cmd_line.GetProgram(), |
755 archive_to_copy, temp_path.path(), prefs_source_path, prefs, | 782 archive_to_copy, temp_path.path(), prefs_source_path, prefs, |
756 *installer_version); | 783 *installer_version); |
757 | 784 |
758 int install_msg_base = IDS_INSTALL_FAILED_BASE; | 785 int install_msg_base = IDS_INSTALL_FAILED_BASE; |
759 string16 chrome_exe; | 786 string16 chrome_exe; |
760 string16 quoted_chrome_exe; | 787 string16 quoted_chrome_exe; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
926 LOG(ERROR) << product.distribution()->GetAppShortCutName() | 953 LOG(ERROR) << product.distribution()->GetAppShortCutName() |
927 << " not found for uninstall."; | 954 << " not found for uninstall."; |
928 return installer::CHROME_NOT_INSTALLED; | 955 return installer::CHROME_NOT_INSTALLED; |
929 } | 956 } |
930 | 957 |
931 return installer::UninstallProduct( | 958 return installer::UninstallProduct( |
932 original_state, installer_state, cmd_line.GetProgram(), product, | 959 original_state, installer_state, cmd_line.GetProgram(), product, |
933 remove_all, force_uninstall, cmd_line); | 960 remove_all, force_uninstall, cmd_line); |
934 } | 961 } |
935 | 962 |
936 // Tell Google Update that an uninstall has taken place. This gives it a chance | |
937 // to uninstall itself straight away if no more products are installed on the | |
938 // system rather than waiting for the next time the scheduled task runs. | |
939 // Success or failure of Google Update has no bearing on the success or failure | |
940 // of Chrome's uninstallation. | |
941 void UninstallGoogleUpdate(bool system_install) { | |
942 string16 uninstall_cmd( | |
943 GoogleUpdateSettings::GetUninstallCommandLine(system_install)); | |
944 if (!uninstall_cmd.empty()) { | |
945 base::win::ScopedHandle process; | |
946 LOG(INFO) << "Launching Google Update's uninstaller: " << uninstall_cmd; | |
947 if (base::LaunchProcess(uninstall_cmd, base::LaunchOptions(), | |
948 process.Receive())) { | |
949 int exit_code = 0; | |
950 if (base::WaitForExitCodeWithTimeout( | |
951 process, &exit_code, | |
952 base::TimeDelta::FromMilliseconds(kGoogleUpdateTimeoutMs))) { | |
953 if (exit_code == 0) { | |
954 LOG(INFO) << " normal exit."; | |
955 } else { | |
956 LOG(ERROR) << "Google Update uninstaller (" << uninstall_cmd | |
957 << ") exited with code " << exit_code << "."; | |
958 } | |
959 } else { | |
960 // The process didn't finish in time, or GetExitCodeProcess failed. | |
961 LOG(ERROR) << "Google Update uninstaller (" << uninstall_cmd | |
962 << ") is taking more than " << kGoogleUpdateTimeoutMs | |
963 << " milliseconds to complete."; | |
964 } | |
965 } else { | |
966 PLOG(ERROR) << "Failed to launch Google Update uninstaller (" | |
967 << uninstall_cmd << ")"; | |
968 } | |
969 } | |
970 } | |
971 | |
972 installer::InstallStatus UninstallProducts( | 963 installer::InstallStatus UninstallProducts( |
973 const InstallationState& original_state, | 964 const InstallationState& original_state, |
974 const InstallerState& installer_state, | 965 const InstallerState& installer_state, |
975 const CommandLine& cmd_line) { | 966 const CommandLine& cmd_line) { |
976 const Products& products = installer_state.products(); | 967 const Products& products = installer_state.products(); |
977 | 968 |
978 if (installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER)) { | 969 if (installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER)) { |
979 // InstallerState::Initialize always puts Chrome first, and we rely on that | 970 // InstallerState::Initialize always puts Chrome first, and we rely on that |
980 // here for this reason: if Chrome is in-use, the user will be prompted to | 971 // here for this reason: if Chrome is in-use, the user will be prompted to |
981 // confirm uninstallation. Upon cancel, we should not continue with the | 972 // confirm uninstallation. Upon cancel, we should not continue with the |
(...skipping 14 matching lines...) Expand all Loading... | |
996 | 987 |
997 for (Products::const_iterator it = products.begin(); | 988 for (Products::const_iterator it = products.begin(); |
998 install_status != installer::UNINSTALL_CANCELLED && it < products.end(); | 989 install_status != installer::UNINSTALL_CANCELLED && it < products.end(); |
999 ++it) { | 990 ++it) { |
1000 prod_status = UninstallProduct(original_state, installer_state, | 991 prod_status = UninstallProduct(original_state, installer_state, |
1001 cmd_line, remove_all, force, **it); | 992 cmd_line, remove_all, force, **it); |
1002 if (prod_status != installer::UNINSTALL_SUCCESSFUL) | 993 if (prod_status != installer::UNINSTALL_SUCCESSFUL) |
1003 install_status = prod_status; | 994 install_status = prod_status; |
1004 } | 995 } |
1005 | 996 |
1006 UninstallGoogleUpdate(installer_state.system_install()); | 997 // Tell Google Update that an uninstall has taken place. |
998 // Ignore the return value: success or failure of Google Update | |
999 // has no bearing on the success or failure of Chrome's uninstallation. | |
1000 google_update::UninstallGoogleUpdate(installer_state.system_install()); | |
1007 | 1001 |
1008 return install_status; | 1002 return install_status; |
1009 } | 1003 } |
1010 | 1004 |
1011 installer::InstallStatus ShowEULADialog(const string16& inner_frame) { | 1005 installer::InstallStatus ShowEULADialog(const string16& inner_frame) { |
1012 VLOG(1) << "About to show EULA"; | 1006 VLOG(1) << "About to show EULA"; |
1013 string16 eula_path = installer::GetLocalizedEulaResource(); | 1007 string16 eula_path = installer::GetLocalizedEulaResource(); |
1014 if (eula_path.empty()) { | 1008 if (eula_path.empty()) { |
1015 LOG(ERROR) << "No EULA path available"; | 1009 LOG(ERROR) << "No EULA path available"; |
1016 return installer::EULA_REJECTED; | 1010 return installer::EULA_REJECTED; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1087 } else if (cmd_line.HasSwitch(installer::switches::kShowEula)) { | 1081 } else if (cmd_line.HasSwitch(installer::switches::kShowEula)) { |
1088 // Check if we need to show the EULA. If it is passed as a command line | 1082 // Check if we need to show the EULA. If it is passed as a command line |
1089 // then the dialog is shown and regardless of the outcome setup exits here. | 1083 // then the dialog is shown and regardless of the outcome setup exits here. |
1090 string16 inner_frame = | 1084 string16 inner_frame = |
1091 cmd_line.GetSwitchValueNative(installer::switches::kShowEula); | 1085 cmd_line.GetSwitchValueNative(installer::switches::kShowEula); |
1092 *exit_code = ShowEULADialog(inner_frame); | 1086 *exit_code = ShowEULADialog(inner_frame); |
1093 if (installer::EULA_REJECTED != *exit_code) { | 1087 if (installer::EULA_REJECTED != *exit_code) { |
1094 GoogleUpdateSettings::SetEULAConsent( | 1088 GoogleUpdateSettings::SetEULAConsent( |
1095 original_state, BrowserDistribution::GetDistribution(), true); | 1089 original_state, BrowserDistribution::GetDistribution(), true); |
1096 } | 1090 } |
1097 } else if (cmd_line.HasSwitch( | 1091 } else if (cmd_line.HasSwitch(installer::switches::kConfigureUserSettings)) { |
1098 installer::switches::kConfigureUserSettings)) { | |
1099 DCHECK(installer_state->system_install()); | 1092 DCHECK(installer_state->system_install()); |
1100 const Product* chrome_install = | 1093 const Product* chrome_install = |
1101 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); | 1094 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); |
1102 DCHECK(chrome_install); | 1095 DCHECK(chrome_install); |
1103 // TODO(gab): Implement the new shortcut functionality here. | 1096 // TODO(gab): Implement the new shortcut functionality here. |
1104 LOG(ERROR) << "--configure-user-settings is not implemented."; | 1097 LOG(ERROR) << "--configure-user-settings is not implemented."; |
1105 } else if (cmd_line.HasSwitch( | 1098 } else if (cmd_line.HasSwitch(installer::switches::kRegisterChromeBrowser)) { |
1106 installer::switches::kRegisterChromeBrowser)) { | |
1107 installer::InstallStatus status = installer::UNKNOWN_STATUS; | 1099 installer::InstallStatus status = installer::UNKNOWN_STATUS; |
1108 const Product* chrome_install = | 1100 const Product* chrome_install = |
1109 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); | 1101 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); |
1110 if (chrome_install) { | 1102 if (chrome_install) { |
1111 // If --register-chrome-browser option is specified, register all | 1103 // If --register-chrome-browser option is specified, register all |
1112 // Chrome protocol/file associations, as well as register it as a valid | 1104 // Chrome protocol/file associations, as well as register it as a valid |
1113 // browser for Start Menu->Internet shortcut. This switch will also | 1105 // browser for Start Menu->Internet shortcut. This switch will also |
1114 // register Chrome as a valid handler for a set of URL protocols that | 1106 // register Chrome as a valid handler for a set of URL protocols that |
1115 // Chrome may become the default handler for, either by the user marking | 1107 // Chrome may become the default handler for, either by the user marking |
1116 // Chrome as the default browser, through the Windows Default Programs | 1108 // Chrome as the default browser, through the Windows Default Programs |
1117 // control panel settings, or through website use of | 1109 // control panel settings, or through website use of |
1118 // registerProtocolHandler. These protocols are found in | 1110 // registerProtocolHandler. These protocols are found in |
1119 // ShellUtil::kPotentialProtocolAssociations. | 1111 // ShellUtil::kPotentialProtocolAssociations. |
1120 // The --register-url-protocol will additionally register Chrome as a | 1112 // The --register-url-protocol will additionally register Chrome as a |
1121 // potential handler for the supplied protocol, and is used if a website | 1113 // potential handler for the supplied protocol, and is used if a website |
1122 // registers a handler for a protocol not found in | 1114 // registers a handler for a protocol not found in |
1123 // ShellUtil::kPotentialProtocolAssociations. | 1115 // ShellUtil::kPotentialProtocolAssociations. |
1124 // These options should only be used when setup.exe is launched with admin | 1116 // These options should only be used when setup.exe is launched with admin |
1125 // rights. We do not make any user specific changes with this option. | 1117 // rights. We do not make any user specific changes with this option. |
1126 DCHECK(IsUserAnAdmin()); | 1118 DCHECK(IsUserAnAdmin()); |
1127 string16 chrome_exe(cmd_line.GetSwitchValueNative( | 1119 string16 chrome_exe(cmd_line.GetSwitchValueNative( |
1128 installer::switches::kRegisterChromeBrowser)); | 1120 installer::switches::kRegisterChromeBrowser)); |
1129 string16 suffix; | 1121 string16 suffix; |
1130 if (cmd_line.HasSwitch( | 1122 if (cmd_line.HasSwitch( |
1131 installer::switches::kRegisterChromeBrowserSuffix)) { | 1123 installer::switches::kRegisterChromeBrowserSuffix)) { |
1132 suffix = cmd_line.GetSwitchValueNative( | 1124 suffix = cmd_line.GetSwitchValueNative( |
1133 installer::switches::kRegisterChromeBrowserSuffix); | 1125 installer::switches::kRegisterChromeBrowserSuffix); |
1134 } | 1126 } |
1135 if (cmd_line.HasSwitch( | 1127 if (cmd_line.HasSwitch(installer::switches::kRegisterURLProtocol)) { |
1136 installer::switches::kRegisterURLProtocol)) { | |
1137 string16 protocol = cmd_line.GetSwitchValueNative( | 1128 string16 protocol = cmd_line.GetSwitchValueNative( |
1138 installer::switches::kRegisterURLProtocol); | 1129 installer::switches::kRegisterURLProtocol); |
1139 // ShellUtil::RegisterChromeForProtocol performs all registration | 1130 // ShellUtil::RegisterChromeForProtocol performs all registration |
1140 // done by ShellUtil::RegisterChromeBrowser, as well as registering | 1131 // done by ShellUtil::RegisterChromeBrowser, as well as registering |
1141 // with Windows as capable of handling the supplied protocol. | 1132 // with Windows as capable of handling the supplied protocol. |
1142 if (ShellUtil::RegisterChromeForProtocol( | 1133 if (ShellUtil::RegisterChromeForProtocol( |
1143 chrome_install->distribution(), chrome_exe, suffix, protocol, | 1134 chrome_install->distribution(), chrome_exe, suffix, protocol, |
1144 false)) | 1135 false)) |
1145 status = installer::IN_USE_UPDATED; | 1136 status = installer::IN_USE_UPDATED; |
1146 } else { | 1137 } else { |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1519 if (!(installer_state.is_msi() && is_uninstall)) | 1510 if (!(installer_state.is_msi() && is_uninstall)) |
1520 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT | 1511 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT |
1521 // to pass through, since this is only returned on uninstall which is | 1512 // to pass through, since this is only returned on uninstall which is |
1522 // never invoked directly by Google Update. | 1513 // never invoked directly by Google Update. |
1523 return_code = InstallUtil::GetInstallReturnCode(install_status); | 1514 return_code = InstallUtil::GetInstallReturnCode(install_status); |
1524 | 1515 |
1525 VLOG(1) << "Installation complete, returning: " << return_code; | 1516 VLOG(1) << "Installation complete, returning: " << return_code; |
1526 | 1517 |
1527 return return_code; | 1518 return return_code; |
1528 } | 1519 } |
OLD | NEW |