- TLB_DoFuncs: code cleanup and elemdescFunc read correctly from TLB.

- TLB_LoadTypeLib: ref count problem.
- ITypeLib::GetTypeInfoOfGuid: safer implementation (pointer testing).
- ITypeInfo::GetRefTypeOfImplType: safer implementation (pointer testing).
- ITypeInfo2::GetDocumentationL return errors if SysAllocString failed.
- TLB loader functions now trace in "typelib" channel.
- Improved traces in AddRef/Release and improved dump_* functions for
  debugging.
This commit is contained in:
Francois Jacques 2000-12-21 20:20:12 +00:00 committed by Alexandre Julliard
parent 8058ead8ea
commit 11ed84009e
1 changed files with 563 additions and 276 deletions

View File

@ -538,7 +538,7 @@ static void dump_TLBFuncDesc(TLBFuncDesc * pfd)
{
while (pfd)
{
TRACE("%s(%u)\n", debugstr_w(pfd->Name), pfd->funcdesc.cParams);
TRACE_(typelib)("%s(%u)\n", debugstr_w(pfd->Name), pfd->funcdesc.cParams);
pfd = pfd->next;
};
}
@ -546,7 +546,7 @@ static void dump_TLBVarDesc(TLBVarDesc * pvd)
{
while (pvd)
{
TRACE("%s\n", debugstr_w(pvd->Name));
TRACE_(typelib)("%s\n", debugstr_w(pvd->Name));
pvd = pvd->next;
};
}
@ -554,16 +554,117 @@ static void dump_TLBRefType(TLBRefType * prt)
{
while (prt)
{
TRACE("%s\n", debugstr_guid(&(prt->guid)));
TRACE(" href:0x%08lx\n", prt->reference);
TRACE_(typelib)("%s\n", debugstr_guid(&(prt->guid)));
TRACE_(typelib)(" href:0x%08lx\n", prt->reference);
prt = prt->next;
};
}
static void dump_Variant(VARIANT * pvar)
{
TRACE("%p %x\n", pvar, pvar?pvar->vt:0 );
if(!pvar) return;
char szVarType[15];
TRACE("(%p)\n", pvar);
if (!pvar) return;
ZeroMemory(szVarType, sizeof(szVarType));
/* FIXME : we could have better trace here, depending on the VARTYPE
* of the variant
*/
switch(V_VT(pvar))
{
case VT_UI1:
sprintf(szVarType, "VT_UI");
break;
case VT_I2:
sprintf(szVarType, "VT_I2");
break;
case VT_I4:
sprintf(szVarType, "VT_I4");
break;
case VT_R4:
sprintf(szVarType, "VT_R4");
break;
case VT_R8:
sprintf(szVarType, "VT_R8");
break;
case VT_BOOL:
sprintf(szVarType, "VT_BOOL");
break;
case VT_ERROR:
sprintf(szVarType, "VT_ERROR");
break;
case VT_CY:
sprintf(szVarType, "VT_CY");
break;
case VT_DATE:
sprintf(szVarType, "VT_DATE");
break;
case VT_BSTR:
sprintf(szVarType, "VT_BSTR");
break;
case VT_BYREF:
case VT_UNKNOWN:
sprintf(szVarType, "VT_BYREF");
break;
case VT_DISPATCH:
sprintf(szVarType, "VT_DISPATCH");
break;
case VT_ARRAY:
sprintf(szVarType, "VT_ARRAY");
break;
case VT_I1:
sprintf(szVarType, "VT_I2");
break;
case VT_UI2:
sprintf(szVarType, "VT_UI2");
break;
case VT_UI4:
sprintf(szVarType, "VT_UI4");
break;
case VT_INT:
sprintf(szVarType, "VT_INT");
break;
case VT_UINT:
sprintf(szVarType, "VT_UINT");
break;
}
TRACE("VARTYPE: %s", szVarType);
switch (V_VT(pvar))
{
case VT_R4:
TRACE("%3.3e\n", V_UNION(pvar, fltVal));
break;
case VT_R8:
TRACE("%3.3e\n", V_UNION(pvar, dblVal));
break;
default:
TRACE("%ld\n", V_UNION(pvar, lVal));
break;
}
if (pvar->vt & VT_BYREF)
return dump_Variant(pvar->u.pvarVal);
@ -571,8 +672,15 @@ static void dump_Variant(VARIANT * pvar)
static void dump_DispParms(DISPPARAMS * pdp)
{
dump_Variant( pdp->rgvarg);
int index = 0;
TRACE("args=%u named args=%u\n", pdp->cArgs, pdp->cNamedArgs);
while (index < pdp->cArgs)
{
dump_Variant( &pdp->rgvarg[index] );
++index;
}
}
static char * typekind_desc[] =
@ -636,7 +744,7 @@ static void TLB_Free(void * ptr)
/* read function */
DWORD TLB_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
{
TRACE("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n",
TRACE_(typelib)("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n",
pcx->pos, count, pcx->oStart, pcx->length, where);
if (where != DO_NOT_SEEK)
@ -658,7 +766,7 @@ DWORD TLB_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
static void TLB_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
{
TRACE("%s\n", debugstr_guid(pGuid));
TRACE_(typelib)("%s\n", debugstr_guid(pGuid));
if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){
memset(pGuid,0, sizeof(GUID));
@ -698,7 +806,7 @@ BSTR TLB_ReadName( TLBContext *pcx, int offset)
HeapFree(GetProcessHeap(), 0, pwstring);
}
TRACE("%s %d\n", debugstr_w(bstrName), lengthInChars);
TRACE_(typelib)("%s %d\n", debugstr_w(bstrName), lengthInChars);
return bstrName;
}
@ -732,7 +840,7 @@ BSTR TLB_ReadString( TLBContext *pcx, int offset)
HeapFree(GetProcessHeap(), 0, pwstring);
}
TRACE("%s %d\n", debugstr_w(bstr), lengthInChars);
TRACE_(typelib)("%s %d\n", debugstr_w(bstr), lengthInChars);
return bstr;
}
/*
@ -742,7 +850,7 @@ static void TLB_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
{
int size;
TRACE("\n");
TRACE_(typelib)("\n");
if(offset <0) { /* data is packed in here */
pVar->vt = (offset & 0x7c000000 )>> 26;
@ -751,7 +859,7 @@ static void TLB_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
}
TLB_Read(&(pVar->vt), sizeof(VARTYPE), pcx,
pcx->pTblDir->pCustData.offset + offset );
TRACE("Vartype = %x\n", pVar->vt);
TRACE_(typelib)("Vartype = %x\n", pVar->vt);
switch(pVar->vt){
case VT_EMPTY: /* FIXME: is this right? */
case VT_NULL: /* FIXME: is this right? */
@ -831,7 +939,7 @@ static int TLB_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
TLBCustData* pNew;
int count=0;
TRACE("\n");
TRACE_(typelib)("\n");
while(offset >=0){
count++;
@ -855,10 +963,15 @@ static void TLB_GetTdesc(TLBContext *pcx, INT type,TYPEDESC * pTd )
else
*pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
TRACE("vt type = %X\n", pTd->vt);
TRACE_(typelib)("vt type = %X\n", pTd->vt);
}
static void TLB_DoFuncs(TLBContext *pcx, int cFuncs, int cVars,
int offset, TLBFuncDesc ** pptfd)
static void
TLB_DoFuncs(TLBContext* pcx,
int cFuncs,
int cVars,
int offset,
TLBFuncDesc** pptfd)
{
/*
* member information is stored in a data structure at offset
@ -885,92 +998,136 @@ static void TLB_DoFuncs(TLBContext *pcx, int cFuncs, int cVars,
* first part of this file segment.
*/
int infolen, nameoffset, reclength, nrattributes;
int infolen, nameoffset, reclength, nrattributes, i;
int recoffset = offset + sizeof(INT);
char recbuf[512];
TLBFuncRecord * pFuncRec=(TLBFuncRecord *) recbuf;
int i, j;
int recoffset=offset+sizeof(INT);
TRACE("\n");
TRACE_(typelib)("\n");
TLB_Read(&infolen, sizeof(INT), pcx, offset);
for ( i = 0; i < cFuncs ; i++ )
{
*pptfd = TLB_Alloc(sizeof(TLBFuncDesc));
TLB_Read(&infolen,sizeof(INT), pcx, offset);
for(i=0;i<cFuncs;i++){
*pptfd=TLB_Alloc(sizeof(TLBFuncDesc));
/* name, eventually add to a hash table */
TLB_Read(&nameoffset, sizeof(INT), pcx,
TLB_Read(&nameoffset,
sizeof(INT),
pcx,
offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
(*pptfd)->Name=TLB_ReadName(pcx, nameoffset);
(*pptfd)->Name = TLB_ReadName(pcx, nameoffset);
/* read the function information record */
TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
reclength &=0x1ff;
reclength &= 0x1ff;
TLB_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
/* do the attributes */
nrattributes=(reclength-pFuncRec->nrargs*3*sizeof(int)-0x18)
/sizeof(int);
if(nrattributes>0){
nrattributes = (reclength - pFuncRec->nrargs * 3 * sizeof(int) - 0x18)
/ sizeof(int);
if ( nrattributes > 0 )
{
(*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
if(nrattributes>1){
if ( nrattributes > 1 )
{
(*pptfd)->HelpString = TLB_ReadString(pcx,
pFuncRec->OptAttr[1]) ;
if(nrattributes>2){
if(pFuncRec->FKCCIC & 0x2000)
if ( nrattributes > 2 )
{
if ( pFuncRec->FKCCIC & 0x2000 )
{
(*pptfd)->Entry = (WCHAR*) pFuncRec->OptAttr[2] ;
}
else
{
(*pptfd)->Entry = TLB_ReadString(pcx,
pFuncRec->OptAttr[2]);
if(nrattributes>5 )
}
if( nrattributes > 5 )
{
(*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;
if(nrattributes>6 && pFuncRec->FKCCIC & 0x80){
TLB_CustData(pcx, pFuncRec->OptAttr[6],
if ( nrattributes > 6 && pFuncRec->FKCCIC & 0x80 )
{
TLB_CustData(pcx,
pFuncRec->OptAttr[6],
&(*pptfd)->pCustData);
}
}
}
}
}
/* fill the FuncDesc Structure */
TLB_Read(&(*pptfd)->funcdesc.memid, sizeof(INT), pcx,
TLB_Read( & (*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.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) ;
TLB_GetTdesc(pcx, pFuncRec->DataType,
TLB_GetTdesc(pcx,
pFuncRec->DataType,
&(*pptfd)->funcdesc.elemdescFunc.tdesc) ;
/* do the parameters/arguments */
if(pFuncRec->nrargs){
if(pFuncRec->nrargs)
{
int j = 0;
TLBParameterInfo paraminfo;
(*pptfd)->funcdesc.lprgelemdescParam=
TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
(*pptfd)->pParamDesc=TLB_Alloc(pFuncRec->nrargs *
sizeof(TLBParDesc));
TLB_Read(&paraminfo,sizeof(paraminfo), pcx, recoffset+reclength -
(*pptfd)->funcdesc.lprgelemdescParam =
TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
(*pptfd)->pParamDesc =
TLB_Alloc(pFuncRec->nrargs * sizeof(TLBParDesc));
TLB_Read(&paraminfo,
sizeof(paraminfo),
pcx,
recoffset + reclength -
pFuncRec->nrargs * sizeof(TLBParameterInfo));
for(j=0;j<pFuncRec->nrargs;j++){
for ( j = 0 ; j < pFuncRec->nrargs ; j++ )
{
TYPEDESC* lpArgTypeDesc = 0;
TLB_GetTdesc(pcx, paraminfo.DataType,
TLB_GetTdesc(pcx,
paraminfo.DataType,
&(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc) ;
V_UNION(&((*pptfd)->funcdesc.lprgelemdescParam[j]),
paramdesc.wParamFlags) = paraminfo.Flags;
(*pptfd)->pParamDesc[j].Name=(void *)paraminfo.oName;
/* SEEK value = jump to offset, from there jump to the end of record,
V_UNION(& ((*pptfd)->funcdesc.lprgelemdescParam[j]),
paramdesc.wParamFlags) = paraminfo.Flags;
(*pptfd)->pParamDesc[j].Name = (void *) paraminfo.oName;
/* SEEK value = jump to offset,
* from there jump to the end of record,
* go back by (j-1) arguments
*/
TLB_Read(&paraminfo,sizeof(TLBParameterInfo), pcx,
recoffset+reclength -
((pFuncRec->nrargs - j - 1) * sizeof(TLBParameterInfo)));
TLB_Read( &paraminfo ,
sizeof(TLBParameterInfo), pcx,
recoffset + reclength - ((pFuncRec->nrargs - j - 1)
* sizeof(TLBParameterInfo)));
lpArgTypeDesc =
& ((*pptfd)->funcdesc.lprgelemdescParam[j].tdesc);
lpArgTypeDesc = & ((*pptfd)->funcdesc.lprgelemdescParam[j].tdesc) ;
while (lpArgTypeDesc != NULL)
while ( lpArgTypeDesc != NULL )
{
switch (lpArgTypeDesc->vt)
switch ( lpArgTypeDesc->vt )
{
case VT_PTR:
lpArgTypeDesc = lpArgTypeDesc->u.lptdesc;
@ -981,8 +1138,13 @@ static void TLB_DoFuncs(TLBContext *pcx, int cFuncs, int cVars,
break;
case VT_USERDEFINED:
(*pptfd)->pParamDesc[j].pRefType = TLB_Alloc(sizeof(TLBRefType));
TLB_DoRefType(pcx, lpArgTypeDesc->u.hreftype, &((*pptfd)->pParamDesc[j].pRefType));
(*pptfd)->pParamDesc[j].pRefType =
TLB_Alloc(sizeof(TLBRefType));
TLB_DoRefType(pcx,
lpArgTypeDesc->u.hreftype,
& ( (*pptfd)->pParamDesc[j].pRefType ));
lpArgTypeDesc = NULL;
break;
@ -991,34 +1153,90 @@ static void TLB_DoFuncs(TLBContext *pcx, int cFuncs, int cVars,
}
}
}
/* parameter is the return value! */
if ( paraminfo.Flags & PARAMFLAG_FRETVAL )
{
TYPEDESC* lpArgTypeDesc;
(*pptfd)->funcdesc.elemdescFunc =
(*pptfd)->funcdesc.lprgelemdescParam[j];
lpArgTypeDesc = & ((*pptfd)->funcdesc.elemdescFunc.tdesc) ;
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:
(*pptfd)->pParamDesc[j].pRefType
= TLB_Alloc(sizeof(TLBRefType));
TLB_DoRefType(pcx,
lpArgTypeDesc->u.hreftype,
&((*pptfd)->pParamDesc[j].pRefType));
lpArgTypeDesc = NULL;
break;
default:
lpArgTypeDesc = NULL;
}
}
}
/* second time around */
for(j=0;j<pFuncRec->nrargs;j++){
for(j=0;j<pFuncRec->nrargs;j++)
{
/* name */
(*pptfd)->pParamDesc[j].Name=
TLB_ReadName(pcx, (int)(*pptfd)->pParamDesc[j].Name);
(*pptfd)->pParamDesc[j].Name =
TLB_ReadName( pcx, (int)(*pptfd)->pParamDesc[j].Name );
/* default value */
if((PARAMFLAG_FHASDEFAULT & V_UNION(&((*pptfd)->funcdesc.
lprgelemdescParam[j]),paramdesc.wParamFlags)) &&
((pFuncRec->FKCCIC) & 0x1000)){
INT *pInt=(INT *)((char *)pFuncRec + reclength -
if ( (PARAMFLAG_FHASDEFAULT &
V_UNION(&((*pptfd)->funcdesc.lprgelemdescParam[j]),
paramdesc.wParamFlags)) &&
((pFuncRec->FKCCIC) & 0x1000) )
{
INT* pInt = (INT *)((char *)pFuncRec +
reclength -
(pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
PARAMDESC * pParamDesc= &V_UNION(&((*pptfd)->funcdesc.
lprgelemdescParam[j]),paramdesc);
PARAMDESC* pParamDesc = &V_UNION(
& ((*pptfd)->funcdesc.lprgelemdescParam[j]),
paramdesc);
pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
pParamDesc->pparamdescex->cBytes= sizeof(PARAMDESCEX);
pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX);
TLB_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
pInt[j], pcx);
}
/* custom info */
if(nrattributes>7+j && pFuncRec->FKCCIC & 0x80)
TLB_CustData(pcx, pFuncRec->OptAttr[7+j],
if ( nrattributes > 7 + j && pFuncRec->FKCCIC & 0x80 )
{
TLB_CustData(pcx,
pFuncRec->OptAttr[7+j],
&(*pptfd)->pParamDesc[j].pCustData);
}
}
}
/* scode is not used: archaic win16 stuff FIXME: right? */
(*pptfd)->funcdesc.cScodes = 0 ;
(*pptfd)->funcdesc.lprgscode = NULL ;
pptfd=&((*pptfd)->next);
pptfd = & ((*pptfd)->next);
recoffset += reclength;
}
}
@ -1031,7 +1249,7 @@ static void TLB_DoVars(TLBContext *pcx, int cFuncs, int cVars,
int i;
int recoffset;
TRACE("\n");
TRACE_(typelib)("\n");
TLB_Read(&infolen,sizeof(INT), pcx, offset);
TLB_Read(&recoffset,sizeof(INT), pcx, offset + infolen +
@ -1082,14 +1300,14 @@ static void TLB_DoRefType(TLBContext *pcx,
{
int j;
TRACE("TLB context %p, TLB offset %x\n", pcx, offset);
TRACE_(typelib)("TLB context %p, TLB offset %x\n", pcx, offset);
if(!HREFTYPE_INTHISFILE( offset)) {
/* external typelib */
TLBImpInfo impinfo;
TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs);
TRACE("offset %x, masked offset %x\n", offset, offset + (offset & 0xfffffffc));
TRACE_(typelib)("offset %x, masked offset %x\n", offset, offset + (offset & 0xfffffffc));
TLB_Read(&impinfo, sizeof(impinfo), pcx,
pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
@ -1120,7 +1338,7 @@ static void TLB_DoImplTypes(TLBContext *pcx, int count,
int i;
TLBRefRecord refrec;
TRACE("\n");
TRACE_(typelib)("\n");
for(i=0;i<count;i++){
if(offset<0) break; /* paranoia */
@ -1145,7 +1363,7 @@ ITypeInfoImpl * TLB_DoTypeInfo(
TLBTypeInfoBase tiBase;
ITypeInfoImpl *ptiRet;
TRACE("count=%u\n", count);
TRACE_(typelib)("count=%u\n", count);
ptiRet = (ITypeInfoImpl*) ITypeInfo_Constructor();
TLB_Read(&tiBase, sizeof(tiBase) ,pcx ,
@ -1154,6 +1372,8 @@ ITypeInfoImpl * TLB_DoTypeInfo(
ptiRet->pTypeLib = pLibInfo;
ptiRet->index=count;
/* fill in the typeattr fields */
FIXME("Assign constructor/destrutor memid\n");
TLB_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx);
ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid; /* FIXME: correct? */
ptiRet->TypeAttr.memidConstructor=MEMBERID_NIL ;/* FIXME */
@ -1178,7 +1398,7 @@ ITypeInfoImpl * TLB_DoTypeInfo(
/* name, eventually add to a hash table */
ptiRet->Name=TLB_ReadName(pcx, tiBase.NameOffset);
TRACE("reading %s\n", debugstr_w(ptiRet->Name));
TRACE_(typelib)("reading %s\n", debugstr_w(ptiRet->Name));
/* help info */
ptiRet->DocString=TLB_ReadString(pcx, tiBase.docstringoffs);
ptiRet->dwHelpStringContext=tiBase.helpstringcontext;
@ -1240,7 +1460,7 @@ ITypeInfoImpl * TLB_DoTypeInfo(
ptiRet->ctCustData=
TLB_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData);
TRACE("%s guid: %s kind:%s\n",
TRACE_(typelib)("%s guid: %s kind:%s\n",
debugstr_w(ptiRet->Name),
debugstr_guid(&ptiRet->TypeAttr.guid),
typekind_desc[ptiRet->TypeAttr.typekind]);
@ -1266,7 +1486,7 @@ int TLB_ReadTypeLib(LPSTR pszFileName, ITypeLib2 **ppTypeLib)
PCHAR pszTypeLibIndex = NULL;
PCHAR pszDllName = NULL;
TRACE("%s\n", pszFileName);
TRACE_(typelib)("%s\n", pszFileName);
*ppTypeLib = NULL;
@ -1311,8 +1531,8 @@ int TLB_ReadTypeLib(LPSTR pszFileName, ITypeLib2 **ppTypeLib)
pszTypeLibIndex = "1\0";
}
TRACE("File name without index %s\n", pszDllName);
TRACE("Index of typelib %s\n", pszTypeLibIndex);
TRACE_(typelib)("File name without index %s\n", pszDllName);
TRACE_(typelib)("Index of typelib %s\n", pszTypeLibIndex);
/* check the signature of the file */
@ -1333,6 +1553,7 @@ int TLB_ReadTypeLib(LPSTR pszFileName, ITypeLib2 **ppTypeLib)
DWORD dwTLBLength = GetFileSize(hFile, NULL);
*ppTypeLib = ITypeLib2_Constructor(pBase, dwTLBLength);
ITypeLib2_AddRef(*ppTypeLib);
}
UnmapViewOfFile(pBase);
}
@ -1362,10 +1583,15 @@ int TLB_ReadTypeLib(LPSTR pszFileName, ITypeLib2 **ppTypeLib)
/* try to load as incore resource */
dwSignature = *((DWORD*) pBase);
if ( dwSignature == MSFT_SIGNATURE)
{
*ppTypeLib = ITypeLib2_Constructor(pBase, dwTLBLength);
ITypeLib2_AddRef(*ppTypeLib);
}
else
{
FIXME("Header type magic 0x%08lx not supported.\n",dwSignature);
}
}
FreeResource( hGlobal );
}
}
@ -1572,6 +1798,7 @@ static ITypeLib2* ITypeLib2_Constructor(LPVOID pLib, DWORD dwTLBLength)
{
*ppTI = TLB_DoTypeInfo(&cx, i, pTypeLibImpl);
ITypeInfo_AddRef((ITypeInfo*) *ppTI);
ppTI = &((*ppTI)->next);
(pTypeLibImpl->TypeInfoCount)++;
}
@ -1627,9 +1854,11 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
{
ICOM_THIS( ITypeLibImpl, iface);
--(This->ref);
TRACE("(%p)->(%u)\n",This, This->ref);
if (!--(This->ref))
if (!This->ref)
{
/* fixme destroy child objects */
@ -1663,6 +1892,7 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
HeapFree(GetProcessHeap(),0,This);
return 0;
}
return This->ref;
}
@ -1687,30 +1917,33 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(
ITypeInfo **ppTInfo)
{
int i;
ICOM_THIS( ITypeLibImpl, iface);
ITypeInfoImpl *pTLBTInfo = This->pTypeInfo;
TRACE("(%p)->(index=%d) \n",This, index);
ICOM_THIS( ITypeLibImpl, iface);
ITypeInfoImpl *pTypeInfo = This->pTypeInfo;
TRACE("(%p)->(index=%d) \n", This, index);
if (!ppTInfo) return E_INVALIDARG;
/* search element n in list */
for(i=0; i < index; i++)
{
pTLBTInfo = pTLBTInfo->next;
if (!pTLBTInfo)
pTypeInfo = pTypeInfo->next;
if (!pTypeInfo)
{
TRACE("-- element not found\n");
return TYPE_E_ELEMENTNOTFOUND;
}
}
*ppTInfo = (ITypeInfo *) pTLBTInfo;
*ppTInfo = (ITypeInfo *) pTypeInfo;
ITypeInfo_AddRef(*ppTInfo);
TRACE("-- found (%p)\n",*ppTInfo);
return S_OK;
}
/* ITypeLibs::GetTypeInfoType
*
* Retrieves the type of a type description.
@ -1755,15 +1988,18 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(
ITypeInfo **ppTInfo)
{
ICOM_THIS( ITypeLibImpl, iface);
ITypeInfoImpl *ppTLBTInfo = This->pTypeInfo; /* head of list */
ITypeInfoImpl *pTypeInfo = This->pTypeInfo; /* head of list */
TRACE("(%p)\n\tguid:\t%s)\n",This,debugstr_guid(guid));
/* serach linked list for guid */
while( !IsEqualIID(guid,&ppTLBTInfo->TypeAttr.guid) )
if (!pTypeInfo) return TYPE_E_ELEMENTNOTFOUND;
/* search linked list for guid */
while( !IsEqualIID(guid,&pTypeInfo->TypeAttr.guid) )
{
ppTLBTInfo = ppTLBTInfo->next;
if (!ppTLBTInfo)
pTypeInfo = pTypeInfo->next;
if (!pTypeInfo)
{
/* end of list reached */
TRACE("-- element not found\n");
@ -1771,9 +2007,11 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(
}
}
TRACE("-- found (%p, %s)\n", ppTLBTInfo, debugstr_w(ppTLBTInfo->Name));
TRACE("-- found (%p, %s)\n",
pTypeInfo,
debugstr_w(pTypeInfo->Name));
*ppTInfo = (ITypeInfo*)ppTLBTInfo;
*ppTInfo = (ITypeInfo*)pTypeInfo;
ITypeInfo_AddRef(*ppTInfo);
return S_OK;
}
@ -1825,31 +2063,63 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
BSTR *pBstrHelpFile)
{
ICOM_THIS( ITypeLibImpl, iface);
HRESULT result;
HRESULT result = E_INVALIDARG;
ITypeInfo *pTInfo;
TRACE("(%p) index %d Name(%p) DocString(%p)"
" HelpContext(%p) HelpFile(%p)\n",
This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
if(index<0){ /* documentation for the typelib */
if(pBstrName)
*pBstrName=SysAllocString(This->Name);
if(pBstrDocString)
*pBstrDocString=SysAllocString(This->DocString);
TRACE("(%p) index %d Name(%p) DocString(%p) HelpContext(%p) HelpFile(%p)\n",
This, index,
pBstrName, pBstrDocString,
pdwHelpContext, pBstrHelpFile);
if(index<0)
{
/* documentation for the typelib */
if(pBstrName && This->Name)
{
*pBstrName = SysAllocString(This->Name);
if (!(*pBstrName)) return STG_E_INSUFFICIENTMEMORY;
}
if(pBstrDocString && This->DocString)
{
*pBstrDocString = SysAllocString(This->DocString);
if (!(*pBstrDocString)) return STG_E_INSUFFICIENTMEMORY;
}
if(pdwHelpContext)
*pdwHelpContext=This->dwHelpContext;
if(pBstrHelpFile)
*pBstrHelpFile=SysAllocString(This->HelpFile);
}else {/* for a typeinfo */
result=ITypeLib2_fnGetTypeInfo(iface, index, &pTInfo);
if(SUCCEEDED(result)){
result=ITypeInfo_GetDocumentation(pTInfo, MEMBERID_NIL, pBstrName,
pBstrDocString, pdwHelpContext, pBstrHelpFile);
{
*pdwHelpContext = This->dwHelpContext;
}
if(pBstrHelpFile && This->HelpFile)
{
*pBstrHelpFile = SysAllocString(This->HelpFile);
if (!(*pBstrHelpFile)) return STG_E_INSUFFICIENTMEMORY;
}
result = S_OK;
}
else
{
/* for a typeinfo */
result = ITypeLib2_fnGetTypeInfo(iface, index, &pTInfo);
if(SUCCEEDED(result))
{
result = ITypeInfo_GetDocumentation(pTInfo,
MEMBERID_NIL,
pBstrName,
pBstrDocString,
pdwHelpContext, pBstrHelpFile);
ITypeInfo_Release(pTInfo);
}
if(!SUCCEEDED(result))
return result;
}
return S_OK;
return result;
}
/* ITypeLib::IsName
@ -2038,27 +2308,37 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
*pdwHelpStringContext=This->dwHelpContext;
if(pbstrHelpStringDll)
*pbstrHelpStringDll=SysAllocString(This->HelpStringDll);
result = S_OK;
}
else
{
/* for a typeinfo */
result=ITypeLib2_GetTypeInfo(iface, index, &pTInfo);
if(SUCCEEDED(result))
{
ITypeInfo2 * pTInfo2;
result = ITypeInfo_QueryInterface(pTInfo, &IID_ITypeInfo2, (LPVOID*) &pTInfo2);
result = ITypeInfo_QueryInterface(pTInfo,
&IID_ITypeInfo2,
(LPVOID*) &pTInfo2);
if(SUCCEEDED(result))
{
result = ITypeInfo2_GetDocumentation2(pTInfo2, MEMBERID_NIL, lcid,
pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
result = ITypeInfo2_GetDocumentation2(pTInfo2,
MEMBERID_NIL,
lcid,
pbstrHelpString,
pdwHelpStringContext,
pbstrHelpStringDll);
ITypeInfo2_Release(pTInfo2);
}
ITypeInfo_Release(pTInfo);
}
if(!SUCCEEDED(result))
return result;
}
return S_OK;
return result;
}
/* ITypeLib2::GetAllCustData
@ -2156,8 +2436,11 @@ static HRESULT WINAPI ITypeInfo_fnQueryInterface(
static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface)
{
ICOM_THIS( ITypeInfoImpl, iface);
++(This->ref);
TRACE("(%p)->ref is %u\n",This, This->ref);
return ++(This->ref);
return This->ref;
}
/* ITypeInfo::Release
@ -2165,14 +2448,16 @@ static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface)
static ULONG WINAPI ITypeInfo_fnRelease( ITypeInfo2 *iface)
{
ICOM_THIS( ITypeInfoImpl, iface);
--(This->ref);
TRACE("(%p)->(%u)\n",This, This->ref);
if (!--(This->ref))
if (!This->ref)
{
FIXME("destroy child objects\n");
TRACE(" destroying ITypeInfo(%p)\n",This);
TRACE("destroying ITypeInfo(%p)\n",This);
if (This->Name)
{
SysFreeString(This->Name);
@ -2354,7 +2639,6 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType(
TRACE("(%p) index %d\n", This, index);
dump_TypeInfo(This);
if(index==(UINT)-1)
{
/* only valid on dual interfaces;
@ -2369,22 +2653,25 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType(
}
else
{
if (!pIref) return TYPE_E_ELEMENTNOTFOUND;
*pRefType = pIref->reference;
}
}
else
{
/* get element n from linked list */
for(i=0; i<index; i++)
for(i=0; pIref && i<index; i++)
{
if (!pIref) return TYPE_E_ELEMENTNOTFOUND;
pIref = pIref->next;
}
if (!pIref) return TYPE_E_ELEMENTNOTFOUND;
*pRefType = pIref->reference;
}
TRACE("-- 0x%08lx %s\n",pIref->reference, debugstr_guid(&pIref->guid) );
}
return S_OK;
}