/*
 *	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
{
    ICreateTypeLib2 ICreateTypeLib2_iface;
    ITypeLib2 ITypeLib2_iface;
    LONG ref;

    BSTR 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_ICreateTypeLib2(ICreateTypeLib2 *iface)
{
    return CONTAINING_RECORD(iface, ICreateTypeLib2Impl, ICreateTypeLib2_iface);
}

static inline ICreateTypeLib2Impl *impl_from_ITypeLib2(ITypeLib2 *iface)
{
    return CONTAINING_RECORD(iface, ICreateTypeLib2Impl, ITypeLib2_iface);
}

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;
        /* fall through */
    case VT_I1:
    case VT_UI1:
    case VT_BOOL:
        if(!mask)
            mask = 0xff;
        /* fall through */
    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;
	    ITypeInfo_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(&This->typelib->ICreateTypeLib2_iface);

    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(&This->typelib->ICreateTypeLib2_iface);
            /* 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->ITypeLib2_iface) {
        /* 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 = ICreateTypeInfo2_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 = ICreateTypeInfo2_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 = ICreateTypeInfo2_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->ITypeLib2_iface,
                    -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;

                ITypeInfo_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->ITypeLib2_iface;
    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 = impl_from_ICreateTypeLib2(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->ITypeLib2_iface;
    }

    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 = impl_from_ICreateTypeLib2(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 = impl_from_ICreateTypeLib2(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;
	}

        SysFreeString(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 = impl_from_ICreateTypeLib2(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 = impl_from_ICreateTypeLib2(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 = impl_from_ICreateTypeLib2(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 = impl_from_ICreateTypeLib2(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 = impl_from_ICreateTypeLib2(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 = impl_from_ICreateTypeLib2(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 = impl_from_ICreateTypeLib2(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 = impl_from_ICreateTypeLib2(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 = impl_from_ICreateTypeLib2(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)) {
        TRACE("Writefile(%p, %d) failed, lasterror %d\n", segment, length, GetLastError());
        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 int 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;
        if (!ctl2_write_chunk(hFile, &iter->u.val, sizeof(int)))
            return 0;
        for(iter=iter->next; iter!=typeinfo->typedata->next; iter=iter->next)
            if (!ctl2_write_chunk(hFile, iter->u.data, ctl2_get_record_size(iter)))
                return 0;

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

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

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

/******************************************************************************
 * ICreateTypeLib2_SaveAllChanges {OLEAUT32}
 */
static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface)
{
    ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(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;

    if (!ctl2_write_typeinfos(This, hFile)) return retval;

    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 = impl_from_ICreateTypeLib2(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 = impl_from_ICreateTypeLib2(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 = impl_from_ICreateTypeLib2(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(&This->ICreateTypeLib2_iface, riid, ppv);
}

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

    return ICreateTypeLib2_AddRef(&This->ICreateTypeLib2_iface);
}

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

    return ICreateTypeLib2_Release(&This->ICreateTypeLib2_iface);
}

/******************************************************************************
 * 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 ITypeInfo2_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 filename)
{
    ICreateTypeLib2Impl *create_tlib2;
    int failed = 0;

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

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

    create_tlib2->filename = SysAllocString(filename);
    if (!create_tlib2->filename) {
	heap_free(create_tlib2);
	return NULL;
    }

    ctl2_init_header(create_tlib2);
    ctl2_init_segdir(create_tlib2);

    create_tlib2->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(create_tlib2, MSFT_SEG_GUIDHASH, 0x80, 0x80) == 0)
    {
        create_tlib2->typelib_guidhash_segment = (int *)create_tlib2->typelib_segment_data[MSFT_SEG_GUIDHASH];
        memset(create_tlib2->typelib_guidhash_segment, 0xff, 0x80);
    }
    else
        failed = 1;

    if (ctl2_alloc_segment(create_tlib2, MSFT_SEG_NAMEHASH, 0x200, 0x200) == 0)
    {
        create_tlib2->typelib_namehash_segment = (int *)create_tlib2->typelib_segment_data[MSFT_SEG_NAMEHASH];
        memset(create_tlib2->typelib_namehash_segment, 0xff, 0x200);        
    }
    else
        failed = 1;

    create_tlib2->ICreateTypeLib2_iface.lpVtbl = &ctypelib2vt;
    create_tlib2->ITypeLib2_iface.lpVtbl = &typelib2vt;
    create_tlib2->ref = 1;

    if (failed) {
        ICreateTypeLib2_fnRelease(&create_tlib2->ICreateTypeLib2_iface);
        heap_free(create_tlib2);
        return NULL;
    }

    return &create_tlib2->ICreateTypeLib2_iface;
}

/******************************************************************************
 * 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;
    }
}
