mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-21 09:14:10 +00:00
jscript: Pass the correct ServiceProvider when invoking external prop.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
parent
9beef3fc5a
commit
c2b5538711
|
@ -572,9 +572,9 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t
|
|||
|
||||
TRACE("call %s %p\n", debugstr_w(prop->name), get_object(prop->u.val));
|
||||
|
||||
return disp_call_value(This->ctx, get_object(prop->u.val),
|
||||
jsval_disp(jsthis ? jsthis : (IDispatch*)&This->IDispatchEx_iface),
|
||||
flags, argc, argv, r);
|
||||
return disp_call_value_with_caller(This->ctx, get_object(prop->u.val),
|
||||
jsval_disp(jsthis ? jsthis : (IDispatch*)&This->IDispatchEx_iface),
|
||||
flags, argc, argv, r, caller);
|
||||
}
|
||||
case PROP_ACCESSOR:
|
||||
case PROP_IDX: {
|
||||
|
@ -585,9 +585,9 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t
|
|||
return hres;
|
||||
|
||||
if(is_object_instance(val)) {
|
||||
hres = disp_call_value(This->ctx, get_object(val),
|
||||
jsval_disp(jsthis ? jsthis : (IDispatch*)&This->IDispatchEx_iface),
|
||||
flags, argc, argv, r);
|
||||
hres = disp_call_value_with_caller(This->ctx, get_object(val),
|
||||
jsval_disp(jsthis ? jsthis : (IDispatch*)&This->IDispatchEx_iface),
|
||||
flags, argc, argv, r, caller);
|
||||
}else {
|
||||
FIXME("invoke %s\n", debugstr_jsval(val));
|
||||
hres = E_NOTIMPL;
|
||||
|
@ -2364,7 +2364,7 @@ HRESULT jsdisp_call(jsdisp_t *disp, DISPID id, WORD flags, unsigned argc, jsval_
|
|||
if(!prop)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
|
||||
return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, NULL);
|
||||
return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, &disp->ctx->jscaller->IServiceProvider_iface);
|
||||
}
|
||||
|
||||
HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
||||
|
@ -2379,10 +2379,11 @@ HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned
|
|||
if(!prop || prop->type == PROP_DELETED)
|
||||
return JS_E_INVALID_PROPERTY;
|
||||
|
||||
return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, NULL);
|
||||
return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, &disp->ctx->jscaller->IServiceProvider_iface);
|
||||
}
|
||||
|
||||
static HRESULT disp_invoke(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, DISPPARAMS *params, VARIANT *r)
|
||||
static HRESULT disp_invoke(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, DISPPARAMS *params, VARIANT *r,
|
||||
IServiceProvider *caller)
|
||||
{
|
||||
IDispatchEx *dispex;
|
||||
EXCEPINFO ei;
|
||||
|
@ -2391,7 +2392,7 @@ static HRESULT disp_invoke(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD f
|
|||
memset(&ei, 0, sizeof(ei));
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, params, r, &ei, &ctx->jscaller->IServiceProvider_iface);
|
||||
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, params, r, &ei, caller);
|
||||
IDispatchEx_Release(dispex);
|
||||
}else {
|
||||
UINT err = 0;
|
||||
|
@ -2489,7 +2490,7 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
|
|||
}
|
||||
|
||||
V_VT(&retv) = VT_EMPTY;
|
||||
hres = disp_invoke(ctx, disp, id, flags, &dp, ret ? &retv : NULL);
|
||||
hres = disp_invoke(ctx, disp, id, flags, &dp, ret ? &retv : NULL, &ctx->jscaller->IServiceProvider_iface);
|
||||
|
||||
for(i=0; i<argc; i++)
|
||||
VariantClear(dp.rgvarg+argc-i-1);
|
||||
|
@ -2529,8 +2530,8 @@ HRESULT disp_call_name(script_ctx_t *ctx, IDispatch *disp, const WCHAR *name, WO
|
|||
return disp_call(ctx, disp, id, flags, argc, argv, ret);
|
||||
}
|
||||
|
||||
HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||
jsval_t *r)
|
||||
HRESULT disp_call_value_with_caller(script_ctx_t *ctx, IDispatch *disp, jsval_t vthis, WORD flags, unsigned argc,
|
||||
jsval_t *argv, jsval_t *r, IServiceProvider *caller)
|
||||
{
|
||||
VARIANT buf[6], retv, *args = buf;
|
||||
IDispatch *jsthis;
|
||||
|
@ -2586,7 +2587,7 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, jsval_t vthis, WORD
|
|||
|
||||
if(SUCCEEDED(hres)) {
|
||||
V_VT(&retv) = VT_EMPTY;
|
||||
hres = disp_invoke(ctx, disp, DISPID_VALUE, flags, &dp, r ? &retv : NULL);
|
||||
hres = disp_invoke(ctx, disp, DISPID_VALUE, flags, &dp, r ? &retv : NULL, caller);
|
||||
}
|
||||
|
||||
for(i = 0; i < argc; i++)
|
||||
|
@ -2665,7 +2666,7 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val)
|
|||
if(V_VT(&var) == VT_DISPATCH)
|
||||
flags |= DISPATCH_PROPERTYPUTREF;
|
||||
|
||||
hres = disp_invoke(ctx, disp, id, flags, &dp, NULL);
|
||||
hres = disp_invoke(ctx, disp, id, flags, &dp, NULL, &ctx->jscaller->IServiceProvider_iface);
|
||||
VariantClear(&var);
|
||||
}
|
||||
|
||||
|
@ -2773,7 +2774,7 @@ HRESULT disp_propget(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t *val
|
|||
jsdisp_release(jsdisp);
|
||||
|
||||
V_VT(&var) = VT_EMPTY;
|
||||
hres = disp_invoke(ctx, disp, id, INVOKE_PROPERTYGET, &dp, &var);
|
||||
hres = disp_invoke(ctx, disp, id, INVOKE_PROPERTYGET, &dp, &var, &ctx->jscaller->IServiceProvider_iface);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = variant_to_jsval(ctx, &var, val);
|
||||
VariantClear(&var);
|
||||
|
|
|
@ -240,7 +240,7 @@ HRESULT init_dispex_from_constr(jsdisp_t*,script_ctx_t*,const builtin_info_t*,js
|
|||
|
||||
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT disp_call_name(script_ctx_t*,IDispatch*,const WCHAR*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT disp_call_value(script_ctx_t*,IDispatch*,jsval_t,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT disp_call_value_with_caller(script_ctx_t*,IDispatch*,jsval_t,WORD,unsigned,jsval_t*,jsval_t*,IServiceProvider*) DECLSPEC_HIDDEN;
|
||||
HRESULT jsdisp_call_value(jsdisp_t*,jsval_t,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT jsdisp_call(jsdisp_t*,DISPID,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT jsdisp_call_name(jsdisp_t*,const WCHAR*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
|
||||
|
@ -483,6 +483,12 @@ static inline DWORD make_grfdex(script_ctx_t *ctx, DWORD flags)
|
|||
return ((ctx->version & 0xff) << 28) | flags;
|
||||
}
|
||||
|
||||
static inline HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, jsval_t vthis, WORD flags, unsigned argc,
|
||||
jsval_t *argv, jsval_t *r)
|
||||
{
|
||||
return disp_call_value_with_caller(ctx, disp, vthis, flags, argc, argv, r, &ctx->jscaller->IServiceProvider_iface);
|
||||
}
|
||||
|
||||
#define FACILITY_JSCRIPT 10
|
||||
|
||||
#define MAKE_JSERROR(code) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_JSCRIPT, code)
|
||||
|
|
|
@ -114,6 +114,9 @@ DEFINE_EXPECT(testobj_newenum);
|
|||
DEFINE_EXPECT(testobj_getidfail_d);
|
||||
DEFINE_EXPECT(testobj_tolocalestr_d);
|
||||
DEFINE_EXPECT(testobj_tolocalestr_i);
|
||||
DEFINE_EXPECT(test_caller_get);
|
||||
DEFINE_EXPECT(test_caller_null);
|
||||
DEFINE_EXPECT(test_caller_obj);
|
||||
DEFINE_EXPECT(testdestrobj);
|
||||
DEFINE_EXPECT(enumvariant_next_0);
|
||||
DEFINE_EXPECT(enumvariant_next_1);
|
||||
|
@ -333,6 +336,44 @@ static IEnumVARIANTVtbl testEnumVARIANTVtbl = {
|
|||
|
||||
static IEnumVARIANT testEnumVARIANT = { &testEnumVARIANTVtbl };
|
||||
|
||||
static HRESULT WINAPI sp_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IServiceProvider, riid)) {
|
||||
*ppv = iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
|
||||
*ppv = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static ULONG WINAPI sp_AddRef(IServiceProvider *iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI sp_Release(IServiceProvider *iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI sp_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv)
|
||||
{
|
||||
ok(0, "unexpected call %s\n", wine_dbgstr_guid(guidService));
|
||||
*ppv = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IServiceProviderVtbl sp_vtbl = {
|
||||
sp_QueryInterface,
|
||||
sp_AddRef,
|
||||
sp_Release,
|
||||
sp_QueryService
|
||||
};
|
||||
|
||||
static IServiceProvider sp_obj = { &sp_vtbl };
|
||||
|
||||
static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
|
@ -629,6 +670,61 @@ static IDispatchExVtbl testObjVtbl = {
|
|||
|
||||
static IDispatchEx testObj = { &testObjVtbl };
|
||||
|
||||
static HRESULT WINAPI testcallerobj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
ok(id == DISPID_VALUE, "id = %ld\n", id);
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(pvarRes != NULL, "pvarRes == NULL\n");
|
||||
ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
|
||||
if(wFlags == DISPATCH_PROPERTYGET) {
|
||||
CHECK_EXPECT(test_caller_get);
|
||||
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
|
||||
ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
|
||||
ok(pei != NULL, "pei == NULL\n");
|
||||
ok(pspCaller != NULL, "pspCaller == NULL\n");
|
||||
ok(pspCaller != &sp_obj, "pspCaller == sp_obj\n");
|
||||
V_VT(pvarRes) = VT_DISPATCH;
|
||||
V_DISPATCH(pvarRes) = (IDispatch*)iface;
|
||||
}else if(pspCaller) {
|
||||
CHECK_EXPECT(test_caller_obj);
|
||||
ok(wFlags == DISPATCH_METHOD, "wFlags = %04x\n", wFlags);
|
||||
ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
|
||||
ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
|
||||
ok(pspCaller == &sp_obj, "pspCaller != sp_obj\n");
|
||||
V_VT(pvarRes) = VT_I4;
|
||||
V_I4(pvarRes) = 137;
|
||||
}else {
|
||||
CHECK_EXPECT(test_caller_null);
|
||||
ok(wFlags == DISPATCH_METHOD, "wFlags = %04x\n", wFlags);
|
||||
ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
|
||||
ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
|
||||
V_VT(pvarRes) = VT_I4;
|
||||
V_I4(pvarRes) = 42;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IDispatchExVtbl testcallerobj_vtbl = {
|
||||
DispatchEx_QueryInterface,
|
||||
DispatchEx_AddRef,
|
||||
DispatchEx_Release,
|
||||
DispatchEx_GetTypeInfoCount,
|
||||
DispatchEx_GetTypeInfo,
|
||||
DispatchEx_GetIDsOfNames,
|
||||
DispatchEx_Invoke,
|
||||
DispatchEx_GetDispID,
|
||||
testcallerobj_InvokeEx,
|
||||
DispatchEx_DeleteMemberByName,
|
||||
DispatchEx_DeleteMemberByDispID,
|
||||
DispatchEx_GetMemberProperties,
|
||||
DispatchEx_GetMemberName,
|
||||
DispatchEx_GetNextDispID,
|
||||
DispatchEx_GetNameSpaceParent
|
||||
};
|
||||
|
||||
static IDispatchEx testcallerobj = { &testcallerobj_vtbl };
|
||||
|
||||
static LONG test_destr_ref;
|
||||
|
||||
static ULONG WINAPI testDestrObj_AddRef(IDispatchEx *iface)
|
||||
|
@ -3214,6 +3310,7 @@ static void test_script_exprs(void)
|
|||
|
||||
static void test_invokeex(void)
|
||||
{
|
||||
static DISPID propput_dispid = DISPID_PROPERTYPUT;
|
||||
DISPPARAMS dp = {NULL}, dp_max = {NULL};
|
||||
DISPID func_id, max_id, prop_id;
|
||||
IActiveScript *script;
|
||||
|
@ -3442,6 +3539,52 @@ static void test_invokeex(void)
|
|||
|
||||
IDispatchEx_Release(dispex);
|
||||
IActiveScript_Release(script);
|
||||
|
||||
/* test InvokeEx with host prop and custom caller */
|
||||
hres = parse_script_expr(L"var o = {}; o", &v, &script);
|
||||
ok(hres == S_OK, "parse_script_expr failed: %08lx\n", hres);
|
||||
ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
|
||||
|
||||
hres = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IDispatchEx, (void**)&dispex);
|
||||
ok(hres == S_OK, "Could not get IDispatchEx iface: %08lx\n", hres);
|
||||
VariantClear(&v);
|
||||
|
||||
str = SysAllocString(L"caller");
|
||||
hres = IDispatchEx_GetDispID(dispex, str, fdexNameEnsure, &func_id);
|
||||
SysFreeString(str);
|
||||
ok(hres == S_OK, "GetDispID failed: %08lx\n", hres);
|
||||
|
||||
SET_EXPECT(test_caller_get);
|
||||
dp.cArgs = dp.cNamedArgs = 1;
|
||||
dp.rgvarg = &arg;
|
||||
dp.rgdispidNamedArgs = &propput_dispid;
|
||||
V_VT(&arg) = VT_DISPATCH;
|
||||
V_DISPATCH(&arg) = (IDispatch*)&testcallerobj;
|
||||
hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, NULL, NULL);
|
||||
ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres);
|
||||
todo_wine
|
||||
CHECK_CALLED(test_caller_get);
|
||||
|
||||
SET_EXPECT(test_caller_null);
|
||||
dp.cArgs = dp.cNamedArgs = 0;
|
||||
dp.rgvarg = NULL;
|
||||
dp.rgdispidNamedArgs = NULL;
|
||||
hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, NULL);
|
||||
ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres);
|
||||
ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
|
||||
ok(V_I4(&v) == 42, "V_I4(v) = %s\n", wine_dbgstr_variant(&v));
|
||||
CHECK_CALLED(test_caller_null);
|
||||
V_VT(&v) = VT_EMPTY;
|
||||
|
||||
SET_EXPECT(test_caller_obj);
|
||||
hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, &sp_obj);
|
||||
ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres);
|
||||
ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
|
||||
ok(V_I4(&v) == 137, "V_I4(v) = %s\n", wine_dbgstr_variant(&v));
|
||||
CHECK_CALLED(test_caller_obj);
|
||||
|
||||
IDispatchEx_Release(dispex);
|
||||
IActiveScript_Release(script);
|
||||
}
|
||||
|
||||
static void test_destructors(void)
|
||||
|
|
Loading…
Reference in a new issue