| OLD | NEW |
| (Empty) |
| 1 // Copyright 2009 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/plugins/update/activex/update3web_control.h" | |
| 17 #include <objbase.h> | |
| 18 #include <objidl.h> | |
| 19 #include "omaha/base/error.h" | |
| 20 #include "omaha/base/system.h" | |
| 21 #include "omaha/base/utils.h" | |
| 22 #include "omaha/base/vistautil.h" | |
| 23 #include "omaha/common/command_line.h" | |
| 24 #include "omaha/common/command_line_builder.h" | |
| 25 #include "omaha/common/const_cmd_line.h" | |
| 26 #include "omaha/common/goopdate_utils.h" | |
| 27 #include "omaha/common/webplugin_utils.h" | |
| 28 #include "omaha/goopdate/app_manager.h" | |
| 29 #include "goopdate/omaha3_idl.h" | |
| 30 | |
| 31 namespace omaha { | |
| 32 | |
| 33 Update3WebControl::Update3WebControl() { | |
| 34 } | |
| 35 | |
| 36 // There is a code generation bug in VC8. If a base class with template | |
| 37 // arguments and virtual members is not the first base class with virtual | |
| 38 // methods, the generated code for calling a virtual method on that base class | |
| 39 // will adjust the this pointer one extra time. This results in all sorts of | |
| 40 // strange things happening; typically, the program will crash at a later point. | |
| 41 // To avoid this, all calls to base class methods that have template arguments | |
| 42 // should have all the template arguments specified, since this seems to prevent | |
| 43 // the code generation bug from occuring. | |
| 44 | |
| 45 STDMETHODIMP Update3WebControl::createOmahaMachineServerAsync( | |
| 46 VARIANT_BOOL create_elevated, IDispatch** async_status) { | |
| 47 ASSERT1(async_status); | |
| 48 | |
| 49 CString url; | |
| 50 HRESULT hr = SiteLock::GetCurrentBrowserUrl(this, &url); | |
| 51 if (FAILED(hr)) { | |
| 52 CORE_LOG(LE, (L"[GetCurrentBrowserUrl failed][0x%08x]", hr)); | |
| 53 return hr; | |
| 54 } | |
| 55 | |
| 56 if (!site_lock_.InApprovedDomain(url)) { | |
| 57 return GOOPDATE_E_ONECLICK_HOSTCHECK_FAILED; | |
| 58 } | |
| 59 | |
| 60 if (!async_status) { | |
| 61 return E_POINTER; | |
| 62 } | |
| 63 | |
| 64 CComPtr<ICoCreateAsync> cocreate_async; | |
| 65 hr = cocreate_async.CoCreateInstance(__uuidof(CoCreateAsyncClass)); | |
| 66 if (FAILED(hr)) { | |
| 67 CORE_LOG(LE, (L"[CoCreate CoCreateAsyncClass failed][0x%08x]", hr)); | |
| 68 return hr; | |
| 69 } | |
| 70 | |
| 71 CComPtr<ICoCreateAsyncStatus> status; | |
| 72 hr = cocreate_async->createOmahaMachineServerAsync(CComBSTR(url), | |
| 73 create_elevated, | |
| 74 &status); | |
| 75 if (FAILED(hr)) { | |
| 76 CORE_LOG(LE, (L"[CreateInstanceAsync failed][0x%08x]", hr)); | |
| 77 return hr; | |
| 78 } | |
| 79 | |
| 80 hr = status->QueryInterface(async_status); | |
| 81 CORE_LOG(L3, (L"[createOmahaMachineServerAsync][0x%p][0x%08x]", this, hr)); | |
| 82 return hr; | |
| 83 } | |
| 84 | |
| 85 STDMETHODIMP Update3WebControl::createOmahaUserServer(IDispatch** server) { | |
| 86 ASSERT1(server); | |
| 87 | |
| 88 CString url; | |
| 89 HRESULT hr = SiteLock::GetCurrentBrowserUrl(this, &url); | |
| 90 if (FAILED(hr)) { | |
| 91 CORE_LOG(LE, (L"[GetCurrentBrowserUrl failed][0x%08x]", hr)); | |
| 92 return hr; | |
| 93 } | |
| 94 | |
| 95 if (!site_lock_.InApprovedDomain(url)) { | |
| 96 return GOOPDATE_E_ONECLICK_HOSTCHECK_FAILED; | |
| 97 } | |
| 98 | |
| 99 if (!server) { | |
| 100 return E_POINTER; | |
| 101 } | |
| 102 | |
| 103 CComPtr<IGoogleUpdate3WebSecurity> security; | |
| 104 hr = security.CoCreateInstance(__uuidof(GoogleUpdate3WebUserClass)); | |
| 105 if (FAILED(hr)) { | |
| 106 CORE_LOG(LE, (_T("[CoCreate failed][0x%08x]"), hr)); | |
| 107 return hr; | |
| 108 } | |
| 109 | |
| 110 hr = security->setOriginURL(CComBSTR(url)); | |
| 111 if (FAILED(hr)) { | |
| 112 CORE_LOG(LE, (_T("[setOriginURL failed][0x%08x]"), hr)); | |
| 113 return hr; | |
| 114 } | |
| 115 | |
| 116 hr = security->QueryInterface(server); | |
| 117 if (FAILED(hr)) { | |
| 118 CORE_LOG(LE, (_T("[QueryInterface failed][0x%08x]"), hr)); | |
| 119 return hr; | |
| 120 } | |
| 121 | |
| 122 CORE_LOG(L3, (L"[createOmahaUserServer][0x%p][0x%p]", this, *server)); | |
| 123 return hr; | |
| 124 } | |
| 125 | |
| 126 STDMETHODIMP Update3WebControl::getInstalledVersion(BSTR guid_string, | |
| 127 VARIANT_BOOL is_machine, | |
| 128 BSTR* version_string) { | |
| 129 if (!site_lock_.InApprovedDomain(this)) { | |
| 130 return GOOPDATE_E_ONECLICK_HOSTCHECK_FAILED; | |
| 131 } | |
| 132 | |
| 133 if (!guid_string || !version_string) { | |
| 134 return E_POINTER; | |
| 135 } | |
| 136 *version_string = NULL; | |
| 137 | |
| 138 CORE_LOG(L2, (_T("[Update3WebControl::getInstalledVersion][%s][%d]"), | |
| 139 guid_string, is_machine)); | |
| 140 | |
| 141 CString version; | |
| 142 HRESULT hr = GetVersionUsingCOMServer(guid_string, is_machine == VARIANT_TRUE, | |
| 143 &version); | |
| 144 if (FAILED(hr)) { | |
| 145 hr = GetVersionUsingRegistry(guid_string, is_machine == VARIANT_TRUE, | |
| 146 &version); | |
| 147 } | |
| 148 | |
| 149 if (SUCCEEDED(hr)) { | |
| 150 *version_string = version.AllocSysString(); | |
| 151 } | |
| 152 | |
| 153 return S_OK; | |
| 154 } | |
| 155 | |
| 156 HRESULT Update3WebControl::GetVersionUsingCOMServer(const TCHAR* guid_string, | |
| 157 bool is_machine, | |
| 158 CString* version_string) { | |
| 159 CORE_LOG(L2, (_T("[GoopdateCtrl::GetVersionUsingCOMServer][%s][%d]"), | |
| 160 guid_string, is_machine)); | |
| 161 ASSERT1(guid_string); | |
| 162 ASSERT1(version_string); | |
| 163 | |
| 164 CComPtr<IGoogleUpdate3Web> update3web; | |
| 165 HRESULT hr = update3web.CoCreateInstance( | |
| 166 is_machine ? __uuidof(GoogleUpdate3WebMachineClass) : | |
| 167 __uuidof(GoogleUpdate3WebUserClass)); | |
| 168 if (FAILED(hr)) { | |
| 169 CORE_LOG(LE, (_T("[update3web.CoCreateInstance failed][0x%x]"), hr)); | |
| 170 return hr; | |
| 171 } | |
| 172 | |
| 173 CComPtr<IDispatch> app_bundle_dispatch; | |
| 174 hr = update3web->createAppBundleWeb(&app_bundle_dispatch); | |
| 175 if (FAILED(hr)) { | |
| 176 CORE_LOG(LE, (_T("[update3web.createAppBundleWeb failed][0x%x]"), hr)); | |
| 177 return hr; | |
| 178 } | |
| 179 | |
| 180 CComPtr<IAppBundleWeb> app_bundle_web; | |
| 181 hr = app_bundle_dispatch->QueryInterface(&app_bundle_web); | |
| 182 if (FAILED(hr)) { | |
| 183 CORE_LOG(LE, (_T("[QueryInterface for IAppBundleWeb failed][0x%x]"), hr)); | |
| 184 return hr; | |
| 185 } | |
| 186 | |
| 187 hr = app_bundle_web->initialize(); | |
| 188 if (FAILED(hr)) { | |
| 189 CORE_LOG(LE, (_T("[initialize fail][0x%x]"), hr)); | |
| 190 return hr; | |
| 191 } | |
| 192 | |
| 193 hr = app_bundle_web->createInstalledApp(CComBSTR(guid_string)); | |
| 194 if (FAILED(hr)) { | |
| 195 CORE_LOG(LE, (_T("[createInstalledApp fail][%s][0x%x]"), guid_string, hr)); | |
| 196 return hr; | |
| 197 } | |
| 198 | |
| 199 CComPtr<IDispatch> app_dispatch; | |
| 200 hr = app_bundle_web->get_appWeb(0, &app_dispatch); | |
| 201 if (FAILED(hr)) { | |
| 202 CORE_LOG(LE, (_T("[get_appWeb failed][0x%x]"), hr)); | |
| 203 return hr; | |
| 204 } | |
| 205 | |
| 206 CComPtr<IAppWeb> app_web; | |
| 207 hr = app_dispatch->QueryInterface(&app_web); | |
| 208 if (FAILED(hr)) { | |
| 209 CORE_LOG(LE, (_T("[QueryInterface for IAppWeb failed][0x%x]"), hr)); | |
| 210 return hr; | |
| 211 } | |
| 212 | |
| 213 CComPtr<IDispatch> app_version_dispatch; | |
| 214 hr = app_web->get_currentVersionWeb(&app_version_dispatch); | |
| 215 if (FAILED(hr)) { | |
| 216 CORE_LOG(LE, (_T("[get_currentVersionWeb failed][0x%x]"), hr)); | |
| 217 return hr; | |
| 218 } | |
| 219 | |
| 220 CComPtr<IAppVersionWeb> app_version_web; | |
| 221 hr = app_version_dispatch->QueryInterface(&app_version_web); | |
| 222 if (FAILED(hr)) { | |
| 223 CORE_LOG(LE, (_T("[QueryInterface for IAppVersionWeb failed][0x%x]"), hr)); | |
| 224 return hr; | |
| 225 } | |
| 226 | |
| 227 CComBSTR version; | |
| 228 hr = app_version_web->get_version(&version); | |
| 229 if (FAILED(hr)) { | |
| 230 CORE_LOG(LE, (_T("[get_version failed][0x%x]"), hr)); | |
| 231 return hr; | |
| 232 } | |
| 233 | |
| 234 *version_string = version; | |
| 235 CORE_LOG(L2, (_T("[Update3WebControl::GetVersionUsingCOMServer][%s][%d][%s]"), | |
| 236 guid_string, is_machine, *version_string)); | |
| 237 return S_OK; | |
| 238 } | |
| 239 | |
| 240 HRESULT Update3WebControl::GetVersionUsingRegistry(const TCHAR* guid_string, | |
| 241 bool is_machine, | |
| 242 CString* version_string) { | |
| 243 CORE_LOG(L2, (_T("[GoopdateCtrl::GetVersionUsingRegistry][%s][%d]"), | |
| 244 guid_string, is_machine)); | |
| 245 ASSERT1(guid_string); | |
| 246 ASSERT1(version_string); | |
| 247 | |
| 248 GUID app_guid = GUID_NULL; | |
| 249 HRESULT hr = StringToGuidSafe(guid_string, &app_guid); | |
| 250 if (FAILED(hr)) { | |
| 251 return hr; | |
| 252 } | |
| 253 | |
| 254 return AppManager::ReadAppVersionNoLock(is_machine, app_guid, version_string); | |
| 255 } | |
| 256 | |
| 257 HRESULT Update3WebControl::crossInstall(BSTR extra_args) { | |
| 258 ASSERT1(extra_args); | |
| 259 | |
| 260 if (!site_lock_.InApprovedDomain(this)) { | |
| 261 return GOOPDATE_E_ONECLICK_HOSTCHECK_FAILED; | |
| 262 } | |
| 263 | |
| 264 if (!extra_args || !extra_args[0]) { | |
| 265 return E_INVALIDARG; | |
| 266 } | |
| 267 | |
| 268 CORE_LOG(L2, (_T("[Update3WebControl::crossInstall][%s]"), extra_args)); | |
| 269 | |
| 270 // Build the full command line as it should eventually be run. (This command | |
| 271 // line will be escaped, including the /install, and stowed in a /pi later.) | |
| 272 | |
| 273 CommandLineBuilder inner_builder(COMMANDLINE_MODE_INSTALL); | |
| 274 inner_builder.set_extra_args(CString(extra_args)); | |
| 275 CString inner_cmd_line_args = inner_builder.GetCommandLineArgs(); | |
| 276 | |
| 277 HRESULT hr = webplugin_utils::IsLanguageSupported(inner_cmd_line_args); | |
| 278 if (FAILED(hr)) { | |
| 279 CORE_LOG(LE, (_T("[IsLanguageSupported failed][0x%08x]"), hr)); | |
| 280 return hr; | |
| 281 } | |
| 282 | |
| 283 CString browser_url; | |
| 284 hr = site_lock_.GetCurrentBrowserUrl(this, &browser_url); | |
| 285 if (FAILED(hr)) { | |
| 286 return hr; | |
| 287 } | |
| 288 | |
| 289 CString url_domain; | |
| 290 hr = SiteLock::GetUrlDomain(browser_url, &url_domain); | |
| 291 if (FAILED(hr)) { | |
| 292 return hr; | |
| 293 } | |
| 294 | |
| 295 // Build the outer command line using /pi. | |
| 296 | |
| 297 CString url_domain_encoded; | |
| 298 CString cmd_line_encoded; | |
| 299 hr = StringEscape(url_domain, false, &url_domain_encoded); | |
| 300 if (FAILED(hr)) { | |
| 301 return hr; | |
| 302 } | |
| 303 | |
| 304 hr = StringEscape(inner_cmd_line_args, false, &cmd_line_encoded); | |
| 305 if (FAILED(hr)) { | |
| 306 return hr; | |
| 307 } | |
| 308 | |
| 309 CommandLineBuilder outer_builder(COMMANDLINE_MODE_WEBPLUGIN); | |
| 310 outer_builder.set_webplugin_url_domain(url_domain_encoded); | |
| 311 outer_builder.set_webplugin_args(cmd_line_encoded); | |
| 312 outer_builder.set_install_source(kCmdLineInstallSource_Update3Web); | |
| 313 CString final_cmd_line_args = outer_builder.GetCommandLineArgs(); | |
| 314 | |
| 315 CORE_LOG(L2, (_T("[Update3WebControl::crossInstall]") | |
| 316 _T("[Final command line params: %s]"), | |
| 317 final_cmd_line_args)); | |
| 318 | |
| 319 // Spawn a gu process. | |
| 320 | |
| 321 scoped_process process_goopdate; | |
| 322 | |
| 323 hr = goopdate_utils::StartGoogleUpdateWithArgs(is_machine(), | |
| 324 final_cmd_line_args, | |
| 325 address(process_goopdate)); | |
| 326 if (FAILED(hr)) { | |
| 327 CORE_LOG(LE, (_T("[Update3WebControl::crossInstall]") | |
| 328 _T("[Failed StartGoogleUpdateWithArgs][0x%x]"), hr)); | |
| 329 return hr; | |
| 330 } | |
| 331 | |
| 332 return S_OK; | |
| 333 } | |
| 334 | |
| 335 HRESULT Update3WebControl::launchAppCommand(BSTR guid_string, | |
| 336 VARIANT_BOOL is_machine, | |
| 337 BSTR cmd_id) { | |
| 338 if (!site_lock_.InApprovedDomain(this)) { | |
| 339 return GOOPDATE_E_ONECLICK_HOSTCHECK_FAILED; | |
| 340 } | |
| 341 | |
| 342 CORE_LOG(L2, (_T("[Update3WebControl::launchAppCommand]"))); | |
| 343 | |
| 344 CComPtr<IOneClickProcessLauncher> process_launcher; | |
| 345 HRESULT hr = E_UNEXPECTED; | |
| 346 | |
| 347 hr = process_launcher.CoCreateInstance( | |
| 348 is_machine ? | |
| 349 CLSID_OneClickMachineProcessLauncherClass : | |
| 350 CLSID_OneClickUserProcessLauncherClass); | |
| 351 | |
| 352 if (FAILED(hr)) { | |
| 353 CORE_LOG(LE, (_T("[Update3WebControl::launchAppCommand]") | |
| 354 _T("[Failed to CoCreate OneClickMachine/User ") | |
| 355 _T("ProcessLauncher implementation: 0x%x"), | |
| 356 hr)); | |
| 357 return hr; | |
| 358 } | |
| 359 | |
| 360 return process_launcher->LaunchAppCommand(guid_string, cmd_id); | |
| 361 } | |
| 362 | |
| 363 Update3WebControl::~Update3WebControl() { | |
| 364 } | |
| 365 | |
| 366 } // namespace omaha | |
| OLD | NEW |