/*
 *	TYPELIB
 *
 *	Copyright 1997	Marcus Meissner
 *		      1999  Rein Klazes
 * there is much left to do here before it can be useful for real world
 * programs
 * know problems:
 * -. Only one format of typelibs is supported
 * -. All testing so far is done using special written windows programs
 * -. Data structures are straightforward, but slow for look-ups.
 * -. (related) nothing is hashed
 * -. a typelib is always read in its entirety into memory and never released.
 * -. there are a number of stubs in ITypeLib and ITypeInfo interfaces. Most
 *      of them I don't know yet how to implement them.
 * -. Most error return values are just guessed not checked with windows
 *      behaviour.
 * -. all locale stuff ignored
 * -. move stuff to wine/dlls
 * -. didn't bother with a c++ interface
 * -. lousy fatal error handling
 * -. some methods just return pointers to internal data structures, this is
 *      partly laziness, partly I want to check how windows does it.
 * 
 */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "winerror.h"
#include "winreg.h"         /* for HKEY_LOCAL_MACHINE */
#include "winnls.h"         /* for PRIMARYLANGID */
#include "wine/winbase16.h" /* for RegQueryValue16(HKEY,LPSTR,LPSTR,LPDWORD) */
#include "heap.h"
#include "wine/obj_base.h"
#include "debugtools.h"
#include "winversion.h"
/* FIXME: get rid of these */
typedef struct ITypeInfoVtbl ITypeLib_VTable, *LPTYPEINFO_VTABLE ; 
typedef struct ITypeLibVtbl *LPTYPELIB_VTABLE  ; 
#include "typelib.h"

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 */
	TLBSegDir * pTblDir;
	TLBLibInfo* pLibInfo;
} TLBContext;

DEFAULT_DEBUG_CHANNEL(ole);
DECLARE_DEBUG_CHANNEL(typelib);

/****************************************************************************
 *		QueryPathOfRegTypeLib16	[TYPELIB.14]
 *
 * the path is "Classes\Typelib\<guid>\<major>.<minor>\<lcid>\win16\"
 * RETURNS
 *	path of typelib
 */
HRESULT WINAPI
QueryPathOfRegTypeLib16(	
	REFGUID guid,	/* [in] referenced guid */
	WORD wMaj,	/* [in] major version */
	WORD wMin,	/* [in] minor version */
	LCID lcid,	/* [in] locale id */
	LPBSTR16 path	/* [out] path of typelib */
) {
	char	xguid[80];
	char	typelibkey[100],pathname[260];
	DWORD	plen;

	if (HIWORD(guid)) {
		WINE_StringFromCLSID(guid,xguid);
		sprintf(typelibkey,"SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%lx\\win16",
			xguid,wMaj,wMin,lcid
		);
	} else {
		sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
		FIXME("(%s,%d,%d,0x%04lx,%p),can't handle non-string guids.\n",xguid,wMaj,wMin,(DWORD)lcid,path);
		return E_FAIL;
	}
	plen = sizeof(pathname);
	if (RegQueryValue16(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
		/* try again without lang specific id */
		if (SUBLANGID(lcid))
			return QueryPathOfRegTypeLib16(guid,wMaj,wMin,PRIMARYLANGID(lcid),path);
		FIXME("key %s not found\n",typelibkey);
		return E_FAIL;
	}
	*path = SysAllocString16(pathname);
	return S_OK;
}
 
/****************************************************************************
 *		QueryPathOfRegTypeLib	[OLEAUT32.164]
 * RETURNS
 *	path of typelib
 */
HRESULT WINAPI
QueryPathOfRegTypeLib(	
	REFGUID guid,	/* [in] referenced guid */
	WORD wMaj,	/* [in] major version */
	WORD wMin,	/* [in] minor version */
	LCID lcid,	/* [in] locale id */
	LPBSTR path	/* [out] path of typelib */
) {
	char	xguid[80];
	char	typelibkey[100],pathname[260];
	DWORD	plen;


	if (HIWORD(guid)) {
		WINE_StringFromCLSID(guid,xguid);
		sprintf(typelibkey,"SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%lx\\win32",
			xguid,wMaj,wMin,lcid
		);
	} else {
		sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
		FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n",xguid,wMaj,wMin,(DWORD)lcid,path);
		return E_FAIL;
	}
	plen = sizeof(pathname);
	if (RegQueryValue16(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
		/* try again without lang specific id */
		if (SUBLANGID(lcid))
			return QueryPathOfRegTypeLib(guid,wMaj,wMin,PRIMARYLANGID(lcid),path);
		FIXME("key %s not found\n",typelibkey);
		return E_FAIL;
	}
	*path = HEAP_strdupAtoW(GetProcessHeap(),0,pathname);
	return S_OK;
}

/******************************************************************************
 * LoadTypeLib [TYPELIB.3]  Loads and registers a type library
 * NOTES
 *    Docs: OLECHAR FAR* szFile
 *    Docs: iTypeLib FAR* FAR* pptLib
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: Status
 */
HRESULT WINAPI LoadTypeLib16(
    LPOLESTR szFile, /* [in] Name of file to load from */
    void * *pptLib) /* [out] Pointer to pointer to loaded type library */
{
    FIXME("('%s',%p): stub\n",debugstr_w((LPWSTR)szFile),pptLib);

    if (pptLib!=0)
      *pptLib=0;

    return E_FAIL;
}

/******************************************************************************
 *		LoadTypeLib	[OLEAUT32.161]
 * Loads and registers a type library
 * NOTES
 *    Docs: OLECHAR FAR* szFile
 *    Docs: iTypeLib FAR* FAR* pptLib
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: Status
 */
int TLB_ReadTypeLib(PCHAR file, ITypeLib **ppTypelib);
HRESULT WINAPI LoadTypeLib(
    OLECHAR *szFile,   /* [in] Name of file to load from */
    ITypeLib * *pptLib) /* [out] Pointer to pointer to loaded type library */
{
    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(
    LPOLESTR szFile,   /* [in] Name of file to load from */
    REGKIND  regkind,  /* specify kind of registration */
    ITypeLib **pptLib) /* [out] Pointer to pointer to loaded type library */
{
    LPSTR p;
    HRESULT res;
    TRACE("('%s',%d,%p)\n",debugstr_w(szFile), regkind, pptLib);
    
    p=HEAP_strdupWtoA(GetProcessHeap(),0,szFile);
    
    if(regkind != REGKIND_NONE)
        FIXME ("registration of typelibs not supported yet!\n");

    res= TLB_ReadTypeLib(p, pptLib);
    /* XXX need to free p ?? */

    TRACE(" returns %ld\n",res);

    return res;
}

/******************************************************************************
 *		LoadRegTypeLib	[OLEAUT32.162]
 */
HRESULT WINAPI LoadRegTypeLib(	
	REFGUID rguid,	/* [in] referenced guid */
	WORD wVerMajor,	/* [in] major version */
	WORD wVerMinor,	/* [in] minor version */
	LCID lcid,	/* [in] locale id */
	ITypeLib **ppTLib	/* [out] path of typelib */
) {
    BSTR bstr=NULL;
    HRESULT res=QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor,
		    lcid, &bstr);
    if(SUCCEEDED(res)){
        res= LoadTypeLib(bstr, ppTLib);
        SysFreeString(bstr);
    }
    if(TRACE_ON(typelib)){
        char xriid[50];
        WINE_StringFromCLSID((LPCLSID)rguid,xriid);
        TRACE("(IID: %s) load %s (%p)\n",xriid,
              SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);
    }
    return res;
}	


/******************************************************************************
 *		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*/
{   FIXME("(%p,%s,%s): stub\n",ptlib, debugstr_w(szFullPath),debugstr_w(szHelpDir));
    return S_OK;	/* FIXME: pretend everything is OK */
}


/******************************************************************************
 *	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)
{   
    char xriid[50];
    WINE_StringFromCLSID((LPCLSID)libid,xriid);
    TRACE("(IID: %s): stub\n",xriid);
    return S_OK;	/* FIXME: pretend everything is OK */
}

/****************************************************************************
 *	OaBuildVersion				(TYPELIB.15)
 *
 * known TYPELIB.DLL versions:
 *
 * OLE 2.01 no OaBuildVersion() avail	1993	--	---
 * OLE 2.02				1993-94	02     3002
 * OLE 2.03					23	730
 * OLE 2.03					03     3025
 * OLE 2.03 W98 SE orig. file !!	1993-95	10     3024
 * OLE 2.1   NT				1993-95	??	???
 * OLE 2.3.1 W95				23	700
 */
DWORD WINAPI OaBuildVersion16(void)
{
    FIXME("Please report to a.mohr@mailto.de if you get version error messages !\n");
    switch(VERSION_GetVersion())
    {
      case WIN31:
		return MAKELONG(3027, 3); /* WfW 3.11 */
	case WIN95:
		return MAKELONG(700, 23); /* Win95A */
	case WIN98:
		return MAKELONG(3024, 10); /* W98 SE */
      default:
	FIXME_(ole)("Version value not known yet. Please investigate it !");
		return 0;
    }
}

/* for better debugging info leave the static out for the time being */
#define static

/*=======================Itypelib methods ===============================*/
/* ITypeLib methods */
static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid,
    VOID **ppvObject); 
static ULONG WINAPI ITypeLib_fnAddRef( LPTYPELIB This); 
static ULONG WINAPI ITypeLib_fnRelease( LPTYPELIB This); 
static UINT WINAPI ITypeLib_fnGetTypeInfoCount( LPTYPELIB This); 
static HRESULT WINAPI ITypeLib_fnGetTypeInfo( LPTYPELIB This, UINT index, 
    ITypeInfo **ppTInfo); 

static HRESULT WINAPI ITypeLib_fnGetTypeInfoType( LPTYPELIB This, UINT index,
    TYPEKIND *pTKind); 

static HRESULT WINAPI ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB This, REFGUID guid,
    ITypeInfo **ppTinfo);

