4 * Copyright 1997 Marcus Meissner
6 * there is much left to do here before it can be useful for real world
9 * -. Only one format of typelibs is supported
10 * -. All testing so far is done using special written windows programs
11 * -. Data structures are straightforward, but slow for look-ups.
12 * -. (related) nothing is hashed
13 * -. a typelib is always read in its entirety into memory and never released.
14 * -. there are a number of stubs in ITypeLib and ITypeInfo interfaces. Most
15 * of them I don't know yet how to implement them.
16 * -. Most error return values are just guessed not checked with windows
18 * -. all locale stuff ignored
19 * -. move stuff to wine/dlls
20 * -. didn't bother with a c++ interface
21 * -. lousy fatal error handling
22 * -. some methods just return pointers to internal data structures, this is
23 * partly laziness, partly I want to check how windows does it.
32 #include "winreg.h" /* for HKEY_LOCAL_MACHINE */
33 #include "winnls.h" /* for PRIMARYLANGID */
34 #include "wine/winbase16.h" /* for RegQueryValue16(HKEY,LPSTR,LPSTR,LPDWORD) */
36 #include "wine/obj_base.h"
37 #include "debugtools.h"
38 #include "winversion.h"
41 DEFAULT_DEBUG_CHANNEL(ole
);
42 DECLARE_DEBUG_CHANNEL(typelib
);
44 /****************************************************************************
45 * QueryPathOfRegTypeLib16 [TYPELIB.14]
47 * the path is "Classes\Typelib\<guid>\<major>.<minor>\<lcid>\win16\"
52 QueryPathOfRegTypeLib16(
53 REFGUID guid
, /* [in] referenced guid */
54 WORD wMaj
, /* [in] major version */
55 WORD wMin
, /* [in] minor version */
56 LCID lcid
, /* [in] locale id */
57 LPBSTR16 path
/* [out] path of typelib */
60 char typelibkey
[100],pathname
[260];
66 sprintf( typelibkey
, "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win16",
67 guid
->Data1
, guid
->Data2
, guid
->Data3
,
68 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
69 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7],
72 sprintf(xguid
,"<guid 0x%08lx>",(DWORD
)guid
);
73 FIXME("(%s,%d,%d,0x%04lx,%p),can't handle non-string guids.\n",xguid
,wMaj
,wMin
,(DWORD
)lcid
,path
);
76 plen
= sizeof(pathname
);
77 if (RegQueryValue16(HKEY_LOCAL_MACHINE
,typelibkey
,pathname
,&plen
)) {
78 /* try again without lang specific id */
80 return QueryPathOfRegTypeLib16(guid
,wMaj
,wMin
,PRIMARYLANGID(lcid
),path
);
81 FIXME("key %s not found\n",typelibkey
);
84 *path
= SysAllocString16(pathname
);
88 /****************************************************************************
89 * QueryPathOfRegTypeLib [OLEAUT32.164]
94 QueryPathOfRegTypeLib(
95 REFGUID guid
, /* [in] referenced guid */
96 WORD wMaj
, /* [in] major version */
97 WORD wMin
, /* [in] minor version */
98 LCID lcid
, /* [in] locale id */
99 LPBSTR path
/* [out] path of typelib */
102 char typelibkey
[100],pathname
[260];
108 sprintf( typelibkey
, "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win32",
109 guid
->Data1
, guid
->Data2
, guid
->Data3
,
110 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
111 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7],
114 sprintf(xguid
,"<guid 0x%08lx>",(DWORD
)guid
);
115 FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n",xguid
,wMaj
,wMin
,(DWORD
)lcid
,path
);
118 plen
= sizeof(pathname
);
119 if (RegQueryValue16(HKEY_LOCAL_MACHINE
,typelibkey
,pathname
,&plen
)) {
120 /* try again without lang specific id */
122 return QueryPathOfRegTypeLib(guid
,wMaj
,wMin
,PRIMARYLANGID(lcid
),path
);
123 FIXME("key %s not found\n",typelibkey
);
126 *path
= HEAP_strdupAtoW(GetProcessHeap(),0,pathname
);
130 /******************************************************************************
131 * LoadTypeLib [TYPELIB.3] Loads and registers a type library
133 * Docs: OLECHAR FAR* szFile
134 * Docs: iTypeLib FAR* FAR* pptLib
140 HRESULT WINAPI
LoadTypeLib16(
141 LPOLESTR szFile
, /* [in] Name of file to load from */
142 void * *pptLib
) /* [out] Pointer to pointer to loaded type library */
144 FIXME("('%s',%p): stub\n",debugstr_w((LPWSTR
)szFile
),pptLib
);
152 /******************************************************************************
153 * LoadTypeLib [OLEAUT32.161]
154 * Loads and registers a type library
156 * Docs: OLECHAR FAR* szFile
157 * Docs: iTypeLib FAR* FAR* pptLib
163 int TLB_ReadTypeLib(PCHAR file
, ITypeLib2
**ppTypelib
);
165 HRESULT WINAPI
LoadTypeLib(
166 OLECHAR
*szFile
, /* [in] Name of file to load from */
167 ITypeLib
* *pptLib
) /* [out] Pointer to pointer to loaded type library */
170 return LoadTypeLibEx(szFile
, REGKIND_DEFAULT
, pptLib
);
173 /******************************************************************************
174 * LoadTypeLibEx [OLEAUT32.183]
175 * Loads and optionally registers a type library
181 HRESULT WINAPI
LoadTypeLibEx(
182 LPOLESTR szFile
, /* [in] Name of file to load from */
183 REGKIND regkind
, /* specify kind of registration */
184 ITypeLib
**pptLib
) /* [out] Pointer to pointer to loaded type library */
188 TRACE("(%s,%d,%p)\n",debugstr_w(szFile
), regkind
, pptLib
);
190 p
=HEAP_strdupWtoA(GetProcessHeap(),0,szFile
);
192 if(regkind
!= REGKIND_NONE
)
193 FIXME ("registration of typelibs not supported yet!\n");
195 res
= TLB_ReadTypeLib(p
, (ITypeLib2
**)pptLib
);
196 HeapFree(GetProcessHeap(),0,p
);
197 TRACE(" returns %08lx\n",res
);
202 /******************************************************************************
203 * LoadRegTypeLib [OLEAUT32.162]
205 HRESULT WINAPI
LoadRegTypeLib(
206 REFGUID rguid
, /* [in] referenced guid */
207 WORD wVerMajor
, /* [in] major version */
208 WORD wVerMinor
, /* [in] minor version */
209 LCID lcid
, /* [in] locale id */
210 ITypeLib
**ppTLib
) /* [out] path of typelib */
213 HRESULT res
=QueryPathOfRegTypeLib( rguid
, wVerMajor
, wVerMinor
, lcid
, &bstr
);
217 res
= LoadTypeLib(bstr
, ppTLib
);
221 TRACE("(IID: %s) load %s (%p)\n",debugstr_guid(rguid
), SUCCEEDED(res
)? "SUCCESS":"FAILED", *ppTLib
);
227 /******************************************************************************
228 * RegisterTypeLib [OLEAUT32.163]
229 * Adds information about a type library to the System Registry
231 * Docs: ITypeLib FAR * ptlib
232 * Docs: OLECHAR FAR* szFullPath
233 * Docs: OLECHAR FAR* szHelpDir
239 HRESULT WINAPI
RegisterTypeLib(
240 ITypeLib
* ptlib
, /*[in] Pointer to the library*/
241 OLECHAR
* szFullPath
, /*[in] full Path of the library*/
242 OLECHAR
* szHelpDir
) /*[in] dir to the helpfile for the library,
244 { FIXME("(%p,%s,%s): stub\n",ptlib
, debugstr_w(szFullPath
),debugstr_w(szHelpDir
));
245 return S_OK
; /* FIXME: pretend everything is OK */
249 /******************************************************************************
250 * UnRegisterTypeLib [OLEAUT32.186]
251 * Removes information about a type library from the System Registry
258 HRESULT WINAPI
UnRegisterTypeLib(
259 REFGUID libid
, /* [in] Guid of the library */
260 WORD wVerMajor
, /* [in] major version */
261 WORD wVerMinor
, /* [in] minor version */
262 LCID lcid
, /* [in] locale id */
265 TRACE("(IID: %s): stub\n",debugstr_guid(libid
));
266 return S_OK
; /* FIXME: pretend everything is OK */
269 /****************************************************************************
270 * OaBuildVersion (TYPELIB.15)
272 * known TYPELIB.DLL versions:
274 * OLE 2.01 no OaBuildVersion() avail 1993 -- ---
275 * OLE 2.02 1993-94 02 3002
278 * OLE 2.03 W98 SE orig. file !! 1993-95 10 3024
279 * OLE 2.1 NT 1993-95 ?? ???
280 * OLE 2.3.1 W95 23 700
282 DWORD WINAPI
OaBuildVersion16(void)
284 FIXME("Please report to a.mohr@mailto.de if you get version error messages !\n");
285 switch(VERSION_GetVersion())
288 return MAKELONG(3027, 3); /* WfW 3.11 */
290 return MAKELONG(700, 23); /* Win95A */
292 return MAKELONG(3024, 10); /* W98 SE */
294 FIXME_(ole
)("Version value not known yet. Please investigate it !");
299 /********************************************************************
300 * LHashValOfNameSysA [OLEAUT32]
302 HRESULT WINAPI
LHashValOfNameSysA(SYSKIND sys
, LCID lcid
, LPSTR name
)
308 /* for better debugging info leave the static out for the time being */
311 /*======================= ITypeLib implementation =======================*/
313 typedef struct tagTLBCustData
317 struct tagTLBCustData
* next
;
320 /* data structure for import typelibs */
321 typedef struct tagTLBImpLib
323 int offset
; /* offset in the file */
324 GUID guid
; /* libid */
325 PCHAR name
; /* name; */
326 struct tagITypeLibImpl
*pImpTypeLib
; /* pointer to loaded typelib */
327 struct tagTLBImpLib
* next
;
330 /* internal ITypeLib data */
331 typedef struct tagITypeLibImpl
333 ICOM_VFIELD(ITypeLib2
);
335 TLIBATTR LibAttr
; /* guid,lcid,syskind,version,flags */
336 /* type libs seem to store the doc strings in ascii
337 * so why should we do it in unicode?
343 unsigned long dwHelpContext
;
344 int TypeInfoCount
; /* nr of typeinfo's in librarry */
345 struct tagITypeInfoImpl
*pTypeInfo
; /* linked list of type info data */
346 int ctCustData
; /* number of items in cust data list */
347 TLBCustData
* pCustData
; /* linked list to cust data; */
348 TLBImpLib
* pImpLibs
; /* linked list to all imported typelibs */
349 TYPEDESC
* pTypeDesc
; /* array of TypeDescriptions found in the libary */
352 static struct ICOM_VTABLE(ITypeLib2
) tlbvt
;
354 /* ITypeLib methods */
355 static ITypeLib2
* ITypeLib2_Constructor(LPVOID pLib
);
357 /*======================= ITypeInfo implementation =======================*/
359 /* internal Parameter data */
360 typedef struct tagTLBParDesc
364 TLBCustData
* pCustData
; /* linked list to cust data; */
367 /* internal Function data */
368 typedef struct tagTLBFuncDesc
370 FUNCDESC funcdesc
; /* lots of info on the function and its attributes. */
371 PCHAR Name
; /* the name of this function */
372 TLBParDesc
*pParamDesc
; /* array with name and custom data */
374 int HelpStringContext
;
376 PCHAR Entry
; /* if its Hiword==0, it numeric; -1 is not present*/
378 TLBCustData
* pCustData
; /* linked list to cust data; */
379 struct tagTLBFuncDesc
* next
;
382 /* internal Variable data */
383 typedef struct tagTLBVarDesc
385 VARDESC vardesc
; /* lots of info on the variable and its attributes. */
386 PCHAR Name
; /* the name of this variable */
388 int HelpStringContext
; /* fixme: where? */
391 TLBCustData
* pCustData
;/* linked list to cust data; */
392 struct tagTLBVarDesc
* next
;
395 /* data for refernced types in a coclass, or an inherited interface */
396 typedef struct tagTLBRefType
398 GUID guid
; /* guid of the referenced type */
399 /* (important if its a imported type) */
403 TLBCustData
* pCustData
;/* linked list to custom data; */
404 TLBImpLib
*pImpTLInfo
;
405 struct tagTLBRefType
* next
;
408 /* internal TypeInfo data */
409 typedef struct tagITypeInfoImpl
411 ICOM_VFIELD(ITypeInfo2
);
413 TYPEATTR TypeAttr
; /* _lots_ of type information. */
414 ITypeLibImpl
* pTypeLib
; /* back pointer to typelib */
415 int index
; /* index in this typelib; */
416 /* type libs seem to store the doc strings in ascii
417 * so why should we do it in unicode?
421 unsigned long dwHelpContext
;
422 unsigned long dwHelpStringContext
;
425 TLBFuncDesc
* funclist
; /* linked list with function descriptions */
428 TLBVarDesc
* varlist
; /* linked list with variable descriptions */
430 /* Implemented Interfaces */
431 TLBRefType
* impltypelist
;
433 TLBCustData
* pCustData
; /* linked list to cust data; */
434 struct tagITypeInfoImpl
* next
;
437 static struct ICOM_VTABLE(ITypeInfo2
) tinfvt
;
439 static ITypeInfo2
* WINAPI
ITypeInfo_Constructor();
441 typedef struct tagTLBContext
443 unsigned int oStart
; /* start of TLB in file */
444 unsigned int pos
; /* current pos */
445 unsigned int length
; /* total length */
446 void *mapping
; /* memory mapping */
448 ITypeLibImpl
* pLibInfo
;
454 static void dump_TLBFuncDesc(TLBFuncDesc
* pfd
)
458 TRACE("%s(%u)\n", pfd
->Name
, pfd
->funcdesc
.cParams
);
462 static void dump_TLBVarDesc(TLBVarDesc
* pvd
)
466 TRACE("%s\n", pvd
->Name
);
470 static void dump_TLBRefType(TLBRefType
* prt
)
474 TRACE("%s\n", debugstr_guid(&(prt
->guid
)));
475 TRACE(" href:0x%08lx\n", prt
->reference
);
480 static void dump_Variant(VARIANT
* pvar
)
482 TRACE("%p %x\n", pvar
, pvar
?pvar
->vt
:0 );
485 if (pvar
->vt
& VT_BYREF
)
486 return dump_Variant(pvar
->u
.pvarVal
);
489 static void dump_DispParms(DISPPARAMS
* pdp
)
491 dump_Variant( pdp
->rgvarg
);
492 TRACE("args=%u named args=%u\n", pdp
->cArgs
, pdp
->cNamedArgs
);
495 static char * typekind_desc
[] =
508 static void dump_TypeInfo(ITypeInfoImpl
* pty
)
510 TRACE("%p ref=%u\n", pty
, pty
->ref
);
511 TRACE("attr:%s\n", debugstr_guid(&(pty
->TypeAttr
.guid
)));
512 TRACE("kind:%s\n", typekind_desc
[pty
->TypeAttr
.typekind
]);
513 TRACE("fct:%u var:%u impl:%u\n",
514 pty
->TypeAttr
.cFuncs
, pty
->TypeAttr
.cVars
, pty
->TypeAttr
.cImplTypes
);
515 TRACE("parent tlb:%p index in TLB:%u\n",pty
->pTypeLib
, pty
->index
);
516 TRACE("%s %s\n", pty
->Name
, pty
->DocString
);
517 dump_TLBFuncDesc(pty
->funclist
);
518 dump_TLBVarDesc(pty
->varlist
);
519 dump_TLBRefType(pty
->impltypelist
);
522 static TYPEDESC stndTypeDesc
[VT_LPWSTR
+1]=
524 /* VT_LPWSTR is largest type that */
525 /* may appear in type description*/
526 {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
527 {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
528 {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
529 {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
530 {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
531 {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
535 static void TLB_abort()
539 static void * TLB_Alloc(unsigned size
)
542 if((ret
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,size
))==NULL
){
544 ERR("cannot allocate memory\n");
549 /* candidate for a more global appearance... */
550 static BSTR
TLB_DupAtoBstr(PCHAR Astr
)
558 pdw
=TLB_Alloc((len
+3)*sizeof(OLECHAR
));
559 pdw
[0]=(len
)*sizeof(OLECHAR
);
560 bstr
=(BSTR
)&( pdw
[1]);
561 lstrcpyAtoW( bstr
, Astr
);
562 TRACE("copying %s to (%p)\n", Astr
, bstr
);
566 static void TLB_Free(void * ptr
)
568 HeapFree(GetProcessHeap(), 0, ptr
);
571 DWORD
TLB_Read(void *buffer
, DWORD count
, TLBContext
*pcx
, long where
)
573 TRACE("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n",
574 pcx
->pos
, count
, pcx
->oStart
, pcx
->length
, where
);
576 if (where
!= DO_NOT_SEEK
)
578 where
+= pcx
->oStart
;
579 if (where
> pcx
->length
)
582 ERR("seek beyond end (%ld/%d)\n", where
, pcx
->length
);
587 if (pcx
->pos
+ count
> pcx
->length
) count
= pcx
->length
- pcx
->pos
;
588 memcpy( buffer
, (char *)pcx
->mapping
+ pcx
->pos
, count
);
593 static void TLB_ReadGuid( GUID
*pGuid
, int offset
, TLBContext
*pcx
)
595 TRACE("%s\n", debugstr_guid(pGuid
));
597 if(offset
<0 || pcx
->pTblDir
->pGuidTab
.offset
<0){
598 memset(pGuid
,0, sizeof(GUID
));
601 TLB_Read(pGuid
, sizeof(GUID
), pcx
, pcx
->pTblDir
->pGuidTab
.offset
+offset
);
604 PCHAR
TLB_ReadName( TLBContext
*pcx
, int offset
)
609 TLB_Read(&niName
, sizeof(niName
), pcx
,
610 pcx
->pTblDir
->pNametab
.offset
+offset
);
611 niName
.namelen
&= 0xFF; /* FIXME: correct ? */
612 name
=TLB_Alloc((niName
.namelen
& 0xff) +1);
613 TLB_Read(name
, (niName
.namelen
& 0xff), pcx
, DO_NOT_SEEK
);
614 name
[niName
.namelen
& 0xff]='\0';
615 TRACE("%s\n", debugstr_a(name
));
618 PCHAR
TLB_ReadString( TLBContext
*pcx
, int offset
)
623 if(offset
<0) return NULL
;
624 TLB_Read(&length
, sizeof(INT16
), pcx
, pcx
->pTblDir
->pStringtab
.offset
+offset
);
625 if(length
<= 0) return 0;
626 string
=TLB_Alloc(length
+1);
627 TLB_Read(string
, length
, pcx
, DO_NOT_SEEK
);
629 TRACE("%s\n", debugstr_a(string
));
633 * read a value and fill a VARIANT structure
635 static void TLB_ReadValue( VARIANT
* pVar
, int offset
, TLBContext
*pcx
)
641 if(offset
<0) { /* data is packed in here */
642 pVar
->vt
= (offset
& 0x7c000000 )>> 26;
643 V_UNION(pVar
, iVal
) = offset
& 0xffff;
646 TLB_Read(&(pVar
->vt
), sizeof(VARTYPE
), pcx
,
647 pcx
->pTblDir
->pCustData
.offset
+ offset
);
648 TRACE("Vartype = %x\n", pVar
->vt
);
650 case VT_EMPTY
: /* FIXME: is this right? */
651 case VT_NULL
: /* FIXME: is this right? */
652 case VT_I2
: /* this should not happen */
663 case VT_VOID
: /* FIXME: is this right? */
671 case VT_DECIMAL
: /* FIXME: is this right? */
674 /* pointer types with known behaviour */
677 TLB_Read(&size
, sizeof(INT
), pcx
, DO_NOT_SEEK
);
679 FIXME("BSTR length = %d?\n", size
);
681 ptr
=TLB_Alloc(size
);/* allocate temp buffer */
682 TLB_Read(ptr
, size
, pcx
, DO_NOT_SEEK
); /* read string (ANSI) */
683 V_UNION(pVar
, bstrVal
)=SysAllocStringLen(NULL
,size
);
684 /* FIXME: do we need a AtoW conversion here? */
685 V_UNION(pVar
, bstrVal
[size
])=L
'\0';
686 while(size
--) V_UNION(pVar
, bstrVal
[size
])=ptr
[size
];
691 /* FIXME: this will not work AT ALL when the variant contains a pointer */
698 case VT_USERDEFINED
:
704 case VT_STREAMED_OBJECT
:
705 case VT_STORED_OBJECT
:
706 case VT_BLOB_OBJECT
:
711 FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
715 if(size
>0) /* (big|small) endian correct? */
716 TLB_Read(&(V_UNION(pVar
, iVal
)), size
, pcx
, DO_NOT_SEEK
);
720 * create a linked list with custom data
722 static int TLB_CustData( TLBContext
*pcx
, int offset
, TLBCustData
** ppCustData
)
732 pNew
=TLB_Alloc(sizeof(TLBCustData
));
733 TLB_Read(&entry
, sizeof(entry
), pcx
,
734 pcx
->pTblDir
->pCDGuids
.offset
+offset
);
735 TLB_ReadGuid(&(pNew
->guid
), entry
.GuidOffset
, pcx
);
736 TLB_ReadValue(&(pNew
->data
), entry
.DataOffset
, pcx
);
737 /* add new custom data at head of the list */
738 pNew
->next
=*ppCustData
;
745 static void TLB_GetTdesc(TLBContext
*pcx
, INT type
,TYPEDESC
* pTd
)
750 pTd
->vt
=type
& VT_TYPEMASK
;
752 *pTd
=pcx
->pLibInfo
->pTypeDesc
[type
/(2*sizeof(INT
))];
754 static void TLB_DoFuncs(TLBContext
*pcx
, int cFuncs
, int cVars
,
755 int offset
, TLBFuncDesc
** pptfd
)
758 * member information is stored in a data structure at offset
759 * indicated by the memoffset field of the typeinfo structure
760 * There are several distinctive parts.
761 * the first part starts with a field that holds the total length
762 * of this (first) part excluding this field. Then follow the records,
763 * for each member there is one record.
765 * First entry is always the length of the record (excluding this
767 * Rest of the record depends on the type of the member. If there is
768 * a field indicating the member type (function variable intereface etc)
769 * I have not found it yet. At this time we depend on the information
770 * in the type info and the usual order how things are stored.
772 * Second follows an array sized nrMEM*sizeof(INT) with a memeber id
775 * Third is a equal sized array with file offsets to the name entry
778 * Forth and last (?) part is an array with offsets to the records in the
779 * first part of this file segment.
782 int infolen
, nameoffset
, reclength
, nrattributes
;
784 TLBFuncRecord
* pFuncRec
=(TLBFuncRecord
*) recbuf
;
786 int recoffset
=offset
+sizeof(INT
);
790 TLB_Read(&infolen
,sizeof(INT
), pcx
, offset
);
791 for(i
=0;i
<cFuncs
;i
++){
792 *pptfd
=TLB_Alloc(sizeof(TLBFuncDesc
));
793 /* name, eventually add to a hash table */
794 TLB_Read(&nameoffset
, sizeof(INT
), pcx
,
795 offset
+ infolen
+ (cFuncs
+ cVars
+ i
+ 1) * sizeof(INT
));
796 (*pptfd
)->Name
=TLB_ReadName(pcx
, nameoffset
);
797 /* read the function information record */
798 TLB_Read(&reclength
, sizeof(INT
), pcx
, recoffset
);
800 TLB_Read(pFuncRec
, reclength
- sizeof(INT
), pcx
, DO_NOT_SEEK
) ;
801 /* do the attributes */
802 nrattributes
=(reclength
-pFuncRec
->nrargs
*3*sizeof(int)-0x18)
805 (*pptfd
)->helpcontext
= pFuncRec
->OptAttr
[0] ;
807 (*pptfd
)->HelpString
= TLB_ReadString(pcx
,
808 pFuncRec
->OptAttr
[1]) ;
810 if(pFuncRec
->FKCCIC
& 0x2000)
811 (*pptfd
)->Entry
= (char *) pFuncRec
->OptAttr
[2] ;
813 (*pptfd
)->Entry
= TLB_ReadString(pcx
,
814 pFuncRec
->OptAttr
[2]);
816 (*pptfd
)->HelpStringContext
= pFuncRec
->OptAttr
[5] ;
817 if(nrattributes
>6 && pFuncRec
->FKCCIC
& 0x80){
818 TLB_CustData(pcx
, pFuncRec
->OptAttr
[6],
819 &(*pptfd
)->pCustData
);
824 /* fill the FuncDesc Structure */
825 TLB_Read(&(*pptfd
)->funcdesc
.memid
, sizeof(INT
), pcx
,
826 offset
+ infolen
+ ( i
+ 1) * sizeof(INT
));
827 (*pptfd
)->funcdesc
.funckind
= (pFuncRec
->FKCCIC
) & 0x7;
828 (*pptfd
)->funcdesc
.invkind
= ((pFuncRec
->FKCCIC
) >>3) & 0xF;
829 (*pptfd
)->funcdesc
.callconv
= (pFuncRec
->FKCCIC
) >>8 & 0xF;
830 (*pptfd
)->funcdesc
.cParams
= pFuncRec
->nrargs
;
831 (*pptfd
)->funcdesc
.cParamsOpt
= pFuncRec
->nroargs
;
832 (*pptfd
)->funcdesc
.oVft
= pFuncRec
->VtableOffset
;
833 (*pptfd
)->funcdesc
.wFuncFlags
= LOWORD(pFuncRec
->Flags
) ;
834 TLB_GetTdesc(pcx
, pFuncRec
->DataType
,
835 &(*pptfd
)->funcdesc
.elemdescFunc
.tdesc
) ;
837 /* do the parameters/arguments */
838 if(pFuncRec
->nrargs
){
839 TLBParameterInfo paraminfo
;
840 (*pptfd
)->funcdesc
.lprgelemdescParam
=
841 TLB_Alloc(pFuncRec
->nrargs
* sizeof(ELEMDESC
));
842 (*pptfd
)->pParamDesc
=TLB_Alloc(pFuncRec
->nrargs
*
845 TLB_Read(¶minfo
,sizeof(paraminfo
), pcx
, recoffset
+reclength
-
846 pFuncRec
->nrargs
* sizeof(TLBParameterInfo
));
847 for(j
=0;j
<pFuncRec
->nrargs
;j
++){
848 TLB_GetTdesc(pcx
, paraminfo
.DataType
,
849 &(*pptfd
)->funcdesc
.lprgelemdescParam
[j
].tdesc
) ;
850 V_UNION(&((*pptfd
)->funcdesc
.lprgelemdescParam
[j
]),
851 paramdesc
.wParamFlags
) = paraminfo
.Flags
;
852 (*pptfd
)->pParamDesc
[j
].Name
=(void *)paraminfo
.oName
;
853 TLB_Read(¶minfo
,sizeof(TLBParameterInfo
), pcx
,
856 /* second time around */
857 for(j
=0;j
<pFuncRec
->nrargs
;j
++){
859 (*pptfd
)->pParamDesc
[j
].Name
=
860 TLB_ReadName(pcx
, (int)(*pptfd
)->pParamDesc
[j
].Name
);
862 if((PARAMFLAG_FHASDEFAULT
& V_UNION(&((*pptfd
)->funcdesc
.
863 lprgelemdescParam
[j
]),paramdesc
.wParamFlags
)) &&
864 ((pFuncRec
->FKCCIC
) & 0x1000)){
865 INT
*pInt
=(INT
*)((char *)pFuncRec
+ reclength
-
866 (pFuncRec
->nrargs
* 4 + 1) * sizeof(INT
) );
867 PARAMDESC
* pParamDesc
= &V_UNION(&((*pptfd
)->funcdesc
.
868 lprgelemdescParam
[j
]),paramdesc
);
869 pParamDesc
->pparamdescex
= TLB_Alloc(sizeof(PARAMDESCEX
));
870 pParamDesc
->pparamdescex
->cBytes
= sizeof(PARAMDESCEX
);
871 TLB_ReadValue(&(pParamDesc
->pparamdescex
->varDefaultValue
),
875 if(nrattributes
>7+j
&& pFuncRec
->FKCCIC
& 0x80)
876 TLB_CustData(pcx
, pFuncRec
->OptAttr
[7+j
],
877 &(*pptfd
)->pParamDesc
[j
].pCustData
);
880 /* scode is not used: archaic win16 stuff FIXME: right? */
881 (*pptfd
)->funcdesc
.cScodes
= 0 ;
882 (*pptfd
)->funcdesc
.lprgscode
= NULL
;
883 pptfd
=&((*pptfd
)->next
);
884 recoffset
+= reclength
;
887 static void TLB_DoVars(TLBContext
*pcx
, int cFuncs
, int cVars
,
888 int offset
, TLBVarDesc
** pptvd
)
890 int infolen
, nameoffset
, reclength
;
892 TLBVarRecord
* pVarRec
=(TLBVarRecord
*) recbuf
;
898 TLB_Read(&infolen
,sizeof(INT
), pcx
, offset
);
899 TLB_Read(&recoffset
,sizeof(INT
), pcx
, offset
+ infolen
+
900 ((cFuncs
+cVars
)*2+cFuncs
+ 1)*sizeof(INT
));
901 recoffset
+= offset
+sizeof(INT
);
902 for(i
=0;i
<cVars
;i
++){
903 *pptvd
=TLB_Alloc(sizeof(TLBVarDesc
));
904 /* name, eventually add to a hash table */
905 TLB_Read(&nameoffset
, sizeof(INT
), pcx
,
906 offset
+ infolen
+ (cFuncs
+ cVars
+ i
+ 1) * sizeof(INT
));
907 (*pptvd
)->Name
=TLB_ReadName(pcx
, nameoffset
);
908 /* read the variable information record */
909 TLB_Read(&reclength
, sizeof(INT
), pcx
, recoffset
);
911 TLB_Read(pVarRec
, reclength
- sizeof(INT
), pcx
, DO_NOT_SEEK
) ;
913 if(reclength
>(6*sizeof(INT
)) )
914 (*pptvd
)->HelpContext
=pVarRec
->HelpContext
;
915 if(reclength
>(7*sizeof(INT
)) )
916 (*pptvd
)->HelpString
= TLB_ReadString(pcx
, pVarRec
->oHelpString
) ;
917 if(reclength
>(8*sizeof(INT
)) )
918 if(reclength
>(9*sizeof(INT
)) )
919 (*pptvd
)->HelpStringContext
=pVarRec
->HelpStringContext
;
920 /* fill the VarDesc Structure */
921 TLB_Read(&(*pptvd
)->vardesc
.memid
, sizeof(INT
), pcx
,
922 offset
+ infolen
+ ( i
+ 1) * sizeof(INT
));
923 (*pptvd
)->vardesc
.varkind
= pVarRec
->VarKind
;
924 (*pptvd
)->vardesc
.wVarFlags
= pVarRec
->Flags
;
925 TLB_GetTdesc(pcx
, pVarRec
->DataType
,
926 &(*pptvd
)->vardesc
.elemdescVar
.tdesc
) ;
927 /* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) fixme?? */
928 if(pVarRec
->VarKind
== VAR_CONST
){
929 V_UNION(&((*pptvd
)->vardesc
),lpvarValue
)=TLB_Alloc(sizeof(VARIANT
));
930 TLB_ReadValue(V_UNION(&((*pptvd
)->vardesc
),lpvarValue
),
931 pVarRec
->OffsValue
, pcx
);
933 V_UNION(&((*pptvd
)->vardesc
),oInst
)=pVarRec
->OffsValue
;
934 pptvd
=&((*pptvd
)->next
);
935 recoffset
+= reclength
;
938 /* fill in data for a hreftype (offset). When the refernced type is contained
939 * in the typelib, its just an (file) offset in the type info base dir.
940 * If comes from import, its an offset+1 in the ImpInfo table
942 static void TLB_DoRefType(TLBContext
*pcx
,
943 int offset
, TLBRefType
** pprtd
)
949 if(!HREFTYPE_INTHISFILE( offset
)) {
950 /* external typelib */
952 TLBImpLib
*pImpLib
=(pcx
->pLibInfo
->pImpLibs
);
953 TLB_Read(&impinfo
, sizeof(impinfo
), pcx
,
954 pcx
->pTblDir
->pImpInfo
.offset
+ (offset
& 0xfffffffc));
955 for(j
=0;pImpLib
;j
++){ /* search the known offsets of all import libraries */
956 if(pImpLib
->offset
==impinfo
.oImpFile
) break;
957 pImpLib
=pImpLib
->next
;
960 (*pprtd
)->reference
=offset
;
961 (*pprtd
)->pImpTLInfo
= pImpLib
;
962 TLB_ReadGuid(&(*pprtd
)->guid
, impinfo
.oGuid
, pcx
);
964 ERR("Cannot find a reference\n");
965 (*pprtd
)->reference
=-1;
966 (*pprtd
)->pImpTLInfo
=(void *)-1;
969 /* in this typelib */
970 (*pprtd
)->reference
=offset
;
971 (*pprtd
)->pImpTLInfo
=(void *)-2;
975 /* process Implemented Interfaces of a com class */
976 static void TLB_DoImplTypes(TLBContext
*pcx
, int count
,
977 int offset
, TLBRefType
** pprtd
)
984 for(i
=0;i
<count
;i
++){
985 if(offset
<0) break; /* paranoia */
986 *pprtd
=TLB_Alloc(sizeof(TLBRefType
));
987 TLB_Read(&refrec
,sizeof(refrec
),pcx
,offset
+pcx
->pTblDir
->pRefTab
.offset
);
988 TLB_DoRefType(pcx
, refrec
.reftype
, pprtd
);
989 (*pprtd
)->flags
=refrec
.flags
;
990 (*pprtd
)->ctCustData
=
991 TLB_CustData(pcx
, refrec
.oCustData
, &(*pprtd
)->pCustData
);
993 pprtd
=&((*pprtd
)->next
);
997 * process a typeinfo record
999 ITypeInfoImpl
* TLB_DoTypeInfo(
1002 ITypeLibImpl
* pLibInfo
)
1004 TLBTypeInfoBase tiBase
;
1005 ITypeInfoImpl
*ptiRet
;
1007 TRACE("count=%u\n", count
);
1009 ptiRet
= (ITypeInfoImpl
*) ITypeInfo_Constructor();
1010 TLB_Read(&tiBase
, sizeof(tiBase
) ,pcx
,
1011 pcx
->pTblDir
->pTypeInfoTab
.offset
+count
*sizeof(tiBase
));
1012 /* this where we are coming from */
1013 ptiRet
->pTypeLib
= pLibInfo
;
1014 ptiRet
->index
=count
;
1015 /* fill in the typeattr fields */
1016 TLB_ReadGuid(&ptiRet
->TypeAttr
.guid
, tiBase
.posguid
, pcx
);
1017 ptiRet
->TypeAttr
.lcid
=pLibInfo
->LibAttr
.lcid
; /* FIXME: correct? */
1018 ptiRet
->TypeAttr
.memidConstructor
=MEMBERID_NIL
;/* FIXME */
1019 ptiRet
->TypeAttr
.memidDestructor
=MEMBERID_NIL
; /* FIXME */
1020 ptiRet
->TypeAttr
.lpstrSchema
=NULL
; /* reserved */
1021 ptiRet
->TypeAttr
.cbSizeInstance
=tiBase
.size
;
1022 ptiRet
->TypeAttr
.typekind
=tiBase
.typekind
& 0xF;
1023 ptiRet
->TypeAttr
.cFuncs
=LOWORD(tiBase
.cElement
);
1024 ptiRet
->TypeAttr
.cVars
=HIWORD(tiBase
.cElement
);
1025 ptiRet
->TypeAttr
.cbAlignment
=(tiBase
.typekind
>> 11 )& 0x1F; /* there are more flags there */
1026 ptiRet
->TypeAttr
.wTypeFlags
=tiBase
.flags
;
1027 ptiRet
->TypeAttr
.wMajorVerNum
=LOWORD(tiBase
.version
);
1028 ptiRet
->TypeAttr
.wMinorVerNum
=HIWORD(tiBase
.version
);
1029 ptiRet
->TypeAttr
.cImplTypes
=tiBase
.cImplTypes
;
1030 ptiRet
->TypeAttr
.cbSizeVft
=tiBase
.cbSizeVft
; /* FIXME: this is only the non inherited part */
1031 if(ptiRet
->TypeAttr
.typekind
== TKIND_ALIAS
)
1032 TLB_GetTdesc(pcx
, tiBase
.datatype1
,
1033 &ptiRet
->TypeAttr
.tdescAlias
) ;
1036 /* IDLDESC idldescType; *//* never saw this one != zero */
1038 /* name, eventually add to a hash table */
1039 ptiRet
->Name
=TLB_ReadName(pcx
, tiBase
.NameOffset
);
1040 TRACE("reading %s\n", ptiRet
->Name
);
1042 ptiRet
->DocString
=TLB_ReadString(pcx
, tiBase
.docstringoffs
);
1043 ptiRet
->dwHelpStringContext
=tiBase
.helpstringcontext
;
1044 ptiRet
->dwHelpContext
=tiBase
.helpcontext
;
1045 /* note: InfoType's Help file and HelpStringDll come from the containing
1046 * library. Further HelpString and Docstring appear to be the same thing :(
1049 if(ptiRet
->TypeAttr
.cFuncs
>0 )
1050 TLB_DoFuncs(pcx
, ptiRet
->TypeAttr
.cFuncs
,ptiRet
->TypeAttr
.cVars
,
1051 tiBase
.memoffset
, & ptiRet
->funclist
);
1053 if(ptiRet
->TypeAttr
.cVars
>0 )
1054 TLB_DoVars(pcx
, ptiRet
->TypeAttr
.cFuncs
,ptiRet
->TypeAttr
.cVars
,
1055 tiBase
.memoffset
, & ptiRet
->varlist
);
1056 if(ptiRet
->TypeAttr
.cImplTypes
>0 ){
1057 if(ptiRet
->TypeAttr
.typekind
== TKIND_COCLASS
)
1058 TLB_DoImplTypes(pcx
, ptiRet
->TypeAttr
.cImplTypes
,
1059 tiBase
.datatype1
, & ptiRet
->impltypelist
);
1060 else if(ptiRet
->TypeAttr
.typekind
!= TKIND_DISPATCH
){
1061 ptiRet
->impltypelist
=TLB_Alloc(sizeof(TLBRefType
));
1062 TLB_DoRefType(pcx
, tiBase
.datatype1
, & ptiRet
->impltypelist
);
1066 TLB_CustData(pcx
, tiBase
.oCustData
, &ptiRet
->pCustData
);
1068 TRACE("%s guid: %s kind:%s\n",
1070 debugstr_guid(&ptiRet
->TypeAttr
.guid
),
1071 typekind_desc
[ptiRet
->TypeAttr
.typekind
]);
1076 /****************************************************************************
1079 * find the type of the typelib file and map the typelib resource into
1082 #define MSFT_SIGNATURE 0x5446534D /* "MSFT" */
1083 int TLB_ReadTypeLib(LPSTR pszFileName
, ITypeLib2
**ppTypeLib
)
1086 DWORD dwSignature
= 0;
1089 TRACE("%s\n", pszFileName
);
1093 /* check the signature of the file */
1094 hFile
= CreateFileA( pszFileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, -1 );
1095 if (INVALID_HANDLE_VALUE
!= hFile
)
1097 HANDLE hMapping
= CreateFileMappingA( hFile
, NULL
, PAGE_READONLY
| SEC_COMMIT
, 0, 0, NULL
);
1100 LPVOID pBase
= MapViewOfFile(hMapping
, FILE_MAP_READ
, 0, 0, 0);
1103 /* first try to load as *.tlb */
1104 dwSignature
= *((DWORD
*) pBase
);
1105 if ( dwSignature
== MSFT_SIGNATURE
)
1107 *ppTypeLib
= ITypeLib2_Constructor(pBase
);
1109 UnmapViewOfFile(pBase
);
1111 CloseHandle(hMapping
);
1116 if( (WORD
)dwSignature
== IMAGE_DOS_SIGNATURE
)
1118 /* find the typelibrary resource*/
1119 HINSTANCE hinstDLL
= LoadLibraryExA(pszFileName
, 0, DONT_RESOLVE_DLL_REFERENCES
|
1120 LOAD_LIBRARY_AS_DATAFILE
|LOAD_WITH_ALTERED_SEARCH_PATH
);
1123 HRSRC hrsrc
= FindResourceA(hinstDLL
, MAKEINTRESOURCEA(1), "TYPELIB");
1126 HGLOBAL hGlobal
= LoadResource(hinstDLL
, hrsrc
);
1129 LPVOID pBase
= LockResource(hGlobal
);
1132 *ppTypeLib
= ITypeLib2_Constructor(pBase
);
1134 FreeResource( hGlobal
);
1137 FreeLibrary(hinstDLL
);
1144 ERR("Loading of typelib %s failed with error 0x%08lx\n", pszFileName
, GetLastError());
1149 /*================== ITypeLib(2) Methods ===================================*/
1151 /****************************************************************************
1152 * ITypeLib2_Constructor
1154 * loading a typelib from a in-memory image
1156 static ITypeLib2
* ITypeLib2_Constructor(LPVOID pLib
)
1160 TLB2Header tlbHeader
;
1161 TLBSegDir tlbSegDir
;
1162 ITypeLibImpl
* pTypeLibImpl
;
1164 TRACE("%p\n", pLib
);
1166 pTypeLibImpl
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ITypeLibImpl
));
1167 if (!pTypeLibImpl
) return NULL
;
1169 ICOM_VTBL(pTypeLibImpl
) = &tlbvt
;
1170 pTypeLibImpl
->ref
= 1;
1172 /* get pointer to beginning of typelib data */
1176 cx
.pLibInfo
= pTypeLibImpl
;
1179 TLB_Read((void*)&tlbHeader
, sizeof(tlbHeader
), &cx
, 0);
1180 TRACE("read header (0x%08x 0x%08x)\n",tlbHeader
.magic1
,tlbHeader
.magic2
);
1182 /* there is a small number of information here until the next important
1184 * the segment directory . Try to calculate the amount of data */
1185 lPSegDir
= sizeof(tlbHeader
) + (tlbHeader
.nrtypeinfos
)*4 + (tlbHeader
.varflags
& HELPDLLFLAG
? 4 :0);
1187 /* now read the segment directory */
1188 TRACE("read segment directory\n");
1189 TLB_Read((void*)&tlbSegDir
, sizeof(tlbSegDir
), &cx
, lPSegDir
);
1190 cx
.pTblDir
= &tlbSegDir
;
1192 /* just check two entries */
1193 if ( tlbSegDir
.pTypeInfoTab
.res0c
!= 0x0F || tlbSegDir
.pImpInfo
.res0c
!= 0x0F)
1195 ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir
);
1196 HeapFree(GetProcessHeap(),0,pTypeLibImpl
);
1200 /* now fill our internal data */
1201 /* TLIBATTR fields */
1202 TLB_ReadGuid(&pTypeLibImpl
->LibAttr
.guid
, tlbHeader
.posguid
, &cx
);
1203 pTypeLibImpl
->LibAttr
.lcid
= tlbHeader
.lcid
;
1204 pTypeLibImpl
->LibAttr
.syskind
= tlbHeader
.varflags
& 0x0f; /* check the mask */
1205 pTypeLibImpl
->LibAttr
.wMajorVerNum
= LOWORD(tlbHeader
.version
);
1206 pTypeLibImpl
->LibAttr
.wMinorVerNum
= HIWORD(tlbHeader
.version
);
1207 pTypeLibImpl
->LibAttr
.wLibFlags
= (WORD
) tlbHeader
.flags
& 0xffff;/* check mask */
1209 /* name, eventually add to a hash table */
1210 pTypeLibImpl
->Name
= TLB_ReadName(&cx
, tlbHeader
.NameOffset
);
1213 pTypeLibImpl
->DocString
= TLB_ReadString(&cx
, tlbHeader
.helpstring
);
1214 pTypeLibImpl
->HelpFile
= TLB_ReadString(&cx
, tlbHeader
.helpfile
);
1216 if( tlbHeader
.varflags
& HELPDLLFLAG
)
1219 TLB_Read(&offset
, sizeof(offset
), &cx
, sizeof(tlbHeader
));
1220 pTypeLibImpl
->HelpStringDll
= TLB_ReadString(&cx
, offset
);
1223 pTypeLibImpl
->dwHelpContext
= tlbHeader
.helpstringcontext
;
1226 if(tlbHeader
.CustomDataOffset
>= 0)
1228 pTypeLibImpl
->ctCustData
= TLB_CustData(&cx
, tlbHeader
.CustomDataOffset
, &pTypeLibImpl
->pCustData
);
1231 /* fill in typedescriptions */
1232 if(tlbSegDir
.pTypdescTab
.length
> 0)
1234 int i
, j
, cTD
= tlbSegDir
.pTypdescTab
.length
/ (2*sizeof(INT
));
1236 pTypeLibImpl
->pTypeDesc
= TLB_Alloc( cTD
* sizeof(TYPEDESC
));
1237 TLB_Read(td
, sizeof(td
), &cx
, tlbSegDir
.pTypdescTab
.offset
);
1240 /* FIXME: add several sanity checks here */
1241 pTypeLibImpl
->pTypeDesc
[i
].vt
= td
[0] & VT_TYPEMASK
;
1242 if(td
[0] == VT_PTR
|| td
[0] == VT_SAFEARRAY
)
1244 /* FIXME: check safearray */
1246 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lptdesc
)= & stndTypeDesc
[td
[2]];
1248 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lptdesc
)= & pTypeLibImpl
->pTypeDesc
[td
[3]/8];
1250 else if(td
[0] == VT_CARRAY
)
1252 /* array descr table here */
1253 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
) = (void *)((int) td
[2]); /* temp store offset in*/
1255 else if(td
[0] == VT_USERDEFINED
)
1257 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),hreftype
) = MAKELONG(td
[2],td
[3]);
1259 if(++i
<cTD
) TLB_Read(td
, sizeof(td
), &cx
, DO_NOT_SEEK
);
1262 /* second time around to fill the array subscript info */
1265 if(pTypeLibImpl
->pTypeDesc
[i
].vt
!= VT_CARRAY
) continue;
1266 if(tlbSegDir
.pArrayDescriptions
.offset
>0)
1268 TLB_Read(td
, sizeof(td
), &cx
, tlbSegDir
.pArrayDescriptions
.offset
+ (int) V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
));
1269 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
) = TLB_Alloc(sizeof(ARRAYDESC
)+sizeof(SAFEARRAYBOUND
)*(td
[3]-1));
1272 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
)->tdescElem
.vt
= td
[0] & VT_TYPEMASK
;
1274 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
)->tdescElem
= stndTypeDesc
[td
[0]/8];
1276 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
)->cDims
= td
[2];
1278 for(j
= 0; j
<td
[2]; j
++)
1280 TLB_Read(& V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
)->rgbounds
[j
].cElements
,
1281 sizeof(INT
), &cx
, DO_NOT_SEEK
);
1282 TLB_Read(& V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
)->rgbounds
[j
].lLbound
,
1283 sizeof(INT
), &cx
, DO_NOT_SEEK
);
1288 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
) = NULL
;
1289 ERR("didn't find array description data\n");
1294 /* imported type libs */
1295 if(tlbSegDir
.pImpFiles
.offset
>0)
1297 TLBImpLib
**ppImpLib
= &(pTypeLibImpl
->pImpLibs
);
1298 int oGuid
, offset
= tlbSegDir
.pImpFiles
.offset
;
1301 while(offset
< tlbSegDir
.pImpFiles
.offset
+tlbSegDir
.pImpFiles
.length
)
1303 *ppImpLib
= TLB_Alloc(sizeof(TLBImpLib
));
1304 (*ppImpLib
)->offset
= offset
- tlbSegDir
.pImpFiles
.offset
;
1305 TLB_Read(&oGuid
, sizeof(INT
), &cx
, offset
);
1306 TLB_ReadGuid(&(*ppImpLib
)->guid
, oGuid
, &cx
);
1308 /* we are skipping some unknown info here */
1309 TLB_Read(& size
,sizeof(UINT16
), &cx
, offset
+3*(sizeof(INT
)));
1311 (*ppImpLib
)->name
= TLB_Alloc(size
+1);
1312 TLB_Read((*ppImpLib
)->name
, size
, &cx
, DO_NOT_SEEK
);
1313 offset
= (offset
+ 3 * (sizeof(INT
)) + sizeof(UINT16
) + size
+ 3) & 0xfffffffc;
1315 ppImpLib
= &(*ppImpLib
)->next
;
1320 if(tlbHeader
.nrtypeinfos
>= 0 )
1322 /*pTypeLibImpl->TypeInfoCount=tlbHeader.nrtypeinfos; */
1323 ITypeInfoImpl
**ppTI
= &(pTypeLibImpl
->pTypeInfo
);
1325 for(i
= 0; i
<(int)tlbHeader
.nrtypeinfos
; i
++)
1327 *ppTI
= TLB_DoTypeInfo(&cx
, i
, pTypeLibImpl
);
1328 ppTI
= &((*ppTI
)->next
);
1329 (pTypeLibImpl
->TypeInfoCount
)++;
1333 TRACE("(%p)\n", pTypeLibImpl
);
1334 return (ITypeLib2
*) pTypeLibImpl
;
1337 /* ITypeLib::QueryInterface
1339 static HRESULT WINAPI
ITypeLib2_fnQueryInterface(
1344 ICOM_THIS( ITypeLibImpl
, iface
);
1346 TRACE("(%p)->(IID: %s)\n",This
,debugstr_guid(riid
));
1349 if(IsEqualIID(riid
, &IID_IUnknown
) ||
1350 IsEqualIID(riid
,&IID_ITypeLib
)||
1351 IsEqualIID(riid
,&IID_ITypeLib2
))
1358 ITypeLib2_AddRef(iface
);
1359 TRACE("-- Interface: (%p)->(%p)\n",ppvObject
,*ppvObject
);
1362 TRACE("-- Interface: E_NOINTERFACE\n");
1363 return E_NOINTERFACE
;
1368 static ULONG WINAPI
ITypeLib2_fnAddRef( ITypeLib2
*iface
)
1370 ICOM_THIS( ITypeLibImpl
, iface
);
1372 TRACE("(%p)->ref is %u\n",This
, This
->ref
);
1374 return ++(This
->ref
);
1377 /* ITypeLib::Release
1379 static ULONG WINAPI
ITypeLib2_fnRelease( ITypeLib2
*iface
)
1381 ICOM_THIS( ITypeLibImpl
, iface
);
1383 TRACE("(%p)->(%u)\n",This
, This
->ref
);
1387 /* fixme destroy child objects */
1389 TRACE(" destroying ITypeLib(%p)\n",This
);
1391 HeapFree(GetProcessHeap(),0,This
);
1397 /* ITypeLib::GetTypeInfoCount
1399 * Returns the number of type descriptions in the type library
1401 static UINT WINAPI
ITypeLib2_fnGetTypeInfoCount( ITypeLib2
*iface
)
1403 ICOM_THIS( ITypeLibImpl
, iface
);
1404 TRACE("(%p)->count is %d\n",This
, This
->TypeInfoCount
);
1405 return This
->TypeInfoCount
;
1408 /* ITypeLib::GetTypeInfo
1410 * retrieves the specified type description in the library.
1412 static HRESULT WINAPI
ITypeLib2_fnGetTypeInfo(
1415 ITypeInfo
**ppTInfo
)
1418 ICOM_THIS( ITypeLibImpl
, iface
);
1419 ITypeInfoImpl
*pTLBTInfo
= This
->pTypeInfo
;
1421 TRACE("(%p)->(index=%d) \n",This
, index
);
1423 if (!ppTInfo
) return E_INVALIDARG
;
1425 /* search element n in list */
1426 for(i
=0; i
< index
; i
++)
1428 pTLBTInfo
= pTLBTInfo
->next
;
1431 TRACE("-- element not found\n");
1432 return TYPE_E_ELEMENTNOTFOUND
;
1436 *ppTInfo
= (ITypeInfo
*) pTLBTInfo
;
1437 ITypeInfo_AddRef(*ppTInfo
);
1438 TRACE("-- found (%p)\n",*ppTInfo
);
1442 /* ITypeLibs::GetTypeInfoType
1444 * Retrieves the type of a type description.
1446 static HRESULT WINAPI
ITypeLib2_fnGetTypeInfoType(
1451 ICOM_THIS( ITypeLibImpl
, iface
);
1453 ITypeInfoImpl
*pTInfo
= This
->pTypeInfo
;
1455 TRACE("(%p) index %d \n",This
, index
);
1457 if(!pTKind
) return E_INVALIDARG
;
1459 /* search element n in list */
1460 for(i
=0; i
< index
; i
++)
1464 TRACE("-- element not found\n");
1465 return TYPE_E_ELEMENTNOTFOUND
;
1467 pTInfo
= pTInfo
->next
;
1470 *pTKind
= pTInfo
->TypeAttr
.typekind
;
1471 TRACE("-- found Type (%d)\n", *pTKind
);
1475 /* ITypeLib::GetTypeInfoOfGuid
1477 * Retrieves the type description that corresponds to the specified GUID.
1480 static HRESULT WINAPI
ITypeLib2_fnGetTypeInfoOfGuid(
1483 ITypeInfo
**ppTInfo
)
1485 ICOM_THIS( ITypeLibImpl
, iface
);
1486 ITypeInfoImpl
*ppTLBTInfo
= This
->pTypeInfo
; /* head of list */
1488 TRACE("(%p)\n\tguid:\t%s)\n",This
,debugstr_guid(guid
));
1490 /* serach linked list for guid */
1491 while( !IsEqualIID(guid
,&ppTLBTInfo
->TypeAttr
.guid
) )
1493 ppTLBTInfo
= ppTLBTInfo
->next
;
1496 /* end of list reached */
1497 TRACE("-- element not found\n");
1498 return TYPE_E_ELEMENTNOTFOUND
;
1502 TRACE("-- found (%p, %s)\n", ppTLBTInfo
, ppTLBTInfo
->Name
);
1504 *ppTInfo
= (ITypeInfo
*)ppTLBTInfo
;
1505 ITypeInfo_AddRef(*ppTInfo
);
1509 /* ITypeLib::GetLibAttr
1511 * Retrieves the structure that contains the library's attributes.
1514 static HRESULT WINAPI
ITypeLib2_fnGetLibAttr(
1516 LPTLIBATTR
*ppTLibAttr
)
1518 ICOM_THIS( ITypeLibImpl
, iface
);
1519 TRACE("(%p)\n",This
);
1520 /* FIXME: must do a copy here */
1521 *ppTLibAttr
=&This
->LibAttr
;
1525 /* ITypeLib::GetTypeComp
1527 * Enables a client compiler to bind to a library's types, variables,
1528 * constants, and global functions.
1531 static HRESULT WINAPI
ITypeLib2_fnGetTypeComp(
1533 ITypeComp
**ppTComp
)
1535 ICOM_THIS( ITypeLibImpl
, iface
);
1536 FIXME("(%p): stub!\n",This
);
1540 /* ITypeLib::GetDocumentation
1542 * Retrieves the library's documentation string, the complete Help file name
1543 * and path, and the context identifier for the library Help topic in the Help
1547 static HRESULT WINAPI
ITypeLib2_fnGetDocumentation(
1551 BSTR
*pBstrDocString
,
1552 DWORD
*pdwHelpContext
,
1553 BSTR
*pBstrHelpFile
)
1555 ICOM_THIS( ITypeLibImpl
, iface
);
1558 TRACE("(%p) index %d Name(%p) DocString(%p)"
1559 " HelpContext(%p) HelpFile(%p)\n",
1560 This
, index
, pBstrName
, pBstrDocString
, pdwHelpContext
, pBstrHelpFile
);
1561 if(index
<0){ /* documentation for the typelib */
1563 *pBstrName
=TLB_DupAtoBstr(This
->Name
);
1565 *pBstrDocString
=TLB_DupAtoBstr(This
->DocString
);
1567 *pdwHelpContext
=This
->dwHelpContext
;
1569 *pBstrHelpFile
=TLB_DupAtoBstr(This
->HelpFile
);
1570 }else {/* for a typeinfo */
1571 result
=ITypeLib2_fnGetTypeInfo(iface
, index
, &pTInfo
);
1572 if(SUCCEEDED(result
)){
1573 result
=ITypeInfo_GetDocumentation(pTInfo
, MEMBERID_NIL
, pBstrName
,
1574 pBstrDocString
, pdwHelpContext
, pBstrHelpFile
);
1575 ITypeInfo_Release(pTInfo
);
1577 if(!SUCCEEDED(result
))
1585 * Indicates whether a passed-in string contains the name of a type or member
1586 * described in the library.
1589 static HRESULT WINAPI
ITypeLib2_fnIsName(
1595 ICOM_THIS( ITypeLibImpl
, iface
);
1596 ITypeInfoImpl
*pTInfo
;
1597 TLBFuncDesc
*pFInfo
;
1600 PCHAR astr
= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf
);
1602 TRACE("(%p)->(%s,%08lx,%p)\n", This
, debugstr_w(szNameBuf
), lHashVal
,
1606 if(!strcmp(astr
,This
->Name
)) goto ITypeLib2_fnIsName_exit
;
1607 for(pTInfo
=This
->pTypeInfo
;pTInfo
;pTInfo
=pTInfo
->next
){
1608 if(!strcmp(astr
,pTInfo
->Name
)) goto ITypeLib2_fnIsName_exit
;
1609 for(pFInfo
=pTInfo
->funclist
;pFInfo
;pFInfo
=pFInfo
->next
) {
1610 if(!strcmp(astr
,pFInfo
->Name
)) goto ITypeLib2_fnIsName_exit
;
1611 for(i
=0;i
<pFInfo
->funcdesc
.cParams
;i
++)
1612 if(!strcmp(astr
,pFInfo
->pParamDesc
[i
].Name
))
1613 goto ITypeLib2_fnIsName_exit
;
1615 for(pVInfo
=pTInfo
->varlist
;pVInfo
;pVInfo
=pVInfo
->next
)
1616 if(!strcmp(astr
,pVInfo
->Name
)) goto ITypeLib2_fnIsName_exit
;
1621 ITypeLib2_fnIsName_exit
:
1622 TRACE("(%p)slow! search for %s: %s found!\n", This
,
1623 debugstr_a(astr
), *pfName
?"NOT":"");
1625 HeapFree( GetProcessHeap(), 0, astr
);
1629 /* ITypeLib::FindName
1631 * Finds occurrences of a type description in a type library. This may be used
1632 * to quickly verify that a name exists in a type library.
1635 static HRESULT WINAPI
ITypeLib2_fnFindName(
1639 ITypeInfo
**ppTInfo
,
1643 ICOM_THIS( ITypeLibImpl
, iface
);
1644 ITypeInfoImpl
*pTInfo
;
1645 TLBFuncDesc
*pFInfo
;
1648 PCHAR astr
= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf
);
1649 for(pTInfo
=This
->pTypeInfo
;pTInfo
&& j
<*pcFound
; pTInfo
=pTInfo
->next
){
1650 if(!strcmp(astr
,pTInfo
->Name
)) goto ITypeLib2_fnFindName_exit
;
1651 for(pFInfo
=pTInfo
->funclist
;pFInfo
;pFInfo
=pFInfo
->next
) {
1652 if(!strcmp(astr
,pFInfo
->Name
)) goto ITypeLib2_fnFindName_exit
;
1653 for(i
=0;i
<pFInfo
->funcdesc
.cParams
;i
++)
1654 if(!strcmp(astr
,pFInfo
->pParamDesc
[i
].Name
))
1655 goto ITypeLib2_fnFindName_exit
;
1657 for(pVInfo
=pTInfo
->varlist
;pVInfo
;pVInfo
=pVInfo
->next
) ;
1658 if(!strcmp(astr
,pVInfo
->Name
)) goto ITypeLib2_fnFindName_exit
;
1660 ITypeLib2_fnFindName_exit
:
1661 ITypeInfo_AddRef((ITypeInfo
*)pTInfo
);
1662 ppTInfo
[j
]=(LPTYPEINFO
)pTInfo
;
1665 TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
1666 This
, *pcFound
, debugstr_a(astr
), j
);
1670 HeapFree( GetProcessHeap(), 0, astr
);
1674 /* ITypeLib::ReleaseTLibAttr
1676 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
1679 static VOID WINAPI
ITypeLib2_fnReleaseTLibAttr(
1681 TLIBATTR
*pTLibAttr
)
1683 ICOM_THIS( ITypeLibImpl
, iface
);
1684 TRACE("freeing (%p)\n",This
);
1688 /* ITypeLib2::GetCustData
1690 * gets the custom data
1692 static HRESULT WINAPI
ITypeLib2_fnGetCustData(
1697 ICOM_THIS( ITypeLibImpl
, iface
);
1698 TLBCustData
*pCData
;
1700 for(pCData
=This
->pCustData
; pCData
; pCData
= pCData
->next
)
1702 if( IsEqualIID(guid
, &pCData
->guid
)) break;
1705 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
1709 VariantInit( pVarVal
);
1710 VariantCopy( pVarVal
, &pCData
->data
);
1713 return E_INVALIDARG
; /* FIXME: correct? */
1716 /* ITypeLib2::GetLibStatistics
1718 * Returns statistics about a type library that are required for efficient
1719 * sizing of hash tables.
1722 static HRESULT WINAPI
ITypeLib2_fnGetLibStatistics(
1724 ULONG
*pcUniqueNames
,
1725 ULONG
*pcchUniqueNames
)
1727 ICOM_THIS( ITypeLibImpl
, iface
);
1729 FIXME("(%p): stub!\n", This
);
1731 if(pcUniqueNames
) *pcUniqueNames
=1;
1732 if(pcchUniqueNames
) *pcchUniqueNames
=1;
1736 /* ITypeLib2::GetDocumentation2
1738 * Retrieves the library's documentation string, the complete Help file name
1739 * and path, the localization context to use, and the context ID for the
1740 * library Help topic in the Help file.
1743 static HRESULT WINAPI
ITypeLib2_fnGetDocumentation2(
1747 BSTR
*pbstrHelpString
,
1748 DWORD
*pdwHelpStringContext
,
1749 BSTR
*pbstrHelpStringDll
)
1751 ICOM_THIS( ITypeLibImpl
, iface
);
1755 FIXME("(%p) index %d lcid %ld half implemented stub!\n", This
, index
, lcid
);
1757 /* the help string should be obtained from the helpstringdll,
1758 * using the _DLLGetDocumentation function, based on the supplied
1759 * lcid. Nice to do sometime...
1763 /* documentation for the typelib */
1765 *pbstrHelpString
=TLB_DupAtoBstr(This
->DocString
);
1766 if(pdwHelpStringContext
)
1767 *pdwHelpStringContext
=This
->dwHelpContext
;
1768 if(pbstrHelpStringDll
)
1769 *pbstrHelpStringDll
=TLB_DupAtoBstr(This
->HelpStringDll
);
1773 /* for a typeinfo */
1774 result
=ITypeLib2_GetTypeInfo(iface
, index
, &pTInfo
);
1775 if(SUCCEEDED(result
))
1777 ITypeInfo2
* pTInfo2
;
1778 result
= ITypeInfo_QueryInterface(pTInfo
, &IID_ITypeInfo2
, (LPVOID
*) &pTInfo2
);
1779 if(SUCCEEDED(result
))
1781 result
= ITypeInfo2_GetDocumentation2(pTInfo2
, MEMBERID_NIL
, lcid
,
1782 pbstrHelpString
, pdwHelpStringContext
, pbstrHelpStringDll
);
1783 ITypeInfo2_Release(pTInfo
);
1785 ITypeInfo_Release(pTInfo
);
1787 if(!SUCCEEDED(result
))
1793 /* ITypeLib2::GetAllCustData
1795 * Gets all custom data items for the library.
1798 static HRESULT WINAPI
ITypeLib2_fnGetAllCustData(
1800 CUSTDATA
*pCustData
)
1802 ICOM_THIS( ITypeLibImpl
, iface
);
1803 TLBCustData
*pCData
;
1805 TRACE("(%p) returning %d items\n", This
, This
->ctCustData
);
1806 pCustData
->prgCustData
= TLB_Alloc(This
->ctCustData
* sizeof(CUSTDATAITEM
));
1807 if(pCustData
->prgCustData
){
1808 pCustData
->cCustData
=This
->ctCustData
;
1809 for(i
=0, pCData
=This
->pCustData
; pCData
; i
++, pCData
= pCData
->next
){
1810 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
1811 VariantCopy(& pCustData
->prgCustData
[i
].varValue
, & pCData
->data
);
1814 ERR(" OUT OF MEMORY! \n");
1815 return E_OUTOFMEMORY
;
1820 static ICOM_VTABLE(ITypeLib2
) tlbvt
= {
1821 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1822 ITypeLib2_fnQueryInterface
,
1824 ITypeLib2_fnRelease
,
1825 ITypeLib2_fnGetTypeInfoCount
,
1826 ITypeLib2_fnGetTypeInfo
,
1827 ITypeLib2_fnGetTypeInfoType
,
1828 ITypeLib2_fnGetTypeInfoOfGuid
,
1829 ITypeLib2_fnGetLibAttr
,
1830 ITypeLib2_fnGetTypeComp
,
1831 ITypeLib2_fnGetDocumentation
,
1833 ITypeLib2_fnFindName
,
1834 ITypeLib2_fnReleaseTLibAttr
,
1836 ITypeLib2_fnGetCustData
,
1837 ITypeLib2_fnGetLibStatistics
,
1838 ITypeLib2_fnGetDocumentation2
,
1839 ITypeLib2_fnGetAllCustData
1842 /*================== ITypeInfo(2) Methods ===================================*/
1843 static ITypeInfo2
* WINAPI
ITypeInfo_Constructor(void)
1845 ITypeInfoImpl
* pTypeInfoImpl
;
1847 pTypeInfoImpl
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ITypeInfoImpl
));
1850 ICOM_VTBL(pTypeInfoImpl
) = &tinfvt
;
1851 pTypeInfoImpl
->ref
=1;
1853 TRACE("(%p)\n", pTypeInfoImpl
);
1854 return (ITypeInfo2
*) pTypeInfoImpl
;
1857 /* ITypeInfo::QueryInterface
1859 static HRESULT WINAPI
ITypeInfo_fnQueryInterface(
1864 ICOM_THIS( ITypeLibImpl
, iface
);
1866 TRACE("(%p)->(IID: %s)\n",This
,debugstr_guid(riid
));
1869 if(IsEqualIID(riid
, &IID_IUnknown
) ||
1870 IsEqualIID(riid
,&IID_ITypeInfo
)||
1871 IsEqualIID(riid
,&IID_ITypeInfo2
))
1875 ITypeInfo_AddRef(iface
);
1876 TRACE("-- Interface: (%p)->(%p)\n",ppvObject
,*ppvObject
);
1879 TRACE("-- Interface: E_NOINTERFACE\n");
1880 return E_NOINTERFACE
;
1883 /* ITypeInfo::AddRef
1885 static ULONG WINAPI
ITypeInfo_fnAddRef( ITypeInfo2
*iface
)
1887 ICOM_THIS( ITypeInfoImpl
, iface
);
1888 TRACE("(%p)->ref is %u\n",This
, This
->ref
);
1889 ITypeLib2_AddRef((ITypeLib
*)This
->pTypeLib
);
1890 return ++(This
->ref
);
1893 /* ITypeInfo::Release
1895 static ULONG WINAPI
ITypeInfo_fnRelease( ITypeInfo2
*iface
)
1897 ICOM_THIS( ITypeInfoImpl
, iface
);
1898 FIXME("(%p)->ref is %u: stub\n",This
, This
->ref
);
1899 TRACE("(%p)->(%u)\n",This
, This
->ref
);
1901 ITypeLib2_Release((ITypeLib
*)This
->pTypeLib
);
1905 /* fixme destroy child objects */
1907 TRACE(" destroying ITypeInfo(%p)\n",This
);
1909 HeapFree(GetProcessHeap(),0,This
);
1915 /* ITypeInfo::GetTypeAttr
1917 * Retrieves a TYPEATTR structure that contains the attributes of the type
1921 static HRESULT WINAPI
ITypeInfo_fnGetTypeAttr( ITypeInfo2
*iface
,
1922 LPTYPEATTR
*ppTypeAttr
)
1924 ICOM_THIS( ITypeInfoImpl
, iface
);
1925 TRACE("(%p)\n",This
);
1926 /* FIXME: must do a copy here */
1927 *ppTypeAttr
=&This
->TypeAttr
;
1931 /* ITypeInfo::GetTypeComp
1933 * Retrieves the ITypeComp interface for the type description, which enables a
1934 * client compiler to bind to the type description's members.
1937 static HRESULT WINAPI
ITypeInfo_fnGetTypeComp( ITypeInfo2
*iface
,
1938 ITypeComp
* *ppTComp
)
1940 ICOM_THIS( ITypeInfoImpl
, iface
);
1941 FIXME("(%p) stub!\n", This
);
1945 /* ITypeInfo::GetFuncDesc
1947 * Retrieves the FUNCDESC structure that contains information about a
1948 * specified function.
1951 static HRESULT WINAPI
ITypeInfo_fnGetFuncDesc( ITypeInfo2
*iface
, UINT index
,
1952 LPFUNCDESC
*ppFuncDesc
)
1954 ICOM_THIS( ITypeInfoImpl
, iface
);
1956 TLBFuncDesc
* pFDesc
;
1957 TRACE("(%p) index %d\n", This
, index
);
1958 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++, pFDesc
=pFDesc
->next
)
1961 /* FIXME: must do a copy here */
1962 *ppFuncDesc
=&pFDesc
->funcdesc
;
1965 return E_INVALIDARG
;
1968 /* ITypeInfo::GetVarDesc
1970 * Retrieves a VARDESC structure that describes the specified variable.
1973 static HRESULT WINAPI
ITypeInfo_fnGetVarDesc( ITypeInfo2
*iface
, UINT index
,
1974 LPVARDESC
*ppVarDesc
)
1976 ICOM_THIS( ITypeInfoImpl
, iface
);
1978 TLBVarDesc
* pVDesc
;
1979 TRACE("(%p) index %d\n", This
, index
);
1980 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++, pVDesc
=pVDesc
->next
)
1983 /* FIXME: must do a copy here */
1984 *ppVarDesc
=&pVDesc
->vardesc
;
1987 return E_INVALIDARG
;
1990 /* ITypeInfo_GetNames
1992 * Retrieves the variable with the specified member ID (or the name of the
1993 * property or method and its parameters) that correspond to the specified
1996 static HRESULT WINAPI
ITypeInfo_fnGetNames( ITypeInfo2
*iface
, MEMBERID memid
,
1997 BSTR
*rgBstrNames
, UINT cMaxNames
, UINT
*pcNames
)
1999 ICOM_THIS( ITypeInfoImpl
, iface
);
2000 TLBFuncDesc
* pFDesc
;
2001 TLBVarDesc
* pVDesc
;
2003 TRACE("(%p) memid=0x%08lx Maxname=%d\n", This
, memid
, cMaxNames
);
2004 for(pFDesc
=This
->funclist
; pFDesc
->funcdesc
.memid
!= memid
&& pFDesc
; pFDesc
=pFDesc
->next
);
2007 /* function found, now return function and parameter names */
2008 for(i
=0; i
<cMaxNames
&& i
<= pFDesc
->funcdesc
.cParams
; i
++)
2011 *rgBstrNames
=TLB_DupAtoBstr(pFDesc
->Name
);
2013 rgBstrNames
[i
]=TLB_DupAtoBstr(pFDesc
->pParamDesc
[i
-1].Name
);
2019 for(pVDesc
=This
->varlist
; pVDesc
->vardesc
.memid
!= memid
&& pVDesc
; pVDesc
=pVDesc
->next
);
2022 *rgBstrNames
=TLB_DupAtoBstr(pFDesc
->Name
);
2027 if(This
->TypeAttr
.typekind
==TKIND_INTERFACE
&& This
->TypeAttr
.cImplTypes
)
2029 /* recursive search */
2032 result
=ITypeInfo_GetRefTypeInfo(iface
, This
->impltypelist
->reference
, &pTInfo
);
2033 if(SUCCEEDED(result
))
2035 result
=ITypeInfo_GetNames(pTInfo
, memid
, rgBstrNames
, cMaxNames
, pcNames
);
2036 ITypeInfo_Release(pTInfo
);
2039 WARN("Could not search inherited interface!\n");
2043 WARN("no names found\n");
2046 return TYPE_E_ELEMENTNOTFOUND
;
2053 /* ITypeInfo::GetRefTypeOfImplType
2055 * If a type description describes a COM class, it retrieves the type
2056 * description of the implemented interface types. For an interface,
2057 * GetRefTypeOfImplType returns the type information for inherited interfaces,
2061 static HRESULT WINAPI
ITypeInfo_fnGetRefTypeOfImplType(
2066 ICOM_THIS( ITypeInfoImpl
, iface
);
2068 TLBRefType
*pIref
= This
->impltypelist
;
2070 TRACE("(%p) index %d\n", This
, index
);
2071 dump_TypeInfo(This
);
2075 /* get the retated interface for this dispinterface */
2076 if( This
->TypeAttr
.typekind
!= TKIND_DISPATCH
) return E_INVALIDARG
;
2077 FIXME("TKIND_INTERFACE expected\n");
2078 return TYPE_E_ELEMENTNOTFOUND
;
2081 /* get element n from linked list */
2082 for(i
=0; i
<index
; i
++)
2084 if (!pIref
) return TYPE_E_ELEMENTNOTFOUND
;
2085 pIref
= pIref
->next
;
2088 *pRefType
= pIref
->reference
;
2089 TRACE("-- 0x%08lx %s\n",pIref
->reference
, debugstr_guid(&pIref
->guid
) );
2093 /* ITypeInfo::GetImplTypeFlags
2095 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
2096 * or base interface in a type description.
2098 static HRESULT WINAPI
ITypeInfo_fnGetImplTypeFlags( ITypeInfo2
*iface
,
2099 UINT index
, INT
*pImplTypeFlags
)
2101 ICOM_THIS( ITypeInfoImpl
, iface
);
2104 TRACE("(%p) index %d\n", This
, index
);
2105 for(i
=0, pIref
=This
->impltypelist
; i
<index
&& pIref
; i
++, pIref
=pIref
->next
)
2107 if(i
==index
&& pIref
){
2108 *pImplTypeFlags
=pIref
->flags
;
2112 return TYPE_E_ELEMENTNOTFOUND
;
2116 * Maps between member names and member IDs, and parameter names and
2119 static HRESULT WINAPI
ITypeInfo_fnGetIDsOfNames( ITypeInfo2
*iface
,
2120 LPOLESTR
*rgszNames
, UINT cNames
, MEMBERID
*pMemId
)
2122 ICOM_THIS( ITypeInfoImpl
, iface
);
2123 TLBFuncDesc
* pFDesc
;
2124 TLBVarDesc
* pVDesc
;
2126 PCHAR aszName
= HEAP_strdupWtoA( GetProcessHeap(), 0, *rgszNames
);
2127 TRACE("(%p) Name %s cNames %d\n", This
, debugstr_a(aszName
),
2129 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
) {
2131 if( !strcmp(aszName
, pFDesc
->Name
)) {
2132 if(cNames
) *pMemId
=pFDesc
->funcdesc
.memid
;
2133 for(i
=1; i
< cNames
; i
++){
2134 PCHAR aszPar
= HEAP_strdupWtoA( GetProcessHeap(), 0,
2136 for(j
=0; j
<pFDesc
->funcdesc
.cParams
; j
++)
2137 if(strcmp(aszPar
,pFDesc
->pParamDesc
[j
].Name
))
2139 if( j
<pFDesc
->funcdesc
.cParams
)
2142 ret
=DISP_E_UNKNOWNNAME
;
2143 HeapFree( GetProcessHeap(), 0, aszPar
);
2145 HeapFree (GetProcessHeap(), 0, aszName
);
2149 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
) {
2150 if( !strcmp(aszName
, pVDesc
->Name
)) {
2151 if(cNames
) *pMemId
=pVDesc
->vardesc
.memid
;
2152 HeapFree (GetProcessHeap(), 0, aszName
);
2156 /* not found, see if this is and interface with an inheritance */
2157 if(This
->TypeAttr
.typekind
==TKIND_INTERFACE
&&
2158 This
->TypeAttr
.cImplTypes
){
2159 /* recursive search */
2161 ret
=ITypeInfo_GetRefTypeInfo(iface
,
2162 This
->impltypelist
->reference
, &pTInfo
);
2164 ret
=ITypeInfo_GetIDsOfNames(pTInfo
, rgszNames
, cNames
, pMemId
);
2165 ITypeInfo_Release(pTInfo
);
2168 WARN("Could not search inherited interface!\n");
2170 WARN("no names found\n");
2171 return DISP_E_UNKNOWNNAME
;
2174 /* ITypeInfo::Invoke
2176 * Invokes a method, or accesses a property of an object, that implements the
2177 * interface described by the type description.
2179 static HRESULT WINAPI
ITypeInfo_fnInvoke(
2184 DISPPARAMS
*pDispParams
,
2185 VARIANT
*pVarResult
,
2186 EXCEPINFO
*pExcepInfo
,
2189 ICOM_THIS( ITypeInfoImpl
, iface
);
2190 FIXME("(%p)(%p,id=0x%08lx,0x%08x,%p,%p,%p,%p) stub!\n",
2191 This
, pIUnk
, memid
, dwFlags
, pDispParams
, pVarResult
, pExcepInfo
, pArgErr
);
2192 dump_DispParms(pDispParams
);
2196 /* ITypeInfo::GetDocumentation
2198 * Retrieves the documentation string, the complete Help file name and path,
2199 * and the context ID for the Help topic for a specified type description.
2201 static HRESULT WINAPI
ITypeInfo_fnGetDocumentation( ITypeInfo2
*iface
,
2202 MEMBERID memid
, BSTR
*pBstrName
, BSTR
*pBstrDocString
,
2203 DWORD
*pdwHelpContext
, BSTR
*pBstrHelpFile
)
2205 ICOM_THIS( ITypeInfoImpl
, iface
);
2206 TLBFuncDesc
* pFDesc
;
2207 TLBVarDesc
* pVDesc
;
2208 TRACE("(%p) memid %ld Name(%p) DocString(%p)"
2209 " HelpContext(%p) HelpFile(%p)\n",
2210 This
, memid
, pBstrName
, pBstrDocString
, pdwHelpContext
, pBstrHelpFile
);
2211 if(memid
==MEMBERID_NIL
){ /* documentation for the typeinfo */
2213 *pBstrName
=TLB_DupAtoBstr(This
->Name
);
2215 *pBstrDocString
=TLB_DupAtoBstr(This
->DocString
);
2217 *pdwHelpContext
=This
->dwHelpContext
;
2219 *pBstrHelpFile
=TLB_DupAtoBstr(This
->DocString
);/* FIXME */
2221 }else {/* for a member */
2222 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
)
2223 if(pFDesc
->funcdesc
.memid
==memid
){
2226 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
)
2227 if(pVDesc
->vardesc
.memid
==memid
){
2231 return TYPE_E_ELEMENTNOTFOUND
;
2234 /* ITypeInfo::GetDllEntry
2236 * Retrieves a description or specification of an entry point for a function
2239 static HRESULT WINAPI
ITypeInfo_fnGetDllEntry( ITypeInfo2
*iface
, MEMBERID memid
,
2240 INVOKEKIND invKind
, BSTR
*pBstrDllName
, BSTR
*pBstrName
,
2243 ICOM_THIS( ITypeInfoImpl
, iface
);
2244 FIXME("(%p) stub!\n", This
);
2248 /* ITypeInfo::GetRefTypeInfo
2250 * If a type description references other type descriptions, it retrieves
2251 * the referenced type descriptions.
2253 static HRESULT WINAPI
ITypeInfo_fnGetRefTypeInfo(
2256 ITypeInfo
**ppTInfo
)
2258 ICOM_THIS( ITypeInfoImpl
, iface
);
2261 if(HREFTYPE_INTHISFILE(hRefType
))
2265 result
= ITypeInfo_GetContainingTypeLib(iface
, &pTLib
, &Index
);
2266 if(SUCCEEDED( result
))
2268 result
=ITypeLib2_GetTypeInfo(pTLib
, HREFTYPE_INDEX(hRefType
), ppTInfo
);
2269 ITypeLib2_Release(pTLib
);
2274 /* imported type lib */
2275 TLBRefType
* pRefType
;
2276 ITypeLibImpl
*pTypeLib
;
2277 for( pRefType
=This
->impltypelist
; pRefType
&&
2278 pRefType
->reference
!= hRefType
; pRefType
=pRefType
->next
);
2280 return TYPE_E_ELEMENTNOTFOUND
; /* FIXME : correct? */
2282 pTypeLib
= pRefType
->pImpTLInfo
->pImpTypeLib
;
2283 if(pTypeLib
) /* typelib already loaded */
2285 result
=ITypeLib2_GetTypeInfoOfGuid(
2286 (LPTYPELIB
)pTypeLib
, &pRefType
->guid
, ppTInfo
);
2290 result
= LoadRegTypeLib( &pRefType
->pImpTLInfo
->guid
,
2292 (LPTYPELIB
*)&pTypeLib
);
2293 if(!SUCCEEDED(result
))
2295 BSTR libnam
=TLB_DupAtoBstr(pRefType
->pImpTLInfo
->name
);
2296 result
=LoadTypeLib(libnam
, (LPTYPELIB
*)&pTypeLib
);
2297 SysFreeString(libnam
);
2299 if(SUCCEEDED(result
))
2301 result
=ITypeLib2_GetTypeInfoOfGuid((LPTYPELIB
)pTypeLib
, &pRefType
->guid
, ppTInfo
);
2302 pRefType
->pImpTLInfo
->pImpTypeLib
= pTypeLib
;
2306 TRACE("(%p) hreftype 0x%04lx loaded %s (%p)\n", This
, hRefType
,
2307 SUCCEEDED(result
)? "SUCCESS":"FAILURE", *ppTInfo
);
2311 /* ITypeInfo::AddressOfMember
2313 * Retrieves the addresses of static functions or variables, such as those
2316 static HRESULT WINAPI
ITypeInfo_fnAddressOfMember( ITypeInfo2
*iface
,
2317 MEMBERID memid
, INVOKEKIND invKind
, PVOID
*ppv
)
2319 ICOM_THIS( ITypeInfoImpl
, iface
);
2320 FIXME("(%p) stub!\n", This
);
2324 /* ITypeInfo::CreateInstance
2326 * Creates a new instance of a type that describes a component object class
2329 static HRESULT WINAPI
ITypeInfo_fnCreateInstance( ITypeInfo2
*iface
,
2330 IUnknown
*pUnk
, REFIID riid
, VOID
**ppvObj
)
2332 ICOM_THIS( ITypeInfoImpl
, iface
);
2333 FIXME("(%p) stub!\n", This
);
2337 /* ITypeInfo::GetMops
2339 * Retrieves marshaling information.
2341 static HRESULT WINAPI
ITypeInfo_fnGetMops( ITypeInfo2
*iface
, MEMBERID memid
,
2344 ICOM_THIS( ITypeInfoImpl
, iface
);
2345 FIXME("(%p) stub!\n", This
);
2349 /* ITypeInfo::GetContainingTypeLib
2351 * Retrieves the containing type library and the index of the type description
2352 * within that type library.
2354 static HRESULT WINAPI
ITypeInfo_fnGetContainingTypeLib( ITypeInfo2
*iface
,
2355 ITypeLib
* *ppTLib
, UINT
*pIndex
)
2357 ICOM_THIS( ITypeInfoImpl
, iface
);
2358 *ppTLib
=(LPTYPELIB
)(This
->pTypeLib
);
2359 *pIndex
=This
->index
;
2360 ITypeLib2_AddRef(*ppTLib
);
2361 TRACE("(%p) returns (%p) index %d!\n", This
, *ppTLib
, *pIndex
);
2365 /* ITypeInfo::ReleaseTypeAttr
2367 * Releases a TYPEATTR previously returned by GetTypeAttr.
2370 static HRESULT WINAPI
ITypeInfo_fnReleaseTypeAttr( ITypeInfo2
*iface
,
2371 TYPEATTR
* pTypeAttr
)
2373 ICOM_THIS( ITypeInfoImpl
, iface
);
2374 TRACE("(%p)->(%p)\n", This
, pTypeAttr
);
2378 /* ITypeInfo::ReleaseFuncDesc
2380 * Releases a FUNCDESC previously returned by GetFuncDesc. *
2382 static HRESULT WINAPI
ITypeInfo_fnReleaseFuncDesc(
2384 FUNCDESC
*pFuncDesc
)
2386 ICOM_THIS( ITypeInfoImpl
, iface
);
2387 TRACE("(%p)->(%p)\n", This
, pFuncDesc
);
2391 /* ITypeInfo::ReleaseVarDesc
2393 * Releases a VARDESC previously returned by GetVarDesc.
2395 static HRESULT WINAPI
ITypeInfo_fnReleaseVarDesc( ITypeInfo2
*iface
,
2398 ICOM_THIS( ITypeInfoImpl
, iface
);
2399 TRACE("(%p)->(%p)\n", This
, pVarDesc
);
2403 /* ITypeInfo2::GetTypeKind
2405 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
2408 static HRESULT WINAPI
ITypeInfo2_fnGetTypeKind( ITypeInfo2
* iface
,
2409 TYPEKIND
*pTypeKind
)
2411 ICOM_THIS( ITypeInfoImpl
, iface
);
2412 *pTypeKind
=This
->TypeAttr
.typekind
;
2413 TRACE("(%p) type 0x%0x\n", This
,*pTypeKind
);
2417 /* ITypeInfo2::GetTypeFlags
2419 * Returns the type flags without any allocations. This returns a DWORD type
2420 * flag, which expands the type flags without growing the TYPEATTR (type
2424 static HRESULT WINAPI
ITypeInfo2_fnGetTypeFlags( ITypeInfo2
* iface
,
2427 ICOM_THIS( ITypeInfoImpl
, iface
);
2428 *pTypeFlags
=This
->TypeAttr
.wTypeFlags
;
2429 TRACE("(%p) flags 0x%04x\n", This
,*pTypeFlags
);
2433 /* ITypeInfo2::GetFuncIndexOfMemId
2434 * Binds to a specific member based on a known DISPID, where the member name
2435 * is not known (for example, when binding to a default member).
2438 static HRESULT WINAPI
ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2
* iface
,
2439 MEMBERID memid
, INVOKEKIND invKind
, UINT
*pFuncIndex
)
2441 ICOM_THIS( ITypeInfoImpl
, iface
);
2442 TLBFuncDesc
*pFuncInfo
;
2445 /* FIXME: should check for invKind??? */
2446 for(i
=0, pFuncInfo
=This
->funclist
;pFuncInfo
&&
2447 memid
!= pFuncInfo
->funcdesc
.memid
; i
++, pFuncInfo
=pFuncInfo
->next
);
2453 result
=E_INVALIDARG
;
2455 TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This
,
2456 memid
, invKind
, SUCCEEDED(result
)? "SUCCES":"FAILED");
2460 /* TypeInfo2::GetVarIndexOfMemId
2462 * Binds to a specific member based on a known DISPID, where the member name
2463 * is not known (for example, when binding to a default member).
2466 static HRESULT WINAPI
ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo2
* iface
,
2467 MEMBERID memid
, UINT
*pVarIndex
)
2469 ICOM_THIS( ITypeInfoImpl
, iface
);
2470 TLBVarDesc
*pVarInfo
;
2473 for(i
=0, pVarInfo
=This
->varlist
; pVarInfo
&&
2474 memid
!= pVarInfo
->vardesc
.memid
; i
++, pVarInfo
=pVarInfo
->next
)
2481 result
=E_INVALIDARG
;
2483 TRACE("(%p) memid 0x%08lx -> %s\n", This
,
2484 memid
, SUCCEEDED(result
)? "SUCCES":"FAILED");
2488 /* ITypeInfo2::GetCustData
2490 * Gets the custom data
2492 static HRESULT WINAPI
ITypeInfo2_fnGetCustData(
2497 ICOM_THIS( ITypeInfoImpl
, iface
);
2498 TLBCustData
*pCData
;
2500 for(pCData
=This
->pCustData
; pCData
; pCData
= pCData
->next
)
2501 if( IsEqualIID(guid
, &pCData
->guid
)) break;
2503 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
2507 VariantInit( pVarVal
);
2508 VariantCopy( pVarVal
, &pCData
->data
);
2511 return E_INVALIDARG
; /* FIXME: correct? */
2514 /* ITypeInfo2::GetFuncCustData
2516 * Gets the custom data
2518 static HRESULT WINAPI
ITypeInfo2_fnGetFuncCustData(
2524 ICOM_THIS( ITypeInfoImpl
, iface
);
2525 TLBCustData
*pCData
=NULL
;
2526 TLBFuncDesc
* pFDesc
;
2528 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++,
2529 pFDesc
=pFDesc
->next
);
2532 for(pCData
=pFDesc
->pCustData
; pCData
; pCData
= pCData
->next
)
2533 if( IsEqualIID(guid
, &pCData
->guid
)) break;
2535 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
2538 VariantInit( pVarVal
);
2539 VariantCopy( pVarVal
, &pCData
->data
);
2542 return E_INVALIDARG
; /* FIXME: correct? */
2545 /* ITypeInfo2::GetParamCustData
2547 * Gets the custom data
2549 static HRESULT WINAPI
ITypeInfo2_fnGetParamCustData(
2556 ICOM_THIS( ITypeInfoImpl
, iface
);
2557 TLBCustData
*pCData
=NULL
;
2558 TLBFuncDesc
* pFDesc
;
2561 for(i
=0, pFDesc
=This
->funclist
; i
!=indexFunc
&& pFDesc
; i
++,pFDesc
=pFDesc
->next
);
2563 if(pFDesc
&& indexParam
>=0 && indexParam
<pFDesc
->funcdesc
.cParams
)
2564 for(pCData
=pFDesc
->pParamDesc
[indexParam
].pCustData
; pCData
;
2565 pCData
= pCData
->next
)
2566 if( IsEqualIID(guid
, &pCData
->guid
)) break;
2568 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
2572 VariantInit( pVarVal
);
2573 VariantCopy( pVarVal
, &pCData
->data
);
2576 return E_INVALIDARG
; /* FIXME: correct? */
2579 /* ITypeInfo2::GetVarcCustData
2581 * Gets the custom data
2583 static HRESULT WINAPI
ITypeInfo2_fnGetVarCustData(
2589 ICOM_THIS( ITypeInfoImpl
, iface
);
2590 TLBCustData
*pCData
=NULL
;
2591 TLBVarDesc
* pVDesc
;
2594 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++, pVDesc
=pVDesc
->next
);
2598 for(pCData
=pVDesc
->pCustData
; pCData
; pCData
= pCData
->next
)
2600 if( IsEqualIID(guid
, &pCData
->guid
)) break;
2604 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
2608 VariantInit( pVarVal
);
2609 VariantCopy( pVarVal
, &pCData
->data
);
2612 return E_INVALIDARG
; /* FIXME: correct? */
2615 /* ITypeInfo2::GetImplcCustData
2617 * Gets the custom data
2619 static HRESULT WINAPI
ITypeInfo2_fnGetImplTypeCustData(
2625 ICOM_THIS( ITypeInfoImpl
, iface
);
2626 TLBCustData
*pCData
=NULL
;
2627 TLBRefType
* pRDesc
;
2630 for(i
=0, pRDesc
=This
->impltypelist
; i
!=index
&& pRDesc
; i
++, pRDesc
=pRDesc
->next
);
2634 for(pCData
=pRDesc
->pCustData
; pCData
; pCData
= pCData
->next
)
2636 if( IsEqualIID(guid
, &pCData
->guid
)) break;
2640 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
2644 VariantInit( pVarVal
);
2645 VariantCopy( pVarVal
, &pCData
->data
);
2648 return E_INVALIDARG
; /* FIXME: correct? */
2651 /* ITypeInfo2::GetDocumentation2
2653 * Retrieves the documentation string, the complete Help file name and path,
2654 * the localization context to use, and the context ID for the library Help
2655 * topic in the Help file.
2658 static HRESULT WINAPI
ITypeInfo2_fnGetDocumentation2(
2662 BSTR
*pbstrHelpString
,
2663 DWORD
*pdwHelpStringContext
,
2664 BSTR
*pbstrHelpStringDll
)
2666 ICOM_THIS( ITypeInfoImpl
, iface
);
2667 TLBFuncDesc
* pFDesc
;
2668 TLBVarDesc
* pVDesc
;
2669 TRACE("(%p) memid %ld lcid(0x%lx) HelpString(%p) "
2670 "HelpStringContext(%p) HelpStringDll(%p)\n",
2671 This
, memid
, lcid
, pbstrHelpString
, pdwHelpStringContext
,
2672 pbstrHelpStringDll
);
2673 /* the help string should be obtained from the helpstringdll,
2674 * using the _DLLGetDocumentation function, based on the supplied
2675 * lcid. Nice to do sometime...
2677 if(memid
==MEMBERID_NIL
){ /* documentation for the typeinfo */
2679 *pbstrHelpString
=TLB_DupAtoBstr(This
->Name
);
2680 if(pdwHelpStringContext
)
2681 *pdwHelpStringContext
=This
->dwHelpStringContext
;
2682 if(pbstrHelpStringDll
)
2683 *pbstrHelpStringDll
=
2684 TLB_DupAtoBstr(This
->pTypeLib
->HelpStringDll
);/* FIXME */
2686 }else {/* for a member */
2687 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
)
2688 if(pFDesc
->funcdesc
.memid
==memid
){
2690 *pbstrHelpString
=TLB_DupAtoBstr(pFDesc
->HelpString
);
2691 if(pdwHelpStringContext
)
2692 *pdwHelpStringContext
=pFDesc
->HelpStringContext
;
2693 if(pbstrHelpStringDll
)
2694 *pbstrHelpStringDll
=
2695 TLB_DupAtoBstr(This
->pTypeLib
->HelpStringDll
);/* FIXME */
2698 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
)
2699 if(pVDesc
->vardesc
.memid
==memid
){
2701 *pbstrHelpString
=TLB_DupAtoBstr(pVDesc
->HelpString
);
2702 if(pdwHelpStringContext
)
2703 *pdwHelpStringContext
=pVDesc
->HelpStringContext
;
2704 if(pbstrHelpStringDll
)
2705 *pbstrHelpStringDll
=
2706 TLB_DupAtoBstr(This
->pTypeLib
->HelpStringDll
);/* FIXME */
2710 return TYPE_E_ELEMENTNOTFOUND
;
2713 /* ITypeInfo2::GetAllCustData
2715 * Gets all custom data items for the Type info.
2718 static HRESULT WINAPI
ITypeInfo2_fnGetAllCustData(
2720 CUSTDATA
*pCustData
)
2722 ICOM_THIS( ITypeInfoImpl
, iface
);
2723 TLBCustData
*pCData
;
2726 TRACE("(%p) returning %d items\n", This
, This
->ctCustData
);
2728 pCustData
->prgCustData
= TLB_Alloc(This
->ctCustData
* sizeof(CUSTDATAITEM
));
2729 if(pCustData
->prgCustData
){
2730 pCustData
->cCustData
=This
->ctCustData
;
2731 for(i
=0, pCData
=This
->pCustData
; pCData
; i
++, pCData
= pCData
->next
){
2732 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
2733 VariantCopy(& pCustData
->prgCustData
[i
].varValue
, & pCData
->data
);
2736 ERR(" OUT OF MEMORY! \n");
2737 return E_OUTOFMEMORY
;
2742 /* ITypeInfo2::GetAllFuncCustData
2744 * Gets all custom data items for the specified Function
2747 static HRESULT WINAPI
ITypeInfo2_fnGetAllFuncCustData(
2750 CUSTDATA
*pCustData
)
2752 ICOM_THIS( ITypeInfoImpl
, iface
);
2753 TLBCustData
*pCData
;
2754 TLBFuncDesc
* pFDesc
;
2756 TRACE("(%p) index %d\n", This
, index
);
2757 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++,
2758 pFDesc
=pFDesc
->next
)
2761 pCustData
->prgCustData
=
2762 TLB_Alloc(pFDesc
->ctCustData
* sizeof(CUSTDATAITEM
));
2763 if(pCustData
->prgCustData
){
2764 pCustData
->cCustData
=pFDesc
->ctCustData
;
2765 for(i
=0, pCData
=pFDesc
->pCustData
; pCData
; i
++,
2766 pCData
= pCData
->next
){
2767 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
2768 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
2772 ERR(" OUT OF MEMORY! \n");
2773 return E_OUTOFMEMORY
;
2777 return TYPE_E_ELEMENTNOTFOUND
;
2780 /* ITypeInfo2::GetAllParamCustData
2782 * Gets all custom data items for the Functions
2785 static HRESULT WINAPI
ITypeInfo2_fnGetAllParamCustData( ITypeInfo2
* iface
,
2786 UINT indexFunc
, UINT indexParam
, CUSTDATA
*pCustData
)
2788 ICOM_THIS( ITypeInfoImpl
, iface
);
2789 TLBCustData
*pCData
=NULL
;
2790 TLBFuncDesc
* pFDesc
;
2792 TRACE("(%p) index %d\n", This
, indexFunc
);
2793 for(i
=0, pFDesc
=This
->funclist
; i
!=indexFunc
&& pFDesc
; i
++,
2794 pFDesc
=pFDesc
->next
)
2796 if(pFDesc
&& indexParam
>=0 && indexParam
<pFDesc
->funcdesc
.cParams
){
2797 pCustData
->prgCustData
=
2798 TLB_Alloc(pFDesc
->pParamDesc
[indexParam
].ctCustData
*
2799 sizeof(CUSTDATAITEM
));
2800 if(pCustData
->prgCustData
){
2801 pCustData
->cCustData
=pFDesc
->pParamDesc
[indexParam
].ctCustData
;
2802 for(i
=0, pCData
=pFDesc
->pParamDesc
[indexParam
].pCustData
;
2803 pCData
; i
++, pCData
= pCData
->next
){
2804 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
2805 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
2809 ERR(" OUT OF MEMORY! \n");
2810 return E_OUTOFMEMORY
;
2814 return TYPE_E_ELEMENTNOTFOUND
;
2817 /* ITypeInfo2::GetAllVarCustData
2819 * Gets all custom data items for the specified Variable
2822 static HRESULT WINAPI
ITypeInfo2_fnGetAllVarCustData( ITypeInfo2
* iface
,
2823 UINT index
, CUSTDATA
*pCustData
)
2825 ICOM_THIS( ITypeInfoImpl
, iface
);
2826 TLBCustData
*pCData
;
2827 TLBVarDesc
* pVDesc
;
2829 TRACE("(%p) index %d\n", This
, index
);
2830 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++,
2831 pVDesc
=pVDesc
->next
)
2834 pCustData
->prgCustData
=
2835 TLB_Alloc(pVDesc
->ctCustData
* sizeof(CUSTDATAITEM
));
2836 if(pCustData
->prgCustData
){
2837 pCustData
->cCustData
=pVDesc
->ctCustData
;
2838 for(i
=0, pCData
=pVDesc
->pCustData
; pCData
; i
++,
2839 pCData
= pCData
->next
){
2840 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
2841 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
2845 ERR(" OUT OF MEMORY! \n");
2846 return E_OUTOFMEMORY
;
2850 return TYPE_E_ELEMENTNOTFOUND
;
2853 /* ITypeInfo2::GetAllImplCustData
2855 * Gets all custom data items for the specified implementation type
2858 static HRESULT WINAPI
ITypeInfo2_fnGetAllImplTypeCustData(
2861 CUSTDATA
*pCustData
)
2863 ICOM_THIS( ITypeInfoImpl
, iface
);
2864 TLBCustData
*pCData
;
2865 TLBRefType
* pRDesc
;
2867 TRACE("(%p) index %d\n", This
, index
);
2868 for(i
=0, pRDesc
=This
->impltypelist
; i
!=index
&& pRDesc
; i
++,
2869 pRDesc
=pRDesc
->next
)
2872 pCustData
->prgCustData
=
2873 TLB_Alloc(pRDesc
->ctCustData
* sizeof(CUSTDATAITEM
));
2874 if(pCustData
->prgCustData
){
2875 pCustData
->cCustData
=pRDesc
->ctCustData
;
2876 for(i
=0, pCData
=pRDesc
->pCustData
; pCData
; i
++,
2877 pCData
= pCData
->next
){
2878 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
2879 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
2883 ERR(" OUT OF MEMORY! \n");
2884 return E_OUTOFMEMORY
;
2888 return TYPE_E_ELEMENTNOTFOUND
;
2891 static ICOM_VTABLE(ITypeInfo2
) tinfvt
=
2893 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2895 ITypeInfo_fnQueryInterface
,
2897 ITypeInfo_fnRelease
,
2899 ITypeInfo_fnGetTypeAttr
,
2900 ITypeInfo_fnGetTypeComp
,
2901 ITypeInfo_fnGetFuncDesc
,
2902 ITypeInfo_fnGetVarDesc
,
2903 ITypeInfo_fnGetNames
,
2904 ITypeInfo_fnGetRefTypeOfImplType
,
2905 ITypeInfo_fnGetImplTypeFlags
,
2906 ITypeInfo_fnGetIDsOfNames
,
2908 ITypeInfo_fnGetDocumentation
,
2909 ITypeInfo_fnGetDllEntry
,
2910 ITypeInfo_fnGetRefTypeInfo
,
2911 ITypeInfo_fnAddressOfMember
,
2912 ITypeInfo_fnCreateInstance
,
2913 ITypeInfo_fnGetMops
,
2914 ITypeInfo_fnGetContainingTypeLib
,
2915 ITypeInfo_fnReleaseTypeAttr
,
2916 ITypeInfo_fnReleaseFuncDesc
,
2917 ITypeInfo_fnReleaseVarDesc
,
2919 ITypeInfo2_fnGetTypeKind
,
2920 ITypeInfo2_fnGetTypeFlags
,
2921 ITypeInfo2_fnGetFuncIndexOfMemId
,
2922 ITypeInfo2_fnGetVarIndexOfMemId
,
2923 ITypeInfo2_fnGetCustData
,
2924 ITypeInfo2_fnGetFuncCustData
,
2925 ITypeInfo2_fnGetParamCustData
,
2926 ITypeInfo2_fnGetVarCustData
,
2927 ITypeInfo2_fnGetImplTypeCustData
,
2928 ITypeInfo2_fnGetDocumentation2
,
2929 ITypeInfo2_fnGetAllCustData
,
2930 ITypeInfo2_fnGetAllFuncCustData
,
2931 ITypeInfo2_fnGetAllParamCustData
,
2932 ITypeInfo2_fnGetAllVarCustData
,
2933 ITypeInfo2_fnGetAllImplTypeCustData
,