diff --git a/reactos/dll/win32/oleaut32/CMakeLists.txt b/reactos/dll/win32/oleaut32/CMakeLists.txt index fa836d0ac99..06cb3aaca97 100644 --- a/reactos/dll/win32/oleaut32/CMakeLists.txt +++ b/reactos/dll/win32/oleaut32/CMakeLists.txt @@ -29,7 +29,6 @@ list(APPEND SOURCE safearray.c tmarshal.c typelib.c - typelib2.c usrmarshal.c varformat.c variant.c diff --git a/reactos/dll/win32/oleaut32/hash.c b/reactos/dll/win32/oleaut32/hash.c index bc07483b8cd..613f4afb16b 100644 --- a/reactos/dll/win32/oleaut32/hash.c +++ b/reactos/dll/win32/oleaut32/hash.c @@ -544,13 +544,13 @@ ULONG WINAPI LHashValOfNameSysA( SYSKIND skind, LCID lcid, LPCSTR lpStr) case LANG_SWEDISH: case LANG_SYRIAC: case LANG_TAMIL: case LANG_TATAR: case LANG_TELUGU: case LANG_THAI: case LANG_UKRAINIAN: case LANG_URDU: case LANG_UZBEK: - case LANG_VIETNAMESE: case LANG_GAELIC: case LANG_MALTESE: + case LANG_VIETNAMESE: case LANG_SCOTTISH_GAELIC: case LANG_MALTESE: case LANG_MAORI: case LANG_ROMANSH: case LANG_IRISH: case LANG_SAMI: case LANG_UPPER_SORBIAN: case LANG_SUTU: case LANG_TSONGA: case LANG_TSWANA: case LANG_VENDA: case LANG_XHOSA: case LANG_ZULU: case LANG_ESPERANTO: case LANG_WALON: case LANG_CORNISH: case LANG_WELSH: - case LANG_BRETON: + case LANG_BRETON: case LANG_MANX_GAELIC: nOffset = 16; pnLookup = Lookup_16; break; diff --git a/reactos/dll/win32/oleaut32/oleaut.c b/reactos/dll/win32/oleaut32/oleaut.c index 2a61c016141..7a6b94a792d 100644 --- a/reactos/dll/win32/oleaut32/oleaut.c +++ b/reactos/dll/win32/oleaut32/oleaut.c @@ -742,7 +742,6 @@ extern HRESULT WINAPI OLEAUTPS_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DEC extern BOOL WINAPI OLEAUTPS_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN; extern HRESULT WINAPI OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN; extern HRESULT WINAPI OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN; -extern GUID const CLSID_PSFactoryBuffer DECLSPEC_HIDDEN; extern void _get_STDFONT_CF(LPVOID *); extern void _get_STDPIC_CF(LPVOID *); diff --git a/reactos/dll/win32/oleaut32/typelib.c b/reactos/dll/win32/oleaut32/typelib.c index 5c81263d86e..f2b71c25695 100644 --- a/reactos/dll/win32/oleaut32/typelib.c +++ b/reactos/dll/win32/oleaut32/typelib.c @@ -5,7 +5,9 @@ * 1999 Rein Klazes * 2000 Francois Jacques * 2001 Huw D M Davies for CodeWeavers + * 2004 Alastair Bridgewater * 2005 Robert Shearman, for CodeWeavers + * 2013 Andrew Eikum for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -67,6 +69,7 @@ //#include "winnls.h" #include #include +#include #include #include @@ -79,6 +82,67 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); WINE_DECLARE_DEBUG_CHANNEL(typelib); +#ifdef __REACTOS__ +/* FIXME: Vista+ */ +#define STATUS_SUCCESS ((NTSTATUS)0x00000000) +static BOOL WINAPI GetFileInformationByHandleEx( HANDLE handle, FILE_INFO_BY_HANDLE_CLASS class, + LPVOID info, DWORD size ) +{ + NTSTATUS status; + IO_STATUS_BLOCK io; + + switch (class) + { + case FileBasicInfo: + case FileStandardInfo: + case FileRenameInfo: + case FileDispositionInfo: + case FileAllocationInfo: + case FileEndOfFileInfo: + case FileStreamInfo: + case FileCompressionInfo: + case FileAttributeTagInfo: + case FileIoPriorityHintInfo: + case FileRemoteProtocolInfo: + case FileFullDirectoryInfo: + case FileFullDirectoryRestartInfo: + case FileStorageInfo: + case FileAlignmentInfo: + case FileIdInfo: + case FileIdExtdDirectoryInfo: + case FileIdExtdDirectoryRestartInfo: + FIXME( "%p, %u, %p, %u\n", handle, class, info, size ); + SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); + return FALSE; + + case FileNameInfo: + status = NtQueryInformationFile( handle, &io, info, size, FileNameInformation ); + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError( status ) ); + return FALSE; + } + return TRUE; + + case FileIdBothDirectoryRestartInfo: + case FileIdBothDirectoryInfo: + status = NtQueryDirectoryFile( handle, NULL, NULL, NULL, &io, info, size, + FileIdBothDirectoryInformation, FALSE, NULL, + (class == FileIdBothDirectoryRestartInfo) ); + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError( status ) ); + return FALSE; + } + return TRUE; + + default: + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } +} +#endif + typedef struct { WORD offset; @@ -101,6 +165,7 @@ typedef struct static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt); static HRESULT TLB_AllocAndInitVarDesc(const VARDESC *src, VARDESC **dest_ptr); +static void TLB_FreeVarDesc(VARDESC*); /**************************************************************************** * FromLExxx @@ -547,10 +612,8 @@ HRESULT WINAPI RegisterTypeLib( if (FAILED(ITypeLib_GetLibAttr(ptlib, &attr))) return E_FAIL; -#ifdef _WIN64 - if (attr->syskind != SYS_WIN64) return TYPE_E_BADMODULEKIND; -#else - if (attr->syskind != SYS_WIN32 && attr->syskind != SYS_WIN16) return TYPE_E_BADMODULEKIND; +#ifndef _WIN64 + if (attr->syskind == SYS_WIN64) return TYPE_E_BADMODULEKIND; #endif get_typelib_key( &attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, keyName ); @@ -956,9 +1019,16 @@ HRESULT WINAPI UnRegisterTypeLibForUser( /*======================= ITypeLib implementation =======================*/ +typedef struct tagTLBGuid { + GUID guid; + INT hreftype; + UINT offset; + struct list entry; +} TLBGuid; + typedef struct tagTLBCustData { - GUID guid; + TLBGuid *guid; VARIANT data; struct list entry; } TLBCustData; @@ -970,7 +1040,7 @@ typedef struct tagTLBImpLib offset in nametable (SLTG) just used to identify library while reading data from file */ - GUID guid; /* libid */ + TLBGuid *guid; /* libid */ BSTR name; /* name */ LCID lcid; /* lcid of imported typelib */ @@ -983,22 +1053,39 @@ typedef struct tagTLBImpLib struct list entry; } TLBImpLib; +typedef struct tagTLBString { + BSTR str; + UINT offset; + struct list entry; +} TLBString; + /* internal ITypeLib data */ typedef struct tagITypeLibImpl { ITypeLib2 ITypeLib2_iface; - const ITypeCompVtbl *lpVtblTypeComp; + ITypeComp ITypeComp_iface; + ICreateTypeLib2 ICreateTypeLib2_iface; LONG ref; - TLIBATTR LibAttr; /* guid,lcid,syskind,version,flags */ + TLBGuid *guid; LCID lcid; + SYSKIND syskind; + int ptr_size; + WORD ver_major; + WORD ver_minor; + WORD libflags; + LCID set_lcid; /* strings can be stored in tlb as multibyte strings BUT they are *always* * exported to the application as a UNICODE string. */ - BSTR Name; - BSTR DocString; - BSTR HelpFile; - BSTR HelpStringDll; + struct list string_list; + struct list name_list; + struct list guid_list; + + const TLBString *Name; + const TLBString *DocString; + const TLBString *HelpFile; + const TLBString *HelpStringDll; DWORD dwHelpContext; int TypeInfoCount; /* nr of typeinfo's in librarry */ struct tagITypeInfoImpl **typeinfos; @@ -1020,10 +1107,26 @@ typedef struct tagITypeLibImpl static const ITypeLib2Vtbl tlbvt; static const ITypeCompVtbl tlbtcvt; +static const ICreateTypeLib2Vtbl CreateTypeLib2Vtbl; + +static inline ITypeLibImpl *impl_from_ITypeLib2(ITypeLib2 *iface) +{ + return CONTAINING_RECORD(iface, ITypeLibImpl, ITypeLib2_iface); +} + +static inline ITypeLibImpl *impl_from_ITypeLib(ITypeLib *iface) +{ + return impl_from_ITypeLib2((ITypeLib2*)iface); +} static inline ITypeLibImpl *impl_from_ITypeComp( ITypeComp *iface ) { - return (ITypeLibImpl *)((char*)iface - FIELD_OFFSET(ITypeLibImpl, lpVtblTypeComp)); + return CONTAINING_RECORD(iface, ITypeLibImpl, ITypeComp_iface); +} + +static inline ITypeLibImpl *impl_from_ICreateTypeLib2( ICreateTypeLib2 *iface ) +{ + return CONTAINING_RECORD(iface, ITypeLibImpl, ICreateTypeLib2_iface); } /* ITypeLib methods */ @@ -1039,7 +1142,8 @@ typedef struct tagTLBRefType it the format is SLTG. -2 indicates to use guid */ - GUID guid; /* guid of the referenced type */ + TYPEKIND tkind; + TLBGuid *guid; /* guid of the referenced type */ /* if index == TLB_REF_USE_GUID */ HREFTYPE reference; /* The href of this ref */ @@ -1058,7 +1162,7 @@ typedef struct tagTLBRefType /* internal Parameter data */ typedef struct tagTLBParDesc { - BSTR Name; + const TLBString *Name; struct list custdata_list; } TLBParDesc; @@ -1066,23 +1170,24 @@ typedef struct tagTLBParDesc typedef struct tagTLBFuncDesc { FUNCDESC funcdesc; /* lots of info on the function and its attributes. */ - BSTR Name; /* the name of this function */ + const TLBString *Name; /* the name of this function */ TLBParDesc *pParamDesc; /* array with param names and custom data */ int helpcontext; int HelpStringContext; - BSTR HelpString; - BSTR Entry; /* if IS_INTRESOURCE true, it's numeric; if -1 it isn't present */ + const TLBString *HelpString; + const TLBString *Entry; /* if IS_INTRESOURCE true, it's numeric; if -1 it isn't present */ struct list custdata_list; } TLBFuncDesc; /* internal Variable data */ typedef struct tagTLBVarDesc { - VARDESC vardesc; /* lots of info on the variable and its attributes. */ - BSTR Name; /* the name of this variable */ + VARDESC vardesc; /* lots of info on the variable and its attributes. */ + VARDESC *vardesc_create; /* additional data needed for storing VARDESC */ + const TLBString *Name; /* the name of this variable */ int HelpContext; int HelpStringContext; - BSTR HelpString; + const TLBString *HelpString; struct list custdata_list; } TLBVarDesc; @@ -1097,20 +1202,41 @@ typedef struct tagTLBImplType /* internal TypeInfo data */ typedef struct tagITypeInfoImpl { - const ITypeInfo2Vtbl *lpVtbl; - const ITypeCompVtbl *lpVtblTypeComp; + ITypeInfo2 ITypeInfo2_iface; + ITypeComp ITypeComp_iface; + ICreateTypeInfo2 ICreateTypeInfo2_iface; LONG ref; BOOL not_attached_to_typelib; - TYPEATTR TypeAttr ; /* _lots_ of type information. */ + BOOL needs_layout; + + TLBGuid *guid; + LCID lcid; + MEMBERID memidConstructor; + MEMBERID memidDestructor; + LPOLESTR lpstrSchema; + ULONG cbSizeInstance; + TYPEKIND typekind; + WORD cFuncs; + WORD cVars; + WORD cImplTypes; + WORD cbSizeVft; + WORD cbAlignment; + WORD wTypeFlags; + WORD wMajorVerNum; + WORD wMinorVerNum; + TYPEDESC *tdescAlias; + IDLDESC idldescType; + ITypeLibImpl * pTypeLib; /* back pointer to typelib */ int index; /* index in this typelib; */ HREFTYPE hreftype; /* hreftype for app object binding */ /* type libs seem to store the doc strings in ascii * so why should we do it in unicode? */ - BSTR Name; - BSTR DocString; - BSTR DllName; + const TLBString *Name; + const TLBString *DocString; + const TLBString *DllName; + const TLBString *Schema; DWORD dwHelpContext; DWORD dwHelpStringContext; @@ -1123,16 +1249,33 @@ typedef struct tagITypeInfoImpl /* Implemented Interfaces */ TLBImplType *impltypes; + struct list *pcustdata_list; struct list custdata_list; } ITypeInfoImpl; static inline ITypeInfoImpl *info_impl_from_ITypeComp( ITypeComp *iface ) { - return (ITypeInfoImpl *)((char*)iface - FIELD_OFFSET(ITypeInfoImpl, lpVtblTypeComp)); + return CONTAINING_RECORD(iface, ITypeInfoImpl, ITypeComp_iface); +} + +static inline ITypeInfoImpl *impl_from_ITypeInfo2( ITypeInfo2 *iface ) +{ + return CONTAINING_RECORD(iface, ITypeInfoImpl, ITypeInfo2_iface); +} + +static inline ITypeInfoImpl *impl_from_ITypeInfo( ITypeInfo *iface ) +{ + return impl_from_ITypeInfo2((ITypeInfo2*)iface); +} + +static inline ITypeInfoImpl *info_impl_from_ICreateTypeInfo2( ICreateTypeInfo2 *iface ) +{ + return CONTAINING_RECORD(iface, ITypeInfoImpl, ICreateTypeInfo2_iface); } static const ITypeInfo2Vtbl tinfvt; static const ITypeCompVtbl tcompvt; +static const ICreateTypeInfo2Vtbl CreateTypeInfo2Vtbl; static ITypeInfoImpl* ITypeInfoImpl_Constructor(void); static void ITypeInfoImpl_Destroy(ITypeInfoImpl *This); @@ -1148,7 +1291,41 @@ typedef struct tagTLBContext } TLBContext; -static void MSFT_DoRefType(TLBContext *pcx, ITypeLibImpl *pTL, int offset); +static inline BSTR TLB_get_bstr(const TLBString *str) +{ + return str != NULL ? str->str : NULL; +} + +static inline int TLB_str_memcmp(void *left, const TLBString *str, DWORD len) +{ + if(!str) + return 1; + return memcmp(left, str->str, len); +} + +static inline const GUID *TLB_get_guidref(const TLBGuid *guid) +{ + return guid != NULL ? &guid->guid : NULL; +} + +static inline const GUID *TLB_get_guid_null(const TLBGuid *guid) +{ + return guid != NULL ? &guid->guid : &GUID_NULL; +} + +static int get_ptr_size(SYSKIND syskind) +{ + switch(syskind){ + case SYS_WIN64: + return 8; + case SYS_WIN32: + case SYS_MAC: + case SYS_WIN16: + return 4; + } + WARN("Unhandled syskind: 0x%x\n", syskind); + return 4; +} /* debug @@ -1273,15 +1450,22 @@ static const char * const typekind_desc[] = static void dump_TLBFuncDescOne(const TLBFuncDesc * pfd) { int i; - MESSAGE("%s(%u)\n", debugstr_w(pfd->Name), pfd->funcdesc.cParams); + MESSAGE("%s(%u)\n", debugstr_w(TLB_get_bstr(pfd->Name)), pfd->funcdesc.cParams); for (i=0;ifuncdesc.cParams;i++) - MESSAGE("\tparm%d: %s\n",i,debugstr_w(pfd->pParamDesc[i].Name)); + MESSAGE("\tparm%d: %s\n",i,debugstr_w(TLB_get_bstr(pfd->pParamDesc[i].Name))); dump_FUNCDESC(&(pfd->funcdesc)); - MESSAGE("\thelpstring: %s\n", debugstr_w(pfd->HelpString)); - MESSAGE("\tentry: %s\n", (pfd->Entry == (void *)-1) ? "invalid" : debugstr_w(pfd->Entry)); + MESSAGE("\thelpstring: %s\n", debugstr_w(TLB_get_bstr(pfd->HelpString))); + if(pfd->Entry == NULL) + MESSAGE("\tentry: (null)\n"); + else if(pfd->Entry == (void*)-1) + MESSAGE("\tentry: invalid\n"); + else if(IS_INTRESOURCE(pfd->Entry)) + MESSAGE("\tentry: %p\n", pfd->Entry); + else + MESSAGE("\tentry: %s\n", debugstr_w(TLB_get_bstr(pfd->Entry))); } static void dump_TLBFuncDesc(const TLBFuncDesc * pfd, UINT n) { @@ -1296,7 +1480,7 @@ static void dump_TLBVarDesc(const TLBVarDesc * pvd, UINT n) { while (n) { - TRACE_(typelib)("%s\n", debugstr_w(pvd->Name)); + TRACE_(typelib)("%s\n", debugstr_w(TLB_get_bstr(pvd->Name))); ++pvd; --n; } @@ -1304,7 +1488,7 @@ static void dump_TLBVarDesc(const TLBVarDesc * pvd, UINT n) static void dump_TLBImpLib(const TLBImpLib *import) { - TRACE_(typelib)("%s %s\n", debugstr_guid(&(import->guid)), + TRACE_(typelib)("%s %s\n", debugstr_guid(TLB_get_guidref(import->guid)), debugstr_w(import->name)); TRACE_(typelib)("v%d.%d lcid=%x offset=%x\n", import->wVersionMajor, import->wVersionMinor, import->lcid, import->offset); @@ -1318,7 +1502,7 @@ static void dump_TLBRefType(const ITypeLibImpl *pTL) { TRACE_(typelib)("href:0x%08x\n", ref->reference); if(ref->index == -1) - TRACE_(typelib)("%s\n", debugstr_guid(&(ref->guid))); + TRACE_(typelib)("%s\n", debugstr_guid(TLB_get_guidref(ref->guid))); else TRACE_(typelib)("type no: %d\n", ref->index); @@ -1421,18 +1605,17 @@ static void dump_DispParms(const DISPPARAMS * pdp) static void dump_TypeInfo(const ITypeInfoImpl * pty) { TRACE("%p ref=%u\n", pty, pty->ref); - TRACE("%s %s\n", debugstr_w(pty->Name), debugstr_w(pty->DocString)); - TRACE("attr:%s\n", debugstr_guid(&(pty->TypeAttr.guid))); - TRACE("kind:%s\n", typekind_desc[pty->TypeAttr.typekind]); - TRACE("fct:%u var:%u impl:%u\n", - pty->TypeAttr.cFuncs, pty->TypeAttr.cVars, pty->TypeAttr.cImplTypes); - TRACE("wTypeFlags: 0x%04x\n", pty->TypeAttr.wTypeFlags); + TRACE("%s %s\n", debugstr_w(TLB_get_bstr(pty->Name)), debugstr_w(TLB_get_bstr(pty->DocString))); + TRACE("attr:%s\n", debugstr_guid(TLB_get_guidref(pty->guid))); + TRACE("kind:%s\n", typekind_desc[pty->typekind]); + TRACE("fct:%u var:%u impl:%u\n", pty->cFuncs, pty->cVars, pty->cImplTypes); + TRACE("wTypeFlags: 0x%04x\n", pty->wTypeFlags); TRACE("parent tlb:%p index in TLB:%u\n",pty->pTypeLib, pty->index); - if (pty->TypeAttr.typekind == TKIND_MODULE) TRACE("dllname:%s\n", debugstr_w(pty->DllName)); + if (pty->typekind == TKIND_MODULE) TRACE("dllname:%s\n", debugstr_w(TLB_get_bstr(pty->DllName))); if (TRACE_ON(ole)) - dump_TLBFuncDesc(pty->funcdescs, pty->TypeAttr.cFuncs); - dump_TLBVarDesc(pty->vardescs, pty->TypeAttr.cVars); - dump_TLBImplType(pty->impltypes, pty->TypeAttr.cImplTypes); + dump_TLBFuncDesc(pty->funcdescs, pty->cFuncs); + dump_TLBVarDesc(pty->vardescs, pty->cVars); + dump_TLBImplType(pty->impltypes, pty->cImplTypes); } static void dump_VARDESC(const VARDESC *v) @@ -1578,7 +1761,7 @@ static inline TLBFuncDesc *TLB_get_funcdesc_by_name(TLBFuncDesc *funcdescs, UINT n, const OLECHAR *name) { while(n){ - if(!lstrcmpiW(funcdescs->Name, name)) + if(!lstrcmpiW(TLB_get_bstr(funcdescs->Name), name)) return funcdescs; ++funcdescs; --n; @@ -1602,7 +1785,7 @@ static inline TLBVarDesc *TLB_get_vardesc_by_name(TLBVarDesc *vardescs, UINT n, const OLECHAR *name) { while(n){ - if(!lstrcmpiW(vardescs->Name, name)) + if(!lstrcmpiW(TLB_get_bstr(vardescs->Name), name)) return vardescs; ++vardescs; --n; @@ -1614,12 +1797,29 @@ static inline TLBCustData *TLB_get_custdata_by_guid(struct list *custdata_list, { TLBCustData *cust_data; LIST_FOR_EACH_ENTRY(cust_data, custdata_list, TLBCustData, entry) - if(IsEqualIID(&cust_data->guid, guid)) + if(IsEqualIID(TLB_get_guid_null(cust_data->guid), guid)) return cust_data; return NULL; } -static TLBVarDesc *TLBVarDesc_Constructor(UINT n) +static inline ITypeInfoImpl *TLB_get_typeinfo_by_name(ITypeInfoImpl **typeinfos, + UINT n, const OLECHAR *name) +{ + while(n){ + if(!lstrcmpiW(TLB_get_bstr((*typeinfos)->Name), name)) + return *typeinfos; + ++typeinfos; + --n; + } + return NULL; +} + +static void TLBVarDesc_Constructor(TLBVarDesc *var_desc) +{ + list_init(&var_desc->custdata_list); +} + +static TLBVarDesc *TLBVarDesc_Alloc(UINT n) { TLBVarDesc *ret; @@ -1628,7 +1828,7 @@ static TLBVarDesc *TLBVarDesc_Constructor(UINT n) return NULL; while(n){ - list_init(&ret[n-1].custdata_list); + TLBVarDesc_Constructor(&ret[n-1]); --n; } @@ -1651,7 +1851,12 @@ static TLBParDesc *TLBParDesc_Constructor(UINT n) return ret; } -static TLBFuncDesc *TLBFuncDesc_Constructor(UINT n) +static void TLBFuncDesc_Constructor(TLBFuncDesc *func_desc) +{ + list_init(&func_desc->custdata_list); +} + +static TLBFuncDesc *TLBFuncDesc_Alloc(UINT n) { TLBFuncDesc *ret; @@ -1660,14 +1865,19 @@ static TLBFuncDesc *TLBFuncDesc_Constructor(UINT n) return NULL; while(n){ - list_init(&ret[n-1].custdata_list); + TLBFuncDesc_Constructor(&ret[n-1]); --n; } return ret; } -static TLBImplType *TLBImplType_Constructor(UINT n) +static void TLBImplType_Constructor(TLBImplType *impl) +{ + list_init(&impl->custdata_list); +} + +static TLBImplType *TLBImplType_Alloc(UINT n) { TLBImplType *ret; @@ -1676,13 +1886,207 @@ static TLBImplType *TLBImplType_Constructor(UINT n) return NULL; while(n){ - list_init(&ret[n-1].custdata_list); + TLBImplType_Constructor(&ret[n-1]); --n; } return ret; } +static TLBGuid *TLB_append_guid(struct list *guid_list, + const GUID *new_guid, HREFTYPE hreftype) +{ + TLBGuid *guid; + + LIST_FOR_EACH_ENTRY(guid, guid_list, TLBGuid, entry) { + if (IsEqualGUID(&guid->guid, new_guid)) + return guid; + } + + guid = heap_alloc(sizeof(TLBGuid)); + if (!guid) + return NULL; + + memcpy(&guid->guid, new_guid, sizeof(GUID)); + guid->hreftype = hreftype; + + list_add_tail(guid_list, &guid->entry); + + return guid; +} + +static HRESULT TLB_set_custdata(struct list *custdata_list, TLBGuid *tlbguid, VARIANT *var) +{ + TLBCustData *cust_data; + + switch(V_VT(var)){ + case VT_I4: + case VT_R4: + case VT_UI4: + case VT_INT: + case VT_UINT: + case VT_HRESULT: + case VT_BSTR: + break; + default: + return DISP_E_BADVARTYPE; + } + + cust_data = TLB_get_custdata_by_guid(custdata_list, TLB_get_guid_null(tlbguid)); + + if (!cust_data) { + cust_data = heap_alloc(sizeof(TLBCustData)); + if (!cust_data) + return E_OUTOFMEMORY; + + cust_data->guid = tlbguid; + VariantInit(&cust_data->data); + + list_add_tail(custdata_list, &cust_data->entry); + }else + VariantClear(&cust_data->data); + + return VariantCopy(&cust_data->data, var); +} + +static TLBString *TLB_append_str(struct list *string_list, BSTR new_str) +{ + TLBString *str; + + LIST_FOR_EACH_ENTRY(str, string_list, TLBString, entry) { + if (strcmpW(str->str, new_str) == 0) + return str; + } + + str = heap_alloc(sizeof(TLBString)); + if (!str) + return NULL; + + str->str = SysAllocString(new_str); + if (!str->str) { + heap_free(str); + return NULL; + } + + list_add_tail(string_list, &str->entry); + + return str; +} + +static HRESULT TLB_get_size_from_hreftype(ITypeInfoImpl *info, HREFTYPE href, + ULONG *size, WORD *align) +{ + ITypeInfo *other; + TYPEATTR *attr; + HRESULT hr; + + hr = ITypeInfo2_GetRefTypeInfo(&info->ITypeInfo2_iface, href, &other); + if(FAILED(hr)) + return hr; + + hr = ITypeInfo_GetTypeAttr(other, &attr); + if(FAILED(hr)){ + ITypeInfo_Release(other); + return hr; + } + + if(size) + *size = attr->cbSizeInstance; + if(align) + *align = attr->cbAlignment; + + ITypeInfo_ReleaseTypeAttr(other, attr); + ITypeInfo_Release(other); + + return S_OK; +} + +static HRESULT TLB_size_instance(ITypeInfoImpl *info, SYSKIND sys, + TYPEDESC *tdesc, ULONG *size, WORD *align) +{ + ULONG i, sub, ptr_size; + HRESULT hr; + + ptr_size = get_ptr_size(sys); + + switch(tdesc->vt){ + case VT_VOID: + *size = 0; + break; + case VT_I1: + case VT_UI1: + *size = 1; + break; + case VT_I2: + case VT_BOOL: + case VT_UI2: + *size = 2; + break; + case VT_I4: + case VT_R4: + case VT_ERROR: + case VT_UI4: + case VT_INT: + case VT_UINT: + case VT_HRESULT: + *size = 4; + break; + case VT_R8: + case VT_I8: + case VT_UI8: + *size = 8; + break; + case VT_BSTR: + case VT_DISPATCH: + case VT_UNKNOWN: + case VT_PTR: + case VT_SAFEARRAY: + case VT_LPSTR: + case VT_LPWSTR: + *size = ptr_size; + break; + case VT_DATE: + *size = sizeof(DATE); + break; + case VT_VARIANT: + *size = sizeof(VARIANT); +#ifdef _WIN64 + if(sys == SYS_WIN32) + *size -= 8; /* 32-bit VARIANT is 8 bytes smaller than 64-bit VARIANT */ +#endif + break; + case VT_DECIMAL: + *size = sizeof(DECIMAL); + break; + case VT_CY: + *size = sizeof(CY); + break; + case VT_CARRAY: + *size = 0; + for(i = 0; i < tdesc->u.lpadesc->cDims; ++i) + *size += tdesc->u.lpadesc->rgbounds[i].cElements; + hr = TLB_size_instance(info, sys, &tdesc->u.lpadesc->tdescElem, &sub, align); + if(FAILED(hr)) + return hr; + *size *= sub; + return S_OK; + case VT_USERDEFINED: + return TLB_get_size_from_hreftype(info, tdesc->u.hreftype, size, align); + default: + FIXME("Unsized VT: 0x%x\n", tdesc->vt); + return E_FAIL; + } + + if(align){ + if(*size < 4) + *align = *size; + else + *align = 4; + } + + return S_OK; +} + /********************************************************************** * * Functions for reading MSFT typelibs (those created by CreateTypeLib2) @@ -1742,17 +2146,43 @@ static DWORD MSFT_ReadLEWords(void *buffer, DWORD count, TLBContext *pcx, return ret; } -static void MSFT_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx) +static HRESULT MSFT_ReadAllGuids(TLBContext *pcx) { - if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){ - memset(pGuid,0, sizeof(GUID)); - return; + TLBGuid *guid; + MSFT_GuidEntry entry; + int offs = 0; + + MSFT_Seek(pcx, pcx->pTblDir->pGuidTab.offset); + while (1) { + if (offs >= pcx->pTblDir->pGuidTab.length) + return S_OK; + + MSFT_ReadLEWords(&entry, sizeof(MSFT_GuidEntry), pcx, DO_NOT_SEEK); + + guid = heap_alloc(sizeof(TLBGuid)); + + guid->offset = offs; + guid->guid = entry.guid; + guid->hreftype = entry.hreftype; + + list_add_tail(&pcx->pLibInfo->guid_list, &guid->entry); + + offs += sizeof(MSFT_GuidEntry); } - MSFT_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset ); - pGuid->Data1 = FromLEDWord(pGuid->Data1); - pGuid->Data2 = FromLEWord(pGuid->Data2); - pGuid->Data3 = FromLEWord(pGuid->Data3); - TRACE_(typelib)("%s\n", debugstr_guid(pGuid)); +} + +static TLBGuid *MSFT_ReadGuid( int offset, TLBContext *pcx) +{ + TLBGuid *ret; + + LIST_FOR_EACH_ENTRY(ret, &pcx->pLibInfo->guid_list, TLBGuid, entry){ + if(ret->offset == offset){ + TRACE_(typelib)("%s\n", debugstr_guid(&ret->guid)); + return ret; + } + } + + return NULL; } static HREFTYPE MSFT_ReadHreftype( TLBContext *pcx, int offset ) @@ -1771,72 +2201,81 @@ static HREFTYPE MSFT_ReadHreftype( TLBContext *pcx, int offset ) return niName.hreftype; } -static BSTR MSFT_ReadName( TLBContext *pcx, int offset) +static HRESULT MSFT_ReadAllNames(TLBContext *pcx) { - char * name; - MSFT_NameIntro niName; - int lengthInChars; - BSTR bstrName = NULL; + char *string; + MSFT_NameIntro intro; + INT16 len_piece; + int offs = 0, lengthInChars; - if (offset < 0) - { - ERR_(typelib)("bad offset %d\n", offset); - return NULL; + MSFT_Seek(pcx, pcx->pTblDir->pNametab.offset); + while (1) { + TLBString *tlbstr; + + if (offs >= pcx->pTblDir->pNametab.length) + return S_OK; + + MSFT_ReadLEWords(&intro, sizeof(MSFT_NameIntro), pcx, DO_NOT_SEEK); + intro.namelen &= 0xFF; + len_piece = intro.namelen + sizeof(MSFT_NameIntro); + if(len_piece % 4) + len_piece = (len_piece + 4) & ~0x3; + if(len_piece < 8) + len_piece = 8; + + string = heap_alloc(len_piece + 1); + MSFT_Read(string, len_piece - sizeof(MSFT_NameIntro), pcx, DO_NOT_SEEK); + string[intro.namelen] = '\0'; + + lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, + string, -1, NULL, 0); + if (!lengthInChars) { + heap_free(string); + return E_UNEXPECTED; + } + + tlbstr = heap_alloc(sizeof(TLBString)); + + tlbstr->offset = offs; + tlbstr->str = SysAllocStringByteLen(NULL, lengthInChars * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, tlbstr->str, lengthInChars); + + heap_free(string); + + list_add_tail(&pcx->pLibInfo->name_list, &tlbstr->entry); + + offs += len_piece; } - MSFT_ReadLEDWords(&niName, sizeof(niName), pcx, - pcx->pTblDir->pNametab.offset+offset); - niName.namelen &= 0xFF; /* FIXME: correct ? */ - name = heap_alloc_zero((niName.namelen & 0xff) +1); - MSFT_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK); - name[niName.namelen & 0xff]='\0'; - - lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, - name, -1, NULL, 0); - - /* no invalid characters in string */ - if (lengthInChars) - { - bstrName = SysAllocStringByteLen(NULL, lengthInChars * sizeof(WCHAR)); - - /* don't check for invalid character since this has been done previously */ - MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, bstrName, lengthInChars); - } - heap_free(name); - - TRACE_(typelib)("%s %d\n", debugstr_w(bstrName), lengthInChars); - return bstrName; } -static BSTR MSFT_ReadString( TLBContext *pcx, int offset) +static TLBString *MSFT_ReadName( TLBContext *pcx, int offset) { - char * string; - INT16 length; - int lengthInChars; - BSTR bstr = NULL; + TLBString *tlbstr; - if(offset<0) return NULL; - MSFT_ReadLEWords(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset); - if(length <= 0) return 0; - string = heap_alloc_zero(length +1); - MSFT_Read(string, length, pcx, DO_NOT_SEEK); - string[length]='\0'; - - lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, - string, -1, NULL, 0); - - /* no invalid characters in string */ - if (lengthInChars) - { - bstr = SysAllocStringByteLen(NULL, lengthInChars * sizeof(WCHAR)); - - /* don't check for invalid character since this has been done previously */ - MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, bstr, lengthInChars); + LIST_FOR_EACH_ENTRY(tlbstr, &pcx->pLibInfo->name_list, TLBString, entry) { + if (tlbstr->offset == offset) { + TRACE_(typelib)("%s\n", debugstr_w(tlbstr->str)); + return tlbstr; + } } - heap_free(string); - TRACE_(typelib)("%s %d\n", debugstr_w(bstr), lengthInChars); - return bstr; + return NULL; } + +static TLBString *MSFT_ReadString( TLBContext *pcx, int offset) +{ + TLBString *tlbstr; + + LIST_FOR_EACH_ENTRY(tlbstr, &pcx->pLibInfo->string_list, TLBString, entry) { + if (tlbstr->offset == offset) { + TRACE_(typelib)("%s\n", debugstr_w(tlbstr->str)); + return tlbstr; + } + } + + return NULL; +} + /* * read a value and fill a VARIANT structure */ @@ -1948,7 +2387,7 @@ static int MSFT_CustData( TLBContext *pcx, int offset, struct list *custdata_lis count++; pNew=heap_alloc_zero(sizeof(TLBCustData)); MSFT_ReadLEDWords(&entry, sizeof(entry), pcx, pcx->pTblDir->pCDGuids.offset+offset); - MSFT_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx); + pNew->guid = MSFT_ReadGuid(entry.GuidOffset, pcx); MSFT_ReadValue(&(pNew->data), entry.DataOffset, pcx); list_add_head(custdata_list, &pNew->entry); offset = entry.next; @@ -1956,46 +2395,21 @@ static int MSFT_CustData( TLBContext *pcx, int offset, struct list *custdata_lis return count; } -static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd, - ITypeInfoImpl *pTI) +static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd) { if(type <0) pTd->vt=type & VT_TYPEMASK; else *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))]; - if(pTd->vt == VT_USERDEFINED) - MSFT_DoRefType(pcx, pTI->pTypeLib, pTd->u.hreftype); - TRACE_(typelib)("vt type = %X\n", pTd->vt); } -static void MSFT_ResolveReferencedTypes(TLBContext *pcx, ITypeInfoImpl *pTI, TYPEDESC *lpTypeDesc) +static int TLB_is_propgetput(INVOKEKIND invkind) { - /* resolve referenced type if any */ - while (lpTypeDesc) - { - switch (lpTypeDesc->vt) - { - case VT_PTR: - lpTypeDesc = lpTypeDesc->u.lptdesc; - break; - - case VT_CARRAY: - lpTypeDesc = & (lpTypeDesc->u.lpadesc->tdescElem); - break; - - case VT_USERDEFINED: - MSFT_DoRefType(pcx, pTI->pTypeLib, - lpTypeDesc->u.hreftype); - - lpTypeDesc = NULL; - break; - - default: - lpTypeDesc = NULL; - } - } + return (invkind == INVOKE_PROPERTYGET || + invkind == INVOKE_PROPERTYPUT || + invkind == INVOKE_PROPERTYPUTREF); } static void @@ -2042,7 +2456,7 @@ MSFT_DoFuncs(TLBContext* pcx, MSFT_ReadLEDWords(&infolen, sizeof(INT), pcx, offset); - *pptfd = TLBFuncDesc_Constructor(cFuncs); + *pptfd = TLBFuncDesc_Alloc(cFuncs); ptfd = *pptfd; for ( i = 0; i < cFuncs ; i++ ) { @@ -2052,13 +2466,6 @@ MSFT_DoFuncs(TLBContext* pcx, MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx, offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT)); - /* nameoffset is sometimes -1 on the second half of a propget/propput - * pair of functions */ - if ((nameoffset == -1) && (i > 0)) - ptfd->Name = SysAllocString(ptfd_prev->Name); - else - ptfd->Name = MSFT_ReadName(pcx, nameoffset); - /* read the function information record */ MSFT_ReadLEDWords(&reclength, sizeof(pFuncRec->Info), pcx, recoffset); @@ -2068,6 +2475,8 @@ MSFT_DoFuncs(TLBContext* pcx, /* size without argument data */ optional = reclength - pFuncRec->nrargs*sizeof(MSFT_ParameterInfo); + if (pFuncRec->FKCCIC & 0x1000) + optional -= pFuncRec->nrargs * sizeof(INT); if (optional > FIELD_OFFSET(MSFT_FuncRecord, HelpContext)) ptfd->helpcontext = pFuncRec->HelpContext; @@ -2081,13 +2490,13 @@ MSFT_DoFuncs(TLBContext* pcx, { if (!IS_INTRESOURCE(pFuncRec->oEntry)) ERR("ordinal 0x%08x invalid, IS_INTRESOURCE is false\n", pFuncRec->oEntry); - ptfd->Entry = (BSTR)(DWORD_PTR)LOWORD(pFuncRec->oEntry); + ptfd->Entry = (TLBString*)(DWORD_PTR)LOWORD(pFuncRec->oEntry); } else ptfd->Entry = MSFT_ReadString(pcx, pFuncRec->oEntry); } else - ptfd->Entry = (BSTR)-1; + ptfd->Entry = (TLBString*)-1; if (optional > FIELD_OFFSET(MSFT_FuncRecord, HelpStringContext)) ptfd->HelpStringContext = pFuncRec->HelpStringContext; @@ -2107,11 +2516,18 @@ MSFT_DoFuncs(TLBContext* pcx, ptfd->funcdesc.oVft = pFuncRec->VtableOffset & ~1; ptfd->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ; + /* nameoffset is sometimes -1 on the second half of a propget/propput + * pair of functions */ + if ((nameoffset == -1) && (i > 0) && + TLB_is_propgetput(ptfd_prev->funcdesc.invkind) && + TLB_is_propgetput(ptfd->funcdesc.invkind)) + ptfd->Name = ptfd_prev->Name; + else + ptfd->Name = MSFT_ReadName(pcx, nameoffset); + MSFT_GetTdesc(pcx, pFuncRec->DataType, - &ptfd->funcdesc.elemdescFunc.tdesc, - pTI); - MSFT_ResolveReferencedTypes(pcx, pTI, &ptfd->funcdesc.elemdescFunc.tdesc); + &ptfd->funcdesc.elemdescFunc.tdesc); /* do the parameters/arguments */ if(pFuncRec->nrargs) @@ -2120,7 +2536,7 @@ MSFT_DoFuncs(TLBContext* pcx, MSFT_ParameterInfo paraminfo; ptfd->funcdesc.lprgelemdescParam = - heap_alloc_zero(pFuncRec->nrargs * sizeof(ELEMDESC)); + heap_alloc_zero(pFuncRec->nrargs * (sizeof(ELEMDESC) + sizeof(PARAMDESCEX))); ptfd->pParamDesc = TLBParDesc_Constructor(pFuncRec->nrargs); @@ -2133,23 +2549,15 @@ MSFT_DoFuncs(TLBContext* pcx, MSFT_GetTdesc(pcx, paraminfo.DataType, - &elemdesc->tdesc, - pTI); + &elemdesc->tdesc); elemdesc->u.paramdesc.wParamFlags = paraminfo.Flags; /* name */ - if (paraminfo.oName == -1) - /* this occurs for [propput] or [propget] methods, so - * we should just set the name of the parameter to the - * name of the method. */ - ptfd->pParamDesc[j].Name = SysAllocString(ptfd->Name); - else + if (paraminfo.oName != -1) ptfd->pParamDesc[j].Name = MSFT_ReadName( pcx, paraminfo.oName ); - TRACE_(typelib)("param[%d] = %s\n", j, debugstr_w(ptfd->pParamDesc[j].Name)); - - MSFT_ResolveReferencedTypes(pcx, pTI, &elemdesc->tdesc); + TRACE_(typelib)("param[%d] = %s\n", j, debugstr_w(TLB_get_bstr(ptfd->pParamDesc[j].Name))); /* default value */ if ( (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) && @@ -2161,7 +2569,7 @@ MSFT_DoFuncs(TLBContext* pcx, PARAMDESC* pParamDesc = &elemdesc->u.paramdesc; - pParamDesc->pparamdescex = heap_alloc_zero(sizeof(PARAMDESCEX)); + pParamDesc->pparamdescex = (PARAMDESCEX*)(ptfd->funcdesc.lprgelemdescParam+pFuncRec->nrargs)+j; pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX); MSFT_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue), @@ -2214,7 +2622,7 @@ static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs, TRACE_(typelib)("\n"); - ptvd = *pptvd = TLBVarDesc_Constructor(cVars); + ptvd = *pptvd = TLBVarDesc_Alloc(cVars); MSFT_ReadLEDWords(&infolen,sizeof(INT), pcx, offset); MSFT_ReadLEDWords(&recoffset,sizeof(INT), pcx, offset + infolen + ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT)); @@ -2245,7 +2653,7 @@ static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs, ptvd->vardesc.varkind = pVarRec->VarKind; ptvd->vardesc.wVarFlags = pVarRec->Flags; MSFT_GetTdesc(pcx, pVarRec->DataType, - &ptvd->vardesc.elemdescVar.tdesc, pTI); + &ptvd->vardesc.elemdescVar.tdesc); /* ptvd->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */ if(pVarRec->VarKind == VAR_CONST ){ ptvd->vardesc.u.lpvarValue = heap_alloc_zero(sizeof(VARIANT)); @@ -2253,66 +2661,10 @@ static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs, pVarRec->OffsValue, pcx); } else ptvd->vardesc.u.oInst=pVarRec->OffsValue; - MSFT_ResolveReferencedTypes(pcx, pTI, &ptvd->vardesc.elemdescVar.tdesc); recoffset += reclength; } } -/* fill in data for a hreftype (offset). When the referenced type is contained - * in the typelib, it's just an (file) offset in the type info base dir. - * If comes from import, it's an offset+1 in the ImpInfo table - * */ -static void MSFT_DoRefType(TLBContext *pcx, ITypeLibImpl *pTL, - int offset) -{ - TLBRefType *ref; - - TRACE_(typelib)("TLB context %p, TLB offset %x\n", pcx, offset); - - LIST_FOR_EACH_ENTRY(ref, &pTL->ref_list, TLBRefType, entry) - { - if(ref->reference == offset) return; - } - - ref = heap_alloc_zero(sizeof(TLBRefType)); - list_add_tail(&pTL->ref_list, &ref->entry); - - if(!MSFT_HREFTYPE_INTHISFILE( offset)) { - /* external typelib */ - MSFT_ImpInfo impinfo; - TLBImpLib *pImpLib; - - TRACE_(typelib)("offset %x, masked offset %x\n", offset, offset + (offset & 0xfffffffc)); - - MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx, - pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc)); - - LIST_FOR_EACH_ENTRY(pImpLib, &pcx->pLibInfo->implib_list, TLBImpLib, entry) - if(pImpLib->offset==impinfo.oImpFile) - break; - - if(&pImpLib->entry != &pcx->pLibInfo->implib_list){ - ref->reference = offset; - ref->pImpTLInfo = pImpLib; - if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) { - MSFT_ReadGuid(&ref->guid, impinfo.oGuid, pcx); - TRACE("importing by guid %s\n", debugstr_guid(&ref->guid)); - ref->index = TLB_REF_USE_GUID; - } else - ref->index = impinfo.oGuid; - }else{ - ERR("Cannot find a reference\n"); - ref->reference = -1; - ref->pImpTLInfo = TLB_REF_NOT_FOUND; - } - }else{ - /* in this typelib */ - ref->index = MSFT_HREFTYPE_INDEX(offset); - ref->reference = offset; - ref->pImpTLInfo = TLB_REF_INTERNAL; - } -} - /* process Implemented Interfaces of a com class */ static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count, int offset) @@ -2323,12 +2675,11 @@ static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count, TRACE_(typelib)("\n"); - pTI->impltypes = TLBImplType_Constructor(count); + pTI->impltypes = TLBImplType_Alloc(count); pImpl = pTI->impltypes; for(i=0;ipTblDir->pRefTab.offset); - MSFT_DoRefType(pcx, pTI->pTypeLib, refrec.reftype); pImpl->hRef = refrec.reftype; pImpl->implflags=refrec.flags; MSFT_CustData(pcx, refrec.oCustData, &pImpl->custdata_list); @@ -2336,6 +2687,47 @@ static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count, ++pImpl; } } + +#ifdef _WIN64 +/* when a 32-bit typelib is loaded in 64-bit mode, we need to resize pointers + * and some structures, and fix the alignment */ +static void TLB_fix_32on64_typeinfo(ITypeInfoImpl *info) +{ + if(info->typekind == TKIND_ALIAS){ + switch(info->tdescAlias->vt){ + case VT_BSTR: + case VT_DISPATCH: + case VT_UNKNOWN: + case VT_PTR: + case VT_SAFEARRAY: + case VT_LPSTR: + case VT_LPWSTR: + info->cbSizeInstance = sizeof(void*); + info->cbAlignment = sizeof(void*); + break; + case VT_CARRAY: + case VT_USERDEFINED: + TLB_size_instance(info, SYS_WIN64, info->tdescAlias, &info->cbSizeInstance, &info->cbAlignment); + break; + case VT_VARIANT: + info->cbSizeInstance = sizeof(VARIANT); + info->cbAlignment = 8; + default: + if(info->cbSizeInstance < sizeof(void*)) + info->cbAlignment = info->cbSizeInstance; + else + info->cbAlignment = sizeof(void*); + break; + } + }else if(info->typekind == TKIND_INTERFACE || + info->typekind == TKIND_DISPATCH || + info->typekind == TKIND_COCLASS){ + info->cbSizeInstance = sizeof(void*); + info->cbAlignment = sizeof(void*); + } +} +#endif + /* * process a typeinfo record */ @@ -2356,24 +2748,26 @@ static ITypeInfoImpl * MSFT_DoTypeInfo( /* this is where we are coming from */ ptiRet->pTypeLib = pLibInfo; ptiRet->index=count; -/* fill in the typeattr fields */ - MSFT_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx); - ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid; /* FIXME: correct? */ - ptiRet->TypeAttr.lpstrSchema=NULL; /* reserved */ - ptiRet->TypeAttr.cbSizeInstance=tiBase.size; - ptiRet->TypeAttr.typekind=tiBase.typekind & 0xF; - ptiRet->TypeAttr.cFuncs=LOWORD(tiBase.cElement); - ptiRet->TypeAttr.cVars=HIWORD(tiBase.cElement); - ptiRet->TypeAttr.cbAlignment=(tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */ - ptiRet->TypeAttr.wTypeFlags=tiBase.flags; - ptiRet->TypeAttr.wMajorVerNum=LOWORD(tiBase.version); - ptiRet->TypeAttr.wMinorVerNum=HIWORD(tiBase.version); - ptiRet->TypeAttr.cImplTypes=tiBase.cImplTypes; - ptiRet->TypeAttr.cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */ - if(ptiRet->TypeAttr.typekind == TKIND_ALIAS) - MSFT_GetTdesc(pcx, tiBase.datatype1, - &ptiRet->TypeAttr.tdescAlias, ptiRet); + ptiRet->guid = MSFT_ReadGuid(tiBase.posguid, pcx); + ptiRet->lcid=pLibInfo->set_lcid; /* FIXME: correct? */ + ptiRet->lpstrSchema=NULL; /* reserved */ + ptiRet->cbSizeInstance=tiBase.size; + ptiRet->typekind=tiBase.typekind & 0xF; + ptiRet->cFuncs=LOWORD(tiBase.cElement); + ptiRet->cVars=HIWORD(tiBase.cElement); + ptiRet->cbAlignment=(tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */ + ptiRet->wTypeFlags=tiBase.flags; + ptiRet->wMajorVerNum=LOWORD(tiBase.version); + ptiRet->wMinorVerNum=HIWORD(tiBase.version); + ptiRet->cImplTypes=tiBase.cImplTypes; + ptiRet->cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */ + if(ptiRet->typekind == TKIND_ALIAS){ + TYPEDESC tmp; + MSFT_GetTdesc(pcx, tiBase.datatype1, &tmp); + ptiRet->tdescAlias = heap_alloc(TLB_SizeTypeDesc(&tmp, TRUE)); + TLB_CopyTypeDesc(NULL, &tmp, ptiRet->tdescAlias); + } /* FIXME: */ /* IDLDESC idldescType; *//* never saw this one != zero */ @@ -2381,33 +2775,33 @@ static ITypeInfoImpl * MSFT_DoTypeInfo( /* name, eventually add to a hash table */ ptiRet->Name=MSFT_ReadName(pcx, tiBase.NameOffset); ptiRet->hreftype = MSFT_ReadHreftype(pcx, tiBase.NameOffset); - TRACE_(typelib)("reading %s\n", debugstr_w(ptiRet->Name)); + TRACE_(typelib)("reading %s\n", debugstr_w(TLB_get_bstr(ptiRet->Name))); /* help info */ ptiRet->DocString=MSFT_ReadString(pcx, tiBase.docstringoffs); ptiRet->dwHelpStringContext=tiBase.helpstringcontext; ptiRet->dwHelpContext=tiBase.helpcontext; - if (ptiRet->TypeAttr.typekind == TKIND_MODULE) + if (ptiRet->typekind == TKIND_MODULE) ptiRet->DllName = MSFT_ReadString(pcx, tiBase.datatype1); /* note: InfoType's Help file and HelpStringDll come from the containing * library. Further HelpString and Docstring appear to be the same thing :( */ /* functions */ - if(ptiRet->TypeAttr.cFuncs >0 ) - MSFT_DoFuncs(pcx, ptiRet, ptiRet->TypeAttr.cFuncs, - ptiRet->TypeAttr.cVars, + if(ptiRet->cFuncs >0 ) + MSFT_DoFuncs(pcx, ptiRet, ptiRet->cFuncs, + ptiRet->cVars, tiBase.memoffset, &ptiRet->funcdescs); /* variables */ - if(ptiRet->TypeAttr.cVars >0 ) - MSFT_DoVars(pcx, ptiRet, ptiRet->TypeAttr.cFuncs, - ptiRet->TypeAttr.cVars, + if(ptiRet->cVars >0 ) + MSFT_DoVars(pcx, ptiRet, ptiRet->cFuncs, + ptiRet->cVars, tiBase.memoffset, &ptiRet->vardescs); - if(ptiRet->TypeAttr.cImplTypes >0 ) { - switch(ptiRet->TypeAttr.typekind) + if(ptiRet->cImplTypes >0 ) { + switch(ptiRet->typekind) { case TKIND_COCLASS: - MSFT_DoImplTypes(pcx, ptiRet, ptiRet->TypeAttr.cImplTypes , + MSFT_DoImplTypes(pcx, ptiRet, ptiRet->cImplTypes, tiBase.datatype1); break; case TKIND_DISPATCH: @@ -2419,30 +2813,113 @@ static ITypeInfoImpl * MSFT_DoTypeInfo( if (tiBase.datatype1 != -1) { - ptiRet->impltypes = TLBImplType_Constructor(1); + ptiRet->impltypes = TLBImplType_Alloc(1); ptiRet->impltypes[0].hRef = tiBase.datatype1; - MSFT_DoRefType(pcx, pLibInfo, tiBase.datatype1); } break; default: - ptiRet->impltypes = TLBImplType_Constructor(1); - MSFT_DoRefType(pcx, pLibInfo, tiBase.datatype1); + ptiRet->impltypes = TLBImplType_Alloc(1); ptiRet->impltypes[0].hRef = tiBase.datatype1; break; } } - MSFT_CustData(pcx, tiBase.oCustData, &ptiRet->custdata_list); + MSFT_CustData(pcx, tiBase.oCustData, ptiRet->pcustdata_list); TRACE_(typelib)("%s guid: %s kind:%s\n", - debugstr_w(ptiRet->Name), - debugstr_guid(&ptiRet->TypeAttr.guid), - typekind_desc[ptiRet->TypeAttr.typekind]); + debugstr_w(TLB_get_bstr(ptiRet->Name)), + debugstr_guid(TLB_get_guidref(ptiRet->guid)), + typekind_desc[ptiRet->typekind]); if (TRACE_ON(typelib)) dump_TypeInfo(ptiRet); return ptiRet; } +static HRESULT MSFT_ReadAllStrings(TLBContext *pcx) +{ + char *string; + INT16 len_str, len_piece; + int offs = 0, lengthInChars; + + MSFT_Seek(pcx, pcx->pTblDir->pStringtab.offset); + while (1) { + TLBString *tlbstr; + + if (offs >= pcx->pTblDir->pStringtab.length) + return S_OK; + + MSFT_ReadLEWords(&len_str, sizeof(INT16), pcx, DO_NOT_SEEK); + len_piece = len_str + sizeof(INT16); + if(len_piece % 4) + len_piece = (len_piece + 4) & ~0x3; + if(len_piece < 8) + len_piece = 8; + + string = heap_alloc(len_piece + 1); + MSFT_Read(string, len_piece - sizeof(INT16), pcx, DO_NOT_SEEK); + string[len_str] = '\0'; + + lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, + string, -1, NULL, 0); + if (!lengthInChars) { + heap_free(string); + return E_UNEXPECTED; + } + + tlbstr = heap_alloc(sizeof(TLBString)); + + tlbstr->offset = offs; + tlbstr->str = SysAllocStringByteLen(NULL, lengthInChars * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, tlbstr->str, lengthInChars); + + heap_free(string); + + list_add_tail(&pcx->pLibInfo->string_list, &tlbstr->entry); + + offs += len_piece; + } +} + +static HRESULT MSFT_ReadAllRefs(TLBContext *pcx) +{ + TLBRefType *ref; + int offs = 0; + + MSFT_Seek(pcx, pcx->pTblDir->pImpInfo.offset); + while (offs < pcx->pTblDir->pImpInfo.length) { + MSFT_ImpInfo impinfo; + TLBImpLib *pImpLib; + + MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx, DO_NOT_SEEK); + + ref = heap_alloc_zero(sizeof(TLBRefType)); + list_add_tail(&pcx->pLibInfo->ref_list, &ref->entry); + + LIST_FOR_EACH_ENTRY(pImpLib, &pcx->pLibInfo->implib_list, TLBImpLib, entry) + if(pImpLib->offset==impinfo.oImpFile) + break; + + if(&pImpLib->entry != &pcx->pLibInfo->implib_list){ + ref->reference = offs; + ref->pImpTLInfo = pImpLib; + if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) { + ref->guid = MSFT_ReadGuid(impinfo.oGuid, pcx); + TRACE("importing by guid %s\n", debugstr_guid(TLB_get_guidref(ref->guid))); + ref->index = TLB_REF_USE_GUID; + } else + ref->index = impinfo.oGuid; + }else{ + ERR("Cannot find a reference\n"); + ref->reference = -1; + ref->pImpTLInfo = TLB_REF_NOT_FOUND; + } + + offs += sizeof(impinfo); + } + + return S_OK; +} + /* Because type library parsing has some degree of overhead, and some apps repeatedly load the same * typelibs over and over, we cache them here. According to MSDN Microsoft have a similar scheme in * place. This will cause a deliberate memory leak, but generally losing RAM for cycles is an acceptable @@ -2461,7 +2938,7 @@ static CRITICAL_SECTION cache_section = { &cache_section_debug, -1, 0, 0, 0, 0 } typedef struct TLB_PEFile { - const IUnknownVtbl *lpvtbl; + IUnknown IUnknown_iface; LONG refs; HMODULE dll; HRSRC typelib_resource; @@ -2469,6 +2946,11 @@ typedef struct TLB_PEFile LPVOID typelib_base; } TLB_PEFile; +static inline TLB_PEFile *pefile_impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, TLB_PEFile, IUnknown_iface); +} + static HRESULT WINAPI TLB_PEFile_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { if (IsEqualIID(riid, &IID_IUnknown)) @@ -2483,13 +2965,13 @@ static HRESULT WINAPI TLB_PEFile_QueryInterface(IUnknown *iface, REFIID riid, vo static ULONG WINAPI TLB_PEFile_AddRef(IUnknown *iface) { - TLB_PEFile *This = (TLB_PEFile *)iface; + TLB_PEFile *This = pefile_impl_from_IUnknown(iface); return InterlockedIncrement(&This->refs); } static ULONG WINAPI TLB_PEFile_Release(IUnknown *iface) { - TLB_PEFile *This = (TLB_PEFile *)iface; + TLB_PEFile *This = pefile_impl_from_IUnknown(iface); ULONG refs = InterlockedDecrement(&This->refs); if (!refs) { @@ -2518,7 +3000,7 @@ static HRESULT TLB_PEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *p if (!This) return E_OUTOFMEMORY; - This->lpvtbl = &TLB_PEFile_Vtable; + This->IUnknown_iface.lpVtbl = &TLB_PEFile_Vtable; This->refs = 1; This->dll = NULL; This->typelib_resource = NULL; @@ -2543,7 +3025,7 @@ static HRESULT TLB_PEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *p { *pdwTLBLength = SizeofResource(This->dll, This->typelib_resource); *ppBase = This->typelib_base; - *ppFile = (IUnknown *)&This->lpvtbl; + *ppFile = &This->IUnknown_iface; return S_OK; } } @@ -2553,17 +3035,22 @@ static HRESULT TLB_PEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *p hr = E_FAIL; } - TLB_PEFile_Release((IUnknown *)&This->lpvtbl); + TLB_PEFile_Release(&This->IUnknown_iface); return hr; } typedef struct TLB_NEFile { - const IUnknownVtbl *lpvtbl; + IUnknown IUnknown_iface; LONG refs; LPVOID typelib_base; } TLB_NEFile; +static inline TLB_NEFile *nefile_impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, TLB_NEFile, IUnknown_iface); +} + static HRESULT WINAPI TLB_NEFile_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { if (IsEqualIID(riid, &IID_IUnknown)) @@ -2578,13 +3065,13 @@ static HRESULT WINAPI TLB_NEFile_QueryInterface(IUnknown *iface, REFIID riid, vo static ULONG WINAPI TLB_NEFile_AddRef(IUnknown *iface) { - TLB_NEFile *This = (TLB_NEFile *)iface; + TLB_NEFile *This = nefile_impl_from_IUnknown(iface); return InterlockedIncrement(&This->refs); } static ULONG WINAPI TLB_NEFile_Release(IUnknown *iface) { - TLB_NEFile *This = (TLB_NEFile *)iface; + TLB_NEFile *This = nefile_impl_from_IUnknown(iface); ULONG refs = InterlockedDecrement(&This->refs); if (!refs) { @@ -2741,7 +3228,7 @@ static HRESULT TLB_NEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *p This = heap_alloc(sizeof(TLB_NEFile)); if (!This) return E_OUTOFMEMORY; - This->lpvtbl = &TLB_NEFile_Vtable; + This->IUnknown_iface.lpVtbl = &TLB_NEFile_Vtable; This->refs = 1; This->typelib_base = NULL; @@ -2761,26 +3248,31 @@ static HRESULT TLB_NEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *p LZClose( lzfd ); *ppBase = This->typelib_base; *pdwTLBLength = reslen; - *ppFile = (IUnknown *)&This->lpvtbl; + *ppFile = &This->IUnknown_iface; return S_OK; } } } if( lzfd >= 0) LZClose( lzfd ); - TLB_NEFile_Release((IUnknown *)&This->lpvtbl); + TLB_NEFile_Release(&This->IUnknown_iface); return hr; } typedef struct TLB_Mapping { - const IUnknownVtbl *lpvtbl; + IUnknown IUnknown_iface; LONG refs; HANDLE file; HANDLE mapping; LPVOID typelib_base; } TLB_Mapping; +static inline TLB_Mapping *mapping_impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, TLB_Mapping, IUnknown_iface); +} + static HRESULT WINAPI TLB_Mapping_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { if (IsEqualIID(riid, &IID_IUnknown)) @@ -2795,13 +3287,13 @@ static HRESULT WINAPI TLB_Mapping_QueryInterface(IUnknown *iface, REFIID riid, v static ULONG WINAPI TLB_Mapping_AddRef(IUnknown *iface) { - TLB_Mapping *This = (TLB_Mapping *)iface; + TLB_Mapping *This = mapping_impl_from_IUnknown(iface); return InterlockedIncrement(&This->refs); } static ULONG WINAPI TLB_Mapping_Release(IUnknown *iface) { - TLB_Mapping *This = (TLB_Mapping *)iface; + TLB_Mapping *This = mapping_impl_from_IUnknown(iface); ULONG refs = InterlockedDecrement(&This->refs); if (!refs) { @@ -2831,7 +3323,7 @@ static HRESULT TLB_Mapping_Open(LPCWSTR path, LPVOID *ppBase, DWORD *pdwTLBLengt if (!This) return E_OUTOFMEMORY; - This->lpvtbl = &TLB_Mapping_Vtable; + This->IUnknown_iface.lpVtbl = &TLB_Mapping_Vtable; This->refs = 1; This->file = INVALID_HANDLE_VALUE; This->mapping = NULL; @@ -2849,13 +3341,13 @@ static HRESULT TLB_Mapping_Open(LPCWSTR path, LPVOID *ppBase, DWORD *pdwTLBLengt /* retrieve file size */ *pdwTLBLength = GetFileSize(This->file, NULL); *ppBase = This->typelib_base; - *ppFile = (IUnknown *)&This->lpvtbl; + *ppFile = &This->IUnknown_iface; return S_OK; } } } - IUnknown_Release((IUnknown *)&This->lpvtbl); + IUnknown_Release(&This->IUnknown_iface); return TYPE_E_CANTLOADLIBRARY; } @@ -2876,6 +3368,7 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath LPVOID pBase = NULL; DWORD dwTLBLength = 0; IUnknown *pFile = NULL; + HANDLE h; *ppTypeLib = NULL; @@ -2910,6 +3403,24 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath if(file != pszFileName) heap_free(file); + h = CreateFileW(pszPath, GENERIC_READ, 0, NULL, OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + if(h != INVALID_HANDLE_VALUE){ + FILE_NAME_INFORMATION *info; + char data[MAX_PATH * sizeof(WCHAR) + sizeof(info->FileNameLength)]; + BOOL br; + + info = (FILE_NAME_INFORMATION*)data; + /* GetFileInformationByHandleEx returns the path of the file without + * WOW64 redirection */ + br = GetFileInformationByHandleEx(h, FileNameInfo, data, sizeof(data)); + if(br){ + info->FileName[info->FileNameLength / sizeof(WCHAR)] = 0; + lstrcpynW(pszPath + 2, info->FileName, cchPath - 2); + } + CloseHandle(h); + } + TRACE_(typelib)("File %s index %d\n", debugstr_w(pszPath), index); /* We look the path up in the typelib cache. If found, we just addref it, and return the pointer. */ @@ -2955,7 +3466,7 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath } if(*ppTypeLib) { - ITypeLibImpl *impl = (ITypeLibImpl*)*ppTypeLib; + ITypeLibImpl *impl = impl_from_ITypeLib2(*ppTypeLib); TRACE("adding to cache\n"); impl->path = heap_alloc((strlenW(pszPath)+1) * sizeof(WCHAR)); @@ -2991,11 +3502,15 @@ static ITypeLibImpl* TypeLibImpl_Constructor(void) if (!pTypeLibImpl) return NULL; pTypeLibImpl->ITypeLib2_iface.lpVtbl = &tlbvt; - pTypeLibImpl->lpVtblTypeComp = &tlbtcvt; + pTypeLibImpl->ITypeComp_iface.lpVtbl = &tlbtcvt; + pTypeLibImpl->ICreateTypeLib2_iface.lpVtbl = &CreateTypeLib2Vtbl; pTypeLibImpl->ref = 1; list_init(&pTypeLibImpl->implib_list); list_init(&pTypeLibImpl->custdata_list); + list_init(&pTypeLibImpl->name_list); + list_init(&pTypeLibImpl->string_list); + list_init(&pTypeLibImpl->guid_list); list_init(&pTypeLibImpl->ref_list); pTypeLibImpl->dispatch_href = -1; @@ -3014,6 +3529,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) MSFT_Header tlbHeader; MSFT_SegDir tlbSegDir; ITypeLibImpl * pTypeLibImpl; + int i; TRACE("%p, TLB length = %d\n", pLib, dwTLBLength); @@ -3055,16 +3571,21 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) return NULL; } + MSFT_ReadAllNames(&cx); + MSFT_ReadAllStrings(&cx); + MSFT_ReadAllGuids(&cx); + /* now fill our internal data */ /* TLIBATTR fields */ - MSFT_ReadGuid(&pTypeLibImpl->LibAttr.guid, tlbHeader.posguid, &cx); + pTypeLibImpl->guid = MSFT_ReadGuid(tlbHeader.posguid, &cx); - pTypeLibImpl->LibAttr.lcid = tlbHeader.lcid2; - pTypeLibImpl->LibAttr.syskind = tlbHeader.varflags & 0x0f; /* check the mask */ - pTypeLibImpl->LibAttr.wMajorVerNum = LOWORD(tlbHeader.version); - pTypeLibImpl->LibAttr.wMinorVerNum = HIWORD(tlbHeader.version); - pTypeLibImpl->LibAttr.wLibFlags = (WORD) tlbHeader.flags & 0xffff;/* check mask */ + pTypeLibImpl->syskind = tlbHeader.varflags & 0x0f; /* check the mask */ + pTypeLibImpl->ptr_size = get_ptr_size(pTypeLibImpl->syskind); + pTypeLibImpl->ver_major = LOWORD(tlbHeader.version); + pTypeLibImpl->ver_minor = HIWORD(tlbHeader.version); + pTypeLibImpl->libflags = (WORD) tlbHeader.flags & 0xffff;/* check mask */ + pTypeLibImpl->set_lcid = tlbHeader.lcid2; pTypeLibImpl->lcid = tlbHeader.lcid; /* name, eventually add to a hash table */ @@ -3179,22 +3700,21 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) pImpLib->name = TLB_MultiByteToBSTR(name); heap_free(name); - MSFT_ReadGuid(&pImpLib->guid, oGuid, &cx); + pImpLib->guid = MSFT_ReadGuid(oGuid, &cx); offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & ~3; list_add_tail(&pTypeLibImpl->implib_list, &pImpLib->entry); } } + MSFT_ReadAllRefs(&cx); + pTypeLibImpl->dispatch_href = tlbHeader.dispatchpos; - if(pTypeLibImpl->dispatch_href != -1) - MSFT_DoRefType(&cx, pTypeLibImpl, pTypeLibImpl->dispatch_href); /* type infos */ if(tlbHeader.nrtypeinfos >= 0 ) { ITypeInfoImpl **ppTI; - int i; ppTI = pTypeLibImpl->typeinfos = heap_alloc_zero(sizeof(ITypeInfoImpl*) * tlbHeader.nrtypeinfos); @@ -3207,6 +3727,13 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) } } +#ifdef _WIN64 + if(pTypeLibImpl->syskind == SYS_WIN32){ + for(i = 0; i < pTypeLibImpl->TypeInfoCount; ++i) + TLB_fix_32on64_typeinfo(pTypeLibImpl->typeinfos[i]); + } +#endif + TRACE("(%p)\n", pTypeLibImpl); return &pTypeLibImpl->ITypeLib2_iface; } @@ -3234,18 +3761,23 @@ static BOOL TLB_GUIDFromString(const char *str, GUID *guid) return TRUE; } -static WORD SLTG_ReadString(const char *ptr, BSTR *pBstr) +static WORD SLTG_ReadString(const char *ptr, const TLBString **pStr, ITypeLibImpl *lib) { WORD bytelen; DWORD len; + BSTR tmp_str; - *pBstr = NULL; + *pStr = NULL; bytelen = *(const WORD*)ptr; if(bytelen == 0xffff) return 2; + len = MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, NULL, 0); - *pBstr = SysAllocStringLen(NULL, len); - if (*pBstr) - len = MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, *pBstr, len); + tmp_str = SysAllocStringLen(NULL, len); + if (tmp_str) { + MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, tmp_str, len); + *pStr = TLB_append_str(&lib->string_list, tmp_str); + SysFreeString(tmp_str); + } return bytelen + 2; } @@ -3262,6 +3794,23 @@ static WORD SLTG_ReadStringA(const char *ptr, char **str) return bytelen + 2; } +static TLBString *SLTG_ReadName(const char *pNameTable, int offset, ITypeLibImpl *lib) +{ + BSTR tmp_str; + TLBString *tlbstr; + + LIST_FOR_EACH_ENTRY(tlbstr, &lib->name_list, TLBString, entry) { + if (tlbstr->offset == offset) + return tlbstr; + } + + tmp_str = TLB_MultiByteToBSTR(pNameTable + offset); + tlbstr = TLB_append_str(&lib->name_list, tmp_str); + SysFreeString(tmp_str); + + return tlbstr; +} + static DWORD SLTG_ReadLibBlk(LPVOID pLibBlk, ITypeLibImpl *pTypeLibImpl) { char *ptr = pLibBlk; @@ -3279,34 +3828,35 @@ static DWORD SLTG_ReadLibBlk(LPVOID pLibBlk, ITypeLibImpl *pTypeLibImpl) } ptr += 2; - ptr += SLTG_ReadString(ptr, &pTypeLibImpl->DocString); + ptr += SLTG_ReadString(ptr, &pTypeLibImpl->DocString, pTypeLibImpl); - ptr += SLTG_ReadString(ptr, &pTypeLibImpl->HelpFile); + ptr += SLTG_ReadString(ptr, &pTypeLibImpl->HelpFile, pTypeLibImpl); pTypeLibImpl->dwHelpContext = *(DWORD*)ptr; ptr += 4; - pTypeLibImpl->LibAttr.syskind = *(WORD*)ptr; + pTypeLibImpl->syskind = *(WORD*)ptr; + pTypeLibImpl->ptr_size = get_ptr_size(pTypeLibImpl->syskind); ptr += 2; if(SUBLANGID(*(WORD*)ptr) == SUBLANG_NEUTRAL) - pTypeLibImpl->lcid = pTypeLibImpl->LibAttr.lcid = MAKELCID(MAKELANGID(PRIMARYLANGID(*(WORD*)ptr),0),0); + pTypeLibImpl->lcid = pTypeLibImpl->set_lcid = MAKELCID(MAKELANGID(PRIMARYLANGID(*(WORD*)ptr),0),0); else - pTypeLibImpl->lcid = pTypeLibImpl->LibAttr.lcid = 0; + pTypeLibImpl->lcid = pTypeLibImpl->set_lcid = 0; ptr += 2; ptr += 4; /* skip res12 */ - pTypeLibImpl->LibAttr.wLibFlags = *(WORD*)ptr; + pTypeLibImpl->libflags = *(WORD*)ptr; ptr += 2; - pTypeLibImpl->LibAttr.wMajorVerNum = *(WORD*)ptr; + pTypeLibImpl->ver_major = *(WORD*)ptr; ptr += 2; - pTypeLibImpl->LibAttr.wMinorVerNum = *(WORD*)ptr; + pTypeLibImpl->ver_minor = *(WORD*)ptr; ptr += 2; - memcpy(&pTypeLibImpl->LibAttr.guid, ptr, sizeof(GUID)); + pTypeLibImpl->guid = TLB_append_guid(&pTypeLibImpl->guid_list, (GUID*)ptr, -2); ptr += sizeof(GUID); return ptr - (char*)pLibBlk; @@ -3459,11 +4009,12 @@ static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL, if(&import->entry == &pTL->implib_list) { char fname[MAX_PATH+1]; int len; + GUID tmpguid; import = heap_alloc_zero(sizeof(*import)); import->offset = lib_offs; - TLB_GUIDFromString( pNameTable + lib_offs + 4, - &import->guid); + TLB_GUIDFromString( pNameTable + lib_offs + 4, &tmpguid); + import->guid = TLB_append_guid(&pTL->guid_list, &tmpguid, 2); if(sscanf(pNameTable + lib_offs + 40, "}#%hd.%hd#%x#%s", &import->wVersionMajor, &import->wVersionMinor, @@ -3481,7 +4032,7 @@ static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL, ref_type->pImpTLInfo = import; /* Store a reference to IDispatch */ - if(pTL->dispatch_href == -1 && IsEqualGUID(&import->guid, &IID_StdOle) && type_num == 4) + if(pTL->dispatch_href == -1 && IsEqualGUID(&import->guid->guid, &IID_StdOle) && type_num == 4) pTL->dispatch_href = typelib_ref; } else { /* internal ref */ @@ -3516,14 +4067,14 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI, info = (SLTG_ImplInfo*)pBlk; while(1){ - pTI->TypeAttr.cImplTypes++; + pTI->cImplTypes++; if(info->next == 0xffff) break; info = (SLTG_ImplInfo*)(pBlk + info->next); } info = (SLTG_ImplInfo*)pBlk; - pTI->impltypes = TLBImplType_Constructor(pTI->TypeAttr.cImplTypes); + pTI->impltypes = TLBImplType_Alloc(pTI->cImplTypes); pImplType = pTI->impltypes; while(1) { sltg_get_typelib_ref(ref_lookup, info->ref, &pImplType->hRef); @@ -3544,12 +4095,12 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign const char *pNameTable, const sltg_ref_lookup_t *ref_lookup) { TLBVarDesc *pVarDesc; - BSTR bstrPrevName = NULL; + const TLBString *prevName = NULL; SLTG_Variable *pItem; unsigned short i; WORD *pType; - pVarDesc = pTI->vardescs = TLBVarDesc_Constructor(cVars); + pVarDesc = pTI->vardescs = TLBVarDesc_Alloc(cVars); for(pItem = (SLTG_Variable *)pFirstItem, i = 0; i < cVars; pItem = (SLTG_Variable *)(pBlk + pItem->next), i++, ++pVarDesc) { @@ -3563,11 +4114,11 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign } if (pItem->name == 0xfffe) - pVarDesc->Name = SysAllocString(bstrPrevName); + pVarDesc->Name = prevName; else - pVarDesc->Name = TLB_MultiByteToBSTR(pItem->name + pNameTable); + pVarDesc->Name = SLTG_ReadName(pNameTable, pItem->name, pTI->pTypeLib); - TRACE_(typelib)("name: %s\n", debugstr_w(pVarDesc->Name)); + TRACE_(typelib)("name: %s\n", debugstr_w(TLB_get_bstr(pVarDesc->Name))); TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs); TRACE_(typelib)("memid = 0x%x\n", pItem->memid); @@ -3646,9 +4197,9 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign if (pItem->flags & 0x80) pVarDesc->vardesc.wVarFlags |= VARFLAG_FREADONLY; - bstrPrevName = pVarDesc->Name; + prevName = pVarDesc->Name; } - pTI->TypeAttr.cVars = cVars; + pTI->cVars = cVars; } static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, @@ -3658,7 +4209,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short i; TLBFuncDesc *pFuncDesc; - pTI->funcdescs = TLBFuncDesc_Constructor(cFuncs); + pTI->funcdescs = TLBFuncDesc_Alloc(cFuncs); pFuncDesc = pTI->funcdescs; for(pFunc = (SLTG_Function*)pFirstItem, i = 0; i < cFuncs && pFunc != (SLTG_Function*)0xFFFF; @@ -3681,7 +4232,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, FIXME("unimplemented func magic = %02x\n", pFunc->magic & ~SLTG_FUNCTION_FLAGS_PRESENT); continue; } - pFuncDesc->Name = TLB_MultiByteToBSTR(pFunc->name + pNameTable); + pFuncDesc->Name = SLTG_ReadName(pNameTable, pFunc->name, pTI->pTypeLib); pFuncDesc->funcdesc.memid = pFunc->dispid; pFuncDesc->funcdesc.invkind = pFunc->inv >> 4; @@ -3748,15 +4299,14 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, pFuncDesc->funcdesc.lprgelemdescParam[param].u.paramdesc.wParamFlags |= PARAMFLAG_FOPT; if(paramName) { - pFuncDesc->pParamDesc[param].Name = - TLB_MultiByteToBSTR(paramName); + pFuncDesc->pParamDesc[param].Name = SLTG_ReadName(pNameTable, + paramName - pNameTable, pTI->pTypeLib); } else { - pFuncDesc->pParamDesc[param].Name = - SysAllocString(pFuncDesc->Name); + pFuncDesc->pParamDesc[param].Name = pFuncDesc->Name; } } } - pTI->TypeAttr.cFuncs = cFuncs; + pTI->cFuncs = cFuncs; } static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI, @@ -3804,7 +4354,7 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, heap_free(ref_lookup); if (TRACE_ON(typelib)) - dump_TLBFuncDesc(pTI->funcdescs, pTI->TypeAttr.cFuncs); + dump_TLBFuncDesc(pTI->funcdescs, pTI->cFuncs); } static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI, @@ -3822,9 +4372,10 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, sltg_ref_lookup_t *ref_lookup = NULL; if (pTITail->simple_alias) { - /* if simple alias, no more processing required */ - pTI->TypeAttr.tdescAlias.vt = pTITail->tdescalias_vt; - return; + /* if simple alias, no more processing required */ + pTI->tdescAlias = heap_alloc_zero(sizeof(TYPEDESC)); + pTI->tdescAlias->vt = pTITail->tdescalias_vt; + return; } if(pTIHeader->href_table != 0xffffffff) { @@ -3835,7 +4386,8 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, /* otherwise it is an offset to a type */ pType = (WORD *)(pBlk + pTITail->tdescalias_vt); - SLTG_DoType(pType, pBlk, &pTI->TypeAttr.tdescAlias, ref_lookup); + pTI->tdescAlias = heap_alloc(sizeof(TYPEDESC)); + SLTG_DoType(pType, pBlk, pTI->tdescAlias, ref_lookup); heap_free(ref_lookup); } @@ -3861,11 +4413,11 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, /* this is necessary to cope with MSFT typelibs that set cFuncs to the number * of dispinterface functions including the IDispatch ones, so * ITypeInfo::GetFuncDesc takes the real value for cFuncs from cbSizeVft */ - pTI->TypeAttr.cbSizeVft = pTI->TypeAttr.cFuncs * sizeof(void *); + pTI->cbSizeVft = pTI->cFuncs * pTI->pTypeLib->ptr_size; heap_free(ref_lookup); if (TRACE_ON(typelib)) - dump_TLBFuncDesc(pTI->funcdescs, pTI->TypeAttr.cFuncs); + dump_TLBFuncDesc(pTI->funcdescs, pTI->cFuncs); } static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI, @@ -4065,7 +4617,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) TRACE_(typelib)("Library name is %s\n", pNameTable + pLibBlk->name); - pTypeLibImpl->Name = TLB_MultiByteToBSTR(pNameTable + pLibBlk->name); + pTypeLibImpl->Name = SLTG_ReadName(pNameTable, pLibBlk->name, pTypeLibImpl); /* Hopefully we now have enough ptrs set up to actually read in @@ -4103,19 +4655,17 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) *ppTypeInfoImpl = ITypeInfoImpl_Constructor(); (*ppTypeInfoImpl)->pTypeLib = pTypeLibImpl; (*ppTypeInfoImpl)->index = i; - (*ppTypeInfoImpl)->Name = TLB_MultiByteToBSTR( - pOtherTypeInfoBlks[i].name_offs + - pNameTable); + (*ppTypeInfoImpl)->Name = SLTG_ReadName(pNameTable, pOtherTypeInfoBlks[i].name_offs, pTypeLibImpl); (*ppTypeInfoImpl)->dwHelpContext = pOtherTypeInfoBlks[i].helpcontext; - (*ppTypeInfoImpl)->TypeAttr.guid = pOtherTypeInfoBlks[i].uuid; - (*ppTypeInfoImpl)->TypeAttr.typekind = pTIHeader->typekind; - (*ppTypeInfoImpl)->TypeAttr.wMajorVerNum = pTIHeader->major_version; - (*ppTypeInfoImpl)->TypeAttr.wMinorVerNum = pTIHeader->minor_version; - (*ppTypeInfoImpl)->TypeAttr.wTypeFlags = + (*ppTypeInfoImpl)->guid = TLB_append_guid(&pTypeLibImpl->guid_list, &pOtherTypeInfoBlks[i].uuid, 2); + (*ppTypeInfoImpl)->typekind = pTIHeader->typekind; + (*ppTypeInfoImpl)->wMajorVerNum = pTIHeader->major_version; + (*ppTypeInfoImpl)->wMinorVerNum = pTIHeader->minor_version; + (*ppTypeInfoImpl)->wTypeFlags = (pTIHeader->typeflags1 >> 3) | (pTIHeader->typeflags2 << 5); - if((*ppTypeInfoImpl)->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL) - (*ppTypeInfoImpl)->TypeAttr.typekind = TKIND_DISPATCH; + if((*ppTypeInfoImpl)->wTypeFlags & TYPEFLAG_FDUAL) + (*ppTypeInfoImpl)->typekind = TKIND_DISPATCH; if((pTIHeader->typeflags1 & 7) != 2) FIXME_(typelib)("typeflags1 = %02x\n", pTIHeader->typeflags1); @@ -4123,18 +4673,18 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) FIXME_(typelib)("typeflags3 = %02x\n", pTIHeader->typeflags3); TRACE_(typelib)("TypeInfo %s of kind %s guid %s typeflags %04x\n", - debugstr_w((*ppTypeInfoImpl)->Name), + debugstr_w(TLB_get_bstr((*ppTypeInfoImpl)->Name)), typekind_desc[pTIHeader->typekind], - debugstr_guid(&(*ppTypeInfoImpl)->TypeAttr.guid), - (*ppTypeInfoImpl)->TypeAttr.wTypeFlags); + debugstr_guid(TLB_get_guidref((*ppTypeInfoImpl)->guid)), + (*ppTypeInfoImpl)->wTypeFlags); pMemHeader = (SLTG_MemberHeader*)((char *)pBlk + pTIHeader->elem_table); pTITail = (SLTG_TypeInfoTail*)((char *)(pMemHeader + 1) + pMemHeader->cbExtra); - (*ppTypeInfoImpl)->TypeAttr.cbAlignment = pTITail->cbAlignment; - (*ppTypeInfoImpl)->TypeAttr.cbSizeInstance = pTITail->cbSizeInstance; - (*ppTypeInfoImpl)->TypeAttr.cbSizeVft = pTITail->cbSizeVft; + (*ppTypeInfoImpl)->cbAlignment = pTITail->cbAlignment; + (*ppTypeInfoImpl)->cbSizeInstance = pTITail->cbSizeInstance; + (*ppTypeInfoImpl)->cbSizeVft = pTITail->cbSizeVft; switch(pTIHeader->typekind) { case TKIND_ENUM: @@ -4209,11 +4759,6 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) return &pTypeLibImpl->ITypeLib2_iface; } -static inline ITypeLibImpl *impl_from_ITypeLib2(ITypeLib2 *iface) -{ - return CONTAINING_RECORD(iface, ITypeLibImpl, ITypeLib2_iface); -} - static HRESULT WINAPI ITypeLib2_fnQueryInterface(ITypeLib2 *iface, REFIID riid, void **ppv) { ITypeLibImpl *This = impl_from_ITypeLib2(iface); @@ -4226,6 +4771,11 @@ static HRESULT WINAPI ITypeLib2_fnQueryInterface(ITypeLib2 *iface, REFIID riid, { *ppv = &This->ITypeLib2_iface; } + else if(IsEqualIID(riid, &IID_ICreateTypeLib) || + IsEqualIID(riid, &IID_ICreateTypeLib2)) + { + *ppv = &This->ICreateTypeLib2_iface; + } else { *ppv = NULL; @@ -4258,6 +4808,8 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface) { TLBImpLib *pImpLib, *pImpLibNext; TLBRefType *ref_type; + TLBString *tlbstr, *tlbstr_next; + TLBGuid *tlbguid, *tlbguid_next; void *cursor2; int i; @@ -4273,17 +4825,22 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface) } TRACE(" destroying ITypeLib(%p)\n",This); - SysFreeString(This->Name); - This->Name = NULL; + LIST_FOR_EACH_ENTRY_SAFE(tlbstr, tlbstr_next, &This->string_list, TLBString, entry) { + list_remove(&tlbstr->entry); + SysFreeString(tlbstr->str); + heap_free(tlbstr); + } - SysFreeString(This->DocString); - This->DocString = NULL; + LIST_FOR_EACH_ENTRY_SAFE(tlbstr, tlbstr_next, &This->name_list, TLBString, entry) { + list_remove(&tlbstr->entry); + SysFreeString(tlbstr->str); + heap_free(tlbstr); + } - SysFreeString(This->HelpFile); - This->HelpFile = NULL; - - SysFreeString(This->HelpStringDll); - This->HelpStringDll = NULL; + LIST_FOR_EACH_ENTRY_SAFE(tlbguid, tlbguid_next, &This->guid_list, TLBGuid, entry) { + list_remove(&tlbguid->entry); + heap_free(tlbguid); + } TLB_FreeCustData(&This->custdata_list); @@ -4309,8 +4866,10 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface) heap_free(ref_type); } - for (i = 0; i < This->TypeInfoCount; ++i) + for (i = 0; i < This->TypeInfoCount; ++i){ + heap_free(This->typeinfos[i]->tdescAlias); ITypeInfoImpl_Destroy(This->typeinfos[i]); + } heap_free(This->typeinfos); heap_free(This); return 0; @@ -4349,7 +4908,7 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeInfo( if(index >= This->TypeInfoCount) return TYPE_E_ELEMENTNOTFOUND; - *ppTInfo = (ITypeInfo*)This->typeinfos[index]; + *ppTInfo = (ITypeInfo *)&This->typeinfos[index]->ITypeInfo2_iface; ITypeInfo_AddRef(*ppTInfo); return S_OK; @@ -4375,7 +4934,7 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType( if(index >= This->TypeInfoCount) return TYPE_E_ELEMENTNOTFOUND; - *pTKind = This->typeinfos[index]->TypeAttr.typekind; + *pTKind = This->typeinfos[index]->typekind; return S_OK; } @@ -4396,8 +4955,8 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid( TRACE("%p %s %p\n", This, debugstr_guid(guid), ppTInfo); for(i = 0; i < This->TypeInfoCount; ++i){ - if(IsEqualIID(&This->typeinfos[i]->TypeAttr.guid, guid)){ - *ppTInfo = (ITypeInfo*)This->typeinfos[i]; + if(IsEqualIID(TLB_get_guid_null(This->typeinfos[i]->guid), guid)){ + *ppTInfo = (ITypeInfo *)&This->typeinfos[i]->ITypeInfo2_iface; ITypeInfo_AddRef(*ppTInfo); return S_OK; } @@ -4424,7 +4983,13 @@ static HRESULT WINAPI ITypeLib2_fnGetLibAttr( *attr = heap_alloc(sizeof(**attr)); if (!*attr) return E_OUTOFMEMORY; - **attr = This->LibAttr; + (*attr)->guid = *TLB_get_guid_null(This->guid); + (*attr)->lcid = This->set_lcid; + (*attr)->syskind = This->syskind; + (*attr)->wMajorVerNum = This->ver_major; + (*attr)->wMinorVerNum = This->ver_minor; + (*attr)->wLibFlags = This->libflags; + return S_OK; } @@ -4441,7 +5006,7 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeComp( ITypeLibImpl *This = impl_from_ITypeLib2(iface); TRACE("(%p)->(%p)\n",This,ppTComp); - *ppTComp = (ITypeComp *)&This->lpVtblTypeComp; + *ppTComp = &This->ITypeComp_iface; ITypeComp_AddRef(*ppTComp); return S_OK; @@ -4480,7 +5045,7 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation( { if (This->Name) { - if(!(*pBstrName = SysAllocString(This->Name))) + if(!(*pBstrName = SysAllocString(TLB_get_bstr(This->Name)))) goto memerr1; } else @@ -4490,12 +5055,7 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation( { if (This->DocString) { - if(!(*pBstrDocString = SysAllocString(This->DocString))) - goto memerr2; - } - else if (This->Name) - { - if(!(*pBstrDocString = SysAllocString(This->Name))) + if(!(*pBstrDocString = SysAllocString(TLB_get_bstr(This->DocString)))) goto memerr2; } else @@ -4509,7 +5069,7 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation( { if (This->HelpFile) { - if(!(*pBstrHelpFile = SysAllocString(This->HelpFile))) + if(!(*pBstrHelpFile = SysAllocString(TLB_get_bstr(This->HelpFile)))) goto memerr3; } else @@ -4565,19 +5125,19 @@ static HRESULT WINAPI ITypeLib2_fnIsName( *pfName=TRUE; for(tic = 0; tic < This->TypeInfoCount; ++tic){ ITypeInfoImpl *pTInfo = This->typeinfos[tic]; - if(!memcmp(szNameBuf,pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; - for(fdc = 0; fdc < pTInfo->TypeAttr.cFuncs; ++fdc) { + if(!TLB_str_memcmp(szNameBuf, pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; + for(fdc = 0; fdc < pTInfo->cFuncs; ++fdc) { TLBFuncDesc *pFInfo = &pTInfo->funcdescs[fdc]; int pc; - - if(!memcmp(szNameBuf,pFInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; - for(pc=0; pc < pFInfo->funcdesc.cParams; pc++) - if(!memcmp(szNameBuf,pFInfo->pParamDesc[pc].Name, nNameBufLen)) + if(!TLB_str_memcmp(szNameBuf, pFInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; + for(pc=0; pc < pFInfo->funcdesc.cParams; pc++){ + if(!TLB_str_memcmp(szNameBuf, pFInfo->pParamDesc[pc].Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; + } } - for(vrc = 0; vrc < pTInfo->TypeAttr.cVars; ++vrc){ + for(vrc = 0; vrc < pTInfo->cVars; ++vrc){ TLBVarDesc *pVInfo = &pTInfo->vardescs[vrc]; - if(!memcmp(szNameBuf,pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; + if(!TLB_str_memcmp(szNameBuf, pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; } } @@ -4620,26 +5180,26 @@ static HRESULT WINAPI ITypeLib2_fnFindName( TLBVarDesc *var; UINT fdc; - if(!memcmp(name, pTInfo->Name, len)) goto ITypeLib2_fnFindName_exit; - for(fdc = 0; fdc < pTInfo->TypeAttr.cFuncs; ++fdc) { + if(!TLB_str_memcmp(name, pTInfo->Name, len)) goto ITypeLib2_fnFindName_exit; + for(fdc = 0; fdc < pTInfo->cFuncs; ++fdc) { TLBFuncDesc *func = &pTInfo->funcdescs[fdc]; int pc; - if(!memcmp(name, func->Name, len)) goto ITypeLib2_fnFindName_exit; + if(!TLB_str_memcmp(name, func->Name, len)) goto ITypeLib2_fnFindName_exit; for(pc = 0; pc < func->funcdesc.cParams; pc++) { - if(!memcmp(name, func->pParamDesc[pc].Name, len)) + if(!TLB_str_memcmp(name, func->pParamDesc[pc].Name, len)) goto ITypeLib2_fnFindName_exit; } } - var = TLB_get_vardesc_by_name(pTInfo->vardescs, pTInfo->TypeAttr.cVars, name); + var = TLB_get_vardesc_by_name(pTInfo->vardescs, pTInfo->cVars, name); if (var) goto ITypeLib2_fnFindName_exit; continue; ITypeLib2_fnFindName_exit: - ITypeInfo_AddRef((ITypeInfo*)pTInfo); - ppTInfo[count]=(LPTYPEINFO)pTInfo; + ITypeInfo2_AddRef(&pTInfo->ITypeInfo2_iface); + ppTInfo[count] = (ITypeInfo *)&pTInfo->ITypeInfo2_iface; count++; } TRACE("found %d typeinfos\n", count); @@ -4736,11 +5296,11 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( { /* documentation for the typelib */ if(pbstrHelpString) - *pbstrHelpString=SysAllocString(This->DocString); + *pbstrHelpString=SysAllocString(TLB_get_bstr(This->DocString)); if(pdwHelpStringContext) *pdwHelpStringContext=This->dwHelpContext; if(pbstrHelpStringDll) - *pbstrHelpStringDll=SysAllocString(This->HelpStringDll); + *pbstrHelpStringDll=SysAllocString(TLB_get_bstr(This->HelpStringDll)); result = S_OK; } @@ -4790,7 +5350,7 @@ static HRESULT TLB_copy_all_custdata(struct list *custdata_list, CUSTDATA *pCust cdi = pCustData->prgCustData; LIST_FOR_EACH_ENTRY(pCData, custdata_list, TLBCustData, entry){ - cdi->guid = pCData->guid; + cdi->guid = *TLB_get_guid_null(pCData->guid); VariantCopy(&cdi->varValue, &pCData->data); ++cdi; } @@ -4876,28 +5436,28 @@ static HRESULT WINAPI ITypeLibComp_fnBind( for(i = 0; i < This->TypeInfoCount; ++i){ ITypeInfoImpl *pTypeInfo = This->typeinfos[i]; - TRACE("testing %s\n", debugstr_w(pTypeInfo->Name)); + TRACE("testing %s\n", debugstr_w(TLB_get_bstr(pTypeInfo->Name))); /* FIXME: check wFlags here? */ /* FIXME: we should use a hash table to look this info up using lHash * instead of an O(n) search */ - if ((pTypeInfo->TypeAttr.typekind == TKIND_ENUM) || - (pTypeInfo->TypeAttr.typekind == TKIND_MODULE)) + if ((pTypeInfo->typekind == TKIND_ENUM) || + (pTypeInfo->typekind == TKIND_MODULE)) { - if (pTypeInfo->Name && !strcmpW(pTypeInfo->Name, szName)) + if (pTypeInfo->Name && !strcmpW(pTypeInfo->Name->str, szName)) { *pDescKind = DESCKIND_TYPECOMP; - pBindPtr->lptcomp = (ITypeComp *)&pTypeInfo->lpVtblTypeComp; + pBindPtr->lptcomp = &pTypeInfo->ITypeComp_iface; ITypeComp_AddRef(pBindPtr->lptcomp); TRACE("module or enum: %s\n", debugstr_w(szName)); return S_OK; } } - if ((pTypeInfo->TypeAttr.typekind == TKIND_MODULE) || - (pTypeInfo->TypeAttr.typekind == TKIND_ENUM)) + if ((pTypeInfo->typekind == TKIND_MODULE) || + (pTypeInfo->typekind == TKIND_ENUM)) { - ITypeComp *pSubTypeComp = (ITypeComp *)&pTypeInfo->lpVtblTypeComp; + ITypeComp *pSubTypeComp = &pTypeInfo->ITypeComp_iface; HRESULT hr; hr = ITypeComp_Bind(pSubTypeComp, szName, lHash, wFlags, ppTInfo, pDescKind, pBindPtr); @@ -4910,10 +5470,10 @@ static HRESULT WINAPI ITypeLibComp_fnBind( typemismatch = 1; } - if ((pTypeInfo->TypeAttr.typekind == TKIND_COCLASS) && - (pTypeInfo->TypeAttr.wTypeFlags & TYPEFLAG_FAPPOBJECT)) + if ((pTypeInfo->typekind == TKIND_COCLASS) && + (pTypeInfo->wTypeFlags & TYPEFLAG_FAPPOBJECT)) { - ITypeComp *pSubTypeComp = (ITypeComp *)&pTypeInfo->lpVtblTypeComp; + ITypeComp *pSubTypeComp = &pTypeInfo->ITypeComp_iface; HRESULT hr; ITypeInfo *subtypeinfo; BINDPTR subbindptr; @@ -4973,7 +5533,7 @@ static HRESULT WINAPI ITypeLibComp_fnBind( return hr; *pDescKind = DESCKIND_IMPLICITAPPOBJ; - *ppTInfo = (ITypeInfo *)pTypeInfo; + *ppTInfo = (ITypeInfo *)&pTypeInfo->ITypeInfo2_iface; ITypeInfo_AddRef(*ppTInfo); return S_OK; } @@ -5002,31 +5562,25 @@ static HRESULT WINAPI ITypeLibComp_fnBindType( ITypeComp ** ppTComp) { ITypeLibImpl *This = impl_from_ITypeComp(iface); - int i; + ITypeInfoImpl *info; TRACE("(%s, %x, %p, %p)\n", debugstr_w(szName), lHash, ppTInfo, ppTComp); if(!szName || !ppTInfo || !ppTComp) return E_INVALIDARG; - for(i = 0; i < This->TypeInfoCount; ++i) - { - ITypeInfoImpl *pTypeInfo = This->typeinfos[i]; - /* FIXME: should use lHash to do the search */ - if (pTypeInfo->Name && !strcmpiW(pTypeInfo->Name, szName)) - { - TRACE("returning %p\n", pTypeInfo); - *ppTInfo = (ITypeInfo *)&pTypeInfo->lpVtbl; - ITypeInfo_AddRef(*ppTInfo); - *ppTComp = (ITypeComp *)&pTypeInfo->lpVtblTypeComp; - ITypeComp_AddRef(*ppTComp); - return S_OK; - } + info = TLB_get_typeinfo_by_name(This->typeinfos, This->TypeInfoCount, szName); + if(!info){ + *ppTInfo = NULL; + *ppTComp = NULL; + return S_OK; } - TRACE("not found\n"); - *ppTInfo = NULL; - *ppTComp = NULL; + *ppTInfo = (ITypeInfo *)&info->ITypeInfo2_iface; + ITypeInfo_AddRef(*ppTInfo); + *ppTComp = &info->ITypeComp_iface; + ITypeComp_AddRef(*ppTComp); + return S_OK; } @@ -5049,13 +5603,15 @@ static ITypeInfoImpl* ITypeInfoImpl_Constructor(void) pTypeInfoImpl = heap_alloc_zero(sizeof(ITypeInfoImpl)); if (pTypeInfoImpl) { - pTypeInfoImpl->lpVtbl = &tinfvt; - pTypeInfoImpl->lpVtblTypeComp = &tcompvt; + pTypeInfoImpl->ITypeInfo2_iface.lpVtbl = &tinfvt; + pTypeInfoImpl->ITypeComp_iface.lpVtbl = &tcompvt; + pTypeInfoImpl->ICreateTypeInfo2_iface.lpVtbl = &CreateTypeInfo2Vtbl; pTypeInfoImpl->ref = 0; pTypeInfoImpl->hreftype = -1; - pTypeInfoImpl->TypeAttr.memidConstructor = MEMBERID_NIL; - pTypeInfoImpl->TypeAttr.memidDestructor = MEMBERID_NIL; - list_init(&pTypeInfoImpl->custdata_list); + pTypeInfoImpl->memidConstructor = MEMBERID_NIL; + pTypeInfoImpl->memidDestructor = MEMBERID_NIL; + pTypeInfoImpl->pcustdata_list = &pTypeInfoImpl->custdata_list; + list_init(pTypeInfoImpl->pcustdata_list); } TRACE("(%p)\n", pTypeInfoImpl); return pTypeInfoImpl; @@ -5068,7 +5624,7 @@ static HRESULT WINAPI ITypeInfo_fnQueryInterface( REFIID riid, VOID **ppvObject) { - ITypeLibImpl *This = (ITypeLibImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid)); @@ -5077,6 +5633,9 @@ static HRESULT WINAPI ITypeInfo_fnQueryInterface( IsEqualIID(riid,&IID_ITypeInfo)|| IsEqualIID(riid,&IID_ITypeInfo2)) *ppvObject = This; + else if(IsEqualIID(riid, &IID_ICreateTypeInfo) || + IsEqualIID(riid, &IID_ICreateTypeInfo2)) + *ppvObject = &This->ICreateTypeInfo2_iface; if(*ppvObject){ ITypeInfo2_AddRef(iface); @@ -5091,7 +5650,7 @@ static HRESULT WINAPI ITypeInfo_fnQueryInterface( */ static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); ULONG ref = InterlockedIncrement(&This->ref); TRACE("(%p)->ref is %u\n",This, ref); @@ -5108,16 +5667,7 @@ static void ITypeInfoImpl_Destroy(ITypeInfoImpl *This) TRACE("destroying ITypeInfo(%p)\n",This); - SysFreeString(This->Name); - This->Name = NULL; - - SysFreeString(This->DocString); - This->DocString = NULL; - - SysFreeString(This->DllName); - This->DllName = NULL; - - for (i = 0; i < This->TypeAttr.cFuncs; ++i) + for (i = 0; i < This->cFuncs; ++i) { int j; TLBFuncDesc *pFInfo = &This->funcdescs[i]; @@ -5125,39 +5675,30 @@ static void ITypeInfoImpl_Destroy(ITypeInfoImpl *This) { ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[j]; if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) - { VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue); - heap_free(elemdesc->u.paramdesc.pparamdescex); - } TLB_FreeCustData(&pFInfo->pParamDesc[j].custdata_list); - SysFreeString(pFInfo->pParamDesc[j].Name); } heap_free(pFInfo->funcdesc.lprgelemdescParam); heap_free(pFInfo->pParamDesc); TLB_FreeCustData(&pFInfo->custdata_list); - if (!IS_INTRESOURCE(pFInfo->Entry) && pFInfo->Entry != (BSTR)-1) - SysFreeString(pFInfo->Entry); - SysFreeString(pFInfo->HelpString); - SysFreeString(pFInfo->Name); } heap_free(This->funcdescs); - for(i = 0; i < This->TypeAttr.cVars; ++i) + for(i = 0; i < This->cVars; ++i) { TLBVarDesc *pVInfo = &This->vardescs[i]; - if (pVInfo->vardesc.varkind == VAR_CONST) - { + if (pVInfo->vardesc_create) { + TLB_FreeVarDesc(pVInfo->vardesc_create); + } else if (pVInfo->vardesc.varkind == VAR_CONST) { VariantClear(pVInfo->vardesc.u.lpvarValue); heap_free(pVInfo->vardesc.u.lpvarValue); } TLB_FreeCustData(&pVInfo->custdata_list); - SysFreeString(pVInfo->Name); - SysFreeString(pVInfo->HelpString); } heap_free(This->vardescs); if(This->impltypes){ - for (i = 0; i < This->TypeAttr.cImplTypes; ++i){ + for (i = 0; i < This->cImplTypes; ++i){ TLBImplType *pImpl = &This->impltypes[i]; TLB_FreeCustData(&pImpl->custdata_list); } @@ -5173,7 +5714,7 @@ static void ITypeInfoImpl_Destroy(ITypeInfoImpl *This) */ static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p)->(%u)\n",This, ref); @@ -5199,28 +5740,47 @@ static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface) static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface, LPTYPEATTR *ppTypeAttr) { - const ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); SIZE_T size; TRACE("(%p)\n",This); size = sizeof(**ppTypeAttr); - if (This->TypeAttr.typekind == TKIND_ALIAS) - size += TLB_SizeTypeDesc(&This->TypeAttr.tdescAlias, FALSE); + if (This->typekind == TKIND_ALIAS && This->tdescAlias) + size += TLB_SizeTypeDesc(This->tdescAlias, FALSE); *ppTypeAttr = heap_alloc(size); if (!*ppTypeAttr) return E_OUTOFMEMORY; - **ppTypeAttr = This->TypeAttr; + (*ppTypeAttr)->guid = *TLB_get_guid_null(This->guid); + (*ppTypeAttr)->lcid = This->lcid; + (*ppTypeAttr)->memidConstructor = This->memidConstructor; + (*ppTypeAttr)->memidDestructor = This->memidDestructor; + (*ppTypeAttr)->lpstrSchema = This->lpstrSchema; + (*ppTypeAttr)->cbSizeInstance = This->cbSizeInstance; + (*ppTypeAttr)->typekind = This->typekind; + (*ppTypeAttr)->cFuncs = This->cFuncs; + (*ppTypeAttr)->cVars = This->cVars; + (*ppTypeAttr)->cImplTypes = This->cImplTypes; + (*ppTypeAttr)->cbSizeVft = This->cbSizeVft; + (*ppTypeAttr)->cbAlignment = This->cbAlignment; + (*ppTypeAttr)->wTypeFlags = This->wTypeFlags; + (*ppTypeAttr)->wMajorVerNum = This->wMajorVerNum; + (*ppTypeAttr)->wMinorVerNum = This->wMinorVerNum; + (*ppTypeAttr)->idldescType = This->idldescType; - if (This->TypeAttr.typekind == TKIND_ALIAS) + if (This->tdescAlias) TLB_CopyTypeDesc(&(*ppTypeAttr)->tdescAlias, - &This->TypeAttr.tdescAlias, *ppTypeAttr + 1); + This->tdescAlias, *ppTypeAttr + 1); + else{ + (*ppTypeAttr)->tdescAlias.vt = VT_EMPTY; + (*ppTypeAttr)->tdescAlias.u.lptdesc = NULL; + } if((*ppTypeAttr)->typekind == TKIND_DISPATCH) { /* This should include all the inherited funcs */ - (*ppTypeAttr)->cFuncs = (*ppTypeAttr)->cbSizeVft / sizeof(void *); + (*ppTypeAttr)->cFuncs = (*ppTypeAttr)->cbSizeVft / This->pTypeLib->ptr_size; /* This is always the size of IDispatch's vtbl */ (*ppTypeAttr)->cbSizeVft = sizeof(IDispatchVtbl); (*ppTypeAttr)->wTypeFlags &= ~TYPEFLAG_FOLEAUTOMATION; @@ -5237,11 +5797,11 @@ static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface, static HRESULT WINAPI ITypeInfo_fnGetTypeComp( ITypeInfo2 *iface, ITypeComp * *ppTComp) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TRACE("(%p)->(%p)\n", This, ppTComp); - *ppTComp = (ITypeComp *)&This->lpVtblTypeComp; + *ppTComp = &This->ITypeComp_iface; ITypeComp_AddRef(*ppTComp); return S_OK; } @@ -5264,6 +5824,7 @@ static HRESULT TLB_CopyElemDesc( const ELEMDESC *src, ELEMDESC *dest, char **buf PARAMDESCEX *pparamdescex_dest = dest->u.paramdesc.pparamdescex = (PARAMDESCEX *)*buffer; *buffer += sizeof(PARAMDESCEX); *pparamdescex_dest = *pparamdescex_src; + pparamdescex_dest->cBytes = sizeof(PARAMDESCEX); VariantInit(&pparamdescex_dest->varDefaultValue); return VariantCopy(&pparamdescex_dest->varDefaultValue, (VARIANTARG *)&pparamdescex_src->varDefaultValue); @@ -5273,6 +5834,27 @@ static HRESULT TLB_CopyElemDesc( const ELEMDESC *src, ELEMDESC *dest, char **buf return S_OK; } +static HRESULT TLB_SanitizeBSTR(BSTR str) +{ + UINT len = SysStringLen(str), i; + for (i = 0; i < len; ++i) + if (str[i] > 0x7f) + str[i] = '?'; + return S_OK; +} + +static HRESULT TLB_SanitizeVariant(VARIANT *var) +{ + if (V_VT(var) == VT_INT) + return VariantChangeType(var, var, 0, VT_I4); + else if (V_VT(var) == VT_UINT) + return VariantChangeType(var, var, 0, VT_UI4); + else if (V_VT(var) == VT_BSTR) + return TLB_SanitizeBSTR(V_BSTR(var)); + + return S_OK; +} + static void TLB_FreeElemDesc( ELEMDESC *elemdesc ) { if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) @@ -5303,9 +5885,14 @@ static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_pt dest->funckind = FUNC_DISPATCH; buffer = (char *)(dest + 1); - dest->lprgscode = (SCODE *)buffer; - memcpy(dest->lprgscode, src->lprgscode, sizeof(*src->lprgscode) * src->cScodes); - buffer += sizeof(*src->lprgscode) * src->cScodes; + dest->oVft = dest->oVft & 0xFFFC; + + if (dest->cScodes) { + dest->lprgscode = (SCODE *)buffer; + memcpy(dest->lprgscode, src->lprgscode, sizeof(*src->lprgscode) * src->cScodes); + buffer += sizeof(*src->lprgscode) * src->cScodes; + } else + dest->lprgscode = NULL; hr = TLB_CopyElemDesc(&src->elemdescFunc, &dest->elemdescFunc, &buffer); if (FAILED(hr)) @@ -5314,23 +5901,26 @@ static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_pt return hr; } - dest->lprgelemdescParam = (ELEMDESC *)buffer; - buffer += sizeof(ELEMDESC) * src->cParams; - for (i = 0; i < src->cParams; i++) - { - hr = TLB_CopyElemDesc(&src->lprgelemdescParam[i], &dest->lprgelemdescParam[i], &buffer); + if (dest->cParams) { + dest->lprgelemdescParam = (ELEMDESC *)buffer; + buffer += sizeof(ELEMDESC) * src->cParams; + for (i = 0; i < src->cParams; i++) + { + hr = TLB_CopyElemDesc(&src->lprgelemdescParam[i], &dest->lprgelemdescParam[i], &buffer); + if (FAILED(hr)) + break; + } if (FAILED(hr)) - break; - } - if (FAILED(hr)) - { - /* undo the above actions */ - for (i = i - 1; i >= 0; i--) - TLB_FreeElemDesc(&dest->lprgelemdescParam[i]); - TLB_FreeElemDesc(&dest->elemdescFunc); - SysFreeString((BSTR)dest); - return hr; - } + { + /* undo the above actions */ + for (i = i - 1; i >= 0; i--) + TLB_FreeElemDesc(&dest->lprgelemdescParam[i]); + TLB_FreeElemDesc(&dest->elemdescFunc); + SysFreeString((BSTR)dest); + return hr; + } + } else + dest->lprgelemdescParam = NULL; /* special treatment for dispinterfaces: this makes functions appear * to return their [retval] value when it is really returning an @@ -5368,11 +5958,19 @@ static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_pt return S_OK; } +static void TLB_FreeVarDesc(VARDESC *var_desc) +{ + TLB_FreeElemDesc(&var_desc->elemdescVar); + if (var_desc->varkind == VAR_CONST) + VariantClear(var_desc->u.lpvarValue); + SysFreeString((BSTR)var_desc); +} + HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc ) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo(iface); - if (index >= This->TypeAttr.cFuncs) + if (index >= This->cFuncs) return TYPE_E_ELEMENTNOTFOUND; *ppFuncDesc = &This->funcdescs[index].funcdesc; @@ -5384,7 +5982,7 @@ HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const F static HRESULT ITypeInfoImpl_GetInternalDispatchFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc, UINT *funcs, UINT *hrefoffset) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo(iface); HRESULT hr; UINT implemented_funcs = 0; @@ -5414,7 +6012,7 @@ static HRESULT ITypeInfoImpl_GetInternalDispatchFuncDesc( ITypeInfo *iface, } if (funcs) - *funcs = implemented_funcs + This->TypeAttr.cFuncs; + *funcs = implemented_funcs + This->cFuncs; else *hrefoffset = 0; @@ -5464,14 +6062,20 @@ static inline void ITypeInfoImpl_FuncDescAddHrefOffset( LPFUNCDESC pFuncDesc, UI static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( ITypeInfo2 *iface, UINT index, LPFUNCDESC *ppFuncDesc) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); const FUNCDESC *internal_funcdesc; HRESULT hr; UINT hrefoffset = 0; TRACE("(%p) index %d\n", This, index); - if (This->TypeAttr.typekind == TKIND_DISPATCH) + if (!ppFuncDesc) + return E_INVALIDARG; + + if (This->needs_layout) + ICreateTypeInfo2_LayOut(&This->ICreateTypeInfo2_iface); + + if (This->typekind == TKIND_DISPATCH) hr = ITypeInfoImpl_GetInternalDispatchFuncDesc((ITypeInfo *)iface, index, &internal_funcdesc, NULL, &hrefoffset); @@ -5487,9 +6091,9 @@ static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( ITypeInfo2 *iface, UINT index, hr = TLB_AllocAndInitFuncDesc( internal_funcdesc, ppFuncDesc, - This->TypeAttr.typekind == TKIND_DISPATCH); + This->typekind == TKIND_DISPATCH); - if ((This->TypeAttr.typekind == TKIND_DISPATCH) && hrefoffset) + if ((This->typekind == TKIND_DISPATCH) && hrefoffset) ITypeInfoImpl_FuncDescAddHrefOffset(*ppFuncDesc, hrefoffset); TRACE("-- 0x%08x\n", hr); @@ -5557,14 +6161,17 @@ static HRESULT TLB_AllocAndInitVarDesc( const VARDESC *src, VARDESC **dest_ptr ) static HRESULT WINAPI ITypeInfo_fnGetVarDesc( ITypeInfo2 *iface, UINT index, LPVARDESC *ppVarDesc) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); const TLBVarDesc *pVDesc = &This->vardescs[index]; TRACE("(%p) index %d\n", This, index); - if(index >= This->TypeAttr.cVars) + if(index >= This->cVars) return TYPE_E_ELEMENTNOTFOUND; + if (This->needs_layout) + ICreateTypeInfo2_LayOut(&This->ICreateTypeInfo2_iface); + return TLB_AllocAndInitVarDesc(&pVDesc->vardesc, ppVarDesc); } @@ -5577,36 +6184,45 @@ static HRESULT WINAPI ITypeInfo_fnGetVarDesc( ITypeInfo2 *iface, UINT index, static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid, BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); const TLBFuncDesc *pFDesc; const TLBVarDesc *pVDesc; int i; TRACE("(%p) memid=0x%08x Maxname=%d\n", This, memid, cMaxNames); - pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->TypeAttr.cFuncs, memid); + + if(!rgBstrNames) + return E_INVALIDARG; + + *pcNames = 0; + + pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->cFuncs, memid); if(pFDesc) { - /* function found, now return function and parameter names */ - for(i=0; ifuncdesc.cParams; i++) - { - if(!i) - *rgBstrNames=SysAllocString(pFDesc->Name); - else - rgBstrNames[i]=SysAllocString(pFDesc->pParamDesc[i-1].Name); - } - *pcNames=i; + if(!cMaxNames || !pFDesc->Name) + return S_OK; + + *rgBstrNames = SysAllocString(TLB_get_bstr(pFDesc->Name)); + ++(*pcNames); + + for(i = 0; i < pFDesc->funcdesc.cParams; ++i){ + if(*pcNames >= cMaxNames || !pFDesc->pParamDesc[i].Name) + return S_OK; + rgBstrNames[*pcNames] = SysAllocString(TLB_get_bstr(pFDesc->pParamDesc[i].Name)); + ++(*pcNames); + } + return S_OK; + } + + pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->cVars, memid); + if(pVDesc) + { + *rgBstrNames=SysAllocString(TLB_get_bstr(pVDesc->Name)); + *pcNames=1; } else { - pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->TypeAttr.cVars, memid); - if(pVDesc) - { - *rgBstrNames=SysAllocString(pVDesc->Name); - *pcNames=1; - } - else - { if(This->impltypes && - (This->TypeAttr.typekind==TKIND_INTERFACE || This->TypeAttr.typekind==TKIND_DISPATCH)) { + (This->typekind==TKIND_INTERFACE || This->typekind==TKIND_DISPATCH)) { /* recursive search */ ITypeInfo *pTInfo; HRESULT result; @@ -5625,7 +6241,6 @@ static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid, } *pcNames=0; return TYPE_E_ELEMENTNOTFOUND; - } } return S_OK; } @@ -5644,7 +6259,7 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( UINT index, HREFTYPE *pRefType) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); HRESULT hr = S_OK; TRACE("(%p) index %d\n", This, index); @@ -5655,28 +6270,30 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( /* only valid on dual interfaces; retrieve the associated TKIND_INTERFACE handle for the current TKIND_DISPATCH */ - if( This->TypeAttr.typekind != TKIND_DISPATCH) return E_INVALIDARG; - if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL) + if (This->wTypeFlags & TYPEFLAG_FDUAL) { - *pRefType = -1; + *pRefType = -2; } else { hr = TYPE_E_ELEMENTNOTFOUND; } } - else if(index == 0 && This->TypeAttr.typekind == TKIND_DISPATCH) + else if(index == 0 && This->typekind == TKIND_DISPATCH) { /* All TKIND_DISPATCHs are made to look like they inherit from IDispatch */ *pRefType = This->pTypeLib->dispatch_href; } else { - if(index >= This->TypeAttr.cImplTypes) + if(index >= This->cImplTypes) hr = TYPE_E_ELEMENTNOTFOUND; - else + else{ *pRefType = This->impltypes[index].hRef; + if(This->typekind == TKIND_INTERFACE) + *pRefType |= 0x2; + } } if(TRACE_ON(ole)) @@ -5698,16 +6315,19 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( ITypeInfo2 *iface, UINT index, INT *pImplTypeFlags) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TRACE("(%p) index %d\n", This, index); - if(This->TypeAttr.typekind == TKIND_DISPATCH && index == 0){ + if(!pImplTypeFlags) + return E_INVALIDARG; + + if(This->typekind == TKIND_DISPATCH && index == 0){ *pImplTypeFlags = 0; return S_OK; } - if(index >= This->TypeAttr.cImplTypes) + if(index >= This->cImplTypes) return TYPE_E_ELEMENTNOTFOUND; *pImplTypeFlags = This->impltypes[index].implflags; @@ -5722,7 +6342,7 @@ static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( ITypeInfo2 *iface, static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface, LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); const TLBVarDesc *pVDesc; HRESULT ret=S_OK; UINT i, fdc; @@ -5734,14 +6354,14 @@ static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface, for (i = 0; i < cNames; i++) pMemId[i] = MEMBERID_NIL; - for (fdc = 0; fdc < This->TypeAttr.cFuncs; ++fdc) { + for (fdc = 0; fdc < This->cFuncs; ++fdc) { int j; const TLBFuncDesc *pFDesc = &This->funcdescs[fdc]; - if(!lstrcmpiW(*rgszNames, pFDesc->Name)) { + if(!lstrcmpiW(*rgszNames, TLB_get_bstr(pFDesc->Name))) { if(cNames) *pMemId=pFDesc->funcdesc.memid; for(i=1; i < cNames; i++){ for(j=0; jfuncdesc.cParams; j++) - if(!lstrcmpiW(rgszNames[i],pFDesc->pParamDesc[j].Name)) + if(!lstrcmpiW(rgszNames[i],TLB_get_bstr(pFDesc->pParamDesc[j].Name))) break; if( jfuncdesc.cParams) pMemId[i]=j; @@ -5752,7 +6372,7 @@ static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface, return ret; } } - pVDesc = TLB_get_vardesc_by_name(This->vardescs, This->TypeAttr.cVars, *rgszNames); + pVDesc = TLB_get_vardesc_by_name(This->vardescs, This->cVars, *rgszNames); if(pVDesc){ if(cNames) *pMemId = pVDesc->vardesc.memid; @@ -6320,7 +6940,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( EXCEPINFO *pExcepInfo, UINT *pArgErr) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); int i; unsigned int var_index; TYPEKIND type_kind; @@ -6332,7 +6952,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( This,pIUnk,memid,wFlags,pDispParams,pVarResult,pExcepInfo,pArgErr ); - if( This->TypeAttr.wTypeFlags & TYPEFLAG_FRESTRICTED ) + if( This->wTypeFlags & TYPEFLAG_FRESTRICTED ) return DISP_E_MEMBERNOTFOUND; if (!pDispParams) @@ -6352,7 +6972,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( /* we do this instead of using GetFuncDesc since it will return a fake * FUNCDESC for dispinterfaces and we want the real function description */ - for (fdc = 0; fdc < This->TypeAttr.cFuncs; ++fdc){ + for (fdc = 0; fdc < This->cFuncs; ++fdc){ pFuncInfo = &This->funcdescs[fdc]; if ((memid == pFuncInfo->funcdesc.memid) && (wFlags & pFuncInfo->funcdesc.invkind) && @@ -6360,7 +6980,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( break; } - if (fdc < This->TypeAttr.cFuncs) { + if (fdc < This->cFuncs) { const FUNCDESC *func_desc = &pFuncInfo->funcdesc; if (TRACE_ON(ole)) @@ -6636,7 +7256,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */ } - hres = DispCallFunc(pIUnk, func_desc->oVft, func_desc->callconv, + hres = DispCallFunc(pIUnk, func_desc->oVft & 0xFFFC, func_desc->callconv, V_VT(&varresult), func_desc->cParams, rgvt, prgpvarg, &varresult); @@ -6851,7 +7471,7 @@ static HRESULT WINAPI ITypeInfo_fnGetDocumentation( ITypeInfo2 *iface, MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); const TLBFuncDesc *pFDesc; const TLBVarDesc *pVDesc; TRACE("(%p) memid %d Name(%p) DocString(%p)" @@ -6859,39 +7479,43 @@ static HRESULT WINAPI ITypeInfo_fnGetDocumentation( ITypeInfo2 *iface, This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */ if(pBstrName) - *pBstrName=SysAllocString(This->Name); + *pBstrName=SysAllocString(TLB_get_bstr(This->Name)); if(pBstrDocString) - *pBstrDocString=SysAllocString(This->DocString); + *pBstrDocString=SysAllocString(TLB_get_bstr(This->DocString)); if(pdwHelpContext) *pdwHelpContext=This->dwHelpContext; if(pBstrHelpFile) - *pBstrHelpFile=SysAllocString(This->DocString);/* FIXME */ + *pBstrHelpFile=SysAllocString(TLB_get_bstr(This->pTypeLib->HelpFile)); return S_OK; }else {/* for a member */ - pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->TypeAttr.cFuncs, memid); + pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->cFuncs, memid); if(pFDesc){ if(pBstrName) - *pBstrName = SysAllocString(pFDesc->Name); + *pBstrName = SysAllocString(TLB_get_bstr(pFDesc->Name)); if(pBstrDocString) - *pBstrDocString=SysAllocString(pFDesc->HelpString); + *pBstrDocString=SysAllocString(TLB_get_bstr(pFDesc->HelpString)); if(pdwHelpContext) *pdwHelpContext=pFDesc->helpcontext; + if(pBstrHelpFile) + *pBstrHelpFile = SysAllocString(TLB_get_bstr(This->pTypeLib->HelpFile)); return S_OK; } - pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->TypeAttr.cVars, memid); + pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->cVars, memid); if(pVDesc){ if(pBstrName) - *pBstrName = SysAllocString(pVDesc->Name); + *pBstrName = SysAllocString(TLB_get_bstr(pVDesc->Name)); if(pBstrDocString) - *pBstrDocString=SysAllocString(pVDesc->HelpString); + *pBstrDocString=SysAllocString(TLB_get_bstr(pVDesc->HelpString)); if(pdwHelpContext) *pdwHelpContext=pVDesc->HelpContext; + if(pBstrHelpFile) + *pBstrHelpFile = SysAllocString(TLB_get_bstr(This->pTypeLib->HelpFile)); return S_OK; } } if(This->impltypes && - (This->TypeAttr.typekind==TKIND_INTERFACE || This->TypeAttr.typekind==TKIND_DISPATCH)) { + (This->typekind==TKIND_INTERFACE || This->typekind==TKIND_DISPATCH)) { /* recursive search */ ITypeInfo *pTInfo; HRESULT result; @@ -6918,7 +7542,7 @@ static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName, WORD *pwOrdinal) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); const TLBFuncDesc *pFDesc; TRACE("(%p)->(memid %x, %d, %p, %p, %p)\n", This, memid, invKind, pBstrDllName, pBstrName, pwOrdinal); @@ -6927,21 +7551,21 @@ static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid if (pBstrName) *pBstrName = NULL; if (pwOrdinal) *pwOrdinal = 0; - if (This->TypeAttr.typekind != TKIND_MODULE) + if (This->typekind != TKIND_MODULE) return TYPE_E_BADMODULEKIND; - pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->TypeAttr.cFuncs, memid); + pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->cFuncs, memid); if(pFDesc){ dump_TypeInfo(This); if (TRACE_ON(ole)) dump_TLBFuncDescOne(pFDesc); if (pBstrDllName) - *pBstrDllName = SysAllocString(This->DllName); + *pBstrDllName = SysAllocString(TLB_get_bstr(This->DllName)); if (!IS_INTRESOURCE(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) { if (pBstrName) - *pBstrName = SysAllocString(pFDesc->Entry); + *pBstrName = SysAllocString(TLB_get_bstr(pFDesc->Entry)); if (pwOrdinal) *pwOrdinal = -1; return S_OK; @@ -6960,7 +7584,7 @@ static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid static HRESULT ITypeInfoImpl_GetDispatchRefTypeInfo( ITypeInfo *iface, HREFTYPE *hRefType, ITypeInfo **ppTInfo) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo(iface); HRESULT hr; TRACE("%p, 0x%x\n", iface, *hRefType); @@ -6997,56 +7621,70 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( HREFTYPE hRefType, ITypeInfo **ppTInfo) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); HRESULT result = E_FAIL; - if ((This->hreftype != -1) && (This->hreftype == hRefType)) - { - *ppTInfo = (ITypeInfo *)&This->lpVtbl; + if(!ppTInfo) + return E_INVALIDARG; + + if ((INT)hRefType < 0) { + ITypeInfoImpl *pTypeInfoImpl; + + if (!(This->wTypeFlags & TYPEFLAG_FDUAL) || + !(This->typekind == TKIND_INTERFACE || + This->typekind == TKIND_DISPATCH)) + return TYPE_E_ELEMENTNOTFOUND; + + /* when we meet a DUAL typeinfo, we must create the alternate + * version of it. + */ + pTypeInfoImpl = ITypeInfoImpl_Constructor(); + + *pTypeInfoImpl = *This; + pTypeInfoImpl->ref = 0; + list_init(&pTypeInfoImpl->custdata_list); + + if (This->typekind == TKIND_INTERFACE) + pTypeInfoImpl->typekind = TKIND_DISPATCH; + else + pTypeInfoImpl->typekind = TKIND_INTERFACE; + + *ppTInfo = (ITypeInfo *)&pTypeInfoImpl->ITypeInfo2_iface; + /* the AddRef implicitly adds a reference to the parent typelib, which + * stops the copied data from being destroyed until the new typeinfo's + * refcount goes to zero, but we need to signal to the new instance to + * not free its data structures when it is destroyed */ + pTypeInfoImpl->not_attached_to_typelib = TRUE; + ITypeInfo_AddRef(*ppTInfo); + result = S_OK; - } - else if (hRefType == -1 && - (This->TypeAttr.typekind == TKIND_DISPATCH) && - (This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL)) - { - /* when we meet a DUAL dispinterface, we must create the interface - * version of it. - */ - ITypeInfoImpl *pTypeInfoImpl = ITypeInfoImpl_Constructor(); - - - /* the interface version contains the same information as the dispinterface - * copy the contents of the structs. - */ - *pTypeInfoImpl = *This; - pTypeInfoImpl->ref = 0; - - /* change the type to interface */ - pTypeInfoImpl->TypeAttr.typekind = TKIND_INTERFACE; - - *ppTInfo = (ITypeInfo*) pTypeInfoImpl; - - /* the AddRef implicitly adds a reference to the parent typelib, which - * stops the copied data from being destroyed until the new typeinfo's - * refcount goes to zero, but we need to signal to the new instance to - * not free its data structures when it is destroyed */ - pTypeInfoImpl->not_attached_to_typelib = TRUE; - - ITypeInfo_AddRef(*ppTInfo); - - result = S_OK; - - } else if ((hRefType != -1) && (hRefType & DISPATCH_HREF_MASK) && - (This->TypeAttr.typekind == TKIND_DISPATCH)) + } else if ((hRefType & DISPATCH_HREF_MASK) && + (This->typekind == TKIND_DISPATCH)) { HREFTYPE href_dispatch = hRefType; result = ITypeInfoImpl_GetDispatchRefTypeInfo((ITypeInfo *)iface, &href_dispatch, ppTInfo); } else { TLBRefType *ref_type; + ITypeLib *pTLib = NULL; + UINT i; + + if(!(hRefType & 0x1)){ + for(i = 0; i < This->pTypeLib->TypeInfoCount; ++i) + { + if (This->pTypeLib->typeinfos[i]->hreftype == (hRefType&(~0x3))) + { + result = S_OK; + *ppTInfo = (ITypeInfo*)&This->pTypeLib->typeinfos[i]->ITypeInfo2_iface; + ITypeInfo_AddRef(*ppTInfo); + goto end; + } + } + } + LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry) { - if(ref_type->reference == hRefType) + if(ref_type->reference == (hRefType & (~0x3))) break; } if(&ref_type->entry == &This->pTypeLib->ref_list) @@ -7054,46 +7692,47 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( FIXME("Can't find pRefType for ref %x\n", hRefType); goto end; } - if(hRefType != -1) { - ITypeLib *pTLib = NULL; - if(ref_type->pImpTLInfo == TLB_REF_INTERNAL) { - UINT Index; - result = ITypeInfo2_GetContainingTypeLib(iface, &pTLib, &Index); - } else { - if(ref_type->pImpTLInfo->pImpTypeLib) { - TRACE("typeinfo in imported typelib that is already loaded\n"); - pTLib = (ITypeLib*)&ref_type->pImpTLInfo->pImpTypeLib->ITypeLib2_iface; + if(ref_type->pImpTLInfo == TLB_REF_INTERNAL) { + UINT Index; + TRACE("internal reference\n"); + result = ITypeInfo2_GetContainingTypeLib(iface, &pTLib, &Index); + } else { + if(ref_type->pImpTLInfo->pImpTypeLib) { + TRACE("typeinfo in imported typelib that is already loaded\n"); + pTLib = (ITypeLib*)&ref_type->pImpTLInfo->pImpTypeLib->ITypeLib2_iface; + ITypeLib_AddRef(pTLib); + result = S_OK; + } else { + BSTR libnam; + + TRACE("typeinfo in imported typelib that isn't already loaded\n"); + + result = query_typelib_path(TLB_get_guid_null(ref_type->pImpTLInfo->guid), + ref_type->pImpTLInfo->wVersionMajor, + ref_type->pImpTLInfo->wVersionMinor, + This->pTypeLib->syskind, + ref_type->pImpTLInfo->lcid, &libnam); + if(FAILED(result)) + libnam = SysAllocString(ref_type->pImpTLInfo->name); + + result = LoadTypeLib(libnam, &pTLib); + SysFreeString(libnam); + + if(SUCCEEDED(result)) { + ref_type->pImpTLInfo->pImpTypeLib = impl_from_ITypeLib(pTLib); ITypeLib_AddRef(pTLib); - result = S_OK; - } else { - TRACE("typeinfo in imported typelib that isn't already loaded\n"); - result = LoadRegTypeLib( &ref_type->pImpTLInfo->guid, - ref_type->pImpTLInfo->wVersionMajor, - ref_type->pImpTLInfo->wVersionMinor, - ref_type->pImpTLInfo->lcid, - &pTLib); - - if(FAILED(result)) { - BSTR libnam=SysAllocString(ref_type->pImpTLInfo->name); - result=LoadTypeLib(libnam, &pTLib); - SysFreeString(libnam); - } - if(SUCCEEDED(result)) { - ref_type->pImpTLInfo->pImpTypeLib = (ITypeLibImpl*)pTLib; - ITypeLib_AddRef(pTLib); - } - } - } - if(SUCCEEDED(result)) { - if(ref_type->index == TLB_REF_USE_GUID) - result = ITypeLib_GetTypeInfoOfGuid(pTLib, &ref_type->guid, ppTInfo); - else - result = ITypeLib_GetTypeInfo(pTLib, ref_type->index, ppTInfo); - } - if (pTLib != NULL) - ITypeLib_Release(pTLib); - } + } + } + } + if(SUCCEEDED(result)) { + if(ref_type->index == TLB_REF_USE_GUID) + result = ITypeLib_GetTypeInfoOfGuid(pTLib, TLB_get_guid_null(ref_type->guid), ppTInfo); + else + result = ITypeLib_GetTypeInfo(pTLib, ref_type->index, ppTInfo); + } + if (pTLib != NULL) + ITypeLib_Release(pTLib); } end: @@ -7110,7 +7749,7 @@ end: static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface, MEMBERID memid, INVOKEKIND invKind, PVOID *ppv) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); HRESULT hr; BSTR dll, entry; WORD ordinal; @@ -7169,7 +7808,7 @@ static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface, static HRESULT WINAPI ITypeInfo_fnCreateInstance( ITypeInfo2 *iface, IUnknown *pOuterUnk, REFIID riid, VOID **ppvObj) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); HRESULT hr; TYPEATTR *pTA; @@ -7223,7 +7862,7 @@ end: static HRESULT WINAPI ITypeInfo_fnGetMops( ITypeInfo2 *iface, MEMBERID memid, BSTR *pBstrMops) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); FIXME("(%p %d) stub!\n", This, memid); *pBstrMops = NULL; return S_OK; @@ -7237,7 +7876,7 @@ static HRESULT WINAPI ITypeInfo_fnGetMops( ITypeInfo2 *iface, MEMBERID memid, static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( ITypeInfo2 *iface, ITypeLib * *ppTLib, UINT *pIndex) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); /* If a pointer is null, we simply ignore it, the ATL in particular passes pIndex as 0 */ if (pIndex) { @@ -7256,13 +7895,13 @@ static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( ITypeInfo2 *iface, /* ITypeInfo::ReleaseTypeAttr * - * Releases a TYPEATTR previously returned by GetTypeAttr. + * Releases a TYPEATTR previously returned by Get * */ static void WINAPI ITypeInfo_fnReleaseTypeAttr( ITypeInfo2 *iface, TYPEATTR* pTypeAttr) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TRACE("(%p)->(%p)\n", This, pTypeAttr); heap_free(pTypeAttr); } @@ -7275,7 +7914,7 @@ static void WINAPI ITypeInfo_fnReleaseFuncDesc( ITypeInfo2 *iface, FUNCDESC *pFuncDesc) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); SHORT i; TRACE("(%p)->(%p)\n", This, pFuncDesc); @@ -7294,13 +7933,10 @@ static void WINAPI ITypeInfo_fnReleaseFuncDesc( static void WINAPI ITypeInfo_fnReleaseVarDesc( ITypeInfo2 *iface, VARDESC *pVarDesc) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TRACE("(%p)->(%p)\n", This, pVarDesc); - TLB_FreeElemDesc(&pVarDesc->elemdescVar); - if (pVarDesc->varkind == VAR_CONST) - VariantClear(pVarDesc->u.lpvarValue); - SysFreeString((BSTR)pVarDesc); + TLB_FreeVarDesc(pVarDesc); } /* ITypeInfo2::GetTypeKind @@ -7311,8 +7947,8 @@ static void WINAPI ITypeInfo_fnReleaseVarDesc( ITypeInfo2 *iface, static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo2 * iface, TYPEKIND *pTypeKind) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - *pTypeKind=This->TypeAttr.typekind; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); + *pTypeKind=This->typekind; TRACE("(%p) type 0x%0x\n", This,*pTypeKind); return S_OK; } @@ -7326,8 +7962,8 @@ static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo2 * iface, */ static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo2 *iface, ULONG *pTypeFlags) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - *pTypeFlags=This->TypeAttr.wTypeFlags; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); + *pTypeFlags=This->wTypeFlags; TRACE("(%p) flags 0x%x\n", This,*pTypeFlags); return S_OK; } @@ -7340,16 +7976,16 @@ static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo2 *iface, ULONG *pType static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2 * iface, MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); UINT fdc; HRESULT result; - for (fdc = 0; fdc < This->TypeAttr.cFuncs; ++fdc){ + for (fdc = 0; fdc < This->cFuncs; ++fdc){ const TLBFuncDesc *pFuncInfo = &This->funcdescs[fdc]; if(memid == pFuncInfo->funcdesc.memid && (invKind & pFuncInfo->funcdesc.invkind)) break; } - if(fdc < This->TypeAttr.cFuncs) { + if(fdc < This->cFuncs) { *pFuncIndex = fdc; result = S_OK; } else @@ -7369,12 +8005,12 @@ static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2 * iface, static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo2 * iface, MEMBERID memid, UINT *pVarIndex) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TLBVarDesc *pVarInfo; TRACE("%p %d %p\n", iface, memid, pVarIndex); - pVarInfo = TLB_get_vardesc_by_memberid(This->vardescs, This->TypeAttr.cVars, memid); + pVarInfo = TLB_get_vardesc_by_memberid(This->vardescs, This->cVars, memid); if(!pVarInfo) return TYPE_E_ELEMENTNOTFOUND; @@ -7392,12 +8028,15 @@ static HRESULT WINAPI ITypeInfo2_fnGetCustData( REFGUID guid, VARIANT *pVarVal) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TLBCustData *pCData; TRACE("%p %s %p\n", This, debugstr_guid(guid), pVarVal); - pCData = TLB_get_custdata_by_guid(&This->custdata_list, guid); + if(!guid || !pVarVal) + return E_INVALIDARG; + + pCData = TLB_get_custdata_by_guid(This->pcustdata_list, guid); VariantInit( pVarVal); if (pCData) @@ -7417,13 +8056,13 @@ static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( REFGUID guid, VARIANT *pVarVal) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TLBCustData *pCData; TLBFuncDesc *pFDesc = &This->funcdescs[index]; TRACE("%p %u %s %p\n", This, index, debugstr_guid(guid), pVarVal); - if(index >= This->TypeAttr.cFuncs) + if(index >= This->cFuncs) return TYPE_E_ELEMENTNOTFOUND; pCData = TLB_get_custdata_by_guid(&pFDesc->custdata_list, guid); @@ -7447,14 +8086,14 @@ static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( REFGUID guid, VARIANT *pVarVal) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TLBCustData *pCData; TLBFuncDesc *pFDesc = &This->funcdescs[indexFunc]; TRACE("%p %u %u %s %p\n", This, indexFunc, indexParam, debugstr_guid(guid), pVarVal); - if(indexFunc >= This->TypeAttr.cFuncs) + if(indexFunc >= This->cFuncs) return TYPE_E_ELEMENTNOTFOUND; if(indexParam >= pFDesc->funcdesc.cParams) @@ -7480,13 +8119,13 @@ static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( REFGUID guid, VARIANT *pVarVal) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TLBCustData *pCData; TLBVarDesc *pVDesc = &This->vardescs[index]; TRACE("%p %s %p\n", This, debugstr_guid(guid), pVarVal); - if(index >= This->TypeAttr.cVars) + if(index >= This->cVars) return TYPE_E_ELEMENTNOTFOUND; pCData = TLB_get_custdata_by_guid(&pVDesc->custdata_list, guid); @@ -7509,13 +8148,13 @@ static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( REFGUID guid, VARIANT *pVarVal) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TLBCustData *pCData; TLBImplType *pRDesc = &This->impltypes[index]; TRACE("%p %u %s %p\n", This, index, debugstr_guid(guid), pVarVal); - if(index >= This->TypeAttr.cImplTypes) + if(index >= This->cImplTypes) return TYPE_E_ELEMENTNOTFOUND; pCData = TLB_get_custdata_by_guid(&pRDesc->custdata_list, guid); @@ -7543,7 +8182,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( DWORD *pdwHelpStringContext, BSTR *pbstrHelpStringDll) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); const TLBFuncDesc *pFDesc; const TLBVarDesc *pVDesc; TRACE("(%p) memid %d lcid(0x%x) HelpString(%p) " @@ -7556,34 +8195,34 @@ static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( */ if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */ if(pbstrHelpString) - *pbstrHelpString=SysAllocString(This->Name); + *pbstrHelpString=SysAllocString(TLB_get_bstr(This->Name)); if(pdwHelpStringContext) *pdwHelpStringContext=This->dwHelpStringContext; if(pbstrHelpStringDll) *pbstrHelpStringDll= - SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */ + SysAllocString(TLB_get_bstr(This->pTypeLib->HelpStringDll));/* FIXME */ return S_OK; }else {/* for a member */ - pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->TypeAttr.cFuncs, memid); + pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->cFuncs, memid); if(pFDesc){ if(pbstrHelpString) - *pbstrHelpString=SysAllocString(pFDesc->HelpString); + *pbstrHelpString=SysAllocString(TLB_get_bstr(pFDesc->HelpString)); if(pdwHelpStringContext) *pdwHelpStringContext=pFDesc->HelpStringContext; if(pbstrHelpStringDll) *pbstrHelpStringDll= - SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */ + SysAllocString(TLB_get_bstr(This->pTypeLib->HelpStringDll));/* FIXME */ return S_OK; } - pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->TypeAttr.cVars, memid); + pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->cVars, memid); if(pVDesc){ if(pbstrHelpString) - *pbstrHelpString=SysAllocString(pVDesc->HelpString); + *pbstrHelpString=SysAllocString(TLB_get_bstr(pVDesc->HelpString)); if(pdwHelpStringContext) *pdwHelpStringContext=pVDesc->HelpStringContext; if(pbstrHelpStringDll) *pbstrHelpStringDll= - SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */ + SysAllocString(TLB_get_bstr(This->pTypeLib->HelpStringDll));/* FIXME */ return S_OK; } } @@ -7599,11 +8238,11 @@ static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( ITypeInfo2 * iface, CUSTDATA *pCustData) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TRACE("%p %p\n", This, pCustData); - return TLB_copy_all_custdata(&This->custdata_list, pCustData); + return TLB_copy_all_custdata(This->pcustdata_list, pCustData); } /* ITypeInfo2::GetAllFuncCustData @@ -7616,12 +8255,12 @@ static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( UINT index, CUSTDATA *pCustData) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TLBFuncDesc *pFDesc = &This->funcdescs[index]; TRACE("%p %u %p\n", This, index, pCustData); - if(index >= This->TypeAttr.cFuncs) + if(index >= This->cFuncs) return TYPE_E_ELEMENTNOTFOUND; return TLB_copy_all_custdata(&pFDesc->custdata_list, pCustData); @@ -7635,12 +8274,12 @@ static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo2 * iface, UINT indexFunc, UINT indexParam, CUSTDATA *pCustData) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TLBFuncDesc *pFDesc = &This->funcdescs[indexFunc]; TRACE("%p %u %u %p\n", This, indexFunc, indexParam, pCustData); - if(indexFunc >= This->TypeAttr.cFuncs) + if(indexFunc >= This->cFuncs) return TYPE_E_ELEMENTNOTFOUND; if(indexParam >= pFDesc->funcdesc.cParams) @@ -7657,12 +8296,12 @@ static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo2 * iface, static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo2 * iface, UINT index, CUSTDATA *pCustData) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TLBVarDesc * pVDesc = &This->vardescs[index]; TRACE("%p %u %p\n", This, index, pCustData); - if(index >= This->TypeAttr.cVars) + if(index >= This->cVars) return TYPE_E_ELEMENTNOTFOUND; return TLB_copy_all_custdata(&pVDesc->custdata_list, pCustData); @@ -7678,12 +8317,12 @@ static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( UINT index, CUSTDATA *pCustData) { - ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); TLBImplType *pRDesc = &This->impltypes[index]; TRACE("%p %u %p\n", This, index, pCustData); - if(index >= This->TypeAttr.cImplTypes) + if(index >= This->cImplTypes) return TYPE_E_ELEMENTNOTFOUND; return TLB_copy_all_custdata(&pRDesc->custdata_list, pCustData); @@ -7770,24 +8409,25 @@ HRESULT WINAPI CreateDispTypeInfo( pTIIface->index = 0; pTIIface->Name = NULL; pTIIface->dwHelpContext = -1; - memset(&pTIIface->TypeAttr.guid, 0, sizeof(GUID)); - pTIIface->TypeAttr.lcid = lcid; - pTIIface->TypeAttr.typekind = TKIND_INTERFACE; - pTIIface->TypeAttr.wMajorVerNum = 0; - pTIIface->TypeAttr.wMinorVerNum = 0; - pTIIface->TypeAttr.cbAlignment = 2; - pTIIface->TypeAttr.cbSizeInstance = -1; - pTIIface->TypeAttr.cbSizeVft = -1; - pTIIface->TypeAttr.cFuncs = 0; - pTIIface->TypeAttr.cImplTypes = 0; - pTIIface->TypeAttr.cVars = 0; - pTIIface->TypeAttr.wTypeFlags = 0; + pTIIface->guid = NULL; + pTIIface->lcid = lcid; + pTIIface->typekind = TKIND_INTERFACE; + pTIIface->wMajorVerNum = 0; + pTIIface->wMinorVerNum = 0; + pTIIface->cbAlignment = 2; + pTIIface->cbSizeInstance = -1; + pTIIface->cbSizeVft = -1; + pTIIface->cFuncs = 0; + pTIIface->cImplTypes = 0; + pTIIface->cVars = 0; + pTIIface->wTypeFlags = 0; + pTIIface->hreftype = 0; - pTIIface->funcdescs = TLBFuncDesc_Constructor(pidata->cMembers); + pTIIface->funcdescs = TLBFuncDesc_Alloc(pidata->cMembers); pFuncDesc = pTIIface->funcdescs; for(func = 0; func < pidata->cMembers; func++) { METHODDATA *md = pidata->pmethdata + func; - pFuncDesc->Name = SysAllocString(md->szName); + pFuncDesc->Name = TLB_append_str(&pTypeLibImpl->name_list, md->szName); pFuncDesc->funcdesc.memid = md->dispid; pFuncDesc->funcdesc.lprgscode = NULL; pFuncDesc->funcdesc.funckind = FUNC_VIRTUAL; @@ -7806,14 +8446,14 @@ HRESULT WINAPI CreateDispTypeInfo( pFuncDesc->pParamDesc = TLBParDesc_Constructor(md->cArgs); for(param = 0; param < md->cArgs; param++) { pFuncDesc->funcdesc.lprgelemdescParam[param].tdesc.vt = md->ppdata[param].vt; - pFuncDesc->pParamDesc[param].Name = SysAllocString(md->ppdata[param].szName); + pFuncDesc->pParamDesc[param].Name = TLB_append_str(&pTypeLibImpl->name_list, md->ppdata[param].szName); } pFuncDesc->helpcontext = 0; pFuncDesc->HelpStringContext = 0; pFuncDesc->HelpString = NULL; pFuncDesc->Entry = NULL; list_init(&pFuncDesc->custdata_list); - pTIIface->TypeAttr.cFuncs++; + pTIIface->cFuncs++; ++pFuncDesc; } @@ -7824,20 +8464,21 @@ HRESULT WINAPI CreateDispTypeInfo( pTIClass->index = 1; pTIClass->Name = NULL; pTIClass->dwHelpContext = -1; - memset(&pTIClass->TypeAttr.guid, 0, sizeof(GUID)); - pTIClass->TypeAttr.lcid = lcid; - pTIClass->TypeAttr.typekind = TKIND_COCLASS; - pTIClass->TypeAttr.wMajorVerNum = 0; - pTIClass->TypeAttr.wMinorVerNum = 0; - pTIClass->TypeAttr.cbAlignment = 2; - pTIClass->TypeAttr.cbSizeInstance = -1; - pTIClass->TypeAttr.cbSizeVft = -1; - pTIClass->TypeAttr.cFuncs = 0; - pTIClass->TypeAttr.cImplTypes = 1; - pTIClass->TypeAttr.cVars = 0; - pTIClass->TypeAttr.wTypeFlags = 0; + pTIClass->guid = NULL; + pTIClass->lcid = lcid; + pTIClass->typekind = TKIND_COCLASS; + pTIClass->wMajorVerNum = 0; + pTIClass->wMinorVerNum = 0; + pTIClass->cbAlignment = 2; + pTIClass->cbSizeInstance = -1; + pTIClass->cbSizeVft = -1; + pTIClass->cFuncs = 0; + pTIClass->cImplTypes = 1; + pTIClass->cVars = 0; + pTIClass->wTypeFlags = 0; + pTIClass->hreftype = sizeof(MSFT_TypeInfoBase); - pTIClass->impltypes = TLBImplType_Constructor(1); + pTIClass->impltypes = TLBImplType_Alloc(1); ref = heap_alloc_zero(sizeof(*ref)); ref->pImpTLInfo = TLB_REF_INTERNAL; @@ -7845,7 +8486,7 @@ HRESULT WINAPI CreateDispTypeInfo( dump_TypeInfo(pTIClass); - *pptinfo = (ITypeInfo*)pTIClass; + *pptinfo = (ITypeInfo *)&pTIClass->ITypeInfo2_iface; ITypeInfo_AddRef(*pptinfo); ITypeLib2_Release(&pTypeLibImpl->ITypeLib2_iface); @@ -7858,21 +8499,21 @@ static HRESULT WINAPI ITypeComp_fnQueryInterface(ITypeComp * iface, REFIID riid, { ITypeInfoImpl *This = info_impl_from_ITypeComp(iface); - return ITypeInfo_QueryInterface((ITypeInfo *)This, riid, ppv); + return ITypeInfo2_QueryInterface(&This->ITypeInfo2_iface, riid, ppv); } static ULONG WINAPI ITypeComp_fnAddRef(ITypeComp * iface) { ITypeInfoImpl *This = info_impl_from_ITypeComp(iface); - return ITypeInfo_AddRef((ITypeInfo *)This); + return ITypeInfo2_AddRef(&This->ITypeInfo2_iface); } static ULONG WINAPI ITypeComp_fnRelease(ITypeComp * iface) { ITypeInfoImpl *This = info_impl_from_ITypeComp(iface); - return ITypeInfo_Release((ITypeInfo *)This); + return ITypeInfo2_Release(&This->ITypeInfo2_iface); } static HRESULT WINAPI ITypeComp_fnBind( @@ -7896,9 +8537,9 @@ static HRESULT WINAPI ITypeComp_fnBind( pBindPtr->lpfuncdesc = NULL; *ppTInfo = NULL; - for(fdc = 0; fdc < This->TypeAttr.cFuncs; ++fdc){ + for(fdc = 0; fdc < This->cFuncs; ++fdc){ pFDesc = &This->funcdescs[fdc]; - if (!strcmpiW(pFDesc->Name, szName)) { + if (!strcmpiW(TLB_get_bstr(pFDesc->Name), szName)) { if (!wFlags || (pFDesc->funcdesc.invkind & wFlags)) break; else @@ -7907,26 +8548,26 @@ static HRESULT WINAPI ITypeComp_fnBind( } } - if (fdc < This->TypeAttr.cFuncs) + if (fdc < This->cFuncs) { HRESULT hr = TLB_AllocAndInitFuncDesc( &pFDesc->funcdesc, &pBindPtr->lpfuncdesc, - This->TypeAttr.typekind == TKIND_DISPATCH); + This->typekind == TKIND_DISPATCH); if (FAILED(hr)) return hr; *pDescKind = DESCKIND_FUNCDESC; - *ppTInfo = (ITypeInfo *)&This->lpVtbl; + *ppTInfo = (ITypeInfo *)&This->ITypeInfo2_iface; ITypeInfo_AddRef(*ppTInfo); return S_OK; } else { - pVDesc = TLB_get_vardesc_by_name(This->vardescs, This->TypeAttr.cVars, szName); + pVDesc = TLB_get_vardesc_by_name(This->vardescs, This->cVars, szName); if(pVDesc){ HRESULT hr = TLB_AllocAndInitVarDesc(&pVDesc->vardesc, &pBindPtr->lpvardesc); if (FAILED(hr)) return hr; *pDescKind = DESCKIND_VARDESC; - *ppTInfo = (ITypeInfo *)&This->lpVtbl; + *ppTInfo = (ITypeInfo *)&This->ITypeInfo2_iface; ITypeInfo_AddRef(*ppTInfo); return S_OK; } @@ -7937,7 +8578,7 @@ static HRESULT WINAPI ITypeComp_fnBind( ITypeInfo *pTInfo; ITypeComp *pTComp; HRESULT hr; - hr=ITypeInfo_GetRefTypeInfo((ITypeInfo *)&This->lpVtbl, This->impltypes[0].hRef, &pTInfo); + hr=ITypeInfo2_GetRefTypeInfo(&This->ITypeInfo2_iface, This->impltypes[0].hRef, &pTInfo); if (SUCCEEDED(hr)) { hr = ITypeInfo_GetTypeComp(pTInfo,&pTComp); @@ -7988,3 +8629,2601 @@ static const ITypeCompVtbl tcompvt = ITypeComp_fnBind, ITypeComp_fnBindType }; + +HRESULT WINAPI CreateTypeLib2(SYSKIND syskind, LPCOLESTR szFile, + ICreateTypeLib2** ppctlib) +{ + ITypeLibImpl *This; + HRESULT hres; + + TRACE("(%d,%s,%p)\n", syskind, debugstr_w(szFile), ppctlib); + + if (!szFile) return E_INVALIDARG; + + This = TypeLibImpl_Constructor(); + if (!This) + return E_OUTOFMEMORY; + + This->lcid = GetSystemDefaultLCID(); + This->syskind = syskind; + This->ptr_size = get_ptr_size(syskind); + + This->path = heap_alloc((lstrlenW(szFile) + 1) * sizeof(WCHAR)); + if (!This->path) { + ITypeLib2_Release(&This->ITypeLib2_iface); + return E_OUTOFMEMORY; + } + lstrcpyW(This->path, szFile); + + hres = ITypeLib2_QueryInterface(&This->ITypeLib2_iface, &IID_ICreateTypeLib2, (LPVOID*)ppctlib); + ITypeLib2_Release(&This->ITypeLib2_iface); + return hres; +} + +static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface(ICreateTypeLib2 *iface, + REFIID riid, void **object) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + + return ITypeLib2_QueryInterface(&This->ITypeLib2_iface, riid, object); +} + +static ULONG WINAPI ICreateTypeLib2_fnAddRef(ICreateTypeLib2 *iface) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + + return ITypeLib2_AddRef(&This->ITypeLib2_iface); +} + +static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + + return ITypeLib2_Release(&This->ITypeLib2_iface); +} + +static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo(ICreateTypeLib2 *iface, + LPOLESTR name, TYPEKIND kind, ICreateTypeInfo **ctinfo) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + ITypeInfoImpl *info; + HRESULT hres; + + TRACE("%p %s %d %p\n", This, wine_dbgstr_w(name), kind, ctinfo); + + if (!ctinfo || !name) + return E_INVALIDARG; + + info = TLB_get_typeinfo_by_name(This->typeinfos, This->TypeInfoCount, name); + if (info) + return TYPE_E_NAMECONFLICT; + + if (This->typeinfos) + This->typeinfos = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->typeinfos, + sizeof(ITypeInfoImpl*) * (This->TypeInfoCount + 1)); + else + This->typeinfos = heap_alloc_zero(sizeof(ITypeInfoImpl*)); + + info = This->typeinfos[This->TypeInfoCount] = ITypeInfoImpl_Constructor(); + + info->pTypeLib = This; + info->Name = TLB_append_str(&This->name_list, name); + info->index = This->TypeInfoCount; + info->typekind = kind; + info->cbAlignment = 4; + + switch(info->typekind) { + case TKIND_ENUM: + case TKIND_INTERFACE: + case TKIND_DISPATCH: + case TKIND_COCLASS: + info->cbSizeInstance = This->ptr_size; + break; + case TKIND_RECORD: + case TKIND_UNION: + info->cbSizeInstance = 0; + break; + case TKIND_MODULE: + info->cbSizeInstance = 2; + break; + case TKIND_ALIAS: + info->cbSizeInstance = -0x75; + break; + default: + FIXME("unrecognized typekind %d\n", info->typekind); + info->cbSizeInstance = 0xdeadbeef; + break; + } + + hres = ITypeInfo2_QueryInterface(&info->ITypeInfo2_iface, + &IID_ICreateTypeInfo, (void **)ctinfo); + if (FAILED(hres)) { + ITypeInfo2_Release(&info->ITypeInfo2_iface); + return hres; + } + + info->hreftype = info->index * sizeof(MSFT_TypeInfoBase); + + ++This->TypeInfoCount; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeLib2_fnSetName(ICreateTypeLib2 *iface, + LPOLESTR name) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + + TRACE("%p %s\n", This, wine_dbgstr_w(name)); + + if (!name) + return E_INVALIDARG; + + This->Name = TLB_append_str(&This->name_list, name); + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeLib2_fnSetVersion(ICreateTypeLib2 *iface, + WORD majorVerNum, WORD minorVerNum) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + + TRACE("%p %d %d\n", This, majorVerNum, minorVerNum); + + This->ver_major = majorVerNum; + This->ver_minor = minorVerNum; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeLib2_fnSetGuid(ICreateTypeLib2 *iface, + REFGUID guid) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + + TRACE("%p %s\n", This, debugstr_guid(guid)); + + This->guid = TLB_append_guid(&This->guid_list, guid, -2); + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeLib2_fnSetDocString(ICreateTypeLib2 *iface, + LPOLESTR doc) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + + TRACE("%p %s\n", This, wine_dbgstr_w(doc)); + + if (!doc) + return E_INVALIDARG; + + This->DocString = TLB_append_str(&This->string_list, doc); + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 *iface, + LPOLESTR helpFileName) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + + TRACE("%p %s\n", This, wine_dbgstr_w(helpFileName)); + + if (!helpFileName) + return E_INVALIDARG; + + This->HelpFile = TLB_append_str(&This->string_list, helpFileName); + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 *iface, + DWORD helpContext) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + + TRACE("%p %d\n", This, helpContext); + + This->dwHelpContext = helpContext; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 *iface, + LCID lcid) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + + TRACE("%p %x\n", This, lcid); + + This->set_lcid = lcid; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeLib2_fnSetLibFlags(ICreateTypeLib2 *iface, + UINT libFlags) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + + TRACE("%p %x\n", This, libFlags); + + This->libflags = libFlags; + + return S_OK; +} + +typedef struct tagWMSFT_SegContents { + DWORD len; + void *data; +} WMSFT_SegContents; + +typedef struct tagWMSFT_TLBFile { + MSFT_Header header; + WMSFT_SegContents typeinfo_seg; + WMSFT_SegContents impfile_seg; + WMSFT_SegContents impinfo_seg; + WMSFT_SegContents ref_seg; + WMSFT_SegContents guidhash_seg; + WMSFT_SegContents guid_seg; + WMSFT_SegContents namehash_seg; + WMSFT_SegContents name_seg; + WMSFT_SegContents string_seg; + WMSFT_SegContents typdesc_seg; + WMSFT_SegContents arraydesc_seg; + WMSFT_SegContents custdata_seg; + WMSFT_SegContents cdguids_seg; + MSFT_SegDir segdir; + WMSFT_SegContents aux_seg; +} WMSFT_TLBFile; + +static HRESULT WMSFT_compile_strings(ITypeLibImpl *This, + WMSFT_TLBFile *file) +{ + TLBString *str; + UINT last_offs; + char *data; + + file->string_seg.len = 0; + LIST_FOR_EACH_ENTRY(str, &This->string_list, TLBString, entry) { + int size; + + size = WideCharToMultiByte(CP_ACP, 0, str->str, strlenW(str->str), NULL, 0, NULL, NULL); + if (size == 0) + return E_UNEXPECTED; + + size += sizeof(INT16); + if (size % 4) + size = (size + 4) & ~0x3; + if (size < 8) + size = 8; + + file->string_seg.len += size; + + /* temporarily use str->offset to store the length of the aligned, + * converted string */ + str->offset = size; + } + + file->string_seg.data = data = heap_alloc(file->string_seg.len); + + last_offs = 0; + LIST_FOR_EACH_ENTRY(str, &This->string_list, TLBString, entry) { + int size; + + size = WideCharToMultiByte(CP_ACP, 0, str->str, strlenW(str->str), + data + sizeof(INT16), file->string_seg.len - last_offs - sizeof(INT16), NULL, NULL); + if (size == 0) { + heap_free(file->string_seg.data); + return E_UNEXPECTED; + } + + *((INT16*)data) = size; + + memset(data + sizeof(INT16) + size, 0x57, str->offset - size - sizeof(INT16)); + + size = str->offset; + data += size; + str->offset = last_offs; + last_offs += size; + } + + return S_OK; +} + +static HRESULT WMSFT_compile_names(ITypeLibImpl *This, + WMSFT_TLBFile *file) +{ + TLBString *str; + UINT last_offs; + char *data; + MSFT_NameIntro *last_intro = NULL; + + file->header.nametablecount = 0; + file->header.nametablechars = 0; + + file->name_seg.len = 0; + LIST_FOR_EACH_ENTRY(str, &This->name_list, TLBString, entry) { + int size; + + size = strlenW(str->str); + file->header.nametablechars += size; + file->header.nametablecount++; + + size = WideCharToMultiByte(CP_ACP, 0, str->str, size, NULL, 0, NULL, NULL); + if (size == 0) + return E_UNEXPECTED; + + size += sizeof(MSFT_NameIntro); + if (size % 4) + size = (size + 4) & ~0x3; + if (size < 8) + size = 8; + + file->name_seg.len += size; + + /* temporarily use str->offset to store the length of the aligned, + * converted string */ + str->offset = size; + } + + /* Allocate bigger buffer so we can temporarily NULL terminate the name */ + file->name_seg.data = data = heap_alloc(file->name_seg.len+1); + + last_offs = 0; + LIST_FOR_EACH_ENTRY(str, &This->name_list, TLBString, entry) { + int size, hash; + MSFT_NameIntro *intro = (MSFT_NameIntro*)data; + + size = WideCharToMultiByte(CP_ACP, 0, str->str, strlenW(str->str), + data + sizeof(MSFT_NameIntro), + file->name_seg.len - last_offs - sizeof(MSFT_NameIntro), NULL, NULL); + if (size == 0) { + heap_free(file->name_seg.data); + return E_UNEXPECTED; + } + data[sizeof(MSFT_NameIntro) + size] = '\0'; + + intro->hreftype = -1; /* TODO? */ + intro->namelen = size & 0xFF; + /* TODO: namelen & 0xFF00 == ??? maybe HREF type indicator? */ + hash = LHashValOfNameSysA(This->syskind, This->lcid, data + sizeof(MSFT_NameIntro)); + intro->namelen |= hash << 16; + intro->next_hash = ((DWORD*)file->namehash_seg.data)[hash & 0x7f]; + ((DWORD*)file->namehash_seg.data)[hash & 0x7f] = last_offs; + + memset(data + sizeof(MSFT_NameIntro) + size, 0x57, + str->offset - size - sizeof(MSFT_NameIntro)); + + /* update str->offset to actual value to use in other + * compilation functions that require positions within + * the string table */ + last_intro = intro; + size = str->offset; + data += size; + str->offset = last_offs; + last_offs += size; + } + + if(last_intro) + last_intro->hreftype = 0; /* last one is 0? */ + + return S_OK; +} + +static inline int hash_guid(GUID *guid) +{ + int i, hash = 0; + + for (i = 0; i < 8; i ++) + hash ^= ((const short *)guid)[i]; + + return hash & 0x1f; +} + +static HRESULT WMSFT_compile_guids(ITypeLibImpl *This, WMSFT_TLBFile *file) +{ + TLBGuid *guid; + MSFT_GuidEntry *entry; + DWORD offs; + int hash_key, *guidhashtab; + + file->guid_seg.len = sizeof(MSFT_GuidEntry) * list_count(&This->guid_list); + file->guid_seg.data = heap_alloc(file->guid_seg.len); + + entry = file->guid_seg.data; + offs = 0; + guidhashtab = file->guidhash_seg.data; + LIST_FOR_EACH_ENTRY(guid, &This->guid_list, TLBGuid, entry){ + memcpy(&entry->guid, &guid->guid, sizeof(GUID)); + entry->hreftype = guid->hreftype; + + hash_key = hash_guid(&guid->guid); + entry->next_hash = guidhashtab[hash_key]; + guidhashtab[hash_key] = offs; + + guid->offset = offs; + offs += sizeof(MSFT_GuidEntry); + ++entry; + } + + return S_OK; +} + +static DWORD WMSFT_encode_variant(VARIANT *value, WMSFT_TLBFile *file) +{ + VARIANT v = *value; + VARTYPE arg_type = V_VT(value); + int mask = 0; + HRESULT hres; + DWORD ret = file->custdata_seg.len; + + if(arg_type == VT_INT) + arg_type = VT_I4; + if(arg_type == VT_UINT) + arg_type = VT_UI4; + + v = *value; + if(V_VT(value) != arg_type) { + hres = VariantChangeType(&v, value, 0, arg_type); + if(FAILED(hres)){ + ERR("VariantChangeType failed: %08x\n", hres); + return -1; + } + } + + /* Check if default value can be stored in-place */ + switch(arg_type){ + case VT_I4: + case VT_UI4: + mask = 0x3ffffff; + if(V_UI4(&v) > 0x3ffffff) + break; + /* fall through */ + case VT_I1: + case VT_UI1: + case VT_BOOL: + if(!mask) + mask = 0xff; + /* fall through */ + case VT_I2: + case VT_UI2: + if(!mask) + mask = 0xffff; + return ((0x80 + 0x4 * V_VT(value)) << 24) | (V_UI4(&v) & mask); + } + + /* have to allocate space in custdata_seg */ + switch(arg_type) { + case VT_I4: + case VT_R4: + case VT_UI4: + case VT_INT: + case VT_UINT: + case VT_HRESULT: + case VT_PTR: { + /* Construct the data to be allocated */ + int *data; + + if(file->custdata_seg.data){ + file->custdata_seg.data = heap_realloc(file->custdata_seg.data, file->custdata_seg.len + sizeof(int) * 2); + data = (int *)(((char *)file->custdata_seg.data) + file->custdata_seg.len); + file->custdata_seg.len += sizeof(int) * 2; + }else{ + file->custdata_seg.len = sizeof(int) * 2; + data = file->custdata_seg.data = heap_alloc(file->custdata_seg.len); + } + + data[0] = V_VT(value) + (V_UI4(&v) << 16); + data[1] = (V_UI4(&v) >> 16) + 0x57570000; + + /* TODO: Check if the encoded data is already present in custdata_seg */ + + return ret; + } + + case VT_BSTR: { + int i, len = (6+SysStringLen(V_BSTR(&v))+3) & ~0x3; + char *data; + + if(file->custdata_seg.data){ + file->custdata_seg.data = heap_realloc(file->custdata_seg.data, file->custdata_seg.len + len); + data = ((char *)file->custdata_seg.data) + file->custdata_seg.len; + file->custdata_seg.len += len; + }else{ + file->custdata_seg.len = len; + data = file->custdata_seg.data = heap_alloc(file->custdata_seg.len); + } + + *((unsigned short *)data) = V_VT(value); + *((unsigned int *)(data+2)) = SysStringLen(V_BSTR(&v)); + for(i=0; iarraydesc_seg.len; + DWORD *encoded; + USHORT i; + + /* TODO: we should check for duplicates, but that's harder because each + * chunk is variable length (really we should store TYPEDESC and ARRAYDESC + * at the library-level) */ + + file->arraydesc_seg.len += (2 + desc->cDims * 2) * sizeof(DWORD); + if(!file->arraydesc_seg.data) + file->arraydesc_seg.data = heap_alloc(file->arraydesc_seg.len); + else + file->arraydesc_seg.data = heap_realloc(file->arraydesc_seg.data, file->arraydesc_seg.len); + encoded = (DWORD*)((char *)file->arraydesc_seg.data) + offs; + + encoded[0] = WMSFT_append_typedesc(&desc->tdescElem, file, NULL, NULL); + encoded[1] = desc->cDims | ((desc->cDims * 2 * sizeof(DWORD)) << 16); + for(i = 0; i < desc->cDims; ++i){ + encoded[2 + i * 2] = desc->rgbounds[i].cElements; + encoded[2 + i * 2 + 1] = desc->rgbounds[i].lLbound; + } + + return offs; +} + +static DWORD WMSFT_append_typedesc(TYPEDESC *desc, WMSFT_TLBFile *file, DWORD *out_mix, INT16 *out_size) +{ + DWORD junk; + INT16 junk2; + DWORD offs = 0; + DWORD encoded[2]; + VARTYPE vt, subtype; + char *data; + + if(!desc) + return -1; + + if(!out_mix) + out_mix = &junk; + if(!out_size) + out_size = &junk2; + + vt = desc->vt & VT_TYPEMASK; + switch(vt){ + case VT_INT: + subtype = VT_I4; + break; + case VT_UINT: + subtype = VT_UI4; + break; + case VT_VOID: + subtype = VT_EMPTY; + break; + default: + subtype = vt; + break; + } + + switch(vt){ + case VT_INT: + case VT_UINT: + case VT_I1: + case VT_UI1: + case VT_I2: + case VT_UI2: + case VT_I4: + case VT_UI4: + case VT_BOOL: + case VT_R4: + case VT_ERROR: + case VT_BSTR: + case VT_HRESULT: + case VT_CY: + case VT_VOID: + case VT_VARIANT: + *out_mix = subtype; + return 0x80000000 | (subtype << 16) | desc->vt; + } + + if(vt == VT_PTR || vt == VT_SAFEARRAY){ + DWORD mix; + encoded[1] = WMSFT_append_typedesc(desc->u.lptdesc, file, &mix, out_size); + encoded[0] = desc->vt | ((mix | VT_BYREF) << 16); + *out_mix = 0x7FFF; + *out_size += 2 * sizeof(DWORD); + }else if(vt == VT_CARRAY){ + encoded[0] = desc->vt | (0x7FFE << 16); + encoded[1] = WMSFT_append_arraydesc(desc->u.lpadesc, file); + *out_mix = 0x7FFE; + }else if(vt == VT_USERDEFINED){ + encoded[0] = desc->vt | (0x7FFF << 16); + encoded[1] = desc->u.hreftype; + *out_mix = 0x7FFF; /* FIXME: Should get TYPEKIND of the hreftype, e.g. TKIND_ENUM => VT_I4 */ + }else{ + FIXME("Don't know what to do! VT: 0x%x\n", desc->vt); + *out_mix = desc->vt; + return 0x80000000 | (desc->vt << 16) | desc->vt; + } + + data = file->typdesc_seg.data; + while(offs < file->typdesc_seg.len){ + if(!memcmp(&data[offs], encoded, sizeof(encoded))) + return offs; + offs += sizeof(encoded); + } + + file->typdesc_seg.len += sizeof(encoded); + if(!file->typdesc_seg.data) + data = file->typdesc_seg.data = heap_alloc(file->typdesc_seg.len); + else + data = file->typdesc_seg.data = heap_realloc(file->typdesc_seg.data, file->typdesc_seg.len); + + memcpy(&data[offs], encoded, sizeof(encoded)); + + return offs; +} + +static DWORD WMSFT_compile_custdata(struct list *custdata_list, WMSFT_TLBFile *file) +{ + WMSFT_SegContents *cdguids_seg = &file->cdguids_seg; + DWORD ret = cdguids_seg->len, offs; + MSFT_CDGuid *cdguid = cdguids_seg->data; + TLBCustData *cd; + + if(list_empty(custdata_list)) + return -1; + + cdguids_seg->len += sizeof(MSFT_CDGuid) * list_count(custdata_list); + if(!cdguids_seg->data){ + cdguid = cdguids_seg->data = heap_alloc(cdguids_seg->len); + }else + cdguids_seg->data = heap_realloc(cdguids_seg->data, cdguids_seg->len); + + offs = ret + sizeof(MSFT_CDGuid); + LIST_FOR_EACH_ENTRY(cd, custdata_list, TLBCustData, entry){ + cdguid->GuidOffset = cd->guid->offset; + cdguid->DataOffset = WMSFT_encode_variant(&cd->data, file); + cdguid->next = offs; + offs += sizeof(MSFT_CDGuid); + ++cdguid; + } + + --cdguid; + cdguid->next = -1; + + return ret; +} + +static DWORD WMSFT_compile_typeinfo_aux(ITypeInfoImpl *info, + WMSFT_TLBFile *file) +{ + WMSFT_SegContents *aux_seg = &file->aux_seg; + DWORD ret = aux_seg->len, i, j, recorded_size = 0, extra_size = 0; + MSFT_VarRecord *varrecord; + MSFT_FuncRecord *funcrecord; + MEMBERID *memid; + DWORD *name, *offsets, offs; + + for(i = 0; i < info->cFuncs; ++i){ + TLBFuncDesc *desc = &info->funcdescs[i]; + + recorded_size += 6 * sizeof(INT); /* mandatory fields */ + + /* optional fields */ + /* TODO: oArgCustData - FuncSetCustData not impl yet */ + if(!list_empty(&desc->custdata_list)) + recorded_size += 7 * sizeof(INT); + else if(desc->HelpStringContext != 0) + recorded_size += 6 * sizeof(INT); + /* res9? resA? */ + else if(desc->Entry) + recorded_size += 3 * sizeof(INT); + else if(desc->HelpString) + recorded_size += 2 * sizeof(INT); + else if(desc->helpcontext) + recorded_size += sizeof(INT); + + recorded_size += desc->funcdesc.cParams * sizeof(MSFT_ParameterInfo); + + for(j = 0; j < desc->funcdesc.cParams; ++j){ + if(desc->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT){ + recorded_size += desc->funcdesc.cParams * sizeof(INT); + break; + } + } + + extra_size += 2 * sizeof(INT); /* memberid, name offs */ + } + + for(i = 0; i < info->cVars; ++i){ + TLBVarDesc *desc = &info->vardescs[i]; + + recorded_size += 5 * sizeof(INT); /* mandatory fields */ + + /* optional fields */ + if(desc->HelpStringContext != 0) + recorded_size += 5 * sizeof(INT); + else if(!list_empty(&desc->custdata_list)) + recorded_size += 4 * sizeof(INT); + /* res9? */ + else if(desc->HelpString) + recorded_size += 2 * sizeof(INT); + else if(desc->HelpContext != 0) + recorded_size += sizeof(INT); + + extra_size += 2 * sizeof(INT); /* memberid, name offs */ + } + + if(!recorded_size && !extra_size) + return ret; + + extra_size += sizeof(INT); /* total aux size for this typeinfo */ + + aux_seg->len += recorded_size + extra_size; + + aux_seg->len += sizeof(INT) * (info->cVars + info->cFuncs); /* offsets at the end */ + + if(aux_seg->data) + aux_seg->data = heap_realloc(aux_seg->data, aux_seg->len); + else + aux_seg->data = heap_alloc(aux_seg->len); + + *((DWORD*)((char *)aux_seg->data + ret)) = recorded_size; + + offsets = (DWORD*)((char *)aux_seg->data + ret + recorded_size + extra_size); + offs = 0; + + funcrecord = (MSFT_FuncRecord*)(((char *)aux_seg->data) + ret + sizeof(INT)); + for(i = 0; i < info->cFuncs; ++i){ + TLBFuncDesc *desc = &info->funcdescs[i]; + DWORD size = 6 * sizeof(INT), paramdefault_size = 0, *paramdefault; + + funcrecord->funcdescsize = sizeof(desc->funcdesc) + desc->funcdesc.cParams * sizeof(ELEMDESC); + funcrecord->DataType = WMSFT_append_typedesc(&desc->funcdesc.elemdescFunc.tdesc, file, NULL, &funcrecord->funcdescsize); + funcrecord->Flags = desc->funcdesc.wFuncFlags; + funcrecord->VtableOffset = desc->funcdesc.oVft; + + /* FKCCIC: + * XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX + * ^^^funckind + * ^^^ ^invkind + * ^has_cust_data + * ^^^^callconv + * ^has_param_defaults + * ^oEntry_is_intresource + */ + funcrecord->FKCCIC = + desc->funcdesc.funckind | + (desc->funcdesc.invkind << 3) | + (list_empty(&desc->custdata_list) ? 0 : 0x80) | + (desc->funcdesc.callconv << 8); + + if(desc->Entry && desc->Entry != (TLBString*)-1 && IS_INTRESOURCE(desc->Entry)) + funcrecord->FKCCIC |= 0x2000; + + for(j = 0; j < desc->funcdesc.cParams; ++j){ + if(desc->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT){ + paramdefault_size = sizeof(INT) * desc->funcdesc.cParams; + funcrecord->funcdescsize += sizeof(PARAMDESCEX); + } + } + if(paramdefault_size > 0) + funcrecord->FKCCIC |= 0x1000; + + funcrecord->nrargs = desc->funcdesc.cParams; + funcrecord->nroargs = desc->funcdesc.cParamsOpt; + + /* optional fields */ + /* res9? resA? */ + if(!list_empty(&desc->custdata_list)){ + size += 7 * sizeof(INT); + funcrecord->HelpContext = desc->helpcontext; + if(desc->HelpString) + funcrecord->oHelpString = desc->HelpString->offset; + else + funcrecord->oHelpString = -1; + if(!desc->Entry) + funcrecord->oEntry = -1; + else if(IS_INTRESOURCE(desc->Entry)) + funcrecord->oEntry = LOWORD(desc->Entry); + else + funcrecord->oEntry = desc->Entry->offset; + funcrecord->res9 = -1; + funcrecord->resA = -1; + funcrecord->HelpStringContext = desc->HelpStringContext; + funcrecord->oCustData = WMSFT_compile_custdata(&desc->custdata_list, file); + }else if(desc->HelpStringContext != 0){ + size += 6 * sizeof(INT); + funcrecord->HelpContext = desc->helpcontext; + if(desc->HelpString) + funcrecord->oHelpString = desc->HelpString->offset; + else + funcrecord->oHelpString = -1; + if(!desc->Entry) + funcrecord->oEntry = -1; + else if(IS_INTRESOURCE(desc->Entry)) + funcrecord->oEntry = LOWORD(desc->Entry); + else + funcrecord->oEntry = desc->Entry->offset; + funcrecord->res9 = -1; + funcrecord->resA = -1; + funcrecord->HelpStringContext = desc->HelpStringContext; + }else if(desc->Entry){ + size += 3 * sizeof(INT); + funcrecord->HelpContext = desc->helpcontext; + if(desc->HelpString) + funcrecord->oHelpString = desc->HelpString->offset; + else + funcrecord->oHelpString = -1; + if(!desc->Entry) + funcrecord->oEntry = -1; + else if(IS_INTRESOURCE(desc->Entry)) + funcrecord->oEntry = LOWORD(desc->Entry); + else + funcrecord->oEntry = desc->Entry->offset; + }else if(desc->HelpString){ + size += 2 * sizeof(INT); + funcrecord->HelpContext = desc->helpcontext; + funcrecord->oHelpString = desc->HelpString->offset; + }else if(desc->helpcontext){ + size += sizeof(INT); + funcrecord->HelpContext = desc->helpcontext; + } + + paramdefault = (DWORD*)((char *)funcrecord + size); + size += paramdefault_size; + + for(j = 0; j < desc->funcdesc.cParams; ++j){ + MSFT_ParameterInfo *info = (MSFT_ParameterInfo*)(((char *)funcrecord) + size); + + info->DataType = WMSFT_append_typedesc(&desc->funcdesc.lprgelemdescParam[j].tdesc, file, NULL, &funcrecord->funcdescsize); + if(desc->pParamDesc[j].Name) + info->oName = desc->pParamDesc[j].Name->offset; + else + info->oName = -1; + info->Flags = desc->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags; + + if(paramdefault_size){ + if(desc->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) + *paramdefault = WMSFT_encode_variant(&desc->funcdesc.lprgelemdescParam[j].u.paramdesc.pparamdescex->varDefaultValue, file); + else if(paramdefault_size) + *paramdefault = -1; + ++paramdefault; + } + + size += sizeof(MSFT_ParameterInfo); + } + + funcrecord->Info = size | (i << 16); /* is it just the index? */ + + *offsets = offs; + offs += size; + ++offsets; + + funcrecord = (MSFT_FuncRecord*)(((char*)funcrecord) + size); + } + + varrecord = (MSFT_VarRecord*)funcrecord; + for(i = 0; i < info->cVars; ++i){ + TLBVarDesc *desc = &info->vardescs[i]; + DWORD size = 5 * sizeof(INT); + + varrecord->vardescsize = sizeof(desc->vardesc); + varrecord->DataType = WMSFT_append_typedesc(&desc->vardesc.elemdescVar.tdesc, file, NULL, &varrecord->vardescsize); + varrecord->Flags = desc->vardesc.wVarFlags; + varrecord->VarKind = desc->vardesc.varkind; + + if(desc->vardesc.varkind == VAR_CONST){ + varrecord->vardescsize += sizeof(VARIANT); + varrecord->OffsValue = WMSFT_encode_variant(desc->vardesc.u.lpvarValue, file); + }else + varrecord->OffsValue = desc->vardesc.u.oInst; + + /* res9? */ + if(desc->HelpStringContext != 0){ + size += 5 * sizeof(INT); + varrecord->HelpContext = desc->HelpContext; + if(desc->HelpString) + varrecord->HelpString = desc->HelpString->offset; + else + varrecord->HelpString = -1; + varrecord->res9 = -1; + varrecord->oCustData = WMSFT_compile_custdata(&desc->custdata_list, file); + varrecord->HelpStringContext = desc->HelpStringContext; + }else if(!list_empty(&desc->custdata_list)){ + size += 4 * sizeof(INT); + varrecord->HelpContext = desc->HelpContext; + if(desc->HelpString) + varrecord->HelpString = desc->HelpString->offset; + else + varrecord->HelpString = -1; + varrecord->res9 = -1; + varrecord->oCustData = WMSFT_compile_custdata(&desc->custdata_list, file); + }else if(desc->HelpString){ + size += 2 * sizeof(INT); + varrecord->HelpContext = desc->HelpContext; + if(desc->HelpString) + varrecord->HelpString = desc->HelpString->offset; + else + varrecord->HelpString = -1; + }else if(desc->HelpContext != 0){ + size += sizeof(INT); + varrecord->HelpContext = desc->HelpContext; + } + + varrecord->Info = size | (i << 16); + + *offsets = offs; + offs += size; + ++offsets; + + varrecord = (MSFT_VarRecord*)(((char*)varrecord) + size); + } + + memid = (MEMBERID*)varrecord; + for(i = 0; i < info->cFuncs; ++i){ + TLBFuncDesc *desc = &info->funcdescs[i]; + *memid = desc->funcdesc.memid; + ++memid; + } + for(i = 0; i < info->cVars; ++i){ + TLBVarDesc *desc = &info->vardescs[i]; + *memid = desc->vardesc.memid; + ++memid; + } + + name = (UINT*)memid; + for(i = 0; i < info->cFuncs; ++i){ + TLBFuncDesc *desc = &info->funcdescs[i]; + if(desc->Name) + *name = desc->Name->offset; + else + *name = -1; + ++name; + } + for(i = 0; i < info->cVars; ++i){ + TLBVarDesc *desc = &info->vardescs[i]; + if(desc->Name) + *name = desc->Name->offset; + else + *name = -1; + ++name; + } + + return ret; +} + +typedef struct tagWMSFT_RefChunk { + DWORD href; + DWORD res04; + DWORD res08; + DWORD next; +} WMSFT_RefChunk; + +static DWORD WMSFT_compile_typeinfo_ref(ITypeInfoImpl *info, WMSFT_TLBFile *file) +{ + DWORD offs = file->ref_seg.len, i; + WMSFT_RefChunk *chunk; + + file->ref_seg.len += info->cImplTypes * sizeof(WMSFT_RefChunk); + if(!file->ref_seg.data) + file->ref_seg.data = heap_alloc(file->ref_seg.len); + else + file->ref_seg.data = heap_realloc(file->ref_seg.data, file->ref_seg.len); + + chunk = (WMSFT_RefChunk*)((char*)file->ref_seg.data + offs); + + for(i = 0; i < info->cImplTypes; ++i){ + chunk->href = info->impltypes[i].hRef; + chunk->res04 = info->impltypes[i].implflags; + chunk->res08 = -1; + if(i < info->cImplTypes - 1) + chunk->next = offs + sizeof(WMSFT_RefChunk) * (i + 1); + else + chunk->next = -1; + ++chunk; + } + + return offs; +} + +static DWORD WMSFT_compile_typeinfo(ITypeInfoImpl *info, INT16 index, WMSFT_TLBFile *file, char *data) +{ + DWORD size; + + size = sizeof(MSFT_TypeInfoBase); + + if(data){ + MSFT_TypeInfoBase *base = (void*)data; + if(info->wTypeFlags & TYPEFLAG_FDUAL) + base->typekind = TKIND_DISPATCH; + else + base->typekind = info->typekind; + base->typekind |= index << 16; /* TODO: There are some other flags here */ + base->typekind |= (info->cbAlignment << 11) | (info->cbAlignment << 6); + base->memoffset = WMSFT_compile_typeinfo_aux(info, file); + base->res2 = 0; + base->res3 = 0; + base->res4 = 3; + base->res5 = 0; + base->cElement = (info->cVars << 16) | info->cFuncs; + base->res7 = 0; + base->res8 = 0; + base->res9 = 0; + base->resA = 0; + if(info->guid) + base->posguid = info->guid->offset; + else + base->posguid = -1; + base->flags = info->wTypeFlags; + if(info->Name) { + base->NameOffset = info->Name->offset; + + ((unsigned char*)file->name_seg.data)[info->Name->offset+9] = 0x38; + *(HREFTYPE*)((unsigned char*)file->name_seg.data+info->Name->offset) = info->hreftype; + }else { + base->NameOffset = -1; + } + base->version = (info->wMinorVerNum << 16) | info->wMajorVerNum; + if(info->DocString) + base->docstringoffs = info->DocString->offset; + else + base->docstringoffs = -1; + base->helpstringcontext = info->dwHelpStringContext; + base->helpcontext = info->dwHelpContext; + base->oCustData = WMSFT_compile_custdata(info->pcustdata_list, file); + base->cImplTypes = info->cImplTypes; + base->cbSizeVft = info->cbSizeVft; + base->size = info->cbSizeInstance; + if(info->typekind == TKIND_COCLASS){ + base->datatype1 = WMSFT_compile_typeinfo_ref(info, file); + }else if(info->typekind == TKIND_ALIAS){ + base->datatype1 = WMSFT_append_typedesc(info->tdescAlias, file, NULL, NULL); + }else if(info->typekind == TKIND_MODULE){ + if(info->DllName) + base->datatype1 = info->DllName->offset; + else + base->datatype1 = -1; + }else{ + if(info->cImplTypes > 0) + base->datatype1 = info->impltypes[0].hRef; + else + base->datatype1 = -1; + } + base->datatype2 = index; /* FIXME: i think there's more here */ + base->res18 = 0; + base->res19 = -1; + } + + return size; +} + +static void WMSFT_compile_typeinfo_seg(ITypeLibImpl *This, WMSFT_TLBFile *file, DWORD *junk) +{ + UINT i; + + file->typeinfo_seg.len = 0; + for(i = 0; i < This->TypeInfoCount; ++i){ + ITypeInfoImpl *info = This->typeinfos[i]; + *junk = file->typeinfo_seg.len; + ++junk; + file->typeinfo_seg.len += WMSFT_compile_typeinfo(info, i, NULL, NULL); + } + + file->typeinfo_seg.data = heap_alloc(file->typeinfo_seg.len); + memset(file->typeinfo_seg.data, 0x96, file->typeinfo_seg.len); + + file->aux_seg.len = 0; + file->aux_seg.data = NULL; + + file->typeinfo_seg.len = 0; + for(i = 0; i < This->TypeInfoCount; ++i){ + ITypeInfoImpl *info = This->typeinfos[i]; + file->typeinfo_seg.len += WMSFT_compile_typeinfo(info, i, file, + ((char *)file->typeinfo_seg.data) + file->typeinfo_seg.len); + } +} + +typedef struct tagWMSFT_ImpFile { + INT guid_offs; + LCID lcid; + DWORD version; +} WMSFT_ImpFile; + +static void WMSFT_compile_impfile(ITypeLibImpl *This, WMSFT_TLBFile *file) +{ + TLBImpLib *implib; + WMSFT_ImpFile *impfile; + char *data; + DWORD last_offs = 0; + + file->impfile_seg.len = 0; + LIST_FOR_EACH_ENTRY(implib, &This->implib_list, TLBImpLib, entry){ + int size = 0; + + if(implib->name){ + WCHAR *path = strrchrW(implib->name, '\\'); + if(path) + ++path; + else + path = implib->name; + size = WideCharToMultiByte(CP_ACP, 0, path, strlenW(path), NULL, 0, NULL, NULL); + if (size == 0) + ERR("failed to convert wide string: %s\n", debugstr_w(path)); + } + + size += sizeof(INT16); + if (size % 4) + size = (size + 4) & ~0x3; + if (size < 8) + size = 8; + + file->impfile_seg.len += sizeof(WMSFT_ImpFile) + size; + } + + data = file->impfile_seg.data = heap_alloc(file->impfile_seg.len); + + LIST_FOR_EACH_ENTRY(implib, &This->implib_list, TLBImpLib, entry){ + int strlen = 0, size; + + impfile = (WMSFT_ImpFile*)data; + impfile->guid_offs = implib->guid->offset; + impfile->lcid = implib->lcid; + impfile->version = (implib->wVersionMinor << 16) | implib->wVersionMajor; + + data += sizeof(WMSFT_ImpFile); + + if(implib->name){ + WCHAR *path= strrchrW(implib->name, '\\'); + if(path) + ++path; + else + path = implib->name; + strlen = WideCharToMultiByte(CP_ACP, 0, path, strlenW(path), + data + sizeof(INT16), file->impfile_seg.len - last_offs - sizeof(INT16), NULL, NULL); + if (strlen == 0) + ERR("failed to convert wide string: %s\n", debugstr_w(path)); + } + + *((INT16*)data) = (strlen << 2) | 1; /* FIXME: is that a flag, or what? */ + + size = strlen + sizeof(INT16); + if (size % 4) + size = (size + 4) & ~0x3; + if (size < 8) + size = 8; + memset(data + sizeof(INT16) + strlen, 0x57, size - strlen - sizeof(INT16)); + + data += size; + implib->offset = last_offs; + last_offs += size + sizeof(WMSFT_ImpFile); + } +} + +static void WMSFT_compile_impinfo(ITypeLibImpl *This, WMSFT_TLBFile *file) +{ + MSFT_ImpInfo *info; + TLBRefType *ref_type; + UINT i = 0; + + WMSFT_compile_impfile(This, file); + + file->impinfo_seg.len = sizeof(MSFT_ImpInfo) * list_count(&This->ref_list); + info = file->impinfo_seg.data = heap_alloc(file->impinfo_seg.len); + + LIST_FOR_EACH_ENTRY(ref_type, &This->ref_list, TLBRefType, entry){ + info->flags = i | ((ref_type->tkind & 0xFF) << 24); + if(ref_type->index == TLB_REF_USE_GUID){ + info->flags |= MSFT_IMPINFO_OFFSET_IS_GUID; + info->oGuid = ref_type->guid->offset; + }else + info->oGuid = ref_type->index; + info->oImpFile = ref_type->pImpTLInfo->offset; + ++i; + ++info; + } +} + +static void WMSFT_compile_guidhash(ITypeLibImpl *This, WMSFT_TLBFile *file) +{ + file->guidhash_seg.len = 0x80; + file->guidhash_seg.data = heap_alloc(file->guidhash_seg.len); + memset(file->guidhash_seg.data, 0xFF, file->guidhash_seg.len); +} + +static void WMSFT_compile_namehash(ITypeLibImpl *This, WMSFT_TLBFile *file) +{ + file->namehash_seg.len = 0x200; + file->namehash_seg.data = heap_alloc(file->namehash_seg.len); + memset(file->namehash_seg.data, 0xFF, file->namehash_seg.len); +} + +static void tmp_fill_segdir_seg(MSFT_pSeg *segdir, WMSFT_SegContents *contents, DWORD *running_offset) +{ + if(contents && contents->len){ + segdir->offset = *running_offset; + segdir->length = contents->len; + *running_offset += segdir->length; + }else{ + segdir->offset = -1; + segdir->length = 0; + } + + /* TODO: do these ever change? */ + segdir->res08 = -1; + segdir->res0c = 0xf; +} + +static void WMSFT_write_segment(HANDLE outfile, WMSFT_SegContents *segment) +{ + DWORD written; + if(segment) + WriteFile(outfile, segment->data, segment->len, &written, NULL); +} + +static HRESULT WMSFT_fixup_typeinfos(ITypeLibImpl *This, WMSFT_TLBFile *file, + DWORD file_len) +{ + DWORD i; + MSFT_TypeInfoBase *base = (MSFT_TypeInfoBase *)file->typeinfo_seg.data; + + for(i = 0; i < This->TypeInfoCount; ++i){ + base->memoffset += file_len; + ++base; + } + + return S_OK; +} + +static void WMSFT_free_file(WMSFT_TLBFile *file) +{ + HeapFree(GetProcessHeap(), 0, file->typeinfo_seg.data); + HeapFree(GetProcessHeap(), 0, file->guidhash_seg.data); + HeapFree(GetProcessHeap(), 0, file->guid_seg.data); + HeapFree(GetProcessHeap(), 0, file->ref_seg.data); + HeapFree(GetProcessHeap(), 0, file->impinfo_seg.data); + HeapFree(GetProcessHeap(), 0, file->impfile_seg.data); + HeapFree(GetProcessHeap(), 0, file->namehash_seg.data); + HeapFree(GetProcessHeap(), 0, file->name_seg.data); + HeapFree(GetProcessHeap(), 0, file->string_seg.data); + HeapFree(GetProcessHeap(), 0, file->typdesc_seg.data); + HeapFree(GetProcessHeap(), 0, file->arraydesc_seg.data); + HeapFree(GetProcessHeap(), 0, file->custdata_seg.data); + HeapFree(GetProcessHeap(), 0, file->cdguids_seg.data); + HeapFree(GetProcessHeap(), 0, file->aux_seg.data); +} + +static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 *iface) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + WMSFT_TLBFile file; + DWORD written, junk_size, junk_offs, running_offset; + BOOL br; + HANDLE outfile; + HRESULT hres; + DWORD *junk; + UINT i; + + TRACE("%p\n", This); + + for(i = 0; i < This->TypeInfoCount; ++i) + if(This->typeinfos[i]->needs_layout) + ICreateTypeInfo2_LayOut(&This->typeinfos[i]->ICreateTypeInfo2_iface); + + memset(&file, 0, sizeof(file)); + + file.header.magic1 = 0x5446534D; + file.header.magic2 = 0x00010002; + file.header.lcid = This->set_lcid ? This->set_lcid : MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); + file.header.lcid2 = This->set_lcid; + file.header.varflags = 0x40 | This->syskind; + if (This->HelpFile) + file.header.varflags |= 0x10; + if (This->HelpStringDll) + file.header.varflags |= HELPDLLFLAG; + file.header.version = (This->ver_minor << 16) | This->ver_major; + file.header.flags = This->libflags; + file.header.helpstringcontext = 0; /* TODO - SetHelpStringContext not implemented yet */ + file.header.helpcontext = This->dwHelpContext; + file.header.res44 = 0x20; + file.header.res48 = 0x80; + file.header.dispatchpos = This->dispatch_href; + + WMSFT_compile_namehash(This, &file); + /* do name and string compilation to get offsets for other compilations */ + hres = WMSFT_compile_names(This, &file); + if (FAILED(hres)){ + WMSFT_free_file(&file); + return hres; + } + + hres = WMSFT_compile_strings(This, &file); + if (FAILED(hres)){ + WMSFT_free_file(&file); + return hres; + } + + WMSFT_compile_guidhash(This, &file); + hres = WMSFT_compile_guids(This, &file); + if (FAILED(hres)){ + WMSFT_free_file(&file); + return hres; + } + + if(This->HelpFile) + file.header.helpfile = This->HelpFile->offset; + else + file.header.helpfile = -1; + + if(This->DocString) + file.header.helpstring = This->DocString->offset; + else + file.header.helpstring = -1; + + /* do some more segment compilation */ + file.header.nimpinfos = list_count(&This->ref_list); + file.header.nrtypeinfos = This->TypeInfoCount; + + if(This->Name) + file.header.NameOffset = This->Name->offset; + else + file.header.NameOffset = -1; + + file.header.CustomDataOffset = -1; /* TODO SetCustData not impl yet */ + + if(This->guid) + file.header.posguid = This->guid->offset; + else + file.header.posguid = -1; + + junk_size = file.header.nrtypeinfos * sizeof(DWORD); + if(file.header.varflags & HELPDLLFLAG) + junk_size += sizeof(DWORD); + if(junk_size){ + junk = heap_alloc_zero(junk_size); + if(file.header.varflags & HELPDLLFLAG){ + *junk = This->HelpStringDll->offset; + junk_offs = 1; + }else + junk_offs = 0; + }else{ + junk = NULL; + junk_offs = 0; + } + + WMSFT_compile_typeinfo_seg(This, &file, junk + junk_offs); + WMSFT_compile_impinfo(This, &file); + + running_offset = 0; + + TRACE("header at: 0x%x\n", running_offset); + running_offset += sizeof(file.header); + + TRACE("junk at: 0x%x\n", running_offset); + running_offset += junk_size; + + TRACE("segdir at: 0x%x\n", running_offset); + running_offset += sizeof(file.segdir); + + TRACE("typeinfo at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.pTypeInfoTab, &file.typeinfo_seg, &running_offset); + + TRACE("guidhashtab at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.pGuidHashTab, &file.guidhash_seg, &running_offset); + + TRACE("guidtab at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.pGuidTab, &file.guid_seg, &running_offset); + + TRACE("reftab at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.pRefTab, &file.ref_seg, &running_offset); + + TRACE("impinfo at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.pImpInfo, &file.impinfo_seg, &running_offset); + + TRACE("impfiles at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.pImpFiles, &file.impfile_seg, &running_offset); + + TRACE("namehashtab at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.pNameHashTab, &file.namehash_seg, &running_offset); + + TRACE("nametab at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.pNametab, &file.name_seg, &running_offset); + + TRACE("stringtab at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.pStringtab, &file.string_seg, &running_offset); + + TRACE("typdesc at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.pTypdescTab, &file.typdesc_seg, &running_offset); + + TRACE("arraydescriptions at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.pArrayDescriptions, &file.arraydesc_seg, &running_offset); + + TRACE("custdata at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.pCustData, &file.custdata_seg, &running_offset); + + TRACE("cdguids at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.pCDGuids, &file.cdguids_seg, &running_offset); + + TRACE("res0e at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.res0e, NULL, &running_offset); + + TRACE("res0f at: 0x%x\n", running_offset); + tmp_fill_segdir_seg(&file.segdir.res0f, NULL, &running_offset); + + TRACE("aux_seg at: 0x%x\n", running_offset); + + WMSFT_fixup_typeinfos(This, &file, running_offset); + + outfile = CreateFileW(This->path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, 0); + if (outfile == INVALID_HANDLE_VALUE){ + WMSFT_free_file(&file); + heap_free(junk); + return TYPE_E_IOERROR; + } + + br = WriteFile(outfile, &file.header, sizeof(file.header), &written, NULL); + if (!br) { + WMSFT_free_file(&file); + CloseHandle(outfile); + heap_free(junk); + return TYPE_E_IOERROR; + } + + br = WriteFile(outfile, junk, junk_size, &written, NULL); + heap_free(junk); + if (!br) { + WMSFT_free_file(&file); + CloseHandle(outfile); + return TYPE_E_IOERROR; + } + + br = WriteFile(outfile, &file.segdir, sizeof(file.segdir), &written, NULL); + if (!br) { + WMSFT_free_file(&file); + CloseHandle(outfile); + return TYPE_E_IOERROR; + } + + WMSFT_write_segment(outfile, &file.typeinfo_seg); + WMSFT_write_segment(outfile, &file.guidhash_seg); + WMSFT_write_segment(outfile, &file.guid_seg); + WMSFT_write_segment(outfile, &file.ref_seg); + WMSFT_write_segment(outfile, &file.impinfo_seg); + WMSFT_write_segment(outfile, &file.impfile_seg); + WMSFT_write_segment(outfile, &file.namehash_seg); + WMSFT_write_segment(outfile, &file.name_seg); + WMSFT_write_segment(outfile, &file.string_seg); + WMSFT_write_segment(outfile, &file.typdesc_seg); + WMSFT_write_segment(outfile, &file.arraydesc_seg); + WMSFT_write_segment(outfile, &file.custdata_seg); + WMSFT_write_segment(outfile, &file.cdguids_seg); + WMSFT_write_segment(outfile, &file.aux_seg); + + WMSFT_free_file(&file); + + CloseHandle(outfile); + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeLib2_fnDeleteTypeInfo(ICreateTypeLib2 *iface, + LPOLESTR name) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + FIXME("%p %s - stub\n", This, wine_dbgstr_w(name)); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeLib2_fnSetCustData(ICreateTypeLib2 *iface, + REFGUID guid, VARIANT *varVal) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + FIXME("%p %s %p - stub\n", This, debugstr_guid(guid), varVal); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 *iface, + ULONG helpStringContext) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + FIXME("%p %u - stub\n", This, helpStringContext); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringDll(ICreateTypeLib2 *iface, + LPOLESTR filename) +{ + ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); + TRACE("%p %s\n", This, wine_dbgstr_w(filename)); + + if (!filename) + return E_INVALIDARG; + + This->HelpStringDll = TLB_append_str(&This->string_list, filename); + + return S_OK; +} + +static const ICreateTypeLib2Vtbl CreateTypeLib2Vtbl = { + ICreateTypeLib2_fnQueryInterface, + ICreateTypeLib2_fnAddRef, + ICreateTypeLib2_fnRelease, + ICreateTypeLib2_fnCreateTypeInfo, + ICreateTypeLib2_fnSetName, + ICreateTypeLib2_fnSetVersion, + ICreateTypeLib2_fnSetGuid, + ICreateTypeLib2_fnSetDocString, + ICreateTypeLib2_fnSetHelpFileName, + ICreateTypeLib2_fnSetHelpContext, + ICreateTypeLib2_fnSetLcid, + ICreateTypeLib2_fnSetLibFlags, + ICreateTypeLib2_fnSaveAllChanges, + ICreateTypeLib2_fnDeleteTypeInfo, + ICreateTypeLib2_fnSetCustData, + ICreateTypeLib2_fnSetHelpStringContext, + ICreateTypeLib2_fnSetHelpStringDll +}; + +static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface(ICreateTypeInfo2 *iface, + REFIID riid, void **object) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + + return ITypeInfo2_QueryInterface(&This->ITypeInfo2_iface, riid, object); +} + +static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + + return ITypeInfo2_AddRef(&This->ITypeInfo2_iface); +} + +static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + + return ITypeInfo2_Release(&This->ITypeInfo2_iface); +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetGuid(ICreateTypeInfo2 *iface, + REFGUID guid) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + + TRACE("%p %s\n", This, debugstr_guid(guid)); + + This->guid = TLB_append_guid(&This->pTypeLib->guid_list, guid, This->hreftype); + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, + UINT typeFlags) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + WORD old_flags; + HRESULT hres; + + TRACE("%p %x\n", This, typeFlags); + + if (typeFlags & TYPEFLAG_FDUAL) { + static const WCHAR stdole2tlb[] = { 's','t','d','o','l','e','2','.','t','l','b',0 }; + ITypeLib *stdole; + ITypeInfo *dispatch; + HREFTYPE hreftype; + HRESULT hres; + + hres = LoadTypeLib(stdole2tlb, &stdole); + if(FAILED(hres)) + return hres; + + hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &dispatch); + ITypeLib_Release(stdole); + if(FAILED(hres)) + return hres; + + hres = ICreateTypeInfo2_AddRefTypeInfo(iface, dispatch, &hreftype); + ITypeInfo_Release(dispatch); + if(FAILED(hres)) + return hres; + } + + old_flags = This->wTypeFlags; + This->wTypeFlags = typeFlags; + + hres = ICreateTypeInfo2_LayOut(iface); + if (FAILED(hres)) { + This->wTypeFlags = old_flags; + return hres; + } + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetDocString(ICreateTypeInfo2 *iface, + LPOLESTR doc) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + + TRACE("%p %s\n", This, wine_dbgstr_w(doc)); + + if (!doc) + return E_INVALIDARG; + + This->DocString = TLB_append_str(&This->pTypeLib->string_list, doc); + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext(ICreateTypeInfo2 *iface, + DWORD helpContext) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + + TRACE("%p %d\n", This, helpContext); + + This->dwHelpContext = helpContext; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetVersion(ICreateTypeInfo2 *iface, + WORD majorVerNum, WORD minorVerNum) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + + TRACE("%p %d %d\n", This, majorVerNum, minorVerNum); + + This->wMajorVerNum = majorVerNum; + This->wMinorVerNum = minorVerNum; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(ICreateTypeInfo2 *iface, + ITypeInfo *typeInfo, HREFTYPE *refType) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + UINT index; + ITypeLib *container; + TLBRefType *ref_type; + TLBImpLib *implib; + TYPEATTR *typeattr; + TLIBATTR *libattr; + HRESULT hres; + + TRACE("%p %p %p\n", This, typeInfo, refType); + + if (!typeInfo || !refType) + return E_INVALIDARG; + + hres = ITypeInfo_GetContainingTypeLib(typeInfo, &container, &index); + if (FAILED(hres)) + return hres; + + if (container == (ITypeLib*)&This->pTypeLib->ITypeLib2_iface) { + ITypeInfoImpl *target = impl_from_ITypeInfo(typeInfo); + + ITypeLib_Release(container); + + *refType = target->hreftype; + + return S_OK; + } + + hres = ITypeLib_GetLibAttr(container, &libattr); + if (FAILED(hres)) { + ITypeLib_Release(container); + return hres; + } + + LIST_FOR_EACH_ENTRY(implib, &This->pTypeLib->implib_list, TLBImpLib, entry){ + if(IsEqualGUID(&implib->guid->guid, &libattr->guid) && + implib->lcid == libattr->lcid && + implib->wVersionMajor == libattr->wMajorVerNum && + implib->wVersionMinor == libattr->wMinorVerNum) + break; + } + + if(&implib->entry == &This->pTypeLib->implib_list){ + implib = heap_alloc_zero(sizeof(TLBImpLib)); + + if((ITypeLib2Vtbl*)container->lpVtbl == &tlbvt){ + const ITypeLibImpl *our_container = impl_from_ITypeLib2((ITypeLib2*)container); + implib->name = SysAllocString(our_container->path); + }else{ + hres = QueryPathOfRegTypeLib(&libattr->guid, libattr->wMajorVerNum, + libattr->wMinorVerNum, libattr->lcid, &implib->name); + if(FAILED(hres)){ + implib->name = NULL; + TRACE("QueryPathOfRegTypeLib failed, no name stored: %08x\n", hres); + } + } + + implib->guid = TLB_append_guid(&This->pTypeLib->guid_list, &libattr->guid, 2); + implib->lcid = libattr->lcid; + implib->wVersionMajor = libattr->wMajorVerNum; + implib->wVersionMinor = libattr->wMinorVerNum; + + list_add_tail(&This->pTypeLib->implib_list, &implib->entry); + } + + ITypeLib_ReleaseTLibAttr(container, libattr); + ITypeLib_Release(container); + + hres = ITypeInfo_GetTypeAttr(typeInfo, &typeattr); + if (FAILED(hres)) + return hres; + + index = 0; + LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry){ + if(ref_type->index == TLB_REF_USE_GUID && + IsEqualGUID(&ref_type->guid->guid, &typeattr->guid) && + ref_type->tkind == typeattr->typekind) + break; + ++index; + } + + if(&ref_type->entry == &This->pTypeLib->ref_list){ + ref_type = heap_alloc_zero(sizeof(TLBRefType)); + + ref_type->tkind = typeattr->typekind; + ref_type->pImpTLInfo = implib; + ref_type->reference = index * sizeof(MSFT_ImpInfo); + + ref_type->index = TLB_REF_USE_GUID; + + ref_type->guid = TLB_append_guid(&This->pTypeLib->guid_list, &typeattr->guid, ref_type->reference+1); + + list_add_tail(&This->pTypeLib->ref_list, &ref_type->entry); + } + + ITypeInfo_ReleaseTypeAttr(typeInfo, typeattr); + + *refType = ref_type->reference | 0x1; + + if(IsEqualGUID(&ref_type->guid->guid, &IID_IDispatch)) + This->pTypeLib->dispatch_href = *refType; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(ICreateTypeInfo2 *iface, + UINT index, FUNCDESC *funcDesc) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + TLBFuncDesc tmp_func_desc, *func_desc; + int buf_size, i; + char *buffer; + HRESULT hres; + + TRACE("%p %u %p\n", This, index, funcDesc); + + if (!funcDesc || funcDesc->oVft & 3) + return E_INVALIDARG; + + switch (This->typekind) { + case TKIND_MODULE: + if (funcDesc->funckind != FUNC_STATIC) + return TYPE_E_BADMODULEKIND; + break; + case TKIND_DISPATCH: + if (funcDesc->funckind != FUNC_DISPATCH) + return TYPE_E_BADMODULEKIND; + break; + default: + if (funcDesc->funckind != FUNC_PUREVIRTUAL) + return TYPE_E_BADMODULEKIND; + } + + if (index > This->cFuncs) + return TYPE_E_ELEMENTNOTFOUND; + + if (funcDesc->invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF) && + !funcDesc->cParams) + return TYPE_E_INCONSISTENTPROPFUNCS; + +#ifdef _WIN64 + if(This->pTypeLib->syskind == SYS_WIN64 && + funcDesc->oVft % 8 != 0) + return E_INVALIDARG; +#endif + + memset(&tmp_func_desc, 0, sizeof(tmp_func_desc)); + TLBFuncDesc_Constructor(&tmp_func_desc); + + tmp_func_desc.funcdesc = *funcDesc; + + if (tmp_func_desc.funcdesc.oVft != 0) + tmp_func_desc.funcdesc.oVft |= 1; + + if (funcDesc->cScodes) { + tmp_func_desc.funcdesc.lprgscode = heap_alloc(sizeof(SCODE) * funcDesc->cScodes); + memcpy(tmp_func_desc.funcdesc.lprgscode, funcDesc->lprgscode, sizeof(SCODE) * funcDesc->cScodes); + } else + tmp_func_desc.funcdesc.lprgscode = NULL; + + buf_size = TLB_SizeElemDesc(&funcDesc->elemdescFunc); + for (i = 0; i < funcDesc->cParams; ++i) { + buf_size += sizeof(ELEMDESC); + buf_size += TLB_SizeElemDesc(funcDesc->lprgelemdescParam + i); + } + tmp_func_desc.funcdesc.lprgelemdescParam = heap_alloc(buf_size); + buffer = (char*)(tmp_func_desc.funcdesc.lprgelemdescParam + funcDesc->cParams); + + hres = TLB_CopyElemDesc(&funcDesc->elemdescFunc, &tmp_func_desc.funcdesc.elemdescFunc, &buffer); + if (FAILED(hres)) { + heap_free(tmp_func_desc.funcdesc.lprgelemdescParam); + heap_free(tmp_func_desc.funcdesc.lprgscode); + return hres; + } + + for (i = 0; i < funcDesc->cParams; ++i) { + hres = TLB_CopyElemDesc(funcDesc->lprgelemdescParam + i, + tmp_func_desc.funcdesc.lprgelemdescParam + i, &buffer); + if (FAILED(hres)) { + heap_free(tmp_func_desc.funcdesc.lprgelemdescParam); + heap_free(tmp_func_desc.funcdesc.lprgscode); + return hres; + } + if (tmp_func_desc.funcdesc.lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT && + tmp_func_desc.funcdesc.lprgelemdescParam[i].tdesc.vt != VT_VARIANT && + tmp_func_desc.funcdesc.lprgelemdescParam[i].tdesc.vt != VT_USERDEFINED){ + hres = TLB_SanitizeVariant(&tmp_func_desc.funcdesc.lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue); + if (FAILED(hres)) { + heap_free(tmp_func_desc.funcdesc.lprgelemdescParam); + heap_free(tmp_func_desc.funcdesc.lprgscode); + return hres; + } + } + } + + tmp_func_desc.pParamDesc = TLBParDesc_Constructor(funcDesc->cParams); + + if (This->funcdescs) { + This->funcdescs = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->funcdescs, + sizeof(TLBFuncDesc) * (This->cFuncs + 1)); + + if (index < This->cFuncs) { + memmove(This->funcdescs + index + 1, This->funcdescs + index, + (This->cFuncs - index) * sizeof(TLBFuncDesc)); + func_desc = This->funcdescs + index; + } else + func_desc = This->funcdescs + This->cFuncs; + + /* move custdata lists to the new memory location */ + for(i = 0; i < This->cFuncs + 1; ++i){ + if(index != i){ + TLBFuncDesc *fd = &This->funcdescs[i]; + if(fd->custdata_list.prev == fd->custdata_list.next) + list_init(&fd->custdata_list); + else{ + fd->custdata_list.prev->next = &fd->custdata_list; + fd->custdata_list.next->prev = &fd->custdata_list; + } + } + } + } else + func_desc = This->funcdescs = heap_alloc(sizeof(TLBFuncDesc)); + + memcpy(func_desc, &tmp_func_desc, sizeof(tmp_func_desc)); + list_init(&func_desc->custdata_list); + + ++This->cFuncs; + + This->needs_layout = TRUE; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(ICreateTypeInfo2 *iface, + UINT index, HREFTYPE refType) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + TLBImplType *impl_type; + HRESULT hres; + + TRACE("%p %u %d\n", This, index, refType); + + switch(This->typekind){ + case TKIND_COCLASS: { + if (index == -1) { + FIXME("Unhandled index: -1\n"); + return E_NOTIMPL; + } + + if(index != This->cImplTypes) + return TYPE_E_ELEMENTNOTFOUND; + + break; + } + case TKIND_INTERFACE: + case TKIND_DISPATCH: + if (index != 0 || This->cImplTypes) + return TYPE_E_ELEMENTNOTFOUND; + break; + default: + FIXME("Unimplemented typekind: %d\n", This->typekind); + return E_NOTIMPL; + } + + if (This->impltypes){ + UINT i; + + This->impltypes = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->impltypes, + sizeof(TLBImplType) * (This->cImplTypes + 1)); + + if (index < This->cImplTypes) { + memmove(This->impltypes + index + 1, This->impltypes + index, + (This->cImplTypes - index) * sizeof(TLBImplType)); + impl_type = This->impltypes + index; + } else + impl_type = This->impltypes + This->cImplTypes; + + /* move custdata lists to the new memory location */ + for(i = 0; i < This->cImplTypes + 1; ++i){ + if(index != i){ + TLBImplType *it = &This->impltypes[i]; + if(it->custdata_list.prev == it->custdata_list.next) + list_init(&it->custdata_list); + else{ + it->custdata_list.prev->next = &it->custdata_list; + it->custdata_list.next->prev = &it->custdata_list; + } + } + } + } else + impl_type = This->impltypes = heap_alloc(sizeof(TLBImplType)); + + memset(impl_type, 0, sizeof(TLBImplType)); + TLBImplType_Constructor(impl_type); + impl_type->hRef = refType; + + ++This->cImplTypes; + + if((refType & (~0x3)) == (This->pTypeLib->dispatch_href & (~0x3))) + This->wTypeFlags |= TYPEFLAG_FDISPATCHABLE; + + hres = ICreateTypeInfo2_LayOut(iface); + if (FAILED(hres)) + return hres; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags(ICreateTypeInfo2 *iface, + UINT index, INT implTypeFlags) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + TLBImplType *impl_type = &This->impltypes[index]; + + TRACE("%p %u %x\n", This, index, implTypeFlags); + + if (This->typekind != TKIND_COCLASS) + return TYPE_E_BADMODULEKIND; + + if (index >= This->cImplTypes) + return TYPE_E_ELEMENTNOTFOUND; + + impl_type->implflags = implTypeFlags; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment(ICreateTypeInfo2 *iface, + WORD alignment) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + + TRACE("%p %d\n", This, alignment); + + This->cbAlignment = alignment; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetSchema(ICreateTypeInfo2 *iface, + LPOLESTR schema) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + + TRACE("%p %s\n", This, wine_dbgstr_w(schema)); + + if (!schema) + return E_INVALIDARG; + + This->Schema = TLB_append_str(&This->pTypeLib->string_list, schema); + + This->lpstrSchema = This->Schema->str; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(ICreateTypeInfo2 *iface, + UINT index, VARDESC *varDesc) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + TLBVarDesc *var_desc; + + TRACE("%p %u %p\n", This, index, varDesc); + + if (This->vardescs){ + UINT i; + + This->vardescs = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->vardescs, + sizeof(TLBVarDesc) * (This->cVars + 1)); + + if (index < This->cVars) { + memmove(This->vardescs + index + 1, This->vardescs + index, + (This->cVars - index) * sizeof(TLBVarDesc)); + var_desc = This->vardescs + index; + } else + var_desc = This->vardescs + This->cVars; + + /* move custdata lists to the new memory location */ + for(i = 0; i < This->cVars + 1; ++i){ + if(index != i){ + TLBVarDesc *var = &This->vardescs[i]; + if(var->custdata_list.prev == var->custdata_list.next) + list_init(&var->custdata_list); + else{ + var->custdata_list.prev->next = &var->custdata_list; + var->custdata_list.next->prev = &var->custdata_list; + } + } + } + } else + var_desc = This->vardescs = heap_alloc_zero(sizeof(TLBVarDesc)); + + TLBVarDesc_Constructor(var_desc); + TLB_AllocAndInitVarDesc(varDesc, &var_desc->vardesc_create); + var_desc->vardesc = *var_desc->vardesc_create; + + ++This->cVars; + + This->needs_layout = TRUE; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames(ICreateTypeInfo2 *iface, + UINT index, LPOLESTR *names, UINT numNames) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + TLBFuncDesc *func_desc = &This->funcdescs[index]; + int i; + + TRACE("%p %u %p %u\n", This, index, names, numNames); + + if (!names) + return E_INVALIDARG; + + if (index >= This->cFuncs || numNames == 0) + return TYPE_E_ELEMENTNOTFOUND; + + if (func_desc->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF)){ + if(numNames > func_desc->funcdesc.cParams) + return TYPE_E_ELEMENTNOTFOUND; + } else + if(numNames > func_desc->funcdesc.cParams + 1) + return TYPE_E_ELEMENTNOTFOUND; + + for(i = 0; i < This->cFuncs; ++i) { + TLBFuncDesc *iter = &This->funcdescs[i]; + if (iter->Name && !strcmpW(TLB_get_bstr(iter->Name), *names)) { + if (iter->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF | INVOKE_PROPERTYGET) && + func_desc->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF | INVOKE_PROPERTYGET) && + func_desc->funcdesc.invkind != iter->funcdesc.invkind) + continue; + return TYPE_E_AMBIGUOUSNAME; + } + } + + func_desc->Name = TLB_append_str(&This->pTypeLib->name_list, *names); + + for (i = 1; i < numNames; ++i) { + TLBParDesc *par_desc = func_desc->pParamDesc + i - 1; + par_desc->Name = TLB_append_str(&This->pTypeLib->name_list, *(names + i)); + } + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName(ICreateTypeInfo2 *iface, + UINT index, LPOLESTR name) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %u %s - stub\n", This, index, wine_dbgstr_w(name)); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias(ICreateTypeInfo2 *iface, + TYPEDESC *tdescAlias) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + HRESULT hr; + + TRACE("%p %p\n", This, tdescAlias); + + if(!tdescAlias) + return E_INVALIDARG; + + if(This->typekind != TKIND_ALIAS) + return TYPE_E_BADMODULEKIND; + + hr = TLB_size_instance(This, This->pTypeLib->syskind, tdescAlias, &This->cbSizeInstance, &This->cbAlignment); + if(FAILED(hr)) + return hr; + + heap_free(This->tdescAlias); + This->tdescAlias = heap_alloc(TLB_SizeTypeDesc(tdescAlias, TRUE)); + TLB_CopyTypeDesc(NULL, tdescAlias, This->tdescAlias); + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry(ICreateTypeInfo2 *iface, + UINT index, LPOLESTR dllName, LPOLESTR procName) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %u %s %s - stub\n", This, index, wine_dbgstr_w(dllName), wine_dbgstr_w(procName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncDocString(ICreateTypeInfo2 *iface, + UINT index, LPOLESTR docString) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %u %s - stub\n", This, index, wine_dbgstr_w(docString)); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetVarDocString(ICreateTypeInfo2 *iface, + UINT index, LPOLESTR docString) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + TLBVarDesc *var_desc = &This->vardescs[index]; + + TRACE("%p %u %s\n", This, index, wine_dbgstr_w(docString)); + + if(!docString) + return E_INVALIDARG; + + if(index >= This->cVars) + return TYPE_E_ELEMENTNOTFOUND; + + var_desc->HelpString = TLB_append_str(&This->pTypeLib->string_list, docString); + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext(ICreateTypeInfo2 *iface, + UINT index, DWORD helpContext) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + TLBFuncDesc *func_desc = &This->funcdescs[index]; + + TRACE("%p %u %d\n", This, index, helpContext); + + if(index >= This->cFuncs) + return TYPE_E_ELEMENTNOTFOUND; + + func_desc->helpcontext = helpContext; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpContext(ICreateTypeInfo2 *iface, + UINT index, DWORD helpContext) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + TLBVarDesc *var_desc = &This->vardescs[index]; + + TRACE("%p %u %d\n", This, index, helpContext); + + if(index >= This->cVars) + return TYPE_E_ELEMENTNOTFOUND; + + var_desc->HelpContext = helpContext; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetMops(ICreateTypeInfo2 *iface, + UINT index, BSTR bstrMops) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %u %s - stub\n", This, index, wine_dbgstr_w(bstrMops)); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc(ICreateTypeInfo2 *iface, + IDLDESC *idlDesc) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + + TRACE("%p %p\n", This, idlDesc); + + if (!idlDesc) + return E_INVALIDARG; + + This->idldescType.dwReserved = idlDesc->dwReserved; + This->idldescType.wIDLFlags = idlDesc->wIDLFlags; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(ICreateTypeInfo2 *iface) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + ITypeInfo *tinfo; + TLBFuncDesc *func_desc; + UINT user_vft = 0, i, depth = 0; + HRESULT hres = S_OK; + + TRACE("%p\n", This); + + This->needs_layout = FALSE; + + hres = ICreateTypeInfo2_QueryInterface(iface, &IID_ITypeInfo, (LPVOID*)&tinfo); + if (FAILED(hres)) + return hres; + + if (This->typekind == TKIND_INTERFACE) { + ITypeInfo *inh; + TYPEATTR *attr; + HREFTYPE inh_href; + + hres = ITypeInfo_GetRefTypeOfImplType(tinfo, 0, &inh_href); + + if (SUCCEEDED(hres)) { + hres = ITypeInfo_GetRefTypeInfo(tinfo, inh_href, &inh); + + if (SUCCEEDED(hres)) { + hres = ITypeInfo_GetTypeAttr(inh, &attr); + if (FAILED(hres)) { + ITypeInfo_Release(inh); + ITypeInfo_Release(tinfo); + return hres; + } + This->cbSizeVft = attr->cbSizeVft; + ITypeInfo_ReleaseTypeAttr(inh, attr); + + do{ + ++depth; + hres = ITypeInfo_GetRefTypeOfImplType(inh, 0, &inh_href); + if(SUCCEEDED(hres)){ + ITypeInfo *next; + hres = ITypeInfo_GetRefTypeInfo(inh, inh_href, &next); + if(SUCCEEDED(hres)){ + ITypeInfo_Release(inh); + inh = next; + } + } + }while(SUCCEEDED(hres)); + hres = S_OK; + + ITypeInfo_Release(inh); + } else if (hres == TYPE_E_ELEMENTNOTFOUND) { + This->cbSizeVft = 0; + hres = S_OK; + } else { + ITypeInfo_Release(tinfo); + return hres; + } + } else if (hres == TYPE_E_ELEMENTNOTFOUND) { + This->cbSizeVft = 0; + hres = S_OK; + } else { + ITypeInfo_Release(tinfo); + return hres; + } + } else if (This->typekind == TKIND_DISPATCH) + This->cbSizeVft = 7 * This->pTypeLib->ptr_size; + else + This->cbSizeVft = 0; + + func_desc = This->funcdescs; + i = 0; + while (i < This->cFuncs) { + if (!(func_desc->funcdesc.oVft & 0x1)) + func_desc->funcdesc.oVft = This->cbSizeVft; + + if ((func_desc->funcdesc.oVft & 0xFFFC) > user_vft) + user_vft = func_desc->funcdesc.oVft & 0xFFFC; + + This->cbSizeVft += This->pTypeLib->ptr_size; + + if (func_desc->funcdesc.memid == MEMBERID_NIL) { + TLBFuncDesc *iter; + UINT j = 0; + BOOL reset = FALSE; + + func_desc->funcdesc.memid = 0x60000000 + (depth << 16) + i; + + iter = This->funcdescs; + while (j < This->cFuncs) { + if (iter != func_desc && iter->funcdesc.memid == func_desc->funcdesc.memid) { + if (!reset) { + func_desc->funcdesc.memid = 0x60000000 + (depth << 16) + This->cFuncs; + reset = TRUE; + } else + ++func_desc->funcdesc.memid; + iter = This->funcdescs; + j = 0; + } else { + ++iter; + ++j; + } + } + } + + ++func_desc; + ++i; + } + + if (user_vft > This->cbSizeVft) + This->cbSizeVft = user_vft + This->pTypeLib->ptr_size; + + for(i = 0; i < This->cVars; ++i){ + TLBVarDesc *var_desc = &This->vardescs[i]; + if(var_desc->vardesc.memid == MEMBERID_NIL){ + UINT j = 0; + BOOL reset = FALSE; + TLBVarDesc *iter; + + var_desc->vardesc.memid = 0x40000000 + (depth << 16) + i; + + iter = This->vardescs; + while (j < This->cVars) { + if (iter != var_desc && iter->vardesc.memid == var_desc->vardesc.memid) { + if (!reset) { + var_desc->vardesc.memid = 0x40000000 + (depth << 16) + This->cVars; + reset = TRUE; + } else + ++var_desc->vardesc.memid; + iter = This->vardescs; + j = 0; + } else { + ++iter; + ++j; + } + } + } + } + + ITypeInfo_Release(tinfo); + return hres; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDesc(ICreateTypeInfo2 *iface, + UINT index) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %u - stub\n", This, index); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDescByMemId(ICreateTypeInfo2 *iface, + MEMBERID memid, INVOKEKIND invKind) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %x %d - stub\n", This, memid, invKind); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDesc(ICreateTypeInfo2 *iface, + UINT index) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %u - stub\n", This, index); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDescByMemId(ICreateTypeInfo2 *iface, + MEMBERID memid) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %x - stub\n", This, memid); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnDeleteImplType(ICreateTypeInfo2 *iface, + UINT index) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %u - stub\n", This, index); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetCustData(ICreateTypeInfo2 *iface, + REFGUID guid, VARIANT *varVal) +{ + TLBGuid *tlbguid; + + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + + TRACE("%p %s %p\n", This, debugstr_guid(guid), varVal); + + if (!guid || !varVal) + return E_INVALIDARG; + + tlbguid = TLB_append_guid(&This->pTypeLib->guid_list, guid, -1); + + return TLB_set_custdata(This->pcustdata_list, tlbguid, varVal); +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncCustData(ICreateTypeInfo2 *iface, + UINT index, REFGUID guid, VARIANT *varVal) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %u %s %p - stub\n", This, index, debugstr_guid(guid), varVal); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetParamCustData(ICreateTypeInfo2 *iface, + UINT funcIndex, UINT paramIndex, REFGUID guid, VARIANT *varVal) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %u %u %s %p - stub\n", This, funcIndex, paramIndex, debugstr_guid(guid), varVal); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetVarCustData(ICreateTypeInfo2 *iface, + UINT index, REFGUID guid, VARIANT *varVal) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %u %s %p - stub\n", This, index, debugstr_guid(guid), varVal); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeCustData(ICreateTypeInfo2 *iface, + UINT index, REFGUID guid, VARIANT *varVal) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %u %s %p - stub\n", This, index, debugstr_guid(guid), varVal); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpStringContext(ICreateTypeInfo2 *iface, + ULONG helpStringContext) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + + TRACE("%p %u\n", This, helpStringContext); + + This->dwHelpStringContext = helpStringContext; + + return S_OK; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpStringContext(ICreateTypeInfo2 *iface, + UINT index, ULONG helpStringContext) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %u %u - stub\n", This, index, helpStringContext); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpStringContext(ICreateTypeInfo2 *iface, + UINT index, ULONG helpStringContext) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p %u %u - stub\n", This, index, helpStringContext); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnInvalidate(ICreateTypeInfo2 *iface) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + FIXME("%p - stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ICreateTypeInfo2_fnSetName(ICreateTypeInfo2 *iface, + LPOLESTR name) +{ + ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); + + TRACE("%p %s\n", This, wine_dbgstr_w(name)); + + if (!name) + return E_INVALIDARG; + + This->Name = TLB_append_str(&This->pTypeLib->name_list, name); + + return S_OK; +} + +static const ICreateTypeInfo2Vtbl CreateTypeInfo2Vtbl = { + ICreateTypeInfo2_fnQueryInterface, + ICreateTypeInfo2_fnAddRef, + ICreateTypeInfo2_fnRelease, + ICreateTypeInfo2_fnSetGuid, + ICreateTypeInfo2_fnSetTypeFlags, + ICreateTypeInfo2_fnSetDocString, + ICreateTypeInfo2_fnSetHelpContext, + ICreateTypeInfo2_fnSetVersion, + ICreateTypeInfo2_fnAddRefTypeInfo, + ICreateTypeInfo2_fnAddFuncDesc, + ICreateTypeInfo2_fnAddImplType, + ICreateTypeInfo2_fnSetImplTypeFlags, + ICreateTypeInfo2_fnSetAlignment, + ICreateTypeInfo2_fnSetSchema, + ICreateTypeInfo2_fnAddVarDesc, + ICreateTypeInfo2_fnSetFuncAndParamNames, + ICreateTypeInfo2_fnSetVarName, + ICreateTypeInfo2_fnSetTypeDescAlias, + ICreateTypeInfo2_fnDefineFuncAsDllEntry, + ICreateTypeInfo2_fnSetFuncDocString, + ICreateTypeInfo2_fnSetVarDocString, + ICreateTypeInfo2_fnSetFuncHelpContext, + ICreateTypeInfo2_fnSetVarHelpContext, + ICreateTypeInfo2_fnSetMops, + ICreateTypeInfo2_fnSetTypeIdldesc, + ICreateTypeInfo2_fnLayOut, + ICreateTypeInfo2_fnDeleteFuncDesc, + ICreateTypeInfo2_fnDeleteFuncDescByMemId, + ICreateTypeInfo2_fnDeleteVarDesc, + ICreateTypeInfo2_fnDeleteVarDescByMemId, + ICreateTypeInfo2_fnDeleteImplType, + ICreateTypeInfo2_fnSetCustData, + ICreateTypeInfo2_fnSetFuncCustData, + ICreateTypeInfo2_fnSetParamCustData, + ICreateTypeInfo2_fnSetVarCustData, + ICreateTypeInfo2_fnSetImplTypeCustData, + ICreateTypeInfo2_fnSetHelpStringContext, + ICreateTypeInfo2_fnSetFuncHelpStringContext, + ICreateTypeInfo2_fnSetVarHelpStringContext, + ICreateTypeInfo2_fnInvalidate, + ICreateTypeInfo2_fnSetName +}; + +/****************************************************************************** + * ClearCustData (OLEAUT32.171) + * + * Clear a custom data type's data. + * + * PARAMS + * lpCust [I] The custom data type instance + * + * RETURNS + * Nothing. + */ +void WINAPI ClearCustData(CUSTDATA *lpCust) +{ + if (lpCust && lpCust->cCustData) + { + if (lpCust->prgCustData) + { + DWORD i; + + for (i = 0; i < lpCust->cCustData; i++) + VariantClear(&lpCust->prgCustData[i].varValue); + + /* FIXME - Should be using a per-thread IMalloc */ + heap_free(lpCust->prgCustData); + lpCust->prgCustData = NULL; + } + lpCust->cCustData = 0; + } +} diff --git a/reactos/dll/win32/oleaut32/typelib.h b/reactos/dll/win32/oleaut32/typelib.h index fdf825fdc0a..0fb04f18647 100644 --- a/reactos/dll/win32/oleaut32/typelib.h +++ b/reactos/dll/win32/oleaut32/typelib.h @@ -100,12 +100,12 @@ typedef struct tagMSFT_SegDir { /*2*/MSFT_pSeg pImpInfo; /* table with info for imported types */ /*3*/MSFT_pSeg pImpFiles; /* import libraries */ /*4*/MSFT_pSeg pRefTab; /* References table */ -/*5*/MSFT_pSeg pLibtab; /* always exists, always same size (0x80) */ - /* hash table w offsets to guid????? */ +/*5*/MSFT_pSeg pGuidHashTab; /* always exists, always same size (0x80) */ + /* hash table with offsets to guid */ /*6*/MSFT_pSeg pGuidTab; /* all guids are stored here together with */ /* offset in some table???? */ -/*7*/MSFT_pSeg res07; /* always created, always same size (0x200) */ - /* purpose largely unknown */ +/*7*/MSFT_pSeg pNameHashTab; /* always created, always same size (0x200) */ + /* hash table with offsets to names */ /*8*/MSFT_pSeg pNametab; /* name tables */ /*9*/MSFT_pSeg pStringtab; /* string table */ /*A*/MSFT_pSeg pTypdescTab; /* table with type descriptors */ diff --git a/reactos/dll/win32/oleaut32/typelib2.c b/reactos/dll/win32/oleaut32/typelib2.c deleted file mode 100644 index cb2c04f72f6..00000000000 --- a/reactos/dll/win32/oleaut32/typelib2.c +++ /dev/null @@ -1,5341 +0,0 @@ -/* - * TYPELIB2 - * - * Copyright 2004 Alastair Bridgewater - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - * -------------------------------------------------------------------------------------- - * Known problems: - * - * Badly incomplete. - * - * Only works on little-endian systems. - * - */ - -#define WIN32_NO_STATUS -#define _INC_WINDOWS - -#include -//#include "wine/port.h" - -//#include -//#include -//#include -//#include -//#include - -#define COBJMACROS -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -//#include "winerror.h" -//#include "windef.h" -//#include "winbase.h" -//#include "winnls.h" -//#include "winreg.h" -//#include "winuser.h" - -#include -#include -#include "typelib.h" -#include - -WINE_DEFAULT_DEBUG_CHANNEL(typelib2); -/* WINE_DEFAULT_DEBUG_CHANNEL(ole); */ - - -/****************************************************************************** - * ICreateTypeLib2 {OLEAUT32} - * - * NOTES - * The ICreateTypeLib2 interface provides an interface whereby one may create - * new type library (.tlb) files. - * - * This interface inherits from ICreateTypeLib, and can be freely cast back - * and forth between an ICreateTypeLib and an ICreateTypeLib2 on local clients. - * This dispensation applies only to ICreateTypeLib objects obtained on MSFT - * format type libraries (those made through CreateTypeLib2). - * - * METHODS - */ - -/****************************************************************************** - * ICreateTypeInfo2 {OLEAUT32} - * - * NOTES - * The ICreateTypeInfo2 interface provides an interface whereby one may add - * type information to type library (.tlb) files. - * - * This interface inherits from ICreateTypeInfo, and can be freely cast back - * and forth between an ICreateTypeInfo and an ICreateTypeInfo2 on local clients. - * This dispensation applies only to ICreateTypeInfo objects obtained on MSFT - * format type libraries (those made through CreateTypeLib2). - * - * METHODS - */ - -/****************************************************************************** - * ITypeLib2 {OLEAUT32} - * - * NOTES - * The ITypeLib2 interface provides an interface whereby one may query MSFT - * format type library (.tlb) files. - * - * This interface inherits from ITypeLib, and can be freely cast back and - * forth between an ITypeLib and an ITypeLib2 on local clients. This - * dispensation applies only to ITypeLib objects obtained on MSFT format type - * libraries (those made through CreateTypeLib2). - * - * METHODS - */ - -/****************************************************************************** - * ITypeInfo2 {OLEAUT32} - * - * NOTES - * The ITypeInfo2 interface provides an interface whereby one may query type - * information stored in MSFT format type library (.tlb) files. - * - * This interface inherits from ITypeInfo, and can be freely cast back and - * forth between an ITypeInfo and an ITypeInfo2 on local clients. This - * dispensation applies only to ITypeInfo objects obtained on MSFT format type - * libraries (those made through CreateTypeLib2). - * - * METHODS - */ - -/*================== Implementation Structures ===================================*/ - -/* Used for storing cyclic list. Tail address is kept */ -typedef enum tagCyclicListElementType { - CyclicListSentinel, - CyclicListFunc, - CyclicListVar -} CyclicListElementType; -typedef struct tagCyclicList { - struct tagCyclicList *next; - int indice; - int name; - CyclicListElementType type; - - union { - int val; - int *data; - }u; -} CyclicList; - -enum MSFT_segment_index { - MSFT_SEG_TYPEINFO = 0, /* type information */ - MSFT_SEG_IMPORTINFO, /* import information */ - MSFT_SEG_IMPORTFILES, /* import filenames */ - MSFT_SEG_REFERENCES, /* references (?) */ - MSFT_SEG_GUIDHASH, /* hash table for guids? */ - MSFT_SEG_GUID, /* guid storage */ - MSFT_SEG_NAMEHASH, /* hash table for names */ - MSFT_SEG_NAME, /* name storage */ - MSFT_SEG_STRING, /* string storage */ - MSFT_SEG_TYPEDESC, /* type descriptions */ - MSFT_SEG_ARRAYDESC, /* array descriptions */ - MSFT_SEG_CUSTDATA, /* custom data */ - MSFT_SEG_CUSTDATAGUID, /* custom data guids */ - MSFT_SEG_UNKNOWN, /* ??? */ - MSFT_SEG_UNKNOWN2, /* ??? */ - MSFT_SEG_MAX /* total number of segments */ -}; - -typedef struct tagMSFT_ImpFile { - int guid; - LCID lcid; - int version; - char filename[0]; /* preceded by two bytes of encoded (length << 2) + flags in the low two bits. */ -} MSFT_ImpFile; - -typedef struct tagICreateTypeLib2Impl -{ - ICreateTypeLib2 ICreateTypeLib2_iface; - ITypeLib2 ITypeLib2_iface; - LONG ref; - - BSTR filename; - - MSFT_Header typelib_header; - INT helpStringDll; - MSFT_pSeg typelib_segdir[MSFT_SEG_MAX]; - unsigned char *typelib_segment_data[MSFT_SEG_MAX]; - int typelib_segment_block_length[MSFT_SEG_MAX]; - - int typelib_guids; /* Number of defined typelib guids */ - int typeinfo_guids; /* Number of defined typeinfo guids */ - - INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */ - - INT *typelib_namehash_segment; - INT *typelib_guidhash_segment; - - struct tagICreateTypeInfo2Impl *typeinfos; - struct tagICreateTypeInfo2Impl *last_typeinfo; -} ICreateTypeLib2Impl; - -static inline ICreateTypeLib2Impl *impl_from_ICreateTypeLib2(ICreateTypeLib2 *iface) -{ - return CONTAINING_RECORD(iface, ICreateTypeLib2Impl, ICreateTypeLib2_iface); -} - -static inline ICreateTypeLib2Impl *impl_from_ITypeLib2(ITypeLib2 *iface) -{ - return CONTAINING_RECORD(iface, ICreateTypeLib2Impl, ITypeLib2_iface); -} - -typedef struct tagICreateTypeInfo2Impl -{ - ICreateTypeInfo2 ICreateTypeInfo2_iface; - ITypeInfo2 ITypeInfo2_iface; - - LONG ref; - - ICreateTypeLib2Impl *typelib; - MSFT_TypeInfoBase *typeinfo; - - struct tagCyclicList *typedata; /* tail of cyclic list */ - - TYPEKIND typekind; - int datawidth; - - struct tagICreateTypeInfo2Impl *next_typeinfo; - struct tagICreateTypeInfo2Impl *dual; -} ICreateTypeInfo2Impl; - -static inline ICreateTypeInfo2Impl *impl_from_ICreateTypeInfo2(ICreateTypeInfo2 *iface) -{ - return CONTAINING_RECORD(iface, ICreateTypeInfo2Impl, ICreateTypeInfo2_iface); -} - -static inline ICreateTypeInfo2Impl *impl_from_ITypeInfo2( ITypeInfo2 *iface ) -{ - return CONTAINING_RECORD(iface, ICreateTypeInfo2Impl, ITypeInfo2_iface); -} - -static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface); - -static CyclicList *alloc_cyclic_list_item(CyclicListElementType type) -{ - CyclicList *ret = heap_alloc_zero(sizeof(CyclicList)); - if (!ret) - return NULL; - ret->type = type; - return ret; -} - -/*================== Internal functions ===================================*/ - -static inline UINT cti2_get_var_count(const MSFT_TypeInfoBase *typeinfo) -{ - return typeinfo->cElement >> 16; -} - -static inline UINT cti2_get_func_count(const MSFT_TypeInfoBase *typeinfo) -{ - return typeinfo->cElement & 0xFFFF; -} - -static inline INT ctl2_get_record_size(const CyclicList *iter) -{ - return iter->u.data[0] & 0xFFFF; -} - -static void ctl2_update_var_size(const ICreateTypeInfo2Impl *This, CyclicList *var, int size) -{ - int old = ctl2_get_record_size(var), i; - - if (old >= size) return; - - /* initialize fields included in size but currently unused */ - for (i = old/sizeof(int); i < (size/sizeof(int) - 1); i++) - { - /* HelpContext/HelpStringContext being 0 means it's not set */ - var->u.data[i] = (i == 5 || i == 9) ? 0 : -1; - } - - var->u.data[0] += size - old; - This->typedata->next->u.val += size - old; -} - -/* NOTE: entry always assumed to be a function */ -static inline INVOKEKIND ctl2_get_invokekind(const CyclicList *func) -{ - /* INVOKEKIND uses bit flags up to 8 */ - return (func->u.data[4] >> 3) & 0xF; -} - -static inline SYSKIND ctl2_get_syskind(const ICreateTypeLib2Impl *This) -{ - return This->typelib_header.varflags & 0xF; -} - -/**************************************************************************** - * ctl2_init_header - * - * Initializes the type library header of a new typelib. - */ -static void ctl2_init_header( - ICreateTypeLib2Impl *This) /* [I] The typelib to initialize. */ -{ - This->typelib_header.magic1 = MSFT_SIGNATURE; - This->typelib_header.magic2 = 0x00010002; - This->typelib_header.posguid = -1; - This->typelib_header.lcid = This->typelib_header.lcid2 = GetUserDefaultLCID(); - This->typelib_header.varflags = 0x40; - This->typelib_header.version = 0; - This->typelib_header.flags = 0; - This->typelib_header.nrtypeinfos = 0; - This->typelib_header.helpstring = -1; - This->typelib_header.helpstringcontext = 0; - This->typelib_header.helpcontext = 0; - This->typelib_header.nametablecount = 0; - This->typelib_header.nametablechars = 0; - This->typelib_header.NameOffset = -1; - This->typelib_header.helpfile = -1; - This->typelib_header.CustomDataOffset = -1; - This->typelib_header.res44 = 0x20; - This->typelib_header.res48 = 0x80; - This->typelib_header.dispatchpos = -1; - This->typelib_header.nimpinfos = 0; - This->helpStringDll = -1; -} - -/**************************************************************************** - * ctl2_init_segdir - * - * Initializes the segment directory of a new typelib. - */ -static void ctl2_init_segdir( - ICreateTypeLib2Impl *This) /* [I] The typelib to initialize. */ -{ - int i; - MSFT_pSeg *segdir; - - segdir = &This->typelib_segdir[MSFT_SEG_TYPEINFO]; - - for (i = 0; i < 15; i++) { - segdir[i].offset = -1; - segdir[i].length = 0; - segdir[i].res08 = -1; - segdir[i].res0c = 0x0f; - } -} - -/**************************************************************************** - * ctl2_hash_guid - * - * Generates a hash key from a GUID. - * - * RETURNS - * - * The hash key for the GUID. - */ -static int ctl2_hash_guid( - REFGUID guid) /* [I] The guid to find. */ -{ - int hash; - int i; - - hash = 0; - for (i = 0; i < 8; i ++) { - hash ^= ((const short *)guid)[i]; - } - - return hash & 0x1f; -} - -/**************************************************************************** - * ctl2_find_guid - * - * Locates a guid in a type library. - * - * RETURNS - * - * The offset into the GUID segment of the guid, or -1 if not found. - */ -static int ctl2_find_guid( - ICreateTypeLib2Impl *This, /* [I] The typelib to operate against. */ - int hash_key, /* [I] The hash key for the guid. */ - REFGUID guid) /* [I] The guid to find. */ -{ - int offset; - MSFT_GuidEntry *guidentry; - - offset = This->typelib_guidhash_segment[hash_key]; - while (offset != -1) { - guidentry = (MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][offset]; - - if (IsEqualGUID(guidentry, guid)) return offset; - - offset = guidentry->next_hash; - } - - return offset; -} - -/**************************************************************************** - * ctl2_find_name - * - * Locates a name in a type library. - * - * RETURNS - * - * The offset into the NAME segment of the name, or -1 if not found. - * - * NOTES - * - * The name must be encoded as with ctl2_encode_name(). - */ -static int ctl2_find_name( - ICreateTypeLib2Impl *This, /* [I] The typelib to operate against. */ - const char *name) /* [I] The encoded name to find. */ -{ - int offset; - int *namestruct; - - offset = This->typelib_namehash_segment[name[2] & 0x7f]; - while (offset != -1) { - namestruct = (int *)&This->typelib_segment_data[MSFT_SEG_NAME][offset]; - - if (!((namestruct[2] ^ *((const int *)name)) & 0xffff00ff)) { - /* hash codes and lengths match, final test */ - if (!strncasecmp(name+4, (void *)(namestruct+3), name[0])) break; - } - - /* move to next item in hash bucket */ - offset = namestruct[1]; - } - - return offset; -} - -/**************************************************************************** - * ctl2_encode_name - * - * Encodes a name string to a form suitable for storing into a type library - * or comparing to a name stored in a type library. - * - * RETURNS - * - * The length of the encoded name, including padding and length+hash fields. - * - * NOTES - * - * Will throw an exception if name or result are NULL. Is not multithread - * safe in the slightest. - */ -static int ctl2_encode_name( - ICreateTypeLib2Impl *This, /* [I] The typelib to operate against (used for LCID only). */ - const WCHAR *name, /* [I] The name string to encode. */ - char **result) /* [O] A pointer to a pointer to receive the encoded name. */ -{ - int length; - static char converted_name[0x104]; - int offset; - int value; - - length = WideCharToMultiByte(CP_ACP, 0, name, strlenW(name), converted_name+4, 0x100, NULL, NULL); - converted_name[0] = length & 0xff; - - converted_name[length + 4] = 0; - - converted_name[1] = 0x00; - - value = LHashValOfNameSysA(ctl2_get_syskind(This), This->typelib_header.lcid, converted_name + 4); - - converted_name[2] = value; - converted_name[3] = value >> 8; - - for (offset = (4 - length) & 3; offset; offset--) converted_name[length + offset + 3] = 0x57; - - *result = converted_name; - - return (length + 7) & ~3; -} - -/**************************************************************************** - * ctl2_decode_name - * - * Converts string stored in typelib data to unicode. - */ -static void ctl2_decode_name( - char *data, /* [I] String to be decoded */ - WCHAR **string) /* [O] Decoded string */ -{ - int i, length; - static WCHAR converted_string[0x104]; - - length = data[0]; - - for(i=0; i> 8) & 0xff; - - for (offset = (4 - (length + 2)) & 3; offset; offset--) converted_string[length + offset + 1] = 0x57; - - *result = converted_string; - - return (length + 5) & ~3; -} - -/**************************************************************************** - * ctl2_decode_string - * - * Converts string stored in typelib data to unicode. - */ -static void ctl2_decode_string( - unsigned char *data,/* [I] String to be decoded */ - WCHAR **string) /* [O] Decoded string */ -{ - int i, length; - static WCHAR converted_string[0x104]; - - length = data[0] + (data[1]<<8); - if((length&0x3) == 1) - length >>= 2; - - for(i=0; itypelib_segment_data[segment]) { - if (!block_size) block_size = 0x2000; - - This->typelib_segment_block_length[segment] = block_size; - This->typelib_segment_data[segment] = heap_alloc(block_size); - if (!This->typelib_segment_data[segment]) return -1; - memset(This->typelib_segment_data[segment], 0x57, block_size); - } - - while ((This->typelib_segdir[segment].length + size) > This->typelib_segment_block_length[segment]) { - unsigned char *block; - - block_size = This->typelib_segment_block_length[segment]; - block = heap_realloc(This->typelib_segment_data[segment], block_size << 1); - if (!block) return -1; - - if (segment == MSFT_SEG_TYPEINFO) { - /* TypeInfos have a direct pointer to their memory space, so we have to fix them up. */ - ICreateTypeInfo2Impl *typeinfo; - - for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { - typeinfo->typeinfo = (void *)&block[((unsigned char *)typeinfo->typeinfo) - This->typelib_segment_data[segment]]; - } - } - - memset(block + block_size, 0x57, block_size); - This->typelib_segment_block_length[segment] = block_size << 1; - This->typelib_segment_data[segment] = block; - } - - offset = This->typelib_segdir[segment].length; - This->typelib_segdir[segment].length += size; - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_typeinfo - * - * Allocates and initializes a typeinfo structure in a type library. - * - * RETURNS - * - * Success: The offset of the new typeinfo. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int ctl2_alloc_typeinfo( - ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ - int nameoffset) /* [I] The offset of the name for this typeinfo. */ -{ - int offset; - MSFT_TypeInfoBase *typeinfo; - - offset = ctl2_alloc_segment(This, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0); - if (offset == -1) return -1; - - This->typelib_typeinfo_offsets[This->typelib_header.nrtypeinfos++] = offset; - - typeinfo = (void *)(This->typelib_segment_data[MSFT_SEG_TYPEINFO] + offset); - - typeinfo->typekind = (This->typelib_header.nrtypeinfos - 1) << 16; - typeinfo->memoffset = -1; /* should be EOF if no elements */ - typeinfo->res2 = 0; - typeinfo->res3 = 0; - typeinfo->res4 = 3; - typeinfo->res5 = 0; - typeinfo->cElement = 0; - typeinfo->res7 = 0; - typeinfo->res8 = 0; - typeinfo->res9 = 0; - typeinfo->resA = 0; - typeinfo->posguid = -1; - typeinfo->flags = 0; - typeinfo->NameOffset = nameoffset; - typeinfo->version = 0; - typeinfo->docstringoffs = -1; - typeinfo->helpstringcontext = 0; - typeinfo->helpcontext = 0; - typeinfo->oCustData = -1; - typeinfo->cbSizeVft = 0; - typeinfo->cImplTypes = 0; - typeinfo->size = 0; - typeinfo->datatype1 = -1; - typeinfo->datatype2 = 0; - typeinfo->res18 = 0; - typeinfo->res19 = -1; - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_guid - * - * Allocates and initializes a GUID structure in a type library. Also updates - * the GUID hash table as needed. - * - * RETURNS - * - * Success: The offset of the new GUID. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int ctl2_alloc_guid( - ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ - MSFT_GuidEntry *guid) /* [I] The GUID to store. */ -{ - int offset; - MSFT_GuidEntry *guid_space; - int hash_key; - - hash_key = ctl2_hash_guid(&guid->guid); - - offset = ctl2_find_guid(This, hash_key, &guid->guid); - if (offset != -1) return offset; - - offset = ctl2_alloc_segment(This, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0); - if (offset == -1) return -1; - - guid_space = (void *)(This->typelib_segment_data[MSFT_SEG_GUID] + offset); - *guid_space = *guid; - - guid_space->next_hash = This->typelib_guidhash_segment[hash_key]; - This->typelib_guidhash_segment[hash_key] = offset; - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_name - * - * Allocates and initializes a name within a type library. Also updates the - * name hash table as needed. - * - * RETURNS - * - * Success: The offset within the segment of the new name. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int ctl2_alloc_name( - ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ - const WCHAR *name) /* [I] The name to store. */ -{ - int length; - int offset; - MSFT_NameIntro *name_space; - char *encoded_name; - - length = ctl2_encode_name(This, name, &encoded_name); - - offset = ctl2_find_name(This, encoded_name); - if (offset != -1) return offset; - - offset = ctl2_alloc_segment(This, MSFT_SEG_NAME, length + 8, 0); - if (offset == -1) return -1; - - name_space = (void *)(This->typelib_segment_data[MSFT_SEG_NAME] + offset); - name_space->hreftype = -1; - name_space->next_hash = -1; - memcpy(&name_space->namelen, encoded_name, length); - - if (This->typelib_namehash_segment[encoded_name[2] & 0x7f] != -1) - name_space->next_hash = This->typelib_namehash_segment[encoded_name[2] & 0x7f]; - - This->typelib_namehash_segment[encoded_name[2] & 0x7f] = offset; - - This->typelib_header.nametablecount += 1; - This->typelib_header.nametablechars += *encoded_name; - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_string - * - * Allocates and initializes a string in a type library. - * - * RETURNS - * - * Success: The offset within the segment of the new string. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int ctl2_alloc_string( - ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ - const WCHAR *string) /* [I] The string to store. */ -{ - int length; - int offset; - unsigned char *string_space; - char *encoded_string; - - length = ctl2_encode_string(This, string, &encoded_string); - - for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_STRING].length; - offset += (((This->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) | - This->typelib_segment_data[MSFT_SEG_STRING][offset + 0]) + 5) & ~3) { - if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_STRING] + offset, length)) return offset; - } - - offset = ctl2_alloc_segment(This, MSFT_SEG_STRING, length, 0); - if (offset == -1) return -1; - - string_space = This->typelib_segment_data[MSFT_SEG_STRING] + offset; - memcpy(string_space, encoded_string, length); - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_importinfo - * - * Allocates and initializes an import information structure in a type library. - * - * RETURNS - * - * Success: The offset of the new importinfo. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int ctl2_alloc_importinfo( - ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ - MSFT_ImpInfo *impinfo) /* [I] The import information to store. */ -{ - int offset; - MSFT_ImpInfo *impinfo_space; - - impinfo_space = (MSFT_ImpInfo*)&This->typelib_segment_data[MSFT_SEG_IMPORTINFO][0]; - for (offset=0; offsettypelib_segdir[MSFT_SEG_IMPORTINFO].length; - offset+=sizeof(MSFT_ImpInfo)) { - if(impinfo_space->oImpFile == impinfo->oImpFile - && impinfo_space->oGuid == impinfo->oGuid) - return offset; - - impinfo_space += 1; - } - - impinfo->flags |= This->typelib_header.nimpinfos++; - - offset = ctl2_alloc_segment(This, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0); - if (offset == -1) return -1; - - impinfo_space = (void *)(This->typelib_segment_data[MSFT_SEG_IMPORTINFO] + offset); - *impinfo_space = *impinfo; - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_importfile - * - * Allocates and initializes an import file definition in a type library. - * - * RETURNS - * - * Success: The offset of the new importinfo. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int ctl2_alloc_importfile( - ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ - int guidoffset, /* [I] The offset to the GUID for the imported library. */ - LCID lcid, /* [I] The LCID of imported library. */ - int major_version, /* [I] The major version number of the imported library. */ - int minor_version, /* [I] The minor version number of the imported library. */ - const WCHAR *filename) /* [I] The filename of the imported library. */ -{ - int length; - int offset; - MSFT_ImpFile *importfile; - char *encoded_string; - - length = ctl2_encode_string(This, filename, &encoded_string); - - encoded_string[0] <<= 2; - encoded_string[0] |= 1; - - for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_IMPORTFILES].length; - offset += (((((This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xd] << 8) | - This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xc]) >> 2) + 5) & 0xfffc) + 0xc) { - if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_IMPORTFILES] + offset + 0xc, length)) return offset; - } - - offset = ctl2_alloc_segment(This, MSFT_SEG_IMPORTFILES, length + 0xc, 0); - if (offset == -1) return -1; - - importfile = (MSFT_ImpFile *)&This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset]; - importfile->guid = guidoffset; - importfile->lcid = lcid; - importfile->version = major_version | (minor_version << 16); - memcpy(importfile->filename, encoded_string, length); - - return offset; -} - -/**************************************************************************** - * ctl2_encode_variant - * - * Encodes a variant, inline if possible or in custom data segment - * - * RETURNS - * - * Success: S_OK - * Failure: Error code from winerror.h - */ -static HRESULT ctl2_encode_variant( - ICreateTypeLib2Impl *This, /* [I] The typelib to allocate data in */ - int *encoded_value, /* [O] The encoded default value or data offset */ - VARIANT *value, /* [I] Default value to be encoded */ - VARTYPE arg_type) /* [I] Argument type */ -{ - VARIANT v; - HRESULT hres; - int mask = 0; - - TRACE("%p %d %d\n", This, V_VT(value), arg_type); - - if(arg_type == VT_INT) - arg_type = VT_I4; - if(arg_type == VT_UINT) - arg_type = VT_UI4; - - v = *value; - if(V_VT(value) != arg_type) { - hres = VariantChangeType(&v, value, 0, arg_type); - if(FAILED(hres)) - return hres; - } - - /* Check if default value can be stored in encoded_value */ - switch(arg_type) { - case VT_I4: - case VT_UI4: - mask = 0x3ffffff; - if(V_UI4(&v)>0x3ffffff) - break; - /* fall through */ - case VT_I1: - case VT_UI1: - case VT_BOOL: - if(!mask) - mask = 0xff; - /* fall through */ - case VT_I2: - case VT_UI2: - if(!mask) - mask = 0xffff; - *encoded_value = (V_UI4(&v)&mask) | ((0x80+0x4*arg_type)<<24); - return S_OK; - } - - switch(arg_type) { - case VT_I4: - case VT_R4: - case VT_UI4: - case VT_INT: - case VT_UINT: - case VT_HRESULT: - case VT_PTR: { - /* Construct the data to be allocated */ - int data[2]; - data[0] = arg_type + (V_UI4(&v)<<16); - data[1] = (V_UI4(&v)>>16) + 0x57570000; - - /* Check if the data was already allocated */ - /* Currently the structures doesn't allow to do it in a nice way */ - for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-8; *encoded_value+=4) - if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8)) - return S_OK; - - /* Allocate the data */ - *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, 8, 0); - if(*encoded_value == -1) - return E_OUTOFMEMORY; - - memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8); - return S_OK; - } - case VT_BSTR: { - /* Construct the data */ - int i, len = (6+SysStringLen(V_BSTR(&v))+3) & ~0x3; - char *data = heap_alloc(len); - - if(!data) - return E_OUTOFMEMORY; - - *((unsigned short*)data) = arg_type; - *((unsigned*)(data+2)) = SysStringLen(V_BSTR(&v)); - for(i=0; itypelib_segdir[MSFT_SEG_CUSTDATA].length-len; *encoded_value+=4) - if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len)) { - heap_free(data); - return S_OK; - } - - /* Allocate the data */ - *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, len, 0); - if(*encoded_value == -1) { - heap_free(data); - return E_OUTOFMEMORY; - } - - memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len); - heap_free(data); - return S_OK; - } - default: - FIXME("Argument type not yet handled\n"); - return E_NOTIMPL; - } -} - -static int ctl2_find_custdata( - ICreateTypeLib2Impl *This, - REFGUID guid, - int offset) -{ - while (offset != -1) { - MSFT_CDGuid *cdentry = - (MSFT_CDGuid *)&This->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][offset]; - MSFT_GuidEntry *guidentry = - (MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][cdentry->GuidOffset]; - - if (IsEqualGUID(guidentry, guid)) - return offset; - - offset = cdentry->next; - } - - return -1; -} - -/**************************************************************************** - * ctl2_decode_variant - * - * Decodes a variant - * - * RETURNS - * - * Success: S_OK - * Failure: Error code from winerror.h - */ -static HRESULT ctl2_decode_variant( - ICreateTypeLib2Impl *This, /* [I] The typelib that contains the variant */ - int data_offs, /* [I] Offset within the data array, or the encoded value itself */ - VARIANT *value) /* [O] Decoded value */ -{ - unsigned char *encoded_data; - VARTYPE type; - - if (data_offs & 0x80000000) { - /* data_offs contains the encoded value */ - V_VT(value) = (data_offs & ~0x80000000) >> 26; - V_UI4(value) = data_offs & ~0xFF000000; - return S_OK; - } - - encoded_data = &This->typelib_segment_data[MSFT_SEG_CUSTDATA][data_offs]; - type = *encoded_data; - - switch(type) { - case VT_I4: - case VT_R4: - case VT_UI4: - case VT_INT: - case VT_UINT: - case VT_HRESULT: - case VT_PTR: { - V_VT(value) = type; - V_UI4(value) = *(unsigned*)(encoded_data + 2); - return S_OK; - } - case VT_BSTR: { - unsigned len, i; - - len = *(unsigned*)(encoded_data + 2); - - V_VT(value) = type; - V_BSTR(value) = SysAllocStringByteLen(NULL, len * sizeof(OLECHAR)); - for (i = 0; i < len; ++i) - V_BSTR(value)[i] = *(encoded_data + 6 + i); - - return S_OK; - } - default: - FIXME("Don't yet have decoder for this VARTYPE: %u\n", type); - return E_NOTIMPL; - } -} - -/**************************************************************************** - * ctl2_set_custdata - * - * Adds a custom data element to an object in a type library. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_INVALIDARG or E_OUTOFMEMORY. - */ -static HRESULT ctl2_set_custdata( - ICreateTypeLib2Impl *This, /* [I] The type library to store the custom data in. */ - REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ - VARIANT *pVarVal, /* [I] The custom data itself. */ - int *offset) /* [I/O] The list of custom data to prepend to. */ -{ - MSFT_GuidEntry guidentry; - HRESULT status; - int dataoffset; - int guidoffset; - int custoffset; - int *custdata; - BOOL new_segment = FALSE; - - switch(V_VT(pVarVal)) - { - case VT_I4: - case VT_R4: - case VT_UI4: - case VT_INT: - case VT_UINT: - case VT_HRESULT: - case VT_BSTR: - /* empty */ - break; - default: - return DISP_E_BADVARTYPE; - } - - guidentry.guid = *guid; - - guidentry.hreftype = -1; - guidentry.next_hash = -1; - - guidoffset = ctl2_alloc_guid(This, &guidentry); - if (guidoffset == -1) return E_OUTOFMEMORY; - - status = ctl2_encode_variant(This, &dataoffset, pVarVal, V_VT(pVarVal)); - if (status) - return status; - - custoffset = ctl2_find_custdata(This, guid, *offset); - if (custoffset == -1) { - custoffset = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATAGUID, 12, 0); - if (custoffset == -1) - return E_OUTOFMEMORY; - new_segment = TRUE; - } - - custdata = (int *)&This->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset]; - custdata[0] = guidoffset; - custdata[1] = dataoffset; - if (new_segment) { - custdata[2] = *offset; - *offset = custoffset; - } - - return S_OK; -} - -/**************************************************************************** - * ctl2_encode_typedesc - * - * Encodes a type description, storing information in the TYPEDESC and ARRAYDESC - * segments as needed. - * - * RETURNS - * - * Success: 0. - * Failure: -1. - */ -static int ctl2_encode_typedesc( - ICreateTypeLib2Impl *This, /* [I] The type library in which to encode the TYPEDESC. */ - const TYPEDESC *tdesc, /* [I] The type description to encode. */ - int *encoded_tdesc, /* [O] The encoded type description. */ - int *width, /* [O] The width of the type, or NULL. */ - int *alignment, /* [O] The alignment of the type, or NULL. */ - int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */ -{ - int default_tdesc; - int scratch; - int typeoffset; - int arrayoffset; - int *typedata; - int *arraydata; - int target_type; - int child_size; - - default_tdesc = 0x80000000 | (tdesc->vt << 16) | tdesc->vt; - if (!width) width = &scratch; - if (!alignment) alignment = &scratch; - if (!decoded_size) decoded_size = &scratch; - - *decoded_size = 0; - - switch (tdesc->vt) { - case VT_UI1: - case VT_I1: - *encoded_tdesc = default_tdesc; - *width = 1; - *alignment = 1; - break; - - case VT_INT: - *encoded_tdesc = 0x80000000 | (VT_I4 << 16) | VT_INT; - if (ctl2_get_syskind(This) == SYS_WIN16) { - *width = 2; - *alignment = 2; - } else { - *width = 4; - *alignment = 4; - } - break; - - case VT_UINT: - *encoded_tdesc = 0x80000000 | (VT_UI4 << 16) | VT_UINT; - if (ctl2_get_syskind(This) == SYS_WIN16) { - *width = 2; - *alignment = 2; - } else { - *width = 4; - *alignment = 4; - } - break; - - case VT_UI2: - case VT_I2: - case VT_BOOL: - *encoded_tdesc = default_tdesc; - *width = 2; - *alignment = 2; - break; - - case VT_I4: - case VT_UI4: - case VT_R4: - case VT_ERROR: - case VT_BSTR: - case VT_HRESULT: - *encoded_tdesc = default_tdesc; - *width = 4; - *alignment = 4; - break; - - case VT_CY: - *encoded_tdesc = default_tdesc; - *width = 8; - *alignment = 4; /* guess? */ - break; - - case VT_VOID: - *encoded_tdesc = 0x80000000 | (VT_EMPTY << 16) | tdesc->vt; - *width = 0; - *alignment = 1; - break; - - case VT_PTR: - case VT_SAFEARRAY: - /* FIXME: Make with the error checking. */ - FIXME("PTR or SAFEARRAY vartype, may not work correctly.\n"); - - ctl2_encode_typedesc(This, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size); - - for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { - typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - if (((typedata[0] & 0xffff) == tdesc->vt) && (typedata[1] == target_type)) break; - } - - if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) { - int mix_field; - - if (target_type & 0x80000000) { - mix_field = (target_type >> 16) & VT_TYPEMASK; - } else { - typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; - switch((typedata[0]>>16) & ~VT_ARRAY) - { - case VT_UI1: - case VT_I1: - case VT_UI2: - case VT_I2: - case VT_I4: - case VT_UI4: - mix_field = typedata[0]>>16; - break; - default: - mix_field = ((typedata[0] >> 16) == 0x7fff) ? 0x7fff : 0x7ffe; - break; - } - } - - if (tdesc->vt == VT_PTR) - mix_field |= VT_BYREF; - else if (tdesc->vt == VT_SAFEARRAY) - mix_field |= VT_ARRAY; - - typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (mix_field << 16) | tdesc->vt; - typedata[1] = target_type; - } - - *encoded_tdesc = typeoffset; - - *width = 4; - *alignment = 4; - *decoded_size = sizeof(TYPEDESC) + child_size; - break; - - case VT_CARRAY: - { - /* FIXME: Make with the error checking. */ - int num_dims = tdesc->u.lpadesc->cDims, elements = 1, dim; - - ctl2_encode_typedesc(This, &tdesc->u.lpadesc->tdescElem, &target_type, width, alignment, NULL); - arrayoffset = ctl2_alloc_segment(This, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(int), 0); - arraydata = (void *)&This->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset]; - - arraydata[0] = target_type; - arraydata[1] = num_dims; - arraydata[1] |= ((num_dims * 2 * sizeof(int)) << 16); - arraydata += 2; - - for(dim = 0; dim < num_dims; dim++) { - arraydata[0] = tdesc->u.lpadesc->rgbounds[dim].cElements; - arraydata[1] = tdesc->u.lpadesc->rgbounds[dim].lLbound; - elements *= tdesc->u.lpadesc->rgbounds[dim].cElements; - arraydata += 2; - } - typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (0x7ffe << 16) | VT_CARRAY; - typedata[1] = arrayoffset; - - *encoded_tdesc = typeoffset; - *width = *width * elements; - *decoded_size = sizeof(ARRAYDESC) + (num_dims - 1) * sizeof(SAFEARRAYBOUND); - - break; - } - case VT_USERDEFINED: - { - const MSFT_TypeInfoBase *basetype; - INT basevt = 0x7fff; - - TRACE("USERDEFINED.\n"); - if (tdesc->u.hreftype % sizeof(*basetype) == 0 && tdesc->u.hreftype < This->typelib_segdir[MSFT_SEG_TYPEINFO].length) - { - basetype = (MSFT_TypeInfoBase*)&(This->typelib_segment_data[MSFT_SEG_TYPEINFO][tdesc->u.hreftype]); - switch(basetype->typekind & 0xf) - { - case TKIND_ENUM: - basevt = VT_I4; - break; - default: - FIXME("USERDEFINED basetype %d not handled\n", basetype->typekind & 0xf); - break; - } - } - for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { - typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - if ((typedata[0] == ((basevt << 16) | VT_USERDEFINED)) && (typedata[1] == tdesc->u.hreftype)) break; - } - - if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) { - typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (basevt << 16) | VT_USERDEFINED; - typedata[1] = tdesc->u.hreftype; - } - - *encoded_tdesc = typeoffset; - *width = 0; - *alignment = 1; - break; - } - - default: - FIXME("Unrecognized type %d.\n", tdesc->vt); - *encoded_tdesc = default_tdesc; - *width = 0; - *alignment = 1; - break; - } - - return 0; -} - -/**************************************************************************** - * ctl2_decode_typedesc - * - * Decodes a type description from an ICreateTypeLib2Impl. - * - * RETURNS - * - * Success: S_OK. - * Failure: HRESULT error code. - */ -static HRESULT ctl2_decode_typedesc( - ICreateTypeLib2Impl *This, /* [I] The type library from which to decode the TYPEDESC. */ - int encoded_tdesc, /* [I] The encoded type description. */ - TYPEDESC *tdesc) /* [O] The decoded type description. */ -{ - int *typedata, i; - HRESULT hres; - - if (encoded_tdesc & 0x80000000) { - tdesc->vt = encoded_tdesc & VT_TYPEMASK; - tdesc->u.lptdesc = NULL; - return S_OK; - } - - typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][encoded_tdesc]; - - tdesc->vt = typedata[0] & 0xFFFF; - - switch(tdesc->vt) { - case VT_PTR: - case VT_SAFEARRAY: - tdesc->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC)); - if (!tdesc->u.lptdesc) - return E_OUTOFMEMORY; - - hres = ctl2_decode_typedesc(This, typedata[1], tdesc->u.lptdesc); - if (FAILED(hres)) { - heap_free(tdesc->u.lptdesc); - return hres; - } - - return S_OK; - - case VT_CARRAY: { - int arrayoffset, *arraydata, num_dims; - - arrayoffset = typedata[1]; - arraydata = (void *)&This->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset]; - num_dims = arraydata[1] & 0xFFFF; - - tdesc->u.lpadesc = heap_alloc_zero(sizeof(ARRAYDESC) + sizeof(SAFEARRAYBOUND) * (num_dims - 1)); - if (!tdesc->u.lpadesc) - return E_OUTOFMEMORY; - - hres = ctl2_decode_typedesc(This, arraydata[0], &tdesc->u.lpadesc->tdescElem); - if (FAILED(hres)) { - heap_free(tdesc->u.lpadesc); - return E_OUTOFMEMORY; - } - - for (i = 0; i < num_dims; ++i) { - tdesc->u.lpadesc->rgbounds[i].cElements = arraydata[2 + i * 2]; - tdesc->u.lpadesc->rgbounds[i].lLbound = arraydata[3 + i * 2]; - } - - return S_OK; - } - case VT_USERDEFINED: - tdesc->u.hreftype = typedata[1]; - return S_OK; - default: - FIXME("unable to decode typedesc (%08x): unknown VT: %d\n", encoded_tdesc, tdesc->vt); - return E_NOTIMPL; - } -} - -/**************************************************************************** - * ctl2_find_nth_reference - * - * Finds a reference by index into the linked list of reference records. - * - * RETURNS - * - * Success: Offset of the desired reference record. - * Failure: -1. - */ -static int ctl2_find_nth_reference( - ICreateTypeLib2Impl *This, /* [I] The type library in which to search. */ - int offset, /* [I] The starting offset of the reference list. */ - int index) /* [I] The index of the reference to find. */ -{ - MSFT_RefRecord *ref; - - for (; index && (offset != -1); index--) { - ref = (MSFT_RefRecord *)&This->typelib_segment_data[MSFT_SEG_REFERENCES][offset]; - offset = ref->onext; - } - - return offset; -} - -/**************************************************************************** - * ctl2_find_typeinfo_from_offset - * - * Finds an ITypeInfo given an offset into the TYPEINFO segment. - * - * RETURNS - * - * Success: S_OK. - * Failure: TYPE_E_ELEMENTNOTFOUND. - */ -static HRESULT ctl2_find_typeinfo_from_offset( - ICreateTypeLib2Impl *This, /* [I] The typelib to find the typeinfo in. */ - int offset, /* [I] The offset of the desired typeinfo. */ - ITypeInfo **ppTinfo) /* [I] The typeinfo found. */ -{ - void *typeinfodata; - ICreateTypeInfo2Impl *typeinfo; - - typeinfodata = &This->typelib_segment_data[MSFT_SEG_TYPEINFO][offset]; - - for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { - if (typeinfo->typeinfo == typeinfodata) { - *ppTinfo = (ITypeInfo *)&typeinfo->ITypeInfo2_iface; - ITypeInfo_AddRef(*ppTinfo); - return S_OK; - } - } - - ERR("Failed to find typeinfo, invariant varied.\n"); - - return TYPE_E_ELEMENTNOTFOUND; -} - -/**************************************************************************** - * funcrecord_reallochdr - * - * Ensure FuncRecord data block contains header of required size - * - * PARAMS - * - * typedata [IO] - reference to pointer to data block - * need [I] - required size of block in bytes - * - * RETURNS - * - * Number of additionally allocated bytes - */ -static INT funcrecord_reallochdr(INT **typedata, int need) -{ - int tail = (*typedata)[5]*((*typedata)[4]&0x1000?16:12); - int hdr = (*typedata)[0] - tail; - int i; - - if (hdr >= need) - return 0; - - *typedata = heap_realloc(*typedata, need + tail); - if (!*typedata) - return -1; - - if (tail) - memmove((char*)*typedata + need, (const char*)*typedata + hdr, tail); - (*typedata)[0] = need + tail; - - /* fill in default values */ - for(i = (hdr+3)/4; (i+1)*4 <= need; i++) - { - switch(i) - { - case 2: - (*typedata)[i] = 0; - break; - case 7: - (*typedata)[i] = -1; - break; - case 8: - (*typedata)[i] = -1; - break; - case 9: - (*typedata)[i] = -1; - break; - case 10: - (*typedata)[i] = -1; - break; - case 11: - (*typedata)[i] = 0; - break; - case 12: - (*typedata)[i] = -1; - break; - } - } - - return need - hdr; -} - -/*================== ICreateTypeInfo2 Implementation ===================================*/ - -/****************************************************************************** - * ICreateTypeInfo2_QueryInterface {OLEAUT32} - * - */ -static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface( - ICreateTypeInfo2 * iface, - REFIID riid, - VOID **ppvObject) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid)); - - *ppvObject=NULL; - if(IsEqualIID(riid, &IID_IUnknown) || - IsEqualIID(riid,&IID_ICreateTypeInfo)|| - IsEqualIID(riid,&IID_ICreateTypeInfo2)) - { - *ppvObject = This; - } else if (IsEqualIID(riid, &IID_ITypeInfo) || - IsEqualIID(riid, &IID_ITypeInfo2)) { - *ppvObject = &This->ITypeInfo2_iface; - } - - if(*ppvObject) - { - ICreateTypeInfo2_AddRef(iface); - TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject); - return S_OK; - } - TRACE("-- Interface: E_NOINTERFACE\n"); - return E_NOINTERFACE; -} - -/****************************************************************************** - * ICreateTypeInfo2_AddRef {OLEAUT32} - */ -static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p)->ref was %u\n",This, ref - 1); - - if(ref==1 && This->typelib) - ICreateTypeLib2_AddRef(&This->typelib->ICreateTypeLib2_iface); - - return ref; -} - -/****************************************************************************** - * ICreateTypeInfo2_Release {OLEAUT32} - */ -static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(%u)\n",This, ref); - - if (!ref) { - if (This->typelib) { - ICreateTypeLib2_fnRelease(&This->typelib->ICreateTypeLib2_iface); - /* Keep This->typelib reference to make stored ICreateTypeInfo structure valid */ - /* This->typelib = NULL; */ - } - - /* ICreateTypeLib2 frees all ICreateTypeInfos when it releases. */ - /* HeapFree(GetProcessHeap(),0,This); */ - return 0; - } - - return ref; -} - - -/****************************************************************************** - * ICreateTypeInfo2_SetGuid {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetGuid(ICreateTypeInfo2 *iface, REFGUID guid) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - MSFT_GuidEntry guidentry; - int offset; - - TRACE("(%p,%s)\n", iface, debugstr_guid(guid)); - - guidentry.guid = *guid; - guidentry.hreftype = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16]; - guidentry.next_hash = -1; - - offset = ctl2_alloc_guid(This->typelib, &guidentry); - - if (offset == -1) return E_OUTOFMEMORY; - - This->typeinfo->posguid = offset; - - if (IsEqualIID(guid, &IID_IDispatch)) { - This->typelib->typelib_header.dispatchpos = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16]; - } - - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetTypeFlags {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, UINT uTypeFlags) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - TRACE("(%p,0x%x)\n", iface, uTypeFlags); - - if(uTypeFlags & TYPEFLAG_FDUAL) { - This->typeinfo->typekind |= 0x10; - This->typeinfo->typekind &= ~0x0f; - This->typeinfo->typekind |= TKIND_DISPATCH; - - if(!This->dual) { - This->dual = heap_alloc(sizeof(ICreateTypeInfo2Impl)); - if(!This->dual) - return E_OUTOFMEMORY; - - memcpy(This->dual, This, sizeof(ICreateTypeInfo2Impl)); - This->dual->ref = 0; - This->dual->typekind = This->typekind==TKIND_DISPATCH ? - TKIND_INTERFACE : TKIND_DISPATCH; - This->dual->dual = This; - } - - /* Make sure dispatch is in typeinfos queue */ - if(This->typekind != TKIND_DISPATCH) { - if(This->typelib->last_typeinfo == This) - This->typelib->last_typeinfo = This->dual; - - if(This->typelib->typeinfos == This) - This->typelib->typeinfos = This->dual; - else { - ICreateTypeInfo2Impl *iter; - - for(iter=This->typelib->typeinfos; iter->next_typeinfo!=This; iter=iter->next_typeinfo); - iter->next_typeinfo = This->dual; - } - } else - iface = &This->dual->ICreateTypeInfo2_iface; - } - - if (uTypeFlags & (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL)) { - static const WCHAR stdole2tlb[] = { 's','t','d','o','l','e','2','.','t','l','b',0 }; - ITypeLib *stdole; - ITypeInfo *dispatch; - HREFTYPE hreftype; - HRESULT hres; - - hres = LoadTypeLib(stdole2tlb, &stdole); - if(FAILED(hres)) - return hres; - - hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &dispatch); - ITypeLib_Release(stdole); - if(FAILED(hres)) - return hres; - - hres = ICreateTypeInfo2_AddRefTypeInfo(iface, dispatch, &hreftype); - ITypeInfo_Release(dispatch); - if(FAILED(hres)) - return hres; - } - - This->typeinfo->flags = uTypeFlags; - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetDocString {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetDocString( - ICreateTypeInfo2* iface, - LPOLESTR pStrDoc) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - int offset; - - TRACE("(%p,%s)\n", iface, debugstr_w(pStrDoc)); - if (!pStrDoc) - return E_INVALIDARG; - - offset = ctl2_alloc_string(This->typelib, pStrDoc); - if (offset == -1) return E_OUTOFMEMORY; - This->typeinfo->docstringoffs = offset; - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetHelpContext {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext( - ICreateTypeInfo2* iface, - DWORD dwHelpContext) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - TRACE("(%p,%d)\n", iface, dwHelpContext); - - This->typeinfo->helpcontext = dwHelpContext; - - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetVersion {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetVersion( - ICreateTypeInfo2* iface, - WORD wMajorVerNum, - WORD wMinorVerNum) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum); - - This->typeinfo->version = wMajorVerNum | (wMinorVerNum << 16); - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_AddRefTypeInfo {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo( - ICreateTypeInfo2* iface, - ITypeInfo* pTInfo, - HREFTYPE* phRefType) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - ITypeLib *container; - UINT index; - HRESULT res; - - TRACE("(%p,%p,%p)\n", iface, pTInfo, phRefType); - - if(!pTInfo || !phRefType) - return E_INVALIDARG; - - /* - * Unfortunately, we can't rely on the passed-in TypeInfo even having the - * same internal structure as one of ours. It could be from another - * implementation of ITypeInfo. So we need to do the following... - */ - res = ITypeInfo_GetContainingTypeLib(pTInfo, &container, &index); - if (FAILED(res)) { - TRACE("failed to find containing typelib.\n"); - return res; - } - - if (container == (ITypeLib *)&This->typelib->ITypeLib2_iface) { - /* Process locally defined TypeInfo */ - *phRefType = This->typelib->typelib_typeinfo_offsets[index]; - } else { - BSTR name; - TLIBATTR *tlibattr; - TYPEATTR *typeattr; - TYPEKIND typekind; - MSFT_GuidEntry guid, *check_guid; - MSFT_ImpInfo impinfo; - int guid_offset, import_offset; - HRESULT hres; - - /* Allocate container GUID */ - hres = ITypeLib_GetLibAttr(container, &tlibattr); - if(FAILED(hres)) { - ITypeLib_Release(container); - return hres; - } - - guid.guid = tlibattr->guid; - guid.hreftype = This->typelib->typelib_segdir[MSFT_SEG_IMPORTFILES].length+2; - guid.next_hash = -1; - - guid_offset = ctl2_alloc_guid(This->typelib, &guid); - if(guid_offset == -1) { - ITypeLib_ReleaseTLibAttr(container, tlibattr); - ITypeLib_Release(container); - return E_OUTOFMEMORY; - } - - check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset]; - if(check_guid->hreftype == guid.hreftype) - This->typelib->typelib_guids++; - - /* Get import file name */ - hres = QueryPathOfRegTypeLib(&guid.guid, tlibattr->wMajorVerNum, - tlibattr->wMinorVerNum, tlibattr->lcid, &name); - if(FAILED(hres)) { - ITypeLib_ReleaseTLibAttr(container, tlibattr); - ITypeLib_Release(container); - return hres; - } - - /* Import file */ - import_offset = ctl2_alloc_importfile(This->typelib, guid_offset, tlibattr->lcid, - tlibattr->wMajorVerNum, tlibattr->wMinorVerNum, strrchrW(name, '\\')+1); - ITypeLib_ReleaseTLibAttr(container, tlibattr); - SysFreeString(name); - - if(import_offset == -1) { - ITypeLib_Release(container); - return E_OUTOFMEMORY; - } - - /* Allocate referenced guid */ - hres = ITypeInfo_GetTypeAttr(pTInfo, &typeattr); - if(FAILED(hres)) { - ITypeLib_Release(container); - return hres; - } - - guid.guid = typeattr->guid; - guid.hreftype = This->typelib->typeinfo_guids*12+1; - guid.next_hash = -1; - typekind = typeattr->typekind; - ITypeInfo_ReleaseTypeAttr(pTInfo, typeattr); - - guid_offset = ctl2_alloc_guid(This->typelib, &guid); - if(guid_offset == -1) { - ITypeLib_Release(container); - return E_OUTOFMEMORY; - } - - check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset]; - if(check_guid->hreftype == guid.hreftype) - This->typelib->typeinfo_guids++; - - /* Allocate importinfo */ - impinfo.flags = (typekind<<24) | MSFT_IMPINFO_OFFSET_IS_GUID; - impinfo.oImpFile = import_offset; - impinfo.oGuid = guid_offset; - *phRefType = ctl2_alloc_importinfo(This->typelib, &impinfo)+1; - - if(IsEqualGUID(&guid.guid, &IID_IDispatch)) - This->typelib->typelib_header.dispatchpos = *phRefType; - } - - ITypeLib_Release(container); - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_AddFuncDesc {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( - ICreateTypeInfo2* iface, - UINT index, - FUNCDESC* pFuncDesc) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - CyclicList *iter, *insert; - int *typedata; - int i, num_defaults = 0, num_retval = 0; - int decoded_size; - HRESULT hres; - - TRACE("(%p,%d,%p)\n", iface, index, pFuncDesc); - - if(!pFuncDesc || pFuncDesc->oVft&3) - return E_INVALIDARG; - - TRACE("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid, - pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind, - pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams, - pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes, - pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags); - - if(pFuncDesc->cParamsOpt || pFuncDesc->cScodes) - FIXME("Unimplemented parameter - created typelib will be incorrect\n"); - - switch(This->typekind) { - case TKIND_MODULE: - if(pFuncDesc->funckind != FUNC_STATIC) - return TYPE_E_BADMODULEKIND; - break; - case TKIND_DISPATCH: - if(pFuncDesc->funckind != FUNC_DISPATCH) - return TYPE_E_BADMODULEKIND; - break; - default: - if(pFuncDesc->funckind != FUNC_PUREVIRTUAL) - return TYPE_E_BADMODULEKIND; - } - - if(cti2_get_func_count(This->typeinfo) < index) - return TYPE_E_ELEMENTNOTFOUND; - - if((pFuncDesc->invkind&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) && - !pFuncDesc->cParams) - return TYPE_E_INCONSISTENTPROPFUNCS; - - /* get number of arguments with default values specified */ - for (i = 0; i < pFuncDesc->cParams; i++) { - if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) - num_defaults++; - if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL) - num_retval++; - } - - if (!This->typedata) { - This->typedata = alloc_cyclic_list_item(CyclicListSentinel); - if(!This->typedata) - return E_OUTOFMEMORY; - - This->typedata->next = This->typedata; - - if(This->dual) - This->dual->typedata = This->typedata; - } - - /* allocate type data space for us */ - insert = alloc_cyclic_list_item(CyclicListFunc); - if(!insert) - return E_OUTOFMEMORY; - insert->u.data = heap_alloc(FIELD_OFFSET(MSFT_FuncRecord, HelpContext) + - sizeof(int)*(num_defaults?4:3)*pFuncDesc->cParams); - if(!insert->u.data) { - heap_free(insert); - return E_OUTOFMEMORY; - } - - /* fill out the basic type information */ - typedata = insert->u.data; - typedata[0] = FIELD_OFFSET(MSFT_FuncRecord, HelpContext) + pFuncDesc->cParams*(num_defaults?16:12); - ctl2_encode_typedesc(This->typelib, &pFuncDesc->elemdescFunc.tdesc, &typedata[1], NULL, NULL, &decoded_size); - typedata[2] = pFuncDesc->wFuncFlags; - typedata[3] = ((sizeof(FUNCDESC) + decoded_size) << 16) | (unsigned short)(pFuncDesc->oVft?pFuncDesc->oVft+1:0); - typedata[4] = (pFuncDesc->callconv << 8) | (pFuncDesc->invkind << 3) | pFuncDesc->funckind; - if(num_defaults) typedata[4] |= 0x1000; - if (num_retval) typedata[4] |= 0x4000; - typedata[5] = pFuncDesc->cParams; - - /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */ - /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */ - typedata[3] += (sizeof(ELEMDESC) * pFuncDesc->cParams) << 16; - typedata[3] += (sizeof(PARAMDESCEX) * num_defaults) << 16; - - /* add default values */ - if(num_defaults) { - for (i = 0; i < pFuncDesc->cParams; i++) - if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) { - hres = ctl2_encode_variant(This->typelib, typedata+6+i, - &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue, - pFuncDesc->lprgelemdescParam[i].tdesc.vt); - - if(FAILED(hres)) { - heap_free(insert->u.data); - heap_free(insert); - return hres; - } - } else - typedata[6+i] = 0xffffffff; - - num_defaults = pFuncDesc->cParams; - } - - /* add arguments */ - for (i = 0; i < pFuncDesc->cParams; i++) { - ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc, - &typedata[6+num_defaults+(i*3)], NULL, NULL, &decoded_size); - typedata[7+num_defaults+(i*3)] = -1; - typedata[8+num_defaults+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags; - typedata[3] += decoded_size << 16; - } - - /* update the index data */ - insert->indice = pFuncDesc->memid; - insert->name = -1; - - /* insert type data to list */ - if(index == cti2_get_func_count(This->typeinfo)) { - insert->next = This->typedata->next; - This->typedata->next = insert; - This->typedata = insert; - - if(This->dual) - This->dual->typedata = This->typedata; - } else { - unsigned int j; - - iter = This->typedata->next; - for (j = 0; j < index; j++) - iter = iter->next; - - insert->next = iter->next; - iter->next = insert; - } - - /* update type data size */ - This->typedata->next->u.val += FIELD_OFFSET(MSFT_FuncRecord, HelpContext) + pFuncDesc->cParams*(num_defaults?16:12); - - /* Increment the number of function elements */ - This->typeinfo->cElement += 1; - - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_AddImplType {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType( - ICreateTypeInfo2* iface, - UINT index, - HREFTYPE hRefType) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - TRACE("(%p,%d,%d)\n", iface, index, hRefType); - - if (This->typekind == TKIND_COCLASS) { - int offset; - MSFT_RefRecord *ref; - - if (index == 0) { - if (This->typeinfo->datatype1 != -1) return TYPE_E_ELEMENTNOTFOUND; - - offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0); - if (offset == -1) return E_OUTOFMEMORY; - - This->typeinfo->datatype1 = offset; - } else { - int lastoffset; - - lastoffset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index - 1); - if (lastoffset == -1) return TYPE_E_ELEMENTNOTFOUND; - - ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][lastoffset]; - if (ref->onext != -1) return TYPE_E_ELEMENTNOTFOUND; - - offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0); - if (offset == -1) return E_OUTOFMEMORY; - - ref->onext = offset; - } - - ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset]; - - ref->reftype = hRefType; - ref->flags = 0; - ref->oCustData = -1; - ref->onext = -1; - This->typeinfo->cImplTypes++; - } else if (This->typekind == TKIND_INTERFACE) { - if (This->typeinfo->cImplTypes && index==1) - return TYPE_E_BADMODULEKIND; - - if( index != 0) return TYPE_E_ELEMENTNOTFOUND; - - This->typeinfo->datatype1 = hRefType; - This->typeinfo->cImplTypes = 1; - } else if (This->typekind == TKIND_DISPATCH) { - if(index != 0) return TYPE_E_ELEMENTNOTFOUND; - - /* FIXME: Check if referenced typeinfo is IDispatch */ - This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE; - This->typeinfo->cImplTypes = 1; - } else { - FIXME("AddImplType unsupported on typekind %d\n", This->typekind); - return E_OUTOFMEMORY; - } - - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetImplTypeFlags {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags( - ICreateTypeInfo2* iface, - UINT index, - INT implTypeFlags) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - int offset; - MSFT_RefRecord *ref; - - TRACE("(%p,%d,0x%x)\n", iface, index, implTypeFlags); - - if (This->typekind != TKIND_COCLASS) { - return TYPE_E_BADMODULEKIND; - } - - offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index); - if (offset == -1) return TYPE_E_ELEMENTNOTFOUND; - - ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset]; - ref->flags = implTypeFlags; - - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetAlignment {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment( - ICreateTypeInfo2* iface, - WORD cbAlignment) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - TRACE("(%p,%d)\n", iface, cbAlignment); - - if (!cbAlignment) return E_INVALIDARG; - if (cbAlignment > 16) return E_INVALIDARG; - - This->typeinfo->typekind &= ~0xffc0; - This->typeinfo->typekind |= cbAlignment << 6; - - /* FIXME: There's probably some way to simplify this. */ - switch (This->typekind) { - case TKIND_ALIAS: - default: - break; - - case TKIND_ENUM: - case TKIND_INTERFACE: - case TKIND_DISPATCH: - case TKIND_COCLASS: - if (cbAlignment > 4) cbAlignment = 4; - break; - - case TKIND_RECORD: - case TKIND_MODULE: - case TKIND_UNION: - cbAlignment = 1; - break; - } - - This->typeinfo->typekind |= cbAlignment << 11; - - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetSchema {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetSchema( - ICreateTypeInfo2* iface, - LPOLESTR pStrSchema) -{ - FIXME("(%p,%s), stub!\n", iface, debugstr_w(pStrSchema)); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_AddVarDesc {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( - ICreateTypeInfo2* iface, - UINT index, - VARDESC* pVarDesc) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - HRESULT status = S_OK; - CyclicList *insert; - INT *typedata; - int var_datawidth; - int var_alignment; - int var_type_size; - int alignment; - - TRACE("(%p,%d,%p)\n", iface, index, pVarDesc); - TRACE("%d, %p, %d, {{%x, %d}, {%p, %x}}, 0x%x, %d\n", pVarDesc->memid, pVarDesc->lpstrSchema, pVarDesc->u.oInst, - pVarDesc->elemdescVar.tdesc.u.hreftype, pVarDesc->elemdescVar.tdesc.vt, - pVarDesc->elemdescVar.u.paramdesc.pparamdescex, pVarDesc->elemdescVar.u.paramdesc.wParamFlags, - pVarDesc->wVarFlags, pVarDesc->varkind); - - if (cti2_get_var_count(This->typeinfo) != index) - return TYPE_E_ELEMENTNOTFOUND; - - if (!This->typedata) { - This->typedata = alloc_cyclic_list_item(CyclicListSentinel); - if(!This->typedata) - return E_OUTOFMEMORY; - - This->typedata->next = This->typedata; - - if(This->dual) - This->dual->typedata = This->typedata; - } - - insert = alloc_cyclic_list_item(CyclicListVar); - if(!insert) - return E_OUTOFMEMORY; - - /* allocate whole structure, it's fixed size always */ - insert->u.data = heap_alloc(sizeof(MSFT_VarRecord)); - if(!insert->u.data) { - heap_free(insert); - return E_OUTOFMEMORY; - } - - insert->next = This->typedata->next; - This->typedata->next = insert; - This->typedata = insert; - - if(This->dual) - This->dual->typedata = This->typedata; - - This->typedata->next->u.val += FIELD_OFFSET(MSFT_VarRecord, HelpContext); - typedata = This->typedata->u.data; - - /* fill out the basic type information */ - - /* no optional fields initially */ - typedata[0] = FIELD_OFFSET(MSFT_VarRecord, HelpContext) | (index << 16); - typedata[2] = pVarDesc->wVarFlags; - typedata[3] = (sizeof(VARDESC) << 16) | pVarDesc->varkind; - - /* update the index data */ - insert->indice = 0x40000000 + index; - insert->name = -1; - - /* figure out type widths and whatnot */ - ctl2_encode_typedesc(This->typelib, &pVarDesc->elemdescVar.tdesc, - &typedata[1], &var_datawidth, &var_alignment, - &var_type_size); - - if (pVarDesc->varkind != VAR_CONST) - { - /* pad out starting position to data width */ - This->datawidth += var_alignment - 1; - This->datawidth &= ~(var_alignment - 1); - typedata[4] = This->datawidth; - - /* add the new variable to the total data width */ - This->datawidth += var_datawidth; - if(This->dual) - This->dual->datawidth = This->datawidth; - - /* add type description size to total required allocation */ - typedata[3] += var_type_size << 16; - - /* fix type alignment */ - alignment = (This->typeinfo->typekind >> 11) & 0x1f; - if (alignment < var_alignment) { - alignment = var_alignment; - This->typeinfo->typekind &= ~0xf800; - This->typeinfo->typekind |= alignment << 11; - } - - /* ??? */ - if (!This->typeinfo->res2) This->typeinfo->res2 = 0x1a; - if ((index == 0) || (index == 1) || (index == 2) || (index == 4) || (index == 9)) { - This->typeinfo->res2 <<= 1; - } - - /* ??? */ - if (This->typeinfo->res3 == -1) This->typeinfo->res3 = 0; - This->typeinfo->res3 += 0x2c; - - /* pad data width to alignment */ - This->typeinfo->size = (This->datawidth + (alignment - 1)) & ~(alignment - 1); - } else { - VARIANT *value = pVarDesc->DUMMYUNIONNAME.lpvarValue; - status = ctl2_encode_variant(This->typelib, typedata+4, value, V_VT(value)); - /* ??? native sets size 0x34 */ - typedata[3] += 0x10 << 16; - } - - /* increment the number of variable elements */ - This->typeinfo->cElement += 0x10000; - - return status; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetFuncAndParamNames {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames( - ICreateTypeInfo2* iface, - UINT index, - LPOLESTR* names, - UINT cNames) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - CyclicList *iter, *iter2; - int offset, len, i; - unsigned char *namedata; - - TRACE("(%p %d %p %d)\n", This, index, names, cNames); - - if(!names) - return E_INVALIDARG; - - if(index >= cti2_get_func_count(This->typeinfo) || cNames == 0) - return TYPE_E_ELEMENTNOTFOUND; - - for(iter=This->typedata->next->next, i=0; /* empty */; iter=iter->next) - if (iter->type == CyclicListFunc) - if (i++ >= index) - break; - - /* cNames == cParams for put or putref accessor, cParams+1 otherwise */ - if(cNames != iter->u.data[5] + (ctl2_get_invokekind(iter) & (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF) ? 0 : 1)) - return TYPE_E_ELEMENTNOTFOUND; - - TRACE("function name %s\n", debugstr_w(names[0])); - len = ctl2_encode_name(This->typelib, names[0], (char**)&namedata); - for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) { - - int cmp = memcmp(namedata, This->typelib->typelib_segment_data[MSFT_SEG_NAME]+iter2->name+8, len); - if (iter2->name != -1 && cmp == 0) { - if (iter2->type == CyclicListFunc) { - INVOKEKIND inv1 = ctl2_get_invokekind(iter); - INVOKEKIND inv2 = ctl2_get_invokekind(iter2); - - /* it's allowed to have PUT, PUTREF and GET methods with the same name */ - if ((inv1 != inv2) && - (inv1 & (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF|INVOKE_PROPERTYGET)) && - (inv2 & (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF|INVOKE_PROPERTYGET))) - continue; - } - - return TYPE_E_AMBIGUOUSNAME; - } - } - - offset = ctl2_alloc_name(This->typelib, names[0]); - if(offset == -1) - return E_OUTOFMEMORY; - - iter->name = offset; - - namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset; - if (*((INT*)namedata) == -1) - *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16]; - - len = ctl2_get_record_size(iter)/4 - iter->u.data[5]*3; - - for (i = 1; i < cNames; i++) { - offset = ctl2_alloc_name(This->typelib, names[i]); - iter->u.data[len + ((i-1)*3) + 1] = offset; - } - - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetVarName {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName( - ICreateTypeInfo2* iface, - UINT index, - LPOLESTR szName) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - CyclicList *iter; - int offset, i; - unsigned char *namedata; - - TRACE("(%p,%d,%s)\n", This, index, debugstr_w(szName)); - - if (cti2_get_var_count(This->typeinfo) <= index) - return TYPE_E_ELEMENTNOTFOUND; - - offset = ctl2_alloc_name(This->typelib, szName); - if (offset == -1) return E_OUTOFMEMORY; - - namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset; - if (*((INT *)namedata) == -1) { - *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16]; - namedata[9] |= 0x10; - } - if (This->typekind == TKIND_ENUM) { - namedata[9] |= 0x20; - } - - for(iter = This->typedata->next->next, i = 0; /* empty */; iter = iter->next) - if (iter->type == CyclicListVar) - if (i++ >= index) - break; - - iter->name = offset; - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetTypeDescAlias {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias( - ICreateTypeInfo2* iface, - TYPEDESC* pTDescAlias) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - int encoded_typedesc; - int width; - - if (This->typekind != TKIND_ALIAS) { - return TYPE_E_WRONGTYPEKIND; - } - - FIXME("(%p,%p), hack!\n", iface, pTDescAlias); - - if (ctl2_encode_typedesc(This->typelib, pTDescAlias, &encoded_typedesc, &width, NULL, NULL) == -1) { - return E_OUTOFMEMORY; - } - - This->typeinfo->size = width; - This->typeinfo->datatype1 = encoded_typedesc; - - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_DefineFuncAsDllEntry {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry( - ICreateTypeInfo2* iface, - UINT index, - LPOLESTR szDllName, - LPOLESTR szProcName) -{ - FIXME("(%p,%d,%s,%s), stub!\n", iface, index, debugstr_w(szDllName), debugstr_w(szProcName)); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetFuncDocString {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncDocString( - ICreateTypeInfo2* iface, - UINT index, - LPOLESTR szDocString) -{ - FIXME("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szDocString)); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetVarDocString {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetVarDocString( - ICreateTypeInfo2* iface, - UINT index, - LPOLESTR docstring) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - CyclicList *iter; - - TRACE("(%p,%d,%s)\n", This, index, debugstr_w(docstring)); - - if (!docstring) return E_INVALIDARG; - - if (cti2_get_var_count(This->typeinfo) <= index) - return TYPE_E_ELEMENTNOTFOUND; - - for (iter = This->typedata->next->next; iter != This->typedata->next; iter = iter->next) - if (iter->type == CyclicListVar) - { - if (index-- == 0) - { - int offset = ctl2_alloc_string(This->typelib, docstring); - - if (offset == -1) return E_OUTOFMEMORY; - ctl2_update_var_size(This, iter, FIELD_OFFSET(MSFT_VarRecord, res9)); - iter->u.data[6] = offset; - return S_OK; - } - } - - return TYPE_E_ELEMENTNOTFOUND; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetFuncHelpContext {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext( - ICreateTypeInfo2* iface, - UINT index, - DWORD dwHelpContext) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - CyclicList *func; - - TRACE("(%p,%d,%d)\n", iface, index, dwHelpContext); - - if(cti2_get_func_count(This->typeinfo) < index) - return TYPE_E_ELEMENTNOTFOUND; - - if(cti2_get_func_count(This->typeinfo) == index && This->typedata->type == CyclicListFunc) - func = This->typedata; - else - for(func=This->typedata->next->next; func!=This->typedata; func=func->next) - if (func->type == CyclicListFunc) - if(index-- == 0) - break; - - This->typedata->next->u.val += funcrecord_reallochdr(&func->u.data, 7*sizeof(int)); - if(!func->u.data) - return E_OUTOFMEMORY; - - func->u.data[6] = dwHelpContext; - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetVarHelpContext {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpContext( - ICreateTypeInfo2* iface, - UINT index, - DWORD context) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - CyclicList *iter; - - TRACE("(%p,%d,%d)\n", This, index, context); - - if (cti2_get_var_count(This->typeinfo) <= index) - return TYPE_E_ELEMENTNOTFOUND; - - for (iter = This->typedata->next->next; iter != This->typedata->next; iter = iter->next) - if (iter->type == CyclicListVar) - { - if (index-- == 0) - { - ctl2_update_var_size(This, iter, FIELD_OFFSET(MSFT_VarRecord, HelpString)); - iter->u.data[5] = context; - return S_OK; - } - } - - return TYPE_E_ELEMENTNOTFOUND; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetMops {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetMops( - ICreateTypeInfo2* iface, - UINT index, - BSTR bstrMops) -{ - FIXME("(%p,%d,%p), stub!\n", iface, index, bstrMops); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetTypeIdldesc {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc( - ICreateTypeInfo2* iface, - IDLDESC* pIdlDesc) -{ - FIXME("(%p,%p), stub!\n", iface, pIdlDesc); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_LayOut {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( - ICreateTypeInfo2* iface) -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - CyclicList *iter, *iter2, *last = NULL, **typedata; - HREFTYPE hreftype; - HRESULT hres; - unsigned user_vft = 0; - int i; - - TRACE("(%p)\n", This); - - /* FIXME: LayOut should be run on all ImplTypes */ - if(This->typekind == TKIND_COCLASS || This->typekind == TKIND_ALIAS) - return S_OK; - - /* Validate inheritance */ - This->typeinfo->datatype2 = 0; - hreftype = This->typeinfo->datatype1; - - /* Process internally defined interfaces */ - for(i=0; itypelib->typelib_header.nrtypeinfos; i++) { - MSFT_TypeInfoBase *header; - - if(hreftype&1) - break; - - header = (MSFT_TypeInfoBase*)&(This->typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][hreftype]); - This->typeinfo->datatype2 += (header->cElement<<16) + 1; - hreftype = header->datatype1; - } - if(i == This->typelib->typelib_header.nrtypeinfos) - return TYPE_E_CIRCULARTYPE; - - /* Process externally defined interfaces */ - if(hreftype != -1) { - ITypeInfo *cur, *next; - TYPEATTR *typeattr; - - hres = ICreateTypeInfo2_QueryInterface(iface, &IID_ITypeInfo, (void**)&next); - if(FAILED(hres)) - return hres; - - hres = ITypeInfo_GetRefTypeInfo(next, hreftype, &cur); - ITypeInfo_Release(next); - if(FAILED(hres)) - return hres; - - - while(1) { - hres = ITypeInfo_GetTypeAttr(cur, &typeattr); - if(FAILED(hres)) { - ITypeInfo_Release(cur); - return hres; - } - - if(IsEqualGUID(&typeattr->guid, &IID_IDispatch)) - This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE; - - This->typeinfo->datatype2 += (typeattr->cFuncs<<16) + 1; - ITypeInfo_ReleaseTypeAttr(cur, typeattr); - - hres = ITypeInfo_GetRefTypeOfImplType(cur, 0, &hreftype); - if(hres == TYPE_E_ELEMENTNOTFOUND) - break; - if(FAILED(hres)) { - ITypeInfo_Release(cur); - return hres; - } - - hres = ITypeInfo_GetRefTypeInfo(cur, hreftype, &next); - if(FAILED(hres)) { - ITypeInfo_Release(cur); - return hres; - } - - ITypeInfo_Release(cur); - cur = next; - } - ITypeInfo_Release(cur); - } - - /* Get cbSizeVft of inherited interface */ - /* Makes LayOut running recursively */ - if(This->typeinfo->datatype1 != -1) { - ITypeInfo *cur, *inherited; - TYPEATTR *typeattr; - - hres = ICreateTypeInfo2_QueryInterface(iface, &IID_ITypeInfo, (void**)&cur); - if(FAILED(hres)) - return hres; - - hres = ITypeInfo_GetRefTypeInfo(cur, This->typeinfo->datatype1, &inherited); - ITypeInfo_Release(cur); - if(FAILED(hres)) - return hres; - - hres = ITypeInfo_GetTypeAttr(inherited, &typeattr); - if(FAILED(hres)) { - ITypeInfo_Release(inherited); - return hres; - } - - This->typeinfo->cbSizeVft = typeattr->cbSizeVft * 4 / sizeof(void *); - - ITypeInfo_ReleaseTypeAttr(inherited, typeattr); - ITypeInfo_Release(inherited); - } else - This->typeinfo->cbSizeVft = 0; - - if(!This->typedata) - return S_OK; - - typedata = heap_alloc(sizeof(CyclicList*)*cti2_get_func_count(This->typeinfo)); - if(!typedata) - return E_OUTOFMEMORY; - - /* Assign IDs and VTBL entries */ - for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) - if (iter->type == CyclicListFunc) - last = iter; - - if(last && last->u.data[3]&1) - user_vft = last->u.data[3]&0xffff; - - i = 0; - for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) { - /* Assign MEMBERID if MEMBERID_NIL was specified */ - if(iter->indice == MEMBERID_NIL) { - iter->indice = 0x60000000 + i + (This->typeinfo->datatype2<<16); - - for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) { - if(iter == iter2) continue; - if(iter2->indice == iter->indice) { - iter->indice = 0x60000000 + This->typeinfo->cElement + (This->typeinfo->datatype2<<16); - - for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) { - if(iter == iter2) continue; - if(iter2->indice == iter->indice) { - ++iter->indice; - iter2 = This->typedata->next; - } - } - - break; - } - } - } - - if (iter->type != CyclicListFunc) - continue; - - typedata[i] = iter; - - iter->u.data[0] = ctl2_get_record_size(iter) | (i<<16); - - if((iter->u.data[3]&1) != (user_vft&1)) { - heap_free(typedata); - return TYPE_E_INVALIDID; - } - - if(user_vft&1) { - if(user_vft < (iter->u.data[3]&0xffff)) - user_vft = (iter->u.data[3]&0xffff); - - if((iter->u.data[3]&0xffff) < This->typeinfo->cbSizeVft) { - heap_free(typedata); - return TYPE_E_INVALIDID; - } - } else if(This->typekind != TKIND_MODULE) { - iter->u.data[3] = (iter->u.data[3]&0xffff0000) | This->typeinfo->cbSizeVft; - This->typeinfo->cbSizeVft += 4; - } - - /* Construct a list of elements with the same memberid */ - iter->u.data[4] = (iter->u.data[4]&0xffff) | (i<<16); - for(iter2=This->typedata->next->next; iter2!=iter; iter2=iter2->next) { - if(iter->indice == iter2->indice) { - int v1, v2; - - v1 = iter->u.data[4] >> 16; - v2 = iter2->u.data[4] >> 16; - - iter->u.data[4] = (iter->u.data[4]&0xffff) | (v2<<16); - iter2->u.data[4] = (iter2->u.data[4]&0xffff) | (v1<<16); - break; - } - } - - i++; - } - - if(user_vft) - This->typeinfo->cbSizeVft = user_vft+3; - - for(i=0; i< cti2_get_func_count(This->typeinfo); i++) { - if(typedata[i]->u.data[4]>>16 > i) { - INVOKEKIND inv = ctl2_get_invokekind(typedata[i]); - - i = typedata[i]->u.data[4] >> 16; - - while(i > typedata[i]->u.data[4]>>16) { - INVOKEKIND invkind = ctl2_get_invokekind(typedata[i]); - - if(inv & invkind) { - heap_free(typedata); - return TYPE_E_DUPLICATEID; - } - - i = typedata[i]->u.data[4] >> 16; - inv |= invkind; - } - - if(inv & INVOKE_FUNC) { - heap_free(typedata); - return TYPE_E_INCONSISTENTPROPFUNCS; - } - } - } - - heap_free(typedata); - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_DeleteFuncDesc {OLEAUT32} - * - * Delete a function description from a type. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDesc( - ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete a function. */ - UINT index) /* [I] The index of the function to delete. */ -{ - FIXME("(%p,%d), stub!\n", iface, index); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_DeleteFuncDescByMemId {OLEAUT32} - * - * Delete a function description from a type. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDescByMemId( - ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete a function. */ - MEMBERID memid, /* [I] The member id of the function to delete. */ - INVOKEKIND invKind) /* [I] The invocation type of the function to delete. (?) */ -{ - FIXME("(%p,%d,%d), stub!\n", iface, memid, invKind); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_DeleteVarDesc {OLEAUT32} - * - * Delete a variable description from a type. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY, E_INVALIDARG, TYPE_E_IOERROR, - * TYPE_E_INVDATAREAD, TYPE_E_UNSUPFORMAT or TYPE_E_INVALIDSTATE. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDesc( - ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete the variable description. */ - UINT index) /* [I] The index of the variable description to delete. */ -{ - FIXME("(%p,%d), stub!\n", iface, index); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_DeleteVarDescByMemId {OLEAUT32} - * - * Delete a variable description from a type. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY, E_INVALIDARG, TYPE_E_IOERROR, - * TYPE_E_INVDATAREAD, TYPE_E_UNSUPFORMAT or TYPE_E_INVALIDSTATE. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDescByMemId( - ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete the variable description. */ - MEMBERID memid) /* [I] The member id of the variable description to delete. */ -{ - FIXME("(%p,%d), stub!\n", iface, memid); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_DeleteImplType {OLEAUT32} - * - * Delete an interface implementation from a type. (?) - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnDeleteImplType( - ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete. */ - UINT index) /* [I] The index of the interface to delete. */ -{ - FIXME("(%p,%d), stub!\n", iface, index); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetCustData {OLEAUT32} - * - * Set the custom data for a type. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetCustData( - ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */ - REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ - VARIANT* pVarVal) /* [I] The custom data. */ -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - TRACE("(%p,%s,%p)!\n", iface, debugstr_guid(guid), pVarVal); - - if (!pVarVal) - return E_INVALIDARG; - - return ctl2_set_custdata(This->typelib, guid, pVarVal, &This->typeinfo->oCustData); -} - -/****************************************************************************** - * ICreateTypeInfo2_SetFuncCustData {OLEAUT32} - * - * Set the custom data for a function. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncCustData( - ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */ - UINT index, /* [I] The index of the function for which to set the custom data. */ - REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ - VARIANT* pVarVal) /* [I] The custom data. */ -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - CyclicList *iter; - - TRACE("(%p,%d,%s,%p)\n", iface, index, debugstr_guid(guid), pVarVal); - - if(index >= cti2_get_func_count(This->typeinfo)) - return TYPE_E_ELEMENTNOTFOUND; - - for(iter=This->typedata->next->next; /* empty */; iter=iter->next) - if (iter->type == CyclicListFunc) - if (index-- == 0) - break; - - This->typedata->next->u.val += funcrecord_reallochdr(&iter->u.data, 13*sizeof(int)); - if(!iter->u.data) - return E_OUTOFMEMORY; - - iter->u.data[4] |= 0x80; - return ctl2_set_custdata(This->typelib, guid, pVarVal, &iter->u.data[12]); -} - -/****************************************************************************** - * ICreateTypeInfo2_SetParamCustData {OLEAUT32} - * - * Set the custom data for a function parameter. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetParamCustData( - ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */ - UINT indexFunc, /* [I] The index of the function on which the parameter resides. */ - UINT indexParam, /* [I] The index of the parameter on which to set the custom data. */ - REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ - VARIANT* pVarVal) /* [I] The custom data. */ -{ - FIXME("(%p,%d,%d,%s,%p), stub!\n", iface, indexFunc, indexParam, debugstr_guid(guid), pVarVal); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetVarCustData {OLEAUT32} - * - * Set the custom data for a variable. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetVarCustData( - ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */ - UINT index, /* [I] The index of the variable on which to set the custom data. */ - REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ - VARIANT* pVarVal) /* [I] The custom data. */ -{ - FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetImplTypeCustData {OLEAUT32} - * - * Set the custom data for an implemented interface. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeCustData( - ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the custom data. */ - UINT index, /* [I] The index of the implemented interface on which to set the custom data. */ - REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ - VARIANT* pVarVal) /* [I] The custom data. */ -{ - FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetHelpStringContext {OLEAUT32} - * - * Set the help string context for the typeinfo. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpStringContext( - ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the help string context. */ - ULONG helpcontext) /* [I] The help string context. */ -{ - ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); - - TRACE("(%p, %d)\n", iface, helpcontext); - - This->typelib->typelib_header.helpcontext = helpcontext; - - return S_OK; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetFuncHelpStringContext {OLEAUT32} - * - * Set the help string context for a function. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpStringContext( - ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the help string context. */ - UINT index, /* [I] The index for the function on which to set the help string context. */ - ULONG dwHelpStringContext) /* [I] The help string context. */ -{ - FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpStringContext); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetVarHelpStringContext {OLEAUT32} - * - * Set the help string context for a variable. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpStringContext( - ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the help string context. */ - UINT index, /* [I] The index of the variable on which to set the help string context. */ - ULONG dwHelpStringContext) /* [I] The help string context */ -{ - FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpStringContext); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_Invalidate {OLEAUT32} - * - * Undocumented function. (!) - */ -static HRESULT WINAPI ICreateTypeInfo2_fnInvalidate( - ICreateTypeInfo2* iface) -{ - FIXME("(%p), stub!\n", iface); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeInfo2_SetName {OLEAUT32} - * - * Set the name for a typeinfo. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of STG_E_INSUFFICIENTMEMORY, E_OUTOFMEMORY, E_INVALIDARG or TYPE_E_INVALIDSTATE. - */ -static HRESULT WINAPI ICreateTypeInfo2_fnSetName( - ICreateTypeInfo2* iface, - LPOLESTR szName) -{ - FIXME("(%p,%s), stub!\n", iface, debugstr_w(szName)); - return E_OUTOFMEMORY; -} - -/*================== ITypeInfo2 Implementation ===================================*/ - -/****************************************************************************** - * ITypeInfo2_QueryInterface {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnQueryInterface(ITypeInfo2 * iface, REFIID riid, LPVOID * ppv) -{ - ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - - return ICreateTypeInfo2_QueryInterface(&This->ICreateTypeInfo2_iface, riid, ppv); -} - -/****************************************************************************** - * ITypeInfo2_AddRef {OLEAUT32} - */ -static ULONG WINAPI ITypeInfo2_fnAddRef(ITypeInfo2 * iface) -{ - ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - - return ICreateTypeInfo2_AddRef(&This->ICreateTypeInfo2_iface); -} - -/****************************************************************************** - * ITypeInfo2_Release {OLEAUT32} - */ -static ULONG WINAPI ITypeInfo2_fnRelease(ITypeInfo2 * iface) -{ - ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - - return ICreateTypeInfo2_Release(&This->ICreateTypeInfo2_iface); -} - -/****************************************************************************** - * ITypeInfo2_GetTypeAttr {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr( - ITypeInfo2* iface, - TYPEATTR** ppTypeAttr) -{ - ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - HRESULT hres; - - TRACE("(%p,%p)\n", iface, ppTypeAttr); - - if(!ppTypeAttr) - return E_INVALIDARG; - - hres = ICreateTypeInfo2_LayOut(&This->ICreateTypeInfo2_iface); - if(FAILED(hres)) - return hres; - - *ppTypeAttr = heap_alloc_zero(sizeof(TYPEATTR)); - if(!*ppTypeAttr) - return E_OUTOFMEMORY; - - if(This->typeinfo->posguid != -1) { - MSFT_GuidEntry *guid; - - guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][This->typeinfo->posguid]; - (*ppTypeAttr)->guid = guid->guid; - } - - (*ppTypeAttr)->lcid = This->typelib->typelib_header.lcid; - (*ppTypeAttr)->cbSizeInstance = This->typeinfo->size; - (*ppTypeAttr)->typekind = This->typekind; - (*ppTypeAttr)->cFuncs = cti2_get_func_count(This->typeinfo); - if(This->typeinfo->flags&TYPEFLAG_FDUAL && This->typekind==TKIND_DISPATCH) - (*ppTypeAttr)->cFuncs += sizeof(IDispatchVtbl)/sizeof(void*); - (*ppTypeAttr)->cVars = cti2_get_var_count(This->typeinfo); - (*ppTypeAttr)->cImplTypes = This->typeinfo->cImplTypes; - (*ppTypeAttr)->cbSizeVft = This->typekind == TKIND_DISPATCH ? sizeof(IDispatchVtbl) : This->typeinfo->cbSizeVft; - (*ppTypeAttr)->cbAlignment = (This->typeinfo->typekind>>11) & 0x1f; - (*ppTypeAttr)->wTypeFlags = This->typeinfo->flags; - (*ppTypeAttr)->wMajorVerNum = LOWORD(This->typeinfo->version); - (*ppTypeAttr)->wMinorVerNum = HIWORD(This->typeinfo->version); - - if((*ppTypeAttr)->typekind == TKIND_ALIAS) - FIXME("TKIND_ALIAS handling not implemented\n"); - - return S_OK; -} - -/****************************************************************************** - * ITypeInfo2_GetTypeComp {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnGetTypeComp( - ITypeInfo2* iface, - ITypeComp** ppTComp) -{ - FIXME("(%p,%p), stub!\n", iface, ppTComp); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetFuncDesc {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnGetFuncDesc( - ITypeInfo2* iface, - UINT index, - FUNCDESC** ppFuncDesc) -{ - ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - int i, *typedata, num_defaults = 0, hdr_len, tail, has_defaults; - CyclicList *desc; - HRESULT hres; - - TRACE("(%p,%d,%p), semi-stub\n", iface, index, ppFuncDesc); - - if (!ppFuncDesc) - return E_INVALIDARG; - - if (index >= cti2_get_func_count(This->typeinfo)) - return TYPE_E_ELEMENTNOTFOUND; - - hres = ICreateTypeInfo2_LayOut(&This->ICreateTypeInfo2_iface); - if (FAILED(hres)) - return hres; - - desc = This->typedata->next; - for (i = index; i >= 0; ) { - desc = desc->next; - if (desc->type == CyclicListFunc) - --i; - } - - typedata = desc->u.data; - - *ppFuncDesc = heap_alloc_zero(sizeof(FUNCDESC)); - if (!*ppFuncDesc) - return E_OUTOFMEMORY; - - (*ppFuncDesc)->memid = desc->indice; - (*ppFuncDesc)->lprgscode = NULL; /* FIXME: Unimplemented */ - (*ppFuncDesc)->funckind = typedata[4] & 0x7; - (*ppFuncDesc)->invkind = (typedata[4] >> 3) & 0xF; - (*ppFuncDesc)->callconv = (typedata[4] >> 8) & 0xF; - (*ppFuncDesc)->cParams = typedata[5]; - (*ppFuncDesc)->cParamsOpt = 0; /* FIXME: Unimplemented*/ - (*ppFuncDesc)->oVft = typedata[3] & 0xFFFF; - if ((*ppFuncDesc)->oVft) - --(*ppFuncDesc)->oVft; - (*ppFuncDesc)->cScodes = 0; /* FIXME: Unimplemented*/ - hres = ctl2_decode_typedesc(This->typelib, typedata[1], - &(*ppFuncDesc)->elemdescFunc.tdesc); - if (FAILED(hres)) { - heap_free(*ppFuncDesc); - return hres; - } - (*ppFuncDesc)->wFuncFlags = typedata[2]; - - has_defaults = typedata[4] & 0x1000; - tail = typedata[5] * (has_defaults ? 16 : 12); - hdr_len = (ctl2_get_record_size(desc) - tail) / sizeof(int); - - if ((*ppFuncDesc)->cParams > 0) { - (*ppFuncDesc)->lprgelemdescParam = heap_alloc_zero((*ppFuncDesc)->cParams * sizeof(ELEMDESC)); - if (!(*ppFuncDesc)->lprgelemdescParam) { - heap_free(*ppFuncDesc); - return E_OUTOFMEMORY; - } - if (has_defaults) { - num_defaults = (*ppFuncDesc)->cParams; - - for (i = 0; i < num_defaults; ++i) { - if (typedata[hdr_len + i] != 0xFFFFFFFF) { - (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.wParamFlags |= PARAMFLAG_FHASDEFAULT; - - (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex = heap_alloc(sizeof(PARAMDESCEX)); - if (!(*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex) { - ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc); - return E_OUTOFMEMORY; - } - - (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex->cBytes = sizeof(PARAMDESCEX); - VariantInit(&(*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue); - hres = ctl2_decode_variant(This->typelib, typedata[hdr_len + i], - &(*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue); - if (FAILED(hres)) { - ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc); - return hres; - } - } - } - } - - for (i = 0; i < (*ppFuncDesc)->cParams; ++i) { - hres = ctl2_decode_typedesc(This->typelib, typedata[hdr_len + num_defaults + (i * 3)], - &((*ppFuncDesc)->lprgelemdescParam + i)->tdesc); - if (FAILED(hres)) { - ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc); - return hres; - } - (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.wParamFlags = typedata[hdr_len + num_defaults + (i * 3) + 2]; - } - } - - return S_OK; -} - -/****************************************************************************** - * ITypeInfo2_GetVarDesc {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnGetVarDesc( - ITypeInfo2* iface, - UINT index, - VARDESC** ppVarDesc) -{ - FIXME("(%p,%d,%p), stub!\n", iface, index, ppVarDesc); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetNames {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnGetNames( - ITypeInfo2* iface, - MEMBERID memid, - BSTR* rgBstrNames, - UINT cMaxNames, - UINT* pcNames) -{ - FIXME("(%p,%d,%p,%d,%p), stub!\n", iface, memid, rgBstrNames, cMaxNames, pcNames); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetRefTypeOfImplType {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnGetRefTypeOfImplType( - ITypeInfo2* iface, - UINT index, - HREFTYPE* pRefType) -{ - ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - MSFT_RefRecord *ref; - int offset; - - TRACE("(%p,%d,%p)\n", iface, index, pRefType); - - if(!pRefType) - return E_INVALIDARG; - - if(This->typeinfo->flags&TYPEFLAG_FDUAL) { - if(index == -1) { - *pRefType = -2; - return S_OK; - } - - if(This->typekind == TKIND_DISPATCH) - return ITypeInfo2_GetRefTypeOfImplType(&This->dual->ITypeInfo2_iface, - index, pRefType); - } - - if(index>=This->typeinfo->cImplTypes) - return TYPE_E_ELEMENTNOTFOUND; - - if(This->typekind == TKIND_INTERFACE) { - *pRefType = This->typeinfo->datatype1 + 2; - return S_OK; - } - - offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index); - if(offset == -1) - return TYPE_E_ELEMENTNOTFOUND; - - ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset]; - *pRefType = ref->reftype; - return S_OK; -} - -/****************************************************************************** - * ITypeInfo2_GetImplTypeFlags {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnGetImplTypeFlags( - ITypeInfo2* iface, - UINT index, - INT* pImplTypeFlags) -{ - ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - int offset; - MSFT_RefRecord *ref; - - TRACE("(%p,%d,%p)\n", iface, index, pImplTypeFlags); - - if(!pImplTypeFlags) - return E_INVALIDARG; - - if(index >= This->typeinfo->cImplTypes) - return TYPE_E_ELEMENTNOTFOUND; - - if(This->typekind != TKIND_COCLASS) { - *pImplTypeFlags = 0; - return S_OK; - } - - offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index); - if(offset == -1) - return TYPE_E_ELEMENTNOTFOUND; - - ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset]; - *pImplTypeFlags = ref->flags; - return S_OK; -} - -/****************************************************************************** - * ITypeInfo2_GetIDsOfNames {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnGetIDsOfNames( - ITypeInfo2* iface, - LPOLESTR* rgszNames, - UINT cNames, - MEMBERID* pMemId) -{ - FIXME("(%p,%p,%d,%p), stub!\n", iface, rgszNames, cNames, pMemId); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_Invoke {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnInvoke( - ITypeInfo2* iface, - PVOID pvInstance, - MEMBERID memid, - WORD wFlags, - DISPPARAMS* pDispParams, - VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, - UINT* puArgErr) -{ - FIXME("(%p,%p,%d,%x,%p,%p,%p,%p), stub!\n", iface, pvInstance, memid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetDocumentation {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnGetDocumentation( - ITypeInfo2* iface, - MEMBERID memid, - BSTR* pBstrName, - BSTR* pBstrDocString, - DWORD* pdwHelpContext, - BSTR* pBstrHelpFile) -{ - ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - HRESULT status = TYPE_E_ELEMENTNOTFOUND; - INT nameoffset, docstringoffset, helpcontext; - - TRACE("(%p,%d,%p,%p,%p,%p)\n", iface, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); - - if (memid == -1) - { - nameoffset = This->typeinfo->NameOffset; - docstringoffset = This->typeinfo->docstringoffs; - helpcontext = This->typeinfo->helpcontext; - status = S_OK; - } else { - CyclicList *iter; - if (This->typedata) { - for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) { - if (iter->indice == memid) { - if (iter->type == CyclicListFunc) { - const int *typedata = iter->u.data; - int size = ctl2_get_record_size(iter) - typedata[5]*(typedata[4]&0x1000?16:12); - - nameoffset = iter->name; - /* FIXME implement this once SetFuncDocString is implemented */ - docstringoffset = -1; - helpcontext = (size < 7*sizeof(int)) ? 0 : typedata[6]; - - status = S_OK; - } else { - FIXME("Not implemented for variable members\n"); - } - - break; - } - } - } - } - - if (!status) { - WCHAR *string; - if (pBstrName) { - if (nameoffset == -1) - *pBstrName = NULL; - else { - MSFT_NameIntro *name = (MSFT_NameIntro*)&This->typelib-> - typelib_segment_data[MSFT_SEG_NAME][nameoffset]; - ctl2_decode_name((char*)&name->namelen, &string); - *pBstrName = SysAllocString(string); - if(!*pBstrName) - return E_OUTOFMEMORY; - } - } - - if (pBstrDocString) { - if (docstringoffset == -1) - *pBstrDocString = NULL; - else { - MSFT_NameIntro *name = (MSFT_NameIntro*)&This->typelib-> - typelib_segment_data[MSFT_SEG_NAME][docstringoffset]; - ctl2_decode_name((char*)&name->namelen, &string); - *pBstrDocString = SysAllocString(string); - if(!*pBstrDocString) { - if (pBstrName) SysFreeString(*pBstrName); - return E_OUTOFMEMORY; - } - } - } - - if (pdwHelpContext) { - *pdwHelpContext = helpcontext; - } - - if (pBstrHelpFile) { - status = ITypeLib_GetDocumentation((ITypeLib*)&This->typelib->ITypeLib2_iface, - -1, NULL, NULL, NULL, pBstrHelpFile); - if (status) { - if (pBstrName) SysFreeString(*pBstrName); - if (pBstrDocString) SysFreeString(*pBstrDocString); - } - } - } - - return status; -} - -/****************************************************************************** - * ITypeInfo2_GetDllEntry {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnGetDllEntry( - ITypeInfo2* iface, - MEMBERID memid, - INVOKEKIND invKind, - BSTR* pBstrDllName, - BSTR* pBstrName, - WORD* pwOrdinal) -{ - FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", iface, memid, invKind, pBstrDllName, pBstrName, pwOrdinal); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetRefTypeInfo {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo( - ITypeInfo2* iface, - HREFTYPE hRefType, - ITypeInfo** ppTInfo) -{ - ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - - TRACE("(%p,%d,%p)\n", iface, hRefType, ppTInfo); - - if(!ppTInfo) - return E_INVALIDARG; - - if(hRefType==-2 && This->dual) { - *ppTInfo = (ITypeInfo *)&This->dual->ITypeInfo2_iface; - ITypeInfo_AddRef(*ppTInfo); - return S_OK; - } - - if(hRefType&1) { - ITypeLib *tl; - MSFT_ImpInfo *impinfo; - MSFT_ImpFile *impfile; - MSFT_GuidEntry *guid; - WCHAR *filename; - HRESULT hres; - - if((hRefType&(~0x3)) >= This->typelib->typelib_segdir[MSFT_SEG_IMPORTINFO].length) - return E_FAIL; - - impinfo = (MSFT_ImpInfo*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO][hRefType&(~0x3)]; - impfile = (MSFT_ImpFile*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][impinfo->oImpFile]; - guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo->oGuid]; - - ctl2_decode_string((unsigned char*)impfile->filename, &filename); - - hres = LoadTypeLib(filename, &tl); - if(FAILED(hres)) - return hres; - - hres = ITypeLib_GetTypeInfoOfGuid(tl, &guid->guid, ppTInfo); - - ITypeLib_Release(tl); - return hres; - } else { - ICreateTypeInfo2Impl *iter; - int i = 0; - - for(iter=This->typelib->typeinfos; iter; iter=iter->next_typeinfo) { - if(This->typelib->typelib_typeinfo_offsets[i] == (hRefType&(~0x3))) { - *ppTInfo = (ITypeInfo *)&iter->ITypeInfo2_iface; - - ITypeInfo_AddRef(*ppTInfo); - return S_OK; - } - i++; - } - } - - return E_FAIL; -} - -/****************************************************************************** - * ITypeInfo2_AddressOfMember {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnAddressOfMember( - ITypeInfo2* iface, - MEMBERID memid, - INVOKEKIND invKind, - PVOID* ppv) -{ - FIXME("(%p,%d,%d,%p), stub!\n", iface, memid, invKind, ppv); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_CreateInstance {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnCreateInstance( - ITypeInfo2* iface, - IUnknown* pUnkOuter, - REFIID riid, - PVOID* ppvObj) -{ - FIXME("(%p,%p,%s,%p), stub!\n", iface, pUnkOuter, debugstr_guid(riid), ppvObj); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetMops {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnGetMops( - ITypeInfo2* iface, - MEMBERID memid, - BSTR* pBstrMops) -{ - FIXME("(%p,%d,%p), stub!\n", iface, memid, pBstrMops); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetContainingTypeLib {OLEAUT32} - */ -static HRESULT WINAPI ITypeInfo2_fnGetContainingTypeLib( - ITypeInfo2* iface, - ITypeLib** ppTLib, - UINT* pIndex) -{ - ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - - TRACE("(%p,%p,%p)\n", iface, ppTLib, pIndex); - - *ppTLib = (ITypeLib *)&This->typelib->ITypeLib2_iface; - ICreateTypeLib_AddRef((ICreateTypeLib*)This->typelib); - *pIndex = This->typeinfo->typekind >> 16; - - return S_OK; -} - -static void release_typedesc(TYPEDESC *tdesc) -{ - while (tdesc) { - TYPEDESC *next; - if (tdesc->vt == VT_USERDEFINED) - next = NULL; - else - next = tdesc->u.lptdesc; - heap_free(tdesc); - tdesc = next; - } -} - -/****************************************************************************** - * ITypeInfo2_ReleaseTypeAttr {OLEAUT32} - */ -static void WINAPI ITypeInfo2_fnReleaseTypeAttr( - ITypeInfo2* iface, - TYPEATTR* pTypeAttr) -{ - TRACE("(%p,%p)\n", iface, pTypeAttr); - - if (pTypeAttr->tdescAlias.vt != VT_USERDEFINED) - release_typedesc(pTypeAttr->tdescAlias.u.lptdesc); - - heap_free(pTypeAttr); -} - -/****************************************************************************** - * ITypeInfo2_ReleaseFuncDesc {OLEAUT32} - */ -static void WINAPI ITypeInfo2_fnReleaseFuncDesc( - ITypeInfo2* iface, - FUNCDESC* pFuncDesc) -{ - int i; - - TRACE("(%p,%p)\n", iface, pFuncDesc); - - heap_free(pFuncDesc->lprgscode); - - if (pFuncDesc->lprgelemdescParam) { - for (i = 0; i < pFuncDesc->cParams; ++i) { - if (pFuncDesc->lprgelemdescParam[i].tdesc.vt != VT_USERDEFINED) - release_typedesc(pFuncDesc->lprgelemdescParam[i].tdesc.u.lptdesc); - - if (pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex) - { - VariantClear(&pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue); - heap_free(pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex); - } - } - heap_free(pFuncDesc->lprgelemdescParam); - } - - heap_free(pFuncDesc->elemdescFunc.u.paramdesc.pparamdescex); - - if (pFuncDesc->elemdescFunc.tdesc.vt != VT_USERDEFINED) - release_typedesc(pFuncDesc->elemdescFunc.tdesc.u.lptdesc); - - heap_free(pFuncDesc); -} - -/****************************************************************************** - * ITypeInfo2_ReleaseVarDesc {OLEAUT32} - */ -static void WINAPI ITypeInfo2_fnReleaseVarDesc( - ITypeInfo2* iface, - VARDESC* pVarDesc) -{ - FIXME("(%p,%p), stub!\n", iface, pVarDesc); -} - -/****************************************************************************** - * ITypeInfo2_GetTypeKind {OLEAUT32} - * - * Get the TYPEKIND value for a TypeInfo. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( - ITypeInfo2* iface, /* [I] The TypeInfo to obtain the typekind for. */ - TYPEKIND* pTypeKind) /* [O] The typekind for this TypeInfo. */ -{ - FIXME("(%p,%p), stub!\n", iface, pTypeKind); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetTypeFlags {OLEAUT32} - * - * Get the Type Flags for a TypeInfo. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( - ITypeInfo2* iface, /* [I] The TypeInfo to obtain the typeflags for. */ - ULONG* pTypeFlags) /* [O] The type flags for this TypeInfo. */ -{ - FIXME("(%p,%p), stub!\n", iface, pTypeFlags); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetFuncIndexOfMemId {OLEAUT32} - * - * Gets the index of a function given its member id. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( - ITypeInfo2* iface, /* [I] The TypeInfo in which to find the function. */ - MEMBERID memid, /* [I] The member id for the function. */ - INVOKEKIND invKind, /* [I] The invocation kind for the function. */ - UINT* pFuncIndex) /* [O] The index of the function. */ -{ - FIXME("(%p,%d,%d,%p), stub!\n", iface, memid, invKind, pFuncIndex); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetVarIndexOfMemId {OLEAUT32} - * - * Gets the index of a variable given its member id. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( - ITypeInfo2* iface, /* [I] The TypeInfo in which to find the variable. */ - MEMBERID memid, /* [I] The member id for the variable. */ - UINT* pVarIndex) /* [O] The index of the variable. */ -{ - FIXME("(%p,%d,%p), stub!\n", iface, memid, pVarIndex); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetCustData {OLEAUT32} - * - * Gets a custom data element from a TypeInfo. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetCustData( - ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ - REFGUID guid, /* [I] The GUID under which the custom data is stored. */ - VARIANT* pVarVal) /* [O] The custom data. */ -{ - ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - MSFT_CDGuid *cdentry; - int offset; - - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), pVarVal); - - if (!guid || !pVarVal) - return E_INVALIDARG; - - VariantClear(pVarVal); - - offset = ctl2_find_custdata(This->typelib, guid, This->typeinfo->oCustData); - if (offset == -1) - return S_OK; - - cdentry = (MSFT_CDGuid *)&This->typelib->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][offset]; - return ctl2_decode_variant(This->typelib, cdentry->DataOffset, pVarVal); -} - -/****************************************************************************** - * ITypeInfo2_GetFuncCustData {OLEAUT32} - * - * Gets a custom data element from a function. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( - ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ - UINT index, /* [I] The index of the function for which to retrieve the custom data. */ - REFGUID guid, /* [I] The GUID under which the custom data is stored. */ - VARIANT* pVarVal) /* [O] The custom data. */ -{ - FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetParamCustData {OLEAUT32} - * - * Gets a custom data element from a parameter. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( - ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ - UINT indexFunc, /* [I] The index of the function for which to retrieve the custom data. */ - UINT indexParam, /* [I] The index of the parameter for which to retrieve the custom data. */ - REFGUID guid, /* [I] The GUID under which the custom data is stored. */ - VARIANT* pVarVal) /* [O] The custom data. */ -{ - FIXME("(%p,%d,%d,%s,%p), stub!\n", iface, indexFunc, indexParam, debugstr_guid(guid), pVarVal); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetVarCustData {OLEAUT32} - * - * Gets a custom data element from a variable. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( - ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ - UINT index, /* [I] The index of the variable for which to retrieve the custom data. */ - REFGUID guid, /* [I] The GUID under which the custom data is stored. */ - VARIANT* pVarVal) /* [O] The custom data. */ -{ - FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetImplTypeCustData {OLEAUT32} - * - * Gets a custom data element from an implemented type of a TypeInfo. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( - ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ - UINT index, /* [I] The index of the implemented type for which to retrieve the custom data. */ - REFGUID guid, /* [I] The GUID under which the custom data is stored. */ - VARIANT* pVarVal) /* [O] The custom data. */ -{ - FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetDocumentation2 {OLEAUT32} - * - * Gets some documentation from a TypeInfo in a locale-aware fashion. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of STG_E_INSUFFICIENTMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( - ITypeInfo2* iface, /* [I] The TypeInfo to retrieve the documentation from. */ - MEMBERID memid, /* [I] The member id (why?). */ - LCID lcid, /* [I] The locale (why?). */ - BSTR* pbstrHelpString, /* [O] The help string. */ - DWORD* pdwHelpStringContext, /* [O] The help string context. */ - BSTR* pbstrHelpStringDll) /* [O] The help file name. */ -{ - FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", iface, memid, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetAllCustData {OLEAUT32} - * - * Gets all of the custom data associated with a TypeInfo. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( - ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ - CUSTDATA* pCustData) /* [O] A pointer to the custom data. */ -{ - FIXME("(%p,%p), stub!\n", iface, pCustData); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetAllFuncCustData {OLEAUT32} - * - * Gets all of the custom data associated with a function. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( - ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ - UINT index, /* [I] The index of the function for which to retrieve the custom data. */ - CUSTDATA* pCustData) /* [O] A pointer to the custom data. */ -{ - FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetAllParamCustData {OLEAUT32} - * - * Gets all of the custom data associated with a parameter. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( - ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ - UINT indexFunc, /* [I] The index of the function for which to retrieve the custom data. */ - UINT indexParam, /* [I] The index of the parameter for which to retrieve the custom data. */ - CUSTDATA* pCustData) /* [O] A pointer to the custom data. */ -{ - FIXME("(%p,%d,%d,%p), stub!\n", iface, indexFunc, indexParam, pCustData); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetAllVarCustData {OLEAUT32} - * - * Gets all of the custom data associated with a variable. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( - ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ - UINT index, /* [I] The index of the variable for which to retrieve the custom data. */ - CUSTDATA* pCustData) /* [O] A pointer to the custom data. */ -{ - FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeInfo2_GetAllImplTypeCustData {OLEAUT32} - * - * Gets all of the custom data associated with an implemented type. - * - * RETURNS - * - * Success: S_OK. - * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( - ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ - UINT index, /* [I] The index of the implemented type for which to retrieve the custom data. */ - CUSTDATA* pCustData) /* [O] A pointer to the custom data. */ -{ - FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData); - return E_OUTOFMEMORY; -} - - -/*================== ICreateTypeInfo2 & ITypeInfo2 VTABLEs And Creation ===================================*/ - -static const ICreateTypeInfo2Vtbl ctypeinfo2vt = -{ - - ICreateTypeInfo2_fnQueryInterface, - ICreateTypeInfo2_fnAddRef, - ICreateTypeInfo2_fnRelease, - - ICreateTypeInfo2_fnSetGuid, - ICreateTypeInfo2_fnSetTypeFlags, - ICreateTypeInfo2_fnSetDocString, - ICreateTypeInfo2_fnSetHelpContext, - ICreateTypeInfo2_fnSetVersion, - ICreateTypeInfo2_fnAddRefTypeInfo, - ICreateTypeInfo2_fnAddFuncDesc, - ICreateTypeInfo2_fnAddImplType, - ICreateTypeInfo2_fnSetImplTypeFlags, - ICreateTypeInfo2_fnSetAlignment, - ICreateTypeInfo2_fnSetSchema, - ICreateTypeInfo2_fnAddVarDesc, - ICreateTypeInfo2_fnSetFuncAndParamNames, - ICreateTypeInfo2_fnSetVarName, - ICreateTypeInfo2_fnSetTypeDescAlias, - ICreateTypeInfo2_fnDefineFuncAsDllEntry, - ICreateTypeInfo2_fnSetFuncDocString, - ICreateTypeInfo2_fnSetVarDocString, - ICreateTypeInfo2_fnSetFuncHelpContext, - ICreateTypeInfo2_fnSetVarHelpContext, - ICreateTypeInfo2_fnSetMops, - ICreateTypeInfo2_fnSetTypeIdldesc, - ICreateTypeInfo2_fnLayOut, - - ICreateTypeInfo2_fnDeleteFuncDesc, - ICreateTypeInfo2_fnDeleteFuncDescByMemId, - ICreateTypeInfo2_fnDeleteVarDesc, - ICreateTypeInfo2_fnDeleteVarDescByMemId, - ICreateTypeInfo2_fnDeleteImplType, - ICreateTypeInfo2_fnSetCustData, - ICreateTypeInfo2_fnSetFuncCustData, - ICreateTypeInfo2_fnSetParamCustData, - ICreateTypeInfo2_fnSetVarCustData, - ICreateTypeInfo2_fnSetImplTypeCustData, - ICreateTypeInfo2_fnSetHelpStringContext, - ICreateTypeInfo2_fnSetFuncHelpStringContext, - ICreateTypeInfo2_fnSetVarHelpStringContext, - ICreateTypeInfo2_fnInvalidate, - ICreateTypeInfo2_fnSetName -}; - -static const ITypeInfo2Vtbl typeinfo2vt = -{ - - ITypeInfo2_fnQueryInterface, - ITypeInfo2_fnAddRef, - ITypeInfo2_fnRelease, - - ITypeInfo2_fnGetTypeAttr, - ITypeInfo2_fnGetTypeComp, - ITypeInfo2_fnGetFuncDesc, - ITypeInfo2_fnGetVarDesc, - ITypeInfo2_fnGetNames, - ITypeInfo2_fnGetRefTypeOfImplType, - ITypeInfo2_fnGetImplTypeFlags, - ITypeInfo2_fnGetIDsOfNames, - ITypeInfo2_fnInvoke, - ITypeInfo2_fnGetDocumentation, - ITypeInfo2_fnGetDllEntry, - ITypeInfo2_fnGetRefTypeInfo, - ITypeInfo2_fnAddressOfMember, - ITypeInfo2_fnCreateInstance, - ITypeInfo2_fnGetMops, - ITypeInfo2_fnGetContainingTypeLib, - ITypeInfo2_fnReleaseTypeAttr, - ITypeInfo2_fnReleaseFuncDesc, - ITypeInfo2_fnReleaseVarDesc, - - ITypeInfo2_fnGetTypeKind, - ITypeInfo2_fnGetTypeFlags, - ITypeInfo2_fnGetFuncIndexOfMemId, - ITypeInfo2_fnGetVarIndexOfMemId, - ITypeInfo2_fnGetCustData, - ITypeInfo2_fnGetFuncCustData, - ITypeInfo2_fnGetParamCustData, - ITypeInfo2_fnGetVarCustData, - ITypeInfo2_fnGetImplTypeCustData, - ITypeInfo2_fnGetDocumentation2, - ITypeInfo2_fnGetAllCustData, - ITypeInfo2_fnGetAllFuncCustData, - ITypeInfo2_fnGetAllParamCustData, - ITypeInfo2_fnGetAllVarCustData, - ITypeInfo2_fnGetAllImplTypeCustData, -}; - -static ICreateTypeInfo2 *ICreateTypeInfo2_Constructor(ICreateTypeLib2Impl *typelib, WCHAR *szName, TYPEKIND tkind) -{ - ICreateTypeInfo2Impl *pCreateTypeInfo2Impl; - - int nameoffset; - int typeinfo_offset; - MSFT_TypeInfoBase *typeinfo; - - TRACE("Constructing ICreateTypeInfo2 for %s with tkind %d\n", debugstr_w(szName), tkind); - - pCreateTypeInfo2Impl = heap_alloc_zero(sizeof(ICreateTypeInfo2Impl)); - if (!pCreateTypeInfo2Impl) return NULL; - - pCreateTypeInfo2Impl->ICreateTypeInfo2_iface.lpVtbl = &ctypeinfo2vt; - pCreateTypeInfo2Impl->ITypeInfo2_iface.lpVtbl = &typeinfo2vt; - pCreateTypeInfo2Impl->ref = 1; - - pCreateTypeInfo2Impl->typelib = typelib; - ICreateTypeLib_AddRef((ICreateTypeLib*)typelib); - - nameoffset = ctl2_alloc_name(typelib, szName); - typeinfo_offset = ctl2_alloc_typeinfo(typelib, nameoffset); - typeinfo = (MSFT_TypeInfoBase *)&typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][typeinfo_offset]; - - typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset + 9] = 0x38; - *((int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset]) = typeinfo_offset; - - pCreateTypeInfo2Impl->typeinfo = typeinfo; - - pCreateTypeInfo2Impl->typekind = tkind; - typeinfo->typekind |= tkind | 0x20; - ICreateTypeInfo2_SetAlignment(&pCreateTypeInfo2Impl->ICreateTypeInfo2_iface, 4); - - switch (tkind) { - case TKIND_ENUM: - case TKIND_INTERFACE: - case TKIND_DISPATCH: - case TKIND_COCLASS: - typeinfo->size = 4; - break; - - case TKIND_RECORD: - case TKIND_UNION: - typeinfo->size = 0; - break; - - case TKIND_MODULE: - typeinfo->size = 2; - break; - - case TKIND_ALIAS: - typeinfo->size = -0x75; - break; - - default: - FIXME("(%s,%d), unrecognized typekind %d\n", debugstr_w(szName), tkind, tkind); - typeinfo->size = 0xdeadbeef; - break; - } - - if (typelib->last_typeinfo) typelib->last_typeinfo->next_typeinfo = pCreateTypeInfo2Impl; - typelib->last_typeinfo = pCreateTypeInfo2Impl; - if (!typelib->typeinfos) typelib->typeinfos = pCreateTypeInfo2Impl; - - TRACE(" -- %p\n", pCreateTypeInfo2Impl); - - return &pCreateTypeInfo2Impl->ICreateTypeInfo2_iface; -} - - -/*================== ICreateTypeLib2 Implementation ===================================*/ - -/****************************************************************************** - * ICreateTypeLib2_QueryInterface {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface( - ICreateTypeLib2 * iface, - REFIID riid, - VOID **ppvObject) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - - TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid)); - - *ppvObject=NULL; - if(IsEqualIID(riid, &IID_IUnknown) || - IsEqualIID(riid,&IID_ICreateTypeLib)|| - IsEqualIID(riid,&IID_ICreateTypeLib2)) - { - *ppvObject = This; - } else if (IsEqualIID(riid, &IID_ITypeLib) || - IsEqualIID(riid, &IID_ITypeLib2)) { - *ppvObject = &This->ITypeLib2_iface; - } - - if(*ppvObject) - { - ICreateTypeLib2_AddRef(iface); - TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject); - return S_OK; - } - TRACE("-- Interface: E_NOINTERFACE\n"); - return E_NOINTERFACE; -} - -/****************************************************************************** - * ICreateTypeLib2_AddRef {OLEAUT32} - */ -static ULONG WINAPI ICreateTypeLib2_fnAddRef(ICreateTypeLib2 *iface) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p)->(%u)\n", This, ref); - - return ref; -} - -/****************************************************************************** - * ICreateTypeLib2_Release {OLEAUT32} - */ -static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(%u)\n", This, ref); - - if (!ref) { - int i; - - for (i = 0; i < MSFT_SEG_MAX; i++) { - heap_free(This->typelib_segment_data[i]); - This->typelib_segment_data[i] = NULL; - } - - SysFreeString(This->filename); - This->filename = NULL; - - while (This->typeinfos) { - ICreateTypeInfo2Impl *typeinfo = This->typeinfos; - This->typeinfos = typeinfo->next_typeinfo; - if(typeinfo->typedata) { - CyclicList *iter, *rem; - - rem = typeinfo->typedata->next; - typeinfo->typedata->next = NULL; - iter = rem->next; - heap_free(rem); - - while(iter) { - rem = iter; - iter = iter->next; - heap_free(rem->u.data); - heap_free(rem); - } - } - - heap_free(typeinfo->dual); - heap_free(typeinfo); - } - - heap_free(This); - } - - return ref; -} - - -/****************************************************************************** - * ICreateTypeLib2_CreateTypeInfo {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo( - ICreateTypeLib2 * iface, - LPOLESTR szName, - TYPEKIND tkind, - ICreateTypeInfo **tinfo) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - char *name; - - TRACE("(%p,%s,%d,%p)\n", iface, debugstr_w(szName), tkind, tinfo); - - if (!szName || !tinfo) return E_INVALIDARG; - - ctl2_encode_name(This, szName, &name); - if(ctl2_find_name(This, name) != -1) - return TYPE_E_NAMECONFLICT; - - *tinfo = (ICreateTypeInfo *)ICreateTypeInfo2_Constructor(This, szName, tkind); - if (!*tinfo) return E_OUTOFMEMORY; - - return S_OK; -} - -/****************************************************************************** - * ICreateTypeLib2_SetName {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeLib2_fnSetName( - ICreateTypeLib2 * iface, - LPOLESTR szName) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - int offset; - - TRACE("(%p,%s)\n", iface, debugstr_w(szName)); - - offset = ctl2_alloc_name(This, szName); - if (offset == -1) return E_OUTOFMEMORY; - This->typelib_header.NameOffset = offset; - return S_OK; -} - -/****************************************************************************** - * ICreateTypeLib2_SetVersion {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeLib2_fnSetVersion(ICreateTypeLib2 * iface, WORD wMajorVerNum, WORD wMinorVerNum) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - - TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum); - - This->typelib_header.version = wMajorVerNum | (wMinorVerNum << 16); - return S_OK; -} - -/****************************************************************************** - * ICreateTypeLib2_SetGuid {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeLib2_fnSetGuid(ICreateTypeLib2 * iface, REFGUID guid) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - MSFT_GuidEntry guidentry; - int offset; - - TRACE("(%p,%s)\n", iface, debugstr_guid(guid)); - - guidentry.guid = *guid; - guidentry.hreftype = -2; - guidentry.next_hash = -1; - - offset = ctl2_alloc_guid(This, &guidentry); - - if (offset == -1) return E_OUTOFMEMORY; - - This->typelib_header.posguid = offset; - - return S_OK; -} - -/****************************************************************************** - * ICreateTypeLib2_SetDocString {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeLib2_fnSetDocString(ICreateTypeLib2 * iface, LPOLESTR szDoc) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - int offset; - - TRACE("(%p,%s)\n", iface, debugstr_w(szDoc)); - if (!szDoc) - return E_INVALIDARG; - - offset = ctl2_alloc_string(This, szDoc); - if (offset == -1) return E_OUTOFMEMORY; - This->typelib_header.helpstring = offset; - return S_OK; -} - -/****************************************************************************** - * ICreateTypeLib2_SetHelpFileName {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 * iface, LPOLESTR szHelpFileName) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - int offset; - - TRACE("(%p,%s)\n", iface, debugstr_w(szHelpFileName)); - - offset = ctl2_alloc_string(This, szHelpFileName); - if (offset == -1) return E_OUTOFMEMORY; - This->typelib_header.helpfile = offset; - This->typelib_header.varflags |= 0x10; - return S_OK; -} - -/****************************************************************************** - * ICreateTypeLib2_SetHelpContext {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 * iface, DWORD dwHelpContext) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - - TRACE("(%p,%d)\n", iface, dwHelpContext); - This->typelib_header.helpcontext = dwHelpContext; - return S_OK; -} - -/****************************************************************************** - * ICreateTypeLib2_SetLcid {OLEAUT32} - * - * Sets both the lcid and lcid2 members in the header to lcid. - * - * As a special case if lcid == LOCALE_NEUTRAL (0), then the first header lcid - * is set to US English while the second one is set to 0. - */ -static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 * iface, LCID lcid) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - - TRACE("(%p,%d)\n", iface, lcid); - - This->typelib_header.lcid = This->typelib_header.lcid2 = lcid; - - if(lcid == LOCALE_NEUTRAL) This->typelib_header.lcid = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); - - return S_OK; -} - -/****************************************************************************** - * ICreateTypeLib2_SetLibFlags {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeLib2_fnSetLibFlags(ICreateTypeLib2 * iface, UINT uLibFlags) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - - TRACE("(%p,0x%x)\n", iface, uLibFlags); - - This->typelib_header.flags = uLibFlags; - - return S_OK; -} - -static int ctl2_write_chunk(HANDLE hFile, const void *segment, int length) -{ - DWORD dwWritten; - if (!WriteFile(hFile, segment, length, &dwWritten, 0)) { - TRACE("Writefile(%p, %d) failed, lasterror %d\n", segment, length, GetLastError()); - CloseHandle(hFile); - return 0; - } - return -1; -} - -static int ctl2_write_segment(ICreateTypeLib2Impl *This, HANDLE hFile, int segment) -{ - DWORD dwWritten; - if (!WriteFile(hFile, This->typelib_segment_data[segment], - This->typelib_segdir[segment].length, &dwWritten, 0)) { - CloseHandle(hFile); - return 0; - } - - return -1; -} - -static HRESULT ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize) -{ - ICreateTypeInfo2Impl *typeinfo; - HRESULT hres; - - for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { - typeinfo->typeinfo->memoffset = filesize; - - hres = ICreateTypeInfo2_fnLayOut(&typeinfo->ICreateTypeInfo2_iface); - if(FAILED(hres)) - return hres; - - if (typeinfo->typedata) - filesize += typeinfo->typedata->next->u.val - + cti2_get_var_count(typeinfo->typeinfo) * 12 - + cti2_get_func_count(typeinfo->typeinfo) * 12 + 4; - } - - return S_OK; -} - -static int ctl2_finalize_segment(ICreateTypeLib2Impl *This, int filepos, int segment) -{ - if (This->typelib_segdir[segment].length) { - This->typelib_segdir[segment].offset = filepos; - } else { - This->typelib_segdir[segment].offset = -1; - } - - return This->typelib_segdir[segment].length; -} - -static int ctl2_write_typeinfos(ICreateTypeLib2Impl *This, HANDLE hFile) -{ - ICreateTypeInfo2Impl *typeinfo; - - for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { - CyclicList *iter; - int offset = 0; - - if (!typeinfo->typedata) continue; - - iter = typeinfo->typedata->next; - if (!ctl2_write_chunk(hFile, &iter->u.val, sizeof(int))) - return 0; - for(iter=iter->next; iter!=typeinfo->typedata->next; iter=iter->next) - if (!ctl2_write_chunk(hFile, iter->u.data, ctl2_get_record_size(iter))) - return 0; - - for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) - if (!ctl2_write_chunk(hFile, &iter->indice, sizeof(int))) - return 0; - - for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) - if (!ctl2_write_chunk(hFile, &iter->name, sizeof(int))) - return 0; - - for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) { - if (!ctl2_write_chunk(hFile, &offset, sizeof(int))) - return 0; - offset += ctl2_get_record_size(iter); - } - } - return 1; -} - -/****************************************************************************** - * ICreateTypeLib2_SaveAllChanges {OLEAUT32} - */ -static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - int retval; - int filepos; - HANDLE hFile; - HRESULT hres; - - TRACE("(%p)\n", iface); - - retval = TYPE_E_IOERROR; - - hFile = CreateFileW(This->filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - if (hFile == INVALID_HANDLE_VALUE) return retval; - - filepos = sizeof(MSFT_Header) + sizeof(MSFT_SegDir); - filepos += This->typelib_header.nrtypeinfos * 4; - - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEINFO); - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUIDHASH); - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUID); - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_REFERENCES); - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTINFO); - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTFILES); - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAMEHASH); - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAME); - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_STRING); - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEDESC); - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_ARRAYDESC); - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATA); - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATAGUID); - - hres = ctl2_finalize_typeinfos(This, filepos); - if(FAILED(hres)) { - CloseHandle(hFile); - return hres; - } - - if (!ctl2_write_chunk(hFile, &This->typelib_header, sizeof(This->typelib_header))) return retval; - if (This->typelib_header.varflags & HELPDLLFLAG) - if (!ctl2_write_chunk(hFile, &This->helpStringDll, sizeof(This->helpStringDll))) return retval; - if (!ctl2_write_chunk(hFile, This->typelib_typeinfo_offsets, This->typelib_header.nrtypeinfos * 4)) return retval; - if (!ctl2_write_chunk(hFile, This->typelib_segdir, sizeof(This->typelib_segdir))) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEINFO )) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUIDHASH )) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUID )) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_REFERENCES )) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTINFO )) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTFILES )) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAMEHASH )) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAME )) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_STRING )) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEDESC )) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_ARRAYDESC )) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATA )) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATAGUID)) return retval; - - if (!ctl2_write_typeinfos(This, hFile)) return retval; - - if (!CloseHandle(hFile)) return retval; - - return S_OK; -} - - -/****************************************************************************** - * ICreateTypeLib2_DeleteTypeInfo {OLEAUT32} - * - * Deletes a named TypeInfo from a type library. - * - * RETURNS - * - * Success: S_OK - * Failure: E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ICreateTypeLib2_fnDeleteTypeInfo( - ICreateTypeLib2 * iface, /* [I] The type library to delete from. */ - LPOLESTR szName) /* [I] The name of the typeinfo to delete. */ -{ - FIXME("(%p,%s), stub!\n", iface, debugstr_w(szName)); - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeLib2_SetCustData {OLEAUT32} - * - * Sets custom data for a type library. - * - * RETURNS - * - * Success: S_OK - * Failure: E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ICreateTypeLib2_fnSetCustData( - ICreateTypeLib2 * iface, /* [I] The type library to store the custom data in. */ - REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ - VARIANT *pVarVal) /* [I] The custom data itself. */ -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), pVarVal); - - return ctl2_set_custdata(This, guid, pVarVal, &This->typelib_header.CustomDataOffset); -} - -/****************************************************************************** - * ICreateTypeLib2_SetHelpStringContext {OLEAUT32} - * - * Sets a context number for the library help string. - * - * PARAMS - * iface [I] The type library to set the help string context for. - * dwContext [I] The help string context. - * - * RETURNS - * Success: S_OK - * Failure: E_OUTOFMEMORY or E_INVALIDARG. - */ -static -HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 * iface, - ULONG dwContext) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - - TRACE("(%p,%d)\n", iface, dwContext); - - This->typelib_header.helpstringcontext = dwContext; - return S_OK; -} - -/****************************************************************************** - * ICreateTypeLib2_SetHelpStringDll {OLEAUT32} - * - * Set the DLL used to look up localized help strings. - * - * PARAMS - * iface [I] The type library to set the help DLL for. - * szDllName [I] The name of the help DLL. - * - * RETURNS - * Success: S_OK - * Failure: E_OUTOFMEMORY or E_INVALIDARG. - */ -static -HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringDll(ICreateTypeLib2 * iface, - LPOLESTR szDllName) -{ - ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); - int offset; - - TRACE("(%p,%s)\n", iface, debugstr_w(szDllName)); - if (!szDllName) - return E_INVALIDARG; - - offset = ctl2_alloc_string(This, szDllName); - if (offset == -1) - return E_OUTOFMEMORY; - This->typelib_header.varflags |= HELPDLLFLAG; - This->helpStringDll = offset; - return S_OK; -} - -/*================== ITypeLib2 Implementation ===================================*/ - -/****************************************************************************** - * ITypeLib2_QueryInterface {OLEAUT32} - */ -static HRESULT WINAPI ITypeLib2_fnQueryInterface(ITypeLib2 * iface, REFIID riid, LPVOID * ppv) -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - return ICreateTypeLib2_QueryInterface(&This->ICreateTypeLib2_iface, riid, ppv); -} - -/****************************************************************************** - * ITypeLib2_AddRef {OLEAUT32} - */ -static ULONG WINAPI ITypeLib2_fnAddRef(ITypeLib2 * iface) -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - return ICreateTypeLib2_AddRef(&This->ICreateTypeLib2_iface); -} - -/****************************************************************************** - * ITypeLib2_Release {OLEAUT32} - */ -static ULONG WINAPI ITypeLib2_fnRelease(ITypeLib2 * iface) -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - return ICreateTypeLib2_Release(&This->ICreateTypeLib2_iface); -} - -/****************************************************************************** - * ITypeLib2_GetTypeInfoCount {OLEAUT32} - */ -static UINT WINAPI ITypeLib2_fnGetTypeInfoCount( - ITypeLib2 * iface) -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - TRACE("(%p)\n", iface); - - return This->typelib_header.nrtypeinfos; -} - -/****************************************************************************** - * ITypeLib2_GetTypeInfo {OLEAUT32} - */ -static HRESULT WINAPI ITypeLib2_fnGetTypeInfo( - ITypeLib2 * iface, - UINT index, - ITypeInfo** ppTInfo) -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - TRACE("(%p,%d,%p)\n", iface, index, ppTInfo); - - if (!ppTInfo) return E_INVALIDARG; - - if (index >= This->typelib_header.nrtypeinfos) { - return TYPE_E_ELEMENTNOTFOUND; - } - - return ctl2_find_typeinfo_from_offset(This, This->typelib_typeinfo_offsets[index], ppTInfo); -} - -/****************************************************************************** - * ITypeLib2_GetTypeInfoType {OLEAUT32} - */ -static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType( - ITypeLib2 * iface, - UINT index, - TYPEKIND* kind) -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - TRACE("(%p,%d,%p)\n", iface, index, kind); - - if (!kind) return E_INVALIDARG; - - if (index >= This->typelib_header.nrtypeinfos) { - return TYPE_E_ELEMENTNOTFOUND; - } - - *kind = (This->typelib_segment_data[MSFT_SEG_TYPEINFO][This->typelib_typeinfo_offsets[index]]) & 0xF; - - return S_OK; -} - -/****************************************************************************** - * ITypeLib2_GetTypeInfoOfGuid {OLEAUT32} - */ -static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid( - ITypeLib2 * iface, - REFGUID guid, - ITypeInfo** ppTinfo) -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - int guidoffset; - int typeinfo; - - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), ppTinfo); - - guidoffset = ctl2_find_guid(This, ctl2_hash_guid(guid), guid); - if (guidoffset == -1) return TYPE_E_ELEMENTNOTFOUND; - - typeinfo = ((MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][guidoffset])->hreftype; - if (typeinfo < 0) return TYPE_E_ELEMENTNOTFOUND; - - return ctl2_find_typeinfo_from_offset(This, typeinfo, ppTinfo); -} - -/****************************************************************************** - * ITypeLib2_GetLibAttr {OLEAUT32} - */ -static HRESULT WINAPI ITypeLib2_fnGetLibAttr( - ITypeLib2 * iface, - TLIBATTR** ppTLibAttr) -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - TRACE("(%p,%p)\n", This, ppTLibAttr); - - if(!ppTLibAttr) - return E_INVALIDARG; - - *ppTLibAttr = heap_alloc_zero(sizeof(TLIBATTR)); - if(!*ppTLibAttr) - return E_OUTOFMEMORY; - - if(This->typelib_header.posguid != -1) { - MSFT_GuidEntry *guid; - - guid = (MSFT_GuidEntry*)&This->typelib_segment_data[MSFT_SEG_GUID][This->typelib_header.posguid]; - (*ppTLibAttr)->guid = guid->guid; - } - - (*ppTLibAttr)->lcid = This->typelib_header.lcid; - (*ppTLibAttr)->syskind = ctl2_get_syskind(This); - (*ppTLibAttr)->wMajorVerNum = LOWORD(This->typelib_header.version); - (*ppTLibAttr)->wMinorVerNum = HIWORD(This->typelib_header.version); - (*ppTLibAttr)->wLibFlags = This->typelib_header.flags; - return S_OK; -} - -/****************************************************************************** - * ITypeLib2_GetTypeComp {OLEAUT32} - */ -static HRESULT WINAPI ITypeLib2_fnGetTypeComp( - ITypeLib2 * iface, - ITypeComp** ppTComp) -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - FIXME("(%p,%p), stub!\n", This, ppTComp); - - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeLib2_GetDocumentation {OLEAUT32} - */ -static HRESULT WINAPI ITypeLib2_fnGetDocumentation( - ITypeLib2 * iface, - INT index, - BSTR* pBstrName, - BSTR* pBstrDocString, - DWORD* pdwHelpContext, - BSTR* pBstrHelpFile) -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - WCHAR *string; - - TRACE("(%p,%d,%p,%p,%p,%p)\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); - - if(index != -1) { - ICreateTypeInfo2Impl *iter; - - for(iter=This->typeinfos; iter!=NULL && index!=0; iter=iter->next_typeinfo) - index--; - - if(!iter) - return TYPE_E_ELEMENTNOTFOUND; - - return ITypeInfo2_GetDocumentation(&iter->ITypeInfo2_iface, - -1, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); - } - - if(pBstrName) { - if(This->typelib_header.NameOffset == -1) - *pBstrName = NULL; - else { - MSFT_NameIntro *name = (MSFT_NameIntro*)&This-> - typelib_segment_data[MSFT_SEG_NAME][This->typelib_header.NameOffset]; - - ctl2_decode_name((char*)&name->namelen, &string); - - *pBstrName = SysAllocString(string); - if(!*pBstrName) - return E_OUTOFMEMORY; - } - } - - if(pBstrDocString) { - if(This->typelib_header.helpstring == -1) - *pBstrDocString = NULL; - else { - ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpstring], &string); - - *pBstrDocString = SysAllocString(string); - if(!*pBstrDocString) { - if(pBstrName) SysFreeString(*pBstrName); - return E_OUTOFMEMORY; - } - } - } - - if(pdwHelpContext) - *pdwHelpContext = This->typelib_header.helpcontext; - - if(pBstrHelpFile) { - if(This->typelib_header.helpfile == -1) - *pBstrHelpFile = NULL; - else { - ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpfile], &string); - - *pBstrHelpFile = SysAllocString(string); - if(!*pBstrHelpFile) { - if(pBstrName) SysFreeString(*pBstrName); - if(pBstrDocString) SysFreeString(*pBstrDocString); - return E_OUTOFMEMORY; - } - } - } - - return S_OK; -} - -/****************************************************************************** - * ITypeLib2_IsName {OLEAUT32} - */ -static HRESULT WINAPI ITypeLib2_fnIsName( - ITypeLib2 * iface, - LPOLESTR szNameBuf, - ULONG lHashVal, - BOOL* pfName) -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - char *encoded_name; - int nameoffset; - MSFT_NameIntro *nameintro; - - TRACE("(%p,%s,%x,%p)\n", iface, debugstr_w(szNameBuf), lHashVal, pfName); - - ctl2_encode_name(This, szNameBuf, &encoded_name); - nameoffset = ctl2_find_name(This, encoded_name); - - *pfName = 0; - - if (nameoffset == -1) return S_OK; - - nameintro = (MSFT_NameIntro *)(&This->typelib_segment_data[MSFT_SEG_NAME][nameoffset]); - if (nameintro->hreftype == -1) return S_OK; - - *pfName = 1; - - FIXME("Should be decoding our copy of the name over szNameBuf.\n"); - - return S_OK; -} - -/****************************************************************************** - * ITypeLib2_FindName {OLEAUT32} - */ -static HRESULT WINAPI ITypeLib2_fnFindName( - ITypeLib2 * iface, - LPOLESTR szNameBuf, - ULONG lHashVal, - ITypeInfo** ppTInfo, - MEMBERID* rgMemId, - USHORT* pcFound) -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - FIXME("(%p,%s,%x,%p,%p,%p), stub!\n", This, debugstr_w(szNameBuf), lHashVal, ppTInfo, rgMemId, pcFound); - - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ITypeLib2_ReleaseTLibAttr {OLEAUT32} - */ -static void WINAPI ITypeLib2_fnReleaseTLibAttr( - ITypeLib2 * iface, - TLIBATTR* attr) -{ - TRACE("(%p,%p)\n", iface, attr); - heap_free(attr); -} - -/****************************************************************************** - * ICreateTypeLib2_GetCustData {OLEAUT32} - * - * Retrieves a custom data value stored on a type library. - * - * RETURNS - * - * Success: S_OK - * Failure: E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeLib2_fnGetCustData( - ITypeLib2 * iface, /* [I] The type library in which to find the custom data. */ - REFGUID guid, /* [I] The GUID under which the custom data is stored. */ - VARIANT* pVarVal) /* [O] The custom data. */ -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - FIXME("(%p,%s,%p), stub!\n", This, debugstr_guid(guid), pVarVal); - - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeLib2_GetLibStatistics {OLEAUT32} - * - * Retrieves some statistics about names in a type library, supposedly for - * hash table optimization purposes. - * - * RETURNS - * - * Success: S_OK - * Failure: E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( - ITypeLib2 * iface, /* [I] The type library to get statistics about. */ - ULONG* pcUniqueNames, /* [O] The number of unique names in the type library. */ - ULONG* pcchUniqueNames) /* [O] The number of changed (?) characters in names in the type library. */ -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - FIXME("(%p,%p,%p), stub!\n", This, pcUniqueNames, pcchUniqueNames); - - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeLib2_GetDocumentation2 {OLEAUT32} - * - * Obtain locale-aware help string information. - * - * RETURNS - * - * Success: S_OK - * Failure: STG_E_INSUFFICIENTMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( - ITypeLib2 * iface, - INT index, - LCID lcid, - BSTR* pbstrHelpString, - DWORD* pdwHelpStringContext, - BSTR* pbstrHelpStringDll) -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", This, index, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll); - - return E_OUTOFMEMORY; -} - -/****************************************************************************** - * ICreateTypeLib2_GetAllCustData {OLEAUT32} - * - * Retrieve all of the custom data for a type library. - * - * RETURNS - * - * Success: S_OK - * Failure: E_OUTOFMEMORY or E_INVALIDARG. - */ -static HRESULT WINAPI ITypeLib2_fnGetAllCustData( - ITypeLib2 * iface, /* [I] The type library in which to find the custom data. */ - CUSTDATA* pCustData) /* [O] The structure in which to place the custom data. */ -{ - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - - FIXME("(%p,%p), stub!\n", This, pCustData); - - return E_OUTOFMEMORY; -} - - -/*================== ICreateTypeLib2 & ITypeLib2 VTABLEs And Creation ===================================*/ - -static const ICreateTypeLib2Vtbl ctypelib2vt = -{ - - ICreateTypeLib2_fnQueryInterface, - ICreateTypeLib2_fnAddRef, - ICreateTypeLib2_fnRelease, - - ICreateTypeLib2_fnCreateTypeInfo, - ICreateTypeLib2_fnSetName, - ICreateTypeLib2_fnSetVersion, - ICreateTypeLib2_fnSetGuid, - ICreateTypeLib2_fnSetDocString, - ICreateTypeLib2_fnSetHelpFileName, - ICreateTypeLib2_fnSetHelpContext, - ICreateTypeLib2_fnSetLcid, - ICreateTypeLib2_fnSetLibFlags, - ICreateTypeLib2_fnSaveAllChanges, - - ICreateTypeLib2_fnDeleteTypeInfo, - ICreateTypeLib2_fnSetCustData, - ICreateTypeLib2_fnSetHelpStringContext, - ICreateTypeLib2_fnSetHelpStringDll -}; - -static const ITypeLib2Vtbl typelib2vt = -{ - - ITypeLib2_fnQueryInterface, - ITypeLib2_fnAddRef, - ITypeLib2_fnRelease, - - ITypeLib2_fnGetTypeInfoCount, - ITypeLib2_fnGetTypeInfo, - ITypeLib2_fnGetTypeInfoType, - ITypeLib2_fnGetTypeInfoOfGuid, - ITypeLib2_fnGetLibAttr, - ITypeLib2_fnGetTypeComp, - ITypeLib2_fnGetDocumentation, - ITypeLib2_fnIsName, - ITypeLib2_fnFindName, - ITypeLib2_fnReleaseTLibAttr, - - ITypeLib2_fnGetCustData, - ITypeLib2_fnGetLibStatistics, - ITypeLib2_fnGetDocumentation2, - ITypeLib2_fnGetAllCustData, -}; - -static ICreateTypeLib2 *ICreateTypeLib2_Constructor(SYSKIND syskind, LPCOLESTR filename) -{ - ICreateTypeLib2Impl *create_tlib2; - int failed = 0; - - TRACE("Constructing ICreateTypeLib2 (%d, %s)\n", syskind, debugstr_w(filename)); - - create_tlib2 = heap_alloc_zero(sizeof(ICreateTypeLib2Impl)); - if (!create_tlib2) return NULL; - - create_tlib2->filename = SysAllocString(filename); - if (!create_tlib2->filename) { - heap_free(create_tlib2); - return NULL; - } - - ctl2_init_header(create_tlib2); - ctl2_init_segdir(create_tlib2); - - create_tlib2->typelib_header.varflags |= syskind; - - /* - * The following two calls return an offset or -1 if out of memory. We - * specifically need an offset of 0, however, so... - */ - if (ctl2_alloc_segment(create_tlib2, MSFT_SEG_GUIDHASH, 0x80, 0x80) == 0) - { - create_tlib2->typelib_guidhash_segment = (int *)create_tlib2->typelib_segment_data[MSFT_SEG_GUIDHASH]; - memset(create_tlib2->typelib_guidhash_segment, 0xff, 0x80); - } - else - failed = 1; - - if (ctl2_alloc_segment(create_tlib2, MSFT_SEG_NAMEHASH, 0x200, 0x200) == 0) - { - create_tlib2->typelib_namehash_segment = (int *)create_tlib2->typelib_segment_data[MSFT_SEG_NAMEHASH]; - memset(create_tlib2->typelib_namehash_segment, 0xff, 0x200); - } - else - failed = 1; - - create_tlib2->ICreateTypeLib2_iface.lpVtbl = &ctypelib2vt; - create_tlib2->ITypeLib2_iface.lpVtbl = &typelib2vt; - create_tlib2->ref = 1; - - if (failed) { - ICreateTypeLib2_fnRelease(&create_tlib2->ICreateTypeLib2_iface); - heap_free(create_tlib2); - return NULL; - } - - return &create_tlib2->ICreateTypeLib2_iface; -} - -/****************************************************************************** - * CreateTypeLib2 [OLEAUT32.180] - * - * Obtains an ICreateTypeLib2 object for creating a new-style (MSFT) type - * library. - * - * NOTES - * - * See also CreateTypeLib. - * - * RETURNS - * Success: S_OK - * Failure: Status - */ -HRESULT WINAPI CreateTypeLib2( - SYSKIND syskind, /* [I] System type library is for */ - LPCOLESTR szFile, /* [I] Type library file name */ - ICreateTypeLib2** ppctlib) /* [O] Storage for object returned */ -{ - TRACE("(%d,%s,%p)\n", syskind, debugstr_w(szFile), ppctlib); - - if (!szFile) return E_INVALIDARG; - *ppctlib = ICreateTypeLib2_Constructor(syskind, szFile); - return (*ppctlib)? S_OK: E_OUTOFMEMORY; -} - -/****************************************************************************** - * ClearCustData (OLEAUT32.171) - * - * Clear a custom data types' data. - * - * PARAMS - * lpCust [I] The custom data type instance - * - * RETURNS - * Nothing. - */ -void WINAPI ClearCustData(LPCUSTDATA lpCust) -{ - if (lpCust && lpCust->cCustData) - { - if (lpCust->prgCustData) - { - DWORD i; - - for (i = 0; i < lpCust->cCustData; i++) - VariantClear(&lpCust->prgCustData[i].varValue); - - /* FIXME - Should be using a per-thread IMalloc */ - heap_free(lpCust->prgCustData); - lpCust->prgCustData = NULL; - } - lpCust->cCustData = 0; - } -} diff --git a/reactos/dll/win32/oleaut32/usrmarshal.c b/reactos/dll/win32/oleaut32/usrmarshal.c index 0c2ff593825..b6fe2e880e8 100644 --- a/reactos/dll/win32/oleaut32/usrmarshal.c +++ b/reactos/dll/win32/oleaut32/usrmarshal.c @@ -1073,15 +1073,16 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B Buffer += sizeof(wiresab[0]) * wiresa->cDims; if(vt) + { *ppsa = SafeArrayCreateEx(vt, wiresa->cDims, wiresab, NULL); + if (!*ppsa) RpcRaiseException(E_OUTOFMEMORY); + } else { - SafeArrayAllocDescriptor(wiresa->cDims, ppsa); - if(*ppsa) - memcpy((*ppsa)->rgsabound, wiresab, sizeof(SAFEARRAYBOUND) * wiresa->cDims); + if (FAILED(SafeArrayAllocDescriptor(wiresa->cDims, ppsa))) + RpcRaiseException(E_OUTOFMEMORY); + memcpy((*ppsa)->rgsabound, wiresab, sizeof(SAFEARRAYBOUND) * wiresa->cDims); } - if (!*ppsa) - RpcRaiseException(E_OUTOFMEMORY); /* be careful about which flags we set since they could be a security * risk */ @@ -2245,8 +2246,17 @@ HRESULT CALLBACK IClassFactory2_CreateInstanceLic_Proxy( BSTR bstrKey, PVOID *ppvObj) { - FIXME("not implemented\n"); - return E_NOTIMPL; + TRACE("(%p, %s, %p)\n", pUnkOuter, debugstr_guid(riid), ppvObj); + + *ppvObj = NULL; + + if (pUnkOuter) + { + ERR("aggregation is not allowed on remote objects\n"); + return CLASS_E_NOAGGREGATION; + } + + return IClassFactory2_RemoteCreateInstanceLic_Proxy(This, riid, bstrKey, (IUnknown**)ppvObj); } HRESULT __RPC_STUB IClassFactory2_CreateInstanceLic_Stub( @@ -2255,8 +2265,8 @@ HRESULT __RPC_STUB IClassFactory2_CreateInstanceLic_Stub( BSTR bstrKey, IUnknown **ppvObj) { - FIXME("not implemented\n"); - return E_NOTIMPL; + TRACE("(%s, %p)\n", debugstr_guid(riid), ppvObj); + return IClassFactory2_CreateInstanceLic(This, NULL, NULL, riid, bstrKey, (void**)ppvObj); } HRESULT CALLBACK IEnumConnections_Next_Proxy( diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index d9cd1fe0c21..07bdb3f6fad 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -144,7 +144,7 @@ reactos/dll/win32/odbc32 # Out of sync. Depends on port of Linux ODBC. reactos/dll/win32/odbccp32 # Synced to Wine-1.5.19 reactos/dll/win32/ole32 # Synced to Wine-1.7.1 reactos/dll/win32/oleacc # Autosync -reactos/dll/win32/oleaut32 # Synced to Wine-1.5.26 +reactos/dll/win32/oleaut32 # Synced to Wine-1.7.1 reactos/dll/win32/olecli32 # Synced to Wine-1.5.19 reactos/dll/win32/oledlg # Autosync reactos/dll/win32/olepro32 # Autosync