/*
 *	TYPELIB Marshaler
 *
 *	Copyright 2002,2005	Marcus Meissner
 *
 * The olerelay debug channel allows you to see calls marshalled by
 * the typelib marshaller. It is not a generic COM relaying system.
 *
 * 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 "config.h"
#include "wine/port.h"

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winreg.h"
#include "winuser.h"

#include "ole2.h"
#include "propidl.h" /* for LPSAFEARRAY_User* functions */
#include "typelib.h"
#include "variant.h"
#include "wine/debug.h"
#include "wine/exception.h"

static const WCHAR IDispatchW[] = { 'I','D','i','s','p','a','t','c','h',0};

WINE_DEFAULT_DEBUG_CHANNEL(ole);
WINE_DECLARE_DEBUG_CHANNEL(olerelay);

#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))

static HRESULT TMarshalDispatchChannel_Create(
    IRpcChannelBuffer *pDelegateChannel, REFIID tmarshal_riid,
    IRpcChannelBuffer **ppChannel);

typedef struct _marshal_state {
    LPBYTE	base;
    int		size;
    int		curoff;
} marshal_state;

/* used in the olerelay code to avoid having the L"" stuff added by debugstr_w */
static char *relaystr(WCHAR *in) {
    char *tmp = (char *)debugstr_w(in);
    tmp += 2;
    tmp[strlen(tmp)-1] = '\0';
    return tmp;
}

static HRESULT
xbuf_resize(marshal_state *buf, DWORD newsize)
{
    if(buf->size >= newsize)
        return S_FALSE;

    if(buf->base)
    {
        buf->base = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buf->base, newsize);
        if(!buf->base)
            return E_OUTOFMEMORY;
    }
    else
    {
        buf->base = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, newsize);
        if(!buf->base)
            return E_OUTOFMEMORY;
    }
    buf->size = newsize;
    return S_OK;
}

static HRESULT
xbuf_add(marshal_state *buf, const BYTE *stuff, DWORD size)
{
    HRESULT hr;

    if(buf->size - buf->curoff < size)
    {
        hr = xbuf_resize(buf, buf->size + size + 100);
        if(FAILED(hr)) return hr;
    }
    memcpy(buf->base+buf->curoff,stuff,size);
    buf->curoff += size;
    return S_OK;
}

static HRESULT
xbuf_get(marshal_state *buf, LPBYTE stuff, DWORD size) {
    if (buf->size < buf->curoff+size) return E_FAIL;
    memcpy(stuff,buf->base+buf->curoff,size);
    buf->curoff += size;
    return S_OK;
}

static HRESULT
xbuf_skip(marshal_state *buf, DWORD size) {
    if (buf->size < buf->curoff+size) return E_FAIL;
    buf->curoff += size;
    return S_OK;
}

static HRESULT
_unmarshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN *pUnk) {
    IStream		*pStm;
    ULARGE_INTEGER	newpos;
    LARGE_INTEGER	seekto;
    ULONG		res;
    HRESULT		hres;
    DWORD		xsize;

    TRACE("...%s...\n",debugstr_guid(riid));
    
    *pUnk = NULL;
    hres = xbuf_get(buf,(LPBYTE)&xsize,sizeof(xsize));
    if (hres) {
        ERR("xbuf_get failed\n");
        return hres;
    }
    
    if (xsize == 0) return S_OK;
    
    hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
    if (hres) {
	ERR("Stream create failed %x\n",hres);
	return hres;
    }
    
    hres = IStream_Write(pStm,buf->base+buf->curoff,xsize,&res);
    if (hres) {
        ERR("stream write %x\n",hres);
        return hres;
    }
    
    memset(&seekto,0,sizeof(seekto));
    hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
    if (hres) {
        ERR("Failed Seek %x\n",hres);
        return hres;
    }
    
    hres = CoUnmarshalInterface(pStm,riid,(LPVOID*)pUnk);
    if (hres) {
	ERR("Unmarshalling interface %s failed with %x\n",debugstr_guid(riid),hres);
	return hres;
    }
    
    IStream_Release(pStm);
    return xbuf_skip(buf,xsize);
}

static HRESULT
_marshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN pUnk) {
    LPBYTE		tempbuf = NULL;
    IStream		*pStm = NULL;
    STATSTG		ststg;
    ULARGE_INTEGER	newpos;
    LARGE_INTEGER	seekto;
    ULONG		res;
    DWORD		xsize;
    HRESULT		hres;

    if (!pUnk) {
	/* this is valid, if for instance we serialize
	 * a VT_DISPATCH with NULL ptr which apparently
	 * can happen. S_OK to make sure we continue
	 * serializing.
	 */
        WARN("pUnk is NULL\n");
        xsize = 0;
        return xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
    }

    hres = E_FAIL;

    TRACE("...%s...\n",debugstr_guid(riid));
    
    hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
    if (hres) {
	ERR("Stream create failed %x\n",hres);
	goto fail;
    }
    
    hres = CoMarshalInterface(pStm,riid,pUnk,0,NULL,0);
    if (hres) {
	ERR("Marshalling interface %s failed with %x\n", debugstr_guid(riid), hres);
	goto fail;
    }
    
    hres = IStream_Stat(pStm,&ststg,STATFLAG_NONAME);
    if (hres) {
        ERR("Stream stat failed\n");
        goto fail;
    }
    
    tempbuf = HeapAlloc(GetProcessHeap(), 0, ststg.cbSize.u.LowPart);
    memset(&seekto,0,sizeof(seekto));
    hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
    if (hres) {
        ERR("Failed Seek %x\n",hres);
        goto fail;
    }
    
    hres = IStream_Read(pStm,tempbuf,ststg.cbSize.u.LowPart,&res);
    if (hres) {
        ERR("Failed Read %x\n",hres);
        goto fail;
    }
    
    xsize = ststg.cbSize.u.LowPart;
    xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
    hres = xbuf_add(buf,tempbuf,ststg.cbSize.u.LowPart);
    
    HeapFree(GetProcessHeap(),0,tempbuf);
    IStream_Release(pStm);
    
    return hres;
    
fail:
    xsize = 0;
    xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
    if (pStm) IUnknown_Release(pStm);
    HeapFree(GetProcessHeap(), 0, tempbuf);
    return hres;
}

/********************* OLE Proxy/Stub Factory ********************************/
static HRESULT WINAPI
PSFacBuf_QueryInterface(LPPSFACTORYBUFFER iface, REFIID iid, LPVOID *ppv) {
    if (IsEqualIID(iid,&IID_IPSFactoryBuffer)||IsEqualIID(iid,&IID_IUnknown)) {
        *ppv = iface;
	/* No ref counting, static class */
	return S_OK;
    }
    FIXME("(%s) unknown IID?\n",debugstr_guid(iid));
    return E_NOINTERFACE;
}

static ULONG WINAPI PSFacBuf_AddRef(LPPSFACTORYBUFFER iface) { return 2; }
static ULONG WINAPI PSFacBuf_Release(LPPSFACTORYBUFFER iface) { return 1; }

static HRESULT
_get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) {
    HRESULT	hres;
    HKEY	ikey;
    char	tlguid[200],typelibkey[300],interfacekey[300],ver[100];
    char	tlfn[260];
    OLECHAR	tlfnW[260];
    DWORD	tlguidlen, verlen, type;
    LONG	tlfnlen;
    ITypeLib	*tl;

    sprintf( interfacekey, "Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib",
	riid->Data1, riid->Data2, riid->Data3,
	riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
	riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]
    );

    if (RegOpenKeyA(HKEY_CLASSES_ROOT,interfacekey,&ikey)) {
	ERR("No %s key found.\n",interfacekey);
       	return E_FAIL;
    }
    tlguidlen = sizeof(tlguid);
    if (RegQueryValueExA(ikey,NULL,NULL,&type,(LPBYTE)tlguid,&tlguidlen)) {
	ERR("Getting typelib guid failed.\n");
	RegCloseKey(ikey);
	return E_FAIL;
    }
    verlen = sizeof(ver);
    if (RegQueryValueExA(ikey,"Version",NULL,&type,(LPBYTE)ver,&verlen)) {
	ERR("Could not get version value?\n");
	RegCloseKey(ikey);
	return E_FAIL;
    }
    RegCloseKey(ikey);
    sprintf(typelibkey,"Typelib\\%s\\%s\\0\\win%u",tlguid,ver,(sizeof(void*) == 8) ? 64 : 32);
    tlfnlen = sizeof(tlfn);
    if (RegQueryValueA(HKEY_CLASSES_ROOT,typelibkey,tlfn,&tlfnlen)) {
	ERR("Could not get typelib fn?\n");
	return E_FAIL;
    }
    MultiByteToWideChar(CP_ACP, 0, tlfn, -1, tlfnW, sizeof(tlfnW) / sizeof(tlfnW[0]));
    hres = LoadTypeLib(tlfnW,&tl);
    if (hres) {
	ERR("Failed to load typelib for %s, but it should be there.\n",debugstr_guid(riid));
	return hres;
    }
    hres = ITypeLib_GetTypeInfoOfGuid(tl,riid,ti);
    if (hres) {
	ERR("typelib does not contain info for %s?\n",debugstr_guid(riid));
	ITypeLib_Release(tl);
	return hres;
    }
    ITypeLib_Release(tl);
    return hres;
}

