vbscript: Convert VT_DISPATCH propput value to trivial value if DISPATCH_PROPERTYPUTREF is not set.

This commit is contained in:
Jacek Caban 2015-03-03 14:40:51 +01:00 committed by Alexandre Julliard
parent 571b09ce42
commit 4bca1665c4
1 changed files with 51 additions and 22 deletions

View File

@ -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;
}
return NULL;
*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 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) {