static HRESULT WINAPI ITypeLib_fnGetLibAttr( LPTYPELIB This, 
    LPTLIBATTR *ppTLibAttr); 

static HRESULT WINAPI ITypeLib_fnGetTypeComp( LPTYPELIB This,
    ITypeComp **ppTComp); 

static HRESULT WINAPI ITypeLib_fnGetDocumentation( LPTYPELIB This, INT index,
    BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, 
    BSTR *pBstrHelpFile);

static HRESULT WINAPI ITypeLib_fnIsName( LPTYPELIB This, LPOLESTR szNameBuf,
    ULONG lHashVal, BOOL *pfName);

static HRESULT WINAPI ITypeLib_fnFindName( LPTYPELIB This, LPOLESTR szNameBuf,
    ULONG lHashVal, ITypeInfo **ppTInfo, MEMBERID *rgMemId, UINT16 *pcFound);

static VOID WINAPI ITypeLib_fnReleaseTLibAttr( LPTYPELIB This,
		TLIBATTR *pTLibAttr);

static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLib * This, REFGUID guid, 
        VARIANT *pVarVal); 

static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( ITypeLib * This, 
        UINT *pcUniqueNames, UINT *pcchUniqueNames); 

static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( ITypeLib * This, 
        INT index, LCID lcid, BSTR *pbstrHelpString,
        INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll); 

static HRESULT WINAPI ITypeLib2_fnGetAllCustData( ITypeLib * This,
        CUSTDATA *pCustData);
static ICOM_VTABLE(ITypeLib) tlbvt = {
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    ITypeLib_fnQueryInterface,
    ITypeLib_fnAddRef,
    ITypeLib_fnRelease,
    ITypeLib_fnGetTypeInfoCount,
    ITypeLib_fnGetTypeInfo,
    ITypeLib_fnGetTypeInfoType,
    ITypeLib_fnGetTypeInfoOfGuid,
    ITypeLib_fnGetLibAttr,
    ITypeLib_fnGetTypeComp,
    ITypeLib_fnGetDocumentation,
    ITypeLib_fnIsName,
    ITypeLib_fnFindName,
    ITypeLib_fnReleaseTLibAttr,
    ITypeLib2_fnGetCustData,
    ITypeLib2_fnGetLibStatistics,
    ITypeLib2_fnGetDocumentation2,
    ITypeLib2_fnGetAllCustData
 };
/* TypeInfo Methods */

static HRESULT WINAPI ITypeInfo_fnQueryInterface( LPTYPEINFO This, REFIID riid,
    VOID **ppvObject); 
static ULONG WINAPI ITypeInfo_fnAddRef( LPTYPEINFO This); 
static ULONG WINAPI ITypeInfo_fnRelease( LPTYPEINFO This); 
static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( LPTYPEINFO This,
        LPTYPEATTR  *ppTypeAttr); 

static HRESULT WINAPI ITypeInfo_fnGetTypeComp( LPTYPEINFO This,
        ITypeComp  * *ppTComp); 

static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( LPTYPEINFO This, UINT index,
        LPFUNCDESC  *ppFuncDesc); 

static HRESULT WINAPI ITypeInfo_fnGetVarDesc( LPTYPEINFO This, UINT index,
        LPVARDESC  *ppVarDesc); 

static HRESULT WINAPI ITypeInfo_fnGetNames( LPTYPEINFO This, MEMBERID memid,
        BSTR  *rgBstrNames, UINT cMaxNames, UINT  *pcNames);


static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO This,
        UINT index, HREFTYPE  *pRefType); 

static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO This,
        UINT index, INT  *pImplTypeFlags); 

static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( LPTYPEINFO This,
        LPOLESTR  *rgszNames, UINT cNames, MEMBERID  *pMemId); 

static HRESULT WINAPI ITypeInfo_fnInvoke( LPTYPEINFO This, VOID  *pIUnk,
        MEMBERID memid, UINT16 dwFlags, DISPPARAMS  *pDispParams, 
        VARIANT  *pVarResult, EXCEPINFO  *pExcepInfo, UINT  *pArgErr);

static HRESULT WINAPI ITypeInfo_fnGetDocumentation( LPTYPEINFO This,
        MEMBERID memid, BSTR  *pBstrName, BSTR  *pBstrDocString, 
        DWORD  *pdwHelpContext, BSTR  *pBstrHelpFile); 

static HRESULT WINAPI ITypeInfo_fnGetDllEntry( LPTYPEINFO This,
        MEMBERID memid, INVOKEKIND invKind, BSTR  *pBstrDllName,
        BSTR  *pBstrName, WORD  *pwOrdinal); 

static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO This,
        HREFTYPE hRefType, ITypeInfo  * *ppTInfo); 

static HRESULT WINAPI ITypeInfo_fnAddressOfMember( LPTYPEINFO This,
        MEMBERID memid, INVOKEKIND invKind, PVOID *ppv); 

static HRESULT WINAPI ITypeInfo_fnCreateInstance( LPTYPEINFO This, 
        IUnknown *pUnk, REFIID riid, VOID  * *ppvObj); 

static HRESULT WINAPI ITypeInfo_fnGetMops( LPTYPEINFO This, MEMBERID memid, 
        BSTR  *pBstrMops);


static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( LPTYPEINFO This,
        ITypeLib  * *ppTLib, UINT  *pIndex); 

static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO This,
        TYPEATTR *pTypeAttr); 

static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO This,
        FUNCDESC *pFuncDesc); 

static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( LPTYPEINFO This,
        VARDESC *pVarDesc); 
/* itypeinfo2 methods */
static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo * This,
    TYPEKIND *pTypeKind);
static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo * This,
    UINT *pTypeFlags);
static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo * This,
    MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex);
static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo * This,
    MEMBERID memid, UINT *pVarIndex);
static HRESULT WINAPI ITypeInfo2_fnGetCustData( ITypeInfo * This,
    REFGUID guid, VARIANT *pVarVal);
static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( ITypeInfo * This,
    UINT index, REFGUID guid, VARIANT *pVarVal);
static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( ITypeInfo * This,
    UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal);
static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( ITypeInfo * This,
    UINT index, REFGUID guid, VARIANT *pVarVal);
static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( ITypeInfo * This,
    UINT index, REFGUID guid, VARIANT *pVarVal);
static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( ITypeInfo * This,
    MEMBERID memid, LCID lcid, BSTR *pbstrHelpString,
    INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll);
static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( ITypeInfo * This,
    CUSTDATA *pCustData);
static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( ITypeInfo * This,
    UINT index, CUSTDATA *pCustData);
static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo * This,
    UINT indexFunc, UINT indexParam, CUSTDATA *pCustData);
static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo * This,
    UINT index, CUSTDATA *pCustData);
static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo * This,
    UINT index, CUSTDATA *pCustData);

static ICOM_VTABLE(ITypeInfo) tinfvt = {
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    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,

};

