blob: 1fbed9abac761abe83a64f706de00bdacc894fa2 [file] [log] [blame]
/*
This Software is provided under the Zope Public License (ZPL) Version 2.1.
Copyright (c) 2009, 2010 by the mingw-w64 project
Written by Kai Tietz.
This license has been certified as open source. It has also been designated
as GPL compatible by the Free Software Foundation (FSF).
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions in source code must retain the accompanying copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the accompanying
copyright notice, this list of conditions, and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
3. Names of the copyright holders must not be used to endorse or promote
products derived from this software without prior written permission
from the copyright holders.
4. The right to distribute this software or to use it for any purpose does
not give you the right to use Servicemarks (sm) or Trademarks (tm) of
the copyright holders. Use of them is covered by separate agreement
with the copyright holders.
5. If any files are modified, you must cause the modified files to carry
prominent notices stating that you changed the files and the date of
any change.
Disclaimer
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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,"] ");
}