1 /*
2 * Copyright 2010 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include "mshtml_private.h"
20
check_load_safety(PluginHost * host)21 static BOOL check_load_safety(PluginHost *host)
22 {
23 DWORD policy_size, policy;
24 struct CONFIRMSAFETY cs;
25 BYTE *ppolicy;
26 HRESULT hres;
27
28 cs.clsid = host->clsid;
29 cs.pUnk = host->plugin_unk;
30 cs.dwFlags = CONFIRMSAFETYACTION_LOADOBJECT;
31
32 hres = IInternetHostSecurityManager_QueryCustomPolicy(&host->doc->IInternetHostSecurityManager_iface,
33 &GUID_CUSTOM_CONFIRMOBJECTSAFETY, &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
34 if(FAILED(hres))
35 return FALSE;
36
37 policy = *(DWORD*)ppolicy;
38 CoTaskMemFree(ppolicy);
39 return policy == URLPOLICY_ALLOW;
40 }
41
check_script_safety(PluginHost * host)42 static BOOL check_script_safety(PluginHost *host)
43 {
44 DISPPARAMS params = {NULL,NULL,0,0};
45 DWORD policy_size, policy;
46 struct CONFIRMSAFETY cs;
47 BYTE *ppolicy;
48 ULONG err = 0;
49 VARIANT v;
50 HRESULT hres;
51
52 cs.clsid = host->clsid;
53 cs.pUnk = host->plugin_unk;
54 cs.dwFlags = 0;
55
56 hres = IInternetHostSecurityManager_QueryCustomPolicy(&host->doc->IInternetHostSecurityManager_iface,
57 &GUID_CUSTOM_CONFIRMOBJECTSAFETY, &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
58 if(FAILED(hres))
59 return FALSE;
60
61 policy = *(DWORD*)ppolicy;
62 CoTaskMemFree(ppolicy);
63
64 if(policy != URLPOLICY_ALLOW)
65 return FALSE;
66
67 V_VT(&v) = VT_EMPTY;
68 hres = IDispatch_Invoke(host->disp, DISPID_SECURITYCTX, &IID_NULL, 0, DISPATCH_PROPERTYGET, ¶ms, &v, NULL, &err);
69 if(SUCCEEDED(hres)) {
70 FIXME("Handle security ctx %s\n", debugstr_variant(&v));
71 return FALSE;
72 }
73
74 return TRUE;
75 }
76
update_readystate(PluginHost * host)77 static void update_readystate(PluginHost *host)
78 {
79 DISPPARAMS params = {NULL,NULL,0,0};
80 IDispatchEx *dispex;
81 IDispatch *disp;
82 ULONG err = 0;
83 VARIANT v;
84 HRESULT hres;
85
86 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IDispatchEx, (void**)&dispex);
87 if(SUCCEEDED(hres)) {
88 FIXME("Use IDispatchEx\n");
89 IDispatchEx_Release(dispex);
90 }
91
92 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IDispatch, (void**)&disp);
93 if(FAILED(hres))
94 return;
95
96 hres = IDispatch_Invoke(disp, DISPID_READYSTATE, &IID_NULL, 0, DISPATCH_PROPERTYGET, ¶ms, &v, NULL, &err);
97 IDispatch_Release(disp);
98 if(SUCCEEDED(hres)) {
99 /* FIXME: make plugin readystate affect document readystate */
100 TRACE("readystate = %s\n", debugstr_variant(&v));
101 VariantClear(&v);
102 }
103 }
104
105 /* FIXME: We shouldn't need this function and we should embed plugin directly in the main document */
get_pos_rect(PluginHost * host,RECT * ret)106 static void get_pos_rect(PluginHost *host, RECT *ret)
107 {
108 ret->top = 0;
109 ret->left = 0;
110 ret->bottom = host->rect.bottom - host->rect.top;
111 ret->right = host->rect.right - host->rect.left;
112 }
113
load_prop_bag(PluginHost * host,IPersistPropertyBag * persist_prop_bag)114 static void load_prop_bag(PluginHost *host, IPersistPropertyBag *persist_prop_bag)
115 {
116 IPropertyBag *prop_bag;
117 HRESULT hres;
118
119 hres = create_param_prop_bag(host->element->element.nselem, &prop_bag);
120 if(FAILED(hres))
121 return;
122
123 if(prop_bag && !check_load_safety(host)) {
124 IPropertyBag_Release(prop_bag);
125 prop_bag = NULL;
126 }
127
128 if(prop_bag) {
129 hres = IPersistPropertyBag_Load(persist_prop_bag, prop_bag, NULL);
130 IPropertyBag_Release(prop_bag);
131 if(FAILED(hres))
132 WARN("Load failed: %08x\n", hres);
133 }else {
134 hres = IPersistPropertyBag_InitNew(persist_prop_bag);
135 if(FAILED(hres))
136 WARN("InitNew failed: %08x\n", hres);
137 }
138 }
139
load_plugin(PluginHost * host)140 static void load_plugin(PluginHost *host)
141 {
142 IPersistPropertyBag2 *persist_prop_bag2;
143 IPersistPropertyBag *persist_prop_bag;
144 HRESULT hres;
145
146 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IPersistPropertyBag2, (void**)&persist_prop_bag2);
147 if(SUCCEEDED(hres)) {
148 FIXME("Use IPersistPropertyBag2 iface\n");
149 IPersistPropertyBag2_Release(persist_prop_bag2);
150 return;
151 }
152
153 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IPersistPropertyBag, (void**)&persist_prop_bag);
154 if(SUCCEEDED(hres)) {
155 load_prop_bag(host, persist_prop_bag);
156 IPersistPropertyBag_Release(persist_prop_bag);
157 return;
158 }
159
160 FIXME("No IPersistPropertyBag iface\n");
161 }
162
initialize_plugin_object(PluginHost * host)163 static void initialize_plugin_object(PluginHost *host)
164 {
165 IClientSecurity *client_security;
166 IQuickActivate *quick_activate;
167 IOleObject *ole_obj = NULL;
168 IOleCommandTarget *cmdtrg;
169 IViewObjectEx *view_obj;
170 IDispatchEx *dispex;
171 IDispatch *disp;
172 HRESULT hres;
173
174 /* Note native calls QI on plugin for an undocumented IID and CLSID_HTMLDocument */
175
176 /* FIXME: call FreezeEvents(TRUE) */
177
178 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IClientSecurity, (void**)&client_security);
179 if(SUCCEEDED(hres)) {
180 FIXME("Handle IClientSecurity\n");
181 IClientSecurity_Release(client_security);
182 return;
183 }
184
185 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IQuickActivate, (void**)&quick_activate);
186 if(SUCCEEDED(hres)) {
187 QACONTAINER container = {sizeof(container)};
188 QACONTROL control = {sizeof(control)};
189
190 TRACE("Using IQuickActivate\n");
191
192 container.pClientSite = &host->IOleClientSite_iface;
193 container.dwAmbientFlags = QACONTAINER_SUPPORTSMNEMONICS|QACONTAINER_MESSAGEREFLECT|QACONTAINER_USERMODE;
194 container.pAdviseSink = &host->IAdviseSinkEx_iface;
195 container.pPropertyNotifySink = &host->IPropertyNotifySink_iface;
196
197 hres = IQuickActivate_QuickActivate(quick_activate, &container, &control);
198 IQuickActivate_Release(quick_activate);
199 if(FAILED(hres))
200 FIXME("QuickActivate failed: %08x\n", hres);
201 }else {
202 DWORD status = 0;
203
204 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IOleObject, (void**)&ole_obj);
205 if(SUCCEEDED(hres)) {
206 hres = IOleObject_GetMiscStatus(ole_obj, DVASPECT_CONTENT, &status);
207 TRACE("GetMiscStatus returned %08x %x\n", hres, status);
208
209 hres = IOleObject_SetClientSite(ole_obj, &host->IOleClientSite_iface);
210 IOleObject_Release(ole_obj);
211 if(FAILED(hres)) {
212 FIXME("SetClientSite failed: %08x\n", hres);
213 return;
214 }
215 }else {
216 TRACE("Plugin does not support IOleObject\n");
217 }
218 }
219
220 load_plugin(host);
221
222 if(ole_obj) {
223 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IViewObjectEx, (void**)&view_obj);
224 if(SUCCEEDED(hres)) {
225 DWORD view_status = 0;
226
227 hres = IViewObjectEx_SetAdvise(view_obj, DVASPECT_CONTENT, 0, (IAdviseSink*)&host->IAdviseSinkEx_iface);
228 if(FAILED(hres))
229 WARN("SetAdvise failed: %08x\n", hres);
230
231 hres = IViewObjectEx_GetViewStatus(view_obj, &view_status);
232 IViewObjectEx_Release(view_obj);
233 TRACE("GetViewStatus returned %08x %x\n", hres, view_status);
234 }
235 }
236
237 update_readystate(host);
238
239 /* NOTE: Native QIs for IActiveScript, an undocumented IID, IOleControl and IRunnableObject */
240
241 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IDispatchEx, (void**)&dispex);
242 if(SUCCEEDED(hres)) {
243 FIXME("Use IDispatchEx\n");
244 host->disp = (IDispatch*)dispex;
245 }else {
246 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IDispatch, (void**)&disp);
247 if(SUCCEEDED(hres))
248 host->disp = disp;
249 else
250 TRACE("no IDispatch iface\n");
251 }
252
253 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
254 if(SUCCEEDED(hres)) {
255 FIXME("Use IOleCommandTarget\n");
256 IOleCommandTarget_Release(cmdtrg);
257 }
258 }
259
embed_plugin_object(PluginHost * host)260 static void embed_plugin_object(PluginHost *host)
261 {
262 IOleObject *ole_obj;
263 RECT rect;
264 HRESULT hres;
265
266 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IOleObject, (void**)&ole_obj);
267 if(FAILED(hres)) {
268 FIXME("Plugin does not support IOleObject\n");
269 return;
270 }
271
272 get_pos_rect(host, &rect);
273 hres = IOleObject_DoVerb(ole_obj, OLEIVERB_INPLACEACTIVATE, NULL, &host->IOleClientSite_iface, 0, host->hwnd, &rect);
274 IOleObject_Release(ole_obj);
275 if(FAILED(hres))
276 WARN("DoVerb failed: %08x\n", hres);
277
278 if(host->ip_object) {
279 HWND hwnd;
280
281 hres = IOleInPlaceObject_GetWindow(host->ip_object, &hwnd);
282 if(SUCCEEDED(hres))
283 TRACE("hwnd %p\n", hwnd);
284 }
285 }
286
update_plugin_window(PluginHost * host,HWND hwnd,const RECT * rect)287 void update_plugin_window(PluginHost *host, HWND hwnd, const RECT *rect)
288 {
289 BOOL rect_changed = FALSE;
290
291 if(!hwnd || (host->hwnd && host->hwnd != hwnd)) {
292 FIXME("unhandled hwnd\n");
293 return;
294 }
295
296 TRACE("%p %s\n", hwnd, wine_dbgstr_rect(rect));
297
298 if(memcmp(rect, &host->rect, sizeof(RECT))) {
299 host->rect = *rect;
300 rect_changed = TRUE;
301 }
302
303 if(!host->hwnd) {
304 host->hwnd = hwnd;
305 embed_plugin_object(host);
306 }
307
308 if(rect_changed && host->ip_object)
309 IOleInPlaceObject_SetObjectRects(host->ip_object, &host->rect, &host->rect);
310 }
311
notif_enabled(PluginHost * plugin_host)312 static void notif_enabled(PluginHost *plugin_host)
313 {
314 DISPPARAMS args = {NULL, NULL, 0, 0};
315 IDispatch *disp;
316 ULONG err = 0;
317 VARIANT res;
318 HRESULT hres;
319
320 hres = IUnknown_QueryInterface(plugin_host->plugin_unk, &IID_IDispatch, (void**)&disp);
321 if(FAILED(hres)) {
322 FIXME("Could not get IDispatch iface: %08x\n", hres);
323 return;
324 }
325
326 V_VT(&res) = VT_EMPTY;
327 hres = IDispatch_Invoke(disp, DISPID_ENABLED, &IID_NULL, 0/*FIXME*/, DISPATCH_PROPERTYGET, &args, &res, NULL, &err);
328 IDispatch_Release(disp);
329 if(SUCCEEDED(hres)) {
330 FIXME("Got enabled %s\n", debugstr_variant(&res));
331 VariantClear(&res);
332 }
333 }
334
notif_container_change(HTMLPluginContainer * plugin_container,DISPID dispid)335 void notif_container_change(HTMLPluginContainer *plugin_container, DISPID dispid)
336 {
337 IOleControl *ole_control;
338 HRESULT hres;
339
340 if(!plugin_container->plugin_host || !plugin_container->plugin_host->plugin_unk)
341 return;
342
343 notif_enabled(plugin_container->plugin_host);
344
345 hres = IUnknown_QueryInterface(plugin_container->plugin_host->plugin_unk, &IID_IOleControl, (void**)&ole_control);
346 if(SUCCEEDED(hres)) {
347 IOleControl_OnAmbientPropertyChange(ole_control, dispid);
348 IOleControl_Release(ole_control);
349 }
350 }
351
get_plugin_disp(HTMLPluginContainer * plugin_container,IDispatch ** ret)352 HRESULT get_plugin_disp(HTMLPluginContainer *plugin_container, IDispatch **ret)
353 {
354 PluginHost *host;
355
356 host = plugin_container->plugin_host;
357 if(!host) {
358 ERR("No plugin host\n");
359 return E_UNEXPECTED;
360 }
361
362 if(!host->disp) {
363 *ret = NULL;
364 return S_OK;
365 }
366
367 if(!check_script_safety(host)) {
368 FIXME("Insecure object\n");
369 return E_FAIL;
370 }
371
372 IDispatch_AddRef(host->disp);
373 *ret = host->disp;
374 return S_OK;
375 }
376
get_plugin_dispid(HTMLPluginContainer * plugin_container,WCHAR * name,DISPID * ret)377 HRESULT get_plugin_dispid(HTMLPluginContainer *plugin_container, WCHAR *name, DISPID *ret)
378 {
379 IDispatch *disp;
380 DISPID id;
381 DWORD i;
382 HRESULT hres;
383
384 if(!plugin_container->plugin_host) {
385 WARN("no plugin host\n");
386 return DISP_E_UNKNOWNNAME;
387 }
388
389 disp = plugin_container->plugin_host->disp;
390 if(!disp)
391 return DISP_E_UNKNOWNNAME;
392
393 hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, &id);
394 if(FAILED(hres)) {
395 TRACE("no prop %s\n", debugstr_w(name));
396 return DISP_E_UNKNOWNNAME;
397 }
398
399 for(i=0; i < plugin_container->props_len; i++) {
400 if(id == plugin_container->props[i]) {
401 *ret = MSHTML_DISPID_CUSTOM_MIN+i;
402 return S_OK;
403 }
404 }
405
406 if(!plugin_container->props) {
407 plugin_container->props = heap_alloc(8*sizeof(DISPID));
408 if(!plugin_container->props)
409 return E_OUTOFMEMORY;
410 plugin_container->props_size = 8;
411 }else if(plugin_container->props_len == plugin_container->props_size) {
412 DISPID *new_props;
413
414 new_props = heap_realloc(plugin_container->props, plugin_container->props_size*2*sizeof(DISPID));
415 if(!new_props)
416 return E_OUTOFMEMORY;
417
418 plugin_container->props = new_props;
419 plugin_container->props_size *= 2;
420 }
421
422 plugin_container->props[plugin_container->props_len] = id;
423 *ret = MSHTML_DISPID_CUSTOM_MIN+plugin_container->props_len;
424 plugin_container->props_len++;
425 return S_OK;
426 }
427
invoke_plugin_prop(HTMLPluginContainer * plugin_container,DISPID id,LCID lcid,WORD flags,DISPPARAMS * params,VARIANT * res,EXCEPINFO * ei)428 HRESULT invoke_plugin_prop(HTMLPluginContainer *plugin_container, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
429 VARIANT *res, EXCEPINFO *ei)
430 {
431 PluginHost *host;
432
433 host = plugin_container->plugin_host;
434 if(!host || !host->disp) {
435 FIXME("Called with no disp\n");
436 return E_UNEXPECTED;
437 }
438
439 if(!check_script_safety(host)) {
440 FIXME("Insecure object\n");
441 return E_FAIL;
442 }
443
444 if(id < MSHTML_DISPID_CUSTOM_MIN || id > MSHTML_DISPID_CUSTOM_MIN + plugin_container->props_len) {
445 ERR("Invalid id\n");
446 return E_FAIL;
447 }
448
449 return IDispatch_Invoke(host->disp, plugin_container->props[id-MSHTML_DISPID_CUSTOM_MIN], &IID_NULL,
450 lcid, flags, params, res, ei, NULL);
451 }
452
453 typedef struct {
454 DISPID id;
455 IDispatch *disp;
456 } sink_entry_t;
457
458 struct PHEventSink {
459 IDispatch IDispatch_iface;
460
461 LONG ref;
462
463 PluginHost *host;
464 ITypeInfo *typeinfo;
465 GUID iid;
466 DWORD cookie;
467 BOOL is_dispiface;
468
469 sink_entry_t *handlers;
470 DWORD handlers_cnt;
471 DWORD handlers_size;
472 };
473
find_sink_entry(PHEventSink * sink,DISPID id)474 static sink_entry_t *find_sink_entry(PHEventSink *sink, DISPID id)
475 {
476 sink_entry_t *iter;
477
478 for(iter = sink->handlers; iter < sink->handlers+sink->handlers_cnt; iter++) {
479 if(iter->id == id)
480 return iter;
481 }
482
483 return NULL;
484 }
485
add_sink_handler(PHEventSink * sink,DISPID id,IDispatch * disp)486 static void add_sink_handler(PHEventSink *sink, DISPID id, IDispatch *disp)
487 {
488 sink_entry_t *entry = find_sink_entry(sink, id);
489
490 if(entry) {
491 if(entry->disp)
492 IDispatch_Release(entry->disp);
493 }else {
494 if(!sink->handlers_size) {
495 sink->handlers = heap_alloc(4*sizeof(*sink->handlers));
496 if(!sink->handlers)
497 return;
498 sink->handlers_size = 4;
499 }else if(sink->handlers_cnt == sink->handlers_size) {
500 sink_entry_t *new_handlers;
501
502 new_handlers = heap_realloc(sink->handlers, 2*sink->handlers_size*sizeof(*sink->handlers));
503 if(!new_handlers)
504 return;
505 sink->handlers = new_handlers;
506 sink->handlers_size *= 2;
507 }
508 entry = sink->handlers + sink->handlers_cnt++;
509 entry->id = id;
510 }
511
512 IDispatch_AddRef(disp);
513 entry->disp = disp;
514 }
515
PHEventSink_from_IDispatch(IDispatch * iface)516 static inline PHEventSink *PHEventSink_from_IDispatch(IDispatch *iface)
517 {
518 return CONTAINING_RECORD(iface, PHEventSink, IDispatch_iface);
519 }
520
PHEventSink_QueryInterface(IDispatch * iface,REFIID riid,void ** ppv)521 static HRESULT WINAPI PHEventSink_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
522 {
523 PHEventSink *This = PHEventSink_from_IDispatch(iface);
524
525 if(IsEqualGUID(riid, &IID_IUnknown)) {
526 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
527 *ppv = &This->IDispatch_iface;
528 }else if(IsEqualGUID(riid, &IID_IDispatch)) {
529 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
530 *ppv = &This->IDispatch_iface;
531 }else if(This->is_dispiface && IsEqualGUID(riid, &This->iid)) {
532 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
533 *ppv = &This->IDispatch_iface;
534 }else {
535 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
536 *ppv = NULL;
537 return E_NOINTERFACE;
538 }
539
540 IUnknown_AddRef((IUnknown*)*ppv);
541 return S_OK;
542 }
543
PHEventSink_AddRef(IDispatch * iface)544 static ULONG WINAPI PHEventSink_AddRef(IDispatch *iface)
545 {
546 PHEventSink *This = PHEventSink_from_IDispatch(iface);
547 LONG ref = InterlockedIncrement(&This->ref);
548
549 TRACE("(%p)\n", This);
550
551 return ref;
552 }
553
PHEventSink_Release(IDispatch * iface)554 static ULONG WINAPI PHEventSink_Release(IDispatch *iface)
555 {
556 PHEventSink *This = PHEventSink_from_IDispatch(iface);
557 LONG ref = InterlockedDecrement(&This->ref);
558
559 TRACE("(%p)\n", This);
560
561 if(!ref) {
562 unsigned i;
563
564 assert(!This->host);
565
566 for(i=0; i < This->handlers_cnt; i++) {
567 if(This->handlers[i].disp)
568 IDispatch_Release(This->handlers[i].disp);
569 }
570 heap_free(This->handlers);
571 heap_free(This);
572 }
573
574 return ref;
575 }
576
PHEventSink_GetTypeInfoCount(IDispatch * iface,UINT * pctinfo)577 static HRESULT WINAPI PHEventSink_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
578 {
579 PHEventSink *This = PHEventSink_from_IDispatch(iface);
580 FIXME("(%p)->(%p)\n", This, pctinfo);
581 return E_NOTIMPL;
582 }
583
PHEventSink_GetTypeInfo(IDispatch * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)584 static HRESULT WINAPI PHEventSink_GetTypeInfo(IDispatch *iface, UINT iTInfo,
585 LCID lcid, ITypeInfo **ppTInfo)
586 {
587 PHEventSink *This = PHEventSink_from_IDispatch(iface);
588 FIXME("(%p)->(%d %d %p)\n", This, iTInfo, lcid, ppTInfo);
589 return E_NOTIMPL;
590 }
591
PHEventSink_GetIDsOfNames(IDispatch * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)592 static HRESULT WINAPI PHEventSink_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
593 UINT cNames, LCID lcid, DISPID *rgDispId)
594 {
595 PHEventSink *This = PHEventSink_from_IDispatch(iface);
596 FIXME("(%p)->(%s %p %u %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
597 return E_NOTIMPL;
598 }
599
PHEventSink_Invoke(IDispatch * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)600 static HRESULT WINAPI PHEventSink_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
601 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
602 {
603 PHEventSink *This = PHEventSink_from_IDispatch(iface);
604 IDispatchEx *dispex;
605 sink_entry_t *entry;
606 HRESULT hres;
607
608 TRACE("(%p)->(%d %s %d %x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), lcid, wFlags,
609 pDispParams, pVarResult, pExcepInfo, puArgErr);
610
611 if(!This->host) {
612 WARN("No host\n");
613 return E_UNEXPECTED;
614 }
615
616 entry = find_sink_entry(This, dispIdMember);
617 if(!entry || !entry->disp) {
618 WARN("No handler %d\n", dispIdMember);
619 if(pVarResult)
620 V_VT(pVarResult) = VT_EMPTY;
621 return S_OK;
622 }
623
624 hres = IDispatch_QueryInterface(entry->disp, &IID_IDispatchEx, (void**)&dispex);
625
626 TRACE("(%p) %d >>>\n", This, entry->id);
627 if(SUCCEEDED(hres)) {
628 hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, NULL);
629 IDispatchEx_Release(dispex);
630 }else {
631 hres = IDispatch_Invoke(entry->disp, DISPID_VALUE, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
632 }
633 if(SUCCEEDED(hres))
634 TRACE("(%p) %d <<<\n", This, entry->id);
635 else
636 WARN("(%p) %d <<< %08x\n", This, entry->id, hres);
637 return hres;
638 }
639
640 static const IDispatchVtbl PHCPDispatchVtbl = {
641 PHEventSink_QueryInterface,
642 PHEventSink_AddRef,
643 PHEventSink_Release,
644 PHEventSink_GetTypeInfoCount,
645 PHEventSink_GetTypeInfo,
646 PHEventSink_GetIDsOfNames,
647 PHEventSink_Invoke
648 };
649
create_event_sink(PluginHost * plugin_host,ITypeInfo * typeinfo)650 static PHEventSink *create_event_sink(PluginHost *plugin_host, ITypeInfo *typeinfo)
651 {
652 IConnectionPointContainer *cp_container;
653 PHEventSink *ret;
654 IConnectionPoint *cp;
655 TYPEATTR *typeattr;
656 TYPEKIND typekind;
657 GUID guid;
658 HRESULT hres;
659
660 hres = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
661 if(FAILED(hres))
662 return NULL;
663
664 typekind = typeattr->typekind;
665 guid = typeattr->guid;
666 ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
667
668 TRACE("guid %s typekind %d\n", debugstr_guid(&guid), typekind);
669
670 if(typekind != TKIND_INTERFACE && typekind != TKIND_DISPATCH) {
671 WARN("invalid typekind %d\n", typekind);
672 return NULL;
673 }
674
675 hres = IUnknown_QueryInterface(plugin_host->plugin_unk, &IID_IConnectionPointContainer, (void**)&cp_container);
676 if(FAILED(hres)) {
677 WARN("Could not get IConnectionPointContainer iface: %08x\n", hres);
678 return NULL;
679 }
680
681 hres = IConnectionPointContainer_FindConnectionPoint(cp_container, &guid, &cp);
682 IConnectionPointContainer_Release(cp_container);
683 if(FAILED(hres)) {
684 WARN("Could not find %s connection point\n", debugstr_guid(&guid));
685 return NULL;
686 }
687
688 ret = heap_alloc_zero(sizeof(*ret));
689 if(ret) {
690 ret->IDispatch_iface.lpVtbl = &PHCPDispatchVtbl;
691 ret->ref = 1;
692 ret->host = plugin_host;
693 ret->iid = guid;
694 ret->is_dispiface = typekind == TKIND_DISPATCH;
695
696 ITypeInfo_AddRef(typeinfo);
697 ret->typeinfo = typeinfo;
698
699 hres = IConnectionPoint_Advise(cp, (IUnknown*)&ret->IDispatch_iface, &ret->cookie);
700 }else {
701 hres = E_OUTOFMEMORY;
702 }
703
704 IConnectionPoint_Release(cp);
705 if(FAILED(hres)) {
706 WARN("Advise failed: %08x\n", hres);
707 return NULL;
708 }
709
710 return ret;
711 }
712
get_eventiface_info(HTMLPluginContainer * plugin_container,ITypeInfo * class_info)713 static ITypeInfo *get_eventiface_info(HTMLPluginContainer *plugin_container, ITypeInfo *class_info)
714 {
715 int impl_types, i, impl_flags;
716 ITypeInfo *ret = NULL;
717 TYPEATTR *typeattr;
718 HREFTYPE ref;
719 HRESULT hres;
720
721 hres = ITypeInfo_GetTypeAttr(class_info, &typeattr);
722 if(FAILED(hres))
723 return NULL;
724
725 if(typeattr->typekind != TKIND_COCLASS) {
726 WARN("not coclass\n");
727 ITypeInfo_ReleaseTypeAttr(class_info, typeattr);
728 return NULL;
729 }
730
731 impl_types = typeattr->cImplTypes;
732 ITypeInfo_ReleaseTypeAttr(class_info, typeattr);
733
734 for(i=0; i<impl_types; i++) {
735 hres = ITypeInfo_GetImplTypeFlags(class_info, i, &impl_flags);
736 if(FAILED(hres))
737 continue;
738
739 if((impl_flags & IMPLTYPEFLAG_FSOURCE)) {
740 if(!(impl_flags & IMPLTYPEFLAG_FDEFAULT)) {
741 FIXME("Handle non-default source iface\n");
742 continue;
743 }
744
745 hres = ITypeInfo_GetRefTypeOfImplType(class_info, i, &ref);
746 if(FAILED(hres))
747 continue;
748
749 hres = ITypeInfo_GetRefTypeInfo(class_info, ref, &ret);
750 if(FAILED(hres))
751 ret = NULL;
752 }
753 }
754
755 return ret;
756 }
757
bind_activex_event(HTMLDocumentNode * doc,HTMLPluginContainer * plugin_container,WCHAR * event,IDispatch * disp)758 void bind_activex_event(HTMLDocumentNode *doc, HTMLPluginContainer *plugin_container, WCHAR *event, IDispatch *disp)
759 {
760 PluginHost *plugin_host = plugin_container->plugin_host;
761 ITypeInfo *class_info, *source_info;
762 DISPID id;
763 HRESULT hres;
764
765 TRACE("(%p %p %s %p)\n", doc, plugin_host, debugstr_w(event), disp);
766
767 if(!plugin_host || !plugin_host->plugin_unk) {
768 WARN("detached element %p\n", plugin_host);
769 return;
770 }
771
772 if(plugin_host->sink) {
773 source_info = plugin_host->sink->typeinfo;
774 ITypeInfo_AddRef(source_info);
775 }else {
776 IProvideClassInfo *provide_ci;
777
778 hres = IUnknown_QueryInterface(plugin_host->plugin_unk, &IID_IProvideClassInfo, (void**)&provide_ci);
779 if(FAILED(hres)) {
780 FIXME("No IProvideClassInfo, try GetTypeInfo?\n");
781 return;
782 }
783
784 hres = IProvideClassInfo_GetClassInfo(provide_ci, &class_info);
785 IProvideClassInfo_Release(provide_ci);
786 if(FAILED(hres) || !class_info) {
787 WARN("GetClassInfo failed: %08x\n", hres);
788 return;
789 }
790
791 source_info = get_eventiface_info(plugin_container, class_info);
792 ITypeInfo_Release(class_info);
793 if(!source_info)
794 return;
795 }
796
797 hres = ITypeInfo_GetIDsOfNames(source_info, &event, 1, &id);
798 if(FAILED(hres))
799 WARN("Could not get disp id: %08x\n", hres);
800 else if(!plugin_host->sink)
801 plugin_host->sink = create_event_sink(plugin_host, source_info);
802
803 ITypeInfo_Release(source_info);
804 if(FAILED(hres) || !plugin_host->sink)
805 return;
806
807 add_sink_handler(plugin_host->sink, id, disp);
808 }
809
impl_from_IOleClientSite(IOleClientSite * iface)810 static inline PluginHost *impl_from_IOleClientSite(IOleClientSite *iface)
811 {
812 return CONTAINING_RECORD(iface, PluginHost, IOleClientSite_iface);
813 }
814
PHClientSite_QueryInterface(IOleClientSite * iface,REFIID riid,void ** ppv)815 static HRESULT WINAPI PHClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
816 {
817 PluginHost *This = impl_from_IOleClientSite(iface);
818
819 if(IsEqualGUID(&IID_IUnknown, riid)) {
820 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
821 *ppv = &This->IOleClientSite_iface;
822 }else if(IsEqualGUID(&IID_IOleClientSite, riid)) {
823 TRACE("(%p)->(IID_IOleClientSite %p)\n", This, ppv);
824 *ppv = &This->IOleClientSite_iface;
825 }else if(IsEqualGUID(&IID_IAdviseSink, riid)) {
826 TRACE("(%p)->(IID_IAdviseSink %p)\n", This, ppv);
827 *ppv = &This->IAdviseSinkEx_iface;
828 }else if(IsEqualGUID(&IID_IAdviseSinkEx, riid)) {
829 TRACE("(%p)->(IID_IAdviseSinkEx %p)\n", This, ppv);
830 *ppv = &This->IAdviseSinkEx_iface;
831 }else if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
832 TRACE("(%p)->(IID_IPropertyNotifySink %p)\n", This, ppv);
833 *ppv = &This->IPropertyNotifySink_iface;
834 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
835 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
836 *ppv = &This->IDispatch_iface;
837 }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
838 TRACE("(%p)->(IID_IOleWindow %p)\n", This, ppv);
839 *ppv = &This->IOleInPlaceSiteEx_iface;
840 }else if(IsEqualGUID(&IID_IOleInPlaceSite, riid)) {
841 TRACE("(%p)->(IID_IOleInPlaceSite %p)\n", This, ppv);
842 *ppv = &This->IOleInPlaceSiteEx_iface;
843 }else if(IsEqualGUID(&IID_IOleInPlaceSiteEx, riid)) {
844 TRACE("(%p)->(IID_IOleInPlaceSiteEx %p)\n", This, ppv);
845 *ppv = &This->IOleInPlaceSiteEx_iface;
846 }else if(IsEqualGUID(&IID_IOleControlSite, riid)) {
847 TRACE("(%p)->(IID_IOleControlSite %p)\n", This, ppv);
848 *ppv = &This->IOleControlSite_iface;
849 }else if(IsEqualGUID(&IID_IBindHost, riid)) {
850 TRACE("(%p)->(IID_IBindHost %p)\n", This, ppv);
851 *ppv = &This->IBindHost_iface;
852 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
853 TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
854 *ppv = &This->IServiceProvider_iface;
855 }else {
856 WARN("Unsupported interface %s\n", debugstr_guid(riid));
857 *ppv = NULL;
858 return E_NOINTERFACE;
859 }
860
861 IUnknown_AddRef((IUnknown*)*ppv);
862 return S_OK;
863 }
864
PHClientSite_AddRef(IOleClientSite * iface)865 static ULONG WINAPI PHClientSite_AddRef(IOleClientSite *iface)
866 {
867 PluginHost *This = impl_from_IOleClientSite(iface);
868 LONG ref = InterlockedIncrement(&This->ref);
869
870 TRACE("(%p) ref=%d\n", This, ref);
871
872 return ref;
873 }
874
release_plugin_ifaces(PluginHost * This)875 static void release_plugin_ifaces(PluginHost *This)
876 {
877 if(This->disp) {
878 IDispatch_Release(This->disp);
879 This->disp = NULL;
880 }
881
882 if(This->ip_object) {
883 IOleInPlaceObject_Release(This->ip_object);
884 This->ip_object = NULL;
885 }
886
887 if(This->plugin_unk) {
888 IUnknown *unk = This->plugin_unk;
889 LONG ref;
890
891 This->plugin_unk = NULL;
892 ref = IUnknown_Release(unk);
893
894 TRACE("plugin ref = %d\n", ref);
895 }
896 }
897
PHClientSite_Release(IOleClientSite * iface)898 static ULONG WINAPI PHClientSite_Release(IOleClientSite *iface)
899 {
900 PluginHost *This = impl_from_IOleClientSite(iface);
901 LONG ref = InterlockedDecrement(&This->ref);
902
903 TRACE("(%p) ref=%d\n", This, ref);
904
905 if(!ref) {
906 release_plugin_ifaces(This);
907 if(This->sink) {
908 This->sink->host = NULL;
909 IDispatch_Release(&This->sink->IDispatch_iface);
910 This->sink = NULL;
911 }
912 list_remove(&This->entry);
913 if(This->element)
914 This->element->plugin_host = NULL;
915 heap_free(This);
916 }
917
918 return ref;
919 }
920
PHClientSite_SaveObject(IOleClientSite * iface)921 static HRESULT WINAPI PHClientSite_SaveObject(IOleClientSite *iface)
922 {
923 PluginHost *This = impl_from_IOleClientSite(iface);
924 FIXME("(%p)\n", This);
925 return E_NOTIMPL;
926 }
927
PHClientSite_GetMoniker(IOleClientSite * iface,DWORD dwAssign,DWORD dwWhichMoniker,IMoniker ** ppmk)928 static HRESULT WINAPI PHClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign,
929 DWORD dwWhichMoniker, IMoniker **ppmk)
930 {
931 PluginHost *This = impl_from_IOleClientSite(iface);
932
933 TRACE("(%p)->(%d %d %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
934
935 switch(dwWhichMoniker) {
936 case OLEWHICHMK_CONTAINER:
937 if(!This->doc || !This->doc->window || !This->doc->window->mon) {
938 FIXME("no moniker\n");
939 return E_UNEXPECTED;
940 }
941
942 *ppmk = This->doc->window->mon;
943 IMoniker_AddRef(*ppmk);
944 break;
945 default:
946 FIXME("which %d\n", dwWhichMoniker);
947 return E_NOTIMPL;
948 }
949
950 return S_OK;
951 }
952
PHClientSite_GetContainer(IOleClientSite * iface,IOleContainer ** ppContainer)953 static HRESULT WINAPI PHClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
954 {
955 PluginHost *This = impl_from_IOleClientSite(iface);
956
957 TRACE("(%p)->(%p)\n", This, ppContainer);
958
959 if(!This->doc) {
960 ERR("Called on detached object\n");
961 return E_UNEXPECTED;
962 }
963
964 *ppContainer = &This->doc->basedoc.IOleContainer_iface;
965 IOleContainer_AddRef(*ppContainer);
966 return S_OK;
967 }
968
PHClientSite_ShowObject(IOleClientSite * iface)969 static HRESULT WINAPI PHClientSite_ShowObject(IOleClientSite *iface)
970 {
971 PluginHost *This = impl_from_IOleClientSite(iface);
972
973 TRACE("(%p)\n", This);
974
975 return S_OK;
976 }
977
PHClientSite_OnShowWindow(IOleClientSite * iface,BOOL fShow)978 static HRESULT WINAPI PHClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
979 {
980 PluginHost *This = impl_from_IOleClientSite(iface);
981 FIXME("(%p)->(%x)\n", This, fShow);
982 return E_NOTIMPL;
983 }
984
PHClientSite_RequestNewObjectLayout(IOleClientSite * iface)985 static HRESULT WINAPI PHClientSite_RequestNewObjectLayout(IOleClientSite *iface)
986 {
987 PluginHost *This = impl_from_IOleClientSite(iface);
988 FIXME("(%p)\n", This);
989 return E_NOTIMPL;
990 }
991
992 static const IOleClientSiteVtbl OleClientSiteVtbl = {
993 PHClientSite_QueryInterface,
994 PHClientSite_AddRef,
995 PHClientSite_Release,
996 PHClientSite_SaveObject,
997 PHClientSite_GetMoniker,
998 PHClientSite_GetContainer,
999 PHClientSite_ShowObject,
1000 PHClientSite_OnShowWindow,
1001 PHClientSite_RequestNewObjectLayout
1002 };
1003
impl_from_IAdviseSinkEx(IAdviseSinkEx * iface)1004 static inline PluginHost *impl_from_IAdviseSinkEx(IAdviseSinkEx *iface)
1005 {
1006 return CONTAINING_RECORD(iface, PluginHost, IAdviseSinkEx_iface);
1007 }
1008
PHAdviseSinkEx_QueryInterface(IAdviseSinkEx * iface,REFIID riid,void ** ppv)1009 static HRESULT WINAPI PHAdviseSinkEx_QueryInterface(IAdviseSinkEx *iface, REFIID riid, void **ppv)
1010 {
1011 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1012 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
1013 }
1014
PHAdviseSinkEx_AddRef(IAdviseSinkEx * iface)1015 static ULONG WINAPI PHAdviseSinkEx_AddRef(IAdviseSinkEx *iface)
1016 {
1017 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1018 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1019 }
1020
PHAdviseSinkEx_Release(IAdviseSinkEx * iface)1021 static ULONG WINAPI PHAdviseSinkEx_Release(IAdviseSinkEx *iface)
1022 {
1023 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1024 return IOleClientSite_Release(&This->IOleClientSite_iface);
1025 }
1026
PHAdviseSinkEx_OnDataChange(IAdviseSinkEx * iface,FORMATETC * pFormatetc,STGMEDIUM * pStgMedium)1027 static void WINAPI PHAdviseSinkEx_OnDataChange(IAdviseSinkEx *iface, FORMATETC *pFormatetc, STGMEDIUM *pStgMedium)
1028 {
1029 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1030 FIXME("(%p)->(%p %p)\n", This, pFormatetc, pStgMedium);
1031 }
1032
PHAdviseSinkEx_OnViewChange(IAdviseSinkEx * iface,DWORD dwAspect,LONG lindex)1033 static void WINAPI PHAdviseSinkEx_OnViewChange(IAdviseSinkEx *iface, DWORD dwAspect, LONG lindex)
1034 {
1035 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1036 FIXME("(%p)->(%d %d)\n", This, dwAspect, lindex);
1037 }
1038
PHAdviseSinkEx_OnRename(IAdviseSinkEx * iface,IMoniker * pmk)1039 static void WINAPI PHAdviseSinkEx_OnRename(IAdviseSinkEx *iface, IMoniker *pmk)
1040 {
1041 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1042 FIXME("(%p)->(%p)\n", This, pmk);
1043 }
1044
PHAdviseSinkEx_OnSave(IAdviseSinkEx * iface)1045 static void WINAPI PHAdviseSinkEx_OnSave(IAdviseSinkEx *iface)
1046 {
1047 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1048 FIXME("(%p)\n", This);
1049 }
1050
PHAdviseSinkEx_OnClose(IAdviseSinkEx * iface)1051 static void WINAPI PHAdviseSinkEx_OnClose(IAdviseSinkEx *iface)
1052 {
1053 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1054 FIXME("(%p)\n", This);
1055 }
1056
PHAdviseSinkEx_OnViewStatusChange(IAdviseSinkEx * iface,DWORD dwViewStatus)1057 static void WINAPI PHAdviseSinkEx_OnViewStatusChange(IAdviseSinkEx *iface, DWORD dwViewStatus)
1058 {
1059 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1060 FIXME("(%p)->(%d)\n", This, dwViewStatus);
1061 }
1062
1063 static const IAdviseSinkExVtbl AdviseSinkExVtbl = {
1064 PHAdviseSinkEx_QueryInterface,
1065 PHAdviseSinkEx_AddRef,
1066 PHAdviseSinkEx_Release,
1067 PHAdviseSinkEx_OnDataChange,
1068 PHAdviseSinkEx_OnViewChange,
1069 PHAdviseSinkEx_OnRename,
1070 PHAdviseSinkEx_OnSave,
1071 PHAdviseSinkEx_OnClose,
1072 PHAdviseSinkEx_OnViewStatusChange
1073 };
1074
impl_from_IPropertyNotifySink(IPropertyNotifySink * iface)1075 static inline PluginHost *impl_from_IPropertyNotifySink(IPropertyNotifySink *iface)
1076 {
1077 return CONTAINING_RECORD(iface, PluginHost, IPropertyNotifySink_iface);
1078 }
1079
PHPropertyNotifySink_QueryInterface(IPropertyNotifySink * iface,REFIID riid,void ** ppv)1080 static HRESULT WINAPI PHPropertyNotifySink_QueryInterface(IPropertyNotifySink *iface, REFIID riid, void **ppv)
1081 {
1082 PluginHost *This = impl_from_IPropertyNotifySink(iface);
1083 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
1084 }
1085
PHPropertyNotifySink_AddRef(IPropertyNotifySink * iface)1086 static ULONG WINAPI PHPropertyNotifySink_AddRef(IPropertyNotifySink *iface)
1087 {
1088 PluginHost *This = impl_from_IPropertyNotifySink(iface);
1089 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1090 }
1091
PHPropertyNotifySink_Release(IPropertyNotifySink * iface)1092 static ULONG WINAPI PHPropertyNotifySink_Release(IPropertyNotifySink *iface)
1093 {
1094 PluginHost *This = impl_from_IPropertyNotifySink(iface);
1095 return IOleClientSite_Release(&This->IOleClientSite_iface);
1096 }
1097
PHPropertyNotifySink_OnChanged(IPropertyNotifySink * iface,DISPID dispID)1098 static HRESULT WINAPI PHPropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
1099 {
1100 PluginHost *This = impl_from_IPropertyNotifySink(iface);
1101
1102 TRACE("(%p)->(%d)\n", This, dispID);
1103
1104 switch(dispID) {
1105 case DISPID_READYSTATE:
1106 update_readystate(This);
1107 break;
1108 default :
1109 FIXME("Unimplemented dispID %d\n", dispID);
1110 return E_NOTIMPL;
1111 }
1112
1113 return S_OK;
1114 }
1115
PHPropertyNotifySink_OnRequestEdit(IPropertyNotifySink * iface,DISPID dispID)1116 static HRESULT WINAPI PHPropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
1117 {
1118 PluginHost *This = impl_from_IPropertyNotifySink(iface);
1119 FIXME("(%p)->(%d)\n", This, dispID);
1120 return E_NOTIMPL;
1121 }
1122
1123 static const IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
1124 PHPropertyNotifySink_QueryInterface,
1125 PHPropertyNotifySink_AddRef,
1126 PHPropertyNotifySink_Release,
1127 PHPropertyNotifySink_OnChanged,
1128 PHPropertyNotifySink_OnRequestEdit
1129 };
1130
impl_from_IDispatch(IDispatch * iface)1131 static inline PluginHost *impl_from_IDispatch(IDispatch *iface)
1132 {
1133 return CONTAINING_RECORD(iface, PluginHost, IDispatch_iface);
1134 }
1135
PHDispatch_QueryInterface(IDispatch * iface,REFIID riid,void ** ppv)1136 static HRESULT WINAPI PHDispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
1137 {
1138 PluginHost *This = impl_from_IDispatch(iface);
1139 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
1140 }
1141
PHDispatch_AddRef(IDispatch * iface)1142 static ULONG WINAPI PHDispatch_AddRef(IDispatch *iface)
1143 {
1144 PluginHost *This = impl_from_IDispatch(iface);
1145 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1146 }
1147
PHDispatch_Release(IDispatch * iface)1148 static ULONG WINAPI PHDispatch_Release(IDispatch *iface)
1149 {
1150 PluginHost *This = impl_from_IDispatch(iface);
1151 return IOleClientSite_Release(&This->IOleClientSite_iface);
1152 }
1153
PHDispatch_GetTypeInfoCount(IDispatch * iface,UINT * pctinfo)1154 static HRESULT WINAPI PHDispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
1155 {
1156 PluginHost *This = impl_from_IDispatch(iface);
1157 FIXME("(%p)->(%p)\n", This, pctinfo);
1158 return E_NOTIMPL;
1159 }
1160
PHDispatch_GetTypeInfo(IDispatch * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)1161 static HRESULT WINAPI PHDispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo,
1162 LCID lcid, ITypeInfo **ppTInfo)
1163 {
1164 PluginHost *This = impl_from_IDispatch(iface);
1165 FIXME("(%p)->(%d %d %p)\n", This, iTInfo, lcid, ppTInfo);
1166 return E_NOTIMPL;
1167 }
1168
PHDispatch_GetIDsOfNames(IDispatch * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)1169 static HRESULT WINAPI PHDispatch_GetIDsOfNames(IDispatch *iface, REFIID riid,
1170 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1171 {
1172 PluginHost *This = impl_from_IDispatch(iface);
1173 FIXME("(%p)->(%s %p %d %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
1174 return E_NOTIMPL;
1175 }
1176
PHDispatch_Invoke(IDispatch * iface,DISPID dispid,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)1177 static HRESULT WINAPI PHDispatch_Invoke(IDispatch *iface, DISPID dispid, REFIID riid, LCID lcid,
1178 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1179 {
1180 PluginHost *This = impl_from_IDispatch(iface);
1181 FIXME("(%p)->(%d %x %p %p)\n", This, dispid, wFlags, pDispParams, pVarResult);
1182 return E_NOTIMPL;
1183 }
1184
1185 static const IDispatchVtbl DispatchVtbl = {
1186 PHDispatch_QueryInterface,
1187 PHDispatch_AddRef,
1188 PHDispatch_Release,
1189 PHDispatch_GetTypeInfoCount,
1190 PHDispatch_GetTypeInfo,
1191 PHDispatch_GetIDsOfNames,
1192 PHDispatch_Invoke
1193 };
1194
impl_from_IOleInPlaceSiteEx(IOleInPlaceSiteEx * iface)1195 static inline PluginHost *impl_from_IOleInPlaceSiteEx(IOleInPlaceSiteEx *iface)
1196 {
1197 return CONTAINING_RECORD(iface, PluginHost, IOleInPlaceSiteEx_iface);
1198 }
1199
PHInPlaceSite_QueryInterface(IOleInPlaceSiteEx * iface,REFIID riid,void ** ppv)1200 static HRESULT WINAPI PHInPlaceSite_QueryInterface(IOleInPlaceSiteEx *iface, REFIID riid, void **ppv)
1201 {
1202 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1203 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
1204 }
1205
PHInPlaceSite_AddRef(IOleInPlaceSiteEx * iface)1206 static ULONG WINAPI PHInPlaceSite_AddRef(IOleInPlaceSiteEx *iface)
1207 {
1208 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1209 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1210 }
1211
PHInPlaceSite_Release(IOleInPlaceSiteEx * iface)1212 static ULONG WINAPI PHInPlaceSite_Release(IOleInPlaceSiteEx *iface)
1213 {
1214 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1215 return IOleClientSite_Release(&This->IOleClientSite_iface);
1216 }
1217
PHInPlaceSite_GetWindow(IOleInPlaceSiteEx * iface,HWND * phwnd)1218 static HRESULT WINAPI PHInPlaceSite_GetWindow(IOleInPlaceSiteEx *iface, HWND *phwnd)
1219 {
1220 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1221
1222 TRACE("(%p)->(%p)\n", This, phwnd);
1223
1224 *phwnd = This->hwnd;
1225 return S_OK;
1226 }
1227
PHInPlaceSite_ContextSensitiveHelp(IOleInPlaceSiteEx * iface,BOOL fEnterMode)1228 static HRESULT WINAPI PHInPlaceSite_ContextSensitiveHelp(IOleInPlaceSiteEx *iface, BOOL fEnterMode)
1229 {
1230 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1231 FIXME("(%p)->(%x)\n", This, fEnterMode);
1232 return E_NOTIMPL;
1233 }
1234
PHInPlaceSite_CanInPlaceActivate(IOleInPlaceSiteEx * iface)1235 static HRESULT WINAPI PHInPlaceSite_CanInPlaceActivate(IOleInPlaceSiteEx *iface)
1236 {
1237 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1238
1239 TRACE("(%p)\n", This);
1240
1241 return S_OK;
1242 }
1243
PHInPlaceSite_OnInPlaceActivate(IOleInPlaceSiteEx * iface)1244 static HRESULT WINAPI PHInPlaceSite_OnInPlaceActivate(IOleInPlaceSiteEx *iface)
1245 {
1246 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1247 FIXME("(%p)\n", This);
1248 return E_NOTIMPL;
1249 }
1250
PHInPlaceSite_OnUIActivate(IOleInPlaceSiteEx * iface)1251 static HRESULT WINAPI PHInPlaceSite_OnUIActivate(IOleInPlaceSiteEx *iface)
1252 {
1253 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1254
1255 TRACE("(%p)\n", This);
1256
1257 if(!This->plugin_unk) {
1258 ERR("No plugin object\n");
1259 return E_UNEXPECTED;
1260 }
1261
1262 This->ui_active = TRUE;
1263
1264 notif_enabled(This);
1265 return S_OK;
1266 }
1267
PHInPlaceSite_GetWindowContext(IOleInPlaceSiteEx * iface,IOleInPlaceFrame ** ppFrame,IOleInPlaceUIWindow ** ppDoc,RECT * lprcPosRect,RECT * lprcClipRect,OLEINPLACEFRAMEINFO * frame_info)1268 static HRESULT WINAPI PHInPlaceSite_GetWindowContext(IOleInPlaceSiteEx *iface,
1269 IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, RECT *lprcPosRect,
1270 RECT *lprcClipRect, OLEINPLACEFRAMEINFO *frame_info)
1271 {
1272 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1273 IOleInPlaceUIWindow *ip_window;
1274 IOleInPlaceFrame *ip_frame;
1275 RECT pr, cr;
1276 HRESULT hres;
1277
1278 TRACE("(%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, frame_info);
1279
1280 if(!This->doc || !This->doc->basedoc.doc_obj || !This->doc->basedoc.doc_obj->ipsite) {
1281 FIXME("No ipsite\n");
1282 return E_UNEXPECTED;
1283 }
1284
1285 hres = IOleInPlaceSite_GetWindowContext(This->doc->basedoc.doc_obj->ipsite, &ip_frame, &ip_window, &pr, &cr, frame_info);
1286 if(FAILED(hres)) {
1287 WARN("GetWindowContext failed: %08x\n", hres);
1288 return hres;
1289 }
1290
1291 if(ip_window)
1292 IOleInPlaceUIWindow_Release(ip_window);
1293 if(ip_frame)
1294 IOleInPlaceFrame_Release(ip_frame);
1295
1296 hres = create_ip_frame(&ip_frame);
1297 if(FAILED(hres))
1298 return hres;
1299
1300 hres = create_ip_window(ppDoc);
1301 if(FAILED(hres)) {
1302 IOleInPlaceFrame_Release(ip_frame);
1303 return hres;
1304 }
1305
1306 *ppFrame = ip_frame;
1307 *lprcPosRect = This->rect;
1308 *lprcClipRect = This->rect;
1309 return S_OK;
1310 }
1311
PHInPlaceSite_Scroll(IOleInPlaceSiteEx * iface,SIZE scrollExtent)1312 static HRESULT WINAPI PHInPlaceSite_Scroll(IOleInPlaceSiteEx *iface, SIZE scrollExtent)
1313 {
1314 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1315 FIXME("(%p)->({%d %d})\n", This, scrollExtent.cx, scrollExtent.cy);
1316 return E_NOTIMPL;
1317 }
1318
PHInPlaceSite_OnUIDeactivate(IOleInPlaceSiteEx * iface,BOOL fUndoable)1319 static HRESULT WINAPI PHInPlaceSite_OnUIDeactivate(IOleInPlaceSiteEx *iface, BOOL fUndoable)
1320 {
1321 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1322 FIXME("(%p)->(%x)\n", This, fUndoable);
1323 return E_NOTIMPL;
1324 }
1325
PHInPlaceSite_OnInPlaceDeactivate(IOleInPlaceSiteEx * iface)1326 static HRESULT WINAPI PHInPlaceSite_OnInPlaceDeactivate(IOleInPlaceSiteEx *iface)
1327 {
1328 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1329
1330 TRACE("(%p)\n", This);
1331
1332 if(This->ip_object) {
1333 IOleInPlaceObject_Release(This->ip_object);
1334 This->ip_object = NULL;
1335 }
1336
1337 return S_OK;
1338 }
1339
PHInPlaceSite_DiscardUndoState(IOleInPlaceSiteEx * iface)1340 static HRESULT WINAPI PHInPlaceSite_DiscardUndoState(IOleInPlaceSiteEx *iface)
1341 {
1342 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1343 FIXME("(%p)\n", This);
1344 return E_NOTIMPL;
1345 }
1346
PHInPlaceSite_DeactivateAndUndo(IOleInPlaceSiteEx * iface)1347 static HRESULT WINAPI PHInPlaceSite_DeactivateAndUndo(IOleInPlaceSiteEx *iface)
1348 {
1349 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1350 FIXME("(%p)\n", This);
1351 return E_NOTIMPL;
1352 }
1353
PHInPlaceSite_OnPosRectChange(IOleInPlaceSiteEx * iface,LPCRECT lprcPosRect)1354 static HRESULT WINAPI PHInPlaceSite_OnPosRectChange(IOleInPlaceSiteEx *iface, LPCRECT lprcPosRect)
1355 {
1356 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1357 FIXME("(%p)->(%p)\n", This, lprcPosRect);
1358 return E_NOTIMPL;
1359 }
1360
PHInPlaceSiteEx_OnInPlaceActivateEx(IOleInPlaceSiteEx * iface,BOOL * pfNoRedraw,DWORD dwFlags)1361 static HRESULT WINAPI PHInPlaceSiteEx_OnInPlaceActivateEx(IOleInPlaceSiteEx *iface, BOOL *pfNoRedraw, DWORD dwFlags)
1362 {
1363 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1364 HWND hwnd;
1365 HRESULT hres;
1366
1367 TRACE("(%p)->(%p %x)\n", This, pfNoRedraw, dwFlags);
1368
1369 if(This->ip_object)
1370 return S_OK;
1371
1372 hres = IUnknown_QueryInterface(This->plugin_unk, &IID_IOleInPlaceObject, (void**)&This->ip_object);
1373 if(FAILED(hres))
1374 return hres;
1375
1376 hres = IOleInPlaceObject_GetWindow(This->ip_object, &hwnd);
1377 if(SUCCEEDED(hres))
1378 FIXME("Use hwnd %p\n", hwnd);
1379
1380 *pfNoRedraw = FALSE;
1381 return S_OK;
1382 }
1383
PHInPlaceSiteEx_OnInPlaceDeactivateEx(IOleInPlaceSiteEx * iface,BOOL fNoRedraw)1384 static HRESULT WINAPI PHInPlaceSiteEx_OnInPlaceDeactivateEx(IOleInPlaceSiteEx *iface, BOOL fNoRedraw)
1385 {
1386 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1387 FIXME("(%p)->(%x)\n", This, fNoRedraw);
1388 return E_NOTIMPL;
1389 }
1390
PHInPlaceSiteEx_RequestUIActivate(IOleInPlaceSiteEx * iface)1391 static HRESULT WINAPI PHInPlaceSiteEx_RequestUIActivate(IOleInPlaceSiteEx *iface)
1392 {
1393 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1394 FIXME("(%p)\n", This);
1395 return E_NOTIMPL;
1396 }
1397
1398 static const IOleInPlaceSiteExVtbl OleInPlaceSiteExVtbl = {
1399 PHInPlaceSite_QueryInterface,
1400 PHInPlaceSite_AddRef,
1401 PHInPlaceSite_Release,
1402 PHInPlaceSite_GetWindow,
1403 PHInPlaceSite_ContextSensitiveHelp,
1404 PHInPlaceSite_CanInPlaceActivate,
1405 PHInPlaceSite_OnInPlaceActivate,
1406 PHInPlaceSite_OnUIActivate,
1407 PHInPlaceSite_GetWindowContext,
1408 PHInPlaceSite_Scroll,
1409 PHInPlaceSite_OnUIDeactivate,
1410 PHInPlaceSite_OnInPlaceDeactivate,
1411 PHInPlaceSite_DiscardUndoState,
1412 PHInPlaceSite_DeactivateAndUndo,
1413 PHInPlaceSite_OnPosRectChange,
1414 PHInPlaceSiteEx_OnInPlaceActivateEx,
1415 PHInPlaceSiteEx_OnInPlaceDeactivateEx,
1416 PHInPlaceSiteEx_RequestUIActivate
1417 };
1418
impl_from_IOleControlSite(IOleControlSite * iface)1419 static inline PluginHost *impl_from_IOleControlSite(IOleControlSite *iface)
1420 {
1421 return CONTAINING_RECORD(iface, PluginHost, IOleControlSite_iface);
1422 }
1423
PHControlSite_QueryInterface(IOleControlSite * iface,REFIID riid,void ** ppv)1424 static HRESULT WINAPI PHControlSite_QueryInterface(IOleControlSite *iface, REFIID riid, void **ppv)
1425 {
1426 PluginHost *This = impl_from_IOleControlSite(iface);
1427 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
1428 }
1429
PHControlSite_AddRef(IOleControlSite * iface)1430 static ULONG WINAPI PHControlSite_AddRef(IOleControlSite *iface)
1431 {
1432 PluginHost *This = impl_from_IOleControlSite(iface);
1433 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1434 }
1435
PHControlSite_Release(IOleControlSite * iface)1436 static ULONG WINAPI PHControlSite_Release(IOleControlSite *iface)
1437 {
1438 PluginHost *This = impl_from_IOleControlSite(iface);
1439 return IOleClientSite_Release(&This->IOleClientSite_iface);
1440 }
1441
PHControlSite_OnControlInfoChanged(IOleControlSite * iface)1442 static HRESULT WINAPI PHControlSite_OnControlInfoChanged(IOleControlSite *iface)
1443 {
1444 PluginHost *This = impl_from_IOleControlSite(iface);
1445 FIXME("(%p)\n", This);
1446 return E_NOTIMPL;
1447 }
1448
PHControlSite_LockInPlaceActive(IOleControlSite * iface,BOOL fLock)1449 static HRESULT WINAPI PHControlSite_LockInPlaceActive(IOleControlSite *iface, BOOL fLock)
1450 {
1451 PluginHost *This = impl_from_IOleControlSite(iface);
1452 FIXME("(%p)->(%x)\n", This, fLock);
1453 return E_NOTIMPL;
1454 }
1455
PHControlSite_GetExtendedControl(IOleControlSite * iface,IDispatch ** ppDisp)1456 static HRESULT WINAPI PHControlSite_GetExtendedControl(IOleControlSite *iface, IDispatch **ppDisp)
1457 {
1458 PluginHost *This = impl_from_IOleControlSite(iface);
1459 FIXME("(%p)->(%p)\n", This, ppDisp);
1460 return E_NOTIMPL;
1461 }
1462
PHControlSite_TransformCoords(IOleControlSite * iface,POINTL * pPtlHimetric,POINTF * pPtfContainer,DWORD dwFlags)1463 static HRESULT WINAPI PHControlSite_TransformCoords(IOleControlSite *iface, POINTL *pPtlHimetric, POINTF *pPtfContainer, DWORD dwFlags)
1464 {
1465 PluginHost *This = impl_from_IOleControlSite(iface);
1466 FIXME("(%p)->(%p %p %x)\n", This, pPtlHimetric, pPtfContainer, dwFlags);
1467 return E_NOTIMPL;
1468 }
1469
PHControlSite_TranslateAccelerator(IOleControlSite * iface,MSG * pMsg,DWORD grfModifiers)1470 static HRESULT WINAPI PHControlSite_TranslateAccelerator(IOleControlSite *iface, MSG *pMsg, DWORD grfModifiers)
1471 {
1472 PluginHost *This = impl_from_IOleControlSite(iface);
1473 FIXME("(%p)->(%x)\n", This, grfModifiers);
1474 return E_NOTIMPL;
1475 }
1476
PHControlSite_OnFocus(IOleControlSite * iface,BOOL fGotFocus)1477 static HRESULT WINAPI PHControlSite_OnFocus(IOleControlSite *iface, BOOL fGotFocus)
1478 {
1479 PluginHost *This = impl_from_IOleControlSite(iface);
1480 FIXME("(%p)->(%x)\n", This, fGotFocus);
1481 return E_NOTIMPL;
1482 }
1483
PHControlSite_ShowPropertyFrame(IOleControlSite * iface)1484 static HRESULT WINAPI PHControlSite_ShowPropertyFrame(IOleControlSite *iface)
1485 {
1486 PluginHost *This = impl_from_IOleControlSite(iface);
1487 FIXME("(%p)\n", This);
1488 return E_NOTIMPL;
1489 }
1490
1491 static const IOleControlSiteVtbl OleControlSiteVtbl = {
1492 PHControlSite_QueryInterface,
1493 PHControlSite_AddRef,
1494 PHControlSite_Release,
1495 PHControlSite_OnControlInfoChanged,
1496 PHControlSite_LockInPlaceActive,
1497 PHControlSite_GetExtendedControl,
1498 PHControlSite_TransformCoords,
1499 PHControlSite_TranslateAccelerator,
1500 PHControlSite_OnFocus,
1501 PHControlSite_ShowPropertyFrame
1502 };
1503
impl_from_IBindHost(IBindHost * iface)1504 static inline PluginHost *impl_from_IBindHost(IBindHost *iface)
1505 {
1506 return CONTAINING_RECORD(iface, PluginHost, IBindHost_iface);
1507 }
1508
PHBindHost_QueryInterface(IBindHost * iface,REFIID riid,void ** ppv)1509 static HRESULT WINAPI PHBindHost_QueryInterface(IBindHost *iface, REFIID riid, void **ppv)
1510 {
1511 PluginHost *This = impl_from_IBindHost(iface);
1512 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
1513 }
1514
PHBindHost_AddRef(IBindHost * iface)1515 static ULONG WINAPI PHBindHost_AddRef(IBindHost *iface)
1516 {
1517 PluginHost *This = impl_from_IBindHost(iface);
1518 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1519 }
1520
PHBindHost_Release(IBindHost * iface)1521 static ULONG WINAPI PHBindHost_Release(IBindHost *iface)
1522 {
1523 PluginHost *This = impl_from_IBindHost(iface);
1524 return IOleClientSite_Release(&This->IOleClientSite_iface);
1525 }
1526
PHBindHost_CreateMoniker(IBindHost * iface,LPOLESTR szName,IBindCtx * pBC,IMoniker ** ppmk,DWORD dwReserved)1527 static HRESULT WINAPI PHBindHost_CreateMoniker(IBindHost *iface, LPOLESTR szName, IBindCtx *pBC, IMoniker **ppmk, DWORD dwReserved)
1528 {
1529 PluginHost *This = impl_from_IBindHost(iface);
1530
1531 TRACE("(%p)->(%s %p %p %x)\n", This, debugstr_w(szName), pBC, ppmk, dwReserved);
1532
1533 if(!This->doc || !This->doc->window || !This->doc->window->mon) {
1534 FIXME("no moniker\n");
1535 return E_UNEXPECTED;
1536 }
1537
1538 return CreateURLMoniker(This->doc->window->mon, szName, ppmk);
1539 }
1540
PHBindHost_MonikerBindToStorage(IBindHost * iface,IMoniker * pMk,IBindCtx * pBC,IBindStatusCallback * pBSC,REFIID riid,void ** ppvObj)1541 static HRESULT WINAPI PHBindHost_MonikerBindToStorage(IBindHost *iface, IMoniker *pMk, IBindCtx *pBC,
1542 IBindStatusCallback *pBSC, REFIID riid, void **ppvObj)
1543 {
1544 PluginHost *This = impl_from_IBindHost(iface);
1545 FIXME("(%p)->(%p %p %p %s %p)\n", This, pMk, pBC, pBSC, debugstr_guid(riid), ppvObj);
1546 return E_NOTIMPL;
1547 }
1548
PHBindHost_MonikerBindToObject(IBindHost * iface,IMoniker * pMk,IBindCtx * pBC,IBindStatusCallback * pBSC,REFIID riid,void ** ppvObj)1549 static HRESULT WINAPI PHBindHost_MonikerBindToObject(IBindHost *iface, IMoniker *pMk, IBindCtx *pBC,
1550 IBindStatusCallback *pBSC, REFIID riid, void **ppvObj)
1551 {
1552 PluginHost *This = impl_from_IBindHost(iface);
1553 FIXME("(%p)->(%p %p %p %s %p)\n", This, pMk, pBC, pBSC, debugstr_guid(riid), ppvObj);
1554 return E_NOTIMPL;
1555 }
1556
1557 static const IBindHostVtbl BindHostVtbl = {
1558 PHBindHost_QueryInterface,
1559 PHBindHost_AddRef,
1560 PHBindHost_Release,
1561 PHBindHost_CreateMoniker,
1562 PHBindHost_MonikerBindToStorage,
1563 PHBindHost_MonikerBindToObject
1564 };
1565
impl_from_IServiceProvider(IServiceProvider * iface)1566 static inline PluginHost *impl_from_IServiceProvider(IServiceProvider *iface)
1567 {
1568 return CONTAINING_RECORD(iface, PluginHost, IServiceProvider_iface);
1569 }
1570
PHServiceProvider_QueryInterface(IServiceProvider * iface,REFIID riid,void ** ppv)1571 static HRESULT WINAPI PHServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
1572 {
1573 PluginHost *This = impl_from_IServiceProvider(iface);
1574 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
1575 }
1576
PHServiceProvider_AddRef(IServiceProvider * iface)1577 static ULONG WINAPI PHServiceProvider_AddRef(IServiceProvider *iface)
1578 {
1579 PluginHost *This = impl_from_IServiceProvider(iface);
1580 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1581 }
1582
PHServiceProvider_Release(IServiceProvider * iface)1583 static ULONG WINAPI PHServiceProvider_Release(IServiceProvider *iface)
1584 {
1585 PluginHost *This = impl_from_IServiceProvider(iface);
1586 return IOleClientSite_Release(&This->IOleClientSite_iface);
1587 }
1588
PHServiceProvider_QueryService(IServiceProvider * iface,REFGUID guidService,REFIID riid,void ** ppv)1589 static HRESULT WINAPI PHServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv)
1590 {
1591 PluginHost *This = impl_from_IServiceProvider(iface);
1592
1593 if(IsEqualGUID(guidService, &SID_SBindHost)) {
1594 TRACE("SID_SBindHost service\n");
1595 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
1596 }
1597
1598 TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
1599
1600 if(!This->doc || !This->doc->basedoc.window) {
1601 *ppv = NULL;
1602 return E_NOINTERFACE;
1603 }
1604
1605 return IServiceProvider_QueryService(&This->doc->basedoc.window->base.IServiceProvider_iface,
1606 guidService, riid, ppv);
1607 }
1608
1609 static const IServiceProviderVtbl ServiceProviderVtbl = {
1610 PHServiceProvider_QueryInterface,
1611 PHServiceProvider_AddRef,
1612 PHServiceProvider_Release,
1613 PHServiceProvider_QueryService
1614 };
1615
parse_classid(const PRUnichar * classid,CLSID * clsid)1616 static BOOL parse_classid(const PRUnichar *classid, CLSID *clsid)
1617 {
1618 const WCHAR *ptr;
1619 unsigned len;
1620 HRESULT hres;
1621
1622 static const PRUnichar clsidW[] = {'c','l','s','i','d',':'};
1623
1624 if(strncmpiW(classid, clsidW, sizeof(clsidW)/sizeof(WCHAR)))
1625 return FALSE;
1626
1627 ptr = classid + sizeof(clsidW)/sizeof(WCHAR);
1628 len = strlenW(ptr);
1629
1630 if(len == 38) {
1631 hres = CLSIDFromString(ptr, clsid);
1632 }else if(len == 36) {
1633 WCHAR buf[39];
1634
1635 buf[0] = '{';
1636 memcpy(buf+1, ptr, len*sizeof(WCHAR));
1637 buf[37] = '}';
1638 buf[38] = 0;
1639 hres = CLSIDFromString(buf, clsid);
1640 }else {
1641 return FALSE;
1642 }
1643
1644 return SUCCEEDED(hres);
1645 }
1646
get_elem_clsid(nsIDOMHTMLElement * elem,CLSID * clsid)1647 static BOOL get_elem_clsid(nsIDOMHTMLElement *elem, CLSID *clsid)
1648 {
1649 const PRUnichar *val;
1650 nsAString val_str;
1651 nsresult nsres;
1652 BOOL ret = FALSE;
1653
1654 static const PRUnichar classidW[] = {'c','l','a','s','s','i','d',0};
1655
1656 nsres = get_elem_attr_value(elem, classidW, &val_str, &val);
1657 if(NS_SUCCEEDED(nsres)) {
1658 if(*val)
1659 ret = parse_classid(val, clsid);
1660 nsAString_Finish(&val_str);
1661 }
1662
1663 return ret;
1664 }
1665
1666 typedef struct {
1667 IBindStatusCallback IBindStatusCallback_iface;
1668 IWindowForBindingUI IWindowForBindingUI_iface;
1669 LONG ref;
1670 } InstallCallback;
1671
impl_from_IBindStatusCallback(IBindStatusCallback * iface)1672 static inline InstallCallback *impl_from_IBindStatusCallback(IBindStatusCallback *iface)
1673 {
1674 return CONTAINING_RECORD(iface, InstallCallback, IBindStatusCallback_iface);
1675 }
1676
InstallCallback_QueryInterface(IBindStatusCallback * iface,REFIID riid,void ** ppv)1677 static HRESULT WINAPI InstallCallback_QueryInterface(IBindStatusCallback *iface,
1678 REFIID riid, void **ppv)
1679 {
1680 InstallCallback *This = impl_from_IBindStatusCallback(iface);
1681
1682 if(IsEqualGUID(&IID_IUnknown, riid)) {
1683 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
1684 *ppv = &This->IBindStatusCallback_iface;
1685 }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
1686 TRACE("(%p)->(IID_IBindStatusCallback %p)\n", This, ppv);
1687 *ppv = &This->IBindStatusCallback_iface;
1688 }else if(IsEqualGUID(&IID_IWindowForBindingUI, riid)) {
1689 TRACE("(%p)->(IID_IWindowForBindingUI %p)\n", This, ppv);
1690 *ppv = &This->IWindowForBindingUI_iface;
1691 }else {
1692 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1693 *ppv = NULL;
1694 return E_NOINTERFACE;
1695 }
1696
1697 IUnknown_AddRef((IUnknown*)*ppv);
1698 return S_OK;
1699 }
1700
InstallCallback_AddRef(IBindStatusCallback * iface)1701 static ULONG WINAPI InstallCallback_AddRef(IBindStatusCallback *iface)
1702 {
1703 InstallCallback *This = impl_from_IBindStatusCallback(iface);
1704 LONG ref = InterlockedIncrement(&This->ref);
1705
1706 TRACE("(%p) ref=%d\n", This, ref);
1707
1708 return ref;
1709 }
1710
InstallCallback_Release(IBindStatusCallback * iface)1711 static ULONG WINAPI InstallCallback_Release(IBindStatusCallback *iface)
1712 {
1713 InstallCallback *This = impl_from_IBindStatusCallback(iface);
1714 LONG ref = InterlockedIncrement(&This->ref);
1715
1716 TRACE("(%p) ref=%d\n", This, ref);
1717
1718 if(!ref)
1719 heap_free(This);
1720
1721 return ref;
1722 }
1723
InstallCallback_OnStartBinding(IBindStatusCallback * iface,DWORD dwReserved,IBinding * pib)1724 static HRESULT WINAPI InstallCallback_OnStartBinding(IBindStatusCallback *iface,
1725 DWORD dwReserved, IBinding *pib)
1726 {
1727 InstallCallback *This = impl_from_IBindStatusCallback(iface);
1728 TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
1729 return S_OK;
1730 }
1731
InstallCallback_GetPriority(IBindStatusCallback * iface,LONG * pnPriority)1732 static HRESULT WINAPI InstallCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
1733 {
1734 InstallCallback *This = impl_from_IBindStatusCallback(iface);
1735 TRACE("(%p)->(%p)\n", This, pnPriority);
1736 return E_NOTIMPL;
1737 }
1738
InstallCallback_OnLowResource(IBindStatusCallback * iface,DWORD dwReserved)1739 static HRESULT WINAPI InstallCallback_OnLowResource(IBindStatusCallback *iface, DWORD dwReserved)
1740 {
1741 InstallCallback *This = impl_from_IBindStatusCallback(iface);
1742 TRACE("(%p)->(%x)\n", This, dwReserved);
1743 return S_OK;
1744 }
1745
InstallCallback_OnProgress(IBindStatusCallback * iface,ULONG ulProgress,ULONG ulProgressMax,ULONG ulStatusCode,LPCWSTR szStatusText)1746 static HRESULT WINAPI InstallCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
1747 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
1748 {
1749 InstallCallback *This = impl_from_IBindStatusCallback(iface);
1750 TRACE("(%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode, debugstr_w(szStatusText));
1751 return S_OK;
1752 }
1753
InstallCallback_OnStopBinding(IBindStatusCallback * iface,HRESULT hresult,LPCWSTR szError)1754 static HRESULT WINAPI InstallCallback_OnStopBinding(IBindStatusCallback *iface,
1755 HRESULT hresult, LPCWSTR szError)
1756 {
1757 InstallCallback *This = impl_from_IBindStatusCallback(iface);
1758 TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
1759 return S_OK;
1760 }
1761
InstallCallback_GetBindInfo(IBindStatusCallback * iface,DWORD * grfBINDF,BINDINFO * pbindinfo)1762 static HRESULT WINAPI InstallCallback_GetBindInfo(IBindStatusCallback *iface,
1763 DWORD* grfBINDF, BINDINFO* pbindinfo)
1764 {
1765 InstallCallback *This = impl_from_IBindStatusCallback(iface);
1766
1767 TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
1768
1769 *grfBINDF = BINDF_ASYNCHRONOUS;
1770 return S_OK;
1771 }
1772
InstallCallback_OnDataAvailable(IBindStatusCallback * iface,DWORD grfBSCF,DWORD dwSize,FORMATETC * pformatetc,STGMEDIUM * pstgmed)1773 static HRESULT WINAPI InstallCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
1774 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
1775 {
1776 InstallCallback *This = impl_from_IBindStatusCallback(iface);
1777 ERR("(%p)\n", This);
1778 return E_NOTIMPL;
1779 }
1780
InstallCallback_OnObjectAvailable(IBindStatusCallback * iface,REFIID riid,IUnknown * punk)1781 static HRESULT WINAPI InstallCallback_OnObjectAvailable(IBindStatusCallback *iface,
1782 REFIID riid, IUnknown* punk)
1783 {
1784 InstallCallback *This = impl_from_IBindStatusCallback(iface);
1785 ERR("(%p)\n", This);
1786 return E_NOTIMPL;
1787 }
1788
1789 static IBindStatusCallbackVtbl InstallCallbackVtbl = {
1790 InstallCallback_QueryInterface,
1791 InstallCallback_AddRef,
1792 InstallCallback_Release,
1793 InstallCallback_OnStartBinding,
1794 InstallCallback_GetPriority,
1795 InstallCallback_OnLowResource,
1796 InstallCallback_OnProgress,
1797 InstallCallback_OnStopBinding,
1798 InstallCallback_GetBindInfo,
1799 InstallCallback_OnDataAvailable,
1800 InstallCallback_OnObjectAvailable
1801 };
1802
impl_from_IWindowForBindingUI(IWindowForBindingUI * iface)1803 static inline InstallCallback *impl_from_IWindowForBindingUI(IWindowForBindingUI *iface)
1804 {
1805 return CONTAINING_RECORD(iface, InstallCallback, IWindowForBindingUI_iface);
1806 }
1807
WindowForBindingUI_QueryInterface(IWindowForBindingUI * iface,REFIID riid,void ** ppv)1808 static HRESULT WINAPI WindowForBindingUI_QueryInterface(IWindowForBindingUI *iface, REFIID riid, void **ppv)
1809 {
1810 InstallCallback *This = impl_from_IWindowForBindingUI(iface);
1811 return IBindStatusCallback_QueryInterface(&This->IBindStatusCallback_iface, riid, ppv);
1812 }
1813
WindowForBindingUI_AddRef(IWindowForBindingUI * iface)1814 static ULONG WINAPI WindowForBindingUI_AddRef(IWindowForBindingUI *iface)
1815 {
1816 InstallCallback *This = impl_from_IWindowForBindingUI(iface);
1817 return IBindStatusCallback_AddRef(&This->IBindStatusCallback_iface);
1818 }
1819
WindowForBindingUI_Release(IWindowForBindingUI * iface)1820 static ULONG WINAPI WindowForBindingUI_Release(IWindowForBindingUI *iface)
1821 {
1822 InstallCallback *This = impl_from_IWindowForBindingUI(iface);
1823 return IBindStatusCallback_Release(&This->IBindStatusCallback_iface);
1824 }
1825
WindowForBindingUI_GetWindow(IWindowForBindingUI * iface,REFGUID rguidReason,HWND * phwnd)1826 static HRESULT WINAPI WindowForBindingUI_GetWindow(IWindowForBindingUI *iface, REFGUID rguidReason, HWND *phwnd)
1827 {
1828 InstallCallback *This = impl_from_IWindowForBindingUI(iface);
1829 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(rguidReason), phwnd);
1830 *phwnd = NULL;
1831 return S_OK;
1832 }
1833
1834 static const IWindowForBindingUIVtbl WindowForBindingUIVtbl = {
1835 WindowForBindingUI_QueryInterface,
1836 WindowForBindingUI_AddRef,
1837 WindowForBindingUI_Release,
1838 WindowForBindingUI_GetWindow
1839 };
1840
1841 typedef struct {
1842 struct list entry;
1843 IUri *uri;
1844 } install_entry_t;
1845
1846 static struct list install_list = LIST_INIT(install_list);
1847
1848 static CRITICAL_SECTION cs_install_list;
1849 static CRITICAL_SECTION_DEBUG cs_install_list_dbg =
1850 {
1851 0, 0, &cs_install_list,
1852 { &cs_install_list_dbg.ProcessLocksList, &cs_install_list_dbg.ProcessLocksList },
1853 0, 0, { (DWORD_PTR)(__FILE__ ": install_list") }
1854 };
1855 static CRITICAL_SECTION cs_install_list = { &cs_install_list_dbg, -1, 0, 0, 0, 0 };
1856
install_codebase(const WCHAR * url)1857 static void install_codebase(const WCHAR *url)
1858 {
1859 InstallCallback *callback;
1860 IBindCtx *bctx;
1861 HRESULT hres;
1862
1863 callback = heap_alloc(sizeof(*callback));
1864 if(!callback)
1865 return;
1866
1867 callback->IBindStatusCallback_iface.lpVtbl = &InstallCallbackVtbl;
1868 callback->IWindowForBindingUI_iface.lpVtbl = &WindowForBindingUIVtbl;
1869 callback->ref = 1;
1870
1871 hres = CreateAsyncBindCtx(0, &callback->IBindStatusCallback_iface, NULL, &bctx);
1872 IBindStatusCallback_Release(&callback->IBindStatusCallback_iface);
1873 if(FAILED(hres))
1874 return;
1875
1876 hres = AsyncInstallDistributionUnit(NULL, NULL, NULL, 0, 0, url, bctx, NULL, 0);
1877 IBindCtx_Release(bctx);
1878 if(FAILED(hres))
1879 WARN("FAILED: %08x\n", hres);
1880 }
1881
check_codebase(HTMLInnerWindow * window,nsIDOMHTMLElement * nselem)1882 static void check_codebase(HTMLInnerWindow *window, nsIDOMHTMLElement *nselem)
1883 {
1884 BOOL is_on_list = FALSE;
1885 install_entry_t *iter;
1886 const PRUnichar *val;
1887 nsAString val_str;
1888 IUri *uri = NULL;
1889 nsresult nsres;
1890 HRESULT hres;
1891
1892 static const PRUnichar codebaseW[] = {'c','o','d','e','b','a','s','e',0};
1893
1894 nsres = get_elem_attr_value(nselem, codebaseW, &val_str, &val);
1895 if(NS_SUCCEEDED(nsres)) {
1896 if(*val) {
1897 hres = CoInternetCombineUrlEx(window->base.outer_window->uri, val, 0, &uri, 0);
1898 if(FAILED(hres))
1899 uri = NULL;
1900 }
1901 nsAString_Finish(&val_str);
1902 }
1903
1904 if(!uri)
1905 return;
1906
1907 EnterCriticalSection(&cs_install_list);
1908
1909 LIST_FOR_EACH_ENTRY(iter, &install_list, install_entry_t, entry) {
1910 BOOL eq;
1911
1912 hres = IUri_IsEqual(uri, iter->uri, &eq);
1913 if(SUCCEEDED(hres) && eq) {
1914 TRACE("already proceeded\n");
1915 is_on_list = TRUE;
1916 break;
1917 }
1918 }
1919
1920 if(!is_on_list) {
1921 iter = heap_alloc(sizeof(*iter));
1922 if(iter) {
1923 IUri_AddRef(uri);
1924 iter->uri = uri;
1925
1926 list_add_tail(&install_list, &iter->entry);
1927 }
1928 }
1929
1930 LeaveCriticalSection(&cs_install_list);
1931
1932 if(!is_on_list) {
1933 BSTR display_uri;
1934
1935 hres = IUri_GetDisplayUri(uri, &display_uri);
1936 if(SUCCEEDED(hres)) {
1937 install_codebase(display_uri);
1938 SysFreeString(display_uri);
1939 }
1940 }
1941
1942 IUri_Release(uri);
1943 }
1944
create_activex_object(HTMLDocumentNode * doc,nsIDOMHTMLElement * nselem,CLSID * clsid)1945 static IUnknown *create_activex_object(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, CLSID *clsid)
1946 {
1947 IClassFactoryEx *cfex;
1948 IClassFactory *cf;
1949 IUnknown *obj;
1950 DWORD policy;
1951 HRESULT hres;
1952
1953 if(!get_elem_clsid(nselem, clsid)) {
1954 WARN("Could not determine element CLSID\n");
1955 return NULL;
1956 }
1957
1958 TRACE("clsid %s\n", debugstr_guid(clsid));
1959
1960 policy = 0;
1961 hres = IInternetHostSecurityManager_ProcessUrlAction(&doc->IInternetHostSecurityManager_iface,
1962 URLACTION_ACTIVEX_RUN, (BYTE*)&policy, sizeof(policy), (BYTE*)clsid, sizeof(GUID), 0, 0);
1963 if(FAILED(hres) || policy != URLPOLICY_ALLOW) {
1964 WARN("ProcessUrlAction returned %08x %x\n", hres, policy);
1965 return NULL;
1966 }
1967
1968 hres = CoGetClassObject(clsid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf);
1969 if(hres == REGDB_E_CLASSNOTREG)
1970 check_codebase(doc->window, nselem);
1971 if(FAILED(hres))
1972 return NULL;
1973
1974 hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, (void**)&cfex);
1975 if(SUCCEEDED(hres)) {
1976 FIXME("Use IClassFactoryEx\n");
1977 IClassFactoryEx_Release(cfex);
1978 }
1979
1980 hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj);
1981 IClassFactory_Release(cf);
1982 if(FAILED(hres))
1983 return NULL;
1984
1985 return obj;
1986 }
1987
detach_plugin_host(PluginHost * host)1988 void detach_plugin_host(PluginHost *host)
1989 {
1990 HRESULT hres;
1991
1992 TRACE("%p\n", host);
1993
1994 if(!host->doc)
1995 return;
1996
1997 if(host->ip_object) {
1998 if(host->ui_active)
1999 IOleInPlaceObject_UIDeactivate(host->ip_object);
2000 IOleInPlaceObject_InPlaceDeactivate(host->ip_object);
2001 }
2002
2003 if(host->plugin_unk) {
2004 IOleObject *ole_obj;
2005
2006 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IOleObject, (void**)&ole_obj);
2007 if(SUCCEEDED(hres)) {
2008 if(!host->ip_object)
2009 IOleObject_Close(ole_obj, OLECLOSE_NOSAVE);
2010 IOleObject_SetClientSite(ole_obj, NULL);
2011 IOleObject_Release(ole_obj);
2012 }
2013 }
2014
2015 if(host->sink) {
2016 IConnectionPointContainer *cp_container;
2017 IConnectionPoint *cp;
2018
2019 assert(host->plugin_unk != NULL);
2020
2021 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IConnectionPointContainer, (void**)&cp_container);
2022 if(SUCCEEDED(hres)) {
2023 hres = IConnectionPointContainer_FindConnectionPoint(cp_container, &host->sink->iid, &cp);
2024 IConnectionPointContainer_Release(cp_container);
2025 if(SUCCEEDED(hres)) {
2026 IConnectionPoint_Unadvise(cp, host->sink->cookie);
2027 IConnectionPoint_Release(cp);
2028 }
2029 }
2030
2031 host->sink->host = NULL;
2032 IDispatch_Release(&host->sink->IDispatch_iface);
2033 host->sink = NULL;
2034 }
2035
2036 release_plugin_ifaces(host);
2037
2038 if(host->element) {
2039 host->element->plugin_host = NULL;
2040 host->element = NULL;
2041 }
2042
2043 list_remove(&host->entry);
2044 list_init(&host->entry);
2045 host->doc = NULL;
2046 }
2047
create_plugin_host(HTMLDocumentNode * doc,HTMLPluginContainer * container)2048 HRESULT create_plugin_host(HTMLDocumentNode *doc, HTMLPluginContainer *container)
2049 {
2050 PluginHost *host;
2051 IUnknown *unk;
2052 CLSID clsid;
2053
2054 assert(!container->plugin_host);
2055
2056 unk = create_activex_object(doc, container->element.nselem, &clsid);
2057 if(!unk)
2058 return E_FAIL;
2059
2060 host = heap_alloc_zero(sizeof(*host));
2061 if(!host) {
2062 IUnknown_Release(unk);
2063 return E_OUTOFMEMORY;
2064 }
2065
2066 host->IOleClientSite_iface.lpVtbl = &OleClientSiteVtbl;
2067 host->IAdviseSinkEx_iface.lpVtbl = &AdviseSinkExVtbl;
2068 host->IPropertyNotifySink_iface.lpVtbl = &PropertyNotifySinkVtbl;
2069 host->IDispatch_iface.lpVtbl = &DispatchVtbl;
2070 host->IOleInPlaceSiteEx_iface.lpVtbl = &OleInPlaceSiteExVtbl;
2071 host->IOleControlSite_iface.lpVtbl = &OleControlSiteVtbl;
2072 host->IBindHost_iface.lpVtbl = &BindHostVtbl;
2073 host->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
2074
2075 host->ref = 1;
2076
2077 host->plugin_unk = unk;
2078 host->clsid = clsid;
2079
2080 host->doc = doc;
2081 list_add_tail(&doc->plugin_hosts, &host->entry);
2082
2083 container->plugin_host = host;
2084 host->element = container;
2085
2086 initialize_plugin_object(host);
2087
2088 return S_OK;
2089 }
2090