jscript: Don't pass 'this' argument to DISPID_VALUE of pure IDispatch interfaces.
This commit is contained in:
parent
8ec82dfaae
commit
7726e01844
|
@ -1205,6 +1205,12 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
|
|||
if(r && argc)
|
||||
flags |= DISPATCH_PROPERTYGET;
|
||||
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
if(FAILED(hres)) {
|
||||
TRACE("using IDispatch\n");
|
||||
dispex = NULL;
|
||||
jsthis = NULL;
|
||||
}
|
||||
|
||||
if(jsthis) {
|
||||
static DISPID this_id = DISPID_THIS;
|
||||
|
@ -1220,8 +1226,11 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
|
|||
|
||||
if(dp.cArgs > sizeof(buf)/sizeof(*buf)) {
|
||||
dp.rgvarg = heap_alloc(dp.cArgs*sizeof(VARIANT));
|
||||
if(!dp.rgvarg)
|
||||
if(!dp.rgvarg) {
|
||||
if(dispex)
|
||||
IDispatchEx_Release(dispex);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}else {
|
||||
dp.rgvarg = buf;
|
||||
}
|
||||
|
@ -1233,6 +1242,8 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
|
|||
VariantClear(dp.rgvarg+dp.cArgs-i-1);
|
||||
if(dp.rgvarg != buf)
|
||||
heap_free(dp.rgvarg);
|
||||
if(dispex)
|
||||
IDispatchEx_Release(dispex);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
@ -1243,8 +1254,7 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
|
|||
|
||||
V_VT(&retv) = VT_EMPTY;
|
||||
clear_ei(ctx);
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
if(SUCCEEDED(hres)) {
|
||||
if(dispex) {
|
||||
hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, ctx->lcid, flags, &dp, r ? &retv : NULL, &ctx->ei.ei,
|
||||
&ctx->jscaller->IServiceProvider_iface);
|
||||
IDispatchEx_Release(dispex);
|
||||
|
@ -1256,7 +1266,6 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
|
|||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
|
||||
TRACE("using IDispatch\n");
|
||||
hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, ctx->lcid, flags, &dp, r ? &retv : NULL, &ctx->ei.ei, &err);
|
||||
}
|
||||
|
||||
|
|
|
@ -90,6 +90,8 @@ DEFINE_EXPECT(global_propargput_i);
|
|||
DEFINE_EXPECT(global_testargtypes_i);
|
||||
DEFINE_EXPECT(puredisp_prop_d);
|
||||
DEFINE_EXPECT(puredisp_noprop_d);
|
||||
DEFINE_EXPECT(puredisp_value);
|
||||
DEFINE_EXPECT(dispexfunc_value);
|
||||
DEFINE_EXPECT(testobj_delete_test);
|
||||
DEFINE_EXPECT(testobj_delete_nodelete);
|
||||
DEFINE_EXPECT(testobj_value);
|
||||
|
@ -131,6 +133,7 @@ DEFINE_EXPECT(DeleteMemberByDispID_false);
|
|||
#define DISPID_GLOBAL_DISPUNK 0x1017
|
||||
#define DISPID_GLOBAL_TESTRES 0x1018
|
||||
#define DISPID_GLOBAL_TESTNORES 0x1019
|
||||
#define DISPID_GLOBAL_DISPEXFUNC 0x101a
|
||||
|
||||
#define DISPID_GLOBAL_TESTPROPDELETE 0x2000
|
||||
#define DISPID_GLOBAL_TESTNOPROPDELETE 0x2001
|
||||
|
@ -244,18 +247,6 @@ static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
|
|||
LPOLESTR *rgszNames, UINT cNames,
|
||||
LCID lcid, DISPID *rgDispId)
|
||||
{
|
||||
ok(IsEqualGUID(riid, &IID_NULL), "Expected IID_NULL\n");
|
||||
ok(cNames==1, "cNames = %d\n", cNames);
|
||||
|
||||
if(!strcmp_wa(*rgszNames, "prop")) {
|
||||
CHECK_EXPECT(puredisp_prop_d);
|
||||
*rgDispId = DISPID_TESTOBJ_PROP;
|
||||
return S_OK;
|
||||
} else if(!strcmp_wa(*rgszNames, "noprop")) {
|
||||
CHECK_EXPECT(puredisp_noprop_d);
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
}
|
||||
|
||||
ok(0, "unexpected call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
@ -268,6 +259,12 @@ static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
|
||||
{
|
||||
ok(0, "unexpected call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
|
||||
{
|
||||
ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
|
||||
|
@ -441,6 +438,60 @@ static IDispatchExVtbl testObjVtbl = {
|
|||
|
||||
static IDispatchEx testObj = { &testObjVtbl };
|
||||
|
||||
static HRESULT WINAPI dispexFunc_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
VARIANT *res, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
ok(pspCaller != NULL, "pspCaller = NULL\n");
|
||||
|
||||
switch(id) {
|
||||
case DISPID_VALUE:
|
||||
CHECK_EXPECT(dispexfunc_value);
|
||||
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
|
||||
ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs != NULL\n");
|
||||
ok(*pdp->rgdispidNamedArgs == DISPID_THIS, "*rgdispidNamedArgs = %d\n", *pdp->rgdispidNamedArgs);
|
||||
ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
|
||||
ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
|
||||
ok(res != NULL, "res == NULL\n");
|
||||
ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
|
||||
ok(pei != NULL, "pei == NULL\n");
|
||||
|
||||
ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
|
||||
ok(!V_BOOL(pdp->rgvarg+1), "V_BOOL(pdp->rgvarg+1) = %x\n", V_BOOL(pdp->rgvarg+1));
|
||||
|
||||
ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
|
||||
ok(V_DISPATCH(pdp->rgvarg) != NULL, "V_DISPATCH(pdp->rgvarg) == NULL\n");
|
||||
|
||||
if(res)
|
||||
V_VT(res) = VT_NULL;
|
||||
return S_OK;
|
||||
default:
|
||||
ok(0, "unexpected call %x\n", id);
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
static IDispatchExVtbl dispexFuncVtbl = {
|
||||
DispatchEx_QueryInterface,
|
||||
DispatchEx_AddRef,
|
||||
DispatchEx_Release,
|
||||
DispatchEx_GetTypeInfoCount,
|
||||
DispatchEx_GetTypeInfo,
|
||||
DispatchEx_GetIDsOfNames,
|
||||
DispatchEx_Invoke,
|
||||
DispatchEx_GetDispID,
|
||||
dispexFunc_InvokeEx,
|
||||
DispatchEx_DeleteMemberByName,
|
||||
DispatchEx_DeleteMemberByDispID,
|
||||
DispatchEx_GetMemberProperties,
|
||||
DispatchEx_GetMemberName,
|
||||
DispatchEx_GetNextDispID,
|
||||
DispatchEx_GetNameSpaceParent
|
||||
};
|
||||
|
||||
static IDispatchEx dispexFunc = { &dispexFuncVtbl };
|
||||
|
||||
static HRESULT WINAPI pureDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch)) {
|
||||
|
@ -452,14 +503,65 @@ static HRESULT WINAPI pureDisp_QueryInterface(IDispatchEx *iface, REFIID riid, v
|
|||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI pureDisp_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
|
||||
LPOLESTR *rgszNames, UINT cNames,
|
||||
LCID lcid, DISPID *rgDispId)
|
||||
{
|
||||
ok(IsEqualGUID(riid, &IID_NULL), "Expected IID_NULL\n");
|
||||
ok(cNames==1, "cNames = %d\n", cNames);
|
||||
|
||||
if(!strcmp_wa(*rgszNames, "prop")) {
|
||||
CHECK_EXPECT(puredisp_prop_d);
|
||||
*rgDispId = DISPID_TESTOBJ_PROP;
|
||||
return S_OK;
|
||||
} else if(!strcmp_wa(*rgszNames, "noprop")) {
|
||||
CHECK_EXPECT(puredisp_noprop_d);
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
}
|
||||
|
||||
ok(0, "unexpected call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI pureDisp_Invoke(IDispatchEx *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
|
||||
WORD wFlags, DISPPARAMS *pdp, VARIANT *res, EXCEPINFO *ei, UINT *puArgErr)
|
||||
{
|
||||
ok(IsEqualGUID(&IID_NULL, riid), "unexpected riid\n");
|
||||
|
||||
switch(dispIdMember) {
|
||||
case DISPID_VALUE:
|
||||
CHECK_EXPECT(puredisp_value);
|
||||
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
|
||||
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
|
||||
ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
|
||||
ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
|
||||
ok(res != NULL, "res == NULL\n");
|
||||
ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
|
||||
ok(ei != NULL, "ei == NULL\n");
|
||||
ok(puArgErr != NULL, "puArgErr == NULL\n");
|
||||
|
||||
ok(V_VT(pdp->rgvarg) == VT_BOOL, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
|
||||
ok(!V_BOOL(pdp->rgvarg), "V_BOOL(pdp->rgvarg) = %x\n", V_BOOL(pdp->rgvarg));
|
||||
|
||||
if(res)
|
||||
V_VT(res) = VT_NULL;
|
||||
return S_OK;
|
||||
default:
|
||||
ok(0, "unexpected call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
static IDispatchExVtbl pureDispVtbl = {
|
||||
pureDisp_QueryInterface,
|
||||
DispatchEx_AddRef,
|
||||
DispatchEx_Release,
|
||||
DispatchEx_GetTypeInfoCount,
|
||||
DispatchEx_GetTypeInfo,
|
||||
DispatchEx_GetIDsOfNames,
|
||||
DispatchEx_Invoke
|
||||
pureDisp_GetIDsOfNames,
|
||||
pureDisp_Invoke
|
||||
};
|
||||
|
||||
static IDispatchEx pureDisp = { &pureDispVtbl };
|
||||
|
@ -628,6 +730,11 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
if(!strcmp_wa(bstrName, "dispexFunc")) {
|
||||
*pid = DISPID_GLOBAL_DISPEXFUNC;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if(strict_dispid_check && strcmp_wa(bstrName, "t"))
|
||||
ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
|
@ -809,6 +916,11 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
|
|||
V_DISPATCH(pvarRes) = (IDispatch*)&pureDisp;
|
||||
return S_OK;
|
||||
|
||||
case DISPID_GLOBAL_DISPEXFUNC:
|
||||
V_VT(pvarRes) = VT_DISPATCH;
|
||||
V_DISPATCH(pvarRes) = (IDispatch*)&dispexFunc;
|
||||
return S_OK;
|
||||
|
||||
case DISPID_GLOBAL_GETNULLBSTR:
|
||||
if(pvarRes) {
|
||||
V_VT(pvarRes) = VT_BSTR;
|
||||
|
@ -1891,6 +2003,22 @@ static BOOL run_tests(void)
|
|||
parse_script_a("ok((delete pureDisp.noprop) === true, 'delete pureDisp.noprop did not return false');");
|
||||
CHECK_CALLED(puredisp_noprop_d);
|
||||
|
||||
SET_EXPECT(puredisp_value);
|
||||
parse_script_a("var t=pureDisp; t=t(false);");
|
||||
CHECK_CALLED(puredisp_value);
|
||||
|
||||
SET_EXPECT(puredisp_value);
|
||||
parse_script_a("var t = {func: pureDisp}; t = t.func(false);");
|
||||
CHECK_CALLED(puredisp_value);
|
||||
|
||||
SET_EXPECT(dispexfunc_value);
|
||||
parse_script_a("var t = dispexFunc; t = t(false);");
|
||||
CHECK_CALLED(dispexfunc_value);
|
||||
|
||||
SET_EXPECT(dispexfunc_value);
|
||||
parse_script_a("var t = {func: dispexFunc}; t = t.func(false);");
|
||||
CHECK_CALLED(dispexfunc_value);
|
||||
|
||||
parse_script_a("(function reportSuccess() {})()");
|
||||
|
||||
parse_script_a("ok(typeof(test) === 'object', \"typeof(test) != 'object'\");");
|
||||
|
|
Loading…
Reference in New Issue