From 00ee406ea6ec439dd0e9cf296caf3e7bc57b8f6d Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 8 Nov 2010 12:48:55 +0100 Subject: [PATCH] mshtml: Added IOmNavigator::get_plugins implementation. --- dlls/mshtml/dispex.c | 2 + dlls/mshtml/mshtml_private.h | 2 + dlls/mshtml/omnavigator.c | 174 ++++++++++++++++++++++++++++++++++- dlls/mshtml/tests/dom.c | 22 +++++ include/mshtml.idl | 22 ++++- 5 files changed, 219 insertions(+), 3 deletions(-) diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 65e6edb2a49..c63181f7979 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -85,6 +85,7 @@ static struct list dispex_data_list = LIST_INIT(dispex_data_list); static REFIID tid_ids[] = { &IID_NULL, &DIID_DispCEventObj, + &DIID_DispCPlugins, &DIID_DispDOMChildrenCollection, &DIID_DispHTMLAnchorElement, &DIID_DispHTMLBody, @@ -150,6 +151,7 @@ static REFIID tid_ids[] = { &IID_IHTMLLocation, &IID_IHTMLObjectElement, &IID_IHTMLOptionElement, + &IID_IHTMLPluginsCollection, &IID_IHTMLRect, &IID_IHTMLScreen, &IID_IHTMLScriptElement, diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index ce71586f137..be11bd4b881 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -67,6 +67,7 @@ typedef struct event_target_t event_target_t; typedef enum { NULL_tid, DispCEventObj_tid, + DispCPlugins_tid, DispDOMChildrenCollection_tid, DispHTMLAnchorElement_tid, DispHTMLBody_tid, @@ -132,6 +133,7 @@ typedef enum { IHTMLLocation_tid, IHTMLObjectElement_tid, IHTMLOptionElement_tid, + IHTMLPluginsCollection_tid, IHTMLRect_tid, IHTMLScreen_tid, IHTMLScriptElement_tid, diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index d127eef57f7..de4489b3756 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -31,15 +31,168 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); +typedef struct HTMLPluginsCollection HTMLPluginsCollection; + typedef struct { DispatchEx dispex; const IOmNavigatorVtbl *lpIOmNavigatorVtbl; LONG ref; + + HTMLPluginsCollection *plugins; } OmNavigator; + #define OMNAVIGATOR(x) ((IOmNavigator*) &(x)->lpIOmNavigatorVtbl) +struct HTMLPluginsCollection { + DispatchEx dispex; + const IHTMLPluginsCollectionVtbl *lpIHTMLPluginsCollectionVtbl; + + LONG ref; + + OmNavigator *navigator; +}; + +#define HTMLPLUGINSCOL(x) ((IHTMLPluginsCollection*) &(x)->lpIHTMLPluginsCollectionVtbl) + +#define HTMLPLUGINCOL_THIS(iface) DEFINE_THIS(HTMLPluginsCollection, IHTMLPluginsCollection, iface) + +static HRESULT WINAPI HTMLPluginsCollection_QueryInterface(IHTMLPluginsCollection *iface, REFIID riid, void **ppv) +{ + HTMLPluginsCollection *This = HTMLPLUGINCOL_THIS(iface); + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = HTMLPLUGINSCOL(This); + }else if(IsEqualGUID(&IID_IHTMLPluginsCollection, riid)) { + TRACE("(%p)->(IID_IHTMLPluginCollection %p)\n", This, ppv); + *ppv = HTMLPLUGINSCOL(This); + }else if(dispex_query_interface(&This->dispex, riid, ppv)) { + return *ppv ? S_OK : E_NOINTERFACE; + }else { + *ppv = NULL; + WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI HTMLPluginsCollection_AddRef(IHTMLPluginsCollection *iface) +{ + HTMLPluginsCollection *This = HTMLPLUGINCOL_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI HTMLPluginsCollection_Release(IHTMLPluginsCollection *iface) +{ + HTMLPluginsCollection *This = HTMLPLUGINCOL_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) { + if(This->navigator) + This->navigator->plugins = NULL; + release_dispex(&This->dispex); + heap_free(This); + } + + return ref; +} + +static HRESULT WINAPI HTMLPluginsCollection_GetTypeInfoCount(IHTMLPluginsCollection *iface, UINT *pctinfo) +{ + HTMLPluginsCollection *This = HTMLPLUGINCOL_THIS(iface); + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo); +} + +static HRESULT WINAPI HTMLPluginsCollection_GetTypeInfo(IHTMLPluginsCollection *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLPluginsCollection *This = HTMLPLUGINCOL_THIS(iface); + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLPluginsCollection_GetIDsOfNames(IHTMLPluginsCollection *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + HTMLPluginsCollection *This = HTMLPLUGINCOL_THIS(iface); + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId); +} + +static HRESULT WINAPI HTMLPluginsCollection_Invoke(IHTMLPluginsCollection *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLPluginsCollection *This = HTMLPLUGINCOL_THIS(iface); + return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLPluginsCollection_get_length(IHTMLPluginsCollection *iface, LONG *p) +{ + HTMLPluginsCollection *This = HTMLPLUGINCOL_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLPluginsCollection_refresh(IHTMLPluginsCollection *iface, VARIANT_BOOL reload) +{ + HTMLPluginsCollection *This = HTMLPLUGINCOL_THIS(iface); + FIXME("(%p)->(%x)\n", This, reload); + return E_NOTIMPL; +} + +#undef HTMLPLUGINSCOL_THIS + +static const IHTMLPluginsCollectionVtbl HTMLPluginsCollectionVtbl = { + HTMLPluginsCollection_QueryInterface, + HTMLPluginsCollection_AddRef, + HTMLPluginsCollection_Release, + HTMLPluginsCollection_GetTypeInfoCount, + HTMLPluginsCollection_GetTypeInfo, + HTMLPluginsCollection_GetIDsOfNames, + HTMLPluginsCollection_Invoke, + HTMLPluginsCollection_get_length, + HTMLPluginsCollection_refresh +}; + +static const tid_t HTMLPluginsCollection_iface_tids[] = { + IHTMLPluginsCollection_tid, + 0 +}; +static dispex_static_data_t HTMLPluginsCollection_dispex = { + NULL, + DispCPlugins_tid, + NULL, + HTMLPluginsCollection_iface_tids +}; + +static HRESULT create_plugins_collection(OmNavigator *navigator, HTMLPluginsCollection **ret) +{ + HTMLPluginsCollection *col; + + col = heap_alloc_zero(sizeof(*col)); + if(!col) + return E_OUTOFMEMORY; + + col->lpIHTMLPluginsCollectionVtbl = &HTMLPluginsCollectionVtbl; + col->ref = 1; + col->navigator = navigator; + + init_dispex(&col->dispex, (IUnknown*)HTMLPLUGINSCOL(col), &HTMLPluginsCollection_dispex); + + *ret = col; + return S_OK; +} + #define OMNAVIGATOR_THIS(iface) DEFINE_THIS(OmNavigator, IOmNavigator, iface) static HRESULT WINAPI OmNavigator_QueryInterface(IOmNavigator *iface, REFIID riid, void **ppv) @@ -85,6 +238,10 @@ static ULONG WINAPI OmNavigator_Release(IOmNavigator *iface) TRACE("(%p) ref=%d\n", This, ref); if(!ref) { + if(This->plugins) { + This->plugins->navigator = NULL; + IHTMLPluginsCollection_Release(HTMLPLUGINSCOL(This->plugins)); + } release_dispex(&This->dispex); heap_free(This); } @@ -232,8 +389,21 @@ static HRESULT WINAPI OmNavigator_get_mimeTypes(IOmNavigator *iface, IHTMLMimeTy static HRESULT WINAPI OmNavigator_get_plugins(IOmNavigator *iface, IHTMLPluginsCollection **p) { OmNavigator *This = OMNAVIGATOR_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + if(!This->plugins) { + HRESULT hres; + + hres = create_plugins_collection(This, &This->plugins); + if(FAILED(hres)) + return hres; + }else { + IHTMLPluginsCollection_AddRef(HTMLPLUGINSCOL(This->plugins)); + } + + *p = HTMLPLUGINSCOL(This->plugins); + return S_OK; } static HRESULT WINAPI OmNavigator_get_cookieEnabled(IOmNavigator *iface, VARIANT_BOOL *p) diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index f4727681471..2134b311661 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -3590,6 +3590,26 @@ static void test_location(IHTMLDocument2 *doc) ok(!ref, "location chould be destroyed here\n"); } +static void test_plugins_col(IOmNavigator *nav) +{ + IHTMLPluginsCollection *col, *col2; + ULONG ref; + HRESULT hres; + + hres = IOmNavigator_get_plugins(nav, &col); + ok(hres == S_OK, "get_plugins failed: %08x\n", hres); + + hres = IOmNavigator_get_plugins(nav, &col2); + ok(hres == S_OK, "get_plugins failed: %08x\n", hres); + ok(iface_cmp((IUnknown*)col, (IUnknown*)col2), "col != col2\n"); + IHTMLPluginsCollection_Release(col2); + + test_disp2((IUnknown*)col, &DIID_DispCPlugins, &IID_IHTMLPluginsCollection, "[object]"); + + ref = IHTMLPluginsCollection_Release(col); + ok(!ref, "ref=%d\n", ref); +} + static void test_navigator(IHTMLDocument2 *doc) { IHTMLWindow2 *window; @@ -3673,6 +3693,8 @@ static void test_navigator(IHTMLDocument2 *doc) skip("nonstandard user agent\n"); } + test_plugins_col(navigator); + ref = IOmNavigator_Release(navigator); ok(!ref, "navigator should be destroyed here\n"); } diff --git a/include/mshtml.idl b/include/mshtml.idl index d76f20c51ca..55740a722f1 100644 --- a/include/mshtml.idl +++ b/include/mshtml.idl @@ -9145,13 +9145,33 @@ interface IHTMLPluginsCollection : IDispatch HRESULT refresh([defaultvalue(0), in] VARIANT_BOOL reload); } +[ + hidden, + uuid(3050f54a-98b5-11cf-bb82-00aa00bdce0b) +] +dispinterface DispCPlugins +{ + properties: +methods: + [propget, id(DISPID_IHTMLPLUGINSCOLLECTION_LENGTH)] + long length(); + + [id(DISPID_IHTMLPLUGINSCOLLECTION_REFRESH)] + void refresh([defaultvalue(0), in] VARIANT_BOOL reload); + + [propget, id(DISPID_IHTMLDOMCONSTRUCTOR_CONSTRUCTOR), hidden] + IDispatch *constructor(); +} + [ noncreatable, uuid(3050f3ff-98b5-11cf-bb82-00aa00bdce0b) ] coclass CPlugins { - [default] interface IHTMLPluginsCollection; + [default] dispinterface DispCPlugins; + interface IHTMLPluginsCollection; + interface IHTMLDOMConstructor; } /*****************************************************************************