jscript: Use DISPATCH_PROPERTYPUTREF flag when setting a property to VT_DISPATCH.

oldstable
Jacek Caban 2014-11-28 16:18:32 +01:00 committed by Alexandre Julliard
parent 6a74a0785a
commit 7e43408eaa
2 changed files with 48 additions and 2 deletions

View File

@ -1346,6 +1346,7 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val)
jsdisp_release(jsdisp);
}else {
DISPID dispid = DISPID_PROPERTYPUT;
DWORD flags = DISPATCH_PROPERTYPUT;
VARIANT var;
DISPPARAMS dp = {&var, &dispid, 1, 1};
IDispatchEx *dispex;
@ -1354,17 +1355,20 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val)
if(FAILED(hres))
return hres;
if(V_VT(&var) == VT_DISPATCH)
flags |= DISPATCH_PROPERTYPUTREF;
clear_ei(ctx);
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if(SUCCEEDED(hres)) {
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ctx->ei.ei,
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, &dp, NULL, &ctx->ei.ei,
&ctx->jscaller->IServiceProvider_iface);
IDispatchEx_Release(dispex);
}else {
ULONG err = 0;
TRACE("using IDispatch\n");
hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ctx->ei.ei, &err);
hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, flags, &dp, NULL, &ctx->ei.ei, &err);
}
VariantClear(&var);

View File

@ -80,6 +80,8 @@ DEFINE_EXPECT(global_propget_d);
DEFINE_EXPECT(global_propget_i);
DEFINE_EXPECT(global_propput_d);
DEFINE_EXPECT(global_propput_i);
DEFINE_EXPECT(global_propputref_d);
DEFINE_EXPECT(global_propputref_i);
DEFINE_EXPECT(global_propdelete_d);
DEFINE_EXPECT(global_nopropdelete_d);
DEFINE_EXPECT(global_success_d);
@ -136,6 +138,7 @@ DEFINE_EXPECT(DeleteMemberByDispID_false);
#define DISPID_GLOBAL_TESTRES 0x1018
#define DISPID_GLOBAL_TESTNORES 0x1019
#define DISPID_GLOBAL_DISPEXFUNC 0x101a
#define DISPID_GLOBAL_TESTPROPPUTREF 0x101b
#define DISPID_GLOBAL_TESTPROPDELETE 0x2000
#define DISPID_GLOBAL_TESTNOPROPDELETE 0x2001
@ -608,6 +611,12 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
*pid = DISPID_GLOBAL_TESTPROPPUT;
return S_OK;
}
if(!strcmp_wa(bstrName, "testPropPutRef")) {
CHECK_EXPECT(global_propputref_d);
test_grfdex(grfdex, fdexNameCaseSensitive);
*pid = DISPID_GLOBAL_TESTPROPPUTREF;
return S_OK;
}
if(!strcmp_wa(bstrName, "testPropDelete")) {
CHECK_EXPECT(global_propdelete_d);
test_grfdex(grfdex, fdexNameCaseSensitive);
@ -841,6 +850,21 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
ok(V_I4(pdp->rgvarg) == 1, "V_I4(pdp->rgvarg)=%d\n", V_I4(pdp->rgvarg));
return S_OK;
case DISPID_GLOBAL_TESTPROPPUTREF:
CHECK_EXPECT(global_propputref_i);
ok(wFlags == (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF), "wFlags = %x\n", wFlags);
ok(pdp != NULL, "pdp == NULL\n");
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
ok(!pvarRes, "pvarRes != NULL\n");
ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg)=%d\n", V_VT(pdp->rgvarg));
return S_OK;
case DISPID_GLOBAL_GETVT:
ok(pdp != NULL, "pdp == NULL\n");
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
@ -2049,6 +2073,18 @@ static BOOL run_tests(void)
CHECK_CALLED(global_propput_d);
CHECK_CALLED(global_propput_i);
SET_EXPECT(global_propputref_d);
SET_EXPECT(global_propputref_i);
parse_script_a("testPropPutRef = new Object();");
CHECK_CALLED(global_propputref_d);
CHECK_CALLED(global_propputref_i);
SET_EXPECT(global_propputref_d);
SET_EXPECT(global_propputref_i);
parse_script_a("testPropPutRef = testObj;");
CHECK_CALLED(global_propputref_d);
CHECK_CALLED(global_propputref_i);
SET_EXPECT(global_success_d);
SET_EXPECT(global_success_i);
parse_script_a("reportSuccess();");
@ -2187,6 +2223,12 @@ static BOOL run_tests(void)
CHECK_CALLED(global_propget_d);
CHECK_CALLED(global_propget_i);
SET_EXPECT(global_propputref_d);
SET_EXPECT(global_propputref_i);
parse_script_a("testPropPutRef = nullDisp;");
CHECK_CALLED(global_propputref_d);
CHECK_CALLED(global_propputref_i);
SET_EXPECT(global_propget_d);
SET_EXPECT(global_propget_i);
parse_script_a("(function () { this.testPropGet; })();");