/*
 * Determine the number of functions including all inherited functions.
 * Note for non-dual dispinterfaces we simply return the size of IDispatch.
 */
static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num)
{
    HRESULT hres;
    TYPEATTR *attr;
    ITypeInfo *tinfo2;

    *num = 0;
    hres = ITypeInfo_GetTypeAttr(tinfo, &attr);
    if (hres) {
        ERR("GetTypeAttr failed with %x\n",hres);
        return hres;
    }

    if(attr->typekind == TKIND_DISPATCH && (attr->wTypeFlags & TYPEFLAG_FDUAL))
    {
        HREFTYPE href;
        hres = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href);
        if(FAILED(hres))
        {
            ERR("Unable to get interface href from dual dispinterface\n");
            goto end;
        }
        hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
        if(FAILED(hres))
        {
            ERR("Unable to get interface from dual dispinterface\n");
            goto end;
        }
        hres = num_of_funcs(tinfo2, num);
        ITypeInfo_Release(tinfo2);
    }
    else
    {
        *num = attr->cbSizeVft / 4;
    }

 end:
    ITypeInfo_ReleaseTypeAttr(tinfo, attr);
    return hres;
}

#ifdef __i386__

#include "pshpack1.h"

typedef struct _TMAsmProxy {
    BYTE	popleax;
    BYTE	pushlval;
    DWORD	nr;
    BYTE	pushleax;
    BYTE	lcall;
    DWORD	xcall;
    BYTE	lret;
    WORD	bytestopop;
    BYTE	nop;
} TMAsmProxy;

#include "poppack.h"

#else /* __i386__ */
# warning You need to implement stubless proxies for your architecture
typedef struct _TMAsmProxy {
} TMAsmProxy;
#endif

typedef struct _TMProxyImpl {
    LPVOID                             *lpvtbl;
    const IRpcProxyBufferVtbl          *lpvtbl2;
    LONG				ref;

    TMAsmProxy				*asmstubs;
    ITypeInfo*				tinfo;
    IRpcChannelBuffer*			chanbuf;
    IID					iid;
    CRITICAL_SECTION	crit;
    IUnknown				*outerunknown;
    IDispatch				*dispatch;
    IRpcProxyBuffer			*dispatch_proxy;
} TMProxyImpl;

static HRESULT WINAPI
TMProxyImpl_QueryInterface(LPRPCPROXYBUFFER iface, REFIID riid, LPVOID *ppv)
{
    TRACE("()\n");
    if (IsEqualIID(riid,&IID_IUnknown)||IsEqualIID(riid,&IID_IRpcProxyBuffer)) {
        *ppv = iface;
        IRpcProxyBuffer_AddRef(iface);
        return S_OK;
    }
    FIXME("no interface for %s\n",debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI
TMProxyImpl_AddRef(LPRPCPROXYBUFFER iface)
{
    ICOM_THIS_MULTI(TMProxyImpl,lpvtbl2,iface);
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);

    return refCount;
}

static ULONG WINAPI
TMProxyImpl_Release(LPRPCPROXYBUFFER iface)
{
    ICOM_THIS_MULTI(TMProxyImpl,lpvtbl2,iface);
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);

    if (!refCount)
    {
        if (This->dispatch_proxy) IRpcProxyBuffer_Release(This->dispatch_proxy);
        This->crit.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection(&This->crit);
        if (This->chanbuf) IRpcChannelBuffer_Release(This->chanbuf);
        VirtualFree(This->asmstubs, 0, MEM_RELEASE);
        HeapFree(GetProcessHeap(), 0, This->lpvtbl);
        ITypeInfo_Release(This->tinfo);
        CoTaskMemFree(This);
    }
    return refCount;
}

static HRESULT WINAPI
TMProxyImpl_Connect(
    LPRPCPROXYBUFFER iface,IRpcChannelBuffer* pRpcChannelBuffer)
{
    ICOM_THIS_MULTI(TMProxyImpl, lpvtbl2, iface);

    TRACE("(%p)\n", pRpcChannelBuffer);

    EnterCriticalSection(&This->crit);

    IRpcChannelBuffer_AddRef(pRpcChannelBuffer);
    This->chanbuf = pRpcChannelBuffer;

    LeaveCriticalSection(&This->crit);

    if (This->dispatch_proxy)
    {
        IRpcChannelBuffer *pDelegateChannel;
        HRESULT hr = TMarshalDispatchChannel_Create(pRpcChannelBuffer, &This->iid, &pDelegateChannel);
        if (FAILED(hr))
            return hr;
        hr = IRpcProxyBuffer_Connect(This->dispatch_proxy, pDelegateChannel);
        IRpcChannelBuffer_Release(pDelegateChannel);
        return hr;
    }

    return S_OK;
}

static void WINAPI
TMProxyImpl_Disconnect(LPRPCPROXYBUFFER iface)
{
    ICOM_THIS_MULTI(TMProxyImpl, lpvtbl2, iface);

    TRACE("()\n");

    EnterCriticalSection(&This->crit);

    IRpcChannelBuffer_Release(This->chanbuf);
    This->chanbuf = NULL;

    LeaveCriticalSection(&This->crit);

    if (This->dispatch_proxy)
        IRpcProxyBuffer_Disconnect(This->dispatch_proxy);
}


static const IRpcProxyBufferVtbl tmproxyvtable = {
    TMProxyImpl_QueryInterface,
    TMProxyImpl_AddRef,
    TMProxyImpl_Release,
    TMProxyImpl_Connect,
    TMProxyImpl_Disconnect
};

/* how much space do we use on stack in DWORD steps. */
static int
_argsize(TYPEDESC *tdesc, ITypeInfo *tinfo) {
    switch (tdesc->vt) {
    case VT_I8:
    case VT_UI8:
	return 8/sizeof(DWORD);
    case VT_R8:
        return sizeof(double)/sizeof(DWORD);
    case VT_CY:
        return sizeof(CY)/sizeof(DWORD);
    case VT_DATE:
	return sizeof(DATE)/sizeof(DWORD);
    case VT_DECIMAL:
        return (sizeof(DECIMAL)+3)/sizeof(DWORD);
    case VT_VARIANT:
	return (sizeof(VARIANT)+3)/sizeof(DWORD);
    case VT_USERDEFINED:
    {
        ITypeInfo *tinfo2;
        TYPEATTR *tattr;
        HRESULT hres;
        DWORD ret;

        hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
        if (FAILED(hres))
            return 0; /* should fail critically in serialize_param */
        ITypeInfo_GetTypeAttr(tinfo2,&tattr);
        ret = (tattr->cbSizeInstance+3)/sizeof(DWORD);
        ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
        ITypeInfo_Release(tinfo2);
        return ret;
    }
    default:
	return 1;
    }
}

/* how much space do we use on the heap (in bytes) */
static int
_xsize(const TYPEDESC *td, ITypeInfo *tinfo) {
    switch (td->vt) {
    case VT_DATE:
	return sizeof(DATE);
    case VT_CY:
        return sizeof(CY);
    /* FIXME: VT_BOOL should return 2? */
    case VT_VARIANT:
	return sizeof(VARIANT)+3; /* FIXME: why the +3? */
    case VT_CARRAY: {
	int i, arrsize = 1;
	const ARRAYDESC *adesc = td->u.lpadesc;

	for (i=0;i<adesc->cDims;i++)
	    arrsize *= adesc->rgbounds[i].cElements;
	return arrsize*_xsize(&adesc->tdescElem, tinfo);
    }
    case VT_UI8:
    case VT_I8:
    case VT_R8:
	return 8;
    case VT_UI2:
    case VT_I2:
	return 2;
    case VT_UI1:
    case VT_I1:
	return 1;
    case VT_USERDEFINED:
    {
        ITypeInfo *tinfo2;
        TYPEATTR *tattr;
        HRESULT hres;
        DWORD ret;

        hres = ITypeInfo_GetRefTypeInfo(tinfo,td->u.hreftype,&tinfo2);
        if (FAILED(hres))
            return 0;
        ITypeInfo_GetTypeAttr(tinfo2,&tattr);
        ret = tattr->cbSizeInstance;
        ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
        ITypeInfo_Release(tinfo2);
        return ret;
    }
    default:
	return 4;
    }
}

