blob: 6619c4ef929d670258c03518f6bda5fefae722dd [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 "genidl_cfg.h"
#include "genidl_typeinfo.h"
#include "genidl_typinfo.h"
#include <malloc.h>
#include <string.h>
#include <memory.h>
int32_t
TI_init_typs (sTITyps *ptyp)
{
if (!ptyp)
return -1;
memset (ptyp, 0, sizeof (sTITyps));
return 0;
}
int32_t
TI_dest_typs (sTITyps *ptyp)
{
size_t i;
int32_t j;
if (!ptyp)
return -1;
for (j=0;j<TITYP_MAX;j++)
{
if (ptyp->buc[j].arr != NULL)
{
for (i = 0; i < ptyp->buc[j].count; i++)
{
if (ptyp->buc[j].arr[i]->refstr)
free (ptyp->buc[j].arr[i]->refstr);
if (ptyp->buc[j].arr[i]->poststr)
free (ptyp->buc[j].arr[i]->poststr);
free (ptyp->buc[j].arr[i]);
}
free (ptyp->buc[j].arr);
}
}
memset (ptyp, 0, sizeof (sTITyps));
return 0;
}
int32_t TI_add_typ (sTITyps *ptyp, uint32_t memid, int32_t kind, int32_t refkind, uint32_t refmem,
const char *refstr, const char *name, const char *poststr)
{
sTITyp *t, **h;
if (TI_get_typ (ptyp, memid, kind) != NULL || kind >= TITYP_MAX)
return -1;
if (!name)
name = "";
if (!refstr)
refstr="";
if (!poststr)
poststr = "";
if (ptyp->buc[kind].count >= ptyp->buc[kind].max)
{
h = (sTITyp **) malloc (sizeof (sTITyp *) * (ptyp->buc[kind].count + 32));
if (ptyp->buc[kind].arr)
{
memcpy (h, ptyp->buc[kind].arr, sizeof (sTITyp*) * ptyp->buc[kind].count);
free (ptyp->buc[kind].arr);
}
ptyp->buc[kind].arr = h;
ptyp->buc[kind].max += 32;
}
t = (sTITyp *) malloc (sizeof (sTITyp) + strlen (name));
t->memid = memid;
t->kind = kind;
t->refkind = refkind;
t->refmem = refmem;
t->refstr = strdup (refstr);
t->poststr = strdup (poststr);
strcpy (t->name, name);
ptyp->buc[kind].arr[ptyp->buc[kind].count] = t;
ptyp->buc[kind].count += 1;
return 0;
}
sTITyp *
TI_get_typ (sTITyps *ptyp, uint32_t memid, int32_t kind)
{
size_t i;
if (!ptyp || kind < 0 || kind >= TITYP_MAX)
return NULL;
for (i = 0; i < ptyp->buc[kind].count; i++)
{
if (ptyp->buc[kind].arr[i]->kind == kind && ptyp->buc[kind].arr[i]->memid == memid)
return ptyp->buc[kind].arr[i];
}
return NULL;
}
static char *
ti_cat (const char *t, const char *r)
{
char *ret;
size_t l;
if (!t)
t = "";
if (!r)
r = "";
l = strlen (t) + strlen (r) +1;
ret = (char *) malloc (l);
strcpy (ret, t);
strcat (ret, r);
return ret;
}
static char *
ti_cat_freel (char *t, const char *r)
{
char *ret = ti_cat (t, r);
if (t)
free (t);
return ret;
}
static int32_t
end_isref (const char *ret)
{
if (!ret || *ret == 0)
return 1;
ret += strlen (ret);
if (ret[-1] == '&' || ret[-1] == '*' || ret[-1] == ']')
return 1;
return 0;
}
char *
TI_get_typ_name (sTITyps *ptyp, uint32_t memid, int32_t kind, const char *varName)
{
static const char *szKind[TITYP_MAX] = {
"Name_", "Str_", "Guid_", "TypeB_", "TypeD_", "Arr_", "Ref_", "Imp_",
"Unknown_", "CD_", "CDGuid_", "ImpR_"
};
sTITyp *t = TI_get_typ (ptyp, memid, kind);
char s[128];
char *ret;
if (!t)
{
sprintf (s, "%s%x",szKind[kind],memid);
ret = strdup (s);
}
else if (t->name[0] == 0)
{
ret = TI_get_typ_name (ptyp, t->refmem, t->refkind, "");
}
else
ret = strdup (t->name);
if (t && t->refstr != NULL && t->refstr[0] != 0)
{
if (!end_isref (ret))
ret = ti_cat_freel (ret, " ");
ret = ti_cat_freel (ret, t->refstr);
}
if (varName != NULL && varName[0] != 0)
{
char *hl = strchr (ret, '[');
char *ar = NULL;
if (hl)
{
ar = strdup (hl);
*hl = 0;
}
if (!end_isref (ret))
ret = ti_cat_freel (ret, " ");
ret = ti_cat_freel (ret, varName);
if (ar)
{
ret = ti_cat_freel (ret, ar);
free (ar);
}
}
if (t && t->poststr != NULL && t->poststr[0] != 0)
{
if (!end_isref (ret) && t->poststr[0] != '[')
ret = ti_cat_freel (ret, " ");
ret = ti_cat_freel (ret, t->poststr);
}
return ret;
}
int32_t
TI2_import_name (sTITyps *nptr, unsigned char *dta, 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 0;
while ((off + 12) <= len)
{
uint32_t memid = off;
unsigned char l;
char *name;
v.dta = &dta[off];
l = v.p->v[0];
name = (char *) malloc (l + 1);
if (!name)
return -1;
if (l != 0)
memcpy (name, &dta[off + 12], l);
name[l] = 0;
if (TI_add_typ (nptr,memid,TITYP_NAME, 0,0,"", name, "") < 0)
return -1;
free (name);
off = (12 + off + (uint32_t) l + 3) & ~3;
}
return 0;
}
int32_t
TI2_import_string (sTITyps *sptr, unsigned char *dta, uint32_t len)
{
uint32_t off = 0;
union {
unsigned char *dta;
unsigned short *len;
} v;
if (!len)
return 0;
while ((off + 2) <= len)
{
char *h;
v.dta = &dta[off];
h = (char *) malloc (v.len[0] + 1);
memcpy (h, &dta[off + 2], v.len[0]);
h[v.len[0]]=0;
if (TI_add_typ (sptr, off, TITYP_STR, 0, 0, "", h, "") < 0)
return -1;
free (h);
off += 2 + (uint32_t) v.len[0];
off = (off + 3) & ~3;
}
return 0;
}
int32_t
TI2_import_guid (sTITyps *gptr, unsigned char *dta, uint32_t length)
{
struct sGuidTab {
uint32_t data1;
uint16_t data2[2];
unsigned char data3[8];
int32_t res1;
int32_t res2; /* Forwarder GUID */
};
char str[260];
uint32_t off = 0;
union {
unsigned char *d;
struct sGuidTab *g;
} v;
if (!length)
return -1;
while ((off + 24) <= length)
{
v.d = &dta[off];
sprintf (str ,"\"%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\"",
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]);
TI_add_typ (gptr, (uint32_t) off, TITYP_GUIDS, 0, 0, "", str, "");
off += 24;
}
return 0;
}
int32_t
TI2_import_typinfo_names (sTITyps *tptr, unsigned char *dta, uint32_t length)
{
char name_unk[32];
char prefix_unk[32];
char *h;
char *name;
const char *prefix;
sMSFT_TypeInfoBase *t = (sMSFT_TypeInfoBase *) dta;
int32_t i;
int32_t free_name;
uint32_t off = 0;
if (!length)
return 0;
i = 0;
while ((off + sizeof (sMSFT_TypeInfoBase)) <= length)
{
free_name = 1;
name = TI_get_typ_name (tptr, (uint32_t) t[i].NameOffset, TITYP_NAME,"");
prefix = "";
if (!name)
{
free_name = 0;
sprintf (name_unk,"Name_%0x", t[i].NameOffset);
name = &name_unk[0];
}
switch (t[i].typekind & 0xf)
{
case TKIND_ENUM: prefix = "enum "; break;
case TKIND_RECORD: prefix = "struct "; break;
case TKIND_MODULE: prefix = "module "; break;
case TKIND_INTERFACE: prefix = "interface "; break;
case TKIND_DISPATCH: prefix = "dispinterface "; break;
case TKIND_COCLASS: prefix = "coclass "; break;
case TKIND_ALIAS: break;
case TKIND_UNION: prefix = "union "; break;
default:
prefix = &prefix_unk[0];
sprintf (prefix_unk, "TK_%u ", t[i].typekind&0xf);
break;
}
h = (char *) malloc (strlen (prefix) + strlen (name) + 1);
sprintf (h, "%s%s", prefix, name);
TI_add_typ (tptr, (uint32_t) off, TITYP_TYPINFO_NAMES, 0,0, "", h, "");
free (h);
if (free_name)
free (name);
off += sizeof (sMSFT_TypeInfoBase);
i++;
}
return 0;
}
char *
getTypeBOrImpRef (sTITyps *dptr, uint32_t off, const char *var)
{
if (off == (uint32_t) -1)
return NULL;
if ((off&1) != 0)
return TI_get_typ_name (dptr, off & ~1U,TITYP_IMPREF, var);
return TI_get_typ_name (dptr, off, TITYP_TYPINFO_NAMES, var);
}
int32_t
TI2_import_typedesc (sTITyps *dptr, unsigned char *dta, uint32_t len)
{
sMSFT_TypeDesc *p;
uint32_t off = 0;
if (!len)
return -1;
while ((off + 7) < len)
{
p = (sMSFT_TypeDesc *) &dta[off];
switch ((p->kind))
{
case 26: /* VT_PTR */
if ((p->vt & 0x80000000) != 0)
{
const char *name;
name = decode_VT_name_tmp (((uint32_t) (p->vt)) & 0xffff);
TI_add_typ (dptr, (uint32_t) off, TITYP_DEREF, TITYP_UNKNOWN,
(uint32_t) p->oArrayD & 0xffff,
((p->flag & 0x7fff) != 0x7ffe ? "*" : ""), &name[0], "");
}
else
{
if ((p->oTypeB & 1) != 0)
TI_add_typ (dptr, (uint32_t) off, TITYP_DEREF,
TITYP_IMPREF, (uint32_t) p->oTypeB & 0xfffffffe,
((p->flag & 0x7fff) != 0x7ffe ? "*" : ""), "", "");
else
TI_add_typ (dptr, (uint32_t) off, TITYP_DEREF,
TITYP_DEREF, (uint32_t) p->oTypeB,
((p->flag & 0x7fff) != 0x7ffe ? "*" : ""), "", "");
}
break;
case 27: /* SAFEARRAY */
if ((p->vt & 0x80000000) != 0)
{
const char *name;
name = decode_VT_name_tmp (((uint32_t) (p->vt)) & 0xffff);
TI_add_typ (dptr, (uint32_t) off, TITYP_DEREF, TITYP_UNKNOWN,
(uint32_t) p->oArrayD & 0xffff,
"", &name[0], ((p->flag & 0x7fff) != 0x7ffe ? "[]" : ""));
}
else
{
if ((p->oTypeB & 1) != 0)
TI_add_typ (dptr, (uint32_t) off, TITYP_DEREF,
TITYP_IMPREF, (uint32_t) p->oTypeB & 0xfffffffe,
"", "", ((p->flag & 0x7fff) != 0x7ffe ? "[]" : ""));
else
TI_add_typ (dptr, (uint32_t) off, TITYP_DEREF,
TITYP_DEREF, (uint32_t) p->oTypeB,
"", "", ((p->flag & 0x7fff) != 0x7ffe ? "[]" : ""));
}
break;
case 28: /* VT_CARRAY */
TI_add_typ (dptr, (uint32_t) off, TITYP_DEREF, TITYP_ARRAY,
(uint32_t) p->oArrayD & 0xffff, "", "", "");
break;
case 29: /* VT_USERDEFINED */
if ((p->vt & 0x80000000) != 0)
{
const char *name;
name = decode_VT_name_tmp (((uint32_t) (p->vt)) & 0xffff);
TI_add_typ (dptr, (uint32_t) off, TITYP_DEREF, TITYP_UNKNOWN,
(uint32_t) p->oArrayD & 0xffff,
"", &name[0], "");
}
else
{
if ((p->oTypeB & 1) != 0)
TI_add_typ (dptr, (uint32_t) off, TITYP_DEREF,
TITYP_IMPREF, (uint32_t) p->oTypeB & 0xfffffffe,
"", "", "");
else
TI_add_typ (dptr, (uint32_t) off, TITYP_DEREF,
TITYP_TYPINFO_NAMES, (uint32_t) p->oTypeB,
"", "", "");
}
break;
default:
{
const char *name;
const char *prefix = "";
name = decode_VT_name_tmp (((uint32_t) (p->vt)) & 0xffff);
if ((p->flag & 0xf000) == 0x4000)
prefix = "*";
TI_add_typ (dptr, (uint32_t) off, TITYP_DEREF, TITYP_UNKNOWN,
(uint32_t) p->oArrayD, prefix, &name[0], "");
}
break;
}
off += 8;
}
return 0;
}
int32_t
TI2_import_customdata (sTITyps *dptr, unsigned char *dta, uint32_t length)
{
sMSFT_CustomData *p;
uint32_t off = 0;
if (!length)
return 0;
while (off < length)
{
uint32_t soff = off;
char *s;
s = NULL;
p = (sMSFT_CustomData *) &dta[off];
off += getVT_data (dptr, p->vt, p->dta, &s);
TI_add_typ (dptr,soff,TITYP_CUSTOMDATA,0,0,"",s,"");
if(s) free (s);
off = (off + 3) & ~3;
//fprintf (fp, "\n");
}
return 0;
}
size_t
getVT_data (sTITyps *dptr, uint32_t vt, unsigned char *dta, char **ret)
{
char s[4096];
size_t b, l, sz;
if (dptr)
sz = 0;
l = getVT_size (vt, dta,&b);
dta += b - 2;
if (l == 0xffffffff)
{
if (vt == 8)
sprintf (s, "L\"\"");
else {
fprintf (stderr, "vt: 0x%x with size of -1!!!\n", vt);
sprintf (s, "vt:0x%x_zero", vt);
}
if (ret)
*ret = strdup (s);
return b;
}
sz = l;
s[0] = 0;
switch (vt) {
case 16: /* VT_I1 */ sprintf (s,"(char) %d", *((char *) dta)); break;
case 17: /* VT_UI1 */ sprintf (s,"(unsigned char) %u", *((unsigned char *) dta)); break;
case 18: /* VT_UI2 */ sprintf (s,"(USHORT) %u", *((uint16_t *) dta)); break;
case 23: /* VT_UINT */
case 19: /* VT_UI4 */ sprintf (s,"(UINT) %uU", *((uint32_t *) dta)); break;
case 20: /* VT_I8 */
#ifdef _WIN32
sprintf (s,"(LONGLONG) %I64dLL", *((int64_t *) dta)); break;
#else
sprintf (s,"(LONGLONG) %lldLL", *((int64_t *) dta)); break;
#endif
case 21: /* VT_UI8 */
#ifdef _WIN32
sprintf (s,"(ULONGLONG) %I64uULL", *((uint64_t *) dta)); break;
#else
sprintf (s,"(ULONGLONG) %lluULL", *((uint64_t *) dta)); break;
#endif
case 10: /* VT_ERROR */ sprintf (s, " = (SCODE) %dL", *((int32_t *) dta)); break;
case 11: /* VT_BOOL */ sprintf (s,"(WINBOOL) %d", *((int16_t *) dta)); break;
case 2: /* VT_I2 */ sprintf (s,"(short) %d", *((int16_t *) dta)); break;
case 22: /* VT_INT */
case 3: /* VT_I4 */ sprintf (s,"(int) %d", *((int32_t *) dta)); break;
case 4: /* VT_R4 */ sprintf (s,"(float) %f", *((float *) dta)); break;
case 5: /* VT_R8 */ sprintf (s,"(double) %g", *((double *) dta)); break;
case 6: /* VT_CY */
#ifdef _WIN32
sprintf (s,"(CY) %I64dLL", *((int64_t *) dta)); break;
#else
sprintf (s,"(CY) %lldLL", *((int64_t *) dta)); break;
#endif
case 8: /* VT_BSTR */
sprintf (s,"L\"");
while (sz>0 && sz < 4094)
{
if (strlen (s) >= 4080)
{
fprintf (stderr, "String too big (%lu)\n", (unsigned long) l);
break;
}
if (*dta >= 0x20 && *dta <= 0x7f)
sprintf (&s[strlen(s)], "%c", *dta);
else
sprintf (&s[strlen(s)],"\\%03o", *dta);
dta++; --sz;
}
sprintf (&s[strlen(s)],"\"");
break;
case 25: /* VT_HRESULT */
case 26: /* VT_PTR */
sprintf (s,"(HRESULT) 0x%x", *((int32_t *) dta)); break;
default:
sprintf (s, "(%s) with %u size", decode_VT_name_tmp (vt), (uint32_t) l);
break;
}
if (ret)
*ret = strdup (s);
return l + b;
}
size_t
getVT_size (uint32_t vt, unsigned char *dta, size_t *basesz)
{
size_t ret = 0;
size_t bsz = 2;
switch (vt&0xfff) {
case 0: /* VT_EMPTY */ break;
case 1: /* VT_NULL */ break;
case 2: /* VT_I2 */ ret = 2; break;
case 3: /* VT_I4 */ ret = 4; break;
case 4: /* VT_R4 */ ret = 4; break;
case 5: /* VT_R8 */ ret = 8; break;
case 6: /* VT_CY */ ret = 16; break;
case 7: /* VT_DATE */ ret = 16; break;
case 8: /* VT_BSTR */ ret = 0; bsz += 4; break;
case 9: /* VT_DISPATCH */ ret = 4; break;
case 10: /* VT_ERROR */ ret = 4; break;
case 11: /* VT_BOOL */ ret = 2; break;
case 12: /* VT_VARIANT */ ret = 0; break;
case 13: /* VT_UNKNOWN */ ret = 4; break;
case 14: /* VT_DECIMAL */ ret = 16; break;
case 16: /* VT_I1 */ ret = 1; break;
case 17: /* VT_UI1 */ ret = 1; break;
case 18: /* VT_UI2 */ ret = 2; break;
case 19: /* VT_UI4 */ ret = 4; break;
case 20: /* VT_I8 */ ret = 8; break;
case 21: /* VT_UI8 */ ret = 8; break;
case 22: /* VT_INT */ ret = 4; break;
case 23: /* VT_UINT */ ret = 4; break;
case 24: /* VT_VOID */ ret = 0; break;
case 25: /* VT_HRESULT */ ret = 4; break;
case 26: /* VT_PTR */ ret = 4; break;
case 27: /* VT_SAFEARRAY */ ret = 0; bsz+=4; break;
case 28: /* VT_CARRAY */ ret = 0; bsz+=4; break;
case 29: /* VT_USERDEFINED */ ret = 0; bsz+=4; break;
case 30: /* VT_LPSTR */ ret = 4; break;
case 31: /* VT_LPWSTR */ ret = 4; break;
case 36: /* VT_RECORD */ ret = 0; bsz+=4; break;
case 37: /* VT_INT_PTR */ ret = 4; break;
case 38: /* VT_UINT_PTR */ ret = 4; break;
case 64: /* VT_FILETIME */ ret = 8; break;
case 65: /* VT_BLOB */ ret = 0; bsz+=4; break;
case 66: /* VT_STREAM */ ret = 0; bsz+=4; break;
case 67: /* VT_STORAGE */ ret = 0; bsz+=4; break;
case 68: /* VT_STREAMED_OBJECT */ ret = 0; bsz+=4; break;
case 69: /* VT_STORED_OBJECT */ ret = 0; bsz+=4; break;
case 70: /* VT_BLOB_OBJECT */ ret = 0; bsz+=4; break;
case 71: /* VT_CF*/ ret = 0; bsz+=4; break;
case 72: /* VT_CLSID */ ret = 0; bsz+=4; break;
case 73: /* VT_VERSIONED_STREAM */ ret = 0; bsz+=4; break;
case 0xfff: /* VT_BSTR_BLOB */ ret = 0; bsz+=4; break;
default:
ret = 0; break;
break;
}
if (bsz>2)
{
ret = *((uint32_t *) dta);
}
if (basesz)
*basesz = bsz;
return ret;
}
const char *
decode_VT_name_tmp (uint16_t vt)
{
static char str[128];
const char *name = "???";
switch ((vt&0xfff))
{
case 0: /* VT_EMPTY */ name = "EMPTY"; break;
case 1: /* VT_NULL */ name = "NULL"; break;
case 2: /* VT_I2 */ name = "short"; break;
case 3: /* VT_I4 */ name = "long"; break;
case 4: /* VT_R4 */ name = "float"; break;
case 5: /* VT_R8 */ name = "double"; break;
case 6: /* VT_CY */ name = "CY"; break;
case 7: /* VT_DATE */ name = "DATE"; break;
case 8: /* VT_BSTR */ name = "BSTR"; break;
case 9: /* VT_DISPATCH */ name = "IDispatch *"; break;
case 10: /* VT_ERROR */ name = "SCODE"; break;
case 11: /* VT_BOOL */ name = "WINBOOL"; break;
case 12: /* VT_VARIANT */ name = "VARIANT"; break;
case 13: /* VT_UNKNOWN */ name = "IUnknown *"; break;
case 14: /* VT_DECIMAL */ name = "DECIMAL"; break;
case 16: /* VT_I1 */ name = "CHAR"; break;
case 17: /* VT_UI1 */ name = "UCHAR"; break;
case 18: /* VT_UI2 */ name = "USHORT"; break;
case 19: /* VT_UI4 */ name = "UINT"; break;
case 20: /* VT_I8 */ name = "LONGLONG"; break;
case 21: /* VT_UI8 */ name = "ULONGLONG"; break;
case 22: /* VT_INT */ name = "int"; break;
case 23: /* VT_UINT */ name = "unsigned int"; break;
case 24: /* VT_VOID */ name = "void"; break;
case 25: /* VT_HRESULT */ name = "HRESULT"; break;
case 26: /* VT_PTR */ name = "PTR"; break;
case 27: /* VT_SAFEARRAY */ name = "SAFEARRAY"; break;
case 28: /* VT_CARRAY */ name = "CARRAY"; break;
case 29: /* VT_USERDEFINED */ name = "USERDEFINED"; break;
case 30: /* VT_LPSTR */ name = "LPSTR"; break;
case 31: /* VT_LPWSTR */ name = "LPWSTR"; break;
case 36: /* VT_RECORD */ name = "RECORD"; break;
case 37: /* VT_INT_PTR */ name = "INT_PTR"; break;
case 38: /* VT_UINT_PTR */ name = "UINT_PTR"; break;
case 64: /* VT_FILETIME */ name = "FILETIME"; break;
case 65: /* VT_BLOB */ name = "BLOB"; break;
case 66: /* VT_STREAM */ name = "STREAM"; break;
case 67: /* VT_STORAGE */ name = "STORAGE"; break;
case 68: /* VT_STREAMED_OBJECT */ name = "STREAMED_OBJECT"; break;
case 69: /* VT_STORED_OBJECT */ name = "STORED_OBJECT"; break;
case 70: /* VT_BLOB_OBJECT */ name = "BLOB_OBJECT"; break;
case 71: /* VT_CF*/ name = "CF"; break;
case 72: /* VT_CLSID */ name = "CLSID"; break;
case 73: /* VT_VERSIONED_STREAM */ name = "VERSIONED_STREAM"; break;
case 0xfff: /* VT_BSTR_BLOB */ name = "BSTR_BLOB"; break;
default:
sprintf (str, "VT_%08x", vt & 0xfff);
name = &str[0];
break;
}
if ((vt & 0xf000) == 0x4000)
strcat (str, " *");
return name;
}
char *
TI_getVTorDref (sTITyps *ptyp,uint32_t vt, const char *varName, int beBase)
{
char *name;
if ((vt & 0x80000000)!=0)
{
name = strdup (decode_VT_name_tmp (vt));
if (varName != NULL && varName[0] != 0)
{
name = ti_cat_freel (name, " ");
name = ti_cat_freel (name, varName);
}
}
else if ((vt&1)!=0)
name = TI_get_typ_name (ptyp, vt & ~1, TITYP_IMPREF, varName);
else if ((vt&3)!=0)
name = TI_get_typ_name (ptyp, vt, TITYP_UNKNOWN, varName);
else
{
if (!beBase)
name = TI_get_typ_name (ptyp, vt, TITYP_DEREF, varName);
else
name = TI_get_typ_name (ptyp, vt, TITYP_TYPINFO_NAMES, varName);
}
return name;
}
int32_t
TI2_import_importlibs (sTITyps *iptr, unsigned char *dta, uint32_t len)
{
sMSFT_ImpFiles *p;
uint32_t off = 0;
if (!len)
return 0;
while ((off + 13) < len)
{
char *h;
unsigned short l;
p = (sMSFT_ImpFiles *) &dta[off];
l = (p->flag >> 2);
h = (char *) malloc (l + 1);
memcpy (h, &dta[off + 14], l);
h[l] = 0;
genidl_strlwr (h);
TI_add_typ (iptr, (uint32_t) off, TITYP_IMP, 0,0,"",h,"");
off = (off + 14 + l + 3) & ~3;
}
return 0;
}
int32_t
TI2_import_ref (sTITyps *gptr, unsigned char *dta, uint32_t len)
{
sMSFT_RefTab *p;
uint32_t off = 0;
if (!len)
return 0;
while ((off + 15) < len)
{
char *h;
p = (sMSFT_RefTab *) & dta[off];
h = getTypeBOrImpRef (gptr, (uint32_t) p->oData1, "");
TI_add_typ (gptr, (uint32_t) off, TITYP_REF, p->data2, p->oNextRef,"",h,"");
free (h);
off += sizeof (sMSFT_RefTab);
}
return 0;
}
int32_t
TI2_import_array (sTITyps *gptr, unsigned char *dta, uint32_t len)
{
char postfix[256];
uint32_t off = 0;
sMSFT_ArrayDesc *p;
if (!len)
return 0;
while ((off + 7) < len)
{
uint32_t num_dims;
uint32_t size;
char *name = NULL;
uint32_t i;
p = (sMSFT_ArrayDesc *) &dta[off];
if ((p->vt & 0x80000000) != 0)
name = strdup (decode_VT_name_tmp (p->vt));
num_dims = p->count;
size = p->size;
if (!size)
size = (num_dims * 2 * 4);
postfix[0] = 0;
for (i=0;i < num_dims; i++)
{
sprintf (&postfix[strlen (postfix)], "[%u]", p->vt_offset[i*2]);
}
TI_add_typ (gptr, (uint32_t) off, TITYP_ARRAY, TITYP_DEREF, (uint32_t) p->vt,"",
(name ? name : ""), postfix);
off += 8 + size;
off +=3; off &= ~3;
}
return 0;
}
int32_t
TI2_import_importref (sTITyps *gptr, unsigned char *dta, uint32_t length)
{
MSFT_ImpInfo *p;
uint32_t off = 0;
char *idstr;
char *iname;
if (!length)
return 0;
while ((off + 11) < length)
{
const char *str;
char s[128];
p = (MSFT_ImpInfo *) &dta[off];
iname = TI_get_typ_name (gptr, (uint32_t) p->oImpFile, TITYP_IMP, "");
if ((p->flags & 1) == 0)
{
sprintf (s, "TypeB_%x", p->oGuid);
}
else
{
char *ni = TI_get_typ_name (gptr, (uint32_t) p->oGuid & ~1, TITYP_GUIDS, "");
if (ni)
{
strcpy (s, ni + 1);
if (strrchr (s, '\"') != NULL)
*strrchr (s, '\"')=0;
free (ni);
}
else
sprintf (s, "Guid_%x", p->oGuid);
}
str = genidl_find_type (iname, &s[0]);
/*if (!str)
{
sprintf (s, "Name_%x", p->oGuid);
str = genidl_find_type (iname, &s[0]);
}*/
if (str)
{
TI_add_typ (gptr, (uint32_t) off, TITYP_IMPREF, 0,0, "", str, "");
}
else
{
idstr = (char *) malloc (strlen (s) + strlen (iname) + 2 + 10);
sprintf (idstr, "%s_%s_%02x_%x", iname, s, p->flags, p->tkind);
fprintf (stderr, "Type %s count: 0x%x tkind:0x%x not found\n", idstr, p->count, p->tkind);
TI_add_typ (gptr, (uint32_t) off, TITYP_IMPREF, 0,0, "", idstr, "");
free (idstr);
}
if (iname)
free (iname);
off += 12;
}
return 0;
}
int32_t
TI2_import_customdataguid (sTITyps *gptr, unsigned char *dta, uint32_t len)
{
if (gptr || dta || len)
return 0;
return 0;
}