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/winestring.h"
37 #include "wine/obj_base.h"
38 #include "debugtools.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 (RegQueryValueA(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 */
101 /* don't need to ZeroMemory those arrays since sprintf and RegQueryValue add
102 string termination character on output strings */
106 DWORD dwPathLen = _MAX_PATH;
110 char szTypeLibKey[100];
111 char szPath[dwPathLen];
119 FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n", szXGUID, wMaj, wMin, (DWORD)lcid, path);
125 sprintf(szTypeLibKey,
126 "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win32",
127 guid->Data1, guid->Data2, guid->Data3,
128 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
129 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7],
134 if (RegQueryValueA(HKEY_LOCAL_MACHINE, szTypeLibKey, szPath, &dwPathLen))
138 else if (myLCID == lcid)
140 /* try with sub-langid */
141 myLCID = SUBLANGID(lcid);
143 else if (myLCID == SUBLANGID(lcid))
145 /* try with system langid */
155 DWORD len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPath, dwPathLen, NULL, 0 );
156 BSTR bstrPath = SysAllocStringLen(NULL,len);
158 MultiByteToWideChar(CP_ACP,
168 TRACE_(typelib)("%s not found\n", szTypeLibKey);
172 /******************************************************************************
173 * CreateTypeLib [OLEAUT32] creates a typelib
179 HRESULT WINAPI CreateTypeLib(
180 SYSKIND syskind, LPCOLESTR szFile, /*ICreateTypeLib*/IUnknown ** ppctlib
182 FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib);
185 /******************************************************************************
186 * LoadTypeLib [TYPELIB.3] Loads and registers a type library
188 * Docs: OLECHAR FAR* szFile
189 * Docs: iTypeLib FAR* FAR* pptLib
195 HRESULT WINAPI LoadTypeLib16(
196 LPOLESTR szFile, /* [in] Name of file to load from */
197 void * *pptLib) /* [out] Pointer to pointer to loaded type library */
199 FIXME("('%s',%p): stub\n",debugstr_w((LPWSTR)szFile),pptLib);
207 /******************************************************************************
208 * LoadTypeLib [OLEAUT32.161]
209 * Loads and registers a type library
211 * Docs: OLECHAR FAR* szFile
212 * Docs: iTypeLib FAR* FAR* pptLib
218 int TLB_ReadTypeLib(PCHAR file, ITypeLib2 **ppTypelib);
220 HRESULT WINAPI LoadTypeLib(
221 OLECHAR *szFile, /* [in] Name of file to load from */
222 ITypeLib * *pptLib) /* [out] Pointer to pointer to loaded type library */
225 return LoadTypeLibEx(szFile, REGKIND_DEFAULT, pptLib);
228 /******************************************************************************
229 * LoadTypeLibEx [OLEAUT32.183]
230 * Loads and optionally registers a type library
236 HRESULT WINAPI LoadTypeLibEx(
237 LPOLESTR szFile, /* [in] Name of file to load from */
238 REGKIND regkind, /* specify kind of registration */
239 ITypeLib **pptLib) /* [out] Pointer to pointer to loaded type library */
243 TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib);
245 p=HEAP_strdupWtoA(GetProcessHeap(),0,szFile);
247 if(regkind != REGKIND_NONE)
248 FIXME ("registration of typelibs not supported yet!\n");
250 res= TLB_ReadTypeLib(p, (ITypeLib2**)pptLib);
251 HeapFree(GetProcessHeap(),0,p);
252 TRACE(" returns %08lx\n",res);
257 /******************************************************************************
258 * LoadRegTypeLib [OLEAUT32.162]
260 HRESULT WINAPI LoadRegTypeLib(
261 REFGUID rguid, /* [in] referenced guid */
262 WORD wVerMajor, /* [in] major version */
263 WORD wVerMinor, /* [in] minor version */
264 LCID lcid, /* [in] locale id */
265 ITypeLib **ppTLib) /* [out] path of typelib */
268 HRESULT res=QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor, lcid, &bstr);
272 res= LoadTypeLib(bstr, ppTLib);
276 TRACE("(IID: %s) load %s (%p)\n",debugstr_guid(rguid), SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);
282 /******************************************************************************
283 * RegisterTypeLib [OLEAUT32.163]
284 * Adds information about a type library to the System Registry
286 * Docs: ITypeLib FAR * ptlib
287 * Docs: OLECHAR FAR* szFullPath
288 * Docs: OLECHAR FAR* szHelpDir
294 HRESULT WINAPI RegisterTypeLib(
295 ITypeLib * ptlib, /*[in] Pointer to the library*/
296 OLECHAR * szFullPath, /*[in] full Path of the library*/
297 OLECHAR * szHelpDir) /*[in] dir to the helpfile for the library,
299 { FIXME("(%p,%s,%s): stub\n",ptlib, debugstr_w(szFullPath),debugstr_w(szHelpDir));
300 return S_OK; /* FIXME: pretend everything is OK */
304 /******************************************************************************
305 * UnRegisterTypeLib [OLEAUT32.186]
306 * Removes information about a type library from the System Registry
313 HRESULT WINAPI UnRegisterTypeLib(
314 REFGUID libid, /* [in] Guid of the library */
315 WORD wVerMajor, /* [in] major version */
316 WORD wVerMinor, /* [in] minor version */
317 LCID lcid, /* [in] locale id */
320 TRACE("(IID: %s): stub\n",debugstr_guid(libid));
321 return S_OK; /* FIXME: pretend everything is OK */
324 /****************************************************************************
325 * OaBuildVersion (TYPELIB.15)
327 * known TYPELIB.DLL versions:
329 * OLE 2.01 no OaBuildVersion() avail 1993 -- ---
330 * OLE 2.02 1993-94 02 3002
333 * OLE 2.03 W98 SE orig. file !! 1993-95 10 3024
334 * OLE 2.1 NT 1993-95 ?? ???
335 * OLE 2.3.1 W95 23 700
337 DWORD WINAPI OaBuildVersion16(void)
339 FIXME("Please report to a.mohr@mailto.de if you get version error messages !\n");
340 switch(GetVersion() & 0x8000ffff) /* mask off build number */
342 case 0x80000a03: /* WIN31 */
343 return MAKELONG(3027, 3); /* WfW 3.11 */
344 case 0x80000004: /* WIN95 */
345 return MAKELONG(700, 23); /* Win95A */
346 case 0x80000a04: /* WIN98 */
347 return MAKELONG(3024, 10); /* W98 SE */
349 FIXME_(ole)("Version value not known yet. Please investigate it !");
354 /* for better debugging info leave the static out for the time being */
357 /*======================= ITypeLib implementation =======================*/
359 typedef struct tagTLBCustData
363 struct tagTLBCustData* next;
366 /* data structure for import typelibs */
367 typedef struct tagTLBImpLib
369 int offset; /* offset in the file */
370 GUID guid; /* libid */
371 PCHAR name; /* name; */
372 struct tagITypeLibImpl *pImpTypeLib; /* pointer to loaded typelib */
373 struct tagTLBImpLib * next;
376 /* internal ITypeLib data */
377 typedef struct tagITypeLibImpl
379 ICOM_VFIELD(ITypeLib2);
381 TLIBATTR LibAttr; /* guid,lcid,syskind,version,flags */
382 /* type libs seem to store the doc strings in ascii
383 * so why should we do it in unicode?
389 unsigned long dwHelpContext;
390 int TypeInfoCount; /* nr of typeinfo's in librarry */
391 struct tagITypeInfoImpl *pTypeInfo; /* linked list of type info data */
392 int ctCustData; /* number of items in cust data list */
393 TLBCustData * pCustData; /* linked list to cust data; */
394 TLBImpLib * pImpLibs; /* linked list to all imported typelibs */
395 TYPEDESC * pTypeDesc; /* array of TypeDescriptions found in the libary */
398 static struct ICOM_VTABLE(ITypeLib2) tlbvt;
400 /* ITypeLib methods */
401 static ITypeLib2* ITypeLib2_Constructor(LPVOID pLib, DWORD dwTLBLength);
403 /*======================= ITypeInfo implementation =======================*/
405 /* internal Parameter data */
406 typedef struct tagTLBParDesc
410 TLBCustData * pCustData; /* linked list to cust data; */
413 /* internal Function data */
414 typedef struct tagTLBFuncDesc
416 FUNCDESC funcdesc; /* lots of info on the function and its attributes. */
417 PCHAR Name; /* the name of this function */
418 TLBParDesc *pParamDesc; /* array with name and custom data */
420 int HelpStringContext;
422 PCHAR Entry; /* if its Hiword==0, it numeric; -1 is not present*/
424 TLBCustData * pCustData; /* linked list to cust data; */
425 struct tagTLBFuncDesc * next;
428 /* internal Variable data */
429 typedef struct tagTLBVarDesc
431 VARDESC vardesc; /* lots of info on the variable and its attributes. */
432 PCHAR Name; /* the name of this variable */
434 int HelpStringContext; /* fixme: where? */
437 TLBCustData * pCustData;/* linked list to cust data; */
438 struct tagTLBVarDesc * next;
441 /* data for refernced types in a coclass, or an inherited interface */
442 typedef struct tagTLBRefType
444 GUID guid; /* guid of the referenced type */
445 /* (important if its a imported type) */
449 TLBCustData * pCustData;/* linked list to custom data; */
450 TLBImpLib *pImpTLInfo;
451 struct tagTLBRefType * next;
454 /* internal TypeInfo data */
455 typedef struct tagITypeInfoImpl
457 ICOM_VFIELD(ITypeInfo2);
459 TYPEATTR TypeAttr ; /* _lots_ of type information. */
460 ITypeLibImpl * pTypeLib; /* back pointer to typelib */
461 int index; /* index in this typelib; */
462 /* type libs seem to store the doc strings in ascii
463 * so why should we do it in unicode?
467 unsigned long dwHelpContext;
468 unsigned long dwHelpStringContext;
471 TLBFuncDesc * funclist; /* linked list with function descriptions */
474 TLBVarDesc * varlist; /* linked list with variable descriptions */
476 /* Implemented Interfaces */
477 TLBRefType * impltypelist;
479 TLBCustData * pCustData; /* linked list to cust data; */
480 struct tagITypeInfoImpl * next;
483 static struct ICOM_VTABLE(ITypeInfo2) tinfvt;
485 static ITypeInfo2 * WINAPI ITypeInfo_Constructor();
487 typedef struct tagTLBContext
489 unsigned int oStart; /* start of TLB in file */
490 unsigned int pos; /* current pos */
491 unsigned int length; /* total length */
492 void *mapping; /* memory mapping */
494 ITypeLibImpl* pLibInfo;
500 static void dump_TLBFuncDesc(TLBFuncDesc * pfd)
504 TRACE("%s(%u)\n", pfd->Name, pfd->funcdesc.cParams);
508 static void dump_TLBVarDesc(TLBVarDesc * pvd)
512 TRACE("%s\n", pvd->Name);
516 static void dump_TLBRefType(TLBRefType * prt)
520 TRACE("%s\n", debugstr_guid(&(prt->guid)));
521 TRACE(" href:0x%08lx\n", prt->reference);
526 static void dump_Variant(VARIANT * pvar)
528 TRACE("%p %x\n", pvar, pvar?pvar->vt:0 );
531 if (pvar->vt & VT_BYREF)
532 return dump_Variant(pvar->u.pvarVal);
535 static void dump_DispParms(DISPPARAMS * pdp)
537 dump_Variant( pdp->rgvarg);
538 TRACE("args=%u named args=%u\n", pdp->cArgs, pdp->cNamedArgs);
541 static char * typekind_desc[] =
554 static void dump_TypeInfo(ITypeInfoImpl * pty)
556 TRACE("%p ref=%u\n", pty, pty->ref);
557 TRACE("attr:%s\n", debugstr_guid(&(pty->TypeAttr.guid)));
558 TRACE("kind:%s\n", typekind_desc[pty->TypeAttr.typekind]);
559 TRACE("fct:%u var:%u impl:%u\n",
560 pty->TypeAttr.cFuncs, pty->TypeAttr.cVars, pty->TypeAttr.cImplTypes);
561 TRACE("parent tlb:%p index in TLB:%u\n",pty->pTypeLib, pty->index);
562 TRACE("%s %s\n", pty->Name, pty->DocString);
563 dump_TLBFuncDesc(pty->funclist);
564 dump_TLBVarDesc(pty->varlist);
565 dump_TLBRefType(pty->impltypelist);
568 static TYPEDESC stndTypeDesc[VT_LPWSTR+1]=
570 /* VT_LPWSTR is largest type that */
571 /* may appear in type description*/
572 {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
573 {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
574 {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
575 {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
576 {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
577 {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
581 static void TLB_abort()
585 static void * TLB_Alloc(unsigned size)
588 if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){
590 ERR("cannot allocate memory\n");
595 /* candidate for a more global appearance... */
596 static BSTR TLB_DupAtoBstr(PCHAR Astr)
604 pdw =TLB_Alloc((len+3)*sizeof(OLECHAR));
605 pdw[0]=(len)*sizeof(OLECHAR);
606 bstr=(BSTR)&( pdw[1]);
607 lstrcpyAtoW( bstr, Astr);
608 TRACE("copying %s to (%p)\n", Astr, bstr);
612 static void TLB_Free(void * ptr)
614 HeapFree(GetProcessHeap(), 0, ptr);
617 DWORD TLB_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
619 TRACE("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n",
620 pcx->pos, count, pcx->oStart, pcx->length, where);
622 if (where != DO_NOT_SEEK)
624 where += pcx->oStart;
625 if (where > pcx->length)
628 ERR("seek beyond end (%ld/%d)\n", where, pcx->length );
633 if (pcx->pos + count > pcx->length) count = pcx->length - pcx->pos;
634 memcpy( buffer, (char *)pcx->mapping + pcx->pos, count );
639 static void TLB_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
641 TRACE("%s\n", debugstr_guid(pGuid));
643 if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){
644 memset(pGuid,0, sizeof(GUID));
647 TLB_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset );
650 PCHAR TLB_ReadName( TLBContext *pcx, int offset)
655 TLB_Read(&niName, sizeof(niName), pcx,
656 pcx->pTblDir->pNametab.offset+offset);
657 niName.namelen &= 0xFF; /* FIXME: correct ? */
658 name=TLB_Alloc((niName.namelen & 0xff) +1);
659 TLB_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK);
660 name[niName.namelen & 0xff]='\0';
661 TRACE("%s\n", debugstr_a(name));
664 PCHAR TLB_ReadString( TLBContext *pcx, int offset)
669 if(offset<0) return NULL;
670 TLB_Read(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
671 if(length <= 0) return 0;
672 string=TLB_Alloc(length +1);
673 TLB_Read(string, length, pcx, DO_NOT_SEEK);
675 TRACE("%s\n", debugstr_a(string));
679 * read a value and fill a VARIANT structure
681 static void TLB_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
687 if(offset <0) { /* data is packed in here */
688 pVar->vt = (offset & 0x7c000000 )>> 26;
689 V_UNION(pVar, iVal) = offset & 0xffff;
692 TLB_Read(&(pVar->vt), sizeof(VARTYPE), pcx,
693 pcx->pTblDir->pCustData.offset + offset );
694 TRACE("Vartype = %x\n", pVar->vt);
696 case VT_EMPTY: /* FIXME: is this right? */
697 case VT_NULL: /* FIXME: is this right? */
698 case VT_I2 : /* this should not happen */
709 case VT_VOID : /* FIXME: is this right? */
717 case VT_DECIMAL : /* FIXME: is this right? */
720 /* pointer types with known behaviour */
723 TLB_Read(&size, sizeof(INT), pcx, DO_NOT_SEEK );
725 FIXME("BSTR length = %d?\n", size);
727 ptr=TLB_Alloc(size);/* allocate temp buffer */
728 TLB_Read(ptr, size, pcx, DO_NOT_SEEK); /* read string (ANSI) */
729 V_UNION(pVar, bstrVal)=SysAllocStringLen(NULL,size);
730 /* FIXME: do we need a AtoW conversion here? */
731 V_UNION(pVar, bstrVal[size])=L'\0';
732 while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
737 /* FIXME: this will not work AT ALL when the variant contains a pointer */
744 case VT_USERDEFINED :
750 case VT_STREAMED_OBJECT :
751 case VT_STORED_OBJECT :
752 case VT_BLOB_OBJECT :
757 FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
761 if(size>0) /* (big|small) endian correct? */
762 TLB_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK );
766 * create a linked list with custom data
768 static int TLB_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
778 pNew=TLB_Alloc(sizeof(TLBCustData));
779 TLB_Read(&entry, sizeof(entry), pcx,
780 pcx->pTblDir->pCDGuids.offset+offset);
781 TLB_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
782 TLB_ReadValue(&(pNew->data), entry.DataOffset, pcx);
783 /* add new custom data at head of the list */
784 pNew->next=*ppCustData;
791 static void TLB_GetTdesc(TLBContext *pcx, INT type,TYPEDESC * pTd )
796 pTd->vt=type & VT_TYPEMASK;
798 *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
800 static void TLB_DoFuncs(TLBContext *pcx, int cFuncs, int cVars,
801 int offset, TLBFuncDesc ** pptfd)
804 * member information is stored in a data structure at offset
805 * indicated by the memoffset field of the typeinfo structure
806 * There are several distinctive parts.
807 * the first part starts with a field that holds the total length
808 * of this (first) part excluding this field. Then follow the records,
809 * for each member there is one record.
811 * First entry is always the length of the record (excluding this
813 * Rest of the record depends on the type of the member. If there is
814 * a field indicating the member type (function variable intereface etc)
815 * I have not found it yet. At this time we depend on the information
816 * in the type info and the usual order how things are stored.
818 * Second follows an array sized nrMEM*sizeof(INT) with a memeber id
821 * Third is a equal sized array with file offsets to the name entry
824 * Forth and last (?) part is an array with offsets to the records in the
825 * first part of this file segment.
828 int infolen, nameoffset, reclength, nrattributes;
830 TLBFuncRecord * pFuncRec=(TLBFuncRecord *) recbuf;
832 int recoffset=offset+sizeof(INT);
836 TLB_Read(&infolen,sizeof(INT), pcx, offset);
837 for(i=0;i<cFuncs;i++){
838 *pptfd=TLB_Alloc(sizeof(TLBFuncDesc));
839 /* name, eventually add to a hash table */
840 TLB_Read(&nameoffset, sizeof(INT), pcx,
841 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
842 (*pptfd)->Name=TLB_ReadName(pcx, nameoffset);
843 /* read the function information record */
844 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
846 TLB_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
847 /* do the attributes */
848 nrattributes=(reclength-pFuncRec->nrargs*3*sizeof(int)-0x18)
851 (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
853 (*pptfd)->HelpString = TLB_ReadString(pcx,
854 pFuncRec->OptAttr[1]) ;
856 if(pFuncRec->FKCCIC & 0x2000)
857 (*pptfd)->Entry = (char *) pFuncRec->OptAttr[2] ;
859 (*pptfd)->Entry = TLB_ReadString(pcx,
860 pFuncRec->OptAttr[2]);
862 (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;
863 if(nrattributes>6 && pFuncRec->FKCCIC & 0x80){
864 TLB_CustData(pcx, pFuncRec->OptAttr[6],
865 &(*pptfd)->pCustData);
870 /* fill the FuncDesc Structure */
871 TLB_Read(&(*pptfd)->funcdesc.memid, sizeof(INT), pcx,
872 offset + infolen + ( i + 1) * sizeof(INT));
873 (*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
874 (*pptfd)->funcdesc.invkind = ((pFuncRec->FKCCIC) >>3) & 0xF;
875 (*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >>8 & 0xF;
876 (*pptfd)->funcdesc.cParams = pFuncRec->nrargs ;
877 (*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ;
878 (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ;
879 (*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
880 TLB_GetTdesc(pcx, pFuncRec->DataType,
881 &(*pptfd)->funcdesc.elemdescFunc.tdesc) ;
883 /* do the parameters/arguments */
884 if(pFuncRec->nrargs){
885 TLBParameterInfo paraminfo;
886 (*pptfd)->funcdesc.lprgelemdescParam=
887 TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
888 (*pptfd)->pParamDesc=TLB_Alloc(pFuncRec->nrargs *
891 TLB_Read(¶minfo,sizeof(paraminfo), pcx, recoffset+reclength -
892 pFuncRec->nrargs * sizeof(TLBParameterInfo));
893 for(j=0;j<pFuncRec->nrargs;j++){
894 TLB_GetTdesc(pcx, paraminfo.DataType,
895 &(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc) ;
896 V_UNION(&((*pptfd)->funcdesc.lprgelemdescParam[j]),
897 paramdesc.wParamFlags) = paraminfo.Flags;
898 (*pptfd)->pParamDesc[j].Name=(void *)paraminfo.oName;
899 TLB_Read(¶minfo,sizeof(TLBParameterInfo), pcx,
902 /* second time around */
903 for(j=0;j<pFuncRec->nrargs;j++){
905 (*pptfd)->pParamDesc[j].Name=
906 TLB_ReadName(pcx, (int)(*pptfd)->pParamDesc[j].Name);
908 if((PARAMFLAG_FHASDEFAULT & V_UNION(&((*pptfd)->funcdesc.
909 lprgelemdescParam[j]),paramdesc.wParamFlags)) &&
910 ((pFuncRec->FKCCIC) & 0x1000)){
911 INT *pInt=(INT *)((char *)pFuncRec + reclength -
912 (pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
913 PARAMDESC * pParamDesc= &V_UNION(&((*pptfd)->funcdesc.
914 lprgelemdescParam[j]),paramdesc);
915 pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
916 pParamDesc->pparamdescex->cBytes= sizeof(PARAMDESCEX);
917 TLB_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
921 if(nrattributes>7+j && pFuncRec->FKCCIC & 0x80)
922 TLB_CustData(pcx, pFuncRec->OptAttr[7+j],
923 &(*pptfd)->pParamDesc[j].pCustData);
926 /* scode is not used: archaic win16 stuff FIXME: right? */
927 (*pptfd)->funcdesc.cScodes = 0 ;
928 (*pptfd)->funcdesc.lprgscode = NULL ;
929 pptfd=&((*pptfd)->next);
930 recoffset += reclength;
933 static void TLB_DoVars(TLBContext *pcx, int cFuncs, int cVars,
934 int offset, TLBVarDesc ** pptvd)
936 int infolen, nameoffset, reclength;
938 TLBVarRecord * pVarRec=(TLBVarRecord *) recbuf;
944 TLB_Read(&infolen,sizeof(INT), pcx, offset);
945 TLB_Read(&recoffset,sizeof(INT), pcx, offset + infolen +
946 ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
947 recoffset += offset+sizeof(INT);
948 for(i=0;i<cVars;i++){
949 *pptvd=TLB_Alloc(sizeof(TLBVarDesc));
950 /* name, eventually add to a hash table */
951 TLB_Read(&nameoffset, sizeof(INT), pcx,
952 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
953 (*pptvd)->Name=TLB_ReadName(pcx, nameoffset);
954 /* read the variable information record */
955 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
957 TLB_Read(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
959 if(reclength >(6*sizeof(INT)) )
960 (*pptvd)->HelpContext=pVarRec->HelpContext;
961 if(reclength >(7*sizeof(INT)) )
962 (*pptvd)->HelpString = TLB_ReadString(pcx, pVarRec->oHelpString) ;
963 if(reclength >(8*sizeof(INT)) )
964 if(reclength >(9*sizeof(INT)) )
965 (*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
966 /* fill the VarDesc Structure */
967 TLB_Read(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
968 offset + infolen + ( i + 1) * sizeof(INT));
969 (*pptvd)->vardesc.varkind = pVarRec->VarKind;
970 (*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
971 TLB_GetTdesc(pcx, pVarRec->DataType,
972 &(*pptvd)->vardesc.elemdescVar.tdesc) ;
973 /* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) fixme?? */
974 if(pVarRec->VarKind == VAR_CONST ){
975 V_UNION(&((*pptvd)->vardesc),lpvarValue)=TLB_Alloc(sizeof(VARIANT));
976 TLB_ReadValue(V_UNION(&((*pptvd)->vardesc),lpvarValue),
977 pVarRec->OffsValue, pcx);
979 V_UNION(&((*pptvd)->vardesc),oInst)=pVarRec->OffsValue;
980 pptvd=&((*pptvd)->next);
981 recoffset += reclength;
984 /* fill in data for a hreftype (offset). When the refernced type is contained
985 * in the typelib, its just an (file) offset in the type info base dir.
986 * If comes from import, its an offset+1 in the ImpInfo table
988 static void TLB_DoRefType(TLBContext *pcx,
989 int offset, TLBRefType ** pprtd)
995 if(!HREFTYPE_INTHISFILE( offset)) {
996 /* external typelib */
998 TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs);
999 TLB_Read(&impinfo, sizeof(impinfo), pcx,
1000 pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
1001 for(j=0;pImpLib;j++){ /* search the known offsets of all import libraries */
1002 if(pImpLib->offset==impinfo.oImpFile) break;
1003 pImpLib=pImpLib->next;
1006 (*pprtd)->reference=offset;
1007 (*pprtd)->pImpTLInfo = pImpLib;
1008 TLB_ReadGuid(&(*pprtd)->guid, impinfo.oGuid, pcx);
1010 ERR("Cannot find a reference\n");
1011 (*pprtd)->reference=-1;
1012 (*pprtd)->pImpTLInfo=(void *)-1;
1015 /* in this typelib */
1016 (*pprtd)->reference=offset;
1017 (*pprtd)->pImpTLInfo=(void *)-2;
1021 /* process Implemented Interfaces of a com class */
1022 static void TLB_DoImplTypes(TLBContext *pcx, int count,
1023 int offset, TLBRefType ** pprtd)
1026 TLBRefRecord refrec;
1030 for(i=0;i<count;i++){
1031 if(offset<0) break; /* paranoia */
1032 *pprtd=TLB_Alloc(sizeof(TLBRefType));
1033 TLB_Read(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
1034 TLB_DoRefType(pcx, refrec.reftype, pprtd);
1035 (*pprtd)->flags=refrec.flags;
1036 (*pprtd)->ctCustData=
1037 TLB_CustData(pcx, refrec.oCustData, &(*pprtd)->pCustData);
1038 offset=refrec.onext;
1039 pprtd=&((*pprtd)->next);
1043 * process a typeinfo record
1045 ITypeInfoImpl * TLB_DoTypeInfo(
1048 ITypeLibImpl * pLibInfo)
1050 TLBTypeInfoBase tiBase;
1051 ITypeInfoImpl *ptiRet;
1053 TRACE("count=%u\n", count);
1055 ptiRet = (ITypeInfoImpl*) ITypeInfo_Constructor();
1056 TLB_Read(&tiBase, sizeof(tiBase) ,pcx ,
1057 pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
1058 /* this where we are coming from */
1059 ptiRet->pTypeLib = pLibInfo;
1060 ptiRet->index=count;
1061 /* fill in the typeattr fields */
1062 TLB_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx);
1063 ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid; /* FIXME: correct? */
1064 ptiRet->TypeAttr.memidConstructor=MEMBERID_NIL ;/* FIXME */
1065 ptiRet->TypeAttr.memidDestructor=MEMBERID_NIL ; /* FIXME */
1066 ptiRet->TypeAttr.lpstrSchema=NULL; /* reserved */
1067 ptiRet->TypeAttr.cbSizeInstance=tiBase.size;
1068 ptiRet->TypeAttr.typekind=tiBase.typekind & 0xF;
1069 ptiRet->TypeAttr.cFuncs=LOWORD(tiBase.cElement);
1070 ptiRet->TypeAttr.cVars=HIWORD(tiBase.cElement);
1071 ptiRet->TypeAttr.cbAlignment=(tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */
1072 ptiRet->TypeAttr.wTypeFlags=tiBase.flags;
1073 ptiRet->TypeAttr.wMajorVerNum=LOWORD(tiBase.version);
1074 ptiRet->TypeAttr.wMinorVerNum=HIWORD(tiBase.version);
1075 ptiRet->TypeAttr.cImplTypes=tiBase.cImplTypes;
1076 ptiRet->TypeAttr.cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
1077 if(ptiRet->TypeAttr.typekind == TKIND_ALIAS)
1078 TLB_GetTdesc(pcx, tiBase.datatype1,
1079 &ptiRet->TypeAttr.tdescAlias) ;
1082 /* IDLDESC idldescType; *//* never saw this one != zero */
1084 /* name, eventually add to a hash table */
1085 ptiRet->Name=TLB_ReadName(pcx, tiBase.NameOffset);
1086 TRACE("reading %s\n", ptiRet->Name);
1088 ptiRet->DocString=TLB_ReadString(pcx, tiBase.docstringoffs);
1089 ptiRet->dwHelpStringContext=tiBase.helpstringcontext;
1090 ptiRet->dwHelpContext=tiBase.helpcontext;
1091 /* note: InfoType's Help file and HelpStringDll come from the containing
1092 * library. Further HelpString and Docstring appear to be the same thing :(
1095 if(ptiRet->TypeAttr.cFuncs >0 )
1096 TLB_DoFuncs(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
1097 tiBase.memoffset, & ptiRet->funclist);
1099 if(ptiRet->TypeAttr.cVars >0 )
1100 TLB_DoVars(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
1101 tiBase.memoffset, & ptiRet->varlist);
1102 if(ptiRet->TypeAttr.cImplTypes >0 ){
1103 if(ptiRet->TypeAttr.typekind == TKIND_COCLASS)
1104 TLB_DoImplTypes(pcx, ptiRet->TypeAttr.cImplTypes ,
1105 tiBase.datatype1, & ptiRet->impltypelist);
1106 else if(ptiRet->TypeAttr.typekind != TKIND_DISPATCH){
1107 ptiRet->impltypelist=TLB_Alloc(sizeof(TLBRefType));
1108 TLB_DoRefType(pcx, tiBase.datatype1, & ptiRet->impltypelist);
1112 TLB_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData);
1114 TRACE("%s guid: %s kind:%s\n",
1116 debugstr_guid(&ptiRet->TypeAttr.guid),
1117 typekind_desc[ptiRet->TypeAttr.typekind]);
1122 /****************************************************************************
1125 * find the type of the typelib file and map the typelib resource into
1128 #define MSFT_SIGNATURE 0x5446534D /* "MSFT" */
1129 int TLB_ReadTypeLib(LPSTR pszFileName, ITypeLib2 **ppTypeLib)
1132 DWORD dwSignature = 0;
1135 TRACE("%s\n", pszFileName);
1139 /* check the signature of the file */
1140 hFile = CreateFileA( pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, -1 );
1141 if (INVALID_HANDLE_VALUE != hFile)
1143 HANDLE hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
1146 LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
1149 /* first try to load as *.tlb */
1150 dwSignature = *((DWORD*) pBase);
1151 if ( dwSignature == MSFT_SIGNATURE)
1153 /* retrieve file size */
1154 DWORD dwTLBLength = GetFileSize(hFile, NULL);
1156 *ppTypeLib = ITypeLib2_Constructor(pBase, dwTLBLength);
1158 UnmapViewOfFile(pBase);
1160 CloseHandle(hMapping);
1165 if( (WORD)dwSignature == IMAGE_DOS_SIGNATURE )
1167 /* find the typelibrary resource*/
1168 HINSTANCE hinstDLL = LoadLibraryExA(pszFileName, 0, DONT_RESOLVE_DLL_REFERENCES|
1169 LOAD_LIBRARY_AS_DATAFILE|LOAD_WITH_ALTERED_SEARCH_PATH);
1172 HRSRC hrsrc = FindResourceA(hinstDLL, MAKEINTRESOURCEA(1), "TYPELIB");
1175 HGLOBAL hGlobal = LoadResource(hinstDLL, hrsrc);
1178 LPVOID pBase = LockResource(hGlobal);
1179 DWORD dwTLBLength = SizeofResource(hinstDLL, hrsrc);
1183 /* try to load as incore resource */
1184 dwSignature = *((DWORD*) pBase);
1185 if ( dwSignature == MSFT_SIGNATURE)
1186 *ppTypeLib = ITypeLib2_Constructor(pBase, dwTLBLength);
1188 FIXME("Header type magic 0x%08lx not supported.\n",dwSignature);
1190 FreeResource( hGlobal );
1193 FreeLibrary(hinstDLL);
1200 ERR("Loading of typelib %s failed with error 0x%08lx\n", pszFileName, GetLastError());
1205 /*================== ITypeLib(2) Methods ===================================*/
1207 /****************************************************************************
1208 * ITypeLib2_Constructor
1210 * loading a typelib from a in-memory image
1212 static ITypeLib2* ITypeLib2_Constructor(LPVOID pLib, DWORD dwTLBLength)
1216 TLB2Header tlbHeader;
1217 TLBSegDir tlbSegDir;
1218 ITypeLibImpl * pTypeLibImpl;
1220 TRACE("%p, TLB length = %ld\n", pLib, dwTLBLength);
1222 pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
1223 if (!pTypeLibImpl) return NULL;
1225 ICOM_VTBL(pTypeLibImpl) = &tlbvt;
1226 pTypeLibImpl->ref = 1;
1228 /* get pointer to beginning of typelib data */
1232 cx.pLibInfo = pTypeLibImpl;
1233 cx.length = dwTLBLength;
1236 TLB_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
1238 TRACE("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2 );
1239 if (memcmp(&tlbHeader.magic1,TLBMAGIC2,4)) {
1240 FIXME("Header type magic 0x%08x not supported.\n",tlbHeader.magic1);
1243 /* there is a small number of information here until the next important
1245 * the segment directory . Try to calculate the amount of data */
1246 lPSegDir = sizeof(tlbHeader) + (tlbHeader.nrtypeinfos)*4 + ((tlbHeader.varflags & HELPDLLFLAG)? 4 :0);
1248 /* now read the segment directory */
1249 TRACE("read segment directory (at %ld)\n",lPSegDir);
1250 TLB_Read((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
1251 cx.pTblDir = &tlbSegDir;
1253 /* just check two entries */
1254 if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F || tlbSegDir.pImpInfo.res0c != 0x0F)
1256 ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir);
1257 HeapFree(GetProcessHeap(),0,pTypeLibImpl);
1261 /* now fill our internal data */
1262 /* TLIBATTR fields */
1263 TLB_ReadGuid(&pTypeLibImpl->LibAttr.guid, tlbHeader.posguid, &cx);
1264 pTypeLibImpl->LibAttr.lcid = tlbHeader.lcid;
1265 pTypeLibImpl->LibAttr.syskind = tlbHeader.varflags & 0x0f; /* check the mask */
1266 pTypeLibImpl->LibAttr.wMajorVerNum = LOWORD(tlbHeader.version);
1267 pTypeLibImpl->LibAttr.wMinorVerNum = HIWORD(tlbHeader.version);
1268 pTypeLibImpl->LibAttr.wLibFlags = (WORD) tlbHeader.flags & 0xffff;/* check mask */
1270 /* name, eventually add to a hash table */
1271 pTypeLibImpl->Name = TLB_ReadName(&cx, tlbHeader.NameOffset);
1274 pTypeLibImpl->DocString = TLB_ReadString(&cx, tlbHeader.helpstring);
1275 pTypeLibImpl->HelpFile = TLB_ReadString(&cx, tlbHeader.helpfile);
1277 if( tlbHeader.varflags & HELPDLLFLAG)
1280 TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
1281 pTypeLibImpl->HelpStringDll = TLB_ReadString(&cx, offset);
1284 pTypeLibImpl->dwHelpContext = tlbHeader.helpstringcontext;
1287 if(tlbHeader.CustomDataOffset >= 0)
1289 pTypeLibImpl->ctCustData = TLB_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->pCustData);
1292 /* fill in typedescriptions */
1293 if(tlbSegDir.pTypdescTab.length > 0)
1295 int i, j, cTD = tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
1297 pTypeLibImpl->pTypeDesc = TLB_Alloc( cTD * sizeof(TYPEDESC));
1298 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
1301 /* FIXME: add several sanity checks here */
1302 pTypeLibImpl->pTypeDesc[i].vt = td[0] & VT_TYPEMASK;
1303 if(td[0] == VT_PTR || td[0] == VT_SAFEARRAY)
1305 /* FIXME: check safearray */
1307 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lptdesc)= & stndTypeDesc[td[2]];
1309 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lptdesc)= & pTypeLibImpl->pTypeDesc[td[2]/8];
1311 else if(td[0] == VT_CARRAY)
1313 /* array descr table here */
1314 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = (void *)((int) td[2]); /* temp store offset in*/
1316 else if(td[0] == VT_USERDEFINED)
1318 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),hreftype) = MAKELONG(td[2],td[3]);
1320 if(++i<cTD) TLB_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
1323 /* second time around to fill the array subscript info */
1326 if(pTypeLibImpl->pTypeDesc[i].vt != VT_CARRAY) continue;
1327 if(tlbSegDir.pArrayDescriptions.offset>0)
1329 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (int) V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc));
1330 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
1333 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->tdescElem.vt = td[0] & VT_TYPEMASK;
1335 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->tdescElem = stndTypeDesc[td[0]/8];
1337 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->cDims = td[2];
1339 for(j = 0; j<td[2]; j++)
1341 TLB_Read(& V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->rgbounds[j].cElements,
1342 sizeof(INT), &cx, DO_NOT_SEEK);
1343 TLB_Read(& V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->rgbounds[j].lLbound,
1344 sizeof(INT), &cx, DO_NOT_SEEK);
1349 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = NULL;
1350 ERR("didn't find array description data\n");
1355 /* imported type libs */
1356 if(tlbSegDir.pImpFiles.offset>0)
1358 TLBImpLib **ppImpLib = &(pTypeLibImpl->pImpLibs);
1359 int oGuid, offset = tlbSegDir.pImpFiles.offset;
1362 while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length)
1364 *ppImpLib = TLB_Alloc(sizeof(TLBImpLib));
1365 (*ppImpLib)->offset = offset - tlbSegDir.pImpFiles.offset;
1366 TLB_Read(&oGuid, sizeof(INT), &cx, offset);
1367 TLB_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
1369 /* we are skipping some unknown info here */
1370 TLB_Read(& size,sizeof(UINT16), &cx, offset+3*(sizeof(INT)));
1372 (*ppImpLib)->name = TLB_Alloc(size+1);
1373 TLB_Read((*ppImpLib)->name, size, &cx, DO_NOT_SEEK);
1374 offset = (offset + 3 * (sizeof(INT)) + sizeof(UINT16) + size + 3) & 0xfffffffc;
1376 ppImpLib = &(*ppImpLib)->next;
1381 if(tlbHeader.nrtypeinfos >= 0 )
1383 /*pTypeLibImpl->TypeInfoCount=tlbHeader.nrtypeinfos; */
1384 ITypeInfoImpl **ppTI = &(pTypeLibImpl->pTypeInfo);
1386 for(i = 0; i<(int)tlbHeader.nrtypeinfos; i++)
1388 *ppTI = TLB_DoTypeInfo(&cx, i, pTypeLibImpl);
1389 ppTI = &((*ppTI)->next);
1390 (pTypeLibImpl->TypeInfoCount)++;
1394 TRACE("(%p)\n", pTypeLibImpl);
1395 return (ITypeLib2*) pTypeLibImpl;
1398 /* ITypeLib::QueryInterface
1400 static HRESULT WINAPI ITypeLib2_fnQueryInterface(
1405 ICOM_THIS( ITypeLibImpl, iface);
1407 TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
1410 if(IsEqualIID(riid, &IID_IUnknown) ||
1411 IsEqualIID(riid,&IID_ITypeLib)||
1412 IsEqualIID(riid,&IID_ITypeLib2))
1419 ITypeLib2_AddRef(iface);
1420 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1423 TRACE("-- Interface: E_NOINTERFACE\n");
1424 return E_NOINTERFACE;
1429 static ULONG WINAPI ITypeLib2_fnAddRef( ITypeLib2 *iface)
1431 ICOM_THIS( ITypeLibImpl, iface);
1433 TRACE("(%p)->ref is %u\n",This, This->ref);
1435 return ++(This->ref);
1438 /* ITypeLib::Release
1440 static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
1442 ICOM_THIS( ITypeLibImpl, iface);
1444 TRACE("(%p)->(%u)\n",This, This->ref);
1448 /* fixme destroy child objects */
1450 TRACE(" destroying ITypeLib(%p)\n",This);
1452 HeapFree(GetProcessHeap(),0,This);
1458 /* ITypeLib::GetTypeInfoCount
1460 * Returns the number of type descriptions in the type library
1462 static UINT WINAPI ITypeLib2_fnGetTypeInfoCount( ITypeLib2 *iface)
1464 ICOM_THIS( ITypeLibImpl, iface);
1465 TRACE("(%p)->count is %d\n",This, This->TypeInfoCount);
1466 return This->TypeInfoCount;
1469 /* ITypeLib::GetTypeInfo
1471 * retrieves the specified type description in the library.
1473 static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(
1476 ITypeInfo **ppTInfo)
1479 ICOM_THIS( ITypeLibImpl, iface);
1480 ITypeInfoImpl *pTLBTInfo = This->pTypeInfo;
1482 TRACE("(%p)->(index=%d) \n",This, index);
1484 if (!ppTInfo) return E_INVALIDARG;
1486 /* search element n in list */
1487 for(i=0; i < index; i++)
1489 pTLBTInfo = pTLBTInfo->next;
1492 TRACE("-- element not found\n");
1493 return TYPE_E_ELEMENTNOTFOUND;
1497 *ppTInfo = (ITypeInfo *) pTLBTInfo;
1498 ITypeInfo_AddRef(*ppTInfo);
1499 TRACE("-- found (%p)\n",*ppTInfo);
1503 /* ITypeLibs::GetTypeInfoType
1505 * Retrieves the type of a type description.
1507 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType(
1512 ICOM_THIS( ITypeLibImpl, iface);
1514 ITypeInfoImpl *pTInfo = This->pTypeInfo;
1516 TRACE("(%p) index %d \n",This, index);
1518 if(!pTKind) return E_INVALIDARG;
1520 /* search element n in list */
1521 for(i=0; i < index; i++)
1525 TRACE("-- element not found\n");
1526 return TYPE_E_ELEMENTNOTFOUND;
1528 pTInfo = pTInfo->next;
1531 *pTKind = pTInfo->TypeAttr.typekind;
1532 TRACE("-- found Type (%d)\n", *pTKind);
1536 /* ITypeLib::GetTypeInfoOfGuid
1538 * Retrieves the type description that corresponds to the specified GUID.
1541 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(
1544 ITypeInfo **ppTInfo)
1546 ICOM_THIS( ITypeLibImpl, iface);
1547 ITypeInfoImpl *ppTLBTInfo = This->pTypeInfo; /* head of list */
1549 TRACE("(%p)\n\tguid:\t%s)\n",This,debugstr_guid(guid));
1551 /* serach linked list for guid */
1552 while( !IsEqualIID(guid,&ppTLBTInfo->TypeAttr.guid) )
1554 ppTLBTInfo = ppTLBTInfo->next;
1557 /* end of list reached */
1558 TRACE("-- element not found\n");
1559 return TYPE_E_ELEMENTNOTFOUND;
1563 TRACE("-- found (%p, %s)\n", ppTLBTInfo, ppTLBTInfo->Name);
1565 *ppTInfo = (ITypeInfo*)ppTLBTInfo;
1566 ITypeInfo_AddRef(*ppTInfo);
1570 /* ITypeLib::GetLibAttr
1572 * Retrieves the structure that contains the library's attributes.
1575 static HRESULT WINAPI ITypeLib2_fnGetLibAttr(
1577 LPTLIBATTR *ppTLibAttr)
1579 ICOM_THIS( ITypeLibImpl, iface);
1580 TRACE("(%p)\n",This);
1581 /* FIXME: must do a copy here */
1582 *ppTLibAttr=&This->LibAttr;
1586 /* ITypeLib::GetTypeComp
1588 * Enables a client compiler to bind to a library's types, variables,
1589 * constants, and global functions.
1592 static HRESULT WINAPI ITypeLib2_fnGetTypeComp(
1594 ITypeComp **ppTComp)
1596 ICOM_THIS( ITypeLibImpl, iface);
1597 FIXME("(%p): stub!\n",This);
1601 /* ITypeLib::GetDocumentation
1603 * Retrieves the library's documentation string, the complete Help file name
1604 * and path, and the context identifier for the library Help topic in the Help
1608 static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
1612 BSTR *pBstrDocString,
1613 DWORD *pdwHelpContext,
1614 BSTR *pBstrHelpFile)
1616 ICOM_THIS( ITypeLibImpl, iface);
1619 TRACE("(%p) index %d Name(%p) DocString(%p)"
1620 " HelpContext(%p) HelpFile(%p)\n",
1621 This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1622 if(index<0){ /* documentation for the typelib */
1624 *pBstrName=TLB_DupAtoBstr(This->Name);
1626 *pBstrDocString=TLB_DupAtoBstr(This->DocString);
1628 *pdwHelpContext=This->dwHelpContext;
1630 *pBstrHelpFile=TLB_DupAtoBstr(This->HelpFile);
1631 }else {/* for a typeinfo */
1632 result=ITypeLib2_fnGetTypeInfo(iface, index, &pTInfo);
1633 if(SUCCEEDED(result)){
1634 result=ITypeInfo_GetDocumentation(pTInfo, MEMBERID_NIL, pBstrName,
1635 pBstrDocString, pdwHelpContext, pBstrHelpFile);
1636 ITypeInfo_Release(pTInfo);
1638 if(!SUCCEEDED(result))
1646 * Indicates whether a passed-in string contains the name of a type or member
1647 * described in the library.
1650 static HRESULT WINAPI ITypeLib2_fnIsName(
1656 ICOM_THIS( ITypeLibImpl, iface);
1657 ITypeInfoImpl *pTInfo;
1658 TLBFuncDesc *pFInfo;
1661 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1663 TRACE("(%p)->(%s,%08lx,%p)\n", This, debugstr_w(szNameBuf), lHashVal,
1667 if(!strcmp(astr,This->Name)) goto ITypeLib2_fnIsName_exit;
1668 for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){
1669 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib2_fnIsName_exit;
1670 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1671 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib2_fnIsName_exit;
1672 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1673 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1674 goto ITypeLib2_fnIsName_exit;
1676 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next)
1677 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib2_fnIsName_exit;
1682 ITypeLib2_fnIsName_exit:
1683 TRACE("(%p)slow! search for %s: %s found!\n", This,
1684 debugstr_a(astr), *pfName?"NOT":"");
1686 HeapFree( GetProcessHeap(), 0, astr );
1690 /* ITypeLib::FindName
1692 * Finds occurrences of a type description in a type library. This may be used
1693 * to quickly verify that a name exists in a type library.
1696 static HRESULT WINAPI ITypeLib2_fnFindName(
1700 ITypeInfo **ppTInfo,
1704 ICOM_THIS( ITypeLibImpl, iface);
1705 ITypeInfoImpl *pTInfo;
1706 TLBFuncDesc *pFInfo;
1709 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1710 for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){
1711 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib2_fnFindName_exit;
1712 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1713 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib2_fnFindName_exit;
1714 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1715 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1716 goto ITypeLib2_fnFindName_exit;
1718 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
1719 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib2_fnFindName_exit;
1721 ITypeLib2_fnFindName_exit:
1722 ITypeInfo_AddRef((ITypeInfo*)pTInfo);
1723 ppTInfo[j]=(LPTYPEINFO)pTInfo;
1726 TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
1727 This, *pcFound, debugstr_a(astr), j);
1731 HeapFree( GetProcessHeap(), 0, astr );
1735 /* ITypeLib::ReleaseTLibAttr
1737 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
1740 static VOID WINAPI ITypeLib2_fnReleaseTLibAttr(
1742 TLIBATTR *pTLibAttr)
1744 ICOM_THIS( ITypeLibImpl, iface);
1745 TRACE("freeing (%p)\n",This);
1749 /* ITypeLib2::GetCustData
1751 * gets the custom data
1753 static HRESULT WINAPI ITypeLib2_fnGetCustData(
1758 ICOM_THIS( ITypeLibImpl, iface);
1759 TLBCustData *pCData;
1761 for(pCData=This->pCustData; pCData; pCData = pCData->next)
1763 if( IsEqualIID(guid, &pCData->guid)) break;
1766 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
1770 VariantInit( pVarVal);
1771 VariantCopy( pVarVal, &pCData->data);
1774 return E_INVALIDARG; /* FIXME: correct? */
1777 /* ITypeLib2::GetLibStatistics
1779 * Returns statistics about a type library that are required for efficient
1780 * sizing of hash tables.
1783 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(
1785 ULONG *pcUniqueNames,
1786 ULONG *pcchUniqueNames)
1788 ICOM_THIS( ITypeLibImpl, iface);
1790 FIXME("(%p): stub!\n", This);
1792 if(pcUniqueNames) *pcUniqueNames=1;
1793 if(pcchUniqueNames) *pcchUniqueNames=1;
1797 /* ITypeLib2::GetDocumentation2
1799 * Retrieves the library's documentation string, the complete Help file name
1800 * and path, the localization context to use, and the context ID for the
1801 * library Help topic in the Help file.
1804 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
1808 BSTR *pbstrHelpString,
1809 DWORD *pdwHelpStringContext,
1810 BSTR *pbstrHelpStringDll)
1812 ICOM_THIS( ITypeLibImpl, iface);
1816 FIXME("(%p) index %d lcid %ld half implemented stub!\n", This, index, lcid);
1818 /* the help string should be obtained from the helpstringdll,
1819 * using the _DLLGetDocumentation function, based on the supplied
1820 * lcid. Nice to do sometime...
1824 /* documentation for the typelib */
1826 *pbstrHelpString=TLB_DupAtoBstr(This->DocString);
1827 if(pdwHelpStringContext)
1828 *pdwHelpStringContext=This->dwHelpContext;
1829 if(pbstrHelpStringDll)
1830 *pbstrHelpStringDll=TLB_DupAtoBstr(This->HelpStringDll);
1834 /* for a typeinfo */
1835 result=ITypeLib2_GetTypeInfo(iface, index, &pTInfo);
1836 if(SUCCEEDED(result))
1838 ITypeInfo2 * pTInfo2;
1839 result = ITypeInfo_QueryInterface(pTInfo, &IID_ITypeInfo2, (LPVOID*) &pTInfo2);
1840 if(SUCCEEDED(result))
1842 result = ITypeInfo2_GetDocumentation2(pTInfo2, MEMBERID_NIL, lcid,
1843 pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
1844 ITypeInfo2_Release(pTInfo);
1846 ITypeInfo_Release(pTInfo);
1848 if(!SUCCEEDED(result))
1854 /* ITypeLib2::GetAllCustData
1856 * Gets all custom data items for the library.
1859 static HRESULT WINAPI ITypeLib2_fnGetAllCustData(
1861 CUSTDATA *pCustData)
1863 ICOM_THIS( ITypeLibImpl, iface);
1864 TLBCustData *pCData;
1866 TRACE("(%p) returning %d items\n", This, This->ctCustData);
1867 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
1868 if(pCustData->prgCustData ){
1869 pCustData->cCustData=This->ctCustData;
1870 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
1871 pCustData->prgCustData[i].guid=pCData->guid;
1872 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
1875 ERR(" OUT OF MEMORY! \n");
1876 return E_OUTOFMEMORY;
1881 static ICOM_VTABLE(ITypeLib2) tlbvt = {
1882 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1883 ITypeLib2_fnQueryInterface,
1885 ITypeLib2_fnRelease,
1886 ITypeLib2_fnGetTypeInfoCount,
1887 ITypeLib2_fnGetTypeInfo,
1888 ITypeLib2_fnGetTypeInfoType,
1889 ITypeLib2_fnGetTypeInfoOfGuid,
1890 ITypeLib2_fnGetLibAttr,
1891 ITypeLib2_fnGetTypeComp,
1892 ITypeLib2_fnGetDocumentation,
1894 ITypeLib2_fnFindName,
1895 ITypeLib2_fnReleaseTLibAttr,
1897 ITypeLib2_fnGetCustData,
1898 ITypeLib2_fnGetLibStatistics,
1899 ITypeLib2_fnGetDocumentation2,
1900 ITypeLib2_fnGetAllCustData
1903 /*================== ITypeInfo(2) Methods ===================================*/
1904 static ITypeInfo2 * WINAPI ITypeInfo_Constructor(void)
1906 ITypeInfoImpl * pTypeInfoImpl;
1908 pTypeInfoImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeInfoImpl));
1911 ICOM_VTBL(pTypeInfoImpl) = &tinfvt;
1912 pTypeInfoImpl->ref=1;
1914 TRACE("(%p)\n", pTypeInfoImpl);
1915 return (ITypeInfo2*) pTypeInfoImpl;
1918 /* ITypeInfo::QueryInterface
1920 static HRESULT WINAPI ITypeInfo_fnQueryInterface(
1925 ICOM_THIS( ITypeLibImpl, iface);
1927 TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
1930 if(IsEqualIID(riid, &IID_IUnknown) ||
1931 IsEqualIID(riid,&IID_ITypeInfo)||
1932 IsEqualIID(riid,&IID_ITypeInfo2))
1936 ITypeInfo_AddRef(iface);
1937 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1940 TRACE("-- Interface: E_NOINTERFACE\n");
1941 return E_NOINTERFACE;
1944 /* ITypeInfo::AddRef
1946 static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface)
1948 ICOM_THIS( ITypeInfoImpl, iface);
1949 TRACE("(%p)->ref is %u\n",This, This->ref);
1950 ITypeLib2_AddRef((ITypeLib*)This->pTypeLib);
1951 return ++(This->ref);
1954 /* ITypeInfo::Release
1956 static ULONG WINAPI ITypeInfo_fnRelease( ITypeInfo2 *iface)
1958 ICOM_THIS( ITypeInfoImpl, iface);
1959 FIXME("(%p)->ref is %u: stub\n",This, This->ref);
1960 TRACE("(%p)->(%u)\n",This, This->ref);
1962 ITypeLib2_Release((ITypeLib*)This->pTypeLib);
1966 /* fixme destroy child objects */
1968 TRACE(" destroying ITypeInfo(%p)\n",This);
1970 HeapFree(GetProcessHeap(),0,This);
1976 /* ITypeInfo::GetTypeAttr
1978 * Retrieves a TYPEATTR structure that contains the attributes of the type
1982 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface,
1983 LPTYPEATTR *ppTypeAttr)
1985 ICOM_THIS( ITypeInfoImpl, iface);
1986 TRACE("(%p)\n",This);
1987 /* FIXME: must do a copy here */
1988 *ppTypeAttr=&This->TypeAttr;
1992 /* ITypeInfo::GetTypeComp
1994 * Retrieves the ITypeComp interface for the type description, which enables a
1995 * client compiler to bind to the type description's members.
1998 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( ITypeInfo2 *iface,
1999 ITypeComp * *ppTComp)
2001 ICOM_THIS( ITypeInfoImpl, iface);
2002 FIXME("(%p) stub!\n", This);
2006 /* ITypeInfo::GetFuncDesc
2008 * Retrieves the FUNCDESC structure that contains information about a
2009 * specified function.
2012 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( ITypeInfo2 *iface, UINT index,
2013 LPFUNCDESC *ppFuncDesc)
2015 ICOM_THIS( ITypeInfoImpl, iface);
2017 TLBFuncDesc * pFDesc;
2018 TRACE("(%p) index %d\n", This, index);
2019 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
2022 /* FIXME: must do a copy here */
2023 *ppFuncDesc=&pFDesc->funcdesc;
2026 return E_INVALIDARG;
2029 /* ITypeInfo::GetVarDesc
2031 * Retrieves a VARDESC structure that describes the specified variable.
2034 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( ITypeInfo2 *iface, UINT index,
2035 LPVARDESC *ppVarDesc)
2037 ICOM_THIS( ITypeInfoImpl, iface);
2039 TLBVarDesc * pVDesc;
2040 TRACE("(%p) index %d\n", This, index);
2041 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next)
2044 /* FIXME: must do a copy here */
2045 *ppVarDesc=&pVDesc->vardesc;
2048 return E_INVALIDARG;
2051 /* ITypeInfo_GetNames
2053 * Retrieves the variable with the specified member ID (or the name of the
2054 * property or method and its parameters) that correspond to the specified
2057 static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
2058 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
2060 ICOM_THIS( ITypeInfoImpl, iface);
2061 TLBFuncDesc * pFDesc;
2062 TLBVarDesc * pVDesc;
2064 TRACE("(%p) memid=0x%08lx Maxname=%d\n", This, memid, cMaxNames);
2065 for(pFDesc=This->funclist; pFDesc && pFDesc->funcdesc.memid != memid; pFDesc=pFDesc->next);
2068 /* function found, now return function and parameter names */
2069 for(i=0; i<cMaxNames && i <= pFDesc->funcdesc.cParams; i++)
2072 *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
2074 rgBstrNames[i]=TLB_DupAtoBstr(pFDesc->pParamDesc[i-1].Name);
2080 for(pVDesc=This->varlist; pVDesc && pVDesc->vardesc.memid != memid; pVDesc=pVDesc->next);
2083 *rgBstrNames=TLB_DupAtoBstr(pVDesc->Name);
2088 if(This->TypeAttr.typekind==TKIND_INTERFACE && This->TypeAttr.cImplTypes )
2090 /* recursive search */
2093 result=ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->reference, &pTInfo);
2094 if(SUCCEEDED(result))
2096 result=ITypeInfo_GetNames(pTInfo, memid, rgBstrNames, cMaxNames, pcNames);
2097 ITypeInfo_Release(pTInfo);
2100 WARN("Could not search inherited interface!\n");
2104 WARN("no names found\n");
2107 return TYPE_E_ELEMENTNOTFOUND;
2114 /* ITypeInfo::GetRefTypeOfImplType
2116 * If a type description describes a COM class, it retrieves the type
2117 * description of the implemented interface types. For an interface,
2118 * GetRefTypeOfImplType returns the type information for inherited interfaces,
2122 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType(
2127 ICOM_THIS( ITypeInfoImpl, iface);
2129 TLBRefType *pIref = This->impltypelist;
2131 TRACE("(%p) index %d\n", This, index);
2132 dump_TypeInfo(This);
2142 /* get the retated interface for this dispinterface */
2143 if( This->TypeAttr.typekind != TKIND_DISPATCH) return E_INVALIDARG;
2144 FIXME("TKIND_INTERFACE expected\n");
2145 return TYPE_E_ELEMENTNOTFOUND;
2148 /* get element n from linked list */
2149 for(i=0; i<index; i++)
2151 if (!pIref) return TYPE_E_ELEMENTNOTFOUND;
2152 pIref = pIref->next;
2155 *pRefType = pIref->reference;
2156 TRACE("-- 0x%08lx %s\n",pIref->reference, debugstr_guid(&pIref->guid) );
2160 /* ITypeInfo::GetImplTypeFlags
2162 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
2163 * or base interface in a type description.
2165 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( ITypeInfo2 *iface,
2166 UINT index, INT *pImplTypeFlags)
2168 ICOM_THIS( ITypeInfoImpl, iface);
2171 TRACE("(%p) index %d\n", This, index);
2172 for(i=0, pIref=This->impltypelist; i<index && pIref; i++, pIref=pIref->next)
2174 if(i==index && pIref){
2175 *pImplTypeFlags=pIref->flags;
2179 return TYPE_E_ELEMENTNOTFOUND;
2183 * Maps between member names and member IDs, and parameter names and
2186 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface,
2187 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
2189 ICOM_THIS( ITypeInfoImpl, iface);
2190 TLBFuncDesc * pFDesc;
2191 TLBVarDesc * pVDesc;
2193 PCHAR aszName= HEAP_strdupWtoA( GetProcessHeap(), 0, *rgszNames);
2194 TRACE("(%p) Name %s cNames %d\n", This, debugstr_a(aszName),
2196 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) {
2198 if( !strcmp(aszName, pFDesc->Name)) {
2199 if(cNames) *pMemId=pFDesc->funcdesc.memid;
2200 for(i=1; i < cNames; i++){
2201 PCHAR aszPar= HEAP_strdupWtoA( GetProcessHeap(), 0,
2203 for(j=0; j<pFDesc->funcdesc.cParams; j++)
2204 if(strcmp(aszPar,pFDesc->pParamDesc[j].Name))
2206 if( j<pFDesc->funcdesc.cParams)
2209 ret=DISP_E_UNKNOWNNAME;
2210 HeapFree( GetProcessHeap(), 0, aszPar);
2212 HeapFree (GetProcessHeap(), 0, aszName);
2216 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
2217 if( !strcmp(aszName, pVDesc->Name)) {
2218 if(cNames) *pMemId=pVDesc->vardesc.memid;
2219 HeapFree (GetProcessHeap(), 0, aszName);
2223 /* not found, see if this is and interface with an inheritance */
2224 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
2225 This->TypeAttr.cImplTypes ){
2226 /* recursive search */
2228 ret=ITypeInfo_GetRefTypeInfo(iface,
2229 This->impltypelist->reference, &pTInfo);
2231 ret=ITypeInfo_GetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
2232 ITypeInfo_Release(pTInfo);
2235 WARN("Could not search inherited interface!\n");
2237 WARN("no names found\n");
2238 return DISP_E_UNKNOWNNAME;
2241 /* ITypeInfo::Invoke
2243 * Invokes a method, or accesses a property of an object, that implements the
2244 * interface described by the type description.
2246 static HRESULT WINAPI ITypeInfo_fnInvoke(
2251 DISPPARAMS *pDispParams,
2252 VARIANT *pVarResult,
2253 EXCEPINFO *pExcepInfo,
2256 ICOM_THIS( ITypeInfoImpl, iface);
2257 FIXME("(%p)(%p,id=0x%08lx,0x%08x,%p,%p,%p,%p) stub!\n",
2258 This, pIUnk, memid, dwFlags, pDispParams, pVarResult, pExcepInfo, pArgErr );
2259 dump_DispParms(pDispParams);
2263 /* ITypeInfo::GetDocumentation
2265 * Retrieves the documentation string, the complete Help file name and path,
2266 * and the context ID for the Help topic for a specified type description.
2268 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( ITypeInfo2 *iface,
2269 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
2270 DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
2272 ICOM_THIS( ITypeInfoImpl, iface);
2273 TLBFuncDesc * pFDesc;
2274 TLBVarDesc * pVDesc;
2275 TRACE("(%p) memid %ld Name(%p) DocString(%p)"
2276 " HelpContext(%p) HelpFile(%p)\n",
2277 This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
2278 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
2280 *pBstrName=TLB_DupAtoBstr(This->Name);
2282 *pBstrDocString=TLB_DupAtoBstr(This->DocString);
2284 *pdwHelpContext=This->dwHelpContext;
2286 *pBstrHelpFile=TLB_DupAtoBstr(This->DocString);/* FIXME */
2288 }else {/* for a member */
2289 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
2290 if(pFDesc->funcdesc.memid==memid){
2293 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
2294 if(pVDesc->vardesc.memid==memid){
2298 return TYPE_E_ELEMENTNOTFOUND;
2301 /* ITypeInfo::GetDllEntry
2303 * Retrieves a description or specification of an entry point for a function
2306 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid,
2307 INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
2310 ICOM_THIS( ITypeInfoImpl, iface);
2311 FIXME("(%p) stub!\n", This);
2315 /* ITypeInfo::GetRefTypeInfo
2317 * If a type description references other type descriptions, it retrieves
2318 * the referenced type descriptions.
2320 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
2323 ITypeInfo **ppTInfo)
2325 ICOM_THIS( ITypeInfoImpl, iface);
2328 if(HREFTYPE_INTHISFILE(hRefType))
2332 result = ITypeInfo_GetContainingTypeLib(iface, &pTLib, &Index);
2333 if(SUCCEEDED( result ))
2335 result=ITypeLib2_GetTypeInfo(pTLib, HREFTYPE_INDEX(hRefType), ppTInfo);
2336 ITypeLib2_Release(pTLib );
2341 /* imported type lib */
2342 TLBRefType * pRefType;
2343 ITypeLibImpl *pTypeLib;
2344 for( pRefType=This->impltypelist; pRefType &&
2345 pRefType->reference != hRefType; pRefType=pRefType->next);
2347 return TYPE_E_ELEMENTNOTFOUND; /* FIXME : correct? */
2349 pTypeLib = pRefType->pImpTLInfo->pImpTypeLib;
2350 if(pTypeLib) /* typelib already loaded */
2352 result=ITypeLib2_GetTypeInfoOfGuid(
2353 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
2357 result = LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
2359 (LPTYPELIB *)&pTypeLib);
2360 if(!SUCCEEDED(result))
2362 BSTR libnam=TLB_DupAtoBstr(pRefType->pImpTLInfo->name);
2363 result=LoadTypeLib(libnam, (LPTYPELIB *)&pTypeLib);
2364 SysFreeString(libnam);
2366 if(SUCCEEDED(result))
2368 result=ITypeLib2_GetTypeInfoOfGuid((LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
2369 pRefType->pImpTLInfo->pImpTypeLib = pTypeLib;
2373 TRACE("(%p) hreftype 0x%04lx loaded %s (%p)\n", This, hRefType,
2374 SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
2378 /* ITypeInfo::AddressOfMember
2380 * Retrieves the addresses of static functions or variables, such as those
2383 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface,
2384 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
2386 ICOM_THIS( ITypeInfoImpl, iface);
2387 FIXME("(%p) stub!\n", This);
2391 /* ITypeInfo::CreateInstance
2393 * Creates a new instance of a type that describes a component object class
2396 static HRESULT WINAPI ITypeInfo_fnCreateInstance( ITypeInfo2 *iface,
2397 IUnknown *pUnk, REFIID riid, VOID **ppvObj)
2399 ICOM_THIS( ITypeInfoImpl, iface);
2400 FIXME("(%p) stub!\n", This);
2404 /* ITypeInfo::GetMops
2406 * Retrieves marshaling information.
2408 static HRESULT WINAPI ITypeInfo_fnGetMops( ITypeInfo2 *iface, MEMBERID memid,
2411 ICOM_THIS( ITypeInfoImpl, iface);
2412 FIXME("(%p) stub!\n", This);
2416 /* ITypeInfo::GetContainingTypeLib
2418 * Retrieves the containing type library and the index of the type description
2419 * within that type library.
2421 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( ITypeInfo2 *iface,
2422 ITypeLib * *ppTLib, UINT *pIndex)
2424 ICOM_THIS( ITypeInfoImpl, iface);
2425 *ppTLib=(LPTYPELIB )(This->pTypeLib);
2426 *pIndex=This->index;
2427 ITypeLib2_AddRef(*ppTLib);
2428 TRACE("(%p) returns (%p) index %d!\n", This, *ppTLib, *pIndex);
2432 /* ITypeInfo::ReleaseTypeAttr
2434 * Releases a TYPEATTR previously returned by GetTypeAttr.
2437 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( ITypeInfo2 *iface,
2438 TYPEATTR* pTypeAttr)
2440 ICOM_THIS( ITypeInfoImpl, iface);
2441 TRACE("(%p)->(%p)\n", This, pTypeAttr);
2445 /* ITypeInfo::ReleaseFuncDesc
2447 * Releases a FUNCDESC previously returned by GetFuncDesc. *
2449 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc(
2451 FUNCDESC *pFuncDesc)
2453 ICOM_THIS( ITypeInfoImpl, iface);
2454 TRACE("(%p)->(%p)\n", This, pFuncDesc);
2458 /* ITypeInfo::ReleaseVarDesc
2460 * Releases a VARDESC previously returned by GetVarDesc.
2462 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( ITypeInfo2 *iface,
2465 ICOM_THIS( ITypeInfoImpl, iface);
2466 TRACE("(%p)->(%p)\n", This, pVarDesc);
2470 /* ITypeInfo2::GetTypeKind
2472 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
2475 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo2 * iface,
2476 TYPEKIND *pTypeKind)
2478 ICOM_THIS( ITypeInfoImpl, iface);
2479 *pTypeKind=This->TypeAttr.typekind;
2480 TRACE("(%p) type 0x%0x\n", This,*pTypeKind);
2484 /* ITypeInfo2::GetTypeFlags
2486 * Returns the type flags without any allocations. This returns a DWORD type
2487 * flag, which expands the type flags without growing the TYPEATTR (type
2491 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo2 * iface,
2494 ICOM_THIS( ITypeInfoImpl, iface);
2495 *pTypeFlags=This->TypeAttr.wTypeFlags;
2496 TRACE("(%p) flags 0x%04x\n", This,*pTypeFlags);
2500 /* ITypeInfo2::GetFuncIndexOfMemId
2501 * Binds to a specific member based on a known DISPID, where the member name
2502 * is not known (for example, when binding to a default member).
2505 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2 * iface,
2506 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
2508 ICOM_THIS( ITypeInfoImpl, iface);
2509 TLBFuncDesc *pFuncInfo;
2512 /* FIXME: should check for invKind??? */
2513 for(i=0, pFuncInfo=This->funclist;pFuncInfo &&
2514 memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next);
2520 result=E_INVALIDARG;
2522 TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This,
2523 memid, invKind, SUCCEEDED(result)? "SUCCES":"FAILED");
2527 /* TypeInfo2::GetVarIndexOfMemId
2529 * Binds to a specific member based on a known DISPID, where the member name
2530 * is not known (for example, when binding to a default member).
2533 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo2 * iface,
2534 MEMBERID memid, UINT *pVarIndex)
2536 ICOM_THIS( ITypeInfoImpl, iface);
2537 TLBVarDesc *pVarInfo;
2540 for(i=0, pVarInfo=This->varlist; pVarInfo &&
2541 memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next)
2548 result=E_INVALIDARG;
2550 TRACE("(%p) memid 0x%08lx -> %s\n", This,
2551 memid, SUCCEEDED(result)? "SUCCES":"FAILED");
2555 /* ITypeInfo2::GetCustData
2557 * Gets the custom data
2559 static HRESULT WINAPI ITypeInfo2_fnGetCustData(
2564 ICOM_THIS( ITypeInfoImpl, iface);
2565 TLBCustData *pCData;
2567 for(pCData=This->pCustData; pCData; pCData = pCData->next)
2568 if( IsEqualIID(guid, &pCData->guid)) break;
2570 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2574 VariantInit( pVarVal);
2575 VariantCopy( pVarVal, &pCData->data);
2578 return E_INVALIDARG; /* FIXME: correct? */
2581 /* ITypeInfo2::GetFuncCustData
2583 * Gets the custom data
2585 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData(
2591 ICOM_THIS( ITypeInfoImpl, iface);
2592 TLBCustData *pCData=NULL;
2593 TLBFuncDesc * pFDesc;
2595 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2596 pFDesc=pFDesc->next);
2599 for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next)
2600 if( IsEqualIID(guid, &pCData->guid)) break;
2602 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2605 VariantInit( pVarVal);
2606 VariantCopy( pVarVal, &pCData->data);
2609 return E_INVALIDARG; /* FIXME: correct? */
2612 /* ITypeInfo2::GetParamCustData
2614 * Gets the custom data
2616 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData(
2623 ICOM_THIS( ITypeInfoImpl, iface);
2624 TLBCustData *pCData=NULL;
2625 TLBFuncDesc * pFDesc;
2628 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,pFDesc=pFDesc->next);
2630 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams)
2631 for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData;
2632 pCData = pCData->next)
2633 if( IsEqualIID(guid, &pCData->guid)) break;
2635 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2639 VariantInit( pVarVal);
2640 VariantCopy( pVarVal, &pCData->data);
2643 return E_INVALIDARG; /* FIXME: correct? */
2646 /* ITypeInfo2::GetVarcCustData
2648 * Gets the custom data
2650 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData(
2656 ICOM_THIS( ITypeInfoImpl, iface);
2657 TLBCustData *pCData=NULL;
2658 TLBVarDesc * pVDesc;
2661 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next);
2665 for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next)
2667 if( IsEqualIID(guid, &pCData->guid)) break;
2671 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2675 VariantInit( pVarVal);
2676 VariantCopy( pVarVal, &pCData->data);
2679 return E_INVALIDARG; /* FIXME: correct? */
2682 /* ITypeInfo2::GetImplcCustData
2684 * Gets the custom data
2686 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData(
2692 ICOM_THIS( ITypeInfoImpl, iface);
2693 TLBCustData *pCData=NULL;
2694 TLBRefType * pRDesc;
2697 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++, pRDesc=pRDesc->next);
2701 for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next)
2703 if( IsEqualIID(guid, &pCData->guid)) break;
2707 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2711 VariantInit( pVarVal);
2712 VariantCopy( pVarVal, &pCData->data);
2715 return E_INVALIDARG; /* FIXME: correct? */
2718 /* ITypeInfo2::GetDocumentation2
2720 * Retrieves the documentation string, the complete Help file name and path,
2721 * the localization context to use, and the context ID for the library Help
2722 * topic in the Help file.
2725 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(
2729 BSTR *pbstrHelpString,
2730 DWORD *pdwHelpStringContext,
2731 BSTR *pbstrHelpStringDll)
2733 ICOM_THIS( ITypeInfoImpl, iface);
2734 TLBFuncDesc * pFDesc;
2735 TLBVarDesc * pVDesc;
2736 TRACE("(%p) memid %ld lcid(0x%lx) HelpString(%p) "
2737 "HelpStringContext(%p) HelpStringDll(%p)\n",
2738 This, memid, lcid, pbstrHelpString, pdwHelpStringContext,
2739 pbstrHelpStringDll );
2740 /* the help string should be obtained from the helpstringdll,
2741 * using the _DLLGetDocumentation function, based on the supplied
2742 * lcid. Nice to do sometime...
2744 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
2746 *pbstrHelpString=TLB_DupAtoBstr(This->Name);
2747 if(pdwHelpStringContext)
2748 *pdwHelpStringContext=This->dwHelpStringContext;
2749 if(pbstrHelpStringDll)
2750 *pbstrHelpStringDll=
2751 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2753 }else {/* for a member */
2754 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
2755 if(pFDesc->funcdesc.memid==memid){
2757 *pbstrHelpString=TLB_DupAtoBstr(pFDesc->HelpString);
2758 if(pdwHelpStringContext)
2759 *pdwHelpStringContext=pFDesc->HelpStringContext;
2760 if(pbstrHelpStringDll)
2761 *pbstrHelpStringDll=
2762 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2765 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
2766 if(pVDesc->vardesc.memid==memid){
2768 *pbstrHelpString=TLB_DupAtoBstr(pVDesc->HelpString);
2769 if(pdwHelpStringContext)
2770 *pdwHelpStringContext=pVDesc->HelpStringContext;
2771 if(pbstrHelpStringDll)
2772 *pbstrHelpStringDll=
2773 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2777 return TYPE_E_ELEMENTNOTFOUND;
2780 /* ITypeInfo2::GetAllCustData
2782 * Gets all custom data items for the Type info.
2785 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData(
2787 CUSTDATA *pCustData)
2789 ICOM_THIS( ITypeInfoImpl, iface);
2790 TLBCustData *pCData;
2793 TRACE("(%p) returning %d items\n", This, This->ctCustData);
2795 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
2796 if(pCustData->prgCustData ){
2797 pCustData->cCustData=This->ctCustData;
2798 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
2799 pCustData->prgCustData[i].guid=pCData->guid;
2800 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
2803 ERR(" OUT OF MEMORY! \n");
2804 return E_OUTOFMEMORY;
2809 /* ITypeInfo2::GetAllFuncCustData
2811 * Gets all custom data items for the specified Function
2814 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData(
2817 CUSTDATA *pCustData)
2819 ICOM_THIS( ITypeInfoImpl, iface);
2820 TLBCustData *pCData;
2821 TLBFuncDesc * pFDesc;
2823 TRACE("(%p) index %d\n", This, index);
2824 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2825 pFDesc=pFDesc->next)
2828 pCustData->prgCustData =
2829 TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM));
2830 if(pCustData->prgCustData ){
2831 pCustData->cCustData=pFDesc->ctCustData;
2832 for(i=0, pCData=pFDesc->pCustData; pCData; i++,
2833 pCData = pCData->next){
2834 pCustData->prgCustData[i].guid=pCData->guid;
2835 VariantCopy(& pCustData->prgCustData[i].varValue,
2839 ERR(" OUT OF MEMORY! \n");
2840 return E_OUTOFMEMORY;
2844 return TYPE_E_ELEMENTNOTFOUND;
2847 /* ITypeInfo2::GetAllParamCustData
2849 * Gets all custom data items for the Functions
2852 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo2 * iface,
2853 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
2855 ICOM_THIS( ITypeInfoImpl, iface);
2856 TLBCustData *pCData=NULL;
2857 TLBFuncDesc * pFDesc;
2859 TRACE("(%p) index %d\n", This, indexFunc);
2860 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
2861 pFDesc=pFDesc->next)
2863 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams){
2864 pCustData->prgCustData =
2865 TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData *
2866 sizeof(CUSTDATAITEM));
2867 if(pCustData->prgCustData ){
2868 pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData;
2869 for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData;
2870 pCData; i++, pCData = pCData->next){
2871 pCustData->prgCustData[i].guid=pCData->guid;
2872 VariantCopy(& pCustData->prgCustData[i].varValue,
2876 ERR(" OUT OF MEMORY! \n");
2877 return E_OUTOFMEMORY;
2881 return TYPE_E_ELEMENTNOTFOUND;
2884 /* ITypeInfo2::GetAllVarCustData
2886 * Gets all custom data items for the specified Variable
2889 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo2 * iface,
2890 UINT index, CUSTDATA *pCustData)
2892 ICOM_THIS( ITypeInfoImpl, iface);
2893 TLBCustData *pCData;
2894 TLBVarDesc * pVDesc;
2896 TRACE("(%p) index %d\n", This, index);
2897 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2898 pVDesc=pVDesc->next)
2901 pCustData->prgCustData =
2902 TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM));
2903 if(pCustData->prgCustData ){
2904 pCustData->cCustData=pVDesc->ctCustData;
2905 for(i=0, pCData=pVDesc->pCustData; pCData; i++,
2906 pCData = pCData->next){
2907 pCustData->prgCustData[i].guid=pCData->guid;
2908 VariantCopy(& pCustData->prgCustData[i].varValue,
2912 ERR(" OUT OF MEMORY! \n");
2913 return E_OUTOFMEMORY;
2917 return TYPE_E_ELEMENTNOTFOUND;
2920 /* ITypeInfo2::GetAllImplCustData
2922 * Gets all custom data items for the specified implementation type
2925 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData(
2928 CUSTDATA *pCustData)
2930 ICOM_THIS( ITypeInfoImpl, iface);
2931 TLBCustData *pCData;
2932 TLBRefType * pRDesc;
2934 TRACE("(%p) index %d\n", This, index);
2935 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2936 pRDesc=pRDesc->next)
2939 pCustData->prgCustData =
2940 TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM));
2941 if(pCustData->prgCustData ){
2942 pCustData->cCustData=pRDesc->ctCustData;
2943 for(i=0, pCData=pRDesc->pCustData; pCData; i++,
2944 pCData = pCData->next){
2945 pCustData->prgCustData[i].guid=pCData->guid;
2946 VariantCopy(& pCustData->prgCustData[i].varValue,
2950 ERR(" OUT OF MEMORY! \n");
2951 return E_OUTOFMEMORY;
2955 return TYPE_E_ELEMENTNOTFOUND;
2958 static ICOM_VTABLE(ITypeInfo2) tinfvt =
2960 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2962 ITypeInfo_fnQueryInterface,
2964 ITypeInfo_fnRelease,
2966 ITypeInfo_fnGetTypeAttr,
2967 ITypeInfo_fnGetTypeComp,
2968 ITypeInfo_fnGetFuncDesc,
2969 ITypeInfo_fnGetVarDesc,
2970 ITypeInfo_fnGetNames,
2971 ITypeInfo_fnGetRefTypeOfImplType,
2972 ITypeInfo_fnGetImplTypeFlags,
2973 ITypeInfo_fnGetIDsOfNames,
2975 ITypeInfo_fnGetDocumentation,
2976 ITypeInfo_fnGetDllEntry,
2977 ITypeInfo_fnGetRefTypeInfo,
2978 ITypeInfo_fnAddressOfMember,
2979 ITypeInfo_fnCreateInstance,
2980 ITypeInfo_fnGetMops,
2981 ITypeInfo_fnGetContainingTypeLib,
2982 ITypeInfo_fnReleaseTypeAttr,
2983 ITypeInfo_fnReleaseFuncDesc,
2984 ITypeInfo_fnReleaseVarDesc,
2986 ITypeInfo2_fnGetTypeKind,
2987 ITypeInfo2_fnGetTypeFlags,
2988 ITypeInfo2_fnGetFuncIndexOfMemId,
2989 ITypeInfo2_fnGetVarIndexOfMemId,
2990 ITypeInfo2_fnGetCustData,
2991 ITypeInfo2_fnGetFuncCustData,
2992 ITypeInfo2_fnGetParamCustData,
2993 ITypeInfo2_fnGetVarCustData,
2994 ITypeInfo2_fnGetImplTypeCustData,
2995 ITypeInfo2_fnGetDocumentation2,
2996 ITypeInfo2_fnGetAllCustData,
2997 ITypeInfo2_fnGetAllFuncCustData,
2998 ITypeInfo2_fnGetAllParamCustData,
2999 ITypeInfo2_fnGetAllVarCustData,
3000 ITypeInfo2_fnGetAllImplTypeCustData,