static HRESULT
serialize_param(
    ITypeInfo		*tinfo,
    BOOL		writeit,
    BOOL		debugout,
    BOOL		dealloc,
    TYPEDESC		*tdesc,
    DWORD		*arg,
    marshal_state	*buf)
{
    HRESULT hres = S_OK;
    VARTYPE vartype;

    TRACE("(tdesc.vt %s)\n",debugstr_vt(tdesc->vt));

    vartype = tdesc->vt;
    if ((vartype & 0xf000) == VT_ARRAY)
        vartype = VT_SAFEARRAY;

    switch (vartype) {
    case VT_I8:
    case VT_UI8:
    case VT_R8:
    case VT_CY:
	hres = S_OK;
	if (debugout) TRACE_(olerelay)("%x%x\n",arg[0],arg[1]);
	if (writeit)
	    hres = xbuf_add(buf,(LPBYTE)arg,8);
	return hres;
    case VT_BOOL:
    case VT_ERROR:
    case VT_INT:
    case VT_UINT:
    case VT_I4:
    case VT_R4:
    case VT_UI4:
	hres = S_OK;
	if (debugout) TRACE_(olerelay)("%x\n",*arg);
	if (writeit)
	    hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
	return hres;
    case VT_I2:
    case VT_UI2:
	hres = S_OK;
	if (debugout) TRACE_(olerelay)("%04x\n",*arg & 0xffff);
	if (writeit)
	    hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
	return hres;
    case VT_I1:
    case VT_UI1:
	hres = S_OK;
	if (debugout) TRACE_(olerelay)("%02x\n",*arg & 0xff);
	if (writeit)
	    hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
	return hres;
    case VT_VARIANT: {
        if (debugout) TRACE_(olerelay)("Vt(%s%s)(",debugstr_vt(V_VT((VARIANT *)arg)),debugstr_vf(V_VT((VARIANT *)arg)));
        if (writeit)
        {
            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
            ULONG size = VARIANT_UserSize(&flags, buf->curoff, (VARIANT *)arg);
            xbuf_resize(buf, size);
            VARIANT_UserMarshal(&flags, buf->base + buf->curoff, (VARIANT *)arg);
            buf->curoff = size;
        }
        if (dealloc)
        {
            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
            VARIANT_UserFree(&flags, (VARIANT *)arg);
        }
        return S_OK;
    }
    case VT_BSTR: {
	if (debugout) {
	    if (*arg)
                   TRACE_(olerelay)("%s",relaystr((WCHAR*)*arg));
	    else
		    TRACE_(olerelay)("<bstr NULL>");
	}
        if (writeit)
        {
            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
            ULONG size = BSTR_UserSize(&flags, buf->curoff, (BSTR *)arg);
            xbuf_resize(buf, size);
            BSTR_UserMarshal(&flags, buf->base + buf->curoff, (BSTR *)arg);
            buf->curoff = size;
        }
        if (dealloc)
        {
            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
            BSTR_UserFree(&flags, (BSTR *)arg);
        }
        return S_OK;
    }
    case VT_PTR: {
	DWORD cookie;
	BOOL        derefhere = TRUE;

	if (tdesc->u.lptdesc->vt == VT_USERDEFINED) {
	    ITypeInfo	*tinfo2;
	    TYPEATTR	*tattr;

	    hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.lptdesc->u.hreftype,&tinfo2);
	    if (hres) {
		ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype);
		return hres;
	    }
	    ITypeInfo_GetTypeAttr(tinfo2,&tattr);
	    switch (tattr->typekind) {
            case TKIND_ALIAS:
                if (tattr->tdescAlias.vt == VT_USERDEFINED)
                {
                    DWORD href = tattr->tdescAlias.u.hreftype;
                    ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
                    ITypeInfo_Release(tinfo2);
                    hres = ITypeInfo_GetRefTypeInfo(tinfo,href,&tinfo2);
                    if (hres) {
                        ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype);
                        return hres;
                    }
                    ITypeInfo_GetTypeAttr(tinfo2,&tattr);
                    derefhere = (tattr->typekind != TKIND_DISPATCH && tattr->typekind != TKIND_INTERFACE);
                }
                break;
	    case TKIND_ENUM:	/* confirmed */
	    case TKIND_RECORD:	/* FIXME: mostly untested */
		break;
	    case TKIND_DISPATCH:	/* will be done in VT_USERDEFINED case */
	    case TKIND_INTERFACE:	/* will be done in VT_USERDEFINED case */
		derefhere=FALSE;
		break;
	    default:
		FIXME("unhandled switch cases tattr->typekind %d\n", tattr->typekind);
		derefhere=FALSE;
		break;
	    }
	    ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
	    ITypeInfo_Release(tinfo2);
	}

	if (debugout) TRACE_(olerelay)("*");
	/* Write always, so the other side knows when it gets a NULL pointer.
	 */
	cookie = *arg ? 0x42424242 : 0;
	hres = xbuf_add(buf,(LPBYTE)&cookie,sizeof(cookie));
	if (hres)
	    return hres;
	if (!*arg) {
	    if (debugout) TRACE_(olerelay)("NULL");
	    return S_OK;
	}
	hres = serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD*)*arg,buf);
	if (derefhere && dealloc) HeapFree(GetProcessHeap(),0,(LPVOID)*arg);
	return hres;
    }
    case VT_UNKNOWN:
	if (debugout) TRACE_(olerelay)("unk(0x%x)",*arg);
	if (writeit)
	    hres = _marshal_interface(buf,&IID_IUnknown,(LPUNKNOWN)*arg);
	if (dealloc && *(IUnknown **)arg)
	    IUnknown_Release((LPUNKNOWN)*arg);
	return hres;
    case VT_DISPATCH:
	if (debugout) TRACE_(olerelay)("idisp(0x%x)",*arg);
	if (writeit)
	    hres = _marshal_interface(buf,&IID_IDispatch,(LPUNKNOWN)*arg);
	if (dealloc && *(IUnknown **)arg)
	    IUnknown_Release((LPUNKNOWN)*arg);
	return hres;
    case VT_VOID:
	if (debugout) TRACE_(olerelay)("<void>");
	return S_OK;
    case VT_USERDEFINED: {
	ITypeInfo	*tinfo2;
	TYPEATTR	*tattr;

	hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
	if (hres) {
	    ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.hreftype);
	    return hres;
	}
	ITypeInfo_GetTypeAttr(tinfo2,&tattr);
	switch (tattr->typekind) {
	case TKIND_DISPATCH:
	case TKIND_INTERFACE:
	    if (writeit)
	       hres=_marshal_interface(buf,&(tattr->guid),(LPUNKNOWN)arg);
	    if (dealloc)
	        IUnknown_Release((LPUNKNOWN)arg);
	    break;
	case TKIND_RECORD: {
	    int i;
	    if (debugout) TRACE_(olerelay)("{");
	    for (i=0;i<tattr->cVars;i++) {
		VARDESC *vdesc;
		ELEMDESC *elem2;
		TYPEDESC *tdesc2;

		hres = ITypeInfo2_GetVarDesc(tinfo2, i, &vdesc);
		if (hres) {
		    ERR("Could not get vardesc of %d\n",i);
		    return hres;
		}
		elem2 = &vdesc->elemdescVar;
		tdesc2 = &elem2->tdesc;
		hres = serialize_param(
		    tinfo2,
		    writeit,
		    debugout,
		    dealloc,
		    tdesc2,
		    (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst),
		    buf
		);
                ITypeInfo_ReleaseVarDesc(tinfo2, vdesc);
		if (hres!=S_OK)
		    return hres;
		if (debugout && (i<(tattr->cVars-1)))
		    TRACE_(olerelay)(",");
	    }
	    if (debugout) TRACE_(olerelay)("}");
	    break;
	}
	case TKIND_ALIAS:
	    hres = serialize_param(tinfo2,writeit,debugout,dealloc,&tattr->tdescAlias,arg,buf);
	    break;
	case TKIND_ENUM:
	    hres = S_OK;
	    if (debugout) TRACE_(olerelay)("%x",*arg);
	    if (writeit)
	        hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
	    break;
	default:
	    FIXME("Unhandled typekind %d\n",tattr->typekind);
	    hres = E_FAIL;
	    break;
	}
	ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
	ITypeInfo_Release(tinfo2);
	return hres;
    }
    case VT_CARRAY: {
	ARRAYDESC *adesc = tdesc->u.lpadesc;
	int i, arrsize = 1;

	if (debugout) TRACE_(olerelay)("carr");
	for (i=0;i<adesc->cDims;i++) {
	    if (debugout) TRACE_(olerelay)("[%d]",adesc->rgbounds[i].cElements);
	    arrsize *= adesc->rgbounds[i].cElements;
	}
	if (debugout) TRACE_(olerelay)("(vt %s)",debugstr_vt(adesc->tdescElem.vt));
	if (debugout) TRACE_(olerelay)("[");
	for (i=0;i<arrsize;i++) {
	    hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)), buf);
	    if (hres)
		return hres;
	    if (debugout && (i<arrsize-1)) TRACE_(olerelay)(",");
	}
	if (debugout) TRACE_(olerelay)("]");
	if (dealloc)
	    HeapFree(GetProcessHeap(), 0, *(void **)arg);
	return S_OK;
    }
    case VT_SAFEARRAY: {
        if (writeit)
        {
            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
            ULONG size = LPSAFEARRAY_UserSize(&flags, buf->curoff, (LPSAFEARRAY *)arg);
            xbuf_resize(buf, size);
            LPSAFEARRAY_UserMarshal(&flags, buf->base + buf->curoff, (LPSAFEARRAY *)arg);
            buf->curoff = size;
        }
        if (dealloc)
        {
            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
            LPSAFEARRAY_UserFree(&flags, (LPSAFEARRAY *)arg);
        }
        return S_OK;
    }
    default:
	ERR("Unhandled marshal type %d.\n",tdesc->vt);
	return S_OK;
    }
}

