diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index a4c1451f0bc..7cfa2733f42 100644
--- a/dlls/mshtml/htmldoc.c
+++ b/dlls/mshtml/htmldoc.c
@@ -1898,9 +1898,11 @@ static void HTMLDocumentNode_destructor(HTMLDOMNode *iface)
detach_selection(This);
detach_ranges(This);
- detach_plugin_hosts(This);
release_nodes(This);
+ while(!list_empty(&This->plugin_hosts))
+ detach_plugin_host(LIST_ENTRY(list_head(&This->plugin_hosts), PluginHost, entry));
+
if(This->nsdoc) {
release_mutation(This);
nsIDOMHTMLDocument_Release(This->nsdoc);
diff --git a/dlls/mshtml/htmlobject.c b/dlls/mshtml/htmlobject.c
index c911dd8ae41..1cb8d60ce08 100644
--- a/dlls/mshtml/htmlobject.c
+++ b/dlls/mshtml/htmlobject.c
@@ -423,7 +423,7 @@ static void HTMLObjectElement_destructor(HTMLDOMNode *iface)
HTMLObjectElement *This = HTMLOBJECT_NODE_THIS(iface);
if(This->plugin_container.plugin_host)
- This->plugin_container.plugin_host->element = NULL;
+ detach_plugin_host(This->plugin_container.plugin_host);
if(This->nsobject)
nsIDOMHTMLObjectElement_Release(This->nsobject);
diff --git a/dlls/mshtml/npplugin.c b/dlls/mshtml/npplugin.c
index ad88da2530b..20a30abe9b9 100644
--- a/dlls/mshtml/npplugin.c
+++ b/dlls/mshtml/npplugin.c
@@ -296,6 +296,7 @@ static NPError CDECL NPP_Destroy(NPP instance, NPSavedData **save)
if(!host)
return NPERR_GENERIC_ERROR;
+ detach_plugin_host(host);
IOleClientSite_Release(&host->IOleClientSite_iface);
instance->pdata = NULL;
return NPERR_NO_ERROR;
diff --git a/dlls/mshtml/pluginhost.c b/dlls/mshtml/pluginhost.c
index 8a7e2a65c4e..bce884ee2fd 100644
--- a/dlls/mshtml/pluginhost.c
+++ b/dlls/mshtml/pluginhost.c
@@ -954,15 +954,37 @@ static HRESULT assoc_element(PluginHost *host, HTMLDocumentNode *doc, nsIDOMElem
return S_OK;
}
-void detach_plugin_hosts(HTMLDocumentNode *doc)
+void detach_plugin_host(PluginHost *host)
{
- PluginHost *iter;
+ HRESULT hres;
- while(!list_empty(&doc->plugin_hosts)) {
- iter = LIST_ENTRY(list_head(&doc->plugin_hosts), PluginHost, entry);
- list_remove(&iter->entry);
- iter->doc = NULL;
+ TRACE("%p\n", host);
+
+ if(!host->doc)
+ return;
+
+ if(host->ip_object)
+ IOleInPlaceObject_InPlaceDeactivate(host->ip_object);
+
+ if(host->plugin_unk) {
+ IOleObject *ole_obj;
+
+ hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IOleObject, (void**)&ole_obj);
+ if(SUCCEEDED(hres)) {
+ if(!host->ip_object)
+ IOleObject_Close(ole_obj, OLECLOSE_NOSAVE);
+ IOleObject_SetClientSite(ole_obj, NULL);
+ IOleObject_Release(ole_obj);
+ }
}
+
+ if(host->element) {
+ host->element->plugin_host = NULL;
+ host->element = NULL;
+ }
+
+ list_remove(&host->entry);
+ host->doc = NULL;
}
HRESULT create_plugin_host(HTMLDocumentNode *doc, nsIDOMElement *nselem, IUnknown *unk, const CLSID *clsid, PluginHost **ret)
diff --git a/dlls/mshtml/pluginhost.h b/dlls/mshtml/pluginhost.h
index 30af989f3ba..135b2a8d36e 100644
--- a/dlls/mshtml/pluginhost.h
+++ b/dlls/mshtml/pluginhost.h
@@ -52,6 +52,6 @@ extern const IID IID_HTMLPluginContainer;
HRESULT create_plugin_host(HTMLDocumentNode*,nsIDOMElement*,IUnknown*,const CLSID*,PluginHost**);
void update_plugin_window(PluginHost*,HWND,const RECT*);
-void detach_plugin_hosts(HTMLDocumentNode*);
+void detach_plugin_host(PluginHost*);
HRESULT create_param_prop_bag(nsIDOMHTMLElement*,IPropertyBag**);