mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
oleaut32: Always read all imports from the typelib.
This commit is contained in:
parent
7adad42745
commit
9afd5845e5
1 changed files with 42 additions and 97 deletions
|
@ -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 )
|
||||
|
|
Loading…
Reference in a new issue