Read/load type libraries. Implementation of ITypeLib, ITYpeInfo,
ITypeLib2 and ITypeInfo2 methods.
diff --git a/include/debugdefs.h b/include/debugdefs.h
index d6e0298..859302b 100644
--- a/include/debugdefs.h
+++ b/include/debugdefs.h
@@ -152,22 +152,23 @@
int dbch_treeview = 141;
int dbch_ttydrv = 142;
int dbch_tweak = 143;
-int dbch_updown = 144;
-int dbch_ver = 145;
-int dbch_virtual = 146;
-int dbch_vxd = 147;
-int dbch_wave = 148;
-int dbch_win = 149;
-int dbch_win16drv = 150;
-int dbch_win32 = 151;
-int dbch_wing = 152;
-int dbch_winsock = 153;
-int dbch_winspool = 154;
-int dbch_wnet = 155;
-int dbch_x11 = 156;
-int dbch_x11drv = 157;
+int dbch_typelib = 144;
+int dbch_updown = 145;
+int dbch_ver = 146;
+int dbch_virtual = 147;
+int dbch_vxd = 148;
+int dbch_wave = 149;
+int dbch_win = 150;
+int dbch_win16drv = 151;
+int dbch_win32 = 152;
+int dbch_wing = 153;
+int dbch_winsock = 154;
+int dbch_winspool = 155;
+int dbch_wnet = 156;
+int dbch_x11 = 157;
+int dbch_x11drv = 158;
-#define DEBUG_CHANNEL_COUNT 158
+#define DEBUG_CHANNEL_COUNT 159
char __debug_msg_enabled[DEBUG_CHANNEL_COUNT][DEBUG_CLASS_COUNT] = {
{1, 1, 0, 0},
@@ -327,6 +328,7 @@
{1, 1, 0, 0},
{1, 1, 0, 0},
{1, 1, 0, 0},
+{1, 1, 0, 0},
{1, 1, 0, 0}
};
@@ -475,6 +477,7 @@
"treeview",
"ttydrv",
"tweak",
+"typelib",
"updown",
"ver",
"virtual",
diff --git a/include/wine/obj_oleaut.h b/include/wine/obj_oleaut.h
index 619912b..5a6a6ef 100644
--- a/include/wine/obj_oleaut.h
+++ b/include/wine/obj_oleaut.h
@@ -199,6 +199,8 @@
#define DISPID_DESTRUCTOR ( -7 )
#define DISPID_COLLECT ( -8 )
+#define MEMBERID_NIL DISPID_UNKNOWN
+
typedef struct tagDISPPARAMS
{
VARIANTARG* rgvarg;
@@ -238,6 +240,15 @@
USHORT wParamFlags;
} PARAMDESC;
+#define PARAMFLAG_NONE (0x00)
+#define PARAMFLAG_FIN (0x01)
+#define PARAMFLAG_FOUT (0x02)
+#define PARAMFLAG_FLCID (0x04)
+#define PARAMFLAG_FRETVAL (0x08)
+#define PARAMFLAG_FOPT (0x10)
+#define PARAMFLAG_FHASDEFAULT (0x20)
+
+
typedef struct tagTYPEDESC
{
union {
@@ -284,7 +295,7 @@
WORD cVars;
WORD cImplTypes;
WORD cbSizeVft;
- WORD cAlignment;
+ WORD cbAlignment;
WORD wTypeFlags;
WORD wMajorVerNum;
WORD wMinorVerNum;
@@ -322,7 +333,7 @@
SCODE *lprgscode;
ELEMDESC *lprgelemdescParam;
FUNCKIND funckind;
- INVOKEKIND invKind;
+ INVOKEKIND invkind;
CALLCONV callconv;
SHORT cParams;
SHORT cParamsOpt;
@@ -498,6 +509,19 @@
* DISP_E_ARRAYISLOCKED : The variant contains an array that is locked.
*/
+
+typedef struct tagCUSTDATAITEM {
+ GUID guid;
+ VARIANTARG varValue;
+} CUSTDATAITEM, *LPCUSTDATAITEM;
+
+typedef struct tagCUSTDATA {
+ INT cCustData;
+ LPCUSTDATAITEM prgCustData; /* count cCustdata */
+} CUSTDATA, *LPCUSTDATA;
+
+
+
/*****************************************************************************
* IDispatch interface
*/
@@ -536,8 +560,9 @@
ICOM_METHOD2(HRESULT,GetFuncDesc, UINT,index, FUNCDESC**,ppFuncDesc) \
ICOM_METHOD2(HRESULT,GetVarDesc, UINT,index, VARDESC**,ppVarDesc) \
ICOM_METHOD4(HRESULT,GetNames, MEMBERID,memid, BSTR*,rgBstrNames, UINT,cMaxNames, UINT*,pcNames) \
- ICOM_METHOD2(HRESULT,GetRefTypeOfImplType, UINT,index, INT*,pImplTypeFlags) \
- ICOM_METHOD2(HRESULT,GetImplTypeFlags, UINT,index, INT*,pImplTypeFlags) \
+ ICOM_METHOD2(HRESULT,GetRefTypeOfImplType, UINT,index, HREFTYPE*,\
+ pRefType) \
+ ICOM_METHOD2(HRESULT,GetImplTypeFlags, UINT,index, INT*,pImplTypeFlags)\
ICOM_METHOD3(HRESULT,GetIDsOfNames, LPOLESTR*,rgszNames, UINT,cNames, MEMBERID*,pMemId) \
ICOM_METHOD7(HRESULT,Invoke, PVOID,pvInstance, MEMBERID,memid, WORD,wFlags, DISPPARAMS*,pDispParams, VARIANT*,pVarResult, EXCEPINFO*,pExcepInfo, UINT*,puArgErr) \
ICOM_METHOD5(HRESULT,GetDocumentation, MEMBERID,memid, BSTR*,pBstrName, BSTR*,pBstrDocString, DWORD*,pdwHelpContext, BSTR*,pBstrHelpFile) \
@@ -549,7 +574,38 @@
ICOM_METHOD2(HRESULT,GetContainingTypeLib, ITypeLib**,ppTLib, UINT*,pIndex) \
ICOM_METHOD1(HRESULT,ReleaseTypeAttr, TYPEATTR*,pTypeAttr) \
ICOM_METHOD1(HRESULT,ReleaseFuncDesc, FUNCDESC*,pFuncDesc) \
- ICOM_METHOD1(HRESULT,ReleaseVarDesc, VARDESC*,pVarDesc)
+ ICOM_METHOD1(HRESULT,ReleaseVarDesc, VARDESC*,pVarDesc)\
+\
+\
+ /* itypeinfo2 methods */\
+ ICOM_METHOD1(HRESULT, GetTypeKind, TYPEKIND*, pTypeKind) \
+ ICOM_METHOD1(HRESULT, GetTypeFlags, UINT*, pTypeFlags) \
+ ICOM_METHOD3(HRESULT, GetFuncIndexOfMemId, MEMBERID, memid, INVOKEKIND,\
+ invKind, UINT*, pFuncIndex) \
+ ICOM_METHOD2(HRESULT, GetVarIndexOfMemId, MEMBERID, memid, UINT*, \
+ pVarIndex) \
+ ICOM_METHOD2(HRESULT, GetCustData, REFGUID, guid, VARIANT*, pVarVal) \
+ ICOM_METHOD3(HRESULT, GetFuncCustData, UINT, index, REFGUID, guid,\
+ VARIANT*, pVarVal) \
+ ICOM_METHOD4(HRESULT, GetParamCustData, UINT, indexFunc, UINT,\
+ indexParam, REFGUID, guid, VARIANT*, pVarVal) \
+ ICOM_METHOD3(HRESULT, GetVarCustData, UINT, index, REFGUID, guid,\
+ VARIANT*, pVarVal) \
+ ICOM_METHOD3(HRESULT, GetImplTypeCustData, UINT, index, REFGUID, guid,\
+ VARIANT*, pVarVal) \
+ ICOM_METHOD5(HRESULT, GetDocumentation2, MEMBERID, memid, LCID, lcid,\
+ BSTR*, pbstrHelpString, INT*, pdwHelpStringContext,\
+ BSTR*, pbstrHelpStringDll) \
+ ICOM_METHOD1(HRESULT, GetAllCustData, CUSTDATA*, pCustData) \
+ ICOM_METHOD2(HRESULT, GetAllFuncCustData, UINT, index, CUSTDATA*,\
+ pCustData)\
+ ICOM_METHOD3(HRESULT, GetAllParamCustData, UINT, indexFunc, UINT,\
+ indexParam, CUSTDATA*, pCustData) \
+ ICOM_METHOD2(HRESULT, GetAllVarCustData, UINT, index, CUSTDATA*,\
+ pCustData) \
+ ICOM_METHOD2(HRESULT, GetAllImplTypeCustData, UINT, index, CUSTDATA*,\
+ pCustData)
+
#define ITypeInfo_IMETHODS \
IUnknown_IMETHODS \
ITypeInfo_METHODS
@@ -562,12 +618,12 @@
#define ITypeInfo_AddRef(p) ICOM_CALL (AddRef,p)
#define ITypeInfo_Release(p) ICOM_CALL (Release,p)
/*** ITypeInfo methods ***/
-#define ITypeInfo_GetTypeAttr(p,a,b) ICOM_CALL2(GetTypeAttr,p,a,b)
+#define ITypeInfo_GetTypeAttr(p,a) ICOM_CALL1(GetTypeAttr,p,a)
#define ITypeInfo_GetTypeComp(p,a) ICOM_CALL1(GetTypeComp,p,a)
#define ITypeInfo_GetFuncDesc(p,a,b) ICOM_CALL2(GetFuncDesc,p,a,b)
#define ITypeInfo_GetVarDesc(p,a,b) ICOM_CALL2(GetVarDesc,p,a,b)
#define ITypeInfo_GetNames(p,a,b,c,d) ICOM_CALL4(GetNames,p,a,b,c,d)
-#define ITypeInfo_GetRefTypeOfImplType(p,a,b) ICOM_CALL2(GetRefTypeOfImplType,p,a)
+#define ITypeInfo_GetRefTypeOfImplType(p,a,b) ICOM_CALL2(GetRefTypeOfImplType,p,a,b)
#define ITypeInfo_GetImplTypeFlags(p,a,b) ICOM_CALL2(GetImplTypeFlags,p,a,b)
#define ITypeInfo_GetIDsOfNames(p,a,b,c) ICOM_CALL3(GetImplTypeFlags,p,a,b,c)
#define ITypeInfo_Invoke(p,a,b,c,d,e,f,g) ICOM_CALL7(Invoke,p,a,b,c,d,e,f,g)
@@ -589,7 +645,7 @@
*/
#define ICOM_INTERFACE ITypeLib
#define ITypeLib_METHODS \
- ICOM_METHOD (HRESULT,GetTypeInfoCount) \
+ ICOM_METHOD (UINT,GetTypeInfoCount) \
ICOM_METHOD2(HRESULT,GetTypeInfo, UINT,index, ITypeInfo**,ppTInfo) \
ICOM_METHOD2(HRESULT,GetTypeInfoType, UINT,index, TYPEKIND*,pTKind) \
ICOM_METHOD2(HRESULT,GetTypeInfoOfGuid, REFGUID,guid, ITypeInfo**,ppTinfo) \
@@ -598,7 +654,16 @@
ICOM_METHOD5(HRESULT,GetDocumentation, INT,index, BSTR*,pBstrName, BSTR*,pBstrDocString, DWORD*,pdwHelpContext, BSTR*,pBstrHelpFile) \
ICOM_METHOD3(HRESULT,IsName, LPOLESTR,szNameBuf, ULONG,lHashVal, BOOL*,bfName) \
ICOM_METHOD5(HRESULT,FindName, LPOLESTR,szNameBuf, ULONG,lHashVal, ITypeInfo**,ppTInfo, MEMBERID*,rgMemId, USHORT*,pcFound) \
- ICOM_METHOD1(HRESULT,ReleaseTLibAttr, TLIBATTR*,pTLibAttr)
+ ICOM_METHOD1(VOID,ReleaseTLibAttr, TLIBATTR*,pTLibAttr)\
+\
+ ICOM_METHOD2(HRESULT,GetCustData, REFGUID,guid, VARIANT*, pVarVal)\
+ ICOM_METHOD2(HRESULT, GetLibStatistics, UINT *,pcUniqueNames, \
+ UINT*, pcchUniqueNames) \
+ ICOM_METHOD5(HRESULT, GetDocumentation2, INT, index, LCID, lcid,\
+ BSTR*, pbstrHelpString, INT*, pdwHelpStringContext,\
+ BSTR*, pbstrHelpStringDll)\
+ ICOM_METHOD1(HRESULT, GetAllCustData, CUSTDATA *, pCustData)
+
#define ITypeLib_IMETHODS \
IUnknown_IMETHODS \
ITypeLib_METHODS
diff --git a/ole/typelib.c b/ole/typelib.c
index b4bf48d..13e5549 100644
--- a/ole/typelib.c
+++ b/ole/typelib.c
@@ -2,6 +2,26 @@
* TYPELIB
*
* Copyright 1997 Marcus Meissner
+ * 1999 Rein Klazes
+ * there is much left to do here before it can be usefull for real world
+ * programs
+ * know problems:
+ * -. Only one format of typelibs is supported
+ * -. All testing until sofar 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 entirely 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 stuf ignored
+ * -. move stuf 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>
@@ -16,8 +36,13 @@
#include "wine/obj_base.h"
#include "debug.h"
#include "winversion.h"
+/* FIXME: get rid of these */
+typedef struct ITypeInfoVtbl ITypeLib_VTable, *LPTYPEINFO_VTABLE ;
+typedef struct ITypeLibVtbl *LPTYPELIB_VTABLE ;
+#include "typelib.h"
DEFAULT_DEBUG_CHANNEL(ole)
+DECLARE_DEBUG_CHANNEL(typelib)
/****************************************************************************
* QueryPathOfRegTypeLib16 [TYPELIB.14]
@@ -58,7 +83,7 @@
}
/****************************************************************************
- * QueryPathOfRegTypeLib32 [OLEAUT32.164]
+ * QueryPathOfRegTypeLib [OLEAUT32.164]
* RETURNS
* path of typelib
*/
@@ -97,7 +122,7 @@
/******************************************************************************
* LoadTypeLib [TYPELIB.3] Loads and registers a type library
* NOTES
- * Docs: OLECHAR32 FAR* szFile
+ * Docs: OLECHAR FAR* szFile
* Docs: iTypeLib FAR* FAR* pptLib
*
* RETURNS
@@ -117,53 +142,68 @@
}
/******************************************************************************
- * LoadTypeLib32 [OLEAUT32.161]
+ * LoadTypeLib [OLEAUT32.161]
* Loads and registers a type library
* NOTES
- * Docs: OLECHAR32 FAR* szFile
+ * 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 */
- void * *pptLib) /* [out] Pointer to pointer to loaded type library */
+ ITypeLib * *pptLib) /* [out] Pointer to pointer to loaded type library */
{
- FIXME(ole, "('%s',%p): stub\n",debugstr_w(szFile),pptLib);
+ LPSTR p;
+ HRESULT res;
+ TRACE(typelib, "('%s',%p)\n",debugstr_w(szFile),pptLib);
+
+ p=HEAP_strdupWtoA(GetProcessHeap(),0,szFile);
+ res= TLB_ReadTypeLib(p, pptLib);
+ //XXX need to free p ??
- if (pptLib!=0)
- *pptLib=0;
+ TRACE( typelib, " returns %ld\n",res);
- return E_FAIL;
+ return res;
}
/******************************************************************************
* LoadRegTypeLib [OLEAUT32.162]
*/
-HRESULT WINAPI LoadRegTypeLib(
- REFGUID rguid,
- unsigned short wVerMajor,
- unsigned short wVerMinor,
- LCID lcid,
- void** pptLib)
-{
- FIXME(ole, "(): stub\n");
+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(typelib,"(IID: %s) load %s (%p)\n",xriid,
+ SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);
+ }
+ return res;
+}
- if (pptLib!=0)
- *pptLib=0;
-
- return E_FAIL;
-}
/******************************************************************************
- * RegisterTypeLib32 [OLEAUT32.163]
+ * RegisterTypeLib [OLEAUT32.163]
* Adds information about a type library to the System Registry
* NOTES
* Docs: ITypeLib FAR * ptlib
- * Docs: OLECHAR32 FAR* szFullPath
- * Docs: OLECHAR32 FAR* szHelpDir
+ * Docs: OLECHAR FAR* szFullPath
+ * Docs: OLECHAR FAR* szHelpDir
*
* RETURNS
* Success: S_OK
@@ -172,11 +212,35 @@
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*/
+ OLECHAR * szHelpDir) /*[in] dir to the helpfile for the library,
+ may be NULL*/
{ FIXME(ole, "(%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(typelib,"(IID: %s): stub\n",xriid);
+ return S_OK; /* FIXME: pretend everything is OK */
+}
+
/****************************************************************************
* OABuildVersion (TYPELIB.15)
* RETURNS
@@ -196,3 +260,2280 @@
return MAKELONG(0xbd0, 0xa); /* return Win95A for now */
}
}
+
+/* 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 = {
+ 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 = {
+ 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()
+{
+ *((int *)0)=0;
+}
+static void * TLB_Alloc(unsigned size)
+{
+ void * ret;
+ if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){
+ /* FIXME */
+ ERR(ole,"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(typelib,"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 )
+{
+ DWORD bytesread=0;
+
+ if((where!=DO_NOT_SEEK &&
+ 0xffffffff== SetFilePointer((HANDLE)pcx->hFile, where, 0, FILE_BEGIN))||
+ !ReadFile((HANDLE)pcx->hFile, buffer, count, &bytesread, NULL) ||
+ count != bytesread){
+ /* FIXME */
+ ERR( typelib, "read error is 0x%lx reading %ld bytes at 0x%lx\n",
+ GetLastError(), count, where);
+ TLB_abort();
+ exit(1);
+ }
+ return bytesread;
+}
+
+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(ole,"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(¶minfo,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(¶minfo,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( typelib ,"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( typelib,"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;
+ int count;
+ char *pChr;
+ count=TLB_Read(buff, TLBBUFSZ, pcx, 0);
+ do {
+ buff[count]='\0';
+ if((pChr=strstr(buff,TLBMAGIC2))){
+ ret += pChr-buff;
+ break;
+ }
+ ret+=count;
+ count=TLB_Read(buff, TLBBUFSZ, pcx, DO_NOT_SEEK);
+ } while(count>0);
+ if(count)
+ return ret;
+/* try again for the other format */
+ ret=0;
+ count=TLB_Read(buff, TLBBUFSZ, pcx, 0);
+ do {
+ buff[count]='\0';
+ if((pChr=strstr(buff,TLBMAGIC1))){
+ ret += pChr-buff;
+ break;
+ }
+ ret+=count;
+ count=TLB_Read(buff, TLBBUFSZ, pcx, DO_NOT_SEEK);
+ } while(count>0);
+ if(count)
+ ERR(ole,"type library format not (yet) implemented\n");
+ else
+ ERR(ole,"not type library found in this file\n");
+ return -1;
+
+}
+
+int TLB_ReadTypeLib(PCHAR file, ITypeLib **ppTypeLib)
+{
+ TLBContext cx;
+ OFSTRUCT ofStruct;
+ long oStart,lPSegDir;
+ TLBLibInfo* pLibInfo=NULL;
+ TLB2Header tlbHeader;
+ TLBSegDir tlbSegDir;
+ if((cx.hFile=(HANDLE)OpenFile(file, &ofStruct, OF_READWRITE))
+ ==(HANDLE)HFILE_ERROR){
+ ERR( typelib,"cannot open %s error 0x%lx\n",file, GetLastError());
+ exit(1);
+ }
+ /* get pointer to beginning of typelib data */
+ if((oStart=TLB_FindTlb(&cx))<0){
+ if(oStart==-1)
+ ERR( typelib,"cannot locate typelib in %s\n",file);
+ else
+ ERR( typelib,"unsupported typelib format in %s\n",file);
+ exit(1);
+ }
+ cx.oStart=oStart;
+ if((pLibInfo=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
+ sizeof(TLBLibInfo)))==NULL){
+ CloseHandle(cx.hFile);
+ 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( typelib,"cannot find the table directory, ptr=0x%lx\n",lPSegDir);
+ }
+ /* 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(ole, "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)++;
+ }
+ }
+
+ CloseHandle(cx.hFile);
+ *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(typelib,"(%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){
+ (*(LPTYPELIB*)ppvObject)->lpvtbl->fnAddRef(This);
+ TRACE(typelib,"-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
+ return S_OK;
+ }
+ TRACE(typelib,"-- Interface: E_NOINTERFACE\n");
+ return E_NOINTERFACE;
+}
+
+/* ITypeLib::AddRef
+ */
+static ULONG WINAPI ITypeLib_fnAddRef( LPTYPELIB iface)
+{
+ ICOM_THIS( TLBLibInfo, iface);
+ TRACE(typelib,"(%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(typelib,"(%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(typelib,"(%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(typelib,"(%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(typelib,"-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
+ return S_OK;
+ }
+ TRACE(typelib,"-- 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(typelib,"(%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(typelib,"-- found Type (%p)->%d\n",pTKind,*pTKind);
+ return S_OK;
+ }
+ TRACE(typelib,"-- 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(typelib,"(%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(typelib,"-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
+ return S_OK;
+ }
+ TRACE(typelib,"-- 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( typelib,"(%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(typelib,"(%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( typelib, "(%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( typelib,"(%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( typelib,"(%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( typelib,"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(typelib,"(%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( typelib,"(%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( typelib,"(%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( typelib,"(%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( typelib," 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(typelib,"(%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){
+ (*(LPTYPEINFO*)ppvObject)->lpvtbl->fnAddRef(iface);
+ TRACE(typelib,"-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
+ return S_OK;
+ }
+ TRACE(typelib,"-- Interface: E_NOINTERFACE\n");
+ return E_NOINTERFACE;
+}
+
+/* ITypeInfo::AddRef
+ */
+static ULONG WINAPI ITypeInfo_fnAddRef( LPTYPEINFO iface)
+{
+ ICOM_THIS( TLBTypeInfo, iface);
+ TRACE(typelib,"(%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(typelib,"(%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( typelib,"(%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( typelib,"(%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( typelib,"(%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( typelib,"(%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( typelib,"(%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=pTInfo->lpvtbl->fnGetNames(pTInfo, memid, rgBstrNames,
+ cMaxNames, pcNames);
+ pTInfo->lpvtbl->fnRelease(pTInfo);
+ return result;
+ }
+ WARN( typelib,"Could not search inherited interface!\n");
+ } else
+ WARN( typelib,"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( typelib,"(%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( typelib,"(%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( typelib,"(%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=This->lpvtbl->fnGetRefTypeInfo(iface,
+ This->impltypelist->reference, &pTInfo);
+ if(SUCCEEDED(ret)){
+ ret=pTInfo->lpvtbl->fnGetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
+ pTInfo->lpvtbl->fnRelease(pTInfo);
+ return ret;
+ }
+ WARN( typelib,"Could not search inherited interface!\n");
+ } else
+ WARN( typelib,"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( typelib,"(%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( typelib, "(%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( typelib,"(%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=pTLib->lpvtbl->fnGetTypeInfo(pTLib,
+ HREFTYPE_INDEX(hRefType),
+ ppTInfo);
+ pTLib->lpvtbl->fnRelease(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=pTypeLib->lpvtbl->fnGetTypeInfoOfGuid(
+ (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=pTypeLib->lpvtbl->fnGetTypeInfoOfGuid(
+ (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
+ pRefType->pImpTLInfo->pImpTypeLib=pTypeLib;
+ }
+ }
+ }
+ TRACE( typelib,"(%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( typelib,"(%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( typelib,"(%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( typelib,"(%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;
+ (*ppTLib)->lpvtbl->fnAddRef(*ppTLib);
+ TRACE( typelib,"(%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( typelib,"(%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( typelib,"(%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( typelib,"(%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( typelib,"(%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( typelib,"(%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( typelib,"(%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( typelib,"(%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(typelib,"(%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(typelib,"(%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(typelib,"(%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(typelib,"(%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(typelib,"(%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( typelib, "(%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( typelib,"(%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( typelib," 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( typelib,"(%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( typelib," 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( typelib,"(%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( typelib," 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( typelib,"(%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( typelib," 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( typelib,"(%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( typelib," OUT OF MEMORY! \n");
+ return E_OUTOFMEMORY;
+ }
+ return S_OK;
+ }
+ return TYPE_E_ELEMENTNOTFOUND;
+}
+
diff --git a/ole/typelib.h b/ole/typelib.h
new file mode 100644
index 0000000..64d7aa0
--- /dev/null
+++ b/ole/typelib.h
@@ -0,0 +1,358 @@
+/*
+ * typelib.h internal wine data structures
+ * used to decode typelib's
+ *
+ * Copyright 1999 Rein KLazes
+ *
+ */
+#ifndef _WINE_TYPELIB_H
+#define _WINE_TYPELIB_H
+
+
+#include "ole2.h"
+#include "oleauto.h"
+#include "oaidl.h"
+
+
+#define TLBMAGIC2 "MSFT"
+#define TLBMAGIC1 "SLTG"
+#define HELPDLLFLAG (0x0100)
+#define DO_NOT_SEEK (-1)
+
+#define HREFTYPE_INTHISFILE(href) (!((href) & 3))
+#define HREFTYPE_INDEX(href) ((href) /sizeof(TLBTypeInfoBase))
+
+typedef struct tagTLBCustData {
+ GUID guid;
+ VARIANT data;
+ struct tagTLBCustData* next;
+} TLBCustData;
+
+/* internal Parameter data */
+typedef struct tagTLBParDesc{
+ PCHAR Name;
+ int ctCustData;
+ TLBCustData * pCustData; /* linked list to cust data; */
+} TLBParDesc;
+
+
+/* internal Function data */
+typedef struct tagTLBFuncDesc{
+ FUNCDESC funcdesc; /* lots of info on the function and its attributes. */
+ PCHAR Name; /* the name of this function */
+ TLBParDesc *pParamDesc; /* array with name and custom data */
+ int helpcontext;
+ int HelpStringContext;
+ PCHAR HelpString;
+ PCHAR Entry; /* if its Hiword==0, it numeric; -1 is not present*/
+ int ctCustData;
+ TLBCustData * pCustData; /* linked list to cust data; */
+ struct tagTLBFuncDesc * next;
+} TLBFuncDesc;
+
+/* internal Variable data */
+typedef struct tagTLBVarDesc{
+ VARDESC vardesc; /* lots of info on the variable and its attributes. */
+ PCHAR Name; /* the name of this variable */
+ int HelpContext;
+ int HelpStringContext; /* fixme: where? */
+ PCHAR HelpString;
+ int ctCustData;
+ TLBCustData * pCustData;/* linked list to cust data; */
+ struct tagTLBVarDesc * next;
+} TLBVarDesc;
+
+/* data for refernced types in a coclass, or an inherited interface */
+typedef struct tagTLBRefType {
+ GUID guid; /* guid of the referenced type */
+ /* (important if its a imported type) */
+ HREFTYPE reference;
+ int flags;
+ int ctCustData;
+ TLBCustData * pCustData;/* linked list to custom data; */
+ struct tagTLBImpLib *pImpTLInfo;
+ struct tagTLBRefType * next;
+ }TLBRefType;
+
+/* internal TypeInfo data */
+typedef struct tagTYPEINFO {
+ LPTYPEINFO_VTABLE lpvtbl;
+ UINT ref;
+ TYPEATTR TypeAttr ; /* _lots_ of type information. */
+ struct tagTYPELIB * pTypeLib; /* back pointer to typelib */
+ int index; /* index in this typelib; */
+ /* type libs seem to store the doc strings in ascii
+ * so why should we do it in unicode?
+ */
+ PCHAR Name;
+ PCHAR DocString;
+ unsigned long dwHelpContext;
+ unsigned long dwHelpStringContext;
+
+/* functions */
+ TLBFuncDesc * funclist; /* linked list with function descriptions */
+/* variables */
+ TLBVarDesc * varlist; /* linked list with variable descriptions */
+/* Implemented Interfaces */
+ TLBRefType * impltypelist;
+ int ctCustData;
+ TLBCustData * pCustData; /* linked list to cust data; */
+ struct tagTYPEINFO * next;
+} TLBTypeInfo;
+
+/* data structure for import typelibs */
+typedef struct tagTLBImpLib {
+ int offset; /* offset in the file */
+ GUID guid; /* libid */
+ PCHAR name; /* name; */
+ struct tagTYPELIB *pImpTypeLib; /* pointer to loaded typelib */
+ struct tagTLBImpLib * next;
+ } TLBImpLib;
+
+/* internal TypeLib data */
+typedef struct tagTYPELIB {
+ LPTYPELIB_VTABLE lpvtbl;
+ UINT ref;
+ TLIBATTR LibAttr; /* guid,lcid,syskind,version,flags */
+ /* type libs seem to store the doc strings in ascii
+ * so why should we do it in unicode?
+ */
+ PCHAR Name;
+ PCHAR DocString;
+ PCHAR HelpFile;
+ PCHAR HelpStringDll;
+ unsigned long dwHelpContext;
+ int TypeInfoCount; /* nr of typeinfo's in librarry */
+ TLBTypeInfo *pTypeInfo; /* linked list of type info data */
+ int ctCustData; /* number of items in cust data list */
+ TLBCustData * pCustData; /* linked list to cust data; */
+ TLBImpLib * pImpLibs; /* linked list to all imported typelibs */
+ TYPEDESC * pTypeDesc; /* array of TypeDescriptions found in the libary */
+} TLBLibInfo;
+
+/*-------------------------FILE STRUCTURES-----------------------------------*/
+
+
+/*
+ * structure of the typelib type2 header
+ * it is at the beginning of a type lib file
+ *
+ */
+typedef struct tagTLB2Header {
+/*0x00*/INT magic1; /* 0x5446534D "MSFT" */
+ INT magic2; /* 0x00010002 version nr? */
+ INT posguid; /* position of libid in guid table */
+ /* (should be, else -1) */
+ INT lcid; /* locale id */
+/*0x10*/INT lcid2;
+ INT varflags; /* (largely) unknown flags ,seems to be always 41 */
+ /* becomes 0x51 with a helpfile defined */
+ /* if help dll defined its 0x151 */
+ /* update : the lower nibble is syskind */
+ INT version; /* set with SetVersion() */
+ INT flags; /* set with SetFlags() */
+/*0x20*/INT nrtypeinfos; /* number of typeinfo's (till so far) */
+ INT helpstring; /* position of help string in stringtable */
+ INT helpstringcontext;
+ INT helpcontext;
+/*0x30*/INT nametablecount; /* number of names in name table */
+ INT nametablechars; /* nr of characters in name table */
+ INT NameOffset; /* offset of name in name table */
+ INT helpfile; /* position of helpfile in stringtable */
+/*0x40*/INT CustomDataOffset; /* if -1 no custom data, else it is offset */
+ /* in customer data/guid offset table */
+ INT res44; /* unknown always: 0x20 */
+ INT res48; /* unknown always: 0x80 */
+ INT dispatchpos; /* gets a value (1+n*0x0c) with Idispatch interfaces */
+/*0x50*/INT res50; /* is zero becomes one when an interface is derived */
+} TLB2Header;
+
+/* segments in the type lib file have a structure like this: */
+typedef struct _tptag {
+ INT offset; /* absolute offset in file */
+ INT length; /* length of segment */
+ INT res08; /* unknown always -1 */
+ INT res0c; /* unknown always 0x0f in the header */
+ /* 0x03 in the typeinfo_data */
+} pSeg;
+
+/* layout of the main segment directory */
+typedef struct tagTLBSegDir {
+/*1*/pSeg pTypeInfoTab; /* each type info get an entry of 0x64 bytes */
+ /* (25 ints) */
+/*2*/pSeg pImpInfo; /* table with info for imported types */
+/*3*/pSeg pImpFiles; /* import libaries */
+/*4*/pSeg pRefTab; /* References table */
+/*5*/pSeg pLibtab; /* always exists, alway same size (0x80) */
+ /* hash table w offsets to guid????? */
+/*6*/pSeg pGuidTab; /* all guids are stored here together with */
+ /* offset in some table???? */
+/*7*/pSeg res07; /* always created, alway same size (0x200) */
+ /* purpose largely unknown */
+/*8*/pSeg pNametab; /* name tables */
+/*9*/pSeg pStringtab; /*string table */
+/*A*/pSeg pTypdescTab; /* table with type descriptors */
+/*B*/pSeg pArrayDescriptions;
+/*C*/pSeg pCustData; /* data table, used for custom data and default */
+ /* parameter values */
+/*D*/pSeg pCDGuids; /* table with offsets for the guids and into the customer data table */
+/*E*/pSeg res0e; /* unknown */
+/*F*/pSeg res0f; /* unknown */
+} TLBSegDir;
+
+
+/* base type info data */
+typedef struct tagTLBTypeInfoBase {
+/*000*/ INT typekind; /* it is the TKIND_xxx */
+ /* some byte alignment stuf */
+ INT memoffset; /* points past the file, if no elements */
+ INT res2; /* zero if no element, N*0x40 */
+ INT res3; /* -1 if no lement, (N-1)*0x38 */
+/*010*/ INT res4; /* always? 3 */
+ INT res5; /* always? zero */
+ INT cElement; /* counts elements, HI=cVars, LO=cFuncs */
+ INT res7; /* always? zero */
+/*020*/ INT res8; /* always? zero */
+ INT res9; /* always? zero */
+ INT resA; /* always? zero */
+ INT posguid; /* position in guid table */
+/*030*/ INT flags; /* Typeflags */
+ INT NameOffset; /* offset in name table */
+ INT version; /* element version */
+ INT docstringoffs; /* offset of docstring in string tab */
+/*040*/ INT helpstringcontext; /* */
+ INT helpcontext; /* */
+ INT oCustData; /* offset in customer data table */
+ INT16 cImplTypes; /* nr of implemented interfaces */
+ INT16 cbSizeVft; /* virtual table size, not including inherits */
+/*050*/ INT size; /* size in bytes, at least for structures */
+ /* fixme: name of this field */
+ INT datatype1; /* position in type description table */
+ /* or in base intefaces */
+ /* if coclass: offset in reftable */
+ /* if interface: reference to inherited if */
+ INT datatype2; /* if 0x8000, entry above is valid */
+ /* actually dunno */
+ /* else it is zero? */
+ INT res18; /* always? 0 */
+/*060*/ INT res19; /* always? -1 */
+ } TLBTypeInfoBase;
+
+/* layout of an entry with information on imported types */
+typedef struct tagTLBImpInfo {
+ INT res0; /* unknown */
+ INT oImpFile; /* offset inthe Import File table */
+ INT oGuid; /* offset in Guid table */
+ } TLBImpInfo;
+
+/* function description data */
+typedef struct {
+/* INT recsize; record size including some xtra stuff */
+ INT DataType; /* data type of the memeber, eg return of function */
+ INT Flags; /* something to do with attribute flags (LOWORD) */
+ INT16 VtableOffset; /* offset in vtable */
+ INT16 res3; /* some offset into dunno what */
+ INT FKCCIC; /* bit string with the following */
+ /* meaning (bit 0 is the msb): */
+ /* bit 2 indicates that oEntry is numeric */
+ /* bit 3 that parameter has default values */
+ /* calling convention (bits 4-7 ) */
+ /* bit 8 indicates that custom data is present */
+ /* Invokation kind (bits 9-12 ) */
+ /* function kind (eg virtual), bits 13-15 */
+ INT16 nrargs; /* number of arguments (including optional ????) */
+ INT16 nroargs; /* nr of optional arguments */
+ /* optional attribute fields, the number of them is variable */
+ INT OptAttr[1];
+/*
+0* INT helpcontext;
+1* INT oHelpString;
+2* INT oEntry; // either offset in string table or numeric as it is //
+3* INT res9; // unknown (-1) //
+4* INT resA; // unknown (-1) //
+5* INT HelpStringContext;
+ // these are controlled by a bit set in the FKCCIC field //
+6* INT oCustData; // custom data for function //
+7* INT oArgCustData[1]; // custom data per argument //
+*/
+} TLBFuncRecord;
+
+/* after this may follow an array with default value pointers if the
+ * appropriate bit in the FKCCIC field has been set:
+ * INT oDefautlValue[nrargs];
+ */
+
+ /* Parameter info one per argument*/
+typedef struct {
+ INT DataType;
+ INT oName;
+ INT Flags;
+ } TLBParameterInfo;
+
+/* Variable description data */
+typedef struct {
+/* INT recsize; // record size including some xtra stuff */
+ INT DataType; /* data type of the variable */
+ INT Flags; /* VarFlags (LOWORD) */
+ INT16 VarKind; /* VarKind */
+ INT16 res3; /* some offset into dunno what */
+ INT OffsValue; /* value of the variable or the offset */
+ /* in the data structure */
+ /* optional attribute fields, the number of them is variable */
+ /* controlled by record length */
+ INT HelpContext;
+ INT oHelpString;
+ INT res9; /* unknown (-1) */
+ INT oCustData; /* custom data for variable */
+ INT HelpStringContext;
+
+} TLBVarRecord;
+
+/* Structure of the reference data */
+typedef struct {
+ INT reftype; /* either offset in type info table, then its */
+ /* a multiple of 64 */
+ /* or offset in the external reference table */
+ /* with an offset of 1 */
+ INT flags;
+ INT oCustData; /* custom data */
+ INT onext; /* next offset, -1 if last */
+} TLBRefRecord;
+
+/* this is how a guid is stored */
+typedef struct {
+ GUID guid;
+ INT unk10; /* differntiate with libid, classid etc? */
+ /* its -2 for a libary */
+ /* it's 0 for an interface */
+ INT unk14; /* always? -1 */
+} TLBGuidEntry;
+/* some data preceding entries in the name table */
+typedef struct {
+ INT unk00; /* sometimes -1 (lib, parameter) ,
+ sometimes 0 (interface, func) */
+ INT unk10; /* sometimes -1 (lib) , sometimes 0 (interface, func),
+ sometime 0x10 (par) */
+ INT namelen; /* only lower 8 bits are valid */
+} TLBNameIntro;
+/* the custom data table directory has enties like this */
+typedef struct {
+ INT GuidOffset;
+ INT DataOffset;
+ INT next; /* next offset in the table, -1 if its the last */
+} TLBCDGuid;
+
+
+
+/*---------------------------END--------------------------------------------*/
+
+typedef struct tagTLBContext {
+ HANDLE hFile; /* open typelib file */
+ long oStart; /* start of TLB in file */
+ TLBSegDir * pTblDir;
+ TLBLibInfo* pLibInfo;
+} TLBContext;
+
+
+#endif
+
diff --git a/relay32/oleaut32.spec b/relay32/oleaut32.spec
index 7b5de51..ffc1e36 100644
--- a/relay32/oleaut32.spec
+++ b/relay32/oleaut32.spec
@@ -143,7 +143,7 @@
183 stub LoadTypeLibEx
184 stub SystemTimeToVariantTime
185 stub VariantTimeToSystemTime
-186 stub UnRegisterTypeLib
+186 stdcall UnRegisterTypeLib (ptr long long long long) UnRegisterTypeLib
190 stub VarDecFromUI1
191 stub VarDecFromI2
192 stub VarDecFromI4