Added DECL_GLOBAL_CONSTRUCTOR macro.
[wine/multimedia.git] / dlls / oleaut32 / typelib.c
blob94983a8aec1a039daff4a136beb1abb67a5b21b0
1 /*
2 * TYPELIB
4 * Copyright 1997 Marcus Meissner
5 * 1999 Rein Klazes
6 * there is much left to do here before it can be useful for real world
7 * programs
8 * know problems:
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
17 * behaviour.
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.
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdio.h>
30 #include <assert.h>
31 #include "winerror.h"
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) */
35 #include "heap.h"
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 ;
42 #include "typelib.h"
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 */
49 TLBSegDir * pTblDir;
50 TLBLibInfo* pLibInfo;
51 } TLBContext;
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\"
60 * RETURNS
61 * path of typelib
63 HRESULT WINAPI
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 */
70 ) {
71 char xguid[80];
72 char typelibkey[100],pathname[260];
73 DWORD plen;
75 if (HIWORD(guid)) {
76 WINE_StringFromCLSID(guid,xguid);
77 sprintf(typelibkey,"SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%lx\\win16",
78 xguid,wMaj,wMin,lcid
80 } else {
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);
83 return E_FAIL;
85 plen = sizeof(pathname);
86 if (RegQueryValue16(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
87 /* try again without lang specific id */
88 if (SUBLANGID(lcid))
89 return QueryPathOfRegTypeLib16(guid,wMaj,wMin,PRIMARYLANGID(lcid),path);
90 FIXME("key %s not found\n",typelibkey);
91 return E_FAIL;
93 *path = SysAllocString16(pathname);
94 return S_OK;
97 /****************************************************************************
98 * QueryPathOfRegTypeLib [OLEAUT32.164]
99 * RETURNS
100 * path of typelib
102 HRESULT WINAPI
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 */
110 char xguid[80];
111 char typelibkey[100],pathname[260];
112 DWORD plen;
115 if (HIWORD(guid)) {
116 WINE_StringFromCLSID(guid,xguid);
117 sprintf(typelibkey,"SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%lx\\win32",
118 xguid,wMaj,wMin,lcid
120 } else {
121 sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
122 FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n",xguid,wMaj,wMin,(DWORD)lcid,path);
123 return E_FAIL;
125 plen = sizeof(pathname);
126 if (RegQueryValue16(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
127 /* try again without lang specific id */
128 if (SUBLANGID(lcid))
129 return QueryPathOfRegTypeLib(guid,wMaj,wMin,PRIMARYLANGID(lcid),path);
130 FIXME("key %s not found\n",typelibkey);
131 return E_FAIL;
133 *path = HEAP_strdupAtoW(GetProcessHeap(),0,pathname);
134 return S_OK;
137 /******************************************************************************
138 * LoadTypeLib [TYPELIB.3] Loads and registers a type library
139 * NOTES
140 * Docs: OLECHAR FAR* szFile
141 * Docs: iTypeLib FAR* FAR* pptLib
143 * RETURNS
144 * Success: S_OK
145 * Failure: Status
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);
153 if (pptLib!=0)
154 *pptLib=0;
156 return E_FAIL;
159 /******************************************************************************
160 * LoadTypeLib [OLEAUT32.161]
161 * Loads and registers a type library
162 * NOTES
163 * Docs: OLECHAR FAR* szFile
164 * Docs: iTypeLib FAR* FAR* pptLib
166 * RETURNS
167 * Success: S_OK
168 * Failure: Status
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
182 * RETURNS
183 * Success: S_OK
184 * Failure: Status
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 */
191 LPSTR p;
192 HRESULT res;
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);
205 return 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 */
218 BSTR bstr=NULL;
219 HRESULT res=QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor,
220 lcid, &bstr);
221 if(SUCCEEDED(res)){
222 res= LoadTypeLib(bstr, ppTLib);
223 SysFreeString(bstr);
225 if(TRACE_ON(typelib)){
226 char xriid[50];
227 WINE_StringFromCLSID((LPCLSID)rguid,xriid);
228 TRACE("(IID: %s) load %s (%p)\n",xriid,
229 SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);
231 return res;
235 /******************************************************************************
236 * RegisterTypeLib [OLEAUT32.163]
237 * Adds information about a type library to the System Registry
238 * NOTES
239 * Docs: ITypeLib FAR * ptlib
240 * Docs: OLECHAR FAR* szFullPath
241 * Docs: OLECHAR FAR* szHelpDir
243 * RETURNS
244 * Success: S_OK
245 * Failure: Status
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,
251 may be NULL*/
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
260 * NOTES
262 * RETURNS
263 * Success: S_OK
264 * Failure: Status
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 */
271 SYSKIND syskind)
273 char xriid[50];
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
286 * OLE 2.03 23 730
287 * OLE 2.03 03 3025
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())
297 case WIN31:
298 return MAKELONG(3027, 3); /* WfW 3.11 */
299 case WIN95:
300 return MAKELONG(700, 23); /* Win95A */
301 case WIN98:
302 return MAKELONG(3024, 10); /* W98 SE */
303 default:
304 FIXME_(ole)("Version value not known yet. Please investigate it !");
305 return 0;
309 /* for better debugging info leave the static out for the time being */
310 #define static
312 /*=======================Itypelib methods ===============================*/
313 /* ITypeLib methods */
314 static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid,
315 VOID **ppvObject);
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,
323 TYPEKIND *pTKind);
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,
348 VARIANT *pVarVal);
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,
362 ITypeLib_fnAddRef,
363 ITypeLib_fnRelease,
364 ITypeLib_fnGetTypeInfoCount,
365 ITypeLib_fnGetTypeInfo,
366 ITypeLib_fnGetTypeInfoType,
367 ITypeLib_fnGetTypeInfoOfGuid,
368 ITypeLib_fnGetLibAttr,
369 ITypeLib_fnGetTypeComp,
370 ITypeLib_fnGetDocumentation,
371 ITypeLib_fnIsName,
372 ITypeLib_fnFindName,
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,
382 VOID **ppvObject);
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,
432 BSTR *pBstrMops);
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,
445 VARDESC *pVarDesc);
446 /* itypeinfo2 methods */
447 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo * This,
448 TYPEKIND *pTypeKind);
449 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo * This,
450 UINT *pTypeFlags);
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,
482 ITypeInfo_fnAddRef,
483 ITypeInfo_fnRelease,
484 ITypeInfo_fnGetTypeAttr,
485 ITypeInfo_fnGetTypeComp,
486 ITypeInfo_fnGetFuncDesc,
487 ITypeInfo_fnGetVarDesc,
488 ITypeInfo_fnGetNames,
489 ITypeInfo_fnGetRefTypeOfImplType,
490 ITypeInfo_fnGetImplTypeFlags,
491 ITypeInfo_fnGetIDsOfNames,
492 ITypeInfo_fnInvoke,
493 ITypeInfo_fnGetDocumentation,
494 ITypeInfo_fnGetDllEntry,
495 ITypeInfo_fnGetRefTypeInfo,
496 ITypeInfo_fnAddressOfMember,
497 ITypeInfo_fnCreateInstance,
498 ITypeInfo_fnGetMops,
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},
530 {{0},30},{{0},31}};
532 static void TLB_abort()
534 DebugBreak();
536 static void * TLB_Alloc(unsigned size)
538 void * ret;
539 if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){
540 /* FIXME */
541 ERR("cannot allocate memory\n");
543 return ret;
546 /* candidate for a more global appearance... */
547 static BSTR TLB_DupAtoBstr(PCHAR Astr)
549 int len;
550 BSTR bstr;
551 DWORD *pdw ;
552 if(!Astr)
553 return NULL;
554 len=strlen(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);
560 return bstr;
563 static void TLB_Free(void * ptr)
565 HeapFree(GetProcessHeap(), 0, ptr);
567 /* read function */
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)
575 /* FIXME */
576 ERR("seek beyond end (%ld/%d)\n", where, pcx->length );
577 TLB_abort();
579 pcx->pos = where;
581 if (pcx->pos + count > pcx->length) count = pcx->length - pcx->pos;
582 memcpy( buffer, (char *)pcx->mapping + pcx->pos, count );
583 pcx->pos += count;
584 return 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));
591 return;
593 TLB_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset );
596 PCHAR TLB_ReadName( TLBContext *pcx, int offset)
598 char * name;
599 TLBNameIntro niName;
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';
606 return name;
608 PCHAR TLB_ReadString( TLBContext *pcx, int offset)
610 char * string;
611 INT16 length;
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);
617 string[length]='\0';
618 return string;
621 * read a value and fill a VARIANT structure
623 static void TLB_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
625 int size;
626 if(offset <0) { /* data is packed in here */
627 pVar->vt = (offset & 0x7c000000 )>> 26;
628 V_UNION(pVar, iVal) = offset & 0xffff;
629 return;
631 TLB_Read(&(pVar->vt), sizeof(VARTYPE), pcx,
632 pcx->pTblDir->pCustData.offset + offset );
633 switch(pVar->vt){
634 case VT_EMPTY: /* FIXME: is this right? */
635 case VT_NULL: /* FIXME: is this right? */
636 case VT_I2 : /* this should not happen */
637 case VT_I4 :
638 case VT_R4 :
639 case VT_ERROR :
640 case VT_BOOL :
641 case VT_I1 :
642 case VT_UI1 :
643 case VT_UI2 :
644 case VT_UI4 :
645 case VT_INT :
646 case VT_UINT :
647 case VT_VOID : /* FIXME: is this right? */
648 case VT_HRESULT :
649 size=4; break;
650 case VT_R8 :
651 case VT_CY :
652 case VT_DATE :
653 case VT_I8 :
654 case VT_UI8 :
655 case VT_DECIMAL : /* FIXME: is this right? */
656 case VT_FILETIME :
657 size=8;break;
658 /* pointer types with known behaviour */
659 case VT_BSTR :{
660 char * ptr;
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];
668 TLB_Free(ptr);
670 size=-4; break;
671 /* FIXME: this will not work AT ALL when the variant contains a pointer */
672 case VT_DISPATCH :
673 case VT_VARIANT :
674 case VT_UNKNOWN :
675 case VT_PTR :
676 case VT_SAFEARRAY :
677 case VT_CARRAY :
678 case VT_USERDEFINED :
679 case VT_LPSTR :
680 case VT_LPWSTR :
681 case VT_BLOB :
682 case VT_STREAM :
683 case VT_STORAGE :
684 case VT_STREAMED_OBJECT :
685 case VT_STORED_OBJECT :
686 case VT_BLOB_OBJECT :
687 case VT_CF :
688 case VT_CLSID :
689 default:
690 size=0;
691 FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
692 pVar->vt);
695 if(size>0) /* (big|small) endian correct? */
696 TLB_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK );
697 return ;
700 * create a linked list with custom data
702 static int TLB_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
704 TLBCDGuid entry;
705 TLBCustData* pNew;
706 int count=0;
707 while(offset >=0){
708 count++;
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;
716 *ppCustData=pNew;
717 offset = entry.next;
719 return count;
722 static void TLB_GetTdesc(TLBContext *pcx, INT type,TYPEDESC * pTd )
724 if(type <0)
725 pTd->vt=type & VT_TYPEMASK;
726 else
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
741 * length word).
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
748 * for each member;
750 * Third is a equal sized array with file offsets to the name entry
751 * of each member.
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;
758 char recbuf[512];
759 TLBFuncRecord * pFuncRec=(TLBFuncRecord *) recbuf;
760 int i, j;
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);
771 reclength &=0x1ff;
772 TLB_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
773 /* do the attributes */
774 nrattributes=(reclength-pFuncRec->nrargs*3*sizeof(int)-0x18)
775 /sizeof(int);
776 if(nrattributes>0){
777 (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
778 if(nrattributes>1){
779 (*pptfd)->HelpString = TLB_ReadString(pcx,
780 pFuncRec->OptAttr[1]) ;
781 if(nrattributes>2){
782 if(pFuncRec->FKCCIC & 0x2000)
783 (*pptfd)->Entry = (char *) pFuncRec->OptAttr[2] ;
784 else
785 (*pptfd)->Entry = TLB_ReadString(pcx,
786 pFuncRec->OptAttr[2]);
787 if(nrattributes>5 )
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 *
815 sizeof(TLBParDesc));
817 TLB_Read(&paraminfo,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(&paraminfo,sizeof(TLBParameterInfo), pcx,
826 DO_NOT_SEEK);
828 /* second time around */
829 for(j=0;j<pFuncRec->nrargs;j++){
830 /* name */
831 (*pptfd)->pParamDesc[j].Name=
832 TLB_ReadName(pcx, (int)(*pptfd)->pParamDesc[j].Name);
833 /* default value */
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),
844 pInt[j], pcx);
846 /* custom info */
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;
863 char recbuf[256];
864 TLBVarRecord * pVarRec=(TLBVarRecord *) recbuf;
865 int i;
866 int recoffset;
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);
879 reclength &=0xff;
880 TLB_Read(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
881 /* Optional data */
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);
901 }else
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
910 * */
911 static void TLB_DoRefType(TLBContext *pcx,
912 int offset, TLBRefType ** pprtd)
914 int j;
915 if(!HREFTYPE_INTHISFILE( offset)) {
916 /* external typelib */
917 TLBImpInfo impinfo;
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;
925 if(pImpLib){
926 (*pprtd)->reference=offset;
927 (*pprtd)->pImpTLInfo=pImpLib;
928 TLB_ReadGuid(&(*pprtd)->guid, impinfo.oGuid, pcx);
929 }else{
930 ERR("Cannot find a reference\n");
931 (*pprtd)->reference=-1;
932 (*pprtd)->pImpTLInfo=(void *)-1;
934 }else{
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)
945 int i;
946 TLBRefRecord refrec;
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);
955 offset=refrec.onext;
956 pprtd=&((*pprtd)->next);
960 * process a typeinfo record
962 TLBTypeInfo * TLB_DoTypeInfo(TLBContext *pcx, int count, TLBLibInfo* pLibInfo)
964 TLBTypeInfoBase tiBase;
965 TLBTypeInfo *ptiRet;
966 ptiRet=TLB_Alloc(sizeof(TLBTypeInfo));
967 ptiRet->lpvtbl = &tinfvt;
968 ptiRet->ref=1;
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;
973 ptiRet->index=count;
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) ;
993 /* FIXME: */
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);
999 /* help info */
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 :(
1006 /* functions */
1007 if(ptiRet->TypeAttr.cFuncs >0 )
1008 TLB_DoFuncs(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
1009 tiBase.memoffset, & ptiRet->funclist);
1010 /* variables */
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);
1023 ptiRet->ctCustData=
1024 TLB_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData);
1025 return ptiRet;
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' */
1035 long ret=0,found=0;
1036 int count;
1037 char *pChr;
1039 #define LOOK_FOR_MAGIC(magic) \
1040 count=TLB_Read(buff, TLBBUFSZ, pcx, 0); \
1041 do { \
1042 buff[count]='\0'; \
1043 pChr = buff; \
1044 while (pChr) { \
1045 pChr = memchr(pChr,magic[0],count-(pChr-buff));\
1046 if (pChr) { \
1047 if (!memcmp(pChr,magic,4)) { \
1048 ret+= pChr-buff; \
1049 found = 1; \
1050 break; \
1052 pChr++; \
1055 if (found) break; \
1056 ret+=count; \
1057 count=TLB_Read(buff, TLBBUFSZ, pcx, DO_NOT_SEEK);\
1058 } while(count>0);
1061 LOOK_FOR_MAGIC(TLBMAGIC2);
1062 if(count)
1063 return ret;
1065 LOOK_FOR_MAGIC(TLBMAGIC1);
1066 if(count)
1067 ERR("type library format not (yet) implemented\n");
1068 else
1069 ERR("not type library found in this file\n");
1070 return -1;
1072 #undef LOOK_FOR_MAGIC
1074 int TLB_ReadTypeLib(PCHAR file, ITypeLib **ppTypeLib)
1076 TLBContext cx;
1077 OFSTRUCT ofStruct;
1078 long oStart,lPSegDir;
1079 TLBLibInfo* pLibInfo=NULL;
1080 TLB2Header tlbHeader;
1081 TLBSegDir tlbSegDir;
1083 HANDLE hFile, hMap;
1084 if((hFile=OpenFile(file, &ofStruct, OF_READ))==HFILE_ERROR) {
1085 ERR("cannot open %s error 0x%lx\n",file, GetLastError());
1086 return E_FAIL;
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());
1093 return E_FAIL;
1095 CloseHandle( hFile );
1096 cx.mapping = MapViewOfFile( hMap, FILE_MAP_READ, 0, 0, 0 );
1097 CloseHandle( hMap );
1098 if (!cx.mapping)
1100 ERR("cannot map view of %s error 0x%lx\n",file, GetLastError());
1101 return E_FAIL;
1103 /* get pointer to beginning of typelib data */
1104 cx.pos = 0;
1105 cx.oStart=0;
1106 if((oStart=TLB_FindTlb(&cx))<0){
1107 if(oStart==-1)
1108 ERR("cannot locate typelib in %s\n",file);
1109 else
1110 ERR("unsupported typelib format in %s\n",file);
1111 UnmapViewOfFile( cx.mapping );
1112 return E_FAIL;
1114 cx.oStart=oStart;
1115 pLibInfo=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TLBLibInfo));
1116 if (!pLibInfo){
1117 UnmapViewOfFile( cx.mapping );
1118 return E_OUTOFMEMORY;
1120 pLibInfo->lpvtbl = &tlbvt;
1121 pLibInfo->ref=1;
1122 cx.pLibInfo=pLibInfo;
1123 /* read header */
1124 TLB_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
1125 /* there is a small number of information here until the next important
1126 * part:
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 );
1140 return E_FAIL;
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);
1152 /* help info */
1153 pLibInfo->DocString=TLB_ReadString(&cx, tlbHeader.helpstring);
1154 pLibInfo->HelpFile=TLB_ReadString(&cx, tlbHeader.helpfile);
1155 if( tlbHeader.varflags & HELPDLLFLAG){
1156 int offset;
1157 TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
1158 pLibInfo->HelpStringDll=TLB_ReadString(&cx, offset);
1161 pLibInfo->dwHelpContext=tlbHeader.helpstringcontext;
1162 /* custom data */
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));
1170 INT16 td[4];
1171 pLibInfo->pTypeDesc=
1172 TLB_Alloc( cTD * sizeof(TYPEDESC));
1173 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
1174 for(i=0;i<cTD;){
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 */
1178 if(td[3]<0)
1179 V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
1180 & stndTypeDesc[td[2]];
1181 else
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 */
1193 for(i=0;i<cTD;i++){
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));
1200 if(td[1]<0)
1201 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem.vt=td[0] & VT_TYPEMASK;
1202 else
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);
1212 }else{
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;
1222 int oGuid;
1223 UINT16 size;
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)));
1231 size >>=2;
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;
1239 /* type info's */
1240 if(tlbHeader.nrtypeinfos >=0 ){
1241 /*pLibInfo->TypeInfoCount=tlbHeader.nrtypeinfos; */
1242 TLBTypeInfo **ppTI=&(pLibInfo->pTypeInfo);
1243 int i;
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;
1253 return S_OK;
1256 /*================== ITypeLib(2) Methods ===================================*/
1258 /* ITypeLib::QueryInterface
1260 static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid,
1261 VOID **ppvObject)
1263 if(TRACE_ON(typelib)){
1264 char xriid[50];
1265 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1266 TRACE("(%p)->(IID: %s)\n",This,xriid);
1268 *ppvObject=NULL;
1269 if(IsEqualIID(riid, &IID_IUnknown) ||
1270 IsEqualIID(riid,&IID_ITypeLib)||
1271 IsEqualIID(riid,&IID_ITypeLib2))
1272 *ppvObject = This;
1273 if(*ppvObject){
1274 ITypeLib_AddRef(This);
1275 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1276 return S_OK;
1278 TRACE("-- Interface: E_NOINTERFACE\n");
1279 return E_NOINTERFACE;
1282 /* ITypeLib::AddRef
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);
1297 (This->ref)--;
1298 return S_OK;
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)
1319 int i;
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;
1325 if(*ppTLBTInfo){
1326 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
1327 TRACE("-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
1328 return S_OK;
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,
1339 TYPEKIND *pTKind)
1341 int i;
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;
1347 if(pTInfo){
1348 *pTKind=pTInfo->TypeAttr.typekind;
1349 TRACE("-- found Type (%p)->%d\n",pTKind,*pTKind);
1350 return S_OK;
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)
1364 int i;
1365 ICOM_THIS( TLBLibInfo, iface);
1366 TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo;
1367 if(TRACE_ON(typelib)){
1368 char xriid[50];
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;
1375 if(*ppTLBTInfo){
1376 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
1377 TRACE("-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
1378 return S_OK;
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;
1396 return S_OK;
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);
1410 return E_NOTIMPL;
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
1417 * file.
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);
1425 HRESULT result;
1426 ITypeInfo *pTInfo;
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 */
1431 if(pBstrName)
1432 *pBstrName=TLB_DupAtoBstr(This->Name);
1433 if(pBstrDocString)
1434 *pBstrName=TLB_DupAtoBstr(This->DocString);
1435 if(pdwHelpContext)
1436 *pdwHelpContext=This->dwHelpContext;
1437 if(pBstrHelpFile)
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))
1447 return result;
1449 return S_OK;
1452 /* ITypeLib::IsName
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;
1464 TLBVarDesc *pVInfo;
1465 int i;
1466 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1467 *pfName=TRUE;
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;
1481 *pfName=FALSE;
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 );
1488 return S_OK;
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;
1503 TLBVarDesc *pVInfo;
1504 int i,j = 0;
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;
1516 continue;
1517 ITypeLib_fnFindName_exit:
1518 pTInfo->lpvtbl->fnAddRef((LPTYPEINFO)pTInfo);
1519 ppTInfo[j]=(LPTYPEINFO)pTInfo;
1520 j++;
1522 TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
1523 This, *pcFound, debugstr_a(astr), j);
1525 *pcFound=j;
1527 HeapFree( GetProcessHeap(), 0, astr );
1528 return S_OK;
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);
1540 /* nothing to do */
1543 /* ITypeLib2::GetCustData
1545 * gets the custom data
1547 static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLib * iface, REFGUID guid,
1548 VARIANT *pVarVal)
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)){
1555 char xriid[50];
1556 WINE_StringFromCLSID((LPCLSID)guid,xriid);
1557 TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
1559 if(pCData){
1560 VariantInit( pVarVal);
1561 VariantCopy( pVarVal, &pCData->data);
1562 return S_OK;
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;
1580 return S_OK;
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);
1595 HRESULT result;
1596 ITypeInfo *pTInfo;
1597 FIXME("(%p) index %d lcid %ld half implemented stub!\n", This,
1598 index, lcid);
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 */
1604 if(pbstrHelpString)
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))
1618 return result;
1620 return S_OK;
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;
1633 int i;
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);
1642 }else{
1643 ERR(" OUT OF MEMORY! \n");
1644 return E_OUTOFMEMORY;
1646 return S_OK;
1650 /*================== ITypeInfo(2) Methods ===================================*/
1652 /* ITypeInfo::QueryInterface
1654 static HRESULT WINAPI ITypeInfo_fnQueryInterface( LPTYPEINFO iface, REFIID riid,
1655 VOID **ppvObject)
1657 ICOM_THIS( TLBTypeInfo, iface);
1658 if(TRACE_ON(typelib)){
1659 char xriid[50];
1660 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1661 TRACE("(%p)->(IID: %s)\n",This,xriid);
1663 *ppvObject=NULL;
1664 if(IsEqualIID(riid, &IID_IUnknown) ||
1665 IsEqualIID(riid,&IID_ITypeInfo)||
1666 IsEqualIID(riid,&IID_ITypeInfo2))
1667 *ppvObject = This;
1668 if(*ppvObject){
1669 ITypeInfo_AddRef(iface);
1670 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1671 return S_OK;
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);
1693 (This->ref)--;
1694 (This->pTypeLib->ref)--;
1695 return S_OK;
1698 /* ITypeInfo::GetTypeAttr
1700 * Retrieves a TYPEATTR structure that contains the attributes of the type
1701 * description.
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;
1711 return S_OK;
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);
1725 return S_OK;
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);
1738 int i;
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)
1743 if(pFDesc){
1744 /* FIXME: must do a copy here */
1745 *ppFuncDesc=&pFDesc->funcdesc;
1746 return S_OK;
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);
1760 int i;
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)
1765 if(pVDesc){
1766 /* FIXME: must do a copy here */
1767 *ppVarDesc=&pVDesc->vardesc;
1768 return S_OK;
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
1777 * function ID.
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;
1785 int i;
1786 TRACE("(%p) memid=0x%08lx Maxname=%d\n", This, memid,
1787 cMaxNames);
1788 for(pFDesc=This->funclist; pFDesc->funcdesc.memid != memid && pFDesc;
1789 pFDesc=pFDesc->next)
1791 if(pFDesc){
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);
1795 else
1796 rgBstrNames[i]=TLB_DupAtoBstr(pFDesc->pParamDesc[i-1].Name);
1799 *pcNames=i;
1800 }else{
1801 for(pVDesc=This->varlist; pVDesc->vardesc.memid != memid && pVDesc;
1802 pVDesc=pVDesc->next)
1804 if(pVDesc){
1805 *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
1806 *pcNames=1;
1807 }else{
1808 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
1809 This->TypeAttr.cImplTypes ){
1810 /* recursive search */
1811 ITypeInfo *pTInfo;
1812 HRESULT result;
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);
1819 return result;
1821 WARN("Could not search inherited interface!\n");
1822 } else
1823 WARN("no names found\n");
1824 *pcNames=0;
1825 return TYPE_E_ELEMENTNOTFOUND;
1828 return S_OK;
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,
1837 * if any exist.
1840 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO iface,
1841 UINT index, HREFTYPE *pRefType)
1843 ICOM_THIS( TLBTypeInfo, iface);
1844 int(i);
1845 TLBRefType *pIref;
1846 TRACE("(%p) index %d\n", This, index);
1847 for(i=0, pIref=This->impltypelist; i<index && pIref;
1848 i++, pIref=pIref->next)
1850 if(i==index){
1851 *pRefType=pIref->reference;
1852 return S_OK;
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);
1866 int(i);
1867 TLBRefType *pIref;
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;
1873 return S_OK;
1875 *pImplTypeFlags=0;
1876 return TYPE_E_ELEMENTNOTFOUND;
1879 /* GetIDsOfNames
1880 * Maps between member names and member IDs, and parameter names and
1881 * parameter IDs.
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;
1889 HRESULT ret=S_OK;
1890 PCHAR aszName= HEAP_strdupWtoA( GetProcessHeap(), 0, *rgszNames);
1891 TRACE("(%p) Name %s cNames %d\n", This, debugstr_a(aszName),
1892 cNames);
1893 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) {
1894 int i, j;
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,
1899 rgszNames[i]);
1900 for(j=0; j<pFDesc->funcdesc.cParams; j++)
1901 if(strcmp(aszPar,pFDesc->pParamDesc[j].Name))
1902 break;
1903 if( j<pFDesc->funcdesc.cParams)
1904 pMemId[i]=j;
1905 else
1906 ret=DISP_E_UNKNOWNNAME;
1907 HeapFree( GetProcessHeap(), 0, aszPar);
1909 HeapFree (GetProcessHeap(), 0, aszName);
1910 return ret;
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);
1917 return ret;
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 */
1924 ITypeInfo *pTInfo;
1925 ret=ITypeInfo_GetRefTypeInfo(iface,
1926 This->impltypelist->reference, &pTInfo);
1927 if(SUCCEEDED(ret)){
1928 ret=ITypeInfo_GetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
1929 ITypeInfo_Release(pTInfo);
1930 return ret;
1932 WARN("Could not search inherited interface!\n");
1933 } else
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);
1949 return S_OK;
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 */
1968 if(pBstrName)
1969 *pBstrName=TLB_DupAtoBstr(This->Name);
1970 if(pBstrDocString)
1971 *pBstrDocString=TLB_DupAtoBstr(This->DocString);
1972 if(pdwHelpContext)
1973 *pdwHelpContext=This->dwHelpContext;
1974 if(pBstrHelpFile)
1975 *pBstrHelpFile=TLB_DupAtoBstr(This->DocString);/* FIXME */
1976 return S_OK;
1977 }else {/* for a member */
1978 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
1979 if(pFDesc->funcdesc.memid==memid){
1980 return S_OK;
1982 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
1983 if(pVDesc->vardesc.memid==memid){
1984 return S_OK;
1987 return TYPE_E_ELEMENTNOTFOUND;
1990 /* ITypeInfo::GetDllEntry
1992 * Retrieves a description or specification of an entry point for a function
1993 * in a DLL.
1995 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( LPTYPEINFO iface, MEMBERID memid,
1996 INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
1997 WORD *pwOrdinal)
1999 ICOM_THIS( TLBTypeInfo, iface);
2000 FIXME("(%p) stub!\n", This);
2001 return E_FAIL;
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);
2013 HRESULT result;
2014 if(HREFTYPE_INTHISFILE(hRefType)){
2015 ITypeLib *pTLib;
2016 int Index;
2017 result=This->lpvtbl->fnGetContainingTypeLib(iface, &pTLib,
2018 &Index);
2019 if(SUCCEEDED(result)){
2020 result=ITypeLib_GetTypeInfo(pTLib,
2021 HREFTYPE_INDEX(hRefType),
2022 ppTInfo);
2023 ITypeLib_Release(pTLib );
2025 } else{
2026 /* imported type lib */
2027 TLBRefType * pRefType;
2028 TLBLibInfo *pTypeLib;
2029 for( pRefType=This->impltypelist; pRefType &&
2030 pRefType->reference != hRefType; pRefType=pRefType->next)
2032 if(!pRefType)
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);
2038 else{
2039 result=LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
2040 0,0,0, /* FIXME */
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);
2056 return result;
2059 /* ITypeInfo::AddressOfMember
2061 * Retrieves the addresses of static functions or variables, such as those
2062 * defined in a DLL.
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);
2069 return S_OK;
2072 /* ITypeInfo::CreateInstance
2074 * Creates a new instance of a type that describes a component object class
2075 * (coclass).
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);
2082 return S_OK;
2085 /* ITypeInfo::GetMops
2087 * Retrieves marshaling information.
2089 static HRESULT WINAPI ITypeInfo_fnGetMops( LPTYPEINFO iface, MEMBERID memid,
2090 BSTR *pBstrMops)
2092 ICOM_THIS( TLBTypeInfo, iface);
2093 FIXME("(%p) stub!\n", This);
2094 return S_OK;
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);
2110 return S_OK;
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);
2123 return S_OK;
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);
2135 return S_OK;
2138 /* ITypeInfo::ReleaseVarDesc
2140 * Releases a VARDESC previously returned by GetVarDesc.
2142 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( LPTYPEINFO iface,
2143 VARDESC *pVarDesc)
2145 ICOM_THIS( TLBTypeInfo, iface);
2146 TRACE("(%p)->(%p)\n", This, pVarDesc);
2147 return S_OK;
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);
2161 return S_OK;
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
2168 * attribute).
2171 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo * iface,
2172 UINT *pTypeFlags)
2174 ICOM_THIS( TLBTypeInfo, iface);
2175 *pTypeFlags=This->TypeAttr.wTypeFlags;
2176 TRACE("(%p) flags 0x%04x\n", This,*pTypeFlags);
2177 return S_OK;
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;
2190 int i;
2191 HRESULT result;
2192 /* FIXME: should check for invKind??? */
2193 for(i=0, pFuncInfo=This->funclist;pFuncInfo &&
2194 memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next);
2195 if(pFuncInfo){
2196 *pFuncIndex=i;
2197 result= S_OK;
2198 }else{
2199 *pFuncIndex=0;
2200 result=E_INVALIDARG;
2202 TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This,
2203 memid, invKind, SUCCEEDED(result)? "SUCCES":"FAILED");
2204 return result;
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;
2218 int i;
2219 HRESULT result;
2220 for(i=0, pVarInfo=This->varlist; pVarInfo &&
2221 memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next)
2223 if(pVarInfo){
2224 *pVarIndex=i;
2225 result= S_OK;
2226 }else{
2227 *pVarIndex=0;
2228 result=E_INVALIDARG;
2230 TRACE("(%p) memid 0x%08lx -> %s\n", This,
2231 memid, SUCCEEDED(result)? "SUCCES":"FAILED");
2232 return result;
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)){
2247 char xriid[50];
2248 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2249 TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
2251 if(pCData){
2252 VariantInit( pVarVal);
2253 VariantCopy( pVarVal, &pCData->data);
2254 return S_OK;
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;
2269 int i;
2270 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2271 pFDesc=pFDesc->next)
2273 if(pFDesc)
2274 for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next)
2275 if( IsEqualIID(guid, &pCData->guid)) break;
2276 if(TRACE_ON(typelib)){
2277 char xriid[50];
2278 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2279 TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
2281 if(pCData){
2282 VariantInit( pVarVal);
2283 VariantCopy( pVarVal, &pCData->data);
2284 return S_OK;
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;
2299 int i;
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)){
2308 char xriid[50];
2309 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2310 TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
2312 if(pCData){
2313 VariantInit( pVarVal);
2314 VariantCopy( pVarVal, &pCData->data);
2315 return S_OK;
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;
2330 int i;
2331 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2332 pVDesc=pVDesc->next)
2334 if(pVDesc)
2335 for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next)
2336 if( IsEqualIID(guid, &pCData->guid)) break;
2337 if(TRACE_ON(typelib)){
2338 char xriid[50];
2339 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2340 TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
2342 if(pCData){
2343 VariantInit( pVarVal);
2344 VariantCopy( pVarVal, &pCData->data);
2345 return S_OK;
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;
2360 int i;
2361 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2362 pRDesc=pRDesc->next)
2364 if(pRDesc)
2365 for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next)
2366 if( IsEqualIID(guid, &pCData->guid)) break;
2367 if(TRACE_ON(typelib)){
2368 char xriid[50];
2369 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2370 TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
2372 if(pCData){
2373 VariantInit( pVarVal);
2374 VariantCopy( pVarVal, &pCData->data);
2375 return S_OK;
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 */
2403 if(pbstrHelpString)
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 */
2410 return S_OK;
2411 }else {/* for a member */
2412 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
2413 if(pFDesc->funcdesc.memid==memid){
2414 if(pbstrHelpString)
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 */
2421 return S_OK;
2423 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
2424 if(pVDesc->vardesc.memid==memid){
2425 if(pbstrHelpString)
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 */
2432 return S_OK;
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;
2448 int i;
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);
2457 }else{
2458 ERR(" OUT OF MEMORY! \n");
2459 return E_OUTOFMEMORY;
2461 return S_OK;
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;
2475 int i;
2476 TRACE("(%p) index %d\n", This, index);
2477 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2478 pFDesc=pFDesc->next)
2480 if(pFDesc){
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,
2489 & pCData->data);
2491 }else{
2492 ERR(" OUT OF MEMORY! \n");
2493 return E_OUTOFMEMORY;
2495 return S_OK;
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;
2511 int i;
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,
2526 & pCData->data);
2528 }else{
2529 ERR(" OUT OF MEMORY! \n");
2530 return E_OUTOFMEMORY;
2532 return S_OK;
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;
2548 int i;
2549 TRACE("(%p) index %d\n", This, index);
2550 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2551 pVDesc=pVDesc->next)
2553 if(pVDesc){
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,
2562 & pCData->data);
2564 }else{
2565 ERR(" OUT OF MEMORY! \n");
2566 return E_OUTOFMEMORY;
2568 return S_OK;
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;
2584 int i;
2585 TRACE("(%p) index %d\n", This, index);
2586 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2587 pRDesc=pRDesc->next)
2589 if(pRDesc){
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,
2598 & pCData->data);
2600 }else{
2601 ERR(" OUT OF MEMORY! \n");
2602 return E_OUTOFMEMORY;
2604 return S_OK;
2606 return TYPE_E_ELEMENTNOTFOUND;