Rob Shearman : oleaut32:
Free allocated memory on typelib and typeinfo destruction.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Oct 23 10:03:03 CDT 2006
Module: wine
Branch: master
Commit: b3d024a7bb96ed04bfc75c2fec01e70d61af6f5c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b3d024a7bb96ed04bfc75c2fec01e70d61af6f5c
Author: Rob Shearman <rob at codeweavers.com>
Date: Mon Oct 23 11:39:21 2006 +0100
oleaut32: Free allocated memory on typelib and typeinfo destruction.
---
dlls/oleaut32/typelib.c | 109 +++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 100 insertions(+), 9 deletions(-)
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 0863c30..cdf2fe1 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -999,6 +999,7 @@ typedef struct tagITypeInfoImpl
const ITypeInfo2Vtbl *lpVtbl;
const ITypeCompVtbl *lpVtblTypeComp;
LONG ref;
+ BOOL no_free_data; /* don't free data structurees */
TYPEATTR TypeAttr ; /* _lots_ of type information. */
ITypeLibImpl * pTypeLib; /* back pointer to typelib */
int index; /* index in this typelib; */
@@ -3546,6 +3547,9 @@ static ULONG WINAPI ITypeLib2_fnRelease(
if (!ref)
{
+ TLBImpLib *pImpLib, *pImpLibNext;
+ TLBCustData *pCustData, *pCustDataNext;
+
/* remove cache entry */
if(This->path)
{
@@ -3557,7 +3561,6 @@ static ULONG WINAPI ITypeLib2_fnRelease(
LeaveCriticalSection(&cache_section);
HeapFree(GetProcessHeap(), 0, This->path);
}
- /* FIXME destroy child objects */
TRACE(" destroying ITypeLib(%p)\n",This);
if (This->Name)
@@ -3584,6 +3587,25 @@ static ULONG WINAPI ITypeLib2_fnRelease(
This->HelpStringDll = NULL;
}
+ for (pCustData = This->pCustData; pCustData; pCustData = pCustDataNext)
+ {
+ VariantClear(&pCustData->data);
+
+ pCustDataNext = pCustData->next;
+ TLB_Free(pCustData);
+ }
+
+ /* FIXME: free arrays inside elements of This->pTypeDesc */
+ TLB_Free(This->pTypeDesc);
+
+ for (pImpLib = This->pImpLibs; pImpLib; pImpLib = pImpLibNext)
+ {
+ TLB_Free(pImpLib->name);
+
+ pImpLibNext = pImpLib->next;
+ TLB_Free(pImpLib);
+ }
+
if (This->pTypeInfo) /* can be NULL */
ITypeInfo_Release((ITypeInfo*) This->pTypeInfo);
HeapFree(GetProcessHeap(),0,This);
@@ -4367,14 +4389,17 @@ static ULONG WINAPI ITypeInfo_fnRelease(
it means that function is called by ITypeLib2_Release */
ITypeLib2_Release((ITypeLib2*)This->pTypeLib);
} else {
- static int once = 0;
- if (!once)
- {
- once = 1;
- FIXME("destroy child objects\n");
- }
+ TLBFuncDesc *pFInfo, *pFInfoNext;
+ TLBVarDesc *pVInfo, *pVInfoNext;
+ TLBImplType *pImpl, *pImplNext;
+ TLBRefType *pRefType,*pRefTypeNext;
+ TLBCustData *pCustData, *pCustDataNext;
TRACE("destroying ITypeInfo(%p)\n",This);
+
+ if (This->no_free_data)
+ goto finish_free;
+
if (This->Name)
{
SysFreeString(This->Name);
@@ -4393,6 +4418,65 @@ static ULONG WINAPI ITypeInfo_fnRelease(
This->DllName = 0;
}
+ for (pFInfo = This->funclist; pFInfo; pFInfo = pFInfoNext)
+ {
+ UINT i;
+ for(i = 0;i < pFInfo->funcdesc.cParams; i++)
+ {
+ ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[i];
+ if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
+ {
+ VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
+ TLB_Free(elemdesc->u.paramdesc.pparamdescex);
+ }
+ SysFreeString(pFInfo->pParamDesc[i].Name);
+ }
+ TLB_Free(pFInfo->funcdesc.lprgelemdescParam);
+ TLB_Free(pFInfo->pParamDesc);
+ for (pCustData = This->pCustData; pCustData; pCustData = pCustDataNext)
+ {
+ VariantClear(&pCustData->data);
+
+ pCustDataNext = pCustData->next;
+ TLB_Free(pCustData);
+ }
+ SysFreeString(pFInfo->HelpString);
+ SysFreeString(pFInfo->Name);
+
+ pFInfoNext = pFInfo->next;
+ TLB_Free(pFInfo);
+ }
+ for (pVInfo = This->varlist; pVInfo; pVInfo = pVInfoNext)
+ {
+ if (pVInfo->vardesc.varkind == VAR_CONST)
+ {
+ VariantClear(pVInfo->vardesc.u.lpvarValue);
+ TLB_Free(pVInfo->vardesc.u.lpvarValue);
+ }
+ SysFreeString(pVInfo->Name);
+ pVInfoNext = pVInfo->next;
+ TLB_Free(pVInfo);
+ }
+ for(pImpl = This->impltypelist; pImpl; pImpl = pImplNext)
+ {
+ for (pCustData = pImpl->pCustData; pCustData; pCustData = pCustDataNext)
+ {
+ VariantClear(&pCustData->data);
+
+ pCustDataNext = pCustData->next;
+ TLB_Free(pCustData);
+ }
+ pImplNext = pImpl->next;
+ TLB_Free(pImpl);
+ }
+ for(pRefType = This->reflist; pRefType; pRefType = pRefTypeNext)
+ {
+ pRefTypeNext = pRefType->next;
+ TLB_Free(pRefType);
+ }
+ TLB_Free(This->pCustData);
+
+finish_free:
if (This->next)
{
ITypeInfo_Release((ITypeInfo*)This->next);
@@ -5783,14 +5867,21 @@ static HRESULT WINAPI ITypeInfo_fnGetRef
* copy the contents of the structs.
*/
*pTypeInfoImpl = *This;
- pTypeInfoImpl->ref = 1;
+ pTypeInfoImpl->ref = 0;
/* change the type to interface */
pTypeInfoImpl->TypeAttr.typekind = TKIND_INTERFACE;
*ppTInfo = (ITypeInfo*) pTypeInfoImpl;
- ITypeInfo_AddRef((ITypeInfo*) pTypeInfoImpl);
+ /* we use data structures from This, so we need to keep a reference
+ * to it to stop it being destroyed and signal to the new instance to
+ * not free its data structures when it is destroyed */
+ pTypeInfoImpl->no_free_data = TRUE;
+ pTypeInfoImpl->next = This;
+ ITypeInfo_AddRef((ITypeInfo*) This);
+
+ ITypeInfo_AddRef(*ppTInfo);
result = S_OK;
More information about the wine-cvs
mailing list