ole32: Generate OXID_INFO in the stub manager.
Copy the OXID_INFO from the stub manager, if available, in proxy_manager_construct. Otherwise, attempt to resolve it. Use ipidRemUnknown from OXID_INFO in the proxy manager instead of magically generating the IPID for RemUnknown.
This commit is contained in:
parent
1fa24db9fd
commit
d1ec56c871
|
@ -93,6 +93,7 @@ struct stub_manager
|
|||
OID oid; /* apartment-scoped unique identifier (RO) */
|
||||
IUnknown *object; /* the object we are managing the stub for (RO) */
|
||||
ULONG next_ipid; /* currently unused (LOCK) */
|
||||
OXID_INFO oxid_info; /* string binding, ipid of rem unknown and other information (RO) */
|
||||
|
||||
/* We need to keep a count of the outstanding marshals, so we can enforce the
|
||||
* marshalling rules (ie, you can only unmarshal normal marshals once). Note
|
||||
|
@ -125,6 +126,7 @@ struct proxy_manager
|
|||
struct apartment *parent; /* owning apartment (RO) */
|
||||
struct list entry; /* entry in apartment (CS parent->cs) */
|
||||
OXID oxid; /* object exported ID (RO) */
|
||||
OXID_INFO oxid_info; /* string binding, ipid of rem unknown and other information (RO) */
|
||||
OID oid; /* object ID (RO) */
|
||||
struct list interfaces; /* imported interfaces (CS cs) */
|
||||
LONG refs; /* proxy reference count (LOCK) */
|
||||
|
@ -227,6 +229,7 @@ void RPC_StopLocalServer(void *registration);
|
|||
HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
|
||||
HRESULT RPC_RegisterChannelHook(REFGUID rguid, IChannelHook *hook);
|
||||
void RPC_UnregisterAllChannelHooks(void);
|
||||
HRESULT RPC_ResolveOxid(OXID oxid, OXID_INFO *oxid_info);
|
||||
|
||||
/* This function initialize the Running Object Table */
|
||||
HRESULT WINAPI RunningObjectTableImpl_Initialize(void);
|
||||
|
|
|
@ -51,7 +51,8 @@ extern const CLSID CLSID_DfMarshal;
|
|||
|
||||
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
|
||||
MSHCTX dest_context, void *dest_context_data,
|
||||
REFIID riid, void **object);
|
||||
REFIID riid, const OXID_INFO *oxid_info,
|
||||
void **object);
|
||||
|
||||
/* Marshalling just passes a unique identifier to the remote client,
|
||||
* that makes it possible to find the passed interface again.
|
||||
|
@ -299,7 +300,7 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
|
|||
hrobj = unmarshal_object(&qiresults[i].std, This->parent,
|
||||
This->dest_context,
|
||||
This->dest_context_data,
|
||||
pMQIs[index].pIID,
|
||||
pMQIs[index].pIID, &This->oxid_info,
|
||||
(void **)&pMQIs[index].pItf);
|
||||
|
||||
if (hrobj == S_OK)
|
||||
|
@ -651,7 +652,7 @@ static void ifproxy_destroy(struct ifproxy * This)
|
|||
|
||||
static HRESULT proxy_manager_construct(
|
||||
APARTMENT * apt, ULONG sorflags, OXID oxid, OID oid,
|
||||
struct proxy_manager ** proxy_manager)
|
||||
const OXID_INFO *oxid_info, struct proxy_manager ** proxy_manager)
|
||||
{
|
||||
struct proxy_manager * This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
|
||||
if (!This) return E_OUTOFMEMORY;
|
||||
|
@ -663,6 +664,25 @@ static HRESULT proxy_manager_construct(
|
|||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
if (oxid_info)
|
||||
{
|
||||
This->oxid_info.dwPid = oxid_info->dwPid;
|
||||
This->oxid_info.dwTid = oxid_info->dwTid;
|
||||
This->oxid_info.ipidRemUnknown = oxid_info->ipidRemUnknown;
|
||||
This->oxid_info.dwAuthnHint = oxid_info->dwAuthnHint;
|
||||
This->oxid_info.psa = NULL /* FIXME: copy from oxid_info */;
|
||||
}
|
||||
else
|
||||
{
|
||||
HRESULT hr = RPC_ResolveOxid(oxid, &This->oxid_info);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
CloseHandle(This->remoting_mutex);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
This->lpVtbl = &ClientIdentity_Vtbl;
|
||||
This->lpVtblMarshal = &ProxyMarshal_Vtbl;
|
||||
This->lpVtblCliSec = &ProxyCliSec_Vtbl;
|
||||
|
@ -951,19 +971,12 @@ static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnk
|
|||
stdobjref.oxid = This->oxid;
|
||||
/* FIXME: what should be used for the oid? The DCOM draft doesn't say */
|
||||
stdobjref.oid = (OID)-1;
|
||||
/* FIXME: this is a hack around not having an OXID resolver yet -
|
||||
* the OXID resolver should give us the IPID of the IRemUnknown
|
||||
* interface */
|
||||
stdobjref.ipid.Data1 = 0xffffffff;
|
||||
stdobjref.ipid.Data2 = 0xffff;
|
||||
stdobjref.ipid.Data3 = 0xffff;
|
||||
assert(sizeof(stdobjref.ipid.Data4) == sizeof(stdobjref.oxid));
|
||||
memcpy(&stdobjref.ipid.Data4, &stdobjref.oxid, sizeof(OXID));
|
||||
|
||||
stdobjref.ipid = This->oxid_info.ipidRemUnknown;
|
||||
|
||||
/* do the unmarshal */
|
||||
hr = unmarshal_object(&stdobjref, This->parent, This->dest_context,
|
||||
This->dest_context_data, &IID_IRemUnknown,
|
||||
(void**)&This->remunk);
|
||||
&This->oxid_info, (void**)&This->remunk);
|
||||
if (hr == S_OK)
|
||||
*remunk = This->remunk;
|
||||
}
|
||||
|
@ -1010,6 +1023,7 @@ static void proxy_manager_destroy(struct proxy_manager * This)
|
|||
}
|
||||
|
||||
if (This->remunk) IRemUnknown_Release(This->remunk);
|
||||
CoTaskMemFree(This->oxid_info.psa);
|
||||
|
||||
DEBUG_CLEAR_CRITSEC_NAME(&This->cs);
|
||||
DeleteCriticalSection(&This->cs);
|
||||
|
@ -1156,7 +1170,8 @@ StdMarshalImpl_MarshalInterface(
|
|||
* and table marshaling */
|
||||
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
|
||||
MSHCTX dest_context, void *dest_context_data,
|
||||
REFIID riid, void **object)
|
||||
REFIID riid, const OXID_INFO *oxid_info,
|
||||
void **object)
|
||||
{
|
||||
struct proxy_manager *proxy_manager = NULL;
|
||||
HRESULT hr = S_OK;
|
||||
|
@ -1174,7 +1189,7 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
|
|||
if (!find_proxy_manager(apt, stdobjref->oxid, stdobjref->oid, &proxy_manager))
|
||||
{
|
||||
hr = proxy_manager_construct(apt, stdobjref->flags,
|
||||
stdobjref->oxid, stdobjref->oid,
|
||||
stdobjref->oxid, stdobjref->oid, oxid_info,
|
||||
&proxy_manager);
|
||||
}
|
||||
else
|
||||
|
@ -1225,7 +1240,7 @@ static HRESULT WINAPI
|
|||
StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
|
||||
{
|
||||
StdMarshalImpl *This = (StdMarshalImpl *)iface;
|
||||
struct stub_manager *stubmgr;
|
||||
struct stub_manager *stubmgr = NULL;
|
||||
STDOBJREF stdobjref;
|
||||
ULONG res;
|
||||
HRESULT hres;
|
||||
|
@ -1276,8 +1291,6 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
|
|||
{
|
||||
if (!stub_manager_notify_unmarshal(stubmgr, &stdobjref.ipid))
|
||||
hres = CO_E_OBJNOTCONNECTED;
|
||||
|
||||
stub_manager_int_release(stubmgr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1286,8 +1299,6 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
|
|||
wine_dbgstr_longlong(stdobjref.oid));
|
||||
hres = CO_E_OBJNOTCONNECTED;
|
||||
}
|
||||
|
||||
apartment_release(stub_apt);
|
||||
}
|
||||
else
|
||||
TRACE("Treating unmarshal from OXID %s as inter-process\n",
|
||||
|
@ -1295,7 +1306,11 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
|
|||
|
||||
if (hres == S_OK)
|
||||
hres = unmarshal_object(&stdobjref, apt, This->dwDestContext,
|
||||
This->pvDestContext, riid, ppv);
|
||||
This->pvDestContext, riid,
|
||||
stubmgr ? &stubmgr->oxid_info : NULL, ppv);
|
||||
|
||||
if (stubmgr) stub_manager_int_release(stubmgr);
|
||||
if (stub_apt) apartment_release(stub_apt);
|
||||
|
||||
if (hres) WARN("Failed with error 0x%08x\n", hres);
|
||||
else TRACE("Successfully created proxy %p\n", *ppv);
|
||||
|
|
|
@ -1488,6 +1488,23 @@ void RPC_UnregisterInterface(REFIID riid)
|
|||
LeaveCriticalSection(&csRegIf);
|
||||
}
|
||||
|
||||
HRESULT RPC_ResolveOxid(OXID oxid, OXID_INFO *oxid_info)
|
||||
{
|
||||
oxid_info->dwTid = 0;
|
||||
oxid_info->dwPid = 0;
|
||||
oxid_info->dwAuthnHint = RPC_C_AUTHN_LEVEL_NONE;
|
||||
/* FIXME: this is a hack around not having an OXID resolver yet -
|
||||
* this function should contact the machine's OXID resolver and then it
|
||||
* should give us the IPID of the IRemUnknown interface */
|
||||
oxid_info->ipidRemUnknown.Data1 = 0xffffffff;
|
||||
oxid_info->ipidRemUnknown.Data2 = 0xffff;
|
||||
oxid_info->ipidRemUnknown.Data3 = 0xffff;
|
||||
memcpy(&oxid_info->ipidRemUnknown.Data4, &oxid, sizeof(OXID));
|
||||
oxid_info->psa = NULL /* FIXME */;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* make the apartment reachable by other threads and processes and create the
|
||||
* IRemUnknown object */
|
||||
void RPC_StartRemoting(struct apartment *apt)
|
||||
|
|
|
@ -70,6 +70,23 @@ struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object)
|
|||
* and the caller will also hold a reference */
|
||||
sm->refs = 2;
|
||||
|
||||
sm->oxid_info.dwPid = GetCurrentProcessId();
|
||||
sm->oxid_info.dwTid = GetCurrentThreadId();
|
||||
/*
|
||||
* FIXME: this is a hack for marshalling IRemUnknown. In real
|
||||
* DCOM, the IPID of the IRemUnknown interface is generated like
|
||||
* any other and passed to the OXID resolver which then returns it
|
||||
* when queried. We don't have an OXID resolver yet so instead we
|
||||
* use a magic IPID reserved for IRemUnknown.
|
||||
*/
|
||||
sm->oxid_info.ipidRemUnknown.Data1 = 0xffffffff;
|
||||
sm->oxid_info.ipidRemUnknown.Data2 = 0xffff;
|
||||
sm->oxid_info.ipidRemUnknown.Data3 = 0xffff;
|
||||
assert(sizeof(sm->oxid_info.ipidRemUnknown.Data4) == sizeof(apt->oxid));
|
||||
memcpy(&sm->oxid_info.ipidRemUnknown.Data4, &apt->oxid, sizeof(OXID));
|
||||
sm->oxid_info.dwAuthnHint = RPC_C_AUTHN_LEVEL_NONE;
|
||||
sm->oxid_info.psa = NULL /* FIXME */;
|
||||
|
||||
/* yes, that's right, this starts at zero. that's zero EXTERNAL
|
||||
* refs, ie nobody has unmarshalled anything yet. we can't have
|
||||
* negative refs because the stub manager cannot be explicitly
|
||||
|
@ -102,6 +119,7 @@ static void stub_manager_delete(struct stub_manager *m)
|
|||
stub_manager_delete_ifstub(m, ifstub);
|
||||
}
|
||||
|
||||
CoTaskMemFree(m->oxid_info.psa);
|
||||
IUnknown_Release(m->object);
|
||||
|
||||
DEBUG_CLEAR_CRITSEC_NAME(&m->lock);
|
||||
|
@ -451,21 +469,10 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
|
|||
stub->flags = flags;
|
||||
stub->iid = *iid;
|
||||
|
||||
/*
|
||||
* FIXME: this is a hack for marshalling IRemUnknown. In real
|
||||
* DCOM, the IPID of the IRemUnknown interface is generated like
|
||||
* any other and passed to the OXID resolver which then returns it
|
||||
* when queried. We don't have an OXID resolver yet so instead we
|
||||
* use a magic IPID reserved for IRemUnknown.
|
||||
*/
|
||||
/* FIXME: find a cleaner way of identifying that we are creating an ifstub
|
||||
* for the remunknown interface */
|
||||
if (IsEqualIID(iid, &IID_IRemUnknown))
|
||||
{
|
||||
stub->ipid.Data1 = 0xffffffff;
|
||||
stub->ipid.Data2 = 0xffff;
|
||||
stub->ipid.Data3 = 0xffff;
|
||||
assert(sizeof(stub->ipid.Data4) == sizeof(m->apt->oxid));
|
||||
memcpy(&stub->ipid.Data4, &m->apt->oxid, sizeof(OXID));
|
||||
}
|
||||
stub->ipid = m->oxid_info.ipidRemUnknown;
|
||||
else
|
||||
generate_ipid(m, &stub->ipid);
|
||||
|
||||
|
|
Loading…
Reference in New Issue