📄 typelib.c
字号:
case VT_SAFEARRAY :
case VT_CARRAY :
case VT_USERDEFINED :
case VT_LPSTR :
case VT_LPWSTR :
case VT_BLOB :
case VT_STREAM :
case VT_STORAGE :
case VT_STREAMED_OBJECT :
case VT_STORED_OBJECT :
case VT_BLOB_OBJECT :
case VT_CF :
case VT_CLSID :
default:
size=0;
FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
V_VT(pVar));
}
if(size>0) /* (big|small) endian correct? */
MSFT_Read(&(V_I2(pVar)), size, pcx, DO_NOT_SEEK );
return;
}
/*
* create a linked list with custom data
*/
static int MSFT_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
{
MSFT_CDGuid entry;
TLBCustData* pNew;
int count=0;
TRACE_(typelib)("\n");
while(offset >=0){
count++;
pNew=TLB_Alloc(sizeof(TLBCustData));
MSFT_ReadLEDWords(&entry, sizeof(entry), pcx, pcx->pTblDir->pCDGuids.offset+offset);
MSFT_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
MSFT_ReadValue(&(pNew->data), entry.DataOffset, pcx);
/* add new custom data at head of the list */
pNew->next=*ppCustData;
*ppCustData=pNew;
offset = entry.next;
}
return count;
}
static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd,
ITypeInfoImpl *pTI)
{
if(type <0)
pTd->vt=type & VT_TYPEMASK;
else
*pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
if(pTd->vt == VT_USERDEFINED)
MSFT_DoRefType(pcx, pTI, pTd->u.hreftype);
TRACE_(typelib)("vt type = %X\n", pTd->vt);
}
static void
MSFT_DoFuncs(TLBContext* pcx,
ITypeInfoImpl* pTI,
int cFuncs,
int cVars,
int offset,
TLBFuncDesc** pptfd)
{
/*
* member information is stored in a data structure at offset
* indicated by the memoffset field of the typeinfo structure
* There are several distinctive parts.
* The first part starts with a field that holds the total length
* of this (first) part excluding this field. Then follow the records,
* for each member there is one record.
*
* The first entry is always the length of the record (including this
* length word).
* The rest of the record depends on the type of the member. If there is
* a field indicating the member type (function, variable, interface, etc)
* I have not found it yet. At this time we depend on the information
* in the type info and the usual order how things are stored.
*
* Second follows an array sized nrMEM*sizeof(INT) with a member id
* for each member;
*
* Third is an equal sized array with file offsets to the name entry
* of each member.
*
* The fourth and last (?) part is an array with offsets to the records
* in the first part of this file segment.
*/
int infolen, nameoffset, reclength, nrattributes, i;
int recoffset = offset + sizeof(INT);
char recbuf[512];
MSFT_FuncRecord * pFuncRec=(MSFT_FuncRecord *) recbuf;
TLBFuncDesc *ptfd_prev = NULL;
TRACE_(typelib)("\n");
MSFT_ReadLEDWords(&infolen, sizeof(INT), pcx, offset);
for ( i = 0; i < cFuncs ; i++ )
{
*pptfd = TLB_Alloc(sizeof(TLBFuncDesc));
/* name, eventually add to a hash table */
MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
/* nameoffset is sometimes -1 on the second half of a propget/propput
* pair of functions */
if ((nameoffset == -1) && (i > 0))
(*pptfd)->Name = SysAllocString(ptfd_prev->Name);
else
(*pptfd)->Name = MSFT_ReadName(pcx, nameoffset);
/* read the function information record */
MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset);
reclength &= 0x1ff;
MSFT_ReadLEDWords(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK);
/* do the attributes */
nrattributes = (reclength - pFuncRec->nrargs * 3 * sizeof(int) - 0x18)
/ sizeof(int);
if ( nrattributes > 0 )
{
(*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
if ( nrattributes > 1 )
{
(*pptfd)->HelpString = MSFT_ReadString(pcx,
pFuncRec->OptAttr[1]) ;
if ( nrattributes > 2 )
{
if ( pFuncRec->FKCCIC & 0x2000 )
{
(*pptfd)->Entry = (WCHAR*) pFuncRec->OptAttr[2] ;
}
else
{
(*pptfd)->Entry = MSFT_ReadString(pcx,
pFuncRec->OptAttr[2]);
}
if( nrattributes > 5 )
{
(*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;
if ( nrattributes > 6 && pFuncRec->FKCCIC & 0x80 )
{
MSFT_CustData(pcx,
pFuncRec->OptAttr[6],
&(*pptfd)->pCustData);
}
}
}
}
}
/* fill the FuncDesc Structure */
MSFT_ReadLEDWords( & (*pptfd)->funcdesc.memid, sizeof(INT), pcx,
offset + infolen + ( i + 1) * sizeof(INT));
(*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
(*pptfd)->funcdesc.invkind = (pFuncRec->FKCCIC) >> 3 & 0xF;
(*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >> 8 & 0xF;
(*pptfd)->funcdesc.cParams = pFuncRec->nrargs ;
(*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ;
(*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ;
(*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
MSFT_GetTdesc(pcx,
pFuncRec->DataType,
&(*pptfd)->funcdesc.elemdescFunc.tdesc,
pTI);
/* do the parameters/arguments */
if(pFuncRec->nrargs)
{
int j = 0;
MSFT_ParameterInfo paraminfo;
(*pptfd)->funcdesc.lprgelemdescParam =
TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
(*pptfd)->pParamDesc =
TLB_Alloc(pFuncRec->nrargs * sizeof(TLBParDesc));
MSFT_ReadLEDWords(¶minfo, sizeof(paraminfo), pcx,
recoffset + reclength - pFuncRec->nrargs * sizeof(MSFT_ParameterInfo));
for ( j = 0 ; j < pFuncRec->nrargs ; j++ )
{
TYPEDESC *lpArgTypeDesc;
ELEMDESC *elemdesc = &(*pptfd)->funcdesc.lprgelemdescParam[j];
MSFT_GetTdesc(pcx,
paraminfo.DataType,
&elemdesc->tdesc,
pTI);
elemdesc->u.paramdesc.wParamFlags = paraminfo.Flags;
/* name */
if (paraminfo.oName == -1)
/* this occurs for [propput] or [propget] methods, so
* we should just set the name of the parameter to the
* name of the method. */
(*pptfd)->pParamDesc[j].Name = SysAllocString((*pptfd)->Name);
else
(*pptfd)->pParamDesc[j].Name =
MSFT_ReadName( pcx, paraminfo.oName );
TRACE_(typelib)("param[%d] = %s\n", j, debugstr_w((*pptfd)->pParamDesc[j].Name));
lpArgTypeDesc = &elemdesc->tdesc;
/* resolve referenced type if any */
while ( lpArgTypeDesc != NULL )
{
switch ( lpArgTypeDesc->vt )
{
case VT_PTR:
lpArgTypeDesc = lpArgTypeDesc->u.lptdesc;
break;
case VT_CARRAY:
lpArgTypeDesc = & (lpArgTypeDesc->u.lpadesc->tdescElem);
break;
case VT_USERDEFINED:
MSFT_DoRefType(pcx, pTI,
lpArgTypeDesc->u.hreftype);
lpArgTypeDesc = NULL;
break;
default:
lpArgTypeDesc = NULL;
}
}
/* default value */
if ( (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) &&
(pFuncRec->FKCCIC & 0x1000) )
{
INT* pInt = (INT *)((char *)pFuncRec +
reclength -
(pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
PARAMDESC* pParamDesc = &elemdesc->u.paramdesc;
pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX);
MSFT_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
pInt[j], pcx);
}
else
elemdesc->u.paramdesc.pparamdescex = NULL;
/* custom info */
if ( nrattributes > 7 + j && pFuncRec->FKCCIC & 0x80 )
{
MSFT_CustData(pcx,
pFuncRec->OptAttr[7+j],
&(*pptfd)->pParamDesc[j].pCustData);
}
/* SEEK value = jump to offset,
* from there jump to the end of record,
* go back by (j-1) arguments
*/
MSFT_ReadLEDWords( ¶minfo ,
sizeof(MSFT_ParameterInfo), pcx,
recoffset + reclength - ((pFuncRec->nrargs - j - 1)
* sizeof(MSFT_ParameterInfo)));
}
}
/* scode is not used: archaic win16 stuff FIXME: right? */
(*pptfd)->funcdesc.cScodes = 0 ;
(*pptfd)->funcdesc.lprgscode = NULL ;
ptfd_prev = *pptfd;
pptfd = & ((*pptfd)->next);
recoffset += reclength;
}
}
static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs,
int cVars, int offset, TLBVarDesc ** pptvd)
{
int infolen, nameoffset, reclength;
char recbuf[256];
MSFT_VarRecord * pVarRec=(MSFT_VarRecord *) recbuf;
int i;
int recoffset;
TRACE_(typelib)("\n");
MSFT_ReadLEDWords(&infolen,sizeof(INT), pcx, offset);
MSFT_ReadLEDWords(&recoffset,sizeof(INT), pcx, offset + infolen +
((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
recoffset += offset+sizeof(INT);
for(i=0;i<cVars;i++){
*pptvd=TLB_Alloc(sizeof(TLBVarDesc));
/* name, eventually add to a hash table */
MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
(*pptvd)->Name=MSFT_ReadName(pcx, nameoffset);
/* read the variable information record */
MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset);
reclength &=0xff;
MSFT_ReadLEDWords(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK);
/* Optional data */
if(reclength >(6*sizeof(INT)) )
(*pptvd)->HelpContext=pVarRec->HelpContext;
if(reclength >(7*sizeof(INT)) )
(*pptvd)->HelpString = MSFT_ReadString(pcx, pVarRec->oHelpString) ;
if(reclength >(8*sizeof(INT)) )
if(reclength >(9*sizeof(INT)) )
(*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
/* fill the VarDesc Structure */
MSFT_ReadLEDWords(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
offset + infolen + ( i + 1) * sizeof(INT));
(*pptvd)->vardesc.varkind = pVarRec->VarKind;
(*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
MSFT_GetTdesc(pcx, pVarRec->DataType,
&(*pptvd)->vardesc.elemdescVar.tdesc, pTI);
/* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */
if(pVarRec->VarKind == VAR_CONST ){
(*pptvd)->vardesc.u.lpvarValue=TLB_Alloc(sizeof(VARIANT));
MSFT_ReadValue((*pptvd)->vardesc.u.lpvarValue,
pVarRec->OffsValue, pcx);
} else
(*pptvd)->vardesc.u.oInst=pVarRec->OffsValue;
pptvd=&((*pptvd)->next);
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, ITypeInfoImpl *pTI,
int offset)
{
int j;
TLBRefType **ppRefType = &pTI->reflist;
TRACE_(typelib)("TLB context %p, TLB offset %x\n", pcx, offset);
while(*ppRefType) {
if((*ppRefType)->reference == offset)
return;
ppRefType = &(*ppRefType)->next;
}
*ppRefType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(**ppRefType));
if(!MSFT_HREFTYPE_INTHISFILE( offset)) {
/* external typelib */
MSFT_ImpInfo impinfo;
TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs);
TRACE_(typelib)("offset %x, masked offset %x\n", offset, offset + (offset & 0xfffffffc));
MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx,
pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
for(j=0;pImpLib;j++){ /* search the known offsets of all import libraries */
if(pImpLib->offset==impinfo.oImpFile) break;
pImpLib=pImpLib->next;
}
if(pImpLib){
(*ppRefType)->reference=offset;
(*ppRefType)->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;
} else
(*ppRefType)->index = impinfo.oGuid;
}else{
ERR("Cannot find a reference\n");
(*ppRefType)->reference=-1;
(*ppRefType)->pImpTLInfo=TLB_REF_NOT_FOU
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -