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/goopdate/update3web.h" | |
17 #include "omaha/base/constants.h" | |
18 #include "omaha/base/error.h" | |
19 #include "omaha/base/user_rights.h" | |
20 #include "omaha/common/const_cmd_line.h" | |
21 #include "omaha/common/update3_utils.h" | |
22 #include "omaha/common/lang.h" | |
23 | |
24 namespace omaha { | |
25 | |
26 namespace { | |
27 | |
28 template <typename Base, typename T, typename Z> | |
29 HRESULT ComInitHelper(T data, Z** p) { | |
30 *p = NULL; | |
31 CComObject<Base>* object; | |
32 HRESULT hr = CComObject<Base>::CreateInstance(&object); | |
33 if (FAILED(hr)) { | |
34 return hr; | |
35 } | |
36 CComPtr<IUnknown> object_releaser = object; | |
37 hr = object->Init(data); | |
38 if (FAILED(hr)) { | |
39 return hr; | |
40 } | |
41 return object->QueryInterface(IID_PPV_ARGS(p)); | |
42 } | |
43 | |
44 class ATL_NO_VTABLE AppBundleWeb | |
45 : public CComObjectRootEx<CComObjectThreadModel>, | |
46 public IDispatchImpl<IAppBundleWeb, | |
47 &__uuidof(IAppBundleWeb), | |
48 &CAtlModule::m_libid, | |
49 kMajorTypeLibVersion, | |
50 kMinorTypeLibVersion> { | |
51 public: | |
52 AppBundleWeb(); | |
53 HRESULT Init(Update3WebBase* update3web); | |
54 | |
55 DECLARE_NOT_AGGREGATABLE(AppBundleWeb); | |
56 DECLARE_NO_REGISTRY(); | |
57 | |
58 BEGIN_COM_MAP(AppBundleWeb) | |
59 COM_INTERFACE_ENTRY(IDispatch) | |
60 COM_INTERFACE_ENTRY(IAppBundleWeb) | |
61 END_COM_MAP() | |
62 | |
63 STDMETHOD(createApp)(BSTR app_id, BSTR brand_code, BSTR language, BSTR ap); | |
64 STDMETHOD(createInstalledApp)(BSTR app_id); | |
65 STDMETHOD(createAllInstalledApps)(); | |
66 STDMETHOD(get_displayLanguage)(BSTR* language); | |
67 STDMETHOD(put_displayLanguage)(BSTR language); | |
68 STDMETHOD(put_parentHWND)(ULONG_PTR hwnd); | |
69 STDMETHOD(get_length)(int* number); | |
70 STDMETHOD(get_appWeb)(int index, IDispatch** app_web); | |
71 STDMETHOD(initialize)(); | |
72 STDMETHOD(checkForUpdate)(); | |
73 STDMETHOD(download)(); | |
74 STDMETHOD(install)(); | |
75 STDMETHOD(pause)(); | |
76 STDMETHOD(resume)(); | |
77 STDMETHOD(cancel)(); | |
78 STDMETHOD(downloadPackage)(BSTR app_id, BSTR package_name); | |
79 STDMETHOD(get_currentState)(VARIANT* current_state); | |
80 | |
81 protected: | |
82 virtual ~AppBundleWeb(); | |
83 | |
84 private: | |
85 Update3WebBase* update3web_; | |
86 CComPtr<IAppBundle> app_bundle_; | |
87 | |
88 DISALLOW_COPY_AND_ASSIGN(AppBundleWeb); | |
89 }; | |
90 | |
91 class ATL_NO_VTABLE AppWeb | |
92 : public CComObjectRootEx<CComObjectThreadModel>, | |
93 public IDispatchImpl<IAppWeb, | |
94 &__uuidof(IAppWeb), | |
95 &CAtlModule::m_libid, | |
96 kMajorTypeLibVersion, | |
97 kMinorTypeLibVersion> { | |
98 public: | |
99 AppWeb(); | |
100 HRESULT Init(IApp* app); | |
101 | |
102 DECLARE_NOT_AGGREGATABLE(AppWeb); | |
103 DECLARE_NO_REGISTRY(); | |
104 | |
105 BEGIN_COM_MAP(AppWeb) | |
106 COM_INTERFACE_ENTRY(IDispatch) | |
107 COM_INTERFACE_ENTRY(IAppWeb) | |
108 END_COM_MAP() | |
109 | |
110 STDMETHOD(get_appId)(BSTR* app_id); | |
111 STDMETHOD(get_currentVersionWeb)(IDispatch** current); | |
112 STDMETHOD(get_nextVersionWeb)(IDispatch** next); | |
113 STDMETHOD(cancel)(); | |
114 STDMETHOD(get_currentState)(IDispatch** current_state); | |
115 STDMETHOD(launch)(); | |
116 STDMETHOD(uninstall)(); | |
117 | |
118 protected: | |
119 virtual ~AppWeb(); | |
120 | |
121 private: | |
122 CComPtr<IApp> app_; | |
123 | |
124 DISALLOW_COPY_AND_ASSIGN(AppWeb); | |
125 }; | |
126 | |
127 class ATL_NO_VTABLE AppVersionWeb | |
128 : public CComObjectRootEx<CComObjectThreadModel>, | |
129 public IDispatchImpl<IAppVersionWeb, | |
130 &__uuidof(IAppVersionWeb), | |
131 &CAtlModule::m_libid, | |
132 kMajorTypeLibVersion, | |
133 kMinorTypeLibVersion> { | |
134 public: | |
135 AppVersionWeb(); | |
136 HRESULT Init(IAppVersion* app_version); | |
137 | |
138 DECLARE_NOT_AGGREGATABLE(AppVersionWeb); | |
139 DECLARE_NO_REGISTRY(); | |
140 | |
141 BEGIN_COM_MAP(AppVersionWeb) | |
142 COM_INTERFACE_ENTRY(IDispatch) | |
143 COM_INTERFACE_ENTRY(IAppVersionWeb) | |
144 END_COM_MAP() | |
145 | |
146 STDMETHOD(get_version)(BSTR* version); | |
147 STDMETHOD(get_packageCount)(long* count); // NOLINT | |
148 STDMETHOD(get_packageWeb)(long index, IDispatch** package); // NOLINT | |
149 | |
150 protected: | |
151 virtual ~AppVersionWeb(); | |
152 | |
153 private: | |
154 CComPtr<IAppVersion> app_version_; | |
155 | |
156 DISALLOW_COPY_AND_ASSIGN(AppVersionWeb); | |
157 }; | |
158 | |
159 HRESULT AppBundleWeb::Init(Update3WebBase* update3web) { | |
160 ASSERT1(update3web); | |
161 | |
162 update3web_ = update3web; | |
163 update3web_->AddRef(); | |
164 | |
165 HRESULT hr = update3_utils::CreateAppBundle(update3web_->omaha_server(), | |
166 &app_bundle_); | |
167 if (FAILED(hr)) { | |
168 CORE_LOG(LE, (_T("[CreateAppBundle failed][0x%x]"), hr)); | |
169 return hr; | |
170 } | |
171 | |
172 // ::CoSetProxyBlanket() settings are per proxy. For Update3Web, after | |
173 // unmarshaling the interface, we need to set the blanket on this new proxy. | |
174 // The proxy blanket on the IAppBundle interface are set explicitly for | |
175 // Update3Web, because Update3Web is a unique case of being a COM server as | |
176 // well as a COM client. The default security settings set for the Update3Web | |
177 // COM server are more restrictive and rightly so, as compared to the settings | |
178 // that we set for a COM client such as the Omaha3 UI. Hence the need to | |
179 // explicitly set the proxy blanket settings and lower the security | |
180 // requirements only when calling out on this interface. | |
181 hr = update3_utils::SetProxyBlanketAllowImpersonate(app_bundle_); | |
182 if (FAILED(hr)) { | |
183 return hr; | |
184 } | |
185 | |
186 hr = app_bundle_->put_originURL(CComBSTR(update3web_->origin_url())); | |
187 if (FAILED(hr)) { | |
188 CORE_LOG(LE, (_T("[put_originURL failed][0x%x]"), hr)); | |
189 return hr; | |
190 } | |
191 | |
192 hr = app_bundle_->put_displayLanguage( | |
193 CComBSTR(lang::GetLanguageForProcess(CString()))); | |
194 if (FAILED(hr)) { | |
195 CORE_LOG(LE, (_T("[put_displayLanguage failed][0x%x]"), hr)); | |
196 return hr; | |
197 } | |
198 | |
199 // TODO(omaha3): Expose setting the display name to the plugin client. | |
200 hr = app_bundle_->put_displayName(CComBSTR(_T("App"))); | |
201 if (FAILED(hr)) { | |
202 CORE_LOG(LE, (_T("[put_displayName failed][0x%x]"), hr)); | |
203 return hr; | |
204 } | |
205 | |
206 hr = app_bundle_->put_installSource( | |
207 CComBSTR(kCmdLineInstallSource_Update3Web)); | |
208 if (FAILED(hr)) { | |
209 CORE_LOG(LE, (_T("[put_installSource failed][0x%x]"), hr)); | |
210 return hr; | |
211 } | |
212 | |
213 if (update3web_->is_machine_install()) { | |
214 hr = app_bundle_->put_altTokens( | |
215 reinterpret_cast<ULONG_PTR>(update3web_->impersonation_token()), | |
216 reinterpret_cast<ULONG_PTR>(update3web_->primary_token()), | |
217 ::GetCurrentProcessId()); | |
218 if (FAILED(hr)) { | |
219 CORE_LOG(LE, (_T("[put_altTokens failed][0x%x]"), hr)); | |
220 return hr; | |
221 } | |
222 } | |
223 | |
224 return S_OK; | |
225 } | |
226 | |
227 STDMETHODIMP AppBundleWeb::get_displayLanguage(BSTR* language) { | |
228 return app_bundle_->get_displayLanguage(language); | |
229 } | |
230 | |
231 STDMETHODIMP AppBundleWeb::put_displayLanguage(BSTR language) { | |
232 return app_bundle_->put_displayLanguage(language); | |
233 } | |
234 | |
235 STDMETHODIMP AppBundleWeb::put_parentHWND(ULONG_PTR hwnd) { | |
236 return app_bundle_->put_parentHWND(hwnd); | |
237 } | |
238 | |
239 STDMETHODIMP AppBundleWeb::get_length(int* number) { | |
240 long long_number = 0; // NOLINT(runtime/int) | |
241 HRESULT hr = app_bundle_->get_Count(&long_number); | |
242 *number = long_number; | |
243 return hr; | |
244 } | |
245 | |
246 STDMETHODIMP AppBundleWeb::get_appWeb(int index, IDispatch** app_web) { | |
247 *app_web = NULL; | |
248 | |
249 CComPtr<IApp> app; | |
250 HRESULT hr = update3_utils::GetApp(app_bundle_, index, &app); | |
251 if (FAILED(hr)) { | |
252 CORE_LOG(LE, (_T("[GetApp failed][0x%x]"), hr)); | |
253 return hr; | |
254 } | |
255 | |
256 return ComInitHelper<AppWeb>(app.p, app_web); | |
257 } | |
258 | |
259 AppBundleWeb::AppBundleWeb() : update3web_(NULL) { | |
260 } | |
261 | |
262 STDMETHODIMP AppBundleWeb::createApp(BSTR app_id, | |
263 BSTR brand_code, | |
264 BSTR language, | |
265 BSTR ap) { | |
266 CComPtr<IApp> app; | |
267 HRESULT hr = update3_utils::CreateApp(app_id, app_bundle_, &app); | |
268 if (FAILED(hr)) { | |
269 CORE_LOG(LE, (_T("[CreateApp failed][0x%x]"), hr)); | |
270 return hr; | |
271 } | |
272 | |
273 hr = app->put_brandCode(brand_code); | |
274 if (FAILED(hr)) { | |
275 return hr; | |
276 } | |
277 | |
278 hr = app->put_language(language); | |
279 if (FAILED(hr)) { | |
280 return hr; | |
281 } | |
282 | |
283 hr = app->put_ap(ap); | |
284 if (FAILED(hr)) { | |
285 return hr; | |
286 } | |
287 | |
288 hr = app->put_isEulaAccepted(VARIANT_TRUE); | |
289 if (FAILED(hr)) { | |
290 return hr; | |
291 } | |
292 | |
293 hr = app_bundle_->put_installSource( | |
294 CComBSTR(kCmdLineInstallSource_Update3Web_NewApps)); | |
295 if (FAILED(hr)) { | |
296 return hr; | |
297 } | |
298 | |
299 return S_OK; | |
300 } | |
301 | |
302 STDMETHODIMP AppBundleWeb::createInstalledApp(BSTR app_id) { | |
303 CComPtr<IApp> app; | |
304 HRESULT hr = update3_utils::CreateInstalledApp(app_id, app_bundle_, &app); | |
305 if (FAILED(hr)) { | |
306 CORE_LOG(LE, (_T("[CreateInstalledApp failed][0x%x]"), hr)); | |
307 return hr; | |
308 } | |
309 | |
310 hr = app_bundle_->put_installSource( | |
311 CComBSTR(kCmdLineInstallSource_Update3Web_OnDemand)); | |
312 if (FAILED(hr)) { | |
313 return hr; | |
314 } | |
315 | |
316 return S_OK; | |
317 } | |
318 | |
319 HRESULT AppBundleWeb::createAllInstalledApps() { | |
320 HRESULT hr = update3_utils::CreateAllInstalledApps(app_bundle_); | |
321 if (FAILED(hr)) { | |
322 CORE_LOG(LE, (_T("[CreateAllInstalledApps failed][0x%x]"), hr)); | |
323 return hr; | |
324 } | |
325 | |
326 return S_OK; | |
327 } | |
328 | |
329 AppBundleWeb::~AppBundleWeb() { | |
330 update3web_->Release(); | |
331 } | |
332 | |
333 STDMETHODIMP AppBundleWeb::initialize() { | |
334 return app_bundle_->initialize(); | |
335 } | |
336 | |
337 STDMETHODIMP AppBundleWeb::checkForUpdate() { | |
338 return app_bundle_->checkForUpdate(); | |
339 } | |
340 | |
341 STDMETHODIMP AppBundleWeb::download() { | |
342 return app_bundle_->download(); | |
343 } | |
344 | |
345 STDMETHODIMP AppBundleWeb::install() { | |
346 if (update3web_->is_machine_install() && | |
347 !UserRights::TokenIsAdmin(update3web_->impersonation_token())) { | |
348 CORE_LOG(LE, (_T("[Need to be an admin to call this method]"))); | |
349 return E_ACCESSDENIED; | |
350 } | |
351 | |
352 return app_bundle_->install(); | |
353 } | |
354 | |
355 STDMETHODIMP AppBundleWeb::pause() { | |
356 return app_bundle_->pause(); | |
357 } | |
358 | |
359 STDMETHODIMP AppBundleWeb::resume() { | |
360 return app_bundle_->resume(); | |
361 } | |
362 | |
363 STDMETHODIMP AppBundleWeb::cancel() { | |
364 if (update3web_->is_machine_install() && | |
365 !UserRights::TokenIsAdmin(update3web_->impersonation_token())) { | |
366 CORE_LOG(LE, (_T("[Need to be an admin to cancel]"))); | |
367 return E_ACCESSDENIED; | |
368 } | |
369 | |
370 return app_bundle_->stop(); | |
371 } | |
372 | |
373 STDMETHODIMP AppBundleWeb::downloadPackage(BSTR app_id, BSTR package_name) { | |
374 CORE_LOG(L1, (_T("[AppBundleWeb::downloadPackage][%s][%s]"), | |
375 app_id, package_name)); | |
376 | |
377 HRESULT hr = app_bundle_->put_installSource( | |
378 CComBSTR(kCmdLineInstallSource_Update3Web_Components)); | |
379 if (FAILED(hr)) { | |
380 return hr; | |
381 } | |
382 | |
383 return app_bundle_->downloadPackage(app_id, package_name); | |
384 } | |
385 | |
386 STDMETHODIMP AppBundleWeb::get_currentState(VARIANT* current_state) { | |
387 return app_bundle_->get_currentState(current_state); | |
388 } | |
389 | |
390 AppWeb::AppWeb() { | |
391 } | |
392 | |
393 HRESULT AppWeb::Init(IApp* app) { | |
394 app_ = app; | |
395 return S_OK; | |
396 } | |
397 | |
398 STDMETHODIMP AppWeb::get_appId(BSTR* app_id) { | |
399 ASSERT1(app_id); | |
400 return app_->get_appId(app_id); | |
401 } | |
402 | |
403 STDMETHODIMP AppWeb::get_currentVersionWeb(IDispatch** current) { | |
404 ASSERT1(current); | |
405 *current = NULL; | |
406 | |
407 CComPtr<IAppVersion> app_version; | |
408 HRESULT hr = update3_utils::GetCurrentAppVersion(app_, &app_version); | |
409 if (FAILED(hr)) { | |
410 return hr; | |
411 } | |
412 | |
413 return ComInitHelper<AppVersionWeb>(app_version.p, current); | |
414 } | |
415 | |
416 STDMETHODIMP AppWeb::get_nextVersionWeb(IDispatch** next) { | |
417 ASSERT1(next); | |
418 *next = NULL; | |
419 | |
420 CComPtr<IAppVersion> app_version; | |
421 HRESULT hr = update3_utils::GetNextAppVersion(app_, &app_version); | |
422 if (FAILED(hr)) { | |
423 return hr; | |
424 } | |
425 | |
426 return ComInitHelper<AppVersionWeb>(app_version.p, next); | |
427 } | |
428 | |
429 STDMETHODIMP AppWeb::cancel() { | |
430 return E_NOTIMPL; | |
431 } | |
432 | |
433 STDMETHODIMP AppWeb::get_currentState(IDispatch** current_state) { | |
434 *current_state = NULL; | |
435 return app_->get_currentState(current_state); | |
436 } | |
437 | |
438 STDMETHODIMP AppWeb::launch() { | |
439 return E_NOTIMPL; | |
440 } | |
441 | |
442 STDMETHODIMP AppWeb::uninstall() { | |
443 // This method should check for adminness when implemented. | |
444 return E_NOTIMPL; | |
445 } | |
446 | |
447 AppWeb::~AppWeb() { | |
448 } | |
449 | |
450 AppVersionWeb::AppVersionWeb() { | |
451 } | |
452 | |
453 HRESULT AppVersionWeb::Init(IAppVersion* app_version) { | |
454 app_version_ = app_version; | |
455 return S_OK; | |
456 } | |
457 | |
458 STDMETHODIMP AppVersionWeb::get_version(BSTR* version) { | |
459 return app_version_->get_version(version); | |
460 } | |
461 | |
462 STDMETHODIMP AppVersionWeb::get_packageCount(long* count) { // NOLINT | |
463 return app_version_->get_packageCount(count); | |
464 } | |
465 | |
466 STDMETHODIMP AppVersionWeb::get_packageWeb(long index, // NOLINT | |
467 IDispatch** package) { | |
468 UNREFERENCED_PARAMETER(index); | |
469 ASSERT1(package); | |
470 *package = NULL; | |
471 | |
472 // TODO(omaha3): Implement this after a security review. | |
473 return E_NOTIMPL; | |
474 } | |
475 | |
476 AppVersionWeb::~AppVersionWeb() { | |
477 } | |
478 | |
479 } // namespace | |
480 | |
481 HRESULT Update3WebBase::FinalConstruct() { | |
482 HRESULT hr = | |
483 update3_utils::CreateGoogleUpdate3Class(is_machine_, &omaha_server_); | |
484 if (FAILED(hr)) { | |
485 CORE_LOG(LE, (_T("[Update3WebBase::FinalConstruct failed][0x%x]"), hr)); | |
486 return hr; | |
487 } | |
488 | |
489 if (!is_machine_) { | |
490 return S_OK; | |
491 } | |
492 | |
493 hr = UserRights::GetCallerToken(&impersonation_token_); | |
494 if (FAILED(hr)) { | |
495 CORE_LOG(LE, (_T("[GetCallerToken failed][0x%x]"), hr)); | |
496 return hr; | |
497 } | |
498 | |
499 if (!impersonation_token_.CreatePrimaryToken(&primary_token_)) { | |
500 HRESULT hr = HRESULTFromLastError(); | |
501 CORE_LOG(LE, (_T("[CreatePrimaryToken failed][0x%x]"), hr)); | |
502 return hr; | |
503 } | |
504 | |
505 return S_OK; | |
506 } | |
507 | |
508 STDMETHODIMP Update3WebBase::createAppBundleWeb(IDispatch** app_bundle_web) { | |
509 ASSERT1(app_bundle_web); | |
510 | |
511 *app_bundle_web = NULL; | |
512 | |
513 return ComInitHelper<AppBundleWeb>(this, app_bundle_web); | |
514 } | |
515 | |
516 STDMETHODIMP Update3WebBase::setOriginURL(BSTR origin_url) { | |
517 CORE_LOG(L3, (_T("[Update3WebBase::setOriginURL][%s]"), origin_url)); | |
518 | |
519 if (!origin_url || !wcslen(origin_url)) { | |
520 return E_INVALIDARG; | |
521 } | |
522 | |
523 origin_url_ = origin_url; | |
524 return S_OK; | |
525 } | |
526 | |
527 } // namespace omaha | |
528 | |
OLD | NEW |