From b3fb1b0408832b7c535cf9e74f6ce3819c4f0ec1 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Fri, 26 Apr 2013 15:47:54 +0200 Subject: [PATCH] mshtml: Support IObjectIdentity interface in HTMLWindow object. --- dlls/mshtml/htmlwindow.c | 55 ++++++++++++++++++++++++++++++++++++ dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/tests/dom.c | 48 +++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 28c071e124..5c40f4157d 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -174,6 +174,9 @@ static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID rii }else if(IsEqualGUID(&IID_ITravelLogClient, riid)) { TRACE("(%p)->(IID_ITravelLogClient %p)\n", This, ppv); *ppv = &This->ITravelLogClient_iface; + }else if(IsEqualGUID(&IID_IObjectIdentity, riid)) { + TRACE("(%p)->(IID_IObjectIdentity %p)\n", This, ppv); + *ppv = &This->IObjectIdentity_iface; }else if(dispex_query_interface(&This->inner_window->dispex, riid, ppv)) { assert(!*ppv); return E_NOINTERFACE; @@ -2295,6 +2298,57 @@ static const ITravelLogClientVtbl TravelLogClientVtbl = { TravelLogClient_LoadHistoryPosition }; +static inline HTMLWindow *impl_from_IObjectIdentity(IObjectIdentity *iface) +{ + return CONTAINING_RECORD(iface, HTMLWindow, IObjectIdentity_iface); +} + +static HRESULT WINAPI ObjectIdentity_QueryInterface(IObjectIdentity *iface, REFIID riid, void **ppv) +{ + HTMLWindow *This = impl_from_IObjectIdentity(iface); + + return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv); +} + +static ULONG WINAPI ObjectIdentity_AddRef(IObjectIdentity *iface) +{ + HTMLWindow *This = impl_from_IObjectIdentity(iface); + + return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface); +} + +static ULONG WINAPI ObjectIdentity_Release(IObjectIdentity *iface) +{ + HTMLWindow *This = impl_from_IObjectIdentity(iface); + + return IHTMLWindow2_Release(&This->IHTMLWindow2_iface); +} + +static HRESULT WINAPI ObjectIdentity_IsEqualObject(IObjectIdentity *iface, IUnknown *unk) +{ + HTMLWindow *This = impl_from_IObjectIdentity(iface); + IServiceProvider *sp; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, unk); + + hres = IUnknown_QueryInterface(unk, &IID_IServiceProvider, (void**)&sp); + if(hres != S_OK) + return hres; + + hres = &This->inner_window->base.IServiceProvider_iface==sp || + &This->outer_window->base.IServiceProvider_iface==sp ? S_OK : S_FALSE; + IServiceProvider_Release(sp); + return hres; +} + +static const IObjectIdentityVtbl ObjectIdentityVtbl = { + ObjectIdentity_QueryInterface, + ObjectIdentity_AddRef, + ObjectIdentity_Release, + ObjectIdentity_IsEqualObject +}; + static inline HTMLWindow *impl_from_IDispatchEx(IDispatchEx *iface) { return CONTAINING_RECORD(iface, HTMLWindow, IDispatchEx_iface); @@ -2793,6 +2847,7 @@ static void *alloc_window(size_t size) window->IDispatchEx_iface.lpVtbl = &WindowDispExVtbl; window->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl; window->ITravelLogClient_iface.lpVtbl = &TravelLogClientVtbl; + window->IObjectIdentity_iface.lpVtbl = &ObjectIdentityVtbl; window->ref = 1; return window; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 08c48ce242..421bf8a89b 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -365,6 +365,7 @@ struct HTMLWindow { IDispatchEx IDispatchEx_iface; IServiceProvider IServiceProvider_iface; ITravelLogClient ITravelLogClient_iface; + IObjectIdentity IObjectIdentity_iface; LONG ref; diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index ffb36144df..7228649e62 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -6966,12 +6966,37 @@ static void test_cond_comment(IHTMLDocument2 *doc) IHTMLElementCollection_Release(col); } +static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) +{ + ok(IsEqualGUID(riid, &IID_IServiceProvider), "riid = %s\n", dbgstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI Unknown_AddRef(IUnknown *iface) +{ + return 2; +} + +static ULONG WINAPI Unknown_Release(IUnknown *iface) +{ + return 1; +} + +static const IUnknownVtbl UnknownVtbl = { + Unknown_QueryInterface, + Unknown_AddRef, + Unknown_Release, +}; +static IUnknown obj_ident_test = { &UnknownVtbl }; + static void test_frame(IDispatch *disp, const char *exp_id) { IHTMLWindow2 *frame2, *parent, *top; IHTMLDocument2 *parent_doc, *top_doc; IHTMLWindow4 *frame; IHTMLFrameBase *frame_elem; + IObjectIdentity *obj_ident; + ITravelLogClient *tlc; HRESULT hres; hres = IDispatch_QueryInterface(disp, &IID_IHTMLWindow4, (void**)&frame); @@ -7002,6 +7027,29 @@ static void test_frame(IDispatch *disp, const char *exp_id) return; } + hres = IHTMLWindow2_QueryInterface(frame2, &IID_IObjectIdentity, (void**)&obj_ident); + ok(hres == S_OK, "Could not get IObjectIdentity interface: %08x\n", hres); + hres = IHTMLWindow2_QueryInterface(frame2, &IID_ITravelLogClient, (void**)&tlc); + if(hres == E_NOINTERFACE) { + win_skip("IID_ITravelLogClient not available\n"); + tlc = NULL; + }else { + ok(hres == S_OK, "Could not get ITravelLogClient interface: %08x\n", hres); + + hres = IObjectIdentity_IsEqualObject(obj_ident, (IUnknown*)tlc); + ok(hres == S_OK, "IsEqualObject returned: 0x%08x\n", hres); + ITravelLogClient_Release(tlc); + } + + hres = IObjectIdentity_IsEqualObject(obj_ident, (IUnknown*)obj_ident); + ok(hres == S_OK, "IsEqualObject returned: 0x%08x\n", hres); + hres = IObjectIdentity_IsEqualObject(obj_ident, (IUnknown*)parent); + ok(hres == S_FALSE, "IsEqualObject returned: 0x%08x\n", hres); + hres = IObjectIdentity_IsEqualObject(obj_ident, &obj_ident_test); + ok(hres == E_NOINTERFACE, "IsEqualObject returned: 0x%08x\n", hres); + + IObjectIdentity_Release(obj_ident); + hres = IHTMLWindow2_get_document(parent, &parent_doc); ok(hres == S_OK, "IHTMLWindow2_get_document failed: 0x%08x\n", hres); IHTMLWindow2_Release(parent); -- 2.32.0.93.g670b81a890