Commit d1ec56c8 authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

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.
parent 1fa24db9
...@@ -93,6 +93,7 @@ struct stub_manager ...@@ -93,6 +93,7 @@ struct stub_manager
OID oid; /* apartment-scoped unique identifier (RO) */ OID oid; /* apartment-scoped unique identifier (RO) */
IUnknown *object; /* the object we are managing the stub for (RO) */ IUnknown *object; /* the object we are managing the stub for (RO) */
ULONG next_ipid; /* currently unused (LOCK) */ 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 /* 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 * marshalling rules (ie, you can only unmarshal normal marshals once). Note
...@@ -125,6 +126,7 @@ struct proxy_manager ...@@ -125,6 +126,7 @@ struct proxy_manager
struct apartment *parent; /* owning apartment (RO) */ struct apartment *parent; /* owning apartment (RO) */
struct list entry; /* entry in apartment (CS parent->cs) */ struct list entry; /* entry in apartment (CS parent->cs) */
OXID oxid; /* object exported ID (RO) */ 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) */ OID oid; /* object ID (RO) */
struct list interfaces; /* imported interfaces (CS cs) */ struct list interfaces; /* imported interfaces (CS cs) */
LONG refs; /* proxy reference count (LOCK) */ LONG refs; /* proxy reference count (LOCK) */
...@@ -227,6 +229,7 @@ void RPC_StopLocalServer(void *registration); ...@@ -227,6 +229,7 @@ void RPC_StopLocalServer(void *registration);
HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv); HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
HRESULT RPC_RegisterChannelHook(REFGUID rguid, IChannelHook *hook); HRESULT RPC_RegisterChannelHook(REFGUID rguid, IChannelHook *hook);
void RPC_UnregisterAllChannelHooks(void); void RPC_UnregisterAllChannelHooks(void);
HRESULT RPC_ResolveOxid(OXID oxid, OXID_INFO *oxid_info);
/* This function initialize the Running Object Table */ /* This function initialize the Running Object Table */
HRESULT WINAPI RunningObjectTableImpl_Initialize(void); HRESULT WINAPI RunningObjectTableImpl_Initialize(void);
......
...@@ -51,7 +51,8 @@ extern const CLSID CLSID_DfMarshal; ...@@ -51,7 +51,8 @@ extern const CLSID CLSID_DfMarshal;
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
MSHCTX dest_context, void *dest_context_data, 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, /* Marshalling just passes a unique identifier to the remote client,
* that makes it possible to find the passed interface again. * that makes it possible to find the passed interface again.
...@@ -299,7 +300,7 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL ...@@ -299,7 +300,7 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
hrobj = unmarshal_object(&qiresults[i].std, This->parent, hrobj = unmarshal_object(&qiresults[i].std, This->parent,
This->dest_context, This->dest_context,
This->dest_context_data, This->dest_context_data,
pMQIs[index].pIID, pMQIs[index].pIID, &This->oxid_info,
(void **)&pMQIs[index].pItf); (void **)&pMQIs[index].pItf);
if (hrobj == S_OK) if (hrobj == S_OK)
...@@ -651,7 +652,7 @@ static void ifproxy_destroy(struct ifproxy * This) ...@@ -651,7 +652,7 @@ static void ifproxy_destroy(struct ifproxy * This)
static HRESULT proxy_manager_construct( static HRESULT proxy_manager_construct(
APARTMENT * apt, ULONG sorflags, OXID oxid, OID oid, 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)); struct proxy_manager * This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
if (!This) return E_OUTOFMEMORY; if (!This) return E_OUTOFMEMORY;
...@@ -663,6 +664,25 @@ static HRESULT proxy_manager_construct( ...@@ -663,6 +664,25 @@ static HRESULT proxy_manager_construct(
return HRESULT_FROM_WIN32(GetLastError()); 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->lpVtbl = &ClientIdentity_Vtbl;
This->lpVtblMarshal = &ProxyMarshal_Vtbl; This->lpVtblMarshal = &ProxyMarshal_Vtbl;
This->lpVtblCliSec = &ProxyCliSec_Vtbl; This->lpVtblCliSec = &ProxyCliSec_Vtbl;
...@@ -951,19 +971,12 @@ static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnk ...@@ -951,19 +971,12 @@ static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnk
stdobjref.oxid = This->oxid; stdobjref.oxid = This->oxid;
/* FIXME: what should be used for the oid? The DCOM draft doesn't say */ /* FIXME: what should be used for the oid? The DCOM draft doesn't say */
stdobjref.oid = (OID)-1; stdobjref.oid = (OID)-1;
/* FIXME: this is a hack around not having an OXID resolver yet - stdobjref.ipid = This->oxid_info.ipidRemUnknown;
* 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));
/* do the unmarshal */ /* do the unmarshal */
hr = unmarshal_object(&stdobjref, This->parent, This->dest_context, hr = unmarshal_object(&stdobjref, This->parent, This->dest_context,
This->dest_context_data, &IID_IRemUnknown, This->dest_context_data, &IID_IRemUnknown,
(void**)&This->remunk); &This->oxid_info, (void**)&This->remunk);
if (hr == S_OK) if (hr == S_OK)
*remunk = This->remunk; *remunk = This->remunk;
} }
...@@ -1010,6 +1023,7 @@ static void proxy_manager_destroy(struct proxy_manager * This) ...@@ -1010,6 +1023,7 @@ static void proxy_manager_destroy(struct proxy_manager * This)
} }
if (This->remunk) IRemUnknown_Release(This->remunk); if (This->remunk) IRemUnknown_Release(This->remunk);
CoTaskMemFree(This->oxid_info.psa);
DEBUG_CLEAR_CRITSEC_NAME(&This->cs); DEBUG_CLEAR_CRITSEC_NAME(&This->cs);
DeleteCriticalSection(&This->cs); DeleteCriticalSection(&This->cs);
...@@ -1156,7 +1170,8 @@ StdMarshalImpl_MarshalInterface( ...@@ -1156,7 +1170,8 @@ StdMarshalImpl_MarshalInterface(
* and table marshaling */ * and table marshaling */
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
MSHCTX dest_context, void *dest_context_data, 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; struct proxy_manager *proxy_manager = NULL;
HRESULT hr = S_OK; HRESULT hr = S_OK;
...@@ -1174,7 +1189,7 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, ...@@ -1174,7 +1189,7 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
if (!find_proxy_manager(apt, stdobjref->oxid, stdobjref->oid, &proxy_manager)) if (!find_proxy_manager(apt, stdobjref->oxid, stdobjref->oid, &proxy_manager))
{ {
hr = proxy_manager_construct(apt, stdobjref->flags, hr = proxy_manager_construct(apt, stdobjref->flags,
stdobjref->oxid, stdobjref->oid, stdobjref->oxid, stdobjref->oid, oxid_info,
&proxy_manager); &proxy_manager);
} }
else else
...@@ -1225,7 +1240,7 @@ static HRESULT WINAPI ...@@ -1225,7 +1240,7 @@ static HRESULT WINAPI
StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv) StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
{ {
StdMarshalImpl *This = (StdMarshalImpl *)iface; StdMarshalImpl *This = (StdMarshalImpl *)iface;
struct stub_manager *stubmgr; struct stub_manager *stubmgr = NULL;
STDOBJREF stdobjref; STDOBJREF stdobjref;
ULONG res; ULONG res;
HRESULT hres; HRESULT hres;
...@@ -1276,8 +1291,6 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v ...@@ -1276,8 +1291,6 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
{ {
if (!stub_manager_notify_unmarshal(stubmgr, &stdobjref.ipid)) if (!stub_manager_notify_unmarshal(stubmgr, &stdobjref.ipid))
hres = CO_E_OBJNOTCONNECTED; hres = CO_E_OBJNOTCONNECTED;
stub_manager_int_release(stubmgr);
} }
else else
{ {
...@@ -1286,8 +1299,6 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v ...@@ -1286,8 +1299,6 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
wine_dbgstr_longlong(stdobjref.oid)); wine_dbgstr_longlong(stdobjref.oid));
hres = CO_E_OBJNOTCONNECTED; hres = CO_E_OBJNOTCONNECTED;
} }
apartment_release(stub_apt);
} }
else else
TRACE("Treating unmarshal from OXID %s as inter-process\n", TRACE("Treating unmarshal from OXID %s as inter-process\n",
...@@ -1295,7 +1306,11 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v ...@@ -1295,7 +1306,11 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
if (hres == S_OK) if (hres == S_OK)
hres = unmarshal_object(&stdobjref, apt, This->dwDestContext, 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); if (hres) WARN("Failed with error 0x%08x\n", hres);
else TRACE("Successfully created proxy %p\n", *ppv); else TRACE("Successfully created proxy %p\n", *ppv);
......
...@@ -1488,6 +1488,23 @@ void RPC_UnregisterInterface(REFIID riid) ...@@ -1488,6 +1488,23 @@ void RPC_UnregisterInterface(REFIID riid)
LeaveCriticalSection(&csRegIf); 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 /* make the apartment reachable by other threads and processes and create the
* IRemUnknown object */ * IRemUnknown object */
void RPC_StartRemoting(struct apartment *apt) void RPC_StartRemoting(struct apartment *apt)
......
...@@ -70,6 +70,23 @@ struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object) ...@@ -70,6 +70,23 @@ struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object)
* and the caller will also hold a reference */ * and the caller will also hold a reference */
sm->refs = 2; 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 /* yes, that's right, this starts at zero. that's zero EXTERNAL
* refs, ie nobody has unmarshalled anything yet. we can't have * refs, ie nobody has unmarshalled anything yet. we can't have
* negative refs because the stub manager cannot be explicitly * negative refs because the stub manager cannot be explicitly
...@@ -102,6 +119,7 @@ static void stub_manager_delete(struct stub_manager *m) ...@@ -102,6 +119,7 @@ static void stub_manager_delete(struct stub_manager *m)
stub_manager_delete_ifstub(m, ifstub); stub_manager_delete_ifstub(m, ifstub);
} }
CoTaskMemFree(m->oxid_info.psa);
IUnknown_Release(m->object); IUnknown_Release(m->object);
DEBUG_CLEAR_CRITSEC_NAME(&m->lock); DEBUG_CLEAR_CRITSEC_NAME(&m->lock);
...@@ -451,21 +469,10 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s ...@@ -451,21 +469,10 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
stub->flags = flags; stub->flags = flags;
stub->iid = *iid; stub->iid = *iid;
/* /* FIXME: find a cleaner way of identifying that we are creating an ifstub
* FIXME: this is a hack for marshalling IRemUnknown. In real * for the remunknown interface */
* 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.
*/
if (IsEqualIID(iid, &IID_IRemUnknown)) if (IsEqualIID(iid, &IID_IRemUnknown))
{ stub->ipid = m->oxid_info.ipidRemUnknown;
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));
}
else else
generate_ipid(m, &stub->ipid); generate_ipid(m, &stub->ipid);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment