oleaut32: Type references are global to the typelib.

Huw Davies huw at codeweavers.com
Thu May 10 07:56:16 CDT 2007


---
 dlls/oleaut32/tests/typelib.c |    2 -
 dlls/oleaut32/typelib.c       |  197 +++++++++++++++++++++-------------------
 2 files changed, 103 insertions(+), 96 deletions(-)

diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c
index 0af9774..6b1b579 100644
--- a/dlls/oleaut32/tests/typelib.c
+++ b/dlls/oleaut32/tests/typelib.c
@@ -343,9 +343,7 @@ static void test_CreateDispTypeInfo(void)
 
     hr = ITypeInfo_GetRefTypeOfImplType(pTypeInfo, 0, &href);
     ok(hr == S_OK, "hr %08x\n", hr);
-    todo_wine {
     ok(href == 0, "href = 0x%x\n", href);
-    }
     hr = ITypeInfo_GetRefTypeInfo(pTypeInfo, href, &pTI2);
     ok(hr == S_OK, "hr %08x\n", hr);
     hr = ITypeInfo_GetTypeAttr(pTI2, &pTypeAttr);
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 50b2928..6c663ac 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -70,6 +70,7 @@
 #include "typelib.h"
 #include "wine/debug.h"
 #include "variant.h"
+#include "wine/list.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 WINE_DECLARE_DEBUG_CHANNEL(typelib);
@@ -894,9 +895,9 @@ typedef struct tagITypeLibImpl
     TLBImpLib   * pImpLibs;     /* linked list to all imported typelibs */
     int ctTypeDesc;             /* number of items in type desc array */
     TYPEDESC * pTypeDesc;       /* array of TypeDescriptions found in the
-				   library. Only used while read MSFT
+				   library. Only used while reading MSFT
 				   typelibs */
-
+    struct list ref_list;       /* list of ref types in this typelib */
     /* typelibs are cached, keyed by path and index, so store the linked list info within them */
     struct tagITypeLibImpl *next, *prev;
     WCHAR *path;
@@ -932,7 +933,7 @@ typedef struct tagTLBRefType
 			       TLB_REF_INTERNAL for internal refs
 			       TLB_REF_NOT_FOUND for broken refs */
 
-    struct tagTLBRefType * next;
+    struct list entry;
 } TLBRefType;
 
 #define TLB_REF_USE_GUID -2
@@ -1015,7 +1016,6 @@ typedef struct tagITypeInfoImpl
     /* Implemented Interfaces  */
     TLBImplType * impltypelist;
 
-    TLBRefType * reflist;
     int ctCustData;
     TLBCustData * pCustData;        /* linked list to cust data; */
     struct tagITypeInfoImpl * next;
@@ -1042,7 +1042,7 @@ typedef struct tagTLBContext
 } TLBContext;
 
 
-static void MSFT_DoRefType(TLBContext *pcx, ITypeInfoImpl *pTI, int offset);
+static void MSFT_DoRefType(TLBContext *pcx, ITypeLibImpl *pTL, int offset);
 
 /*
  debug
@@ -1200,23 +1200,24 @@ static void dump_TLBImpLib(const TLBImpLib *import)
 		    import->wVersionMinor, import->lcid, import->offset);
 }
 
-static void dump_TLBRefType(const TLBRefType * prt)
+static void dump_TLBRefType(const ITypeLibImpl *pTL)
 {
-	while (prt)
-	{
-	  TRACE_(typelib)("href:0x%08x\n", prt->reference);
-	  if(prt->index == -1)
-	    TRACE_(typelib)("%s\n", debugstr_guid(&(prt->guid)));
-	  else
-	    TRACE_(typelib)("type no: %d\n", prt->index);
-
-	  if(prt->pImpTLInfo != TLB_REF_INTERNAL &&
-	     prt->pImpTLInfo != TLB_REF_NOT_FOUND) {
-	      TRACE_(typelib)("in lib\n");
-	      dump_TLBImpLib(prt->pImpTLInfo);
-	  }
-	  prt = prt->next;
-	};
+    TLBRefType *ref;
+
+    LIST_FOR_EACH_ENTRY(ref, &pTL->ref_list, TLBRefType, entry)
+    {
+        TRACE_(typelib)("href:0x%08x\n", ref->reference);
+        if(ref->index == -1)
+	    TRACE_(typelib)("%s\n", debugstr_guid(&(ref->guid)));
+        else
+	    TRACE_(typelib)("type no: %d\n", ref->index);
+
+        if(ref->pImpTLInfo != TLB_REF_INTERNAL && ref->pImpTLInfo != TLB_REF_NOT_FOUND)
+        {
+            TRACE_(typelib)("in lib\n");
+            dump_TLBImpLib(ref->pImpTLInfo);
+        }
+    }
 }
 
 static void dump_TLBImplType(const TLBImplType * impl)
@@ -1697,7 +1698,7 @@ static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd,
         *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
 
     if(pTd->vt == VT_USERDEFINED)
-      MSFT_DoRefType(pcx, pTI, pTd->u.hreftype);
+      MSFT_DoRefType(pcx, pTI->pTypeLib, pTd->u.hreftype);
 
     TRACE_(typelib)("vt type = %X\n", pTd->vt);
 }
@@ -1718,7 +1719,7 @@ static void MSFT_ResolveReferencedTypes(TLBContext *pcx, ITypeInfoImpl *pTI, TYP
             break;
 
         case VT_USERDEFINED:
-            MSFT_DoRefType(pcx, pTI,
+            MSFT_DoRefType(pcx, pTI->pTypeLib,
                            lpTypeDesc->u.hreftype);
 
             lpTypeDesc = NULL;
@@ -2002,22 +2003,21 @@ static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs,
  * in the typelib, it's just an (file) offset in the type info base dir.
  * If comes from import, it's an offset+1 in the ImpInfo table
  * */
-static void MSFT_DoRefType(TLBContext *pcx, ITypeInfoImpl *pTI,
+static void MSFT_DoRefType(TLBContext *pcx, ITypeLibImpl *pTL,
                           int offset)
 {
     int j;
-    TLBRefType **ppRefType = &pTI->reflist;
+    TLBRefType *ref;
 
     TRACE_(typelib)("TLB context %p, TLB offset %x\n", pcx, offset);
 
-    while(*ppRefType) {
-        if((*ppRefType)->reference == offset)
-	    return;
-	ppRefType = &(*ppRefType)->next;
+    LIST_FOR_EACH_ENTRY(ref, &pTL->ref_list, TLBRefType, entry)
+    {
+        if(ref->reference == offset) return;
     }
 
-    *ppRefType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-			   sizeof(**ppRefType));
+    ref = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ref));
+    list_add_tail(&pTL->ref_list, &ref->entry);
 
     if(!MSFT_HREFTYPE_INTHISFILE( offset)) {
         /* external typelib */
@@ -2033,24 +2033,24 @@ static void MSFT_DoRefType(TLBContext *pcx, ITypeInfoImpl *pTI,
             pImpLib=pImpLib->next;
         }
         if(pImpLib){
-            (*ppRefType)->reference=offset;
-            (*ppRefType)->pImpTLInfo = pImpLib;
+            ref->reference = offset;
+            ref->pImpTLInfo = pImpLib;
             if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
-                MSFT_ReadGuid(&(*ppRefType)->guid, impinfo.oGuid, pcx);
-                TRACE("importing by guid %s\n", debugstr_guid(&(*ppRefType)->guid));
-                (*ppRefType)->index = TLB_REF_USE_GUID;
+                MSFT_ReadGuid(&ref->guid, impinfo.oGuid, pcx);
+                TRACE("importing by guid %s\n", debugstr_guid(&ref->guid));
+                ref->index = TLB_REF_USE_GUID;
             } else
-                (*ppRefType)->index = impinfo.oGuid;
+                ref->index = impinfo.oGuid;
         }else{
             ERR("Cannot find a reference\n");
-            (*ppRefType)->reference=-1;
-            (*ppRefType)->pImpTLInfo=TLB_REF_NOT_FOUND;
+            ref->reference = -1;
+            ref->pImpTLInfo = TLB_REF_NOT_FOUND;
         }
     }else{
         /* in this typelib */
-        (*ppRefType)->index = MSFT_HREFTYPE_INDEX(offset);
-        (*ppRefType)->reference=offset;
-        (*ppRefType)->pImpTLInfo=TLB_REF_INTERNAL;
+        ref->index = MSFT_HREFTYPE_INDEX(offset);
+        ref->reference = offset;
+        ref->pImpTLInfo = TLB_REF_INTERNAL;
     }
 }
 
