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
33 #include "mshtml_private.h"
34 #include "pluginhost.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
40 const IID IID_HTMLPluginContainer
=
41 {0xbd7a6050,0xb373,0x4f6f,{0xa4,0x93,0xdd,0x40,0xc5,0x23,0xa8,0x6a}};
43 static BOOL
check_load_safety(PluginHost
*host
)
45 DWORD policy_size
, policy
;
46 struct CONFIRMSAFETY cs
;
50 cs
.clsid
= host
->clsid
;
51 cs
.pUnk
= host
->plugin_unk
;
52 cs
.dwFlags
= CONFIRMSAFETYACTION_LOADOBJECT
;
54 hres
= IInternetHostSecurityManager_QueryCustomPolicy(&host
->doc
->IInternetHostSecurityManager_iface
,
55 &GUID_CUSTOM_CONFIRMOBJECTSAFETY
, &ppolicy
, &policy_size
, (BYTE
*)&cs
, sizeof(cs
), 0);
59 policy
= *(DWORD
*)ppolicy
;
60 CoTaskMemFree(ppolicy
);
61 return policy
== URLPOLICY_ALLOW
;
64 static BOOL
check_script_safety(PluginHost
*host
)
66 DISPPARAMS params
= {NULL
,NULL
,0,0};
67 DWORD policy_size
, policy
;
68 struct CONFIRMSAFETY cs
;
74 cs
.clsid
= host
->clsid
;
75 cs
.pUnk
= host
->plugin_unk
;
78 hres
= IInternetHostSecurityManager_QueryCustomPolicy(&host
->doc
->IInternetHostSecurityManager_iface
,
79 &GUID_CUSTOM_CONFIRMOBJECTSAFETY
, &ppolicy
, &policy_size
, (BYTE
*)&cs
, sizeof(cs
), 0);
83 policy
= *(DWORD
*)ppolicy
;
84 CoTaskMemFree(ppolicy
);
86 if(policy
!= URLPOLICY_ALLOW
)
90 hres
= IDispatch_Invoke(host
->disp
, DISPID_SECURITYCTX
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, &v
, NULL
, &err
);
92 FIXME("Handle security ctx %s\n", debugstr_variant(&v
));
99 static void update_readystate(PluginHost
*host
)
101 DISPPARAMS params
= {NULL
,NULL
,0,0};
108 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IDispatchEx
, (void**)&dispex
);
109 if(SUCCEEDED(hres
)) {
110 FIXME("Use IDispatchEx\n");
111 IDispatchEx_Release(dispex
);
114 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IDispatch
, (void**)&disp
);
118 hres
= IDispatch_Invoke(disp
, DISPID_READYSTATE
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, &v
, NULL
, &err
);
119 IDispatch_Release(disp
);
120 if(SUCCEEDED(hres
)) {
121 /* FIXME: make plugin readystate affect document readystate */
122 TRACE("readystate = %s\n", debugstr_variant(&v
));
127 /* FIXME: We shouldn't need this function and we should embed plugin directly in the main document */
128 static void get_pos_rect(PluginHost
*host
, RECT
*ret
)
132 ret
->bottom
= host
->rect
.bottom
- host
->rect
.top
;
133 ret
->right
= host
->rect
.right
- host
->rect
.left
;
136 static void load_prop_bag(PluginHost
*host
, IPersistPropertyBag
*persist_prop_bag
)
138 IPropertyBag
*prop_bag
;
141 hres
= create_param_prop_bag(host
->element
->element
.nselem
, &prop_bag
);
145 if(prop_bag
&& !check_load_safety(host
)) {
146 IPropertyBag_Release(prop_bag
);
151 hres
= IPersistPropertyBag_Load(persist_prop_bag
, prop_bag
, NULL
);
152 IPropertyBag_Release(prop_bag
);
154 WARN("Load failed: %08x\n", hres
);
156 hres
= IPersistPropertyBag_InitNew(persist_prop_bag
);
158 WARN("InitNew failed: %08x\n", hres
);
162 static void load_plugin(PluginHost
*host
)
164 IPersistPropertyBag2
*persist_prop_bag2
;
165 IPersistPropertyBag
*persist_prop_bag
;
168 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IPersistPropertyBag2
, (void**)&persist_prop_bag2
);
169 if(SUCCEEDED(hres
)) {
170 FIXME("Use IPersistPropertyBag2 iface\n");
171 IPersistPropertyBag2_Release(persist_prop_bag2
);
175 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IPersistPropertyBag
, (void**)&persist_prop_bag
);
176 if(SUCCEEDED(hres
)) {
177 load_prop_bag(host
, persist_prop_bag
);
178 IPersistPropertyBag_Release(persist_prop_bag
);
182 FIXME("No IPersistPropertyBag iface\n");
185 static void activate_plugin(PluginHost
*host
)
187 IClientSecurity
*client_security
;
188 IQuickActivate
*quick_activate
;
189 IOleObject
*ole_obj
= NULL
;
190 IOleCommandTarget
*cmdtrg
;
191 IViewObjectEx
*view_obj
;
197 if(!host
->plugin_unk
)
200 /* Note native calls QI on plugin for an undocumented IID and CLSID_HTMLDocument */
202 /* FIXME: call FreezeEvents(TRUE) */
204 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IClientSecurity
, (void**)&client_security
);
205 if(SUCCEEDED(hres
)) {
206 FIXME("Handle IClientSecurity\n");
207 IClientSecurity_Release(client_security
);
211 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IQuickActivate
, (void**)&quick_activate
);
212 if(SUCCEEDED(hres
)) {
213 QACONTAINER container
= {sizeof(container
)};
214 QACONTROL control
= {sizeof(control
)};
216 TRACE("Using IQuickActivate\n");
218 container
.pClientSite
= &host
->IOleClientSite_iface
;
219 container
.dwAmbientFlags
= QACONTAINER_SUPPORTSMNEMONICS
|QACONTAINER_MESSAGEREFLECT
|QACONTAINER_USERMODE
;
220 container
.pAdviseSink
= &host
->IAdviseSinkEx_iface
;
221 container
.pPropertyNotifySink
= &host
->IPropertyNotifySink_iface
;
223 hres
= IQuickActivate_QuickActivate(quick_activate
, &container
, &control
);
224 IQuickActivate_Release(quick_activate
);
226 FIXME("QuickActivate failed: %08x\n", hres
);
230 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IOleObject
, (void**)&ole_obj
);
231 if(SUCCEEDED(hres
)) {
232 hres
= IOleObject_GetMiscStatus(ole_obj
, DVASPECT_CONTENT
, &status
);
233 TRACE("GetMiscStatus returned %08x %x\n", hres
, status
);
235 hres
= IOleObject_SetClientSite(ole_obj
, &host
->IOleClientSite_iface
);
236 IOleObject_Release(ole_obj
);
238 FIXME("SetClientSite failed: %08x\n", hres
);
242 TRACE("Plugin does not support IOleObject\n");
249 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IViewObjectEx
, (void**)&view_obj
);
250 if(SUCCEEDED(hres
)) {
251 DWORD view_status
= 0;
253 hres
= IViewObjectEx_SetAdvise(view_obj
, DVASPECT_CONTENT
, 0, (IAdviseSink
*)&host
->IAdviseSinkEx_iface
);
255 WARN("SetAdvise failed: %08x\n", hres
);
257 hres
= IViewObjectEx_GetViewStatus(view_obj
, &view_status
);
258 IViewObjectEx_Release(view_obj
);
259 TRACE("GetViewStatus returned %08x %x\n", hres
, view_status
);
263 update_readystate(host
);
265 /* NOTE: Native QIs for IActiveScript, an undocumented IID, IOleControl and IRunnableObject */
267 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IDispatchEx
, (void**)&dispex
);
268 if(SUCCEEDED(hres
)) {
269 FIXME("Use IDispatchEx\n");
270 host
->disp
= (IDispatch
*)dispex
;
272 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IDispatch
, (void**)&disp
);
276 TRACE("no IDispatch iface\n");
279 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IOleCommandTarget
, (void**)&cmdtrg
);
280 if(SUCCEEDED(hres
)) {
281 FIXME("Use IOleCommandTarget\n");
282 IOleCommandTarget_Release(cmdtrg
);
285 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IOleObject
, (void**)&ole_obj
);
287 FIXME("Plugin does not support IOleObject\n");
292 get_pos_rect(host
, &rect
);
293 hres
= IOleObject_DoVerb(ole_obj
, OLEIVERB_INPLACEACTIVATE
, NULL
, &host
->IOleClientSite_iface
, 0, host
->hwnd
, &rect
);
294 IOleObject_Release(ole_obj
);
296 WARN("DoVerb failed: %08x\n", hres
);
299 if(host
->ip_object
) {
302 hres
= IOleInPlaceObject_GetWindow(host
->ip_object
, &hwnd
);
304 TRACE("hwnd %p\n", hwnd
);
308 void update_plugin_window(PluginHost
*host
, HWND hwnd
, const RECT
*rect
)
310 BOOL rect_changed
= FALSE
;
312 if(!hwnd
|| (host
->hwnd
&& host
->hwnd
!= hwnd
)) {
313 FIXME("unhandled hwnd\n");
317 TRACE("%p %s\n", hwnd
, wine_dbgstr_rect(rect
));
319 if(memcmp(rect
, &host
->rect
, sizeof(RECT
))) {
326 activate_plugin(host
);
329 if(rect_changed
&& host
->ip_object
)
330 IOleInPlaceObject_SetObjectRects(host
->ip_object
, &host
->rect
, &host
->rect
);
333 static void notif_enabled(PluginHost
*plugin_host
)
335 DISPPARAMS args
= {NULL
, NULL
, 0, 0};
341 hres
= IUnknown_QueryInterface(plugin_host
->plugin_unk
, &IID_IDispatch
, (void**)&disp
);
343 FIXME("Could not get IDispatch iface: %08x\n", hres
);
347 V_VT(&res
) = VT_EMPTY
;
348 hres
= IDispatch_Invoke(disp
, DISPID_ENABLED
, &IID_NULL
, 0/*FIXME*/, DISPATCH_PROPERTYGET
, &args
, &res
, NULL
, &err
);
349 IDispatch_Release(disp
);
350 if(SUCCEEDED(hres
)) {
351 FIXME("Got enabled %s\n", debugstr_variant(&res
));
356 void notif_container_change(HTMLPluginContainer
*plugin_container
, DISPID dispid
)
358 IOleControl
*ole_control
;
361 if(!plugin_container
->plugin_host
|| !plugin_container
->plugin_host
->plugin_unk
)
364 notif_enabled(plugin_container
->plugin_host
);
366 hres
= IUnknown_QueryInterface(plugin_container
->plugin_host
->plugin_unk
, &IID_IOleControl
, (void**)&ole_control
);
367 if(SUCCEEDED(hres
)) {
368 IOleControl_OnAmbientPropertyChange(ole_control
, dispid
);
369 IOleControl_Release(ole_control
);
373 HRESULT
get_plugin_disp(HTMLPluginContainer
*plugin_container
, IDispatch
**ret
)
377 host
= plugin_container
->plugin_host
;
379 ERR("No plugin host\n");
388 if(!check_script_safety(host
)) {
389 FIXME("Insecure object\n");
393 IDispatch_AddRef(host
->disp
);
398 HRESULT
get_plugin_dispid(HTMLPluginContainer
*plugin_container
, WCHAR
*name
, DISPID
*ret
)
405 if(!plugin_container
->plugin_host
) {
406 WARN("no plugin host\n");
407 return DISP_E_UNKNOWNNAME
;
410 disp
= plugin_container
->plugin_host
->disp
;
412 return DISP_E_UNKNOWNNAME
;
414 hres
= IDispatch_GetIDsOfNames(disp
, &IID_NULL
, &name
, 1, 0, &id
);
416 TRACE("no prop %s\n", debugstr_w(name
));
417 return DISP_E_UNKNOWNNAME
;
420 for(i
=0; i
< plugin_container
->props_len
; i
++) {
421 if(id
== plugin_container
->props
[i
]) {
422 *ret
= MSHTML_DISPID_CUSTOM_MIN
+i
;
427 if(!plugin_container
->props
) {
428 plugin_container
->props
= heap_alloc(8*sizeof(DISPID
));
429 if(!plugin_container
->props
)
430 return E_OUTOFMEMORY
;
431 plugin_container
->props_size
= 8;
432 }else if(plugin_container
->props_len
== plugin_container
->props_size
) {
435 new_props
= heap_realloc(plugin_container
->props
, plugin_container
->props_size
*2*sizeof(DISPID
));
437 return E_OUTOFMEMORY
;
439 plugin_container
->props
= new_props
;
440 plugin_container
->props_size
*= 2;
443 plugin_container
->props
[plugin_container
->props_len
] = id
;
444 *ret
= MSHTML_DISPID_CUSTOM_MIN
+plugin_container
->props_len
;
445 plugin_container
->props_len
++;
449 HRESULT
invoke_plugin_prop(HTMLPluginContainer
*plugin_container
, DISPID id
, LCID lcid
, WORD flags
, DISPPARAMS
*params
,
450 VARIANT
*res
, EXCEPINFO
*ei
)
454 host
= plugin_container
->plugin_host
;
455 if(!host
|| !host
->disp
) {
456 FIXME("Called with no disp\n");
460 if(!check_script_safety(host
)) {
461 FIXME("Insecure object\n");
465 if(id
< MSHTML_DISPID_CUSTOM_MIN
|| id
> MSHTML_DISPID_CUSTOM_MIN
+ plugin_container
->props_len
) {
470 return IDispatch_Invoke(host
->disp
, plugin_container
->props
[id
-MSHTML_DISPID_CUSTOM_MIN
], &IID_NULL
,
471 lcid
, flags
, params
, res
, ei
, NULL
);
480 IDispatch IDispatch_iface
;
490 sink_entry_t
*handlers
;
495 static sink_entry_t
*find_sink_entry(PHEventSink
*sink
, DISPID id
)
499 for(iter
= sink
->handlers
; iter
< sink
->handlers
+sink
->handlers_cnt
; iter
++) {
507 static void add_sink_handler(PHEventSink
*sink
, DISPID id
, IDispatch
*disp
)
509 sink_entry_t
*entry
= find_sink_entry(sink
, id
);
513 IDispatch_Release(entry
->disp
);
515 if(!sink
->handlers_size
) {
516 sink
->handlers
= heap_alloc(4*sizeof(*sink
->handlers
));
519 sink
->handlers_size
= 4;
520 }else if(sink
->handlers_cnt
== sink
->handlers_size
) {
521 sink_entry_t
*new_handlers
;
523 new_handlers
= heap_realloc(sink
->handlers
, 2*sink
->handlers_size
*sizeof(*sink
->handlers
));
526 sink
->handlers
= new_handlers
;
527 sink
->handlers_size
*= 2;
529 entry
= sink
->handlers
+ sink
->handlers_cnt
++;
533 IDispatch_AddRef(disp
);
537 static inline PHEventSink
*PHEventSink_from_IDispatch(IDispatch
*iface
)
539 return CONTAINING_RECORD(iface
, PHEventSink
, IDispatch_iface
);
542 static HRESULT WINAPI
PHEventSink_QueryInterface(IDispatch
*iface
, REFIID riid
, void **ppv
)
544 PHEventSink
*This
= PHEventSink_from_IDispatch(iface
);
546 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
547 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
548 *ppv
= &This
->IDispatch_iface
;
549 }else if(IsEqualGUID(riid
, &IID_IDispatch
)) {
550 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
551 *ppv
= &This
->IDispatch_iface
;
552 }else if(This
->is_dispiface
&& IsEqualGUID(riid
, &This
->iid
)) {
553 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
554 *ppv
= &This
->IDispatch_iface
;
556 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
558 return E_NOINTERFACE
;
561 IUnknown_AddRef((IUnknown
*)*ppv
);
565 static ULONG WINAPI
PHEventSink_AddRef(IDispatch
*iface
)
567 PHEventSink
*This
= PHEventSink_from_IDispatch(iface
);
568 LONG ref
= InterlockedIncrement(&This
->ref
);
570 TRACE("(%p)\n", This
);
575 static ULONG WINAPI
PHEventSink_Release(IDispatch
*iface
)
577 PHEventSink
*This
= PHEventSink_from_IDispatch(iface
);
578 LONG ref
= InterlockedDecrement(&This
->ref
);
580 TRACE("(%p)\n", This
);
587 for(i
=0; i
< This
->handlers_cnt
; i
++) {
588 if(This
->handlers
[i
].disp
)
589 IDispatch_Release(This
->handlers
[i
].disp
);
591 heap_free(This
->handlers
);
598 static HRESULT WINAPI
PHEventSink_GetTypeInfoCount(IDispatch
*iface
, UINT
*pctinfo
)
600 PHEventSink
*This
= PHEventSink_from_IDispatch(iface
);
601 FIXME("(%p)->(%p)\n", This
, pctinfo
);
605 static HRESULT WINAPI
PHEventSink_GetTypeInfo(IDispatch
*iface
, UINT iTInfo
,
606 LCID lcid
, ITypeInfo
**ppTInfo
)
608 PHEventSink
*This
= PHEventSink_from_IDispatch(iface
);
609 FIXME("(%p)->(%d %d %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
613 static HRESULT WINAPI
PHEventSink_GetIDsOfNames(IDispatch
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
614 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
616 PHEventSink
*This
= PHEventSink_from_IDispatch(iface
);
617 FIXME("(%p)->(%s %p %u %d %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
621 static HRESULT WINAPI
PHEventSink_Invoke(IDispatch
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
622 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
624 PHEventSink
*This
= PHEventSink_from_IDispatch(iface
);
629 TRACE("(%p)->(%d %s %d %x %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
), lcid
, wFlags
,
630 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
637 entry
= find_sink_entry(This
, dispIdMember
);
638 if(!entry
|| !entry
->disp
) {
639 WARN("No handler %d\n", dispIdMember
);
641 V_VT(pVarResult
) = VT_EMPTY
;
645 hres
= IDispatch_QueryInterface(entry
->disp
, &IID_IDispatchEx
, (void**)&dispex
);
647 TRACE("(%p) %d >>>\n", This
, entry
->id
);
648 if(SUCCEEDED(hres
)) {
649 hres
= IDispatchEx_InvokeEx(dispex
, DISPID_VALUE
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, NULL
);
650 IDispatchEx_Release(dispex
);
652 hres
= IDispatch_Invoke(entry
->disp
, DISPID_VALUE
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
655 TRACE("(%p) %d <<<\n", This
, entry
->id
);
657 WARN("(%p) %d <<< %08x\n", This
, entry
->id
, hres
);
661 static const IDispatchVtbl PHCPDispatchVtbl
= {
662 PHEventSink_QueryInterface
,
665 PHEventSink_GetTypeInfoCount
,
666 PHEventSink_GetTypeInfo
,
667 PHEventSink_GetIDsOfNames
,
671 static PHEventSink
*create_event_sink(PluginHost
*plugin_host
, ITypeInfo
*typeinfo
)
673 IConnectionPointContainer
*cp_container
;
675 IConnectionPoint
*cp
;
681 hres
= ITypeInfo_GetTypeAttr(typeinfo
, &typeattr
);
685 typekind
= typeattr
->typekind
;
686 guid
= typeattr
->guid
;
687 ITypeInfo_ReleaseTypeAttr(typeinfo
, typeattr
);
689 TRACE("guid %s typekind %d\n", debugstr_guid(&guid
), typekind
);
691 if(typekind
!= TKIND_INTERFACE
&& typekind
!= TKIND_DISPATCH
) {
692 WARN("invalid typekind %d\n", typekind
);
696 hres
= IUnknown_QueryInterface(plugin_host
->plugin_unk
, &IID_IConnectionPointContainer
, (void**)&cp_container
);
698 WARN("Could not get IConnectionPointContainer iface: %08x\n", hres
);
702 hres
= IConnectionPointContainer_FindConnectionPoint(cp_container
, &guid
, &cp
);
703 IConnectionPointContainer_Release(cp_container
);
705 WARN("Could not find %s connection point\n", debugstr_guid(&guid
));
709 ret
= heap_alloc_zero(sizeof(*ret
));
711 ret
->IDispatch_iface
.lpVtbl
= &PHCPDispatchVtbl
;
713 ret
->host
= plugin_host
;
715 ret
->is_dispiface
= typekind
== TKIND_DISPATCH
;
717 ITypeInfo_AddRef(typeinfo
);
718 ret
->typeinfo
= typeinfo
;
720 hres
= IConnectionPoint_Advise(cp
, (IUnknown
*)&ret
->IDispatch_iface
, &ret
->cookie
);
722 hres
= E_OUTOFMEMORY
;
725 IConnectionPoint_Release(cp
);
727 WARN("Advise failed: %08x\n", hres
);
734 static ITypeInfo
*get_eventiface_info(HTMLPluginContainer
*plugin_container
, ITypeInfo
*class_info
)
736 int impl_types
, i
, impl_flags
;
737 ITypeInfo
*ret
= NULL
;
742 hres
= ITypeInfo_GetTypeAttr(class_info
, &typeattr
);
746 if(typeattr
->typekind
!= TKIND_COCLASS
) {
747 WARN("not coclass\n");
748 ITypeInfo_ReleaseTypeAttr(class_info
, typeattr
);
752 impl_types
= typeattr
->cImplTypes
;
753 ITypeInfo_ReleaseTypeAttr(class_info
, typeattr
);
755 for(i
=0; i
<impl_types
; i
++) {
756 hres
= ITypeInfo_GetImplTypeFlags(class_info
, i
, &impl_flags
);
760 if((impl_flags
& IMPLTYPEFLAG_FSOURCE
)) {
761 if(!(impl_flags
& IMPLTYPEFLAG_FDEFAULT
)) {
762 FIXME("Handle non-default source iface\n");
766 hres
= ITypeInfo_GetRefTypeOfImplType(class_info
, i
, &ref
);
770 hres
= ITypeInfo_GetRefTypeInfo(class_info
, ref
, &ret
);
779 void bind_activex_event(HTMLDocumentNode
*doc
, HTMLPluginContainer
*plugin_container
, WCHAR
*event
, IDispatch
*disp
)
781 PluginHost
*plugin_host
= plugin_container
->plugin_host
;
782 ITypeInfo
*class_info
, *source_info
;
786 TRACE("(%p %p %s %p)\n", doc
, plugin_host
, debugstr_w(event
), disp
);
788 if(!plugin_host
|| !plugin_host
->plugin_unk
) {
789 WARN("detached element %p\n", plugin_host
);
793 if(plugin_host
->sink
) {
794 source_info
= plugin_host
->sink
->typeinfo
;
795 ITypeInfo_AddRef(source_info
);
797 IProvideClassInfo
*provide_ci
;
799 hres
= IUnknown_QueryInterface(plugin_host
->plugin_unk
, &IID_IProvideClassInfo
, (void**)&provide_ci
);
801 FIXME("No IProvideClassInfo, try GetTypeInfo?\n");
805 hres
= IProvideClassInfo_GetClassInfo(provide_ci
, &class_info
);
806 IProvideClassInfo_Release(provide_ci
);
807 if(FAILED(hres
) || !class_info
) {
808 WARN("GetClassInfo failed: %08x\n", hres
);
812 source_info
= get_eventiface_info(plugin_container
, class_info
);
813 ITypeInfo_Release(class_info
);
818 hres
= ITypeInfo_GetIDsOfNames(source_info
, &event
, 1, &id
);
820 WARN("Could not get disp id: %08x\n", hres
);
821 else if(!plugin_host
->sink
)
822 plugin_host
->sink
= create_event_sink(plugin_host
, source_info
);
824 ITypeInfo_Release(source_info
);
825 if(FAILED(hres
) || !plugin_host
->sink
)
828 add_sink_handler(plugin_host
->sink
, id
, disp
);
831 static inline PluginHost
*impl_from_IOleClientSite(IOleClientSite
*iface
)
833 return CONTAINING_RECORD(iface
, PluginHost
, IOleClientSite_iface
);
836 static HRESULT WINAPI
PHClientSite_QueryInterface(IOleClientSite
*iface
, REFIID riid
, void **ppv
)
838 PluginHost
*This
= impl_from_IOleClientSite(iface
);
840 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
841 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
842 *ppv
= &This
->IOleClientSite_iface
;
843 }else if(IsEqualGUID(&IID_IOleClientSite
, riid
)) {
844 TRACE("(%p)->(IID_IOleClientSite %p)\n", This
, ppv
);
845 *ppv
= &This
->IOleClientSite_iface
;
846 }else if(IsEqualGUID(&IID_IAdviseSink
, riid
)) {
847 TRACE("(%p)->(IID_IAdviseSink %p)\n", This
, ppv
);
848 *ppv
= &This
->IAdviseSinkEx_iface
;
849 }else if(IsEqualGUID(&IID_IAdviseSinkEx
, riid
)) {
850 TRACE("(%p)->(IID_IAdviseSinkEx %p)\n", This
, ppv
);
851 *ppv
= &This
->IAdviseSinkEx_iface
;
852 }else if(IsEqualGUID(&IID_IPropertyNotifySink
, riid
)) {
853 TRACE("(%p)->(IID_IPropertyNotifySink %p)\n", This
, ppv
);
854 *ppv
= &This
->IPropertyNotifySink_iface
;
855 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
856 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
857 *ppv
= &This
->IDispatch_iface
;
858 }else if(IsEqualGUID(&IID_IOleWindow
, riid
)) {
859 TRACE("(%p)->(IID_IOleWindow %p)\n", This
, ppv
);
860 *ppv
= &This
->IOleInPlaceSiteEx_iface
;
861 }else if(IsEqualGUID(&IID_IOleInPlaceSite
, riid
)) {
862 TRACE("(%p)->(IID_IOleInPlaceSite %p)\n", This
, ppv
);
863 *ppv
= &This
->IOleInPlaceSiteEx_iface
;
864 }else if(IsEqualGUID(&IID_IOleInPlaceSiteEx
, riid
)) {
865 TRACE("(%p)->(IID_IOleInPlaceSiteEx %p)\n", This
, ppv
);
866 *ppv
= &This
->IOleInPlaceSiteEx_iface
;
867 }else if(IsEqualGUID(&IID_IOleControlSite
, riid
)) {
868 TRACE("(%p)->(IID_IOleControlSite %p)\n", This
, ppv
);
869 *ppv
= &This
->IOleControlSite_iface
;
870 }else if(IsEqualGUID(&IID_IBindHost
, riid
)) {
871 TRACE("(%p)->(IID_IBindHost %p)\n", This
, ppv
);
872 *ppv
= &This
->IBindHost_iface
;
873 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
874 TRACE("(%p)->(IID_IServiceProvider %p)\n", This
, ppv
);
875 *ppv
= &This
->IServiceProvider_iface
;
877 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
879 return E_NOINTERFACE
;
882 IUnknown_AddRef((IUnknown
*)*ppv
);
886 static ULONG WINAPI
PHClientSite_AddRef(IOleClientSite
*iface
)
888 PluginHost
*This
= impl_from_IOleClientSite(iface
);
889 LONG ref
= InterlockedIncrement(&This
->ref
);
891 TRACE("(%p) ref=%d\n", This
, ref
);
896 static void release_plugin_ifaces(PluginHost
*This
)
899 IDispatch_Release(This
->disp
);
903 if(This
->ip_object
) {
904 IOleInPlaceObject_Release(This
->ip_object
);
905 This
->ip_object
= NULL
;
908 if(This
->plugin_unk
) {
909 IUnknown
*unk
= This
->plugin_unk
;
912 This
->plugin_unk
= NULL
;
913 ref
= IUnknown_Release(unk
);
915 TRACE("plugin ref = %d\n", ref
);
919 static ULONG WINAPI
PHClientSite_Release(IOleClientSite
*iface
)
921 PluginHost
*This
= impl_from_IOleClientSite(iface
);
922 LONG ref
= InterlockedDecrement(&This
->ref
);
924 TRACE("(%p) ref=%d\n", This
, ref
);
927 release_plugin_ifaces(This
);
929 This
->sink
->host
= NULL
;
930 IDispatch_Release(&This
->sink
->IDispatch_iface
);
933 list_remove(&This
->entry
);
935 This
->element
->plugin_host
= NULL
;
942 static HRESULT WINAPI
PHClientSite_SaveObject(IOleClientSite
*iface
)
944 PluginHost
*This
= impl_from_IOleClientSite(iface
);
945 FIXME("(%p)\n", This
);
949 static HRESULT WINAPI
PHClientSite_GetMoniker(IOleClientSite
*iface
, DWORD dwAssign
,
950 DWORD dwWhichMoniker
, IMoniker
**ppmk
)
952 PluginHost
*This
= impl_from_IOleClientSite(iface
);
954 TRACE("(%p)->(%d %d %p)\n", This
, dwAssign
, dwWhichMoniker
, ppmk
);
956 switch(dwWhichMoniker
) {
957 case OLEWHICHMK_CONTAINER
:
958 if(!This
->doc
|| !This
->doc
->window
|| !This
->doc
->window
->mon
) {
959 FIXME("no moniker\n");
963 *ppmk
= This
->doc
->window
->mon
;
964 IMoniker_AddRef(*ppmk
);
967 FIXME("which %d\n", dwWhichMoniker
);
974 static HRESULT WINAPI
PHClientSite_GetContainer(IOleClientSite
*iface
, IOleContainer
**ppContainer
)
976 PluginHost
*This
= impl_from_IOleClientSite(iface
);
978 TRACE("(%p)->(%p)\n", This
, ppContainer
);
981 ERR("Called on detached object\n");
985 *ppContainer
= &This
->doc
->basedoc
.IOleContainer_iface
;
986 IOleContainer_AddRef(*ppContainer
);
990 static HRESULT WINAPI
PHClientSite_ShowObject(IOleClientSite
*iface
)
992 PluginHost
*This
= impl_from_IOleClientSite(iface
);
994 TRACE("(%p)\n", This
);
999 static HRESULT WINAPI
PHClientSite_OnShowWindow(IOleClientSite
*iface
, BOOL fShow
)
1001 PluginHost
*This
= impl_from_IOleClientSite(iface
);
1002 FIXME("(%p)->(%x)\n", This
, fShow
);
1006 static HRESULT WINAPI
PHClientSite_RequestNewObjectLayout(IOleClientSite
*iface
)
1008 PluginHost
*This
= impl_from_IOleClientSite(iface
);
1009 FIXME("(%p)\n", This
);
1013 static const IOleClientSiteVtbl OleClientSiteVtbl
= {
1014 PHClientSite_QueryInterface
,
1015 PHClientSite_AddRef
,
1016 PHClientSite_Release
,
1017 PHClientSite_SaveObject
,
1018 PHClientSite_GetMoniker
,
1019 PHClientSite_GetContainer
,
1020 PHClientSite_ShowObject
,
1021 PHClientSite_OnShowWindow
,
1022 PHClientSite_RequestNewObjectLayout
1025 static inline PluginHost
*impl_from_IAdviseSinkEx(IAdviseSinkEx
*iface
)
1027 return CONTAINING_RECORD(iface
, PluginHost
, IAdviseSinkEx_iface
);
1030 static HRESULT WINAPI
PHAdviseSinkEx_QueryInterface(IAdviseSinkEx
*iface
, REFIID riid
, void **ppv
)
1032 PluginHost
*This
= impl_from_IAdviseSinkEx(iface
);
1033 return IOleClientSite_QueryInterface(&This
->IOleClientSite_iface
, riid
, ppv
);
1036 static ULONG WINAPI
PHAdviseSinkEx_AddRef(IAdviseSinkEx
*iface
)
1038 PluginHost
*This
= impl_from_IAdviseSinkEx(iface
);
1039 return IOleClientSite_AddRef(&This
->IOleClientSite_iface
);
1042 static ULONG WINAPI
PHAdviseSinkEx_Release(IAdviseSinkEx
*iface
)
1044 PluginHost
*This
= impl_from_IAdviseSinkEx(iface
);
1045 return IOleClientSite_Release(&This
->IOleClientSite_iface
);
1048 static void WINAPI
PHAdviseSinkEx_OnDataChange(IAdviseSinkEx
*iface
, FORMATETC
*pFormatetc
, STGMEDIUM
*pStgMedium
)
1050 PluginHost
*This
= impl_from_IAdviseSinkEx(iface
);
1051 FIXME("(%p)->(%p %p)\n", This
, pFormatetc
, pStgMedium
);
1054 static void WINAPI
PHAdviseSinkEx_OnViewChange(IAdviseSinkEx
*iface
, DWORD dwAspect
, LONG lindex
)
1056 PluginHost
*This
= impl_from_IAdviseSinkEx(iface
);
1057 FIXME("(%p)->(%d %d)\n", This
, dwAspect
, lindex
);
1060 static void WINAPI
PHAdviseSinkEx_OnRename(IAdviseSinkEx
*iface
, IMoniker
*pmk
)
1062 PluginHost
*This
= impl_from_IAdviseSinkEx(iface
);
1063 FIXME("(%p)->(%p)\n", This
, pmk
);
1066 static void WINAPI
PHAdviseSinkEx_OnSave(IAdviseSinkEx
*iface
)
1068 PluginHost
*This
= impl_from_IAdviseSinkEx(iface
);
1069 FIXME("(%p)\n", This
);
1072 static void WINAPI
PHAdviseSinkEx_OnClose(IAdviseSinkEx
*iface
)
1074 PluginHost
*This
= impl_from_IAdviseSinkEx(iface
);
1075 FIXME("(%p)\n", This
);
1078 static void WINAPI
PHAdviseSinkEx_OnViewStatusChange(IAdviseSinkEx
*iface
, DWORD dwViewStatus
)
1080 PluginHost
*This
= impl_from_IAdviseSinkEx(iface
);
1081 FIXME("(%p)->(%d)\n", This
, dwViewStatus
);
1084 static const IAdviseSinkExVtbl AdviseSinkExVtbl
= {
1085 PHAdviseSinkEx_QueryInterface
,
1086 PHAdviseSinkEx_AddRef
,
1087 PHAdviseSinkEx_Release
,
1088 PHAdviseSinkEx_OnDataChange
,
1089 PHAdviseSinkEx_OnViewChange
,
1090 PHAdviseSinkEx_OnRename
,
1091 PHAdviseSinkEx_OnSave
,
1092 PHAdviseSinkEx_OnClose
,
1093 PHAdviseSinkEx_OnViewStatusChange
1096 static inline PluginHost
*impl_from_IPropertyNotifySink(IPropertyNotifySink
*iface
)
1098 return CONTAINING_RECORD(iface
, PluginHost
, IPropertyNotifySink_iface
);
1101 static HRESULT WINAPI
PHPropertyNotifySink_QueryInterface(IPropertyNotifySink
*iface
, REFIID riid
, void **ppv
)
1103 PluginHost
*This
= impl_from_IPropertyNotifySink(iface
);
1104 return IOleClientSite_QueryInterface(&This
->IOleClientSite_iface
, riid
, ppv
);
1107 static ULONG WINAPI
PHPropertyNotifySink_AddRef(IPropertyNotifySink
*iface
)
1109 PluginHost
*This
= impl_from_IPropertyNotifySink(iface
);
1110 return IOleClientSite_AddRef(&This
->IOleClientSite_iface
);
1113 static ULONG WINAPI
PHPropertyNotifySink_Release(IPropertyNotifySink
*iface
)
1115 PluginHost
*This
= impl_from_IPropertyNotifySink(iface
);
1116 return IOleClientSite_Release(&This
->IOleClientSite_iface
);
1119 static HRESULT WINAPI
PHPropertyNotifySink_OnChanged(IPropertyNotifySink
*iface
, DISPID dispID
)
1121 PluginHost
*This
= impl_from_IPropertyNotifySink(iface
);
1123 TRACE("(%p)->(%d)\n", This
, dispID
);
1126 case DISPID_READYSTATE
:
1127 update_readystate(This
);
1130 FIXME("Unimplemented dispID %d\n", dispID
);
1137 static HRESULT WINAPI
PHPropertyNotifySink_OnRequestEdit(IPropertyNotifySink
*iface
, DISPID dispID
)
1139 PluginHost
*This
= impl_from_IPropertyNotifySink(iface
);
1140 FIXME("(%p)->(%d)\n", This
, dispID
);
1144 static const IPropertyNotifySinkVtbl PropertyNotifySinkVtbl
= {
1145 PHPropertyNotifySink_QueryInterface
,
1146 PHPropertyNotifySink_AddRef
,
1147 PHPropertyNotifySink_Release
,
1148 PHPropertyNotifySink_OnChanged
,
1149 PHPropertyNotifySink_OnRequestEdit
1152 static inline PluginHost
*impl_from_IDispatch(IDispatch
*iface
)
1154 return CONTAINING_RECORD(iface
, PluginHost
, IDispatch_iface
);
1157 static HRESULT WINAPI
PHDispatch_QueryInterface(IDispatch
*iface
, REFIID riid
, void **ppv
)
1159 PluginHost
*This
= impl_from_IDispatch(iface
);
1160 return IOleClientSite_QueryInterface(&This
->IOleClientSite_iface
, riid
, ppv
);
1163 static ULONG WINAPI
PHDispatch_AddRef(IDispatch
*iface
)
1165 PluginHost
*This
= impl_from_IDispatch(iface
);
1166 return IOleClientSite_AddRef(&This
->IOleClientSite_iface
);
1169 static ULONG WINAPI
PHDispatch_Release(IDispatch
*iface
)
1171 PluginHost
*This
= impl_from_IDispatch(iface
);
1172 return IOleClientSite_Release(&This
->IOleClientSite_iface
);
1175 static HRESULT WINAPI
PHDispatch_GetTypeInfoCount(IDispatch
*iface
, UINT
*pctinfo
)
1177 PluginHost
*This
= impl_from_IDispatch(iface
);
1178 FIXME("(%p)->(%p)\n", This
, pctinfo
);
1182 static HRESULT WINAPI
PHDispatch_GetTypeInfo(IDispatch
*iface
, UINT iTInfo
,
1183 LCID lcid
, ITypeInfo
**ppTInfo
)
1185 PluginHost
*This
= impl_from_IDispatch(iface
);
1186 FIXME("(%p)->(%d %d %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1190 static HRESULT WINAPI
PHDispatch_GetIDsOfNames(IDispatch
*iface
, REFIID riid
,
1191 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1193 PluginHost
*This
= impl_from_IDispatch(iface
);
1194 FIXME("(%p)->(%s %p %d %d %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
1198 static HRESULT WINAPI
PHDispatch_Invoke(IDispatch
*iface
, DISPID dispid
, REFIID riid
, LCID lcid
,
1199 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1201 PluginHost
*This
= impl_from_IDispatch(iface
);
1202 FIXME("(%p)->(%d %x %p %p)\n", This
, dispid
, wFlags
, pDispParams
, pVarResult
);
1206 static const IDispatchVtbl DispatchVtbl
= {
1207 PHDispatch_QueryInterface
,
1210 PHDispatch_GetTypeInfoCount
,
1211 PHDispatch_GetTypeInfo
,
1212 PHDispatch_GetIDsOfNames
,
1216 static inline PluginHost
*impl_from_IOleInPlaceSiteEx(IOleInPlaceSiteEx
*iface
)
1218 return CONTAINING_RECORD(iface
, PluginHost
, IOleInPlaceSiteEx_iface
);
1221 static HRESULT WINAPI
PHInPlaceSite_QueryInterface(IOleInPlaceSiteEx
*iface
, REFIID riid
, void **ppv
)
1223 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1224 return IOleClientSite_QueryInterface(&This
->IOleClientSite_iface
, riid
, ppv
);
1227 static ULONG WINAPI
PHInPlaceSite_AddRef(IOleInPlaceSiteEx
*iface
)
1229 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1230 return IOleClientSite_AddRef(&This
->IOleClientSite_iface
);
1233 static ULONG WINAPI
PHInPlaceSite_Release(IOleInPlaceSiteEx
*iface
)
1235 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1236 return IOleClientSite_Release(&This
->IOleClientSite_iface
);
1239 static HRESULT WINAPI
PHInPlaceSite_GetWindow(IOleInPlaceSiteEx
*iface
, HWND
*phwnd
)
1241 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1243 TRACE("(%p)->(%p)\n", This
, phwnd
);
1245 *phwnd
= This
->hwnd
;
1249 static HRESULT WINAPI
PHInPlaceSite_ContextSensitiveHelp(IOleInPlaceSiteEx
*iface
, BOOL fEnterMode
)
1251 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1252 FIXME("(%p)->(%x)\n", This
, fEnterMode
);
1256 static HRESULT WINAPI
PHInPlaceSite_CanInPlaceActivate(IOleInPlaceSiteEx
*iface
)
1258 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1260 TRACE("(%p)\n", This
);
1265 static HRESULT WINAPI
PHInPlaceSite_OnInPlaceActivate(IOleInPlaceSiteEx
*iface
)
1267 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1268 FIXME("(%p)\n", This
);
1272 static HRESULT WINAPI
PHInPlaceSite_OnUIActivate(IOleInPlaceSiteEx
*iface
)
1274 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1276 TRACE("(%p)\n", This
);
1278 if(!This
->plugin_unk
) {
1279 ERR("No plugin object\n");
1280 return E_UNEXPECTED
;
1283 This
->ui_active
= TRUE
;
1285 notif_enabled(This
);
1289 static HRESULT WINAPI
PHInPlaceSite_GetWindowContext(IOleInPlaceSiteEx
*iface
,
1290 IOleInPlaceFrame
**ppFrame
, IOleInPlaceUIWindow
**ppDoc
, RECT
*lprcPosRect
,
1291 RECT
*lprcClipRect
, OLEINPLACEFRAMEINFO
*frame_info
)
1293 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1294 IOleInPlaceUIWindow
*ip_window
;
1295 IOleInPlaceFrame
*ip_frame
;
1299 TRACE("(%p)->(%p %p %p %p %p)\n", This
, ppFrame
, ppDoc
, lprcPosRect
, lprcClipRect
, frame_info
);
1301 if(!This
->doc
|| !This
->doc
->basedoc
.doc_obj
|| !This
->doc
->basedoc
.doc_obj
->ipsite
) {
1302 FIXME("No ipsite\n");
1303 return E_UNEXPECTED
;
1306 hres
= IOleInPlaceSite_GetWindowContext(This
->doc
->basedoc
.doc_obj
->ipsite
, &ip_frame
, &ip_window
, &pr
, &cr
, frame_info
);
1308 WARN("GetWindowContext failed: %08x\n", hres
);
1313 IOleInPlaceUIWindow_Release(ip_window
);
1315 IOleInPlaceFrame_Release(ip_frame
);
1317 hres
= create_ip_frame(&ip_frame
);
1321 hres
= create_ip_window(ppDoc
);
1323 IOleInPlaceFrame_Release(ip_frame
);
1327 *ppFrame
= ip_frame
;
1328 *lprcPosRect
= This
->rect
;
1329 *lprcClipRect
= This
->rect
;
1333 static HRESULT WINAPI
PHInPlaceSite_Scroll(IOleInPlaceSiteEx
*iface
, SIZE scrollExtent
)
1335 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1336 FIXME("(%p)->({%d %d})\n", This
, scrollExtent
.cx
, scrollExtent
.cy
);
1340 static HRESULT WINAPI
PHInPlaceSite_OnUIDeactivate(IOleInPlaceSiteEx
*iface
, BOOL fUndoable
)
1342 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1343 FIXME("(%p)->(%x)\n", This
, fUndoable
);
1347 static HRESULT WINAPI
PHInPlaceSite_OnInPlaceDeactivate(IOleInPlaceSiteEx
*iface
)
1349 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1351 TRACE("(%p)\n", This
);
1353 if(This
->ip_object
) {
1354 IOleInPlaceObject_Release(This
->ip_object
);
1355 This
->ip_object
= NULL
;
1361 static HRESULT WINAPI
PHInPlaceSite_DiscardUndoState(IOleInPlaceSiteEx
*iface
)
1363 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1364 FIXME("(%p)\n", This
);
1368 static HRESULT WINAPI
PHInPlaceSite_DeactivateAndUndo(IOleInPlaceSiteEx
*iface
)
1370 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1371 FIXME("(%p)\n", This
);
1375 static HRESULT WINAPI
PHInPlaceSite_OnPosRectChange(IOleInPlaceSiteEx
*iface
, LPCRECT lprcPosRect
)
1377 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1378 FIXME("(%p)->(%p)\n", This
, lprcPosRect
);
1382 static HRESULT WINAPI
PHInPlaceSiteEx_OnInPlaceActivateEx(IOleInPlaceSiteEx
*iface
, BOOL
*pfNoRedraw
, DWORD dwFlags
)
1384 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1388 TRACE("(%p)->(%p %x)\n", This
, pfNoRedraw
, dwFlags
);
1393 hres
= IUnknown_QueryInterface(This
->plugin_unk
, &IID_IOleInPlaceObject
, (void**)&This
->ip_object
);
1397 hres
= IOleInPlaceObject_GetWindow(This
->ip_object
, &hwnd
);
1399 FIXME("Use hwnd %p\n", hwnd
);
1401 *pfNoRedraw
= FALSE
;
1405 static HRESULT WINAPI
PHInPlaceSiteEx_OnInPlaceDeactivateEx(IOleInPlaceSiteEx
*iface
, BOOL fNoRedraw
)
1407 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1408 FIXME("(%p)->(%x)\n", This
, fNoRedraw
);
1412 static HRESULT WINAPI
PHInPlaceSiteEx_RequestUIActivate(IOleInPlaceSiteEx
*iface
)
1414 PluginHost
*This
= impl_from_IOleInPlaceSiteEx(iface
);
1415 FIXME("(%p)\n", This
);
1419 static const IOleInPlaceSiteExVtbl OleInPlaceSiteExVtbl
= {
1420 PHInPlaceSite_QueryInterface
,
1421 PHInPlaceSite_AddRef
,
1422 PHInPlaceSite_Release
,
1423 PHInPlaceSite_GetWindow
,
1424 PHInPlaceSite_ContextSensitiveHelp
,
1425 PHInPlaceSite_CanInPlaceActivate
,
1426 PHInPlaceSite_OnInPlaceActivate
,
1427 PHInPlaceSite_OnUIActivate
,
1428 PHInPlaceSite_GetWindowContext
,
1429 PHInPlaceSite_Scroll
,
1430 PHInPlaceSite_OnUIDeactivate
,
1431 PHInPlaceSite_OnInPlaceDeactivate
,
1432 PHInPlaceSite_DiscardUndoState
,
1433 PHInPlaceSite_DeactivateAndUndo
,
1434 PHInPlaceSite_OnPosRectChange
,
1435 PHInPlaceSiteEx_OnInPlaceActivateEx
,
1436 PHInPlaceSiteEx_OnInPlaceDeactivateEx
,
1437 PHInPlaceSiteEx_RequestUIActivate
1440 static inline PluginHost
*impl_from_IOleControlSite(IOleControlSite
*iface
)
1442 return CONTAINING_RECORD(iface
, PluginHost
, IOleControlSite_iface
);
1445 static HRESULT WINAPI
PHControlSite_QueryInterface(IOleControlSite
*iface
, REFIID riid
, void **ppv
)
1447 PluginHost
*This
= impl_from_IOleControlSite(iface
);
1448 return IOleClientSite_QueryInterface(&This
->IOleClientSite_iface
, riid
, ppv
);
1451 static ULONG WINAPI
PHControlSite_AddRef(IOleControlSite
*iface
)
1453 PluginHost
*This
= impl_from_IOleControlSite(iface
);
1454 return IOleClientSite_AddRef(&This
->IOleClientSite_iface
);
1457 static ULONG WINAPI
PHControlSite_Release(IOleControlSite
*iface
)
1459 PluginHost
*This
= impl_from_IOleControlSite(iface
);
1460 return IOleClientSite_Release(&This
->IOleClientSite_iface
);
1463 static HRESULT WINAPI
PHControlSite_OnControlInfoChanged(IOleControlSite
*iface
)
1465 PluginHost
*This
= impl_from_IOleControlSite(iface
);
1466 FIXME("(%p)\n", This
);
1470 static HRESULT WINAPI
PHControlSite_LockInPlaceActive(IOleControlSite
*iface
, BOOL fLock
)
1472 PluginHost
*This
= impl_from_IOleControlSite(iface
);
1473 FIXME("(%p)->(%x)\n", This
, fLock
);
1477 static HRESULT WINAPI
PHControlSite_GetExtendedControl(IOleControlSite
*iface
, IDispatch
**ppDisp
)
1479 PluginHost
*This
= impl_from_IOleControlSite(iface
);
1480 FIXME("(%p)->(%p)\n", This
, ppDisp
);
1484 static HRESULT WINAPI
PHControlSite_TransformCoords(IOleControlSite
*iface
, POINTL
*pPtlHimetric
, POINTF
*pPtfContainer
, DWORD dwFlags
)
1486 PluginHost
*This
= impl_from_IOleControlSite(iface
);
1487 FIXME("(%p)->(%p %p %x)\n", This
, pPtlHimetric
, pPtfContainer
, dwFlags
);
1491 static HRESULT WINAPI
PHControlSite_TranslateAccelerator(IOleControlSite
*iface
, MSG
*pMsg
, DWORD grfModifiers
)
1493 PluginHost
*This
= impl_from_IOleControlSite(iface
);
1494 FIXME("(%p)->(%x)\n", This
, grfModifiers
);
1498 static HRESULT WINAPI
PHControlSite_OnFocus(IOleControlSite
*iface
, BOOL fGotFocus
)
1500 PluginHost
*This
= impl_from_IOleControlSite(iface
);
1501 FIXME("(%p)->(%x)\n", This
, fGotFocus
);
1505 static HRESULT WINAPI
PHControlSite_ShowPropertyFrame(IOleControlSite
*iface
)
1507 PluginHost
*This
= impl_from_IOleControlSite(iface
);
1508 FIXME("(%p)\n", This
);
1512 static const IOleControlSiteVtbl OleControlSiteVtbl
= {
1513 PHControlSite_QueryInterface
,
1514 PHControlSite_AddRef
,
1515 PHControlSite_Release
,
1516 PHControlSite_OnControlInfoChanged
,
1517 PHControlSite_LockInPlaceActive
,
1518 PHControlSite_GetExtendedControl
,
1519 PHControlSite_TransformCoords
,
1520 PHControlSite_TranslateAccelerator
,
1521 PHControlSite_OnFocus
,
1522 PHControlSite_ShowPropertyFrame
1525 static inline PluginHost
*impl_from_IBindHost(IBindHost
*iface
)
1527 return CONTAINING_RECORD(iface
, PluginHost
, IBindHost_iface
);
1530 static HRESULT WINAPI
PHBindHost_QueryInterface(IBindHost
*iface
, REFIID riid
, void **ppv
)
1532 PluginHost
*This
= impl_from_IBindHost(iface
);
1533 return IOleClientSite_QueryInterface(&This
->IOleClientSite_iface
, riid
, ppv
);
1536 static ULONG WINAPI
PHBindHost_AddRef(IBindHost
*iface
)
1538 PluginHost
*This
= impl_from_IBindHost(iface
);
1539 return IOleClientSite_AddRef(&This
->IOleClientSite_iface
);
1542 static ULONG WINAPI
PHBindHost_Release(IBindHost
*iface
)
1544 PluginHost
*This
= impl_from_IBindHost(iface
);
1545 return IOleClientSite_Release(&This
->IOleClientSite_iface
);
1548 static HRESULT WINAPI
PHBindHost_CreateMoniker(IBindHost
*iface
, LPOLESTR szName
, IBindCtx
*pBC
, IMoniker
**ppmk
, DWORD dwReserved
)
1550 PluginHost
*This
= impl_from_IBindHost(iface
);
1552 TRACE("(%p)->(%s %p %p %x)\n", This
, debugstr_w(szName
), pBC
, ppmk
, dwReserved
);
1554 if(!This
->doc
|| !This
->doc
->window
|| !This
->doc
->window
->mon
) {
1555 FIXME("no moniker\n");
1556 return E_UNEXPECTED
;
1559 return CreateURLMoniker(This
->doc
->window
->mon
, szName
, ppmk
);
1562 static HRESULT WINAPI
PHBindHost_MonikerBindToStorage(IBindHost
*iface
, IMoniker
*pMk
, IBindCtx
*pBC
,
1563 IBindStatusCallback
*pBSC
, REFIID riid
, void **ppvObj
)
1565 PluginHost
*This
= impl_from_IBindHost(iface
);
1566 FIXME("(%p)->(%p %p %p %s %p)\n", This
, pMk
, pBC
, pBSC
, debugstr_guid(riid
), ppvObj
);
1570 static HRESULT WINAPI
PHBindHost_MonikerBindToObject(IBindHost
*iface
, IMoniker
*pMk
, IBindCtx
*pBC
,
1571 IBindStatusCallback
*pBSC
, REFIID riid
, void **ppvObj
)
1573 PluginHost
*This
= impl_from_IBindHost(iface
);
1574 FIXME("(%p)->(%p %p %p %s %p)\n", This
, pMk
, pBC
, pBSC
, debugstr_guid(riid
), ppvObj
);
1578 static const IBindHostVtbl BindHostVtbl
= {
1579 PHBindHost_QueryInterface
,
1582 PHBindHost_CreateMoniker
,
1583 PHBindHost_MonikerBindToStorage
,
1584 PHBindHost_MonikerBindToObject
1587 static inline PluginHost
*impl_from_IServiceProvider(IServiceProvider
*iface
)
1589 return CONTAINING_RECORD(iface
, PluginHost
, IServiceProvider_iface
);
1592 static HRESULT WINAPI
PHServiceProvider_QueryInterface(IServiceProvider
*iface
, REFIID riid
, void **ppv
)
1594 PluginHost
*This
= impl_from_IServiceProvider(iface
);
1595 return IOleClientSite_QueryInterface(&This
->IOleClientSite_iface
, riid
, ppv
);
1598 static ULONG WINAPI
PHServiceProvider_AddRef(IServiceProvider
*iface
)
1600 PluginHost
*This
= impl_from_IServiceProvider(iface
);
1601 return IOleClientSite_AddRef(&This
->IOleClientSite_iface
);
1604 static ULONG WINAPI
PHServiceProvider_Release(IServiceProvider
*iface
)
1606 PluginHost
*This
= impl_from_IServiceProvider(iface
);
1607 return IOleClientSite_Release(&This
->IOleClientSite_iface
);
1610 static HRESULT WINAPI
PHServiceProvider_QueryService(IServiceProvider
*iface
, REFGUID guidService
, REFIID riid
, void **ppv
)
1612 PluginHost
*This
= impl_from_IServiceProvider(iface
);
1614 if(IsEqualGUID(guidService
, &SID_SBindHost
)) {
1615 TRACE("SID_SBindHost service\n");
1616 return IOleClientSite_QueryInterface(&This
->IOleClientSite_iface
, riid
, ppv
);
1619 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
1621 if(!This
->doc
|| !This
->doc
->basedoc
.window
) {
1623 return E_NOINTERFACE
;
1626 return IServiceProvider_QueryService(&This
->doc
->basedoc
.window
->base
.IServiceProvider_iface
,
1627 guidService
, riid
, ppv
);
1630 static const IServiceProviderVtbl ServiceProviderVtbl
= {
1631 PHServiceProvider_QueryInterface
,
1632 PHServiceProvider_AddRef
,
1633 PHServiceProvider_Release
,
1634 PHServiceProvider_QueryService
1637 static HRESULT
assoc_element(PluginHost
*host
, HTMLDocumentNode
*doc
, nsIDOMElement
*nselem
)
1639 HTMLPluginContainer
*container_elem
;
1643 hres
= get_node(doc
, (nsIDOMNode
*)nselem
, TRUE
, &node
);
1647 hres
= IHTMLDOMNode_QueryInterface(&node
->IHTMLDOMNode_iface
, &IID_HTMLPluginContainer
,
1648 (void**)&container_elem
);
1651 ERR("Not an object element\n");
1655 container_elem
->plugin_host
= host
;
1656 host
->element
= container_elem
;
1660 void detach_plugin_host(PluginHost
*host
)
1664 TRACE("%p\n", host
);
1669 if(host
->ip_object
) {
1671 IOleInPlaceObject_UIDeactivate(host
->ip_object
);
1672 IOleInPlaceObject_InPlaceDeactivate(host
->ip_object
);
1675 if(host
->plugin_unk
) {
1676 IOleObject
*ole_obj
;
1678 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IOleObject
, (void**)&ole_obj
);
1679 if(SUCCEEDED(hres
)) {
1680 if(!host
->ip_object
)
1681 IOleObject_Close(ole_obj
, OLECLOSE_NOSAVE
);
1682 IOleObject_SetClientSite(ole_obj
, NULL
);
1683 IOleObject_Release(ole_obj
);
1688 IConnectionPointContainer
*cp_container
;
1689 IConnectionPoint
*cp
;
1691 assert(host
->plugin_unk
!= NULL
);
1693 hres
= IUnknown_QueryInterface(host
->plugin_unk
, &IID_IConnectionPointContainer
, (void**)&cp_container
);
1694 if(SUCCEEDED(hres
)) {
1695 hres
= IConnectionPointContainer_FindConnectionPoint(cp_container
, &host
->sink
->iid
, &cp
);
1696 IConnectionPointContainer_Release(cp_container
);
1697 if(SUCCEEDED(hres
)) {
1698 IConnectionPoint_Unadvise(cp
, host
->sink
->cookie
);
1699 IConnectionPoint_Release(cp
);
1703 host
->sink
->host
= NULL
;
1704 IDispatch_Release(&host
->sink
->IDispatch_iface
);
1708 release_plugin_ifaces(host
);
1711 host
->element
->plugin_host
= NULL
;
1712 host
->element
= NULL
;
1715 list_remove(&host
->entry
);
1716 list_init(&host
->entry
);
1720 HRESULT
create_plugin_host(HTMLDocumentNode
*doc
, nsIDOMElement
*nselem
, IUnknown
*unk
, const CLSID
*clsid
, PluginHost
**ret
)
1725 host
= heap_alloc_zero(sizeof(*host
));
1727 return E_OUTOFMEMORY
;
1729 host
->IOleClientSite_iface
.lpVtbl
= &OleClientSiteVtbl
;
1730 host
->IAdviseSinkEx_iface
.lpVtbl
= &AdviseSinkExVtbl
;
1731 host
->IPropertyNotifySink_iface
.lpVtbl
= &PropertyNotifySinkVtbl
;
1732 host
->IDispatch_iface
.lpVtbl
= &DispatchVtbl
;
1733 host
->IOleInPlaceSiteEx_iface
.lpVtbl
= &OleInPlaceSiteExVtbl
;
1734 host
->IOleControlSite_iface
.lpVtbl
= &OleControlSiteVtbl
;
1735 host
->IBindHost_iface
.lpVtbl
= &BindHostVtbl
;
1736 host
->IServiceProvider_iface
.lpVtbl
= &ServiceProviderVtbl
;
1740 hres
= assoc_element(host
, doc
, nselem
);
1746 IUnknown_AddRef(unk
);
1747 host
->plugin_unk
= unk
;
1748 host
->clsid
= *clsid
;
1751 list_add_tail(&doc
->plugin_hosts
, &host
->entry
);