From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmllocation.c | 50 +++++++++++++++++++++++++----------- dlls/mshtml/htmlwindow.c | 32 +++++++++++++++-------- dlls/mshtml/mshtml_private.h | 8 ++++-- 3 files changed, 62 insertions(+), 28 deletions(-)
diff --git a/dlls/mshtml/htmllocation.c b/dlls/mshtml/htmllocation.c index d9e458d9c5f..c361df7d85e 100644 --- a/dlls/mshtml/htmllocation.c +++ b/dlls/mshtml/htmllocation.c @@ -36,19 +36,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
-static inline HTMLOuterWindow *get_window(HTMLLocation *This) -{ - return CONTAINING_RECORD(This, HTMLOuterWindow, location); -} - static IUri *get_uri(HTMLLocation *This) { - return get_window(This)->uri; + return This->window->uri; }
static HRESULT get_url_components(HTMLLocation *This, URL_COMPONENTSW *url) { - const WCHAR *doc_url = get_window(This)->url ? get_window(This)->url : L"about:blank"; + const WCHAR *doc_url = This->window->url ? This->window->url : L"about:blank";
if(!InternetCrackUrlW(doc_url, 0, 0, url)) { FIXME("InternetCrackUrlW failed: 0x%08lx\n", GetLastError()); @@ -93,13 +88,27 @@ static HRESULT WINAPI HTMLLocation_QueryInterface(IHTMLLocation *iface, REFIID r static ULONG WINAPI HTMLLocation_AddRef(IHTMLLocation *iface) { HTMLLocation *This = impl_from_IHTMLLocation(iface); - return IHTMLWindow2_AddRef(&get_window(This)->base.IHTMLWindow2_iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + return ref; }
static ULONG WINAPI HTMLLocation_Release(IHTMLLocation *iface) { HTMLLocation *This = impl_from_IHTMLLocation(iface); - return IHTMLWindow2_Release(&get_window(This)->base.IHTMLWindow2_iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + if(!ref) { + IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); + release_dispex(&This->dispex); + free(This); + } + + return ref; }
static HRESULT WINAPI HTMLLocation_GetTypeInfoCount(IHTMLLocation *iface, UINT *pctinfo) @@ -139,7 +148,7 @@ static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
- return navigate_url(get_window(This), v, get_uri(This), BINDING_NAVIGATED); + return navigate_url(This->window, v, get_uri(This), BINDING_NAVIGATED); }
static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p) @@ -500,7 +509,7 @@ static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v) memcpy(hash + 1, v, size - sizeof(WCHAR)); }
- hres = navigate_url(get_window(This), hash, get_uri(This), BINDING_NAVIGATED); + hres = navigate_url(This->window, hash, get_uri(This), BINDING_NAVIGATED);
if(hash != v) free(hash); @@ -544,12 +553,12 @@ static HRESULT WINAPI HTMLLocation_reload(IHTMLLocation *iface, VARIANT_BOOL fla TRACE("(%p)->(%x)\n", This, flag);
/* reload is supposed to fail if called from a script with different origin, but IE doesn't care */ - if(!is_main_content_window(get_window(This))) { + if(!is_main_content_window(This->window)) { FIXME("Unsupported on iframe\n"); return E_NOTIMPL; }
- return reload_page(get_window(This)); + return reload_page(This->window); }
static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr) @@ -558,7 +567,7 @@ static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr)
TRACE("(%p)->(%s)\n", This, debugstr_w(bstr));
- return navigate_url(get_window(This), bstr, get_uri(This), BINDING_NAVIGATED | BINDING_REPLACE); + return navigate_url(This->window, bstr, get_uri(This), BINDING_NAVIGATED | BINDING_REPLACE); }
static HRESULT WINAPI HTMLLocation_assign(IHTMLLocation *iface, BSTR bstr) @@ -618,10 +627,21 @@ static dispex_static_data_t HTMLLocation_dispex = { HTMLLocation_iface_tids };
-void HTMLLocation_Init(HTMLLocation *location) +HRESULT create_location(HTMLOuterWindow *window, HTMLLocation **ret) { + HTMLLocation *location; + + if(!(location = calloc(1, sizeof(*location)))) + return E_OUTOFMEMORY; + location->IHTMLLocation_iface.lpVtbl = &HTMLLocationVtbl; + location->ref = 1; + location->window = window; + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
init_dispatch(&location->dispex, (IUnknown*)&location->IHTMLLocation_iface, &HTMLLocation_dispex, COMPAT_MODE_QUIRKS); + + *ret = location; + return S_OK; } diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index c2e5b10b90a..ff9c5622ec7 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -67,13 +67,17 @@ static inline BOOL is_outer_window(HTMLWindow *window) return &window->outer_window->base == window; }
-static void get_location(HTMLOuterWindow *This, HTMLLocation **ret) +static HRESULT get_location(HTMLOuterWindow *This, HTMLLocation **ret) { - if(!This->location.dispex.outer) - HTMLLocation_Init(&This->location); + if(!This->location) { + HRESULT hres = create_location(This, &This->location); + if(FAILED(hres)) + return hres; + }
- IHTMLLocation_AddRef(&This->location.IHTMLLocation_iface); - *ret = &This->location; + IHTMLLocation_AddRef(&This->location->IHTMLLocation_iface); + *ret = This->location; + return S_OK; }
void get_top_window(HTMLOuterWindow *window, HTMLOuterWindow **ret) @@ -127,8 +131,8 @@ static void detach_inner_window(HTMLInnerWindow *window) if(doc) detach_document_node(doc);
- if(outer_window && outer_window->location.dispex.outer) - dispex_unlink(&outer_window->location.dispex); + if(outer_window && outer_window->location) + dispex_unlink(&outer_window->location->dispex);
abort_window_bindings(window); remove_target_tasks(window->task_magic); @@ -234,8 +238,8 @@ static void release_outer_window(HTMLOuterWindow *This) if(This->base.inner_window) detach_inner_window(This->base.inner_window);
- if(This->location.dispex.outer) - release_dispex(&This->location.dispex); + if(This->location) + IHTMLLocation_Release(&This->location->IHTMLLocation_iface);
if(This->frame_element) This->frame_element->content_window = NULL; @@ -799,10 +803,14 @@ static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocatio { HTMLWindow *This = impl_from_IHTMLWindow2(iface); HTMLLocation *location; + HRESULT hres;
TRACE("(%p)->(%p)\n", This, p);
- get_location(This->outer_window, &location); + hres = get_location(This->outer_window, &location); + if(FAILED(hres)) + return hres; + *p = &location->IHTMLLocation_iface; return S_OK; } @@ -3920,7 +3928,9 @@ static HRESULT IHTMLWindow2_location_hook(DispatchEx *dispex, WORD flags, DISPPA
TRACE("forwarding to location.href\n");
- get_location(This->base.outer_window, &location); + hres = get_location(This->base.outer_window, &location); + if(FAILED(hres)) + return hres;
hres = IDispatchEx_InvokeEx(&location->dispex.IDispatchEx_iface, DISPID_VALUE, 0, flags, dp, res, ei, caller); IHTMLLocation_Release(&location->IHTMLLocation_iface); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 87c3c062483..7987f964ef9 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -491,6 +491,10 @@ typedef struct { struct HTMLLocation { DispatchEx dispex; IHTMLLocation IHTMLLocation_iface; + + LONG ref; + + HTMLOuterWindow *window; };
typedef struct { @@ -546,7 +550,7 @@ struct HTMLOuterWindow { BOOL readystate_pending;
HTMLInnerWindow *pending_window; - HTMLLocation location; + HTMLLocation *location; IMoniker *mon; IUri *uri; IUri *uri_nofrag; @@ -982,7 +986,7 @@ void get_top_window(HTMLOuterWindow*,HTMLOuterWindow**); HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow*,HTMLOptionElementFactory**); HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow*,HTMLImageElementFactory**); HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow*,HTMLXMLHttpRequestFactory**); -void HTMLLocation_Init(HTMLLocation*); +HRESULT create_location(HTMLOuterWindow*,HTMLLocation**); HRESULT create_navigator(compat_mode_t,IOmNavigator**); HRESULT create_html_screen(compat_mode_t,IHTMLScreen**); HRESULT create_performance(HTMLInnerWindow*,IHTMLPerformance**);