[PATCH 5/5] oleaut32: Always read all imports from the typelib

Andrew Eikum aeikum at codeweavers.com
Wed Jun 5 07:57:44 CDT 2013


---
 dlls/oleaut32/typelib.c | 139 +++++++++++++++---------------------------------
 1 file changed, 42 insertions(+), 97 deletions(-)

diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 959c87b..4a98952 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -1223,8 +1223,6 @@ typedef struct tagTLBContext
 } TLBContext;
 
 
-static void MSFT_DoRefType(TLBContext *pcx, ITypeLibImpl *pTL, int offset);
-
 static inline BSTR TLB_get_bstr(const TLBString *str)
 {
     return str != NULL ? str->str : NULL;
@@ -2206,40 +2204,9 @@ static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd,
     else
         *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
 
-    if(pTd->vt == VT_USERDEFINED)
-      MSFT_DoRefType(pcx, pTI->pTypeLib, pTd->u.hreftype);
-
     TRACE_(typelib)("vt type = %X\n", pTd->vt);
 }
 
-static void MSFT_ResolveReferencedTypes(TLBContext *pcx, ITypeInfoImpl *pTI, TYPEDESC *lpTypeDesc)
-{
-    /* resolve referenced type if any */
-    while (lpTypeDesc)
-    {
-        switch (lpTypeDesc->vt)
-        {
-        case VT_PTR:
-            lpTypeDesc = lpTypeDesc->u.lptdesc;
-            break;
-
-        case VT_CARRAY:
-            lpTypeDesc = & (lpTypeDesc->u.lpadesc->tdescElem);
-            break;
-
-        case VT_USERDEFINED:
-            MSFT_DoRefType(pcx, pTI->pTypeLib,
-                           lpTypeDesc->u.hreftype);
-
-            lpTypeDesc = NULL;
-            break;
-
-        default:
-            lpTypeDesc = NULL;
-        }
-    }
-}
-
 static int TLB_is_propgetput(INVOKEKIND invkind)
 {
     return (invkind == INVOKE_PROPERTYGET ||
@@ -2364,7 +2331,6 @@ MSFT_DoFuncs(TLBContext*     pcx,
 		      pFuncRec->DataType,
 		      &ptfd->funcdesc.elemdescFunc.tdesc,
 		      pTI);
-        MSFT_ResolveReferencedTypes(pcx, pTI, &ptfd->funcdesc.elemdescFunc.tdesc);
 
         /* do the parameters/arguments */
         if(pFuncRec->nrargs)
@@ -2397,8 +2363,6 @@ MSFT_DoFuncs(TLBContext*     pcx,
                         MSFT_ReadName( pcx, paraminfo.oName );
                 TRACE_(typelib)("param[%d] = %s\n", j, debugstr_w(TLB_get_bstr(ptfd->pParamDesc[j].Name)));
 
-                MSFT_ResolveReferencedTypes(pcx, pTI, &elemdesc->tdesc);
-
                 /* default value */
                 if ( (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) &&
                      (pFuncRec->FKCCIC & 0x1000) )
@@ -2501,66 +2465,10 @@ static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs,
                 pVarRec->OffsValue, pcx);
         } else
             ptvd->vardesc.u.oInst=pVarRec->OffsValue;
-        MSFT_ResolveReferencedTypes(pcx, pTI, &ptvd->vardesc.elemdescVar.tdesc);
         recoffset += reclength;
     }
 }
 
-/* fill in data for a hreftype (offset). When the referenced type is contained
- * 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, ITypeLibImpl *pTL,
-                          int offset)
-{
-    TLBRefType *ref;
-
-    TRACE_(typelib)("TLB context %p, TLB offset %x\n", pcx, offset);
-
-    LIST_FOR_EACH_ENTRY(ref, &pTL->ref_list, TLBRefType, entry)
-    {
-        if(ref->reference == offset) return;
-    }
-
-    ref = heap_alloc_zero(sizeof(TLBRefType));
-    list_add_tail(&pTL->ref_list, &ref->entry);
-
-    if(!MSFT_HREFTYPE_INTHISFILE( offset)) {
-        /* external typelib */
-        MSFT_ImpInfo impinfo;
-        TLBImpLib *pImpLib;
-
-        TRACE_(typelib)("offset %x, masked offset %x\n", offset, offset + (offset & 0xfffffffc));
-
-        MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx,
-                          pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
-
-        LIST_FOR_EACH_ENTRY(pImpLib, &pcx->pLibInfo->implib_list, TLBImpLib, entry)
-            if(pImpLib->offset==impinfo.oImpFile)
-                break;
-
-        if(&pImpLib->entry != &pcx->pLibInfo->implib_list){
-            ref->reference = offset & (~0x3);
-            ref->pImpTLInfo = pImpLib;
-            if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
-                ref->guid = MSFT_ReadGuid(impinfo.oGuid, pcx);
-                TRACE("importing by guid %s\n", debugstr_guid(TLB_get_guidref(ref->guid)));
-                ref->index = TLB_REF_USE_GUID;
-            } else
-                ref->index = impinfo.oGuid;
-        }else{
-            ERR("Cannot find a reference\n");
-            ref->reference = -1;
-            ref->pImpTLInfo = TLB_REF_NOT_FOUND;
-        }
-    }else{
-        /* in this typelib */
-        ref->index = MSFT_HREFTYPE_INDEX(offset);
-        ref->reference = offset;
-        ref->pImpTLInfo = TLB_REF_INTERNAL;
-    }
-}
-
 /* process Implemented Interfaces of a com class */
 static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count,
 			    int offset)
