From 346188b7558debfe48a38a53d2bbfd464dfb5c1e Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Thu, 6 Jan 2005 20:45:21 +0000 Subject: [PATCH] Initial support for typelib generation. --- tools/widl/Makefile.in | 4 +- tools/widl/hash.c | 621 ++++++++++++++ tools/widl/hash.h | 33 + tools/widl/header.c | 1 + tools/widl/parser.y | 3 + tools/widl/typelib.c | 59 +- tools/widl/typelib.h | 57 ++ tools/widl/typelib_struct.h | 591 +++++++++++++ tools/widl/widltypes.h | 6 +- tools/widl/write_msft.c | 1603 +++++++++++++++++++++++++++++++++++ 10 files changed, 2917 insertions(+), 61 deletions(-) create mode 100644 tools/widl/hash.c create mode 100644 tools/widl/hash.h create mode 100644 tools/widl/typelib_struct.h create mode 100644 tools/widl/write_msft.c diff --git a/tools/widl/Makefile.in b/tools/widl/Makefile.in index 73c1bcd5a1c..df682580cd7 100644 --- a/tools/widl/Makefile.in +++ b/tools/widl/Makefile.in @@ -10,11 +10,13 @@ PROGRAMS = widl$(EXEEXT) MODULE = none C_SRCS = \ + hash.c \ header.c \ proxy.c \ typelib.c \ utils.c \ - widl.c + widl.c \ + write_msft.c EXTRA_SRCS = parser.y parser.l EXTRA_OBJS = y.tab.o @LEX_OUTPUT_ROOT@.o diff --git a/tools/widl/hash.c b/tools/widl/hash.c new file mode 100644 index 00000000000..aeaff068fa5 --- /dev/null +++ b/tools/widl/hash.c @@ -0,0 +1,621 @@ +/* + * Oleaut32 hash functions + * + * Copyright 1999 Corel Corporation + * Copyright 2001-2003 Jon Griffiths + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" + +#include "hash.h" + +static const unsigned char Lookup_16[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + + /* Windows */ + 0x7F, 0x7F, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x8C, + 0x7F, 0x7F, 0x7F, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x7F, 0x7F, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x55, 0xDE, 0x55, + + /* Mac */ + 0x41, 0x41, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0x41, 0x4F, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0x41, 0x4F, 0xBD, 0x41, 0x4F, 0xC0, + 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x41, 0x41, 0x4F, + 0xCE, 0xCE, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x55, 0x55, 0xDA, + 0xDB, 0xDC, 0xDD, 0x3F, 0x3F, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x41, 0x45, 0x41, + 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4F, 0x4F, 0x3F, 0x4F, 0x55, 0x55, 0x55, + 0x49, 0x7F, 0xF7, 0x7F, 0xF9, 0xFA, 0xFB, 0x3F, 0xFD, 0xFE, 0x7F +}; + +static const unsigned char Lookup_32[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + + /* Windows */ + 0x7F, 0x7F, 0x82, 0x7F, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x53, + 0x54, 0x5A, 0x5A, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x7F, 0x99, + 0x53, 0x9B, 0x53, 0x54, 0x5A, 0x5A, 0xA0, 0x7F, 0xA2, 0x4C, 0xA4, 0x41, 0xA6, + 0xA7, 0xA8, 0xA9, 0x53, 0xAB, 0xAC, 0x96, 0xAE, 0x5A, 0xB0, 0xB1, 0xB2, 0x4C, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x41, 0x53, 0xBB, 0x4C, 0xBD, 0x4C, 0x5A, 0x52, + 0x41, 0x41, 0x41, 0x41, 0x4C, 0x43, 0x43, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, + 0x49, 0x44, 0xD0, 0x4E, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x52, 0x55, 0x55, + 0x55, 0x55, 0x59, 0x54, 0xDF, 0x52, 0x41, 0x41, 0x41, 0x41, 0x4C, 0x43, 0x43, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x44, 0xD0, 0x4E, 0x4E, 0x4F, 0x4F, + 0x4F, 0x4F, 0xF7, 0x52, 0x55, 0x55, 0x55, 0x55, 0x59, 0x54, 0xFF, + + /* Mac */ + 0x41, 0x41, 0x41, 0x45, 0x41, 0x4F, 0x55, 0x41, 0x41, 0x43, 0x41, 0x43, 0x43, + 0x43, 0x45, 0x5A, 0x5A, 0x44, 0x49, 0x44, 0x45, 0x45, 0x45, 0x4F, 0x45, 0x4F, + 0x4F, 0x4F, 0x55, 0x45, 0x45, 0x55, 0xA0, 0xA1, 0x45, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0x45, 0xAC, 0xAD, 0x47, 0x49, 0x49, 0x49, 0xB2, 0xB3, + 0x49, 0x4B, 0xB6, 0xB7, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4E, 0x4E, + 0x4E, 0xC2, 0xC3, 0x4E, 0x4E, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x4E, 0x4F, 0x4F, + 0x4F, 0x4F, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x4F, 0x52, 0x52, + 0x52, 0xDC, 0xDD, 0x52, 0x52, 0x52, 0x53, 0xE2, 0xE3, 0x53, 0x53, 0x53, 0x41, + 0x54, 0x54, 0x49, 0x5A, 0x5A, 0x55, 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x59, 0x59, 0x4B, 0x5A, 0x4C, 0x4C, 0x47, 0xFF +}; + +static const unsigned char Lookup_48[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + + /* Windows */ + 0x7F, 0x7F, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x8C, + 0x7F, 0x7F, 0x7F, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x7F, 0x7F, 0x59, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0x55, 0x59, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x59, 0xDE, 0x59, + + /* Mac */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, + 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAB, 0xAD, 0xAE, 0xAE, 0xB0, 0xB1, 0xB2, 0xB3, + 0xA7, 0xB5, 0xB6, 0xB7, 0xB8, 0xB8, 0xBA, 0xBA, 0xBC, 0xBC, 0xBE, 0xBE, 0xB7, + 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCB, 0xCD, + 0xCD, 0xC1, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD8, 0xDA, + 0xDA, 0xDC, 0xDD, 0xDD, 0x9F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F +}; + +static const unsigned char Lookup_64[128 * 3] = { + /* Common */ + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* Mac */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static const unsigned char Lookup_80[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + + /* Mac */ + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, +}; + +static const unsigned char Lookup_112[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + + /* Mac */ + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, +}; + +static const unsigned char Lookup_128[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, + +/* Windows */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x00, 0x8B, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x00, 0x99, + 0x00, 0x9B, 0x00, 0x00, 0x00, 0x00, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x00, 0xAB, 0xAC, 0x2D, 0xAE, 0x2D, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xBA, + 0xA2, 0xC2, 0xC3, 0xC4, 0xB8, 0xC6, 0xB9, 0xC8, 0xBA, 0xCA, 0xCB, 0xCC, 0xCD, + 0xCE, 0xBC, 0xD0, 0xD1, 0x00, 0xD3, 0xD4, 0xBE, 0xD6, 0xD7, 0xD8, 0xBF, 0xBA, + 0xBE, 0xA2, 0xB8, 0xB9, 0xBA, 0xBE, 0xA2, 0xC2, 0xC3, 0xC4, 0xB8, 0xC6, 0xB9, + 0xC8, 0xBA, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xBC, 0xD0, 0xD1, 0xD3, 0xD3, 0xD4, + 0xBE, 0xD6, 0xD7, 0xD8, 0xBF, 0xBA, 0xBE, 0xBC, 0xBE, 0xBF, 0x00, + + /* Mac */ + 0x41, 0x31, 0x32, 0x45, 0x33, 0x4F, 0x55, 0x87, 0x41, 0x41, 0x41, 0x00, 0x8C, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x92, 0x93, 0x49, 0x49, 0x96, 0x97, 0x98, 0x4F, + 0x4F, 0x9B, 0x3F, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xAB, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xB0, + 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0x09, 0xBD, 0xCC, 0xB0, + 0xB6, 0xCF, 0x2D, 0x2D, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xB8, 0xAB, 0xC3, 0xBD, + 0xB6, 0xB8, 0xAB, 0xC3, 0xBF, 0xBD, 0xB0, 0xB5, 0xBE, 0xA2, 0xB6, 0xBC, 0xA1, + 0xB8, 0xAB, 0xA5, 0xBA, 0xA4, 0xBB, 0xC1, 0xC3, 0xA6, 0xBF, 0xC4, 0xAA, 0xC6, + 0xA3, 0xBF, 0xAA, 0xCC, 0xBD, 0xB7, 0xAB, 0xBD, 0xAB, 0xBD, 0x3F, +}; + +static const unsigned char Lookup_144[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, + +/* Windows */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0xDA, + 0x55, 0x55, 0xDD, 0xDE, 0xDF, 0x41, 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, + 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, + 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0xDA, 0x55, 0x55, 0xDD, 0xDE, 0x59, + + /* Mac */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0xDA, + 0x55, 0x55, 0xDD, 0xDE, 0xDF, 0x41, 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, + 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, + 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0xDA, 0x55, 0x55, 0xDD, 0xDE, 0x59, +}; + +static const unsigned char Lookup_160[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, + +/* Windows */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0xDC, 0xDD, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0xD6, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0xDC, 0xDD, 0xDE, 0x59, + + /* Mac */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0xDC, 0xDD, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0xD6, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0xDC, 0xDD, 0xDE, 0x59, +}; + +static const unsigned char Lookup_176[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, + + /* Windows */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0xC4, 0xC5, 0xC4, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0x55, + 0x55, 0x59, 0x59, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0xC4, 0xC5, 0xC4, 0x43, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0x59, + + /* Mac */ + 0x80, 0x81, 0x43, 0x45, 0x4E, 0x85, 0x59, 0x41, 0x41, 0x41, 0x80, 0x41, 0x81, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, + 0x85, 0x4F, 0x55, 0x55, 0x55, 0x59, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0x80, 0x85, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0x41, 0x4F, 0xBD, 0x80, 0x85, 0xC0, + 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0x09, 0x41, 0x41, 0x4F, + 0xCE, 0xCE, 0x2D, 0x2D, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x59, 0x59, 0xDA, + 0xDB, 0xDC, 0xDD, 0x3F, 0x3F, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x41, 0x45, 0x41, + 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4F, 0x4F, 0x3F, 0x4F, 0x55, 0x55, 0x55, + 0x49, 0x00, 0xF7, 0x00, 0xF9, 0xFA, 0xFB, 0x3F, 0xFD, 0xFE, 0x00 +}; + +static const unsigned char Lookup_208[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x80, 0x81, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x5E, 0x89, 0x8A, 0x8B, 0x8C, + 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9A, 0x9B, 0x8C, 0x9D, 0x00, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, + 0xC1, 0xC2, 0xC1, 0xC1, 0xC1, 0xC1, 0xC7, 0xC8, 0xC9, 0xC9, 0xCB, 0xCC, 0xCD, + 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xDB, 0x00, 0xDD, 0xDE, 0xDF, 0x41, 0xE1, 0x41, 0xE3, 0xE4, 0xE5, 0xE6, 0x43, + 0x45, 0x45, 0x45, 0x45, 0xEC, 0xEC, 0x49, 0x49, 0xF0, 0xF1, 0xF2, 0xF3, 0x4F, + 0xF5, 0xF6, 0xF7, 0xF8, 0x55, 0xFA, 0x55, 0x55, 0x00, 0x00, 0xFF, + + /* Mac */ + 0x41, 0x81, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x8B, 0x8C, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x93, 0x49, 0x49, 0x4E, 0x4F, 0x98, 0x4F, + 0x4F, 0x9B, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, + 0xC1, 0xC2, 0xC1, 0xC1, 0xC1, 0xC1, 0xC7, 0xC8, 0xC9, 0xC9, 0xCB, 0xCC, 0xCD, + 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0x00, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xE9, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, + 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +static const unsigned char Lookup_224[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x80, 0x81, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x5E, 0x89, 0x8A, 0x8B, 0x8C, + 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, + 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, + 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEA, 0xEC, 0xED, 0xED, 0xEF, 0xEF, 0xF1, 0xF2, 0xF3, 0xF3, + 0xF5, 0xF5, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0x00, 0x00, 0xFF, + + /* Mac */ + 0x41, 0x41, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, + 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, + 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEA, 0xEC, 0xED, 0xED, 0xEF, 0xEF, 0xF1, 0xF2, 0xF3, 0xF3, + 0xF5, 0xF5, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +/*********************************************************************** + * lhash_val_of_name_sys + * + * Copy of oleaut32.LHashValOfNameSysA + * Produce a string hash value. + * + * PARAMS + * skind [I] Type of the system. + * lcid [I] Locale id for the hash. + * lpStr [I] String to hash. + * + * RETURNS + * Success: The hash value of the string. + * Failure: 0, if lpStr is NULL. + * + * NOTES + * This function produces a two part hash: The high word is based on + * skind and lcid, while the low word is based on a repeated string + * hash of skind/str. + */ +unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr) +{ + ULONG nOffset, nMask = skind == SYS_MAC ? 1 : 0; + ULONG nHiWord, nLoWord = 0x0deadbee; + const unsigned char *str = (const unsigned char *)lpStr, *pnLookup = NULL; + + if (!str) + return 0; + + switch (PRIMARYLANGID(LANGIDFROMLCID(lcid))) + { + default: + fprintf(stderr, "Unknown lcid %lx, treating as latin-based, please report\n", lcid); + /* .. Fall Through .. */ + case LANG_AFRIKAANS: case LANG_ALBANIAN: case LANG_ARMENIAN: + case LANG_ASSAMESE: case LANG_AZERI: case LANG_BASQUE: + case LANG_BELARUSIAN: case LANG_BENGALI: case LANG_BULGARIAN: + case LANG_CATALAN: case LANG_DANISH: case LANG_DIVEHI: + case LANG_DUTCH: case LANG_ENGLISH: case LANG_ESTONIAN: + case LANG_FAEROESE: case LANG_FINNISH: case LANG_FRENCH: + case LANG_GALICIAN: case LANG_GEORGIAN: case LANG_GERMAN: + case LANG_GUJARATI: case LANG_HINDI: case LANG_INDONESIAN: + case LANG_ITALIAN: case LANG_KANNADA: case LANG_KASHMIRI: + case LANG_KAZAK: case LANG_KONKANI: case LANG_KYRGYZ: + case LANG_LATVIAN: case LANG_LITHUANIAN: case LANG_MACEDONIAN: + case LANG_MALAY: case LANG_MALAYALAM: case LANG_MANIPURI: + case LANG_MARATHI: case LANG_MONGOLIAN: case LANG_NEPALI: + case LANG_ORIYA: case LANG_PORTUGUESE: case LANG_PUNJABI: + case LANG_ROMANIAN: case LANG_SANSKRIT: case LANG_SERBIAN: + case LANG_SINDHI: case LANG_SLOVENIAN: case LANG_SWAHILI: + case LANG_SWEDISH: case LANG_SYRIAC: case LANG_TAMIL: + case LANG_TATAR: case LANG_TELUGU: case LANG_THAI: + case LANG_UKRAINIAN: case LANG_URDU: case LANG_UZBEK: + case LANG_VIETNAMESE: case LANG_GAELIC: case LANG_MALTESE: + case LANG_MAORI: case LANG_RHAETO_ROMANCE: + case LANG_SAAMI: case LANG_SORBIAN: case LANG_SUTU: + case LANG_TSONGA: case LANG_TSWANA: case LANG_VENDA: + case LANG_XHOSA: case LANG_ZULU: case LANG_ESPERANTO: + case LANG_WALON: case LANG_CORNISH: case LANG_WELSH: + case LANG_BRETON: + nOffset = 16; + pnLookup = Lookup_16; + break; + case LANG_CZECH: case LANG_HUNGARIAN: case LANG_POLISH: + case LANG_SLOVAK: case LANG_SPANISH: + nOffset = 32; + pnLookup = Lookup_32; + break; + case LANG_HEBREW: + nOffset = 48; + pnLookup = Lookup_48; + break; + case LANG_JAPANESE: + nOffset = 64; + pnLookup = Lookup_64; + break; + case LANG_KOREAN: + nOffset = 80; + pnLookup = Lookup_80; + break; + case LANG_CHINESE: + nOffset = 112; + pnLookup = Lookup_112; + break; + case LANG_GREEK: + nOffset = 128; + pnLookup = Lookup_128; + break; + case LANG_ICELANDIC: + nOffset = 144; + pnLookup = Lookup_144; + break; + case LANG_TURKISH: + nOffset = 160; + pnLookup = Lookup_160; + break; + case LANG_NORWEGIAN: + if (SUBLANGID(LANGIDFROMLCID(lcid)) == SUBLANG_NORWEGIAN_NYNORSK) + { + nOffset = 176; + pnLookup = Lookup_176; + } + else + { + nOffset = 16; + pnLookup = Lookup_16; + } + break; + case LANG_ARABIC: + case LANG_FARSI: + nOffset = 208; + pnLookup = Lookup_208; + break; + case LANG_RUSSIAN: + nOffset = 224; + pnLookup = Lookup_224; + break; + } + + nHiWord = (nOffset | nMask) << 16; + + while (*str) + { + ULONG newLoWord = 0, i; + + /* Cumulative prime multiplication (*37) with modulo 2^32 wrap-around */ + for (i = 0; i < 37; i++) + newLoWord += nLoWord; + + nLoWord = newLoWord + pnLookup[*str > 0x7f && nMask ? *str + 0x80 : *str]; + str++; + } + /* Constrain to a prime modulo and sizeof(WORD) */ + nLoWord = (nLoWord % 65599) & 0xffff; + + return nHiWord | nLoWord; +} diff --git a/tools/widl/hash.h b/tools/widl/hash.h new file mode 100644 index 00000000000..de91849ebc6 --- /dev/null +++ b/tools/widl/hash.h @@ -0,0 +1,33 @@ +/* + * Hash definitions + * + * Copyright 2005 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __WIDL_HASH_H +#define __WIDL_HASH_H + +typedef enum tag_syskind_t { + SYS_WIN16 = 0, + SYS_WIN32, + SYS_MAC +} syskind_t; + +extern unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr); + +#endif diff --git a/tools/widl/header.c b/tools/widl/header.c index 75becddf828..67ea841dbdb 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -30,6 +30,7 @@ #include #include +#include "windef.h" #include "widl.h" #include "utils.h" #include "parser.h" diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 86b22e1bfd0..dfcf1b04d05 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -31,6 +31,8 @@ #include #endif +#include "windef.h" + #include "widl.h" #include "utils.h" #include "parser.h" @@ -969,6 +971,7 @@ static type_t *make_type(unsigned char type, type_t *ref) t->sign = 0; t->defined = FALSE; t->written = FALSE; + t->typelib_idx = -1; INIT_LINK(t); return t; } diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c index e9a28cefb56..c03002501a6 100644 --- a/tools/widl/typelib.c +++ b/tools/widl/typelib.c @@ -36,60 +36,6 @@ int in_typelib = 0; -/* Copied from wtypes.h. Not included directly because that would create a - * circular dependency (after all, wtypes.h is generated by widl...) */ - -enum VARENUM { - VT_EMPTY = 0, - VT_NULL = 1, - VT_I2 = 2, - VT_I4 = 3, - VT_R4 = 4, - VT_R8 = 5, - VT_CY = 6, - VT_DATE = 7, - VT_BSTR = 8, - VT_DISPATCH = 9, - VT_ERROR = 10, - VT_BOOL = 11, - VT_VARIANT = 12, - VT_UNKNOWN = 13, - VT_DECIMAL = 14, - VT_I1 = 16, - VT_UI1 = 17, - VT_UI2 = 18, - VT_UI4 = 19, - VT_I8 = 20, - VT_UI8 = 21, - VT_INT = 22, - VT_UINT = 23, - VT_VOID = 24, - VT_HRESULT = 25, - VT_PTR = 26, - VT_SAFEARRAY = 27, - VT_CARRAY = 28, - VT_USERDEFINED = 29, - VT_LPSTR = 30, - VT_LPWSTR = 31, - VT_RECORD = 36, - VT_FILETIME = 64, - VT_BLOB = 65, - VT_STREAM = 66, - VT_STORAGE = 67, - VT_STREAMED_OBJECT = 68, - VT_STORED_OBJECT = 69, - VT_BLOB_OBJECT = 70, - VT_CF = 71, - VT_CLSID = 72, - VT_BSTR_BLOB = 0xfff, - VT_VECTOR = 0x1000, - VT_ARRAY = 0x2000, - VT_BYREF = 0x4000, - VT_RESERVED = 0x8000, - VT_ILLEGAL = 0xffff, - VT_ILLEGALMASKED = 0xfff, - VT_TYPEMASK = 0xfff -}; static typelib_t *typelib; /* List of oleauto types that should be recognized by name. @@ -195,8 +141,11 @@ unsigned short get_type_vt(type_t *t) } /* FIXME: should we recurse and add a VT_BYREF? */ /* Or just return VT_PTR? */ + if(t->ref) return get_type_vt(t->ref); error("get_type_vt: unknown-deref-type: %d\n", t->ref->type); break; + case RPC_FC_STRUCT: + return VT_USERDEFINED; default: error("get_type_vt: unknown-type: %d\n", t->type); } @@ -231,7 +180,7 @@ void end_typelib(void) in_typelib--; if (!typelib) return; -/* create_msft_typelib(typelib);*/ + create_msft_typelib(typelib); return; } diff --git a/tools/widl/typelib.h b/tools/widl/typelib.h index fe173b4ac68..ba5260b2d68 100644 --- a/tools/widl/typelib.h +++ b/tools/widl/typelib.h @@ -29,4 +29,61 @@ extern void add_coclass(class_t *cls); extern void add_module(type_t *module); extern void add_struct(type_t *structure); +/* Copied from wtypes.h. Not included directly because that would create a + * circular dependency (after all, wtypes.h is generated by widl...) */ + +enum VARENUM { + VT_EMPTY = 0, + VT_NULL = 1, + VT_I2 = 2, + VT_I4 = 3, + VT_R4 = 4, + VT_R8 = 5, + VT_CY = 6, + VT_DATE = 7, + VT_BSTR = 8, + VT_DISPATCH = 9, + VT_ERROR = 10, + VT_BOOL = 11, + VT_VARIANT = 12, + VT_UNKNOWN = 13, + VT_DECIMAL = 14, + VT_I1 = 16, + VT_UI1 = 17, + VT_UI2 = 18, + VT_UI4 = 19, + VT_I8 = 20, + VT_UI8 = 21, + VT_INT = 22, + VT_UINT = 23, + VT_VOID = 24, + VT_HRESULT = 25, + VT_PTR = 26, + VT_SAFEARRAY = 27, + VT_CARRAY = 28, + VT_USERDEFINED = 29, + VT_LPSTR = 30, + VT_LPWSTR = 31, + VT_RECORD = 36, + VT_FILETIME = 64, + VT_BLOB = 65, + VT_STREAM = 66, + VT_STORAGE = 67, + VT_STREAMED_OBJECT = 68, + VT_STORED_OBJECT = 69, + VT_BLOB_OBJECT = 70, + VT_CF = 71, + VT_CLSID = 72, + VT_BSTR_BLOB = 0xfff, + VT_VECTOR = 0x1000, + VT_ARRAY = 0x2000, + VT_BYREF = 0x4000, + VT_RESERVED = 0x8000, + VT_ILLEGAL = 0xffff, + VT_ILLEGALMASKED = 0xfff, + VT_TYPEMASK = 0xfff +}; +extern unsigned short get_type_vt(type_t *t); + +extern int create_msft_typelib(typelib_t *typelib); #endif diff --git a/tools/widl/typelib_struct.h b/tools/widl/typelib_struct.h new file mode 100644 index 00000000000..cafd424db73 --- /dev/null +++ b/tools/widl/typelib_struct.h @@ -0,0 +1,591 @@ +/* + * typelib_struct.h internal wine data structures + * used to decode typelib's + * + * Copyright 1999 Rein KLazes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _WIDL_TYPELIB_STRUCT_H +#define _WIDL_TYPELIB_STRUCT_H + +#define HELPDLLFLAG (0x0100) +#define DO_NOT_SEEK (-1) + +#define MSFT_HREFTYPE_INTHISFILE(href) (!((href) & 3)) +#define MSFT_HREFTYPE_INDEX(href) ((href) /sizeof(MSFT_TypeInfoBase)) + +/*-------------------------FILE STRUCTURES-----------------------------------*/ + +/* There are two known file formats, those created with ICreateTypeLib + * have the signature "SLTG" as their first four bytes, while those created + * with ICreateTypeLib2 have "MSFT". + */ + +/***************************************************** + * MSFT typelibs + * + * These are TypeLibs created with ICreateTypeLib2 + * + */ + +/* + * structure of the typelib type2 header + * it is at the beginning of a type lib file + * + */ +typedef struct tagMSFT_Header { +/*0x00*/INT magic1; /* 0x5446534D "MSFT" */ + INT magic2; /* 0x00010002 version nr? */ + INT posguid; /* position of libid in guid table */ + /* (should be, else -1) */ + INT lcid; /* locale id */ +/*0x10*/INT lcid2; + INT varflags; /* (largely) unknown flags ,seems to be always 41 */ + /* becomes 0x51 with a helpfile defined */ + /* if help dll defined it's 0x151 */ + /* update : the lower nibble is syskind */ + INT version; /* set with SetVersion() */ + INT flags; /* set with SetFlags() */ +/*0x20*/INT nrtypeinfos; /* number of typeinfo's (till so far) */ + INT helpstring; /* position of help string in stringtable */ + INT helpstringcontext; + INT helpcontext; +/*0x30*/INT nametablecount; /* number of names in name table */ + INT nametablechars; /* nr of characters in name table */ + INT NameOffset; /* offset of name in name table */ + INT helpfile; /* position of helpfile in stringtable */ +/*0x40*/INT CustomDataOffset; /* if -1 no custom data, else it is offset */ + /* in customer data/guid offset table */ + INT res44; /* unknown always: 0x20 (guid hash size?) */ + INT res48; /* unknown always: 0x80 (name hash size?) */ + INT dispatchpos; /* HREFTYPE to IDispatch, or -1 if no IDispatch */ +/*0x50*/INT res50; /* is zero becomes one when an interface is derived */ +} MSFT_Header; + +/* segments in the type lib file have a structure like this: */ +typedef struct tagMSFT_pSeg { + INT offset; /* absolute offset in file */ + INT length; /* length of segment */ + INT res08; /* unknown always -1 */ + INT res0c; /* unknown always 0x0f in the header */ + /* 0x03 in the typeinfo_data */ +} MSFT_pSeg; + +/* layout of the main segment directory */ +typedef struct tagMSFT_SegDir { +/*1*/MSFT_pSeg pTypeInfoTab; /* each type info get an entry of 0x64 bytes */ + /* (25 ints) */ +/*2*/MSFT_pSeg pImpInfo; /* table with info for imported types */ +/*3*/MSFT_pSeg pImpFiles; /* import libaries */ +/*4*/MSFT_pSeg pRefTab; /* References table */ +/*5*/MSFT_pSeg pLibtab; /* always exists, alway same size (0x80) */ + /* hash table w offsets to guid????? */ +/*6*/MSFT_pSeg pGuidTab; /* all guids are stored here together with */ + /* offset in some table???? */ +/*7*/MSFT_pSeg res07; /* always created, alway same size (0x200) */ + /* purpose largely unknown */ +/*8*/MSFT_pSeg pNametab; /* name tables */ +/*9*/MSFT_pSeg pStringtab; /* string table */ +/*A*/MSFT_pSeg pTypdescTab; /* table with type descriptors */ +/*B*/MSFT_pSeg pArrayDescriptions; +/*C*/MSFT_pSeg pCustData; /* data table, used for custom data and default */ + /* parameter values */ +/*D*/MSFT_pSeg pCDGuids; /* table with offsets for the guids and into */ + /* the customer data table */ +/*E*/MSFT_pSeg res0e; /* unknown */ +/*F*/MSFT_pSeg res0f; /* unknown */ +} MSFT_SegDir; + + +/* base type info data */ +typedef struct tagMSFT_TypeInfoBase { +/*000*/ INT typekind; /* it is the TKIND_xxx */ + /* some byte alignment stuf */ + INT memoffset; /* points past the file, if no elements */ + INT res2; /* zero if no element, N*0x40 */ + INT res3; /* -1 if no lement, (N-1)*0x38 */ +/*010*/ INT res4; /* always? 3 */ + INT res5; /* always? zero */ + INT cElement; /* counts elements, HI=cVars, LO=cFuncs */ + INT res7; /* always? zero */ +/*020*/ INT res8; /* always? zero */ + INT res9; /* always? zero */ + INT resA; /* always? zero */ + INT posguid; /* position in guid table */ +/*030*/ INT flags; /* Typeflags */ + INT NameOffset; /* offset in name table */ + INT version; /* element version */ + INT docstringoffs; /* offset of docstring in string tab */ +/*040*/ INT helpstringcontext; /* */ + INT helpcontext; /* */ + INT oCustData; /* offset in customer data table */ +#ifdef WORDS_BIGENDIAN + INT16 cbSizeVft; /* virtual table size, not including inherits */ + INT16 cImplTypes; /* nr of implemented interfaces */ +#else + INT16 cImplTypes; /* nr of implemented interfaces */ + INT16 cbSizeVft; /* virtual table size, not including inherits */ +#endif +/*050*/ INT size; /* size in bytes, at least for structures */ + /* FIXME: name of this field */ + INT datatype1; /* position in type description table */ + /* 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 res18; /* always? 0 */ +/*060*/ INT res19; /* always? -1 */ + } MSFT_TypeInfoBase; + +/* layout of an entry with information on imported types */ +typedef struct tagMSFT_ImpInfo { + INT res0; /* unknown */ + INT oImpFile; /* offset inthe Import File table */ + INT oGuid; /* offset in Guid table */ + } MSFT_ImpInfo; + +/* function description data */ +typedef struct { +/* INT recsize; record size including some xtra stuff */ + INT DataType; /* data type of the memeber, eg return of function */ + INT Flags; /* something to do with attribute flags (LOWORD) */ +#ifdef WORDS_BIGENDIAN + INT16 funcdescsize; /* size of reconstituted FUNCDESC and related structs */ + INT16 VtableOffset; /* offset in vtable */ +#else + INT16 VtableOffset; /* offset in vtable */ + INT16 funcdescsize; /* size of reconstituted FUNCDESC and related structs */ +#endif + INT FKCCIC; /* bit string with the following */ + /* meaning (bit 0 is the msb): */ + /* bit 2 indicates that oEntry is numeric */ + /* bit 3 that parameter has default values */ + /* calling convention (bits 4-7 ) */ + /* bit 8 indicates that custom data is present */ + /* Invokation kind (bits 9-12 ) */ + /* function kind (eg virtual), bits 13-15 */ +#ifdef WORDS_BIGENDIAN + INT16 nroargs; /* nr of optional arguments */ + INT16 nrargs; /* number of arguments (including optional ????) */ +#else + INT16 nrargs; /* number of arguments (including optional ????) */ + INT16 nroargs; /* nr of optional arguments */ +#endif + /* optional attribute fields, the number of them is variable */ + INT OptAttr[1]; +/* +0* INT helpcontext; +1* INT oHelpString; +2* INT oEntry; // either offset in string table or numeric as it is // +3* INT res9; // unknown (-1) // +4* INT resA; // unknown (-1) // +5* INT HelpStringContext; + // these are controlled by a bit set in the FKCCIC field // +6* INT oCustData; // custom data for function // +7* INT oArgCustData[1]; // custom data per argument // +*/ +} MSFT_FuncRecord; + +/* after this may follow an array with default value pointers if the + * appropriate bit in the FKCCIC field has been set: + * INT oDefautlValue[nrargs]; + */ + + /* Parameter info one per argument*/ +typedef struct { + INT DataType; + INT oName; + INT Flags; + } MSFT_ParameterInfo; + +/* Variable description data */ +typedef struct { +/* INT recsize; // record size including some xtra stuff */ + INT DataType; /* data type of the variable */ + INT Flags; /* VarFlags (LOWORD) */ +#ifdef WORDS_BIGENDIAN + INT16 vardescsize; /* size of reconstituted VARDESC and related structs */ + INT16 VarKind; /* VarKind */ +#else + INT16 VarKind; /* VarKind */ + INT16 vardescsize; /* size of reconstituted VARDESC and related structs */ +#endif + INT OffsValue; /* value of the variable or the offset */ + /* in the data structure */ + /* optional attribute fields, the number of them is variable */ + /* controlled by record length */ + INT HelpContext; + INT oHelpString; + INT res9; /* unknown (-1) */ + INT oCustData; /* custom data for variable */ + INT HelpStringContext; + +} MSFT_VarRecord; + +/* Structure of the reference data */ +typedef struct { + INT reftype; /* either offset in type info table, then it's */ + /* a multiple of 64 */ + /* or offset in the external reference table */ + /* with an offset of 1 */ + INT flags; + INT oCustData; /* custom data */ + INT onext; /* next offset, -1 if last */ +} MSFT_RefRecord; + +/* this is how a guid is stored */ +typedef struct { + GUID guid; + INT hreftype; /* -2 for the typelib guid, typeinfo offset + for typeinfo guid, low two bits are 01 if + this is an imported typeinfo, low two bits + are 10 if this is an imported typelib (used + by imported typeinfos) */ + INT next_hash; /* offset to next guid in the hash bucket */ +} MSFT_GuidEntry; +/* some data preceding entries in the name table */ +typedef struct { + INT hreftype; /* is -1 if name is for neither a typeinfo, + a variable, or a function (that is, name + is for a typelib or a function parameter). + otherwise is the offset of the first + typeinfo that this name refers to (either + 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 */ +} MSFT_NameIntro; +/* the custom data table directory has enties like this */ +typedef struct { + INT GuidOffset; + INT DataOffset; + INT next; /* next offset in the table, -1 if it's the last */ +} MSFT_CDGuid; + + +/*********************************************************** + * + * SLTG typelibs. + * + * These are created with ICreateTypeLib + * + */ + +#include "pshpack1.h" + +typedef struct { +/*00*/ DWORD SLTG_magic; /* 0x47544c53 == "SLTG" */ +/*04*/ WORD nrOfFileBlks; /* no of SLTG_BlkEntry's + 1 */ +/*06*/ WORD res06; /* ?? always 9 */ +/*08*/ WORD res08; /* some kind of len/offset ?? */ +/*0a*/ WORD first_blk; /* 1 based index into blk entries that + corresponds to first block in file */ +/*0c*/ DWORD res0c; /* always 0x000204ff */ +/*10*/ DWORD res10; /* always 0x00000000 */ +/*14*/ DWORD res14; /* always 0x000000c0 */ +/*18*/ DWORD res18; /* always 0x46000000 */ +/*1c*/ DWORD res1c; /* always 0x00000044 */ +/*20*/ DWORD res20; /* always 0xffff0000 */ +} SLTG_Header; + +/* This gets followed by a list of block entries */ +typedef struct { +/*00*/ DWORD len; +/*04*/ WORD index_string; /* offs from start of SLTG_Magic to index string */ +/*06*/ WORD next; +} SLTG_BlkEntry; + +/* The order of the blocks in the file is given by starting at Block + entry firt_blk and stepping through using the next pointer */ + +/* These then get followed by this magic */ +typedef struct { +/*00*/ BYTE res00; /* always 0x01 */ +/*01*/ CHAR CompObj_magic[8]; /* always "CompObj" */ +/*09*/ CHAR dir_magic[4]; /* always "dir" */ +} SLTG_Magic; + +#define SLTG_COMPOBJ_MAGIC "CompObj" +#define SLTG_DIR_MAGIC "dir" + +/* Next we have SLTG_Header.nrOfFileBlks - 2 of Index strings. These +are presumably unique to within the file and look something like +"AAAAAAAAAA" with the first character incremented from 'A' to ensure +uniqueness. I guess successive chars increment when we need to wrap +the first one. */ + +typedef struct { +/*00*/ CHAR string[11]; +} SLTG_Index; + + +/* This is followed by SLTG_pad9 */ +typedef struct { +/*00*/ CHAR pad[9]; /* 9 '\0's */ +} SLTG_Pad9; + + +/* Now we have the noOfFileBlks - 1 worth of blocks. The length of +each block is given by its entry in SLTG_BlkEntry. */ + +/* type SLTG_NAME in rather like a BSTR except that the length in +bytes is given by the first WORD and the string contains 8bit chars */ + +typedef WORD SLTG_Name; + +/* The main library block looks like this. This one seems to come last */ + +typedef struct { +/*00*/ WORD magic; /* 0x51cc */ +/*02*/ WORD res02; /* 0x0003, 0x0004 */ +/*04*/ WORD name; /* offset to name in name table */ +/*06*/ SLTG_Name res06; /* maybe this is just WORD == 0xffff */ + SLTG_Name helpstring; + SLTG_Name helpfile; + DWORD helpcontext; + WORD syskind; /* == 1 for win32, 0 for win16 */ + WORD lcid; /* == 0x409, 0x809 etc */ + DWORD res12; /* == 0 */ + WORD libflags; /* LIBFLAG_* */ + WORD maj_vers; + WORD min_vers; + GUID uuid; +} SLTG_LibBlk; + +#define SLTG_LIBBLK_MAGIC 0x51cc + +/* we then get 0x40 bytes worth of 0xffff or small numbers followed by + nrOfFileBlks - 2 of these */ +typedef struct { + WORD small_no; + SLTG_Name index_name; /* This refers to a name in the directory */ + SLTG_Name other_name; /* Another one of these weird names */ + WORD res1a; /* 0xffff */ + WORD name_offs; /* offset to name in name table */ + WORD more_bytes; /* if this is non-zero we get this many + bytes before the next element, which seem + to reference the docstring of the type ? */ + WORD res20; /* 0xffff */ + DWORD helpcontext; + WORD res26; /* 0xffff */ + GUID uuid; +} SLTG_OtherTypeInfo; + +/* Next we get WORD 0x0003 followed by a DWORD which if we add to +0x216 gives the offset to the name table from the start of the LibBlk +struct */ + +typedef struct { +/*00*/ WORD magic; /* 0x0501 */ +/*02*/ DWORD href_table; /* if not 0xffffffff, then byte offset from + beginning of struct to href table */ +/*06*/ DWORD res06; /* 0xffffffff */ +/*0a*/ DWORD elem_table; /* offset to members */ +/*0e*/ DWORD res0e; /* 0xffffffff */ +/*12*/ WORD major_version; /* major version number */ +/*14*/ WORD minor_version; /* minor version number */ +/*16*/ DWORD res16; /* 0xfffe0000 */ +/*1a*/ BYTE typeflags1;/* 0x02 | top 5 bits hold l5sbs of TYPEFLAGS */ +/*1b*/ BYTE typeflags2;/* TYPEFLAGS >> 5 */ +/*1c*/ BYTE typeflags3;/* 0x02*/ +/*1d*/ BYTE typekind; /* 0x03 == TKIND_INTERFACE etc. */ +/*1e*/ DWORD res1e; /* 0x00000000 or 0xffffffff */ +} SLTG_TypeInfoHeader; + +#define SLTG_TIHEADER_MAGIC 0x0501 + +typedef struct { +/*00*/ WORD cFuncs; +/*02*/ WORD cVars; +/*04*/ WORD cImplTypes; +/*06*/ WORD res06; +/*08*/ WORD res08; +/*0a*/ WORD res0a; +/*0c*/ WORD res0c; +/*0e*/ WORD res0e; +/*10*/ WORD res10; +/*12*/ WORD res12; +/*14*/ WORD tdescalias_vt; /* for TKIND_ALIAS */ +/*16*/ WORD res16; +/*18*/ WORD res18; +/*1a*/ WORD res1a; +/*1c*/ WORD res1c; +/*1e*/ WORD res1e; +/*20*/ WORD cbSizeInstance; +/*22*/ WORD cbAlignment; +/*24*/ WORD res24; +/*26*/ WORD res26; +/*28*/ WORD cbSizeVft; +/*2a*/ WORD res2a; +/*2c*/ WORD res2c; +/*2e*/ WORD res2e; +/*30*/ WORD res30; +/*32*/ WORD res32; +/*34*/ WORD res34; +} SLTG_TypeInfoTail; + +typedef struct { +/*00*/ WORD res00; /* 0x0001 sometimes 0x0003 ?? */ +/*02*/ WORD res02; /* 0xffff */ +/*04*/ BYTE res04; /* 0x01 */ +/*05*/ DWORD cbExtra; /* No of bytes that follow */ +} SLTG_MemberHeader; + +typedef struct { +/*00*/ WORD magic; /* 0x120a */ +/*02*/ WORD next; /* offset in bytes to next block from start of block + group, 0xffff if last item */ +/*04*/ WORD name; /* offset to name within name table */ +/*06*/ WORD value; /* offset to value from start of block group */ +/*08*/ WORD res08; /* 0x56 */ +/*0a*/ DWORD memid; /* memid */ +/*0e*/ WORD helpcontext;/* 0xfffe == no context, 0x0001 == stored in EnumInfo struct, else offset + to value from start of block group */ +/*10*/ WORD helpstring;/* offset from start of block group to string offset */ +} SLTG_EnumItem; + +#define SLTG_ENUMITEM_MAGIC 0x120a + +typedef struct { +/*00*/ WORD vt; /* vartype, 0xffff marks end. */ +/*02*/ WORD res02; /* ?, 0xffff marks end */ +} SLTG_AliasItem; + +#define SLTG_ALIASITEM_MAGIC 0x001d + + +typedef struct { + BYTE magic; /* 0x4c or 0x6c */ + BYTE inv; /* high nibble is INVOKE_KIND, low nibble = 2 */ + WORD next; /* byte offset from beginning of group to next fn */ + WORD name; /* Offset within name table to name */ + DWORD dispid; /* dispid */ + WORD helpcontext; /* helpcontext (again 1 is special) */ + WORD helpstring;/* helpstring offset to offset */ + WORD arg_off; /* offset to args from start of block */ + BYTE nacc; /* lowest 3bits are CALLCONV, rest are no of args */ + BYTE retnextopt;/* if 0x80 bit set ret type follows else next WORD + is offset to ret type. No of optional args is + middle 6 bits */ + WORD rettype; /* return type VT_?? or offset to ret type */ + WORD vtblpos; /* position in vtbl? */ + WORD funcflags; /* present if magic == 0x6c */ +/* Param list starts, repeat next two as required */ +#if 0 + WORD name; /* offset to 2nd letter of name */ + WORD+ type; /* VT_ of param */ +#endif +} SLTG_Function; + +#define SLTG_FUNCTION_MAGIC 0x4c +#define SLTG_FUNCTION_WITH_FLAGS_MAGIC 0x6c + +typedef struct { +/*00*/ BYTE magic; /* 0xdf */ +/*01*/ BYTE res01; /* 0x00 */ +/*02*/ DWORD res02; /* 0xffffffff */ +/*06*/ DWORD res06; /* 0xffffffff */ +/*0a*/ DWORD res0a; /* 0xffffffff */ +/*0e*/ DWORD res0e; /* 0xffffffff */ +/*12*/ DWORD res12; /* 0xffffffff */ +/*16*/ DWORD res16; /* 0xffffffff */ +/*1a*/ DWORD res1a; /* 0xffffffff */ +/*1e*/ DWORD res1e; /* 0xffffffff */ +/*22*/ DWORD res22; /* 0xffffffff */ +/*26*/ DWORD res26; /* 0xffffffff */ +/*2a*/ DWORD res2a; /* 0xffffffff */ +/*2e*/ DWORD res2e; /* 0xffffffff */ +/*32*/ DWORD res32; /* 0xffffffff */ +/*36*/ DWORD res36; /* 0xffffffff */ +/*3a*/ DWORD res3a; /* 0xffffffff */ +/*3e*/ DWORD res3e; /* 0xffffffff */ +/*42*/ WORD res42; /* 0xffff */ +/*44*/ DWORD number; /* this is 8 times the number of refs */ +/*48*/ /* Now we have number bytes (8 for each ref) of SLTG_UnknownRefInfo */ + +/*50*/ WORD res50; /* 0xffff */ +/*52*/ BYTE res52; /* 0x01 */ +/*53*/ DWORD res53; /* 0x00000000 */ +/*57*/ SLTG_Name names[1]; + /* Now we have number/8 SLTG_Names (first WORD is no of bytes in the ascii + * string). Strings look like "*\Rxxxx*#n". If xxxx == ffff then the + * ref refers to the nth type listed in this library (0 based). Else + * the xxxx (which maybe fewer than 4 digits) is the offset into the name + * table to a string "*\G{}#1.0#0#C:\WINNT\System32\stdole32.tlb#" + * The guid is the typelib guid; the ref again refers to the nth type of + * the imported typelib. + */ + +/*xx*/ BYTE resxx; /* 0xdf */ + +} SLTG_RefInfo; + +#define SLTG_REF_MAGIC 0xdf + +typedef struct { + WORD res00; /* 0x0001 */ + BYTE res02; /* 0x02 */ + BYTE res03; /* 0x40 if internal ref, 0x00 if external ? */ + WORD res04; /* 0xffff */ + WORD res06; /* 0x0000, 0x0013 or 0xffff ?? */ +} SLTG_UnknownRefInfo; + +typedef struct { + WORD res00; /* 0x004a */ + WORD next; /* byte offs to next interface */ + WORD res04; /* 0xffff */ + BYTE impltypeflags; /* IMPLTYPEFLAG_* */ + BYTE res07; /* 0x80 */ + WORD res08; /* 0x0012, 0x0028 ?? */ + WORD ref; /* number in ref table ? */ + WORD res0c; /* 0x4000 */ + WORD res0e; /* 0xfffe */ + WORD res10; /* 0xffff */ + WORD res12; /* 0x001d */ + WORD pos_in_table; /* 0x0, 0x4, ? */ +} SLTG_ImplInfo; + +#define SLTG_IMPL_MAGIC 0x004a + +typedef struct { + BYTE magic; /* 0x0a */ + BYTE typepos; + WORD next; + WORD name; + WORD byte_offs; /* pos in struct */ + WORD type; /* if typepos == 0x02 this is the type, else offset to type */ + DWORD memid; + WORD helpcontext; /* ?? */ + WORD helpstring; /* ?? */ +} SLTG_RecordItem; + +#define SLTG_RECORD_MAGIC 0x0a + + +/* CARRAYs look like this +WORD type == VT_CARRAY +WORD offset from start of block to SAFEARRAY +WORD typeofarray +*/ + +#include "poppack.h" + +/*---------------------------END--------------------------------------------*/ +#endif diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 4918b4e6784..f04c984c4d4 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -33,10 +33,6 @@ typedef GUID UUID; #define TRUE 1 #define FALSE 0 -#define LOWORD(l) ((unsigned short)(l)) -#define HIWORD(l) ((unsigned short)((unsigned long)(l) >> 16)) -#define MAKELONG(low,high) ((unsigned long)(((unsigned short)(low)) | (((unsigned long)((unsigned short)(high))) << 16))) - typedef struct _attr_t attr_t; typedef struct _expr_t expr_t; typedef struct _type_t type_t; @@ -177,7 +173,7 @@ struct _type_t { var_t *fields; int ignore, is_const, sign; int defined, written; - + int typelib_idx; /* parser-internal */ DECL_LINK(type_t) }; diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c new file mode 100644 index 00000000000..5f557ee831f --- /dev/null +++ b/tools/widl/write_msft.c @@ -0,0 +1,1603 @@ +/* + * Typelib v2 (MSFT) generation + * + * Copyright 2004 Alastair Bridgewater + * 2004, 2005 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------------------- + * Known problems: + * + * Badly incomplete. + * + * Only works on little-endian systems. + * + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#include +#include + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "winerror.h" +#include "windef.h" +#include "winbase.h" +#include "winnls.h" + +#include "wine/unicode.h" + +#include "widltypes.h" +#include "typelib.h" +#include "typelib_struct.h" +#include "utils.h" +#include "hash.h" + +enum MSFT_segment_index { + MSFT_SEG_TYPEINFO = 0, /* type information */ + MSFT_SEG_IMPORTINFO, /* import information */ + MSFT_SEG_IMPORTFILES, /* import filenames */ + MSFT_SEG_REFERENCES, /* references (?) */ + MSFT_SEG_GUIDHASH, /* hash table for guids? */ + MSFT_SEG_GUID, /* guid storage */ + MSFT_SEG_NAMEHASH, /* hash table for names */ + MSFT_SEG_NAME, /* name storage */ + MSFT_SEG_STRING, /* string storage */ + MSFT_SEG_TYPEDESC, /* type descriptions */ + MSFT_SEG_ARRAYDESC, /* array descriptions */ + MSFT_SEG_CUSTDATA, /* custom data */ + MSFT_SEG_CUSTDATAGUID, /* custom data guids */ + MSFT_SEG_UNKNOWN, /* ??? */ + MSFT_SEG_UNKNOWN2, /* ??? */ + MSFT_SEG_MAX /* total number of segments */ +}; + +typedef struct tagMSFT_ImpFile { + int guid; + LCID lcid; + int version; + char filename[0]; /* preceeded by two bytes of encoded (length << 2) + flags in the low two bits. */ +} MSFT_ImpFile; + +typedef struct _msft_typelib_t +{ + typelib_t *typelib; + MSFT_Header typelib_header; + MSFT_pSeg typelib_segdir[MSFT_SEG_MAX]; + char *typelib_segment_data[MSFT_SEG_MAX]; + int typelib_segment_block_length[MSFT_SEG_MAX]; + + INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */ + + INT *typelib_namehash_segment; + INT *typelib_guidhash_segment; + + struct _msft_typeinfo_t *typeinfos; + struct _msft_typeinfo_t *last_typeinfo; +} msft_typelib_t; + +typedef struct _msft_typeinfo_t +{ + msft_typelib_t *typelib; + MSFT_TypeInfoBase *typeinfo; + + INT *typedata; + int typedata_allocated; + int typedata_length; + + int indices[42]; + int names[42]; + int offsets[42]; + + int datawidth; + + struct _msft_typeinfo_t *next_typeinfo; +} msft_typeinfo_t; + + + +/*================== Internal functions ===================================*/ + +/**************************************************************************** + * ctl2_init_header + * + * Initializes the type library header of a new typelib. + */ +static void ctl2_init_header( + msft_typelib_t *typelib) /* [I] The typelib to initialize. */ +{ + typelib->typelib_header.magic1 = 0x5446534d; + typelib->typelib_header.magic2 = 0x00010002; + typelib->typelib_header.posguid = -1; + typelib->typelib_header.lcid = 0x0409; /* or do we use the current one? */ + typelib->typelib_header.lcid2 = 0x0; + typelib->typelib_header.varflags = 0x40; + typelib->typelib_header.version = 0; + typelib->typelib_header.flags = 0; + typelib->typelib_header.nrtypeinfos = 0; + typelib->typelib_header.helpstring = -1; + typelib->typelib_header.helpstringcontext = 0; + typelib->typelib_header.helpcontext = 0; + typelib->typelib_header.nametablecount = 0; + typelib->typelib_header.nametablechars = 0; + typelib->typelib_header.NameOffset = -1; + typelib->typelib_header.helpfile = -1; + typelib->typelib_header.CustomDataOffset = -1; + typelib->typelib_header.res44 = 0x20; + typelib->typelib_header.res48 = 0x80; + typelib->typelib_header.dispatchpos = -1; + typelib->typelib_header.res50 = 0; +} + +/**************************************************************************** + * ctl2_init_segdir + * + * Initializes the segment directory of a new typelib. + */ +static void ctl2_init_segdir( + msft_typelib_t *typelib) /* [I] The typelib to initialize. */ +{ + int i; + MSFT_pSeg *segdir; + + segdir = &typelib->typelib_segdir[MSFT_SEG_TYPEINFO]; + + for (i = 0; i < 15; i++) { + segdir[i].offset = -1; + segdir[i].length = 0; + segdir[i].res08 = -1; + segdir[i].res0c = 0x0f; + } +} + +/**************************************************************************** + * ctl2_hash_guid + * + * Generates a hash key from a GUID. + * + * RETURNS + * + * The hash key for the GUID. + */ +static int ctl2_hash_guid( + REFGUID guid) /* [I] The guid to find. */ +{ + int hash; + int i; + + hash = 0; + for (i = 0; i < 8; i ++) { + hash ^= ((const short *)guid)[i]; + } + + return (hash & 0xf) | ((hash & 0x10) & (0 - !!(hash & 0xe0))); +} + +/**************************************************************************** + * ctl2_find_guid + * + * Locates a guid in a type library. + * + * RETURNS + * + * The offset into the GUID segment of the guid, or -1 if not found. + */ +static int ctl2_find_guid( + msft_typelib_t *typelib, /* [I] The typelib to operate against. */ + int hash_key, /* [I] The hash key for the guid. */ + REFGUID guid) /* [I] The guid to find. */ +{ + int offset; + MSFT_GuidEntry *guidentry; + + offset = typelib->typelib_guidhash_segment[hash_key]; + while (offset != -1) { + guidentry = (MSFT_GuidEntry *)&typelib->typelib_segment_data[MSFT_SEG_GUID][offset]; + + if (!memcmp(guidentry, guid, sizeof(GUID))) return offset; + + offset = guidentry->next_hash; + } + + return offset; +} + +/**************************************************************************** + * ctl2_find_name + * + * Locates a name in a type library. + * + * RETURNS + * + * The offset into the NAME segment of the name, or -1 if not found. + * + * NOTES + * + * The name must be encoded as with ctl2_encode_name(). + */ +static int ctl2_find_name( + msft_typelib_t *typelib, /* [I] The typelib to operate against. */ + char *name) /* [I] The encoded name to find. */ +{ + int offset; + int *namestruct; + + offset = typelib->typelib_namehash_segment[name[2] & 0x7f]; + while (offset != -1) { + namestruct = (int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][offset]; + + if (!((namestruct[2] ^ *((int *)name)) & 0xffff00ff)) { + /* hash codes and lengths match, final test */ + if (!strncasecmp(name+4, (void *)(namestruct+3), name[0])) break; + } + + /* move to next item in hash bucket */ + offset = namestruct[1]; + } + + return offset; +} + +/**************************************************************************** + * ctl2_encode_name + * + * Encodes a name string to a form suitable for storing into a type library + * or comparing to a name stored in a type library. + * + * RETURNS + * + * The length of the encoded name, including padding and length+hash fields. + * + * NOTES + * + * Will throw an exception if name or result are NULL. Is not multithread + * safe in the slightest. + */ +static int ctl2_encode_name( + msft_typelib_t *typelib, /* [I] The typelib to operate against (used for LCID only). */ + const char *name, /* [I] The name string to encode. */ + char **result) /* [O] A pointer to a pointer to receive the encoded name. */ +{ + int length; + static char converted_name[0x104]; + int offset; + int value; + + length = strlen(name); + memcpy(converted_name + 4, name, length); + converted_name[0] = length & 0xff; + + converted_name[length + 4] = 0; + + converted_name[1] = 0x00; + + value = lhash_val_of_name_sys(typelib->typelib_header.varflags & 0x0f, typelib->typelib_header.lcid, converted_name + 4); + + converted_name[2] = value; + converted_name[3] = value >> 8; + + for (offset = (4 - length) & 3; offset; offset--) converted_name[length + offset + 3] = 0x57; + + *result = converted_name; + + return (length + 7) & ~3; +} + +/**************************************************************************** + * ctl2_encode_string + * + * Encodes a string to a form suitable for storing into a type library or + * comparing to a string stored in a type library. + * + * RETURNS + * + * The length of the encoded string, including padding and length fields. + * + * NOTES + * + * Will throw an exception if string or result are NULL. Is not multithread + * safe in the slightest. + */ +static int ctl2_encode_string( + msft_typelib_t *typelib, /* [I] The typelib to operate against (not used?). */ + const char *string, /* [I] The string to encode. */ + char **result) /* [O] A pointer to a pointer to receive the encoded string. */ +{ + int length; + static char converted_string[0x104]; + int offset; + + length = strlen(string); + memcpy(converted_string + 2, string, length); + converted_string[0] = length & 0xff; + converted_string[1] = (length >> 8) & 0xff; + + for (offset = (4 - (length + 2)) & 3; offset; offset--) converted_string[length + offset + 1] = 0x57; + + *result = converted_string; + + return (length + 5) & ~3; +} + +/**************************************************************************** + * ctl2_alloc_segment + * + * Allocates memory from a segment in a type library. + * + * RETURNS + * + * Success: The offset within the segment of the new data area. + * Failure: -1 (this is invariably an out of memory condition). + * + * BUGS + * + * Does not (yet) handle the case where the allocated segment memory needs to grow. + */ +static int ctl2_alloc_segment( + msft_typelib_t *typelib, /* [I] The type library in which to allocate. */ + enum MSFT_segment_index segment, /* [I] The segment in which to allocate. */ + int size, /* [I] The amount to allocate. */ + int block_size) /* [I] Initial allocation block size, or 0 for default. */ +{ + int offset; + + if(!typelib->typelib_segment_data[segment]) { + if (!block_size) block_size = 0x2000; + + typelib->typelib_segment_block_length[segment] = block_size; + typelib->typelib_segment_data[segment] = xmalloc(block_size); + if (!typelib->typelib_segment_data[segment]) return -1; + memset(typelib->typelib_segment_data[segment], 0x57, block_size); + } + + while ((typelib->typelib_segdir[segment].length + size) > typelib->typelib_segment_block_length[segment]) { + char *block; + + block_size = typelib->typelib_segment_block_length[segment]; + block = realloc(typelib->typelib_segment_data[segment], block_size << 1); + if (!block) return -1; + + if (segment == MSFT_SEG_TYPEINFO) { + /* TypeInfos have a direct pointer to their memory space, so we have to fix them up. */ + msft_typeinfo_t *typeinfo; + + for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { + typeinfo->typeinfo = (void *)&block[((char *)typeinfo->typeinfo) - typelib->typelib_segment_data[segment]]; + } + } + + memset(block + block_size, 0x57, block_size); + typelib->typelib_segment_block_length[segment] = block_size << 1; + typelib->typelib_segment_data[segment] = block; + } + + offset = typelib->typelib_segdir[segment].length; + typelib->typelib_segdir[segment].length += size; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_typeinfo + * + * Allocates and initializes a typeinfo structure in a type library. + * + * RETURNS + * + * Success: The offset of the new typeinfo. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_typeinfo( + msft_typelib_t *typelib, /* [I] The type library to allocate in. */ + int nameoffset) /* [I] The offset of the name for this typeinfo. */ +{ + int offset; + MSFT_TypeInfoBase *typeinfo; + + offset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0); + if (offset == -1) return -1; + + typelib->typelib_typeinfo_offsets[typelib->typelib_header.nrtypeinfos++] = offset; + + typeinfo = (void *)(typelib->typelib_segment_data[MSFT_SEG_TYPEINFO] + offset); + + typeinfo->typekind = (typelib->typelib_header.nrtypeinfos - 1) << 16; + typeinfo->memoffset = -1; /* should be EOF if no elements */ + typeinfo->res2 = 0; + typeinfo->res3 = -1; + typeinfo->res4 = 3; + typeinfo->res5 = 0; + typeinfo->cElement = 0; + typeinfo->res7 = 0; + typeinfo->res8 = 0; + typeinfo->res9 = 0; + typeinfo->resA = 0; + typeinfo->posguid = -1; + typeinfo->flags = 0; + typeinfo->NameOffset = nameoffset; + typeinfo->version = 0; + typeinfo->docstringoffs = -1; + typeinfo->helpstringcontext = 0; + typeinfo->helpcontext = 0; + typeinfo->oCustData = -1; + typeinfo->cbSizeVft = 0; + typeinfo->cImplTypes = 0; + typeinfo->size = 0; + typeinfo->datatype1 = -1; + typeinfo->datatype2 = 0; + typeinfo->res18 = 0; + typeinfo->res19 = -1; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_guid + * + * Allocates and initializes a GUID structure in a type library. Also updates + * the GUID hash table as needed. + * + * RETURNS + * + * Success: The offset of the new GUID. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_guid( + msft_typelib_t *typelib, /* [I] The type library to allocate in. */ + MSFT_GuidEntry *guid) /* [I] The GUID to store. */ +{ + int offset; + MSFT_GuidEntry *guid_space; + int hash_key; + + hash_key = ctl2_hash_guid(&guid->guid); + + offset = ctl2_find_guid(typelib, hash_key, &guid->guid); + if (offset != -1) return offset; + + offset = ctl2_alloc_segment(typelib, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0); + if (offset == -1) return -1; + + guid_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_GUID] + offset); + *guid_space = *guid; + + guid_space->next_hash = typelib->typelib_guidhash_segment[hash_key]; + typelib->typelib_guidhash_segment[hash_key] = offset; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_name + * + * Allocates and initializes a name within a type library. Also updates the + * name hash table as needed. + * + * RETURNS + * + * Success: The offset within the segment of the new name. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_name( + msft_typelib_t *typelib, /* [I] The type library to allocate in. */ + const char *name) /* [I] The name to store. */ +{ + int length; + int offset; + MSFT_NameIntro *name_space; + char *encoded_name; + + length = ctl2_encode_name(typelib, name, &encoded_name); + + offset = ctl2_find_name(typelib, encoded_name); + if (offset != -1) return offset; + + offset = ctl2_alloc_segment(typelib, MSFT_SEG_NAME, length + 8, 0); + if (offset == -1) return -1; + + name_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_NAME] + offset); + name_space->hreftype = -1; + name_space->next_hash = -1; + memcpy(&name_space->namelen, encoded_name, length); + + if (typelib->typelib_namehash_segment[encoded_name[2] & 0x7f] != -1) + name_space->next_hash = typelib->typelib_namehash_segment[encoded_name[2] & 0x7f]; + + typelib->typelib_namehash_segment[encoded_name[2] & 0x7f] = offset; + + typelib->typelib_header.nametablecount += 1; + typelib->typelib_header.nametablechars += *encoded_name; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_string + * + * Allocates and initializes a string in a type library. + * + * RETURNS + * + * Success: The offset within the segment of the new string. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_string( + msft_typelib_t *typelib, /* [I] The type library to allocate in. */ + const char *string) /* [I] The string to store. */ +{ + int length; + int offset; + char *string_space; + char *encoded_string; + + length = ctl2_encode_string(typelib, string, &encoded_string); + + for (offset = 0; offset < typelib->typelib_segdir[MSFT_SEG_STRING].length; + offset += ((((typelib->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) & 0xff) + | (typelib->typelib_segment_data[MSFT_SEG_STRING][offset + 0] & 0xff)) + 5) & ~3) { + if (!memcmp(encoded_string, typelib->typelib_segment_data[MSFT_SEG_STRING] + offset, length)) return offset; + } + + offset = ctl2_alloc_segment(typelib, MSFT_SEG_STRING, length, 0); + if (offset == -1) return -1; + + string_space = typelib->typelib_segment_data[MSFT_SEG_STRING] + offset; + memcpy(string_space, encoded_string, length); + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_importinfo + * + * Allocates and initializes an import information structure in a type library. + * + * RETURNS + * + * Success: The offset of the new importinfo. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_importinfo( + msft_typelib_t *typelib, /* [I] The type library to allocate in. */ + MSFT_ImpInfo *impinfo) /* [I] The import information to store. */ +{ + int offset; + MSFT_ImpInfo *impinfo_space; + + for (offset = 0; + offset < typelib->typelib_segdir[MSFT_SEG_IMPORTINFO].length; + offset += sizeof(MSFT_ImpInfo)) { + if (!memcmp(&(typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO][offset]), + impinfo, sizeof(MSFT_ImpInfo))) { + return offset; + } + } + + offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0); + if (offset == -1) return -1; + + impinfo_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO] + offset); + *impinfo_space = *impinfo; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_importfile + * + * Allocates and initializes an import file definition in a type library. + * + * RETURNS + * + * Success: The offset of the new importinfo. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_importfile( + msft_typelib_t *typelib, /* [I] The type library to allocate in. */ + int guidoffset, /* [I] The offset to the GUID for the imported library. */ + int major_version, /* [I] The major version number of the imported library. */ + int minor_version, /* [I] The minor version number of the imported library. */ + const char *filename) /* [I] The filename of the imported library. */ +{ + int length; + int offset; + MSFT_ImpFile *importfile; + char *encoded_string; + + length = ctl2_encode_string(typelib, filename, &encoded_string); + + encoded_string[0] <<= 2; + encoded_string[0] |= 1; + + for (offset = 0; offset < typelib->typelib_segdir[MSFT_SEG_IMPORTFILES].length; + offset += ((((typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xd] << 8) & 0xff) + | (typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xc] & 0xff)) >> 2) + 0xc) { + if (!memcmp(encoded_string, typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES] + offset + 0xc, length)) return offset; + } + + offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTFILES, length + 0xc, 0); + if (offset == -1) return -1; + + importfile = (MSFT_ImpFile *)&typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset]; + importfile->guid = guidoffset; + importfile->lcid = typelib->typelib_header.lcid2; + importfile->version = major_version | (minor_version << 16); + memcpy(&importfile->filename, encoded_string, length); + + return offset; +} + + +/**************************************************************************** + * ctl2_encode_typedesc + * + * Encodes a type description, storing information in the TYPEDESC and ARRAYDESC + * segments as needed. + * + * RETURNS + * + * Success: 0. + * Failure: -1. + */ +static int ctl2_encode_type( + msft_typelib_t *typelib, /* [I] The type library in which to encode the TYPEDESC. */ + type_t *type, /* [I] The type description to encode. */ + int ptr_level, /* [I] ptr level */ + expr_t *array, /* [I] arrary description */ + int *encoded_type, /* [O] The encoded type description. */ + int *width, /* [O] The width of the type, or NULL. */ + int *alignment, /* [O] The alignment of the type, or NULL. */ + int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */ +{ + int default_type; + int scratch; + int typeoffset; + int arrayoffset; + int *typedata; + int *arraydata; + int target_type; + int child_size; + unsigned short vt = get_type_vt(type); + + chat("encode_type vt %d ptr_level %d\n", vt, ptr_level); + + default_type = 0x80000000 | (vt << 16) | vt; + if (!width) width = &scratch; + if (!alignment) alignment = &scratch; + if (!decoded_size) decoded_size = &scratch; + + *decoded_size = 0; + + if(ptr_level--) { + + ctl2_encode_type(typelib, type, ptr_level, array, &target_type, NULL, NULL, &child_size); + + for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + if (((typedata[0] & 0xffff) == VT_PTR) && (typedata[1] == target_type)) break; + } + + if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { + int mix_field; + + if (target_type & 0x80000000) { + mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF; + } else { + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; + mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; + } + + typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (mix_field << 16) | VT_PTR; + typedata[1] = target_type; + } + + *encoded_type = typeoffset; + + *width = 4; + *alignment = 4; + *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; + return 0; + } + + if(array) { + expr_t *dim = array; + int num_dims = 1, elements = 1; + + while(NEXT_LINK(dim)) { + dim = NEXT_LINK(dim); + num_dims++; + } + chat("array with %d dimensions\n", num_dims); + ctl2_encode_type(typelib, type, 0, NULL, &target_type, width, alignment, NULL); + arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(long), 0); + arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset]; + + arraydata[0] = target_type; + arraydata[1] = num_dims; + arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16); + + arraydata += 2; + while(dim) { + arraydata[0] = dim->cval; + arraydata[1] = 0; + arraydata += 2; + elements *= dim->cval; + dim = PREV_LINK(dim); + } + + typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (0x7ffe << 16) | VT_CARRAY; + typedata[1] = arrayoffset; + + *encoded_type = typeoffset; + *width = *width * elements; + *decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/; + return 0; + } + + switch (vt) { + case VT_I1: + case VT_UI1: + *encoded_type = default_type; + *width = 1; + *alignment = 1; + break; + + case VT_INT: + *encoded_type = 0x80000000 | (VT_I4 << 16) | VT_INT; + if ((typelib->typelib_header.varflags & 0x0f) == SYS_WIN16) { + *width = 2; + *alignment = 2; + } else { + *width = 4; + *alignment = 4; + } + break; + + case VT_UINT: + *encoded_type = 0x80000000 | (VT_UI4 << 16) | VT_UINT; + if ((typelib->typelib_header.varflags & 0x0f) == SYS_WIN16) { + *width = 2; + *alignment = 2; + } else { + *width = 4; + *alignment = 4; + } + break; + + case VT_UI2: + case VT_I2: + case VT_BOOL: + *encoded_type = default_type; + *width = 2; + *alignment = 2; + break; + + case VT_I4: + case VT_UI4: + case VT_R4: + case VT_ERROR: + case VT_BSTR: + case VT_HRESULT: + *encoded_type = default_type; + *width = 4; + *alignment = 4; + break; + + case VT_CY: + *encoded_type = default_type; + *width = 8; + *alignment = 4; /* guess? */ + break; + + case VT_VOID: + *encoded_type = 0x80000000 | (VT_EMPTY << 16) | vt; + *width = 0; + *alignment = 1; + break; + +#if 0 + + + case VT_SAFEARRAY: + /* FIXME: Make with the error checking. */ + FIXME("SAFEARRAY vartype, may not work correctly.\n"); + + ctl2_encode_typedesc(typelib, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size); + + for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + if (((typedata[0] & 0xffff) == VT_SAFEARRAY) && (typedata[1] == target_type)) break; + } + + if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { + int mix_field; + + if (target_type & 0x80000000) { + mix_field = ((target_type >> 16) & VT_TYPEMASK) | VT_ARRAY; + } else { + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; + mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; + } + + typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (mix_field << 16) | VT_SAFEARRAY; + typedata[1] = target_type; + } + + *encoded_tdesc = typeoffset; + + *width = 4; + *alignment = 4; + *decoded_size = sizeof(TYPEDESC) + child_size; + break; + + +#endif + + case VT_USERDEFINED: + { + int typeinfo_offset; + chat("USERDEFINED.\n"); + chat("type %p name = %s idx %d\n", type, type->name, type->typelib_idx); + + if(type->typelib_idx == -1) + error("trying to ref not added type\n"); + + typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx]; + for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + if ((typedata[0] == ((0x7fff << 16) | VT_USERDEFINED)) && (typedata[1] == typeinfo_offset)) break; + } + + if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { + typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (0x7fff << 16) | VT_USERDEFINED; + typedata[1] = typeinfo_offset; + } + + *encoded_type = typeoffset; + *width = 0; + *alignment = 1; + break; + } + + default: + error("Unrecognized type %d.\n", vt); + *encoded_type = default_type; + *width = 0; + *alignment = 1; + break; + } + + return 0; +} + +/**************************************************************************** + * ctl2_find_nth_reference + * + * Finds a reference by index into the linked list of reference records. + * + * RETURNS + * + * Success: Offset of the desired reference record. + * Failure: -1. + */ +static int ctl2_find_nth_reference( + msft_typelib_t *typelib, /* [I] The type library in which to search. */ + int offset, /* [I] The starting offset of the reference list. */ + int index) /* [I] The index of the reference to find. */ +{ + MSFT_RefRecord *ref; + + for (; index && (offset != -1); index--) { + ref = (MSFT_RefRecord *)&typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset]; + offset = ref->onext; + } + + return offset; +} + + +static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func) +{ + int offset; + int *typedata; + int i, index = func->idx, id; + int decoded_size; + int num_params = 0; + var_t *arg, *last_arg = NULL; + char *namedata; + attr_t *attr; + unsigned int funcflags = 0, callconv = 4; + + id = ((0x6000 | typeinfo->typeinfo->cImplTypes) << 16) | index; + + chat("(%p,%d)\n", typeinfo, index); + + if (!typeinfo->typedata) { + typeinfo->typedata = xmalloc(0x2000); + typeinfo->typedata[0] = 0; + } + + for(arg = func->args; arg; arg = NEXT_LINK(arg)) { + last_arg = arg; + num_params++; + } + + chat("num of params %d\n", num_params); + + for(attr = func->def->attrs; attr; attr = NEXT_LINK(attr)) { + switch(attr->type) { + case ATTR_ID: + { + expr_t *expr = attr->u.pval; + id = expr->u.lval; + break; + } + case ATTR_OUT: + break; + + default: + warning("ignoring attr %d\n", attr->type); + break; + } + } + /* allocate type data space for us */ + offset = typeinfo->typedata[0]; + typeinfo->typedata[0] += 0x18 + (num_params * 12); + typedata = typeinfo->typedata + (offset >> 2) + 1; + + /* fill out the basic type information */ + typedata[0] = (0x18 + (num_params * 12)) | (index << 16); + ctl2_encode_type(typeinfo->typelib, func->def->type, func->def->ptr_level, func->def->array, &typedata[1], NULL, NULL, &decoded_size); + typedata[2] = funcflags; + typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft; + typedata[4] = (index << 16) | (callconv << 8) | 9; + typedata[5] = num_params; + + /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */ + /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */ + typedata[3] += (16 /*sizeof(ELEMDESC)*/ * num_params) << 16; + + for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) { + attr_t *attr; + int paramflags = 0; + + for(attr = arg->attrs; attr; attr = NEXT_LINK(attr)) { + switch(attr->type) { + case ATTR_IN: + paramflags |= 0x01; /* PARAMFLAG_FIN */ + break; + case ATTR_OUT: + paramflags |= 0x02; /* PARAMFLAG_FOUT */ + break; + case ATTR_RETVAL: + paramflags |= 0x08; /* PARAMFLAG_FRETVAL */ + break; + default: + chat("unhandled param attr %d\n", attr->type); + break; + } + } + ctl2_encode_type(typeinfo->typelib, arg->type, arg->ptr_level, arg->array, &typedata[6+(i*3)], NULL, NULL, &decoded_size); + typedata[7+(i*3)] = -1; + typedata[8+(i*3)] = paramflags; + typedata[3] += decoded_size << 16; + +#if 0 + /* FIXME: Doesn't work. Doesn't even come up with usable VTs for varDefaultValue. */ + if (pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) { + ctl2_alloc_custdata(This->typelib, &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue); + } +#endif + } + + /* update the index data */ + typeinfo->indices[index] = id; + typeinfo->names[index] = -1; + typeinfo->offsets[index] = offset; + + /* ??? */ + if (!typeinfo->typeinfo->res2) typeinfo->typeinfo->res2 = 0x20; + typeinfo->typeinfo->res2 <<= 1; + + /* ??? */ + if (typeinfo->typeinfo->res3 == -1) typeinfo->typeinfo->res3 = 0; + typeinfo->typeinfo->res3 += 0x38; + + /* ??? */ + if (index < 2) typeinfo->typeinfo->res2 += num_params << 4; + typeinfo->typeinfo->res3 += num_params << 4; + + /* adjust size of VTBL */ + typeinfo->typeinfo->cbSizeVft += 4; + + /* Increment the number of function elements */ + typeinfo->typeinfo->cElement += 1; + + + offset = ctl2_alloc_name(typeinfo->typelib, func->def->name); + chat("name offset = %d index %d\n", offset, index); + typeinfo->names[index] = offset; + + namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset; + namedata[9] &= ~0x10; + if (*((INT *)namedata) == -1) { + *((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16]; + } + + for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) { + /* FIXME: Almost certainly easy to break */ + int *paramdata = &typeinfo->typedata[typeinfo->offsets[index] >> 2]; + + offset = ctl2_alloc_name(typeinfo->typelib, arg->name); + paramdata[(i * 3) + 8] = offset; + chat("param %d name %s offset %d\n", i, arg->name, offset); + } + return S_OK; +} + + +static void set_alignment( + msft_typeinfo_t* typeinfo, + WORD cbAlignment) +{ + + if (!cbAlignment) return; + if (cbAlignment > 16) return; + + typeinfo->typeinfo->typekind &= ~0xffc0; + typeinfo->typeinfo->typekind |= cbAlignment << 6; + + /* FIXME: There's probably some way to simplify this. */ + switch (typeinfo->typeinfo->typekind & 15) { + case TKIND_ALIAS: + default: + break; + + case TKIND_ENUM: + case TKIND_INTERFACE: + case TKIND_DISPATCH: + case TKIND_COCLASS: + if (cbAlignment > 4) cbAlignment = 4; + break; + + case TKIND_RECORD: + case TKIND_MODULE: + case TKIND_UNION: + cbAlignment = 1; + break; + } + + typeinfo->typeinfo->typekind |= cbAlignment << 11; + + return; +} + +static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var) +{ + int offset; + INT *typedata; + int var_datawidth; + int var_alignment; + int var_type_size; + int alignment; + int varflags = 0; + attr_t *attr; + char *namedata; + + chat("add_var_desc(%d,%s) array %p\n", index, var->name, var->array); + + if ((typeinfo->typeinfo->cElement >> 16) != index) { + error("Out-of-order element.\n"); + return TYPE_E_ELEMENTNOTFOUND; + } + + + for(attr = var->attrs; attr; attr = NEXT_LINK(attr)) { + switch(attr->type) { + default: + warning("AddVarDesc: unhandled attr type %d\n", attr->type); + break; + } + } + + if (!typeinfo->typedata) { + typeinfo->typedata = xmalloc(0x2000); + typeinfo->typedata[0] = 0; + } + + /* allocate type data space for us */ + offset = typeinfo->typedata[0]; + typeinfo->typedata[0] += 0x14; + typedata = typeinfo->typedata + (offset >> 2) + 1; + + /* fill out the basic type information */ + typedata[0] = 0x14 | (index << 16); + typedata[2] = varflags; + typedata[3] = (36 /*sizeof(VARDESC)*/ << 16) | 0; + + /* update the index data */ + typeinfo->indices[index] = 0x40000000 + index; + typeinfo->names[index] = -1; + typeinfo->offsets[index] = offset; + + /* figure out type widths and whatnot */ + ctl2_encode_type(typeinfo->typelib, var->type, var->ptr_level, var->array, + &typedata[1], &var_datawidth, &var_alignment, + &var_type_size); + + /* pad out starting position to data width */ + typeinfo->datawidth += var_alignment - 1; + typeinfo->datawidth &= ~(var_alignment - 1); + typedata[4] = typeinfo->datawidth; + + /* add the new variable to the total data width */ + typeinfo->datawidth += var_datawidth; + + /* add type description size to total required allocation */ + typedata[3] += var_type_size << 16; + + /* fix type alignment */ + alignment = (typeinfo->typeinfo->typekind >> 11) & 0x1f; + if (alignment < var_alignment) { + alignment = var_alignment; + typeinfo->typeinfo->typekind &= ~0xf800; + typeinfo->typeinfo->typekind |= alignment << 11; + } + + /* ??? */ + if (!typeinfo->typeinfo->res2) typeinfo->typeinfo->res2 = 0x1a; + if ((index == 0) || (index == 1) || (index == 2) || (index == 4) || (index == 9)) { + typeinfo->typeinfo->res2 <<= 1; + } + + /* ??? */ + if (typeinfo->typeinfo->res3 == -1) typeinfo->typeinfo->res3 = 0; + typeinfo->typeinfo->res3 += 0x2c; + + /* increment the number of variable elements */ + typeinfo->typeinfo->cElement += 0x10000; + + /* pad data width to alignment */ + typeinfo->typeinfo->size = (typeinfo->datawidth + (alignment - 1)) & ~(alignment - 1); + + offset = ctl2_alloc_name(typeinfo->typelib, var->name); + if (offset == -1) return E_OUTOFMEMORY; + + namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset; + if (*((INT *)namedata) == -1) { + *((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16]; + namedata[9] |= 0x10; + } + if ((typeinfo->typeinfo->typekind & 15) == TKIND_ENUM) { + namedata[9] |= 0x20; + } + typeinfo->names[index] = offset; + + return S_OK; +} + + +static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, typelib_entry_t *entry, int idx) +{ + msft_typeinfo_t *msft_typeinfo; + int nameoffset; + int typeinfo_offset; + MSFT_TypeInfoBase *typeinfo; + char *name; + MSFT_GuidEntry guidentry; + attr_t *attr; + + switch(entry->kind) { + case TKIND_INTERFACE: + name = entry->u.interface->name; + attr = entry->u.interface->attrs; + entry->u.interface->typelib_idx = idx; + break; + case TKIND_MODULE: + name = entry->u.module->name; + attr = entry->u.module->attrs; + break; + case TKIND_COCLASS: + name = entry->u.class->name; + attr = entry->u.class->attrs; + break; + case TKIND_RECORD: + name = entry->u.structure->name; + attr = entry->u.structure->attrs; + entry->u.structure->typelib_idx = idx; + chat("type = %p\n", entry->u.structure); + break; + default: + error("create_msft_typeinfo: unhandled type %d\n", entry->kind); + return NULL; + } + + + chat("Constructing msft_typeinfo for name %s kind %d\n", name, entry->kind); + + msft_typeinfo = xmalloc(sizeof(*msft_typeinfo)); + + msft_typeinfo->typelib = typelib; + + nameoffset = ctl2_alloc_name(typelib, name); + typeinfo_offset = ctl2_alloc_typeinfo(typelib, nameoffset); + typeinfo = (MSFT_TypeInfoBase *)&typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][typeinfo_offset]; + + typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset + 9] = 0x38; + *((int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset]) = typeinfo_offset; + + msft_typeinfo->typeinfo = typeinfo; + + typeinfo->typekind |= entry->kind | 0x20; + set_alignment(msft_typeinfo, 4); + + switch (entry->kind) { + case TKIND_ENUM: + case TKIND_INTERFACE: + case TKIND_DISPATCH: + case TKIND_COCLASS: + typeinfo->size = 4; + break; + + case TKIND_RECORD: + case TKIND_UNION: + typeinfo->size = 0; + break; + + case TKIND_MODULE: + typeinfo->size = 2; + break; + + case TKIND_ALIAS: + typeinfo->size = -0x75; + break; + + default: + error("%s unrecognized typekind %d\n", name, entry->kind); + typeinfo->size = 0xdeadbeef; + break; + } + + + for( ; attr; attr = NEXT_LINK(attr)) { + if(attr->type == ATTR_UUID) { + guidentry.guid = *(GUID*)attr->u.pval; + guidentry.hreftype = typelib->typelib_typeinfo_offsets[typeinfo->typekind >> 16]; + guidentry.next_hash = -1; + typeinfo->posguid = ctl2_alloc_guid(typelib, &guidentry); +#if 0 + if (IsEqualIID(guid, &IID_IDispatch)) { + typelib->typelib_header.dispatchpos = typelib->typelib_typeinfo_offsets[typeinfo->typekind >> 16]; + } +#endif + } + } + + if (typelib->last_typeinfo) typelib->last_typeinfo->next_typeinfo = msft_typeinfo; + typelib->last_typeinfo = msft_typeinfo; + if (!typelib->typeinfos) typelib->typeinfos = msft_typeinfo; + + + return msft_typeinfo; +} + + +static void set_name(msft_typelib_t *typelib) +{ + int offset; + + offset = ctl2_alloc_name(typelib, typelib->typelib->name); + if (offset == -1) return; + typelib->typelib_header.NameOffset = offset; + return; +} + +static void set_version(msft_typelib_t *typelib) +{ + long version = MAKELONG(0,0); + attr_t *attr; + + for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { + if(attr->type == ATTR_VERSION) { + version = attr->u.ival; + } + } + typelib->typelib_header.version = version; + return; +} + +static void set_guid(msft_typelib_t *typelib) +{ + MSFT_GuidEntry guidentry; + int offset; + attr_t *attr; + GUID guid = {0,0,0,{0,0,0,0,0,0}}; + + guidentry.guid = guid; + guidentry.hreftype = -2; + guidentry.next_hash = -1; + + for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { + if(attr->type == ATTR_UUID) { + guidentry.guid = *(GUID*)(attr->u.pval); + } + } + + offset = ctl2_alloc_guid(typelib, &guidentry); + + if (offset == -1) return; + + typelib->typelib_header.posguid = offset; + + return; +} + +static void set_doc_string(msft_typelib_t *typelib) +{ + attr_t *attr; + int offset; + + for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { + if(attr->type == ATTR_HELPSTRING) { + offset = ctl2_alloc_string(typelib, attr->u.pval); + if (offset == -1) return; + typelib->typelib_header.helpstring = offset; + } + } + return; +} + +static void set_help_file_name(msft_typelib_t *typelib) +{ + int offset; + offset = ctl2_alloc_string(typelib, "help file name"); + if (offset == -1) return; + typelib->typelib_header.helpfile = offset; + typelib->typelib_header.varflags |= 0x10; + return; +} + +static void set_lcid(msft_typelib_t *typelib) +{ + typelib->typelib_header.lcid2 = 0x0; + return; +} + +static void set_lib_flags(msft_typelib_t *typelib) +{ + typelib->typelib_header.flags = 0; + return; +} + +static int ctl2_write_chunk(int fd, void *segment, int length) +{ + if (write(fd, segment, length) != length) { + close(fd); + return 0; + } + return -1; +} + +static int ctl2_write_segment(msft_typelib_t *typelib, int fd, int segment) +{ + if (write(fd, typelib->typelib_segment_data[segment], typelib->typelib_segdir[segment].length) + != typelib->typelib_segdir[segment].length) { + close(fd); + return 0; + } + + return -1; +} + +static void ctl2_finalize_typeinfos(msft_typelib_t *typelib, int filesize) +{ + msft_typeinfo_t *typeinfo; + + for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { + typeinfo->typeinfo->memoffset = filesize; + if (typeinfo->typedata) { + /*LayOut(typeinfo);*/ + filesize += typeinfo->typedata[0] + ((typeinfo->typeinfo->cElement >> 16) * 12) + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4; + } + } +} + +static int ctl2_finalize_segment(msft_typelib_t *typelib, int filepos, int segment) +{ + if (typelib->typelib_segdir[segment].length) { + typelib->typelib_segdir[segment].offset = filepos; + } else { + typelib->typelib_segdir[segment].offset = -1; + } + + return typelib->typelib_segdir[segment].length; +} + + +static void ctl2_write_typeinfos(msft_typelib_t *typelib, int fd) +{ + msft_typeinfo_t *typeinfo; + + for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { + if (!typeinfo->typedata) continue; + + ctl2_write_chunk(fd, typeinfo->typedata, typeinfo->typedata[0] + 4); + ctl2_write_chunk(fd, typeinfo->indices, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4); + chat("writing name chunk len %d %08lx\n", ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4, *(DWORD*)typeinfo->names); + ctl2_write_chunk(fd, typeinfo->names, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4); + ctl2_write_chunk(fd, typeinfo->offsets, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4); + } +} + +static int save_all_changes(msft_typelib_t *typelib) +{ + int retval; + int filepos; + int fd; + + chat("save_all_changes(%p)\n", typelib); + + retval = TYPE_E_IOERROR; + + fd = creat(typelib->typelib->filename, 0666); + if (fd == -1) return retval; + + filepos = sizeof(MSFT_Header) + sizeof(MSFT_SegDir); + filepos += typelib->typelib_header.nrtypeinfos * 4; + + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_TYPEINFO); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_GUIDHASH); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_GUID); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_IMPORTINFO); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_IMPORTFILES); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_REFERENCES); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_NAMEHASH); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_NAME); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_STRING); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_TYPEDESC); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_ARRAYDESC); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_CUSTDATA); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_CUSTDATAGUID); + + ctl2_finalize_typeinfos(typelib, filepos); + + if (!ctl2_write_chunk(fd, &typelib->typelib_header, sizeof(typelib->typelib_header))) return retval; + if (!ctl2_write_chunk(fd, typelib->typelib_typeinfo_offsets, typelib->typelib_header.nrtypeinfos * 4)) return retval; + if (!ctl2_write_chunk(fd, &typelib->typelib_segdir, sizeof(typelib->typelib_segdir))) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_TYPEINFO )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_GUIDHASH )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_GUID )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_IMPORTINFO )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_IMPORTFILES )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_REFERENCES )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_NAMEHASH )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_NAME )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_STRING )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_TYPEDESC )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_ARRAYDESC )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_CUSTDATA )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_CUSTDATAGUID)) return retval; + + ctl2_write_typeinfos(typelib, fd); + + if (close(fd) == -1) return retval; + + retval = S_OK; + return retval; +} + + + + +int create_msft_typelib(typelib_t *typelib) +{ + msft_typelib_t *msft; + int failed = 0, typelib_idx; + typelib_entry_t *entry; + + msft = malloc(sizeof(*msft)); + if (!msft) return 0; + memset(msft, 0, sizeof(*msft)); + msft->typelib = typelib; + + ctl2_init_header(msft); + ctl2_init_segdir(msft); + + msft->typelib_header.varflags |= SYS_WIN32; + + /* + * The following two calls return an offset or -1 if out of memory. We + * specifically need an offset of 0, however, so... + */ + if (ctl2_alloc_segment(msft, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; } + if (ctl2_alloc_segment(msft, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; } + + if(failed) return 0; + + msft->typelib_guidhash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_GUIDHASH]; + msft->typelib_namehash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_NAMEHASH]; + + memset(msft->typelib_guidhash_segment, 0xff, 0x80); + memset(msft->typelib_namehash_segment, 0xff, 0x200); + + set_lib_flags(msft); + set_lcid(msft); +/* set_help_file_name(msft);*/ + set_doc_string(msft); + set_guid(msft); + set_version(msft); + set_name(msft); + + typelib_idx = 0; + for(entry = typelib->entry; NEXT_LINK(entry); entry = NEXT_LINK(entry)) + ; + for( ; entry; entry = PREV_LINK(entry)) { + msft_typeinfo_t *msft_typeinfo = create_msft_typeinfo(msft, entry, typelib_idx); + switch(entry->kind) { + case TKIND_INTERFACE: + { + int idx = 0; + func_t *cur = entry->u.interface->funcs; + while(NEXT_LINK(cur)) cur = NEXT_LINK(cur); + while(cur) { + if(cur->idx == -1) cur->idx = idx; + else if(cur->idx != idx) error("method index mismatch\n"); + add_func_desc(msft_typeinfo, cur); + idx++; + cur = PREV_LINK(cur); + } + break; + } + case TKIND_RECORD: + { + int idx = 0; + var_t *cur = entry->u.structure->fields; + while(NEXT_LINK(cur)) cur = NEXT_LINK(cur); + while(cur) { + add_var_desc(msft_typeinfo, idx, cur); + idx++; + cur = PREV_LINK(cur); + } + break; + } + + default: + error("create_msft_typelib: unhandled type %d\n", entry->kind); + break; + } + typelib_idx++; + } + save_all_changes(msft); + return 1; +}