blob: 419e507732fcd3703f0ad31fa47ce5c487da1691 [file] [log] [blame]
/*
genidl - Generate interface defintion language listing from a
Portable Executable.
Copyright (C) 2009-2016 mingw-w64 project
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define _CRT_SECURE_NO_WARNINGS
#include <inttypes.h>
#include "genidl_cfg.h"
#include "genidl_typeinfo.h"
#include "genidl_typinfo.h"
void dumpHexFp (FILE *fp,size_t off, const unsigned char *dta, size_t len);
void dumpDecFp (FILE *fp, const unsigned char *dta, size_t len, const char *prefix);
void printPrefix (FILE *fp, const char *name, int32_t val);
void printPrefix2 (FILE *fp, const char *name, int32_t val);
uint32_t printVT (FILE *fp, uint32_t vt, unsigned char *dta);
void printVTData (FILE * fp,uint32_t vt,unsigned char *dta, uint32_t sz);
const char *getFunkKindName (int32_t fkind);
const char *getInvokeKindName (int32_t ikind);
const char *getParamFlagName (uint32_t pflag);
const char *getTKindName (uint32_t tkind);
void printVarflags (FILE *fp, uint32_t flags);
void printFuncFlags (FILE *fp, uint32_t flags);
void printTypFlags (FILE *fp, uint32_t flags);
static void
dumpMemInfo (FILE *fp, unsigned char *dta,uint32_t cVar, uint32_t cFunc,uint32_t tkind);
static const char *getVTTypeName (uint32_t vt, uint32_t *dataSize);
static void dumpMem (FILE *fp, unsigned char *dta,unsigned char *umap, uint32_t cVar, uint32_t cFunc);
static void dumpImpFile (FILE *fp, unsigned char *segImp, uint32_t length, int32_t importinfos);
static void dumpTypeInfo (FILE *fp, unsigned char *segImp, uint32_t length, int32_t nr, unsigned char *umap, unsigned char *dta, size_t size, uint32_t *typinfo);
static void
dumpString (FILE *fp, unsigned char *segString, uint32_t length);
static void
dumpName (FILE *fp, unsigned char *segName, uint32_t len);
static void
dumpGuid (FILE *fp, unsigned char *d, uint32_t length);
static void
dumpRefTab (FILE *fp, unsigned char *d, uint32_t len);
static void
dumpTypedesc (FILE *fp, unsigned char *d,uint32_t len);
static void
dumpImpFiles (FILE *fp, unsigned char *d, uint32_t len);
static void
dumpArrayDesc (FILE *fp, unsigned char *d, uint32_t len);
static void
dumpCustomData (FILE *fp, unsigned char *d, uint32_t len);
static void
dumpCustomDataGuid (FILE *fp, unsigned char *d, uint32_t len);
sTITyps ti2_typs;
void dumpInfo (FILE *fp, unsigned char *dta, size_t size)
{
char *umap;
sTypeLibMSFT *t = (sTypeLibMSFT *) dta;
unsigned char *d;
sSegMSFT *segs;
int32_t *typeinfos;
int i;
TI_init_typs (&ti2_typs);
if (!t || !size)
return;
if (t->magic1 != TYPELIB_MSFT_MAGIC)
{
size_t k,j;
fprintf (fp, "Unknown magic 0x%x (%"PRIxMAX")\n", t->magic1, (uintmax_t) size);
for (k = 0; k < size && k < (16 * 32);)
{
fprintf (fp, "0x%08"PRIxMAX": ", (uintmax_t)k);
for (j=0; j < 16 && k < size && k < (16 * 32); j++, k++)
{
fprintf (fp, " %02X", dta[k]);
}
fprintf (fp,"\n");
}
return;
}
umap = (char *) malloc (size + 1);
memset (umap, 0, size);
umap[size]=1;
i = 0;
if (t->var_flags & 0x100)
i++;
typeinfos= (int32_t *) &t->dta[i];
d = (unsigned char *) &typeinfos[t->nr_typeinfos];
segs = (sSegMSFT *) d;
d = (unsigned char *) &segs[eSegMSFT_MAX];
memset (umap, 1, (size_t) (d-dta));
for (i=0;i<eSegMSFT_MAX;i++)
{
if (segs[i].length != 0)
memset (umap + segs[i].offset, 1, segs[i].length);
}
/* Initialize constants pools. */
TI2_import_name (&ti2_typs,dta + segs[eSegMSFT_NAME].offset, segs[eSegMSFT_NAME].length);
TI2_import_string (&ti2_typs,dta + segs[eSegMSFT_STRING].offset, segs[eSegMSFT_STRING].length);
TI2_import_guid (&ti2_typs,dta + segs[eSegMSFT_GUID].offset, segs[eSegMSFT_GUID].length);
TI2_import_importlibs (&ti2_typs, dta + segs[eSegMSFT_IMPORTFILES].offset, segs[eSegMSFT_IMPORTFILES].length);
TI2_import_importref (&ti2_typs, dta + segs[eSegMSFT_IMPORTINFO].offset, segs[eSegMSFT_IMPORTINFO].length);
TI2_import_typinfo_names (&ti2_typs,
dta + segs[eSegMSFT_TYPEINFO].offset, segs[eSegMSFT_TYPEINFO].length);
TI2_import_typedesc (&ti2_typs,dta + segs[eSegMSFT_TYPEDESC].offset, segs[eSegMSFT_TYPEDESC].length);
TI2_import_customdata (&ti2_typs, dta + segs[eSegMSFT_CUSTDATA].offset, segs[eSegMSFT_CUSTDATA].length);
TI2_import_customdataguid (&ti2_typs, dta + segs[eSegMSFT_CUSTDATAGUID].offset, segs[eSegMSFT_CUSTDATAGUID].length);
TI2_import_array (&ti2_typs, dta + segs[eSegMSFT_ARRAYDESC].offset, segs[eSegMSFT_ARRAYDESC].length);
TI2_import_ref (&ti2_typs, dta + segs[eSegMSFT_REFERENCES].offset, segs[eSegMSFT_REFERENCES].length);
fprintf (fp, "/* TypeLib V%u.%u Version:%d, SetFlags:0x%x */\n", t->ver_major,t->ver_minor,t->version,
t->flags);
fprintf (fp, " Guid at ");
printPrefix (fp, "Guid_", t->pos_guid);
fprintf (fp, ", Lcid1: %d Lcide2: %d\n", t->lcid,t->lcid2);
fprintf (fp, " var flags: 0x%x\n", t->var_flags);
fprintf (fp, " # of typeinfos: %d, # of import infos: %d\n",
t->nr_typeinfos, t->nr_impinfos);
fprintf (fp, " helpstring: ");
printPrefix (fp, "Str_", t->helpstring);
fprintf (fp, ", helpfile: ");
printPrefix (fp, "Str_", t->helpfile);
fprintf (fp, ", helpstring-context:%d, help-context:%d\n",
t->helpstringcontext, t->helpcontext);
fprintf (fp, " Nametable strings:%d with %u # of characters. Name is ",
t->nametable_count,t->nametable_size);
printPrefix (fp, "Name_", t->name_offset);
fprintf (fp, "\n");
fprintf (fp," Custom data offset: %d, Res44(Hash):0x%x, Res48(name hash):0x%x\n",
t->custom_data_offset, t->res44, t->res48);
fprintf (fp, " Dispatch: %d\n", t->dispatchpos);
if (t->var_flags & 0x100)
{
fprintf (fp, " HelpstringDll: ");
printPrefix (fp, "Str_", t->dta[0]);
fprintf (fp, "\n");
}
for (i=0;i<eSegMSFT_MAX;i++)
{
fprintf (fp," Seg %d: offset=", i);
if (((int) segs[i].offset) < 0)
fprintf (fp, "%d", segs[i].offset);
else
fprintf (fp, "0x%x length=0x%x", segs[i].offset, segs[i].length);
fprintf (fp, ", res08=%d, res0c=%d\n",
segs[i].res08,segs[i].res0c);
}
for (i=0;i<eSegMSFT_MAX;i++)
{
switch (i) {
case eSegMSFT_TYPEINFO:
dumpTypeInfo (fp, dta + segs[eSegMSFT_TYPEINFO].offset, segs[eSegMSFT_TYPEINFO].length,
t->nr_typeinfos, (unsigned char *) umap, dta, size, (uint32_t *) typeinfos);
break;
case eSegMSFT_IMPORTINFO:
dumpImpFile (fp, dta + segs[eSegMSFT_IMPORTINFO].offset, segs[eSegMSFT_IMPORTINFO].length,
t->nr_impinfos);
break;
case eSegMSFT_TYPEDESC:
dumpTypedesc (fp ,dta + segs[eSegMSFT_TYPEDESC].offset, segs[eSegMSFT_TYPEDESC].length);
break;
case eSegMSFT_IMPORTFILES:
dumpImpFiles (fp ,dta + segs[i].offset, segs[i].length);
break;
case eSegMSFT_ARRAYDESC:
dumpArrayDesc (fp ,dta + segs[i].offset, segs[i].length);
break;
case eSegMSFT_CUSTDATA:
dumpCustomData (fp ,dta + segs[i].offset, segs[i].length);
break;
case eSegMSFT_CUSTDATAGUID:
dumpCustomDataGuid (fp ,dta + segs[i].offset, segs[i].length);
break;
case eSegMSFT_REFERENCES:
dumpRefTab (fp ,dta + segs[i].offset, segs[i].length);
break;
case eSegMSFT_STRING:
dumpString (fp, dta + segs[i].offset, segs[i].length);
break;
case eSegMSFT_NAME:
dumpName (fp ,dta + segs[i].offset, segs[i].length);
break;
case eSegMSFT_GUID:
dumpGuid (fp ,dta + segs[i].offset, segs[i].length);
break;
case eSegMSFT_GUIDHASH:
fprintf (fp,"GUIDHASH:\n");
dumpDecFp(fp, dta + segs[i].offset, segs[i].length,"Guid_");
break;
case eSegMSFT_NAMEHASH:
fprintf (fp,"NAMEHASH:\n");
dumpDecFp(fp, dta + segs[i].offset, segs[i].length,"Name_");
break;
default:
if(segs[i].length == 0)
break;
fprintf (fp,"Segment %d\n", i);
dumpHexFp (fp, 0, dta + segs[i].offset, segs[i].length);
break;
}
}
{
size_t lr, off = 0;
size_t li = 0;
while (li < size)
{
if (umap[li] == 1)
{
do { li++; } while (li < size && umap[li] == 1);
off = 0;
continue;
}
lr = li + 1;
while (lr < size && umap[lr] == 0)
lr++;
if (umap[li] == 3)
fprintf (fp, "\n");
else
{
off = 0;
fprintf (fp," mem:0x%x\n", (int32_t) li);
}
dumpHexFp (fp,off, &dta[li], (lr-li));
off += (lr-li);
li = lr;
}
}
TI_dest_typs (&ti2_typs);
}
static void
dumpTypeInfo (FILE *fp, unsigned char *segImp, uint32_t length, int32_t nr, unsigned char *umap,
unsigned char *dta, size_t size, uint32_t*typinfo)
{
sMSFT_TypeInfoBase *t = (sMSFT_TypeInfoBase *) segImp;
int32_t i;
uint32_t off = 0;
if (!length)
return;
fprintf (fp,"Has %d typeinfo blocks\n", nr);
for (i=0;i<nr;i++) {
if (t[i].memoffset > 0 && umap[t[i].memoffset]!=1)
umap[t[i].memoffset]=2;
fprintf (fp, " ");
printPrefix2 (fp, "TypeB_", (int32_t) off);
fprintf (fp, ": #%d, TypInfoId:%d",i, typinfo[i]);
if (t[i].cElement != 0)
fprintf (fp, "(mem:0x%x) ", t[i].memoffset);
off += sizeof (sMSFT_TypeInfoBase);
fprintf (fp, ", typekind:#%u, %s:0x%x, res2:%u, res3:%d, res4:%d\n",
(t[i].typekind >> 16) % 0xffff,
getTKindName (t[i].typekind & 0xf),
(t[i].typekind >> 4) & 0xfff,t[i].res2, t[i].res3, t[i].res4);
fprintf (fp, "\t");
if (t[i].res5 != 0)
fprintf (fp, "res5:%d!=0,", t[i].res5);
if (t[i].res7 != 0)
fprintf (fp, "res7:%d!=0,", t[i].res7);
if (t[i].res8 != 0)
fprintf (fp, "res8:%d!=0,", t[i].res8);
if (t[i].res9 != 0)
fprintf (fp, "res9:%d!=0,", t[i].res9);
fprintf (fp, "cVar:0x%x,cFunc:0x%x\n", (t[i].cElement>>16)&0xffff,t[i].cElement&0xffff);
if (t[i].resA != 0)
fprintf (fp, "\tresA:%d!=0,GUID:",t[i].resA);
else
fprintf (fp, "\tGUID:");
printPrefix (fp, "Guid_", t[i].posguid);
fprintf (fp, "\n\tName:");
printPrefix (fp, "Name_", t[i].NameOffset);
fprintf (fp, "\n\tVersion:%d\n\t", t[i].version);
printTypFlags (fp, t[i].flags);
if (t[i].docstringoffs != -1)
{
fprintf (fp, " Doc:");
printPrefix (fp, "Str_", t[i].docstringoffs);
fprintf (fp, "\n");
}
fprintf (fp, "\tHelpStringCtx:%d,HelpCtx:%d,ImplTypes:%d\n",
t[i].helpstringcontext,t[i].helpcontext,t[i].cImplTypes);
if (t[i].oCustData != -1)
{
fprintf (fp, "\tCustomData:");
printPrefix (fp, "CD_", t[i].oCustData);
fprintf (fp, "\n");
}
fprintf (fp,"\t");
if (t[i].res18 != 0)
fprintf (fp, "res18:%d != 0, ",t[i].res18);
if (t[i].res19 != -1)
fprintf (fp, "res19:%d != -1, ",t[i].res19);
fprintf (fp, "VirtualTableSize+Inherits:%d,TypeSize:%d,OffsetTDT|BI|COC|INTF:0x%x\n"
"\t#InheritFuncts:%d,unkown:%d\n",
t[i].cbSizeVft,t[i].size,t[i].datatype1,
(t[i].datatype2 >> 16)&0xffff, t[i].datatype2 & 0xffff);
if (t[i].memoffset > 0 && t[i].memoffset < size)
dumpMem (fp, dta + t[i].memoffset,&umap[t[i].memoffset],
(t[i].cElement>>16)&0xfff,t[i].cElement&0xfff);
dumpMemInfo (fp, dta + t[i].memoffset,(t[i].cElement>>16)&0xfff,t[i].cElement&0xfff,
t[i].typekind & 0xf);
}
}
static void
dumpMemInfo (FILE *fp, unsigned char *dta, uint32_t cVar, uint32_t cFunc, uint32_t tkind)
{
uint32_t off = 0;
int32_t max = cVar + cFunc;
sMSFT_memblob *b;
sMSFT_func *func;
sMSFT_var *var;
uint32_t *d;
if (!cVar && !cFunc)
return;
b = (sMSFT_memblob *) dta;
d = (uint32_t *) &b->dta[b->size];
while (off < b->size)
{
if (cFunc)
{
sMSFT_FuncParam *params;
uint32_t oVars, *pData , *pCustData;
int32_t c,cc;
char *rettyp = NULL;
char *fctname = NULL;
func = (sMSFT_func *) &b->dta[off];
c = func->nrArgs;
oVars = func->rlen;
oVars -= (c * 12);
params = (sMSFT_FuncParam *) &b->dta[off+oVars];
pData = func->data;
pCustData = NULL;
if (func->f.hasParamDefValue)
pCustData = (uint32_t *) &b->dta[off+oVars-c*4];
off += func->rlen;
fprintf (fp, " #%u:", func->id);
fprintf (fp, " oVTable:0x%x FuncDescSize:0x%x #Args:%u,#OptArgs:%u\n",
func->vtableOffset,func->funcdescSize,func->nrArgs,func->nrOptArgs);
fprintf (fp, "\t invokekind:%s nextIndexWithSameID:%u",
getInvokeKindName(func->f.invokeKind),
func->f.nextIndexWithSameID
);
fprintf (fp, ", Offset:0x%x\n", d[max*2]);
rettyp = TI_getVTorDref (&ti2_typs, func->datatype, "", 0);
fctname = TI_get_typ_name (&ti2_typs, d[max], TITYP_NAME, "");
if (d[0] < 0x100)
fprintf (fp, "\t[id(%u)", d[0]);
else
fprintf (fp, "\t[id(0x%x)", d[0]);
printFuncFlags (fp, func->flags);
while ((char*) pData < (char *) params
&& (!pCustData || ((char*) pData < (char*) pCustData)))
{
int32_t jj;
fprintf (fp, "\t");
for (jj=0;jj<8 && (char*) pData < (char *) params
&& (!pCustData || ((char*)pData < (char*) pCustData)); jj++,pData++)
{
fprintf (fp, "%s0x%x", (jj== 0 ? "" : ", "), *pData);
}
fprintf (fp,"\n");
}
fprintf (fp, "%s%s%s%s%s",
func->f.hasCustomData ? " customData" : "",
func->f.hasParamDefValue ? " paramDefValue" : "",
func->f.isOEntryNumeric ? " oEntryNumeric" : "",
func->f.hasRetvalParam ? " retvalParam" : "",
func->f.reserved1 ? " reserved1" : "");
fprintf (fp, "]\n");
fprintf (fp, "\t%s %s %s %s (",
rettyp,
getFunkKindName (func->f.funcKind),
getCallConvName (func->f.callconv),
fctname);
free (rettyp);
free (fctname);
for (cc=0;cc< c;cc++)
{
char *x, *n;
if (params[cc].oName == -1)
n = strdup ("");
else
n = TI_get_typ_name (&ti2_typs, (uint32_t) params[cc].oName, TITYP_NAME, "");
x = TI_getVTorDref (&ti2_typs,params[cc].dataType, n, 0);
free (n);
fprintf(fp,"[%s] %s",getParamFlagName(params[cc].flags), x);
free (x);
if (pCustData && (params[cc].flags & PARAMFLAG_FHASDEFAULT) != 0)
{
fprintf (fp," = ");
printValue(fp, &ti2_typs, pCustData[cc]);
}
if ((cc+1)!=c)
{
fprintf (fp, ",");
if ((cc&1)!=0)
fprintf(fp, "\n\t ");
}
}
if (c == 0)
fprintf (fp, "void");
fprintf (fp, ");\n");
--cFunc;
}
else if (cVar)
{
char *varType,*varName;
cVar--;
var = (sMSFT_var *) &b->dta[off];
off += var->rlen;
fprintf (fp, " #%u:", var->id);
fprintf (fp, "\n\tvarKind:0x%x vardescSize:0x%x",var->varKind, var->vardescSize);
fprintf (fp, ", Offset:0x%x\n", d[max*2]);
varName = TI_get_typ_name (&ti2_typs, d[max], TITYP_NAME, "");
varType = TI_getVTorDref (&ti2_typs,var->datatype, varName, 0);
free (varName);
if (d[0] < 0x100)
fprintf (fp, "\t[id(%u)", d[0]);
else
fprintf (fp, "\t[id(0x%x)", d[0]);
printVarflags (fp, var->flags);
fprintf (fp, "] %s", varType);
free (varType);
if (var->varKind == tkind)
{
fprintf (fp, " = ");
printValue (fp, &ti2_typs, var->oValue);
}
fprintf (fp,";\n");
}
else
return;
d++;
}
}
static void
dumpMem (FILE *fp, unsigned char *dta, unsigned char *umap, uint32_t cVar, uint32_t cFunc)
{
uint32_t off;
unsigned char *d = dta;
uint32_t oData1, oData2;
if (fp)
oData1 = 0;
if (!cVar && !cFunc)
return;
oData1 = ((uint32_t *) d)[0];
umap[4]=3;
umap[4+(oData1&0xffff)]=3;
off = 0;
d += 4;
while (off < oData1)
{
oData2 = ((uint32_t *) d)[0];
d+= (oData2 & 0xffff);
off+=oData2 & 0xffff;
umap[(d-dta)]=3;
}
}
/*
default_type = 0x80000000 | (vt << 16) | vt;
VT_LPSTR = 30,
VT_LPWSTR = 31,
case VT_LPSTR:
case VT_LPWSTR:
*encoded_type = 0xfffe0000 | vt;
VT_BYREF VT_PTR
VT_USERDEFINED
VT_SAFEARRAY
kind: 0x1a 26 == VT_PTR
base-vt16: vt: if (0x80000000) -> vt + base-vt16
base-vt16 if (!0x80000000) -> TypeD(vt&0xffff)
0x7fff -> TypeD(vt&0xffff)
0x7ffe -> vt&0xffff
kind: 0x1b 27 == SAFEARRAY
kind: 0x1c 28 == VT_CARRAY
0x7ffe -> ArrayD(vt&0xffff)
kind: 0x1d 29 == VT_USERDEFINED
0x7fff -> (if !(vt&1) TypeB (vt&0xffff)
if (vt&1) Imp (vt&0xfffe)
$$$$ */
static void
dumpTypedesc (FILE *fp, unsigned char *d, uint32_t len)
{
sMSFT_TypeDesc *p;
uint32_t off = 0;
if (!len)
return;
fprintf (fp, "Type Description\n");
while ((off + 7) < len)
{
p = (sMSFT_TypeDesc *) &d[off];
fprintf (fp, " ");
printPrefix2 (fp, "TypeD_", (int32_t) off);
fprintf (fp, ": kind:0x%x, flags:0x%x, vt:0x%x, ",p->kind, p->flag, p->vt);
switch ((p->kind))
{
case 26: /* VT_PTR */
if ((p->vt & 0x80000000) != 0)
{
printVT (fp, ((uint32_t) p->vt) & 0xffff, NULL);
if ((p->flag & 0x7fff) != 0x7ffe)
fprintf (fp, " *");
}
else
{
if ((p->oTypeB & 1) != 0)
printPrefix (fp, "ImpI_", p->oTypeB & 0xfffffffe);
else
printPrefix (fp, "TypeD_", p->oTypeB);
if ((p->flag & 0x7fff) != 0x7ffe)
fprintf (fp, " *");
}
break;
case 27: /* SAFEARRAY */
if ((p->vt & 0x80000000) != 0)
{
printVT (fp, ((uint32_t) p->vt) & 0xffff, NULL);
if ((p->flag & 0x7fff) != 0x7ffe)
fprintf (fp, " []");
}
else
{
if ((p->oTypeB & 1) != 0)
printPrefix (fp, "ImpI_", p->oTypeB & 0xfffffffe);
else
printPrefix (fp, "TypeD_", p->oTypeB);
if ((p->flag & 0x7fff) != 0x7ffe)
fprintf (fp, " []");
}
break;
case 28: /* VT_CARRAY */
printPrefix (fp, "ArrayD_", p->oArrayD & 0xffff);
break;
case 29: /* VT_USERDEFINED */
if ((p->vt & 0x80000000) != 0)
{
printVT (fp, ((uint32_t) p->vt) & 0xffff, NULL);
}
else
{
if ((p->oTypeB & 1) != 0)
printPrefix (fp, "ImpI_", p->oTypeB & 0xfffffffe);
else
printPrefix (fp, "TypeB_", p->oTypeB);
}
break;
default:
fprintf (fp, " !!!");
printVT (fp, (((uint32_t) (p->vt)) & 0xffff), NULL);
if ((p->flag & 0xf000) == 0x4000)
fprintf (fp, " *");
break;
}
off += 8;
fprintf (fp, "\n");
}
}
static void
dumpImpFile (FILE *fp, unsigned char *segImp, uint32_t length, int32_t importinfos)
{
MSFT_ImpInfo *p;
uint32_t off = 0;
if (!length)
return;
fprintf (fp, "ImportFile Information. Has %d Import Files\n", importinfos);
while ((off + 11) < length)
{
p=(MSFT_ImpInfo *) &segImp[off];
fprintf (fp, " ");
printPrefix (fp, "ImpI_", (int) off);
fprintf (fp, ": count:%d, flags:0x%x, tkind:%s, ",
p->count, p->flags, getTKindName(p->tkind));
printPrefix2 (fp, "Imp_", p->oImpFile);
fprintf(fp, ", ");
printPrefix2 (fp, ((p->flags & 0x1) != 0 ? "Guid_" : "TypeB_"), p->oGuid);
fprintf(fp, "\n");
off += 12;
}
}
static void
dumpArrayDesc (FILE *fp, unsigned char *d, uint32_t len)
{
uint32_t off = 0;
sMSFT_ArrayDesc *p;
if (!len)
return;
fprintf (fp, "Array Description\n");
while ((off + 7) < len)
{
int i;
p = (sMSFT_ArrayDesc *) &d[off];
fprintf (fp, " ");
printPrefix (fp, "ArrayD_", (int) off);
fprintf (fp, ": vt:(0x%x)",p->vt);
printVT (fp, p->vt >> 16, NULL);
off += 8;
fprintf (fp,", %u (%d bytes)", p->count, p->size);
for (i=0;i<p->count;i++)
fprintf (fp, ",[%u]", p->vt_offset[i*2]);
off += p->size;
off +=3; off &= ~3;
fprintf (fp,"\n");
}
}
static void
dumpImpFiles (FILE *fp, unsigned char *d, uint32_t len)
{
sMSFT_ImpFiles *p;
uint32_t off = 0;
if (!len)
return;
fprintf (fp, "Import Files\n");
while ((off + 13) < len)
{
uint16_t l;
p = (sMSFT_ImpFiles *) &d[off];
fprintf (fp, " ");
printPrefix (fp, "Imp_", (int) off);
off+=14;
l = (p->flag >> 2);
fprintf (fp, ": %d,%d,%d, flag:%u, \"",
p->res1,p->res2,p->res3, (p->flag & 3));
while (l > 0 && off < len)
{
if (d[off] >=0x20 && d[off] <= 0x7f)
fprintf (fp,"%c", d[off++]);
else
fprintf (fp,"\\%03o", d[off++]);
--l;
}
fprintf (fp, "\"\n");
off += 3;
off &= ~3;
}
}
static void
dumpRefTab (FILE *fp, unsigned char *d, uint32_t len)
{
sMSFT_RefTab *p;
uint32_t off = 0;
if (!len)
return;
fprintf (fp, "Reference Table\n");
while ((off + 15) < len)
{
p = (sMSFT_RefTab *) & d[off];
fprintf (fp, " ");
printPrefix (fp, "Ref_", (int) off);
fprintf (fp,": ");
printPrefix (fp, "TypeB_", p->oData1);
fprintf (fp,", %d, %d, ",p->no, p->data2);
printPrefix (fp, "Ref_", p->oNextRef);
fprintf (fp, "\n");
off += sizeof (sMSFT_RefTab);
}
}
static void
dumpName (FILE *fp, unsigned char *segName, uint32_t len)
{
struct sMSFTNamePrologue {
int32_t res1;
int32_t res2;
#ifdef __GNUC__
__extension__
#endif
union {
unsigned char v[4];
uint16_t us[2];
};
};
#ifdef __GNUC__
__extension__
#endif
union {
unsigned char *dta;
struct sMSFTNamePrologue *p;
} v;
uint32_t off = 0;
if (!len)
return;
fprintf (fp,"NameTable\n");
while ((off + 12) < len)
{
unsigned char l;
v.dta=&segName[off];
fprintf (fp, " Name_%x", (int32_t) off);
fprintf (fp, ": %d,",v.p->res1);
printPrefix (fp,"Name_", v.p->res2);
fprintf (fp, ", 0x%02x,0x%04x, \"", v.p->v[1], v.p->us[1]);
l = v.p->v[0];
off += 12;
while (l > 0)
{
if (segName[off]>=0x20 && segName[off]<=0x7f)
fprintf (fp, "%c", segName[off++]);
else
fprintf (fp, "\\%03o", segName[off++]);
--l;
}
off = (off + 3) & ~3;
fprintf (fp,"\"\n");
}
}
static void
dumpGuid (FILE *fp, unsigned char *d, uint32_t length)
{
uint32_t off = 0;
struct sGuidTab {
uint32_t data1;
uint16_t data2[2];
unsigned char data3[8];
int32_t res1;
int32_t res2; /* Forwarder GUID */
};
union {
unsigned char *d;
struct sGuidTab *g;
} v;
if (length==0)
return;
fprintf (fp,"GuidTab:\n");
while ((off + 24) <= length)
{
fprintf (fp," ");
printPrefix2 (fp, "Guid_", (int32_t) off);
fprintf (fp,": ");
v.d = &d[off];
fprintf (fp,"%d,",v.g->res1);
printPrefix2 (fp, "Guid_", v.g->res2);
fprintf (fp,", \"%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\"\n",
v.g->data1, v.g->data2[0], v.g->data2[1],
v.g->data3[0],v.g->data3[1],v.g->data3[2],v.g->data3[3],
v.g->data3[4],v.g->data3[5],v.g->data3[6],v.g->data3[7]);
off += 24;
}
if (length != off)
fprintf (fp," Junk at end of %u bytes\n", (length-off));
}
static void
dumpCustomDataGuid (FILE *fp, unsigned char *d, uint32_t len)
{
uint32_t off = 0;
sMSFT_CDGuid *p;
if(!len)
return;
fprintf (fp, "CustomData GUIDs\n");
while ((off + 11) < len)
{
p = (sMSFT_CDGuid *) &d[off];
fprintf(fp," ");
printPrefix2 (fp, "CDGuid_", (int) off);
fprintf (fp, ": ");
printPrefix (fp, "Guid_", p->oGuid);
fprintf (fp,", ");
printValue (fp, &ti2_typs, p->oData);
fprintf (fp,", ");
printPrefix (fp, "CDGuid_", p->next);
fprintf (fp,"\n");
off += 12;
}
}
static void
dumpCustomData (FILE *fp, unsigned char *d, uint32_t len)
{
sMSFT_CustomData *p;
uint32_t off = 0;
if (!len)
return;
fprintf (fp, "CustomData\n");
while (off < len)
{
p = (sMSFT_CustomData *) &d[off];
fprintf (fp, " ");
printPrefix2 (fp, "CD_", (int32_t) off);
fprintf (fp, ": ");
off += printVT (fp,p->vt,p->dta) - 2;
off = (off + 3) & ~3;
fprintf (fp, "\n");
}
}
static void
dumpString (FILE *fp, unsigned char *segString, uint32_t length)
{
uint32_t off = 0;
uint16_t len;
union {
unsigned char *dta;
uint16_t *len;
} v;
if (!length)
return;
fprintf (fp,"StringTable\n");
while ((off + 2) < length)
{
v.dta=&segString[off];
len = v.len[0];
fprintf (fp," ");
printPrefix2 (fp, "Str_", (int) off);
fprintf (fp,": \"");
off+=2;
while (len > 0)
{
if (segString[off]>=0x20 && segString[off]<=0x7f)
fprintf (fp, "%c", segString[off++]);
else
fprintf (fp, "\\%03o", segString[off++]);
--len;
}
fprintf(fp,"\"\n");
off = (off + 3)&~3;
}
}
void
dumpHexFp (FILE *fp, size_t off, const unsigned char *dta, size_t len)
{
size_t i,k;
char s[17];
if (!len || !fp)
return;
for (i = 0; i < len;)
{
fprintf (fp, "0x%08x:", (uint32_t) (off + i));
for (k=0; i < len && k < 16;k++,i++)
{
fprintf (fp, " %02X", dta[i]);
if (dta[i] >= 0x20 && dta[i]<=0x7f)
s[k]=(char) dta[i];
else
s[k]='.';
s[k+1]=0;
}
fprintf (fp, " ; %s\n",s);
}
}
void
dumpDecFp (FILE *fp, const unsigned char *dta, size_t len, const char *prefix)
{
size_t i,j;
if (!len)
return;
if ((len&3)!=0)
fprintf (fp, "Has not 4 byte alignment!\n");
len = (len & ~3);
for (i = 0; i < len;)
{
fprintf (fp,"0x%x:", (uint32_t) (i/4));
for (j=0;j< 4 && i < len;j++,i+=4)
{
fprintf (fp, "%s", (j == 0 ? " " : ","));
printPrefix2 (fp, prefix ? prefix : "0x", *((const int32_t *) &dta[i]));
}
fprintf (fp,"\n");
}
}
void
printPrefix2 (FILE *fp, const char *name, int32_t val)
{
if (!name)
name = "";
if (val <= -1)
fprintf (fp, "%d", val);
else
fprintf (fp, "%s%x", name, val);
}
void
printPrefix (FILE *fp, const char *name, int32_t val)
{
if (!name)
name = "";
if (val <= -1)
fprintf (fp, "%d", val);
else
{
char *nam = NULL;
if (!strcmp (name, "Name_"))
nam = TI_get_typ_name (&ti2_typs, (uint32_t) val, TITYP_NAME, "");
else if (!strcmp (name, "Str_"))
{
nam = TI_get_typ_name (&ti2_typs, (uint32_t) val, TITYP_STR, "");
if (nam)
{
fprintf (fp, "\"%s\"", nam);
free (nam);
return;
}
}
else if (!strcmp (name, "Guid_"))
{
nam = TI_get_typ_name (&ti2_typs, (uint32_t) val, TITYP_GUIDS, "");
}
else if (!strcmp (name, "TypeB_"))
nam = TI_get_typ_name (&ti2_typs, (uint32_t) val, TITYP_TYPINFO_NAMES, "");
else if (!strcmp (name, "TypeD_"))
nam = TI_get_typ_name (&ti2_typs, (uint32_t) val, TITYP_DEREF, "");
else if (!strcmp (name, "CD_"))
nam = TI_get_typ_name (&ti2_typs, (uint32_t) val, TITYP_CUSTOMDATA, "");
if (nam)
{
fprintf (fp,"%s",nam);
free (nam);
}
else
printPrefix2 (fp, name, val);
}
}
static const char *
getVTTypeName (uint32_t vt, uint32_t *dataSize)
{
static char str[128];
const char *name = "";
uint32_t sz = 0;
switch ((vt&0xfff))
{
case 0: /* VT_EMPTY */ name = "EMPTY"; break;
case 1: /* VT_NULL */ name = "NULL"; break;
case 2: /* VT_I2 */ name = "short"; sz=2; break;
case 3: /* VT_I4 */ name = "long"; sz=4; break;
case 4: /* VT_R4 */ name = "FLOAT"; sz=4; break;
case 5: /* VT_R8 */ name = "DOUBLE"; sz=8; break;
case 6: /* VT_CY */ name = "CY"; sz=8; break;
case 7: /* VT_DATE */ name = "DATE"; sz = 0xffffffff; break;
case 8: /* VT_BSTR */ name = "BSTR"; sz = 0xfffffffe; break;
case 9: /* VT_DISPATCH */ name = "IDispatch *"; sz = 0xffffffff; break;
case 10: /* VT_ERROR */ name = "SCODE"; sz = 4; break;
case 11: /* VT_BOOL */ name = "WINBOOL"; sz = 2; break;
case 12: /* VT_VARIANT */ name = "VARIANT"; sz = 0xffffffff; break;
case 13: /* VT_UNKNOWN */ name = "IUnknown *"; sz = 0xffffffff; break;
case 14: /* VT_DECIMAL */ name = "DECIMAL"; sz = 16; break;
case 16: /* VT_I1 */ name = "CHAR"; sz=1; break;
case 17: /* VT_UI1 */ name = "UCHAR"; sz=1; break;
case 18: /* VT_UI2 */ name = "USHORT"; sz=2; break;
case 19: /* VT_UI4 */ name = "UINT"; sz=4; break;
case 20: /* VT_I8 */ name = "LONGLONG"; sz=8; break;
case 21: /* VT_UI8 */ name = "ULONGLONG"; sz=8; break;
case 22: /* VT_INT */ name = "int"; sz=4; break;
case 23: /* VT_UINT */ name = "unsigned int"; sz=4; break;
case 24: /* VT_VOID */ name = "VOID"; sz=0; break;
case 25: /* VT_HRESULT */ name = "HRESULT"; sz = 4; break;
case 26: /* VT_PTR */ name = "PTR"; sz = 4; break;
case 27: /* VT_SAFEARRAY */ name = "SAFEARRAY"; sz = 0xfffffffe; break;
case 28: /* VT_CARRAY */ name = "CARRAY"; sz = 0xfffffffe; break;
case 29: /* VT_USERDEFINED */ name = "USERDEFINED"; sz = 0xfffffffe; break;
case 30: /* VT_LPSTR */ name = "LPSTR"; sz = 4; break;
case 31: /* VT_LPWSTR */ name = "LPWSTR"; sz = 4; break;
case 36: /* VT_RECORD */ name = "RECORD"; sz = 0xfffffffe; break;
case 37: /* VT_INT_PTR */ name = "INT_PTR"; sz=4; break;
case 38: /* VT_UINT_PTR */ name = "UINT_PTR"; sz = 4; break;
case 64: /* VT_FILETIME */ name = "FILETIME"; sz = 8; break;
case 65: /* VT_BLOB */ name = "BLOB"; sz = 0xfffffffe; /* Has 4 bytes size */ break;
case 66: /* VT_STREAM */ name = "STREAM"; sz = 0xffffffff; break;
case 67: /* VT_STORAGE */ name = "STORAGE"; sz = 0xffffffff; break;
case 68: /* VT_STREAMED_OBJECT */ name = "STREAMED_OBJECT"; sz = 0xfffffffe; break;
case 69: /* VT_STORED_OBJECT */ name = "STORED_OBJECT"; sz = 0xffffffff; break;
case 70: /* VT_BLOB_OBJECT */ name = "BLOB_OBJECT"; sz = 0xfffffffe; break;
case 71: /* VT_CF*/ name = "CF"; sz = 0xfffffffe; break;
case 72: /* VT_CLSID */ name = "CLSID";sz = 0xfffffffe; break;
case 73: /* VT_VERSIONED_STREAM */ name = "VERSIONED_STREAM";sz = 0xfffffffe; break;
case 0xfff: /* VT_BSTR_BLOB */ name = "BSTR_BLOB"; sz = 0xfffffffe; break;
default:
sprintf (str, "VT_%08x", vt & 0xfff);
name = &str[0]; sz = 0xffffffff;
break;
}
if ((vt &0xf000) == 0x4000)
sprintf (str, " *");
if (dataSize)
*dataSize = sz;
return name;
}
uint32_t
printVT (FILE *fp, uint32_t vt, unsigned char *dta)
{
uint32_t sz = 0;
fprintf (fp, "%s", getVTTypeName (vt, &sz));
if ((vt & 0x1000)!=0)
fprintf (fp, " vector");
if ((vt & 0x2000)!=0)
fprintf (fp, " array");
if ((vt & 0x4000)!=0)
fprintf (fp, " byref");
if ((vt & 0xf000)!=0)
return 4;
if (!dta)
return sz + 4;
if (sz == 0xfffffffe)
{
sz = *((uint32_t *) dta);
printVTData (fp, vt & 0x7ff, &dta[4], sz);
sz += 4;
}
else
printVTData (fp, vt & 0x7ff, dta, sz);
sz += 4;
return sz;
}
void
printVTData (FILE * fp,uint32_t vt, unsigned char *dta, uint32_t sz)
{
if (!sz && vt != 8)
return;
switch (vt) {
case 16: /* VT_I1 */ fprintf (fp," = %d", *((char *) dta)); break;
case 17: /* VT_UI1 */ fprintf (fp," = %u", *((unsigned char *) dta)); break;
case 18: /* VT_UI2 */ fprintf (fp," = %u", *((uint16_t *) dta)); break;
case 23: /* VT_UINT */
case 19: /* VT_UI4 */ fprintf (fp," = %uU", *((uint32_t *) dta)); break;
case 20: /* VT_I8 */
#ifdef _WIN32
fprintf (fp," = %I64dLL", *((int64_t *) dta)); break;
#else
fprintf (fp," = %lldLL", *((int64_t *) dta)); break;
#endif
case 21: /* VT_UI8 */
#ifdef _WIN32
fprintf (fp," = %I64uULL", *((uint64_t *) dta)); break;
#else
fprintf (fp," = %lluULL", *((uint64_t *) dta)); break;
#endif
case 10: /* VT_ERROR */
fprintf (fp, " = (SCODE) %dL", *((int32_t *) dta)); break;
case 11: /* VT_BOOL */
case 2: /* VT_I2 */ fprintf (fp," = %d", *((int16_t *) dta)); break;
case 22: /* VT_INT */
case 3: /* VT_I4 */ fprintf (fp," = %d", *((int32_t *) dta)); break;
case 4: /* VT_R4 */ fprintf (fp," = %f", *((float *) dta)); break;
case 5: /* VT_R8 */ fprintf (fp," = %g", *((double *) dta)); break;
case 6: /* VT_CY */
#ifdef _WIN32
fprintf (fp," = %I64dLL", *((int64_t *) dta)); break;
#else
fprintf (fp," = %lldLL", *((int64_t *) dta)); break;
#endif
case 8: /* VT_BSTR */
fprintf (fp," = \"");
while (sz>0)
{
if (*dta >= 0x20 && *dta <= 0x7f)
fprintf (fp, "%c", *dta);
else
fprintf (fp,"\\%03o", *dta);
dta++; --sz;
}
fprintf (fp,"\"");
break;
case 25: /* VT_HRESULT */
case 26: /* VT_PTR */
fprintf (fp," = 0x%x", *((int *) dta)); break;
default:
break;
}
}
const char *
getInvokeKindName (int32_t ikind)
{
static char name[260];
const char *ret;
name[0] = 0;
if ((ikind & INVOKIND_FUNC) != 0)
strcat (name," function");
if ((ikind & INVOKIND_PROPERTYGET) != 0)
strcat (name," propertyget");
if ((ikind & INVOKIND_PROPERTYPUT)!=0)
strcat (name, " propertyput");
if ((ikind & INVOKIND_PROPERTYPUTREF)!=0)
strcat (name, " propertyputref");
if ((ikind & ~0xf)!=0)
sprintf (name + strlen (name)," | 0x%x",ikind & ~0xf);
ret = &name[0];
if (*ret == ' ')
ret++;
return ret;
}
const char *
getFunkKindName (int32_t fkind)
{
static char name[260];
const char *ret;
switch (fkind)
{
case FUNCTKIND_VIRTUAL: ret = "virtual"; break;
case FUNCTKIND_PUREVIRTUAL: ret = "pure virtual"; break;
case FUNCTKIND_NONVIRTUAL: ret = ""; break;
case FUNCTKIND_STATIC: ret = "static"; break;
case FUNCTKIND_DISPATCH: ret = "dispatch"; break;
default:
sprintf (name, "FunkKind_%d", fkind);
ret = &name[0];
break;
}
return ret;
}
const char *
getCallConvName (int32_t cc)
{
static char name[260];
const char *ret = &name[0];
switch (cc) {
case CALLCONV_FASTCALL: ret = "__fastcall"; break;
case CALLCONV_CDECL: ret = "__cdecl"; break;
case CALLCONV_PASCAL: ret = "__pascal"; break;
case CALLCONV_MACPASCAL: ret = "__macpascal"; break;
case CALLCONV_STDCALL: ret = "__stdcall"; break;
case CALLCONV_FPFASTCALL: ret = "__fpfastcall"; break;
case CALLCONV_SYSCALL: ret = "__syscall"; break;
case CALLCONV_MPWCDECL: ret = "__mpwcdecl"; break;
case CALLCONV_MPWPASCAL: ret = "__mpwpascal"; break;
default:
sprintf (name, "CC_%d", cc);
break;
}
return ret;
}
const char *
getParamFlagName (uint32_t pflag)
{
static char name[260];
const char *ret = &name[0];
name[0]=0;
if ((pflag&PARAMFLAG_FIN)!=0)
strcat (name, " IN");
if ((pflag&PARAMFLAG_FOUT)!=0)
strcat (name, " OUT");
if ((pflag&4)!=0)
strcat (name, " | 4");
if ((pflag &PARAMFLAG_FRETVAL)!=0)
strcat (name," RETVAL");
if ((pflag & PARAMFLAG_FOPT)!=0)
strcat (name, " OPT");
if ((pflag & PARAMFLAG_FHASDEFAULT)!=0)
strcat (name, " DEFAULT");
if ((pflag & ~0x3f)!=0)
sprintf (name + strlen(name)," | 0x%x", pflag & ~0x3f);
return ret;
}
void
printValue (FILE *fp, sTITyps *typs, uint32_t val)
{
if ((val & 0x80000000) != 0)
{
union {
long long i8;
unsigned long long ui8;
uint32_t ui4;
int32_t i4;
int16_t i2;
uint16_t ui2;
char i1;
unsigned char ui1;
float f4;
double f8;
} u;
uint32_t vt = (val >> 26) & 0x1f;
u.ui4 = val & 0x3fffffff;
switch (vt)
{
case 0: case 1:
break;
case 2: /* VT_I2 */
if (abs ((int) u.i2) < 0x100)
fprintf (fp, "(short) %d", u.i2);
else if (u.i2 < 0)
fprintf (fp, "(short) -0x%x", -u.i2);
else
fprintf (fp, "(short) 0x%x", u.i2);
break;
case 22: /* VT_INT */
case 3: /* VT_I4 */
if (abs (u.i4) < 0x100)
fprintf (fp, "(int) %d", u.i4);
else if (u.i4 < 0)
fprintf (fp, "(int) -0x%x", -u.i4);
else
fprintf (fp, "(int) 0x%x", u.i4);
break;
case 4: /* VT_R4 */
fprintf (fp, "(float) %g", u.f4); break;
case 5: /* VT_R8 */
fprintf (fp, "(double) %g", u.f8); break;
case 6: /* VT_CY */
fprintf (fp, "(CY) 0x%x", u.ui4); break;
case 7: /* VT_DATE */
fprintf (fp, "(DATE) 0x%x", u.ui4); break;
case 8: /* VT_BSTR */
fprintf (fp, "(BSTR) 0x%x", u.ui4); break;
case 9: /* VT_DISPATCH */
fprintf (fp, "(IDispatch *) 0x%x", u.ui4); break;
case 10: /* VT_ERROR */
fprintf (fp, "(SCODE) %d", u.i4); break;
case 11: /* VT_BOOL */
fprintf (fp, "(WINBOOL) %d", u.i2); break;
case 12: /* VT_VARIANT */
fprintf (fp, "(VARIANT) 0x%x", u.ui4); break;
case 13: /* VT_UNKNOWN */
fprintf (fp, "(IUnknown *) 0x%x", u.ui4); break;
case 14: /* VT_DECIMAL */
fprintf (fp, "(DECIMAL) 0x%x", u.ui4); break;
case 16: /* VT_I1 */
fprintf (fp, "(CHAR) %d", u.i1); break;
case 17: /* VT_UI1 */
fprintf (fp, "(UCHAR) 0x%x", u.ui1); break;
case 18: /* VT_UI2 */
fprintf (fp, "(USHORT) 0x%x", u.ui2); break;
case 19: /* VT_UI4 */
fprintf (fp, "(UINT) 0x%xU", u.ui4); break;
case 20: /* VT_I8 */
#ifdef _WIN32
fprintf (fp, "(LONGLONG) %I64dLL", u.i8); break;
#else
fprintf (fp, "(LONGLONG) %lldLL", u.i8); break;
#endif
case 21: /* VT_UI8 */
#ifdef _WIN32
fprintf (fp, "(ULONGLONG) 0x%I64xULL", u.ui8); break;
#else
fprintf (fp, "(ULONGLONG) 0x%llxULL", u.ui8); break;
#endif
case 23: /* VT_UINT */
fprintf (fp, "(unsigned int) 0x%xU", u.ui4); break;
case 24: /* VT_VOID */
break;
case 25: /* VT_HRESULT */
fprintf (fp, "(HRESULT) %dL", u.i4); break;
case 26: /* VT_PTR */
fprintf (fp, "(void *) %u", u.ui4); break;
case 27: /* VT_SAFEARRAY */
fprintf (fp, "(SAFEARRAY) %u", u.ui4); break;
case 28: /* VT_CARRAY */
fprintf (fp, "(CARRAY) %u", u.ui4); break;
case 29: /* VT_USERDEFINED */
fprintf (fp, "%u", u.ui4); break;
case 30: /* VT_LPSTR */
fprintf (fp, "(LPSTR) %u", u.ui4); break;
case 31: /* VT_LPWSTR */
fprintf (fp, "(LPWSTR) %u", u.ui4); break;
}
}
else
{
char *h = NULL;
h = TI_get_typ_name (typs, (uint32_t) val, TITYP_CUSTOMDATA,"");
if (h)
{
fprintf (fp, "%s", h);
free (h);
}
else
fprintf (fp, "CD_%x", val);
}
}
const char *
getTKindName (uint32_t tkind)
{
static char name[260];
const char *ret = &name[0];
switch (tkind)
{
case TKIND_ENUM: ret = "enum"; break;
case TKIND_RECORD: return "struct"; break;
case TKIND_MODULE: return "module"; break;
case TKIND_INTERFACE: return "interface"; break;
case TKIND_DISPATCH: return "dispatch"; break;
case TKIND_COCLASS: return "coclass"; break;
case TKIND_ALIAS: return "alias"; break;
case TKIND_UNION: return "union"; break;
default:
sprintf (name,"TKIND_%u", tkind);
break;
}
return ret;
}
void
printVarflags (FILE *fp, uint32_t flags)
{
if (!flags)
return;
if ((flags & VARFLAG_FREADONLY)!=0)
fprintf (fp, " readonly");
if ((flags & VARFLAG_FSOURCE) != 0)
fprintf (fp, " source");
if ((flags & VARFLAG_FBINDABLE) != 0)
fprintf (fp, " bindable");
if ((flags & VARFLAG_FREQUESTEDIT)!=0)
fprintf (fp, " requestedit");
if ((flags & VARFLAG_FDISPLAYBIND)!=0)
fprintf (fp, " displaybind");
if ((flags & VARFLAG_FDEFAULTBIND)!=0)
fprintf (fp, " defaultbind");
if ((flags & VARFLAG_FHIDDEN)!=0)
fprintf (fp, " hidden");
if ((flags & VARFLAG_FRESTRICTED)!=0)
fprintf (fp, " restricted");
if ((flags & VARFLAG_FDEFAULTCOLLELEM)!=0)
fprintf (fp, " defaultcollelem");
if ((flags & VARFLAG_FUIDEFAULT)!=0)
fprintf (fp, " uidefault");
if ((flags & VARFLAG_FNONBROWSABLE)!=0)
fprintf (fp, " nonbrowsable");
if ((flags & VARFLAG_FREPLACEABLE)!=0)
fprintf (fp, " replaceable");
if ((flags & VARFLAG_FIMMEDIATEBIND)!=0)
fprintf (fp, "immediatebind");
if ((flags & ~0x1fff)!=0)
fprintf (fp, " /* flags:0x%x */", (flags & ~0x1fff));
}
void
printFuncFlags (FILE *fp, uint32_t flags)
{
if ((flags & FUNCFLAG_FRESTRICTED) != 0)
fprintf (fp, " restricted");
if ((flags & FUNCFLAG_FSOURCE) != 0)
fprintf (fp, " source");
if ((flags & FUNCFLAG_FBINDABLE) != 0)
fprintf (fp, " bindable");
if ((flags & FUNCFLAG_FREQUESTEDIT) != 0)
fprintf (fp, " requestedit");
if ((flags & FUNCFLAG_FDISPLAYBIND) != 0)
fprintf (fp, " displaybind");
if ((flags & FUNCFLAG_FDEFAULTBIND) != 0)
fprintf (fp, " defaultbind");
if ((flags & FUNCFLAG_FHIDDEN) != 0)
fprintf (fp, " hidden");
if ((flags & FUNCFLAG_FUSESGETLASTERROR) != 0)
fprintf (fp, " usegetlasterror");
if ((flags & FUNCFLAG_FDEFAULTCOLLELEM) != 0)
fprintf (fp, " defaultcollelem");
if ((flags & FUNCFLAG_FUIDEFAULT) != 0)
fprintf (fp, " uidefault");
if ((flags & FUNCFLAG_FNONBROWSABLE) != 0)
fprintf (fp, " nobrowsable");
if ((flags & FUNCFLAG_FREPLACEABLE) != 0)
fprintf (fp, " replaceable");
if ((flags & FUNCFLAG_FIMMEDIATEBIND) != 0)
fprintf (fp, " immediatebind");
if ((flags & ~0x1fff)!=0)
fprintf (fp, " /* flags:0x%x */", (flags & ~0x1fff));
}
void
printTypFlags (FILE *fp, uint32_t flags)
{
const char *first = "";
if (flags!=0)
fprintf (fp,"[");
if ((flags & TYPEFLAG_FAPPOBJECT) != 0)
{ fprintf (fp, "%sappobject", first); first=" "; }
if ((flags & TYPEFLAG_FCANCREATE) != 0)
{ fprintf (fp, "%scancreate", first); first=" "; }
if ((flags & TYPEFLAG_FLICENSED) != 0)
{ fprintf (fp, "%slicensed", first); first=" "; }
if ((flags & TYPEFLAG_FPREDECLID) != 0)
{ fprintf (fp, "%spredclid", first); first=" "; }
if ((flags & TYPEFLAG_FHIDDEN) != 0)
{ fprintf (fp, "%shidden", first); first=" "; }
if ((flags & TYPEFLAG_FCONTROL) != 0)
{ fprintf (fp, "%scontrol", first); first=" "; }
if ((flags & TYPEFLAG_FDUAL) != 0)
{ fprintf (fp, "%sdual", first); first=" "; }
if ((flags & TYPEFLAG_FNONEXTENSIBLE) != 0)
{ fprintf (fp, "%snonextensible", first); first=" "; }
if ((flags & TYPEFLAG_FOLEAUTOMATION) != 0)
{ fprintf (fp, "%soleautomation", first); first=" "; }
if ((flags & TYPEFLAG_FRESTRICTED) != 0)
{ fprintf (fp, "%srestricted", first); first=" "; }
if ((flags & TYPEFLAG_FAGGREGATABLE) != 0)
{ fprintf (fp, "%saggregatable", first); first=" "; }
if ((flags & TYPEFLAG_FREPLACEABLE) != 0)
{ fprintf (fp, "%sreplaceable", first); first=" "; }
if ((flags & TYPEFLAG_FDISPATCHABLE) != 0)
{ fprintf (fp, "%sdispatchable", first); first=" "; }
if ((flags & TYPEFLAG_FREVERSEBIND) != 0)
{ fprintf (fp, "%sreversbind", first); first=" "; }
if ((flags & TYPEFLAG_FPROXY) != 0)
{ fprintf (fp, "%sproxy", first); first=" "; }
if ((flags & ~0x7fff)!=0)
fprintf (fp, " /* TYPFLAG:0x%x */", flags & ~0x7fff);
if (flags!=0)
fprintf (fp,"] ");
}