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