[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