4 * Copyright 1997 Marcus Meissner
6 * there is much left to do here before it can be useful for real world
9 * -. Only one format of typelibs is supported
10 * -. All testing so far is done using special written windows programs
11 * -. Data structures are straightforward, but slow for look-ups.
12 * -. (related) nothing is hashed
13 * -. a typelib is always read in its entirety into memory and never released.
14 * -. there are a number of stubs in ITypeLib and ITypeInfo interfaces. Most
15 * of them I don't know yet how to implement them.
16 * -. Most error return values are just guessed not checked with windows
18 * -. all locale stuff ignored
19 * -. move stuff to wine/dlls
20 * -. didn't bother with a c++ interface
21 * -. lousy fatal error handling
22 * -. some methods just return pointers to internal data structures, this is
23 * partly laziness, partly I want to check how windows does it.
32 #include "winreg.h" /* for HKEY_LOCAL_MACHINE */
33 #include "winnls.h" /* for PRIMARYLANGID */
34 #include "wine/winbase16.h" /* for RegQueryValue16(HKEY,LPSTR,LPSTR,LPDWORD) */
36 #include "wine/obj_base.h"
37 #include "debugtools.h"
38 #include "winversion.h"
41 DEFAULT_DEBUG_CHANNEL(ole);
42 DECLARE_DEBUG_CHANNEL(typelib);
44 /****************************************************************************
45 * QueryPathOfRegTypeLib16 [TYPELIB.14]
47 * the path is "Classes\Typelib\<guid>\<major>.<minor>\<lcid>\win16\"
52 QueryPathOfRegTypeLib16(
53 REFGUID guid, /* [in] referenced guid */
54 WORD wMaj, /* [in] major version */
55 WORD wMin, /* [in] minor version */
56 LCID lcid, /* [in] locale id */
57 LPBSTR16 path /* [out] path of typelib */
60 char typelibkey[100],pathname[260];
66 sprintf( typelibkey, "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win16",
67 guid->Data1, guid->Data2, guid->Data3,
68 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
69 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7],
72 sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
73 FIXME("(%s,%d,%d,0x%04lx,%p),can't handle non-string guids.\n",xguid,wMaj,wMin,(DWORD)lcid,path);
76 plen = sizeof(pathname);
77 if (RegQueryValue16(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
78 /* try again without lang specific id */
80 return QueryPathOfRegTypeLib16(guid,wMaj,wMin,PRIMARYLANGID(lcid),path);
81 FIXME("key %s not found\n",typelibkey);
84 *path = SysAllocString16(pathname);
88 /****************************************************************************
89 * QueryPathOfRegTypeLib [OLEAUT32.164]
94 QueryPathOfRegTypeLib(
95 REFGUID guid, /* [in] referenced guid */
96 WORD wMaj, /* [in] major version */
97 WORD wMin, /* [in] minor version */
98 LCID lcid, /* [in] locale id */
99 LPBSTR path /* [out] path of typelib */
102 char typelibkey[100],pathname[260];
108 sprintf( typelibkey, "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win32",
109 guid->Data1, guid->Data2, guid->Data3,
110 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
111 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7],
114 sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
115 FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n",xguid,wMaj,wMin,(DWORD)lcid,path);
118 plen = sizeof(pathname);
119 if (RegQueryValue16(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
120 /* try again without lang specific id */
122 return QueryPathOfRegTypeLib(guid,wMaj,wMin,PRIMARYLANGID(lcid),path);
123 FIXME("key %s not found\n",typelibkey);
126 *path = HEAP_strdupAtoW(GetProcessHeap(),0,pathname);
130 /******************************************************************************
131 * CreateTypeLib [OLEAUT32] creates a typelib
137 HRESULT WINAPI CreateTypeLib(
138 SYSKIND syskind, LPCOLESTR szFile, /*ICreateTypeLib*/IUnknown ** ppctlib
140 FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib);
143 /******************************************************************************
144 * LoadTypeLib [TYPELIB.3] Loads and registers a type library
146 * Docs: OLECHAR FAR* szFile
147 * Docs: iTypeLib FAR* FAR* pptLib
153 HRESULT WINAPI LoadTypeLib16(
154 LPOLESTR szFile, /* [in] Name of file to load from */
155 void * *pptLib) /* [out] Pointer to pointer to loaded type library */
157 FIXME("('%s',%p): stub\n",debugstr_w((LPWSTR)szFile),pptLib);
165 /******************************************************************************
166 * LoadTypeLib [OLEAUT32.161]
167 * Loads and registers a type library
169 * Docs: OLECHAR FAR* szFile
170 * Docs: iTypeLib FAR* FAR* pptLib
176 int TLB_ReadTypeLib(PCHAR file, ITypeLib2 **ppTypelib);
178 HRESULT WINAPI LoadTypeLib(
179 OLECHAR *szFile, /* [in] Name of file to load from */
180 ITypeLib * *pptLib) /* [out] Pointer to pointer to loaded type library */
183 return LoadTypeLibEx(szFile, REGKIND_DEFAULT, pptLib);
186 /******************************************************************************
187 * LoadTypeLibEx [OLEAUT32.183]
188 * Loads and optionally registers a type library
194 HRESULT WINAPI LoadTypeLibEx(
195 LPOLESTR szFile, /* [in] Name of file to load from */
196 REGKIND regkind, /* specify kind of registration */
197 ITypeLib **pptLib) /* [out] Pointer to pointer to loaded type library */
201 TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib);
203 p=HEAP_strdupWtoA(GetProcessHeap(),0,szFile);
205 if(regkind != REGKIND_NONE)
206 FIXME ("registration of typelibs not supported yet!\n");
208 res= TLB_ReadTypeLib(p, (ITypeLib2**)pptLib);
209 HeapFree(GetProcessHeap(),0,p);
210 TRACE(" returns %08lx\n",res);
215 /******************************************************************************
216 * LoadRegTypeLib [OLEAUT32.162]
218 HRESULT WINAPI LoadRegTypeLib(
219 REFGUID rguid, /* [in] referenced guid */
220 WORD wVerMajor, /* [in] major version */
221 WORD wVerMinor, /* [in] minor version */
222 LCID lcid, /* [in] locale id */
223 ITypeLib **ppTLib) /* [out] path of typelib */
226 HRESULT res=QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor, lcid, &bstr);
230 res= LoadTypeLib(bstr, ppTLib);
234 TRACE("(IID: %s) load %s (%p)\n",debugstr_guid(rguid), SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);
240 /******************************************************************************
241 * RegisterTypeLib [OLEAUT32.163]
242 * Adds information about a type library to the System Registry
244 * Docs: ITypeLib FAR * ptlib
245 * Docs: OLECHAR FAR* szFullPath
246 * Docs: OLECHAR FAR* szHelpDir
252 HRESULT WINAPI RegisterTypeLib(
253 ITypeLib * ptlib, /*[in] Pointer to the library*/
254 OLECHAR * szFullPath, /*[in] full Path of the library*/
255 OLECHAR * szHelpDir) /*[in] dir to the helpfile for the library,
257 { FIXME("(%p,%s,%s): stub\n",ptlib, debugstr_w(szFullPath),debugstr_w(szHelpDir));
258 return S_OK; /* FIXME: pretend everything is OK */
262 /******************************************************************************
263 * UnRegisterTypeLib [OLEAUT32.186]
264 * Removes information about a type library from the System Registry
271 HRESULT WINAPI UnRegisterTypeLib(
272 REFGUID libid, /* [in] Guid of the library */
273 WORD wVerMajor, /* [in] major version */
274 WORD wVerMinor, /* [in] minor version */
275 LCID lcid, /* [in] locale id */
278 TRACE("(IID: %s): stub\n",debugstr_guid(libid));
279 return S_OK; /* FIXME: pretend everything is OK */
282 /****************************************************************************
283 * OaBuildVersion (TYPELIB.15)
285 * known TYPELIB.DLL versions:
287 * OLE 2.01 no OaBuildVersion() avail 1993 -- ---
288 * OLE 2.02 1993-94 02 3002
291 * OLE 2.03 W98 SE orig. file !! 1993-95 10 3024
292 * OLE 2.1 NT 1993-95 ?? ???
293 * OLE 2.3.1 W95 23 700
295 DWORD WINAPI OaBuildVersion16(void)
297 FIXME("Please report to a.mohr@mailto.de if you get version error messages !\n");
298 switch(VERSION_GetVersion())
301 return MAKELONG(3027, 3); /* WfW 3.11 */
303 return MAKELONG(700, 23); /* Win95A */
305 return MAKELONG(3024, 10); /* W98 SE */
307 FIXME_(ole)("Version value not known yet. Please investigate it !");
312 /* for better debugging info leave the static out for the time being */
315 /*======================= ITypeLib implementation =======================*/
317 typedef struct tagTLBCustData
321 struct tagTLBCustData* next;
324 /* data structure for import typelibs */
325 typedef struct tagTLBImpLib
327 int offset; /* offset in the file */
328 GUID guid; /* libid */
329 PCHAR name; /* name; */
330 struct tagITypeLibImpl *pImpTypeLib; /* pointer to loaded typelib */
331 struct tagTLBImpLib * next;
334 /* internal ITypeLib data */
335 typedef struct tagITypeLibImpl
337 ICOM_VFIELD(ITypeLib2);
339 TLIBATTR LibAttr; /* guid,lcid,syskind,version,flags */
340 /* type libs seem to store the doc strings in ascii
341 * so why should we do it in unicode?
347 unsigned long dwHelpContext;
348 int TypeInfoCount; /* nr of typeinfo's in librarry */
349 struct tagITypeInfoImpl *pTypeInfo; /* linked list of type info data */
350 int ctCustData; /* number of items in cust data list */
351 TLBCustData * pCustData; /* linked list to cust data; */
352 TLBImpLib * pImpLibs; /* linked list to all imported typelibs */
353 TYPEDESC * pTypeDesc; /* array of TypeDescriptions found in the libary */
356 static struct ICOM_VTABLE(ITypeLib2) tlbvt;
358 /* ITypeLib methods */
359 static ITypeLib2* ITypeLib2_Constructor(LPVOID pLib);
361 /*======================= ITypeInfo implementation =======================*/
363 /* internal Parameter data */
364 typedef struct tagTLBParDesc
368 TLBCustData * pCustData; /* linked list to cust data; */
371 /* internal Function data */
372 typedef struct tagTLBFuncDesc
374 FUNCDESC funcdesc; /* lots of info on the function and its attributes. */
375 PCHAR Name; /* the name of this function */
376 TLBParDesc *pParamDesc; /* array with name and custom data */
378 int HelpStringContext;
380 PCHAR Entry; /* if its Hiword==0, it numeric; -1 is not present*/
382 TLBCustData * pCustData; /* linked list to cust data; */
383 struct tagTLBFuncDesc * next;
386 /* internal Variable data */
387 typedef struct tagTLBVarDesc
389 VARDESC vardesc; /* lots of info on the variable and its attributes. */
390 PCHAR Name; /* the name of this variable */
392 int HelpStringContext; /* fixme: where? */
395 TLBCustData * pCustData;/* linked list to cust data; */
396 struct tagTLBVarDesc * next;
399 /* data for refernced types in a coclass, or an inherited interface */
400 typedef struct tagTLBRefType
402 GUID guid; /* guid of the referenced type */
403 /* (important if its a imported type) */
407 TLBCustData * pCustData;/* linked list to custom data; */
408 TLBImpLib *pImpTLInfo;
409 struct tagTLBRefType * next;
412 /* internal TypeInfo data */
413 typedef struct tagITypeInfoImpl
415 ICOM_VFIELD(ITypeInfo2);
417 TYPEATTR TypeAttr ; /* _lots_ of type information. */
418 ITypeLibImpl * pTypeLib; /* back pointer to typelib */
419 int index; /* index in this typelib; */
420 /* type libs seem to store the doc strings in ascii
421 * so why should we do it in unicode?
425 unsigned long dwHelpContext;
426 unsigned long dwHelpStringContext;
429 TLBFuncDesc * funclist; /* linked list with function descriptions */
432 TLBVarDesc * varlist; /* linked list with variable descriptions */
434 /* Implemented Interfaces */
435 TLBRefType * impltypelist;
437 TLBCustData * pCustData; /* linked list to cust data; */
438 struct tagITypeInfoImpl * next;
441 static struct ICOM_VTABLE(ITypeInfo2) tinfvt;
443 static ITypeInfo2 * WINAPI ITypeInfo_Constructor();
445 typedef struct tagTLBContext
447 unsigned int oStart; /* start of TLB in file */
448 unsigned int pos; /* current pos */
449 unsigned int length; /* total length */
450 void *mapping; /* memory mapping */
452 ITypeLibImpl* pLibInfo;
458 static void dump_TLBFuncDesc(TLBFuncDesc * pfd)
462 TRACE("%s(%u)\n", pfd->Name, pfd->funcdesc.cParams);
466 static void dump_TLBVarDesc(TLBVarDesc * pvd)
470 TRACE("%s\n", pvd->Name);
474 static void dump_TLBRefType(TLBRefType * prt)
478 TRACE("%s\n", debugstr_guid(&(prt->guid)));
479 TRACE(" href:0x%08lx\n", prt->reference);
484 static void dump_Variant(VARIANT * pvar)
486 TRACE("%p %x\n", pvar, pvar?pvar->vt:0 );
489 if (pvar->vt & VT_BYREF)
490 return dump_Variant(pvar->u.pvarVal);
493 static void dump_DispParms(DISPPARAMS * pdp)
495 dump_Variant( pdp->rgvarg);
496 TRACE("args=%u named args=%u\n", pdp->cArgs, pdp->cNamedArgs);
499 static char * typekind_desc[] =
512 static void dump_TypeInfo(ITypeInfoImpl * pty)
514 TRACE("%p ref=%u\n", pty, pty->ref);
515 TRACE("attr:%s\n", debugstr_guid(&(pty->TypeAttr.guid)));
516 TRACE("kind:%s\n", typekind_desc[pty->TypeAttr.typekind]);
517 TRACE("fct:%u var:%u impl:%u\n",
518 pty->TypeAttr.cFuncs, pty->TypeAttr.cVars, pty->TypeAttr.cImplTypes);
519 TRACE("parent tlb:%p index in TLB:%u\n",pty->pTypeLib, pty->index);
520 TRACE("%s %s\n", pty->Name, pty->DocString);
521 dump_TLBFuncDesc(pty->funclist);
522 dump_TLBVarDesc(pty->varlist);
523 dump_TLBRefType(pty->impltypelist);
526 static TYPEDESC stndTypeDesc[VT_LPWSTR+1]=
528 /* VT_LPWSTR is largest type that */
529 /* may appear in type description*/
530 {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
531 {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
532 {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
533 {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
534 {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
535 {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
539 static void TLB_abort()
543 static void * TLB_Alloc(unsigned size)
546 if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){
548 ERR("cannot allocate memory\n");
553 /* candidate for a more global appearance... */
554 static BSTR TLB_DupAtoBstr(PCHAR Astr)
562 pdw =TLB_Alloc((len+3)*sizeof(OLECHAR));
563 pdw[0]=(len)*sizeof(OLECHAR);
564 bstr=(BSTR)&( pdw[1]);
565 lstrcpyAtoW( bstr, Astr);
566 TRACE("copying %s to (%p)\n", Astr, bstr);
570 static void TLB_Free(void * ptr)
572 HeapFree(GetProcessHeap(), 0, ptr);
575 DWORD TLB_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
577 TRACE("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n",
578 pcx->pos, count, pcx->oStart, pcx->length, where);
580 if (where != DO_NOT_SEEK)
582 where += pcx->oStart;
583 if (where > pcx->length)
586 ERR("seek beyond end (%ld/%d)\n", where, pcx->length );
591 if (pcx->pos + count > pcx->length) count = pcx->length - pcx->pos;
592 memcpy( buffer, (char *)pcx->mapping + pcx->pos, count );
597 static void TLB_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
599 TRACE("%s\n", debugstr_guid(pGuid));
601 if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){
602 memset(pGuid,0, sizeof(GUID));
605 TLB_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset );
608 PCHAR TLB_ReadName( TLBContext *pcx, int offset)
613 TLB_Read(&niName, sizeof(niName), pcx,
614 pcx->pTblDir->pNametab.offset+offset);
615 niName.namelen &= 0xFF; /* FIXME: correct ? */
616 name=TLB_Alloc((niName.namelen & 0xff) +1);
617 TLB_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK);
618 name[niName.namelen & 0xff]='\0';
619 TRACE("%s\n", debugstr_a(name));
622 PCHAR TLB_ReadString( TLBContext *pcx, int offset)
627 if(offset<0) return NULL;
628 TLB_Read(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
629 if(length <= 0) return 0;
630 string=TLB_Alloc(length +1);
631 TLB_Read(string, length, pcx, DO_NOT_SEEK);
633 TRACE("%s\n", debugstr_a(string));
637 * read a value and fill a VARIANT structure
639 static void TLB_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
645 if(offset <0) { /* data is packed in here */
646 pVar->vt = (offset & 0x7c000000 )>> 26;
647 V_UNION(pVar, iVal) = offset & 0xffff;
650 TLB_Read(&(pVar->vt), sizeof(VARTYPE), pcx,
651 pcx->pTblDir->pCustData.offset + offset );
652 TRACE("Vartype = %x\n", pVar->vt);
654 case VT_EMPTY: /* FIXME: is this right? */
655 case VT_NULL: /* FIXME: is this right? */
656 case VT_I2 : /* this should not happen */
667 case VT_VOID : /* FIXME: is this right? */
675 case VT_DECIMAL : /* FIXME: is this right? */
678 /* pointer types with known behaviour */
681 TLB_Read(&size, sizeof(INT), pcx, DO_NOT_SEEK );
683 FIXME("BSTR length = %d?\n", size);
685 ptr=TLB_Alloc(size);/* allocate temp buffer */
686 TLB_Read(ptr, size, pcx, DO_NOT_SEEK); /* read string (ANSI) */
687 V_UNION(pVar, bstrVal)=SysAllocStringLen(NULL,size);
688 /* FIXME: do we need a AtoW conversion here? */
689 V_UNION(pVar, bstrVal[size])=L'\0';
690 while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
695 /* FIXME: this will not work AT ALL when the variant contains a pointer */
702 case VT_USERDEFINED :
708 case VT_STREAMED_OBJECT :
709 case VT_STORED_OBJECT :
710 case VT_BLOB_OBJECT :
715 FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
719 if(size>0) /* (big|small) endian correct? */
720 TLB_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK );
724 * create a linked list with custom data
726 static int TLB_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
736 pNew=TLB_Alloc(sizeof(TLBCustData));
737 TLB_Read(&entry, sizeof(entry), pcx,
738 pcx->pTblDir->pCDGuids.offset+offset);
739 TLB_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
740 TLB_ReadValue(&(pNew->data), entry.DataOffset, pcx);
741 /* add new custom data at head of the list */
742 pNew->next=*ppCustData;
749 static void TLB_GetTdesc(TLBContext *pcx, INT type,TYPEDESC * pTd )
754 pTd->vt=type & VT_TYPEMASK;
756 *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
758 static void TLB_DoFuncs(TLBContext *pcx, int cFuncs, int cVars,
759 int offset, TLBFuncDesc ** pptfd)
762 * member information is stored in a data structure at offset
763 * indicated by the memoffset field of the typeinfo structure
764 * There are several distinctive parts.
765 * the first part starts with a field that holds the total length
766 * of this (first) part excluding this field. Then follow the records,
767 * for each member there is one record.
769 * First entry is always the length of the record (excluding this
771 * Rest of the record depends on the type of the member. If there is
772 * a field indicating the member type (function variable intereface etc)
773 * I have not found it yet. At this time we depend on the information
774 * in the type info and the usual order how things are stored.
776 * Second follows an array sized nrMEM*sizeof(INT) with a memeber id
779 * Third is a equal sized array with file offsets to the name entry
782 * Forth and last (?) part is an array with offsets to the records in the
783 * first part of this file segment.
786 int infolen, nameoffset, reclength, nrattributes;
788 TLBFuncRecord * pFuncRec=(TLBFuncRecord *) recbuf;
790 int recoffset=offset+sizeof(INT);
794 TLB_Read(&infolen,sizeof(INT), pcx, offset);
795 for(i=0;i<cFuncs;i++){
796 *pptfd=TLB_Alloc(sizeof(TLBFuncDesc));
797 /* name, eventually add to a hash table */
798 TLB_Read(&nameoffset, sizeof(INT), pcx,
799 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
800 (*pptfd)->Name=TLB_ReadName(pcx, nameoffset);
801 /* read the function information record */
802 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
804 TLB_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
805 /* do the attributes */
806 nrattributes=(reclength-pFuncRec->nrargs*3*sizeof(int)-0x18)
809 (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
811 (*pptfd)->HelpString = TLB_ReadString(pcx,
812 pFuncRec->OptAttr[1]) ;
814 if(pFuncRec->FKCCIC & 0x2000)
815 (*pptfd)->Entry = (char *) pFuncRec->OptAttr[2] ;
817 (*pptfd)->Entry = TLB_ReadString(pcx,
818 pFuncRec->OptAttr[2]);
820 (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;
821 if(nrattributes>6 && pFuncRec->FKCCIC & 0x80){
822 TLB_CustData(pcx, pFuncRec->OptAttr[6],
823 &(*pptfd)->pCustData);
828 /* fill the FuncDesc Structure */
829 TLB_Read(&(*pptfd)->funcdesc.memid, sizeof(INT), pcx,
830 offset + infolen + ( i + 1) * sizeof(INT));
831 (*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
832 (*pptfd)->funcdesc.invkind = ((pFuncRec->FKCCIC) >>3) & 0xF;
833 (*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >>8 & 0xF;
834 (*pptfd)->funcdesc.cParams = pFuncRec->nrargs ;
835 (*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ;
836 (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ;
837 (*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
838 TLB_GetTdesc(pcx, pFuncRec->DataType,
839 &(*pptfd)->funcdesc.elemdescFunc.tdesc) ;
841 /* do the parameters/arguments */
842 if(pFuncRec->nrargs){
843 TLBParameterInfo paraminfo;
844 (*pptfd)->funcdesc.lprgelemdescParam=
845 TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
846 (*pptfd)->pParamDesc=TLB_Alloc(pFuncRec->nrargs *
849 TLB_Read(¶minfo,sizeof(paraminfo), pcx, recoffset+reclength -
850 pFuncRec->nrargs * sizeof(TLBParameterInfo));
851 for(j=0;j<pFuncRec->nrargs;j++){
852 TLB_GetTdesc(pcx, paraminfo.DataType,
853 &(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc) ;
854 V_UNION(&((*pptfd)->funcdesc.lprgelemdescParam[j]),
855 paramdesc.wParamFlags) = paraminfo.Flags;
856 (*pptfd)->pParamDesc[j].Name=(void *)paraminfo.oName;
857 TLB_Read(¶minfo,sizeof(TLBParameterInfo), pcx,
860 /* second time around */
861 for(j=0;j<pFuncRec->nrargs;j++){
863 (*pptfd)->pParamDesc[j].Name=
864 TLB_ReadName(pcx, (int)(*pptfd)->pParamDesc[j].Name);
866 if((PARAMFLAG_FHASDEFAULT & V_UNION(&((*pptfd)->funcdesc.
867 lprgelemdescParam[j]),paramdesc.wParamFlags)) &&
868 ((pFuncRec->FKCCIC) & 0x1000)){
869 INT *pInt=(INT *)((char *)pFuncRec + reclength -
870 (pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
871 PARAMDESC * pParamDesc= &V_UNION(&((*pptfd)->funcdesc.
872 lprgelemdescParam[j]),paramdesc);
873 pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
874 pParamDesc->pparamdescex->cBytes= sizeof(PARAMDESCEX);
875 TLB_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
879 if(nrattributes>7+j && pFuncRec->FKCCIC & 0x80)
880 TLB_CustData(pcx, pFuncRec->OptAttr[7+j],
881 &(*pptfd)->pParamDesc[j].pCustData);
884 /* scode is not used: archaic win16 stuff FIXME: right? */
885 (*pptfd)->funcdesc.cScodes = 0 ;
886 (*pptfd)->funcdesc.lprgscode = NULL ;
887 pptfd=&((*pptfd)->next);
888 recoffset += reclength;
891 static void TLB_DoVars(TLBContext *pcx, int cFuncs, int cVars,
892 int offset, TLBVarDesc ** pptvd)
894 int infolen, nameoffset, reclength;
896 TLBVarRecord * pVarRec=(TLBVarRecord *) recbuf;
902 TLB_Read(&infolen,sizeof(INT), pcx, offset);
903 TLB_Read(&recoffset,sizeof(INT), pcx, offset + infolen +
904 ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
905 recoffset += offset+sizeof(INT);
906 for(i=0;i<cVars;i++){
907 *pptvd=TLB_Alloc(sizeof(TLBVarDesc));
908 /* name, eventually add to a hash table */
909 TLB_Read(&nameoffset, sizeof(INT), pcx,
910 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
911 (*pptvd)->Name=TLB_ReadName(pcx, nameoffset);
912 /* read the variable information record */
913 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
915 TLB_Read(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
917 if(reclength >(6*sizeof(INT)) )
918 (*pptvd)->HelpContext=pVarRec->HelpContext;
919 if(reclength >(7*sizeof(INT)) )
920 (*pptvd)->HelpString = TLB_ReadString(pcx, pVarRec->oHelpString) ;
921 if(reclength >(8*sizeof(INT)) )
922 if(reclength >(9*sizeof(INT)) )
923 (*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
924 /* fill the VarDesc Structure */
925 TLB_Read(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
926 offset + infolen + ( i + 1) * sizeof(INT));
927 (*pptvd)->vardesc.varkind = pVarRec->VarKind;
928 (*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
929 TLB_GetTdesc(pcx, pVarRec->DataType,
930 &(*pptvd)->vardesc.elemdescVar.tdesc) ;
931 /* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) fixme?? */
932 if(pVarRec->VarKind == VAR_CONST ){
933 V_UNION(&((*pptvd)->vardesc),lpvarValue)=TLB_Alloc(sizeof(VARIANT));
934 TLB_ReadValue(V_UNION(&((*pptvd)->vardesc),lpvarValue),
935 pVarRec->OffsValue, pcx);
937 V_UNION(&((*pptvd)->vardesc),oInst)=pVarRec->OffsValue;
938 pptvd=&((*pptvd)->next);
939 recoffset += reclength;
942 /* fill in data for a hreftype (offset). When the refernced type is contained
943 * in the typelib, its just an (file) offset in the type info base dir.
944 * If comes from import, its an offset+1 in the ImpInfo table
946 static void TLB_DoRefType(TLBContext *pcx,
947 int offset, TLBRefType ** pprtd)
953 if(!HREFTYPE_INTHISFILE( offset)) {
954 /* external typelib */
956 TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs);
957 TLB_Read(&impinfo, sizeof(impinfo), pcx,
958 pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
959 for(j=0;pImpLib;j++){ /* search the known offsets of all import libraries */
960 if(pImpLib->offset==impinfo.oImpFile) break;
961 pImpLib=pImpLib->next;
964 (*pprtd)->reference=offset;
965 (*pprtd)->pImpTLInfo = pImpLib;
966 TLB_ReadGuid(&(*pprtd)->guid, impinfo.oGuid, pcx);
968 ERR("Cannot find a reference\n");
969 (*pprtd)->reference=-1;
970 (*pprtd)->pImpTLInfo=(void *)-1;
973 /* in this typelib */
974 (*pprtd)->reference=offset;
975 (*pprtd)->pImpTLInfo=(void *)-2;
979 /* process Implemented Interfaces of a com class */
980 static void TLB_DoImplTypes(TLBContext *pcx, int count,
981 int offset, TLBRefType ** pprtd)
988 for(i=0;i<count;i++){
989 if(offset<0) break; /* paranoia */
990 *pprtd=TLB_Alloc(sizeof(TLBRefType));
991 TLB_Read(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
992 TLB_DoRefType(pcx, refrec.reftype, pprtd);
993 (*pprtd)->flags=refrec.flags;
994 (*pprtd)->ctCustData=
995 TLB_CustData(pcx, refrec.oCustData, &(*pprtd)->pCustData);
997 pprtd=&((*pprtd)->next);
1001 * process a typeinfo record
1003 ITypeInfoImpl * TLB_DoTypeInfo(
1006 ITypeLibImpl * pLibInfo)
1008 TLBTypeInfoBase tiBase;
1009 ITypeInfoImpl *ptiRet;
1011 TRACE("count=%u\n", count);
1013 ptiRet = (ITypeInfoImpl*) ITypeInfo_Constructor();
1014 TLB_Read(&tiBase, sizeof(tiBase) ,pcx ,
1015 pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
1016 /* this where we are coming from */
1017 ptiRet->pTypeLib = pLibInfo;
1018 ptiRet->index=count;
1019 /* fill in the typeattr fields */
1020 TLB_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx);
1021 ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid; /* FIXME: correct? */
1022 ptiRet->TypeAttr.memidConstructor=MEMBERID_NIL ;/* FIXME */
1023 ptiRet->TypeAttr.memidDestructor=MEMBERID_NIL ; /* FIXME */
1024 ptiRet->TypeAttr.lpstrSchema=NULL; /* reserved */
1025 ptiRet->TypeAttr.cbSizeInstance=tiBase.size;
1026 ptiRet->TypeAttr.typekind=tiBase.typekind & 0xF;
1027 ptiRet->TypeAttr.cFuncs=LOWORD(tiBase.cElement);
1028 ptiRet->TypeAttr.cVars=HIWORD(tiBase.cElement);
1029 ptiRet->TypeAttr.cbAlignment=(tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */
1030 ptiRet->TypeAttr.wTypeFlags=tiBase.flags;
1031 ptiRet->TypeAttr.wMajorVerNum=LOWORD(tiBase.version);
1032 ptiRet->TypeAttr.wMinorVerNum=HIWORD(tiBase.version);
1033 ptiRet->TypeAttr.cImplTypes=tiBase.cImplTypes;
1034 ptiRet->TypeAttr.cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
1035 if(ptiRet->TypeAttr.typekind == TKIND_ALIAS)
1036 TLB_GetTdesc(pcx, tiBase.datatype1,
1037 &ptiRet->TypeAttr.tdescAlias) ;
1040 /* IDLDESC idldescType; *//* never saw this one != zero */
1042 /* name, eventually add to a hash table */
1043 ptiRet->Name=TLB_ReadName(pcx, tiBase.NameOffset);
1044 TRACE("reading %s\n", ptiRet->Name);
1046 ptiRet->DocString=TLB_ReadString(pcx, tiBase.docstringoffs);
1047 ptiRet->dwHelpStringContext=tiBase.helpstringcontext;
1048 ptiRet->dwHelpContext=tiBase.helpcontext;
1049 /* note: InfoType's Help file and HelpStringDll come from the containing
1050 * library. Further HelpString and Docstring appear to be the same thing :(
1053 if(ptiRet->TypeAttr.cFuncs >0 )
1054 TLB_DoFuncs(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
1055 tiBase.memoffset, & ptiRet->funclist);
1057 if(ptiRet->TypeAttr.cVars >0 )
1058 TLB_DoVars(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
1059 tiBase.memoffset, & ptiRet->varlist);
1060 if(ptiRet->TypeAttr.cImplTypes >0 ){
1061 if(ptiRet->TypeAttr.typekind == TKIND_COCLASS)
1062 TLB_DoImplTypes(pcx, ptiRet->TypeAttr.cImplTypes ,
1063 tiBase.datatype1, & ptiRet->impltypelist);
1064 else if(ptiRet->TypeAttr.typekind != TKIND_DISPATCH){
1065 ptiRet->impltypelist=TLB_Alloc(sizeof(TLBRefType));
1066 TLB_DoRefType(pcx, tiBase.datatype1, & ptiRet->impltypelist);
1070 TLB_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData);
1072 TRACE("%s guid: %s kind:%s\n",
1074 debugstr_guid(&ptiRet->TypeAttr.guid),
1075 typekind_desc[ptiRet->TypeAttr.typekind]);
1080 /****************************************************************************
1083 * find the type of the typelib file and map the typelib resource into
1086 #define MSFT_SIGNATURE 0x5446534D /* "MSFT" */
1087 int TLB_ReadTypeLib(LPSTR pszFileName, ITypeLib2 **ppTypeLib)
1090 DWORD dwSignature = 0;
1093 TRACE("%s\n", pszFileName);
1097 /* check the signature of the file */
1098 hFile = CreateFileA( pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, -1 );
1099 if (INVALID_HANDLE_VALUE != hFile)
1101 HANDLE hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
1104 LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
1107 /* first try to load as *.tlb */
1108 dwSignature = *((DWORD*) pBase);
1109 if ( dwSignature == MSFT_SIGNATURE)
1111 *ppTypeLib = ITypeLib2_Constructor(pBase);
1113 UnmapViewOfFile(pBase);
1115 CloseHandle(hMapping);
1120 if( (WORD)dwSignature == IMAGE_DOS_SIGNATURE )
1122 /* find the typelibrary resource*/
1123 HINSTANCE hinstDLL = LoadLibraryExA(pszFileName, 0, DONT_RESOLVE_DLL_REFERENCES|
1124 LOAD_LIBRARY_AS_DATAFILE|LOAD_WITH_ALTERED_SEARCH_PATH);
1127 HRSRC hrsrc = FindResourceA(hinstDLL, MAKEINTRESOURCEA(1), "TYPELIB");
1130 HGLOBAL hGlobal = LoadResource(hinstDLL, hrsrc);
1133 LPVOID pBase = LockResource(hGlobal);
1136 /* try to load as incore resource */
1137 dwSignature = *((DWORD*) pBase);
1138 if ( dwSignature == MSFT_SIGNATURE)
1139 *ppTypeLib = ITypeLib2_Constructor(pBase);
1141 FIXME("Header type magic 0x%08lx not supported.\n",dwSignature);
1143 FreeResource( hGlobal );
1146 FreeLibrary(hinstDLL);
1153 ERR("Loading of typelib %s failed with error 0x%08lx\n", pszFileName, GetLastError());
1158 /*================== ITypeLib(2) Methods ===================================*/
1160 /****************************************************************************
1161 * ITypeLib2_Constructor
1163 * loading a typelib from a in-memory image
1165 static ITypeLib2* ITypeLib2_Constructor(LPVOID pLib)
1169 TLB2Header tlbHeader;
1170 TLBSegDir tlbSegDir;
1171 ITypeLibImpl * pTypeLibImpl;
1173 TRACE("%p\n", pLib);
1175 pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
1176 if (!pTypeLibImpl) return NULL;
1178 ICOM_VTBL(pTypeLibImpl) = &tlbvt;
1179 pTypeLibImpl->ref = 1;
1181 /* get pointer to beginning of typelib data */
1185 cx.pLibInfo = pTypeLibImpl;
1188 TLB_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
1190 TRACE("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2 );
1191 if (memcmp(&tlbHeader.magic1,TLBMAGIC2,4)) {
1192 FIXME("Header type magic 0x%08x not supported.\n",tlbHeader.magic1);
1195 /* there is a small number of information here until the next important
1197 * the segment directory . Try to calculate the amount of data */
1198 lPSegDir = sizeof(tlbHeader) + (tlbHeader.nrtypeinfos)*4 + ((tlbHeader.varflags & HELPDLLFLAG)? 4 :0);
1200 /* now read the segment directory */
1201 TRACE("read segment directory (at %ld)\n",lPSegDir);
1202 TLB_Read((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
1203 cx.pTblDir = &tlbSegDir;
1205 /* just check two entries */
1206 if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F || tlbSegDir.pImpInfo.res0c != 0x0F)
1208 ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir);
1209 HeapFree(GetProcessHeap(),0,pTypeLibImpl);
1213 /* now fill our internal data */
1214 /* TLIBATTR fields */
1215 TLB_ReadGuid(&pTypeLibImpl->LibAttr.guid, tlbHeader.posguid, &cx);
1216 pTypeLibImpl->LibAttr.lcid = tlbHeader.lcid;
1217 pTypeLibImpl->LibAttr.syskind = tlbHeader.varflags & 0x0f; /* check the mask */
1218 pTypeLibImpl->LibAttr.wMajorVerNum = LOWORD(tlbHeader.version);
1219 pTypeLibImpl->LibAttr.wMinorVerNum = HIWORD(tlbHeader.version);
1220 pTypeLibImpl->LibAttr.wLibFlags = (WORD) tlbHeader.flags & 0xffff;/* check mask */
1222 /* name, eventually add to a hash table */
1223 pTypeLibImpl->Name = TLB_ReadName(&cx, tlbHeader.NameOffset);
1226 pTypeLibImpl->DocString = TLB_ReadString(&cx, tlbHeader.helpstring);
1227 pTypeLibImpl->HelpFile = TLB_ReadString(&cx, tlbHeader.helpfile);
1229 if( tlbHeader.varflags & HELPDLLFLAG)
1232 TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
1233 pTypeLibImpl->HelpStringDll = TLB_ReadString(&cx, offset);
1236 pTypeLibImpl->dwHelpContext = tlbHeader.helpstringcontext;
1239 if(tlbHeader.CustomDataOffset >= 0)
1241 pTypeLibImpl->ctCustData = TLB_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->pCustData);
1244 /* fill in typedescriptions */
1245 if(tlbSegDir.pTypdescTab.length > 0)
1247 int i, j, cTD = tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
1249 pTypeLibImpl->pTypeDesc = TLB_Alloc( cTD * sizeof(TYPEDESC));
1250 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
1253 /* FIXME: add several sanity checks here */
1254 pTypeLibImpl->pTypeDesc[i].vt = td[0] & VT_TYPEMASK;
1255 if(td[0] == VT_PTR || td[0] == VT_SAFEARRAY)
1257 /* FIXME: check safearray */
1259 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lptdesc)= & stndTypeDesc[td[2]];
1261 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lptdesc)= & pTypeLibImpl->pTypeDesc[td[3]/8];
1263 else if(td[0] == VT_CARRAY)
1265 /* array descr table here */
1266 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = (void *)((int) td[2]); /* temp store offset in*/
1268 else if(td[0] == VT_USERDEFINED)
1270 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),hreftype) = MAKELONG(td[2],td[3]);
1272 if(++i<cTD) TLB_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
1275 /* second time around to fill the array subscript info */
1278 if(pTypeLibImpl->pTypeDesc[i].vt != VT_CARRAY) continue;
1279 if(tlbSegDir.pArrayDescriptions.offset>0)
1281 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (int) V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc));
1282 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
1285 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->tdescElem.vt = td[0] & VT_TYPEMASK;
1287 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->tdescElem = stndTypeDesc[td[0]/8];
1289 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->cDims = td[2];
1291 for(j = 0; j<td[2]; j++)
1293 TLB_Read(& V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->rgbounds[j].cElements,
1294 sizeof(INT), &cx, DO_NOT_SEEK);
1295 TLB_Read(& V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->rgbounds[j].lLbound,
1296 sizeof(INT), &cx, DO_NOT_SEEK);
1301 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = NULL;
1302 ERR("didn't find array description data\n");
1307 /* imported type libs */
1308 if(tlbSegDir.pImpFiles.offset>0)
1310 TLBImpLib **ppImpLib = &(pTypeLibImpl->pImpLibs);
1311 int oGuid, offset = tlbSegDir.pImpFiles.offset;
1314 while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length)
1316 *ppImpLib = TLB_Alloc(sizeof(TLBImpLib));
1317 (*ppImpLib)->offset = offset - tlbSegDir.pImpFiles.offset;
1318 TLB_Read(&oGuid, sizeof(INT), &cx, offset);
1319 TLB_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
1321 /* we are skipping some unknown info here */
1322 TLB_Read(& size,sizeof(UINT16), &cx, offset+3*(sizeof(INT)));
1324 (*ppImpLib)->name = TLB_Alloc(size+1);
1325 TLB_Read((*ppImpLib)->name, size, &cx, DO_NOT_SEEK);
1326 offset = (offset + 3 * (sizeof(INT)) + sizeof(UINT16) + size + 3) & 0xfffffffc;
1328 ppImpLib = &(*ppImpLib)->next;
1333 if(tlbHeader.nrtypeinfos >= 0 )
1335 /*pTypeLibImpl->TypeInfoCount=tlbHeader.nrtypeinfos; */
1336 ITypeInfoImpl **ppTI = &(pTypeLibImpl->pTypeInfo);
1338 for(i = 0; i<(int)tlbHeader.nrtypeinfos; i++)
1340 *ppTI = TLB_DoTypeInfo(&cx, i, pTypeLibImpl);
1341 ppTI = &((*ppTI)->next);
1342 (pTypeLibImpl->TypeInfoCount)++;
1346 TRACE("(%p)\n", pTypeLibImpl);
1347 return (ITypeLib2*) pTypeLibImpl;
1350 /* ITypeLib::QueryInterface
1352 static HRESULT WINAPI ITypeLib2_fnQueryInterface(
1357 ICOM_THIS( ITypeLibImpl, iface);
1359 TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
1362 if(IsEqualIID(riid, &IID_IUnknown) ||
1363 IsEqualIID(riid,&IID_ITypeLib)||
1364 IsEqualIID(riid,&IID_ITypeLib2))
1371 ITypeLib2_AddRef(iface);
1372 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1375 TRACE("-- Interface: E_NOINTERFACE\n");
1376 return E_NOINTERFACE;
1381 static ULONG WINAPI ITypeLib2_fnAddRef( ITypeLib2 *iface)
1383 ICOM_THIS( ITypeLibImpl, iface);
1385 TRACE("(%p)->ref is %u\n",This, This->ref);
1387 return ++(This->ref);
1390 /* ITypeLib::Release
1392 static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
1394 ICOM_THIS( ITypeLibImpl, iface);
1396 TRACE("(%p)->(%u)\n",This, This->ref);
1400 /* fixme destroy child objects */
1402 TRACE(" destroying ITypeLib(%p)\n",This);
1404 HeapFree(GetProcessHeap(),0,This);
1410 /* ITypeLib::GetTypeInfoCount
1412 * Returns the number of type descriptions in the type library
1414 static UINT WINAPI ITypeLib2_fnGetTypeInfoCount( ITypeLib2 *iface)
1416 ICOM_THIS( ITypeLibImpl, iface);
1417 TRACE("(%p)->count is %d\n",This, This->TypeInfoCount);
1418 return This->TypeInfoCount;
1421 /* ITypeLib::GetTypeInfo
1423 * retrieves the specified type description in the library.
1425 static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(
1428 ITypeInfo **ppTInfo)
1431 ICOM_THIS( ITypeLibImpl, iface);
1432 ITypeInfoImpl *pTLBTInfo = This->pTypeInfo;
1434 TRACE("(%p)->(index=%d) \n",This, index);
1436 if (!ppTInfo) return E_INVALIDARG;
1438 /* search element n in list */
1439 for(i=0; i < index; i++)
1441 pTLBTInfo = pTLBTInfo->next;
1444 TRACE("-- element not found\n");
1445 return TYPE_E_ELEMENTNOTFOUND;
1449 *ppTInfo = (ITypeInfo *) pTLBTInfo;
1450 ITypeInfo_AddRef(*ppTInfo);
1451 TRACE("-- found (%p)\n",*ppTInfo);
1455 /* ITypeLibs::GetTypeInfoType
1457 * Retrieves the type of a type description.
1459 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType(
1464 ICOM_THIS( ITypeLibImpl, iface);
1466 ITypeInfoImpl *pTInfo = This->pTypeInfo;
1468 TRACE("(%p) index %d \n",This, index);
1470 if(!pTKind) return E_INVALIDARG;
1472 /* search element n in list */
1473 for(i=0; i < index; i++)
1477 TRACE("-- element not found\n");
1478 return TYPE_E_ELEMENTNOTFOUND;
1480 pTInfo = pTInfo->next;
1483 *pTKind = pTInfo->TypeAttr.typekind;
1484 TRACE("-- found Type (%d)\n", *pTKind);
1488 /* ITypeLib::GetTypeInfoOfGuid
1490 * Retrieves the type description that corresponds to the specified GUID.
1493 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(
1496 ITypeInfo **ppTInfo)
1498 ICOM_THIS( ITypeLibImpl, iface);
1499 ITypeInfoImpl *ppTLBTInfo = This->pTypeInfo; /* head of list */
1501 TRACE("(%p)\n\tguid:\t%s)\n",This,debugstr_guid(guid));
1503 /* serach linked list for guid */
1504 while( !IsEqualIID(guid,&ppTLBTInfo->TypeAttr.guid) )
1506 ppTLBTInfo = ppTLBTInfo->next;
1509 /* end of list reached */
1510 TRACE("-- element not found\n");
1511 return TYPE_E_ELEMENTNOTFOUND;
1515 TRACE("-- found (%p, %s)\n", ppTLBTInfo, ppTLBTInfo->Name);
1517 *ppTInfo = (ITypeInfo*)ppTLBTInfo;
1518 ITypeInfo_AddRef(*ppTInfo);
1522 /* ITypeLib::GetLibAttr
1524 * Retrieves the structure that contains the library's attributes.
1527 static HRESULT WINAPI ITypeLib2_fnGetLibAttr(
1529 LPTLIBATTR *ppTLibAttr)
1531 ICOM_THIS( ITypeLibImpl, iface);
1532 TRACE("(%p)\n",This);
1533 /* FIXME: must do a copy here */
1534 *ppTLibAttr=&This->LibAttr;
1538 /* ITypeLib::GetTypeComp
1540 * Enables a client compiler to bind to a library's types, variables,
1541 * constants, and global functions.
1544 static HRESULT WINAPI ITypeLib2_fnGetTypeComp(
1546 ITypeComp **ppTComp)
1548 ICOM_THIS( ITypeLibImpl, iface);
1549 FIXME("(%p): stub!\n",This);
1553 /* ITypeLib::GetDocumentation
1555 * Retrieves the library's documentation string, the complete Help file name
1556 * and path, and the context identifier for the library Help topic in the Help
1560 static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
1564 BSTR *pBstrDocString,
1565 DWORD *pdwHelpContext,
1566 BSTR *pBstrHelpFile)
1568 ICOM_THIS( ITypeLibImpl, iface);
1571 TRACE("(%p) index %d Name(%p) DocString(%p)"
1572 " HelpContext(%p) HelpFile(%p)\n",
1573 This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1574 if(index<0){ /* documentation for the typelib */
1576 *pBstrName=TLB_DupAtoBstr(This->Name);
1578 *pBstrDocString=TLB_DupAtoBstr(This->DocString);
1580 *pdwHelpContext=This->dwHelpContext;
1582 *pBstrHelpFile=TLB_DupAtoBstr(This->HelpFile);
1583 }else {/* for a typeinfo */
1584 result=ITypeLib2_fnGetTypeInfo(iface, index, &pTInfo);
1585 if(SUCCEEDED(result)){
1586 result=ITypeInfo_GetDocumentation(pTInfo, MEMBERID_NIL, pBstrName,
1587 pBstrDocString, pdwHelpContext, pBstrHelpFile);
1588 ITypeInfo_Release(pTInfo);
1590 if(!SUCCEEDED(result))
1598 * Indicates whether a passed-in string contains the name of a type or member
1599 * described in the library.
1602 static HRESULT WINAPI ITypeLib2_fnIsName(
1608 ICOM_THIS( ITypeLibImpl, iface);
1609 ITypeInfoImpl *pTInfo;
1610 TLBFuncDesc *pFInfo;
1613 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1615 TRACE("(%p)->(%s,%08lx,%p)\n", This, debugstr_w(szNameBuf), lHashVal,
1619 if(!strcmp(astr,This->Name)) goto ITypeLib2_fnIsName_exit;
1620 for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){
1621 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib2_fnIsName_exit;
1622 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1623 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib2_fnIsName_exit;
1624 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1625 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1626 goto ITypeLib2_fnIsName_exit;
1628 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next)
1629 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib2_fnIsName_exit;
1634 ITypeLib2_fnIsName_exit:
1635 TRACE("(%p)slow! search for %s: %s found!\n", This,
1636 debugstr_a(astr), *pfName?"NOT":"");
1638 HeapFree( GetProcessHeap(), 0, astr );
1642 /* ITypeLib::FindName
1644 * Finds occurrences of a type description in a type library. This may be used
1645 * to quickly verify that a name exists in a type library.
1648 static HRESULT WINAPI ITypeLib2_fnFindName(
1652 ITypeInfo **ppTInfo,
1656 ICOM_THIS( ITypeLibImpl, iface);
1657 ITypeInfoImpl *pTInfo;
1658 TLBFuncDesc *pFInfo;
1661 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1662 for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){
1663 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib2_fnFindName_exit;
1664 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1665 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib2_fnFindName_exit;
1666 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1667 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1668 goto ITypeLib2_fnFindName_exit;
1670 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
1671 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib2_fnFindName_exit;
1673 ITypeLib2_fnFindName_exit:
1674 ITypeInfo_AddRef((ITypeInfo*)pTInfo);
1675 ppTInfo[j]=(LPTYPEINFO)pTInfo;
1678 TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
1679 This, *pcFound, debugstr_a(astr), j);
1683 HeapFree( GetProcessHeap(), 0, astr );
1687 /* ITypeLib::ReleaseTLibAttr
1689 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
1692 static VOID WINAPI ITypeLib2_fnReleaseTLibAttr(
1694 TLIBATTR *pTLibAttr)
1696 ICOM_THIS( ITypeLibImpl, iface);
1697 TRACE("freeing (%p)\n",This);
1701 /* ITypeLib2::GetCustData
1703 * gets the custom data
1705 static HRESULT WINAPI ITypeLib2_fnGetCustData(
1710 ICOM_THIS( ITypeLibImpl, iface);
1711 TLBCustData *pCData;
1713 for(pCData=This->pCustData; pCData; pCData = pCData->next)
1715 if( IsEqualIID(guid, &pCData->guid)) break;
1718 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
1722 VariantInit( pVarVal);
1723 VariantCopy( pVarVal, &pCData->data);
1726 return E_INVALIDARG; /* FIXME: correct? */
1729 /* ITypeLib2::GetLibStatistics
1731 * Returns statistics about a type library that are required for efficient
1732 * sizing of hash tables.
1735 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(
1737 ULONG *pcUniqueNames,
1738 ULONG *pcchUniqueNames)
1740 ICOM_THIS( ITypeLibImpl, iface);
1742 FIXME("(%p): stub!\n", This);
1744 if(pcUniqueNames) *pcUniqueNames=1;
1745 if(pcchUniqueNames) *pcchUniqueNames=1;
1749 /* ITypeLib2::GetDocumentation2
1751 * Retrieves the library's documentation string, the complete Help file name
1752 * and path, the localization context to use, and the context ID for the
1753 * library Help topic in the Help file.
1756 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
1760 BSTR *pbstrHelpString,
1761 DWORD *pdwHelpStringContext,
1762 BSTR *pbstrHelpStringDll)
1764 ICOM_THIS( ITypeLibImpl, iface);
1768 FIXME("(%p) index %d lcid %ld half implemented stub!\n", This, index, lcid);
1770 /* the help string should be obtained from the helpstringdll,
1771 * using the _DLLGetDocumentation function, based on the supplied
1772 * lcid. Nice to do sometime...
1776 /* documentation for the typelib */
1778 *pbstrHelpString=TLB_DupAtoBstr(This->DocString);
1779 if(pdwHelpStringContext)
1780 *pdwHelpStringContext=This->dwHelpContext;
1781 if(pbstrHelpStringDll)
1782 *pbstrHelpStringDll=TLB_DupAtoBstr(This->HelpStringDll);
1786 /* for a typeinfo */
1787 result=ITypeLib2_GetTypeInfo(iface, index, &pTInfo);
1788 if(SUCCEEDED(result))
1790 ITypeInfo2 * pTInfo2;
1791 result = ITypeInfo_QueryInterface(pTInfo, &IID_ITypeInfo2, (LPVOID*) &pTInfo2);
1792 if(SUCCEEDED(result))
1794 result = ITypeInfo2_GetDocumentation2(pTInfo2, MEMBERID_NIL, lcid,
1795 pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
1796 ITypeInfo2_Release(pTInfo);
1798 ITypeInfo_Release(pTInfo);
1800 if(!SUCCEEDED(result))
1806 /* ITypeLib2::GetAllCustData
1808 * Gets all custom data items for the library.
1811 static HRESULT WINAPI ITypeLib2_fnGetAllCustData(
1813 CUSTDATA *pCustData)
1815 ICOM_THIS( ITypeLibImpl, iface);
1816 TLBCustData *pCData;
1818 TRACE("(%p) returning %d items\n", This, This->ctCustData);
1819 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
1820 if(pCustData->prgCustData ){
1821 pCustData->cCustData=This->ctCustData;
1822 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
1823 pCustData->prgCustData[i].guid=pCData->guid;
1824 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
1827 ERR(" OUT OF MEMORY! \n");
1828 return E_OUTOFMEMORY;
1833 static ICOM_VTABLE(ITypeLib2) tlbvt = {
1834 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1835 ITypeLib2_fnQueryInterface,
1837 ITypeLib2_fnRelease,
1838 ITypeLib2_fnGetTypeInfoCount,
1839 ITypeLib2_fnGetTypeInfo,
1840 ITypeLib2_fnGetTypeInfoType,
1841 ITypeLib2_fnGetTypeInfoOfGuid,
1842 ITypeLib2_fnGetLibAttr,
1843 ITypeLib2_fnGetTypeComp,
1844 ITypeLib2_fnGetDocumentation,
1846 ITypeLib2_fnFindName,
1847 ITypeLib2_fnReleaseTLibAttr,
1849 ITypeLib2_fnGetCustData,
1850 ITypeLib2_fnGetLibStatistics,
1851 ITypeLib2_fnGetDocumentation2,
1852 ITypeLib2_fnGetAllCustData
1855 /*================== ITypeInfo(2) Methods ===================================*/
1856 static ITypeInfo2 * WINAPI ITypeInfo_Constructor(void)
1858 ITypeInfoImpl * pTypeInfoImpl;
1860 pTypeInfoImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeInfoImpl));
1863 ICOM_VTBL(pTypeInfoImpl) = &tinfvt;
1864 pTypeInfoImpl->ref=1;
1866 TRACE("(%p)\n", pTypeInfoImpl);
1867 return (ITypeInfo2*) pTypeInfoImpl;
1870 /* ITypeInfo::QueryInterface
1872 static HRESULT WINAPI ITypeInfo_fnQueryInterface(
1877 ICOM_THIS( ITypeLibImpl, iface);
1879 TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
1882 if(IsEqualIID(riid, &IID_IUnknown) ||
1883 IsEqualIID(riid,&IID_ITypeInfo)||
1884 IsEqualIID(riid,&IID_ITypeInfo2))
1888 ITypeInfo_AddRef(iface);
1889 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1892 TRACE("-- Interface: E_NOINTERFACE\n");
1893 return E_NOINTERFACE;
1896 /* ITypeInfo::AddRef
1898 static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface)
1900 ICOM_THIS( ITypeInfoImpl, iface);
1901 TRACE("(%p)->ref is %u\n",This, This->ref);
1902 ITypeLib2_AddRef((ITypeLib*)This->pTypeLib);
1903 return ++(This->ref);
1906 /* ITypeInfo::Release
1908 static ULONG WINAPI ITypeInfo_fnRelease( ITypeInfo2 *iface)
1910 ICOM_THIS( ITypeInfoImpl, iface);
1911 FIXME("(%p)->ref is %u: stub\n",This, This->ref);
1912 TRACE("(%p)->(%u)\n",This, This->ref);
1914 ITypeLib2_Release((ITypeLib*)This->pTypeLib);
1918 /* fixme destroy child objects */
1920 TRACE(" destroying ITypeInfo(%p)\n",This);
1922 HeapFree(GetProcessHeap(),0,This);
1928 /* ITypeInfo::GetTypeAttr
1930 * Retrieves a TYPEATTR structure that contains the attributes of the type
1934 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface,
1935 LPTYPEATTR *ppTypeAttr)
1937 ICOM_THIS( ITypeInfoImpl, iface);
1938 TRACE("(%p)\n",This);
1939 /* FIXME: must do a copy here */
1940 *ppTypeAttr=&This->TypeAttr;
1944 /* ITypeInfo::GetTypeComp
1946 * Retrieves the ITypeComp interface for the type description, which enables a
1947 * client compiler to bind to the type description's members.
1950 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( ITypeInfo2 *iface,
1951 ITypeComp * *ppTComp)
1953 ICOM_THIS( ITypeInfoImpl, iface);
1954 FIXME("(%p) stub!\n", This);
1958 /* ITypeInfo::GetFuncDesc
1960 * Retrieves the FUNCDESC structure that contains information about a
1961 * specified function.
1964 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( ITypeInfo2 *iface, UINT index,
1965 LPFUNCDESC *ppFuncDesc)
1967 ICOM_THIS( ITypeInfoImpl, iface);
1969 TLBFuncDesc * pFDesc;
1970 TRACE("(%p) index %d\n", This, index);
1971 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
1974 /* FIXME: must do a copy here */
1975 *ppFuncDesc=&pFDesc->funcdesc;
1978 return E_INVALIDARG;
1981 /* ITypeInfo::GetVarDesc
1983 * Retrieves a VARDESC structure that describes the specified variable.
1986 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( ITypeInfo2 *iface, UINT index,
1987 LPVARDESC *ppVarDesc)
1989 ICOM_THIS( ITypeInfoImpl, iface);
1991 TLBVarDesc * pVDesc;
1992 TRACE("(%p) index %d\n", This, index);
1993 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next)
1996 /* FIXME: must do a copy here */
1997 *ppVarDesc=&pVDesc->vardesc;
2000 return E_INVALIDARG;
2003 /* ITypeInfo_GetNames
2005 * Retrieves the variable with the specified member ID (or the name of the
2006 * property or method and its parameters) that correspond to the specified
2009 static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
2010 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
2012 ICOM_THIS( ITypeInfoImpl, iface);
2013 TLBFuncDesc * pFDesc;
2014 TLBVarDesc * pVDesc;
2016 TRACE("(%p) memid=0x%08lx Maxname=%d\n", This, memid, cMaxNames);
2017 for(pFDesc=This->funclist; pFDesc->funcdesc.memid != memid && pFDesc; pFDesc=pFDesc->next);
2020 /* function found, now return function and parameter names */
2021 for(i=0; i<cMaxNames && i <= pFDesc->funcdesc.cParams; i++)
2024 *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
2026 rgBstrNames[i]=TLB_DupAtoBstr(pFDesc->pParamDesc[i-1].Name);
2032 for(pVDesc=This->varlist; pVDesc->vardesc.memid != memid && pVDesc; pVDesc=pVDesc->next);
2035 *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
2040 if(This->TypeAttr.typekind==TKIND_INTERFACE && This->TypeAttr.cImplTypes )
2042 /* recursive search */
2045 result=ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->reference, &pTInfo);
2046 if(SUCCEEDED(result))
2048 result=ITypeInfo_GetNames(pTInfo, memid, rgBstrNames, cMaxNames, pcNames);
2049 ITypeInfo_Release(pTInfo);
2052 WARN("Could not search inherited interface!\n");
2056 WARN("no names found\n");
2059 return TYPE_E_ELEMENTNOTFOUND;
2066 /* ITypeInfo::GetRefTypeOfImplType
2068 * If a type description describes a COM class, it retrieves the type
2069 * description of the implemented interface types. For an interface,
2070 * GetRefTypeOfImplType returns the type information for inherited interfaces,
2074 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType(
2079 ICOM_THIS( ITypeInfoImpl, iface);
2081 TLBRefType *pIref = This->impltypelist;
2083 TRACE("(%p) index %d\n", This, index);
2084 dump_TypeInfo(This);
2088 /* get the retated interface for this dispinterface */
2089 if( This->TypeAttr.typekind != TKIND_DISPATCH) return E_INVALIDARG;
2090 FIXME("TKIND_INTERFACE expected\n");
2091 return TYPE_E_ELEMENTNOTFOUND;
2094 /* get element n from linked list */
2095 for(i=0; i<index; i++)
2097 if (!pIref) return TYPE_E_ELEMENTNOTFOUND;
2098 pIref = pIref->next;
2101 *pRefType = pIref->reference;
2102 TRACE("-- 0x%08lx %s\n",pIref->reference, debugstr_guid(&pIref->guid) );
2106 /* ITypeInfo::GetImplTypeFlags
2108 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
2109 * or base interface in a type description.
2111 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( ITypeInfo2 *iface,
2112 UINT index, INT *pImplTypeFlags)
2114 ICOM_THIS( ITypeInfoImpl, iface);
2117 TRACE("(%p) index %d\n", This, index);
2118 for(i=0, pIref=This->impltypelist; i<index && pIref; i++, pIref=pIref->next)
2120 if(i==index && pIref){
2121 *pImplTypeFlags=pIref->flags;
2125 return TYPE_E_ELEMENTNOTFOUND;
2129 * Maps between member names and member IDs, and parameter names and
2132 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface,
2133 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
2135 ICOM_THIS( ITypeInfoImpl, iface);
2136 TLBFuncDesc * pFDesc;
2137 TLBVarDesc * pVDesc;
2139 PCHAR aszName= HEAP_strdupWtoA( GetProcessHeap(), 0, *rgszNames);
2140 TRACE("(%p) Name %s cNames %d\n", This, debugstr_a(aszName),
2142 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) {
2144 if( !strcmp(aszName, pFDesc->Name)) {
2145 if(cNames) *pMemId=pFDesc->funcdesc.memid;
2146 for(i=1; i < cNames; i++){
2147 PCHAR aszPar= HEAP_strdupWtoA( GetProcessHeap(), 0,
2149 for(j=0; j<pFDesc->funcdesc.cParams; j++)
2150 if(strcmp(aszPar,pFDesc->pParamDesc[j].Name))
2152 if( j<pFDesc->funcdesc.cParams)
2155 ret=DISP_E_UNKNOWNNAME;
2156 HeapFree( GetProcessHeap(), 0, aszPar);
2158 HeapFree (GetProcessHeap(), 0, aszName);
2162 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
2163 if( !strcmp(aszName, pVDesc->Name)) {
2164 if(cNames) *pMemId=pVDesc->vardesc.memid;
2165 HeapFree (GetProcessHeap(), 0, aszName);
2169 /* not found, see if this is and interface with an inheritance */
2170 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
2171 This->TypeAttr.cImplTypes ){
2172 /* recursive search */
2174 ret=ITypeInfo_GetRefTypeInfo(iface,
2175 This->impltypelist->reference, &pTInfo);
2177 ret=ITypeInfo_GetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
2178 ITypeInfo_Release(pTInfo);
2181 WARN("Could not search inherited interface!\n");
2183 WARN("no names found\n");
2184 return DISP_E_UNKNOWNNAME;
2187 /* ITypeInfo::Invoke
2189 * Invokes a method, or accesses a property of an object, that implements the
2190 * interface described by the type description.
2192 static HRESULT WINAPI ITypeInfo_fnInvoke(
2197 DISPPARAMS *pDispParams,
2198 VARIANT *pVarResult,
2199 EXCEPINFO *pExcepInfo,
2202 ICOM_THIS( ITypeInfoImpl, iface);
2203 FIXME("(%p)(%p,id=0x%08lx,0x%08x,%p,%p,%p,%p) stub!\n",
2204 This, pIUnk, memid, dwFlags, pDispParams, pVarResult, pExcepInfo, pArgErr );
2205 dump_DispParms(pDispParams);
2209 /* ITypeInfo::GetDocumentation
2211 * Retrieves the documentation string, the complete Help file name and path,
2212 * and the context ID for the Help topic for a specified type description.
2214 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( ITypeInfo2 *iface,
2215 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
2216 DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
2218 ICOM_THIS( ITypeInfoImpl, iface);
2219 TLBFuncDesc * pFDesc;
2220 TLBVarDesc * pVDesc;
2221 TRACE("(%p) memid %ld Name(%p) DocString(%p)"
2222 " HelpContext(%p) HelpFile(%p)\n",
2223 This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
2224 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
2226 *pBstrName=TLB_DupAtoBstr(This->Name);
2228 *pBstrDocString=TLB_DupAtoBstr(This->DocString);
2230 *pdwHelpContext=This->dwHelpContext;
2232 *pBstrHelpFile=TLB_DupAtoBstr(This->DocString);/* FIXME */
2234 }else {/* for a member */
2235 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
2236 if(pFDesc->funcdesc.memid==memid){
2239 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
2240 if(pVDesc->vardesc.memid==memid){
2244 return TYPE_E_ELEMENTNOTFOUND;
2247 /* ITypeInfo::GetDllEntry
2249 * Retrieves a description or specification of an entry point for a function
2252 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid,
2253 INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
2256 ICOM_THIS( ITypeInfoImpl, iface);
2257 FIXME("(%p) stub!\n", This);
2261 /* ITypeInfo::GetRefTypeInfo
2263 * If a type description references other type descriptions, it retrieves
2264 * the referenced type descriptions.
2266 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
2269 ITypeInfo **ppTInfo)
2271 ICOM_THIS( ITypeInfoImpl, iface);
2274 if(HREFTYPE_INTHISFILE(hRefType))
2278 result = ITypeInfo_GetContainingTypeLib(iface, &pTLib, &Index);
2279 if(SUCCEEDED( result ))
2281 result=ITypeLib2_GetTypeInfo(pTLib, HREFTYPE_INDEX(hRefType), ppTInfo);
2282 ITypeLib2_Release(pTLib );
2287 /* imported type lib */
2288 TLBRefType * pRefType;
2289 ITypeLibImpl *pTypeLib;
2290 for( pRefType=This->impltypelist; pRefType &&
2291 pRefType->reference != hRefType; pRefType=pRefType->next);
2293 return TYPE_E_ELEMENTNOTFOUND; /* FIXME : correct? */
2295 pTypeLib = pRefType->pImpTLInfo->pImpTypeLib;
2296 if(pTypeLib) /* typelib already loaded */
2298 result=ITypeLib2_GetTypeInfoOfGuid(
2299 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
2303 result = LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
2305 (LPTYPELIB *)&pTypeLib);
2306 if(!SUCCEEDED(result))
2308 BSTR libnam=TLB_DupAtoBstr(pRefType->pImpTLInfo->name);
2309 result=LoadTypeLib(libnam, (LPTYPELIB *)&pTypeLib);
2310 SysFreeString(libnam);
2312 if(SUCCEEDED(result))
2314 result=ITypeLib2_GetTypeInfoOfGuid((LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
2315 pRefType->pImpTLInfo->pImpTypeLib = pTypeLib;
2319 TRACE("(%p) hreftype 0x%04lx loaded %s (%p)\n", This, hRefType,
2320 SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
2324 /* ITypeInfo::AddressOfMember
2326 * Retrieves the addresses of static functions or variables, such as those
2329 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface,
2330 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
2332 ICOM_THIS( ITypeInfoImpl, iface);
2333 FIXME("(%p) stub!\n", This);
2337 /* ITypeInfo::CreateInstance
2339 * Creates a new instance of a type that describes a component object class
2342 static HRESULT WINAPI ITypeInfo_fnCreateInstance( ITypeInfo2 *iface,
2343 IUnknown *pUnk, REFIID riid, VOID **ppvObj)
2345 ICOM_THIS( ITypeInfoImpl, iface);
2346 FIXME("(%p) stub!\n", This);
2350 /* ITypeInfo::GetMops
2352 * Retrieves marshaling information.
2354 static HRESULT WINAPI ITypeInfo_fnGetMops( ITypeInfo2 *iface, MEMBERID memid,
2357 ICOM_THIS( ITypeInfoImpl, iface);
2358 FIXME("(%p) stub!\n", This);
2362 /* ITypeInfo::GetContainingTypeLib
2364 * Retrieves the containing type library and the index of the type description
2365 * within that type library.
2367 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( ITypeInfo2 *iface,
2368 ITypeLib * *ppTLib, UINT *pIndex)
2370 ICOM_THIS( ITypeInfoImpl, iface);
2371 *ppTLib=(LPTYPELIB )(This->pTypeLib);
2372 *pIndex=This->index;
2373 ITypeLib2_AddRef(*ppTLib);
2374 TRACE("(%p) returns (%p) index %d!\n", This, *ppTLib, *pIndex);
2378 /* ITypeInfo::ReleaseTypeAttr
2380 * Releases a TYPEATTR previously returned by GetTypeAttr.
2383 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( ITypeInfo2 *iface,
2384 TYPEATTR* pTypeAttr)
2386 ICOM_THIS( ITypeInfoImpl, iface);
2387 TRACE("(%p)->(%p)\n", This, pTypeAttr);
2391 /* ITypeInfo::ReleaseFuncDesc
2393 * Releases a FUNCDESC previously returned by GetFuncDesc. *
2395 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc(
2397 FUNCDESC *pFuncDesc)
2399 ICOM_THIS( ITypeInfoImpl, iface);
2400 TRACE("(%p)->(%p)\n", This, pFuncDesc);
2404 /* ITypeInfo::ReleaseVarDesc
2406 * Releases a VARDESC previously returned by GetVarDesc.
2408 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( ITypeInfo2 *iface,
2411 ICOM_THIS( ITypeInfoImpl, iface);
2412 TRACE("(%p)->(%p)\n", This, pVarDesc);
2416 /* ITypeInfo2::GetTypeKind
2418 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
2421 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo2 * iface,
2422 TYPEKIND *pTypeKind)
2424 ICOM_THIS( ITypeInfoImpl, iface);
2425 *pTypeKind=This->TypeAttr.typekind;
2426 TRACE("(%p) type 0x%0x\n", This,*pTypeKind);
2430 /* ITypeInfo2::GetTypeFlags
2432 * Returns the type flags without any allocations. This returns a DWORD type
2433 * flag, which expands the type flags without growing the TYPEATTR (type
2437 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo2 * iface,
2440 ICOM_THIS( ITypeInfoImpl, iface);
2441 *pTypeFlags=This->TypeAttr.wTypeFlags;
2442 TRACE("(%p) flags 0x%04x\n", This,*pTypeFlags);
2446 /* ITypeInfo2::GetFuncIndexOfMemId
2447 * Binds to a specific member based on a known DISPID, where the member name
2448 * is not known (for example, when binding to a default member).
2451 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2 * iface,
2452 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
2454 ICOM_THIS( ITypeInfoImpl, iface);
2455 TLBFuncDesc *pFuncInfo;
2458 /* FIXME: should check for invKind??? */
2459 for(i=0, pFuncInfo=This->funclist;pFuncInfo &&
2460 memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next);
2466 result=E_INVALIDARG;
2468 TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This,
2469 memid, invKind, SUCCEEDED(result)? "SUCCES":"FAILED");
2473 /* TypeInfo2::GetVarIndexOfMemId
2475 * Binds to a specific member based on a known DISPID, where the member name
2476 * is not known (for example, when binding to a default member).
2479 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo2 * iface,
2480 MEMBERID memid, UINT *pVarIndex)
2482 ICOM_THIS( ITypeInfoImpl, iface);
2483 TLBVarDesc *pVarInfo;
2486 for(i=0, pVarInfo=This->varlist; pVarInfo &&
2487 memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next)
2494 result=E_INVALIDARG;
2496 TRACE("(%p) memid 0x%08lx -> %s\n", This,
2497 memid, SUCCEEDED(result)? "SUCCES":"FAILED");
2501 /* ITypeInfo2::GetCustData
2503 * Gets the custom data
2505 static HRESULT WINAPI ITypeInfo2_fnGetCustData(
2510 ICOM_THIS( ITypeInfoImpl, iface);
2511 TLBCustData *pCData;
2513 for(pCData=This->pCustData; pCData; pCData = pCData->next)
2514 if( IsEqualIID(guid, &pCData->guid)) break;
2516 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2520 VariantInit( pVarVal);
2521 VariantCopy( pVarVal, &pCData->data);
2524 return E_INVALIDARG; /* FIXME: correct? */
2527 /* ITypeInfo2::GetFuncCustData
2529 * Gets the custom data
2531 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData(
2537 ICOM_THIS( ITypeInfoImpl, iface);
2538 TLBCustData *pCData=NULL;
2539 TLBFuncDesc * pFDesc;
2541 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2542 pFDesc=pFDesc->next);
2545 for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next)
2546 if( IsEqualIID(guid, &pCData->guid)) break;
2548 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2551 VariantInit( pVarVal);
2552 VariantCopy( pVarVal, &pCData->data);
2555 return E_INVALIDARG; /* FIXME: correct? */
2558 /* ITypeInfo2::GetParamCustData
2560 * Gets the custom data
2562 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData(
2569 ICOM_THIS( ITypeInfoImpl, iface);
2570 TLBCustData *pCData=NULL;
2571 TLBFuncDesc * pFDesc;
2574 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,pFDesc=pFDesc->next);
2576 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams)
2577 for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData;
2578 pCData = pCData->next)
2579 if( IsEqualIID(guid, &pCData->guid)) break;
2581 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2585 VariantInit( pVarVal);
2586 VariantCopy( pVarVal, &pCData->data);
2589 return E_INVALIDARG; /* FIXME: correct? */
2592 /* ITypeInfo2::GetVarcCustData
2594 * Gets the custom data
2596 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData(
2602 ICOM_THIS( ITypeInfoImpl, iface);
2603 TLBCustData *pCData=NULL;
2604 TLBVarDesc * pVDesc;
2607 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next);
2611 for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next)
2613 if( IsEqualIID(guid, &pCData->guid)) break;
2617 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2621 VariantInit( pVarVal);
2622 VariantCopy( pVarVal, &pCData->data);
2625 return E_INVALIDARG; /* FIXME: correct? */
2628 /* ITypeInfo2::GetImplcCustData
2630 * Gets the custom data
2632 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData(
2638 ICOM_THIS( ITypeInfoImpl, iface);
2639 TLBCustData *pCData=NULL;
2640 TLBRefType * pRDesc;
2643 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++, pRDesc=pRDesc->next);
2647 for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next)
2649 if( IsEqualIID(guid, &pCData->guid)) break;
2653 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2657 VariantInit( pVarVal);
2658 VariantCopy( pVarVal, &pCData->data);
2661 return E_INVALIDARG; /* FIXME: correct? */
2664 /* ITypeInfo2::GetDocumentation2
2666 * Retrieves the documentation string, the complete Help file name and path,
2667 * the localization context to use, and the context ID for the library Help
2668 * topic in the Help file.
2671 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(
2675 BSTR *pbstrHelpString,
2676 DWORD *pdwHelpStringContext,
2677 BSTR *pbstrHelpStringDll)
2679 ICOM_THIS( ITypeInfoImpl, iface);
2680 TLBFuncDesc * pFDesc;
2681 TLBVarDesc * pVDesc;
2682 TRACE("(%p) memid %ld lcid(0x%lx) HelpString(%p) "
2683 "HelpStringContext(%p) HelpStringDll(%p)\n",
2684 This, memid, lcid, pbstrHelpString, pdwHelpStringContext,
2685 pbstrHelpStringDll );
2686 /* the help string should be obtained from the helpstringdll,
2687 * using the _DLLGetDocumentation function, based on the supplied
2688 * lcid. Nice to do sometime...
2690 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
2692 *pbstrHelpString=TLB_DupAtoBstr(This->Name);
2693 if(pdwHelpStringContext)
2694 *pdwHelpStringContext=This->dwHelpStringContext;
2695 if(pbstrHelpStringDll)
2696 *pbstrHelpStringDll=
2697 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2699 }else {/* for a member */
2700 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
2701 if(pFDesc->funcdesc.memid==memid){
2703 *pbstrHelpString=TLB_DupAtoBstr(pFDesc->HelpString);
2704 if(pdwHelpStringContext)
2705 *pdwHelpStringContext=pFDesc->HelpStringContext;
2706 if(pbstrHelpStringDll)
2707 *pbstrHelpStringDll=
2708 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2711 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
2712 if(pVDesc->vardesc.memid==memid){
2714 *pbstrHelpString=TLB_DupAtoBstr(pVDesc->HelpString);
2715 if(pdwHelpStringContext)
2716 *pdwHelpStringContext=pVDesc->HelpStringContext;
2717 if(pbstrHelpStringDll)
2718 *pbstrHelpStringDll=
2719 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2723 return TYPE_E_ELEMENTNOTFOUND;
2726 /* ITypeInfo2::GetAllCustData
2728 * Gets all custom data items for the Type info.
2731 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData(
2733 CUSTDATA *pCustData)
2735 ICOM_THIS( ITypeInfoImpl, iface);
2736 TLBCustData *pCData;
2739 TRACE("(%p) returning %d items\n", This, This->ctCustData);
2741 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
2742 if(pCustData->prgCustData ){
2743 pCustData->cCustData=This->ctCustData;
2744 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
2745 pCustData->prgCustData[i].guid=pCData->guid;
2746 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
2749 ERR(" OUT OF MEMORY! \n");
2750 return E_OUTOFMEMORY;
2755 /* ITypeInfo2::GetAllFuncCustData
2757 * Gets all custom data items for the specified Function
2760 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData(
2763 CUSTDATA *pCustData)
2765 ICOM_THIS( ITypeInfoImpl, iface);
2766 TLBCustData *pCData;
2767 TLBFuncDesc * pFDesc;
2769 TRACE("(%p) index %d\n", This, index);
2770 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2771 pFDesc=pFDesc->next)
2774 pCustData->prgCustData =
2775 TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM));
2776 if(pCustData->prgCustData ){
2777 pCustData->cCustData=pFDesc->ctCustData;
2778 for(i=0, pCData=pFDesc->pCustData; pCData; i++,
2779 pCData = pCData->next){
2780 pCustData->prgCustData[i].guid=pCData->guid;
2781 VariantCopy(& pCustData->prgCustData[i].varValue,
2785 ERR(" OUT OF MEMORY! \n");
2786 return E_OUTOFMEMORY;
2790 return TYPE_E_ELEMENTNOTFOUND;
2793 /* ITypeInfo2::GetAllParamCustData
2795 * Gets all custom data items for the Functions
2798 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo2 * iface,
2799 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
2801 ICOM_THIS( ITypeInfoImpl, iface);
2802 TLBCustData *pCData=NULL;
2803 TLBFuncDesc * pFDesc;
2805 TRACE("(%p) index %d\n", This, indexFunc);
2806 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
2807 pFDesc=pFDesc->next)
2809 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams){
2810 pCustData->prgCustData =
2811 TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData *
2812 sizeof(CUSTDATAITEM));
2813 if(pCustData->prgCustData ){
2814 pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData;
2815 for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData;
2816 pCData; i++, pCData = pCData->next){
2817 pCustData->prgCustData[i].guid=pCData->guid;
2818 VariantCopy(& pCustData->prgCustData[i].varValue,
2822 ERR(" OUT OF MEMORY! \n");
2823 return E_OUTOFMEMORY;
2827 return TYPE_E_ELEMENTNOTFOUND;
2830 /* ITypeInfo2::GetAllVarCustData
2832 * Gets all custom data items for the specified Variable
2835 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo2 * iface,
2836 UINT index, CUSTDATA *pCustData)
2838 ICOM_THIS( ITypeInfoImpl, iface);
2839 TLBCustData *pCData;
2840 TLBVarDesc * pVDesc;
2842 TRACE("(%p) index %d\n", This, index);
2843 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2844 pVDesc=pVDesc->next)
2847 pCustData->prgCustData =
2848 TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM));
2849 if(pCustData->prgCustData ){
2850 pCustData->cCustData=pVDesc->ctCustData;
2851 for(i=0, pCData=pVDesc->pCustData; pCData; i++,
2852 pCData = pCData->next){
2853 pCustData->prgCustData[i].guid=pCData->guid;
2854 VariantCopy(& pCustData->prgCustData[i].varValue,
2858 ERR(" OUT OF MEMORY! \n");
2859 return E_OUTOFMEMORY;
2863 return TYPE_E_ELEMENTNOTFOUND;
2866 /* ITypeInfo2::GetAllImplCustData
2868 * Gets all custom data items for the specified implementation type
2871 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData(
2874 CUSTDATA *pCustData)
2876 ICOM_THIS( ITypeInfoImpl, iface);
2877 TLBCustData *pCData;
2878 TLBRefType * pRDesc;
2880 TRACE("(%p) index %d\n", This, index);
2881 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2882 pRDesc=pRDesc->next)
2885 pCustData->prgCustData =
2886 TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM));
2887 if(pCustData->prgCustData ){
2888 pCustData->cCustData=pRDesc->ctCustData;
2889 for(i=0, pCData=pRDesc->pCustData; pCData; i++,
2890 pCData = pCData->next){
2891 pCustData->prgCustData[i].guid=pCData->guid;
2892 VariantCopy(& pCustData->prgCustData[i].varValue,
2896 ERR(" OUT OF MEMORY! \n");
2897 return E_OUTOFMEMORY;
2901 return TYPE_E_ELEMENTNOTFOUND;
2904 static ICOM_VTABLE(ITypeInfo2) tinfvt =
2906 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2908 ITypeInfo_fnQueryInterface,
2910 ITypeInfo_fnRelease,
2912 ITypeInfo_fnGetTypeAttr,
2913 ITypeInfo_fnGetTypeComp,
2914 ITypeInfo_fnGetFuncDesc,
2915 ITypeInfo_fnGetVarDesc,
2916 ITypeInfo_fnGetNames,
2917 ITypeInfo_fnGetRefTypeOfImplType,
2918 ITypeInfo_fnGetImplTypeFlags,
2919 ITypeInfo_fnGetIDsOfNames,
2921 ITypeInfo_fnGetDocumentation,
2922 ITypeInfo_fnGetDllEntry,
2923 ITypeInfo_fnGetRefTypeInfo,
2924 ITypeInfo_fnAddressOfMember,
2925 ITypeInfo_fnCreateInstance,
2926 ITypeInfo_fnGetMops,
2927 ITypeInfo_fnGetContainingTypeLib,
2928 ITypeInfo_fnReleaseTypeAttr,
2929 ITypeInfo_fnReleaseFuncDesc,
2930 ITypeInfo_fnReleaseVarDesc,
2932 ITypeInfo2_fnGetTypeKind,
2933 ITypeInfo2_fnGetTypeFlags,
2934 ITypeInfo2_fnGetFuncIndexOfMemId,
2935 ITypeInfo2_fnGetVarIndexOfMemId,
2936 ITypeInfo2_fnGetCustData,
2937 ITypeInfo2_fnGetFuncCustData,
2938 ITypeInfo2_fnGetParamCustData,
2939 ITypeInfo2_fnGetVarCustData,
2940 ITypeInfo2_fnGetImplTypeCustData,
2941 ITypeInfo2_fnGetDocumentation2,
2942 ITypeInfo2_fnGetAllCustData,
2943 ITypeInfo2_fnGetAllFuncCustData,
2944 ITypeInfo2_fnGetAllParamCustData,
2945 ITypeInfo2_fnGetAllVarCustData,
2946 ITypeInfo2_fnGetAllImplTypeCustData,