- 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 */ /* Standard Marshalling definitions */
typedef struct _wine_marshal_id { typedef struct _wine_marshal_id {
DWORD processid; OXID oxid;
DWORD objectid; /* unique value corresp. IUnknown of object */ OID oid; /* unique value corresp. IUnknown of object */
IID iid; IID iid;
} wine_marshal_id; } wine_marshal_id;
inline static BOOL inline static BOOL
MARSHAL_Compare_Mids(wine_marshal_id *mid1,wine_marshal_id *mid2) { MARSHAL_Compare_Mids(wine_marshal_id *mid1,wine_marshal_id *mid2) {
return return
(mid1->processid == mid2->processid) && (mid1->oxid == mid2->oxid) &&
(mid1->objectid == mid2->objectid) && (mid1->oid == mid2->oid) &&
IsEqualIID(&(mid1->iid),&(mid2->iid)) IsEqualIID(&(mid1->iid),&(mid2->iid))
; ;
} }
@ -141,8 +141,8 @@ MARSHAL_Compare_Mids(wine_marshal_id *mid1,wine_marshal_id *mid2) {
inline static BOOL inline static BOOL
MARSHAL_Compare_Mids_NoInterface(wine_marshal_id *mid1, wine_marshal_id *mid2) { MARSHAL_Compare_Mids_NoInterface(wine_marshal_id *mid1, wine_marshal_id *mid2) {
return return
(mid1->processid == mid2->processid) && (mid1->oxid == mid2->oxid) &&
(mid1->objectid == mid2->objectid) (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))) { if (MARSHAL_Compare_Mids(mid,&(stubs[i].mid))) {
stubs[i].valid = FALSE; stubs[i].valid = FALSE;
IUnknown_Release(stubs[i].pUnkServer);
return; return;
} }
} }
@ -144,7 +145,7 @@ static HRESULT
MARSHAL_Register_Stub(wine_marshal_id *mid,LPUNKNOWN pUnk,IRpcStubBuffer *stub) { MARSHAL_Register_Stub(wine_marshal_id *mid,LPUNKNOWN pUnk,IRpcStubBuffer *stub) {
LPUNKNOWN xPunk; LPUNKNOWN xPunk;
if (!MARSHAL_Find_Stub(mid,&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; return S_OK;
} }
if (nrofstubs) if (nrofstubs)
@ -265,8 +266,8 @@ StdMarshalImpl_MarshalInterface(
TRACE("(...,%s,...)\n",debugstr_guid(riid)); TRACE("(...,%s,...)\n",debugstr_guid(riid));
IUnknown_QueryInterface((LPUNKNOWN)pv,&IID_IUnknown,(LPVOID*)&pUnk); IUnknown_QueryInterface((LPUNKNOWN)pv,&IID_IUnknown,(LPVOID*)&pUnk);
mid.processid = GetCurrentProcessId(); mid.oxid = COM_CurrentApt()->oxid;
mid.objectid = (DWORD)pUnk; /* FIXME */ mid.oid = (DWORD)pUnk; /* FIXME */
IUnknown_Release(pUnk); IUnknown_Release(pUnk);
memcpy(&mid.iid,riid,sizeof(mid.iid)); memcpy(&mid.iid,riid,sizeof(mid.iid));
md.dwDestContext = dwDestContext; md.dwDestContext = dwDestContext;
@ -307,16 +308,31 @@ StdMarshalImpl_UnmarshalInterface(
IPSFactoryBuffer *psfacbuf; IPSFactoryBuffer *psfacbuf;
IRpcProxyBuffer *rpcproxy; IRpcProxyBuffer *rpcproxy;
IRpcChannelBuffer *chanbuf; IRpcChannelBuffer *chanbuf;
int i;
TRACE("(...,%s,....)\n",debugstr_guid(riid)); TRACE("(...,%s,....)\n",debugstr_guid(riid));
hres = IStream_Read(pStm,&mid,sizeof(mid),&res); hres = IStream_Read(pStm,&mid,sizeof(mid),&res);
if (hres) return hres; if (hres) return hres;
hres = IStream_Read(pStm,&md,sizeof(md),&res); hres = IStream_Read(pStm,&md,sizeof(md),&res);
if (hres) return hres; if (hres) return hres;
if (SUCCEEDED(MARSHAL_Find_Stub(&mid,(LPUNKNOWN*)ppv))) { for (i=0; i < nrofstubs; i++)
FIXME("Calling back to ourselves for %s!\n",debugstr_guid(riid)); {
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; return S_OK;
} }
}
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_NULL)) { if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_NULL)) {
/* should return proxy manager IUnknown object */ /* should return proxy manager IUnknown object */
FIXME("Special treatment required for IID of %s\n", debugstr_guid(riid)); FIXME("Special treatment required for IID of %s\n", debugstr_guid(riid));
@ -354,7 +370,6 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
wine_marshal_id mid; wine_marshal_id mid;
ULONG res; ULONG res;
HRESULT hres; HRESULT hres;
IRpcStubBuffer *stub = NULL;
int i; int i;
hres = IStream_Read(pStm,&mid,sizeof(mid),&res); hres = IStream_Read(pStm,&mid,sizeof(mid),&res);
@ -366,23 +381,19 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
if (MARSHAL_Compare_Mids(&mid, &(stubs[i].mid))) if (MARSHAL_Compare_Mids(&mid, &(stubs[i].mid)))
{ {
IRpcStubBuffer *stub = NULL;
stub = stubs[i].stub; stub = stubs[i].stub;
break;
}
}
if (!stub)
{
FIXME("Could not map MID to stub??\n");
return E_FAIL;
}
res = IRpcStubBuffer_Release(stub); res = IRpcStubBuffer_Release(stub);
stubs[i].valid = FALSE; stubs[i].valid = FALSE;
TRACE("stub refcount of %p is %ld\n", stub, res); TRACE("stub refcount of %p is %ld\n", stub, res);
return S_OK; return S_OK;
} }
}
FIXME("Could not map MID to stub??\n");
return E_FAIL;
}
static HRESULT WINAPI static HRESULT WINAPI
StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved) { StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved) {
@ -504,9 +515,9 @@ CoMarshalInterface( IStream *pStm, REFIID riid, IUnknown *pUnk,
start_listener_thread(); /* Just to be sure we have one running. */ 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); IUnknown_QueryInterface(pUnk,&IID_IUnknown,(LPVOID*)&pUnknown);
mid.objectid = (DWORD)pUnknown; mid.oid = (DWORD)pUnknown;
IUnknown_Release(pUnknown); IUnknown_Release(pUnknown);
memcpy(&mid.iid,riid,sizeof(mid.iid)); memcpy(&mid.iid,riid,sizeof(mid.iid));
md.dwDestContext = dwDestContext; md.dwDestContext = dwDestContext;

View File

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