@@ -2068,7 +2068,7 @@ static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count,
         if(offset<0) break; /* paranoia */
         *ppImpl=TLB_Alloc(sizeof(**ppImpl));
         MSFT_ReadLEDWords(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
-        MSFT_DoRefType(pcx, pTI, refrec.reftype);
+        MSFT_DoRefType(pcx, pTI->pTypeLib, refrec.reftype);
 	(*ppImpl)->hRef = refrec.reftype;
 	(*ppImpl)->implflags=refrec.flags;
         (*ppImpl)->ctCustData=
@@ -2157,18 +2157,18 @@ static ITypeInfoImpl * MSFT_DoTypeInfo(
 
             if (tiBase.datatype1 != -1)
             {
-              MSFT_DoRefType(pcx, ptiRet, tiBase.datatype1);
+              MSFT_DoRefType(pcx, pLibInfo, tiBase.datatype1);
 	      ptiRet->impltypelist->hRef = tiBase.datatype1;
             }
             else
 	    {
-              MSFT_DoRefType(pcx, ptiRet, dispatch_href);
+              MSFT_DoRefType(pcx, pLibInfo, dispatch_href);
               ptiRet->impltypelist->hRef = dispatch_href;
             }
             break;
         default:
             ptiRet->impltypelist=TLB_Alloc(sizeof(TLBImplType));
-            MSFT_DoRefType(pcx, ptiRet, tiBase.datatype1);
+            MSFT_DoRefType(pcx, pLibInfo, tiBase.datatype1);
 	    ptiRet->impltypelist->hRef = tiBase.datatype1;
             break;
        }
@@ -2362,6 +2362,8 @@ static ITypeLibImpl* TypeLibImpl_Constructor(void)
     pTypeLibImpl->lpVtblTypeComp = &tlbtcvt;
     pTypeLibImpl->ref = 1;
 
+    list_init(&pTypeLibImpl->ref_list);
+
     return pTypeLibImpl;
 }
 
@@ -2781,12 +2783,12 @@ static WORD *SLTG_DoElem(WORD *pType, char *pBlk, ELEMDESC *pElem)
 }
 
 
-static void SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeInfoImpl *pTI,
+static void SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL,
 			char *pNameTable)
 {
     int ref;
     char *name;
-    TLBRefType **ppRefType;
+    TLBRefType *ref_type;
 
     if(pRef->magic != SLTG_REF_MAGIC) {
         FIXME("Ref magic = %x\n", pRef->magic);
@@ -2794,19 +2796,17 @@ static void SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeInfoImpl *pTI,
     }
     name = ( (char*)(&pRef->names) + pRef->number);
 
-    ppRefType = &pTI->reflist;
     for(ref = 0; ref < pRef->number >> 3; ref++) {
         char *refname;
 	unsigned int lib_offs, type_num;
 
-	*ppRefType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-			       sizeof(**ppRefType));
+	ref_type = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ref_type));
 
 	name += SLTG_ReadStringA(name, &refname);
 	if(sscanf(refname, "*\\R%x*#%x", &lib_offs, &type_num) != 2)
 	    FIXME("Can't sscanf ref\n");
 	if(lib_offs != 0xffff) {
-	    TLBImpLib **import = &pTI->pTypeLib->pImpLibs;
+	    TLBImpLib **import = &pTL->pImpLibs;
 
 	    while(*import) {
 	        if((*import)->offset == lib_offs)
@@ -2835,19 +2835,19 @@ static void SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeInfoImpl *pTI,
 		fname[len-1] = '\0';
 		(*import)->name = TLB_MultiByteToBSTR(fname);
 	    }
-	    (*ppRefType)->pImpTLInfo = *import;
+	    ref_type->pImpTLInfo = *import;
 	} else { /* internal ref */
-	  (*ppRefType)->pImpTLInfo = TLB_REF_INTERNAL;
+	  ref_type->pImpTLInfo = TLB_REF_INTERNAL;
 	}