static HRESULT
deserialize_param(
    ITypeInfo		*tinfo,
    BOOL		readit,
    BOOL		debugout,
    BOOL		alloc,
    TYPEDESC		*tdesc,
    DWORD		*arg,
    marshal_state	*buf)
{
    HRESULT hres = S_OK;
    VARTYPE vartype;

    TRACE("vt %s at %p\n",debugstr_vt(tdesc->vt),arg);

    vartype = tdesc->vt;
    if ((vartype & 0xf000) == VT_ARRAY)
        vartype = VT_SAFEARRAY;

    while (1) {
	switch (vartype) {
	case VT_VARIANT: {
	    if (readit)
	    {
		ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
		unsigned char *buffer;
		buffer = VARIANT_UserUnmarshal(&flags, buf->base + buf->curoff, (VARIANT *)arg);
		buf->curoff = buffer - buf->base;
	    }
	    return S_OK;
	}
        case VT_I8:
        case VT_UI8:
        case VT_R8:
        case VT_CY:
	    if (readit) {
		hres = xbuf_get(buf,(LPBYTE)arg,8);
		if (hres) ERR("Failed to read integer 8 byte\n");
	    }
	    if (debugout) TRACE_(olerelay)("%x%x",arg[0],arg[1]);
	    return hres;
        case VT_ERROR:
	case VT_BOOL:
        case VT_I4:
        case VT_INT:
        case VT_UINT:
        case VT_R4:
        case VT_UI4:
	    if (readit) {
		hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
		if (hres) ERR("Failed to read integer 4 byte\n");
	    }
	    if (debugout) TRACE_(olerelay)("%x",*arg);
	    return hres;
        case VT_I2:
        case VT_UI2:
	    if (readit) {
		DWORD x;
		hres = xbuf_get(buf,(LPBYTE)&x,sizeof(DWORD));
		if (hres) ERR("Failed to read integer 4 byte\n");
		memcpy(arg,&x,2);
	    }
	    if (debugout) TRACE_(olerelay)("%04x",*arg & 0xffff);
	    return hres;
        case VT_I1:
	case VT_UI1:
	    if (readit) {
		DWORD x;
		hres = xbuf_get(buf,(LPBYTE)&x,sizeof(DWORD));
		if (hres) ERR("Failed to read integer 4 byte\n");
		memcpy(arg,&x,1);
	    }
	    if (debugout) TRACE_(olerelay)("%02x",*arg & 0xff);
	    return hres;
	case VT_BSTR: {
	    if (readit)
	    {
		ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
		unsigned char *buffer;
		buffer = BSTR_UserUnmarshal(&flags, buf->base + buf->curoff, (BSTR *)arg);
		buf->curoff = buffer - buf->base;
		if (debugout) TRACE_(olerelay)("%s",debugstr_w(*(BSTR *)arg));
	    }
	    return S_OK;
	}
	case VT_PTR: {
	    DWORD	cookie;
	    BOOL        derefhere = TRUE;

	    if (tdesc->u.lptdesc->vt == VT_USERDEFINED) {
		ITypeInfo	*tinfo2;
		TYPEATTR	*tattr;

		hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.lptdesc->u.hreftype,&tinfo2);
		if (hres) {
		    ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype);
		    return hres;
		}
		ITypeInfo_GetTypeAttr(tinfo2,&tattr);
		switch (tattr->typekind) {
                case TKIND_ALIAS:
                    if (tattr->tdescAlias.vt == VT_USERDEFINED)
                    {
                        DWORD href = tattr->tdescAlias.u.hreftype;
                        ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
                        ITypeInfo_Release(tinfo2);
                        hres = ITypeInfo_GetRefTypeInfo(tinfo,href,&tinfo2);
                        if (hres) {
                            ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype);
                            return hres;
                        }
                        ITypeInfo_GetTypeAttr(tinfo2,&tattr);
                        derefhere = (tattr->typekind != TKIND_DISPATCH && tattr->typekind != TKIND_INTERFACE);
                    }
                    break;
		case TKIND_ENUM:	/* confirmed */
		case TKIND_RECORD:	/* FIXME: mostly untested */
		    break;
		case TKIND_DISPATCH:	/* will be done in VT_USERDEFINED case */
		case TKIND_INTERFACE:	/* will be done in VT_USERDEFINED case */
		    derefhere=FALSE;
		    break;
		default:
		    FIXME("unhandled switch cases tattr->typekind %d\n", tattr->typekind);
		    derefhere=FALSE;
		    break;
		}
		ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
		ITypeInfo_Release(tinfo2);
	    }
	    /* read it in all cases, we need to know if we have 
	     * NULL pointer or not.
	     */
	    hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie));
	    if (hres) {
		ERR("Failed to load pointer cookie.\n");
		return hres;
	    }
	    if (cookie != 0x42424242) {
		/* we read a NULL ptr from the remote side */
		if (debugout) TRACE_(olerelay)("NULL");
		*arg = 0;
		return S_OK;
	    }
	    if (debugout) TRACE_(olerelay)("*");
	    if (alloc) {
		/* Allocate space for the referenced struct */
		if (derefhere)
		    *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo));
	    }
	    if (derefhere)
		return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, (LPDWORD)*arg, buf);
	    else
		return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, arg, buf);
        }
	case VT_UNKNOWN:
	    /* FIXME: UNKNOWN is unknown ..., but allocate 4 byte for it */
	    if (alloc)
	        *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD));
	    hres = S_OK;
	    if (readit)
		hres = _unmarshal_interface(buf,&IID_IUnknown,(LPUNKNOWN*)arg);
	    if (debugout)
		TRACE_(olerelay)("unk(%p)",arg);
	    return hres;
	case VT_DISPATCH:
	    hres = S_OK;
	    if (readit)
		hres = _unmarshal_interface(buf,&IID_IDispatch,(LPUNKNOWN*)arg);
	    if (debugout)
		TRACE_(olerelay)("idisp(%p)",arg);
	    return hres;
	case VT_VOID:
	    if (debugout) TRACE_(olerelay)("<void>");
	    return S_OK;
	case VT_USERDEFINED: {
	    ITypeInfo	*tinfo2;
	    TYPEATTR	*tattr;

	    hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
	    if (hres) {
		ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.hreftype);
		return hres;
	    }
	    hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr);
	    if (hres) {
		ERR("Could not get typeattr in VT_USERDEFINED.\n");
	    } else {
		switch (tattr->typekind) {
		case TKIND_DISPATCH:
		case TKIND_INTERFACE:
		    if (readit)
			hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg);
		    break;
		case TKIND_RECORD: {
		    int i;

		    if (debugout) TRACE_(olerelay)("{");
		    for (i=0;i<tattr->cVars;i++) {
			VARDESC *vdesc;

			hres = ITypeInfo2_GetVarDesc(tinfo2, i, &vdesc);
			if (hres) {
			    ERR("Could not get vardesc of %d\n",i);
			    ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
			    ITypeInfo_Release(tinfo2);
			    return hres;
			}
			hres = deserialize_param(
			    tinfo2,
			    readit,
			    debugout,
			    alloc,
			    &vdesc->elemdescVar.tdesc,
			    (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst),
			    buf
			);
                        ITypeInfo2_ReleaseVarDesc(tinfo2, vdesc);
		        if (debugout && (i<tattr->cVars-1)) TRACE_(olerelay)(",");
		    }
		    if (debugout) TRACE_(olerelay)("}");
		    break;
		}
		case TKIND_ALIAS:
		    hres = deserialize_param(tinfo2,readit,debugout,alloc,&tattr->tdescAlias,arg,buf);
		    break;
		case TKIND_ENUM:
		    if (readit) {
		        hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
		        if (hres) ERR("Failed to read enum (4 byte)\n");
		    }
		    if (debugout) TRACE_(olerelay)("%x",*arg);
		    break;
		default:
		    ERR("Unhandled typekind %d\n",tattr->typekind);
		    hres = E_FAIL;
		    break;
		}
		ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
	    }
	    if (hres)
		ERR("failed to stuballoc in TKIND_RECORD.\n");
	    ITypeInfo_Release(tinfo2);
	    return hres;
	}
	case VT_CARRAY: {
	    /* arg is pointing to the start of the array. */
	    ARRAYDESC *adesc = tdesc->u.lpadesc;
	    int		arrsize,i;
	    arrsize = 1;
	    if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it work?\n");
	    for (i=0;i<adesc->cDims;i++)
		arrsize *= adesc->rgbounds[i].cElements;
	    *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize);
	    for (i=0;i<arrsize;i++)
		deserialize_param(
		    tinfo,
		    readit,
		    debugout,
		    alloc,
		    &adesc->tdescElem,
		    (DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)),
		    buf
		);
	    return S_OK;
	}
    case VT_SAFEARRAY: {
	    if (readit)
	    {
		ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
		unsigned char *buffer;
		buffer = LPSAFEARRAY_UserUnmarshal(&flags, buf->base + buf->curoff, (LPSAFEARRAY *)arg);
		buf->curoff = buffer - buf->base;
	    }
	    return S_OK;
	}
	default:
	    ERR("No handler for VT type %d!\n",tdesc->vt);
	    return S_OK;
	}
    }
}

/* Retrieves a function's funcdesc, searching back into inherited interfaces. */
static HRESULT get_funcdesc(ITypeInfo *tinfo, int iMethod, ITypeInfo **tactual, const FUNCDESC **fdesc,
                            BSTR *iname, BSTR *fname, UINT *num)
{
    HRESULT hr;
    UINT i, impl_types;
    UINT inherited_funcs = 0;
    TYPEATTR *attr;

    if (fname) *fname = NULL;
    if (iname) *iname = NULL;
    if (num) *num = 0;
    *tactual = NULL;

    hr = ITypeInfo_GetTypeAttr(tinfo, &attr);
    if (FAILED(hr))
    {
        ERR("GetTypeAttr failed with %x\n",hr);
        return hr;
    }

    if(attr->typekind == TKIND_DISPATCH)
    {
        if(attr->wTypeFlags & TYPEFLAG_FDUAL)
        {
            HREFTYPE href;
            ITypeInfo *tinfo2;

            hr = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href);
            if(FAILED(hr))
            {
                ERR("Cannot get interface href from dual dispinterface\n");
                ITypeInfo_ReleaseTypeAttr(tinfo, attr);
                return hr;
            }
            hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
            if(FAILED(hr))
            {
                ERR("Cannot get interface from dual dispinterface\n");
                ITypeInfo_ReleaseTypeAttr(tinfo, attr);
                return hr;
            }
            hr = get_funcdesc(tinfo2, iMethod, tactual, fdesc, iname, fname, num);
            ITypeInfo_Release(tinfo2);
            ITypeInfo_ReleaseTypeAttr(tinfo, attr);
            return hr;
        }
        ERR("Shouldn't be called with a non-dual dispinterface\n");
        return E_FAIL;
    }

    impl_types = attr->cImplTypes;
    ITypeInfo_ReleaseTypeAttr(tinfo, attr);

    for (i = 0; i < impl_types; i++)
    {
        HREFTYPE href;
        ITypeInfo *pSubTypeInfo;
        UINT sub_funcs;

        hr = ITypeInfo_GetRefTypeOfImplType(tinfo, i, &href);
        if (FAILED(hr)) return hr;
        hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &pSubTypeInfo);
        if (FAILED(hr)) return hr;

        hr = get_funcdesc(pSubTypeInfo, iMethod, tactual, fdesc, iname, fname, &sub_funcs);
        inherited_funcs += sub_funcs;
        ITypeInfo_Release(pSubTypeInfo);
        if(SUCCEEDED(hr)) return hr;
    }
    if(iMethod < inherited_funcs)
    {
        ERR("shouldn't be here\n");
        return E_INVALIDARG;
    }

    for(i = inherited_funcs; i <= iMethod; i++)
    {
        hr = ITypeInfoImpl_GetInternalFuncDesc(tinfo, i - inherited_funcs, fdesc);
        if(FAILED(hr))
        {
            if(num) *num = i;
            return hr;
        }
    }

    /* found it. We don't care about num so zero it */
    if(num) *num = 0;
    *tactual = tinfo;
    ITypeInfo_AddRef(*tactual);
    if (fname) ITypeInfo_GetDocumentation(tinfo,(*fdesc)->memid,fname,NULL,NULL,NULL);
    if (iname) ITypeInfo_GetDocumentation(tinfo,-1,iname,NULL,NULL,NULL);
    return S_OK;
}

static inline BOOL is_in_elem(const ELEMDESC *elem)
{
    return (elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN || !elem->u.paramdesc.wParamFlags);
}

static inline BOOL is_out_elem(const ELEMDESC *elem)
{
    return (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT || !elem->u.paramdesc.wParamFlags);
}

static DWORD
xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
{
    DWORD		*args = ((DWORD*)&tpinfo)+1, *xargs;
    const FUNCDESC	*fdesc;
    HRESULT		hres;
    int			i, relaydeb = TRACE_ON(olerelay);
    marshal_state	buf;
    RPCOLEMESSAGE	msg;
    ULONG		status;
    BSTR		fname,iname;
    BSTR		names[10];
    UINT		nrofnames;
    DWORD		remoteresult = 0;
    ITypeInfo 		*tinfo;
    IRpcChannelBuffer *chanbuf;

    EnterCriticalSection(&tpinfo->crit);

    hres = get_funcdesc(tpinfo->tinfo,method,&tinfo,&fdesc,&iname,&fname,NULL);
    if (hres) {
        ERR("Did not find typeinfo/funcdesc entry for method %d!\n",method);
        LeaveCriticalSection(&tpinfo->crit);
        return E_FAIL;
    }

    if (!tpinfo->chanbuf)
    {
        WARN("Tried to use disconnected proxy\n");
        ITypeInfo_Release(tinfo);
        LeaveCriticalSection(&tpinfo->crit);
        return RPC_E_DISCONNECTED;
    }
    chanbuf = tpinfo->chanbuf;
    IRpcChannelBuffer_AddRef(chanbuf);

    LeaveCriticalSection(&tpinfo->crit);

    if (relaydeb) {
       TRACE_(olerelay)("->");
	if (iname)
	    TRACE_(olerelay)("%s:",relaystr(iname));
	if (fname)
	    TRACE_(olerelay)("%s(%d)",relaystr(fname),method);
	else
	    TRACE_(olerelay)("%d",method);
	TRACE_(olerelay)("(");
    }

    SysFreeString(iname);
    SysFreeString(fname);

    memset(&buf,0,sizeof(buf));

    /* normal typelib driven serializing */

    /* Need them for hack below */
    memset(names,0,sizeof(names));
    if (ITypeInfo_GetNames(tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames))
	nrofnames = 0;
    if (nrofnames > sizeof(names)/sizeof(names[0]))
	ERR("Need more names!\n");

    xargs = args;
    for (i=0;i<fdesc->cParams;i++) {
	ELEMDESC	*elem = fdesc->lprgelemdescParam+i;
	if (relaydeb) {
	    if (i) TRACE_(olerelay)(",");
	    if (i+1<nrofnames && names[i+1])
		TRACE_(olerelay)("%s=",relaystr(names[i+1]));
	}
	/* No need to marshal other data than FIN and any VT_PTR. */
	if (!is_in_elem(elem) && (elem->tdesc.vt != VT_PTR)) {
	    xargs+=_argsize(&elem->tdesc, tinfo);
	    if (relaydeb) TRACE_(olerelay)("[out]");
	    continue;
	}
	hres = serialize_param(
	    tinfo,
	    is_in_elem(elem),
	    relaydeb,
	    FALSE,
	    &elem->tdesc,
	    xargs,
	    &buf
	);

	if (hres) {
	    ERR("Failed to serialize param, hres %x\n",hres);
	    break;
	}
	xargs+=_argsize(&elem->tdesc, tinfo);
    }
    if (relaydeb) TRACE_(olerelay)(")");

    memset(&msg,0,sizeof(msg));
    msg.cbBuffer = buf.curoff;
    msg.iMethod  = method;
    hres = IRpcChannelBuffer_GetBuffer(chanbuf,&msg,&(tpinfo->iid));
    if (hres) {
	ERR("RpcChannelBuffer GetBuffer failed, %x\n",hres);
	goto exit;
    }
    memcpy(msg.Buffer,buf.base,buf.curoff);
    if (relaydeb) TRACE_(olerelay)("\n");
    hres = IRpcChannelBuffer_SendReceive(chanbuf,&msg,&status);
    if (hres) {
	ERR("RpcChannelBuffer SendReceive failed, %x\n",hres);
	goto exit;
    }

    if (relaydeb) TRACE_(olerelay)(" status = %08x (",status);
    if (buf.base)
	buf.base = HeapReAlloc(GetProcessHeap(),0,buf.base,msg.cbBuffer);
    else
	buf.base = HeapAlloc(GetProcessHeap(),0,msg.cbBuffer);
    buf.size = msg.cbBuffer;
    memcpy(buf.base,msg.Buffer,buf.size);
    buf.curoff = 0;

    /* generic deserializer using typelib description */
    xargs = args;
    status = S_OK;
    for (i=0;i<fdesc->cParams;i++) {
	ELEMDESC	*elem = fdesc->lprgelemdescParam+i;

	if (relaydeb) {
	    if (i) TRACE_(olerelay)(",");
	    if (i+1<nrofnames && names[i+1]) TRACE_(olerelay)("%s=",relaystr(names[i+1]));
	}
	/* No need to marshal other data than FOUT and any VT_PTR */
	if (!is_out_elem(elem) && (elem->tdesc.vt != VT_PTR)) {
	    xargs += _argsize(&elem->tdesc, tinfo);
	    if (relaydeb) TRACE_(olerelay)("[in]");
	    continue;
	}
	hres = deserialize_param(
	    tinfo,
	    is_out_elem(elem),
	    relaydeb,
	    FALSE,
	    &(elem->tdesc),
	    xargs,
	    &buf
        );
	if (hres) {
	    ERR("Failed to unmarshall param, hres %x\n",hres);
	    status = hres;
	    break;
	}
	xargs += _argsize(&elem->tdesc, tinfo);
    }

    hres = xbuf_get(&buf, (LPBYTE)&remoteresult, sizeof(DWORD));
    if (hres != S_OK)
        goto exit;
    if (relaydeb) TRACE_(olerelay)(") = %08x\n", remoteresult);

    hres = remoteresult;

exit:
    IRpcChannelBuffer_FreeBuffer(chanbuf,&msg);
    for (i = 0; i < nrofnames; i++)
        SysFreeString(names[i]);
    HeapFree(GetProcessHeap(),0,buf.base);
    IRpcChannelBuffer_Release(chanbuf);
    ITypeInfo_Release(tinfo);
    TRACE("-- 0x%08x\n", hres);
    return hres;
}

