Fixed TLB_Read (can easily get count!=bytesread at the end of the file).
[wine/dcerpc.git] / ole / typelib.c
blob830778ee2e368ae88456dc1e2862df4788e08c01
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( pcx->hFile, where, 0,FILE_BEGIN))
527 ) ||
528 !ReadFile(pcx->hFile, buffer, count, &bytesread, NULL)
530 /* FIXME */
531 ERR(typelib,"read error is 0x%lx reading %ld bytes at 0x%lx\n",
532 GetLastError(), count, where);
533 TLB_abort();
534 exit(1);
536 return bytesread;
539 static void TLB_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
541 if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){
542 memset(pGuid,0, sizeof(GUID));
543 return;
545 TLB_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset );
548 PCHAR TLB_ReadName( TLBContext *pcx, int offset)
550 char * name;
551 TLBNameIntro niName;
552 TLB_Read(&niName, sizeof(niName), pcx,
553 pcx->pTblDir->pNametab.offset+offset);
554 niName.namelen &= 0xFF; /* FIXME: correct ? */
555 name=TLB_Alloc((niName.namelen & 0xff) +1);
556 TLB_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK);
557 name[niName.namelen & 0xff]='\0';
558 return name;
560 PCHAR TLB_ReadString( TLBContext *pcx, int offset)
562 char * string;
563 INT16 length;
564 if(offset<0) return NULL;
565 TLB_Read(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
566 if(length <= 0) return 0;
567 string=TLB_Alloc(length +1);
568 TLB_Read(string, length, pcx, DO_NOT_SEEK);
569 string[length]='\0';
570 return string;
573 * read a value and fill a VARIANT structure
575 static void TLB_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
577 int size;
578 if(offset <0) { /* data is packed in here */
579 pVar->vt = (offset & 0x7c000000 )>> 26;
580 V_UNION(pVar, iVal) = offset & 0xffff;
581 return;
583 TLB_Read(&(pVar->vt), sizeof(VARTYPE), pcx,
584 pcx->pTblDir->pCustData.offset + offset );
585 switch(pVar->vt){
586 case VT_EMPTY: /* FIXME: is this right? */
587 case VT_NULL: /* FIXME: is this right? */
588 case VT_I2 : /* this should not happen */
589 case VT_I4 :
590 case VT_R4 :
591 case VT_ERROR :
592 case VT_BOOL :
593 case VT_I1 :
594 case VT_UI1 :
595 case VT_UI2 :
596 case VT_UI4 :
597 case VT_INT :
598 case VT_UINT :
599 case VT_VOID : /* FIXME: is this right? */
600 case VT_HRESULT :
601 size=4; break;
602 case VT_R8 :
603 case VT_CY :
604 case VT_DATE :
605 case VT_I8 :
606 case VT_UI8 :
607 case VT_DECIMAL : /* FIXME: is this right? */
608 case VT_FILETIME :
609 size=8;break;
610 /* pointer types with known behaviour */
611 case VT_BSTR :{
612 char * ptr;
613 TLB_Read(&size, sizeof(INT), pcx, DO_NOT_SEEK );
614 ptr=TLB_Alloc(size);/* allocate temp buffer */
615 TLB_Read(ptr, size, pcx, DO_NOT_SEEK ); /* read string (ANSI) */
616 V_UNION(pVar, bstrVal)=SysAllocStringLen(NULL,size);
617 /* FIXME: do we need a AtoW conversion here? */
618 V_UNION(pVar, bstrVal[size])=L'\0';
619 while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
620 TLB_Free(ptr);
622 size=-4; break;
623 /* FIXME: this will not work AT ALL when the variant contains a pointer */
624 case VT_DISPATCH :
625 case VT_VARIANT :
626 case VT_UNKNOWN :
627 case VT_PTR :
628 case VT_SAFEARRAY :
629 case VT_CARRAY :
630 case VT_USERDEFINED :
631 case VT_LPSTR :
632 case VT_LPWSTR :
633 case VT_BLOB :
634 case VT_STREAM :
635 case VT_STORAGE :
636 case VT_STREAMED_OBJECT :
637 case VT_STORED_OBJECT :
638 case VT_BLOB_OBJECT :
639 case VT_CF :
640 case VT_CLSID :
641 default:
642 size=0;
643 FIXME(ole,"VARTYPE %d is not supported, setting pointer to NULL\n",
644 pVar->vt);
647 if(size>0) /* (big|small) endian correct? */
648 TLB_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK );
649 return ;
652 * create a linked list with custom data
654 static int TLB_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
656 TLBCDGuid entry;
657 TLBCustData* pNew;
658 int count=0;
659 while(offset >=0){
660 count++;
661 pNew=TLB_Alloc(sizeof(TLBCustData));
662 TLB_Read(&entry, sizeof(entry), pcx,
663 pcx->pTblDir->pCDGuids.offset+offset);
664 TLB_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
665 TLB_ReadValue(&(pNew->data), entry.DataOffset, pcx);
666 /* add new custom data at head of the list */
667 pNew->next=*ppCustData;
668 *ppCustData=pNew;
669 offset = entry.next;
671 return count;
674 static void TLB_GetTdesc(TLBContext *pcx, INT type,TYPEDESC * pTd )
676 if(type <0)
677 pTd->vt=type & VT_TYPEMASK;
678 else
679 *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
681 static void TLB_DoFuncs(TLBContext *pcx, int cFuncs, int cVars,
682 int offset, TLBFuncDesc ** pptfd)
685 * member information is stored in a data structure at offset
686 * indicated by the memoffset field of the typeinfo structure
687 * There are several distinctive parts.
688 * the first part starts with a field that holds the total length
689 * of this (first) part excluding this field. Then follow the records,
690 * for each member there is one record.
692 * First entry is always the length of the record (excluding this
693 * length word).
694 * Rest of the record depends on the type of the member. If there is
695 * a field indicating the member type (function variable intereface etc)
696 * I have not found it yet. At this time we depend on the information
697 * in the type info and the usual order how things are stored.
699 * Second follows an array sized nrMEM*sizeof(INT) with a memeber id
700 * for each member;
702 * Third is a equal sized array with file offsets to the name entry
703 * of each member.
705 * Forth and last (?) part is an array with offsets to the records in the
706 * first part of this file segment.
709 int infolen, nameoffset, reclength, nrattributes;
710 char recbuf[512];
711 TLBFuncRecord * pFuncRec=(TLBFuncRecord *) recbuf;
712 int i, j;
713 int recoffset=offset+sizeof(INT);
714 TLB_Read(&infolen,sizeof(INT), pcx, offset);
715 for(i=0;i<cFuncs;i++){
716 *pptfd=TLB_Alloc(sizeof(TLBFuncDesc));
717 /* name, eventually add to a hash table */
718 TLB_Read(&nameoffset, sizeof(INT), pcx,
719 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
720 (*pptfd)->Name=TLB_ReadName(pcx, nameoffset);
721 /* read the function information record */
722 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
723 reclength &=0x1ff;
724 TLB_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
725 /* do the attributes */
726 nrattributes=(reclength-pFuncRec->nrargs*3*sizeof(int)-0x18)
727 /sizeof(int);
728 if(nrattributes>0){
729 (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
730 if(nrattributes>1){
731 (*pptfd)->HelpString = TLB_ReadString(pcx,
732 pFuncRec->OptAttr[1]) ;
733 if(nrattributes>2){
734 if(pFuncRec->FKCCIC & 0x2000)
735 (*pptfd)->Entry = (char *) pFuncRec->OptAttr[2] ;
736 else
737 (*pptfd)->Entry = TLB_ReadString(pcx,
738 pFuncRec->OptAttr[2]);
739 if(nrattributes>5 )
740 (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;
741 if(nrattributes>6 && pFuncRec->FKCCIC & 0x80){
742 TLB_CustData(pcx, pFuncRec->OptAttr[6],
743 &(*pptfd)->pCustData);
748 /* fill the FuncDesc Structure */
749 TLB_Read(&(*pptfd)->funcdesc.memid, sizeof(INT), pcx,
750 offset + infolen + ( i + 1) * sizeof(INT));
751 (*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
752 (*pptfd)->funcdesc.invkind = ((pFuncRec->FKCCIC) >>3) & 0xF;
753 (*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >>8 & 0xF;
754 (*pptfd)->funcdesc.cParams = pFuncRec->nrargs ;
755 (*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ;
756 (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ;
757 (*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
758 TLB_GetTdesc(pcx, pFuncRec->DataType,
759 &(*pptfd)->funcdesc.elemdescFunc.tdesc) ;
761 /* do the parameters/arguments */
762 if(pFuncRec->nrargs){
763 TLBParameterInfo paraminfo;
764 (*pptfd)->funcdesc.lprgelemdescParam=
765 TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
766 (*pptfd)->pParamDesc=TLB_Alloc(pFuncRec->nrargs *
767 sizeof(TLBParDesc));
769 TLB_Read(&paraminfo,sizeof(paraminfo), pcx, recoffset+reclength -
770 pFuncRec->nrargs * sizeof(TLBParameterInfo));
771 for(j=0;j<pFuncRec->nrargs;j++){
772 TLB_GetTdesc(pcx, paraminfo.DataType,
773 &(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc) ;
774 V_UNION(&((*pptfd)->funcdesc.lprgelemdescParam[j]),
775 paramdesc.wParamFlags) = paraminfo.Flags;
776 (*pptfd)->pParamDesc[j].Name=(void *)paraminfo.oName;
777 TLB_Read(&paraminfo,sizeof(TLBParameterInfo), pcx,
778 DO_NOT_SEEK);
780 /* second time around */
781 for(j=0;j<pFuncRec->nrargs;j++){
782 /* name */
783 (*pptfd)->pParamDesc[j].Name=
784 TLB_ReadName(pcx, (int)(*pptfd)->pParamDesc[j].Name);
785 /* default value */
786 if((PARAMFLAG_FHASDEFAULT & V_UNION(&((*pptfd)->funcdesc.
787 lprgelemdescParam[j]),paramdesc.wParamFlags)) &&
788 ((pFuncRec->FKCCIC) & 0x1000)){
789 INT *pInt=(INT *)((char *)pFuncRec + reclength -
790 (pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
791 PARAMDESC * pParamDesc= &V_UNION(&((*pptfd)->funcdesc.
792 lprgelemdescParam[j]),paramdesc);
793 pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
794 pParamDesc->pparamdescex->cBytes= sizeof(PARAMDESCEX);
795 TLB_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
796 pInt[j], pcx);
798 /* custom info */
799 if(nrattributes>7+j && pFuncRec->FKCCIC & 0x80)
800 TLB_CustData(pcx, pFuncRec->OptAttr[7+j],
801 &(*pptfd)->pParamDesc[j].pCustData);
804 /* scode is not used: archaic win16 stuff FIXME: right? */
805 (*pptfd)->funcdesc.cScodes = 0 ;
806 (*pptfd)->funcdesc.lprgscode = NULL ;
807 pptfd=&((*pptfd)->next);
808 recoffset += reclength;
811 static void TLB_DoVars(TLBContext *pcx, int cFuncs, int cVars,
812 int offset, TLBVarDesc ** pptvd)
814 int infolen, nameoffset, reclength;
815 char recbuf[256];
816 TLBVarRecord * pVarRec=(TLBVarRecord *) recbuf;
817 int i;
818 int recoffset;
819 TLB_Read(&infolen,sizeof(INT), pcx, offset);
820 TLB_Read(&recoffset,sizeof(INT), pcx, offset + infolen +
821 ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
822 recoffset += offset+sizeof(INT);
823 for(i=0;i<cVars;i++){
824 *pptvd=TLB_Alloc(sizeof(TLBVarDesc));
825 /* name, eventually add to a hash table */
826 TLB_Read(&nameoffset, sizeof(INT), pcx,
827 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
828 (*pptvd)->Name=TLB_ReadName(pcx, nameoffset);
829 /* read the variable information record */
830 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
831 reclength &=0xff;
832 TLB_Read(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
833 /* Optional data */
834 if(reclength >(6*sizeof(INT)) )
835 (*pptvd)->HelpContext=pVarRec->HelpContext;
836 if(reclength >(7*sizeof(INT)) )
837 (*pptvd)->HelpString = TLB_ReadString(pcx, pVarRec->oHelpString) ;
838 if(reclength >(8*sizeof(INT)) )
839 if(reclength >(9*sizeof(INT)) )
840 (*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
841 /* fill the VarDesc Structure */
842 TLB_Read(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
843 offset + infolen + ( i + 1) * sizeof(INT));
844 (*pptvd)->vardesc.varkind = pVarRec->VarKind;
845 (*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
846 TLB_GetTdesc(pcx, pVarRec->DataType,
847 &(*pptvd)->vardesc.elemdescVar.tdesc) ;
848 /* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) fixme?? */
849 if(pVarRec->VarKind == VAR_CONST ){
850 V_UNION(&((*pptvd)->vardesc),lpvarValue)=TLB_Alloc(sizeof(VARIANT));
851 TLB_ReadValue(V_UNION(&((*pptvd)->vardesc),lpvarValue),
852 pVarRec->OffsValue, pcx);
853 }else
854 V_UNION(&((*pptvd)->vardesc),oInst)=pVarRec->OffsValue;
855 pptvd=&((*pptvd)->next);
856 recoffset += reclength;
859 /* fill in data for a hreftype (offset). When the refernced type is contained
860 * in the typelib, its just an (file) offset in the type info base dir.
861 * If comes fom import, its an offset+1 in the ImpInfo table
862 * */
863 static void TLB_DoRefType(TLBContext *pcx,
864 int offset, TLBRefType ** pprtd)
866 int j;
867 if(!HREFTYPE_INTHISFILE( offset)) {
868 /* external typelib */
869 TLBImpInfo impinfo;
870 TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs);
871 TLB_Read(&impinfo, sizeof(impinfo), pcx,
872 pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
873 for(j=0;pImpLib;j++){ /* search the known offsets of all import libraries */
874 if(pImpLib->offset==impinfo.oImpFile) break;
875 pImpLib=pImpLib->next;
877 if(pImpLib){
878 (*pprtd)->reference=offset;
879 (*pprtd)->pImpTLInfo=pImpLib;
880 TLB_ReadGuid(&(*pprtd)->guid, impinfo.oGuid, pcx);
881 }else{
882 ERR( typelib ,"Cannot find a reference\n");
883 (*pprtd)->reference=-1;
884 (*pprtd)->pImpTLInfo=(void *)-1;
886 }else{
887 /* in this typelib */
888 (*pprtd)->reference=offset;
889 (*pprtd)->pImpTLInfo=(void *)-2;
893 /* process Implemented Interfaces of a com class */
894 static void TLB_DoImplTypes(TLBContext *pcx, int count,
895 int offset, TLBRefType ** pprtd)
897 int i;
898 TLBRefRecord refrec;
899 for(i=0;i<count;i++){
900 if(offset<0) break; /* paranoia */
901 *pprtd=TLB_Alloc(sizeof(TLBRefType));
902 TLB_Read(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
903 TLB_DoRefType(pcx, refrec.reftype, pprtd);
904 (*pprtd)->flags=refrec.flags;
905 (*pprtd)->ctCustData=
906 TLB_CustData(pcx, refrec.oCustData, &(*pprtd)->pCustData);
907 offset=refrec.onext;
908 pprtd=&((*pprtd)->next);
912 * process a typeinfo record
914 TLBTypeInfo * TLB_DoTypeInfo(TLBContext *pcx, int count, TLBLibInfo* pLibInfo)
916 TLBTypeInfoBase tiBase;
917 TLBTypeInfo *ptiRet;
918 ptiRet=TLB_Alloc(sizeof(TLBTypeInfo));
919 ptiRet->lpvtbl = &tinfvt;
920 ptiRet->ref=1;
921 TLB_Read(&tiBase, sizeof(tiBase) ,pcx ,
922 pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
923 /* this where we are coming from */
924 ptiRet->pTypeLib=pLibInfo;
925 ptiRet->index=count;
926 /* fill in the typeattr fields */
927 TLB_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx);
928 ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid; /* FIXME: correct? */
929 ptiRet->TypeAttr.memidConstructor=MEMBERID_NIL ;/* FIXME */
930 ptiRet->TypeAttr.memidDestructor=MEMBERID_NIL ; /* FIXME */
931 ptiRet->TypeAttr.lpstrSchema=NULL; /* reserved */
932 ptiRet->TypeAttr.cbSizeInstance=tiBase.size;
933 ptiRet->TypeAttr.typekind=tiBase.typekind & 0xF;
934 ptiRet->TypeAttr.cFuncs=LOWORD(tiBase.cElement);
935 ptiRet->TypeAttr.cVars=HIWORD(tiBase.cElement);
936 ptiRet->TypeAttr.cbAlignment=(tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */
937 ptiRet->TypeAttr.wTypeFlags=tiBase.flags;
938 ptiRet->TypeAttr.wMajorVerNum=LOWORD(tiBase.version);
939 ptiRet->TypeAttr.wMinorVerNum=HIWORD(tiBase.version);
940 ptiRet->TypeAttr.cImplTypes=tiBase.cImplTypes;
941 ptiRet->TypeAttr.cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
942 if(ptiRet->TypeAttr.typekind == TKIND_ALIAS)
943 TLB_GetTdesc(pcx, tiBase.datatype1,
944 &ptiRet->TypeAttr.tdescAlias) ;
945 /* FIXME: */
946 /* IDLDESC idldescType; *//* never saw this one != zero */
948 /* name, eventually add to a hash table */
949 ptiRet->Name=TLB_ReadName(pcx, tiBase.NameOffset);
950 TRACE( typelib,"reading %s\n", ptiRet->Name);
951 /* help info */
952 ptiRet->DocString=TLB_ReadString(pcx, tiBase.docstringoffs);
953 ptiRet->dwHelpStringContext=tiBase.helpstringcontext;
954 ptiRet->dwHelpContext=tiBase.helpcontext;
955 /* note: InfoType's Help file and HelpStringDll come from the containing
956 * library. Further HelpString and Docstring appear to be the same thing :(
958 /* functions */
959 if(ptiRet->TypeAttr.cFuncs >0 )
960 TLB_DoFuncs(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
961 tiBase.memoffset, & ptiRet->funclist);
962 /* variables */
963 if(ptiRet->TypeAttr.cVars >0 )
964 TLB_DoVars(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
965 tiBase.memoffset, & ptiRet->varlist);
966 if(ptiRet->TypeAttr.cImplTypes >0 ){
967 if(ptiRet->TypeAttr.typekind == TKIND_COCLASS)
968 TLB_DoImplTypes(pcx, ptiRet->TypeAttr.cImplTypes ,
969 tiBase.datatype1, & ptiRet->impltypelist);
970 else if(ptiRet->TypeAttr.typekind != TKIND_DISPATCH){
971 ptiRet->impltypelist=TLB_Alloc(sizeof(TLBRefType));
972 TLB_DoRefType(pcx, tiBase.datatype1, & ptiRet->impltypelist);
975 ptiRet->ctCustData=
976 TLB_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData);
977 return ptiRet;
981 long TLB_FindTlb(TLBContext *pcx)
982 {/* FIXME: should parse the file properly
983 * hack to find our tlb data
985 #define TLBBUFSZ 1024
986 char buff[TLBBUFSZ+1]; /* room for a trailing '\0' */
987 long ret=0,found=0;
988 int count;
989 char *pChr;
991 #define LOOK_FOR_MAGIC(magic) \
992 count=TLB_Read(buff, TLBBUFSZ, pcx, 0); \
993 do { \
994 buff[count]='\0'; \
995 pChr = buff; \
996 while (pChr) { \
997 pChr = memchr(pChr,magic[0],count-(pChr-buff));\
998 if (pChr) { \
999 if (!memcmp(pChr,magic,4)) { \
1000 ret+= pChr-buff; \
1001 found = 1; \
1002 break; \
1004 pChr++; \
1007 if (found) break; \
1008 ret+=count; \
1009 count=TLB_Read(buff, TLBBUFSZ, pcx, DO_NOT_SEEK);\
1010 } while(count>0);
1013 LOOK_FOR_MAGIC(TLBMAGIC2);
1014 if(count)
1015 return ret;
1017 LOOK_FOR_MAGIC(TLBMAGIC1);
1018 if(count)
1019 ERR(ole,"type library format not (yet) implemented\n");
1020 else
1021 ERR(ole,"not type library found in this file\n");
1022 return -1;
1024 #undef LOOK_FOR_MAGIC
1026 int TLB_ReadTypeLib(PCHAR file, ITypeLib **ppTypeLib)
1028 TLBContext cx;
1029 OFSTRUCT ofStruct;
1030 long oStart,lPSegDir;
1031 TLBLibInfo* pLibInfo=NULL;
1032 TLB2Header tlbHeader;
1033 TLBSegDir tlbSegDir;
1034 if((cx.hFile=OpenFile(file, &ofStruct, OF_READWRITE))==HFILE_ERROR) {
1035 ERR( typelib,"cannot open %s error 0x%lx\n",file, GetLastError());
1036 return E_FAIL;
1038 /* get pointer to beginning of typelib data */
1039 if((oStart=TLB_FindTlb(&cx))<0){
1040 if(oStart==-1)
1041 ERR( typelib,"cannot locate typelib in %s\n",file);
1042 else
1043 ERR( typelib,"unsupported typelib format in %s\n",file);
1044 return E_FAIL;
1046 cx.oStart=oStart;
1047 pLibInfo=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TLBLibInfo));
1048 if (!pLibInfo){
1049 CloseHandle(cx.hFile);
1050 return E_OUTOFMEMORY;
1052 pLibInfo->lpvtbl = &tlbvt;
1053 pLibInfo->ref=1;
1054 cx.pLibInfo=pLibInfo;
1055 /* read header */
1056 TLB_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
1057 /* there is a small number of information here until the next important
1058 * part:
1059 * the segment directory . Try to calculate the amount of data */
1060 lPSegDir=sizeof(tlbHeader)+
1061 (tlbHeader.nrtypeinfos)*4+
1062 (tlbHeader.varflags & HELPDLLFLAG? 4 :0);
1063 /* now read the segment directory */
1064 TLB_Read((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
1065 cx.pTblDir=&tlbSegDir;
1066 /* just check two entries */
1067 if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F ||
1068 tlbSegDir.pImpInfo.res0c != 0x0F
1070 ERR( typelib,"cannot find the table directory, ptr=0x%lx\n",lPSegDir);
1072 /* now fill our internal data */
1073 /* TLIBATTR fields */
1074 TLB_ReadGuid(&pLibInfo->LibAttr.guid, tlbHeader.posguid, &cx);
1075 pLibInfo->LibAttr.lcid=tlbHeader.lcid;
1076 pLibInfo->LibAttr.syskind=tlbHeader.varflags & 0x0f; /* check the mask */
1077 pLibInfo->LibAttr.wMajorVerNum=LOWORD(tlbHeader.version);
1078 pLibInfo->LibAttr.wMinorVerNum=HIWORD(tlbHeader.version);
1079 pLibInfo->LibAttr.wLibFlags=(WORD) tlbHeader.flags & 0xffff;/* check mask */
1080 /* name, eventually add to a hash table */
1081 pLibInfo->Name=TLB_ReadName(&cx, tlbHeader.NameOffset);
1082 /* help info */
1083 pLibInfo->DocString=TLB_ReadString(&cx, tlbHeader.helpstring);
1084 pLibInfo->HelpFile=TLB_ReadString(&cx, tlbHeader.helpfile);
1085 if( tlbHeader.varflags & HELPDLLFLAG){
1086 int offset;
1087 TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
1088 pLibInfo->HelpStringDll=TLB_ReadString(&cx, offset);
1091 pLibInfo->dwHelpContext=tlbHeader.helpstringcontext;
1092 /* custom data */
1093 if(tlbHeader.CustomDataOffset >= 0) {
1094 pLibInfo->ctCustData=
1095 TLB_CustData(&cx, tlbHeader.CustomDataOffset, &pLibInfo->pCustData);
1097 /* fill in typedescriptions */
1098 if(tlbSegDir.pTypdescTab.length >0){
1099 int i, j, cTD=tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
1100 INT16 td[4];
1101 pLibInfo->pTypeDesc=
1102 TLB_Alloc( cTD * sizeof(TYPEDESC));
1103 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
1104 for(i=0;i<cTD;){
1105 /* FIXME: add several sanity checks here */
1106 pLibInfo->pTypeDesc[i].vt=td[0] & VT_TYPEMASK;
1107 if(td[0]==VT_PTR ||td[0]==VT_SAFEARRAY){/* FIXME: check safearray */
1108 if(td[3]<0)
1109 V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
1110 & stndTypeDesc[td[2]];
1111 else
1112 V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
1113 & pLibInfo->pTypeDesc[td[3]/8];
1114 }else if(td[0]==VT_CARRAY)
1115 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
1116 (void *)((int) td[2]); /* temp store offset in*/
1117 /* array descr table here */
1118 else if(td[0]==VT_USERDEFINED)
1119 V_UNION(&(pLibInfo->pTypeDesc[i]),hreftype)=MAKELONG(td[2],td[3]);
1120 if(++i<cTD) TLB_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
1122 /* second time around to fill the array subscript info */
1123 for(i=0;i<cTD;i++){
1124 if(pLibInfo->pTypeDesc[i].vt != VT_CARRAY) continue;
1125 if(tlbSegDir.pArrayDescriptions.offset>0){
1126 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset +
1127 (int) V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc));
1128 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
1129 TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
1130 if(td[1]<0)
1131 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem.vt=td[0] & VT_TYPEMASK;
1132 else
1133 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem=stndTypeDesc[td[0]/8];
1134 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->cDims=td[2];
1135 for(j=0;j<td[2];j++){
1136 TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->rgbounds[j].cElements,
1137 sizeof(INT), &cx, DO_NOT_SEEK);
1138 TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)
1139 ->rgbounds[j].lLbound,
1140 sizeof(INT), &cx, DO_NOT_SEEK);
1142 }else{
1143 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=NULL;
1144 ERR(ole, "didn't find array description data\n");
1148 /* imported type libs */
1149 if(tlbSegDir.pImpFiles.offset>0){
1150 TLBImpLib **ppImpLib=&(pLibInfo->pImpLibs);
1151 int offset=tlbSegDir.pImpFiles.offset;
1152 int oGuid;
1153 UINT16 size;
1154 while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length){
1155 *ppImpLib=TLB_Alloc(sizeof(TLBImpLib));
1156 (*ppImpLib)->offset=offset - tlbSegDir.pImpFiles.offset;
1157 TLB_Read(&oGuid, sizeof(INT), &cx, offset);
1158 TLB_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
1159 /* we are skipping some unknown info here */
1160 TLB_Read(& size,sizeof(UINT16), &cx, offset+3*(sizeof(INT)));
1161 size >>=2;
1162 (*ppImpLib)->name=TLB_Alloc(size+1);
1163 TLB_Read((*ppImpLib)->name,size, &cx, DO_NOT_SEEK);
1164 offset=(offset+3*(sizeof(INT))+sizeof(UINT16)+size+3) & 0xfffffffc;
1166 ppImpLib=&(*ppImpLib)->next;
1169 /* type info's */
1170 if(tlbHeader.nrtypeinfos >=0 ){
1171 /*pLibInfo->TypeInfoCount=tlbHeader.nrtypeinfos; */
1172 TLBTypeInfo **ppTI=&(pLibInfo->pTypeInfo);
1173 int i;
1174 for(i=0;i<(int)tlbHeader.nrtypeinfos;i++){
1175 *ppTI=TLB_DoTypeInfo(&cx, i, pLibInfo);
1176 ppTI=&((*ppTI)->next);
1177 (pLibInfo->TypeInfoCount)++;
1181 CloseHandle(cx.hFile);
1182 *ppTypeLib=(LPTYPELIB)pLibInfo;
1183 return S_OK;
1186 /*================== ITypeLib(2) Methods ===================================*/
1188 /* ITypeLib::QueryInterface
1190 static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid,
1191 VOID **ppvObject)
1193 if(TRACE_ON(typelib)){
1194 char xriid[50];
1195 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1196 TRACE(typelib,"(%p)->(IID: %s)\n",This,xriid);
1198 *ppvObject=NULL;
1199 if(IsEqualIID(riid, &IID_IUnknown) ||
1200 IsEqualIID(riid,&IID_ITypeLib)||
1201 IsEqualIID(riid,&IID_ITypeLib2))
1202 *ppvObject = This;
1203 if(*ppvObject){
1204 (*(LPTYPELIB*)ppvObject)->lpvtbl->fnAddRef(This);
1205 TRACE(typelib,"-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1206 return S_OK;
1208 TRACE(typelib,"-- Interface: E_NOINTERFACE\n");
1209 return E_NOINTERFACE;
1212 /* ITypeLib::AddRef
1214 static ULONG WINAPI ITypeLib_fnAddRef( LPTYPELIB iface)
1216 ICOM_THIS( TLBLibInfo, iface);
1217 TRACE(typelib,"(%p)->ref is %u\n",This, This->ref);
1218 return ++(This->ref);
1221 /* ITypeLib::Release
1223 static ULONG WINAPI ITypeLib_fnRelease( LPTYPELIB iface)
1225 ICOM_THIS( TLBLibInfo, iface);
1226 FIXME(typelib,"(%p)->ref is %u: stub\n",This, This->ref);
1227 (This->ref)--;
1228 return S_OK;
1231 /* ITypeLib::GetTypeInfoCount
1233 * Returns the number of type descriptions in the type library
1235 static UINT WINAPI ITypeLib_fnGetTypeInfoCount( LPTYPELIB iface)
1237 ICOM_THIS( TLBLibInfo, iface);
1238 TRACE(typelib,"(%p)->count is %d\n",This, This->TypeInfoCount);
1239 return This->TypeInfoCount;
1242 /* ITypeLib::GetTypeInfo
1244 *etrieves the specified type description in the library.
1246 static HRESULT WINAPI ITypeLib_fnGetTypeInfo( LPTYPELIB iface, UINT index,
1247 ITypeInfo **ppTInfo)
1249 int i;
1250 ICOM_THIS( TLBLibInfo, iface);
1251 TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo;
1252 TRACE(typelib,"(%p) index %d \n",This, index);
1253 for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo && i != index;i++)
1254 *ppTLBTInfo=(*ppTLBTInfo)->next;
1255 if(*ppTLBTInfo){
1256 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
1257 TRACE(typelib,"-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
1258 return S_OK;
1260 TRACE(typelib,"-- element not found\n");
1261 return TYPE_E_ELEMENTNOTFOUND;
1264 /* ITypeLibs::GetTypeInfoType
1266 * Retrieves the type of a type description.
1268 static HRESULT WINAPI ITypeLib_fnGetTypeInfoType( LPTYPELIB iface, UINT index,
1269 TYPEKIND *pTKind)
1271 int i;
1272 TLBTypeInfo *pTInfo;
1273 ICOM_THIS( TLBLibInfo, iface);
1274 TRACE(typelib,"(%p) index %d \n",This, index);
1275 for(i=0,pTInfo=This->pTypeInfo;pTInfo && i != index;i++)
1276 pTInfo=(pTInfo)->next;
1277 if(pTInfo){
1278 *pTKind=pTInfo->TypeAttr.typekind;
1279 TRACE(typelib,"-- found Type (%p)->%d\n",pTKind,*pTKind);
1280 return S_OK;
1282 TRACE(typelib,"-- element not found\n");
1283 return TYPE_E_ELEMENTNOTFOUND;
1286 /* ITypeLib::GetTypeInfoOfGuid
1288 * Retrieves the type description that corresponds to the specified GUID.
1291 static HRESULT WINAPI ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB iface,
1292 REFGUID guid, ITypeInfo **ppTInfo)
1294 int i;
1295 ICOM_THIS( TLBLibInfo, iface);
1296 TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo;
1297 if(TRACE_ON(typelib)){
1298 char xriid[50];
1299 WINE_StringFromCLSID((LPCLSID)guid,xriid);
1300 TRACE(typelib,"(%p) guid %sx)\n",This,xriid);
1302 for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo &&
1303 !IsEqualIID(guid,&(*ppTLBTInfo)->TypeAttr.guid);i++)
1304 *ppTLBTInfo=(*ppTLBTInfo)->next;
1305 if(*ppTLBTInfo){
1306 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
1307 TRACE(typelib,"-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
1308 return S_OK;
1310 TRACE(typelib,"-- element not found\n");
1311 return TYPE_E_ELEMENTNOTFOUND;
1314 /* ITypeLib::GetLibAttr
1316 * Retrieves the structure that contains the library's attributes.
1319 static HRESULT WINAPI ITypeLib_fnGetLibAttr( LPTYPELIB iface,
1320 LPTLIBATTR *ppTLibAttr)
1322 ICOM_THIS( TLBLibInfo, iface);
1323 TRACE( typelib,"(%p)\n",This);
1324 /* FIXME: must do a copy here */
1325 *ppTLibAttr=&This->LibAttr;
1326 return S_OK;
1329 /* ITypeLib::GetTypeComp
1331 * Enables a client compiler to bind to a library's types, variables,
1332 * constants, and global functions.
1335 static HRESULT WINAPI ITypeLib_fnGetTypeComp( LPTYPELIB iface,
1336 ITypeComp **ppTComp)
1338 ICOM_THIS( TLBLibInfo, iface);
1339 FIXME(typelib,"(%p): stub!\n",This);
1340 return E_NOTIMPL;
1343 /* ITypeLib::GetDocumentation
1345 * Retrieves the library's documentation string, the complete Help file name
1346 * and path, and the context identifier for the library Help topic in the Help
1347 * file.
1350 static HRESULT WINAPI ITypeLib_fnGetDocumentation( LPTYPELIB iface, INT index,
1351 BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext,
1352 BSTR *pBstrHelpFile)
1354 ICOM_THIS( TLBLibInfo, iface);
1355 HRESULT result;
1356 ITypeInfo *pTInfo;
1357 TRACE( typelib, "(%p) index %d Name(%p) DocString(%p)"
1358 " HelpContext(%p) HelpFile(%p)\n",
1359 This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1360 if(index<0){ /* documentation for the typelib */
1361 if(pBstrName)
1362 *pBstrName=TLB_DupAtoBstr(This->Name);
1363 if(pBstrDocString)
1364 *pBstrName=TLB_DupAtoBstr(This->DocString);
1365 if(pdwHelpContext)
1366 *pdwHelpContext=This->dwHelpContext;
1367 if(pBstrHelpFile)
1368 *pBstrName=TLB_DupAtoBstr(This->HelpFile);
1369 }else {/* for a typeinfo */
1370 result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo);
1371 if(SUCCEEDED(result)){
1372 result=ITypeInfo_GetDocumentation(pTInfo, MEMBERID_NIL, pBstrName,
1373 pBstrDocString, pdwHelpContext, pBstrHelpFile);
1374 ITypeInfo_Release(pTInfo);
1376 if(!SUCCEEDED(result))
1377 return result;
1379 return S_OK;
1382 /* ITypeLib::IsName
1384 * Indicates whether a passed-in string contains the name of a type or member
1385 * described in the library.
1388 static HRESULT WINAPI ITypeLib_fnIsName( LPTYPELIB iface, LPOLESTR szNameBuf,
1389 ULONG lHashVal, BOOL *pfName)
1391 ICOM_THIS( TLBLibInfo, iface);
1392 TLBTypeInfo *pTInfo;
1393 TLBFuncDesc *pFInfo;
1394 TLBVarDesc *pVInfo;
1395 int i;
1396 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1397 *pfName=TRUE;
1398 if(!strcmp(astr,This->Name)) goto ITypeLib_fnIsName_exit;
1399 for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){
1400 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnIsName_exit;
1401 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1402 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnIsName_exit;
1403 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1404 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1405 goto ITypeLib_fnIsName_exit;
1407 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
1408 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnIsName_exit;
1411 *pfName=FALSE;
1413 ITypeLib_fnIsName_exit:
1414 TRACE( typelib,"(%p)slow! search for %s: %s found!\n", This,
1415 debugstr_a(astr), *pfName?"NOT":"");
1417 HeapFree( GetProcessHeap(), 0, astr );
1418 return S_OK;
1421 /* ITypeLib::FindName
1423 * Finds occurrences of a type description in a type library. This may be used
1424 * to quickly verify that a name exists in a type library.
1427 static HRESULT WINAPI ITypeLib_fnFindName( LPTYPELIB iface, LPOLESTR szNameBuf,
1428 ULONG lHashVal, ITypeInfo **ppTInfo, MEMBERID *rgMemId, UINT16 *pcFound)
1430 ICOM_THIS( TLBLibInfo, iface);
1431 TLBTypeInfo *pTInfo;
1432 TLBFuncDesc *pFInfo;
1433 TLBVarDesc *pVInfo;
1434 int i,j = 0;
1435 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1436 for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){
1437 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnFindName_exit;
1438 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1439 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnFindName_exit;
1440 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1441 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1442 goto ITypeLib_fnFindName_exit;
1444 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
1445 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnFindName_exit;
1446 continue;
1447 ITypeLib_fnFindName_exit:
1448 pTInfo->lpvtbl->fnAddRef((LPTYPEINFO)pTInfo);
1449 ppTInfo[j]=(LPTYPEINFO)pTInfo;
1450 j++;
1452 TRACE( typelib,"(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
1453 This, *pcFound, debugstr_a(astr), j);
1455 *pcFound=j;
1457 HeapFree( GetProcessHeap(), 0, astr );
1458 return S_OK;
1461 /* ITypeLib::ReleaseTLibAttr
1463 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
1466 static VOID WINAPI ITypeLib_fnReleaseTLibAttr( LPTYPELIB iface, TLIBATTR *pTLibAttr)
1468 ICOM_THIS( TLBLibInfo, iface);
1469 TRACE( typelib,"freeing (%p)\n",This);
1470 /* nothing to do */
1473 /* ITypeLib2::GetCustData
1475 * gets the custom data
1477 static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLib * iface, REFGUID guid,
1478 VARIANT *pVarVal)
1480 ICOM_THIS( TLBLibInfo, iface);
1481 TLBCustData *pCData;
1482 for(pCData=This->pCustData; pCData; pCData = pCData->next)
1483 if( IsEqualIID(guid, &pCData->guid)) break;
1484 if(TRACE_ON(typelib)){
1485 char xriid[50];
1486 WINE_StringFromCLSID((LPCLSID)guid,xriid);
1487 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
1488 pCData? "" : "NOT");
1490 if(pCData){
1491 VariantInit( pVarVal);
1492 VariantCopy( pVarVal, &pCData->data);
1493 return S_OK;
1495 return E_INVALIDARG; /* FIXME: correct? */
1498 /* ITypeLib2::GetLibStatistics
1500 * Returns statistics about a type library that are required for efficient
1501 * sizing of hash tables.
1504 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( ITypeLib * iface,
1505 UINT *pcUniqueNames, UINT *pcchUniqueNames)
1507 ICOM_THIS( TLBLibInfo, iface);
1508 FIXME( typelib,"(%p): stub!\n", This);
1509 if(pcUniqueNames) *pcUniqueNames=1;
1510 if(pcchUniqueNames) *pcchUniqueNames=1;
1511 return S_OK;
1514 /* ITypeLib2::GetDocumentation2
1516 * Retrieves the library's documentation string, the complete Help file name
1517 * and path, the localization context to use, and the context ID for the
1518 * library Help topic in the Help file.
1521 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( ITypeLib * iface,
1522 INT index, LCID lcid, BSTR *pbstrHelpString,
1523 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
1525 ICOM_THIS( TLBLibInfo, iface);
1526 HRESULT result;
1527 ITypeInfo *pTInfo;
1528 FIXME( typelib,"(%p) index %d lcid %ld half implemented stub!\n", This,
1529 index, lcid);
1530 /* the help string should be obtained from the helpstringdll,
1531 * using the _DLLGetDocumentation function, based on the supplied
1532 * lcid. Nice to do sometime...
1534 if(index<0){ /* documentation for the typelib */
1535 if(pbstrHelpString)
1536 *pbstrHelpString=TLB_DupAtoBstr(This->DocString);
1537 if(pdwHelpStringContext)
1538 *pdwHelpStringContext=This->dwHelpContext;
1539 if(pbstrHelpStringDll)
1540 *pbstrHelpStringDll=TLB_DupAtoBstr(This->HelpStringDll);
1541 }else {/* for a typeinfo */
1542 result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo);
1543 if(SUCCEEDED(result)){
1544 result=ITypeInfo2_fnGetDocumentation2(pTInfo, MEMBERID_NIL, lcid,
1545 pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
1546 ITypeInfo_Release(pTInfo);
1548 if(!SUCCEEDED(result))
1549 return result;
1551 return S_OK;
1554 /* ITypeLib2::GetAllCustData
1556 * Gets all custom data items for the library.
1559 static HRESULT WINAPI ITypeLib2_fnGetAllCustData( ITypeLib * iface,
1560 CUSTDATA *pCustData)
1562 ICOM_THIS( TLBLibInfo, iface);
1563 TLBCustData *pCData;
1564 int i;
1565 TRACE( typelib,"(%p) returning %d items\n", This, This->ctCustData);
1566 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
1567 if(pCustData->prgCustData ){
1568 pCustData->cCustData=This->ctCustData;
1569 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
1570 pCustData->prgCustData[i].guid=pCData->guid;
1571 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
1573 }else{
1574 ERR( typelib," OUT OF MEMORY! \n");
1575 return E_OUTOFMEMORY;
1577 return S_OK;
1581 /*================== ITypeInfo(2) Methods ===================================*/
1583 /* ITypeInfo::QueryInterface
1585 static HRESULT WINAPI ITypeInfo_fnQueryInterface( LPTYPEINFO iface, REFIID riid,
1586 VOID **ppvObject)
1588 ICOM_THIS( TLBTypeInfo, iface);
1589 if(TRACE_ON(typelib)){
1590 char xriid[50];
1591 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1592 TRACE(typelib,"(%p)->(IID: %s)\n",This,xriid);
1594 *ppvObject=NULL;
1595 if(IsEqualIID(riid, &IID_IUnknown) ||
1596 IsEqualIID(riid,&IID_ITypeInfo)||
1597 IsEqualIID(riid,&IID_ITypeInfo2))
1598 *ppvObject = This;
1599 if(*ppvObject){
1600 (*(LPTYPEINFO*)ppvObject)->lpvtbl->fnAddRef(iface);
1601 TRACE(typelib,"-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1602 return S_OK;
1604 TRACE(typelib,"-- Interface: E_NOINTERFACE\n");
1605 return E_NOINTERFACE;
1608 /* ITypeInfo::AddRef
1610 static ULONG WINAPI ITypeInfo_fnAddRef( LPTYPEINFO iface)
1612 ICOM_THIS( TLBTypeInfo, iface);
1613 TRACE(typelib,"(%p)->ref is %u\n",This, This->ref);
1614 (This->pTypeLib->ref)++;
1615 return ++(This->ref);
1618 /* ITypeInfo::Release
1620 static ULONG WINAPI ITypeInfo_fnRelease( LPTYPEINFO iface)
1622 ICOM_THIS( TLBTypeInfo, iface);
1623 FIXME(typelib,"(%p)->ref is %u: stub\n",This, This->ref);
1624 (This->ref)--;
1625 (This->pTypeLib->ref)--;
1626 return S_OK;
1629 /* ITypeInfo::GetTypeAttr
1631 * Retrieves a TYPEATTR structure that contains the attributes of the type
1632 * description.
1635 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( LPTYPEINFO iface,
1636 LPTYPEATTR *ppTypeAttr)
1638 ICOM_THIS( TLBTypeInfo, iface);
1639 TRACE( typelib,"(%p)\n",This);
1640 /* FIXME: must do a copy here */
1641 *ppTypeAttr=&This->TypeAttr;
1642 return S_OK;
1645 /* ITypeInfo::GetTypeComp
1647 * Retrieves the ITypeComp interface for the type description, which enables a
1648 * client compiler to bind to the type description's members.
1651 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( LPTYPEINFO iface,
1652 ITypeComp * *ppTComp)
1654 ICOM_THIS( TLBTypeInfo, iface);
1655 FIXME( typelib,"(%p) stub!\n", This);
1656 return S_OK;
1659 /* ITypeInfo::GetFuncDesc
1661 * Retrieves the FUNCDESC structure that contains information about a
1662 * specified function.
1665 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( LPTYPEINFO iface, UINT index,
1666 LPFUNCDESC *ppFuncDesc)
1668 ICOM_THIS( TLBTypeInfo, iface);
1669 int i;
1670 TLBFuncDesc * pFDesc;
1671 TRACE( typelib,"(%p) index %d\n", This, index);
1672 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
1674 if(pFDesc){
1675 /* FIXME: must do a copy here */
1676 *ppFuncDesc=&pFDesc->funcdesc;
1677 return S_OK;
1679 return E_INVALIDARG;
1682 /* ITypeInfo::GetVarDesc
1684 * Retrieves a VARDESC structure that describes the specified variable.
1687 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( LPTYPEINFO iface, UINT index,
1688 LPVARDESC *ppVarDesc)
1690 ICOM_THIS( TLBTypeInfo, iface);
1691 int i;
1692 TLBVarDesc * pVDesc;
1693 TRACE( typelib,"(%p) index %d\n", This, index);
1694 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next)
1696 if(pVDesc){
1697 /* FIXME: must do a copy here */
1698 *ppVarDesc=&pVDesc->vardesc;
1699 return S_OK;
1701 return E_INVALIDARG;
1704 /* ITypeInfo_GetNames
1706 * Retrieves the variable with the specified member ID (or the name of the
1707 * property or method and its parameters) that correspond to the specified
1708 * function ID.
1710 static HRESULT WINAPI ITypeInfo_fnGetNames( LPTYPEINFO iface, MEMBERID memid,
1711 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
1713 ICOM_THIS( TLBTypeInfo, iface);
1714 TLBFuncDesc * pFDesc;
1715 TLBVarDesc * pVDesc;
1716 int i;
1717 TRACE( typelib,"(%p) memid=0x%08lx Maxname=%d\n", This, memid,
1718 cMaxNames);
1719 for(pFDesc=This->funclist; pFDesc->funcdesc.memid != memid && pFDesc;
1720 pFDesc=pFDesc->next)
1722 if(pFDesc){
1723 /* function found, now return function and parameter names */
1724 for(i=0; i<cMaxNames && i <= pFDesc->funcdesc.cParams; i++){
1725 if(!i) *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
1726 else
1727 rgBstrNames[i]=TLB_DupAtoBstr(pFDesc->pParamDesc[i-1].Name);
1730 *pcNames=i;
1731 }else{
1732 for(pVDesc=This->varlist; pVDesc->vardesc.memid != memid && pVDesc;
1733 pVDesc=pVDesc->next)
1735 if(pVDesc){
1736 *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
1737 *pcNames=1;
1738 }else{
1739 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
1740 This->TypeAttr.cImplTypes ){
1741 /* recursive search */
1742 ITypeInfo *pTInfo;
1743 HRESULT result;
1744 result=This->lpvtbl->fnGetRefTypeInfo(iface,
1745 This->impltypelist->reference, &pTInfo);
1746 if(SUCCEEDED(result)){
1747 result=pTInfo->lpvtbl->fnGetNames(pTInfo, memid, rgBstrNames,
1748 cMaxNames, pcNames);
1749 pTInfo->lpvtbl->fnRelease(pTInfo);
1750 return result;
1752 WARN( typelib,"Could not search inherited interface!\n");
1753 } else
1754 WARN( typelib,"no names found\n");
1755 *pcNames=0;
1756 return TYPE_E_ELEMENTNOTFOUND;
1759 return S_OK;
1763 /* ITypeInfo::GetRefTypeOfImplType
1765 * If a type description describes a COM class, it retrieves the type
1766 * description of the implemented interface types. For an interface,
1767 * GetRefTypeOfImplType returns the type information for inherited interfaces,
1768 * if any exist.
1771 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO iface,
1772 UINT index, HREFTYPE *pRefType)
1774 ICOM_THIS( TLBTypeInfo, iface);
1775 int(i);
1776 TLBRefType *pIref;
1777 TRACE( typelib,"(%p) index %d\n", This, index);
1778 for(i=0, pIref=This->impltypelist; i<index && pIref;
1779 i++, pIref=pIref->next)
1781 if(i==index){
1782 *pRefType=pIref->reference;
1783 return S_OK;
1785 return TYPE_E_ELEMENTNOTFOUND;
1788 /* ITypeInfo::GetImplTypeFlags
1790 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
1791 * or base interface in a type description.
1793 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO iface,
1794 UINT index, INT *pImplTypeFlags)
1796 ICOM_THIS( TLBTypeInfo, iface);
1797 int(i);
1798 TLBRefType *pIref;
1799 TRACE( typelib,"(%p) index %d\n", This, index);
1800 for(i=0, pIref=This->impltypelist; i<index && pIref; i++, pIref=pIref->next)
1802 if(i==index && pIref){
1803 *pImplTypeFlags=pIref->flags;
1804 return S_OK;
1806 *pImplTypeFlags=0;
1807 return TYPE_E_ELEMENTNOTFOUND;
1810 /* GetIDsOfNames
1811 * Maps between member names and member IDs, and parameter names and
1812 * parameter IDs.
1814 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( LPTYPEINFO iface,
1815 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
1817 ICOM_THIS( TLBTypeInfo, iface);
1818 TLBFuncDesc * pFDesc;
1819 TLBVarDesc * pVDesc;
1820 HRESULT ret=S_OK;
1821 PCHAR aszName= HEAP_strdupWtoA( GetProcessHeap(), 0, *rgszNames);
1822 TRACE( typelib,"(%p) Name %s cNames %d\n", This, debugstr_a(aszName),
1823 cNames);
1824 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) {
1825 int i, j;
1826 if( !strcmp(aszName, pFDesc->Name)) {
1827 if(cNames) *pMemId=pFDesc->funcdesc.memid;
1828 for(i=1; i < cNames; i++){
1829 PCHAR aszPar= HEAP_strdupWtoA( GetProcessHeap(), 0,
1830 rgszNames[i]);
1831 for(j=0; j<pFDesc->funcdesc.cParams; j++)
1832 if(strcmp(aszPar,pFDesc->pParamDesc[j].Name))
1833 break;
1834 if( j<pFDesc->funcdesc.cParams)
1835 pMemId[i]=j;
1836 else
1837 ret=DISP_E_UNKNOWNNAME;
1838 HeapFree( GetProcessHeap(), 0, aszPar);
1840 HeapFree (GetProcessHeap(), 0, aszName);
1841 return ret;
1844 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
1845 if( !strcmp(aszName, pVDesc->Name)) {
1846 if(cNames) *pMemId=pVDesc->vardesc.memid;
1847 HeapFree (GetProcessHeap(), 0, aszName);
1848 return ret;
1851 /* not found, see if this is and interface with an inheritance */
1852 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
1853 This->TypeAttr.cImplTypes ){
1854 /* recursive search */
1855 ITypeInfo *pTInfo;
1856 ret=This->lpvtbl->fnGetRefTypeInfo(iface,
1857 This->impltypelist->reference, &pTInfo);
1858 if(SUCCEEDED(ret)){
1859 ret=pTInfo->lpvtbl->fnGetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
1860 pTInfo->lpvtbl->fnRelease(pTInfo);
1861 return ret;
1863 WARN( typelib,"Could not search inherited interface!\n");
1864 } else
1865 WARN( typelib,"no names found\n");
1866 return DISP_E_UNKNOWNNAME;
1869 /* ITypeInfo::Invoke
1871 * Invokes a method, or accesses a property of an object, that implements the
1872 * interface described by the type description.
1874 static HRESULT WINAPI ITypeInfo_fnInvoke( LPTYPEINFO iface, VOID *pIUnk,
1875 MEMBERID memid, UINT16 dwFlags, DISPPARAMS *pDispParams,
1876 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *pArgErr)
1878 ICOM_THIS( TLBTypeInfo, iface);
1879 FIXME( typelib,"(%p) stub!", This);
1880 return S_OK;
1883 /* ITypeInfo::GetDocumentation
1885 * Retrieves the documentation string, the complete Help file name and path,
1886 * and the context ID for the Help topic for a specified type description.
1888 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( LPTYPEINFO iface,
1889 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
1890 DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
1892 ICOM_THIS( TLBTypeInfo, iface);
1893 TLBFuncDesc * pFDesc;
1894 TLBVarDesc * pVDesc;
1895 TRACE( typelib, "(%p) memid %ld Name(%p) DocString(%p)"
1896 " HelpContext(%p) HelpFile(%p)\n",
1897 This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1898 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
1899 if(pBstrName)
1900 *pBstrName=TLB_DupAtoBstr(This->Name);
1901 if(pBstrDocString)
1902 *pBstrDocString=TLB_DupAtoBstr(This->DocString);
1903 if(pdwHelpContext)
1904 *pdwHelpContext=This->dwHelpContext;
1905 if(pBstrHelpFile)
1906 *pBstrHelpFile=TLB_DupAtoBstr(This->DocString);/* FIXME */
1907 return S_OK;
1908 }else {/* for a member */
1909 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
1910 if(pFDesc->funcdesc.memid==memid){
1911 return S_OK;
1913 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
1914 if(pVDesc->vardesc.memid==memid){
1915 return S_OK;
1918 return TYPE_E_ELEMENTNOTFOUND;
1921 /* ITypeInfo::GetDllEntry
1923 * Retrieves a description or specification of an entry point for a function
1924 * in a DLL.
1926 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( LPTYPEINFO iface, MEMBERID memid,
1927 INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
1928 WORD *pwOrdinal)
1930 ICOM_THIS( TLBTypeInfo, iface);
1931 FIXME( typelib,"(%p) stub!\n", This);
1932 return E_FAIL;
1935 /* ITypeInfo::GetRefTypeInfo
1937 * If a type description references other type descriptions, it retrieves
1938 * the referenced type descriptions.
1940 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO iface,
1941 HREFTYPE hRefType, ITypeInfo * *ppTInfo)
1943 ICOM_THIS( TLBTypeInfo, iface);
1944 HRESULT result;
1945 if(HREFTYPE_INTHISFILE(hRefType)){
1946 ITypeLib *pTLib;
1947 int Index;
1948 result=This->lpvtbl->fnGetContainingTypeLib(iface, &pTLib,
1949 &Index);
1950 if(SUCCEEDED(result)){
1951 result=pTLib->lpvtbl->fnGetTypeInfo(pTLib,
1952 HREFTYPE_INDEX(hRefType),
1953 ppTInfo);
1954 pTLib->lpvtbl->fnRelease(pTLib );
1956 } else{
1957 /* imported type lib */
1958 TLBRefType * pRefType;
1959 TLBLibInfo *pTypeLib;
1960 for( pRefType=This->impltypelist; pRefType &&
1961 pRefType->reference != hRefType; pRefType=pRefType->next)
1963 if(!pRefType)
1964 return TYPE_E_ELEMENTNOTFOUND; //FIXME : correct?
1965 pTypeLib=pRefType->pImpTLInfo->pImpTypeLib;
1966 if(pTypeLib) // typelib already loaded
1967 result=pTypeLib->lpvtbl->fnGetTypeInfoOfGuid(
1968 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
1969 else{
1970 result=LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
1971 0,0,0, /* FIXME */
1972 (LPTYPELIB *)&pTypeLib);
1973 if(!SUCCEEDED(result)){
1974 BSTR libnam=TLB_DupAtoBstr(pRefType->pImpTLInfo->name);
1975 result=LoadTypeLib(libnam, (LPTYPELIB *)&pTypeLib);
1976 SysFreeString(libnam);
1978 if(SUCCEEDED(result)){
1979 result=pTypeLib->lpvtbl->fnGetTypeInfoOfGuid(
1980 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
1981 pRefType->pImpTLInfo->pImpTypeLib=pTypeLib;
1985 TRACE( typelib,"(%p) hreftype 0x%04lx loaded %s (%p)\n", This, hRefType,
1986 SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
1987 return result;
1990 /* ITypeInfo::AddressOfMember
1992 * Retrieves the addresses of static functions or variables, such as those
1993 * defined in a DLL.
1995 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( LPTYPEINFO iface,
1996 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
1998 ICOM_THIS( TLBTypeInfo, iface);
1999 FIXME( typelib,"(%p) stub!\n", This);
2000 return S_OK;
2003 /* ITypeInfo::CreateInstance
2005 * Creates a new instance of a type that describes a component object class
2006 * (coclass).
2008 static HRESULT WINAPI ITypeInfo_fnCreateInstance( LPTYPEINFO iface,
2009 IUnknown *pUnk, REFIID riid, VOID **ppvObj)
2011 ICOM_THIS( TLBTypeInfo, iface);
2012 FIXME( typelib,"(%p) stub!\n", This);
2013 return S_OK;
2016 /* ITypeInfo::GetMops
2018 * Retrieves marshaling information.
2020 static HRESULT WINAPI ITypeInfo_fnGetMops( LPTYPEINFO iface, MEMBERID memid,
2021 BSTR *pBstrMops)
2023 ICOM_THIS( TLBTypeInfo, iface);
2024 FIXME( typelib,"(%p) stub!\n", This);
2025 return S_OK;
2028 /* ITypeInfo::GetContainingTypeLib
2030 * Retrieves the containing type library and the index of the type description
2031 * within that type library.
2033 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( LPTYPEINFO iface,
2034 ITypeLib * *ppTLib, UINT *pIndex)
2036 ICOM_THIS( TLBTypeInfo, iface);
2037 *ppTLib=(LPTYPELIB )(This->pTypeLib);
2038 *pIndex=This->index;
2039 (*ppTLib)->lpvtbl->fnAddRef(*ppTLib);
2040 TRACE( typelib,"(%p) returns (%p) index %d!\n", This, *ppTLib, *pIndex);
2041 return S_OK;
2044 /* ITypeInfo::ReleaseTypeAttr
2046 * Releases a TYPEATTR previously returned by GetTypeAttr.
2049 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO iface,
2050 TYPEATTR* pTypeAttr)
2052 ICOM_THIS( TLBTypeInfo, iface);
2053 TRACE( typelib,"(%p)->(%p)\n", This, pTypeAttr);
2054 return S_OK;
2057 /* ITypeInfo::ReleaseFuncDesc
2059 * Releases a FUNCDESC previously returned by GetFuncDesc. *
2061 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO iface,
2062 FUNCDESC *pFuncDesc)
2064 ICOM_THIS( TLBTypeInfo, iface);
2065 TRACE( typelib,"(%p)->(%p)\n", This, pFuncDesc);
2066 return S_OK;
2069 /* ITypeInfo::ReleaseVarDesc
2071 * Releases a VARDESC previously returned by GetVarDesc.
2073 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( LPTYPEINFO iface,
2074 VARDESC *pVarDesc)
2076 ICOM_THIS( TLBTypeInfo, iface);
2077 TRACE( typelib,"(%p)->(%p)\n", This, pVarDesc);
2078 return S_OK;
2081 /* ITypeInfo2::GetTypeKind
2083 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
2086 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo * iface,
2087 TYPEKIND *pTypeKind)
2089 ICOM_THIS( TLBTypeInfo, iface);
2090 *pTypeKind=This->TypeAttr.typekind;
2091 TRACE( typelib,"(%p) type 0x%0x\n", This,*pTypeKind);
2092 return S_OK;
2095 /* ITypeInfo2::GetTypeFlags
2097 * Returns the type flags without any allocations. This returns a DWORD type
2098 * flag, which expands the type flags without growing the TYPEATTR (type
2099 * attribute).
2102 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo * iface,
2103 UINT *pTypeFlags)
2105 ICOM_THIS( TLBTypeInfo, iface);
2106 *pTypeFlags=This->TypeAttr.wTypeFlags;
2107 TRACE( typelib,"(%p) flags 0x%04x\n", This,*pTypeFlags);
2108 return S_OK;
2111 /* ITypeInfo2::GetFuncIndexOfMemId
2112 * Binds to a specific member based on a known DISPID, where the member name
2113 * is not known (for example, when binding to a default member).
2116 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo * iface,
2117 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
2119 ICOM_THIS( TLBTypeInfo, iface);
2120 TLBFuncDesc *pFuncInfo;
2121 int i;
2122 HRESULT result;
2123 /* FIXME: should check for invKind??? */
2124 for(i=0, pFuncInfo=This->funclist;pFuncInfo &&
2125 memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next);
2126 if(pFuncInfo){
2127 *pFuncIndex=i;
2128 result= S_OK;
2129 }else{
2130 *pFuncIndex=0;
2131 result=E_INVALIDARG;
2133 TRACE( typelib,"(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This,
2134 memid, invKind, SUCCEEDED(result)? "SUCCES":"FAILED");
2135 return result;
2138 /* TypeInfo2::GetVarIndexOfMemId
2140 * Binds to a specific member based on a known DISPID, where the member name
2141 * is not known (for example, when binding to a default member).
2144 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo * iface,
2145 MEMBERID memid, UINT *pVarIndex)
2147 ICOM_THIS( TLBTypeInfo, iface);
2148 TLBVarDesc *pVarInfo;
2149 int i;
2150 HRESULT result;
2151 for(i=0, pVarInfo=This->varlist; pVarInfo &&
2152 memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next)
2154 if(pVarInfo){
2155 *pVarIndex=i;
2156 result= S_OK;
2157 }else{
2158 *pVarIndex=0;
2159 result=E_INVALIDARG;
2161 TRACE( typelib,"(%p) memid 0x%08lx -> %s\n", This,
2162 memid, SUCCEEDED(result)? "SUCCES":"FAILED");
2163 return result;
2166 /* ITypeInfo2::GetCustData
2168 * Gets the custom data
2170 static HRESULT WINAPI ITypeInfo2_fnGetCustData( ITypeInfo * iface,
2171 REFGUID guid, VARIANT *pVarVal)
2173 ICOM_THIS( TLBTypeInfo, iface);
2174 TLBCustData *pCData;
2175 for(pCData=This->pCustData; pCData; pCData = pCData->next)
2176 if( IsEqualIID(guid, &pCData->guid)) break;
2177 if(TRACE_ON(typelib)){
2178 char xriid[50];
2179 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2180 TRACE(typelib,"(%p) guid %s %s found!x)\n", This, xriid,
2181 pCData? "" : "NOT");
2183 if(pCData){
2184 VariantInit( pVarVal);
2185 VariantCopy( pVarVal, &pCData->data);
2186 return S_OK;
2188 return E_INVALIDARG; /* FIXME: correct? */
2191 /* ITypeInfo2::GetFuncCustData
2193 * Gets the custom data
2195 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( ITypeInfo * iface,
2196 UINT index, REFGUID guid, VARIANT *pVarVal)
2198 ICOM_THIS( TLBTypeInfo, iface);
2199 TLBCustData *pCData=NULL;
2200 TLBFuncDesc * pFDesc;
2201 int i;
2202 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2203 pFDesc=pFDesc->next)
2205 if(pFDesc)
2206 for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next)
2207 if( IsEqualIID(guid, &pCData->guid)) break;
2208 if(TRACE_ON(typelib)){
2209 char xriid[50];
2210 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2211 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
2212 pCData? "" : "NOT");
2214 if(pCData){
2215 VariantInit( pVarVal);
2216 VariantCopy( pVarVal, &pCData->data);
2217 return S_OK;
2219 return E_INVALIDARG; /* FIXME: correct? */
2222 /* ITypeInfo2::GetParamCustData
2224 * Gets the custom data
2226 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( ITypeInfo * iface,
2227 UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal)
2229 ICOM_THIS( TLBTypeInfo, iface);
2230 TLBCustData *pCData=NULL;
2231 TLBFuncDesc * pFDesc;
2232 int i;
2233 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
2234 pFDesc=pFDesc->next)
2236 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams)
2237 for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData;
2238 pCData = pCData->next)
2239 if( IsEqualIID(guid, &pCData->guid)) break;
2240 if(TRACE_ON(typelib)){
2241 char xriid[50];
2242 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2243 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
2244 pCData? "" : "NOT");
2246 if(pCData){
2247 VariantInit( pVarVal);
2248 VariantCopy( pVarVal, &pCData->data);
2249 return S_OK;
2251 return E_INVALIDARG; /* FIXME: correct? */
2254 /* ITypeInfo2::GetVarcCustData
2256 * Gets the custom data
2258 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( ITypeInfo * iface,
2259 UINT index, REFGUID guid, VARIANT *pVarVal)
2261 ICOM_THIS( TLBTypeInfo, iface);
2262 TLBCustData *pCData=NULL;
2263 TLBVarDesc * pVDesc;
2264 int i;
2265 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2266 pVDesc=pVDesc->next)
2268 if(pVDesc)
2269 for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next)
2270 if( IsEqualIID(guid, &pCData->guid)) break;
2271 if(TRACE_ON(typelib)){
2272 char xriid[50];
2273 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2274 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
2275 pCData? "" : "NOT");
2277 if(pCData){
2278 VariantInit( pVarVal);
2279 VariantCopy( pVarVal, &pCData->data);
2280 return S_OK;
2282 return E_INVALIDARG; /* FIXME: correct? */
2285 /* ITypeInfo2::GetImplcCustData
2287 * Gets the custom data
2289 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( ITypeInfo * iface,
2290 UINT index, REFGUID guid, VARIANT *pVarVal)
2292 ICOM_THIS( TLBTypeInfo, iface);
2293 TLBCustData *pCData=NULL;
2294 TLBRefType * pRDesc;
2295 int i;
2296 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2297 pRDesc=pRDesc->next)
2299 if(pRDesc)
2300 for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next)
2301 if( IsEqualIID(guid, &pCData->guid)) break;
2302 if(TRACE_ON(typelib)){
2303 char xriid[50];
2304 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2305 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
2306 pCData? "" : "NOT");
2308 if(pCData){
2309 VariantInit( pVarVal);
2310 VariantCopy( pVarVal, &pCData->data);
2311 return S_OK;
2313 return E_INVALIDARG; /* FIXME: correct? */
2316 /* ITypeInfo2::GetDocumentation2
2318 * Retrieves the documentation string, the complete Help file name and path,
2319 * the localization context to use, and the context ID for the library Help
2320 * topic in the Help file.
2323 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( ITypeInfo * iface,
2324 MEMBERID memid, LCID lcid, BSTR *pbstrHelpString,
2325 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
2327 ICOM_THIS( TLBTypeInfo, iface);
2328 TLBFuncDesc * pFDesc;
2329 TLBVarDesc * pVDesc;
2330 TRACE( typelib, "(%p) memid %ld lcid(0x%lx) HelpString(%p) "
2331 "HelpStringContext(%p) HelpStringDll(%p)\n",
2332 This, memid, lcid, pbstrHelpString, pdwHelpStringContext,
2333 pbstrHelpStringDll );
2334 /* the help string should be obtained from the helpstringdll,
2335 * using the _DLLGetDocumentation function, based on the supplied
2336 * lcid. Nice to do sometime...
2338 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
2339 if(pbstrHelpString)
2340 *pbstrHelpString=TLB_DupAtoBstr(This->Name);
2341 if(pdwHelpStringContext)
2342 *pdwHelpStringContext=This->dwHelpStringContext;
2343 if(pbstrHelpStringDll)
2344 *pbstrHelpStringDll=
2345 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2346 return S_OK;
2347 }else {/* for a member */
2348 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
2349 if(pFDesc->funcdesc.memid==memid){
2350 if(pbstrHelpString)
2351 *pbstrHelpString=TLB_DupAtoBstr(pFDesc->HelpString);
2352 if(pdwHelpStringContext)
2353 *pdwHelpStringContext=pFDesc->HelpStringContext;
2354 if(pbstrHelpStringDll)
2355 *pbstrHelpStringDll=
2356 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2357 return S_OK;
2359 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
2360 if(pVDesc->vardesc.memid==memid){
2361 if(pbstrHelpString)
2362 *pbstrHelpString=TLB_DupAtoBstr(pVDesc->HelpString);
2363 if(pdwHelpStringContext)
2364 *pdwHelpStringContext=pVDesc->HelpStringContext;
2365 if(pbstrHelpStringDll)
2366 *pbstrHelpStringDll=
2367 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2368 return S_OK;
2371 return TYPE_E_ELEMENTNOTFOUND;
2374 /* ITypeInfo2::GetAllCustData
2376 * Gets all custom data items for the Type info.
2379 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( ITypeInfo * iface,
2380 CUSTDATA *pCustData)
2382 ICOM_THIS( TLBTypeInfo, iface);
2383 TLBCustData *pCData;
2384 int i;
2385 TRACE( typelib,"(%p) returning %d items\n", This, This->ctCustData);
2386 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
2387 if(pCustData->prgCustData ){
2388 pCustData->cCustData=This->ctCustData;
2389 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
2390 pCustData->prgCustData[i].guid=pCData->guid;
2391 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
2393 }else{
2394 ERR( typelib," OUT OF MEMORY! \n");
2395 return E_OUTOFMEMORY;
2397 return S_OK;
2400 /* ITypeInfo2::GetAllFuncCustData
2402 * Gets all custom data items for the specified Function
2405 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( ITypeInfo * iface,
2406 UINT index, CUSTDATA *pCustData)
2408 ICOM_THIS( TLBTypeInfo, iface);
2409 TLBCustData *pCData;
2410 TLBFuncDesc * pFDesc;
2411 int i;
2412 TRACE( typelib,"(%p) index %d\n", This, index);
2413 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2414 pFDesc=pFDesc->next)
2416 if(pFDesc){
2417 pCustData->prgCustData =
2418 TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM));
2419 if(pCustData->prgCustData ){
2420 pCustData->cCustData=pFDesc->ctCustData;
2421 for(i=0, pCData=pFDesc->pCustData; pCData; i++,
2422 pCData = pCData->next){
2423 pCustData->prgCustData[i].guid=pCData->guid;
2424 VariantCopy(& pCustData->prgCustData[i].varValue,
2425 & pCData->data);
2427 }else{
2428 ERR( typelib," OUT OF MEMORY! \n");
2429 return E_OUTOFMEMORY;
2431 return S_OK;
2433 return TYPE_E_ELEMENTNOTFOUND;
2436 /* ITypeInfo2::GetAllParamCustData
2438 * Gets all custom data items for the Functions
2441 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo * iface,
2442 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
2444 ICOM_THIS( TLBTypeInfo, iface);
2445 TLBCustData *pCData=NULL;
2446 TLBFuncDesc * pFDesc;
2447 int i;
2448 TRACE( typelib,"(%p) index %d\n", This, indexFunc);
2449 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
2450 pFDesc=pFDesc->next)
2452 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams){
2453 pCustData->prgCustData =
2454 TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData *
2455 sizeof(CUSTDATAITEM));
2456 if(pCustData->prgCustData ){
2457 pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData;
2458 for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData;
2459 pCData; i++, pCData = pCData->next){
2460 pCustData->prgCustData[i].guid=pCData->guid;
2461 VariantCopy(& pCustData->prgCustData[i].varValue,
2462 & pCData->data);
2464 }else{
2465 ERR( typelib," OUT OF MEMORY! \n");
2466 return E_OUTOFMEMORY;
2468 return S_OK;
2470 return TYPE_E_ELEMENTNOTFOUND;
2473 /* ITypeInfo2::GetAllVarCustData
2475 * Gets all custom data items for the specified Variable
2478 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo * iface,
2479 UINT index, CUSTDATA *pCustData)
2481 ICOM_THIS( TLBTypeInfo, iface);
2482 TLBCustData *pCData;
2483 TLBVarDesc * pVDesc;
2484 int i;
2485 TRACE( typelib,"(%p) index %d\n", This, index);
2486 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2487 pVDesc=pVDesc->next)
2489 if(pVDesc){
2490 pCustData->prgCustData =
2491 TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM));
2492 if(pCustData->prgCustData ){
2493 pCustData->cCustData=pVDesc->ctCustData;
2494 for(i=0, pCData=pVDesc->pCustData; pCData; i++,
2495 pCData = pCData->next){
2496 pCustData->prgCustData[i].guid=pCData->guid;
2497 VariantCopy(& pCustData->prgCustData[i].varValue,
2498 & pCData->data);
2500 }else{
2501 ERR( typelib," OUT OF MEMORY! \n");
2502 return E_OUTOFMEMORY;
2504 return S_OK;
2506 return TYPE_E_ELEMENTNOTFOUND;
2509 /* ITypeInfo2::GetAllImplCustData
2511 * Gets all custom data items for the specified implementation type
2514 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo * iface,
2515 UINT index, CUSTDATA *pCustData)
2517 ICOM_THIS( TLBTypeInfo, iface);
2518 TLBCustData *pCData;
2519 TLBRefType * pRDesc;
2520 int i;
2521 TRACE( typelib,"(%p) index %d\n", This, index);
2522 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2523 pRDesc=pRDesc->next)
2525 if(pRDesc){
2526 pCustData->prgCustData =
2527 TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM));
2528 if(pCustData->prgCustData ){
2529 pCustData->cCustData=pRDesc->ctCustData;
2530 for(i=0, pCData=pRDesc->pCustData; pCData; i++,
2531 pCData = pCData->next){
2532 pCustData->prgCustData[i].guid=pCData->guid;
2533 VariantCopy(& pCustData->prgCustData[i].varValue,
2534 & pCData->data);
2536 }else{
2537 ERR( typelib," OUT OF MEMORY! \n");
2538 return E_OUTOFMEMORY;
2540 return S_OK;
2542 return TYPE_E_ELEMENTNOTFOUND;