-	(*ppRefType)->reference = ref;
-	(*ppRefType)->index = type_num;
+	ref_type->reference = ref;
+	ref_type->index = type_num;
 
 	HeapFree(GetProcessHeap(), 0, refname);
-	ppRefType = &(*ppRefType)->next;
+        list_add_tail(&pTL->ref_list, &ref_type->entry);
     }
     if((BYTE)*name != SLTG_REF_MAGIC)
       FIXME("End of ref block magic = %x\n", *name);
-    dump_TLBRefType(pTI->reflist);
+    dump_TLBRefType(pTL);
 }
 
 static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
@@ -3074,7 +3074,7 @@ static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI,
     char *pFirstItem, *pNextItem;
 
     if(pTIHeader->href_table != 0xffffffff) {
-        SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI,
+        SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
 		    pNameTable);
     }
 
@@ -3093,7 +3093,7 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI,
     char *pFirstItem, *pNextItem;
 
     if(pTIHeader->href_table != 0xffffffff) {
-        SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI,
+        SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
 		    pNameTable);
     }
 
@@ -3130,7 +3130,7 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
   }
 
   if(pTIHeader->href_table != 0xffffffff) {
-      SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI,
+      SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
 		  pNameTable);
   }
 
@@ -3145,7 +3145,7 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
 				 SLTG_TypeInfoTail *pTITail)
 {
   if (pTIHeader->href_table != 0xffffffff)
-      SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI,
+      SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
                                   pNameTable);
 
   if (pTITail->vars_off != 0xffff)
@@ -3175,7 +3175,7 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
 			       SLTG_TypeInfoTail *pTITail)
 {
   if (pTIHeader->href_table != 0xffffffff)
-      SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI,
+      SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
                                   pNameTable);
 
   if (pTITail->vars_off != 0xffff)
@@ -3553,6 +3553,8 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
     {
       TLBImpLib *pImpLib, *pImpLibNext;
       TLBCustData *pCustData, *pCustDataNext;
+      TLBRefType *ref_type;
+      void *cursor2;
       int i;
 
       /* remove cache entry */
@@ -3616,6 +3618,12 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
           TLB_Free(pImpLib);
       }
 
+      LIST_FOR_EACH_ENTRY_SAFE(ref_type, cursor2, &This->ref_list, TLBRefType, entry)
+      {
+          list_remove(&ref_type->entry);
+          TLB_Free(ref_type);
+      }
+
       if (This->pTypeInfo) /* can be NULL */
       	  ITypeInfo_Release((ITypeInfo*) This->pTypeInfo);
       HeapFree(GetProcessHeap(),0,This);
@@ -4402,7 +4410,6 @@ static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
       TLBFuncDesc *pFInfo, *pFInfoNext;
       TLBVarDesc *pVInfo, *pVInfoNext;
       TLBImplType *pImpl, *pImplNext;
-      TLBRefType *pRefType,*pRefTypeNext;
       TLBCustData *pCustData, *pCustDataNext;
 
       TRACE("destroying ITypeInfo(%p)\n",This);
@@ -4481,11 +4488,6 @@ static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
           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:
