Jacek Caban : mshtml: Allow setting function properties to any VARIANT type.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Nov 28 12:49:04 CST 2014
Module: wine
Branch: master
Commit: 275a231fbb403a2020b72a5724d531789d0a1cd9
URL: http://source.winehq.org/git/wine.git/?a=commit;h=275a231fbb403a2020b72a5724d531789d0a1cd9
Author: Jacek Caban <jacek at codeweavers.com>
Date: Fri Nov 28 16:18:53 2014 +0100
mshtml: Allow setting function properties to any VARIANT type.
---
dlls/mshtml/dispex.c | 63 +++++++++++++++++++++-------------------------
dlls/mshtml/tests/script.c | 2 +-
2 files changed, 29 insertions(+), 36 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c
index f294d91..1f1204a 100644
--- a/dlls/mshtml/dispex.c
+++ b/dlls/mshtml/dispex.c
@@ -87,7 +87,7 @@ typedef struct {
typedef struct {
func_disp_t *func_obj;
- IDispatch *val;
+ VARIANT val;
} func_obj_entry_t;
struct dispex_dynamic_data_t {
@@ -833,6 +833,7 @@ static HRESULT invoke_disp_value(DispatchEx *This, IDispatch *func_disp, LCID lc
static HRESULT get_func_obj_entry(DispatchEx *This, func_info_t *func, func_obj_entry_t **ret)
{
dispex_dynamic_data_t *dynamic_data;
+ func_obj_entry_t *entry;
dynamic_data = get_dynamic_data(This);
if(!dynamic_data)
@@ -844,20 +845,18 @@ static HRESULT get_func_obj_entry(DispatchEx *This, func_info_t *func, func_obj_
return E_OUTOFMEMORY;
}
- if(!dynamic_data->func_disps[func->func_disp_idx].func_obj) {
- func_disp_t *func_obj;
-
- func_obj = create_func_disp(This, func);
- if(!func_obj)
+ entry = dynamic_data->func_disps + func->func_disp_idx;
+ if(!entry->func_obj) {
+ entry->func_obj = create_func_disp(This, func);
+ if(!entry->func_obj)
return E_OUTOFMEMORY;
- dynamic_data->func_disps[func->func_disp_idx].func_obj = func_obj;
-
- IDispatchEx_AddRef(&func_obj->dispex.IDispatchEx_iface);
- dynamic_data->func_disps[func->func_disp_idx].val = (IDispatch*)&func_obj->dispex.IDispatchEx_iface;
+ IDispatchEx_AddRef(&entry->func_obj->dispex.IDispatchEx_iface);
+ V_VT(&entry->val) = VT_DISPATCH;
+ V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface;
}
- *ret = dynamic_data->func_disps+func->func_disp_idx;
+ *ret = entry;
return S_OK;
}
@@ -1131,13 +1130,18 @@ static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags,
&& This->dynamic_data->func_disps[func->func_disp_idx].func_obj) {
func_obj_entry_t *entry = This->dynamic_data->func_disps + func->func_disp_idx;
- if((IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface != entry->val) {
- if(!entry->val) {
+ if(V_VT(&entry->val) != VT_DISPATCH) {
+ FIXME("calling %s not supported\n", debugstr_variant(&entry->val));
+ return E_NOTIMPL;
+ }
+
+ if((IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface != V_DISPATCH(&entry->val)) {
+ if(!V_DISPATCH(&entry->val)) {
FIXME("Calling null\n");
return E_FAIL;
}
- hres = invoke_disp_value(This, entry->val, 0, flags, dp, res, ei, NULL);
+ hres = invoke_disp_value(This, V_DISPATCH(&entry->val), 0, flags, dp, res, ei, NULL);
break;
}
}
@@ -1166,16 +1170,11 @@ static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags,
if(FAILED(hres))
return hres;
- V_VT(res) = VT_DISPATCH;
- V_DISPATCH(res) = entry->val;
- if(V_DISPATCH(res))
- IDispatch_AddRef(V_DISPATCH(res));
- hres = S_OK;
- break;
+ V_VT(res) = VT_EMPTY;
+ return VariantCopy(res, &entry->val);
}
case DISPATCH_PROPERTYPUT: {
func_obj_entry_t *entry;
- VARIANT *v;
if(dp->cArgs != 1 || (dp->cNamedArgs == 1 && *dp->rgdispidNamedArgs != DISPID_PROPERTYPUT)
|| dp->cNamedArgs > 1) {
@@ -1183,22 +1182,17 @@ static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags,
return E_INVALIDARG;
}
- v = dp->rgvarg;
- /* FIXME: not exactly right */
- if(V_VT(v) != VT_DISPATCH)
- return E_NOTIMPL;
-
+ /*
+ * NOTE: Although we have IDispatchEx tests showing, that it's not allowed to set
+ * function property using InvokeEx, it's possible to do that from jscript.
+ * Native probably uses some undocumented interface in this case, but it should
+ * be fine for us to allow IDispatchEx handle that.
+ */
hres = get_func_obj_entry(This, func, &entry);
if(FAILED(hres))
return hres;
- if(entry->val)
- IDispatch_Release(entry->val);
- entry->val = V_DISPATCH(v);
- if(entry->val)
- IDispatch_AddRef(entry->val);
- hres = S_OK;
- break;
+ return VariantCopy(&entry->val, dp->rgvarg);
}
default:
FIXME("Unimplemented flags %x\n", flags);
@@ -1722,8 +1716,7 @@ void release_dispex(DispatchEx *This)
iter->func_obj->obj = NULL;
IDispatchEx_Release(&iter->func_obj->dispex.IDispatchEx_iface);
}
- if(iter->val)
- IDispatch_Release(iter->val);
+ VariantClear(&iter->val);
}
heap_free(This->dynamic_data->func_disps);
diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c
index c9b9eb5..9681fd6 100644
--- a/dlls/mshtml/tests/script.c
+++ b/dlls/mshtml/tests/script.c
@@ -1915,7 +1915,7 @@ static void test_func(IDispatchEx *obj)
V_VT(&var) = VT_I4;
V_I4(&var) = 100;
hres = dispex_propput(obj, id, 0, &var, NULL);
- ok(hres == E_NOTIMPL, "InvokeEx failed: %08x\n", hres);
+ todo_wine ok(hres == E_NOTIMPL, "InvokeEx failed: %08x\n", hres);
hres = dispex_propget(dispex, DISPID_VALUE, &var, NULL);
ok(hres == E_ACCESSDENIED, "InvokeEx returned: %08x, expected E_ACCESSDENIED\n", hres);
More information about the wine-cvs
mailing list