- 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:
parent
7a6c099921
commit
2c3de6db24
|
@ -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 */
|
||||
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)
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,16 +308,31 @@ 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));
|
||||
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 */
|
||||
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;
|
||||
ULONG res;
|
||||
HRESULT hres;
|
||||
IRpcStubBuffer *stub = NULL;
|
||||
int i;
|
||||
|
||||
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)))
|
||||
{
|
||||
IRpcStubBuffer *stub = NULL;
|
||||
stub = stubs[i].stub;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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. */
|
||||
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue