/*
 *	TYPELIB Marshaler
 *
 *	Copyright 2002	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

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

#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 "wine/unicode.h"
#include "ole2disp.h"
#include "typelib.h"
#include "wine/debug.h"
#include "winternl.h"

static const WCHAR riidW[5] = {'r','i','i','d',0};
static const WCHAR pdispparamsW[] = {'p','d','i','s','p','p','a','r','a','m','s',0};
static const WCHAR ppvObjectW[] = {'p','p','v','O','b','j','e','c','t',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))

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

    BOOL	thisisiid;
    IID		iid;	/* HACK: for VT_VOID */
} 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_add(marshal_state *buf, LPBYTE stuff, DWORD size) {
    while (buf->size - buf->curoff < size) {
	if (buf->base) {
	    buf->size += 100;
	    buf->base = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,buf->base,buf->size);
	    if (!buf->base)
		return E_OUTOFMEMORY;
	} else {
	    buf->base = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,32);
	    buf->size = 32;
	    if (!buf->base)
		return E_OUTOFMEMORY;
	}
    }
    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) return hres;
    if (xsize == 0) return S_OK;
    hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
    if (hres) {
	FIXME("Stream create failed %lx\n",hres);
	return hres;
    }
    hres = IStream_Write(pStm,buf->base+buf->curoff,xsize,&res);
    if (hres) { FIXME("stream write %lx\n",hres); return hres; }
    memset(&seekto,0,sizeof(seekto));
    hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
    if (hres) { FIXME("Failed Seek %lx\n",hres); return hres;}
    hres = CoUnmarshalInterface(pStm,riid,(LPVOID*)pUnk);
    if (hres) {
	FIXME("Marshalling interface %s failed with %lx\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) {
    LPUNKNOWN		newiface;
    LPBYTE		tempbuf;
    IStream		*pStm;
    STATSTG		ststg;
    ULARGE_INTEGER	newpos;
    LARGE_INTEGER	seekto;
    ULONG		res;
    DWORD		xsize;
    HRESULT		hres;

    hres = S_OK;
    if (!pUnk)
	goto fail;

    TRACE("...%s...\n",debugstr_guid(riid));
    hres=IUnknown_QueryInterface(pUnk,riid,(LPVOID*)&newiface);
    if (hres) {
	TRACE("%p does not support iface %s\n",pUnk,debugstr_guid(riid));
	goto fail;
    }
    hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
    if (hres) {
	FIXME("Stream create failed %lx\n",hres);
	goto fail;
    }
    hres = CoMarshalInterface(pStm,riid,newiface,0,NULL,0);
    IUnknown_Release(newiface);
    if (hres) {
	FIXME("Marshalling interface %s failed with %lx\n",
		debugstr_guid(riid),hres
	);
	goto fail;
    }
    hres = IStream_Stat(pStm,&ststg,0);
    tempbuf = HeapAlloc(GetProcessHeap(), 0, ststg.cbSize.u.LowPart);
    memset(&seekto,0,sizeof(seekto));
    hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
    if (hres) { FIXME("Failed Seek %lx\n",hres); goto fail;}
    hres = IStream_Read(pStm,tempbuf,ststg.cbSize.u.LowPart,&res);
    if (hres) { FIXME("Failed Read %lx\n",hres); goto fail;}
    IStream_Release(pStm);
    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);
    return hres;
fail:
    xsize = 0;
    xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
    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 = (LPVOID)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, tlfnlen;
    ITypeLib	*tl;

    sprintf( interfacekey, "Interface\\{%08lx-%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)) {
	FIXME("No %s key found.\n",interfacekey);
       	return E_FAIL;
    }
    type = (1<<REG_SZ);
    tlguidlen = sizeof(tlguid);
    if (RegQueryValueExA(ikey,NULL,NULL,&type,tlguid,&tlguidlen)) {
	FIXME("Getting typelib guid failed.\n");
	RegCloseKey(ikey);
	return E_FAIL;
    }
    type = (1<<REG_SZ);
    verlen = sizeof(ver);
    if (RegQueryValueExA(ikey,"Version",NULL,&type,ver,&verlen)) {
	FIXME("Could not get version value?\n");
	RegCloseKey(ikey);
	return E_FAIL;
    }
    RegCloseKey(ikey);
    sprintf(typelibkey,"Typelib\\%s\\%s\\0\\win32",tlguid,ver);
    tlfnlen = sizeof(tlfn);
    if (RegQueryValueA(HKEY_CLASSES_ROOT,typelibkey,tlfn,&tlfnlen)) {
	FIXME("Could not get typelib fn?\n");
	return E_FAIL;
    }
    MultiByteToWideChar(CP_ACP, 0, tlfn, -1, tlfnW, -1);
    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;
    }
    /* FIXME: do this?  ITypeLib_Release(tl); */
    return hres;
}

/* Determine nr of functions. Since we use the toplevel interface and all
 * inherited ones have lower numbers, we are ok to not to descent into
 * the inheritance tree I think.
 */
static int _nroffuncs(ITypeInfo *tinfo) {
    int 	n, max = 0;
    FUNCDESC	*fdesc;
    HRESULT	hres;

    n=0;
    while (1) {
	hres = ITypeInfo_GetFuncDesc(tinfo,n,&fdesc);
	if (hres)
	    return max+1;
	if (fdesc->oVft/4 > max)
	    max = fdesc->oVft/4;
	n++;
    }
    /*NOTREACHED*/
}