@@ -5999,51 +6001,55 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
 	  result = S_OK;
 
     } else {
-        TLBRefType *pRefType;
-        for(pRefType = This->reflist; pRefType; pRefType = pRefType->next) {
-	    if(pRefType->reference == hRefType)
-	        break;
-	}
-	if(!pRefType)
-	  FIXME("Can't find pRefType for ref %x\n", hRefType);
-	if(pRefType && hRefType != -1) {
+        TLBRefType *ref_type;
+        LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry)
+        {
+            if(ref_type->reference == hRefType)
+                break;
+        }
+        if(&ref_type->entry == &This->pTypeLib->ref_list)
+        {
+            FIXME("Can't find pRefType for ref %x\n", hRefType);
+            goto end;
+        }
+        if(hRefType != -1) {
             ITypeLib *pTLib = NULL;
 
-	    if(pRefType->pImpTLInfo == TLB_REF_INTERNAL) {
+            if(ref_type->pImpTLInfo == TLB_REF_INTERNAL) {
 	        UINT Index;
 		result = ITypeInfo_GetContainingTypeLib(iface, &pTLib, &Index);
 	    } else {
-	        if(pRefType->pImpTLInfo->pImpTypeLib) {
+                if(ref_type->pImpTLInfo->pImpTypeLib) {
 		    TRACE("typeinfo in imported typelib that is already loaded\n");
-		    pTLib = (ITypeLib*)pRefType->pImpTLInfo->pImpTypeLib;
+                    pTLib = (ITypeLib*)ref_type->pImpTLInfo->pImpTypeLib;
 		    ITypeLib2_AddRef((ITypeLib*) pTLib);
 		    result = S_OK;
 		} else {
 		    TRACE("typeinfo in imported typelib that isn't already loaded\n");
-		    result = LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
-					     pRefType->pImpTLInfo->wVersionMajor,
-					     pRefType->pImpTLInfo->wVersionMinor,
-					     pRefType->pImpTLInfo->lcid,
+                    result = LoadRegTypeLib( &ref_type->pImpTLInfo->guid,
+                                             ref_type->pImpTLInfo->wVersionMajor,
+                                             ref_type->pImpTLInfo->wVersionMinor,
+                                             ref_type->pImpTLInfo->lcid,
 					     &pTLib);
 
 		    if(!SUCCEEDED(result)) {
-		        BSTR libnam=SysAllocString(pRefType->pImpTLInfo->name);
+                        BSTR libnam=SysAllocString(ref_type->pImpTLInfo->name);
 			result=LoadTypeLib(libnam, &pTLib);
 			SysFreeString(libnam);
 		    }
 		    if(SUCCEEDED(result)) {
-		        pRefType->pImpTLInfo->pImpTypeLib = (ITypeLibImpl*)pTLib;
+                        ref_type->pImpTLInfo->pImpTypeLib = (ITypeLibImpl*)pTLib;
 			ITypeLib2_AddRef(pTLib);
 		    }
 		}
 	    }
 	    if(SUCCEEDED(result)) {
-	        if(pRefType->index == TLB_REF_USE_GUID)
+                if(ref_type->index == TLB_REF_USE_GUID)
 		    result = ITypeLib2_GetTypeInfoOfGuid(pTLib,
-							 &pRefType->guid,
+                                                         &ref_type->guid,
 							 ppTInfo);
 		else
-		    result = ITypeLib2_GetTypeInfo(pTLib, pRefType->index,
+                    result = ITypeLib2_GetTypeInfo(pTLib, ref_type->index,
 						   ppTInfo);
 	    }
 	    if (pTLib != NULL)
@@ -6051,6 +6057,7 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
 	}
     }
 
+end:
     TRACE("(%p) hreftype 0x%04x loaded %s (%p)\n", This, hRefType,
           SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
     return result;
@@ -6809,6 +6816,7 @@ HRESULT WINAPI CreateDispTypeInfo(
     ITypeLibImpl *pTypeLibImpl;
     int param, func;
     TLBFuncDesc **ppFuncDesc;
+    TLBRefType *ref;
 
     TRACE("\n");
     pTypeLibImpl = TypeLibImpl_Constructor();
@@ -6892,12 +6900,13 @@ HRESULT WINAPI CreateDispTypeInfo(
     pTIClass->TypeAttr.wTypeFlags = 0;
 
     pTIClass->impltypelist = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pTIClass->impltypelist));
-    pTIClass->impltypelist->hRef = 1;
+    pTIClass->impltypelist->hRef = 0;
 
-    pTIClass->reflist = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pTIClass->reflist));
-    pTIClass->reflist->index = 0;
-    pTIClass->reflist->reference = 1;
-    pTIClass->reflist->pImpTLInfo = TLB_REF_INTERNAL;
+    ref = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ref));
+    ref->index = 0;
+    ref->reference = 0;
+    ref->pImpTLInfo = TLB_REF_INTERNAL;
+    list_add_head(&pTypeLibImpl->ref_list, &ref->entry);
 
     dump_TypeInfo(pTIClass);
 
-- 
1.5.0.5




More information about the wine-patches mailing list