On NE process creation, move major part of NE EXE module loading and
[wine.git] / ole / typelib.c
blobbd27e9e84668d05f03dc22d2015f48f69aecaeba
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);
1071 CloseHandle(cx.hFile);
1072 return E_FAIL;
1074 /* now fill our internal data */
1075 /* TLIBATTR fields */
1076 TLB_ReadGuid(&pLibInfo->LibAttr.guid, tlbHeader.posguid, &cx);
1077 pLibInfo->LibAttr.lcid=tlbHeader.lcid;
1078 pLibInfo->LibAttr.syskind=tlbHeader.varflags & 0x0f; /* check the mask */
1079 pLibInfo->LibAttr.wMajorVerNum=LOWORD(tlbHeader.version);
1080 pLibInfo->LibAttr.wMinorVerNum=HIWORD(tlbHeader.version);
1081 pLibInfo->LibAttr.wLibFlags=(WORD) tlbHeader.flags & 0xffff;/* check mask */
1082 /* name, eventually add to a hash table */
1083 pLibInfo->Name=TLB_ReadName(&cx, tlbHeader.NameOffset);
1084 /* help info */
1085 pLibInfo->DocString=TLB_ReadString(&cx, tlbHeader.helpstring);
1086 pLibInfo->HelpFile=TLB_ReadString(&cx, tlbHeader.helpfile);
1087 if( tlbHeader.varflags & HELPDLLFLAG){
1088 int offset;
1089 TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
1090 pLibInfo->HelpStringDll=TLB_ReadString(&cx, offset);
1093 pLibInfo->dwHelpContext=tlbHeader.helpstringcontext;
1094 /* custom data */
1095 if(tlbHeader.CustomDataOffset >= 0) {
1096 pLibInfo->ctCustData=
1097 TLB_CustData(&cx, tlbHeader.CustomDataOffset, &pLibInfo->pCustData);
1099 /* fill in typedescriptions */
1100 if(tlbSegDir.pTypdescTab.length >0){
1101 int i, j, cTD=tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
1102 INT16 td[4];
1103 pLibInfo->pTypeDesc=
1104 TLB_Alloc( cTD * sizeof(TYPEDESC));
1105 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
1106 for(i=0;i<cTD;){
1107 /* FIXME: add several sanity checks here */
1108 pLibInfo->pTypeDesc[i].vt=td[0] & VT_TYPEMASK;
1109 if(td[0]==VT_PTR ||td[0]==VT_SAFEARRAY){/* FIXME: check safearray */
1110 if(td[3]<0)
1111 V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
1112 & stndTypeDesc[td[2]];
1113 else
1114 V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
1115 & pLibInfo->pTypeDesc[td[3]/8];
1116 }else if(td[0]==VT_CARRAY)
1117 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
1118 (void *)((int) td[2]); /* temp store offset in*/
1119 /* array descr table here */
1120 else if(td[0]==VT_USERDEFINED)
1121 V_UNION(&(pLibInfo->pTypeDesc[i]),hreftype)=MAKELONG(td[2],td[3]);
1122 if(++i<cTD) TLB_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
1124 /* second time around to fill the array subscript info */
1125 for(i=0;i<cTD;i++){
1126 if(pLibInfo->pTypeDesc[i].vt != VT_CARRAY) continue;
1127 if(tlbSegDir.pArrayDescriptions.offset>0){
1128 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset +
1129 (int) V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc));
1130 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
1131 TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
1132 if(td[1]<0)
1133 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem.vt=td[0] & VT_TYPEMASK;
1134 else
1135 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem=stndTypeDesc[td[0]/8];
1136 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->cDims=td[2];
1137 for(j=0;j<td[2];j++){
1138 TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->rgbounds[j].cElements,
1139 sizeof(INT), &cx, DO_NOT_SEEK);
1140 TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)
1141 ->rgbounds[j].lLbound,
1142 sizeof(INT), &cx, DO_NOT_SEEK);
1144 }else{
1145 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=NULL;
1146 ERR(ole, "didn't find array description data\n");
1150 /* imported type libs */
1151 if(tlbSegDir.pImpFiles.offset>0){
1152 TLBImpLib **ppImpLib=&(pLibInfo->pImpLibs);
1153 int offset=tlbSegDir.pImpFiles.offset;
1154 int oGuid;
1155 UINT16 size;
1156 while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length){
1157 *ppImpLib=TLB_Alloc(sizeof(TLBImpLib));
1158 (*ppImpLib)->offset=offset - tlbSegDir.pImpFiles.offset;
1159 TLB_Read(&oGuid, sizeof(INT), &cx, offset);
1160 TLB_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
1161 /* we are skipping some unknown info here */
1162 TLB_Read(& size,sizeof(UINT16), &cx, offset+3*(sizeof(INT)));
1163 size >>=2;
1164 (*ppImpLib)->name=TLB_Alloc(size+1);
1165 TLB_Read((*ppImpLib)->name,size, &cx, DO_NOT_SEEK);
1166 offset=(offset+3*(sizeof(INT))+sizeof(UINT16)+size+3) & 0xfffffffc;
1168 ppImpLib=&(*ppImpLib)->next;
1171 /* type info's */
1172 if(tlbHeader.nrtypeinfos >=0 ){
1173 /*pLibInfo->TypeInfoCount=tlbHeader.nrtypeinfos; */
1174 TLBTypeInfo **ppTI=&(pLibInfo->pTypeInfo);
1175 int i;
1176 for(i=0;i<(int)tlbHeader.nrtypeinfos;i++){
1177 *ppTI=TLB_DoTypeInfo(&cx, i, pLibInfo);
1178 ppTI=&((*ppTI)->next);
1179 (pLibInfo->TypeInfoCount)++;
1183 CloseHandle(cx.hFile);
1184 *ppTypeLib=(LPTYPELIB)pLibInfo;
1185 return S_OK;
1188 /*================== ITypeLib(2) Methods ===================================*/
1190 /* ITypeLib::QueryInterface
1192 static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid,
1193 VOID **ppvObject)
1195 if(TRACE_ON(typelib)){
1196 char xriid[50];
1197 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1198 TRACE(typelib,"(%p)->(IID: %s)\n",This,xriid);
1200 *ppvObject=NULL;
1201 if(IsEqualIID(riid, &IID_IUnknown) ||
1202 IsEqualIID(riid,&IID_ITypeLib)||
1203 IsEqualIID(riid,&IID_ITypeLib2))
1204 *ppvObject = This;
1205 if(*ppvObject){
1206 (*(LPTYPELIB*)ppvObject)->lpvtbl->fnAddRef(This);
1207 TRACE(typelib,"-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1208 return S_OK;
1210 TRACE(typelib,"-- Interface: E_NOINTERFACE\n");
1211 return E_NOINTERFACE;
1214 /* ITypeLib::AddRef
1216 static ULONG WINAPI ITypeLib_fnAddRef( LPTYPELIB iface)
1218 ICOM_THIS( TLBLibInfo, iface);
1219 TRACE(typelib,"(%p)->ref is %u\n",This, This->ref);
1220 return ++(This->ref);
1223 /* ITypeLib::Release
1225 static ULONG WINAPI ITypeLib_fnRelease( LPTYPELIB iface)
1227 ICOM_THIS( TLBLibInfo, iface);
1228 FIXME(typelib,"(%p)->ref is %u: stub\n",This, This->ref);
1229 (This->ref)--;
1230 return S_OK;
1233 /* ITypeLib::GetTypeInfoCount
1235 * Returns the number of type descriptions in the type library
1237 static UINT WINAPI ITypeLib_fnGetTypeInfoCount( LPTYPELIB iface)
1239 ICOM_THIS( TLBLibInfo, iface);
1240 TRACE(typelib,"(%p)->count is %d\n",This, This->TypeInfoCount);
1241 return This->TypeInfoCount;
1244 /* ITypeLib::GetTypeInfo
1246 *etrieves the specified type description in the library.
1248 static HRESULT WINAPI ITypeLib_fnGetTypeInfo( LPTYPELIB iface, UINT index,
1249 ITypeInfo **ppTInfo)
1251 int i;
1252 ICOM_THIS( TLBLibInfo, iface);
1253 TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo;
1254 TRACE(typelib,"(%p) index %d \n",This, index);
1255 for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo && i != index;i++)
1256 *ppTLBTInfo=(*ppTLBTInfo)->next;
1257 if(*ppTLBTInfo){
1258 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
1259 TRACE(typelib,"-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
1260 return S_OK;
1262 TRACE(typelib,"-- element not found\n");
1263 return TYPE_E_ELEMENTNOTFOUND;
1266 /* ITypeLibs::GetTypeInfoType
1268 * Retrieves the type of a type description.
1270 static HRESULT WINAPI ITypeLib_fnGetTypeInfoType( LPTYPELIB iface, UINT index,
1271 TYPEKIND *pTKind)
1273 int i;
1274 TLBTypeInfo *pTInfo;
1275 ICOM_THIS( TLBLibInfo, iface);
1276 TRACE(typelib,"(%p) index %d \n",This, index);
1277 for(i=0,pTInfo=This->pTypeInfo;pTInfo && i != index;i++)
1278 pTInfo=(pTInfo)->next;
1279 if(pTInfo){
1280 *pTKind=pTInfo->TypeAttr.typekind;
1281 TRACE(typelib,"-- found Type (%p)->%d\n",pTKind,*pTKind);
1282 return S_OK;
1284 TRACE(typelib,"-- element not found\n");
1285 return TYPE_E_ELEMENTNOTFOUND;
1288 /* ITypeLib::GetTypeInfoOfGuid
1290 * Retrieves the type description that corresponds to the specified GUID.
1293 static HRESULT WINAPI ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB iface,
1294 REFGUID guid, ITypeInfo **ppTInfo)
1296 int i;
1297 ICOM_THIS( TLBLibInfo, iface);
1298 TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo;
1299 if(TRACE_ON(typelib)){
1300 char xriid[50];
1301 WINE_StringFromCLSID((LPCLSID)guid,xriid);
1302 TRACE(typelib,"(%p) guid %sx)\n",This,xriid);
1304 for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo &&
1305 !IsEqualIID(guid,&(*ppTLBTInfo)->TypeAttr.guid);i++)
1306 *ppTLBTInfo=(*ppTLBTInfo)->next;
1307 if(*ppTLBTInfo){
1308 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
1309 TRACE(typelib,"-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
1310 return S_OK;
1312 TRACE(typelib,"-- element not found\n");
1313 return TYPE_E_ELEMENTNOTFOUND;
1316 /* ITypeLib::GetLibAttr
1318 * Retrieves the structure that contains the library's attributes.
1321 static HRESULT WINAPI ITypeLib_fnGetLibAttr( LPTYPELIB iface,
1322 LPTLIBATTR *ppTLibAttr)
1324 ICOM_THIS( TLBLibInfo, iface);
1325 TRACE( typelib,"(%p)\n",This);
1326 /* FIXME: must do a copy here */
1327 *ppTLibAttr=&This->LibAttr;
1328 return S_OK;
1331 /* ITypeLib::GetTypeComp
1333 * Enables a client compiler to bind to a library's types, variables,
1334 * constants, and global functions.
1337 static HRESULT WINAPI ITypeLib_fnGetTypeComp( LPTYPELIB iface,
1338 ITypeComp **ppTComp)
1340 ICOM_THIS( TLBLibInfo, iface);
1341 FIXME(typelib,"(%p): stub!\n",This);
1342 return E_NOTIMPL;
1345 /* ITypeLib::GetDocumentation
1347 * Retrieves the library's documentation string, the complete Help file name
1348 * and path, and the context identifier for the library Help topic in the Help
1349 * file.
1352 static HRESULT WINAPI ITypeLib_fnGetDocumentation( LPTYPELIB iface, INT index,
1353 BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext,
1354 BSTR *pBstrHelpFile)
1356 ICOM_THIS( TLBLibInfo, iface);
1357 HRESULT result;
1358 ITypeInfo *pTInfo;
1359 TRACE( typelib, "(%p) index %d Name(%p) DocString(%p)"
1360 " HelpContext(%p) HelpFile(%p)\n",
1361 This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1362 if(index<0){ /* documentation for the typelib */
1363 if(pBstrName)
1364 *pBstrName=TLB_DupAtoBstr(This->Name);
1365 if(pBstrDocString)
1366 *pBstrName=TLB_DupAtoBstr(This->DocString);
1367 if(pdwHelpContext)
1368 *pdwHelpContext=This->dwHelpContext;
1369 if(pBstrHelpFile)
1370 *pBstrName=TLB_DupAtoBstr(This->HelpFile);
1371 }else {/* for a typeinfo */
1372 result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo);
1373 if(SUCCEEDED(result)){
1374 result=ITypeInfo_GetDocumentation(pTInfo, MEMBERID_NIL, pBstrName,
1375 pBstrDocString, pdwHelpContext, pBstrHelpFile);
1376 ITypeInfo_Release(pTInfo);
1378 if(!SUCCEEDED(result))
1379 return result;
1381 return S_OK;
1384 /* ITypeLib::IsName
1386 * Indicates whether a passed-in string contains the name of a type or member
1387 * described in the library.
1390 static HRESULT WINAPI ITypeLib_fnIsName( LPTYPELIB iface, LPOLESTR szNameBuf,
1391 ULONG lHashVal, BOOL *pfName)
1393 ICOM_THIS( TLBLibInfo, iface);
1394 TLBTypeInfo *pTInfo;
1395 TLBFuncDesc *pFInfo;
1396 TLBVarDesc *pVInfo;
1397 int i;
1398 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1399 *pfName=TRUE;
1400 if(!strcmp(astr,This->Name)) goto ITypeLib_fnIsName_exit;
1401 for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){
1402 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnIsName_exit;
1403 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1404 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnIsName_exit;
1405 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1406 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1407 goto ITypeLib_fnIsName_exit;
1409 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
1410 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnIsName_exit;
1413 *pfName=FALSE;
1415 ITypeLib_fnIsName_exit:
1416 TRACE( typelib,"(%p)slow! search for %s: %s found!\n", This,
1417 debugstr_a(astr), *pfName?"NOT":"");
1419 HeapFree( GetProcessHeap(), 0, astr );
1420 return S_OK;
1423 /* ITypeLib::FindName
1425 * Finds occurrences of a type description in a type library. This may be used
1426 * to quickly verify that a name exists in a type library.
1429 static HRESULT WINAPI ITypeLib_fnFindName( LPTYPELIB iface, LPOLESTR szNameBuf,
1430 ULONG lHashVal, ITypeInfo **ppTInfo, MEMBERID *rgMemId, UINT16 *pcFound)
1432 ICOM_THIS( TLBLibInfo, iface);
1433 TLBTypeInfo *pTInfo;
1434 TLBFuncDesc *pFInfo;
1435 TLBVarDesc *pVInfo;
1436 int i,j = 0;
1437 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1438 for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){
1439 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnFindName_exit;
1440 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1441 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnFindName_exit;
1442 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1443 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1444 goto ITypeLib_fnFindName_exit;
1446 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
1447 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnFindName_exit;
1448 continue;
1449 ITypeLib_fnFindName_exit:
1450 pTInfo->lpvtbl->fnAddRef((LPTYPEINFO)pTInfo);
1451 ppTInfo[j]=(LPTYPEINFO)pTInfo;
1452 j++;
1454 TRACE( typelib,"(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
1455 This, *pcFound, debugstr_a(astr), j);
1457 *pcFound=j;
1459 HeapFree( GetProcessHeap(), 0, astr );
1460 return S_OK;
1463 /* ITypeLib::ReleaseTLibAttr
1465 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
1468 static VOID WINAPI ITypeLib_fnReleaseTLibAttr( LPTYPELIB iface, TLIBATTR *pTLibAttr)
1470 ICOM_THIS( TLBLibInfo, iface);
1471 TRACE( typelib,"freeing (%p)\n",This);
1472 /* nothing to do */
1475 /* ITypeLib2::GetCustData
1477 * gets the custom data
1479 static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLib * iface, REFGUID guid,
1480 VARIANT *pVarVal)
1482 ICOM_THIS( TLBLibInfo, iface);
1483 TLBCustData *pCData;
1484 for(pCData=This->pCustData; pCData; pCData = pCData->next)
1485 if( IsEqualIID(guid, &pCData->guid)) break;
1486 if(TRACE_ON(typelib)){
1487 char xriid[50];
1488 WINE_StringFromCLSID((LPCLSID)guid,xriid);
1489 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
1490 pCData? "" : "NOT");
1492 if(pCData){
1493 VariantInit( pVarVal);
1494 VariantCopy( pVarVal, &pCData->data);
1495 return S_OK;
1497 return E_INVALIDARG; /* FIXME: correct? */
1500 /* ITypeLib2::GetLibStatistics
1502 * Returns statistics about a type library that are required for efficient
1503 * sizing of hash tables.
1506 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( ITypeLib * iface,
1507 UINT *pcUniqueNames, UINT *pcchUniqueNames)
1509 ICOM_THIS( TLBLibInfo, iface);
1510 FIXME( typelib,"(%p): stub!\n", This);
1511 if(pcUniqueNames) *pcUniqueNames=1;
1512 if(pcchUniqueNames) *pcchUniqueNames=1;
1513 return S_OK;
1516 /* ITypeLib2::GetDocumentation2
1518 * Retrieves the library's documentation string, the complete Help file name
1519 * and path, the localization context to use, and the context ID for the
1520 * library Help topic in the Help file.
1523 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( ITypeLib * iface,
1524 INT index, LCID lcid, BSTR *pbstrHelpString,
1525 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
1527 ICOM_THIS( TLBLibInfo, iface);
1528 HRESULT result;
1529 ITypeInfo *pTInfo;
1530 FIXME( typelib,"(%p) index %d lcid %ld half implemented stub!\n", This,
1531 index, lcid);
1532 /* the help string should be obtained from the helpstringdll,
1533 * using the _DLLGetDocumentation function, based on the supplied
1534 * lcid. Nice to do sometime...
1536 if(index<0){ /* documentation for the typelib */
1537 if(pbstrHelpString)
1538 *pbstrHelpString=TLB_DupAtoBstr(This->DocString);
1539 if(pdwHelpStringContext)
1540 *pdwHelpStringContext=This->dwHelpContext;
1541 if(pbstrHelpStringDll)
1542 *pbstrHelpStringDll=TLB_DupAtoBstr(This->HelpStringDll);
1543 }else {/* for a typeinfo */
1544 result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo);
1545 if(SUCCEEDED(result)){
1546 result=ITypeInfo2_fnGetDocumentation2(pTInfo, MEMBERID_NIL, lcid,
1547 pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
1548 ITypeInfo_Release(pTInfo);
1550 if(!SUCCEEDED(result))
1551 return result;
1553 return S_OK;
1556 /* ITypeLib2::GetAllCustData
1558 * Gets all custom data items for the library.
1561 static HRESULT WINAPI ITypeLib2_fnGetAllCustData( ITypeLib * iface,
1562 CUSTDATA *pCustData)
1564 ICOM_THIS( TLBLibInfo, iface);
1565 TLBCustData *pCData;
1566 int i;
1567 TRACE( typelib,"(%p) returning %d items\n", This, This->ctCustData);
1568 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
1569 if(pCustData->prgCustData ){
1570 pCustData->cCustData=This->ctCustData;
1571 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
1572 pCustData->prgCustData[i].guid=pCData->guid;
1573 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
1575 }else{
1576 ERR( typelib," OUT OF MEMORY! \n");
1577 return E_OUTOFMEMORY;
1579 return S_OK;
1583 /*================== ITypeInfo(2) Methods ===================================*/
1585 /* ITypeInfo::QueryInterface
1587 static HRESULT WINAPI ITypeInfo_fnQueryInterface( LPTYPEINFO iface, REFIID riid,
1588 VOID **ppvObject)
1590 ICOM_THIS( TLBTypeInfo, iface);
1591 if(TRACE_ON(typelib)){
1592 char xriid[50];
1593 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1594 TRACE(typelib,"(%p)->(IID: %s)\n",This,xriid);
1596 *ppvObject=NULL;
1597 if(IsEqualIID(riid, &IID_IUnknown) ||
1598 IsEqualIID(riid,&IID_ITypeInfo)||
1599 IsEqualIID(riid,&IID_ITypeInfo2))
1600 *ppvObject = This;
1601 if(*ppvObject){
1602 (*(LPTYPEINFO*)ppvObject)->lpvtbl->fnAddRef(iface);
1603 TRACE(typelib,"-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1604 return S_OK;
1606 TRACE(typelib,"-- Interface: E_NOINTERFACE\n");
1607 return E_NOINTERFACE;
1610 /* ITypeInfo::AddRef
1612 static ULONG WINAPI ITypeInfo_fnAddRef( LPTYPEINFO iface)
1614 ICOM_THIS( TLBTypeInfo, iface);
1615 TRACE(typelib,"(%p)->ref is %u\n",This, This->ref);
1616 (This->pTypeLib->ref)++;
1617 return ++(This->ref);
1620 /* ITypeInfo::Release
1622 static ULONG WINAPI ITypeInfo_fnRelease( LPTYPEINFO iface)
1624 ICOM_THIS( TLBTypeInfo, iface);
1625 FIXME(typelib,"(%p)->ref is %u: stub\n",This, This->ref);
1626 (This->ref)--;
1627 (This->pTypeLib->ref)--;
1628 return S_OK;
1631 /* ITypeInfo::GetTypeAttr
1633 * Retrieves a TYPEATTR structure that contains the attributes of the type
1634 * description.
1637 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( LPTYPEINFO iface,
1638 LPTYPEATTR *ppTypeAttr)
1640 ICOM_THIS( TLBTypeInfo, iface);
1641 TRACE( typelib,"(%p)\n",This);
1642 /* FIXME: must do a copy here */
1643 *ppTypeAttr=&This->TypeAttr;
1644 return S_OK;
1647 /* ITypeInfo::GetTypeComp
1649 * Retrieves the ITypeComp interface for the type description, which enables a
1650 * client compiler to bind to the type description's members.
1653 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( LPTYPEINFO iface,
1654 ITypeComp * *ppTComp)
1656 ICOM_THIS( TLBTypeInfo, iface);
1657 FIXME( typelib,"(%p) stub!\n", This);
1658 return S_OK;
1661 /* ITypeInfo::GetFuncDesc
1663 * Retrieves the FUNCDESC structure that contains information about a
1664 * specified function.
1667 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( LPTYPEINFO iface, UINT index,
1668 LPFUNCDESC *ppFuncDesc)
1670 ICOM_THIS( TLBTypeInfo, iface);
1671 int i;
1672 TLBFuncDesc * pFDesc;
1673 TRACE( typelib,"(%p) index %d\n", This, index);
1674 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
1676 if(pFDesc){
1677 /* FIXME: must do a copy here */
1678 *ppFuncDesc=&pFDesc->funcdesc;
1679 return S_OK;
1681 return E_INVALIDARG;
1684 /* ITypeInfo::GetVarDesc
1686 * Retrieves a VARDESC structure that describes the specified variable.
1689 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( LPTYPEINFO iface, UINT index,
1690 LPVARDESC *ppVarDesc)
1692 ICOM_THIS( TLBTypeInfo, iface);
1693 int i;
1694 TLBVarDesc * pVDesc;
1695 TRACE( typelib,"(%p) index %d\n", This, index);
1696 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next)
1698 if(pVDesc){
1699 /* FIXME: must do a copy here */
1700 *ppVarDesc=&pVDesc->vardesc;
1701 return S_OK;
1703 return E_INVALIDARG;
1706 /* ITypeInfo_GetNames
1708 * Retrieves the variable with the specified member ID (or the name of the
1709 * property or method and its parameters) that correspond to the specified
1710 * function ID.
1712 static HRESULT WINAPI ITypeInfo_fnGetNames( LPTYPEINFO iface, MEMBERID memid,
1713 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
1715 ICOM_THIS( TLBTypeInfo, iface);
1716 TLBFuncDesc * pFDesc;
1717 TLBVarDesc * pVDesc;
1718 int i;
1719 TRACE( typelib,"(%p) memid=0x%08lx Maxname=%d\n", This, memid,
1720 cMaxNames);
1721 for(pFDesc=This->funclist; pFDesc->funcdesc.memid != memid && pFDesc;
1722 pFDesc=pFDesc->next)
1724 if(pFDesc){
1725 /* function found, now return function and parameter names */
1726 for(i=0; i<cMaxNames && i <= pFDesc->funcdesc.cParams; i++){
1727 if(!i) *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
1728 else
1729 rgBstrNames[i]=TLB_DupAtoBstr(pFDesc->pParamDesc[i-1].Name);
1732 *pcNames=i;
1733 }else{
1734 for(pVDesc=This->varlist; pVDesc->vardesc.memid != memid && pVDesc;
1735 pVDesc=pVDesc->next)
1737 if(pVDesc){
1738 *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
1739 *pcNames=1;
1740 }else{
1741 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
1742 This->TypeAttr.cImplTypes ){
1743 /* recursive search */
1744 ITypeInfo *pTInfo;
1745 HRESULT result;
1746 result=This->lpvtbl->fnGetRefTypeInfo(iface,
1747 This->impltypelist->reference, &pTInfo);
1748 if(SUCCEEDED(result)){
1749 result=pTInfo->lpvtbl->fnGetNames(pTInfo, memid, rgBstrNames,
1750 cMaxNames, pcNames);
1751 pTInfo->lpvtbl->fnRelease(pTInfo);
1752 return result;
1754 WARN( typelib,"Could not search inherited interface!\n");
1755 } else
1756 WARN( typelib,"no names found\n");
1757 *pcNames=0;
1758 return TYPE_E_ELEMENTNOTFOUND;
1761 return S_OK;
1765 /* ITypeInfo::GetRefTypeOfImplType
1767 * If a type description describes a COM class, it retrieves the type
1768 * description of the implemented interface types. For an interface,
1769 * GetRefTypeOfImplType returns the type information for inherited interfaces,
1770 * if any exist.
1773 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO iface,
1774 UINT index, HREFTYPE *pRefType)
1776 ICOM_THIS( TLBTypeInfo, iface);
1777 int(i);
1778 TLBRefType *pIref;
1779 TRACE( typelib,"(%p) index %d\n", This, index);
1780 for(i=0, pIref=This->impltypelist; i<index && pIref;
1781 i++, pIref=pIref->next)
1783 if(i==index){
1784 *pRefType=pIref->reference;
1785 return S_OK;
1787 return TYPE_E_ELEMENTNOTFOUND;
1790 /* ITypeInfo::GetImplTypeFlags
1792 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
1793 * or base interface in a type description.
1795 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO iface,
1796 UINT index, INT *pImplTypeFlags)
1798 ICOM_THIS( TLBTypeInfo, iface);
1799 int(i);
1800 TLBRefType *pIref;
1801 TRACE( typelib,"(%p) index %d\n", This, index);
1802 for(i=0, pIref=This->impltypelist; i<index && pIref; i++, pIref=pIref->next)
1804 if(i==index && pIref){
1805 *pImplTypeFlags=pIref->flags;
1806 return S_OK;
1808 *pImplTypeFlags=0;
1809 return TYPE_E_ELEMENTNOTFOUND;
1812 /* GetIDsOfNames
1813 * Maps between member names and member IDs, and parameter names and
1814 * parameter IDs.
1816 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( LPTYPEINFO iface,
1817 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
1819 ICOM_THIS( TLBTypeInfo, iface);
1820 TLBFuncDesc * pFDesc;
1821 TLBVarDesc * pVDesc;
1822 HRESULT ret=S_OK;
1823 PCHAR aszName= HEAP_strdupWtoA( GetProcessHeap(), 0, *rgszNames);
1824 TRACE( typelib,"(%p) Name %s cNames %d\n", This, debugstr_a(aszName),
1825 cNames);
1826 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) {
1827 int i, j;
1828 if( !strcmp(aszName, pFDesc->Name)) {
1829 if(cNames) *pMemId=pFDesc->funcdesc.memid;
1830 for(i=1; i < cNames; i++){
1831 PCHAR aszPar= HEAP_strdupWtoA( GetProcessHeap(), 0,
1832 rgszNames[i]);
1833 for(j=0; j<pFDesc->funcdesc.cParams; j++)
1834 if(strcmp(aszPar,pFDesc->pParamDesc[j].Name))
1835 break;
1836 if( j<pFDesc->funcdesc.cParams)
1837 pMemId[i]=j;
1838 else
1839 ret=DISP_E_UNKNOWNNAME;
1840 HeapFree( GetProcessHeap(), 0, aszPar);
1842 HeapFree (GetProcessHeap(), 0, aszName);
1843 return ret;
1846 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
1847 if( !strcmp(aszName, pVDesc->Name)) {
1848 if(cNames) *pMemId=pVDesc->vardesc.memid;
1849 HeapFree (GetProcessHeap(), 0, aszName);
1850 return ret;
1853 /* not found, see if this is and interface with an inheritance */
1854 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
1855 This->TypeAttr.cImplTypes ){
1856 /* recursive search */
1857 ITypeInfo *pTInfo;
1858 ret=This->lpvtbl->fnGetRefTypeInfo(iface,
1859 This->impltypelist->reference, &pTInfo);
1860 if(SUCCEEDED(ret)){
1861 ret=pTInfo->lpvtbl->fnGetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
1862 pTInfo->lpvtbl->fnRelease(pTInfo);
1863 return ret;
1865 WARN( typelib,"Could not search inherited interface!\n");
1866 } else
1867 WARN( typelib,"no names found\n");
1868 return DISP_E_UNKNOWNNAME;
1871 /* ITypeInfo::Invoke
1873 * Invokes a method, or accesses a property of an object, that implements the
1874 * interface described by the type description.
1876 static HRESULT WINAPI ITypeInfo_fnInvoke( LPTYPEINFO iface, VOID *pIUnk,
1877 MEMBERID memid, UINT16 dwFlags, DISPPARAMS *pDispParams,
1878 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *pArgErr)
1880 ICOM_THIS( TLBTypeInfo, iface);
1881 FIXME( typelib,"(%p) stub!", This);
1882 return S_OK;
1885 /* ITypeInfo::GetDocumentation
1887 * Retrieves the documentation string, the complete Help file name and path,
1888 * and the context ID for the Help topic for a specified type description.
1890 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( LPTYPEINFO iface,
1891 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
1892 DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
1894 ICOM_THIS( TLBTypeInfo, iface);
1895 TLBFuncDesc * pFDesc;
1896 TLBVarDesc * pVDesc;
1897 TRACE( typelib, "(%p) memid %ld Name(%p) DocString(%p)"
1898 " HelpContext(%p) HelpFile(%p)\n",
1899 This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1900 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
1901 if(pBstrName)
1902 *pBstrName=TLB_DupAtoBstr(This->Name);
1903 if(pBstrDocString)
1904 *pBstrDocString=TLB_DupAtoBstr(This->DocString);
1905 if(pdwHelpContext)
1906 *pdwHelpContext=This->dwHelpContext;
1907 if(pBstrHelpFile)
1908 *pBstrHelpFile=TLB_DupAtoBstr(This->DocString);/* FIXME */
1909 return S_OK;
1910 }else {/* for a member */
1911 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
1912 if(pFDesc->funcdesc.memid==memid){
1913 return S_OK;
1915 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
1916 if(pVDesc->vardesc.memid==memid){
1917 return S_OK;
1920 return TYPE_E_ELEMENTNOTFOUND;
1923 /* ITypeInfo::GetDllEntry
1925 * Retrieves a description or specification of an entry point for a function
1926 * in a DLL.
1928 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( LPTYPEINFO iface, MEMBERID memid,
1929 INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
1930 WORD *pwOrdinal)
1932 ICOM_THIS( TLBTypeInfo, iface);
1933 FIXME( typelib,"(%p) stub!\n", This);
1934 return E_FAIL;
1937 /* ITypeInfo::GetRefTypeInfo
1939 * If a type description references other type descriptions, it retrieves
1940 * the referenced type descriptions.
1942 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO iface,
1943 HREFTYPE hRefType, ITypeInfo * *ppTInfo)
1945 ICOM_THIS( TLBTypeInfo, iface);
1946 HRESULT result;
1947 if(HREFTYPE_INTHISFILE(hRefType)){
1948 ITypeLib *pTLib;
1949 int Index;
1950 result=This->lpvtbl->fnGetContainingTypeLib(iface, &pTLib,
1951 &Index);
1952 if(SUCCEEDED(result)){
1953 result=pTLib->lpvtbl->fnGetTypeInfo(pTLib,
1954 HREFTYPE_INDEX(hRefType),
1955 ppTInfo);
1956 pTLib->lpvtbl->fnRelease(pTLib );
1958 } else{
1959 /* imported type lib */
1960 TLBRefType * pRefType;
1961 TLBLibInfo *pTypeLib;
1962 for( pRefType=This->impltypelist; pRefType &&
1963 pRefType->reference != hRefType; pRefType=pRefType->next)
1965 if(!pRefType)
1966 return TYPE_E_ELEMENTNOTFOUND; /* FIXME : correct? */
1967 pTypeLib=pRefType->pImpTLInfo->pImpTypeLib;
1968 if(pTypeLib) /* typelib already loaded */
1969 result=pTypeLib->lpvtbl->fnGetTypeInfoOfGuid(
1970 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
1971 else{
1972 result=LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
1973 0,0,0, /* FIXME */
1974 (LPTYPELIB *)&pTypeLib);
1975 if(!SUCCEEDED(result)){
1976 BSTR libnam=TLB_DupAtoBstr(pRefType->pImpTLInfo->name);
1977 result=LoadTypeLib(libnam, (LPTYPELIB *)&pTypeLib);
1978 SysFreeString(libnam);
1980 if(SUCCEEDED(result)){
1981 result=pTypeLib->lpvtbl->fnGetTypeInfoOfGuid(
1982 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
1983 pRefType->pImpTLInfo->pImpTypeLib=pTypeLib;
1987 TRACE( typelib,"(%p) hreftype 0x%04lx loaded %s (%p)\n", This, hRefType,
1988 SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
1989 return result;
1992 /* ITypeInfo::AddressOfMember
1994 * Retrieves the addresses of static functions or variables, such as those
1995 * defined in a DLL.
1997 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( LPTYPEINFO iface,
1998 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
2000 ICOM_THIS( TLBTypeInfo, iface);
2001 FIXME( typelib,"(%p) stub!\n", This);
2002 return S_OK;
2005 /* ITypeInfo::CreateInstance
2007 * Creates a new instance of a type that describes a component object class
2008 * (coclass).
2010 static HRESULT WINAPI ITypeInfo_fnCreateInstance( LPTYPEINFO iface,
2011 IUnknown *pUnk, REFIID riid, VOID **ppvObj)
2013 ICOM_THIS( TLBTypeInfo, iface);
2014 FIXME( typelib,"(%p) stub!\n", This);
2015 return S_OK;
2018 /* ITypeInfo::GetMops
2020 * Retrieves marshaling information.
2022 static HRESULT WINAPI ITypeInfo_fnGetMops( LPTYPEINFO iface, MEMBERID memid,
2023 BSTR *pBstrMops)
2025 ICOM_THIS( TLBTypeInfo, iface);
2026 FIXME( typelib,"(%p) stub!\n", This);
2027 return S_OK;
2030 /* ITypeInfo::GetContainingTypeLib
2032 * Retrieves the containing type library and the index of the type description
2033 * within that type library.
2035 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( LPTYPEINFO iface,
2036 ITypeLib * *ppTLib, UINT *pIndex)
2038 ICOM_THIS( TLBTypeInfo, iface);
2039 *ppTLib=(LPTYPELIB )(This->pTypeLib);
2040 *pIndex=This->index;
2041 (*ppTLib)->lpvtbl->fnAddRef(*ppTLib);
2042 TRACE( typelib,"(%p) returns (%p) index %d!\n", This, *ppTLib, *pIndex);
2043 return S_OK;
2046 /* ITypeInfo::ReleaseTypeAttr
2048 * Releases a TYPEATTR previously returned by GetTypeAttr.
2051 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO iface,
2052 TYPEATTR* pTypeAttr)
2054 ICOM_THIS( TLBTypeInfo, iface);
2055 TRACE( typelib,"(%p)->(%p)\n", This, pTypeAttr);
2056 return S_OK;
2059 /* ITypeInfo::ReleaseFuncDesc
2061 * Releases a FUNCDESC previously returned by GetFuncDesc. *
2063 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO iface,
2064 FUNCDESC *pFuncDesc)
2066 ICOM_THIS( TLBTypeInfo, iface);
2067 TRACE( typelib,"(%p)->(%p)\n", This, pFuncDesc);
2068 return S_OK;
2071 /* ITypeInfo::ReleaseVarDesc
2073 * Releases a VARDESC previously returned by GetVarDesc.
2075 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( LPTYPEINFO iface,
2076 VARDESC *pVarDesc)
2078 ICOM_THIS( TLBTypeInfo, iface);
2079 TRACE( typelib,"(%p)->(%p)\n", This, pVarDesc);
2080 return S_OK;
2083 /* ITypeInfo2::GetTypeKind
2085 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
2088 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo * iface,
2089 TYPEKIND *pTypeKind)
2091 ICOM_THIS( TLBTypeInfo, iface);
2092 *pTypeKind=This->TypeAttr.typekind;
2093 TRACE( typelib,"(%p) type 0x%0x\n", This,*pTypeKind);
2094 return S_OK;
2097 /* ITypeInfo2::GetTypeFlags
2099 * Returns the type flags without any allocations. This returns a DWORD type
2100 * flag, which expands the type flags without growing the TYPEATTR (type
2101 * attribute).
2104 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo * iface,
2105 UINT *pTypeFlags)
2107 ICOM_THIS( TLBTypeInfo, iface);
2108 *pTypeFlags=This->TypeAttr.wTypeFlags;
2109 TRACE( typelib,"(%p) flags 0x%04x\n", This,*pTypeFlags);
2110 return S_OK;
2113 /* ITypeInfo2::GetFuncIndexOfMemId
2114 * Binds to a specific member based on a known DISPID, where the member name
2115 * is not known (for example, when binding to a default member).
2118 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo * iface,
2119 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
2121 ICOM_THIS( TLBTypeInfo, iface);
2122 TLBFuncDesc *pFuncInfo;
2123 int i;
2124 HRESULT result;
2125 /* FIXME: should check for invKind??? */
2126 for(i=0, pFuncInfo=This->funclist;pFuncInfo &&
2127 memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next);
2128 if(pFuncInfo){
2129 *pFuncIndex=i;
2130 result= S_OK;
2131 }else{
2132 *pFuncIndex=0;
2133 result=E_INVALIDARG;
2135 TRACE( typelib,"(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This,
2136 memid, invKind, SUCCEEDED(result)? "SUCCES":"FAILED");
2137 return result;
2140 /* TypeInfo2::GetVarIndexOfMemId
2142 * Binds to a specific member based on a known DISPID, where the member name
2143 * is not known (for example, when binding to a default member).
2146 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo * iface,
2147 MEMBERID memid, UINT *pVarIndex)
2149 ICOM_THIS( TLBTypeInfo, iface);
2150 TLBVarDesc *pVarInfo;
2151 int i;
2152 HRESULT result;
2153 for(i=0, pVarInfo=This->varlist; pVarInfo &&
2154 memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next)
2156 if(pVarInfo){
2157 *pVarIndex=i;
2158 result= S_OK;
2159 }else{
2160 *pVarIndex=0;
2161 result=E_INVALIDARG;
2163 TRACE( typelib,"(%p) memid 0x%08lx -> %s\n", This,
2164 memid, SUCCEEDED(result)? "SUCCES":"FAILED");
2165 return result;
2168 /* ITypeInfo2::GetCustData
2170 * Gets the custom data
2172 static HRESULT WINAPI ITypeInfo2_fnGetCustData( ITypeInfo * iface,
2173 REFGUID guid, VARIANT *pVarVal)
2175 ICOM_THIS( TLBTypeInfo, iface);
2176 TLBCustData *pCData;
2177 for(pCData=This->pCustData; pCData; pCData = pCData->next)
2178 if( IsEqualIID(guid, &pCData->guid)) break;
2179 if(TRACE_ON(typelib)){
2180 char xriid[50];
2181 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2182 TRACE(typelib,"(%p) guid %s %s found!x)\n", This, xriid,
2183 pCData? "" : "NOT");
2185 if(pCData){
2186 VariantInit( pVarVal);
2187 VariantCopy( pVarVal, &pCData->data);
2188 return S_OK;
2190 return E_INVALIDARG; /* FIXME: correct? */
2193 /* ITypeInfo2::GetFuncCustData
2195 * Gets the custom data
2197 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( ITypeInfo * iface,
2198 UINT index, REFGUID guid, VARIANT *pVarVal)
2200 ICOM_THIS( TLBTypeInfo, iface);
2201 TLBCustData *pCData=NULL;
2202 TLBFuncDesc * pFDesc;
2203 int i;
2204 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2205 pFDesc=pFDesc->next)
2207 if(pFDesc)
2208 for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next)
2209 if( IsEqualIID(guid, &pCData->guid)) break;
2210 if(TRACE_ON(typelib)){
2211 char xriid[50];
2212 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2213 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
2214 pCData? "" : "NOT");
2216 if(pCData){
2217 VariantInit( pVarVal);
2218 VariantCopy( pVarVal, &pCData->data);
2219 return S_OK;
2221 return E_INVALIDARG; /* FIXME: correct? */
2224 /* ITypeInfo2::GetParamCustData
2226 * Gets the custom data
2228 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( ITypeInfo * iface,
2229 UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal)
2231 ICOM_THIS( TLBTypeInfo, iface);
2232 TLBCustData *pCData=NULL;
2233 TLBFuncDesc * pFDesc;
2234 int i;
2235 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
2236 pFDesc=pFDesc->next)
2238 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams)
2239 for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData;
2240 pCData = pCData->next)
2241 if( IsEqualIID(guid, &pCData->guid)) break;
2242 if(TRACE_ON(typelib)){
2243 char xriid[50];
2244 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2245 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
2246 pCData? "" : "NOT");
2248 if(pCData){
2249 VariantInit( pVarVal);
2250 VariantCopy( pVarVal, &pCData->data);
2251 return S_OK;
2253 return E_INVALIDARG; /* FIXME: correct? */
2256 /* ITypeInfo2::GetVarcCustData
2258 * Gets the custom data
2260 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( ITypeInfo * iface,
2261 UINT index, REFGUID guid, VARIANT *pVarVal)
2263 ICOM_THIS( TLBTypeInfo, iface);
2264 TLBCustData *pCData=NULL;
2265 TLBVarDesc * pVDesc;
2266 int i;
2267 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2268 pVDesc=pVDesc->next)
2270 if(pVDesc)
2271 for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next)
2272 if( IsEqualIID(guid, &pCData->guid)) break;
2273 if(TRACE_ON(typelib)){
2274 char xriid[50];
2275 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2276 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
2277 pCData? "" : "NOT");
2279 if(pCData){
2280 VariantInit( pVarVal);
2281 VariantCopy( pVarVal, &pCData->data);
2282 return S_OK;
2284 return E_INVALIDARG; /* FIXME: correct? */
2287 /* ITypeInfo2::GetImplcCustData
2289 * Gets the custom data
2291 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( ITypeInfo * iface,
2292 UINT index, REFGUID guid, VARIANT *pVarVal)
2294 ICOM_THIS( TLBTypeInfo, iface);
2295 TLBCustData *pCData=NULL;
2296 TLBRefType * pRDesc;
2297 int i;
2298 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2299 pRDesc=pRDesc->next)
2301 if(pRDesc)
2302 for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next)
2303 if( IsEqualIID(guid, &pCData->guid)) break;
2304 if(TRACE_ON(typelib)){
2305 char xriid[50];
2306 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2307 TRACE(typelib,"(%p) guid %s %s found!x)\n",This,xriid,
2308 pCData? "" : "NOT");
2310 if(pCData){
2311 VariantInit( pVarVal);
2312 VariantCopy( pVarVal, &pCData->data);
2313 return S_OK;
2315 return E_INVALIDARG; /* FIXME: correct? */
2318 /* ITypeInfo2::GetDocumentation2
2320 * Retrieves the documentation string, the complete Help file name and path,
2321 * the localization context to use, and the context ID for the library Help
2322 * topic in the Help file.
2325 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( ITypeInfo * iface,
2326 MEMBERID memid, LCID lcid, BSTR *pbstrHelpString,
2327 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
2329 ICOM_THIS( TLBTypeInfo, iface);
2330 TLBFuncDesc * pFDesc;
2331 TLBVarDesc * pVDesc;
2332 TRACE( typelib, "(%p) memid %ld lcid(0x%lx) HelpString(%p) "
2333 "HelpStringContext(%p) HelpStringDll(%p)\n",
2334 This, memid, lcid, pbstrHelpString, pdwHelpStringContext,
2335 pbstrHelpStringDll );
2336 /* the help string should be obtained from the helpstringdll,
2337 * using the _DLLGetDocumentation function, based on the supplied
2338 * lcid. Nice to do sometime...
2340 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
2341 if(pbstrHelpString)
2342 *pbstrHelpString=TLB_DupAtoBstr(This->Name);
2343 if(pdwHelpStringContext)
2344 *pdwHelpStringContext=This->dwHelpStringContext;
2345 if(pbstrHelpStringDll)
2346 *pbstrHelpStringDll=
2347 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2348 return S_OK;
2349 }else {/* for a member */
2350 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
2351 if(pFDesc->funcdesc.memid==memid){
2352 if(pbstrHelpString)
2353 *pbstrHelpString=TLB_DupAtoBstr(pFDesc->HelpString);
2354 if(pdwHelpStringContext)
2355 *pdwHelpStringContext=pFDesc->HelpStringContext;
2356 if(pbstrHelpStringDll)
2357 *pbstrHelpStringDll=
2358 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2359 return S_OK;
2361 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
2362 if(pVDesc->vardesc.memid==memid){
2363 if(pbstrHelpString)
2364 *pbstrHelpString=TLB_DupAtoBstr(pVDesc->HelpString);
2365 if(pdwHelpStringContext)
2366 *pdwHelpStringContext=pVDesc->HelpStringContext;
2367 if(pbstrHelpStringDll)
2368 *pbstrHelpStringDll=
2369 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2370 return S_OK;
2373 return TYPE_E_ELEMENTNOTFOUND;
2376 /* ITypeInfo2::GetAllCustData
2378 * Gets all custom data items for the Type info.
2381 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( ITypeInfo * iface,
2382 CUSTDATA *pCustData)
2384 ICOM_THIS( TLBTypeInfo, iface);
2385 TLBCustData *pCData;
2386 int i;
2387 TRACE( typelib,"(%p) returning %d items\n", This, This->ctCustData);
2388 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
2389 if(pCustData->prgCustData ){
2390 pCustData->cCustData=This->ctCustData;
2391 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
2392 pCustData->prgCustData[i].guid=pCData->guid;
2393 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
2395 }else{
2396 ERR( typelib," OUT OF MEMORY! \n");
2397 return E_OUTOFMEMORY;
2399 return S_OK;
2402 /* ITypeInfo2::GetAllFuncCustData
2404 * Gets all custom data items for the specified Function
2407 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( ITypeInfo * iface,
2408 UINT index, CUSTDATA *pCustData)
2410 ICOM_THIS( TLBTypeInfo, iface);
2411 TLBCustData *pCData;
2412 TLBFuncDesc * pFDesc;
2413 int i;
2414 TRACE( typelib,"(%p) index %d\n", This, index);
2415 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2416 pFDesc=pFDesc->next)
2418 if(pFDesc){
2419 pCustData->prgCustData =
2420 TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM));
2421 if(pCustData->prgCustData ){
2422 pCustData->cCustData=pFDesc->ctCustData;
2423 for(i=0, pCData=pFDesc->pCustData; pCData; i++,
2424 pCData = pCData->next){
2425 pCustData->prgCustData[i].guid=pCData->guid;
2426 VariantCopy(& pCustData->prgCustData[i].varValue,
2427 & pCData->data);
2429 }else{
2430 ERR( typelib," OUT OF MEMORY! \n");
2431 return E_OUTOFMEMORY;
2433 return S_OK;
2435 return TYPE_E_ELEMENTNOTFOUND;
2438 /* ITypeInfo2::GetAllParamCustData
2440 * Gets all custom data items for the Functions
2443 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo * iface,
2444 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
2446 ICOM_THIS( TLBTypeInfo, iface);
2447 TLBCustData *pCData=NULL;
2448 TLBFuncDesc * pFDesc;
2449 int i;
2450 TRACE( typelib,"(%p) index %d\n", This, indexFunc);
2451 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
2452 pFDesc=pFDesc->next)
2454 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams){
2455 pCustData->prgCustData =
2456 TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData *
2457 sizeof(CUSTDATAITEM));
2458 if(pCustData->prgCustData ){
2459 pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData;
2460 for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData;
2461 pCData; i++, pCData = pCData->next){
2462 pCustData->prgCustData[i].guid=pCData->guid;
2463 VariantCopy(& pCustData->prgCustData[i].varValue,
2464 & pCData->data);
2466 }else{
2467 ERR( typelib," OUT OF MEMORY! \n");
2468 return E_OUTOFMEMORY;
2470 return S_OK;
2472 return TYPE_E_ELEMENTNOTFOUND;
2475 /* ITypeInfo2::GetAllVarCustData
2477 * Gets all custom data items for the specified Variable
2480 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo * iface,
2481 UINT index, CUSTDATA *pCustData)
2483 ICOM_THIS( TLBTypeInfo, iface);
2484 TLBCustData *pCData;
2485 TLBVarDesc * pVDesc;
2486 int i;
2487 TRACE( typelib,"(%p) index %d\n", This, index);
2488 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2489 pVDesc=pVDesc->next)
2491 if(pVDesc){
2492 pCustData->prgCustData =
2493 TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM));
2494 if(pCustData->prgCustData ){
2495 pCustData->cCustData=pVDesc->ctCustData;
2496 for(i=0, pCData=pVDesc->pCustData; pCData; i++,
2497 pCData = pCData->next){
2498 pCustData->prgCustData[i].guid=pCData->guid;
2499 VariantCopy(& pCustData->prgCustData[i].varValue,
2500 & pCData->data);
2502 }else{
2503 ERR( typelib," OUT OF MEMORY! \n");
2504 return E_OUTOFMEMORY;
2506 return S_OK;
2508 return TYPE_E_ELEMENTNOTFOUND;
2511 /* ITypeInfo2::GetAllImplCustData
2513 * Gets all custom data items for the specified implementation type
2516 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo * iface,
2517 UINT index, CUSTDATA *pCustData)
2519 ICOM_THIS( TLBTypeInfo, iface);
2520 TLBCustData *pCData;
2521 TLBRefType * pRDesc;
2522 int i;
2523 TRACE( typelib,"(%p) index %d\n", This, index);
2524 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2525 pRDesc=pRDesc->next)
2527 if(pRDesc){
2528 pCustData->prgCustData =
2529 TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM));
2530 if(pCustData->prgCustData ){
2531 pCustData->cCustData=pRDesc->ctCustData;
2532 for(i=0, pCData=pRDesc->pCustData; pCData; i++,
2533 pCData = pCData->next){
2534 pCustData->prgCustData[i].guid=pCData->guid;
2535 VariantCopy(& pCustData->prgCustData[i].varValue,
2536 & pCData->data);
2538 }else{
2539 ERR( typelib," OUT OF MEMORY! \n");
2540 return E_OUTOFMEMORY;
2542 return S_OK;
2544 return TYPE_E_ELEMENTNOTFOUND;