@@ -2576,7 +2484,6 @@ static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count,
     for(i=0;i<count;i++){
         if(offset<0) break; /* paranoia */
         MSFT_ReadLEDWords(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
-        MSFT_DoRefType(pcx, pTI->pTypeLib, refrec.reftype);
         pImpl->hRef = refrec.reftype;
         pImpl->implflags=refrec.flags;
         MSFT_CustData(pcx, refrec.oCustData, &pImpl->custdata_list);
@@ -2668,12 +2575,10 @@ static ITypeInfoImpl * MSFT_DoTypeInfo(
             {
                 ptiRet->impltypes = TLBImplType_Alloc(1);
                 ptiRet->impltypes[0].hRef = tiBase.datatype1;
-                MSFT_DoRefType(pcx, pLibInfo, tiBase.datatype1);
             }
             break;
         default:
             ptiRet->impltypes = TLBImplType_Alloc(1);
-            MSFT_DoRefType(pcx, pLibInfo, tiBase.datatype1);
             ptiRet->impltypes[0].hRef = tiBase.datatype1;
             break;
        }
@@ -2735,6 +2640,46 @@ static HRESULT MSFT_ReadAllStrings(TLBContext *pcx)
     }
 }
 
+static HRESULT MSFT_ReadAllRefs(TLBContext *pcx)
+{
+    TLBRefType *ref;
+    int offs = 0;
+
+    MSFT_Seek(pcx, pcx->pTblDir->pImpInfo.offset);
+    while (offs < pcx->pTblDir->pImpInfo.length) {
+        MSFT_ImpInfo impinfo;
+        TLBImpLib *pImpLib;
+
+        MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx, DO_NOT_SEEK);
+
+        ref = heap_alloc_zero(sizeof(TLBRefType));
+        list_add_tail(&pcx->pLibInfo->ref_list, &ref->entry);
+
+        LIST_FOR_EACH_ENTRY(pImpLib, &pcx->pLibInfo->implib_list, TLBImpLib, entry)
+            if(pImpLib->offset==impinfo.oImpFile)
+                break;
+
+        if(&pImpLib->entry != &pcx->pLibInfo->implib_list){
+            ref->reference = offs;
+            ref->pImpTLInfo = pImpLib;
+            if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
+                ref->guid = MSFT_ReadGuid(impinfo.oGuid, pcx);
+                TRACE("importing by guid %s\n", debugstr_guid(TLB_get_guidref(ref->guid)));
+                ref->index = TLB_REF_USE_GUID;
+            } else
+                ref->index = impinfo.oGuid;
+        }else{
+            ERR("Cannot find a reference\n");
+            ref->reference = -1;
+            ref->pImpTLInfo = TLB_REF_NOT_FOUND;
+        }
+
+        offs += sizeof(impinfo);
+    }
+
+    return S_OK;
+}
+
 /* Because type library parsing has some degree of overhead, and some apps repeatedly load the same
  * typelibs over and over, we cache them here. According to MSDN Microsoft have a similar scheme in
  * place. This will cause a deliberate memory leak, but generally losing RAM for cycles is an acceptable
@@ -3501,9 +3446,9 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
         }
     }
 
+    MSFT_ReadAllRefs(&cx);
+
     pTypeLibImpl->dispatch_href = tlbHeader.dispatchpos;
-    if(pTypeLibImpl->dispatch_href != -1)
-        MSFT_DoRefType(&cx, pTypeLibImpl, pTypeLibImpl->dispatch_href);
 
     /* type infos */
     if(tlbHeader.nrtypeinfos >= 0 )
-- 
1.8.3




More information about the wine-patches mailing list