- Add a new flag SORFP_NOLIFETIMEMGMT to tell the proxy manager not to
call any IRemUnknown functions. - Move the low-level unmarshaling code into a new function, unmarshal_object, so that it can be easily reused for unmarshaling IRemUnknown.
This commit is contained in:
parent
cb4652a71c
commit
6b89a92215
|
@ -109,6 +109,7 @@ struct proxy_manager
|
|||
struct list interfaces; /* imported interfaces (CS cs) */
|
||||
DWORD refs; /* proxy reference count (LOCK) */
|
||||
CRITICAL_SECTION cs; /* thread safety for this object and children */
|
||||
ULONG sorflags; /* STDOBJREF flags (RO) */
|
||||
};
|
||||
|
||||
/* this needs to become a COM object that implements IRemUnknown */
|
||||
|
|
|
@ -52,6 +52,10 @@ extern const CLSID CLSID_DfMarshal;
|
|||
/* number of refs given out for normal marshaling */
|
||||
#define NORMALEXTREFS 1 /* FIXME: this should be 5, but we have to wait for IRemUnknown support first */
|
||||
|
||||
/* private flag indicating that the caller does not want to notify the stub
|
||||
* when the proxy disconnects or is destroyed */
|
||||
#define SORFP_NOLIFETIMEMGMT SORF_OXRES1
|
||||
|
||||
/* Marshalling just passes a unique identifier to the remote client,
|
||||
* that makes it possible to find the passed interface again.
|
||||
*
|
||||
|
@ -324,7 +328,9 @@ static void ifproxy_destroy(struct ifproxy * This)
|
|||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
static HRESULT proxy_manager_construct(APARTMENT * apt, OXID oxid, OID oid, IRpcChannelBuffer * channel, struct proxy_manager ** proxy_manager)
|
||||
static HRESULT proxy_manager_construct(
|
||||
APARTMENT * apt, ULONG sorflags, OXID oxid, OID oid,
|
||||
IRpcChannelBuffer * channel, struct proxy_manager ** proxy_manager)
|
||||
{
|
||||
struct proxy_manager * This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
|
||||
if (!This) return E_OUTOFMEMORY;
|
||||
|
@ -344,6 +350,7 @@ static HRESULT proxy_manager_construct(APARTMENT * apt, OXID oxid, OID oid, IRpc
|
|||
This->oid = oid;
|
||||
|
||||
This->refs = 1;
|
||||
This->sorflags = sorflags;
|
||||
|
||||
This->chan = channel; /* FIXME: we should take the binding strings and construct the channel in this function */
|
||||
|
||||
|
@ -355,7 +362,9 @@ static HRESULT proxy_manager_construct(APARTMENT * apt, OXID oxid, OID oid, IRpc
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT proxy_manager_create_ifproxy(struct proxy_manager * This, IPID ipid, REFIID riid, ULONG cPublicRefs, struct ifproxy ** iif_out)
|
||||
static HRESULT proxy_manager_create_ifproxy(
|
||||
struct proxy_manager * This, IPID ipid, REFIID riid, ULONG cPublicRefs,
|
||||
struct ifproxy ** iif_out)
|
||||
{
|
||||
HRESULT hr;
|
||||
IPSFactoryBuffer * psfb;
|
||||
|
@ -436,7 +445,8 @@ static void proxy_manager_disconnect(struct proxy_manager * This)
|
|||
{
|
||||
struct list * cursor;
|
||||
|
||||
TRACE("oid = %s\n", wine_dbgstr_longlong(This->oid));
|
||||
TRACE("oxid = %s, oid = %s\n", wine_dbgstr_longlong(This->oxid),
|
||||
wine_dbgstr_longlong(This->oid));
|
||||
|
||||
EnterCriticalSection(&This->cs);
|
||||
|
||||
|
@ -637,6 +647,67 @@ StdMarshalImpl_MarshalInterface(
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with
|
||||
* no questions asked about the rules surrounding same-apartment unmarshals
|
||||
* and table marshaling */
|
||||
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFIID riid, void **object)
|
||||
{
|
||||
struct proxy_manager *proxy_manager = NULL;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
/* create an a new proxy manager if one doesn't already exist for the
|
||||
* object */
|
||||
if (!find_proxy_manager(apt, stdobjref->oxid, stdobjref->oid, &proxy_manager))
|
||||
{
|
||||
IRpcChannelBuffer *chanbuf;
|
||||
wine_marshal_id mid;
|
||||
|
||||
mid.oxid = stdobjref->oxid;
|
||||
mid.oid = stdobjref->oid;
|
||||
mid.ipid = stdobjref->ipid;
|
||||
|
||||
hr = PIPE_GetNewPipeBuf(&mid,&chanbuf);
|
||||
if (hr == S_OK)
|
||||
hr = proxy_manager_construct(apt, stdobjref->flags,
|
||||
stdobjref->oxid, stdobjref->oid,
|
||||
chanbuf, &proxy_manager);
|
||||
}
|
||||
|
||||
if (hr == S_OK)
|
||||
{
|
||||
/* the IUnknown interface is special because it does not have an
|
||||
* ifproxy associated with it. we simply return the controlling
|
||||
* IUnknown of the proxy manager. */
|
||||
if (IsEqualIID(riid, &IID_IUnknown))
|
||||
{
|
||||
ClientIdentity_AddRef((IInternalUnknown*)&proxy_manager->lpVtbl);
|
||||
*object = (LPVOID)(&proxy_manager->lpVtbl);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct ifproxy * ifproxy;
|
||||
hr = proxy_manager_find_ifproxy(proxy_manager, riid, &ifproxy);
|
||||
if (hr == E_NOINTERFACE)
|
||||
hr = proxy_manager_create_ifproxy(proxy_manager, stdobjref->ipid,
|
||||
riid, stdobjref->cPublicRefs,
|
||||
&ifproxy);
|
||||
|
||||
if (hr == S_OK)
|
||||
{
|
||||
/* FIXME: push this AddRef inside proxy_manager_find_ifproxy/create_ifproxy? */
|
||||
ClientIdentity_AddRef((IInternalUnknown*)&proxy_manager->lpVtbl);
|
||||
*object = ifproxy->iface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* release our reference to the proxy manager - the client/apartment
|
||||
* will hold on to the remaining reference for us */
|
||||
if (proxy_manager) ClientIdentity_Release((IInternalUnknown*)&proxy_manager->lpVtbl);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
|
||||
{
|
||||
|
@ -644,18 +715,19 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
|
|||
STDOBJREF stdobjref;
|
||||
ULONG res;
|
||||
HRESULT hres;
|
||||
struct proxy_manager *proxy_manager = NULL;
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
APARTMENT *stub_apt;
|
||||
|
||||
TRACE("(...,%s,....)\n",debugstr_guid(riid));
|
||||
|
||||
/* we need an apartment to unmarshal into */
|
||||
if (!apt)
|
||||
{
|
||||
ERR("Apartment not initialized\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
/* read STDOBJREF from wire */
|
||||
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
|
||||
if (hres) return hres;
|
||||
|
||||
|
@ -703,57 +775,13 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
|
|||
TRACE("Treating unmarshal from OXID %s as inter-process\n",
|
||||
wine_dbgstr_longlong(stdobjref.oxid));
|
||||
|
||||
if (hres) return hres;
|
||||
if (hres == S_OK)
|
||||
hres = unmarshal_object(&stdobjref, apt, riid, ppv);
|
||||
|
||||
if (!find_proxy_manager(apt, stdobjref.oxid, stdobjref.oid, &proxy_manager))
|
||||
{
|
||||
IRpcChannelBuffer *chanbuf;
|
||||
wine_marshal_id mid;
|
||||
if (hres) WARN("Failed with error 0x%08lx\n", hres);
|
||||
else TRACE("Successfully created proxy %p\n", *ppv);
|
||||
|
||||
mid.oxid = stdobjref.oxid;
|
||||
mid.oid = stdobjref.oid;
|
||||
mid.ipid = stdobjref.ipid;
|
||||
|
||||
hres = PIPE_GetNewPipeBuf(&mid,&chanbuf);
|
||||
if (hres == S_OK)
|
||||
hres = proxy_manager_construct(apt, stdobjref.oxid, stdobjref.oid,
|
||||
chanbuf, &proxy_manager);
|
||||
}
|
||||
|
||||
if (hres == S_OK)
|
||||
{
|
||||
/* the IUnknown interface is special because it does not have an
|
||||
* ifproxy associated with it. we simply return the controlling
|
||||
* IUnknown of the proxy manager. */
|
||||
if (IsEqualIID(riid, &IID_IUnknown))
|
||||
{
|
||||
ClientIdentity_AddRef((IInternalUnknown*)&proxy_manager->lpVtbl);
|
||||
*ppv = (LPVOID)(&proxy_manager->lpVtbl);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct ifproxy * ifproxy;
|
||||
hres = proxy_manager_find_ifproxy(proxy_manager, riid, &ifproxy);
|
||||
if (hres == E_NOINTERFACE)
|
||||
hres = proxy_manager_create_ifproxy(proxy_manager, stdobjref.ipid,
|
||||
riid, stdobjref.cPublicRefs,
|
||||
&ifproxy);
|
||||
|
||||
if (hres == S_OK)
|
||||
{
|
||||
/* FIXME: push this AddRef inside proxy_manager_find_ifproxy/create_ifproxy? */
|
||||
ClientIdentity_AddRef((IInternalUnknown*)&proxy_manager->lpVtbl);
|
||||
*ppv = ifproxy->iface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (proxy_manager) ClientIdentity_Release((IInternalUnknown*)&proxy_manager->lpVtbl);
|
||||
|
||||
if (hres) WARN("Failed with error 0x%08lx\n", hres);
|
||||
else TRACE("Successfully created proxy %p\n", *ppv);
|
||||
|
||||
return hres;
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
|
|
Loading…
Reference in New Issue