Commit 6592c25b authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

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.
parent 4b1d527b
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment