mshtml: Added support for forwarding object element's DOM calls to ActiveX control.
This commit is contained in:
parent
26049daf47
commit
42d9e0c813
|
@ -439,6 +439,26 @@ static HRESULT HTMLObjectElement_get_readystate(HTMLDOMNode *iface, BSTR *p)
|
||||||
return E_NOTIMPL;
|
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
|
#undef HTMLOBJECT_NODE_THIS
|
||||||
|
|
||||||
static const NodeImplVtbl HTMLObjectElementImplVtbl = {
|
static const NodeImplVtbl HTMLObjectElementImplVtbl = {
|
||||||
|
@ -450,7 +470,9 @@ static const NodeImplVtbl HTMLObjectElementImplVtbl = {
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
HTMLObjectElement_get_readystate
|
HTMLObjectElement_get_readystate,
|
||||||
|
HTMLObjectElement_get_dispid,
|
||||||
|
HTMLObjectElement_invoke
|
||||||
};
|
};
|
||||||
|
|
||||||
static const tid_t HTMLObjectElement_iface_tids[] = {
|
static const tid_t HTMLObjectElement_iface_tids[] = {
|
||||||
|
|
|
@ -318,6 +318,82 @@ HRESULT get_plugin_disp(HTMLPluginContainer *plugin_container, IDispatch **ret)
|
||||||
return S_OK;
|
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)
|
static inline PluginHost *impl_from_IOleClientSite(IOleClientSite *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, PluginHost, IOleClientSite_iface);
|
return CONTAINING_RECORD(iface, PluginHost, IOleClientSite_iface);
|
||||||
|
|
|
@ -50,6 +50,10 @@ struct HTMLPluginContainer {
|
||||||
HTMLElement element;
|
HTMLElement element;
|
||||||
|
|
||||||
PluginHost *plugin_host;
|
PluginHost *plugin_host;
|
||||||
|
|
||||||
|
DISPID *props;
|
||||||
|
DWORD props_size;
|
||||||
|
DWORD props_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const IID IID_HTMLPluginContainer;
|
extern const IID IID_HTMLPluginContainer;
|
||||||
|
@ -64,3 +68,5 @@ HRESULT create_ip_window(IOleInPlaceUIWindow**);
|
||||||
HRESULT create_ip_frame(IOleInPlaceFrame**);
|
HRESULT create_ip_frame(IOleInPlaceFrame**);
|
||||||
|
|
||||||
HRESULT get_plugin_disp(HTMLPluginContainer*,IDispatch**);
|
HRESULT get_plugin_disp(HTMLPluginContainer*,IDispatch**);
|
||||||
|
HRESULT get_plugin_dispid(HTMLPluginContainer*,WCHAR*,DISPID*);
|
||||||
|
HRESULT invoke_plugin_prop(HTMLPluginContainer*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*);
|
||||||
|
|
|
@ -70,6 +70,8 @@ DEFINE_EXPECT(Invoke_READYSTATE);
|
||||||
DEFINE_EXPECT(Invoke_ENABLED);
|
DEFINE_EXPECT(Invoke_ENABLED);
|
||||||
DEFINE_EXPECT(Invoke_VALID);
|
DEFINE_EXPECT(Invoke_VALID);
|
||||||
DEFINE_EXPECT(Invoke_SECURITYCTX);
|
DEFINE_EXPECT(Invoke_SECURITYCTX);
|
||||||
|
DEFINE_EXPECT(Invoke_SCRIPTPROP);
|
||||||
|
DEFINE_EXPECT(GetIDsOfNames_scriptprop);
|
||||||
DEFINE_EXPECT(DoVerb);
|
DEFINE_EXPECT(DoVerb);
|
||||||
DEFINE_EXPECT(SetExtent);
|
DEFINE_EXPECT(SetExtent);
|
||||||
DEFINE_EXPECT(GetExtent);
|
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,
|
static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
|
||||||
UINT cNames, LCID lcid, DISPID *rgDispId)
|
UINT cNames, LCID lcid, DISPID *rgDispId)
|
||||||
{
|
{
|
||||||
ok(0, "unexpected call\n");
|
CHECK_EXPECT(GetIDsOfNames_scriptprop);
|
||||||
return E_FAIL;
|
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,
|
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(!pExcepInfo, "pExcepInfo != NULL\n");
|
||||||
ok(puArgErr != NULL, "puArgErr == NULL\n");
|
ok(puArgErr != NULL, "puArgErr == NULL\n");
|
||||||
return DISP_E_MEMBERNOTFOUND;
|
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:
|
default:
|
||||||
ok(0, "unexpected call %d\n", dispIdMember);
|
ok(0, "unexpected call %d\n", dispIdMember);
|
||||||
}
|
}
|
||||||
|
@ -1197,10 +1217,42 @@ static const IClassFactoryVtbl ClassFactoryVtbl = {
|
||||||
|
|
||||||
static IClassFactory activex_cf = { &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)
|
static void test_object_elem(IHTMLDocument2 *doc)
|
||||||
{
|
{
|
||||||
IHTMLObjectElement *objelem;
|
IHTMLObjectElement *objelem;
|
||||||
IHTMLDocument3 *doc3;
|
IHTMLDocument3 *doc3;
|
||||||
|
IDispatchEx *dispex;
|
||||||
IHTMLElement *elem;
|
IHTMLElement *elem;
|
||||||
IDispatch *disp;
|
IDispatch *disp;
|
||||||
BSTR str;
|
BSTR str;
|
||||||
|
@ -1227,6 +1279,10 @@ static void test_object_elem(IHTMLDocument2 *doc)
|
||||||
ok(disp == &Dispatch, "disp != Dispatch\n");
|
ok(disp == &Dispatch, "disp != Dispatch\n");
|
||||||
CHECK_CALLED(Invoke_SECURITYCTX);
|
CHECK_CALLED(Invoke_SECURITYCTX);
|
||||||
|
|
||||||
|
hres = IHTMLObjectElement_QueryInterface(objelem, &IID_IDispatchEx, (void**)&dispex);
|
||||||
|
test_elem_dispex(dispex);
|
||||||
|
IDispatchEx_Release(dispex);
|
||||||
|
|
||||||
IHTMLObjectElement_Release(objelem);
|
IHTMLObjectElement_Release(objelem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue