4 * Copyright 1997 Marcus Meissner
6 * there is much left to do here before it can be useful for real world
9 * -. Only one format of typelibs is supported
10 * -. All testing so far is done using special written windows programs
11 * -. Data structures are straightforward, but slow for look-ups.
12 * -. (related) nothing is hashed
13 * -. a typelib is always read in its entirety into memory and never released.
14 * -. there are a number of stubs in ITypeLib and ITypeInfo interfaces. Most
15 * of them I don't know yet how to implement them.
16 * -. Most error return values are just guessed not checked with windows
18 * -. all locale stuff ignored
19 * -. move stuff to wine/dlls
20 * -. didn't bother with a c++ interface
21 * -. lousy fatal error handling
22 * -. some methods just return pointers to internal data structures, this is
23 * partly laziness, partly I want to check how windows does it.
31 #include "winreg.h" /* for HKEY_LOCAL_MACHINE */
32 #include "winnls.h" /* for PRIMARYLANGID */
33 #include "wine/winbase16.h" /* for RegQueryValue16(HKEY,LPSTR,LPSTR,LPDWORD) */
35 #include "wine/obj_base.h"
36 #include "debugtools.h"
37 #include "winversion.h"
38 /* FIXME: get rid of these */
39 typedef struct ITypeInfoVtbl ITypeLib_VTable, *LPTYPEINFO_VTABLE ;
40 typedef struct ITypeLibVtbl *LPTYPELIB_VTABLE ;
43 DEFAULT_DEBUG_CHANNEL(ole)
44 DECLARE_DEBUG_CHANNEL(typelib)
46 /****************************************************************************
47 * QueryPathOfRegTypeLib16 [TYPELIB.14]
49 * the path is "Classes\Typelib\<guid>\<major>.<minor>\<lcid>\win16\"
54 QueryPathOfRegTypeLib16(
55 REFGUID guid, /* [in] referenced guid */
56 WORD wMaj, /* [in] major version */
57 WORD wMin, /* [in] minor version */
58 LCID lcid, /* [in] locale id */
59 LPBSTR16 path /* [out] path of typelib */
62 char typelibkey[100],pathname[260];
66 WINE_StringFromCLSID(guid,xguid);
67 sprintf(typelibkey,"SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%lx\\win16",
71 sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
72 FIXME("(%s,%d,%d,0x%04lx,%p),can't handle non-string guids.\n",xguid,wMaj,wMin,(DWORD)lcid,path);
75 plen = sizeof(pathname);
76 if (RegQueryValue16(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
77 /* try again without lang specific id */
79 return QueryPathOfRegTypeLib16(guid,wMaj,wMin,PRIMARYLANGID(lcid),path);
80 FIXME("key %s not found\n",typelibkey);
83 *path = SysAllocString16(pathname);
87 /****************************************************************************
88 * QueryPathOfRegTypeLib [OLEAUT32.164]
93 QueryPathOfRegTypeLib(
94 REFGUID guid, /* [in] referenced guid */
95 WORD wMaj, /* [in] major version */
96 WORD wMin, /* [in] minor version */
97 LCID lcid, /* [in] locale id */
98 LPBSTR path /* [out] path of typelib */
101 char typelibkey[100],pathname[260];
106 WINE_StringFromCLSID(guid,xguid);
107 sprintf(typelibkey,"SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%lx\\win32",
111 sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
112 FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n",xguid,wMaj,wMin,(DWORD)lcid,path);
115 plen = sizeof(pathname);
116 if (RegQueryValue16(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
117 /* try again without lang specific id */
119 return QueryPathOfRegTypeLib(guid,wMaj,wMin,PRIMARYLANGID(lcid),path);
120 FIXME("key %s not found\n",typelibkey);
123 *path = HEAP_strdupAtoW(GetProcessHeap(),0,pathname);
127 /******************************************************************************
128 * LoadTypeLib [TYPELIB.3] Loads and registers a type library
130 * Docs: OLECHAR FAR* szFile
131 * Docs: iTypeLib FAR* FAR* pptLib
137 HRESULT WINAPI LoadTypeLib16(
138 LPOLESTR szFile, /* [in] Name of file to load from */
139 void * *pptLib) /* [out] Pointer to pointer to loaded type library */
141 FIXME("('%s',%p): stub\n",debugstr_w((LPWSTR)szFile),pptLib);
149 /******************************************************************************
150 * LoadTypeLib [OLEAUT32.161]
151 * Loads and registers a type library
153 * Docs: OLECHAR FAR* szFile
154 * Docs: iTypeLib FAR* FAR* pptLib
160 int TLB_ReadTypeLib(PCHAR file, ITypeLib **ppTypelib);
161 HRESULT WINAPI LoadTypeLib(
162 OLECHAR *szFile, /* [in] Name of file to load from */
163 ITypeLib * *pptLib) /* [out] Pointer to pointer to loaded type library */
165 return LoadTypeLibEx(szFile, REGKIND_DEFAULT, pptLib);
168 /******************************************************************************
169 * LoadTypeLibEx [OLEAUT32.183]
170 * Loads and optionally registers a type library
176 HRESULT WINAPI LoadTypeLibEx(
177 LPOLESTR szFile, /* [in] Name of file to load from */
178 REGKIND regkind, /* specify kind of registration */
179 ITypeLib **pptLib) /* [out] Pointer to pointer to loaded type library */
183 TRACE("('%s',%d,%p)\n",debugstr_w(szFile), regkind, pptLib);
185 p=HEAP_strdupWtoA(GetProcessHeap(),0,szFile);
187 if(regkind != REGKIND_NONE)
188 FIXME ("registration of typelibs not supported yet!\n");
190 res= TLB_ReadTypeLib(p, pptLib);
191 /* XXX need to free p ?? */
193 TRACE(" returns %ld\n",res);
198 /******************************************************************************
199 * LoadRegTypeLib [OLEAUT32.162]
201 HRESULT WINAPI LoadRegTypeLib(
202 REFGUID rguid, /* [in] referenced guid */
203 WORD wVerMajor, /* [in] major version */
204 WORD wVerMinor, /* [in] minor version */
205 LCID lcid, /* [in] locale id */
206 ITypeLib **ppTLib /* [out] path of typelib */
209 HRESULT res=QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor,
212 res= LoadTypeLib(bstr, ppTLib);
215 if(TRACE_ON(typelib)){
217 WINE_StringFromCLSID((LPCLSID)rguid,xriid);
218 TRACE("(IID: %s) load %s (%p)\n",xriid,
219 SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);
225 /******************************************************************************
226 * RegisterTypeLib [OLEAUT32.163]
227 * Adds information about a type library to the System Registry
229 * Docs: ITypeLib FAR * ptlib
230 * Docs: OLECHAR FAR* szFullPath
231 * Docs: OLECHAR FAR* szHelpDir
237 HRESULT WINAPI RegisterTypeLib(
238 ITypeLib * ptlib, /*[in] Pointer to the library*/
239 OLECHAR * szFullPath, /*[in] full Path of the library*/
240 OLECHAR * szHelpDir) /*[in] dir to the helpfile for the library,
242 { FIXME("(%p,%s,%s): stub\n",ptlib, debugstr_w(szFullPath),debugstr_w(szHelpDir));
243 return S_OK; /* FIXME: pretend everything is OK */
247 /******************************************************************************
248 * UnRegisterTypeLib [OLEAUT32.186]
249 * Removes information about a type library from the System Registry
256 HRESULT WINAPI UnRegisterTypeLib(
257 REFGUID libid, /* [in] Guid of the library */
258 WORD wVerMajor, /* [in] major version */
259 WORD wVerMinor, /* [in] minor version */
260 LCID lcid, /* [in] locale id */
264 WINE_StringFromCLSID((LPCLSID)libid,xriid);
265 TRACE("(IID: %s): stub\n",xriid);
266 return S_OK; /* FIXME: pretend everything is OK */
269 /****************************************************************************
270 * OaBuildVersion (TYPELIB.15)
272 * known TYPELIB.DLL versions:
274 * OLE 2.01 no OaBuildVersion() avail 1993 -- ---
275 * OLE 2.02 1993-94 02 3002
278 * OLE 2.03 W98 SE orig. file !! 1993-95 10 3024
279 * OLE 2.1 NT 1993-95 ?? ???
280 * OLE 2.3.1 W95 23 700
282 DWORD WINAPI OaBuildVersion16(void)
284 FIXME("Please report to a.mohr@mailto.de if you get version error messages !\n");
285 switch(VERSION_GetVersion())
288 return MAKELONG(3027, 3); /* WfW 3.11 */
290 return MAKELONG(700, 23); /* Win95A */
292 return MAKELONG(3024, 10); /* W98 SE */
294 FIXME_(ole)("Version value not known yet. Please investigate it !");
299 /* for better debugging info leave the static out for the time being */
302 /*=======================Itypelib methods ===============================*/
303 /* ITypeLib methods */
304 static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid,
306 static ULONG WINAPI ITypeLib_fnAddRef( LPTYPELIB This);
307 static ULONG WINAPI ITypeLib_fnRelease( LPTYPELIB This);
308 static UINT WINAPI ITypeLib_fnGetTypeInfoCount( LPTYPELIB This);
309 static HRESULT WINAPI ITypeLib_fnGetTypeInfo( LPTYPELIB This, UINT index,
310 ITypeInfo **ppTInfo);
312 static HRESULT WINAPI ITypeLib_fnGetTypeInfoType( LPTYPELIB This, UINT index,
315 static HRESULT WINAPI ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB This, REFGUID guid,
316 ITypeInfo **ppTinfo);
318 static HRESULT WINAPI ITypeLib_fnGetLibAttr( LPTYPELIB This,
319 LPTLIBATTR *ppTLibAttr);
321 static HRESULT WINAPI ITypeLib_fnGetTypeComp( LPTYPELIB This,
322 ITypeComp **ppTComp);
324 static HRESULT WINAPI ITypeLib_fnGetDocumentation( LPTYPELIB This, INT index,
325 BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext,
326 BSTR *pBstrHelpFile);
328 static HRESULT WINAPI ITypeLib_fnIsName( LPTYPELIB This, LPOLESTR szNameBuf,
329 ULONG lHashVal, BOOL *pfName);
331 static HRESULT WINAPI ITypeLib_fnFindName( LPTYPELIB This, LPOLESTR szNameBuf,
332 ULONG lHashVal, ITypeInfo **ppTInfo, MEMBERID *rgMemId, UINT16 *pcFound);
334 static VOID WINAPI ITypeLib_fnReleaseTLibAttr( LPTYPELIB This,
335 TLIBATTR *pTLibAttr);
337 static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLib * This, REFGUID guid,
340 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( ITypeLib * This,
341 UINT *pcUniqueNames, UINT *pcchUniqueNames);
343 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( ITypeLib * This,
344 INT index, LCID lcid, BSTR *pbstrHelpString,
345 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll);
347 static HRESULT WINAPI ITypeLib2_fnGetAllCustData( ITypeLib * This,
348 CUSTDATA *pCustData);
349 static ICOM_VTABLE(ITypeLib) tlbvt = {
350 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
351 ITypeLib_fnQueryInterface,
354 ITypeLib_fnGetTypeInfoCount,
355 ITypeLib_fnGetTypeInfo,
356 ITypeLib_fnGetTypeInfoType,
357 ITypeLib_fnGetTypeInfoOfGuid,
358 ITypeLib_fnGetLibAttr,
359 ITypeLib_fnGetTypeComp,
360 ITypeLib_fnGetDocumentation,
363 ITypeLib_fnReleaseTLibAttr,
364 ITypeLib2_fnGetCustData,
365 ITypeLib2_fnGetLibStatistics,
366 ITypeLib2_fnGetDocumentation2,
367 ITypeLib2_fnGetAllCustData
369 /* TypeInfo Methods */
371 static HRESULT WINAPI ITypeInfo_fnQueryInterface( LPTYPEINFO This, REFIID riid,
373 static ULONG WINAPI ITypeInfo_fnAddRef( LPTYPEINFO This);
374 static ULONG WINAPI ITypeInfo_fnRelease( LPTYPEINFO This);
375 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( LPTYPEINFO This,
376 LPTYPEATTR *ppTypeAttr);
378 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( LPTYPEINFO This,
379 ITypeComp * *ppTComp);
381 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( LPTYPEINFO This, UINT index,
382 LPFUNCDESC *ppFuncDesc);
384 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( LPTYPEINFO This, UINT index,
385 LPVARDESC *ppVarDesc);
387 static HRESULT WINAPI ITypeInfo_fnGetNames( LPTYPEINFO This, MEMBERID memid,
388 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames);
391 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO This,
392 UINT index, HREFTYPE *pRefType);
394 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO This,
395 UINT index, INT *pImplTypeFlags);
397 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( LPTYPEINFO This,
398 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId);
400 static HRESULT WINAPI ITypeInfo_fnInvoke( LPTYPEINFO This, VOID *pIUnk,
401 MEMBERID memid, UINT16 dwFlags, DISPPARAMS *pDispParams,
402 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *pArgErr);
404 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( LPTYPEINFO This,
405 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
406 DWORD *pdwHelpContext, BSTR *pBstrHelpFile);
408 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( LPTYPEINFO This,
409 MEMBERID memid, INVOKEKIND invKind, BSTR *pBstrDllName,
410 BSTR *pBstrName, WORD *pwOrdinal);
412 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO This,
413 HREFTYPE hRefType, ITypeInfo * *ppTInfo);
415 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( LPTYPEINFO This,
416 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv);
418 static HRESULT WINAPI ITypeInfo_fnCreateInstance( LPTYPEINFO This,
419 IUnknown *pUnk, REFIID riid, VOID * *ppvObj);
421 static HRESULT WINAPI ITypeInfo_fnGetMops( LPTYPEINFO This, MEMBERID memid,
425 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( LPTYPEINFO This,
426 ITypeLib * *ppTLib, UINT *pIndex);
428 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO This,
429 TYPEATTR *pTypeAttr);
431 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO This,
432 FUNCDESC *pFuncDesc);
434 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( LPTYPEINFO This,
436 /* itypeinfo2 methods */
437 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo * This,
438 TYPEKIND *pTypeKind);
439 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo * This,
441 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo * This,
442 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex);
443 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo * This,
444 MEMBERID memid, UINT *pVarIndex);
445 static HRESULT WINAPI ITypeInfo2_fnGetCustData( ITypeInfo * This,
446 REFGUID guid, VARIANT *pVarVal);
447 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( ITypeInfo * This,
448 UINT index, REFGUID guid, VARIANT *pVarVal);
449 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( ITypeInfo * This,
450 UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal);
451 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( ITypeInfo * This,
452 UINT index, REFGUID guid, VARIANT *pVarVal);
453 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( ITypeInfo * This,
454 UINT index, REFGUID guid, VARIANT *pVarVal);
455 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( ITypeInfo * This,
456 MEMBERID memid, LCID lcid, BSTR *pbstrHelpString,
457 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll);
458 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( ITypeInfo * This,
459 CUSTDATA *pCustData);
460 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( ITypeInfo * This,
461 UINT index, CUSTDATA *pCustData);
462 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo * This,
463 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData);
464 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo * This,
465 UINT index, CUSTDATA *pCustData);
466 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo * This,
467 UINT index, CUSTDATA *pCustData);
469 static ICOM_VTABLE(ITypeInfo) tinfvt = {
470 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
471 ITypeInfo_fnQueryInterface,
474 ITypeInfo_fnGetTypeAttr,
475 ITypeInfo_fnGetTypeComp,
476 ITypeInfo_fnGetFuncDesc,
477 ITypeInfo_fnGetVarDesc,
478 ITypeInfo_fnGetNames,
479 ITypeInfo_fnGetRefTypeOfImplType,
480 ITypeInfo_fnGetImplTypeFlags,
481 ITypeInfo_fnGetIDsOfNames,
483 ITypeInfo_fnGetDocumentation,
484 ITypeInfo_fnGetDllEntry,
485 ITypeInfo_fnGetRefTypeInfo,
486 ITypeInfo_fnAddressOfMember,
487 ITypeInfo_fnCreateInstance,
489 ITypeInfo_fnGetContainingTypeLib,
490 ITypeInfo_fnReleaseTypeAttr,
491 ITypeInfo_fnReleaseFuncDesc,
492 ITypeInfo_fnReleaseVarDesc,
494 ITypeInfo2_fnGetTypeKind,
495 ITypeInfo2_fnGetTypeFlags,
496 ITypeInfo2_fnGetFuncIndexOfMemId,
497 ITypeInfo2_fnGetVarIndexOfMemId,
498 ITypeInfo2_fnGetCustData,
499 ITypeInfo2_fnGetFuncCustData,
500 ITypeInfo2_fnGetParamCustData,
501 ITypeInfo2_fnGetVarCustData,
502 ITypeInfo2_fnGetImplTypeCustData,
503 ITypeInfo2_fnGetDocumentation2,
504 ITypeInfo2_fnGetAllCustData,
505 ITypeInfo2_fnGetAllFuncCustData,
506 ITypeInfo2_fnGetAllParamCustData,
507 ITypeInfo2_fnGetAllVarCustData,
508 ITypeInfo2_fnGetAllImplTypeCustData,
512 static TYPEDESC stndTypeDesc[VT_LPWSTR+1]={/* VT_LPWSTR is largest type that */
513 /* may appear in type description*/
514 {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
515 {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
516 {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
517 {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
518 {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
519 {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
522 static void TLB_abort()
526 static void * TLB_Alloc(unsigned size)
529 if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){
531 ERR("cannot allocate memory\n");
536 /* candidate for a more global appearance... */
537 static BSTR TLB_DupAtoBstr(PCHAR Astr)
545 pdw =TLB_Alloc((len+3)*sizeof(OLECHAR));
546 pdw[0]=(len)*sizeof(OLECHAR);
547 bstr=(BSTR)&( pdw[1]);
548 lstrcpyAtoW( bstr, Astr);
549 TRACE("copying %s to (%p)\n", Astr, bstr);
553 static void TLB_Free(void * ptr)
555 HeapFree(GetProcessHeap(), 0, ptr);
558 DWORD TLB_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
562 if (( where != DO_NOT_SEEK &&
563 (0xffffffff == SetFilePointer( pcx->hFile, where + pcx->oStart,
566 !ReadFile(pcx->hFile, buffer, count, &bytesread, NULL)
569 ERR("read error is 0x%lx reading %ld bytes at 0x%lx\n",
570 GetLastError(), count, where);
577 static void TLB_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
579 if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){
580 memset(pGuid,0, sizeof(GUID));
583 TLB_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset );
586 PCHAR TLB_ReadName( TLBContext *pcx, int offset)
590 TLB_Read(&niName, sizeof(niName), pcx,
591 pcx->pTblDir->pNametab.offset+offset);
592 niName.namelen &= 0xFF; /* FIXME: correct ? */
593 name=TLB_Alloc((niName.namelen & 0xff) +1);
594 TLB_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK);
595 name[niName.namelen & 0xff]='\0';
598 PCHAR TLB_ReadString( TLBContext *pcx, int offset)
602 if(offset<0) return NULL;
603 TLB_Read(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
604 if(length <= 0) return 0;
605 string=TLB_Alloc(length +1);
606 TLB_Read(string, length, pcx, DO_NOT_SEEK);
611 * read a value and fill a VARIANT structure
613 static void TLB_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
616 if(offset <0) { /* data is packed in here */
617 pVar->vt = (offset & 0x7c000000 )>> 26;
618 V_UNION(pVar, iVal) = offset & 0xffff;
621 TLB_Read(&(pVar->vt), sizeof(VARTYPE), pcx,
622 pcx->pTblDir->pCustData.offset + offset );
624 case VT_EMPTY: /* FIXME: is this right? */
625 case VT_NULL: /* FIXME: is this right? */
626 case VT_I2 : /* this should not happen */
637 case VT_VOID : /* FIXME: is this right? */
645 case VT_DECIMAL : /* FIXME: is this right? */
648 /* pointer types with known behaviour */
651 TLB_Read(&size, sizeof(INT), pcx, DO_NOT_SEEK );
652 ptr=TLB_Alloc(size);/* allocate temp buffer */
653 TLB_Read(ptr, size, pcx, DO_NOT_SEEK ); /* read string (ANSI) */
654 V_UNION(pVar, bstrVal)=SysAllocStringLen(NULL,size);
655 /* FIXME: do we need a AtoW conversion here? */
656 V_UNION(pVar, bstrVal[size])=L'\0';
657 while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
661 /* FIXME: this will not work AT ALL when the variant contains a pointer */
668 case VT_USERDEFINED :
674 case VT_STREAMED_OBJECT :
675 case VT_STORED_OBJECT :
676 case VT_BLOB_OBJECT :
681 FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
685 if(size>0) /* (big|small) endian correct? */
686 TLB_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK );
690 * create a linked list with custom data
692 static int TLB_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
699 pNew=TLB_Alloc(sizeof(TLBCustData));
700 TLB_Read(&entry, sizeof(entry), pcx,
701 pcx->pTblDir->pCDGuids.offset+offset);
702 TLB_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
703 TLB_ReadValue(&(pNew->data), entry.DataOffset, pcx);
704 /* add new custom data at head of the list */
705 pNew->next=*ppCustData;
712 static void TLB_GetTdesc(TLBContext *pcx, INT type,TYPEDESC * pTd )
715 pTd->vt=type & VT_TYPEMASK;
717 *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
719 static void TLB_DoFuncs(TLBContext *pcx, int cFuncs, int cVars,
720 int offset, TLBFuncDesc ** pptfd)
723 * member information is stored in a data structure at offset
724 * indicated by the memoffset field of the typeinfo structure
725 * There are several distinctive parts.
726 * the first part starts with a field that holds the total length
727 * of this (first) part excluding this field. Then follow the records,
728 * for each member there is one record.
730 * First entry is always the length of the record (excluding this
732 * Rest of the record depends on the type of the member. If there is
733 * a field indicating the member type (function variable intereface etc)
734 * I have not found it yet. At this time we depend on the information
735 * in the type info and the usual order how things are stored.
737 * Second follows an array sized nrMEM*sizeof(INT) with a memeber id
740 * Third is a equal sized array with file offsets to the name entry
743 * Forth and last (?) part is an array with offsets to the records in the
744 * first part of this file segment.
747 int infolen, nameoffset, reclength, nrattributes;
749 TLBFuncRecord * pFuncRec=(TLBFuncRecord *) recbuf;
751 int recoffset=offset+sizeof(INT);
752 TLB_Read(&infolen,sizeof(INT), pcx, offset);
753 for(i=0;i<cFuncs;i++){
754 *pptfd=TLB_Alloc(sizeof(TLBFuncDesc));
755 /* name, eventually add to a hash table */
756 TLB_Read(&nameoffset, sizeof(INT), pcx,
757 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
758 (*pptfd)->Name=TLB_ReadName(pcx, nameoffset);
759 /* read the function information record */
760 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
762 TLB_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
763 /* do the attributes */
764 nrattributes=(reclength-pFuncRec->nrargs*3*sizeof(int)-0x18)
767 (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
769 (*pptfd)->HelpString = TLB_ReadString(pcx,
770 pFuncRec->OptAttr[1]) ;
772 if(pFuncRec->FKCCIC & 0x2000)
773 (*pptfd)->Entry = (char *) pFuncRec->OptAttr[2] ;
775 (*pptfd)->Entry = TLB_ReadString(pcx,
776 pFuncRec->OptAttr[2]);
778 (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;
779 if(nrattributes>6 && pFuncRec->FKCCIC & 0x80){
780 TLB_CustData(pcx, pFuncRec->OptAttr[6],
781 &(*pptfd)->pCustData);
786 /* fill the FuncDesc Structure */
787 TLB_Read(&(*pptfd)->funcdesc.memid, sizeof(INT), pcx,
788 offset + infolen + ( i + 1) * sizeof(INT));
789 (*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
790 (*pptfd)->funcdesc.invkind = ((pFuncRec->FKCCIC) >>3) & 0xF;
791 (*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >>8 & 0xF;
792 (*pptfd)->funcdesc.cParams = pFuncRec->nrargs ;
793 (*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ;
794 (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ;
795 (*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
796 TLB_GetTdesc(pcx, pFuncRec->DataType,
797 &(*pptfd)->funcdesc.elemdescFunc.tdesc) ;
799 /* do the parameters/arguments */
800 if(pFuncRec->nrargs){
801 TLBParameterInfo paraminfo;
802 (*pptfd)->funcdesc.lprgelemdescParam=
803 TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
804 (*pptfd)->pParamDesc=TLB_Alloc(pFuncRec->nrargs *
807 TLB_Read(¶minfo,sizeof(paraminfo), pcx, recoffset+reclength -
808 pFuncRec->nrargs * sizeof(TLBParameterInfo));
809 for(j=0;j<pFuncRec->nrargs;j++){
810 TLB_GetTdesc(pcx, paraminfo.DataType,
811 &(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc) ;
812 V_UNION(&((*pptfd)->funcdesc.lprgelemdescParam[j]),
813 paramdesc.wParamFlags) = paraminfo.Flags;
814 (*pptfd)->pParamDesc[j].Name=(void *)paraminfo.oName;
815 TLB_Read(¶minfo,sizeof(TLBParameterInfo), pcx,
818 /* second time around */
819 for(j=0;j<pFuncRec->nrargs;j++){
821 (*pptfd)->pParamDesc[j].Name=
822 TLB_ReadName(pcx, (int)(*pptfd)->pParamDesc[j].Name);
824 if((PARAMFLAG_FHASDEFAULT & V_UNION(&((*pptfd)->funcdesc.
825 lprgelemdescParam[j]),paramdesc.wParamFlags)) &&
826 ((pFuncRec->FKCCIC) & 0x1000)){
827 INT *pInt=(INT *)((char *)pFuncRec + reclength -
828 (pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
829 PARAMDESC * pParamDesc= &V_UNION(&((*pptfd)->funcdesc.
830 lprgelemdescParam[j]),paramdesc);
831 pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
832 pParamDesc->pparamdescex->cBytes= sizeof(PARAMDESCEX);
833 TLB_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
837 if(nrattributes>7+j && pFuncRec->FKCCIC & 0x80)
838 TLB_CustData(pcx, pFuncRec->OptAttr[7+j],
839 &(*pptfd)->pParamDesc[j].pCustData);
842 /* scode is not used: archaic win16 stuff FIXME: right? */
843 (*pptfd)->funcdesc.cScodes = 0 ;
844 (*pptfd)->funcdesc.lprgscode = NULL ;
845 pptfd=&((*pptfd)->next);
846 recoffset += reclength;
849 static void TLB_DoVars(TLBContext *pcx, int cFuncs, int cVars,
850 int offset, TLBVarDesc ** pptvd)
852 int infolen, nameoffset, reclength;
854 TLBVarRecord * pVarRec=(TLBVarRecord *) recbuf;
857 TLB_Read(&infolen,sizeof(INT), pcx, offset);
858 TLB_Read(&recoffset,sizeof(INT), pcx, offset + infolen +
859 ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
860 recoffset += offset+sizeof(INT);
861 for(i=0;i<cVars;i++){
862 *pptvd=TLB_Alloc(sizeof(TLBVarDesc));
863 /* name, eventually add to a hash table */
864 TLB_Read(&nameoffset, sizeof(INT), pcx,
865 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
866 (*pptvd)->Name=TLB_ReadName(pcx, nameoffset);
867 /* read the variable information record */
868 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
870 TLB_Read(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
872 if(reclength >(6*sizeof(INT)) )
873 (*pptvd)->HelpContext=pVarRec->HelpContext;
874 if(reclength >(7*sizeof(INT)) )
875 (*pptvd)->HelpString = TLB_ReadString(pcx, pVarRec->oHelpString) ;
876 if(reclength >(8*sizeof(INT)) )
877 if(reclength >(9*sizeof(INT)) )
878 (*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
879 /* fill the VarDesc Structure */
880 TLB_Read(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
881 offset + infolen + ( i + 1) * sizeof(INT));
882 (*pptvd)->vardesc.varkind = pVarRec->VarKind;
883 (*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
884 TLB_GetTdesc(pcx, pVarRec->DataType,
885 &(*pptvd)->vardesc.elemdescVar.tdesc) ;
886 /* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) fixme?? */
887 if(pVarRec->VarKind == VAR_CONST ){
888 V_UNION(&((*pptvd)->vardesc),lpvarValue)=TLB_Alloc(sizeof(VARIANT));
889 TLB_ReadValue(V_UNION(&((*pptvd)->vardesc),lpvarValue),
890 pVarRec->OffsValue, pcx);
892 V_UNION(&((*pptvd)->vardesc),oInst)=pVarRec->OffsValue;
893 pptvd=&((*pptvd)->next);
894 recoffset += reclength;
897 /* fill in data for a hreftype (offset). When the refernced type is contained
898 * in the typelib, its just an (file) offset in the type info base dir.
899 * If comes fom import, its an offset+1 in the ImpInfo table
901 static void TLB_DoRefType(TLBContext *pcx,
902 int offset, TLBRefType ** pprtd)
905 if(!HREFTYPE_INTHISFILE( offset)) {
906 /* external typelib */
908 TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs);
909 TLB_Read(&impinfo, sizeof(impinfo), pcx,
910 pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
911 for(j=0;pImpLib;j++){ /* search the known offsets of all import libraries */
912 if(pImpLib->offset==impinfo.oImpFile) break;
913 pImpLib=pImpLib->next;
916 (*pprtd)->reference=offset;
917 (*pprtd)->pImpTLInfo=pImpLib;
918 TLB_ReadGuid(&(*pprtd)->guid, impinfo.oGuid, pcx);
920 ERR("Cannot find a reference\n");
921 (*pprtd)->reference=-1;
922 (*pprtd)->pImpTLInfo=(void *)-1;
925 /* in this typelib */
926 (*pprtd)->reference=offset;
927 (*pprtd)->pImpTLInfo=(void *)-2;
931 /* process Implemented Interfaces of a com class */
932 static void TLB_DoImplTypes(TLBContext *pcx, int count,
933 int offset, TLBRefType ** pprtd)
937 for(i=0;i<count;i++){
938 if(offset<0) break; /* paranoia */
939 *pprtd=TLB_Alloc(sizeof(TLBRefType));
940 TLB_Read(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
941 TLB_DoRefType(pcx, refrec.reftype, pprtd);
942 (*pprtd)->flags=refrec.flags;
943 (*pprtd)->ctCustData=
944 TLB_CustData(pcx, refrec.oCustData, &(*pprtd)->pCustData);
946 pprtd=&((*pprtd)->next);
950 * process a typeinfo record
952 TLBTypeInfo * TLB_DoTypeInfo(TLBContext *pcx, int count, TLBLibInfo* pLibInfo)
954 TLBTypeInfoBase tiBase;
956 ptiRet=TLB_Alloc(sizeof(TLBTypeInfo));
957 ptiRet->lpvtbl = &tinfvt;
959 TLB_Read(&tiBase, sizeof(tiBase) ,pcx ,
960 pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
961 /* this where we are coming from */
962 ptiRet->pTypeLib=pLibInfo;
964 /* fill in the typeattr fields */
965 TLB_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx);
966 ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid; /* FIXME: correct? */
967 ptiRet->TypeAttr.memidConstructor=MEMBERID_NIL ;/* FIXME */
968 ptiRet->TypeAttr.memidDestructor=MEMBERID_NIL ; /* FIXME */
969 ptiRet->TypeAttr.lpstrSchema=NULL; /* reserved */
970 ptiRet->TypeAttr.cbSizeInstance=tiBase.size;
971 ptiRet->TypeAttr.typekind=tiBase.typekind & 0xF;
972 ptiRet->TypeAttr.cFuncs=LOWORD(tiBase.cElement);
973 ptiRet->TypeAttr.cVars=HIWORD(tiBase.cElement);
974 ptiRet->TypeAttr.cbAlignment=(tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */
975 ptiRet->TypeAttr.wTypeFlags=tiBase.flags;
976 ptiRet->TypeAttr.wMajorVerNum=LOWORD(tiBase.version);
977 ptiRet->TypeAttr.wMinorVerNum=HIWORD(tiBase.version);
978 ptiRet->TypeAttr.cImplTypes=tiBase.cImplTypes;
979 ptiRet->TypeAttr.cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
980 if(ptiRet->TypeAttr.typekind == TKIND_ALIAS)
981 TLB_GetTdesc(pcx, tiBase.datatype1,
982 &ptiRet->TypeAttr.tdescAlias) ;
984 /* IDLDESC idldescType; *//* never saw this one != zero */
986 /* name, eventually add to a hash table */
987 ptiRet->Name=TLB_ReadName(pcx, tiBase.NameOffset);
988 TRACE("reading %s\n", ptiRet->Name);
990 ptiRet->DocString=TLB_ReadString(pcx, tiBase.docstringoffs);
991 ptiRet->dwHelpStringContext=tiBase.helpstringcontext;
992 ptiRet->dwHelpContext=tiBase.helpcontext;
993 /* note: InfoType's Help file and HelpStringDll come from the containing
994 * library. Further HelpString and Docstring appear to be the same thing :(
997 if(ptiRet->TypeAttr.cFuncs >0 )
998 TLB_DoFuncs(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
999 tiBase.memoffset, & ptiRet->funclist);
1001 if(ptiRet->TypeAttr.cVars >0 )
1002 TLB_DoVars(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
1003 tiBase.memoffset, & ptiRet->varlist);
1004 if(ptiRet->TypeAttr.cImplTypes >0 ){
1005 if(ptiRet->TypeAttr.typekind == TKIND_COCLASS)
1006 TLB_DoImplTypes(pcx, ptiRet->TypeAttr.cImplTypes ,
1007 tiBase.datatype1, & ptiRet->impltypelist);
1008 else if(ptiRet->TypeAttr.typekind != TKIND_DISPATCH){
1009 ptiRet->impltypelist=TLB_Alloc(sizeof(TLBRefType));
1010 TLB_DoRefType(pcx, tiBase.datatype1, & ptiRet->impltypelist);
1014 TLB_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData);
1019 long TLB_FindTlb(TLBContext *pcx)
1020 {/* FIXME: should parse the file properly
1021 * hack to find our tlb data
1023 #define TLBBUFSZ 1024
1024 char buff[TLBBUFSZ+1]; /* room for a trailing '\0' */
1029 #define LOOK_FOR_MAGIC(magic) \
1030 count=TLB_Read(buff, TLBBUFSZ, pcx, 0); \
1035 pChr = memchr(pChr,magic[0],count-(pChr-buff));\
1037 if (!memcmp(pChr,magic,4)) { \
1047 count=TLB_Read(buff, TLBBUFSZ, pcx, DO_NOT_SEEK);\
1051 LOOK_FOR_MAGIC(TLBMAGIC2);
1055 LOOK_FOR_MAGIC(TLBMAGIC1);
1057 ERR("type library format not (yet) implemented\n");
1059 ERR("not type library found in this file\n");
1062 #undef LOOK_FOR_MAGIC
1064 int TLB_ReadTypeLib(PCHAR file, ITypeLib **ppTypeLib)
1068 long oStart,lPSegDir;
1069 TLBLibInfo* pLibInfo=NULL;
1070 TLB2Header tlbHeader;
1071 TLBSegDir tlbSegDir;
1072 if((cx.hFile=OpenFile(file, &ofStruct, OF_READWRITE))==HFILE_ERROR) {
1073 ERR("cannot open %s error 0x%lx\n",file, GetLastError());
1076 /* get pointer to beginning of typelib data */
1078 if((oStart=TLB_FindTlb(&cx))<0){
1080 ERR("cannot locate typelib in %s\n",file);
1082 ERR("unsupported typelib format in %s\n",file);
1086 pLibInfo=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TLBLibInfo));
1088 CloseHandle(cx.hFile);
1089 return E_OUTOFMEMORY;
1091 pLibInfo->lpvtbl = &tlbvt;
1093 cx.pLibInfo=pLibInfo;
1095 TLB_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
1096 /* there is a small number of information here until the next important
1098 * the segment directory . Try to calculate the amount of data */
1099 lPSegDir=sizeof(tlbHeader)+
1100 (tlbHeader.nrtypeinfos)*4+
1101 (tlbHeader.varflags & HELPDLLFLAG? 4 :0);
1102 /* now read the segment directory */
1103 TLB_Read((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
1104 cx.pTblDir=&tlbSegDir;
1105 /* just check two entries */
1106 if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F ||
1107 tlbSegDir.pImpInfo.res0c != 0x0F
1109 ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir);
1110 CloseHandle(cx.hFile);
1113 /* now fill our internal data */
1114 /* TLIBATTR fields */
1115 TLB_ReadGuid(&pLibInfo->LibAttr.guid, tlbHeader.posguid, &cx);
1116 pLibInfo->LibAttr.lcid=tlbHeader.lcid;
1117 pLibInfo->LibAttr.syskind=tlbHeader.varflags & 0x0f; /* check the mask */
1118 pLibInfo->LibAttr.wMajorVerNum=LOWORD(tlbHeader.version);
1119 pLibInfo->LibAttr.wMinorVerNum=HIWORD(tlbHeader.version);
1120 pLibInfo->LibAttr.wLibFlags=(WORD) tlbHeader.flags & 0xffff;/* check mask */
1121 /* name, eventually add to a hash table */
1122 pLibInfo->Name=TLB_ReadName(&cx, tlbHeader.NameOffset);
1124 pLibInfo->DocString=TLB_ReadString(&cx, tlbHeader.helpstring);
1125 pLibInfo->HelpFile=TLB_ReadString(&cx, tlbHeader.helpfile);
1126 if( tlbHeader.varflags & HELPDLLFLAG){
1128 TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
1129 pLibInfo->HelpStringDll=TLB_ReadString(&cx, offset);
1132 pLibInfo->dwHelpContext=tlbHeader.helpstringcontext;
1134 if(tlbHeader.CustomDataOffset >= 0) {
1135 pLibInfo->ctCustData=
1136 TLB_CustData(&cx, tlbHeader.CustomDataOffset, &pLibInfo->pCustData);
1138 /* fill in typedescriptions */
1139 if(tlbSegDir.pTypdescTab.length >0){
1140 int i, j, cTD=tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
1142 pLibInfo->pTypeDesc=
1143 TLB_Alloc( cTD * sizeof(TYPEDESC));
1144 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
1146 /* FIXME: add several sanity checks here */
1147 pLibInfo->pTypeDesc[i].vt=td[0] & VT_TYPEMASK;
1148 if(td[0]==VT_PTR ||td[0]==VT_SAFEARRAY){/* FIXME: check safearray */
1150 V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
1151 & stndTypeDesc[td[2]];
1153 V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
1154 & pLibInfo->pTypeDesc[td[3]/8];
1155 }else if(td[0]==VT_CARRAY)
1156 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
1157 (void *)((int) td[2]); /* temp store offset in*/
1158 /* array descr table here */
1159 else if(td[0]==VT_USERDEFINED)
1160 V_UNION(&(pLibInfo->pTypeDesc[i]),hreftype)=MAKELONG(td[2],td[3]);
1161 if(++i<cTD) TLB_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
1163 /* second time around to fill the array subscript info */
1165 if(pLibInfo->pTypeDesc[i].vt != VT_CARRAY) continue;
1166 if(tlbSegDir.pArrayDescriptions.offset>0){
1167 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset +
1168 (int) V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc));
1169 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
1170 TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
1172 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem.vt=td[0] & VT_TYPEMASK;
1174 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem=stndTypeDesc[td[0]/8];
1175 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->cDims=td[2];
1176 for(j=0;j<td[2];j++){
1177 TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->rgbounds[j].cElements,
1178 sizeof(INT), &cx, DO_NOT_SEEK);
1179 TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)
1180 ->rgbounds[j].lLbound,
1181 sizeof(INT), &cx, DO_NOT_SEEK);
1184 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=NULL;
1185 ERR("didn't find array description data\n");
1189 /* imported type libs */
1190 if(tlbSegDir.pImpFiles.offset>0){
1191 TLBImpLib **ppImpLib=&(pLibInfo->pImpLibs);
1192 int offset=tlbSegDir.pImpFiles.offset;
1195 while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length){
1196 *ppImpLib=TLB_Alloc(sizeof(TLBImpLib));
1197 (*ppImpLib)->offset=offset - tlbSegDir.pImpFiles.offset;
1198 TLB_Read(&oGuid, sizeof(INT), &cx, offset);
1199 TLB_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
1200 /* we are skipping some unknown info here */
1201 TLB_Read(& size,sizeof(UINT16), &cx, offset+3*(sizeof(INT)));
1203 (*ppImpLib)->name=TLB_Alloc(size+1);
1204 TLB_Read((*ppImpLib)->name,size, &cx, DO_NOT_SEEK);
1205 offset=(offset+3*(sizeof(INT))+sizeof(UINT16)+size+3) & 0xfffffffc;
1207 ppImpLib=&(*ppImpLib)->next;
1211 if(tlbHeader.nrtypeinfos >=0 ){
1212 /*pLibInfo->TypeInfoCount=tlbHeader.nrtypeinfos; */
1213 TLBTypeInfo **ppTI=&(pLibInfo->pTypeInfo);
1215 for(i=0;i<(int)tlbHeader.nrtypeinfos;i++){
1216 *ppTI=TLB_DoTypeInfo(&cx, i, pLibInfo);
1217 ppTI=&((*ppTI)->next);
1218 (pLibInfo->TypeInfoCount)++;
1222 CloseHandle(cx.hFile);
1223 *ppTypeLib=(LPTYPELIB)pLibInfo;
1227 /*================== ITypeLib(2) Methods ===================================*/
1229 /* ITypeLib::QueryInterface
1231 static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid,
1234 if(TRACE_ON(typelib)){
1236 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1237 TRACE("(%p)->(IID: %s)\n",This,xriid);
1240 if(IsEqualIID(riid, &IID_IUnknown) ||
1241 IsEqualIID(riid,&IID_ITypeLib)||
1242 IsEqualIID(riid,&IID_ITypeLib2))
1245 ITypeLib_AddRef(This);
1246 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1249 TRACE("-- Interface: E_NOINTERFACE\n");
1250 return E_NOINTERFACE;
1255 static ULONG WINAPI ITypeLib_fnAddRef( LPTYPELIB iface)
1257 ICOM_THIS( TLBLibInfo, iface);
1258 TRACE("(%p)->ref is %u\n",This, This->ref);
1259 return ++(This->ref);
1262 /* ITypeLib::Release
1264 static ULONG WINAPI ITypeLib_fnRelease( LPTYPELIB iface)
1266 ICOM_THIS( TLBLibInfo, iface);
1267 FIXME("(%p)->ref is %u: stub\n",This, This->ref);
1272 /* ITypeLib::GetTypeInfoCount
1274 * Returns the number of type descriptions in the type library
1276 static UINT WINAPI ITypeLib_fnGetTypeInfoCount( LPTYPELIB iface)
1278 ICOM_THIS( TLBLibInfo, iface);
1279 TRACE("(%p)->count is %d\n",This, This->TypeInfoCount);
1280 return This->TypeInfoCount;
1283 /* ITypeLib::GetTypeInfo
1285 *etrieves the specified type description in the library.
1287 static HRESULT WINAPI ITypeLib_fnGetTypeInfo( LPTYPELIB iface, UINT index,
1288 ITypeInfo **ppTInfo)
1291 ICOM_THIS( TLBLibInfo, iface);
1292 TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo;
1293 TRACE("(%p) index %d \n",This, index);
1294 for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo && i != index;i++)
1295 *ppTLBTInfo=(*ppTLBTInfo)->next;
1297 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
1298 TRACE("-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
1301 TRACE("-- element not found\n");
1302 return TYPE_E_ELEMENTNOTFOUND;
1305 /* ITypeLibs::GetTypeInfoType
1307 * Retrieves the type of a type description.
1309 static HRESULT WINAPI ITypeLib_fnGetTypeInfoType( LPTYPELIB iface, UINT index,
1313 TLBTypeInfo *pTInfo;
1314 ICOM_THIS( TLBLibInfo, iface);
1315 TRACE("(%p) index %d \n",This, index);
1316 for(i=0,pTInfo=This->pTypeInfo;pTInfo && i != index;i++)
1317 pTInfo=(pTInfo)->next;
1319 *pTKind=pTInfo->TypeAttr.typekind;
1320 TRACE("-- found Type (%p)->%d\n",pTKind,*pTKind);
1323 TRACE("-- element not found\n");
1324 return TYPE_E_ELEMENTNOTFOUND;
1327 /* ITypeLib::GetTypeInfoOfGuid
1329 * Retrieves the type description that corresponds to the specified GUID.
1332 static HRESULT WINAPI ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB iface,
1333 REFGUID guid, ITypeInfo **ppTInfo)
1336 ICOM_THIS( TLBLibInfo, iface);
1337 TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo;
1338 if(TRACE_ON(typelib)){
1340 WINE_StringFromCLSID((LPCLSID)guid,xriid);
1341 TRACE("(%p) guid %sx)\n",This,xriid);
1343 for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo &&
1344 !IsEqualIID(guid,&(*ppTLBTInfo)->TypeAttr.guid);i++)
1345 *ppTLBTInfo=(*ppTLBTInfo)->next;
1347 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
1348 TRACE("-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
1351 TRACE("-- element not found\n");
1352 return TYPE_E_ELEMENTNOTFOUND;
1355 /* ITypeLib::GetLibAttr
1357 * Retrieves the structure that contains the library's attributes.
1360 static HRESULT WINAPI ITypeLib_fnGetLibAttr( LPTYPELIB iface,
1361 LPTLIBATTR *ppTLibAttr)
1363 ICOM_THIS( TLBLibInfo, iface);
1364 TRACE("(%p)\n",This);
1365 /* FIXME: must do a copy here */
1366 *ppTLibAttr=&This->LibAttr;
1370 /* ITypeLib::GetTypeComp
1372 * Enables a client compiler to bind to a library's types, variables,
1373 * constants, and global functions.
1376 static HRESULT WINAPI ITypeLib_fnGetTypeComp( LPTYPELIB iface,
1377 ITypeComp **ppTComp)
1379 ICOM_THIS( TLBLibInfo, iface);
1380 FIXME("(%p): stub!\n",This);
1384 /* ITypeLib::GetDocumentation
1386 * Retrieves the library's documentation string, the complete Help file name
1387 * and path, and the context identifier for the library Help topic in the Help
1391 static HRESULT WINAPI ITypeLib_fnGetDocumentation( LPTYPELIB iface, INT index,
1392 BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext,
1393 BSTR *pBstrHelpFile)
1395 ICOM_THIS( TLBLibInfo, iface);
1398 TRACE("(%p) index %d Name(%p) DocString(%p)"
1399 " HelpContext(%p) HelpFile(%p)\n",
1400 This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1401 if(index<0){ /* documentation for the typelib */
1403 *pBstrName=TLB_DupAtoBstr(This->Name);
1405 *pBstrName=TLB_DupAtoBstr(This->DocString);
1407 *pdwHelpContext=This->dwHelpContext;
1409 *pBstrName=TLB_DupAtoBstr(This->HelpFile);
1410 }else {/* for a typeinfo */
1411 result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo);
1412 if(SUCCEEDED(result)){
1413 result=ITypeInfo_GetDocumentation(pTInfo, MEMBERID_NIL, pBstrName,
1414 pBstrDocString, pdwHelpContext, pBstrHelpFile);
1415 ITypeInfo_Release(pTInfo);
1417 if(!SUCCEEDED(result))
1425 * Indicates whether a passed-in string contains the name of a type or member
1426 * described in the library.
1429 static HRESULT WINAPI ITypeLib_fnIsName( LPTYPELIB iface, LPOLESTR szNameBuf,
1430 ULONG lHashVal, BOOL *pfName)
1432 ICOM_THIS( TLBLibInfo, iface);
1433 TLBTypeInfo *pTInfo;
1434 TLBFuncDesc *pFInfo;
1437 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1439 if(!strcmp(astr,This->Name)) goto ITypeLib_fnIsName_exit;
1440 for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){
1441 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnIsName_exit;
1442 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1443 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnIsName_exit;
1444 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1445 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1446 goto ITypeLib_fnIsName_exit;
1448 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
1449 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnIsName_exit;
1454 ITypeLib_fnIsName_exit:
1455 TRACE("(%p)slow! search for %s: %s found!\n", This,
1456 debugstr_a(astr), *pfName?"NOT":"");
1458 HeapFree( GetProcessHeap(), 0, astr );
1462 /* ITypeLib::FindName
1464 * Finds occurrences of a type description in a type library. This may be used
1465 * to quickly verify that a name exists in a type library.
1468 static HRESULT WINAPI ITypeLib_fnFindName( LPTYPELIB iface, LPOLESTR szNameBuf,
1469 ULONG lHashVal, ITypeInfo **ppTInfo, MEMBERID *rgMemId, UINT16 *pcFound)
1471 ICOM_THIS( TLBLibInfo, iface);
1472 TLBTypeInfo *pTInfo;
1473 TLBFuncDesc *pFInfo;
1476 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1477 for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){
1478 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnFindName_exit;
1479 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1480 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnFindName_exit;
1481 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1482 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1483 goto ITypeLib_fnFindName_exit;
1485 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
1486 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnFindName_exit;
1488 ITypeLib_fnFindName_exit:
1489 pTInfo->lpvtbl->fnAddRef((LPTYPEINFO)pTInfo);
1490 ppTInfo[j]=(LPTYPEINFO)pTInfo;
1493 TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
1494 This, *pcFound, debugstr_a(astr), j);
1498 HeapFree( GetProcessHeap(), 0, astr );
1502 /* ITypeLib::ReleaseTLibAttr
1504 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
1507 static VOID WINAPI ITypeLib_fnReleaseTLibAttr( LPTYPELIB iface, TLIBATTR *pTLibAttr)
1509 ICOM_THIS( TLBLibInfo, iface);
1510 TRACE("freeing (%p)\n",This);
1514 /* ITypeLib2::GetCustData
1516 * gets the custom data
1518 static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLib * iface, REFGUID guid,
1521 ICOM_THIS( TLBLibInfo, iface);
1522 TLBCustData *pCData;
1523 for(pCData=This->pCustData; pCData; pCData = pCData->next)
1524 if( IsEqualIID(guid, &pCData->guid)) break;
1525 if(TRACE_ON(typelib)){
1527 WINE_StringFromCLSID((LPCLSID)guid,xriid);
1528 TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
1531 VariantInit( pVarVal);
1532 VariantCopy( pVarVal, &pCData->data);
1535 return E_INVALIDARG; /* FIXME: correct? */
1538 /* ITypeLib2::GetLibStatistics
1540 * Returns statistics about a type library that are required for efficient
1541 * sizing of hash tables.
1544 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( ITypeLib * iface,
1545 UINT *pcUniqueNames, UINT *pcchUniqueNames)
1547 ICOM_THIS( TLBLibInfo, iface);
1548 FIXME("(%p): stub!\n", This);
1549 if(pcUniqueNames) *pcUniqueNames=1;
1550 if(pcchUniqueNames) *pcchUniqueNames=1;
1554 /* ITypeLib2::GetDocumentation2
1556 * Retrieves the library's documentation string, the complete Help file name
1557 * and path, the localization context to use, and the context ID for the
1558 * library Help topic in the Help file.
1561 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( ITypeLib * iface,
1562 INT index, LCID lcid, BSTR *pbstrHelpString,
1563 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
1565 ICOM_THIS( TLBLibInfo, iface);
1568 FIXME("(%p) index %d lcid %ld half implemented stub!\n", This,
1570 /* the help string should be obtained from the helpstringdll,
1571 * using the _DLLGetDocumentation function, based on the supplied
1572 * lcid. Nice to do sometime...
1574 if(index<0){ /* documentation for the typelib */
1576 *pbstrHelpString=TLB_DupAtoBstr(This->DocString);
1577 if(pdwHelpStringContext)
1578 *pdwHelpStringContext=This->dwHelpContext;
1579 if(pbstrHelpStringDll)
1580 *pbstrHelpStringDll=TLB_DupAtoBstr(This->HelpStringDll);
1581 }else {/* for a typeinfo */
1582 result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo);
1583 if(SUCCEEDED(result)){
1584 result=ITypeInfo2_fnGetDocumentation2(pTInfo, MEMBERID_NIL, lcid,
1585 pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
1586 ITypeInfo_Release(pTInfo);
1588 if(!SUCCEEDED(result))
1594 /* ITypeLib2::GetAllCustData
1596 * Gets all custom data items for the library.
1599 static HRESULT WINAPI ITypeLib2_fnGetAllCustData( ITypeLib * iface,
1600 CUSTDATA *pCustData)
1602 ICOM_THIS( TLBLibInfo, iface);
1603 TLBCustData *pCData;
1605 TRACE("(%p) returning %d items\n", This, This->ctCustData);
1606 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
1607 if(pCustData->prgCustData ){
1608 pCustData->cCustData=This->ctCustData;
1609 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
1610 pCustData->prgCustData[i].guid=pCData->guid;
1611 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
1614 ERR(" OUT OF MEMORY! \n");
1615 return E_OUTOFMEMORY;
1621 /*================== ITypeInfo(2) Methods ===================================*/
1623 /* ITypeInfo::QueryInterface
1625 static HRESULT WINAPI ITypeInfo_fnQueryInterface( LPTYPEINFO iface, REFIID riid,
1628 ICOM_THIS( TLBTypeInfo, iface);
1629 if(TRACE_ON(typelib)){
1631 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1632 TRACE("(%p)->(IID: %s)\n",This,xriid);
1635 if(IsEqualIID(riid, &IID_IUnknown) ||
1636 IsEqualIID(riid,&IID_ITypeInfo)||
1637 IsEqualIID(riid,&IID_ITypeInfo2))
1640 ITypeInfo_AddRef(iface);
1641 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1644 TRACE("-- Interface: E_NOINTERFACE\n");
1645 return E_NOINTERFACE;
1648 /* ITypeInfo::AddRef
1650 static ULONG WINAPI ITypeInfo_fnAddRef( LPTYPEINFO iface)
1652 ICOM_THIS( TLBTypeInfo, iface);
1653 TRACE("(%p)->ref is %u\n",This, This->ref);
1654 (This->pTypeLib->ref)++;
1655 return ++(This->ref);
1658 /* ITypeInfo::Release
1660 static ULONG WINAPI ITypeInfo_fnRelease( LPTYPEINFO iface)
1662 ICOM_THIS( TLBTypeInfo, iface);
1663 FIXME("(%p)->ref is %u: stub\n",This, This->ref);
1665 (This->pTypeLib->ref)--;
1669 /* ITypeInfo::GetTypeAttr
1671 * Retrieves a TYPEATTR structure that contains the attributes of the type
1675 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( LPTYPEINFO iface,
1676 LPTYPEATTR *ppTypeAttr)
1678 ICOM_THIS( TLBTypeInfo, iface);
1679 TRACE("(%p)\n",This);
1680 /* FIXME: must do a copy here */
1681 *ppTypeAttr=&This->TypeAttr;
1685 /* ITypeInfo::GetTypeComp
1687 * Retrieves the ITypeComp interface for the type description, which enables a
1688 * client compiler to bind to the type description's members.
1691 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( LPTYPEINFO iface,
1692 ITypeComp * *ppTComp)
1694 ICOM_THIS( TLBTypeInfo, iface);
1695 FIXME("(%p) stub!\n", This);
1699 /* ITypeInfo::GetFuncDesc
1701 * Retrieves the FUNCDESC structure that contains information about a
1702 * specified function.
1705 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( LPTYPEINFO iface, UINT index,
1706 LPFUNCDESC *ppFuncDesc)
1708 ICOM_THIS( TLBTypeInfo, iface);
1710 TLBFuncDesc * pFDesc;
1711 TRACE("(%p) index %d\n", This, index);
1712 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
1715 /* FIXME: must do a copy here */
1716 *ppFuncDesc=&pFDesc->funcdesc;
1719 return E_INVALIDARG;
1722 /* ITypeInfo::GetVarDesc
1724 * Retrieves a VARDESC structure that describes the specified variable.
1727 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( LPTYPEINFO iface, UINT index,
1728 LPVARDESC *ppVarDesc)
1730 ICOM_THIS( TLBTypeInfo, iface);
1732 TLBVarDesc * pVDesc;
1733 TRACE("(%p) index %d\n", This, index);
1734 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next)
1737 /* FIXME: must do a copy here */
1738 *ppVarDesc=&pVDesc->vardesc;
1741 return E_INVALIDARG;
1744 /* ITypeInfo_GetNames
1746 * Retrieves the variable with the specified member ID (or the name of the
1747 * property or method and its parameters) that correspond to the specified
1750 static HRESULT WINAPI ITypeInfo_fnGetNames( LPTYPEINFO iface, MEMBERID memid,
1751 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
1753 ICOM_THIS( TLBTypeInfo, iface);
1754 TLBFuncDesc * pFDesc;
1755 TLBVarDesc * pVDesc;
1757 TRACE("(%p) memid=0x%08lx Maxname=%d\n", This, memid,
1759 for(pFDesc=This->funclist; pFDesc->funcdesc.memid != memid && pFDesc;
1760 pFDesc=pFDesc->next)
1763 /* function found, now return function and parameter names */
1764 for(i=0; i<cMaxNames && i <= pFDesc->funcdesc.cParams; i++){
1765 if(!i) *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
1767 rgBstrNames[i]=TLB_DupAtoBstr(pFDesc->pParamDesc[i-1].Name);
1772 for(pVDesc=This->varlist; pVDesc->vardesc.memid != memid && pVDesc;
1773 pVDesc=pVDesc->next)
1776 *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
1779 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
1780 This->TypeAttr.cImplTypes ){
1781 /* recursive search */
1784 result=This->lpvtbl->fnGetRefTypeInfo(iface,
1785 This->impltypelist->reference, &pTInfo);
1786 if(SUCCEEDED(result)){
1787 result=ITypeInfo_GetNames(pTInfo, memid, rgBstrNames,
1788 cMaxNames, pcNames);
1789 ITypeInfo_Release(pTInfo);
1792 WARN("Could not search inherited interface!\n");
1794 WARN("no names found\n");
1796 return TYPE_E_ELEMENTNOTFOUND;
1803 /* ITypeInfo::GetRefTypeOfImplType
1805 * If a type description describes a COM class, it retrieves the type
1806 * description of the implemented interface types. For an interface,
1807 * GetRefTypeOfImplType returns the type information for inherited interfaces,
1811 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO iface,
1812 UINT index, HREFTYPE *pRefType)
1814 ICOM_THIS( TLBTypeInfo, iface);
1817 TRACE("(%p) index %d\n", This, index);
1818 for(i=0, pIref=This->impltypelist; i<index && pIref;
1819 i++, pIref=pIref->next)
1822 *pRefType=pIref->reference;
1825 return TYPE_E_ELEMENTNOTFOUND;
1828 /* ITypeInfo::GetImplTypeFlags
1830 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
1831 * or base interface in a type description.
1833 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO iface,
1834 UINT index, INT *pImplTypeFlags)
1836 ICOM_THIS( TLBTypeInfo, iface);
1839 TRACE("(%p) index %d\n", This, index);
1840 for(i=0, pIref=This->impltypelist; i<index && pIref; i++, pIref=pIref->next)
1842 if(i==index && pIref){
1843 *pImplTypeFlags=pIref->flags;
1847 return TYPE_E_ELEMENTNOTFOUND;
1851 * Maps between member names and member IDs, and parameter names and
1854 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( LPTYPEINFO iface,
1855 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
1857 ICOM_THIS( TLBTypeInfo, iface);
1858 TLBFuncDesc * pFDesc;
1859 TLBVarDesc * pVDesc;
1861 PCHAR aszName= HEAP_strdupWtoA( GetProcessHeap(), 0, *rgszNames);
1862 TRACE("(%p) Name %s cNames %d\n", This, debugstr_a(aszName),
1864 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) {
1866 if( !strcmp(aszName, pFDesc->Name)) {
1867 if(cNames) *pMemId=pFDesc->funcdesc.memid;
1868 for(i=1; i < cNames; i++){
1869 PCHAR aszPar= HEAP_strdupWtoA( GetProcessHeap(), 0,
1871 for(j=0; j<pFDesc->funcdesc.cParams; j++)
1872 if(strcmp(aszPar,pFDesc->pParamDesc[j].Name))
1874 if( j<pFDesc->funcdesc.cParams)
1877 ret=DISP_E_UNKNOWNNAME;
1878 HeapFree( GetProcessHeap(), 0, aszPar);
1880 HeapFree (GetProcessHeap(), 0, aszName);
1884 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
1885 if( !strcmp(aszName, pVDesc->Name)) {
1886 if(cNames) *pMemId=pVDesc->vardesc.memid;
1887 HeapFree (GetProcessHeap(), 0, aszName);
1891 /* not found, see if this is and interface with an inheritance */
1892 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
1893 This->TypeAttr.cImplTypes ){
1894 /* recursive search */
1896 ret=ITypeInfo_GetRefTypeInfo(iface,
1897 This->impltypelist->reference, &pTInfo);
1899 ret=ITypeInfo_GetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
1900 ITypeInfo_Release(pTInfo);
1903 WARN("Could not search inherited interface!\n");
1905 WARN("no names found\n");
1906 return DISP_E_UNKNOWNNAME;
1909 /* ITypeInfo::Invoke
1911 * Invokes a method, or accesses a property of an object, that implements the
1912 * interface described by the type description.
1914 static HRESULT WINAPI ITypeInfo_fnInvoke( LPTYPEINFO iface, VOID *pIUnk,
1915 MEMBERID memid, UINT16 dwFlags, DISPPARAMS *pDispParams,
1916 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *pArgErr)
1918 ICOM_THIS( TLBTypeInfo, iface);
1919 FIXME("(%p) stub!", This);
1923 /* ITypeInfo::GetDocumentation
1925 * Retrieves the documentation string, the complete Help file name and path,
1926 * and the context ID for the Help topic for a specified type description.
1928 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( LPTYPEINFO iface,
1929 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
1930 DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
1932 ICOM_THIS( TLBTypeInfo, iface);
1933 TLBFuncDesc * pFDesc;
1934 TLBVarDesc * pVDesc;
1935 TRACE("(%p) memid %ld Name(%p) DocString(%p)"
1936 " HelpContext(%p) HelpFile(%p)\n",
1937 This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1938 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
1940 *pBstrName=TLB_DupAtoBstr(This->Name);
1942 *pBstrDocString=TLB_DupAtoBstr(This->DocString);
1944 *pdwHelpContext=This->dwHelpContext;
1946 *pBstrHelpFile=TLB_DupAtoBstr(This->DocString);/* FIXME */
1948 }else {/* for a member */
1949 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
1950 if(pFDesc->funcdesc.memid==memid){
1953 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
1954 if(pVDesc->vardesc.memid==memid){
1958 return TYPE_E_ELEMENTNOTFOUND;
1961 /* ITypeInfo::GetDllEntry
1963 * Retrieves a description or specification of an entry point for a function
1966 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( LPTYPEINFO iface, MEMBERID memid,
1967 INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
1970 ICOM_THIS( TLBTypeInfo, iface);
1971 FIXME("(%p) stub!\n", This);
1975 /* ITypeInfo::GetRefTypeInfo
1977 * If a type description references other type descriptions, it retrieves
1978 * the referenced type descriptions.
1980 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO iface,
1981 HREFTYPE hRefType, ITypeInfo * *ppTInfo)
1983 ICOM_THIS( TLBTypeInfo, iface);
1985 if(HREFTYPE_INTHISFILE(hRefType)){
1988 result=This->lpvtbl->fnGetContainingTypeLib(iface, &pTLib,
1990 if(SUCCEEDED(result)){
1991 result=ITypeLib_GetTypeInfo(pTLib,
1992 HREFTYPE_INDEX(hRefType),
1994 ITypeLib_Release(pTLib );
1997 /* imported type lib */
1998 TLBRefType * pRefType;
1999 TLBLibInfo *pTypeLib;
2000 for( pRefType=This->impltypelist; pRefType &&
2001 pRefType->reference != hRefType; pRefType=pRefType->next)
2004 return TYPE_E_ELEMENTNOTFOUND; /* FIXME : correct? */
2005 pTypeLib=pRefType->pImpTLInfo->pImpTypeLib;
2006 if(pTypeLib) /* typelib already loaded */
2007 result=ITypeLib_GetTypeInfoOfGuid(
2008 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
2010 result=LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
2012 (LPTYPELIB *)&pTypeLib);
2013 if(!SUCCEEDED(result)){
2014 BSTR libnam=TLB_DupAtoBstr(pRefType->pImpTLInfo->name);
2015 result=LoadTypeLib(libnam, (LPTYPELIB *)&pTypeLib);
2016 SysFreeString(libnam);
2018 if(SUCCEEDED(result)){
2019 result=ITypeLib_GetTypeInfoOfGuid(
2020 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
2021 pRefType->pImpTLInfo->pImpTypeLib=pTypeLib;
2025 TRACE("(%p) hreftype 0x%04lx loaded %s (%p)\n", This, hRefType,
2026 SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
2030 /* ITypeInfo::AddressOfMember
2032 * Retrieves the addresses of static functions or variables, such as those
2035 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( LPTYPEINFO iface,
2036 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
2038 ICOM_THIS( TLBTypeInfo, iface);
2039 FIXME("(%p) stub!\n", This);
2043 /* ITypeInfo::CreateInstance
2045 * Creates a new instance of a type that describes a component object class
2048 static HRESULT WINAPI ITypeInfo_fnCreateInstance( LPTYPEINFO iface,
2049 IUnknown *pUnk, REFIID riid, VOID **ppvObj)
2051 ICOM_THIS( TLBTypeInfo, iface);
2052 FIXME("(%p) stub!\n", This);
2056 /* ITypeInfo::GetMops
2058 * Retrieves marshaling information.
2060 static HRESULT WINAPI ITypeInfo_fnGetMops( LPTYPEINFO iface, MEMBERID memid,
2063 ICOM_THIS( TLBTypeInfo, iface);
2064 FIXME("(%p) stub!\n", This);
2068 /* ITypeInfo::GetContainingTypeLib
2070 * Retrieves the containing type library and the index of the type description
2071 * within that type library.
2073 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( LPTYPEINFO iface,
2074 ITypeLib * *ppTLib, UINT *pIndex)
2076 ICOM_THIS( TLBTypeInfo, iface);
2077 *ppTLib=(LPTYPELIB )(This->pTypeLib);
2078 *pIndex=This->index;
2079 ITypeLib_AddRef(*ppTLib);
2080 TRACE("(%p) returns (%p) index %d!\n", This, *ppTLib, *pIndex);
2084 /* ITypeInfo::ReleaseTypeAttr
2086 * Releases a TYPEATTR previously returned by GetTypeAttr.
2089 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO iface,
2090 TYPEATTR* pTypeAttr)
2092 ICOM_THIS( TLBTypeInfo, iface);
2093 TRACE("(%p)->(%p)\n", This, pTypeAttr);
2097 /* ITypeInfo::ReleaseFuncDesc
2099 * Releases a FUNCDESC previously returned by GetFuncDesc. *
2101 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO iface,
2102 FUNCDESC *pFuncDesc)
2104 ICOM_THIS( TLBTypeInfo, iface);
2105 TRACE("(%p)->(%p)\n", This, pFuncDesc);
2109 /* ITypeInfo::ReleaseVarDesc
2111 * Releases a VARDESC previously returned by GetVarDesc.
2113 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( LPTYPEINFO iface,
2116 ICOM_THIS( TLBTypeInfo, iface);
2117 TRACE("(%p)->(%p)\n", This, pVarDesc);
2121 /* ITypeInfo2::GetTypeKind
2123 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
2126 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo * iface,
2127 TYPEKIND *pTypeKind)
2129 ICOM_THIS( TLBTypeInfo, iface);
2130 *pTypeKind=This->TypeAttr.typekind;
2131 TRACE("(%p) type 0x%0x\n", This,*pTypeKind);
2135 /* ITypeInfo2::GetTypeFlags
2137 * Returns the type flags without any allocations. This returns a DWORD type
2138 * flag, which expands the type flags without growing the TYPEATTR (type
2142 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo * iface,
2145 ICOM_THIS( TLBTypeInfo, iface);
2146 *pTypeFlags=This->TypeAttr.wTypeFlags;
2147 TRACE("(%p) flags 0x%04x\n", This,*pTypeFlags);
2151 /* ITypeInfo2::GetFuncIndexOfMemId
2152 * Binds to a specific member based on a known DISPID, where the member name
2153 * is not known (for example, when binding to a default member).
2156 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo * iface,
2157 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
2159 ICOM_THIS( TLBTypeInfo, iface);
2160 TLBFuncDesc *pFuncInfo;
2163 /* FIXME: should check for invKind??? */
2164 for(i=0, pFuncInfo=This->funclist;pFuncInfo &&
2165 memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next);
2171 result=E_INVALIDARG;
2173 TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This,
2174 memid, invKind, SUCCEEDED(result)? "SUCCES":"FAILED");
2178 /* TypeInfo2::GetVarIndexOfMemId
2180 * Binds to a specific member based on a known DISPID, where the member name
2181 * is not known (for example, when binding to a default member).
2184 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo * iface,
2185 MEMBERID memid, UINT *pVarIndex)
2187 ICOM_THIS( TLBTypeInfo, iface);
2188 TLBVarDesc *pVarInfo;
2191 for(i=0, pVarInfo=This->varlist; pVarInfo &&
2192 memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next)
2199 result=E_INVALIDARG;
2201 TRACE("(%p) memid 0x%08lx -> %s\n", This,
2202 memid, SUCCEEDED(result)? "SUCCES":"FAILED");
2206 /* ITypeInfo2::GetCustData
2208 * Gets the custom data
2210 static HRESULT WINAPI ITypeInfo2_fnGetCustData( ITypeInfo * iface,
2211 REFGUID guid, VARIANT *pVarVal)
2213 ICOM_THIS( TLBTypeInfo, iface);
2214 TLBCustData *pCData;
2215 for(pCData=This->pCustData; pCData; pCData = pCData->next)
2216 if( IsEqualIID(guid, &pCData->guid)) break;
2217 if(TRACE_ON(typelib)){
2219 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2220 TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
2223 VariantInit( pVarVal);
2224 VariantCopy( pVarVal, &pCData->data);
2227 return E_INVALIDARG; /* FIXME: correct? */
2230 /* ITypeInfo2::GetFuncCustData
2232 * Gets the custom data
2234 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( ITypeInfo * iface,
2235 UINT index, REFGUID guid, VARIANT *pVarVal)
2237 ICOM_THIS( TLBTypeInfo, iface);
2238 TLBCustData *pCData=NULL;
2239 TLBFuncDesc * pFDesc;
2241 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2242 pFDesc=pFDesc->next)
2245 for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next)
2246 if( IsEqualIID(guid, &pCData->guid)) break;
2247 if(TRACE_ON(typelib)){
2249 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2250 TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
2253 VariantInit( pVarVal);
2254 VariantCopy( pVarVal, &pCData->data);
2257 return E_INVALIDARG; /* FIXME: correct? */
2260 /* ITypeInfo2::GetParamCustData
2262 * Gets the custom data
2264 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( ITypeInfo * iface,
2265 UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal)
2267 ICOM_THIS( TLBTypeInfo, iface);
2268 TLBCustData *pCData=NULL;
2269 TLBFuncDesc * pFDesc;
2271 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
2272 pFDesc=pFDesc->next)
2274 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams)
2275 for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData;
2276 pCData = pCData->next)
2277 if( IsEqualIID(guid, &pCData->guid)) break;
2278 if(TRACE_ON(typelib)){
2280 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2281 TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
2284 VariantInit( pVarVal);
2285 VariantCopy( pVarVal, &pCData->data);
2288 return E_INVALIDARG; /* FIXME: correct? */
2291 /* ITypeInfo2::GetVarcCustData
2293 * Gets the custom data
2295 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( ITypeInfo * iface,
2296 UINT index, REFGUID guid, VARIANT *pVarVal)
2298 ICOM_THIS( TLBTypeInfo, iface);
2299 TLBCustData *pCData=NULL;
2300 TLBVarDesc * pVDesc;
2302 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2303 pVDesc=pVDesc->next)
2306 for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next)
2307 if( IsEqualIID(guid, &pCData->guid)) break;
2308 if(TRACE_ON(typelib)){
2310 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2311 TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
2314 VariantInit( pVarVal);
2315 VariantCopy( pVarVal, &pCData->data);
2318 return E_INVALIDARG; /* FIXME: correct? */
2321 /* ITypeInfo2::GetImplcCustData
2323 * Gets the custom data
2325 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( ITypeInfo * iface,
2326 UINT index, REFGUID guid, VARIANT *pVarVal)
2328 ICOM_THIS( TLBTypeInfo, iface);
2329 TLBCustData *pCData=NULL;
2330 TLBRefType * pRDesc;
2332 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2333 pRDesc=pRDesc->next)
2336 for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next)
2337 if( IsEqualIID(guid, &pCData->guid)) break;
2338 if(TRACE_ON(typelib)){
2340 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2341 TRACE("(%p) guid %s %s found!x)\n", This, xriid, pCData? "" : "NOT");
2344 VariantInit( pVarVal);
2345 VariantCopy( pVarVal, &pCData->data);
2348 return E_INVALIDARG; /* FIXME: correct? */
2351 /* ITypeInfo2::GetDocumentation2
2353 * Retrieves the documentation string, the complete Help file name and path,
2354 * the localization context to use, and the context ID for the library Help
2355 * topic in the Help file.
2358 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( ITypeInfo * iface,
2359 MEMBERID memid, LCID lcid, BSTR *pbstrHelpString,
2360 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
2362 ICOM_THIS( TLBTypeInfo, iface);
2363 TLBFuncDesc * pFDesc;
2364 TLBVarDesc * pVDesc;
2365 TRACE("(%p) memid %ld lcid(0x%lx) HelpString(%p) "
2366 "HelpStringContext(%p) HelpStringDll(%p)\n",
2367 This, memid, lcid, pbstrHelpString, pdwHelpStringContext,
2368 pbstrHelpStringDll );
2369 /* the help string should be obtained from the helpstringdll,
2370 * using the _DLLGetDocumentation function, based on the supplied
2371 * lcid. Nice to do sometime...
2373 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
2375 *pbstrHelpString=TLB_DupAtoBstr(This->Name);
2376 if(pdwHelpStringContext)
2377 *pdwHelpStringContext=This->dwHelpStringContext;
2378 if(pbstrHelpStringDll)
2379 *pbstrHelpStringDll=
2380 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2382 }else {/* for a member */
2383 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
2384 if(pFDesc->funcdesc.memid==memid){
2386 *pbstrHelpString=TLB_DupAtoBstr(pFDesc->HelpString);
2387 if(pdwHelpStringContext)
2388 *pdwHelpStringContext=pFDesc->HelpStringContext;
2389 if(pbstrHelpStringDll)
2390 *pbstrHelpStringDll=
2391 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2394 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
2395 if(pVDesc->vardesc.memid==memid){
2397 *pbstrHelpString=TLB_DupAtoBstr(pVDesc->HelpString);
2398 if(pdwHelpStringContext)
2399 *pdwHelpStringContext=pVDesc->HelpStringContext;
2400 if(pbstrHelpStringDll)
2401 *pbstrHelpStringDll=
2402 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2406 return TYPE_E_ELEMENTNOTFOUND;
2409 /* ITypeInfo2::GetAllCustData
2411 * Gets all custom data items for the Type info.
2414 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( ITypeInfo * iface,
2415 CUSTDATA *pCustData)
2417 ICOM_THIS( TLBTypeInfo, iface);
2418 TLBCustData *pCData;
2420 TRACE("(%p) returning %d items\n", This, This->ctCustData);
2421 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
2422 if(pCustData->prgCustData ){
2423 pCustData->cCustData=This->ctCustData;
2424 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
2425 pCustData->prgCustData[i].guid=pCData->guid;
2426 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
2429 ERR(" OUT OF MEMORY! \n");
2430 return E_OUTOFMEMORY;
2435 /* ITypeInfo2::GetAllFuncCustData
2437 * Gets all custom data items for the specified Function
2440 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( ITypeInfo * iface,
2441 UINT index, CUSTDATA *pCustData)
2443 ICOM_THIS( TLBTypeInfo, iface);
2444 TLBCustData *pCData;
2445 TLBFuncDesc * pFDesc;
2447 TRACE("(%p) index %d\n", This, index);
2448 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2449 pFDesc=pFDesc->next)
2452 pCustData->prgCustData =
2453 TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM));
2454 if(pCustData->prgCustData ){
2455 pCustData->cCustData=pFDesc->ctCustData;
2456 for(i=0, pCData=pFDesc->pCustData; pCData; i++,
2457 pCData = pCData->next){
2458 pCustData->prgCustData[i].guid=pCData->guid;
2459 VariantCopy(& pCustData->prgCustData[i].varValue,
2463 ERR(" OUT OF MEMORY! \n");
2464 return E_OUTOFMEMORY;
2468 return TYPE_E_ELEMENTNOTFOUND;
2471 /* ITypeInfo2::GetAllParamCustData
2473 * Gets all custom data items for the Functions
2476 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo * iface,
2477 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
2479 ICOM_THIS( TLBTypeInfo, iface);
2480 TLBCustData *pCData=NULL;
2481 TLBFuncDesc * pFDesc;
2483 TRACE("(%p) index %d\n", This, indexFunc);
2484 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
2485 pFDesc=pFDesc->next)
2487 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams){
2488 pCustData->prgCustData =
2489 TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData *
2490 sizeof(CUSTDATAITEM));
2491 if(pCustData->prgCustData ){
2492 pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData;
2493 for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData;
2494 pCData; i++, pCData = pCData->next){
2495 pCustData->prgCustData[i].guid=pCData->guid;
2496 VariantCopy(& pCustData->prgCustData[i].varValue,
2500 ERR(" OUT OF MEMORY! \n");
2501 return E_OUTOFMEMORY;
2505 return TYPE_E_ELEMENTNOTFOUND;
2508 /* ITypeInfo2::GetAllVarCustData
2510 * Gets all custom data items for the specified Variable
2513 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo * iface,
2514 UINT index, CUSTDATA *pCustData)
2516 ICOM_THIS( TLBTypeInfo, iface);
2517 TLBCustData *pCData;
2518 TLBVarDesc * pVDesc;
2520 TRACE("(%p) index %d\n", This, index);
2521 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2522 pVDesc=pVDesc->next)
2525 pCustData->prgCustData =
2526 TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM));
2527 if(pCustData->prgCustData ){
2528 pCustData->cCustData=pVDesc->ctCustData;
2529 for(i=0, pCData=pVDesc->pCustData; pCData; i++,
2530 pCData = pCData->next){
2531 pCustData->prgCustData[i].guid=pCData->guid;
2532 VariantCopy(& pCustData->prgCustData[i].varValue,
2536 ERR(" OUT OF MEMORY! \n");
2537 return E_OUTOFMEMORY;
2541 return TYPE_E_ELEMENTNOTFOUND;
2544 /* ITypeInfo2::GetAllImplCustData
2546 * Gets all custom data items for the specified implementation type
2549 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo * iface,
2550 UINT index, CUSTDATA *pCustData)
2552 ICOM_THIS( TLBTypeInfo, iface);
2553 TLBCustData *pCData;
2554 TLBRefType * pRDesc;
2556 TRACE("(%p) index %d\n", This, index);
2557 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2558 pRDesc=pRDesc->next)
2561 pCustData->prgCustData =
2562 TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM));
2563 if(pCustData->prgCustData ){
2564 pCustData->cCustData=pRDesc->ctCustData;
2565 for(i=0, pCData=pRDesc->pCustData; pCData; i++,
2566 pCData = pCData->next){
2567 pCustData->prgCustData[i].guid=pCData->guid;
2568 VariantCopy(& pCustData->prgCustData[i].varValue,
2572 ERR(" OUT OF MEMORY! \n");
2573 return E_OUTOFMEMORY;
2577 return TYPE_E_ELEMENTNOTFOUND;