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"
39 /* FIXME: get rid of these */
40 typedef struct ITypeInfoVtbl ITypeLib_VTable
, *LPTYPEINFO_VTABLE
;
41 typedef struct ITypeLibVtbl
*LPTYPELIB_VTABLE
;
44 typedef struct tagTLBContext
{
45 unsigned int oStart
; /* start of TLB in file */
46 unsigned int pos
; /* current pos */
47 unsigned int length
; /* total length */
48 void *mapping
; /* memory mapping */
53 DEFAULT_DEBUG_CHANNEL(ole
);
54 DECLARE_DEBUG_CHANNEL(typelib
);
56 /****************************************************************************
57 * QueryPathOfRegTypeLib16 [TYPELIB.14]
59 * the path is "Classes\Typelib\<guid>\<major>.<minor>\<lcid>\win16\"
64 QueryPathOfRegTypeLib16(
65 REFGUID guid
, /* [in] referenced guid */
66 WORD wMaj
, /* [in] major version */
67 WORD wMin
, /* [in] minor version */
68 LCID lcid
, /* [in] locale id */
69 LPBSTR16 path
/* [out] path of typelib */
72 char typelibkey
[100],pathname
[260];
76 WINE_StringFromCLSID(guid
,xguid
);
77 sprintf(typelibkey
,"SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%lx\\win16",
81 sprintf(xguid
,"<guid 0x%08lx>",(DWORD
)guid
);
82 FIXME("(%s,%d,%d,0x%04lx,%p),can't handle non-string guids.\n",xguid
,wMaj
,wMin
,(DWORD
)lcid
,path
);
85 plen
= sizeof(pathname
);
86 if (RegQueryValue16(HKEY_LOCAL_MACHINE
,typelibkey
,pathname
,&plen
)) {
87 /* try again without lang specific id */
89 return QueryPathOfRegTypeLib16(guid
,wMaj
,wMin
,PRIMARYLANGID(lcid
),path
);
90 FIXME("key %s not found\n",typelibkey
);
93 *path
= SysAllocString16(pathname
);
97 /****************************************************************************
98 * QueryPathOfRegTypeLib [OLEAUT32.164]
103 QueryPathOfRegTypeLib(
104 REFGUID guid
, /* [in] referenced guid */
105 WORD wMaj
, /* [in] major version */
106 WORD wMin
, /* [in] minor version */
107 LCID lcid
, /* [in] locale id */
108 LPBSTR path
/* [out] path of typelib */
111 char typelibkey
[100],pathname
[260];
116 WINE_StringFromCLSID(guid
,xguid
);
117 sprintf(typelibkey
,"SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%lx\\win32",
121 sprintf(xguid
,"<guid 0x%08lx>",(DWORD
)guid
);
122 FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n",xguid
,wMaj
,wMin
,(DWORD
)lcid
,path
);
125 plen
= sizeof(pathname
);
126 if (RegQueryValue16(HKEY_LOCAL_MACHINE
,typelibkey
,pathname
,&plen
)) {
127 /* try again without lang specific id */
129 return QueryPathOfRegTypeLib(guid
,wMaj
,wMin
,PRIMARYLANGID(lcid
),path
);
130 FIXME("key %s not found\n",typelibkey
);
133 *path
= HEAP_strdupAtoW(GetProcessHeap(),0,pathname
);
137 /******************************************************************************
138 * LoadTypeLib [TYPELIB.3] Loads and registers a type library
140 * Docs: OLECHAR FAR* szFile
141 * Docs: iTypeLib FAR* FAR* pptLib
147 HRESULT WINAPI
LoadTypeLib16(
148 LPOLESTR szFile
, /* [in] Name of file to load from */
149 void * *pptLib
) /* [out] Pointer to pointer to loaded type library */
151 FIXME("('%s',%p): stub\n",debugstr_w((LPWSTR
)szFile
),pptLib
);
159 /******************************************************************************
160 * LoadTypeLib [OLEAUT32.161]
161 * Loads and registers a type library
163 * Docs: OLECHAR FAR* szFile
164 * Docs: iTypeLib FAR* FAR* pptLib
170 int TLB_ReadTypeLib(PCHAR file
, ITypeLib
**ppTypelib
);
171 HRESULT WINAPI
LoadTypeLib(
172 OLECHAR
*szFile
, /* [in] Name of file to load from */
173 ITypeLib
* *pptLib
) /* [out] Pointer to pointer to loaded type library */
175 return LoadTypeLibEx(szFile
, REGKIND_DEFAULT
, pptLib
);
178 /******************************************************************************
179 * LoadTypeLibEx [OLEAUT32.183]
180 * Loads and optionally registers a type library
186 HRESULT WINAPI
LoadTypeLibEx(
187 LPOLESTR szFile
, /* [in] Name of file to load from */
188 REGKIND regkind
, /* specify kind of registration */
189 ITypeLib
**pptLib
) /* [out] Pointer to pointer to loaded type library */
193 TRACE("('%s',%d,%p)\n",debugstr_w(szFile
), regkind
, pptLib
);
195 p
=HEAP_strdupWtoA(GetProcessHeap(),0,szFile
);
197 if(regkind
!= REGKIND_NONE
)
198 FIXME ("registration of typelibs not supported yet!\n");
200 res
= TLB_ReadTypeLib(p
, pptLib
);
201 /* XXX need to free p ?? */
203 TRACE(" returns %ld\n",res
);
208 /******************************************************************************
209 * LoadRegTypeLib [OLEAUT32.162]
211 HRESULT WINAPI
LoadRegTypeLib(
212 REFGUID rguid
, /* [in] referenced guid */
213 WORD wVerMajor
, /* [in] major version */
214 WORD wVerMinor
, /* [in] minor version */
215 LCID lcid
, /* [in] locale id */
216 ITypeLib
**ppTLib
/* [out] path of typelib */
219 HRESULT res
=QueryPathOfRegTypeLib( rguid
, wVerMajor
, wVerMinor
,
222 res
= LoadTypeLib(bstr
, ppTLib
);
225 if(TRACE_ON(typelib
)){
227 WINE_StringFromCLSID((LPCLSID
)rguid
,xriid
);
228 TRACE("(IID: %s) load %s (%p)\n",xriid
,
229 SUCCEEDED(res
)? "SUCCESS":"FAILED", *ppTLib
);
235 /******************************************************************************
236 * RegisterTypeLib [OLEAUT32.163]
237 * Adds information about a type library to the System Registry
239 * Docs: ITypeLib FAR * ptlib
240 * Docs: OLECHAR FAR* szFullPath
241 * Docs: OLECHAR FAR* szHelpDir
247 HRESULT WINAPI
RegisterTypeLib(
248 ITypeLib
* ptlib
, /*[in] Pointer to the library*/
249 OLECHAR
* szFullPath
, /*[in] full Path of the library*/
250 OLECHAR
* szHelpDir
) /*[in] dir to the helpfile for the library,
252 { FIXME("(%p,%s,%s): stub\n",ptlib
, debugstr_w(szFullPath
),debugstr_w(szHelpDir
));
253 return S_OK
; /* FIXME: pretend everything is OK */
257 /******************************************************************************
258 * UnRegisterTypeLib [OLEAUT32.186]
259 * Removes information about a type library from the System Registry
266 HRESULT WINAPI
UnRegisterTypeLib(
267 REFGUID libid
, /* [in] Guid of the library */
268 WORD wVerMajor
, /* [in] major version */
269 WORD wVerMinor
, /* [in] minor version */
270 LCID lcid
, /* [in] locale id */
274 WINE_StringFromCLSID((LPCLSID
)libid
,xriid
);
275 TRACE("(IID: %s): stub\n",xriid
);
276 return S_OK
; /* FIXME: pretend everything is OK */
279 /****************************************************************************
280 * OaBuildVersion (TYPELIB.15)
282 * known TYPELIB.DLL versions:
284 * OLE 2.01 no OaBuildVersion() avail 1993 -- ---
285 * OLE 2.02 1993-94 02 3002
288 * OLE 2.03 W98 SE orig. file !! 1993-95 10 3024
289 * OLE 2.1 NT 1993-95 ?? ???
290 * OLE 2.3.1 W95 23 700
292 DWORD WINAPI
OaBuildVersion16(void)
294 FIXME("Please report to a.mohr@mailto.de if you get version error messages !\n");
295 switch(VERSION_GetVersion())
298 return MAKELONG(3027, 3); /* WfW 3.11 */
300 return MAKELONG(700, 23); /* Win95A */
302 return MAKELONG(3024, 10); /* W98 SE */
304 FIXME_(ole
)("Version value not known yet. Please investigate it !");
309 /* for better debugging info leave the static out for the time being */
312 /*=======================Itypelib methods ===============================*/
313 /* ITypeLib methods */
314 static HRESULT WINAPI
ITypeLib_fnQueryInterface( LPTYPELIB This
, REFIID riid
,
316 static ULONG WINAPI
ITypeLib_fnAddRef( LPTYPELIB This
);
317 static ULONG WINAPI
ITypeLib_fnRelease( LPTYPELIB This
);
318 static UINT WINAPI
ITypeLib_fnGetTypeInfoCount( LPTYPELIB This
);
319 static HRESULT WINAPI
ITypeLib_fnGetTypeInfo( LPTYPELIB This
, UINT index
,
320 ITypeInfo
**ppTInfo
);
322 static HRESULT WINAPI
ITypeLib_fnGetTypeInfoType( LPTYPELIB This
, UINT index
,
325 static HRESULT WINAPI
ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB This
, REFGUID guid
,
326 ITypeInfo
**ppTinfo
);
328 static HRESULT WINAPI
ITypeLib_fnGetLibAttr( LPTYPELIB This
,
329 LPTLIBATTR
*ppTLibAttr
);
331 static HRESULT WINAPI
ITypeLib_fnGetTypeComp( LPTYPELIB This
,
332 ITypeComp
**ppTComp
);
334 static HRESULT WINAPI
ITypeLib_fnGetDocumentation( LPTYPELIB This
, INT index
,
335 BSTR
*pBstrName
, BSTR
*pBstrDocString
, DWORD
*pdwHelpContext
,
336 BSTR
*pBstrHelpFile
);
338 static HRESULT WINAPI
ITypeLib_fnIsName( LPTYPELIB This
, LPOLESTR szNameBuf
,
339 ULONG lHashVal
, BOOL
*pfName
);
341 static HRESULT WINAPI
ITypeLib_fnFindName( LPTYPELIB This
, LPOLESTR szNameBuf
,
342 ULONG lHashVal
, ITypeInfo
**ppTInfo
, MEMBERID
*rgMemId
, UINT16
*pcFound
);
344 static VOID WINAPI
ITypeLib_fnReleaseTLibAttr( LPTYPELIB This
,
345 TLIBATTR
*pTLibAttr
);
347 static HRESULT WINAPI
ITypeLib2_fnGetCustData( ITypeLib
* This
, REFGUID guid
,
350 static HRESULT WINAPI
ITypeLib2_fnGetLibStatistics( ITypeLib
* This
,
351 UINT
*pcUniqueNames
, UINT
*pcchUniqueNames
);
353 static HRESULT WINAPI
ITypeLib2_fnGetDocumentation2( ITypeLib
* This
,
354 INT index
, LCID lcid
, BSTR
*pbstrHelpString
,
355 INT
*pdwHelpStringContext
, BSTR
*pbstrHelpStringDll
);
357 static HRESULT WINAPI
ITypeLib2_fnGetAllCustData( ITypeLib
* This
,
358 CUSTDATA
*pCustData
);
359 static ICOM_VTABLE(ITypeLib
) tlbvt
= {
360 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
361 ITypeLib_fnQueryInterface
,
364 ITypeLib_fnGetTypeInfoCount
,
365 ITypeLib_fnGetTypeInfo
,
366 ITypeLib_fnGetTypeInfoType
,
367 ITypeLib_fnGetTypeInfoOfGuid
,
368 ITypeLib_fnGetLibAttr
,
369 ITypeLib_fnGetTypeComp
,
370 ITypeLib_fnGetDocumentation
,
373 ITypeLib_fnReleaseTLibAttr
,
374 ITypeLib2_fnGetCustData
,
375 ITypeLib2_fnGetLibStatistics
,
376 ITypeLib2_fnGetDocumentation2
,
377 ITypeLib2_fnGetAllCustData
379 /* TypeInfo Methods */
381 static HRESULT WINAPI
ITypeInfo_fnQueryInterface( LPTYPEINFO This
, REFIID riid
,
383 static ULONG WINAPI
ITypeInfo_fnAddRef( LPTYPEINFO This
);
384 static ULONG WINAPI
ITypeInfo_fnRelease( LPTYPEINFO This
);
385 static HRESULT WINAPI
ITypeInfo_fnGetTypeAttr( LPTYPEINFO This
,
386 LPTYPEATTR
*ppTypeAttr
);
388 static HRESULT WINAPI
ITypeInfo_fnGetTypeComp( LPTYPEINFO This
,
389 ITypeComp
* *ppTComp
);
391 static HRESULT WINAPI
ITypeInfo_fnGetFuncDesc( LPTYPEINFO This
, UINT index
,
392 LPFUNCDESC
*ppFuncDesc
);
394 static HRESULT WINAPI
ITypeInfo_fnGetVarDesc( LPTYPEINFO This
, UINT index
,
395 LPVARDESC
*ppVarDesc
);
397 static HRESULT WINAPI
ITypeInfo_fnGetNames( LPTYPEINFO This
, MEMBERID memid
,
398 BSTR
*rgBstrNames
, UINT cMaxNames
, UINT
*pcNames
);
401 static HRESULT WINAPI
ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO This
,
402 UINT index
, HREFTYPE
*pRefType
);
404 static HRESULT WINAPI
ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO This
,
405 UINT index
, INT
*pImplTypeFlags
);
407 static HRESULT WINAPI
ITypeInfo_fnGetIDsOfNames( LPTYPEINFO This
,
408 LPOLESTR
*rgszNames
, UINT cNames
, MEMBERID
*pMemId
);
410 static HRESULT WINAPI
ITypeInfo_fnInvoke( LPTYPEINFO This
, VOID
*pIUnk
,
411 MEMBERID memid
, UINT16 dwFlags
, DISPPARAMS
*pDispParams
,
412 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*pArgErr
);
414 static HRESULT WINAPI
ITypeInfo_fnGetDocumentation( LPTYPEINFO This
,
415 MEMBERID memid
, BSTR
*pBstrName
, BSTR
*pBstrDocString
,
416 DWORD
*pdwHelpContext
, BSTR
*pBstrHelpFile
);
418 static HRESULT WINAPI
ITypeInfo_fnGetDllEntry( LPTYPEINFO This
,
419 MEMBERID memid
, INVOKEKIND invKind
, BSTR
*pBstrDllName
,
420 BSTR
*pBstrName
, WORD
*pwOrdinal
);
422 static HRESULT WINAPI
ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO This
,
423 HREFTYPE hRefType
, ITypeInfo
* *ppTInfo
);
425 static HRESULT WINAPI
ITypeInfo_fnAddressOfMember( LPTYPEINFO This
,
426 MEMBERID memid
, INVOKEKIND invKind
, PVOID
*ppv
);
428 static HRESULT WINAPI
ITypeInfo_fnCreateInstance( LPTYPEINFO This
,
429 IUnknown
*pUnk
, REFIID riid
, VOID
* *ppvObj
);
431 static HRESULT WINAPI
ITypeInfo_fnGetMops( LPTYPEINFO This
, MEMBERID memid
,
435 static HRESULT WINAPI
ITypeInfo_fnGetContainingTypeLib( LPTYPEINFO This
,
436 ITypeLib
* *ppTLib
, UINT
*pIndex
);
438 static HRESULT WINAPI
ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO This
,
439 TYPEATTR
*pTypeAttr
);
441 static HRESULT WINAPI
ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO This
,
442 FUNCDESC
*pFuncDesc
);
444 static HRESULT WINAPI
ITypeInfo_fnReleaseVarDesc( LPTYPEINFO This
,
446 /* itypeinfo2 methods */
447 static HRESULT WINAPI
ITypeInfo2_fnGetTypeKind( ITypeInfo
* This
,
448 TYPEKIND
*pTypeKind
);
449 static HRESULT WINAPI
ITypeInfo2_fnGetTypeFlags( ITypeInfo
* This
,
451 static HRESULT WINAPI
ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo
* This
,
452 MEMBERID memid
, INVOKEKIND invKind
, UINT
*pFuncIndex
);
453 static HRESULT WINAPI
ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo
* This
,
454 MEMBERID memid
, UINT
*pVarIndex
);
455 static HRESULT WINAPI
ITypeInfo2_fnGetCustData( ITypeInfo
* This
,
456 REFGUID guid
, VARIANT
*pVarVal
);
457 static HRESULT WINAPI
ITypeInfo2_fnGetFuncCustData( ITypeInfo
* This
,
458 UINT index
, REFGUID guid
, VARIANT
*pVarVal
);
459 static HRESULT WINAPI
ITypeInfo2_fnGetParamCustData( ITypeInfo
* This
,
460 UINT indexFunc
, UINT indexParam
, REFGUID guid
, VARIANT
*pVarVal
);
461 static HRESULT WINAPI
ITypeInfo2_fnGetVarCustData( ITypeInfo
* This
,
462 UINT index
, REFGUID guid
, VARIANT
*pVarVal
);
463 static HRESULT WINAPI
ITypeInfo2_fnGetImplTypeCustData( ITypeInfo
* This
,
464 UINT index
, REFGUID guid
, VARIANT
*pVarVal
);
465 static HRESULT WINAPI
ITypeInfo2_fnGetDocumentation2( ITypeInfo
* This
,
466 MEMBERID memid
, LCID lcid
, BSTR
*pbstrHelpString
,
467 INT
*pdwHelpStringContext
, BSTR
*pbstrHelpStringDll
);
468 static HRESULT WINAPI
ITypeInfo2_fnGetAllCustData( ITypeInfo
* This
,
469 CUSTDATA
*pCustData
);
470 static HRESULT WINAPI
ITypeInfo2_fnGetAllFuncCustData( ITypeInfo
* This
,
471 UINT index
, CUSTDATA
*pCustData
);
472 static HRESULT WINAPI
ITypeInfo2_fnGetAllParamCustData( ITypeInfo
* This
,
473 UINT indexFunc
, UINT indexParam
, CUSTDATA
*pCustData
);
474 static HRESULT WINAPI
ITypeInfo2_fnGetAllVarCustData( ITypeInfo
* This
,
475 UINT index
, CUSTDATA
*pCustData
);
476 static HRESULT WINAPI
ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo
* This
,
477 UINT index
, CUSTDATA
*pCustData
);
479 static ICOM_VTABLE(ITypeInfo
) tinfvt
= {
480 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
481 ITypeInfo_fnQueryInterface
,
484 ITypeInfo_fnGetTypeAttr
,
485 ITypeInfo_fnGetTypeComp
,
486 ITypeInfo_fnGetFuncDesc
,
487 ITypeInfo_fnGetVarDesc
,
488 ITypeInfo_fnGetNames
,
489 ITypeInfo_fnGetRefTypeOfImplType
,
490 ITypeInfo_fnGetImplTypeFlags
,
491 ITypeInfo_fnGetIDsOfNames
,
493 ITypeInfo_fnGetDocumentation
,
494 ITypeInfo_fnGetDllEntry
,
495 ITypeInfo_fnGetRefTypeInfo
,
496 ITypeInfo_fnAddressOfMember
,
497 ITypeInfo_fnCreateInstance
,
499 ITypeInfo_fnGetContainingTypeLib
,
500 ITypeInfo_fnReleaseTypeAttr
,
501 ITypeInfo_fnReleaseFuncDesc
,
502 ITypeInfo_fnReleaseVarDesc
,
504 ITypeInfo2_fnGetTypeKind
,
505 ITypeInfo2_fnGetTypeFlags
,
506 ITypeInfo2_fnGetFuncIndexOfMemId
,
507 ITypeInfo2_fnGetVarIndexOfMemId
,
508 ITypeInfo2_fnGetCustData
,
509 ITypeInfo2_fnGetFuncCustData
,
510 ITypeInfo2_fnGetParamCustData
,
511 ITypeInfo2_fnGetVarCustData
,
512 ITypeInfo2_fnGetImplTypeCustData
,
513 ITypeInfo2_fnGetDocumentation2
,
514 ITypeInfo2_fnGetAllCustData
,
515 ITypeInfo2_fnGetAllFuncCustData
,
516 ITypeInfo2_fnGetAllParamCustData
,
517 ITypeInfo2_fnGetAllVarCustData
,
518 ITypeInfo2_fnGetAllImplTypeCustData
,
522 static TYPEDESC stndTypeDesc
[VT_LPWSTR
+1]={/* VT_LPWSTR is largest type that */
523 /* may appear in type description*/
524 {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
525 {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
526 {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
527 {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
528 {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
529 {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
532 static void TLB_abort()
536 static void * TLB_Alloc(unsigned size
)
539 if((ret
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,size
))==NULL
){
541 ERR("cannot allocate memory\n");
546 /* candidate for a more global appearance... */
547 static BSTR
TLB_DupAtoBstr(PCHAR Astr
)
555 pdw
=TLB_Alloc((len
+3)*sizeof(OLECHAR
));
556 pdw
[0]=(len
)*sizeof(OLECHAR
);
557 bstr
=(BSTR
)&( pdw
[1]);
558 lstrcpyAtoW( bstr
, Astr
);
559 TRACE("copying %s to (%p)\n", Astr
, bstr
);
563 static void TLB_Free(void * ptr
)
565 HeapFree(GetProcessHeap(), 0, ptr
);
568 DWORD
TLB_Read(void *buffer
, DWORD count
, TLBContext
*pcx
, long where
)
570 if (where
!= DO_NOT_SEEK
)
572 where
+= pcx
->oStart
;
573 if (where
> pcx
->length
)
576 ERR("seek beyond end (%ld/%d)\n", where
, pcx
->length
);
581 if (pcx
->pos
+ count
> pcx
->length
) count
= pcx
->length
- pcx
->pos
;
582 memcpy( buffer
, (char *)pcx
->mapping
+ pcx
->pos
, count
);
587 static void TLB_ReadGuid( GUID
*pGuid
, int offset
, TLBContext
*pcx
)
589 if(offset
<0 || pcx
->pTblDir
->pGuidTab
.offset
<0){
590 memset(pGuid
,0, sizeof(GUID
));
593 TLB_Read(pGuid
, sizeof(GUID
), pcx
, pcx
->pTblDir
->pGuidTab
.offset
+offset
);
596 PCHAR
TLB_ReadName( TLBContext
*pcx
, int offset
)
600 TLB_Read(&niName
, sizeof(niName
), pcx
,
601 pcx
->pTblDir
->pNametab
.offset
+offset
);
602 niName
.namelen
&= 0xFF; /* FIXME: correct ? */
603 name
=TLB_Alloc((niName
.namelen
& 0xff) +1);
604 TLB_Read(name
, (niName
.namelen
& 0xff), pcx
, DO_NOT_SEEK
);
605 name
[niName
.namelen
& 0xff]='\0';
608 PCHAR
TLB_ReadString( TLBContext
*pcx
, int offset
)
612 if(offset
<0) return NULL
;
613 TLB_Read(&length
, sizeof(INT16
), pcx
, pcx
->pTblDir
->pStringtab
.offset
+offset
);
614 if(length
<= 0) return 0;
615 string
=TLB_Alloc(length
+1);
616 TLB_Read(string
, length
, pcx
, DO_NOT_SEEK
);
621 * read a value and fill a VARIANT structure
623 static void TLB_ReadValue( VARIANT
* pVar
, int offset
, TLBContext
*pcx
)
626 if(offset
<0) { /* data is packed in here */
627 pVar
->vt
= (offset
& 0x7c000000 )>> 26;
628 V_UNION(pVar
, iVal
) = offset
& 0xffff;
631 TLB_Read(&(pVar
->vt
), sizeof(VARTYPE
), pcx
,
632 pcx
->pTblDir
->pCustData
.offset
+ offset
);
634 case VT_EMPTY
: /* FIXME: is this right? */
635 case VT_NULL
: /* FIXME: is this right? */
636 case VT_I2
: /* this should not happen */
647 case VT_VOID
: /* FIXME: is this right? */
655 case VT_DECIMAL
: /* FIXME: is this right? */
658 /* pointer types with known behaviour */
661 TLB_Read(&size
, sizeof(INT
), pcx
, DO_NOT_SEEK
);
662 ptr
=TLB_Alloc(size
);/* allocate temp buffer */
663 TLB_Read(ptr
, size
, pcx
, DO_NOT_SEEK
); /* read string (ANSI) */
664 V_UNION(pVar
, bstrVal
)=SysAllocStringLen(NULL
,size
);
665 /* FIXME: do we need a AtoW conversion here? */
666 V_UNION(pVar
, bstrVal
[size
])=L
'\0';
667 while(size
--) V_UNION(pVar
, bstrVal
[size
])=ptr
[size
];
671 /* FIXME: this will not work AT ALL when the variant contains a pointer */
678 case VT_USERDEFINED
:
684 case VT_STREAMED_OBJECT
:
685 case VT_STORED_OBJECT
:
686 case VT_BLOB_OBJECT
:
691 FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
695 if(size
>0) /* (big|small) endian correct? */
696 TLB_Read(&(V_UNION(pVar
, iVal
)), size
, pcx
, DO_NOT_SEEK
);
700 * create a linked list with custom data
702 static int TLB_CustData( TLBContext
*pcx
, int offset
, TLBCustData
** ppCustData
)
709 pNew
=TLB_Alloc(sizeof(TLBCustData
));
710 TLB_Read(&entry
, sizeof(entry
), pcx
,
711 pcx
->pTblDir
->pCDGuids
.offset
+offset
);
712 TLB_ReadGuid(&(pNew
->guid
), entry
.GuidOffset
, pcx
);
713 TLB_ReadValue(&(pNew
->data
), entry
.DataOffset
, pcx
);
714 /* add new custom data at head of the list */
715 pNew
->next
=*ppCustData
;
722 static void TLB_GetTdesc(TLBContext
*pcx
, INT type
,TYPEDESC
* pTd
)
725 pTd
->vt
=type
& VT_TYPEMASK
;
727 *pTd
=pcx
->pLibInfo
->pTypeDesc
[type
/(2*sizeof(INT
))];
729 static void TLB_DoFuncs(TLBContext
*pcx
, int cFuncs
, int cVars
,
730 int offset
, TLBFuncDesc
** pptfd
)
733 * member information is stored in a data structure at offset
734 * indicated by the memoffset field of the typeinfo structure
735 * There are several distinctive parts.
736 * the first part starts with a field that holds the total length
737 * of this (first) part excluding this field. Then follow the records,
738 * for each member there is one record.
740 * First entry is always the length of the record (excluding this
742 * Rest of the record depends on the type of the member. If there is
743 * a field indicating the member type (function variable intereface etc)
744 * I have not found it yet. At this time we depend on the information
745 * in the type info and the usual order how things are stored.
747 * Second follows an array sized nrMEM*sizeof(INT) with a memeber id
750 * Third is a equal sized array with file offsets to the name entry
753 * Forth and last (?) part is an array with offsets to the records in the
754 * first part of this file segment.
757 int infolen
, nameoffset
, reclength
, nrattributes
;
759 TLBFuncRecord
* pFuncRec
=(TLBFuncRecord
*) recbuf
;
761 int recoffset
=offset
+sizeof(INT
);
762 TLB_Read(&infolen
,sizeof(INT
), pcx
, offset
);
763 for(i
=0;i
<cFuncs
;i
++){
764 *pptfd
=TLB_Alloc(sizeof(TLBFuncDesc
));
765 /* name, eventually add to a hash table */
766 TLB_Read(&nameoffset
, sizeof(INT
), pcx
,
767 offset
+ infolen
+ (cFuncs
+ cVars
+ i
+ 1) * sizeof(INT
));
768 (*pptfd
)->Name
=TLB_ReadName(pcx
, nameoffset
);
769 /* read the function information record */
770 TLB_Read(&reclength
, sizeof(INT
), pcx
, recoffset
);
772 TLB_Read(pFuncRec
, reclength
- sizeof(INT
), pcx
, DO_NOT_SEEK
) ;
773 /* do the attributes */
774 nrattributes
=(reclength
-pFuncRec
->nrargs
*3*sizeof(int)-0x18)
777 (*pptfd
)->helpcontext
= pFuncRec
->OptAttr
[0] ;
779 (*pptfd
)->HelpString
= TLB_ReadString(pcx
,
780 pFuncRec
->OptAttr
[1]) ;
782 if(pFuncRec
->FKCCIC
& 0x2000)
783 (*pptfd
)->Entry
= (char *) pFuncRec
->OptAttr
[2] ;
785 (*pptfd
)->Entry
= TLB_ReadString(pcx
,
786 pFuncRec
->OptAttr
[2]);
788 (*pptfd
)->HelpStringContext
= pFuncRec
->OptAttr
[5] ;
789 if(nrattributes
>6 && pFuncRec
->FKCCIC
& 0x80){
790 TLB_CustData(pcx
, pFuncRec
->OptAttr
[6],
791 &(*pptfd
)->pCustData
);
796 /* fill the FuncDesc Structure */
797 TLB_Read(&(*pptfd
)->funcdesc
.memid
, sizeof(INT
), pcx
,
798 offset
+ infolen
+ ( i
+ 1) * sizeof(INT
));
799 (*pptfd
)->funcdesc
.funckind
= (pFuncRec
->FKCCIC
) & 0x7;
800 (*pptfd
)->funcdesc
.invkind
= ((pFuncRec
->FKCCIC
) >>3) & 0xF;
801 (*pptfd
)->funcdesc
.callconv
= (pFuncRec
->FKCCIC
) >>8 & 0xF;
802 (*pptfd
)->funcdesc
.cParams
= pFuncRec
->nrargs
;
803 (*pptfd
)->funcdesc
.cParamsOpt
= pFuncRec
->nroargs
;
804 (*pptfd
)->funcdesc
.oVft
= pFuncRec
->VtableOffset
;
805 (*pptfd
)->funcdesc
.wFuncFlags
= LOWORD(pFuncRec
->Flags
) ;
806 TLB_GetTdesc(pcx
, pFuncRec
->DataType
,
807 &(*pptfd
)->funcdesc
.elemdescFunc
.tdesc
) ;
809 /* do the parameters/arguments */
810 if(pFuncRec
->nrargs
){
811 TLBParameterInfo paraminfo
;
812 (*pptfd
)->funcdesc
.lprgelemdescParam
=
813 TLB_Alloc(pFuncRec
->nrargs
* sizeof(ELEMDESC
));
814 (*pptfd
)->pParamDesc
=TLB_Alloc(pFuncRec
->nrargs
*
817 TLB_Read(¶minfo
,sizeof(paraminfo
), pcx
, recoffset
+reclength
-
818 pFuncRec
->nrargs
* sizeof(TLBParameterInfo
));
819 for(j
=0;j
<pFuncRec
->nrargs
;j
++){
820 TLB_GetTdesc(pcx
, paraminfo
.DataType
,
821 &(*pptfd
)->funcdesc
.lprgelemdescParam
[j
].tdesc
) ;
822 V_UNION(&((*pptfd
)->funcdesc
.lprgelemdescParam
[j
]),
823 paramdesc
.wParamFlags
) = paraminfo
.Flags
;
824 (*pptfd
)->pParamDesc
[j
].Name
=(void *)paraminfo
.oName
;
825 TLB_Read(¶minfo
,sizeof(TLBParameterInfo
), pcx
,
828 /* second time around */
829 for(j
=0;j
<pFuncRec
->nrargs
;j
++){
831 (*pptfd
)->pParamDesc
[j
].Name
=
832 TLB_ReadName(pcx
, (int)(*pptfd
)->pParamDesc
[j
].Name
);
834 if((PARAMFLAG_FHASDEFAULT
& V_UNION(&((*pptfd
)->funcdesc
.
835 lprgelemdescParam
[j
]),paramdesc
.wParamFlags
)) &&
836 ((pFuncRec
->FKCCIC
) & 0x1000)){
837 INT
*pInt
=(INT
*)((char *)pFuncRec
+ reclength
-
838 (pFuncRec
->nrargs
* 4 + 1) * sizeof(INT
) );
839 PARAMDESC
* pParamDesc
= &V_UNION(&((*pptfd
)->funcdesc
.
840 lprgelemdescParam
[j
]),paramdesc
);
841 pParamDesc
->pparamdescex
= TLB_Alloc(sizeof(PARAMDESCEX
));
842 pParamDesc
->pparamdescex
->cBytes
= sizeof(PARAMDESCEX
);
843 TLB_ReadValue(&(pParamDesc
->pparamdescex
->varDefaultValue
),
847 if(nrattributes
>7+j
&& pFuncRec
->FKCCIC
& 0x80)
848 TLB_CustData(pcx
, pFuncRec
->OptAttr
[7+j
],
849 &(*pptfd
)->pParamDesc
[j
].pCustData
);
852 /* scode is not used: archaic win16 stuff FIXME: right? */
853 (*pptfd
)->funcdesc
.cScodes
= 0 ;
854 (*pptfd
)->funcdesc
.lprgscode
= NULL
;
855 pptfd
=&((*pptfd
)->next
);
856 recoffset
+= reclength
;
859 static void TLB_DoVars(TLBContext
*pcx
, int cFuncs
, int cVars
,
860 int offset
, TLBVarDesc
** pptvd
)
862 int infolen
, nameoffset
, reclength
;
864 TLBVarRecord
* pVarRec
=(TLBVarRecord
*) recbuf
;
867 TLB_Read(&infolen
,sizeof(INT
), pcx
, offset
);
868 TLB_Read(&recoffset
,sizeof(INT
), pcx
, offset
+ infolen
+
869 ((cFuncs
+cVars
)*2+cFuncs
+ 1)*sizeof(INT
));
870 recoffset
+= offset
+sizeof(INT
);
871 for(i
=0;i
<cVars
;i
++){
872 *pptvd
=TLB_Alloc(sizeof(TLBVarDesc
));
873 /* name, eventually add to a hash table */
874 TLB_Read(&nameoffset
, sizeof(INT
), pcx
,
875 offset
+ infolen
+ (cFuncs
+ cVars
+ i
+ 1) * sizeof(INT
));
876 (*pptvd
)->Name
=TLB_ReadName(pcx
, nameoffset
);
877 /* read the variable information record */
878 TLB_Read(&reclength
, sizeof(INT
), pcx
, recoffset
);
880 TLB_Read(pVarRec
, reclength
- sizeof(INT
), pcx
, DO_NOT_SEEK
) ;
882 if(reclength
>(6*sizeof(INT
)) )
883 (*pptvd
)->HelpContext
=pVarRec
->HelpContext
;
884 if(reclength
>(7*sizeof(INT
)) )
885 (*pptvd
)->HelpString
= TLB_ReadString(pcx
, pVarRec
->oHelpString
) ;
886 if(reclength
>(8*sizeof(INT
)) )
887 if(reclength
>(9*sizeof(INT
)) )
888 (*pptvd
)->HelpStringContext
=pVarRec
->HelpStringContext
;
889 /* fill the VarDesc Structure */
890 TLB_Read(&(*pptvd
)->vardesc
.memid
, sizeof(INT
), pcx
,
891 offset
+ infolen
+ ( i
+ 1) * sizeof(INT
));
892 (*pptvd
)->vardesc
.varkind
= pVarRec
->VarKind
;
893 (*pptvd
)->vardesc
.wVarFlags
= pVarRec
->Flags
;
894 TLB_GetTdesc(pcx
, pVarRec
->DataType
,
895 &(*pptvd
)->vardesc
.elemdescVar
.tdesc
) ;
896 /* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) fixme?? */
897 if(pVarRec
->VarKind
== VAR_CONST
){
898 V_UNION(&((*pptvd
)->vardesc
),lpvarValue
)=TLB_Alloc(sizeof(VARIANT
));
899 TLB_ReadValue(V_UNION(&((*pptvd
)->vardesc
),lpvarValue
),
900 pVarRec
->OffsValue
, pcx
);
902 V_UNION(&((*pptvd
)->vardesc
),oInst
)=pVarRec
->OffsValue
;
903 pptvd
=&((*pptvd
)->next
);
904 recoffset
+= reclength
;
907 /* fill in data for a hreftype (offset). When the refernced type is contained
908 * in the typelib, its just an (file) offset in the type info base dir.
909 * If comes fom import, its an offset+1 in the ImpInfo table
911 static void TLB_DoRefType(TLBContext
*pcx
,
912 int offset
, TLBRefType
** pprtd
)
915 if(!HREFTYPE_INTHISFILE( offset
)) {
916 /* external typelib */
918 TLBImpLib
*pImpLib
=(pcx
->pLibInfo
->pImpLibs
);
919 TLB_Read(&impinfo
, sizeof(impinfo
), pcx
,
920 pcx
->pTblDir
->pImpInfo
.offset
+ (offset
& 0xfffffffc));
921 for(j
=0;pImpLib
;j
++){ /* search the known offsets of all import libraries */
922 if(pImpLib
->offset
==impinfo
.oImpFile
) break;
923 pImpLib
=pImpLib
->next
;
926 (*pprtd
)->reference
=offset
;
927 (*pprtd
)->pImpTLInfo
=pImpLib
;
928 TLB_ReadGuid(&(*pprtd
)->guid
, impinfo
.oGuid
, pcx
);
930 ERR("Cannot find a reference\n");
931 (*pprtd
)->reference
=-1;
932 (*pprtd
)->pImpTLInfo
=(void *)-1;
935 /* in this typelib */
936 (*pprtd
)->reference
=offset
;
937 (*pprtd
)->pImpTLInfo
=(void *)-2;
941 /* process Implemented Interfaces of a com class */
942 static void TLB_DoImplTypes(TLBContext
*pcx
, int count
,
943 int offset
, TLBRefType
** pprtd
)
947 for(i
=0;i
<count
;i
++){
948 if(offset
<0) break; /* paranoia */
949 *pprtd
=TLB_Alloc(sizeof(TLBRefType
));
950 TLB_Read(&refrec
,sizeof(refrec
),pcx
,offset
+pcx
->pTblDir
->pRefTab
.offset
);
951 TLB_DoRefType(pcx
, refrec
.reftype
, pprtd
);
952 (*pprtd
)->flags
=refrec
.flags
;
953 (*pprtd
)->ctCustData
=
954 TLB_CustData(pcx
, refrec
.oCustData
, &(*pprtd
)->pCustData
);
956 pprtd
=&((*pprtd
)->next
);
960 * process a typeinfo record
962 TLBTypeInfo
* TLB_DoTypeInfo(TLBContext
*pcx
, int count
, TLBLibInfo
* pLibInfo
)
964 TLBTypeInfoBase tiBase
;
966 ptiRet
=TLB_Alloc(sizeof(TLBTypeInfo
));
967 ptiRet
->lpvtbl
= &tinfvt
;
969 TLB_Read(&tiBase
, sizeof(tiBase
) ,pcx
,
970 pcx
->pTblDir
->pTypeInfoTab
.offset
+count
*sizeof(tiBase
));
971 /* this where we are coming from */
972 ptiRet
->pTypeLib
=pLibInfo
;
974 /* fill in the typeattr fields */
975 TLB_ReadGuid(&ptiRet
->TypeAttr
.guid
, tiBase
.posguid
, pcx
);
976 ptiRet
->TypeAttr
.lcid
=pLibInfo
->LibAttr
.lcid
; /* FIXME: correct? */
977 ptiRet
->TypeAttr
.memidConstructor
=MEMBERID_NIL
;/* FIXME */
978 ptiRet
->TypeAttr
.memidDestructor
=MEMBERID_NIL
; /* FIXME */
979 ptiRet
->TypeAttr
.lpstrSchema
=NULL
; /* reserved */
980 ptiRet
->TypeAttr
.cbSizeInstance
=tiBase
.size
;
981 ptiRet
->TypeAttr
.typekind
=tiBase
.typekind
& 0xF;
982 ptiRet
->TypeAttr
.cFuncs
=LOWORD(tiBase
.cElement
);
983 ptiRet
->TypeAttr
.cVars
=HIWORD(tiBase
.cElement
);
984 ptiRet
->TypeAttr
.cbAlignment
=(tiBase
.typekind
>> 11 )& 0x1F; /* there are more flags there */
985 ptiRet
->TypeAttr
.wTypeFlags
=tiBase
.flags
;
986 ptiRet
->TypeAttr
.wMajorVerNum
=LOWORD(tiBase
.version
);
987 ptiRet
->TypeAttr
.wMinorVerNum
=HIWORD(tiBase
.version
);
988 ptiRet
->TypeAttr
.cImplTypes
=tiBase
.cImplTypes
;
989 ptiRet
->TypeAttr
.cbSizeVft
=tiBase
.cbSizeVft
; /* FIXME: this is only the non inherited part */
990 if(ptiRet
->TypeAttr
.typekind
== TKIND_ALIAS
)
991 TLB_GetTdesc(pcx
, tiBase
.datatype1
,
992 &ptiRet
->TypeAttr
.tdescAlias
) ;
994 /* IDLDESC idldescType; *//* never saw this one != zero */
996 /* name, eventually add to a hash table */
997 ptiRet
->Name
=TLB_ReadName(pcx
, tiBase
.NameOffset
);
998 TRACE("reading %s\n", ptiRet
->Name
);
1000 ptiRet
->DocString
=TLB_ReadString(pcx
, tiBase
.docstringoffs
);
1001 ptiRet
->dwHelpStringContext
=tiBase
.helpstringcontext
;
1002 ptiRet
->dwHelpContext
=tiBase
.helpcontext
;
1003 /* note: InfoType's Help file and HelpStringDll come from the containing
1004 * library. Further HelpString and Docstring appear to be the same thing :(
1007 if(ptiRet
->TypeAttr
.cFuncs
>0 )
1008 TLB_DoFuncs(pcx
, ptiRet
->TypeAttr
.cFuncs
,ptiRet
->TypeAttr
.cVars
,
1009 tiBase
.memoffset
, & ptiRet
->funclist
);
1011 if(ptiRet
->TypeAttr
.cVars
>0 )
1012 TLB_DoVars(pcx
, ptiRet
->TypeAttr
.cFuncs
,ptiRet
->TypeAttr
.cVars
,
1013 tiBase
.memoffset
, & ptiRet
->varlist
);
1014 if(ptiRet
->TypeAttr
.cImplTypes
>0 ){
1015 if(ptiRet
->TypeAttr
.typekind
== TKIND_COCLASS
)
1016 TLB_DoImplTypes(pcx
, ptiRet
->TypeAttr
.cImplTypes
,
1017 tiBase
.datatype1
, & ptiRet
->impltypelist
);
1018 else if(ptiRet
->TypeAttr
.typekind
!= TKIND_DISPATCH
){
1019 ptiRet
->impltypelist
=TLB_Alloc(sizeof(TLBRefType
));
1020 TLB_DoRefType(pcx
, tiBase
.datatype1
, & ptiRet
->impltypelist
);
1024 TLB_CustData(pcx
, tiBase
.oCustData
, &ptiRet
->pCustData
);
1029 long TLB_FindTlb(TLBContext
*pcx
)
1030 {/* FIXME: should parse the file properly
1031 * hack to find our tlb data
1033 #define TLBBUFSZ 1024
1034 char buff
[TLBBUFSZ
+1]; /* room for a trailing '\0' */
1039 #define LOOK_FOR_MAGIC(magic) \
1040 count=TLB_Read(buff, TLBBUFSZ, pcx, 0); \
1045 pChr = memchr(pChr,magic[0],count-(pChr-buff));\
1047 if (!memcmp(pChr,magic,4)) { \
1057 count=TLB_Read(buff, TLBBUFSZ, pcx, DO_NOT_SEEK);\
1061 LOOK_FOR_MAGIC(TLBMAGIC2
);
1065 LOOK_FOR_MAGIC(TLBMAGIC1
);
1067 ERR("type library format not (yet) implemented\n");
1069 ERR("not type library found in this file\n");
1072 #undef LOOK_FOR_MAGIC
1074 int TLB_ReadTypeLib(PCHAR file
, ITypeLib
**ppTypeLib
)
1078 long oStart
,lPSegDir
;
1079 TLBLibInfo
* pLibInfo
=NULL
;
1080 TLB2Header tlbHeader
;
1081 TLBSegDir tlbSegDir
;
1084 if((hFile
=OpenFile(file
, &ofStruct
, OF_READ
))==HFILE_ERROR
) {
1085 ERR("cannot open %s error 0x%lx\n",file
, GetLastError());
1088 cx
.length
= SetFilePointer( hFile
, 0, NULL
, FILE_END
);
1089 if (!(hMap
= CreateFileMappingA( hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
)))
1091 CloseHandle( hFile
);
1092 ERR("cannot map %s error 0x%lx\n",file
, GetLastError());
1095 CloseHandle( hFile
);
1096 cx
.mapping
= MapViewOfFile( hMap
, FILE_MAP_READ
, 0, 0, 0 );
1097 CloseHandle( hMap
);
1100 ERR("cannot map view of %s error 0x%lx\n",file
, GetLastError());
1103 /* get pointer to beginning of typelib data */
1106 if((oStart
=TLB_FindTlb(&cx
))<0){
1108 ERR("cannot locate typelib in %s\n",file
);
1110 ERR("unsupported typelib format in %s\n",file
);
1111 UnmapViewOfFile( cx
.mapping
);
1115 pLibInfo
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(TLBLibInfo
));
1117 UnmapViewOfFile( cx
.mapping
);
1118 return E_OUTOFMEMORY
;
1120 pLibInfo
->lpvtbl
= &tlbvt
;
1122 cx
.pLibInfo
=pLibInfo
;
1124 TLB_Read((void*)&tlbHeader
, sizeof(tlbHeader
), &cx
, 0);
1125 /* there is a small number of information here until the next important
1127 * the segment directory . Try to calculate the amount of data */
1128 lPSegDir
=sizeof(tlbHeader
)+
1129 (tlbHeader
.nrtypeinfos
)*4+
1130 (tlbHeader
.varflags
& HELPDLLFLAG
? 4 :0);
1131 /* now read the segment directory */
1132 TLB_Read((void*)&tlbSegDir
, sizeof(tlbSegDir
), &cx
, lPSegDir
);
1133 cx
.pTblDir
=&tlbSegDir
;
1134 /* just check two entries */
1135 if ( tlbSegDir
.pTypeInfoTab
.res0c
!= 0x0F ||
1136 tlbSegDir
.pImpInfo
.res0c
!= 0x0F
1138 ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir
);
1139 UnmapViewOfFile( cx
.mapping
);
1142 /* now fill our internal data */
1143 /* TLIBATTR fields */
1144 TLB_ReadGuid(&pLibInfo
->LibAttr
.guid
, tlbHeader
.posguid
, &cx
);
1145 pLibInfo
->LibAttr
.lcid
=tlbHeader
.lcid
;
1146 pLibInfo
->LibAttr
.syskind
=tlbHeader
.varflags
& 0x0f; /* check the mask */
1147 pLibInfo
->LibAttr
.wMajorVerNum
=LOWORD(tlbHeader
.version
);
1148 pLibInfo
->LibAttr
.wMinorVerNum
=HIWORD(tlbHeader
.version
);
1149 pLibInfo
->LibAttr
.wLibFlags
=(WORD
) tlbHeader
.flags
& 0xffff;/* check mask */
1150 /* name, eventually add to a hash table */
1151 pLibInfo
->Name
=TLB_ReadName(&cx
, tlbHeader
.NameOffset
);
1153 pLibInfo
->DocString
=TLB_ReadString(&cx
, tlbHeader
.helpstring
);
1154 pLibInfo
->HelpFile
=TLB_ReadString(&cx
, tlbHeader
.helpfile
);
1155 if( tlbHeader
.varflags
& HELPDLLFLAG
){
1157 TLB_Read(&offset
, sizeof(offset
), &cx
, sizeof(tlbHeader
));
1158 pLibInfo
->HelpStringDll
=TLB_ReadString(&cx
, offset
);
1161 pLibInfo
->dwHelpContext
=tlbHeader
.helpstringcontext
;
1163 if(tlbHeader
.CustomDataOffset
>= 0) {
1164 pLibInfo
->ctCustData
=
1165 TLB_CustData(&cx
, tlbHeader
.CustomDataOffset
, &pLibInfo
->pCustData
);
1167 /* fill in typedescriptions */
1168 if(tlbSegDir
.pTypdescTab
.length
>0){
1169 int i
, j
, cTD
=tlbSegDir
.pTypdescTab
.length
/ (2*sizeof(INT
));
1171 pLibInfo
->pTypeDesc
=
1172 TLB_Alloc( cTD
* sizeof(TYPEDESC
));
1173 TLB_Read(td
, sizeof(td
), &cx
, tlbSegDir
.pTypdescTab
.offset
);
1175 /* FIXME: add several sanity checks here */
1176 pLibInfo
->pTypeDesc
[i
].vt
=td
[0] & VT_TYPEMASK
;
1177 if(td
[0]==VT_PTR
||td
[0]==VT_SAFEARRAY
){/* FIXME: check safearray */
1179 V_UNION(&(pLibInfo
->pTypeDesc
[i
]),lptdesc
)=
1180 & stndTypeDesc
[td
[2]];
1182 V_UNION(&(pLibInfo
->pTypeDesc
[i
]),lptdesc
)=
1183 & pLibInfo
->pTypeDesc
[td
[3]/8];
1184 }else if(td
[0]==VT_CARRAY
)
1185 V_UNION(&(pLibInfo
->pTypeDesc
[i
]),lpadesc
)=
1186 (void *)((int) td
[2]); /* temp store offset in*/
1187 /* array descr table here */
1188 else if(td
[0]==VT_USERDEFINED
)
1189 V_UNION(&(pLibInfo
->pTypeDesc
[i
]),hreftype
)=MAKELONG(td
[2],td
[3]);
1190 if(++i
<cTD
) TLB_Read(td
, sizeof(td
), &cx
, DO_NOT_SEEK
);
1192 /* second time around to fill the array subscript info */
1194 if(pLibInfo
->pTypeDesc
[i
].vt
!= VT_CARRAY
) continue;
1195 if(tlbSegDir
.pArrayDescriptions
.offset
>0){
1196 TLB_Read(td
, sizeof(td
), &cx
, tlbSegDir
.pArrayDescriptions
.offset
+
1197 (int) V_UNION(&(pLibInfo
->pTypeDesc
[i
]),lpadesc
));
1198 V_UNION(&(pLibInfo
->pTypeDesc
[i
]),lpadesc
)=
1199 TLB_Alloc(sizeof(ARRAYDESC
)+sizeof(SAFEARRAYBOUND
)*(td
[3]-1));
1201 V_UNION(&(pLibInfo
->pTypeDesc
[i
]),lpadesc
)->tdescElem
.vt
=td
[0] & VT_TYPEMASK
;
1203 V_UNION(&(pLibInfo
->pTypeDesc
[i
]),lpadesc
)->tdescElem
=stndTypeDesc
[td
[0]/8];
1204 V_UNION(&(pLibInfo
->pTypeDesc
[i
]),lpadesc
)->cDims
=td
[2];
1205 for(j
=0;j
<td
[2];j
++){
1206 TLB_Read(& V_UNION(&(pLibInfo
->pTypeDesc
[i
]),lpadesc
)->rgbounds
[j
].cElements
,
1207 sizeof(INT
), &cx
, DO_NOT_SEEK
);
1208 TLB_Read(& V_UNION(&(pLibInfo
->pTypeDesc
[i
]),lpadesc
)
1209 ->rgbounds
[j
].lLbound
,
1210 sizeof(INT
), &cx
, DO_NOT_SEEK
);
1213 V_UNION(&(pLibInfo
->pTypeDesc
[i
]),lpadesc
)=NULL
;
1214 ERR("didn't find array description data\n");
1218 /* imported type libs */
1219 if(tlbSegDir
.pImpFiles
.offset
>0){
1220 TLBImpLib
**ppImpLib
=&(pLibInfo
->pImpLibs
);
1221 int offset
=tlbSegDir
.pImpFiles
.offset
;
1224 while(offset
< tlbSegDir
.pImpFiles
.offset
+tlbSegDir
.pImpFiles
.length
){
1225 *ppImpLib
=TLB_Alloc(sizeof(TLBImpLib
));
1226 (*ppImpLib
)->offset
=offset
- tlbSegDir
.pImpFiles
.offset
;
1227 TLB_Read(&oGuid
, sizeof(INT
), &cx
, offset
);
1228 TLB_ReadGuid(&(*ppImpLib
)->guid
, oGuid
, &cx
);
1229 /* we are skipping some unknown info here */
1230 TLB_Read(& size
,sizeof(UINT16
), &cx
, offset
+3*(sizeof(INT
)));
1232 (*ppImpLib
)->name
=TLB_Alloc(size
+1);
1233 TLB_Read((*ppImpLib
)->name
,size
, &cx
, DO_NOT_SEEK
);
1234 offset
=(offset
+3*(sizeof(INT
))+sizeof(UINT16
)+size
+3) & 0xfffffffc;
1236 ppImpLib
=&(*ppImpLib
)->next
;
1240 if(tlbHeader
.nrtypeinfos
>=0 ){
1241 /*pLibInfo->TypeInfoCount=tlbHeader.nrtypeinfos; */
1242 TLBTypeInfo
**ppTI
=&(pLibInfo
->pTypeInfo
);
1244 for(i
=0;i
<(int)tlbHeader
.nrtypeinfos
;i
++){
1245 *ppTI
=TLB_DoTypeInfo(&cx
, i
, pLibInfo
);
1246 ppTI
=&((*ppTI
)->next
);
1247 (pLibInfo
->TypeInfoCount
)++;
1251 UnmapViewOfFile( cx
.mapping
);
1252 *ppTypeLib
=(LPTYPELIB
)pLibInfo
;
1256 /*================== ITypeLib(2) Methods ===================================*/
1258 /* ITypeLib::QueryInterface
1260 static HRESULT WINAPI
ITypeLib_fnQueryInterface( LPTYPELIB This
, REFIID riid
,
1263 if(TRACE_ON(typelib
)){
1265 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
1266 TRACE("(%p)->(IID: %s)\n",This
,xriid
);
1269 if(IsEqualIID(riid
, &IID_IUnknown
) ||
1270 IsEqualIID(riid
,&IID_ITypeLib
)||
1271 IsEqualIID(riid
,&IID_ITypeLib2
))
1274 ITypeLib_AddRef(This
);
1275 TRACE("-- Interface: (%p)->(%p)\n",ppvObject
,*ppvObject
);
1278 TRACE("-- Interface: E_NOINTERFACE\n");
1279 return E_NOINTERFACE
;
1284 static ULONG WINAPI
ITypeLib_fnAddRef( LPTYPELIB iface
)
1286 ICOM_THIS( TLBLibInfo
, iface
);
1287 TRACE("(%p)->ref is %u\n",This
, This
->ref
);
1288 return ++(This
->ref
);
1291 /* ITypeLib::Release
1293 static ULONG WINAPI
ITypeLib_fnRelease( LPTYPELIB iface
)
1295 ICOM_THIS( TLBLibInfo
, iface
);
1296 FIXME("(%p)->ref is %u: stub\n",This
, This
->ref
);
1301 /* ITypeLib::GetTypeInfoCount
1303 * Returns the number of type descriptions in the type library
1305 static UINT WINAPI
ITypeLib_fnGetTypeInfoCount( LPTYPELIB iface
)
1307 ICOM_THIS( TLBLibInfo
, iface
);
1308 TRACE("(%p)->count is %d\n",This
, This
->TypeInfoCount
);
1309 return This
->TypeInfoCount
;
1312 /* ITypeLib::GetTypeInfo
1314 *etrieves the specified type description in the library.
1316 static HRESULT WINAPI
ITypeLib_fnGetTypeInfo( LPTYPELIB iface
, UINT index
,
1317 ITypeInfo
**ppTInfo
)
1320 ICOM_THIS( TLBLibInfo
, iface
);
1321 TLBTypeInfo
**ppTLBTInfo
=(TLBTypeInfo
**)ppTInfo
;
1322 TRACE("(%p) index %d \n",This
, index
);
1323 for(i
=0,*ppTLBTInfo
=This
->pTypeInfo
;*ppTLBTInfo
&& i
!= index
;i
++)
1324 *ppTLBTInfo
=(*ppTLBTInfo
)->next
;
1326 (*ppTLBTInfo
)->lpvtbl
->fnAddRef(*ppTInfo
);
1327 TRACE("-- found (%p)->(%p)\n",ppTLBTInfo
,*ppTLBTInfo
);
1330 TRACE("-- element not found\n");
1331 return TYPE_E_ELEMENTNOTFOUND
;
1334 /* ITypeLibs::GetTypeInfoType
1336 * Retrieves the type of a type description.
1338 static HRESULT WINAPI
ITypeLib_fnGetTypeInfoType( LPTYPELIB iface
, UINT index
,
1342 TLBTypeInfo
*pTInfo
;
1343 ICOM_THIS( TLBLibInfo
, iface
);
1344 TRACE("(%p) index %d \n",This
, index
);
1345 for(i
=0,pTInfo
=This
->pTypeInfo
;pTInfo
&& i
!= index
;i
++)
1346 pTInfo
=(pTInfo
)->next
;
1348 *pTKind
=pTInfo
->TypeAttr
.typekind
;
1349 TRACE("-- found Type (%p)->%d\n",pTKind
,*pTKind
);
1352 TRACE("-- element not found\n");
1353 return TYPE_E_ELEMENTNOTFOUND
;
1356 /* ITypeLib::GetTypeInfoOfGuid
1358 * Retrieves the type description that corresponds to the specified GUID.
1361 static HRESULT WINAPI
ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB iface
,
1362 REFGUID guid
, ITypeInfo
**ppTInfo
)
1365 ICOM_THIS( TLBLibInfo
, iface
);
1366 TLBTypeInfo
**ppTLBTInfo
=(TLBTypeInfo
**)ppTInfo
;
1367 if(TRACE_ON(typelib
)){
1369 WINE_StringFromCLSID((LPCLSID
)guid
,xriid
);
1370 TRACE("(%p) guid %sx)\n",This
,xriid
);
1372 for(i
=0,*ppTLBTInfo
=This
->pTypeInfo
;*ppTLBTInfo
&&
1373 !IsEqualIID(guid
,&(*ppTLBTInfo
)->TypeAttr
.guid
);i
++)
1374 *ppTLBTInfo
=(*ppTLBTInfo
)->next
;
1376 (*ppTLBTInfo
)->lpvtbl
->fnAddRef(*ppTInfo
);
1377 TRACE("-- found (%p)->(%p)\n",ppTLBTInfo
,*ppTLBTInfo
);
1380 TRACE("-- element not found\n");
1381 return TYPE_E_ELEMENTNOTFOUND
;
1384 /* ITypeLib::GetLibAttr
1386 * Retrieves the structure that contains the library's attributes.
1389 static HRESULT WINAPI
ITypeLib_fnGetLibAttr( LPTYPELIB iface
,
1390 LPTLIBATTR
*ppTLibAttr
)
1392 ICOM_THIS( TLBLibInfo
, iface
);
1393 TRACE("(%p)\n",This
);
1394 /* FIXME: must do a copy here */
1395 *ppTLibAttr
=&This
->LibAttr
;
1399 /* ITypeLib::GetTypeComp
1401 * Enables a client compiler to bind to a library's types, variables,
1402 * constants, and global functions.
1405 static HRESULT WINAPI
ITypeLib_fnGetTypeComp( LPTYPELIB iface
,
1406 ITypeComp
**ppTComp
)
1408 ICOM_THIS( TLBLibInfo
, iface
);
1409 FIXME("(%p): stub!\n",This
);
1413 /* ITypeLib::GetDocumentation
1415 * Retrieves the library's documentation string, the complete Help file name
1416 * and path, and the context identifier for the library Help topic in the Help
1420 static HRESULT WINAPI
ITypeLib_fnGetDocumentation( LPTYPELIB iface
, INT index
,
1421 BSTR
*pBstrName
, BSTR
*pBstrDocString
, DWORD
*pdwHelpContext
,
1422 BSTR
*pBstrHelpFile
)
1424 ICOM_THIS( TLBLibInfo
, iface
);
1427 TRACE("(%p) index %d Name(%p) DocString(%p)"
1428 " HelpContext(%p) HelpFile(%p)\n",
1429 This
, index
, pBstrName
, pBstrDocString
, pdwHelpContext
, pBstrHelpFile
);
1430 if(index
<0){ /* documentation for the typelib */
1432 *pBstrName
=TLB_DupAtoBstr(This
->Name
);
1434 *pBstrName
=TLB_DupAtoBstr(This
->DocString
);
1436 *pdwHelpContext
=This
->dwHelpContext
;
1438 *pBstrName
=TLB_DupAtoBstr(This
->HelpFile
);
1439 }else {/* for a typeinfo */
1440 result
=ITypeLib_fnGetTypeInfo(iface
, index
, &pTInfo
);
1441 if(SUCCEEDED(result
)){
1442 result
=ITypeInfo_GetDocumentation(pTInfo
, MEMBERID_NIL
, pBstrName
,
1443 pBstrDocString
, pdwHelpContext
, pBstrHelpFile
);
1444 ITypeInfo_Release(pTInfo
);
1446 if(!SUCCEEDED(result
))
1454 * Indicates whether a passed-in string contains the name of a type or member
1455 * described in the library.
1458 static HRESULT WINAPI
ITypeLib_fnIsName( LPTYPELIB iface
, LPOLESTR szNameBuf
,
1459 ULONG lHashVal
, BOOL
*pfName
)
1461 ICOM_THIS( TLBLibInfo
, iface
);
1462 TLBTypeInfo
*pTInfo
;
1463 TLBFuncDesc
*pFInfo
;
1466 PCHAR astr
= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf
);
1468 if(!strcmp(astr
,This
->Name
)) goto ITypeLib_fnIsName_exit
;
1469 for(pTInfo
=This
->pTypeInfo
;pTInfo
;pTInfo
=pTInfo
->next
){
1470 if(!strcmp(astr
,pTInfo
->Name
)) goto ITypeLib_fnIsName_exit
;
1471 for(pFInfo
=pTInfo
->funclist
;pFInfo
;pFInfo
=pFInfo
->next
) {
1472 if(!strcmp(astr
,pFInfo
->Name
)) goto ITypeLib_fnIsName_exit
;
1473 for(i
=0;i
<pFInfo
->funcdesc
.cParams
;i
++)
1474 if(!strcmp(astr
,pFInfo
->pParamDesc
[i
].Name
))
1475 goto ITypeLib_fnIsName_exit
;
1477 for(pVInfo
=pTInfo
->varlist
;pVInfo
;pVInfo
=pVInfo
->next
) ;
1478 if(!strcmp(astr
,pVInfo
->Name
)) goto ITypeLib_fnIsName_exit
;
1483 ITypeLib_fnIsName_exit
:
1484 TRACE("(%p)slow! search for %s: %s found!\n", This
,
1485 debugstr_a(astr
), *pfName
?"NOT":"");
1487 HeapFree( GetProcessHeap(), 0, astr
);
1491 /* ITypeLib::FindName
1493 * Finds occurrences of a type description in a type library. This may be used
1494 * to quickly verify that a name exists in a type library.
1497 static HRESULT WINAPI
ITypeLib_fnFindName( LPTYPELIB iface
, LPOLESTR szNameBuf
,
1498 ULONG lHashVal
, ITypeInfo
**ppTInfo
, MEMBERID
*rgMemId
, UINT16
*pcFound
)
1500 ICOM_THIS( TLBLibInfo
, iface
);
1501 TLBTypeInfo
*pTInfo
;
1502 TLBFuncDesc
*pFInfo
;
1505 PCHAR astr
= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf
);
1506 for(pTInfo
=This
->pTypeInfo
;pTInfo
&& j
<*pcFound
; pTInfo
=pTInfo
->next
){
1507 if(!strcmp(astr
,pTInfo
->Name
)) goto ITypeLib_fnFindName_exit
;
1508 for(pFInfo
=pTInfo
->funclist
;pFInfo
;pFInfo
=pFInfo
->next
) {
1509 if(!strcmp(astr
,pFInfo
->Name
)) goto ITypeLib_fnFindName_exit
;
1510 for(i
=0;i
<pFInfo
->funcdesc
.cParams
;i
++)
1511 if(!strcmp(astr
,pFInfo
->pParamDesc
[i
].Name
))
1512 goto ITypeLib_fnFindName_exit
;
1514 for(pVInfo
=pTInfo
->varlist
;pVInfo
;pVInfo
=pVInfo
->next
) ;
1515 if(!strcmp(astr
,pVInfo
->Name
)) goto ITypeLib_fnFindName_exit
;
1517 ITypeLib_fnFindName_exit
:
1518 pTInfo
->lpvtbl
->fnAddRef((LPTYPEINFO
)pTInfo
);
1519 ppTInfo
[j
]=(LPTYPEINFO
)pTInfo
;
1522 TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
1523 This
, *pcFound
, debugstr_a(astr
), j
);
1527 HeapFree( GetProcessHeap(), 0, astr
);
1531 /* ITypeLib::ReleaseTLibAttr
1533 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
1536 static VOID WINAPI
ITypeLib_fnReleaseTLibAttr( LPTYPELIB iface
, TLIBATTR
*pTLibAttr
)
1538 ICOM_THIS( TLBLibInfo
, iface
);
1539 TRACE("freeing (%p)\n",This
);
1543 /* ITypeLib2::GetCustData
1545 * gets the custom data
1547 static HRESULT WINAPI
ITypeLib2_fnGetCustData( ITypeLib
* iface
, REFGUID guid
,
1550 ICOM_THIS( TLBLibInfo
, iface
);
1551 TLBCustData
*pCData
;
1552 for(pCData
=This
->pCustData
; pCData
; pCData
= pCData
->next
)
1553 if( IsEqualIID(guid
, &pCData
->guid
)) break;
1554 if(TRACE_ON(typelib
)){
1556 WINE_StringFromCLSID((LPCLSID
)guid
,xriid
);
1557 TRACE("(%p) guid %s %s found!x)\n", This
, xriid
, pCData
? "" : "NOT");
1560 VariantInit( pVarVal
);
1561 VariantCopy( pVarVal
, &pCData
->data
);
1564 return E_INVALIDARG
; /* FIXME: correct? */
1567 /* ITypeLib2::GetLibStatistics
1569 * Returns statistics about a type library that are required for efficient
1570 * sizing of hash tables.
1573 static HRESULT WINAPI
ITypeLib2_fnGetLibStatistics( ITypeLib
* iface
,
1574 UINT
*pcUniqueNames
, UINT
*pcchUniqueNames
)
1576 ICOM_THIS( TLBLibInfo
, iface
);
1577 FIXME("(%p): stub!\n", This
);
1578 if(pcUniqueNames
) *pcUniqueNames
=1;
1579 if(pcchUniqueNames
) *pcchUniqueNames
=1;
1583 /* ITypeLib2::GetDocumentation2
1585 * Retrieves the library's documentation string, the complete Help file name
1586 * and path, the localization context to use, and the context ID for the
1587 * library Help topic in the Help file.
1590 static HRESULT WINAPI
ITypeLib2_fnGetDocumentation2( ITypeLib
* iface
,
1591 INT index
, LCID lcid
, BSTR
*pbstrHelpString
,
1592 INT
*pdwHelpStringContext
, BSTR
*pbstrHelpStringDll
)
1594 ICOM_THIS( TLBLibInfo
, iface
);
1597 FIXME("(%p) index %d lcid %ld half implemented stub!\n", This
,
1599 /* the help string should be obtained from the helpstringdll,
1600 * using the _DLLGetDocumentation function, based on the supplied
1601 * lcid. Nice to do sometime...
1603 if(index
<0){ /* documentation for the typelib */
1605 *pbstrHelpString
=TLB_DupAtoBstr(This
->DocString
);
1606 if(pdwHelpStringContext
)
1607 *pdwHelpStringContext
=This
->dwHelpContext
;
1608 if(pbstrHelpStringDll
)
1609 *pbstrHelpStringDll
=TLB_DupAtoBstr(This
->HelpStringDll
);
1610 }else {/* for a typeinfo */
1611 result
=ITypeLib_fnGetTypeInfo(iface
, index
, &pTInfo
);
1612 if(SUCCEEDED(result
)){
1613 result
=ITypeInfo2_fnGetDocumentation2(pTInfo
, MEMBERID_NIL
, lcid
,
1614 pbstrHelpString
, pdwHelpStringContext
, pbstrHelpStringDll
);
1615 ITypeInfo_Release(pTInfo
);
1617 if(!SUCCEEDED(result
))
1623 /* ITypeLib2::GetAllCustData
1625 * Gets all custom data items for the library.
1628 static HRESULT WINAPI
ITypeLib2_fnGetAllCustData( ITypeLib
* iface
,
1629 CUSTDATA
*pCustData
)
1631 ICOM_THIS( TLBLibInfo
, iface
);
1632 TLBCustData
*pCData
;
1634 TRACE("(%p) returning %d items\n", This
, This
->ctCustData
);
1635 pCustData
->prgCustData
= TLB_Alloc(This
->ctCustData
* sizeof(CUSTDATAITEM
));
1636 if(pCustData
->prgCustData
){
1637 pCustData
->cCustData
=This
->ctCustData
;
1638 for(i
=0, pCData
=This
->pCustData
; pCData
; i
++, pCData
= pCData
->next
){
1639 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
1640 VariantCopy(& pCustData
->prgCustData
[i
].varValue
, & pCData
->data
);
1643 ERR(" OUT OF MEMORY! \n");
1644 return E_OUTOFMEMORY
;
1650 /*================== ITypeInfo(2) Methods ===================================*/
1652 /* ITypeInfo::QueryInterface
1654 static HRESULT WINAPI
ITypeInfo_fnQueryInterface( LPTYPEINFO iface
, REFIID riid
,
1657 ICOM_THIS( TLBTypeInfo
, iface
);
1658 if(TRACE_ON(typelib
)){
1660 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
1661 TRACE("(%p)->(IID: %s)\n",This
,xriid
);
1664 if(IsEqualIID(riid
, &IID_IUnknown
) ||
1665 IsEqualIID(riid
,&IID_ITypeInfo
)||
1666 IsEqualIID(riid
,&IID_ITypeInfo2
))
1669 ITypeInfo_AddRef(iface
);
1670 TRACE("-- Interface: (%p)->(%p)\n",ppvObject
,*ppvObject
);
1673 TRACE("-- Interface: E_NOINTERFACE\n");
1674 return E_NOINTERFACE
;
1677 /* ITypeInfo::AddRef
1679 static ULONG WINAPI
ITypeInfo_fnAddRef( LPTYPEINFO iface
)
1681 ICOM_THIS( TLBTypeInfo
, iface
);
1682 TRACE("(%p)->ref is %u\n",This
, This
->ref
);
1683 (This
->pTypeLib
->ref
)++;
1684 return ++(This
->ref
);
1687 /* ITypeInfo::Release
1689 static ULONG WINAPI
ITypeInfo_fnRelease( LPTYPEINFO iface
)
1691 ICOM_THIS( TLBTypeInfo
, iface
);
1692 FIXME("(%p)->ref is %u: stub\n",This
, This
->ref
);
1694 (This
->pTypeLib
->ref
)--;
1698 /* ITypeInfo::GetTypeAttr
1700 * Retrieves a TYPEATTR structure that contains the attributes of the type
1704 static HRESULT WINAPI
ITypeInfo_fnGetTypeAttr( LPTYPEINFO iface
,
1705 LPTYPEATTR
*ppTypeAttr
)
1707 ICOM_THIS( TLBTypeInfo
, iface
);
1708 TRACE("(%p)\n",This
);
1709 /* FIXME: must do a copy here */
1710 *ppTypeAttr
=&This
->TypeAttr
;
1714 /* ITypeInfo::GetTypeComp
1716 * Retrieves the ITypeComp interface for the type description, which enables a
1717 * client compiler to bind to the type description's members.
1720 static HRESULT WINAPI
ITypeInfo_fnGetTypeComp( LPTYPEINFO iface
,
1721 ITypeComp
* *ppTComp
)
1723 ICOM_THIS( TLBTypeInfo
, iface
);
1724 FIXME("(%p) stub!\n", This
);
1728 /* ITypeInfo::GetFuncDesc
1730 * Retrieves the FUNCDESC structure that contains information about a
1731 * specified function.
1734 static HRESULT WINAPI
ITypeInfo_fnGetFuncDesc( LPTYPEINFO iface
, UINT index
,
1735 LPFUNCDESC
*ppFuncDesc
)
1737 ICOM_THIS( TLBTypeInfo
, iface
);
1739 TLBFuncDesc
* pFDesc
;
1740 TRACE("(%p) index %d\n", This
, index
);
1741 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++, pFDesc
=pFDesc
->next
)
1744 /* FIXME: must do a copy here */
1745 *ppFuncDesc
=&pFDesc
->funcdesc
;
1748 return E_INVALIDARG
;
1751 /* ITypeInfo::GetVarDesc
1753 * Retrieves a VARDESC structure that describes the specified variable.
1756 static HRESULT WINAPI
ITypeInfo_fnGetVarDesc( LPTYPEINFO iface
, UINT index
,
1757 LPVARDESC
*ppVarDesc
)
1759 ICOM_THIS( TLBTypeInfo
, iface
);
1761 TLBVarDesc
* pVDesc
;
1762 TRACE("(%p) index %d\n", This
, index
);
1763 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++, pVDesc
=pVDesc
->next
)
1766 /* FIXME: must do a copy here */
1767 *ppVarDesc
=&pVDesc
->vardesc
;
1770 return E_INVALIDARG
;
1773 /* ITypeInfo_GetNames
1775 * Retrieves the variable with the specified member ID (or the name of the
1776 * property or method and its parameters) that correspond to the specified
1779 static HRESULT WINAPI
ITypeInfo_fnGetNames( LPTYPEINFO iface
, MEMBERID memid
,
1780 BSTR
*rgBstrNames
, UINT cMaxNames
, UINT
*pcNames
)
1782 ICOM_THIS( TLBTypeInfo
, iface
);
1783 TLBFuncDesc
* pFDesc
;
1784 TLBVarDesc
* pVDesc
;
1786 TRACE("(%p) memid=0x%08lx Maxname=%d\n", This
, memid
,
1788 for(pFDesc
=This
->funclist
; pFDesc
->funcdesc
.memid
!= memid
&& pFDesc
;
1789 pFDesc
=pFDesc
->next
)
1792 /* function found, now return function and parameter names */
1793 for(i
=0; i
<cMaxNames
&& i
<= pFDesc
->funcdesc
.cParams
; i
++){
1794 if(!i
) *rgBstrNames
=TLB_DupAtoBstr(pFDesc
->Name
);
1796 rgBstrNames
[i
]=TLB_DupAtoBstr(pFDesc
->pParamDesc
[i
-1].Name
);
1801 for(pVDesc
=This
->varlist
; pVDesc
->vardesc
.memid
!= memid
&& pVDesc
;
1802 pVDesc
=pVDesc
->next
)
1805 *rgBstrNames
=TLB_DupAtoBstr(pFDesc
->Name
);
1808 if(This
->TypeAttr
.typekind
==TKIND_INTERFACE
&&
1809 This
->TypeAttr
.cImplTypes
){
1810 /* recursive search */
1813 result
=This
->lpvtbl
->fnGetRefTypeInfo(iface
,
1814 This
->impltypelist
->reference
, &pTInfo
);
1815 if(SUCCEEDED(result
)){
1816 result
=ITypeInfo_GetNames(pTInfo
, memid
, rgBstrNames
,
1817 cMaxNames
, pcNames
);
1818 ITypeInfo_Release(pTInfo
);
1821 WARN("Could not search inherited interface!\n");
1823 WARN("no names found\n");
1825 return TYPE_E_ELEMENTNOTFOUND
;
1832 /* ITypeInfo::GetRefTypeOfImplType
1834 * If a type description describes a COM class, it retrieves the type
1835 * description of the implemented interface types. For an interface,
1836 * GetRefTypeOfImplType returns the type information for inherited interfaces,
1840 static HRESULT WINAPI
ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO iface
,
1841 UINT index
, HREFTYPE
*pRefType
)
1843 ICOM_THIS( TLBTypeInfo
, iface
);
1846 TRACE("(%p) index %d\n", This
, index
);
1847 for(i
=0, pIref
=This
->impltypelist
; i
<index
&& pIref
;
1848 i
++, pIref
=pIref
->next
)
1851 *pRefType
=pIref
->reference
;
1854 return TYPE_E_ELEMENTNOTFOUND
;
1857 /* ITypeInfo::GetImplTypeFlags
1859 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
1860 * or base interface in a type description.
1862 static HRESULT WINAPI
ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO iface
,
1863 UINT index
, INT
*pImplTypeFlags
)
1865 ICOM_THIS( TLBTypeInfo
, iface
);
1868 TRACE("(%p) index %d\n", This
, index
);
1869 for(i
=0, pIref
=This
->impltypelist
; i
<index
&& pIref
; i
++, pIref
=pIref
->next
)
1871 if(i
==index
&& pIref
){
1872 *pImplTypeFlags
=pIref
->flags
;
1876 return TYPE_E_ELEMENTNOTFOUND
;
1880 * Maps between member names and member IDs, and parameter names and
1883 static HRESULT WINAPI
ITypeInfo_fnGetIDsOfNames( LPTYPEINFO iface
,
1884 LPOLESTR
*rgszNames
, UINT cNames
, MEMBERID
*pMemId
)
1886 ICOM_THIS( TLBTypeInfo
, iface
);
1887 TLBFuncDesc
* pFDesc
;
1888 TLBVarDesc
* pVDesc
;
1890 PCHAR aszName
= HEAP_strdupWtoA( GetProcessHeap(), 0, *rgszNames
);
1891 TRACE("(%p) Name %s cNames %d\n", This
, debugstr_a(aszName
),
1893 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
) {
1895 if( !strcmp(aszName
, pFDesc
->Name
)) {
1896 if(cNames
) *pMemId
=pFDesc
->funcdesc
.memid
;
1897 for(i
=1; i
< cNames
; i
++){
1898 PCHAR aszPar
= HEAP_strdupWtoA( GetProcessHeap(), 0,
1900 for(j
=0; j
<pFDesc
->funcdesc
.cParams
; j
++)
1901 if(strcmp(aszPar
,pFDesc
->pParamDesc
[j
].Name
))
1903 if( j
<pFDesc
->funcdesc
.cParams
)
1906 ret
=DISP_E_UNKNOWNNAME
;
1907 HeapFree( GetProcessHeap(), 0, aszPar
);
1909 HeapFree (GetProcessHeap(), 0, aszName
);
1913 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
) {
1914 if( !strcmp(aszName
, pVDesc
->Name
)) {
1915 if(cNames
) *pMemId
=pVDesc
->vardesc
.memid
;
1916 HeapFree (GetProcessHeap(), 0, aszName
);
1920 /* not found, see if this is and interface with an inheritance */
1921 if(This
->TypeAttr
.typekind
==TKIND_INTERFACE
&&
1922 This
->TypeAttr
.cImplTypes
){
1923 /* recursive search */
1925 ret
=ITypeInfo_GetRefTypeInfo(iface
,
1926 This
->impltypelist
->reference
, &pTInfo
);
1928 ret
=ITypeInfo_GetIDsOfNames(pTInfo
, rgszNames
, cNames
, pMemId
);
1929 ITypeInfo_Release(pTInfo
);
1932 WARN("Could not search inherited interface!\n");
1934 WARN("no names found\n");
1935 return DISP_E_UNKNOWNNAME
;
1938 /* ITypeInfo::Invoke
1940 * Invokes a method, or accesses a property of an object, that implements the
1941 * interface described by the type description.
1943 static HRESULT WINAPI
ITypeInfo_fnInvoke( LPTYPEINFO iface
, VOID
*pIUnk
,
1944 MEMBERID memid
, UINT16 dwFlags
, DISPPARAMS
*pDispParams
,
1945 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*pArgErr
)
1947 ICOM_THIS( TLBTypeInfo
, iface
);
1948 FIXME("(%p) stub!", This
);
1952 /* ITypeInfo::GetDocumentation
1954 * Retrieves the documentation string, the complete Help file name and path,
1955 * and the context ID for the Help topic for a specified type description.
1957 static HRESULT WINAPI
ITypeInfo_fnGetDocumentation( LPTYPEINFO iface
,
1958 MEMBERID memid
, BSTR
*pBstrName
, BSTR
*pBstrDocString
,
1959 DWORD
*pdwHelpContext
, BSTR
*pBstrHelpFile
)
1961 ICOM_THIS( TLBTypeInfo
, iface
);
1962 TLBFuncDesc
* pFDesc
;
1963 TLBVarDesc
* pVDesc
;
1964 TRACE("(%p) memid %ld Name(%p) DocString(%p)"
1965 " HelpContext(%p) HelpFile(%p)\n",
1966 This
, memid
, pBstrName
, pBstrDocString
, pdwHelpContext
, pBstrHelpFile
);
1967 if(memid
==MEMBERID_NIL
){ /* documentation for the typeinfo */
1969 *pBstrName
=TLB_DupAtoBstr(This
->Name
);
1971 *pBstrDocString
=TLB_DupAtoBstr(This
->DocString
);
1973 *pdwHelpContext
=This
->dwHelpContext
;
1975 *pBstrHelpFile
=TLB_DupAtoBstr(This
->DocString
);/* FIXME */
1977 }else {/* for a member */
1978 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
)
1979 if(pFDesc
->funcdesc
.memid
==memid
){
1982 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
)
1983 if(pVDesc
->vardesc
.memid
==memid
){
1987 return TYPE_E_ELEMENTNOTFOUND
;
1990 /* ITypeInfo::GetDllEntry
1992 * Retrieves a description or specification of an entry point for a function
1995 static HRESULT WINAPI
ITypeInfo_fnGetDllEntry( LPTYPEINFO iface
, MEMBERID memid
,
1996 INVOKEKIND invKind
, BSTR
*pBstrDllName
, BSTR
*pBstrName
,
1999 ICOM_THIS( TLBTypeInfo
, iface
);
2000 FIXME("(%p) stub!\n", This
);
2004 /* ITypeInfo::GetRefTypeInfo
2006 * If a type description references other type descriptions, it retrieves
2007 * the referenced type descriptions.
2009 static HRESULT WINAPI
ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO iface
,
2010 HREFTYPE hRefType
, ITypeInfo
* *ppTInfo
)
2012 ICOM_THIS( TLBTypeInfo
, iface
);
2014 if(HREFTYPE_INTHISFILE(hRefType
)){
2017 result
=This
->lpvtbl
->fnGetContainingTypeLib(iface
, &pTLib
,
2019 if(SUCCEEDED(result
)){
2020 result
=ITypeLib_GetTypeInfo(pTLib
,
2021 HREFTYPE_INDEX(hRefType
),
2023 ITypeLib_Release(pTLib
);
2026 /* imported type lib */
2027 TLBRefType
* pRefType
;
2028 TLBLibInfo
*pTypeLib
;
2029 for( pRefType
=This
->impltypelist
; pRefType
&&
2030 pRefType
->reference
!= hRefType
; pRefType
=pRefType
->next
)
2033 return TYPE_E_ELEMENTNOTFOUND
; /* FIXME : correct? */
2034 pTypeLib
=pRefType
->pImpTLInfo
->pImpTypeLib
;
2035 if(pTypeLib
) /* typelib already loaded */
2036 result
=ITypeLib_GetTypeInfoOfGuid(
2037 (LPTYPELIB
)pTypeLib
, &pRefType
->guid
, ppTInfo
);
2039 result
=LoadRegTypeLib( &pRefType
->pImpTLInfo
->guid
,
2041 (LPTYPELIB
*)&pTypeLib
);
2042 if(!SUCCEEDED(result
)){
2043 BSTR libnam
=TLB_DupAtoBstr(pRefType
->pImpTLInfo
->name
);
2044 result
=LoadTypeLib(libnam
, (LPTYPELIB
*)&pTypeLib
);
2045 SysFreeString(libnam
);
2047 if(SUCCEEDED(result
)){
2048 result
=ITypeLib_GetTypeInfoOfGuid(
2049 (LPTYPELIB
)pTypeLib
, &pRefType
->guid
, ppTInfo
);
2050 pRefType
->pImpTLInfo
->pImpTypeLib
=pTypeLib
;
2054 TRACE("(%p) hreftype 0x%04lx loaded %s (%p)\n", This
, hRefType
,
2055 SUCCEEDED(result
)? "SUCCESS":"FAILURE", *ppTInfo
);
2059 /* ITypeInfo::AddressOfMember
2061 * Retrieves the addresses of static functions or variables, such as those
2064 static HRESULT WINAPI
ITypeInfo_fnAddressOfMember( LPTYPEINFO iface
,
2065 MEMBERID memid
, INVOKEKIND invKind
, PVOID
*ppv
)
2067 ICOM_THIS( TLBTypeInfo
, iface
);
2068 FIXME("(%p) stub!\n", This
);
2072 /* ITypeInfo::CreateInstance
2074 * Creates a new instance of a type that describes a component object class
2077 static HRESULT WINAPI
ITypeInfo_fnCreateInstance( LPTYPEINFO iface
,
2078 IUnknown
*pUnk
, REFIID riid
, VOID
**ppvObj
)
2080 ICOM_THIS( TLBTypeInfo
, iface
);
2081 FIXME("(%p) stub!\n", This
);
2085 /* ITypeInfo::GetMops
2087 * Retrieves marshaling information.
2089 static HRESULT WINAPI
ITypeInfo_fnGetMops( LPTYPEINFO iface
, MEMBERID memid
,
2092 ICOM_THIS( TLBTypeInfo
, iface
);
2093 FIXME("(%p) stub!\n", This
);
2097 /* ITypeInfo::GetContainingTypeLib
2099 * Retrieves the containing type library and the index of the type description
2100 * within that type library.
2102 static HRESULT WINAPI
ITypeInfo_fnGetContainingTypeLib( LPTYPEINFO iface
,
2103 ITypeLib
* *ppTLib
, UINT
*pIndex
)
2105 ICOM_THIS( TLBTypeInfo
, iface
);
2106 *ppTLib
=(LPTYPELIB
)(This
->pTypeLib
);
2107 *pIndex
=This
->index
;
2108 ITypeLib_AddRef(*ppTLib
);
2109 TRACE("(%p) returns (%p) index %d!\n", This
, *ppTLib
, *pIndex
);
2113 /* ITypeInfo::ReleaseTypeAttr
2115 * Releases a TYPEATTR previously returned by GetTypeAttr.
2118 static HRESULT WINAPI
ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO iface
,
2119 TYPEATTR
* pTypeAttr
)
2121 ICOM_THIS( TLBTypeInfo
, iface
);
2122 TRACE("(%p)->(%p)\n", This
, pTypeAttr
);
2126 /* ITypeInfo::ReleaseFuncDesc
2128 * Releases a FUNCDESC previously returned by GetFuncDesc. *
2130 static HRESULT WINAPI
ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO iface
,
2131 FUNCDESC
*pFuncDesc
)
2133 ICOM_THIS( TLBTypeInfo
, iface
);
2134 TRACE("(%p)->(%p)\n", This
, pFuncDesc
);
2138 /* ITypeInfo::ReleaseVarDesc
2140 * Releases a VARDESC previously returned by GetVarDesc.
2142 static HRESULT WINAPI
ITypeInfo_fnReleaseVarDesc( LPTYPEINFO iface
,
2145 ICOM_THIS( TLBTypeInfo
, iface
);
2146 TRACE("(%p)->(%p)\n", This
, pVarDesc
);
2150 /* ITypeInfo2::GetTypeKind
2152 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
2155 static HRESULT WINAPI
ITypeInfo2_fnGetTypeKind( ITypeInfo
* iface
,
2156 TYPEKIND
*pTypeKind
)
2158 ICOM_THIS( TLBTypeInfo
, iface
);
2159 *pTypeKind
=This
->TypeAttr
.typekind
;
2160 TRACE("(%p) type 0x%0x\n", This
,*pTypeKind
);
2164 /* ITypeInfo2::GetTypeFlags
2166 * Returns the type flags without any allocations. This returns a DWORD type
2167 * flag, which expands the type flags without growing the TYPEATTR (type
2171 static HRESULT WINAPI
ITypeInfo2_fnGetTypeFlags( ITypeInfo
* iface
,
2174 ICOM_THIS( TLBTypeInfo
, iface
);
2175 *pTypeFlags
=This
->TypeAttr
.wTypeFlags
;
2176 TRACE("(%p) flags 0x%04x\n", This
,*pTypeFlags
);
2180 /* ITypeInfo2::GetFuncIndexOfMemId
2181 * Binds to a specific member based on a known DISPID, where the member name
2182 * is not known (for example, when binding to a default member).
2185 static HRESULT WINAPI
ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo
* iface
,
2186 MEMBERID memid
, INVOKEKIND invKind
, UINT
*pFuncIndex
)
2188 ICOM_THIS( TLBTypeInfo
, iface
);
2189 TLBFuncDesc
*pFuncInfo
;
2192 /* FIXME: should check for invKind??? */
2193 for(i
=0, pFuncInfo
=This
->funclist
;pFuncInfo
&&
2194 memid
!= pFuncInfo
->funcdesc
.memid
; i
++, pFuncInfo
=pFuncInfo
->next
);
2200 result
=E_INVALIDARG
;
2202 TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This
,
2203 memid
, invKind
, SUCCEEDED(result
)? "SUCCES":"FAILED");
2207 /* TypeInfo2::GetVarIndexOfMemId
2209 * Binds to a specific member based on a known DISPID, where the member name
2210 * is not known (for example, when binding to a default member).
2213 static HRESULT WINAPI
ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo
* iface
,
2214 MEMBERID memid
, UINT
*pVarIndex
)
2216 ICOM_THIS( TLBTypeInfo
, iface
);
2217 TLBVarDesc
*pVarInfo
;
2220 for(i
=0, pVarInfo
=This
->varlist
; pVarInfo
&&
2221 memid
!= pVarInfo
->vardesc
.memid
; i
++, pVarInfo
=pVarInfo
->next
)
2228 result
=E_INVALIDARG
;
2230 TRACE("(%p) memid 0x%08lx -> %s\n", This
,
2231 memid
, SUCCEEDED(result
)? "SUCCES":"FAILED");
2235 /* ITypeInfo2::GetCustData
2237 * Gets the custom data
2239 static HRESULT WINAPI
ITypeInfo2_fnGetCustData( ITypeInfo
* iface
,
2240 REFGUID guid
, VARIANT
*pVarVal
)
2242 ICOM_THIS( TLBTypeInfo
, iface
);
2243 TLBCustData
*pCData
;
2244 for(pCData
=This
->pCustData
; pCData
; pCData
= pCData
->next
)
2245 if( IsEqualIID(guid
, &pCData
->guid
)) break;
2246 if(TRACE_ON(typelib
)){
2248 WINE_StringFromCLSID((LPCLSID
)guid
,xriid
);
2249 TRACE("(%p) guid %s %s found!x)\n", This
, xriid
, pCData
? "" : "NOT");
2252 VariantInit( pVarVal
);
2253 VariantCopy( pVarVal
, &pCData
->data
);
2256 return E_INVALIDARG
; /* FIXME: correct? */
2259 /* ITypeInfo2::GetFuncCustData
2261 * Gets the custom data
2263 static HRESULT WINAPI
ITypeInfo2_fnGetFuncCustData( ITypeInfo
* iface
,
2264 UINT index
, REFGUID guid
, VARIANT
*pVarVal
)
2266 ICOM_THIS( TLBTypeInfo
, iface
);
2267 TLBCustData
*pCData
=NULL
;
2268 TLBFuncDesc
* pFDesc
;
2270 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++,
2271 pFDesc
=pFDesc
->next
)
2274 for(pCData
=pFDesc
->pCustData
; pCData
; pCData
= pCData
->next
)
2275 if( IsEqualIID(guid
, &pCData
->guid
)) break;
2276 if(TRACE_ON(typelib
)){
2278 WINE_StringFromCLSID((LPCLSID
)guid
,xriid
);
2279 TRACE("(%p) guid %s %s found!x)\n", This
, xriid
, pCData
? "" : "NOT");
2282 VariantInit( pVarVal
);
2283 VariantCopy( pVarVal
, &pCData
->data
);
2286 return E_INVALIDARG
; /* FIXME: correct? */
2289 /* ITypeInfo2::GetParamCustData
2291 * Gets the custom data
2293 static HRESULT WINAPI
ITypeInfo2_fnGetParamCustData( ITypeInfo
* iface
,
2294 UINT indexFunc
, UINT indexParam
, REFGUID guid
, VARIANT
*pVarVal
)
2296 ICOM_THIS( TLBTypeInfo
, iface
);
2297 TLBCustData
*pCData
=NULL
;
2298 TLBFuncDesc
* pFDesc
;
2300 for(i
=0, pFDesc
=This
->funclist
; i
!=indexFunc
&& pFDesc
; i
++,
2301 pFDesc
=pFDesc
->next
)
2303 if(pFDesc
&& indexParam
>=0 && indexParam
<pFDesc
->funcdesc
.cParams
)
2304 for(pCData
=pFDesc
->pParamDesc
[indexParam
].pCustData
; pCData
;
2305 pCData
= pCData
->next
)
2306 if( IsEqualIID(guid
, &pCData
->guid
)) break;
2307 if(TRACE_ON(typelib
)){
2309 WINE_StringFromCLSID((LPCLSID
)guid
,xriid
);
2310 TRACE("(%p) guid %s %s found!x)\n", This
, xriid
, pCData
? "" : "NOT");
2313 VariantInit( pVarVal
);
2314 VariantCopy( pVarVal
, &pCData
->data
);
2317 return E_INVALIDARG
; /* FIXME: correct? */
2320 /* ITypeInfo2::GetVarcCustData
2322 * Gets the custom data
2324 static HRESULT WINAPI
ITypeInfo2_fnGetVarCustData( ITypeInfo
* iface
,
2325 UINT index
, REFGUID guid
, VARIANT
*pVarVal
)
2327 ICOM_THIS( TLBTypeInfo
, iface
);
2328 TLBCustData
*pCData
=NULL
;
2329 TLBVarDesc
* pVDesc
;
2331 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++,
2332 pVDesc
=pVDesc
->next
)
2335 for(pCData
=pVDesc
->pCustData
; pCData
; pCData
= pCData
->next
)
2336 if( IsEqualIID(guid
, &pCData
->guid
)) break;
2337 if(TRACE_ON(typelib
)){
2339 WINE_StringFromCLSID((LPCLSID
)guid
,xriid
);
2340 TRACE("(%p) guid %s %s found!x)\n", This
, xriid
, pCData
? "" : "NOT");
2343 VariantInit( pVarVal
);
2344 VariantCopy( pVarVal
, &pCData
->data
);
2347 return E_INVALIDARG
; /* FIXME: correct? */
2350 /* ITypeInfo2::GetImplcCustData
2352 * Gets the custom data
2354 static HRESULT WINAPI
ITypeInfo2_fnGetImplTypeCustData( ITypeInfo
* iface
,
2355 UINT index
, REFGUID guid
, VARIANT
*pVarVal
)
2357 ICOM_THIS( TLBTypeInfo
, iface
);
2358 TLBCustData
*pCData
=NULL
;
2359 TLBRefType
* pRDesc
;
2361 for(i
=0, pRDesc
=This
->impltypelist
; i
!=index
&& pRDesc
; i
++,
2362 pRDesc
=pRDesc
->next
)
2365 for(pCData
=pRDesc
->pCustData
; pCData
; pCData
= pCData
->next
)
2366 if( IsEqualIID(guid
, &pCData
->guid
)) break;
2367 if(TRACE_ON(typelib
)){
2369 WINE_StringFromCLSID((LPCLSID
)guid
,xriid
);
2370 TRACE("(%p) guid %s %s found!x)\n", This
, xriid
, pCData
? "" : "NOT");
2373 VariantInit( pVarVal
);
2374 VariantCopy( pVarVal
, &pCData
->data
);
2377 return E_INVALIDARG
; /* FIXME: correct? */
2380 /* ITypeInfo2::GetDocumentation2
2382 * Retrieves the documentation string, the complete Help file name and path,
2383 * the localization context to use, and the context ID for the library Help
2384 * topic in the Help file.
2387 static HRESULT WINAPI
ITypeInfo2_fnGetDocumentation2( ITypeInfo
* iface
,
2388 MEMBERID memid
, LCID lcid
, BSTR
*pbstrHelpString
,
2389 INT
*pdwHelpStringContext
, BSTR
*pbstrHelpStringDll
)
2391 ICOM_THIS( TLBTypeInfo
, iface
);
2392 TLBFuncDesc
* pFDesc
;
2393 TLBVarDesc
* pVDesc
;
2394 TRACE("(%p) memid %ld lcid(0x%lx) HelpString(%p) "
2395 "HelpStringContext(%p) HelpStringDll(%p)\n",
2396 This
, memid
, lcid
, pbstrHelpString
, pdwHelpStringContext
,
2397 pbstrHelpStringDll
);
2398 /* the help string should be obtained from the helpstringdll,
2399 * using the _DLLGetDocumentation function, based on the supplied
2400 * lcid. Nice to do sometime...
2402 if(memid
==MEMBERID_NIL
){ /* documentation for the typeinfo */
2404 *pbstrHelpString
=TLB_DupAtoBstr(This
->Name
);
2405 if(pdwHelpStringContext
)
2406 *pdwHelpStringContext
=This
->dwHelpStringContext
;
2407 if(pbstrHelpStringDll
)
2408 *pbstrHelpStringDll
=
2409 TLB_DupAtoBstr(This
->pTypeLib
->HelpStringDll
);/* FIXME */
2411 }else {/* for a member */
2412 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
)
2413 if(pFDesc
->funcdesc
.memid
==memid
){
2415 *pbstrHelpString
=TLB_DupAtoBstr(pFDesc
->HelpString
);
2416 if(pdwHelpStringContext
)
2417 *pdwHelpStringContext
=pFDesc
->HelpStringContext
;
2418 if(pbstrHelpStringDll
)
2419 *pbstrHelpStringDll
=
2420 TLB_DupAtoBstr(This
->pTypeLib
->HelpStringDll
);/* FIXME */
2423 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
)
2424 if(pVDesc
->vardesc
.memid
==memid
){
2426 *pbstrHelpString
=TLB_DupAtoBstr(pVDesc
->HelpString
);
2427 if(pdwHelpStringContext
)
2428 *pdwHelpStringContext
=pVDesc
->HelpStringContext
;
2429 if(pbstrHelpStringDll
)
2430 *pbstrHelpStringDll
=
2431 TLB_DupAtoBstr(This
->pTypeLib
->HelpStringDll
);/* FIXME */
2435 return TYPE_E_ELEMENTNOTFOUND
;
2438 /* ITypeInfo2::GetAllCustData
2440 * Gets all custom data items for the Type info.
2443 static HRESULT WINAPI
ITypeInfo2_fnGetAllCustData( ITypeInfo
* iface
,
2444 CUSTDATA
*pCustData
)
2446 ICOM_THIS( TLBTypeInfo
, iface
);
2447 TLBCustData
*pCData
;
2449 TRACE("(%p) returning %d items\n", This
, This
->ctCustData
);
2450 pCustData
->prgCustData
= TLB_Alloc(This
->ctCustData
* sizeof(CUSTDATAITEM
));
2451 if(pCustData
->prgCustData
){
2452 pCustData
->cCustData
=This
->ctCustData
;
2453 for(i
=0, pCData
=This
->pCustData
; pCData
; i
++, pCData
= pCData
->next
){
2454 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
2455 VariantCopy(& pCustData
->prgCustData
[i
].varValue
, & pCData
->data
);
2458 ERR(" OUT OF MEMORY! \n");
2459 return E_OUTOFMEMORY
;
2464 /* ITypeInfo2::GetAllFuncCustData
2466 * Gets all custom data items for the specified Function
2469 static HRESULT WINAPI
ITypeInfo2_fnGetAllFuncCustData( ITypeInfo
* iface
,
2470 UINT index
, CUSTDATA
*pCustData
)
2472 ICOM_THIS( TLBTypeInfo
, iface
);
2473 TLBCustData
*pCData
;
2474 TLBFuncDesc
* pFDesc
;
2476 TRACE("(%p) index %d\n", This
, index
);
2477 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++,
2478 pFDesc
=pFDesc
->next
)
2481 pCustData
->prgCustData
=
2482 TLB_Alloc(pFDesc
->ctCustData
* sizeof(CUSTDATAITEM
));
2483 if(pCustData
->prgCustData
){
2484 pCustData
->cCustData
=pFDesc
->ctCustData
;
2485 for(i
=0, pCData
=pFDesc
->pCustData
; pCData
; i
++,
2486 pCData
= pCData
->next
){
2487 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
2488 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
2492 ERR(" OUT OF MEMORY! \n");
2493 return E_OUTOFMEMORY
;
2497 return TYPE_E_ELEMENTNOTFOUND
;
2500 /* ITypeInfo2::GetAllParamCustData
2502 * Gets all custom data items for the Functions
2505 static HRESULT WINAPI
ITypeInfo2_fnGetAllParamCustData( ITypeInfo
* iface
,
2506 UINT indexFunc
, UINT indexParam
, CUSTDATA
*pCustData
)
2508 ICOM_THIS( TLBTypeInfo
, iface
);
2509 TLBCustData
*pCData
=NULL
;
2510 TLBFuncDesc
* pFDesc
;
2512 TRACE("(%p) index %d\n", This
, indexFunc
);
2513 for(i
=0, pFDesc
=This
->funclist
; i
!=indexFunc
&& pFDesc
; i
++,
2514 pFDesc
=pFDesc
->next
)
2516 if(pFDesc
&& indexParam
>=0 && indexParam
<pFDesc
->funcdesc
.cParams
){
2517 pCustData
->prgCustData
=
2518 TLB_Alloc(pFDesc
->pParamDesc
[indexParam
].ctCustData
*
2519 sizeof(CUSTDATAITEM
));
2520 if(pCustData
->prgCustData
){
2521 pCustData
->cCustData
=pFDesc
->pParamDesc
[indexParam
].ctCustData
;
2522 for(i
=0, pCData
=pFDesc
->pParamDesc
[indexParam
].pCustData
;
2523 pCData
; i
++, pCData
= pCData
->next
){
2524 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
2525 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
2529 ERR(" OUT OF MEMORY! \n");
2530 return E_OUTOFMEMORY
;
2534 return TYPE_E_ELEMENTNOTFOUND
;
2537 /* ITypeInfo2::GetAllVarCustData
2539 * Gets all custom data items for the specified Variable
2542 static HRESULT WINAPI
ITypeInfo2_fnGetAllVarCustData( ITypeInfo
* iface
,
2543 UINT index
, CUSTDATA
*pCustData
)
2545 ICOM_THIS( TLBTypeInfo
, iface
);
2546 TLBCustData
*pCData
;
2547 TLBVarDesc
* pVDesc
;
2549 TRACE("(%p) index %d\n", This
, index
);
2550 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++,
2551 pVDesc
=pVDesc
->next
)
2554 pCustData
->prgCustData
=
2555 TLB_Alloc(pVDesc
->ctCustData
* sizeof(CUSTDATAITEM
));
2556 if(pCustData
->prgCustData
){
2557 pCustData
->cCustData
=pVDesc
->ctCustData
;
2558 for(i
=0, pCData
=pVDesc
->pCustData
; pCData
; i
++,
2559 pCData
= pCData
->next
){
2560 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
2561 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
2565 ERR(" OUT OF MEMORY! \n");
2566 return E_OUTOFMEMORY
;
2570 return TYPE_E_ELEMENTNOTFOUND
;
2573 /* ITypeInfo2::GetAllImplCustData
2575 * Gets all custom data items for the specified implementation type
2578 static HRESULT WINAPI
ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo
* iface
,
2579 UINT index
, CUSTDATA
*pCustData
)
2581 ICOM_THIS( TLBTypeInfo
, iface
);
2582 TLBCustData
*pCData
;
2583 TLBRefType
* pRDesc
;
2585 TRACE("(%p) index %d\n", This
, index
);
2586 for(i
=0, pRDesc
=This
->impltypelist
; i
!=index
&& pRDesc
; i
++,
2587 pRDesc
=pRDesc
->next
)
2590 pCustData
->prgCustData
=
2591 TLB_Alloc(pRDesc
->ctCustData
* sizeof(CUSTDATAITEM
));
2592 if(pCustData
->prgCustData
){
2593 pCustData
->cCustData
=pRDesc
->ctCustData
;
2594 for(i
=0, pCData
=pRDesc
->pCustData
; pCData
; i
++,
2595 pCData
= pCData
->next
){
2596 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
2597 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
2601 ERR(" OUT OF MEMORY! \n");
2602 return E_OUTOFMEMORY
;
2606 return TYPE_E_ELEMENTNOTFOUND
;