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

Unified Diff: client/install.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « client/install.h ('k') | client/install_apps.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: client/install.cc
diff --git a/client/install.cc b/client/install.cc
deleted file mode 100644
index 7e27ce3838c88f896955cad3940ceb68a3e2e903..0000000000000000000000000000000000000000
--- a/client/install.cc
+++ /dev/null
@@ -1,830 +0,0 @@
-// Copyright 2007-2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// ========================================================================
-
-#include "omaha/client/install.h"
-#include "omaha/client/install_internal.h"
-#include "omaha/base/app_util.h"
-#include "omaha/base/const_object_names.h"
-#include "omaha/base/debug.h"
-#include "omaha/base/error.h"
-#include "omaha/base/file.h"
-#include "omaha/base/logging.h"
-#include "omaha/base/omaha_version.h"
-#include "omaha/base/path.h"
-#include "omaha/base/process.h"
-#include "omaha/base/reg_key.h"
-#include "omaha/base/scoped_any.h"
-#include "omaha/base/string.h"
-#include "omaha/base/time.h"
-#include "omaha/base/utils.h"
-#include "omaha/base/vistautil.h"
-#include "omaha/client/client_utils.h"
-#include "omaha/client/install_self.h"
-#include "omaha/client/resource.h"
-#include "omaha/common/app_registry_utils.h"
-#include "omaha/common/command_line_builder.h"
-#include "omaha/common/config_manager.h"
-#include "omaha/common/const_cmd_line.h"
-#include "omaha/common/const_goopdate.h"
-#include "omaha/common/goopdate_utils.h"
-#include "omaha/common/oem_install_utils.h"
-#include "omaha/common/ping.h"
-#include "omaha/setup/setup_metrics.h"
-#include "omaha/ui/splash_screen.h"
-
-namespace omaha {
-
-namespace {
-
-// Returns whether elevation is required.
-bool IsElevationRequired(bool is_machine) {
- return is_machine && !vista_util::IsUserAdmin();
-}
-
-} // namespace
-
-namespace internal {
-
-// TODO(omaha3): Make this elevate the metainstaller instead of
-// GoogleUpdate.exe so the files are extracted to a secure location.
-// May need to add all languages to the metainstaller's version resources so
-// the user sees the localized string in the UAC.
-// TODO(omaha3): We will need to save the metainstaller for OneClick
-// cross-installs. We may need to change the metainstaller behavior to not
-// use the tag if any command line args are provided. This will allow us to
-// reuse a tagged metainstaller that we saved for other purposes, such as
-// OneClick cross-installs.
-// TODO(omaha3): The "metainstaller" may also be some type of wrapper around
-// a differential update. We'll address that later. This wrapper should not
-// need localized resource strings since it always runs silently.
-HRESULT DoElevation(bool is_interactive,
- bool is_install_elevated_instance,
- const CString& cmd_line,
- DWORD* exit_code) {
- ASSERT1(exit_code);
- ASSERT1(IsElevationRequired(true));
-
- if (!is_interactive) {
- return GOOPDATE_E_SILENT_INSTALL_NEEDS_ELEVATION;
- }
-
- if (is_install_elevated_instance) {
- // This can happen if UAC is disabled. See http://b/1187784.
- CORE_LOG(LE, (_T("[Install elevated process requires elevation]")));
- return GOOPDATE_E_INSTALL_ELEVATED_PROCESS_NEEDS_ELEVATION;
- }
-
- HRESULT hr = ElevateAndWait(cmd_line, exit_code);
- if (FAILED(hr)) {
- CORE_LOG(LE, (_T("[ElevateAndWait failed][%s][0x%08x]"), cmd_line, hr));
- }
-
- return hr;
-}
-
-// Assumes it is running with the necessary privileges.
-HRESULT DoInstall(bool is_machine,
- bool is_app_install,
- bool is_eula_required,
- bool is_oem_install,
- const CString& current_version,
- const CommandLineArgs& args,
- const CString& session_id,
- SplashScreen* splash_screen,
- int* extra_code1,
- bool* has_setup_succeeded,
- bool* has_launched_handoff,
- bool* has_ui_been_displayed) {
- ASSERT1(!IsElevationRequired(is_machine));
- ASSERT1(extra_code1);
- ASSERT1(splash_screen);
- ASSERT1(has_setup_succeeded);
- ASSERT1(has_launched_handoff);
- ASSERT1(has_ui_been_displayed);
-
- *extra_code1 = 0;
-
- // TODO(omaha3): We may need to take an "installing apps" lock here if
- // is_app_install. There was code in Omaha 2 that relied on the fact that
- // the Setup lock was held while the install worker was launched, even in
- // handoff scenarios. This allowed checking for the Setup lock and running
- // install workers to be sufficient to ensure that the number of Clients keys
- // was stable. Note that Omaha 2 also held the shutdown event while the worker
- // was launched.
- // TODO(omaha3): Consider taking the Setup lock in this file (via a public
- // method in Setup) and releasing it. This would allow us to address the above
- // issue and maybe the EULA not accepted issue.
- // TODO(omaha3): We may also want to call ShouldInstall after a Lock(0) to
- // determine whether we even need to display the splash screen or we can skip
- // it and Setup altogether and just launch the /handoff process.
-
- HRESULT hr = install_self::InstallSelf(is_machine,
- is_eula_required,
- is_oem_install,
- current_version,
- args.install_source,
- args.extra,
- session_id,
- extra_code1);
- *has_setup_succeeded = SUCCEEDED(hr);
- if (FAILED(hr)) {
- OPT_LOG(LE, (_T("[InstallSelf failed][0x%08x]"), hr));
- return hr;
- }
-
- if (!is_app_install) {
- return S_OK;
- }
-
- hr = InstallApplications(is_machine,
- is_eula_required,
- args,
- session_id,
- splash_screen,
- has_ui_been_displayed,
- has_launched_handoff);
- if (FAILED(hr)) {
- OPT_LOG(LE, (_T("[InstallApplications failed][0x%08x]"), hr));
- return hr;
- }
-
- return S_OK;
-};
-
-HRESULT InstallApplications(bool is_machine,
- bool is_eula_required,
- const CommandLineArgs& args,
- const CString& session_id,
- SplashScreen* splash_screen,
- bool* has_ui_been_displayed,
- bool* has_launched_handoff) {
- ASSERT1(has_ui_been_displayed);
- ASSERT1(has_launched_handoff);
-
- *has_launched_handoff = false;
-
- CString offline_dir;
- const bool is_offline_install = CopyOfflineFiles(is_machine,
- args.extra.apps,
- &offline_dir);
- if (!is_offline_install && oem_install_utils::IsOemInstalling(is_machine)) {
- return GOOPDATE_E_OEM_WITH_ONLINE_INSTALLER;
- }
- if (!is_offline_install && is_eula_required) {
- return GOOPDATE_E_EULA_REQURED_WITH_ONLINE_INSTALLER;
- }
-
- // Start the handoff to install the app.
- scoped_process handoff_process;
- HRESULT hr = LaunchHandoffProcess(is_machine,
- offline_dir,
- args,
- session_id,
- address(handoff_process));
- if (FAILED(hr)) {
- OPT_LOG(LE, (_T("[Failed to launch installed instance][0x%08x]"), hr));
- return hr;
- }
-
- *has_launched_handoff = true;
-
- OPT_LOG(L1, (_T("[Waiting for application install to complete]")));
- uint32 exit_code(0);
- hr = WaitForProcessExit(get(handoff_process),
- splash_screen,
- has_ui_been_displayed,
- &exit_code);
-
- if (FAILED(hr)) {
- OPT_LOG(LE, (_T("[Failed waiting for app install][0x%08x]"), hr));
- return hr;
- }
- if (exit_code) {
- OPT_LOG(LE, (_T("[Handoff exited with error][0x%08x]"), exit_code));
- ASSERT1(FAILED(exit_code));
- return exit_code;
- }
-
- return S_OK;
-}
-
-// The behavior depends on the OS:
-// 1. OS < Vista : Fail.
-// 2. OS >= Vista : Try to elevate - causes a UAC dialog.
-// We should be here only in case of initial machine installs when the user is
-// not an elevated admin.
-HRESULT ElevateAndWait(const CString& cmd_line, DWORD* exit_code) {
- OPT_LOG(L1, (_T("[Elevating][%s]"), cmd_line));
- ASSERT1(!vista_util::IsUserAdmin());
- ASSERT1(exit_code);
-
- if (!vista_util::IsVistaOrLater()) {
- // TODO(omaha): We could consider to ask for credentials here.
- // This TODO existed in Omaha 1. How would we even do this?
- CORE_LOG(LE, (_T("[Non Admin trying to install admin app]")));
- ++metric_setup_machine_app_non_admin;
- return GOOPDATE_E_NONADMIN_INSTALL_ADMIN_APP;
- }
-
- CString cmd_line_elevated(GetCmdLineTail(cmd_line));
- cmd_line_elevated.AppendFormat(_T(" /%s"), kCmdLineInstallElevated);
-
- HRESULT hr = goopdate_utils::StartElevatedSelfWithArgsAndWait(
- cmd_line_elevated, exit_code);
- if (FAILED(hr)) {
- OPT_LOG(LE, (_T("[Starting elevated GoogleUpdate.exe failed][%s][0x%08x]"),
- cmd_line, hr));
-
- // TODO(omaha3): Report hr somehow. Was reported in extra code in Omaha 2.
- if (vista_util::IsUserNonElevatedAdmin()) {
- return GOOPDATE_E_ELEVATION_FAILED_ADMIN;
- } else {
- return GOOPDATE_E_ELEVATION_FAILED_NON_ADMIN;
- }
- }
-
- return S_OK;
-}
-
-bool CopyOfflineFiles(bool is_machine,
- const std::vector<CommandLineAppArgs>& apps,
- CString* offline_dir) {
- ASSERT1(offline_dir);
- offline_dir->Empty();
-
- if (apps.empty()) {
- return false;
- }
-
- GUID guid(GUID_NULL);
- VERIFY1(SUCCEEDED(::CoCreateGuid(&guid)));
- CString parent_offline_dir(
- is_machine ?
- ConfigManager::Instance()->GetMachineSecureOfflineStorageDir() :
- ConfigManager::Instance()->GetUserOfflineStorageDir());
- CString unique_offline_dir =
- ConcatenatePath(parent_offline_dir, GuidToString(guid));
- VERIFY1(SUCCEEDED(CreateDir(unique_offline_dir, NULL)));
-
- HRESULT hr = CopyOfflineManifest(unique_offline_dir);
- if (FAILED(hr)) {
- CORE_LOG(L3, (_T("[CopyOfflineManifest failed][0x%08x]"), hr));
- return false;
- }
-
- for (size_t i = 0; i < apps.size(); ++i) {
- const GUID& app_id = apps[i].app_guid;
- HRESULT hr = CopyOfflineFilesForApp(GuidToString(app_id),
- unique_offline_dir);
- if (FAILED(hr)) {
- ASSERT(false, (_T("[CopyOfflineFilesForApp failed][0x%08x]"), hr));
- return false;
- }
- }
-
- CORE_LOG(L3, (_T("[CopyOfflineFiles done][%s]"), unique_offline_dir));
- *offline_dir = unique_offline_dir;
- return true;
-}
-
-HRESULT CopyOfflineManifest(const CString& offline_dir) {
- CORE_LOG(L3, (_T("[CopyOfflineManifest][%s]"), offline_dir));
-
- // Copy offline manifest into "<offline_dir>\<kOfflineManifestFileName>".
- CString setup_temp_dir(app_util::GetCurrentModuleDirectory());
- CString source_manifest_path = ConcatenatePath(setup_temp_dir,
- kOfflineManifestFileName);
- if (!File::Exists(source_manifest_path)) {
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
- CString dest_manifest_path = ConcatenatePath(offline_dir,
- kOfflineManifestFileName);
- HRESULT hr = File::Copy(source_manifest_path, dest_manifest_path, true);
- if (FAILED(hr)) {
- CORE_LOG(LE, (_T("[File copy failed][%s][%s][0x%08x]"),
- source_manifest_path, dest_manifest_path, hr));
- return hr;
- }
-
- return S_OK;
-}
-
-HRESULT CopyOfflineFilesForApp(const CString& app_id,
- const CString& offline_dir) {
- CORE_LOG(L3, (_T("[CopyOfflineFilesForApp][%s][%s]"),
- app_id, offline_dir));
-
- CString setup_temp_dir(app_util::GetCurrentModuleDirectory());
- CString pattern;
- // Copy the installer files that are named with the pattern "*.<app_id>" to
- // the directory "<offline_dir>\<app_id>".
- pattern.Format(_T("*.%s"), app_id);
- std::vector<CString> files;
- HRESULT hr = FindFiles(setup_temp_dir, pattern, &files);
- if (FAILED(hr)) {
- CORE_LOG(LE, (_T("[FindFiles failed][0x%08x]"), hr));
- return hr;
- }
- if (files.empty()) {
- CORE_LOG(LE, (_T("[FindFiles found no files]")));
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
-
- CString offline_app_dir = ConcatenatePath(offline_dir, app_id);
- if (File::IsDirectory(offline_app_dir)) {
- VERIFY1(SUCCEEDED(DeleteDirectoryFiles(offline_app_dir)));
- } else {
- hr = CreateDir(offline_app_dir, NULL);
- if (FAILED(hr)) {
- CORE_LOG(LE, (_T("[CreateDir failed][%s]"), offline_app_dir));
- return hr;
- }
- }
-
- for (size_t i = 0; i < files.size(); ++i) {
- const CString& file_name = files[i];
- ASSERT1(file_name.GetLength() > app_id.GetLength());
-
- CPath renamed_file_name(file_name);
- renamed_file_name.RemoveExtension();
- ASSERT1(file_name.Left(file_name.GetLength() - app_id.GetLength() - 1) ==
- static_cast<const CString&>(renamed_file_name));
- CString new_file_path = ConcatenatePath(offline_app_dir, renamed_file_name);
- CORE_LOG(L4, (_T("[new_file_path][%s]"), new_file_path));
-
- CString source_file_path = ConcatenatePath(setup_temp_dir, file_name);
- hr = File::Copy(source_file_path, new_file_path, true);
- if (FAILED(hr)) {
- CORE_LOG(LE, (_T("[Copy failed][%s][%s]"),
- source_file_path, new_file_path));
- return hr;
- }
- }
-
- return S_OK;
-}
-
-
-// TODO(omaha3): This implementation requires updating this code whenever a
-// new option is added. We could do a string replace of "/install" with
-// "/handoff", but we'd need to remove things such as /oem. Alternatively,
-// allow a CommandLineBuilder to be populated with existing args. Doing
-// replacement would allow us to only pass one copy of the command line to
-// Install() instead of passing both the string and struct. Be sure to handle
-// /appargs when making any changes.
-// TODO(omaha): Extract the command line building and unit test it.
-HRESULT LaunchHandoffProcess(bool is_machine,
- const CString& offline_dir,
- const CommandLineArgs& install_args,
- const CString& session_id,
- HANDLE* process) { // process can be NULL.
- CORE_LOG(L2, (_T("[LaunchHandoffProcess]")));
-
- // The install source has been either specified or set to a default value by
- // the time the execution flow reaches this function. The install source is
- // propagated to the handoff process except in certain offline install cases,
- // such as a tagged offline installer or an offline installer that did not
- // have an install source.
- //
- // TODO(omaha): refactor so that the handling of the install source is
- // encapsulated in just one module.
- ASSERT1(!install_args.install_source.IsEmpty());
- ASSERT1(!install_args.extra_args_str.IsEmpty());
-
- CommandLineBuilder builder(COMMANDLINE_MODE_HANDOFF_INSTALL);
-
- builder.set_is_silent_set(install_args.is_silent_set);
- builder.set_is_eula_required_set(install_args.is_eula_required_set);
- builder.set_extra_args(install_args.extra_args_str);
- builder.set_app_args(install_args.app_args_str);
- builder.set_install_source(install_args.install_source);
- builder.set_session_id(session_id);
-
- if (!offline_dir.IsEmpty()) {
- builder.SetOfflineDir(offline_dir);
- const CString& install_source(install_args.install_source);
- if (install_source == kCmdLineInstallSource_InstallDefault ||
- install_source == kCmdLineInstallSource_TaggedMetainstaller) {
- builder.set_install_source(kCmdLineInstallSource_Offline);
- }
- }
-
- CString cmd_line = builder.GetCommandLineArgs();
-
- HRESULT hr = goopdate_utils::StartGoogleUpdateWithArgs(is_machine,
- cmd_line,
- process);
- if (FAILED(hr)) {
- OPT_LOG(LE, (_T("[Google Update hand off failed][%s][0x%08x]"),
- cmd_line, hr));
- // TODO(omaha3): Report hr somehow. Was reported in extra code in Omaha 2.
- return GOOPDATE_E_HANDOFF_FAILED;
- }
-
- return S_OK;
-}
-
-HRESULT WaitForProcessExit(HANDLE process,
- SplashScreen* splash_screen,
- bool* has_ui_been_displayed,
- uint32* exit_code) {
- CORE_LOG(L3, (_T("[WaitForProcessExit]")));
- ASSERT1(process);
- ASSERT1(exit_code);
- ASSERT1(has_ui_been_displayed);
- *exit_code = 0;
-
- int res = ::WaitForInputIdle(process, INFINITE);
- if (res == 0) {
- *has_ui_been_displayed = true;
- }
- if (splash_screen) {
- splash_screen->Dismiss();
- }
-
- res = ::WaitForSingleObject(process, INFINITE);
- ASSERT1(WAIT_OBJECT_0 == res);
- if (WAIT_FAILED == res) {
- DWORD error = ::GetLastError();
- CORE_LOG(LE, (_T("[::WaitForMultipleObjects failed][%u]"), error));
- return HRESULT_FROM_WIN32(error);
- }
-
- // Get the exit code.
- DWORD local_exit_code = 0;
- if (::GetExitCodeProcess(process, &local_exit_code)) {
- CORE_LOG(L2, (_T("[process exited][PID %u][exit code 0x%08x]"),
- Process::GetProcessIdFromHandle(process), local_exit_code));
- *exit_code = local_exit_code;
- } else {
- DWORD error = ::GetLastError();
- CORE_LOG(LE, (_T("[::GetExitCodeProcess failed][%u]"), error));
- return HRESULT_FROM_WIN32(error);
- }
-
- return S_OK;
-}
-
-// TODO(omaha): needs to handle errors when loading the strings.
-CString GetErrorText(HRESULT error, const CString& bundle_name) {
- ASSERT1(!bundle_name.IsEmpty());
-
- CString error_text;
-
- switch (error) {
- case GOOPDATE_E_INSTALL_ELEVATED_PROCESS_NEEDS_ELEVATION:
- case GOOPDATE_E_NONADMIN_INSTALL_ADMIN_APP:
- error_text.FormatMessage(IDS_NEED_ADMIN_TO_INSTALL, bundle_name);
- break;
- case GOOPDATE_E_ELEVATION_FAILED_ADMIN:
- case GOOPDATE_E_ELEVATION_FAILED_NON_ADMIN:
- error_text.FormatMessage(IDS_ELEVATION_FAILED, bundle_name);
- break;
- case GOOPDATE_E_FAILED_TO_GET_LOCK:
- case GOOPDATE_E_FAILED_TO_GET_LOCK_MATCHING_INSTALL_PROCESS_RUNNING:
- case GOOPDATE_E_FAILED_TO_GET_LOCK_NONMATCHING_INSTALL_PROCESS_RUNNING:
- case GOOPDATE_E_FAILED_TO_GET_LOCK_UPDATE_PROCESS_RUNNING:
- {
- CString company_name;
- VERIFY1(company_name.LoadString(IDS_FRIENDLY_COMPANY_NAME));
- error_text.FormatMessage(IDS_APPLICATION_INSTALLING_GOOGLE_UPDATE,
- company_name,
- bundle_name);
- }
- break;
- case GOOPDATE_E_INSTANCES_RUNNING:
- {
- CString company_name;
- VERIFY1(company_name.LoadString(IDS_FRIENDLY_COMPANY_NAME));
- error_text.FormatMessage(IDS_INSTANCES_RUNNING_AFTER_SHUTDOWN,
- company_name,
- bundle_name);
- }
- break;
- case GOOPDATE_E_RUNNING_INFERIOR_MSXML:
- error_text.FormatMessage(IDS_WINDOWS_IS_NOT_UP_TO_DATE, bundle_name);
- break;
- case GOOPDATE_E_HANDOFF_FAILED:
- error_text.FormatMessage(IDS_HANDOFF_FAILED, bundle_name);
- break;
- default:
- {
- CString product_name;
- VERIFY1(product_name.LoadString(IDS_PRODUCT_DISPLAY_NAME));
- error_text.FormatMessage(IDS_SETUP_FAILED, product_name, error);
- }
- break;
- }
-
- return error_text;
-}
-
-// Displays an error in the Google Update UI and sends a ping if allowed.
-void HandleInstallError(HRESULT error,
- int extra_code1,
- const CString& session_id,
- bool is_machine,
- bool is_interactive,
- bool is_eula_required,
- bool is_oem_install,
- const CString& current_version,
- const CString& install_source,
- const CommandLineExtraArgs& extra_args,
- bool has_setup_succeeded,
- bool has_launched_handoff,
- bool* has_ui_been_displayed) {
- ASSERT1(FAILED(error));
- ASSERT1(has_ui_been_displayed);
-
- const CString& bundle_name(extra_args.bundle_name);
- const CString error_text(GetErrorText(error, bundle_name));
-
- OPT_LOG(LE, (_T("[Failed to install][0x%08x][%s]"), error, error_text));
-
- if (is_interactive && !*has_ui_been_displayed) {
- CString primary_app_id;
- if (!extra_args.apps.empty()) {
- primary_app_id = GuidToString(extra_args.apps[0].app_guid);
- }
- *has_ui_been_displayed = client_utils::DisplayError(
- is_machine,
- bundle_name,
- error,
- extra_code1,
- error_text,
- primary_app_id,
- extra_args.language,
- extra_args.installation_id,
- extra_args.brand_code);
- }
-
- // Send an EVENT_INSTALL_COMPLETE ping for Omaha and wait for the ping to be
- // sent. This ping may cause a firewall prompt since the process sending the
- // ping may run from a temporary directory.
- //
- // An EVENT_INSTALL_COMPLETE ping for the apps is also sent in the case the
- /// handoff process did not launch successfully, otherwise, the handoff
- // process is responsible for sending this ping.
- //
- // Setup can fail before setting either eula or oem states in the
- // registry. Therefore, ConfigManager::CanUseNetwork can't be called yet.
- if (is_eula_required || is_oem_install) {
- return;
- }
- Ping ping(is_machine, session_id, install_source);
- ping.LoadAppDataFromExtraArgs(extra_args);
- if (!has_setup_succeeded) {
- PingEventPtr setup_install_complete_ping_event(
- new PingEvent(PingEvent::EVENT_INSTALL_COMPLETE, // Type 2.
- PingEvent::EVENT_RESULT_ERROR,
- error,
- extra_code1));
- const CString next_version(GetVersionString());
- ping.BuildOmahaPing(current_version,
- next_version,
- setup_install_complete_ping_event);
- }
- if (!has_launched_handoff) {
- PingEventPtr install_complete_ping_event(
- new PingEvent(PingEvent::EVENT_INSTALL_COMPLETE, // Type 2.
- PingEvent::EVENT_RESULT_ERROR,
- error,
- extra_code1));
- ping.BuildAppsPing(install_complete_ping_event);
- }
- HRESULT hr = ping.Send(false);
- if (FAILED(hr)) {
- CORE_LOG(LW, (_T("[Ping::Send failed][0x%x]"), hr));
- }
-}
-
-} // namespace internal
-
-// This function handles command-line installs. This is the only function that
-// can install Omaha in non-update cases. If elevation is required, the function
-// elevates an instance of Omaha and waits for that instance to exit before
-// returning. If needed, the function starts a handoff process to install the
-// applications and waits for the handoff process to exit.
-//
-// 'install_cmd_line' parameter is the command line for the current instance and
-// used to elevate if necessary.
-// 'args' parameter is the parsed args corresponding to install_cmd_line and it
-// is used to build the handoff command line if necessary.
-HRESULT Install(bool is_interactive,
- bool is_app_install,
- bool is_eula_required,
- bool is_oem_install,
- bool is_install_elevated_instance,
- const CString& install_cmd_line,
- const CommandLineArgs& args,
- bool* is_machine,
- bool* has_ui_been_displayed) {
- ASSERT1(!install_cmd_line.IsEmpty());
- ASSERT1(is_machine);
- ASSERT1(has_ui_been_displayed);
-
- CORE_LOG(L2, (_T("[Install][%d][%d][%s]"),
- *is_machine, is_interactive, install_cmd_line));
- ++metric_setup_install_total;
- if (is_install_elevated_instance) {
- ++metric_setup_uac_succeeded;
- }
-
- if (!*is_machine &&
- vista_util::IsVistaOrLater() &&
- vista_util::IsUserAdmin()) {
- ++metric_setup_user_app_admin;
- }
-
- // Allocate a session ID to connect all update checks and pings involved
- // with this run of Omaha. This will need to be passed along to any child
- // processes we create.
- CString session_id;
- VERIFY1(SUCCEEDED(GetGuid(&session_id)));
-
- // 'current_version' corresponds to the value of 'pv' read from
- // registry. This value is either empty, in the case of a new install or
- // the version of the installed Omaha before the setup code ran.
- CString current_version;
- app_registry_utils::GetAppVersion(*is_machine,
- kGoogleUpdateAppId,
- &current_version);
-
- bool has_setup_succeeded = false;
- bool has_launched_handoff = false;
-
- if (IsElevationRequired(*is_machine)) {
- ASSERT1(!ConfigManager::Instance()->IsWindowsInstalling());
-
- DWORD exit_code = 0;
- HRESULT hr = internal::DoElevation(is_interactive,
- is_install_elevated_instance,
- install_cmd_line,
- &exit_code);
-
- if (FAILED(hr)) {
- CORE_LOG(LE, (_T("[DoElevation failed][%s][0x%08x]"),
- install_cmd_line, hr));
-
- bool attempt_per_user_install = false;
- if (is_interactive &&
- args.extra.apps[0].needs_admin == NEEDS_ADMIN_PREFERS) {
- if (hr == GOOPDATE_E_NONADMIN_INSTALL_ADMIN_APP ||
- hr == GOOPDATE_E_INSTALL_ELEVATED_PROCESS_NEEDS_ELEVATION) {
- attempt_per_user_install = true;
- } else {
- *has_ui_been_displayed = client_utils::DisplayContinueAsNonAdmin(
- args.extra.bundle_name, &attempt_per_user_install);
- }
- }
-
- if (attempt_per_user_install) {
- *is_machine = false;
- CString no_admin_cmd_line(String_ReplaceIgnoreCase(install_cmd_line,
- kNeedsAdminPrefers,
- kNeedsAdminNo));
- CommandLineArgs no_admin_args = args;
- no_admin_args.extra.apps[0].needs_admin = NEEDS_ADMIN_NO;
- no_admin_args.extra_args_str = String_ReplaceIgnoreCase(
- no_admin_args.extra_args_str, kNeedsAdminPrefers, kNeedsAdminNo);
-
- return Install(is_interactive,
- is_app_install,
- is_eula_required,
- is_oem_install,
- is_install_elevated_instance,
- no_admin_cmd_line,
- no_admin_args,
- is_machine,
- has_ui_been_displayed);
- }
-
- internal::HandleInstallError(hr,
- 0,
- session_id,
- *is_machine,
- is_interactive,
- is_eula_required,
- is_oem_install,
- current_version,
- args.install_source,
- args.extra,
- has_setup_succeeded,
- has_launched_handoff,
- has_ui_been_displayed);
- return hr;
- }
-
- // TODO(omaha): waiting for input idle of an elevated process fails if the
- // caller is not elevated. The code assumes that the elevated process
- // displays UI if the elevation succeeded. It is possible that the elevated
- // process ran but had terminated before displaying UI. This is an uncommon
- // case and for simplicity, it is not handled here.
- *has_ui_been_displayed = true;
-
- return exit_code;
- }
-
- SplashScreen splash_screen(args.extra.bundle_name);
- if (is_interactive) {
- splash_screen.Show();
- }
-
- int extra_code1 = 0;
- HRESULT hr = internal::DoInstall(*is_machine,
- is_app_install,
- is_eula_required,
- is_oem_install,
- current_version,
- args,
- session_id,
- &splash_screen,
- &extra_code1,
- &has_setup_succeeded,
- &has_launched_handoff,
- has_ui_been_displayed);
- if (is_interactive) {
- splash_screen.Dismiss();
- }
-
- if (FAILED(hr)) {
- CORE_LOG(LE, (_T("[DoInstall failed][0x%08x]"), hr));
- internal::HandleInstallError(hr,
- extra_code1,
- session_id,
- *is_machine,
- is_interactive,
- is_eula_required,
- is_oem_install,
- current_version,
- args.install_source,
- args.extra,
- has_setup_succeeded,
- has_launched_handoff,
- has_ui_been_displayed);
- return hr;
- }
-
- if (!is_app_install) {
- // TODO(omaha): Display UI if we want to support interactive Omaha-only
- // installs.
- ASSERT1(!is_interactive);
- // TODO(omaha3): Figure out a way to send a ping from the installed location
- // for Omaha-only install success.
- }
-
- ++metric_setup_install_succeeded;
- return S_OK;
-}
-
-HRESULT OemInstall(bool is_interactive,
- bool is_app_install,
- bool is_eula_required,
- bool is_install_elevated_instance,
- const CString& install_cmd_line,
- const CommandLineArgs& args,
- bool* is_machine,
- bool* has_ui_been_displayed) {
- ASSERT1(is_machine);
- ASSERT1(has_ui_been_displayed);
-
- // OEM is handled as a special case, and the state must be correct before
- // calling Install().
- HRESULT hr = oem_install_utils::SetOemInstallState(*is_machine);
- if (FAILED(hr)) {
- CORE_LOG(LE, (_T("[SetOemInstallState failed][0x%x]"), hr));
- return hr;
- }
-
- hr = Install(is_interactive,
- is_app_install,
- is_eula_required,
- true,
- is_install_elevated_instance,
- install_cmd_line,
- args,
- is_machine,
- has_ui_been_displayed);
-
- if (FAILED(hr)) {
- VERIFY1(SUCCEEDED(oem_install_utils::ResetOemInstallState(*is_machine)));
- return hr;
- }
-
- ASSERT1(oem_install_utils::IsOemInstalling(*is_machine));
- return S_OK;
-}
-
-} // namespace omaha
« no previous file with comments | « client/install.h ('k') | client/install_apps.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698