#ifdef __i386__

#include "pshpack1.h"

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

#include "poppack.h"

#else /* __i386__ */
# error You need to implement stubless proxies for your architecture
#endif

typedef struct _TMProxyImpl {
    LPVOID				*lpvtbl;
    IRpcProxyBufferVtbl	*lpvtbl2;
    ULONG				ref;

    TMAsmProxy				*asmstubs;
    ITypeInfo*				tinfo;
    IRpcChannelBuffer*			chanbuf;
    IID					iid;
    CRITICAL_SECTION	crit;
} TMProxyImpl;

static HRESULT WINAPI
TMProxyImpl_QueryInterface(LPRPCPROXYBUFFER iface, REFIID riid, LPVOID *ppv)
{
    TRACE("()\n");
    if (IsEqualIID(riid,&IID_IUnknown)||IsEqualIID(riid,&IID_IRpcProxyBuffer)) {
        *ppv = (LPVOID)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);

    TRACE("()\n");

    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI
TMProxyImpl_Release(LPRPCPROXYBUFFER iface)
{
    ULONG refs;
    ICOM_THIS_MULTI(TMProxyImpl,lpvtbl2,iface);

    TRACE("()\n");

    refs = InterlockedDecrement(&This->ref);
    if (!refs)
    {
        DeleteCriticalSection(&This->crit);
        if (This->chanbuf) IRpcChannelBuffer_Release(This->chanbuf);
        VirtualFree(This->asmstubs, 0, MEM_RELEASE);
        CoTaskMemFree(This);
    }
    return refs;
}

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

    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);
}


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

/* how much space do we use on stack in DWORD steps. */
int const
_argsize(DWORD vt) {
    switch (vt) {
    case VT_DATE:
	return sizeof(DATE)/sizeof(DWORD);
    case VT_VARIANT:
	return (sizeof(VARIANT)+3)/sizeof(DWORD);
    default:
	return 1;
    }
}

static int
_xsize(TYPEDESC *td) {
    switch (td->vt) {
    case VT_DATE:
	return sizeof(DATE);
    case VT_VARIANT:
	return sizeof(VARIANT)+3;
    case VT_CARRAY: {
	int i, arrsize = 1;
	ARRAYDESC *adesc = td->u.lpadesc;

	for (i=0;i<adesc->cDims;i++)
	    arrsize *= adesc->rgbounds[i].cElements;
	return arrsize*_xsize(&adesc->tdescElem);
    }
    case VT_UI2:
    case VT_I2:
	return 2;
    case VT_UI1:
    case VT_I1:
	return 1;
    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;

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

    switch (tdesc->vt) {
    case VT_EMPTY: /* nothing. empty variant for instance */
	return S_OK;
    case VT_BOOL:
    case VT_ERROR:
    case VT_UI4:
    case VT_UINT:
    case VT_I4:
    case VT_R4:
    case VT_UI2:
    case VT_UI1:
	hres = S_OK;
	if (debugout) TRACE_(olerelay)("%lx",*arg);
	if (writeit)
	    hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
	return hres;
    case VT_VARIANT: {
	TYPEDESC	tdesc2;
	VARIANT		*vt = (VARIANT*)arg;
	DWORD		vttype = V_VT(vt);

	if (debugout) TRACE_(olerelay)("Vt(%ld)(",vttype);
	tdesc2.vt = vttype;
	if (writeit) {
	    hres = xbuf_add(buf,(LPBYTE)&vttype,sizeof(vttype));
	    if (hres) return hres;
	}
	/* need to recurse since we need to free the stuff */
	hres = serialize_param(tinfo,writeit,debugout,dealloc,&tdesc2,&(V_I4(vt)),buf);
	if (debugout) TRACE_(olerelay)(")");
	return hres;
    }
    case VT_BSTR: {
	if (debugout) {
	    if (arg)
		    TRACE_(olerelay)("%s",relaystr((BSTR)*arg));
	    else
		    TRACE_(olerelay)("<bstr NULL>");
	}
	if (writeit) {
	    if (!*arg) {
		DWORD fakelen = -1;
		hres = xbuf_add(buf,(LPBYTE)&fakelen,4);
		if (hres)
		    return hres;
	    } else {
		DWORD *bstr = ((DWORD*)(*arg))-1;

		hres = xbuf_add(buf,(LPBYTE)bstr,bstr[0]+4);
		if (hres)
		    return hres;
	    }
	}

	if (dealloc && arg)
	    SysFreeString((BSTR)*arg);
	return S_OK;
    }
    case VT_PTR: {
	DWORD cookie;

	if (debugout) TRACE_(olerelay)("*");
	if (writeit) {
	    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 (dealloc) HeapFree(GetProcessHeap(),0,(LPVOID)arg);
	return hres;
    }
    case VT_UNKNOWN:
	if (debugout) TRACE_(olerelay)("unk(0x%lx)",*arg);
	if (writeit)
	    hres = _marshal_interface(buf,&IID_IUnknown,(LPUNKNOWN)*arg);
	return hres;
    case VT_DISPATCH:
	if (debugout) TRACE_(olerelay)("idisp(0x%lx)",*arg);
	if (writeit)
	    hres = _marshal_interface(buf,&IID_IDispatch,(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) {
	    FIXME("Could not get typeinfo of hreftype %lx 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);
	    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) {
		    FIXME("Could not get vardesc of %d\n",i);
		    return hres;
		}
		/* Need them for hack below */
		/*
		memset(names,0,sizeof(names));
		hres = ITypeInfo_GetNames(tinfo2,vdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames);
		if (nrofnames > sizeof(names)/sizeof(names[0])) {
		    ERR("Need more names!\n");
		}
		if (!hres && debugout)
		    TRACE_(olerelay)("%s=",relaystr(names[0]));
		*/
		elem2 = &vdesc->elemdescVar;
		tdesc2 = &elem2->tdesc;
		hres = serialize_param(
		    tinfo2,
		    writeit,
		    debugout,
		    dealloc,
		    tdesc2,
		    (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst),
		    buf
		);
		if (hres!=S_OK)
		    return hres;
		if (debugout && (i<(tattr->cVars-1)))
		    TRACE_(olerelay)(",");
	    }
	    if (buf->thisisiid && (tattr->cbSizeInstance==sizeof(GUID)))
		memcpy(&(buf->iid),arg,sizeof(buf->iid));
	    if (debugout) TRACE_(olerelay)("}");
	    break;
	}
	default:
	    FIXME("Unhandled typekind %d\n",tattr->typekind);
	    hres = E_FAIL;
	    break;
	}
	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)("[%ld]",adesc->rgbounds[i].cElements);
	    arrsize *= adesc->rgbounds[i].cElements;
	}
	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)), buf);
	    if (hres)
		return hres;
	    if (debugout && (i<arrsize-1)) TRACE_(olerelay)(",");
	}
	if (debugout) TRACE_(olerelay)("]");
	return S_OK;
    }
    default:
	ERR("Unhandled marshal type %d.\n",tdesc->vt);
	return S_OK;
    }
}

static HRESULT
serialize_LPVOID_ptr(
    ITypeInfo		*tinfo,
    BOOL		writeit,
    BOOL		debugout,
    BOOL		dealloc,
    TYPEDESC		*tdesc,
    DWORD		*arg,
    marshal_state	*buf)
{
    HRESULT	hres;
    DWORD	cookie;

    if ((tdesc->vt != VT_PTR)			||
	(tdesc->u.lptdesc->vt != VT_PTR)	||
	(tdesc->u.lptdesc->u.lptdesc->vt != VT_VOID)
    ) {
	FIXME("ppvObject not expressed as VT_PTR -> VT_PTR -> VT_VOID?\n");
	return E_FAIL;
    }
    cookie = (*arg) ? 0x42424242: 0x0;
    if (writeit) {
	hres = xbuf_add(buf, (LPVOID)&cookie, sizeof(cookie));
	if (hres)
	    return hres;
    }
    if (!*arg) {
	if (debugout) TRACE_(olerelay)("<lpvoid NULL>");
	return S_OK;
    }
    if (debugout)
	TRACE_(olerelay)("ppv(%p)",*(LPUNKNOWN*)*arg);
    if (writeit) {
	hres = _marshal_interface(buf,&(buf->iid),*(LPUNKNOWN*)*arg);
	if (hres)
	    return hres;
    }
    if (dealloc)
	HeapFree(GetProcessHeap(),0,(LPVOID)*arg);
    return S_OK;
}

