| OLD | NEW |
| (Empty) |
| 1 // Copyright 2009-2010 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 | |
| 16 #include "omaha/client/install_apps.h" | |
| 17 #include <atlsafe.h> | |
| 18 #include "base/scoped_ptr.h" | |
| 19 #include "omaha/base/const_object_names.h" | |
| 20 #include "omaha/base/debug.h" | |
| 21 #include "omaha/base/error.h" | |
| 22 #include "omaha/base/logging.h" | |
| 23 #include "omaha/base/reactor.h" | |
| 24 #include "omaha/base/scope_guard.h" | |
| 25 #include "omaha/base/scoped_ptr_address.h" | |
| 26 #include "omaha/base/shutdown_callback.h" | |
| 27 #include "omaha/base/shutdown_handler.h" | |
| 28 #include "omaha/base/string.h" | |
| 29 #include "omaha/base/time.h" | |
| 30 #include "omaha/base/utils.h" | |
| 31 #include "omaha/base/vista_utils.h" | |
| 32 #include "omaha/client/bundle_creator.h" | |
| 33 #include "omaha/client/bundle_installer.h" | |
| 34 #include "omaha/client/client_metrics.h" | |
| 35 #include "omaha/client/client_utils.h" | |
| 36 #include "omaha/client/help_url_builder.h" | |
| 37 #include "omaha/client/install_apps_internal.h" | |
| 38 #include "omaha/client/install_progress_observer.h" | |
| 39 #include "omaha/client/resource.h" | |
| 40 #include "omaha/common/command_line.h" | |
| 41 #include "omaha/common/config_manager.h" | |
| 42 #include "omaha/common/const_cmd_line.h" | |
| 43 #include "omaha/common/goopdate_utils.h" | |
| 44 #include "omaha/common/lang.h" | |
| 45 #include "omaha/common/ping.h" | |
| 46 #include "omaha/common/update3_utils.h" | |
| 47 #include "goopdate/omaha3_idl.h" | |
| 48 #include "omaha/ui/progress_wnd.h" | |
| 49 | |
| 50 namespace omaha { | |
| 51 | |
| 52 namespace { | |
| 53 | |
| 54 // Implements the UI progress window. | |
| 55 class SilentProgressObserver : public InstallProgressObserver { | |
| 56 public: | |
| 57 explicit SilentProgressObserver(BundleInstaller* installer) | |
| 58 : installer_(installer) { | |
| 59 ASSERT1(installer); | |
| 60 } | |
| 61 | |
| 62 virtual void OnCheckingForUpdate() { | |
| 63 CORE_LOG(L3, (_T("[SilentProgressObserver::OnCheckingForUpdate]"))); | |
| 64 } | |
| 65 | |
| 66 virtual void OnUpdateAvailable(const CString& app_name, | |
| 67 const CString& version_string) { | |
| 68 CORE_LOG(L3, (_T("[SilentProgressObserver::OnUpdateAvailable][%s][%s]"), | |
| 69 app_name, version_string)); | |
| 70 UNREFERENCED_PARAMETER(app_name); | |
| 71 UNREFERENCED_PARAMETER(version_string); | |
| 72 } | |
| 73 | |
| 74 virtual void OnWaitingToDownload(const CString& app_name) { | |
| 75 CORE_LOG(L3, (_T("[SilentProgressObserver::OnWaitingToDownload][%s]"), | |
| 76 app_name)); | |
| 77 UNREFERENCED_PARAMETER(app_name); | |
| 78 } | |
| 79 | |
| 80 virtual void OnDownloading(const CString& app_name, | |
| 81 int time_remaining_ms, | |
| 82 int pos) { | |
| 83 CORE_LOG(L5, (_T("[SilentProgressObserver::OnDownloading]") | |
| 84 _T("[%s][remaining ms=%d][pos=%d]"), | |
| 85 app_name, time_remaining_ms, pos)); | |
| 86 UNREFERENCED_PARAMETER(app_name); | |
| 87 UNREFERENCED_PARAMETER(time_remaining_ms); | |
| 88 UNREFERENCED_PARAMETER(pos); | |
| 89 } | |
| 90 | |
| 91 virtual void OnWaitingRetryDownload(const CString& app_name, | |
| 92 time64 next_retry_time) { | |
| 93 CORE_LOG(L5, (_T("[SilentProgressObserver::OnWaitingRetryDownload]") | |
| 94 _T("[%s][next retry time=%llu]"), | |
| 95 app_name, next_retry_time)); | |
| 96 UNREFERENCED_PARAMETER(app_name); | |
| 97 UNREFERENCED_PARAMETER(next_retry_time); | |
| 98 } | |
| 99 | |
| 100 virtual void OnWaitingToInstall(const CString& app_name, | |
| 101 bool* can_start_install) { | |
| 102 CORE_LOG(L3, (_T("[SilentProgressObserver::OnWaitingToInstall][%s]"), | |
| 103 app_name)); | |
| 104 ASSERT1(can_start_install); | |
| 105 UNREFERENCED_PARAMETER(app_name); | |
| 106 UNREFERENCED_PARAMETER(can_start_install); | |
| 107 } | |
| 108 | |
| 109 virtual void OnInstalling(const CString& app_name) { | |
| 110 CORE_LOG(L5, (_T("[SilentProgressObserver::OnInstalling][%s]"), app_name)); | |
| 111 UNREFERENCED_PARAMETER(app_name); | |
| 112 } | |
| 113 | |
| 114 virtual void OnPause() { | |
| 115 CORE_LOG(L3, (_T("[SilentProgressObserver::OnPause]"))); | |
| 116 } | |
| 117 | |
| 118 // Terminates the message loop. | |
| 119 virtual void OnComplete(const ObserverCompletionInfo& observer_info) { | |
| 120 CORE_LOG(L3, (_T("[SilentProgressObserver::OnComplete][%s]"), | |
| 121 observer_info.ToString())); | |
| 122 UNREFERENCED_PARAMETER(observer_info); | |
| 123 | |
| 124 installer_->DoExit(); | |
| 125 CORE_LOG(L1, (_T("[SilentProgressObserver][DoExit() called]"))); | |
| 126 } | |
| 127 | |
| 128 private: | |
| 129 BundleInstaller *const installer_; | |
| 130 }; | |
| 131 | |
| 132 class OnDemandEvents : public OnDemandEventsInterface { | |
| 133 public: | |
| 134 explicit OnDemandEvents(BundleInstaller* installer) | |
| 135 : installer_(installer) { | |
| 136 ASSERT1(installer); | |
| 137 } | |
| 138 virtual void DoClose() { | |
| 139 installer_->DoClose(); | |
| 140 } | |
| 141 virtual void DoExit() { | |
| 142 installer_->DoExit(); | |
| 143 } | |
| 144 | |
| 145 private: | |
| 146 BundleInstaller *const installer_; | |
| 147 }; | |
| 148 | |
| 149 // This ATL module is used for BundleInstaller message loop shutdown intrinsics. | |
| 150 // It is also needed for cases where the Update3 server COM objects are created | |
| 151 // inproc. | |
| 152 class BundleAtlModule : public CAtlExeModuleT<BundleAtlModule> { | |
| 153 public: | |
| 154 explicit BundleAtlModule() : allow_post_quit_(false) { | |
| 155 // Disable the delay on shutdown mechanism in CAtlExeModuleT. | |
| 156 m_bDelayShutdown = false; | |
| 157 } | |
| 158 ~BundleAtlModule() {} | |
| 159 | |
| 160 LONG Unlock() throw() { | |
| 161 LONG lRet = CComGlobalsThreadModel::Decrement(&m_nLockCnt); | |
| 162 | |
| 163 if (lRet == 0 && allow_post_quit_) { | |
| 164 ::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0); | |
| 165 } | |
| 166 | |
| 167 return lRet; | |
| 168 } | |
| 169 | |
| 170 // BundleAtlModule will only post WM_QUIT if enable_quit() is called, to avoid | |
| 171 // spurious WM_QUITs during bundle initialization. | |
| 172 void enable_quit() { | |
| 173 allow_post_quit_ = true; | |
| 174 } | |
| 175 | |
| 176 private: | |
| 177 bool allow_post_quit_; | |
| 178 | |
| 179 DISALLOW_COPY_AND_ASSIGN(BundleAtlModule); | |
| 180 }; | |
| 181 | |
| 182 } // namespace | |
| 183 | |
| 184 namespace internal { | |
| 185 | |
| 186 bool IsBrowserRestartSupported(BrowserType browser_type) { | |
| 187 return (browser_type != BROWSER_UNKNOWN && | |
| 188 browser_type != BROWSER_DEFAULT && | |
| 189 browser_type < BROWSER_MAX); | |
| 190 } | |
| 191 | |
| 192 InstallAppsWndEvents::InstallAppsWndEvents(bool is_machine, | |
| 193 BundleInstaller* installer, | |
| 194 BrowserType browser_type) | |
| 195 : is_machine_(is_machine), | |
| 196 installer_(installer), | |
| 197 browser_type_(browser_type) { | |
| 198 ASSERT1(installer_); | |
| 199 } | |
| 200 | |
| 201 void InstallAppsWndEvents::DoClose() { | |
| 202 ASSERT1(installer_); | |
| 203 installer_->DoClose(); | |
| 204 } | |
| 205 | |
| 206 void InstallAppsWndEvents::DoExit() { | |
| 207 ASSERT1(installer_); | |
| 208 installer_->DoExit(); | |
| 209 } | |
| 210 | |
| 211 void InstallAppsWndEvents::DoCancel() { | |
| 212 ASSERT1(installer_); | |
| 213 installer_->DoCancel(); | |
| 214 } | |
| 215 | |
| 216 // TODO(omaha3): Need to address elevated Vista installs. Since we are doing | |
| 217 // a handoff, we know that Omaha is installed and can do de-elevation. | |
| 218 // However, BuildGetHelpUrl will return an empty string right now. Best to | |
| 219 // just solve the general problem. | |
| 220 bool InstallAppsWndEvents::DoLaunchBrowser(const CString& url) { | |
| 221 CORE_LOG(L2, (_T("[InstallAppsWndEvents::DoLaunchBrowser %s]"), url)); | |
| 222 const BrowserType browser = BROWSER_UNKNOWN == browser_type_ ? | |
| 223 BROWSER_DEFAULT : | |
| 224 browser_type_; | |
| 225 return SUCCEEDED(goopdate_utils::LaunchBrowser(is_machine_, browser, url)); | |
| 226 } | |
| 227 | |
| 228 // Restarts the browser(s) and returns whether the browser was successfully | |
| 229 // restarted. | |
| 230 bool InstallAppsWndEvents::DoRestartBrowser(bool terminate_all_browsers, | |
| 231 const std::vector<CString>& urls) { | |
| 232 // UI should not trigger this call back if the browser type is unknown. | |
| 233 // Instead it should ask user to restart the browser(s) manually. | |
| 234 ASSERT1(IsBrowserRestartSupported(browser_type_)); | |
| 235 | |
| 236 BrowserType browser = browser_type_; | |
| 237 if (browser == BROWSER_DEFAULT) { | |
| 238 GetDefaultBrowserType(&browser); | |
| 239 } | |
| 240 | |
| 241 TerminateBrowserResult browser_res; | |
| 242 TerminateBrowserResult default_res; | |
| 243 if (terminate_all_browsers) { | |
| 244 VERIFY1(SUCCEEDED(goopdate_utils::TerminateAllBrowsers(browser, | |
| 245 &browser_res, | |
| 246 &default_res))); | |
| 247 } else { | |
| 248 VERIFY1(SUCCEEDED(goopdate_utils::TerminateBrowserProcesses(browser, | |
| 249 &browser_res, | |
| 250 &default_res))); | |
| 251 } | |
| 252 | |
| 253 BrowserType default_browser_type = BROWSER_UNKNOWN; | |
| 254 HRESULT hr = GetDefaultBrowserType(&default_browser_type); | |
| 255 if (FAILED(hr)) { | |
| 256 CORE_LOG(LE, (_T("[GetDefaultBrowserType failed][0x%08x]"), hr)); | |
| 257 } | |
| 258 | |
| 259 BrowserType browser_to_restart = BROWSER_UNKNOWN; | |
| 260 if (!goopdate_utils::GetBrowserToRestart(browser, | |
| 261 default_browser_type, | |
| 262 browser_res, | |
| 263 default_res, | |
| 264 &browser_to_restart)) { | |
| 265 CORE_LOG(LE, (_T("[GetBrowserToRestart returned false. Not launching.]"))); | |
| 266 return false; | |
| 267 } | |
| 268 ASSERT1(IsBrowserRestartSupported(browser_to_restart)); | |
| 269 | |
| 270 bool succeeded = true; | |
| 271 for (size_t i = 0; i < urls.size(); ++i) { | |
| 272 succeeded &= SUCCEEDED(goopdate_utils::LaunchBrowser(is_machine_, | |
| 273 browser_to_restart, | |
| 274 urls[i])); | |
| 275 } | |
| 276 | |
| 277 return succeeded; | |
| 278 } | |
| 279 | |
| 280 // Initiates a reboot and returns whether it was iniated successfully. | |
| 281 bool InstallAppsWndEvents::DoReboot() { | |
| 282 ASSERT(false, (_T("Not implemented."))); | |
| 283 return false; | |
| 284 } | |
| 285 | |
| 286 CString GetBundleDisplayName(IAppBundle* app_bundle) { | |
| 287 if (!app_bundle) { | |
| 288 return client_utils::GetDefaultBundleName(); | |
| 289 } | |
| 290 | |
| 291 CComBSTR bundle_name; | |
| 292 HRESULT hr = app_bundle->get_displayName(&bundle_name); | |
| 293 if (FAILED(hr)) { | |
| 294 CORE_LOG(LW, (_T("[get_displayName failed][0x%08x]"), hr)); | |
| 295 } | |
| 296 | |
| 297 return (SUCCEEDED(hr) && bundle_name.Length()) ? | |
| 298 CString(bundle_name) : client_utils::GetDefaultBundleName(); | |
| 299 } | |
| 300 | |
| 301 HRESULT CreateClientUI(bool is_machine, | |
| 302 BrowserType browser_type, | |
| 303 BundleInstaller* installer, | |
| 304 IAppBundle* app_bundle, | |
| 305 InstallProgressObserver** observer, | |
| 306 OmahaWndEvents** ui_sink) { | |
| 307 ASSERT1(installer); | |
| 308 ASSERT1(observer); | |
| 309 ASSERT1(!*observer); | |
| 310 ASSERT1(ui_sink); | |
| 311 ASSERT1(!*ui_sink); | |
| 312 | |
| 313 scoped_ptr<ProgressWnd> progress_wnd( | |
| 314 new ProgressWnd(installer->message_loop(), NULL)); | |
| 315 ScopeGuard destroy_window_guard = MakeObjGuard(*progress_wnd, | |
| 316 &ProgressWnd::DestroyWindow); | |
| 317 | |
| 318 progress_wnd->set_is_machine(is_machine); | |
| 319 progress_wnd->set_bundle_name(internal::GetBundleDisplayName(app_bundle)); | |
| 320 | |
| 321 HRESULT hr = progress_wnd->Initialize(); | |
| 322 if (FAILED(hr)) { | |
| 323 return hr; | |
| 324 } | |
| 325 | |
| 326 scoped_ptr<internal::InstallAppsWndEvents> progress_wnd_events( | |
| 327 new internal::InstallAppsWndEvents(is_machine, installer, browser_type)); | |
| 328 progress_wnd->SetEventSink(progress_wnd_events.get()); | |
| 329 | |
| 330 progress_wnd->Show(); | |
| 331 installer->SetBundleParentWindow(progress_wnd->m_hWnd); | |
| 332 | |
| 333 destroy_window_guard.Dismiss(); | |
| 334 *observer = progress_wnd.release(); | |
| 335 *ui_sink = progress_wnd_events.release(); | |
| 336 return S_OK; | |
| 337 } | |
| 338 | |
| 339 // The order of construction is important because it ensures the objects are | |
| 340 // deleted in a safe order (objects before their dependencies). | |
| 341 // Any early returns before the message loop is run must call | |
| 342 // progress_wnd.DestroyWindow(). Errors do not need to be reported in a UI | |
| 343 // because they are handled further up the call stack. | |
| 344 HRESULT DoInstallApps(BundleInstaller* installer, | |
| 345 IAppBundle* app_bundle, | |
| 346 bool is_machine, | |
| 347 bool is_interactive, | |
| 348 bool is_update_all_apps, | |
| 349 BrowserType browser_type, | |
| 350 bool* has_ui_been_displayed) { | |
| 351 CORE_LOG(L2, (_T("[DoInstallApps]"))); | |
| 352 ASSERT1(installer); | |
| 353 ASSERT1(has_ui_been_displayed); | |
| 354 | |
| 355 scoped_ptr<InstallProgressObserver> observer; | |
| 356 scoped_ptr<OmahaWndEvents> ui_sink; | |
| 357 bool listen_to_shutdown_event = false; | |
| 358 | |
| 359 CComPtr<IAppBundle> app_bundle_ptr; | |
| 360 app_bundle_ptr.Attach(app_bundle); | |
| 361 | |
| 362 HRESULT hr = S_OK; | |
| 363 if (is_interactive) { | |
| 364 hr = CreateClientUI(is_machine, | |
| 365 browser_type, | |
| 366 installer, | |
| 367 app_bundle, | |
| 368 address(observer), | |
| 369 address(ui_sink)); | |
| 370 if (FAILED(hr)) { | |
| 371 CORE_LOG(LE, (_T("CreateClientUI failed][0x%08x]"), hr)); | |
| 372 return hr; | |
| 373 } | |
| 374 *has_ui_been_displayed = true; | |
| 375 } else { | |
| 376 observer.reset(new SilentProgressObserver(installer)); | |
| 377 if (is_update_all_apps) { | |
| 378 listen_to_shutdown_event = true; | |
| 379 } | |
| 380 } | |
| 381 | |
| 382 hr = installer->InstallBundle(is_machine, | |
| 383 listen_to_shutdown_event, | |
| 384 app_bundle_ptr.Detach(), | |
| 385 observer.get()); | |
| 386 | |
| 387 observer.reset(); | |
| 388 | |
| 389 // ui_sink must be destroyed after observer and before installer. | |
| 390 ui_sink.reset(); | |
| 391 | |
| 392 CORE_LOG(L1, (_T("DoInstallApps returning][0x%08x]"), hr)); | |
| 393 return hr; | |
| 394 } | |
| 395 | |
| 396 void HandleInstallAppsError(HRESULT error, | |
| 397 int extra_code1, | |
| 398 bool is_machine, | |
| 399 bool is_interactive, | |
| 400 bool is_eula_accepted, | |
| 401 bool is_oem_install, | |
| 402 const CString& install_source, | |
| 403 const CommandLineExtraArgs& extra_args, | |
| 404 const CString& session_id, | |
| 405 bool* has_ui_been_displayed) { | |
| 406 ASSERT1(FAILED(error)); | |
| 407 ASSERT1(has_ui_been_displayed); | |
| 408 | |
| 409 const CString& bundle_name = extra_args.bundle_name; | |
| 410 ASSERT1(!bundle_name.IsEmpty()); | |
| 411 | |
| 412 CString error_text; | |
| 413 | |
| 414 switch (error) { | |
| 415 case GOOPDATE_E_USER_AND_ELEVATED_WITH_UAC_ON: | |
| 416 error_text.FormatMessage(IDS_USER_SHOULD_NOT_RUN_ELEVATED_WITH_UAC_ON, | |
| 417 bundle_name); | |
| 418 break; | |
| 419 default: { | |
| 420 CString product_name; | |
| 421 VERIFY1(product_name.LoadString(IDS_PRODUCT_DISPLAY_NAME)); | |
| 422 error_text.FormatMessage(IDS_SETUP_FAILED, product_name, error); | |
| 423 break; | |
| 424 } | |
| 425 } | |
| 426 | |
| 427 OPT_LOG(LE, (_T("[Failed to install apps][0x%08x][%s]"), error, error_text)); | |
| 428 | |
| 429 if (is_interactive && !*has_ui_been_displayed) { | |
| 430 CString primary_app_id; | |
| 431 if (!extra_args.apps.empty()) { | |
| 432 primary_app_id = GuidToString(extra_args.apps[0].app_guid); | |
| 433 } | |
| 434 | |
| 435 *has_ui_been_displayed = client_utils::DisplayError( | |
| 436 is_machine, | |
| 437 bundle_name, | |
| 438 error, | |
| 439 extra_code1, | |
| 440 error_text, | |
| 441 primary_app_id, | |
| 442 extra_args.language, | |
| 443 extra_args.installation_id, | |
| 444 extra_args.brand_code); | |
| 445 } | |
| 446 | |
| 447 if (!is_eula_accepted || is_oem_install) { | |
| 448 return; | |
| 449 } | |
| 450 | |
| 451 // Send an install complete ping and do not wait for the ping to be sent. | |
| 452 // Since Omaha has been installed at this point, it should be able to | |
| 453 // send this ping without blocking the user flow. | |
| 454 Ping ping(is_machine, session_id, install_source); | |
| 455 ping.LoadAppDataFromExtraArgs(extra_args); | |
| 456 PingEventPtr ping_event( | |
| 457 new PingEvent(PingEvent::EVENT_INSTALL_COMPLETE, | |
| 458 PingEvent::EVENT_RESULT_HANDOFF_ERROR, | |
| 459 error, | |
| 460 extra_code1)); | |
| 461 ping.BuildAppsPing(ping_event); | |
| 462 HRESULT send_result = ping.Send(true); | |
| 463 if (FAILED(send_result)) { | |
| 464 CORE_LOG(LW, (_T("[Ping::Send failed][0x%x]"), send_result)); | |
| 465 } | |
| 466 } | |
| 467 | |
| 468 } // namespace internal | |
| 469 | |
| 470 HRESULT UpdateAppOnDemand(bool is_machine, | |
| 471 const CString& app_id, | |
| 472 bool is_update_check_only, | |
| 473 const CString& session_id, | |
| 474 HANDLE impersonation_token, | |
| 475 HANDLE primary_token, | |
| 476 OnDemandObserver* observer) { | |
| 477 CORE_LOG(L2, (_T("[UpdateAppOnDemand][%d][%s][%d]"), | |
| 478 is_machine, app_id, is_update_check_only)); | |
| 479 | |
| 480 const TCHAR* install_source = is_update_check_only ? | |
| 481 kCmdLineInstallSource_OnDemandCheckForUpdate : | |
| 482 kCmdLineInstallSource_OnDemandUpdate; | |
| 483 CComPtr<IAppBundle> app_bundle; | |
| 484 HRESULT hr = bundle_creator::CreateForOnDemand(is_machine, | |
| 485 app_id, | |
| 486 install_source, | |
| 487 session_id, | |
| 488 impersonation_token, | |
| 489 primary_token, | |
| 490 &app_bundle); | |
| 491 if (SUCCEEDED(hr)) { | |
| 492 BundleInstaller installer(NULL, // No help URL for on-demand. | |
| 493 false, // Is not update all apps. | |
| 494 is_update_check_only, | |
| 495 false); | |
| 496 hr = installer.Initialize(); | |
| 497 if (SUCCEEDED(hr)) { | |
| 498 OnDemandEvents install_events(&installer); | |
| 499 observer->SetEventSink(&install_events); | |
| 500 | |
| 501 // TODO(omaha3): Listen to shutdown event during installation? | |
| 502 return installer.InstallBundle(is_machine, | |
| 503 false, | |
| 504 app_bundle.Detach(), | |
| 505 observer); | |
| 506 } | |
| 507 } | |
| 508 | |
| 509 // The observer must be notified that the bundle has completed with an error | |
| 510 // since the bundle will not be processed. | |
| 511 observer->OnComplete(ObserverCompletionInfo(COMPLETION_CODE_ERROR)); | |
| 512 return hr; | |
| 513 } | |
| 514 | |
| 515 HRESULT InstallApps(bool is_machine, | |
| 516 bool is_interactive, | |
| 517 bool is_eula_accepted, | |
| 518 bool is_oem_install, | |
| 519 bool is_offline, | |
| 520 const CString& offline_directory, | |
| 521 const CommandLineExtraArgs& extra_args, | |
| 522 const CString& install_source, | |
| 523 const CString& session_id, | |
| 524 bool* has_ui_been_displayed) { | |
| 525 CORE_LOG(L2, (_T("[InstallApps][is_machine: %u][is_interactive: %u]") | |
| 526 _T("[is_eula_accepted: %u][is_oem_install: %u][is_offline: %u]") | |
| 527 _T("[offline_directory: %s]"), is_machine, is_interactive, | |
| 528 is_eula_accepted, is_oem_install, is_offline, offline_directory)); | |
| 529 ASSERT1(has_ui_been_displayed); | |
| 530 | |
| 531 BundleAtlModule atl_module; | |
| 532 | |
| 533 CComPtr<IAppBundle> app_bundle; | |
| 534 HRESULT hr = bundle_creator::CreateFromCommandLine(is_machine, | |
| 535 is_eula_accepted, | |
| 536 is_offline, | |
| 537 offline_directory, | |
| 538 extra_args, | |
| 539 install_source, | |
| 540 session_id, | |
| 541 is_interactive, | |
| 542 &app_bundle); | |
| 543 if (FAILED(hr)) { | |
| 544 CORE_LOG(LE, (_T("[bundle_creator::CreateFromCommandLine][0x%08x]"), hr)); | |
| 545 internal::HandleInstallAppsError(hr, | |
| 546 0, | |
| 547 is_machine, | |
| 548 is_interactive, | |
| 549 is_eula_accepted, | |
| 550 is_oem_install, | |
| 551 install_source, | |
| 552 extra_args, | |
| 553 session_id, | |
| 554 has_ui_been_displayed); | |
| 555 return hr; | |
| 556 } | |
| 557 | |
| 558 BundleInstaller installer( | |
| 559 new HelpUrlBuilder(is_machine, | |
| 560 extra_args.language, | |
| 561 extra_args.installation_id, | |
| 562 extra_args.brand_code), | |
| 563 false, // is_update_all_apps | |
| 564 false, // is_update_check_only | |
| 565 internal::IsBrowserRestartSupported(extra_args.browser_type)); | |
| 566 hr = installer.Initialize(); | |
| 567 if (FAILED(hr)) { | |
| 568 return hr; | |
| 569 } | |
| 570 | |
| 571 atl_module.enable_quit(); | |
| 572 return internal::DoInstallApps(&installer, | |
| 573 app_bundle.Detach(), | |
| 574 is_machine, | |
| 575 is_interactive, | |
| 576 false, // Is not update all apps. | |
| 577 extra_args.browser_type, | |
| 578 has_ui_been_displayed); | |
| 579 } | |
| 580 | |
| 581 HRESULT UpdateAllApps(bool is_machine, | |
| 582 bool is_interactive, | |
| 583 const CString& install_source, | |
| 584 const CString& display_language, | |
| 585 const CString& session_id, | |
| 586 bool* has_ui_been_displayed) { | |
| 587 CORE_LOG(L2, (_T("[UpdateAllApps][%u][%u]"), is_machine, is_interactive)); | |
| 588 ASSERT1(has_ui_been_displayed); | |
| 589 | |
| 590 BundleAtlModule atl_module; | |
| 591 | |
| 592 CComPtr<IAppBundle> app_bundle; | |
| 593 HRESULT hr = bundle_creator::Create(is_machine, | |
| 594 display_language, | |
| 595 install_source, | |
| 596 session_id, | |
| 597 is_interactive, | |
| 598 &app_bundle); | |
| 599 if (FAILED(hr)) { | |
| 600 CORE_LOG(LE, (_T("[bundle_creator::Create failed][0x%08x]"), hr)); | |
| 601 return hr; | |
| 602 } | |
| 603 | |
| 604 BundleInstaller installer(new HelpUrlBuilder(is_machine, | |
| 605 display_language, | |
| 606 GUID_NULL, | |
| 607 CString()), | |
| 608 true, // is_update_all_apps | |
| 609 false, // is_update_check_only | |
| 610 BROWSER_UNKNOWN); | |
| 611 hr = installer.Initialize(); | |
| 612 if (FAILED(hr)) { | |
| 613 return hr; | |
| 614 } | |
| 615 | |
| 616 atl_module.enable_quit(); | |
| 617 return internal::DoInstallApps(&installer, | |
| 618 app_bundle.Detach(), | |
| 619 is_machine, | |
| 620 is_interactive, | |
| 621 true, // Is update all apps. | |
| 622 BROWSER_UNKNOWN, | |
| 623 has_ui_been_displayed); | |
| 624 } | |
| 625 | |
| 626 } // namespace omaha | |
| OLD | NEW |