DWORD xsize;
TRACE("...%s...\n",debugstr_guid(riid));
-
+
*pUnk = NULL;
hres = xbuf_get(buf,(LPBYTE)&xsize,sizeof(xsize));
if (hres) {
ERR("xbuf_get failed\n");
return hres;
}
-
+
if (xsize == 0) return S_OK;
-
+
hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
if (hres) {
ERR("Stream create failed %x\n",hres);
return hres;
}
-
+
hres = IStream_Write(pStm,buf->base+buf->curoff,xsize,&res);
if (hres) {
ERR("stream write %x\n",hres);
IStream_Release(pStm);
return hres;
}
-
+
memset(&seekto,0,sizeof(seekto));
hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
if (hres) {
IStream_Release(pStm);
return hres;
}
-
+
hres = CoUnmarshalInterface(pStm,riid,(LPVOID*)pUnk);
if (hres) {
ERR("Unmarshalling interface %s failed with %x\n",debugstr_guid(riid),hres);
IStream_Release(pStm);
return hres;
}
-
+
IStream_Release(pStm);
return xbuf_skip(buf,xsize);
}
hres = E_FAIL;
TRACE("...%s...\n",debugstr_guid(riid));
-
+
hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
if (hres) {
ERR("Stream create failed %x\n",hres);
goto fail;
}
-
+
hres = CoMarshalInterface(pStm,riid,pUnk,0,NULL,0);
if (hres) {
ERR("Marshalling interface %s failed with %x\n", debugstr_guid(riid), hres);
goto fail;
}
-
+
hres = IStream_Stat(pStm,&ststg,STATFLAG_NONAME);
if (hres) {
ERR("Stream stat failed\n");
goto fail;
}
-
+
tempbuf = HeapAlloc(GetProcessHeap(), 0, ststg.cbSize.u.LowPart);
memset(&seekto,0,sizeof(seekto));
hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
ERR("Failed Seek %x\n",hres);
goto fail;
}
-
+
hres = IStream_Read(pStm,tempbuf,ststg.cbSize.u.LowPart,&res);
if (hres) {
ERR("Failed Read %x\n",hres);
goto fail;
}
-
+
xsize = ststg.cbSize.u.LowPart;
xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
hres = xbuf_add(buf,tempbuf,ststg.cbSize.u.LowPart);
-
+
HeapFree(GetProcessHeap(),0,tempbuf);
IStream_Release(pStm);
-
+
return hres;
-
+
fail:
xsize = 0;
xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
#include "pshpack1.h"
typedef struct _TMAsmProxy {
- BYTE popleax;
+ DWORD lealeax;
+ BYTE pushleax;
BYTE pushlval;
DWORD nr;
- BYTE pushleax;
BYTE lcall;
DWORD xcall;
BYTE lret;
WORD bytestopop;
- BYTE nop;
+ WORD nop;
} TMAsmProxy;
#include "poppack.h"
);
return S_OK;
}
- case VT_SAFEARRAY: {
+ case VT_SAFEARRAY: {
if (readit)
{
ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
return (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT || !elem->u.paramdesc.wParamFlags);
}
-static DWORD
-xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
+static DWORD WINAPI xCall(int method, void **args)
{
- DWORD *args = ((DWORD*)&tpinfo)+1, *xargs;
+ TMProxyImpl *tpinfo = args[0];
+ DWORD *xargs;
const FUNCDESC *fdesc;
HRESULT hres;
- int i, relaydeb = TRACE_ON(olerelay);
+ int i;
marshal_state buf;
RPCOLEMESSAGE msg;
ULONG status;
LeaveCriticalSection(&tpinfo->crit);
- if (relaydeb) {
+ if (TRACE_ON(olerelay)) {
TRACE_(olerelay)("->");
if (iname)
TRACE_(olerelay)("%s:",relaystr(iname));
if (nrofnames > sizeof(names)/sizeof(names[0]))
ERR("Need more names!\n");
- xargs = args;
+ xargs = (DWORD *)(args + 1);
for (i=0;i<fdesc->cParams;i++) {
ELEMDESC *elem = fdesc->lprgelemdescParam+i;
- if (relaydeb) {
+ if (TRACE_ON(olerelay)) {
if (i) TRACE_(olerelay)(",");
if (i+1<nrofnames && names[i+1])
TRACE_(olerelay)("%s=",relaystr(names[i+1]));
if (elem->tdesc.vt != VT_PTR)
{
xargs+=_argsize(&elem->tdesc, tinfo);
- if (relaydeb) TRACE_(olerelay)("[out]");
+ TRACE_(olerelay)("[out]");
continue;
}
else
hres = serialize_param(
tinfo,
is_in_elem(elem),
- relaydeb,
+ TRACE_ON(olerelay),
FALSE,
&elem->tdesc,
xargs,
}
xargs+=_argsize(&elem->tdesc, tinfo);
}
- if (relaydeb) TRACE_(olerelay)(")");
+ TRACE_(olerelay)(")");
memset(&msg,0,sizeof(msg));
msg.cbBuffer = buf.curoff;
goto exit;
}
memcpy(msg.Buffer,buf.base,buf.curoff);
- if (relaydeb) TRACE_(olerelay)("\n");
+ TRACE_(olerelay)("\n");
hres = IRpcChannelBuffer_SendReceive(chanbuf,&msg,&status);
if (hres) {
ERR("RpcChannelBuffer SendReceive failed, %x\n",hres);
goto exit;
}
- if (relaydeb) TRACE_(olerelay)(" status = %08x (",status);
+ TRACE_(olerelay)(" status = %08x (",status);
if (buf.base)
buf.base = HeapReAlloc(GetProcessHeap(),0,buf.base,msg.cbBuffer);
else
buf.curoff = 0;
/* generic deserializer using typelib description */
- xargs = args;
+ xargs = (DWORD *)(args + 1);
status = S_OK;
for (i=0;i<fdesc->cParams;i++) {
ELEMDESC *elem = fdesc->lprgelemdescParam+i;
- if (relaydeb) {
- if (i) TRACE_(olerelay)(",");
- if (i+1<nrofnames && names[i+1]) TRACE_(olerelay)("%s=",relaystr(names[i+1]));
- }
+ if (i) TRACE_(olerelay)(",");
+ if (i+1<nrofnames && names[i+1]) TRACE_(olerelay)("%s=",relaystr(names[i+1]));
+
/* No need to marshal other data than FOUT and any VT_PTR */
if (!is_out_elem(elem) && (elem->tdesc.vt != VT_PTR)) {
xargs += _argsize(&elem->tdesc, tinfo);
- if (relaydeb) TRACE_(olerelay)("[in]");
+ TRACE_(olerelay)("[in]");
continue;
}
hres = deserialize_param(
tinfo,
is_out_elem(elem),
- relaydeb,
+ TRACE_ON(olerelay),
FALSE,
&(elem->tdesc),
xargs,
hres = xbuf_get(&buf, (LPBYTE)&remoteresult, sizeof(DWORD));
if (hres != S_OK)
goto exit;
- if (relaydeb) TRACE_(olerelay)(") = %08x\n", remoteresult);
+ TRACE_(olerelay)(") = %08x\n", remoteresult);
hres = remoteresult;
if (ref)
return ref;
- IRpcChannelBuffer_Release(This->pDelegateChannel);
+ IRpcChannelBuffer_Release(This->pDelegateChannel);
HeapFree(GetProcessHeap(), 0, This);
return 0;
}
static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num)
{
int j;
- /* nrofargs without This */
- int nrofargs;
+ /* nrofargs including This */
+ int nrofargs = 1;
ITypeInfo *tinfo2;
TMAsmProxy *xasm = proxy->asmstubs + num;
HRESULT hres;
}
ITypeInfo_Release(tinfo2);
/* some args take more than 4 byte on the stack */
- nrofargs = 0;
for (j=0;j<fdesc->cParams;j++)
nrofargs += _argsize(&fdesc->lprgelemdescParam[j].tdesc, proxy->tinfo);
ERR("calling convention is not stdcall????\n");
return E_FAIL;
}
-/* popl %eax - return ptr
- * pushl <nr>
+/* leal 4(%esp),%eax
* pushl %eax
+ * pushl <nr>
* call xCall
- * lret <nr> (+4)
- *
- *
- * arg3 arg2 arg1 <method> <returnptr>
+ * lret <nr>
*/
- xasm->popleax = 0x58;
+ xasm->lealeax = 0x0424448d;
+ xasm->pushleax = 0x50;
xasm->pushlval = 0x68;
xasm->nr = num;
- xasm->pushleax = 0x50;
- xasm->lcall = 0xe8; /* relative jump */
- xasm->xcall = (DWORD)xCall;
- xasm->xcall -= (DWORD)&(xasm->lret);
+ xasm->lcall = 0xe8;
+ xasm->xcall = (char *)xCall - (char *)&xasm->lret;
xasm->lret = 0xc2;
- xasm->bytestopop = (nrofargs+2)*4; /* pop args, This, iMethod */
- xasm->nop = 0x90;
+ xasm->bytestopop = nrofargs * 4;
+ xasm->nop = 0x9090;
proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm;
#else
FIXME("not implemented on non i386\n");
proxy = CoTaskMemAlloc(sizeof(TMProxyImpl));
if (!proxy) return E_OUTOFMEMORY;
- assert(sizeof(TMAsmProxy) == 16);
-
proxy->dispatch = NULL;
proxy->dispatch_proxy = NULL;
proxy->outerunknown = pUnkOuter;
proxy->lpvtbl[i] = ProxyIUnknown_Release;
break;
case 3:
- if(!defer_to_dispatch)
- {
- hres = init_proxy_entry_point(proxy, i);
- if(FAILED(hres)) return hres;
- }
+ if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
else proxy->lpvtbl[3] = ProxyIDispatch_GetTypeInfoCount;
break;
case 4:
- if(!defer_to_dispatch)
- {
- hres = init_proxy_entry_point(proxy, i);
- if(FAILED(hres)) return hres;
- }
+ if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
else proxy->lpvtbl[4] = ProxyIDispatch_GetTypeInfo;
break;
case 5:
- if(!defer_to_dispatch)
- {
- hres = init_proxy_entry_point(proxy, i);
- if(FAILED(hres)) return hres;
- }
+ if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
else proxy->lpvtbl[5] = ProxyIDispatch_GetIDsOfNames;
break;
case 6:
- if(!defer_to_dispatch)
- {
- hres = init_proxy_entry_point(proxy, i);
- if(FAILED(hres)) return hres;
- }
+ if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
else proxy->lpvtbl[6] = ProxyIDispatch_Invoke;
break;
default:
hres = init_proxy_entry_point(proxy, i);
- if(FAILED(hres)) return hres;
}
}