static HRESULT
serialize_DISPPARAM_ptr(
    ITypeInfo		*tinfo,
    BOOL		writeit,
    BOOL		debugout,
    BOOL		dealloc,
    TYPEDESC		*tdesc,
    DWORD		*arg,
    marshal_state	*buf)
{
    DWORD	cookie;
    HRESULT	hres;
    DISPPARAMS	*disp;
    int		i;

    if ((tdesc->vt != VT_PTR) || (tdesc->u.lptdesc->vt != VT_USERDEFINED)) {
	FIXME("DISPPARAMS not expressed as VT_PTR -> VT_USERDEFINED?\n");
	return E_FAIL;
    }

    cookie = *arg ? 0x42424242 : 0x0;
    if (writeit) {
	hres = xbuf_add(buf,(LPBYTE)&cookie,sizeof(cookie));
	if (hres)
	    return hres;
    }
    if (!*arg) {
	if (debugout) TRACE_(olerelay)("<DISPPARAMS NULL>");
	return S_OK;
    }
    disp = (DISPPARAMS*)*arg;
    if (writeit) {
	hres = xbuf_add(buf,(LPBYTE)&disp->cArgs,sizeof(disp->cArgs));
	if (hres)
	    return hres;
    }
    if (debugout) TRACE_(olerelay)("D{");
    for (i=0;i<disp->cArgs;i++) {
	TYPEDESC	vtdesc;

	vtdesc.vt = VT_VARIANT;
	serialize_param(
	    tinfo,
	    writeit,
	    debugout,
	    dealloc,
	    &vtdesc,
	    (DWORD*)(disp->rgvarg+i),
	    buf
        );
	if (debugout && (i<disp->cArgs-1))
	    TRACE_(olerelay)(",");
    }
    if (dealloc)
	HeapFree(GetProcessHeap(),0,disp->rgvarg);
    if (writeit) {
	hres = xbuf_add(buf,(LPBYTE)&disp->cNamedArgs,sizeof(disp->cNamedArgs));
	if (hres)
	    return hres;
    }
    if (debugout) TRACE_(olerelay)("}{");
    for (i=0;i<disp->cNamedArgs;i++) {
	TYPEDESC	vtdesc;

	vtdesc.vt = VT_UINT;
	serialize_param(
	    tinfo,
	    writeit,
	    debugout,
	    dealloc,
	    &vtdesc,
	    (DWORD*)(disp->rgdispidNamedArgs+i),
	    buf
	);
	if (debugout && (i<disp->cNamedArgs-1))
	    TRACE_(olerelay)(",");
    }
    if (debugout) TRACE_(olerelay)("}");
    if (dealloc) {
	HeapFree(GetProcessHeap(),0,disp->rgdispidNamedArgs);
	HeapFree(GetProcessHeap(),0,disp);
    }
    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;

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

    while (1) {
	switch (tdesc->vt) {
	case VT_EMPTY:
	    if (debugout) TRACE_(olerelay)("<empty>");
	    return S_OK;
	case VT_NULL:
	    if (debugout) TRACE_(olerelay)("<null>");
	    return S_OK;
	case VT_VARIANT: {
	    VARIANT	*vt = (VARIANT*)arg;

	    if (readit) {
		DWORD	vttype;
		TYPEDESC	tdesc2;
		hres = xbuf_get(buf,(LPBYTE)&vttype,sizeof(vttype));
		if (hres) {
		    FIXME("vt type not read?\n");
		    return hres;
		}
		memset(&tdesc2,0,sizeof(tdesc2));
		tdesc2.vt = vttype;
		V_VT(vt)  = vttype;
	        if (debugout) TRACE_(olerelay)("Vt(%ld)(",vttype);
		hres = deserialize_param(tinfo, readit, debugout, alloc, &tdesc2, &(V_I4(vt)), buf);
		TRACE_(olerelay)(")");
		return hres;
	    } else {
		VariantInit(vt);
		return S_OK;
	    }
	}
        case VT_ERROR:
	case VT_BOOL: case VT_I4: case VT_UI4: case VT_UINT: case VT_R4:
        case VT_UI2:
	case VT_UI1:
	    if (readit) {
		hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
		if (hres) FIXME("Failed to read integer 4 byte\n");
	    }
	    if (debugout) TRACE_(olerelay)("%lx",*arg);
	    return hres;
	case VT_BSTR: {
	    WCHAR	*str;
	    DWORD	len;

	    if (readit) {
		hres = xbuf_get(buf,(LPBYTE)&len,sizeof(DWORD));
		if (hres) {
		    FIXME("failed to read bstr klen\n");
		    return hres;
		}
		if (len == -1) {
		    *arg = 0;
		    if (debugout) TRACE_(olerelay)("<bstr NULL>");
		} else {
		    str  = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+sizeof(WCHAR));
		    hres = xbuf_get(buf,(LPBYTE)str,len);
		    if (hres) {
			FIXME("Failed to read BSTR.\n");
			return hres;
		    }
		    *arg = (DWORD)SysAllocStringLen(str,len);
		    if (debugout) TRACE_(olerelay)("%s",relaystr(str));
		    HeapFree(GetProcessHeap(),0,str);
		}
	    } else {
	        *arg = 0;
	    }
	    return S_OK;
	}
	case VT_PTR: {
	    DWORD	cookie;
	    BOOL	derefhere = 0;

	    derefhere = (tdesc->u.lptdesc->vt != VT_USERDEFINED);

	    if (readit) {
		hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie));
		if (hres) {
		    FIXME("Failed to load pointer cookie.\n");
		    return hres;
		}
		if (cookie != 0x42424242) {
		    if (debugout) TRACE_(olerelay)("NULL");
		    *arg = 0;
		    return S_OK;
		}
		if (debugout) TRACE_(olerelay)("*");
	    }
	    if (alloc) {
		if (derefhere)
		    *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc));
	    }
	    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) {
		FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED.\n",tdesc->u.hreftype);
		return hres;
	    }
	    hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr);
	    if (hres) {
		FIXME("Could not get typeattr in VT_USERDEFINED.\n");
	    } else {
		if (alloc)
		    *arg = (DWORD)HeapAlloc(GetProcessHeap(),0,tattr->cbSizeInstance);
		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) {
			    FIXME("Could not get vardesc of %d\n",i);
			    return hres;
			}
			hres = deserialize_param(
			    tinfo2,
			    readit,
			    debugout,
			    alloc,
			    &vdesc->elemdescVar.tdesc,
			    (DWORD*)(((LPBYTE)*arg)+vdesc->u.oInst),
			    buf
			);
		        if (debugout && (i<tattr->cVars-1)) TRACE_(olerelay)(",");
		    }
		    if (buf->thisisiid && (tattr->cbSizeInstance==sizeof(GUID)))
			memcpy(&(buf->iid),(LPBYTE)*arg,sizeof(buf->iid));
		    if (debugout) TRACE_(olerelay)("}");
		    break;
		}
		default:
		    ERR("Unhandled typekind %d\n",tattr->typekind);
		    hres = E_FAIL;
		    break;
		}
	    }
	    if (hres)
		FIXME("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;
	    for (i=0;i<arrsize;i++)
		deserialize_param(
		    tinfo,
		    readit,
		    debugout,
		    alloc,
		    &adesc->tdescElem,
		    (DWORD*)((LPBYTE)(arg)+i*_xsize(&adesc->tdescElem)),
		    buf
		);
	    return S_OK;
	}
	default:
	    ERR("No handler for VT type %d!\n",tdesc->vt);
	    return S_OK;
	}
    }
}

