When adding an interface, midl adds the inherited interface first
unless the inherited interface doesn't itself inherit. Fix the id, sizevft and datatype2 fields for interfaces that inherit. Prevent a crash if the typelib is empty. Clarify a few more entries on typelib_struct.h
This commit is contained in:
parent
e5f2ed4c66
commit
652ec646ad
|
@ -137,11 +137,11 @@ typedef struct tagMSFT_TypeInfoBase {
|
|||
INT helpcontext; /* */
|
||||
INT oCustData; /* offset in customer data table */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
INT16 cbSizeVft; /* virtual table size, not including inherits */
|
||||
INT16 cbSizeVft; /* virtual table size, including inherits */
|
||||
INT16 cImplTypes; /* nr of implemented interfaces */
|
||||
#else
|
||||
INT16 cImplTypes; /* nr of implemented interfaces */
|
||||
INT16 cbSizeVft; /* virtual table size, not including inherits */
|
||||
INT16 cbSizeVft; /* virtual table size, including inherits */
|
||||
#endif
|
||||
/*050*/ INT size; /* size in bytes, at least for structures */
|
||||
/* FIXME: name of this field */
|
||||
|
@ -149,9 +149,8 @@ typedef struct tagMSFT_TypeInfoBase {
|
|||
/* or in base intefaces */
|
||||
/* if coclass: offset in reftable */
|
||||
/* if interface: reference to inherited if */
|
||||
INT datatype2; /* if 0x8000, entry above is valid */
|
||||
/* actually dunno */
|
||||
/* else it is zero? */
|
||||
INT datatype2; /* for interfaces: hiword is num of inherited funcs */
|
||||
/* loword is num of inherited interfaces */
|
||||
INT res18; /* always? 0 */
|
||||
/*060*/ INT res19; /* always? -1 */
|
||||
} MSFT_TypeInfoBase;
|
||||
|
@ -272,9 +271,11 @@ typedef struct {
|
|||
to the typeinfo itself or to a member of
|
||||
the typeinfo */
|
||||
INT next_hash; /* offset to next name in the hash bucket */
|
||||
INT namelen; /* only lower 8 bits are valid,
|
||||
lower-middle 8 bits are unknown (flags?),
|
||||
upper 16 bits are hash code */
|
||||
INT namelen; /* only lower 8 bits are valid */
|
||||
/* 0x1000 if name is only used once as a variable name */
|
||||
/* 0x2000 if name is a variable in an enumeration */
|
||||
/* 0x3800 if name is typeinfo name */
|
||||
/* upper 16 bits are hash code */
|
||||
} MSFT_NameIntro;
|
||||
/* the custom data table directory has enties like this */
|
||||
typedef struct {
|
||||
|
|
|
@ -1179,7 +1179,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index)
|
|||
unsigned int funckind = 1 /* FUNC_PUREVIRTUAL */, invokekind = 1 /* INVOKE_FUNC */;
|
||||
int help_context = 0, help_string_context = 0, help_string_offset = -1;
|
||||
|
||||
id = ((0x6000 | typeinfo->typeinfo->cImplTypes) << 16) | index;
|
||||
id = ((0x6000 | (typeinfo->typeinfo->datatype2 & 0xffff)) << 16) | index;
|
||||
|
||||
chat("add_func_desc(%p,%d)\n", typeinfo, index);
|
||||
|
||||
|
@ -1580,12 +1580,19 @@ static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_
|
|||
return msft_typeinfo;
|
||||
}
|
||||
|
||||
|
||||
static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
|
||||
{
|
||||
int idx = 0;
|
||||
func_t *cur = interface->funcs;
|
||||
func_t *func;
|
||||
type_t *ref;
|
||||
msft_typeinfo_t *msft_typeinfo;
|
||||
int num_parents = 0, num_funcs = 0;
|
||||
|
||||
/* midl adds the parent interface first, unless the parent itself
|
||||
has no parent (i.e. it stops before IUnknown). */
|
||||
|
||||
if(interface->ref && interface->ref->ref && interface->ref->typelib_idx == -1)
|
||||
add_interface_typeinfo(typelib, interface->ref);
|
||||
|
||||
interface->typelib_idx = typelib->typelib_header.nrtypeinfos;
|
||||
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs,
|
||||
|
@ -1596,11 +1603,27 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
|
|||
if(interface->ref)
|
||||
add_impl_type(msft_typeinfo, interface->ref);
|
||||
|
||||
while(NEXT_LINK(cur)) cur = NEXT_LINK(cur);
|
||||
while(cur) {
|
||||
if(add_func_desc(msft_typeinfo, cur, idx) == S_OK)
|
||||
/* count the number of inherited interfaces and non-local functions */
|
||||
for(ref = interface->ref; ref; ref = ref->ref) {
|
||||
num_parents++;
|
||||
for(func = ref->funcs; func; func = NEXT_LINK(func)) {
|
||||
attr_t *attr;
|
||||
for(attr = func->def->attrs; attr; attr = NEXT_LINK(attr))
|
||||
if(attr->type == ATTR_LOCAL)
|
||||
break;
|
||||
if(!attr)
|
||||
num_funcs++;
|
||||
}
|
||||
}
|
||||
msft_typeinfo->typeinfo->datatype2 = num_funcs << 16 | num_parents;
|
||||
msft_typeinfo->typeinfo->cbSizeVft = num_funcs * 4;
|
||||
|
||||
func = interface->funcs;
|
||||
while(NEXT_LINK(func)) func = NEXT_LINK(func);
|
||||
while(func) {
|
||||
if(add_func_desc(msft_typeinfo, func, idx) == S_OK)
|
||||
idx++;
|
||||
cur = PREV_LINK(cur);
|
||||
func = PREV_LINK(func);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1985,7 +2008,7 @@ int create_msft_typelib(typelib_t *typelib)
|
|||
set_custdata(msft, &midl_time_guid, VT_UI4, &cur_time, &msft->typelib_header.CustomDataOffset);
|
||||
set_custdata(msft, &midl_version_guid, VT_UI4, &version, &msft->typelib_header.CustomDataOffset);
|
||||
|
||||
for(entry = typelib->entry; NEXT_LINK(entry); entry = NEXT_LINK(entry))
|
||||
for(entry = typelib->entry; entry && NEXT_LINK(entry); entry = NEXT_LINK(entry))
|
||||
;
|
||||
|
||||
for( ; entry; entry = PREV_LINK(entry))
|
||||
|
|
Loading…
Reference in New Issue