Added cmdlgr.h
[wine/wine-kai.git] / ole / typelib.c
blob13e554911641cd8278cf004657cd01bdc1ae2a7e
1 /*
2 * TYPELIB
4 * Copyright 1997 Marcus Meissner
5 * 1999 Rein Klazes
6 * there is much left to do here before it can be usefull for real world
7 * programs
8 * know problems:
9 * -. Only one format of typelibs is supported
10 * -. All testing until sofar 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 entirely 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 stuf ignored
19 * -. move stuf 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 <assert.h>
30 #include "windef.h"
31 #include "winerror.h"
32 #include "winreg.h"
33 #include "oleauto.h"
34 #include "wine/winbase16.h"
35 #include "heap.h"
36 #include "wine/obj_base.h"
37 #include "debug.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 DEFAULT_DEBUG_CHANNEL(ole)
45 DECLARE_DEBUG_CHANNEL(typelib)
47 /****************************************************************************
48 * QueryPathOfRegTypeLib16 [TYPELIB.14]
50 * the path is "Classes\Typelib\<guid>\<major>.<minor>\<lcid>\win16\"
51 * RETURNS
52 * path of typelib
54 HRESULT WINAPI
55 QueryPathOfRegTypeLib16(
56 REFGUID guid, /* [in] referenced guid */
57 WORD wMaj, /* [in] major version */
58 WORD wMin, /* [in] minor version */
59 LCID lcid, /* [in] locale id */
60 LPBSTR16 path /* [out] path of typelib */
61 ) {
62 char xguid[80];
63 char typelibkey[100],pathname[260];
64 DWORD plen;
66 if (HIWORD(guid)) {
67 WINE_StringFromCLSID(guid,xguid);
68 sprintf(typelibkey,"SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%ld\\win16",
69 xguid,wMaj,wMin,lcid&0xff
71 } else {
72 sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
73 FIXME(ole,"(%s,%d,%d,0x%04lx,%p),can't handle non-string guids.\n",xguid,wMaj,wMin,(DWORD)lcid,path);
74 return E_FAIL;
76 plen = sizeof(pathname);
77 if (RegQueryValue16(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
78 FIXME(ole,"key %s not found\n",typelibkey);
79 return E_FAIL;
81 *path = SysAllocString16(pathname);
82 return S_OK;
85 /****************************************************************************
86 * QueryPathOfRegTypeLib [OLEAUT32.164]
87 * RETURNS
88 * path of typelib
90 HRESULT WINAPI
91 QueryPathOfRegTypeLib(
92 REFGUID guid, /* [in] referenced guid */
93 WORD wMaj, /* [in] major version */
94 WORD wMin, /* [in] minor version */
95 LCID lcid, /* [in] locale id */
96 LPBSTR path /* [out] path of typelib */
97 ) {
98 char xguid[80];
99 char typelibkey[100],pathname[260];
100 DWORD plen;
103 if (HIWORD(guid)) {
104 WINE_StringFromCLSID(guid,xguid);
105 sprintf(typelibkey,"SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%ld\\win32",
106 xguid,wMaj,wMin,lcid&0xff
108 } else {
109 sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
110 FIXME(ole,"(%s,%d,%d,0x%04lx,%p),stub!\n",xguid,wMaj,wMin,(DWORD)lcid,path);
111 return E_FAIL;
113 plen = sizeof(pathname);
114 if (RegQueryValue16(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
115 FIXME(ole,"key %s not found\n",typelibkey);
116 return E_FAIL;
118 *path = HEAP_strdupAtoW(GetProcessHeap(),0,pathname);
119 return S_OK;
122 /******************************************************************************
123 * LoadTypeLib [TYPELIB.3] Loads and registers a type library
124 * NOTES
125 * Docs: OLECHAR FAR* szFile
126 * Docs: iTypeLib FAR* FAR* pptLib
128 * RETURNS
129 * Success: S_OK
130 * Failure: Status
132 HRESULT WINAPI LoadTypeLib16(
133 OLECHAR *szFile, /* [in] Name of file to load from */
134 void * *pptLib) /* [out] Pointer to pointer to loaded type library */
136 FIXME(ole, "('%s',%p): stub\n",debugstr_w((LPWSTR)szFile),pptLib);
138 if (pptLib!=0)
139 *pptLib=0;
141 return E_FAIL;
144 /******************************************************************************
145 * LoadTypeLib [OLEAUT32.161]
146 * Loads and registers a type library
147 * NOTES
148 * Docs: OLECHAR FAR* szFile
149 * Docs: iTypeLib FAR* FAR* pptLib
151 * RETURNS
152 * Success: S_OK
153 * Failure: Status
155 int TLB_ReadTypeLib(PCHAR file, ITypeLib **ppTypelib);
156 HRESULT WINAPI LoadTypeLib(
157 OLECHAR *szFile, /* [in] Name of file to load from */
158 ITypeLib * *pptLib) /* [out] Pointer to pointer to loaded type library */
160 LPSTR p;
161 HRESULT res;
162 TRACE(typelib, "('%s',%p)\n",debugstr_w(szFile),pptLib);
164 p=HEAP_strdupWtoA(GetProcessHeap(),0,szFile);
165 res= TLB_ReadTypeLib(p, pptLib);
166 //XXX need to free p ??
168 TRACE( typelib, " returns %ld\n",res);
170 return res;
173 /******************************************************************************
174 * LoadRegTypeLib [OLEAUT32.162]
176 HRESULT WINAPI LoadRegTypeLib(
177 REFGUID rguid, /* [in] referenced guid */
178 WORD wVerMajor, /* [in] major version */
179 WORD wVerMinor, /* [in] minor version */
180 LCID lcid, /* [in] locale id */
181 ITypeLib **ppTLib /* [out] path of typelib */
183 BSTR bstr=NULL;
184 HRESULT res=QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor,
185 lcid, &bstr);
186 if(SUCCEEDED(res)){
187 res= LoadTypeLib(bstr, ppTLib);
188 SysFreeString(bstr);
190 if(TRACE_ON(typelib)){
191 char xriid[50];
192 WINE_StringFromCLSID((LPCLSID)rguid,xriid);
193 TRACE(typelib,"(IID: %s) load %s (%p)\n",xriid,
194 SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);
196 return res;
200 /******************************************************************************
201 * RegisterTypeLib [OLEAUT32.163]
202 * Adds information about a type library to the System Registry
203 * NOTES
204 * Docs: ITypeLib FAR * ptlib
205 * Docs: OLECHAR FAR* szFullPath
206 * Docs: OLECHAR FAR* szHelpDir
208 * RETURNS
209 * Success: S_OK
210 * Failure: Status
212 HRESULT WINAPI RegisterTypeLib(
213 ITypeLib * ptlib, /*[in] Pointer to the library*/
214 OLECHAR * szFullPath, /*[in] full Path of the library*/
215 OLECHAR * szHelpDir) /*[in] dir to the helpfile for the library,
216 may be NULL*/
217 { FIXME(ole, "(%p,%s,%s): stub\n",ptlib, debugstr_w(szFullPath),debugstr_w(szHelpDir));
218 return S_OK; /* FIXME: pretend everything is OK */
222 /******************************************************************************
223 * UnRegisterTypeLib [OLEAUT32.186]
224 * Removes information about a type library from the System Registry
225 * NOTES
227 * RETURNS
228 * Success: S_OK
229 * Failure: Status
231 HRESULT WINAPI UnRegisterTypeLib(
232 REFGUID libid, /* [in] Guid of the library */
233 WORD wVerMajor, /* [in] major version */
234 WORD wVerMinor, /* [in] minor version */
235 LCID lcid, /* [in] locale id */
236 SYSKIND syskind)
238 char xriid[50];
239 WINE_StringFromCLSID((LPCLSID)libid,xriid);
240 TRACE(typelib,"(IID: %s): stub\n",xriid);
241 return S_OK; /* FIXME: pretend everything is OK */
244 /****************************************************************************
245 * OABuildVersion (TYPELIB.15)
246 * RETURNS
247 * path of typelib
249 DWORD WINAPI OABuildVersion16(void)
251 WINDOWS_VERSION ver = VERSION_GetVersion();
253 switch (ver) {
254 case WIN95:
255 return MAKELONG(0xbd0, 0xa); /* Win95A */
256 case WIN31:
257 return MAKELONG(0xbd3, 0x3); /* WfW 3.11 */
258 default:
259 FIXME(ole, "Version value not known yet. Please investigate it !");
260 return MAKELONG(0xbd0, 0xa); /* return Win95A for now */
264 /* for better debugging info leave the static out for the time being */
265 #define static
267 /*=======================Itypelib methods ===============================*/
268 /* ITypeLib methods */
269 static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid,
270 VOID **ppvObject);
271 static ULONG WINAPI ITypeLib_fnAddRef( LPTYPELIB This);
272 static ULONG WINAPI ITypeLib_fnRelease( LPTYPELIB This);
273 static UINT WINAPI ITypeLib_fnGetTypeInfoCount( LPTYPELIB This);
274 static HRESULT WINAPI ITypeLib_fnGetTypeInfo( LPTYPELIB This, UINT index,
275 ITypeInfo **ppTInfo);
277 static HRESULT WINAPI ITypeLib_fnGetTypeInfoType( LPTYPELIB This, UINT index,
278 TYPEKIND *pTKind);
280 static HRESULT WINAPI ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB This, REFGUID guid,
281 ITypeInfo **ppTinfo);
283 static HRESULT WINAPI ITypeLib_fnGetLibAttr( LPTYPELIB This,
284 LPTLIBATTR *ppTLibAttr);
286 static HRESULT WINAPI ITypeLib_fnGetTypeComp( LPTYPELIB This,
287 ITypeComp **ppTComp);
289 static HRESULT WINAPI ITypeLib_fnGetDocumentation( LPTYPELIB This, INT index,
290 BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext,
291 BSTR *pBstrHelpFile);
293 static HRESULT WINAPI ITypeLib_fnIsName( LPTYPELIB This, LPOLESTR szNameBuf,
294 ULONG lHashVal, BOOL *pfName);
296 static HRESULT WINAPI ITypeLib_fnFindName( LPTYPELIB This, LPOLESTR szNameBuf,
297 ULONG lHashVal, ITypeInfo **ppTInfo, MEMBERID *rgMemId, UINT16 *pcFound);
299 static VOID WINAPI ITypeLib_fnReleaseTLibAttr( LPTYPELIB This,
300 TLIBATTR *pTLibAttr);
302 static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLib * This, REFGUID guid,
303 VARIANT *pVarVal);
305 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( ITypeLib * This,
306 UINT *pcUniqueNames, UINT *pcchUniqueNames);
308 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( ITypeLib * This,
309 INT index, LCID lcid, BSTR *pbstrHelpString,
310 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll);
312 static HRESULT WINAPI ITypeLib2_fnGetAllCustData( ITypeLib * This,
313 CUSTDATA *pCustData);
314 static ICOM_VTABLE(ITypeLib) tlbvt = {
315 ITypeLib_fnQueryInterface,
316 ITypeLib_fnAddRef,
317 ITypeLib_fnRelease,
318 ITypeLib_fnGetTypeInfoCount,
319 ITypeLib_fnGetTypeInfo,
320 ITypeLib_fnGetTypeInfoType,
321 ITypeLib_fnGetTypeInfoOfGuid,
322 ITypeLib_fnGetLibAttr,
323 ITypeLib_fnGetTypeComp,
324 ITypeLib_fnGetDocumentation,
325 ITypeLib_fnIsName,
326 ITypeLib_fnFindName,
327 ITypeLib_fnReleaseTLibAttr,
328 ITypeLib2_fnGetCustData,
329 ITypeLib2_fnGetLibStatistics,
330 ITypeLib2_fnGetDocumentation2,
331 ITypeLib2_fnGetAllCustData
333 /* TypeInfo Methods */
335 static HRESULT WINAPI ITypeInfo_fnQueryInterface( LPTYPEINFO This, REFIID riid,
336 VOID **ppvObject);
337 static ULONG WINAPI ITypeInfo_fnAddRef( LPTYPEINFO This);
338 static ULONG WINAPI ITypeInfo_fnRelease( LPTYPEINFO This);
339 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( LPTYPEINFO This,
340 LPTYPEATTR *ppTypeAttr);
342 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( LPTYPEINFO This,
343 ITypeComp * *ppTComp);
345 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( LPTYPEINFO This, UINT index,
346 LPFUNCDESC *ppFuncDesc);
348 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( LPTYPEINFO This, UINT index,
349 LPVARDESC *ppVarDesc);
351 static HRESULT WINAPI ITypeInfo_fnGetNames( LPTYPEINFO This, MEMBERID memid,
352 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames);
355 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO This,
356 UINT index, HREFTYPE *pRefType);
358 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO This,
359 UINT index, INT *pImplTypeFlags);
361 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( LPTYPEINFO This,
362 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId);
364 static HRESULT WINAPI ITypeInfo_fnInvoke( LPTYPEINFO This, VOID *pIUnk,
365 MEMBERID memid, UINT16 dwFlags, DISPPARAMS *pDispParams,
366 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *pArgErr);
368 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( LPTYPEINFO This,
369 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
370 DWORD *pdwHelpContext, BSTR *pBstrHelpFile);
372 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( LPTYPEINFO This,
373 MEMBERID memid, INVOKEKIND invKind, BSTR *pBstrDllName,
374 BSTR *pBstrName, WORD *pwOrdinal);
376 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO This,
377 HREFTYPE hRefType, ITypeInfo * *ppTInfo);
379 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( LPTYPEINFO This,
380 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv);
382 static HRESULT WINAPI ITypeInfo_fnCreateInstance( LPTYPEINFO This,
383 IUnknown *pUnk, REFIID riid, VOID * *ppvObj);
385 static HRESULT WINAPI ITypeInfo_fnGetMops( LPTYPEINFO This, MEMBERID memid,
386 BSTR *pBstrMops);
389 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( LPTYPEINFO This,
390 ITypeLib * *ppTLib, UINT *pIndex);
392 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO This,
393 TYPEATTR *pTypeAttr);
395 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO This,
396 FUNCDESC *pFuncDesc);
398 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( LPTYPEINFO This,
399 VARDESC *pVarDesc);
400 /* itypeinfo2 methods */
401 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo * This,
402 TYPEKIND *pTypeKind);
403 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo * This,
404 UINT *pTypeFlags);
405 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo * This,
406 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex);
407 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo * This,
408 MEMBERID memid, UINT *pVarIndex);
409 static HRESULT WINAPI ITypeInfo2_fnGetCustData( ITypeInfo * This,
410 REFGUID guid, VARIANT *pVarVal);
411 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( ITypeInfo * This,
412 UINT index, REFGUID guid, VARIANT *pVarVal);
413 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( ITypeInfo * This,
414 UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal);
415 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( ITypeInfo * This,
416 UINT index, REFGUID guid, VARIANT *pVarVal);
417 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( ITypeInfo * This,
418 UINT index, REFGUID guid, VARIANT *pVarVal);
419 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( ITypeInfo * This,
420 MEMBERID memid, LCID lcid, BSTR *pbstrHelpString,
421 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll);
422 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( ITypeInfo * This,
423 CUSTDATA *pCustData);
424 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( ITypeInfo * This,
425 UINT index, CUSTDATA *pCustData);
426 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo * This,
427 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData);
428 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo * This,
429 UINT index, CUSTDATA *pCustData);
430 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo * This,
431 UINT index, CUSTDATA *pCustData);
433 static ICOM_VTABLE(ITypeInfo) tinfvt = {
434 ITypeInfo_fnQueryInterface,
435 ITypeInfo_fnAddRef,
436 ITypeInfo_fnRelease,
437 ITypeInfo_fnGetTypeAttr,
438 ITypeInfo_fnGetTypeComp,
439 ITypeInfo_fnGetFuncDesc,
440 ITypeInfo_fnGetVarDesc,
441 ITypeInfo_fnGetNames,
442 ITypeInfo_fnGetRefTypeOfImplType,
443 ITypeInfo_fnGetImplTypeFlags,
444 ITypeInfo_fnGetIDsOfNames,
445 ITypeInfo_fnInvoke,
446 ITypeInfo_fnGetDocumentation,
447 ITypeInfo_fnGetDllEntry,
448 ITypeInfo_fnGetRefTypeInfo,
449 ITypeInfo_fnAddressOfMember,
450 ITypeInfo_fnCreateInstance,
451 ITypeInfo_fnGetMops,
452 ITypeInfo_fnGetContainingTypeLib,
453 ITypeInfo_fnReleaseTypeAttr,
454 ITypeInfo_fnReleaseFuncDesc,
455 ITypeInfo_fnReleaseVarDesc,
457 ITypeInfo2_fnGetTypeKind,
458 ITypeInfo2_fnGetTypeFlags,
459 ITypeInfo2_fnGetFuncIndexOfMemId,
460 ITypeInfo2_fnGetVarIndexOfMemId,
461 ITypeInfo2_fnGetCustData,
462 ITypeInfo2_fnGetFuncCustData,
463 ITypeInfo2_fnGetParamCustData,
464 ITypeInfo2_fnGetVarCustData,
465 ITypeInfo2_fnGetImplTypeCustData,
466 ITypeInfo2_fnGetDocumentation2,
467 ITypeInfo2_fnGetAllCustData,
468 ITypeInfo2_fnGetAllFuncCustData,
469 ITypeInfo2_fnGetAllParamCustData,
470 ITypeInfo2_fnGetAllVarCustData,
471 ITypeInfo2_fnGetAllImplTypeCustData,
475 static TYPEDESC stndTypeDesc[VT_LPWSTR+1]={/* VT_LPWSTR is largest type that */
476 /* may appear in type description*/
477 {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
478 {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
479 {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
480 {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
481 {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
482 {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
483 {{0},30},{{0},31}};
485 static void TLB_abort()
487 *((int *)0)=0;
489 static void * TLB_Alloc(unsigned size)
491 void * ret;
492 if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){
493 /* FIXME */
494 ERR(ole,"cannot allocate memory\n");
496 return ret;
499 /* candidate for a more global appearance... */
500 static BSTR TLB_DupAtoBstr(PCHAR Astr)
502 int len;
503 BSTR bstr;
504 DWORD *pdw ;
505 if(!Astr)
506 return NULL;
507 len=strlen(Astr);
508 pdw =TLB_Alloc((len+3)*sizeof(OLECHAR));
509 pdw[0]=(len)*sizeof(OLECHAR);
510 bstr=(BSTR)&( pdw[1]);
511 lstrcpyAtoW( bstr, Astr);
512 TRACE(typelib,"copying %s to (%p)\n", Astr, bstr);
513 return bstr;
516 static void TLB_Free(void * ptr)
518 HeapFree(GetProcessHeap(), 0, ptr);
520 /* read function */
521 DWORD TLB_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
523 DWORD bytesread=0;
525 if((where!=DO_NOT_SEEK &&
526 0xffffffff== SetFilePointer((HANDLE)pcx->hFile, where, 0, FILE_BEGIN))||
527 !ReadFile((HANDLE)pcx->hFile, buffer, count, &bytesread, NULL) ||
528 count != bytesread){
529 /* FIXME */
530 ERR( typelib, "read error is 0x%lx reading %ld bytes at 0x%lx\n",
531 GetLastError(), count, where);
532 TLB_abort();
533 exit(1);
535 return bytesread;
538 static void TLB_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
540 if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){
541 memset(pGuid,0, sizeof(GUID));
542 return;
544 TLB_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset );
547 PCHAR TLB_ReadName( TLBContext *pcx, int offset)
549 char * name;
550 TLBNameIntro niName;
551 TLB_Read(&niName, sizeof(niName), pcx,
552 pcx->pTblDir->pNametab.offset+offset);
553 niName.namelen &= 0xFF; /* FIXME: correct ? */
554 name=TLB_Alloc((niName.namelen & 0xff) +1);
555 TLB_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK);
556 name[niName.namelen & 0xff]='\0';
557 return name;
559 PCHAR TLB_ReadString( TLBContext *pcx, int offset)
561 char * string;
562 INT16 length;
563 if(offset<0) return NULL;
564 TLB_Read(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
565 if(length <= 0) return 0;
566 string=TLB_Alloc(length +1);
567 TLB_Read(string, length, pcx, DO_NOT_SEEK);
568 string[length]='\0';
569 return string;
572 * read a value and fill a VARIANT structure
574 static void TLB_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
576 int size;
577 if(offset <0) { /* data is packed in here */
578 pVar->vt = (offset & 0x7c000000 )>> 26;
579 V_UNION(pVar, iVal) = offset & 0xffff;
580 return;
582 TLB_Read(&(pVar->vt), sizeof(VARTYPE), pcx,
583 pcx->pTblDir->pCustData.offset + offset );
584 switch(pVar->vt){
585 case VT_EMPTY: /* FIXME: is this right? */
586 case VT_NULL: /* FIXME: is this right? */
587 case VT_I2 : /* this should not happen */
588 case VT_I4 :
589 case VT_R4 :
590 case VT_ERROR :
591 case VT_BOOL :
592 case VT_I1 :
593 case VT_UI1 :
594 case VT_UI2 :
595 case VT_UI4 :
596 case VT_INT :
597 case VT_UINT :
598 case VT_VOID : /* FIXME: is this right? */
599 case VT_HRESULT :
600 size=4; break;
601 case VT_R8 :
602 case VT_CY :
603 case VT_DATE :
604 case VT_I8 :
605 case VT_UI8 :
606 case VT_DECIMAL : /* FIXME: is this right? */
607 case VT_FILETIME :
608 size=8;break;
609 /* pointer types with known behaviour */
610 case VT_BSTR :{
611 char * ptr;
612 TLB_Read(&size, sizeof(INT), pcx, DO_NOT_SEEK );
613 ptr=TLB_Alloc(size);/* allocate temp buffer */
614 TLB_Read(ptr, size, pcx, DO_NOT_SEEK ); /* read string (ANSI) */
615 V_UNION(pVar, bstrVal)=SysAllocStringLen(NULL,size);
616 /* FIXME: do we need a AtoW conversion here? */
617 V_UNION(pVar, bstrVal[size])=L'\0';
618 while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
619 TLB_Free(ptr);
621 size=-4; break;
622 /* FIXME: this will not work AT ALL when the variant contains a pointer */
623 case VT_DISPATCH :
624 case VT_VARIANT :
625 case VT_UNKNOWN :
626 case VT_PTR :
627 case VT_SAFEARRAY :
628 case VT_CARRAY :
629 case VT_USERDEFINED :
630 case VT_LPSTR :
631 case VT_LPWSTR :
632 case VT_BLOB :
633 case VT_STREAM :
634 case VT_STORAGE :
635 case VT_STREAMED_OBJECT :
636 case VT_STORED_OBJECT :
637 case VT_BLOB_OBJECT :
638 case VT_CF :
639 case VT_CLSID :
640 default:
641 size=0;
642 FIXME(ole,"VARTYPE %d is not supported, setting pointer to NULL\n",
643 pVar->vt);
646 if(size>0) /* (big|small) endian correct? */
647 TLB_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK );
648 return ;
651 * create a linked list with custom data
653 static int TLB_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
655 TLBCDGuid entry;
656 TLBCustData* pNew;
657 int count=0;
658 while(offset >=0){
659 count++;
660 pNew=TLB_Alloc(sizeof(TLBCustData));
661 TLB_Read(&entry, sizeof(entry), pcx,
662 pcx->pTblDir->pCDGuids.offset+offset);
663 TLB_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
664 TLB_ReadValue(&(pNew->data), entry.DataOffset, pcx);
665 /* add new custom data at head of the list */
666 pNew->next=*ppCustData;
667 *ppCustData=pNew;
668 offset = entry.next;
670 return count;
673 static void TLB_GetTdesc(TLBContext *pcx, INT type,TYPEDESC * pTd )
675 if(type <0)
676 pTd->vt=type & VT_TYPEMASK;
677 else
678 *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
680 static void TLB_DoFuncs(TLBContext *pcx, int cFuncs, int cVars,
681 int offset, TLBFuncDesc ** pptfd)
684 * member information is stored in a data structure at offset
685 * indicated by the memoffset field of the typeinfo structure
686 * There are several distinctive parts.
687 * the first part starts with a field that holds the total length
688 * of this (first) part excluding this field. Then follow the records,
689 * for each member there is one record.
691 * First entry is always the length of the record (excluding this
692 * length word).
693 * Rest of the record depends on the type of the member. If there is
694 * a field indicating the member type (function variable intereface etc)
695 * I have not found it yet. At this time we depend on the information
696 * in the type info and the usual order how things are stored.
698 * Second follows an array sized nrMEM*sizeof(INT) with a memeber id
699 * for each member;
701 * Third is a equal sized array with file offsets to the name entry
702 * of each member.
704 * Forth and last (?) part is an array with offsets to the records in the
705 * first part of this file segment.
708 int infolen, nameoffset, reclength, nrattributes;
709 char recbuf[512];
710 TLBFuncRecord * pFuncRec=(TLBFuncRecord *) recbuf;
711 int i, j;
712 int recoffset=offset+sizeof(INT);
713 TLB_Read(&infolen,sizeof(INT), pcx, offset);
714 for(i=0;i<cFuncs;i++){
715 *pptfd=TLB_Alloc(sizeof(TLBFuncDesc));
716 /* name, eventually add to a hash table */
717 TLB_Read(&nameoffset, sizeof(INT), pcx,
718 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
719 (*pptfd)->Name=TLB_ReadName(pcx, nameoffset);
720 /* read the function information record */
721 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
722 reclength &=0x1ff;
723 TLB_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
724 /* do the attributes */
725 nrattributes=(reclength-pFuncRec->nrargs*3*sizeof(int)-0x18)
726 /sizeof(int);
727 if(nrattributes>0){
728 (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
729 if(nrattributes>1){
730 (*pptfd)->HelpString = TLB_ReadString(pcx,
731 pFuncRec->OptAttr[1]) ;
732 if(nrattributes>2){
733 if(pFuncRec->FKCCIC & 0x2000)
734 (*pptfd)->Entry = (char *) pFuncRec->OptAttr[2] ;
735 else
736 (*pptfd)->Entry = TLB_ReadString(pcx,
737 pFuncRec->OptAttr[2]);
738 if(nrattributes>5 )
739 (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;
740 if(nrattributes>6 && pFuncRec->FKCCIC & 0x80){
741 TLB_CustData(pcx, pFuncRec->OptAttr[6],
742 &(*pptfd)->pCustData);
747 /* fill the FuncDesc Structure */
748 TLB_Read(&(*pptfd)->funcdesc.memid, sizeof(INT), pcx,
749 offset + infolen + ( i + 1) * sizeof(INT));
750 (*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
751 (*pptfd)->funcdesc.invkind = ((pFuncRec->FKCCIC) >>3) & 0xF;
752 (*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >>8 & 0xF;
753 (*pptfd)->funcdesc.cParams = pFuncRec->nrargs ;
754 (*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ;
755 (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ;
756 (*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
757 TLB_GetTdesc(pcx, pFuncRec->DataType,
758 &(*pptfd)->funcdesc.elemdescFunc.tdesc) ;
760 /* do the parameters/arguments */
761 if(pFuncRec->nrargs){
762 TLBParameterInfo paraminfo;
763 (*pptfd)->funcdesc.lprgelemdescParam=
764 TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
765 (*pptfd)->pParamDesc=TLB_Alloc(pFuncRec->nrargs *
766 sizeof(TLBParDesc));
768 TLB_Read(&paraminfo,sizeof(paraminfo), pcx, recoffset+reclength -
769 pFuncRec->nrargs * sizeof(TLBParameterInfo));
770 for(j=0;j<pFuncRec->nrargs;j++){
771 TLB_GetTdesc(pcx, paraminfo.DataType,
772 &(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc) ;
773 V_UNION(&((*pptfd)->funcdesc.lprgelemdescParam[j]),
774 paramdesc.wParamFlags) = paraminfo.Flags;
775 (*pptfd)->pParamDesc[j].Name=(void *)paraminfo.oName;
776 TLB_Read(&paraminfo,sizeof(TLBParameterInfo), pcx,
777 DO_NOT_SEEK);
779 /* second time around */
780 for(j=0;j<pFuncRec->nrargs;j++){
781 /* name */
782 (*pptfd)->pParamDesc[j].Name=
783 TLB_ReadName(pcx, (int)(*pptfd)->pParamDesc[j].Name);
784 /* default value */
785 if((PARAMFLAG_FHASDEFAULT & V_UNION(&((*pptfd)->funcdesc.
786 lprgelemdescParam[j]),paramdesc.wParamFlags)) &&
787 ((pFuncRec->FKCCIC) & 0x1000)){
788 INT *pInt=(INT *)((char *)pFuncRec + reclength -
789 (pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
790 PARAMDESC * pParamDesc= &V_UNION(&((*pptfd)->funcdesc.
791 lprgelemdescParam[j]),paramdesc);
792 pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
793 pParamDesc->pparamdescex->cBytes= sizeof(PARAMDESCEX);
794 TLB_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
795 pInt[j], pcx);
797 /* custom info */
798 if(nrattributes>7+j && pFuncRec->FKCCIC & 0x80)
799 TLB_CustData(pcx, pFuncRec->OptAttr[7+j],
800 &(*pptfd)->pParamDesc[j].pCustData);
803 /* scode is not used: archaic win16 stuff FIXME: right? */
804 (*pptfd)->funcdesc.cScodes = 0 ;
805 (*pptfd)->funcdesc.lprgscode = NULL ;
806 pptfd=&((*pptfd)->next);
807 recoffset += reclength;
810 static void TLB_DoVars(TLBContext *pcx, int cFuncs, int cVars,
811 int offset, TLBVarDesc ** pptvd)
813 int infolen, nameoffset, reclength;
814 char recbuf[256];
815 TLBVarRecord * pVarRec=(TLBVarRecord *) recbuf;
816 int i;
817 int recoffset;
818 TLB_Read(&infolen,sizeof(INT), pcx, offset);
819 TLB_Read(&recoffset,sizeof(INT), pcx, offset + infolen +
820 ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
821 recoffset += offset+sizeof(INT);
822 for(i=0;i<cVars;i++){
823 *pptvd=TLB_Alloc(sizeof(TLBVarDesc));
824 /* name, eventually add to a hash table */
825 TLB_Read(&nameoffset, sizeof(INT), pcx,
826 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
827 (*pptvd)->Name=TLB_ReadName(pcx, nameoffset);
828 /* read the variable information record */
829 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
830 reclength &=0xff;
831 TLB_Read(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
832 /* Optional data */
833 if(reclength >(6*sizeof(INT)) )
834 (*pptvd)->HelpContext=pVarRec->HelpContext;
835 if(reclength >(7*sizeof(INT)) )
836 (*pptvd)->HelpString = TLB_ReadString(pcx, pVarRec->oHelpString) ;
837 if(reclength >(8*sizeof(INT)) )
838 if(reclength >(9*sizeof(INT)) )
839 (*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
840 /* fill the VarDesc Structure */
841 TLB_Read(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
842 offset + infolen + ( i + 1) * sizeof(INT));
843 (*pptvd)->vardesc.varkind = pVarRec->VarKind;
844 (*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
845 TLB_GetTdesc(pcx, pVarRec->DataType,
846 &(*pptvd)->vardesc.elemdescVar.tdesc) ;
847 /* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) fixme?? */
848 if(pVarRec->VarKind == VAR_CONST ){
849 V_UNION(&((*pptvd)->vardesc),lpvarValue)=TLB_Alloc(sizeof(VARIANT));
850 TLB_ReadValue(V_UNION(&((*pptvd)->vardesc),lpvarValue),
851 pVarRec->OffsValue, pcx);
852 }else
853 V_UNION(&((*pptvd)->vardesc),oInst)=pVarRec->OffsValue;
854 pptvd=&((*pptvd)->next);
855 recoffset += reclength;
858 /* fill in data for a hreftype (offset). When the refernced type is contained
859 * in the typelib, its just an (file) offset in the type info base dir.
860 * If comes fom import, its an offset+1 in the ImpInfo table
861 * */
862 static void TLB_DoRefType(TLBContext *pcx,
863 int offset, TLBRefType ** pprtd)
865 int j;
866 if(!HREFTYPE_INTHISFILE( offset)) {
867 /* external typelib */
868 TLBImpInfo impinfo;
869 TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs);
870 TLB_Read(&impinfo, sizeof(impinfo), pcx,
871 pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
872 for(j=0;pImpLib;j++){ /* search the known offsets of all import libraries */
873 if(pImpLib->offset==impinfo.oImpFile) break;
874 pImpLib=pImpLib->next;
876 if(pImpLib){
877 (*pprtd)->reference=offset;
878 (*pprtd)->pImpTLInfo=pImpLib;
879 TLB_ReadGuid(&(*pprtd)->guid, impinfo.oGuid, pcx);
880 }else{
881 ERR( typelib ,"Cannot find a reference\n");
882 (*pprtd)->reference=-1;
883 (*pprtd)->pImpTLInfo=(void *)-1;
885 }else{
886 /* in this typelib */
887 (*pprtd)->reference=offset;
888 (*pprtd)->pImpTLInfo=(void *)-2;
892 /* process Implemented Interfaces of a com class */
893 static void TLB_DoImplTypes(TLBContext *pcx, int count,
894 int offset, TLBRefType ** pprtd)
896 int i;
897 TLBRefRecord refrec;
898 for(i=0;i<count;i++){
899 if(offset<0) break; /* paranoia */
900 *pprtd=TLB_Alloc(sizeof(TLBRefType));
901 TLB_Read(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
902 TLB_DoRefType(pcx, refrec.reftype, pprtd);
903 (*pprtd)->flags=refrec.flags;
904 (*pprtd)->ctCustData=
905 TLB_CustData(pcx, refrec.oCustData, &(*pprtd)->pCustData);
906 offset=refrec.onext;
907 pprtd=&((*pprtd)->next);
911 * process a typeinfo record
913 TLBTypeInfo * TLB_DoTypeInfo(TLBContext *pcx, int count, TLBLibInfo* pLibInfo)
915 TLBTypeInfoBase tiBase;
916 TLBTypeInfo *ptiRet;
917 ptiRet=TLB_Alloc(sizeof(TLBTypeInfo));
918 ptiRet->lpvtbl = &tinfvt;
919 ptiRet->ref=1;
920 TLB_Read(&tiBase, sizeof(tiBase) ,pcx ,
921 pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
922 /* this where we are coming from */
923 ptiRet->pTypeLib=pLibInfo;
924 ptiRet->index=count;
925 /* fill in the typeattr fields */
926 TLB_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx);
927 ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid; /* FIXME: correct? */
928 ptiRet->TypeAttr.memidConstructor=MEMBERID_NIL ;/* FIXME */
929 ptiRet->TypeAttr.memidDestructor=MEMBERID_NIL ; /* FIXME */
930 ptiRet->TypeAttr.lpstrSchema=NULL; /* reserved */
931 ptiRet->TypeAttr.cbSizeInstance=tiBase.size;
932 ptiRet->TypeAttr.typekind=tiBase.typekind & 0xF;
933 ptiRet->TypeAttr.cFuncs=LOWORD(tiBase.cElement);
934 ptiRet->TypeAttr.cVars=HIWORD(tiBase.cElement);
935 ptiRet->TypeAttr.cbAlignment=(tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */
936 ptiRet->TypeAttr.wTypeFlags=tiBase.flags;
937 ptiRet->TypeAttr.wMajorVerNum=LOWORD(tiBase.version);
938 ptiRet->TypeAttr.wMinorVerNum=HIWORD(tiBase.version);
939 ptiRet->TypeAttr.cImplTypes=tiBase.cImplTypes;
940 ptiRet->TypeAttr.cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
941 if(ptiRet->TypeAttr.typekind == TKIND_ALIAS)
942 TLB_GetTdesc(pcx, tiBase.datatype1,
943 &ptiRet->TypeAttr.tdescAlias) ;
944 /* FIXME: */
945 /* IDLDESC idldescType; *//* never saw this one != zero */
947 /* name, eventually add to a hash table */
948 ptiRet->Name=TLB_ReadName(pcx, tiBase.NameOffset);
949 TRACE( typelib,"reading %s\n", ptiRet->Name);
950 /* help info */
951 ptiRet->DocString=TLB_ReadString(pcx, tiBase.docstringoffs);
952 ptiRet->dwHelpStringContext=tiBase.helpstringcontext;
953 ptiRet->dwHelpContext=tiBase.helpcontext;
954 /* note: InfoType's Help file and HelpStringDll come from the containing
955 * library. Further HelpString and Docstring appear to be the same thing :(
957 /* functions */
958 if(ptiRet->TypeAttr.cFuncs >0 )
959 TLB_DoFuncs(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
960 tiBase.memoffset, & ptiRet->funclist);
961 /* variables */
962 if(ptiRet->TypeAttr.cVars >0 )
963 TLB_DoVars(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
964 tiBase.memoffset, & ptiRet->varlist);
965 if(ptiRet->TypeAttr.cImplTypes >0 ){
966 if(ptiRet->TypeAttr.typekind == TKIND_COCLASS)
967 TLB_DoImplTypes(pcx, ptiRet->TypeAttr.cImplTypes ,
968 tiBase.datatype1, & ptiRet->impltypelist);
969 else if(ptiRet->TypeAttr.typekind != TKIND_DISPATCH){
970 ptiRet->impltypelist=TLB_Alloc(sizeof(TLBRefType));
971 TLB_DoRefType(pcx, tiBase.datatype1, & ptiRet->impltypelist);
974 ptiRet->ctCustData=
975 TLB_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData);
976 return ptiRet;
980 long TLB_FindTlb(TLBContext *pcx)
981 {/* FIXME: should parse the file properly
982 * hack to find our tlb data
984 #define TLBBUFSZ 1024
985 char buff[TLBBUFSZ+1]; /* room for a trailing '\0' */
986 long ret=0;
987 int count;
988 char *pChr;
989 count=TLB_Read(buff, TLBBUFSZ, pcx, 0);
990 do {
991 buff[count]='\0';
992 if((pChr=strstr(buff,TLBMAGIC2))){
993 ret += pChr-buff;
994 break;
996 ret+=count;
997 count=TLB_Read(buff, TLBBUFSZ, pcx, DO_NOT_SEEK);
998 } while(count>0);
999 if(count)
1000 return ret;
1001 /* try again for the other format */
1002 ret=0;
1003 count=TLB_Read(buff, TLBBUFSZ, pcx, 0);
1004 do {
1005 buff[count]='\0';
1006 if((pChr=strstr(buff,TLBMAGIC1))){
1007 ret += pChr-buff;
1008 break;
1010 ret+=count;
1011 count=TLB_Read(buff, TLBBUFSZ, pcx, DO_NOT_SEEK);
1012 } while(count>0);
1013 if(count)
1014 ERR(ole,"type library format not (yet) implemented\n");
1015 else
1016 ERR(ole,"not type library found in this file\n");
1017 return -1;
1021 int TLB_ReadTypeLib(PCHAR file, ITypeLib **ppTypeLib)
1023 TLBContext cx;
1024 OFSTRUCT ofStruct;
1025 long oStart,lPSegDir;
1026 TLBLibInfo* pLibInfo=NULL;
1027 TLB2Header tlbHeader;
1028 TLBSegDir tlbSegDir;
1029 if((cx.hFile=(HANDLE)OpenFile(file, &ofStruct, OF_READWRITE))
1030 ==(HANDLE)HFILE_ERROR){
1031 ERR( typelib,"cannot open %s error 0x%lx\n",file, GetLastError());
1032 exit(1);
1034 /* get pointer to beginning of typelib data */
1035 if((oStart=TLB_FindTlb(&cx))<0){
1036 if(oStart==-1)
1037 ERR( typelib,"cannot locate typelib in %s\n",file);
1038 else
1039 ERR( typelib,"unsupported typelib format in %s\n",file);
1040 exit(1);
1042 cx.oStart=oStart;
1043 if((pLibInfo=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1044 sizeof(TLBLibInfo)))==NULL){
1045 CloseHandle(cx.hFile);
1046 return E_OUTOFMEMORY;
1048 pLibInfo->lpvtbl = &tlbvt;
1049 pLibInfo->ref=1;
1050 cx.pLibInfo=pLibInfo;
1051 /* read header */
1052 TLB_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
1053 /* there is a small number of information here until the next important
1054 * part:
1055 * the segment directory . Try to calculate the amount of data */
1056 lPSegDir=sizeof(tlbHeader)+
1057 (tlbHeader.nrtypeinfos)*4+
1058 (tlbHeader.varflags & HELPDLLFLAG? 4 :0);
1059 /* now read the segment directory */
1060 TLB_Read((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
1061 cx.pTblDir=&tlbSegDir;
1062 /* just check two entries */
1063 if(tlbSegDir.pTypeInfoTab.res0c != 0x0F ||
1064 tlbSegDir.pImpInfo.res0c != 0x0F){
1065 ERR( typelib,"cannot find the table directory, ptr=0x%lx\n",lPSegDir);
1067 /* now fill our internal data */
1068 /* TLIBATTR fields */
1069 TLB_ReadGuid(&pLibInfo->LibAttr.guid, tlbHeader.posguid, &cx);
1070 pLibInfo->LibAttr.lcid=tlbHeader.lcid;
1071 pLibInfo->LibAttr.syskind=tlbHeader.varflags & 0x0f; /* check the mask */
1072 pLibInfo->LibAttr.wMajorVerNum=LOWORD(tlbHeader.version);
1073 pLibInfo->LibAttr.wMinorVerNum=HIWORD(tlbHeader.version);
1074 pLibInfo->LibAttr.wLibFlags=(WORD) tlbHeader.flags & 0xffff;/* check mask */
1075 /* name, eventually add to a hash table */
1076 pLibInfo->Name=TLB_ReadName(&cx, tlbHeader.NameOffset);
1077 /* help info */
1078 pLibInfo->DocString=TLB_ReadString(&cx, tlbHeader.helpstring);
1079 pLibInfo->HelpFile=TLB_ReadString(&cx, tlbHeader.helpfile);
1080 if( tlbHeader.varflags & HELPDLLFLAG){
1081 int offset;
1082 TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
1083 pLibInfo->HelpStringDll=TLB_ReadString(&cx, offset);
1086 pLibInfo->dwHelpContext=tlbHeader.helpstringcontext;
1087 /* custom data */
1088 if(tlbHeader.CustomDataOffset >= 0) {
1089 pLibInfo->ctCustData=
1090 TLB_CustData(&cx, tlbHeader.CustomDataOffset, &pLibInfo->pCustData);
1092 /* fill in typedescriptions */
1093 if(tlbSegDir.pTypdescTab.length >0){
1094 int i, j, cTD=tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
1095 INT16 td[4];
1096 pLibInfo->pTypeDesc=
1097 TLB_Alloc( cTD * sizeof(TYPEDESC));
1098 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
1099 for(i=0;i<cTD;){
1100 /* FIXME: add several sanity checks here */
1101 pLibInfo->pTypeDesc[i].vt=td[0] & VT_TYPEMASK;
1102 if(td[0]==VT_PTR ||td[0]==VT_SAFEARRAY){/* FIXME: check safearray */
1103 if(td[3]<0)
1104 V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
1105 & stndTypeDesc[td[2]];
1106 else
1107 V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
1108 & pLibInfo->pTypeDesc[td[3]/8];
1109 }else if(td[0]==VT_CARRAY)
1110 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
1111 (void *)((int) td[2]); /* temp store offset in*/
1112 /* array descr table here */
1113 else if(td[0]==VT_USERDEFINED)
1114 V_UNION(&(pLibInfo->pTypeDesc[i]),hreftype)=MAKELONG(td[2],td[3]);
1115 if(++i<cTD) TLB_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
1117 /* second time around to fill the array subscript info */
1118 for(i=0;i<cTD;i++){
1119 if(pLibInfo->pTypeDesc[i].vt != VT_CARRAY) continue;
1120 if(tlbSegDir.pArrayDescriptions.offset>0){
1121 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset +
1122 (int) V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc));
1123 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
1124 TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
1125 if(td[1]<0)
1126 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem.vt=td[0] & VT_TYPEMASK;
1127 else
1128 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem=stndTypeDesc[td[0]/8];
1129 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->cDims=td[2];
1130 for(j=0;j<td[2];j++){
1131 TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->rgbounds[j].cElements,
1132 sizeof(INT), &cx, DO_NOT_SEEK);
1133 TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)
1134 ->rgbounds[j].lLbound,
1135 sizeof(INT), &cx, DO_NOT_SEEK);
1137 }else{
1138 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=NULL;
1139 ERR(ole, "didn't find array description data\n");
1143 /* imported type libs */
1144 if(tlbSegDir.pImpFiles.offset>0){
1145 TLBImpLib **ppImpLib=&(pLibInfo->pImpLibs);
1146 int offset=tlbSegDir.pImpFiles.offset;
1147 int oGuid;
1148 UINT16 size;
1149 while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length){
1150 *ppImpLib=TLB_Alloc(sizeof(TLBImpLib));
1151 (*ppImpLib)->offset=offset - tlbSegDir.pImpFiles.offset;
1152 TLB_Read(&oGuid, sizeof(INT), &cx, offset);
1153 TLB_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
1154 /* we are skipping some unknown info here */
1155 TLB_Read(& size,sizeof(UINT16), &cx, offset+3*(sizeof(INT)));
1156 size >>=2;
1157 (*ppImpLib)->name=TLB_Alloc(size+1);
1158 TLB_Read((*ppImpLib)->name,size, &cx, DO_NOT_SEEK);
1159 offset=(offset+3*(sizeof(INT))+sizeof(UINT16)+size+3) & 0xfffffffc;
1161 ppImpLib=&(*ppImpLib)->next;
1164 /* type info's */
1165 if(tlbHeader.nrtypeinfos >=0 ){
1166 /*pLibInfo->TypeInfoCount=tlbHeader.nrtypeinfos; */
1167 TLBTypeInfo **ppTI=&(pLibInfo->pTypeInfo);
1168 int i;
1169 for(i=0;i<(int)tlbHeader.nrtypeinfos;i++){
1170 *ppTI=TLB_DoTypeInfo(&cx, i, pLibInfo);
1171 ppTI=&((*ppTI)->next);
1172 (pLibInfo->TypeInfoCount)++;
1176 CloseHandle(cx.hFile);
1177 *ppTypeLib=(LPTYPELIB)pLibInfo;
1178 return S_OK;
1181 /*================== ITypeLib(2) Methods ===================================*/
1183 /* ITypeLib::QueryInterface
1185 static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid,
1186 VOID **ppvObject)
1188 if(TRACE_ON(typelib)){
1189 char xriid[50];
1190 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1191 TRACE(typelib,"(%p)->(IID: %s)\n",This,xriid);
1193 *ppvObject=NULL;
1194 if(IsEqualIID(riid, &IID_IUnknown) ||
1195 IsEqualIID(riid,&IID_ITypeLib)||
1196 IsEqualIID(riid,&IID_ITypeLib2))
1197 *ppvObject = This;
1198 if(*ppvObject){
1199 (*(LPTYPELIB*)ppvObject)->lpvtbl->fnAddRef(This);
1200 TRACE(typelib,"-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1201 return S_OK;
1203 TRACE(typelib,"-- Interface: E_NOINTERFACE\n");
1204 return E_NOINTERFACE;
1207 /* ITypeLib::AddRef
1209 static ULONG WINAPI ITypeLib_fnAddRef( LPTYPELIB iface)
1211 ICOM_THIS( TLBLibInfo, iface);
1212 TRACE(typelib,"(%p)->ref is %u\n",This, This->ref);
1213 return ++(This->ref);
1216 /* ITypeLib::Release
1218 static ULONG WINAPI ITypeLib_fnRelease( LPTYPELIB iface)
1220 ICOM_THIS( TLBLibInfo, iface);
1221 FIXME(typelib,"(%p)->ref is %u: stub\n",This, This->ref);
1222 (This->ref)--;
1223 return S_OK;
1226 /* ITypeLib::GetTypeInfoCount
1228 * Returns the number of type descriptions in the type library
1230 static UINT WINAPI ITypeLib_fnGetTypeInfoCount( LPTYPELIB iface)
1232 ICOM_THIS( TLBLibInfo, iface);
1233 TRACE(typelib,"(%p)->count is %d\n",This, This->TypeInfoCount);
1234 return This->TypeInfoCount;
1237 /* ITypeLib::GetTypeInfo
1239 *etrieves the specified type description in the library.
1241 static HRESULT WINAPI ITypeLib_fnGetTypeInfo( LPTYPELIB iface, UINT index,
1242 ITypeInfo **ppTInfo)
1244 int i;
1245 ICOM_THIS( TLBLibInfo, iface);
1246 TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo;
1247 TRACE(typelib,"(%p) index %d \n",This, index);
1248 for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo && i != index;i++)
1249 *ppTLBTInfo=(*ppTLBTInfo)->next;
1250 if(*ppTLBTInfo){
1251 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
1252 TRACE(typelib,"-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
1253 return S_OK;
1255 TRACE(typelib,"-- element not found\n");
1256 return TYPE_E_ELEMENTNOTFOUND;
1259 /* ITypeLibs::GetTypeInfoType
1261 * Retrieves the type of a type description.
1263 static HRESULT WINAPI ITypeLib_fnGetTypeInfoType( LPTYPELIB iface, UINT index,
1264 TYPEKIND *pTKind)
1266 int i;
1267 TLBTypeInfo *pTInfo;
1268 ICOM_THIS( TLBLibInfo, iface);
1269 TRACE(typelib,"(%p) index %d \n",This, index);
1270 for(i=0,pTInfo=This->pTypeInfo;pTInfo && i != index;i++)
1271 pTInfo=(pTInfo)->next;
1272 if(pTInfo){
1273 *pTKind=pTInfo->TypeAttr.typekind;
1274 TRACE(typelib,"-- found Type (%p)->%d\n",pTKind,*pTKind);
1275 return S_OK;
1277 TRACE(typelib,"-- element not found\n");
1278 return TYPE_E_ELEMENTNOTFOUND;
1281 /* ITypeLib::GetTypeInfoOfGuid
1283 * Retrieves the type description that corresponds to the specified GUID.
1286 static HRESULT WINAPI ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB iface,
1287 REFGUID guid, ITypeInfo **ppTInfo)
1289 int i;
1290 ICOM_THIS( TLBLibInfo, iface);
1291 TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo;
1292 if(TRACE_ON(typelib)){
1293 char xriid[50];
1294 WINE_StringFromCLSID((LPCLSID)guid,xriid);
1295 TRACE(typelib,"(%p) guid %sx)\n",This,xriid);
1297 for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo &&
1298 !IsEqualIID(guid,&(*ppTLBTInfo)->TypeAttr.guid);i++)
1299 *ppTLBTInfo=(*ppTLBTInfo)->next;
1300 if(*ppTLBTInfo){
1301 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
1302 TRACE(typelib,"-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
1303 return S_OK;
1305 TRACE(typelib,"-- element not found\n");
1306 return TYPE_E_ELEMENTNOTFOUND;
1309 /* ITypeLib::GetLibAttr
1311 * Retrieves the structure that contains the library's attributes.
1314 static HRESULT WINAPI ITypeLib_fnGetLibAttr( LPTYPELIB iface,
1315 LPTLIBATTR *ppTLibAttr)
1317 ICOM_THIS( TLBLibInfo, iface);
1318 TRACE( typelib,"(%p)\n",This);
1319 /* FIXME: must do a copy here */
1320 *ppTLibAttr=&This->LibAttr;
1321 return S_OK;
1324 /* ITypeLib::GetTypeComp
1326 * Enables a client compiler to bind to a library's types, variables,
1327 * constants, and global functions.
1330 static HRESULT WINAPI ITypeLib_fnGetTypeComp( LPTYPELIB iface,
1331 ITypeComp **ppTComp)
1333 ICOM_THIS( TLBLibInfo, iface);
1334 FIXME(typelib,"(%p): stub!\n",This);
1335 return E_NOTIMPL;
1338 /* ITypeLib::GetDocumentation
1340 * Retrieves the library's documentation string, the complete Help file name
1341 * and path, and the context identifier for the library Help topic in the Help
1342 * file.
1345 static HRESULT WINAPI ITypeLib_fnGetDocumentation( LPTYPELIB iface, INT index,
1346 BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext,
1347 BSTR *pBstrHelpFile)
1349 ICOM_THIS( TLBLibInfo, iface);
1350 HRESULT result;
1351 ITypeInfo *pTInfo;
1352 TRACE( typelib, "(%p) index %d Name(%p) DocString(%p)"
1353 " HelpContext(%p) HelpFile(%p)\n",
1354 This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1355 if(index<0){ /* documentation for the typelib */
1356 if(pBstrName)
1357 *pBstrName=TLB_DupAtoBstr(This->Name);
1358 if(pBstrDocString)
1359 *pBstrName=TLB_DupAtoBstr(This->DocString);
1360 if(pdwHelpContext)
1361 *pdwHelpContext=This->dwHelpContext;
1362 if(pBstrHelpFile)
1363 *pBstrName=TLB_DupAtoBstr(This->HelpFile);
1364 }else {/* for a typeinfo */
1365 result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo);
1366 if(SUCCEEDED(result)){
1367 result=ITypeInfo_GetDocumentation(pTInfo, MEMBERID_NIL, pBstrName,
1368 pBstrDocString, pdwHelpContext, pBstrHelpFile);
1369 ITypeInfo_Release(pTInfo);
1371 if(!SUCCEEDED(result))
1372 return result;
1374 return S_OK;
1377 /* ITypeLib::IsName
1379 * Indicates whether a passed-in string contains the name of a type or member
1380 * described in the library.
1383 static HRESULT WINAPI ITypeLib_fnIsName( LPTYPELIB iface, LPOLESTR szNameBuf,
1384 ULONG lHashVal, BOOL *pfName)
1386 ICOM_THIS( TLBLibInfo, iface);
1387 TLBTypeInfo *pTInfo;
1388 TLBFuncDesc *pFInfo;
1389 TLBVarDesc *pVInfo;
1390 int i;
1391 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1392 *pfName=TRUE;
1393 if(!strcmp(astr,This->Name)) goto ITypeLib_fnIsName_exit;
1394 for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){
1395 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnIsName_exit;
1396 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1397 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnIsName_exit;
1398 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1399 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1400 goto ITypeLib_fnIsName_exit;
1402 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
1403 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnIsName_exit;
1406 *pfName=FALSE;
1408 ITypeLib_fnIsName_exit:
1409 TRACE( typelib,"(%p)slow! search for %s: %s found!\n", This,
1410 debugstr_a(astr), *pfName?"NOT":"");
1412 HeapFree( GetProcessHeap(), 0, astr );
1413 return S_OK;
1416 /* ITypeLib::FindName
1418 * Finds occurrences of a type description in a type library. This may be used
1419 * to quickly verify that a name exists in a type library.
1422 static HRESULT WINAPI ITypeLib_fnFindName( LPTYPELIB iface, LPOLESTR szNameBuf,
1423 ULONG lHashVal, ITypeInfo **ppTInfo, MEMBERID *rgMemId, UINT16 *pcFound)
1425 ICOM_THIS( TLBLibInfo, iface);
1426 TLBTypeInfo *pTInfo;
1427 TLBFuncDesc *pFInfo;
1428 TLBVarDesc *pVInfo;
1429 int i,j = 0;
1430 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1431 for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){
1432 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnFindName_exit;
1433 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1434 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnFindName_exit;
1435 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1436 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1437 goto ITypeLib_fnFindName_exit;
1439 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
1440 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnFindName_exit;
1441 continue;
1442 ITypeLib_fnFindName_exit:
1443 pTInfo->lpvtbl->fnAddRef((LPTYPEINFO)pTInfo);
1444 ppTInfo[j]=(LPTYPEINFO)pTInfo;
1445 j++;
1447 TRACE( typelib,"(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
1448 This, *pcFound, debugstr_a(astr), j);
1450 *pcFound=j;
1452 HeapFree( GetProcessHeap(), 0, astr );
1453 return S_OK;
1456 /* ITypeLib::ReleaseTLibAttr
1458 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
1461 static VOID WINAPI ITypeLib_fnReleaseTLibAttr( LPTYPELIB iface, TLIBATTR *pTLibAttr)
1463 ICOM_THIS( TLBLibInfo, iface);
1464 TRACE( typelib,"freeing (%p)\n",This);
1465 /* nothing to do */
1468 /* ITypeLib2::GetCustData
1470 * gets the custom data
1472 static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLib * iface, REFGUID guid,
1473 VARIANT *pVarVal)
1475 ICOM_THIS( TLBLibInfo, iface);
1476 TLBCustData *pCData;
1477 for(pCData=This->pCustData; pCData; pCData = pCData->next)
1478 if( IsEqualIID(guid, &pCData->guid)) break;
1479 if(TRACE_ON(typelib)){
1480 char xriid[50];
1481 WINE_StringFromCLSID((LPCLSID)guid,xriid);
1482 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
1483 pCData? "" : "NOT");
1485 if(pCData){
1486 VariantInit( pVarVal);
1487 VariantCopy( pVarVal, &pCData->data);
1488 return S_OK;
1490 return E_INVALIDARG; /* FIXME: correct? */
1493 /* ITypeLib2::GetLibStatistics
1495 * Returns statistics about a type library that are required for efficient
1496 * sizing of hash tables.
1499 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( ITypeLib * iface,
1500 UINT *pcUniqueNames, UINT *pcchUniqueNames)
1502 ICOM_THIS( TLBLibInfo, iface);
1503 FIXME( typelib,"(%p): stub!\n", This);
1504 if(pcUniqueNames) *pcUniqueNames=1;
1505 if(pcchUniqueNames) *pcchUniqueNames=1;
1506 return S_OK;
1509 /* ITypeLib2::GetDocumentation2
1511 * Retrieves the library's documentation string, the complete Help file name
1512 * and path, the localization context to use, and the context ID for the
1513 * library Help topic in the Help file.
1516 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( ITypeLib * iface,
1517 INT index, LCID lcid, BSTR *pbstrHelpString,
1518 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
1520 ICOM_THIS( TLBLibInfo, iface);
1521 HRESULT result;
1522 ITypeInfo *pTInfo;
1523 FIXME( typelib,"(%p) index %d lcid %ld half implemented stub!\n", This,
1524 index, lcid);
1525 /* the help string should be obtained from the helpstringdll,
1526 * using the _DLLGetDocumentation function, based on the supplied
1527 * lcid. Nice to do sometime...
1529 if(index<0){ /* documentation for the typelib */
1530 if(pbstrHelpString)
1531 *pbstrHelpString=TLB_DupAtoBstr(This->DocString);
1532 if(pdwHelpStringContext)
1533 *pdwHelpStringContext=This->dwHelpContext;
1534 if(pbstrHelpStringDll)
1535 *pbstrHelpStringDll=TLB_DupAtoBstr(This->HelpStringDll);
1536 }else {/* for a typeinfo */
1537 result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo);
1538 if(SUCCEEDED(result)){
1539 result=ITypeInfo2_fnGetDocumentation2(pTInfo, MEMBERID_NIL, lcid,
1540 pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
1541 ITypeInfo_Release(pTInfo);
1543 if(!SUCCEEDED(result))
1544 return result;
1546 return S_OK;
1549 /* ITypeLib2::GetAllCustData
1551 * Gets all custom data items for the library.
1554 static HRESULT WINAPI ITypeLib2_fnGetAllCustData( ITypeLib * iface,
1555 CUSTDATA *pCustData)
1557 ICOM_THIS( TLBLibInfo, iface);
1558 TLBCustData *pCData;
1559 int i;
1560 TRACE( typelib,"(%p) returning %d items\n", This, This->ctCustData);
1561 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
1562 if(pCustData->prgCustData ){
1563 pCustData->cCustData=This->ctCustData;
1564 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
1565 pCustData->prgCustData[i].guid=pCData->guid;
1566 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
1568 }else{
1569 ERR( typelib," OUT OF MEMORY! \n");
1570 return E_OUTOFMEMORY;
1572 return S_OK;
1576 /*================== ITypeInfo(2) Methods ===================================*/
1578 /* ITypeInfo::QueryInterface
1580 static HRESULT WINAPI ITypeInfo_fnQueryInterface( LPTYPEINFO iface, REFIID riid,
1581 VOID **ppvObject)
1583 ICOM_THIS( TLBTypeInfo, iface);
1584 if(TRACE_ON(typelib)){
1585 char xriid[50];
1586 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1587 TRACE(typelib,"(%p)->(IID: %s)\n",This,xriid);
1589 *ppvObject=NULL;
1590 if(IsEqualIID(riid, &IID_IUnknown) ||
1591 IsEqualIID(riid,&IID_ITypeInfo)||
1592 IsEqualIID(riid,&IID_ITypeInfo2))
1593 *ppvObject = This;
1594 if(*ppvObject){
1595 (*(LPTYPEINFO*)ppvObject)->lpvtbl->fnAddRef(iface);
1596 TRACE(typelib,"-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1597 return S_OK;
1599 TRACE(typelib,"-- Interface: E_NOINTERFACE\n");
1600 return E_NOINTERFACE;
1603 /* ITypeInfo::AddRef
1605 static ULONG WINAPI ITypeInfo_fnAddRef( LPTYPEINFO iface)
1607 ICOM_THIS( TLBTypeInfo, iface);
1608 TRACE(typelib,"(%p)->ref is %u\n",This, This->ref);
1609 (This->pTypeLib->ref)++;
1610 return ++(This->ref);
1613 /* ITypeInfo::Release
1615 static ULONG WINAPI ITypeInfo_fnRelease( LPTYPEINFO iface)
1617 ICOM_THIS( TLBTypeInfo, iface);
1618 FIXME(typelib,"(%p)->ref is %u: stub\n",This, This->ref);
1619 (This->ref)--;
1620 (This->pTypeLib->ref)--;
1621 return S_OK;
1624 /* ITypeInfo::GetTypeAttr
1626 * Retrieves a TYPEATTR structure that contains the attributes of the type
1627 * description.
1630 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( LPTYPEINFO iface,
1631 LPTYPEATTR *ppTypeAttr)
1633 ICOM_THIS( TLBTypeInfo, iface);
1634 TRACE( typelib,"(%p)\n",This);
1635 /* FIXME: must do a copy here */
1636 *ppTypeAttr=&This->TypeAttr;
1637 return S_OK;
1640 /* ITypeInfo::GetTypeComp
1642 * Retrieves the ITypeComp interface for the type description, which enables a
1643 * client compiler to bind to the type description's members.
1646 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( LPTYPEINFO iface,
1647 ITypeComp * *ppTComp)
1649 ICOM_THIS( TLBTypeInfo, iface);
1650 FIXME( typelib,"(%p) stub!\n", This);
1651 return S_OK;
1654 /* ITypeInfo::GetFuncDesc
1656 * Retrieves the FUNCDESC structure that contains information about a
1657 * specified function.
1660 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( LPTYPEINFO iface, UINT index,
1661 LPFUNCDESC *ppFuncDesc)
1663 ICOM_THIS( TLBTypeInfo, iface);
1664 int i;
1665 TLBFuncDesc * pFDesc;
1666 TRACE( typelib,"(%p) index %d\n", This, index);
1667 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
1669 if(pFDesc){
1670 /* FIXME: must do a copy here */
1671 *ppFuncDesc=&pFDesc->funcdesc;
1672 return S_OK;
1674 return E_INVALIDARG;
1677 /* ITypeInfo::GetVarDesc
1679 * Retrieves a VARDESC structure that describes the specified variable.
1682 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( LPTYPEINFO iface, UINT index,
1683 LPVARDESC *ppVarDesc)
1685 ICOM_THIS( TLBTypeInfo, iface);
1686 int i;
1687 TLBVarDesc * pVDesc;
1688 TRACE( typelib,"(%p) index %d\n", This, index);
1689 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next)
1691 if(pVDesc){
1692 /* FIXME: must do a copy here */
1693 *ppVarDesc=&pVDesc->vardesc;
1694 return S_OK;
1696 return E_INVALIDARG;
1699 /* ITypeInfo_GetNames
1701 * Retrieves the variable with the specified member ID (or the name of the
1702 * property or method and its parameters) that correspond to the specified
1703 * function ID.
1705 static HRESULT WINAPI ITypeInfo_fnGetNames( LPTYPEINFO iface, MEMBERID memid,
1706 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
1708 ICOM_THIS( TLBTypeInfo, iface);
1709 TLBFuncDesc * pFDesc;
1710 TLBVarDesc * pVDesc;
1711 int i;
1712 TRACE( typelib,"(%p) memid=0x%08lx Maxname=%d\n", This, memid,
1713 cMaxNames);
1714 for(pFDesc=This->funclist; pFDesc->funcdesc.memid != memid && pFDesc;
1715 pFDesc=pFDesc->next)
1717 if(pFDesc){
1718 /* function found, now return function and parameter names */
1719 for(i=0; i<cMaxNames && i <= pFDesc->funcdesc.cParams; i++){
1720 if(!i) *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
1721 else
1722 rgBstrNames[i]=TLB_DupAtoBstr(pFDesc->pParamDesc[i-1].Name);
1725 *pcNames=i;
1726 }else{
1727 for(pVDesc=This->varlist; pVDesc->vardesc.memid != memid && pVDesc;
1728 pVDesc=pVDesc->next)
1730 if(pVDesc){
1731 *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
1732 *pcNames=1;
1733 }else{
1734 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
1735 This->TypeAttr.cImplTypes ){
1736 /* recursive search */
1737 ITypeInfo *pTInfo;
1738 HRESULT result;
1739 result=This->lpvtbl->fnGetRefTypeInfo(iface,
1740 This->impltypelist->reference, &pTInfo);
1741 if(SUCCEEDED(result)){
1742 result=pTInfo->lpvtbl->fnGetNames(pTInfo, memid, rgBstrNames,
1743 cMaxNames, pcNames);
1744 pTInfo->lpvtbl->fnRelease(pTInfo);
1745 return result;
1747 WARN( typelib,"Could not search inherited interface!\n");
1748 } else
1749 WARN( typelib,"no names found\n");
1750 *pcNames=0;
1751 return TYPE_E_ELEMENTNOTFOUND;
1754 return S_OK;
1758 /* ITypeInfo::GetRefTypeOfImplType
1760 * If a type description describes a COM class, it retrieves the type
1761 * description of the implemented interface types. For an interface,
1762 * GetRefTypeOfImplType returns the type information for inherited interfaces,
1763 * if any exist.
1766 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO iface,
1767 UINT index, HREFTYPE *pRefType)
1769 ICOM_THIS( TLBTypeInfo, iface);
1770 int(i);
1771 TLBRefType *pIref;
1772 TRACE( typelib,"(%p) index %d\n", This, index);
1773 for(i=0, pIref=This->impltypelist; i<index && pIref;
1774 i++, pIref=pIref->next)
1776 if(i==index){
1777 *pRefType=pIref->reference;
1778 return S_OK;
1780 return TYPE_E_ELEMENTNOTFOUND;
1783 /* ITypeInfo::GetImplTypeFlags
1785 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
1786 * or base interface in a type description.
1788 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO iface,
1789 UINT index, INT *pImplTypeFlags)
1791 ICOM_THIS( TLBTypeInfo, iface);
1792 int(i);
1793 TLBRefType *pIref;
1794 TRACE( typelib,"(%p) index %d\n", This, index);
1795 for(i=0, pIref=This->impltypelist; i<index && pIref; i++, pIref=pIref->next)
1797 if(i==index && pIref){
1798 *pImplTypeFlags=pIref->flags;
1799 return S_OK;
1801 *pImplTypeFlags=0;
1802 return TYPE_E_ELEMENTNOTFOUND;
1805 /* GetIDsOfNames
1806 * Maps between member names and member IDs, and parameter names and
1807 * parameter IDs.
1809 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( LPTYPEINFO iface,
1810 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
1812 ICOM_THIS( TLBTypeInfo, iface);
1813 TLBFuncDesc * pFDesc;
1814 TLBVarDesc * pVDesc;
1815 HRESULT ret=S_OK;
1816 PCHAR aszName= HEAP_strdupWtoA( GetProcessHeap(), 0, *rgszNames);
1817 TRACE( typelib,"(%p) Name %s cNames %d\n", This, debugstr_a(aszName),
1818 cNames);
1819 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) {
1820 int i, j;
1821 if( !strcmp(aszName, pFDesc->Name)) {
1822 if(cNames) *pMemId=pFDesc->funcdesc.memid;
1823 for(i=1; i < cNames; i++){
1824 PCHAR aszPar= HEAP_strdupWtoA( GetProcessHeap(), 0,
1825 rgszNames[i]);
1826 for(j=0; j<pFDesc->funcdesc.cParams; j++)
1827 if(strcmp(aszPar,pFDesc->pParamDesc[j].Name))
1828 break;
1829 if( j<pFDesc->funcdesc.cParams)
1830 pMemId[i]=j;
1831 else
1832 ret=DISP_E_UNKNOWNNAME;
1833 HeapFree( GetProcessHeap(), 0, aszPar);
1835 HeapFree (GetProcessHeap(), 0, aszName);
1836 return ret;
1839 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
1840 if( !strcmp(aszName, pVDesc->Name)) {
1841 if(cNames) *pMemId=pVDesc->vardesc.memid;
1842 HeapFree (GetProcessHeap(), 0, aszName);
1843 return ret;
1846 /* not found, see if this is and interface with an inheritance */
1847 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
1848 This->TypeAttr.cImplTypes ){
1849 /* recursive search */
1850 ITypeInfo *pTInfo;
1851 ret=This->lpvtbl->fnGetRefTypeInfo(iface,
1852 This->impltypelist->reference, &pTInfo);
1853 if(SUCCEEDED(ret)){
1854 ret=pTInfo->lpvtbl->fnGetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
1855 pTInfo->lpvtbl->fnRelease(pTInfo);
1856 return ret;
1858 WARN( typelib,"Could not search inherited interface!\n");
1859 } else
1860 WARN( typelib,"no names found\n");
1861 return DISP_E_UNKNOWNNAME;
1864 /* ITypeInfo::Invoke
1866 * Invokes a method, or accesses a property of an object, that implements the
1867 * interface described by the type description.
1869 static HRESULT WINAPI ITypeInfo_fnInvoke( LPTYPEINFO iface, VOID *pIUnk,
1870 MEMBERID memid, UINT16 dwFlags, DISPPARAMS *pDispParams,
1871 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *pArgErr)
1873 ICOM_THIS( TLBTypeInfo, iface);
1874 FIXME( typelib,"(%p) stub!", This);
1875 return S_OK;
1878 /* ITypeInfo::GetDocumentation
1880 * Retrieves the documentation string, the complete Help file name and path,
1881 * and the context ID for the Help topic for a specified type description.
1883 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( LPTYPEINFO iface,
1884 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
1885 DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
1887 ICOM_THIS( TLBTypeInfo, iface);
1888 TLBFuncDesc * pFDesc;
1889 TLBVarDesc * pVDesc;
1890 TRACE( typelib, "(%p) memid %ld Name(%p) DocString(%p)"
1891 " HelpContext(%p) HelpFile(%p)\n",
1892 This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1893 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
1894 if(pBstrName)
1895 *pBstrName=TLB_DupAtoBstr(This->Name);
1896 if(pBstrDocString)
1897 *pBstrDocString=TLB_DupAtoBstr(This->DocString);
1898 if(pdwHelpContext)
1899 *pdwHelpContext=This->dwHelpContext;
1900 if(pBstrHelpFile)
1901 *pBstrHelpFile=TLB_DupAtoBstr(This->DocString);/* FIXME */
1902 return S_OK;
1903 }else {/* for a member */
1904 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
1905 if(pFDesc->funcdesc.memid==memid){
1906 return S_OK;
1908 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
1909 if(pVDesc->vardesc.memid==memid){
1910 return S_OK;
1913 return TYPE_E_ELEMENTNOTFOUND;
1916 /* ITypeInfo::GetDllEntry
1918 * Retrieves a description or specification of an entry point for a function
1919 * in a DLL.
1921 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( LPTYPEINFO iface, MEMBERID memid,
1922 INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
1923 WORD *pwOrdinal)
1925 ICOM_THIS( TLBTypeInfo, iface);
1926 FIXME( typelib,"(%p) stub!\n", This);
1927 return E_FAIL;
1930 /* ITypeInfo::GetRefTypeInfo
1932 * If a type description references other type descriptions, it retrieves
1933 * the referenced type descriptions.
1935 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO iface,
1936 HREFTYPE hRefType, ITypeInfo * *ppTInfo)
1938 ICOM_THIS( TLBTypeInfo, iface);
1939 HRESULT result;
1940 if(HREFTYPE_INTHISFILE(hRefType)){
1941 ITypeLib *pTLib;
1942 int Index;
1943 result=This->lpvtbl->fnGetContainingTypeLib(iface, &pTLib,
1944 &Index);
1945 if(SUCCEEDED(result)){
1946 result=pTLib->lpvtbl->fnGetTypeInfo(pTLib,
1947 HREFTYPE_INDEX(hRefType),
1948 ppTInfo);
1949 pTLib->lpvtbl->fnRelease(pTLib );
1951 } else{
1952 /* imported type lib */
1953 TLBRefType * pRefType;
1954 TLBLibInfo *pTypeLib;
1955 for( pRefType=This->impltypelist; pRefType &&
1956 pRefType->reference != hRefType; pRefType=pRefType->next)
1958 if(!pRefType)
1959 return TYPE_E_ELEMENTNOTFOUND; //FIXME : correct?
1960 pTypeLib=pRefType->pImpTLInfo->pImpTypeLib;
1961 if(pTypeLib) // typelib already loaded
1962 result=pTypeLib->lpvtbl->fnGetTypeInfoOfGuid(
1963 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
1964 else{
1965 result=LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
1966 0,0,0, /* FIXME */
1967 (LPTYPELIB *)&pTypeLib);
1968 if(!SUCCEEDED(result)){
1969 BSTR libnam=TLB_DupAtoBstr(pRefType->pImpTLInfo->name);
1970 result=LoadTypeLib(libnam, (LPTYPELIB *)&pTypeLib);
1971 SysFreeString(libnam);
1973 if(SUCCEEDED(result)){
1974 result=pTypeLib->lpvtbl->fnGetTypeInfoOfGuid(
1975 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
1976 pRefType->pImpTLInfo->pImpTypeLib=pTypeLib;
1980 TRACE( typelib,"(%p) hreftype 0x%04lx loaded %s (%p)\n", This, hRefType,
1981 SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
1982 return result;
1985 /* ITypeInfo::AddressOfMember
1987 * Retrieves the addresses of static functions or variables, such as those
1988 * defined in a DLL.
1990 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( LPTYPEINFO iface,
1991 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
1993 ICOM_THIS( TLBTypeInfo, iface);
1994 FIXME( typelib,"(%p) stub!\n", This);
1995 return S_OK;
1998 /* ITypeInfo::CreateInstance
2000 * Creates a new instance of a type that describes a component object class
2001 * (coclass).
2003 static HRESULT WINAPI ITypeInfo_fnCreateInstance( LPTYPEINFO iface,
2004 IUnknown *pUnk, REFIID riid, VOID **ppvObj)
2006 ICOM_THIS( TLBTypeInfo, iface);
2007 FIXME( typelib,"(%p) stub!\n", This);
2008 return S_OK;
2011 /* ITypeInfo::GetMops
2013 * Retrieves marshaling information.
2015 static HRESULT WINAPI ITypeInfo_fnGetMops( LPTYPEINFO iface, MEMBERID memid,
2016 BSTR *pBstrMops)
2018 ICOM_THIS( TLBTypeInfo, iface);
2019 FIXME( typelib,"(%p) stub!\n", This);
2020 return S_OK;
2023 /* ITypeInfo::GetContainingTypeLib
2025 * Retrieves the containing type library and the index of the type description
2026 * within that type library.
2028 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( LPTYPEINFO iface,
2029 ITypeLib * *ppTLib, UINT *pIndex)
2031 ICOM_THIS( TLBTypeInfo, iface);
2032 *ppTLib=(LPTYPELIB )(This->pTypeLib);
2033 *pIndex=This->index;
2034 (*ppTLib)->lpvtbl->fnAddRef(*ppTLib);
2035 TRACE( typelib,"(%p) returns (%p) index %d!\n", This, *ppTLib, *pIndex);
2036 return S_OK;
2039 /* ITypeInfo::ReleaseTypeAttr
2041 * Releases a TYPEATTR previously returned by GetTypeAttr.
2044 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO iface,
2045 TYPEATTR* pTypeAttr)
2047 ICOM_THIS( TLBTypeInfo, iface);
2048 TRACE( typelib,"(%p)->(%p)\n", This, pTypeAttr);
2049 return S_OK;
2052 /* ITypeInfo::ReleaseFuncDesc
2054 * Releases a FUNCDESC previously returned by GetFuncDesc. *
2056 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO iface,
2057 FUNCDESC *pFuncDesc)
2059 ICOM_THIS( TLBTypeInfo, iface);
2060 TRACE( typelib,"(%p)->(%p)\n", This, pFuncDesc);
2061 return S_OK;
2064 /* ITypeInfo::ReleaseVarDesc
2066 * Releases a VARDESC previously returned by GetVarDesc.
2068 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( LPTYPEINFO iface,
2069 VARDESC *pVarDesc)
2071 ICOM_THIS( TLBTypeInfo, iface);
2072 TRACE( typelib,"(%p)->(%p)\n", This, pVarDesc);
2073 return S_OK;
2076 /* ITypeInfo2::GetTypeKind
2078 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
2081 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo * iface,
2082 TYPEKIND *pTypeKind)
2084 ICOM_THIS( TLBTypeInfo, iface);
2085 *pTypeKind=This->TypeAttr.typekind;
2086 TRACE( typelib,"(%p) type 0x%0x\n", This,*pTypeKind);
2087 return S_OK;
2090 /* ITypeInfo2::GetTypeFlags
2092 * Returns the type flags without any allocations. This returns a DWORD type
2093 * flag, which expands the type flags without growing the TYPEATTR (type
2094 * attribute).
2097 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo * iface,
2098 UINT *pTypeFlags)
2100 ICOM_THIS( TLBTypeInfo, iface);
2101 *pTypeFlags=This->TypeAttr.wTypeFlags;
2102 TRACE( typelib,"(%p) flags 0x%04x\n", This,*pTypeFlags);
2103 return S_OK;
2106 /* ITypeInfo2::GetFuncIndexOfMemId
2107 * Binds to a specific member based on a known DISPID, where the member name
2108 * is not known (for example, when binding to a default member).
2111 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo * iface,
2112 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
2114 ICOM_THIS( TLBTypeInfo, iface);
2115 TLBFuncDesc *pFuncInfo;
2116 int i;
2117 HRESULT result;
2118 /* FIXME: should check for invKind??? */
2119 for(i=0, pFuncInfo=This->funclist;pFuncInfo &&
2120 memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next);
2121 if(pFuncInfo){
2122 *pFuncIndex=i;
2123 result= S_OK;
2124 }else{
2125 *pFuncIndex=0;
2126 result=E_INVALIDARG;
2128 TRACE( typelib,"(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This,
2129 memid, invKind, SUCCEEDED(result)? "SUCCES":"FAILED");
2130 return result;
2133 /* TypeInfo2::GetVarIndexOfMemId
2135 * Binds to a specific member based on a known DISPID, where the member name
2136 * is not known (for example, when binding to a default member).
2139 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo * iface,
2140 MEMBERID memid, UINT *pVarIndex)
2142 ICOM_THIS( TLBTypeInfo, iface);
2143 TLBVarDesc *pVarInfo;
2144 int i;
2145 HRESULT result;
2146 for(i=0, pVarInfo=This->varlist; pVarInfo &&
2147 memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next)
2149 if(pVarInfo){
2150 *pVarIndex=i;
2151 result= S_OK;
2152 }else{
2153 *pVarIndex=0;
2154 result=E_INVALIDARG;
2156 TRACE( typelib,"(%p) memid 0x%08lx -> %s\n", This,
2157 memid, SUCCEEDED(result)? "SUCCES":"FAILED");
2158 return result;
2161 /* ITypeInfo2::GetCustData
2163 * Gets the custom data
2165 static HRESULT WINAPI ITypeInfo2_fnGetCustData( ITypeInfo * iface,
2166 REFGUID guid, VARIANT *pVarVal)
2168 ICOM_THIS( TLBTypeInfo, iface);
2169 TLBCustData *pCData;
2170 for(pCData=This->pCustData; pCData; pCData = pCData->next)
2171 if( IsEqualIID(guid, &pCData->guid)) break;
2172 if(TRACE_ON(typelib)){
2173 char xriid[50];
2174 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2175 TRACE(typelib,"(%p) guid %s %s found!x)\n", This, xriid,
2176 pCData? "" : "NOT");
2178 if(pCData){
2179 VariantInit( pVarVal);
2180 VariantCopy( pVarVal, &pCData->data);
2181 return S_OK;
2183 return E_INVALIDARG; /* FIXME: correct? */
2186 /* ITypeInfo2::GetFuncCustData
2188 * Gets the custom data
2190 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( ITypeInfo * iface,
2191 UINT index, REFGUID guid, VARIANT *pVarVal)
2193 ICOM_THIS( TLBTypeInfo, iface);
2194 TLBCustData *pCData=NULL;
2195 TLBFuncDesc * pFDesc;
2196 int i;
2197 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2198 pFDesc=pFDesc->next)
2200 if(pFDesc)
2201 for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next)
2202 if( IsEqualIID(guid, &pCData->guid)) break;
2203 if(TRACE_ON(typelib)){
2204 char xriid[50];
2205 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2206 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
2207 pCData? "" : "NOT");
2209 if(pCData){
2210 VariantInit( pVarVal);
2211 VariantCopy( pVarVal, &pCData->data);
2212 return S_OK;
2214 return E_INVALIDARG; /* FIXME: correct? */
2217 /* ITypeInfo2::GetParamCustData
2219 * Gets the custom data
2221 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( ITypeInfo * iface,
2222 UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal)
2224 ICOM_THIS( TLBTypeInfo, iface);
2225 TLBCustData *pCData=NULL;
2226 TLBFuncDesc * pFDesc;
2227 int i;
2228 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
2229 pFDesc=pFDesc->next)
2231 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams)
2232 for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData;
2233 pCData = pCData->next)
2234 if( IsEqualIID(guid, &pCData->guid)) break;
2235 if(TRACE_ON(typelib)){
2236 char xriid[50];
2237 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2238 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
2239 pCData? "" : "NOT");
2241 if(pCData){
2242 VariantInit( pVarVal);
2243 VariantCopy( pVarVal, &pCData->data);
2244 return S_OK;
2246 return E_INVALIDARG; /* FIXME: correct? */
2249 /* ITypeInfo2::GetVarcCustData
2251 * Gets the custom data
2253 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( ITypeInfo * iface,
2254 UINT index, REFGUID guid, VARIANT *pVarVal)
2256 ICOM_THIS( TLBTypeInfo, iface);
2257 TLBCustData *pCData=NULL;
2258 TLBVarDesc * pVDesc;
2259 int i;
2260 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2261 pVDesc=pVDesc->next)
2263 if(pVDesc)
2264 for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next)
2265 if( IsEqualIID(guid, &pCData->guid)) break;
2266 if(TRACE_ON(typelib)){
2267 char xriid[50];
2268 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2269 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
2270 pCData? "" : "NOT");
2272 if(pCData){
2273 VariantInit( pVarVal);
2274 VariantCopy( pVarVal, &pCData->data);
2275 return S_OK;
2277 return E_INVALIDARG; /* FIXME: correct? */
2280 /* ITypeInfo2::GetImplcCustData
2282 * Gets the custom data
2284 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( ITypeInfo * iface,
2285 UINT index, REFGUID guid, VARIANT *pVarVal)
2287 ICOM_THIS( TLBTypeInfo, iface);
2288 TLBCustData *pCData=NULL;
2289 TLBRefType * pRDesc;
2290 int i;
2291 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2292 pRDesc=pRDesc->next)
2294 if(pRDesc)
2295 for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next)
2296 if( IsEqualIID(guid, &pCData->guid)) break;
2297 if(TRACE_ON(typelib)){
2298 char xriid[50];
2299 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2300 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
2301 pCData? "" : "NOT");
2303 if(pCData){
2304 VariantInit( pVarVal);
2305 VariantCopy( pVarVal, &pCData->data);
2306 return S_OK;
2308 return E_INVALIDARG; /* FIXME: correct? */
2311 /* ITypeInfo2::GetDocumentation2
2313 * Retrieves the documentation string, the complete Help file name and path,
2314 * the localization context to use, and the context ID for the library Help
2315 * topic in the Help file.
2318 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( ITypeInfo * iface,
2319 MEMBERID memid, LCID lcid, BSTR *pbstrHelpString,
2320 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
2322 ICOM_THIS( TLBTypeInfo, iface);
2323 TLBFuncDesc * pFDesc;
2324 TLBVarDesc * pVDesc;
2325 TRACE( typelib, "(%p) memid %ld lcid(0x%lx) HelpString(%p) "
2326 "HelpStringContext(%p) HelpStringDll(%p)\n",
2327 This, memid, lcid, pbstrHelpString, pdwHelpStringContext,
2328 pbstrHelpStringDll );
2329 /* the help string should be obtained from the helpstringdll,
2330 * using the _DLLGetDocumentation function, based on the supplied
2331 * lcid. Nice to do sometime...
2333 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
2334 if(pbstrHelpString)
2335 *pbstrHelpString=TLB_DupAtoBstr(This->Name);
2336 if(pdwHelpStringContext)
2337 *pdwHelpStringContext=This->dwHelpStringContext;
2338 if(pbstrHelpStringDll)
2339 *pbstrHelpStringDll=
2340 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2341 return S_OK;
2342 }else {/* for a member */
2343 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
2344 if(pFDesc->funcdesc.memid==memid){
2345 if(pbstrHelpString)
2346 *pbstrHelpString=TLB_DupAtoBstr(pFDesc->HelpString);
2347 if(pdwHelpStringContext)
2348 *pdwHelpStringContext=pFDesc->HelpStringContext;
2349 if(pbstrHelpStringDll)
2350 *pbstrHelpStringDll=
2351 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2352 return S_OK;
2354 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
2355 if(pVDesc->vardesc.memid==memid){
2356 if(pbstrHelpString)
2357 *pbstrHelpString=TLB_DupAtoBstr(pVDesc->HelpString);
2358 if(pdwHelpStringContext)
2359 *pdwHelpStringContext=pVDesc->HelpStringContext;
2360 if(pbstrHelpStringDll)
2361 *pbstrHelpStringDll=
2362 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2363 return S_OK;
2366 return TYPE_E_ELEMENTNOTFOUND;
2369 /* ITypeInfo2::GetAllCustData
2371 * Gets all custom data items for the Type info.
2374 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( ITypeInfo * iface,
2375 CUSTDATA *pCustData)
2377 ICOM_THIS( TLBTypeInfo, iface);
2378 TLBCustData *pCData;
2379 int i;
2380 TRACE( typelib,"(%p) returning %d items\n", This, This->ctCustData);
2381 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
2382 if(pCustData->prgCustData ){
2383 pCustData->cCustData=This->ctCustData;
2384 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
2385 pCustData->prgCustData[i].guid=pCData->guid;
2386 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
2388 }else{
2389 ERR( typelib," OUT OF MEMORY! \n");
2390 return E_OUTOFMEMORY;
2392 return S_OK;
2395 /* ITypeInfo2::GetAllFuncCustData
2397 * Gets all custom data items for the specified Function
2400 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( ITypeInfo * iface,
2401 UINT index, CUSTDATA *pCustData)
2403 ICOM_THIS( TLBTypeInfo, iface);
2404 TLBCustData *pCData;
2405 TLBFuncDesc * pFDesc;
2406 int i;
2407 TRACE( typelib,"(%p) index %d\n", This, index);
2408 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2409 pFDesc=pFDesc->next)
2411 if(pFDesc){
2412 pCustData->prgCustData =
2413 TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM));
2414 if(pCustData->prgCustData ){
2415 pCustData->cCustData=pFDesc->ctCustData;
2416 for(i=0, pCData=pFDesc->pCustData; pCData; i++,
2417 pCData = pCData->next){
2418 pCustData->prgCustData[i].guid=pCData->guid;
2419 VariantCopy(& pCustData->prgCustData[i].varValue,
2420 & pCData->data);
2422 }else{
2423 ERR( typelib," OUT OF MEMORY! \n");
2424 return E_OUTOFMEMORY;
2426 return S_OK;
2428 return TYPE_E_ELEMENTNOTFOUND;
2431 /* ITypeInfo2::GetAllParamCustData
2433 * Gets all custom data items for the Functions
2436 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo * iface,
2437 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
2439 ICOM_THIS( TLBTypeInfo, iface);
2440 TLBCustData *pCData=NULL;
2441 TLBFuncDesc * pFDesc;
2442 int i;
2443 TRACE( typelib,"(%p) index %d\n", This, indexFunc);
2444 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
2445 pFDesc=pFDesc->next)
2447 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams){
2448 pCustData->prgCustData =
2449 TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData *
2450 sizeof(CUSTDATAITEM));
2451 if(pCustData->prgCustData ){
2452 pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData;
2453 for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData;
2454 pCData; i++, pCData = pCData->next){
2455 pCustData->prgCustData[i].guid=pCData->guid;
2456 VariantCopy(& pCustData->prgCustData[i].varValue,
2457 & pCData->data);
2459 }else{
2460 ERR( typelib," OUT OF MEMORY! \n");
2461 return E_OUTOFMEMORY;
2463 return S_OK;
2465 return TYPE_E_ELEMENTNOTFOUND;
2468 /* ITypeInfo2::GetAllVarCustData
2470 * Gets all custom data items for the specified Variable
2473 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo * iface,
2474 UINT index, CUSTDATA *pCustData)
2476 ICOM_THIS( TLBTypeInfo, iface);
2477 TLBCustData *pCData;
2478 TLBVarDesc * pVDesc;
2479 int i;
2480 TRACE( typelib,"(%p) index %d\n", This, index);
2481 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2482 pVDesc=pVDesc->next)
2484 if(pVDesc){
2485 pCustData->prgCustData =
2486 TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM));
2487 if(pCustData->prgCustData ){
2488 pCustData->cCustData=pVDesc->ctCustData;
2489 for(i=0, pCData=pVDesc->pCustData; pCData; i++,
2490 pCData = pCData->next){
2491 pCustData->prgCustData[i].guid=pCData->guid;
2492 VariantCopy(& pCustData->prgCustData[i].varValue,
2493 & pCData->data);
2495 }else{
2496 ERR( typelib," OUT OF MEMORY! \n");
2497 return E_OUTOFMEMORY;
2499 return S_OK;
2501 return TYPE_E_ELEMENTNOTFOUND;
2504 /* ITypeInfo2::GetAllImplCustData
2506 * Gets all custom data items for the specified implementation type
2509 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo * iface,
2510 UINT index, CUSTDATA *pCustData)
2512 ICOM_THIS( TLBTypeInfo, iface);
2513 TLBCustData *pCData;
2514 TLBRefType * pRDesc;
2515 int i;
2516 TRACE( typelib,"(%p) index %d\n", This, index);
2517 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2518 pRDesc=pRDesc->next)
2520 if(pRDesc){
2521 pCustData->prgCustData =
2522 TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM));
2523 if(pCustData->prgCustData ){
2524 pCustData->cCustData=pRDesc->ctCustData;
2525 for(i=0, pCData=pRDesc->pCustData; pCData; i++,
2526 pCData = pCData->next){
2527 pCustData->prgCustData[i].guid=pCData->guid;
2528 VariantCopy(& pCustData->prgCustData[i].varValue,
2529 & pCData->data);
2531 }else{
2532 ERR( typelib," OUT OF MEMORY! \n");
2533 return E_OUTOFMEMORY;
2535 return S_OK;
2537 return TYPE_E_ELEMENTNOTFOUND;