[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