static HRESULT invoke_variant_prop(script_ctx_t *ctx, VARIANT *v, WORD flags, DISPPARAMS *dp, VARIANT *res) { HRESULT hres; switch(flags) { case DISPATCH_PROPERTYGET|DISPATCH_METHOD: case DISPATCH_PROPERTYGET: if(dp->cArgs) { WARN("called with arguments\n"); return DISP_E_MEMBERNOTFOUND; /* That's what tests show */ } hres = VariantCopyInd(res, v); break; case DISPATCH_PROPERTYPUT: case DISPATCH_PROPERTYPUTREF: case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: { VARIANT put_val; BOOL own_val; 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"); return E_NOTIMPL; } if(res) V_VT(res) = VT_EMPTY; if(own_val) *v = put_val; else hres = VariantCopyInd(v, &put_val); break; } default: FIXME("unimplemented flags %x\n", flags); return E_NOTIMPL; } return hres; }
static HRESULT invoke_variant_prop(VARIANT *v, WORD flags, DISPPARAMS *dp, VARIANT *res) { HRESULT hres; switch(flags) { case DISPATCH_PROPERTYGET|DISPATCH_METHOD: case DISPATCH_PROPERTYGET: if(dp->cArgs) { WARN("called with arguments\n"); return DISP_E_MEMBERNOTFOUND; /* That's what tests show */ } hres = VariantCopyInd(res, v); break; case DISPATCH_PROPERTYPUT: { VARIANT *put_val; put_val = get_propput_arg(dp); if(!put_val) { WARN("no value to set\n"); return DISP_E_PARAMNOTOPTIONAL; } if(arg_cnt(dp)) { FIXME("Arguments not supported\n"); return E_NOTIMPL; } if(res) V_VT(res) = VT_EMPTY; hres = VariantCopyInd(v, put_val); break; } default: FIXME("unimplemented flags %x\n", flags); return E_NOTIMPL; } return hres; }
static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { vbdisp_t *This = impl_from_IDispatchEx(iface); TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); if(!This->desc) return E_UNEXPECTED; if(pvarRes) V_VT(pvarRes) = VT_EMPTY; if(id < 0) return DISP_E_MEMBERNOTFOUND; if(is_func_id(This, id)) { function_t *func; switch(wFlags) { case DISPATCH_PROPERTYGET: func = This->desc->funcs[id].entries[VBDISP_CALLGET]; if(!func || (func->type != FUNC_PROPGET && func->type != FUNC_DEFGET)) { WARN("no getter\n"); return DISP_E_MEMBERNOTFOUND; } return exec_script(This->desc->ctx, func, This, pdp, pvarRes); case DISPATCH_METHOD: case DISPATCH_METHOD|DISPATCH_PROPERTYGET: func = This->desc->funcs[id].entries[VBDISP_CALLGET]; if(!func) { FIXME("no invoke/getter\n"); return DISP_E_MEMBERNOTFOUND; } return exec_script(This->desc->ctx, func, This, pdp, pvarRes); case DISPATCH_PROPERTYPUT: case DISPATCH_PROPERTYPUTREF: case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: { 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; } 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]; if(!func) { FIXME("no letter/setter\n"); return DISP_E_MEMBERNOTFOUND; } hres = exec_script(This->desc->ctx, func, This, &dp, NULL); if(needs_release) VariantClear(&put_val); return hres; } default: FIXME("flags %x\n", wFlags); return DISP_E_MEMBERNOTFOUND; } } if(id < This->desc->prop_cnt + This->desc->func_cnt) 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; while(min <= max) { i = (min+max)/2; if(This->desc->builtin_props[i].id == id) return invoke_builtin(This, This->desc->builtin_props+i, wFlags, pdp, pvarRes); if(This->desc->builtin_props[i].id < id) min = i+1; else max = i-1; } } return DISP_E_MEMBERNOTFOUND; }
static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { vbdisp_t *This = impl_from_IDispatchEx(iface); TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); if(!This->desc) return E_UNEXPECTED; if(pvarRes) V_VT(pvarRes) = VT_EMPTY; if(id < 0) return DISP_E_MEMBERNOTFOUND; if(is_func_id(This, id)) { function_t *func; switch(wFlags) { case DISPATCH_METHOD: case DISPATCH_METHOD|DISPATCH_PROPERTYGET: func = This->desc->funcs[id].entries[VBDISP_CALLGET]; if(!func) { FIXME("no invoke/getter\n"); return DISP_E_MEMBERNOTFOUND; } return exec_script(This->desc->ctx, func, (IDispatch*)&This->IDispatchEx_iface, pdp, pvarRes); case DISPATCH_PROPERTYPUT: { VARIANT *put_val; DISPPARAMS dp = {NULL, NULL, 1, 0}; 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; } 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, (IDispatch*)&This->IDispatchEx_iface, &dp, NULL); } default: FIXME("flags %x\n", wFlags); return DISP_E_MEMBERNOTFOUND; } } if(id < This->desc->prop_cnt + This->desc->func_cnt) return invoke_variant_prop(This, 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; while(min <= max) { i = (min+max)/2; if(This->desc->builtin_props[i].id == id) return invoke_builtin(This, This->desc->builtin_props+i, wFlags, pdp, pvarRes); if(This->desc->builtin_props[i].id < id) min = i+1; else max = i-1; } } return DISP_E_MEMBERNOTFOUND; }