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 |