static HRESULT
deserialize_LPVOID_ptr(
    ITypeInfo		*tinfo,
    BOOL		readit,
    BOOL		debugout,
    BOOL		alloc,
    TYPEDESC		*tdesc,
    DWORD		*arg,
    marshal_state	*buf
) {
    HRESULT	hres;
    DWORD	cookie;

    if ((tdesc->vt != VT_PTR)			||
	(tdesc->u.lptdesc->vt != VT_PTR)	||
	(tdesc->u.lptdesc->u.lptdesc->vt != VT_VOID)
    ) {
	FIXME("ppvObject not expressed as VT_PTR -> VT_PTR -> VT_VOID?\n");
	return E_FAIL;
    }
    if (alloc)
	*arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LPVOID));
    if (readit) {
	hres = xbuf_get(buf, (LPVOID)&cookie, sizeof(cookie));
	if (hres)
	    return hres;
	if (cookie != 0x42424242) {
	    *(DWORD*)*arg = 0;
	    if (debugout) TRACE_(olerelay)("<lpvoid NULL>");
	    return S_OK;
	}
    }
    if (readit) {
	hres = _unmarshal_interface(buf,&buf->iid,(LPUNKNOWN*)*arg);
	if (hres)
	    return hres;
    }
    if (debugout) TRACE_(olerelay)("ppv(%p)",(LPVOID)*arg);
    return S_OK;
}

static HRESULT
deserialize_DISPPARAM_ptr(
    ITypeInfo		*tinfo,
    BOOL		readit,
    BOOL		debugout,
    BOOL		alloc,
    TYPEDESC		*tdesc,
    DWORD		*arg,
    marshal_state	*buf)
{
    DWORD	cookie;
    DISPPARAMS	*disps;
    HRESULT	hres;
    int		i;

    if ((tdesc->vt != VT_PTR) || (tdesc->u.lptdesc->vt != VT_USERDEFINED)) {
	FIXME("DISPPARAMS not expressed as VT_PTR -> VT_USERDEFINED?\n");
	return E_FAIL;
    }
    if (readit) {
	hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie));
	if (hres)
	    return hres;
	if (cookie == 0) {
	    *arg = 0;
	    if (debugout) TRACE_(olerelay)("<DISPPARAMS NULL>");
	    return S_OK;
	}
    }
    if (alloc)
	*arg = (DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DISPPARAMS));
    disps = (DISPPARAMS*)*arg;
    if (!readit)
	return S_OK;
    hres = xbuf_get(buf, (LPBYTE)&disps->cArgs, sizeof(disps->cArgs));
    if (hres)
	return hres;
    if (alloc)
        disps->rgvarg = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(VARIANT)*disps->cArgs);
    if (debugout) TRACE_(olerelay)("D{");
    for (i=0; i< disps->cArgs; i++) {
        TYPEDESC vdesc;

	vdesc.vt = VT_VARIANT;
	hres = deserialize_param(
	    tinfo,
	    readit,
	    debugout,
	    alloc,
	    &vdesc,
	    (DWORD*)(disps->rgvarg+i),
	    buf
	);
    }
    if (debugout) TRACE_(olerelay)("}{");
    hres = xbuf_get(buf, (LPBYTE)&disps->cNamedArgs, sizeof(disps->cNamedArgs));
    if (hres)
	return hres;
    if (disps->cNamedArgs) {
	if (alloc)
	    disps->rgdispidNamedArgs = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DISPID)*disps->cNamedArgs);
	for (i=0; i< disps->cNamedArgs; i++) {
	    TYPEDESC vdesc;

	    vdesc.vt = VT_UINT;
	    hres = deserialize_param(
		tinfo,
		readit,
		debugout,
		alloc,
		&vdesc,
		(DWORD*)(disps->rgdispidNamedArgs+i),
		buf
	    );
	    if (debugout && i<(disps->cNamedArgs-1)) TRACE_(olerelay)(",");
	}
    }
    if (debugout) TRACE_(olerelay)("}");
    return S_OK;
}