static HRESULT WINAPI ProxyIUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
    TMProxyImpl *proxy = (TMProxyImpl *)iface;

    TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);

    if (proxy->outerunknown)
        return IUnknown_QueryInterface(proxy->outerunknown, riid, ppv);

    FIXME("No interface\n");
    return E_NOINTERFACE;
}

static ULONG WINAPI ProxyIUnknown_AddRef(IUnknown *iface)
{
    TMProxyImpl *proxy = (TMProxyImpl *)iface;

    TRACE("\n");

    if (proxy->outerunknown)
        return IUnknown_AddRef(proxy->outerunknown);

    return 2; /* FIXME */
}

static ULONG WINAPI ProxyIUnknown_Release(IUnknown *iface)
{
    TMProxyImpl *proxy = (TMProxyImpl *)iface;

    TRACE("\n");

    if (proxy->outerunknown)
        return IUnknown_Release(proxy->outerunknown);

    return 1; /* FIXME */
}

static HRESULT WINAPI ProxyIDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pctinfo)
{
    TMProxyImpl *This = (TMProxyImpl *)iface;

    TRACE("(%p)\n", pctinfo);

    return IDispatch_GetTypeInfoCount(This->dispatch, pctinfo);
}

static HRESULT WINAPI ProxyIDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
{
    TMProxyImpl *This = (TMProxyImpl *)iface;

    TRACE("(%d, %x, %p)\n", iTInfo, lcid, ppTInfo);

    return IDispatch_GetTypeInfo(This->dispatch, iTInfo, lcid, ppTInfo);
}

static HRESULT WINAPI ProxyIDispatch_GetIDsOfNames(LPDISPATCH iface, REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId)
{
    TMProxyImpl *This = (TMProxyImpl *)iface;

    TRACE("(%s, %p, %d, 0x%x, %p)\n", debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);

    return IDispatch_GetIDsOfNames(This->dispatch, riid, rgszNames,
                                   cNames, lcid, rgDispId);
}

static HRESULT WINAPI ProxyIDispatch_Invoke(LPDISPATCH iface, DISPID dispIdMember, REFIID riid, LCID lcid,
                                            WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult,
                                            EXCEPINFO * pExcepInfo, UINT * puArgErr)
{
    TMProxyImpl *This = (TMProxyImpl *)iface;

    TRACE("(%d, %s, 0x%x, 0x%x, %p, %p, %p, %p)\n", dispIdMember,
          debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
          pExcepInfo, puArgErr);

    return IDispatch_Invoke(This->dispatch, dispIdMember, riid, lcid,
                            wFlags, pDispParams, pVarResult, pExcepInfo,
                            puArgErr);
}

typedef struct
{
    const IRpcChannelBufferVtbl *lpVtbl;
    LONG                  refs;
    /* the IDispatch-derived interface we are handling */
	IID                   tmarshal_iid;
    IRpcChannelBuffer    *pDelegateChannel;
} TMarshalDispatchChannel;

static HRESULT WINAPI TMarshalDispatchChannel_QueryInterface(LPRPCCHANNELBUFFER iface, REFIID riid, LPVOID *ppv)
{
    *ppv = NULL;
    if (IsEqualIID(riid,&IID_IRpcChannelBuffer) || IsEqualIID(riid,&IID_IUnknown))
    {
        *ppv = iface;
        IUnknown_AddRef(iface);
        return S_OK;
    }
    return E_NOINTERFACE;
}

static ULONG WINAPI TMarshalDispatchChannel_AddRef(LPRPCCHANNELBUFFER iface)
{
    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
    return InterlockedIncrement(&This->refs);
}

static ULONG WINAPI TMarshalDispatchChannel_Release(LPRPCCHANNELBUFFER iface)
{
    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
    ULONG ref;

    ref = InterlockedDecrement(&This->refs);
    if (ref)
        return ref;

	IRpcChannelBuffer_Release(This->pDelegateChannel);
    HeapFree(GetProcessHeap(), 0, This);
    return 0;
}

static HRESULT WINAPI TMarshalDispatchChannel_GetBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg, REFIID riid)
{
    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
    TRACE("(%p, %s)\n", olemsg, debugstr_guid(riid));
    /* Note: we are pretending to invoke a method on the interface identified
     * by tmarshal_iid so that we can re-use the IDispatch proxy/stub code
     * without the RPC runtime getting confused by not exporting an IDispatch interface */
    return IRpcChannelBuffer_GetBuffer(This->pDelegateChannel, olemsg, &This->tmarshal_iid);
}

static HRESULT WINAPI TMarshalDispatchChannel_SendReceive(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, ULONG *pstatus)
{
    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
    TRACE("(%p, %p)\n", olemsg, pstatus);
    return IRpcChannelBuffer_SendReceive(This->pDelegateChannel, olemsg, pstatus);
}

static HRESULT WINAPI TMarshalDispatchChannel_FreeBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg)
{
    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
    TRACE("(%p)\n", olemsg);
    return IRpcChannelBuffer_FreeBuffer(This->pDelegateChannel, olemsg);
}

static HRESULT WINAPI TMarshalDispatchChannel_GetDestCtx(LPRPCCHANNELBUFFER iface, DWORD* pdwDestContext, void** ppvDestContext)
{
    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
    TRACE("(%p,%p)\n", pdwDestContext, ppvDestContext);
    return IRpcChannelBuffer_GetDestCtx(This->pDelegateChannel, pdwDestContext, ppvDestContext);
}

static HRESULT WINAPI TMarshalDispatchChannel_IsConnected(LPRPCCHANNELBUFFER iface)
{
    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
    TRACE("()\n");
    return IRpcChannelBuffer_IsConnected(This->pDelegateChannel);
}

static const IRpcChannelBufferVtbl TMarshalDispatchChannelVtbl =
{
    TMarshalDispatchChannel_QueryInterface,
    TMarshalDispatchChannel_AddRef,
    TMarshalDispatchChannel_Release,
    TMarshalDispatchChannel_GetBuffer,
    TMarshalDispatchChannel_SendReceive,
    TMarshalDispatchChannel_FreeBuffer,
    TMarshalDispatchChannel_GetDestCtx,
    TMarshalDispatchChannel_IsConnected
};

static HRESULT TMarshalDispatchChannel_Create(
    IRpcChannelBuffer *pDelegateChannel, REFIID tmarshal_riid,
    IRpcChannelBuffer **ppChannel)
{
    TMarshalDispatchChannel *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
    if (!This)
        return E_OUTOFMEMORY;

    This->lpVtbl = &TMarshalDispatchChannelVtbl;
    This->refs = 1;
    IRpcChannelBuffer_AddRef(pDelegateChannel);
    This->pDelegateChannel = pDelegateChannel;
    This->tmarshal_iid = *tmarshal_riid;

    *ppChannel = (IRpcChannelBuffer *)&This->lpVtbl;
    return S_OK;
}


static inline HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
{
    HRESULT       hr;
    CLSID         clsid;

    if ((hr = CoGetPSClsid(riid, &clsid)))
        return hr;
    return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL,
                             &IID_IPSFactoryBuffer, (LPVOID*)facbuf);
}

