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

    *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;
      TLBString *tlbstr, *tlbstr_next;
      TLBGuid *tlbguid, *tlbguid_next;
      void *cursor2;
      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, cursor2, &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:
        tdesc = &tattr->tdescAlias;
        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;
    }
}
