Jacek Caban : widl: Added importlib reading implementation.

Alexandre Julliard julliard at wine.codeweavers.com
Wed May 17 14:48:33 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 6137e1b60a12094681318d6806f97c0b47a26764
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=6137e1b60a12094681318d6806f97c0b47a26764

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon May 15 21:55:04 2006 +0200

widl: Added importlib reading implementation.

---

 tools/widl/typelib.c        |  127 +++++++++++++++++++++++++++++++++++++++++++
 tools/widl/typelib_struct.h |    4 +
 tools/widl/widltypes.h      |   28 +++++++++
 3 files changed, 158 insertions(+), 1 deletions(-)

diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c
index fb8fd66..77d5155 100644
--- a/tools/widl/typelib.c
+++ b/tools/widl/typelib.c
@@ -2,6 +2,7 @@
  * IDL Compiler
  *
  * Copyright 2004 Ove Kaaven
+ * Copyright 2006 Jacek Caban for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -19,20 +20,33 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
+#include "wine/wpp.h"
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <unistd.h>
 #include <string.h>
 #include <assert.h>
 #include <ctype.h>
 #include <signal.h>
 
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "windef.h"
+#include "winbase.h"
+
+#include "wine/unicode.h"
+
 #include "widl.h"
 #include "utils.h"
 #include "parser.h"
 #include "header.h"
 #include "typelib.h"
+#include "widltypes.h"
+#include "typelib_struct.h"
 
 int in_typelib = 0;
 
@@ -279,9 +293,122 @@ void add_typedef(type_t *tdef, var_t *na
      typelib->entry = entry;
 }
 
+static void tlb_read(int fd, void *buf, size_t count)
+{
+    if(read(fd, buf, count) < count)
+        error("error while reading importlib.\n");
+}
+
+static void tlb_lseek(int fd, off_t offset)
+{
+    if(lseek(fd, offset, SEEK_SET) == -1)
+        error("lseek failed\n");
+}
+
+static void msft_read_guid(int fd, MSFT_SegDir *segdir, int offset, GUID *guid)
+{
+    tlb_lseek(fd, segdir->pGuidTab.offset+offset);
+    tlb_read(fd, guid, sizeof(GUID));
+}
+
+static void read_msft_importlib(importlib_t *importlib, int fd)
+{
+    MSFT_Header header;
+    MSFT_SegDir segdir;
+    int *typeinfo_offs;
+    int i;
+
+    importlib->allocated = 0;
+
+    tlb_lseek(fd, 0);
+    tlb_read(fd, &header, sizeof(header));
+
+    importlib->version = header.version;
+
+    typeinfo_offs = xmalloc(header.nrtypeinfos*sizeof(INT));
+    tlb_read(fd, typeinfo_offs, header.nrtypeinfos*sizeof(INT));
+    tlb_read(fd, &segdir, sizeof(segdir));
+
+    msft_read_guid(fd, &segdir, header.posguid, &importlib->guid);
+
+    importlib->ntypeinfos = header.nrtypeinfos;
+    importlib->importinfos = xmalloc(importlib->ntypeinfos*sizeof(importinfo_t));
+
+    for(i=0; i < importlib->ntypeinfos; i++) {
+        MSFT_TypeInfoBase base;
+        MSFT_NameIntro nameintro;
+        int len;
+
+        tlb_lseek(fd, sizeof(MSFT_Header) + header.nrtypeinfos*sizeof(INT) + sizeof(MSFT_SegDir)
+                 + typeinfo_offs[i]);
+        tlb_read(fd, &base, sizeof(base));
+
+        importlib->importinfos[i].importlib = importlib;
+        importlib->importinfos[i].flags = (base.typekind&0xf)<<24;
+        importlib->importinfos[i].offset = -1;
+        importlib->importinfos[i].id = i;
+
+        if(base.posguid != -1) {
+            importlib->importinfos[i].flags |= MSFT_IMPINFO_OFFSET_IS_GUID;
+            msft_read_guid(fd, &segdir, base.posguid, &importlib->importinfos[i].guid);
+        }
+
+        tlb_lseek(fd, segdir.pNametab.offset + base.NameOffset);
+        tlb_read(fd, &nameintro, sizeof(nameintro));
+
+        len = nameintro.namelen & 0xff;
+
+        importlib->importinfos[i].name = xmalloc(len+1);
+        tlb_read(fd, importlib->importinfos[i].name, len);
+        importlib->importinfos[i].name[len] = 0;
+    }
+
+    free(typeinfo_offs);
+}
+
+static void read_importlib(importlib_t *importlib)
+{
+    int fd;
+    INT magic;
+    char *file_name;
+
+    file_name = wpp_find_include(importlib->name, NULL);
+    if(file_name) {
+        fd = open(file_name, O_RDONLY);
+        free(file_name);
+    }else {
+        fd = open(importlib->name, O_RDONLY);
+    }
+
+    if(fd < 0)
+        error("Could not open importlib %s.\n", importlib->name);
+
+    tlb_read(fd, &magic, sizeof(magic));
+
+    switch(magic) {
+    case MSFT_MAGIC:
+        read_msft_importlib(importlib, fd);
+        break;
+    default:
+        error("Wrong or unsupported typelib magic %x\n", magic);
+    };
+
+    close(fd);
+}
+
 void add_importlib(const char *name)
 {
+    importlib_t *importlib;
+
     if(!typelib) return;
 
+    importlib = xmalloc(sizeof(*importlib));
+    importlib->name = xstrdup(name);
+
+    read_importlib(importlib);
+
+    LINK(importlib, typelib->importlibs);
+    typelib->importlibs = importlib;
+
     warning("importlib is not yet supported.\n");
 }
