From 26049daf47b13c207ee5217056e3548824fa146c Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 17 Dec 2010 03:38:21 +0100 Subject: [PATCH] mshtml: Added IHTMLObjectElement::get_object implementation. --- dlls/mshtml/htmlobject.c | 6 ++-- dlls/mshtml/pluginhost.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ dlls/mshtml/pluginhost.h | 4 +++ dlls/mshtml/tests/activex.c | 68 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 150 insertions(+), 5 deletions(-) diff --git a/dlls/mshtml/htmlobject.c b/dlls/mshtml/htmlobject.c index 1cb8d60ce08..fe97eb98759 100644 --- a/dlls/mshtml/htmlobject.c +++ b/dlls/mshtml/htmlobject.c @@ -101,8 +101,10 @@ static HRESULT WINAPI HTMLObjectElement_Invoke(IHTMLObjectElement *iface, DISPID static HRESULT WINAPI HTMLObjectElement_get_object(IHTMLObjectElement *iface, IDispatch **p) { HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_plugin_disp(&This->plugin_container, p); } static HRESULT WINAPI HTMLObjectElement_get_classid(IHTMLObjectElement *iface, BSTR *p) diff --git a/dlls/mshtml/pluginhost.c b/dlls/mshtml/pluginhost.c index 1f5ca006478..91b6fdac4a4 100644 --- a/dlls/mshtml/pluginhost.c +++ b/dlls/mshtml/pluginhost.c @@ -27,6 +27,7 @@ #include "winuser.h" #include "ole2.h" #include "shlobj.h" +#include "mshtmdid.h" #include "mshtml_private.h" #include "pluginhost.h" @@ -60,6 +61,41 @@ static BOOL check_load_safety(PluginHost *host) return policy == URLPOLICY_ALLOW; } +static BOOL check_script_safety(PluginHost *host) +{ + DISPPARAMS params = {NULL,NULL,0,0}; + DWORD policy_size, policy; + struct CONFIRMSAFETY cs; + BYTE *ppolicy; + ULONG err = 0; + VARIANT v; + HRESULT hres; + + cs.clsid = host->clsid; + cs.pUnk = host->plugin_unk; + cs.dwFlags = 0; + + hres = IInternetHostSecurityManager_QueryCustomPolicy(HOSTSECMGR(host->doc), + &GUID_CUSTOM_CONFIRMOBJECTSAFETY, &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0); + if(FAILED(hres)) + return FALSE; + + policy = *(DWORD*)ppolicy; + CoTaskMemFree(ppolicy); + + if(policy != URLPOLICY_ALLOW) + return FALSE; + + V_VT(&v) = VT_EMPTY; + hres = IDispatch_Invoke(host->disp, DISPID_SECURITYCTX, &IID_NULL, 0, DISPATCH_PROPERTYGET, ¶ms, &v, NULL, &err); + if(SUCCEEDED(hres)) { + FIXME("Handle security ctx %s\n", debugstr_variant(&v)); + return FALSE; + } + + return TRUE; +} + static void update_readystate(PluginHost *host) { DISPPARAMS params = {NULL,NULL,0,0}; @@ -152,6 +188,8 @@ static void activate_plugin(PluginHost *host) IQuickActivate *quick_activate; IOleCommandTarget *cmdtrg; IOleObject *ole_obj; + IDispatchEx *dispex; + IDispatch *disp; RECT rect; HRESULT hres; @@ -191,6 +229,18 @@ static void activate_plugin(PluginHost *host) /* NOTE: Native QIs for IViewObjectEx, IActiveScript, an undocumented IID, IOleControl and IRunnableObject */ + hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IDispatchEx, (void**)&dispex); + if(SUCCEEDED(hres)) { + FIXME("Use IDispatchEx\n"); + host->disp = (IDispatch*)dispex; + }else { + hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IDispatch, (void**)&disp); + if(SUCCEEDED(hres)) + host->disp = disp; + else + TRACE("no IDispatch iface\n"); + } + hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IOleCommandTarget, (void**)&cmdtrg); if(SUCCEEDED(hres)) { FIXME("Use IOleCommandTarget\n"); @@ -243,6 +293,31 @@ void update_plugin_window(PluginHost *host, HWND hwnd, const RECT *rect) IOleInPlaceObject_SetObjectRects(host->ip_object, &host->rect, &host->rect); } +HRESULT get_plugin_disp(HTMLPluginContainer *plugin_container, IDispatch **ret) +{ + PluginHost *host; + + host = plugin_container->plugin_host; + if(!host) { + ERR("No plugin host\n"); + return E_UNEXPECTED; + } + + if(!host->disp) { + *ret = NULL; + return S_OK; + } + + if(!check_script_safety(host)) { + FIXME("Insecure object\n"); + return E_FAIL; + } + + IDispatch_AddRef(host->disp); + *ret = host->disp; + return S_OK; +} + static inline PluginHost *impl_from_IOleClientSite(IOleClientSite *iface) { return CONTAINING_RECORD(iface, PluginHost, IOleClientSite_iface); @@ -316,6 +391,8 @@ static ULONG WINAPI PHClientSite_Release(IOleClientSite *iface) TRACE("(%p) ref=%d\n", This, ref); if(!ref) { + if(This->disp) + IDispatch_Release(This->disp); if(This->ip_object) IOleInPlaceObject_Release(This->ip_object); list_remove(&This->entry); diff --git a/dlls/mshtml/pluginhost.h b/dlls/mshtml/pluginhost.h index 65ccb60578f..bedb8caf420 100644 --- a/dlls/mshtml/pluginhost.h +++ b/dlls/mshtml/pluginhost.h @@ -34,6 +34,8 @@ typedef struct { IOleInPlaceObject *ip_object; CLSID clsid; + IDispatch *disp; + HWND hwnd; RECT rect; BOOL ui_active; @@ -60,3 +62,5 @@ HRESULT create_param_prop_bag(nsIDOMHTMLElement*,IPropertyBag**); HRESULT create_ip_window(IOleInPlaceUIWindow**); HRESULT create_ip_frame(IOleInPlaceFrame**); + +HRESULT get_plugin_disp(HTMLPluginContainer*,IDispatch**); diff --git a/dlls/mshtml/tests/activex.c b/dlls/mshtml/tests/activex.c index 64b72c67f07..809453b72dc 100644 --- a/dlls/mshtml/tests/activex.c +++ b/dlls/mshtml/tests/activex.c @@ -33,6 +33,7 @@ #include "mshtmhst.h" #include "activscp.h" #include "objsafe.h" +#include "mshtmdid.h" #include "mshtml_test.h" #define DEFINE_EXPECT(func) \ @@ -68,6 +69,7 @@ DEFINE_EXPECT(IPersistPropertyBag_Load); DEFINE_EXPECT(Invoke_READYSTATE); DEFINE_EXPECT(Invoke_ENABLED); DEFINE_EXPECT(Invoke_VALID); +DEFINE_EXPECT(Invoke_SECURITYCTX); DEFINE_EXPECT(DoVerb); DEFINE_EXPECT(SetExtent); DEFINE_EXPECT(GetExtent); @@ -80,6 +82,8 @@ DEFINE_EXPECT(InPlaceDeactivate); DEFINE_EXPECT(UIDeactivate); DEFINE_EXPECT(QueryService_TestActiveX); +#define DISPID_SCRIPTPROP 1000 + static HWND container_hwnd, plugin_hwnd; #define TESTACTIVEX_CLSID "{178fc163-f585-4e24-9c13-4bb7f6680746}" @@ -159,6 +163,18 @@ static int strcmp_wa(LPCWSTR strw, const char *stra) return lstrcmpA(stra, buf); } +static BSTR a2bstr(const char *str) +{ + BSTR ret; + int len; + + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + ret = SysAllocStringLen(NULL, len); + MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); + + return ret; +} + static IOleClientSite *client_site; static READYSTATE plugin_readystate = READYSTATE_UNINITIALIZED; @@ -555,7 +571,7 @@ static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOL UINT cNames, LCID lcid, DISPID *rgDispId) { ok(0, "unexpected call\n"); - return E_NOTIMPL; + return E_FAIL; } static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid, @@ -567,8 +583,6 @@ static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REF ok(!pDispParams->cNamedArgs, "pDispParams->cNamedArgs = %d\n", pDispParams->cNamedArgs); ok(!pDispParams->rgdispidNamedArgs, "pDispParams->rgdispidNamedArgs != NULL\n"); ok(pVarResult != NULL, "pVarResult == NULL\n"); - ok(!pExcepInfo, "pExcepInfo != NULL\n"); - ok(puArgErr != NULL, "puArgErr == NULL\n"); switch(dispIdMember) { case DISPID_READYSTATE: @@ -576,6 +590,8 @@ static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REF ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags); ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs); ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n"); + ok(!pExcepInfo, "pExcepInfo != NULL\n"); + ok(puArgErr != NULL, "puArgErr == NULL\n"); V_VT(pVarResult) = VT_I4; V_I4(pVarResult) = plugin_readystate; @@ -585,12 +601,24 @@ static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REF ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags); ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs); ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n"); + ok(!pExcepInfo, "pExcepInfo != NULL\n"); + ok(puArgErr != NULL, "puArgErr == NULL\n"); return DISP_E_MEMBERNOTFOUND; case DISPID_VALID: CHECK_EXPECT(Invoke_VALID); ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags); ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs); ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n"); + ok(!pExcepInfo, "pExcepInfo != NULL\n"); + ok(puArgErr != NULL, "puArgErr == NULL\n"); + return DISP_E_MEMBERNOTFOUND; + case DISPID_SECURITYCTX: + CHECK_EXPECT(Invoke_SECURITYCTX); + ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags); + ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs); + ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n"); + ok(!pExcepInfo, "pExcepInfo != NULL\n"); + ok(puArgErr != NULL, "puArgErr == NULL\n"); return DISP_E_MEMBERNOTFOUND; default: ok(0, "unexpected call %d\n", dispIdMember); @@ -1169,6 +1197,39 @@ static const IClassFactoryVtbl ClassFactoryVtbl = { static IClassFactory activex_cf = { &ClassFactoryVtbl }; +static void test_object_elem(IHTMLDocument2 *doc) +{ + IHTMLObjectElement *objelem; + IHTMLDocument3 *doc3; + IHTMLElement *elem; + IDispatch *disp; + BSTR str; + HRESULT hres; + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3); + ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres); + + str = a2bstr("objid"); + elem = (void*)0xdeadbeef; + hres = IHTMLDocument3_getElementById(doc3, str, &elem); + IHTMLDocument3_Release(doc3); + SysFreeString(str); + ok(hres == S_OK, "getElementById failed: %08x\n", hres); + ok(elem != NULL, "elem == NULL\n"); + + hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLObjectElement, (void**)&objelem); + IHTMLElement_Release(elem); + ok(hres == S_OK, "Could not get IHTMLObjectElement iface: %08x\n", hres); + + SET_EXPECT(Invoke_SECURITYCTX); + hres = IHTMLObjectElement_get_object(objelem, &disp); + ok(hres == S_OK, "get_object failed: %08x\n", hres); + ok(disp == &Dispatch, "disp != Dispatch\n"); + CHECK_CALLED(Invoke_SECURITYCTX); + + IHTMLObjectElement_Release(objelem); +} + static void test_container(IHTMLDocument2 *doc_obj) { IHTMLWindow2 *parent_window, *html_window; @@ -1871,6 +1932,7 @@ static void test_object_ax(void) test_ui_activate(); test_container(notif_doc); + test_object_elem(notif_doc); SET_EXPECT(UIDeactivate); SET_EXPECT(Invoke_ENABLED); -- 2.11.4.GIT