static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num)
{
    int j;
    /* nrofargs without This */
    int nrofargs;
    ITypeInfo *tinfo2;
    TMAsmProxy	*xasm = proxy->asmstubs + num;
    HRESULT hres;
    const FUNCDESC *fdesc;

    hres = get_funcdesc(proxy->tinfo, num, &tinfo2, &fdesc, NULL, NULL, NULL);
    if (hres) {
        ERR("GetFuncDesc %x should not fail here.\n",hres);
        return hres;
    }
    ITypeInfo_Release(tinfo2);
    /* some args take more than 4 byte on the stack */
    nrofargs = 0;
    for (j=0;j<fdesc->cParams;j++)
        nrofargs += _argsize(&fdesc->lprgelemdescParam[j].tdesc, proxy->tinfo);

#ifdef __i386__
    if (fdesc->callconv != CC_STDCALL) {
        ERR("calling convention is not stdcall????\n");
        return E_FAIL;
    }
/* popl %eax	-	return ptr
 * pushl <nr>
 * pushl %eax
 * call xCall
 * lret <nr> (+4)
 *
 *
 * arg3 arg2 arg1 <method> <returnptr>
 */
    xasm->popleax       = 0x58;
    xasm->pushlval      = 0x68;
    xasm->nr            = num;
    xasm->pushleax      = 0x50;
    xasm->lcall         = 0xe8; /* relative jump */
    xasm->xcall         = (DWORD)xCall;
    xasm->xcall        -= (DWORD)&(xasm->lret);
    xasm->lret          = 0xc2;
    xasm->bytestopop    = (nrofargs+2)*4; /* pop args, This, iMethod */
    xasm->nop           = 0x90;
    proxy->lpvtbl[num]  = xasm;
#else
    FIXME("not implemented on non i386\n");
    return E_FAIL;
#endif
    return S_OK;
}

static HRESULT WINAPI
PSFacBuf_CreateProxy(
    LPPSFACTORYBUFFER iface, IUnknown* pUnkOuter, REFIID riid,
    IRpcProxyBuffer **ppProxy, LPVOID *ppv)
{
    HRESULT	hres;
    ITypeInfo	*tinfo;
    unsigned int i, nroffuncs;
    TMProxyImpl	*proxy;
    TYPEATTR	*typeattr;
    BOOL        defer_to_dispatch = FALSE;

    TRACE("(...%s...)\n",debugstr_guid(riid));
    hres = _get_typeinfo_for_iid(riid,&tinfo);
    if (hres) {
	ERR("No typeinfo for %s?\n",debugstr_guid(riid));
	return hres;
    }

    hres = num_of_funcs(tinfo, &nroffuncs);
    if (FAILED(hres)) {
        ERR("Cannot get number of functions for typeinfo %s\n",debugstr_guid(riid));
        ITypeInfo_Release(tinfo);
        return hres;
    }

    proxy = CoTaskMemAlloc(sizeof(TMProxyImpl));
    if (!proxy) return E_OUTOFMEMORY;

    assert(sizeof(TMAsmProxy) == 16);

    proxy->dispatch = NULL;
    proxy->dispatch_proxy = NULL;
    proxy->outerunknown = pUnkOuter;
    proxy->asmstubs = VirtualAlloc(NULL, sizeof(TMAsmProxy) * nroffuncs, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (!proxy->asmstubs) {
        ERR("Could not commit pages for proxy thunks\n");
        CoTaskMemFree(proxy);
        return E_OUTOFMEMORY;
    }
    proxy->lpvtbl2	= &tmproxyvtable;
    /* one reference for the proxy */
    proxy->ref		= 1;
    proxy->tinfo	= tinfo;
    proxy->iid		= *riid;
    proxy->chanbuf      = 0;

    InitializeCriticalSection(&proxy->crit);
    proxy->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TMProxyImpl.crit");

    proxy->lpvtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPBYTE)*nroffuncs);

    /* if we derive from IDispatch then defer to its proxy for its methods */
    hres = ITypeInfo_GetTypeAttr(tinfo, &typeattr);
    if (hres == S_OK)
    {
        if (typeattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE)
        {
            IPSFactoryBuffer *factory_buffer;
            hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer);
            if (hres == S_OK)
            {
                hres = IPSFactoryBuffer_CreateProxy(factory_buffer, NULL,
                    &IID_IDispatch, &proxy->dispatch_proxy,
                    (void **)&proxy->dispatch);
                IPSFactoryBuffer_Release(factory_buffer);
            }
            if ((hres == S_OK) && (nroffuncs < 7))
            {
                ERR("nroffuncs calculated incorrectly (%d)\n", nroffuncs);
                hres = E_UNEXPECTED;
            }
            if (hres == S_OK)
            {
                defer_to_dispatch = TRUE;
            }
        }
        ITypeInfo_ReleaseTypeAttr(tinfo, typeattr);
    }

    for (i=0;i<nroffuncs;i++) {
	switch (i) {
	case 0:
		proxy->lpvtbl[i] = ProxyIUnknown_QueryInterface;
		break;
	case 1:
		proxy->lpvtbl[i] = ProxyIUnknown_AddRef;
		break;
	case 2:
		proxy->lpvtbl[i] = ProxyIUnknown_Release;
		break;
        case 3:
                if(!defer_to_dispatch)
                {
                    hres = init_proxy_entry_point(proxy, i);
                    if(FAILED(hres)) return hres;
                }
                else proxy->lpvtbl[3] = ProxyIDispatch_GetTypeInfoCount;
                break;
        case 4:
                if(!defer_to_dispatch)
                {
                    hres = init_proxy_entry_point(proxy, i);
                    if(FAILED(hres)) return hres;
                }
                else proxy->lpvtbl[4] = ProxyIDispatch_GetTypeInfo;
                break;
        case 5:
                if(!defer_to_dispatch)
                {
                    hres = init_proxy_entry_point(proxy, i);
                    if(FAILED(hres)) return hres;
                }
                else proxy->lpvtbl[5] = ProxyIDispatch_GetIDsOfNames;
                break;
        case 6:
                if(!defer_to_dispatch)
                {
                    hres = init_proxy_entry_point(proxy, i);
                    if(FAILED(hres)) return hres;
                }
                else proxy->lpvtbl[6] = ProxyIDispatch_Invoke;
                break;
	default:
                hres = init_proxy_entry_point(proxy, i);
                if(FAILED(hres)) return hres;
	}
    }

    if (hres == S_OK)
    {
        *ppv = proxy;
        *ppProxy = (IRpcProxyBuffer *)&(proxy->lpvtbl2);
        IUnknown_AddRef((IUnknown *)*ppv);
        return S_OK;
    }
    else
        TMProxyImpl_Release((IRpcProxyBuffer *)&proxy->lpvtbl2);
    return hres;
}

typedef struct _TMStubImpl {
    const IRpcStubBufferVtbl   *lpvtbl;
    LONG			ref;

    LPUNKNOWN			pUnk;
    ITypeInfo			*tinfo;
    IID				iid;
    IRpcStubBuffer		*dispatch_stub;
    BOOL			dispatch_derivative;
} TMStubImpl;

