d3dx10: Forward D3DX10CreateEffectFromFileA() to D3DX10CreateEffectFromFileW().
[wine.git] / dlls / mshtml / pluginhost.c
blobad67db5548c8f5667877c40167f46722633ff0e9
1 /*
2 * Copyright 2010 Jacek Caban for CodeWeavers
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.
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.
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
19 #include <stdarg.h>
21 #define COBJMACROS
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
27 #include "shlobj.h"
28 #include "mshtmdid.h"
30 #include "mshtml_private.h"
31 #include "pluginhost.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
37 typedef struct {
38 IPropertyBag IPropertyBag_iface;
39 IPropertyBag2 IPropertyBag2_iface;
41 LONG ref;
43 struct list props;
44 } PropertyBag;
46 typedef struct {
47 struct list entry;
48 WCHAR *name;
49 WCHAR *value;
50 } param_prop_t;
52 static void free_prop(param_prop_t *prop)
54 list_remove(&prop->entry);
56 heap_free(prop->name);
57 heap_free(prop->value);
58 heap_free(prop);
61 static param_prop_t *find_prop(PropertyBag *prop_bag, const WCHAR *name)
63 param_prop_t *iter;
65 LIST_FOR_EACH_ENTRY(iter, &prop_bag->props, param_prop_t, entry) {
66 if(!wcsicmp(iter->name, name))
67 return iter;
70 return NULL;
73 static HRESULT add_prop(PropertyBag *prop_bag, const WCHAR *name, const WCHAR *value)
75 param_prop_t *prop;
77 if(!name || !value)
78 return S_OK;
80 TRACE("%p %s %s\n", prop_bag, debugstr_w(name), debugstr_w(value));
82 prop = heap_alloc(sizeof(*prop));
83 if(!prop)
84 return E_OUTOFMEMORY;
86 prop->name = heap_strdupW(name);
87 prop->value = heap_strdupW(value);
88 if(!prop->name || !prop->value) {
89 list_init(&prop->entry);
90 free_prop(prop);
91 return E_OUTOFMEMORY;
94 list_add_tail(&prop_bag->props, &prop->entry);
95 return S_OK;
98 static inline PropertyBag *impl_from_IPropertyBag(IPropertyBag *iface)
100 return CONTAINING_RECORD(iface, PropertyBag, IPropertyBag_iface);
103 static HRESULT WINAPI PropertyBag_QueryInterface(IPropertyBag *iface, REFIID riid, void **ppv)
105 PropertyBag *This = impl_from_IPropertyBag(iface);
107 if(IsEqualGUID(&IID_IUnknown, riid)) {
108 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
109 *ppv = &This->IPropertyBag_iface;
110 }else if(IsEqualGUID(&IID_IPropertyBag, riid)) {
111 TRACE("(%p)->(IID_IPropertyBag %p)\n", This, ppv);
112 *ppv = &This->IPropertyBag_iface;
113 }else if(IsEqualGUID(&IID_IPropertyBag2, riid)) {
114 TRACE("(%p)->(IID_IPropertyBag2 %p)\n", This, ppv);
115 *ppv = &This->IPropertyBag2_iface;
116 }else {
117 WARN("Unsopported interface %s\n", debugstr_guid(riid));
118 *ppv = NULL;
119 return E_NOINTERFACE;
122 IUnknown_AddRef((IUnknown*)*ppv);
123 return S_OK;
126 static ULONG WINAPI PropertyBag_AddRef(IPropertyBag *iface)
128 PropertyBag *This = impl_from_IPropertyBag(iface);
129 LONG ref = InterlockedIncrement(&This->ref);
131 TRACE("(%p) ref=%d\n", This, ref);
133 return ref;
136 static ULONG WINAPI PropertyBag_Release(IPropertyBag *iface)
138 PropertyBag *This = impl_from_IPropertyBag(iface);
139 LONG ref = InterlockedDecrement(&This->ref);
141 TRACE("(%p) ref=%d\n", This, ref);
143 if(!ref) {
144 while(!list_empty(&This->props))
145 free_prop(LIST_ENTRY(This->props.next, param_prop_t, entry));
146 heap_free(This);
149 return ref;
152 static HRESULT WINAPI PropertyBag_Read(IPropertyBag *iface, LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog)
154 PropertyBag *This = impl_from_IPropertyBag(iface);
155 param_prop_t *prop;
156 VARIANT v;
158 TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog);
160 prop = find_prop(This, pszPropName);
161 if(!prop) {
162 TRACE("Not found\n");
163 return E_INVALIDARG;
166 V_BSTR(&v) = SysAllocString(prop->value);
167 if(!V_BSTR(&v))
168 return E_OUTOFMEMORY;
170 if(V_VT(pVar) != VT_BSTR) {
171 HRESULT hres;
173 V_VT(&v) = VT_BSTR;
174 hres = VariantChangeType(pVar, &v, 0, V_VT(pVar));
175 SysFreeString(V_BSTR(&v));
176 return hres;
179 V_BSTR(pVar) = V_BSTR(&v);
180 return S_OK;
183 static HRESULT WINAPI PropertyBag_Write(IPropertyBag *iface, LPCOLESTR pszPropName, VARIANT *pVar)
185 PropertyBag *This = impl_from_IPropertyBag(iface);
186 FIXME("(%p)->(%s %s)\n", This, debugstr_w(pszPropName), debugstr_variant(pVar));
187 return E_NOTIMPL;
190 static const IPropertyBagVtbl PropertyBagVtbl = {
191 PropertyBag_QueryInterface,
192 PropertyBag_AddRef,
193 PropertyBag_Release,
194 PropertyBag_Read,
195 PropertyBag_Write
198 static inline PropertyBag *impl_from_IPropertyBag2(IPropertyBag2 *iface)
200 return CONTAINING_RECORD(iface, PropertyBag, IPropertyBag2_iface);
203 static HRESULT WINAPI PropertyBag2_QueryInterface(IPropertyBag2 *iface, REFIID riid, void **ppv)
205 PropertyBag *This = impl_from_IPropertyBag2(iface);
206 return IPropertyBag_QueryInterface(&This->IPropertyBag_iface, riid, ppv);
209 static ULONG WINAPI PropertyBag2_AddRef(IPropertyBag2 *iface)
211 PropertyBag *This = impl_from_IPropertyBag2(iface);
212 return IPropertyBag_AddRef(&This->IPropertyBag_iface);
215 static ULONG WINAPI PropertyBag2_Release(IPropertyBag2 *iface)
217 PropertyBag *This = impl_from_IPropertyBag2(iface);
218 return IPropertyBag_Release(&This->IPropertyBag_iface);
221 static HRESULT WINAPI PropertyBag2_Read(IPropertyBag2 *iface, ULONG cProperties, PROPBAG2 *pPropBag,
222 IErrorLog *pErrLog, VARIANT *pvarValue, HRESULT *phrError)
224 PropertyBag *This = impl_from_IPropertyBag2(iface);
225 FIXME("(%p)->(%d %p %p %p %p)\n", This, cProperties, pPropBag, pErrLog, pvarValue, phrError);
226 return E_NOTIMPL;
229 static HRESULT WINAPI PropertyBag2_Write(IPropertyBag2 *iface, ULONG cProperties, PROPBAG2 *pPropBag, VARIANT *pvarValue)
231 PropertyBag *This = impl_from_IPropertyBag2(iface);
232 FIXME("(%p)->(%d %p %s)\n", This, cProperties, pPropBag, debugstr_variant(pvarValue));
233 return E_NOTIMPL;
236 static HRESULT WINAPI PropertyBag2_CountProperties(IPropertyBag2 *iface, ULONG *pcProperties)
238 PropertyBag *This = impl_from_IPropertyBag2(iface);
239 FIXME("(%p)->(%p)\n", This, pcProperties);
240 return E_NOTIMPL;
243 static HRESULT WINAPI PropertyBag2_GetPropertyInfo(IPropertyBag2 *iface, ULONG iProperty, ULONG cProperties,
244 PROPBAG2 *pPropBag, ULONG *pcProperties)
246 PropertyBag *This = impl_from_IPropertyBag2(iface);
247 FIXME("(%p)->(%u %u %p %p)\n", This, iProperty, cProperties, pPropBag, pcProperties);
248 return E_NOTIMPL;
251 static HRESULT WINAPI PropertyBag2_LoadObject(IPropertyBag2 *iface, LPCOLESTR pstrName, DWORD dwHint,
252 IUnknown *pUnkObject, IErrorLog *pErrLog)
254 PropertyBag *This = impl_from_IPropertyBag2(iface);
255 FIXME("(%p)->(%s %x %p %p)\n", This, debugstr_w(pstrName), dwHint, pUnkObject, pErrLog);
256 return E_NOTIMPL;
259 static const IPropertyBag2Vtbl PropertyBag2Vtbl = {
260 PropertyBag2_QueryInterface,
261 PropertyBag2_AddRef,
262 PropertyBag2_Release,
263 PropertyBag2_Read,
264 PropertyBag2_Write,
265 PropertyBag2_CountProperties,
266 PropertyBag2_GetPropertyInfo,
267 PropertyBag2_LoadObject
270 static HRESULT fill_props(nsIDOMElement *nselem, PropertyBag *prop_bag)
272 const PRUnichar *name, *value;
273 nsAString name_str, value_str;
274 nsIDOMHTMLCollection *params;
275 nsIDOMElement *param_elem;
276 UINT32 length, i;
277 nsIDOMNode *nsnode;
278 nsresult nsres;
279 HRESULT hres = S_OK;
281 nsAString_InitDepend(&name_str, L"param");
282 nsres = nsIDOMElement_GetElementsByTagName(nselem, &name_str, &params);
283 nsAString_Finish(&name_str);
284 if(NS_FAILED(nsres))
285 return E_FAIL;
287 nsres = nsIDOMHTMLCollection_GetLength(params, &length);
288 if(NS_FAILED(nsres))
289 length = 0;
291 for(i=0; i < length; i++) {
292 nsres = nsIDOMHTMLCollection_Item(params, i, &nsnode);
293 if(NS_FAILED(nsres)) {
294 hres = E_FAIL;
295 break;
298 nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMElement, (void**)&param_elem);
299 nsIDOMNode_Release(nsnode);
300 if(NS_FAILED(nsres)) {
301 hres = E_FAIL;
302 break;
305 nsres = get_elem_attr_value(param_elem, L"name", &name_str, &name);
306 if(NS_SUCCEEDED(nsres)) {
307 nsres = get_elem_attr_value(param_elem, L"value", &value_str, &value);
308 if(NS_SUCCEEDED(nsres)) {
309 hres = add_prop(prop_bag, name, value);
310 nsAString_Finish(&value_str);
313 nsAString_Finish(&name_str);
316 nsIDOMElement_Release(param_elem);
317 if(FAILED(hres))
318 break;
319 if(NS_FAILED(nsres)) {
320 hres = E_FAIL;
321 break;
325 nsIDOMHTMLCollection_Release(params);
326 return hres;
329 static HRESULT create_param_prop_bag(nsIDOMElement *nselem, IPropertyBag **ret)
331 PropertyBag *prop_bag;
332 HRESULT hres;
334 prop_bag = heap_alloc(sizeof(*prop_bag));
335 if(!prop_bag)
336 return E_OUTOFMEMORY;
338 prop_bag->IPropertyBag_iface.lpVtbl = &PropertyBagVtbl;
339 prop_bag->IPropertyBag2_iface.lpVtbl = &PropertyBag2Vtbl;
340 prop_bag->ref = 1;
342 list_init(&prop_bag->props);
343 hres = fill_props(nselem, prop_bag);
344 if(FAILED(hres) || list_empty(&prop_bag->props)) {
345 IPropertyBag_Release(&prop_bag->IPropertyBag_iface);
346 *ret = NULL;
347 return hres;
350 *ret = &prop_bag->IPropertyBag_iface;
351 return S_OK;
354 static BOOL check_load_safety(PluginHost *host)
356 DWORD policy_size, policy;
357 struct CONFIRMSAFETY cs;
358 BYTE *ppolicy;
359 HRESULT hres;
361 cs.clsid = host->clsid;
362 cs.pUnk = host->plugin_unk;
363 cs.dwFlags = CONFIRMSAFETYACTION_LOADOBJECT;
365 hres = IInternetHostSecurityManager_QueryCustomPolicy(&host->doc->IInternetHostSecurityManager_iface,
366 &GUID_CUSTOM_CONFIRMOBJECTSAFETY, &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
367 if(FAILED(hres))
368 return FALSE;
370 policy = *(DWORD*)ppolicy;
371 CoTaskMemFree(ppolicy);
372 return policy == URLPOLICY_ALLOW;
375 static BOOL check_script_safety(PluginHost *host)
377 DISPPARAMS params = {NULL,NULL,0,0};
378 DWORD policy_size, policy;
379 struct CONFIRMSAFETY cs;
380 BYTE *ppolicy;
381 ULONG err = 0;
382 VARIANT v;
383 HRESULT hres;
385 cs.clsid = host->clsid;
386 cs.pUnk = host->plugin_unk;
387 cs.dwFlags = 0;
389 hres = IInternetHostSecurityManager_QueryCustomPolicy(&host->doc->IInternetHostSecurityManager_iface,
390 &GUID_CUSTOM_CONFIRMOBJECTSAFETY, &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
391 if(FAILED(hres))
392 return FALSE;
394 policy = *(DWORD*)ppolicy;
395 CoTaskMemFree(ppolicy);
397 if(policy != URLPOLICY_ALLOW)
398 return FALSE;
400 V_VT(&v) = VT_EMPTY;
401 hres = IDispatch_Invoke(host->disp, DISPID_SECURITYCTX, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, &v, NULL, &err);
402 if(SUCCEEDED(hres)) {
403 FIXME("Handle security ctx %s\n", debugstr_variant(&v));
404 return FALSE;
407 return TRUE;
410 static void update_readystate(PluginHost *host)
412 DISPPARAMS params = {NULL,NULL,0,0};
413 IDispatchEx *dispex;
414 IDispatch *disp;
415 ULONG err = 0;
416 VARIANT v;
417 HRESULT hres;
419 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IDispatchEx, (void**)&dispex);
420 if(SUCCEEDED(hres)) {
421 FIXME("Use IDispatchEx\n");
422 IDispatchEx_Release(dispex);
425 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IDispatch, (void**)&disp);
426 if(FAILED(hres))
427 return;
429 hres = IDispatch_Invoke(disp, DISPID_READYSTATE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, &v, NULL, &err);
430 IDispatch_Release(disp);
431 if(SUCCEEDED(hres)) {
432 /* FIXME: make plugin readystate affect document readystate */
433 TRACE("readystate = %s\n", debugstr_variant(&v));
434 VariantClear(&v);
438 /* FIXME: We shouldn't need this function and we should embed plugin directly in the main document */
439 static void get_pos_rect(PluginHost *host, RECT *ret)
441 SetRect(ret, 0, 0, host->rect.right - host->rect.left, host->rect.bottom - host->rect.top);
444 static void load_prop_bag(PluginHost *host, IPersistPropertyBag *persist_prop_bag)
446 IPropertyBag *prop_bag;
447 HRESULT hres;
449 hres = create_param_prop_bag(host->element->element.dom_element, &prop_bag);
450 if(FAILED(hres))
451 return;
453 if(prop_bag && !check_load_safety(host)) {
454 IPropertyBag_Release(prop_bag);
455 prop_bag = NULL;
458 if(prop_bag) {
459 hres = IPersistPropertyBag_Load(persist_prop_bag, prop_bag, NULL);
460 IPropertyBag_Release(prop_bag);
461 if(FAILED(hres))
462 WARN("Load failed: %08x\n", hres);
463 }else {
464 hres = IPersistPropertyBag_InitNew(persist_prop_bag);
465 if(FAILED(hres))
466 WARN("InitNew failed: %08x\n", hres);
470 static void load_plugin(PluginHost *host)
472 IPersistPropertyBag2 *persist_prop_bag2;
473 IPersistPropertyBag *persist_prop_bag;
474 HRESULT hres;
476 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IPersistPropertyBag2, (void**)&persist_prop_bag2);
477 if(SUCCEEDED(hres)) {
478 FIXME("Use IPersistPropertyBag2 iface\n");
479 IPersistPropertyBag2_Release(persist_prop_bag2);
480 return;
483 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IPersistPropertyBag, (void**)&persist_prop_bag);
484 if(SUCCEEDED(hres)) {
485 load_prop_bag(host, persist_prop_bag);
486 IPersistPropertyBag_Release(persist_prop_bag);
487 return;
490 FIXME("No IPersistPropertyBag iface\n");
493 static void initialize_plugin_object(PluginHost *host)
495 IClientSecurity *client_security;
496 IQuickActivate *quick_activate;
497 IOleObject *ole_obj = NULL;
498 IOleCommandTarget *cmdtrg;
499 IViewObjectEx *view_obj;
500 IDispatchEx *dispex;
501 IDispatch *disp;
502 HRESULT hres;
504 /* Note native calls QI on plugin for an undocumented IID and CLSID_HTMLDocument */
506 /* FIXME: call FreezeEvents(TRUE) */
508 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IClientSecurity, (void**)&client_security);
509 if(SUCCEEDED(hres)) {
510 FIXME("Handle IClientSecurity\n");
511 IClientSecurity_Release(client_security);
512 return;
515 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IQuickActivate, (void**)&quick_activate);
516 if(SUCCEEDED(hres)) {
517 QACONTAINER container = {sizeof(container)};
518 QACONTROL control = {sizeof(control)};
520 TRACE("Using IQuickActivate\n");
522 container.pClientSite = &host->IOleClientSite_iface;
523 container.dwAmbientFlags = QACONTAINER_SUPPORTSMNEMONICS|QACONTAINER_MESSAGEREFLECT|QACONTAINER_USERMODE;
524 container.pAdviseSink = &host->IAdviseSinkEx_iface;
525 container.pPropertyNotifySink = &host->IPropertyNotifySink_iface;
527 hres = IQuickActivate_QuickActivate(quick_activate, &container, &control);
528 IQuickActivate_Release(quick_activate);
529 if(FAILED(hres))
530 FIXME("QuickActivate failed: %08x\n", hres);
531 }else {
532 DWORD status = 0;
534 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IOleObject, (void**)&ole_obj);
535 if(SUCCEEDED(hres)) {
536 hres = IOleObject_GetMiscStatus(ole_obj, DVASPECT_CONTENT, &status);
537 TRACE("GetMiscStatus returned %08x %x\n", hres, status);
539 hres = IOleObject_SetClientSite(ole_obj, &host->IOleClientSite_iface);
540 IOleObject_Release(ole_obj);
541 if(FAILED(hres)) {
542 FIXME("SetClientSite failed: %08x\n", hres);
543 return;
545 }else {
546 TRACE("Plugin does not support IOleObject\n");
550 load_plugin(host);
552 if(ole_obj) {
553 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IViewObjectEx, (void**)&view_obj);
554 if(SUCCEEDED(hres)) {
555 DWORD view_status = 0;
557 hres = IViewObjectEx_SetAdvise(view_obj, DVASPECT_CONTENT, 0, (IAdviseSink*)&host->IAdviseSinkEx_iface);
558 if(FAILED(hres))
559 WARN("SetAdvise failed: %08x\n", hres);
561 hres = IViewObjectEx_GetViewStatus(view_obj, &view_status);
562 IViewObjectEx_Release(view_obj);
563 TRACE("GetViewStatus returned %08x %x\n", hres, view_status);
567 update_readystate(host);
569 /* NOTE: Native QIs for IActiveScript, an undocumented IID, IOleControl and IRunnableObject */
571 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IDispatchEx, (void**)&dispex);
572 if(SUCCEEDED(hres)) {
573 FIXME("Use IDispatchEx\n");
574 host->disp = (IDispatch*)dispex;
575 }else {
576 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IDispatch, (void**)&disp);
577 if(SUCCEEDED(hres))
578 host->disp = disp;
579 else
580 TRACE("no IDispatch iface\n");
583 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
584 if(SUCCEEDED(hres)) {
585 FIXME("Use IOleCommandTarget\n");
586 IOleCommandTarget_Release(cmdtrg);
590 static void embed_plugin_object(PluginHost *host)
592 IOleObject *ole_obj;
593 RECT rect;
594 HRESULT hres;
596 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IOleObject, (void**)&ole_obj);
597 if(FAILED(hres)) {
598 FIXME("Plugin does not support IOleObject\n");
599 return;
602 get_pos_rect(host, &rect);
603 hres = IOleObject_DoVerb(ole_obj, OLEIVERB_INPLACEACTIVATE, NULL, &host->IOleClientSite_iface, 0, host->hwnd, &rect);
604 IOleObject_Release(ole_obj);
605 if(FAILED(hres))
606 WARN("DoVerb failed: %08x\n", hres);
608 if(host->ip_object) {
609 HWND hwnd;
611 hres = IOleInPlaceObject_GetWindow(host->ip_object, &hwnd);
612 if(SUCCEEDED(hres))
613 TRACE("hwnd %p\n", hwnd);
617 void update_plugin_window(PluginHost *host, HWND hwnd, const RECT *rect)
619 BOOL rect_changed = FALSE;
621 if(!hwnd || (host->hwnd && host->hwnd != hwnd)) {
622 FIXME("unhandled hwnd\n");
623 return;
626 TRACE("%p %s\n", hwnd, wine_dbgstr_rect(rect));
628 if(!EqualRect(rect, &host->rect)) {
629 host->rect = *rect;
630 rect_changed = TRUE;
633 if(!host->hwnd) {
634 host->hwnd = hwnd;
635 embed_plugin_object(host);
638 if(rect_changed && host->ip_object)
639 IOleInPlaceObject_SetObjectRects(host->ip_object, &host->rect, &host->rect);
642 static void notif_enabled(PluginHost *plugin_host)
644 DISPPARAMS args = {NULL, NULL, 0, 0};
645 IDispatch *disp;
646 ULONG err = 0;
647 VARIANT res;
648 HRESULT hres;
650 hres = IUnknown_QueryInterface(plugin_host->plugin_unk, &IID_IDispatch, (void**)&disp);
651 if(FAILED(hres)) {
652 FIXME("Could not get IDispatch iface: %08x\n", hres);
653 return;
656 V_VT(&res) = VT_EMPTY;
657 hres = IDispatch_Invoke(disp, DISPID_ENABLED, &IID_NULL, 0/*FIXME*/, DISPATCH_PROPERTYGET, &args, &res, NULL, &err);
658 IDispatch_Release(disp);
659 if(SUCCEEDED(hres)) {
660 FIXME("Got enabled %s\n", debugstr_variant(&res));
661 VariantClear(&res);
665 void notif_container_change(HTMLPluginContainer *plugin_container, DISPID dispid)
667 IOleControl *ole_control;
668 HRESULT hres;
670 if(!plugin_container->plugin_host || !plugin_container->plugin_host->plugin_unk)
671 return;
673 notif_enabled(plugin_container->plugin_host);
675 hres = IUnknown_QueryInterface(plugin_container->plugin_host->plugin_unk, &IID_IOleControl, (void**)&ole_control);
676 if(SUCCEEDED(hres)) {
677 IOleControl_OnAmbientPropertyChange(ole_control, dispid);
678 IOleControl_Release(ole_control);
682 HRESULT get_plugin_disp(HTMLPluginContainer *plugin_container, IDispatch **ret)
684 PluginHost *host;
686 host = plugin_container->plugin_host;
687 if(!host) {
688 ERR("No plugin host\n");
689 return E_UNEXPECTED;
692 if(!host->disp) {
693 *ret = NULL;
694 return S_OK;
697 if(!check_script_safety(host)) {
698 FIXME("Insecure object\n");
699 return E_FAIL;
702 IDispatch_AddRef(host->disp);
703 *ret = host->disp;
704 return S_OK;
707 HRESULT get_plugin_dispid(HTMLPluginContainer *plugin_container, WCHAR *name, DISPID *ret)
709 IDispatch *disp;
710 DISPID id;
711 DWORD i;
712 HRESULT hres;
714 if(!plugin_container->plugin_host) {
715 WARN("no plugin host\n");
716 return DISP_E_UNKNOWNNAME;
719 disp = plugin_container->plugin_host->disp;
720 if(!disp)
721 return DISP_E_UNKNOWNNAME;
723 hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, &id);
724 if(FAILED(hres)) {
725 TRACE("no prop %s\n", debugstr_w(name));
726 return DISP_E_UNKNOWNNAME;
729 for(i=0; i < plugin_container->props_len; i++) {
730 if(id == plugin_container->props[i]) {
731 *ret = MSHTML_DISPID_CUSTOM_MIN+i;
732 return S_OK;
736 if(!plugin_container->props) {
737 plugin_container->props = heap_alloc(8*sizeof(DISPID));
738 if(!plugin_container->props)
739 return E_OUTOFMEMORY;
740 plugin_container->props_size = 8;
741 }else if(plugin_container->props_len == plugin_container->props_size) {
742 DISPID *new_props;
744 new_props = heap_realloc(plugin_container->props, plugin_container->props_size*2*sizeof(DISPID));
745 if(!new_props)
746 return E_OUTOFMEMORY;
748 plugin_container->props = new_props;
749 plugin_container->props_size *= 2;
752 plugin_container->props[plugin_container->props_len] = id;
753 *ret = MSHTML_DISPID_CUSTOM_MIN+plugin_container->props_len;
754 plugin_container->props_len++;
755 return S_OK;
758 HRESULT invoke_plugin_prop(HTMLPluginContainer *plugin_container, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
759 VARIANT *res, EXCEPINFO *ei)
761 PluginHost *host;
763 host = plugin_container->plugin_host;
764 if(!host || !host->disp) {
765 FIXME("Called with no disp\n");
766 return E_UNEXPECTED;
769 if(!check_script_safety(host)) {
770 FIXME("Insecure object\n");
771 return E_FAIL;
774 if(id < MSHTML_DISPID_CUSTOM_MIN || id > MSHTML_DISPID_CUSTOM_MIN + plugin_container->props_len) {
775 ERR("Invalid id\n");
776 return E_FAIL;
779 return IDispatch_Invoke(host->disp, plugin_container->props[id-MSHTML_DISPID_CUSTOM_MIN], &IID_NULL,
780 lcid, flags, params, res, ei, NULL);
783 typedef struct {
784 DISPID id;
785 IDispatch *disp;
786 } sink_entry_t;
788 struct PHEventSink {
789 IDispatch IDispatch_iface;
791 LONG ref;
793 PluginHost *host;
794 ITypeInfo *typeinfo;
795 GUID iid;
796 DWORD cookie;
797 BOOL is_dispiface;
799 sink_entry_t *handlers;
800 DWORD handlers_cnt;
801 DWORD handlers_size;
804 static sink_entry_t *find_sink_entry(PHEventSink *sink, DISPID id)
806 sink_entry_t *iter;
808 for(iter = sink->handlers; iter < sink->handlers+sink->handlers_cnt; iter++) {
809 if(iter->id == id)
810 return iter;
813 return NULL;
816 static void add_sink_handler(PHEventSink *sink, DISPID id, IDispatch *disp)
818 sink_entry_t *entry = find_sink_entry(sink, id);
820 if(entry) {
821 if(entry->disp)
822 IDispatch_Release(entry->disp);
823 }else {
824 if(!sink->handlers_size) {
825 sink->handlers = heap_alloc(4*sizeof(*sink->handlers));
826 if(!sink->handlers)
827 return;
828 sink->handlers_size = 4;
829 }else if(sink->handlers_cnt == sink->handlers_size) {
830 sink_entry_t *new_handlers;
832 new_handlers = heap_realloc(sink->handlers, 2*sink->handlers_size*sizeof(*sink->handlers));
833 if(!new_handlers)
834 return;
835 sink->handlers = new_handlers;
836 sink->handlers_size *= 2;
838 entry = sink->handlers + sink->handlers_cnt++;
839 entry->id = id;
842 IDispatch_AddRef(disp);
843 entry->disp = disp;
846 static inline PHEventSink *PHEventSink_from_IDispatch(IDispatch *iface)
848 return CONTAINING_RECORD(iface, PHEventSink, IDispatch_iface);
851 static HRESULT WINAPI PHEventSink_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
853 PHEventSink *This = PHEventSink_from_IDispatch(iface);
855 if(IsEqualGUID(riid, &IID_IUnknown)) {
856 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
857 *ppv = &This->IDispatch_iface;
858 }else if(IsEqualGUID(riid, &IID_IDispatch)) {
859 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
860 *ppv = &This->IDispatch_iface;
861 }else if(This->is_dispiface && IsEqualGUID(riid, &This->iid)) {
862 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
863 *ppv = &This->IDispatch_iface;
864 }else {
865 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
866 *ppv = NULL;
867 return E_NOINTERFACE;
870 IUnknown_AddRef((IUnknown*)*ppv);
871 return S_OK;
874 static ULONG WINAPI PHEventSink_AddRef(IDispatch *iface)
876 PHEventSink *This = PHEventSink_from_IDispatch(iface);
877 LONG ref = InterlockedIncrement(&This->ref);
879 TRACE("(%p)\n", This);
881 return ref;
884 static ULONG WINAPI PHEventSink_Release(IDispatch *iface)
886 PHEventSink *This = PHEventSink_from_IDispatch(iface);
887 LONG ref = InterlockedDecrement(&This->ref);
889 TRACE("(%p)\n", This);
891 if(!ref) {
892 unsigned i;
894 assert(!This->host);
896 for(i=0; i < This->handlers_cnt; i++) {
897 if(This->handlers[i].disp)
898 IDispatch_Release(This->handlers[i].disp);
900 heap_free(This->handlers);
901 heap_free(This);
904 return ref;
907 static HRESULT WINAPI PHEventSink_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
909 PHEventSink *This = PHEventSink_from_IDispatch(iface);
910 FIXME("(%p)->(%p)\n", This, pctinfo);
911 return E_NOTIMPL;
914 static HRESULT WINAPI PHEventSink_GetTypeInfo(IDispatch *iface, UINT iTInfo,
915 LCID lcid, ITypeInfo **ppTInfo)
917 PHEventSink *This = PHEventSink_from_IDispatch(iface);
918 FIXME("(%p)->(%d %d %p)\n", This, iTInfo, lcid, ppTInfo);
919 return E_NOTIMPL;
922 static HRESULT WINAPI PHEventSink_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
923 UINT cNames, LCID lcid, DISPID *rgDispId)
925 PHEventSink *This = PHEventSink_from_IDispatch(iface);
926 FIXME("(%p)->(%s %p %u %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
927 return E_NOTIMPL;
930 static HRESULT WINAPI PHEventSink_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
931 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
933 PHEventSink *This = PHEventSink_from_IDispatch(iface);
934 IDispatchEx *dispex;
935 sink_entry_t *entry;
936 HRESULT hres;
938 TRACE("(%p)->(%d %s %d %x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), lcid, wFlags,
939 pDispParams, pVarResult, pExcepInfo, puArgErr);
941 if(!This->host) {
942 WARN("No host\n");
943 return E_UNEXPECTED;
946 entry = find_sink_entry(This, dispIdMember);
947 if(!entry || !entry->disp) {
948 WARN("No handler %d\n", dispIdMember);
949 if(pVarResult)
950 V_VT(pVarResult) = VT_EMPTY;
951 return S_OK;
954 hres = IDispatch_QueryInterface(entry->disp, &IID_IDispatchEx, (void**)&dispex);
956 TRACE("(%p) %d >>>\n", This, entry->id);
957 if(SUCCEEDED(hres)) {
958 hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, NULL);
959 IDispatchEx_Release(dispex);
960 }else {
961 hres = IDispatch_Invoke(entry->disp, DISPID_VALUE, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
963 if(SUCCEEDED(hres))
964 TRACE("(%p) %d <<<\n", This, entry->id);
965 else
966 WARN("(%p) %d <<< %08x\n", This, entry->id, hres);
967 return hres;
970 static const IDispatchVtbl PHCPDispatchVtbl = {
971 PHEventSink_QueryInterface,
972 PHEventSink_AddRef,
973 PHEventSink_Release,
974 PHEventSink_GetTypeInfoCount,
975 PHEventSink_GetTypeInfo,
976 PHEventSink_GetIDsOfNames,
977 PHEventSink_Invoke
980 static PHEventSink *create_event_sink(PluginHost *plugin_host, ITypeInfo *typeinfo)
982 IConnectionPointContainer *cp_container;
983 PHEventSink *ret;
984 IConnectionPoint *cp;
985 TYPEATTR *typeattr;
986 TYPEKIND typekind;
987 GUID guid;
988 HRESULT hres;
990 hres = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
991 if(FAILED(hres))
992 return NULL;
994 typekind = typeattr->typekind;
995 guid = typeattr->guid;
996 ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
998 TRACE("guid %s typekind %d\n", debugstr_guid(&guid), typekind);
1000 if(typekind != TKIND_INTERFACE && typekind != TKIND_DISPATCH) {
1001 WARN("invalid typekind %d\n", typekind);
1002 return NULL;
1005 hres = IUnknown_QueryInterface(plugin_host->plugin_unk, &IID_IConnectionPointContainer, (void**)&cp_container);
1006 if(FAILED(hres)) {
1007 WARN("Could not get IConnectionPointContainer iface: %08x\n", hres);
1008 return NULL;
1011 hres = IConnectionPointContainer_FindConnectionPoint(cp_container, &guid, &cp);
1012 IConnectionPointContainer_Release(cp_container);
1013 if(FAILED(hres)) {
1014 WARN("Could not find %s connection point\n", debugstr_guid(&guid));
1015 return NULL;
1018 ret = heap_alloc_zero(sizeof(*ret));
1019 if(ret) {
1020 ret->IDispatch_iface.lpVtbl = &PHCPDispatchVtbl;
1021 ret->ref = 1;
1022 ret->host = plugin_host;
1023 ret->iid = guid;
1024 ret->is_dispiface = typekind == TKIND_DISPATCH;
1026 ITypeInfo_AddRef(typeinfo);
1027 ret->typeinfo = typeinfo;
1029 hres = IConnectionPoint_Advise(cp, (IUnknown*)&ret->IDispatch_iface, &ret->cookie);
1030 }else {
1031 hres = E_OUTOFMEMORY;
1034 IConnectionPoint_Release(cp);
1035 if(FAILED(hres)) {
1036 WARN("Advise failed: %08x\n", hres);
1037 return NULL;
1040 return ret;
1043 static ITypeInfo *get_eventiface_info(HTMLPluginContainer *plugin_container, ITypeInfo *class_info)
1045 int impl_types, i, impl_flags;
1046 ITypeInfo *ret = NULL;
1047 TYPEATTR *typeattr;
1048 HREFTYPE ref;
1049 HRESULT hres;
1051 hres = ITypeInfo_GetTypeAttr(class_info, &typeattr);
1052 if(FAILED(hres))
1053 return NULL;
1055 if(typeattr->typekind != TKIND_COCLASS) {
1056 WARN("not coclass\n");
1057 ITypeInfo_ReleaseTypeAttr(class_info, typeattr);
1058 return NULL;
1061 impl_types = typeattr->cImplTypes;
1062 ITypeInfo_ReleaseTypeAttr(class_info, typeattr);
1064 for(i=0; i<impl_types; i++) {
1065 hres = ITypeInfo_GetImplTypeFlags(class_info, i, &impl_flags);
1066 if(FAILED(hres))
1067 continue;
1069 if((impl_flags & IMPLTYPEFLAG_FSOURCE)) {
1070 if(!(impl_flags & IMPLTYPEFLAG_FDEFAULT)) {
1071 FIXME("Handle non-default source iface\n");
1072 continue;
1075 hres = ITypeInfo_GetRefTypeOfImplType(class_info, i, &ref);
1076 if(FAILED(hres))
1077 continue;
1079 hres = ITypeInfo_GetRefTypeInfo(class_info, ref, &ret);
1080 if(FAILED(hres))
1081 ret = NULL;
1085 return ret;
1088 void bind_activex_event(HTMLDocumentNode *doc, HTMLPluginContainer *plugin_container, WCHAR *event, IDispatch *disp)
1090 PluginHost *plugin_host = plugin_container->plugin_host;
1091 ITypeInfo *class_info, *source_info;
1092 DISPID id;
1093 HRESULT hres;
1095 TRACE("(%p %p %s %p)\n", doc, plugin_host, debugstr_w(event), disp);
1097 if(!plugin_host || !plugin_host->plugin_unk) {
1098 WARN("detached element %p\n", plugin_host);
1099 return;
1102 if(plugin_host->sink) {
1103 source_info = plugin_host->sink->typeinfo;
1104 ITypeInfo_AddRef(source_info);
1105 }else {
1106 IProvideClassInfo *provide_ci;
1108 hres = IUnknown_QueryInterface(plugin_host->plugin_unk, &IID_IProvideClassInfo, (void**)&provide_ci);
1109 if(FAILED(hres)) {
1110 FIXME("No IProvideClassInfo, try GetTypeInfo?\n");
1111 return;
1114 hres = IProvideClassInfo_GetClassInfo(provide_ci, &class_info);
1115 IProvideClassInfo_Release(provide_ci);
1116 if(FAILED(hres) || !class_info) {
1117 WARN("GetClassInfo failed: %08x\n", hres);
1118 return;
1121 source_info = get_eventiface_info(plugin_container, class_info);
1122 ITypeInfo_Release(class_info);
1123 if(!source_info)
1124 return;
1127 hres = ITypeInfo_GetIDsOfNames(source_info, &event, 1, &id);
1128 if(FAILED(hres))
1129 WARN("Could not get disp id: %08x\n", hres);
1130 else if(!plugin_host->sink)
1131 plugin_host->sink = create_event_sink(plugin_host, source_info);
1133 ITypeInfo_Release(source_info);
1134 if(FAILED(hres) || !plugin_host->sink)
1135 return;
1137 add_sink_handler(plugin_host->sink, id, disp);
1140 typedef struct {
1141 IOleInPlaceFrame IOleInPlaceFrame_iface;
1142 LONG ref;
1143 } InPlaceFrame;
1145 static inline InPlaceFrame *impl_from_IOleInPlaceFrame(IOleInPlaceFrame *iface)
1147 return CONTAINING_RECORD(iface, InPlaceFrame, IOleInPlaceFrame_iface);
1150 static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface,
1151 REFIID riid, void **ppv)
1153 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1155 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
1157 if(IsEqualGUID(&IID_IUnknown, riid)) {
1158 *ppv = &This->IOleInPlaceFrame_iface;
1159 }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
1160 *ppv = &This->IOleInPlaceFrame_iface;
1161 }else if(IsEqualGUID(&IID_IOleInPlaceUIWindow, riid)) {
1162 *ppv = &This->IOleInPlaceFrame_iface;
1163 }else if(IsEqualGUID(&IID_IOleInPlaceFrame, riid)) {
1164 *ppv = &This->IOleInPlaceFrame_iface;
1165 }else {
1166 WARN("Unsopported interface %s\n", debugstr_mshtml_guid(riid));
1167 *ppv = NULL;
1168 return E_NOINTERFACE;
1171 IUnknown_AddRef((IUnknown*)*ppv);
1172 return S_OK;
1175 static ULONG WINAPI InPlaceFrame_AddRef(IOleInPlaceFrame *iface)
1177 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1178 LONG ref = InterlockedIncrement(&This->ref);
1180 TRACE("(%p) ref=%d\n", This, ref);
1182 return ref;
1185 static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface)
1187 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1188 LONG ref = InterlockedDecrement(&This->ref);
1190 TRACE("(%p) ref=%d\n", This, ref);
1192 if(!ref)
1193 heap_free(This);
1195 return ref;
1198 static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd)
1200 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1201 FIXME("(%p)->(%p)\n", This, phwnd);
1202 return E_NOTIMPL;
1205 static HRESULT WINAPI InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface,
1206 BOOL fEnterMode)
1208 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1209 FIXME("(%p)->(%x)\n", This, fEnterMode);
1210 return E_NOTIMPL;
1213 static HRESULT WINAPI InPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
1215 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1216 FIXME("(%p)->(%p)\n", This, lprectBorder);
1217 return E_NOTIMPL;
1220 static HRESULT WINAPI InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface,
1221 LPCBORDERWIDTHS pborderwidths)
1223 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1224 FIXME("(%p)->(%p)\n", This, pborderwidths);
1225 return E_NOTIMPL;
1228 static HRESULT WINAPI InPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface,
1229 LPCBORDERWIDTHS pborderwidths)
1231 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1232 FIXME("(%p)->(%p)\n", This, pborderwidths);
1233 return E_NOTIMPL;
1236 static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface,
1237 IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
1239 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1240 FIXME("(%p)->(%p %s)\n", This, pActiveObject, debugstr_w(pszObjName));
1241 return E_NOTIMPL;
1244 static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared,
1245 LPOLEMENUGROUPWIDTHS lpMenuWidths)
1247 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1248 FIXME("(%p)->(%p %p)\n", This, hmenuShared, lpMenuWidths);
1249 return E_NOTIMPL;
1252 static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared,
1253 HOLEMENU holemenu, HWND hwndActiveObject)
1255 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1256 FIXME("(%p)->(%p %p %p)\n", This, hmenuShared, holemenu, hwndActiveObject);
1257 return E_NOTIMPL;
1260 static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
1262 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1263 FIXME("(%p)->(%p)\n", This, hmenuShared);
1264 return E_NOTIMPL;
1267 static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface,
1268 LPCOLESTR pszStatusText)
1270 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1271 FIXME("(%p)->(%s)\n", This, debugstr_w(pszStatusText));
1272 return E_NOTIMPL;
1275 static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
1277 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1278 FIXME("(%p)->(%x)\n", This, fEnable);
1279 return E_NOTIMPL;
1282 static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg,
1283 WORD wID)
1285 InPlaceFrame *This = impl_from_IOleInPlaceFrame(iface);
1286 FIXME("(%p)->(%p %d)\n", This, lpmsg, wID);
1287 return E_NOTIMPL;
1290 static const IOleInPlaceFrameVtbl OleInPlaceFrameVtbl = {
1291 InPlaceFrame_QueryInterface,
1292 InPlaceFrame_AddRef,
1293 InPlaceFrame_Release,
1294 InPlaceFrame_GetWindow,
1295 InPlaceFrame_ContextSensitiveHelp,
1296 InPlaceFrame_GetBorder,
1297 InPlaceFrame_RequestBorderSpace,
1298 InPlaceFrame_SetBorderSpace,
1299 InPlaceFrame_SetActiveObject,
1300 InPlaceFrame_InsertMenus,
1301 InPlaceFrame_SetMenu,
1302 InPlaceFrame_RemoveMenus,
1303 InPlaceFrame_SetStatusText,
1304 InPlaceFrame_EnableModeless,
1305 InPlaceFrame_TranslateAccelerator
1308 static HRESULT create_ip_frame(IOleInPlaceFrame **ret)
1310 InPlaceFrame *frame;
1312 frame = heap_alloc_zero(sizeof(*frame));
1313 if(!frame)
1314 return E_OUTOFMEMORY;
1316 frame->IOleInPlaceFrame_iface.lpVtbl = &OleInPlaceFrameVtbl;
1317 frame->ref = 1;
1319 *ret = &frame->IOleInPlaceFrame_iface;
1320 return S_OK;
1323 typedef struct {
1324 IOleInPlaceUIWindow IOleInPlaceUIWindow_iface;
1325 LONG ref;
1326 } InPlaceUIWindow;
1328 static inline InPlaceUIWindow *impl_from_IOleInPlaceUIWindow(IOleInPlaceUIWindow *iface)
1330 return CONTAINING_RECORD(iface, InPlaceUIWindow, IOleInPlaceUIWindow_iface);
1333 static HRESULT WINAPI InPlaceUIWindow_QueryInterface(IOleInPlaceUIWindow *iface, REFIID riid, void **ppv)
1335 InPlaceUIWindow *This = impl_from_IOleInPlaceUIWindow(iface);
1337 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
1339 if(IsEqualGUID(&IID_IUnknown, riid)) {
1340 *ppv = &This->IOleInPlaceUIWindow_iface;
1341 }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
1342 *ppv = &This->IOleInPlaceUIWindow_iface;
1343 }else if(IsEqualGUID(&IID_IOleInPlaceUIWindow, riid)) {
1344 *ppv = &This->IOleInPlaceUIWindow_iface;
1345 }else {
1346 WARN("Unsopported interface %s\n", debugstr_mshtml_guid(riid));
1347 *ppv = NULL;
1348 return E_NOINTERFACE;
1351 IUnknown_AddRef((IUnknown*)*ppv);
1352 return S_OK;
1355 static ULONG WINAPI InPlaceUIWindow_AddRef(IOleInPlaceUIWindow *iface)
1357 InPlaceUIWindow *This = impl_from_IOleInPlaceUIWindow(iface);
1358 LONG ref = InterlockedIncrement(&This->ref);
1360 TRACE("(%p) ref=%d\n", This, ref);
1362 return ref;
1365 static ULONG WINAPI InPlaceUIWindow_Release(IOleInPlaceUIWindow *iface)
1367 InPlaceUIWindow *This = impl_from_IOleInPlaceUIWindow(iface);
1368 LONG ref = InterlockedDecrement(&This->ref);
1370 TRACE("(%p) ref=%d\n", This, ref);
1372 if(!ref)
1373 heap_free(This);
1375 return ref;
1378 static HRESULT WINAPI InPlaceUIWindow_GetWindow(IOleInPlaceUIWindow *iface, HWND *phwnd)
1380 InPlaceUIWindow *This = impl_from_IOleInPlaceUIWindow(iface);
1381 FIXME("(%p)->(%p)\n", This, phwnd);
1382 return E_NOTIMPL;
1385 static HRESULT WINAPI InPlaceUIWindow_ContextSensitiveHelp(IOleInPlaceUIWindow *iface,
1386 BOOL fEnterMode)
1388 InPlaceUIWindow *This = impl_from_IOleInPlaceUIWindow(iface);
1389 FIXME("(%p)->(%x)\n", This, fEnterMode);
1390 return E_NOTIMPL;
1393 static HRESULT WINAPI InPlaceUIWindow_GetBorder(IOleInPlaceUIWindow *iface, LPRECT lprectBorder)
1395 InPlaceUIWindow *This = impl_from_IOleInPlaceUIWindow(iface);
1396 FIXME("(%p)->(%p)\n", This, lprectBorder);
1397 return E_NOTIMPL;
1400 static HRESULT WINAPI InPlaceUIWindow_RequestBorderSpace(IOleInPlaceUIWindow *iface,
1401 LPCBORDERWIDTHS pborderwidths)
1403 InPlaceUIWindow *This = impl_from_IOleInPlaceUIWindow(iface);
1404 FIXME("(%p)->(%p)\n", This, pborderwidths);
1405 return E_NOTIMPL;
1408 static HRESULT WINAPI InPlaceUIWindow_SetBorderSpace(IOleInPlaceUIWindow *iface,
1409 LPCBORDERWIDTHS pborderwidths)
1411 InPlaceUIWindow *This = impl_from_IOleInPlaceUIWindow(iface);
1412 FIXME("(%p)->(%p)\n", This, pborderwidths);
1413 return E_NOTIMPL;
1416 static HRESULT WINAPI InPlaceUIWindow_SetActiveObject(IOleInPlaceUIWindow *iface,
1417 IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
1419 InPlaceUIWindow *This = impl_from_IOleInPlaceUIWindow(iface);
1420 FIXME("(%p)->(%p %s)\n", This, pActiveObject, debugstr_w(pszObjName));
1421 return E_NOTIMPL;
1424 static const IOleInPlaceUIWindowVtbl OleInPlaceUIWindowVtbl = {
1425 InPlaceUIWindow_QueryInterface,
1426 InPlaceUIWindow_AddRef,
1427 InPlaceUIWindow_Release,
1428 InPlaceUIWindow_GetWindow,
1429 InPlaceUIWindow_ContextSensitiveHelp,
1430 InPlaceUIWindow_GetBorder,
1431 InPlaceUIWindow_RequestBorderSpace,
1432 InPlaceUIWindow_SetBorderSpace,
1433 InPlaceUIWindow_SetActiveObject,
1436 static HRESULT create_ip_window(IOleInPlaceUIWindow **ret)
1438 InPlaceUIWindow *uiwindow;
1440 uiwindow = heap_alloc_zero(sizeof(*uiwindow));
1441 if(!uiwindow)
1442 return E_OUTOFMEMORY;
1444 uiwindow->IOleInPlaceUIWindow_iface.lpVtbl = &OleInPlaceUIWindowVtbl;
1445 uiwindow->ref = 1;
1447 *ret = &uiwindow->IOleInPlaceUIWindow_iface;
1448 return S_OK;
1451 static inline PluginHost *impl_from_IOleClientSite(IOleClientSite *iface)
1453 return CONTAINING_RECORD(iface, PluginHost, IOleClientSite_iface);
1456 static HRESULT WINAPI PHClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
1458 PluginHost *This = impl_from_IOleClientSite(iface);
1460 if(IsEqualGUID(&IID_IUnknown, riid)) {
1461 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
1462 *ppv = &This->IOleClientSite_iface;
1463 }else if(IsEqualGUID(&IID_IOleClientSite, riid)) {
1464 TRACE("(%p)->(IID_IOleClientSite %p)\n", This, ppv);
1465 *ppv = &This->IOleClientSite_iface;
1466 }else if(IsEqualGUID(&IID_IAdviseSink, riid)) {
1467 TRACE("(%p)->(IID_IAdviseSink %p)\n", This, ppv);
1468 *ppv = &This->IAdviseSinkEx_iface;
1469 }else if(IsEqualGUID(&IID_IAdviseSinkEx, riid)) {
1470 TRACE("(%p)->(IID_IAdviseSinkEx %p)\n", This, ppv);
1471 *ppv = &This->IAdviseSinkEx_iface;
1472 }else if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
1473 TRACE("(%p)->(IID_IPropertyNotifySink %p)\n", This, ppv);
1474 *ppv = &This->IPropertyNotifySink_iface;
1475 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1476 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
1477 *ppv = &This->IDispatch_iface;
1478 }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
1479 TRACE("(%p)->(IID_IOleWindow %p)\n", This, ppv);
1480 *ppv = &This->IOleInPlaceSiteEx_iface;
1481 }else if(IsEqualGUID(&IID_IOleInPlaceSite, riid)) {
1482 TRACE("(%p)->(IID_IOleInPlaceSite %p)\n", This, ppv);
1483 *ppv = &This->IOleInPlaceSiteEx_iface;
1484 }else if(IsEqualGUID(&IID_IOleInPlaceSiteEx, riid)) {
1485 TRACE("(%p)->(IID_IOleInPlaceSiteEx %p)\n", This, ppv);
1486 *ppv = &This->IOleInPlaceSiteEx_iface;
1487 }else if(IsEqualGUID(&IID_IOleControlSite, riid)) {
1488 TRACE("(%p)->(IID_IOleControlSite %p)\n", This, ppv);
1489 *ppv = &This->IOleControlSite_iface;
1490 }else if(IsEqualGUID(&IID_IBindHost, riid)) {
1491 TRACE("(%p)->(IID_IBindHost %p)\n", This, ppv);
1492 *ppv = &This->IBindHost_iface;
1493 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
1494 TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
1495 *ppv = &This->IServiceProvider_iface;
1496 }else {
1497 WARN("Unsupported interface %s\n", debugstr_guid(riid));
1498 *ppv = NULL;
1499 return E_NOINTERFACE;
1502 IUnknown_AddRef((IUnknown*)*ppv);
1503 return S_OK;
1506 static ULONG WINAPI PHClientSite_AddRef(IOleClientSite *iface)
1508 PluginHost *This = impl_from_IOleClientSite(iface);
1509 LONG ref = InterlockedIncrement(&This->ref);
1511 TRACE("(%p) ref=%d\n", This, ref);
1513 return ref;
1516 static void release_plugin_ifaces(PluginHost *This)
1518 if(This->disp) {
1519 IDispatch_Release(This->disp);
1520 This->disp = NULL;
1523 if(This->ip_object) {
1524 IOleInPlaceObject_Release(This->ip_object);
1525 This->ip_object = NULL;
1528 if(This->plugin_unk) {
1529 IUnknown *unk = This->plugin_unk;
1530 LONG ref;
1532 This->plugin_unk = NULL;
1533 ref = IUnknown_Release(unk);
1535 TRACE("plugin ref = %d\n", ref);
1539 static ULONG WINAPI PHClientSite_Release(IOleClientSite *iface)
1541 PluginHost *This = impl_from_IOleClientSite(iface);
1542 LONG ref = InterlockedDecrement(&This->ref);
1544 TRACE("(%p) ref=%d\n", This, ref);
1546 if(!ref) {
1547 release_plugin_ifaces(This);
1548 if(This->sink) {
1549 This->sink->host = NULL;
1550 IDispatch_Release(&This->sink->IDispatch_iface);
1551 This->sink = NULL;
1553 list_remove(&This->entry);
1554 if(This->element)
1555 This->element->plugin_host = NULL;
1556 heap_free(This);
1559 return ref;
1562 static HRESULT WINAPI PHClientSite_SaveObject(IOleClientSite *iface)
1564 PluginHost *This = impl_from_IOleClientSite(iface);
1565 FIXME("(%p)\n", This);
1566 return E_NOTIMPL;
1569 static HRESULT WINAPI PHClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign,
1570 DWORD dwWhichMoniker, IMoniker **ppmk)
1572 PluginHost *This = impl_from_IOleClientSite(iface);
1574 TRACE("(%p)->(%d %d %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
1576 switch(dwWhichMoniker) {
1577 case OLEWHICHMK_CONTAINER:
1578 if(!This->doc || !This->doc->window || !This->doc->window->mon) {
1579 FIXME("no moniker\n");
1580 return E_UNEXPECTED;
1583 *ppmk = This->doc->window->mon;
1584 IMoniker_AddRef(*ppmk);
1585 break;
1586 default:
1587 FIXME("which %d\n", dwWhichMoniker);
1588 return E_NOTIMPL;
1591 return S_OK;
1594 static HRESULT WINAPI PHClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
1596 PluginHost *This = impl_from_IOleClientSite(iface);
1598 TRACE("(%p)->(%p)\n", This, ppContainer);
1600 if(!This->doc) {
1601 ERR("Called on detached object\n");
1602 return E_UNEXPECTED;
1605 *ppContainer = &This->doc->basedoc.IOleContainer_iface;
1606 IOleContainer_AddRef(*ppContainer);
1607 return S_OK;
1610 static HRESULT WINAPI PHClientSite_ShowObject(IOleClientSite *iface)
1612 PluginHost *This = impl_from_IOleClientSite(iface);
1614 TRACE("(%p)\n", This);
1616 return S_OK;
1619 static HRESULT WINAPI PHClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
1621 PluginHost *This = impl_from_IOleClientSite(iface);
1622 FIXME("(%p)->(%x)\n", This, fShow);
1623 return E_NOTIMPL;
1626 static HRESULT WINAPI PHClientSite_RequestNewObjectLayout(IOleClientSite *iface)
1628 PluginHost *This = impl_from_IOleClientSite(iface);
1629 FIXME("(%p)\n", This);
1630 return E_NOTIMPL;
1633 static const IOleClientSiteVtbl OleClientSiteVtbl = {
1634 PHClientSite_QueryInterface,
1635 PHClientSite_AddRef,
1636 PHClientSite_Release,
1637 PHClientSite_SaveObject,
1638 PHClientSite_GetMoniker,
1639 PHClientSite_GetContainer,
1640 PHClientSite_ShowObject,
1641 PHClientSite_OnShowWindow,
1642 PHClientSite_RequestNewObjectLayout
1645 static inline PluginHost *impl_from_IAdviseSinkEx(IAdviseSinkEx *iface)
1647 return CONTAINING_RECORD(iface, PluginHost, IAdviseSinkEx_iface);
1650 static HRESULT WINAPI PHAdviseSinkEx_QueryInterface(IAdviseSinkEx *iface, REFIID riid, void **ppv)
1652 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1653 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
1656 static ULONG WINAPI PHAdviseSinkEx_AddRef(IAdviseSinkEx *iface)
1658 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1659 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1662 static ULONG WINAPI PHAdviseSinkEx_Release(IAdviseSinkEx *iface)
1664 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1665 return IOleClientSite_Release(&This->IOleClientSite_iface);
1668 static void WINAPI PHAdviseSinkEx_OnDataChange(IAdviseSinkEx *iface, FORMATETC *pFormatetc, STGMEDIUM *pStgMedium)
1670 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1671 FIXME("(%p)->(%p %p)\n", This, pFormatetc, pStgMedium);
1674 static void WINAPI PHAdviseSinkEx_OnViewChange(IAdviseSinkEx *iface, DWORD dwAspect, LONG lindex)
1676 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1677 FIXME("(%p)->(%d %d)\n", This, dwAspect, lindex);
1680 static void WINAPI PHAdviseSinkEx_OnRename(IAdviseSinkEx *iface, IMoniker *pmk)
1682 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1683 FIXME("(%p)->(%p)\n", This, pmk);
1686 static void WINAPI PHAdviseSinkEx_OnSave(IAdviseSinkEx *iface)
1688 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1689 FIXME("(%p)\n", This);
1692 static void WINAPI PHAdviseSinkEx_OnClose(IAdviseSinkEx *iface)
1694 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1695 FIXME("(%p)\n", This);
1698 static void WINAPI PHAdviseSinkEx_OnViewStatusChange(IAdviseSinkEx *iface, DWORD dwViewStatus)
1700 PluginHost *This = impl_from_IAdviseSinkEx(iface);
1701 FIXME("(%p)->(%d)\n", This, dwViewStatus);
1704 static const IAdviseSinkExVtbl AdviseSinkExVtbl = {
1705 PHAdviseSinkEx_QueryInterface,
1706 PHAdviseSinkEx_AddRef,
1707 PHAdviseSinkEx_Release,
1708 PHAdviseSinkEx_OnDataChange,
1709 PHAdviseSinkEx_OnViewChange,
1710 PHAdviseSinkEx_OnRename,
1711 PHAdviseSinkEx_OnSave,
1712 PHAdviseSinkEx_OnClose,
1713 PHAdviseSinkEx_OnViewStatusChange
1716 static inline PluginHost *impl_from_IPropertyNotifySink(IPropertyNotifySink *iface)
1718 return CONTAINING_RECORD(iface, PluginHost, IPropertyNotifySink_iface);
1721 static HRESULT WINAPI PHPropertyNotifySink_QueryInterface(IPropertyNotifySink *iface, REFIID riid, void **ppv)
1723 PluginHost *This = impl_from_IPropertyNotifySink(iface);
1724 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
1727 static ULONG WINAPI PHPropertyNotifySink_AddRef(IPropertyNotifySink *iface)
1729 PluginHost *This = impl_from_IPropertyNotifySink(iface);
1730 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1733 static ULONG WINAPI PHPropertyNotifySink_Release(IPropertyNotifySink *iface)
1735 PluginHost *This = impl_from_IPropertyNotifySink(iface);
1736 return IOleClientSite_Release(&This->IOleClientSite_iface);
1739 static HRESULT WINAPI PHPropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
1741 PluginHost *This = impl_from_IPropertyNotifySink(iface);
1743 TRACE("(%p)->(%d)\n", This, dispID);
1745 switch(dispID) {
1746 case DISPID_READYSTATE:
1747 update_readystate(This);
1748 break;
1749 default :
1750 FIXME("Unimplemented dispID %d\n", dispID);
1751 return E_NOTIMPL;
1754 return S_OK;
1757 static HRESULT WINAPI PHPropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
1759 PluginHost *This = impl_from_IPropertyNotifySink(iface);
1760 FIXME("(%p)->(%d)\n", This, dispID);
1761 return E_NOTIMPL;
1764 static const IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
1765 PHPropertyNotifySink_QueryInterface,
1766 PHPropertyNotifySink_AddRef,
1767 PHPropertyNotifySink_Release,
1768 PHPropertyNotifySink_OnChanged,
1769 PHPropertyNotifySink_OnRequestEdit
1772 static inline PluginHost *impl_from_IDispatch(IDispatch *iface)
1774 return CONTAINING_RECORD(iface, PluginHost, IDispatch_iface);
1777 static HRESULT WINAPI PHDispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
1779 PluginHost *This = impl_from_IDispatch(iface);
1780 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
1783 static ULONG WINAPI PHDispatch_AddRef(IDispatch *iface)
1785 PluginHost *This = impl_from_IDispatch(iface);
1786 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1789 static ULONG WINAPI PHDispatch_Release(IDispatch *iface)
1791 PluginHost *This = impl_from_IDispatch(iface);
1792 return IOleClientSite_Release(&This->IOleClientSite_iface);
1795 static HRESULT WINAPI PHDispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
1797 PluginHost *This = impl_from_IDispatch(iface);
1798 FIXME("(%p)->(%p)\n", This, pctinfo);
1799 return E_NOTIMPL;
1802 static HRESULT WINAPI PHDispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo,
1803 LCID lcid, ITypeInfo **ppTInfo)
1805 PluginHost *This = impl_from_IDispatch(iface);
1806 FIXME("(%p)->(%d %d %p)\n", This, iTInfo, lcid, ppTInfo);
1807 return E_NOTIMPL;
1810 static HRESULT WINAPI PHDispatch_GetIDsOfNames(IDispatch *iface, REFIID riid,
1811 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1813 PluginHost *This = impl_from_IDispatch(iface);
1814 FIXME("(%p)->(%s %p %d %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
1815 return E_NOTIMPL;
1818 static HRESULT WINAPI PHDispatch_Invoke(IDispatch *iface, DISPID dispid, REFIID riid, LCID lcid,
1819 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1821 PluginHost *This = impl_from_IDispatch(iface);
1822 FIXME("(%p)->(%d %x %p %p)\n", This, dispid, wFlags, pDispParams, pVarResult);
1823 return E_NOTIMPL;
1826 static const IDispatchVtbl DispatchVtbl = {
1827 PHDispatch_QueryInterface,
1828 PHDispatch_AddRef,
1829 PHDispatch_Release,
1830 PHDispatch_GetTypeInfoCount,
1831 PHDispatch_GetTypeInfo,
1832 PHDispatch_GetIDsOfNames,
1833 PHDispatch_Invoke
1836 static inline PluginHost *impl_from_IOleInPlaceSiteEx(IOleInPlaceSiteEx *iface)
1838 return CONTAINING_RECORD(iface, PluginHost, IOleInPlaceSiteEx_iface);
1841 static HRESULT WINAPI PHInPlaceSite_QueryInterface(IOleInPlaceSiteEx *iface, REFIID riid, void **ppv)
1843 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1844 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
1847 static ULONG WINAPI PHInPlaceSite_AddRef(IOleInPlaceSiteEx *iface)
1849 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1850 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1853 static ULONG WINAPI PHInPlaceSite_Release(IOleInPlaceSiteEx *iface)
1855 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1856 return IOleClientSite_Release(&This->IOleClientSite_iface);
1859 static HRESULT WINAPI PHInPlaceSite_GetWindow(IOleInPlaceSiteEx *iface, HWND *phwnd)
1861 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1863 TRACE("(%p)->(%p)\n", This, phwnd);
1865 *phwnd = This->hwnd;
1866 return S_OK;
1869 static HRESULT WINAPI PHInPlaceSite_ContextSensitiveHelp(IOleInPlaceSiteEx *iface, BOOL fEnterMode)
1871 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1872 FIXME("(%p)->(%x)\n", This, fEnterMode);
1873 return E_NOTIMPL;
1876 static HRESULT WINAPI PHInPlaceSite_CanInPlaceActivate(IOleInPlaceSiteEx *iface)
1878 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1880 TRACE("(%p)\n", This);
1882 return S_OK;
1885 static HRESULT WINAPI PHInPlaceSite_OnInPlaceActivate(IOleInPlaceSiteEx *iface)
1887 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1888 FIXME("(%p)\n", This);
1889 return E_NOTIMPL;
1892 static HRESULT WINAPI PHInPlaceSite_OnUIActivate(IOleInPlaceSiteEx *iface)
1894 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1896 TRACE("(%p)\n", This);
1898 if(!This->plugin_unk) {
1899 ERR("No plugin object\n");
1900 return E_UNEXPECTED;
1903 This->ui_active = TRUE;
1905 notif_enabled(This);
1906 return S_OK;
1909 static HRESULT WINAPI PHInPlaceSite_GetWindowContext(IOleInPlaceSiteEx *iface,
1910 IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, RECT *lprcPosRect,
1911 RECT *lprcClipRect, OLEINPLACEFRAMEINFO *frame_info)
1913 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1914 IOleInPlaceUIWindow *ip_window;
1915 IOleInPlaceFrame *ip_frame;
1916 RECT pr, cr;
1917 HRESULT hres;
1919 TRACE("(%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, frame_info);
1921 if(!This->doc || !This->doc->basedoc.doc_obj || !This->doc->basedoc.doc_obj->ipsite) {
1922 FIXME("No ipsite\n");
1923 return E_UNEXPECTED;
1926 hres = IOleInPlaceSite_GetWindowContext(This->doc->basedoc.doc_obj->ipsite, &ip_frame, &ip_window, &pr, &cr, frame_info);
1927 if(FAILED(hres)) {
1928 WARN("GetWindowContext failed: %08x\n", hres);
1929 return hres;
1932 if(ip_window)
1933 IOleInPlaceUIWindow_Release(ip_window);
1934 if(ip_frame)
1935 IOleInPlaceFrame_Release(ip_frame);
1937 hres = create_ip_frame(&ip_frame);
1938 if(FAILED(hres))
1939 return hres;
1941 hres = create_ip_window(ppDoc);
1942 if(FAILED(hres)) {
1943 IOleInPlaceFrame_Release(ip_frame);
1944 return hres;
1947 *ppFrame = ip_frame;
1948 *lprcPosRect = This->rect;
1949 *lprcClipRect = This->rect;
1950 return S_OK;
1953 static HRESULT WINAPI PHInPlaceSite_Scroll(IOleInPlaceSiteEx *iface, SIZE scrollExtent)
1955 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1956 FIXME("(%p)->({%d %d})\n", This, scrollExtent.cx, scrollExtent.cy);
1957 return E_NOTIMPL;
1960 static HRESULT WINAPI PHInPlaceSite_OnUIDeactivate(IOleInPlaceSiteEx *iface, BOOL fUndoable)
1962 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1963 FIXME("(%p)->(%x)\n", This, fUndoable);
1964 return E_NOTIMPL;
1967 static HRESULT WINAPI PHInPlaceSite_OnInPlaceDeactivate(IOleInPlaceSiteEx *iface)
1969 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1971 TRACE("(%p)\n", This);
1973 if(This->ip_object) {
1974 IOleInPlaceObject_Release(This->ip_object);
1975 This->ip_object = NULL;
1978 return S_OK;
1981 static HRESULT WINAPI PHInPlaceSite_DiscardUndoState(IOleInPlaceSiteEx *iface)
1983 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1984 FIXME("(%p)\n", This);
1985 return E_NOTIMPL;
1988 static HRESULT WINAPI PHInPlaceSite_DeactivateAndUndo(IOleInPlaceSiteEx *iface)
1990 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1991 FIXME("(%p)\n", This);
1992 return E_NOTIMPL;
1995 static HRESULT WINAPI PHInPlaceSite_OnPosRectChange(IOleInPlaceSiteEx *iface, LPCRECT lprcPosRect)
1997 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
1998 FIXME("(%p)->(%p)\n", This, lprcPosRect);
1999 return E_NOTIMPL;
2002 static HRESULT WINAPI PHInPlaceSiteEx_OnInPlaceActivateEx(IOleInPlaceSiteEx *iface, BOOL *pfNoRedraw, DWORD dwFlags)
2004 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
2005 HWND hwnd;
2006 HRESULT hres;
2008 TRACE("(%p)->(%p %x)\n", This, pfNoRedraw, dwFlags);
2010 if(This->ip_object)
2011 return S_OK;
2013 hres = IUnknown_QueryInterface(This->plugin_unk, &IID_IOleInPlaceObject, (void**)&This->ip_object);
2014 if(FAILED(hres))
2015 return hres;
2017 hres = IOleInPlaceObject_GetWindow(This->ip_object, &hwnd);
2018 if(SUCCEEDED(hres))
2019 FIXME("Use hwnd %p\n", hwnd);
2021 *pfNoRedraw = FALSE;
2022 return S_OK;
2025 static HRESULT WINAPI PHInPlaceSiteEx_OnInPlaceDeactivateEx(IOleInPlaceSiteEx *iface, BOOL fNoRedraw)
2027 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
2028 FIXME("(%p)->(%x)\n", This, fNoRedraw);
2029 return E_NOTIMPL;
2032 static HRESULT WINAPI PHInPlaceSiteEx_RequestUIActivate(IOleInPlaceSiteEx *iface)
2034 PluginHost *This = impl_from_IOleInPlaceSiteEx(iface);
2035 FIXME("(%p)\n", This);
2036 return E_NOTIMPL;
2039 static const IOleInPlaceSiteExVtbl OleInPlaceSiteExVtbl = {
2040 PHInPlaceSite_QueryInterface,
2041 PHInPlaceSite_AddRef,
2042 PHInPlaceSite_Release,
2043 PHInPlaceSite_GetWindow,
2044 PHInPlaceSite_ContextSensitiveHelp,
2045 PHInPlaceSite_CanInPlaceActivate,
2046 PHInPlaceSite_OnInPlaceActivate,
2047 PHInPlaceSite_OnUIActivate,
2048 PHInPlaceSite_GetWindowContext,
2049 PHInPlaceSite_Scroll,
2050 PHInPlaceSite_OnUIDeactivate,
2051 PHInPlaceSite_OnInPlaceDeactivate,
2052 PHInPlaceSite_DiscardUndoState,
2053 PHInPlaceSite_DeactivateAndUndo,
2054 PHInPlaceSite_OnPosRectChange,
2055 PHInPlaceSiteEx_OnInPlaceActivateEx,
2056 PHInPlaceSiteEx_OnInPlaceDeactivateEx,
2057 PHInPlaceSiteEx_RequestUIActivate
2060 static inline PluginHost *impl_from_IOleControlSite(IOleControlSite *iface)
2062 return CONTAINING_RECORD(iface, PluginHost, IOleControlSite_iface);
2065 static HRESULT WINAPI PHControlSite_QueryInterface(IOleControlSite *iface, REFIID riid, void **ppv)
2067 PluginHost *This = impl_from_IOleControlSite(iface);
2068 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
2071 static ULONG WINAPI PHControlSite_AddRef(IOleControlSite *iface)
2073 PluginHost *This = impl_from_IOleControlSite(iface);
2074 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
2077 static ULONG WINAPI PHControlSite_Release(IOleControlSite *iface)
2079 PluginHost *This = impl_from_IOleControlSite(iface);
2080 return IOleClientSite_Release(&This->IOleClientSite_iface);
2083 static HRESULT WINAPI PHControlSite_OnControlInfoChanged(IOleControlSite *iface)
2085 PluginHost *This = impl_from_IOleControlSite(iface);
2086 FIXME("(%p)\n", This);
2087 return E_NOTIMPL;
2090 static HRESULT WINAPI PHControlSite_LockInPlaceActive(IOleControlSite *iface, BOOL fLock)
2092 PluginHost *This = impl_from_IOleControlSite(iface);
2093 FIXME("(%p)->(%x)\n", This, fLock);
2094 return E_NOTIMPL;
2097 static HRESULT WINAPI PHControlSite_GetExtendedControl(IOleControlSite *iface, IDispatch **ppDisp)
2099 PluginHost *This = impl_from_IOleControlSite(iface);
2100 FIXME("(%p)->(%p)\n", This, ppDisp);
2101 return E_NOTIMPL;
2104 static HRESULT WINAPI PHControlSite_TransformCoords(IOleControlSite *iface, POINTL *pPtlHimetric, POINTF *pPtfContainer, DWORD dwFlags)
2106 PluginHost *This = impl_from_IOleControlSite(iface);
2107 FIXME("(%p)->(%p %p %x)\n", This, pPtlHimetric, pPtfContainer, dwFlags);
2108 return E_NOTIMPL;
2111 static HRESULT WINAPI PHControlSite_TranslateAccelerator(IOleControlSite *iface, MSG *pMsg, DWORD grfModifiers)
2113 PluginHost *This = impl_from_IOleControlSite(iface);
2114 FIXME("(%p)->(%x)\n", This, grfModifiers);
2115 return E_NOTIMPL;
2118 static HRESULT WINAPI PHControlSite_OnFocus(IOleControlSite *iface, BOOL fGotFocus)
2120 PluginHost *This = impl_from_IOleControlSite(iface);
2121 FIXME("(%p)->(%x)\n", This, fGotFocus);
2122 return E_NOTIMPL;
2125 static HRESULT WINAPI PHControlSite_ShowPropertyFrame(IOleControlSite *iface)
2127 PluginHost *This = impl_from_IOleControlSite(iface);
2128 FIXME("(%p)\n", This);
2129 return E_NOTIMPL;
2132 static const IOleControlSiteVtbl OleControlSiteVtbl = {
2133 PHControlSite_QueryInterface,
2134 PHControlSite_AddRef,
2135 PHControlSite_Release,
2136 PHControlSite_OnControlInfoChanged,
2137 PHControlSite_LockInPlaceActive,
2138 PHControlSite_GetExtendedControl,
2139 PHControlSite_TransformCoords,
2140 PHControlSite_TranslateAccelerator,
2141 PHControlSite_OnFocus,
2142 PHControlSite_ShowPropertyFrame
2145 static inline PluginHost *impl_from_IBindHost(IBindHost *iface)
2147 return CONTAINING_RECORD(iface, PluginHost, IBindHost_iface);
2150 static HRESULT WINAPI PHBindHost_QueryInterface(IBindHost *iface, REFIID riid, void **ppv)
2152 PluginHost *This = impl_from_IBindHost(iface);
2153 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
2156 static ULONG WINAPI PHBindHost_AddRef(IBindHost *iface)
2158 PluginHost *This = impl_from_IBindHost(iface);
2159 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
2162 static ULONG WINAPI PHBindHost_Release(IBindHost *iface)
2164 PluginHost *This = impl_from_IBindHost(iface);
2165 return IOleClientSite_Release(&This->IOleClientSite_iface);
2168 static HRESULT WINAPI PHBindHost_CreateMoniker(IBindHost *iface, LPOLESTR szName, IBindCtx *pBC, IMoniker **ppmk, DWORD dwReserved)
2170 PluginHost *This = impl_from_IBindHost(iface);
2172 TRACE("(%p)->(%s %p %p %x)\n", This, debugstr_w(szName), pBC, ppmk, dwReserved);
2174 if(!This->doc || !This->doc->window || !This->doc->window->mon) {
2175 FIXME("no moniker\n");
2176 return E_UNEXPECTED;
2179 return CreateURLMoniker(This->doc->window->mon, szName, ppmk);
2182 static HRESULT WINAPI PHBindHost_MonikerBindToStorage(IBindHost *iface, IMoniker *pMk, IBindCtx *pBC,
2183 IBindStatusCallback *pBSC, REFIID riid, void **ppvObj)
2185 PluginHost *This = impl_from_IBindHost(iface);
2186 FIXME("(%p)->(%p %p %p %s %p)\n", This, pMk, pBC, pBSC, debugstr_guid(riid), ppvObj);
2187 return E_NOTIMPL;
2190 static HRESULT WINAPI PHBindHost_MonikerBindToObject(IBindHost *iface, IMoniker *pMk, IBindCtx *pBC,
2191 IBindStatusCallback *pBSC, REFIID riid, void **ppvObj)
2193 PluginHost *This = impl_from_IBindHost(iface);
2194 FIXME("(%p)->(%p %p %p %s %p)\n", This, pMk, pBC, pBSC, debugstr_guid(riid), ppvObj);
2195 return E_NOTIMPL;
2198 static const IBindHostVtbl BindHostVtbl = {
2199 PHBindHost_QueryInterface,
2200 PHBindHost_AddRef,
2201 PHBindHost_Release,
2202 PHBindHost_CreateMoniker,
2203 PHBindHost_MonikerBindToStorage,
2204 PHBindHost_MonikerBindToObject
2207 static inline PluginHost *impl_from_IServiceProvider(IServiceProvider *iface)
2209 return CONTAINING_RECORD(iface, PluginHost, IServiceProvider_iface);
2212 static HRESULT WINAPI PHServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
2214 PluginHost *This = impl_from_IServiceProvider(iface);
2215 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
2218 static ULONG WINAPI PHServiceProvider_AddRef(IServiceProvider *iface)
2220 PluginHost *This = impl_from_IServiceProvider(iface);
2221 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
2224 static ULONG WINAPI PHServiceProvider_Release(IServiceProvider *iface)
2226 PluginHost *This = impl_from_IServiceProvider(iface);
2227 return IOleClientSite_Release(&This->IOleClientSite_iface);
2230 static HRESULT WINAPI PHServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv)
2232 PluginHost *This = impl_from_IServiceProvider(iface);
2234 if(IsEqualGUID(guidService, &SID_SBindHost)) {
2235 TRACE("SID_SBindHost service\n");
2236 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
2239 TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
2241 if(!This->doc || !This->doc->basedoc.window) {
2242 *ppv = NULL;
2243 return E_NOINTERFACE;
2246 return IServiceProvider_QueryService(&This->doc->basedoc.window->base.IServiceProvider_iface,
2247 guidService, riid, ppv);
2250 static const IServiceProviderVtbl ServiceProviderVtbl = {
2251 PHServiceProvider_QueryInterface,
2252 PHServiceProvider_AddRef,
2253 PHServiceProvider_Release,
2254 PHServiceProvider_QueryService
2257 static BOOL parse_classid(const PRUnichar *classid, CLSID *clsid)
2259 const WCHAR *ptr;
2260 unsigned len;
2261 HRESULT hres;
2263 static const PRUnichar clsidW[] = {'c','l','s','i','d',':'};
2265 if(wcsnicmp(classid, clsidW, ARRAY_SIZE(clsidW)))
2266 return FALSE;
2268 ptr = classid + ARRAY_SIZE(clsidW);
2269 len = lstrlenW(ptr);
2271 if(len == 38) {
2272 hres = CLSIDFromString(ptr, clsid);
2273 }else if(len == 36) {
2274 WCHAR buf[39];
2276 buf[0] = '{';
2277 memcpy(buf+1, ptr, len*sizeof(WCHAR));
2278 buf[37] = '}';
2279 buf[38] = 0;
2280 hres = CLSIDFromString(buf, clsid);
2281 }else {
2282 return FALSE;
2285 return SUCCEEDED(hres);
2288 static BOOL get_elem_clsid(nsIDOMElement *elem, CLSID *clsid)
2290 const PRUnichar *val;
2291 nsAString val_str;
2292 nsresult nsres;
2293 BOOL ret = FALSE;
2295 nsres = get_elem_attr_value(elem, L"classid", &val_str, &val);
2296 if(NS_SUCCEEDED(nsres)) {
2297 if(*val)
2298 ret = parse_classid(val, clsid);
2299 nsAString_Finish(&val_str);
2302 return ret;
2305 typedef struct {
2306 IBindStatusCallback IBindStatusCallback_iface;
2307 IWindowForBindingUI IWindowForBindingUI_iface;
2308 LONG ref;
2309 } InstallCallback;
2311 static inline InstallCallback *impl_from_IBindStatusCallback(IBindStatusCallback *iface)
2313 return CONTAINING_RECORD(iface, InstallCallback, IBindStatusCallback_iface);
2316 static HRESULT WINAPI InstallCallback_QueryInterface(IBindStatusCallback *iface,
2317 REFIID riid, void **ppv)
2319 InstallCallback *This = impl_from_IBindStatusCallback(iface);
2321 if(IsEqualGUID(&IID_IUnknown, riid)) {
2322 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
2323 *ppv = &This->IBindStatusCallback_iface;
2324 }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
2325 TRACE("(%p)->(IID_IBindStatusCallback %p)\n", This, ppv);
2326 *ppv = &This->IBindStatusCallback_iface;
2327 }else if(IsEqualGUID(&IID_IWindowForBindingUI, riid)) {
2328 TRACE("(%p)->(IID_IWindowForBindingUI %p)\n", This, ppv);
2329 *ppv = &This->IWindowForBindingUI_iface;
2330 }else {
2331 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2332 *ppv = NULL;
2333 return E_NOINTERFACE;
2336 IUnknown_AddRef((IUnknown*)*ppv);
2337 return S_OK;
2340 static ULONG WINAPI InstallCallback_AddRef(IBindStatusCallback *iface)
2342 InstallCallback *This = impl_from_IBindStatusCallback(iface);
2343 LONG ref = InterlockedIncrement(&This->ref);
2345 TRACE("(%p) ref=%d\n", This, ref);
2347 return ref;
2350 static ULONG WINAPI InstallCallback_Release(IBindStatusCallback *iface)
2352 InstallCallback *This = impl_from_IBindStatusCallback(iface);
2353 LONG ref = InterlockedIncrement(&This->ref);
2355 TRACE("(%p) ref=%d\n", This, ref);
2357 if(!ref)
2358 heap_free(This);
2360 return ref;
2363 static HRESULT WINAPI InstallCallback_OnStartBinding(IBindStatusCallback *iface,
2364 DWORD dwReserved, IBinding *pib)
2366 InstallCallback *This = impl_from_IBindStatusCallback(iface);
2367 TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
2368 return S_OK;
2371 static HRESULT WINAPI InstallCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
2373 InstallCallback *This = impl_from_IBindStatusCallback(iface);
2374 TRACE("(%p)->(%p)\n", This, pnPriority);
2375 return E_NOTIMPL;
2378 static HRESULT WINAPI InstallCallback_OnLowResource(IBindStatusCallback *iface, DWORD dwReserved)
2380 InstallCallback *This = impl_from_IBindStatusCallback(iface);
2381 TRACE("(%p)->(%x)\n", This, dwReserved);
2382 return S_OK;
2385 static HRESULT WINAPI InstallCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
2386 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
2388 InstallCallback *This = impl_from_IBindStatusCallback(iface);
2389 TRACE("(%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode, debugstr_w(szStatusText));
2390 return S_OK;
2393 static HRESULT WINAPI InstallCallback_OnStopBinding(IBindStatusCallback *iface,
2394 HRESULT hresult, LPCWSTR szError)
2396 InstallCallback *This = impl_from_IBindStatusCallback(iface);
2397 TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
2398 return S_OK;
2401 static HRESULT WINAPI InstallCallback_GetBindInfo(IBindStatusCallback *iface,
2402 DWORD* grfBINDF, BINDINFO* pbindinfo)
2404 InstallCallback *This = impl_from_IBindStatusCallback(iface);
2406 TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
2408 *grfBINDF = BINDF_ASYNCHRONOUS;
2409 return S_OK;
2412 static HRESULT WINAPI InstallCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
2413 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
2415 InstallCallback *This = impl_from_IBindStatusCallback(iface);
2416 ERR("(%p)\n", This);
2417 return E_NOTIMPL;
2420 static HRESULT WINAPI InstallCallback_OnObjectAvailable(IBindStatusCallback *iface,
2421 REFIID riid, IUnknown* punk)
2423 InstallCallback *This = impl_from_IBindStatusCallback(iface);
2424 ERR("(%p)\n", This);
2425 return E_NOTIMPL;
2428 static IBindStatusCallbackVtbl InstallCallbackVtbl = {
2429 InstallCallback_QueryInterface,
2430 InstallCallback_AddRef,
2431 InstallCallback_Release,
2432 InstallCallback_OnStartBinding,
2433 InstallCallback_GetPriority,
2434 InstallCallback_OnLowResource,
2435 InstallCallback_OnProgress,
2436 InstallCallback_OnStopBinding,
2437 InstallCallback_GetBindInfo,
2438 InstallCallback_OnDataAvailable,
2439 InstallCallback_OnObjectAvailable
2442 static inline InstallCallback *impl_from_IWindowForBindingUI(IWindowForBindingUI *iface)
2444 return CONTAINING_RECORD(iface, InstallCallback, IWindowForBindingUI_iface);
2447 static HRESULT WINAPI WindowForBindingUI_QueryInterface(IWindowForBindingUI *iface, REFIID riid, void **ppv)
2449 InstallCallback *This = impl_from_IWindowForBindingUI(iface);
2450 return IBindStatusCallback_QueryInterface(&This->IBindStatusCallback_iface, riid, ppv);
2453 static ULONG WINAPI WindowForBindingUI_AddRef(IWindowForBindingUI *iface)
2455 InstallCallback *This = impl_from_IWindowForBindingUI(iface);
2456 return IBindStatusCallback_AddRef(&This->IBindStatusCallback_iface);
2459 static ULONG WINAPI WindowForBindingUI_Release(IWindowForBindingUI *iface)
2461 InstallCallback *This = impl_from_IWindowForBindingUI(iface);
2462 return IBindStatusCallback_Release(&This->IBindStatusCallback_iface);
2465 static HRESULT WINAPI WindowForBindingUI_GetWindow(IWindowForBindingUI *iface, REFGUID rguidReason, HWND *phwnd)
2467 InstallCallback *This = impl_from_IWindowForBindingUI(iface);
2468 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(rguidReason), phwnd);
2469 *phwnd = NULL;
2470 return S_OK;
2473 static const IWindowForBindingUIVtbl WindowForBindingUIVtbl = {
2474 WindowForBindingUI_QueryInterface,
2475 WindowForBindingUI_AddRef,
2476 WindowForBindingUI_Release,
2477 WindowForBindingUI_GetWindow
2480 typedef struct {
2481 struct list entry;
2482 IUri *uri;
2483 } install_entry_t;
2485 static struct list install_list = LIST_INIT(install_list);
2487 static CRITICAL_SECTION cs_install_list;
2488 static CRITICAL_SECTION_DEBUG cs_install_list_dbg =
2490 0, 0, &cs_install_list,
2491 { &cs_install_list_dbg.ProcessLocksList, &cs_install_list_dbg.ProcessLocksList },
2492 0, 0, { (DWORD_PTR)(__FILE__ ": install_list") }
2494 static CRITICAL_SECTION cs_install_list = { &cs_install_list_dbg, -1, 0, 0, 0, 0 };
2496 static void install_codebase(const WCHAR *url)
2498 InstallCallback *callback;
2499 IBindCtx *bctx;
2500 HRESULT hres;
2502 callback = heap_alloc(sizeof(*callback));
2503 if(!callback)
2504 return;
2506 callback->IBindStatusCallback_iface.lpVtbl = &InstallCallbackVtbl;
2507 callback->IWindowForBindingUI_iface.lpVtbl = &WindowForBindingUIVtbl;
2508 callback->ref = 1;
2510 hres = CreateAsyncBindCtx(0, &callback->IBindStatusCallback_iface, NULL, &bctx);
2511 IBindStatusCallback_Release(&callback->IBindStatusCallback_iface);
2512 if(FAILED(hres))
2513 return;
2515 hres = AsyncInstallDistributionUnit(NULL, NULL, NULL, 0, 0, url, bctx, NULL, 0);
2516 IBindCtx_Release(bctx);
2517 if(FAILED(hres))
2518 WARN("FAILED: %08x\n", hres);
2521 static void check_codebase(HTMLInnerWindow *window, nsIDOMElement *nselem)
2523 BOOL is_on_list = FALSE;
2524 install_entry_t *iter;
2525 const PRUnichar *val;
2526 nsAString val_str;
2527 IUri *uri = NULL;
2528 nsresult nsres;
2529 HRESULT hres;
2531 nsres = get_elem_attr_value(nselem, L"codebase", &val_str, &val);
2532 if(NS_SUCCEEDED(nsres)) {
2533 if(*val) {
2534 hres = CoInternetCombineUrlEx(window->base.outer_window->uri, val, 0, &uri, 0);
2535 if(FAILED(hres))
2536 uri = NULL;
2538 nsAString_Finish(&val_str);
2541 if(!uri)
2542 return;
2544 EnterCriticalSection(&cs_install_list);
2546 LIST_FOR_EACH_ENTRY(iter, &install_list, install_entry_t, entry) {
2547 BOOL eq;
2549 hres = IUri_IsEqual(uri, iter->uri, &eq);
2550 if(SUCCEEDED(hres) && eq) {
2551 TRACE("already proceeded\n");
2552 is_on_list = TRUE;
2553 break;
2557 if(!is_on_list) {
2558 iter = heap_alloc(sizeof(*iter));
2559 if(iter) {
2560 IUri_AddRef(uri);
2561 iter->uri = uri;
2563 list_add_tail(&install_list, &iter->entry);
2567 LeaveCriticalSection(&cs_install_list);
2569 if(!is_on_list) {
2570 BSTR display_uri;
2572 hres = IUri_GetDisplayUri(uri, &display_uri);
2573 if(SUCCEEDED(hres)) {
2574 install_codebase(display_uri);
2575 SysFreeString(display_uri);
2579 IUri_Release(uri);
2582 static IUnknown *create_activex_object(HTMLDocumentNode *doc, nsIDOMElement *nselem, CLSID *clsid)
2584 IClassFactoryEx *cfex;
2585 IClassFactory *cf;
2586 IUnknown *obj;
2587 DWORD policy;
2588 HRESULT hres;
2590 if(!get_elem_clsid(nselem, clsid)) {
2591 WARN("Could not determine element CLSID\n");
2592 return NULL;
2595 TRACE("clsid %s\n", debugstr_guid(clsid));
2597 policy = 0;
2598 hres = IInternetHostSecurityManager_ProcessUrlAction(&doc->IInternetHostSecurityManager_iface,
2599 URLACTION_ACTIVEX_RUN, (BYTE*)&policy, sizeof(policy), (BYTE*)clsid, sizeof(GUID), 0, 0);
2600 if(FAILED(hres) || policy != URLPOLICY_ALLOW) {
2601 WARN("ProcessUrlAction returned %08x %x\n", hres, policy);
2602 return NULL;
2605 hres = CoGetClassObject(clsid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf);
2606 if(hres == REGDB_E_CLASSNOTREG)
2607 check_codebase(doc->window, nselem);
2608 if(FAILED(hres))
2609 return NULL;
2611 hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, (void**)&cfex);
2612 if(SUCCEEDED(hres)) {
2613 FIXME("Use IClassFactoryEx\n");
2614 IClassFactoryEx_Release(cfex);
2617 hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj);
2618 IClassFactory_Release(cf);
2619 if(FAILED(hres))
2620 return NULL;
2622 return obj;
2625 void detach_plugin_host(PluginHost *host)
2627 HRESULT hres;
2629 TRACE("%p\n", host);
2631 if(!host->doc)
2632 return;
2634 if(host->ip_object) {
2635 if(host->ui_active)
2636 IOleInPlaceObject_UIDeactivate(host->ip_object);
2637 IOleInPlaceObject_InPlaceDeactivate(host->ip_object);
2640 if(host->plugin_unk) {
2641 IOleObject *ole_obj;
2643 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IOleObject, (void**)&ole_obj);
2644 if(SUCCEEDED(hres)) {
2645 if(!host->ip_object)
2646 IOleObject_Close(ole_obj, OLECLOSE_NOSAVE);
2647 IOleObject_SetClientSite(ole_obj, NULL);
2648 IOleObject_Release(ole_obj);
2652 if(host->sink) {
2653 IConnectionPointContainer *cp_container;
2654 IConnectionPoint *cp;
2656 assert(host->plugin_unk != NULL);
2658 hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IConnectionPointContainer, (void**)&cp_container);
2659 if(SUCCEEDED(hres)) {
2660 hres = IConnectionPointContainer_FindConnectionPoint(cp_container, &host->sink->iid, &cp);
2661 IConnectionPointContainer_Release(cp_container);
2662 if(SUCCEEDED(hres)) {
2663 IConnectionPoint_Unadvise(cp, host->sink->cookie);
2664 IConnectionPoint_Release(cp);
2668 host->sink->host = NULL;
2669 IDispatch_Release(&host->sink->IDispatch_iface);
2670 host->sink = NULL;
2673 release_plugin_ifaces(host);
2675 if(host->element) {
2676 host->element->plugin_host = NULL;
2677 host->element = NULL;
2680 list_remove(&host->entry);
2681 list_init(&host->entry);
2682 host->doc = NULL;
2685 HRESULT create_plugin_host(HTMLDocumentNode *doc, HTMLPluginContainer *container)
2687 PluginHost *host;
2688 IUnknown *unk;
2689 CLSID clsid;
2691 assert(!container->plugin_host);
2693 unk = create_activex_object(doc, container->element.dom_element, &clsid);
2694 if(!unk)
2695 return E_FAIL;
2697 host = heap_alloc_zero(sizeof(*host));
2698 if(!host) {
2699 IUnknown_Release(unk);
2700 return E_OUTOFMEMORY;
2703 host->IOleClientSite_iface.lpVtbl = &OleClientSiteVtbl;
2704 host->IAdviseSinkEx_iface.lpVtbl = &AdviseSinkExVtbl;
2705 host->IPropertyNotifySink_iface.lpVtbl = &PropertyNotifySinkVtbl;
2706 host->IDispatch_iface.lpVtbl = &DispatchVtbl;
2707 host->IOleInPlaceSiteEx_iface.lpVtbl = &OleInPlaceSiteExVtbl;
2708 host->IOleControlSite_iface.lpVtbl = &OleControlSiteVtbl;
2709 host->IBindHost_iface.lpVtbl = &BindHostVtbl;
2710 host->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
2712 host->ref = 1;
2714 host->plugin_unk = unk;
2715 host->clsid = clsid;
2717 host->doc = doc;
2718 list_add_tail(&doc->plugin_hosts, &host->entry);
2720 container->plugin_host = host;
2721 host->element = container;
2723 initialize_plugin_object(host);
2725 return S_OK;