static TYPEDESC stndTypeDesc[VT_LPWSTR+1]={/* VT_LPWSTR is largest type that */
										/* may appear in type description*/
	{{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
        {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
    {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
        {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
    {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
        {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
    {{0},30},{{0},31}};

static void TLB_abort()
{
    DebugBreak();
}
static void * TLB_Alloc(unsigned size)
{
    void * ret;
    if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){
        /* FIXME */
        ERR("cannot allocate memory\n");
    }
    return ret;
}

/* candidate for a more global appearance... */
static BSTR  TLB_DupAtoBstr(PCHAR Astr)
{
    int len;
    BSTR bstr;
    DWORD *pdw  ;
    if(!Astr)
        return NULL;
    len=strlen(Astr);
    pdw  =TLB_Alloc((len+3)*sizeof(OLECHAR));
    pdw[0]=(len)*sizeof(OLECHAR);
    bstr=(BSTR)&( pdw[1]);
    lstrcpyAtoW( bstr, Astr);
    TRACE("copying %s to (%p)\n", Astr, bstr);
    return bstr;
}

static void TLB_Free(void * ptr)
{
    HeapFree(GetProcessHeap(), 0, ptr);
}
/* read function */
DWORD TLB_Read(void *buffer,  DWORD count, TLBContext *pcx, long where )
{
    if (where != DO_NOT_SEEK)
    {
        where += pcx->oStart;
        if (where > pcx->length)
        {
            /* FIXME */
            ERR("seek beyond end (%ld/%d)\n", where, pcx->length );
            TLB_abort();
        }
        pcx->pos = 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 void TLB_ReadGuid( GUID *pGuid, int offset,   TLBContext *pcx)
{
    if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){
        memset(pGuid,0, sizeof(GUID));
        return;
    }
    TLB_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset );
}

PCHAR TLB_ReadName( TLBContext *pcx, int offset)
{
    char * name;
    TLBNameIntro niName;
    TLB_Read(&niName, sizeof(niName), pcx,
				pcx->pTblDir->pNametab.offset+offset);
    niName.namelen &= 0xFF; /* FIXME: correct ? */
    name=TLB_Alloc((niName.namelen & 0xff) +1);
    TLB_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK);
    name[niName.namelen & 0xff]='\0';
    return name;
}
PCHAR TLB_ReadString( TLBContext *pcx, int offset)
{
    char * string;
    INT16 length;
    if(offset<0) return NULL;
    TLB_Read(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
    if(length <= 0) return 0;
    string=TLB_Alloc(length +1);
    TLB_Read(string, length, pcx, DO_NOT_SEEK);
    string[length]='\0';
    return string;
}
/*
 * read a value and fill a VARIANT structure 
 */
static void TLB_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
{
    int size;
    if(offset <0) { /* data is packed in here */
        pVar->vt = (offset & 0x7c000000 )>> 26;
        V_UNION(pVar, iVal) = offset & 0xffff;
        return;
    }
    TLB_Read(&(pVar->vt), sizeof(VARTYPE), pcx, 
        pcx->pTblDir->pCustData.offset + offset );
    switch(pVar->vt){
        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;
            TLB_Read(&size, sizeof(INT), pcx, DO_NOT_SEEK );
            ptr=TLB_Alloc(size);/* allocate temp buffer */
            TLB_Read(ptr, size, pcx, DO_NOT_SEEK ); /* read string (ANSI) */
            V_UNION(pVar, bstrVal)=SysAllocStringLen(NULL,size);
            /* FIXME: do we need a AtoW conversion here? */
            V_UNION(pVar, bstrVal[size])=L'\0';
            while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
            TLB_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",
                pVar->vt);
    }

    if(size>0) /* (big|small) endian correct? */
        TLB_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK );
        return ;
}
/*
 * create a linked list with custom data
 */
static int TLB_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
{
    TLBCDGuid entry;
    TLBCustData* pNew;
    int count=0;
    while(offset >=0){
        count++;
        pNew=TLB_Alloc(sizeof(TLBCustData));
        TLB_Read(&entry, sizeof(entry), pcx, 
            pcx->pTblDir->pCDGuids.offset+offset);
        TLB_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
        TLB_ReadValue(&(pNew->data), entry.DataOffset, pcx);
        /* add new custom data at head of the list */
        pNew->next=*ppCustData;
        *ppCustData=pNew;
        offset = entry.next;
    }
    return count;
}

static void TLB_GetTdesc(TLBContext *pcx, INT type,TYPEDESC * pTd )
{
    if(type <0)
        pTd->vt=type & VT_TYPEMASK;
    else
        *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
}
static void TLB_DoFuncs(TLBContext *pcx, 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.
     *
     * First entry is always the length of the record (excluding this
     * length word). 
     * Rest of the record depends on the type of the member. If there is 
     * a field indicating the member type (function variable intereface 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 memeber id
     * for each member;
     * 
     * Third is a equal sized array with file offsets to the name entry 
     * of each member.
     * 
     * Forth and last (?) part is an array with offsets to the records in the
     * first part of this file segment.
     */

    int infolen, nameoffset, reclength, nrattributes;
    char recbuf[512];
    TLBFuncRecord * pFuncRec=(TLBFuncRecord *) recbuf;
    int i, j;
    int recoffset=offset+sizeof(INT);
    TLB_Read(&infolen,sizeof(INT), pcx, offset);
    for(i=0;i<cFuncs;i++){
        *pptfd=TLB_Alloc(sizeof(TLBFuncDesc));
    /* name, eventually add to a hash table */
        TLB_Read(&nameoffset, sizeof(INT), pcx, 
            offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
        (*pptfd)->Name=TLB_ReadName(pcx, nameoffset);
    /* read the function information record */
        TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
        reclength &=0x1ff;
        TLB_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ; 
    /* do the attributes */
        nrattributes=(reclength-pFuncRec->nrargs*3*sizeof(int)-0x18)
            /sizeof(int);
        if(nrattributes>0){
            (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
            if(nrattributes>1){
                (*pptfd)->HelpString = TLB_ReadString(pcx,
                                                      pFuncRec->OptAttr[1]) ;
                if(nrattributes>2){
                    if(pFuncRec->FKCCIC & 0x2000)
                        (*pptfd)->Entry = (char *) pFuncRec->OptAttr[2] ;
                    else
                        (*pptfd)->Entry = TLB_ReadString(pcx,
                                                         pFuncRec->OptAttr[2]);
                    if(nrattributes>5 )
                        (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;
                    if(nrattributes>6 && pFuncRec->FKCCIC & 0x80){
                        TLB_CustData(pcx, pFuncRec->OptAttr[6],
                                &(*pptfd)->pCustData);
                    }
                }
            }
        }
    /* fill the FuncDesc Structure */
        TLB_Read(&(*pptfd)->funcdesc.memid, sizeof(INT), pcx, 
            offset + infolen + ( i + 1) * sizeof(INT));
        (*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
        (*pptfd)->funcdesc.invkind = ((pFuncRec->FKCCIC) >>3) & 0xF;
        (*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >>8 & 0xF;
        (*pptfd)->funcdesc.cParams = pFuncRec->nrargs ;
        (*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ;
        (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ;
        (*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags)  ;
        TLB_GetTdesc(pcx, pFuncRec->DataType,   
            &(*pptfd)->funcdesc.elemdescFunc.tdesc) ;
                                    
        /* do the parameters/arguments */
        if(pFuncRec->nrargs){
            TLBParameterInfo paraminfo;
            (*pptfd)->funcdesc.lprgelemdescParam=
                TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
            (*pptfd)->pParamDesc=TLB_Alloc(pFuncRec->nrargs *
                sizeof(TLBParDesc));

            TLB_Read(&paraminfo,sizeof(paraminfo), pcx, recoffset+reclength -
                pFuncRec->nrargs * sizeof(TLBParameterInfo));
            for(j=0;j<pFuncRec->nrargs;j++){
                TLB_GetTdesc(pcx, paraminfo.DataType,   
                    &(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc) ;
                V_UNION(&((*pptfd)->funcdesc.lprgelemdescParam[j]),
                    paramdesc.wParamFlags) = paraminfo.Flags;
                (*pptfd)->pParamDesc[j].Name=(void *)paraminfo.oName;
                TLB_Read(&paraminfo,sizeof(TLBParameterInfo), pcx,
                        DO_NOT_SEEK);
            }
            /* second time around */
            for(j=0;j<pFuncRec->nrargs;j++){
                /* name */
                (*pptfd)->pParamDesc[j].Name=
                    TLB_ReadName(pcx, (int)(*pptfd)->pParamDesc[j].Name);
                /* default value */
                if((PARAMFLAG_FHASDEFAULT & V_UNION(&((*pptfd)->funcdesc.
                    lprgelemdescParam[j]),paramdesc.wParamFlags)) &&
                    ((pFuncRec->FKCCIC) & 0x1000)){
                    INT *pInt=(INT *)((char *)pFuncRec + reclength -
                        (pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
                    PARAMDESC * pParamDesc= &V_UNION(&((*pptfd)->funcdesc.
                        lprgelemdescParam[j]),paramdesc);
                    pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
                    pParamDesc->pparamdescex->cBytes= sizeof(PARAMDESCEX);
                    TLB_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue), 
                        pInt[j], pcx);
                }
                /* custom info */
                if(nrattributes>7+j && pFuncRec->FKCCIC & 0x80)
                    TLB_CustData(pcx, pFuncRec->OptAttr[7+j],
									&(*pptfd)->pParamDesc[j].pCustData);
            }
        }
    /* scode is not used: archaic win16 stuff FIXME: right? */
        (*pptfd)->funcdesc.cScodes = 0 ;
        (*pptfd)->funcdesc.lprgscode = NULL ;
        pptfd=&((*pptfd)->next);
        recoffset += reclength;
    }
}
static void TLB_DoVars(TLBContext *pcx, int cFuncs, int cVars,
                          int offset, TLBVarDesc ** pptvd)
{
    int infolen, nameoffset, reclength;
    char recbuf[256];
    TLBVarRecord * pVarRec=(TLBVarRecord *) recbuf;
    int i;
    int recoffset;
    TLB_Read(&infolen,sizeof(INT), pcx, offset);
    TLB_Read(&recoffset,sizeof(INT), pcx, offset + infolen + 
        ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
    recoffset += offset+sizeof(INT);
    for(i=0;i<cVars;i++){
        *pptvd=TLB_Alloc(sizeof(TLBVarDesc));
    /* name, eventually add to a hash table */
        TLB_Read(&nameoffset, sizeof(INT), pcx, 
            offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
        (*pptvd)->Name=TLB_ReadName(pcx, nameoffset);
    /* read the variable information record */
        TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
        reclength &=0xff;
        TLB_Read(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ; 
    /* Optional data */
        if(reclength >(6*sizeof(INT)) )
            (*pptvd)->HelpContext=pVarRec->HelpContext;
        if(reclength >(7*sizeof(INT)) )
            (*pptvd)->HelpString = TLB_ReadString(pcx, pVarRec->oHelpString) ;
        if(reclength >(8*sizeof(INT)) )
        if(reclength >(9*sizeof(INT)) )
            (*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
    /* fill the VarDesc Structure */
        TLB_Read(&(*pptvd)->vardesc.memid, sizeof(INT), pcx, 
            offset + infolen + ( i + 1) * sizeof(INT));
        (*pptvd)->vardesc.varkind = pVarRec->VarKind;
        (*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
        TLB_GetTdesc(pcx, pVarRec->DataType,    
            &(*pptvd)->vardesc.elemdescVar.tdesc) ;
/*   (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) fixme?? */
        if(pVarRec->VarKind == VAR_CONST ){
            V_UNION(&((*pptvd)->vardesc),lpvarValue)=TLB_Alloc(sizeof(VARIANT));
            TLB_ReadValue(V_UNION(&((*pptvd)->vardesc),lpvarValue), 
                pVarRec->OffsValue, pcx);
        }else
            V_UNION(&((*pptvd)->vardesc),oInst)=pVarRec->OffsValue;
        pptvd=&((*pptvd)->next);
        recoffset += reclength;
    }
}
/* fill in data for a hreftype (offset). When the refernced type is contained
 * in the typelib, its just an (file) offset in the type info base dir.
 * If comes fom import, its an offset+1 in the ImpInfo table
 * */
static void TLB_DoRefType(TLBContext *pcx, 
                          int offset, TLBRefType ** pprtd)
{
    int j;
    if(!HREFTYPE_INTHISFILE( offset)) {
        /* external typelib */
        TLBImpInfo impinfo;
        TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs);
        TLB_Read(&impinfo, sizeof(impinfo), pcx, 
            pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
        for(j=0;pImpLib;j++){   /* search the known offsets of all import libraries */
            if(pImpLib->offset==impinfo.oImpFile) break;
            pImpLib=pImpLib->next;
        }
        if(pImpLib){
            (*pprtd)->reference=offset;
            (*pprtd)->pImpTLInfo=pImpLib;
            TLB_ReadGuid(&(*pprtd)->guid, impinfo.oGuid, pcx);
        }else{
            ERR("Cannot find a reference\n");
            (*pprtd)->reference=-1;
            (*pprtd)->pImpTLInfo=(void *)-1;
        }
    }else{
        /* in this typelib */
        (*pprtd)->reference=offset;
        (*pprtd)->pImpTLInfo=(void *)-2;
    }
}

/* process Implemented Interfaces of a com class */
static void TLB_DoImplTypes(TLBContext *pcx, int count,
                          int offset, TLBRefType ** pprtd)
{
    int i;
    TLBRefRecord refrec;
    for(i=0;i<count;i++){
        if(offset<0) break; /* paranoia */
        *pprtd=TLB_Alloc(sizeof(TLBRefType));
        TLB_Read(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
        TLB_DoRefType(pcx, refrec.reftype, pprtd);
        (*pprtd)->flags=refrec.flags;
        (*pprtd)->ctCustData=
            TLB_CustData(pcx, refrec.oCustData, &(*pprtd)->pCustData);
        offset=refrec.onext;
        pprtd=&((*pprtd)->next);
    }
}
/*
 * process a typeinfo record
 */
TLBTypeInfo * TLB_DoTypeInfo(TLBContext *pcx, int count, TLBLibInfo* pLibInfo)
{
    TLBTypeInfoBase tiBase;
    TLBTypeInfo *ptiRet;
    ptiRet=TLB_Alloc(sizeof(TLBTypeInfo));
    ptiRet->lpvtbl = &tinfvt;
    ptiRet->ref=1;
    TLB_Read(&tiBase, sizeof(tiBase) ,pcx ,
        pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
/* this where we are coming from */
    ptiRet->pTypeLib=pLibInfo;
    ptiRet->index=count;
/* fill in the typeattr fields */
    TLB_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx);
    ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid;   /* FIXME: correct? */
    ptiRet->TypeAttr.memidConstructor=MEMBERID_NIL ;/* FIXME */
    ptiRet->TypeAttr.memidDestructor=MEMBERID_NIL ; /* FIXME */
    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)
        TLB_GetTdesc(pcx, tiBase.datatype1, 
            &ptiRet->TypeAttr.tdescAlias) ;
/*  FIXME: */
/*    IDLDESC  idldescType; *//* never saw this one != zero  */

/* name, eventually add to a hash table */
    ptiRet->Name=TLB_ReadName(pcx, tiBase.NameOffset);
    TRACE("reading %s\n", ptiRet->Name);
    /* help info */
    ptiRet->DocString=TLB_ReadString(pcx, tiBase.docstringoffs);
    ptiRet->dwHelpStringContext=tiBase.helpstringcontext;
    ptiRet->dwHelpContext=tiBase.helpcontext;
/* 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 )
        TLB_DoFuncs(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars, 
        tiBase.memoffset, & ptiRet->funclist);
    /* variables */
    if(ptiRet->TypeAttr.cVars >0 )
        TLB_DoVars(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars, 
        tiBase.memoffset, & ptiRet->varlist);
    if(ptiRet->TypeAttr.cImplTypes >0 ){
        if(ptiRet->TypeAttr.typekind == TKIND_COCLASS)
            TLB_DoImplTypes(pcx, ptiRet->TypeAttr.cImplTypes , 
                tiBase.datatype1, & ptiRet->impltypelist);
        else if(ptiRet->TypeAttr.typekind != TKIND_DISPATCH){
            ptiRet->impltypelist=TLB_Alloc(sizeof(TLBRefType));
            TLB_DoRefType(pcx, tiBase.datatype1, & ptiRet->impltypelist);
        }
	}
    ptiRet->ctCustData=
        TLB_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData);
    return ptiRet;
}


long TLB_FindTlb(TLBContext *pcx)
{/* FIXME: should parse the file properly
  * hack to find our tlb data
  */
#define TLBBUFSZ 1024
    char buff[TLBBUFSZ+1]; /* room for a trailing '\0' */
    long ret=0,found=0;
    int count;
    char *pChr;

#define LOOK_FOR_MAGIC(magic)				\
    count=TLB_Read(buff, TLBBUFSZ, pcx, 0);		\
    do {						\
        buff[count]='\0';				\
	pChr = buff;					\
	while (pChr) {					\
	    pChr = memchr(pChr,magic[0],count-(pChr-buff));\
	    if (pChr) {					\
		if (!memcmp(pChr,magic,4)) {		\
		    ret+= pChr-buff;			\
		    found = 1;				\
		    break;				\
		}					\
		pChr++;					\
	    }						\
	}						\
	if (found) break;				\
        ret+=count;					\
	count=TLB_Read(buff, TLBBUFSZ, pcx, DO_NOT_SEEK);\
    } while(count>0);


    LOOK_FOR_MAGIC(TLBMAGIC2);
    if(count)
        return ret;

    LOOK_FOR_MAGIC(TLBMAGIC1);
    if(count)
        ERR("type library format not (yet) implemented\n");
    else
        ERR("not type library found in this file\n");
    return -1;
}
#undef LOOK_FOR_MAGIC

int TLB_ReadTypeLib(PCHAR file, ITypeLib **ppTypeLib)
{
    TLBContext cx;
    OFSTRUCT ofStruct;
    long oStart,lPSegDir;
    TLBLibInfo* pLibInfo=NULL;
    TLB2Header tlbHeader;
    TLBSegDir tlbSegDir;

    HANDLE hFile, hMap;
    if((hFile=OpenFile(file, &ofStruct, OF_READ))==HFILE_ERROR) {
	ERR("cannot open %s error 0x%lx\n",file, GetLastError());
	return E_FAIL;
    }
    cx.length = SetFilePointer( hFile, 0, NULL, FILE_END );
    if (!(hMap = CreateFileMappingA( hFile, NULL, PAGE_READONLY, 0, 0, NULL )))
    {
        CloseHandle( hFile );
	ERR("cannot map %s error 0x%lx\n",file, GetLastError());
	return E_FAIL;
    }
    CloseHandle( hFile );
    cx.mapping = MapViewOfFile( hMap, FILE_MAP_READ, 0, 0, 0 );
    CloseHandle( hMap );
    if (!cx.mapping)
    {
	ERR("cannot map view of %s error 0x%lx\n",file, GetLastError());
	return E_FAIL;
    }
    /* get pointer to beginning of typelib data */
    cx.pos = 0;
    cx.oStart=0;
    if((oStart=TLB_FindTlb(&cx))<0){
        if(oStart==-1)
            ERR("cannot locate typelib in  %s\n",file);
        else
            ERR("unsupported typelib format in  %s\n",file);
        UnmapViewOfFile( cx.mapping );
        return E_FAIL;
    }
    cx.oStart=oStart;
    pLibInfo=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TLBLibInfo));
    if (!pLibInfo){
        UnmapViewOfFile( cx.mapping );
        return E_OUTOFMEMORY;
    }
    pLibInfo->lpvtbl = &tlbvt;
    pLibInfo->ref=1;
    cx.pLibInfo=pLibInfo;
    /* read header */
    TLB_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
    /* there is a small number 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 */
    TLB_Read((void*)&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%lx\n",lPSegDir);
        UnmapViewOfFile( cx.mapping );
        return E_FAIL;
    }
    /* now fill our internal data */
    /* TLIBATTR fields */
    TLB_ReadGuid(&pLibInfo->LibAttr.guid, tlbHeader.posguid, &cx);
    pLibInfo->LibAttr.lcid=tlbHeader.lcid;
    pLibInfo->LibAttr.syskind=tlbHeader.varflags & 0x0f; /* check the mask */
    pLibInfo->LibAttr.wMajorVerNum=LOWORD(tlbHeader.version);
    pLibInfo->LibAttr.wMinorVerNum=HIWORD(tlbHeader.version);
    pLibInfo->LibAttr.wLibFlags=(WORD) tlbHeader.flags & 0xffff;/* check mask */
    /* name, eventually add to a hash table */
    pLibInfo->Name=TLB_ReadName(&cx, tlbHeader.NameOffset);
    /* help info */
    pLibInfo->DocString=TLB_ReadString(&cx, tlbHeader.helpstring);
    pLibInfo->HelpFile=TLB_ReadString(&cx, tlbHeader.helpfile);
    if( tlbHeader.varflags & HELPDLLFLAG){
            int offset;
            TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
            pLibInfo->HelpStringDll=TLB_ReadString(&cx, offset);
    }

    pLibInfo->dwHelpContext=tlbHeader.helpstringcontext;
    /* custom data */
    if(tlbHeader.CustomDataOffset >= 0) {
        pLibInfo->ctCustData=
            TLB_CustData(&cx, tlbHeader.CustomDataOffset, &pLibInfo->pCustData);
    }
    /* fill in typedescriptions */
    if(tlbSegDir.pTypdescTab.length >0){
        int i, j, cTD=tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
        INT16 td[4];
        pLibInfo->pTypeDesc=
            TLB_Alloc( cTD * sizeof(TYPEDESC));
        TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
        for(i=0;i<cTD;){
            /* FIXME: add several sanity checks here */
            pLibInfo->pTypeDesc[i].vt=td[0] & VT_TYPEMASK;
            if(td[0]==VT_PTR ||td[0]==VT_SAFEARRAY){/* FIXME: check safearray */
                if(td[3]<0)
                    V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
                        & stndTypeDesc[td[2]];
                else
                    V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
                        & pLibInfo->pTypeDesc[td[3]/8];
            }else if(td[0]==VT_CARRAY)
                V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
                    (void *)((int) td[2]);  /* temp store offset in*/
                                            /* array descr table here */
            else if(td[0]==VT_USERDEFINED)
                V_UNION(&(pLibInfo->pTypeDesc[i]),hreftype)=MAKELONG(td[2],td[3]);
            if(++i<cTD) TLB_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
        }
        /* second time around to fill the array subscript info */
        for(i=0;i<cTD;i++){
            if(pLibInfo->pTypeDesc[i].vt != VT_CARRAY) continue;
            if(tlbSegDir.pArrayDescriptions.offset>0){
                TLB_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset +
                    (int) V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc));
                V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
                    TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
                if(td[1]<0)
                    V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem.vt=td[0] & VT_TYPEMASK;
                else
                    V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem=stndTypeDesc[td[0]/8];
                V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->cDims=td[2];
                for(j=0;j<td[2];j++){
                    TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->rgbounds[j].cElements, 
                        sizeof(INT), &cx, DO_NOT_SEEK);
                    TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)
                        ->rgbounds[j].lLbound, 
                        sizeof(INT), &cx, DO_NOT_SEEK);
                }
            }else{
                V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=NULL;
                ERR("didn't find array description data\n");
            }
        }
    }
    /* imported type libs */
    if(tlbSegDir.pImpFiles.offset>0){
        TLBImpLib **ppImpLib=&(pLibInfo->pImpLibs);
        int offset=tlbSegDir.pImpFiles.offset;
        int oGuid;
        UINT16 size;
        while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length){
            *ppImpLib=TLB_Alloc(sizeof(TLBImpLib));
            (*ppImpLib)->offset=offset - tlbSegDir.pImpFiles.offset;
            TLB_Read(&oGuid, sizeof(INT), &cx, offset);
            TLB_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
            /* we are skipping some unknown info here */
            TLB_Read(& size,sizeof(UINT16), &cx, offset+3*(sizeof(INT)));
            size >>=2;
            (*ppImpLib)->name=TLB_Alloc(size+1);
            TLB_Read((*ppImpLib)->name,size, &cx, DO_NOT_SEEK);
            offset=(offset+3*(sizeof(INT))+sizeof(UINT16)+size+3) & 0xfffffffc;

            ppImpLib=&(*ppImpLib)->next;
        }
    }
    /* type info's */
    if(tlbHeader.nrtypeinfos >=0 ){
        /*pLibInfo->TypeInfoCount=tlbHeader.nrtypeinfos; */
        TLBTypeInfo **ppTI=&(pLibInfo->pTypeInfo);
        int i;
        for(i=0;i<(int)tlbHeader.nrtypeinfos;i++){
            *ppTI=TLB_DoTypeInfo(&cx, i, pLibInfo);
            ppTI=&((*ppTI)->next);
            (pLibInfo->TypeInfoCount)++;
        }
    }

    UnmapViewOfFile( cx.mapping );
    *ppTypeLib=(LPTYPELIB)pLibInfo;
    return S_OK;
}

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

/* ITypeLib::QueryInterface
 */
static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid,
    VOID **ppvObject)
{
    if(TRACE_ON(typelib)){
        char xriid[50];
        WINE_StringFromCLSID((LPCLSID)riid,xriid);
        TRACE("(%p)->(IID: %s)\n",This,xriid);
    }
    *ppvObject=NULL;
    if(IsEqualIID(riid, &IID_IUnknown) || 
            IsEqualIID(riid,&IID_ITypeLib)||
            IsEqualIID(riid,&IID_ITypeLib2))
        *ppvObject = This;
    if(*ppvObject){
        ITypeLib_AddRef(This);
        TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
        return S_OK;
    }
    TRACE("-- Interface: E_NOINTERFACE\n");
    return E_NOINTERFACE;
}

/* ITypeLib::AddRef
 */
static ULONG WINAPI ITypeLib_fnAddRef( LPTYPELIB iface)
{
	ICOM_THIS( TLBLibInfo, iface);
    TRACE("(%p)->ref is %u\n",This, This->ref);
    return ++(This->ref);
}

/* ITypeLib::Release
 */
static ULONG WINAPI ITypeLib_fnRelease( LPTYPELIB iface)
{
	ICOM_THIS( TLBLibInfo, iface);
    FIXME("(%p)->ref is %u:   stub\n",This, This->ref);
    (This->ref)--;
    return S_OK;
}

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

/* ITypeLib::GetTypeInfo
 *
 *etrieves the specified type description in the library.
 */
static HRESULT WINAPI ITypeLib_fnGetTypeInfo( LPTYPELIB iface, UINT index, 
    ITypeInfo **ppTInfo)
{
    int i;
	ICOM_THIS( TLBLibInfo, iface);
	TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo;
    TRACE("(%p) index %d \n",This, index);
    for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo && i != index;i++)
        *ppTLBTInfo=(*ppTLBTInfo)->next;
    if(*ppTLBTInfo){
        (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
        TRACE("-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
        return S_OK;
    }
    TRACE("-- element not found\n");
    return TYPE_E_ELEMENTNOTFOUND;
}

/* ITypeLibs::GetTypeInfoType
 *
 * Retrieves the type of a type description.
 */
static HRESULT WINAPI ITypeLib_fnGetTypeInfoType( LPTYPELIB iface, UINT index,
    TYPEKIND *pTKind)
{
    int i;
    TLBTypeInfo *pTInfo;
	ICOM_THIS( TLBLibInfo, iface);
    TRACE("(%p) index %d \n",This, index);
    for(i=0,pTInfo=This->pTypeInfo;pTInfo && i != index;i++)
        pTInfo=(pTInfo)->next;
    if(pTInfo){
        *pTKind=pTInfo->TypeAttr.typekind;
        TRACE("-- found Type (%p)->%d\n",pTKind,*pTKind);
        return S_OK;
    }
    TRACE("-- element not found\n");
    return TYPE_E_ELEMENTNOTFOUND;
}

/* ITypeLib::GetTypeInfoOfGuid
 *
 * Retrieves the type description that corresponds to the specified GUID.
 *
 */
static HRESULT WINAPI ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB iface,
				REFGUID guid, ITypeInfo **ppTInfo)
{
    int i;
	ICOM_THIS( TLBLibInfo, iface);
	TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo;
    if(TRACE_ON(typelib)){
        char xriid[50];
        WINE_StringFromCLSID((LPCLSID)guid,xriid);
        TRACE("(%p) guid %sx)\n",This,xriid);
    }
    for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo && 
            !IsEqualIID(guid,&(*ppTLBTInfo)->TypeAttr.guid);i++)
        *ppTLBTInfo=(*ppTLBTInfo)->next;
    if(*ppTLBTInfo){
        (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
        TRACE("-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
        return S_OK;
    }
    TRACE("-- element not found\n");
    return TYPE_E_ELEMENTNOTFOUND;
}

/* ITypeLib::GetLibAttr
 *
 * Retrieves the structure that contains the library's attributes.
 *
 */
static HRESULT WINAPI ITypeLib_fnGetLibAttr( LPTYPELIB iface, 
    LPTLIBATTR *ppTLibAttr)
{
	ICOM_THIS( TLBLibInfo, iface);
    TRACE("(%p)\n",This);
    /* FIXME: must do a copy here */
    *ppTLibAttr=&This->LibAttr;
    return S_OK;
}

/* ITypeLib::GetTypeComp
 *
 * Enables a client compiler to bind to a library's types, variables,
 * constants, and global functions.
 *
 */
static HRESULT WINAPI ITypeLib_fnGetTypeComp( LPTYPELIB iface,
    ITypeComp **ppTComp)
{
	ICOM_THIS( TLBLibInfo, iface);
    FIXME("(%p): stub!\n",This);
    return E_NOTIMPL;
}

/* 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.
 *
 */
static HRESULT WINAPI ITypeLib_fnGetDocumentation( LPTYPELIB iface, INT index,
    BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, 
    BSTR *pBstrHelpFile)
{
	ICOM_THIS( TLBLibInfo, iface);
    HRESULT result;
    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)
            *pBstrName=TLB_DupAtoBstr(This->Name);
        if(pBstrDocString)
            *pBstrName=TLB_DupAtoBstr(This->DocString);
        if(pdwHelpContext)
            *pdwHelpContext=This->dwHelpContext;
        if(pBstrHelpFile)
            *pBstrName=TLB_DupAtoBstr(This->HelpFile);
    }else {/* for a typeinfo */
        result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo);
        if(SUCCEEDED(result)){
            result=ITypeInfo_GetDocumentation(pTInfo, MEMBERID_NIL,  pBstrName,
                pBstrDocString, pdwHelpContext, pBstrHelpFile);
            ITypeInfo_Release(pTInfo);
        }
        if(!SUCCEEDED(result))
            return result;
    }
    return S_OK;
}

/* ITypeLib::IsName
 *
 * Indicates whether a passed-in string contains the name of a type or member
 * described in the library.
 *
 */
static HRESULT WINAPI ITypeLib_fnIsName( LPTYPELIB iface, LPOLESTR szNameBuf,
    ULONG lHashVal, BOOL *pfName)
{
	ICOM_THIS( TLBLibInfo, iface);
    TLBTypeInfo *pTInfo;
    TLBFuncDesc *pFInfo;
    TLBVarDesc *pVInfo;
    int i;
    PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
    *pfName=TRUE;
    if(!strcmp(astr,This->Name)) goto ITypeLib_fnIsName_exit;
    for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){
        if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnIsName_exit;
        for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
            if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnIsName_exit;
            for(i=0;i<pFInfo->funcdesc.cParams;i++)
                if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
                    goto ITypeLib_fnIsName_exit;
        }
        for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
            if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnIsName_exit;
       
    }
    *pfName=FALSE;

ITypeLib_fnIsName_exit:
    TRACE("(%p)slow! search for %s: %s found!\n", This,
          debugstr_a(astr), *pfName?"NOT":"");
    
    HeapFree( GetProcessHeap(), 0, astr );
    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 ITypeLib_fnFindName( LPTYPELIB iface, LPOLESTR szNameBuf,
    ULONG lHashVal, ITypeInfo **ppTInfo, MEMBERID *rgMemId, UINT16 *pcFound)
{
	ICOM_THIS( TLBLibInfo, iface);
    TLBTypeInfo *pTInfo;
    TLBFuncDesc *pFInfo;
    TLBVarDesc *pVInfo;
    int i,j = 0;
    PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
    for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){
        if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnFindName_exit;
        for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
            if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnFindName_exit;
            for(i=0;i<pFInfo->funcdesc.cParams;i++)
                if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
                    goto ITypeLib_fnFindName_exit;
        }
        for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
            if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnFindName_exit;
        continue;
ITypeLib_fnFindName_exit:
        pTInfo->lpvtbl->fnAddRef((LPTYPEINFO)pTInfo);
        ppTInfo[j]=(LPTYPEINFO)pTInfo;
        j++;
    }
    TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
          This, *pcFound, debugstr_a(astr), j);

    *pcFound=j;
    
    HeapFree( GetProcessHeap(), 0, astr );
    return S_OK;
}

/* ITypeLib::ReleaseTLibAttr
 *
 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
 *
 */
static VOID WINAPI ITypeLib_fnReleaseTLibAttr( LPTYPELIB iface, TLIBATTR *pTLibAttr)
{
	ICOM_THIS( TLBLibInfo, iface);
    TRACE("freeing (%p)\n",This);
    /* nothing to do */
}

/* ITypeLib2::GetCustData
 *
 * gets the custom data
 */
static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLib * iface, REFGUID guid, 
        VARIANT *pVarVal)
{
	ICOM_THIS( TLBLibInfo, iface);
    TLBCustData *pCData;
    for(pCData=This->pCustData; pCData; pCData = pCData->next)
        if( IsEqualIID(guid, &pCData->guid)) break;
    if(TRACE_ON(typelib)){
        char xriid[50];
        WINE_StringFromCLSID((LPCLSID)guid,xriid);
        TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
    }
    if(pCData){
        VariantInit( pVarVal);
        VariantCopy( pVarVal, &pCData->data);
        return S_OK;
    }
    return E_INVALIDARG;  /* FIXME: correct? */
}

/* ITypeLib2::GetLibStatistics
 *
 * Returns statistics about a type library that are required for efficient
 * sizing of hash tables.
 *
 */
static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( ITypeLib * iface, 
        UINT *pcUniqueNames, UINT *pcchUniqueNames)
{
	ICOM_THIS( TLBLibInfo, 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( ITypeLib * iface, 
        INT index, LCID lcid, BSTR *pbstrHelpString,
        INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
{
	ICOM_THIS( TLBLibInfo, iface);
    HRESULT result;
    ITypeInfo *pTInfo;
    FIXME("(%p) index %d lcid %ld 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=TLB_DupAtoBstr(This->DocString);
        if(pdwHelpStringContext)
            *pdwHelpStringContext=This->dwHelpContext;
        if(pbstrHelpStringDll)
            *pbstrHelpStringDll=TLB_DupAtoBstr(This->HelpStringDll);
    }else {/* for a typeinfo */
        result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo);
        if(SUCCEEDED(result)){
            result=ITypeInfo2_fnGetDocumentation2(pTInfo, MEMBERID_NIL, lcid,
                pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
            ITypeInfo_Release(pTInfo);
        }
        if(!SUCCEEDED(result))
            return result;
    }
    return S_OK;
}

/* ITypeLib2::GetAllCustData
 *
 * Gets all custom data items for the library. 
 *
 */
static HRESULT WINAPI ITypeLib2_fnGetAllCustData( ITypeLib * iface,
        CUSTDATA *pCustData)
{
	ICOM_THIS( TLBLibInfo, iface);
    TLBCustData *pCData;
    int i;
    TRACE("(%p) returning %d items\n", This, This->ctCustData); 
    pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
    if(pCustData->prgCustData ){
        pCustData->cCustData=This->ctCustData;
        for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
            pCustData->prgCustData[i].guid=pCData->guid;
            VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
        }
    }else{
        ERR(" OUT OF MEMORY! \n");
        return E_OUTOFMEMORY;
    }
    return S_OK;
}


/*================== ITypeInfo(2) Methods ===================================*/

/* ITypeInfo::QueryInterface
 */
static HRESULT WINAPI ITypeInfo_fnQueryInterface( LPTYPEINFO iface, REFIID riid,
    VOID **ppvObject)
{
	ICOM_THIS( TLBTypeInfo, iface);
    if(TRACE_ON(typelib)){
        char xriid[50];
        WINE_StringFromCLSID((LPCLSID)riid,xriid);
        TRACE("(%p)->(IID: %s)\n",This,xriid);
    }
    *ppvObject=NULL;
    if(IsEqualIID(riid, &IID_IUnknown) || 
            IsEqualIID(riid,&IID_ITypeInfo)||
            IsEqualIID(riid,&IID_ITypeInfo2))
        *ppvObject = This;
    if(*ppvObject){
        ITypeInfo_AddRef(iface);
        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( LPTYPEINFO iface)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TRACE("(%p)->ref is %u\n",This, This->ref);
    (This->pTypeLib->ref)++;
    return ++(This->ref);
}

/* ITypeInfo::Release
 */
static ULONG WINAPI ITypeInfo_fnRelease( LPTYPEINFO iface)
{
	ICOM_THIS( TLBTypeInfo, iface);
    FIXME("(%p)->ref is %u:   stub\n",This, This->ref);
    (This->ref)--;
    (This->pTypeLib->ref)--;
    return S_OK;
}

/* ITypeInfo::GetTypeAttr
 *
 * Retrieves a TYPEATTR structure that contains the attributes of the type
 * description.
 *
 */
static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( LPTYPEINFO iface,
        LPTYPEATTR  *ppTypeAttr)
{
	ICOM_THIS( TLBTypeInfo, iface);
     TRACE("(%p)\n",This);
    /* FIXME: must do a copy here */
    *ppTypeAttr=&This->TypeAttr;
    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( LPTYPEINFO iface,
        ITypeComp  * *ppTComp)
{
	ICOM_THIS( TLBTypeInfo, iface);
    FIXME("(%p) stub!\n", This);
    return S_OK;
}

/* ITypeInfo::GetFuncDesc
 *
 * Retrieves the FUNCDESC structure that contains information about a
 * specified function.
 *
 */
static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( LPTYPEINFO iface, UINT index,
        LPFUNCDESC  *ppFuncDesc)
{
	ICOM_THIS( TLBTypeInfo, iface);
    int i;
    TLBFuncDesc * pFDesc; 
    TRACE("(%p) index %d\n", This, index);
    for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
        ;
    if(pFDesc){
        /* FIXME: must do a copy here */
        *ppFuncDesc=&pFDesc->funcdesc;
        return S_OK;
    }
    return E_INVALIDARG;
}

/* ITypeInfo::GetVarDesc
 *
 * Retrieves a VARDESC structure that describes the specified variable. 
 *
 */
static HRESULT WINAPI ITypeInfo_fnGetVarDesc( LPTYPEINFO iface, UINT index,
        LPVARDESC  *ppVarDesc)
{
	ICOM_THIS( TLBTypeInfo, iface);
    int i;
    TLBVarDesc * pVDesc; 
    TRACE("(%p) index %d\n", This, index);
    for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next)
        ;
    if(pVDesc){
        /* FIXME: must do a copy here */
        *ppVarDesc=&pVDesc->vardesc;
        return S_OK;
    }
    return E_INVALIDARG;
}

/* 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( LPTYPEINFO iface, MEMBERID memid,
        BSTR  *rgBstrNames, UINT cMaxNames, UINT  *pcNames)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TLBFuncDesc * pFDesc; 
    TLBVarDesc * pVDesc; 
    int i;
    TRACE("(%p) memid=0x%08lx Maxname=%d\n", This, memid,
            cMaxNames);
    for(pFDesc=This->funclist; pFDesc->funcdesc.memid != memid && pFDesc;
            pFDesc=pFDesc->next)
        ;
    if(pFDesc){
        /* function found, now return function and parameter names */
        for(i=0; i<cMaxNames && i <= pFDesc->funcdesc.cParams; i++){
            if(!i) *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
            else
                rgBstrNames[i]=TLB_DupAtoBstr(pFDesc->pParamDesc[i-1].Name);
                
        }
        *pcNames=i;
    }else{
        for(pVDesc=This->varlist; pVDesc->vardesc.memid != memid && pVDesc;
                pVDesc=pVDesc->next)
            ;
        if(pVDesc){
            *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
            *pcNames=1;
        }else{
            if(This->TypeAttr.typekind==TKIND_INTERFACE && 
                    This->TypeAttr.cImplTypes ){
                /* recursive search */
                ITypeInfo *pTInfo;
                HRESULT result;
                result=This->lpvtbl->fnGetRefTypeInfo(iface, 
                        This->impltypelist->reference, &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( LPTYPEINFO iface,
        UINT index, HREFTYPE  *pRefType)
{
	ICOM_THIS( TLBTypeInfo, iface);
    int(i);
    TLBRefType *pIref;
    TRACE("(%p) index %d\n", This, index);
    for(i=0, pIref=This->impltypelist; i<index && pIref;
            i++, pIref=pIref->next)
        ;
    if(i==index){
        *pRefType=pIref->reference;
        return S_OK;
    }
    return TYPE_E_ELEMENTNOTFOUND;
}

/* ITypeInfo::GetImplTypeFlags
 * 
 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface 
 * or base interface in a type description.
 */
static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO iface,
        UINT index, INT  *pImplTypeFlags)
{
	ICOM_THIS( TLBTypeInfo, iface);
    int(i);
    TLBRefType *pIref;
    TRACE("(%p) index %d\n", This, index);
    for(i=0, pIref=This->impltypelist; i<index && pIref; i++, pIref=pIref->next)
        ;
    if(i==index && pIref){
        *pImplTypeFlags=pIref->flags;
        return S_OK;
    }
    *pImplTypeFlags=0;
    return TYPE_E_ELEMENTNOTFOUND;
}

/* GetIDsOfNames
 * Maps between member names and member IDs, and parameter names and
 * parameter IDs.
 */
static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( LPTYPEINFO iface,
        LPOLESTR  *rgszNames, UINT cNames, MEMBERID  *pMemId)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TLBFuncDesc * pFDesc; 
    TLBVarDesc * pVDesc; 
    HRESULT ret=S_OK;
    PCHAR aszName= HEAP_strdupWtoA( GetProcessHeap(), 0, *rgszNames);
    TRACE("(%p) Name %s cNames %d\n", This, debugstr_a(aszName),
            cNames);
    for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) {
        int i, j;
        if( !strcmp(aszName, pFDesc->Name)) {
            if(cNames) *pMemId=pFDesc->funcdesc.memid;
            for(i=1; i < cNames; i++){
                PCHAR aszPar= HEAP_strdupWtoA( GetProcessHeap(), 0,
                        rgszNames[i]);
                for(j=0; j<pFDesc->funcdesc.cParams; j++)
                    if(strcmp(aszPar,pFDesc->pParamDesc[j].Name))
                            break;
                if( j<pFDesc->funcdesc.cParams)
                    pMemId[i]=j;
                else
                   ret=DISP_E_UNKNOWNNAME;
                HeapFree( GetProcessHeap(), 0, aszPar);         
            };
            HeapFree (GetProcessHeap(), 0, aszName);
            return ret;
        }
    }   
    for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
        if( !strcmp(aszName, pVDesc->Name)) {
            if(cNames) *pMemId=pVDesc->vardesc.memid;
            HeapFree (GetProcessHeap(), 0, aszName);
            return ret;
        }
    }
    /* not found, see if this is and interface with an inheritance */       
    if(This->TypeAttr.typekind==TKIND_INTERFACE && 
            This->TypeAttr.cImplTypes ){
        /* recursive search */
        ITypeInfo *pTInfo;
        ret=ITypeInfo_GetRefTypeInfo(iface, 
                This->impltypelist->reference, &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;
}

/* ITypeInfo::Invoke
 * 
 * Invokes a method, or accesses a property of an object, that implements the
 * interface described by the type description.
 */
static HRESULT WINAPI ITypeInfo_fnInvoke( LPTYPEINFO iface, VOID  *pIUnk,
        MEMBERID memid, UINT16 dwFlags, DISPPARAMS  *pDispParams,
        VARIANT  *pVarResult, EXCEPINFO  *pExcepInfo, UINT  *pArgErr)
{
	ICOM_THIS( TLBTypeInfo, iface);
    FIXME("(%p) stub!", This);
    return S_OK;
}

/* 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.
 */
static HRESULT WINAPI ITypeInfo_fnGetDocumentation( LPTYPEINFO iface,
        MEMBERID memid, BSTR  *pBstrName, BSTR  *pBstrDocString,
        DWORD  *pdwHelpContext, BSTR  *pBstrHelpFile)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TLBFuncDesc * pFDesc; 
    TLBVarDesc * pVDesc; 
    TRACE("(%p) memid %ld 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=TLB_DupAtoBstr(This->Name);
        if(pBstrDocString)
            *pBstrDocString=TLB_DupAtoBstr(This->DocString);
        if(pdwHelpContext)
            *pdwHelpContext=This->dwHelpContext;
        if(pBstrHelpFile)
            *pBstrHelpFile=TLB_DupAtoBstr(This->DocString);/* FIXME */
        return S_OK;
    }else {/* for a member */
    for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
        if(pFDesc->funcdesc.memid==memid){
            return S_OK;
        }
    for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
        if(pVDesc->vardesc.memid==memid){
            return S_OK;
        }
    }
    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( LPTYPEINFO iface, MEMBERID memid,
        INVOKEKIND invKind, BSTR  *pBstrDllName, BSTR  *pBstrName,
        WORD  *pwOrdinal)
{
	ICOM_THIS( TLBTypeInfo, iface);
    FIXME("(%p) stub!\n", This);
    return E_FAIL;
}

/* ITypeInfo::GetRefTypeInfo
 * 
 * If a type description references other type descriptions, it retrieves
 * the referenced type descriptions.
 */
static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO iface,
        HREFTYPE hRefType, ITypeInfo  * *ppTInfo)
{
	ICOM_THIS( TLBTypeInfo, iface);
    HRESULT result;
    if(HREFTYPE_INTHISFILE(hRefType)){
        ITypeLib *pTLib;
        int Index;
        result=This->lpvtbl->fnGetContainingTypeLib(iface, &pTLib, 
                &Index);
        if(SUCCEEDED(result)){
            result=ITypeLib_GetTypeInfo(pTLib,
                    HREFTYPE_INDEX(hRefType),
                    ppTInfo);
            ITypeLib_Release(pTLib );
        }
    } else{
        /* imported type lib */
        TLBRefType * pRefType;
        TLBLibInfo *pTypeLib;
        for( pRefType=This->impltypelist; pRefType &&
                pRefType->reference != hRefType; pRefType=pRefType->next)
            ;
        if(!pRefType)
            return TYPE_E_ELEMENTNOTFOUND; /* FIXME : correct? */
        pTypeLib=pRefType->pImpTLInfo->pImpTypeLib;
        if(pTypeLib) /* typelib already loaded */
            result=ITypeLib_GetTypeInfoOfGuid(
                    (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
        else{
            result=LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
                    0,0,0, /* FIXME */
                    (LPTYPELIB *)&pTypeLib);
            if(!SUCCEEDED(result)){
                BSTR libnam=TLB_DupAtoBstr(pRefType->pImpTLInfo->name);
                result=LoadTypeLib(libnam, (LPTYPELIB *)&pTypeLib);
                SysFreeString(libnam);
            }
            if(SUCCEEDED(result)){
                result=ITypeLib_GetTypeInfoOfGuid(
                        (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
                pRefType->pImpTLInfo->pImpTypeLib=pTypeLib;
           }
        }
    }
    TRACE("(%p) hreftype 0x%04lx 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( LPTYPEINFO iface,
        MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
{
	ICOM_THIS( TLBTypeInfo, iface);
    FIXME("(%p) stub!\n", This);
    return S_OK;
}

/* ITypeInfo::CreateInstance
 * 
 * Creates a new instance of a type that describes a component object class 
 * (coclass).
 */
static HRESULT WINAPI ITypeInfo_fnCreateInstance( LPTYPEINFO iface, 
        IUnknown *pUnk, REFIID riid, VOID  **ppvObj) 
{
	ICOM_THIS( TLBTypeInfo, iface);
    FIXME("(%p) stub!\n", This);
    return S_OK;
}

/* ITypeInfo::GetMops
 *
 * Retrieves marshaling information.
 */
static HRESULT WINAPI ITypeInfo_fnGetMops( LPTYPEINFO iface, MEMBERID memid,
				BSTR  *pBstrMops)
{
	ICOM_THIS( TLBTypeInfo, iface);
    FIXME("(%p) stub!\n", This);
    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( LPTYPEINFO iface,
        ITypeLib  * *ppTLib, UINT  *pIndex)
{
	ICOM_THIS( TLBTypeInfo, iface);
    *ppTLib=(LPTYPELIB )(This->pTypeLib);
    *pIndex=This->index;
    ITypeLib_AddRef(*ppTLib);
    TRACE("(%p) returns (%p) index %d!\n", This, *ppTLib, *pIndex);
    return S_OK;
}

/* ITypeInfo::ReleaseTypeAttr
 *
 * Releases a TYPEATTR previously returned by GetTypeAttr.
 *
 */
static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO iface,
        TYPEATTR* pTypeAttr)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TRACE("(%p)->(%p)\n", This, pTypeAttr);
    return S_OK;
}

/* ITypeInfo::ReleaseFuncDesc
 *
 * Releases a FUNCDESC previously returned by GetFuncDesc. *
 */
static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO iface,
        FUNCDESC *pFuncDesc)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TRACE("(%p)->(%p)\n", This, pFuncDesc);
    return S_OK;
}

/* ITypeInfo::ReleaseVarDesc
 *
 * Releases a VARDESC previously returned by GetVarDesc.
 */
static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( LPTYPEINFO iface,
        VARDESC *pVarDesc)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TRACE("(%p)->(%p)\n", This, pVarDesc);
    return S_OK;
}

/* ITypeInfo2::GetTypeKind
 *
 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo * iface,
    TYPEKIND *pTypeKind)
{
	ICOM_THIS( TLBTypeInfo, 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( ITypeInfo * iface,
    UINT *pTypeFlags)
{
	ICOM_THIS( TLBTypeInfo, iface);
    *pTypeFlags=This->TypeAttr.wTypeFlags;
    TRACE("(%p) flags 0x%04x\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( ITypeInfo * iface,
    MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TLBFuncDesc *pFuncInfo;
    int i;
    HRESULT result;
    /* FIXME: should check for invKind??? */
    for(i=0, pFuncInfo=This->funclist;pFuncInfo && 
            memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next);
    if(pFuncInfo){
        *pFuncIndex=i;
        result= S_OK;
    }else{
        *pFuncIndex=0;
        result=E_INVALIDARG;
    }
    TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This,
          memid, invKind, SUCCEEDED(result)? "SUCCES":"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( ITypeInfo * iface,
    MEMBERID memid, UINT *pVarIndex)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TLBVarDesc *pVarInfo;
    int i;
    HRESULT result;
    for(i=0, pVarInfo=This->varlist; pVarInfo && 
            memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next)
        ;
    if(pVarInfo){
        *pVarIndex=i;
        result= S_OK;
    }else{
        *pVarIndex=0;
        result=E_INVALIDARG;
    }
    TRACE("(%p) memid 0x%08lx -> %s\n", This,
          memid, SUCCEEDED(result)? "SUCCES":"FAILED");
    return result;
}

/* ITypeInfo2::GetCustData
 *
 * Gets the custom data
 */
static HRESULT WINAPI ITypeInfo2_fnGetCustData( ITypeInfo * iface,
    REFGUID guid, VARIANT *pVarVal)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TLBCustData *pCData;
    for(pCData=This->pCustData; pCData; pCData = pCData->next)
        if( IsEqualIID(guid, &pCData->guid)) break;
    if(TRACE_ON(typelib)){
        char xriid[50];
        WINE_StringFromCLSID((LPCLSID)guid,xriid);
        TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
    }
    if(pCData){
        VariantInit( pVarVal);
        VariantCopy( pVarVal, &pCData->data);
        return S_OK;
    }
    return E_INVALIDARG;  /* FIXME: correct? */
}

/* ITypeInfo2::GetFuncCustData
 *
 * Gets the custom data
 */
static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( ITypeInfo * iface,
    UINT index, REFGUID guid, VARIANT *pVarVal)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TLBCustData *pCData=NULL;
    TLBFuncDesc * pFDesc; 
    int i;
    for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
            pFDesc=pFDesc->next)
        ;
    if(pFDesc)
        for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next)
            if( IsEqualIID(guid, &pCData->guid)) break;
    if(TRACE_ON(typelib)){
        char xriid[50];
        WINE_StringFromCLSID((LPCLSID)guid,xriid);
        TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
    }
    if(pCData){
        VariantInit( pVarVal);
        VariantCopy( pVarVal, &pCData->data);
        return S_OK;
    }
    return E_INVALIDARG;  /* FIXME: correct? */
}

