Commit df07561c authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

dispex: Implement proxy and stub for IDispatchEx_InvokeEx.

parent 2efd2355
......@@ -14396,6 +14396,10 @@ wine_fn_config_dll dispex
wine_fn_config_makefile dlls/dispex "dlls/Makedll.rules \$(MAKEDEP)"
test "x$enable_dispex" != xno && wine_fn_append_file ALL_DLL_DIRS "dlls/dispex"
wine_fn_config_test dlls/dispex/tests dispex_test
wine_fn_config_makefile dlls/dispex/tests "Maketest.rules \$(MAKEDEP)"
test "x$enable_tests" != xno && wine_fn_append_file ALL_TEST_DIRS "dlls/dispex/tests"
wine_fn_config_dll display.drv16
wine_fn_config_makefile dlls/display.drv16 "dlls/Makedll.rules \$(MAKEDEP)"
test "x$enable_win16" != xno && wine_fn_append_file ALL_DLL_DIRS "dlls/display.drv16"
......@@ -17080,6 +17084,7 @@ do
"dlls/dinput8/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dinput8/Makefile" ;;
"dlls/dispdib.dll16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dispdib.dll16/Makefile" ;;
"dlls/dispex/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dispex/Makefile" ;;
"dlls/dispex/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dispex/tests/Makefile" ;;
"dlls/display.drv16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/display.drv16/Makefile" ;;
"dlls/dmband/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dmband/Makefile" ;;
"dlls/dmcompos/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dmcompos/Makefile" ;;
......
......@@ -2260,6 +2260,7 @@ WINE_CONFIG_TEST(dlls/dinput/tests)
WINE_CONFIG_DLL(dinput8,,[dinput8])
WINE_CONFIG_DLL(dispdib.dll16,enable_win16)
WINE_CONFIG_DLL(dispex)
WINE_CONFIG_TEST(dlls/dispex/tests)
WINE_CONFIG_DLL(display.drv16,enable_win16)
WINE_CONFIG_DLL(dmband)
WINE_CONFIG_DLL(dmcompos)
......
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../../..
SRCDIR = @srcdir@
VPATH = @srcdir@
TESTDLL = dispex.dll
IMPORTS = oleaut32 ole32 rpcrt4 user32 gdi32 advapi32 kernel32
C_SRCS = \
marshal.c
@MAKE_TEST_RULES@
......@@ -41,18 +41,92 @@ HRESULT CALLBACK IDispatchEx_InvokeEx_Proxy(IDispatchEx* This, DISPID id, LCID l
DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei,
IServiceProvider *pspCaller)
{
FIXME("(%p)->(%08x, %04x, %04x, %p, %p, %p, %p): stub\n", This, id, lcid, wFlags,
HRESULT hr;
VARIANT result;
EXCEPINFO excep_info;
UINT byref_args, arg;
VARIANT dummy_arg, *ref_arg = &dummy_arg, *copy_arg, *orig_arg = NULL;
UINT *ref_idx = NULL;
TRACE("(%p)->(%08x, %04x, %04x, %p, %p, %p, %p)\n", This, id, lcid, wFlags,
pdp, pvarRes, pei, pspCaller);
return E_NOTIMPL;
if(!pvarRes) pvarRes = &result;
if(!pei) pei = &excep_info;
for(arg = 0, byref_args = 0; arg < pdp->cArgs; arg++)
if(V_ISBYREF(pdp->rgvarg + arg)) byref_args++;
if(byref_args)
{
DWORD size = pdp->cArgs * sizeof(VARIANT) +
byref_args * (sizeof(VARIANT) + sizeof(UINT));
copy_arg = CoTaskMemAlloc(size);
if(!copy_arg) return E_OUTOFMEMORY;
ref_arg = copy_arg + pdp->cArgs;
ref_idx = (UINT*)(ref_arg + byref_args);
/* copy the byref args to ref_arg[], the others go to copy_arg[] */
for(arg = 0, byref_args = 0; arg < pdp->cArgs; arg++)
{
if(V_ISBYREF(pdp->rgvarg + arg))
{
ref_arg[byref_args] = pdp->rgvarg[arg];
ref_idx[byref_args] = arg;
VariantInit(copy_arg + arg);
byref_args++;
}
else
copy_arg[arg] = pdp->rgvarg[arg];
}
orig_arg = pdp->rgvarg;
pdp->rgvarg = copy_arg;
}
hr = IDispatchEx_RemoteInvokeEx_Proxy(This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller,
byref_args, ref_idx, ref_arg);
if(byref_args)
{
CoTaskMemFree(pdp->rgvarg);
pdp->rgvarg = orig_arg;
}
if(pvarRes == &result) VariantClear(pvarRes);
if(pei == &excep_info)
{
SysFreeString(pei->bstrSource);
SysFreeString(pei->bstrDescription);
SysFreeString(pei->bstrHelpFile);
}
return hr;
}
HRESULT __RPC_STUB IDispatchEx_InvokeEx_Stub(IDispatchEx* This, DISPID id, LCID lcid, DWORD dwFlags,
DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei,
IServiceProvider *pspCaller, UINT cvarRefArg,
UINT *rgiRefArg, VARIANT *rgvarRefArg)
DISPPARAMS *pdp, VARIANT *result, EXCEPINFO *pei,
IServiceProvider *pspCaller, UINT byref_args,
UINT *ref_idx, VARIANT *ref_arg)
{
FIXME("(%p)->(%08x, %04x, %08x, %p, %p, %p, %p, %d, %p, %p): stub\n", This, id, lcid, dwFlags,
pdp, pvarRes, pei, pspCaller, cvarRefArg, rgiRefArg, rgvarRefArg);
return E_NOTIMPL;
HRESULT hr;
UINT arg;
TRACE("(%p)->(%08x, %04x, %08x, %p, %p, %p, %p, %d, %p, %p)\n", This, id, lcid, dwFlags,
pdp, result, pei, pspCaller, byref_args, ref_idx, ref_arg);
VariantInit(result);
memset(pei, 0, sizeof(*pei));
for(arg = 0; arg < byref_args; arg++)
pdp->rgvarg[ref_idx[arg]] = ref_arg[arg];
hr = IDispatchEx_InvokeEx(This, id, lcid, dwFlags, pdp, result, pei, pspCaller);
for(arg = 0; arg < byref_args; arg++)
VariantInit(pdp->rgvarg + ref_idx[arg]);
return hr;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment