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