| Index: goopdate/goopdate.cc
|
| diff --git a/goopdate/goopdate.cc b/goopdate/goopdate.cc
|
| deleted file mode 100644
|
| index aeda0aad554816c2bd3be877f4678364b108e607..0000000000000000000000000000000000000000
|
| --- a/goopdate/goopdate.cc
|
| +++ /dev/null
|
| @@ -1,1618 +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.
|
| -// ========================================================================
|
| -//
|
| -// For interactive instances, do not access the network before displaying the
|
| -// UI. This provides a better user experience - quick UI - when the network is
|
| -// slow. It is also required to ensure that UI displayed event is signaled
|
| -// before potentially waiting on a firewall prompt.
|
| -//
|
| -// Debugging notes:
|
| -// * Omaha initial install:
|
| -// /install "appguid={8A69D345-D564-463C-AFF1-A69D9E530F96}&appname=Google%20Chrome&needsadmin=False&lang=en" // NOLINT
|
| -// /install "appguid={283EAF47-8817-4c2b-A801-AD1FADFB7BAA}&appname=Gears&needsadmin=True&lang=en" // NOLINT
|
| -// * App install:
|
| -// /handoff "appguid={8A69D345-D564-463C-AFF1-A69D9E530F96}&appname=Google%20Chrome&needsadmin=False&lang=en" // NOLINT
|
| -// /handoff "appguid={283EAF47-8817-4c2b-A801-AD1FADFB7BAA}&appname=Gears&needsadmin=True&lang=en" // NOLINT
|
| -// * Silent install:
|
| -// * Add "/silent" to any of the above command lines (not to the tag).
|
| -// * Google Update self-update:
|
| -// /update
|
| -// * Update check for apps that need it:
|
| -// /ua
|
| -// * Core:
|
| -// /c
|
| -// * Cod Red check:
|
| -// /cr
|
| -// * Cod Red repair:
|
| -// /recover [/machine]
|
| -// * OneClick:
|
| -// /pi "http://www.google.com/" "/install%20%22appguid=%7B8A69D345-D564-463C-AFF1-A69D9E530F96%7D%26lang=en%26appname=Google%2520Chrome%26needsadmin=false" /installsource oneclick // NOLINT
|
| -// * COM server:
|
| -// -Embedding
|
| -
|
| -#include "omaha/goopdate/goopdate.h"
|
| -
|
| -#include <atlstr.h>
|
| -#include <new>
|
| -#include "base/scoped_ptr.h"
|
| -#include "omaha/base/app_util.h"
|
| -#include "omaha/base/const_object_names.h"
|
| -#include "omaha/base/crash_if_specific_error.h"
|
| -#include "omaha/base/debug.h"
|
| -#include "omaha/base/error.h"
|
| -#include "omaha/base/file.h"
|
| -#include "omaha/base/logging.h"
|
| -#include "omaha/base/module_utils.h"
|
| -#include "omaha/base/omaha_version.h"
|
| -#include "omaha/base/proc_utils.h"
|
| -#include "omaha/base/reg_key.h"
|
| -#include "omaha/base/safe_format.h"
|
| -#include "omaha/base/scoped_any.h"
|
| -#include "omaha/base/scoped_ptr_address.h"
|
| -#include "omaha/base/system_info.h"
|
| -#include "omaha/base/utils.h"
|
| -#include "omaha/base/vistautil.h"
|
| -#include "omaha/client/client_utils.h"
|
| -#include "omaha/client/install.h"
|
| -#include "omaha/client/install_apps.h"
|
| -#include "omaha/client/install_self.h"
|
| -#include "omaha/client/resource.h" // IDS_* are used in client modes only.
|
| -#include "omaha/client/ua.h"
|
| -#include "omaha/common/app_registry_utils.h"
|
| -#include "omaha/common/command_line.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/ping.h"
|
| -#include "omaha/common/lang.h"
|
| -#include "omaha/common/oem_install_utils.h"
|
| -#include "omaha/common/stats_uploader.h"
|
| -#include "omaha/common/webplugin_utils.h"
|
| -#include "omaha/core/core.h"
|
| -#include "omaha/core/crash_handler.h"
|
| -#include "omaha/goopdate/code_red_check.h"
|
| -#include "omaha/goopdate/crash.h"
|
| -#include "omaha/goopdate/google_update.h"
|
| -#include "omaha/goopdate/goopdate_internal.h"
|
| -#include "omaha/goopdate/goopdate_metrics.h"
|
| -#include "omaha/goopdate/resource_manager.h"
|
| -#include "omaha/net/net_diags.h"
|
| -#include "omaha/service/service_main.h"
|
| -#include "omaha/setup/setup_service.h"
|
| -#include "third_party/breakpad/src/client/windows/sender/crash_report_sender.h"
|
| -#include "third_party/breakpad/src/client/windows/handler/exception_handler.h"
|
| -
|
| -// TODO(omaha3): Where should we put this? In Omaha 2, it was in worker.cc.
|
| -// TODO(omaha): fix this clunkiness and require explicit registration of the
|
| -// http creators with the factory. Not ideal but better then linker options.
|
| -#pragma comment(linker, "/INCLUDE:_kRegisterWinHttp")
|
| -
|
| -namespace omaha {
|
| -
|
| -namespace {
|
| -
|
| -#if DEBUG
|
| -const TCHAR* const kBuildType = _T("dbg");
|
| -#else
|
| -const TCHAR* const kBuildType = _T("opt");
|
| -#endif
|
| -
|
| -#if OFFICIAL_BUILD
|
| -const TCHAR* const kOfficialBuild = _T("official");
|
| -#else
|
| -const TCHAR* const kOfficialBuild = _T("dev");
|
| -#endif
|
| -
|
| -#if DEBUG
|
| -// Returns true if the binary's version matches the installed version or this
|
| -// mode does not require the versions to match.
|
| -bool CheckRegisteredVersion(const CString& version,
|
| - bool is_machine,
|
| - CommandLineMode mode) {
|
| - switch (mode) {
|
| - // Modes that may run before or during installation or otherwise do not
|
| - // need to match the installed version.
|
| - case COMMANDLINE_MODE_UNKNOWN:
|
| - case COMMANDLINE_MODE_NOARGS:
|
| - case COMMANDLINE_MODE_REGSERVER:
|
| - case COMMANDLINE_MODE_UNREGSERVER:
|
| - case COMMANDLINE_MODE_NETDIAGS:
|
| - case COMMANDLINE_MODE_CRASH:
|
| - case COMMANDLINE_MODE_REPORTCRASH:
|
| - case COMMANDLINE_MODE_INSTALL:
|
| - case COMMANDLINE_MODE_UPDATE:
|
| - case COMMANDLINE_MODE_RECOVER:
|
| - case COMMANDLINE_MODE_WEBPLUGIN:
|
| - case COMMANDLINE_MODE_REGISTER_PRODUCT:
|
| - case COMMANDLINE_MODE_UNREGISTER_PRODUCT:
|
| - case COMMANDLINE_MODE_SERVICE_REGISTER:
|
| - case COMMANDLINE_MODE_SERVICE_UNREGISTER:
|
| - case COMMANDLINE_MODE_PING:
|
| - return true;
|
| -
|
| - // COM servers and services that should only run after installation.
|
| - case COMMANDLINE_MODE_CORE:
|
| - case COMMANDLINE_MODE_SERVICE:
|
| - case COMMANDLINE_MODE_CODE_RED_CHECK:
|
| - case COMMANDLINE_MODE_COMSERVER:
|
| - case COMMANDLINE_MODE_CRASH_HANDLER:
|
| - case COMMANDLINE_MODE_COMBROKER:
|
| - case COMMANDLINE_MODE_ONDEMAND:
|
| - case COMMANDLINE_MODE_MEDIUM_SERVICE:
|
| -
|
| - // Clients that should only run after installation and should match the
|
| - // installed version.
|
| - case COMMANDLINE_MODE_HANDOFF_INSTALL:
|
| - case COMMANDLINE_MODE_UA:
|
| - case COMMANDLINE_MODE_UNINSTALL:
|
| -
|
| - default:
|
| - // This binary's version should be the installed version.
|
| - CString installed_version;
|
| - VERIFY1(SUCCEEDED(RegKey::GetValue(
|
| - ConfigManager::Instance()->registry_update(is_machine),
|
| - kRegValueInstalledVersion,
|
| - &installed_version)));
|
| - return version == installed_version;
|
| - }
|
| -}
|
| -#endif
|
| -
|
| -} // namespace
|
| -
|
| -namespace detail {
|
| -
|
| -class GoopdateImpl {
|
| - public:
|
| - GoopdateImpl(Goopdate* goopdate, bool is_local_system);
|
| - ~GoopdateImpl();
|
| -
|
| - HRESULT Main(HINSTANCE instance, const TCHAR* cmd_line, int cmd_show);
|
| -
|
| - HRESULT QueueUserWorkItem(UserWorkItem* work_item, uint32 flags);
|
| -
|
| - void Stop();
|
| -
|
| - bool is_local_system() const { return is_local_system_; }
|
| -
|
| - private:
|
| - HRESULT DoMain(HINSTANCE instance, const TCHAR* cmd_line, int cmd_show);
|
| -
|
| - // Performs initialization that must be done as soon as the command line has
|
| - // been parsed and loads the resources. If this method succeeds, we can use
|
| - // the resources - for example, to display error messagse.
|
| - HRESULT InitializeGoopdateAndLoadResources();
|
| -
|
| - // Executes the mode determined by DoMain().
|
| - HRESULT ExecuteMode(bool* has_ui_been_displayed);
|
| -
|
| - // Returns whether a process is a machine process.
|
| - // Does not determine whether the process has the appropriate privileges.
|
| - bool IsMachineProcess();
|
| -
|
| - bool ShouldCheckShutdownEvent(CommandLineMode mode);
|
| - bool IsShutdownEventSet();
|
| -
|
| - HRESULT LoadResourceDllIfNecessary(CommandLineMode mode,
|
| - const CString& resource_dir);
|
| -
|
| - HRESULT SetUsageStatsEnable();
|
| -
|
| - // Handles error conditions by showing UI if appropriate.
|
| - void HandleError(HRESULT hr, bool has_ui_been_displayed);
|
| -
|
| - // Handles response to /pi command.
|
| - HRESULT HandleWebPlugin();
|
| -
|
| - // Handles responses to /cr command.
|
| - HRESULT HandleCodeRedCheck();
|
| -
|
| - // Handles /report command.
|
| - HRESULT HandleReportCrash();
|
| -
|
| - // Installs apps for the /handoff instance.
|
| - HRESULT DoHandoff(bool* has_ui_been_displayed);
|
| -
|
| - // Updates all registered apps for the /ua instance.
|
| - HRESULT DoUpdateAllApps(bool* has_ui_been_displayed);
|
| -
|
| - // Generates a divide by zero to trigger breakpad dump.
|
| - // Is only enabled in debug builds.
|
| - HRESULT DoCrash();
|
| -
|
| - // Install Omaha.
|
| - HRESULT DoInstall(bool* has_ui_been_displayed);
|
| -
|
| - // Silently update Omaha.
|
| - HRESULT DoSelfUpdate();
|
| -
|
| - // Handles the recover command in Google Update.
|
| - HRESULT DoRecover();
|
| -
|
| - // Uninstalls Omaha if appropriate.
|
| - HRESULT HandleUninstall();
|
| -
|
| - // Pings the Omaha server with a string.
|
| - HRESULT HandlePing();
|
| -
|
| - // TODO(omaha): Reconcile the two uninstall functions and paths.
|
| - void MaybeUninstallGoogleUpdate();
|
| -
|
| - // Uninstalls Google Update if a /install process failed to install itself
|
| - // or the app and there are no other apps registered.
|
| - HRESULT UninstallIfNecessary();
|
| -
|
| - // Called by operator new or operator new[] when they cannot satisfy
|
| - // a request for additional storage.
|
| - static void OutOfMemoryHandler();
|
| -
|
| - static HRESULT CaptureOSMetrics();
|
| -
|
| - HINSTANCE module_instance_; // Current module instance.
|
| - CString cmd_line_; // Command line, as provided by the OS.
|
| - int cmd_show_;
|
| -
|
| - CommandLineArgs args_; // Command line options and flags.
|
| -
|
| - // True if the process belongs to a machine Omaha "session".
|
| - bool is_machine_;
|
| - bool is_local_system_; // True if running as LOCAL_SYSTEM.
|
| - CString this_version_; // Version of this Goopdate DLL.
|
| -
|
| - // True if Omaha has been uninstalled by the Worker.
|
| - bool has_uninstalled_;
|
| -
|
| - // Language identifier for the current user locale.
|
| - CString user_default_language_id_;
|
| -
|
| - scoped_ptr<ThreadPool> thread_pool_;
|
| -
|
| - Goopdate* goopdate_;
|
| -
|
| - DISALLOW_EVIL_CONSTRUCTORS(GoopdateImpl);
|
| -};
|
| -
|
| -GoopdateImpl::GoopdateImpl(Goopdate* goopdate, bool is_local_system)
|
| - : module_instance_(NULL),
|
| - cmd_show_(0),
|
| - is_local_system_(is_local_system),
|
| - has_uninstalled_(false),
|
| - goopdate_(goopdate) {
|
| - ASSERT1(goopdate);
|
| -
|
| - ++metric_goopdate_constructor;
|
| -
|
| - // The command line needs to be parsed to accurately determine if the current
|
| - // process is a machine process or not. Take an upfront guess before that.
|
| - is_machine_ = vista_util::IsUserAdmin() &&
|
| - goopdate_utils::IsRunningFromOfficialGoopdateDir(true);
|
| -
|
| - // Install an error-handling mechanism which gets called when new operator
|
| - // fails to allocate memory.
|
| - VERIFY1(set_new_handler(&GoopdateImpl::OutOfMemoryHandler) == 0);
|
| -
|
| - // Install the exception handler.
|
| - VERIFY1(SUCCEEDED(Crash::InstallCrashHandler(is_machine_)));
|
| -
|
| - // Hints network configure manager how to create its singleton.
|
| - NetworkConfigManager::set_is_machine(is_machine_);
|
| -
|
| - // Initialize the global metrics collection.
|
| - stats_report::g_global_metrics.Initialize();
|
| -
|
| - // TODO(omaha): Support multiple HRESULT codes to crash on.
|
| - // TODO(omaha): Support passing in HRESULT codes via the command line,
|
| - // especially for "/update".
|
| - DWORD crash_specific_error = 0;
|
| - if (SUCCEEDED(RegKey::GetValue(MACHINE_REG_UPDATE_DEV,
|
| - kRegValueNameCrashIfSpecificError,
|
| - &crash_specific_error))) {
|
| - omaha::g_crash_specific_error = static_cast<HRESULT>(crash_specific_error);
|
| - }
|
| -
|
| - static const int kThreadPoolShutdownDelayMs = 60000;
|
| - thread_pool_.reset(new ThreadPool);
|
| - HRESULT hr = thread_pool_->Initialize(kThreadPoolShutdownDelayMs);
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE, (_T("[thread_pool_->Initialize failed][0x%08x]"), hr));
|
| - }
|
| -}
|
| -
|
| -GoopdateImpl::~GoopdateImpl() {
|
| - CORE_LOG(L2, (_T("[GoopdateImpl::~GoopdateImpl]")));
|
| -
|
| - ++metric_goopdate_destructor;
|
| -
|
| - Stop();
|
| -
|
| - // Bug 994348 does not repro anymore.
|
| - // If the assert fires, clean up the key, and fix the code if we have unit
|
| - // tests or application code that create the key.
|
| - ASSERT(!RegKey::HasKey(_T("HKEY_USERS\\.DEFAULT\\Software\\Google\\Update")),
|
| - (_T("This assert has fired because it has found the registry key at ")
|
| - _T("'HKEY_USERS\\.DEFAULT\\Software\\Google\\Update'. ")
|
| - _T("Please delete the key and report to omaha-core team if ")
|
| - _T("the assert fires again.")));
|
| -
|
| - // The global metrics collection must be uninitialized before the metrics
|
| - // destructors are called.
|
| - stats_report::g_global_metrics.Uninitialize();
|
| -
|
| - // Uninstall the exception handler. Program crashes are handled by Windows
|
| - // Error Reporting (WER) beyond this point.
|
| - Crash::UninstallCrashHandler();
|
| -
|
| - // Reset the new handler.
|
| - set_new_handler(NULL);
|
| -}
|
| -
|
| -HRESULT GoopdateImpl::QueueUserWorkItem(UserWorkItem* work_item, uint32 flags) {
|
| - CORE_LOG(L3, (_T("[GoopdateImpl::QueueUserWorkItem]")));
|
| - ASSERT1(work_item);
|
| -
|
| - ASSERT1(thread_pool_.get());
|
| -
|
| - return thread_pool_->QueueUserWorkItem(work_item, flags);
|
| -}
|
| -
|
| -void GoopdateImpl::Stop() {
|
| - // The thread pool destructor waits for any remaining jobs to complete.
|
| - thread_pool_.reset();
|
| -}
|
| -
|
| -// Assumes the resources are loaded and members are initialized.
|
| -void GoopdateImpl::HandleError(HRESULT hr, bool has_ui_been_displayed) {
|
| - CORE_LOG(L3, (_T("[GoopdateImpl::HandleError][0x%x][%u]"),
|
| - hr, has_ui_been_displayed));
|
| -
|
| - if (has_ui_been_displayed ||
|
| - !internal::CanDisplayUi(args_.mode, args_.is_silent_set)) {
|
| - return;
|
| - }
|
| -
|
| - const CString& bundle_name = args_.extra.bundle_name;
|
| - CString primary_app_guid;
|
| - if (!args_.extra.apps.empty()) {
|
| - primary_app_guid = GuidToString(args_.extra.apps[0].app_guid);
|
| - }
|
| -
|
| - CString error_text;
|
| - switch (hr) {
|
| - case GOOPDATE_E_UA_ALREADY_RUNNING:
|
| - error_text.FormatMessage(IDS_APPLICATION_ALREADY_INSTALLING,
|
| - client_utils::GetUpdateAllAppsBundleName());
|
| - break;
|
| - case OMAHA_NET_E_WINHTTP_NOT_AVAILABLE:
|
| - ASSERT1(!bundle_name.IsEmpty());
|
| - error_text.FormatMessage(IDS_WINDOWS_IS_NOT_UP_TO_DATE,
|
| - bundle_name);
|
| - break;
|
| - default:
|
| - // TODO(omaha3): This currently assumes that any error returned here is
|
| - // related to Setup.
|
| - CString product_name;
|
| - VERIFY1(product_name.LoadString(IDS_PRODUCT_DISPLAY_NAME));
|
| - error_text.FormatMessage(IDS_SETUP_FAILED, product_name, hr);
|
| - break;
|
| - }
|
| -
|
| - VERIFY1(client_utils::DisplayError(is_machine_,
|
| - bundle_name,
|
| - hr,
|
| - 0,
|
| - error_text,
|
| - primary_app_guid,
|
| - args_.extra.language,
|
| - args_.extra.installation_id,
|
| - args_.extra.brand_code));
|
| -}
|
| -
|
| -HRESULT GoopdateImpl::Main(HINSTANCE instance,
|
| - const TCHAR* cmd_line,
|
| - int cmd_show) {
|
| - ++metric_goopdate_main;
|
| -
|
| - HRESULT hr = DoMain(instance, cmd_line, cmd_show);
|
| -
|
| - CORE_LOG(L2, (_T("[has_uninstalled_ is %d]"), has_uninstalled_));
|
| -
|
| - // For install processes, verify the Google Update EULA has been accepted and
|
| - // we can use the network unless a) the command line specifies EULA is
|
| - // required or b) in OEM installing mode, which also prevents network use.
|
| - if ((COMMANDLINE_MODE_INSTALL == args_.mode ||
|
| - COMMANDLINE_MODE_HANDOFF_INSTALL == args_.mode) &&
|
| - SUCCEEDED(hr)) {
|
| - ASSERT1(args_.is_eula_required_set ||
|
| - ConfigManager::Instance()->CanUseNetwork(is_machine_) ||
|
| - oem_install_utils::IsOemInstalling(is_machine_));
|
| - }
|
| -
|
| - // In the /install case, clean up if Google Update and/or app install did not
|
| - // complete successfully.
|
| - // Only aggregate the metrics if there is no chance that Google Update has
|
| - // or may be uninstalled and the process has the appropriate permissions.
|
| - // Uninstall will aggregate and report the metrics as appropriate.
|
| - bool did_install_uninstall_fail = false;
|
| - if (COMMANDLINE_MODE_INSTALL == args_.mode) {
|
| - did_install_uninstall_fail = FAILED(UninstallIfNecessary());
|
| - } else if (!has_uninstalled_) {
|
| - if (args_.mode == COMMANDLINE_MODE_UA) {
|
| - VERIFY1(SUCCEEDED(AggregateAndReportMetrics(is_machine_, false)));
|
| - } else if (!is_machine_ || vista_util::IsUserAdmin()) {
|
| - VERIFY1(SUCCEEDED(AggregateMetrics(is_machine_)));
|
| - }
|
| - }
|
| -
|
| - Worker::DeleteInstance();
|
| -
|
| - // Uninitializing the network configuration must happen after reporting the
|
| - // metrics. The call succeeds even if the network has not been initialized
|
| - // due to errors up the execution path.
|
| - NetworkConfigManager::DeleteInstance();
|
| -
|
| - if (COMMANDLINE_MODE_INSTALL == args_.mode &&
|
| - args_.is_oem_set &&
|
| - SUCCEEDED(hr) &&
|
| - !oem_install_utils::IsOemInstalling(is_machine_)) {
|
| - ASSERT1(false);
|
| - hr = GOOPDATE_E_OEM_INSTALL_SUCCEEDED_BUT_NOT_IN_OEM_INSTALLING_MODE;
|
| - }
|
| -
|
| - // Verify that Google Update is either completely installed or uninstalled.
|
| - // Do not check in the following cases:
|
| - // * Modes that may exit during Setup, during uninstall, or while Omaha
|
| - // is partially installed.
|
| - // * The mode is unknown, which means the args were not be parsed.
|
| - // * /cr instance, which may exit after Omaha is uninstalled.
|
| - // * /install instance that would not have called Setup.Uninstall().
|
| - // * /install instance when Uninstall failed for some reason since the
|
| - // the consistency check may expect the wrong state.
|
| - // * /update instance that failed due to an install/uninstall in progress.
|
| - if (COMMANDLINE_MODE_REGSERVER != args_.mode &&
|
| - COMMANDLINE_MODE_UNREGSERVER != args_.mode &&
|
| - COMMANDLINE_MODE_COMSERVER != args_.mode &&
|
| - COMMANDLINE_MODE_CODE_RED_CHECK != args_.mode &&
|
| - COMMANDLINE_MODE_SERVICE_REGISTER != args_.mode &&
|
| - COMMANDLINE_MODE_SERVICE_UNREGISTER != args_.mode &&
|
| - COMMANDLINE_MODE_UNKNOWN != args_.mode &&
|
| - !(COMMANDLINE_MODE_INSTALL == args_.mode &&
|
| - is_machine_ &&
|
| - !vista_util::IsUserAdmin()) &&
|
| - !(COMMANDLINE_MODE_UPDATE == args_.mode &&
|
| - GOOPDATE_E_FAILED_TO_GET_LOCK == hr) &&
|
| - !did_install_uninstall_fail) {
|
| - install_self::CheckInstallStateConsistency(is_machine_);
|
| - }
|
| -
|
| - ResourceManager::Delete();
|
| -
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT GoopdateImpl::DoMain(HINSTANCE instance,
|
| - const TCHAR* cmd_line,
|
| - int cmd_show) {
|
| - module_instance_ = instance;
|
| - cmd_line_ = cmd_line;
|
| - cmd_show_ = cmd_show;
|
| -
|
| - // The system terminates the process without displaying a retry dialog box
|
| - // for the user. GoogleUpdate has no user state to be saved, therefore
|
| - // prompting the user for input is meaningless.
|
| - VERIFY1(SUCCEEDED(SetProcessSilentShutdown()));
|
| -
|
| - VERIFY1(SUCCEEDED(CaptureOSMetrics()));
|
| -
|
| - InitializeVersionFromModule(module_instance_);
|
| - this_version_ = GetVersionString();
|
| -
|
| - TCHAR path[MAX_PATH] = {0};
|
| - VERIFY1(::GetModuleFileName(module_instance_, path, MAX_PATH));
|
| - OPT_LOG(L1, (_T("[%s][version %s][%s][%s]"),
|
| - path, this_version_, kBuildType, kOfficialBuild));
|
| -
|
| - CORE_LOG(L2, (_T("[is system %d]")
|
| - _T("[elevated admin %d]")
|
| - _T("[non-elevated admin %d]")
|
| - _T("[testsource %s]"),
|
| - is_local_system_,
|
| - vista_util::IsUserAdmin(),
|
| - vista_util::IsUserNonElevatedAdmin(),
|
| - ConfigManager::Instance()->GetTestSource()));
|
| -
|
| - HRESULT parse_hr = omaha::ParseCommandLine(cmd_line_, &args_);
|
| - if (FAILED(parse_hr)) {
|
| - CORE_LOG(LE, (_T("[Parse cmd line failed][0x%08x]"), parse_hr));
|
| - args_.mode = COMMANDLINE_MODE_UNKNOWN;
|
| - // Continue because we want to load the resources and display an error.
|
| - }
|
| -
|
| - // TODO(omaha3): Interactive updates might be useful for debugging or even
|
| - // on-demand updates of all apps. Figure out how to expose this. For now, no
|
| - // install source, which should not happen normally, is used as the trigger.
|
| - // The simplest way to make this work is to set args_.is_silent_set
|
| - // accordingly. However, we also need a way for this to work for per-machine
|
| - // instances since IsMachineProcess() relies on being Local System. When we
|
| - // settle on a mechanism, we should update the parser and remove this.
|
| - if (args_.mode == COMMANDLINE_MODE_UA) {
|
| - args_.is_silent_set = !args_.install_source.IsEmpty();
|
| - }
|
| -
|
| - HRESULT hr = InitializeGoopdateAndLoadResources();
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE,
|
| - (_T("[InitializeGoopdateAndLoadResources failed][0x%08x]"), hr));
|
| - if (internal::CanDisplayUi(args_.mode, args_.is_silent_set)) {
|
| - // The resources are unavaliable, so we must use hard-coded text.
|
| - const TCHAR* const kMsgBoxTitle = _T("Google Installer");
|
| - CString message;
|
| - message.Format(_T("Installation failed with error 0x%08x."), hr);
|
| - VERIFY1(IDOK == ::MessageBox(NULL, message, kMsgBoxTitle, MB_OK));
|
| - }
|
| - return hr;
|
| - }
|
| - // The resources are now loaded and available if applicable for this instance.
|
| - // If there was no bundle name specified on the command line, we take the
|
| - // bundle name from the first app's name; if that has no name (or if there is
|
| - // no apps, as in a runtime-only install) it will be an empty string.
|
| - // Replace it with the localized installer name.
|
| - if (args_.extra.bundle_name.IsEmpty()) {
|
| - args_.extra.bundle_name.LoadString(IDS_PRODUCT_DISPLAY_NAME);
|
| - }
|
| -
|
| - CORE_LOG(L2, (_T("[can use network %d]")
|
| - _T("[can collect stats %d]"),
|
| - ConfigManager::Instance()->CanUseNetwork(is_machine_),
|
| - ConfigManager::Instance()->CanCollectStats(is_machine_)));
|
| -
|
| - bool has_ui_been_displayed = false;
|
| -
|
| - if (!is_machine_ && vista_util::IsElevatedWithUACMaybeOn()) {
|
| - CORE_LOG(LW, (_T("User GoogleUpdate is possibly running in an unsupported ")
|
| - _T("way, at High integrity with UAC possibly enabled.")));
|
| - }
|
| -
|
| - if (FAILED(parse_hr)) {
|
| - ASSERT1(args_.mode == COMMANDLINE_MODE_UNKNOWN);
|
| - hr = parse_hr;
|
| - } else {
|
| - ASSERT1(args_.mode != COMMANDLINE_MODE_UNKNOWN);
|
| - // TODO(omaha): I would like to pass the mode as an argument, but there
|
| - // are so many uses for args_.mode and they could easily creep in. Consider
|
| - // eliminating the args_ member.
|
| - hr = ExecuteMode(&has_ui_been_displayed);
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE, (_T("[ExecuteMode failed][0x%08x]"), hr));
|
| - // Continue and display error.
|
| - }
|
| - }
|
| -
|
| - if (FAILED(hr)) {
|
| - HandleError(hr, has_ui_been_displayed);
|
| - return hr;
|
| - }
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| -// Assumes the command line has been parsed.
|
| -HRESULT GoopdateImpl::InitializeGoopdateAndLoadResources() {
|
| - // IsMachineProcess requires the command line be parsed first.
|
| - is_machine_ = IsMachineProcess();
|
| - OPT_LOG(L1, (_T("[is machine: %d]"), is_machine_));
|
| -
|
| - if (!::SetEnvironmentVariable(kEnvVariableIsMachine,
|
| - is_machine_ ? _T("1") : _T("0"))) {
|
| - HRESULT hr = HRESULTFromLastError();
|
| - CORE_LOG(LW, (_T("[::SetEnvironmentVariable failed][%s][0x%x]"),
|
| - kEnvVariableIsMachine, hr));
|
| - }
|
| -
|
| - // After parsing the command line, reinstall the crash handler to match the
|
| - // state of the process.
|
| - if (is_machine_ != Crash::is_machine()) {
|
| - VERIFY1(SUCCEEDED(Crash::InstallCrashHandler(is_machine_)));
|
| - }
|
| -
|
| - // We have parsed the command line, and we are now resetting is_machine.
|
| - NetworkConfigManager::set_is_machine(
|
| - is_machine_ && vista_util::IsUserAdmin());
|
| -
|
| - // Set the current directory to be the one that the DLL was launched from.
|
| - TCHAR module_directory[MAX_PATH] = {0};
|
| - if (!GetModuleDirectory(module_instance_, module_directory)) {
|
| - return HRESULTFromLastError();
|
| - }
|
| - if (!::SetCurrentDirectory(module_directory)) {
|
| - return HRESULTFromLastError();
|
| - }
|
| - OPT_LOG(L3, (_T("[Current dir][%s]"), module_directory));
|
| -
|
| - // Set the usage stats as soon as possible, which is after the command line
|
| - // has been parsed, so that we can report crashes and other stats.
|
| - VERIFY1(SUCCEEDED(SetUsageStatsEnable()));
|
| -
|
| - VERIFY1(SUCCEEDED(internal::PromoteAppEulaAccepted(is_machine_)));
|
| -
|
| - if (ShouldCheckShutdownEvent(args_.mode) && IsShutdownEventSet()) {
|
| - return GOOPDATE_E_SHUTDOWN_SIGNALED;
|
| - }
|
| -
|
| - HRESULT hr = LoadResourceDllIfNecessary(args_.mode, module_directory);
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE, (_T("[LoadResourceDllIfNecessary failed][0x%08x]"), hr));
|
| - return hr;
|
| - }
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| -// Assumes Goopdate is initialized and resources are loaded.
|
| -HRESULT GoopdateImpl::ExecuteMode(bool* has_ui_been_displayed) {
|
| - ASSERT1(has_ui_been_displayed);
|
| -
|
| - // Save the mode on the stack for post-mortem debugging purposes.
|
| - volatile CommandLineMode mode = args_.mode;
|
| -
|
| - user_default_language_id_ = lang::GetDefaultLanguage(is_local_system_);
|
| -
|
| - ASSERT1(CheckRegisteredVersion(GetVersionString(), is_machine_, mode));
|
| -
|
| -#pragma warning(push)
|
| -// C4061: enumerator 'xxx' in switch of enum 'yyy' is not explicitly handled by
|
| -// a case label.
|
| -#pragma warning(disable : 4061)
|
| - switch (mode) {
|
| - // Delegate to the service or the core. Both have reliability requirements
|
| - // and resource constraints. Generally speaking, they do not use COM nor
|
| - // networking code.
|
| - case COMMANDLINE_MODE_SERVICE:
|
| - return omaha::Update3ServiceModule().Main(SW_HIDE);
|
| -
|
| - case COMMANDLINE_MODE_MEDIUM_SERVICE:
|
| - return omaha::UpdateMediumServiceModule().Main(SW_HIDE);
|
| -
|
| - case COMMANDLINE_MODE_SERVICE_REGISTER: {
|
| - HRESULT hr = SetupUpdate3Service::InstallService(
|
| - app_util::GetModulePath(NULL));
|
| - if (FAILED(hr)) {
|
| - return hr;
|
| - }
|
| - return SetupUpdateMediumService::InstallService(
|
| - app_util::GetModulePath(NULL));
|
| - }
|
| -
|
| - case COMMANDLINE_MODE_SERVICE_UNREGISTER: {
|
| - HRESULT hr = SetupUpdate3Service::UninstallService();
|
| - if (FAILED(hr)) {
|
| - return hr;
|
| - }
|
| - return SetupUpdateMediumService::UninstallService();
|
| - }
|
| -
|
| - default: {
|
| - scoped_co_init init_com_apt(COINIT_MULTITHREADED);
|
| - HRESULT hr = init_com_apt.hresult();
|
| - if (FAILED(hr)) {
|
| - return hr;
|
| - }
|
| -
|
| - switch (mode) {
|
| - case COMMANDLINE_MODE_CORE:
|
| - return omaha::Core().Main(is_local_system_,
|
| - !args_.is_crash_handler_disabled);
|
| -
|
| - case COMMANDLINE_MODE_CRASH_HANDLER:
|
| - return omaha::CrashHandler().Main(is_local_system_);
|
| -
|
| - case COMMANDLINE_MODE_NOARGS:
|
| - return GOOPDATE_E_NO_ARGS;
|
| -
|
| - case COMMANDLINE_MODE_UNREGISTER_PRODUCT:
|
| - // TODO(omaha3): Eliminate the need for this mode.
|
| - return E_FAIL;
|
| -
|
| - case COMMANDLINE_MODE_COMBROKER:
|
| - return omaha::GoogleUpdate(is_machine_,
|
| - omaha::GoogleUpdate::kBrokerMode).Main();
|
| -
|
| - case COMMANDLINE_MODE_ONDEMAND:
|
| - return omaha::GoogleUpdate(
|
| - is_machine_,
|
| - omaha::GoogleUpdate::kOnDemandMode).Main();
|
| -
|
| - default: {
|
| - // Reference the network instance here so the singleton can be
|
| - // created before possible impersonation.
|
| - NetworkConfigManager::Instance();
|
| -
|
| - switch (mode) {
|
| - case COMMANDLINE_MODE_WEBPLUGIN:
|
| - return HandleWebPlugin();
|
| -
|
| - case COMMANDLINE_MODE_CODE_RED_CHECK:
|
| - return HandleCodeRedCheck();
|
| -
|
| - case COMMANDLINE_MODE_NETDIAGS:
|
| - return NetDiags().Main();
|
| -
|
| - case COMMANDLINE_MODE_REGISTER_PRODUCT:
|
| - // TODO(omaha3): Eliminate the need for this mode.
|
| - return E_FAIL;
|
| -
|
| - case COMMANDLINE_MODE_INSTALL:
|
| - return DoInstall(has_ui_been_displayed);
|
| -
|
| - case COMMANDLINE_MODE_UPDATE:
|
| - return DoSelfUpdate();
|
| -
|
| - case COMMANDLINE_MODE_RECOVER:
|
| - return DoRecover();
|
| -
|
| - case COMMANDLINE_MODE_HANDOFF_INSTALL:
|
| - return DoHandoff(has_ui_been_displayed);
|
| -
|
| - case COMMANDLINE_MODE_UA:
|
| - return DoUpdateAllApps(has_ui_been_displayed);
|
| -
|
| - case COMMANDLINE_MODE_CRASH:
|
| - return DoCrash();
|
| -
|
| - case COMMANDLINE_MODE_REPORTCRASH:
|
| - return HandleReportCrash();
|
| -
|
| - case COMMANDLINE_MODE_REGSERVER:
|
| - case COMMANDLINE_MODE_UNREGSERVER: {
|
| - hr = omaha::GoogleUpdate(
|
| - is_machine_, omaha::GoogleUpdate::kUpdate3Mode).Main();
|
| - if (FAILED(hr)) {
|
| - return hr;
|
| - }
|
| - hr = omaha::GoogleUpdate(
|
| - is_machine_, omaha::GoogleUpdate::kBrokerMode).Main();
|
| - if (FAILED(hr)) {
|
| - return hr;
|
| - }
|
| - return omaha::GoogleUpdate(
|
| - is_machine_, omaha::GoogleUpdate::kOnDemandMode).Main();
|
| - }
|
| -
|
| - case COMMANDLINE_MODE_COMSERVER:
|
| - return omaha::GoogleUpdate(
|
| - is_machine_, omaha::GoogleUpdate::kUpdate3Mode).Main();
|
| -
|
| - case COMMANDLINE_MODE_UNINSTALL:
|
| - return HandleUninstall();
|
| -
|
| - case COMMANDLINE_MODE_PING:
|
| - return HandlePing();
|
| -
|
| - default:
|
| - // We have a COMMANDLINE_MODE_ that isn't being handled.
|
| - ASSERT1(false);
|
| - OPT_LOG(LE, (_T("[Command line has unhandled mode]")));
|
| - return E_UNEXPECTED;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - }
|
| -#pragma warning(pop)
|
| -}
|
| -
|
| -bool GoopdateImpl::IsMachineProcess() {
|
| - Tristate needs_admin(TRISTATE_NONE);
|
| - if (!args_.extra.apps.empty()) {
|
| - needs_admin = args_.extra.apps[0].needs_admin != NEEDS_ADMIN_NO ?
|
| - TRISTATE_TRUE : TRISTATE_FALSE;
|
| - }
|
| -
|
| - return internal::IsMachineProcess(
|
| - args_.mode,
|
| - goopdate_utils::IsRunningFromOfficialGoopdateDir(true),
|
| - is_local_system_,
|
| - args_.is_machine_set,
|
| - needs_admin);
|
| -}
|
| -
|
| -
|
| -HRESULT GoopdateImpl::HandleReportCrash() {
|
| - ++metric_goopdate_handle_report_crash;
|
| - VERIFY1(SUCCEEDED(AggregateMetrics(is_machine_)));
|
| -
|
| - // Catch exceptions to avoid reporting crashes when handling a crash.
|
| - // TODO(omaha): maybe let Windows handle the crashes when reporting crashes
|
| - // in certain interactive modes.
|
| - HRESULT hr = S_OK;
|
| - __try {
|
| - // Crashes are uploaded always in the out-of-process case.
|
| - //
|
| - // Google Update internal crashes are handled in-process. They are uploaded
|
| - // only for the users that have opted in sending usage stats and when
|
| - // network use is allowed, and from systems that are not development
|
| - // nor test.
|
| - // This default behavior can be overriden by an UpdatedDev parameter that
|
| - // allows crashes to be uploaded always.
|
| - //
|
| - // All GoogleUpdate crashes are logged in the Windows event log for
|
| - // applications, unless the logging is disabled by the administrator.
|
| - ConfigManager* cm = ConfigManager::Instance();
|
| - const bool can_upload_in_process = cm->AlwaysAllowCrashUploads() ||
|
| - (cm->CanCollectStats(is_machine_) &&
|
| - cm->CanUseNetwork(is_machine_) &&
|
| - !goopdate_utils::IsTestSource());
|
| - hr = Crash::Report(can_upload_in_process,
|
| - args_.crash_filename,
|
| - args_.custom_info_filename,
|
| - user_default_language_id_);
|
| - }
|
| - __except(EXCEPTION_EXECUTE_HANDLER) {
|
| - hr = E_FAIL;
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -bool GoopdateImpl::ShouldCheckShutdownEvent(CommandLineMode mode) {
|
| - switch (mode) {
|
| - // Modes that may run before or during installation or otherwise do not
|
| - // need to listen to shutdown.
|
| - case COMMANDLINE_MODE_UNKNOWN:
|
| - case COMMANDLINE_MODE_NOARGS:
|
| - case COMMANDLINE_MODE_REGSERVER:
|
| - case COMMANDLINE_MODE_UNREGSERVER:
|
| - case COMMANDLINE_MODE_NETDIAGS:
|
| - case COMMANDLINE_MODE_CRASH:
|
| - case COMMANDLINE_MODE_REPORTCRASH:
|
| - case COMMANDLINE_MODE_RECOVER:
|
| - case COMMANDLINE_MODE_SERVICE_REGISTER:
|
| - case COMMANDLINE_MODE_SERVICE_UNREGISTER:
|
| -
|
| - case COMMANDLINE_MODE_INSTALL:
|
| - case COMMANDLINE_MODE_UPDATE:
|
| - case COMMANDLINE_MODE_WEBPLUGIN:
|
| - case COMMANDLINE_MODE_CODE_RED_CHECK:
|
| - case COMMANDLINE_MODE_REGISTER_PRODUCT:
|
| - case COMMANDLINE_MODE_UNREGISTER_PRODUCT:
|
| - case COMMANDLINE_MODE_PING:
|
| - return false;
|
| -
|
| - // Modes that should honor shutdown.
|
| - case COMMANDLINE_MODE_CORE:
|
| - case COMMANDLINE_MODE_SERVICE:
|
| - case COMMANDLINE_MODE_COMSERVER:
|
| - case COMMANDLINE_MODE_CRASH_HANDLER:
|
| - case COMMANDLINE_MODE_COMBROKER:
|
| - case COMMANDLINE_MODE_ONDEMAND:
|
| - case COMMANDLINE_MODE_MEDIUM_SERVICE:
|
| -
|
| - case COMMANDLINE_MODE_HANDOFF_INSTALL:
|
| - case COMMANDLINE_MODE_UA:
|
| - case COMMANDLINE_MODE_UNINSTALL:
|
| - return true;
|
| -
|
| - default:
|
| - ASSERT1(false);
|
| - return true;
|
| - }
|
| -}
|
| -
|
| -bool GoopdateImpl::IsShutdownEventSet() {
|
| - NamedObjectAttributes attr;
|
| - GetNamedObjectAttributes(kShutdownEvent, is_machine_, &attr);
|
| - scoped_event shutdown_event(::OpenEvent(SYNCHRONIZE, false, attr.name));
|
| - if (!shutdown_event) {
|
| - return false;
|
| - }
|
| -
|
| - return WAIT_OBJECT_0 == ::WaitForSingleObject(get(shutdown_event), 0);
|
| -}
|
| -
|
| -// The resource dll is loaded only in the following cases:
|
| -// 1. Initial setup: /install
|
| -// 2. Handoff install: /handoff
|
| -// 3. App update worker: /ua
|
| -// 4. Various registrations.
|
| -// 5. Modes where an error message needs to be displayed.
|
| -HRESULT GoopdateImpl::LoadResourceDllIfNecessary(CommandLineMode mode,
|
| - const CString& resource_dir) {
|
| - switch (mode) {
|
| - case COMMANDLINE_MODE_UNKNOWN: // Displays an error using UI.
|
| - case COMMANDLINE_MODE_NOARGS: // Displays an error using UI.
|
| - case COMMANDLINE_MODE_INSTALL: // Has UI on errors.
|
| - case COMMANDLINE_MODE_UPDATE: // Task and Service descriptions.
|
| - case COMMANDLINE_MODE_RECOVER: // Writes strings to registry.
|
| - case COMMANDLINE_MODE_HANDOFF_INSTALL: // Has optional UI.
|
| - case COMMANDLINE_MODE_UA: // Has optional UI.
|
| - case COMMANDLINE_MODE_COMSERVER: // Returns strings to caller.
|
| - case COMMANDLINE_MODE_SERVICE: // Returns strings to caller.
|
| - case COMMANDLINE_MODE_MEDIUM_SERVICE: // TODO(omaha): Check & explain.
|
| - case COMMANDLINE_MODE_SERVICE_REGISTER: // Requires the RGS resources.
|
| - case COMMANDLINE_MODE_SERVICE_UNREGISTER: // Requires the RGS resources.
|
| - case COMMANDLINE_MODE_ONDEMAND: // Worker, etc. load strings.
|
| - // Load the resource DLL for these modes.
|
| - break;
|
| -
|
| - // For the Core, the resource DLL needs to be loaded when the Core is
|
| - // servicing IGoogleUpdate3. The Core loads the resource DLL after the Code
|
| - // Red kickoff, from within core.cc.
|
| - case COMMANDLINE_MODE_CORE:
|
| - case COMMANDLINE_MODE_REGSERVER:
|
| - case COMMANDLINE_MODE_UNREGSERVER:
|
| - case COMMANDLINE_MODE_NETDIAGS:
|
| - case COMMANDLINE_MODE_CRASH:
|
| - case COMMANDLINE_MODE_REPORTCRASH:
|
| - case COMMANDLINE_MODE_WEBPLUGIN:
|
| - case COMMANDLINE_MODE_CODE_RED_CHECK:
|
| - case COMMANDLINE_MODE_REGISTER_PRODUCT:
|
| - case COMMANDLINE_MODE_UNREGISTER_PRODUCT:
|
| - case COMMANDLINE_MODE_CRASH_HANDLER:
|
| - case COMMANDLINE_MODE_COMBROKER:
|
| - case COMMANDLINE_MODE_UNINSTALL:
|
| - case COMMANDLINE_MODE_PING:
|
| - default:
|
| - // These modes do not need the resource DLL.
|
| - ASSERT1(!internal::CanDisplayUi(mode, false));
|
| - return S_OK;
|
| - }
|
| -
|
| - // TODO(omaha3): Consider not using ResourceManager in this file.
|
| - HRESULT hr = ResourceManager::Create(
|
| - is_machine_,
|
| - resource_dir,
|
| - lang::GetLanguageForProcess(args_.extra.language));
|
| - if (FAILED(hr)) {
|
| - ASSERT(false, (_T("ResourceManager::Create failed with 0x%08x"), hr));
|
| - return hr;
|
| - }
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| -// Writes the information for the primary app to enable Omaha to send usage
|
| -// stats now. It will be set for each app in the args when they are installed.
|
| -HRESULT GoopdateImpl::SetUsageStatsEnable() {
|
| - if (args_.extra.apps.empty()) {
|
| - return S_OK;
|
| - }
|
| -
|
| - HRESULT hr = app_registry_utils::SetUsageStatsEnable(
|
| - args_.extra.apps[0].needs_admin != NEEDS_ADMIN_NO,
|
| - GuidToString(args_.extra.apps[0].app_guid),
|
| - args_.extra.usage_stats_enable);
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LW, (_T("[SetUsageStatsEnable failed][0x%08x]"), hr));
|
| -
|
| - if ((HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hr) &&
|
| - args_.extra.apps[0].needs_admin &&
|
| - !vista_util::IsUserAdmin()) {
|
| - CORE_LOG(L3, (_T("[Process does not have permission to HKLM]")));
|
| - return S_OK;
|
| - }
|
| - return hr;
|
| - }
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| -HRESULT GoopdateImpl::HandleCodeRedCheck() {
|
| - CORE_LOG(L2, (_T("[GoopdateImpl::HandleCodeRedCheck]")));
|
| - ++metric_cr_process_total;
|
| -
|
| - // Call the utils method instead of member method because we want to execute
|
| - // as little code as possible.
|
| - bool is_machine = internal::IsMachineProcess(args_.mode,
|
| - false, // machine dir
|
| - is_local_system_,
|
| - args_.is_machine_set,
|
| - TRISTATE_NONE);
|
| - ASSERT1(IsMachineProcess() == is_machine);
|
| -
|
| - if (!ConfigManager::Instance()->CanUseNetwork(is_machine)) {
|
| - CORE_LOG(L1,
|
| - (_T("[Code Red check not sent because network use prohibited]")));
|
| - return GOOPDATE_E_CANNOT_USE_NETWORK;
|
| - }
|
| -
|
| - CheckForCodeRed(is_machine, this_version_);
|
| - return S_OK;
|
| -}
|
| -
|
| -// Even though http://b/1135173 is fixed, there is still a possibility that only
|
| -// some of the files will be copied if Setup is currently running.
|
| -// TODO(omaha3): If we save and use the metainstaller for OneClick, that may
|
| -// address this.
|
| -
|
| -// If we're called with the /webplugin command, we need to handle it and exit.
|
| -// This is called from the browser and the command line arguments come from the
|
| -// website so we need to be restrictive of what we let past. If everything from
|
| -// the plugin is valid, we'll relaunch goopdate with the proper commands.
|
| -HRESULT GoopdateImpl::HandleWebPlugin() {
|
| - return webplugin_utils::DoOneClickInstall(args_);
|
| -}
|
| -
|
| -HRESULT GoopdateImpl::DoInstall(bool* has_ui_been_displayed) {
|
| - OPT_LOG(L1, (_T("[GoopdateImpl::DoInstall]")));
|
| - ASSERT1(has_ui_been_displayed);
|
| -
|
| - // Some /install command lines, such as /silent /install will not necessarily
|
| - // have an install source. To differentiate these from other sources, such as
|
| - // other clients using the COM API, specify a generic source for /install.
|
| - // TODO(omaha3): Updating two types of command line/args is undesirable, and
|
| - // this does not use CommandLineBuilder. This could be addressed in several
|
| - // ways. See the TODO above install.cc::LaunchHandoffProcess().
|
| - ASSERT1(args_.mode == COMMANDLINE_MODE_INSTALL);
|
| - CString install_command_line = cmd_line_;
|
| - CommandLineArgs install_args = args_;
|
| - if (args_.install_source.IsEmpty()) {
|
| - ASSERT1(-1 == cmd_line_.Find(kCmdLineInstallSource));
|
| - SafeCStringAppendFormat(&install_command_line, _T(" /%s %s"),
|
| - kCmdLineInstallSource,
|
| - kCmdLineInstallSource_InstallDefault);
|
| - install_args.install_source = kCmdLineInstallSource_InstallDefault;
|
| - }
|
| -
|
| - HRESULT hr = S_OK;
|
| - if (args_.is_oem_set) {
|
| - hr = OemInstall(!args_.is_silent_set, // is_interactive
|
| - !args_.extra.runtime_only, // is_app_install
|
| - args_.is_eula_required_set,
|
| - args_.is_install_elevated,
|
| - install_command_line,
|
| - install_args,
|
| - &is_machine_,
|
| - has_ui_been_displayed);
|
| - } else {
|
| - hr = Install(!args_.is_silent_set, // is_interactive
|
| - !args_.extra.runtime_only, // is_app_install
|
| - args_.is_eula_required_set,
|
| - false,
|
| - args_.is_install_elevated,
|
| - install_command_line,
|
| - install_args,
|
| - &is_machine_,
|
| - has_ui_been_displayed);
|
| - }
|
| -
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE, (_T("[Install failed][0x%08x]"), hr));
|
| - return hr;
|
| - }
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| -HRESULT GoopdateImpl::DoSelfUpdate() {
|
| - OPT_LOG(L1, (_T("[GoopdateImpl::DoSelfUpdate]")));
|
| -
|
| - HRESULT hr = install_self::UpdateSelf(is_machine_, args_.session_id);
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE, (_T("[UpdateSelf failed][0x%08x]"), hr));
|
| - return hr;
|
| - }
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| -// Attempts to launch the repair file elevated using the MSP. If elevation is
|
| -// not needed or fails, attempts to install without elevating.
|
| -// The code_red_metainstaller_path arg is the repair file.
|
| -HRESULT GoopdateImpl::DoRecover() {
|
| - OPT_LOG(L1, (_T("[GoopdateImpl::DoRecover()]")));
|
| -
|
| -// TODO(omaha3): Enable. Maybe build without the builder.
|
| -#if 0
|
| - CommandLineBuilder builder(COMMANDLINE_MODE_UPDATE);
|
| -
|
| - HRESULT hr = S_OK;
|
| - if (LaunchRepairFileElevated(is_machine_,
|
| - args_.code_red_metainstaller_path,
|
| - builder.GetCommandLineArgs(),
|
| - &hr)) {
|
| - ASSERT1(SUCCEEDED(hr));
|
| - return S_OK;
|
| - }
|
| -#else
|
| - HRESULT hr = S_OK;
|
| -#endif
|
| -
|
| - if (FAILED(hr)) {
|
| - OPT_LOG(LW, (_T("[LaunchRepairFileElevated failed][0x%08x]"), hr));
|
| - }
|
| -
|
| - hr = install_self::Repair(is_machine_);
|
| - if (FAILED(hr)) {
|
| - OPT_LOG(LE, (_T("[Non-elevated repair failed][0x%08x]"), hr));
|
| - return hr;
|
| - }
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| -// Clears the EULA flag in the handoff instance in case an older installer that
|
| -// does not know about the EULA flag is used to launch the install.
|
| -// Failing to clear flag fails installation because this would prevent updates.
|
| -HRESULT GoopdateImpl::DoHandoff(bool* has_ui_been_displayed) {
|
| - OPT_LOG(L1, (_T("[GoopdateImpl::DoHandoff]")));
|
| - ASSERT1(has_ui_been_displayed);
|
| -
|
| - if (!args_.is_eula_required_set) {
|
| - HRESULT hr = install_self::SetEulaAccepted(is_machine_);
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE, (_T("[install_self::SetEulaAccepted failed][0x%08x]"), hr));
|
| - return hr;
|
| - }
|
| - }
|
| -
|
| - HRESULT hr = InitializeClientSecurity();
|
| - if (FAILED(hr)) {
|
| - return hr;
|
| - }
|
| -
|
| - // If /sessionid wasn't specified on the command line, generate a random GUID
|
| - // to use for the session ID. (This can happen if a metainstaller from the
|
| - // prior version does a handoff to a newer version.)
|
| - CString session_id = args_.session_id;
|
| - if (session_id.IsEmpty()) {
|
| - VERIFY1(SUCCEEDED(GetGuid(&session_id)));
|
| - }
|
| -
|
| - hr = InstallApps(is_machine_,
|
| - !args_.is_silent_set, // is_interactive.
|
| - !args_.is_eula_required_set, // is_eula_accepted.
|
| - args_.is_oem_set,
|
| - args_.is_offline_set,
|
| - args_.offline_dir,
|
| - args_.extra,
|
| - args_.install_source,
|
| - session_id,
|
| - has_ui_been_displayed);
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE, (_T("[Install failed][0x%08x]"), hr));
|
| - return hr;
|
| - }
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| -HRESULT GoopdateImpl::DoUpdateAllApps(bool* has_ui_been_displayed ) {
|
| - OPT_LOG(L1, (_T("[GoopdateImpl::DoUpdateAllApps]")));
|
| - ASSERT1(has_ui_been_displayed);
|
| -
|
| - bool is_interactive_update = !args_.is_silent_set;
|
| -
|
| - // TODO(omaha3): Interactive is used as an indication of an on-demand request.
|
| - // It might also be useful to allow on-demand silent update requests.
|
| - // This was a request when we added the ability to disable updates.
|
| - // TODO(omaha3): These on-demand requests should also allow updates if the
|
| - // app update policy is set to on-demand in addition to silent auto.
|
| - const bool is_on_demand = is_interactive_update;
|
| -
|
| - CString install_source = args_.install_source;
|
| -
|
| - if (is_on_demand && install_source.IsEmpty()) {
|
| - // Set an install source for interactive/on-demand update all apps.
|
| - install_source = kCmdLineInstallSource_OnDemandUA;
|
| - }
|
| -
|
| - // TODO(omaha): Consider moving InitializeClientSecurity calls inside
|
| - // install_apps.cc or maybe to update3_utils::CreateGoogleUpdate3Class().
|
| - HRESULT hr = InitializeClientSecurity();
|
| - if (FAILED(hr)) {
|
| - ASSERT1(false);
|
| - return is_interactive_update ? hr : S_OK;
|
| - }
|
| -
|
| - hr = UpdateApps(is_machine_,
|
| - is_interactive_update,
|
| - is_on_demand,
|
| - install_source,
|
| - args_.extra.language,
|
| - has_ui_been_displayed);
|
| - OPT_LOG(L2, (_T("[Update all apps process finished][0x%x]"), hr));
|
| -
|
| - // The UA worker always returns S_OK. UA can be launched by the scheduled task
|
| - // or the core, neither of which wait for a return code. On Vista, returning
|
| - // an error code from the scheduled task reportedly causes issues with the
|
| - // task scheduler in rare cases, so returning S_OK helps with that as well.
|
| - // However, in interactive cases, we should return the actual error so that it
|
| - // can be reported to the user if necessary.
|
| - return is_interactive_update ? hr : S_OK;
|
| -}
|
| -
|
| -HRESULT GoopdateImpl::DoCrash() {
|
| -#if DEBUG
|
| - return static_cast<HRESULT>(Crash::CrashNow());
|
| -#else
|
| - return S_OK;
|
| -#endif
|
| -}
|
| -
|
| -HRESULT GoopdateImpl::HandleUninstall() {
|
| - // TODO(omaha3): Why don't we always acquire this lock before uninstalling?
|
| - // We don't in the /install case. I guess it's important that we uninstall
|
| - // the first time in that case, but there's a chance that the case in the
|
| - // referenced bug could occur while a user is installing.
|
| -
|
| - // Attempt a conditional uninstall and always return S_OK to avoid
|
| - // executing error handling code in the case of an actual uninstall.
|
| - // Do not attempt to uninstall if MSI is busy to avoid spurious uninstalls.
|
| - // See http://b/1436223. The call to WaitForMSIExecute blocks with a
|
| - // timeout. It is better to block here than block while holding the setup
|
| - // lock.
|
| - HRESULT hr = WaitForMSIExecute(kWaitForMSIExecuteMs);
|
| - CORE_LOG(L2, (_T("[WaitForMSIExecute returned 0x%08x]"), hr));
|
| - if (SUCCEEDED(hr)) {
|
| - MaybeUninstallGoogleUpdate();
|
| - }
|
| - return S_OK;
|
| -}
|
| -
|
| -HRESULT GoopdateImpl::HandlePing() {
|
| - return Ping::HandlePing(is_machine_, args_.ping_string);
|
| -}
|
| -
|
| -// TODO(omaha3): In Omaha 2, this was also called when /ig failed. There is a
|
| -// separate call to UninstallSelf for /install in goopdate.cc. Should we call
|
| -// this instead to ensure we ping? Should we try to only call from one location?
|
| -// If we move it, make sure it is called regardless of LastChecked. See
|
| -// http://b/2663423.
|
| -
|
| -// Uninstall is a tricky use case. Uninstall can primarily happen in three cases
|
| -// and there are two mechanisms to uninstall. The cases in which Omaha
|
| -// uninstalls are:
|
| -// 1. The last registered application uninstalls. If Omaha is long-running,
|
| -// Omaha monitors the Client keys and it will trigger an immediate uninstall in
|
| -// this case.
|
| -// 2. The core starts an update worker, if there are no registered
|
| -// applications, the update worker will do the uninstall.
|
| -// 3. An error, including user cancel, happens during Omaha or app installation
|
| -// and there are no registered applications.
|
| -// The uninstall is implemented in terms of the following mechanisms:
|
| -// * An update worker launched with "/ua /uninstalled" by the core, in the
|
| -// first two cases above.
|
| -// * A direct uninstall, in the case of errors or user cancellations, in the
|
| -// last case above.
|
| -//
|
| -// Omaha can uninstall only if there are no install workers running and no
|
| -// registered applications. This check is done under the setup lock protection.
|
| -// In addition, the uninstall worker takes the update worker lock. Acquiring
|
| -// this lock is important since the silent installers can modify the
|
| -// registration of apps and trigger uninstalls workers. Therefore, both
|
| -// setup lock and the update worker locks are needed.
|
| -//
|
| -// In the direct uninstall case there is a small race condition, since there is
|
| -// no other single lock that can be acquired to prevent changes to the
|
| -// application registration. The code looks for install workers but the test is
|
| -// racy if not protected by locks.
|
| -void GoopdateImpl::MaybeUninstallGoogleUpdate() {
|
| - CORE_LOG(L1, (_T("[MaybeUninstallGoogleUpdate]")));
|
| - has_uninstalled_ =
|
| - !!SUCCEEDED(install_self::UninstallSelf(is_machine_, true));
|
| -}
|
| -
|
| -// In dbg builds, also checks the post conditions of a /install process to
|
| -// ensure that the registry is correctly populated or has been cleaned up.
|
| -HRESULT GoopdateImpl::UninstallIfNecessary() {
|
| - ASSERT1(COMMANDLINE_MODE_INSTALL == args_.mode);
|
| - ASSERT(!has_uninstalled_, (_T("Worker doesn't uninstall in /install mode")));
|
| -
|
| - if (is_machine_ && !vista_util::IsUserAdmin()) {
|
| - // The non-elevated instance, so do not try to uninstall.
|
| - return S_OK;
|
| - } else {
|
| - CORE_LOG(L2, (_T("[GoopdateImpl::Main /install][Uninstall if necessary]")));
|
| - // COM must be initialized in order to uninstall the scheduled task(s).
|
| - scoped_co_init init_com_apt(COINIT_MULTITHREADED);
|
| - return install_self::UninstallSelf(is_machine_, false);
|
| - }
|
| -}
|
| -
|
| -void GoopdateImpl::OutOfMemoryHandler() {
|
| - ::RaiseException(EXCEPTION_ACCESS_VIOLATION,
|
| - EXCEPTION_NONCONTINUABLE,
|
| - 0,
|
| - NULL);
|
| -}
|
| -
|
| -HRESULT GoopdateImpl::CaptureOSMetrics() {
|
| - int major_version(0);
|
| - int minor_version(0);
|
| - int service_pack_major(0);
|
| - int service_pack_minor(0);
|
| - TCHAR name[MAX_PATH] = {0};
|
| -
|
| - HRESULT hr = SystemInfo::GetSystemVersion(&major_version,
|
| - &minor_version,
|
| - &service_pack_major,
|
| - &service_pack_minor,
|
| - name,
|
| - arraysize(name));
|
| - if (SUCCEEDED(hr)) {
|
| - metric_windows_major_version = major_version;
|
| - metric_windows_minor_version = minor_version;
|
| - metric_windows_sp_major_version = service_pack_major;
|
| - metric_windows_sp_minor_version = service_pack_minor;
|
| - }
|
| -
|
| - return hr;
|
| -}
|
| -
|
| -} // namespace detail
|
| -
|
| -namespace internal {
|
| -
|
| -// TODO(omaha3): Consider moving to app_registry_utils.
|
| -// Returns early if Google Update's EULA is already accepted, as indicated by
|
| -// the lack of eulaaccepted in the Update key.
|
| -// The apps' values are not modified or deleted.
|
| -HRESULT PromoteAppEulaAccepted(bool is_machine) {
|
| - const TCHAR* update_key_name =
|
| - ConfigManager::Instance()->registry_update(is_machine);
|
| - if (!RegKey::HasValue(update_key_name, kRegValueOmahaEulaAccepted)) {
|
| - return S_OK;
|
| - }
|
| -
|
| - const TCHAR* state_key_name =
|
| - ConfigManager::Instance()->registry_client_state(is_machine);
|
| -
|
| - RegKey state_key;
|
| - HRESULT hr = state_key.Open(state_key_name, KEY_READ);
|
| - if (FAILED(hr)) {
|
| - if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) {
|
| - return S_FALSE;
|
| - }
|
| - return hr;
|
| - }
|
| -
|
| - // TODO(omaha): This should actually be iterating over registered products
|
| - // rather than present ClientState keys. These are identical in most cases.
|
| - int num_sub_keys = state_key.GetSubkeyCount();
|
| - for (int i = 0; i < num_sub_keys; ++i) {
|
| - CString sub_key_name;
|
| - if (FAILED(state_key.GetSubkeyNameAt(i, &sub_key_name))) {
|
| - continue;
|
| - }
|
| -
|
| - if (app_registry_utils::IsAppEulaAccepted(is_machine, sub_key_name, true)) {
|
| - ASSERT1(kGoogleUpdateAppId != sub_key_name);
|
| - return install_self::SetEulaAccepted(is_machine);
|
| - }
|
| - }
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| -// TODO(omaha): Use a registry override instead.
|
| -#if !OFFICIAL_BUILD
|
| -bool IsOmahaShellRunningFromStaging() {
|
| - return !app_util::GetModuleName(NULL).CompareNoCase(kOmahaShellFileName) &&
|
| - app_util::GetModuleDirectory(NULL).Right(_tcslen(_T("staging"))) ==
|
| - _T("staging");
|
| -}
|
| -#endif
|
| -
|
| -// TODO(omaha): needs_admin is only used for one case. Can we avoid it?
|
| -bool IsMachineProcess(CommandLineMode mode,
|
| - bool is_running_from_official_machine_directory,
|
| - bool is_local_system,
|
| - bool is_machine_override,
|
| - Tristate needs_admin) {
|
| - switch (mode) {
|
| - // These "install" operations may not be running from the installed
|
| - // location.
|
| - case COMMANDLINE_MODE_INSTALL:
|
| - case COMMANDLINE_MODE_HANDOFF_INSTALL:
|
| - case COMMANDLINE_MODE_REGISTER_PRODUCT:
|
| - case COMMANDLINE_MODE_UNREGISTER_PRODUCT:
|
| - ASSERT1(TRISTATE_NONE != needs_admin);
|
| - return TRISTATE_TRUE == needs_admin;
|
| -
|
| - // The following is a Code Red repair executable, which runs from temp dir.
|
| - case COMMANDLINE_MODE_RECOVER:
|
| - return is_machine_override;
|
| -
|
| - // The following always runs as the user and may provide UI for on-demand
|
| - // installs and browser launches.
|
| - // The install location determines user vs. machine.
|
| - case COMMANDLINE_MODE_COMSERVER:
|
| - case COMMANDLINE_MODE_ONDEMAND:
|
| -#if !OFFICIAL_BUILD
|
| - // Return machine == true. This is to facilitate unit tests such as
|
| - // GoogleUpdateCoreTest.LaunchCmdElevated_LocalServerRegistered.
|
| - if (IsOmahaShellRunningFromStaging()) {
|
| - return true;
|
| - }
|
| -#endif
|
| -
|
| - ASSERT1(goopdate_utils::IsRunningFromOfficialGoopdateDir(false) ||
|
| - goopdate_utils::IsRunningFromOfficialGoopdateDir(true) ||
|
| - _T("omaha_unittest.exe") == app_util::GetCurrentModuleName() ||
|
| - _T("GoogleUpdate_unsigned.exe") ==
|
| - app_util::GetModuleName(NULL)); // Running in debugger.
|
| - return is_running_from_official_machine_directory;
|
| -
|
| - // The broker forwarder is elevatable and always runs as the user it was
|
| - // created as.
|
| - case COMMANDLINE_MODE_COMBROKER:
|
| - return is_running_from_official_machine_directory;
|
| -
|
| - // The following always runs as the user and is user-initiated.
|
| - case COMMANDLINE_MODE_WEBPLUGIN:
|
| - // The install location determines user vs. machine.
|
| - // This may not be the desired value when doing a cross-install or using
|
| - // the opposite plugin (i.e. user plugin is often used before the machine
|
| - // one).
|
| - ASSERT1(goopdate_utils::IsRunningFromOfficialGoopdateDir(false) ||
|
| - goopdate_utils::IsRunningFromOfficialGoopdateDir(true) ||
|
| - _T("omaha_unittest.exe") == app_util::GetCurrentModuleName());
|
| - return is_running_from_official_machine_directory;
|
| -
|
| - // The following all run silently as the user for user installs or Local
|
| - // System for machine installs.
|
| - case COMMANDLINE_MODE_UPDATE:
|
| - case COMMANDLINE_MODE_CODE_RED_CHECK:
|
| - return is_local_system;
|
| -
|
| - // The following all run silently as the user for user installs or Local
|
| - // System for machine installs.
|
| - case COMMANDLINE_MODE_UA:
|
| - return is_local_system ? true : is_machine_override;
|
| -
|
| - // /ua runs silently as the user for user installs or Local System for
|
| - // machine installs. Interactive machine /ua may be run as the user if
|
| - // /machine is specified.
|
| - case COMMANDLINE_MODE_CORE:
|
| - case COMMANDLINE_MODE_CRASH_HANDLER:
|
| - return is_local_system;
|
| -
|
| - // The following runs silently as Local System.
|
| - case COMMANDLINE_MODE_SERVICE:
|
| - case COMMANDLINE_MODE_MEDIUM_SERVICE:
|
| - ASSERT1(is_local_system);
|
| - return is_local_system;
|
| -
|
| - // The following run as machine for all installs.
|
| - case COMMANDLINE_MODE_SERVICE_REGISTER:
|
| - case COMMANDLINE_MODE_SERVICE_UNREGISTER:
|
| - return true;
|
| -
|
| - // The crashing process determines whether it was a machine or user omaha
|
| - // and correctly sets the /machine switch.
|
| - case COMMANDLINE_MODE_REPORTCRASH:
|
| - return is_machine_override;
|
| -
|
| - // The following all run silently as the user for all installs.
|
| - case COMMANDLINE_MODE_REGSERVER:
|
| - case COMMANDLINE_MODE_UNREGSERVER:
|
| -#if !OFFICIAL_BUILD
|
| - // Return machine == true. This is to facilitate unit tests such as
|
| - // GoogleUpdateCoreTest.LaunchCmdElevated_LocalServerRegistered.
|
| - if (IsOmahaShellRunningFromStaging()) {
|
| - return true;
|
| - }
|
| -#endif
|
| -
|
| - ASSERT1(goopdate_utils::IsRunningFromOfficialGoopdateDir(false) ||
|
| - goopdate_utils::IsRunningFromOfficialGoopdateDir(true) ||
|
| - _T("omaha_unittest.exe") == app_util::GetCurrentModuleName());
|
| - return is_running_from_official_machine_directory;
|
| -
|
| - // The following may run as user or Local System. Thus, use the directory.
|
| - case COMMANDLINE_MODE_UNINSTALL:
|
| - case COMMANDLINE_MODE_PING:
|
| - ASSERT1(goopdate_utils::IsRunningFromOfficialGoopdateDir(false) ||
|
| - goopdate_utils::IsRunningFromOfficialGoopdateDir(true) ||
|
| - _T("omaha_unittest.exe") == app_util::GetCurrentModuleName());
|
| - return is_running_from_official_machine_directory;
|
| -
|
| - // The following are miscellaneous modes that we do not expect to be running
|
| - // in the wild.
|
| - case COMMANDLINE_MODE_NOARGS:
|
| - case COMMANDLINE_MODE_UNKNOWN:
|
| - case COMMANDLINE_MODE_NETDIAGS:
|
| - case COMMANDLINE_MODE_CRASH:
|
| - default:
|
| - return is_running_from_official_machine_directory;
|
| - }
|
| -}
|
| -
|
| -bool CanDisplayUi(CommandLineMode mode, bool is_silent) {
|
| - switch (mode) {
|
| - case COMMANDLINE_MODE_UNKNOWN:
|
| - // This mode is not one of our known silent modes. Therefore, we can
|
| - // display an error UI.
|
| - return true;
|
| -
|
| - case COMMANDLINE_MODE_INSTALL:
|
| - case COMMANDLINE_MODE_HANDOFF_INSTALL:
|
| - case COMMANDLINE_MODE_UA:
|
| - // These modes have UI unless they are silent.
|
| - // UA is usually silent, but follows the same logic.
|
| - return !is_silent;
|
| -
|
| - case COMMANDLINE_MODE_NOARGS:
|
| - case COMMANDLINE_MODE_CORE:
|
| - case COMMANDLINE_MODE_SERVICE:
|
| - case COMMANDLINE_MODE_REGSERVER:
|
| - case COMMANDLINE_MODE_UNREGSERVER:
|
| - case COMMANDLINE_MODE_NETDIAGS:
|
| - case COMMANDLINE_MODE_CRASH:
|
| - case COMMANDLINE_MODE_REPORTCRASH:
|
| - case COMMANDLINE_MODE_UPDATE:
|
| - case COMMANDLINE_MODE_RECOVER:
|
| - case COMMANDLINE_MODE_WEBPLUGIN:
|
| - case COMMANDLINE_MODE_CODE_RED_CHECK:
|
| - case COMMANDLINE_MODE_COMSERVER:
|
| - case COMMANDLINE_MODE_REGISTER_PRODUCT:
|
| - case COMMANDLINE_MODE_UNREGISTER_PRODUCT:
|
| - case COMMANDLINE_MODE_SERVICE_REGISTER:
|
| - case COMMANDLINE_MODE_SERVICE_UNREGISTER:
|
| - case COMMANDLINE_MODE_CRASH_HANDLER:
|
| - case COMMANDLINE_MODE_COMBROKER:
|
| - case COMMANDLINE_MODE_ONDEMAND:
|
| - case COMMANDLINE_MODE_MEDIUM_SERVICE:
|
| - case COMMANDLINE_MODE_UNINSTALL:
|
| - case COMMANDLINE_MODE_PING:
|
| - default:
|
| - // These modes are always silent.
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -} // namespace internal
|
| -
|
| -Goopdate* Goopdate::instance_ = NULL;
|
| -
|
| -Goopdate& Goopdate::Instance() {
|
| - ASSERT1(instance_);
|
| - return *instance_;
|
| -}
|
| -
|
| -Goopdate::Goopdate(bool is_local_system) {
|
| - CORE_LOG(L2, (_T("[Goopdate::Goopdate]")));
|
| - impl_.reset(new detail::GoopdateImpl(this, is_local_system));
|
| -
|
| - ASSERT1(!instance_);
|
| - instance_ = this;
|
| -}
|
| -
|
| -Goopdate::~Goopdate() {
|
| - CORE_LOG(L2, (_T("[Goopdate::~Goopdate]")));
|
| -
|
| - Stop();
|
| -
|
| - instance_ = NULL;
|
| -}
|
| -
|
| -HRESULT Goopdate::Main(HINSTANCE instance,
|
| - const TCHAR* cmd_line,
|
| - int cmd_show) {
|
| - return impl_->Main(instance, cmd_line, cmd_show);
|
| -}
|
| -
|
| -HRESULT Goopdate::QueueUserWorkItem(UserWorkItem* work_item, uint32 flags) {
|
| - return impl_->QueueUserWorkItem(work_item, flags);
|
| -}
|
| -
|
| -void Goopdate::Stop() {
|
| - return impl_->Stop();
|
| -}
|
| -
|
| -bool Goopdate::is_local_system() const {
|
| - return impl_->is_local_system();
|
| -}
|
| -
|
| -} // namespace omaha
|
|
|