Jacek Caban : widl:
Added support for importing parent interfaces from importlib.
Alexandre Julliard
julliard at wine.codeweavers.com
Sat May 20 07:26:19 CDT 2006
Module: wine
Branch: refs/heads/master
Commit: a7fa3a985bd46c3cd2d8280d85555bce22a908c7
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=a7fa3a985bd46c3cd2d8280d85555bce22a908c7
Author: Jacek Caban <jacek at codeweavers.com>
Date: Thu May 18 22:42:32 2006 +0200
widl: Added support for importing parent interfaces from importlib.
---
tools/widl/write_msft.c | 108 ++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 96 insertions(+), 12 deletions(-)
diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c
index fcb5f9c..ff9e0c8 100644
--- a/tools/widl/write_msft.c
+++ b/tools/widl/write_msft.c
@@ -583,7 +583,7 @@ static int ctl2_alloc_string(
}
/****************************************************************************
- * alloc_importinfo
+ * alloc_msft_importinfo
*
* Allocates and initializes an import information structure in a type library.
*
@@ -592,7 +592,7 @@ static int ctl2_alloc_string(
* Success: The offset of the new importinfo.
* Failure: -1 (this is invariably an out of memory condition).
*/
-static int alloc_importinfo(
+static int alloc_msft_importinfo(
msft_typelib_t *typelib, /* [I] The type library to allocate in. */
MSFT_ImpInfo *impinfo) /* [I] The import information to store. */
{
@@ -664,6 +664,79 @@ static int alloc_importfile(
return offset;
}
+static void alloc_importinfo(msft_typelib_t *typelib, importinfo_t *importinfo)
+{
+ importlib_t *importlib = importinfo->importlib;
+
+ chat("alloc_importinfo: %s\n", importinfo->name);
+
+ if(!importlib->allocated) {
+ MSFT_GuidEntry guid;
+ int guid_idx;
+
+ chat("allocating importlib %s\n", importlib->name);
+
+ importlib->allocated = -1;
+
+ memcpy(&guid.guid, &importlib->guid, sizeof(GUID));
+ guid.hreftype = 2;
+
+ guid_idx = ctl2_alloc_guid(typelib, &guid);
+
+ alloc_importfile(typelib, guid_idx, importlib->version&0xffff,
+ importlib->version>>16, importlib->name);
+ }
+
+ if(importinfo->offset == -1 || !(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID)) {
+ MSFT_ImpInfo impinfo;
+
+ impinfo.flags = importinfo->flags;
+ impinfo.oImpFile = 0;
+
+ if(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
+ MSFT_GuidEntry guid;
+
+ guid.hreftype = 0;
+ memcpy(&guid.guid, &importinfo->guid, sizeof(GUID));
+
+ impinfo.oGuid = ctl2_alloc_guid(typelib, &guid);
+
+ importinfo->offset = alloc_msft_importinfo(typelib, &impinfo);
+
+ typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo.oGuid+sizeof(GUID)]
+ = importinfo->offset+1;
+
+ if(!strcmp(importinfo->name, "IDispatch"))
+ typelib->typelib_header.dispatchpos = importinfo->offset+1;
+ }else {
+ impinfo.oGuid = importinfo->id;
+ importinfo->offset = alloc_msft_importinfo(typelib, &impinfo);
+ }
+ }
+}
+
+static importinfo_t *find_importinfo(msft_typelib_t *typelib, const char *name)
+{
+ importlib_t *importlib;
+ int i;
+
+ chat("search importlib %s\n", name);
+
+ if(!name)
+ return NULL;
+
+ for(importlib = typelib->typelib->importlibs; importlib; importlib = NEXT_LINK(importlib)) {
+ for(i=0; i < importlib->ntypeinfos; i++) {
+ if(!strcmp(name, importlib->importinfos[i].name)) {
+ chat("Found %s in importlib.\n", name);
+ return importlib->importinfos+i;
+ }
+ }
+ }
+
+ return NULL;
+}
+
static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure);
static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface);
static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration);
@@ -1634,14 +1707,20 @@ static HRESULT add_var_desc(msft_typeinf
return S_OK;
}
-static HRESULT add_impl_type(msft_typeinfo_t *typeinfo, type_t *ref)
+static HRESULT add_impl_type(msft_typeinfo_t *typeinfo, type_t *ref, importinfo_t *importinfo)
{
- if(ref->typelib_idx == -1)
- add_interface_typeinfo(typeinfo->typelib, ref);
- if(ref->typelib_idx == -1)
- error("add_impl_type: unable to add inherited interface\n");
+ if(importinfo) {
+ alloc_importinfo(typeinfo->typelib, importinfo);
+ typeinfo->typeinfo->datatype1 = importinfo->offset+1;
+ }else {
+ if(ref->typelib_idx == -1)
+ add_interface_typeinfo(typeinfo->typelib, ref);
+ if(ref->typelib_idx == -1)
+ error("add_impl_type: unable to add inherited interface\n");
+
+ typeinfo->typeinfo->datatype1 = typeinfo->typelib->typelib_typeinfo_offsets[ref->typelib_idx];
+ }
- typeinfo->typeinfo->datatype1 = typeinfo->typelib->typelib_typeinfo_offsets[ref->typelib_idx];
typeinfo->typeinfo->cImplTypes++;
return S_OK;
}
@@ -1807,7 +1886,7 @@ static void add_dispatch(msft_typelib_t
impinfo.flags = TKIND_INTERFACE << 24 | MSFT_IMPINFO_OFFSET_IS_GUID;
impinfo.oImpFile = impfile_offset;
impinfo.oGuid = ctl2_alloc_guid(typelib, &guidentry);
- typelib->typelib_header.dispatchpos = alloc_importinfo(typelib, &impinfo) | 0x01;
+ typelib->typelib_header.dispatchpos = alloc_msft_importinfo(typelib, &impinfo) | 0x01;
}
static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface)
@@ -1861,6 +1940,7 @@ static void add_interface_typeinfo(msft_
func_t *func;
type_t *ref;
msft_typeinfo_t *msft_typeinfo;
+ importinfo_t *ref_importinfo = NULL;
int num_parents = 0, num_funcs = 0;
const attr_t *attr;
const type_t *derived;
@@ -1872,8 +1952,12 @@ static void add_interface_typeinfo(msft_
/* 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);
+ if(interface->ref) {
+ ref_importinfo = find_importinfo(typelib, interface->ref->name);
+
+ if(!ref_importinfo && 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,
@@ -1890,7 +1974,7 @@ static void add_interface_typeinfo(msft_
msft_typeinfo->typeinfo->flags &= ~0x40; /* TYPEFLAG_FDUAL */
if(interface->ref)
- add_impl_type(msft_typeinfo, interface->ref);
+ add_impl_type(msft_typeinfo, interface->ref, ref_importinfo);
/* count the number of inherited interfaces and non-local functions */
for(ref = interface->ref; ref; ref = ref->ref) {
More information about the wine-cvs
mailing list