Rob Shearman : ole32: Fix circular reference count in default handler objects.
Alexandre Julliard
julliard at winehq.org
Tue Nov 24 12:40:24 CST 2009
Module: wine
Branch: master
Commit: 6592c25bc749373cad0e7584ef13e010b4a2431d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6592c25bc749373cad0e7584ef13e010b4a2431d
Author: Rob Shearman <robertshearman at gmail.com>
Date: Tue Nov 24 14:06:57 2009 +0000
ole32: Fix circular reference count in default handler objects.
This is caused by caching a pointer and reference to the data cache's
IPersistStorage interface without managing reference counts
appropriately.
---
dlls/ole32/defaulthandler.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/dlls/ole32/defaulthandler.c b/dlls/ole32/defaulthandler.c
index a3da0dd..5130513 100644
--- a/dlls/ole32/defaulthandler.c
+++ b/dlls/ole32/defaulthandler.c
@@ -1960,9 +1960,21 @@ static DefaultHandler* DefaultHandler_Construct(
&IID_IUnknown,
(void**)&This->dataCache);
if(SUCCEEDED(hr))
+ {
hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
+ /* keeping a reference to This->dataCache_PersistStg causes us to keep a
+ * reference on the outer object */
+ if (SUCCEEDED(hr))
+ IUnknown_Release(This->outerUnknown);
+ else
+ IUnknown_Release(This->dataCache);
+ }
if(FAILED(hr))
+ {
ERR("Unexpected error creating data cache\n");
+ HeapFree(GetProcessHeap(), 0, This);
+ return NULL;
+ }
This->clsid = *clsid;
This->clientSite = NULL;
@@ -2009,6 +2021,13 @@ static DefaultHandler* DefaultHandler_Construct(
static void DefaultHandler_Destroy(
DefaultHandler* This)
{
+ TRACE("(%p)\n", This);
+
+ /* AddRef/Release may be called on this object during destruction.
+ * Prevent the object being destroyed recursively by artificially raising
+ * the reference count. */
+ This->ref = 10000;
+
/* release delegates */
DefaultHandler_Stop(This);
release_delegates(This);
@@ -2020,6 +2039,9 @@ static void DefaultHandler_Destroy(
if (This->dataCache)
{
+ /* to balance out the release of dataCache_PersistStg which will result
+ * in a reference being released from the outer unknown */
+ IUnknown_AddRef(This->outerUnknown);
IPersistStorage_Release(This->dataCache_PersistStg);
IUnknown_Release(This->dataCache);
This->dataCache_PersistStg = NULL;
More information about the wine-cvs
mailing list