mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 09:57:19 +00:00
mshtml: Hold ref to HTMLDocumentObj when calling external code.
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>
This commit is contained in:
parent
ff64d67f76
commit
a62be201c8
|
@ -854,6 +854,7 @@ static HRESULT WINAPI HTMLDocument_get_scripts(IHTMLDocument2 *iface, IHTMLEleme
|
|||
static HRESULT WINAPI HTMLDocument_put_designMode(IHTMLDocument2 *iface, BSTR v)
|
||||
{
|
||||
HTMLDocumentNode *This = impl_from_IHTMLDocument2(iface);
|
||||
HTMLDocumentObj *doc_obj;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
|
||||
|
@ -863,7 +864,10 @@ static HRESULT WINAPI HTMLDocument_put_designMode(IHTMLDocument2 *iface, BSTR v)
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
hres = setup_edit_mode(This->doc_obj);
|
||||
doc_obj = This->doc_obj;
|
||||
IUnknown_AddRef(doc_obj->outer_unk);
|
||||
hres = setup_edit_mode(doc_obj);
|
||||
IUnknown_Release(doc_obj->outer_unk);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
|
|
@ -291,17 +291,21 @@ static void parse_complete(HTMLDocumentObj *doc)
|
|||
|
||||
static nsresult run_end_load(HTMLDocumentNode *This, nsISupports *arg1, nsISupports *arg2)
|
||||
{
|
||||
HTMLDocumentObj *doc_obj = This->doc_obj;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
if(!This->doc_obj)
|
||||
if(!doc_obj)
|
||||
return NS_OK;
|
||||
|
||||
if(This == This->doc_obj->doc_node) {
|
||||
if(This == doc_obj->doc_node) {
|
||||
/*
|
||||
* This should be done in the worker thread that parses HTML,
|
||||
* but we don't have such thread (Gecko parses HTML for us).
|
||||
*/
|
||||
parse_complete(This->doc_obj);
|
||||
IUnknown_AddRef(doc_obj->outer_unk);
|
||||
parse_complete(doc_obj);
|
||||
IUnknown_Release(doc_obj->outer_unk);
|
||||
}
|
||||
|
||||
bind_event_scripts(This);
|
||||
|
|
|
@ -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(window->browser->doc, 0);
|
||||
set_download_state(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;
|
||||
|
@ -2209,6 +2228,7 @@ static HRESULT navigate_fragment(HTMLOuterWindow *window, IUri *uri)
|
|||
|
||||
HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, DWORD flags, const WCHAR *headers, BYTE *post_data, DWORD post_data_size)
|
||||
{
|
||||
HTMLDocumentObj *doc_obj;
|
||||
nsChannelBSC *bsc;
|
||||
IUri *uri_nofrag;
|
||||
IMoniker *mon;
|
||||
|
@ -2219,10 +2239,13 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, DWORD flags, const WC
|
|||
if(!uri_nofrag)
|
||||
return E_FAIL;
|
||||
|
||||
if(window->browser->doc->client && !(flags & BINDING_REFRESH)) {
|
||||
doc_obj = window->browser->doc;
|
||||
IUnknown_AddRef(doc_obj->outer_unk);
|
||||
|
||||
if(doc_obj->client && !(flags & BINDING_REFRESH)) {
|
||||
IOleCommandTarget *cmdtrg;
|
||||
|
||||
hres = IOleClientSite_QueryInterface(window->browser->doc->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
|
||||
hres = IOleClientSite_QueryInterface(doc_obj->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
|
||||
if(SUCCEEDED(hres)) {
|
||||
VARIANT in, out;
|
||||
BSTR url_str;
|
||||
|
@ -2249,14 +2272,15 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, DWORD flags, const WC
|
|||
if(SUCCEEDED(hres) && eq) {
|
||||
IUri_Release(uri_nofrag);
|
||||
TRACE("fragment navigate\n");
|
||||
return navigate_fragment(window, uri);
|
||||
hres = navigate_fragment(window, uri);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
hres = CreateURLMonikerEx2(NULL, uri_nofrag, &mon, URL_MK_UNIFORM);
|
||||
IUri_Release(uri_nofrag);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
goto done;
|
||||
|
||||
/* FIXME: Why not set_ready_state? */
|
||||
window->readystate = READYSTATE_UNINITIALIZED;
|
||||
|
@ -2264,10 +2288,10 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, DWORD flags, const WC
|
|||
hres = create_channelbsc(mon, headers, post_data, post_data_size, TRUE, &bsc);
|
||||
if(FAILED(hres)) {
|
||||
IMoniker_Release(mon);
|
||||
return hres;
|
||||
goto done;
|
||||
}
|
||||
|
||||
prepare_for_binding(window->browser->doc, mon, flags);
|
||||
prepare_for_binding(doc_obj, mon, flags);
|
||||
|
||||
hres = IUri_GetScheme(uri, &scheme);
|
||||
if(hres == S_OK && scheme == URL_SCHEME_JAVASCRIPT) {
|
||||
|
@ -2277,13 +2301,15 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, DWORD flags, const WC
|
|||
IMoniker_Release(mon);
|
||||
|
||||
task = malloc(sizeof(*task));
|
||||
if(!task)
|
||||
return E_OUTOFMEMORY;
|
||||
if(!task) {
|
||||
hres = E_OUTOFMEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Why silently? */
|
||||
window->readystate = READYSTATE_COMPLETE;
|
||||
if(!(flags & BINDING_FROMHIST))
|
||||
call_docview_84(window->browser->doc);
|
||||
call_docview_84(doc_obj);
|
||||
|
||||
IUri_AddRef(uri);
|
||||
task->window = window;
|
||||
|
@ -2302,13 +2328,14 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, DWORD flags, const WC
|
|||
if(!task) {
|
||||
IBindStatusCallback_Release(&bsc->bsc.IBindStatusCallback_iface);
|
||||
IMoniker_Release(mon);
|
||||
return E_OUTOFMEMORY;
|
||||
hres = E_OUTOFMEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Silently and repeated when real loading starts? */
|
||||
window->readystate = READYSTATE_LOADING;
|
||||
if(!(flags & (BINDING_FROMHIST|BINDING_REFRESH)))
|
||||
call_docview_84(window->browser->doc);
|
||||
call_docview_84(doc_obj);
|
||||
|
||||
task->window = window;
|
||||
task->bscallback = bsc;
|
||||
|
@ -2320,6 +2347,8 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, DWORD flags, const WC
|
|||
hres = push_task(&task->header, navigate_proc, navigate_task_destr, window->task_magic);
|
||||
}
|
||||
|
||||
done:
|
||||
IUnknown_Release(doc_obj->outer_unk);
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -687,12 +687,19 @@ static HRESULT exec_browsemode(HTMLDocumentNode *doc, DWORD cmdexecopt, VARIANT
|
|||
|
||||
static HRESULT exec_editmode(HTMLDocumentNode *doc, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
|
||||
{
|
||||
HTMLDocumentObj *doc_obj;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%08lx %p %p)\n", doc, cmdexecopt, in, out);
|
||||
|
||||
if(in || out)
|
||||
FIXME("unsupported args\n");
|
||||
|
||||
return setup_edit_mode(doc->browser->doc);
|
||||
doc_obj = doc->browser->doc;
|
||||
IUnknown_AddRef(doc_obj->outer_unk);
|
||||
hres = setup_edit_mode(doc_obj);
|
||||
IUnknown_Release(doc_obj->outer_unk);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT exec_htmleditmode(HTMLDocumentNode *doc, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
|
||||
|
|
|
@ -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)
|
||||
|
@ -341,16 +349,12 @@ HRESULT set_moniker(HTMLOuterWindow *window, IMoniker *mon, IUri *nav_uri, IBind
|
|||
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 +405,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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue