/*
 *	TYPELIB2
 *
 *	Copyright 2004  Alastair Bridgewater
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * --------------------------------------------------------------------------------------
 *  Known problems:
 *
 *    Badly incomplete.
 *
 *    Only works on little-endian systems.
 *
 */

#include "config.h"
#include "wine/port.h"

#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winreg.h"
#include "winuser.h"

#include "wine/unicode.h"
#include "objbase.h"
#include "typelib.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(typelib2);
/* WINE_DEFAULT_DEBUG_CHANNEL(ole); */


/******************************************************************************
 * ICreateTypeLib2 {OLEAUT32}
 *
 * NOTES
 *  The ICreateTypeLib2 interface provides an interface whereby one may create
 *  new type library (.tlb) files.
 *
 *  This interface inherits from ICreateTypeLib, and can be freely cast back
 *  and forth between an ICreateTypeLib and an ICreateTypeLib2 on local clients.
 *  This dispensation applies only to ICreateTypeLib objects obtained on MSFT
 *  format type libraries (those made through CreateTypeLib2).
 *
 * METHODS
 */

/******************************************************************************
 * ICreateTypeInfo2 {OLEAUT32}
 *
 * NOTES
 *  The ICreateTypeInfo2 interface provides an interface whereby one may add
 *  type information to type library (.tlb) files.
 *
 *  This interface inherits from ICreateTypeInfo, and can be freely cast back
 *  and forth between an ICreateTypeInfo and an ICreateTypeInfo2 on local clients.
 *  This dispensation applies only to ICreateTypeInfo objects obtained on MSFT
 *  format type libraries (those made through CreateTypeLib2).
 *
 * METHODS
 */

/******************************************************************************
 * ITypeLib2 {OLEAUT32}
 *
 * NOTES
 *  The ITypeLib2 interface provides an interface whereby one may query MSFT
 *  format type library (.tlb) files.
 *
 *  This interface inherits from ITypeLib, and can be freely cast back and
 *  forth between an ITypeLib and an ITypeLib2 on local clients. This
 *  dispensation applies only to ITypeLib objects obtained on MSFT format type
 *  libraries (those made through CreateTypeLib2).
 *
 * METHODS
 */

/******************************************************************************
 * ITypeInfo2 {OLEAUT32}
 *
 * NOTES
 *  The ITypeInfo2 interface provides an interface whereby one may query type
 *  information stored in MSFT format type library (.tlb) files.
 *
 *  This interface inherits from ITypeInfo, and can be freely cast back and
 *  forth between an ITypeInfo and an ITypeInfo2 on local clients. This
 *  dispensation applies only to ITypeInfo objects obtained on MSFT format type
 *  libraries (those made through CreateTypeLib2).
 *
 * METHODS
 */

/*================== Implementation Structures ===================================*/

/* Used for storing cyclic list. Tail address is kept */
typedef enum tagCyclicListElementType {
    CyclicListSentinel,
    CyclicListFunc,
    CyclicListVar
} CyclicListElementType;
typedef struct tagCyclicList {
    struct tagCyclicList *next;
    int indice;
    int name;
    CyclicListElementType type;

    union {
        int val;
        int *data;
    }u;
} CyclicList;

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]; /* preceded by two bytes of encoded (length << 2) + flags in the low two bits. */
} MSFT_ImpFile;

typedef struct tagICreateTypeLib2Impl
{
    const ICreateTypeLib2Vtbl *lpVtbl;
    const ITypeLib2Vtbl       *lpVtblTypeLib2;

    LONG ref;

    WCHAR *filename;

    MSFT_Header typelib_header;
    INT helpStringDll;
    MSFT_pSeg typelib_segdir[MSFT_SEG_MAX];
    unsigned char *typelib_segment_data[MSFT_SEG_MAX];
    int typelib_segment_block_length[MSFT_SEG_MAX];

    int typelib_guids; /* Number of defined typelib guids */
    int typeinfo_guids; /* Number of defined typeinfo guids */

    INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */

    INT *typelib_namehash_segment;
    INT *typelib_guidhash_segment;

    struct tagICreateTypeInfo2Impl *typeinfos;
    struct tagICreateTypeInfo2Impl *last_typeinfo;
} ICreateTypeLib2Impl;

static inline ICreateTypeLib2Impl *impl_from_ITypeLib2( ITypeLib2 *iface )
{
    return (ICreateTypeLib2Impl *)((char*)iface - FIELD_OFFSET(ICreateTypeLib2Impl, lpVtblTypeLib2));
}

typedef struct tagICreateTypeInfo2Impl
{
    ICreateTypeInfo2           ICreateTypeInfo2_iface;
    ITypeInfo2                 ITypeInfo2_iface;

    LONG ref;

    ICreateTypeLib2Impl *typelib;
    MSFT_TypeInfoBase *typeinfo;

    struct tagCyclicList *typedata; /* tail of cyclic list */

    TYPEKIND typekind;
    int datawidth;

    struct tagICreateTypeInfo2Impl *next_typeinfo;
    struct tagICreateTypeInfo2Impl *dual;
} ICreateTypeInfo2Impl;

static inline ICreateTypeInfo2Impl *impl_from_ICreateTypeInfo2(ICreateTypeInfo2 *iface)
{
    return CONTAINING_RECORD(iface, ICreateTypeInfo2Impl, ICreateTypeInfo2_iface);
}

static inline ICreateTypeInfo2Impl *impl_from_ITypeInfo2( ITypeInfo2 *iface )
{
    return CONTAINING_RECORD(iface, ICreateTypeInfo2Impl, ITypeInfo2_iface);
}

static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface);

static CyclicList *alloc_cyclic_list_item(CyclicListElementType type)
{
    CyclicList *ret = heap_alloc_zero(sizeof(CyclicList));
    if (!ret)
        return NULL;
    ret->type = type;
    return ret;
}

/*================== Internal functions ===================================*/

static inline UINT cti2_get_var_count(const MSFT_TypeInfoBase *typeinfo)
{
    return typeinfo->cElement >> 16;
}

static inline UINT cti2_get_func_count(const MSFT_TypeInfoBase *typeinfo)
{
    return typeinfo->cElement & 0xFFFF;
}

static inline INT ctl2_get_record_size(const CyclicList *iter)
{
    return iter->u.data[0] & 0xFFFF;
}

static void ctl2_update_var_size(const ICreateTypeInfo2Impl *This, CyclicList *var, int size)
{
    int old = ctl2_get_record_size(var), i;

    if (old >= size) return;

    /* initialize fields included in size but currently unused */
    for (i = old/sizeof(int); i < (size/sizeof(int) - 1); i++)
    {
        /* HelpContext/HelpStringContext being 0 means it's not set */
        var->u.data[i] = (i == 5 || i == 9) ? 0 : -1;
    }

    var->u.data[0] += size - old;
    This->typedata->next->u.val += size - old;
}

/* NOTE: entry always assumed to be a function */
static inline INVOKEKIND ctl2_get_invokekind(const CyclicList *func)
{
    /* INVOKEKIND uses bit flags up to 8 */
    return (func->u.data[4] >> 3) & 0xF;
}

static inline SYSKIND ctl2_get_syskind(const ICreateTypeLib2Impl *This)
{
    return This->typelib_header.varflags & 0xF;
}

/****************************************************************************
 *	ctl2_init_header
 *
 *  Initializes the type library header of a new typelib.
 */
static void ctl2_init_header(
	ICreateTypeLib2Impl *This) /* [I] The typelib to initialize. */
{
    This->typelib_header.magic1 = MSFT_SIGNATURE;
    This->typelib_header.magic2 = 0x00010002;
    This->typelib_header.posguid = -1;
    This->typelib_header.lcid = This->typelib_header.lcid2 = GetUserDefaultLCID();
    This->typelib_header.varflags = 0x40;
    This->typelib_header.version = 0;
    This->typelib_header.flags = 0;
    This->typelib_header.nrtypeinfos = 0;
    This->typelib_header.helpstring = -1;
    This->typelib_header.helpstringcontext = 0;
    This->typelib_header.helpcontext = 0;
    This->typelib_header.nametablecount = 0;
    This->typelib_header.nametablechars = 0;
    This->typelib_header.NameOffset = -1;
    This->typelib_header.helpfile = -1;
    This->typelib_header.CustomDataOffset = -1;
    This->typelib_header.res44 = 0x20;
    This->typelib_header.res48 = 0x80;
    This->typelib_header.dispatchpos = -1;
    This->typelib_header.nimpinfos = 0;
    This->helpStringDll = -1;
}

/****************************************************************************
 *	ctl2_init_segdir
 *
 *  Initializes the segment directory of a new typelib.
 */
static void ctl2_init_segdir(
	ICreateTypeLib2Impl *This) /* [I] The typelib to initialize. */
{
    int i;
    MSFT_pSeg *segdir;

    segdir = &This->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 & 0x1f;
}

/****************************************************************************
 *	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(
	ICreateTypeLib2Impl *This, /* [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 = This->typelib_guidhash_segment[hash_key];
    while (offset != -1) {
	guidentry = (MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][offset];

        if (IsEqualGUID(guidentry, 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(
	ICreateTypeLib2Impl *This, /* [I] The typelib to operate against. */
	const char *name)          /* [I] The encoded name to find. */
{
    int offset;
    int *namestruct;

    offset = This->typelib_namehash_segment[name[2] & 0x7f];
    while (offset != -1) {
	namestruct = (int *)&This->typelib_segment_data[MSFT_SEG_NAME][offset];

	if (!((namestruct[2] ^ *((const 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(
	ICreateTypeLib2Impl *This, /* [I] The typelib to operate against (used for LCID only). */
	const WCHAR *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 = WideCharToMultiByte(CP_ACP, 0, name, strlenW(name), converted_name+4, 0x100, NULL, NULL);
    converted_name[0] = length & 0xff;

    converted_name[length + 4] = 0;

    converted_name[1] = 0x00;

    value = LHashValOfNameSysA(ctl2_get_syskind(This), This->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_decode_name
 *
 * Converts string stored in typelib data to unicode.
 */
static void ctl2_decode_name(
        char *data,         /* [I] String to be decoded */
        WCHAR **string)     /* [O] Decoded string */
{
    int i, length;
    static WCHAR converted_string[0x104];

    length = data[0];

    for(i=0; i<length; i++)
        converted_string[i] = data[i+4];
    converted_string[length] = '\0';

    *string = converted_string;
}

/****************************************************************************
 *	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(
	ICreateTypeLib2Impl *This, /* [I] The typelib to operate against (not used?). */
	const WCHAR *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 = WideCharToMultiByte(CP_ACP, 0, string, strlenW(string), converted_string+2, 0x102, NULL, NULL);
    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_decode_string
 *
 * Converts string stored in typelib data to unicode.
 */
static void ctl2_decode_string(
        unsigned char *data,/* [I] String to be decoded */
        WCHAR **string)     /* [O] Decoded string */
{
    int i, length;
    static WCHAR converted_string[0x104];

    length = data[0] + (data[1]<<8);
    if((length&0x3) == 1)
        length >>= 2;

    for(i=0; i<length; i++)
        converted_string[i] = data[i+2];
    converted_string[length] = '\0';

    *string = converted_string;
}

/****************************************************************************
 *	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(
	ICreateTypeLib2Impl *This,       /* [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(!This->typelib_segment_data[segment]) {
	if (!block_size) block_size = 0x2000;

	This->typelib_segment_block_length[segment] = block_size;
	This->typelib_segment_data[segment] = heap_alloc(block_size);
	if (!This->typelib_segment_data[segment]) return -1;
	memset(This->typelib_segment_data[segment], 0x57, block_size);
    }

    while ((This->typelib_segdir[segment].length + size) > This->typelib_segment_block_length[segment]) {
	unsigned char *block;

	block_size = This->typelib_segment_block_length[segment];
	block = heap_realloc(This->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. */
	    ICreateTypeInfo2Impl *typeinfo;

	    for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
		typeinfo->typeinfo = (void *)&block[((unsigned char *)typeinfo->typeinfo) - This->typelib_segment_data[segment]];
	    }
	}

	memset(block + block_size, 0x57, block_size);
	This->typelib_segment_block_length[segment] = block_size << 1;
	This->typelib_segment_data[segment] = block;
    }

    offset = This->typelib_segdir[segment].length;
    This->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(
	ICreateTypeLib2Impl *This, /* [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(This, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0);
    if (offset == -1) return -1;

    This->typelib_typeinfo_offsets[This->typelib_header.nrtypeinfos++] = offset;

    typeinfo = (void *)(This->typelib_segment_data[MSFT_SEG_TYPEINFO] + offset);

    typeinfo->typekind = (This->typelib_header.nrtypeinfos - 1) << 16;
    typeinfo->memoffset = -1; /* should be EOF if no elements */
    typeinfo->res2 = 0;
    typeinfo->res3 = 0;
    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(
	ICreateTypeLib2Impl *This, /* [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(This, hash_key, &guid->guid);
    if (offset != -1) return offset;

    offset = ctl2_alloc_segment(This, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0);
    if (offset == -1) return -1;

    guid_space = (void *)(This->typelib_segment_data[MSFT_SEG_GUID] + offset);
    *guid_space = *guid;

    guid_space->next_hash = This->typelib_guidhash_segment[hash_key];
    This->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(
	ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
	const WCHAR *name)         /* [I] The name to store. */
{
    int length;
    int offset;
    MSFT_NameIntro *name_space;
    char *encoded_name;

    length = ctl2_encode_name(This, name, &encoded_name);

    offset = ctl2_find_name(This, encoded_name);
    if (offset != -1) return offset;

    offset = ctl2_alloc_segment(This, MSFT_SEG_NAME, length + 8, 0);
    if (offset == -1) return -1;

    name_space = (void *)(This->typelib_segment_data[MSFT_SEG_NAME] + offset);
    name_space->hreftype = -1;
    name_space->next_hash = -1;
    memcpy(&name_space->namelen, encoded_name, length);

    if (This->typelib_namehash_segment[encoded_name[2] & 0x7f] != -1)
	name_space->next_hash = This->typelib_namehash_segment[encoded_name[2] & 0x7f];

    This->typelib_namehash_segment[encoded_name[2] & 0x7f] = offset;

    This->typelib_header.nametablecount += 1;
    This->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(
	ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
	const WCHAR *string)       /* [I] The string to store. */
{
    int length;
    int offset;
    unsigned char *string_space;
    char *encoded_string;

    length = ctl2_encode_string(This, string, &encoded_string);

    for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_STRING].length;
	 offset += (((This->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) |
	     This->typelib_segment_data[MSFT_SEG_STRING][offset + 0]) + 5) & ~3) {
	if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_STRING] + offset, length)) return offset;
    }

    offset = ctl2_alloc_segment(This, MSFT_SEG_STRING, length, 0);
    if (offset == -1) return -1;

    string_space = This->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(
        ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
        MSFT_ImpInfo *impinfo)     /* [I] The import information to store. */
{
    int offset;
    MSFT_ImpInfo *impinfo_space;

    impinfo_space = (MSFT_ImpInfo*)&This->typelib_segment_data[MSFT_SEG_IMPORTINFO][0];
    for (offset=0; offset<This->typelib_segdir[MSFT_SEG_IMPORTINFO].length;
            offset+=sizeof(MSFT_ImpInfo)) {
        if(impinfo_space->oImpFile == impinfo->oImpFile
                && impinfo_space->oGuid == impinfo->oGuid)
            return offset;

        impinfo_space += 1;
    }

    impinfo->flags |= This->typelib_header.nimpinfos++;

    offset = ctl2_alloc_segment(This, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0);
    if (offset == -1) return -1;

    impinfo_space = (void *)(This->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(
	ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
	int guidoffset,            /* [I] The offset to the GUID for the imported library. */
        LCID lcid,                 /* [I] The LCID of 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 WCHAR *filename)     /* [I] The filename of the imported library. */
{
    int length;
    int offset;
    MSFT_ImpFile *importfile;
    char *encoded_string;

    length = ctl2_encode_string(This, filename, &encoded_string);

    encoded_string[0] <<= 2;
    encoded_string[0] |= 1;

    for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_IMPORTFILES].length;
	 offset += (((((This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xd] << 8) |
	     This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xc]) >> 2) + 5) & 0xfffc) + 0xc) {
	if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_IMPORTFILES] + offset + 0xc, length)) return offset;
    }

    offset = ctl2_alloc_segment(This, MSFT_SEG_IMPORTFILES, length + 0xc, 0);
    if (offset == -1) return -1;

    importfile = (MSFT_ImpFile *)&This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset];
    importfile->guid = guidoffset;
    importfile->lcid = lcid;
    importfile->version = major_version | (minor_version << 16);
    memcpy(importfile->filename, encoded_string, length);

    return offset;
}

/****************************************************************************
 *      ctl2_encode_variant
 *
 *  Encodes a variant, inline if possible or in custom data segment
 *
 * RETURNS
 *
 *  Success: S_OK
 *  Failure: Error code from winerror.h
 */
static HRESULT ctl2_encode_variant(
        ICreateTypeLib2Impl *This, /* [I] The typelib to allocate data in */
        int *encoded_value,        /* [O] The encoded default value or data offset */
        VARIANT *value,            /* [I] Default value to be encoded */
        VARTYPE arg_type)          /* [I] Argument type */
{
    VARIANT v;
    HRESULT hres;
    int mask = 0;

    TRACE("%p %d %d\n", This, V_VT(value), arg_type);

    if(arg_type == VT_INT)
        arg_type = VT_I4;
    if(arg_type == VT_UINT)
        arg_type = VT_UI4;

    v = *value;
    if(V_VT(value) != arg_type) {
        hres = VariantChangeType(&v, value, 0, arg_type);
        if(FAILED(hres))
            return hres;
    }

    /* Check if default value can be stored in encoded_value */
    switch(arg_type) {
    case VT_I4:
    case VT_UI4:
        mask = 0x3ffffff;
        if(V_UI4(&v)>0x3ffffff)
            break;
    case VT_I1:
    case VT_UI1:
    case VT_BOOL:
         if(!mask)
             mask = 0xff;
    case VT_I2:
    case VT_UI2:
        if(!mask)
            mask = 0xffff;
        *encoded_value = (V_UI4(&v)&mask) | ((0x80+0x4*arg_type)<<24);
        return S_OK;
    }

    switch(arg_type) {
    case VT_I4:
    case VT_R4:
    case VT_UI4:
    case VT_INT:
    case VT_UINT:
    case VT_HRESULT:
    case VT_PTR: {
        /* Construct the data to be allocated */
        int data[2];
        data[0] = arg_type + (V_UI4(&v)<<16);
        data[1] = (V_UI4(&v)>>16) + 0x57570000;

        /* Check if the data was already allocated */
        /* Currently the structures doesn't allow to do it in a nice way */
        for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-8; *encoded_value+=4)
            if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8))
                return S_OK;

        /* Allocate the data */
        *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, 8, 0);
        if(*encoded_value == -1)
            return E_OUTOFMEMORY;

        memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8);
        return S_OK;
    }
    case VT_BSTR: {
        /* Construct the data */
        int i, len = (6+SysStringLen(V_BSTR(&v))+3) & ~0x3;
        char *data = heap_alloc(len);

        if(!data)
            return E_OUTOFMEMORY;

        *((unsigned short*)data) = arg_type;
        *((unsigned*)(data+2)) = SysStringLen(V_BSTR(&v));
        for(i=0; i<SysStringLen(V_BSTR(&v)); i++) {
            if(V_BSTR(&v)[i] <= 0x7f)
                data[i+6] = V_BSTR(&v)[i];
            else
                data[i+6] = '?';
        }
        WideCharToMultiByte(CP_ACP, 0, V_BSTR(&v), SysStringLen(V_BSTR(&v)), &data[6], len-6, NULL, NULL);
        for(i=6+SysStringLen(V_BSTR(&v)); i<len; i++)
            data[i] = 0x57;

        /* Check if the data was already allocated */
        for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-len; *encoded_value+=4)
            if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len)) {
                heap_free(data);
                return S_OK;
            }

        /* Allocate the data */
        *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, len, 0);
        if(*encoded_value == -1) {
            heap_free(data);
            return E_OUTOFMEMORY;
        }

        memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len);
        heap_free(data);
        return S_OK;
    }
    default:
        FIXME("Argument type not yet handled\n");
        return E_NOTIMPL;
    }
}

static int ctl2_find_custdata(
    ICreateTypeLib2Impl *This,
    REFGUID guid,
    int offset)
{
    while (offset != -1) {
        MSFT_CDGuid *cdentry =
            (MSFT_CDGuid *)&This->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][offset];
        MSFT_GuidEntry *guidentry =
            (MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][cdentry->GuidOffset];

        if (IsEqualGUID(guidentry, guid))
            return offset;

        offset = cdentry->next;
    }

    return -1;
}

/****************************************************************************
 *      ctl2_decode_variant
 *
 *  Decodes a variant
 *
 * RETURNS
 *
 *  Success: S_OK
 *  Failure: Error code from winerror.h
 */
static HRESULT ctl2_decode_variant(
        ICreateTypeLib2Impl *This, /* [I] The typelib that contains the variant */
        int data_offs,             /* [I] Offset within the data array, or the encoded value itself */
        VARIANT *value)            /* [O] Decoded value */
{
    unsigned char *encoded_data;
    VARTYPE type;

    if (data_offs & 0x80000000) {
        /* data_offs contains the encoded value */
        V_VT(value) = (data_offs & ~0x80000000) >> 26;
        V_UI4(value) = data_offs & ~0xFF000000;
        return S_OK;
    }

    encoded_data = &This->typelib_segment_data[MSFT_SEG_CUSTDATA][data_offs];
    type = *encoded_data;

    switch(type) {
    case VT_I4:
    case VT_R4:
    case VT_UI4:
    case VT_INT:
    case VT_UINT:
    case VT_HRESULT:
    case VT_PTR: {
        V_VT(value) = type;
        V_UI4(value) = *(unsigned*)(encoded_data + 2);
        return S_OK;
    }
    case VT_BSTR: {
        unsigned len, i;

        len = *(unsigned*)(encoded_data + 2);

        V_VT(value) = type;
        V_BSTR(value) = SysAllocStringByteLen(NULL, len * sizeof(OLECHAR));
        for (i = 0; i < len; ++i)
            V_BSTR(value)[i] = *(encoded_data + 6 + i);

        return S_OK;
    }
    default:
        FIXME("Don't yet have decoder for this VARTYPE: %u\n", type);
        return E_NOTIMPL;
    }
}

/****************************************************************************
 *	ctl2_set_custdata
 *
 *  Adds a custom data element to an object in a type library.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_INVALIDARG or E_OUTOFMEMORY.
 */
static HRESULT ctl2_set_custdata(
	ICreateTypeLib2Impl *This, /* [I] The type library to store the custom data in. */
	REFGUID guid,              /* [I] The GUID used as a key to retrieve the custom data. */
	VARIANT *pVarVal,          /* [I] The custom data itself. */
	int *offset)               /* [I/O] The list of custom data to prepend to. */
{
    MSFT_GuidEntry guidentry;
    HRESULT status;
    int dataoffset;
    int guidoffset;
    int custoffset;
    int *custdata;
    BOOL new_segment = FALSE;

    switch(V_VT(pVarVal))
    {
    case VT_I4:
    case VT_R4:
    case VT_UI4:
    case VT_INT:
    case VT_UINT:
    case VT_HRESULT:
    case VT_BSTR:
	/* empty */
	break;
    default:
	return DISP_E_BADVARTYPE;
    }

    guidentry.guid = *guid;

    guidentry.hreftype = -1;
    guidentry.next_hash = -1;

    guidoffset = ctl2_alloc_guid(This, &guidentry);
    if (guidoffset == -1) return E_OUTOFMEMORY;

    status = ctl2_encode_variant(This, &dataoffset, pVarVal, V_VT(pVarVal));
    if (status)
	return status;

    custoffset = ctl2_find_custdata(This, guid, *offset);
    if (custoffset == -1) {
        custoffset = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATAGUID, 12, 0);
        if (custoffset == -1)
            return E_OUTOFMEMORY;
        new_segment = TRUE;
    }

    custdata = (int *)&This->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset];
    custdata[0] = guidoffset;
    custdata[1] = dataoffset;
    if (new_segment) {
        custdata[2] = *offset;
        *offset = custoffset;
    }

    return S_OK;
}

/****************************************************************************
 *	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_typedesc(
	ICreateTypeLib2Impl *This, /* [I] The type library in which to encode the TYPEDESC. */
	const TYPEDESC *tdesc,     /* [I] The type description to encode. */
	int *encoded_tdesc,        /* [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_tdesc;
    int scratch;
    int typeoffset;
    int arrayoffset;
    int *typedata;
    int *arraydata;
    int target_type;
    int child_size;

    default_tdesc = 0x80000000 | (tdesc->vt << 16) | tdesc->vt;
    if (!width) width = &scratch;
    if (!alignment) alignment = &scratch;
    if (!decoded_size) decoded_size = &scratch;

    *decoded_size = 0;

    switch (tdesc->vt) {
    case VT_UI1:
    case VT_I1:
	*encoded_tdesc = default_tdesc;
	*width = 1;
	*alignment = 1;
	break;

    case VT_INT:
	*encoded_tdesc = 0x80000000 | (VT_I4 << 16) | VT_INT;
	if (ctl2_get_syskind(This) == SYS_WIN16) {
	    *width = 2;
	    *alignment = 2;
	} else {
	    *width = 4;
	    *alignment = 4;
	}
	break;

    case VT_UINT:
	*encoded_tdesc = 0x80000000 | (VT_UI4 << 16) | VT_UINT;
	if (ctl2_get_syskind(This) == SYS_WIN16) {
	    *width = 2;
	    *alignment = 2;
	} else {
	    *width = 4;
	    *alignment = 4;
	}
	break;

    case VT_UI2:
    case VT_I2:
    case VT_BOOL:
	*encoded_tdesc = default_tdesc;
	*width = 2;
	*alignment = 2;
	break;

    case VT_I4:
    case VT_UI4:
    case VT_R4:
    case VT_ERROR:
    case VT_BSTR:
    case VT_HRESULT:
	*encoded_tdesc = default_tdesc;
	*width = 4;
	*alignment = 4;
	break;

    case VT_CY:
	*encoded_tdesc = default_tdesc;
	*width = 8;
	*alignment = 4; /* guess? */
	break;

    case VT_VOID:
	*encoded_tdesc = 0x80000000 | (VT_EMPTY << 16) | tdesc->vt;
	*width = 0;
	*alignment = 1;
	break;

    case VT_PTR:
    case VT_SAFEARRAY:
	/* FIXME: Make with the error checking. */
	FIXME("PTR or SAFEARRAY vartype, may not work correctly.\n");

	ctl2_encode_typedesc(This, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size);

	for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
	    typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
	    if (((typedata[0] & 0xffff) == tdesc->vt) && (typedata[1] == target_type)) break;
	}

	if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
	    int mix_field;
	    
	    if (target_type & 0x80000000) {
		mix_field = (target_type >> 16) & VT_TYPEMASK;
	    } else {
		typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
		switch((typedata[0]>>16) & ~VT_ARRAY)
		{
		    case VT_UI1:
		    case VT_I1:
		    case VT_UI2:
		    case VT_I2:
		    case VT_I4:
		    case VT_UI4:
			mix_field = typedata[0]>>16;
			break;
		    default:
			mix_field = ((typedata[0] >> 16) == 0x7fff) ? 0x7fff : 0x7ffe;
			break;
		}
	    }

	    if (tdesc->vt == VT_PTR)
		mix_field |= VT_BYREF;
	    else if (tdesc->vt == VT_SAFEARRAY)
		mix_field |= VT_ARRAY;

	    typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
	    typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];

	    typedata[0] = (mix_field << 16) | tdesc->vt;
	    typedata[1] = target_type;
	}

	*encoded_tdesc = typeoffset;

	*width = 4;
	*alignment = 4;
	*decoded_size = sizeof(TYPEDESC) + child_size;
	break;

    case VT_CARRAY:
      {
	/* FIXME: Make with the error checking. */
        int num_dims = tdesc->u.lpadesc->cDims, elements = 1, dim;

	ctl2_encode_typedesc(This, &tdesc->u.lpadesc->tdescElem, &target_type, width, alignment, NULL);
	arrayoffset = ctl2_alloc_segment(This, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(int), 0);
	arraydata = (void *)&This->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];

	arraydata[0] = target_type;
	arraydata[1] = num_dims;
        arraydata[1] |= ((num_dims * 2 * sizeof(int)) << 16);
        arraydata += 2;

        for(dim = 0; dim < num_dims; dim++) {
            arraydata[0] = tdesc->u.lpadesc->rgbounds[dim].cElements;
            arraydata[1] = tdesc->u.lpadesc->rgbounds[dim].lLbound;
            elements *= tdesc->u.lpadesc->rgbounds[dim].cElements;
            arraydata += 2;
        }
	typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
	typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];

	typedata[0] = (0x7ffe << 16) | VT_CARRAY;
	typedata[1] = arrayoffset;

	*encoded_tdesc = typeoffset;
	*width = *width * elements;
	*decoded_size = sizeof(ARRAYDESC) + (num_dims - 1) * sizeof(SAFEARRAYBOUND);

	break;
      }
    case VT_USERDEFINED:
      {
	const MSFT_TypeInfoBase *basetype;
	INT basevt = 0x7fff;

	TRACE("USERDEFINED.\n");
	if (tdesc->u.hreftype % sizeof(*basetype) == 0 && tdesc->u.hreftype < This->typelib_segdir[MSFT_SEG_TYPEINFO].length)
	{
	    basetype = (MSFT_TypeInfoBase*)&(This->typelib_segment_data[MSFT_SEG_TYPEINFO][tdesc->u.hreftype]);
	    switch(basetype->typekind & 0xf)
	    {
		case TKIND_ENUM:
		    basevt = VT_I4;
		    break;
		default:
		    FIXME("USERDEFINED basetype %d not handled\n", basetype->typekind & 0xf);
		    break;
	    }
	}
	for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
	    typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
	    if ((typedata[0] == ((basevt << 16) | VT_USERDEFINED)) && (typedata[1] == tdesc->u.hreftype)) break;
	}

	if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
	    typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
	    typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];

	    typedata[0] = (basevt << 16) | VT_USERDEFINED;
	    typedata[1] = tdesc->u.hreftype;
	}

	*encoded_tdesc = typeoffset;
	*width = 0;
	*alignment = 1;
	break;
      }

    default:
	FIXME("Unrecognized type %d.\n", tdesc->vt);
	*encoded_tdesc = default_tdesc;
	*width = 0;
	*alignment = 1;
	break;
    }

    return 0;
}

/****************************************************************************
 *	ctl2_decode_typedesc
 *
 *  Decodes a type description from an ICreateTypeLib2Impl.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: HRESULT error code.
 */
static HRESULT ctl2_decode_typedesc(
	ICreateTypeLib2Impl *This, /* [I] The type library from which to decode the TYPEDESC. */
	int encoded_tdesc,         /* [I] The encoded type description. */
	TYPEDESC *tdesc)           /* [O] The decoded type description. */
{
    int *typedata, i;
    HRESULT hres;

    if (encoded_tdesc & 0x80000000) {
        tdesc->vt = encoded_tdesc & VT_TYPEMASK;
        tdesc->u.lptdesc = NULL;
        return S_OK;
    }

    typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][encoded_tdesc];

    tdesc->vt = typedata[0] & 0xFFFF;

    switch(tdesc->vt) {
    case VT_PTR:
    case VT_SAFEARRAY:
        tdesc->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC));
        if (!tdesc->u.lptdesc)
            return E_OUTOFMEMORY;

        hres = ctl2_decode_typedesc(This, typedata[1], tdesc->u.lptdesc);
        if (FAILED(hres)) {
            heap_free(tdesc->u.lptdesc);
            return hres;
        }

        return S_OK;

    case VT_CARRAY: {
        int arrayoffset, *arraydata, num_dims;

        arrayoffset = typedata[1];
        arraydata = (void *)&This->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
        num_dims = arraydata[1] & 0xFFFF;

        tdesc->u.lpadesc = heap_alloc_zero(sizeof(ARRAYDESC) + sizeof(SAFEARRAYBOUND) * (num_dims - 1));
        if (!tdesc->u.lpadesc)
            return E_OUTOFMEMORY;

        hres = ctl2_decode_typedesc(This, arraydata[0], &tdesc->u.lpadesc->tdescElem);
        if (FAILED(hres)) {
            heap_free(tdesc->u.lpadesc);
            return E_OUTOFMEMORY;
        }

        for (i = 0; i < num_dims; ++i) {
            tdesc->u.lpadesc->rgbounds[i].cElements = arraydata[2 + i * 2];
            tdesc->u.lpadesc->rgbounds[i].lLbound = arraydata[3 + i * 2];
        }

        return S_OK;
    }
    case VT_USERDEFINED:
        tdesc->u.hreftype = typedata[1];
        return S_OK;
    default:
        FIXME("unable to decode typedesc (%08x): unknown VT: %d\n", encoded_tdesc, tdesc->vt);
        return E_NOTIMPL;
    }
}

/****************************************************************************
 *	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(
	ICreateTypeLib2Impl *This, /* [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 *)&This->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
	offset = ref->onext;
    }

    return offset;
}

/****************************************************************************
 *	ctl2_find_typeinfo_from_offset
 *
 *  Finds an ITypeInfo given an offset into the TYPEINFO segment.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: TYPE_E_ELEMENTNOTFOUND.
 */
static HRESULT ctl2_find_typeinfo_from_offset(
	ICreateTypeLib2Impl *This, /* [I] The typelib to find the typeinfo in. */
	int offset,                /* [I] The offset of the desired typeinfo. */
	ITypeInfo **ppTinfo)       /* [I] The typeinfo found. */
{
    void *typeinfodata;
    ICreateTypeInfo2Impl *typeinfo;

    typeinfodata = &This->typelib_segment_data[MSFT_SEG_TYPEINFO][offset];

    for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
	if (typeinfo->typeinfo == typeinfodata) {
	    *ppTinfo = (ITypeInfo *)&typeinfo->ITypeInfo2_iface;
	    ITypeInfo2_AddRef(*ppTinfo);
	    return S_OK;
	}
    }

    ERR("Failed to find typeinfo, invariant varied.\n");

    return TYPE_E_ELEMENTNOTFOUND;
}

/****************************************************************************
 *      funcrecord_reallochdr
 *
 *  Ensure FuncRecord data block contains header of required size
 *
 *  PARAMS
 *
 *   typedata [IO] - reference to pointer to data block
 *   need     [I]  - required size of block in bytes
 *
 * RETURNS
 *
 *  Number of additionally allocated bytes
 */
static INT funcrecord_reallochdr(INT **typedata, int need)
{
    int tail = (*typedata)[5]*((*typedata)[4]&0x1000?16:12);
    int hdr = (*typedata)[0] - tail;
    int i;

    if (hdr >= need)
        return 0;

    *typedata = heap_realloc(*typedata, need + tail);
    if (!*typedata)
        return -1;

    if (tail)
        memmove((char*)*typedata + need, (const char*)*typedata + hdr, tail);
    (*typedata)[0] = need + tail;

    /* fill in default values */
    for(i = (hdr+3)/4; (i+1)*4 <= need; i++)
    {
        switch(i)
        {
            case 2:
                (*typedata)[i] = 0;
                break;
            case 7:
                (*typedata)[i] = -1;
                break;
            case 8:
                (*typedata)[i] = -1;
                break;
            case 9:
                (*typedata)[i] = -1;
                break;
            case 10:
                (*typedata)[i] = -1;
                break;
            case 11:
                (*typedata)[i] = 0;
                break;
            case 12:
                (*typedata)[i] = -1;
                break;
        }
    }

    return need - hdr;
}

/*================== ICreateTypeInfo2 Implementation ===================================*/

/******************************************************************************
 * ICreateTypeInfo2_QueryInterface {OLEAUT32}
 *
 */
static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface(
	ICreateTypeInfo2 * iface,
	REFIID riid,
	VOID **ppvObject)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));

    *ppvObject=NULL;
    if(IsEqualIID(riid, &IID_IUnknown) ||
       IsEqualIID(riid,&IID_ICreateTypeInfo)||
       IsEqualIID(riid,&IID_ICreateTypeInfo2))
    {
        *ppvObject = This;
    } else if (IsEqualIID(riid, &IID_ITypeInfo) ||
	       IsEqualIID(riid, &IID_ITypeInfo2)) {
        *ppvObject = &This->ITypeInfo2_iface;
    }

    if(*ppvObject)
    {
        ICreateTypeInfo2_AddRef(iface);
        TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
        return S_OK;
    }
    TRACE("-- Interface: E_NOINTERFACE\n");
    return E_NOINTERFACE;
}

/******************************************************************************
 * ICreateTypeInfo2_AddRef {OLEAUT32}
 */
static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p)->ref was %u\n",This, ref - 1);

    if(ref==1 && This->typelib)
        ICreateTypeLib2_AddRef((ICreateTypeLib2 *)This->typelib);

    return ref;
}

/******************************************************************************
 * ICreateTypeInfo2_Release {OLEAUT32}
 */
static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%u)\n",This, ref);

    if (!ref) {
	if (This->typelib) {
	    ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)This->typelib);
            /* Keep This->typelib reference to make stored ICreateTypeInfo structure valid */
            /* This->typelib = NULL; */
	}

	/* ICreateTypeLib2 frees all ICreateTypeInfos when it releases. */
	/* HeapFree(GetProcessHeap(),0,This); */
	return 0;
    }

    return ref;
}


/******************************************************************************
 * ICreateTypeInfo2_SetGuid {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetGuid(ICreateTypeInfo2 *iface, REFGUID guid)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    MSFT_GuidEntry guidentry;
    int offset;

    TRACE("(%p,%s)\n", iface, debugstr_guid(guid));

    guidentry.guid = *guid;
    guidentry.hreftype = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
    guidentry.next_hash = -1;

    offset = ctl2_alloc_guid(This->typelib, &guidentry);
    
    if (offset == -1) return E_OUTOFMEMORY;

    This->typeinfo->posguid = offset;

    if (IsEqualIID(guid, &IID_IDispatch)) {
	This->typelib->typelib_header.dispatchpos = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
    }

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetTypeFlags {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, UINT uTypeFlags)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    TRACE("(%p,0x%x)\n", iface, uTypeFlags);

    if(uTypeFlags & TYPEFLAG_FDUAL) {
        This->typeinfo->typekind |= 0x10;
        This->typeinfo->typekind &= ~0x0f;
        This->typeinfo->typekind |= TKIND_DISPATCH;

        if(!This->dual) {
            This->dual = heap_alloc(sizeof(ICreateTypeInfo2Impl));
            if(!This->dual)
                return E_OUTOFMEMORY;

            memcpy(This->dual, This, sizeof(ICreateTypeInfo2Impl));
            This->dual->ref = 0;
            This->dual->typekind = This->typekind==TKIND_DISPATCH ?
                TKIND_INTERFACE : TKIND_DISPATCH;
            This->dual->dual = This;
        }

        /* Make sure dispatch is in typeinfos queue */
        if(This->typekind != TKIND_DISPATCH) {
            if(This->typelib->last_typeinfo == This)
                This->typelib->last_typeinfo = This->dual;

            if(This->typelib->typeinfos == This)
                This->typelib->typeinfos = This->dual;
            else {
                ICreateTypeInfo2Impl *iter;

                for(iter=This->typelib->typeinfos; iter->next_typeinfo!=This; iter=iter->next_typeinfo);
                iter->next_typeinfo = This->dual;
            }
        } else
            iface = &This->dual->ICreateTypeInfo2_iface;
    }

    if (uTypeFlags & (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL)) {
        static const WCHAR stdole2tlb[] = { 's','t','d','o','l','e','2','.','t','l','b',0 };
        ITypeLib *stdole;
        ITypeInfo *dispatch;
        HREFTYPE hreftype;
        HRESULT hres;

        hres = LoadTypeLib(stdole2tlb, &stdole);
        if(FAILED(hres))
            return hres;

        hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &dispatch);
        ITypeLib_Release(stdole);
        if(FAILED(hres))
            return hres;

        hres = ICreateTypeInfo2_AddRefTypeInfo(iface, dispatch, &hreftype);
        ITypeInfo_Release(dispatch);
        if(FAILED(hres))
            return hres;
    }

    This->typeinfo->flags = uTypeFlags;
    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetDocString {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetDocString(
        ICreateTypeInfo2* iface,
        LPOLESTR pStrDoc)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    int offset;

    TRACE("(%p,%s)\n", iface, debugstr_w(pStrDoc));
    if (!pStrDoc)
        return E_INVALIDARG;

    offset = ctl2_alloc_string(This->typelib, pStrDoc);
    if (offset == -1) return E_OUTOFMEMORY;
    This->typeinfo->docstringoffs = offset;
    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetHelpContext {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext(
        ICreateTypeInfo2* iface,
        DWORD dwHelpContext)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    TRACE("(%p,%d)\n", iface, dwHelpContext);

    This->typeinfo->helpcontext = dwHelpContext;

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetVersion {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetVersion(
        ICreateTypeInfo2* iface,
        WORD wMajorVerNum,
        WORD wMinorVerNum)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum);

    This->typeinfo->version = wMajorVerNum | (wMinorVerNum << 16);
    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_AddRefTypeInfo {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(
        ICreateTypeInfo2* iface,
        ITypeInfo* pTInfo,
        HREFTYPE* phRefType)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    ITypeLib *container;
    UINT index;
    HRESULT res;

    TRACE("(%p,%p,%p)\n", iface, pTInfo, phRefType);

    if(!pTInfo || !phRefType)
        return E_INVALIDARG;

    /*
     * Unfortunately, we can't rely on the passed-in TypeInfo even having the
     * same internal structure as one of ours. It could be from another
     * implementation of ITypeInfo. So we need to do the following...
     */
    res = ITypeInfo_GetContainingTypeLib(pTInfo, &container, &index);
    if (FAILED(res)) {
	TRACE("failed to find containing typelib.\n");
	return res;
    }

    if (container == (ITypeLib *)&This->typelib->lpVtblTypeLib2) {
        /* Process locally defined TypeInfo */
	*phRefType = This->typelib->typelib_typeinfo_offsets[index];
    } else {
        BSTR name;
        TLIBATTR *tlibattr;
        TYPEATTR *typeattr;
        TYPEKIND typekind;
        MSFT_GuidEntry guid, *check_guid;
        MSFT_ImpInfo impinfo;
        int guid_offset, import_offset;
        HRESULT hres;

        /* Allocate container GUID */
        hres = ITypeLib_GetLibAttr(container, &tlibattr);
        if(FAILED(hres)) {
            ITypeLib_Release(container);
            return hres;
        }

        guid.guid = tlibattr->guid;
        guid.hreftype = This->typelib->typelib_segdir[MSFT_SEG_IMPORTFILES].length+2;
        guid.next_hash = -1;

        guid_offset = ctl2_alloc_guid(This->typelib, &guid);
        if(guid_offset == -1) {
            ITypeLib_ReleaseTLibAttr(container, tlibattr);
            ITypeLib_Release(container);
            return E_OUTOFMEMORY;
        }

        check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset];
        if(check_guid->hreftype == guid.hreftype)
            This->typelib->typelib_guids++;

        /* Get import file name */
        hres = QueryPathOfRegTypeLib(&guid.guid, tlibattr->wMajorVerNum,
                tlibattr->wMinorVerNum, tlibattr->lcid, &name);
        if(FAILED(hres)) {
            ITypeLib_ReleaseTLibAttr(container, tlibattr);
            ITypeLib_Release(container);
            return hres;
        }

        /* Import file */
        import_offset = ctl2_alloc_importfile(This->typelib, guid_offset, tlibattr->lcid,
                tlibattr->wMajorVerNum, tlibattr->wMinorVerNum, strrchrW(name, '\\')+1);
        ITypeLib_ReleaseTLibAttr(container, tlibattr);
        SysFreeString(name);

        if(import_offset == -1) {
            ITypeLib_Release(container);
            return E_OUTOFMEMORY;
        }

        /* Allocate referenced guid */
        hres = ITypeInfo_GetTypeAttr(pTInfo, &typeattr);
        if(FAILED(hres)) {
            ITypeLib_Release(container);
            return hres;
        }

        guid.guid = typeattr->guid;
        guid.hreftype = This->typelib->typeinfo_guids*12+1;
        guid.next_hash = -1;
        typekind = typeattr->typekind;
        ITypeInfo_ReleaseTypeAttr(pTInfo, typeattr);

        guid_offset = ctl2_alloc_guid(This->typelib, &guid);
        if(guid_offset == -1) {
            ITypeLib_Release(container);
            return E_OUTOFMEMORY;
        }

        check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset];
        if(check_guid->hreftype == guid.hreftype)
            This->typelib->typeinfo_guids++;

        /* Allocate importinfo */
        impinfo.flags = (typekind<<24) | MSFT_IMPINFO_OFFSET_IS_GUID;
        impinfo.oImpFile = import_offset;
        impinfo.oGuid = guid_offset;
        *phRefType = ctl2_alloc_importinfo(This->typelib, &impinfo)+1;

        if(IsEqualGUID(&guid.guid, &IID_IDispatch))
            This->typelib->typelib_header.dispatchpos = *phRefType;
    }

    ITypeLib_Release(container);
    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_AddFuncDesc {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
        ICreateTypeInfo2* iface,
        UINT index,
        FUNCDESC* pFuncDesc)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    CyclicList *iter, *insert;
    int *typedata;
    int i, num_defaults = 0, num_retval = 0;
    int decoded_size;
    HRESULT hres;

    TRACE("(%p,%d,%p)\n", iface, index, pFuncDesc);

    if(!pFuncDesc || pFuncDesc->oVft&3)
        return E_INVALIDARG;

    TRACE("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid,
            pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind,
            pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams,
            pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes,
            pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags);

    if(pFuncDesc->cParamsOpt || pFuncDesc->cScodes)
        FIXME("Unimplemented parameter - created typelib will be incorrect\n");

    switch(This->typekind) {
    case TKIND_MODULE:
        if(pFuncDesc->funckind != FUNC_STATIC)
            return TYPE_E_BADMODULEKIND;
        break;
    case TKIND_DISPATCH:
        if(pFuncDesc->funckind != FUNC_DISPATCH)
            return TYPE_E_BADMODULEKIND;
        break;
    default:
        if(pFuncDesc->funckind != FUNC_PUREVIRTUAL)
            return TYPE_E_BADMODULEKIND;
    }

    if(cti2_get_func_count(This->typeinfo) < index)
        return TYPE_E_ELEMENTNOTFOUND;

    if((pFuncDesc->invkind&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) &&
        !pFuncDesc->cParams)
        return TYPE_E_INCONSISTENTPROPFUNCS;

    /* get number of arguments with default values specified */
    for (i = 0; i < pFuncDesc->cParams; i++) {
        if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
            num_defaults++;
        if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL)
            num_retval++;
    }

    if (!This->typedata) {
        This->typedata = alloc_cyclic_list_item(CyclicListSentinel);
        if(!This->typedata)
            return E_OUTOFMEMORY;

        This->typedata->next = This->typedata;

        if(This->dual)
            This->dual->typedata = This->typedata;
    }

    /* allocate type data space for us */
    insert = alloc_cyclic_list_item(CyclicListFunc);
    if(!insert)
        return E_OUTOFMEMORY;
    insert->u.data = heap_alloc(FIELD_OFFSET(MSFT_FuncRecord, HelpContext) +
                            sizeof(int[(num_defaults?4:3)])*pFuncDesc->cParams);
    if(!insert->u.data) {
        heap_free(insert);
        return E_OUTOFMEMORY;
    }

    /* fill out the basic type information */
    typedata = insert->u.data;
    typedata[0] = FIELD_OFFSET(MSFT_FuncRecord, HelpContext) + pFuncDesc->cParams*(num_defaults?16:12);
    ctl2_encode_typedesc(This->typelib, &pFuncDesc->elemdescFunc.tdesc, &typedata[1], NULL, NULL, &decoded_size);
    typedata[2] = pFuncDesc->wFuncFlags;
    typedata[3] = ((sizeof(FUNCDESC) + decoded_size) << 16) | (unsigned short)(pFuncDesc->oVft?pFuncDesc->oVft+1:0);
    typedata[4] = (pFuncDesc->callconv << 8) | (pFuncDesc->invkind << 3) | pFuncDesc->funckind;
    if(num_defaults) typedata[4] |= 0x1000;
    if (num_retval) typedata[4] |= 0x4000;
    typedata[5] = pFuncDesc->cParams;

    /* 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] += (sizeof(ELEMDESC) * pFuncDesc->cParams) << 16;
    typedata[3] += (sizeof(PARAMDESCEX) * num_defaults) << 16;

    /* add default values */
    if(num_defaults) {
        for (i = 0; i < pFuncDesc->cParams; i++)
            if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) {
                hres = ctl2_encode_variant(This->typelib, typedata+6+i,
                        &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue,
                        pFuncDesc->lprgelemdescParam[i].tdesc.vt);

                if(FAILED(hres)) {
                    heap_free(insert->u.data);
                    heap_free(insert);
                    return hres;
                }
            } else
                typedata[6+i] = 0xffffffff;

        num_defaults = pFuncDesc->cParams;
    }

    /* add arguments */
    for (i = 0; i < pFuncDesc->cParams; i++) {
	ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc,
                &typedata[6+num_defaults+(i*3)], NULL, NULL, &decoded_size);
	typedata[7+num_defaults+(i*3)] = -1;
	typedata[8+num_defaults+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
	typedata[3] += decoded_size << 16;
    }

    /* update the index data */
    insert->indice = pFuncDesc->memid;
    insert->name = -1;

    /* insert type data to list */
    if(index == cti2_get_func_count(This->typeinfo)) {
        insert->next = This->typedata->next;
        This->typedata->next = insert;
        This->typedata = insert;

        if(This->dual)
            This->dual->typedata = This->typedata;
    } else {
        iter = This->typedata->next;
        for(i=0; i<index; i++)
            iter = iter->next;

        insert->next = iter->next;
        iter->next = insert;
    }

    /* update type data size */
    This->typedata->next->u.val += FIELD_OFFSET(MSFT_FuncRecord, HelpContext) + pFuncDesc->cParams*(num_defaults?16:12);

    /* Increment the number of function elements */
    This->typeinfo->cElement += 1;

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_AddImplType {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(
        ICreateTypeInfo2* iface,
        UINT index,
        HREFTYPE hRefType)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    TRACE("(%p,%d,%d)\n", iface, index, hRefType);

    if (This->typekind == TKIND_COCLASS) {
	int offset;
	MSFT_RefRecord *ref;

	if (index == 0) {
	    if (This->typeinfo->datatype1 != -1) return TYPE_E_ELEMENTNOTFOUND;

	    offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0);
	    if (offset == -1) return E_OUTOFMEMORY;

	    This->typeinfo->datatype1 = offset;
	} else {
	    int lastoffset;

	    lastoffset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index - 1);
	    if (lastoffset == -1) return TYPE_E_ELEMENTNOTFOUND;

	    ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][lastoffset];
	    if (ref->onext != -1) return TYPE_E_ELEMENTNOTFOUND;

	    offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0);
	    if (offset == -1) return E_OUTOFMEMORY;

	    ref->onext = offset;
	}

	ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];

	ref->reftype = hRefType;
	ref->flags = 0;
	ref->oCustData = -1;
	ref->onext = -1;
        This->typeinfo->cImplTypes++;
    } else if (This->typekind == TKIND_INTERFACE) {
        if (This->typeinfo->cImplTypes && index==1)
            return TYPE_E_BADMODULEKIND;

        if( index != 0)  return TYPE_E_ELEMENTNOTFOUND;

        This->typeinfo->datatype1 = hRefType;
        This->typeinfo->cImplTypes = 1;
    } else if (This->typekind == TKIND_DISPATCH) {
        if(index != 0) return TYPE_E_ELEMENTNOTFOUND;

        /* FIXME: Check if referenced typeinfo is IDispatch */
        This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE;
        This->typeinfo->cImplTypes = 1;
    } else {
	FIXME("AddImplType unsupported on typekind %d\n", This->typekind);
	return E_OUTOFMEMORY;
    }

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetImplTypeFlags {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags(
        ICreateTypeInfo2* iface,
        UINT index,
        INT implTypeFlags)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);
    int offset;
    MSFT_RefRecord *ref;

    TRACE("(%p,%d,0x%x)\n", iface, index, implTypeFlags);

    if (This->typekind != TKIND_COCLASS) {
	return TYPE_E_BADMODULEKIND;
    }

    offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
    if (offset == -1) return TYPE_E_ELEMENTNOTFOUND;

    ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
    ref->flags = implTypeFlags;

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetAlignment {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment(
        ICreateTypeInfo2* iface,
        WORD cbAlignment)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    TRACE("(%p,%d)\n", iface, cbAlignment);

    if (!cbAlignment) return E_INVALIDARG;
    if (cbAlignment > 16) return E_INVALIDARG;

    This->typeinfo->typekind &= ~0xffc0;
    This->typeinfo->typekind |= cbAlignment << 6;

    /* FIXME: There's probably some way to simplify this. */
    switch (This->typekind) {
    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;
    }

    This->typeinfo->typekind |= cbAlignment << 11;

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetSchema {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetSchema(
        ICreateTypeInfo2* iface,
        LPOLESTR pStrSchema)
{
    FIXME("(%p,%s), stub!\n", iface, debugstr_w(pStrSchema));
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_AddVarDesc {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(
        ICreateTypeInfo2* iface,
        UINT index,
        VARDESC* pVarDesc)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    HRESULT status = S_OK;
    CyclicList *insert;
    INT *typedata;
    int var_datawidth;
    int var_alignment;
    int var_type_size;
    int alignment;

    TRACE("(%p,%d,%p)\n", iface, index, pVarDesc);
    TRACE("%d, %p, %d, {{%x, %d}, {%p, %x}}, 0x%x, %d\n", pVarDesc->memid, pVarDesc->lpstrSchema, pVarDesc->u.oInst,
	  pVarDesc->elemdescVar.tdesc.u.hreftype, pVarDesc->elemdescVar.tdesc.vt,
	  pVarDesc->elemdescVar.u.paramdesc.pparamdescex, pVarDesc->elemdescVar.u.paramdesc.wParamFlags,
	  pVarDesc->wVarFlags, pVarDesc->varkind);

    if (cti2_get_var_count(This->typeinfo) != index)
	return TYPE_E_ELEMENTNOTFOUND;

    if (!This->typedata) {
        This->typedata = alloc_cyclic_list_item(CyclicListSentinel);
        if(!This->typedata)
            return E_OUTOFMEMORY;

        This->typedata->next = This->typedata;

        if(This->dual)
            This->dual->typedata = This->typedata;
    }

    insert = alloc_cyclic_list_item(CyclicListVar);
    if(!insert)
        return E_OUTOFMEMORY;

    /* allocate whole structure, it's fixed size always */
    insert->u.data = heap_alloc(sizeof(MSFT_VarRecord));
    if(!insert->u.data) {
        heap_free(insert);
        return E_OUTOFMEMORY;
    }

    insert->next = This->typedata->next;
    This->typedata->next = insert;
    This->typedata = insert;

    if(This->dual)
        This->dual->typedata = This->typedata;

    This->typedata->next->u.val += FIELD_OFFSET(MSFT_VarRecord, HelpContext);
    typedata = This->typedata->u.data;

    /* fill out the basic type information */

    /* no optional fields initially */
    typedata[0] = FIELD_OFFSET(MSFT_VarRecord, HelpContext) | (index << 16);
    typedata[2] = pVarDesc->wVarFlags;
    typedata[3] = (sizeof(VARDESC) << 16) | pVarDesc->varkind;

    /* update the index data */
    insert->indice = 0x40000000 + index;
    insert->name = -1;

    /* figure out type widths and whatnot */
    ctl2_encode_typedesc(This->typelib, &pVarDesc->elemdescVar.tdesc,
			 &typedata[1], &var_datawidth, &var_alignment,
			 &var_type_size);

    if (pVarDesc->varkind != VAR_CONST)
    {
	/* pad out starting position to data width */
	This->datawidth += var_alignment - 1;
	This->datawidth &= ~(var_alignment - 1);
	typedata[4] = This->datawidth;

	/* add the new variable to the total data width */
	This->datawidth += var_datawidth;
	if(This->dual)
	    This->dual->datawidth = This->datawidth;

	/* add type description size to total required allocation */
	typedata[3] += var_type_size << 16;

	/* fix type alignment */
	alignment = (This->typeinfo->typekind >> 11) & 0x1f;
	if (alignment < var_alignment) {
	    alignment = var_alignment;
	    This->typeinfo->typekind &= ~0xf800;
	    This->typeinfo->typekind |= alignment << 11;
	}

	/* ??? */
	if (!This->typeinfo->res2) This->typeinfo->res2 = 0x1a;
	if ((index == 0) || (index == 1) || (index == 2) || (index == 4) || (index == 9)) {
	    This->typeinfo->res2 <<= 1;
	}

	/* ??? */
	if (This->typeinfo->res3 == -1) This->typeinfo->res3 = 0;
	This->typeinfo->res3 += 0x2c;

	/* pad data width to alignment */
	This->typeinfo->size = (This->datawidth + (alignment - 1)) & ~(alignment - 1);
    } else {
	VARIANT *value = pVarDesc->DUMMYUNIONNAME.lpvarValue;
	status = ctl2_encode_variant(This->typelib, typedata+4, value, V_VT(value));
        /* ??? native sets size 0x34 */
	typedata[3] += 0x10 << 16;
    }

    /* increment the number of variable elements */
    This->typeinfo->cElement += 0x10000;

    return status;
}

/******************************************************************************
 * ICreateTypeInfo2_SetFuncAndParamNames {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames(
        ICreateTypeInfo2* iface,
        UINT index,
        LPOLESTR* names,
        UINT cNames)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);
    CyclicList *iter, *iter2;
    int offset, len, i;
    unsigned char *namedata;

    TRACE("(%p %d %p %d)\n", This, index, names, cNames);

    if(!names)
        return E_INVALIDARG;

    if(index >= cti2_get_func_count(This->typeinfo) || cNames == 0)
        return TYPE_E_ELEMENTNOTFOUND;

    for(iter=This->typedata->next->next, i=0; /* empty */; iter=iter->next)
        if (iter->type == CyclicListFunc)
            if (i++ >= index)
                break;

    /* cNames == cParams for put or putref accessor, cParams+1 otherwise */
    if(cNames != iter->u.data[5] + (ctl2_get_invokekind(iter) & (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF) ? 0 : 1))
        return TYPE_E_ELEMENTNOTFOUND;

    TRACE("function name %s\n", debugstr_w(names[0]));
    len = ctl2_encode_name(This->typelib, names[0], (char**)&namedata);
    for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {

        int cmp = memcmp(namedata, This->typelib->typelib_segment_data[MSFT_SEG_NAME]+iter2->name+8, len);
        if (iter2->name != -1 && cmp == 0) {
            if (iter2->type == CyclicListFunc) {
                INVOKEKIND inv1 = ctl2_get_invokekind(iter);
                INVOKEKIND inv2 = ctl2_get_invokekind(iter2);

                /* it's allowed to have PUT, PUTREF and GET methods with the same name */
                if ((inv1 != inv2) &&
                    (inv1 & (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF|INVOKE_PROPERTYGET)) &&
                    (inv2 & (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF|INVOKE_PROPERTYGET)))
                    continue;
            }

            return TYPE_E_AMBIGUOUSNAME;
        }
    }

    offset = ctl2_alloc_name(This->typelib, names[0]);
    if(offset == -1)
        return E_OUTOFMEMORY;

    iter->name = offset;

    namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
    if (*((INT*)namedata) == -1)
	    *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];

    len = ctl2_get_record_size(iter)/4 - iter->u.data[5]*3;

    for (i = 1; i < cNames; i++) {
	offset = ctl2_alloc_name(This->typelib, names[i]);
	iter->u.data[len + ((i-1)*3) + 1] = offset;
    }

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetVarName {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName(
        ICreateTypeInfo2* iface,
        UINT index,
        LPOLESTR szName)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);
    CyclicList *iter;
    int offset, i;
    unsigned char *namedata;

    TRACE("(%p,%d,%s)\n", This, index, debugstr_w(szName));

    if (cti2_get_var_count(This->typeinfo) <= index)
	return TYPE_E_ELEMENTNOTFOUND;

    offset = ctl2_alloc_name(This->typelib, szName);
    if (offset == -1) return E_OUTOFMEMORY;

    namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
    if (*((INT *)namedata) == -1) {
	*((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
	namedata[9] |= 0x10;
    }
    if (This->typekind == TKIND_ENUM) {
	namedata[9] |= 0x20;
    }

    for(iter = This->typedata->next->next, i = 0; /* empty */; iter = iter->next)
        if (iter->type == CyclicListVar)
            if (i++ >= index)
                break;

    iter->name = offset;
    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetTypeDescAlias {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias(
        ICreateTypeInfo2* iface,
        TYPEDESC* pTDescAlias)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    int encoded_typedesc;
    int width;

    if (This->typekind != TKIND_ALIAS) {
	return TYPE_E_WRONGTYPEKIND;
    }

    FIXME("(%p,%p), hack!\n", iface, pTDescAlias);

    if (ctl2_encode_typedesc(This->typelib, pTDescAlias, &encoded_typedesc, &width, NULL, NULL) == -1) {
	return E_OUTOFMEMORY;
    }

    This->typeinfo->size = width;
    This->typeinfo->datatype1 = encoded_typedesc;

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_DefineFuncAsDllEntry {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry(
        ICreateTypeInfo2* iface,
        UINT index,
        LPOLESTR szDllName,
        LPOLESTR szProcName)
{
    FIXME("(%p,%d,%s,%s), stub!\n", iface, index, debugstr_w(szDllName), debugstr_w(szProcName));
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_SetFuncDocString {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncDocString(
        ICreateTypeInfo2* iface,
        UINT index,
        LPOLESTR szDocString)
{
    FIXME("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szDocString));
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_SetVarDocString {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarDocString(
        ICreateTypeInfo2* iface,
        UINT index,
        LPOLESTR docstring)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);
    CyclicList *iter;

    TRACE("(%p,%d,%s)\n", This, index, debugstr_w(docstring));

    if (!docstring) return E_INVALIDARG;

    if (cti2_get_var_count(This->typeinfo) <= index)
	return TYPE_E_ELEMENTNOTFOUND;

    for (iter = This->typedata->next->next; iter != This->typedata->next; iter = iter->next)
       if (iter->type == CyclicListVar)
       {
           if (index-- == 0)
           {
               int offset = ctl2_alloc_string(This->typelib, docstring);

               if (offset == -1) return E_OUTOFMEMORY;
               ctl2_update_var_size(This, iter, FIELD_OFFSET(MSFT_VarRecord, res9));
               iter->u.data[6] = offset;
               return S_OK;
           }
       }

    return TYPE_E_ELEMENTNOTFOUND;
}

/******************************************************************************
 * ICreateTypeInfo2_SetFuncHelpContext {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext(
        ICreateTypeInfo2* iface,
        UINT index,
        DWORD dwHelpContext)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);
    CyclicList *func;

    TRACE("(%p,%d,%d)\n", iface, index, dwHelpContext);

    if(cti2_get_func_count(This->typeinfo) < index)
        return TYPE_E_ELEMENTNOTFOUND;

    if(cti2_get_func_count(This->typeinfo) == index && This->typedata->type == CyclicListFunc)
        func = This->typedata;
    else
        for(func=This->typedata->next->next; func!=This->typedata; func=func->next)
            if (func->type == CyclicListFunc)
                if(index-- == 0)
                    break;

    This->typedata->next->u.val += funcrecord_reallochdr(&func->u.data, 7*sizeof(int));
    if(!func->u.data)
        return E_OUTOFMEMORY;

    func->u.data[6] = dwHelpContext;
    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetVarHelpContext {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpContext(
        ICreateTypeInfo2* iface,
        UINT index,
        DWORD context)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);
    CyclicList *iter;

    TRACE("(%p,%d,%d)\n", This, index, context);

    if (cti2_get_var_count(This->typeinfo) <= index)
	return TYPE_E_ELEMENTNOTFOUND;

    for (iter = This->typedata->next->next; iter != This->typedata->next; iter = iter->next)
       if (iter->type == CyclicListVar)
       {
           if (index-- == 0)
           {
               ctl2_update_var_size(This, iter, FIELD_OFFSET(MSFT_VarRecord, HelpString));
               iter->u.data[5] = context;
               return S_OK;
           }
       }

    return TYPE_E_ELEMENTNOTFOUND;
}

/******************************************************************************
 * ICreateTypeInfo2_SetMops {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetMops(
        ICreateTypeInfo2* iface,
        UINT index,
        BSTR bstrMops)
{
    FIXME("(%p,%d,%p), stub!\n", iface, index, bstrMops);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_SetTypeIdldesc {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc(
        ICreateTypeInfo2* iface,
        IDLDESC* pIdlDesc)
{
    FIXME("(%p,%p), stub!\n", iface, pIdlDesc);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_LayOut {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
	ICreateTypeInfo2* iface)
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);
    CyclicList *iter, *iter2, *last = NULL, **typedata;
    HREFTYPE hreftype;
    HRESULT hres;
    unsigned user_vft = 0;
    int i;

    TRACE("(%p)\n", This);

    /* FIXME: LayOut should be run on all ImplTypes */
    if(This->typekind == TKIND_COCLASS || This->typekind == TKIND_ALIAS)
        return S_OK;

    /* Validate inheritance */
    This->typeinfo->datatype2 = 0;
    hreftype = This->typeinfo->datatype1;

    /* Process internally defined interfaces */
    for(i=0; i<This->typelib->typelib_header.nrtypeinfos; i++) {
        MSFT_TypeInfoBase *header;

        if(hreftype&1)
            break;

        header = (MSFT_TypeInfoBase*)&(This->typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][hreftype]);
        This->typeinfo->datatype2 += (header->cElement<<16) + 1;
        hreftype = header->datatype1;
    }
    if(i == This->typelib->typelib_header.nrtypeinfos)
        return TYPE_E_CIRCULARTYPE;

    /* Process externally defined interfaces */
    if(hreftype != -1) {
        ITypeInfo *cur, *next;
        TYPEATTR *typeattr;

        hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&next);
        if(FAILED(hres))
            return hres;

        hres = ITypeInfo_GetRefTypeInfo(next, hreftype, &cur);
        ITypeInfo_Release(next);
        if(FAILED(hres))
            return hres;


        while(1) {
            hres = ITypeInfo_GetTypeAttr(cur, &typeattr);
            if(FAILED(hres)) {
                ITypeInfo_Release(cur);
                return hres;
            }

            if(IsEqualGUID(&typeattr->guid, &IID_IDispatch))
                This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE;

            This->typeinfo->datatype2 += (typeattr->cFuncs<<16) + 1;
            ITypeInfo_ReleaseTypeAttr(cur, typeattr);

            hres = ITypeInfo_GetRefTypeOfImplType(cur, 0, &hreftype);
            if(hres == TYPE_E_ELEMENTNOTFOUND)
                break;
            if(FAILED(hres)) {
                ITypeInfo_Release(cur);
                return hres;
            }

            hres = ITypeInfo_GetRefTypeInfo(cur, hreftype, &next);
            if(FAILED(hres)) {
                ITypeInfo_Release(cur);
                return hres;
            }

            ITypeInfo_Release(cur);
            cur = next;
        }
        ITypeInfo_Release(cur);
    }

    /* Get cbSizeVft of inherited interface */
    /* Makes LayOut running recursively */
    if(This->typeinfo->datatype1 != -1) {
        ITypeInfo *cur, *inherited;
        TYPEATTR *typeattr;

        hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&cur);
        if(FAILED(hres))
            return hres;

        hres = ITypeInfo_GetRefTypeInfo(cur, This->typeinfo->datatype1, &inherited);
        ITypeInfo_Release(cur);
        if(FAILED(hres))
            return hres;

        hres = ITypeInfo_GetTypeAttr(inherited, &typeattr);
        if(FAILED(hres)) {
            ITypeInfo_Release(inherited);
            return hres;
        }

        This->typeinfo->cbSizeVft = typeattr->cbSizeVft * 4 / sizeof(void *);

        ITypeInfo_ReleaseTypeAttr(inherited, typeattr);
        ITypeInfo_Release(inherited);
    } else
        This->typeinfo->cbSizeVft = 0;

    if(!This->typedata)
        return S_OK;

    typedata = heap_alloc(sizeof(CyclicList*)*cti2_get_func_count(This->typeinfo));
    if(!typedata)
        return E_OUTOFMEMORY;

    /* Assign IDs and VTBL entries */
    for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next)
        if (iter->type == CyclicListFunc)
            last = iter;

    if(last && last->u.data[3]&1)
        user_vft = last->u.data[3]&0xffff;

    i = 0;
    for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) {
        /* Assign MEMBERID if MEMBERID_NIL was specified */
        if(iter->indice == MEMBERID_NIL) {
            iter->indice = 0x60000000 + i + (This->typeinfo->datatype2<<16);

            for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
                if(iter == iter2) continue;
                if(iter2->indice == iter->indice) {
                    iter->indice = 0x60000000 + This->typeinfo->cElement + (This->typeinfo->datatype2<<16);

                    for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
                        if(iter == iter2) continue;
                        if(iter2->indice == iter->indice) {
                            ++iter->indice;
                            iter2 = This->typedata->next;
                        }
                    }

                    break;
                }
            }
        }

        if (iter->type != CyclicListFunc)
            continue;

        typedata[i] = iter;

        iter->u.data[0] = ctl2_get_record_size(iter) | (i<<16);

        if((iter->u.data[3]&1) != (user_vft&1)) {
            heap_free(typedata);
            return TYPE_E_INVALIDID;
        }

        if(user_vft&1) {
            if(user_vft < (iter->u.data[3]&0xffff))
                user_vft = (iter->u.data[3]&0xffff);

            if((iter->u.data[3]&0xffff) < This->typeinfo->cbSizeVft) {
                heap_free(typedata);
                return TYPE_E_INVALIDID;
            }
        } else if(This->typekind != TKIND_MODULE) {
            iter->u.data[3] = (iter->u.data[3]&0xffff0000) | This->typeinfo->cbSizeVft;
            This->typeinfo->cbSizeVft += 4;
        }

        /* Construct a list of elements with the same memberid */
        iter->u.data[4] = (iter->u.data[4]&0xffff) | (i<<16);
        for(iter2=This->typedata->next->next; iter2!=iter; iter2=iter2->next) {
            if(iter->indice == iter2->indice) {
                int v1, v2;

                v1 = iter->u.data[4] >> 16;
                v2 = iter2->u.data[4] >> 16;

                iter->u.data[4] = (iter->u.data[4]&0xffff) | (v2<<16);
                iter2->u.data[4] = (iter2->u.data[4]&0xffff) | (v1<<16);
                break;
            }
        }

        i++;
    }

    if(user_vft)
        This->typeinfo->cbSizeVft = user_vft+3;

    for(i=0; i< cti2_get_func_count(This->typeinfo); i++) {
        if(typedata[i]->u.data[4]>>16 > i) {
            INVOKEKIND inv = ctl2_get_invokekind(typedata[i]);

            i = typedata[i]->u.data[4] >> 16;

            while(i > typedata[i]->u.data[4]>>16) {
                INVOKEKIND invkind = ctl2_get_invokekind(typedata[i]);

                if(inv & invkind) {
                    heap_free(typedata);
                    return TYPE_E_DUPLICATEID;
                }

                i = typedata[i]->u.data[4] >> 16;
                inv |= invkind;
            }

            if(inv & INVOKE_FUNC) {
                heap_free(typedata);
                return TYPE_E_INCONSISTENTPROPFUNCS;
            }
        }
    }

    heap_free(typedata);
    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_DeleteFuncDesc {OLEAUT32}
 *
 *  Delete a function description from a type.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDesc(
        ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete a function. */
        UINT index)              /* [I] The index of the function to delete. */
{
    FIXME("(%p,%d), stub!\n", iface, index);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_DeleteFuncDescByMemId {OLEAUT32}
 *
 *  Delete a function description from a type.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDescByMemId(
        ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete a function. */
        MEMBERID memid,          /* [I] The member id of the function to delete. */
        INVOKEKIND invKind)      /* [I] The invocation type of the function to delete. (?) */
{
    FIXME("(%p,%d,%d), stub!\n", iface, memid, invKind);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_DeleteVarDesc {OLEAUT32}
 *
 *  Delete a variable description from a type.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY, E_INVALIDARG, TYPE_E_IOERROR,
 *  TYPE_E_INVDATAREAD, TYPE_E_UNSUPFORMAT or TYPE_E_INVALIDSTATE.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDesc(
        ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete the variable description. */
        UINT index)              /* [I] The index of the variable description to delete. */
{
    FIXME("(%p,%d), stub!\n", iface, index);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_DeleteVarDescByMemId {OLEAUT32}
 *
 *  Delete a variable description from a type.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY, E_INVALIDARG, TYPE_E_IOERROR,
 *  TYPE_E_INVDATAREAD, TYPE_E_UNSUPFORMAT or TYPE_E_INVALIDSTATE.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDescByMemId(
        ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete the variable description. */
        MEMBERID memid)          /* [I] The member id of the variable description to delete. */
{
    FIXME("(%p,%d), stub!\n", iface, memid);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_DeleteImplType {OLEAUT32}
 *
 *  Delete an interface implementation from a type. (?)
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteImplType(
        ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete. */
        UINT index)              /* [I] The index of the interface to delete. */
{
    FIXME("(%p,%d), stub!\n", iface, index);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_SetCustData {OLEAUT32}
 *
 *  Set the custom data for a type.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetCustData(
        ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
        REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
        VARIANT* pVarVal)        /* [I] The custom data. */
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    TRACE("(%p,%s,%p)!\n", iface, debugstr_guid(guid), pVarVal);

    if (!pVarVal)
	    return E_INVALIDARG;

    return ctl2_set_custdata(This->typelib, guid, pVarVal, &This->typeinfo->oCustData);
}

/******************************************************************************
 * ICreateTypeInfo2_SetFuncCustData {OLEAUT32}
 *
 *  Set the custom data for a function.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncCustData(
        ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
        UINT index,              /* [I] The index of the function for which to set the custom data. */
        REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
        VARIANT* pVarVal)        /* [I] The custom data. */
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);
    CyclicList *iter;

    TRACE("(%p,%d,%s,%p)\n", iface, index, debugstr_guid(guid), pVarVal);

    if(index >= cti2_get_func_count(This->typeinfo))
        return TYPE_E_ELEMENTNOTFOUND;

    for(iter=This->typedata->next->next; /* empty */; iter=iter->next)
        if (iter->type == CyclicListFunc)
            if (index-- == 0)
                break;

    This->typedata->next->u.val += funcrecord_reallochdr(&iter->u.data, 13*sizeof(int));
    if(!iter->u.data)
        return E_OUTOFMEMORY;

    iter->u.data[4] |= 0x80;
    return ctl2_set_custdata(This->typelib, guid, pVarVal, &iter->u.data[12]);
}

/******************************************************************************
 * ICreateTypeInfo2_SetParamCustData {OLEAUT32}
 *
 *  Set the custom data for a function parameter.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetParamCustData(
        ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
        UINT indexFunc,          /* [I] The index of the function on which the parameter resides. */
        UINT indexParam,         /* [I] The index of the parameter on which to set the custom data. */
        REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
        VARIANT* pVarVal)        /* [I] The custom data. */
{
    FIXME("(%p,%d,%d,%s,%p), stub!\n", iface, indexFunc, indexParam, debugstr_guid(guid), pVarVal);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_SetVarCustData {OLEAUT32}
 *
 *  Set the custom data for a variable.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarCustData(
        ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
        UINT index,              /* [I] The index of the variable on which to set the custom data. */
        REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
        VARIANT* pVarVal)        /* [I] The custom data. */
{
    FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_SetImplTypeCustData {OLEAUT32}
 *
 *  Set the custom data for an implemented interface.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeCustData(
        ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the custom data. */
        UINT index,              /* [I] The index of the implemented interface on which to set the custom data. */
        REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
        VARIANT* pVarVal)        /* [I] The custom data. */
{
    FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_SetHelpStringContext {OLEAUT32}
 *
 *  Set the help string context for the typeinfo.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpStringContext(
        ICreateTypeInfo2* iface,   /* [I] The typeinfo on which to set the help string context. */
        ULONG helpcontext) /* [I] The help string context. */
{
    ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface);

    TRACE("(%p, %d)\n", iface, helpcontext);

    This->typelib->typelib_header.helpcontext = helpcontext;

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetFuncHelpStringContext {OLEAUT32}
 *
 *  Set the help string context for a function.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpStringContext(
        ICreateTypeInfo2* iface,   /* [I] The typeinfo on which to set the help string context. */
        UINT index,                /* [I] The index for the function on which to set the help string context. */
        ULONG dwHelpStringContext) /* [I] The help string context. */
{
    FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpStringContext);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_SetVarHelpStringContext {OLEAUT32}
 *
 *  Set the help string context for a variable.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpStringContext(
        ICreateTypeInfo2* iface,   /* [I] The typeinfo on which to set the help string context. */
        UINT index,                /* [I] The index of the variable on which to set the help string context. */
        ULONG dwHelpStringContext) /* [I] The help string context */
{
    FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpStringContext);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_Invalidate {OLEAUT32}
 *
 *  Undocumented function. (!)
 */
static HRESULT WINAPI ICreateTypeInfo2_fnInvalidate(
        ICreateTypeInfo2* iface)
{
    FIXME("(%p), stub!\n", iface);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_SetName {OLEAUT32}
 *
 *  Set the name for a typeinfo.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of STG_E_INSUFFICIENTMEMORY, E_OUTOFMEMORY, E_INVALIDARG or TYPE_E_INVALIDSTATE.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetName(
        ICreateTypeInfo2* iface,
        LPOLESTR szName)
{
    FIXME("(%p,%s), stub!\n", iface, debugstr_w(szName));
    return E_OUTOFMEMORY;
}

/*================== ITypeInfo2 Implementation ===================================*/

/******************************************************************************
 * ITypeInfo2_QueryInterface {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnQueryInterface(ITypeInfo2 * iface, REFIID riid, LPVOID * ppv)
{
    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);

    return ICreateTypeInfo2_QueryInterface(&This->ICreateTypeInfo2_iface, riid, ppv);
}

/******************************************************************************
 * ITypeInfo2_AddRef {OLEAUT32}
 */
static ULONG WINAPI ITypeInfo2_fnAddRef(ITypeInfo2 * iface)
{
    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);

    return ICreateTypeInfo2_AddRef(&This->ICreateTypeInfo2_iface);
}

/******************************************************************************
 * ITypeInfo2_Release {OLEAUT32}
 */
static ULONG WINAPI ITypeInfo2_fnRelease(ITypeInfo2 * iface)
{
    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);

    return ICreateTypeInfo2_Release(&This->ICreateTypeInfo2_iface);
}

/******************************************************************************
 * ITypeInfo2_GetTypeAttr {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr(
        ITypeInfo2* iface,
        TYPEATTR** ppTypeAttr)
{
    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
    HRESULT hres;

    TRACE("(%p,%p)\n", iface, ppTypeAttr);

    if(!ppTypeAttr)
        return E_INVALIDARG;

    hres = ICreateTypeInfo_LayOut(&This->ICreateTypeInfo2_iface);
    if(FAILED(hres))
        return hres;

    *ppTypeAttr = heap_alloc_zero(sizeof(TYPEATTR));
    if(!*ppTypeAttr)
        return E_OUTOFMEMORY;

    if(This->typeinfo->posguid != -1) {
        MSFT_GuidEntry *guid;

        guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][This->typeinfo->posguid];
        (*ppTypeAttr)->guid = guid->guid;
    }

    (*ppTypeAttr)->lcid = This->typelib->typelib_header.lcid;
    (*ppTypeAttr)->cbSizeInstance = This->typeinfo->size;
    (*ppTypeAttr)->typekind = This->typekind;
    (*ppTypeAttr)->cFuncs = cti2_get_func_count(This->typeinfo);
    if(This->typeinfo->flags&TYPEFLAG_FDUAL && This->typekind==TKIND_DISPATCH)
        (*ppTypeAttr)->cFuncs += sizeof(IDispatchVtbl)/sizeof(void*);
    (*ppTypeAttr)->cVars = cti2_get_var_count(This->typeinfo);
    (*ppTypeAttr)->cImplTypes = This->typeinfo->cImplTypes;
    (*ppTypeAttr)->cbSizeVft = This->typekind == TKIND_DISPATCH ? sizeof(IDispatchVtbl) : This->typeinfo->cbSizeVft;
    (*ppTypeAttr)->cbAlignment = (This->typeinfo->typekind>>11) & 0x1f;
    (*ppTypeAttr)->wTypeFlags = This->typeinfo->flags;
    (*ppTypeAttr)->wMajorVerNum = LOWORD(This->typeinfo->version);
    (*ppTypeAttr)->wMinorVerNum = HIWORD(This->typeinfo->version);

    if((*ppTypeAttr)->typekind == TKIND_ALIAS)
        FIXME("TKIND_ALIAS handling not implemented\n");

    return S_OK;
}

/******************************************************************************
 * ITypeInfo2_GetTypeComp {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnGetTypeComp(
        ITypeInfo2* iface,
        ITypeComp** ppTComp)
{
    FIXME("(%p,%p), stub!\n", iface, ppTComp);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetFuncDesc {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnGetFuncDesc(
        ITypeInfo2* iface,
        UINT index,
        FUNCDESC** ppFuncDesc)
{
    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
    int i, *typedata, num_defaults = 0, hdr_len, tail, has_defaults;
    CyclicList *desc;
    HRESULT hres;

    TRACE("(%p,%d,%p), semi-stub\n", iface, index, ppFuncDesc);

    if (!ppFuncDesc)
        return E_INVALIDARG;

    if (index >= cti2_get_func_count(This->typeinfo))
        return TYPE_E_ELEMENTNOTFOUND;

    hres = ICreateTypeInfo2_LayOut(&This->ICreateTypeInfo2_iface);
    if (FAILED(hres))
        return hres;

    desc = This->typedata->next;
    for (i = index; i >= 0; ) {
        desc = desc->next;
        if (desc->type == CyclicListFunc)
            --i;
    }

    typedata = desc->u.data;

    *ppFuncDesc = heap_alloc_zero(sizeof(FUNCDESC));
    if (!*ppFuncDesc)
        return E_OUTOFMEMORY;

    (*ppFuncDesc)->memid = desc->indice;
    (*ppFuncDesc)->lprgscode = NULL; /* FIXME: Unimplemented */
    (*ppFuncDesc)->funckind = typedata[4] & 0x7;
    (*ppFuncDesc)->invkind = (typedata[4] >> 3) & 0xF;
    (*ppFuncDesc)->callconv = (typedata[4] >> 8) & 0xF;
    (*ppFuncDesc)->cParams = typedata[5];
    (*ppFuncDesc)->cParamsOpt = 0; /* FIXME: Unimplemented*/
    (*ppFuncDesc)->oVft = typedata[3] & 0xFFFF;
    if ((*ppFuncDesc)->oVft)
        --(*ppFuncDesc)->oVft;
    (*ppFuncDesc)->cScodes = 0; /* FIXME: Unimplemented*/
    hres = ctl2_decode_typedesc(This->typelib, typedata[1],
            &(*ppFuncDesc)->elemdescFunc.tdesc);
    if (FAILED(hres)) {
        heap_free(*ppFuncDesc);
        return hres;
    }
    (*ppFuncDesc)->wFuncFlags = typedata[2];

    has_defaults = typedata[4] & 0x1000;
    tail = typedata[5] * (has_defaults ? 16 : 12);
    hdr_len = (ctl2_get_record_size(desc) - tail) / sizeof(int);

    if ((*ppFuncDesc)->cParams > 0) {
        (*ppFuncDesc)->lprgelemdescParam = heap_alloc_zero((*ppFuncDesc)->cParams * sizeof(ELEMDESC));
        if (!(*ppFuncDesc)->lprgelemdescParam) {
            heap_free(*ppFuncDesc);
            return E_OUTOFMEMORY;
        }
        if (has_defaults) {
            num_defaults = (*ppFuncDesc)->cParams;

            for (i = 0; i < num_defaults; ++i) {
                if (typedata[hdr_len + i] != 0xFFFFFFFF) {
                    (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.wParamFlags |= PARAMFLAG_FHASDEFAULT;

                    (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex = heap_alloc(sizeof(PARAMDESCEX));
                    if (!(*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex) {
                        ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc);
                        return E_OUTOFMEMORY;
                    }

                    (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex->cBytes = sizeof(PARAMDESCEX);
                    VariantInit(&(*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
                    hres = ctl2_decode_variant(This->typelib, typedata[hdr_len + i],
                            &(*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
                    if (FAILED(hres)) {
                        ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc);
                        return hres;
                    }
                }
            }
        }

        for (i = 0; i < (*ppFuncDesc)->cParams; ++i) {
            hres = ctl2_decode_typedesc(This->typelib, typedata[hdr_len + num_defaults + (i * 3)],
                    &((*ppFuncDesc)->lprgelemdescParam + i)->tdesc);
            if (FAILED(hres)) {
                ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc);
                return hres;
            }
            (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.wParamFlags = typedata[hdr_len + num_defaults + (i * 3) + 2];
        }
    }

    return S_OK;
}

/******************************************************************************
 * ITypeInfo2_GetVarDesc {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnGetVarDesc(
        ITypeInfo2* iface,
        UINT index,
        VARDESC** ppVarDesc)
{
    FIXME("(%p,%d,%p), stub!\n", iface, index, ppVarDesc);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetNames {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnGetNames(
        ITypeInfo2* iface,
        MEMBERID memid,
        BSTR* rgBstrNames,
        UINT cMaxNames,
        UINT* pcNames)
{
    FIXME("(%p,%d,%p,%d,%p), stub!\n", iface, memid, rgBstrNames, cMaxNames, pcNames);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetRefTypeOfImplType {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnGetRefTypeOfImplType(
        ITypeInfo2* iface,
        UINT index,
        HREFTYPE* pRefType)
{
    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
    MSFT_RefRecord *ref;
    int offset;

    TRACE("(%p,%d,%p)\n", iface, index, pRefType);

    if(!pRefType)
        return E_INVALIDARG;

    if(This->typeinfo->flags&TYPEFLAG_FDUAL) {
        if(index == -1) {
            *pRefType = -2;
            return S_OK;
        }

        if(This->typekind == TKIND_DISPATCH)
            return ITypeInfo2_GetRefTypeOfImplType(&This->dual->ITypeInfo2_iface,
                    index, pRefType);
    }

    if(index>=This->typeinfo->cImplTypes)
        return TYPE_E_ELEMENTNOTFOUND;

    if(This->typekind == TKIND_INTERFACE) {
        *pRefType = This->typeinfo->datatype1 + 2;
        return S_OK;
    }

    offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
    if(offset == -1)
        return TYPE_E_ELEMENTNOTFOUND;

    ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
    *pRefType = ref->reftype;
    return S_OK;
}

/******************************************************************************
 * ITypeInfo2_GetImplTypeFlags {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnGetImplTypeFlags(
        ITypeInfo2* iface,
        UINT index,
        INT* pImplTypeFlags)
{
    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
    int offset;
    MSFT_RefRecord *ref;

    TRACE("(%p,%d,%p)\n", iface, index, pImplTypeFlags);

    if(!pImplTypeFlags)
        return E_INVALIDARG;

    if(index >= This->typeinfo->cImplTypes)
        return TYPE_E_ELEMENTNOTFOUND;

    if(This->typekind != TKIND_COCLASS) {
        *pImplTypeFlags = 0;
        return S_OK;
    }

    offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
    if(offset == -1)
        return TYPE_E_ELEMENTNOTFOUND;

    ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
    *pImplTypeFlags = ref->flags;
    return S_OK;
}

/******************************************************************************
 * ITypeInfo2_GetIDsOfNames {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnGetIDsOfNames(
        ITypeInfo2* iface,
        LPOLESTR* rgszNames,
        UINT cNames,
        MEMBERID* pMemId)
{
    FIXME("(%p,%p,%d,%p), stub!\n", iface, rgszNames, cNames, pMemId);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_Invoke {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnInvoke(
        ITypeInfo2* iface,
        PVOID pvInstance,
        MEMBERID memid,
        WORD wFlags,
        DISPPARAMS* pDispParams,
        VARIANT* pVarResult,
        EXCEPINFO* pExcepInfo,
        UINT* puArgErr)
{
    FIXME("(%p,%p,%d,%x,%p,%p,%p,%p), stub!\n", iface, pvInstance, memid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetDocumentation {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnGetDocumentation(
        ITypeInfo2* iface,
        MEMBERID memid,
        BSTR* pBstrName,
        BSTR* pBstrDocString,
        DWORD* pdwHelpContext,
        BSTR* pBstrHelpFile)
{
    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
    HRESULT status = TYPE_E_ELEMENTNOTFOUND;
    INT nameoffset, docstringoffset, helpcontext;

    TRACE("(%p,%d,%p,%p,%p,%p)\n", iface, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);

    if (memid == -1)
    {
        nameoffset = This->typeinfo->NameOffset;
        docstringoffset = This->typeinfo->docstringoffs;
        helpcontext = This->typeinfo->helpcontext;
        status = S_OK;
    } else {
        CyclicList *iter;
        if (This->typedata) {
            for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) {
                if (iter->indice == memid) {
                    if (iter->type == CyclicListFunc) {
                        const int *typedata = iter->u.data;
                        int size = ctl2_get_record_size(iter) - typedata[5]*(typedata[4]&0x1000?16:12);

                        nameoffset = iter->name;
                        /* FIXME implement this once SetFuncDocString is implemented */
                        docstringoffset = -1;
                        helpcontext = (size < 7*sizeof(int)) ? 0 : typedata[6];

                        status = S_OK;
                    } else {
                        FIXME("Not implemented for variable members\n");
                    }

                    break;
                }
            }
        }
    }

    if (!status) {
        WCHAR *string;
        if (pBstrName) {
            if (nameoffset == -1)
                *pBstrName = NULL;
            else {
                MSFT_NameIntro *name = (MSFT_NameIntro*)&This->typelib->
                        typelib_segment_data[MSFT_SEG_NAME][nameoffset];
                ctl2_decode_name((char*)&name->namelen, &string);
                *pBstrName = SysAllocString(string);
                if(!*pBstrName)
                    return E_OUTOFMEMORY;
            }
        }

        if (pBstrDocString) {
            if (docstringoffset == -1)
                *pBstrDocString = NULL;
            else {
                MSFT_NameIntro *name = (MSFT_NameIntro*)&This->typelib->
                        typelib_segment_data[MSFT_SEG_NAME][docstringoffset];
                ctl2_decode_name((char*)&name->namelen, &string);
                *pBstrDocString = SysAllocString(string);
                if(!*pBstrDocString) {
                    if (pBstrName) SysFreeString(*pBstrName);
                    return E_OUTOFMEMORY;
                }
            }
        }

        if (pdwHelpContext) {
            *pdwHelpContext = helpcontext;
        }

        if (pBstrHelpFile) {
            status = ITypeLib_GetDocumentation((ITypeLib*)&This->typelib->lpVtblTypeLib2,
                    -1, NULL, NULL, NULL, pBstrHelpFile);
            if (status) {
                if (pBstrName) SysFreeString(*pBstrName);
                if (pBstrDocString) SysFreeString(*pBstrDocString);
            }
        }
    }

    return status;
}

/******************************************************************************
 * ITypeInfo2_GetDllEntry {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnGetDllEntry(
        ITypeInfo2* iface,
        MEMBERID memid,
        INVOKEKIND invKind,
        BSTR* pBstrDllName,
        BSTR* pBstrName,
        WORD* pwOrdinal)
{
    FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", iface, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetRefTypeInfo {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo(
        ITypeInfo2* iface,
        HREFTYPE hRefType,
        ITypeInfo** ppTInfo)
{
    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);

    TRACE("(%p,%d,%p)\n", iface, hRefType, ppTInfo);

    if(!ppTInfo)
        return E_INVALIDARG;

    if(hRefType==-2 && This->dual) {
        *ppTInfo = (ITypeInfo *)&This->dual->ITypeInfo2_iface;
        ITypeInfo_AddRef(*ppTInfo);
        return S_OK;
    }

    if(hRefType&1) {
        ITypeLib *tl;
        MSFT_ImpInfo *impinfo;
        MSFT_ImpFile *impfile;
        MSFT_GuidEntry *guid;
        WCHAR *filename;
        HRESULT hres;

        if((hRefType&(~0x3)) >= This->typelib->typelib_segdir[MSFT_SEG_IMPORTINFO].length)
            return E_FAIL;

        impinfo = (MSFT_ImpInfo*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO][hRefType&(~0x3)];
        impfile = (MSFT_ImpFile*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][impinfo->oImpFile];
        guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo->oGuid];

        ctl2_decode_string((unsigned char*)impfile->filename, &filename);

        hres = LoadTypeLib(filename, &tl);
        if(FAILED(hres))
            return hres;

        hres = ITypeLib_GetTypeInfoOfGuid(tl, &guid->guid, ppTInfo);

        ITypeLib_Release(tl);
        return hres;
    } else {
        ICreateTypeInfo2Impl *iter;
        int i = 0;

        for(iter=This->typelib->typeinfos; iter; iter=iter->next_typeinfo) {
            if(This->typelib->typelib_typeinfo_offsets[i] == (hRefType&(~0x3))) {
                *ppTInfo = (ITypeInfo *)&iter->ITypeInfo2_iface;

                ITypeLib_AddRef(*ppTInfo);
                return S_OK;
            }
            i++;
        }
    }

    return E_FAIL;
}

/******************************************************************************
 * ITypeInfo2_AddressOfMember {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnAddressOfMember(
        ITypeInfo2* iface,
        MEMBERID memid,
        INVOKEKIND invKind,
        PVOID* ppv)
{
    FIXME("(%p,%d,%d,%p), stub!\n", iface, memid, invKind, ppv);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_CreateInstance {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnCreateInstance(
        ITypeInfo2* iface,
        IUnknown* pUnkOuter,
        REFIID riid,
        PVOID* ppvObj)
{
    FIXME("(%p,%p,%s,%p), stub!\n", iface, pUnkOuter, debugstr_guid(riid), ppvObj);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetMops {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnGetMops(
        ITypeInfo2* iface,
        MEMBERID memid,
        BSTR* pBstrMops)
{
    FIXME("(%p,%d,%p), stub!\n", iface, memid, pBstrMops);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetContainingTypeLib {OLEAUT32}
 */
static HRESULT WINAPI ITypeInfo2_fnGetContainingTypeLib(
        ITypeInfo2* iface,
        ITypeLib** ppTLib,
        UINT* pIndex)
{
    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);

    TRACE("(%p,%p,%p)\n", iface, ppTLib, pIndex);
    
    *ppTLib = (ITypeLib *)&This->typelib->lpVtblTypeLib2;
    ICreateTypeLib_AddRef((ICreateTypeLib*)This->typelib);
    *pIndex = This->typeinfo->typekind >> 16;

    return S_OK;
}

static void release_typedesc(TYPEDESC *tdesc)
{
    while (tdesc) {
        TYPEDESC *next;
        if (tdesc->vt == VT_USERDEFINED)
            next = NULL;
        else
            next = tdesc->u.lptdesc;
        heap_free(tdesc);
        tdesc = next;
    }
}

/******************************************************************************
 * ITypeInfo2_ReleaseTypeAttr {OLEAUT32}
 */
static void WINAPI ITypeInfo2_fnReleaseTypeAttr(
        ITypeInfo2* iface,
        TYPEATTR* pTypeAttr)
{
    TRACE("(%p,%p)\n", iface, pTypeAttr);

    if (pTypeAttr->tdescAlias.vt != VT_USERDEFINED)
        release_typedesc(pTypeAttr->tdescAlias.u.lptdesc);

    heap_free(pTypeAttr);
}

/******************************************************************************
 * ITypeInfo2_ReleaseFuncDesc {OLEAUT32}
 */
static void WINAPI ITypeInfo2_fnReleaseFuncDesc(
        ITypeInfo2* iface,
        FUNCDESC* pFuncDesc)
{
    int i;

    TRACE("(%p,%p)\n", iface, pFuncDesc);

    heap_free(pFuncDesc->lprgscode);

    if (pFuncDesc->lprgelemdescParam) {
        for (i = 0; i < pFuncDesc->cParams; ++i) {
            if (pFuncDesc->lprgelemdescParam[i].tdesc.vt != VT_USERDEFINED)
                release_typedesc(pFuncDesc->lprgelemdescParam[i].tdesc.u.lptdesc);

            if (pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex)
            {
                VariantClear(&pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
                heap_free(pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex);
            }
        }
        heap_free(pFuncDesc->lprgelemdescParam);
    }

    heap_free(pFuncDesc->elemdescFunc.u.paramdesc.pparamdescex);

    if (pFuncDesc->elemdescFunc.tdesc.vt != VT_USERDEFINED)
        release_typedesc(pFuncDesc->elemdescFunc.tdesc.u.lptdesc);

    heap_free(pFuncDesc);
}

/******************************************************************************
 * ITypeInfo2_ReleaseVarDesc {OLEAUT32}
 */
static void WINAPI ITypeInfo2_fnReleaseVarDesc(
        ITypeInfo2* iface,
        VARDESC* pVarDesc)
{
    FIXME("(%p,%p), stub!\n", iface, pVarDesc);
}

/******************************************************************************
 * ITypeInfo2_GetTypeKind {OLEAUT32}
 *
 *  Get the TYPEKIND value for a TypeInfo.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetTypeKind(
        ITypeInfo2* iface,   /* [I] The TypeInfo to obtain the typekind for. */
        TYPEKIND* pTypeKind) /* [O] The typekind for this TypeInfo. */
{
    FIXME("(%p,%p), stub!\n", iface, pTypeKind);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetTypeFlags {OLEAUT32}
 *
 *  Get the Type Flags for a TypeInfo.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags(
        ITypeInfo2* iface, /* [I] The TypeInfo to obtain the typeflags for. */
        ULONG* pTypeFlags) /* [O] The type flags for this TypeInfo. */
{
    FIXME("(%p,%p), stub!\n", iface, pTypeFlags);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetFuncIndexOfMemId {OLEAUT32}
 *
 *  Gets the index of a function given its member id.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId(
        ITypeInfo2* iface,  /* [I] The TypeInfo in which to find the function. */
        MEMBERID memid,     /* [I] The member id for the function. */
        INVOKEKIND invKind, /* [I] The invocation kind for the function. */
        UINT* pFuncIndex)   /* [O] The index of the function. */
{
    FIXME("(%p,%d,%d,%p), stub!\n", iface, memid, invKind, pFuncIndex);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetVarIndexOfMemId {OLEAUT32}
 *
 *  Gets the index of a variable given its member id.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId(
        ITypeInfo2* iface, /* [I] The TypeInfo in which to find the variable. */
        MEMBERID memid,    /* [I] The member id for the variable. */
        UINT* pVarIndex)   /* [O] The index of the variable. */
{
    FIXME("(%p,%d,%p), stub!\n", iface, memid, pVarIndex);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetCustData {OLEAUT32}
 *
 *  Gets a custom data element from a TypeInfo.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetCustData(
        ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
        REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
        VARIANT* pVarVal)  /* [O] The custom data. */
{
    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
    MSFT_CDGuid *cdentry;
    int offset;

    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), pVarVal);

    if (!guid || !pVarVal)
        return E_INVALIDARG;

    VariantClear(pVarVal);

    offset = ctl2_find_custdata(This->typelib, guid, This->typeinfo->oCustData);
    if (offset == -1)
        return S_OK;

    cdentry = (MSFT_CDGuid *)&This->typelib->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][offset];
    return ctl2_decode_variant(This->typelib, cdentry->DataOffset, pVarVal);
}

/******************************************************************************
 * ITypeInfo2_GetFuncCustData {OLEAUT32}
 *
 *  Gets a custom data element from a function.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData(
        ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
        UINT index,        /* [I] The index of the function for which to retrieve the custom data. */
        REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
        VARIANT* pVarVal)  /* [O] The custom data. */
{
    FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetParamCustData {OLEAUT32}
 *
 *  Gets a custom data element from a parameter.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetParamCustData(
        ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
        UINT indexFunc,    /* [I] The index of the function for which to retrieve the custom data. */
        UINT indexParam,   /* [I] The index of the parameter for which to retrieve the custom data. */
        REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
        VARIANT* pVarVal)  /* [O] The custom data. */
{
    FIXME("(%p,%d,%d,%s,%p), stub!\n", iface, indexFunc, indexParam, debugstr_guid(guid), pVarVal);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetVarCustData {OLEAUT32}
 *
 *  Gets a custom data element from a variable.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetVarCustData(
        ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
        UINT index,        /* [I] The index of the variable for which to retrieve the custom data. */
        REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
        VARIANT* pVarVal)  /* [O] The custom data. */
{
    FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetImplTypeCustData {OLEAUT32}
 *
 *  Gets a custom data element from an implemented type of a TypeInfo.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData(
        ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
        UINT index,        /* [I] The index of the implemented type for which to retrieve the custom data. */
        REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
        VARIANT* pVarVal)  /* [O] The custom data. */
{
    FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetDocumentation2 {OLEAUT32}
 *
 *  Gets some documentation from a TypeInfo in a locale-aware fashion.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of STG_E_INSUFFICIENTMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(
        ITypeInfo2* iface,           /* [I] The TypeInfo to retrieve the documentation from. */
        MEMBERID memid,              /* [I] The member id (why?). */
        LCID lcid,                   /* [I] The locale (why?). */
        BSTR* pbstrHelpString,       /* [O] The help string. */
        DWORD* pdwHelpStringContext, /* [O] The help string context. */
        BSTR* pbstrHelpStringDll)    /* [O] The help file name. */
{
    FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", iface, memid, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetAllCustData {OLEAUT32}
 *
 *  Gets all of the custom data associated with a TypeInfo.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllCustData(
        ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
        CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
{
    FIXME("(%p,%p), stub!\n", iface, pCustData);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetAllFuncCustData {OLEAUT32}
 *
 *  Gets all of the custom data associated with a function.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData(
        ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
        UINT index,          /* [I] The index of the function for which to retrieve the custom data. */
        CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
{
    FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetAllParamCustData {OLEAUT32}
 *
 *  Gets all of the custom data associated with a parameter.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData(
        ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
        UINT indexFunc,      /* [I] The index of the function for which to retrieve the custom data. */
        UINT indexParam,     /* [I] The index of the parameter for which to retrieve the custom data. */
        CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
{
    FIXME("(%p,%d,%d,%p), stub!\n", iface, indexFunc, indexParam, pCustData);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetAllVarCustData {OLEAUT32}
 *
 *  Gets all of the custom data associated with a variable.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData(
        ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
        UINT index,          /* [I] The index of the variable for which to retrieve the custom data. */
        CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
{
    FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeInfo2_GetAllImplTypeCustData {OLEAUT32}
 *
 *  Gets all of the custom data associated with an implemented type.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData(
        ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
        UINT index,          /* [I] The index of the implemented type for which to retrieve the custom data. */
        CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
{
    FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
    return E_OUTOFMEMORY;
}


/*================== ICreateTypeInfo2 & ITypeInfo2 VTABLEs And Creation ===================================*/

static const ICreateTypeInfo2Vtbl ctypeinfo2vt =
{

    ICreateTypeInfo2_fnQueryInterface,
    ICreateTypeInfo2_fnAddRef,
    ICreateTypeInfo2_fnRelease,

    ICreateTypeInfo2_fnSetGuid,
    ICreateTypeInfo2_fnSetTypeFlags,
    ICreateTypeInfo2_fnSetDocString,
    ICreateTypeInfo2_fnSetHelpContext,
    ICreateTypeInfo2_fnSetVersion,
    ICreateTypeInfo2_fnAddRefTypeInfo,
    ICreateTypeInfo2_fnAddFuncDesc,
    ICreateTypeInfo2_fnAddImplType,
    ICreateTypeInfo2_fnSetImplTypeFlags,
    ICreateTypeInfo2_fnSetAlignment,
    ICreateTypeInfo2_fnSetSchema,
    ICreateTypeInfo2_fnAddVarDesc,
    ICreateTypeInfo2_fnSetFuncAndParamNames,
    ICreateTypeInfo2_fnSetVarName,
    ICreateTypeInfo2_fnSetTypeDescAlias,
    ICreateTypeInfo2_fnDefineFuncAsDllEntry,
    ICreateTypeInfo2_fnSetFuncDocString,
    ICreateTypeInfo2_fnSetVarDocString,
    ICreateTypeInfo2_fnSetFuncHelpContext,
    ICreateTypeInfo2_fnSetVarHelpContext,
    ICreateTypeInfo2_fnSetMops,
    ICreateTypeInfo2_fnSetTypeIdldesc,
    ICreateTypeInfo2_fnLayOut,

    ICreateTypeInfo2_fnDeleteFuncDesc,
    ICreateTypeInfo2_fnDeleteFuncDescByMemId,
    ICreateTypeInfo2_fnDeleteVarDesc,
    ICreateTypeInfo2_fnDeleteVarDescByMemId,
    ICreateTypeInfo2_fnDeleteImplType,
    ICreateTypeInfo2_fnSetCustData,
    ICreateTypeInfo2_fnSetFuncCustData,
    ICreateTypeInfo2_fnSetParamCustData,
    ICreateTypeInfo2_fnSetVarCustData,
    ICreateTypeInfo2_fnSetImplTypeCustData,
    ICreateTypeInfo2_fnSetHelpStringContext,
    ICreateTypeInfo2_fnSetFuncHelpStringContext,
    ICreateTypeInfo2_fnSetVarHelpStringContext,
    ICreateTypeInfo2_fnInvalidate,
    ICreateTypeInfo2_fnSetName
};

static const ITypeInfo2Vtbl typeinfo2vt =
{

    ITypeInfo2_fnQueryInterface,
    ITypeInfo2_fnAddRef,
    ITypeInfo2_fnRelease,

    ITypeInfo2_fnGetTypeAttr,
    ITypeInfo2_fnGetTypeComp,
    ITypeInfo2_fnGetFuncDesc,
    ITypeInfo2_fnGetVarDesc,
    ITypeInfo2_fnGetNames,
    ITypeInfo2_fnGetRefTypeOfImplType,
    ITypeInfo2_fnGetImplTypeFlags,
    ITypeInfo2_fnGetIDsOfNames,
    ITypeInfo2_fnInvoke,
    ITypeInfo2_fnGetDocumentation,
    ITypeInfo2_fnGetDllEntry,
    ITypeInfo2_fnGetRefTypeInfo,
    ITypeInfo2_fnAddressOfMember,
    ITypeInfo2_fnCreateInstance,
    ITypeInfo2_fnGetMops,
    ITypeInfo2_fnGetContainingTypeLib,
    ITypeInfo2_fnReleaseTypeAttr,
    ITypeInfo2_fnReleaseFuncDesc,
    ITypeInfo2_fnReleaseVarDesc,

    ITypeInfo2_fnGetTypeKind,
    ITypeInfo2_fnGetTypeFlags,
    ITypeInfo2_fnGetFuncIndexOfMemId,
    ITypeInfo2_fnGetVarIndexOfMemId,
    ITypeInfo2_fnGetCustData,
    ITypeInfo2_fnGetFuncCustData,
    ITypeInfo2_fnGetParamCustData,
    ITypeInfo2_fnGetVarCustData,
    ITypeInfo2_fnGetImplTypeCustData,
    ITypeInfo2_fnGetDocumentation2,
    ITypeInfo2_fnGetAllCustData,
    ITypeInfo2_fnGetAllFuncCustData,
    ITypeInfo2_fnGetAllParamCustData,
    ITypeInfo2_fnGetAllVarCustData,
    ITypeInfo2_fnGetAllImplTypeCustData,
};

static ICreateTypeInfo2 *ICreateTypeInfo2_Constructor(ICreateTypeLib2Impl *typelib, WCHAR *szName, TYPEKIND tkind)
{
    ICreateTypeInfo2Impl *pCreateTypeInfo2Impl;

    int nameoffset;
    int typeinfo_offset;
    MSFT_TypeInfoBase *typeinfo;

    TRACE("Constructing ICreateTypeInfo2 for %s with tkind %d\n", debugstr_w(szName), tkind);

    pCreateTypeInfo2Impl = heap_alloc_zero(sizeof(ICreateTypeInfo2Impl));
    if (!pCreateTypeInfo2Impl) return NULL;

    pCreateTypeInfo2Impl->ICreateTypeInfo2_iface.lpVtbl = &ctypeinfo2vt;
    pCreateTypeInfo2Impl->ITypeInfo2_iface.lpVtbl = &typeinfo2vt;
    pCreateTypeInfo2Impl->ref = 1;

    pCreateTypeInfo2Impl->typelib = typelib;
    ICreateTypeLib_AddRef((ICreateTypeLib*)typelib);

    nameoffset = ctl2_alloc_name(typelib, szName);
    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;

    pCreateTypeInfo2Impl->typeinfo = typeinfo;

    pCreateTypeInfo2Impl->typekind = tkind;
    typeinfo->typekind |= tkind | 0x20;
    ICreateTypeInfo2_SetAlignment(&pCreateTypeInfo2Impl->ICreateTypeInfo2_iface, 4);

    switch (tkind) {
    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:
	FIXME("(%s,%d), unrecognized typekind %d\n", debugstr_w(szName), tkind, tkind);
	typeinfo->size = 0xdeadbeef;
	break;
    }

    if (typelib->last_typeinfo) typelib->last_typeinfo->next_typeinfo = pCreateTypeInfo2Impl;
    typelib->last_typeinfo = pCreateTypeInfo2Impl;
    if (!typelib->typeinfos) typelib->typeinfos = pCreateTypeInfo2Impl;

    TRACE(" -- %p\n", pCreateTypeInfo2Impl);

    return &pCreateTypeInfo2Impl->ICreateTypeInfo2_iface;
}


/*================== ICreateTypeLib2 Implementation ===================================*/

/******************************************************************************
 * ICreateTypeLib2_QueryInterface {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface(
	ICreateTypeLib2 * iface,
	REFIID riid,
	VOID **ppvObject)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;

    TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));

    *ppvObject=NULL;
    if(IsEqualIID(riid, &IID_IUnknown) ||
       IsEqualIID(riid,&IID_ICreateTypeLib)||
       IsEqualIID(riid,&IID_ICreateTypeLib2))
    {
        *ppvObject = This;
    } else if (IsEqualIID(riid, &IID_ITypeLib) ||
	       IsEqualIID(riid, &IID_ITypeLib2)) {
	*ppvObject = &This->lpVtblTypeLib2;
    }

    if(*ppvObject)
    {
        ICreateTypeLib2_AddRef(iface);
        TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
        return S_OK;
    }
    TRACE("-- Interface: E_NOINTERFACE\n");
    return E_NOINTERFACE;
}

/******************************************************************************
 * ICreateTypeLib2_AddRef {OLEAUT32}
 */
static ULONG WINAPI ICreateTypeLib2_fnAddRef(ICreateTypeLib2 *iface)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(%u)\n", This, ref);

    return ref;
}

/******************************************************************************
 * ICreateTypeLib2_Release {OLEAUT32}
 */
static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%u)\n", This, ref);

    if (!ref) {
	int i;

	for (i = 0; i < MSFT_SEG_MAX; i++) {
            heap_free(This->typelib_segment_data[i]);
            This->typelib_segment_data[i] = NULL;
	}

        heap_free(This->filename);
        This->filename = NULL;

	while (This->typeinfos) {
	    ICreateTypeInfo2Impl *typeinfo = This->typeinfos;
	    This->typeinfos = typeinfo->next_typeinfo;
            if(typeinfo->typedata) {
                CyclicList *iter, *rem;

                rem = typeinfo->typedata->next;
                typeinfo->typedata->next = NULL;
                iter = rem->next;
                heap_free(rem);

                while(iter) {
                    rem = iter;
                    iter = iter->next;
                    heap_free(rem->u.data);
                    heap_free(rem);
                }
            }

            heap_free(typeinfo->dual);
            heap_free(typeinfo);
	}

	heap_free(This);
    }

    return ref;
}


/******************************************************************************
 * ICreateTypeLib2_CreateTypeInfo {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo(
	ICreateTypeLib2 * iface,
	LPOLESTR szName,
	TYPEKIND tkind,
	ICreateTypeInfo **tinfo)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
    char *name;

    TRACE("(%p,%s,%d,%p)\n", iface, debugstr_w(szName), tkind, tinfo);

    if (!szName || !tinfo) return E_INVALIDARG;

    ctl2_encode_name(This, szName, &name);
    if(ctl2_find_name(This, name) != -1)
        return TYPE_E_NAMECONFLICT;

    *tinfo = (ICreateTypeInfo *)ICreateTypeInfo2_Constructor(This, szName, tkind);
    if (!*tinfo) return E_OUTOFMEMORY;

    return S_OK;
}

/******************************************************************************
 * ICreateTypeLib2_SetName {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeLib2_fnSetName(
	ICreateTypeLib2 * iface,
	LPOLESTR szName)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;

    int offset;

    TRACE("(%p,%s)\n", iface, debugstr_w(szName));

    offset = ctl2_alloc_name(This, szName);
    if (offset == -1) return E_OUTOFMEMORY;
    This->typelib_header.NameOffset = offset;
    return S_OK;
}

/******************************************************************************
 * ICreateTypeLib2_SetVersion {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeLib2_fnSetVersion(ICreateTypeLib2 * iface, WORD wMajorVerNum, WORD wMinorVerNum)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;

    TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum);

    This->typelib_header.version = wMajorVerNum | (wMinorVerNum << 16);
    return S_OK;
}

/******************************************************************************
 * ICreateTypeLib2_SetGuid {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeLib2_fnSetGuid(ICreateTypeLib2 * iface, REFGUID guid)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;

    MSFT_GuidEntry guidentry;
    int offset;

    TRACE("(%p,%s)\n", iface, debugstr_guid(guid));

    guidentry.guid = *guid;
    guidentry.hreftype = -2;
    guidentry.next_hash = -1;

    offset = ctl2_alloc_guid(This, &guidentry);
    
    if (offset == -1) return E_OUTOFMEMORY;

    This->typelib_header.posguid = offset;

    return S_OK;
}

/******************************************************************************
 * ICreateTypeLib2_SetDocString {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeLib2_fnSetDocString(ICreateTypeLib2 * iface, LPOLESTR szDoc)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;

    int offset;

    TRACE("(%p,%s)\n", iface, debugstr_w(szDoc));
    if (!szDoc)
        return E_INVALIDARG;

    offset = ctl2_alloc_string(This, szDoc);
    if (offset == -1) return E_OUTOFMEMORY;
    This->typelib_header.helpstring = offset;
    return S_OK;
}

/******************************************************************************
 * ICreateTypeLib2_SetHelpFileName {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 * iface, LPOLESTR szHelpFileName)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;

    int offset;

    TRACE("(%p,%s)\n", iface, debugstr_w(szHelpFileName));

    offset = ctl2_alloc_string(This, szHelpFileName);
    if (offset == -1) return E_OUTOFMEMORY;
    This->typelib_header.helpfile = offset;
    This->typelib_header.varflags |= 0x10;
    return S_OK;
}

/******************************************************************************
 * ICreateTypeLib2_SetHelpContext {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 * iface, DWORD dwHelpContext)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;

    TRACE("(%p,%d)\n", iface, dwHelpContext);
    This->typelib_header.helpcontext = dwHelpContext;
    return S_OK;
}

/******************************************************************************
 * ICreateTypeLib2_SetLcid {OLEAUT32}
 *
 * Sets both the lcid and lcid2 members in the header to lcid.
 *
 * As a special case if lcid == LOCALE_NEUTRAL (0), then the first header lcid
 * is set to US English while the second one is set to 0.
 */
static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 * iface, LCID lcid)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;

    TRACE("(%p,%d)\n", iface, lcid);

    This->typelib_header.lcid = This->typelib_header.lcid2 = lcid;

    if(lcid == LOCALE_NEUTRAL) This->typelib_header.lcid = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);

    return S_OK;
}

/******************************************************************************
 * ICreateTypeLib2_SetLibFlags {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeLib2_fnSetLibFlags(ICreateTypeLib2 * iface, UINT uLibFlags)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;

    TRACE("(%p,0x%x)\n", iface, uLibFlags);

    This->typelib_header.flags = uLibFlags;

    return S_OK;
}

static int ctl2_write_chunk(HANDLE hFile, const void *segment, int length)
{
    DWORD dwWritten;
    if (!WriteFile(hFile, segment, length, &dwWritten, 0)) {
        CloseHandle(hFile);
        return 0;
    }
    return -1;
}

static int ctl2_write_segment(ICreateTypeLib2Impl *This, HANDLE hFile, int segment)
{
    DWORD dwWritten;
    if (!WriteFile(hFile, This->typelib_segment_data[segment],
		   This->typelib_segdir[segment].length, &dwWritten, 0)) {
	CloseHandle(hFile);
	return 0;
    }

    return -1;
}

static HRESULT ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize)
{
    ICreateTypeInfo2Impl *typeinfo;
    HRESULT hres;

    for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
        typeinfo->typeinfo->memoffset = filesize;

        hres = ICreateTypeInfo2_fnLayOut(&typeinfo->ICreateTypeInfo2_iface);
        if(FAILED(hres))
            return hres;

	if (typeinfo->typedata)
	    filesize += typeinfo->typedata->next->u.val
                + cti2_get_var_count(typeinfo->typeinfo) * 12
                + cti2_get_func_count(typeinfo->typeinfo) * 12 + 4;
    }

    return S_OK;
}

static int ctl2_finalize_segment(ICreateTypeLib2Impl *This, int filepos, int segment)
{
    if (This->typelib_segdir[segment].length) {
	This->typelib_segdir[segment].offset = filepos;
    } else {
	This->typelib_segdir[segment].offset = -1;
    }

    return This->typelib_segdir[segment].length;
}

static void ctl2_write_typeinfos(ICreateTypeLib2Impl *This, HANDLE hFile)
{
    ICreateTypeInfo2Impl *typeinfo;

    for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
        CyclicList *iter;
        int offset = 0;

	if (!typeinfo->typedata) continue;

        iter = typeinfo->typedata->next;
        ctl2_write_chunk(hFile, &iter->u.val, sizeof(int));
        for(iter=iter->next; iter!=typeinfo->typedata->next; iter=iter->next)
            ctl2_write_chunk(hFile, iter->u.data, ctl2_get_record_size(iter));

        for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
            ctl2_write_chunk(hFile, &iter->indice, sizeof(int));

        for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
            ctl2_write_chunk(hFile, &iter->name, sizeof(int));

        for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) {
            ctl2_write_chunk(hFile, &offset, sizeof(int));
            offset += ctl2_get_record_size(iter);
        }
    }
}

/******************************************************************************
 * ICreateTypeLib2_SaveAllChanges {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;

    int retval;
    int filepos;
    HANDLE hFile;
    HRESULT hres;

    TRACE("(%p)\n", iface);

    retval = TYPE_E_IOERROR;

    hFile = CreateFileW(This->filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    if (hFile == INVALID_HANDLE_VALUE) return retval;

    filepos = sizeof(MSFT_Header) + sizeof(MSFT_SegDir);
    filepos += This->typelib_header.nrtypeinfos * 4;

    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEINFO);
    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUIDHASH);
    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUID);
    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_REFERENCES);
    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTINFO);
    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTFILES);
    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAMEHASH);
    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAME);
    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_STRING);
    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEDESC);
    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_ARRAYDESC);
    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATA);
    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATAGUID);

    hres = ctl2_finalize_typeinfos(This, filepos);
    if(FAILED(hres)) {
        CloseHandle(hFile);
        return hres;
    }

    if (!ctl2_write_chunk(hFile, &This->typelib_header, sizeof(This->typelib_header))) return retval;
    if (This->typelib_header.varflags & HELPDLLFLAG)
        if (!ctl2_write_chunk(hFile, &This->helpStringDll, sizeof(This->helpStringDll))) return retval;
    if (!ctl2_write_chunk(hFile, This->typelib_typeinfo_offsets, This->typelib_header.nrtypeinfos * 4)) return retval;
    if (!ctl2_write_chunk(hFile, This->typelib_segdir, sizeof(This->typelib_segdir))) return retval;
    if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEINFO    )) return retval;
    if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUIDHASH    )) return retval;
    if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUID        )) return retval;
    if (!ctl2_write_segment(This, hFile, MSFT_SEG_REFERENCES  )) return retval;
    if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTINFO  )) return retval;
    if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTFILES )) return retval;
    if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAMEHASH    )) return retval;
    if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAME        )) return retval;
    if (!ctl2_write_segment(This, hFile, MSFT_SEG_STRING      )) return retval;
    if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEDESC    )) return retval;
    if (!ctl2_write_segment(This, hFile, MSFT_SEG_ARRAYDESC   )) return retval;
    if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATA    )) return retval;
    if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATAGUID)) return retval;

    ctl2_write_typeinfos(This, hFile);

    if (!CloseHandle(hFile)) return retval;

    return S_OK;
}


/******************************************************************************
 * ICreateTypeLib2_DeleteTypeInfo {OLEAUT32}
 *
 *  Deletes a named TypeInfo from a type library.
 *
 * RETURNS
 *
 *  Success: S_OK
 *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ICreateTypeLib2_fnDeleteTypeInfo(
	ICreateTypeLib2 * iface, /* [I] The type library to delete from. */
	LPOLESTR szName)         /* [I] The name of the typeinfo to delete. */
{
    FIXME("(%p,%s), stub!\n", iface, debugstr_w(szName));
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeLib2_SetCustData {OLEAUT32}
 *
 *  Sets custom data for a type library.
 *
 * RETURNS
 *
 *  Success: S_OK
 *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ICreateTypeLib2_fnSetCustData(
	ICreateTypeLib2 * iface, /* [I] The type library to store the custom data in. */
	REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
	VARIANT *pVarVal)        /* [I] The custom data itself. */
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;

    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), pVarVal);

    return ctl2_set_custdata(This, guid, pVarVal, &This->typelib_header.CustomDataOffset);
}

/******************************************************************************
 * ICreateTypeLib2_SetHelpStringContext {OLEAUT32}
 *
 *  Sets a context number for the library help string.
 *
 * PARAMS
 *  iface     [I] The type library to set the help string context for.
 *  dwContext [I] The help string context.
 *
 * RETURNS
 *  Success: S_OK
 *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
 */
static
HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 * iface,
                                                      ULONG dwContext)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;

    TRACE("(%p,%d)\n", iface, dwContext);

    This->typelib_header.helpstringcontext = dwContext;
    return S_OK;
}

/******************************************************************************
 * ICreateTypeLib2_SetHelpStringDll {OLEAUT32}
 *
 *  Set the DLL used to look up localized help strings.
 *
 * PARAMS
 *  iface     [I] The type library to set the help DLL for.
 *  szDllName [I] The name of the help DLL.
 *
 * RETURNS
 *  Success: S_OK
 *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
 */
static
HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringDll(ICreateTypeLib2 * iface,
                                                  LPOLESTR szDllName)
{
    ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
    int offset;

    TRACE("(%p,%s)\n", iface, debugstr_w(szDllName));
    if (!szDllName)
        return E_INVALIDARG;

    offset = ctl2_alloc_string(This, szDllName);
    if (offset == -1)
        return E_OUTOFMEMORY;
    This->typelib_header.varflags |= HELPDLLFLAG;
    This->helpStringDll = offset;
    return S_OK;
}

/*================== ITypeLib2 Implementation ===================================*/

/******************************************************************************
 * ITypeLib2_QueryInterface {OLEAUT32}
 */
static HRESULT WINAPI ITypeLib2_fnQueryInterface(ITypeLib2 * iface, REFIID riid, LPVOID * ppv)
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    return ICreateTypeLib2_QueryInterface((ICreateTypeLib2 *)This, riid, ppv);
}

/******************************************************************************
 * ITypeLib2_AddRef {OLEAUT32}
 */
static ULONG WINAPI ITypeLib2_fnAddRef(ITypeLib2 * iface)
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    return ICreateTypeLib2_AddRef((ICreateTypeLib2 *)This);
}

/******************************************************************************
 * ITypeLib2_Release {OLEAUT32}
 */
static ULONG WINAPI ITypeLib2_fnRelease(ITypeLib2 * iface)
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    return ICreateTypeLib2_Release((ICreateTypeLib2 *)This);
}

/******************************************************************************
 * ITypeLib2_GetTypeInfoCount {OLEAUT32}
 */
static UINT WINAPI ITypeLib2_fnGetTypeInfoCount(
        ITypeLib2 * iface)
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    TRACE("(%p)\n", iface);

    return This->typelib_header.nrtypeinfos;
}

/******************************************************************************
 * ITypeLib2_GetTypeInfo {OLEAUT32}
 */
static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(
        ITypeLib2 * iface,
        UINT index,
        ITypeInfo** ppTInfo)
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    TRACE("(%p,%d,%p)\n", iface, index, ppTInfo);

    if (!ppTInfo) return E_INVALIDARG;

    if (index >= This->typelib_header.nrtypeinfos) {
	return TYPE_E_ELEMENTNOTFOUND;
    }

    return ctl2_find_typeinfo_from_offset(This, This->typelib_typeinfo_offsets[index], ppTInfo);
}

/******************************************************************************
 * ITypeLib2_GetTypeInfoType {OLEAUT32}
 */
static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType(
        ITypeLib2 * iface,
        UINT index,
        TYPEKIND* kind)
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    TRACE("(%p,%d,%p)\n", iface, index, kind);

    if (!kind) return E_INVALIDARG;

    if (index >= This->typelib_header.nrtypeinfos) {
	return TYPE_E_ELEMENTNOTFOUND;
    }

    *kind = (This->typelib_segment_data[MSFT_SEG_TYPEINFO][This->typelib_typeinfo_offsets[index]]) & 0xF;

    return S_OK;
}

/******************************************************************************
 * ITypeLib2_GetTypeInfoOfGuid {OLEAUT32}
 */
static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(
        ITypeLib2 * iface,
        REFGUID guid,
        ITypeInfo** ppTinfo)
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    int guidoffset;
    int typeinfo;

    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), ppTinfo);

    guidoffset = ctl2_find_guid(This, ctl2_hash_guid(guid), guid);
    if (guidoffset == -1) return TYPE_E_ELEMENTNOTFOUND;

    typeinfo = ((MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][guidoffset])->hreftype;
    if (typeinfo < 0) return TYPE_E_ELEMENTNOTFOUND;

    return ctl2_find_typeinfo_from_offset(This, typeinfo, ppTinfo);
}

/******************************************************************************
 * ITypeLib2_GetLibAttr {OLEAUT32}
 */
static HRESULT WINAPI ITypeLib2_fnGetLibAttr(
        ITypeLib2 * iface,
        TLIBATTR** ppTLibAttr)
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    TRACE("(%p,%p)\n", This, ppTLibAttr);

    if(!ppTLibAttr)
        return E_INVALIDARG;

    *ppTLibAttr = heap_alloc_zero(sizeof(TLIBATTR));
    if(!*ppTLibAttr)
        return E_OUTOFMEMORY;

    if(This->typelib_header.posguid != -1) {
        MSFT_GuidEntry *guid;

        guid = (MSFT_GuidEntry*)&This->typelib_segment_data[MSFT_SEG_GUID][This->typelib_header.posguid];
        (*ppTLibAttr)->guid = guid->guid;
    }

    (*ppTLibAttr)->lcid = This->typelib_header.lcid;
    (*ppTLibAttr)->syskind = ctl2_get_syskind(This);
    (*ppTLibAttr)->wMajorVerNum = LOWORD(This->typelib_header.version);
    (*ppTLibAttr)->wMinorVerNum = HIWORD(This->typelib_header.version);
    (*ppTLibAttr)->wLibFlags = This->typelib_header.flags;
    return S_OK;
}

/******************************************************************************
 * ITypeLib2_GetTypeComp {OLEAUT32}
 */
static HRESULT WINAPI ITypeLib2_fnGetTypeComp(
        ITypeLib2 * iface,
        ITypeComp** ppTComp)
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    FIXME("(%p,%p), stub!\n", This, ppTComp);

    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeLib2_GetDocumentation {OLEAUT32}
 */
static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
        ITypeLib2 * iface,
        INT index,
        BSTR* pBstrName,
        BSTR* pBstrDocString,
        DWORD* pdwHelpContext,
        BSTR* pBstrHelpFile)
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
    WCHAR *string;

    TRACE("(%p,%d,%p,%p,%p,%p)\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);

    if(index != -1) {
        ICreateTypeInfo2Impl *iter;

        for(iter=This->typeinfos; iter!=NULL && index!=0; iter=iter->next_typeinfo)
            index--;

        if(!iter)
            return TYPE_E_ELEMENTNOTFOUND;

        return ITypeInfo_GetDocumentation(&iter->ITypeInfo2_iface,
                -1, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
    }

    if(pBstrName) {
        if(This->typelib_header.NameOffset == -1)
            *pBstrName = NULL;
        else {
            MSFT_NameIntro *name = (MSFT_NameIntro*)&This->
                typelib_segment_data[MSFT_SEG_NAME][This->typelib_header.NameOffset];

            ctl2_decode_name((char*)&name->namelen, &string);

            *pBstrName = SysAllocString(string);
            if(!*pBstrName)
                return E_OUTOFMEMORY;
        }
    }

    if(pBstrDocString) {
        if(This->typelib_header.helpstring == -1)
            *pBstrDocString = NULL;
        else {
            ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpstring], &string);

            *pBstrDocString = SysAllocString(string);
            if(!*pBstrDocString) {
                if(pBstrName) SysFreeString(*pBstrName);
                return E_OUTOFMEMORY;
            }
        }
    }

    if(pdwHelpContext)
        *pdwHelpContext = This->typelib_header.helpcontext;

    if(pBstrHelpFile) {
        if(This->typelib_header.helpfile == -1)
            *pBstrHelpFile = NULL;
        else {
            ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpfile], &string);

            *pBstrHelpFile = SysAllocString(string);
            if(!*pBstrHelpFile) {
                if(pBstrName) SysFreeString(*pBstrName);
                if(pBstrDocString) SysFreeString(*pBstrDocString);
                return E_OUTOFMEMORY;
            }
        }
    }

    return S_OK;
}

