4 * Copyright 1997 Marcus Meissner
6 * 2000 Francois Jacques
7 * --------------------------------------------------------------------------------------
8 * Known problems (2000, Francois Jacques)
10 * - Tested using OLEVIEW (Platform SDK tool) only.
12 * - dual interface dispinterfaces. vtable-interface ITypeInfo instances are
13 * creating by doing a straight copy of the dispinterface instance and just changing
14 * its typekind. Pointed structures aren't copied - only the address of the pointers.
15 * So when you release the dispinterface, you delete the vtable-interface structures
16 * as well... fortunately, clean up of structures is not implemented.
18 * - locale stuff is partially implemented but hasn't been tested.
20 * - imported typelib should be stored together in a linked list instead of having
21 * independant TLBImpLib structures in each ITypeInfo. This way, imported libraries
22 * are just imported once (major optimization)
24 * - typelib file is still read it's in entirety, but it is released now.
25 * - some garbage is read from function names on some very rare occasion
27 * --------------------------------------------------------------------------------------
28 * Known problems left from previous implementation (1999, Rein Klazes) :
30 * -. Only one format of typelibs is supported
31 * -. Data structures are straightforward, but slow for look-ups.
32 * -. (related) nothing is hashed
33 * -. there are a number of stubs in ITypeLib and ITypeInfo interfaces. Most
34 * of them I don't know yet how to implement them.
35 * -. Most error return values are just guessed not checked with windows
37 * -. didn't bother with a c++ interface
38 * -. lousy fatal error handling
39 * -. some methods just return pointers to internal data structures, this is
40 * partly laziness, partly I want to check how windows does it.
52 #include "winnls.h" /* for PRIMARYLANGID */
53 #include "winreg.h" /* for HKEY_LOCAL_MACHINE */
55 #include "wine/obj_base.h"
60 #include "debugtools.h"
62 DEFAULT_DEBUG_CHANNEL(ole);
63 DECLARE_DEBUG_CHANNEL(typelib);
65 /****************************************************************************
66 * QueryPathOfRegTypeLib [TYPELIB.14]
68 * the path is "Classes\Typelib\<guid>\<major>.<minor>\<lcid>\win16\"
73 QueryPathOfRegTypeLib16(
74 REFGUID guid, /* [in] referenced guid */
75 WORD wMaj, /* [in] major version */
76 WORD wMin, /* [in] minor version */
77 LCID lcid, /* [in] locale id */
78 LPBSTR16 path /* [out] path of typelib */
81 char typelibkey[100],pathname[260];
87 sprintf( typelibkey, "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win16",
88 guid->Data1, guid->Data2, guid->Data3,
89 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
90 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7],
93 sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
94 FIXME("(%s,%d,%d,0x%04lx,%p),can't handle non-string guids.\n",xguid,wMaj,wMin,(DWORD)lcid,path);
97 plen = sizeof(pathname);
98 if (RegQueryValueA(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
99 /* try again without lang specific id */
101 return QueryPathOfRegTypeLib16(guid,wMaj,wMin,PRIMARYLANGID(lcid),path);
102 FIXME("key %s not found\n",typelibkey);
105 *path = SysAllocString16(pathname);
109 /****************************************************************************
110 * QueryPathOfRegTypeLib [OLEAUT32.164]
115 QueryPathOfRegTypeLib(
116 REFGUID guid, /* [in] referenced guid */
117 WORD wMaj, /* [in] major version */
118 WORD wMin, /* [in] minor version */
119 LCID lcid, /* [in] locale id */
120 LPBSTR path ) /* [out] path of typelib */
122 /* don't need to ZeroMemory those arrays since sprintf and RegQueryValue add
123 string termination character on output strings */
127 DWORD dwPathLen = _MAX_PATH;
131 char szTypeLibKey[100];
132 char szPath[dwPathLen];
140 FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n", szXGUID, wMaj, wMin, (DWORD)lcid, path);
146 sprintf(szTypeLibKey,
147 "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win32",
148 guid->Data1, guid->Data2, guid->Data3,
149 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
150 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7],
155 if (RegQueryValueA(HKEY_LOCAL_MACHINE, szTypeLibKey, szPath, &dwPathLen))
159 else if (myLCID == lcid)
161 /* try with sub-langid */
162 myLCID = SUBLANGID(lcid);
164 else if ((myLCID == SUBLANGID(lcid)) && myLCID)
166 /* try with system langid */
176 DWORD len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPath, dwPathLen, NULL, 0 );
177 BSTR bstrPath = SysAllocStringLen(NULL,len);
179 MultiByteToWideChar(CP_ACP,
191 TRACE_(typelib)("%s not found\n", szTypeLibKey);
196 /******************************************************************************
197 * CreateTypeLib [OLEAUT32.160] creates a typelib
203 HRESULT WINAPI CreateTypeLib(
204 SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib** ppctlib
206 FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib);
209 /******************************************************************************
210 * LoadTypeLib [TYPELIB.3] Loads and registers a type library
212 * Docs: OLECHAR FAR* szFile
213 * Docs: iTypeLib FAR* FAR* pptLib
219 HRESULT WINAPI LoadTypeLib16(
220 LPOLESTR szFile, /* [in] Name of file to load from */
221 ITypeLib** pptLib) /* [out] Pointer to pointer to loaded type library */
223 FIXME("(%s,%p): stub\n",debugstr_w((LPWSTR)szFile),pptLib);
231 /******************************************************************************
232 * LoadTypeLib [OLEAUT32.161]
233 * Loads and registers a type library
235 * Docs: OLECHAR FAR* szFile
236 * Docs: iTypeLib FAR* FAR* pptLib
242 int TLB_ReadTypeLib(PCHAR file, ITypeLib2 **ppTypelib);
244 HRESULT WINAPI LoadTypeLib(
245 const OLECHAR *szFile,/* [in] Name of file to load from */
246 ITypeLib * *pptLib) /* [out] Pointer to pointer to loaded type library */
249 return LoadTypeLibEx(szFile, REGKIND_DEFAULT, pptLib);
252 /******************************************************************************
253 * LoadTypeLibEx [OLEAUT32.183]
254 * Loads and optionally registers a type library
260 HRESULT WINAPI LoadTypeLibEx(
261 LPCOLESTR szFile, /* [in] Name of file to load from */
262 REGKIND regkind, /* [in] Specify kind of registration */
263 ITypeLib **pptLib) /* [out] Pointer to pointer to loaded type library */
267 TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib);
269 p=HEAP_strdupWtoA(GetProcessHeap(),0,szFile);
271 res= TLB_ReadTypeLib(p, (ITypeLib2**)pptLib);
276 case REGKIND_DEFAULT:
277 /* FIXME: is this correct? */
278 if (!p || !p[0] || (p[0] != '\\' && p[0] != '/' && p[1] != ':'))
280 /* else fall-through */
281 case REGKIND_REGISTER:
282 /* FIXME: Help path? */
283 if (!SUCCEEDED(res = RegisterTypeLib(*pptLib, (LPOLESTR)szFile, NULL)))
285 IUnknown_Release(*pptLib);
293 HeapFree(GetProcessHeap(),0,p);
294 TRACE(" returns %08lx\n",res);
298 /******************************************************************************
299 * LoadRegTypeLib [OLEAUT32.162]
301 HRESULT WINAPI LoadRegTypeLib(
302 REFGUID rguid, /* [in] referenced guid */
303 WORD wVerMajor, /* [in] major version */
304 WORD wVerMinor, /* [in] minor version */
305 LCID lcid, /* [in] locale id */
306 ITypeLib **ppTLib) /* [out] path of typelib */
309 HRESULT res=QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor, lcid, &bstr);
313 res= LoadTypeLib(bstr, ppTLib);
317 TRACE("(IID: %s) load %s (%p)\n",debugstr_guid(rguid), SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);
323 /******************************************************************************
324 * RegisterTypeLib [OLEAUT32.163]
325 * Adds information about a type library to the System Registry
327 * Docs: ITypeLib FAR * ptlib
328 * Docs: OLECHAR FAR* szFullPath
329 * Docs: OLECHAR FAR* szHelpDir
335 HRESULT WINAPI RegisterTypeLib(
336 ITypeLib * ptlib, /* [in] Pointer to the library*/
337 OLECHAR * szFullPath, /* [in] full Path of the library*/
338 OLECHAR * szHelpDir) /* [in] dir to the helpfile for the library,
348 if (ptlib == NULL || szFullPath == NULL)
351 if (!SUCCEEDED(ITypeLib_GetLibAttr(ptlib, &attr)))
354 StringFromGUID2(&attr->guid, guid, 80);
355 guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid);
356 snprintf(keyName, sizeof(keyName), "TypeLib\\%s\\%x.%x",
357 guidA, attr->wMajorVerNum, attr->wMinorVerNum);
358 HeapFree(GetProcessHeap(), 0, guidA);
361 if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
362 KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS)
366 if (SUCCEEDED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL)))
368 if (RegSetValueExW(key, NULL, 0, REG_SZ,
369 (BYTE *)doc, lstrlenW(doc) * sizeof(OLECHAR)) != ERROR_SUCCESS)
377 /* FIXME: This *seems* to be 0 always, not sure though */
378 if (res == S_OK && RegCreateKeyExA(key, "0\\win32", 0, NULL, 0,
379 KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
381 if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
382 (BYTE *)szFullPath, lstrlenW(szFullPath) * sizeof(OLECHAR)) != ERROR_SUCCESS)
390 if (res == S_OK && RegCreateKeyExA(key, "FLAGS", 0, NULL, 0,
391 KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
394 /* FIXME: is %u correct? */
395 snprintf(buf, sizeof(buf), "%u", attr->wLibFlags);
396 if (RegSetValueExA(subKey, NULL, 0, REG_SZ,
397 buf, lstrlenA(buf) + 1) != ERROR_SUCCESS)
405 ITypeLib_ReleaseTLibAttr(ptlib, attr);
410 /******************************************************************************
411 * UnRegisterTypeLib [OLEAUT32.186]
412 * Removes information about a type library from the System Registry
419 HRESULT WINAPI UnRegisterTypeLib(
420 REFGUID libid, /* [in] Guid of the library */
421 WORD wVerMajor, /* [in] major version */
422 WORD wVerMinor, /* [in] minor version */
423 LCID lcid, /* [in] locale id */
426 TRACE("(IID: %s): stub\n",debugstr_guid(libid));
427 return S_OK; /* FIXME: pretend everything is OK */
430 /****************************************************************************
431 * OaBuildVersion (TYPELIB.15)
433 * known TYPELIB.DLL versions:
435 * OLE 2.01 no OaBuildVersion() avail 1993 -- ---
436 * OLE 2.02 1993-94 02 3002
439 * OLE 2.03 W98 SE orig. file !! 1993-95 10 3024
440 * OLE 2.1 NT 1993-95 ?? ???
441 * OLE 2.3.1 W95 23 700
442 * OLE2 4.0 NT4SP6 1993-98 40 4277
444 DWORD WINAPI OaBuildVersion16(void)
446 /* FIXME: I'd like to return the highest currently known version value
447 * in case the user didn't force a --winver, but I don't know how
448 * to retrieve the "versionForced" info from misc/version.c :(
449 * (this would be useful in other places, too) */
450 FIXME("Please report to a.mohr@mailto.de if you get version error messages !\n");
451 switch(GetVersion() & 0x8000ffff) /* mask off build number */
453 case 0x80000a03: /* WIN31 */
454 return MAKELONG(3027, 3); /* WfW 3.11 */
455 case 0x80000004: /* WIN95 */
456 return MAKELONG(700, 23); /* Win95A */
457 case 0x80000a04: /* WIN98 */
458 return MAKELONG(3024, 10); /* W98 SE */
459 case 0x00000004: /* NT4 */
460 return MAKELONG(4277, 40); /* NT4 SP6 */
462 FIXME("Version value not known yet. Please investigate it!\n");
467 /* for better debugging info leave the static out for the time being */
470 /*======================= ITypeLib implementation =======================*/
472 typedef struct tagTLBCustData
476 struct tagTLBCustData* next;
479 /* data structure for import typelibs */
480 typedef struct tagTLBImpLib
482 int offset; /* offset in the file */
483 GUID guid; /* libid */
484 BSTR name; /* name; */
486 LCID lcid; /* lcid of imported typelib */
488 WORD wVersionMajor; /* major version number */
489 WORD wVersionMinor; /* minor version number */
491 struct tagITypeLibImpl *pImpTypeLib; /* pointer to loaded typelib */
492 struct tagTLBImpLib * next;
495 /* internal ITypeLib data */
496 typedef struct tagITypeLibImpl
498 ICOM_VFIELD(ITypeLib2);
500 TLIBATTR LibAttr; /* guid,lcid,syskind,version,flags */
502 /* strings can be stored in tlb as multibyte strings BUT they are *always*
503 * exported to the application as a UNICODE string.
509 unsigned long dwHelpContext;
510 int TypeInfoCount; /* nr of typeinfo's in librarry */
511 struct tagITypeInfoImpl *pTypeInfo; /* linked list of type info data */
512 int ctCustData; /* number of items in cust data list */
513 TLBCustData * pCustData; /* linked list to cust data; */
514 TLBImpLib * pImpLibs; /* linked list to all imported typelibs */
515 TYPEDESC * pTypeDesc; /* array of TypeDescriptions found in the libary */
518 static struct ICOM_VTABLE(ITypeLib2) tlbvt;
520 /* ITypeLib methods */
521 static ITypeLib2* ITypeLib2_Constructor(LPVOID pLib, DWORD dwTLBLength);
523 /*======================= ITypeInfo implementation =======================*/
525 /* data for refernced types in a coclass, or an inherited interface */
526 typedef struct tagTLBRefType
528 GUID guid; /* guid of the referenced type */
529 /* (important if its a imported type) */
533 TLBCustData * pCustData;/* linked list to custom data; */
534 TLBImpLib *pImpTLInfo;
535 struct tagTLBRefType * next;
538 /* internal Parameter data */
539 typedef struct tagTLBParDesc
543 TLBCustData * pCustData; /* linked list to cust data; */
544 TLBRefType * pRefType; /* linked list to referenced types */
547 /* internal Function data */
548 typedef struct tagTLBFuncDesc
550 FUNCDESC funcdesc; /* lots of info on the function and its attributes. */
551 BSTR Name; /* the name of this function */
552 TLBParDesc *pParamDesc; /* array with name and custom data */
554 int HelpStringContext;
556 BSTR Entry; /* if its Hiword==0, it numeric; -1 is not present*/
558 TLBCustData * pCustData; /* linked list to cust data; */
559 struct tagTLBFuncDesc * next;
562 /* internal Variable data */
563 typedef struct tagTLBVarDesc
565 VARDESC vardesc; /* lots of info on the variable and its attributes. */
566 BSTR Name; /* the name of this variable */
568 int HelpStringContext; /* fixme: where? */
571 TLBCustData * pCustData;/* linked list to cust data; */
572 struct tagTLBVarDesc * next;
575 /* internal TypeInfo data */
576 typedef struct tagITypeInfoImpl
578 ICOM_VFIELD(ITypeInfo2);
580 TYPEATTR TypeAttr ; /* _lots_ of type information. */
581 ITypeLibImpl * pTypeLib; /* back pointer to typelib */
582 int index; /* index in this typelib; */
583 /* type libs seem to store the doc strings in ascii
584 * so why should we do it in unicode?
588 unsigned long dwHelpContext;
589 unsigned long dwHelpStringContext;
592 TLBFuncDesc * funclist; /* linked list with function descriptions */
595 TLBVarDesc * varlist; /* linked list with variable descriptions */
597 /* Implemented Interfaces */
598 TLBRefType * impltypelist;
600 TLBCustData * pCustData; /* linked list to cust data; */
601 struct tagITypeInfoImpl * next;
604 static struct ICOM_VTABLE(ITypeInfo2) tinfvt;
606 static ITypeInfo2 * WINAPI ITypeInfo_Constructor();
608 typedef struct tagTLBContext
610 unsigned int oStart; /* start of TLB in file */
611 unsigned int pos; /* current pos */
612 unsigned int length; /* total length */
613 void *mapping; /* memory mapping */
615 ITypeLibImpl* pLibInfo;
619 static void TLB_DoRefType(TLBContext *pcx, int offset, TLBRefType ** pprtd);
624 static void dump_VarType(VARTYPE vt,char *szVarType) {
625 /* FIXME : we could have better trace here, depending on the VARTYPE
629 case VT_UI1: sprintf(szVarType, "VT_UI"); break;
630 case VT_I2: sprintf(szVarType, "VT_I2"); break;
631 case VT_I4: sprintf(szVarType, "VT_I4"); break;
632 case VT_R4: sprintf(szVarType, "VT_R4"); break;
633 case VT_R8: sprintf(szVarType, "VT_R8"); break;
634 case VT_BOOL: sprintf(szVarType, "VT_BOOL"); break;
635 case VT_ERROR: sprintf(szVarType, "VT_ERROR"); break;
636 case VT_CY: sprintf(szVarType, "VT_CY"); break;
637 case VT_DATE: sprintf(szVarType, "VT_DATE"); break;
638 case VT_BSTR: sprintf(szVarType, "VT_BSTR"); break;
639 case VT_BYREF: case VT_UNKNOWN: sprintf(szVarType, "VT_BYREF"); break;
640 case VT_DISPATCH: sprintf(szVarType, "VT_DISPATCH"); break;
641 case VT_ARRAY: sprintf(szVarType, "VT_ARRAY"); break;
642 case VT_I1: sprintf(szVarType, "VT_I2"); break;
643 case VT_UI2: sprintf(szVarType, "VT_UI2"); break;
644 case VT_UI4: sprintf(szVarType, "VT_UI4"); break;
645 case VT_INT: sprintf(szVarType, "VT_INT"); break;
646 case VT_UINT: sprintf(szVarType, "VT_UINT"); break;
647 default: sprintf(szVarType, "unknown");break;
650 static void dump_ELEMDESC(ELEMDESC *edesc) {
652 dump_VarType(edesc->tdesc.vt,buf);
653 MESSAGE("\t\ttdesc.vartype %d (%s)\n",edesc->tdesc.vt,buf);
654 MESSAGE("\t\tu.parmadesc.flags %x\n",edesc->u.paramdesc.wParamFlags);
655 MESSAGE("\t\tu.parmadesc.lpex %p\n",edesc->u.paramdesc.pparamdescex);
657 static void dump_FUNCDESC(FUNCDESC *funcdesc) {
659 MESSAGE("memid is %d\n",(int)funcdesc->memid);
660 for (i=0;i<funcdesc->cParams;i++)
661 MESSAGE("Param %d:\n",i);dump_ELEMDESC(funcdesc->lprgelemdescParam+i);
662 MESSAGE("\tfunckind: %d (",funcdesc->funckind);
663 switch (funcdesc->funckind) {
664 case FUNC_VIRTUAL: MESSAGE("virtual");break;
665 case FUNC_PUREVIRTUAL: MESSAGE("pure virtual");break;
666 case FUNC_NONVIRTUAL: MESSAGE("nonvirtual");break;
667 case FUNC_STATIC: MESSAGE("static");break;
668 case FUNC_DISPATCH: MESSAGE("dispatch");break;
669 default: MESSAGE("unknown");break;
671 MESSAGE(")\n\tinvkind: %d (",funcdesc->invkind);
672 switch (funcdesc->invkind) {
673 case INVOKE_FUNC: MESSAGE("func");break;
674 case INVOKE_PROPERTYGET: MESSAGE("property get");break;
675 case INVOKE_PROPERTYPUT: MESSAGE("property put");break;
676 case INVOKE_PROPERTYPUTREF: MESSAGE("property put ref");break;
678 MESSAGE(")\n\tcallconv: %d (",funcdesc->callconv);
679 switch (funcdesc->callconv) {
680 case CC_CDECL: MESSAGE("cdecl");break;
681 case CC_PASCAL: MESSAGE("pascal");break;
682 case CC_STDCALL: MESSAGE("stdcall");break;
683 case CC_SYSCALL: MESSAGE("syscall");break;
686 MESSAGE(")\n\toVft: %d\n", funcdesc->oVft);
687 MESSAGE("\tcParamsOpt: %d\n", funcdesc->cParamsOpt);
688 MESSAGE("\twFlags: %x\n", funcdesc->wFuncFlags);
690 static void dump_TLBFuncDescOne(TLBFuncDesc * pfd)
693 if (!TRACE_ON(typelib))
695 MESSAGE("%s(%u)\n", debugstr_w(pfd->Name), pfd->funcdesc.cParams);
696 for (i=0;i<pfd->funcdesc.cParams;i++)
697 MESSAGE("\tparm%d: %s\n",i,debugstr_w(pfd->pParamDesc[i].Name));
700 dump_FUNCDESC(&(pfd->funcdesc));
702 MESSAGE("\thelpstring: %s\n", debugstr_w(pfd->HelpString));
703 MESSAGE("\tentry: %s\n", debugstr_w(pfd->Entry));
705 static void dump_TLBFuncDesc(TLBFuncDesc * pfd)
709 dump_TLBFuncDescOne(pfd);
713 static void dump_TLBVarDesc(TLBVarDesc * pvd)
717 TRACE_(typelib)("%s\n", debugstr_w(pvd->Name));
721 static void dump_TLBRefType(TLBRefType * prt)
725 TRACE_(typelib)("%s\n", debugstr_guid(&(prt->guid)));
726 TRACE_(typelib)(" href:0x%08lx\n", prt->reference);
731 static void dump_Variant(VARIANT * pvar)
735 TRACE("(%p)\n", pvar);
739 ZeroMemory(szVarType, sizeof(szVarType));
741 /* FIXME : we could have better trace here, depending on the VARTYPE
744 dump_VarType(V_VT(pvar),szVarType);
746 TRACE("VARTYPE: %s\n", szVarType);
751 TRACE("%3.3e\n", V_UNION(pvar, fltVal));
755 TRACE("%3.3e\n", V_UNION(pvar, dblVal));
759 TRACE("%ld\n", V_UNION(pvar, lVal));
763 if (pvar->vt & VT_BYREF)
764 return dump_Variant(pvar->u.pvarVal);
767 static void dump_DispParms(DISPPARAMS * pdp)
771 TRACE("args=%u named args=%u\n", pdp->cArgs, pdp->cNamedArgs);
773 while (index < pdp->cArgs)
775 dump_Variant( &pdp->rgvarg[index] );
780 static char * typekind_desc[] =
793 static void dump_TypeInfo(ITypeInfoImpl * pty)
795 TRACE("%p ref=%u\n", pty, pty->ref);
796 TRACE("attr:%s\n", debugstr_guid(&(pty->TypeAttr.guid)));
797 TRACE("kind:%s\n", typekind_desc[pty->TypeAttr.typekind]);
798 TRACE("fct:%u var:%u impl:%u\n",
799 pty->TypeAttr.cFuncs, pty->TypeAttr.cVars, pty->TypeAttr.cImplTypes);
800 TRACE("parent tlb:%p index in TLB:%u\n",pty->pTypeLib, pty->index);
801 TRACE("%s %s\n", debugstr_w(pty->Name), debugstr_w(pty->DocString));
802 dump_TLBFuncDesc(pty->funclist);
803 dump_TLBVarDesc(pty->varlist);
804 dump_TLBRefType(pty->impltypelist);
807 static TYPEDESC stndTypeDesc[VT_LPWSTR+1]=
809 /* VT_LPWSTR is largest type that */
810 /* may appear in type description*/
811 {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
812 {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
813 {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
814 {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
815 {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
816 {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
820 static void TLB_abort()
824 static void * TLB_Alloc(unsigned size)
827 if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){
829 ERR("cannot allocate memory\n");
834 static void TLB_Free(void * ptr)
836 HeapFree(GetProcessHeap(), 0, ptr);
839 DWORD TLB_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
841 TRACE_(typelib)("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n",
842 pcx->pos, count, pcx->oStart, pcx->length, where);
844 if (where != DO_NOT_SEEK)
846 where += pcx->oStart;
847 if (where > pcx->length)
850 ERR("seek beyond end (%ld/%d)\n", where, pcx->length );
855 if (pcx->pos + count > pcx->length) count = pcx->length - pcx->pos;
856 memcpy( buffer, (char *)pcx->mapping + pcx->pos, count );
861 static void TLB_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
863 TRACE_(typelib)("%s\n", debugstr_guid(pGuid));
865 if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){
866 memset(pGuid,0, sizeof(GUID));
869 TLB_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset );
872 BSTR TLB_ReadName( TLBContext *pcx, int offset)
877 WCHAR* pwstring = NULL;
878 BSTR bstrName = NULL;
880 TLB_Read(&niName, sizeof(niName), pcx,
881 pcx->pTblDir->pNametab.offset+offset);
882 niName.namelen &= 0xFF; /* FIXME: correct ? */
883 name=TLB_Alloc((niName.namelen & 0xff) +1);
884 TLB_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK);
885 name[niName.namelen & 0xff]='\0';
887 lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
890 /* no invalid characters in string */
893 pwstring = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*lengthInChars);
895 /* don't check for invalid character since this has been done previously */
896 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, pwstring, lengthInChars);
898 bstrName = SysAllocStringLen(pwstring, lengthInChars);
899 lengthInChars = SysStringLen(bstrName);
900 HeapFree(GetProcessHeap(), 0, pwstring);
903 TRACE_(typelib)("%s %d\n", debugstr_w(bstrName), lengthInChars);
907 BSTR TLB_ReadString( TLBContext *pcx, int offset)
914 if(offset<0) return NULL;
915 TLB_Read(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
916 if(length <= 0) return 0;
917 string=TLB_Alloc(length +1);
918 TLB_Read(string, length, pcx, DO_NOT_SEEK);
921 lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
922 string, -1, NULL, 0);
924 /* no invalid characters in string */
927 WCHAR* pwstring = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*lengthInChars);
929 /* don't check for invalid character since this has been done previously */
930 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, pwstring, lengthInChars);
932 bstr = SysAllocStringLen(pwstring, lengthInChars);
933 lengthInChars = SysStringLen(bstr);
934 HeapFree(GetProcessHeap(), 0, pwstring);
937 TRACE_(typelib)("%s %d\n", debugstr_w(bstr), lengthInChars);
941 * read a value and fill a VARIANT structure
943 static void TLB_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
947 TRACE_(typelib)("\n");
949 if(offset <0) { /* data is packed in here */
950 pVar->vt = (offset & 0x7c000000 )>> 26;
951 V_UNION(pVar, iVal) = offset & 0xffff;
954 TLB_Read(&(pVar->vt), sizeof(VARTYPE), pcx,
955 pcx->pTblDir->pCustData.offset + offset );
956 TRACE_(typelib)("Vartype = %x\n", pVar->vt);
958 case VT_EMPTY: /* FIXME: is this right? */
959 case VT_NULL: /* FIXME: is this right? */
960 case VT_I2 : /* this should not happen */
971 case VT_VOID : /* FIXME: is this right? */
979 case VT_DECIMAL : /* FIXME: is this right? */
982 /* pointer types with known behaviour */
985 TLB_Read(&size, sizeof(INT), pcx, DO_NOT_SEEK );
987 FIXME("BSTR length = %d?\n", size);
989 ptr=TLB_Alloc(size);/* allocate temp buffer */
990 TLB_Read(ptr, size, pcx, DO_NOT_SEEK); /* read string (ANSI) */
991 V_UNION(pVar, bstrVal)=SysAllocStringLen(NULL,size);
992 /* FIXME: do we need a AtoW conversion here? */
993 V_UNION(pVar, bstrVal[size])=L'\0';
994 while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
999 /* FIXME: this will not work AT ALL when the variant contains a pointer */
1006 case VT_USERDEFINED :
1012 case VT_STREAMED_OBJECT :
1013 case VT_STORED_OBJECT :
1014 case VT_BLOB_OBJECT :
1019 FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
1023 if(size>0) /* (big|small) endian correct? */
1024 TLB_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK );
1028 * create a linked list with custom data
1030 static int TLB_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
1036 TRACE_(typelib)("\n");
1040 pNew=TLB_Alloc(sizeof(TLBCustData));
1041 TLB_Read(&entry, sizeof(entry), pcx,
1042 pcx->pTblDir->pCDGuids.offset+offset);
1043 TLB_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
1044 TLB_ReadValue(&(pNew->data), entry.DataOffset, pcx);
1045 /* add new custom data at head of the list */
1046 pNew->next=*ppCustData;
1048 offset = entry.next;
1053 static void TLB_GetTdesc(TLBContext *pcx, INT type,TYPEDESC * pTd )
1056 pTd->vt=type & VT_TYPEMASK;
1058 *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
1060 TRACE_(typelib)("vt type = %X\n", pTd->vt);
1064 TLB_DoFuncs(TLBContext* pcx,
1068 TLBFuncDesc** pptfd)
1071 * member information is stored in a data structure at offset
1072 * indicated by the memoffset field of the typeinfo structure
1073 * There are several distinctive parts.
1074 * the first part starts with a field that holds the total length
1075 * of this (first) part excluding this field. Then follow the records,
1076 * for each member there is one record.
1078 * First entry is always the length of the record (excluding this
1080 * Rest of the record depends on the type of the member. If there is
1081 * a field indicating the member type (function variable intereface etc)
1082 * I have not found it yet. At this time we depend on the information
1083 * in the type info and the usual order how things are stored.
1085 * Second follows an array sized nrMEM*sizeof(INT) with a memeber id
1088 * Third is a equal sized array with file offsets to the name entry
1091 * Forth and last (?) part is an array with offsets to the records in the
1092 * first part of this file segment.
1095 int infolen, nameoffset, reclength, nrattributes, i;
1096 int recoffset = offset + sizeof(INT);
1099 TLBFuncRecord * pFuncRec=(TLBFuncRecord *) recbuf;
1101 TRACE_(typelib)("\n");
1103 TLB_Read(&infolen, sizeof(INT), pcx, offset);
1105 for ( i = 0; i < cFuncs ; i++ )
1107 *pptfd = TLB_Alloc(sizeof(TLBFuncDesc));
1109 /* name, eventually add to a hash table */
1110 TLB_Read(&nameoffset,
1113 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
1115 (*pptfd)->Name = TLB_ReadName(pcx, nameoffset);
1117 /* read the function information record */
1118 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
1122 TLB_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
1124 /* do the attributes */
1125 nrattributes = (reclength - pFuncRec->nrargs * 3 * sizeof(int) - 0x18)
1128 if ( nrattributes > 0 )
1130 (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
1132 if ( nrattributes > 1 )
1134 (*pptfd)->HelpString = TLB_ReadString(pcx,
1135 pFuncRec->OptAttr[1]) ;
1137 if ( nrattributes > 2 )
1139 if ( pFuncRec->FKCCIC & 0x2000 )
1141 (*pptfd)->Entry = (WCHAR*) pFuncRec->OptAttr[2] ;
1145 (*pptfd)->Entry = TLB_ReadString(pcx,
1146 pFuncRec->OptAttr[2]);
1148 if( nrattributes > 5 )
1150 (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;
1152 if ( nrattributes > 6 && pFuncRec->FKCCIC & 0x80 )
1155 pFuncRec->OptAttr[6],
1156 &(*pptfd)->pCustData);
1163 /* fill the FuncDesc Structure */
1164 TLB_Read( & (*pptfd)->funcdesc.memid,
1166 offset + infolen + ( i + 1) * sizeof(INT));
1168 (*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
1169 (*pptfd)->funcdesc.invkind = (pFuncRec->FKCCIC) >> 3 & 0xF;
1170 (*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >> 8 & 0xF;
1171 (*pptfd)->funcdesc.cParams = pFuncRec->nrargs ;
1172 (*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ;
1173 (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ;
1174 (*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
1178 &(*pptfd)->funcdesc.elemdescFunc.tdesc) ;
1180 /* do the parameters/arguments */
1181 if(pFuncRec->nrargs)
1184 TLBParameterInfo paraminfo;
1186 (*pptfd)->funcdesc.lprgelemdescParam =
1187 TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
1189 (*pptfd)->pParamDesc =
1190 TLB_Alloc(pFuncRec->nrargs * sizeof(TLBParDesc));
1192 TLB_Read(¶minfo,
1195 recoffset + reclength -
1196 pFuncRec->nrargs * sizeof(TLBParameterInfo));
1198 for ( j = 0 ; j < pFuncRec->nrargs ; j++ )
1200 TYPEDESC* lpArgTypeDesc = 0;
1204 &(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc) ;
1206 V_UNION(& ((*pptfd)->funcdesc.lprgelemdescParam[j]),
1207 paramdesc.wParamFlags) = paraminfo.Flags;
1209 (*pptfd)->pParamDesc[j].Name = (void *) paraminfo.oName;
1211 /* SEEK value = jump to offset,
1212 * from there jump to the end of record,
1213 * go back by (j-1) arguments
1215 TLB_Read( ¶minfo ,
1216 sizeof(TLBParameterInfo), pcx,
1217 recoffset + reclength - ((pFuncRec->nrargs - j - 1)
1218 * sizeof(TLBParameterInfo)));
1220 & ((*pptfd)->funcdesc.lprgelemdescParam[j].tdesc);
1222 while ( lpArgTypeDesc != NULL )
1224 switch ( lpArgTypeDesc->vt )
1227 lpArgTypeDesc = lpArgTypeDesc->u.lptdesc;
1231 lpArgTypeDesc = & (lpArgTypeDesc->u.lpadesc->tdescElem);
1234 case VT_USERDEFINED:
1235 (*pptfd)->pParamDesc[j].pRefType =
1236 TLB_Alloc(sizeof(TLBRefType));
1239 lpArgTypeDesc->u.hreftype,
1240 & ( (*pptfd)->pParamDesc[j].pRefType ));
1242 lpArgTypeDesc = NULL;
1246 lpArgTypeDesc = NULL;
1252 /* parameter is the return value! */
1253 if ( paraminfo.Flags & PARAMFLAG_FRETVAL )
1255 TYPEDESC* lpArgTypeDesc;
1257 (*pptfd)->funcdesc.elemdescFunc =
1258 (*pptfd)->funcdesc.lprgelemdescParam[j];
1260 lpArgTypeDesc = & ((*pptfd)->funcdesc.elemdescFunc.tdesc) ;
1262 while ( lpArgTypeDesc != NULL )
1264 switch ( lpArgTypeDesc->vt )
1267 lpArgTypeDesc = lpArgTypeDesc->u.lptdesc;
1271 & (lpArgTypeDesc->u.lpadesc->tdescElem);
1275 case VT_USERDEFINED:
1276 (*pptfd)->pParamDesc[j].pRefType
1277 = TLB_Alloc(sizeof(TLBRefType));
1280 lpArgTypeDesc->u.hreftype,
1281 &((*pptfd)->pParamDesc[j].pRefType));
1283 lpArgTypeDesc = NULL;
1287 lpArgTypeDesc = NULL;
1292 /* second time around */
1293 for(j=0;j<pFuncRec->nrargs;j++)
1296 (*pptfd)->pParamDesc[j].Name =
1297 TLB_ReadName( pcx, (int)(*pptfd)->pParamDesc[j].Name );
1300 if ( (PARAMFLAG_FHASDEFAULT &
1301 V_UNION(&((*pptfd)->funcdesc.lprgelemdescParam[j]),
1302 paramdesc.wParamFlags)) &&
1303 ((pFuncRec->FKCCIC) & 0x1000) )
1305 INT* pInt = (INT *)((char *)pFuncRec +
1307 (pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
1309 PARAMDESC* pParamDesc = &V_UNION(
1310 & ((*pptfd)->funcdesc.lprgelemdescParam[j]),
1313 pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
1314 pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX);
1316 TLB_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
1320 if ( nrattributes > 7 + j && pFuncRec->FKCCIC & 0x80 )
1323 pFuncRec->OptAttr[7+j],
1324 &(*pptfd)->pParamDesc[j].pCustData);
1329 /* scode is not used: archaic win16 stuff FIXME: right? */
1330 (*pptfd)->funcdesc.cScodes = 0 ;
1331 (*pptfd)->funcdesc.lprgscode = NULL ;
1333 pptfd = & ((*pptfd)->next);
1334 recoffset += reclength;
1337 static void TLB_DoVars(TLBContext *pcx, int cFuncs, int cVars,
1338 int offset, TLBVarDesc ** pptvd)
1340 int infolen, nameoffset, reclength;
1342 TLBVarRecord * pVarRec=(TLBVarRecord *) recbuf;
1346 TRACE_(typelib)("\n");
1348 TLB_Read(&infolen,sizeof(INT), pcx, offset);
1349 TLB_Read(&recoffset,sizeof(INT), pcx, offset + infolen +
1350 ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
1351 recoffset += offset+sizeof(INT);
1352 for(i=0;i<cVars;i++){
1353 *pptvd=TLB_Alloc(sizeof(TLBVarDesc));
1354 /* name, eventually add to a hash table */
1355 TLB_Read(&nameoffset, sizeof(INT), pcx,
1356 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
1357 (*pptvd)->Name=TLB_ReadName(pcx, nameoffset);
1358 /* read the variable information record */
1359 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
1361 TLB_Read(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
1363 if(reclength >(6*sizeof(INT)) )
1364 (*pptvd)->HelpContext=pVarRec->HelpContext;
1365 if(reclength >(7*sizeof(INT)) )
1366 (*pptvd)->HelpString = TLB_ReadString(pcx, pVarRec->oHelpString) ;
1367 if(reclength >(8*sizeof(INT)) )
1368 if(reclength >(9*sizeof(INT)) )
1369 (*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
1370 /* fill the VarDesc Structure */
1371 TLB_Read(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
1372 offset + infolen + ( i + 1) * sizeof(INT));
1373 (*pptvd)->vardesc.varkind = pVarRec->VarKind;
1374 (*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
1375 TLB_GetTdesc(pcx, pVarRec->DataType,
1376 &(*pptvd)->vardesc.elemdescVar.tdesc) ;
1377 /* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) fixme?? */
1378 if(pVarRec->VarKind == VAR_CONST ){
1379 V_UNION(&((*pptvd)->vardesc),lpvarValue)=TLB_Alloc(sizeof(VARIANT));
1380 TLB_ReadValue(V_UNION(&((*pptvd)->vardesc),lpvarValue),
1381 pVarRec->OffsValue, pcx);
1383 V_UNION(&((*pptvd)->vardesc),oInst)=pVarRec->OffsValue;
1384 pptvd=&((*pptvd)->next);
1385 recoffset += reclength;
1388 /* fill in data for a hreftype (offset). When the refernced type is contained
1389 * in the typelib, its just an (file) offset in the type info base dir.
1390 * If comes from import, its an offset+1 in the ImpInfo table
1392 static void TLB_DoRefType(TLBContext *pcx,
1393 int offset, TLBRefType ** pprtd)
1397 TRACE_(typelib)("TLB context %p, TLB offset %x\n", pcx, offset);
1399 if(!HREFTYPE_INTHISFILE( offset)) {
1400 /* external typelib */
1402 TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs);
1404 TRACE_(typelib)("offset %x, masked offset %x\n", offset, offset + (offset & 0xfffffffc));
1406 TLB_Read(&impinfo, sizeof(impinfo), pcx,
1407 pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
1408 for(j=0;pImpLib;j++){ /* search the known offsets of all import libraries */
1409 if(pImpLib->offset==impinfo.oImpFile) break;
1410 pImpLib=pImpLib->next;
1413 (*pprtd)->reference=offset;
1414 (*pprtd)->pImpTLInfo = pImpLib;
1415 TLB_ReadGuid(&(*pprtd)->guid, impinfo.oGuid, pcx);
1417 ERR("Cannot find a reference\n");
1418 (*pprtd)->reference=-1;
1419 (*pprtd)->pImpTLInfo=(void *)-1;
1422 /* in this typelib */
1423 (*pprtd)->reference=offset;
1424 (*pprtd)->pImpTLInfo=(void *)-2;
1428 /* process Implemented Interfaces of a com class */
1429 static void TLB_DoImplTypes(TLBContext *pcx, int count,
1430 int offset, TLBRefType ** pprtd)
1433 TLBRefRecord refrec;
1435 TRACE_(typelib)("\n");
1437 for(i=0;i<count;i++){
1438 if(offset<0) break; /* paranoia */
1439 *pprtd=TLB_Alloc(sizeof(TLBRefType));
1440 TLB_Read(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
1441 TLB_DoRefType(pcx, refrec.reftype, pprtd);
1442 (*pprtd)->flags=refrec.flags;
1443 (*pprtd)->ctCustData=
1444 TLB_CustData(pcx, refrec.oCustData, &(*pprtd)->pCustData);
1445 offset=refrec.onext;
1446 pprtd=&((*pprtd)->next);
1450 * process a typeinfo record
1452 ITypeInfoImpl * TLB_DoTypeInfo(
1455 ITypeLibImpl * pLibInfo)
1457 TLBTypeInfoBase tiBase;
1458 ITypeInfoImpl *ptiRet;
1460 TRACE_(typelib)("count=%u\n", count);
1462 ptiRet = (ITypeInfoImpl*) ITypeInfo_Constructor();
1463 TLB_Read(&tiBase, sizeof(tiBase) ,pcx ,
1464 pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
1465 /* this is where we are coming from */
1466 ptiRet->pTypeLib = pLibInfo;
1467 ptiRet->index=count;
1468 /* fill in the typeattr fields */
1469 FIXME("Assign constructor/destructor memid\n");
1471 TLB_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx);
1472 ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid; /* FIXME: correct? */
1473 ptiRet->TypeAttr.memidConstructor=MEMBERID_NIL ;/* FIXME */
1474 ptiRet->TypeAttr.memidDestructor=MEMBERID_NIL ; /* FIXME */
1475 ptiRet->TypeAttr.lpstrSchema=NULL; /* reserved */
1476 ptiRet->TypeAttr.cbSizeInstance=tiBase.size;
1477 ptiRet->TypeAttr.typekind=tiBase.typekind & 0xF;
1478 ptiRet->TypeAttr.cFuncs=LOWORD(tiBase.cElement);
1479 ptiRet->TypeAttr.cVars=HIWORD(tiBase.cElement);
1480 ptiRet->TypeAttr.cbAlignment=(tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */
1481 ptiRet->TypeAttr.wTypeFlags=tiBase.flags;
1482 ptiRet->TypeAttr.wMajorVerNum=LOWORD(tiBase.version);
1483 ptiRet->TypeAttr.wMinorVerNum=HIWORD(tiBase.version);
1484 ptiRet->TypeAttr.cImplTypes=tiBase.cImplTypes;
1485 ptiRet->TypeAttr.cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
1486 if(ptiRet->TypeAttr.typekind == TKIND_ALIAS)
1487 TLB_GetTdesc(pcx, tiBase.datatype1,
1488 &ptiRet->TypeAttr.tdescAlias) ;
1491 /* IDLDESC idldescType; *//* never saw this one != zero */
1493 /* name, eventually add to a hash table */
1494 ptiRet->Name=TLB_ReadName(pcx, tiBase.NameOffset);
1495 TRACE_(typelib)("reading %s\n", debugstr_w(ptiRet->Name));
1497 ptiRet->DocString=TLB_ReadString(pcx, tiBase.docstringoffs);
1498 ptiRet->dwHelpStringContext=tiBase.helpstringcontext;
1499 ptiRet->dwHelpContext=tiBase.helpcontext;
1500 /* note: InfoType's Help file and HelpStringDll come from the containing
1501 * library. Further HelpString and Docstring appear to be the same thing :(
1504 if(ptiRet->TypeAttr.cFuncs >0 )
1505 TLB_DoFuncs(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
1506 tiBase.memoffset, & ptiRet->funclist);
1508 if(ptiRet->TypeAttr.cVars >0 )
1509 TLB_DoVars(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
1510 tiBase.memoffset, & ptiRet->varlist);
1511 if(ptiRet->TypeAttr.cImplTypes >0 ){
1512 switch(ptiRet->TypeAttr.typekind)
1515 TLB_DoImplTypes(pcx, ptiRet->TypeAttr.cImplTypes ,
1516 tiBase.datatype1, & ptiRet->impltypelist);
1518 case TKIND_DISPATCH:
1519 ptiRet->impltypelist=TLB_Alloc(sizeof(TLBRefType));
1521 if (tiBase.datatype1 != -1)
1523 TLB_DoRefType(pcx, tiBase.datatype1, & ptiRet->impltypelist);
1527 char* szStdOle = "stdole2.tlb\0";
1528 int nStdOleLen = strlen(szStdOle);
1530 ptiRet->impltypelist->guid = IID_IDispatch;
1531 ptiRet->impltypelist->reference = -1;
1532 ptiRet->impltypelist->pImpTLInfo = TLB_Alloc(sizeof(TLBImpLib));
1533 ptiRet->impltypelist->pImpTLInfo->guid = IID_StdOle;
1534 ptiRet->impltypelist->pImpTLInfo->name = SysAllocStringLen(NULL, nStdOleLen + 1);
1536 MultiByteToWideChar(CP_ACP,
1540 ptiRet->impltypelist->pImpTLInfo->name,
1541 SysStringLen(ptiRet->impltypelist->pImpTLInfo->name));
1543 ptiRet->impltypelist->pImpTLInfo->lcid = 0;
1544 ptiRet->impltypelist->pImpTLInfo->wVersionMajor = 2;
1545 ptiRet->impltypelist->pImpTLInfo->wVersionMinor = 0;
1549 ptiRet->impltypelist=TLB_Alloc(sizeof(TLBRefType));
1550 TLB_DoRefType(pcx, tiBase.datatype1, & ptiRet->impltypelist);
1555 TLB_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData);
1557 TRACE_(typelib)("%s guid: %s kind:%s\n",
1558 debugstr_w(ptiRet->Name),
1559 debugstr_guid(&ptiRet->TypeAttr.guid),
1560 typekind_desc[ptiRet->TypeAttr.typekind]);
1565 /****************************************************************************
1568 * find the type of the typelib file and map the typelib resource into
1571 #define MSFT_SIGNATURE 0x5446534D /* "MSFT" */
1572 int TLB_ReadTypeLib(LPSTR pszFileName, ITypeLib2 **ppTypeLib)
1575 DWORD dwSignature = 0;
1577 int nStrLen = strlen(pszFileName);
1580 PCHAR pszTypeLibIndex = NULL;
1581 PCHAR pszDllName = NULL;
1583 TRACE_(typelib)("%s\n", pszFileName);
1588 for (i=0 ; i < nStrLen ; ++i)
1590 pszFileName[i] = tolower(pszFileName[i]);
1592 pszTypeLibIndex = strstr(pszFileName, ".dll");
1594 /* find if there's a back-slash after .DLL (good sign of the presence of a typelib index) */
1595 if (pszTypeLibIndex)
1597 pszTypeLibIndex = strstr(pszTypeLibIndex, "\\");
1600 /* is there any thing after trailing back-slash ? */
1601 if (pszTypeLibIndex && pszTypeLibIndex < pszFileName + nStrLen)
1603 /* yes -> it's a index! store DLL name, without the trailing back-slash */
1604 size_t nMemToAlloc = pszTypeLibIndex - pszFileName;
1606 pszDllName = HeapAlloc(GetProcessHeap(),
1610 strncpy(pszDllName, pszFileName, nMemToAlloc);
1612 /* move index string pointer pass the backslash */
1613 while (*pszTypeLibIndex == '\\')
1618 /* No index, reset variable to 1 */
1619 pszDllName = HeapAlloc(GetProcessHeap(),
1623 strncpy(pszDllName, pszFileName, nStrLen);
1625 pszTypeLibIndex = "1\0";
1628 TRACE_(typelib)("File name without index %s\n", pszDllName);
1629 TRACE_(typelib)("Index of typelib %s\n", pszTypeLibIndex);
1632 /* check the signature of the file */
1633 hFile = CreateFileA( pszDllName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
1634 if (INVALID_HANDLE_VALUE != hFile)
1636 HANDLE hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
1639 LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
1642 /* first try to load as *.tlb */
1643 dwSignature = *((DWORD*) pBase);
1644 if ( dwSignature == MSFT_SIGNATURE)
1646 /* retrieve file size */
1647 DWORD dwTLBLength = GetFileSize(hFile, NULL);
1649 *ppTypeLib = ITypeLib2_Constructor(pBase, dwTLBLength);
1650 ITypeLib2_AddRef(*ppTypeLib);
1652 UnmapViewOfFile(pBase);
1654 CloseHandle(hMapping);
1659 if( (WORD)dwSignature == IMAGE_DOS_SIGNATURE )
1661 /* find the typelibrary resource*/
1662 HINSTANCE hinstDLL = LoadLibraryExA(pszDllName, 0, DONT_RESOLVE_DLL_REFERENCES|
1663 LOAD_LIBRARY_AS_DATAFILE|LOAD_WITH_ALTERED_SEARCH_PATH);
1666 HRSRC hrsrc = FindResourceA(hinstDLL, MAKEINTRESOURCEA(atoi(pszTypeLibIndex)), "TYPELIB");
1669 HGLOBAL hGlobal = LoadResource(hinstDLL, hrsrc);
1672 LPVOID pBase = LockResource(hGlobal);
1673 DWORD dwTLBLength = SizeofResource(hinstDLL, hrsrc);
1677 /* try to load as incore resource */
1678 dwSignature = *((DWORD*) pBase);
1679 if ( dwSignature == MSFT_SIGNATURE)
1681 *ppTypeLib = ITypeLib2_Constructor(pBase, dwTLBLength);
1682 ITypeLib2_AddRef(*ppTypeLib);
1686 FIXME("Header type magic 0x%08lx not supported.\n",dwSignature);
1689 FreeResource( hGlobal );
1692 FreeLibrary(hinstDLL);
1696 HeapFree(GetProcessHeap(), 0, pszDllName);
1701 ERR("Loading of typelib %s failed with error 0x%08lx\n", pszFileName, GetLastError());
1706 /*================== ITypeLib(2) Methods ===================================*/
1708 /****************************************************************************
1709 * ITypeLib2_Constructor
1711 * loading a typelib from a in-memory image
1713 static ITypeLib2* ITypeLib2_Constructor(LPVOID pLib, DWORD dwTLBLength)
1717 TLB2Header tlbHeader;
1718 TLBSegDir tlbSegDir;
1719 ITypeLibImpl * pTypeLibImpl;
1721 TRACE("%p, TLB length = %ld\n", pLib, dwTLBLength);
1723 pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
1724 if (!pTypeLibImpl) return NULL;
1726 ICOM_VTBL(pTypeLibImpl) = &tlbvt;
1727 pTypeLibImpl->ref = 1;
1729 /* get pointer to beginning of typelib data */
1733 cx.pLibInfo = pTypeLibImpl;
1734 cx.length = dwTLBLength;
1737 TLB_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
1739 TRACE("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2 );
1740 if (memcmp(&tlbHeader.magic1,TLBMAGIC2,4)) {
1741 FIXME("Header type magic 0x%08x not supported.\n",tlbHeader.magic1);
1744 /* there is a small number of information here until the next important
1746 * the segment directory . Try to calculate the amount of data */
1747 lPSegDir = sizeof(tlbHeader) + (tlbHeader.nrtypeinfos)*4 + ((tlbHeader.varflags & HELPDLLFLAG)? 4 :0);
1749 /* now read the segment directory */
1750 TRACE("read segment directory (at %ld)\n",lPSegDir);
1751 TLB_Read((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
1752 cx.pTblDir = &tlbSegDir;
1754 /* just check two entries */
1755 if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F || tlbSegDir.pImpInfo.res0c != 0x0F)
1757 ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir);
1758 HeapFree(GetProcessHeap(),0,pTypeLibImpl);
1762 /* now fill our internal data */
1763 /* TLIBATTR fields */
1764 TLB_ReadGuid(&pTypeLibImpl->LibAttr.guid, tlbHeader.posguid, &cx);
1765 pTypeLibImpl->LibAttr.lcid = tlbHeader.lcid;
1766 pTypeLibImpl->LibAttr.syskind = tlbHeader.varflags & 0x0f; /* check the mask */
1767 pTypeLibImpl->LibAttr.wMajorVerNum = LOWORD(tlbHeader.version);
1768 pTypeLibImpl->LibAttr.wMinorVerNum = HIWORD(tlbHeader.version);
1769 pTypeLibImpl->LibAttr.wLibFlags = (WORD) tlbHeader.flags & 0xffff;/* check mask */
1771 /* name, eventually add to a hash table */
1772 pTypeLibImpl->Name = TLB_ReadName(&cx, tlbHeader.NameOffset);
1775 pTypeLibImpl->DocString = TLB_ReadString(&cx, tlbHeader.helpstring);
1776 pTypeLibImpl->HelpFile = TLB_ReadString(&cx, tlbHeader.helpfile);
1778 if( tlbHeader.varflags & HELPDLLFLAG)
1781 TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
1782 pTypeLibImpl->HelpStringDll = TLB_ReadString(&cx, offset);
1785 pTypeLibImpl->dwHelpContext = tlbHeader.helpstringcontext;
1788 if(tlbHeader.CustomDataOffset >= 0)
1790 pTypeLibImpl->ctCustData = TLB_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->pCustData);
1793 /* fill in typedescriptions */
1794 if(tlbSegDir.pTypdescTab.length > 0)
1796 int i, j, cTD = tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
1798 pTypeLibImpl->pTypeDesc = TLB_Alloc( cTD * sizeof(TYPEDESC));
1799 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
1802 /* FIXME: add several sanity checks here */
1803 pTypeLibImpl->pTypeDesc[i].vt = td[0] & VT_TYPEMASK;
1804 if(td[0] == VT_PTR || td[0] == VT_SAFEARRAY)
1806 /* FIXME: check safearray */
1808 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lptdesc)= & stndTypeDesc[td[2]];
1810 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lptdesc)= & pTypeLibImpl->pTypeDesc[td[2]/8];
1812 else if(td[0] == VT_CARRAY)
1814 /* array descr table here */
1815 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = (void *)((int) td[2]); /* temp store offset in*/
1817 else if(td[0] == VT_USERDEFINED)
1819 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),hreftype) = MAKELONG(td[2],td[3]);
1821 if(++i<cTD) TLB_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
1824 /* second time around to fill the array subscript info */
1827 if(pTypeLibImpl->pTypeDesc[i].vt != VT_CARRAY) continue;
1828 if(tlbSegDir.pArrayDescriptions.offset>0)
1830 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (int) V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc));
1831 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
1834 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->tdescElem.vt = td[0] & VT_TYPEMASK;
1836 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->tdescElem = stndTypeDesc[td[0]/8];
1838 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->cDims = td[2];
1840 for(j = 0; j<td[2]; j++)
1842 TLB_Read(& V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->rgbounds[j].cElements,
1843 sizeof(INT), &cx, DO_NOT_SEEK);
1844 TLB_Read(& V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->rgbounds[j].lLbound,
1845 sizeof(INT), &cx, DO_NOT_SEEK);
1850 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = NULL;
1851 ERR("didn't find array description data\n");
1856 /* imported type libs */
1857 if(tlbSegDir.pImpFiles.offset>0)
1859 TLBImpLib **ppImpLib = &(pTypeLibImpl->pImpLibs);
1860 int oGuid, offset = tlbSegDir.pImpFiles.offset;
1863 while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length)
1865 *ppImpLib = TLB_Alloc(sizeof(TLBImpLib));
1866 (*ppImpLib)->offset = offset - tlbSegDir.pImpFiles.offset;
1867 TLB_Read(&oGuid, sizeof(INT), &cx, offset);
1869 TLB_Read(&(*ppImpLib)->lcid, sizeof(LCID), &cx, DO_NOT_SEEK);
1870 TLB_Read(&(*ppImpLib)->wVersionMajor, sizeof(WORD), &cx, DO_NOT_SEEK);
1871 TLB_Read(&(*ppImpLib)->wVersionMinor, sizeof(WORD), &cx, DO_NOT_SEEK);
1872 TLB_Read(& size, sizeof(UINT16), &cx, DO_NOT_SEEK);
1875 (*ppImpLib)->name = TLB_Alloc(size+1);
1876 TLB_Read((*ppImpLib)->name, size, &cx, DO_NOT_SEEK);
1877 TLB_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
1878 offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & 0xfffffffc;
1880 ppImpLib = &(*ppImpLib)->next;
1885 if(tlbHeader.nrtypeinfos >= 0 )
1887 /*pTypeLibImpl->TypeInfoCount=tlbHeader.nrtypeinfos; */
1888 ITypeInfoImpl **ppTI = &(pTypeLibImpl->pTypeInfo);
1891 for(i = 0; i<(int)tlbHeader.nrtypeinfos; i++)
1893 *ppTI = TLB_DoTypeInfo(&cx, i, pTypeLibImpl);
1895 ITypeInfo_AddRef((ITypeInfo*) *ppTI);
1896 ppTI = &((*ppTI)->next);
1897 (pTypeLibImpl->TypeInfoCount)++;
1901 TRACE("(%p)\n", pTypeLibImpl);
1902 return (ITypeLib2*) pTypeLibImpl;
1905 /* ITypeLib::QueryInterface
1907 static HRESULT WINAPI ITypeLib2_fnQueryInterface(
1912 ICOM_THIS( ITypeLibImpl, iface);
1914 TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
1917 if(IsEqualIID(riid, &IID_IUnknown) ||
1918 IsEqualIID(riid,&IID_ITypeLib)||
1919 IsEqualIID(riid,&IID_ITypeLib2))
1926 ITypeLib2_AddRef(iface);
1927 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1930 TRACE("-- Interface: E_NOINTERFACE\n");
1931 return E_NOINTERFACE;
1936 static ULONG WINAPI ITypeLib2_fnAddRef( ITypeLib2 *iface)
1938 ICOM_THIS( ITypeLibImpl, iface);
1940 TRACE("(%p)->ref is %u\n",This, This->ref);
1942 return ++(This->ref);
1945 /* ITypeLib::Release
1947 static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
1949 ICOM_THIS( ITypeLibImpl, iface);
1953 TRACE("(%p)->(%u)\n",This, This->ref);
1957 /* fixme destroy child objects */
1959 TRACE(" destroying ITypeLib(%p)\n",This);
1963 SysFreeString(This->Name);
1967 if (This->DocString)
1969 SysFreeString(This->DocString);
1970 This->DocString = NULL;
1975 SysFreeString(This->HelpFile);
1976 This->HelpFile = NULL;
1979 if (This->HelpStringDll)
1981 SysFreeString(This->HelpStringDll);
1982 This->HelpStringDll = NULL;
1985 ITypeInfo_Release((ITypeInfo*) This->pTypeInfo);
1986 HeapFree(GetProcessHeap(),0,This);
1993 /* ITypeLib::GetTypeInfoCount
1995 * Returns the number of type descriptions in the type library
1997 static UINT WINAPI ITypeLib2_fnGetTypeInfoCount( ITypeLib2 *iface)
1999 ICOM_THIS( ITypeLibImpl, iface);
2000 TRACE("(%p)->count is %d\n",This, This->TypeInfoCount);
2001 return This->TypeInfoCount;
2004 /* ITypeLib::GetTypeInfo
2006 * retrieves the specified type description in the library.
2008 static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(
2011 ITypeInfo **ppTInfo)
2015 ICOM_THIS( ITypeLibImpl, iface);
2016 ITypeInfoImpl *pTypeInfo = This->pTypeInfo;
2018 TRACE("(%p)->(index=%d) \n", This, index);
2020 if (!ppTInfo) return E_INVALIDARG;
2022 /* search element n in list */
2023 for(i=0; i < index; i++)
2025 pTypeInfo = pTypeInfo->next;
2028 TRACE("-- element not found\n");
2029 return TYPE_E_ELEMENTNOTFOUND;
2033 *ppTInfo = (ITypeInfo *) pTypeInfo;
2035 ITypeInfo_AddRef(*ppTInfo);
2036 TRACE("-- found (%p)\n",*ppTInfo);
2041 /* ITypeLibs::GetTypeInfoType
2043 * Retrieves the type of a type description.
2045 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType(
2050 ICOM_THIS( ITypeLibImpl, iface);
2052 ITypeInfoImpl *pTInfo = This->pTypeInfo;
2054 TRACE("(%p) index %d \n",This, index);
2056 if(!pTKind) return E_INVALIDARG;
2058 /* search element n in list */
2059 for(i=0; i < index; i++)
2063 TRACE("-- element not found\n");
2064 return TYPE_E_ELEMENTNOTFOUND;
2066 pTInfo = pTInfo->next;
2069 *pTKind = pTInfo->TypeAttr.typekind;
2070 TRACE("-- found Type (%d)\n", *pTKind);
2074 /* ITypeLib::GetTypeInfoOfGuid
2076 * Retrieves the type description that corresponds to the specified GUID.
2079 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(
2082 ITypeInfo **ppTInfo)
2084 ICOM_THIS( ITypeLibImpl, iface);
2085 ITypeInfoImpl *pTypeInfo = This->pTypeInfo; /* head of list */
2087 TRACE("(%p)\n\tguid:\t%s)\n",This,debugstr_guid(guid));
2089 if (!pTypeInfo) return TYPE_E_ELEMENTNOTFOUND;
2091 /* search linked list for guid */
2092 while( !IsEqualIID(guid,&pTypeInfo->TypeAttr.guid) )
2094 pTypeInfo = pTypeInfo->next;
2098 /* end of list reached */
2099 TRACE("-- element not found\n");
2100 return TYPE_E_ELEMENTNOTFOUND;
2104 TRACE("-- found (%p, %s)\n",
2106 debugstr_w(pTypeInfo->Name));
2108 *ppTInfo = (ITypeInfo*)pTypeInfo;
2109 ITypeInfo_AddRef(*ppTInfo);
2113 /* ITypeLib::GetLibAttr
2115 * Retrieves the structure that contains the library's attributes.
2118 static HRESULT WINAPI ITypeLib2_fnGetLibAttr(
2120 LPTLIBATTR *ppTLibAttr)
2122 ICOM_THIS( ITypeLibImpl, iface);
2123 TRACE("(%p)\n",This);
2124 /* FIXME: must do a copy here */
2125 *ppTLibAttr=&This->LibAttr;
2129 /* ITypeLib::GetTypeComp
2131 * Enables a client compiler to bind to a library's types, variables,
2132 * constants, and global functions.
2135 static HRESULT WINAPI ITypeLib2_fnGetTypeComp(
2137 ITypeComp **ppTComp)
2139 ICOM_THIS( ITypeLibImpl, iface);
2140 FIXME("(%p): stub!\n",This);
2144 /* ITypeLib::GetDocumentation
2146 * Retrieves the library's documentation string, the complete Help file name
2147 * and path, and the context identifier for the library Help topic in the Help
2151 static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
2155 BSTR *pBstrDocString,
2156 DWORD *pdwHelpContext,
2157 BSTR *pBstrHelpFile)
2159 ICOM_THIS( ITypeLibImpl, iface);
2161 HRESULT result = E_INVALIDARG;
2166 TRACE("(%p) index %d Name(%p) DocString(%p) HelpContext(%p) HelpFile(%p)\n",
2168 pBstrName, pBstrDocString,
2169 pdwHelpContext, pBstrHelpFile);
2173 /* documentation for the typelib */
2174 if(pBstrName && This->Name)
2176 *pBstrName = SysAllocString(This->Name);
2178 if (!(*pBstrName)) return STG_E_INSUFFICIENTMEMORY;
2180 if(pBstrDocString && This->DocString)
2182 *pBstrDocString = SysAllocString(This->DocString);
2184 if (!(*pBstrDocString)) return STG_E_INSUFFICIENTMEMORY;
2189 *pdwHelpContext = This->dwHelpContext;
2191 if(pBstrHelpFile && This->HelpFile)
2193 *pBstrHelpFile = SysAllocString(This->HelpFile);
2195 if (!(*pBstrHelpFile)) return STG_E_INSUFFICIENTMEMORY;
2202 /* for a typeinfo */
2203 result = ITypeLib2_fnGetTypeInfo(iface, index, &pTInfo);
2205 if(SUCCEEDED(result))
2207 result = ITypeInfo_GetDocumentation(pTInfo,
2211 pdwHelpContext, pBstrHelpFile);
2213 ITypeInfo_Release(pTInfo);
2221 * Indicates whether a passed-in string contains the name of a type or member
2222 * described in the library.
2225 static HRESULT WINAPI ITypeLib2_fnIsName(
2231 ICOM_THIS( ITypeLibImpl, iface);
2232 ITypeInfoImpl *pTInfo;
2233 TLBFuncDesc *pFInfo;
2236 UINT nNameBufLen = SysStringLen(szNameBuf);
2238 TRACE("(%p)->(%s,%08lx,%p)\n", This, debugstr_w(szNameBuf), lHashVal,
2242 for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){
2243 if(!memcmp(szNameBuf,pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
2244 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
2245 if(!memcmp(szNameBuf,pFInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
2246 for(i=0;i<pFInfo->funcdesc.cParams;i++)
2247 if(!memcmp(szNameBuf,pFInfo->pParamDesc[i].Name, nNameBufLen))
2248 goto ITypeLib2_fnIsName_exit;
2250 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next)
2251 if(!memcmp(szNameBuf,pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
2256 ITypeLib2_fnIsName_exit:
2257 TRACE("(%p)slow! search for %s: %s found!\n", This,
2258 debugstr_w(szNameBuf), *pfName?"NOT":"");
2263 /* ITypeLib::FindName
2265 * Finds occurrences of a type description in a type library. This may be used
2266 * to quickly verify that a name exists in a type library.
2269 static HRESULT WINAPI ITypeLib2_fnFindName(
2273 ITypeInfo **ppTInfo,
2277 ICOM_THIS( ITypeLibImpl, iface);
2278 ITypeInfoImpl *pTInfo;
2279 TLBFuncDesc *pFInfo;
2283 UINT nNameBufLen = SysStringLen(szNameBuf);
2285 for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){
2286 if(!memcmp(szNameBuf,pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnFindName_exit;
2287 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
2288 if(!memcmp(szNameBuf,pFInfo->Name,nNameBufLen)) goto ITypeLib2_fnFindName_exit;
2289 for(i=0;i<pFInfo->funcdesc.cParams;i++)
2290 if(!memcmp(szNameBuf,pFInfo->pParamDesc[i].Name,nNameBufLen))
2291 goto ITypeLib2_fnFindName_exit;
2293 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next)
2294 if(!memcmp(szNameBuf,pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnFindName_exit;
2296 ITypeLib2_fnFindName_exit:
2297 ITypeInfo_AddRef((ITypeInfo*)pTInfo);
2298 ppTInfo[j]=(LPTYPEINFO)pTInfo;
2301 TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
2302 This, *pcFound, debugstr_w(szNameBuf), j);
2309 /* ITypeLib::ReleaseTLibAttr
2311 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
2314 static VOID WINAPI ITypeLib2_fnReleaseTLibAttr(
2316 TLIBATTR *pTLibAttr)
2318 ICOM_THIS( ITypeLibImpl, iface);
2319 TRACE("freeing (%p)\n",This);
2323 /* ITypeLib2::GetCustData
2325 * gets the custom data
2327 static HRESULT WINAPI ITypeLib2_fnGetCustData(
2332 ICOM_THIS( ITypeLibImpl, iface);
2333 TLBCustData *pCData;
2335 for(pCData=This->pCustData; pCData; pCData = pCData->next)
2337 if( IsEqualIID(guid, &pCData->guid)) break;
2340 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2344 VariantInit( pVarVal);
2345 VariantCopy( pVarVal, &pCData->data);
2348 return E_INVALIDARG; /* FIXME: correct? */
2351 /* ITypeLib2::GetLibStatistics
2353 * Returns statistics about a type library that are required for efficient
2354 * sizing of hash tables.
2357 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(
2359 ULONG *pcUniqueNames,
2360 ULONG *pcchUniqueNames)
2362 ICOM_THIS( ITypeLibImpl, iface);
2364 FIXME("(%p): stub!\n", This);
2366 if(pcUniqueNames) *pcUniqueNames=1;
2367 if(pcchUniqueNames) *pcchUniqueNames=1;
2371 /* ITypeLib2::GetDocumentation2
2373 * Retrieves the library's documentation string, the complete Help file name
2374 * and path, the localization context to use, and the context ID for the
2375 * library Help topic in the Help file.
2378 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
2382 BSTR *pbstrHelpString,
2383 DWORD *pdwHelpStringContext,
2384 BSTR *pbstrHelpStringDll)
2386 ICOM_THIS( ITypeLibImpl, iface);
2390 FIXME("(%p) index %d lcid %ld half implemented stub!\n", This, index, lcid);
2392 /* the help string should be obtained from the helpstringdll,
2393 * using the _DLLGetDocumentation function, based on the supplied
2394 * lcid. Nice to do sometime...
2398 /* documentation for the typelib */
2400 *pbstrHelpString=SysAllocString(This->DocString);
2401 if(pdwHelpStringContext)
2402 *pdwHelpStringContext=This->dwHelpContext;
2403 if(pbstrHelpStringDll)
2404 *pbstrHelpStringDll=SysAllocString(This->HelpStringDll);
2410 /* for a typeinfo */
2411 result=ITypeLib2_GetTypeInfo(iface, index, &pTInfo);
2413 if(SUCCEEDED(result))
2415 ITypeInfo2 * pTInfo2;
2416 result = ITypeInfo_QueryInterface(pTInfo,
2418 (LPVOID*) &pTInfo2);
2420 if(SUCCEEDED(result))
2422 result = ITypeInfo2_GetDocumentation2(pTInfo2,
2426 pdwHelpStringContext,
2427 pbstrHelpStringDll);
2429 ITypeInfo2_Release(pTInfo2);
2432 ITypeInfo_Release(pTInfo);
2438 /* ITypeLib2::GetAllCustData
2440 * Gets all custom data items for the library.
2443 static HRESULT WINAPI ITypeLib2_fnGetAllCustData(
2445 CUSTDATA *pCustData)
2447 ICOM_THIS( ITypeLibImpl, iface);
2448 TLBCustData *pCData;
2450 TRACE("(%p) returning %d items\n", This, This->ctCustData);
2451 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
2452 if(pCustData->prgCustData ){
2453 pCustData->cCustData=This->ctCustData;
2454 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
2455 pCustData->prgCustData[i].guid=pCData->guid;
2456 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
2459 ERR(" OUT OF MEMORY! \n");
2460 return E_OUTOFMEMORY;
2465 static ICOM_VTABLE(ITypeLib2) tlbvt = {
2466 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2467 ITypeLib2_fnQueryInterface,
2469 ITypeLib2_fnRelease,
2470 ITypeLib2_fnGetTypeInfoCount,
2471 ITypeLib2_fnGetTypeInfo,
2472 ITypeLib2_fnGetTypeInfoType,
2473 ITypeLib2_fnGetTypeInfoOfGuid,
2474 ITypeLib2_fnGetLibAttr,
2475 ITypeLib2_fnGetTypeComp,
2476 ITypeLib2_fnGetDocumentation,
2478 ITypeLib2_fnFindName,
2479 ITypeLib2_fnReleaseTLibAttr,
2481 ITypeLib2_fnGetCustData,
2482 ITypeLib2_fnGetLibStatistics,
2483 ITypeLib2_fnGetDocumentation2,
2484 ITypeLib2_fnGetAllCustData
2487 /*================== ITypeInfo(2) Methods ===================================*/
2488 static ITypeInfo2 * WINAPI ITypeInfo_Constructor(void)
2490 ITypeInfoImpl * pTypeInfoImpl;
2492 pTypeInfoImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeInfoImpl));
2495 ICOM_VTBL(pTypeInfoImpl) = &tinfvt;
2496 pTypeInfoImpl->ref=1;
2498 TRACE("(%p)\n", pTypeInfoImpl);
2499 return (ITypeInfo2*) pTypeInfoImpl;
2502 /* ITypeInfo::QueryInterface
2504 static HRESULT WINAPI ITypeInfo_fnQueryInterface(
2509 ICOM_THIS( ITypeLibImpl, iface);
2511 TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
2514 if(IsEqualIID(riid, &IID_IUnknown) ||
2515 IsEqualIID(riid,&IID_ITypeInfo)||
2516 IsEqualIID(riid,&IID_ITypeInfo2))
2520 ITypeInfo_AddRef(iface);
2521 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
2524 TRACE("-- Interface: E_NOINTERFACE\n");
2525 return E_NOINTERFACE;
2528 /* ITypeInfo::AddRef
2530 static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface)
2532 ICOM_THIS( ITypeInfoImpl, iface);
2536 TRACE("(%p)->ref is %u\n",This, This->ref);
2540 /* ITypeInfo::Release
2542 static ULONG WINAPI ITypeInfo_fnRelease( ITypeInfo2 *iface)
2544 ICOM_THIS( ITypeInfoImpl, iface);
2548 TRACE("(%p)->(%u)\n",This, This->ref);
2552 FIXME("destroy child objects\n");
2554 TRACE("destroying ITypeInfo(%p)\n",This);
2557 SysFreeString(This->Name);
2561 if (This->DocString)
2563 SysFreeString(This->DocString);
2564 This->DocString = 0;
2569 ITypeInfo_Release((ITypeInfo*)This->next);
2572 HeapFree(GetProcessHeap(),0,This);
2578 /* ITypeInfo::GetTypeAttr
2580 * Retrieves a TYPEATTR structure that contains the attributes of the type
2584 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface,
2585 LPTYPEATTR *ppTypeAttr)
2587 ICOM_THIS( ITypeInfoImpl, iface);
2588 TRACE("(%p)\n",This);
2589 /* FIXME: must do a copy here */
2590 *ppTypeAttr=&This->TypeAttr;
2594 /* ITypeInfo::GetTypeComp
2596 * Retrieves the ITypeComp interface for the type description, which enables a
2597 * client compiler to bind to the type description's members.
2600 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( ITypeInfo2 *iface,
2601 ITypeComp * *ppTComp)
2603 ICOM_THIS( ITypeInfoImpl, iface);
2604 FIXME("(%p) stub!\n", This);
2608 /* ITypeInfo::GetFuncDesc
2610 * Retrieves the FUNCDESC structure that contains information about a
2611 * specified function.
2614 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( ITypeInfo2 *iface, UINT index,
2615 LPFUNCDESC *ppFuncDesc)
2617 ICOM_THIS( ITypeInfoImpl, iface);
2619 TLBFuncDesc * pFDesc;
2620 TRACE("(%p) index %d\n", This, index);
2621 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
2624 /* FIXME: must do a copy here */
2625 *ppFuncDesc=&pFDesc->funcdesc;
2628 return E_INVALIDARG;
2631 /* ITypeInfo::GetVarDesc
2633 * Retrieves a VARDESC structure that describes the specified variable.
2636 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( ITypeInfo2 *iface, UINT index,
2637 LPVARDESC *ppVarDesc)
2639 ICOM_THIS( ITypeInfoImpl, iface);
2641 TLBVarDesc * pVDesc;
2642 TRACE("(%p) index %d\n", This, index);
2643 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next)
2646 /* FIXME: must do a copy here */
2647 *ppVarDesc=&pVDesc->vardesc;
2650 return E_INVALIDARG;
2653 /* ITypeInfo_GetNames
2655 * Retrieves the variable with the specified member ID (or the name of the
2656 * property or method and its parameters) that correspond to the specified
2659 static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
2660 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
2662 ICOM_THIS( ITypeInfoImpl, iface);
2663 TLBFuncDesc * pFDesc;
2664 TLBVarDesc * pVDesc;
2666 TRACE("(%p) memid=0x%08lx Maxname=%d\n", This, memid, cMaxNames);
2667 for(pFDesc=This->funclist; pFDesc && pFDesc->funcdesc.memid != memid; pFDesc=pFDesc->next);
2670 /* function found, now return function and parameter names */
2671 for(i=0; i<cMaxNames && i <= pFDesc->funcdesc.cParams; i++)
2674 *rgBstrNames=SysAllocString(pFDesc->Name);
2676 rgBstrNames[i]=SysAllocString(pFDesc->pParamDesc[i-1].Name);
2682 for(pVDesc=This->varlist; pVDesc && pVDesc->vardesc.memid != memid; pVDesc=pVDesc->next);
2685 *rgBstrNames=SysAllocString(pVDesc->Name);
2690 if(This->TypeAttr.typekind==TKIND_INTERFACE && This->TypeAttr.cImplTypes )
2692 /* recursive search */
2695 result=ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->reference, &pTInfo);
2696 if(SUCCEEDED(result))
2698 result=ITypeInfo_GetNames(pTInfo, memid, rgBstrNames, cMaxNames, pcNames);
2699 ITypeInfo_Release(pTInfo);
2702 WARN("Could not search inherited interface!\n");
2706 WARN("no names found\n");
2709 return TYPE_E_ELEMENTNOTFOUND;
2716 /* ITypeInfo::GetRefTypeOfImplType
2718 * If a type description describes a COM class, it retrieves the type
2719 * description of the implemented interface types. For an interface,
2720 * GetRefTypeOfImplType returns the type information for inherited interfaces,
2724 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType(
2729 ICOM_THIS( ITypeInfoImpl, iface);
2731 TLBRefType *pIref = This->impltypelist;
2733 TRACE("(%p) index %d\n", This, index);
2734 dump_TypeInfo(This);
2738 /* only valid on dual interfaces;
2739 retrieve the associated TKIND_INTERFACE handle for the current TKIND_DISPATCH
2741 if( This->TypeAttr.typekind != TKIND_DISPATCH) return E_INVALIDARG;
2743 if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDISPATCHABLE &&
2744 This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL )
2750 if (!pIref) return TYPE_E_ELEMENTNOTFOUND;
2751 *pRefType = pIref->reference;
2756 /* get element n from linked list */
2757 for(i=0; pIref && i<index; i++)
2759 pIref = pIref->next;
2762 if (!pIref) return TYPE_E_ELEMENTNOTFOUND;
2764 *pRefType = pIref->reference;
2766 TRACE("-- 0x%08lx %s\n",pIref->reference, debugstr_guid(&pIref->guid) );
2773 /* ITypeInfo::GetImplTypeFlags
2775 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
2776 * or base interface in a type description.
2778 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( ITypeInfo2 *iface,
2779 UINT index, INT *pImplTypeFlags)
2781 ICOM_THIS( ITypeInfoImpl, iface);
2784 TRACE("(%p) index %d\n", This, index);
2785 for(i=0, pIref=This->impltypelist; i<index && pIref; i++, pIref=pIref->next)
2787 if(i==index && pIref){
2788 *pImplTypeFlags=pIref->flags;
2792 return TYPE_E_ELEMENTNOTFOUND;
2796 * Maps between member names and member IDs, and parameter names and
2799 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface,
2800 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
2802 ICOM_THIS( ITypeInfoImpl, iface);
2803 TLBFuncDesc * pFDesc;
2804 TLBVarDesc * pVDesc;
2806 UINT nNameLen = SysStringLen(*rgszNames);
2808 TRACE("(%p) Name %s cNames %d\n", This, debugstr_w(*rgszNames),
2810 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) {
2812 if( !memcmp(*rgszNames, pFDesc->Name, nNameLen)) {
2813 if(cNames) *pMemId=pFDesc->funcdesc.memid;
2814 for(i=1; i < cNames; i++){
2815 UINT nParamLen = SysStringLen(rgszNames[i]);
2816 for(j=0; j<pFDesc->funcdesc.cParams; j++)
2817 if(memcmp(rgszNames[i],pFDesc->pParamDesc[j].Name, nParamLen))
2819 if( j<pFDesc->funcdesc.cParams)
2822 ret=DISP_E_UNKNOWNNAME;
2827 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
2828 if( !memcmp(*rgszNames, pVDesc->Name, nNameLen)) {
2829 if(cNames) *pMemId=pVDesc->vardesc.memid;
2833 /* not found, see if this is and interface with an inheritance */
2834 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
2835 This->TypeAttr.cImplTypes ){
2836 /* recursive search */
2838 ret=ITypeInfo_GetRefTypeInfo(iface,
2839 This->impltypelist->reference, &pTInfo);
2841 ret=ITypeInfo_GetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
2842 ITypeInfo_Release(pTInfo);
2845 WARN("Could not search inherited interface!\n");
2847 WARN("no names found\n");
2848 return DISP_E_UNKNOWNNAME;
2851 /* ITypeInfo::Invoke
2853 * Invokes a method, or accesses a property of an object, that implements the
2854 * interface described by the type description.
2856 static DWORD _invoke(LPVOID func,CALLCONV callconv, int nrargs, DWORD *args) {
2859 if (TRACE_ON(ole)) {
2861 MESSAGE("Calling %p(",func);
2862 for (i=0;i<nrargs;i++) MESSAGE("%08lx,",args[i]);
2871 DWORD (WINAPI *xfunc)() = func;
2876 DWORD (WINAPI *xfunc)(DWORD) = func;
2877 res = xfunc(args[0]);
2881 DWORD (WINAPI *xfunc)(DWORD,DWORD) = func;
2882 res = xfunc(args[0],args[1]);
2886 DWORD (WINAPI *xfunc)(DWORD,DWORD,DWORD) = func;
2887 res = xfunc(args[0],args[1],args[2]);
2891 FIXME("unsupported number of arguments %d in stdcall\n",nrargs);
2897 FIXME("unsupported calling convention %d\n",callconv);
2901 TRACE("returns %08lx\n",res);
2905 static HRESULT WINAPI ITypeInfo_fnInvoke(
2910 DISPPARAMS *pDispParams,
2911 VARIANT *pVarResult,
2912 EXCEPINFO *pExcepInfo,
2915 ICOM_THIS( ITypeInfoImpl, iface);
2916 TLBFuncDesc * pFDesc;
2917 TLBVarDesc * pVDesc;
2920 TRACE("(%p)(%p,id=%ld,flags=0x%08x,%p,%p,%p,%p) partial stub!\n",
2921 This,pIUnk,memid,dwFlags,pDispParams,pVarResult,pExcepInfo,pArgErr
2923 dump_DispParms(pDispParams);
2925 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
2926 if (pFDesc->funcdesc.memid == memid) {
2927 if (pFDesc->funcdesc.invkind & (dwFlags & ~DISPATCH_METHOD))
2931 dump_TLBFuncDescOne(pFDesc);
2932 switch (pFDesc->funcdesc.funckind) {
2933 case FUNC_PUREVIRTUAL:
2934 case FUNC_VIRTUAL: {
2936 DWORD *args = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*(pFDesc->funcdesc.cParams+1));
2937 DWORD *args2 = (DWORD*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD)*(pFDesc->funcdesc.cParams));
2938 args[0] = (DWORD)pIUnk;
2940 for (i=0;i<pFDesc->funcdesc.cParams;i++) {
2941 if (i<pDispParams->cArgs) {
2942 TRACE("set %d to disparg type %d vs %d\n",i,
2943 pDispParams->rgvarg[i].vt,
2944 pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt
2946 args[i+1] = pDispParams->rgvarg[i].u.lVal;
2948 TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i].tdesc);
2949 TRACE("set %d to pointer for get (type is %d)\n",i,tdesc->vt);
2950 /*FIXME: give pointers for the rest, so propertyget works*/
2951 args[i+1] = (DWORD)&args2[i];
2953 /* If pointer to variant, pass reference to variant
2954 * in result variant array.
2956 if ((tdesc->vt == VT_PTR) &&
2957 (tdesc->u.lptdesc->vt == VT_VARIANT) &&
2960 args[i+1] = (DWORD)(pVarResult+(i-pDispParams->cArgs));
2963 if (pFDesc->funcdesc.cParamsOpt)
2964 FIXME("Does not support optional parameters (%d)\n",
2965 pFDesc->funcdesc.cParamsOpt
2968 res = _invoke((*(DWORD***)pIUnk)[pFDesc->funcdesc.oVft/4],
2969 pFDesc->funcdesc.callconv,
2970 pFDesc->funcdesc.cParams+1,
2973 if (pVarResult && (dwFlags & (DISPATCH_PROPERTYGET))) {
2974 for (i=0;i<pFDesc->funcdesc.cParams-pDispParams->cArgs;i++) {
2975 TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i].tdesc);
2976 /* If we are a pointer to a variant, we are done already */
2977 if ((tdesc->vt==VT_PTR)&&(tdesc->u.lptdesc->vt==VT_VARIANT))
2980 VariantInit(&pVarResult[i]);
2981 pVarResult[i].u.intVal = args2[i];
2983 if (tdesc->vt == VT_PTR)
2984 tdesc = tdesc->u.lptdesc;
2985 pVarResult[i].vt = tdesc->vt;
2987 /* HACK: VB5 likes this.
2988 * I do not know why. There is 1 example in MSDN which uses
2989 * this which appears broken (mixes int vals and
2992 if ((tdesc->vt == VT_PTR) && (dwFlags & DISPATCH_METHOD))
2993 pVarResult[i].vt = VT_DISPATCH;
2994 TRACE("storing into variant: [%d] type %d, val %08x\n",
2995 i,pVarResult[i].vt,pVarResult[i].u.intVal
2999 HeapFree(GetProcessHeap(),0,args2);
3000 HeapFree(GetProcessHeap(),0,args);
3003 case FUNC_DISPATCH: {
3007 hr = IUnknown_QueryInterface((LPUNKNOWN)pIUnk,&IID_IDispatch,(LPVOID*)&disp);
3009 FIXME("FUNC_DISPATCH used on object without IDispatch iface?\n");
3012 FIXME("Calling Invoke in IDispatch iface. untested!\n");
3013 hr = IDispatch_Invoke(
3014 disp,memid,&IID_NULL,LOCALE_USER_DEFAULT,dwFlags,pDispParams,
3015 pVarResult,pExcepInfo,pArgErr
3018 FIXME("IDispatch::Invoke failed with %08lx. (Could be not a real error?)\n",hr);
3019 IDispatch_Release(disp);
3023 FIXME("Unknown function invocation type %d\n",pFDesc->funcdesc.funckind);
3027 FIXME("variable based invoking not supported yet.\n");
3028 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
3029 if (pVDesc->vardesc.memid == memid) {
3030 FIXME("varseek: Found memid name %s\n",debugstr_w(((LPWSTR)pVDesc->Name)));
3031 dump_TLBVarDesc(pVDesc);
3036 FIXME("Did not find member id %d!\n",(int)memid);
3037 return DISP_E_MEMBERNOTFOUND;
3040 /* ITypeInfo::GetDocumentation
3042 * Retrieves the documentation string, the complete Help file name and path,
3043 * and the context ID for the Help topic for a specified type description.
3045 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( ITypeInfo2 *iface,
3046 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
3047 DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
3049 ICOM_THIS( ITypeInfoImpl, iface);
3050 TLBFuncDesc * pFDesc;
3051 TLBVarDesc * pVDesc;
3052 TRACE("(%p) memid %ld Name(%p) DocString(%p)"
3053 " HelpContext(%p) HelpFile(%p)\n",
3054 This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
3055 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
3057 *pBstrName=SysAllocString(This->Name);
3059 *pBstrDocString=SysAllocString(This->DocString);
3061 *pdwHelpContext=This->dwHelpContext;
3063 *pBstrHelpFile=SysAllocString(This->DocString);/* FIXME */
3065 }else {/* for a member */
3066 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
3067 if(pFDesc->funcdesc.memid==memid){
3070 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
3071 if(pVDesc->vardesc.memid==memid){
3075 return TYPE_E_ELEMENTNOTFOUND;
3078 /* ITypeInfo::GetDllEntry
3080 * Retrieves a description or specification of an entry point for a function
3083 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid,
3084 INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
3087 ICOM_THIS( ITypeInfoImpl, iface);
3088 FIXME("(%p) stub!\n", This);
3092 /* ITypeInfo::GetRefTypeInfo
3094 * If a type description references other type descriptions, it retrieves
3095 * the referenced type descriptions.
3097 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
3100 ITypeInfo **ppTInfo)
3102 ICOM_THIS( ITypeInfoImpl, iface);
3103 HRESULT result = E_FAIL;
3105 if(HREFTYPE_INTHISFILE(hRefType))
3109 result = ITypeInfo_GetContainingTypeLib(iface, &pTLib, &Index);
3110 if(SUCCEEDED( result ))
3112 result=ITypeLib2_GetTypeInfo(pTLib, HREFTYPE_INDEX(hRefType), ppTInfo);
3113 ITypeLib2_Release(pTLib );
3116 else if (hRefType == -1 &&
3117 (((ITypeInfoImpl*) This)->TypeAttr.typekind == TKIND_DISPATCH) &&
3118 (((ITypeInfoImpl*) This)->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL))
3120 /* when we meet a DUAL dispinterface, we must create the interface
3123 ITypeInfoImpl* pTypeInfoImpl = (ITypeInfoImpl*) ITypeInfo_Constructor();
3126 /* the interface version contains the same information as the dispinterface
3127 * copy the contents of the structs.
3129 *pTypeInfoImpl = *This;
3130 pTypeInfoImpl->ref = 1;
3132 /* change the type to interface */
3133 pTypeInfoImpl->TypeAttr.typekind = TKIND_INTERFACE;
3135 *ppTInfo = (ITypeInfo*) pTypeInfoImpl;
3137 ITypeInfo_AddRef((ITypeInfo*) pTypeInfoImpl);
3143 /* imported type lib */
3144 TLBRefType *pRefType = NULL;
3146 /* search in implemented types */
3147 for( pRefType = This->impltypelist;
3148 pRefType && (pRefType->reference != hRefType);
3149 pRefType = pRefType->next);
3153 TYPEATTR* pMyTypeAttr = &This->TypeAttr;
3154 unsigned short cFuncs = pMyTypeAttr->cFuncs;
3155 unsigned short cVars = pMyTypeAttr->cVars;
3157 /* search in arguments */
3160 unsigned short cFuncIndex = 0;
3162 TLBFuncDesc* pCurrFunc = This->funclist;
3164 for (cFuncIndex = 0; !pRefType && cFuncIndex < cFuncs ; ++cFuncIndex)
3166 FUNCDESC* pCurrFuncDesc = &pCurrFunc->funcdesc;
3168 short cParams = pCurrFuncDesc->cParams;
3169 short cParamIndex = 0;
3171 for (cParamIndex = 0 ;
3172 !pRefType && cParamIndex < cParams ;
3175 TLBParDesc* pCurrParamDesc = &(pCurrFunc->pParamDesc[cParamIndex]);
3177 if ( pCurrParamDesc->pRefType && pCurrParamDesc->pRefType->reference == hRefType)
3179 pRefType = pCurrParamDesc->pRefType;
3180 break; /* also break from outer loop since pRefType != 0 */
3184 pCurrFunc = pCurrFunc->next;
3187 /* search in variables */
3190 FIXME("search hreftype in variables, if any\n");
3191 result = E_INVALIDARG; // FIXME : correct?
3195 /* href-referenced typeinfo found! */
3196 if (pRefType || hRefType == -1)
3198 ITypeLibImpl *pTypeLib = pRefType->pImpTLInfo->pImpTypeLib;
3202 TRACE("typeinfo in imported typelib that is already loaded\n");
3204 result = ITypeLib2_GetTypeInfoOfGuid((LPTYPELIB)pTypeLib,
3210 result = LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
3211 pRefType->pImpTLInfo->wVersionMajor,
3212 pRefType->pImpTLInfo->wVersionMinor,
3213 pRefType->pImpTLInfo->lcid,
3214 (LPTYPELIB *)&pTypeLib);
3216 if(!SUCCEEDED(result))
3218 BSTR libnam=SysAllocString(pRefType->pImpTLInfo->name);
3219 TRACE("typeinfo in imported typelib that isn't already loaded\n");
3220 result=LoadTypeLib(libnam, (LPTYPELIB *)&pTypeLib);
3221 SysFreeString(libnam);
3223 if(SUCCEEDED(result))
3225 result=ITypeLib2_GetTypeInfoOfGuid((LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
3226 pRefType->pImpTLInfo->pImpTypeLib = pTypeLib;
3227 ITypeLib2_AddRef((ITypeLib*) pTypeLib);
3233 TRACE("(%p) hreftype 0x%04lx loaded %s (%p)\n", This, hRefType,
3234 SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
3238 /* ITypeInfo::AddressOfMember
3240 * Retrieves the addresses of static functions or variables, such as those
3243 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface,
3244 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
3246 ICOM_THIS( ITypeInfoImpl, iface);
3247 FIXME("(%p) stub!\n", This);
3251 /* ITypeInfo::CreateInstance
3253 * Creates a new instance of a type that describes a component object class
3256 static HRESULT WINAPI ITypeInfo_fnCreateInstance( ITypeInfo2 *iface,
3257 IUnknown *pUnk, REFIID riid, VOID **ppvObj)
3259 ICOM_THIS( ITypeInfoImpl, iface);
3260 FIXME("(%p) stub!\n", This);
3264 /* ITypeInfo::GetMops
3266 * Retrieves marshaling information.
3268 static HRESULT WINAPI ITypeInfo_fnGetMops( ITypeInfo2 *iface, MEMBERID memid,
3271 ICOM_THIS( ITypeInfoImpl, iface);
3272 FIXME("(%p) stub!\n", This);
3276 /* ITypeInfo::GetContainingTypeLib
3278 * Retrieves the containing type library and the index of the type description
3279 * within that type library.
3281 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( ITypeInfo2 *iface,
3282 ITypeLib * *ppTLib, UINT *pIndex)
3284 ICOM_THIS( ITypeInfoImpl, iface);
3286 return E_INVALIDARG;
3287 *ppTLib=(LPTYPELIB )(This->pTypeLib);
3288 *pIndex=This->index;
3289 ITypeLib2_AddRef(*ppTLib);
3290 TRACE("(%p) returns (%p) index %d!\n", This, *ppTLib, *pIndex);
3294 /* ITypeInfo::ReleaseTypeAttr
3296 * Releases a TYPEATTR previously returned by GetTypeAttr.
3299 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( ITypeInfo2 *iface,
3300 TYPEATTR* pTypeAttr)
3302 ICOM_THIS( ITypeInfoImpl, iface);
3303 TRACE("(%p)->(%p)\n", This, pTypeAttr);
3307 /* ITypeInfo::ReleaseFuncDesc
3309 * Releases a FUNCDESC previously returned by GetFuncDesc. *
3311 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc(
3313 FUNCDESC *pFuncDesc)
3315 ICOM_THIS( ITypeInfoImpl, iface);
3316 TRACE("(%p)->(%p)\n", This, pFuncDesc);
3320 /* ITypeInfo::ReleaseVarDesc
3322 * Releases a VARDESC previously returned by GetVarDesc.
3324 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( ITypeInfo2 *iface,
3327 ICOM_THIS( ITypeInfoImpl, iface);
3328 TRACE("(%p)->(%p)\n", This, pVarDesc);
3332 /* ITypeInfo2::GetTypeKind
3334 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
3337 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo2 * iface,
3338 TYPEKIND *pTypeKind)
3340 ICOM_THIS( ITypeInfoImpl, iface);
3341 *pTypeKind=This->TypeAttr.typekind;
3342 TRACE("(%p) type 0x%0x\n", This,*pTypeKind);
3346 /* ITypeInfo2::GetTypeFlags
3348 * Returns the type flags without any allocations. This returns a DWORD type
3349 * flag, which expands the type flags without growing the TYPEATTR (type
3353 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo2 * iface,
3356 ICOM_THIS( ITypeInfoImpl, iface);
3357 *pTypeFlags=This->TypeAttr.wTypeFlags;
3358 TRACE("(%p) flags 0x%04x\n", This,*pTypeFlags);
3362 /* ITypeInfo2::GetFuncIndexOfMemId
3363 * Binds to a specific member based on a known DISPID, where the member name
3364 * is not known (for example, when binding to a default member).
3367 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2 * iface,
3368 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
3370 ICOM_THIS( ITypeInfoImpl, iface);
3371 TLBFuncDesc *pFuncInfo;
3374 /* FIXME: should check for invKind??? */
3375 for(i=0, pFuncInfo=This->funclist;pFuncInfo &&
3376 memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next);
3382 result=E_INVALIDARG;
3384 TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This,
3385 memid, invKind, SUCCEEDED(result)? "SUCCES":"FAILED");
3389 /* TypeInfo2::GetVarIndexOfMemId
3391 * Binds to a specific member based on a known DISPID, where the member name
3392 * is not known (for example, when binding to a default member).
3395 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo2 * iface,
3396 MEMBERID memid, UINT *pVarIndex)
3398 ICOM_THIS( ITypeInfoImpl, iface);
3399 TLBVarDesc *pVarInfo;
3402 for(i=0, pVarInfo=This->varlist; pVarInfo &&
3403 memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next)
3410 result=E_INVALIDARG;
3412 TRACE("(%p) memid 0x%08lx -> %s\n", This,
3413 memid, SUCCEEDED(result)? "SUCCES":"FAILED");
3417 /* ITypeInfo2::GetCustData
3419 * Gets the custom data
3421 static HRESULT WINAPI ITypeInfo2_fnGetCustData(
3426 ICOM_THIS( ITypeInfoImpl, iface);
3427 TLBCustData *pCData;
3429 for(pCData=This->pCustData; pCData; pCData = pCData->next)
3430 if( IsEqualIID(guid, &pCData->guid)) break;
3432 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
3436 VariantInit( pVarVal);
3437 VariantCopy( pVarVal, &pCData->data);
3440 return E_INVALIDARG; /* FIXME: correct? */
3443 /* ITypeInfo2::GetFuncCustData
3445 * Gets the custom data
3447 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData(
3453 ICOM_THIS( ITypeInfoImpl, iface);
3454 TLBCustData *pCData=NULL;
3455 TLBFuncDesc * pFDesc;
3457 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
3458 pFDesc=pFDesc->next);
3461 for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next)
3462 if( IsEqualIID(guid, &pCData->guid)) break;
3464 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
3467 VariantInit( pVarVal);
3468 VariantCopy( pVarVal, &pCData->data);
3471 return E_INVALIDARG; /* FIXME: correct? */
3474 /* ITypeInfo2::GetParamCustData
3476 * Gets the custom data
3478 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData(
3485 ICOM_THIS( ITypeInfoImpl, iface);
3486 TLBCustData *pCData=NULL;
3487 TLBFuncDesc * pFDesc;
3490 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,pFDesc=pFDesc->next);
3492 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams)
3493 for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData;
3494 pCData = pCData->next)
3495 if( IsEqualIID(guid, &pCData->guid)) break;
3497 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
3501 VariantInit( pVarVal);
3502 VariantCopy( pVarVal, &pCData->data);
3505 return E_INVALIDARG; /* FIXME: correct? */
3508 /* ITypeInfo2::GetVarcCustData
3510 * Gets the custom data
3512 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData(
3518 ICOM_THIS( ITypeInfoImpl, iface);
3519 TLBCustData *pCData=NULL;
3520 TLBVarDesc * pVDesc;
3523 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next);
3527 for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next)
3529 if( IsEqualIID(guid, &pCData->guid)) break;
3533 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
3537 VariantInit( pVarVal);
3538 VariantCopy( pVarVal, &pCData->data);
3541 return E_INVALIDARG; /* FIXME: correct? */
3544 /* ITypeInfo2::GetImplcCustData
3546 * Gets the custom data
3548 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData(
3554 ICOM_THIS( ITypeInfoImpl, iface);
3555 TLBCustData *pCData=NULL;
3556 TLBRefType * pRDesc;
3559 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++, pRDesc=pRDesc->next);
3563 for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next)
3565 if( IsEqualIID(guid, &pCData->guid)) break;
3569 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
3573 VariantInit( pVarVal);
3574 VariantCopy( pVarVal, &pCData->data);
3577 return E_INVALIDARG; /* FIXME: correct? */
3580 /* ITypeInfo2::GetDocumentation2
3582 * Retrieves the documentation string, the complete Help file name and path,
3583 * the localization context to use, and the context ID for the library Help
3584 * topic in the Help file.
3587 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(
3591 BSTR *pbstrHelpString,
3592 DWORD *pdwHelpStringContext,
3593 BSTR *pbstrHelpStringDll)
3595 ICOM_THIS( ITypeInfoImpl, iface);
3596 TLBFuncDesc * pFDesc;
3597 TLBVarDesc * pVDesc;
3598 TRACE("(%p) memid %ld lcid(0x%lx) HelpString(%p) "
3599 "HelpStringContext(%p) HelpStringDll(%p)\n",
3600 This, memid, lcid, pbstrHelpString, pdwHelpStringContext,
3601 pbstrHelpStringDll );
3602 /* the help string should be obtained from the helpstringdll,
3603 * using the _DLLGetDocumentation function, based on the supplied
3604 * lcid. Nice to do sometime...
3606 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
3608 *pbstrHelpString=SysAllocString(This->Name);
3609 if(pdwHelpStringContext)
3610 *pdwHelpStringContext=This->dwHelpStringContext;
3611 if(pbstrHelpStringDll)
3612 *pbstrHelpStringDll=
3613 SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */
3615 }else {/* for a member */
3616 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
3617 if(pFDesc->funcdesc.memid==memid){
3619 *pbstrHelpString=SysAllocString(pFDesc->HelpString);
3620 if(pdwHelpStringContext)
3621 *pdwHelpStringContext=pFDesc->HelpStringContext;
3622 if(pbstrHelpStringDll)
3623 *pbstrHelpStringDll=
3624 SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */
3627 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
3628 if(pVDesc->vardesc.memid==memid){
3630 *pbstrHelpString=SysAllocString(pVDesc->HelpString);
3631 if(pdwHelpStringContext)
3632 *pdwHelpStringContext=pVDesc->HelpStringContext;
3633 if(pbstrHelpStringDll)
3634 *pbstrHelpStringDll=
3635 SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */
3639 return TYPE_E_ELEMENTNOTFOUND;
3642 /* ITypeInfo2::GetAllCustData
3644 * Gets all custom data items for the Type info.
3647 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData(
3649 CUSTDATA *pCustData)
3651 ICOM_THIS( ITypeInfoImpl, iface);
3652 TLBCustData *pCData;
3655 TRACE("(%p) returning %d items\n", This, This->ctCustData);
3657 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
3658 if(pCustData->prgCustData ){
3659 pCustData->cCustData=This->ctCustData;
3660 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
3661 pCustData->prgCustData[i].guid=pCData->guid;
3662 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
3665 ERR(" OUT OF MEMORY! \n");
3666 return E_OUTOFMEMORY;
3671 /* ITypeInfo2::GetAllFuncCustData
3673 * Gets all custom data items for the specified Function
3676 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData(
3679 CUSTDATA *pCustData)
3681 ICOM_THIS( ITypeInfoImpl, iface);
3682 TLBCustData *pCData;
3683 TLBFuncDesc * pFDesc;
3685 TRACE("(%p) index %d\n", This, index);
3686 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
3687 pFDesc=pFDesc->next)
3690 pCustData->prgCustData =
3691 TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM));
3692 if(pCustData->prgCustData ){
3693 pCustData->cCustData=pFDesc->ctCustData;
3694 for(i=0, pCData=pFDesc->pCustData; pCData; i++,
3695 pCData = pCData->next){
3696 pCustData->prgCustData[i].guid=pCData->guid;
3697 VariantCopy(& pCustData->prgCustData[i].varValue,
3701 ERR(" OUT OF MEMORY! \n");
3702 return E_OUTOFMEMORY;
3706 return TYPE_E_ELEMENTNOTFOUND;
3709 /* ITypeInfo2::GetAllParamCustData
3711 * Gets all custom data items for the Functions
3714 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo2 * iface,
3715 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
3717 ICOM_THIS( ITypeInfoImpl, iface);
3718 TLBCustData *pCData=NULL;
3719 TLBFuncDesc * pFDesc;
3721 TRACE("(%p) index %d\n", This, indexFunc);
3722 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
3723 pFDesc=pFDesc->next)
3725 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams){
3726 pCustData->prgCustData =
3727 TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData *
3728 sizeof(CUSTDATAITEM));
3729 if(pCustData->prgCustData ){
3730 pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData;
3731 for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData;
3732 pCData; i++, pCData = pCData->next){
3733 pCustData->prgCustData[i].guid=pCData->guid;
3734 VariantCopy(& pCustData->prgCustData[i].varValue,
3738 ERR(" OUT OF MEMORY! \n");
3739 return E_OUTOFMEMORY;
3743 return TYPE_E_ELEMENTNOTFOUND;
3746 /* ITypeInfo2::GetAllVarCustData
3748 * Gets all custom data items for the specified Variable
3751 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo2 * iface,
3752 UINT index, CUSTDATA *pCustData)
3754 ICOM_THIS( ITypeInfoImpl, iface);
3755 TLBCustData *pCData;
3756 TLBVarDesc * pVDesc;
3758 TRACE("(%p) index %d\n", This, index);
3759 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
3760 pVDesc=pVDesc->next)
3763 pCustData->prgCustData =
3764 TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM));
3765 if(pCustData->prgCustData ){
3766 pCustData->cCustData=pVDesc->ctCustData;
3767 for(i=0, pCData=pVDesc->pCustData; pCData; i++,
3768 pCData = pCData->next){
3769 pCustData->prgCustData[i].guid=pCData->guid;
3770 VariantCopy(& pCustData->prgCustData[i].varValue,
3774 ERR(" OUT OF MEMORY! \n");
3775 return E_OUTOFMEMORY;
3779 return TYPE_E_ELEMENTNOTFOUND;
3782 /* ITypeInfo2::GetAllImplCustData
3784 * Gets all custom data items for the specified implementation type
3787 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData(
3790 CUSTDATA *pCustData)
3792 ICOM_THIS( ITypeInfoImpl, iface);
3793 TLBCustData *pCData;
3794 TLBRefType * pRDesc;
3796 TRACE("(%p) index %d\n", This, index);
3797 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
3798 pRDesc=pRDesc->next)
3801 pCustData->prgCustData =
3802 TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM));
3803 if(pCustData->prgCustData ){
3804 pCustData->cCustData=pRDesc->ctCustData;
3805 for(i=0, pCData=pRDesc->pCustData; pCData; i++,
3806 pCData = pCData->next){
3807 pCustData->prgCustData[i].guid=pCData->guid;
3808 VariantCopy(& pCustData->prgCustData[i].varValue,
3812 ERR(" OUT OF MEMORY! \n");
3813 return E_OUTOFMEMORY;
3817 return TYPE_E_ELEMENTNOTFOUND;
3820 static ICOM_VTABLE(ITypeInfo2) tinfvt =
3822 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3824 ITypeInfo_fnQueryInterface,
3826 ITypeInfo_fnRelease,
3828 ITypeInfo_fnGetTypeAttr,
3829 ITypeInfo_fnGetTypeComp,
3830 ITypeInfo_fnGetFuncDesc,
3831 ITypeInfo_fnGetVarDesc,
3832 ITypeInfo_fnGetNames,
3833 ITypeInfo_fnGetRefTypeOfImplType,
3834 ITypeInfo_fnGetImplTypeFlags,
3835 ITypeInfo_fnGetIDsOfNames,
3837 ITypeInfo_fnGetDocumentation,
3838 ITypeInfo_fnGetDllEntry,
3839 ITypeInfo_fnGetRefTypeInfo,
3840 ITypeInfo_fnAddressOfMember,
3841 ITypeInfo_fnCreateInstance,
3842 ITypeInfo_fnGetMops,
3843 ITypeInfo_fnGetContainingTypeLib,
3844 ITypeInfo_fnReleaseTypeAttr,
3845 ITypeInfo_fnReleaseFuncDesc,
3846 ITypeInfo_fnReleaseVarDesc,
3848 ITypeInfo2_fnGetTypeKind,
3849 ITypeInfo2_fnGetTypeFlags,
3850 ITypeInfo2_fnGetFuncIndexOfMemId,
3851 ITypeInfo2_fnGetVarIndexOfMemId,
3852 ITypeInfo2_fnGetCustData,
3853 ITypeInfo2_fnGetFuncCustData,
3854 ITypeInfo2_fnGetParamCustData,
3855 ITypeInfo2_fnGetVarCustData,
3856 ITypeInfo2_fnGetImplTypeCustData,
3857 ITypeInfo2_fnGetDocumentation2,
3858 ITypeInfo2_fnGetAllCustData,
3859 ITypeInfo2_fnGetAllFuncCustData,
3860 ITypeInfo2_fnGetAllParamCustData,
3861 ITypeInfo2_fnGetAllVarCustData,
3862 ITypeInfo2_fnGetAllImplTypeCustData,