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