/******************************************************************************
 * ITypeLib2_IsName {OLEAUT32}
 */
static HRESULT WINAPI ITypeLib2_fnIsName(
        ITypeLib2 * iface,
        LPOLESTR szNameBuf,
        ULONG lHashVal,
        BOOL* pfName)
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    char *encoded_name;
    int nameoffset;
    MSFT_NameIntro *nameintro;

    TRACE("(%p,%s,%x,%p)\n", iface, debugstr_w(szNameBuf), lHashVal, pfName);

    ctl2_encode_name(This, szNameBuf, &encoded_name);
    nameoffset = ctl2_find_name(This, encoded_name);

    *pfName = 0;

    if (nameoffset == -1) return S_OK;

    nameintro = (MSFT_NameIntro *)(&This->typelib_segment_data[MSFT_SEG_NAME][nameoffset]);
    if (nameintro->hreftype == -1) return S_OK;

    *pfName = 1;

    FIXME("Should be decoding our copy of the name over szNameBuf.\n");

    return S_OK;
}

/******************************************************************************
 * ITypeLib2_FindName {OLEAUT32}
 */
static HRESULT WINAPI ITypeLib2_fnFindName(
        ITypeLib2 * iface,
        LPOLESTR szNameBuf,
        ULONG lHashVal,
        ITypeInfo** ppTInfo,
        MEMBERID* rgMemId,
        USHORT* pcFound)
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    FIXME("(%p,%s,%x,%p,%p,%p), stub!\n", This, debugstr_w(szNameBuf), lHashVal, ppTInfo, rgMemId, pcFound);

    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ITypeLib2_ReleaseTLibAttr {OLEAUT32}
 */
static void WINAPI ITypeLib2_fnReleaseTLibAttr(
        ITypeLib2 * iface,
        TLIBATTR* attr)
{
    TRACE("(%p,%p)\n", iface, attr);
    heap_free(attr);
}

/******************************************************************************
 * ICreateTypeLib2_GetCustData {OLEAUT32}
 *
 *  Retrieves a custom data value stored on a type library.
 *
 * RETURNS
 *
 *  Success: S_OK
 *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeLib2_fnGetCustData(
        ITypeLib2 * iface, /* [I] The type library in which to find the custom data. */
        REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
        VARIANT* pVarVal)  /* [O] The custom data. */
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    FIXME("(%p,%s,%p), stub!\n", This, debugstr_guid(guid), pVarVal);

    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeLib2_GetLibStatistics {OLEAUT32}
 *
 *  Retrieves some statistics about names in a type library, supposedly for
 *  hash table optimization purposes.
 *
 * RETURNS
 *
 *  Success: S_OK
 *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(
        ITypeLib2 * iface,      /* [I] The type library to get statistics about. */
        ULONG* pcUniqueNames,   /* [O] The number of unique names in the type library. */
        ULONG* pcchUniqueNames) /* [O] The number of changed (?) characters in names in the type library. */
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    FIXME("(%p,%p,%p), stub!\n", This, pcUniqueNames, pcchUniqueNames);

    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeLib2_GetDocumentation2 {OLEAUT32}
 *
 *  Obtain locale-aware help string information.
 *
 * RETURNS
 *
 *  Success: S_OK
 *  Failure: STG_E_INSUFFICIENTMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
        ITypeLib2 * iface,
        INT index,
        LCID lcid,
        BSTR* pbstrHelpString,
        DWORD* pdwHelpStringContext,
        BSTR* pbstrHelpStringDll)
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", This, index, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);

    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeLib2_GetAllCustData {OLEAUT32}
 *
 *  Retrieve all of the custom data for a type library.
 *
 * RETURNS
 *
 *  Success: S_OK
 *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
 */
static HRESULT WINAPI ITypeLib2_fnGetAllCustData(
        ITypeLib2 * iface,   /* [I] The type library in which to find the custom data. */
        CUSTDATA* pCustData) /* [O] The structure in which to place the custom data. */
{
    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);

    FIXME("(%p,%p), stub!\n", This, pCustData);

    return E_OUTOFMEMORY;
}


/*================== ICreateTypeLib2 & ITypeLib2 VTABLEs And Creation ===================================*/

static const ICreateTypeLib2Vtbl ctypelib2vt =
{

    ICreateTypeLib2_fnQueryInterface,
    ICreateTypeLib2_fnAddRef,
    ICreateTypeLib2_fnRelease,

    ICreateTypeLib2_fnCreateTypeInfo,
    ICreateTypeLib2_fnSetName,
    ICreateTypeLib2_fnSetVersion,
    ICreateTypeLib2_fnSetGuid,
    ICreateTypeLib2_fnSetDocString,
    ICreateTypeLib2_fnSetHelpFileName,
    ICreateTypeLib2_fnSetHelpContext,
    ICreateTypeLib2_fnSetLcid,
    ICreateTypeLib2_fnSetLibFlags,
    ICreateTypeLib2_fnSaveAllChanges,

    ICreateTypeLib2_fnDeleteTypeInfo,
    ICreateTypeLib2_fnSetCustData,
    ICreateTypeLib2_fnSetHelpStringContext,
    ICreateTypeLib2_fnSetHelpStringDll
};

static const ITypeLib2Vtbl typelib2vt =
{

    ITypeLib2_fnQueryInterface,
    ITypeLib2_fnAddRef,
    ITypeLib2_fnRelease,

    ITypeLib2_fnGetTypeInfoCount,
    ITypeLib2_fnGetTypeInfo,
    ITypeLib2_fnGetTypeInfoType,
    ITypeLib2_fnGetTypeInfoOfGuid,
    ITypeLib2_fnGetLibAttr,
    ITypeLib2_fnGetTypeComp,
    ITypeLib2_fnGetDocumentation,
    ITypeLib2_fnIsName,
    ITypeLib2_fnFindName,
    ITypeLib2_fnReleaseTLibAttr,

    ITypeLib2_fnGetCustData,
    ITypeLib2_fnGetLibStatistics,
    ITypeLib2_fnGetDocumentation2,
    ITypeLib2_fnGetAllCustData,
};

static ICreateTypeLib2 *ICreateTypeLib2_Constructor(SYSKIND syskind, LPCOLESTR szFile)
{
    ICreateTypeLib2Impl *pCreateTypeLib2Impl;
    int failed = 0;

    TRACE("Constructing ICreateTypeLib2 (%d, %s)\n", syskind, debugstr_w(szFile));

    pCreateTypeLib2Impl = heap_alloc_zero(sizeof(ICreateTypeLib2Impl));
    if (!pCreateTypeLib2Impl) return NULL;

    pCreateTypeLib2Impl->filename = heap_alloc((strlenW(szFile) + 1) * sizeof(WCHAR));
    if (!pCreateTypeLib2Impl->filename) {
	heap_free(pCreateTypeLib2Impl);
	return NULL;
    }
    strcpyW(pCreateTypeLib2Impl->filename, szFile);

    ctl2_init_header(pCreateTypeLib2Impl);
    ctl2_init_segdir(pCreateTypeLib2Impl);

    pCreateTypeLib2Impl->typelib_header.varflags |= syskind;

    /*
     * 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(pCreateTypeLib2Impl, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; }
    if (ctl2_alloc_segment(pCreateTypeLib2Impl, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; }

    pCreateTypeLib2Impl->typelib_guidhash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_GUIDHASH];
    pCreateTypeLib2Impl->typelib_namehash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_NAMEHASH];

    memset(pCreateTypeLib2Impl->typelib_guidhash_segment, 0xff, 0x80);
    memset(pCreateTypeLib2Impl->typelib_namehash_segment, 0xff, 0x200);

    pCreateTypeLib2Impl->lpVtbl = &ctypelib2vt;
    pCreateTypeLib2Impl->lpVtblTypeLib2 = &typelib2vt;
    pCreateTypeLib2Impl->ref = 1;

    if (failed) {
	ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)pCreateTypeLib2Impl);
	return 0;
    }

    return (ICreateTypeLib2 *)pCreateTypeLib2Impl;
}

/******************************************************************************
 * CreateTypeLib2 [OLEAUT32.180]
 *
 *  Obtains an ICreateTypeLib2 object for creating a new-style (MSFT) type
 *  library.
 *
 * NOTES
 *
 *  See also CreateTypeLib.
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: Status
 */
HRESULT WINAPI CreateTypeLib2(
	SYSKIND syskind,           /* [I] System type library is for */
	LPCOLESTR szFile,          /* [I] Type library file name */
	ICreateTypeLib2** ppctlib) /* [O] Storage for object returned */
{
    TRACE("(%d,%s,%p)\n", syskind, debugstr_w(szFile), ppctlib);

    if (!szFile) return E_INVALIDARG;
    *ppctlib = ICreateTypeLib2_Constructor(syskind, szFile);
    return (*ppctlib)? S_OK: E_OUTOFMEMORY;
}

/******************************************************************************
 * ClearCustData (OLEAUT32.171)
 *
 * Clear a custom data types' data.
 *
 * PARAMS
 *  lpCust [I] The custom data type instance
 *
 * RETURNS
 *  Nothing.
 */
void WINAPI ClearCustData(LPCUSTDATA lpCust)
{
    if (lpCust && lpCust->cCustData)
    {
        if (lpCust->prgCustData)
        {
            DWORD i;

            for (i = 0; i < lpCust->cCustData; i++)
                VariantClear(&lpCust->prgCustData[i].varValue);

            /* FIXME - Should be using a per-thread IMalloc */
            heap_free(lpCust->prgCustData);
            lpCust->prgCustData = NULL;
        }
        lpCust->cCustData = 0;
    }
}
