/*
 *	TYPELIB
 *
 *	Copyright 1997	Marcus Meissner
 *		      1999  Rein Klazes
 *		      2000  Francois Jacques
 *		      2001  Huw D M Davies for CodeWeavers
 *		      2004  Alastair Bridgewater
 *		      2005  Robert Shearman, for CodeWeavers
 *		      2013  Andrew Eikum for CodeWeavers
 *
 * 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 (2000, Francois Jacques)
 *
 * - Tested using OLEVIEW (Platform SDK tool) only.
 *
 * - dual interface dispinterfaces. vtable-interface ITypeInfo instances are
 *   creating by doing a straight copy of the dispinterface instance and just changing
 *   its typekind. Pointed structures aren't copied - only the address of the pointers.
 *
 * - locale stuff is partially implemented but hasn't been tested.
 *
 * - typelib file is still read in its entirety, but it is released now.
 *
 * --------------------------------------------------------------------------------------
 *  Known problems left from previous implementation (1999, Rein Klazes) :
 *
 * -. Data structures are straightforward, but slow for look-ups.
 * -. (related) nothing is hashed
 * -. Most error return values are just guessed not checked with windows
 *      behaviour.
 * -. lousy fatal error handling
 *
 */

#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

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

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

WINE_DEFAULT_DEBUG_CHANNEL(ole);
WINE_DECLARE_DEBUG_CHANNEL(typelib);

typedef struct
{
    WORD     offset;
    WORD     length;
    WORD     flags;
    WORD     id;
    WORD     handle;
    WORD     usage;
} NE_NAMEINFO;

typedef struct
{
    WORD        type_id;   /* Type identifier */
    WORD        count;     /* Number of resources of this type */
    DWORD       resloader; /* SetResourceHandler() */
    /*
     * Name info array.
     */
} NE_TYPEINFO;

static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt);
static HRESULT TLB_AllocAndInitVarDesc(const VARDESC *src, VARDESC **dest_ptr);
static void TLB_FreeVarDesc(VARDESC*);

/****************************************************************************
 *              FromLExxx
 *
 * Takes p_iVal (which is in little endian) and returns it
 *   in the host machine's byte order.
 */
#ifdef WORDS_BIGENDIAN
static WORD FromLEWord(WORD p_iVal)
{
  return (((p_iVal & 0x00FF) << 8) |
	  ((p_iVal & 0xFF00) >> 8));
}


static DWORD FromLEDWord(DWORD p_iVal)
{
  return (((p_iVal & 0x000000FF) << 24) |
	  ((p_iVal & 0x0000FF00) <<  8) |
	  ((p_iVal & 0x00FF0000) >>  8) |
	  ((p_iVal & 0xFF000000) >> 24));
}
#else
#define FromLEWord(X)  (X)
#define FromLEDWord(X) (X)
#endif

#define DISPATCH_HREF_OFFSET 0x01000000
#define DISPATCH_HREF_MASK   0xff000000

/****************************************************************************
 *              FromLExxx
 *
 * Fix byte order in any structure if necessary
 */
#ifdef WORDS_BIGENDIAN
static void FromLEWords(void *p_Val, int p_iSize)
{
  WORD *Val = p_Val;

  p_iSize /= sizeof(WORD);

  while (p_iSize) {
    *Val = FromLEWord(*Val);
    Val++;
    p_iSize--;
  }
}


static void FromLEDWords(void *p_Val, int p_iSize)
{
  DWORD *Val = p_Val;

  p_iSize /= sizeof(DWORD);

  while (p_iSize) {
    *Val = FromLEDWord(*Val);
    Val++;
    p_iSize--;
  }
}
#else
#define FromLEWords(X,Y) /*nothing*/
#define FromLEDWords(X,Y) /*nothing*/
#endif

/*
 * Find a typelib key which matches a requested maj.min version.
 */
static BOOL find_typelib_key( REFGUID guid, WORD *wMaj, WORD *wMin )
{
    static const WCHAR typelibW[] = {'T','y','p','e','l','i','b','\\',0};
    WCHAR buffer[60];
    char key_name[16];
    DWORD len, i;
    INT best_maj = -1, best_min = -1;
    HKEY hkey;

    memcpy( buffer, typelibW, sizeof(typelibW) );
    StringFromGUID2( guid, buffer + strlenW(buffer), 40 );

    if (RegOpenKeyExW( HKEY_CLASSES_ROOT, buffer, 0, KEY_READ, &hkey ) != ERROR_SUCCESS)
        return FALSE;

    len = sizeof(key_name);
    i = 0;
    while (RegEnumKeyExA(hkey, i++, key_name, &len, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
    {
        INT v_maj, v_min;

        if (sscanf(key_name, "%x.%x", &v_maj, &v_min) == 2)
        {
            TRACE("found %s: %x.%x\n", debugstr_w(buffer), v_maj, v_min);

            if (*wMaj == 0xffff && *wMin == 0xffff)
            {
                if (v_maj > best_maj) best_maj = v_maj;
                if (v_min > best_min) best_min = v_min;
            }
            else if (*wMaj == v_maj)
            {
                best_maj = v_maj;

                if (*wMin == v_min)
                {
                    best_min = v_min;
                    break; /* exact match */
                }
                if (*wMin != 0xffff && v_min > best_min) best_min = v_min;
            }
        }
        len = sizeof(key_name);
    }
    RegCloseKey( hkey );

    TRACE("found best_maj %d, best_min %d\n", best_maj, best_min);

    if (*wMaj == 0xffff && *wMin == 0xffff)
    {
        if (best_maj >= 0 && best_min >= 0)
        {
            *wMaj = best_maj;
            *wMin = best_min;
            return TRUE;
        }
    }

    if (*wMaj == best_maj && best_min >= 0)
    {
        *wMin = best_min;
        return TRUE;
    }
    return FALSE;
}

/* get the path of a typelib key, in the form "Typelib\\<guid>\\<maj>.<min>" */
/* buffer must be at least 60 characters long */
static WCHAR *get_typelib_key( REFGUID guid, WORD wMaj, WORD wMin, WCHAR *buffer )
{
    static const WCHAR TypelibW[] = {'T','y','p','e','l','i','b','\\',0};
    static const WCHAR VersionFormatW[] = {'\\','%','x','.','%','x',0};

    memcpy( buffer, TypelibW, sizeof(TypelibW) );
    StringFromGUID2( guid, buffer + strlenW(buffer), 40 );
    sprintfW( buffer + strlenW(buffer), VersionFormatW, wMaj, wMin );
    return buffer;
}

/* get the path of an interface key, in the form "Interface\\<guid>" */
/* buffer must be at least 50 characters long */
static WCHAR *get_interface_key( REFGUID guid, WCHAR *buffer )
{
    static const WCHAR InterfaceW[] = {'I','n','t','e','r','f','a','c','e','\\',0};

    memcpy( buffer, InterfaceW, sizeof(InterfaceW) );
    StringFromGUID2( guid, buffer + strlenW(buffer), 40 );
    return buffer;
}

/* get the lcid subkey for a typelib, in the form "<lcid>\\<syskind>" */
/* buffer must be at least 16 characters long */
static WCHAR *get_lcid_subkey( LCID lcid, SYSKIND syskind, WCHAR *buffer )
{
    static const WCHAR LcidFormatW[] = {'%','l','x','\\',0};
    static const WCHAR win16W[] = {'w','i','n','1','6',0};
    static const WCHAR win32W[] = {'w','i','n','3','2',0};
    static const WCHAR win64W[] = {'w','i','n','6','4',0};

    sprintfW( buffer, LcidFormatW, lcid );
    switch(syskind)
    {
    case SYS_WIN16: strcatW( buffer, win16W ); break;
    case SYS_WIN32: strcatW( buffer, win32W ); break;
    case SYS_WIN64: strcatW( buffer, win64W ); break;
    default:
        TRACE("Typelib is for unsupported syskind %i\n", syskind);
        return NULL;
    }
    return buffer;
}

static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib);

struct tlibredirect_data
{
    ULONG  size;
    DWORD  res;
    ULONG  name_len;
    ULONG  name_offset;
    LANGID langid;
    WORD   flags;
    ULONG  help_len;
    ULONG  help_offset;
    WORD   major_version;
    WORD   minor_version;
};

/* Get the path to a registered type library. Helper for QueryPathOfRegTypeLib. */
static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin,
                                   SYSKIND syskind, LCID lcid, BSTR *path, BOOL redir )
{
    HRESULT hr = TYPE_E_LIBNOTREGISTERED;
    LCID myLCID = lcid;
    HKEY hkey;
    WCHAR buffer[60];
    WCHAR Path[MAX_PATH];
    LONG res;

    TRACE_(typelib)("(%s, %x.%x, 0x%x, %p)\n", debugstr_guid(guid), wMaj, wMin, lcid, path);

    if (redir)
    {
        ACTCTX_SECTION_KEYED_DATA data;

        data.cbSize = sizeof(data);
        if (FindActCtxSectionGuid( 0, NULL, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION, guid, &data ))
        {
            struct tlibredirect_data *tlib = (struct tlibredirect_data*)data.lpData;
            WCHAR *nameW;
            DWORD len;

            if ((wMaj != 0xffff || wMin != 0xffff) && (tlib->major_version != wMaj || tlib->minor_version < wMin))
                return TYPE_E_LIBNOTREGISTERED;

            nameW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset);
            len = SearchPathW( NULL, nameW, NULL, sizeof(Path)/sizeof(WCHAR), Path, NULL );
            if (!len) return TYPE_E_LIBNOTREGISTERED;

            TRACE_(typelib)("got path from context %s\n", debugstr_w(Path));
            *path = SysAllocString( Path );
            return S_OK;
        }
    }

    if (!find_typelib_key( guid, &wMaj, &wMin )) return TYPE_E_LIBNOTREGISTERED;
    get_typelib_key( guid, wMaj, wMin, buffer );

    res = RegOpenKeyExW( HKEY_CLASSES_ROOT, buffer, 0, KEY_READ, &hkey );
    if (res == ERROR_FILE_NOT_FOUND)
    {
        TRACE_(typelib)("%s not found\n", debugstr_w(buffer));
        return TYPE_E_LIBNOTREGISTERED;
    }
    else if (res != ERROR_SUCCESS)
    {
        TRACE_(typelib)("failed to open %s for read access\n", debugstr_w(buffer));
        return TYPE_E_REGISTRYACCESS;
    }

    while (hr != S_OK)
    {
        LONG dwPathLen = sizeof(Path);

        get_lcid_subkey( myLCID, syskind, buffer );

        if (RegQueryValueW(hkey, buffer, Path, &dwPathLen))
        {
            if (!lcid)
                break;
            else if (myLCID == lcid)
            {
                /* try with sub-langid */
                myLCID = SUBLANGID(lcid);
            }
            else if ((myLCID == SUBLANGID(lcid)) && myLCID)
            {
                /* try with system langid */
                myLCID = 0;
            }
            else
            {
                break;
            }
        }
        else
        {
            *path = SysAllocString( Path );
            hr = S_OK;
        }
    }
    RegCloseKey( hkey );
    TRACE_(typelib)("-- 0x%08x\n", hr);
    return hr;
}

/****************************************************************************
 *		QueryPathOfRegTypeLib	[OLEAUT32.164]
 *
 * Gets the path to a registered type library.
 *
 * PARAMS
 *  guid [I] referenced guid
 *  wMaj [I] major version
 *  wMin [I] minor version
 *  lcid [I] locale id
 *  path [O] path of typelib
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: If the type library is not registered then TYPE_E_LIBNOTREGISTERED
 *  or TYPE_E_REGISTRYACCESS if the type library registration key couldn't be
 *  opened.
 */
HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD wMaj, WORD wMin, LCID lcid, LPBSTR path )
{
    BOOL redir = TRUE;
#ifdef _WIN64
    HRESULT hres = query_typelib_path( guid, wMaj, wMin, SYS_WIN64, lcid, path, TRUE );
    if(SUCCEEDED(hres))
        return hres;
    redir = FALSE;
#endif
    return query_typelib_path( guid, wMaj, wMin, SYS_WIN32, lcid, path, redir );
}

/******************************************************************************
 * CreateTypeLib [OLEAUT32.160]  creates a typelib
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: Status
 */
HRESULT WINAPI CreateTypeLib(
	SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib** ppctlib
) {
    FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib);
    return E_FAIL;
}

/******************************************************************************
 *		LoadTypeLib	[OLEAUT32.161]
 *
 * Loads a type library
 *
 * PARAMS
 *  szFile [I] Name of file to load from.
 *  pptLib [O] Pointer that receives ITypeLib object on success.
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: Status
 *
 * SEE
 *  LoadTypeLibEx, LoadRegTypeLib, CreateTypeLib.
 */
HRESULT WINAPI LoadTypeLib(const OLECHAR *szFile, ITypeLib * *pptLib)
{
    TRACE("(%s,%p)\n",debugstr_w(szFile), pptLib);
    return LoadTypeLibEx(szFile, REGKIND_DEFAULT, pptLib);
}

/******************************************************************************
 *		LoadTypeLibEx	[OLEAUT32.183]
 *
 * Loads and optionally registers a type library
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: Status
 */
HRESULT WINAPI LoadTypeLibEx(
    LPCOLESTR szFile,  /* [in] Name of file to load from */
    REGKIND  regkind,  /* [in] Specify kind of registration */
    ITypeLib **pptLib) /* [out] Pointer to pointer to loaded type library */
{
    WCHAR szPath[MAX_PATH+1];
    HRESULT res;

    TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib);

    if (!szFile || !pptLib)
        return E_INVALIDARG;

    *pptLib = NULL;

    res = TLB_ReadTypeLib(szFile, szPath, MAX_PATH + 1, (ITypeLib2**)pptLib);

    if (SUCCEEDED(res))
        switch(regkind)
        {
            case REGKIND_DEFAULT:
                /* don't register typelibs supplied with full path. Experimentation confirms the following */
                if (((szFile[0] == '\\') && (szFile[1] == '\\')) ||
                    (szFile[0] && (szFile[1] == ':'))) break;
                /* else fall-through */

            case REGKIND_REGISTER:
                if (FAILED(res = RegisterTypeLib(*pptLib, szPath, NULL)))
                {
                    ITypeLib_Release(*pptLib);
                    *pptLib = 0;
                }
                break;
            case REGKIND_NONE:
                break;
        }

    TRACE(" returns %08x\n",res);
    return res;
}

/******************************************************************************
 *		LoadRegTypeLib	[OLEAUT32.162]
 *
 * Loads a registered type library.
 *
 * PARAMS
 *  rguid     [I] GUID of the registered type library.
 *  wVerMajor [I] major version.
 *  wVerMinor [I] minor version.
 *  lcid      [I] locale ID.
 *  ppTLib    [O] pointer that receives an ITypeLib object on success.
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: Any HRESULT code returned from QueryPathOfRegTypeLib or
 *  LoadTypeLib.
 */
HRESULT WINAPI LoadRegTypeLib(
	REFGUID rguid,
	WORD wVerMajor,
	WORD wVerMinor,
	LCID lcid,
	ITypeLib **ppTLib)
{
    BSTR bstr=NULL;
    HRESULT res;

    *ppTLib = NULL;

    res = QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor, lcid, &bstr);

    if(SUCCEEDED(res))
    {
        res= LoadTypeLib(bstr, ppTLib);
        SysFreeString(bstr);

        if ((wVerMajor!=0xffff || wVerMinor!=0xffff) && *ppTLib)
        {
            TLIBATTR *attr;

            res = ITypeLib_GetLibAttr(*ppTLib, &attr);
            if (res == S_OK)
            {
                BOOL mismatch = attr->wMajorVerNum != wVerMajor || attr->wMinorVerNum < wVerMinor;
                ITypeLib_ReleaseTLibAttr(*ppTLib, attr);

                if (mismatch)
                {
                    ITypeLib_Release(*ppTLib);
                    *ppTLib = NULL;
                    res = TYPE_E_LIBNOTREGISTERED;
                }
            }
        }
    }

    TRACE("(IID: %s) load %s (%p)\n",debugstr_guid(rguid), SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);

    return res;
}


/* some string constants shared between RegisterTypeLib and UnRegisterTypeLib */
static const WCHAR TypeLibW[] = {'T','y','p','e','L','i','b',0};
static const WCHAR FLAGSW[] = {'F','L','A','G','S',0};
static const WCHAR HELPDIRW[] = {'H','E','L','P','D','I','R',0};
static const WCHAR ProxyStubClsidW[] = {'P','r','o','x','y','S','t','u','b','C','l','s','i','d',0};
static const WCHAR ProxyStubClsid32W[] = {'P','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0};

static void TLB_register_interface(TLIBATTR *libattr, LPOLESTR name, TYPEATTR *tattr, DWORD flag)
{
    WCHAR keyName[60];
    HKEY key, subKey;

    static const WCHAR PSOA[] = {'{','0','0','0','2','0','4','2','4','-',
                                 '0','0','0','0','-','0','0','0','0','-','C','0','0','0','-',
                                 '0','0','0','0','0','0','0','0','0','0','4','6','}',0};

    get_interface_key( &tattr->guid, keyName );
    if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
                        KEY_WRITE | flag, NULL, &key, NULL) == ERROR_SUCCESS)
    {
        if (name)
            RegSetValueExW(key, NULL, 0, REG_SZ,
                           (BYTE *)name, (strlenW(name)+1) * sizeof(OLECHAR));

        if (RegCreateKeyExW(key, ProxyStubClsidW, 0, NULL, 0,
            KEY_WRITE | flag, NULL, &subKey, NULL) == ERROR_SUCCESS) {
            RegSetValueExW(subKey, NULL, 0, REG_SZ,
                           (const BYTE *)PSOA, sizeof PSOA);
            RegCloseKey(subKey);
        }

        if (RegCreateKeyExW(key, ProxyStubClsid32W, 0, NULL, 0,
            KEY_WRITE | flag, NULL, &subKey, NULL) == ERROR_SUCCESS) {
            RegSetValueExW(subKey, NULL, 0, REG_SZ,
                           (const BYTE *)PSOA, sizeof PSOA);
            RegCloseKey(subKey);
        }

        if (RegCreateKeyExW(key, TypeLibW, 0, NULL, 0,
            KEY_WRITE | flag, NULL, &subKey, NULL) == ERROR_SUCCESS)
        {
            WCHAR buffer[40];
            static const WCHAR fmtver[] = {'%','x','.','%','x',0 };
            static const WCHAR VersionW[] = {'V','e','r','s','i','o','n',0};

            StringFromGUID2(&libattr->guid, buffer, 40);
            RegSetValueExW(subKey, NULL, 0, REG_SZ,
                           (BYTE *)buffer, (strlenW(buffer)+1) * sizeof(WCHAR));
            sprintfW(buffer, fmtver, libattr->wMajorVerNum, libattr->wMinorVerNum);
            RegSetValueExW(subKey, VersionW, 0, REG_SZ,
                           (BYTE*)buffer, (strlenW(buffer)+1) * sizeof(WCHAR));
            RegCloseKey(subKey);
        }

        RegCloseKey(key);
    }
}

/******************************************************************************
 *		RegisterTypeLib	[OLEAUT32.163]
 * Adds information about a type library to the System Registry
 * NOTES
 *    Docs: ITypeLib FAR * ptlib
 *    Docs: OLECHAR FAR* szFullPath
 *    Docs: OLECHAR FAR* szHelpDir
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: Status
 */
HRESULT WINAPI RegisterTypeLib(
     ITypeLib * ptlib,     /* [in] Pointer to the library*/
     OLECHAR * szFullPath, /* [in] full Path of the library*/
     OLECHAR * szHelpDir)  /* [in] dir to the helpfile for the library,
							 may be NULL*/
{
    HRESULT res;
    TLIBATTR *attr;
    WCHAR keyName[60];
    WCHAR tmp[16];
    HKEY key, subKey;
    UINT types, tidx;
    TYPEKIND kind;
    DWORD disposition;

    if (ptlib == NULL || szFullPath == NULL)
        return E_INVALIDARG;

    if (FAILED(ITypeLib_GetLibAttr(ptlib, &attr)))
        return E_FAIL;

#ifndef _WIN64
    if (attr->syskind == SYS_WIN64) return TYPE_E_BADMODULEKIND;
#endif

    get_typelib_key( &attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, keyName );

    res = S_OK;
    if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
        KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS)
    {
        LPOLESTR doc;

        /* Set the human-readable name of the typelib */
        if (FAILED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL)))
            res = E_FAIL;
        else if (doc)
        {
            if (RegSetValueExW(key, NULL, 0, REG_SZ,
                (BYTE *)doc, (lstrlenW(doc)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS)
                res = E_FAIL;

            SysFreeString(doc);
        }

        /* Make up the name of the typelib path subkey */
        if (!get_lcid_subkey( attr->lcid, attr->syskind, tmp )) res = E_FAIL;

        /* Create the typelib path subkey */
        if (res == S_OK && RegCreateKeyExW(key, tmp, 0, NULL, 0,
            KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
        {
            if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
                (BYTE *)szFullPath, (lstrlenW(szFullPath)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS)
                res = E_FAIL;

            RegCloseKey(subKey);
        }
        else
            res = E_FAIL;

        /* Create the flags subkey */
        if (res == S_OK && RegCreateKeyExW(key, FLAGSW, 0, NULL, 0,
            KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
        {
            /* FIXME: is %u correct? */
            static const WCHAR formatW[] = {'%','u',0};
            WCHAR buf[20];
            sprintfW(buf, formatW, attr->wLibFlags);
            if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
                               (BYTE *)buf, (strlenW(buf) + 1)*sizeof(WCHAR) ) != ERROR_SUCCESS)
                res = E_FAIL;

            RegCloseKey(subKey);
        }
        else
            res = E_FAIL;

        /* create the helpdir subkey */
        if (res == S_OK && RegCreateKeyExW(key, HELPDIRW, 0, NULL, 0,
            KEY_WRITE, NULL, &subKey, &disposition) == ERROR_SUCCESS)
        {
            BOOL freeHelpDir = FALSE;
            OLECHAR* pIndexStr;

            /* if we created a new key, and helpDir was null, set the helpdir
               to the directory which contains the typelib. However,
               if we just opened an existing key, we leave the helpdir alone */
            if ((disposition == REG_CREATED_NEW_KEY) && (szHelpDir == NULL)) {
                szHelpDir = SysAllocString(szFullPath);
                pIndexStr = strrchrW(szHelpDir, '\\');
                if (pIndexStr) {
                    *pIndexStr = 0;
                }
                freeHelpDir = TRUE;
            }

            /* if we have an szHelpDir, set it! */
            if (szHelpDir != NULL) {
                if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
                    (BYTE *)szHelpDir, (lstrlenW(szHelpDir)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS) {
                    res = E_FAIL;
                }
            }

            /* tidy up */
            if (freeHelpDir) SysFreeString(szHelpDir);
            RegCloseKey(subKey);

        } else {
            res = E_FAIL;
        }

        RegCloseKey(key);
    }
    else
        res = E_FAIL;

    /* register OLE Automation-compatible interfaces for this typelib */
    types = ITypeLib_GetTypeInfoCount(ptlib);
    for (tidx=0; tidx<types; tidx++) {
	if (SUCCEEDED(ITypeLib_GetTypeInfoType(ptlib, tidx, &kind))) {
	    LPOLESTR name = NULL;
	    ITypeInfo *tinfo = NULL;

	    ITypeLib_GetDocumentation(ptlib, tidx, &name, NULL, NULL, NULL);

	    switch (kind) {
	    case TKIND_INTERFACE:
		TRACE_(typelib)("%d: interface %s\n", tidx, debugstr_w(name));
		ITypeLib_GetTypeInfo(ptlib, tidx, &tinfo);
		break;

	    case TKIND_DISPATCH:
		TRACE_(typelib)("%d: dispinterface %s\n", tidx, debugstr_w(name));
                ITypeLib_GetTypeInfo(ptlib, tidx, &tinfo);
		break;

	    default:
		TRACE_(typelib)("%d: %s\n", tidx, debugstr_w(name));
		break;
	    }

	    if (tinfo) {
		TYPEATTR *tattr = NULL;
		ITypeInfo_GetTypeAttr(tinfo, &tattr);

		if (tattr) {
		    TRACE_(typelib)("guid=%s, flags=%04x (",
				    debugstr_guid(&tattr->guid),
				    tattr->wTypeFlags);

		    if (TRACE_ON(typelib)) {
#define XX(x) if (TYPEFLAG_##x & tattr->wTypeFlags) MESSAGE(#x"|");
			XX(FAPPOBJECT);
			XX(FCANCREATE);
			XX(FLICENSED);
			XX(FPREDECLID);
			XX(FHIDDEN);
			XX(FCONTROL);
			XX(FDUAL);
			XX(FNONEXTENSIBLE);
			XX(FOLEAUTOMATION);
			XX(FRESTRICTED);
			XX(FAGGREGATABLE);
			XX(FREPLACEABLE);
			XX(FDISPATCHABLE);
			XX(FREVERSEBIND);
			XX(FPROXY);
#undef XX
			MESSAGE("\n");
		    }

                    /* Register all dispinterfaces (which includes dual interfaces) and
                       oleautomation interfaces */
		    if ((kind == TKIND_INTERFACE && (tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) ||
                        kind == TKIND_DISPATCH)
		    {
                        BOOL is_wow64;
                        DWORD opposite = (sizeof(void*) == 8 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY);

                        /* register interface<->typelib coupling */
                        TLB_register_interface(attr, name, tattr, 0);

                        /* register TLBs into the opposite registry view, too */
                        if(opposite == KEY_WOW64_32KEY ||
                                 (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64))
                            TLB_register_interface(attr, name, tattr, opposite);
		    }

		    ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
		}

		ITypeInfo_Release(tinfo);
	    }

	    SysFreeString(name);
	}
    }

    ITypeLib_ReleaseTLibAttr(ptlib, attr);

    return res;
}

static void TLB_unregister_interface(GUID *guid, REGSAM flag)
{
    WCHAR subKeyName[50];
    HKEY subKey;

    /* the path to the type */
    get_interface_key( guid, subKeyName );

    /* Delete its bits */
    if (RegOpenKeyExW(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE | flag, &subKey) != ERROR_SUCCESS)
        return;

    RegDeleteKeyW(subKey, ProxyStubClsidW);
    RegDeleteKeyW(subKey, ProxyStubClsid32W);
    RegDeleteKeyW(subKey, TypeLibW);
    RegCloseKey(subKey);
    RegDeleteKeyExW(HKEY_CLASSES_ROOT, subKeyName, flag, 0);
}

/******************************************************************************
 *	UnRegisterTypeLib	[OLEAUT32.186]
 * Removes information about a type library from the System Registry
 * NOTES
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: Status
 */
HRESULT WINAPI UnRegisterTypeLib(
    REFGUID libid,	/* [in] Guid of the library */
	WORD wVerMajor,	/* [in] major version */
	WORD wVerMinor,	/* [in] minor version */
	LCID lcid,	/* [in] locale id */
	SYSKIND syskind)
{
    BSTR tlibPath = NULL;
    DWORD tmpLength;
    WCHAR keyName[60];
    WCHAR subKeyName[50];
    int result = S_OK;
    DWORD i = 0;
    BOOL deleteOtherStuff;
    HKEY key = NULL;
    TYPEATTR* typeAttr = NULL;
    TYPEKIND kind;
    ITypeInfo* typeInfo = NULL;
    ITypeLib* typeLib = NULL;
    int numTypes;

    TRACE("(IID: %s)\n",debugstr_guid(libid));

    /* Create the path to the key */
    get_typelib_key( libid, wVerMajor, wVerMinor, keyName );

    if (syskind != SYS_WIN16 && syskind != SYS_WIN32 && syskind != SYS_WIN64)
    {
        TRACE("Unsupported syskind %i\n", syskind);
        result = E_INVALIDARG;
        goto end;
    }

    /* get the path to the typelib on disk */
    if (query_typelib_path(libid, wVerMajor, wVerMinor, syskind, lcid, &tlibPath, FALSE) != S_OK) {
        result = E_INVALIDARG;
        goto end;
    }

    /* Try and open the key to the type library. */
    if (RegOpenKeyExW(HKEY_CLASSES_ROOT, keyName, 0, KEY_READ | KEY_WRITE, &key) != ERROR_SUCCESS) {
        result = E_INVALIDARG;
        goto end;
    }

    /* Try and load the type library */
    if (LoadTypeLibEx(tlibPath, REGKIND_NONE, &typeLib) != S_OK) {
        result = TYPE_E_INVALIDSTATE;
        goto end;
    }

    /* remove any types registered with this typelib */
    numTypes = ITypeLib_GetTypeInfoCount(typeLib);
    for (i=0; i<numTypes; i++) {
        /* get the kind of type */
        if (ITypeLib_GetTypeInfoType(typeLib, i, &kind) != S_OK) {
            goto enddeleteloop;
        }

        /* skip non-interfaces, and get type info for the type */
        if ((kind != TKIND_INTERFACE) && (kind != TKIND_DISPATCH)) {
            goto enddeleteloop;
        }
        if (ITypeLib_GetTypeInfo(typeLib, i, &typeInfo) != S_OK) {
            goto enddeleteloop;
        }
        if (ITypeInfo_GetTypeAttr(typeInfo, &typeAttr) != S_OK) {
            goto enddeleteloop;
        }

        if ((kind == TKIND_INTERFACE && (typeAttr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) ||
            kind == TKIND_DISPATCH)
        {
            BOOL is_wow64;
            REGSAM opposite = (sizeof(void*) == 8 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY);

            TLB_unregister_interface(&typeAttr->guid, 0);

            /* unregister TLBs into the opposite registry view, too */
            if(opposite == KEY_WOW64_32KEY ||
               (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)) {
                TLB_unregister_interface(&typeAttr->guid, opposite);
            }
        }

enddeleteloop:
        if (typeAttr) ITypeInfo_ReleaseTypeAttr(typeInfo, typeAttr);
        typeAttr = NULL;
        if (typeInfo) ITypeInfo_Release(typeInfo);
        typeInfo = NULL;
    }

    /* Now, delete the type library path subkey */
    get_lcid_subkey( lcid, syskind, subKeyName );
    RegDeleteKeyW(key, subKeyName);
    *strrchrW( subKeyName, '\\' ) = 0;  /* remove last path component */
    RegDeleteKeyW(key, subKeyName);

    /* check if there is anything besides the FLAGS/HELPDIR keys.
       If there is, we don't delete them */
    tmpLength = sizeof(subKeyName)/sizeof(WCHAR);
    deleteOtherStuff = TRUE;
    i = 0;
    while(RegEnumKeyExW(key, i++, subKeyName, &tmpLength, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
        tmpLength = sizeof(subKeyName)/sizeof(WCHAR);

        /* if its not FLAGS or HELPDIR, then we must keep the rest of the key */
        if (!strcmpW(subKeyName, FLAGSW)) continue;
        if (!strcmpW(subKeyName, HELPDIRW)) continue;
        deleteOtherStuff = FALSE;
        break;
    }

    /* only delete the other parts of the key if we're absolutely sure */
    if (deleteOtherStuff) {
        RegDeleteKeyW(key, FLAGSW);
        RegDeleteKeyW(key, HELPDIRW);
        RegCloseKey(key);
        key = NULL;

        RegDeleteKeyW(HKEY_CLASSES_ROOT, keyName);
        *strrchrW( keyName, '\\' ) = 0;  /* remove last path component */
        RegDeleteKeyW(HKEY_CLASSES_ROOT, keyName);
    }

end:
    SysFreeString(tlibPath);
    if (typeLib) ITypeLib_Release(typeLib);
    if (key) RegCloseKey(key);
    return result;
}

/******************************************************************************
 *		RegisterTypeLibForUser	[OLEAUT32.442]
 * Adds information about a type library to the user registry
 * NOTES
 *    Docs: ITypeLib FAR * ptlib
 *    Docs: OLECHAR FAR* szFullPath
 *    Docs: OLECHAR FAR* szHelpDir
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: Status
 */
HRESULT WINAPI RegisterTypeLibForUser(
     ITypeLib * ptlib,     /* [in] Pointer to the library*/
     OLECHAR * szFullPath, /* [in] full Path of the library*/
     OLECHAR * szHelpDir)  /* [in] dir to the helpfile for the library,
							 may be NULL*/
{
    FIXME("(%p, %s, %s) registering the typelib system-wide\n", ptlib,
          debugstr_w(szFullPath), debugstr_w(szHelpDir));
    return RegisterTypeLib(ptlib, szFullPath, szHelpDir);
}

/******************************************************************************
 *	UnRegisterTypeLibForUser	[OLEAUT32.443]
 * Removes information about a type library from the user registry
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: Status
 */
HRESULT WINAPI UnRegisterTypeLibForUser(
    REFGUID libid,	/* [in] GUID of the library */
    WORD wVerMajor,	/* [in] major version */
    WORD wVerMinor,	/* [in] minor version */
    LCID lcid,	/* [in] locale id */
    SYSKIND syskind)
{
    FIXME("(%s, %u, %u, %u, %u) unregistering the typelib system-wide\n",
          debugstr_guid(libid), wVerMajor, wVerMinor, lcid, syskind);
    return UnRegisterTypeLib(libid, wVerMajor, wVerMinor, lcid, syskind);
}

/*======================= ITypeLib implementation =======================*/

typedef struct tagTLBGuid {
    GUID guid;
    INT hreftype;
    UINT offset;
    struct list entry;
} TLBGuid;

typedef struct tagTLBCustData
{
    TLBGuid *guid;
    VARIANT data;
    struct list entry;
} TLBCustData;

/* data structure for import typelibs */
typedef struct tagTLBImpLib
{
    int offset;                 /* offset in the file (MSFT)
				   offset in nametable (SLTG)
				   just used to identify library while reading
				   data from file */
    TLBGuid *guid;                  /* libid */
    BSTR name;                  /* name */

    LCID lcid;                  /* lcid of imported typelib */

    WORD wVersionMajor;         /* major version number */
    WORD wVersionMinor;         /* minor version number */

    struct tagITypeLibImpl *pImpTypeLib; /* pointer to loaded typelib, or
					    NULL if not yet loaded */
    struct list entry;
} TLBImpLib;

typedef struct tagTLBString {
    BSTR str;
    UINT offset;
    struct list entry;
} TLBString;

/* internal ITypeLib data */
typedef struct tagITypeLibImpl
{
    ITypeLib2 ITypeLib2_iface;
    ITypeComp ITypeComp_iface;
    ICreateTypeLib2 ICreateTypeLib2_iface;
    LONG ref;
    TLBGuid *guid;
    LCID lcid;
    SYSKIND syskind;
    int ptr_size;
    WORD ver_major;
    WORD ver_minor;
    WORD libflags;
    LCID set_lcid;

    /* strings can be stored in tlb as multibyte strings BUT they are *always*
     * exported to the application as a UNICODE string.
     */
    struct list string_list;
    struct list name_list;
    struct list guid_list;

    const TLBString *Name;
    const TLBString *DocString;
    const TLBString *HelpFile;
    const TLBString *HelpStringDll;
    DWORD dwHelpContext;
    int TypeInfoCount;          /* nr of typeinfo's in librarry */
    struct tagITypeInfoImpl **typeinfos;
    struct list custdata_list;
    struct list implib_list;
    int ctTypeDesc;             /* number of items in type desc array */
    TYPEDESC * pTypeDesc;       /* array of TypeDescriptions found in the
				   library. Only used while reading MSFT
				   typelibs */
    struct list ref_list;       /* list of ref types in this typelib */
    HREFTYPE dispatch_href;     /* reference to IDispatch, -1 if unused */


    /* typelibs are cached, keyed by path and index, so store the linked list info within them */
    struct list entry;
    WCHAR *path;
    INT index;
} ITypeLibImpl;

static const ITypeLib2Vtbl tlbvt;
static const ITypeCompVtbl tlbtcvt;
static const ICreateTypeLib2Vtbl CreateTypeLib2Vtbl;

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

static inline ITypeLibImpl *impl_from_ITypeLib(ITypeLib *iface)
{
    return impl_from_ITypeLib2((ITypeLib2*)iface);
}

static inline ITypeLibImpl *impl_from_ITypeComp( ITypeComp *iface )
{
    return CONTAINING_RECORD(iface, ITypeLibImpl, ITypeComp_iface);
}

static inline ITypeLibImpl *impl_from_ICreateTypeLib2( ICreateTypeLib2 *iface )
{
    return CONTAINING_RECORD(iface, ITypeLibImpl, ICreateTypeLib2_iface);
}

/* ITypeLib methods */
static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength);
static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength);

/*======================= ITypeInfo implementation =======================*/

/* data for referenced types */
typedef struct tagTLBRefType
{
    INT index;              /* Type index for internal ref or for external ref
			       it the format is SLTG.  -2 indicates to
			       use guid */

    TYPEKIND tkind;
    TLBGuid *guid;              /* guid of the referenced type */
                            /* if index == TLB_REF_USE_GUID */

    HREFTYPE reference;     /* The href of this ref */
    TLBImpLib *pImpTLInfo;  /* If ref is external ptr to library data
			       TLB_REF_INTERNAL for internal refs
			       TLB_REF_NOT_FOUND for broken refs */

    struct list entry;
} TLBRefType;

#define TLB_REF_USE_GUID -2

#define TLB_REF_INTERNAL (void*)-2
#define TLB_REF_NOT_FOUND (void*)-1

/* internal Parameter data */
typedef struct tagTLBParDesc
{
    const TLBString *Name;
    struct list custdata_list;
} TLBParDesc;

/* internal Function data */
typedef struct tagTLBFuncDesc
{
    FUNCDESC funcdesc;      /* lots of info on the function and its attributes. */
    const TLBString *Name;             /* the name of this function */
    TLBParDesc *pParamDesc; /* array with param names and custom data */
    int helpcontext;
    int HelpStringContext;
    const TLBString *HelpString;
    const TLBString *Entry;            /* if IS_INTRESOURCE true, it's numeric; if -1 it isn't present */
    struct list custdata_list;
} TLBFuncDesc;

/* internal Variable data */
typedef struct tagTLBVarDesc
{
    VARDESC vardesc;                /* lots of info on the variable and its attributes. */
    VARDESC *vardesc_create;        /* additional data needed for storing VARDESC */
    const TLBString *Name;          /* the name of this variable */
    int HelpContext;
    int HelpStringContext;
    const TLBString *HelpString;
    struct list custdata_list;
} TLBVarDesc;

/* internal implemented interface data */
typedef struct tagTLBImplType
{
    HREFTYPE hRef;          /* hRef of interface */
    int implflags;          /* IMPLFLAG_*s */
    struct list custdata_list;
} TLBImplType;

/* internal TypeInfo data */
typedef struct tagITypeInfoImpl
{
    ITypeInfo2 ITypeInfo2_iface;
    ITypeComp ITypeComp_iface;
    ICreateTypeInfo2 ICreateTypeInfo2_iface;
    LONG ref;
    BOOL not_attached_to_typelib;
    BOOL needs_layout;

    TLBGuid *guid;
    TYPEATTR typeattr;
    TYPEDESC *tdescAlias;

    ITypeLibImpl * pTypeLib;        /* back pointer to typelib */
    int index;                  /* index in this typelib; */
    HREFTYPE hreftype;          /* hreftype for app object binding */
    /* type libs seem to store the doc strings in ascii
     * so why should we do it in unicode?
     */
    const TLBString *Name;
    const TLBString *DocString;
    const TLBString *DllName;
    const TLBString *Schema;
    DWORD dwHelpContext;
    DWORD dwHelpStringContext;

    /* functions  */
    TLBFuncDesc *funcdescs;

    /* variables  */
    TLBVarDesc *vardescs;

    /* Implemented Interfaces  */
    TLBImplType *impltypes;

    struct list *pcustdata_list;
    struct list custdata_list;
} ITypeInfoImpl;

static inline ITypeInfoImpl *info_impl_from_ITypeComp( ITypeComp *iface )
{
    return CONTAINING_RECORD(iface, ITypeInfoImpl, ITypeComp_iface);
}

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

static inline ITypeInfoImpl *impl_from_ITypeInfo( ITypeInfo *iface )
{
    return impl_from_ITypeInfo2((ITypeInfo2*)iface);
}

static inline ITypeInfoImpl *info_impl_from_ICreateTypeInfo2( ICreateTypeInfo2 *iface )
{
    return CONTAINING_RECORD(iface, ITypeInfoImpl, ICreateTypeInfo2_iface);
}

static const ITypeInfo2Vtbl tinfvt;
static const ITypeCompVtbl  tcompvt;
static const ICreateTypeInfo2Vtbl CreateTypeInfo2Vtbl;

static ITypeInfoImpl* ITypeInfoImpl_Constructor(void);
static void ITypeInfoImpl_Destroy(ITypeInfoImpl *This);

typedef struct tagTLBContext
{
	unsigned int oStart;  /* start of TLB in file */
	unsigned int pos;     /* current pos */
	unsigned int length;  /* total length */
	void *mapping;        /* memory mapping */
	MSFT_SegDir * pTblDir;
	ITypeLibImpl* pLibInfo;
} TLBContext;


static inline BSTR TLB_get_bstr(const TLBString *str)
{
    return str != NULL ? str->str : NULL;
}

static inline int TLB_str_memcmp(void *left, const TLBString *str, DWORD len)
{
    if(!str)
        return 1;
    return memcmp(left, str->str, len);
}

static inline const GUID *TLB_get_guidref(const TLBGuid *guid)
{
    return guid != NULL ? &guid->guid : NULL;
}

static inline const GUID *TLB_get_guid_null(const TLBGuid *guid)
{
    return guid != NULL ? &guid->guid : &GUID_NULL;
}

static int get_ptr_size(SYSKIND syskind)
{
    switch(syskind){
    case SYS_WIN64:
        return 8;
    case SYS_WIN32:
    case SYS_MAC:
    case SYS_WIN16:
        return 4;
    }
    WARN("Unhandled syskind: 0x%x\n", syskind);
    return 4;
}

/*
 debug
*/
static void dump_TypeDesc(const TYPEDESC *pTD,char *szVarType) {
    if (pTD->vt & VT_RESERVED)
	szVarType += strlen(strcpy(szVarType, "reserved | "));
    if (pTD->vt & VT_BYREF)
	szVarType += strlen(strcpy(szVarType, "ref to "));
    if (pTD->vt & VT_ARRAY)
	szVarType += strlen(strcpy(szVarType, "array of "));
    if (pTD->vt & VT_VECTOR)
	szVarType += strlen(strcpy(szVarType, "vector of "));
    switch(pTD->vt & VT_TYPEMASK) {
    case VT_UI1: sprintf(szVarType, "VT_UI1"); break;
    case VT_I2: sprintf(szVarType, "VT_I2"); break;
    case VT_I4: sprintf(szVarType, "VT_I4"); break;
    case VT_R4: sprintf(szVarType, "VT_R4"); break;
    case VT_R8: sprintf(szVarType, "VT_R8"); break;
    case VT_BOOL: sprintf(szVarType, "VT_BOOL"); break;
    case VT_ERROR: sprintf(szVarType, "VT_ERROR"); break;
    case VT_CY: sprintf(szVarType, "VT_CY"); break;
    case VT_DATE: sprintf(szVarType, "VT_DATE"); break;
    case VT_BSTR: sprintf(szVarType, "VT_BSTR"); break;
    case VT_UNKNOWN: sprintf(szVarType, "VT_UNKNOWN"); break;
    case VT_DISPATCH: sprintf(szVarType, "VT_DISPATCH"); break;
    case VT_I1: sprintf(szVarType, "VT_I1"); break;
    case VT_UI2: sprintf(szVarType, "VT_UI2"); break;
    case VT_UI4: sprintf(szVarType, "VT_UI4"); break;
    case VT_INT: sprintf(szVarType, "VT_INT"); break;
    case VT_UINT: sprintf(szVarType, "VT_UINT"); break;
    case VT_VARIANT: sprintf(szVarType, "VT_VARIANT"); break;
    case VT_VOID: sprintf(szVarType, "VT_VOID"); break;
    case VT_HRESULT: sprintf(szVarType, "VT_HRESULT"); break;
    case VT_USERDEFINED: sprintf(szVarType, "VT_USERDEFINED ref = %x",
				 pTD->u.hreftype); break;
    case VT_LPSTR: sprintf(szVarType, "VT_LPSTR"); break;
    case VT_LPWSTR: sprintf(szVarType, "VT_LPWSTR"); break;
    case VT_PTR: sprintf(szVarType, "ptr to ");
      dump_TypeDesc(pTD->u.lptdesc, szVarType + 7);
      break;
    case VT_SAFEARRAY: sprintf(szVarType, "safearray of ");
      dump_TypeDesc(pTD->u.lptdesc, szVarType + 13);
      break;
    case VT_CARRAY: sprintf(szVarType, "%d dim array of ",
			    pTD->u.lpadesc->cDims); /* FIXME print out sizes */
      dump_TypeDesc(&pTD->u.lpadesc->tdescElem, szVarType + strlen(szVarType));
      break;

    default: sprintf(szVarType, "unknown(%d)", pTD->vt & VT_TYPEMASK); break;
    }
}

static void dump_ELEMDESC(const ELEMDESC *edesc) {
  char buf[200];
  USHORT flags = edesc->u.paramdesc.wParamFlags;
  dump_TypeDesc(&edesc->tdesc,buf);
  MESSAGE("\t\ttdesc.vartype %d (%s)\n",edesc->tdesc.vt,buf);
  MESSAGE("\t\tu.paramdesc.wParamFlags");
  if (!flags) MESSAGE(" PARAMFLAGS_NONE");
  if (flags & PARAMFLAG_FIN) MESSAGE(" PARAMFLAG_FIN");
  if (flags & PARAMFLAG_FOUT) MESSAGE(" PARAMFLAG_FOUT");
  if (flags & PARAMFLAG_FLCID) MESSAGE(" PARAMFLAG_FLCID");
  if (flags & PARAMFLAG_FRETVAL) MESSAGE(" PARAMFLAG_FRETVAL");
  if (flags & PARAMFLAG_FOPT) MESSAGE(" PARAMFLAG_FOPT");
  if (flags & PARAMFLAG_FHASDEFAULT) MESSAGE(" PARAMFLAG_FHASDEFAULT");
  if (flags & PARAMFLAG_FHASCUSTDATA) MESSAGE(" PARAMFLAG_FHASCUSTDATA");
  MESSAGE("\n\t\tu.paramdesc.lpex %p\n",edesc->u.paramdesc.pparamdescex);
}
static void dump_FUNCDESC(const FUNCDESC *funcdesc) {
  int i;
  MESSAGE("memid is %08x\n",funcdesc->memid);
  for (i=0;i<funcdesc->cParams;i++) {
      MESSAGE("Param %d:\n",i);
      dump_ELEMDESC(funcdesc->lprgelemdescParam+i);
  }
  MESSAGE("\tfunckind: %d (",funcdesc->funckind);
  switch (funcdesc->funckind) {
  case FUNC_VIRTUAL: MESSAGE("virtual");break;
  case FUNC_PUREVIRTUAL: MESSAGE("pure virtual");break;
  case FUNC_NONVIRTUAL: MESSAGE("nonvirtual");break;
  case FUNC_STATIC: MESSAGE("static");break;
  case FUNC_DISPATCH: MESSAGE("dispatch");break;
  default: MESSAGE("unknown");break;
  }
  MESSAGE(")\n\tinvkind: %d (",funcdesc->invkind);
  switch (funcdesc->invkind) {
  case INVOKE_FUNC: MESSAGE("func");break;
  case INVOKE_PROPERTYGET: MESSAGE("property get");break;
  case INVOKE_PROPERTYPUT: MESSAGE("property put");break;
  case INVOKE_PROPERTYPUTREF: MESSAGE("property put ref");break;
  }
  MESSAGE(")\n\tcallconv: %d (",funcdesc->callconv);
  switch (funcdesc->callconv) {
  case CC_CDECL: MESSAGE("cdecl");break;
  case CC_PASCAL: MESSAGE("pascal");break;
  case CC_STDCALL: MESSAGE("stdcall");break;
  case CC_SYSCALL: MESSAGE("syscall");break;
  default:break;
  }
  MESSAGE(")\n\toVft: %d\n", funcdesc->oVft);
  MESSAGE("\tcParamsOpt: %d\n", funcdesc->cParamsOpt);
  MESSAGE("\twFlags: %x\n", funcdesc->wFuncFlags);

  MESSAGE("\telemdescFunc (return value type):\n");
  dump_ELEMDESC(&funcdesc->elemdescFunc);
}

static const char * const typekind_desc[] =
{
	"TKIND_ENUM",
	"TKIND_RECORD",
	"TKIND_MODULE",
	"TKIND_INTERFACE",
	"TKIND_DISPATCH",
	"TKIND_COCLASS",
	"TKIND_ALIAS",
	"TKIND_UNION",
	"TKIND_MAX"
};

static void dump_TLBFuncDescOne(const TLBFuncDesc * pfd)
{
  int i;
  MESSAGE("%s(%u)\n", debugstr_w(TLB_get_bstr(pfd->Name)), pfd->funcdesc.cParams);
  for (i=0;i<pfd->funcdesc.cParams;i++)
      MESSAGE("\tparm%d: %s\n",i,debugstr_w(TLB_get_bstr(pfd->pParamDesc[i].Name)));


  dump_FUNCDESC(&(pfd->funcdesc));

  MESSAGE("\thelpstring: %s\n", debugstr_w(TLB_get_bstr(pfd->HelpString)));
  if(pfd->Entry == NULL)
      MESSAGE("\tentry: (null)\n");
  else if(pfd->Entry == (void*)-1)
      MESSAGE("\tentry: invalid\n");
  else if(IS_INTRESOURCE(pfd->Entry))
      MESSAGE("\tentry: %p\n", pfd->Entry);
  else
      MESSAGE("\tentry: %s\n", debugstr_w(TLB_get_bstr(pfd->Entry)));
}
static void dump_TLBFuncDesc(const TLBFuncDesc * pfd, UINT n)
{
	while (n)
	{
	  dump_TLBFuncDescOne(pfd);
	  ++pfd;
	  --n;
	}
}
static void dump_TLBVarDesc(const TLBVarDesc * pvd, UINT n)
{
	while (n)
	{
	  TRACE_(typelib)("%s\n", debugstr_w(TLB_get_bstr(pvd->Name)));
	  ++pvd;
	  --n;
	}
}

static void dump_TLBImpLib(const TLBImpLib *import)
{
    TRACE_(typelib)("%s %s\n", debugstr_guid(TLB_get_guidref(import->guid)),
		    debugstr_w(import->name));
    TRACE_(typelib)("v%d.%d lcid=%x offset=%x\n", import->wVersionMajor,
		    import->wVersionMinor, import->lcid, import->offset);
}

static void dump_TLBRefType(const ITypeLibImpl *pTL)
{
    TLBRefType *ref;

    LIST_FOR_EACH_ENTRY(ref, &pTL->ref_list, TLBRefType, entry)
    {
        TRACE_(typelib)("href:0x%08x\n", ref->reference);
        if(ref->index == -1)
	    TRACE_(typelib)("%s\n", debugstr_guid(TLB_get_guidref(ref->guid)));
        else
	    TRACE_(typelib)("type no: %d\n", ref->index);

        if(ref->pImpTLInfo != TLB_REF_INTERNAL && ref->pImpTLInfo != TLB_REF_NOT_FOUND)
        {
            TRACE_(typelib)("in lib\n");
            dump_TLBImpLib(ref->pImpTLInfo);
        }
    }
}

static void dump_TLBImplType(const TLBImplType * impl, UINT n)
{
    if(!impl)
        return;
    while (n) {
        TRACE_(typelib)("implementing/inheriting interface hRef = %x implflags %x\n",
            impl->hRef, impl->implflags);
        ++impl;
        --n;
    }
}

static void dump_DispParms(const DISPPARAMS * pdp)
{
    unsigned int index;

    TRACE("args=%u named args=%u\n", pdp->cArgs, pdp->cNamedArgs);

    if (pdp->cNamedArgs && pdp->rgdispidNamedArgs)
    {
        TRACE("named args:\n");
        for (index = 0; index < pdp->cNamedArgs; index++)
            TRACE( "\t0x%x\n", pdp->rgdispidNamedArgs[index] );
    }

    if (pdp->cArgs && pdp->rgvarg)
    {
        TRACE("args:\n");
        for (index = 0; index < pdp->cArgs; index++)
            TRACE("  [%d] %s\n", index, debugstr_variant(pdp->rgvarg+index));
    }
}

static void dump_TypeInfo(const ITypeInfoImpl * pty)
{
    TRACE("%p ref=%u\n", pty, pty->ref);
    TRACE("%s %s\n", debugstr_w(TLB_get_bstr(pty->Name)), debugstr_w(TLB_get_bstr(pty->DocString)));
    TRACE("attr:%s\n", debugstr_guid(TLB_get_guidref(pty->guid)));
    TRACE("kind:%s\n", typekind_desc[pty->typeattr.typekind]);
    TRACE("fct:%u var:%u impl:%u\n", pty->typeattr.cFuncs, pty->typeattr.cVars, pty->typeattr.cImplTypes);
    TRACE("wTypeFlags: 0x%04x\n", pty->typeattr.wTypeFlags);
    TRACE("parent tlb:%p index in TLB:%u\n",pty->pTypeLib, pty->index);
    if (pty->typeattr.typekind == TKIND_MODULE) TRACE("dllname:%s\n", debugstr_w(TLB_get_bstr(pty->DllName)));
    if (TRACE_ON(ole))
        dump_TLBFuncDesc(pty->funcdescs, pty->typeattr.cFuncs);
    dump_TLBVarDesc(pty->vardescs, pty->typeattr.cVars);
    dump_TLBImplType(pty->impltypes, pty->typeattr.cImplTypes);
}

static void dump_VARDESC(const VARDESC *v)
{
    MESSAGE("memid %d\n",v->memid);
    MESSAGE("lpstrSchema %s\n",debugstr_w(v->lpstrSchema));
    MESSAGE("oInst %d\n",v->u.oInst);
    dump_ELEMDESC(&(v->elemdescVar));
    MESSAGE("wVarFlags %x\n",v->wVarFlags);
    MESSAGE("varkind %d\n",v->varkind);
}

static TYPEDESC std_typedesc[VT_LPWSTR+1] =
{
    /* VT_LPWSTR is largest type that, may appear in type description */
    {{0}, VT_EMPTY},  {{0}, VT_NULL},        {{0}, VT_I2},      {{0}, VT_I4},
    {{0}, VT_R4},     {{0}, VT_R8},          {{0}, VT_CY},      {{0}, VT_DATE},
    {{0}, VT_BSTR},   {{0}, VT_DISPATCH},    {{0}, VT_ERROR},   {{0}, VT_BOOL},
    {{0}, VT_VARIANT},{{0}, VT_UNKNOWN},     {{0}, VT_DECIMAL}, {{0}, 15}, /* unused in VARENUM */
    {{0}, VT_I1},     {{0}, VT_UI1},         {{0}, VT_UI2},     {{0}, VT_UI4},
    {{0}, VT_I8},     {{0}, VT_UI8},         {{0}, VT_INT},     {{0}, VT_UINT},
    {{0}, VT_VOID},   {{0}, VT_HRESULT},     {{0}, VT_PTR},     {{0}, VT_SAFEARRAY},
    {{0}, VT_CARRAY}, {{0}, VT_USERDEFINED}, {{0}, VT_LPSTR},   {{0}, VT_LPWSTR}
};

static void TLB_abort(void)
{
    DebugBreak();
}

/* returns the size required for a deep copy of a typedesc into a
 * flat buffer */
static SIZE_T TLB_SizeTypeDesc( const TYPEDESC *tdesc, BOOL alloc_initial_space )
{
    SIZE_T size = 0;

    if (alloc_initial_space)
        size += sizeof(TYPEDESC);

    switch (tdesc->vt)
    {
    case VT_PTR:
    case VT_SAFEARRAY:
        size += TLB_SizeTypeDesc(tdesc->u.lptdesc, TRUE);
        break;
    case VT_CARRAY:
        size += FIELD_OFFSET(ARRAYDESC, rgbounds[tdesc->u.lpadesc->cDims]);
        size += TLB_SizeTypeDesc(&tdesc->u.lpadesc->tdescElem, FALSE);
        break;
    }
    return size;
}

/* deep copy a typedesc into a flat buffer */
static void *TLB_CopyTypeDesc( TYPEDESC *dest, const TYPEDESC *src, void *buffer )
{
    if (!dest)
    {
        dest = buffer;
        buffer = (char *)buffer + sizeof(TYPEDESC);
    }

    *dest = *src;

    switch (src->vt)
    {
    case VT_PTR:
    case VT_SAFEARRAY:
        dest->u.lptdesc = buffer;
        buffer = TLB_CopyTypeDesc(NULL, src->u.lptdesc, buffer);
        break;
    case VT_CARRAY:
        dest->u.lpadesc = buffer;
        memcpy(dest->u.lpadesc, src->u.lpadesc, FIELD_OFFSET(ARRAYDESC, rgbounds[src->u.lpadesc->cDims]));
        buffer = (char *)buffer + FIELD_OFFSET(ARRAYDESC, rgbounds[src->u.lpadesc->cDims]);
        buffer = TLB_CopyTypeDesc(&dest->u.lpadesc->tdescElem, &src->u.lpadesc->tdescElem, buffer);
        break;
    }
    return buffer;
}

/* free custom data allocated by MSFT_CustData */
static inline void TLB_FreeCustData(struct list *custdata_list)
{
    TLBCustData *cd, *cdn;
    LIST_FOR_EACH_ENTRY_SAFE(cd, cdn, custdata_list, TLBCustData, entry)
    {
        list_remove(&cd->entry);
        VariantClear(&cd->data);
        heap_free(cd);
    }
}

static BSTR TLB_MultiByteToBSTR(const char *ptr)
{
    DWORD len;
    BSTR ret;

    len = MultiByteToWideChar(CP_ACP, 0, ptr, -1, NULL, 0);
    ret = SysAllocStringLen(NULL, len - 1);
    if (!ret) return ret;
    MultiByteToWideChar(CP_ACP, 0, ptr, -1, ret, len);
    return ret;
}

static inline TLBFuncDesc *TLB_get_funcdesc_by_memberid(TLBFuncDesc *funcdescs,
        UINT n, MEMBERID memid)
{
    while(n){
        if(funcdescs->funcdesc.memid == memid)
            return funcdescs;
        ++funcdescs;
        --n;
    }
    return NULL;
}

static inline TLBVarDesc *TLB_get_vardesc_by_memberid(TLBVarDesc *vardescs,
        UINT n, MEMBERID memid)
{
    while(n){
        if(vardescs->vardesc.memid == memid)
            return vardescs;
        ++vardescs;
        --n;
    }
    return NULL;
}

static inline TLBVarDesc *TLB_get_vardesc_by_name(TLBVarDesc *vardescs,
        UINT n, const OLECHAR *name)
{
    while(n){
        if(!lstrcmpiW(TLB_get_bstr(vardescs->Name), name))
            return vardescs;
        ++vardescs;
        --n;
    }
    return NULL;
}

static inline TLBCustData *TLB_get_custdata_by_guid(struct list *custdata_list, REFGUID guid)
{
    TLBCustData *cust_data;
    LIST_FOR_EACH_ENTRY(cust_data, custdata_list, TLBCustData, entry)
        if(IsEqualIID(TLB_get_guid_null(cust_data->guid), guid))
            return cust_data;
    return NULL;
}

static inline ITypeInfoImpl *TLB_get_typeinfo_by_name(ITypeInfoImpl **typeinfos,
        UINT n, const OLECHAR *name)
{
    while(n){
        if(!lstrcmpiW(TLB_get_bstr((*typeinfos)->Name), name))
            return *typeinfos;
        ++typeinfos;
        --n;
    }
    return NULL;
}

static void TLBVarDesc_Constructor(TLBVarDesc *var_desc)
{
    list_init(&var_desc->custdata_list);
}

static TLBVarDesc *TLBVarDesc_Alloc(UINT n)
{
    TLBVarDesc *ret;

    ret = heap_alloc_zero(sizeof(TLBVarDesc) * n);
    if(!ret)
        return NULL;

    while(n){
        TLBVarDesc_Constructor(&ret[n-1]);
        --n;
    }

    return ret;
}

static TLBParDesc *TLBParDesc_Constructor(UINT n)
{
    TLBParDesc *ret;

    ret = heap_alloc_zero(sizeof(TLBParDesc) * n);
    if(!ret)
        return NULL;

    while(n){
        list_init(&ret[n-1].custdata_list);
        --n;
    }

    return ret;
}

static void TLBFuncDesc_Constructor(TLBFuncDesc *func_desc)
{
    list_init(&func_desc->custdata_list);
}

static TLBFuncDesc *TLBFuncDesc_Alloc(UINT n)
{
    TLBFuncDesc *ret;

    ret = heap_alloc_zero(sizeof(TLBFuncDesc) * n);
    if(!ret)
        return NULL;

    while(n){
        TLBFuncDesc_Constructor(&ret[n-1]);
        --n;
    }

    return ret;
}

static void TLBImplType_Constructor(TLBImplType *impl)
{
    list_init(&impl->custdata_list);
}

static TLBImplType *TLBImplType_Alloc(UINT n)
{
    TLBImplType *ret;

    ret = heap_alloc_zero(sizeof(TLBImplType) * n);
    if(!ret)
        return NULL;

    while(n){
        TLBImplType_Constructor(&ret[n-1]);
        --n;
    }

    return ret;
}

static TLBGuid *TLB_append_guid(struct list *guid_list,
        const GUID *new_guid, HREFTYPE hreftype)
{
    TLBGuid *guid;

    LIST_FOR_EACH_ENTRY(guid, guid_list, TLBGuid, entry) {
        if (IsEqualGUID(&guid->guid, new_guid))
            return guid;
    }

    guid = heap_alloc(sizeof(TLBGuid));
    if (!guid)
        return NULL;

    memcpy(&guid->guid, new_guid, sizeof(GUID));
    guid->hreftype = hreftype;

    list_add_tail(guid_list, &guid->entry);

    return guid;
}

static HRESULT TLB_set_custdata(struct list *custdata_list, TLBGuid *tlbguid, VARIANT *var)
{
    TLBCustData *cust_data;

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

    cust_data = TLB_get_custdata_by_guid(custdata_list, TLB_get_guid_null(tlbguid));

    if (!cust_data) {
        cust_data = heap_alloc(sizeof(TLBCustData));
        if (!cust_data)
            return E_OUTOFMEMORY;

        cust_data->guid = tlbguid;
        VariantInit(&cust_data->data);

        list_add_tail(custdata_list, &cust_data->entry);
    }else
        VariantClear(&cust_data->data);

    return VariantCopy(&cust_data->data, var);
}

static TLBString *TLB_append_str(struct list *string_list, BSTR new_str)
{
    TLBString *str;

    if(!new_str)
        return NULL;

    LIST_FOR_EACH_ENTRY(str, string_list, TLBString, entry) {
        if (strcmpW(str->str, new_str) == 0)
            return str;
    }

    str = heap_alloc(sizeof(TLBString));
    if (!str)
        return NULL;

    str->str = SysAllocString(new_str);
    if (!str->str) {
        heap_free(str);
        return NULL;
    }

    list_add_tail(string_list, &str->entry);

    return str;
}

static HRESULT TLB_get_size_from_hreftype(ITypeInfoImpl *info, HREFTYPE href,
        ULONG *size, WORD *align)
{
    ITypeInfo *other;
    TYPEATTR *attr;
    HRESULT hr;

    hr = ITypeInfo2_GetRefTypeInfo(&info->ITypeInfo2_iface, href, &other);
    if(FAILED(hr))
        return hr;

    hr = ITypeInfo_GetTypeAttr(other, &attr);
    if(FAILED(hr)){
        ITypeInfo_Release(other);
        return hr;
    }

    if(size)
        *size = attr->cbSizeInstance;
    if(align)
        *align = attr->cbAlignment;

    ITypeInfo_ReleaseTypeAttr(other, attr);
    ITypeInfo_Release(other);

    return S_OK;
}

static HRESULT TLB_size_instance(ITypeInfoImpl *info, SYSKIND sys,
        TYPEDESC *tdesc, ULONG *size, WORD *align)
{
    ULONG i, sub, ptr_size;
    HRESULT hr;

    ptr_size = get_ptr_size(sys);

    switch(tdesc->vt){
    case VT_VOID:
        *size = 0;
        break;
    case VT_I1:
    case VT_UI1:
        *size = 1;
        break;
    case VT_I2:
    case VT_BOOL:
    case VT_UI2:
        *size = 2;
        break;
    case VT_I4:
    case VT_R4:
    case VT_ERROR:
    case VT_UI4:
    case VT_INT:
    case VT_UINT:
    case VT_HRESULT:
        *size = 4;
        break;
    case VT_R8:
    case VT_I8:
    case VT_UI8:
        *size = 8;
        break;
    case VT_BSTR:
    case VT_DISPATCH:
    case VT_UNKNOWN:
    case VT_PTR:
    case VT_SAFEARRAY:
    case VT_LPSTR:
    case VT_LPWSTR:
        *size = ptr_size;
        break;
    case VT_DATE:
        *size = sizeof(DATE);
        break;
    case VT_VARIANT:
        *size = sizeof(VARIANT);
#ifdef _WIN64
        if(sys == SYS_WIN32)
            *size -= 8; /* 32-bit VARIANT is 8 bytes smaller than 64-bit VARIANT */
#endif
        break;
    case VT_DECIMAL:
        *size = sizeof(DECIMAL);
        break;
    case VT_CY:
        *size = sizeof(CY);
        break;
    case VT_CARRAY:
        *size = 0;
        for(i = 0; i < tdesc->u.lpadesc->cDims; ++i)
            *size += tdesc->u.lpadesc->rgbounds[i].cElements;
        hr = TLB_size_instance(info, sys, &tdesc->u.lpadesc->tdescElem, &sub, align);
        if(FAILED(hr))
            return hr;
        *size *= sub;
        return S_OK;
    case VT_USERDEFINED:
        return TLB_get_size_from_hreftype(info, tdesc->u.hreftype, size, align);
    default:
        FIXME("Unsized VT: 0x%x\n", tdesc->vt);
        return E_FAIL;
    }

    if(align){
        if(*size < 4)
            *align = *size;
        else
            *align = 4;
    }

    return S_OK;
}

/**********************************************************************
 *
 *  Functions for reading MSFT typelibs (those created by CreateTypeLib2)
 */

static inline void MSFT_Seek(TLBContext *pcx, LONG where)
{
    if (where != DO_NOT_SEEK)
    {
        where += pcx->oStart;
        if (where > pcx->length)
        {
            /* FIXME */
            ERR("seek beyond end (%d/%d)\n", where, pcx->length );
            TLB_abort();
        }
        pcx->pos = where;
    }
}

/* read function */
static DWORD MSFT_Read(void *buffer,  DWORD count, TLBContext *pcx, LONG where )
{
    TRACE_(typelib)("pos=0x%08x len=0x%08x 0x%08x 0x%08x 0x%08x\n",
       pcx->pos, count, pcx->oStart, pcx->length, where);

    MSFT_Seek(pcx, where);
    if (pcx->pos + count > pcx->length) count = pcx->length - pcx->pos;
    memcpy( buffer, (char *)pcx->mapping + pcx->pos, count );
    pcx->pos += count;
    return count;
}

static DWORD MSFT_ReadLEDWords(void *buffer,  DWORD count, TLBContext *pcx,
                               LONG where )
{
  DWORD ret;

  ret = MSFT_Read(buffer, count, pcx, where);
  FromLEDWords(buffer, ret);

  return ret;
}

static DWORD MSFT_ReadLEWords(void *buffer,  DWORD count, TLBContext *pcx,
                              LONG where )
{
  DWORD ret;

  ret = MSFT_Read(buffer, count, pcx, where);
  FromLEWords(buffer, ret);

  return ret;
}

static HRESULT MSFT_ReadAllGuids(TLBContext *pcx)
{
    TLBGuid *guid;
    MSFT_GuidEntry entry;
    int offs = 0;

    MSFT_Seek(pcx, pcx->pTblDir->pGuidTab.offset);
    while (1) {
        if (offs >= pcx->pTblDir->pGuidTab.length)
            return S_OK;

        MSFT_ReadLEWords(&entry, sizeof(MSFT_GuidEntry), pcx, DO_NOT_SEEK);

        guid = heap_alloc(sizeof(TLBGuid));

        guid->offset = offs;
        guid->guid = entry.guid;
        guid->hreftype = entry.hreftype;

        list_add_tail(&pcx->pLibInfo->guid_list, &guid->entry);

        offs += sizeof(MSFT_GuidEntry);
    }
}

static TLBGuid *MSFT_ReadGuid( int offset, TLBContext *pcx)
{
    TLBGuid *ret;

    LIST_FOR_EACH_ENTRY(ret, &pcx->pLibInfo->guid_list, TLBGuid, entry){
        if(ret->offset == offset){
            TRACE_(typelib)("%s\n", debugstr_guid(&ret->guid));
            return ret;
        }
    }

    return NULL;
}

static HREFTYPE MSFT_ReadHreftype( TLBContext *pcx, int offset )
{
    MSFT_NameIntro niName;

    if (offset < 0)
    {
        ERR_(typelib)("bad offset %d\n", offset);
        return -1;
    }

    MSFT_ReadLEDWords(&niName, sizeof(niName), pcx,
		      pcx->pTblDir->pNametab.offset+offset);

    return niName.hreftype;
}

static HRESULT MSFT_ReadAllNames(TLBContext *pcx)
{
    char *string;
    MSFT_NameIntro intro;
    INT16 len_piece;
    int offs = 0, lengthInChars;

    MSFT_Seek(pcx, pcx->pTblDir->pNametab.offset);
    while (1) {
        TLBString *tlbstr;

        if (offs >= pcx->pTblDir->pNametab.length)
            return S_OK;

        MSFT_ReadLEWords(&intro, sizeof(MSFT_NameIntro), pcx, DO_NOT_SEEK);
        intro.namelen &= 0xFF;
        len_piece = intro.namelen + sizeof(MSFT_NameIntro);
        if(len_piece % 4)
            len_piece = (len_piece + 4) & ~0x3;
        if(len_piece < 8)
            len_piece = 8;

        string = heap_alloc(len_piece + 1);
        MSFT_Read(string, len_piece - sizeof(MSFT_NameIntro), pcx, DO_NOT_SEEK);
        string[intro.namelen] = '\0';

        lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
                                            string, -1, NULL, 0);
        if (!lengthInChars) {
            heap_free(string);
            return E_UNEXPECTED;
        }

        tlbstr = heap_alloc(sizeof(TLBString));

        tlbstr->offset = offs;
        tlbstr->str = SysAllocStringByteLen(NULL, lengthInChars * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, tlbstr->str, lengthInChars);

        heap_free(string);

        list_add_tail(&pcx->pLibInfo->name_list, &tlbstr->entry);

        offs += len_piece;
    }
}

static TLBString *MSFT_ReadName( TLBContext *pcx, int offset)
{
    TLBString *tlbstr;

    LIST_FOR_EACH_ENTRY(tlbstr, &pcx->pLibInfo->name_list, TLBString, entry) {
        if (tlbstr->offset == offset) {
            TRACE_(typelib)("%s\n", debugstr_w(tlbstr->str));
            return tlbstr;
        }
    }

    return NULL;
}

static TLBString *MSFT_ReadString( TLBContext *pcx, int offset)
{
    TLBString *tlbstr;

    LIST_FOR_EACH_ENTRY(tlbstr, &pcx->pLibInfo->string_list, TLBString, entry) {
        if (tlbstr->offset == offset) {
            TRACE_(typelib)("%s\n", debugstr_w(tlbstr->str));
            return tlbstr;
        }
    }

    return NULL;
}

/*
 * read a value and fill a VARIANT structure
 */
static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
{
    int size;

    TRACE_(typelib)("\n");

    if(offset <0) { /* data are packed in here */
        V_VT(pVar) = (offset & 0x7c000000 )>> 26;
        V_I4(pVar) = offset & 0x3ffffff;
        return;
    }
    MSFT_ReadLEWords(&(V_VT(pVar)), sizeof(VARTYPE), pcx,
                     pcx->pTblDir->pCustData.offset + offset );
    TRACE_(typelib)("Vartype = %x\n", V_VT(pVar));
    switch (V_VT(pVar)){
        case VT_EMPTY:  /* FIXME: is this right? */
        case VT_NULL:   /* FIXME: is this right? */
        case VT_I2  :   /* this should not happen */
        case VT_I4  :
        case VT_R4  :
        case VT_ERROR   :
        case VT_BOOL    :
        case VT_I1  :
        case VT_UI1 :
        case VT_UI2 :
        case VT_UI4 :
        case VT_INT :
        case VT_UINT    :
        case VT_VOID    : /* FIXME: is this right? */
        case VT_HRESULT :
            size=4; break;
        case VT_R8  :
        case VT_CY  :
        case VT_DATE    :
        case VT_I8  :
        case VT_UI8 :
        case VT_DECIMAL :  /* FIXME: is this right? */
        case VT_FILETIME :
            size=8;break;
            /* pointer types with known behaviour */
        case VT_BSTR    :{
            char * ptr;
            MSFT_ReadLEDWords(&size, sizeof(INT), pcx, DO_NOT_SEEK );
            if(size == -1){
                V_BSTR(pVar) = NULL;
            }else{
                ptr = heap_alloc_zero(size);
                MSFT_Read(ptr, size, pcx, DO_NOT_SEEK);
                V_BSTR(pVar)=SysAllocStringLen(NULL,size);
                /* FIXME: do we need a AtoW conversion here? */
                V_UNION(pVar, bstrVal[size])='\0';
                while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
                heap_free(ptr);
            }
	}
	size=-4; break;
    /* FIXME: this will not work AT ALL when the variant contains a pointer */
        case VT_DISPATCH :
        case VT_VARIANT :
        case VT_UNKNOWN :
        case VT_PTR :
        case VT_SAFEARRAY :
        case VT_CARRAY  :
        case VT_USERDEFINED :
        case VT_LPSTR   :
        case VT_LPWSTR  :
        case VT_BLOB    :
        case VT_STREAM  :
        case VT_STORAGE :
        case VT_STREAMED_OBJECT :
        case VT_STORED_OBJECT   :
        case VT_BLOB_OBJECT :
        case VT_CF  :
        case VT_CLSID   :
        default:
            size=0;
            FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
                V_VT(pVar));
    }

    if(size>0) /* (big|small) endian correct? */
        MSFT_Read(&(V_I2(pVar)), size, pcx, DO_NOT_SEEK );
    return;
}
/*
 * create a linked list with custom data
 */
static int MSFT_CustData( TLBContext *pcx, int offset, struct list *custdata_list)
{
    MSFT_CDGuid entry;
    TLBCustData* pNew;
    int count=0;

    TRACE_(typelib)("\n");

    if (pcx->pTblDir->pCDGuids.offset < 0) return 0;

    while(offset >=0){
        count++;
        pNew=heap_alloc_zero(sizeof(TLBCustData));
        MSFT_ReadLEDWords(&entry, sizeof(entry), pcx, pcx->pTblDir->pCDGuids.offset+offset);
        pNew->guid = MSFT_ReadGuid(entry.GuidOffset, pcx);
        MSFT_ReadValue(&(pNew->data), entry.DataOffset, pcx);
        list_add_head(custdata_list, &pNew->entry);
        offset = entry.next;
    }
    return count;
}

static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd)
{
    if(type <0)
        pTd->vt=type & VT_TYPEMASK;
    else
        *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];

    TRACE_(typelib)("vt type = %X\n", pTd->vt);
}

static BOOL TLB_is_propgetput(INVOKEKIND invkind)
{
    return (invkind == INVOKE_PROPERTYGET ||
        invkind == INVOKE_PROPERTYPUT ||
        invkind == INVOKE_PROPERTYPUTREF);
}

static void
MSFT_DoFuncs(TLBContext*     pcx,
	    ITypeInfoImpl*  pTI,
            int             cFuncs,
            int             cVars,
            int             offset,
            TLBFuncDesc**   pptfd)
{
    /*
     * member information is stored in a data structure at offset
     * indicated by the memoffset field of the typeinfo structure
     * There are several distinctive parts.
     * The first part starts with a field that holds the total length
     * of this (first) part excluding this field. Then follow the records,
     * for each member there is one record.
     *
     * The first entry is always the length of the record (including this
     * length word).
     * The rest of the record depends on the type of the member. If there is
     * a field indicating the member type (function, variable, interface, etc)
     * I have not found it yet. At this time we depend on the information
     * in the type info and the usual order how things are stored.
     *
     * Second follows an array sized nrMEM*sizeof(INT) with a member id
     * for each member;
     *
     * Third is an equal sized array with file offsets to the name entry
     * of each member.
     *
     * The fourth and last (?) part is an array with offsets to the records
     * in the first part of this file segment.
     */

    int infolen, nameoffset, reclength, i;
    int recoffset = offset + sizeof(INT);

    char *recbuf = heap_alloc(0xffff);
    MSFT_FuncRecord *pFuncRec = (MSFT_FuncRecord*)recbuf;
    TLBFuncDesc *ptfd_prev = NULL, *ptfd;

    TRACE_(typelib)("\n");

    MSFT_ReadLEDWords(&infolen, sizeof(INT), pcx, offset);

    *pptfd = TLBFuncDesc_Alloc(cFuncs);
    ptfd = *pptfd;
    for ( i = 0; i < cFuncs ; i++ )
    {
        int optional;

        /* name, eventually add to a hash table */
        MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
                          offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));

        /* read the function information record */
        MSFT_ReadLEDWords(&reclength, sizeof(pFuncRec->Info), pcx, recoffset);

        reclength &= 0xffff;

        MSFT_ReadLEDWords(&pFuncRec->DataType, reclength - FIELD_OFFSET(MSFT_FuncRecord, DataType), pcx, DO_NOT_SEEK);

        /* size without argument data */
        optional = reclength - pFuncRec->nrargs*sizeof(MSFT_ParameterInfo);
        if (pFuncRec->FKCCIC & 0x1000)
            optional -= pFuncRec->nrargs * sizeof(INT);

        if (optional > FIELD_OFFSET(MSFT_FuncRecord, HelpContext))
            ptfd->helpcontext = pFuncRec->HelpContext;

        if (optional > FIELD_OFFSET(MSFT_FuncRecord, oHelpString))
            ptfd->HelpString = MSFT_ReadString(pcx, pFuncRec->oHelpString);

        if (optional > FIELD_OFFSET(MSFT_FuncRecord, oEntry))
        {
            if (pFuncRec->FKCCIC & 0x2000 )
            {
                if (!IS_INTRESOURCE(pFuncRec->oEntry))
                    ERR("ordinal 0x%08x invalid, IS_INTRESOURCE is false\n", pFuncRec->oEntry);
                ptfd->Entry = (TLBString*)(DWORD_PTR)LOWORD(pFuncRec->oEntry);
            }
            else
                ptfd->Entry = MSFT_ReadString(pcx, pFuncRec->oEntry);
        }
        else
            ptfd->Entry = (TLBString*)-1;

        if (optional > FIELD_OFFSET(MSFT_FuncRecord, HelpStringContext))
            ptfd->HelpStringContext = pFuncRec->HelpStringContext;

        if (optional > FIELD_OFFSET(MSFT_FuncRecord, oCustData) && pFuncRec->FKCCIC & 0x80)
            MSFT_CustData(pcx, pFuncRec->oCustData, &ptfd->custdata_list);

        /* fill the FuncDesc Structure */
        MSFT_ReadLEDWords( & ptfd->funcdesc.memid, sizeof(INT), pcx,
                           offset + infolen + ( i + 1) * sizeof(INT));

        ptfd->funcdesc.funckind   =  (pFuncRec->FKCCIC)      & 0x7;
        ptfd->funcdesc.invkind    =  (pFuncRec->FKCCIC) >> 3 & 0xF;
        ptfd->funcdesc.callconv   =  (pFuncRec->FKCCIC) >> 8 & 0xF;
        ptfd->funcdesc.cParams    =   pFuncRec->nrargs  ;
        ptfd->funcdesc.cParamsOpt =   pFuncRec->nroargs ;
        ptfd->funcdesc.oVft       =   pFuncRec->VtableOffset & ~1;
        ptfd->funcdesc.wFuncFlags =   LOWORD(pFuncRec->Flags) ;

        /* nameoffset is sometimes -1 on the second half of a propget/propput
         * pair of functions */
        if ((nameoffset == -1) && (i > 0) &&
                TLB_is_propgetput(ptfd_prev->funcdesc.invkind) &&
                TLB_is_propgetput(ptfd->funcdesc.invkind))
            ptfd->Name = ptfd_prev->Name;
        else
            ptfd->Name = MSFT_ReadName(pcx, nameoffset);

        MSFT_GetTdesc(pcx,
		      pFuncRec->DataType,
		      &ptfd->funcdesc.elemdescFunc.tdesc);

        /* do the parameters/arguments */
        if(pFuncRec->nrargs)
        {
            int j = 0;
            MSFT_ParameterInfo paraminfo;

            ptfd->funcdesc.lprgelemdescParam =
                heap_alloc_zero(pFuncRec->nrargs * (sizeof(ELEMDESC) + sizeof(PARAMDESCEX)));

            ptfd->pParamDesc = TLBParDesc_Constructor(pFuncRec->nrargs);

            MSFT_ReadLEDWords(&paraminfo, sizeof(paraminfo), pcx,
                              recoffset + reclength - pFuncRec->nrargs * sizeof(MSFT_ParameterInfo));

            for ( j = 0 ; j < pFuncRec->nrargs ; j++ )
            {
                ELEMDESC *elemdesc = &ptfd->funcdesc.lprgelemdescParam[j];

                MSFT_GetTdesc(pcx,
			      paraminfo.DataType,
			      &elemdesc->tdesc);

                elemdesc->u.paramdesc.wParamFlags = paraminfo.Flags;

                /* name */
                if (paraminfo.oName != -1)
                    ptfd->pParamDesc[j].Name =
                        MSFT_ReadName( pcx, paraminfo.oName );
                TRACE_(typelib)("param[%d] = %s\n", j, debugstr_w(TLB_get_bstr(ptfd->pParamDesc[j].Name)));

                /* default value */
                if ( (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) &&
                     (pFuncRec->FKCCIC & 0x1000) )
                {
                    INT* pInt = (INT *)((char *)pFuncRec +
                                   reclength -
                                   (pFuncRec->nrargs * 4) * sizeof(INT) );

                    PARAMDESC* pParamDesc = &elemdesc->u.paramdesc;

                    pParamDesc->pparamdescex = (PARAMDESCEX*)(ptfd->funcdesc.lprgelemdescParam+pFuncRec->nrargs)+j;
                    pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX);

		    MSFT_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
                        pInt[j], pcx);
                }
                else
                    elemdesc->u.paramdesc.pparamdescex = NULL;

                /* custom info */
                if (optional > (FIELD_OFFSET(MSFT_FuncRecord, oArgCustData) +
                                j*sizeof(pFuncRec->oArgCustData[0])) &&
                    pFuncRec->FKCCIC & 0x80 )
                {
                    MSFT_CustData(pcx,
				  pFuncRec->oArgCustData[j],
				  &ptfd->pParamDesc[j].custdata_list);
                }

                /* SEEK value = jump to offset,
                 * from there jump to the end of record,
                 * go back by (j-1) arguments
                 */
                MSFT_ReadLEDWords( &paraminfo ,
			   sizeof(MSFT_ParameterInfo), pcx,
			   recoffset + reclength - ((pFuncRec->nrargs - j - 1)
					       * sizeof(MSFT_ParameterInfo)));
            }
        }

        /* scode is not used: archaic win16 stuff FIXME: right? */
        ptfd->funcdesc.cScodes   = 0 ;
        ptfd->funcdesc.lprgscode = NULL ;

        ptfd_prev = ptfd;
        ++ptfd;
        recoffset += reclength;
    }
    heap_free(recbuf);
}

static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs,
		       int cVars, int offset, TLBVarDesc ** pptvd)
{
    int infolen, nameoffset, reclength;
    char recbuf[256];
    MSFT_VarRecord *pVarRec = (MSFT_VarRecord*)recbuf;
    TLBVarDesc *ptvd;
    int i;
    int recoffset;

    TRACE_(typelib)("\n");

    ptvd = *pptvd = TLBVarDesc_Alloc(cVars);
    MSFT_ReadLEDWords(&infolen,sizeof(INT), pcx, offset);
    MSFT_ReadLEDWords(&recoffset,sizeof(INT), pcx, offset + infolen +
                      ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
    recoffset += offset+sizeof(INT);
    for(i=0;i<cVars;i++, ++ptvd){
    /* name, eventually add to a hash table */
        MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
                          offset + infolen + (2*cFuncs + cVars + i + 1) * sizeof(INT));
        ptvd->Name=MSFT_ReadName(pcx, nameoffset);
    /* read the variable information record */
        MSFT_ReadLEDWords(&reclength, sizeof(pVarRec->Info), pcx, recoffset);
        reclength &= 0xff;
        MSFT_ReadLEDWords(&pVarRec->DataType, reclength - FIELD_OFFSET(MSFT_VarRecord, DataType), pcx, DO_NOT_SEEK);

        /* optional data */
        if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpContext))
            ptvd->HelpContext = pVarRec->HelpContext;

        if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpString))
            ptvd->HelpString = MSFT_ReadString(pcx, pVarRec->HelpString);

        if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpStringContext))
            ptvd->HelpStringContext = pVarRec->HelpStringContext;

    /* fill the VarDesc Structure */
        MSFT_ReadLEDWords(&ptvd->vardesc.memid, sizeof(INT), pcx,
                          offset + infolen + (cFuncs + i + 1) * sizeof(INT));
        ptvd->vardesc.varkind = pVarRec->VarKind;
        ptvd->vardesc.wVarFlags = pVarRec->Flags;
        MSFT_GetTdesc(pcx, pVarRec->DataType,
            &ptvd->vardesc.elemdescVar.tdesc);
/*   ptvd->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */
        if(pVarRec->VarKind == VAR_CONST ){
            ptvd->vardesc.u.lpvarValue = heap_alloc_zero(sizeof(VARIANT));
            MSFT_ReadValue(ptvd->vardesc.u.lpvarValue,
                pVarRec->OffsValue, pcx);
        } else
            ptvd->vardesc.u.oInst=pVarRec->OffsValue;
        recoffset += reclength;
    }
}

/* process Implemented Interfaces of a com class */
static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count,
			    int offset)
{
    int i;
    MSFT_RefRecord refrec;
    TLBImplType *pImpl;

    TRACE_(typelib)("\n");

    pTI->impltypes = TLBImplType_Alloc(count);
    pImpl = pTI->impltypes;
    for(i=0;i<count;i++){
        if(offset<0) break; /* paranoia */
        MSFT_ReadLEDWords(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
        pImpl->hRef = refrec.reftype;
        pImpl->implflags=refrec.flags;
        MSFT_CustData(pcx, refrec.oCustData, &pImpl->custdata_list);
        offset=refrec.onext;
        ++pImpl;
    }
}

#ifdef _WIN64
/* when a 32-bit typelib is loaded in 64-bit mode, we need to resize pointers
 * and some structures, and fix the alignment */
static void TLB_fix_32on64_typeinfo(ITypeInfoImpl *info)
{
    if(info->typeattr.typekind == TKIND_ALIAS){
        switch(info->tdescAlias->vt){
        case VT_BSTR:
        case VT_DISPATCH:
        case VT_UNKNOWN:
        case VT_PTR:
        case VT_SAFEARRAY:
        case VT_LPSTR:
        case VT_LPWSTR:
            info->typeattr.cbSizeInstance = sizeof(void*);
            info->typeattr.cbAlignment = sizeof(void*);
            break;
        case VT_CARRAY:
        case VT_USERDEFINED:
            TLB_size_instance(info, SYS_WIN64, info->tdescAlias, &info->typeattr.cbSizeInstance, &info->typeattr.cbAlignment);
            break;
        case VT_VARIANT:
            info->typeattr.cbSizeInstance = sizeof(VARIANT);
            info->typeattr.cbAlignment = 8;
        default:
            if(info->typeattr.cbSizeInstance < sizeof(void*))
                info->typeattr.cbAlignment = info->typeattr.cbSizeInstance;
            else
                info->typeattr.cbAlignment = sizeof(void*);
            break;
        }
    }else if(info->typeattr.typekind == TKIND_INTERFACE ||
            info->typeattr.typekind == TKIND_DISPATCH ||
            info->typeattr.typekind == TKIND_COCLASS){
        info->typeattr.cbSizeInstance = sizeof(void*);
        info->typeattr.cbAlignment = sizeof(void*);
    }
}
#endif

/*
 * process a typeinfo record
 */
static ITypeInfoImpl * MSFT_DoTypeInfo(
    TLBContext *pcx,
    int count,
    ITypeLibImpl * pLibInfo)
{
    MSFT_TypeInfoBase tiBase;
    ITypeInfoImpl *ptiRet;

    TRACE_(typelib)("count=%u\n", count);

    ptiRet = ITypeInfoImpl_Constructor();
    MSFT_ReadLEDWords(&tiBase, sizeof(tiBase) ,pcx ,
                      pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));

/* this is where we are coming from */
    ptiRet->pTypeLib = pLibInfo;
    ptiRet->index=count;

    ptiRet->guid = MSFT_ReadGuid(tiBase.posguid, pcx);
    ptiRet->typeattr.lcid = pLibInfo->set_lcid;   /* FIXME: correct? */
    ptiRet->typeattr.lpstrSchema = NULL;              /* reserved */
    ptiRet->typeattr.cbSizeInstance = tiBase.size;
    ptiRet->typeattr.typekind = tiBase.typekind & 0xF;
    ptiRet->typeattr.cFuncs = LOWORD(tiBase.cElement);
    ptiRet->typeattr.cVars = HIWORD(tiBase.cElement);
    ptiRet->typeattr.cbAlignment = (tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */
    ptiRet->typeattr.wTypeFlags = tiBase.flags;
    ptiRet->typeattr.wMajorVerNum = LOWORD(tiBase.version);
    ptiRet->typeattr.wMinorVerNum = HIWORD(tiBase.version);
    ptiRet->typeattr.cImplTypes = tiBase.cImplTypes;
    ptiRet->typeattr.cbSizeVft = tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
    if (ptiRet->typeattr.typekind == TKIND_ALIAS) {
        TYPEDESC tmp;
        MSFT_GetTdesc(pcx, tiBase.datatype1, &tmp);
        ptiRet->tdescAlias = heap_alloc(TLB_SizeTypeDesc(&tmp, TRUE));
        TLB_CopyTypeDesc(NULL, &tmp, ptiRet->tdescAlias);
    }

/*  FIXME: */
/*    IDLDESC  idldescType; *//* never saw this one != zero  */

/* name, eventually add to a hash table */
    ptiRet->Name=MSFT_ReadName(pcx, tiBase.NameOffset);
    ptiRet->hreftype = MSFT_ReadHreftype(pcx, tiBase.NameOffset);
    TRACE_(typelib)("reading %s\n", debugstr_w(TLB_get_bstr(ptiRet->Name)));
    /* help info */
    ptiRet->DocString=MSFT_ReadString(pcx, tiBase.docstringoffs);
    ptiRet->dwHelpStringContext=tiBase.helpstringcontext;
    ptiRet->dwHelpContext=tiBase.helpcontext;

    if (ptiRet->typeattr.typekind == TKIND_MODULE)
        ptiRet->DllName = MSFT_ReadString(pcx, tiBase.datatype1);

/* note: InfoType's Help file and HelpStringDll come from the containing
 * library. Further HelpString and Docstring appear to be the same thing :(
 */
    /* functions */
    if(ptiRet->typeattr.cFuncs >0 )
        MSFT_DoFuncs(pcx, ptiRet, ptiRet->typeattr.cFuncs,
		    ptiRet->typeattr.cVars,
		    tiBase.memoffset, &ptiRet->funcdescs);
    /* variables */
    if(ptiRet->typeattr.cVars >0 )
        MSFT_DoVars(pcx, ptiRet, ptiRet->typeattr.cFuncs,
		   ptiRet->typeattr.cVars,
		   tiBase.memoffset, &ptiRet->vardescs);
    if(ptiRet->typeattr.cImplTypes >0 ) {
        switch(ptiRet->typeattr.typekind)
        {
        case TKIND_COCLASS:
            MSFT_DoImplTypes(pcx, ptiRet, ptiRet->typeattr.cImplTypes,
                tiBase.datatype1);
            break;
        case TKIND_DISPATCH:
            /* This is not -1 when the interface is a non-base dual interface or
               when a dispinterface wraps an interface, i.e., the idl 'dispinterface x {interface y;};'.
               Note however that GetRefTypeOfImplType(0) always returns a ref to IDispatch and
               not this interface.
            */

            if (tiBase.datatype1 != -1)
            {
                ptiRet->impltypes = TLBImplType_Alloc(1);
                ptiRet->impltypes[0].hRef = tiBase.datatype1;
            }
            break;
        default:
            ptiRet->impltypes = TLBImplType_Alloc(1);
            ptiRet->impltypes[0].hRef = tiBase.datatype1;
            break;
       }
    }
    MSFT_CustData(pcx, tiBase.oCustData, ptiRet->pcustdata_list);

    TRACE_(typelib)("%s guid: %s kind:%s\n",
       debugstr_w(TLB_get_bstr(ptiRet->Name)),
       debugstr_guid(TLB_get_guidref(ptiRet->guid)),
       typekind_desc[ptiRet->typeattr.typekind]);
    if (TRACE_ON(typelib))
      dump_TypeInfo(ptiRet);

    return ptiRet;
}

static HRESULT MSFT_ReadAllStrings(TLBContext *pcx)
{
    char *string;
    INT16 len_str, len_piece;
    int offs = 0, lengthInChars;

    MSFT_Seek(pcx, pcx->pTblDir->pStringtab.offset);
    while (1) {
        TLBString *tlbstr;

        if (offs >= pcx->pTblDir->pStringtab.length)
            return S_OK;

        MSFT_ReadLEWords(&len_str, sizeof(INT16), pcx, DO_NOT_SEEK);
        len_piece = len_str + sizeof(INT16);
        if(len_piece % 4)
            len_piece = (len_piece + 4) & ~0x3;
        if(len_piece < 8)
            len_piece = 8;

        string = heap_alloc(len_piece + 1);
        MSFT_Read(string, len_piece - sizeof(INT16), pcx, DO_NOT_SEEK);
        string[len_str] = '\0';

        lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
                                            string, -1, NULL, 0);
        if (!lengthInChars) {
            heap_free(string);
            return E_UNEXPECTED;
        }

        tlbstr = heap_alloc(sizeof(TLBString));

        tlbstr->offset = offs;
        tlbstr->str = SysAllocStringByteLen(NULL, lengthInChars * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, tlbstr->str, lengthInChars);

        heap_free(string);

        list_add_tail(&pcx->pLibInfo->string_list, &tlbstr->entry);

        offs += len_piece;
    }
}

static HRESULT MSFT_ReadAllRefs(TLBContext *pcx)
{
    TLBRefType *ref;
    int offs = 0;

    MSFT_Seek(pcx, pcx->pTblDir->pImpInfo.offset);
    while (offs < pcx->pTblDir->pImpInfo.length) {
        MSFT_ImpInfo impinfo;
        TLBImpLib *pImpLib;

        MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx, DO_NOT_SEEK);

        ref = heap_alloc_zero(sizeof(TLBRefType));
        list_add_tail(&pcx->pLibInfo->ref_list, &ref->entry);

        LIST_FOR_EACH_ENTRY(pImpLib, &pcx->pLibInfo->implib_list, TLBImpLib, entry)
            if(pImpLib->offset==impinfo.oImpFile)
                break;

        if(&pImpLib->entry != &pcx->pLibInfo->implib_list){
            ref->reference = offs;
            ref->pImpTLInfo = pImpLib;
            if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
                ref->guid = MSFT_ReadGuid(impinfo.oGuid, pcx);
                TRACE("importing by guid %s\n", debugstr_guid(TLB_get_guidref(ref->guid)));
                ref->index = TLB_REF_USE_GUID;
            } else
                ref->index = impinfo.oGuid;
        }else{
            ERR("Cannot find a reference\n");
            ref->reference = -1;
            ref->pImpTLInfo = TLB_REF_NOT_FOUND;
        }

        offs += sizeof(impinfo);
    }

    return S_OK;
}

/* Because type library parsing has some degree of overhead, and some apps repeatedly load the same
 * typelibs over and over, we cache them here. According to MSDN Microsoft have a similar scheme in
 * place. This will cause a deliberate memory leak, but generally losing RAM for cycles is an acceptable
 * tradeoff here.
 */
static struct list tlb_cache = LIST_INIT(tlb_cache);
static CRITICAL_SECTION cache_section;
static CRITICAL_SECTION_DEBUG cache_section_debug =
{
    0, 0, &cache_section,
    { &cache_section_debug.ProcessLocksList, &cache_section_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": typelib loader cache") }
};
static CRITICAL_SECTION cache_section = { &cache_section_debug, -1, 0, 0, 0, 0 };


typedef struct TLB_PEFile
{
    IUnknown IUnknown_iface;
    LONG refs;
    HMODULE dll;
    HRSRC typelib_resource;
    HGLOBAL typelib_global;
    LPVOID typelib_base;
} TLB_PEFile;

static inline TLB_PEFile *pefile_impl_from_IUnknown(IUnknown *iface)
{
    return CONTAINING_RECORD(iface, TLB_PEFile, IUnknown_iface);
}

static HRESULT WINAPI TLB_PEFile_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
    if (IsEqualIID(riid, &IID_IUnknown))
    {
        *ppv = iface;
        IUnknown_AddRef(iface);
        return S_OK;
    }
    *ppv = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI TLB_PEFile_AddRef(IUnknown *iface)
{
    TLB_PEFile *This = pefile_impl_from_IUnknown(iface);
    return InterlockedIncrement(&This->refs);
}

static ULONG WINAPI TLB_PEFile_Release(IUnknown *iface)
{
    TLB_PEFile *This = pefile_impl_from_IUnknown(iface);
    ULONG refs = InterlockedDecrement(&This->refs);
    if (!refs)
    {
        if (This->typelib_global)
            FreeResource(This->typelib_global);
        if (This->dll)
            FreeLibrary(This->dll);
        heap_free(This);
    }
    return refs;
}

static const IUnknownVtbl TLB_PEFile_Vtable =
{
    TLB_PEFile_QueryInterface,
    TLB_PEFile_AddRef,
    TLB_PEFile_Release
};

static HRESULT TLB_PEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
{
    TLB_PEFile *This;
    HRESULT hr = TYPE_E_CANTLOADLIBRARY;

    This = heap_alloc(sizeof(TLB_PEFile));
    if (!This)
        return E_OUTOFMEMORY;

    This->IUnknown_iface.lpVtbl = &TLB_PEFile_Vtable;
    This->refs = 1;
    This->dll = NULL;
    This->typelib_resource = NULL;
    This->typelib_global = NULL;
    This->typelib_base = NULL;

    This->dll = LoadLibraryExW(path, 0, DONT_RESOLVE_DLL_REFERENCES |
                    LOAD_LIBRARY_AS_DATAFILE | LOAD_WITH_ALTERED_SEARCH_PATH);

    if (This->dll)
    {
        static const WCHAR TYPELIBW[] = {'T','Y','P','E','L','I','B',0};
        This->typelib_resource = FindResourceW(This->dll, MAKEINTRESOURCEW(index), TYPELIBW);
        if (This->typelib_resource)
        {
            This->typelib_global = LoadResource(This->dll, This->typelib_resource);
            if (This->typelib_global)
            {
                This->typelib_base = LockResource(This->typelib_global);

                if (This->typelib_base)
                {
                    *pdwTLBLength = SizeofResource(This->dll, This->typelib_resource);
                    *ppBase = This->typelib_base;
                    *ppFile = &This->IUnknown_iface;
                    return S_OK;
                }
            }
        }

        TRACE("No TYPELIB resource found\n");
        hr = E_FAIL;
    }

    TLB_PEFile_Release(&This->IUnknown_iface);
    return hr;
}

typedef struct TLB_NEFile
{
    IUnknown IUnknown_iface;
    LONG refs;
    LPVOID typelib_base;
} TLB_NEFile;

static inline TLB_NEFile *nefile_impl_from_IUnknown(IUnknown *iface)
{
    return CONTAINING_RECORD(iface, TLB_NEFile, IUnknown_iface);
}

static HRESULT WINAPI TLB_NEFile_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
    if (IsEqualIID(riid, &IID_IUnknown))
    {
        *ppv = iface;
        IUnknown_AddRef(iface);
        return S_OK;
    }
    *ppv = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI TLB_NEFile_AddRef(IUnknown *iface)
{
    TLB_NEFile *This = nefile_impl_from_IUnknown(iface);
    return InterlockedIncrement(&This->refs);
}

static ULONG WINAPI TLB_NEFile_Release(IUnknown *iface)
{
    TLB_NEFile *This = nefile_impl_from_IUnknown(iface);
    ULONG refs = InterlockedDecrement(&This->refs);
    if (!refs)
    {
        heap_free(This->typelib_base);
        heap_free(This);
    }
    return refs;
}

static const IUnknownVtbl TLB_NEFile_Vtable =
{
    TLB_NEFile_QueryInterface,
    TLB_NEFile_AddRef,
    TLB_NEFile_Release
};

/***********************************************************************
 *           read_xx_header         [internal]
 */
static int read_xx_header( HFILE lzfd )
{
    IMAGE_DOS_HEADER mzh;
    char magic[3];

    LZSeek( lzfd, 0, SEEK_SET );
    if ( sizeof(mzh) != LZRead( lzfd, (LPSTR)&mzh, sizeof(mzh) ) )
        return 0;
    if ( mzh.e_magic != IMAGE_DOS_SIGNATURE )
        return 0;

    LZSeek( lzfd, mzh.e_lfanew, SEEK_SET );
    if ( 2 != LZRead( lzfd, magic, 2 ) )
        return 0;

    LZSeek( lzfd, mzh.e_lfanew, SEEK_SET );

    if ( magic[0] == 'N' && magic[1] == 'E' )
        return IMAGE_OS2_SIGNATURE;
    if ( magic[0] == 'P' && magic[1] == 'E' )
        return IMAGE_NT_SIGNATURE;

    magic[2] = '\0';
    WARN("Can't handle %s files.\n", magic );
    return 0;
}


/***********************************************************************
 *           find_ne_resource         [internal]
 */
static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
                                DWORD *resLen, DWORD *resOff )
{
    IMAGE_OS2_HEADER nehd;
    NE_TYPEINFO *typeInfo;
    NE_NAMEINFO *nameInfo;
    DWORD nehdoffset;
    LPBYTE resTab;
    DWORD resTabSize;
    int count;

    /* Read in NE header */
    nehdoffset = LZSeek( lzfd, 0, SEEK_CUR );
    if ( sizeof(nehd) != LZRead( lzfd, (LPSTR)&nehd, sizeof(nehd) ) ) return FALSE;

    resTabSize = nehd.ne_restab - nehd.ne_rsrctab;
    if ( !resTabSize )
    {
        TRACE("No resources in NE dll\n" );
        return FALSE;
    }

    /* Read in resource table */
    resTab = heap_alloc( resTabSize );
    if ( !resTab ) return FALSE;

    LZSeek( lzfd, nehd.ne_rsrctab + nehdoffset, SEEK_SET );
    if ( resTabSize != LZRead( lzfd, (char*)resTab, resTabSize ) )
    {
        heap_free( resTab );
        return FALSE;
    }

    /* Find resource */
    typeInfo = (NE_TYPEINFO *)(resTab + 2);

    if (!IS_INTRESOURCE(typeid))  /* named type */
    {
        BYTE len = strlen( typeid );
        while (typeInfo->type_id)
        {
            if (!(typeInfo->type_id & 0x8000))
            {
                BYTE *p = resTab + typeInfo->type_id;
                if ((*p == len) && !strncasecmp( (char*)p+1, typeid, len )) goto found_type;
            }
            typeInfo = (NE_TYPEINFO *)((char *)(typeInfo + 1) +
                                       typeInfo->count * sizeof(NE_NAMEINFO));
        }
    }
    else  /* numeric type id */
    {
        WORD id = LOWORD(typeid) | 0x8000;
        while (typeInfo->type_id)
        {
            if (typeInfo->type_id == id) goto found_type;
            typeInfo = (NE_TYPEINFO *)((char *)(typeInfo + 1) +
                                       typeInfo->count * sizeof(NE_NAMEINFO));
        }
    }
    TRACE("No typeid entry found for %p\n", typeid );
    heap_free( resTab );
    return FALSE;

 found_type:
    nameInfo = (NE_NAMEINFO *)(typeInfo + 1);

    if (!IS_INTRESOURCE(resid))  /* named resource */
    {
        BYTE len = strlen( resid );
        for (count = typeInfo->count; count > 0; count--, nameInfo++)
        {
            BYTE *p = resTab + nameInfo->id;
            if (nameInfo->id & 0x8000) continue;
            if ((*p == len) && !strncasecmp( (char*)p+1, resid, len )) goto found_name;
        }
    }
    else  /* numeric resource id */
    {
        WORD id = LOWORD(resid) | 0x8000;
        for (count = typeInfo->count; count > 0; count--, nameInfo++)
            if (nameInfo->id == id) goto found_name;
    }
    TRACE("No resid entry found for %p\n", typeid );
    heap_free( resTab );
    return FALSE;

 found_name:
    /* Return resource data */
    if ( resLen ) *resLen = nameInfo->length << *(WORD *)resTab;
    if ( resOff ) *resOff = nameInfo->offset << *(WORD *)resTab;

    heap_free( resTab );
    return TRUE;
}

static HRESULT TLB_NEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile){

    HFILE lzfd = -1;
    OFSTRUCT ofs;
    HRESULT hr = TYPE_E_CANTLOADLIBRARY;
    TLB_NEFile *This;

    This = heap_alloc(sizeof(TLB_NEFile));
    if (!This) return E_OUTOFMEMORY;

    This->IUnknown_iface.lpVtbl = &TLB_NEFile_Vtable;
    This->refs = 1;
    This->typelib_base = NULL;

    lzfd = LZOpenFileW( (LPWSTR)path, &ofs, OF_READ );
    if ( lzfd >= 0 && read_xx_header( lzfd ) == IMAGE_OS2_SIGNATURE )
    {
        DWORD reslen, offset;
        if( find_ne_resource( lzfd, "TYPELIB", MAKEINTRESOURCEA(index), &reslen, &offset ) )
        {
            This->typelib_base = heap_alloc(reslen);
            if( !This->typelib_base )
                hr = E_OUTOFMEMORY;
            else
            {
                LZSeek( lzfd, offset, SEEK_SET );
                reslen = LZRead( lzfd, This->typelib_base, reslen );
                LZClose( lzfd );
                *ppBase = This->typelib_base;
                *pdwTLBLength = reslen;
                *ppFile = &This->IUnknown_iface;
                return S_OK;
            }
        }
    }

    if( lzfd >= 0) LZClose( lzfd );
    TLB_NEFile_Release(&This->IUnknown_iface);
    return hr;
}

typedef struct TLB_Mapping
{
    IUnknown IUnknown_iface;
    LONG refs;
    HANDLE file;
    HANDLE mapping;
    LPVOID typelib_base;
} TLB_Mapping;

static inline TLB_Mapping *mapping_impl_from_IUnknown(IUnknown *iface)
{
    return CONTAINING_RECORD(iface, TLB_Mapping, IUnknown_iface);
}

static HRESULT WINAPI TLB_Mapping_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
    if (IsEqualIID(riid, &IID_IUnknown))
    {
        *ppv = iface;
        IUnknown_AddRef(iface);
        return S_OK;
    }
    *ppv = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI TLB_Mapping_AddRef(IUnknown *iface)
{
    TLB_Mapping *This = mapping_impl_from_IUnknown(iface);
    return InterlockedIncrement(&This->refs);
}

static ULONG WINAPI TLB_Mapping_Release(IUnknown *iface)
{
    TLB_Mapping *This = mapping_impl_from_IUnknown(iface);
    ULONG refs = InterlockedDecrement(&This->refs);
    if (!refs)
    {
        if (This->typelib_base)
            UnmapViewOfFile(This->typelib_base);
        if (This->mapping)
            CloseHandle(This->mapping);
        if (This->file != INVALID_HANDLE_VALUE)
            CloseHandle(This->file);
        heap_free(This);
    }
    return refs;
}

static const IUnknownVtbl TLB_Mapping_Vtable =
{
    TLB_Mapping_QueryInterface,
    TLB_Mapping_AddRef,
    TLB_Mapping_Release
};

static HRESULT TLB_Mapping_Open(LPCWSTR path, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
{
    TLB_Mapping *This;

    This = heap_alloc(sizeof(TLB_Mapping));
    if (!This)
        return E_OUTOFMEMORY;

    This->IUnknown_iface.lpVtbl = &TLB_Mapping_Vtable;
    This->refs = 1;
    This->file = INVALID_HANDLE_VALUE;
    This->mapping = NULL;
    This->typelib_base = NULL;

    This->file = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
    if (INVALID_HANDLE_VALUE != This->file)
    {
        This->mapping = CreateFileMappingW(This->file, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
        if (This->mapping)
        {
            This->typelib_base = MapViewOfFile(This->mapping, FILE_MAP_READ, 0, 0, 0);
            if(This->typelib_base)
            {
                /* retrieve file size */
                *pdwTLBLength = GetFileSize(This->file, NULL);
                *ppBase = This->typelib_base;
                *ppFile = &This->IUnknown_iface;
                return S_OK;
            }
        }
    }

    IUnknown_Release(&This->IUnknown_iface);
    return TYPE_E_CANTLOADLIBRARY;
}

/****************************************************************************
 *	TLB_ReadTypeLib
 *
 * find the type of the typelib file and map the typelib resource into
 * the memory
 */

#define SLTG_SIGNATURE 0x47544c53 /* "SLTG" */
static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib)
{
    ITypeLibImpl *entry;
    HRESULT ret;
    INT index = 1;
    LPWSTR index_str, file = (LPWSTR)pszFileName;
    LPVOID pBase = NULL;
    DWORD dwTLBLength = 0;
    IUnknown *pFile = NULL;
    HANDLE h;

    *ppTypeLib = NULL;

    index_str = strrchrW(pszFileName, '\\');
    if(index_str && *++index_str != '\0')
    {
        LPWSTR end_ptr;
        LONG idx = strtolW(index_str, &end_ptr, 10);
        if(*end_ptr == '\0')
        {
            int str_len = index_str - pszFileName - 1;
            index = idx;
            file = heap_alloc((str_len + 1) * sizeof(WCHAR));
            memcpy(file, pszFileName, str_len * sizeof(WCHAR));
            file[str_len] = 0;
        }
    }

    if(!SearchPathW(NULL, file, NULL, cchPath, pszPath, NULL))
    {
        if(strchrW(file, '\\'))
        {
            lstrcpyW(pszPath, file);
        }
        else
        {
            int len = GetSystemDirectoryW(pszPath, cchPath);
            pszPath[len] = '\\';
            memcpy(pszPath + len + 1, file, (strlenW(file) + 1) * sizeof(WCHAR));
        }
    }

    if(file != pszFileName) heap_free(file);

    h = CreateFileW(pszPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if(h != INVALID_HANDLE_VALUE){
        FILE_NAME_INFORMATION size_info;
        BOOL br;

        /* GetFileInformationByHandleEx returns the path of the file without
         * WOW64 redirection */
        br = GetFileInformationByHandleEx(h, FileNameInfo, &size_info, sizeof(size_info));
        if(br || GetLastError() == ERROR_MORE_DATA){
            FILE_NAME_INFORMATION *info;
            DWORD size = sizeof(*info) + size_info.FileNameLength + sizeof(WCHAR);

            info = HeapAlloc(GetProcessHeap(), 0, size);

            br = GetFileInformationByHandleEx(h, FileNameInfo, info, size);
            if(br){
                info->FileName[info->FileNameLength / sizeof(WCHAR)] = 0;
                lstrcpynW(pszPath + 2, info->FileName, cchPath - 2);
            }

            HeapFree(GetProcessHeap(), 0, info);
        }

        CloseHandle(h);
    }

    TRACE_(typelib)("File %s index %d\n", debugstr_w(pszPath), index);

    /* We look the path up in the typelib cache. If found, we just addref it, and return the pointer. */
    EnterCriticalSection(&cache_section);
    LIST_FOR_EACH_ENTRY(entry, &tlb_cache, ITypeLibImpl, entry)
    {
        if (!strcmpiW(entry->path, pszPath) && entry->index == index)
        {
            TRACE("cache hit\n");
            *ppTypeLib = &entry->ITypeLib2_iface;
            ITypeLib2_AddRef(*ppTypeLib);
            LeaveCriticalSection(&cache_section);
            return S_OK;
        }
    }
    LeaveCriticalSection(&cache_section);

    /* now actually load and parse the typelib */

    ret = TLB_PEFile_Open(pszPath, index, &pBase, &dwTLBLength, &pFile);
    if (ret == TYPE_E_CANTLOADLIBRARY)
        ret = TLB_NEFile_Open(pszPath, index, &pBase, &dwTLBLength, &pFile);
    if (ret == TYPE_E_CANTLOADLIBRARY)
        ret = TLB_Mapping_Open(pszPath, &pBase, &dwTLBLength, &pFile);
    if (SUCCEEDED(ret))
    {
        if (dwTLBLength >= 4)
        {
            DWORD dwSignature = FromLEDWord(*((DWORD*) pBase));
            if (dwSignature == MSFT_SIGNATURE)
                *ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength);
            else if (dwSignature == SLTG_SIGNATURE)
                *ppTypeLib = ITypeLib2_Constructor_SLTG(pBase, dwTLBLength);
            else
            {
                FIXME("Header type magic 0x%08x not supported.\n",dwSignature);
                ret = TYPE_E_CANTLOADLIBRARY;
            }
        }
        else
            ret = TYPE_E_CANTLOADLIBRARY;
        IUnknown_Release(pFile);
    }

    if(*ppTypeLib) {
	ITypeLibImpl *impl = impl_from_ITypeLib2(*ppTypeLib);

	TRACE("adding to cache\n");
	impl->path = heap_alloc((strlenW(pszPath)+1) * sizeof(WCHAR));
	lstrcpyW(impl->path, pszPath);
	/* We should really canonicalise the path here. */
        impl->index = index;

        /* FIXME: check if it has added already in the meantime */
        EnterCriticalSection(&cache_section);
        list_add_head(&tlb_cache, &impl->entry);
        LeaveCriticalSection(&cache_section);
        ret = S_OK;
    }
    else
    {
        if(ret != E_FAIL)
            ERR("Loading of typelib %s failed with error %d\n", debugstr_w(pszFileName), GetLastError());

        ret = TYPE_E_CANTLOADLIBRARY;
    }


    return ret;
}

/*================== ITypeLib(2) Methods ===================================*/

static ITypeLibImpl* TypeLibImpl_Constructor(void)
{
    ITypeLibImpl* pTypeLibImpl;

    pTypeLibImpl = heap_alloc_zero(sizeof(ITypeLibImpl));
    if (!pTypeLibImpl) return NULL;

    pTypeLibImpl->ITypeLib2_iface.lpVtbl = &tlbvt;
    pTypeLibImpl->ITypeComp_iface.lpVtbl = &tlbtcvt;
    pTypeLibImpl->ICreateTypeLib2_iface.lpVtbl = &CreateTypeLib2Vtbl;
    pTypeLibImpl->ref = 1;

    list_init(&pTypeLibImpl->implib_list);
    list_init(&pTypeLibImpl->custdata_list);
    list_init(&pTypeLibImpl->name_list);
    list_init(&pTypeLibImpl->string_list);
    list_init(&pTypeLibImpl->guid_list);
    list_init(&pTypeLibImpl->ref_list);
    pTypeLibImpl->dispatch_href = -1;

    return pTypeLibImpl;
}

/****************************************************************************
 *	ITypeLib2_Constructor_MSFT
 *
 * loading an MSFT typelib from an in-memory image
 */
static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
{
    TLBContext cx;
    LONG lPSegDir;
    MSFT_Header tlbHeader;
    MSFT_SegDir tlbSegDir;
    ITypeLibImpl * pTypeLibImpl;
    int i;

    TRACE("%p, TLB length = %d\n", pLib, dwTLBLength);

    pTypeLibImpl = TypeLibImpl_Constructor();
    if (!pTypeLibImpl) return NULL;

    /* get pointer to beginning of typelib data */
    cx.pos = 0;
    cx.oStart=0;
    cx.mapping = pLib;
    cx.pLibInfo = pTypeLibImpl;
    cx.length = dwTLBLength;

    /* read header */
    MSFT_ReadLEDWords(&tlbHeader, sizeof(tlbHeader), &cx, 0);
    TRACE_(typelib)("header:\n");
    TRACE_(typelib)("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2 );
    if (tlbHeader.magic1 != MSFT_SIGNATURE) {
	FIXME("Header type magic 0x%08x not supported.\n",tlbHeader.magic1);
	return NULL;
    }
    TRACE_(typelib)("\tdispatchpos = 0x%x\n", tlbHeader.dispatchpos);

    /* there is a small amount of information here until the next important
     * part:
     * the segment directory . Try to calculate the amount of data */
    lPSegDir = sizeof(tlbHeader) + (tlbHeader.nrtypeinfos)*4 + ((tlbHeader.varflags & HELPDLLFLAG)? 4 :0);

    /* now read the segment directory */
    TRACE("read segment directory (at %d)\n",lPSegDir);
    MSFT_ReadLEDWords(&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
    cx.pTblDir = &tlbSegDir;

    /* just check two entries */
    if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F || tlbSegDir.pImpInfo.res0c != 0x0F)
    {
        ERR("cannot find the table directory, ptr=0x%x\n",lPSegDir);
	heap_free(pTypeLibImpl);
	return NULL;
    }

    MSFT_ReadAllNames(&cx);
    MSFT_ReadAllStrings(&cx);
    MSFT_ReadAllGuids(&cx);

    /* now fill our internal data */
    /* TLIBATTR fields */
    pTypeLibImpl->guid = MSFT_ReadGuid(tlbHeader.posguid, &cx);

    pTypeLibImpl->syskind = tlbHeader.varflags & 0x0f; /* check the mask */
    pTypeLibImpl->ptr_size = get_ptr_size(pTypeLibImpl->syskind);
    pTypeLibImpl->ver_major = LOWORD(tlbHeader.version);
    pTypeLibImpl->ver_minor = HIWORD(tlbHeader.version);
    pTypeLibImpl->libflags = ((WORD) tlbHeader.flags & 0xffff) /* check mask */ | LIBFLAG_FHASDISKIMAGE;

    pTypeLibImpl->set_lcid = tlbHeader.lcid2;
    pTypeLibImpl->lcid = tlbHeader.lcid;

    /* name, eventually add to a hash table */
    pTypeLibImpl->Name = MSFT_ReadName(&cx, tlbHeader.NameOffset);

    /* help info */
    pTypeLibImpl->DocString = MSFT_ReadString(&cx, tlbHeader.helpstring);
    pTypeLibImpl->HelpFile = MSFT_ReadString(&cx, tlbHeader.helpfile);

    if( tlbHeader.varflags & HELPDLLFLAG)
    {
            int offset;
            MSFT_ReadLEDWords(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
            pTypeLibImpl->HelpStringDll = MSFT_ReadString(&cx, offset);
    }

    pTypeLibImpl->dwHelpContext = tlbHeader.helpstringcontext;

    /* custom data */
    if(tlbHeader.CustomDataOffset >= 0)
    {
        MSFT_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->custdata_list);
    }

    /* fill in type descriptions */
    if(tlbSegDir.pTypdescTab.length > 0)
    {
        int i, j, cTD = tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
        INT16 td[4];
        pTypeLibImpl->ctTypeDesc = cTD;
        pTypeLibImpl->pTypeDesc = heap_alloc_zero( cTD * sizeof(TYPEDESC));
        MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
        for(i=0; i<cTD; )
	{
            /* FIXME: add several sanity checks here */
            pTypeLibImpl->pTypeDesc[i].vt = td[0] & VT_TYPEMASK;
            if(td[0] == VT_PTR || td[0] == VT_SAFEARRAY)
	    {
	        /* FIXME: check safearray */
                if(td[3] < 0)
                    pTypeLibImpl->pTypeDesc[i].u.lptdesc = &std_typedesc[td[2]];
                else
                    pTypeLibImpl->pTypeDesc[i].u.lptdesc = &pTypeLibImpl->pTypeDesc[td[2]/8];
            }
	    else if(td[0] == VT_CARRAY)
            {
	        /* array descr table here */
	        pTypeLibImpl->pTypeDesc[i].u.lpadesc = (void *)(INT_PTR)td[2];  /* temp store offset in*/
            }
            else if(td[0] == VT_USERDEFINED)
	    {
                pTypeLibImpl->pTypeDesc[i].u.hreftype = MAKELONG(td[2],td[3]);
            }
	    if(++i<cTD) MSFT_ReadLEWords(td, sizeof(td), &cx, DO_NOT_SEEK);
        }

        /* second time around to fill the array subscript info */
        for(i=0;i<cTD;i++)
	{
            if(pTypeLibImpl->pTypeDesc[i].vt != VT_CARRAY) continue;
            if(tlbSegDir.pArrayDescriptions.offset>0)
	    {
                MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (INT_PTR)pTypeLibImpl->pTypeDesc[i].u.lpadesc);
                pTypeLibImpl->pTypeDesc[i].u.lpadesc = heap_alloc_zero(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));

                if(td[1]<0)
                    pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem.vt = td[0] & VT_TYPEMASK;
                else
                    pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem = cx.pLibInfo->pTypeDesc[td[0]/(2*sizeof(INT))];

                pTypeLibImpl->pTypeDesc[i].u.lpadesc->cDims = td[2];

                for(j = 0; j<td[2]; j++)
		{
                    MSFT_ReadLEDWords(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].cElements,
                                      sizeof(INT), &cx, DO_NOT_SEEK);
                    MSFT_ReadLEDWords(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].lLbound,
                                      sizeof(INT), &cx, DO_NOT_SEEK);
                }
            }
	    else
	    {
                pTypeLibImpl->pTypeDesc[i].u.lpadesc = NULL;
                ERR("didn't find array description data\n");
            }
        }
    }

    /* imported type libs */
    if(tlbSegDir.pImpFiles.offset>0)
    {
        TLBImpLib *pImpLib;
        int oGuid, offset = tlbSegDir.pImpFiles.offset;
        UINT16 size;

        while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length)
	{
            char *name;

            pImpLib = heap_alloc_zero(sizeof(TLBImpLib));
            pImpLib->offset = offset - tlbSegDir.pImpFiles.offset;
            MSFT_ReadLEDWords(&oGuid, sizeof(INT), &cx, offset);

            MSFT_ReadLEDWords(&pImpLib->lcid,         sizeof(LCID),   &cx, DO_NOT_SEEK);
            MSFT_ReadLEWords(&pImpLib->wVersionMajor, sizeof(WORD),   &cx, DO_NOT_SEEK);
            MSFT_ReadLEWords(&pImpLib->wVersionMinor, sizeof(WORD),   &cx, DO_NOT_SEEK);
            MSFT_ReadLEWords(& size,                      sizeof(UINT16), &cx, DO_NOT_SEEK);

            size >>= 2;
            name = heap_alloc_zero(size+1);
            MSFT_Read(name, size, &cx, DO_NOT_SEEK);
            pImpLib->name = TLB_MultiByteToBSTR(name);
            heap_free(name);

            pImpLib->guid = MSFT_ReadGuid(oGuid, &cx);
            offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & ~3;

            list_add_tail(&pTypeLibImpl->implib_list, &pImpLib->entry);
        }
    }

    MSFT_ReadAllRefs(&cx);

    pTypeLibImpl->dispatch_href = tlbHeader.dispatchpos;

    /* type infos */
    if(tlbHeader.nrtypeinfos >= 0 )
    {
        ITypeInfoImpl **ppTI;

        ppTI = pTypeLibImpl->typeinfos = heap_alloc_zero(sizeof(ITypeInfoImpl*) * tlbHeader.nrtypeinfos);

        for(i = 0; i < tlbHeader.nrtypeinfos; i++)
        {
            *ppTI = MSFT_DoTypeInfo(&cx, i, pTypeLibImpl);

            ++ppTI;
            (pTypeLibImpl->TypeInfoCount)++;
        }
    }

#ifdef _WIN64
    if(pTypeLibImpl->syskind == SYS_WIN32){
        for(i = 0; i < pTypeLibImpl->TypeInfoCount; ++i)
            TLB_fix_32on64_typeinfo(pTypeLibImpl->typeinfos[i]);
    }
#endif

    TRACE("(%p)\n", pTypeLibImpl);
    return &pTypeLibImpl->ITypeLib2_iface;
}


static BOOL TLB_GUIDFromString(const char *str, GUID *guid)
{
  char b[3];
  int i;
  short s;

  if(sscanf(str, "%x-%hx-%hx-%hx", &guid->Data1, &guid->Data2, &guid->Data3, &s) != 4) {
    FIXME("Can't parse guid %s\n", debugstr_guid(guid));
    return FALSE;
  }

  guid->Data4[0] = s >> 8;
  guid->Data4[1] = s & 0xff;

  b[2] = '\0';
  for(i = 0; i < 6; i++) {
    memcpy(b, str + 24 + 2 * i, 2);
    guid->Data4[i + 2] = strtol(b, NULL, 16);
  }
  return TRUE;
}

static WORD SLTG_ReadString(const char *ptr, const TLBString **pStr, ITypeLibImpl *lib)
{
    WORD bytelen;
    DWORD len;
    BSTR tmp_str;

    *pStr = NULL;
    bytelen = *(const WORD*)ptr;
    if(bytelen == 0xffff) return 2;

    len = MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, NULL, 0);
    tmp_str = SysAllocStringLen(NULL, len);
    if (tmp_str) {
        MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, tmp_str, len);
        *pStr = TLB_append_str(&lib->string_list, tmp_str);
        SysFreeString(tmp_str);
    }
    return bytelen + 2;
}

static WORD SLTG_ReadStringA(const char *ptr, char **str)
{
    WORD bytelen;

    *str = NULL;
    bytelen = *(const WORD*)ptr;
    if(bytelen == 0xffff) return 2;
    *str = heap_alloc(bytelen + 1);
    memcpy(*str, ptr + 2, bytelen);
    (*str)[bytelen] = '\0';
    return bytelen + 2;
}

static TLBString *SLTG_ReadName(const char *pNameTable, int offset, ITypeLibImpl *lib)
{
    BSTR tmp_str;
    TLBString *tlbstr;

    LIST_FOR_EACH_ENTRY(tlbstr, &lib->name_list, TLBString, entry) {
        if (tlbstr->offset == offset)
            return tlbstr;
    }

    tmp_str = TLB_MultiByteToBSTR(pNameTable + offset);
    tlbstr = TLB_append_str(&lib->name_list, tmp_str);
    SysFreeString(tmp_str);

    return tlbstr;
}

static DWORD SLTG_ReadLibBlk(LPVOID pLibBlk, ITypeLibImpl *pTypeLibImpl)
{
    char *ptr = pLibBlk;
    WORD w;

    if((w = *(WORD*)ptr) != SLTG_LIBBLK_MAGIC) {
        FIXME("libblk magic = %04x\n", w);
	return 0;
    }

    ptr += 6;
    if((w = *(WORD*)ptr) != 0xffff) {
        FIXME("LibBlk.res06 = %04x. Assumung string and skipping\n", w);
        ptr += w;
    }
    ptr += 2;

    ptr += SLTG_ReadString(ptr, &pTypeLibImpl->DocString, pTypeLibImpl);

    ptr += SLTG_ReadString(ptr, &pTypeLibImpl->HelpFile, pTypeLibImpl);

    pTypeLibImpl->dwHelpContext = *(DWORD*)ptr;
    ptr += 4;

    pTypeLibImpl->syskind = *(WORD*)ptr;
    pTypeLibImpl->ptr_size = get_ptr_size(pTypeLibImpl->syskind);
    ptr += 2;

    if(SUBLANGID(*(WORD*)ptr) == SUBLANG_NEUTRAL)
        pTypeLibImpl->lcid = pTypeLibImpl->set_lcid = MAKELCID(MAKELANGID(PRIMARYLANGID(*(WORD*)ptr),0),0);
    else
        pTypeLibImpl->lcid = pTypeLibImpl->set_lcid = 0;
    ptr += 2;

    ptr += 4; /* skip res12 */

    pTypeLibImpl->libflags = *(WORD*)ptr;
    ptr += 2;

    pTypeLibImpl->ver_major = *(WORD*)ptr;
    ptr += 2;

    pTypeLibImpl->ver_minor = *(WORD*)ptr;
    ptr += 2;

    pTypeLibImpl->guid = TLB_append_guid(&pTypeLibImpl->guid_list, (GUID*)ptr, -2);
    ptr += sizeof(GUID);

    return ptr - (char*)pLibBlk;
}

/* stores a mapping between the sltg typeinfo's references and the typelib's HREFTYPEs */
typedef struct
{
    unsigned int num;
    HREFTYPE refs[1];
} sltg_ref_lookup_t;

static HRESULT sltg_get_typelib_ref(const sltg_ref_lookup_t *table, DWORD typeinfo_ref,
				    HREFTYPE *typelib_ref)
{
    if(table && typeinfo_ref < table->num)
    {
        *typelib_ref = table->refs[typeinfo_ref];
        return S_OK;
    }

    ERR_(typelib)("Unable to find reference\n");
    *typelib_ref = -1;
    return E_FAIL;
}

static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD, const sltg_ref_lookup_t *ref_lookup)
{
    BOOL done = FALSE;

    while(!done) {
        if((*pType & 0xe00) == 0xe00) {
	    pTD->vt = VT_PTR;
	    pTD->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC));
	    pTD = pTD->u.lptdesc;
	}
	switch(*pType & 0x3f) {
	case VT_PTR:
	    pTD->vt = VT_PTR;
	    pTD->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC));
	    pTD = pTD->u.lptdesc;
	    break;

	case VT_USERDEFINED:
	    pTD->vt = VT_USERDEFINED;
            sltg_get_typelib_ref(ref_lookup, *(++pType) / 4, &pTD->u.hreftype);
	    done = TRUE;
	    break;

	case VT_CARRAY:
	  {
	    /* *(pType+1) is offset to a SAFEARRAY, *(pType+2) is type of
	       array */

	    SAFEARRAY *pSA = (SAFEARRAY *)(pBlk + *(++pType));

	    pTD->vt = VT_CARRAY;
	    pTD->u.lpadesc = heap_alloc_zero(sizeof(ARRAYDESC) + (pSA->cDims - 1) * sizeof(SAFEARRAYBOUND));
	    pTD->u.lpadesc->cDims = pSA->cDims;
	    memcpy(pTD->u.lpadesc->rgbounds, pSA->rgsabound,
		   pSA->cDims * sizeof(SAFEARRAYBOUND));

	    pTD = &pTD->u.lpadesc->tdescElem;
	    break;
	  }

	case VT_SAFEARRAY:
	  {
	    /* FIXME: *(pType+1) gives an offset to SAFEARRAY, is this
	       useful? */

	    pType++;
	    pTD->vt = VT_SAFEARRAY;
	    pTD->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC));
	    pTD = pTD->u.lptdesc;
	    break;
	  }
	default:
	    pTD->vt = *pType & 0x3f;
	    done = TRUE;
	    break;
	}
	pType++;
    }
    return pType;
}

static WORD *SLTG_DoElem(WORD *pType, char *pBlk,
			 ELEMDESC *pElem, const sltg_ref_lookup_t *ref_lookup)
{
    /* Handle [in/out] first */
    if((*pType & 0xc000) == 0xc000)
        pElem->u.paramdesc.wParamFlags = PARAMFLAG_NONE;
    else if(*pType & 0x8000)
        pElem->u.paramdesc.wParamFlags = PARAMFLAG_FIN | PARAMFLAG_FOUT;
    else if(*pType & 0x4000)
        pElem->u.paramdesc.wParamFlags = PARAMFLAG_FOUT;
    else
        pElem->u.paramdesc.wParamFlags = PARAMFLAG_FIN;

    if(*pType & 0x2000)
        pElem->u.paramdesc.wParamFlags |= PARAMFLAG_FLCID;

    if(*pType & 0x80)
        pElem->u.paramdesc.wParamFlags |= PARAMFLAG_FRETVAL;

    return SLTG_DoType(pType, pBlk, &pElem->tdesc, ref_lookup);
}


static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL,
			char *pNameTable)
{
    unsigned int ref;
    char *name;
    TLBRefType *ref_type;
    sltg_ref_lookup_t *table;
    HREFTYPE typelib_ref;

    if(pRef->magic != SLTG_REF_MAGIC) {
        FIXME("Ref magic = %x\n", pRef->magic);
	return NULL;
    }
    name = ( (char*)pRef->names + pRef->number);

    table = heap_alloc(sizeof(*table) + ((pRef->number >> 3) - 1) * sizeof(table->refs[0]));
    table->num = pRef->number >> 3;

    /* FIXME should scan the existing list and reuse matching refs added by previous typeinfos */

    /* We don't want the first href to be 0 */
    typelib_ref = (list_count(&pTL->ref_list) + 1) << 2;

    for(ref = 0; ref < pRef->number >> 3; ref++) {
        char *refname;
	unsigned int lib_offs, type_num;

	ref_type = heap_alloc_zero(sizeof(TLBRefType));

	name += SLTG_ReadStringA(name, &refname);
	if(sscanf(refname, "*\\R%x*#%x", &lib_offs, &type_num) != 2)
	    FIXME_(typelib)("Can't sscanf ref\n");
	if(lib_offs != 0xffff) {
	    TLBImpLib *import;

            LIST_FOR_EACH_ENTRY(import, &pTL->implib_list, TLBImpLib, entry)
                if(import->offset == lib_offs)
                    break;

            if(&import->entry == &pTL->implib_list) {
	        char fname[MAX_PATH+1];
		int len;
                GUID tmpguid;

		import = heap_alloc_zero(sizeof(*import));
		import->offset = lib_offs;
		TLB_GUIDFromString( pNameTable + lib_offs + 4, &tmpguid);
                import->guid = TLB_append_guid(&pTL->guid_list, &tmpguid, 2);
		if(sscanf(pNameTable + lib_offs + 40, "}#%hd.%hd#%x#%s",
			  &import->wVersionMajor,
			  &import->wVersionMinor,
			  &import->lcid, fname) != 4) {
		  FIXME_(typelib)("can't sscanf ref %s\n",
			pNameTable + lib_offs + 40);
		}
		len = strlen(fname);
		if(fname[len-1] != '#')
		    FIXME("fname = %s\n", fname);
		fname[len-1] = '\0';
		import->name = TLB_MultiByteToBSTR(fname);
		list_add_tail(&pTL->implib_list, &import->entry);
	    }
	    ref_type->pImpTLInfo = import;

            /* Store a reference to IDispatch */
            if(pTL->dispatch_href == -1 && IsEqualGUID(&import->guid->guid, &IID_StdOle) && type_num == 4)
                pTL->dispatch_href = typelib_ref;

	} else { /* internal ref */
	  ref_type->pImpTLInfo = TLB_REF_INTERNAL;
	}
	ref_type->reference = typelib_ref;
	ref_type->index = type_num;

	heap_free(refname);
        list_add_tail(&pTL->ref_list, &ref_type->entry);

        table->refs[ref] = typelib_ref;
        typelib_ref += 4;
    }
    if((BYTE)*name != SLTG_REF_MAGIC)
      FIXME_(typelib)("End of ref block magic = %x\n", *name);
    dump_TLBRefType(pTL);
    return table;
}

static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
			  BOOL OneOnly, const sltg_ref_lookup_t *ref_lookup)
{
    SLTG_ImplInfo *info;
    TLBImplType *pImplType;
    /* I don't really get this structure, usually it's 0x16 bytes
       long, but iuser.tlb contains some that are 0x18 bytes long.
       That's ok because we can use the next ptr to jump to the next
       one. But how do we know the length of the last one?  The WORD
       at offs 0x8 might be the clue.  For now I'm just assuming that
       the last one is the regular 0x16 bytes. */

    info = (SLTG_ImplInfo*)pBlk;
    while(1){
        pTI->typeattr.cImplTypes++;
        if(info->next == 0xffff)
            break;
        info = (SLTG_ImplInfo*)(pBlk + info->next);
    }

    info = (SLTG_ImplInfo*)pBlk;
    pTI->impltypes = TLBImplType_Alloc(pTI->typeattr.cImplTypes);
    pImplType = pTI->impltypes;
    while(1) {
	sltg_get_typelib_ref(ref_lookup, info->ref, &pImplType->hRef);
	pImplType->implflags = info->impltypeflags;
	++pImplType;

	if(info->next == 0xffff)
	    break;
	if(OneOnly)
	    FIXME_(typelib)("Interface inheriting more than one interface\n");
	info = (SLTG_ImplInfo*)(pBlk + info->next);
    }
    info++; /* see comment at top of function */
    return (char*)info;
}

static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars,
			const char *pNameTable, const sltg_ref_lookup_t *ref_lookup)
{
  TLBVarDesc *pVarDesc;
  const TLBString *prevName = NULL;
  SLTG_Variable *pItem;
  unsigned short i;
  WORD *pType;

  pVarDesc = pTI->vardescs = TLBVarDesc_Alloc(cVars);

  for(pItem = (SLTG_Variable *)pFirstItem, i = 0; i < cVars;
      pItem = (SLTG_Variable *)(pBlk + pItem->next), i++, ++pVarDesc) {

      pVarDesc->vardesc.memid = pItem->memid;

      if (pItem->magic != SLTG_VAR_MAGIC &&
          pItem->magic != SLTG_VAR_WITH_FLAGS_MAGIC) {
	  FIXME_(typelib)("var magic = %02x\n", pItem->magic);
	  return;
      }

      if (pItem->name == 0xfffe)
        pVarDesc->Name = prevName;
      else
        pVarDesc->Name = SLTG_ReadName(pNameTable, pItem->name, pTI->pTypeLib);

      TRACE_(typelib)("name: %s\n", debugstr_w(TLB_get_bstr(pVarDesc->Name)));
      TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs);
      TRACE_(typelib)("memid = 0x%x\n", pItem->memid);

      if(pItem->flags & 0x02)
	  pType = &pItem->type;
      else
	  pType = (WORD*)(pBlk + pItem->type);

      if (pItem->flags & ~0xda)
        FIXME_(typelib)("unhandled flags = %02x\n", pItem->flags & ~0xda);

      SLTG_DoElem(pType, pBlk,
		  &pVarDesc->vardesc.elemdescVar, ref_lookup);

      if (TRACE_ON(typelib)) {
          char buf[300];
          dump_TypeDesc(&pVarDesc->vardesc.elemdescVar.tdesc, buf);
          TRACE_(typelib)("elemdescVar: %s\n", buf);
      }

      if (pItem->flags & 0x40) {
        TRACE_(typelib)("VAR_DISPATCH\n");
        pVarDesc->vardesc.varkind = VAR_DISPATCH;
      }
      else if (pItem->flags & 0x10) {
        TRACE_(typelib)("VAR_CONST\n");
        pVarDesc->vardesc.varkind = VAR_CONST;
        pVarDesc->vardesc.u.lpvarValue = heap_alloc(sizeof(VARIANT));
        V_VT(pVarDesc->vardesc.u.lpvarValue) = VT_INT;
        if (pItem->flags & 0x08)
          V_INT(pVarDesc->vardesc.u.lpvarValue) = pItem->byte_offs;
        else {
          switch (pVarDesc->vardesc.elemdescVar.tdesc.vt)
          {
            case VT_LPSTR:
            case VT_LPWSTR:
            case VT_BSTR:
            {
              WORD len = *(WORD *)(pBlk + pItem->byte_offs);
              BSTR str;
              TRACE_(typelib)("len = %u\n", len);
              if (len == 0xffff) {
                str = NULL;
              } else {
                INT alloc_len = MultiByteToWideChar(CP_ACP, 0, pBlk + pItem->byte_offs + 2, len, NULL, 0);
                str = SysAllocStringLen(NULL, alloc_len);
                MultiByteToWideChar(CP_ACP, 0, pBlk + pItem->byte_offs + 2, len, str, alloc_len);
              }
              V_VT(pVarDesc->vardesc.u.lpvarValue) = VT_BSTR;
              V_BSTR(pVarDesc->vardesc.u.lpvarValue) = str;
              break;
            }
            case VT_I2:
            case VT_UI2:
            case VT_I4:
            case VT_UI4:
            case VT_INT:
            case VT_UINT:
              V_INT(pVarDesc->vardesc.u.lpvarValue) =
                *(INT*)(pBlk + pItem->byte_offs);
              break;
            default:
              FIXME_(typelib)("VAR_CONST unimplemented for type %d\n", pVarDesc->vardesc.elemdescVar.tdesc.vt);
          }
        }
      }
      else {
        TRACE_(typelib)("VAR_PERINSTANCE\n");
        pVarDesc->vardesc.u.oInst = pItem->byte_offs;
        pVarDesc->vardesc.varkind = VAR_PERINSTANCE;
      }

      if (pItem->magic == SLTG_VAR_WITH_FLAGS_MAGIC)
        pVarDesc->vardesc.wVarFlags = pItem->varflags;

      if (pItem->flags & 0x80)
        pVarDesc->vardesc.wVarFlags |= VARFLAG_FREADONLY;

      prevName = pVarDesc->Name;
  }
  pTI->typeattr.cVars = cVars;
}

static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
			 unsigned short cFuncs, char *pNameTable, const sltg_ref_lookup_t *ref_lookup)
{
    SLTG_Function *pFunc;
    unsigned short i;
    TLBFuncDesc *pFuncDesc;

    pTI->funcdescs = TLBFuncDesc_Alloc(cFuncs);

    pFuncDesc = pTI->funcdescs;
    for(pFunc = (SLTG_Function*)pFirstItem, i = 0; i < cFuncs && pFunc != (SLTG_Function*)0xFFFF;
	pFunc = (SLTG_Function*)(pBlk + pFunc->next), i++, ++pFuncDesc) {

        int param;
	WORD *pType, *pArg;

        switch (pFunc->magic & ~SLTG_FUNCTION_FLAGS_PRESENT) {
        case SLTG_FUNCTION_MAGIC:
            pFuncDesc->funcdesc.funckind = FUNC_PUREVIRTUAL;
            break;
        case SLTG_DISPATCH_FUNCTION_MAGIC:
            pFuncDesc->funcdesc.funckind = FUNC_DISPATCH;
            break;
        case SLTG_STATIC_FUNCTION_MAGIC:
            pFuncDesc->funcdesc.funckind = FUNC_STATIC;
            break;
        default:
	    FIXME("unimplemented func magic = %02x\n", pFunc->magic & ~SLTG_FUNCTION_FLAGS_PRESENT);
	    continue;
	}
	pFuncDesc->Name = SLTG_ReadName(pNameTable, pFunc->name, pTI->pTypeLib);

	pFuncDesc->funcdesc.memid = pFunc->dispid;
	pFuncDesc->funcdesc.invkind = pFunc->inv >> 4;
	pFuncDesc->funcdesc.callconv = pFunc->nacc & 0x7;
	pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3;
	pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1;
	pFuncDesc->funcdesc.oVft = pFunc->vtblpos & ~1;

	if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT)
	    pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags;

	if(pFunc->retnextopt & 0x80)
	    pType = &pFunc->rettype;
	else
	    pType = (WORD*)(pBlk + pFunc->rettype);

	SLTG_DoElem(pType, pBlk, &pFuncDesc->funcdesc.elemdescFunc, ref_lookup);

	pFuncDesc->funcdesc.lprgelemdescParam =
	  heap_alloc_zero(pFuncDesc->funcdesc.cParams * sizeof(ELEMDESC));
	pFuncDesc->pParamDesc = TLBParDesc_Constructor(pFuncDesc->funcdesc.cParams);

	pArg = (WORD*)(pBlk + pFunc->arg_off);

	for(param = 0; param < pFuncDesc->funcdesc.cParams; param++) {
	    char *paramName = pNameTable + *pArg;
	    BOOL HaveOffs;
	    /* If arg type follows then paramName points to the 2nd
	       letter of the name, else the next WORD is an offset to
	       the arg type and paramName points to the first letter.
	       So let's take one char off paramName and see if we're
	       pointing at an alpha-numeric char.  However if *pArg is
	       0xffff or 0xfffe then the param has no name, the former
	       meaning that the next WORD is the type, the latter
	       meaning that the next WORD is an offset to the type. */

	    HaveOffs = FALSE;
	    if(*pArg == 0xffff)
	        paramName = NULL;
	    else if(*pArg == 0xfffe) {
	        paramName = NULL;
		HaveOffs = TRUE;
	    }
	    else if(paramName[-1] && !isalnum(paramName[-1]))
	        HaveOffs = TRUE;

	    pArg++;

	    if(HaveOffs) { /* the next word is an offset to type */
	        pType = (WORD*)(pBlk + *pArg);
		SLTG_DoElem(pType, pBlk,
			    &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
		pArg++;
	    } else {
		if(paramName)
		  paramName--;
		pArg = SLTG_DoElem(pArg, pBlk,
                                   &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
	    }

	    /* Are we an optional param ? */
	    if(pFuncDesc->funcdesc.cParams - param <=
	       pFuncDesc->funcdesc.cParamsOpt)
	      pFuncDesc->funcdesc.lprgelemdescParam[param].u.paramdesc.wParamFlags |= PARAMFLAG_FOPT;

	    if(paramName) {
	        pFuncDesc->pParamDesc[param].Name = SLTG_ReadName(pNameTable,
	                paramName - pNameTable, pTI->pTypeLib);
	    } else {
	        pFuncDesc->pParamDesc[param].Name = pFuncDesc->Name;
	    }
	}
    }
    pTI->typeattr.cFuncs = cFuncs;
}

static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI,
				char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
				SLTG_TypeInfoTail *pTITail)
{
    char *pFirstItem;
    sltg_ref_lookup_t *ref_lookup = NULL;

    if(pTIHeader->href_table != 0xffffffff) {
        ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
		    pNameTable);
    }

    pFirstItem = pBlk;

    if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) {
        SLTG_DoImpls(pFirstItem, pTI, FALSE, ref_lookup);
    }
    heap_free(ref_lookup);
}


static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI,
				  char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
				  const SLTG_TypeInfoTail *pTITail)
{
    char *pFirstItem;
    sltg_ref_lookup_t *ref_lookup = NULL;

    if(pTIHeader->href_table != 0xffffffff) {
        ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
		    pNameTable);
    }

    pFirstItem = pBlk;

    if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) {
        SLTG_DoImpls(pFirstItem, pTI, TRUE, ref_lookup);
    }

    if (pTITail->funcs_off != 0xffff)
        SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);

    heap_free(ref_lookup);

    if (TRACE_ON(typelib))
        dump_TLBFuncDesc(pTI->funcdescs, pTI->typeattr.cFuncs);
}

static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI,
			       const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
			       const SLTG_TypeInfoTail *pTITail)
{
  SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL);
}

static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
			      char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
			      const SLTG_TypeInfoTail *pTITail)
{
  WORD *pType;
  sltg_ref_lookup_t *ref_lookup = NULL;

  if (pTITail->simple_alias) {
      /* if simple alias, no more processing required */
      pTI->tdescAlias = heap_alloc_zero(sizeof(TYPEDESC));
      pTI->tdescAlias->vt = pTITail->tdescalias_vt;
      return;
  }

  if(pTIHeader->href_table != 0xffffffff) {
      ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
		  pNameTable);
  }

  /* otherwise it is an offset to a type */
  pType = (WORD *)(pBlk + pTITail->tdescalias_vt);

  pTI->tdescAlias = heap_alloc(sizeof(TYPEDESC));
  SLTG_DoType(pType, pBlk, pTI->tdescAlias, ref_lookup);

  heap_free(ref_lookup);
}

static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
				 char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
				 const SLTG_TypeInfoTail *pTITail)
{
  sltg_ref_lookup_t *ref_lookup = NULL;
  if (pTIHeader->href_table != 0xffffffff)
      ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
                                  pNameTable);

  if (pTITail->vars_off != 0xffff)
    SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup);

  if (pTITail->funcs_off != 0xffff)
    SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);

  if (pTITail->impls_off != 0xffff)
    SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup);

  /* this is necessary to cope with MSFT typelibs that set cFuncs to the number
   * of dispinterface functions including the IDispatch ones, so
   * ITypeInfo::GetFuncDesc takes the real value for cFuncs from cbSizeVft */
  pTI->typeattr.cbSizeVft = pTI->typeattr.cFuncs * pTI->pTypeLib->ptr_size;

  heap_free(ref_lookup);
  if (TRACE_ON(typelib))
      dump_TLBFuncDesc(pTI->funcdescs, pTI->typeattr.cFuncs);
}

static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI,
			     const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
			     const SLTG_TypeInfoTail *pTITail)
{
  SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL);
}

static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
			       char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
			       const SLTG_TypeInfoTail *pTITail)
{
  sltg_ref_lookup_t *ref_lookup = NULL;
  if (pTIHeader->href_table != 0xffffffff)
      ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
                                  pNameTable);

  if (pTITail->vars_off != 0xffff)
    SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup);

  if (pTITail->funcs_off != 0xffff)
    SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
  heap_free(ref_lookup);
  if (TRACE_ON(typelib))
    dump_TypeInfo(pTI);
}

/* Because SLTG_OtherTypeInfo is such a painful struct, we make a more
   manageable copy of it into this */
typedef struct {
  WORD small_no;
  char *index_name;
  char *other_name;
  WORD res1a;
  WORD name_offs;
  WORD more_bytes;
  char *extra;
  WORD res20;
  DWORD helpcontext;
  WORD res26;
  GUID uuid;
} SLTG_InternalOtherTypeInfo;

/****************************************************************************
 *	ITypeLib2_Constructor_SLTG
 *
 * loading a SLTG typelib from an in-memory image
 */
static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
{
    ITypeLibImpl *pTypeLibImpl;
    SLTG_Header *pHeader;
    SLTG_BlkEntry *pBlkEntry;
    SLTG_Magic *pMagic;
    SLTG_Index *pIndex;
    SLTG_Pad9 *pPad9;
    LPVOID pBlk, pFirstBlk;
    SLTG_LibBlk *pLibBlk;
    SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks;
    char *pAfterOTIBlks = NULL;
    char *pNameTable, *ptr;
    int i;
    DWORD len, order;
    ITypeInfoImpl **ppTypeInfoImpl;

    TRACE_(typelib)("%p, TLB length = %d\n", pLib, dwTLBLength);


    pTypeLibImpl = TypeLibImpl_Constructor();
    if (!pTypeLibImpl) return NULL;

    pHeader = pLib;

    TRACE_(typelib)("header:\n");
    TRACE_(typelib)("\tmagic=0x%08x, file blocks = %d\n", pHeader->SLTG_magic,
	  pHeader->nrOfFileBlks );
    if (pHeader->SLTG_magic != SLTG_SIGNATURE) {
	FIXME_(typelib)("Header type magic 0x%08x not supported.\n",
	      pHeader->SLTG_magic);
	return NULL;
    }

    /* There are pHeader->nrOfFileBlks - 2 TypeInfo records in this typelib */
    pTypeLibImpl->TypeInfoCount = pHeader->nrOfFileBlks - 2;

    /* This points to pHeader->nrOfFileBlks - 1 of SLTG_BlkEntry */
    pBlkEntry = (SLTG_BlkEntry*)(pHeader + 1);

    /* Next we have a magic block */
    pMagic = (SLTG_Magic*)(pBlkEntry + pHeader->nrOfFileBlks - 1);

    /* Let's see if we're still in sync */
    if(memcmp(pMagic->CompObj_magic, SLTG_COMPOBJ_MAGIC,
	      sizeof(SLTG_COMPOBJ_MAGIC))) {
        FIXME_(typelib)("CompObj magic = %s\n", pMagic->CompObj_magic);
	return NULL;
    }
    if(memcmp(pMagic->dir_magic, SLTG_DIR_MAGIC,
	      sizeof(SLTG_DIR_MAGIC))) {
        FIXME_(typelib)("dir magic = %s\n", pMagic->dir_magic);
	return NULL;
    }

    pIndex = (SLTG_Index*)(pMagic+1);

    pPad9 = (SLTG_Pad9*)(pIndex + pTypeLibImpl->TypeInfoCount);

    pFirstBlk = pPad9 + 1;

    /* We'll set up a ptr to the main library block, which is the last one. */

    for(pBlk = pFirstBlk, order = pHeader->first_blk - 1;
	  pBlkEntry[order].next != 0;
	  order = pBlkEntry[order].next - 1) {
       pBlk = (char*)pBlk + pBlkEntry[order].len;
    }
    pLibBlk = pBlk;

    len = SLTG_ReadLibBlk(pLibBlk, pTypeLibImpl);

    /* Now there are 0x40 bytes of 0xffff with the numbers 0 to TypeInfoCount
       interspersed */

    len += 0x40;

    /* And now TypeInfoCount of SLTG_OtherTypeInfo */

    pOtherTypeInfoBlks = heap_alloc_zero(sizeof(*pOtherTypeInfoBlks) * pTypeLibImpl->TypeInfoCount);


    ptr = (char*)pLibBlk + len;

    for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) {
	WORD w, extra;
	len = 0;

	pOtherTypeInfoBlks[i].small_no = *(WORD*)ptr;

	w = *(WORD*)(ptr + 2);
	if(w != 0xffff) {
	    len += w;
	    pOtherTypeInfoBlks[i].index_name = heap_alloc(w+1);
	    memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 4, w);
	    pOtherTypeInfoBlks[i].index_name[w] = '\0';
	}
	w = *(WORD*)(ptr + 4 + len);
	if(w != 0xffff) {
	    TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 6 + len, w));
	    len += w;
	    pOtherTypeInfoBlks[i].other_name = heap_alloc(w+1);
	    memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 6 + len, w);
	    pOtherTypeInfoBlks[i].other_name[w] = '\0';
	}
	pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + len + 6);
	pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + len + 8);
	extra = pOtherTypeInfoBlks[i].more_bytes = *(WORD*)(ptr + 10 + len);
	if(extra) {
	    pOtherTypeInfoBlks[i].extra = heap_alloc(extra);
	    memcpy(pOtherTypeInfoBlks[i].extra, ptr + 12, extra);
	    len += extra;
	}
	pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 12 + len);
	pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 14 + len);
	pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 18 + len);
	memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 20 + len, sizeof(GUID));
	len += sizeof(SLTG_OtherTypeInfo);
	ptr += len;
    }

    pAfterOTIBlks = ptr;

    /* Skip this WORD and get the next DWORD */
    len = *(DWORD*)(pAfterOTIBlks + 2);

    /* Now add this to pLibBLk look at what we're pointing at and
       possibly add 0x20, then add 0x216, sprinkle a bit a magic
       dust and we should be pointing at the beginning of the name
       table */

    pNameTable = (char*)pLibBlk + len;

   switch(*(WORD*)pNameTable) {
   case 0xffff:
       break;
   case 0x0200:
       pNameTable += 0x20;
       break;
   default:
       FIXME_(typelib)("pNameTable jump = %x\n", *(WORD*)pNameTable);
       break;
   }

    pNameTable += 0x216;

    pNameTable += 2;

    TRACE_(typelib)("Library name is %s\n", pNameTable + pLibBlk->name);

    pTypeLibImpl->Name = SLTG_ReadName(pNameTable, pLibBlk->name, pTypeLibImpl);


    /* Hopefully we now have enough ptrs set up to actually read in
       some TypeInfos.  It's not clear which order to do them in, so
       I'll just follow the links along the BlkEntry chain and read
       them in the order in which they are in the file */

    pTypeLibImpl->typeinfos = heap_alloc_zero(pTypeLibImpl->TypeInfoCount * sizeof(ITypeInfoImpl*));
    ppTypeInfoImpl = pTypeLibImpl->typeinfos;

    for(pBlk = pFirstBlk, order = pHeader->first_blk - 1, i = 0;
	pBlkEntry[order].next != 0;
	order = pBlkEntry[order].next - 1, i++) {

      SLTG_TypeInfoHeader *pTIHeader;
      SLTG_TypeInfoTail *pTITail;
      SLTG_MemberHeader *pMemHeader;

      if(strcmp(pBlkEntry[order].index_string + (char*)pMagic, pOtherTypeInfoBlks[i].index_name)) {
        FIXME_(typelib)("Index strings don't match\n");
        heap_free(pOtherTypeInfoBlks);
        return NULL;
      }

      pTIHeader = pBlk;
      if(pTIHeader->magic != SLTG_TIHEADER_MAGIC) {
	FIXME_(typelib)("TypeInfoHeader magic = %04x\n", pTIHeader->magic);
       heap_free(pOtherTypeInfoBlks);
	return NULL;
      }
      TRACE_(typelib)("pTIHeader->res06 = %x, pTIHeader->res0e = %x, "
        "pTIHeader->res16 = %x, pTIHeader->res1e = %x\n",
        pTIHeader->res06, pTIHeader->res0e, pTIHeader->res16, pTIHeader->res1e);

      *ppTypeInfoImpl = ITypeInfoImpl_Constructor();
      (*ppTypeInfoImpl)->pTypeLib = pTypeLibImpl;
      (*ppTypeInfoImpl)->index = i;
      (*ppTypeInfoImpl)->Name = SLTG_ReadName(pNameTable, pOtherTypeInfoBlks[i].name_offs, pTypeLibImpl);
      (*ppTypeInfoImpl)->dwHelpContext = pOtherTypeInfoBlks[i].helpcontext;
      (*ppTypeInfoImpl)->guid = TLB_append_guid(&pTypeLibImpl->guid_list, &pOtherTypeInfoBlks[i].uuid, 2);
      (*ppTypeInfoImpl)->typeattr.typekind = pTIHeader->typekind;
      (*ppTypeInfoImpl)->typeattr.wMajorVerNum = pTIHeader->major_version;
      (*ppTypeInfoImpl)->typeattr.wMinorVerNum = pTIHeader->minor_version;
      (*ppTypeInfoImpl)->typeattr.wTypeFlags =
	(pTIHeader->typeflags1 >> 3) | (pTIHeader->typeflags2 << 5);

      if((*ppTypeInfoImpl)->typeattr.wTypeFlags & TYPEFLAG_FDUAL)
	(*ppTypeInfoImpl)->typeattr.typekind = TKIND_DISPATCH;

      if((pTIHeader->typeflags1 & 7) != 2)
	FIXME_(typelib)("typeflags1 = %02x\n", pTIHeader->typeflags1);
      if(pTIHeader->typeflags3 != 2)
	FIXME_(typelib)("typeflags3 = %02x\n", pTIHeader->typeflags3);

      TRACE_(typelib)("TypeInfo %s of kind %s guid %s typeflags %04x\n",
	    debugstr_w(TLB_get_bstr((*ppTypeInfoImpl)->Name)),
	    typekind_desc[pTIHeader->typekind],
	    debugstr_guid(TLB_get_guidref((*ppTypeInfoImpl)->guid)),
	    (*ppTypeInfoImpl)->typeattr.wTypeFlags);

      pMemHeader = (SLTG_MemberHeader*)((char *)pBlk + pTIHeader->elem_table);

      pTITail = (SLTG_TypeInfoTail*)((char *)(pMemHeader + 1) + pMemHeader->cbExtra);

      (*ppTypeInfoImpl)->typeattr.cbAlignment = pTITail->cbAlignment;
      (*ppTypeInfoImpl)->typeattr.cbSizeInstance = pTITail->cbSizeInstance;
      (*ppTypeInfoImpl)->typeattr.cbSizeVft = pTITail->cbSizeVft;

      switch(pTIHeader->typekind) {
      case TKIND_ENUM:
	SLTG_ProcessEnum((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
                         pTIHeader, pTITail);
	break;

      case TKIND_RECORD:
	SLTG_ProcessRecord((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
                           pTIHeader, pTITail);
	break;

      case TKIND_INTERFACE:
	SLTG_ProcessInterface((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
                              pTIHeader, pTITail);
	break;

      case TKIND_COCLASS:
	SLTG_ProcessCoClass((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
                            pTIHeader, pTITail);
	break;

      case TKIND_ALIAS:
	SLTG_ProcessAlias((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
                          pTIHeader, pTITail);
	break;

      case TKIND_DISPATCH:
	SLTG_ProcessDispatch((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
                             pTIHeader, pTITail);
	break;

      case TKIND_MODULE:
	SLTG_ProcessModule((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
                           pTIHeader, pTITail);
	break;

      default:
	FIXME("Not processing typekind %d\n", pTIHeader->typekind);
	break;

      }

      /* could get cFuncs, cVars and cImplTypes from here
		       but we've already set those */
#define X(x) TRACE_(typelib)("tt "#x": %x\n",pTITail->res##x);
      X(06);
      X(16);
      X(18);
      X(1a);
      X(1e);
      X(24);
      X(26);
      X(2a);
      X(2c);
      X(2e);
      X(30);
      X(32);
      X(34);
#undef X
      ++ppTypeInfoImpl;
      pBlk = (char*)pBlk + pBlkEntry[order].len;
    }

    if(i != pTypeLibImpl->TypeInfoCount) {
      FIXME("Somehow processed %d TypeInfos\n", i);
      heap_free(pOtherTypeInfoBlks);
      return NULL;
    }

    heap_free(pOtherTypeInfoBlks);
    return &pTypeLibImpl->ITypeLib2_iface;
}

static HRESULT WINAPI ITypeLib2_fnQueryInterface(ITypeLib2 *iface, REFIID riid, void **ppv)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);

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

    if(IsEqualIID(riid, &IID_IUnknown) ||
       IsEqualIID(riid,&IID_ITypeLib)||
       IsEqualIID(riid,&IID_ITypeLib2))
    {
        *ppv = &This->ITypeLib2_iface;
    }
    else if(IsEqualIID(riid, &IID_ICreateTypeLib) ||
             IsEqualIID(riid, &IID_ICreateTypeLib2))
    {
        *ppv = &This->ICreateTypeLib2_iface;
    }
    else
    {
        *ppv = NULL;
        TRACE("-- Interface: E_NOINTERFACE\n");
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI ITypeLib2_fnAddRef( ITypeLib2 *iface)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if (!ref)
    {
      TLBImpLib *pImpLib, *pImpLibNext;
      TLBRefType *ref_type, *ref_type_next;
      TLBString *tlbstr, *tlbstr_next;
      TLBGuid *tlbguid, *tlbguid_next;
      int i;

      /* remove cache entry */
      if(This->path)
      {
          TRACE("removing from cache list\n");
          EnterCriticalSection(&cache_section);
          if(This->entry.next)
              list_remove(&This->entry);
          LeaveCriticalSection(&cache_section);
          heap_free(This->path);
      }
      TRACE(" destroying ITypeLib(%p)\n",This);

      LIST_FOR_EACH_ENTRY_SAFE(tlbstr, tlbstr_next, &This->string_list, TLBString, entry) {
          list_remove(&tlbstr->entry);
          SysFreeString(tlbstr->str);
          heap_free(tlbstr);
      }

      LIST_FOR_EACH_ENTRY_SAFE(tlbstr, tlbstr_next, &This->name_list, TLBString, entry) {
          list_remove(&tlbstr->entry);
          SysFreeString(tlbstr->str);
          heap_free(tlbstr);
      }

      LIST_FOR_EACH_ENTRY_SAFE(tlbguid, tlbguid_next, &This->guid_list, TLBGuid, entry) {
          list_remove(&tlbguid->entry);
          heap_free(tlbguid);
      }

      TLB_FreeCustData(&This->custdata_list);

      for (i = 0; i < This->ctTypeDesc; i++)
          if (This->pTypeDesc[i].vt == VT_CARRAY)
              heap_free(This->pTypeDesc[i].u.lpadesc);

      heap_free(This->pTypeDesc);

      LIST_FOR_EACH_ENTRY_SAFE(pImpLib, pImpLibNext, &This->implib_list, TLBImpLib, entry)
      {
          if (pImpLib->pImpTypeLib)
              ITypeLib2_Release(&pImpLib->pImpTypeLib->ITypeLib2_iface);
          SysFreeString(pImpLib->name);

          list_remove(&pImpLib->entry);
          heap_free(pImpLib);
      }

      LIST_FOR_EACH_ENTRY_SAFE(ref_type, ref_type_next, &This->ref_list, TLBRefType, entry)
      {
          list_remove(&ref_type->entry);
          heap_free(ref_type);
      }

      for (i = 0; i < This->TypeInfoCount; ++i){
          heap_free(This->typeinfos[i]->tdescAlias);
          ITypeInfoImpl_Destroy(This->typeinfos[i]);
      }
      heap_free(This->typeinfos);
      heap_free(This);
      return 0;
    }

    return ref;
}

/* ITypeLib::GetTypeInfoCount
 *
 * Returns the number of type descriptions in the type library
 */
static UINT WINAPI ITypeLib2_fnGetTypeInfoCount( ITypeLib2 *iface)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);
    TRACE("(%p)->count is %d\n",This, This->TypeInfoCount);
    return This->TypeInfoCount;
}

/* ITypeLib::GetTypeInfo
 *
 * retrieves the specified type description in the library.
 */
static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(
    ITypeLib2 *iface,
    UINT index,
    ITypeInfo **ppTInfo)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);

    TRACE("%p %u %p\n", This, index, ppTInfo);

    if(!ppTInfo)
        return E_INVALIDARG;

    if(index >= This->TypeInfoCount)
        return TYPE_E_ELEMENTNOTFOUND;

    *ppTInfo = (ITypeInfo *)&This->typeinfos[index]->ITypeInfo2_iface;
    ITypeInfo_AddRef(*ppTInfo);

    return S_OK;
}


/* ITypeLibs::GetTypeInfoType
 *
 * Retrieves the type of a type description.
 */
static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType(
    ITypeLib2 *iface,
    UINT index,
    TYPEKIND *pTKind)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);

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

    if(!pTKind)
        return E_INVALIDARG;

    if(index >= This->TypeInfoCount)
        return TYPE_E_ELEMENTNOTFOUND;

    *pTKind = This->typeinfos[index]->typeattr.typekind;

    return S_OK;
}

/* ITypeLib::GetTypeInfoOfGuid
 *
 * Retrieves the type description that corresponds to the specified GUID.
 *
 */
static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(
    ITypeLib2 *iface,
    REFGUID guid,
    ITypeInfo **ppTInfo)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);
    int i;

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

    for(i = 0; i < This->TypeInfoCount; ++i){
        if(IsEqualIID(TLB_get_guid_null(This->typeinfos[i]->guid), guid)){
            *ppTInfo = (ITypeInfo *)&This->typeinfos[i]->ITypeInfo2_iface;
            ITypeInfo_AddRef(*ppTInfo);
            return S_OK;
        }
    }

    return TYPE_E_ELEMENTNOTFOUND;
}

/* ITypeLib::GetLibAttr
 *
 * Retrieves the structure that contains the library's attributes.
 *
 */
static HRESULT WINAPI ITypeLib2_fnGetLibAttr(
	ITypeLib2 *iface,
	LPTLIBATTR *attr)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);

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

    if (!attr) return E_INVALIDARG;

    *attr = heap_alloc(sizeof(**attr));
    if (!*attr) return E_OUTOFMEMORY;

    (*attr)->guid = *TLB_get_guid_null(This->guid);
    (*attr)->lcid = This->set_lcid;
    (*attr)->syskind = This->syskind;
    (*attr)->wMajorVerNum = This->ver_major;
    (*attr)->wMinorVerNum = This->ver_minor;
    (*attr)->wLibFlags = This->libflags;

    return S_OK;
}

/* ITypeLib::GetTypeComp
 *
 * Enables a client compiler to bind to a library's types, variables,
 * constants, and global functions.
 *
 */
static HRESULT WINAPI ITypeLib2_fnGetTypeComp(
	ITypeLib2 *iface,
	ITypeComp **ppTComp)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);

    TRACE("(%p)->(%p)\n",This,ppTComp);
    *ppTComp = &This->ITypeComp_iface;
    ITypeComp_AddRef(*ppTComp);

    return S_OK;
}

/* ITypeLib::GetDocumentation
 *
 * Retrieves the library's documentation string, the complete Help file name
 * and path, and the context identifier for the library Help topic in the Help
 * file.
 *
 * On a successful return all non-null BSTR pointers will have been set,
 * possibly to NULL.
 */
static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
    ITypeLib2 *iface,
    INT index,
    BSTR *pBstrName,
    BSTR *pBstrDocString,
    DWORD *pdwHelpContext,
    BSTR *pBstrHelpFile)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);
    HRESULT result = E_INVALIDARG;
    ITypeInfo *pTInfo;

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

    if(index<0)
    {
        /* documentation for the typelib */
        if(pBstrName)
        {
            if (This->Name)
            {
                if(!(*pBstrName = SysAllocString(TLB_get_bstr(This->Name))))
                    goto memerr1;
            }
            else
                *pBstrName = NULL;
        }
        if(pBstrDocString)
        {
            if (This->DocString)
            {
                if(!(*pBstrDocString = SysAllocString(TLB_get_bstr(This->DocString))))
                    goto memerr2;
            }
            else
                *pBstrDocString = NULL;
        }
        if(pdwHelpContext)
        {
            *pdwHelpContext = This->dwHelpContext;
        }
        if(pBstrHelpFile)
        {
            if (This->HelpFile)
            {
                if(!(*pBstrHelpFile = SysAllocString(TLB_get_bstr(This->HelpFile))))
                    goto memerr3;
            }
            else
                *pBstrHelpFile = NULL;
        }

        result = S_OK;
    }
    else
    {
        /* for a typeinfo */
        result = ITypeLib2_fnGetTypeInfo(iface, index, &pTInfo);

        if(SUCCEEDED(result))
        {
            result = ITypeInfo_GetDocumentation(pTInfo,
                                          MEMBERID_NIL,
                                          pBstrName,
                                          pBstrDocString,
                                          pdwHelpContext, pBstrHelpFile);

            ITypeInfo_Release(pTInfo);
        }
    }
    return result;
memerr3:
    if (pBstrDocString) SysFreeString (*pBstrDocString);
memerr2:
    if (pBstrName) SysFreeString (*pBstrName);
memerr1:
    return STG_E_INSUFFICIENTMEMORY;
}

/* ITypeLib::IsName
 *
 * Indicates whether a passed-in string contains the name of a type or member
 * described in the library.
 *
 */
static HRESULT WINAPI ITypeLib2_fnIsName(
	ITypeLib2 *iface,
	LPOLESTR szNameBuf,
	ULONG lHashVal,
	BOOL *pfName)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);
    int tic;
    UINT nNameBufLen = (lstrlenW(szNameBuf)+1)*sizeof(WCHAR), fdc, vrc;

    TRACE("(%p)->(%s,%08x,%p)\n", This, debugstr_w(szNameBuf), lHashVal,
	  pfName);

    *pfName=TRUE;
    for(tic = 0; tic < This->TypeInfoCount; ++tic){
        ITypeInfoImpl *pTInfo = This->typeinfos[tic];
        if(!TLB_str_memcmp(szNameBuf, pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
        for(fdc = 0; fdc < pTInfo->typeattr.cFuncs; ++fdc) {
            TLBFuncDesc *pFInfo = &pTInfo->funcdescs[fdc];
            int pc;
            if(!TLB_str_memcmp(szNameBuf, pFInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
            for(pc=0; pc < pFInfo->funcdesc.cParams; pc++){
                if(!TLB_str_memcmp(szNameBuf, pFInfo->pParamDesc[pc].Name, nNameBufLen))
                    goto ITypeLib2_fnIsName_exit;
            }
        }
        for(vrc = 0; vrc < pTInfo->typeattr.cVars; ++vrc){
            TLBVarDesc *pVInfo = &pTInfo->vardescs[vrc];
            if(!TLB_str_memcmp(szNameBuf, pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
        }

    }
    *pfName=FALSE;

ITypeLib2_fnIsName_exit:
    TRACE("(%p)slow! search for %s: %sfound!\n", This,
          debugstr_w(szNameBuf), *pfName ? "" : "NOT ");

    return S_OK;
}

/* ITypeLib::FindName
 *
 * Finds occurrences of a type description in a type library. This may be used
 * to quickly verify that a name exists in a type library.
 *
 */
static HRESULT WINAPI ITypeLib2_fnFindName(
	ITypeLib2 *iface,
	LPOLESTR name,
	ULONG hash,
	ITypeInfo **ppTInfo,
	MEMBERID *memid,
	UINT16 *found)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);
    int tic;
    UINT count = 0;
    UINT len;

    TRACE("(%p)->(%s %u %p %p %p)\n", This, debugstr_w(name), hash, ppTInfo, memid, found);

    if ((!name && hash == 0) || !ppTInfo || !memid || !found)
        return E_INVALIDARG;

    len = (lstrlenW(name) + 1)*sizeof(WCHAR);
    for(tic = 0; count < *found && tic < This->TypeInfoCount; ++tic) {
        ITypeInfoImpl *pTInfo = This->typeinfos[tic];
        TLBVarDesc *var;
        UINT fdc;

        if(!TLB_str_memcmp(name, pTInfo->Name, len)) {
            memid[count] = MEMBERID_NIL;
            goto ITypeLib2_fnFindName_exit;
        }

        for(fdc = 0; fdc < pTInfo->typeattr.cFuncs; ++fdc) {
            TLBFuncDesc *func = &pTInfo->funcdescs[fdc];

            if(!TLB_str_memcmp(name, func->Name, len)) {
                memid[count] = func->funcdesc.memid;
                goto ITypeLib2_fnFindName_exit;
            }
        }

        var = TLB_get_vardesc_by_name(pTInfo->vardescs, pTInfo->typeattr.cVars, name);
        if (var) {
            memid[count] = var->vardesc.memid;
            goto ITypeLib2_fnFindName_exit;
        }

        continue;
ITypeLib2_fnFindName_exit:
        ITypeInfo2_AddRef(&pTInfo->ITypeInfo2_iface);
        ppTInfo[count] = (ITypeInfo *)&pTInfo->ITypeInfo2_iface;
        count++;
    }
    TRACE("found %d typeinfos\n", count);

    *found = count;

    return S_OK;
}

/* ITypeLib::ReleaseTLibAttr
 *
 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
 *
 */
static VOID WINAPI ITypeLib2_fnReleaseTLibAttr(
	ITypeLib2 *iface,
	TLIBATTR *pTLibAttr)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);
    TRACE("(%p)->(%p)\n", This, pTLibAttr);
    heap_free(pTLibAttr);
}

/* ITypeLib2::GetCustData
 *
 * gets the custom data
 */
static HRESULT WINAPI ITypeLib2_fnGetCustData(
	ITypeLib2 * iface,
	REFGUID guid,
        VARIANT *pVarVal)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);
    TLBCustData *pCData;

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(guid), pVarVal);

    pCData = TLB_get_custdata_by_guid(&This->custdata_list, guid);
    if(!pCData)
        return TYPE_E_ELEMENTNOTFOUND;

    VariantInit(pVarVal);
    VariantCopy(pVarVal, &pCData->data);

    return S_OK;
}

/* ITypeLib2::GetLibStatistics
 *
 * Returns statistics about a type library that are required for efficient
 * sizing of hash tables.
 *
 */
static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(
	ITypeLib2 * iface,
        ULONG *pcUniqueNames,
	ULONG *pcchUniqueNames)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);

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

    if(pcUniqueNames) *pcUniqueNames=1;
    if(pcchUniqueNames) *pcchUniqueNames=1;
    return S_OK;
}

/* ITypeLib2::GetDocumentation2
 *
 * Retrieves the library's documentation string, the complete Help file name
 * and path, the localization context to use, and the context ID for the
 * library Help topic in the Help file.
 *
 */
static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
	ITypeLib2 * iface,
        INT index,
	LCID lcid,
	BSTR *pbstrHelpString,
        DWORD *pdwHelpStringContext,
	BSTR *pbstrHelpStringDll)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);
    HRESULT result;
    ITypeInfo *pTInfo;

    FIXME("(%p) index %d lcid %d half implemented stub!\n", This, index, lcid);

    /* the help string should be obtained from the helpstringdll,
     * using the _DLLGetDocumentation function, based on the supplied
     * lcid. Nice to do sometime...
     */
    if(index<0)
    {
      /* documentation for the typelib */
      if(pbstrHelpString)
        *pbstrHelpString=SysAllocString(TLB_get_bstr(This->DocString));
      if(pdwHelpStringContext)
        *pdwHelpStringContext=This->dwHelpContext;
      if(pbstrHelpStringDll)
        *pbstrHelpStringDll=SysAllocString(TLB_get_bstr(This->HelpStringDll));

      result = S_OK;
    }
    else
    {
      /* for a typeinfo */
      result=ITypeLib2_GetTypeInfo(iface, index, &pTInfo);

      if(SUCCEEDED(result))
      {
        ITypeInfo2 * pTInfo2;
        result = ITypeInfo_QueryInterface(pTInfo,
                                          &IID_ITypeInfo2,
                                          (LPVOID*) &pTInfo2);

        if(SUCCEEDED(result))
        {
          result = ITypeInfo2_GetDocumentation2(pTInfo2,
                                           MEMBERID_NIL,
                                           lcid,
                                           pbstrHelpString,
                                           pdwHelpStringContext,
                                           pbstrHelpStringDll);

          ITypeInfo2_Release(pTInfo2);
        }

        ITypeInfo_Release(pTInfo);
      }
    }
    return result;
}

static HRESULT TLB_copy_all_custdata(struct list *custdata_list, CUSTDATA *pCustData)
{
    TLBCustData *pCData;
    unsigned int ct;
    CUSTDATAITEM *cdi;

    ct = list_count(custdata_list);

    pCustData->prgCustData = CoTaskMemAlloc(ct * sizeof(CUSTDATAITEM));
    if(!pCustData->prgCustData)
        return E_OUTOFMEMORY;

    pCustData->cCustData = ct;

    cdi = pCustData->prgCustData;
    LIST_FOR_EACH_ENTRY(pCData, custdata_list, TLBCustData, entry){
        cdi->guid = *TLB_get_guid_null(pCData->guid);
        VariantCopy(&cdi->varValue, &pCData->data);
        ++cdi;
    }

    return S_OK;
}


/* ITypeLib2::GetAllCustData
 *
 * Gets all custom data items for the library.
 *
 */
static HRESULT WINAPI ITypeLib2_fnGetAllCustData(
	ITypeLib2 * iface,
        CUSTDATA *pCustData)
{
    ITypeLibImpl *This = impl_from_ITypeLib2(iface);
    TRACE("(%p)->(%p)\n", This, pCustData);
    return TLB_copy_all_custdata(&This->custdata_list, pCustData);
}

static const ITypeLib2Vtbl tlbvt = {
    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 HRESULT WINAPI ITypeLibComp_fnQueryInterface(ITypeComp * iface, REFIID riid, LPVOID * ppv)
{
    ITypeLibImpl *This = impl_from_ITypeComp(iface);

    return ITypeLib2_QueryInterface(&This->ITypeLib2_iface, riid, ppv);
}

static ULONG WINAPI ITypeLibComp_fnAddRef(ITypeComp * iface)
{
    ITypeLibImpl *This = impl_from_ITypeComp(iface);

    return ITypeLib2_AddRef(&This->ITypeLib2_iface);
}

static ULONG WINAPI ITypeLibComp_fnRelease(ITypeComp * iface)
{
    ITypeLibImpl *This = impl_from_ITypeComp(iface);

    return ITypeLib2_Release(&This->ITypeLib2_iface);
}

static HRESULT WINAPI ITypeLibComp_fnBind(
    ITypeComp * iface,
    OLECHAR * szName,
    ULONG lHash,
    WORD wFlags,
    ITypeInfo ** ppTInfo,
    DESCKIND * pDescKind,
    BINDPTR * pBindPtr)
{
    ITypeLibImpl *This = impl_from_ITypeComp(iface);
    BOOL typemismatch = FALSE;
    int i;

    TRACE("(%p)->(%s, 0x%x, 0x%x, %p, %p, %p)\n", This, debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr);

    *pDescKind = DESCKIND_NONE;
    pBindPtr->lptcomp = NULL;
    *ppTInfo = NULL;

    for(i = 0; i < This->TypeInfoCount; ++i){
        ITypeInfoImpl *pTypeInfo = This->typeinfos[i];
        TRACE("testing %s\n", debugstr_w(TLB_get_bstr(pTypeInfo->Name)));

        /* FIXME: check wFlags here? */
        /* FIXME: we should use a hash table to look this info up using lHash
         * instead of an O(n) search */
        if ((pTypeInfo->typeattr.typekind == TKIND_ENUM) ||
            (pTypeInfo->typeattr.typekind == TKIND_MODULE))
        {
            if (pTypeInfo->Name && !strcmpW(pTypeInfo->Name->str, szName))
            {
                *pDescKind = DESCKIND_TYPECOMP;
                pBindPtr->lptcomp = &pTypeInfo->ITypeComp_iface;
                ITypeComp_AddRef(pBindPtr->lptcomp);
                TRACE("module or enum: %s\n", debugstr_w(szName));
                return S_OK;
            }
        }

        if ((pTypeInfo->typeattr.typekind == TKIND_MODULE) ||
            (pTypeInfo->typeattr.typekind == TKIND_ENUM))
        {
            ITypeComp *pSubTypeComp = &pTypeInfo->ITypeComp_iface;
            HRESULT hr;

            hr = ITypeComp_Bind(pSubTypeComp, szName, lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
            if (SUCCEEDED(hr) && (*pDescKind != DESCKIND_NONE))
            {
                TRACE("found in module or in enum: %s\n", debugstr_w(szName));
                return S_OK;
            }
            else if (hr == TYPE_E_TYPEMISMATCH)
                typemismatch = TRUE;
        }

        if ((pTypeInfo->typeattr.typekind == TKIND_COCLASS) &&
            (pTypeInfo->typeattr.wTypeFlags & TYPEFLAG_FAPPOBJECT))
        {
            ITypeComp *pSubTypeComp = &pTypeInfo->ITypeComp_iface;
            HRESULT hr;
            ITypeInfo *subtypeinfo;
            BINDPTR subbindptr;
            DESCKIND subdesckind;

            hr = ITypeComp_Bind(pSubTypeComp, szName, lHash, wFlags,
                &subtypeinfo, &subdesckind, &subbindptr);
            if (SUCCEEDED(hr) && (subdesckind != DESCKIND_NONE))
            {
                TYPEDESC tdesc_appobject;
                const VARDESC vardesc_appobject =
                {
                    -2,         /* memid */
                    NULL,       /* lpstrSchema */
                    {
                        0       /* oInst */
                    },
                    {
                                /* ELEMDESC */
                        {
                                /* TYPEDESC */
                                {
                                    &tdesc_appobject
                                },
                                VT_PTR
                        },
                    },
                    0,          /* wVarFlags */
                    VAR_STATIC  /* varkind */
                };

                tdesc_appobject.u.hreftype = pTypeInfo->hreftype;
                tdesc_appobject.vt = VT_USERDEFINED;

                TRACE("found in implicit app object: %s\n", debugstr_w(szName));

                /* cleanup things filled in by Bind call so we can put our
                 * application object data in there instead */
                switch (subdesckind)
                {
                case DESCKIND_FUNCDESC:
                    ITypeInfo_ReleaseFuncDesc(subtypeinfo, subbindptr.lpfuncdesc);
                    break;
                case DESCKIND_VARDESC:
                    ITypeInfo_ReleaseVarDesc(subtypeinfo, subbindptr.lpvardesc);
                    break;
                default:
                    break;
                }
                if (subtypeinfo) ITypeInfo_Release(subtypeinfo);

                if (pTypeInfo->hreftype == -1)
                    FIXME("no hreftype for interface %p\n", pTypeInfo);

                hr = TLB_AllocAndInitVarDesc(&vardesc_appobject, &pBindPtr->lpvardesc);
                if (FAILED(hr))
                    return hr;

                *pDescKind = DESCKIND_IMPLICITAPPOBJ;
                *ppTInfo = (ITypeInfo *)&pTypeInfo->ITypeInfo2_iface;
                ITypeInfo_AddRef(*ppTInfo);
                return S_OK;
            }
            else if (hr == TYPE_E_TYPEMISMATCH)
                typemismatch = TRUE;
        }
    }

    if (typemismatch)
    {
        TRACE("type mismatch %s\n", debugstr_w(szName));
        return TYPE_E_TYPEMISMATCH;
    }
    else
    {
        TRACE("name not found %s\n", debugstr_w(szName));
        return S_OK;
    }
}

static HRESULT WINAPI ITypeLibComp_fnBindType(
    ITypeComp * iface,
    OLECHAR * szName,
    ULONG lHash,
    ITypeInfo ** ppTInfo,
    ITypeComp ** ppTComp)
{
    ITypeLibImpl *This = impl_from_ITypeComp(iface);
    ITypeInfoImpl *info;

    TRACE("(%s, %x, %p, %p)\n", debugstr_w(szName), lHash, ppTInfo, ppTComp);

    if(!szName || !ppTInfo || !ppTComp)
        return E_INVALIDARG;

    info = TLB_get_typeinfo_by_name(This->typeinfos, This->TypeInfoCount, szName);
    if(!info){
        *ppTInfo = NULL;
        *ppTComp = NULL;
        return S_OK;
    }

    *ppTInfo = (ITypeInfo *)&info->ITypeInfo2_iface;
    ITypeInfo_AddRef(*ppTInfo);
    *ppTComp = &info->ITypeComp_iface;
    ITypeComp_AddRef(*ppTComp);

    return S_OK;
}

static const ITypeCompVtbl tlbtcvt =
{

    ITypeLibComp_fnQueryInterface,
    ITypeLibComp_fnAddRef,
    ITypeLibComp_fnRelease,

    ITypeLibComp_fnBind,
    ITypeLibComp_fnBindType
};

/*================== ITypeInfo(2) Methods ===================================*/
static ITypeInfoImpl* ITypeInfoImpl_Constructor(void)
{
    ITypeInfoImpl *pTypeInfoImpl;

    pTypeInfoImpl = heap_alloc_zero(sizeof(ITypeInfoImpl));
    if (pTypeInfoImpl)
    {
      pTypeInfoImpl->ITypeInfo2_iface.lpVtbl = &tinfvt;
      pTypeInfoImpl->ITypeComp_iface.lpVtbl = &tcompvt;
      pTypeInfoImpl->ICreateTypeInfo2_iface.lpVtbl = &CreateTypeInfo2Vtbl;
      pTypeInfoImpl->ref = 0;
      pTypeInfoImpl->hreftype = -1;
      pTypeInfoImpl->typeattr.memidConstructor = MEMBERID_NIL;
      pTypeInfoImpl->typeattr.memidDestructor = MEMBERID_NIL;
      pTypeInfoImpl->pcustdata_list = &pTypeInfoImpl->custdata_list;
      list_init(pTypeInfoImpl->pcustdata_list);
    }
    TRACE("(%p)\n", pTypeInfoImpl);
    return pTypeInfoImpl;
}

/* ITypeInfo::QueryInterface
 */
static HRESULT WINAPI ITypeInfo_fnQueryInterface(
	ITypeInfo2 *iface,
	REFIID riid,
	VOID **ppvObject)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);

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

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

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

/* ITypeInfo::AddRef
 */
static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    if (ref == 1 /* incremented from 0 */)
        ITypeLib2_AddRef(&This->pTypeLib->ITypeLib2_iface);

    return ref;
}

static void ITypeInfoImpl_Destroy(ITypeInfoImpl *This)
{
    UINT i;

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

    for (i = 0; i < This->typeattr.cFuncs; ++i)
    {
        int j;
        TLBFuncDesc *pFInfo = &This->funcdescs[i];
        for(j = 0; j < pFInfo->funcdesc.cParams; j++)
        {
            ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[j];
            if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
                VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
            TLB_FreeCustData(&pFInfo->pParamDesc[j].custdata_list);
        }
        heap_free(pFInfo->funcdesc.lprgelemdescParam);
        heap_free(pFInfo->pParamDesc);
        TLB_FreeCustData(&pFInfo->custdata_list);
    }
    heap_free(This->funcdescs);

    for(i = 0; i < This->typeattr.cVars; ++i)
    {
        TLBVarDesc *pVInfo = &This->vardescs[i];
        if (pVInfo->vardesc_create) {
            TLB_FreeVarDesc(pVInfo->vardesc_create);
        } else if (pVInfo->vardesc.varkind == VAR_CONST) {
            VariantClear(pVInfo->vardesc.u.lpvarValue);
            heap_free(pVInfo->vardesc.u.lpvarValue);
        }
        TLB_FreeCustData(&pVInfo->custdata_list);
    }
    heap_free(This->vardescs);

    if(This->impltypes){
        for (i = 0; i < This->typeattr.cImplTypes; ++i){
            TLBImplType *pImpl = &This->impltypes[i];
            TLB_FreeCustData(&pImpl->custdata_list);
        }
        heap_free(This->impltypes);
    }

    TLB_FreeCustData(&This->custdata_list);

    heap_free(This);
}

/* ITypeInfo::Release
 */
static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if (!ref)
    {
        BOOL not_attached_to_typelib = This->not_attached_to_typelib;
        ITypeLib2_Release(&This->pTypeLib->ITypeLib2_iface);
        if (not_attached_to_typelib)
            heap_free(This);
        /* otherwise This will be freed when typelib is freed */
    }

    return ref;
}

/* ITypeInfo::GetTypeAttr
 *
 * Retrieves a TYPEATTR structure that contains the attributes of the type
 * description.
 *
 */
static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface,
        LPTYPEATTR  *ppTypeAttr)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    SIZE_T size;

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

    size = sizeof(**ppTypeAttr);
    if (This->typeattr.typekind == TKIND_ALIAS && This->tdescAlias)
        size += TLB_SizeTypeDesc(This->tdescAlias, FALSE);

    *ppTypeAttr = heap_alloc(size);
    if (!*ppTypeAttr)
        return E_OUTOFMEMORY;

    **ppTypeAttr = This->typeattr;
    (*ppTypeAttr)->guid = *TLB_get_guid_null(This->guid);

    if (This->tdescAlias)
        TLB_CopyTypeDesc(&(*ppTypeAttr)->tdescAlias, This->tdescAlias, *ppTypeAttr + 1);

    if((*ppTypeAttr)->typekind == TKIND_DISPATCH) {
        /* This should include all the inherited funcs */
        (*ppTypeAttr)->cFuncs = (*ppTypeAttr)->cbSizeVft / This->pTypeLib->ptr_size;
        /* This is always the size of IDispatch's vtbl */
        (*ppTypeAttr)->cbSizeVft = sizeof(IDispatchVtbl);
        (*ppTypeAttr)->wTypeFlags &= ~TYPEFLAG_FOLEAUTOMATION;
    }
    return S_OK;
}

/* ITypeInfo::GetTypeComp
 *
 * Retrieves the ITypeComp interface for the type description, which enables a
 * client compiler to bind to the type description's members.
 *
 */
static HRESULT WINAPI ITypeInfo_fnGetTypeComp( ITypeInfo2 *iface,
        ITypeComp  * *ppTComp)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);

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

    *ppTComp = &This->ITypeComp_iface;
    ITypeComp_AddRef(*ppTComp);
    return S_OK;
}

static SIZE_T TLB_SizeElemDesc( const ELEMDESC *elemdesc )
{
    SIZE_T size = TLB_SizeTypeDesc(&elemdesc->tdesc, FALSE);
    if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
        size += sizeof(*elemdesc->u.paramdesc.pparamdescex);
    return size;
}

static HRESULT TLB_CopyElemDesc( const ELEMDESC *src, ELEMDESC *dest, char **buffer )
{
    *dest = *src;
    *buffer = TLB_CopyTypeDesc(&dest->tdesc, &src->tdesc, *buffer);
    if (src->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
    {
        const PARAMDESCEX *pparamdescex_src = src->u.paramdesc.pparamdescex;
        PARAMDESCEX *pparamdescex_dest = dest->u.paramdesc.pparamdescex = (PARAMDESCEX *)*buffer;
        *buffer += sizeof(PARAMDESCEX);
        *pparamdescex_dest = *pparamdescex_src;
        pparamdescex_dest->cBytes = sizeof(PARAMDESCEX);
        VariantInit(&pparamdescex_dest->varDefaultValue);
        return VariantCopy(&pparamdescex_dest->varDefaultValue, 
                           (VARIANTARG *)&pparamdescex_src->varDefaultValue);
    }
    else
        dest->u.paramdesc.pparamdescex = NULL;
    return S_OK;
}

static HRESULT TLB_SanitizeBSTR(BSTR str)
{
    UINT len = SysStringLen(str), i;
    for (i = 0; i < len; ++i)
        if (str[i] > 0x7f)
            str[i] = '?';
    return S_OK;
}

static HRESULT TLB_SanitizeVariant(VARIANT *var)
{
    if (V_VT(var) == VT_INT)
        return VariantChangeType(var, var, 0, VT_I4);
    else if (V_VT(var) == VT_UINT)
        return VariantChangeType(var, var, 0, VT_UI4);
    else if (V_VT(var) == VT_BSTR)
        return TLB_SanitizeBSTR(V_BSTR(var));

    return S_OK;
}

static void TLB_FreeElemDesc( ELEMDESC *elemdesc )
{
    if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
        VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
}

static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_ptr, BOOL dispinterface )
{
    FUNCDESC *dest;
    char *buffer;
    SIZE_T size = sizeof(*src);
    SHORT i;
    HRESULT hr;

    size += sizeof(*src->lprgscode) * src->cScodes;
    size += TLB_SizeElemDesc(&src->elemdescFunc);
    for (i = 0; i < src->cParams; i++)
    {
        size += sizeof(ELEMDESC);
        size += TLB_SizeElemDesc(&src->lprgelemdescParam[i]);
    }

    dest = (FUNCDESC *)SysAllocStringByteLen(NULL, size);
    if (!dest) return E_OUTOFMEMORY;

    *dest = *src;
    if (dispinterface)    /* overwrite funckind */
        dest->funckind = FUNC_DISPATCH;
    buffer = (char *)(dest + 1);

    dest->oVft = dest->oVft & 0xFFFC;

    if (dest->cScodes) {
        dest->lprgscode = (SCODE *)buffer;
        memcpy(dest->lprgscode, src->lprgscode, sizeof(*src->lprgscode) * src->cScodes);
        buffer += sizeof(*src->lprgscode) * src->cScodes;
    } else
        dest->lprgscode = NULL;

    hr = TLB_CopyElemDesc(&src->elemdescFunc, &dest->elemdescFunc, &buffer);
    if (FAILED(hr))
    {
        SysFreeString((BSTR)dest);
        return hr;
    }

    if (dest->cParams) {
        dest->lprgelemdescParam = (ELEMDESC *)buffer;
        buffer += sizeof(ELEMDESC) * src->cParams;
        for (i = 0; i < src->cParams; i++)
        {
            hr = TLB_CopyElemDesc(&src->lprgelemdescParam[i], &dest->lprgelemdescParam[i], &buffer);
            if (FAILED(hr))
                break;
        }
        if (FAILED(hr))
        {
            /* undo the above actions */
            for (i = i - 1; i >= 0; i--)
                TLB_FreeElemDesc(&dest->lprgelemdescParam[i]);
            TLB_FreeElemDesc(&dest->elemdescFunc);
            SysFreeString((BSTR)dest);
            return hr;
        }
    } else
        dest->lprgelemdescParam = NULL;

    /* special treatment for dispinterfaces: this makes functions appear
     * to return their [retval] value when it is really returning an
     * HRESULT */
    if (dispinterface && dest->elemdescFunc.tdesc.vt == VT_HRESULT)
    {
        if (dest->cParams &&
            (dest->lprgelemdescParam[dest->cParams - 1].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL))
        {
            ELEMDESC *elemdesc = &dest->lprgelemdescParam[dest->cParams - 1];
            if (elemdesc->tdesc.vt != VT_PTR)
            {
                ERR("elemdesc should have started with VT_PTR instead of:\n");
                if (ERR_ON(ole))
                    dump_ELEMDESC(elemdesc);
                return E_UNEXPECTED;
            }

            /* copy last parameter to the return value. we are using a flat
             * buffer so there is no danger of leaking memory in
             * elemdescFunc */
            dest->elemdescFunc.tdesc = *elemdesc->tdesc.u.lptdesc;

            /* remove the last parameter */
            dest->cParams--;
        }
        else
            /* otherwise this function is made to appear to have no return
             * value */
            dest->elemdescFunc.tdesc.vt = VT_VOID;

    }

    *dest_ptr = dest;
    return S_OK;
}

static void TLB_FreeVarDesc(VARDESC *var_desc)
{
    TLB_FreeElemDesc(&var_desc->elemdescVar);
    if (var_desc->varkind == VAR_CONST)
        VariantClear(var_desc->u.lpvarValue);
    SysFreeString((BSTR)var_desc);
}

HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc )
{
    ITypeInfoImpl *This = impl_from_ITypeInfo(iface);

    if (index >= This->typeattr.cFuncs)
        return TYPE_E_ELEMENTNOTFOUND;

    *ppFuncDesc = &This->funcdescs[index].funcdesc;
    return S_OK;
}

/* internal function to make the inherited interfaces' methods appear
 * part of the interface */
static HRESULT ITypeInfoImpl_GetInternalDispatchFuncDesc( ITypeInfo *iface,
    UINT index, const FUNCDESC **ppFuncDesc, UINT *funcs, UINT *hrefoffset)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo(iface);
    HRESULT hr;
    UINT implemented_funcs = 0;

    if (funcs)
        *funcs = 0;
    else
        *hrefoffset = DISPATCH_HREF_OFFSET;

    if(This->impltypes)
    {
        ITypeInfo *pSubTypeInfo;
        UINT sub_funcs;

        hr = ITypeInfo_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pSubTypeInfo);
        if (FAILED(hr))
            return hr;

        hr = ITypeInfoImpl_GetInternalDispatchFuncDesc(pSubTypeInfo,
                                                       index,
                                                       ppFuncDesc,
                                                       &sub_funcs, hrefoffset);
        implemented_funcs += sub_funcs;
        ITypeInfo_Release(pSubTypeInfo);
        if (SUCCEEDED(hr))
            return hr;
        *hrefoffset += DISPATCH_HREF_OFFSET;
    }

    if (funcs)
        *funcs = implemented_funcs + This->typeattr.cFuncs;
    else
        *hrefoffset = 0;
    
    if (index < implemented_funcs)
        return E_INVALIDARG;
    return ITypeInfoImpl_GetInternalFuncDesc(iface, index - implemented_funcs,
                                             ppFuncDesc);
}

static inline void ITypeInfoImpl_ElemDescAddHrefOffset( LPELEMDESC pElemDesc, UINT hrefoffset)
{
    TYPEDESC *pTypeDesc = &pElemDesc->tdesc;
    while (TRUE)
    {
        switch (pTypeDesc->vt)
        {
        case VT_USERDEFINED:
            pTypeDesc->u.hreftype += hrefoffset;
            return;
        case VT_PTR:
        case VT_SAFEARRAY:
            pTypeDesc = pTypeDesc->u.lptdesc;
            break;
        case VT_CARRAY:
            pTypeDesc = &pTypeDesc->u.lpadesc->tdescElem;
            break;
        default:
            return;
        }
    }
}

static inline void ITypeInfoImpl_FuncDescAddHrefOffset( LPFUNCDESC pFuncDesc, UINT hrefoffset)
{
    SHORT i;
    for (i = 0; i < pFuncDesc->cParams; i++)
        ITypeInfoImpl_ElemDescAddHrefOffset(&pFuncDesc->lprgelemdescParam[i], hrefoffset);
    ITypeInfoImpl_ElemDescAddHrefOffset(&pFuncDesc->elemdescFunc, hrefoffset);
}

/* ITypeInfo::GetFuncDesc
 *
 * Retrieves the FUNCDESC structure that contains information about a
 * specified function.
 *
 */
static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( ITypeInfo2 *iface, UINT index,
        LPFUNCDESC  *ppFuncDesc)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    const FUNCDESC *internal_funcdesc;
    HRESULT hr;
    UINT hrefoffset = 0;

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

    if (!ppFuncDesc)
        return E_INVALIDARG;

    if (This->needs_layout)
        ICreateTypeInfo2_LayOut(&This->ICreateTypeInfo2_iface);

    if (This->typeattr.typekind == TKIND_DISPATCH)
        hr = ITypeInfoImpl_GetInternalDispatchFuncDesc((ITypeInfo *)iface, index,
                                                       &internal_funcdesc, NULL,
                                                       &hrefoffset);
    else
        hr = ITypeInfoImpl_GetInternalFuncDesc((ITypeInfo *)iface, index,
                                               &internal_funcdesc);
    if (FAILED(hr))
    {
        WARN("description for function %d not found\n", index);
        return hr;
    }

    hr = TLB_AllocAndInitFuncDesc(
        internal_funcdesc,
        ppFuncDesc,
        This->typeattr.typekind == TKIND_DISPATCH);

    if ((This->typeattr.typekind == TKIND_DISPATCH) && hrefoffset)
        ITypeInfoImpl_FuncDescAddHrefOffset(*ppFuncDesc, hrefoffset);

    TRACE("-- 0x%08x\n", hr);
    return hr;
}

static HRESULT TLB_AllocAndInitVarDesc( const VARDESC *src, VARDESC **dest_ptr )
{
    VARDESC *dest;
    char *buffer;
    SIZE_T size = sizeof(*src);
    HRESULT hr;

    if (src->lpstrSchema) size += (strlenW(src->lpstrSchema) + 1) * sizeof(WCHAR);
    if (src->varkind == VAR_CONST)
        size += sizeof(VARIANT);
    size += TLB_SizeElemDesc(&src->elemdescVar);

    dest = (VARDESC *)SysAllocStringByteLen(NULL, size);
    if (!dest) return E_OUTOFMEMORY;

    *dest = *src;
    buffer = (char *)(dest + 1);
    if (src->lpstrSchema)
    {
        int len;
        dest->lpstrSchema = (LPOLESTR)buffer;
        len = strlenW(src->lpstrSchema);
        memcpy(dest->lpstrSchema, src->lpstrSchema, (len + 1) * sizeof(WCHAR));
        buffer += (len + 1) * sizeof(WCHAR);
    }

    if (src->varkind == VAR_CONST)
    {
        HRESULT hr;

        dest->u.lpvarValue = (VARIANT *)buffer;
        *dest->u.lpvarValue = *src->u.lpvarValue;
        buffer += sizeof(VARIANT);
        VariantInit(dest->u.lpvarValue);
        hr = VariantCopy(dest->u.lpvarValue, src->u.lpvarValue);
        if (FAILED(hr))
        {
            SysFreeString((BSTR)dest);
            return hr;
        }
    }
    hr = TLB_CopyElemDesc(&src->elemdescVar, &dest->elemdescVar, &buffer);
    if (FAILED(hr))
    {
        if (src->varkind == VAR_CONST)
            VariantClear(dest->u.lpvarValue);
        SysFreeString((BSTR)dest);
        return hr;
    }
    *dest_ptr = dest;
    return S_OK;
}

/* ITypeInfo::GetVarDesc
 *
 * Retrieves a VARDESC structure that describes the specified variable.
 *
 */
static HRESULT WINAPI ITypeInfo_fnGetVarDesc( ITypeInfo2 *iface, UINT index,
        LPVARDESC  *ppVarDesc)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    const TLBVarDesc *pVDesc = &This->vardescs[index];

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

    if(index >= This->typeattr.cVars)
        return TYPE_E_ELEMENTNOTFOUND;

    if (This->needs_layout)
        ICreateTypeInfo2_LayOut(&This->ICreateTypeInfo2_iface);

    return TLB_AllocAndInitVarDesc(&pVDesc->vardesc, ppVarDesc);
}

/* ITypeInfo_GetNames
 *
 * Retrieves the variable with the specified member ID (or the name of the
 * property or method and its parameters) that correspond to the specified
 * function ID.
 */
static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
        BSTR  *rgBstrNames, UINT cMaxNames, UINT  *pcNames)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    const TLBFuncDesc *pFDesc;
    const TLBVarDesc *pVDesc;
    int i;
    TRACE("(%p) memid=0x%08x Maxname=%d\n", This, memid, cMaxNames);

    if(!rgBstrNames)
        return E_INVALIDARG;

    *pcNames = 0;

    pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->typeattr.cFuncs, memid);
    if(pFDesc)
    {
        if(!cMaxNames || !pFDesc->Name)
            return S_OK;

        *rgBstrNames = SysAllocString(TLB_get_bstr(pFDesc->Name));
        ++(*pcNames);

        for(i = 0; i < pFDesc->funcdesc.cParams; ++i){
            if(*pcNames >= cMaxNames || !pFDesc->pParamDesc[i].Name)
                return S_OK;
            rgBstrNames[*pcNames] = SysAllocString(TLB_get_bstr(pFDesc->pParamDesc[i].Name));
            ++(*pcNames);
        }
        return S_OK;
    }

    pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->typeattr.cVars, memid);
    if(pVDesc)
    {
      *rgBstrNames=SysAllocString(TLB_get_bstr(pVDesc->Name));
      *pcNames=1;
    }
    else
    {
        if(This->impltypes &&
	   (This->typeattr.typekind == TKIND_INTERFACE || This->typeattr.typekind == TKIND_DISPATCH)) {
          /* recursive search */
          ITypeInfo *pTInfo;
          HRESULT result;
          result = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo);
          if(SUCCEEDED(result))
	  {
            result=ITypeInfo_GetNames(pTInfo, memid, rgBstrNames, cMaxNames, pcNames);
            ITypeInfo_Release(pTInfo);
            return result;
          }
          WARN("Could not search inherited interface!\n");
        }
        else
	{
          WARN("no names found\n");
	}
        *pcNames=0;
        return TYPE_E_ELEMENTNOTFOUND;
    }
    return S_OK;
}


/* ITypeInfo::GetRefTypeOfImplType
 *
 * If a type description describes a COM class, it retrieves the type
 * description of the implemented interface types. For an interface,
 * GetRefTypeOfImplType returns the type information for inherited interfaces,
 * if any exist.
 *
 */
static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType(
	ITypeInfo2 *iface,
        UINT index,
	HREFTYPE  *pRefType)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    HRESULT hr = S_OK;

    TRACE("(%p) index %d\n", This, index);
    if (TRACE_ON(ole)) dump_TypeInfo(This);

    if(index==(UINT)-1)
    {
      /* only valid on dual interfaces;
         retrieve the associated TKIND_INTERFACE handle for the current TKIND_DISPATCH
      */

      if (This->typeattr.wTypeFlags & TYPEFLAG_FDUAL)
      {
          *pRefType = -2;
      }
      else
      {
        hr = TYPE_E_ELEMENTNOTFOUND;
      }
    }
    else if(index == 0 && This->typeattr.typekind == TKIND_DISPATCH)
    {
      /* All TKIND_DISPATCHs are made to look like they inherit from IDispatch */
      *pRefType = This->pTypeLib->dispatch_href;
    }
    else
    {
        if(index >= This->typeattr.cImplTypes)
            hr = TYPE_E_ELEMENTNOTFOUND;
        else{
            *pRefType = This->impltypes[index].hRef;
            if (This->typeattr.typekind == TKIND_INTERFACE)
                *pRefType |= 0x2;
        }
    }

    if(TRACE_ON(ole))
    {
        if(SUCCEEDED(hr))
            TRACE("SUCCESS -- hRef = 0x%08x\n", *pRefType );
        else
            TRACE("FAILURE -- hresult = 0x%08x\n", hr);
    }

    return hr;
}

/* ITypeInfo::GetImplTypeFlags
 *
 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
 * or base interface in a type description.
 */
static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( ITypeInfo2 *iface,
        UINT index, INT  *pImplTypeFlags)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);

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

    if(!pImplTypeFlags)
        return E_INVALIDARG;

    if(This->typeattr.typekind == TKIND_DISPATCH && index == 0){
        *pImplTypeFlags = 0;
        return S_OK;
    }

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

    *pImplTypeFlags = This->impltypes[index].implflags;

    return S_OK;
}

/* GetIDsOfNames
 * Maps between member names and member IDs, and parameter names and
 * parameter IDs.
 */
static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface,
        LPOLESTR  *rgszNames, UINT cNames, MEMBERID  *pMemId)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    const TLBVarDesc *pVDesc;
    HRESULT ret=S_OK;
    UINT i, fdc;

    TRACE("(%p) Name %s cNames %d\n", This, debugstr_w(*rgszNames),
            cNames);

    /* init out parameters in case of failure */
    for (i = 0; i < cNames; i++)
        pMemId[i] = MEMBERID_NIL;

    for (fdc = 0; fdc < This->typeattr.cFuncs; ++fdc) {
        int j;
        const TLBFuncDesc *pFDesc = &This->funcdescs[fdc];
        if(!lstrcmpiW(*rgszNames, TLB_get_bstr(pFDesc->Name))) {
            if(cNames) *pMemId=pFDesc->funcdesc.memid;
            for(i=1; i < cNames; i++){
                for(j=0; j<pFDesc->funcdesc.cParams; j++)
                    if(!lstrcmpiW(rgszNames[i],TLB_get_bstr(pFDesc->pParamDesc[j].Name)))
                            break;
                if( j<pFDesc->funcdesc.cParams)
                    pMemId[i]=j;
                else
                   ret=DISP_E_UNKNOWNNAME;
            };
            TRACE("-- 0x%08x\n", ret);
            return ret;
        }
    }
    pVDesc = TLB_get_vardesc_by_name(This->vardescs, This->typeattr.cVars, *rgszNames);
    if(pVDesc){
        if(cNames)
            *pMemId = pVDesc->vardesc.memid;
        return ret;
    }
    /* not found, see if it can be found in an inherited interface */
    if(This->impltypes) {
        /* recursive search */
        ITypeInfo *pTInfo;
        ret = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo);
        if(SUCCEEDED(ret)){
            ret=ITypeInfo_GetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
            ITypeInfo_Release(pTInfo);
            return ret;
        }
        WARN("Could not search inherited interface!\n");
    } else
        WARN("no names found\n");
    return DISP_E_UNKNOWNNAME;
}


#ifdef __i386__

extern LONGLONG call_method( void *func, int nb_args, const DWORD *args, int *stack_offset );
__ASM_GLOBAL_FUNC( call_method,
                   "pushl %ebp\n\t"
                   __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
                   __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
                   "movl %esp,%ebp\n\t"
                   __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
                   "pushl %esi\n\t"
                  __ASM_CFI(".cfi_rel_offset %esi,-4\n\t")
                   "pushl %edi\n\t"
                  __ASM_CFI(".cfi_rel_offset %edi,-8\n\t")
                   "movl 12(%ebp),%edx\n\t"
                   "movl %esp,%edi\n\t"
                   "shll $2,%edx\n\t"
                   "jz 1f\n\t"
                   "subl %edx,%edi\n\t"
                   "andl $~15,%edi\n\t"
                   "movl %edi,%esp\n\t"
                   "movl 12(%ebp),%ecx\n\t"
                   "movl 16(%ebp),%esi\n\t"
                   "cld\n\t"
                   "rep; movsl\n"
                   "1:\tcall *8(%ebp)\n\t"
                   "subl %esp,%edi\n\t"
                   "movl 20(%ebp),%ecx\n\t"
                   "movl %edi,(%ecx)\n\t"
                   "leal -8(%ebp),%esp\n\t"
                   "popl %edi\n\t"
                   __ASM_CFI(".cfi_same_value %edi\n\t")
                   "popl %esi\n\t"
                   __ASM_CFI(".cfi_same_value %esi\n\t")
                   "popl %ebp\n\t"
                   __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
                   __ASM_CFI(".cfi_same_value %ebp\n\t")
                   "ret" )

/* same function but returning floating point */
static double (* const call_double_method)(void*,int,const DWORD*,int*) = (void *)call_method;

/* ITypeInfo::Invoke
 *
 * Invokes a method, or accesses a property of an object, that implements the
 * interface described by the type description.
 */
DWORD
_invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) {
    DWORD res;
    int stack_offset;

    if (TRACE_ON(ole)) {
	int i;
	TRACE("Calling %p(",func);
	for (i=0;i<min(nrargs,30);i++) TRACE("%08x,",args[i]);
	if (nrargs > 30) TRACE("...");
	TRACE(")\n");
    }

    switch (callconv) {
    case CC_STDCALL:
    case CC_CDECL:
        res = call_method( func, nrargs, args, &stack_offset );
	break;
    default:
	FIXME("unsupported calling convention %d\n",callconv);
	res = -1;
	break;
    }
    TRACE("returns %08x\n",res);
    return res;
}

#elif defined(__x86_64__)

extern DWORD_PTR CDECL call_method( void *func, int nb_args, const DWORD_PTR *args );
__ASM_GLOBAL_FUNC( call_method,
                   "pushq %rbp\n\t"
                   __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t")
                   __ASM_CFI(".cfi_rel_offset %rbp,0\n\t")
                   "movq %rsp,%rbp\n\t"
                   __ASM_CFI(".cfi_def_cfa_register %rbp\n\t")
                   "pushq %rsi\n\t"
                   __ASM_CFI(".cfi_rel_offset %rsi,-8\n\t")
                   "pushq %rdi\n\t"
                   __ASM_CFI(".cfi_rel_offset %rdi,-16\n\t")
                   "movq %rcx,%rax\n\t"
                   "movq $4,%rcx\n\t"
                   "cmp %rcx,%rdx\n\t"
                   "cmovgq %rdx,%rcx\n\t"
                   "leaq 0(,%rcx,8),%rdx\n\t"
                   "subq %rdx,%rsp\n\t"
                   "andq $~15,%rsp\n\t"
                   "movq %rsp,%rdi\n\t"
                   "movq %r8,%rsi\n\t"
                   "rep; movsq\n\t"
                   "movq 0(%rsp),%rcx\n\t"
                   "movq 8(%rsp),%rdx\n\t"
                   "movq 16(%rsp),%r8\n\t"
                   "movq 24(%rsp),%r9\n\t"
                   "movq 0(%rsp),%xmm0\n\t"
                   "movq 8(%rsp),%xmm1\n\t"
                   "movq 16(%rsp),%xmm2\n\t"
                   "movq 24(%rsp),%xmm3\n\t"
                   "callq *%rax\n\t"
                   "leaq -16(%rbp),%rsp\n\t"
                   "popq %rdi\n\t"
                   __ASM_CFI(".cfi_same_value %rdi\n\t")
                   "popq %rsi\n\t"
                   __ASM_CFI(".cfi_same_value %rsi\n\t")
                   __ASM_CFI(".cfi_def_cfa_register %rsp\n\t")
                   "popq %rbp\n\t"
                   __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
                   __ASM_CFI(".cfi_same_value %rbp\n\t")
                   "ret")

/* same function but returning floating point */
static double (CDECL * const call_double_method)(void*,int,const DWORD_PTR*) = (void *)call_method;

#endif  /* __x86_64__ */

static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
{
    HRESULT hr = S_OK;
    ITypeInfo *tinfo2 = NULL;
    TYPEATTR *tattr = NULL;

    hr = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->u.hreftype, &tinfo2);
    if (hr)
    {
        ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED, "
            "hr = 0x%08x\n",
              tdesc->u.hreftype, hr);
        return hr;
    }
    hr = ITypeInfo_GetTypeAttr(tinfo2, &tattr);
    if (hr)
    {
        ERR("ITypeInfo_GetTypeAttr failed, hr = 0x%08x\n", hr);
        ITypeInfo_Release(tinfo2);
        return hr;
    }

    switch (tattr->typekind)
    {
    case TKIND_ENUM:
        *vt |= VT_I4;
        break;

    case TKIND_ALIAS:
        hr = typedescvt_to_variantvt(tinfo2, &tattr->tdescAlias, vt);
        break;

    case TKIND_INTERFACE:
        if (tattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE)
           *vt |= VT_DISPATCH;
        else
           *vt |= VT_UNKNOWN;
        break;

    case TKIND_DISPATCH:
        *vt |= VT_DISPATCH;
        break;

    case TKIND_COCLASS:
        *vt |= VT_DISPATCH;
        break;

    case TKIND_RECORD:
        FIXME("TKIND_RECORD unhandled.\n");
        hr = E_NOTIMPL;
        break;

    case TKIND_UNION:
        FIXME("TKIND_UNION unhandled.\n");
        hr = E_NOTIMPL;
        break;

    default:
        FIXME("TKIND %d unhandled.\n",tattr->typekind);
        hr = E_NOTIMPL;
        break;
    }
    ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
    ITypeInfo_Release(tinfo2);
    return hr;
}

static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
{
    HRESULT hr = S_OK;

    /* enforce only one level of pointer indirection */
    if (!(*vt & VT_BYREF) && !(*vt & VT_ARRAY) && (tdesc->vt == VT_PTR))
    {
        tdesc = tdesc->u.lptdesc;

        /* munch VT_PTR -> VT_USERDEFINED(interface) into VT_UNKNOWN or
         * VT_DISPATCH and VT_PTR -> VT_PTR -> VT_USERDEFINED(interface) into 
         * VT_BYREF|VT_DISPATCH or VT_BYREF|VT_UNKNOWN */
        if ((tdesc->vt == VT_USERDEFINED) ||
            ((tdesc->vt == VT_PTR) && (tdesc->u.lptdesc->vt == VT_USERDEFINED)))
        {
            VARTYPE vt_userdefined = 0;
            const TYPEDESC *tdesc_userdefined = tdesc;
            if (tdesc->vt == VT_PTR)
            {
                vt_userdefined = VT_BYREF;
                tdesc_userdefined = tdesc->u.lptdesc;
            }
            hr = userdefined_to_variantvt(tinfo, tdesc_userdefined, &vt_userdefined);
            if ((hr == S_OK) && 
                (((vt_userdefined & VT_TYPEMASK) == VT_UNKNOWN) ||
                 ((vt_userdefined & VT_TYPEMASK) == VT_DISPATCH)))
            {
                *vt |= vt_userdefined;
                return S_OK;
            }
        }
        *vt = VT_BYREF;
    }

    switch (tdesc->vt)
    {
    case VT_HRESULT:
        *vt |= VT_ERROR;
        break;
    case VT_USERDEFINED:
        hr = userdefined_to_variantvt(tinfo, tdesc, vt);
        break;
    case VT_VOID:
    case VT_CARRAY:
    case VT_PTR:
    case VT_LPSTR:
    case VT_LPWSTR:
        ERR("cannot convert type %d into variant VT\n", tdesc->vt);
        hr = DISP_E_BADVARTYPE;
        break;
    case VT_SAFEARRAY:
        *vt |= VT_ARRAY;
        hr = typedescvt_to_variantvt(tinfo, tdesc->u.lptdesc, vt);
        break;
    case VT_INT:
        *vt |= VT_I4;
        break;
    case VT_UINT:
        *vt |= VT_UI4;
        break;
    default:
        *vt |= tdesc->vt;
        break;
    }
    return hr;
}

static HRESULT get_iface_guid(ITypeInfo *tinfo, const TYPEDESC *tdesc, GUID *guid)
{
    ITypeInfo *tinfo2;
    TYPEATTR *tattr;
    HRESULT hres;

    hres = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->u.hreftype, &tinfo2);
    if(FAILED(hres))
        return hres;

    hres = ITypeInfo_GetTypeAttr(tinfo2, &tattr);
    if(FAILED(hres)) {
        ITypeInfo_Release(tinfo2);
        return hres;
    }

    switch(tattr->typekind) {
    case TKIND_ALIAS:
        hres = get_iface_guid(tinfo2, &tattr->tdescAlias, guid);
        break;

    case TKIND_INTERFACE:
    case TKIND_DISPATCH:
        *guid = tattr->guid;
        break;

    default:
        ERR("Unexpected typekind %d\n", tattr->typekind);
        hres = E_UNEXPECTED;
    }

    ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
    ITypeInfo_Release(tinfo2);
    return hres;
}

/***********************************************************************
 *		DispCallFunc (OLEAUT32.@)
 *
 * Invokes a function of the specified calling convention, passing the
 * specified arguments and returns the result.
 *
 * PARAMS
 *  pvInstance  [I] Optional pointer to the instance whose function to invoke.
 *  oVft        [I] The offset in the vtable. See notes.
 *  cc          [I] Calling convention of the function to call.
 *  vtReturn    [I] The return type of the function.
 *  cActuals    [I] Number of parameters.
 *  prgvt       [I] The types of the parameters to pass. This is used for sizing only.
 *  prgpvarg    [I] The arguments to pass.
 *  pvargResult [O] The return value of the function. Can be NULL.
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: HRESULT code.
 *
 * NOTES
 *  The HRESULT return value of this function is not affected by the return
 *  value of the user supplied function, which is returned in pvargResult.
 *
 *  If pvInstance is NULL then a non-object function is to be called and oVft
 *  is the address of the function to call.
 *
 * The cc parameter can be one of the following values:
 *|CC_FASTCALL
 *|CC_CDECL
 *|CC_PASCAL
 *|CC_STDCALL
 *|CC_FPFASTCALL
 *|CC_SYSCALL
 *|CC_MPWCDECL
 *|CC_MPWPASCAL
 *
 */
HRESULT WINAPI
DispCallFunc(
    void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals,
    VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult)
{
#ifdef __i386__
    int argspos, stack_offset;
    void *func;
    UINT i;
    DWORD *args;

    TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
        pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg,
        pvargResult, V_VT(pvargResult));

    if (cc != CC_STDCALL && cc != CC_CDECL)
    {
        FIXME("unsupported calling convention %d\n",cc);
        return E_INVALIDARG;
    }

    /* maximum size for an argument is sizeof(VARIANT) */
    args = heap_alloc(sizeof(VARIANT) * cActuals + sizeof(DWORD) * 2 );

    /* start at 1 in case we need to pass a pointer to the return value as arg 0 */
    argspos = 1;
    if (pvInstance)
    {
        const FARPROC *vtable = *(FARPROC **)pvInstance;
        func = vtable[oVft/sizeof(void *)];
        args[argspos++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
    }
    else func = (void *)oVft;

    for (i = 0; i < cActuals; i++)
    {
        VARIANT *arg = prgpvarg[i];

        switch (prgvt[i])
        {
        case VT_EMPTY:
            break;
        case VT_I8:
        case VT_UI8:
        case VT_R8:
        case VT_DATE:
        case VT_CY:
            memcpy( &args[argspos], &V_I8(arg), sizeof(V_I8(arg)) );
            argspos += sizeof(V_I8(arg)) / sizeof(DWORD);
            break;
        case VT_DECIMAL:
        case VT_VARIANT:
            memcpy( &args[argspos], arg, sizeof(*arg) );
            argspos += sizeof(*arg) / sizeof(DWORD);
            break;
        case VT_BOOL:  /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
            args[argspos++] = V_BOOL(arg);
            break;
        default:
            args[argspos++] = V_UI4(arg);
            break;
        }
        TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
    }

    switch (vtReturn)
    {
    case VT_EMPTY:
        call_method( func, argspos - 1, args + 1, &stack_offset );
        break;
    case VT_R4:
        V_R4(pvargResult) = call_double_method( func, argspos - 1, args + 1, &stack_offset );
        break;
    case VT_R8:
    case VT_DATE:
        V_R8(pvargResult) = call_double_method( func, argspos - 1, args + 1, &stack_offset );
        break;
    case VT_DECIMAL:
    case VT_VARIANT:
        args[0] = (DWORD)pvargResult;  /* arg 0 is a pointer to the result */
        call_method( func, argspos, args, &stack_offset );
        break;
    case VT_I8:
    case VT_UI8:
    case VT_CY:
        V_UI8(pvargResult) = call_method( func, argspos - 1, args + 1, &stack_offset );
        break;
    case VT_HRESULT:
        WARN("invalid return type %u\n", vtReturn);
        heap_free( args );
        return E_INVALIDARG;
    default:
        V_UI4(pvargResult) = call_method( func, argspos - 1, args + 1, &stack_offset );
        break;
    }
    heap_free( args );
    if (stack_offset && cc == CC_STDCALL)
    {
        WARN( "stack pointer off by %d\n", stack_offset );
        return DISP_E_BADCALLEE;
    }
    if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
    TRACE("retval: %s\n", debugstr_variant(pvargResult));
    return S_OK;

#elif defined(__x86_64__)
    int argspos;
    UINT i;
    DWORD_PTR *args;
    void *func;

    TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
          pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg,
          pvargResult, V_VT(pvargResult));

    if (cc != CC_STDCALL && cc != CC_CDECL)
    {
	FIXME("unsupported calling convention %d\n",cc);
        return E_INVALIDARG;
    }

    /* maximum size for an argument is sizeof(DWORD_PTR) */
    args = heap_alloc( sizeof(DWORD_PTR) * (cActuals + 2) );

    /* start at 1 in case we need to pass a pointer to the return value as arg 0 */
    argspos = 1;
    if (pvInstance)
    {
        const FARPROC *vtable = *(FARPROC **)pvInstance;
        func = vtable[oVft/sizeof(void *)];
        args[argspos++] = (DWORD_PTR)pvInstance; /* the This pointer is always the first parameter */
    }
    else func = (void *)oVft;

    for (i = 0; i < cActuals; i++)
    {
        VARIANT *arg = prgpvarg[i];

        switch (prgvt[i])
        {
        case VT_DECIMAL:
        case VT_VARIANT:
            args[argspos++] = (ULONG_PTR)arg;
            break;
        case VT_BOOL:  /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
            args[argspos++] = V_BOOL(arg);
            break;
        default:
            args[argspos++] = V_UI8(arg);
            break;
        }
        TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
    }

    switch (vtReturn)
    {
    case VT_R4:
        V_R4(pvargResult) = call_double_method( func, argspos - 1, args + 1 );
        break;
    case VT_R8:
    case VT_DATE:
        V_R8(pvargResult) = call_double_method( func, argspos - 1, args + 1 );
        break;
    case VT_DECIMAL:
    case VT_VARIANT:
        args[0] = (DWORD_PTR)pvargResult;  /* arg 0 is a pointer to the result */
        call_method( func, argspos, args );
        break;
    case VT_HRESULT:
        WARN("invalid return type %u\n", vtReturn);
        heap_free( args );
        return E_INVALIDARG;
    default:
        V_UI8(pvargResult) = call_method( func, argspos - 1, args + 1 );
        break;
    }
    heap_free( args );
    if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
    TRACE("retval: %s\n", debugstr_variant(pvargResult));
    return S_OK;

#else
    FIXME( "(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d)): not implemented for this CPU\n",
           pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
    return E_NOTIMPL;
#endif
}

static inline BOOL func_restricted( const FUNCDESC *desc )
{
    return (desc->wFuncFlags & FUNCFLAG_FRESTRICTED) && (desc->memid >= 0);
}

#define INVBUF_ELEMENT_SIZE \
    (sizeof(VARIANTARG) + sizeof(VARIANTARG) + sizeof(VARIANTARG *) + sizeof(VARTYPE))
#define INVBUF_GET_ARG_ARRAY(buffer, params) (buffer)
#define INVBUF_GET_MISSING_ARG_ARRAY(buffer, params) \
    ((VARIANTARG *)((char *)(buffer) + sizeof(VARIANTARG) * (params)))
#define INVBUF_GET_ARG_PTR_ARRAY(buffer, params) \
    ((VARIANTARG **)((char *)(buffer) + (sizeof(VARIANTARG) + sizeof(VARIANTARG)) * (params)))
#define INVBUF_GET_ARG_TYPE_ARRAY(buffer, params) \
    ((VARTYPE *)((char *)(buffer) + (sizeof(VARIANTARG) + sizeof(VARIANTARG) + sizeof(VARIANTARG *)) * (params)))

static HRESULT WINAPI ITypeInfo_fnInvoke(
    ITypeInfo2 *iface,
    VOID  *pIUnk,
    MEMBERID memid,
    UINT16 wFlags,
    DISPPARAMS  *pDispParams,
    VARIANT  *pVarResult,
    EXCEPINFO  *pExcepInfo,
    UINT  *pArgErr)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    int i;
    unsigned int var_index;
    TYPEKIND type_kind;
    HRESULT hres;
    const TLBFuncDesc *pFuncInfo;
    UINT fdc;

    TRACE("(%p)(%p,id=%d,flags=0x%08x,%p,%p,%p,%p)\n",
      This,pIUnk,memid,wFlags,pDispParams,pVarResult,pExcepInfo,pArgErr
    );

    if( This->typeattr.wTypeFlags & TYPEFLAG_FRESTRICTED )
        return DISP_E_MEMBERNOTFOUND;

    if (!pDispParams)
    {
        ERR("NULL pDispParams not allowed\n");
        return E_INVALIDARG;
    }

    dump_DispParms(pDispParams);

    if (pDispParams->cNamedArgs > pDispParams->cArgs)
    {
        ERR("named argument array cannot be bigger than argument array (%d/%d)\n",
            pDispParams->cNamedArgs, pDispParams->cArgs);
        return E_INVALIDARG;
    }

    /* we do this instead of using GetFuncDesc since it will return a fake
     * FUNCDESC for dispinterfaces and we want the real function description */
    for (fdc = 0; fdc < This->typeattr.cFuncs; ++fdc){
        pFuncInfo = &This->funcdescs[fdc];
        if ((memid == pFuncInfo->funcdesc.memid) &&
            (wFlags & pFuncInfo->funcdesc.invkind) &&
            !func_restricted( &pFuncInfo->funcdesc ))
            break;
    }

    if (fdc < This->typeattr.cFuncs) {
        const FUNCDESC *func_desc = &pFuncInfo->funcdesc;

        if (TRACE_ON(ole))
        {
            TRACE("invoking:\n");
            dump_TLBFuncDescOne(pFuncInfo);
        }
        
	switch (func_desc->funckind) {
	case FUNC_PUREVIRTUAL:
	case FUNC_VIRTUAL: {
            void *buffer = heap_alloc_zero(INVBUF_ELEMENT_SIZE * func_desc->cParams);
            VARIANT varresult;
            VARIANT retval; /* pointer for storing byref retvals in */
            VARIANTARG **prgpvarg = INVBUF_GET_ARG_PTR_ARRAY(buffer, func_desc->cParams);
            VARIANTARG *rgvarg = INVBUF_GET_ARG_ARRAY(buffer, func_desc->cParams);
            VARTYPE *rgvt = INVBUF_GET_ARG_TYPE_ARRAY(buffer, func_desc->cParams);
            UINT cNamedArgs = pDispParams->cNamedArgs;
            DISPID *rgdispidNamedArgs = pDispParams->rgdispidNamedArgs;
            UINT vargs_converted=0;

            hres = S_OK;

            if (func_desc->invkind & (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF))
            {
                if (!cNamedArgs || (rgdispidNamedArgs[0] != DISPID_PROPERTYPUT))
                {
                    ERR("first named arg for property put invocation must be DISPID_PROPERTYPUT\n");
                    hres = DISP_E_PARAMNOTFOUND;
                    goto func_fail;
                }
            }

            if (func_desc->cParamsOpt < 0 && cNamedArgs)
            {
                ERR("functions with the vararg attribute do not support named arguments\n");
                hres = DISP_E_NONAMEDARGS;
                goto func_fail;
            }

            for (i = 0; i < func_desc->cParams; i++)
            {
                TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
                hres = typedescvt_to_variantvt((ITypeInfo *)iface, tdesc, &rgvt[i]);
                if (FAILED(hres))
                    goto func_fail;
            }

            TRACE("changing args\n");
            for (i = 0; i < func_desc->cParams; i++)
            {
                USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
                TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
                VARIANTARG *src_arg;

                if (wParamFlags & PARAMFLAG_FLCID)
                {
                    VARIANTARG *arg;
                    arg = prgpvarg[i] = &rgvarg[i];
                    V_VT(arg) = VT_I4;
                    V_I4(arg) = This->pTypeLib->lcid;
                    continue;
                }

                src_arg = NULL;

                if (cNamedArgs)
                {
                    USHORT j;
                    for (j = 0; j < cNamedArgs; j++)
                        if (rgdispidNamedArgs[j] == i || (i == func_desc->cParams-1 && rgdispidNamedArgs[j] == DISPID_PROPERTYPUT))
                        {
                            src_arg = &pDispParams->rgvarg[j];
                            break;
                        }
                }

                if (!src_arg && vargs_converted + cNamedArgs < pDispParams->cArgs)
                {
                    src_arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
                    vargs_converted++;
                }

                if (wParamFlags & PARAMFLAG_FRETVAL)
                {
                    /* under most conditions the caller is not allowed to
                     * pass in a dispparam arg in the index of what would be
                     * the retval parameter. however, there is an exception
                     * where the extra parameter is used in an extra
                     * IDispatch::Invoke below */
                    if ((i < pDispParams->cArgs) &&
                        ((func_desc->cParams != 1) || !pVarResult ||
                         !(func_desc->invkind & INVOKE_PROPERTYGET)))
                    {
                        hres = DISP_E_BADPARAMCOUNT;
                        break;
                    }

                    /* note: this check is placed so that if the caller passes
                     * in a VARIANTARG for the retval we just ignore it, like
                     * native does */
                    if (i == func_desc->cParams - 1)
                    {
                        VARIANTARG *arg;
                        arg = prgpvarg[i] = &rgvarg[i];
                        memset(arg, 0, sizeof(*arg));
                        V_VT(arg) = rgvt[i];
                        memset(&retval, 0, sizeof(retval));
                        V_BYREF(arg) = &retval;
                    }
                    else
                    {
                        ERR("[retval] parameter must be the last parameter of the method (%d/%d)\n", i, func_desc->cParams);
                        hres = E_UNEXPECTED;
                        break;
                    }
                }
                else if (src_arg)
                {
                    TRACE("%s\n", debugstr_variant(src_arg));

                    if(rgvt[i]!=V_VT(src_arg))
                    {
                        if (rgvt[i] == VT_VARIANT)
                            hres = VariantCopy(&rgvarg[i], src_arg);
                        else if (rgvt[i] == (VT_VARIANT | VT_BYREF))
                        {
                            if (rgvt[i] == V_VT(src_arg))
                                V_VARIANTREF(&rgvarg[i]) = V_VARIANTREF(src_arg);
                            else
                            {
                                VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
                                if (wParamFlags & PARAMFLAG_FIN)
                                    hres = VariantCopy(&missing_arg[i], src_arg);
                                V_VARIANTREF(&rgvarg[i]) = &missing_arg[i];
                            }
                            V_VT(&rgvarg[i]) = rgvt[i];
                        }
                        else if ((rgvt[i] == (VT_VARIANT | VT_ARRAY) || rgvt[i] == (VT_VARIANT | VT_ARRAY | VT_BYREF)) && func_desc->cParamsOpt < 0)
                        {
                            SAFEARRAY *a;
                            SAFEARRAYBOUND bound;
                            VARIANT *v;
                            LONG j;
                            bound.lLbound = 0;
                            bound.cElements = pDispParams->cArgs-i;
                            if (!(a = SafeArrayCreate(VT_VARIANT, 1, &bound)))
                            {
                                ERR("SafeArrayCreate failed\n");
                                break;
                            }
                            hres = SafeArrayAccessData(a, (LPVOID)&v);
                            if (hres != S_OK)
                            {
                                ERR("SafeArrayAccessData failed with %x\n", hres);
                                SafeArrayDestroy(a);
                                break;
                            }
                            for (j = 0; j < bound.cElements; j++)
                                VariantCopy(&v[j], &pDispParams->rgvarg[pDispParams->cArgs - 1 - i - j]);
                            hres = SafeArrayUnaccessData(a);
                            if (hres != S_OK)
                            {
                                ERR("SafeArrayUnaccessData failed with %x\n", hres);
                                SafeArrayDestroy(a);
                                break;
                            }
                            if (rgvt[i] & VT_BYREF)
                                V_BYREF(&rgvarg[i]) = &a;
                            else
                                V_ARRAY(&rgvarg[i]) = a;
                            V_VT(&rgvarg[i]) = rgvt[i];
                        }
                        else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg))
                        {
                            VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
                            if (wParamFlags & PARAMFLAG_FIN)
                                hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF);
                            else
                                V_VT(&missing_arg[i]) = rgvt[i] & ~VT_BYREF;
                            V_BYREF(&rgvarg[i]) = &V_NONE(&missing_arg[i]);
                            V_VT(&rgvarg[i]) = rgvt[i];
                        }
                        else if ((rgvt[i] & VT_BYREF) && (rgvt[i] == V_VT(src_arg)))
                        {
                            V_BYREF(&rgvarg[i]) = V_BYREF(src_arg);
                            V_VT(&rgvarg[i]) = rgvt[i];
                        }
                        else
                        {
                            /* FIXME: this doesn't work for VT_BYREF arguments if
                             * they are not the same type as in the paramdesc */
                            V_VT(&rgvarg[i]) = V_VT(src_arg);
                            hres = VariantChangeType(&rgvarg[i], src_arg, 0, rgvt[i]);
                            V_VT(&rgvarg[i]) = rgvt[i];
                        }

                        if (FAILED(hres))
                        {
                            ERR("failed to convert param %d to %s from %s\n", i,
                                debugstr_vt(rgvt[i]), debugstr_variant(src_arg));
                            break;
                        }
                        prgpvarg[i] = &rgvarg[i];
                    }
                    else
                    {
                        prgpvarg[i] = src_arg;
                    }

                    if((tdesc->vt == VT_USERDEFINED || (tdesc->vt == VT_PTR && tdesc->u.lptdesc->vt == VT_USERDEFINED))
                       && (V_VT(prgpvarg[i]) == VT_DISPATCH || V_VT(prgpvarg[i]) == VT_UNKNOWN)
                       && V_UNKNOWN(prgpvarg[i])) {
                        IUnknown *userdefined_iface;
                        GUID guid;

                        hres = get_iface_guid((ITypeInfo*)iface, tdesc->vt == VT_PTR ? tdesc->u.lptdesc : tdesc, &guid);
                        if(FAILED(hres))
                            break;

                        hres = IUnknown_QueryInterface(V_UNKNOWN(prgpvarg[i]), &guid, (void**)&userdefined_iface);
                        if(FAILED(hres)) {
                            ERR("argument does not support %s interface\n", debugstr_guid(&guid));
                            break;
                        }

                        IUnknown_Release(V_UNKNOWN(prgpvarg[i]));
                        V_UNKNOWN(prgpvarg[i]) = userdefined_iface;
                    }
                }
                else if (wParamFlags & PARAMFLAG_FOPT)
                {
                    VARIANTARG *arg;
                    arg = prgpvarg[i] = &rgvarg[i];
                    if (wParamFlags & PARAMFLAG_FHASDEFAULT)
                    {
                        hres = VariantCopy(arg, &func_desc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
                        if (FAILED(hres))
                            break;
                    }
                    else
                    {
                        VARIANTARG *missing_arg;
                        /* if the function wants a pointer to a variant then
                         * set that up, otherwise just pass the VT_ERROR in
                         * the argument by value */
                        if (rgvt[i] & VT_BYREF)
                        {
                            missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams) + i;
                            V_VT(arg) = VT_VARIANT | VT_BYREF;
                            V_VARIANTREF(arg) = missing_arg;
                        }
                        else
                            missing_arg = arg;
                        V_VT(missing_arg) = VT_ERROR;
                        V_ERROR(missing_arg) = DISP_E_PARAMNOTFOUND;
                    }
                }
                else
                {
                    hres = DISP_E_BADPARAMCOUNT;
                    break;
                }
            }
            if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */

            /* VT_VOID is a special case for return types, so it is not
             * handled in the general function */
            if (func_desc->elemdescFunc.tdesc.vt == VT_VOID)
                V_VT(&varresult) = VT_EMPTY;
            else
            {
                V_VT(&varresult) = 0;
                hres = typedescvt_to_variantvt((ITypeInfo *)iface, &func_desc->elemdescFunc.tdesc, &V_VT(&varresult));
                if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */
            }

            hres = DispCallFunc(pIUnk, func_desc->oVft & 0xFFFC, func_desc->callconv,
                                V_VT(&varresult), func_desc->cParams, rgvt,
                                prgpvarg, &varresult);

            vargs_converted = 0;

            for (i = 0; i < func_desc->cParams; i++)
            {
                USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
                VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);

                if (wParamFlags & PARAMFLAG_FLCID)
                    continue;
                else if (wParamFlags & PARAMFLAG_FRETVAL)
                {
                    TRACE("[retval] value: %s\n", debugstr_variant(prgpvarg[i]));

                    if (pVarResult)
                    {
                        VariantInit(pVarResult);
                        /* deref return value */
                        hres = VariantCopyInd(pVarResult, prgpvarg[i]);
                    }

                    VARIANT_ClearInd(prgpvarg[i]);
                }
                else if (vargs_converted < pDispParams->cArgs)
                {
                    VARIANTARG *arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
                    if (wParamFlags & PARAMFLAG_FOUT)
                    {
                        if ((rgvt[i] & VT_BYREF) && !(V_VT(arg) & VT_BYREF))
                        {
                            hres = VariantChangeType(arg, &rgvarg[i], 0, V_VT(arg));

                            if (FAILED(hres))
                            {
                                ERR("failed to convert param %d to vt %d\n", i,
                                    V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted]));
                                break;
                            }
                        }
                    }
                    else if (V_VT(prgpvarg[i]) == (VT_VARIANT | VT_ARRAY) &&
                             func_desc->cParamsOpt < 0 &&
                             i == func_desc->cParams-1)
                    {
                        SAFEARRAY *a = V_ARRAY(prgpvarg[i]);
                        LONG j, ubound;
                        VARIANT *v;
                        hres = SafeArrayGetUBound(a, 1, &ubound);
                        if (hres != S_OK)
                        {
                            ERR("SafeArrayGetUBound failed with %x\n", hres);
                            break;
                        }
                        hres = SafeArrayAccessData(a, (LPVOID)&v);
                        if (hres != S_OK)
                        {
                            ERR("SafeArrayAccessData failed with %x\n", hres);
                            break;
                        }
                        for (j = 0; j <= ubound; j++)
                            VariantClear(&v[j]);
                        hres = SafeArrayUnaccessData(a);
                        if (hres != S_OK)
                        {
                            ERR("SafeArrayUnaccessData failed with %x\n", hres);
                            break;
                        }
                    }
                    VariantClear(&rgvarg[i]);
                    vargs_converted++;
                }
                else if (wParamFlags & PARAMFLAG_FOPT)
                {
                    if (wParamFlags & PARAMFLAG_FHASDEFAULT)
                        VariantClear(&rgvarg[i]);
                }

                VariantClear(&missing_arg[i]);
            }

            if ((V_VT(&varresult) == VT_ERROR) && FAILED(V_ERROR(&varresult)))
            {
                WARN("invoked function failed with error 0x%08x\n", V_ERROR(&varresult));
                hres = DISP_E_EXCEPTION;
                if (pExcepInfo)
                {
                    IErrorInfo *pErrorInfo;
                    pExcepInfo->scode = V_ERROR(&varresult);
                    if (GetErrorInfo(0, &pErrorInfo) == S_OK)
                    {
                        IErrorInfo_GetDescription(pErrorInfo, &pExcepInfo->bstrDescription);
                        IErrorInfo_GetHelpFile(pErrorInfo, &pExcepInfo->bstrHelpFile);
                        IErrorInfo_GetSource(pErrorInfo, &pExcepInfo->bstrSource);
                        IErrorInfo_GetHelpContext(pErrorInfo, &pExcepInfo->dwHelpContext);

                        IErrorInfo_Release(pErrorInfo);
                    }
                }
            }
            if (V_VT(&varresult) != VT_ERROR)
            {
                TRACE("varresult value: %s\n", debugstr_variant(&varresult));

                if (pVarResult)
                {
                    VariantClear(pVarResult);
                    *pVarResult = varresult;
                }
                else
                    VariantClear(&varresult);
            }

            if (SUCCEEDED(hres) && pVarResult && (func_desc->cParams == 1) &&
                (func_desc->invkind & INVOKE_PROPERTYGET) &&
                (func_desc->lprgelemdescParam[0].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL) &&
                (pDispParams->cArgs != 0))
            {
                if (V_VT(pVarResult) == VT_DISPATCH)
                {
                    IDispatch *pDispatch = V_DISPATCH(pVarResult);
                    /* Note: not VariantClear; we still need the dispatch
                     * pointer to be valid */
                    VariantInit(pVarResult);
                    hres = IDispatch_Invoke(pDispatch, DISPID_VALUE, &IID_NULL,
                        GetSystemDefaultLCID(), INVOKE_PROPERTYGET,
                        pDispParams, pVarResult, pExcepInfo, pArgErr);
                    IDispatch_Release(pDispatch);
                }
                else
                {
                    VariantClear(pVarResult);
                    hres = DISP_E_NOTACOLLECTION;
                }
            }

func_fail:
            heap_free(buffer);
            break;
        }
	case FUNC_DISPATCH:  {
	   IDispatch *disp;

	   hres = IUnknown_QueryInterface((LPUNKNOWN)pIUnk,&IID_IDispatch,(LPVOID*)&disp);
	   if (SUCCEEDED(hres)) {
               FIXME("Calling Invoke in IDispatch iface. untested!\n");
               hres = IDispatch_Invoke(
                                     disp,memid,&IID_NULL,LOCALE_USER_DEFAULT,wFlags,pDispParams,
                                     pVarResult,pExcepInfo,pArgErr
                                     );
               if (FAILED(hres))
                   FIXME("IDispatch::Invoke failed with %08x. (Could be not a real error?)\n", hres);
               IDispatch_Release(disp);
           } else
	       FIXME("FUNC_DISPATCH used on object without IDispatch iface?\n");
           break;
	}
	default:
            FIXME("Unknown function invocation type %d\n", func_desc->funckind);
            hres = E_FAIL;
            break;
        }

        TRACE("-- 0x%08x\n", hres);
        return hres;

    } else if(SUCCEEDED(hres = ITypeInfo2_GetVarIndexOfMemId(iface, memid, &var_index))) {
        VARDESC *var_desc;

        hres = ITypeInfo2_GetVarDesc(iface, var_index, &var_desc);
        if(FAILED(hres)) return hres;
        
        FIXME("varseek: Found memid, but variable-based invoking not supported\n");
        dump_VARDESC(var_desc);
        ITypeInfo2_ReleaseVarDesc(iface, var_desc);
        return E_NOTIMPL;
    }

    /* not found, look for it in inherited interfaces */
    ITypeInfo2_GetTypeKind(iface, &type_kind);
    if(type_kind == TKIND_INTERFACE || type_kind == TKIND_DISPATCH) {
        if(This->impltypes) {
            /* recursive search */
            ITypeInfo *pTInfo;
            hres = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo);
            if(SUCCEEDED(hres)){
                hres = ITypeInfo_Invoke(pTInfo,pIUnk,memid,wFlags,pDispParams,pVarResult,pExcepInfo,pArgErr);
                ITypeInfo_Release(pTInfo);
                return hres;
            }
            WARN("Could not search inherited interface!\n");
        }
    }
    WARN("did not find member id %d, flags 0x%x!\n", memid, wFlags);
    return DISP_E_MEMBERNOTFOUND;
}

/* ITypeInfo::GetDocumentation
 *
 * Retrieves the documentation string, the complete Help file name and path,
 * and the context ID for the Help topic for a specified type description.
 *
 * (Can be tested by the Visual Basic Editor in Word for instance.)
 */
static HRESULT WINAPI ITypeInfo_fnGetDocumentation( ITypeInfo2 *iface,
        MEMBERID memid, BSTR  *pBstrName, BSTR  *pBstrDocString,
        DWORD  *pdwHelpContext, BSTR  *pBstrHelpFile)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    const TLBFuncDesc *pFDesc;
    const TLBVarDesc *pVDesc;
    TRACE("(%p) memid %d Name(%p) DocString(%p)"
          " HelpContext(%p) HelpFile(%p)\n",
        This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
    if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
        if(pBstrName)
            *pBstrName=SysAllocString(TLB_get_bstr(This->Name));
        if(pBstrDocString)
            *pBstrDocString=SysAllocString(TLB_get_bstr(This->DocString));
        if(pdwHelpContext)
            *pdwHelpContext=This->dwHelpContext;
        if(pBstrHelpFile)
            *pBstrHelpFile=SysAllocString(TLB_get_bstr(This->pTypeLib->HelpFile));
        return S_OK;
    }else {/* for a member */
        pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->typeattr.cFuncs, memid);
        if(pFDesc){
            if(pBstrName)
              *pBstrName = SysAllocString(TLB_get_bstr(pFDesc->Name));
            if(pBstrDocString)
              *pBstrDocString=SysAllocString(TLB_get_bstr(pFDesc->HelpString));
            if(pdwHelpContext)
              *pdwHelpContext=pFDesc->helpcontext;
            if(pBstrHelpFile)
              *pBstrHelpFile = SysAllocString(TLB_get_bstr(This->pTypeLib->HelpFile));
            return S_OK;
        }
        pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->typeattr.cVars, memid);
        if(pVDesc){
            if(pBstrName)
              *pBstrName = SysAllocString(TLB_get_bstr(pVDesc->Name));
            if(pBstrDocString)
              *pBstrDocString=SysAllocString(TLB_get_bstr(pVDesc->HelpString));
            if(pdwHelpContext)
              *pdwHelpContext=pVDesc->HelpContext;
            if(pBstrHelpFile)
              *pBstrHelpFile = SysAllocString(TLB_get_bstr(This->pTypeLib->HelpFile));
            return S_OK;
        }
    }

    if(This->impltypes &&
       (This->typeattr.typekind == TKIND_INTERFACE || This->typeattr.typekind == TKIND_DISPATCH)) {
        /* recursive search */
        ITypeInfo *pTInfo;
        HRESULT result;
        result = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo);
        if(SUCCEEDED(result)) {
            result = ITypeInfo_GetDocumentation(pTInfo, memid, pBstrName,
                pBstrDocString, pdwHelpContext, pBstrHelpFile);
            ITypeInfo_Release(pTInfo);
            return result;
        }
        WARN("Could not search inherited interface!\n");
    }

    WARN("member %d not found\n", memid);
    return TYPE_E_ELEMENTNOTFOUND;
}

/*  ITypeInfo::GetDllEntry
 *
 * Retrieves a description or specification of an entry point for a function
 * in a DLL.
 */
static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid,
        INVOKEKIND invKind, BSTR  *pBstrDllName, BSTR  *pBstrName,
        WORD  *pwOrdinal)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    const TLBFuncDesc *pFDesc;

    TRACE("(%p)->(memid %x, %d, %p, %p, %p)\n", This, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);

    if (pBstrDllName) *pBstrDllName = NULL;
    if (pBstrName) *pBstrName = NULL;
    if (pwOrdinal) *pwOrdinal = 0;

    if (This->typeattr.typekind != TKIND_MODULE)
        return TYPE_E_BADMODULEKIND;

    pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->typeattr.cFuncs, memid);
    if(pFDesc){
	    dump_TypeInfo(This);
	    if (TRACE_ON(ole))
		dump_TLBFuncDescOne(pFDesc);

	    if (pBstrDllName)
		*pBstrDllName = SysAllocString(TLB_get_bstr(This->DllName));

            if (!IS_INTRESOURCE(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) {
		if (pBstrName)
		    *pBstrName = SysAllocString(TLB_get_bstr(pFDesc->Entry));
		if (pwOrdinal)
		    *pwOrdinal = -1;
		return S_OK;
	    }
	    if (pBstrName)
		*pBstrName = NULL;
	    if (pwOrdinal)
		*pwOrdinal = LOWORD(pFDesc->Entry);
	    return S_OK;
        }
    return TYPE_E_ELEMENTNOTFOUND;
}

/* internal function to make the inherited interfaces' methods appear
 * part of the interface */
static HRESULT ITypeInfoImpl_GetDispatchRefTypeInfo( ITypeInfo *iface,
    HREFTYPE *hRefType, ITypeInfo  **ppTInfo)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo(iface);
    HRESULT hr;

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

    if (This->impltypes && (*hRefType & DISPATCH_HREF_MASK))
    {
        ITypeInfo *pSubTypeInfo;

        hr = ITypeInfo_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pSubTypeInfo);
        if (FAILED(hr))
            return hr;

        hr = ITypeInfoImpl_GetDispatchRefTypeInfo(pSubTypeInfo,
                                                  hRefType, ppTInfo);
        ITypeInfo_Release(pSubTypeInfo);
        if (SUCCEEDED(hr))
            return hr;
    }
    *hRefType -= DISPATCH_HREF_OFFSET;

    if (!(*hRefType & DISPATCH_HREF_MASK))
        return ITypeInfo_GetRefTypeInfo(iface, *hRefType, ppTInfo);
    else
        return E_FAIL;
}

struct search_res_tlb_params
{
    const GUID *guid;
    ITypeLib *pTLib;
};

static BOOL CALLBACK search_res_tlb(HMODULE hModule, LPCWSTR lpszType, LPWSTR lpszName, LONG_PTR lParam)
{
    struct search_res_tlb_params *params = (LPVOID)lParam;
    static const WCHAR formatW[] = {'\\','%','d',0};
    WCHAR szPath[MAX_PATH+1];
    ITypeLib *pTLib = NULL;
    HRESULT ret;
    DWORD len;

    if (IS_INTRESOURCE(lpszName) == FALSE)
        return TRUE;

    if (!(len = GetModuleFileNameW(hModule, szPath, MAX_PATH)))
        return TRUE;

    if (snprintfW(szPath + len, sizeof(szPath)/sizeof(WCHAR) - len, formatW, LOWORD(lpszName)) < 0)
        return TRUE;

    ret = LoadTypeLibEx(szPath, REGKIND_NONE, &pTLib);
    if (SUCCEEDED(ret))
    {
        ITypeLibImpl *impl = impl_from_ITypeLib(pTLib);
        if (IsEqualGUID(params->guid, impl->guid))
        {
            params->pTLib = pTLib;
            return FALSE; /* stop enumeration */
        }
        ITypeLib_Release(pTLib);
    }

    return TRUE;
}

/* ITypeInfo::GetRefTypeInfo
 *
 * If a type description references other type descriptions, it retrieves
 * the referenced type descriptions.
 */
static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
	ITypeInfo2 *iface,
        HREFTYPE hRefType,
	ITypeInfo  **ppTInfo)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    HRESULT result = E_FAIL;

    if(!ppTInfo)
        return E_INVALIDARG;

    if ((INT)hRefType < 0) {
        ITypeInfoImpl *pTypeInfoImpl;

        if (!(This->typeattr.wTypeFlags & TYPEFLAG_FDUAL) ||
                !(This->typeattr.typekind == TKIND_INTERFACE ||
                    This->typeattr.typekind == TKIND_DISPATCH))
            return TYPE_E_ELEMENTNOTFOUND;

        /* when we meet a DUAL typeinfo, we must create the alternate
        * version of it.
        */
        pTypeInfoImpl = ITypeInfoImpl_Constructor();

        *pTypeInfoImpl = *This;
        pTypeInfoImpl->ref = 0;
        list_init(&pTypeInfoImpl->custdata_list);

        if (This->typeattr.typekind == TKIND_INTERFACE)
            pTypeInfoImpl->typeattr.typekind = TKIND_DISPATCH;
        else
            pTypeInfoImpl->typeattr.typekind = TKIND_INTERFACE;

        *ppTInfo = (ITypeInfo *)&pTypeInfoImpl->ITypeInfo2_iface;
        /* the AddRef implicitly adds a reference to the parent typelib, which
         * stops the copied data from being destroyed until the new typeinfo's
         * refcount goes to zero, but we need to signal to the new instance to
         * not free its data structures when it is destroyed */
        pTypeInfoImpl->not_attached_to_typelib = TRUE;

        ITypeInfo_AddRef(*ppTInfo);

        result = S_OK;
    } else if ((hRefType & DISPATCH_HREF_MASK) &&
        (This->typeattr.typekind == TKIND_DISPATCH))
    {
        HREFTYPE href_dispatch = hRefType;
        result = ITypeInfoImpl_GetDispatchRefTypeInfo((ITypeInfo *)iface, &href_dispatch, ppTInfo);
    } else {
        TLBRefType *ref_type;
        ITypeLib *pTLib = NULL;
        UINT i;

        if(!(hRefType & 0x1)){
            for(i = 0; i < This->pTypeLib->TypeInfoCount; ++i)
            {
                if (This->pTypeLib->typeinfos[i]->hreftype == (hRefType&(~0x3)))
                {
                    result = S_OK;
                    *ppTInfo = (ITypeInfo*)&This->pTypeLib->typeinfos[i]->ITypeInfo2_iface;
                    ITypeInfo_AddRef(*ppTInfo);
                    goto end;
                }
            }
        }

        LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry)
        {
            if(ref_type->reference == (hRefType & (~0x3)))
                break;
        }
        if(&ref_type->entry == &This->pTypeLib->ref_list)
        {
            FIXME("Can't find pRefType for ref %x\n", hRefType);
            goto end;
        }

        if(ref_type->pImpTLInfo == TLB_REF_INTERNAL) {
            UINT Index;
            TRACE("internal reference\n");
            result = ITypeInfo2_GetContainingTypeLib(iface, &pTLib, &Index);
        } else {
            if(ref_type->pImpTLInfo->pImpTypeLib) {
                TRACE("typeinfo in imported typelib that is already loaded\n");
                pTLib = (ITypeLib*)&ref_type->pImpTLInfo->pImpTypeLib->ITypeLib2_iface;
                ITypeLib_AddRef(pTLib);
                result = S_OK;
            } else {
                static const WCHAR TYPELIBW[] = {'T','Y','P','E','L','I','B',0};
                struct search_res_tlb_params params;
                BSTR libnam;

                TRACE("typeinfo in imported typelib that isn't already loaded\n");

                /* Search in resource table */
                params.guid  = TLB_get_guid_null(ref_type->pImpTLInfo->guid);
                params.pTLib = NULL;
                EnumResourceNamesW(NULL, TYPELIBW, search_res_tlb, (LONG_PTR)&params);
                pTLib  = params.pTLib;
                result = S_OK;

                if (!pTLib)
                {
                    /* Search on disk */
                    result = query_typelib_path(TLB_get_guid_null(ref_type->pImpTLInfo->guid),
                            ref_type->pImpTLInfo->wVersionMajor,
                            ref_type->pImpTLInfo->wVersionMinor,
                            This->pTypeLib->syskind,
                            ref_type->pImpTLInfo->lcid, &libnam, TRUE);
                    if (FAILED(result))
                        libnam = SysAllocString(ref_type->pImpTLInfo->name);

                    result = LoadTypeLib(libnam, &pTLib);
                    SysFreeString(libnam);
                }

                if(SUCCEEDED(result)) {
                    ref_type->pImpTLInfo->pImpTypeLib = impl_from_ITypeLib(pTLib);
                    ITypeLib_AddRef(pTLib);
                }
            }
        }
        if(SUCCEEDED(result)) {
            if(ref_type->index == TLB_REF_USE_GUID)
                result = ITypeLib_GetTypeInfoOfGuid(pTLib, TLB_get_guid_null(ref_type->guid), ppTInfo);
            else
                result = ITypeLib_GetTypeInfo(pTLib, ref_type->index, ppTInfo);
        }
        if (pTLib != NULL)
            ITypeLib_Release(pTLib);
    }

end:
    TRACE("(%p) hreftype 0x%04x loaded %s (%p)\n", This, hRefType,
          SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
    return result;
}

/* ITypeInfo::AddressOfMember
 *
 * Retrieves the addresses of static functions or variables, such as those
 * defined in a DLL.
 */
static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface,
        MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    HRESULT hr;
    BSTR dll, entry;
    WORD ordinal;
    HMODULE module;

    TRACE("(%p)->(0x%x, 0x%x, %p)\n", This, memid, invKind, ppv);

    hr = ITypeInfo2_GetDllEntry(iface, memid, invKind, &dll, &entry, &ordinal);
    if (FAILED(hr))
        return hr;

    module = LoadLibraryW(dll);
    if (!module)
    {
        ERR("couldn't load %s\n", debugstr_w(dll));
        SysFreeString(dll);
        SysFreeString(entry);
        return STG_E_FILENOTFOUND;
    }
    /* FIXME: store library somewhere where we can free it */

    if (entry)
    {
        LPSTR entryA;
        INT len = WideCharToMultiByte(CP_ACP, 0, entry, -1, NULL, 0, NULL, NULL);
        entryA = heap_alloc(len);
        WideCharToMultiByte(CP_ACP, 0, entry, -1, entryA, len, NULL, NULL);

        *ppv = GetProcAddress(module, entryA);
        if (!*ppv)
            ERR("function not found %s\n", debugstr_a(entryA));

        heap_free(entryA);
    }
    else
    {
        *ppv = GetProcAddress(module, MAKEINTRESOURCEA(ordinal));
        if (!*ppv)
            ERR("function not found %d\n", ordinal);
    }

    SysFreeString(dll);
    SysFreeString(entry);

    if (!*ppv)
        return TYPE_E_DLLFUNCTIONNOTFOUND;

    return S_OK;
}

/* ITypeInfo::CreateInstance
 *
 * Creates a new instance of a type that describes a component object class
 * (coclass).
 */
static HRESULT WINAPI ITypeInfo_fnCreateInstance( ITypeInfo2 *iface,
        IUnknown *pOuterUnk, REFIID riid, VOID  **ppvObj)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    HRESULT hr;
    TYPEATTR *pTA;

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

    *ppvObj = NULL;

    if(pOuterUnk)
    {
        WARN("Not able to aggregate\n");
        return CLASS_E_NOAGGREGATION;
    }

    hr = ITypeInfo2_GetTypeAttr(iface, &pTA);
    if(FAILED(hr)) return hr;

    if(pTA->typekind != TKIND_COCLASS)
    {
        WARN("CreateInstance on typeinfo of type %x\n", pTA->typekind);
        hr = E_INVALIDARG;
        goto end;
    }

    hr = S_FALSE;
    if(pTA->wTypeFlags & TYPEFLAG_FAPPOBJECT)
    {
        IUnknown *pUnk;
        hr = GetActiveObject(&pTA->guid, NULL, &pUnk);
        TRACE("GetActiveObject rets %08x\n", hr);
        if(hr == S_OK)
        {
            hr = IUnknown_QueryInterface(pUnk, riid, ppvObj);
            IUnknown_Release(pUnk);
        }
    }

    if(hr != S_OK)
        hr = CoCreateInstance(&pTA->guid, NULL,
                              CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
                              riid, ppvObj);

end:
    ITypeInfo2_ReleaseTypeAttr(iface, pTA);
    return hr;
}

/* ITypeInfo::GetMops
 *
 * Retrieves marshalling information.
 */
static HRESULT WINAPI ITypeInfo_fnGetMops( ITypeInfo2 *iface, MEMBERID memid,
				BSTR  *pBstrMops)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    FIXME("(%p %d) stub!\n", This, memid);
    *pBstrMops = NULL;
    return S_OK;
}

/* ITypeInfo::GetContainingTypeLib
 *
 * Retrieves the containing type library and the index of the type description
 * within that type library.
 */
static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( ITypeInfo2 *iface,
        ITypeLib  * *ppTLib, UINT  *pIndex)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);

    /* If a pointer is null, we simply ignore it, the ATL in particular passes pIndex as 0 */
    if (pIndex) {
      *pIndex=This->index;
      TRACE("returning pIndex=%d\n", *pIndex);
    }

    if (ppTLib) {
      *ppTLib = (ITypeLib *)&This->pTypeLib->ITypeLib2_iface;
      ITypeLib_AddRef(*ppTLib);
      TRACE("returning ppTLib=%p\n", *ppTLib);
    }

    return S_OK;
}

/* ITypeInfo::ReleaseTypeAttr
 *
 * Releases a TYPEATTR previously returned by Get
 *
 */
static void WINAPI ITypeInfo_fnReleaseTypeAttr( ITypeInfo2 *iface,
        TYPEATTR* pTypeAttr)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    TRACE("(%p)->(%p)\n", This, pTypeAttr);
    heap_free(pTypeAttr);
}

/* ITypeInfo::ReleaseFuncDesc
 *
 * Releases a FUNCDESC previously returned by GetFuncDesc. *
 */
static void WINAPI ITypeInfo_fnReleaseFuncDesc(
	ITypeInfo2 *iface,
        FUNCDESC *pFuncDesc)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    SHORT i;

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

    for (i = 0; i < pFuncDesc->cParams; i++)
        TLB_FreeElemDesc(&pFuncDesc->lprgelemdescParam[i]);
    TLB_FreeElemDesc(&pFuncDesc->elemdescFunc);

    SysFreeString((BSTR)pFuncDesc);
}

/* ITypeInfo::ReleaseVarDesc
 *
 * Releases a VARDESC previously returned by GetVarDesc.
 */
static void WINAPI ITypeInfo_fnReleaseVarDesc( ITypeInfo2 *iface,
        VARDESC *pVarDesc)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    TRACE("(%p)->(%p)\n", This, pVarDesc);

    TLB_FreeVarDesc(pVarDesc);
}

/* ITypeInfo2::GetTypeKind
 *
 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo2 * iface,
    TYPEKIND *pTypeKind)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    *pTypeKind = This->typeattr.typekind;
    TRACE("(%p) type 0x%0x\n", This,*pTypeKind);
    return S_OK;
}

/* ITypeInfo2::GetTypeFlags
 *
 * Returns the type flags without any allocations. This returns a DWORD type
 * flag, which expands the type flags without growing the TYPEATTR (type
 * attribute).
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo2 *iface, ULONG *pTypeFlags)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    *pTypeFlags=This->typeattr.wTypeFlags;
    TRACE("(%p) flags 0x%x\n", This,*pTypeFlags);
    return S_OK;
}

/* ITypeInfo2::GetFuncIndexOfMemId
 * Binds to a specific member based on a known DISPID, where the member name
 * is not known (for example, when binding to a default member).
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2 * iface,
    MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    UINT fdc;
    HRESULT result;

    for (fdc = 0; fdc < This->typeattr.cFuncs; ++fdc){
        const TLBFuncDesc *pFuncInfo = &This->funcdescs[fdc];
        if(memid == pFuncInfo->funcdesc.memid && (invKind & pFuncInfo->funcdesc.invkind))
            break;
    }
    if(fdc < This->typeattr.cFuncs) {
        *pFuncIndex = fdc;
        result = S_OK;
    } else
        result = TYPE_E_ELEMENTNOTFOUND;

    TRACE("(%p) memid 0x%08x invKind 0x%04x -> %s\n", This,
          memid, invKind, SUCCEEDED(result) ? "SUCCESS" : "FAILED");
    return result;
}

/* TypeInfo2::GetVarIndexOfMemId
 *
 * Binds to a specific member based on a known DISPID, where the member name
 * is not known (for example, when binding to a default member).
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo2 * iface,
    MEMBERID memid, UINT *pVarIndex)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    TLBVarDesc *pVarInfo;

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

    pVarInfo = TLB_get_vardesc_by_memberid(This->vardescs, This->typeattr.cVars, memid);
    if(!pVarInfo)
        return TYPE_E_ELEMENTNOTFOUND;

    *pVarIndex = (pVarInfo - This->vardescs);

    return S_OK;
}

/* ITypeInfo2::GetCustData
 *
 * Gets the custom data
 */
static HRESULT WINAPI ITypeInfo2_fnGetCustData(
	ITypeInfo2 * iface,
	REFGUID guid,
	VARIANT *pVarVal)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    TLBCustData *pCData;

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

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

    pCData = TLB_get_custdata_by_guid(This->pcustdata_list, guid);

    VariantInit( pVarVal);
    if (pCData)
        VariantCopy( pVarVal, &pCData->data);
    else
        VariantClear( pVarVal );
    return S_OK;
}

/* ITypeInfo2::GetFuncCustData
 *
 * Gets the custom data
 */
static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData(
	ITypeInfo2 * iface,
	UINT index,
	REFGUID guid,
	VARIANT *pVarVal)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    TLBCustData *pCData;
    TLBFuncDesc *pFDesc = &This->funcdescs[index];

    TRACE("%p %u %s %p\n", This, index, debugstr_guid(guid), pVarVal);

    if(index >= This->typeattr.cFuncs)
        return TYPE_E_ELEMENTNOTFOUND;

    pCData = TLB_get_custdata_by_guid(&pFDesc->custdata_list, guid);
    if(!pCData)
        return TYPE_E_ELEMENTNOTFOUND;

    VariantInit(pVarVal);
    VariantCopy(pVarVal, &pCData->data);

    return S_OK;
}

/* ITypeInfo2::GetParamCustData
 *
 * Gets the custom data
 */
static HRESULT WINAPI ITypeInfo2_fnGetParamCustData(
	ITypeInfo2 * iface,
	UINT indexFunc,
	UINT indexParam,
	REFGUID guid,
	VARIANT *pVarVal)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    TLBCustData *pCData;
    TLBFuncDesc *pFDesc = &This->funcdescs[indexFunc];

    TRACE("%p %u %u %s %p\n", This, indexFunc, indexParam,
            debugstr_guid(guid), pVarVal);

    if(indexFunc >= This->typeattr.cFuncs)
        return TYPE_E_ELEMENTNOTFOUND;

    if(indexParam >= pFDesc->funcdesc.cParams)
        return TYPE_E_ELEMENTNOTFOUND;

    pCData = TLB_get_custdata_by_guid(&pFDesc->pParamDesc[indexParam].custdata_list, guid);
    if(!pCData)
        return TYPE_E_ELEMENTNOTFOUND;

    VariantInit(pVarVal);
    VariantCopy(pVarVal, &pCData->data);

    return S_OK;
}

/* ITypeInfo2::GetVarCustData
 *
 * Gets the custom data
 */
static HRESULT WINAPI ITypeInfo2_fnGetVarCustData(
	ITypeInfo2 * iface,
	UINT index,
	REFGUID guid,
	VARIANT *pVarVal)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    TLBCustData *pCData;
    TLBVarDesc *pVDesc = &This->vardescs[index];

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

    if(index >= This->typeattr.cVars)
        return TYPE_E_ELEMENTNOTFOUND;

    pCData = TLB_get_custdata_by_guid(&pVDesc->custdata_list, guid);
    if(!pCData)
        return TYPE_E_ELEMENTNOTFOUND;

    VariantInit(pVarVal);
    VariantCopy(pVarVal, &pCData->data);

    return S_OK;
}

/* ITypeInfo2::GetImplCustData
 *
 * Gets the custom data
 */
static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData(
	ITypeInfo2 * iface,
	UINT index,
	REFGUID guid,
	VARIANT *pVarVal)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    TLBCustData *pCData;
    TLBImplType *pRDesc = &This->impltypes[index];

    TRACE("%p %u %s %p\n", This, index, debugstr_guid(guid), pVarVal);

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

    pCData = TLB_get_custdata_by_guid(&pRDesc->custdata_list, guid);
    if(!pCData)
        return TYPE_E_ELEMENTNOTFOUND;

    VariantInit(pVarVal);
    VariantCopy(pVarVal, &pCData->data);

    return S_OK;
}

/* ITypeInfo2::GetDocumentation2
 *
 * Retrieves the documentation string, the complete Help file name and path,
 * the localization context to use, and the context ID for the library Help
 * topic in the Help file.
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(
	ITypeInfo2 * iface,
	MEMBERID memid,
	LCID lcid,
	BSTR *pbstrHelpString,
	DWORD *pdwHelpStringContext,
	BSTR *pbstrHelpStringDll)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    const TLBFuncDesc *pFDesc;
    const TLBVarDesc *pVDesc;
    TRACE("(%p) memid %d lcid(0x%x)  HelpString(%p) "
          "HelpStringContext(%p) HelpStringDll(%p)\n",
          This, memid, lcid, pbstrHelpString, pdwHelpStringContext,
          pbstrHelpStringDll );
    /* the help string should be obtained from the helpstringdll,
     * using the _DLLGetDocumentation function, based on the supplied
     * lcid. Nice to do sometime...
     */
    if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
        if(pbstrHelpString)
            *pbstrHelpString=SysAllocString(TLB_get_bstr(This->Name));
        if(pdwHelpStringContext)
            *pdwHelpStringContext=This->dwHelpStringContext;
        if(pbstrHelpStringDll)
            *pbstrHelpStringDll=
                SysAllocString(TLB_get_bstr(This->pTypeLib->HelpStringDll));/* FIXME */
        return S_OK;
    }else {/* for a member */
        pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->typeattr.cFuncs, memid);
        if(pFDesc){
            if(pbstrHelpString)
                *pbstrHelpString=SysAllocString(TLB_get_bstr(pFDesc->HelpString));
            if(pdwHelpStringContext)
                *pdwHelpStringContext=pFDesc->HelpStringContext;
            if(pbstrHelpStringDll)
                *pbstrHelpStringDll=
                    SysAllocString(TLB_get_bstr(This->pTypeLib->HelpStringDll));/* FIXME */
            return S_OK;
        }
        pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->typeattr.cVars, memid);
        if(pVDesc){
            if(pbstrHelpString)
                *pbstrHelpString=SysAllocString(TLB_get_bstr(pVDesc->HelpString));
            if(pdwHelpStringContext)
                *pdwHelpStringContext=pVDesc->HelpStringContext;
            if(pbstrHelpStringDll)
                *pbstrHelpStringDll=
                    SysAllocString(TLB_get_bstr(This->pTypeLib->HelpStringDll));/* FIXME */
            return S_OK;
        }
    }
    return TYPE_E_ELEMENTNOTFOUND;
}

/* ITypeInfo2::GetAllCustData
 *
 * Gets all custom data items for the Type info.
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllCustData(
	ITypeInfo2 * iface,
	CUSTDATA *pCustData)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);

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

    return TLB_copy_all_custdata(This->pcustdata_list, pCustData);
}

/* ITypeInfo2::GetAllFuncCustData
 *
 * Gets all custom data items for the specified Function
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData(
	ITypeInfo2 * iface,
	UINT index,
	CUSTDATA *pCustData)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    TLBFuncDesc *pFDesc = &This->funcdescs[index];

    TRACE("%p %u %p\n", This, index, pCustData);

    if(index >= This->typeattr.cFuncs)
        return TYPE_E_ELEMENTNOTFOUND;

    return TLB_copy_all_custdata(&pFDesc->custdata_list, pCustData);
}

/* ITypeInfo2::GetAllParamCustData
 *
 * Gets all custom data items for the Functions
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo2 * iface,
    UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    TLBFuncDesc *pFDesc = &This->funcdescs[indexFunc];

    TRACE("%p %u %u %p\n", This, indexFunc, indexParam, pCustData);

    if(indexFunc >= This->typeattr.cFuncs)
        return TYPE_E_ELEMENTNOTFOUND;

    if(indexParam >= pFDesc->funcdesc.cParams)
        return TYPE_E_ELEMENTNOTFOUND;

    return TLB_copy_all_custdata(&pFDesc->pParamDesc[indexParam].custdata_list, pCustData);
}

/* ITypeInfo2::GetAllVarCustData
 *
 * Gets all custom data items for the specified Variable
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo2 * iface,
    UINT index, CUSTDATA *pCustData)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    TLBVarDesc * pVDesc = &This->vardescs[index];

    TRACE("%p %u %p\n", This, index, pCustData);

    if(index >= This->typeattr.cVars)
        return TYPE_E_ELEMENTNOTFOUND;

    return TLB_copy_all_custdata(&pVDesc->custdata_list, pCustData);
}

/* ITypeInfo2::GetAllImplCustData
 *
 * Gets all custom data items for the specified implementation type
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData(
	ITypeInfo2 * iface,
	UINT index,
	CUSTDATA *pCustData)
{
    ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
    TLBImplType *pRDesc = &This->impltypes[index];

    TRACE("%p %u %p\n", This, index, pCustData);

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

    return TLB_copy_all_custdata(&pRDesc->custdata_list, pCustData);
}

static const ITypeInfo2Vtbl tinfvt =
{

    ITypeInfo_fnQueryInterface,
    ITypeInfo_fnAddRef,
    ITypeInfo_fnRelease,

    ITypeInfo_fnGetTypeAttr,
    ITypeInfo_fnGetTypeComp,
    ITypeInfo_fnGetFuncDesc,
    ITypeInfo_fnGetVarDesc,
    ITypeInfo_fnGetNames,
    ITypeInfo_fnGetRefTypeOfImplType,
    ITypeInfo_fnGetImplTypeFlags,
    ITypeInfo_fnGetIDsOfNames,
    ITypeInfo_fnInvoke,
    ITypeInfo_fnGetDocumentation,
    ITypeInfo_fnGetDllEntry,
    ITypeInfo_fnGetRefTypeInfo,
    ITypeInfo_fnAddressOfMember,
    ITypeInfo_fnCreateInstance,
    ITypeInfo_fnGetMops,
    ITypeInfo_fnGetContainingTypeLib,
    ITypeInfo_fnReleaseTypeAttr,
    ITypeInfo_fnReleaseFuncDesc,
    ITypeInfo_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,
};

/******************************************************************************
 * CreateDispTypeInfo [OLEAUT32.31]
 *
 * Build type information for an object so it can be called through an
 * IDispatch interface.
 *
 * RETURNS
 *  Success: S_OK. pptinfo contains the created ITypeInfo object.
 *  Failure: E_INVALIDARG, if one or more arguments is invalid.
 *
 * NOTES
 *  This call allows an objects methods to be accessed through IDispatch, by
 *  building an ITypeInfo object that IDispatch can use to call through.
 */
HRESULT WINAPI CreateDispTypeInfo(
	INTERFACEDATA *pidata, /* [I] Description of the interface to build type info for */
	LCID lcid, /* [I] Locale Id */
	ITypeInfo **pptinfo) /* [O] Destination for created ITypeInfo object */
{
    ITypeInfoImpl *pTIClass, *pTIIface;
    ITypeLibImpl *pTypeLibImpl;
    unsigned int param, func;
    TLBFuncDesc *pFuncDesc;
    TLBRefType *ref;

    TRACE("\n");
    pTypeLibImpl = TypeLibImpl_Constructor();
    if (!pTypeLibImpl) return E_FAIL;

    pTypeLibImpl->TypeInfoCount = 2;
    pTypeLibImpl->typeinfos = heap_alloc_zero(pTypeLibImpl->TypeInfoCount * sizeof(ITypeInfoImpl*));

    pTIIface = pTypeLibImpl->typeinfos[0] = ITypeInfoImpl_Constructor();
    pTIIface->pTypeLib = pTypeLibImpl;
    pTIIface->index = 0;
    pTIIface->Name = NULL;
    pTIIface->dwHelpContext = -1;
    pTIIface->guid = NULL;
    pTIIface->typeattr.lcid = lcid;
    pTIIface->typeattr.typekind = TKIND_INTERFACE;
    pTIIface->typeattr.wMajorVerNum = 0;
    pTIIface->typeattr.wMinorVerNum = 0;
    pTIIface->typeattr.cbAlignment = 2;
    pTIIface->typeattr.cbSizeInstance = -1;
    pTIIface->typeattr.cbSizeVft = -1;
    pTIIface->typeattr.cFuncs = 0;
    pTIIface->typeattr.cImplTypes = 0;
    pTIIface->typeattr.cVars = 0;
    pTIIface->typeattr.wTypeFlags = 0;
    pTIIface->hreftype = 0;

    pTIIface->funcdescs = TLBFuncDesc_Alloc(pidata->cMembers);
    pFuncDesc = pTIIface->funcdescs;
    for(func = 0; func < pidata->cMembers; func++) {
        METHODDATA *md = pidata->pmethdata + func;
        pFuncDesc->Name = TLB_append_str(&pTypeLibImpl->name_list, md->szName);
        pFuncDesc->funcdesc.memid = md->dispid;
        pFuncDesc->funcdesc.lprgscode = NULL;
        pFuncDesc->funcdesc.funckind = FUNC_VIRTUAL;
        pFuncDesc->funcdesc.invkind = md->wFlags;
        pFuncDesc->funcdesc.callconv = md->cc;
        pFuncDesc->funcdesc.cParams = md->cArgs;
        pFuncDesc->funcdesc.cParamsOpt = 0;
        pFuncDesc->funcdesc.oVft = md->iMeth * sizeof(void *);
        pFuncDesc->funcdesc.cScodes = 0;
        pFuncDesc->funcdesc.wFuncFlags = 0;
        pFuncDesc->funcdesc.elemdescFunc.tdesc.vt = md->vtReturn;
        pFuncDesc->funcdesc.elemdescFunc.u.paramdesc.wParamFlags = PARAMFLAG_NONE;
        pFuncDesc->funcdesc.elemdescFunc.u.paramdesc.pparamdescex = NULL;
        pFuncDesc->funcdesc.lprgelemdescParam = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                                                              md->cArgs * sizeof(ELEMDESC));
        pFuncDesc->pParamDesc = TLBParDesc_Constructor(md->cArgs);
        for(param = 0; param < md->cArgs; param++) {
            pFuncDesc->funcdesc.lprgelemdescParam[param].tdesc.vt = md->ppdata[param].vt;
            pFuncDesc->pParamDesc[param].Name = TLB_append_str(&pTypeLibImpl->name_list, md->ppdata[param].szName);
        }
        pFuncDesc->helpcontext = 0;
        pFuncDesc->HelpStringContext = 0;
        pFuncDesc->HelpString = NULL;
        pFuncDesc->Entry = NULL;
        list_init(&pFuncDesc->custdata_list);
        pTIIface->typeattr.cFuncs++;
        ++pFuncDesc;
    }

    dump_TypeInfo(pTIIface);

    pTIClass = pTypeLibImpl->typeinfos[1] = ITypeInfoImpl_Constructor();
    pTIClass->pTypeLib = pTypeLibImpl;
    pTIClass->index = 1;
    pTIClass->Name = NULL;
    pTIClass->dwHelpContext = -1;
    pTIClass->guid = NULL;
    pTIClass->typeattr.lcid = lcid;
    pTIClass->typeattr.typekind = TKIND_COCLASS;
    pTIClass->typeattr.wMajorVerNum = 0;
    pTIClass->typeattr.wMinorVerNum = 0;
    pTIClass->typeattr.cbAlignment = 2;
    pTIClass->typeattr.cbSizeInstance = -1;
    pTIClass->typeattr.cbSizeVft = -1;
    pTIClass->typeattr.cFuncs = 0;
    pTIClass->typeattr.cImplTypes = 1;
    pTIClass->typeattr.cVars = 0;
    pTIClass->typeattr.wTypeFlags = 0;
    pTIClass->hreftype = sizeof(MSFT_TypeInfoBase);

    pTIClass->impltypes = TLBImplType_Alloc(1);

    ref = heap_alloc_zero(sizeof(*ref));
    ref->pImpTLInfo = TLB_REF_INTERNAL;
    list_add_head(&pTypeLibImpl->ref_list, &ref->entry);

    dump_TypeInfo(pTIClass);

    *pptinfo = (ITypeInfo *)&pTIClass->ITypeInfo2_iface;

    ITypeInfo_AddRef(*pptinfo);
    ITypeLib2_Release(&pTypeLibImpl->ITypeLib2_iface);

    return S_OK;

}

static HRESULT WINAPI ITypeComp_fnQueryInterface(ITypeComp * iface, REFIID riid, LPVOID * ppv)
{
    ITypeInfoImpl *This = info_impl_from_ITypeComp(iface);

    return ITypeInfo2_QueryInterface(&This->ITypeInfo2_iface, riid, ppv);
}

static ULONG WINAPI ITypeComp_fnAddRef(ITypeComp * iface)
{
    ITypeInfoImpl *This = info_impl_from_ITypeComp(iface);

    return ITypeInfo2_AddRef(&This->ITypeInfo2_iface);
}

static ULONG WINAPI ITypeComp_fnRelease(ITypeComp * iface)
{
    ITypeInfoImpl *This = info_impl_from_ITypeComp(iface);

    return ITypeInfo2_Release(&This->ITypeInfo2_iface);
}

static HRESULT WINAPI ITypeComp_fnBind(
    ITypeComp * iface,
    OLECHAR * szName,
    ULONG lHash,
    WORD wFlags,
    ITypeInfo ** ppTInfo,
    DESCKIND * pDescKind,
    BINDPTR * pBindPtr)
{
    ITypeInfoImpl *This = info_impl_from_ITypeComp(iface);
    const TLBFuncDesc *pFDesc;
    const TLBVarDesc *pVDesc;
    HRESULT hr = DISP_E_MEMBERNOTFOUND;
    UINT fdc;

    TRACE("(%p)->(%s, %x, 0x%x, %p, %p, %p)\n", This, debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr);

    *pDescKind = DESCKIND_NONE;
    pBindPtr->lpfuncdesc = NULL;
    *ppTInfo = NULL;

    for(fdc = 0; fdc < This->typeattr.cFuncs; ++fdc){
        pFDesc = &This->funcdescs[fdc];
        if (!lstrcmpiW(TLB_get_bstr(pFDesc->Name), szName)) {
            if (!wFlags || (pFDesc->funcdesc.invkind & wFlags))
                break;
            else
                /* name found, but wrong flags */
                hr = TYPE_E_TYPEMISMATCH;
        }
    }

    if (fdc < This->typeattr.cFuncs)
    {
        HRESULT hr = TLB_AllocAndInitFuncDesc(
            &pFDesc->funcdesc,
            &pBindPtr->lpfuncdesc,
            This->typeattr.typekind == TKIND_DISPATCH);
        if (FAILED(hr))
            return hr;
        *pDescKind = DESCKIND_FUNCDESC;
        *ppTInfo = (ITypeInfo *)&This->ITypeInfo2_iface;
        ITypeInfo_AddRef(*ppTInfo);
        return S_OK;
    } else {
        pVDesc = TLB_get_vardesc_by_name(This->vardescs, This->typeattr.cVars, szName);
        if(pVDesc){
            HRESULT hr = TLB_AllocAndInitVarDesc(&pVDesc->vardesc, &pBindPtr->lpvardesc);
            if (FAILED(hr))
                return hr;
            *pDescKind = DESCKIND_VARDESC;
            *ppTInfo = (ITypeInfo *)&This->ITypeInfo2_iface;
            ITypeInfo_AddRef(*ppTInfo);
            return S_OK;
        }
    }

    if (hr == DISP_E_MEMBERNOTFOUND && This->impltypes) {
        /* recursive search */
        ITypeInfo *pTInfo;
        ITypeComp *pTComp;
        HRESULT hr;
        hr=ITypeInfo2_GetRefTypeInfo(&This->ITypeInfo2_iface, This->impltypes[0].hRef, &pTInfo);
        if (SUCCEEDED(hr))
        {
            hr = ITypeInfo_GetTypeComp(pTInfo,&pTComp);
            ITypeInfo_Release(pTInfo);
        }
        if (SUCCEEDED(hr))
        {
            hr = ITypeComp_Bind(pTComp, szName, lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
            ITypeComp_Release(pTComp);
            if (SUCCEEDED(hr) && *pDescKind == DESCKIND_FUNCDESC &&
                    This->typeattr.typekind == TKIND_DISPATCH)
            {
                FUNCDESC *tmp = pBindPtr->lpfuncdesc;
                hr = TLB_AllocAndInitFuncDesc(tmp, &pBindPtr->lpfuncdesc, TRUE);
                SysFreeString((BSTR)tmp);
            }
            return hr;
        }
        WARN("Could not search inherited interface!\n");
    }
    if (hr == DISP_E_MEMBERNOTFOUND)
        hr = S_OK;
    TRACE("did not find member with name %s, flags 0x%x\n", debugstr_w(szName), wFlags);
    return hr;
}

static HRESULT WINAPI ITypeComp_fnBindType(
    ITypeComp * iface,
    OLECHAR * szName,
    ULONG lHash,
    ITypeInfo ** ppTInfo,
    ITypeComp ** ppTComp)
{
    TRACE("(%s, %x, %p, %p)\n", debugstr_w(szName), lHash, ppTInfo, ppTComp);

    /* strange behaviour (does nothing) but like the
     * original */

    if (!ppTInfo || !ppTComp)
        return E_POINTER;

    *ppTInfo = NULL;
    *ppTComp = NULL;

    return S_OK;
}

static const ITypeCompVtbl tcompvt =
{

    ITypeComp_fnQueryInterface,
    ITypeComp_fnAddRef,
    ITypeComp_fnRelease,

    ITypeComp_fnBind,
    ITypeComp_fnBindType
};

HRESULT WINAPI CreateTypeLib2(SYSKIND syskind, LPCOLESTR szFile,
        ICreateTypeLib2** ppctlib)
{
    ITypeLibImpl *This;
    HRESULT hres;

    TRACE("(%d,%s,%p)\n", syskind, debugstr_w(szFile), ppctlib);

    if (!szFile) return E_INVALIDARG;

    This = TypeLibImpl_Constructor();
    if (!This)
        return E_OUTOFMEMORY;

    This->lcid = GetSystemDefaultLCID();
    This->syskind = syskind;
    This->ptr_size = get_ptr_size(syskind);

    This->path = heap_alloc((lstrlenW(szFile) + 1) * sizeof(WCHAR));
    if (!This->path) {
        ITypeLib2_Release(&This->ITypeLib2_iface);
        return E_OUTOFMEMORY;
    }
    lstrcpyW(This->path, szFile);

    hres = ITypeLib2_QueryInterface(&This->ITypeLib2_iface, &IID_ICreateTypeLib2, (LPVOID*)ppctlib);
    ITypeLib2_Release(&This->ITypeLib2_iface);
    return hres;
}

static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface(ICreateTypeLib2 *iface,
        REFIID riid, void **object)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);

    return ITypeLib2_QueryInterface(&This->ITypeLib2_iface, riid, object);
}

static ULONG WINAPI ICreateTypeLib2_fnAddRef(ICreateTypeLib2 *iface)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);

    return ITypeLib2_AddRef(&This->ITypeLib2_iface);
}

static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);

    return ITypeLib2_Release(&This->ITypeLib2_iface);
}

static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo(ICreateTypeLib2 *iface,
        LPOLESTR name, TYPEKIND kind, ICreateTypeInfo **ctinfo)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);
    ITypeInfoImpl *info;
    HRESULT hres;

    TRACE("%p %s %d %p\n", This, wine_dbgstr_w(name), kind, ctinfo);

    if (!ctinfo || !name)
        return E_INVALIDARG;

    info = TLB_get_typeinfo_by_name(This->typeinfos, This->TypeInfoCount, name);
    if (info)
        return TYPE_E_NAMECONFLICT;

    if (This->typeinfos)
        This->typeinfos = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->typeinfos,
                sizeof(ITypeInfoImpl*) * (This->TypeInfoCount + 1));
    else
        This->typeinfos = heap_alloc_zero(sizeof(ITypeInfoImpl*));

    info = This->typeinfos[This->TypeInfoCount] = ITypeInfoImpl_Constructor();

    info->pTypeLib = This;
    info->Name = TLB_append_str(&This->name_list, name);
    info->index = This->TypeInfoCount;
    info->typeattr.typekind = kind;
    info->typeattr.cbAlignment = 4;

    switch (info->typeattr.typekind) {
    case TKIND_ENUM:
    case TKIND_INTERFACE:
    case TKIND_DISPATCH:
    case TKIND_COCLASS:
        info->typeattr.cbSizeInstance = This->ptr_size;
        break;
    case TKIND_RECORD:
    case TKIND_UNION:
        info->typeattr.cbSizeInstance = 0;
        break;
    case TKIND_MODULE:
        info->typeattr.cbSizeInstance = 2;
        break;
    case TKIND_ALIAS:
        info->typeattr.cbSizeInstance = -0x75;
        break;
    default:
        FIXME("unrecognized typekind %d\n", info->typeattr.typekind);
        info->typeattr.cbSizeInstance = 0xdeadbeef;
        break;
    }

    hres = ITypeInfo2_QueryInterface(&info->ITypeInfo2_iface,
            &IID_ICreateTypeInfo, (void **)ctinfo);
    if (FAILED(hres)) {
        ITypeInfo2_Release(&info->ITypeInfo2_iface);
        return hres;
    }

    info->hreftype = info->index * sizeof(MSFT_TypeInfoBase);

    ++This->TypeInfoCount;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeLib2_fnSetName(ICreateTypeLib2 *iface,
        LPOLESTR name)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);

    TRACE("%p %s\n", This, wine_dbgstr_w(name));

    if (!name)
        return E_INVALIDARG;

    This->Name = TLB_append_str(&This->name_list, name);

    return S_OK;
}

static HRESULT WINAPI ICreateTypeLib2_fnSetVersion(ICreateTypeLib2 *iface,
        WORD majorVerNum, WORD minorVerNum)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);

    TRACE("%p %d %d\n", This, majorVerNum, minorVerNum);

    This->ver_major = majorVerNum;
    This->ver_minor = minorVerNum;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeLib2_fnSetGuid(ICreateTypeLib2 *iface,
        REFGUID guid)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);

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

    This->guid = TLB_append_guid(&This->guid_list, guid, -2);

    return S_OK;
}

static HRESULT WINAPI ICreateTypeLib2_fnSetDocString(ICreateTypeLib2 *iface,
        LPOLESTR doc)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);

    TRACE("%p %s\n", This, wine_dbgstr_w(doc));

    if (!doc)
        return E_INVALIDARG;

    This->DocString = TLB_append_str(&This->string_list, doc);

    return S_OK;
}

static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 *iface,
        LPOLESTR helpFileName)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);

    TRACE("%p %s\n", This, wine_dbgstr_w(helpFileName));

    if (!helpFileName)
        return E_INVALIDARG;

    This->HelpFile = TLB_append_str(&This->string_list, helpFileName);

    return S_OK;
}

static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 *iface,
        DWORD helpContext)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);

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

    This->dwHelpContext = helpContext;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 *iface,
        LCID lcid)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);

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

    This->set_lcid = lcid;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeLib2_fnSetLibFlags(ICreateTypeLib2 *iface,
        UINT libFlags)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);

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

    This->libflags = libFlags;

    return S_OK;
}

typedef struct tagWMSFT_SegContents {
    DWORD len;
    void *data;
} WMSFT_SegContents;

typedef struct tagWMSFT_TLBFile {
    MSFT_Header header;
    WMSFT_SegContents typeinfo_seg;
    WMSFT_SegContents impfile_seg;
    WMSFT_SegContents impinfo_seg;
    WMSFT_SegContents ref_seg;
    WMSFT_SegContents guidhash_seg;
    WMSFT_SegContents guid_seg;
    WMSFT_SegContents namehash_seg;
    WMSFT_SegContents name_seg;
    WMSFT_SegContents string_seg;
    WMSFT_SegContents typdesc_seg;
    WMSFT_SegContents arraydesc_seg;
    WMSFT_SegContents custdata_seg;
    WMSFT_SegContents cdguids_seg;
    MSFT_SegDir segdir;
    WMSFT_SegContents aux_seg;
} WMSFT_TLBFile;

static HRESULT WMSFT_compile_strings(ITypeLibImpl *This,
        WMSFT_TLBFile *file)
{
    TLBString *str;
    UINT last_offs;
    char *data;

    file->string_seg.len = 0;
    LIST_FOR_EACH_ENTRY(str, &This->string_list, TLBString, entry) {
        int size;

        size = WideCharToMultiByte(CP_ACP, 0, str->str, strlenW(str->str), NULL, 0, NULL, NULL);
        if (size == 0)
            return E_UNEXPECTED;

        size += sizeof(INT16);
        if (size % 4)
            size = (size + 4) & ~0x3;
        if (size < 8)
            size = 8;

        file->string_seg.len += size;

        /* temporarily use str->offset to store the length of the aligned,
         * converted string */
        str->offset = size;
    }

    file->string_seg.data = data = heap_alloc(file->string_seg.len);

    last_offs = 0;
    LIST_FOR_EACH_ENTRY(str, &This->string_list, TLBString, entry) {
        int size;

        size = WideCharToMultiByte(CP_ACP, 0, str->str, strlenW(str->str),
                data + sizeof(INT16), file->string_seg.len - last_offs - sizeof(INT16), NULL, NULL);
        if (size == 0) {
            heap_free(file->string_seg.data);
            return E_UNEXPECTED;
        }

        *((INT16*)data) = size;

        memset(data + sizeof(INT16) + size, 0x57, str->offset - size - sizeof(INT16));

        size = str->offset;
        data += size;
        str->offset = last_offs;
        last_offs += size;
    }

    return S_OK;
}

static HRESULT WMSFT_compile_names(ITypeLibImpl *This,
        WMSFT_TLBFile *file)
{
    TLBString *str;
    UINT last_offs;
    char *data;
    MSFT_NameIntro *last_intro = NULL;

    file->header.nametablecount = 0;
    file->header.nametablechars = 0;

    file->name_seg.len = 0;
    LIST_FOR_EACH_ENTRY(str, &This->name_list, TLBString, entry) {
        int size;

        size = strlenW(str->str);
        file->header.nametablechars += size;
        file->header.nametablecount++;

        size = WideCharToMultiByte(CP_ACP, 0, str->str, size, NULL, 0, NULL, NULL);
        if (size == 0)
            return E_UNEXPECTED;

        size += sizeof(MSFT_NameIntro);
        if (size % 4)
            size = (size + 4) & ~0x3;
        if (size < 8)
            size = 8;

        file->name_seg.len += size;

        /* temporarily use str->offset to store the length of the aligned,
         * converted string */
        str->offset = size;
    }

    /* Allocate bigger buffer so we can temporarily NULL terminate the name */
    file->name_seg.data = data = heap_alloc(file->name_seg.len+1);

    last_offs = 0;
    LIST_FOR_EACH_ENTRY(str, &This->name_list, TLBString, entry) {
        int size, hash;
        MSFT_NameIntro *intro = (MSFT_NameIntro*)data;

        size = WideCharToMultiByte(CP_ACP, 0, str->str, strlenW(str->str),
                data + sizeof(MSFT_NameIntro),
                file->name_seg.len - last_offs - sizeof(MSFT_NameIntro), NULL, NULL);
        if (size == 0) {
            heap_free(file->name_seg.data);
            return E_UNEXPECTED;
        }
        data[sizeof(MSFT_NameIntro) + size] = '\0';

        intro->hreftype = -1; /* TODO? */
        intro->namelen = size & 0xFF;
        /* TODO: namelen & 0xFF00 == ??? maybe HREF type indicator? */
        hash = LHashValOfNameSysA(This->syskind, This->lcid, data + sizeof(MSFT_NameIntro));
        intro->namelen |= hash << 16;
        intro->next_hash = ((DWORD*)file->namehash_seg.data)[hash & 0x7f];
        ((DWORD*)file->namehash_seg.data)[hash & 0x7f] = last_offs;

        memset(data + sizeof(MSFT_NameIntro) + size, 0x57,
                str->offset - size - sizeof(MSFT_NameIntro));

        /* update str->offset to actual value to use in other
         * compilation functions that require positions within
         * the string table */
        last_intro = intro;
        size = str->offset;
        data += size;
        str->offset = last_offs;
        last_offs += size;
    }

    if(last_intro)
        last_intro->hreftype = 0; /* last one is 0? */

    return S_OK;
}

static inline int hash_guid(GUID *guid)
{
    int i, hash = 0;

    for (i = 0; i < 8; i ++)
        hash ^= ((const short *)guid)[i];

    return hash & 0x1f;
}

static HRESULT WMSFT_compile_guids(ITypeLibImpl *This, WMSFT_TLBFile *file)
{
    TLBGuid *guid;
    MSFT_GuidEntry *entry;
    DWORD offs;
    int hash_key, *guidhashtab;

    file->guid_seg.len = sizeof(MSFT_GuidEntry) * list_count(&This->guid_list);
    file->guid_seg.data = heap_alloc(file->guid_seg.len);

    entry = file->guid_seg.data;
    offs = 0;
    guidhashtab = file->guidhash_seg.data;
    LIST_FOR_EACH_ENTRY(guid, &This->guid_list, TLBGuid, entry){
        memcpy(&entry->guid, &guid->guid, sizeof(GUID));
        entry->hreftype = guid->hreftype;

        hash_key = hash_guid(&guid->guid);
        entry->next_hash = guidhashtab[hash_key];
        guidhashtab[hash_key] = offs;

        guid->offset = offs;
        offs += sizeof(MSFT_GuidEntry);
        ++entry;
    }

    return S_OK;
}

static DWORD WMSFT_encode_variant(VARIANT *value, WMSFT_TLBFile *file)
{
    VARIANT v = *value;
    VARTYPE arg_type = V_VT(value);
    int mask = 0;
    HRESULT hres;
    DWORD ret = file->custdata_seg.len;

    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)){
            ERR("VariantChangeType failed: %08x\n", hres);
            return -1;
        }
    }

    /* Check if default value can be stored in-place */
    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;
        return ((0x80 + 0x4 * V_VT(value)) << 24) | (V_UI4(&v) & mask);
    }

    /* have to allocate space in custdata_seg */
    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;

        if(file->custdata_seg.data){
            file->custdata_seg.data = heap_realloc(file->custdata_seg.data, file->custdata_seg.len + sizeof(int) * 2);
            data = (int *)(((char *)file->custdata_seg.data) + file->custdata_seg.len);
            file->custdata_seg.len += sizeof(int) * 2;
        }else{
            file->custdata_seg.len = sizeof(int) * 2;
            data = file->custdata_seg.data = heap_alloc(file->custdata_seg.len);
        }

        data[0] = V_VT(value) + (V_UI4(&v) << 16);
        data[1] = (V_UI4(&v) >> 16) + 0x57570000;

        /* TODO: Check if the encoded data is already present in custdata_seg */

        return ret;
    }

    case VT_BSTR: {
        int i, len = (6+SysStringLen(V_BSTR(&v))+3) & ~0x3;
        char *data;

        if(file->custdata_seg.data){
            file->custdata_seg.data = heap_realloc(file->custdata_seg.data, file->custdata_seg.len + len);
            data = ((char *)file->custdata_seg.data) + file->custdata_seg.len;
            file->custdata_seg.len += len;
        }else{
            file->custdata_seg.len = len;
            data = file->custdata_seg.data = heap_alloc(file->custdata_seg.len);
        }

        *((unsigned short *)data) = V_VT(value);
        *((unsigned int *)(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;

        /* TODO: Check if the encoded data is already present in custdata_seg */

        return ret;
    }
    default:
        FIXME("Argument type not yet handled\n");
        return -1;
    }
}

static DWORD WMSFT_append_typedesc(TYPEDESC *desc, WMSFT_TLBFile *file, DWORD *out_mix, INT16 *out_size);

static DWORD WMSFT_append_arraydesc(ARRAYDESC *desc, WMSFT_TLBFile *file)
{
    DWORD offs = file->arraydesc_seg.len;
    DWORD *encoded;
    USHORT i;

    /* TODO: we should check for duplicates, but that's harder because each
     * chunk is variable length (really we should store TYPEDESC and ARRAYDESC
     * at the library-level) */

    file->arraydesc_seg.len += (2 + desc->cDims * 2) * sizeof(DWORD);
    if(!file->arraydesc_seg.data)
        file->arraydesc_seg.data = heap_alloc(file->arraydesc_seg.len);
    else
        file->arraydesc_seg.data = heap_realloc(file->arraydesc_seg.data, file->arraydesc_seg.len);
    encoded = (DWORD*)((char *)file->arraydesc_seg.data + offs);

    encoded[0] = WMSFT_append_typedesc(&desc->tdescElem, file, NULL, NULL);
    encoded[1] = desc->cDims | ((desc->cDims * 2 * sizeof(DWORD)) << 16);
    for(i = 0; i < desc->cDims; ++i){
        encoded[2 + i * 2] =  desc->rgbounds[i].cElements;
        encoded[2 + i * 2 + 1] = desc->rgbounds[i].lLbound;
    }

    return offs;
}

static DWORD WMSFT_append_typedesc(TYPEDESC *desc, WMSFT_TLBFile *file, DWORD *out_mix, INT16 *out_size)
{
    DWORD junk;
    INT16 junk2;
    DWORD offs = 0;
    DWORD encoded[2];
    VARTYPE vt, subtype;
    char *data;

    if(!desc)
        return -1;

    if(!out_mix)
        out_mix = &junk;
    if(!out_size)
        out_size = &junk2;

    vt = desc->vt & VT_TYPEMASK;

    if(vt == VT_PTR || vt == VT_SAFEARRAY){
        DWORD mix;
        encoded[1] = WMSFT_append_typedesc(desc->u.lptdesc, file, &mix, out_size);
        encoded[0] = desc->vt | ((mix | VT_BYREF) << 16);
        *out_mix = 0x7FFF;
        *out_size += 2 * sizeof(DWORD);
    }else if(vt == VT_CARRAY){
        encoded[0] = desc->vt | (0x7FFE << 16);
        encoded[1] = WMSFT_append_arraydesc(desc->u.lpadesc, file);
        *out_mix = 0x7FFE;
    }else if(vt == VT_USERDEFINED){
        encoded[0] = desc->vt | (0x7FFF << 16);
        encoded[1] = desc->u.hreftype;
        *out_mix = 0x7FFF; /* FIXME: Should get TYPEKIND of the hreftype, e.g. TKIND_ENUM => VT_I4 */
    }else{
        TRACE("Mixing in-place, VT: 0x%x\n", desc->vt);

        switch(vt){
        case VT_INT:
            subtype = VT_I4;
            break;
        case VT_UINT:
            subtype = VT_UI4;
            break;
        case VT_VOID:
            subtype = VT_EMPTY;
            break;
        default:
            subtype = vt;
            break;
        }

        *out_mix = subtype;
        return 0x80000000 | (subtype << 16) | desc->vt;
    }

    data = file->typdesc_seg.data;
    while(offs < file->typdesc_seg.len){
        if(!memcmp(&data[offs], encoded, sizeof(encoded)))
            return offs;
        offs += sizeof(encoded);
    }

    file->typdesc_seg.len += sizeof(encoded);
    if(!file->typdesc_seg.data)
        data = file->typdesc_seg.data = heap_alloc(file->typdesc_seg.len);
    else
        data = file->typdesc_seg.data = heap_realloc(file->typdesc_seg.data, file->typdesc_seg.len);

    memcpy(&data[offs], encoded, sizeof(encoded));

    return offs;
}

static DWORD WMSFT_compile_custdata(struct list *custdata_list, WMSFT_TLBFile *file)
{
    WMSFT_SegContents *cdguids_seg = &file->cdguids_seg;
    DWORD ret = cdguids_seg->len, offs;
    MSFT_CDGuid *cdguid;
    TLBCustData *cd;

    if(list_empty(custdata_list))
        return -1;

    cdguids_seg->len += sizeof(MSFT_CDGuid) * list_count(custdata_list);
    if(!cdguids_seg->data){
        cdguid = cdguids_seg->data = heap_alloc(cdguids_seg->len);
    }else {
        cdguids_seg->data = heap_realloc(cdguids_seg->data, cdguids_seg->len);
        cdguid = (MSFT_CDGuid*)((char*)cdguids_seg->data + ret);
    }

    offs = ret + sizeof(MSFT_CDGuid);
    LIST_FOR_EACH_ENTRY(cd, custdata_list, TLBCustData, entry){
        cdguid->GuidOffset = cd->guid->offset;
        cdguid->DataOffset = WMSFT_encode_variant(&cd->data, file);
        cdguid->next = offs;
        offs += sizeof(MSFT_CDGuid);
        ++cdguid;
    }

    --cdguid;
    cdguid->next = -1;

    return ret;
}

static DWORD WMSFT_compile_typeinfo_aux(ITypeInfoImpl *info,
        WMSFT_TLBFile *file)
{
    WMSFT_SegContents *aux_seg = &file->aux_seg;
    DWORD ret = aux_seg->len, i, j, recorded_size = 0, extra_size = 0;
    MSFT_VarRecord *varrecord;
    MSFT_FuncRecord *funcrecord;
    MEMBERID *memid;
    DWORD *name, *offsets, offs;

    for(i = 0; i < info->typeattr.cFuncs; ++i){
        TLBFuncDesc *desc = &info->funcdescs[i];

        recorded_size += 6 * sizeof(INT); /* mandatory fields */

        /* optional fields */
        /* TODO: oArgCustData - FuncSetCustData not impl yet */
        if(!list_empty(&desc->custdata_list))
            recorded_size += 7 * sizeof(INT);
        else if(desc->HelpStringContext != 0)
            recorded_size += 6 * sizeof(INT);
        /* res9? resA? */
        else if(desc->Entry)
            recorded_size += 3 * sizeof(INT);
        else if(desc->HelpString)
            recorded_size += 2 * sizeof(INT);
        else if(desc->helpcontext)
            recorded_size += sizeof(INT);

        recorded_size += desc->funcdesc.cParams * sizeof(MSFT_ParameterInfo);

        for(j = 0; j < desc->funcdesc.cParams; ++j){
            if(desc->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT){
                recorded_size += desc->funcdesc.cParams * sizeof(INT);
                break;
            }
        }

        extra_size += 2 * sizeof(INT); /* memberid, name offs */
    }

    for(i = 0; i < info->typeattr.cVars; ++i){
        TLBVarDesc *desc = &info->vardescs[i];

        recorded_size += 5 * sizeof(INT); /* mandatory fields */

        /* optional fields */
        if(desc->HelpStringContext != 0)
            recorded_size += 5 * sizeof(INT);
        else if(!list_empty(&desc->custdata_list))
            recorded_size += 4 * sizeof(INT);
        /* res9? */
        else if(desc->HelpString)
            recorded_size += 2 * sizeof(INT);
        else if(desc->HelpContext != 0)
            recorded_size += sizeof(INT);

        extra_size += 2 * sizeof(INT); /* memberid, name offs */
    }

    if(!recorded_size && !extra_size)
        return ret;

    extra_size += sizeof(INT); /* total aux size for this typeinfo */

    aux_seg->len += recorded_size + extra_size;

    aux_seg->len += sizeof(INT) * (info->typeattr.cVars + info->typeattr.cFuncs); /* offsets at the end */

    if(aux_seg->data)
        aux_seg->data = heap_realloc(aux_seg->data, aux_seg->len);
    else
        aux_seg->data = heap_alloc(aux_seg->len);

    *((DWORD*)((char *)aux_seg->data + ret)) = recorded_size;

    offsets = (DWORD*)((char *)aux_seg->data + ret + recorded_size + extra_size);
    offs = 0;

    funcrecord = (MSFT_FuncRecord*)(((char *)aux_seg->data) + ret + sizeof(INT));
    for(i = 0; i < info->typeattr.cFuncs; ++i){
        TLBFuncDesc *desc = &info->funcdescs[i];
        DWORD size = 6 * sizeof(INT), paramdefault_size = 0, *paramdefault;

        funcrecord->funcdescsize = sizeof(desc->funcdesc) + desc->funcdesc.cParams * sizeof(ELEMDESC);
        funcrecord->DataType = WMSFT_append_typedesc(&desc->funcdesc.elemdescFunc.tdesc, file, NULL, &funcrecord->funcdescsize);
        funcrecord->Flags = desc->funcdesc.wFuncFlags;
        funcrecord->VtableOffset = desc->funcdesc.oVft;

        /* FKCCIC:
         * XXXX XXXX XXXX XXXX  XXXX XXXX XXXX XXXX
         *                                      ^^^funckind
         *                                 ^^^ ^invkind
         *                                ^has_cust_data
         *                           ^^^^callconv
         *                         ^has_param_defaults
         *                        ^oEntry_is_intresource
         */
        funcrecord->FKCCIC =
            desc->funcdesc.funckind |
            (desc->funcdesc.invkind << 3) |
            (list_empty(&desc->custdata_list) ? 0 : 0x80) |
            (desc->funcdesc.callconv << 8);

        if(desc->Entry && desc->Entry != (TLBString*)-1 && IS_INTRESOURCE(desc->Entry))
            funcrecord->FKCCIC |= 0x2000;

        for(j = 0; j < desc->funcdesc.cParams; ++j){
            if(desc->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT){
                paramdefault_size = sizeof(INT) * desc->funcdesc.cParams;
                funcrecord->funcdescsize += sizeof(PARAMDESCEX);
            }
        }
        if(paramdefault_size > 0)
            funcrecord->FKCCIC |= 0x1000;

        funcrecord->nrargs = desc->funcdesc.cParams;
        funcrecord->nroargs = desc->funcdesc.cParamsOpt;

        /* optional fields */
        /* res9? resA? */
        if(!list_empty(&desc->custdata_list)){
            size += 7 * sizeof(INT);
            funcrecord->HelpContext = desc->helpcontext;
            if(desc->HelpString)
                funcrecord->oHelpString = desc->HelpString->offset;
            else
                funcrecord->oHelpString = -1;
            if(!desc->Entry)
                funcrecord->oEntry = -1;
            else if(IS_INTRESOURCE(desc->Entry))
                funcrecord->oEntry = LOWORD(desc->Entry);
            else
                funcrecord->oEntry = desc->Entry->offset;
            funcrecord->res9 = -1;
            funcrecord->resA = -1;
            funcrecord->HelpStringContext = desc->HelpStringContext;
            funcrecord->oCustData = WMSFT_compile_custdata(&desc->custdata_list, file);
        }else if(desc->HelpStringContext != 0){
            size += 6 * sizeof(INT);
            funcrecord->HelpContext = desc->helpcontext;
            if(desc->HelpString)
                funcrecord->oHelpString = desc->HelpString->offset;
            else
                funcrecord->oHelpString = -1;
            if(!desc->Entry)
                funcrecord->oEntry = -1;
            else if(IS_INTRESOURCE(desc->Entry))
                funcrecord->oEntry = LOWORD(desc->Entry);
            else
                funcrecord->oEntry = desc->Entry->offset;
            funcrecord->res9 = -1;
            funcrecord->resA = -1;
            funcrecord->HelpStringContext = desc->HelpStringContext;
        }else if(desc->Entry){
            size += 3 * sizeof(INT);
            funcrecord->HelpContext = desc->helpcontext;
            if(desc->HelpString)
                funcrecord->oHelpString = desc->HelpString->offset;
            else
                funcrecord->oHelpString = -1;
            if(!desc->Entry)
                funcrecord->oEntry = -1;
            else if(IS_INTRESOURCE(desc->Entry))
                funcrecord->oEntry = LOWORD(desc->Entry);
            else
                funcrecord->oEntry = desc->Entry->offset;
        }else if(desc->HelpString){
            size += 2 * sizeof(INT);
            funcrecord->HelpContext = desc->helpcontext;
            funcrecord->oHelpString = desc->HelpString->offset;
        }else if(desc->helpcontext){
            size += sizeof(INT);
            funcrecord->HelpContext = desc->helpcontext;
        }

        paramdefault = (DWORD*)((char *)funcrecord + size);
        size += paramdefault_size;

        for(j = 0; j < desc->funcdesc.cParams; ++j){
            MSFT_ParameterInfo *info = (MSFT_ParameterInfo*)(((char *)funcrecord) + size);

            info->DataType = WMSFT_append_typedesc(&desc->funcdesc.lprgelemdescParam[j].tdesc, file, NULL, &funcrecord->funcdescsize);
            if(desc->pParamDesc[j].Name)
                info->oName = desc->pParamDesc[j].Name->offset;
            else
                info->oName = -1;
            info->Flags = desc->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags;

            if(paramdefault_size){
                if(desc->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
                    *paramdefault = WMSFT_encode_variant(&desc->funcdesc.lprgelemdescParam[j].u.paramdesc.pparamdescex->varDefaultValue, file);
                else if(paramdefault_size)
                    *paramdefault = -1;
                ++paramdefault;
            }

            size += sizeof(MSFT_ParameterInfo);
        }

        funcrecord->Info = size | (i << 16); /* is it just the index? */

        *offsets = offs;
        offs += size;
        ++offsets;

        funcrecord = (MSFT_FuncRecord*)(((char*)funcrecord) + size);
    }

    varrecord = (MSFT_VarRecord*)funcrecord;
    for(i = 0; i < info->typeattr.cVars; ++i){
        TLBVarDesc *desc = &info->vardescs[i];
        DWORD size = 5 * sizeof(INT);

        varrecord->vardescsize = sizeof(desc->vardesc);
        varrecord->DataType = WMSFT_append_typedesc(&desc->vardesc.elemdescVar.tdesc, file, NULL, &varrecord->vardescsize);
        varrecord->Flags = desc->vardesc.wVarFlags;
        varrecord->VarKind = desc->vardesc.varkind;

        if(desc->vardesc.varkind == VAR_CONST){
            varrecord->vardescsize += sizeof(VARIANT);
            varrecord->OffsValue = WMSFT_encode_variant(desc->vardesc.u.lpvarValue, file);
        }else
            varrecord->OffsValue = desc->vardesc.u.oInst;

        /* res9? */
        if(desc->HelpStringContext != 0){
            size += 5 * sizeof(INT);
            varrecord->HelpContext = desc->HelpContext;
            if(desc->HelpString)
                varrecord->HelpString = desc->HelpString->offset;
            else
                varrecord->HelpString = -1;
            varrecord->res9 = -1;
            varrecord->oCustData = WMSFT_compile_custdata(&desc->custdata_list, file);
            varrecord->HelpStringContext = desc->HelpStringContext;
        }else if(!list_empty(&desc->custdata_list)){
            size += 4 * sizeof(INT);
            varrecord->HelpContext = desc->HelpContext;
            if(desc->HelpString)
                varrecord->HelpString = desc->HelpString->offset;
            else
                varrecord->HelpString = -1;
            varrecord->res9 = -1;
            varrecord->oCustData = WMSFT_compile_custdata(&desc->custdata_list, file);
        }else if(desc->HelpString){
            size += 2 * sizeof(INT);
            varrecord->HelpContext = desc->HelpContext;
            if(desc->HelpString)
                varrecord->HelpString = desc->HelpString->offset;
            else
                varrecord->HelpString = -1;
        }else if(desc->HelpContext != 0){
            size += sizeof(INT);
            varrecord->HelpContext = desc->HelpContext;
        }

        varrecord->Info = size | (i << 16);

        *offsets = offs;
        offs += size;
        ++offsets;

        varrecord = (MSFT_VarRecord*)(((char*)varrecord) + size);
    }

    memid = (MEMBERID*)varrecord;
    for(i = 0; i < info->typeattr.cFuncs; ++i){
        TLBFuncDesc *desc = &info->funcdescs[i];
        *memid = desc->funcdesc.memid;
        ++memid;
    }
    for(i = 0; i < info->typeattr.cVars; ++i){
        TLBVarDesc *desc = &info->vardescs[i];
        *memid = desc->vardesc.memid;
        ++memid;
    }

    name = (UINT*)memid;
    for(i = 0; i < info->typeattr.cFuncs; ++i){
        TLBFuncDesc *desc = &info->funcdescs[i];
        if(desc->Name)
            *name = desc->Name->offset;
        else
            *name = -1;
        ++name;
    }
    for(i = 0; i < info->typeattr.cVars; ++i){
        TLBVarDesc *desc = &info->vardescs[i];
        if(desc->Name)
            *name = desc->Name->offset;
        else
            *name = -1;
        ++name;
    }

    return ret;
}

typedef struct tagWMSFT_RefChunk {
    DWORD href;
    DWORD res04;
    DWORD res08;
    DWORD next;
} WMSFT_RefChunk;

static DWORD WMSFT_compile_typeinfo_ref(ITypeInfoImpl *info, WMSFT_TLBFile *file)
{
    DWORD offs = file->ref_seg.len, i;
    WMSFT_RefChunk *chunk;

    file->ref_seg.len += info->typeattr.cImplTypes * sizeof(WMSFT_RefChunk);
    if(!file->ref_seg.data)
        file->ref_seg.data = heap_alloc(file->ref_seg.len);
    else
        file->ref_seg.data = heap_realloc(file->ref_seg.data, file->ref_seg.len);

    chunk = (WMSFT_RefChunk*)((char*)file->ref_seg.data + offs);

    for(i = 0; i < info->typeattr.cImplTypes; ++i){
        chunk->href = info->impltypes[i].hRef;
        chunk->res04 = info->impltypes[i].implflags;
        chunk->res08 = -1;
        if(i < info->typeattr.cImplTypes - 1)
            chunk->next = offs + sizeof(WMSFT_RefChunk) * (i + 1);
        else
            chunk->next = -1;
        ++chunk;
    }

    return offs;
}

static DWORD WMSFT_compile_typeinfo(ITypeInfoImpl *info, INT16 index, WMSFT_TLBFile *file, char *data)
{
    DWORD size;

    size = sizeof(MSFT_TypeInfoBase);

    if(data){
        MSFT_TypeInfoBase *base = (MSFT_TypeInfoBase*)data;
        if(info->typeattr.wTypeFlags & TYPEFLAG_FDUAL)
            base->typekind = TKIND_DISPATCH;
        else
            base->typekind = info->typeattr.typekind;
        base->typekind |= index << 16; /* TODO: There are some other flags here */
        base->typekind |= (info->typeattr.cbAlignment << 11) | (info->typeattr.cbAlignment << 6);
        base->memoffset = WMSFT_compile_typeinfo_aux(info, file);
        base->res2 = 0;
        base->res3 = 0;
        base->res4 = 3;
        base->res5 = 0;
        base->cElement = (info->typeattr.cVars << 16) | info->typeattr.cFuncs;
        base->res7 = 0;
        base->res8 = 0;
        base->res9 = 0;
        base->resA = 0;
        if(info->guid)
            base->posguid = info->guid->offset;
        else
            base->posguid = -1;
        base->flags = info->typeattr.wTypeFlags;
        if(info->Name) {
            base->NameOffset = info->Name->offset;

            ((unsigned char*)file->name_seg.data)[info->Name->offset+9] = 0x38;
            *(HREFTYPE*)((unsigned char*)file->name_seg.data+info->Name->offset) = info->hreftype;
        }else {
            base->NameOffset = -1;
        }
        base->version = (info->typeattr.wMinorVerNum << 16) | info->typeattr.wMajorVerNum;
        if(info->DocString)
            base->docstringoffs = info->DocString->offset;
        else
            base->docstringoffs = -1;
        base->helpstringcontext = info->dwHelpStringContext;
        base->helpcontext = info->dwHelpContext;
        base->oCustData = WMSFT_compile_custdata(info->pcustdata_list, file);
        base->cImplTypes = info->typeattr.cImplTypes;
        base->cbSizeVft = info->typeattr.cbSizeVft;
        base->size = info->typeattr.cbSizeInstance;
        if(info->typeattr.typekind == TKIND_COCLASS){
            base->datatype1 = WMSFT_compile_typeinfo_ref(info, file);
        }else if(info->typeattr.typekind == TKIND_ALIAS){
            base->datatype1 = WMSFT_append_typedesc(info->tdescAlias, file, NULL, NULL);
        }else if(info->typeattr.typekind == TKIND_MODULE){
            if(info->DllName)
                base->datatype1 = info->DllName->offset;
            else
                base->datatype1 = -1;
        }else{
            if(info->typeattr.cImplTypes > 0)
                base->datatype1 = info->impltypes[0].hRef;
            else
                base->datatype1 = -1;
        }
        base->datatype2 = index; /* FIXME: i think there's more here */
        base->res18 = 0;
        base->res19 = -1;
    }

    return size;
}

static void WMSFT_compile_typeinfo_seg(ITypeLibImpl *This, WMSFT_TLBFile *file, DWORD *junk)
{
    UINT i;

    file->typeinfo_seg.len = 0;
    for(i = 0; i < This->TypeInfoCount; ++i){
        ITypeInfoImpl *info = This->typeinfos[i];
        *junk = file->typeinfo_seg.len;
        ++junk;
        file->typeinfo_seg.len += WMSFT_compile_typeinfo(info, i, NULL, NULL);
    }

    file->typeinfo_seg.data = heap_alloc(file->typeinfo_seg.len);
    memset(file->typeinfo_seg.data, 0x96, file->typeinfo_seg.len);

    file->aux_seg.len = 0;
    file->aux_seg.data = NULL;

    file->typeinfo_seg.len = 0;
    for(i = 0; i < This->TypeInfoCount; ++i){
        ITypeInfoImpl *info = This->typeinfos[i];
        file->typeinfo_seg.len += WMSFT_compile_typeinfo(info, i, file,
                ((char *)file->typeinfo_seg.data) + file->typeinfo_seg.len);
    }
}

typedef struct tagWMSFT_ImpFile {
    INT guid_offs;
    LCID lcid;
    DWORD version;
} WMSFT_ImpFile;

static void WMSFT_compile_impfile(ITypeLibImpl *This, WMSFT_TLBFile *file)
{
    TLBImpLib *implib;
    WMSFT_ImpFile *impfile;
    char *data;
    DWORD last_offs = 0;

    file->impfile_seg.len = 0;
    LIST_FOR_EACH_ENTRY(implib, &This->implib_list, TLBImpLib, entry){
        int size = 0;

        if(implib->name){
            WCHAR *path = strrchrW(implib->name, '\\');
            if(path)
                ++path;
            else
                path = implib->name;
            size = WideCharToMultiByte(CP_ACP, 0, path, strlenW(path), NULL, 0, NULL, NULL);
            if (size == 0)
                ERR("failed to convert wide string: %s\n", debugstr_w(path));
        }

        size += sizeof(INT16);
        if (size % 4)
            size = (size + 4) & ~0x3;
        if (size < 8)
            size = 8;

        file->impfile_seg.len += sizeof(WMSFT_ImpFile) + size;
    }

    data = file->impfile_seg.data = heap_alloc(file->impfile_seg.len);

    LIST_FOR_EACH_ENTRY(implib, &This->implib_list, TLBImpLib, entry){
        int strlen = 0, size;

        impfile = (WMSFT_ImpFile*)data;
        impfile->guid_offs = implib->guid->offset;
        impfile->lcid = implib->lcid;
        impfile->version = (implib->wVersionMinor << 16) | implib->wVersionMajor;

        data += sizeof(WMSFT_ImpFile);

        if(implib->name){
            WCHAR *path= strrchrW(implib->name, '\\');
            if(path)
                ++path;
            else
                path = implib->name;
            strlen = WideCharToMultiByte(CP_ACP, 0, path, strlenW(path),
                    data + sizeof(INT16), file->impfile_seg.len - last_offs - sizeof(INT16), NULL, NULL);
            if (strlen == 0)
                ERR("failed to convert wide string: %s\n", debugstr_w(path));
        }

        *((INT16*)data) = (strlen << 2) | 1; /* FIXME: is that a flag, or what? */

        size = strlen + sizeof(INT16);
        if (size % 4)
            size = (size + 4) & ~0x3;
        if (size < 8)
            size = 8;
        memset(data + sizeof(INT16) + strlen, 0x57, size - strlen - sizeof(INT16));

        data += size;
        implib->offset = last_offs;
        last_offs += size + sizeof(WMSFT_ImpFile);
    }
}

static void WMSFT_compile_impinfo(ITypeLibImpl *This, WMSFT_TLBFile *file)
{
    MSFT_ImpInfo *info;
    TLBRefType *ref_type;
    UINT i = 0;

    WMSFT_compile_impfile(This, file);

    file->impinfo_seg.len = sizeof(MSFT_ImpInfo) * list_count(&This->ref_list);
    info = file->impinfo_seg.data = heap_alloc(file->impinfo_seg.len);

    LIST_FOR_EACH_ENTRY(ref_type, &This->ref_list, TLBRefType, entry){
        info->flags = i | ((ref_type->tkind & 0xFF) << 24);
        if(ref_type->index == TLB_REF_USE_GUID){
            info->flags |= MSFT_IMPINFO_OFFSET_IS_GUID;
            info->oGuid = ref_type->guid->offset;
        }else
            info->oGuid = ref_type->index;
        info->oImpFile = ref_type->pImpTLInfo->offset;
        ++i;
        ++info;
    }
}

static void WMSFT_compile_guidhash(ITypeLibImpl *This, WMSFT_TLBFile *file)
{
    file->guidhash_seg.len = 0x80;
    file->guidhash_seg.data = heap_alloc(file->guidhash_seg.len);
    memset(file->guidhash_seg.data, 0xFF, file->guidhash_seg.len);
}

static void WMSFT_compile_namehash(ITypeLibImpl *This, WMSFT_TLBFile *file)
{
    file->namehash_seg.len = 0x200;
    file->namehash_seg.data = heap_alloc(file->namehash_seg.len);
    memset(file->namehash_seg.data, 0xFF, file->namehash_seg.len);
}

static void tmp_fill_segdir_seg(MSFT_pSeg *segdir, WMSFT_SegContents *contents, DWORD *running_offset)
{
    if(contents && contents->len){
        segdir->offset = *running_offset;
        segdir->length = contents->len;
        *running_offset += segdir->length;
    }else{
        segdir->offset = -1;
        segdir->length = 0;
    }

    /* TODO: do these ever change? */
    segdir->res08 = -1;
    segdir->res0c = 0xf;
}

static void WMSFT_write_segment(HANDLE outfile, WMSFT_SegContents *segment)
{
    DWORD written;
    if(segment)
        WriteFile(outfile, segment->data, segment->len, &written, NULL);
}

static HRESULT WMSFT_fixup_typeinfos(ITypeLibImpl *This, WMSFT_TLBFile *file,
        DWORD file_len)
{
    DWORD i;
    MSFT_TypeInfoBase *base = (MSFT_TypeInfoBase *)file->typeinfo_seg.data;

    for(i = 0; i < This->TypeInfoCount; ++i){
        base->memoffset += file_len;
        ++base;
    }

    return S_OK;
}

static void WMSFT_free_file(WMSFT_TLBFile *file)
{
    HeapFree(GetProcessHeap(), 0, file->typeinfo_seg.data);
    HeapFree(GetProcessHeap(), 0, file->guidhash_seg.data);
    HeapFree(GetProcessHeap(), 0, file->guid_seg.data);
    HeapFree(GetProcessHeap(), 0, file->ref_seg.data);
    HeapFree(GetProcessHeap(), 0, file->impinfo_seg.data);
    HeapFree(GetProcessHeap(), 0, file->impfile_seg.data);
    HeapFree(GetProcessHeap(), 0, file->namehash_seg.data);
    HeapFree(GetProcessHeap(), 0, file->name_seg.data);
    HeapFree(GetProcessHeap(), 0, file->string_seg.data);
    HeapFree(GetProcessHeap(), 0, file->typdesc_seg.data);
    HeapFree(GetProcessHeap(), 0, file->arraydesc_seg.data);
    HeapFree(GetProcessHeap(), 0, file->custdata_seg.data);
    HeapFree(GetProcessHeap(), 0, file->cdguids_seg.data);
    HeapFree(GetProcessHeap(), 0, file->aux_seg.data);
}

static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 *iface)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);
    WMSFT_TLBFile file;
    DWORD written, junk_size, junk_offs, running_offset;
    BOOL br;
    HANDLE outfile;
    HRESULT hres;
    DWORD *junk;
    UINT i;

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

    for(i = 0; i < This->TypeInfoCount; ++i)
        if(This->typeinfos[i]->needs_layout)
            ICreateTypeInfo2_LayOut(&This->typeinfos[i]->ICreateTypeInfo2_iface);

    memset(&file, 0, sizeof(file));

    file.header.magic1 = 0x5446534D;
    file.header.magic2 = 0x00010002;
    file.header.lcid = This->set_lcid ? This->set_lcid : MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
    file.header.lcid2 = This->set_lcid;
    file.header.varflags = 0x40 | This->syskind;
    if (This->HelpFile)
        file.header.varflags |= 0x10;
    if (This->HelpStringDll)
        file.header.varflags |= HELPDLLFLAG;
    file.header.version = (This->ver_minor << 16) | This->ver_major;
    file.header.flags = This->libflags;
    file.header.helpstringcontext = 0; /* TODO - SetHelpStringContext not implemented yet */
    file.header.helpcontext = This->dwHelpContext;
    file.header.res44 = 0x20;
    file.header.res48 = 0x80;
    file.header.dispatchpos = This->dispatch_href;

    WMSFT_compile_namehash(This, &file);
    /* do name and string compilation to get offsets for other compilations */
    hres = WMSFT_compile_names(This, &file);
    if (FAILED(hres)){
        WMSFT_free_file(&file);
        return hres;
    }

    hres = WMSFT_compile_strings(This, &file);
    if (FAILED(hres)){
        WMSFT_free_file(&file);
        return hres;
    }

    WMSFT_compile_guidhash(This, &file);
    hres = WMSFT_compile_guids(This, &file);
    if (FAILED(hres)){
        WMSFT_free_file(&file);
        return hres;
    }

    if(This->HelpFile)
        file.header.helpfile = This->HelpFile->offset;
    else
        file.header.helpfile = -1;

    if(This->DocString)
        file.header.helpstring = This->DocString->offset;
    else
        file.header.helpstring = -1;

    /* do some more segment compilation */
    file.header.nimpinfos = list_count(&This->ref_list);
    file.header.nrtypeinfos = This->TypeInfoCount;

    if(This->Name)
        file.header.NameOffset = This->Name->offset;
    else
        file.header.NameOffset = -1;

    file.header.CustomDataOffset = WMSFT_compile_custdata(&This->custdata_list, &file);

    if(This->guid)
        file.header.posguid = This->guid->offset;
    else
        file.header.posguid = -1;

    junk_size = file.header.nrtypeinfos * sizeof(DWORD);
    if(file.header.varflags & HELPDLLFLAG)
        junk_size += sizeof(DWORD);
    if(junk_size){
        junk = heap_alloc_zero(junk_size);
        if(file.header.varflags & HELPDLLFLAG){
            *junk = This->HelpStringDll->offset;
            junk_offs = 1;
        }else
            junk_offs = 0;
    }else{
        junk = NULL;
        junk_offs = 0;
    }

    WMSFT_compile_typeinfo_seg(This, &file, junk + junk_offs);
    WMSFT_compile_impinfo(This, &file);

    running_offset = 0;

    TRACE("header at: 0x%x\n", running_offset);
    running_offset += sizeof(file.header);

    TRACE("junk at: 0x%x\n", running_offset);
    running_offset += junk_size;

    TRACE("segdir at: 0x%x\n", running_offset);
    running_offset += sizeof(file.segdir);

    TRACE("typeinfo at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.pTypeInfoTab, &file.typeinfo_seg, &running_offset);

    TRACE("guidhashtab at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.pGuidHashTab, &file.guidhash_seg, &running_offset);

    TRACE("guidtab at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.pGuidTab, &file.guid_seg, &running_offset);

    TRACE("reftab at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.pRefTab, &file.ref_seg, &running_offset);

    TRACE("impinfo at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.pImpInfo, &file.impinfo_seg, &running_offset);

    TRACE("impfiles at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.pImpFiles, &file.impfile_seg, &running_offset);

    TRACE("namehashtab at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.pNameHashTab, &file.namehash_seg, &running_offset);

    TRACE("nametab at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.pNametab, &file.name_seg, &running_offset);

    TRACE("stringtab at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.pStringtab, &file.string_seg, &running_offset);

    TRACE("typdesc at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.pTypdescTab, &file.typdesc_seg, &running_offset);

    TRACE("arraydescriptions at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.pArrayDescriptions, &file.arraydesc_seg, &running_offset);

    TRACE("custdata at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.pCustData, &file.custdata_seg, &running_offset);

    TRACE("cdguids at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.pCDGuids, &file.cdguids_seg, &running_offset);

    TRACE("res0e at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.res0e, NULL, &running_offset);

    TRACE("res0f at: 0x%x\n", running_offset);
    tmp_fill_segdir_seg(&file.segdir.res0f, NULL, &running_offset);

    TRACE("aux_seg at: 0x%x\n", running_offset);

    WMSFT_fixup_typeinfos(This, &file, running_offset);

    outfile = CreateFileW(This->path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL, 0);
    if (outfile == INVALID_HANDLE_VALUE){
        WMSFT_free_file(&file);
        heap_free(junk);
        return TYPE_E_IOERROR;
    }

    br = WriteFile(outfile, &file.header, sizeof(file.header), &written, NULL);
    if (!br) {
        WMSFT_free_file(&file);
        CloseHandle(outfile);
        heap_free(junk);
        return TYPE_E_IOERROR;
    }

    br = WriteFile(outfile, junk, junk_size, &written, NULL);
    heap_free(junk);
    if (!br) {
        WMSFT_free_file(&file);
        CloseHandle(outfile);
        return TYPE_E_IOERROR;
    }

    br = WriteFile(outfile, &file.segdir, sizeof(file.segdir), &written, NULL);
    if (!br) {
        WMSFT_free_file(&file);
        CloseHandle(outfile);
        return TYPE_E_IOERROR;
    }

    WMSFT_write_segment(outfile, &file.typeinfo_seg);
    WMSFT_write_segment(outfile, &file.guidhash_seg);
    WMSFT_write_segment(outfile, &file.guid_seg);
    WMSFT_write_segment(outfile, &file.ref_seg);
    WMSFT_write_segment(outfile, &file.impinfo_seg);
    WMSFT_write_segment(outfile, &file.impfile_seg);
    WMSFT_write_segment(outfile, &file.namehash_seg);
    WMSFT_write_segment(outfile, &file.name_seg);
    WMSFT_write_segment(outfile, &file.string_seg);
    WMSFT_write_segment(outfile, &file.typdesc_seg);
    WMSFT_write_segment(outfile, &file.arraydesc_seg);
    WMSFT_write_segment(outfile, &file.custdata_seg);
    WMSFT_write_segment(outfile, &file.cdguids_seg);
    WMSFT_write_segment(outfile, &file.aux_seg);

    WMSFT_free_file(&file);

    CloseHandle(outfile);

    return S_OK;
}

static HRESULT WINAPI ICreateTypeLib2_fnDeleteTypeInfo(ICreateTypeLib2 *iface,
        LPOLESTR name)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);
    FIXME("%p %s - stub\n", This, wine_dbgstr_w(name));
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeLib2_fnSetCustData(ICreateTypeLib2 *iface,
        REFGUID guid, VARIANT *varVal)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);
    TLBGuid *tlbguid;

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

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

    tlbguid = TLB_append_guid(&This->guid_list, guid, -1);

    return TLB_set_custdata(&This->custdata_list, tlbguid, varVal);
}

static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 *iface,
        ULONG helpStringContext)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);
    FIXME("%p %u - stub\n", This, helpStringContext);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringDll(ICreateTypeLib2 *iface,
        LPOLESTR filename)
{
    ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);
    TRACE("%p %s\n", This, wine_dbgstr_w(filename));

    if (!filename)
        return E_INVALIDARG;

    This->HelpStringDll = TLB_append_str(&This->string_list, filename);

    return S_OK;
}

static const ICreateTypeLib2Vtbl CreateTypeLib2Vtbl = {
    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 HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface(ICreateTypeInfo2 *iface,
        REFIID riid, void **object)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

    return ITypeInfo2_QueryInterface(&This->ITypeInfo2_iface, riid, object);
}

static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

    return ITypeInfo2_AddRef(&This->ITypeInfo2_iface);
}

static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

    return ITypeInfo2_Release(&This->ITypeInfo2_iface);
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetGuid(ICreateTypeInfo2 *iface,
        REFGUID guid)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

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

    This->guid = TLB_append_guid(&This->pTypeLib->guid_list, guid, This->hreftype);

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface,
        UINT typeFlags)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    WORD old_flags;
    HRESULT hres;

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

    if (typeFlags & 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;
    }

    old_flags = This->typeattr.wTypeFlags;
    This->typeattr.wTypeFlags = typeFlags;

    hres = ICreateTypeInfo2_LayOut(iface);
    if (FAILED(hres)) {
        This->typeattr.wTypeFlags = old_flags;
        return hres;
    }

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetDocString(ICreateTypeInfo2 *iface,
        LPOLESTR doc)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

    TRACE("%p %s\n", This, wine_dbgstr_w(doc));

    if (!doc)
        return E_INVALIDARG;

    This->DocString = TLB_append_str(&This->pTypeLib->string_list, doc);

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext(ICreateTypeInfo2 *iface,
        DWORD helpContext)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

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

    This->dwHelpContext = helpContext;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetVersion(ICreateTypeInfo2 *iface,
        WORD majorVerNum, WORD minorVerNum)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

    TRACE("%p %d %d\n", This, majorVerNum, minorVerNum);

    This->typeattr.wMajorVerNum = majorVerNum;
    This->typeattr.wMinorVerNum = minorVerNum;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(ICreateTypeInfo2 *iface,
        ITypeInfo *typeInfo, HREFTYPE *refType)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    UINT index;
    ITypeLib *container;
    TLBRefType *ref_type;
    TLBImpLib *implib;
    TYPEATTR *typeattr;
    TLIBATTR *libattr;
    HRESULT hres;

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

    if (!typeInfo || !refType)
        return E_INVALIDARG;

    hres = ITypeInfo_GetContainingTypeLib(typeInfo, &container, &index);
    if (FAILED(hres))
        return hres;

    if (container == (ITypeLib*)&This->pTypeLib->ITypeLib2_iface) {
        ITypeInfoImpl *target = impl_from_ITypeInfo(typeInfo);

        ITypeLib_Release(container);

        *refType = target->hreftype;

        return S_OK;
    }

    hres = ITypeLib_GetLibAttr(container, &libattr);
    if (FAILED(hres)) {
        ITypeLib_Release(container);
        return hres;
    }

    LIST_FOR_EACH_ENTRY(implib, &This->pTypeLib->implib_list, TLBImpLib, entry){
        if(IsEqualGUID(&implib->guid->guid, &libattr->guid) &&
                implib->lcid == libattr->lcid &&
                implib->wVersionMajor == libattr->wMajorVerNum &&
                implib->wVersionMinor == libattr->wMinorVerNum)
            break;
    }

    if(&implib->entry == &This->pTypeLib->implib_list){
        implib = heap_alloc_zero(sizeof(TLBImpLib));

        if((ITypeLib2Vtbl*)container->lpVtbl == &tlbvt){
            const ITypeLibImpl *our_container = impl_from_ITypeLib2((ITypeLib2*)container);
            implib->name = SysAllocString(our_container->path);
        }else{
            hres = QueryPathOfRegTypeLib(&libattr->guid, libattr->wMajorVerNum,
                    libattr->wMinorVerNum, libattr->lcid, &implib->name);
            if(FAILED(hres)){
                implib->name = NULL;
                TRACE("QueryPathOfRegTypeLib failed, no name stored: %08x\n", hres);
            }
        }

        implib->guid = TLB_append_guid(&This->pTypeLib->guid_list, &libattr->guid, 2);
        implib->lcid = libattr->lcid;
        implib->wVersionMajor = libattr->wMajorVerNum;
        implib->wVersionMinor = libattr->wMinorVerNum;

        list_add_tail(&This->pTypeLib->implib_list, &implib->entry);
    }

    ITypeLib_ReleaseTLibAttr(container, libattr);
    ITypeLib_Release(container);

    hres = ITypeInfo_GetTypeAttr(typeInfo, &typeattr);
    if (FAILED(hres))
        return hres;

    index = 0;
    LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry){
        if(ref_type->index == TLB_REF_USE_GUID &&
                IsEqualGUID(&ref_type->guid->guid, &typeattr->guid) &&
                ref_type->tkind == typeattr->typekind)
            break;
        ++index;
    }

    if(&ref_type->entry == &This->pTypeLib->ref_list){
        ref_type = heap_alloc_zero(sizeof(TLBRefType));

        ref_type->tkind = typeattr->typekind;
        ref_type->pImpTLInfo = implib;
        ref_type->reference = index * sizeof(MSFT_ImpInfo);

        ref_type->index = TLB_REF_USE_GUID;

        ref_type->guid = TLB_append_guid(&This->pTypeLib->guid_list, &typeattr->guid, ref_type->reference+1);

        list_add_tail(&This->pTypeLib->ref_list, &ref_type->entry);
    }

    ITypeInfo_ReleaseTypeAttr(typeInfo, typeattr);

    *refType = ref_type->reference | 0x1;

    if(IsEqualGUID(&ref_type->guid->guid, &IID_IDispatch))
        This->pTypeLib->dispatch_href = *refType;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(ICreateTypeInfo2 *iface,
        UINT index, FUNCDESC *funcDesc)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    TLBFuncDesc tmp_func_desc, *func_desc;
    int buf_size, i;
    char *buffer;
    HRESULT hres;

    TRACE("%p %u %p\n", This, index, funcDesc);

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

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

    if (index > This->typeattr.cFuncs)
        return TYPE_E_ELEMENTNOTFOUND;

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

#ifdef _WIN64
    if(This->pTypeLib->syskind == SYS_WIN64 &&
            funcDesc->oVft % 8 != 0)
        return E_INVALIDARG;
#endif

    memset(&tmp_func_desc, 0, sizeof(tmp_func_desc));
    TLBFuncDesc_Constructor(&tmp_func_desc);

    tmp_func_desc.funcdesc = *funcDesc;

    if (tmp_func_desc.funcdesc.oVft != 0)
        tmp_func_desc.funcdesc.oVft |= 1;

    if (funcDesc->cScodes && funcDesc->lprgscode) {
        tmp_func_desc.funcdesc.lprgscode = heap_alloc(sizeof(SCODE) * funcDesc->cScodes);
        memcpy(tmp_func_desc.funcdesc.lprgscode, funcDesc->lprgscode, sizeof(SCODE) * funcDesc->cScodes);
    } else {
        tmp_func_desc.funcdesc.lprgscode = NULL;
        tmp_func_desc.funcdesc.cScodes = 0;
    }

    buf_size = TLB_SizeElemDesc(&funcDesc->elemdescFunc);
    for (i = 0; i < funcDesc->cParams; ++i) {
        buf_size += sizeof(ELEMDESC);
        buf_size += TLB_SizeElemDesc(funcDesc->lprgelemdescParam + i);
    }
    tmp_func_desc.funcdesc.lprgelemdescParam = heap_alloc(buf_size);
    buffer = (char*)(tmp_func_desc.funcdesc.lprgelemdescParam + funcDesc->cParams);

    hres = TLB_CopyElemDesc(&funcDesc->elemdescFunc, &tmp_func_desc.funcdesc.elemdescFunc, &buffer);
    if (FAILED(hres)) {
        heap_free(tmp_func_desc.funcdesc.lprgelemdescParam);
        heap_free(tmp_func_desc.funcdesc.lprgscode);
        return hres;
    }

    for (i = 0; i < funcDesc->cParams; ++i) {
        hres = TLB_CopyElemDesc(funcDesc->lprgelemdescParam + i,
                tmp_func_desc.funcdesc.lprgelemdescParam + i, &buffer);
        if (FAILED(hres)) {
            heap_free(tmp_func_desc.funcdesc.lprgelemdescParam);
            heap_free(tmp_func_desc.funcdesc.lprgscode);
            return hres;
        }
        if (tmp_func_desc.funcdesc.lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT &&
                tmp_func_desc.funcdesc.lprgelemdescParam[i].tdesc.vt != VT_VARIANT &&
                tmp_func_desc.funcdesc.lprgelemdescParam[i].tdesc.vt != VT_USERDEFINED){
            hres = TLB_SanitizeVariant(&tmp_func_desc.funcdesc.lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
            if (FAILED(hres)) {
                heap_free(tmp_func_desc.funcdesc.lprgelemdescParam);
                heap_free(tmp_func_desc.funcdesc.lprgscode);
                return hres;
            }
        }
    }

    tmp_func_desc.pParamDesc = TLBParDesc_Constructor(funcDesc->cParams);

    if (This->funcdescs) {
        This->funcdescs = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->funcdescs,
                sizeof(TLBFuncDesc) * (This->typeattr.cFuncs + 1));

        if (index < This->typeattr.cFuncs) {
            memmove(This->funcdescs + index + 1, This->funcdescs + index,
                    (This->typeattr.cFuncs - index) * sizeof(TLBFuncDesc));
            func_desc = This->funcdescs + index;
        } else
            func_desc = This->funcdescs + This->typeattr.cFuncs;

        /* move custdata lists to the new memory location */
        for(i = 0; i < This->typeattr.cFuncs + 1; ++i){
            if(index != i){
                TLBFuncDesc *fd = &This->funcdescs[i];
                if(fd->custdata_list.prev == fd->custdata_list.next)
                    list_init(&fd->custdata_list);
                else{
                    fd->custdata_list.prev->next = &fd->custdata_list;
                    fd->custdata_list.next->prev = &fd->custdata_list;
                }
            }
        }
    } else
        func_desc = This->funcdescs = heap_alloc(sizeof(TLBFuncDesc));

    memcpy(func_desc, &tmp_func_desc, sizeof(tmp_func_desc));
    list_init(&func_desc->custdata_list);

    ++This->typeattr.cFuncs;

    This->needs_layout = TRUE;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(ICreateTypeInfo2 *iface,
        UINT index, HREFTYPE refType)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    TLBImplType *impl_type;
    HRESULT hres;

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

    switch(This->typeattr.typekind){
        case TKIND_COCLASS: {
            if (index == -1) {
                FIXME("Unhandled index: -1\n");
                return E_NOTIMPL;
            }

            if(index != This->typeattr.cImplTypes)
                return TYPE_E_ELEMENTNOTFOUND;

            break;
        }
        case TKIND_INTERFACE:
        case TKIND_DISPATCH:
            if (index != 0 || This->typeattr.cImplTypes)
                return TYPE_E_ELEMENTNOTFOUND;
            break;
        default:
            FIXME("Unimplemented typekind: %d\n", This->typeattr.typekind);
            return E_NOTIMPL;
    }

    if (This->impltypes){
        UINT i;

        This->impltypes = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->impltypes,
                sizeof(TLBImplType) * (This->typeattr.cImplTypes + 1));

        if (index < This->typeattr.cImplTypes) {
            memmove(This->impltypes + index + 1, This->impltypes + index,
                    (This->typeattr.cImplTypes - index) * sizeof(TLBImplType));
            impl_type = This->impltypes + index;
        } else
            impl_type = This->impltypes + This->typeattr.cImplTypes;

        /* move custdata lists to the new memory location */
        for(i = 0; i < This->typeattr.cImplTypes + 1; ++i){
            if(index != i){
                TLBImplType *it = &This->impltypes[i];
                if(it->custdata_list.prev == it->custdata_list.next)
                    list_init(&it->custdata_list);
                else{
                    it->custdata_list.prev->next = &it->custdata_list;
                    it->custdata_list.next->prev = &it->custdata_list;
                }
            }
        }
    } else
        impl_type = This->impltypes = heap_alloc(sizeof(TLBImplType));

    memset(impl_type, 0, sizeof(TLBImplType));
    TLBImplType_Constructor(impl_type);
    impl_type->hRef = refType;

    ++This->typeattr.cImplTypes;

    if((refType & (~0x3)) == (This->pTypeLib->dispatch_href & (~0x3)))
        This->typeattr.wTypeFlags |= TYPEFLAG_FDISPATCHABLE;

    hres = ICreateTypeInfo2_LayOut(iface);
    if (FAILED(hres))
        return hres;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags(ICreateTypeInfo2 *iface,
        UINT index, INT implTypeFlags)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    TLBImplType *impl_type = &This->impltypes[index];

    TRACE("%p %u %x\n", This, index, implTypeFlags);

    if (This->typeattr.typekind != TKIND_COCLASS)
        return TYPE_E_BADMODULEKIND;

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

    impl_type->implflags = implTypeFlags;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment(ICreateTypeInfo2 *iface,
        WORD alignment)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

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

    This->typeattr.cbAlignment = alignment;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetSchema(ICreateTypeInfo2 *iface,
        LPOLESTR schema)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

    TRACE("%p %s\n", This, wine_dbgstr_w(schema));

    if (!schema)
        return E_INVALIDARG;

    This->Schema = TLB_append_str(&This->pTypeLib->string_list, schema);

    This->typeattr.lpstrSchema = This->Schema->str;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(ICreateTypeInfo2 *iface,
        UINT index, VARDESC *varDesc)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    TLBVarDesc *var_desc;

    TRACE("%p %u %p\n", This, index, varDesc);

    if (This->vardescs){
        UINT i;

        This->vardescs = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->vardescs,
                sizeof(TLBVarDesc) * (This->typeattr.cVars + 1));

        if (index < This->typeattr.cVars) {
            memmove(This->vardescs + index + 1, This->vardescs + index,
                    (This->typeattr.cVars - index) * sizeof(TLBVarDesc));
            var_desc = This->vardescs + index;
        } else
            var_desc = This->vardescs + This->typeattr.cVars;

        /* move custdata lists to the new memory location */
        for(i = 0; i < This->typeattr.cVars + 1; ++i){
            if(index != i){
                TLBVarDesc *var = &This->vardescs[i];
                if(var->custdata_list.prev == var->custdata_list.next)
                    list_init(&var->custdata_list);
                else{
                    var->custdata_list.prev->next = &var->custdata_list;
                    var->custdata_list.next->prev = &var->custdata_list;
                }
            }
        }
    } else
        var_desc = This->vardescs = heap_alloc_zero(sizeof(TLBVarDesc));

    TLBVarDesc_Constructor(var_desc);
    TLB_AllocAndInitVarDesc(varDesc, &var_desc->vardesc_create);
    var_desc->vardesc = *var_desc->vardesc_create;

    ++This->typeattr.cVars;

    This->needs_layout = TRUE;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames(ICreateTypeInfo2 *iface,
        UINT index, LPOLESTR *names, UINT numNames)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    TLBFuncDesc *func_desc = &This->funcdescs[index];
    int i;

    TRACE("%p %u %p %u\n", This, index, names, numNames);

    if (!names)
        return E_INVALIDARG;

    if (index >= This->typeattr.cFuncs || numNames == 0)
        return TYPE_E_ELEMENTNOTFOUND;

    if (func_desc->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF)){
        if(numNames > func_desc->funcdesc.cParams)
            return TYPE_E_ELEMENTNOTFOUND;
    } else
        if(numNames > func_desc->funcdesc.cParams + 1)
            return TYPE_E_ELEMENTNOTFOUND;

    for(i = 0; i < This->typeattr.cFuncs; ++i) {
        TLBFuncDesc *iter = &This->funcdescs[i];
        if (iter->Name && !strcmpW(TLB_get_bstr(iter->Name), *names)) {
            if (iter->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF | INVOKE_PROPERTYGET) &&
                    func_desc->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF | INVOKE_PROPERTYGET) &&
                    func_desc->funcdesc.invkind != iter->funcdesc.invkind)
                continue;
            return TYPE_E_AMBIGUOUSNAME;
        }
    }

    func_desc->Name = TLB_append_str(&This->pTypeLib->name_list, *names);

    for (i = 1; i < numNames; ++i) {
        TLBParDesc *par_desc = func_desc->pParamDesc + i - 1;
        par_desc->Name = TLB_append_str(&This->pTypeLib->name_list, *(names + i));
    }

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName(ICreateTypeInfo2 *iface,
        UINT index, LPOLESTR name)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

    TRACE("%p %u %s\n", This, index, wine_dbgstr_w(name));

    if(!name)
        return E_INVALIDARG;

    if(index >= This->typeattr.cVars)
        return TYPE_E_ELEMENTNOTFOUND;

    This->vardescs[index].Name = TLB_append_str(&This->pTypeLib->name_list, name);
    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias(ICreateTypeInfo2 *iface,
        TYPEDESC *tdescAlias)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    HRESULT hr;

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

    if(!tdescAlias)
        return E_INVALIDARG;

    if(This->typeattr.typekind != TKIND_ALIAS)
        return TYPE_E_BADMODULEKIND;

    hr = TLB_size_instance(This, This->pTypeLib->syskind, tdescAlias, &This->typeattr.cbSizeInstance, &This->typeattr.cbAlignment);
    if(FAILED(hr))
        return hr;

    heap_free(This->tdescAlias);
    This->tdescAlias = heap_alloc(TLB_SizeTypeDesc(tdescAlias, TRUE));
    TLB_CopyTypeDesc(NULL, tdescAlias, This->tdescAlias);

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry(ICreateTypeInfo2 *iface,
        UINT index, LPOLESTR dllName, LPOLESTR procName)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p %u %s %s - stub\n", This, index, wine_dbgstr_w(dllName), wine_dbgstr_w(procName));
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncDocString(ICreateTypeInfo2 *iface,
        UINT index, LPOLESTR docString)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    TLBFuncDesc *func_desc = &This->funcdescs[index];

    TRACE("%p %u %s\n", This, index, wine_dbgstr_w(docString));

    if(!docString)
        return E_INVALIDARG;

    if(index >= This->typeattr.cFuncs)
        return TYPE_E_ELEMENTNOTFOUND;

    func_desc->HelpString = TLB_append_str(&This->pTypeLib->string_list, docString);

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetVarDocString(ICreateTypeInfo2 *iface,
        UINT index, LPOLESTR docString)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    TLBVarDesc *var_desc = &This->vardescs[index];

    TRACE("%p %u %s\n", This, index, wine_dbgstr_w(docString));

    if(!docString)
        return E_INVALIDARG;

    if(index >= This->typeattr.cVars)
        return TYPE_E_ELEMENTNOTFOUND;

    var_desc->HelpString = TLB_append_str(&This->pTypeLib->string_list, docString);

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext(ICreateTypeInfo2 *iface,
        UINT index, DWORD helpContext)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    TLBFuncDesc *func_desc = &This->funcdescs[index];

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

    if(index >= This->typeattr.cFuncs)
        return TYPE_E_ELEMENTNOTFOUND;

    func_desc->helpcontext = helpContext;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpContext(ICreateTypeInfo2 *iface,
        UINT index, DWORD helpContext)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    TLBVarDesc *var_desc = &This->vardescs[index];

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

    if(index >= This->typeattr.cVars)
        return TYPE_E_ELEMENTNOTFOUND;

    var_desc->HelpContext = helpContext;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetMops(ICreateTypeInfo2 *iface,
        UINT index, BSTR bstrMops)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p %u %s - stub\n", This, index, wine_dbgstr_w(bstrMops));
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc(ICreateTypeInfo2 *iface,
        IDLDESC *idlDesc)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

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

    if (!idlDesc)
        return E_INVALIDARG;

    This->typeattr.idldescType.dwReserved = idlDesc->dwReserved;
    This->typeattr.idldescType.wIDLFlags = idlDesc->wIDLFlags;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(ICreateTypeInfo2 *iface)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    ITypeInfo *tinfo;
    TLBFuncDesc *func_desc;
    UINT user_vft = 0, i, depth = 0;
    HRESULT hres = S_OK;

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

    This->needs_layout = FALSE;

    hres = ICreateTypeInfo2_QueryInterface(iface, &IID_ITypeInfo, (LPVOID*)&tinfo);
    if (FAILED(hres))
        return hres;

    if (This->typeattr.typekind == TKIND_INTERFACE) {
        ITypeInfo *inh;
        TYPEATTR *attr;
        HREFTYPE inh_href;

        hres = ITypeInfo_GetRefTypeOfImplType(tinfo, 0, &inh_href);

        if (SUCCEEDED(hres)) {
            hres = ITypeInfo_GetRefTypeInfo(tinfo, inh_href, &inh);

            if (SUCCEEDED(hres)) {
                hres = ITypeInfo_GetTypeAttr(inh, &attr);
                if (FAILED(hres)) {
                    ITypeInfo_Release(inh);
                    ITypeInfo_Release(tinfo);
                    return hres;
                }
                This->typeattr.cbSizeVft = attr->cbSizeVft;
                ITypeInfo_ReleaseTypeAttr(inh, attr);

                do{
                    ++depth;
                    hres = ITypeInfo_GetRefTypeOfImplType(inh, 0, &inh_href);
                    if(SUCCEEDED(hres)){
                        ITypeInfo *next;
                        hres = ITypeInfo_GetRefTypeInfo(inh, inh_href, &next);
                        if(SUCCEEDED(hres)){
                            ITypeInfo_Release(inh);
                            inh = next;
                        }
                    }
                }while(SUCCEEDED(hres));
                hres = S_OK;

                ITypeInfo_Release(inh);
            } else if (hres == TYPE_E_ELEMENTNOTFOUND) {
                This->typeattr.cbSizeVft = 0;
                hres = S_OK;
            } else {
                ITypeInfo_Release(tinfo);
                return hres;
            }
        } else if (hres == TYPE_E_ELEMENTNOTFOUND) {
            This->typeattr.cbSizeVft = 0;
            hres = S_OK;
        } else {
            ITypeInfo_Release(tinfo);
            return hres;
        }
    } else if (This->typeattr.typekind == TKIND_DISPATCH)
        This->typeattr.cbSizeVft = 7 * This->pTypeLib->ptr_size;
    else
        This->typeattr.cbSizeVft = 0;

    func_desc = This->funcdescs;
    i = 0;
    while (i < This->typeattr.cFuncs) {
        if (!(func_desc->funcdesc.oVft & 0x1))
            func_desc->funcdesc.oVft = This->typeattr.cbSizeVft;

        if ((func_desc->funcdesc.oVft & 0xFFFC) > user_vft)
            user_vft = func_desc->funcdesc.oVft & 0xFFFC;

        This->typeattr.cbSizeVft += This->pTypeLib->ptr_size;

        if (func_desc->funcdesc.memid == MEMBERID_NIL) {
            TLBFuncDesc *iter;
            UINT j = 0;
            BOOL reset = FALSE;

            func_desc->funcdesc.memid = 0x60000000 + (depth << 16) + i;

            iter = This->funcdescs;
            while (j < This->typeattr.cFuncs) {
                if (iter != func_desc && iter->funcdesc.memid == func_desc->funcdesc.memid) {
                    if (!reset) {
                        func_desc->funcdesc.memid = 0x60000000 + (depth << 16) + This->typeattr.cFuncs;
                        reset = TRUE;
                    } else
                        ++func_desc->funcdesc.memid;
                    iter = This->funcdescs;
                    j = 0;
                } else {
                    ++iter;
                    ++j;
                }
            }
        }

        ++func_desc;
        ++i;
    }

    if (user_vft > This->typeattr.cbSizeVft)
        This->typeattr.cbSizeVft = user_vft + This->pTypeLib->ptr_size;

    for(i = 0; i < This->typeattr.cVars; ++i){
        TLBVarDesc *var_desc = &This->vardescs[i];
        if(var_desc->vardesc.memid == MEMBERID_NIL){
            UINT j = 0;
            BOOL reset = FALSE;
            TLBVarDesc *iter;

            var_desc->vardesc.memid = 0x40000000 + (depth << 16) + i;

            iter = This->vardescs;
            while (j < This->typeattr.cVars) {
                if (iter != var_desc && iter->vardesc.memid == var_desc->vardesc.memid) {
                    if (!reset) {
                        var_desc->vardesc.memid = 0x40000000 + (depth << 16) + This->typeattr.cVars;
                        reset = TRUE;
                    } else
                        ++var_desc->vardesc.memid;
                    iter = This->vardescs;
                    j = 0;
                } else {
                    ++iter;
                    ++j;
                }
            }
        }
    }

    ITypeInfo_Release(tinfo);
    return hres;
}

static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDesc(ICreateTypeInfo2 *iface,
        UINT index)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p %u - stub\n", This, index);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDescByMemId(ICreateTypeInfo2 *iface,
        MEMBERID memid, INVOKEKIND invKind)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p %x %d - stub\n", This, memid, invKind);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDesc(ICreateTypeInfo2 *iface,
        UINT index)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p %u - stub\n", This, index);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDescByMemId(ICreateTypeInfo2 *iface,
        MEMBERID memid)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p %x - stub\n", This, memid);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnDeleteImplType(ICreateTypeInfo2 *iface,
        UINT index)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p %u - stub\n", This, index);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetCustData(ICreateTypeInfo2 *iface,
        REFGUID guid, VARIANT *varVal)
{
    TLBGuid *tlbguid;

    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

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

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

    tlbguid = TLB_append_guid(&This->pTypeLib->guid_list, guid, -1);

    return TLB_set_custdata(This->pcustdata_list, tlbguid, varVal);
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncCustData(ICreateTypeInfo2 *iface,
        UINT index, REFGUID guid, VARIANT *varVal)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p %u %s %p - stub\n", This, index, debugstr_guid(guid), varVal);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetParamCustData(ICreateTypeInfo2 *iface,
        UINT funcIndex, UINT paramIndex, REFGUID guid, VARIANT *varVal)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p %u %u %s %p - stub\n", This, funcIndex, paramIndex, debugstr_guid(guid), varVal);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetVarCustData(ICreateTypeInfo2 *iface,
        UINT index, REFGUID guid, VARIANT *varVal)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p %u %s %p - stub\n", This, index, debugstr_guid(guid), varVal);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeCustData(ICreateTypeInfo2 *iface,
        UINT index, REFGUID guid, VARIANT *varVal)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p %u %s %p - stub\n", This, index, debugstr_guid(guid), varVal);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpStringContext(ICreateTypeInfo2 *iface,
        ULONG helpStringContext)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

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

    This->dwHelpStringContext = helpStringContext;

    return S_OK;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpStringContext(ICreateTypeInfo2 *iface,
        UINT index, ULONG helpStringContext)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p %u %u - stub\n", This, index, helpStringContext);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpStringContext(ICreateTypeInfo2 *iface,
        UINT index, ULONG helpStringContext)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p %u %u - stub\n", This, index, helpStringContext);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnInvalidate(ICreateTypeInfo2 *iface)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);
    FIXME("%p - stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI ICreateTypeInfo2_fnSetName(ICreateTypeInfo2 *iface,
        LPOLESTR name)
{
    ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface);

    TRACE("%p %s\n", This, wine_dbgstr_w(name));

    if (!name)
        return E_INVALIDARG;

    This->Name = TLB_append_str(&This->pTypeLib->name_list, name);

    return S_OK;
}

static const ICreateTypeInfo2Vtbl CreateTypeInfo2Vtbl = {
    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
};

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

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

            CoTaskMemFree(lpCust->prgCustData);
            lpCust->prgCustData = NULL;
        }
        lpCust->cCustData = 0;
    }
}