/* ITypeInfo2::GetParamCustData
 *
 * Gets the custom data
 */
static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( ITypeInfo * iface,
    UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal)
{   
	ICOM_THIS( TLBTypeInfo, iface);
    TLBCustData *pCData=NULL;
    TLBFuncDesc * pFDesc; 
    int i;
    for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
            pFDesc=pFDesc->next)
        ;
    if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams)
        for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData; 
                pCData = pCData->next)
            if( IsEqualIID(guid, &pCData->guid)) break;
    if(TRACE_ON(typelib)){
        char xriid[50];
        WINE_StringFromCLSID((LPCLSID)guid,xriid);
        TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
    }
    if(pCData){
        VariantInit( pVarVal);
        VariantCopy( pVarVal, &pCData->data);
        return S_OK;
    }
    return E_INVALIDARG;  /* FIXME: correct? */
}

/* ITypeInfo2::GetVarcCustData
 *
 * Gets the custom data
 */
static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( ITypeInfo * iface,
    UINT index, REFGUID guid, VARIANT *pVarVal)
{   
	ICOM_THIS( TLBTypeInfo, iface);
    TLBCustData *pCData=NULL;
    TLBVarDesc * pVDesc; 
    int i;
    for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
            pVDesc=pVDesc->next)
        ;
    if(pVDesc)
        for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next)
            if( IsEqualIID(guid, &pCData->guid)) break;
    if(TRACE_ON(typelib)){
        char xriid[50];
        WINE_StringFromCLSID((LPCLSID)guid,xriid);
        TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
    }
    if(pCData){
        VariantInit( pVarVal);
        VariantCopy( pVarVal, &pCData->data);
        return S_OK;
    }
    return E_INVALIDARG;  /* FIXME: correct? */
}

