Jacek Caban : ole32: Use proper IUnknown implementation when finding and creating stub manager.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Aug 31 06:41:59 CDT 2015


Module: wine
Branch: master
Commit: e5edbc6fa00192a8048a3b81c70075537eaa2c97
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e5edbc6fa00192a8048a3b81c70075537eaa2c97

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Aug 28 14:58:55 2015 +0200

ole32: Use proper IUnknown implementation when finding and creating stub manager.

---

 dlls/ole32/compobj.c         | 36 ++++++++++--------------------------
 dlls/ole32/compobj_private.h |  3 +--
 dlls/ole32/marshal.c         | 14 +++-----------
 dlls/ole32/stubmanager.c     | 21 +++++++++++++++++----
 4 files changed, 31 insertions(+), 43 deletions(-)

diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 6a30d7d..23c825a 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -3605,32 +3605,8 @@ HRESULT WINAPI CoLockObjectExternal(
     apt = COM_CurrentApt();
     if (!apt) return CO_E_NOTINITIALIZED;
 
-    stubmgr = get_stub_manager_from_object(apt, pUnk);
-    
-    if (stubmgr)
-    {
-        if (fLock)
-            stub_manager_ext_addref(stubmgr, 1, FALSE);
-        else
-            stub_manager_ext_release(stubmgr, 1, FALSE, fLastUnlockReleases);
-        
-        stub_manager_int_release(stubmgr);
-
-        return S_OK;
-    }
-    else if (fLock)
-    {
-        stubmgr = new_stub_manager(apt, pUnk);
-
-        if (stubmgr)
-        {
-            stub_manager_ext_addref(stubmgr, 1, FALSE);
-            stub_manager_int_release(stubmgr);
-        }
-
-        return S_OK;
-    }
-    else
+    stubmgr = get_stub_manager_from_object(apt, pUnk, fLock);
+    if (!stubmgr)
     {
         WARN("stub object not found %p\n", pUnk);
         /* Note: native is pretty broken here because it just silently
@@ -3638,6 +3614,14 @@ HRESULT WINAPI CoLockObjectExternal(
          * think that the object was disconnected, when it actually wasn't */
         return S_OK;
     }
+
+    if (fLock)
+        stub_manager_ext_addref(stubmgr, 1, FALSE);
+    else
+        stub_manager_ext_release(stubmgr, 1, FALSE, fLastUnlockReleases);
+
+    stub_manager_int_release(stubmgr);
+    return S_OK;
 }
 
 /***********************************************************************
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index 933b71c..f11186c 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -185,14 +185,13 @@ HRESULT FTMarshalCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
 /* Stub Manager */
 
 ULONG stub_manager_int_release(struct stub_manager *This) DECLSPEC_HIDDEN;
-struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object) DECLSPEC_HIDDEN;
 ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak) DECLSPEC_HIDDEN;
 ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases) DECLSPEC_HIDDEN;
 struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid,
      DWORD dest_context, void *dest_context_data, MSHLFLAGS flags) DECLSPEC_HIDDEN;
 struct ifstub *stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags) DECLSPEC_HIDDEN;
 struct stub_manager *get_stub_manager(APARTMENT *apt, OID oid) DECLSPEC_HIDDEN;
-struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object) DECLSPEC_HIDDEN;
+struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, IUnknown *object, BOOL alloc) DECLSPEC_HIDDEN;
 BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid) DECLSPEC_HIDDEN;
 BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid) DECLSPEC_HIDDEN;
 void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid, BOOL tableweak) DECLSPEC_HIDDEN;
diff --git a/dlls/ole32/marshal.c b/dlls/ole32/marshal.c
index 9a640c9..d142b93 100644
--- a/dlls/ole32/marshal.c
+++ b/dlls/ole32/marshal.c
@@ -132,22 +132,14 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
     if (hr != S_OK)
         return hr;
 
+    if (!(manager = get_stub_manager_from_object(apt, object, TRUE)))
+        return E_OUTOFMEMORY;
+
     stdobjref->flags = SORF_NULL;
     if (mshlflags & MSHLFLAGS_TABLEWEAK)
         stdobjref->flags |= SORFP_TABLEWEAK;
     if (mshlflags & MSHLFLAGS_NOPING)
         stdobjref->flags |= SORF_NOPING;
-
-    if ((manager = get_stub_manager_from_object(apt, object)))
-        TRACE("registering new ifstub on pre-existing manager\n");
-    else
-    {
-        TRACE("constructing new stub manager\n");
-
-        manager = new_stub_manager(apt, object);
-        if (!manager)
-            return E_OUTOFMEMORY;
-    }
     stdobjref->oid = manager->oid;
 
     tablemarshal = ((mshlflags & MSHLFLAGS_TABLESTRONG) || (mshlflags & MSHLFLAGS_TABLEWEAK));
diff --git a/dlls/ole32/stubmanager.c b/dlls/ole32/stubmanager.c
index fda4944..1f79ff5 100644
--- a/dlls/ole32/stubmanager.c
+++ b/dlls/ole32/stubmanager.c
@@ -168,7 +168,7 @@ struct ifstub *stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHL
 /* creates a new stub manager and adds it into the apartment. caller must
  * release stub manager when it is no longer required. the apartment and
  * external refs together take one implicit ref */
-struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object)
+static struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object)
 {
     struct stub_manager *sm;
     HRESULT hres;
@@ -298,10 +298,18 @@ ULONG stub_manager_int_release(struct stub_manager *This)
 /* gets the stub manager associated with an object - caller must have
  * a reference to the apartment while a reference to the stub manager is held.
  * it must also call release on the stub manager when it is no longer needed */
-struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object)
+struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, IUnknown *obj, BOOL alloc)
 {
     struct stub_manager *result = NULL;
     struct list         *cursor;
+    IUnknown *object;
+    HRESULT hres;
+
+    hres = IUnknown_QueryInterface(obj, &IID_IUnknown, (void**)&object);
+    if (FAILED(hres)) {
+        ERR("QueryInterface(IID_IUnknown failed): %08x\n", hres);
+        return NULL;
+    }
 
     EnterCriticalSection(&apt->cs);
     LIST_FOR_EACH( cursor, &apt->stubmgrs )
@@ -317,11 +325,16 @@ struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object)
     }
     LeaveCriticalSection(&apt->cs);
 
-    if (result)
+    if (result) {
         TRACE("found %p for object %p\n", result, object);
-    else
+    }else if (alloc) {
+        TRACE("not found, creating new stub manager...\n");
+        result = new_stub_manager(apt, object);
+    }else {
         TRACE("not found for object %p\n", object);
+    }
 
+    IUnknown_Release(object);
     return result;    
 }
 




More information about the wine-cvs mailing list