/*
 *    Misc marshaling routinues
 *
 * Copyright 2010 Huw Davies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
#include <stdarg.h>
#include <string.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "objbase.h"
#include "oleauto.h"
#include "dispex.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

#define NULL_RESULT    0x20000
#define NULL_EXCEPINFO 0x40000

HRESULT CALLBACK IDispatchEx_InvokeEx_Proxy(IDispatchEx* This, DISPID id, LCID lcid, WORD wFlags,
                                            DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei,
                                            IServiceProvider *pspCaller)
{
    HRESULT hr;
    VARIANT result;
    EXCEPINFO excep_info;
    UINT byref_args, arg, dummy_idx;
    VARIANT dummy_arg, *ref_arg = &dummy_arg, *copy_arg, *orig_arg = NULL;
    UINT *ref_idx = &dummy_idx;
    DWORD dword_flags = wFlags & 0xf;

    TRACE("(%p)->(%08x, %04x, %04x, %p, %p, %p, %p)\n", This, id, lcid, wFlags,
          pdp, pvarRes, pei, pspCaller);

    if(!pvarRes)
    {
        pvarRes = &result;
        dword_flags |= NULL_RESULT;
    }

    if(!pei)
    {
        pei = &excep_info;
        dword_flags |= NULL_EXCEPINFO;
    }

    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, dword_flags, pdp, pvarRes, pei, pspCaller,
                                          byref_args, ref_idx, ref_arg);

    if(byref_args)
    {
        CoTaskMemFree(pdp->rgvarg);
        pdp->rgvarg = orig_arg;
    }

    return hr;
}

HRESULT __RPC_STUB IDispatchEx_InvokeEx_Stub(IDispatchEx* This, DISPID id, LCID lcid, DWORD dwFlags,
                                             DISPPARAMS *pdp, VARIANT *result, EXCEPINFO *pei,
                                             IServiceProvider *pspCaller, UINT byref_args,
                                             UINT *ref_idx, VARIANT *ref_arg)
{
    HRESULT hr;
    UINT arg;
    VARTYPE *vt_list = NULL;

    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];

    if(dwFlags & NULL_RESULT) result = NULL;
    if(dwFlags & NULL_EXCEPINFO) pei = NULL;

    /* Create an array of the original VTs to check that the function doesn't change
       any on return. */
    if(byref_args)
    {
        vt_list = HeapAlloc(GetProcessHeap(), 0, pdp->cArgs * sizeof(vt_list[0]));
        if(!vt_list) return E_OUTOFMEMORY;
        for(arg = 0; arg < pdp->cArgs; arg++)
            vt_list[arg] = V_VT(pdp->rgvarg + arg);
    }

    hr = IDispatchEx_InvokeEx(This, id, lcid, dwFlags & 0xffff, pdp, result, pei, pspCaller);

    if(SUCCEEDED(hr) && byref_args)
    {
        for(arg = 0; arg < pdp->cArgs; arg++)
        {
            if(vt_list[arg] != V_VT(pdp->rgvarg + arg))
            {
                hr = DISP_E_BADCALLEE;
                break;
            }
        }
    }

    if(hr == DISP_E_EXCEPTION)
    {
        if(pei && pei->pfnDeferredFillIn)
        {
            pei->pfnDeferredFillIn(pei);
            pei->pfnDeferredFillIn = NULL;
        }
    }

    for(arg = 0; arg < byref_args; arg++)
        VariantInit(pdp->rgvarg + ref_idx[arg]);

    HeapFree(GetProcessHeap(), 0, vt_list);
    return hr;
}