/* ITypeInfo2::GetImplcCustData
 *
 * Gets the custom data
 */
static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( ITypeInfo * iface,
    UINT index, REFGUID guid, VARIANT *pVarVal)
{   
	ICOM_THIS( TLBTypeInfo, iface);
    TLBCustData *pCData=NULL;
    TLBRefType * pRDesc; 
    int i;
    for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
            pRDesc=pRDesc->next)
        ;
    if(pRDesc)
        for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next)
            if( IsEqualIID(guid, &pCData->guid)) break;
    if(TRACE_ON(typelib)){
        char xriid[50];
        WINE_StringFromCLSID((LPCLSID)guid,xriid);
        TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
    }
    if(pCData){
        VariantInit( pVarVal);
        VariantCopy( pVarVal, &pCData->data);
        return S_OK;
    }
    return E_INVALIDARG;  /* FIXME: correct? */
}

/* 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( ITypeInfo * iface,
    MEMBERID memid, LCID lcid, BSTR *pbstrHelpString,
    INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TLBFuncDesc * pFDesc; 
    TLBVarDesc * pVDesc; 
    TRACE("(%p) memid %ld lcid(0x%lx)  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=TLB_DupAtoBstr(This->Name);
        if(pdwHelpStringContext)
            *pdwHelpStringContext=This->dwHelpStringContext;
        if(pbstrHelpStringDll)
            *pbstrHelpStringDll=
                TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
        return S_OK;
    }else {/* for a member */
    for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
        if(pFDesc->funcdesc.memid==memid){
             if(pbstrHelpString)
                *pbstrHelpString=TLB_DupAtoBstr(pFDesc->HelpString);
            if(pdwHelpStringContext)
                *pdwHelpStringContext=pFDesc->HelpStringContext;
            if(pbstrHelpStringDll)
                *pbstrHelpStringDll=
                    TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
        return S_OK;
    }
    for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
        if(pVDesc->vardesc.memid==memid){
             if(pbstrHelpString)
                *pbstrHelpString=TLB_DupAtoBstr(pVDesc->HelpString);
            if(pdwHelpStringContext)
                *pdwHelpStringContext=pVDesc->HelpStringContext;
            if(pbstrHelpStringDll)
                *pbstrHelpStringDll=
                    TLB_DupAtoBstr(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( ITypeInfo * iface,
    CUSTDATA *pCustData)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TLBCustData *pCData;
    int i;
    TRACE("(%p) returning %d items\n", This, This->ctCustData); 
    pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
    if(pCustData->prgCustData ){
        pCustData->cCustData=This->ctCustData;
        for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
            pCustData->prgCustData[i].guid=pCData->guid;
            VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
        }
    }else{
        ERR(" OUT OF MEMORY! \n");
        return E_OUTOFMEMORY;
    }
    return S_OK;
}

/* ITypeInfo2::GetAllFuncCustData
 *
 * Gets all custom data items for the specified Function
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( ITypeInfo * iface,
    UINT index, CUSTDATA *pCustData)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TLBCustData *pCData;
    TLBFuncDesc * pFDesc; 
    int i;
    TRACE("(%p) index %d\n", This, index); 
    for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
            pFDesc=pFDesc->next)
        ;
    if(pFDesc){
        pCustData->prgCustData =
            TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM));
        if(pCustData->prgCustData ){
            pCustData->cCustData=pFDesc->ctCustData;
            for(i=0, pCData=pFDesc->pCustData; pCData; i++,
                    pCData = pCData->next){
                pCustData->prgCustData[i].guid=pCData->guid;
                VariantCopy(& pCustData->prgCustData[i].varValue,
                        & pCData->data);
            }
        }else{
            ERR(" OUT OF MEMORY! \n");
            return E_OUTOFMEMORY;
        }
        return S_OK;
    }
    return TYPE_E_ELEMENTNOTFOUND;
}

/* ITypeInfo2::GetAllParamCustData
 *
 * Gets all custom data items for the Functions
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo * iface,
    UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TLBCustData *pCData=NULL;
    TLBFuncDesc * pFDesc; 
    int i;
    TRACE("(%p) index %d\n", This, indexFunc); 
    for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
            pFDesc=pFDesc->next)
        ;
    if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams){
        pCustData->prgCustData = 
            TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData *
                    sizeof(CUSTDATAITEM));
        if(pCustData->prgCustData ){
            pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData;
            for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData;
                    pCData; i++, pCData = pCData->next){
                pCustData->prgCustData[i].guid=pCData->guid;
                VariantCopy(& pCustData->prgCustData[i].varValue,
                        & pCData->data);
            }
        }else{
            ERR(" OUT OF MEMORY! \n");
            return E_OUTOFMEMORY;
        }
        return S_OK;
    }
    return TYPE_E_ELEMENTNOTFOUND;
}

/* ITypeInfo2::GetAllVarCustData
 *
 * Gets all custom data items for the specified Variable
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo * iface,
    UINT index, CUSTDATA *pCustData)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TLBCustData *pCData;
    TLBVarDesc * pVDesc; 
    int i;
    TRACE("(%p) index %d\n", This, index); 
    for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
            pVDesc=pVDesc->next)
        ;
    if(pVDesc){
        pCustData->prgCustData =
            TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM));
        if(pCustData->prgCustData ){
            pCustData->cCustData=pVDesc->ctCustData;
            for(i=0, pCData=pVDesc->pCustData; pCData; i++,
                    pCData = pCData->next){
                pCustData->prgCustData[i].guid=pCData->guid;
                VariantCopy(& pCustData->prgCustData[i].varValue,
                        & pCData->data);
            }
        }else{
            ERR(" OUT OF MEMORY! \n");
            return E_OUTOFMEMORY;
        }
        return S_OK;
    }
    return TYPE_E_ELEMENTNOTFOUND;
}

/* ITypeInfo2::GetAllImplCustData
 *
 * Gets all custom data items for the specified implementation type
 *
 */
static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo * iface,
    UINT index, CUSTDATA *pCustData)
{
	ICOM_THIS( TLBTypeInfo, iface);
    TLBCustData *pCData;
    TLBRefType * pRDesc; 
    int i;
    TRACE("(%p) index %d\n", This, index); 
    for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
            pRDesc=pRDesc->next)
        ;
    if(pRDesc){
        pCustData->prgCustData =
            TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM));
        if(pCustData->prgCustData ){
            pCustData->cCustData=pRDesc->ctCustData;
            for(i=0, pCData=pRDesc->pCustData; pCData; i++,
                    pCData = pCData->next){
                pCustData->prgCustData[i].guid=pCData->guid;
                VariantCopy(& pCustData->prgCustData[i].varValue,
                        & pCData->data);
            }
        }else{
            ERR(" OUT OF MEMORY! \n");
            return E_OUTOFMEMORY;
        }
        return S_OK;
    }
    return TYPE_E_ELEMENTNOTFOUND;
}

