Jacek Caban : mshtml: Added support for forwarding object element' s DOM calls to ActiveX control.
Alexandre Julliard
julliard at winehq.org
Fri Dec 17 11:30:47 CST 2010
Module: wine
Branch: master
Commit: 42d9e0c813e6f8f76a14ecd328906b7e38cd258d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=42d9e0c813e6f8f76a14ecd328906b7e38cd258d
Author: Jacek Caban <jacek at codeweavers.com>
Date: Fri Dec 17 03:38:33 2010 +0100
mshtml: Added support for forwarding object element's DOM calls to ActiveX control.
---
dlls/mshtml/htmlobject.c | 24 +++++++++++++-
dlls/mshtml/pluginhost.c | 76 +++++++++++++++++++++++++++++++++++++++++++
dlls/mshtml/pluginhost.h | 6 +++
dlls/mshtml/tests/activex.c | 60 ++++++++++++++++++++++++++++++++-
4 files changed, 163 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/htmlobject.c b/dlls/mshtml/htmlobject.c
index fe97eb9..8f8bef2 100644
--- a/dlls/mshtml/htmlobject.c
+++ b/dlls/mshtml/htmlobject.c
@@ -439,6 +439,26 @@ static HRESULT HTMLObjectElement_get_readystate(HTMLDOMNode *iface, BSTR *p)
return E_NOTIMPL;
}
+static HRESULT HTMLObjectElement_get_dispid(HTMLDOMNode *iface, BSTR name,
+ DWORD grfdex, DISPID *pid)
+{
+ HTMLObjectElement *This = HTMLOBJECT_NODE_THIS(iface);
+
+ TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(name), grfdex, pid);
+
+ return get_plugin_dispid(&This->plugin_container, name, pid);
+}
+
+static HRESULT HTMLObjectElement_invoke(HTMLDOMNode *iface, DISPID id, LCID lcid,
+ WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
+{
+ HTMLObjectElement *This = HTMLOBJECT_NODE_THIS(iface);
+
+ TRACE("(%p)->(%d)\n", This, id);
+
+ return invoke_plugin_prop(&This->plugin_container, id, lcid, flags, params, res, ei);
+}
+
#undef HTMLOBJECT_NODE_THIS
static const NodeImplVtbl HTMLObjectElementImplVtbl = {
@@ -450,7 +470,9 @@ static const NodeImplVtbl HTMLObjectElementImplVtbl = {
NULL,
NULL,
NULL,
- HTMLObjectElement_get_readystate
+ HTMLObjectElement_get_readystate,
+ HTMLObjectElement_get_dispid,
+ HTMLObjectElement_invoke
};
static const tid_t HTMLObjectElement_iface_tids[] = {
diff --git a/dlls/mshtml/pluginhost.c b/dlls/mshtml/pluginhost.c
index 91b6fda..c6df421 100644
--- a/dlls/mshtml/pluginhost.c
+++ b/dlls/mshtml/pluginhost.c
@@ -318,6 +318,82 @@ HRESULT get_plugin_disp(HTMLPluginContainer *plugin_container, IDispatch **ret)
return S_OK;
}
+HRESULT get_plugin_dispid(HTMLPluginContainer *plugin_container, WCHAR *name, DISPID *ret)
+{
+ IDispatch *disp;
+ DISPID id;
+ DWORD i;
+ HRESULT hres;
+
+ if(!plugin_container->plugin_host) {
+ WARN("no plugin host\n");
+ return DISP_E_UNKNOWNNAME;
+ }
+
+ disp = plugin_container->plugin_host->disp;
+ if(!disp)
+ return DISP_E_UNKNOWNNAME;
+
+ hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, &id);
+ if(FAILED(hres)) {
+ TRACE("no prop %s\n", debugstr_w(name));
+ return DISP_E_UNKNOWNNAME;
+ }
+
+ for(i=0; i < plugin_container->props_len; i++) {
+ if(id == plugin_container->props[i]) {
+ *ret = MSHTML_DISPID_CUSTOM_MIN+i;
+ return S_OK;
+ }
+ }
+
+ if(!plugin_container->props) {
+ plugin_container->props = heap_alloc(8*sizeof(DISPID));
+ if(!plugin_container->props)
+ return E_OUTOFMEMORY;
+ plugin_container->props_size = 8;
+ }else if(plugin_container->props_len == plugin_container->props_size) {
+ DISPID *new_props;
+
+ new_props = heap_realloc(plugin_container->props, plugin_container->props_size*2);
+ if(!new_props)
+ return E_OUTOFMEMORY;
+
+ plugin_container->props = new_props;
+ plugin_container->props_size *= 2;
+ }
+
+ plugin_container->props[plugin_container->props_len] = id;
+ *ret = MSHTML_DISPID_CUSTOM_MIN+plugin_container->props_len;
+ plugin_container->props_len++;
+ return S_OK;
+}
+
+HRESULT invoke_plugin_prop(HTMLPluginContainer *plugin_container, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
+ VARIANT *res, EXCEPINFO *ei)
+{
+ PluginHost *host;
+
+ host = plugin_container->plugin_host;
+ if(!host || !host->disp) {
+ FIXME("Called with no disp\n");
+ return E_UNEXPECTED;
+ }
+
+ if(!check_script_safety(host)) {
+ FIXME("Insecure object\n");
+ return E_FAIL;
+ }
+
+ if(id < MSHTML_DISPID_CUSTOM_MIN || id > MSHTML_DISPID_CUSTOM_MIN + plugin_container->props_len) {
+ ERR("Invalid id\n");
+ return E_FAIL;
+ }
+
+ return IDispatch_Invoke(host->disp, plugin_container->props[id-MSHTML_DISPID_CUSTOM_MIN], &IID_NULL,
+ lcid, flags, params, res, ei, NULL);
+}
+
static inline PluginHost *impl_from_IOleClientSite(IOleClientSite *iface)
{
return CONTAINING_RECORD(iface, PluginHost, IOleClientSite_iface);
diff --git a/dlls/mshtml/pluginhost.h b/dlls/mshtml/pluginhost.h
index bedb8ca..014e3ac 100644
--- a/dlls/mshtml/pluginhost.h
+++ b/dlls/mshtml/pluginhost.h
@@ -50,6 +50,10 @@ struct HTMLPluginContainer {
HTMLElement element;
PluginHost *plugin_host;
+
+ DISPID *props;
+ DWORD props_size;
+ DWORD props_len;
};
extern const IID IID_HTMLPluginContainer;
@@ -64,3 +68,5 @@ HRESULT create_ip_window(IOleInPlaceUIWindow**);
HRESULT create_ip_frame(IOleInPlaceFrame**);
HRESULT get_plugin_disp(HTMLPluginContainer*,IDispatch**);
+HRESULT get_plugin_dispid(HTMLPluginContainer*,WCHAR*,DISPID*);
+HRESULT invoke_plugin_prop(HTMLPluginContainer*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*);
diff --git a/dlls/mshtml/tests/activex.c b/dlls/mshtml/tests/activex.c
index 809453b..d3cbb9d 100644
--- a/dlls/mshtml/tests/activex.c
+++ b/dlls/mshtml/tests/activex.c
@@ -70,6 +70,8 @@ DEFINE_EXPECT(Invoke_READYSTATE);
DEFINE_EXPECT(Invoke_ENABLED);
DEFINE_EXPECT(Invoke_VALID);
DEFINE_EXPECT(Invoke_SECURITYCTX);
+DEFINE_EXPECT(Invoke_SCRIPTPROP);
+DEFINE_EXPECT(GetIDsOfNames_scriptprop);
DEFINE_EXPECT(DoVerb);
DEFINE_EXPECT(SetExtent);
DEFINE_EXPECT(GetExtent);
@@ -570,8 +572,15 @@ static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID l
static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
UINT cNames, LCID lcid, DISPID *rgDispId)
{
- ok(0, "unexpected call\n");
- return E_FAIL;
+ CHECK_EXPECT(GetIDsOfNames_scriptprop);
+ ok(IsEqualGUID(riid, &IID_NULL), "riid = %s\n", debugstr_guid(riid));
+ ok(cNames == 1, "cNames = %d\n", cNames);
+ ok(rgszNames != NULL, "rgszNames == NULL\n");
+ ok(!strcmp_wa(rgszNames[0], "scriptprop"), "rgszNames[0] = %s\n", wine_dbgstr_w(rgszNames[0]));
+ ok(rgDispId != NULL, "rgDispId == NULL\n");
+
+ *rgDispId = DISPID_SCRIPTPROP;
+ return S_OK;
}
static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
@@ -620,6 +629,17 @@ static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REF
ok(!pExcepInfo, "pExcepInfo != NULL\n");
ok(puArgErr != NULL, "puArgErr == NULL\n");
return DISP_E_MEMBERNOTFOUND;
+ case DISPID_SCRIPTPROP:
+ CHECK_EXPECT(Invoke_SCRIPTPROP);
+ 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 != NULL, "pExcepInfo == NULL\n");
+ ok(!puArgErr, "puArgErr != NULL\n");
+
+ V_VT(pVarResult) = VT_I4;
+ V_I4(pVarResult) = 4;
+ return S_OK;
default:
ok(0, "unexpected call %d\n", dispIdMember);
}
@@ -1197,10 +1217,42 @@ static const IClassFactoryVtbl ClassFactoryVtbl = {
static IClassFactory activex_cf = { &ClassFactoryVtbl };
+static void test_elem_dispex(IDispatchEx *dispex)
+{
+ DISPPARAMS dp;
+ EXCEPINFO ei;
+ VARIANT v;
+ DISPID id;
+ BSTR str;
+ HRESULT hres;
+
+ str = a2bstr("scriptprop");
+ SET_EXPECT(GetIDsOfNames_scriptprop);
+ hres = IDispatchEx_GetDispID(dispex, str, 0, &id);
+ CHECK_CALLED(GetIDsOfNames_scriptprop);
+ SysFreeString(str);
+ ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
+ todo_wine
+ ok(id == DISPID_SCRIPTPROP, "id = %d\n", id);
+
+ SET_EXPECT(Invoke_SECURITYCTX);
+ SET_EXPECT(Invoke_SCRIPTPROP);
+ memset(&dp, 0, sizeof(dp));
+ memset(&ei, 0, sizeof(ei));
+ V_VT(&v) = VT_EMPTY;
+ hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
+ ok(V_I4(&v) == 4, "V_I4(v) = %d\n", V_I4(&v));
+ CHECK_CALLED(Invoke_SECURITYCTX);
+ CHECK_CALLED(Invoke_SCRIPTPROP);
+}
+
static void test_object_elem(IHTMLDocument2 *doc)
{
IHTMLObjectElement *objelem;
IHTMLDocument3 *doc3;
+ IDispatchEx *dispex;
IHTMLElement *elem;
IDispatch *disp;
BSTR str;
@@ -1227,6 +1279,10 @@ static void test_object_elem(IHTMLDocument2 *doc)
ok(disp == &Dispatch, "disp != Dispatch\n");
CHECK_CALLED(Invoke_SECURITYCTX);
+ hres = IHTMLObjectElement_QueryInterface(objelem, &IID_IDispatchEx, (void**)&dispex);
+ test_elem_dispex(dispex);
+ IDispatchEx_Release(dispex);
+
IHTMLObjectElement_Release(objelem);
}
More information about the wine-cvs
mailing list