Jacek Caban : vbscript: Convert VT_DISPATCH propput value to trivial value if DISPATCH_PROPERTYPUTREF is not set.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Mar 3 09:42:11 CST 2015
Module: wine
Branch: master
Commit: 4bca1665c4dcd6e1c58322b8cb4e0b0ca9915033
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4bca1665c4dcd6e1c58322b8cb4e0b0ca9915033
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Mar 3 14:40:51 2015 +0100
vbscript: Convert VT_DISPATCH propput value to trivial value if DISPATCH_PROPERTYPUTREF is not set.
---
dlls/vbscript/vbdisp.c | 73 +++++++++++++++++++++++++++++++++++---------------
1 file changed, 51 insertions(+), 22 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 18ba966..a07020b 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -85,19 +85,43 @@ HRESULT vbdisp_get_id(vbdisp_t *This, BSTR name, vbdisp_invoke_type_t invoke_typ
return DISP_E_UNKNOWNNAME;
}
-static VARIANT *get_propput_arg(const DISPPARAMS *dp)
+static HRESULT get_propput_arg(script_ctx_t *ctx, const DISPPARAMS *dp, WORD flags, VARIANT *v, BOOL *is_owned)
{
unsigned i;
for(i=0; i < dp->cNamedArgs; i++) {
if(dp->rgdispidNamedArgs[i] == DISPID_PROPERTYPUT)
- return dp->rgvarg+i;
+ break;
+ }
+ if(i == dp->cNamedArgs) {
+ WARN("no value to set\n");
+ return DISP_E_PARAMNOTOPTIONAL;
+ }
+
+ *v = dp->rgvarg[i];
+ if(V_VT(v) == (VT_VARIANT|VT_BYREF))
+ *v = *V_VARIANTREF(v);
+ *is_owned = FALSE;
+
+ if(V_VT(v) == VT_DISPATCH) {
+ if(!(flags & DISPATCH_PROPERTYPUTREF)) {
+ DISPPARAMS val_dp = {NULL};
+ VARIANT value;
+ HRESULT hres;
+
+ hres = disp_call(ctx, V_DISPATCH(v), DISPID_VALUE, &val_dp, &value);
+ if(FAILED(hres))
+ return hres;
+
+ *v = value;
+ *is_owned = TRUE;
+ }
}
- return NULL;
+ return S_OK;
}
-static HRESULT invoke_variant_prop(VARIANT *v, WORD flags, DISPPARAMS *dp, VARIANT *res)
+static HRESULT invoke_variant_prop(script_ctx_t *ctx, VARIANT *v, WORD flags, DISPPARAMS *dp, VARIANT *res)
{
HRESULT hres;
@@ -115,13 +139,12 @@ static HRESULT invoke_variant_prop(VARIANT *v, WORD flags, DISPPARAMS *dp, VARIA
case DISPATCH_PROPERTYPUT:
case DISPATCH_PROPERTYPUTREF:
case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: {
- VARIANT *put_val;
+ VARIANT put_val;
+ BOOL own_val;
- put_val = get_propput_arg(dp);
- if(!put_val) {
- WARN("no value to set\n");
- return DISP_E_PARAMNOTOPTIONAL;
- }
+ hres = get_propput_arg(ctx, dp, flags, &put_val, &own_val);
+ if(FAILED(hres))
+ return hres;
if(arg_cnt(dp)) {
FIXME("Arguments not supported\n");
@@ -131,7 +154,10 @@ static HRESULT invoke_variant_prop(VARIANT *v, WORD flags, DISPPARAMS *dp, VARIA
if(res)
V_VT(res) = VT_EMPTY;
- hres = VariantCopyInd(v, put_val);
+ if(own_val)
+ *v = put_val;
+ else
+ hres = VariantCopyInd(v, &put_val);
break;
}
@@ -414,28 +440,31 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
case DISPATCH_PROPERTYPUT:
case DISPATCH_PROPERTYPUTREF:
case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: {
- VARIANT *put_val;
DISPPARAMS dp = {NULL, NULL, 1, 0};
+ BOOL needs_release;
+ VARIANT put_val;
+ HRESULT hres;
if(arg_cnt(pdp)) {
FIXME("arguments not implemented\n");
return E_NOTIMPL;
}
- put_val = get_propput_arg(pdp);
- if(!put_val) {
- WARN("no value to set\n");
- return DISP_E_PARAMNOTOPTIONAL;
- }
+ hres = get_propput_arg(This->desc->ctx, pdp, wFlags, &put_val, &needs_release);
+ if(FAILED(hres))
+ return hres;
- dp.rgvarg = put_val;
- func = This->desc->funcs[id].entries[V_VT(put_val) == VT_DISPATCH ? VBDISP_SET : VBDISP_LET];
+ dp.rgvarg = &put_val;
+ func = This->desc->funcs[id].entries[V_VT(&put_val) == VT_DISPATCH ? VBDISP_SET : VBDISP_LET];
if(!func) {
FIXME("no letter/setter\n");
return DISP_E_MEMBERNOTFOUND;
}
- return exec_script(This->desc->ctx, func, This, &dp, NULL);
+ hres = exec_script(This->desc->ctx, func, This, &dp, NULL);
+ if(needs_release)
+ VariantClear(&put_val);
+ return hres;
}
default:
FIXME("flags %x\n", wFlags);
@@ -444,7 +473,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
}
if(id < This->desc->prop_cnt + This->desc->func_cnt)
- return invoke_variant_prop(This->props+(id-This->desc->func_cnt), wFlags, pdp, pvarRes);
+ return invoke_variant_prop(This->desc->ctx, This->props+(id-This->desc->func_cnt), wFlags, pdp, pvarRes);
if(This->desc->builtin_prop_cnt) {
unsigned min = 0, max = This->desc->builtin_prop_cnt-1, i;
@@ -849,7 +878,7 @@ static HRESULT WINAPI ScriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
return E_NOTIMPL;
}
- return invoke_variant_prop(&ident->u.var->v, wFlags, pdp, pvarRes);
+ return invoke_variant_prop(This->ctx, &ident->u.var->v, wFlags, pdp, pvarRes);
}
switch(wFlags) {
More information about the wine-cvs
mailing list