From: Gabriel Ivăncescu gabrielopcode@gmail.com
It's possible for it (and the GeckoBrowser) to get detached and destroyed while processing an external callback notification.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/editor.c | 10 +++++++--- dlls/mshtml/mutation.c | 3 +++ dlls/mshtml/navigate.c | 43 ++++++++++++++++++++++++++++++------------ dlls/mshtml/nsevents.c | 15 +++++++++------ dlls/mshtml/nsio.c | 11 +++++++++-- dlls/mshtml/persist.c | 22 +++++++++++++++------ dlls/mshtml/view.c | 3 +++ 7 files changed, 78 insertions(+), 29 deletions(-)
diff --git a/dlls/mshtml/editor.c b/dlls/mshtml/editor.c index 478c30932c1..b478bfdebf6 100644 --- a/dlls/mshtml/editor.c +++ b/dlls/mshtml/editor.c @@ -1195,6 +1195,7 @@ HRESULT setup_edit_mode(HTMLDocumentObj *doc) return S_OK;
doc->nscontainer->usermode = EDITMODE; + IUnknown_AddRef(doc->outer_unk);
if(doc->window->mon) { CLSID clsid = IID_NULL; @@ -1250,14 +1251,14 @@ HRESULT setup_edit_mode(HTMLDocumentObj *doc) hres = CreateURLMoniker(NULL, L"about:blank", &mon); if(FAILED(hres)) { FIXME("CreateURLMoniker failed: %08lx\n", hres); - return hres; + goto done; } }
hres = IPersistMoniker_Load(&doc->IPersistMoniker_iface, TRUE, mon, NULL, 0); IMoniker_Release(mon); if(FAILED(hres)) - return hres; + goto done;
if(doc->ui_active) { if(doc->ip_window) @@ -1281,6 +1282,9 @@ HRESULT setup_edit_mode(HTMLDocumentObj *doc) if(doc->frame) IOleInPlaceFrame_SetBorderSpace(doc->frame, &rcBorderWidths); } + hres = S_OK;
- return S_OK; +done: + IUnknown_Release(doc->outer_unk); + return hres; } diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index e308c1af31b..79850447f64 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -295,6 +295,7 @@ static nsresult run_end_load(HTMLDocumentNode *This, nsISupports *arg1, nsISuppo
if(!This->doc_obj) return NS_OK; + IUnknown_AddRef(This->doc_obj->outer_unk);
if(This == This->doc_obj->doc_node) { /* @@ -308,6 +309,8 @@ static nsresult run_end_load(HTMLDocumentNode *This, nsISupports *arg1, nsISuppo
This->window->performance_timing->dom_interactive_time = get_time_stamp(); set_ready_state(This->outer_window, READYSTATE_INTERACTIVE); + + IUnknown_Release(This->doc_obj->outer_unk); return NS_OK; }
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index b8d7937f071..68fd8a796c0 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1651,6 +1651,7 @@ static void handle_extern_mime_navigation(nsChannelBSC *This) return;
doc_obj = This->bsc.window->base.outer_window->browser->doc; + IUnknown_AddRef(doc_obj->outer_unk);
hres = IOleClientSite_QueryInterface(doc_obj->client, &IID_IOleCommandTarget, (void**)&cmdtrg); if(SUCCEEDED(hres)) { @@ -1662,17 +1663,17 @@ static void handle_extern_mime_navigation(nsChannelBSC *This)
if(!doc_obj->webbrowser) { FIXME("unimplemented in non-webbrowser mode\n"); - return; + goto done; }
uri = get_moniker_uri(This->bsc.mon); if(!uri) - return; + goto done;
hres = CreateBindCtx(0, &bind_ctx); if(FAILED(hres)) { IUri_Release(uri); - return; + goto done; }
V_VT(&flags) = VT_I4; @@ -1701,6 +1702,9 @@ static void handle_extern_mime_navigation(nsChannelBSC *This) }
IUri_Release(uri); + +done: + IUnknown_Release(doc_obj->outer_unk); }
static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG progress, ULONG total, ULONG status_code, LPCWSTR status_text) @@ -2066,25 +2070,31 @@ static void navigate_javascript_proc(task_t *_task) { navigate_javascript_task_t *task = (navigate_javascript_task_t*)_task; HTMLOuterWindow *window = task->window; + HTMLDocumentObj *doc = NULL; BSTR code = NULL; VARIANT v; HRESULT hres;
- task->window->readystate = READYSTATE_COMPLETE; + window->readystate = READYSTATE_COMPLETE; + if(window->browser) { + doc = window->browser->doc; + IUnknown_AddRef(doc->outer_unk); + }
hres = IUri_GetPath(task->uri, &code); if(hres != S_OK) { SysFreeString(code); - return; + goto done; }
hres = UrlUnescapeW(code, NULL, NULL, URL_UNESCAPE_INPLACE); if(FAILED(hres)) { SysFreeString(code); - return; + goto done; }
- set_download_state(window->browser->doc, 1); + if(doc) + set_download_state(doc, 1);
V_VT(&v) = VT_EMPTY; hres = exec_script(window->base.inner_window, code, L"jscript", &v); @@ -2094,10 +2104,16 @@ static void navigate_javascript_proc(task_t *_task) VariantClear(&v); }
- if(window->browser->doc->view_sink) - IAdviseSink_OnViewChange(window->browser->doc->view_sink, DVASPECT_CONTENT, -1); + if(doc) { + if(doc->view_sink) + IAdviseSink_OnViewChange(doc->view_sink, DVASPECT_CONTENT, -1); + + set_download_state(doc, 0); + }
- set_download_state(window->browser->doc, 0); +done: + if(doc) + IUnknown_Release(doc->outer_unk); }
static void navigate_javascript_task_destr(task_t *_task) @@ -2199,9 +2215,12 @@ static HRESULT navigate_fragment(HTMLOuterWindow *window, IUri *uri) SysFreeString(frag);
if(window->browser->doc->doc_object_service) { - IDocObjectService_FireNavigateComplete2(window->browser->doc->doc_object_service, &window->base.IHTMLWindow2_iface, 0x10); - IDocObjectService_FireDocumentComplete(window->browser->doc->doc_object_service, &window->base.IHTMLWindow2_iface, 0); + HTMLDocumentObj *doc_obj = window->browser->doc;
+ IUnknown_AddRef(doc_obj->outer_unk); + IDocObjectService_FireNavigateComplete2(doc_obj->doc_object_service, &window->base.IHTMLWindow2_iface, 0x10); + IDocObjectService_FireDocumentComplete(doc_obj->doc_object_service, &window->base.IHTMLWindow2_iface, 0); + IUnknown_Release(doc_obj->outer_unk); }
return S_OK; diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index b3616b64964..177981acc25 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -339,9 +339,10 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event)
if(!doc->outer_window) return NS_ERROR_FAILURE; - if(doc->doc_obj && doc->doc_obj->doc_node == doc) + if(doc->doc_obj && doc->doc_obj->doc_node == doc) { doc_obj = doc->doc_obj; - + IUnknown_AddRef(doc_obj->outer_unk); + } connect_scripts(doc->window);
if(doc_obj) @@ -357,11 +358,13 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event) set_statustext(doc_obj, IDS_STATUS_DONE, NULL);
update_title(doc_obj); - }
- if(doc_obj && doc_obj->doc_object_service && !(doc->outer_window->load_flags & BINDING_REFRESH)) - IDocObjectService_FireDocumentComplete(doc_obj->doc_object_service, - &doc->outer_window->base.IHTMLWindow2_iface, 0); + if(doc_obj->doc_object_service && !(doc->outer_window->load_flags & BINDING_REFRESH)) + IDocObjectService_FireDocumentComplete(doc_obj->doc_object_service, + &doc->outer_window->base.IHTMLWindow2_iface, 0); + + IUnknown_Release(doc_obj->outer_unk); + }
doc->window->performance_timing->load_event_start_time = get_time_stamp();
diff --git a/dlls/mshtml/nsio.c b/dlls/mshtml/nsio.c index 509a83efbd3..d29bb43544e 100644 --- a/dlls/mshtml/nsio.c +++ b/dlls/mshtml/nsio.c @@ -217,6 +217,9 @@ static BOOL exec_shldocvw_67(HTMLDocumentObj *doc, BSTR url) IOleCommandTarget *cmdtrg = NULL; HRESULT hres;
+ if(!doc->client) + return TRUE; + hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&cmdtrg); if(SUCCEEDED(hres)) { VARIANT varUrl, varRes; @@ -252,6 +255,7 @@ static nsresult before_async_open(nsChannel *channel, GeckoBrowser *container, B hres = IUri_GetDisplayUri(channel->uri->uri, &display_uri); if(FAILED(hres)) return NS_ERROR_FAILURE; + IUnknown_AddRef(doc->outer_unk);
if(doc->hostui) { OLECHAR *new_url; @@ -261,7 +265,7 @@ static nsresult before_async_open(nsChannel *channel, GeckoBrowser *container, B FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(display_uri), debugstr_w(new_url)); CoTaskMemFree(new_url); *cancel = TRUE; - return NS_OK; + goto done; } CoTaskMemFree(new_url); } @@ -270,13 +274,16 @@ static nsresult before_async_open(nsChannel *channel, GeckoBrowser *container, B if(!exec_shldocvw_67(doc, display_uri)) { SysFreeString(display_uri); *cancel = FALSE; - return NS_OK; + goto done; }
hres = hlink_frame_navigate(doc, display_uri, channel, 0, cancel); SysFreeString(display_uri); if(FAILED(hres)) *cancel = TRUE; + +done: + IUnknown_Release(doc->outer_unk); return NS_OK; }
diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c index 486643d8b21..94b52e3a476 100644 --- a/dlls/mshtml/persist.c +++ b/dlls/mshtml/persist.c @@ -208,6 +208,8 @@ static void set_progress_proc(task_t *_task)
TRACE("(%p)\n", doc);
+ IUnknown_AddRef(doc->outer_unk); + if(doc->client) IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd);
@@ -238,6 +240,8 @@ static void set_progress_proc(task_t *_task) hostinfo.cbSize, hostinfo.dwFlags, hostinfo.dwDoubleClick, debugstr_w(hostinfo.pchHostCss), debugstr_w(hostinfo.pchHostNS)); } + + IUnknown_Release(doc->outer_unk); }
static void set_progress_destr(task_t *_task) @@ -252,13 +256,14 @@ static void set_downloading_proc(task_t *_task)
TRACE("(%p)\n", doc);
+ IUnknown_AddRef(doc->outer_unk); set_statustext(doc, IDS_STATUS_DOWNLOADINGFROM, task->url);
if(task->set_download) set_download_state(doc, 1);
if(!doc->client) - return; + goto done;
if(doc->view_sink) IAdviseSink_OnViewChange(doc->view_sink, DVASPECT_CONTENT, -1); @@ -272,6 +277,9 @@ static void set_downloading_proc(task_t *_task) IDropTarget_Release(drop_target); } } + +done: + IUnknown_Release(doc->outer_unk); }
static void set_downloading_task_destr(task_t *_task) @@ -285,6 +293,8 @@ void prepare_for_binding(HTMLDocumentObj *This, IMoniker *mon, DWORD flags) { HRESULT hres;
+ IUnknown_AddRef(This->outer_unk); + if(This->client) { VARIANT silent, offline;
@@ -335,22 +345,20 @@ void prepare_for_binding(HTMLDocumentObj *This, IMoniker *mon, DWORD flags) IOleCommandTarget_Release(cmdtrg); } } + + IUnknown_Release(This->outer_unk); }
HRESULT set_moniker(HTMLOuterWindow *window, IMoniker *mon, IUri *nav_uri, IBindCtx *pibc, nsChannelBSC *async_bsc, BOOL set_download) { download_proc_task_t *download_task; - HTMLDocumentObj *doc_obj = NULL; nsChannelBSC *bscallback; nsWineURI *nsuri; LPOLESTR url; IUri *uri; HRESULT hres;
- if(is_main_content_window(window)) - doc_obj = window->browser->doc; - hres = IMoniker_GetDisplayName(mon, pibc, NULL, &url); if(FAILED(hres)) { WARN("GetDisplayName failed: %08lx\n", hres); @@ -401,7 +409,9 @@ HRESULT set_moniker(HTMLOuterWindow *window, IMoniker *mon, IUri *nav_uri, IBind return hres; }
- if(doc_obj) { + if(is_main_content_window(window)) { + HTMLDocumentObj *doc_obj = window->browser->doc; + HTMLDocument_LockContainer(doc_obj, TRUE);
if(doc_obj->frame) { diff --git a/dlls/mshtml/view.c b/dlls/mshtml/view.c index 6b7ecb0bc27..346fccf4955 100644 --- a/dlls/mshtml/view.c +++ b/dlls/mshtml/view.c @@ -117,6 +117,7 @@ static LRESULT on_timer(HTMLDocumentObj *This)
if(!This->update) return 0; + IUnknown_AddRef(This->outer_unk);
if(This->update & UPDATE_UI) { if(This->hostui) @@ -138,6 +139,8 @@ static LRESULT on_timer(HTMLDocumentObj *This)
update_title(This); This->update = 0; + + IUnknown_Release(This->outer_unk); return 0; }