/* Searches function, also in inherited interfaces */
static HRESULT
_get_funcdesc(
    ITypeInfo *tinfo, int iMethod, FUNCDESC **fdesc, BSTR *iname, BSTR *fname)
{
    int i = 0, j = 0;
    HRESULT hres;

    if (fname) *fname = NULL;
    if (iname) *iname = NULL;

    while (1) {
	hres = ITypeInfo_GetFuncDesc(tinfo, i, fdesc);
	if (hres) {
	    ITypeInfo	*tinfo2;
	    HREFTYPE	href;
	    TYPEATTR	*attr;

	    hres = ITypeInfo_GetTypeAttr(tinfo, &attr);
	    if (hres) {
		FIXME("GetTypeAttr failed with %lx\n",hres);
		return hres;
	    }
	    /* Not found, so look in inherited ifaces. */
	    for (j=0;j<attr->cImplTypes;j++) {
		hres = ITypeInfo_GetRefTypeOfImplType(tinfo, j, &href);
		if (hres) {
		    FIXME("Did not find a reftype for interface offset %d?\n",j);
		    break;
		}
		hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
		if (hres) {
		    FIXME("Did not find a typeinfo for reftype %ld?\n",href);
		    continue;
		}
		hres = _get_funcdesc(tinfo2,iMethod,fdesc,iname,fname);
		ITypeInfo_Release(tinfo2);
		if (!hres) return S_OK;
	    }
	    return E_FAIL;
	}
	if (((*fdesc)->oVft/4) == iMethod) {
	    if (fname)
		ITypeInfo_GetDocumentation(tinfo,(*fdesc)->memid,fname,NULL,NULL,NULL);
	    if (iname)
		ITypeInfo_GetDocumentation(tinfo,-1,iname,NULL,NULL,NULL);
	    return S_OK;
	}
	i++;
    }
    return E_FAIL;
}

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

    EnterCriticalSection(&tpinfo->crit);

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

    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)("(");
	if (iname) SysFreeString(iname);
	if (fname) SysFreeString(fname);
    }
    /* Need them for hack below */
    memset(names,0,sizeof(names));
    if (ITypeInfo_GetNames(tpinfo->tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames))
	nrofnames = 0;
    if (nrofnames > sizeof(names)/sizeof(names[0]))
	ERR("Need more names!\n");

    memset(&buf,0,sizeof(buf));
    buf.iid = IID_IUnknown;
    if (method == 0) {
	xbuf_add(&buf,(LPBYTE)args[0],sizeof(IID));
	if (relaydeb) TRACE_(olerelay)("riid=%s,[out]",debugstr_guid((REFIID)args[0]));
    } else {
	xargs = args;
	for (i=0;i<fdesc->cParams;i++) {
	    ELEMDESC	*elem = fdesc->lprgelemdescParam+i;
	    BOOL	isserialized = FALSE;
	    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 */
	    if (!(elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN)) {
		xargs+=_argsize(elem->tdesc.vt);
		if (relaydeb) TRACE_(olerelay)("[out]");
		continue;
	    }
	    if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) {
		/* If the parameter is 'riid', we use it as interface IID
		 * for a later ppvObject serialization.
		 */
		buf.thisisiid = !lstrcmpW(names[i+1],riidW);

		/* DISPPARAMS* needs special serializer */
		if (!lstrcmpW(names[i+1],pdispparamsW)) {
		    hres = serialize_DISPPARAM_ptr(
			tpinfo->tinfo,
			elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
			relaydeb,
			FALSE,
			&elem->tdesc,
			xargs,
			&buf
		    );
		    isserialized = TRUE;
		}
		if (!lstrcmpW(names[i+1],ppvObjectW)) {
		    hres = serialize_LPVOID_ptr(
			tpinfo->tinfo,
			elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
			relaydeb,
			FALSE,
			&elem->tdesc,
			xargs,
			&buf
		    );
		    if (hres == S_OK)
		        isserialized = TRUE;
		}
	    }
	    if (!isserialized)
		hres = serialize_param(
		    tpinfo->tinfo,
		    elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
		    relaydeb,
		    FALSE,
		    &elem->tdesc,
		    xargs,
		    &buf
		);

	    if (hres) {
		FIXME("Failed to serialize param, hres %lx\n",hres);
		break;
	    }
	    xargs+=_argsize(elem->tdesc.vt);
	}
    }
    if (relaydeb) TRACE_(olerelay)(")");
    memset(&msg,0,sizeof(msg));
    msg.cbBuffer = buf.curoff;
    msg.iMethod  = method;
    hres = IRpcChannelBuffer_GetBuffer(tpinfo->chanbuf,&msg,&(tpinfo->iid));
    if (hres) {
	FIXME("RpcChannelBuffer GetBuffer failed, %lx\n",hres);
        LeaveCriticalSection(&tpinfo->crit);
	return hres;
    }
    memcpy(msg.Buffer,buf.base,buf.curoff);
    if (relaydeb) TRACE_(olerelay)("\n");
    hres = IRpcChannelBuffer_SendReceive(tpinfo->chanbuf,&msg,&status);
    if (hres) {
	FIXME("RpcChannelBuffer SendReceive failed, %lx\n",hres);
        LeaveCriticalSection(&tpinfo->crit);
	return hres;
    }

    if (relaydeb) TRACE_(olerelay)(" = %08lx (",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;
    if (method == 0) {
	_unmarshal_interface(&buf,(REFIID)args[0],(LPUNKNOWN*)args[1]);
	if (relaydeb) TRACE_(olerelay)("[in],%p",*((DWORD**)args[1]));
    } else {
	xargs = args;
	for (i=0;i<fdesc->cParams;i++) {
	    ELEMDESC	*elem = fdesc->lprgelemdescParam+i;
	    BOOL	isdeserialized = FALSE;

	    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 I think */
	    if (!(elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT)) {
		xargs += _argsize(elem->tdesc.vt);
		if (relaydeb) TRACE_(olerelay)("[in]");
		continue;
	    }
	    if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) {
		/* If the parameter is 'riid', we use it as interface IID
		 * for a later ppvObject serialization.
		 */
		buf.thisisiid = !lstrcmpW(names[i+1],riidW);

		/* deserialize DISPPARAM */
		if (!lstrcmpW(names[i+1],pdispparamsW)) {
		    hres = deserialize_DISPPARAM_ptr(
			tpinfo->tinfo,
			elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
			relaydeb,
			FALSE,
			&(elem->tdesc),
			xargs,
			&buf
		    );
		    if (hres) {
			FIXME("Failed to deserialize DISPPARAM*, hres %lx\n",hres);
			break;
		    }
		    isdeserialized = TRUE;
		}
		if (!lstrcmpW(names[i+1],ppvObjectW)) {
		    hres = deserialize_LPVOID_ptr(
			tpinfo->tinfo,
			elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
			relaydeb,
			FALSE,
			&elem->tdesc,
			xargs,
			&buf
		    );
		    if (hres == S_OK)
			isdeserialized = TRUE;
		}
	    }
	    if (!isdeserialized)
		hres = deserialize_param(
		    tpinfo->tinfo,
		    elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
		    relaydeb,
		    FALSE,
		    &(elem->tdesc),
		    xargs,
		    &buf
		);
	    if (hres) {
		FIXME("Failed to unmarshall param, hres %lx\n",hres);
		break;
	    }
	    xargs += _argsize(elem->tdesc.vt);
	}
    }
    if (relaydeb) TRACE_(olerelay)(")\n");
    HeapFree(GetProcessHeap(),0,buf.base);

    LeaveCriticalSection(&tpinfo->crit);

    return status;
}

