?? typelib.c
字號:
case VT_UI2 :
case VT_UI4 :
case VT_INT :
case VT_UINT :
case VT_VOID : /* FIXME: is this right? */
case VT_HRESULT :
size=4; break;
case VT_R8 :
case VT_CY :
case VT_DATE :
case VT_I8 :
case VT_UI8 :
case VT_DECIMAL : /* FIXME: is this right? */
case VT_FILETIME :
size=8;break;
/* pointer types with known behaviour */
case VT_BSTR :{
char * ptr;
MSFT_ReadLEDWords(&size, sizeof(INT), pcx, DO_NOT_SEEK );
if(size < 0) {
char next;
DWORD origPos = MSFT_Tell(pcx), nullPos;
do {
MSFT_Read(&next, 1, pcx, DO_NOT_SEEK);
} while (next);
nullPos = MSFT_Tell(pcx);
size = nullPos - origPos;
MSFT_Seek(pcx, origPos);
}
ptr=TLB_Alloc(size);/* allocate temp buffer */
MSFT_Read(ptr, size, pcx, DO_NOT_SEEK);/* read string (ANSI) */
V_BSTR(pVar)=SysAllocStringLen(NULL,size);
/* FIXME: do we need a AtoW conversion here? */
V_UNION(pVar, bstrVal[size])='\0';
while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
TLB_Free(ptr);
}
size=-4; break;
/* FIXME: this will not work AT ALL when the variant contains a pointer */
case VT_DISPATCH :
case VT_VARIANT :
case VT_UNKNOWN :
case VT_PTR :
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->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 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 = HeapAlloc(GetProcessHeap(), 0, 0xffff);
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 &= 0xffff;
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 )
{
if (HIWORD(pFuncRec->OptAttr[2]) != 0)
ERR("ordinal 0x%08x invalid, HIWORD != 0\n", pFuncRec->OptAttr[2]);
(*pptfd)->Entry = (BSTR)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);
}
}
}
else
{
(*pptfd)->Entry = (BSTR)-1;
}
}
}
/* 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);
MSFT_ResolveReferencedTypes(pcx, pTI, &(*pptfd)->funcdesc.elemdescFunc.tdesc);
/* 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++ )
{
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));
MSFT_ResolveReferencedTypes(pcx, pTI, &elemdesc->tdesc);
/* 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;
}
HeapFree(GetProcessHeap(), 0, recbuf);
}
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 + (2*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 + (cFuncs + 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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -