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