static HRESULT WINAPI
PSFacBuf_CreateProxy(
    LPPSFACTORYBUFFER iface, IUnknown* pUnkOuter, REFIID riid,
    IRpcProxyBuffer **ppProxy, LPVOID *ppv)
{
    HRESULT	hres;
    ITypeInfo	*tinfo;
    int		i, nroffuncs;
    FUNCDESC	*fdesc;
    TMProxyImpl	*proxy;

    TRACE("(...%s...)\n",debugstr_guid(riid));
    hres = _get_typeinfo_for_iid(riid,&tinfo);
    if (hres) {
	FIXME("No typeinfo for %s?\n",debugstr_guid(riid));
	return hres;
    }
    nroffuncs = _nroffuncs(tinfo);
    proxy = CoTaskMemAlloc(sizeof(TMProxyImpl));
    if (!proxy) return E_OUTOFMEMORY;

    assert(sizeof(TMAsmProxy) == 12);

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

    InitializeCriticalSection(&proxy->crit);

    proxy->lpvtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPBYTE)*nroffuncs);
    for (i=0;i<nroffuncs;i++) {
	int		nrofargs;
	TMAsmProxy	*xasm = proxy->asmstubs+i;

	/* nrofargs without This */
	switch (i) {
	case 0: nrofargs = 2;
		break;
	case 1: case 2: nrofargs = 0;
		break;
	default: {
		int j;
		hres = _get_funcdesc(tinfo,i,&fdesc,NULL,NULL);
		if (hres) {
		    FIXME("GetFuncDesc %lx should not fail here.\n",hres);
		    return hres;
		}
		/* 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.vt);

		if (fdesc->callconv != CC_STDCALL) {
		    ERR("calling convention is not stdcall????\n");
		    return E_FAIL;
		}
		break;
	    }
	}
/* popl %eax	-	return ptr
 * pushl <nr>
 * pushl %eax
 * call xCall
 * lret <nr> (+4)
 *
 *
 * arg3 arg2 arg1 <method> <returnptr>
 */
	xasm->popleax	= 0x58;
	xasm->pushlval	= 0x6a;
	xasm->nr	= i;
	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 */
	proxy->lpvtbl[i] = xasm;
    }
    proxy->lpvtbl2	= &tmproxyvtable;
    /* 1 reference for the proxy and 1 for the object */
    proxy->ref		= 2;
    proxy->tinfo	= tinfo;
    memcpy(&proxy->iid,riid,sizeof(*riid));
    *ppv		= (LPVOID)proxy;
    *ppProxy		= (IRpcProxyBuffer *)&(proxy->lpvtbl2);
    return S_OK;
}

typedef struct _TMStubImpl {
    IRpcStubBufferVtbl	*lpvtbl;
    ULONG			ref;

    LPUNKNOWN			pUnk;
    ITypeInfo			*tinfo;
    IID				iid;
} TMStubImpl;

static HRESULT WINAPI
TMStubImpl_QueryInterface(LPRPCSTUBBUFFER iface, REFIID riid, LPVOID *ppv)
{
    if (IsEqualIID(riid,&IID_IRpcStubBuffer)||IsEqualIID(riid,&IID_IUnknown)){
	*ppv = (LPVOID)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;
        
    TRACE("(%p) before %lu\n", This, This->ref);

    return InterlockedIncrement(&This->ref);
}

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

    TRACE("(%p) after %lu\n", This, This->ref-1);

    refs = InterlockedDecrement(&This->ref);
    if (!refs)
    {
        IRpcStubBuffer_Disconnect(iface);
        CoTaskMemFree(This);
    }
    return refs;
}

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;
    return S_OK;
}

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

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

    IUnknown_Release(This->pUnk);
    This->pUnk = NULL;
    return;
}

