[PATCH 4b/13] ole32: Generate OXID_INFO in the stub manager.
Robert Shearman
rob at codeweavers.com
Mon Mar 26 12:23:16 CDT 2007
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.
---
dlls/ole32/compobj_private.h | 3 ++
dlls/ole32/marshal.c | 57
+++++++++++++++++++++++++++---------------
dlls/ole32/rpc.c | 17 +++++++++++++
dlls/ole32/stubmanager.c | 35 +++++++++++++++-----------
4 files changed, 77 insertions(+), 35 deletions(-)
-------------- next part --------------
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index 0d27922..ec51944 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -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 *regist
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);
diff --git a/dlls/ole32/marshal.c b/dlls/ole32/marshal.c
index ded3a6a..0475ba5 100644
--- a/dlls/ole32/marshal.c
+++ b/dlls/ole32/marshal.c
@@ -51,7 +51,8 @@ #define SORFP_NOLIFETIMEMGMT SORF_OXRES1
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_Que
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 ifpro
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_remunkn
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
}
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 ST
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(LPMARS
{
if (!stub_manager_notify_unmarshal(stubmgr, &stdobjref.ipid))
hres = CO_E_OBJNOTCONNECTED;
-
- stub_manager_int_release(stubmgr);
}
else
{
@@ -1286,8 +1299,6 @@ StdMarshalImpl_UnmarshalInterface(LPMARS
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(LPMARS
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);
diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c
index d6b1a66..60bd0d3 100644
--- a/dlls/ole32/rpc.c
+++ b/dlls/ole32/rpc.c
@@ -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)
diff --git a/dlls/ole32/stubmanager.c b/dlls/ole32/stubmanager.c
index 3665443..0fb175d 100644
--- a/dlls/ole32/stubmanager.c
+++ b/dlls/ole32/stubmanager.c
@@ -70,6 +70,23 @@ struct stub_manager *new_stub_manager(AP
* 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 s
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(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);
More information about the wine-patches
mailing list