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 strucutures 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.
49 #include "winreg.h" /* for HKEY_LOCAL_MACHINE */
50 #include "winnls.h" /* for PRIMARYLANGID */
53 #include "wine/obj_base.h"
54 #include "debugtools.h"
57 DEFAULT_DEBUG_CHANNEL(ole
);
58 DECLARE_DEBUG_CHANNEL(typelib
);
60 /****************************************************************************
61 * QueryPathOfRegTypeLib16 [TYPELIB.14]
63 * the path is "Classes\Typelib\<guid>\<major>.<minor>\<lcid>\win16\"
68 QueryPathOfRegTypeLib16(
69 REFGUID guid
, /* [in] referenced guid */
70 WORD wMaj
, /* [in] major version */
71 WORD wMin
, /* [in] minor version */
72 LCID lcid
, /* [in] locale id */
73 LPBSTR16 path
/* [out] path of typelib */
76 char typelibkey
[100],pathname
[260];
82 sprintf( typelibkey
, "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win16",
83 guid
->Data1
, guid
->Data2
, guid
->Data3
,
84 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
85 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7],
88 sprintf(xguid
,"<guid 0x%08lx>",(DWORD
)guid
);
89 FIXME("(%s,%d,%d,0x%04lx,%p),can't handle non-string guids.\n",xguid
,wMaj
,wMin
,(DWORD
)lcid
,path
);
92 plen
= sizeof(pathname
);
93 if (RegQueryValueA(HKEY_LOCAL_MACHINE
,typelibkey
,pathname
,&plen
)) {
94 /* try again without lang specific id */
96 return QueryPathOfRegTypeLib16(guid
,wMaj
,wMin
,PRIMARYLANGID(lcid
),path
);
97 FIXME("key %s not found\n",typelibkey
);
100 *path
= SysAllocString16(pathname
);
104 /****************************************************************************
105 * QueryPathOfRegTypeLib [OLEAUT32.164]
110 QueryPathOfRegTypeLib(
111 REFGUID guid
, /* [in] referenced guid */
112 WORD wMaj
, /* [in] major version */
113 WORD wMin
, /* [in] minor version */
114 LCID lcid
, /* [in] locale id */
115 LPBSTR path
) /* [out] path of typelib */
117 /* don't need to ZeroMemory those arrays since sprintf and RegQueryValue add
118 string termination character on output strings */
122 DWORD dwPathLen
= _MAX_PATH
;
126 char szTypeLibKey
[100];
127 char szPath
[dwPathLen
];
135 FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n", szXGUID
, wMaj
, wMin
, (DWORD
)lcid
, path
);
141 sprintf(szTypeLibKey
,
142 "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win32",
143 guid
->Data1
, guid
->Data2
, guid
->Data3
,
144 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
145 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7],
150 if (RegQueryValueA(HKEY_LOCAL_MACHINE
, szTypeLibKey
, szPath
, &dwPathLen
))
154 else if (myLCID
== lcid
)
156 /* try with sub-langid */
157 myLCID
= SUBLANGID(lcid
);
159 else if ((myLCID
== SUBLANGID(lcid
)) && myLCID
)
161 /* try with system langid */
171 DWORD len
= MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, szPath
, dwPathLen
, NULL
, 0 );
172 BSTR bstrPath
= SysAllocStringLen(NULL
,len
);
174 MultiByteToWideChar(CP_ACP
,
186 TRACE_(typelib
)("%s not found\n", szTypeLibKey
);
191 /******************************************************************************
192 * CreateTypeLib [OLEAUT32] creates a typelib
198 HRESULT WINAPI
CreateTypeLib(
199 SYSKIND syskind
, LPCOLESTR szFile
, ICreateTypeLib
** ppctlib
201 FIXME("(%d,%s,%p), stub!\n",syskind
,debugstr_w(szFile
),ppctlib
);
204 /******************************************************************************
205 * LoadTypeLib [TYPELIB.3] Loads and registers a type library
207 * Docs: OLECHAR FAR* szFile
208 * Docs: iTypeLib FAR* FAR* pptLib
214 HRESULT WINAPI
LoadTypeLib16(
215 LPOLESTR szFile
, /* [in] Name of file to load from */
216 ITypeLib
** pptLib
) /* [out] Pointer to pointer to loaded type library */
218 FIXME("('%s',%p): stub\n",debugstr_w((LPWSTR
)szFile
),pptLib
);
226 /******************************************************************************
227 * LoadTypeLib [OLEAUT32.161]
228 * Loads and registers a type library
230 * Docs: OLECHAR FAR* szFile
231 * Docs: iTypeLib FAR* FAR* pptLib
237 int TLB_ReadTypeLib(PCHAR file
, ITypeLib2
**ppTypelib
);
239 HRESULT WINAPI
LoadTypeLib(
240 const OLECHAR
*szFile
,/* [in] Name of file to load from */
241 ITypeLib
* *pptLib
) /* [out] Pointer to pointer to loaded type library */
244 return LoadTypeLibEx(szFile
, REGKIND_DEFAULT
, pptLib
);
247 /******************************************************************************
248 * LoadTypeLibEx [OLEAUT32.183]
249 * Loads and optionally registers a type library
255 HRESULT WINAPI
LoadTypeLibEx(
256 LPCOLESTR szFile
, /* [in] Name of file to load from */
257 REGKIND regkind
, /* [in] Specify kind of registration */
258 ITypeLib
**pptLib
) /* [out] Pointer to pointer to loaded type library */
262 TRACE("(%s,%d,%p)\n",debugstr_w(szFile
), regkind
, pptLib
);
264 p
=HEAP_strdupWtoA(GetProcessHeap(),0,szFile
);
266 if(regkind
!= REGKIND_NONE
)
267 FIXME ("registration of typelibs not supported yet!\n");
269 res
= TLB_ReadTypeLib(p
, (ITypeLib2
**)pptLib
);
270 HeapFree(GetProcessHeap(),0,p
);
271 TRACE(" returns %08lx\n",res
);
276 /******************************************************************************
277 * LoadRegTypeLib [OLEAUT32.162]
279 HRESULT WINAPI
LoadRegTypeLib(
280 REFGUID rguid
, /* [in] referenced guid */
281 WORD wVerMajor
, /* [in] major version */
282 WORD wVerMinor
, /* [in] minor version */
283 LCID lcid
, /* [in] locale id */
284 ITypeLib
**ppTLib
) /* [out] path of typelib */
287 HRESULT res
=QueryPathOfRegTypeLib( rguid
, wVerMajor
, wVerMinor
, lcid
, &bstr
);
291 res
= LoadTypeLib(bstr
, ppTLib
);
295 TRACE("(IID: %s) load %s (%p)\n",debugstr_guid(rguid
), SUCCEEDED(res
)? "SUCCESS":"FAILED", *ppTLib
);
301 /******************************************************************************
302 * RegisterTypeLib [OLEAUT32.163]
303 * Adds information about a type library to the System Registry
305 * Docs: ITypeLib FAR * ptlib
306 * Docs: OLECHAR FAR* szFullPath
307 * Docs: OLECHAR FAR* szHelpDir
313 HRESULT WINAPI
RegisterTypeLib(
314 ITypeLib
* ptlib
, /* [in] Pointer to the library*/
315 OLECHAR
* szFullPath
, /* [in] full Path of the library*/
316 OLECHAR
* szHelpDir
) /* [in] dir to the helpfile for the library,
318 { FIXME("(%p,%s,%s): stub\n",ptlib
, debugstr_w(szFullPath
),debugstr_w(szHelpDir
));
319 return S_OK
; /* FIXME: pretend everything is OK */
323 /******************************************************************************
324 * UnRegisterTypeLib [OLEAUT32.186]
325 * Removes information about a type library from the System Registry
332 HRESULT WINAPI
UnRegisterTypeLib(
333 REFGUID libid
, /* [in] Guid of the library */
334 WORD wVerMajor
, /* [in] major version */
335 WORD wVerMinor
, /* [in] minor version */
336 LCID lcid
, /* [in] locale id */
339 TRACE("(IID: %s): stub\n",debugstr_guid(libid
));
340 return S_OK
; /* FIXME: pretend everything is OK */
343 /****************************************************************************
344 * OaBuildVersion (TYPELIB.15)
346 * known TYPELIB.DLL versions:
348 * OLE 2.01 no OaBuildVersion() avail 1993 -- ---
349 * OLE 2.02 1993-94 02 3002
352 * OLE 2.03 W98 SE orig. file !! 1993-95 10 3024
353 * OLE 2.1 NT 1993-95 ?? ???
354 * OLE 2.3.1 W95 23 700
355 * OLE2 4.0 NT4SP6 1993-98 40 4277
357 DWORD WINAPI
OaBuildVersion16(void)
359 /* FIXME: I'd like to return the highest currently known version value
360 * in case the user didn't force a --winver, but I don't know how
361 * to retrieve the "versionForced" info from misc/version.c :(
362 * (this would be useful in other places, too) */
363 FIXME("Please report to a.mohr@mailto.de if you get version error messages !\n");
364 switch(GetVersion() & 0x8000ffff) /* mask off build number */
366 case 0x80000a03: /* WIN31 */
367 return MAKELONG(3027, 3); /* WfW 3.11 */
368 case 0x80000004: /* WIN95 */
369 return MAKELONG(700, 23); /* Win95A */
370 case 0x80000a04: /* WIN98 */
371 return MAKELONG(3024, 10); /* W98 SE */
372 case 0x00000004: /* NT4 */
373 return MAKELONG(4277, 40); /* NT4 SP6 */
375 FIXME("Version value not known yet. Please investigate it !");
380 /* for better debugging info leave the static out for the time being */
383 /*======================= ITypeLib implementation =======================*/
385 typedef struct tagTLBCustData
389 struct tagTLBCustData
* next
;
392 /* data structure for import typelibs */
393 typedef struct tagTLBImpLib
395 int offset
; /* offset in the file */
396 GUID guid
; /* libid */
397 BSTR name
; /* name; */
399 LCID lcid
; /* lcid of imported typelib */
401 WORD wVersionMajor
; /* major version number */
402 WORD wVersionMinor
; /* minor version number */
404 struct tagITypeLibImpl
*pImpTypeLib
; /* pointer to loaded typelib */
405 struct tagTLBImpLib
* next
;
408 /* internal ITypeLib data */
409 typedef struct tagITypeLibImpl
411 ICOM_VFIELD(ITypeLib2
);
413 TLIBATTR LibAttr
; /* guid,lcid,syskind,version,flags */
415 /* strings can be stored in tlb as multibyte strings BUT they are *always*
416 * exported to the application as a UNICODE string.
422 unsigned long dwHelpContext
;
423 int TypeInfoCount
; /* nr of typeinfo's in librarry */
424 struct tagITypeInfoImpl
*pTypeInfo
; /* linked list of type info data */
425 int ctCustData
; /* number of items in cust data list */
426 TLBCustData
* pCustData
; /* linked list to cust data; */
427 TLBImpLib
* pImpLibs
; /* linked list to all imported typelibs */
428 TYPEDESC
* pTypeDesc
; /* array of TypeDescriptions found in the libary */
431 static struct ICOM_VTABLE(ITypeLib2
) tlbvt
;
433 /* ITypeLib methods */
434 static ITypeLib2
* ITypeLib2_Constructor(LPVOID pLib
, DWORD dwTLBLength
);
436 /*======================= ITypeInfo implementation =======================*/
438 /* data for refernced types in a coclass, or an inherited interface */
439 typedef struct tagTLBRefType
441 GUID guid
; /* guid of the referenced type */
442 /* (important if its a imported type) */
446 TLBCustData
* pCustData
;/* linked list to custom data; */
447 TLBImpLib
*pImpTLInfo
;
448 struct tagTLBRefType
* next
;
451 /* internal Parameter data */
452 typedef struct tagTLBParDesc
456 TLBCustData
* pCustData
; /* linked list to cust data; */
457 TLBRefType
* pRefType
; /* linked list to referenced types */
460 /* internal Function data */
461 typedef struct tagTLBFuncDesc
463 FUNCDESC funcdesc
; /* lots of info on the function and its attributes. */
464 BSTR Name
; /* the name of this function */
465 TLBParDesc
*pParamDesc
; /* array with name and custom data */
467 int HelpStringContext
;
469 BSTR Entry
; /* if its Hiword==0, it numeric; -1 is not present*/
471 TLBCustData
* pCustData
; /* linked list to cust data; */
472 struct tagTLBFuncDesc
* next
;
475 /* internal Variable data */
476 typedef struct tagTLBVarDesc
478 VARDESC vardesc
; /* lots of info on the variable and its attributes. */
479 BSTR Name
; /* the name of this variable */
481 int HelpStringContext
; /* fixme: where? */
484 TLBCustData
* pCustData
;/* linked list to cust data; */
485 struct tagTLBVarDesc
* next
;
488 /* internal TypeInfo data */
489 typedef struct tagITypeInfoImpl
491 ICOM_VFIELD(ITypeInfo2
);
493 TYPEATTR TypeAttr
; /* _lots_ of type information. */
494 ITypeLibImpl
* pTypeLib
; /* back pointer to typelib */
495 int index
; /* index in this typelib; */
496 /* type libs seem to store the doc strings in ascii
497 * so why should we do it in unicode?
501 unsigned long dwHelpContext
;
502 unsigned long dwHelpStringContext
;
505 TLBFuncDesc
* funclist
; /* linked list with function descriptions */
508 TLBVarDesc
* varlist
; /* linked list with variable descriptions */
510 /* Implemented Interfaces */
511 TLBRefType
* impltypelist
;
513 TLBCustData
* pCustData
; /* linked list to cust data; */
514 struct tagITypeInfoImpl
* next
;
517 static struct ICOM_VTABLE(ITypeInfo2
) tinfvt
;
519 static ITypeInfo2
* WINAPI
ITypeInfo_Constructor();
521 typedef struct tagTLBContext
523 unsigned int oStart
; /* start of TLB in file */
524 unsigned int pos
; /* current pos */
525 unsigned int length
; /* total length */
526 void *mapping
; /* memory mapping */
528 ITypeLibImpl
* pLibInfo
;
532 static void TLB_DoRefType(TLBContext
*pcx
, int offset
, TLBRefType
** pprtd
);
537 static void dump_TLBFuncDesc(TLBFuncDesc
* pfd
)
541 TRACE_(typelib
)("%s(%u)\n", debugstr_w(pfd
->Name
), pfd
->funcdesc
.cParams
);
545 static void dump_TLBVarDesc(TLBVarDesc
* pvd
)
549 TRACE_(typelib
)("%s\n", debugstr_w(pvd
->Name
));
553 static void dump_TLBRefType(TLBRefType
* prt
)
557 TRACE_(typelib
)("%s\n", debugstr_guid(&(prt
->guid
)));
558 TRACE_(typelib
)(" href:0x%08lx\n", prt
->reference
);
563 static void dump_Variant(VARIANT
* pvar
)
567 TRACE("(%p)\n", pvar
);
571 ZeroMemory(szVarType
, sizeof(szVarType
));
573 /* FIXME : we could have better trace here, depending on the VARTYPE
579 sprintf(szVarType
, "VT_UI");
583 sprintf(szVarType
, "VT_I2");
587 sprintf(szVarType
, "VT_I4");
591 sprintf(szVarType
, "VT_R4");
595 sprintf(szVarType
, "VT_R8");
599 sprintf(szVarType
, "VT_BOOL");
603 sprintf(szVarType
, "VT_ERROR");
607 sprintf(szVarType
, "VT_CY");
611 sprintf(szVarType
, "VT_DATE");
615 sprintf(szVarType
, "VT_BSTR");
620 sprintf(szVarType
, "VT_BYREF");
624 sprintf(szVarType
, "VT_DISPATCH");
628 sprintf(szVarType
, "VT_ARRAY");
632 sprintf(szVarType
, "VT_I2");
636 sprintf(szVarType
, "VT_UI2");
640 sprintf(szVarType
, "VT_UI4");
644 sprintf(szVarType
, "VT_INT");
648 sprintf(szVarType
, "VT_UINT");
652 TRACE("VARTYPE: %s", szVarType
);
657 TRACE("%3.3e\n", V_UNION(pvar
, fltVal
));
661 TRACE("%3.3e\n", V_UNION(pvar
, dblVal
));
665 TRACE("%ld\n", V_UNION(pvar
, lVal
));
669 if (pvar
->vt
& VT_BYREF
)
670 return dump_Variant(pvar
->u
.pvarVal
);
673 static void dump_DispParms(DISPPARAMS
* pdp
)
677 TRACE("args=%u named args=%u\n", pdp
->cArgs
, pdp
->cNamedArgs
);
679 while (index
< pdp
->cArgs
)
681 dump_Variant( &pdp
->rgvarg
[index
] );
686 static char * typekind_desc
[] =
699 static void dump_TypeInfo(ITypeInfoImpl
* pty
)
701 TRACE("%p ref=%u\n", pty
, pty
->ref
);
702 TRACE("attr:%s\n", debugstr_guid(&(pty
->TypeAttr
.guid
)));
703 TRACE("kind:%s\n", typekind_desc
[pty
->TypeAttr
.typekind
]);
704 TRACE("fct:%u var:%u impl:%u\n",
705 pty
->TypeAttr
.cFuncs
, pty
->TypeAttr
.cVars
, pty
->TypeAttr
.cImplTypes
);
706 TRACE("parent tlb:%p index in TLB:%u\n",pty
->pTypeLib
, pty
->index
);
707 TRACE("%s %s\n", debugstr_w(pty
->Name
), debugstr_w(pty
->DocString
));
708 dump_TLBFuncDesc(pty
->funclist
);
709 dump_TLBVarDesc(pty
->varlist
);
710 dump_TLBRefType(pty
->impltypelist
);
713 static TYPEDESC stndTypeDesc
[VT_LPWSTR
+1]=
715 /* VT_LPWSTR is largest type that */
716 /* may appear in type description*/
717 {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
718 {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
719 {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
720 {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
721 {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
722 {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
726 static void TLB_abort()
730 static void * TLB_Alloc(unsigned size
)
733 if((ret
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,size
))==NULL
){
735 ERR("cannot allocate memory\n");
740 static void TLB_Free(void * ptr
)
742 HeapFree(GetProcessHeap(), 0, ptr
);
745 DWORD
TLB_Read(void *buffer
, DWORD count
, TLBContext
*pcx
, long where
)
747 TRACE_(typelib
)("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n",
748 pcx
->pos
, count
, pcx
->oStart
, pcx
->length
, where
);
750 if (where
!= DO_NOT_SEEK
)
752 where
+= pcx
->oStart
;
753 if (where
> pcx
->length
)
756 ERR("seek beyond end (%ld/%d)\n", where
, pcx
->length
);
761 if (pcx
->pos
+ count
> pcx
->length
) count
= pcx
->length
- pcx
->pos
;
762 memcpy( buffer
, (char *)pcx
->mapping
+ pcx
->pos
, count
);
767 static void TLB_ReadGuid( GUID
*pGuid
, int offset
, TLBContext
*pcx
)
769 TRACE_(typelib
)("%s\n", debugstr_guid(pGuid
));
771 if(offset
<0 || pcx
->pTblDir
->pGuidTab
.offset
<0){
772 memset(pGuid
,0, sizeof(GUID
));
775 TLB_Read(pGuid
, sizeof(GUID
), pcx
, pcx
->pTblDir
->pGuidTab
.offset
+offset
);
778 BSTR
TLB_ReadName( TLBContext
*pcx
, int offset
)
783 WCHAR
* pwstring
= NULL
;
784 BSTR bstrName
= NULL
;
786 TLB_Read(&niName
, sizeof(niName
), pcx
,
787 pcx
->pTblDir
->pNametab
.offset
+offset
);
788 niName
.namelen
&= 0xFF; /* FIXME: correct ? */
789 name
=TLB_Alloc((niName
.namelen
& 0xff) +1);
790 TLB_Read(name
, (niName
.namelen
& 0xff), pcx
, DO_NOT_SEEK
);
791 name
[niName
.namelen
& 0xff]='\0';
793 lengthInChars
= MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
| MB_ERR_INVALID_CHARS
,
796 /* no invalid characters in string */
799 pwstring
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*lengthInChars
);
801 /* don't check for invalid character since this has been done previously */
802 MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, name
, -1, pwstring
, lengthInChars
);
804 bstrName
= SysAllocStringLen(pwstring
, lengthInChars
);
805 lengthInChars
= SysStringLen(bstrName
);
806 HeapFree(GetProcessHeap(), 0, pwstring
);
809 TRACE_(typelib
)("%s %d\n", debugstr_w(bstrName
), lengthInChars
);
813 BSTR
TLB_ReadString( TLBContext
*pcx
, int offset
)
820 if(offset
<0) return NULL
;
821 TLB_Read(&length
, sizeof(INT16
), pcx
, pcx
->pTblDir
->pStringtab
.offset
+offset
);
822 if(length
<= 0) return 0;
823 string
=TLB_Alloc(length
+1);
824 TLB_Read(string
, length
, pcx
, DO_NOT_SEEK
);
827 lengthInChars
= MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
| MB_ERR_INVALID_CHARS
,
828 string
, -1, NULL
, 0);
830 /* no invalid characters in string */
833 WCHAR
* pwstring
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*lengthInChars
);
835 /* don't check for invalid character since this has been done previously */
836 MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, string
, -1, pwstring
, lengthInChars
);
838 bstr
= SysAllocStringLen(pwstring
, lengthInChars
);
839 lengthInChars
= SysStringLen(bstr
);
840 HeapFree(GetProcessHeap(), 0, pwstring
);
843 TRACE_(typelib
)("%s %d\n", debugstr_w(bstr
), lengthInChars
);
847 * read a value and fill a VARIANT structure
849 static void TLB_ReadValue( VARIANT
* pVar
, int offset
, TLBContext
*pcx
)
853 TRACE_(typelib
)("\n");
855 if(offset
<0) { /* data is packed in here */
856 pVar
->vt
= (offset
& 0x7c000000 )>> 26;
857 V_UNION(pVar
, iVal
) = offset
& 0xffff;
860 TLB_Read(&(pVar
->vt
), sizeof(VARTYPE
), pcx
,
861 pcx
->pTblDir
->pCustData
.offset
+ offset
);
862 TRACE_(typelib
)("Vartype = %x\n", pVar
->vt
);
864 case VT_EMPTY
: /* FIXME: is this right? */
865 case VT_NULL
: /* FIXME: is this right? */
866 case VT_I2
: /* this should not happen */
877 case VT_VOID
: /* FIXME: is this right? */
885 case VT_DECIMAL
: /* FIXME: is this right? */
888 /* pointer types with known behaviour */
891 TLB_Read(&size
, sizeof(INT
), pcx
, DO_NOT_SEEK
);
893 FIXME("BSTR length = %d?\n", size
);
895 ptr
=TLB_Alloc(size
);/* allocate temp buffer */
896 TLB_Read(ptr
, size
, pcx
, DO_NOT_SEEK
); /* read string (ANSI) */
897 V_UNION(pVar
, bstrVal
)=SysAllocStringLen(NULL
,size
);
898 /* FIXME: do we need a AtoW conversion here? */
899 V_UNION(pVar
, bstrVal
[size
])=L
'\0';
900 while(size
--) V_UNION(pVar
, bstrVal
[size
])=ptr
[size
];
905 /* FIXME: this will not work AT ALL when the variant contains a pointer */
912 case VT_USERDEFINED
:
918 case VT_STREAMED_OBJECT
:
919 case VT_STORED_OBJECT
:
920 case VT_BLOB_OBJECT
:
925 FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
929 if(size
>0) /* (big|small) endian correct? */
930 TLB_Read(&(V_UNION(pVar
, iVal
)), size
, pcx
, DO_NOT_SEEK
);
934 * create a linked list with custom data
936 static int TLB_CustData( TLBContext
*pcx
, int offset
, TLBCustData
** ppCustData
)
942 TRACE_(typelib
)("\n");
946 pNew
=TLB_Alloc(sizeof(TLBCustData
));
947 TLB_Read(&entry
, sizeof(entry
), pcx
,
948 pcx
->pTblDir
->pCDGuids
.offset
+offset
);
949 TLB_ReadGuid(&(pNew
->guid
), entry
.GuidOffset
, pcx
);
950 TLB_ReadValue(&(pNew
->data
), entry
.DataOffset
, pcx
);
951 /* add new custom data at head of the list */
952 pNew
->next
=*ppCustData
;
959 static void TLB_GetTdesc(TLBContext
*pcx
, INT type
,TYPEDESC
* pTd
)
962 pTd
->vt
=type
& VT_TYPEMASK
;
964 *pTd
=pcx
->pLibInfo
->pTypeDesc
[type
/(2*sizeof(INT
))];
966 TRACE_(typelib
)("vt type = %X\n", pTd
->vt
);
970 TLB_DoFuncs(TLBContext
* pcx
,
977 * member information is stored in a data structure at offset
978 * indicated by the memoffset field of the typeinfo structure
979 * There are several distinctive parts.
980 * the first part starts with a field that holds the total length
981 * of this (first) part excluding this field. Then follow the records,
982 * for each member there is one record.
984 * First entry is always the length of the record (excluding this
986 * Rest of the record depends on the type of the member. If there is
987 * a field indicating the member type (function variable intereface etc)
988 * I have not found it yet. At this time we depend on the information
989 * in the type info and the usual order how things are stored.
991 * Second follows an array sized nrMEM*sizeof(INT) with a memeber id
994 * Third is a equal sized array with file offsets to the name entry
997 * Forth and last (?) part is an array with offsets to the records in the
998 * first part of this file segment.
1001 int infolen
, nameoffset
, reclength
, nrattributes
, i
;
1002 int recoffset
= offset
+ sizeof(INT
);
1005 TLBFuncRecord
* pFuncRec
=(TLBFuncRecord
*) recbuf
;
1007 TRACE_(typelib
)("\n");
1009 TLB_Read(&infolen
, sizeof(INT
), pcx
, offset
);
1011 for ( i
= 0; i
< cFuncs
; i
++ )
1013 *pptfd
= TLB_Alloc(sizeof(TLBFuncDesc
));
1015 /* name, eventually add to a hash table */
1016 TLB_Read(&nameoffset
,
1019 offset
+ infolen
+ (cFuncs
+ cVars
+ i
+ 1) * sizeof(INT
));
1021 (*pptfd
)->Name
= TLB_ReadName(pcx
, nameoffset
);
1023 /* read the function information record */
1024 TLB_Read(&reclength
, sizeof(INT
), pcx
, recoffset
);
1028 TLB_Read(pFuncRec
, reclength
- sizeof(INT
), pcx
, DO_NOT_SEEK
) ;
1030 /* do the attributes */
1031 nrattributes
= (reclength
- pFuncRec
->nrargs
* 3 * sizeof(int) - 0x18)
1034 if ( nrattributes
> 0 )
1036 (*pptfd
)->helpcontext
= pFuncRec
->OptAttr
[0] ;
1038 if ( nrattributes
> 1 )
1040 (*pptfd
)->HelpString
= TLB_ReadString(pcx
,
1041 pFuncRec
->OptAttr
[1]) ;
1043 if ( nrattributes
> 2 )
1045 if ( pFuncRec
->FKCCIC
& 0x2000 )
1047 (*pptfd
)->Entry
= (WCHAR
*) pFuncRec
->OptAttr
[2] ;
1051 (*pptfd
)->Entry
= TLB_ReadString(pcx
,
1052 pFuncRec
->OptAttr
[2]);
1054 if( nrattributes
> 5 )
1056 (*pptfd
)->HelpStringContext
= pFuncRec
->OptAttr
[5] ;
1058 if ( nrattributes
> 6 && pFuncRec
->FKCCIC
& 0x80 )
1061 pFuncRec
->OptAttr
[6],
1062 &(*pptfd
)->pCustData
);
1069 /* fill the FuncDesc Structure */
1070 TLB_Read( & (*pptfd
)->funcdesc
.memid
,
1072 offset
+ infolen
+ ( i
+ 1) * sizeof(INT
));
1074 (*pptfd
)->funcdesc
.funckind
= (pFuncRec
->FKCCIC
) & 0x7;
1075 (*pptfd
)->funcdesc
.invkind
= (pFuncRec
->FKCCIC
) >> 3 & 0xF;
1076 (*pptfd
)->funcdesc
.callconv
= (pFuncRec
->FKCCIC
) >> 8 & 0xF;
1077 (*pptfd
)->funcdesc
.cParams
= pFuncRec
->nrargs
;
1078 (*pptfd
)->funcdesc
.cParamsOpt
= pFuncRec
->nroargs
;
1079 (*pptfd
)->funcdesc
.oVft
= pFuncRec
->VtableOffset
;
1080 (*pptfd
)->funcdesc
.wFuncFlags
= LOWORD(pFuncRec
->Flags
) ;
1084 &(*pptfd
)->funcdesc
.elemdescFunc
.tdesc
) ;
1086 /* do the parameters/arguments */
1087 if(pFuncRec
->nrargs
)
1090 TLBParameterInfo paraminfo
;
1092 (*pptfd
)->funcdesc
.lprgelemdescParam
=
1093 TLB_Alloc(pFuncRec
->nrargs
* sizeof(ELEMDESC
));
1095 (*pptfd
)->pParamDesc
=
1096 TLB_Alloc(pFuncRec
->nrargs
* sizeof(TLBParDesc
));
1098 TLB_Read(¶minfo
,
1101 recoffset
+ reclength
-
1102 pFuncRec
->nrargs
* sizeof(TLBParameterInfo
));
1104 for ( j
= 0 ; j
< pFuncRec
->nrargs
; j
++ )
1106 TYPEDESC
* lpArgTypeDesc
= 0;
1110 &(*pptfd
)->funcdesc
.lprgelemdescParam
[j
].tdesc
) ;
1112 V_UNION(& ((*pptfd
)->funcdesc
.lprgelemdescParam
[j
]),
1113 paramdesc
.wParamFlags
) = paraminfo
.Flags
;
1115 (*pptfd
)->pParamDesc
[j
].Name
= (void *) paraminfo
.oName
;
1117 /* SEEK value = jump to offset,
1118 * from there jump to the end of record,
1119 * go back by (j-1) arguments
1121 TLB_Read( ¶minfo
,
1122 sizeof(TLBParameterInfo
), pcx
,
1123 recoffset
+ reclength
- ((pFuncRec
->nrargs
- j
- 1)
1124 * sizeof(TLBParameterInfo
)));
1126 & ((*pptfd
)->funcdesc
.lprgelemdescParam
[j
].tdesc
);
1128 while ( lpArgTypeDesc
!= NULL
)
1130 switch ( lpArgTypeDesc
->vt
)
1133 lpArgTypeDesc
= lpArgTypeDesc
->u
.lptdesc
;
1137 lpArgTypeDesc
= & (lpArgTypeDesc
->u
.lpadesc
->tdescElem
);
1140 case VT_USERDEFINED
:
1141 (*pptfd
)->pParamDesc
[j
].pRefType
=
1142 TLB_Alloc(sizeof(TLBRefType
));
1145 lpArgTypeDesc
->u
.hreftype
,
1146 & ( (*pptfd
)->pParamDesc
[j
].pRefType
));
1148 lpArgTypeDesc
= NULL
;
1152 lpArgTypeDesc
= NULL
;
1158 /* parameter is the return value! */
1159 if ( paraminfo
.Flags
& PARAMFLAG_FRETVAL
)
1161 TYPEDESC
* lpArgTypeDesc
;
1163 (*pptfd
)->funcdesc
.elemdescFunc
=
1164 (*pptfd
)->funcdesc
.lprgelemdescParam
[j
];
1166 lpArgTypeDesc
= & ((*pptfd
)->funcdesc
.elemdescFunc
.tdesc
) ;
1168 while ( lpArgTypeDesc
!= NULL
)
1170 switch ( lpArgTypeDesc
->vt
)
1173 lpArgTypeDesc
= lpArgTypeDesc
->u
.lptdesc
;
1177 & (lpArgTypeDesc
->u
.lpadesc
->tdescElem
);
1181 case VT_USERDEFINED
:
1182 (*pptfd
)->pParamDesc
[j
].pRefType
1183 = TLB_Alloc(sizeof(TLBRefType
));
1186 lpArgTypeDesc
->u
.hreftype
,
1187 &((*pptfd
)->pParamDesc
[j
].pRefType
));
1189 lpArgTypeDesc
= NULL
;
1193 lpArgTypeDesc
= NULL
;
1198 /* second time around */
1199 for(j
=0;j
<pFuncRec
->nrargs
;j
++)
1202 (*pptfd
)->pParamDesc
[j
].Name
=
1203 TLB_ReadName( pcx
, (int)(*pptfd
)->pParamDesc
[j
].Name
);
1206 if ( (PARAMFLAG_FHASDEFAULT
&
1207 V_UNION(&((*pptfd
)->funcdesc
.lprgelemdescParam
[j
]),
1208 paramdesc
.wParamFlags
)) &&
1209 ((pFuncRec
->FKCCIC
) & 0x1000) )
1211 INT
* pInt
= (INT
*)((char *)pFuncRec
+
1213 (pFuncRec
->nrargs
* 4 + 1) * sizeof(INT
) );
1215 PARAMDESC
* pParamDesc
= &V_UNION(
1216 & ((*pptfd
)->funcdesc
.lprgelemdescParam
[j
]),
1219 pParamDesc
->pparamdescex
= TLB_Alloc(sizeof(PARAMDESCEX
));
1220 pParamDesc
->pparamdescex
->cBytes
= sizeof(PARAMDESCEX
);
1222 TLB_ReadValue(&(pParamDesc
->pparamdescex
->varDefaultValue
),
1226 if ( nrattributes
> 7 + j
&& pFuncRec
->FKCCIC
& 0x80 )
1229 pFuncRec
->OptAttr
[7+j
],
1230 &(*pptfd
)->pParamDesc
[j
].pCustData
);
1235 /* scode is not used: archaic win16 stuff FIXME: right? */
1236 (*pptfd
)->funcdesc
.cScodes
= 0 ;
1237 (*pptfd
)->funcdesc
.lprgscode
= NULL
;
1239 pptfd
= & ((*pptfd
)->next
);
1240 recoffset
+= reclength
;
1243 static void TLB_DoVars(TLBContext
*pcx
, int cFuncs
, int cVars
,
1244 int offset
, TLBVarDesc
** pptvd
)
1246 int infolen
, nameoffset
, reclength
;
1248 TLBVarRecord
* pVarRec
=(TLBVarRecord
*) recbuf
;
1252 TRACE_(typelib
)("\n");
1254 TLB_Read(&infolen
,sizeof(INT
), pcx
, offset
);
1255 TLB_Read(&recoffset
,sizeof(INT
), pcx
, offset
+ infolen
+
1256 ((cFuncs
+cVars
)*2+cFuncs
+ 1)*sizeof(INT
));
1257 recoffset
+= offset
+sizeof(INT
);
1258 for(i
=0;i
<cVars
;i
++){
1259 *pptvd
=TLB_Alloc(sizeof(TLBVarDesc
));
1260 /* name, eventually add to a hash table */
1261 TLB_Read(&nameoffset
, sizeof(INT
), pcx
,
1262 offset
+ infolen
+ (cFuncs
+ cVars
+ i
+ 1) * sizeof(INT
));
1263 (*pptvd
)->Name
=TLB_ReadName(pcx
, nameoffset
);
1264 /* read the variable information record */
1265 TLB_Read(&reclength
, sizeof(INT
), pcx
, recoffset
);
1267 TLB_Read(pVarRec
, reclength
- sizeof(INT
), pcx
, DO_NOT_SEEK
) ;
1269 if(reclength
>(6*sizeof(INT
)) )
1270 (*pptvd
)->HelpContext
=pVarRec
->HelpContext
;
1271 if(reclength
>(7*sizeof(INT
)) )
1272 (*pptvd
)->HelpString
= TLB_ReadString(pcx
, pVarRec
->oHelpString
) ;
1273 if(reclength
>(8*sizeof(INT
)) )
1274 if(reclength
>(9*sizeof(INT
)) )
1275 (*pptvd
)->HelpStringContext
=pVarRec
->HelpStringContext
;
1276 /* fill the VarDesc Structure */
1277 TLB_Read(&(*pptvd
)->vardesc
.memid
, sizeof(INT
), pcx
,
1278 offset
+ infolen
+ ( i
+ 1) * sizeof(INT
));
1279 (*pptvd
)->vardesc
.varkind
= pVarRec
->VarKind
;
1280 (*pptvd
)->vardesc
.wVarFlags
= pVarRec
->Flags
;
1281 TLB_GetTdesc(pcx
, pVarRec
->DataType
,
1282 &(*pptvd
)->vardesc
.elemdescVar
.tdesc
) ;
1283 /* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) fixme?? */
1284 if(pVarRec
->VarKind
== VAR_CONST
){
1285 V_UNION(&((*pptvd
)->vardesc
),lpvarValue
)=TLB_Alloc(sizeof(VARIANT
));
1286 TLB_ReadValue(V_UNION(&((*pptvd
)->vardesc
),lpvarValue
),
1287 pVarRec
->OffsValue
, pcx
);
1289 V_UNION(&((*pptvd
)->vardesc
),oInst
)=pVarRec
->OffsValue
;
1290 pptvd
=&((*pptvd
)->next
);
1291 recoffset
+= reclength
;
1294 /* fill in data for a hreftype (offset). When the refernced type is contained
1295 * in the typelib, its just an (file) offset in the type info base dir.
1296 * If comes from import, its an offset+1 in the ImpInfo table
1298 static void TLB_DoRefType(TLBContext
*pcx
,
1299 int offset
, TLBRefType
** pprtd
)
1303 TRACE_(typelib
)("TLB context %p, TLB offset %x\n", pcx
, offset
);
1305 if(!HREFTYPE_INTHISFILE( offset
)) {
1306 /* external typelib */
1308 TLBImpLib
*pImpLib
=(pcx
->pLibInfo
->pImpLibs
);
1310 TRACE_(typelib
)("offset %x, masked offset %x\n", offset
, offset
+ (offset
& 0xfffffffc));
1312 TLB_Read(&impinfo
, sizeof(impinfo
), pcx
,
1313 pcx
->pTblDir
->pImpInfo
.offset
+ (offset
& 0xfffffffc));
1314 for(j
=0;pImpLib
;j
++){ /* search the known offsets of all import libraries */
1315 if(pImpLib
->offset
==impinfo
.oImpFile
) break;
1316 pImpLib
=pImpLib
->next
;
1319 (*pprtd
)->reference
=offset
;
1320 (*pprtd
)->pImpTLInfo
= pImpLib
;
1321 TLB_ReadGuid(&(*pprtd
)->guid
, impinfo
.oGuid
, pcx
);
1323 ERR("Cannot find a reference\n");
1324 (*pprtd
)->reference
=-1;
1325 (*pprtd
)->pImpTLInfo
=(void *)-1;
1328 /* in this typelib */
1329 (*pprtd
)->reference
=offset
;
1330 (*pprtd
)->pImpTLInfo
=(void *)-2;
1334 /* process Implemented Interfaces of a com class */
1335 static void TLB_DoImplTypes(TLBContext
*pcx
, int count
,
1336 int offset
, TLBRefType
** pprtd
)
1339 TLBRefRecord refrec
;
1341 TRACE_(typelib
)("\n");
1343 for(i
=0;i
<count
;i
++){
1344 if(offset
<0) break; /* paranoia */
1345 *pprtd
=TLB_Alloc(sizeof(TLBRefType
));
1346 TLB_Read(&refrec
,sizeof(refrec
),pcx
,offset
+pcx
->pTblDir
->pRefTab
.offset
);
1347 TLB_DoRefType(pcx
, refrec
.reftype
, pprtd
);
1348 (*pprtd
)->flags
=refrec
.flags
;
1349 (*pprtd
)->ctCustData
=
1350 TLB_CustData(pcx
, refrec
.oCustData
, &(*pprtd
)->pCustData
);
1351 offset
=refrec
.onext
;
1352 pprtd
=&((*pprtd
)->next
);
1356 * process a typeinfo record
1358 ITypeInfoImpl
* TLB_DoTypeInfo(
1361 ITypeLibImpl
* pLibInfo
)
1363 TLBTypeInfoBase tiBase
;
1364 ITypeInfoImpl
*ptiRet
;
1366 TRACE_(typelib
)("count=%u\n", count
);
1368 ptiRet
= (ITypeInfoImpl
*) ITypeInfo_Constructor();
1369 TLB_Read(&tiBase
, sizeof(tiBase
) ,pcx
,
1370 pcx
->pTblDir
->pTypeInfoTab
.offset
+count
*sizeof(tiBase
));
1371 /* this is where we are coming from */
1372 ptiRet
->pTypeLib
= pLibInfo
;
1373 ptiRet
->index
=count
;
1374 /* fill in the typeattr fields */
1375 FIXME("Assign constructor/destrutor memid\n");
1377 TLB_ReadGuid(&ptiRet
->TypeAttr
.guid
, tiBase
.posguid
, pcx
);
1378 ptiRet
->TypeAttr
.lcid
=pLibInfo
->LibAttr
.lcid
; /* FIXME: correct? */
1379 ptiRet
->TypeAttr
.memidConstructor
=MEMBERID_NIL
;/* FIXME */
1380 ptiRet
->TypeAttr
.memidDestructor
=MEMBERID_NIL
; /* FIXME */
1381 ptiRet
->TypeAttr
.lpstrSchema
=NULL
; /* reserved */
1382 ptiRet
->TypeAttr
.cbSizeInstance
=tiBase
.size
;
1383 ptiRet
->TypeAttr
.typekind
=tiBase
.typekind
& 0xF;
1384 ptiRet
->TypeAttr
.cFuncs
=LOWORD(tiBase
.cElement
);
1385 ptiRet
->TypeAttr
.cVars
=HIWORD(tiBase
.cElement
);
1386 ptiRet
->TypeAttr
.cbAlignment
=(tiBase
.typekind
>> 11 )& 0x1F; /* there are more flags there */
1387 ptiRet
->TypeAttr
.wTypeFlags
=tiBase
.flags
;
1388 ptiRet
->TypeAttr
.wMajorVerNum
=LOWORD(tiBase
.version
);
1389 ptiRet
->TypeAttr
.wMinorVerNum
=HIWORD(tiBase
.version
);
1390 ptiRet
->TypeAttr
.cImplTypes
=tiBase
.cImplTypes
;
1391 ptiRet
->TypeAttr
.cbSizeVft
=tiBase
.cbSizeVft
; /* FIXME: this is only the non inherited part */
1392 if(ptiRet
->TypeAttr
.typekind
== TKIND_ALIAS
)
1393 TLB_GetTdesc(pcx
, tiBase
.datatype1
,
1394 &ptiRet
->TypeAttr
.tdescAlias
) ;
1397 /* IDLDESC idldescType; *//* never saw this one != zero */
1399 /* name, eventually add to a hash table */
1400 ptiRet
->Name
=TLB_ReadName(pcx
, tiBase
.NameOffset
);
1401 TRACE_(typelib
)("reading %s\n", debugstr_w(ptiRet
->Name
));
1403 ptiRet
->DocString
=TLB_ReadString(pcx
, tiBase
.docstringoffs
);
1404 ptiRet
->dwHelpStringContext
=tiBase
.helpstringcontext
;
1405 ptiRet
->dwHelpContext
=tiBase
.helpcontext
;
1406 /* note: InfoType's Help file and HelpStringDll come from the containing
1407 * library. Further HelpString and Docstring appear to be the same thing :(
1410 if(ptiRet
->TypeAttr
.cFuncs
>0 )
1411 TLB_DoFuncs(pcx
, ptiRet
->TypeAttr
.cFuncs
,ptiRet
->TypeAttr
.cVars
,
1412 tiBase
.memoffset
, & ptiRet
->funclist
);
1414 if(ptiRet
->TypeAttr
.cVars
>0 )
1415 TLB_DoVars(pcx
, ptiRet
->TypeAttr
.cFuncs
,ptiRet
->TypeAttr
.cVars
,
1416 tiBase
.memoffset
, & ptiRet
->varlist
);
1417 if(ptiRet
->TypeAttr
.cImplTypes
>0 ){
1418 switch(ptiRet
->TypeAttr
.typekind
)
1421 TLB_DoImplTypes(pcx
, ptiRet
->TypeAttr
.cImplTypes
,
1422 tiBase
.datatype1
, & ptiRet
->impltypelist
);
1424 case TKIND_DISPATCH
:
1425 ptiRet
->impltypelist
=TLB_Alloc(sizeof(TLBRefType
));
1427 if (tiBase
.datatype1
!= -1)
1429 TLB_DoRefType(pcx
, tiBase
.datatype1
, & ptiRet
->impltypelist
);
1433 char* szStdOle
= "stdole2.tlb\0";
1434 int nStdOleLen
= strlen(szStdOle
);
1436 ptiRet
->impltypelist
->guid
= IID_IDispatch
;
1437 ptiRet
->impltypelist
->reference
= -1;
1438 ptiRet
->impltypelist
->pImpTLInfo
= TLB_Alloc(sizeof(TLBImpLib
));
1439 ptiRet
->impltypelist
->pImpTLInfo
->guid
= IID_StdOle
;
1440 ptiRet
->impltypelist
->pImpTLInfo
->name
= SysAllocStringLen(NULL
, nStdOleLen
+ 1);
1442 MultiByteToWideChar(CP_ACP
,
1446 ptiRet
->impltypelist
->pImpTLInfo
->name
,
1447 SysStringLen(ptiRet
->impltypelist
->pImpTLInfo
->name
));
1449 ptiRet
->impltypelist
->pImpTLInfo
->lcid
= 0;
1450 ptiRet
->impltypelist
->pImpTLInfo
->wVersionMajor
= 2;
1451 ptiRet
->impltypelist
->pImpTLInfo
->wVersionMinor
= 0;
1455 ptiRet
->impltypelist
=TLB_Alloc(sizeof(TLBRefType
));
1456 TLB_DoRefType(pcx
, tiBase
.datatype1
, & ptiRet
->impltypelist
);
1461 TLB_CustData(pcx
, tiBase
.oCustData
, &ptiRet
->pCustData
);
1463 TRACE_(typelib
)("%s guid: %s kind:%s\n",
1464 debugstr_w(ptiRet
->Name
),
1465 debugstr_guid(&ptiRet
->TypeAttr
.guid
),
1466 typekind_desc
[ptiRet
->TypeAttr
.typekind
]);
1471 /****************************************************************************
1474 * find the type of the typelib file and map the typelib resource into
1477 #define MSFT_SIGNATURE 0x5446534D /* "MSFT" */
1478 int TLB_ReadTypeLib(LPSTR pszFileName
, ITypeLib2
**ppTypeLib
)
1481 DWORD dwSignature
= 0;
1483 int nStrLen
= strlen(pszFileName
);
1486 PCHAR pszTypeLibIndex
= NULL
;
1487 PCHAR pszDllName
= NULL
;
1489 TRACE_(typelib
)("%s\n", pszFileName
);
1494 for (i
=0 ; i
< nStrLen
; ++i
)
1496 pszFileName
[i
] = tolower(pszFileName
[i
]);
1498 pszTypeLibIndex
= strstr(pszFileName
, ".dll");
1500 /* find if there's a back-slash after .DLL (good sign of the presence of a typelib index) */
1501 if (pszTypeLibIndex
)
1503 pszTypeLibIndex
= strstr(pszTypeLibIndex
, "\\");
1506 /* is there any thing after trailing back-slash ? */
1507 if (pszTypeLibIndex
&& pszTypeLibIndex
< pszFileName
+ nStrLen
)
1509 /* yes -> it's a index! store DLL name, without the trailing back-slash */
1510 size_t nMemToAlloc
= pszTypeLibIndex
- pszFileName
;
1512 pszDllName
= HeapAlloc(GetProcessHeap(),
1516 strncpy(pszDllName
, pszFileName
, nMemToAlloc
);
1518 /* move index string pointer pass the backslash */
1519 while (*pszTypeLibIndex
== '\\')
1524 /* No index, reset variable to 1 */
1525 pszDllName
= HeapAlloc(GetProcessHeap(),
1529 strncpy(pszDllName
, pszFileName
, nStrLen
);
1531 pszTypeLibIndex
= "1\0";
1534 TRACE_(typelib
)("File name without index %s\n", pszDllName
);
1535 TRACE_(typelib
)("Index of typelib %s\n", pszTypeLibIndex
);
1538 /* check the signature of the file */
1539 hFile
= CreateFileA( pszDllName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, 0 );
1540 if (INVALID_HANDLE_VALUE
!= hFile
)
1542 HANDLE hMapping
= CreateFileMappingA( hFile
, NULL
, PAGE_READONLY
| SEC_COMMIT
, 0, 0, NULL
);
1545 LPVOID pBase
= MapViewOfFile(hMapping
, FILE_MAP_READ
, 0, 0, 0);
1548 /* first try to load as *.tlb */
1549 dwSignature
= *((DWORD
*) pBase
);
1550 if ( dwSignature
== MSFT_SIGNATURE
)
1552 /* retrieve file size */
1553 DWORD dwTLBLength
= GetFileSize(hFile
, NULL
);
1555 *ppTypeLib
= ITypeLib2_Constructor(pBase
, dwTLBLength
);
1556 ITypeLib2_AddRef(*ppTypeLib
);
1558 UnmapViewOfFile(pBase
);
1560 CloseHandle(hMapping
);
1565 if( (WORD
)dwSignature
== IMAGE_DOS_SIGNATURE
)
1567 /* find the typelibrary resource*/
1568 HINSTANCE hinstDLL
= LoadLibraryExA(pszDllName
, 0, DONT_RESOLVE_DLL_REFERENCES
|
1569 LOAD_LIBRARY_AS_DATAFILE
|LOAD_WITH_ALTERED_SEARCH_PATH
);
1572 HRSRC hrsrc
= FindResourceA(hinstDLL
, MAKEINTRESOURCEA(atoi(pszTypeLibIndex
)), "TYPELIB");
1575 HGLOBAL hGlobal
= LoadResource(hinstDLL
, hrsrc
);
1578 LPVOID pBase
= LockResource(hGlobal
);
1579 DWORD dwTLBLength
= SizeofResource(hinstDLL
, hrsrc
);
1583 /* try to load as incore resource */
1584 dwSignature
= *((DWORD
*) pBase
);
1585 if ( dwSignature
== MSFT_SIGNATURE
)
1587 *ppTypeLib
= ITypeLib2_Constructor(pBase
, dwTLBLength
);
1588 ITypeLib2_AddRef(*ppTypeLib
);
1592 FIXME("Header type magic 0x%08lx not supported.\n",dwSignature
);
1595 FreeResource( hGlobal
);
1598 FreeLibrary(hinstDLL
);
1602 HeapFree(GetProcessHeap(), 0, pszDllName
);
1607 ERR("Loading of typelib %s failed with error 0x%08lx\n", pszFileName
, GetLastError());
1612 /*================== ITypeLib(2) Methods ===================================*/
1614 /****************************************************************************
1615 * ITypeLib2_Constructor
1617 * loading a typelib from a in-memory image
1619 static ITypeLib2
* ITypeLib2_Constructor(LPVOID pLib
, DWORD dwTLBLength
)
1623 TLB2Header tlbHeader
;
1624 TLBSegDir tlbSegDir
;
1625 ITypeLibImpl
* pTypeLibImpl
;
1627 TRACE("%p, TLB length = %ld\n", pLib
, dwTLBLength
);
1629 pTypeLibImpl
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ITypeLibImpl
));
1630 if (!pTypeLibImpl
) return NULL
;
1632 ICOM_VTBL(pTypeLibImpl
) = &tlbvt
;
1633 pTypeLibImpl
->ref
= 1;
1635 /* get pointer to beginning of typelib data */
1639 cx
.pLibInfo
= pTypeLibImpl
;
1640 cx
.length
= dwTLBLength
;
1643 TLB_Read((void*)&tlbHeader
, sizeof(tlbHeader
), &cx
, 0);
1645 TRACE("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader
.magic1
,tlbHeader
.magic2
);
1646 if (memcmp(&tlbHeader
.magic1
,TLBMAGIC2
,4)) {
1647 FIXME("Header type magic 0x%08x not supported.\n",tlbHeader
.magic1
);
1650 /* there is a small number of information here until the next important
1652 * the segment directory . Try to calculate the amount of data */
1653 lPSegDir
= sizeof(tlbHeader
) + (tlbHeader
.nrtypeinfos
)*4 + ((tlbHeader
.varflags
& HELPDLLFLAG
)? 4 :0);
1655 /* now read the segment directory */
1656 TRACE("read segment directory (at %ld)\n",lPSegDir
);
1657 TLB_Read((void*)&tlbSegDir
, sizeof(tlbSegDir
), &cx
, lPSegDir
);
1658 cx
.pTblDir
= &tlbSegDir
;
1660 /* just check two entries */
1661 if ( tlbSegDir
.pTypeInfoTab
.res0c
!= 0x0F || tlbSegDir
.pImpInfo
.res0c
!= 0x0F)
1663 ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir
);
1664 HeapFree(GetProcessHeap(),0,pTypeLibImpl
);
1668 /* now fill our internal data */
1669 /* TLIBATTR fields */
1670 TLB_ReadGuid(&pTypeLibImpl
->LibAttr
.guid
, tlbHeader
.posguid
, &cx
);
1671 pTypeLibImpl
->LibAttr
.lcid
= tlbHeader
.lcid
;
1672 pTypeLibImpl
->LibAttr
.syskind
= tlbHeader
.varflags
& 0x0f; /* check the mask */
1673 pTypeLibImpl
->LibAttr
.wMajorVerNum
= LOWORD(tlbHeader
.version
);
1674 pTypeLibImpl
->LibAttr
.wMinorVerNum
= HIWORD(tlbHeader
.version
);
1675 pTypeLibImpl
->LibAttr
.wLibFlags
= (WORD
) tlbHeader
.flags
& 0xffff;/* check mask */
1677 /* name, eventually add to a hash table */
1678 pTypeLibImpl
->Name
= TLB_ReadName(&cx
, tlbHeader
.NameOffset
);
1681 pTypeLibImpl
->DocString
= TLB_ReadString(&cx
, tlbHeader
.helpstring
);
1682 pTypeLibImpl
->HelpFile
= TLB_ReadString(&cx
, tlbHeader
.helpfile
);
1684 if( tlbHeader
.varflags
& HELPDLLFLAG
)
1687 TLB_Read(&offset
, sizeof(offset
), &cx
, sizeof(tlbHeader
));
1688 pTypeLibImpl
->HelpStringDll
= TLB_ReadString(&cx
, offset
);
1691 pTypeLibImpl
->dwHelpContext
= tlbHeader
.helpstringcontext
;
1694 if(tlbHeader
.CustomDataOffset
>= 0)
1696 pTypeLibImpl
->ctCustData
= TLB_CustData(&cx
, tlbHeader
.CustomDataOffset
, &pTypeLibImpl
->pCustData
);
1699 /* fill in typedescriptions */
1700 if(tlbSegDir
.pTypdescTab
.length
> 0)
1702 int i
, j
, cTD
= tlbSegDir
.pTypdescTab
.length
/ (2*sizeof(INT
));
1704 pTypeLibImpl
->pTypeDesc
= TLB_Alloc( cTD
* sizeof(TYPEDESC
));
1705 TLB_Read(td
, sizeof(td
), &cx
, tlbSegDir
.pTypdescTab
.offset
);
1708 /* FIXME: add several sanity checks here */
1709 pTypeLibImpl
->pTypeDesc
[i
].vt
= td
[0] & VT_TYPEMASK
;
1710 if(td
[0] == VT_PTR
|| td
[0] == VT_SAFEARRAY
)
1712 /* FIXME: check safearray */
1714 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lptdesc
)= & stndTypeDesc
[td
[2]];
1716 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lptdesc
)= & pTypeLibImpl
->pTypeDesc
[td
[2]/8];
1718 else if(td
[0] == VT_CARRAY
)
1720 /* array descr table here */
1721 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
) = (void *)((int) td
[2]); /* temp store offset in*/
1723 else if(td
[0] == VT_USERDEFINED
)
1725 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),hreftype
) = MAKELONG(td
[2],td
[3]);
1727 if(++i
<cTD
) TLB_Read(td
, sizeof(td
), &cx
, DO_NOT_SEEK
);
1730 /* second time around to fill the array subscript info */
1733 if(pTypeLibImpl
->pTypeDesc
[i
].vt
!= VT_CARRAY
) continue;
1734 if(tlbSegDir
.pArrayDescriptions
.offset
>0)
1736 TLB_Read(td
, sizeof(td
), &cx
, tlbSegDir
.pArrayDescriptions
.offset
+ (int) V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
));
1737 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
) = TLB_Alloc(sizeof(ARRAYDESC
)+sizeof(SAFEARRAYBOUND
)*(td
[3]-1));
1740 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
)->tdescElem
.vt
= td
[0] & VT_TYPEMASK
;
1742 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
)->tdescElem
= stndTypeDesc
[td
[0]/8];
1744 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
)->cDims
= td
[2];
1746 for(j
= 0; j
<td
[2]; j
++)
1748 TLB_Read(& V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
)->rgbounds
[j
].cElements
,
1749 sizeof(INT
), &cx
, DO_NOT_SEEK
);
1750 TLB_Read(& V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
)->rgbounds
[j
].lLbound
,
1751 sizeof(INT
), &cx
, DO_NOT_SEEK
);
1756 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
) = NULL
;
1757 ERR("didn't find array description data\n");
1762 /* imported type libs */
1763 if(tlbSegDir
.pImpFiles
.offset
>0)
1765 TLBImpLib
**ppImpLib
= &(pTypeLibImpl
->pImpLibs
);
1766 int oGuid
, offset
= tlbSegDir
.pImpFiles
.offset
;
1769 while(offset
< tlbSegDir
.pImpFiles
.offset
+tlbSegDir
.pImpFiles
.length
)
1771 *ppImpLib
= TLB_Alloc(sizeof(TLBImpLib
));
1772 (*ppImpLib
)->offset
= offset
- tlbSegDir
.pImpFiles
.offset
;
1773 TLB_Read(&oGuid
, sizeof(INT
), &cx
, offset
);
1775 TLB_Read(&(*ppImpLib
)->lcid
, sizeof(LCID
), &cx
, DO_NOT_SEEK
);
1776 TLB_Read(&(*ppImpLib
)->wVersionMajor
, sizeof(WORD
), &cx
, DO_NOT_SEEK
);
1777 TLB_Read(&(*ppImpLib
)->wVersionMinor
, sizeof(WORD
), &cx
, DO_NOT_SEEK
);
1778 TLB_Read(& size
, sizeof(UINT16
), &cx
, DO_NOT_SEEK
);
1781 (*ppImpLib
)->name
= TLB_Alloc(size
+1);
1782 TLB_Read((*ppImpLib
)->name
, size
, &cx
, DO_NOT_SEEK
);
1783 TLB_ReadGuid(&(*ppImpLib
)->guid
, oGuid
, &cx
);
1784 offset
= (offset
+ sizeof(INT
) + sizeof(DWORD
) + sizeof(LCID
) + sizeof(UINT16
) + size
+ 3) & 0xfffffffc;
1786 ppImpLib
= &(*ppImpLib
)->next
;
1791 if(tlbHeader
.nrtypeinfos
>= 0 )
1793 /*pTypeLibImpl->TypeInfoCount=tlbHeader.nrtypeinfos; */
1794 ITypeInfoImpl
**ppTI
= &(pTypeLibImpl
->pTypeInfo
);
1797 for(i
= 0; i
<(int)tlbHeader
.nrtypeinfos
; i
++)
1799 *ppTI
= TLB_DoTypeInfo(&cx
, i
, pTypeLibImpl
);
1801 ITypeInfo_AddRef((ITypeInfo
*) *ppTI
);
1802 ppTI
= &((*ppTI
)->next
);
1803 (pTypeLibImpl
->TypeInfoCount
)++;
1807 TRACE("(%p)\n", pTypeLibImpl
);
1808 return (ITypeLib2
*) pTypeLibImpl
;
1811 /* ITypeLib::QueryInterface
1813 static HRESULT WINAPI
ITypeLib2_fnQueryInterface(
1818 ICOM_THIS( ITypeLibImpl
, iface
);
1820 TRACE("(%p)->(IID: %s)\n",This
,debugstr_guid(riid
));
1823 if(IsEqualIID(riid
, &IID_IUnknown
) ||
1824 IsEqualIID(riid
,&IID_ITypeLib
)||
1825 IsEqualIID(riid
,&IID_ITypeLib2
))
1832 ITypeLib2_AddRef(iface
);
1833 TRACE("-- Interface: (%p)->(%p)\n",ppvObject
,*ppvObject
);
1836 TRACE("-- Interface: E_NOINTERFACE\n");
1837 return E_NOINTERFACE
;
1842 static ULONG WINAPI
ITypeLib2_fnAddRef( ITypeLib2
*iface
)
1844 ICOM_THIS( ITypeLibImpl
, iface
);
1846 TRACE("(%p)->ref is %u\n",This
, This
->ref
);
1848 return ++(This
->ref
);
1851 /* ITypeLib::Release
1853 static ULONG WINAPI
ITypeLib2_fnRelease( ITypeLib2
*iface
)
1855 ICOM_THIS( ITypeLibImpl
, iface
);
1859 TRACE("(%p)->(%u)\n",This
, This
->ref
);
1863 /* fixme destroy child objects */
1865 TRACE(" destroying ITypeLib(%p)\n",This
);
1869 SysFreeString(This
->Name
);
1873 if (This
->DocString
)
1875 SysFreeString(This
->DocString
);
1876 This
->DocString
= NULL
;
1881 SysFreeString(This
->HelpFile
);
1882 This
->HelpFile
= NULL
;
1885 if (This
->HelpStringDll
)
1887 SysFreeString(This
->HelpStringDll
);
1888 This
->HelpStringDll
= NULL
;
1891 ITypeInfo_Release((ITypeInfo
*) This
->pTypeInfo
);
1892 HeapFree(GetProcessHeap(),0,This
);
1899 /* ITypeLib::GetTypeInfoCount
1901 * Returns the number of type descriptions in the type library
1903 static UINT WINAPI
ITypeLib2_fnGetTypeInfoCount( ITypeLib2
*iface
)
1905 ICOM_THIS( ITypeLibImpl
, iface
);
1906 TRACE("(%p)->count is %d\n",This
, This
->TypeInfoCount
);
1907 return This
->TypeInfoCount
;
1910 /* ITypeLib::GetTypeInfo
1912 * retrieves the specified type description in the library.
1914 static HRESULT WINAPI
ITypeLib2_fnGetTypeInfo(
1917 ITypeInfo
**ppTInfo
)
1921 ICOM_THIS( ITypeLibImpl
, iface
);
1922 ITypeInfoImpl
*pTypeInfo
= This
->pTypeInfo
;
1924 TRACE("(%p)->(index=%d) \n", This
, index
);
1926 if (!ppTInfo
) return E_INVALIDARG
;
1928 /* search element n in list */
1929 for(i
=0; i
< index
; i
++)
1931 pTypeInfo
= pTypeInfo
->next
;
1934 TRACE("-- element not found\n");
1935 return TYPE_E_ELEMENTNOTFOUND
;
1939 *ppTInfo
= (ITypeInfo
*) pTypeInfo
;
1941 ITypeInfo_AddRef(*ppTInfo
);
1942 TRACE("-- found (%p)\n",*ppTInfo
);
1947 /* ITypeLibs::GetTypeInfoType
1949 * Retrieves the type of a type description.
1951 static HRESULT WINAPI
ITypeLib2_fnGetTypeInfoType(
1956 ICOM_THIS( ITypeLibImpl
, iface
);
1958 ITypeInfoImpl
*pTInfo
= This
->pTypeInfo
;
1960 TRACE("(%p) index %d \n",This
, index
);
1962 if(!pTKind
) return E_INVALIDARG
;
1964 /* search element n in list */
1965 for(i
=0; i
< index
; i
++)
1969 TRACE("-- element not found\n");
1970 return TYPE_E_ELEMENTNOTFOUND
;
1972 pTInfo
= pTInfo
->next
;
1975 *pTKind
= pTInfo
->TypeAttr
.typekind
;
1976 TRACE("-- found Type (%d)\n", *pTKind
);
1980 /* ITypeLib::GetTypeInfoOfGuid
1982 * Retrieves the type description that corresponds to the specified GUID.
1985 static HRESULT WINAPI
ITypeLib2_fnGetTypeInfoOfGuid(
1988 ITypeInfo
**ppTInfo
)
1990 ICOM_THIS( ITypeLibImpl
, iface
);
1991 ITypeInfoImpl
*pTypeInfo
= This
->pTypeInfo
; /* head of list */
1993 TRACE("(%p)\n\tguid:\t%s)\n",This
,debugstr_guid(guid
));
1995 if (!pTypeInfo
) return TYPE_E_ELEMENTNOTFOUND
;
1997 /* search linked list for guid */
1998 while( !IsEqualIID(guid
,&pTypeInfo
->TypeAttr
.guid
) )
2000 pTypeInfo
= pTypeInfo
->next
;
2004 /* end of list reached */
2005 TRACE("-- element not found\n");
2006 return TYPE_E_ELEMENTNOTFOUND
;
2010 TRACE("-- found (%p, %s)\n",
2012 debugstr_w(pTypeInfo
->Name
));
2014 *ppTInfo
= (ITypeInfo
*)pTypeInfo
;
2015 ITypeInfo_AddRef(*ppTInfo
);
2019 /* ITypeLib::GetLibAttr
2021 * Retrieves the structure that contains the library's attributes.
2024 static HRESULT WINAPI
ITypeLib2_fnGetLibAttr(
2026 LPTLIBATTR
*ppTLibAttr
)
2028 ICOM_THIS( ITypeLibImpl
, iface
);
2029 TRACE("(%p)\n",This
);
2030 /* FIXME: must do a copy here */
2031 *ppTLibAttr
=&This
->LibAttr
;
2035 /* ITypeLib::GetTypeComp
2037 * Enables a client compiler to bind to a library's types, variables,
2038 * constants, and global functions.
2041 static HRESULT WINAPI
ITypeLib2_fnGetTypeComp(
2043 ITypeComp
**ppTComp
)
2045 ICOM_THIS( ITypeLibImpl
, iface
);
2046 FIXME("(%p): stub!\n",This
);
2050 /* ITypeLib::GetDocumentation
2052 * Retrieves the library's documentation string, the complete Help file name
2053 * and path, and the context identifier for the library Help topic in the Help
2057 static HRESULT WINAPI
ITypeLib2_fnGetDocumentation(
2061 BSTR
*pBstrDocString
,
2062 DWORD
*pdwHelpContext
,
2063 BSTR
*pBstrHelpFile
)
2065 ICOM_THIS( ITypeLibImpl
, iface
);
2067 HRESULT result
= E_INVALIDARG
;
2072 TRACE("(%p) index %d Name(%p) DocString(%p) HelpContext(%p) HelpFile(%p)\n",
2074 pBstrName
, pBstrDocString
,
2075 pdwHelpContext
, pBstrHelpFile
);
2079 /* documentation for the typelib */
2080 if(pBstrName
&& This
->Name
)
2082 *pBstrName
= SysAllocString(This
->Name
);
2084 if (!(*pBstrName
)) return STG_E_INSUFFICIENTMEMORY
;
2086 if(pBstrDocString
&& This
->DocString
)
2088 *pBstrDocString
= SysAllocString(This
->DocString
);
2090 if (!(*pBstrDocString
)) return STG_E_INSUFFICIENTMEMORY
;
2095 *pdwHelpContext
= This
->dwHelpContext
;
2097 if(pBstrHelpFile
&& This
->HelpFile
)
2099 *pBstrHelpFile
= SysAllocString(This
->HelpFile
);
2101 if (!(*pBstrHelpFile
)) return STG_E_INSUFFICIENTMEMORY
;
2108 /* for a typeinfo */
2109 result
= ITypeLib2_fnGetTypeInfo(iface
, index
, &pTInfo
);
2111 if(SUCCEEDED(result
))
2113 result
= ITypeInfo_GetDocumentation(pTInfo
,
2117 pdwHelpContext
, pBstrHelpFile
);
2119 ITypeInfo_Release(pTInfo
);
2127 * Indicates whether a passed-in string contains the name of a type or member
2128 * described in the library.
2131 static HRESULT WINAPI
ITypeLib2_fnIsName(
2137 ICOM_THIS( ITypeLibImpl
, iface
);
2138 ITypeInfoImpl
*pTInfo
;
2139 TLBFuncDesc
*pFInfo
;
2142 UINT nNameBufLen
= SysStringLen(szNameBuf
);
2144 TRACE("(%p)->(%s,%08lx,%p)\n", This
, debugstr_w(szNameBuf
), lHashVal
,
2148 for(pTInfo
=This
->pTypeInfo
;pTInfo
;pTInfo
=pTInfo
->next
){
2149 if(!memcmp(szNameBuf
,pTInfo
->Name
, nNameBufLen
)) goto ITypeLib2_fnIsName_exit
;
2150 for(pFInfo
=pTInfo
->funclist
;pFInfo
;pFInfo
=pFInfo
->next
) {
2151 if(!memcmp(szNameBuf
,pFInfo
->Name
, nNameBufLen
)) goto ITypeLib2_fnIsName_exit
;
2152 for(i
=0;i
<pFInfo
->funcdesc
.cParams
;i
++)
2153 if(!memcmp(szNameBuf
,pFInfo
->pParamDesc
[i
].Name
, nNameBufLen
))
2154 goto ITypeLib2_fnIsName_exit
;
2156 for(pVInfo
=pTInfo
->varlist
;pVInfo
;pVInfo
=pVInfo
->next
)
2157 if(!memcmp(szNameBuf
,pVInfo
->Name
, nNameBufLen
)) goto ITypeLib2_fnIsName_exit
;
2162 ITypeLib2_fnIsName_exit
:
2163 TRACE("(%p)slow! search for %s: %s found!\n", This
,
2164 debugstr_w(szNameBuf
), *pfName
?"NOT":"");
2169 /* ITypeLib::FindName
2171 * Finds occurrences of a type description in a type library. This may be used
2172 * to quickly verify that a name exists in a type library.
2175 static HRESULT WINAPI
ITypeLib2_fnFindName(
2179 ITypeInfo
**ppTInfo
,
2183 ICOM_THIS( ITypeLibImpl
, iface
);
2184 ITypeInfoImpl
*pTInfo
;
2185 TLBFuncDesc
*pFInfo
;
2189 UINT nNameBufLen
= SysStringLen(szNameBuf
);
2191 for(pTInfo
=This
->pTypeInfo
;pTInfo
&& j
<*pcFound
; pTInfo
=pTInfo
->next
){
2192 if(!memcmp(szNameBuf
,pTInfo
->Name
, nNameBufLen
)) goto ITypeLib2_fnFindName_exit
;
2193 for(pFInfo
=pTInfo
->funclist
;pFInfo
;pFInfo
=pFInfo
->next
) {
2194 if(!memcmp(szNameBuf
,pFInfo
->Name
,nNameBufLen
)) goto ITypeLib2_fnFindName_exit
;
2195 for(i
=0;i
<pFInfo
->funcdesc
.cParams
;i
++)
2196 if(!memcmp(szNameBuf
,pFInfo
->pParamDesc
[i
].Name
,nNameBufLen
))
2197 goto ITypeLib2_fnFindName_exit
;
2199 for(pVInfo
=pTInfo
->varlist
;pVInfo
;pVInfo
=pVInfo
->next
)
2200 if(!memcmp(szNameBuf
,pVInfo
->Name
, nNameBufLen
)) goto ITypeLib2_fnFindName_exit
;
2202 ITypeLib2_fnFindName_exit
:
2203 ITypeInfo_AddRef((ITypeInfo
*)pTInfo
);
2204 ppTInfo
[j
]=(LPTYPEINFO
)pTInfo
;
2207 TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
2208 This
, *pcFound
, debugstr_w(szNameBuf
), j
);
2215 /* ITypeLib::ReleaseTLibAttr
2217 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
2220 static VOID WINAPI
ITypeLib2_fnReleaseTLibAttr(
2222 TLIBATTR
*pTLibAttr
)
2224 ICOM_THIS( ITypeLibImpl
, iface
);
2225 TRACE("freeing (%p)\n",This
);
2229 /* ITypeLib2::GetCustData
2231 * gets the custom data
2233 static HRESULT WINAPI
ITypeLib2_fnGetCustData(
2238 ICOM_THIS( ITypeLibImpl
, iface
);
2239 TLBCustData
*pCData
;
2241 for(pCData
=This
->pCustData
; pCData
; pCData
= pCData
->next
)
2243 if( IsEqualIID(guid
, &pCData
->guid
)) break;
2246 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
2250 VariantInit( pVarVal
);
2251 VariantCopy( pVarVal
, &pCData
->data
);
2254 return E_INVALIDARG
; /* FIXME: correct? */
2257 /* ITypeLib2::GetLibStatistics
2259 * Returns statistics about a type library that are required for efficient
2260 * sizing of hash tables.
2263 static HRESULT WINAPI
ITypeLib2_fnGetLibStatistics(
2265 ULONG
*pcUniqueNames
,
2266 ULONG
*pcchUniqueNames
)
2268 ICOM_THIS( ITypeLibImpl
, iface
);
2270 FIXME("(%p): stub!\n", This
);
2272 if(pcUniqueNames
) *pcUniqueNames
=1;
2273 if(pcchUniqueNames
) *pcchUniqueNames
=1;
2277 /* ITypeLib2::GetDocumentation2
2279 * Retrieves the library's documentation string, the complete Help file name
2280 * and path, the localization context to use, and the context ID for the
2281 * library Help topic in the Help file.
2284 static HRESULT WINAPI
ITypeLib2_fnGetDocumentation2(
2288 BSTR
*pbstrHelpString
,
2289 DWORD
*pdwHelpStringContext
,
2290 BSTR
*pbstrHelpStringDll
)
2292 ICOM_THIS( ITypeLibImpl
, iface
);
2296 FIXME("(%p) index %d lcid %ld half implemented stub!\n", This
, index
, lcid
);
2298 /* the help string should be obtained from the helpstringdll,
2299 * using the _DLLGetDocumentation function, based on the supplied
2300 * lcid. Nice to do sometime...
2304 /* documentation for the typelib */
2306 *pbstrHelpString
=SysAllocString(This
->DocString
);
2307 if(pdwHelpStringContext
)
2308 *pdwHelpStringContext
=This
->dwHelpContext
;
2309 if(pbstrHelpStringDll
)
2310 *pbstrHelpStringDll
=SysAllocString(This
->HelpStringDll
);
2316 /* for a typeinfo */
2317 result
=ITypeLib2_GetTypeInfo(iface
, index
, &pTInfo
);
2319 if(SUCCEEDED(result
))
2321 ITypeInfo2
* pTInfo2
;
2322 result
= ITypeInfo_QueryInterface(pTInfo
,
2324 (LPVOID
*) &pTInfo2
);
2326 if(SUCCEEDED(result
))
2328 result
= ITypeInfo2_GetDocumentation2(pTInfo2
,
2332 pdwHelpStringContext
,
2333 pbstrHelpStringDll
);
2335 ITypeInfo2_Release(pTInfo2
);
2338 ITypeInfo_Release(pTInfo
);
2344 /* ITypeLib2::GetAllCustData
2346 * Gets all custom data items for the library.
2349 static HRESULT WINAPI
ITypeLib2_fnGetAllCustData(
2351 CUSTDATA
*pCustData
)
2353 ICOM_THIS( ITypeLibImpl
, iface
);
2354 TLBCustData
*pCData
;
2356 TRACE("(%p) returning %d items\n", This
, This
->ctCustData
);
2357 pCustData
->prgCustData
= TLB_Alloc(This
->ctCustData
* sizeof(CUSTDATAITEM
));
2358 if(pCustData
->prgCustData
){
2359 pCustData
->cCustData
=This
->ctCustData
;
2360 for(i
=0, pCData
=This
->pCustData
; pCData
; i
++, pCData
= pCData
->next
){
2361 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
2362 VariantCopy(& pCustData
->prgCustData
[i
].varValue
, & pCData
->data
);
2365 ERR(" OUT OF MEMORY! \n");
2366 return E_OUTOFMEMORY
;
2371 static ICOM_VTABLE(ITypeLib2
) tlbvt
= {
2372 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2373 ITypeLib2_fnQueryInterface
,
2375 ITypeLib2_fnRelease
,
2376 ITypeLib2_fnGetTypeInfoCount
,
2377 ITypeLib2_fnGetTypeInfo
,
2378 ITypeLib2_fnGetTypeInfoType
,
2379 ITypeLib2_fnGetTypeInfoOfGuid
,
2380 ITypeLib2_fnGetLibAttr
,
2381 ITypeLib2_fnGetTypeComp
,
2382 ITypeLib2_fnGetDocumentation
,
2384 ITypeLib2_fnFindName
,
2385 ITypeLib2_fnReleaseTLibAttr
,
2387 ITypeLib2_fnGetCustData
,
2388 ITypeLib2_fnGetLibStatistics
,
2389 ITypeLib2_fnGetDocumentation2
,
2390 ITypeLib2_fnGetAllCustData
2393 /*================== ITypeInfo(2) Methods ===================================*/
2394 static ITypeInfo2
* WINAPI
ITypeInfo_Constructor(void)
2396 ITypeInfoImpl
* pTypeInfoImpl
;
2398 pTypeInfoImpl
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ITypeInfoImpl
));
2401 ICOM_VTBL(pTypeInfoImpl
) = &tinfvt
;
2402 pTypeInfoImpl
->ref
=1;
2404 TRACE("(%p)\n", pTypeInfoImpl
);
2405 return (ITypeInfo2
*) pTypeInfoImpl
;
2408 /* ITypeInfo::QueryInterface
2410 static HRESULT WINAPI
ITypeInfo_fnQueryInterface(
2415 ICOM_THIS( ITypeLibImpl
, iface
);
2417 TRACE("(%p)->(IID: %s)\n",This
,debugstr_guid(riid
));
2420 if(IsEqualIID(riid
, &IID_IUnknown
) ||
2421 IsEqualIID(riid
,&IID_ITypeInfo
)||
2422 IsEqualIID(riid
,&IID_ITypeInfo2
))
2426 ITypeInfo_AddRef(iface
);
2427 TRACE("-- Interface: (%p)->(%p)\n",ppvObject
,*ppvObject
);
2430 TRACE("-- Interface: E_NOINTERFACE\n");
2431 return E_NOINTERFACE
;
2434 /* ITypeInfo::AddRef
2436 static ULONG WINAPI
ITypeInfo_fnAddRef( ITypeInfo2
*iface
)
2438 ICOM_THIS( ITypeInfoImpl
, iface
);
2442 TRACE("(%p)->ref is %u\n",This
, This
->ref
);
2446 /* ITypeInfo::Release
2448 static ULONG WINAPI
ITypeInfo_fnRelease( ITypeInfo2
*iface
)
2450 ICOM_THIS( ITypeInfoImpl
, iface
);
2454 TRACE("(%p)->(%u)\n",This
, This
->ref
);
2458 FIXME("destroy child objects\n");
2460 TRACE("destroying ITypeInfo(%p)\n",This
);
2463 SysFreeString(This
->Name
);
2467 if (This
->DocString
)
2469 SysFreeString(This
->DocString
);
2470 This
->DocString
= 0;
2475 ITypeInfo_Release((ITypeInfo
*)This
->next
);
2478 HeapFree(GetProcessHeap(),0,This
);
2484 /* ITypeInfo::GetTypeAttr
2486 * Retrieves a TYPEATTR structure that contains the attributes of the type
2490 static HRESULT WINAPI
ITypeInfo_fnGetTypeAttr( ITypeInfo2
*iface
,
2491 LPTYPEATTR
*ppTypeAttr
)
2493 ICOM_THIS( ITypeInfoImpl
, iface
);
2494 TRACE("(%p)\n",This
);
2495 /* FIXME: must do a copy here */
2496 *ppTypeAttr
=&This
->TypeAttr
;
2500 /* ITypeInfo::GetTypeComp
2502 * Retrieves the ITypeComp interface for the type description, which enables a
2503 * client compiler to bind to the type description's members.
2506 static HRESULT WINAPI
ITypeInfo_fnGetTypeComp( ITypeInfo2
*iface
,
2507 ITypeComp
* *ppTComp
)
2509 ICOM_THIS( ITypeInfoImpl
, iface
);
2510 FIXME("(%p) stub!\n", This
);
2514 /* ITypeInfo::GetFuncDesc
2516 * Retrieves the FUNCDESC structure that contains information about a
2517 * specified function.
2520 static HRESULT WINAPI
ITypeInfo_fnGetFuncDesc( ITypeInfo2
*iface
, UINT index
,
2521 LPFUNCDESC
*ppFuncDesc
)
2523 ICOM_THIS( ITypeInfoImpl
, iface
);
2525 TLBFuncDesc
* pFDesc
;
2526 TRACE("(%p) index %d\n", This
, index
);
2527 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++, pFDesc
=pFDesc
->next
)
2530 /* FIXME: must do a copy here */
2531 *ppFuncDesc
=&pFDesc
->funcdesc
;
2534 return E_INVALIDARG
;
2537 /* ITypeInfo::GetVarDesc
2539 * Retrieves a VARDESC structure that describes the specified variable.
2542 static HRESULT WINAPI
ITypeInfo_fnGetVarDesc( ITypeInfo2
*iface
, UINT index
,
2543 LPVARDESC
*ppVarDesc
)
2545 ICOM_THIS( ITypeInfoImpl
, iface
);
2547 TLBVarDesc
* pVDesc
;
2548 TRACE("(%p) index %d\n", This
, index
);
2549 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++, pVDesc
=pVDesc
->next
)
2552 /* FIXME: must do a copy here */
2553 *ppVarDesc
=&pVDesc
->vardesc
;
2556 return E_INVALIDARG
;
2559 /* ITypeInfo_GetNames
2561 * Retrieves the variable with the specified member ID (or the name of the
2562 * property or method and its parameters) that correspond to the specified
2565 static HRESULT WINAPI
ITypeInfo_fnGetNames( ITypeInfo2
*iface
, MEMBERID memid
,
2566 BSTR
*rgBstrNames
, UINT cMaxNames
, UINT
*pcNames
)
2568 ICOM_THIS( ITypeInfoImpl
, iface
);
2569 TLBFuncDesc
* pFDesc
;
2570 TLBVarDesc
* pVDesc
;
2572 TRACE("(%p) memid=0x%08lx Maxname=%d\n", This
, memid
, cMaxNames
);
2573 for(pFDesc
=This
->funclist
; pFDesc
&& pFDesc
->funcdesc
.memid
!= memid
; pFDesc
=pFDesc
->next
);
2576 /* function found, now return function and parameter names */
2577 for(i
=0; i
<cMaxNames
&& i
<= pFDesc
->funcdesc
.cParams
; i
++)
2580 *rgBstrNames
=SysAllocString(pFDesc
->Name
);
2582 rgBstrNames
[i
]=SysAllocString(pFDesc
->pParamDesc
[i
-1].Name
);
2588 for(pVDesc
=This
->varlist
; pVDesc
&& pVDesc
->vardesc
.memid
!= memid
; pVDesc
=pVDesc
->next
);
2591 *rgBstrNames
=SysAllocString(pVDesc
->Name
);
2596 if(This
->TypeAttr
.typekind
==TKIND_INTERFACE
&& This
->TypeAttr
.cImplTypes
)
2598 /* recursive search */
2601 result
=ITypeInfo_GetRefTypeInfo(iface
, This
->impltypelist
->reference
, &pTInfo
);
2602 if(SUCCEEDED(result
))
2604 result
=ITypeInfo_GetNames(pTInfo
, memid
, rgBstrNames
, cMaxNames
, pcNames
);
2605 ITypeInfo_Release(pTInfo
);
2608 WARN("Could not search inherited interface!\n");
2612 WARN("no names found\n");
2615 return TYPE_E_ELEMENTNOTFOUND
;
2622 /* ITypeInfo::GetRefTypeOfImplType
2624 * If a type description describes a COM class, it retrieves the type
2625 * description of the implemented interface types. For an interface,
2626 * GetRefTypeOfImplType returns the type information for inherited interfaces,
2630 static HRESULT WINAPI
ITypeInfo_fnGetRefTypeOfImplType(
2635 ICOM_THIS( ITypeInfoImpl
, iface
);
2637 TLBRefType
*pIref
= This
->impltypelist
;
2639 TRACE("(%p) index %d\n", This
, index
);
2640 dump_TypeInfo(This
);
2644 /* only valid on dual interfaces;
2645 retrieve the associated TKIND_INTERFACE handle for the current TKIND_DISPATCH
2647 if( This
->TypeAttr
.typekind
!= TKIND_DISPATCH
) return E_INVALIDARG
;
2649 if (This
->TypeAttr
.wTypeFlags
& TYPEFLAG_FDISPATCHABLE
&&
2650 This
->TypeAttr
.wTypeFlags
& TYPEFLAG_FDUAL
)
2656 if (!pIref
) return TYPE_E_ELEMENTNOTFOUND
;
2657 *pRefType
= pIref
->reference
;
2662 /* get element n from linked list */
2663 for(i
=0; pIref
&& i
<index
; i
++)
2665 pIref
= pIref
->next
;
2668 if (!pIref
) return TYPE_E_ELEMENTNOTFOUND
;
2670 *pRefType
= pIref
->reference
;
2672 TRACE("-- 0x%08lx %s\n",pIref
->reference
, debugstr_guid(&pIref
->guid
) );
2679 /* ITypeInfo::GetImplTypeFlags
2681 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
2682 * or base interface in a type description.
2684 static HRESULT WINAPI
ITypeInfo_fnGetImplTypeFlags( ITypeInfo2
*iface
,
2685 UINT index
, INT
*pImplTypeFlags
)
2687 ICOM_THIS( ITypeInfoImpl
, iface
);
2690 TRACE("(%p) index %d\n", This
, index
);
2691 for(i
=0, pIref
=This
->impltypelist
; i
<index
&& pIref
; i
++, pIref
=pIref
->next
)
2693 if(i
==index
&& pIref
){
2694 *pImplTypeFlags
=pIref
->flags
;
2698 return TYPE_E_ELEMENTNOTFOUND
;
2702 * Maps between member names and member IDs, and parameter names and
2705 static HRESULT WINAPI
ITypeInfo_fnGetIDsOfNames( ITypeInfo2
*iface
,
2706 LPOLESTR
*rgszNames
, UINT cNames
, MEMBERID
*pMemId
)
2708 ICOM_THIS( ITypeInfoImpl
, iface
);
2709 TLBFuncDesc
* pFDesc
;
2710 TLBVarDesc
* pVDesc
;
2712 UINT nNameLen
= SysStringLen(*rgszNames
);
2714 TRACE("(%p) Name %s cNames %d\n", This
, debugstr_w(*rgszNames
),
2716 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
) {
2718 if( !memcmp(*rgszNames
, pFDesc
->Name
, nNameLen
)) {
2719 if(cNames
) *pMemId
=pFDesc
->funcdesc
.memid
;
2720 for(i
=1; i
< cNames
; i
++){
2721 UINT nParamLen
= SysStringLen(rgszNames
[i
]);
2722 for(j
=0; j
<pFDesc
->funcdesc
.cParams
; j
++)
2723 if(memcmp(rgszNames
[i
],pFDesc
->pParamDesc
[j
].Name
, nParamLen
))
2725 if( j
<pFDesc
->funcdesc
.cParams
)
2728 ret
=DISP_E_UNKNOWNNAME
;
2733 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
) {
2734 if( !memcmp(*rgszNames
, pVDesc
->Name
, nNameLen
)) {
2735 if(cNames
) *pMemId
=pVDesc
->vardesc
.memid
;
2739 /* not found, see if this is and interface with an inheritance */
2740 if(This
->TypeAttr
.typekind
==TKIND_INTERFACE
&&
2741 This
->TypeAttr
.cImplTypes
){
2742 /* recursive search */
2744 ret
=ITypeInfo_GetRefTypeInfo(iface
,
2745 This
->impltypelist
->reference
, &pTInfo
);
2747 ret
=ITypeInfo_GetIDsOfNames(pTInfo
, rgszNames
, cNames
, pMemId
);
2748 ITypeInfo_Release(pTInfo
);
2751 WARN("Could not search inherited interface!\n");
2753 WARN("no names found\n");
2754 return DISP_E_UNKNOWNNAME
;
2757 /* ITypeInfo::Invoke
2759 * Invokes a method, or accesses a property of an object, that implements the
2760 * interface described by the type description.
2762 static HRESULT WINAPI
ITypeInfo_fnInvoke(
2767 DISPPARAMS
*pDispParams
,
2768 VARIANT
*pVarResult
,
2769 EXCEPINFO
*pExcepInfo
,
2772 ICOM_THIS( ITypeInfoImpl
, iface
);
2773 FIXME("(%p)(%p,id=0x%08lx,0x%08x,%p,%p,%p,%p) stub!\n",
2774 This
, pIUnk
, memid
, dwFlags
, pDispParams
, pVarResult
, pExcepInfo
, pArgErr
);
2775 dump_DispParms(pDispParams
);
2779 /* ITypeInfo::GetDocumentation
2781 * Retrieves the documentation string, the complete Help file name and path,
2782 * and the context ID for the Help topic for a specified type description.
2784 static HRESULT WINAPI
ITypeInfo_fnGetDocumentation( ITypeInfo2
*iface
,
2785 MEMBERID memid
, BSTR
*pBstrName
, BSTR
*pBstrDocString
,
2786 DWORD
*pdwHelpContext
, BSTR
*pBstrHelpFile
)
2788 ICOM_THIS( ITypeInfoImpl
, iface
);
2789 TLBFuncDesc
* pFDesc
;
2790 TLBVarDesc
* pVDesc
;
2791 TRACE("(%p) memid %ld Name(%p) DocString(%p)"
2792 " HelpContext(%p) HelpFile(%p)\n",
2793 This
, memid
, pBstrName
, pBstrDocString
, pdwHelpContext
, pBstrHelpFile
);
2794 if(memid
==MEMBERID_NIL
){ /* documentation for the typeinfo */
2796 *pBstrName
=SysAllocString(This
->Name
);
2798 *pBstrDocString
=SysAllocString(This
->DocString
);
2800 *pdwHelpContext
=This
->dwHelpContext
;
2802 *pBstrHelpFile
=SysAllocString(This
->DocString
);/* FIXME */
2804 }else {/* for a member */
2805 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
)
2806 if(pFDesc
->funcdesc
.memid
==memid
){
2809 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
)
2810 if(pVDesc
->vardesc
.memid
==memid
){
2814 return TYPE_E_ELEMENTNOTFOUND
;
2817 /* ITypeInfo::GetDllEntry
2819 * Retrieves a description or specification of an entry point for a function
2822 static HRESULT WINAPI
ITypeInfo_fnGetDllEntry( ITypeInfo2
*iface
, MEMBERID memid
,
2823 INVOKEKIND invKind
, BSTR
*pBstrDllName
, BSTR
*pBstrName
,
2826 ICOM_THIS( ITypeInfoImpl
, iface
);
2827 FIXME("(%p) stub!\n", This
);
2831 /* ITypeInfo::GetRefTypeInfo
2833 * If a type description references other type descriptions, it retrieves
2834 * the referenced type descriptions.
2836 static HRESULT WINAPI
ITypeInfo_fnGetRefTypeInfo(
2839 ITypeInfo
**ppTInfo
)
2841 ICOM_THIS( ITypeInfoImpl
, iface
);
2842 HRESULT result
= E_FAIL
;
2844 if(HREFTYPE_INTHISFILE(hRefType
))
2848 result
= ITypeInfo_GetContainingTypeLib(iface
, &pTLib
, &Index
);
2849 if(SUCCEEDED( result
))
2851 result
=ITypeLib2_GetTypeInfo(pTLib
, HREFTYPE_INDEX(hRefType
), ppTInfo
);
2852 ITypeLib2_Release(pTLib
);
2855 else if (hRefType
== -1 &&
2856 (((ITypeInfoImpl
*) This
)->TypeAttr
.typekind
== TKIND_DISPATCH
) &&
2857 (((ITypeInfoImpl
*) This
)->TypeAttr
.wTypeFlags
& TYPEFLAG_FDUAL
))
2859 /* when we meet a DUAL dispinterface, we must create the interface
2862 ITypeInfoImpl
* pTypeInfoImpl
= (ITypeInfoImpl
*) ITypeInfo_Constructor();
2865 /* the interface version contains the same information as the dispinterface
2866 * copy the contents of the structs.
2868 *pTypeInfoImpl
= *This
;
2869 pTypeInfoImpl
->ref
= 1;
2871 /* change the type to interface */
2872 pTypeInfoImpl
->TypeAttr
.typekind
= TKIND_INTERFACE
;
2874 *ppTInfo
= (ITypeInfo
*) pTypeInfoImpl
;
2876 ITypeInfo_AddRef((ITypeInfo
*) pTypeInfoImpl
);
2882 /* imported type lib */
2883 TLBRefType
*pRefType
= NULL
;
2885 /* search in implemented types */
2886 for( pRefType
= This
->impltypelist
;
2887 pRefType
&& (pRefType
->reference
!= hRefType
);
2888 pRefType
= pRefType
->next
);
2892 TYPEATTR
* pMyTypeAttr
= &This
->TypeAttr
;
2893 unsigned short cFuncs
= pMyTypeAttr
->cFuncs
;
2894 unsigned short cVars
= pMyTypeAttr
->cVars
;
2896 /* search in arguments */
2899 unsigned short cFuncIndex
= 0;
2901 TLBFuncDesc
* pCurrFunc
= This
->funclist
;
2903 for (cFuncIndex
= 0; !pRefType
&& cFuncIndex
< cFuncs
; ++cFuncIndex
)
2905 FUNCDESC
* pCurrFuncDesc
= &pCurrFunc
->funcdesc
;
2907 short cParams
= pCurrFuncDesc
->cParams
;
2908 short cParamIndex
= 0;
2910 for (cParamIndex
= 0 ;
2911 !pRefType
&& cParamIndex
< cParams
;
2914 TLBParDesc
* pCurrParamDesc
= &(pCurrFunc
->pParamDesc
[cParamIndex
]);
2916 if ( pCurrParamDesc
->pRefType
&& pCurrParamDesc
->pRefType
->reference
== hRefType
)
2918 pRefType
= pCurrParamDesc
->pRefType
;
2919 break; /* also break from outer loop since pRefType != 0 */
2923 pCurrFunc
= pCurrFunc
->next
;
2926 /* search in variables */
2929 FIXME("search hreftype in variables, if any\n");
2930 result
= E_INVALIDARG
; // FIXME : correct?
2934 /* href-referenced typeinfo found! */
2935 if (pRefType
|| hRefType
== -1)
2937 ITypeLibImpl
*pTypeLib
= pRefType
->pImpTLInfo
->pImpTypeLib
;
2941 TRACE("typeinfo in imported typelib that is already loaded\n");
2943 result
= ITypeLib2_GetTypeInfoOfGuid((LPTYPELIB
)pTypeLib
,
2949 result
= LoadRegTypeLib( &pRefType
->pImpTLInfo
->guid
,
2950 pRefType
->pImpTLInfo
->wVersionMajor
,
2951 pRefType
->pImpTLInfo
->wVersionMinor
,
2952 pRefType
->pImpTLInfo
->lcid
,
2953 (LPTYPELIB
*)&pTypeLib
);
2955 if(!SUCCEEDED(result
))
2957 BSTR libnam
=SysAllocString(pRefType
->pImpTLInfo
->name
);
2958 TRACE("typeinfo in imported typelib that isn't already loaded\n");
2959 result
=LoadTypeLib(libnam
, (LPTYPELIB
*)&pTypeLib
);
2960 SysFreeString(libnam
);
2962 if(SUCCEEDED(result
))
2964 result
=ITypeLib2_GetTypeInfoOfGuid((LPTYPELIB
)pTypeLib
, &pRefType
->guid
, ppTInfo
);
2965 pRefType
->pImpTLInfo
->pImpTypeLib
= pTypeLib
;
2966 ITypeLib2_AddRef((ITypeLib
*) pTypeLib
);
2972 TRACE("(%p) hreftype 0x%04lx loaded %s (%p)\n", This
, hRefType
,
2973 SUCCEEDED(result
)? "SUCCESS":"FAILURE", *ppTInfo
);
2977 /* ITypeInfo::AddressOfMember
2979 * Retrieves the addresses of static functions or variables, such as those
2982 static HRESULT WINAPI
ITypeInfo_fnAddressOfMember( ITypeInfo2
*iface
,
2983 MEMBERID memid
, INVOKEKIND invKind
, PVOID
*ppv
)
2985 ICOM_THIS( ITypeInfoImpl
, iface
);
2986 FIXME("(%p) stub!\n", This
);
2990 /* ITypeInfo::CreateInstance
2992 * Creates a new instance of a type that describes a component object class
2995 static HRESULT WINAPI
ITypeInfo_fnCreateInstance( ITypeInfo2
*iface
,
2996 IUnknown
*pUnk
, REFIID riid
, VOID
**ppvObj
)
2998 ICOM_THIS( ITypeInfoImpl
, iface
);
2999 FIXME("(%p) stub!\n", This
);
3003 /* ITypeInfo::GetMops
3005 * Retrieves marshaling information.
3007 static HRESULT WINAPI
ITypeInfo_fnGetMops( ITypeInfo2
*iface
, MEMBERID memid
,
3010 ICOM_THIS( ITypeInfoImpl
, iface
);
3011 FIXME("(%p) stub!\n", This
);
3015 /* ITypeInfo::GetContainingTypeLib
3017 * Retrieves the containing type library and the index of the type description
3018 * within that type library.
3020 static HRESULT WINAPI
ITypeInfo_fnGetContainingTypeLib( ITypeInfo2
*iface
,
3021 ITypeLib
* *ppTLib
, UINT
*pIndex
)
3023 ICOM_THIS( ITypeInfoImpl
, iface
);
3025 return E_INVALIDARG
;
3026 *ppTLib
=(LPTYPELIB
)(This
->pTypeLib
);
3027 *pIndex
=This
->index
;
3028 ITypeLib2_AddRef(*ppTLib
);
3029 TRACE("(%p) returns (%p) index %d!\n", This
, *ppTLib
, *pIndex
);
3033 /* ITypeInfo::ReleaseTypeAttr
3035 * Releases a TYPEATTR previously returned by GetTypeAttr.
3038 static HRESULT WINAPI
ITypeInfo_fnReleaseTypeAttr( ITypeInfo2
*iface
,
3039 TYPEATTR
* pTypeAttr
)
3041 ICOM_THIS( ITypeInfoImpl
, iface
);
3042 TRACE("(%p)->(%p)\n", This
, pTypeAttr
);
3046 /* ITypeInfo::ReleaseFuncDesc
3048 * Releases a FUNCDESC previously returned by GetFuncDesc. *
3050 static HRESULT WINAPI
ITypeInfo_fnReleaseFuncDesc(
3052 FUNCDESC
*pFuncDesc
)
3054 ICOM_THIS( ITypeInfoImpl
, iface
);
3055 TRACE("(%p)->(%p)\n", This
, pFuncDesc
);
3059 /* ITypeInfo::ReleaseVarDesc
3061 * Releases a VARDESC previously returned by GetVarDesc.
3063 static HRESULT WINAPI
ITypeInfo_fnReleaseVarDesc( ITypeInfo2
*iface
,
3066 ICOM_THIS( ITypeInfoImpl
, iface
);
3067 TRACE("(%p)->(%p)\n", This
, pVarDesc
);
3071 /* ITypeInfo2::GetTypeKind
3073 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
3076 static HRESULT WINAPI
ITypeInfo2_fnGetTypeKind( ITypeInfo2
* iface
,
3077 TYPEKIND
*pTypeKind
)
3079 ICOM_THIS( ITypeInfoImpl
, iface
);
3080 *pTypeKind
=This
->TypeAttr
.typekind
;
3081 TRACE("(%p) type 0x%0x\n", This
,*pTypeKind
);
3085 /* ITypeInfo2::GetTypeFlags
3087 * Returns the type flags without any allocations. This returns a DWORD type
3088 * flag, which expands the type flags without growing the TYPEATTR (type
3092 static HRESULT WINAPI
ITypeInfo2_fnGetTypeFlags( ITypeInfo2
* iface
,
3095 ICOM_THIS( ITypeInfoImpl
, iface
);
3096 *pTypeFlags
=This
->TypeAttr
.wTypeFlags
;
3097 TRACE("(%p) flags 0x%04x\n", This
,*pTypeFlags
);
3101 /* ITypeInfo2::GetFuncIndexOfMemId
3102 * Binds to a specific member based on a known DISPID, where the member name
3103 * is not known (for example, when binding to a default member).
3106 static HRESULT WINAPI
ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2
* iface
,
3107 MEMBERID memid
, INVOKEKIND invKind
, UINT
*pFuncIndex
)
3109 ICOM_THIS( ITypeInfoImpl
, iface
);
3110 TLBFuncDesc
*pFuncInfo
;
3113 /* FIXME: should check for invKind??? */
3114 for(i
=0, pFuncInfo
=This
->funclist
;pFuncInfo
&&
3115 memid
!= pFuncInfo
->funcdesc
.memid
; i
++, pFuncInfo
=pFuncInfo
->next
);
3121 result
=E_INVALIDARG
;
3123 TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This
,
3124 memid
, invKind
, SUCCEEDED(result
)? "SUCCES":"FAILED");
3128 /* TypeInfo2::GetVarIndexOfMemId
3130 * Binds to a specific member based on a known DISPID, where the member name
3131 * is not known (for example, when binding to a default member).
3134 static HRESULT WINAPI
ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo2
* iface
,
3135 MEMBERID memid
, UINT
*pVarIndex
)
3137 ICOM_THIS( ITypeInfoImpl
, iface
);
3138 TLBVarDesc
*pVarInfo
;
3141 for(i
=0, pVarInfo
=This
->varlist
; pVarInfo
&&
3142 memid
!= pVarInfo
->vardesc
.memid
; i
++, pVarInfo
=pVarInfo
->next
)
3149 result
=E_INVALIDARG
;
3151 TRACE("(%p) memid 0x%08lx -> %s\n", This
,
3152 memid
, SUCCEEDED(result
)? "SUCCES":"FAILED");
3156 /* ITypeInfo2::GetCustData
3158 * Gets the custom data
3160 static HRESULT WINAPI
ITypeInfo2_fnGetCustData(
3165 ICOM_THIS( ITypeInfoImpl
, iface
);
3166 TLBCustData
*pCData
;
3168 for(pCData
=This
->pCustData
; pCData
; pCData
= pCData
->next
)
3169 if( IsEqualIID(guid
, &pCData
->guid
)) break;
3171 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
3175 VariantInit( pVarVal
);
3176 VariantCopy( pVarVal
, &pCData
->data
);
3179 return E_INVALIDARG
; /* FIXME: correct? */
3182 /* ITypeInfo2::GetFuncCustData
3184 * Gets the custom data
3186 static HRESULT WINAPI
ITypeInfo2_fnGetFuncCustData(
3192 ICOM_THIS( ITypeInfoImpl
, iface
);
3193 TLBCustData
*pCData
=NULL
;
3194 TLBFuncDesc
* pFDesc
;
3196 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++,
3197 pFDesc
=pFDesc
->next
);
3200 for(pCData
=pFDesc
->pCustData
; pCData
; pCData
= pCData
->next
)
3201 if( IsEqualIID(guid
, &pCData
->guid
)) break;
3203 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
3206 VariantInit( pVarVal
);
3207 VariantCopy( pVarVal
, &pCData
->data
);
3210 return E_INVALIDARG
; /* FIXME: correct? */
3213 /* ITypeInfo2::GetParamCustData
3215 * Gets the custom data
3217 static HRESULT WINAPI
ITypeInfo2_fnGetParamCustData(
3224 ICOM_THIS( ITypeInfoImpl
, iface
);
3225 TLBCustData
*pCData
=NULL
;
3226 TLBFuncDesc
* pFDesc
;
3229 for(i
=0, pFDesc
=This
->funclist
; i
!=indexFunc
&& pFDesc
; i
++,pFDesc
=pFDesc
->next
);
3231 if(pFDesc
&& indexParam
>=0 && indexParam
<pFDesc
->funcdesc
.cParams
)
3232 for(pCData
=pFDesc
->pParamDesc
[indexParam
].pCustData
; pCData
;
3233 pCData
= pCData
->next
)
3234 if( IsEqualIID(guid
, &pCData
->guid
)) break;
3236 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
3240 VariantInit( pVarVal
);
3241 VariantCopy( pVarVal
, &pCData
->data
);
3244 return E_INVALIDARG
; /* FIXME: correct? */
3247 /* ITypeInfo2::GetVarcCustData
3249 * Gets the custom data
3251 static HRESULT WINAPI
ITypeInfo2_fnGetVarCustData(
3257 ICOM_THIS( ITypeInfoImpl
, iface
);
3258 TLBCustData
*pCData
=NULL
;
3259 TLBVarDesc
* pVDesc
;
3262 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++, pVDesc
=pVDesc
->next
);
3266 for(pCData
=pVDesc
->pCustData
; pCData
; pCData
= pCData
->next
)
3268 if( IsEqualIID(guid
, &pCData
->guid
)) break;
3272 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
3276 VariantInit( pVarVal
);
3277 VariantCopy( pVarVal
, &pCData
->data
);
3280 return E_INVALIDARG
; /* FIXME: correct? */
3283 /* ITypeInfo2::GetImplcCustData
3285 * Gets the custom data
3287 static HRESULT WINAPI
ITypeInfo2_fnGetImplTypeCustData(
3293 ICOM_THIS( ITypeInfoImpl
, iface
);
3294 TLBCustData
*pCData
=NULL
;
3295 TLBRefType
* pRDesc
;
3298 for(i
=0, pRDesc
=This
->impltypelist
; i
!=index
&& pRDesc
; i
++, pRDesc
=pRDesc
->next
);
3302 for(pCData
=pRDesc
->pCustData
; pCData
; pCData
= pCData
->next
)
3304 if( IsEqualIID(guid
, &pCData
->guid
)) break;
3308 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
3312 VariantInit( pVarVal
);
3313 VariantCopy( pVarVal
, &pCData
->data
);
3316 return E_INVALIDARG
; /* FIXME: correct? */
3319 /* ITypeInfo2::GetDocumentation2
3321 * Retrieves the documentation string, the complete Help file name and path,
3322 * the localization context to use, and the context ID for the library Help
3323 * topic in the Help file.
3326 static HRESULT WINAPI
ITypeInfo2_fnGetDocumentation2(
3330 BSTR
*pbstrHelpString
,
3331 DWORD
*pdwHelpStringContext
,
3332 BSTR
*pbstrHelpStringDll
)
3334 ICOM_THIS( ITypeInfoImpl
, iface
);
3335 TLBFuncDesc
* pFDesc
;
3336 TLBVarDesc
* pVDesc
;
3337 TRACE("(%p) memid %ld lcid(0x%lx) HelpString(%p) "
3338 "HelpStringContext(%p) HelpStringDll(%p)\n",
3339 This
, memid
, lcid
, pbstrHelpString
, pdwHelpStringContext
,
3340 pbstrHelpStringDll
);
3341 /* the help string should be obtained from the helpstringdll,
3342 * using the _DLLGetDocumentation function, based on the supplied
3343 * lcid. Nice to do sometime...
3345 if(memid
==MEMBERID_NIL
){ /* documentation for the typeinfo */
3347 *pbstrHelpString
=SysAllocString(This
->Name
);
3348 if(pdwHelpStringContext
)
3349 *pdwHelpStringContext
=This
->dwHelpStringContext
;
3350 if(pbstrHelpStringDll
)
3351 *pbstrHelpStringDll
=
3352 SysAllocString(This
->pTypeLib
->HelpStringDll
);/* FIXME */
3354 }else {/* for a member */
3355 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
)
3356 if(pFDesc
->funcdesc
.memid
==memid
){
3358 *pbstrHelpString
=SysAllocString(pFDesc
->HelpString
);
3359 if(pdwHelpStringContext
)
3360 *pdwHelpStringContext
=pFDesc
->HelpStringContext
;
3361 if(pbstrHelpStringDll
)
3362 *pbstrHelpStringDll
=
3363 SysAllocString(This
->pTypeLib
->HelpStringDll
);/* FIXME */
3366 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
)
3367 if(pVDesc
->vardesc
.memid
==memid
){
3369 *pbstrHelpString
=SysAllocString(pVDesc
->HelpString
);
3370 if(pdwHelpStringContext
)
3371 *pdwHelpStringContext
=pVDesc
->HelpStringContext
;
3372 if(pbstrHelpStringDll
)
3373 *pbstrHelpStringDll
=
3374 SysAllocString(This
->pTypeLib
->HelpStringDll
);/* FIXME */
3378 return TYPE_E_ELEMENTNOTFOUND
;
3381 /* ITypeInfo2::GetAllCustData
3383 * Gets all custom data items for the Type info.
3386 static HRESULT WINAPI
ITypeInfo2_fnGetAllCustData(
3388 CUSTDATA
*pCustData
)
3390 ICOM_THIS( ITypeInfoImpl
, iface
);
3391 TLBCustData
*pCData
;
3394 TRACE("(%p) returning %d items\n", This
, This
->ctCustData
);
3396 pCustData
->prgCustData
= TLB_Alloc(This
->ctCustData
* sizeof(CUSTDATAITEM
));
3397 if(pCustData
->prgCustData
){
3398 pCustData
->cCustData
=This
->ctCustData
;
3399 for(i
=0, pCData
=This
->pCustData
; pCData
; i
++, pCData
= pCData
->next
){
3400 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
3401 VariantCopy(& pCustData
->prgCustData
[i
].varValue
, & pCData
->data
);
3404 ERR(" OUT OF MEMORY! \n");
3405 return E_OUTOFMEMORY
;
3410 /* ITypeInfo2::GetAllFuncCustData
3412 * Gets all custom data items for the specified Function
3415 static HRESULT WINAPI
ITypeInfo2_fnGetAllFuncCustData(
3418 CUSTDATA
*pCustData
)
3420 ICOM_THIS( ITypeInfoImpl
, iface
);
3421 TLBCustData
*pCData
;
3422 TLBFuncDesc
* pFDesc
;
3424 TRACE("(%p) index %d\n", This
, index
);
3425 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++,
3426 pFDesc
=pFDesc
->next
)
3429 pCustData
->prgCustData
=
3430 TLB_Alloc(pFDesc
->ctCustData
* sizeof(CUSTDATAITEM
));
3431 if(pCustData
->prgCustData
){
3432 pCustData
->cCustData
=pFDesc
->ctCustData
;
3433 for(i
=0, pCData
=pFDesc
->pCustData
; pCData
; i
++,
3434 pCData
= pCData
->next
){
3435 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
3436 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
3440 ERR(" OUT OF MEMORY! \n");
3441 return E_OUTOFMEMORY
;
3445 return TYPE_E_ELEMENTNOTFOUND
;
3448 /* ITypeInfo2::GetAllParamCustData
3450 * Gets all custom data items for the Functions
3453 static HRESULT WINAPI
ITypeInfo2_fnGetAllParamCustData( ITypeInfo2
* iface
,
3454 UINT indexFunc
, UINT indexParam
, CUSTDATA
*pCustData
)
3456 ICOM_THIS( ITypeInfoImpl
, iface
);
3457 TLBCustData
*pCData
=NULL
;
3458 TLBFuncDesc
* pFDesc
;
3460 TRACE("(%p) index %d\n", This
, indexFunc
);
3461 for(i
=0, pFDesc
=This
->funclist
; i
!=indexFunc
&& pFDesc
; i
++,
3462 pFDesc
=pFDesc
->next
)
3464 if(pFDesc
&& indexParam
>=0 && indexParam
<pFDesc
->funcdesc
.cParams
){
3465 pCustData
->prgCustData
=
3466 TLB_Alloc(pFDesc
->pParamDesc
[indexParam
].ctCustData
*
3467 sizeof(CUSTDATAITEM
));
3468 if(pCustData
->prgCustData
){
3469 pCustData
->cCustData
=pFDesc
->pParamDesc
[indexParam
].ctCustData
;
3470 for(i
=0, pCData
=pFDesc
->pParamDesc
[indexParam
].pCustData
;
3471 pCData
; i
++, pCData
= pCData
->next
){
3472 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
3473 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
3477 ERR(" OUT OF MEMORY! \n");
3478 return E_OUTOFMEMORY
;
3482 return TYPE_E_ELEMENTNOTFOUND
;
3485 /* ITypeInfo2::GetAllVarCustData
3487 * Gets all custom data items for the specified Variable
3490 static HRESULT WINAPI
ITypeInfo2_fnGetAllVarCustData( ITypeInfo2
* iface
,
3491 UINT index
, CUSTDATA
*pCustData
)
3493 ICOM_THIS( ITypeInfoImpl
, iface
);
3494 TLBCustData
*pCData
;
3495 TLBVarDesc
* pVDesc
;
3497 TRACE("(%p) index %d\n", This
, index
);
3498 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++,
3499 pVDesc
=pVDesc
->next
)
3502 pCustData
->prgCustData
=
3503 TLB_Alloc(pVDesc
->ctCustData
* sizeof(CUSTDATAITEM
));
3504 if(pCustData
->prgCustData
){
3505 pCustData
->cCustData
=pVDesc
->ctCustData
;
3506 for(i
=0, pCData
=pVDesc
->pCustData
; pCData
; i
++,
3507 pCData
= pCData
->next
){
3508 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
3509 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
3513 ERR(" OUT OF MEMORY! \n");
3514 return E_OUTOFMEMORY
;
3518 return TYPE_E_ELEMENTNOTFOUND
;
3521 /* ITypeInfo2::GetAllImplCustData
3523 * Gets all custom data items for the specified implementation type
3526 static HRESULT WINAPI
ITypeInfo2_fnGetAllImplTypeCustData(
3529 CUSTDATA
*pCustData
)
3531 ICOM_THIS( ITypeInfoImpl
, iface
);
3532 TLBCustData
*pCData
;
3533 TLBRefType
* pRDesc
;
3535 TRACE("(%p) index %d\n", This
, index
);
3536 for(i
=0, pRDesc
=This
->impltypelist
; i
!=index
&& pRDesc
; i
++,
3537 pRDesc
=pRDesc
->next
)
3540 pCustData
->prgCustData
=
3541 TLB_Alloc(pRDesc
->ctCustData
* sizeof(CUSTDATAITEM
));
3542 if(pCustData
->prgCustData
){
3543 pCustData
->cCustData
=pRDesc
->ctCustData
;
3544 for(i
=0, pCData
=pRDesc
->pCustData
; pCData
; i
++,
3545 pCData
= pCData
->next
){
3546 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
3547 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
3551 ERR(" OUT OF MEMORY! \n");
3552 return E_OUTOFMEMORY
;
3556 return TYPE_E_ELEMENTNOTFOUND
;
3559 static ICOM_VTABLE(ITypeInfo2
) tinfvt
=
3561 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3563 ITypeInfo_fnQueryInterface
,
3565 ITypeInfo_fnRelease
,
3567 ITypeInfo_fnGetTypeAttr
,
3568 ITypeInfo_fnGetTypeComp
,
3569 ITypeInfo_fnGetFuncDesc
,
3570 ITypeInfo_fnGetVarDesc
,
3571 ITypeInfo_fnGetNames
,
3572 ITypeInfo_fnGetRefTypeOfImplType
,
3573 ITypeInfo_fnGetImplTypeFlags
,
3574 ITypeInfo_fnGetIDsOfNames
,
3576 ITypeInfo_fnGetDocumentation
,
3577 ITypeInfo_fnGetDllEntry
,
3578 ITypeInfo_fnGetRefTypeInfo
,
3579 ITypeInfo_fnAddressOfMember
,
3580 ITypeInfo_fnCreateInstance
,
3581 ITypeInfo_fnGetMops
,
3582 ITypeInfo_fnGetContainingTypeLib
,
3583 ITypeInfo_fnReleaseTypeAttr
,
3584 ITypeInfo_fnReleaseFuncDesc
,
3585 ITypeInfo_fnReleaseVarDesc
,
3587 ITypeInfo2_fnGetTypeKind
,
3588 ITypeInfo2_fnGetTypeFlags
,
3589 ITypeInfo2_fnGetFuncIndexOfMemId
,
3590 ITypeInfo2_fnGetVarIndexOfMemId
,
3591 ITypeInfo2_fnGetCustData
,
3592 ITypeInfo2_fnGetFuncCustData
,
3593 ITypeInfo2_fnGetParamCustData
,
3594 ITypeInfo2_fnGetVarCustData
,
3595 ITypeInfo2_fnGetImplTypeCustData
,
3596 ITypeInfo2_fnGetDocumentation2
,
3597 ITypeInfo2_fnGetAllCustData
,
3598 ITypeInfo2_fnGetAllFuncCustData
,
3599 ITypeInfo2_fnGetAllParamCustData
,
3600 ITypeInfo2_fnGetAllVarCustData
,
3601 ITypeInfo2_fnGetAllImplTypeCustData
,