static HRESULT WINAPI
TMStubImpl_QueryInterface(LPRPCSTUBBUFFER iface, REFIID riid, LPVOID *ppv)
{
    if (IsEqualIID(riid,&IID_IRpcStubBuffer)||IsEqualIID(riid,&IID_IUnknown)){
        *ppv = iface;
	IRpcStubBuffer_AddRef(iface);
	return S_OK;
    }
    FIXME("%s, not supported IID.\n",debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI
TMStubImpl_AddRef(LPRPCSTUBBUFFER iface)
{
    TMStubImpl *This = (TMStubImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);
        
    TRACE("(%p)->(ref before=%u)\n", This, refCount - 1);

    return refCount;
}

static ULONG WINAPI
TMStubImpl_Release(LPRPCSTUBBUFFER iface)
{
    TMStubImpl *This = (TMStubImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(ref before=%u)\n", This, refCount + 1);

    if (!refCount)
    {
        IRpcStubBuffer_Disconnect(iface);
        ITypeInfo_Release(This->tinfo);
        if (This->dispatch_stub)
            IRpcStubBuffer_Release(This->dispatch_stub);
        CoTaskMemFree(This);
    }
    return refCount;
}

static HRESULT WINAPI
TMStubImpl_Connect(LPRPCSTUBBUFFER iface, LPUNKNOWN pUnkServer)
{
    TMStubImpl *This = (TMStubImpl *)iface;

    TRACE("(%p)->(%p)\n", This, pUnkServer);

    IUnknown_AddRef(pUnkServer);
    This->pUnk = pUnkServer;

    if (This->dispatch_stub)
        IRpcStubBuffer_Connect(This->dispatch_stub, pUnkServer);

    return S_OK;
}

static void WINAPI
TMStubImpl_Disconnect(LPRPCSTUBBUFFER iface)
{
    TMStubImpl *This = (TMStubImpl *)iface;

    TRACE("(%p)->()\n", This);

    if (This->pUnk)
    {
        IUnknown_Release(This->pUnk);
        This->pUnk = NULL;
    }

    if (This->dispatch_stub)
        IRpcStubBuffer_Disconnect(This->dispatch_stub);
}

static HRESULT WINAPI
TMStubImpl_Invoke(
    LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf)
{
#ifdef __i386__
    int		i;
    const FUNCDESC *fdesc;
    TMStubImpl *This = (TMStubImpl *)iface;
    HRESULT	hres;
    DWORD	*args = NULL, res, *xargs, nrofargs;
    marshal_state	buf;
    UINT	nrofnames = 0;
    BSTR	names[10];
    BSTR	iname = NULL;
    ITypeInfo 	*tinfo = NULL;

    TRACE("...\n");

    if (xmsg->iMethod < 3) {
        ERR("IUnknown methods cannot be marshaled by the typelib marshaler\n");
        return E_UNEXPECTED;
    }

    if (This->dispatch_derivative && xmsg->iMethod < sizeof(IDispatchVtbl)/sizeof(void *))
    {
        IPSFactoryBuffer *factory_buffer;
        hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer);
        if (hres == S_OK)
        {
            hres = IPSFactoryBuffer_CreateStub(factory_buffer, &IID_IDispatch,
                This->pUnk, &This->dispatch_stub);
            IPSFactoryBuffer_Release(factory_buffer);
        }
        if (hres != S_OK)
            return hres;
        return IRpcStubBuffer_Invoke(This->dispatch_stub, xmsg, rpcchanbuf);
    }

    memset(&buf,0,sizeof(buf));
    buf.size	= xmsg->cbBuffer;
    buf.base	= HeapAlloc(GetProcessHeap(), 0, xmsg->cbBuffer);
    memcpy(buf.base, xmsg->Buffer, xmsg->cbBuffer);
    buf.curoff	= 0;

    hres = get_funcdesc(This->tinfo,xmsg->iMethod,&tinfo,&fdesc,&iname,NULL,NULL);
    if (hres) {
	ERR("GetFuncDesc on method %d failed with %x\n",xmsg->iMethod,hres);
	return hres;
    }

    if (iname && !lstrcmpW(iname, IDispatchW))
    {
        ERR("IDispatch cannot be marshaled by the typelib marshaler\n");
        hres = E_UNEXPECTED;
        SysFreeString (iname);
        goto exit;
    }

    SysFreeString (iname);

    /* Need them for hack below */
    memset(names,0,sizeof(names));
    ITypeInfo_GetNames(tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames);
    if (nrofnames > sizeof(names)/sizeof(names[0])) {
	ERR("Need more names!\n");
    }

    /*dump_FUNCDESC(fdesc);*/
    nrofargs = 0;
    for (i=0;i<fdesc->cParams;i++)
	nrofargs += _argsize(&fdesc->lprgelemdescParam[i].tdesc, tinfo);
    args = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(nrofargs+1)*sizeof(DWORD));
    if (!args)
    {
        hres = E_OUTOFMEMORY;
        goto exit;
    }

    /* Allocate all stuff used by call. */
    xargs = args+1;
    for (i=0;i<fdesc->cParams;i++) {
	ELEMDESC	*elem = fdesc->lprgelemdescParam+i;

	hres = deserialize_param(
	   tinfo,
	   is_in_elem(elem),
	   FALSE,
	   TRUE,
	   &(elem->tdesc),
	   xargs,
	   &buf
	);
	xargs += _argsize(&elem->tdesc, tinfo);
	if (hres) {
	    ERR("Failed to deserialize param %s, hres %x\n",relaystr(names[i+1]),hres);
	    break;
	}
    }

    args[0] = (DWORD)This->pUnk;

    __TRY
    {
        res = _invoke(
            (*((FARPROC**)args[0]))[fdesc->oVft/4],
            fdesc->callconv,
            (xargs-args),
            args
        );
    }
    __EXCEPT_ALL
    {
        DWORD dwExceptionCode = GetExceptionCode();
        ERR("invoke call failed with exception 0x%08x (%d)\n", dwExceptionCode, dwExceptionCode);
        if (FAILED(dwExceptionCode))
            hres = dwExceptionCode;
        else
            hres = HRESULT_FROM_WIN32(dwExceptionCode);
    }
    __ENDTRY

    if (hres != S_OK)
        goto exit;

    buf.curoff = 0;

    xargs = args+1;
    for (i=0;i<fdesc->cParams;i++) {
	ELEMDESC	*elem = fdesc->lprgelemdescParam+i;
	hres = serialize_param(
	   tinfo,
	   is_out_elem(elem),
	   FALSE,
	   TRUE,
	   &elem->tdesc,
	   xargs,
	   &buf
	);
	xargs += _argsize(&elem->tdesc, tinfo);
	if (hres) {
	    ERR("Failed to stuballoc param, hres %x\n",hres);
	    break;
	}
    }

    hres = xbuf_add (&buf, (LPBYTE)&res, sizeof(DWORD));

    if (hres != S_OK)
        goto exit;

    xmsg->cbBuffer	= buf.curoff;
    hres = IRpcChannelBuffer_GetBuffer(rpcchanbuf, xmsg, &This->iid);
    if (hres != S_OK)
        ERR("IRpcChannelBuffer_GetBuffer failed with error 0x%08x\n", hres);

    if (hres == S_OK)
        memcpy(xmsg->Buffer, buf.base, buf.curoff);

exit:
    for (i = 0; i < nrofnames; i++)
        SysFreeString(names[i]);

    ITypeInfo_Release(tinfo);
    HeapFree(GetProcessHeap(), 0, args);

    HeapFree(GetProcessHeap(), 0, buf.base);

    TRACE("returning\n");
    return hres;
#else
    FIXME( "not implemented on non-i386\n" );
    return E_FAIL;
#endif
}

static LPRPCSTUBBUFFER WINAPI
TMStubImpl_IsIIDSupported(LPRPCSTUBBUFFER iface, REFIID riid) {
    FIXME("Huh (%s)?\n",debugstr_guid(riid));
    return NULL;
}

static ULONG WINAPI
TMStubImpl_CountRefs(LPRPCSTUBBUFFER iface) {
    TMStubImpl *This = (TMStubImpl *)iface;

    FIXME("()\n");
    return This->ref; /*FIXME? */
}

static HRESULT WINAPI
TMStubImpl_DebugServerQueryInterface(LPRPCSTUBBUFFER iface, LPVOID *ppv) {
    return E_NOTIMPL;
}

static void WINAPI
TMStubImpl_DebugServerRelease(LPRPCSTUBBUFFER iface, LPVOID ppv) {
    return;
}

static const IRpcStubBufferVtbl tmstubvtbl = {
    TMStubImpl_QueryInterface,
    TMStubImpl_AddRef,
    TMStubImpl_Release,
    TMStubImpl_Connect,
    TMStubImpl_Disconnect,
    TMStubImpl_Invoke,
    TMStubImpl_IsIIDSupported,
    TMStubImpl_CountRefs,
    TMStubImpl_DebugServerQueryInterface,
    TMStubImpl_DebugServerRelease
};

static HRESULT WINAPI
PSFacBuf_CreateStub(
    LPPSFACTORYBUFFER iface, REFIID riid,IUnknown *pUnkServer,
    IRpcStubBuffer** ppStub
) {
    HRESULT hres;
    ITypeInfo	*tinfo;
    TMStubImpl	*stub;
    TYPEATTR *typeattr;

    TRACE("(%s,%p,%p)\n",debugstr_guid(riid),pUnkServer,ppStub);

    hres = _get_typeinfo_for_iid(riid,&tinfo);
    if (hres) {
	ERR("No typeinfo for %s?\n",debugstr_guid(riid));
	return hres;
    }

    stub = CoTaskMemAlloc(sizeof(TMStubImpl));
    if (!stub)
	return E_OUTOFMEMORY;
    stub->lpvtbl	= &tmstubvtbl;
    stub->ref		= 1;
    stub->tinfo		= tinfo;
    stub->dispatch_stub = NULL;
    stub->dispatch_derivative = FALSE;
    stub->iid		= *riid;
    hres = IRpcStubBuffer_Connect((LPRPCSTUBBUFFER)stub,pUnkServer);
    *ppStub 		= (LPRPCSTUBBUFFER)stub;
    TRACE("IRpcStubBuffer: %p\n", stub);
    if (hres)
	ERR("Connect to pUnkServer failed?\n");

    /* if we derive from IDispatch then defer to its stub for some of its methods */
    hres = ITypeInfo_GetTypeAttr(tinfo, &typeattr);
    if (hres == S_OK)
    {
        if (typeattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE)
            stub->dispatch_derivative = TRUE;
        ITypeInfo_ReleaseTypeAttr(tinfo, typeattr);
    }

    return hres;
}

static const IPSFactoryBufferVtbl psfacbufvtbl = {
    PSFacBuf_QueryInterface,
    PSFacBuf_AddRef,
    PSFacBuf_Release,
    PSFacBuf_CreateProxy,
    PSFacBuf_CreateStub
};

/* This is the whole PSFactoryBuffer object, just the vtableptr */
static const IPSFactoryBufferVtbl *lppsfac = &psfacbufvtbl;

/***********************************************************************
 *           TMARSHAL_DllGetClassObject
 */
HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
{
    if (IsEqualIID(iid,&IID_IPSFactoryBuffer)) {
	*ppv = &lppsfac;
	return S_OK;
    }
    return E_NOINTERFACE;
}
