mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-21 12:14:10 +00:00
jscript: Implement SID_GetCaller for QueryService.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
parent
a9a3c65cd0
commit
6deee88a6c
|
@ -1900,6 +1900,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
jsdisp_t *This = impl_from_IDispatchEx(iface);
|
||||
IServiceProvider *prev_caller;
|
||||
dispex_prop_t *prop;
|
||||
jsexcept_t ei;
|
||||
HRESULT hres;
|
||||
|
@ -1917,6 +1918,11 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
|
||||
enter_script(This->ctx, &ei);
|
||||
|
||||
prev_caller = This->ctx->jscaller->caller;
|
||||
This->ctx->jscaller->caller = pspCaller;
|
||||
if(pspCaller)
|
||||
IServiceProvider_AddRef(pspCaller);
|
||||
|
||||
switch(wFlags) {
|
||||
case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
|
||||
wFlags = DISPATCH_METHOD;
|
||||
|
@ -2000,6 +2006,9 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
break;
|
||||
}
|
||||
|
||||
This->ctx->jscaller->caller = prev_caller;
|
||||
if(pspCaller)
|
||||
IServiceProvider_Release(pspCaller);
|
||||
return leave_script(This->ctx, hres);
|
||||
}
|
||||
|
||||
|
|
|
@ -428,6 +428,17 @@ static void release_named_item_list(JScript *This)
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT exec_global_code(script_ctx_t *ctx, bytecode_t *code, jsval_t *r)
|
||||
{
|
||||
IServiceProvider *prev_caller = ctx->jscaller->caller;
|
||||
HRESULT hres;
|
||||
|
||||
ctx->jscaller->caller = SP_CALLER_UNINITIALIZED;
|
||||
hres = exec_source(ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, 0, NULL, r);
|
||||
ctx->jscaller->caller = prev_caller;
|
||||
return hres;
|
||||
}
|
||||
|
||||
static void exec_queued_code(JScript *This)
|
||||
{
|
||||
bytecode_t *iter;
|
||||
|
@ -436,7 +447,7 @@ static void exec_queued_code(JScript *This)
|
|||
|
||||
LIST_FOR_EACH_ENTRY(iter, &This->queued_code, bytecode_t, entry) {
|
||||
enter_script(This->ctx, &ei);
|
||||
hres = exec_source(This->ctx, EXEC_GLOBAL, iter, &iter->global_code, NULL, NULL, NULL, 0, NULL, NULL);
|
||||
hres = exec_global_code(This->ctx, iter, NULL);
|
||||
leave_script(This->ctx, hres);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
|
@ -1103,7 +1114,7 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface,
|
|||
if(dwFlags & SCRIPTTEXT_ISEXPRESSION) {
|
||||
jsval_t r;
|
||||
|
||||
hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, 0, NULL, &r);
|
||||
hres = exec_global_code(This->ctx, code, &r);
|
||||
if(SUCCEEDED(hres)) {
|
||||
if(pvarResult)
|
||||
hres = jsval_to_variant(r, pvarResult);
|
||||
|
@ -1122,7 +1133,7 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface,
|
|||
if(!pvarResult && !is_started(This->ctx)) {
|
||||
list_add_tail(&This->queued_code, &code->entry);
|
||||
}else {
|
||||
hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, 0, NULL, NULL);
|
||||
hres = exec_global_code(This->ctx, code, NULL);
|
||||
if(code->is_persistent)
|
||||
list_add_tail(&This->persistent_code, &code->entry);
|
||||
else
|
||||
|
|
|
@ -331,12 +331,15 @@ typedef struct {
|
|||
|
||||
void release_cc(cc_ctx_t*) DECLSPEC_HIDDEN;
|
||||
|
||||
#define SP_CALLER_UNINITIALIZED ((IServiceProvider*)IntToPtr(-1))
|
||||
|
||||
typedef struct {
|
||||
IServiceProvider IServiceProvider_iface;
|
||||
|
||||
LONG ref;
|
||||
|
||||
script_ctx_t *ctx;
|
||||
IServiceProvider *caller;
|
||||
} JSCaller;
|
||||
|
||||
#include "jsval.h"
|
||||
|
|
|
@ -1034,6 +1034,14 @@ static HRESULT WINAPI JSCaller_QueryService(IServiceProvider *iface, REFGUID gui
|
|||
{
|
||||
JSCaller *This = impl_from_IServiceProvider(iface);
|
||||
|
||||
if(IsEqualGUID(guidService, &SID_GetCaller)) {
|
||||
TRACE("(%p)->(SID_GetCaller)\n", This);
|
||||
*ppv = NULL;
|
||||
if(!This->caller)
|
||||
return S_OK;
|
||||
return (This->caller == SP_CALLER_UNINITIALIZED) ? E_NOINTERFACE : IServiceProvider_QueryInterface(This->caller, riid, ppv);
|
||||
}
|
||||
|
||||
if(IsEqualGUID(guidService, &SID_VariantConversion) && This->ctx && This->ctx->active_script) {
|
||||
TRACE("(%p)->(SID_VariantConversion)\n", This);
|
||||
return IActiveScript_QueryInterface(This->ctx->active_script, riid, ppv);
|
||||
|
@ -1063,6 +1071,7 @@ HRESULT create_jscaller(script_ctx_t *ctx)
|
|||
ret->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
|
||||
ret->ref = 1;
|
||||
ret->ctx = ctx;
|
||||
ret->caller = SP_CALLER_UNINITIALIZED;
|
||||
|
||||
ctx->jscaller = ret;
|
||||
return S_OK;
|
||||
|
|
|
@ -74,14 +74,23 @@ static const CLSID CLSID_JScript =
|
|||
#define CLEAR_CALLED(func) \
|
||||
expect_ ## func = called_ ## func = FALSE
|
||||
|
||||
DEFINE_EXPECT(sp_caller_QI_NULL);
|
||||
DEFINE_EXPECT(testArgConv);
|
||||
DEFINE_EXPECT(testGetCaller);
|
||||
DEFINE_EXPECT(testGetCallerJS);
|
||||
DEFINE_EXPECT(testGetCallerNested);
|
||||
DEFINE_EXPECT(OnEnterScript);
|
||||
DEFINE_EXPECT(OnLeaveScript);
|
||||
|
||||
static IActiveScriptParse *active_script_parser;
|
||||
static IVariantChangeType *script_change_type;
|
||||
static IDispatch *stored_obj;
|
||||
static IServiceProvider *test_get_caller_sp;
|
||||
|
||||
#define DISPID_TEST_TESTARGCONV 0x1000
|
||||
#define DISPID_TEST_TESTGETCALLER 0x1001
|
||||
#define DISPID_TEST_TESTGETCALLERJS 0x1002
|
||||
#define DISPID_TEST_TESTGETCALLERNESTED 0x1003
|
||||
|
||||
typedef struct {
|
||||
int int_result;
|
||||
|
@ -254,6 +263,55 @@ static void test_caller(IServiceProvider *caller, IDispatch *arg_obj)
|
|||
IVariantChangeType_Release(change_type);
|
||||
}
|
||||
|
||||
static IServiceProvider sp_caller_obj;
|
||||
|
||||
static HRESULT WINAPI sp_caller_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IServiceProvider, riid))
|
||||
*ppv = &sp_caller_obj;
|
||||
else {
|
||||
ok(IsEqualGUID(&IID_NULL, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
|
||||
CHECK_EXPECT(sp_caller_QI_NULL);
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI sp_caller_AddRef(IServiceProvider *iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI sp_caller_Release(IServiceProvider *iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI sp_caller_QueryService(IServiceProvider *iface, REFGUID guidService,
|
||||
REFIID riid, void **ppv)
|
||||
{
|
||||
if(IsEqualGUID(guidService, &SID_GetCaller)) {
|
||||
ok(IsEqualGUID(riid, &IID_IServiceProvider), "unexpected riid %s\n", wine_dbgstr_guid(riid));
|
||||
*ppv = NULL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ok(0, "unexpected guidService %s with riid %s\n", wine_dbgstr_guid(guidService), wine_dbgstr_guid(riid));
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static const IServiceProviderVtbl sp_caller_vtbl = {
|
||||
sp_caller_QueryInterface,
|
||||
sp_caller_AddRef,
|
||||
sp_caller_Release,
|
||||
sp_caller_QueryService
|
||||
};
|
||||
|
||||
static IServiceProvider sp_caller_obj = { &sp_caller_vtbl };
|
||||
|
||||
static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
if(IsEqualGUID(riid, &IID_IUnknown)) {
|
||||
|
@ -350,6 +408,21 @@ static HRESULT WINAPI Test_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD gr
|
|||
*pid = DISPID_TEST_TESTARGCONV;
|
||||
return S_OK;
|
||||
}
|
||||
if(!lstrcmpW(bstrName, L"testGetCaller")) {
|
||||
ok(grfdex == fdexNameCaseSensitive, "grfdex = %lx\n", grfdex);
|
||||
*pid = DISPID_TEST_TESTGETCALLER;
|
||||
return S_OK;
|
||||
}
|
||||
if(!lstrcmpW(bstrName, L"testGetCallerJS")) {
|
||||
ok(grfdex == fdexNameCaseSensitive, "grfdex = %lx\n", grfdex);
|
||||
*pid = DISPID_TEST_TESTGETCALLERJS;
|
||||
return S_OK;
|
||||
}
|
||||
if(!lstrcmpW(bstrName, L"testGetCallerNested")) {
|
||||
ok(grfdex == fdexNameCaseSensitive, "grfdex = %lx\n", grfdex);
|
||||
*pid = DISPID_TEST_TESTGETCALLERNESTED;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
@ -357,6 +430,9 @@ static HRESULT WINAPI Test_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD gr
|
|||
static HRESULT WINAPI Test_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
IServiceProvider *caller = (void*)0xdeadbeef;
|
||||
HRESULT hres;
|
||||
|
||||
ok(pspCaller != NULL, "pspCaller == NULL\n");
|
||||
|
||||
switch(id) {
|
||||
|
@ -380,6 +456,80 @@ static HRESULT WINAPI Test_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WO
|
|||
IDispatch_AddRef(stored_obj);
|
||||
break;
|
||||
|
||||
case DISPID_TEST_TESTGETCALLER: {
|
||||
void *iface = (void*)0xdeadbeef;
|
||||
|
||||
CHECK_EXPECT(testGetCaller);
|
||||
CHECK_CALLED(OnEnterScript);
|
||||
|
||||
ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
|
||||
ok(!pvarRes, "pvarRes != NULL\n");
|
||||
ok(pei != NULL, "pei == NULL\n");
|
||||
|
||||
SET_EXPECT(OnEnterScript);
|
||||
SET_EXPECT(OnLeaveScript);
|
||||
SET_EXPECT(testGetCallerNested);
|
||||
hres = IActiveScriptParse_ParseScriptText(active_script_parser, L"testGetCallerNested(1,2)",
|
||||
NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
|
||||
ok(hres == S_OK, "ParseScriptText failed: %08lx\n", hres);
|
||||
CHECK_CALLED(testGetCallerNested);
|
||||
CHECK_CALLED(OnLeaveScript);
|
||||
CHECK_CALLED(OnEnterScript);
|
||||
SET_EXPECT(OnLeaveScript);
|
||||
|
||||
hres = IServiceProvider_QueryService(pspCaller, &SID_GetCaller, &IID_IServiceProvider, (void**)&caller);
|
||||
ok(hres == S_OK, "Could not get SID_GetCaller service: %08lx\n", hres);
|
||||
ok(caller == test_get_caller_sp, "caller != test_get_caller_sp\n");
|
||||
if(caller) IServiceProvider_Release(caller);
|
||||
|
||||
if(test_get_caller_sp)
|
||||
SET_EXPECT(sp_caller_QI_NULL);
|
||||
hres = IServiceProvider_QueryService(pspCaller, &SID_GetCaller, &IID_NULL, &iface);
|
||||
ok(hres == (test_get_caller_sp ? E_NOINTERFACE : S_OK), "Could not query SID_GetCaller with IID_NULL: %08lx\n", hres);
|
||||
ok(iface == NULL, "iface != NULL\n");
|
||||
if(test_get_caller_sp)
|
||||
CHECK_CALLED(sp_caller_QI_NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
case DISPID_TEST_TESTGETCALLERJS:
|
||||
CHECK_EXPECT(testGetCallerJS);
|
||||
|
||||
ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
|
||||
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
|
||||
ok(!pvarRes, "pvarRes != NULL\n");
|
||||
ok(pei != NULL, "pei == NULL\n");
|
||||
ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));
|
||||
ok(V_I4(pdp->rgvarg) == 42, "V_I4(rgvarg) = %ld\n", V_I4(pdp->rgvarg));
|
||||
|
||||
hres = IServiceProvider_QueryService(pspCaller, &SID_GetCaller, &IID_IServiceProvider, (void**)&caller);
|
||||
ok(hres == E_NOINTERFACE, "QueryService(SID_GetCaller) returned: %08lx\n", hres);
|
||||
ok(caller == NULL, "caller != NULL\n");
|
||||
break;
|
||||
|
||||
case DISPID_TEST_TESTGETCALLERNESTED:
|
||||
CHECK_EXPECT(testGetCallerNested);
|
||||
|
||||
ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
|
||||
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
|
||||
ok(!pvarRes, "pvarRes != NULL\n");
|
||||
ok(pei != NULL, "pei == NULL\n");
|
||||
ok(V_VT(&pdp->rgvarg[0]) == VT_I4, "V_VT(rgvarg[0]) = %d\n", V_VT(&pdp->rgvarg[0]));
|
||||
ok(V_VT(&pdp->rgvarg[1]) == VT_I4, "V_VT(rgvarg[1]) = %d\n", V_VT(&pdp->rgvarg[1]));
|
||||
ok(V_I4(&pdp->rgvarg[0]) == 2, "V_I4(rgvarg[0]) = %ld\n", V_I4(&pdp->rgvarg[0]));
|
||||
ok(V_I4(&pdp->rgvarg[1]) == 1, "V_I4(rgvarg[1]) = %ld\n", V_I4(&pdp->rgvarg[1]));
|
||||
|
||||
hres = IServiceProvider_QueryService(pspCaller, &SID_GetCaller, &IID_IServiceProvider, (void**)&caller);
|
||||
ok(hres == E_NOINTERFACE, "QueryService(SID_GetCaller) returned: %08lx\n", hres);
|
||||
ok(caller == NULL, "caller != NULL\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(0, "unexpected call\n");
|
||||
return E_NOTIMPL;
|
||||
|
@ -542,22 +692,32 @@ static IActiveScriptParse *create_script(void)
|
|||
|
||||
static void run_scripts(void)
|
||||
{
|
||||
IActiveScriptParse *parser;
|
||||
IActiveScript *active_script;
|
||||
DISPPARAMS dp = { 0 };
|
||||
IDispatchEx *dispex;
|
||||
IDispatch *disp;
|
||||
DISPID dispid;
|
||||
HRESULT hres;
|
||||
VARIANT var;
|
||||
BSTR bstr;
|
||||
|
||||
parser = create_script();
|
||||
active_script_parser = create_script();
|
||||
|
||||
hres = IActiveScriptParse_QueryInterface(parser, &IID_IVariantChangeType, (void**)&script_change_type);
|
||||
hres = IActiveScriptParse_QueryInterface(active_script_parser, &IID_IVariantChangeType, (void**)&script_change_type);
|
||||
ok(hres == S_OK, "Could not get IVariantChangeType iface: %08lx\n", hres);
|
||||
|
||||
SET_EXPECT(OnEnterScript); /* checked in callback */
|
||||
SET_EXPECT(testArgConv);
|
||||
parse_script(parser,
|
||||
SET_EXPECT(testGetCallerJS);
|
||||
parse_script(active_script_parser,
|
||||
L"var obj = {"
|
||||
L" toString: function() { return 'strval'; },"
|
||||
L" valueOf: function() { return 10; }"
|
||||
L"};"
|
||||
L"testArgConv(obj);");
|
||||
L"testArgConv(obj);"
|
||||
L"function testGetCallerFunc() { testGetCaller(); };"
|
||||
L"testGetCallerJS(42);");
|
||||
CHECK_CALLED(testGetCallerJS);
|
||||
CHECK_CALLED(testArgConv);
|
||||
CHECK_CALLED(OnLeaveScript); /* set in callback */
|
||||
|
||||
|
@ -565,7 +725,47 @@ static void run_scripts(void)
|
|||
IDispatch_Release(stored_obj);
|
||||
IVariantChangeType_Release(script_change_type);
|
||||
|
||||
IActiveScriptParse_Release(parser);
|
||||
hres = IActiveScriptParse_QueryInterface(active_script_parser, &IID_IActiveScript, (void**)&active_script);
|
||||
ok(hres == S_OK, "Could not get IActiveScript: %08lx\n", hres);
|
||||
hres = IActiveScript_GetScriptDispatch(active_script, NULL, &disp);
|
||||
ok(hres == S_OK, "GetScriptDispatch failed: %08lx\n", hres);
|
||||
IActiveScript_Release(active_script);
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
ok(hres == S_OK, "Could not get IDispatchEx: %08lx\n", hres);
|
||||
IDispatch_Release(disp);
|
||||
bstr = SysAllocString(L"testGetCallerFunc");
|
||||
hres = IDispatchEx_GetDispID(dispex, bstr, 0, &dispid);
|
||||
ok(hres == S_OK, "GetDispID failed: %08lx\n", hres);
|
||||
SysFreeString(bstr);
|
||||
|
||||
hres = IDispatchEx_InvokeEx(dispex, dispid, 0, DISPATCH_PROPERTYGET, &dp, &var, NULL, NULL);
|
||||
ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres);
|
||||
ok(V_VT(&var) == VT_DISPATCH, "V_VT(testGetCallerFunc) = %d\n", V_VT(&var));
|
||||
ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(testGetCallerFunc) = NULL\n");
|
||||
IDispatchEx_Release(dispex);
|
||||
hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IDispatchEx, (void**)&dispex);
|
||||
ok(hres == S_OK, "Could not get IDispatchEx: %08lx\n", hres);
|
||||
IDispatch_Release(V_DISPATCH(&var));
|
||||
|
||||
SET_EXPECT(OnEnterScript);
|
||||
SET_EXPECT(OnLeaveScript);
|
||||
SET_EXPECT(testGetCaller);
|
||||
hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, NULL, NULL, NULL);
|
||||
ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres);
|
||||
CHECK_CALLED(testGetCaller);
|
||||
CHECK_CALLED(OnLeaveScript);
|
||||
test_get_caller_sp = &sp_caller_obj;
|
||||
SET_EXPECT(OnEnterScript);
|
||||
SET_EXPECT(OnLeaveScript);
|
||||
SET_EXPECT(testGetCaller);
|
||||
hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, NULL, NULL, test_get_caller_sp);
|
||||
ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres);
|
||||
CHECK_CALLED(testGetCaller);
|
||||
CHECK_CALLED(OnLeaveScript);
|
||||
IDispatchEx_Release(dispex);
|
||||
|
||||
IActiveScriptParse_Release(active_script_parser);
|
||||
active_script_parser = NULL;
|
||||
}
|
||||
|
||||
static BOOL check_jscript(void)
|
||||
|
|
Loading…
Reference in a new issue