- Implement interprocess clipboard communication.
[wine.git] / ole / typelib.c
blob107a9f88c5782ebf8adcd5c22222fc4cd831650f
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 "winerror.h"
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) */
34 #include "heap.h"
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 ;
41 #include "typelib.h"
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\"
50 * RETURNS
51 * path of typelib
53 HRESULT WINAPI
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 */
60 ) {
61 char xguid[80];
62 char typelibkey[100],pathname[260];
63 DWORD plen;
65 if (HIWORD(guid)) {
66 WINE_StringFromCLSID(guid,xguid);
67 sprintf(typelibkey,"SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%lx\\win16",
68 xguid,wMaj,wMin,lcid
70 } else {
71 sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
72 FIXME_(ole)("(%s,%d,%d,0x%04lx,%p),can't handle non-string guids.\n",xguid,wMaj,wMin,(DWORD)lcid,path);
73 return E_FAIL;
75 plen = sizeof(pathname);
76 if (RegQueryValue16(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
77 /* try again without lang specific id */
78 if (SUBLANGID(lcid))
79 return QueryPathOfRegTypeLib16(guid,wMaj,wMin,PRIMARYLANGID(lcid),path);
80 FIXME_(ole)("key %s not found\n",typelibkey);
81 return E_FAIL;
83 *path = SysAllocString16(pathname);
84 return S_OK;
87 /****************************************************************************
88 * QueryPathOfRegTypeLib [OLEAUT32.164]
89 * RETURNS
90 * path of typelib
92 HRESULT WINAPI
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 */
99 ) {
100 char xguid[80];
101 char typelibkey[100],pathname[260];
102 DWORD plen;
105 if (HIWORD(guid)) {
106 WINE_StringFromCLSID(guid,xguid);
107 sprintf(typelibkey,"SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%lx\\win32",
108 xguid,wMaj,wMin,lcid
110 } else {
111 sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
112 FIXME_(ole)("(%s,%d,%d,0x%04lx,%p),stub!\n",xguid,wMaj,wMin,(DWORD)lcid,path);
113 return E_FAIL;
115 plen = sizeof(pathname);
116 if (RegQueryValue16(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
117 /* try again without lang specific id */
118 if (SUBLANGID(lcid))
119 return QueryPathOfRegTypeLib(guid,wMaj,wMin,PRIMARYLANGID(lcid),path);
120 FIXME_(ole)("key %s not found\n",typelibkey);
121 return E_FAIL;
123 *path = HEAP_strdupAtoW(GetProcessHeap(),0,pathname);
124 return S_OK;
127 /******************************************************************************
128 * LoadTypeLib [TYPELIB.3] Loads and registers a type library
129 * NOTES
130 * Docs: OLECHAR FAR* szFile
131 * Docs: iTypeLib FAR* FAR* pptLib
133 * RETURNS
134 * Success: S_OK
135 * Failure: Status
137 HRESULT WINAPI LoadTypeLib16(
138 OLECHAR *szFile, /* [in] Name of file to load from */
139 void * *pptLib) /* [out] Pointer to pointer to loaded type library */
141 FIXME_(ole)("('%s',%p): stub\n",debugstr_w((LPWSTR)szFile),pptLib);
143 if (pptLib!=0)
144 *pptLib=0;
146 return E_FAIL;
149 /******************************************************************************
150 * LoadTypeLib [OLEAUT32.161]
151 * Loads and registers a type library
152 * NOTES
153 * Docs: OLECHAR FAR* szFile
154 * Docs: iTypeLib FAR* FAR* pptLib
156 * RETURNS
157 * Success: S_OK
158 * Failure: Status
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 LPSTR p;
166 HRESULT res;
167 TRACE_(typelib)("('%s',%p)\n",debugstr_w(szFile),pptLib);
169 p=HEAP_strdupWtoA(GetProcessHeap(),0,szFile);
170 res= TLB_ReadTypeLib(p, pptLib);
171 /* XXX need to free p ?? */
173 TRACE_(typelib)(" returns %ld\n",res);
175 return res;
178 /******************************************************************************
179 * LoadRegTypeLib [OLEAUT32.162]
181 HRESULT WINAPI LoadRegTypeLib(
182 REFGUID rguid, /* [in] referenced guid */
183 WORD wVerMajor, /* [in] major version */
184 WORD wVerMinor, /* [in] minor version */
185 LCID lcid, /* [in] locale id */
186 ITypeLib **ppTLib /* [out] path of typelib */
188 BSTR bstr=NULL;
189 HRESULT res=QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor,
190 lcid, &bstr);
191 if(SUCCEEDED(res)){
192 res= LoadTypeLib(bstr, ppTLib);
193 SysFreeString(bstr);
195 if(TRACE_ON(typelib)){
196 char xriid[50];
197 WINE_StringFromCLSID((LPCLSID)rguid,xriid);
198 TRACE_(typelib)("(IID: %s) load %s (%p)\n",xriid,
199 SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);
201 return res;
205 /******************************************************************************
206 * RegisterTypeLib [OLEAUT32.163]
207 * Adds information about a type library to the System Registry
208 * NOTES
209 * Docs: ITypeLib FAR * ptlib
210 * Docs: OLECHAR FAR* szFullPath
211 * Docs: OLECHAR FAR* szHelpDir
213 * RETURNS
214 * Success: S_OK
215 * Failure: Status
217 HRESULT WINAPI RegisterTypeLib(
218 ITypeLib * ptlib, /*[in] Pointer to the library*/
219 OLECHAR * szFullPath, /*[in] full Path of the library*/
220 OLECHAR * szHelpDir) /*[in] dir to the helpfile for the library,
221 may be NULL*/
222 { FIXME_(ole)("(%p,%s,%s): stub\n",ptlib, debugstr_w(szFullPath),debugstr_w(szHelpDir));
223 return S_OK; /* FIXME: pretend everything is OK */
227 /******************************************************************************
228 * UnRegisterTypeLib [OLEAUT32.186]
229 * Removes information about a type library from the System Registry
230 * NOTES
232 * RETURNS
233 * Success: S_OK
234 * Failure: Status
236 HRESULT WINAPI UnRegisterTypeLib(
237 REFGUID libid, /* [in] Guid of the library */
238 WORD wVerMajor, /* [in] major version */
239 WORD wVerMinor, /* [in] minor version */
240 LCID lcid, /* [in] locale id */
241 SYSKIND syskind)
243 char xriid[50];
244 WINE_StringFromCLSID((LPCLSID)libid,xriid);
245 TRACE_(typelib)("(IID: %s): stub\n",xriid);
246 return S_OK; /* FIXME: pretend everything is OK */
249 /****************************************************************************
250 * OABuildVersion (TYPELIB.15)
251 * RETURNS
252 * path of typelib
254 DWORD WINAPI OABuildVersion16(void)
256 WINDOWS_VERSION ver = VERSION_GetVersion();
258 switch (ver) {
259 case WIN95:
260 return MAKELONG(0xbd0, 0xa); /* Win95A */
261 case WIN31:
262 return MAKELONG(0xbd3, 0x3); /* WfW 3.11 */
263 default:
264 FIXME_(ole)("Version value not known yet. Please investigate it !");
265 return MAKELONG(0xbd0, 0xa); /* return Win95A for now */
269 /* for better debugging info leave the static out for the time being */
270 #define static
272 /*=======================Itypelib methods ===============================*/
273 /* ITypeLib methods */
274 static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid,
275 VOID **ppvObject);
276 static ULONG WINAPI ITypeLib_fnAddRef( LPTYPELIB This);
277 static ULONG WINAPI ITypeLib_fnRelease( LPTYPELIB This);
278 static UINT WINAPI ITypeLib_fnGetTypeInfoCount( LPTYPELIB This);
279 static HRESULT WINAPI ITypeLib_fnGetTypeInfo( LPTYPELIB This, UINT index,
280 ITypeInfo **ppTInfo);
282 static HRESULT WINAPI ITypeLib_fnGetTypeInfoType( LPTYPELIB This, UINT index,
283 TYPEKIND *pTKind);
285 static HRESULT WINAPI ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB This, REFGUID guid,
286 ITypeInfo **ppTinfo);
288 static HRESULT WINAPI ITypeLib_fnGetLibAttr( LPTYPELIB This,
289 LPTLIBATTR *ppTLibAttr);
291 static HRESULT WINAPI ITypeLib_fnGetTypeComp( LPTYPELIB This,
292 ITypeComp **ppTComp);
294 static HRESULT WINAPI ITypeLib_fnGetDocumentation( LPTYPELIB This, INT index,
295 BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext,
296 BSTR *pBstrHelpFile);
298 static HRESULT WINAPI ITypeLib_fnIsName( LPTYPELIB This, LPOLESTR szNameBuf,
299 ULONG lHashVal, BOOL *pfName);
301 static HRESULT WINAPI ITypeLib_fnFindName( LPTYPELIB This, LPOLESTR szNameBuf,
302 ULONG lHashVal, ITypeInfo **ppTInfo, MEMBERID *rgMemId, UINT16 *pcFound);
304 static VOID WINAPI ITypeLib_fnReleaseTLibAttr( LPTYPELIB This,
305 TLIBATTR *pTLibAttr);
307 static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLib * This, REFGUID guid,
308 VARIANT *pVarVal);
310 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( ITypeLib * This,
311 UINT *pcUniqueNames, UINT *pcchUniqueNames);
313 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( ITypeLib * This,
314 INT index, LCID lcid, BSTR *pbstrHelpString,
315 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll);
317 static HRESULT WINAPI ITypeLib2_fnGetAllCustData( ITypeLib * This,
318 CUSTDATA *pCustData);
319 static ICOM_VTABLE(ITypeLib) tlbvt = {
320 ITypeLib_fnQueryInterface,
321 ITypeLib_fnAddRef,
322 ITypeLib_fnRelease,
323 ITypeLib_fnGetTypeInfoCount,
324 ITypeLib_fnGetTypeInfo,
325 ITypeLib_fnGetTypeInfoType,
326 ITypeLib_fnGetTypeInfoOfGuid,
327 ITypeLib_fnGetLibAttr,
328 ITypeLib_fnGetTypeComp,
329 ITypeLib_fnGetDocumentation,
330 ITypeLib_fnIsName,
331 ITypeLib_fnFindName,
332 ITypeLib_fnReleaseTLibAttr,
333 ITypeLib2_fnGetCustData,
334 ITypeLib2_fnGetLibStatistics,
335 ITypeLib2_fnGetDocumentation2,
336 ITypeLib2_fnGetAllCustData
338 /* TypeInfo Methods */
340 static HRESULT WINAPI ITypeInfo_fnQueryInterface( LPTYPEINFO This, REFIID riid,
341 VOID **ppvObject);
342 static ULONG WINAPI ITypeInfo_fnAddRef( LPTYPEINFO This);
343 static ULONG WINAPI ITypeInfo_fnRelease( LPTYPEINFO This);
344 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( LPTYPEINFO This,
345 LPTYPEATTR *ppTypeAttr);
347 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( LPTYPEINFO This,
348 ITypeComp * *ppTComp);
350 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( LPTYPEINFO This, UINT index,
351 LPFUNCDESC *ppFuncDesc);
353 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( LPTYPEINFO This, UINT index,
354 LPVARDESC *ppVarDesc);
356 static HRESULT WINAPI ITypeInfo_fnGetNames( LPTYPEINFO This, MEMBERID memid,
357 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames);
360 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO This,
361 UINT index, HREFTYPE *pRefType);
363 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO This,
364 UINT index, INT *pImplTypeFlags);
366 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( LPTYPEINFO This,
367 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId);
369 static HRESULT WINAPI ITypeInfo_fnInvoke( LPTYPEINFO This, VOID *pIUnk,
370 MEMBERID memid, UINT16 dwFlags, DISPPARAMS *pDispParams,
371 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *pArgErr);
373 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( LPTYPEINFO This,
374 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
375 DWORD *pdwHelpContext, BSTR *pBstrHelpFile);
377 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( LPTYPEINFO This,
378 MEMBERID memid, INVOKEKIND invKind, BSTR *pBstrDllName,
379 BSTR *pBstrName, WORD *pwOrdinal);
381 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO This,
382 HREFTYPE hRefType, ITypeInfo * *ppTInfo);
384 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( LPTYPEINFO This,
385 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv);
387 static HRESULT WINAPI ITypeInfo_fnCreateInstance( LPTYPEINFO This,
388 IUnknown *pUnk, REFIID riid, VOID * *ppvObj);
390 static HRESULT WINAPI ITypeInfo_fnGetMops( LPTYPEINFO This, MEMBERID memid,
391 BSTR *pBstrMops);
394 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( LPTYPEINFO This,
395 ITypeLib * *ppTLib, UINT *pIndex);
397 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO This,
398 TYPEATTR *pTypeAttr);
400 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO This,
401 FUNCDESC *pFuncDesc);
403 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( LPTYPEINFO This,
404 VARDESC *pVarDesc);
405 /* itypeinfo2 methods */
406 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo * This,
407 TYPEKIND *pTypeKind);
408 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo * This,
409 UINT *pTypeFlags);
410 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo * This,
411 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex);
412 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo * This,
413 MEMBERID memid, UINT *pVarIndex);
414 static HRESULT WINAPI ITypeInfo2_fnGetCustData( ITypeInfo * This,
415 REFGUID guid, VARIANT *pVarVal);
416 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( ITypeInfo * This,
417 UINT index, REFGUID guid, VARIANT *pVarVal);
418 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( ITypeInfo * This,
419 UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal);
420 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( ITypeInfo * This,
421 UINT index, REFGUID guid, VARIANT *pVarVal);
422 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( ITypeInfo * This,
423 UINT index, REFGUID guid, VARIANT *pVarVal);
424 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( ITypeInfo * This,
425 MEMBERID memid, LCID lcid, BSTR *pbstrHelpString,
426 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll);
427 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( ITypeInfo * This,
428 CUSTDATA *pCustData);
429 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( ITypeInfo * This,
430 UINT index, CUSTDATA *pCustData);
431 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo * This,
432 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData);
433 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo * This,
434 UINT index, CUSTDATA *pCustData);
435 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo * This,
436 UINT index, CUSTDATA *pCustData);
438 static ICOM_VTABLE(ITypeInfo) tinfvt = {
439 ITypeInfo_fnQueryInterface,
440 ITypeInfo_fnAddRef,
441 ITypeInfo_fnRelease,
442 ITypeInfo_fnGetTypeAttr,
443 ITypeInfo_fnGetTypeComp,
444 ITypeInfo_fnGetFuncDesc,
445 ITypeInfo_fnGetVarDesc,
446 ITypeInfo_fnGetNames,
447 ITypeInfo_fnGetRefTypeOfImplType,
448 ITypeInfo_fnGetImplTypeFlags,
449 ITypeInfo_fnGetIDsOfNames,
450 ITypeInfo_fnInvoke,
451 ITypeInfo_fnGetDocumentation,
452 ITypeInfo_fnGetDllEntry,
453 ITypeInfo_fnGetRefTypeInfo,
454 ITypeInfo_fnAddressOfMember,
455 ITypeInfo_fnCreateInstance,
456 ITypeInfo_fnGetMops,
457 ITypeInfo_fnGetContainingTypeLib,
458 ITypeInfo_fnReleaseTypeAttr,
459 ITypeInfo_fnReleaseFuncDesc,
460 ITypeInfo_fnReleaseVarDesc,
462 ITypeInfo2_fnGetTypeKind,
463 ITypeInfo2_fnGetTypeFlags,
464 ITypeInfo2_fnGetFuncIndexOfMemId,
465 ITypeInfo2_fnGetVarIndexOfMemId,
466 ITypeInfo2_fnGetCustData,
467 ITypeInfo2_fnGetFuncCustData,
468 ITypeInfo2_fnGetParamCustData,
469 ITypeInfo2_fnGetVarCustData,
470 ITypeInfo2_fnGetImplTypeCustData,
471 ITypeInfo2_fnGetDocumentation2,
472 ITypeInfo2_fnGetAllCustData,
473 ITypeInfo2_fnGetAllFuncCustData,
474 ITypeInfo2_fnGetAllParamCustData,
475 ITypeInfo2_fnGetAllVarCustData,
476 ITypeInfo2_fnGetAllImplTypeCustData,
480 static TYPEDESC stndTypeDesc[VT_LPWSTR+1]={/* VT_LPWSTR is largest type that */
481 /* may appear in type description*/
482 {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
483 {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
484 {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
485 {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
486 {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
487 {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
488 {{0},30},{{0},31}};
490 static void TLB_abort()
492 *((int *)0)=0;
494 static void * TLB_Alloc(unsigned size)
496 void * ret;
497 if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){
498 /* FIXME */
499 ERR_(ole)("cannot allocate memory\n");
501 return ret;
504 /* candidate for a more global appearance... */
505 static BSTR TLB_DupAtoBstr(PCHAR Astr)
507 int len;
508 BSTR bstr;
509 DWORD *pdw ;
510 if(!Astr)
511 return NULL;
512 len=strlen(Astr);
513 pdw =TLB_Alloc((len+3)*sizeof(OLECHAR));
514 pdw[0]=(len)*sizeof(OLECHAR);
515 bstr=(BSTR)&( pdw[1]);
516 lstrcpyAtoW( bstr, Astr);
517 TRACE_(typelib)("copying %s to (%p)\n", Astr, bstr);
518 return bstr;
521 static void TLB_Free(void * ptr)
523 HeapFree(GetProcessHeap(), 0, ptr);
525 /* read function */
526 DWORD TLB_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
528 DWORD bytesread=0;
530 if (( where != DO_NOT_SEEK &&
531 (0xffffffff == SetFilePointer( pcx->hFile, where + pcx->oStart,
532 0,FILE_BEGIN))
533 ) ||
534 !ReadFile(pcx->hFile, buffer, count, &bytesread, NULL)
536 /* FIXME */
537 ERR_(typelib)("read error is 0x%lx reading %ld bytes at 0x%lx\n",
538 GetLastError(), count, where);
539 TLB_abort();
540 exit(1);
542 return bytesread;
545 static void TLB_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
547 if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){
548 memset(pGuid,0, sizeof(GUID));
549 return;
551 TLB_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset );
554 PCHAR TLB_ReadName( TLBContext *pcx, int offset)
556 char * name;
557 TLBNameIntro niName;
558 TLB_Read(&niName, sizeof(niName), pcx,
559 pcx->pTblDir->pNametab.offset+offset);
560 niName.namelen &= 0xFF; /* FIXME: correct ? */
561 name=TLB_Alloc((niName.namelen & 0xff) +1);
562 TLB_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK);
563 name[niName.namelen & 0xff]='\0';
564 return name;
566 PCHAR TLB_ReadString( TLBContext *pcx, int offset)
568 char * string;
569 INT16 length;
570 if(offset<0) return NULL;
571 TLB_Read(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
572 if(length <= 0) return 0;
573 string=TLB_Alloc(length +1);
574 TLB_Read(string, length, pcx, DO_NOT_SEEK);
575 string[length]='\0';
576 return string;
579 * read a value and fill a VARIANT structure
581 static void TLB_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
583 int size;
584 if(offset <0) { /* data is packed in here */
585 pVar->vt = (offset & 0x7c000000 )>> 26;
586 V_UNION(pVar, iVal) = offset & 0xffff;
587 return;
589 TLB_Read(&(pVar->vt), sizeof(VARTYPE), pcx,
590 pcx->pTblDir->pCustData.offset + offset );
591 switch(pVar->vt){
592 case VT_EMPTY: /* FIXME: is this right? */
593 case VT_NULL: /* FIXME: is this right? */
594 case VT_I2 : /* this should not happen */
595 case VT_I4 :
596 case VT_R4 :
597 case VT_ERROR :
598 case VT_BOOL :
599 case VT_I1 :
600 case VT_UI1 :
601 case VT_UI2 :
602 case VT_UI4 :
603 case VT_INT :
604 case VT_UINT :
605 case VT_VOID : /* FIXME: is this right? */
606 case VT_HRESULT :
607 size=4; break;
608 case VT_R8 :
609 case VT_CY :
610 case VT_DATE :
611 case VT_I8 :
612 case VT_UI8 :
613 case VT_DECIMAL : /* FIXME: is this right? */
614 case VT_FILETIME :
615 size=8;break;
616 /* pointer types with known behaviour */
617 case VT_BSTR :{
618 char * ptr;
619 TLB_Read(&size, sizeof(INT), pcx, DO_NOT_SEEK );
620 ptr=TLB_Alloc(size);/* allocate temp buffer */
621 TLB_Read(ptr, size, pcx, DO_NOT_SEEK ); /* read string (ANSI) */
622 V_UNION(pVar, bstrVal)=SysAllocStringLen(NULL,size);
623 /* FIXME: do we need a AtoW conversion here? */
624 V_UNION(pVar, bstrVal[size])=L'\0';
625 while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
626 TLB_Free(ptr);
628 size=-4; break;
629 /* FIXME: this will not work AT ALL when the variant contains a pointer */
630 case VT_DISPATCH :
631 case VT_VARIANT :
632 case VT_UNKNOWN :
633 case VT_PTR :
634 case VT_SAFEARRAY :
635 case VT_CARRAY :
636 case VT_USERDEFINED :
637 case VT_LPSTR :
638 case VT_LPWSTR :
639 case VT_BLOB :
640 case VT_STREAM :
641 case VT_STORAGE :
642 case VT_STREAMED_OBJECT :
643 case VT_STORED_OBJECT :
644 case VT_BLOB_OBJECT :
645 case VT_CF :
646 case VT_CLSID :
647 default:
648 size=0;
649 FIXME_(ole)("VARTYPE %d is not supported, setting pointer to NULL\n",
650 pVar->vt);
653 if(size>0) /* (big|small) endian correct? */
654 TLB_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK );
655 return ;
658 * create a linked list with custom data
660 static int TLB_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
662 TLBCDGuid entry;
663 TLBCustData* pNew;
664 int count=0;
665 while(offset >=0){
666 count++;
667 pNew=TLB_Alloc(sizeof(TLBCustData));
668 TLB_Read(&entry, sizeof(entry), pcx,
669 pcx->pTblDir->pCDGuids.offset+offset);
670 TLB_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
671 TLB_ReadValue(&(pNew->data), entry.DataOffset, pcx);
672 /* add new custom data at head of the list */
673 pNew->next=*ppCustData;
674 *ppCustData=pNew;
675 offset = entry.next;
677 return count;
680 static void TLB_GetTdesc(TLBContext *pcx, INT type,TYPEDESC * pTd )
682 if(type <0)
683 pTd->vt=type & VT_TYPEMASK;
684 else
685 *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
687 static void TLB_DoFuncs(TLBContext *pcx, int cFuncs, int cVars,
688 int offset, TLBFuncDesc ** pptfd)
691 * member information is stored in a data structure at offset
692 * indicated by the memoffset field of the typeinfo structure
693 * There are several distinctive parts.
694 * the first part starts with a field that holds the total length
695 * of this (first) part excluding this field. Then follow the records,
696 * for each member there is one record.
698 * First entry is always the length of the record (excluding this
699 * length word).
700 * Rest of the record depends on the type of the member. If there is
701 * a field indicating the member type (function variable intereface etc)
702 * I have not found it yet. At this time we depend on the information
703 * in the type info and the usual order how things are stored.
705 * Second follows an array sized nrMEM*sizeof(INT) with a memeber id
706 * for each member;
708 * Third is a equal sized array with file offsets to the name entry
709 * of each member.
711 * Forth and last (?) part is an array with offsets to the records in the
712 * first part of this file segment.
715 int infolen, nameoffset, reclength, nrattributes;
716 char recbuf[512];
717 TLBFuncRecord * pFuncRec=(TLBFuncRecord *) recbuf;
718 int i, j;
719 int recoffset=offset+sizeof(INT);
720 TLB_Read(&infolen,sizeof(INT), pcx, offset);
721 for(i=0;i<cFuncs;i++){
722 *pptfd=TLB_Alloc(sizeof(TLBFuncDesc));
723 /* name, eventually add to a hash table */
724 TLB_Read(&nameoffset, sizeof(INT), pcx,
725 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
726 (*pptfd)->Name=TLB_ReadName(pcx, nameoffset);
727 /* read the function information record */
728 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
729 reclength &=0x1ff;
730 TLB_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
731 /* do the attributes */
732 nrattributes=(reclength-pFuncRec->nrargs*3*sizeof(int)-0x18)
733 /sizeof(int);
734 if(nrattributes>0){
735 (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
736 if(nrattributes>1){
737 (*pptfd)->HelpString = TLB_ReadString(pcx,
738 pFuncRec->OptAttr[1]) ;
739 if(nrattributes>2){
740 if(pFuncRec->FKCCIC & 0x2000)
741 (*pptfd)->Entry = (char *) pFuncRec->OptAttr[2] ;
742 else
743 (*pptfd)->Entry = TLB_ReadString(pcx,
744 pFuncRec->OptAttr[2]);
745 if(nrattributes>5 )
746 (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;
747 if(nrattributes>6 && pFuncRec->FKCCIC & 0x80){
748 TLB_CustData(pcx, pFuncRec->OptAttr[6],
749 &(*pptfd)->pCustData);
754 /* fill the FuncDesc Structure */
755 TLB_Read(&(*pptfd)->funcdesc.memid, sizeof(INT), pcx,
756 offset + infolen + ( i + 1) * sizeof(INT));
757 (*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
758 (*pptfd)->funcdesc.invkind = ((pFuncRec->FKCCIC) >>3) & 0xF;
759 (*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >>8 & 0xF;
760 (*pptfd)->funcdesc.cParams = pFuncRec->nrargs ;
761 (*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ;
762 (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ;
763 (*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
764 TLB_GetTdesc(pcx, pFuncRec->DataType,
765 &(*pptfd)->funcdesc.elemdescFunc.tdesc) ;
767 /* do the parameters/arguments */
768 if(pFuncRec->nrargs){
769 TLBParameterInfo paraminfo;
770 (*pptfd)->funcdesc.lprgelemdescParam=
771 TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
772 (*pptfd)->pParamDesc=TLB_Alloc(pFuncRec->nrargs *
773 sizeof(TLBParDesc));
775 TLB_Read(&paraminfo,sizeof(paraminfo), pcx, recoffset+reclength -
776 pFuncRec->nrargs * sizeof(TLBParameterInfo));
777 for(j=0;j<pFuncRec->nrargs;j++){
778 TLB_GetTdesc(pcx, paraminfo.DataType,
779 &(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc) ;
780 V_UNION(&((*pptfd)->funcdesc.lprgelemdescParam[j]),
781 paramdesc.wParamFlags) = paraminfo.Flags;
782 (*pptfd)->pParamDesc[j].Name=(void *)paraminfo.oName;
783 TLB_Read(&paraminfo,sizeof(TLBParameterInfo), pcx,
784 DO_NOT_SEEK);
786 /* second time around */
787 for(j=0;j<pFuncRec->nrargs;j++){
788 /* name */
789 (*pptfd)->pParamDesc[j].Name=
790 TLB_ReadName(pcx, (int)(*pptfd)->pParamDesc[j].Name);
791 /* default value */
792 if((PARAMFLAG_FHASDEFAULT & V_UNION(&((*pptfd)->funcdesc.
793 lprgelemdescParam[j]),paramdesc.wParamFlags)) &&
794 ((pFuncRec->FKCCIC) & 0x1000)){
795 INT *pInt=(INT *)((char *)pFuncRec + reclength -
796 (pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
797 PARAMDESC * pParamDesc= &V_UNION(&((*pptfd)->funcdesc.
798 lprgelemdescParam[j]),paramdesc);
799 pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
800 pParamDesc->pparamdescex->cBytes= sizeof(PARAMDESCEX);
801 TLB_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
802 pInt[j], pcx);
804 /* custom info */
805 if(nrattributes>7+j && pFuncRec->FKCCIC & 0x80)
806 TLB_CustData(pcx, pFuncRec->OptAttr[7+j],
807 &(*pptfd)->pParamDesc[j].pCustData);
810 /* scode is not used: archaic win16 stuff FIXME: right? */
811 (*pptfd)->funcdesc.cScodes = 0 ;
812 (*pptfd)->funcdesc.lprgscode = NULL ;
813 pptfd=&((*pptfd)->next);
814 recoffset += reclength;
817 static void TLB_DoVars(TLBContext *pcx, int cFuncs, int cVars,
818 int offset, TLBVarDesc ** pptvd)
820 int infolen, nameoffset, reclength;
821 char recbuf[256];
822 TLBVarRecord * pVarRec=(TLBVarRecord *) recbuf;
823 int i;
824 int recoffset;
825 TLB_Read(&infolen,sizeof(INT), pcx, offset);
826 TLB_Read(&recoffset,sizeof(INT), pcx, offset + infolen +
827 ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
828 recoffset += offset+sizeof(INT);
829 for(i=0;i<cVars;i++){
830 *pptvd=TLB_Alloc(sizeof(TLBVarDesc));
831 /* name, eventually add to a hash table */
832 TLB_Read(&nameoffset, sizeof(INT), pcx,
833 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
834 (*pptvd)->Name=TLB_ReadName(pcx, nameoffset);
835 /* read the variable information record */
836 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
837 reclength &=0xff;
838 TLB_Read(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
839 /* Optional data */
840 if(reclength >(6*sizeof(INT)) )
841 (*pptvd)->HelpContext=pVarRec->HelpContext;
842 if(reclength >(7*sizeof(INT)) )
843 (*pptvd)->HelpString = TLB_ReadString(pcx, pVarRec->oHelpString) ;
844 if(reclength >(8*sizeof(INT)) )
845 if(reclength >(9*sizeof(INT)) )
846 (*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
847 /* fill the VarDesc Structure */
848 TLB_Read(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
849 offset + infolen + ( i + 1) * sizeof(INT));
850 (*pptvd)->vardesc.varkind = pVarRec->VarKind;
851 (*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
852 TLB_GetTdesc(pcx, pVarRec->DataType,
853 &(*pptvd)->vardesc.elemdescVar.tdesc) ;
854 /* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) fixme?? */
855 if(pVarRec->VarKind == VAR_CONST ){
856 V_UNION(&((*pptvd)->vardesc),lpvarValue)=TLB_Alloc(sizeof(VARIANT));
857 TLB_ReadValue(V_UNION(&((*pptvd)->vardesc),lpvarValue),
858 pVarRec->OffsValue, pcx);
859 }else
860 V_UNION(&((*pptvd)->vardesc),oInst)=pVarRec->OffsValue;
861 pptvd=&((*pptvd)->next);
862 recoffset += reclength;
865 /* fill in data for a hreftype (offset). When the refernced type is contained
866 * in the typelib, its just an (file) offset in the type info base dir.
867 * If comes fom import, its an offset+1 in the ImpInfo table
868 * */
869 static void TLB_DoRefType(TLBContext *pcx,
870 int offset, TLBRefType ** pprtd)
872 int j;
873 if(!HREFTYPE_INTHISFILE( offset)) {
874 /* external typelib */
875 TLBImpInfo impinfo;
876 TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs);
877 TLB_Read(&impinfo, sizeof(impinfo), pcx,
878 pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
879 for(j=0;pImpLib;j++){ /* search the known offsets of all import libraries */
880 if(pImpLib->offset==impinfo.oImpFile) break;
881 pImpLib=pImpLib->next;
883 if(pImpLib){
884 (*pprtd)->reference=offset;
885 (*pprtd)->pImpTLInfo=pImpLib;
886 TLB_ReadGuid(&(*pprtd)->guid, impinfo.oGuid, pcx);
887 }else{
888 ERR_(typelib)("Cannot find a reference\n");
889 (*pprtd)->reference=-1;
890 (*pprtd)->pImpTLInfo=(void *)-1;
892 }else{
893 /* in this typelib */
894 (*pprtd)->reference=offset;
895 (*pprtd)->pImpTLInfo=(void *)-2;
899 /* process Implemented Interfaces of a com class */
900 static void TLB_DoImplTypes(TLBContext *pcx, int count,
901 int offset, TLBRefType ** pprtd)
903 int i;
904 TLBRefRecord refrec;
905 for(i=0;i<count;i++){
906 if(offset<0) break; /* paranoia */
907 *pprtd=TLB_Alloc(sizeof(TLBRefType));
908 TLB_Read(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
909 TLB_DoRefType(pcx, refrec.reftype, pprtd);
910 (*pprtd)->flags=refrec.flags;
911 (*pprtd)->ctCustData=
912 TLB_CustData(pcx, refrec.oCustData, &(*pprtd)->pCustData);
913 offset=refrec.onext;
914 pprtd=&((*pprtd)->next);
918 * process a typeinfo record
920 TLBTypeInfo * TLB_DoTypeInfo(TLBContext *pcx, int count, TLBLibInfo* pLibInfo)
922 TLBTypeInfoBase tiBase;
923 TLBTypeInfo *ptiRet;
924 ptiRet=TLB_Alloc(sizeof(TLBTypeInfo));
925 ptiRet->lpvtbl = &tinfvt;
926 ptiRet->ref=1;
927 TLB_Read(&tiBase, sizeof(tiBase) ,pcx ,
928 pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
929 /* this where we are coming from */
930 ptiRet->pTypeLib=pLibInfo;
931 ptiRet->index=count;
932 /* fill in the typeattr fields */
933 TLB_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx);
934 ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid; /* FIXME: correct? */
935 ptiRet->TypeAttr.memidConstructor=MEMBERID_NIL ;/* FIXME */
936 ptiRet->TypeAttr.memidDestructor=MEMBERID_NIL ; /* FIXME */
937 ptiRet->TypeAttr.lpstrSchema=NULL; /* reserved */
938 ptiRet->TypeAttr.cbSizeInstance=tiBase.size;
939 ptiRet->TypeAttr.typekind=tiBase.typekind & 0xF;
940 ptiRet->TypeAttr.cFuncs=LOWORD(tiBase.cElement);
941 ptiRet->TypeAttr.cVars=HIWORD(tiBase.cElement);
942 ptiRet->TypeAttr.cbAlignment=(tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */
943 ptiRet->TypeAttr.wTypeFlags=tiBase.flags;
944 ptiRet->TypeAttr.wMajorVerNum=LOWORD(tiBase.version);
945 ptiRet->TypeAttr.wMinorVerNum=HIWORD(tiBase.version);
946 ptiRet->TypeAttr.cImplTypes=tiBase.cImplTypes;
947 ptiRet->TypeAttr.cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
948 if(ptiRet->TypeAttr.typekind == TKIND_ALIAS)
949 TLB_GetTdesc(pcx, tiBase.datatype1,
950 &ptiRet->TypeAttr.tdescAlias) ;
951 /* FIXME: */
952 /* IDLDESC idldescType; *//* never saw this one != zero */
954 /* name, eventually add to a hash table */
955 ptiRet->Name=TLB_ReadName(pcx, tiBase.NameOffset);
956 TRACE_(typelib)("reading %s\n", ptiRet->Name);
957 /* help info */
958 ptiRet->DocString=TLB_ReadString(pcx, tiBase.docstringoffs);
959 ptiRet->dwHelpStringContext=tiBase.helpstringcontext;
960 ptiRet->dwHelpContext=tiBase.helpcontext;
961 /* note: InfoType's Help file and HelpStringDll come from the containing
962 * library. Further HelpString and Docstring appear to be the same thing :(
964 /* functions */
965 if(ptiRet->TypeAttr.cFuncs >0 )
966 TLB_DoFuncs(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
967 tiBase.memoffset, & ptiRet->funclist);
968 /* variables */
969 if(ptiRet->TypeAttr.cVars >0 )
970 TLB_DoVars(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
971 tiBase.memoffset, & ptiRet->varlist);
972 if(ptiRet->TypeAttr.cImplTypes >0 ){
973 if(ptiRet->TypeAttr.typekind == TKIND_COCLASS)
974 TLB_DoImplTypes(pcx, ptiRet->TypeAttr.cImplTypes ,
975 tiBase.datatype1, & ptiRet->impltypelist);
976 else if(ptiRet->TypeAttr.typekind != TKIND_DISPATCH){
977 ptiRet->impltypelist=TLB_Alloc(sizeof(TLBRefType));
978 TLB_DoRefType(pcx, tiBase.datatype1, & ptiRet->impltypelist);
981 ptiRet->ctCustData=
982 TLB_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData);
983 return ptiRet;
987 long TLB_FindTlb(TLBContext *pcx)
988 {/* FIXME: should parse the file properly
989 * hack to find our tlb data
991 #define TLBBUFSZ 1024
992 char buff[TLBBUFSZ+1]; /* room for a trailing '\0' */
993 long ret=0,found=0;
994 int count;
995 char *pChr;
997 #define LOOK_FOR_MAGIC(magic) \
998 count=TLB_Read(buff, TLBBUFSZ, pcx, 0); \
999 do { \
1000 buff[count]='\0'; \
1001 pChr = buff; \
1002 while (pChr) { \
1003 pChr = memchr(pChr,magic[0],count-(pChr-buff));\
1004 if (pChr) { \
1005 if (!memcmp(pChr,magic,4)) { \
1006 ret+= pChr-buff; \
1007 found = 1; \
1008 break; \
1010 pChr++; \
1013 if (found) break; \
1014 ret+=count; \
1015 count=TLB_Read(buff, TLBBUFSZ, pcx, DO_NOT_SEEK);\
1016 } while(count>0);
1019 LOOK_FOR_MAGIC(TLBMAGIC2);
1020 if(count)
1021 return ret;
1023 LOOK_FOR_MAGIC(TLBMAGIC1);
1024 if(count)
1025 ERR_(ole)("type library format not (yet) implemented\n");
1026 else
1027 ERR_(ole)("not type library found in this file\n");
1028 return -1;
1030 #undef LOOK_FOR_MAGIC
1032 int TLB_ReadTypeLib(PCHAR file, ITypeLib **ppTypeLib)
1034 TLBContext cx;
1035 OFSTRUCT ofStruct;
1036 long oStart,lPSegDir;
1037 TLBLibInfo* pLibInfo=NULL;
1038 TLB2Header tlbHeader;
1039 TLBSegDir tlbSegDir;
1040 if((cx.hFile=OpenFile(file, &ofStruct, OF_READWRITE))==HFILE_ERROR) {
1041 ERR_(typelib)("cannot open %s error 0x%lx\n",file, GetLastError());
1042 return E_FAIL;
1044 /* get pointer to beginning of typelib data */
1045 cx.oStart=0;
1046 if((oStart=TLB_FindTlb(&cx))<0){
1047 if(oStart==-1)
1048 ERR_(typelib)("cannot locate typelib in %s\n",file);
1049 else
1050 ERR_(typelib)("unsupported typelib format in %s\n",file);
1051 return E_FAIL;
1053 cx.oStart=oStart;
1054 pLibInfo=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TLBLibInfo));
1055 if (!pLibInfo){
1056 CloseHandle(cx.hFile);
1057 return E_OUTOFMEMORY;
1059 pLibInfo->lpvtbl = &tlbvt;
1060 pLibInfo->ref=1;
1061 cx.pLibInfo=pLibInfo;
1062 /* read header */
1063 TLB_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
1064 /* there is a small number of information here until the next important
1065 * part:
1066 * the segment directory . Try to calculate the amount of data */
1067 lPSegDir=sizeof(tlbHeader)+
1068 (tlbHeader.nrtypeinfos)*4+
1069 (tlbHeader.varflags & HELPDLLFLAG? 4 :0);
1070 /* now read the segment directory */
1071 TLB_Read((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
1072 cx.pTblDir=&tlbSegDir;
1073 /* just check two entries */
1074 if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F ||
1075 tlbSegDir.pImpInfo.res0c != 0x0F
1077 ERR_(typelib)("cannot find the table directory, ptr=0x%lx\n",lPSegDir);
1078 CloseHandle(cx.hFile);
1079 return E_FAIL;
1081 /* now fill our internal data */
1082 /* TLIBATTR fields */
1083 TLB_ReadGuid(&pLibInfo->LibAttr.guid, tlbHeader.posguid, &cx);
1084 pLibInfo->LibAttr.lcid=tlbHeader.lcid;
1085 pLibInfo->LibAttr.syskind=tlbHeader.varflags & 0x0f; /* check the mask */
1086 pLibInfo->LibAttr.wMajorVerNum=LOWORD(tlbHeader.version);
1087 pLibInfo->LibAttr.wMinorVerNum=HIWORD(tlbHeader.version);
1088 pLibInfo->LibAttr.wLibFlags=(WORD) tlbHeader.flags & 0xffff;/* check mask */
1089 /* name, eventually add to a hash table */
1090 pLibInfo->Name=TLB_ReadName(&cx, tlbHeader.NameOffset);
1091 /* help info */
1092 pLibInfo->DocString=TLB_ReadString(&cx, tlbHeader.helpstring);
1093 pLibInfo->HelpFile=TLB_ReadString(&cx, tlbHeader.helpfile);
1094 if( tlbHeader.varflags & HELPDLLFLAG){
1095 int offset;
1096 TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
1097 pLibInfo->HelpStringDll=TLB_ReadString(&cx, offset);
1100 pLibInfo->dwHelpContext=tlbHeader.helpstringcontext;
1101 /* custom data */
1102 if(tlbHeader.CustomDataOffset >= 0) {
1103 pLibInfo->ctCustData=
1104 TLB_CustData(&cx, tlbHeader.CustomDataOffset, &pLibInfo->pCustData);
1106 /* fill in typedescriptions */
1107 if(tlbSegDir.pTypdescTab.length >0){
1108 int i, j, cTD=tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
1109 INT16 td[4];
1110 pLibInfo->pTypeDesc=
1111 TLB_Alloc( cTD * sizeof(TYPEDESC));
1112 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
1113 for(i=0;i<cTD;){
1114 /* FIXME: add several sanity checks here */
1115 pLibInfo->pTypeDesc[i].vt=td[0] & VT_TYPEMASK;
1116 if(td[0]==VT_PTR ||td[0]==VT_SAFEARRAY){/* FIXME: check safearray */
1117 if(td[3]<0)
1118 V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
1119 & stndTypeDesc[td[2]];
1120 else
1121 V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
1122 & pLibInfo->pTypeDesc[td[3]/8];
1123 }else if(td[0]==VT_CARRAY)
1124 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
1125 (void *)((int) td[2]); /* temp store offset in*/
1126 /* array descr table here */
1127 else if(td[0]==VT_USERDEFINED)
1128 V_UNION(&(pLibInfo->pTypeDesc[i]),hreftype)=MAKELONG(td[2],td[3]);
1129 if(++i<cTD) TLB_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
1131 /* second time around to fill the array subscript info */
1132 for(i=0;i<cTD;i++){
1133 if(pLibInfo->pTypeDesc[i].vt != VT_CARRAY) continue;
1134 if(tlbSegDir.pArrayDescriptions.offset>0){
1135 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset +
1136 (int) V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc));
1137 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
1138 TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
1139 if(td[1]<0)
1140 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem.vt=td[0] & VT_TYPEMASK;
1141 else
1142 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem=stndTypeDesc[td[0]/8];
1143 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->cDims=td[2];
1144 for(j=0;j<td[2];j++){
1145 TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->rgbounds[j].cElements,
1146 sizeof(INT), &cx, DO_NOT_SEEK);
1147 TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)
1148 ->rgbounds[j].lLbound,
1149 sizeof(INT), &cx, DO_NOT_SEEK);
1151 }else{
1152 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=NULL;
1153 ERR_(ole)("didn't find array description data\n");
1157 /* imported type libs */
1158 if(tlbSegDir.pImpFiles.offset>0){
1159 TLBImpLib **ppImpLib=&(pLibInfo->pImpLibs);
1160 int offset=tlbSegDir.pImpFiles.offset;
1161 int oGuid;
1162 UINT16 size;
1163 while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length){
1164 *ppImpLib=TLB_Alloc(sizeof(TLBImpLib));
1165 (*ppImpLib)->offset=offset - tlbSegDir.pImpFiles.offset;
1166 TLB_Read(&oGuid, sizeof(INT), &cx, offset);
1167 TLB_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
1168 /* we are skipping some unknown info here */
1169 TLB_Read(& size,sizeof(UINT16), &cx, offset+3*(sizeof(INT)));
1170 size >>=2;
1171 (*ppImpLib)->name=TLB_Alloc(size+1);
1172 TLB_Read((*ppImpLib)->name,size, &cx, DO_NOT_SEEK);
1173 offset=(offset+3*(sizeof(INT))+sizeof(UINT16)+size+3) & 0xfffffffc;
1175 ppImpLib=&(*ppImpLib)->next;
1178 /* type info's */
1179 if(tlbHeader.nrtypeinfos >=0 ){
1180 /*pLibInfo->TypeInfoCount=tlbHeader.nrtypeinfos; */
1181 TLBTypeInfo **ppTI=&(pLibInfo->pTypeInfo);
1182 int i;
1183 for(i=0;i<(int)tlbHeader.nrtypeinfos;i++){
1184 *ppTI=TLB_DoTypeInfo(&cx, i, pLibInfo);
1185 ppTI=&((*ppTI)->next);
1186 (pLibInfo->TypeInfoCount)++;
1190 CloseHandle(cx.hFile);
1191 *ppTypeLib=(LPTYPELIB)pLibInfo;
1192 return S_OK;
1195 /*================== ITypeLib(2) Methods ===================================*/
1197 /* ITypeLib::QueryInterface
1199 static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid,
1200 VOID **ppvObject)
1202 if(TRACE_ON(typelib)){
1203 char xriid[50];
1204 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1205 TRACE_(typelib)("(%p)->(IID: %s)\n",This,xriid);
1207 *ppvObject=NULL;
1208 if(IsEqualIID(riid, &IID_IUnknown) ||
1209 IsEqualIID(riid,&IID_ITypeLib)||
1210 IsEqualIID(riid,&IID_ITypeLib2))
1211 *ppvObject = This;
1212 if(*ppvObject){
1213 (*(LPTYPELIB*)ppvObject)->lpvtbl->fnAddRef(This);
1214 TRACE_(typelib)("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1215 return S_OK;
1217 TRACE_(typelib)("-- Interface: E_NOINTERFACE\n");
1218 return E_NOINTERFACE;
1221 /* ITypeLib::AddRef
1223 static ULONG WINAPI ITypeLib_fnAddRef( LPTYPELIB iface)
1225 ICOM_THIS( TLBLibInfo, iface);
1226 TRACE_(typelib)("(%p)->ref is %u\n",This, This->ref);
1227 return ++(This->ref);
1230 /* ITypeLib::Release
1232 static ULONG WINAPI ITypeLib_fnRelease( LPTYPELIB iface)
1234 ICOM_THIS( TLBLibInfo, iface);
1235 FIXME_(typelib)("(%p)->ref is %u: stub\n",This, This->ref);
1236 (This->ref)--;
1237 return S_OK;
1240 /* ITypeLib::GetTypeInfoCount
1242 * Returns the number of type descriptions in the type library
1244 static UINT WINAPI ITypeLib_fnGetTypeInfoCount( LPTYPELIB iface)
1246 ICOM_THIS( TLBLibInfo, iface);
1247 TRACE_(typelib)("(%p)->count is %d\n",This, This->TypeInfoCount);
1248 return This->TypeInfoCount;
1251 /* ITypeLib::GetTypeInfo
1253 *etrieves the specified type description in the library.
1255 static HRESULT WINAPI ITypeLib_fnGetTypeInfo( LPTYPELIB iface, UINT index,
1256 ITypeInfo **ppTInfo)
1258 int i;
1259 ICOM_THIS( TLBLibInfo, iface);
1260 TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo;
1261 TRACE_(typelib)("(%p) index %d \n",This, index);
1262 for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo && i != index;i++)
1263 *ppTLBTInfo=(*ppTLBTInfo)->next;
1264 if(*ppTLBTInfo){
1265 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
1266 TRACE_(typelib)("-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
1267 return S_OK;
1269 TRACE_(typelib)("-- element not found\n");
1270 return TYPE_E_ELEMENTNOTFOUND;
1273 /* ITypeLibs::GetTypeInfoType
1275 * Retrieves the type of a type description.
1277 static HRESULT WINAPI ITypeLib_fnGetTypeInfoType( LPTYPELIB iface, UINT index,
1278 TYPEKIND *pTKind)
1280 int i;
1281 TLBTypeInfo *pTInfo;
1282 ICOM_THIS( TLBLibInfo, iface);
1283 TRACE_(typelib)("(%p) index %d \n",This, index);
1284 for(i=0,pTInfo=This->pTypeInfo;pTInfo && i != index;i++)
1285 pTInfo=(pTInfo)->next;
1286 if(pTInfo){
1287 *pTKind=pTInfo->TypeAttr.typekind;
1288 TRACE_(typelib)("-- found Type (%p)->%d\n",pTKind,*pTKind);
1289 return S_OK;
1291 TRACE_(typelib)("-- element not found\n");
1292 return TYPE_E_ELEMENTNOTFOUND;
1295 /* ITypeLib::GetTypeInfoOfGuid
1297 * Retrieves the type description that corresponds to the specified GUID.
1300 static HRESULT WINAPI ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB iface,
1301 REFGUID guid, ITypeInfo **ppTInfo)
1303 int i;
1304 ICOM_THIS( TLBLibInfo, iface);
1305 TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo;
1306 if(TRACE_ON(typelib)){
1307 char xriid[50];
1308 WINE_StringFromCLSID((LPCLSID)guid,xriid);
1309 TRACE_(typelib)("(%p) guid %sx)\n",This,xriid);
1311 for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo &&
1312 !IsEqualIID(guid,&(*ppTLBTInfo)->TypeAttr.guid);i++)
1313 *ppTLBTInfo=(*ppTLBTInfo)->next;
1314 if(*ppTLBTInfo){
1315 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo);
1316 TRACE_(typelib)("-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo);
1317 return S_OK;
1319 TRACE_(typelib)("-- element not found\n");
1320 return TYPE_E_ELEMENTNOTFOUND;
1323 /* ITypeLib::GetLibAttr
1325 * Retrieves the structure that contains the library's attributes.
1328 static HRESULT WINAPI ITypeLib_fnGetLibAttr( LPTYPELIB iface,
1329 LPTLIBATTR *ppTLibAttr)
1331 ICOM_THIS( TLBLibInfo, iface);
1332 TRACE_(typelib)("(%p)\n",This);
1333 /* FIXME: must do a copy here */
1334 *ppTLibAttr=&This->LibAttr;
1335 return S_OK;
1338 /* ITypeLib::GetTypeComp
1340 * Enables a client compiler to bind to a library's types, variables,
1341 * constants, and global functions.
1344 static HRESULT WINAPI ITypeLib_fnGetTypeComp( LPTYPELIB iface,
1345 ITypeComp **ppTComp)
1347 ICOM_THIS( TLBLibInfo, iface);
1348 FIXME_(typelib)("(%p): stub!\n",This);
1349 return E_NOTIMPL;
1352 /* ITypeLib::GetDocumentation
1354 * Retrieves the library's documentation string, the complete Help file name
1355 * and path, and the context identifier for the library Help topic in the Help
1356 * file.
1359 static HRESULT WINAPI ITypeLib_fnGetDocumentation( LPTYPELIB iface, INT index,
1360 BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext,
1361 BSTR *pBstrHelpFile)
1363 ICOM_THIS( TLBLibInfo, iface);
1364 HRESULT result;
1365 ITypeInfo *pTInfo;
1366 TRACE_(typelib)("(%p) index %d Name(%p) DocString(%p)"
1367 " HelpContext(%p) HelpFile(%p)\n",
1368 This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1369 if(index<0){ /* documentation for the typelib */
1370 if(pBstrName)
1371 *pBstrName=TLB_DupAtoBstr(This->Name);
1372 if(pBstrDocString)
1373 *pBstrName=TLB_DupAtoBstr(This->DocString);
1374 if(pdwHelpContext)
1375 *pdwHelpContext=This->dwHelpContext;
1376 if(pBstrHelpFile)
1377 *pBstrName=TLB_DupAtoBstr(This->HelpFile);
1378 }else {/* for a typeinfo */
1379 result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo);
1380 if(SUCCEEDED(result)){
1381 result=ITypeInfo_GetDocumentation(pTInfo, MEMBERID_NIL, pBstrName,
1382 pBstrDocString, pdwHelpContext, pBstrHelpFile);
1383 ITypeInfo_Release(pTInfo);
1385 if(!SUCCEEDED(result))
1386 return result;
1388 return S_OK;
1391 /* ITypeLib::IsName
1393 * Indicates whether a passed-in string contains the name of a type or member
1394 * described in the library.
1397 static HRESULT WINAPI ITypeLib_fnIsName( LPTYPELIB iface, LPOLESTR szNameBuf,
1398 ULONG lHashVal, BOOL *pfName)
1400 ICOM_THIS( TLBLibInfo, iface);
1401 TLBTypeInfo *pTInfo;
1402 TLBFuncDesc *pFInfo;
1403 TLBVarDesc *pVInfo;
1404 int i;
1405 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1406 *pfName=TRUE;
1407 if(!strcmp(astr,This->Name)) goto ITypeLib_fnIsName_exit;
1408 for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){
1409 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnIsName_exit;
1410 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1411 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnIsName_exit;
1412 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1413 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1414 goto ITypeLib_fnIsName_exit;
1416 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
1417 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnIsName_exit;
1420 *pfName=FALSE;
1422 ITypeLib_fnIsName_exit:
1423 TRACE_(typelib)("(%p)slow! search for %s: %s found!\n", This,
1424 debugstr_a(astr), *pfName?"NOT":"");
1426 HeapFree( GetProcessHeap(), 0, astr );
1427 return S_OK;
1430 /* ITypeLib::FindName
1432 * Finds occurrences of a type description in a type library. This may be used
1433 * to quickly verify that a name exists in a type library.
1436 static HRESULT WINAPI ITypeLib_fnFindName( LPTYPELIB iface, LPOLESTR szNameBuf,
1437 ULONG lHashVal, ITypeInfo **ppTInfo, MEMBERID *rgMemId, UINT16 *pcFound)
1439 ICOM_THIS( TLBLibInfo, iface);
1440 TLBTypeInfo *pTInfo;
1441 TLBFuncDesc *pFInfo;
1442 TLBVarDesc *pVInfo;
1443 int i,j = 0;
1444 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf );
1445 for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){
1446 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnFindName_exit;
1447 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1448 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnFindName_exit;
1449 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1450 if(!strcmp(astr,pFInfo->pParamDesc[i].Name))
1451 goto ITypeLib_fnFindName_exit;
1453 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
1454 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnFindName_exit;
1455 continue;
1456 ITypeLib_fnFindName_exit:
1457 pTInfo->lpvtbl->fnAddRef((LPTYPEINFO)pTInfo);
1458 ppTInfo[j]=(LPTYPEINFO)pTInfo;
1459 j++;
1461 TRACE_(typelib)("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
1462 This, *pcFound, debugstr_a(astr), j);
1464 *pcFound=j;
1466 HeapFree( GetProcessHeap(), 0, astr );
1467 return S_OK;
1470 /* ITypeLib::ReleaseTLibAttr
1472 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
1475 static VOID WINAPI ITypeLib_fnReleaseTLibAttr( LPTYPELIB iface, TLIBATTR *pTLibAttr)
1477 ICOM_THIS( TLBLibInfo, iface);
1478 TRACE_(typelib)("freeing (%p)\n",This);
1479 /* nothing to do */
1482 /* ITypeLib2::GetCustData
1484 * gets the custom data
1486 static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLib * iface, REFGUID guid,
1487 VARIANT *pVarVal)
1489 ICOM_THIS( TLBLibInfo, iface);
1490 TLBCustData *pCData;
1491 for(pCData=This->pCustData; pCData; pCData = pCData->next)
1492 if( IsEqualIID(guid, &pCData->guid)) break;
1493 if(TRACE_ON(typelib)){
1494 char xriid[50];
1495 WINE_StringFromCLSID((LPCLSID)guid,xriid);
1496 TRACE_(typelib)("(%p) guid %s %s found!x)\n",This,xriid,
1497 pCData? "" : "NOT");
1499 if(pCData){
1500 VariantInit( pVarVal);
1501 VariantCopy( pVarVal, &pCData->data);
1502 return S_OK;
1504 return E_INVALIDARG; /* FIXME: correct? */
1507 /* ITypeLib2::GetLibStatistics
1509 * Returns statistics about a type library that are required for efficient
1510 * sizing of hash tables.
1513 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( ITypeLib * iface,
1514 UINT *pcUniqueNames, UINT *pcchUniqueNames)
1516 ICOM_THIS( TLBLibInfo, iface);
1517 FIXME_(typelib)("(%p): stub!\n", This);
1518 if(pcUniqueNames) *pcUniqueNames=1;
1519 if(pcchUniqueNames) *pcchUniqueNames=1;
1520 return S_OK;
1523 /* ITypeLib2::GetDocumentation2
1525 * Retrieves the library's documentation string, the complete Help file name
1526 * and path, the localization context to use, and the context ID for the
1527 * library Help topic in the Help file.
1530 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( ITypeLib * iface,
1531 INT index, LCID lcid, BSTR *pbstrHelpString,
1532 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
1534 ICOM_THIS( TLBLibInfo, iface);
1535 HRESULT result;
1536 ITypeInfo *pTInfo;
1537 FIXME_(typelib)("(%p) index %d lcid %ld half implemented stub!\n", This,
1538 index, lcid);
1539 /* the help string should be obtained from the helpstringdll,
1540 * using the _DLLGetDocumentation function, based on the supplied
1541 * lcid. Nice to do sometime...
1543 if(index<0){ /* documentation for the typelib */
1544 if(pbstrHelpString)
1545 *pbstrHelpString=TLB_DupAtoBstr(This->DocString);
1546 if(pdwHelpStringContext)
1547 *pdwHelpStringContext=This->dwHelpContext;
1548 if(pbstrHelpStringDll)
1549 *pbstrHelpStringDll=TLB_DupAtoBstr(This->HelpStringDll);
1550 }else {/* for a typeinfo */
1551 result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo);
1552 if(SUCCEEDED(result)){
1553 result=ITypeInfo2_fnGetDocumentation2(pTInfo, MEMBERID_NIL, lcid,
1554 pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
1555 ITypeInfo_Release(pTInfo);
1557 if(!SUCCEEDED(result))
1558 return result;
1560 return S_OK;
1563 /* ITypeLib2::GetAllCustData
1565 * Gets all custom data items for the library.
1568 static HRESULT WINAPI ITypeLib2_fnGetAllCustData( ITypeLib * iface,
1569 CUSTDATA *pCustData)
1571 ICOM_THIS( TLBLibInfo, iface);
1572 TLBCustData *pCData;
1573 int i;
1574 TRACE_(typelib)("(%p) returning %d items\n", This, This->ctCustData);
1575 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
1576 if(pCustData->prgCustData ){
1577 pCustData->cCustData=This->ctCustData;
1578 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
1579 pCustData->prgCustData[i].guid=pCData->guid;
1580 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
1582 }else{
1583 ERR_(typelib)(" OUT OF MEMORY! \n");
1584 return E_OUTOFMEMORY;
1586 return S_OK;
1590 /*================== ITypeInfo(2) Methods ===================================*/
1592 /* ITypeInfo::QueryInterface
1594 static HRESULT WINAPI ITypeInfo_fnQueryInterface( LPTYPEINFO iface, REFIID riid,
1595 VOID **ppvObject)
1597 ICOM_THIS( TLBTypeInfo, iface);
1598 if(TRACE_ON(typelib)){
1599 char xriid[50];
1600 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1601 TRACE_(typelib)("(%p)->(IID: %s)\n",This,xriid);
1603 *ppvObject=NULL;
1604 if(IsEqualIID(riid, &IID_IUnknown) ||
1605 IsEqualIID(riid,&IID_ITypeInfo)||
1606 IsEqualIID(riid,&IID_ITypeInfo2))
1607 *ppvObject = This;
1608 if(*ppvObject){
1609 (*(LPTYPEINFO*)ppvObject)->lpvtbl->fnAddRef(iface);
1610 TRACE_(typelib)("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1611 return S_OK;
1613 TRACE_(typelib)("-- Interface: E_NOINTERFACE\n");
1614 return E_NOINTERFACE;
1617 /* ITypeInfo::AddRef
1619 static ULONG WINAPI ITypeInfo_fnAddRef( LPTYPEINFO iface)
1621 ICOM_THIS( TLBTypeInfo, iface);
1622 TRACE_(typelib)("(%p)->ref is %u\n",This, This->ref);
1623 (This->pTypeLib->ref)++;
1624 return ++(This->ref);
1627 /* ITypeInfo::Release
1629 static ULONG WINAPI ITypeInfo_fnRelease( LPTYPEINFO iface)
1631 ICOM_THIS( TLBTypeInfo, iface);
1632 FIXME_(typelib)("(%p)->ref is %u: stub\n",This, This->ref);
1633 (This->ref)--;
1634 (This->pTypeLib->ref)--;
1635 return S_OK;
1638 /* ITypeInfo::GetTypeAttr
1640 * Retrieves a TYPEATTR structure that contains the attributes of the type
1641 * description.
1644 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( LPTYPEINFO iface,
1645 LPTYPEATTR *ppTypeAttr)
1647 ICOM_THIS( TLBTypeInfo, iface);
1648 TRACE_(typelib)("(%p)\n",This);
1649 /* FIXME: must do a copy here */
1650 *ppTypeAttr=&This->TypeAttr;
1651 return S_OK;
1654 /* ITypeInfo::GetTypeComp
1656 * Retrieves the ITypeComp interface for the type description, which enables a
1657 * client compiler to bind to the type description's members.
1660 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( LPTYPEINFO iface,
1661 ITypeComp * *ppTComp)
1663 ICOM_THIS( TLBTypeInfo, iface);
1664 FIXME_(typelib)("(%p) stub!\n", This);
1665 return S_OK;
1668 /* ITypeInfo::GetFuncDesc
1670 * Retrieves the FUNCDESC structure that contains information about a
1671 * specified function.
1674 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( LPTYPEINFO iface, UINT index,
1675 LPFUNCDESC *ppFuncDesc)
1677 ICOM_THIS( TLBTypeInfo, iface);
1678 int i;
1679 TLBFuncDesc * pFDesc;
1680 TRACE_(typelib)("(%p) index %d\n", This, index);
1681 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
1683 if(pFDesc){
1684 /* FIXME: must do a copy here */
1685 *ppFuncDesc=&pFDesc->funcdesc;
1686 return S_OK;
1688 return E_INVALIDARG;
1691 /* ITypeInfo::GetVarDesc
1693 * Retrieves a VARDESC structure that describes the specified variable.
1696 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( LPTYPEINFO iface, UINT index,
1697 LPVARDESC *ppVarDesc)
1699 ICOM_THIS( TLBTypeInfo, iface);
1700 int i;
1701 TLBVarDesc * pVDesc;
1702 TRACE_(typelib)("(%p) index %d\n", This, index);
1703 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next)
1705 if(pVDesc){
1706 /* FIXME: must do a copy here */
1707 *ppVarDesc=&pVDesc->vardesc;
1708 return S_OK;
1710 return E_INVALIDARG;
1713 /* ITypeInfo_GetNames
1715 * Retrieves the variable with the specified member ID (or the name of the
1716 * property or method and its parameters) that correspond to the specified
1717 * function ID.
1719 static HRESULT WINAPI ITypeInfo_fnGetNames( LPTYPEINFO iface, MEMBERID memid,
1720 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
1722 ICOM_THIS( TLBTypeInfo, iface);
1723 TLBFuncDesc * pFDesc;
1724 TLBVarDesc * pVDesc;
1725 int i;
1726 TRACE_(typelib)("(%p) memid=0x%08lx Maxname=%d\n", This, memid,
1727 cMaxNames);
1728 for(pFDesc=This->funclist; pFDesc->funcdesc.memid != memid && pFDesc;
1729 pFDesc=pFDesc->next)
1731 if(pFDesc){
1732 /* function found, now return function and parameter names */
1733 for(i=0; i<cMaxNames && i <= pFDesc->funcdesc.cParams; i++){
1734 if(!i) *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
1735 else
1736 rgBstrNames[i]=TLB_DupAtoBstr(pFDesc->pParamDesc[i-1].Name);
1739 *pcNames=i;
1740 }else{
1741 for(pVDesc=This->varlist; pVDesc->vardesc.memid != memid && pVDesc;
1742 pVDesc=pVDesc->next)
1744 if(pVDesc){
1745 *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name);
1746 *pcNames=1;
1747 }else{
1748 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
1749 This->TypeAttr.cImplTypes ){
1750 /* recursive search */
1751 ITypeInfo *pTInfo;
1752 HRESULT result;
1753 result=This->lpvtbl->fnGetRefTypeInfo(iface,
1754 This->impltypelist->reference, &pTInfo);
1755 if(SUCCEEDED(result)){
1756 result=pTInfo->lpvtbl->fnGetNames(pTInfo, memid, rgBstrNames,
1757 cMaxNames, pcNames);
1758 pTInfo->lpvtbl->fnRelease(pTInfo);
1759 return result;
1761 WARN_(typelib)("Could not search inherited interface!\n");
1762 } else
1763 WARN_(typelib)("no names found\n");
1764 *pcNames=0;
1765 return TYPE_E_ELEMENTNOTFOUND;
1768 return S_OK;
1772 /* ITypeInfo::GetRefTypeOfImplType
1774 * If a type description describes a COM class, it retrieves the type
1775 * description of the implemented interface types. For an interface,
1776 * GetRefTypeOfImplType returns the type information for inherited interfaces,
1777 * if any exist.
1780 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO iface,
1781 UINT index, HREFTYPE *pRefType)
1783 ICOM_THIS( TLBTypeInfo, iface);
1784 int(i);
1785 TLBRefType *pIref;
1786 TRACE_(typelib)("(%p) index %d\n", This, index);
1787 for(i=0, pIref=This->impltypelist; i<index && pIref;
1788 i++, pIref=pIref->next)
1790 if(i==index){
1791 *pRefType=pIref->reference;
1792 return S_OK;
1794 return TYPE_E_ELEMENTNOTFOUND;
1797 /* ITypeInfo::GetImplTypeFlags
1799 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
1800 * or base interface in a type description.
1802 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO iface,
1803 UINT index, INT *pImplTypeFlags)
1805 ICOM_THIS( TLBTypeInfo, iface);
1806 int(i);
1807 TLBRefType *pIref;
1808 TRACE_(typelib)("(%p) index %d\n", This, index);
1809 for(i=0, pIref=This->impltypelist; i<index && pIref; i++, pIref=pIref->next)
1811 if(i==index && pIref){
1812 *pImplTypeFlags=pIref->flags;
1813 return S_OK;
1815 *pImplTypeFlags=0;
1816 return TYPE_E_ELEMENTNOTFOUND;
1819 /* GetIDsOfNames
1820 * Maps between member names and member IDs, and parameter names and
1821 * parameter IDs.
1823 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( LPTYPEINFO iface,
1824 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
1826 ICOM_THIS( TLBTypeInfo, iface);
1827 TLBFuncDesc * pFDesc;
1828 TLBVarDesc * pVDesc;
1829 HRESULT ret=S_OK;
1830 PCHAR aszName= HEAP_strdupWtoA( GetProcessHeap(), 0, *rgszNames);
1831 TRACE_(typelib)("(%p) Name %s cNames %d\n", This, debugstr_a(aszName),
1832 cNames);
1833 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) {
1834 int i, j;
1835 if( !strcmp(aszName, pFDesc->Name)) {
1836 if(cNames) *pMemId=pFDesc->funcdesc.memid;
1837 for(i=1; i < cNames; i++){
1838 PCHAR aszPar= HEAP_strdupWtoA( GetProcessHeap(), 0,
1839 rgszNames[i]);
1840 for(j=0; j<pFDesc->funcdesc.cParams; j++)
1841 if(strcmp(aszPar,pFDesc->pParamDesc[j].Name))
1842 break;
1843 if( j<pFDesc->funcdesc.cParams)
1844 pMemId[i]=j;
1845 else
1846 ret=DISP_E_UNKNOWNNAME;
1847 HeapFree( GetProcessHeap(), 0, aszPar);
1849 HeapFree (GetProcessHeap(), 0, aszName);
1850 return ret;
1853 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
1854 if( !strcmp(aszName, pVDesc->Name)) {
1855 if(cNames) *pMemId=pVDesc->vardesc.memid;
1856 HeapFree (GetProcessHeap(), 0, aszName);
1857 return ret;
1860 /* not found, see if this is and interface with an inheritance */
1861 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
1862 This->TypeAttr.cImplTypes ){
1863 /* recursive search */
1864 ITypeInfo *pTInfo;
1865 ret=This->lpvtbl->fnGetRefTypeInfo(iface,
1866 This->impltypelist->reference, &pTInfo);
1867 if(SUCCEEDED(ret)){
1868 ret=pTInfo->lpvtbl->fnGetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
1869 pTInfo->lpvtbl->fnRelease(pTInfo);
1870 return ret;
1872 WARN_(typelib)("Could not search inherited interface!\n");
1873 } else
1874 WARN_(typelib)("no names found\n");
1875 return DISP_E_UNKNOWNNAME;
1878 /* ITypeInfo::Invoke
1880 * Invokes a method, or accesses a property of an object, that implements the
1881 * interface described by the type description.
1883 static HRESULT WINAPI ITypeInfo_fnInvoke( LPTYPEINFO iface, VOID *pIUnk,
1884 MEMBERID memid, UINT16 dwFlags, DISPPARAMS *pDispParams,
1885 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *pArgErr)
1887 ICOM_THIS( TLBTypeInfo, iface);
1888 FIXME_(typelib)("(%p) stub!", This);
1889 return S_OK;
1892 /* ITypeInfo::GetDocumentation
1894 * Retrieves the documentation string, the complete Help file name and path,
1895 * and the context ID for the Help topic for a specified type description.
1897 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( LPTYPEINFO iface,
1898 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
1899 DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
1901 ICOM_THIS( TLBTypeInfo, iface);
1902 TLBFuncDesc * pFDesc;
1903 TLBVarDesc * pVDesc;
1904 TRACE_(typelib)("(%p) memid %ld Name(%p) DocString(%p)"
1905 " HelpContext(%p) HelpFile(%p)\n",
1906 This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1907 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
1908 if(pBstrName)
1909 *pBstrName=TLB_DupAtoBstr(This->Name);
1910 if(pBstrDocString)
1911 *pBstrDocString=TLB_DupAtoBstr(This->DocString);
1912 if(pdwHelpContext)
1913 *pdwHelpContext=This->dwHelpContext;
1914 if(pBstrHelpFile)
1915 *pBstrHelpFile=TLB_DupAtoBstr(This->DocString);/* FIXME */
1916 return S_OK;
1917 }else {/* for a member */
1918 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
1919 if(pFDesc->funcdesc.memid==memid){
1920 return S_OK;
1922 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
1923 if(pVDesc->vardesc.memid==memid){
1924 return S_OK;
1927 return TYPE_E_ELEMENTNOTFOUND;
1930 /* ITypeInfo::GetDllEntry
1932 * Retrieves a description or specification of an entry point for a function
1933 * in a DLL.
1935 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( LPTYPEINFO iface, MEMBERID memid,
1936 INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
1937 WORD *pwOrdinal)
1939 ICOM_THIS( TLBTypeInfo, iface);
1940 FIXME_(typelib)("(%p) stub!\n", This);
1941 return E_FAIL;
1944 /* ITypeInfo::GetRefTypeInfo
1946 * If a type description references other type descriptions, it retrieves
1947 * the referenced type descriptions.
1949 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO iface,
1950 HREFTYPE hRefType, ITypeInfo * *ppTInfo)
1952 ICOM_THIS( TLBTypeInfo, iface);
1953 HRESULT result;
1954 if(HREFTYPE_INTHISFILE(hRefType)){
1955 ITypeLib *pTLib;
1956 int Index;
1957 result=This->lpvtbl->fnGetContainingTypeLib(iface, &pTLib,
1958 &Index);
1959 if(SUCCEEDED(result)){
1960 result=pTLib->lpvtbl->fnGetTypeInfo(pTLib,
1961 HREFTYPE_INDEX(hRefType),
1962 ppTInfo);
1963 pTLib->lpvtbl->fnRelease(pTLib );
1965 } else{
1966 /* imported type lib */
1967 TLBRefType * pRefType;
1968 TLBLibInfo *pTypeLib;
1969 for( pRefType=This->impltypelist; pRefType &&
1970 pRefType->reference != hRefType; pRefType=pRefType->next)
1972 if(!pRefType)
1973 return TYPE_E_ELEMENTNOTFOUND; /* FIXME : correct? */
1974 pTypeLib=pRefType->pImpTLInfo->pImpTypeLib;
1975 if(pTypeLib) /* typelib already loaded */
1976 result=pTypeLib->lpvtbl->fnGetTypeInfoOfGuid(
1977 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
1978 else{
1979 result=LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
1980 0,0,0, /* FIXME */
1981 (LPTYPELIB *)&pTypeLib);
1982 if(!SUCCEEDED(result)){
1983 BSTR libnam=TLB_DupAtoBstr(pRefType->pImpTLInfo->name);
1984 result=LoadTypeLib(libnam, (LPTYPELIB *)&pTypeLib);
1985 SysFreeString(libnam);
1987 if(SUCCEEDED(result)){
1988 result=pTypeLib->lpvtbl->fnGetTypeInfoOfGuid(
1989 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
1990 pRefType->pImpTLInfo->pImpTypeLib=pTypeLib;
1994 TRACE_(typelib)("(%p) hreftype 0x%04lx loaded %s (%p)\n", This, hRefType,
1995 SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
1996 return result;
1999 /* ITypeInfo::AddressOfMember
2001 * Retrieves the addresses of static functions or variables, such as those
2002 * defined in a DLL.
2004 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( LPTYPEINFO iface,
2005 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
2007 ICOM_THIS( TLBTypeInfo, iface);
2008 FIXME_(typelib)("(%p) stub!\n", This);
2009 return S_OK;
2012 /* ITypeInfo::CreateInstance
2014 * Creates a new instance of a type that describes a component object class
2015 * (coclass).
2017 static HRESULT WINAPI ITypeInfo_fnCreateInstance( LPTYPEINFO iface,
2018 IUnknown *pUnk, REFIID riid, VOID **ppvObj)
2020 ICOM_THIS( TLBTypeInfo, iface);
2021 FIXME_(typelib)("(%p) stub!\n", This);
2022 return S_OK;
2025 /* ITypeInfo::GetMops
2027 * Retrieves marshaling information.
2029 static HRESULT WINAPI ITypeInfo_fnGetMops( LPTYPEINFO iface, MEMBERID memid,
2030 BSTR *pBstrMops)
2032 ICOM_THIS( TLBTypeInfo, iface);
2033 FIXME_(typelib)("(%p) stub!\n", This);
2034 return S_OK;
2037 /* ITypeInfo::GetContainingTypeLib
2039 * Retrieves the containing type library and the index of the type description
2040 * within that type library.
2042 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( LPTYPEINFO iface,
2043 ITypeLib * *ppTLib, UINT *pIndex)
2045 ICOM_THIS( TLBTypeInfo, iface);
2046 *ppTLib=(LPTYPELIB )(This->pTypeLib);
2047 *pIndex=This->index;
2048 (*ppTLib)->lpvtbl->fnAddRef(*ppTLib);
2049 TRACE_(typelib)("(%p) returns (%p) index %d!\n", This, *ppTLib, *pIndex);
2050 return S_OK;
2053 /* ITypeInfo::ReleaseTypeAttr
2055 * Releases a TYPEATTR previously returned by GetTypeAttr.
2058 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO iface,
2059 TYPEATTR* pTypeAttr)
2061 ICOM_THIS( TLBTypeInfo, iface);
2062 TRACE_(typelib)("(%p)->(%p)\n", This, pTypeAttr);
2063 return S_OK;
2066 /* ITypeInfo::ReleaseFuncDesc
2068 * Releases a FUNCDESC previously returned by GetFuncDesc. *
2070 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO iface,
2071 FUNCDESC *pFuncDesc)
2073 ICOM_THIS( TLBTypeInfo, iface);
2074 TRACE_(typelib)("(%p)->(%p)\n", This, pFuncDesc);
2075 return S_OK;
2078 /* ITypeInfo::ReleaseVarDesc
2080 * Releases a VARDESC previously returned by GetVarDesc.
2082 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( LPTYPEINFO iface,
2083 VARDESC *pVarDesc)
2085 ICOM_THIS( TLBTypeInfo, iface);
2086 TRACE_(typelib)("(%p)->(%p)\n", This, pVarDesc);
2087 return S_OK;
2090 /* ITypeInfo2::GetTypeKind
2092 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
2095 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo * iface,
2096 TYPEKIND *pTypeKind)
2098 ICOM_THIS( TLBTypeInfo, iface);
2099 *pTypeKind=This->TypeAttr.typekind;
2100 TRACE_(typelib)("(%p) type 0x%0x\n", This,*pTypeKind);
2101 return S_OK;
2104 /* ITypeInfo2::GetTypeFlags
2106 * Returns the type flags without any allocations. This returns a DWORD type
2107 * flag, which expands the type flags without growing the TYPEATTR (type
2108 * attribute).
2111 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo * iface,
2112 UINT *pTypeFlags)
2114 ICOM_THIS( TLBTypeInfo, iface);
2115 *pTypeFlags=This->TypeAttr.wTypeFlags;
2116 TRACE_(typelib)("(%p) flags 0x%04x\n", This,*pTypeFlags);
2117 return S_OK;
2120 /* ITypeInfo2::GetFuncIndexOfMemId
2121 * Binds to a specific member based on a known DISPID, where the member name
2122 * is not known (for example, when binding to a default member).
2125 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo * iface,
2126 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
2128 ICOM_THIS( TLBTypeInfo, iface);
2129 TLBFuncDesc *pFuncInfo;
2130 int i;
2131 HRESULT result;
2132 /* FIXME: should check for invKind??? */
2133 for(i=0, pFuncInfo=This->funclist;pFuncInfo &&
2134 memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next);
2135 if(pFuncInfo){
2136 *pFuncIndex=i;
2137 result= S_OK;
2138 }else{
2139 *pFuncIndex=0;
2140 result=E_INVALIDARG;
2142 TRACE_(typelib)("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This,
2143 memid, invKind, SUCCEEDED(result)? "SUCCES":"FAILED");
2144 return result;
2147 /* TypeInfo2::GetVarIndexOfMemId
2149 * Binds to a specific member based on a known DISPID, where the member name
2150 * is not known (for example, when binding to a default member).
2153 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo * iface,
2154 MEMBERID memid, UINT *pVarIndex)
2156 ICOM_THIS( TLBTypeInfo, iface);
2157 TLBVarDesc *pVarInfo;
2158 int i;
2159 HRESULT result;
2160 for(i=0, pVarInfo=This->varlist; pVarInfo &&
2161 memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next)
2163 if(pVarInfo){
2164 *pVarIndex=i;
2165 result= S_OK;
2166 }else{
2167 *pVarIndex=0;
2168 result=E_INVALIDARG;
2170 TRACE_(typelib)("(%p) memid 0x%08lx -> %s\n", This,
2171 memid, SUCCEEDED(result)? "SUCCES":"FAILED");
2172 return result;
2175 /* ITypeInfo2::GetCustData
2177 * Gets the custom data
2179 static HRESULT WINAPI ITypeInfo2_fnGetCustData( ITypeInfo * iface,
2180 REFGUID guid, VARIANT *pVarVal)
2182 ICOM_THIS( TLBTypeInfo, iface);
2183 TLBCustData *pCData;
2184 for(pCData=This->pCustData; pCData; pCData = pCData->next)
2185 if( IsEqualIID(guid, &pCData->guid)) break;
2186 if(TRACE_ON(typelib)){
2187 char xriid[50];
2188 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2189 TRACE_(typelib)("(%p) guid %s %s found!x)\n", This, xriid,
2190 pCData? "" : "NOT");
2192 if(pCData){
2193 VariantInit( pVarVal);
2194 VariantCopy( pVarVal, &pCData->data);
2195 return S_OK;
2197 return E_INVALIDARG; /* FIXME: correct? */
2200 /* ITypeInfo2::GetFuncCustData
2202 * Gets the custom data
2204 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( ITypeInfo * iface,
2205 UINT index, REFGUID guid, VARIANT *pVarVal)
2207 ICOM_THIS( TLBTypeInfo, iface);
2208 TLBCustData *pCData=NULL;
2209 TLBFuncDesc * pFDesc;
2210 int i;
2211 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2212 pFDesc=pFDesc->next)
2214 if(pFDesc)
2215 for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next)
2216 if( IsEqualIID(guid, &pCData->guid)) break;
2217 if(TRACE_ON(typelib)){
2218 char xriid[50];
2219 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2220 TRACE_(typelib)("(%p) guid %s %s found!x)\n",This,xriid,
2221 pCData? "" : "NOT");
2223 if(pCData){
2224 VariantInit( pVarVal);
2225 VariantCopy( pVarVal, &pCData->data);
2226 return S_OK;
2228 return E_INVALIDARG; /* FIXME: correct? */
2231 /* ITypeInfo2::GetParamCustData
2233 * Gets the custom data
2235 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( ITypeInfo * iface,
2236 UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal)
2238 ICOM_THIS( TLBTypeInfo, iface);
2239 TLBCustData *pCData=NULL;
2240 TLBFuncDesc * pFDesc;
2241 int i;
2242 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
2243 pFDesc=pFDesc->next)
2245 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams)
2246 for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData;
2247 pCData = pCData->next)
2248 if( IsEqualIID(guid, &pCData->guid)) break;
2249 if(TRACE_ON(typelib)){
2250 char xriid[50];
2251 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2252 TRACE_(typelib)("(%p) guid %s %s found!x)\n",This,xriid,
2253 pCData? "" : "NOT");
2255 if(pCData){
2256 VariantInit( pVarVal);
2257 VariantCopy( pVarVal, &pCData->data);
2258 return S_OK;
2260 return E_INVALIDARG; /* FIXME: correct? */
2263 /* ITypeInfo2::GetVarcCustData
2265 * Gets the custom data
2267 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( ITypeInfo * iface,
2268 UINT index, REFGUID guid, VARIANT *pVarVal)
2270 ICOM_THIS( TLBTypeInfo, iface);
2271 TLBCustData *pCData=NULL;
2272 TLBVarDesc * pVDesc;
2273 int i;
2274 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2275 pVDesc=pVDesc->next)
2277 if(pVDesc)
2278 for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next)
2279 if( IsEqualIID(guid, &pCData->guid)) break;
2280 if(TRACE_ON(typelib)){
2281 char xriid[50];
2282 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2283 TRACE_(typelib)("(%p) guid %s %s found!x)\n",This,xriid,
2284 pCData? "" : "NOT");
2286 if(pCData){
2287 VariantInit( pVarVal);
2288 VariantCopy( pVarVal, &pCData->data);
2289 return S_OK;
2291 return E_INVALIDARG; /* FIXME: correct? */
2294 /* ITypeInfo2::GetImplcCustData
2296 * Gets the custom data
2298 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( ITypeInfo * iface,
2299 UINT index, REFGUID guid, VARIANT *pVarVal)
2301 ICOM_THIS( TLBTypeInfo, iface);
2302 TLBCustData *pCData=NULL;
2303 TLBRefType * pRDesc;
2304 int i;
2305 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2306 pRDesc=pRDesc->next)
2308 if(pRDesc)
2309 for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next)
2310 if( IsEqualIID(guid, &pCData->guid)) break;
2311 if(TRACE_ON(typelib)){
2312 char xriid[50];
2313 WINE_StringFromCLSID((LPCLSID)guid,xriid);
2314 TRACE_(typelib)("(%p) guid %s %s found!x)\n",This,xriid,
2315 pCData? "" : "NOT");
2317 if(pCData){
2318 VariantInit( pVarVal);
2319 VariantCopy( pVarVal, &pCData->data);
2320 return S_OK;
2322 return E_INVALIDARG; /* FIXME: correct? */
2325 /* ITypeInfo2::GetDocumentation2
2327 * Retrieves the documentation string, the complete Help file name and path,
2328 * the localization context to use, and the context ID for the library Help
2329 * topic in the Help file.
2332 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( ITypeInfo * iface,
2333 MEMBERID memid, LCID lcid, BSTR *pbstrHelpString,
2334 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
2336 ICOM_THIS( TLBTypeInfo, iface);
2337 TLBFuncDesc * pFDesc;
2338 TLBVarDesc * pVDesc;
2339 TRACE_(typelib)("(%p) memid %ld lcid(0x%lx) HelpString(%p) "
2340 "HelpStringContext(%p) HelpStringDll(%p)\n",
2341 This, memid, lcid, pbstrHelpString, pdwHelpStringContext,
2342 pbstrHelpStringDll );
2343 /* the help string should be obtained from the helpstringdll,
2344 * using the _DLLGetDocumentation function, based on the supplied
2345 * lcid. Nice to do sometime...
2347 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
2348 if(pbstrHelpString)
2349 *pbstrHelpString=TLB_DupAtoBstr(This->Name);
2350 if(pdwHelpStringContext)
2351 *pdwHelpStringContext=This->dwHelpStringContext;
2352 if(pbstrHelpStringDll)
2353 *pbstrHelpStringDll=
2354 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2355 return S_OK;
2356 }else {/* for a member */
2357 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
2358 if(pFDesc->funcdesc.memid==memid){
2359 if(pbstrHelpString)
2360 *pbstrHelpString=TLB_DupAtoBstr(pFDesc->HelpString);
2361 if(pdwHelpStringContext)
2362 *pdwHelpStringContext=pFDesc->HelpStringContext;
2363 if(pbstrHelpStringDll)
2364 *pbstrHelpStringDll=
2365 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2366 return S_OK;
2368 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
2369 if(pVDesc->vardesc.memid==memid){
2370 if(pbstrHelpString)
2371 *pbstrHelpString=TLB_DupAtoBstr(pVDesc->HelpString);
2372 if(pdwHelpStringContext)
2373 *pdwHelpStringContext=pVDesc->HelpStringContext;
2374 if(pbstrHelpStringDll)
2375 *pbstrHelpStringDll=
2376 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */
2377 return S_OK;
2380 return TYPE_E_ELEMENTNOTFOUND;
2383 /* ITypeInfo2::GetAllCustData
2385 * Gets all custom data items for the Type info.
2388 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( ITypeInfo * iface,
2389 CUSTDATA *pCustData)
2391 ICOM_THIS( TLBTypeInfo, iface);
2392 TLBCustData *pCData;
2393 int i;
2394 TRACE_(typelib)("(%p) returning %d items\n", This, This->ctCustData);
2395 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
2396 if(pCustData->prgCustData ){
2397 pCustData->cCustData=This->ctCustData;
2398 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
2399 pCustData->prgCustData[i].guid=pCData->guid;
2400 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
2402 }else{
2403 ERR_(typelib)(" OUT OF MEMORY! \n");
2404 return E_OUTOFMEMORY;
2406 return S_OK;
2409 /* ITypeInfo2::GetAllFuncCustData
2411 * Gets all custom data items for the specified Function
2414 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( ITypeInfo * iface,
2415 UINT index, CUSTDATA *pCustData)
2417 ICOM_THIS( TLBTypeInfo, iface);
2418 TLBCustData *pCData;
2419 TLBFuncDesc * pFDesc;
2420 int i;
2421 TRACE_(typelib)("(%p) index %d\n", This, index);
2422 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2423 pFDesc=pFDesc->next)
2425 if(pFDesc){
2426 pCustData->prgCustData =
2427 TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM));
2428 if(pCustData->prgCustData ){
2429 pCustData->cCustData=pFDesc->ctCustData;
2430 for(i=0, pCData=pFDesc->pCustData; pCData; i++,
2431 pCData = pCData->next){
2432 pCustData->prgCustData[i].guid=pCData->guid;
2433 VariantCopy(& pCustData->prgCustData[i].varValue,
2434 & pCData->data);
2436 }else{
2437 ERR_(typelib)(" OUT OF MEMORY! \n");
2438 return E_OUTOFMEMORY;
2440 return S_OK;
2442 return TYPE_E_ELEMENTNOTFOUND;
2445 /* ITypeInfo2::GetAllParamCustData
2447 * Gets all custom data items for the Functions
2450 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo * iface,
2451 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
2453 ICOM_THIS( TLBTypeInfo, iface);
2454 TLBCustData *pCData=NULL;
2455 TLBFuncDesc * pFDesc;
2456 int i;
2457 TRACE_(typelib)("(%p) index %d\n", This, indexFunc);
2458 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
2459 pFDesc=pFDesc->next)
2461 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams){
2462 pCustData->prgCustData =
2463 TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData *
2464 sizeof(CUSTDATAITEM));
2465 if(pCustData->prgCustData ){
2466 pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData;
2467 for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData;
2468 pCData; i++, pCData = pCData->next){
2469 pCustData->prgCustData[i].guid=pCData->guid;
2470 VariantCopy(& pCustData->prgCustData[i].varValue,
2471 & pCData->data);
2473 }else{
2474 ERR_(typelib)(" OUT OF MEMORY! \n");
2475 return E_OUTOFMEMORY;
2477 return S_OK;
2479 return TYPE_E_ELEMENTNOTFOUND;
2482 /* ITypeInfo2::GetAllVarCustData
2484 * Gets all custom data items for the specified Variable
2487 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo * iface,
2488 UINT index, CUSTDATA *pCustData)
2490 ICOM_THIS( TLBTypeInfo, iface);
2491 TLBCustData *pCData;
2492 TLBVarDesc * pVDesc;
2493 int i;
2494 TRACE_(typelib)("(%p) index %d\n", This, index);
2495 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
2496 pVDesc=pVDesc->next)
2498 if(pVDesc){
2499 pCustData->prgCustData =
2500 TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM));
2501 if(pCustData->prgCustData ){
2502 pCustData->cCustData=pVDesc->ctCustData;
2503 for(i=0, pCData=pVDesc->pCustData; pCData; i++,
2504 pCData = pCData->next){
2505 pCustData->prgCustData[i].guid=pCData->guid;
2506 VariantCopy(& pCustData->prgCustData[i].varValue,
2507 & pCData->data);
2509 }else{
2510 ERR_(typelib)(" OUT OF MEMORY! \n");
2511 return E_OUTOFMEMORY;
2513 return S_OK;
2515 return TYPE_E_ELEMENTNOTFOUND;
2518 /* ITypeInfo2::GetAllImplCustData
2520 * Gets all custom data items for the specified implementation type
2523 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo * iface,
2524 UINT index, CUSTDATA *pCustData)
2526 ICOM_THIS( TLBTypeInfo, iface);
2527 TLBCustData *pCData;
2528 TLBRefType * pRDesc;
2529 int i;
2530 TRACE_(typelib)("(%p) index %d\n", This, index);
2531 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
2532 pRDesc=pRDesc->next)
2534 if(pRDesc){
2535 pCustData->prgCustData =
2536 TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM));
2537 if(pCustData->prgCustData ){
2538 pCustData->cCustData=pRDesc->ctCustData;
2539 for(i=0, pCData=pRDesc->pCustData; pCData; i++,
2540 pCData = pCData->next){
2541 pCustData->prgCustData[i].guid=pCData->guid;
2542 VariantCopy(& pCustData->prgCustData[i].varValue,
2543 & pCData->data);
2545 }else{
2546 ERR_(typelib)(" OUT OF MEMORY! \n");
2547 return E_OUTOFMEMORY;
2549 return S_OK;
2551 return TYPE_E_ELEMENTNOTFOUND;