diff --git a/tools/widl/typelib_struct.h b/tools/widl/typelib_struct.h index a952f5af4f8..8e271a406d8 100644 --- a/tools/widl/typelib_struct.h +++ b/tools/widl/typelib_struct.h @@ -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 { diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index 1f4ed088f7a..b32ffc7d7a2 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -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))