static HRESULT WINAPI
TMStubImpl_Invoke(
    LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf)
{
    int		i;
    FUNCDESC	*fdesc;
    TMStubImpl *This = (TMStubImpl *)iface;
    HRESULT	hres;
    DWORD	*args, res, *xargs, nrofargs;
    marshal_state	buf;
    int		nrofnames;
    BSTR	names[10];

    memset(&buf,0,sizeof(buf));
    buf.size	= xmsg->cbBuffer;
    buf.base	= xmsg->Buffer;
    buf.curoff	= 0;
    buf.iid	= IID_IUnknown;

    TRACE("...\n");
    if (xmsg->iMethod == 0) { /* QI */
	IID		xiid;
	/* in: IID, out: <iface> */

	xbuf_get(&buf,(LPBYTE)&xiid,sizeof(xiid));
	buf.curoff = 0;
	hres = _marshal_interface(&buf,&xiid,This->pUnk);
	xmsg->Buffer	= buf.base; /* Might have been reallocated */
	xmsg->cbBuffer	= buf.size;
	return hres;
    }
    hres = _get_funcdesc(This->tinfo,xmsg->iMethod,&fdesc,NULL,NULL);
    if (hres) {
	FIXME("GetFuncDesc on method %ld failed with %lx\n",xmsg->iMethod,hres);
	return hres;
    }
    /* Need them for hack below */
    memset(names,0,sizeof(names));
    ITypeInfo_GetNames(This->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.vt);
    args = HeapAlloc(GetProcessHeap(),0,(nrofargs+1)*sizeof(DWORD));
    if (!args) return E_OUTOFMEMORY;

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

	if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) {
	    /* If the parameter is 'riid', we use it as interface IID
	     * for a later ppvObject serialization.
	     */
	    buf.thisisiid = !lstrcmpW(names[i+1],riidW);

	    /* deserialize DISPPARAM */
	    if (!lstrcmpW(names[i+1],pdispparamsW)) {
		hres = deserialize_DISPPARAM_ptr(
		    This->tinfo,
		    elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
		    FALSE,
		    TRUE,
		    &(elem->tdesc),
		    xargs,
		    &buf
		);
		if (hres) {
		    FIXME("Failed to deserialize DISPPARAM*, hres %lx\n",hres);
		    break;
		}
		isdeserialized = TRUE;
	    }
	    if (!lstrcmpW(names[i+1],ppvObjectW)) {
		hres = deserialize_LPVOID_ptr(
		    This->tinfo,
		    elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
		    FALSE,
		    TRUE,
		    &elem->tdesc,
		    xargs,
		    &buf
		);
		if (hres == S_OK)
		    isdeserialized = TRUE;
	    }
	}
	if (!isdeserialized)
	    hres = deserialize_param(
		This->tinfo,
		elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
		FALSE,
		TRUE,
		&(elem->tdesc),
		xargs,
		&buf
	    );
	xargs += _argsize(elem->tdesc.vt);
	if (hres) {
	    FIXME("Failed to deserialize param %s, hres %lx\n",relaystr(names[i+1]),hres);
	    break;
	}
    }
    hres = IUnknown_QueryInterface(This->pUnk,&(This->iid),(LPVOID*)&(args[0]));
    if (hres) {
	ERR("Does not support iface %s\n",debugstr_guid(&(This->iid)));
	return hres;
    }
    res = _invoke(
	    (*((FARPROC**)args[0]))[fdesc->oVft/4],
	    fdesc->callconv,
	    (xargs-args),
	    args
    );
    IUnknown_Release((LPUNKNOWN)args[0]);
    buf.curoff = 0;
    xargs = args+1;
    for (i=0;i<fdesc->cParams;i++) {
	ELEMDESC	*elem = fdesc->lprgelemdescParam+i;
	BOOL		isserialized = FALSE;

	if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) {
	    /* If the parameter is 'riid', we use it as interface IID
	     * for a later ppvObject serialization.
	     */
	    buf.thisisiid = !lstrcmpW(names[i+1],riidW);

	    /* DISPPARAMS* needs special serializer */
	    if (!lstrcmpW(names[i+1],pdispparamsW)) {
		hres = serialize_DISPPARAM_ptr(
		    This->tinfo,
		    elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
		    FALSE,
		    TRUE,
		    &elem->tdesc,
		    xargs,
		    &buf
		);
		isserialized = TRUE;
	    }
	    if (!lstrcmpW(names[i+1],ppvObjectW)) {
		hres = serialize_LPVOID_ptr(
		    This->tinfo,
		    elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
		    FALSE,
		    TRUE,
		    &elem->tdesc,
		    xargs,
		    &buf
		);
		if (hres == S_OK)
		    isserialized = TRUE;
	    }
	}
	if (!isserialized)
	    hres = serialize_param(
	       This->tinfo,
	       elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
	       FALSE,
	       TRUE,
	       &elem->tdesc,
	       xargs,
	       &buf
	    );
	xargs += _argsize(elem->tdesc.vt);
	if (hres) {
	    FIXME("Failed to stuballoc param, hres %lx\n",hres);
	    break;
	}
    }
    /* might need to use IRpcChannelBuffer_GetBuffer ? */
    xmsg->cbBuffer	= buf.curoff;
    xmsg->Buffer	= buf.base;
    HeapFree(GetProcessHeap(),0,args);
    return res;
}

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;

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

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;

    TRACE("(%s,%p,%p)\n",debugstr_guid(riid),pUnkServer,ppStub);
    hres = _get_typeinfo_for_iid(riid,&tinfo);
    if (hres) {
	FIXME("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;
    memcpy(&(stub->iid),riid,sizeof(*riid));
    hres = IRpcStubBuffer_Connect((LPRPCSTUBBUFFER)stub,pUnkServer);
    *ppStub 		= (LPRPCSTUBBUFFER)stub;
    TRACE("IRpcStubBuffer: %p\n", stub);
    if (hres)
	FIXME("Connect to pUnkServer failed?\n");
    return hres;
}

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

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

/***********************************************************************
 *           DllGetClassObject [OLE32.63]
 */
HRESULT WINAPI
TypeLibFac_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
{
    if (IsEqualIID(iid,&IID_IPSFactoryBuffer)) {
	*ppv = &lppsfac;
	return S_OK;
    }
    return E_NOINTERFACE;
}