diff --git a/tools/widl/typelib_struct.h b/tools/widl/typelib_struct.h
index 961105c..6067abb 100644
--- a/tools/widl/typelib_struct.h
+++ b/tools/widl/typelib_struct.h
@@ -34,6 +34,8 @@ #define MSFT_HREFTYPE_INDEX(href) ((href
  * with ICreateTypeLib2 have "MSFT".
  */
 
+#define MSFT_MAGIC 0x5446534d
+
 /*****************************************************
  *                MSFT typelibs
  *
@@ -162,7 +164,7 @@ typedef struct tagMSFT_ImpInfo {
                             /*               if clear oGuid is a typeinfo index in the specified typelib */
                             /* bits 24 - 31: TKIND of reference */
     INT     oImpFile;       /* offset in the Import File table */
-    INT     oGuid;          /* offset in Guid table or typeinfo index (see bit 16 of res0) */
+    INT     oGuid;          /* offset in Guid table or typeinfo index (see bit 16 of flags) */
 } MSFT_ImpInfo;
 
 #define MSFT_IMPINFO_OFFSET_IS_GUID 0x00010000
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index a2d917b..83d2311 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -42,6 +42,8 @@ typedef struct _func_t func_t;
 typedef struct _ifref_t ifref_t;
 typedef struct _class_t class_t;
 typedef struct _typelib_entry_t typelib_entry_t;
+typedef struct _importlib_t importlib_t;
+typedef struct _importinfo_t importinfo_t;
 typedef struct _typelib_t typelib_t;
 
 #define DECL_LINK(type) \
@@ -260,11 +262,37 @@ struct _typelib_entry_t {
     DECL_LINK(typelib_entry_t)
 };
 
+struct _importinfo_t {
+    int offset;
+    GUID guid;
+    int flags;
+    int id;
+
+    char *name;
+
+    importlib_t *importlib;
+};
+
+struct _importlib_t {
+    char *name;
+
+    int version;
+    GUID guid;
+
+    importinfo_t *importinfos;
+    int ntypeinfos;
+
+    int allocated;
+
+    DECL_LINK(importlib_t);
+};
+
 struct _typelib_t {
     char *name;
     char *filename;
     attr_t *attrs;
     typelib_entry_t *entry;
+    importlib_t *importlibs;
 };
 
 #endif




More information about the wine-cvs mailing list