Ignore:
Timestamp:
Jun 11, 2002, 8:30:56 AM (23 years ago)
Author:
sandervl
Message:

Wine updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/oleaut32/tmarshal.c

    r8450 r8640  
    4444
    4545static const WCHAR riidW[5] = {'r','i','i','d',0};
     46static const WCHAR pdispparamsW[] = {'p','d','i','s','p','p','a','r','a','m','s',0};
     47static const WCHAR ppvObjectW[] = {'p','p','v','O','b','j','e','c','t',0};
    4648
    4749WINE_DEFAULT_DEBUG_CHANNEL(ole);
     
    183185PSFacBuf_QueryInterface(LPPSFACTORYBUFFER iface, REFIID iid, LPVOID *ppv) {
    184186    if (IsEqualIID(iid,&IID_IPSFactoryBuffer)||IsEqualIID(iid,&IID_IUnknown)) {
    185         *ppv = (LPVOID)iface; 
     187        *ppv = (LPVOID)iface;
    186188        /* No ref counting, static class */
    187189        return S_OK;
     
    252254
    253255/* Determine nr of functions. Since we use the toplevel interface and all
    254  * inherited ones have lower numbers, we are ok to not to descent into 
     256 * inherited ones have lower numbers, we are ok to not to descent into
    255257 * the inheritance tree I think.
    256258 */
     
    275277#include <pshpack1.h>
    276278#endif
    277 
    278279typedef struct _TMAsmProxy {
    279280    BYTE        popleax;
     
    286287    WORD        bytestopop;
    287288} WINE_PACKED TMAsmProxy;
    288 
    289289#ifdef __WIN32OS2__
    290290#include <poppack.h>
     
    366366};
    367367
     368/* how much space do we use on stack in DWORD steps. */
     369static int const
     370_argsize(DWORD vt) {
     371    switch (vt) {
     372    case VT_VARIANT:
     373        return (sizeof(VARIANT)+3)/sizeof(DWORD);
     374    default:
     375        return 1;
     376    }
     377}
     378
     379static int
     380_xsize(TYPEDESC *td) {
     381    switch (td->vt) {
     382    case VT_VARIANT:
     383        return sizeof(VARIANT)+3;
     384    case VT_CARRAY: {
     385        int i, arrsize = 1;
     386        ARRAYDESC *adesc = td->u.lpadesc;
     387
     388        for (i=0;i<adesc->cDims;i++)
     389            arrsize *= adesc->rgbounds[i].cElements;
     390        return arrsize*_xsize(&adesc->tdescElem);
     391    }
     392    case VT_UI2:
     393    case VT_I2:
     394        return 2;
     395    case VT_UI1:
     396    case VT_I1:
     397        return 1;
     398    default:
     399        return 4;
     400    }
     401}
     402
    368403static HRESULT
    369 marshall_param(
    370     ITypeInfo *tinfo, ELEMDESC *elem, TYPEDESC *tdesc, DWORD *arg, marshal_state *buf
     404serialize_param(
     405    ITypeInfo           *tinfo,
     406    BOOL                writeit,
     407    BOOL                debugout,
     408    BOOL                dealloc,
     409    TYPEDESC            *tdesc,
     410    DWORD               *arg,
     411    marshal_state       *buf
    371412) {
    372     int relaydeb = TRACE_ON(olerelay);
    373     HRESULT     hres;
    374 
    375     if (!tdesc) tdesc = &(elem->tdesc);
     413    HRESULT hres = S_OK;
     414
     415    TRACE("(tdesc.vt %d)\n",tdesc->vt);
     416
    376417    switch (tdesc->vt) {
    377     case VT_NULL:
     418    case VT_EMPTY: /* nothing. empty variant for instance */
    378419        return S_OK;
    379     case VT_BSTR: {     /* DWORD size, string data */
    380 
    381             if (*arg) {
     420    case VT_BOOL:
     421    case VT_ERROR:
     422    case VT_UI4:
     423    case VT_UINT:
     424    case VT_I4:
     425    case VT_UI2:
     426    case VT_UI1:
     427        hres = S_OK;
     428        if (debugout) MESSAGE("%lx",*arg);
     429        if (writeit)
     430            hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
     431        return hres;
     432    case VT_VARIANT: {
     433        TYPEDESC        tdesc2;
     434        VARIANT         *vt = (VARIANT*)arg;
     435        DWORD           vttype = V_VT(vt);
     436
     437        if (debugout) MESSAGE("Vt(%ld)(",vttype);
     438        tdesc2.vt = vttype;
     439        if (writeit) {
     440            hres = xbuf_add(buf,(LPBYTE)&vttype,sizeof(vttype));
     441            if (hres) return hres;
     442        }
     443        /* need to recurse since we need to free the stuff */
     444        hres = serialize_param(tinfo,writeit,debugout,dealloc,&tdesc2,&(V_I4(vt)),buf);
     445        if (debugout) MESSAGE(")");
     446        return hres;
     447    }
     448    case VT_BSTR: {
     449        if (debugout) {
     450            if (arg)
     451                    MESSAGE("%s",debugstr_w((BSTR)*arg));
     452            else
     453                    MESSAGE("<bstr NULL>");
     454        }
     455        if (writeit) {
     456            if (!*arg) {
     457                DWORD fakelen = -1;
     458                hres = xbuf_add(buf,(LPBYTE)&fakelen,4);
     459                if (hres)
     460                    return hres;
     461            } else {
    382462                DWORD *bstr = ((DWORD*)(*arg))-1;
    383463
    384                 if (relaydeb) MESSAGE("%s",debugstr_w((LPWSTR)(bstr+1)));
    385                 return xbuf_add(buf,(LPBYTE)bstr,bstr[0]+4);
    386             } else {
    387                 DWORD xnull = 0;
    388 
    389                 return xbuf_add(buf,(LPBYTE)&xnull,sizeof(xnull));
    390             }
    391         }
    392     case VT_BOOL:
    393     case VT_I4:
    394         if (relaydeb) MESSAGE("%ld",*arg);
    395         return xbuf_add(buf,(LPBYTE)arg,4);
    396     case VT_VARIANT: {
    397         /* We use ourselves to marshal the value further */
    398         TYPEDESC tdesc2;
    399         VARIANT *vt = (VARIANT*)arg;
    400         DWORD vttype = V_VT(vt);
    401 
    402         hres = xbuf_add(buf,(LPBYTE)&vttype,sizeof(vttype));
    403         if (hres) return hres;
    404         tdesc2.vt = vttype;
    405         if (relaydeb) MESSAGE("Vt %ld ",vttype);
    406         /* shield your eyes, bad pointer voodoo below */
    407         return marshall_param(tinfo,elem,&tdesc2,(DWORD*)&(V_I4(vt)),buf);
    408     }
    409     case VT_PTR:
    410         return marshall_param(tinfo,elem,tdesc->u.lptdesc,(DWORD*)*arg,buf);
     464                hres = xbuf_add(buf,(LPBYTE)bstr,bstr[0]+4);
     465                if (hres)
     466                    return hres;
     467            }
     468        }
     469        if (dealloc && arg)
     470            SysFreeString((BSTR)arg);
     471        return S_OK;
     472    }
     473    case VT_PTR: {
     474        DWORD cookie;
     475
     476        if (debugout) MESSAGE("*");
     477        if (writeit) {
     478            cookie = *arg ? 0x42424242 : 0;
     479            hres = xbuf_add(buf,(LPBYTE)&cookie,sizeof(cookie));
     480            if (hres)
     481                return hres;
     482        }
     483        if (!*arg) {
     484            if (debugout) MESSAGE("NULL");
     485            return S_OK;
     486        }
     487        hres = serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD*)*arg,buf);
     488        if (dealloc) HeapFree(GetProcessHeap(),0,(LPVOID)arg);
     489        return hres;
     490    }
     491    case VT_UNKNOWN:
     492        if (debugout) MESSAGE("unk(0x%lx)",*arg);
     493        if (writeit)
     494            hres = _marshal_interface(buf,&IID_IUnknown,(LPUNKNOWN)*arg);
     495        return hres;
     496    case VT_DISPATCH:
     497        if (debugout) MESSAGE("idisp(0x%lx)",*arg);
     498        if (writeit)
     499            hres = _marshal_interface(buf,&IID_IDispatch,(LPUNKNOWN)*arg);
     500        return hres;
    411501    case VT_VOID:
    412         hres = _marshal_interface(buf,&(buf->iid),(LPUNKNOWN)arg);
    413         if (hres) {
    414             FIXME("Failed unmarshaling VT_VOID with guid %s?\n",debugstr_guid(&(buf->iid)));
    415         }
    416         return hres;
     502        if (debugout) MESSAGE("<void>");
     503        return S_OK;
    417504    case VT_USERDEFINED: {
    418505        ITypeInfo       *tinfo2;
    419506        TYPEATTR        *tattr;
    420507
    421         /*FIXME("VT_USERDEFINED arg is %p, *arg is %p\n",arg,*arg);*/
    422508        hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
    423509        if (hres) {
     
    428514        switch (tattr->typekind) {
    429515        case TKIND_INTERFACE:
    430             if (relaydeb) MESSAGE("if(%p), vtbl %p",arg,(LPVOID)*arg);
    431             hres = _marshal_interface(buf,&(tattr->guid),(LPUNKNOWN)arg);
     516            if (writeit)
     517               hres=_marshal_interface(buf,&(tattr->guid),(LPUNKNOWN)arg);
    432518            break;
    433         case TKIND_RECORD:
    434             if (relaydeb) MESSAGE("record %p",arg);
    435             if (buf->thisisiid)
     519        case TKIND_RECORD: {
     520            int i;
     521            if (debugout) MESSAGE("{");
     522            for (i=0;i<tattr->cVars;i++) {
     523                VARDESC *vdesc;
     524                ELEMDESC *elem2;
     525                TYPEDESC *tdesc2;
     526
     527                hres = ITypeInfo2_GetVarDesc(tinfo2, i, &vdesc);
     528                if (hres) {
     529                    FIXME("Could not get vardesc of %d\n",i);
     530                    return hres;
     531                }
     532                /* Need them for hack below */
     533                /*
     534                memset(names,0,sizeof(names));
     535                hres = ITypeInfo_GetNames(tinfo2,vdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames);
     536                if (nrofnames > sizeof(names)/sizeof(names[0])) {
     537                    ERR("Need more names!\n");
     538                }
     539                if (!hres && debugout)
     540                    MESSAGE("%s=",debugstr_w(names[0]));
     541                */
     542                elem2 = &vdesc->elemdescVar;
     543                tdesc2 = &elem2->tdesc;
     544                hres = serialize_param(
     545                    tinfo2,
     546                    writeit,
     547                    debugout,
     548                    dealloc,
     549                    tdesc2,
     550                    (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst),
     551                    buf
     552                );
     553                if (hres!=S_OK)
     554                    return hres;
     555                if (debugout && (i<(tattr->cVars-1)))
     556                    MESSAGE(",");
     557            }
     558            if (buf->thisisiid && (tattr->cbSizeInstance==sizeof(GUID)))
    436559                memcpy(&(buf->iid),arg,sizeof(buf->iid));
    437             hres = xbuf_add(buf,(LPBYTE)arg,tattr->cbSizeInstance);
     560            if (debugout) MESSAGE("}");
    438561            break;
     562        }
    439563        default:
    440564            FIXME("Don't know how to marshal type kind %d\n",tattr->typekind);
     
    445569        return hres;
    446570    }
     571    case VT_CARRAY: {
     572        ARRAYDESC *adesc = tdesc->u.lpadesc;
     573        int i, arrsize = 1;
     574
     575        if (debugout) MESSAGE("carr");
     576        for (i=0;i<adesc->cDims;i++) {
     577            if (debugout) MESSAGE("[%ld]",adesc->rgbounds[i].cElements);
     578            arrsize *= adesc->rgbounds[i].cElements;
     579        }
     580        if (debugout) MESSAGE("[");
     581        for (i=0;i<arrsize;i++) {
     582            hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)arg+i*_xsize(&adesc->tdescElem)), buf);
     583            if (hres)
     584                return hres;
     585            if (debugout && (i<arrsize-1)) MESSAGE(",");
     586        }
     587        if (debugout) MESSAGE("]");
     588        return S_OK;
     589    }
    447590    default:
    448         ERR("Cannot marshal type %d\n",tdesc->vt);
    449         /*dump_ELEMDESC(elem);*/
     591        ERR("Unhandled marshal type %d.\n",tdesc->vt);
     592        return S_OK;
     593    }
     594}
     595
     596static HRESULT
     597serialize_LPVOID_ptr(
     598    ITypeInfo           *tinfo,
     599    BOOL                writeit,
     600    BOOL                debugout,
     601    BOOL                dealloc,
     602    TYPEDESC            *tdesc,
     603    DWORD               *arg,
     604    marshal_state       *buf
     605) {
     606    HRESULT     hres;
     607    DWORD       cookie;
     608
     609    if ((tdesc->vt != VT_PTR)                   ||
     610        (tdesc->u.lptdesc->vt != VT_PTR)        ||
     611        (tdesc->u.lptdesc->u.lptdesc->vt != VT_VOID)
     612    ) {
     613        FIXME("ppvObject not expressed as VT_PTR -> VT_PTR -> VT_VOID?\n");
    450614        return E_FAIL;
    451615    }
     616    cookie = (*arg) ? 0x42424242: 0x0;
     617    if (writeit) {
     618        hres = xbuf_add(buf, (LPVOID)&cookie, sizeof(cookie));
     619        if (hres)
     620            return hres;
     621    }
     622    if (!*arg) {
     623        if (debugout) MESSAGE("<lpvoid NULL>");
     624        return S_OK;
     625    }
     626    if (debugout)
     627        MESSAGE("ppv(%p)",*(LPUNKNOWN*)*arg);
     628    if (writeit) {
     629        hres = _marshal_interface(buf,&(buf->iid),*(LPUNKNOWN*)*arg);
     630        if (hres)
     631            return hres;
     632    }
     633    if (dealloc)
     634        HeapFree(GetProcessHeap(),0,(LPVOID)*arg);
    452635    return S_OK;
    453636}
    454637
    455638static HRESULT
    456 unmarshall_param(
    457     ITypeInfo *tinfo, ELEMDESC *elem, TYPEDESC *tdesc, DWORD *arg, marshal_state *buf
     639serialize_DISPPARAM_ptr(
     640    ITypeInfo           *tinfo,
     641    BOOL                writeit,
     642    BOOL                debugout,
     643    BOOL                dealloc,
     644    TYPEDESC            *tdesc,
     645    DWORD               *arg,
     646    marshal_state       *buf
     647) {
     648    DWORD       cookie;
     649    HRESULT     hres;
     650    DISPPARAMS  *disp;
     651    int         i;
     652
     653    if ((tdesc->vt != VT_PTR) || (tdesc->u.lptdesc->vt != VT_USERDEFINED)) {
     654        FIXME("DISPPARAMS not expressed as VT_PTR -> VT_USERDEFINED?\n");
     655        return E_FAIL;
     656    }
     657
     658    cookie = *arg ? 0x42424242 : 0x0;
     659    if (writeit) {
     660        hres = xbuf_add(buf,(LPBYTE)&cookie,sizeof(cookie));
     661        if (hres)
     662            return hres;
     663    }
     664    if (!*arg) {
     665        if (debugout) MESSAGE("<DISPPARAMS NULL>");
     666        return S_OK;
     667    }
     668    disp = (DISPPARAMS*)*arg;
     669    if (writeit) {
     670        hres = xbuf_add(buf,(LPBYTE)&disp->cArgs,sizeof(disp->cArgs));
     671        if (hres)
     672            return hres;
     673    }
     674    if (debugout) MESSAGE("D{");
     675    for (i=0;i<disp->cArgs;i++) {
     676        TYPEDESC        vtdesc;
     677
     678        vtdesc.vt = VT_VARIANT;
     679        serialize_param(
     680            tinfo,
     681            writeit,
     682            debugout,
     683            dealloc,
     684            &vtdesc,
     685            (DWORD*)(disp->rgvarg+i),
     686            buf
     687        );
     688        if (debugout && (i<disp->cArgs-1))
     689            MESSAGE(",");
     690    }
     691    if (dealloc)
     692        HeapFree(GetProcessHeap(),0,disp->rgvarg);
     693    if (writeit) {
     694        hres = xbuf_add(buf,(LPBYTE)&disp->cNamedArgs,sizeof(disp->cNamedArgs));
     695        if (hres)
     696            return hres;
     697    }
     698    if (debugout) MESSAGE("}{");
     699    for (i=0;i<disp->cNamedArgs;i++) {
     700        TYPEDESC        vtdesc;
     701
     702        vtdesc.vt = VT_UINT;
     703        serialize_param(
     704            tinfo,
     705            writeit,
     706            debugout,
     707            dealloc,
     708            &vtdesc,
     709            (DWORD*)(disp->rgdispidNamedArgs+i),
     710            buf
     711        );
     712        if (debugout && (i<disp->cNamedArgs-1))
     713            MESSAGE(",");
     714    }
     715    if (debugout) MESSAGE("}");
     716    if (dealloc) {
     717        HeapFree(GetProcessHeap(),0,disp->rgdispidNamedArgs);
     718        HeapFree(GetProcessHeap(),0,disp);
     719    }
     720    return S_OK;
     721}
     722
     723static HRESULT
     724deserialize_param(
     725    ITypeInfo           *tinfo,
     726    BOOL                readit,
     727    BOOL                debugout,
     728    BOOL                alloc,
     729    TYPEDESC            *tdesc,
     730    DWORD               *arg,
     731    marshal_state       *buf
    458732) {
    459733    HRESULT hres = S_OK;
    460     int relaydeb = TRACE_ON(olerelay);
    461 
    462     if (!tdesc) tdesc = &(elem->tdesc);
    463     switch (tdesc->vt) {
    464     case VT_I4: {
    465         DWORD x;
    466         xbuf_get(buf,(LPBYTE)&x,sizeof(x));
    467         *arg = x;
    468         if (relaydeb) MESSAGE("%ld ",x);
     734
     735    TRACE("vt %d at %p\n",tdesc->vt,arg);
     736
     737    while (1) {
     738        switch (tdesc->vt) {
     739        case VT_EMPTY:
     740            if (debugout) MESSAGE("<empty>");
     741            return S_OK;
     742        case VT_NULL:
     743            if (debugout) MESSAGE("<null>");
     744            return S_OK;
     745        case VT_VARIANT: {
     746            VARIANT     *vt = (VARIANT*)arg;
     747
     748            if (readit) {
     749                DWORD   vttype;
     750                TYPEDESC        tdesc2;
     751                hres = xbuf_get(buf,(LPBYTE)&vttype,sizeof(vttype));
     752                if (hres) {
     753                    FIXME("vt type not read?\n");
     754                    return hres;
     755                }
     756                memset(&tdesc2,0,sizeof(tdesc2));
     757                tdesc2.vt = vttype;
     758                V_VT(vt)  = vttype;
     759                if (debugout) MESSAGE("Vt(%ld)(",vttype);
     760                hres = deserialize_param(tinfo, readit, debugout, alloc, &tdesc2, &(V_I4(vt)), buf);
     761                MESSAGE(")");
     762                return hres;
     763            } else {
     764                VariantInit(vt);
     765                return S_OK;
     766            }
     767        }
     768        case VT_ERROR:
     769        case VT_BOOL: case VT_I4: case VT_UI4: case VT_UINT:
     770        case VT_UI2:
     771        case VT_UI1:
     772            if (readit) {
     773                hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
     774                if (hres) FIXME("Failed to read integer 4 byte\n");
     775            }
     776            if (debugout) MESSAGE("%lx",*arg);
     777            return hres;
     778        case VT_BSTR: {
     779            WCHAR       *str;
     780            DWORD       len;
     781
     782            if (readit) {
     783                hres = xbuf_get(buf,(LPBYTE)&len,sizeof(DWORD));
     784                if (hres) {
     785                    FIXME("failed to read bstr klen\n");
     786                    return hres;
     787                }
     788                if (len == -1) {
     789                    *arg = 0;
     790                    if (debugout) MESSAGE("<bstr NULL>");
     791                } else {
     792                    str  = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+sizeof(WCHAR));
     793                    hres = xbuf_get(buf,(LPBYTE)str,len);
     794                    if (hres) {
     795                        FIXME("Failed to read BSTR.\n");
     796                        return hres;
     797                    }
     798                    *arg = (DWORD)SysAllocStringLen(str,len);
     799                    if (debugout) MESSAGE("%s",debugstr_w(str));
     800                    HeapFree(GetProcessHeap(),0,str);
     801                }
     802            } else {
     803                *arg = 0;
     804            }
     805            return S_OK;
     806        }
     807        case VT_PTR: {
     808            DWORD       cookie;
     809            BOOL        derefhere = 0;
     810
     811            derefhere = (tdesc->u.lptdesc->vt != VT_USERDEFINED);
     812
     813            if (readit) {
     814                hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie));
     815                if (hres) {
     816                    FIXME("Failed to load pointer cookie.\n");
     817                    return hres;
     818                }
     819                if (cookie != 0x42424242) {
     820                    if (debugout) MESSAGE("NULL");
     821                    *arg = 0;
     822                    return S_OK;
     823                }
     824                if (debugout) MESSAGE("*");
     825            }
     826            if (alloc) {
     827                if (derefhere)
     828                    *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc));
     829            }
     830            if (derefhere)
     831                return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, (LPDWORD)*arg, buf);
     832            else
     833                return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, arg, buf);
     834        }
     835        case VT_UNKNOWN:
     836            /* FIXME: UNKNOWN is unknown ..., but allocate 4 byte for it */
     837            if (alloc)
     838                *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD));
     839            hres = S_OK;
     840            if (readit)
     841                hres = _unmarshal_interface(buf,&IID_IUnknown,(LPUNKNOWN*)arg);
     842            if (debugout)
     843                MESSAGE("unk(%p)",arg);
     844            return hres;
     845        case VT_DISPATCH:
     846            hres = S_OK;
     847            if (readit)
     848                hres = _unmarshal_interface(buf,&IID_IDispatch,(LPUNKNOWN*)arg);
     849            if (debugout)
     850                MESSAGE("idisp(%p)",arg);
     851            return hres;
     852        case VT_VOID:
     853            if (debugout) MESSAGE("<void>");
     854            return S_OK;
     855        case VT_USERDEFINED: {
     856            ITypeInfo   *tinfo2;
     857            TYPEATTR    *tattr;
     858
     859            hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
     860            if (hres) {
     861                FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED.\n",tdesc->u.hreftype);
     862                return hres;
     863            }
     864            hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr);
     865            if (hres) {
     866                FIXME("Could not get typeattr in VT_USERDEFINED.\n");
     867            } else {
     868                if (alloc)
     869                    *arg = (DWORD)HeapAlloc(GetProcessHeap(),0,tattr->cbSizeInstance);
     870                switch (tattr->typekind) {
     871                case TKIND_INTERFACE:
     872                    if (readit)
     873                        hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg);
     874                    break;
     875                case TKIND_RECORD: {
     876                    int i;
     877
     878                    if (debugout) MESSAGE("{");
     879                    for (i=0;i<tattr->cVars;i++) {
     880                        VARDESC *vdesc;
     881
     882                        hres = ITypeInfo2_GetVarDesc(tinfo2, i, &vdesc);
     883                        if (hres) {
     884                            FIXME("Could not get vardesc of %d\n",i);
     885                            return hres;
     886                        }
     887                        hres = deserialize_param(
     888                            tinfo2,
     889                            readit,
     890                            debugout,
     891                            alloc,
     892                            &vdesc->elemdescVar.tdesc,
     893                            (DWORD*)(((LPBYTE)*arg)+vdesc->u.oInst),
     894                            buf
     895                        );
     896                        if (debugout && (i<tattr->cVars-1)) MESSAGE(",");
     897                    }
     898                    if (buf->thisisiid && (tattr->cbSizeInstance==sizeof(GUID)))
     899                        memcpy(&(buf->iid),(LPBYTE)*arg,sizeof(buf->iid));
     900                    if (debugout) MESSAGE("}");
     901                    break;
     902                }
     903                default:
     904                    FIXME("Don't know how to marshal type kind %d\n",tattr->typekind);
     905                    hres = E_FAIL;
     906                    break;
     907                }
     908            }
     909            if (hres)
     910                FIXME("failed to stuballoc in TKIND_RECORD.\n");
     911            ITypeInfo_Release(tinfo2);
     912            return hres;
     913        }
     914        case VT_CARRAY: {
     915            /* arg is pointing to the start of the array. */
     916            ARRAYDESC *adesc = tdesc->u.lpadesc;
     917            int         arrsize,i;
     918            arrsize = 1;
     919            if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it work?\n");
     920            for (i=0;i<adesc->cDims;i++)
     921                arrsize *= adesc->rgbounds[i].cElements;
     922            for (i=0;i<arrsize;i++)
     923                deserialize_param(
     924                    tinfo,
     925                    readit,
     926                    debugout,
     927                    alloc,
     928                    &adesc->tdescElem,
     929                    (DWORD*)((LPBYTE)(arg)+i*_xsize(&adesc->tdescElem)),
     930                    buf
     931                );
     932            return S_OK;
     933        }
     934        default:
     935            ERR("No handler for VT type %d!\n",tdesc->vt);
     936            return S_OK;
     937        }
     938    }
     939}
     940
     941static HRESULT
     942deserialize_LPVOID_ptr(
     943    ITypeInfo           *tinfo,
     944    BOOL                readit,
     945    BOOL                debugout,
     946    BOOL                alloc,
     947    TYPEDESC            *tdesc,
     948    DWORD               *arg,
     949    marshal_state       *buf
     950) {
     951    HRESULT     hres;
     952    DWORD       cookie;
     953
     954    if ((tdesc->vt != VT_PTR)                   ||
     955        (tdesc->u.lptdesc->vt != VT_PTR)        ||
     956        (tdesc->u.lptdesc->u.lptdesc->vt != VT_VOID)
     957    ) {
     958        FIXME("ppvObject not expressed as VT_PTR -> VT_PTR -> VT_VOID?\n");
     959        return E_FAIL;
     960    }
     961    if (alloc)
     962        *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LPVOID));
     963    if (readit) {
     964        hres = xbuf_get(buf, (LPVOID)&cookie, sizeof(cookie));
     965        if (hres)
     966            return hres;
     967        if (cookie != 0x42424242) {
     968            *(DWORD*)*arg = 0;
     969            if (debugout) MESSAGE("<lpvoid NULL>");
     970            return S_OK;
     971        }
     972    }
     973    if (readit) {
     974        hres = _unmarshal_interface(buf,&buf->iid,(LPUNKNOWN*)*arg);
     975        if (hres)
     976            return hres;
     977    }
     978    if (debugout) MESSAGE("ppv(%p)",(LPVOID)*arg);
     979    return S_OK;
     980}
     981
     982static HRESULT
     983deserialize_DISPPARAM_ptr(
     984    ITypeInfo           *tinfo,
     985    BOOL                readit,
     986    BOOL                debugout,
     987    BOOL                alloc,
     988    TYPEDESC            *tdesc,
     989    DWORD               *arg,
     990    marshal_state       *buf
     991) {
     992    DWORD       cookie;
     993    DISPPARAMS  *disps;
     994    HRESULT     hres;
     995    int         i;
     996
     997    if ((tdesc->vt != VT_PTR) || (tdesc->u.lptdesc->vt != VT_USERDEFINED)) {
     998        FIXME("DISPPARAMS not expressed as VT_PTR -> VT_USERDEFINED?\n");
     999        return E_FAIL;
     1000    }
     1001    if (readit) {
     1002        hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie));
     1003        if (hres)
     1004            return hres;
     1005        if (cookie == 0) {
     1006            *arg = 0;
     1007            if (debugout) MESSAGE("<DISPPARAMS NULL>");
     1008            return S_OK;
     1009        }
     1010    }
     1011    if (alloc)
     1012        *arg = (DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DISPPARAMS));
     1013    disps = (DISPPARAMS*)*arg;
     1014    if (!readit)
    4691015        return S_OK;
    470     }
    471     case VT_PTR:
    472         if ((tdesc->u.lptdesc->vt != VT_USERDEFINED) &&
    473             (tdesc->u.lptdesc->vt != VT_VOID)
    474         )
    475             hres = unmarshall_param(tinfo,elem,tdesc->u.lptdesc,(DWORD*)(*arg),buf);
    476         else
    477             hres = unmarshall_param(tinfo,elem,tdesc->u.lptdesc,arg,buf);
    478         if (relaydeb) MESSAGE("%p ",(LPVOID)*arg);
    479         return S_OK;
    480     case VT_USERDEFINED: {
    481         ITypeInfo       *tinfo2;
    482         TYPEATTR        *tattr;
    483 
    484         if (relaydeb) MESSAGE("%p",arg);
    485         hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
    486         if (hres) {
    487             FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED.\n",tdesc->u.hreftype);
    488             return hres;
    489         }
    490         hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr);
    491         if (hres) {
    492             FIXME("Could not get typeattr in VT_USERDEFINED.\n");
    493             return hres;
    494         }
    495         switch (tattr->typekind) {
    496         case TKIND_INTERFACE:
    497             hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg);
    498             break;
    499         case TKIND_RECORD:
    500             hres = xbuf_get(buf,(LPBYTE)arg,tattr->cbSizeInstance);
    501             break;
    502         default:
    503             hres = E_FAIL;
    504             FIXME("Don't know how to marshal type kind %d\n",tattr->typekind);
    505         }
    506         ITypeInfo_Release(tinfo2);
    507         return hres;
    508     }
    509     case VT_VOID:
    510         /* Hacky. If we are LPVOID* we apparently have to guess the IID
    511          * for the interface. This sucks pretty badly. */
    512         return _unmarshal_interface(buf,&(buf->iid),(LPUNKNOWN*)arg);
    513     default:    ERR("Cannot unmarshal type %d\n",tdesc->vt);
    514                 return E_FAIL;
    515     }
     1016    hres = xbuf_get(buf, (LPBYTE)&disps->cArgs, sizeof(disps->cArgs));
     1017    if (hres)
     1018        return hres;
     1019    if (alloc)
     1020        disps->rgvarg = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(VARIANT)*disps->cArgs);
     1021    if (debugout) MESSAGE("D{");
     1022    for (i=0; i< disps->cArgs; i++) {
     1023        TYPEDESC vdesc;
     1024
     1025        vdesc.vt = VT_VARIANT;
     1026        hres = deserialize_param(
     1027            tinfo,
     1028            readit,
     1029            debugout,
     1030            alloc,
     1031            &vdesc,
     1032            (DWORD*)(disps->rgvarg+i),
     1033            buf
     1034        );
     1035    }
     1036    if (debugout) MESSAGE("}{");
     1037    hres = xbuf_get(buf, (LPBYTE)&disps->cNamedArgs, sizeof(disps->cNamedArgs));
     1038    if (hres)
     1039        return hres;
     1040    if (disps->cNamedArgs) {
     1041        if (alloc)
     1042            disps->rgdispidNamedArgs = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DISPID)*disps->cNamedArgs);
     1043        for (i=0; i< disps->cNamedArgs; i++) {
     1044            TYPEDESC vdesc;
     1045
     1046            vdesc.vt = VT_UINT;
     1047            hres = deserialize_param(
     1048                tinfo,
     1049                readit,
     1050                debugout,
     1051                alloc,
     1052                &vdesc,
     1053                (DWORD*)(disps->rgdispidNamedArgs+i),
     1054                buf
     1055            );
     1056            if (debugout && i<(disps->cNamedArgs-1)) MESSAGE(",");
     1057        }
     1058    }
     1059    if (debugout) MESSAGE("}");
    5161060    return S_OK;
    5171061}
     
    5201064static HRESULT
    5211065_get_funcdesc(
    522         ITypeInfo *tinfo, int iMethod, FUNCDESC **fdesc,
    523         BSTR *iname, BSTR *fname
     1066    ITypeInfo *tinfo, int iMethod, FUNCDESC **fdesc, BSTR *iname, BSTR *fname
    5241067) {
    5251068    int i = 0, j = 0;
     
    5691112    }
    5701113    return E_FAIL;
    571 }
    572 
    573 /* how much space do we use on stack in DWORD steps. */
    574 static int
    575 _argsize(DWORD vt_type) {
    576     switch (vt_type) {
    577     case VT_VARIANT:
    578         return (sizeof(VARIANT)+3)/sizeof(DWORD);
    579     default:
    580         return 1;
    581     }
    5821114}
    5831115
     
    6201152    /* Need them for hack below */
    6211153    memset(names,0,sizeof(names));
    622     ITypeInfo_GetNames(tpinfo->tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames);
    623     if (nrofnames > sizeof(names)/sizeof(names[0])) {
     1154    if (ITypeInfo_GetNames(tpinfo->tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames))
     1155        nrofnames = 0;
     1156    if (nrofnames > sizeof(names)/sizeof(names[0]))
    6241157        ERR("Need more names!\n");
    625     }
     1158
    6261159    memset(&buf,0,sizeof(buf));
    6271160    buf.iid = IID_IUnknown;
     
    6331166        for (i=0;i<fdesc->cParams;i++) {
    6341167            ELEMDESC    *elem = fdesc->lprgelemdescParam+i;
     1168            BOOL        isserialized = FALSE;
    6351169            if (relaydeb) {
    6361170                if (i) MESSAGE(",");
    6371171                if (i+1<nrofnames && names[i+1])
    6381172                    MESSAGE("%s=",debugstr_w(names[i+1]));
    639             }
    640             if (((i+1)<nrofnames) && !lstrcmpW(names[i+1],riidW)) {
    641                 buf.thisisiid = TRUE;
    642             } else {
    643                 buf.thisisiid = FALSE;
    6441173            }
    6451174            /* No need to marshal other data than FIN */
     
    6491178                continue;
    6501179            }
    651             hres = marshall_param(tpinfo->tinfo,elem,NULL,xargs,&buf);
     1180            if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) {
     1181                /* If the parameter is 'riid', we use it as interface IID
     1182                 * for a later ppvObject serialization.
     1183                 */
     1184                buf.thisisiid = !lstrcmpW(names[i+1],riidW);
     1185
     1186                /* DISPPARAMS* needs special serializer */
     1187                if (!lstrcmpW(names[i+1],pdispparamsW)) {
     1188                    hres = serialize_DISPPARAM_ptr(
     1189                        tpinfo->tinfo,
     1190                        elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
     1191                        relaydeb,
     1192                        FALSE,
     1193                        &elem->tdesc,
     1194                        xargs,
     1195                        &buf
     1196                    );
     1197                    isserialized = TRUE;
     1198                }
     1199                if (!lstrcmpW(names[i+1],ppvObjectW)) {
     1200                    hres = serialize_LPVOID_ptr(
     1201                        tpinfo->tinfo,
     1202                        elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
     1203                        relaydeb,
     1204                        FALSE,
     1205                        &elem->tdesc,
     1206                        xargs,
     1207                        &buf
     1208                    );
     1209                    if (hres == S_OK)
     1210                        isserialized = TRUE;
     1211                }
     1212            }
     1213            if (!isserialized)
     1214                hres = serialize_param(
     1215                    tpinfo->tinfo,
     1216                    elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
     1217                    relaydeb,
     1218                    FALSE,
     1219                    &elem->tdesc,
     1220                    xargs,
     1221                    &buf
     1222                );
     1223
     1224            if (hres) {
     1225                FIXME("Failed to serialize param, hres %lx\n",hres);
     1226                break;
     1227            }
    6521228            xargs+=_argsize(elem->tdesc.vt);
    653             if (hres) {
    654                 FIXME("Failed to marshall param, hres %lx\n",hres);
    655                 break;
    656             }
    6571229        }
    6581230    }
     
    6671239    }
    6681240    memcpy(msg.Buffer,buf.base,buf.curoff);
     1241    if (relaydeb) MESSAGE("\n");
    6691242    hres = IRpcChannelBuffer_SendReceive(tpinfo->chanbuf,&msg,&status);
    6701243    if (hres) {
     
    6721245        return hres;
    6731246    }
     1247    relaydeb = TRACE_ON(olerelay);
    6741248    if (relaydeb) MESSAGE(" = %08lx (",status);
    6751249    if (buf.base)
     
    6871261        for (i=0;i<fdesc->cParams;i++) {
    6881262            ELEMDESC    *elem = fdesc->lprgelemdescParam+i;
     1263            BOOL        isdeserialized = FALSE;
    6891264
    6901265            if (relaydeb) {
     
    6981273                continue;
    6991274            }
    700             hres = unmarshall_param(tpinfo->tinfo,elem,&(elem->tdesc),xargs,&buf);
    701             xargs += _argsize(elem->tdesc.vt);
     1275            if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) {
     1276                /* If the parameter is 'riid', we use it as interface IID
     1277                 * for a later ppvObject serialization.
     1278                 */
     1279                buf.thisisiid = !lstrcmpW(names[i+1],riidW);
     1280
     1281                /* deserialize DISPPARAM */
     1282                if (!lstrcmpW(names[i+1],pdispparamsW)) {
     1283                    hres = deserialize_DISPPARAM_ptr(
     1284                        tpinfo->tinfo,
     1285                        elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
     1286                        relaydeb,
     1287                        FALSE,
     1288                        &(elem->tdesc),
     1289                        xargs,
     1290                        &buf
     1291                    );
     1292                    if (hres) {
     1293                        FIXME("Failed to deserialize DISPPARAM*, hres %lx\n",hres);
     1294                        break;
     1295                    }
     1296                    isdeserialized = TRUE;
     1297                }
     1298                if (!lstrcmpW(names[i+1],ppvObjectW)) {
     1299                    hres = deserialize_LPVOID_ptr(
     1300                        tpinfo->tinfo,
     1301                        elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
     1302                        relaydeb,
     1303                        FALSE,
     1304                        &elem->tdesc,
     1305                        xargs,
     1306                        &buf
     1307                    );
     1308                    if (hres == S_OK)
     1309                        isdeserialized = TRUE;
     1310                }
     1311            }
     1312            if (!isdeserialized)
     1313                hres = deserialize_param(
     1314                    tpinfo->tinfo,
     1315                    elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
     1316                    relaydeb,
     1317                    FALSE,
     1318                    &(elem->tdesc),
     1319                    xargs,
     1320                    &buf
     1321                );
    7021322            if (hres) {
    7031323                FIXME("Failed to unmarshall param, hres %lx\n",hres);
    7041324                break;
    7051325            }
    706         }
    707     }
    708     if (relaydeb) MESSAGE(")\n");
     1326            xargs += _argsize(elem->tdesc.vt);
     1327        }
     1328    }
     1329    if (relaydeb) MESSAGE(")\n\n");
    7091330    HeapFree(GetProcessHeap(),0,buf.base);
    7101331    return status;
     
    7211342    FUNCDESC    *fdesc;
    7221343    TMProxyImpl *proxy;
    723    
     1344
    7241345    TRACE("(...%s...)\n",debugstr_guid(riid));
    7251346    hres = _get_typeinfo_for_iid(riid,&tinfo);
     
    8511472}
    8521473
    853 static HRESULT
    854 stuballoc_param(
    855     ITypeInfo *tinfo, ELEMDESC *elem, TYPEDESC *tdesc, DWORD *arg, marshal_state *buf
    856 ) {
    857     HRESULT hres;
    858 
    859     while (1) {
    860         switch (tdesc->vt) {
    861         case VT_VARIANT: {
    862             DWORD       vttype;
    863             VARIANT     *vt = (VARIANT*)arg;
    864             TYPEDESC    tdesc2;
    865 
    866             hres = xbuf_get(buf,(LPBYTE)&vttype,sizeof(vttype));
    867             if (hres) return hres;
    868             memset(&tdesc2,0,sizeof(tdesc));
    869             tdesc2.vt = vttype;
    870             V_VT(vt)  = vttype;
    871             return stuballoc_param(tinfo,elem,&tdesc2,&(V_I4(vt)),buf);
    872         }
    873         case VT_BOOL: case VT_I4:
    874             xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
    875             return S_OK;
    876         case VT_BSTR: {
    877                 WCHAR   *str;
    878                 DWORD   len;
    879 
    880                 hres = xbuf_get(buf,(LPBYTE)&len,sizeof(DWORD));
    881                 if (hres)
    882                     return hres;
    883                 str  = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+sizeof(WCHAR));
    884                 hres = xbuf_get(buf,(LPBYTE)str,len);
    885                 if (hres) return hres;
    886                 *arg = (DWORD)SysAllocStringLen(str,len);
    887                 HeapFree(GetProcessHeap(),0,str);
    888                 return S_OK;
    889             }
    890         case VT_PTR:
    891             if ((tdesc->u.lptdesc->vt != VT_USERDEFINED) &&
    892                 (tdesc->u.lptdesc->vt != VT_VOID)
    893             ) {
    894                 *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LPVOID));
    895                 arg = (DWORD*)*arg;
    896             }
    897             tdesc = tdesc->u.lptdesc;
    898             break;
    899         case VT_UNKNOWN:
    900             /* FIXME: UNKNOWN is unknown ..., but allocate 4 byte for it */
    901             *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD));
    902             return S_OK;
    903         case VT_VOID:
    904             *arg = (DWORD)HeapAlloc(GetProcessHeap(),0,sizeof(LPVOID));
    905             hres = S_OK;
    906             if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN)
    907                 hres = _unmarshal_interface(buf,&(buf->iid),(LPUNKNOWN*)arg);
    908             return hres;
    909         case VT_USERDEFINED: {
    910             if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN) {
    911                 ITypeInfo       *tinfo2;
    912                 TYPEATTR        *tattr;
    913 
    914                 hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
    915                 if (hres) {
    916                     FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED.\n",tdesc->u.hreftype);
    917                     return hres;
    918                 }
    919                 hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr);
    920                 if (hres) {
    921                     FIXME("Could not get typeattr in VT_USERDEFINED.\n");
    922                     return hres;
    923                 }
    924                 switch (tattr->typekind) {
    925                 case TKIND_INTERFACE:
    926                     hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg);
    927                     break;
    928                 case TKIND_RECORD:
    929                     *arg = (DWORD)HeapAlloc(GetProcessHeap(),0,tattr->cbSizeInstance);
    930                     hres = xbuf_get(buf,(LPBYTE)*arg,tattr->cbSizeInstance);
    931                     if (buf->thisisiid)
    932                         memcpy(&(buf->iid),(LPBYTE)*arg,sizeof(buf->iid));
    933                     break;
    934                 default:
    935                     FIXME("Don't know how to marshal type kind %d\n",tattr->typekind);
    936                     hres = E_FAIL;
    937                     break;
    938                 }
    939                 ITypeInfo_Release(tinfo2);
    940                 return hres;
    941             } else {
    942                 *arg = (DWORD)HeapAlloc(GetProcessHeap(),0,sizeof(LPVOID));
    943                 return S_OK;
    944             }
    945         }
    946         default:
    947             ERR("No handler for VT type %d, just allocating 4 bytes.\n",tdesc->vt);
    948             *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD));
    949             return S_OK;
    950         }
    951     }
    952 }
    953 
    954 static HRESULT
    955 stubunalloc_param(
    956     ITypeInfo *tinfo, ELEMDESC *elem, TYPEDESC *tdesc, DWORD *arg, marshal_state *buf
    957 ) {
    958     HRESULT hres = S_OK;
    959 
    960     if (!tdesc) tdesc = &(elem->tdesc);
    961 
    962     switch (tdesc->vt) {
    963     case VT_BOOL:
    964     case VT_I4:
    965         hres = S_OK;
    966         if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT)
    967             hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
    968         return hres;
    969     case VT_VARIANT: {
    970         TYPEDESC        tdesc2;
    971         VARIANT         *vt = (VARIANT*)arg;
    972         DWORD           vttype = V_VT(vt);
    973 
    974         tdesc2.vt = vttype;
    975         if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT) {
    976             hres = xbuf_add(buf,(LPBYTE)&vttype,sizeof(vttype));
    977             if (hres) return hres;
    978         }
    979         /* need to recurse since we need to free the stuff */
    980         hres = stubunalloc_param(tinfo,elem,&tdesc2,&(V_I4(vt)),buf);
    981         return hres;
    982     }
    983     case VT_BSTR: {
    984         if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT) {
    985             DWORD *bstr = ((DWORD*)(*arg))-1;
    986 
    987             hres = xbuf_add(buf,(LPBYTE)bstr,bstr[0]+4);
    988             if (hres)
    989                 return hres;
    990         }
    991         SysFreeString((BSTR)*arg);
    992         return S_OK;
    993     }
    994     case VT_PTR:
    995         /*FIXME("VT_PTR *arg is %p\n",(LPVOID)*arg);*/
    996         if ((tdesc->u.lptdesc->vt != VT_USERDEFINED) &&
    997             (tdesc->u.lptdesc->vt != VT_VOID)
    998         ) {
    999             hres = stubunalloc_param(tinfo,elem,tdesc->u.lptdesc,arg,buf);
    1000         } else {
    1001             hres = stubunalloc_param(tinfo,elem,tdesc->u.lptdesc,(DWORD*)*arg,buf);
    1002             HeapFree(GetProcessHeap(),0,(LPVOID)*arg);
    1003         }
    1004         return hres;
    1005     case VT_UNKNOWN:
    1006         if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT) {
    1007             FIXME("Marshaling back VT_UNKNOWN %lx\n",*arg);
    1008             hres = xbuf_add(buf,(LPBYTE)*arg,sizeof(DWORD));
    1009         }
    1010         HeapFree(GetProcessHeap(),0,(LPVOID)*arg);
    1011         return hres;
    1012     case VT_VOID:
    1013         hres = S_OK;
    1014         if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT)
    1015             hres = _marshal_interface(buf,&(buf->iid),(LPUNKNOWN)*arg);
    1016         return hres;
    1017     case VT_USERDEFINED: {
    1018         ITypeInfo       *tinfo2;
    1019         TYPEATTR        *tattr;
    1020 
    1021         if (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT) {
    1022             /*FIXME("VT_USERDEFINED arg is %p, *arg is %p\n",arg,*arg);*/
    1023             hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
    1024             if (hres) {
    1025                 FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED.\n",tdesc->u.hreftype);
    1026                 return hres;
    1027             }
    1028             ITypeInfo_GetTypeAttr(tinfo2,&tattr);
    1029             switch (tattr->typekind) {
    1030             case TKIND_INTERFACE:
    1031                 hres = _marshal_interface(buf,&(tattr->guid),(LPUNKNOWN)*arg);
    1032                 break;
    1033             case TKIND_RECORD:
    1034                 hres = xbuf_add(buf,(LPBYTE)arg,tattr->cbSizeInstance);
    1035                 break;
    1036             default:
    1037                 FIXME("Don't know how to marshal type kind %d\n",tattr->typekind);
    1038                 hres = E_FAIL;
    1039                 break;
    1040             }
    1041             ITypeInfo_Release(tinfo2);
    1042         }
    1043         return hres;
    1044     }
    1045     default:
    1046         ERR("Unhandled marshal type %d.\n",tdesc->vt);
    1047         HeapFree(GetProcessHeap(),0,(LPVOID)*arg);
    1048         return S_OK;
    1049     }
    1050 }
    1051 
    10521474static HRESULT WINAPI
    10531475TMStubImpl_Invoke(
     
    11041526    for (i=0;i<fdesc->cParams;i++) {
    11051527        ELEMDESC        *elem = fdesc->lprgelemdescParam+i;
    1106 
    1107         if (((i+1)<nrofnames) && !lstrcmpW(names[i+1],riidW))
    1108             buf.thisisiid = TRUE;
    1109         else
    1110             buf.thisisiid = FALSE;
    1111         hres   = stuballoc_param(This->tinfo,elem,&(elem->tdesc),xargs,&buf);
     1528        BOOL            isdeserialized = FALSE;
     1529
     1530        if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) {
     1531            /* If the parameter is 'riid', we use it as interface IID
     1532             * for a later ppvObject serialization.
     1533             */
     1534            buf.thisisiid = !lstrcmpW(names[i+1],riidW);
     1535
     1536            /* deserialize DISPPARAM */
     1537            if (!lstrcmpW(names[i+1],pdispparamsW)) {
     1538                hres = deserialize_DISPPARAM_ptr(
     1539                    This->tinfo,
     1540                    elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
     1541                    FALSE,
     1542                    TRUE,
     1543                    &(elem->tdesc),
     1544                    xargs,
     1545                    &buf
     1546                );
     1547                if (hres) {
     1548                    FIXME("Failed to deserialize DISPPARAM*, hres %lx\n",hres);
     1549                    break;
     1550                }
     1551                isdeserialized = TRUE;
     1552            }
     1553            if (!lstrcmpW(names[i+1],ppvObjectW)) {
     1554                hres = deserialize_LPVOID_ptr(
     1555                    This->tinfo,
     1556                    elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
     1557                    FALSE,
     1558                    TRUE,
     1559                    &elem->tdesc,
     1560                    xargs,
     1561                    &buf
     1562                );
     1563                if (hres == S_OK)
     1564                    isdeserialized = TRUE;
     1565            }
     1566        }
     1567        if (!isdeserialized)
     1568            hres = deserialize_param(
     1569                This->tinfo,
     1570                elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN,
     1571                FALSE,
     1572                TRUE,
     1573                &(elem->tdesc),
     1574                xargs,
     1575                &buf
     1576            );
    11121577        xargs += _argsize(elem->tdesc.vt);
    11131578        if (hres) {
    1114             FIXME("Failed to stuballoc param %s, hres %lx\n",debugstr_w(names[i+1]),hres);
     1579            FIXME("Failed to deserialize param %s, hres %lx\n",debugstr_w(names[i+1]),hres);
    11151580            break;
    11161581        }
     
    11321597    for (i=0;i<fdesc->cParams;i++) {
    11331598        ELEMDESC        *elem = fdesc->lprgelemdescParam+i;
    1134         hres = stubunalloc_param(This->tinfo,elem,NULL,xargs,&buf);
     1599        BOOL            isserialized = FALSE;
     1600
     1601        if (((i+1)<nrofnames) && !IsBadStringPtrW(names[i+1],1)) {
     1602            /* If the parameter is 'riid', we use it as interface IID
     1603             * for a later ppvObject serialization.
     1604             */
     1605            buf.thisisiid = !lstrcmpW(names[i+1],riidW);
     1606
     1607            /* DISPPARAMS* needs special serializer */
     1608            if (!lstrcmpW(names[i+1],pdispparamsW)) {
     1609                hres = serialize_DISPPARAM_ptr(
     1610                    This->tinfo,
     1611                    elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
     1612                    FALSE,
     1613                    TRUE,
     1614                    &elem->tdesc,
     1615                    xargs,
     1616                    &buf
     1617                );
     1618                isserialized = TRUE;
     1619            }
     1620            if (!lstrcmpW(names[i+1],ppvObjectW)) {
     1621                hres = serialize_LPVOID_ptr(
     1622                    This->tinfo,
     1623                    elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
     1624                    FALSE,
     1625                    TRUE,
     1626                    &elem->tdesc,
     1627                    xargs,
     1628                    &buf
     1629                );
     1630                if (hres == S_OK)
     1631                    isserialized = TRUE;
     1632            }
     1633        }
     1634        if (!isserialized)
     1635            hres = serialize_param(
     1636               This->tinfo,
     1637               elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT,
     1638               FALSE,
     1639               TRUE,
     1640               &elem->tdesc,
     1641               xargs,
     1642               &buf
     1643            );
    11351644        xargs += _argsize(elem->tdesc.vt);
    11361645        if (hres) {
Note: See TracChangeset for help on using the changeset viewer.