- Make the wine_marshal_id structure more like the DCOM OBJREF

structure, by replacing the process id field by apartment id (OXID),
  changing the users of the process id field to use the new field and
  renaming the objectid field to oid.
- Fix StdMarshalImpl_UnmarshalInterface to invalidate and release its
  stub when doing a same apartment marshal.
This commit is contained in:
Robert Shearman 2004-12-08 17:49:30 +00:00 committed by Alexandre Julliard
parent 7a6c099921
commit 2c3de6db24
3 changed files with 49 additions and 41 deletions

View File

@ -123,16 +123,16 @@ extern void* StdGlobalInterfaceTableInstance;
/* Standard Marshalling definitions */
typedef struct _wine_marshal_id {
DWORD processid;
DWORD objectid; /* unique value corresp. IUnknown of object */
IID iid;
OXID oxid;
OID oid; /* unique value corresp. IUnknown of object */
IID iid;
} wine_marshal_id;
inline static BOOL
MARSHAL_Compare_Mids(wine_marshal_id *mid1,wine_marshal_id *mid2) {
return
(mid1->processid == mid2->processid) &&
(mid1->objectid == mid2->objectid) &&
(mid1->oxid == mid2->oxid) &&
(mid1->oid == mid2->oid) &&
IsEqualIID(&(mid1->iid),&(mid2->iid))
;
}
@ -141,8 +141,8 @@ MARSHAL_Compare_Mids(wine_marshal_id *mid1,wine_marshal_id *mid2) {
inline static BOOL
MARSHAL_Compare_Mids_NoInterface(wine_marshal_id *mid1, wine_marshal_id *mid2) {
return
(mid1->processid == mid2->processid) &&
(mid1->objectid == mid2->objectid)
(mid1->oxid == mid2->oxid) &&
(mid1->oid == mid2->oid)
;
}

View File

@ -101,6 +101,7 @@ void MARSHAL_Invalidate_Stub_From_MID(wine_marshal_id *mid) {
if (MARSHAL_Compare_Mids(mid,&(stubs[i].mid))) {
stubs[i].valid = FALSE;
IUnknown_Release(stubs[i].pUnkServer);
return;
}
}
@ -144,7 +145,7 @@ static HRESULT
MARSHAL_Register_Stub(wine_marshal_id *mid,LPUNKNOWN pUnk,IRpcStubBuffer *stub) {
LPUNKNOWN xPunk;
if (!MARSHAL_Find_Stub(mid,&xPunk)) {
FIXME("Already have entry for (%lx/%s)!\n",mid->objectid,debugstr_guid(&(mid->iid)));
FIXME("Already have entry for (%s/%s)!\n",wine_dbgstr_longlong(mid->oid),debugstr_guid(&(mid->iid)));
return S_OK;
}
if (nrofstubs)
@ -265,8 +266,8 @@ StdMarshalImpl_MarshalInterface(
TRACE("(...,%s,...)\n",debugstr_guid(riid));
IUnknown_QueryInterface((LPUNKNOWN)pv,&IID_IUnknown,(LPVOID*)&pUnk);
mid.processid = GetCurrentProcessId();
mid.objectid = (DWORD)pUnk; /* FIXME */
mid.oxid = COM_CurrentApt()->oxid;
mid.oid = (DWORD)pUnk; /* FIXME */
IUnknown_Release(pUnk);
memcpy(&mid.iid,riid,sizeof(mid.iid));
md.dwDestContext = dwDestContext;
@ -307,15 +308,30 @@ StdMarshalImpl_UnmarshalInterface(
IPSFactoryBuffer *psfacbuf;
IRpcProxyBuffer *rpcproxy;
IRpcChannelBuffer *chanbuf;
int i;
TRACE("(...,%s,....)\n",debugstr_guid(riid));
hres = IStream_Read(pStm,&mid,sizeof(mid),&res);
if (hres) return hres;
hres = IStream_Read(pStm,&md,sizeof(md),&res);
if (hres) return hres;
if (SUCCEEDED(MARSHAL_Find_Stub(&mid,(LPUNKNOWN*)ppv))) {
FIXME("Calling back to ourselves for %s!\n",debugstr_guid(riid));
return S_OK;
for (i=0; i < nrofstubs; i++)
{
if (!stubs[i].valid) continue;
if (MARSHAL_Compare_Mids(&mid, &(stubs[i].mid)))
{
IRpcStubBuffer *stub = NULL;
stub = stubs[i].stub;
res = IRpcStubBuffer_Release(stub);
TRACE("Same apartment marshal for %s, returning original object\n",
debugstr_guid(riid));
stubs[i].valid = FALSE;
IUnknown_QueryInterface(stubs[i].pUnkServer, riid, ppv);
IUnknown_Release(stubs[i].pUnkServer); /* no longer need our reference */
return S_OK;
}
}
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_NULL)) {
/* should return proxy manager IUnknown object */
@ -354,7 +370,6 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
wine_marshal_id mid;
ULONG res;
HRESULT hres;
IRpcStubBuffer *stub = NULL;
int i;
hres = IStream_Read(pStm,&mid,sizeof(mid),&res);
@ -366,22 +381,18 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
if (MARSHAL_Compare_Mids(&mid, &(stubs[i].mid)))
{
stub = stubs[i].stub;
break;
IRpcStubBuffer *stub = NULL;
stub = stubs[i].stub;
res = IRpcStubBuffer_Release(stub);
stubs[i].valid = FALSE;
TRACE("stub refcount of %p is %ld\n", stub, res);
return S_OK;
}
}
if (!stub)
{
FIXME("Could not map MID to stub??\n");
return E_FAIL;
}
res = IRpcStubBuffer_Release(stub);
stubs[i].valid = FALSE;
TRACE("stub refcount of %p is %ld\n", stub, res);
return S_OK;
FIXME("Could not map MID to stub??\n");
return E_FAIL;
}
static HRESULT WINAPI
@ -504,9 +515,9 @@ CoMarshalInterface( IStream *pStm, REFIID riid, IUnknown *pUnk,
start_listener_thread(); /* Just to be sure we have one running. */
mid.processid = GetCurrentProcessId();
mid.oxid = COM_CurrentApt()->oxid;
IUnknown_QueryInterface(pUnk,&IID_IUnknown,(LPVOID*)&pUnknown);
mid.objectid = (DWORD)pUnknown;
mid.oid = (DWORD)pUnknown;
IUnknown_Release(pUnknown);
memcpy(&mid.iid,riid,sizeof(mid.iid));
md.dwDestContext = dwDestContext;

View File

@ -181,7 +181,7 @@ PIPE_RegisterPipe(wine_marshal_id *mid, HANDLE hPipe, BOOL startreader) {
wine_pipe *new_pipes;
for (i=0;i<nrofpipes;i++)
if (pipes[i].mid.processid==mid->processid)
if (pipes[i].mid.oxid==mid->oxid)
return S_OK;
if (pipes)
new_pipes=(wine_pipe*)HeapReAlloc(GetProcessHeap(),0,pipes,sizeof(pipes[0])*(nrofpipes+1));
@ -189,7 +189,7 @@ PIPE_RegisterPipe(wine_marshal_id *mid, HANDLE hPipe, BOOL startreader) {
new_pipes=(wine_pipe*)HeapAlloc(GetProcessHeap(),0,sizeof(pipes[0]));
if (!new_pipes) return E_OUTOFMEMORY;
pipes = new_pipes;
sprintf(pipefn,OLESTUBMGR"_%08lx",mid->processid);
sprintf(pipefn,OLESTUBMGR"_%08lx%08lx",(DWORD)(mid->oxid >> 32),(DWORD)mid->oxid);
memcpy(&(pipes[nrofpipes].mid),mid,sizeof(*mid));
pipes[nrofpipes].hPipe = hPipe;
InitializeCriticalSection(&(pipes[nrofpipes].crit));
@ -206,7 +206,7 @@ static HANDLE
PIPE_FindByMID(wine_marshal_id *mid) {
int i;
for (i=0;i<nrofpipes;i++)
if ((pipes[i].mid.processid==mid->processid) &&
if ((pipes[i].mid.oxid==mid->oxid) &&
(GetCurrentThreadId()==pipes[i].tid)
)
return pipes[i].hPipe;
@ -217,7 +217,7 @@ static wine_pipe*
PIPE_GetFromMID(wine_marshal_id *mid) {
int i;
for (i=0;i<nrofpipes;i++) {
if ((pipes[i].mid.processid==mid->processid) &&
if ((pipes[i].mid.oxid==mid->oxid) &&
(GetCurrentThreadId()==pipes[i].tid)
)
return pipes+i;
@ -378,10 +378,6 @@ RPC_QueueRequestAndWait(wine_rpc_request *req) {
FIXME("no pipe found.\n");
return E_POINTER;
}
if (GetCurrentProcessId() == req->reqh.mid.processid) {
ERR("In current process?\n");
return E_FAIL;
}
req->hPipe = xpipe->hPipe;
req->state = REQSTATE_REQ_WAITING_FOR_REPLY;
reqtype = REQTYPE_REQUEST;
@ -423,7 +419,7 @@ PipeBuf_SendReceive(
TRACE("()\n");
if (This->mid.processid == GetCurrentProcessId()) {
if (This->mid.oxid == COM_CurrentApt()->oxid) {
ERR("Need to call directly!\n");
return E_FAIL;
}
@ -489,7 +485,7 @@ PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf) {
hPipe = PIPE_FindByMID(mid);
if (hPipe == INVALID_HANDLE_VALUE) {
char pipefn[200];
sprintf(pipefn,OLESTUBMGR"_%08lx",mid->processid);
sprintf(pipefn,OLESTUBMGR"_%08lx%08lx",(DWORD)(mid->oxid >> 32),(DWORD)mid->oxid);
hPipe = CreateFileA(
pipefn,
GENERIC_READ|GENERIC_WRITE,
@ -506,7 +502,7 @@ PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf) {
hres = PIPE_RegisterPipe(mid, hPipe, FALSE);
if (hres) return hres;
memset(&ourid,0,sizeof(ourid));
ourid.processid = GetCurrentProcessId();
ourid.oxid = COM_CurrentApt()->oxid;
if (!WriteFile(hPipe,&ourid,sizeof(ourid),&res,NULL)||(res!=sizeof(ourid))) {
ERR("Failed writing startup mid!\n");
return E_FAIL;
@ -673,7 +669,8 @@ COM_RpcReceive(wine_pipe *xpipe) {
hres = MARSHAL_Find_Stub_Buffer(&header.mid, &stub);
if (hres) {
ERR("could not locate stub to disconnect, mid.objectid=%p\n", (void*)header.mid.objectid);
ERR("could not locate stub to disconnect, mid.oid=%s\n",
wine_dbgstr_longlong(header.mid.oid));
goto end;
}