Check the attributes of the *current* section, not only the attributes
[wine/testsucceed.git] / dlls / oleaut32 / typelib.c
blob70e5e40bde98d92c155125fa59ef8ea5520f0319
1 /*
2 * TYPELIB
4 * Copyright 1997 Marcus Meissner
5 * 1999 Rein Klazes
6 * 2000 Francois Jacques
7 * --------------------------------------------------------------------------------------
8 * Known problems (2000, Francois Jacques)
10 * - Tested using OLEVIEW (Platform SDK tool) only.
12 * - dual interface dispinterfaces. vtable-interface ITypeInfo instances are
13 * creating by doing a straight copy of the dispinterface instance and just changing
14 * its typekind. Pointed structures aren't copied - only the address of the pointers.
15 * So when you release the dispinterface, you delete the vtable-interface structures
16 * as well... fortunately, clean up of structures is not implemented.
18 * - locale stuff is partially implemented but hasn't been tested.
20 * - imported typelib should be stored together in a linked list instead of having
21 * independant TLBImpLib strucutures in each ITypeInfo. This way, imported libraries
22 * are just imported once (major optimization)
24 * - typelib file is still read it's in entirety, but it is released now.
25 * - some garbage is read from function names on some very rare occasion
27 * --------------------------------------------------------------------------------------
28 * Known problems left from previous implementation (1999, Rein Klazes) :
30 * -. Only one format of typelibs is supported
31 * -. Data structures are straightforward, but slow for look-ups.
32 * -. (related) nothing is hashed
33 * -. there are a number of stubs in ITypeLib and ITypeInfo interfaces. Most
34 * of them I don't know yet how to implement them.
35 * -. Most error return values are just guessed not checked with windows
36 * behaviour.
37 * -. didn't bother with a c++ interface
38 * -. lousy fatal error handling
39 * -. some methods just return pointers to internal data structures, this is
40 * partly laziness, partly I want to check how windows does it.
44 #include <stdlib.h>
45 #include <string.h>
46 #include <stdio.h>
47 #include <ctype.h>
48 #include "winerror.h"
49 #include "winreg.h" /* for HKEY_LOCAL_MACHINE */
50 #include "winnls.h" /* for PRIMARYLANGID */
51 #include "ole.h"
52 #include "heap.h"
53 #include "wine/obj_base.h"
54 #include "debugtools.h"
55 #include "typelib.h"
57 DEFAULT_DEBUG_CHANNEL(ole);
58 DECLARE_DEBUG_CHANNEL(typelib);
60 /****************************************************************************
61 * QueryPathOfRegTypeLib16 [TYPELIB.14]
63 * the path is "Classes\Typelib\<guid>\<major>.<minor>\<lcid>\win16\"
64 * RETURNS
65 * path of typelib
67 HRESULT WINAPI
68 QueryPathOfRegTypeLib16(
69 REFGUID guid, /* [in] referenced guid */
70 WORD wMaj, /* [in] major version */
71 WORD wMin, /* [in] minor version */
72 LCID lcid, /* [in] locale id */
73 LPBSTR16 path /* [out] path of typelib */
74 ) {
75 char xguid[80];
76 char typelibkey[100],pathname[260];
77 DWORD plen;
79 TRACE("\n");
81 if (HIWORD(guid)) {
82 sprintf( typelibkey, "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win16",
83 guid->Data1, guid->Data2, guid->Data3,
84 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
85 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7],
86 wMaj,wMin,lcid);
87 } else {
88 sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
89 FIXME("(%s,%d,%d,0x%04lx,%p),can't handle non-string guids.\n",xguid,wMaj,wMin,(DWORD)lcid,path);
90 return E_FAIL;
92 plen = sizeof(pathname);
93 if (RegQueryValueA(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) {
94 /* try again without lang specific id */
95 if (SUBLANGID(lcid))
96 return QueryPathOfRegTypeLib16(guid,wMaj,wMin,PRIMARYLANGID(lcid),path);
97 FIXME("key %s not found\n",typelibkey);
98 return E_FAIL;
100 *path = SysAllocString16(pathname);
101 return S_OK;
104 /****************************************************************************
105 * QueryPathOfRegTypeLib [OLEAUT32.164]
106 * RETURNS
107 * path of typelib
109 HRESULT WINAPI
110 QueryPathOfRegTypeLib(
111 REFGUID guid, /* [in] referenced guid */
112 WORD wMaj, /* [in] major version */
113 WORD wMin, /* [in] minor version */
114 LCID lcid, /* [in] locale id */
115 LPBSTR path ) /* [out] path of typelib */
117 /* don't need to ZeroMemory those arrays since sprintf and RegQueryValue add
118 string termination character on output strings */
120 HRESULT hr = E_FAIL;
122 DWORD dwPathLen = _MAX_PATH;
123 LCID myLCID = lcid;
125 char szXGUID[80];
126 char szTypeLibKey[100];
127 char szPath[dwPathLen];
129 if ( !HIWORD(guid) )
131 sprintf(szXGUID,
132 "<guid 0x%08lx>",
133 (DWORD) guid);
135 FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n", szXGUID, wMaj, wMin, (DWORD)lcid, path);
136 return E_FAIL;
139 while (hr != S_OK)
141 sprintf(szTypeLibKey,
142 "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win32",
143 guid->Data1, guid->Data2, guid->Data3,
144 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
145 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7],
146 wMaj,
147 wMin,
148 myLCID);
150 if (RegQueryValueA(HKEY_LOCAL_MACHINE, szTypeLibKey, szPath, &dwPathLen))
152 if (!lcid)
153 break;
154 else if (myLCID == lcid)
156 /* try with sub-langid */
157 myLCID = SUBLANGID(lcid);
159 else if (myLCID == SUBLANGID(lcid))
161 /* try with system langid */
162 myLCID = 0;
164 else
166 break;
169 else
171 DWORD len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPath, dwPathLen, NULL, 0 );
172 BSTR bstrPath = SysAllocStringLen(NULL,len);
174 MultiByteToWideChar(CP_ACP,
175 MB_PRECOMPOSED,
176 szPath,
177 dwPathLen,
178 bstrPath,
179 len);
180 *path = bstrPath;
181 hr = S_OK;
185 if (hr != S_OK)
186 TRACE_(typelib)("%s not found\n", szTypeLibKey);
188 return hr;
191 /******************************************************************************
192 * CreateTypeLib [OLEAUT32] creates a typelib
194 * RETURNS
195 * Success: S_OK
196 * Failure: Status
198 HRESULT WINAPI CreateTypeLib(
199 SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib** ppctlib
201 FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib);
202 return E_FAIL;
204 /******************************************************************************
205 * LoadTypeLib [TYPELIB.3] Loads and registers a type library
206 * NOTES
207 * Docs: OLECHAR FAR* szFile
208 * Docs: iTypeLib FAR* FAR* pptLib
210 * RETURNS
211 * Success: S_OK
212 * Failure: Status
214 HRESULT WINAPI LoadTypeLib16(
215 LPOLESTR szFile, /* [in] Name of file to load from */
216 ITypeLib** pptLib) /* [out] Pointer to pointer to loaded type library */
218 FIXME("('%s',%p): stub\n",debugstr_w((LPWSTR)szFile),pptLib);
220 if (pptLib!=0)
221 *pptLib=0;
223 return E_FAIL;
226 /******************************************************************************
227 * LoadTypeLib [OLEAUT32.161]
228 * Loads and registers a type library
229 * NOTES
230 * Docs: OLECHAR FAR* szFile
231 * Docs: iTypeLib FAR* FAR* pptLib
233 * RETURNS
234 * Success: S_OK
235 * Failure: Status
237 int TLB_ReadTypeLib(PCHAR file, ITypeLib2 **ppTypelib);
239 HRESULT WINAPI LoadTypeLib(
240 const OLECHAR *szFile,/* [in] Name of file to load from */
241 ITypeLib * *pptLib) /* [out] Pointer to pointer to loaded type library */
243 TRACE("\n");
244 return LoadTypeLibEx(szFile, REGKIND_DEFAULT, pptLib);
247 /******************************************************************************
248 * LoadTypeLibEx [OLEAUT32.183]
249 * Loads and optionally registers a type library
251 * RETURNS
252 * Success: S_OK
253 * Failure: Status
255 HRESULT WINAPI LoadTypeLibEx(
256 LPCOLESTR szFile, /* [in] Name of file to load from */
257 REGKIND regkind, /* [in] Specify kind of registration */
258 ITypeLib **pptLib) /* [out] Pointer to pointer to loaded type library */
260 LPSTR p;
261 HRESULT res;
262 TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib);
264 p=HEAP_strdupWtoA(GetProcessHeap(),0,szFile);
266 if(regkind != REGKIND_NONE)
267 FIXME ("registration of typelibs not supported yet!\n");
269 res= TLB_ReadTypeLib(p, (ITypeLib2**)pptLib);
270 HeapFree(GetProcessHeap(),0,p);
271 TRACE(" returns %08lx\n",res);
273 return res;
276 /******************************************************************************
277 * LoadRegTypeLib [OLEAUT32.162]
279 HRESULT WINAPI LoadRegTypeLib(
280 REFGUID rguid, /* [in] referenced guid */
281 WORD wVerMajor, /* [in] major version */
282 WORD wVerMinor, /* [in] minor version */
283 LCID lcid, /* [in] locale id */
284 ITypeLib **ppTLib) /* [out] path of typelib */
286 BSTR bstr=NULL;
287 HRESULT res=QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor, lcid, &bstr);
289 if(SUCCEEDED(res))
291 res= LoadTypeLib(bstr, ppTLib);
292 SysFreeString(bstr);
295 TRACE("(IID: %s) load %s (%p)\n",debugstr_guid(rguid), SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);
297 return res;
301 /******************************************************************************
302 * RegisterTypeLib [OLEAUT32.163]
303 * Adds information about a type library to the System Registry
304 * NOTES
305 * Docs: ITypeLib FAR * ptlib
306 * Docs: OLECHAR FAR* szFullPath
307 * Docs: OLECHAR FAR* szHelpDir
309 * RETURNS
310 * Success: S_OK
311 * Failure: Status
313 HRESULT WINAPI RegisterTypeLib(
314 ITypeLib * ptlib, /* [in] Pointer to the library*/
315 OLECHAR * szFullPath, /* [in] full Path of the library*/
316 OLECHAR * szHelpDir) /* [in] dir to the helpfile for the library,
317 may be NULL*/
318 { FIXME("(%p,%s,%s): stub\n",ptlib, debugstr_w(szFullPath),debugstr_w(szHelpDir));
319 return S_OK; /* FIXME: pretend everything is OK */
323 /******************************************************************************
324 * UnRegisterTypeLib [OLEAUT32.186]
325 * Removes information about a type library from the System Registry
326 * NOTES
328 * RETURNS
329 * Success: S_OK
330 * Failure: Status
332 HRESULT WINAPI UnRegisterTypeLib(
333 REFGUID libid, /* [in] Guid of the library */
334 WORD wVerMajor, /* [in] major version */
335 WORD wVerMinor, /* [in] minor version */
336 LCID lcid, /* [in] locale id */
337 SYSKIND syskind)
339 TRACE("(IID: %s): stub\n",debugstr_guid(libid));
340 return S_OK; /* FIXME: pretend everything is OK */
343 /****************************************************************************
344 * OaBuildVersion (TYPELIB.15)
346 * known TYPELIB.DLL versions:
348 * OLE 2.01 no OaBuildVersion() avail 1993 -- ---
349 * OLE 2.02 1993-94 02 3002
350 * OLE 2.03 23 730
351 * OLE 2.03 03 3025
352 * OLE 2.03 W98 SE orig. file !! 1993-95 10 3024
353 * OLE 2.1 NT 1993-95 ?? ???
354 * OLE 2.3.1 W95 23 700
355 * OLE2 4.0 NT4SP6 1993-98 40 4277
357 DWORD WINAPI OaBuildVersion16(void)
359 /* FIXME: I'd like to return the highest currently known version value
360 * in case the user didn't force a --winver, but I don't know how
361 * to retrieve the "versionForced" info from misc/version.c :(
362 * (this would be useful in other places, too) */
363 FIXME("Please report to a.mohr@mailto.de if you get version error messages !\n");
364 switch(GetVersion() & 0x8000ffff) /* mask off build number */
366 case 0x80000a03: /* WIN31 */
367 return MAKELONG(3027, 3); /* WfW 3.11 */
368 case 0x80000004: /* WIN95 */
369 return MAKELONG(700, 23); /* Win95A */
370 case 0x80000a04: /* WIN98 */
371 return MAKELONG(3024, 10); /* W98 SE */
372 case 0x00000004: /* NT4 */
373 return MAKELONG(4277, 40); /* NT4 SP6 */
374 default:
375 FIXME("Version value not known yet. Please investigate it !");
376 return 0;
380 /* for better debugging info leave the static out for the time being */
381 #define static
383 /*======================= ITypeLib implementation =======================*/
385 typedef struct tagTLBCustData
387 GUID guid;
388 VARIANT data;
389 struct tagTLBCustData* next;
390 } TLBCustData;
392 /* data structure for import typelibs */
393 typedef struct tagTLBImpLib
395 int offset; /* offset in the file */
396 GUID guid; /* libid */
397 BSTR name; /* name; */
399 LCID lcid; /* lcid of imported typelib */
401 WORD wVersionMajor; /* major version number */
402 WORD wVersionMinor; /* minor version number */
404 struct tagITypeLibImpl *pImpTypeLib; /* pointer to loaded typelib */
405 struct tagTLBImpLib * next;
406 } TLBImpLib;
408 /* internal ITypeLib data */
409 typedef struct tagITypeLibImpl
411 ICOM_VFIELD(ITypeLib2);
412 UINT ref;
413 TLIBATTR LibAttr; /* guid,lcid,syskind,version,flags */
415 /* strings can be stored in tlb as multibyte strings BUT they are *always*
416 * exported to the application as a UNICODE string.
418 BSTR Name;
419 BSTR DocString;
420 BSTR HelpFile;
421 BSTR HelpStringDll;
422 unsigned long dwHelpContext;
423 int TypeInfoCount; /* nr of typeinfo's in librarry */
424 struct tagITypeInfoImpl *pTypeInfo; /* linked list of type info data */
425 int ctCustData; /* number of items in cust data list */
426 TLBCustData * pCustData; /* linked list to cust data; */
427 TLBImpLib * pImpLibs; /* linked list to all imported typelibs */
428 TYPEDESC * pTypeDesc; /* array of TypeDescriptions found in the libary */
429 } ITypeLibImpl;
431 static struct ICOM_VTABLE(ITypeLib2) tlbvt;
433 /* ITypeLib methods */
434 static ITypeLib2* ITypeLib2_Constructor(LPVOID pLib, DWORD dwTLBLength);
436 /*======================= ITypeInfo implementation =======================*/
438 /* data for refernced types in a coclass, or an inherited interface */
439 typedef struct tagTLBRefType
441 GUID guid; /* guid of the referenced type */
442 /* (important if its a imported type) */
443 HREFTYPE reference;
444 int flags;
445 int ctCustData;
446 TLBCustData * pCustData;/* linked list to custom data; */
447 TLBImpLib *pImpTLInfo;
448 struct tagTLBRefType * next;
449 } TLBRefType;
451 /* internal Parameter data */
452 typedef struct tagTLBParDesc
454 BSTR Name;
455 int ctCustData;
456 TLBCustData * pCustData; /* linked list to cust data; */
457 TLBRefType * pRefType; /* linked list to referenced types */
458 } TLBParDesc;
460 /* internal Function data */
461 typedef struct tagTLBFuncDesc
463 FUNCDESC funcdesc; /* lots of info on the function and its attributes. */
464 BSTR Name; /* the name of this function */
465 TLBParDesc *pParamDesc; /* array with name and custom data */
466 int helpcontext;
467 int HelpStringContext;
468 BSTR HelpString;
469 BSTR Entry; /* if its Hiword==0, it numeric; -1 is not present*/
470 int ctCustData;
471 TLBCustData * pCustData; /* linked list to cust data; */
472 struct tagTLBFuncDesc * next;
473 } TLBFuncDesc;
475 /* internal Variable data */
476 typedef struct tagTLBVarDesc
478 VARDESC vardesc; /* lots of info on the variable and its attributes. */
479 BSTR Name; /* the name of this variable */
480 int HelpContext;
481 int HelpStringContext; /* fixme: where? */
482 BSTR HelpString;
483 int ctCustData;
484 TLBCustData * pCustData;/* linked list to cust data; */
485 struct tagTLBVarDesc * next;
486 } TLBVarDesc;
488 /* internal TypeInfo data */
489 typedef struct tagITypeInfoImpl
491 ICOM_VFIELD(ITypeInfo2);
492 UINT ref;
493 TYPEATTR TypeAttr ; /* _lots_ of type information. */
494 ITypeLibImpl * pTypeLib; /* back pointer to typelib */
495 int index; /* index in this typelib; */
496 /* type libs seem to store the doc strings in ascii
497 * so why should we do it in unicode?
499 BSTR Name;
500 BSTR DocString;
501 unsigned long dwHelpContext;
502 unsigned long dwHelpStringContext;
504 /* functions */
505 TLBFuncDesc * funclist; /* linked list with function descriptions */
507 /* variables */
508 TLBVarDesc * varlist; /* linked list with variable descriptions */
510 /* Implemented Interfaces */
511 TLBRefType * impltypelist;
512 int ctCustData;
513 TLBCustData * pCustData; /* linked list to cust data; */
514 struct tagITypeInfoImpl * next;
515 } ITypeInfoImpl;
517 static struct ICOM_VTABLE(ITypeInfo2) tinfvt;
519 static ITypeInfo2 * WINAPI ITypeInfo_Constructor();
521 typedef struct tagTLBContext
523 unsigned int oStart; /* start of TLB in file */
524 unsigned int pos; /* current pos */
525 unsigned int length; /* total length */
526 void *mapping; /* memory mapping */
527 TLBSegDir * pTblDir;
528 ITypeLibImpl* pLibInfo;
529 } TLBContext;
532 static void TLB_DoRefType(TLBContext *pcx, int offset, TLBRefType ** pprtd);
535 debug
537 static void dump_TLBFuncDesc(TLBFuncDesc * pfd)
539 while (pfd)
541 TRACE("%s(%u)\n", debugstr_w(pfd->Name), pfd->funcdesc.cParams);
542 pfd = pfd->next;
545 static void dump_TLBVarDesc(TLBVarDesc * pvd)
547 while (pvd)
549 TRACE("%s\n", debugstr_w(pvd->Name));
550 pvd = pvd->next;
553 static void dump_TLBRefType(TLBRefType * prt)
555 while (prt)
557 TRACE("%s\n", debugstr_guid(&(prt->guid)));
558 TRACE(" href:0x%08lx\n", prt->reference);
559 prt = prt->next;
563 static void dump_Variant(VARIANT * pvar)
565 TRACE("%p %x\n", pvar, pvar?pvar->vt:0 );
566 if(!pvar) return;
568 if (pvar->vt & VT_BYREF)
569 return dump_Variant(pvar->u.pvarVal);
572 static void dump_DispParms(DISPPARAMS * pdp)
574 dump_Variant( pdp->rgvarg);
575 TRACE("args=%u named args=%u\n", pdp->cArgs, pdp->cNamedArgs);
578 static char * typekind_desc[] =
580 "TKIND_ENUM",
581 "TKIND_RECORD",
582 "TKIND_MODULE",
583 "TKIND_INTERFACE",
584 "TKIND_DISPATCH",
585 "TKIND_COCLASS",
586 "TKIND_ALIAS",
587 "TKIND_UNION",
588 "TKIND_MAX"
591 static void dump_TypeInfo(ITypeInfoImpl * pty)
593 TRACE("%p ref=%u\n", pty, pty->ref);
594 TRACE("attr:%s\n", debugstr_guid(&(pty->TypeAttr.guid)));
595 TRACE("kind:%s\n", typekind_desc[pty->TypeAttr.typekind]);
596 TRACE("fct:%u var:%u impl:%u\n",
597 pty->TypeAttr.cFuncs, pty->TypeAttr.cVars, pty->TypeAttr.cImplTypes);
598 TRACE("parent tlb:%p index in TLB:%u\n",pty->pTypeLib, pty->index);
599 TRACE("%s %s\n", debugstr_w(pty->Name), debugstr_w(pty->DocString));
600 dump_TLBFuncDesc(pty->funclist);
601 dump_TLBVarDesc(pty->varlist);
602 dump_TLBRefType(pty->impltypelist);
605 static TYPEDESC stndTypeDesc[VT_LPWSTR+1]=
607 /* VT_LPWSTR is largest type that */
608 /* may appear in type description*/
609 {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
610 {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
611 {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
612 {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
613 {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
614 {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
615 {{0},30},{{0},31}
618 static void TLB_abort()
620 DebugBreak();
622 static void * TLB_Alloc(unsigned size)
624 void * ret;
625 if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){
626 /* FIXME */
627 ERR("cannot allocate memory\n");
629 return ret;
632 static void TLB_Free(void * ptr)
634 HeapFree(GetProcessHeap(), 0, ptr);
636 /* read function */
637 DWORD TLB_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
639 TRACE("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n",
640 pcx->pos, count, pcx->oStart, pcx->length, where);
642 if (where != DO_NOT_SEEK)
644 where += pcx->oStart;
645 if (where > pcx->length)
647 /* FIXME */
648 ERR("seek beyond end (%ld/%d)\n", where, pcx->length );
649 TLB_abort();
651 pcx->pos = where;
653 if (pcx->pos + count > pcx->length) count = pcx->length - pcx->pos;
654 memcpy( buffer, (char *)pcx->mapping + pcx->pos, count );
655 pcx->pos += count;
656 return count;
659 static void TLB_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
661 TRACE("%s\n", debugstr_guid(pGuid));
663 if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){
664 memset(pGuid,0, sizeof(GUID));
665 return;
667 TLB_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset );
670 BSTR TLB_ReadName( TLBContext *pcx, int offset)
672 char * name;
673 TLBNameIntro niName;
674 int lengthInChars;
675 WCHAR* pwstring = NULL;
676 BSTR bstrName = NULL;
678 TLB_Read(&niName, sizeof(niName), pcx,
679 pcx->pTblDir->pNametab.offset+offset);
680 niName.namelen &= 0xFF; /* FIXME: correct ? */
681 name=TLB_Alloc((niName.namelen & 0xff) +1);
682 TLB_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK);
683 name[niName.namelen & 0xff]='\0';
685 lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
686 name, -1, NULL, NULL);
688 /* no invalid characters in string */
689 if (lengthInChars)
691 pwstring = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*lengthInChars);
693 /* don't check for invalid character since this has been done previously */
694 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, pwstring, lengthInChars);
696 bstrName = SysAllocStringLen(pwstring, lengthInChars);
697 lengthInChars = SysStringLen(bstrName);
698 HeapFree(GetProcessHeap(), 0, pwstring);
701 TRACE("%s %d\n", debugstr_w(bstrName), lengthInChars);
702 return bstrName;
705 BSTR TLB_ReadString( TLBContext *pcx, int offset)
707 char * string;
708 INT16 length;
709 int lengthInChars;
710 BSTR bstr = NULL;
712 if(offset<0) return NULL;
713 TLB_Read(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
714 if(length <= 0) return 0;
715 string=TLB_Alloc(length +1);
716 TLB_Read(string, length, pcx, DO_NOT_SEEK);
717 string[length]='\0';
719 lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
720 string, -1, NULL, NULL);
722 /* no invalid characters in string */
723 if (lengthInChars)
725 WCHAR* pwstring = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*lengthInChars);
727 /* don't check for invalid character since this has been done previously */
728 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, pwstring, lengthInChars);
730 bstr = SysAllocStringLen(pwstring, lengthInChars);
731 lengthInChars = SysStringLen(bstr);
732 HeapFree(GetProcessHeap(), 0, pwstring);
735 TRACE("%s %d\n", debugstr_w(bstr), lengthInChars);
736 return bstr;
739 * read a value and fill a VARIANT structure
741 static void TLB_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
743 int size;
745 TRACE("\n");
747 if(offset <0) { /* data is packed in here */
748 pVar->vt = (offset & 0x7c000000 )>> 26;
749 V_UNION(pVar, iVal) = offset & 0xffff;
750 return;
752 TLB_Read(&(pVar->vt), sizeof(VARTYPE), pcx,
753 pcx->pTblDir->pCustData.offset + offset );
754 TRACE("Vartype = %x\n", pVar->vt);
755 switch(pVar->vt){
756 case VT_EMPTY: /* FIXME: is this right? */
757 case VT_NULL: /* FIXME: is this right? */
758 case VT_I2 : /* this should not happen */
759 case VT_I4 :
760 case VT_R4 :
761 case VT_ERROR :
762 case VT_BOOL :
763 case VT_I1 :
764 case VT_UI1 :
765 case VT_UI2 :
766 case VT_UI4 :
767 case VT_INT :
768 case VT_UINT :
769 case VT_VOID : /* FIXME: is this right? */
770 case VT_HRESULT :
771 size=4; break;
772 case VT_R8 :
773 case VT_CY :
774 case VT_DATE :
775 case VT_I8 :
776 case VT_UI8 :
777 case VT_DECIMAL : /* FIXME: is this right? */
778 case VT_FILETIME :
779 size=8;break;
780 /* pointer types with known behaviour */
781 case VT_BSTR :{
782 char * ptr;
783 TLB_Read(&size, sizeof(INT), pcx, DO_NOT_SEEK );
784 if(size <= 0) {
785 FIXME("BSTR length = %d?\n", size);
786 } else {
787 ptr=TLB_Alloc(size);/* allocate temp buffer */
788 TLB_Read(ptr, size, pcx, DO_NOT_SEEK); /* read string (ANSI) */
789 V_UNION(pVar, bstrVal)=SysAllocStringLen(NULL,size);
790 /* FIXME: do we need a AtoW conversion here? */
791 V_UNION(pVar, bstrVal[size])=L'\0';
792 while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
793 TLB_Free(ptr);
796 size=-4; break;
797 /* FIXME: this will not work AT ALL when the variant contains a pointer */
798 case VT_DISPATCH :
799 case VT_VARIANT :
800 case VT_UNKNOWN :
801 case VT_PTR :
802 case VT_SAFEARRAY :
803 case VT_CARRAY :
804 case VT_USERDEFINED :
805 case VT_LPSTR :
806 case VT_LPWSTR :
807 case VT_BLOB :
808 case VT_STREAM :
809 case VT_STORAGE :
810 case VT_STREAMED_OBJECT :
811 case VT_STORED_OBJECT :
812 case VT_BLOB_OBJECT :
813 case VT_CF :
814 case VT_CLSID :
815 default:
816 size=0;
817 FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
818 pVar->vt);
821 if(size>0) /* (big|small) endian correct? */
822 TLB_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK );
823 return;
826 * create a linked list with custom data
828 static int TLB_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
830 TLBCDGuid entry;
831 TLBCustData* pNew;
832 int count=0;
834 TRACE("\n");
836 while(offset >=0){
837 count++;
838 pNew=TLB_Alloc(sizeof(TLBCustData));
839 TLB_Read(&entry, sizeof(entry), pcx,
840 pcx->pTblDir->pCDGuids.offset+offset);
841 TLB_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
842 TLB_ReadValue(&(pNew->data), entry.DataOffset, pcx);
843 /* add new custom data at head of the list */
844 pNew->next=*ppCustData;
845 *ppCustData=pNew;
846 offset = entry.next;
848 return count;
851 static void TLB_GetTdesc(TLBContext *pcx, INT type,TYPEDESC * pTd )
853 if(type <0)
854 pTd->vt=type & VT_TYPEMASK;
855 else
856 *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
858 TRACE("vt type = %X\n", pTd->vt);
860 static void TLB_DoFuncs(TLBContext *pcx, int cFuncs, int cVars,
861 int offset, TLBFuncDesc ** pptfd)
864 * member information is stored in a data structure at offset
865 * indicated by the memoffset field of the typeinfo structure
866 * There are several distinctive parts.
867 * the first part starts with a field that holds the total length
868 * of this (first) part excluding this field. Then follow the records,
869 * for each member there is one record.
871 * First entry is always the length of the record (excluding this
872 * length word).
873 * Rest of the record depends on the type of the member. If there is
874 * a field indicating the member type (function variable intereface etc)
875 * I have not found it yet. At this time we depend on the information
876 * in the type info and the usual order how things are stored.
878 * Second follows an array sized nrMEM*sizeof(INT) with a memeber id
879 * for each member;
881 * Third is a equal sized array with file offsets to the name entry
882 * of each member.
884 * Forth and last (?) part is an array with offsets to the records in the
885 * first part of this file segment.
888 int infolen, nameoffset, reclength, nrattributes;
889 char recbuf[512];
890 TLBFuncRecord * pFuncRec=(TLBFuncRecord *) recbuf;
891 int i, j;
892 int recoffset=offset+sizeof(INT);
894 TRACE("\n");
896 TLB_Read(&infolen,sizeof(INT), pcx, offset);
897 for(i=0;i<cFuncs;i++){
898 *pptfd=TLB_Alloc(sizeof(TLBFuncDesc));
899 /* name, eventually add to a hash table */
900 TLB_Read(&nameoffset, sizeof(INT), pcx,
901 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
902 (*pptfd)->Name=TLB_ReadName(pcx, nameoffset);
903 /* read the function information record */
904 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
905 reclength &=0x1ff;
906 TLB_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
907 /* do the attributes */
908 nrattributes=(reclength-pFuncRec->nrargs*3*sizeof(int)-0x18)
909 /sizeof(int);
910 if(nrattributes>0){
911 (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
912 if(nrattributes>1){
913 (*pptfd)->HelpString = TLB_ReadString(pcx,
914 pFuncRec->OptAttr[1]) ;
915 if(nrattributes>2){
916 if(pFuncRec->FKCCIC & 0x2000)
917 (*pptfd)->Entry = (WCHAR*) pFuncRec->OptAttr[2] ;
918 else
919 (*pptfd)->Entry = TLB_ReadString(pcx,
920 pFuncRec->OptAttr[2]);
921 if(nrattributes>5 )
922 (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;
923 if(nrattributes>6 && pFuncRec->FKCCIC & 0x80){
924 TLB_CustData(pcx, pFuncRec->OptAttr[6],
925 &(*pptfd)->pCustData);
930 /* fill the FuncDesc Structure */
931 TLB_Read(&(*pptfd)->funcdesc.memid, sizeof(INT), pcx,
932 offset + infolen + ( i + 1) * sizeof(INT));
933 (*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
934 (*pptfd)->funcdesc.invkind = ((pFuncRec->FKCCIC) >>3) & 0xF;
935 (*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >>8 & 0xF;
936 (*pptfd)->funcdesc.cParams = pFuncRec->nrargs ;
937 (*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ;
938 (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ;
939 (*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
940 TLB_GetTdesc(pcx, pFuncRec->DataType,
941 &(*pptfd)->funcdesc.elemdescFunc.tdesc) ;
943 /* do the parameters/arguments */
944 if(pFuncRec->nrargs){
945 TLBParameterInfo paraminfo;
946 (*pptfd)->funcdesc.lprgelemdescParam=
947 TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
948 (*pptfd)->pParamDesc=TLB_Alloc(pFuncRec->nrargs *
949 sizeof(TLBParDesc));
951 TLB_Read(&paraminfo,sizeof(paraminfo), pcx, recoffset+reclength -
952 pFuncRec->nrargs * sizeof(TLBParameterInfo));
953 for(j=0;j<pFuncRec->nrargs;j++){
954 TYPEDESC* lpArgTypeDesc = 0;
956 TLB_GetTdesc(pcx, paraminfo.DataType,
957 &(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc) ;
958 V_UNION(&((*pptfd)->funcdesc.lprgelemdescParam[j]),
959 paramdesc.wParamFlags) = paraminfo.Flags;
960 (*pptfd)->pParamDesc[j].Name=(void *)paraminfo.oName;
962 /* SEEK value = jump to offset, from there jump to the end of record,
963 * go back by (j-1) arguments
965 TLB_Read(&paraminfo,sizeof(TLBParameterInfo), pcx,
966 recoffset+reclength -
967 ((pFuncRec->nrargs - j - 1) * sizeof(TLBParameterInfo)));
969 lpArgTypeDesc = & ((*pptfd)->funcdesc.lprgelemdescParam[j].tdesc) ;
971 while (lpArgTypeDesc != NULL)
973 switch (lpArgTypeDesc->vt)
975 case VT_PTR:
976 lpArgTypeDesc = lpArgTypeDesc->u.lptdesc;
977 break;
979 case VT_CARRAY:
980 lpArgTypeDesc = & (lpArgTypeDesc->u.lpadesc->tdescElem);
981 break;
983 case VT_USERDEFINED:
984 (*pptfd)->pParamDesc[j].pRefType = TLB_Alloc(sizeof(TLBRefType));
985 TLB_DoRefType(pcx, lpArgTypeDesc->u.hreftype, &((*pptfd)->pParamDesc[j].pRefType));
986 lpArgTypeDesc = NULL;
987 break;
989 default:
990 lpArgTypeDesc = NULL;
994 /* second time around */
995 for(j=0;j<pFuncRec->nrargs;j++){
996 /* name */
997 (*pptfd)->pParamDesc[j].Name=
998 TLB_ReadName(pcx, (int)(*pptfd)->pParamDesc[j].Name);
999 /* default value */
1000 if((PARAMFLAG_FHASDEFAULT & V_UNION(&((*pptfd)->funcdesc.
1001 lprgelemdescParam[j]),paramdesc.wParamFlags)) &&
1002 ((pFuncRec->FKCCIC) & 0x1000)){
1003 INT *pInt=(INT *)((char *)pFuncRec + reclength -
1004 (pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
1005 PARAMDESC * pParamDesc= &V_UNION(&((*pptfd)->funcdesc.
1006 lprgelemdescParam[j]),paramdesc);
1007 pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
1008 pParamDesc->pparamdescex->cBytes= sizeof(PARAMDESCEX);
1009 TLB_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
1010 pInt[j], pcx);
1012 /* custom info */
1013 if(nrattributes>7+j && pFuncRec->FKCCIC & 0x80)
1014 TLB_CustData(pcx, pFuncRec->OptAttr[7+j],
1015 &(*pptfd)->pParamDesc[j].pCustData);
1018 /* scode is not used: archaic win16 stuff FIXME: right? */
1019 (*pptfd)->funcdesc.cScodes = 0 ;
1020 (*pptfd)->funcdesc.lprgscode = NULL ;
1021 pptfd=&((*pptfd)->next);
1022 recoffset += reclength;
1025 static void TLB_DoVars(TLBContext *pcx, int cFuncs, int cVars,
1026 int offset, TLBVarDesc ** pptvd)
1028 int infolen, nameoffset, reclength;
1029 char recbuf[256];
1030 TLBVarRecord * pVarRec=(TLBVarRecord *) recbuf;
1031 int i;
1032 int recoffset;
1034 TRACE("\n");
1036 TLB_Read(&infolen,sizeof(INT), pcx, offset);
1037 TLB_Read(&recoffset,sizeof(INT), pcx, offset + infolen +
1038 ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
1039 recoffset += offset+sizeof(INT);
1040 for(i=0;i<cVars;i++){
1041 *pptvd=TLB_Alloc(sizeof(TLBVarDesc));
1042 /* name, eventually add to a hash table */
1043 TLB_Read(&nameoffset, sizeof(INT), pcx,
1044 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
1045 (*pptvd)->Name=TLB_ReadName(pcx, nameoffset);
1046 /* read the variable information record */
1047 TLB_Read(&reclength, sizeof(INT), pcx, recoffset);
1048 reclength &=0xff;
1049 TLB_Read(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
1050 /* Optional data */
1051 if(reclength >(6*sizeof(INT)) )
1052 (*pptvd)->HelpContext=pVarRec->HelpContext;
1053 if(reclength >(7*sizeof(INT)) )
1054 (*pptvd)->HelpString = TLB_ReadString(pcx, pVarRec->oHelpString) ;
1055 if(reclength >(8*sizeof(INT)) )
1056 if(reclength >(9*sizeof(INT)) )
1057 (*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
1058 /* fill the VarDesc Structure */
1059 TLB_Read(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
1060 offset + infolen + ( i + 1) * sizeof(INT));
1061 (*pptvd)->vardesc.varkind = pVarRec->VarKind;
1062 (*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
1063 TLB_GetTdesc(pcx, pVarRec->DataType,
1064 &(*pptvd)->vardesc.elemdescVar.tdesc) ;
1065 /* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) fixme?? */
1066 if(pVarRec->VarKind == VAR_CONST ){
1067 V_UNION(&((*pptvd)->vardesc),lpvarValue)=TLB_Alloc(sizeof(VARIANT));
1068 TLB_ReadValue(V_UNION(&((*pptvd)->vardesc),lpvarValue),
1069 pVarRec->OffsValue, pcx);
1070 }else
1071 V_UNION(&((*pptvd)->vardesc),oInst)=pVarRec->OffsValue;
1072 pptvd=&((*pptvd)->next);
1073 recoffset += reclength;
1076 /* fill in data for a hreftype (offset). When the refernced type is contained
1077 * in the typelib, its just an (file) offset in the type info base dir.
1078 * If comes from import, its an offset+1 in the ImpInfo table
1079 * */
1080 static void TLB_DoRefType(TLBContext *pcx,
1081 int offset, TLBRefType ** pprtd)
1083 int j;
1085 TRACE("TLB context %p, TLB offset %x\n", pcx, offset);
1087 if(!HREFTYPE_INTHISFILE( offset)) {
1088 /* external typelib */
1089 TLBImpInfo impinfo;
1090 TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs);
1092 TRACE("offset %x, masked offset %x\n", offset, offset + (offset & 0xfffffffc));
1094 TLB_Read(&impinfo, sizeof(impinfo), pcx,
1095 pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
1096 for(j=0;pImpLib;j++){ /* search the known offsets of all import libraries */
1097 if(pImpLib->offset==impinfo.oImpFile) break;
1098 pImpLib=pImpLib->next;
1100 if(pImpLib){
1101 (*pprtd)->reference=offset;
1102 (*pprtd)->pImpTLInfo = pImpLib;
1103 TLB_ReadGuid(&(*pprtd)->guid, impinfo.oGuid, pcx);
1104 }else{
1105 ERR("Cannot find a reference\n");
1106 (*pprtd)->reference=-1;
1107 (*pprtd)->pImpTLInfo=(void *)-1;
1109 }else{
1110 /* in this typelib */
1111 (*pprtd)->reference=offset;
1112 (*pprtd)->pImpTLInfo=(void *)-2;
1116 /* process Implemented Interfaces of a com class */
1117 static void TLB_DoImplTypes(TLBContext *pcx, int count,
1118 int offset, TLBRefType ** pprtd)
1120 int i;
1121 TLBRefRecord refrec;
1123 TRACE("\n");
1125 for(i=0;i<count;i++){
1126 if(offset<0) break; /* paranoia */
1127 *pprtd=TLB_Alloc(sizeof(TLBRefType));
1128 TLB_Read(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
1129 TLB_DoRefType(pcx, refrec.reftype, pprtd);
1130 (*pprtd)->flags=refrec.flags;
1131 (*pprtd)->ctCustData=
1132 TLB_CustData(pcx, refrec.oCustData, &(*pprtd)->pCustData);
1133 offset=refrec.onext;
1134 pprtd=&((*pprtd)->next);
1138 * process a typeinfo record
1140 ITypeInfoImpl * TLB_DoTypeInfo(
1141 TLBContext *pcx,
1142 int count,
1143 ITypeLibImpl * pLibInfo)
1145 TLBTypeInfoBase tiBase;
1146 ITypeInfoImpl *ptiRet;
1148 TRACE("count=%u\n", count);
1150 ptiRet = (ITypeInfoImpl*) ITypeInfo_Constructor();
1151 TLB_Read(&tiBase, sizeof(tiBase) ,pcx ,
1152 pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
1153 /* this where we are coming from */
1154 ptiRet->pTypeLib = pLibInfo;
1155 ptiRet->index=count;
1156 /* fill in the typeattr fields */
1157 TLB_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx);
1158 ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid; /* FIXME: correct? */
1159 ptiRet->TypeAttr.memidConstructor=MEMBERID_NIL ;/* FIXME */
1160 ptiRet->TypeAttr.memidDestructor=MEMBERID_NIL ; /* FIXME */
1161 ptiRet->TypeAttr.lpstrSchema=NULL; /* reserved */
1162 ptiRet->TypeAttr.cbSizeInstance=tiBase.size;
1163 ptiRet->TypeAttr.typekind=tiBase.typekind & 0xF;
1164 ptiRet->TypeAttr.cFuncs=LOWORD(tiBase.cElement);
1165 ptiRet->TypeAttr.cVars=HIWORD(tiBase.cElement);
1166 ptiRet->TypeAttr.cbAlignment=(tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */
1167 ptiRet->TypeAttr.wTypeFlags=tiBase.flags;
1168 ptiRet->TypeAttr.wMajorVerNum=LOWORD(tiBase.version);
1169 ptiRet->TypeAttr.wMinorVerNum=HIWORD(tiBase.version);
1170 ptiRet->TypeAttr.cImplTypes=tiBase.cImplTypes;
1171 ptiRet->TypeAttr.cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
1172 if(ptiRet->TypeAttr.typekind == TKIND_ALIAS)
1173 TLB_GetTdesc(pcx, tiBase.datatype1,
1174 &ptiRet->TypeAttr.tdescAlias) ;
1176 /* FIXME: */
1177 /* IDLDESC idldescType; *//* never saw this one != zero */
1179 /* name, eventually add to a hash table */
1180 ptiRet->Name=TLB_ReadName(pcx, tiBase.NameOffset);
1181 TRACE("reading %s\n", debugstr_w(ptiRet->Name));
1182 /* help info */
1183 ptiRet->DocString=TLB_ReadString(pcx, tiBase.docstringoffs);
1184 ptiRet->dwHelpStringContext=tiBase.helpstringcontext;
1185 ptiRet->dwHelpContext=tiBase.helpcontext;
1186 /* note: InfoType's Help file and HelpStringDll come from the containing
1187 * library. Further HelpString and Docstring appear to be the same thing :(
1189 /* functions */
1190 if(ptiRet->TypeAttr.cFuncs >0 )
1191 TLB_DoFuncs(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
1192 tiBase.memoffset, & ptiRet->funclist);
1193 /* variables */
1194 if(ptiRet->TypeAttr.cVars >0 )
1195 TLB_DoVars(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars,
1196 tiBase.memoffset, & ptiRet->varlist);
1197 if(ptiRet->TypeAttr.cImplTypes >0 ){
1198 switch(ptiRet->TypeAttr.typekind)
1200 case TKIND_COCLASS:
1201 TLB_DoImplTypes(pcx, ptiRet->TypeAttr.cImplTypes ,
1202 tiBase.datatype1, & ptiRet->impltypelist);
1203 break;
1204 case TKIND_DISPATCH:
1205 ptiRet->impltypelist=TLB_Alloc(sizeof(TLBRefType));
1207 if (tiBase.datatype1 != -1)
1209 TLB_DoRefType(pcx, tiBase.datatype1, & ptiRet->impltypelist);
1211 else
1213 char* szStdOle = "stdole2.tlb\0";
1214 int nStdOleLen = strlen(szStdOle);
1216 ptiRet->impltypelist->guid = IID_IDispatch;
1217 ptiRet->impltypelist->reference = -1;
1218 ptiRet->impltypelist->pImpTLInfo = TLB_Alloc(sizeof(TLBImpLib));
1219 ptiRet->impltypelist->pImpTLInfo->guid = IID_StdOle;
1220 ptiRet->impltypelist->pImpTLInfo->name = SysAllocStringLen(NULL, nStdOleLen + 1);
1222 MultiByteToWideChar(CP_ACP,
1223 MB_PRECOMPOSED,
1224 szStdOle,
1226 ptiRet->impltypelist->pImpTLInfo->name,
1227 SysStringLen(ptiRet->impltypelist->pImpTLInfo->name));
1229 ptiRet->impltypelist->pImpTLInfo->lcid = 0;
1230 ptiRet->impltypelist->pImpTLInfo->wVersionMajor = 2;
1231 ptiRet->impltypelist->pImpTLInfo->wVersionMinor = 0;
1233 break;
1234 default:
1235 ptiRet->impltypelist=TLB_Alloc(sizeof(TLBRefType));
1236 TLB_DoRefType(pcx, tiBase.datatype1, & ptiRet->impltypelist);
1237 break;
1240 ptiRet->ctCustData=
1241 TLB_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData);
1243 TRACE("%s guid: %s kind:%s\n",
1244 debugstr_w(ptiRet->Name),
1245 debugstr_guid(&ptiRet->TypeAttr.guid),
1246 typekind_desc[ptiRet->TypeAttr.typekind]);
1248 return ptiRet;
1251 /****************************************************************************
1252 * TLB_ReadTypeLib
1254 * find the type of the typelib file and map the typelib resource into
1255 * the memory
1257 #define MSFT_SIGNATURE 0x5446534D /* "MSFT" */
1258 int TLB_ReadTypeLib(LPSTR pszFileName, ITypeLib2 **ppTypeLib)
1260 int ret = E_FAIL;
1261 DWORD dwSignature = 0;
1262 HFILE hFile;
1263 int nStrLen = strlen(pszFileName);
1264 int i;
1266 PCHAR pszTypeLibIndex = NULL;
1267 PCHAR pszDllName = NULL;
1269 TRACE("%s\n", pszFileName);
1271 *ppTypeLib = NULL;
1273 /* is it a DLL? */
1274 for (i=0 ; i < nStrLen ; ++i)
1276 pszFileName[i] = tolower(pszFileName[i]);
1278 pszTypeLibIndex = strstr(pszFileName, ".dll");
1280 /* find if there's a back-slash after .DLL (good sign of the presence of a typelib index) */
1281 if (pszTypeLibIndex)
1283 pszTypeLibIndex = strstr(pszTypeLibIndex, "\\");
1286 /* is there any thing after trailing back-slash ? */
1287 if (pszTypeLibIndex && pszTypeLibIndex < pszFileName + nStrLen)
1289 /* yes -> it's a index! store DLL name, without the trailing back-slash */
1290 size_t nMemToAlloc = pszTypeLibIndex - pszFileName;
1292 pszDllName = HeapAlloc(GetProcessHeap(),
1293 HEAP_ZERO_MEMORY,
1294 nMemToAlloc + 1);
1296 strncpy(pszDllName, pszFileName, nMemToAlloc);
1298 /* move index string pointer pass the backslash */
1299 ++pszTypeLibIndex;
1301 else
1303 /* No index, reset variable to 1 */
1304 pszDllName = HeapAlloc(GetProcessHeap(),
1305 HEAP_ZERO_MEMORY,
1306 nStrLen + 1);
1308 strncpy(pszDllName, pszFileName, nStrLen);
1310 pszTypeLibIndex = "1\0";
1313 TRACE("File name without index %s\n", pszDllName);
1314 TRACE("Index of typelib %s\n", pszTypeLibIndex);
1317 /* check the signature of the file */
1318 hFile = CreateFileA( pszDllName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, -1 );
1319 if (INVALID_HANDLE_VALUE != hFile)
1321 HANDLE hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
1322 if (hMapping)
1324 LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
1325 if(pBase)
1327 /* first try to load as *.tlb */
1328 dwSignature = *((DWORD*) pBase);
1329 if ( dwSignature == MSFT_SIGNATURE)
1331 /* retrieve file size */
1332 DWORD dwTLBLength = GetFileSize(hFile, NULL);
1334 *ppTypeLib = ITypeLib2_Constructor(pBase, dwTLBLength);
1336 UnmapViewOfFile(pBase);
1338 CloseHandle(hMapping);
1340 CloseHandle(hFile);
1343 if( (WORD)dwSignature == IMAGE_DOS_SIGNATURE )
1345 /* find the typelibrary resource*/
1346 HINSTANCE hinstDLL = LoadLibraryExA(pszDllName, 0, DONT_RESOLVE_DLL_REFERENCES|
1347 LOAD_LIBRARY_AS_DATAFILE|LOAD_WITH_ALTERED_SEARCH_PATH);
1348 if (hinstDLL)
1350 HRSRC hrsrc = FindResourceA(hinstDLL, MAKEINTRESOURCEA(atoi(pszTypeLibIndex)), "TYPELIB");
1351 if (hrsrc)
1353 HGLOBAL hGlobal = LoadResource(hinstDLL, hrsrc);
1354 if (hGlobal)
1356 LPVOID pBase = LockResource(hGlobal);
1357 DWORD dwTLBLength = SizeofResource(hinstDLL, hrsrc);
1359 if (pBase)
1361 /* try to load as incore resource */
1362 dwSignature = *((DWORD*) pBase);
1363 if ( dwSignature == MSFT_SIGNATURE)
1364 *ppTypeLib = ITypeLib2_Constructor(pBase, dwTLBLength);
1365 else
1366 FIXME("Header type magic 0x%08lx not supported.\n",dwSignature);
1368 FreeResource( hGlobal );
1371 FreeLibrary(hinstDLL);
1375 HeapFree(GetProcessHeap(), 0, pszDllName);
1377 if(*ppTypeLib)
1378 ret = S_OK;
1379 else
1380 ERR("Loading of typelib %s failed with error 0x%08lx\n", pszFileName, GetLastError());
1382 return ret;
1385 /*================== ITypeLib(2) Methods ===================================*/
1387 /****************************************************************************
1388 * ITypeLib2_Constructor
1390 * loading a typelib from a in-memory image
1392 static ITypeLib2* ITypeLib2_Constructor(LPVOID pLib, DWORD dwTLBLength)
1394 TLBContext cx;
1395 long lPSegDir;
1396 TLB2Header tlbHeader;
1397 TLBSegDir tlbSegDir;
1398 ITypeLibImpl * pTypeLibImpl;
1400 TRACE("%p, TLB length = %ld\n", pLib, dwTLBLength);
1402 pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
1403 if (!pTypeLibImpl) return NULL;
1405 ICOM_VTBL(pTypeLibImpl) = &tlbvt;
1406 pTypeLibImpl->ref = 1;
1408 /* get pointer to beginning of typelib data */
1409 cx.pos = 0;
1410 cx.oStart=0;
1411 cx.mapping = pLib;
1412 cx.pLibInfo = pTypeLibImpl;
1413 cx.length = dwTLBLength;
1415 /* read header */
1416 TLB_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
1417 TRACE("header:\n");
1418 TRACE("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2 );
1419 if (memcmp(&tlbHeader.magic1,TLBMAGIC2,4)) {
1420 FIXME("Header type magic 0x%08x not supported.\n",tlbHeader.magic1);
1421 return NULL;
1423 /* there is a small number of information here until the next important
1424 * part:
1425 * the segment directory . Try to calculate the amount of data */
1426 lPSegDir = sizeof(tlbHeader) + (tlbHeader.nrtypeinfos)*4 + ((tlbHeader.varflags & HELPDLLFLAG)? 4 :0);
1428 /* now read the segment directory */
1429 TRACE("read segment directory (at %ld)\n",lPSegDir);
1430 TLB_Read((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
1431 cx.pTblDir = &tlbSegDir;
1433 /* just check two entries */
1434 if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F || tlbSegDir.pImpInfo.res0c != 0x0F)
1436 ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir);
1437 HeapFree(GetProcessHeap(),0,pTypeLibImpl);
1438 return NULL;
1441 /* now fill our internal data */
1442 /* TLIBATTR fields */
1443 TLB_ReadGuid(&pTypeLibImpl->LibAttr.guid, tlbHeader.posguid, &cx);
1444 pTypeLibImpl->LibAttr.lcid = tlbHeader.lcid;
1445 pTypeLibImpl->LibAttr.syskind = tlbHeader.varflags & 0x0f; /* check the mask */
1446 pTypeLibImpl->LibAttr.wMajorVerNum = LOWORD(tlbHeader.version);
1447 pTypeLibImpl->LibAttr.wMinorVerNum = HIWORD(tlbHeader.version);
1448 pTypeLibImpl->LibAttr.wLibFlags = (WORD) tlbHeader.flags & 0xffff;/* check mask */
1450 /* name, eventually add to a hash table */
1451 pTypeLibImpl->Name = TLB_ReadName(&cx, tlbHeader.NameOffset);
1453 /* help info */
1454 pTypeLibImpl->DocString = TLB_ReadString(&cx, tlbHeader.helpstring);
1455 pTypeLibImpl->HelpFile = TLB_ReadString(&cx, tlbHeader.helpfile);
1457 if( tlbHeader.varflags & HELPDLLFLAG)
1459 int offset;
1460 TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
1461 pTypeLibImpl->HelpStringDll = TLB_ReadString(&cx, offset);
1464 pTypeLibImpl->dwHelpContext = tlbHeader.helpstringcontext;
1466 /* custom data */
1467 if(tlbHeader.CustomDataOffset >= 0)
1469 pTypeLibImpl->ctCustData = TLB_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->pCustData);
1472 /* fill in typedescriptions */
1473 if(tlbSegDir.pTypdescTab.length > 0)
1475 int i, j, cTD = tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
1476 INT16 td[4];
1477 pTypeLibImpl->pTypeDesc = TLB_Alloc( cTD * sizeof(TYPEDESC));
1478 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
1479 for(i=0; i<cTD; )
1481 /* FIXME: add several sanity checks here */
1482 pTypeLibImpl->pTypeDesc[i].vt = td[0] & VT_TYPEMASK;
1483 if(td[0] == VT_PTR || td[0] == VT_SAFEARRAY)
1485 /* FIXME: check safearray */
1486 if(td[3] < 0)
1487 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lptdesc)= & stndTypeDesc[td[2]];
1488 else
1489 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lptdesc)= & pTypeLibImpl->pTypeDesc[td[2]/8];
1491 else if(td[0] == VT_CARRAY)
1493 /* array descr table here */
1494 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = (void *)((int) td[2]); /* temp store offset in*/
1496 else if(td[0] == VT_USERDEFINED)
1498 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),hreftype) = MAKELONG(td[2],td[3]);
1500 if(++i<cTD) TLB_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
1503 /* second time around to fill the array subscript info */
1504 for(i=0;i<cTD;i++)
1506 if(pTypeLibImpl->pTypeDesc[i].vt != VT_CARRAY) continue;
1507 if(tlbSegDir.pArrayDescriptions.offset>0)
1509 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (int) V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc));
1510 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
1512 if(td[1]<0)
1513 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->tdescElem.vt = td[0] & VT_TYPEMASK;
1514 else
1515 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->tdescElem = stndTypeDesc[td[0]/8];
1517 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->cDims = td[2];
1519 for(j = 0; j<td[2]; j++)
1521 TLB_Read(& V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->rgbounds[j].cElements,
1522 sizeof(INT), &cx, DO_NOT_SEEK);
1523 TLB_Read(& V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->rgbounds[j].lLbound,
1524 sizeof(INT), &cx, DO_NOT_SEEK);
1527 else
1529 V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = NULL;
1530 ERR("didn't find array description data\n");
1535 /* imported type libs */
1536 if(tlbSegDir.pImpFiles.offset>0)
1538 TLBImpLib **ppImpLib = &(pTypeLibImpl->pImpLibs);
1539 int oGuid, offset = tlbSegDir.pImpFiles.offset;
1540 UINT16 size;
1542 while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length)
1544 *ppImpLib = TLB_Alloc(sizeof(TLBImpLib));
1545 (*ppImpLib)->offset = offset - tlbSegDir.pImpFiles.offset;
1546 TLB_Read(&oGuid, sizeof(INT), &cx, offset);
1548 TLB_Read(&(*ppImpLib)->lcid, sizeof(LCID), &cx, DO_NOT_SEEK);
1549 TLB_Read(&(*ppImpLib)->wVersionMajor, sizeof(WORD), &cx, DO_NOT_SEEK);
1550 TLB_Read(&(*ppImpLib)->wVersionMinor, sizeof(WORD), &cx, DO_NOT_SEEK);
1551 TLB_Read(& size, sizeof(UINT16), &cx, DO_NOT_SEEK);
1553 size >>= 2;
1554 (*ppImpLib)->name = TLB_Alloc(size+1);
1555 TLB_Read((*ppImpLib)->name, size, &cx, DO_NOT_SEEK);
1556 TLB_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
1557 offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & 0xfffffffc;
1559 ppImpLib = &(*ppImpLib)->next;
1563 /* type info's */
1564 if(tlbHeader.nrtypeinfos >= 0 )
1566 /*pTypeLibImpl->TypeInfoCount=tlbHeader.nrtypeinfos; */
1567 ITypeInfoImpl **ppTI = &(pTypeLibImpl->pTypeInfo);
1568 int i;
1570 for(i = 0; i<(int)tlbHeader.nrtypeinfos; i++)
1572 *ppTI = TLB_DoTypeInfo(&cx, i, pTypeLibImpl);
1574 ppTI = &((*ppTI)->next);
1575 (pTypeLibImpl->TypeInfoCount)++;
1579 TRACE("(%p)\n", pTypeLibImpl);
1580 return (ITypeLib2*) pTypeLibImpl;
1583 /* ITypeLib::QueryInterface
1585 static HRESULT WINAPI ITypeLib2_fnQueryInterface(
1586 ITypeLib2 * iface,
1587 REFIID riid,
1588 VOID **ppvObject)
1590 ICOM_THIS( ITypeLibImpl, iface);
1592 TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
1594 *ppvObject=NULL;
1595 if(IsEqualIID(riid, &IID_IUnknown) ||
1596 IsEqualIID(riid,&IID_ITypeLib)||
1597 IsEqualIID(riid,&IID_ITypeLib2))
1599 *ppvObject = This;
1602 if(*ppvObject)
1604 ITypeLib2_AddRef(iface);
1605 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1606 return S_OK;
1608 TRACE("-- Interface: E_NOINTERFACE\n");
1609 return E_NOINTERFACE;
1612 /* ITypeLib::AddRef
1614 static ULONG WINAPI ITypeLib2_fnAddRef( ITypeLib2 *iface)
1616 ICOM_THIS( ITypeLibImpl, iface);
1618 TRACE("(%p)->ref is %u\n",This, This->ref);
1620 return ++(This->ref);
1623 /* ITypeLib::Release
1625 static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
1627 ICOM_THIS( ITypeLibImpl, iface);
1629 TRACE("(%p)->(%u)\n",This, This->ref);
1631 if (!--(This->ref))
1633 /* fixme destroy child objects */
1635 TRACE(" destroying ITypeLib(%p)\n",This);
1637 if (This->Name)
1639 SysFreeString(This->Name);
1640 This->Name = NULL;
1643 if (This->DocString)
1645 SysFreeString(This->DocString);
1646 This->DocString = NULL;
1649 if (This->HelpFile)
1651 SysFreeString(This->HelpFile);
1652 This->HelpFile = NULL;
1655 if (This->HelpStringDll)
1657 SysFreeString(This->HelpStringDll);
1658 This->HelpStringDll = NULL;
1661 ITypeInfo_Release((ITypeInfo*) This->pTypeInfo);
1662 HeapFree(GetProcessHeap(),0,This);
1663 return 0;
1665 return This->ref;
1668 /* ITypeLib::GetTypeInfoCount
1670 * Returns the number of type descriptions in the type library
1672 static UINT WINAPI ITypeLib2_fnGetTypeInfoCount( ITypeLib2 *iface)
1674 ICOM_THIS( ITypeLibImpl, iface);
1675 TRACE("(%p)->count is %d\n",This, This->TypeInfoCount);
1676 return This->TypeInfoCount;
1679 /* ITypeLib::GetTypeInfo
1681 * retrieves the specified type description in the library.
1683 static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(
1684 ITypeLib2 *iface,
1685 UINT index,
1686 ITypeInfo **ppTInfo)
1688 int i;
1689 ICOM_THIS( ITypeLibImpl, iface);
1690 ITypeInfoImpl *pTLBTInfo = This->pTypeInfo;
1692 TRACE("(%p)->(index=%d) \n",This, index);
1694 if (!ppTInfo) return E_INVALIDARG;
1696 /* search element n in list */
1697 for(i=0; i < index; i++)
1699 pTLBTInfo = pTLBTInfo->next;
1700 if (!pTLBTInfo)
1702 TRACE("-- element not found\n");
1703 return TYPE_E_ELEMENTNOTFOUND;
1707 *ppTInfo = (ITypeInfo *) pTLBTInfo;
1708 ITypeInfo_AddRef(*ppTInfo);
1709 TRACE("-- found (%p)\n",*ppTInfo);
1710 return S_OK;
1713 /* ITypeLibs::GetTypeInfoType
1715 * Retrieves the type of a type description.
1717 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType(
1718 ITypeLib2 *iface,
1719 UINT index,
1720 TYPEKIND *pTKind)
1722 ICOM_THIS( ITypeLibImpl, iface);
1723 int i;
1724 ITypeInfoImpl *pTInfo = This->pTypeInfo;
1726 TRACE("(%p) index %d \n",This, index);
1728 if(!pTKind) return E_INVALIDARG;
1730 /* search element n in list */
1731 for(i=0; i < index; i++)
1733 if(!pTInfo)
1735 TRACE("-- element not found\n");
1736 return TYPE_E_ELEMENTNOTFOUND;
1738 pTInfo = pTInfo->next;
1741 *pTKind = pTInfo->TypeAttr.typekind;
1742 TRACE("-- found Type (%d)\n", *pTKind);
1743 return S_OK;
1746 /* ITypeLib::GetTypeInfoOfGuid
1748 * Retrieves the type description that corresponds to the specified GUID.
1751 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(
1752 ITypeLib2 *iface,
1753 REFGUID guid,
1754 ITypeInfo **ppTInfo)
1756 ICOM_THIS( ITypeLibImpl, iface);
1757 ITypeInfoImpl *ppTLBTInfo = This->pTypeInfo; /* head of list */
1759 TRACE("(%p)\n\tguid:\t%s)\n",This,debugstr_guid(guid));
1761 /* serach linked list for guid */
1762 while( !IsEqualIID(guid,&ppTLBTInfo->TypeAttr.guid) )
1764 ppTLBTInfo = ppTLBTInfo->next;
1765 if (!ppTLBTInfo)
1767 /* end of list reached */
1768 TRACE("-- element not found\n");
1769 return TYPE_E_ELEMENTNOTFOUND;
1773 TRACE("-- found (%p, %s)\n", ppTLBTInfo, debugstr_w(ppTLBTInfo->Name));
1775 *ppTInfo = (ITypeInfo*)ppTLBTInfo;
1776 ITypeInfo_AddRef(*ppTInfo);
1777 return S_OK;
1780 /* ITypeLib::GetLibAttr
1782 * Retrieves the structure that contains the library's attributes.
1785 static HRESULT WINAPI ITypeLib2_fnGetLibAttr(
1786 ITypeLib2 *iface,
1787 LPTLIBATTR *ppTLibAttr)
1789 ICOM_THIS( ITypeLibImpl, iface);
1790 TRACE("(%p)\n",This);
1791 /* FIXME: must do a copy here */
1792 *ppTLibAttr=&This->LibAttr;
1793 return S_OK;
1796 /* ITypeLib::GetTypeComp
1798 * Enables a client compiler to bind to a library's types, variables,
1799 * constants, and global functions.
1802 static HRESULT WINAPI ITypeLib2_fnGetTypeComp(
1803 ITypeLib2 *iface,
1804 ITypeComp **ppTComp)
1806 ICOM_THIS( ITypeLibImpl, iface);
1807 FIXME("(%p): stub!\n",This);
1808 return E_NOTIMPL;
1811 /* ITypeLib::GetDocumentation
1813 * Retrieves the library's documentation string, the complete Help file name
1814 * and path, and the context identifier for the library Help topic in the Help
1815 * file.
1818 static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
1819 ITypeLib2 *iface,
1820 INT index,
1821 BSTR *pBstrName,
1822 BSTR *pBstrDocString,
1823 DWORD *pdwHelpContext,
1824 BSTR *pBstrHelpFile)
1826 ICOM_THIS( ITypeLibImpl, iface);
1827 HRESULT result;
1828 ITypeInfo *pTInfo;
1829 TRACE("(%p) index %d Name(%p) DocString(%p)"
1830 " HelpContext(%p) HelpFile(%p)\n",
1831 This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1832 if(index<0){ /* documentation for the typelib */
1833 if(pBstrName)
1834 *pBstrName=SysAllocString(This->Name);
1835 if(pBstrDocString)
1836 *pBstrDocString=SysAllocString(This->DocString);
1837 if(pdwHelpContext)
1838 *pdwHelpContext=This->dwHelpContext;
1839 if(pBstrHelpFile)
1840 *pBstrHelpFile=SysAllocString(This->HelpFile);
1841 }else {/* for a typeinfo */
1842 result=ITypeLib2_fnGetTypeInfo(iface, index, &pTInfo);
1843 if(SUCCEEDED(result)){
1844 result=ITypeInfo_GetDocumentation(pTInfo, MEMBERID_NIL, pBstrName,
1845 pBstrDocString, pdwHelpContext, pBstrHelpFile);
1846 ITypeInfo_Release(pTInfo);
1848 if(!SUCCEEDED(result))
1849 return result;
1851 return S_OK;
1854 /* ITypeLib::IsName
1856 * Indicates whether a passed-in string contains the name of a type or member
1857 * described in the library.
1860 static HRESULT WINAPI ITypeLib2_fnIsName(
1861 ITypeLib2 *iface,
1862 LPOLESTR szNameBuf,
1863 ULONG lHashVal,
1864 BOOL *pfName)
1866 ICOM_THIS( ITypeLibImpl, iface);
1867 ITypeInfoImpl *pTInfo;
1868 TLBFuncDesc *pFInfo;
1869 TLBVarDesc *pVInfo;
1870 int i;
1871 UINT nNameBufLen = SysStringLen(szNameBuf);
1873 TRACE("(%p)->(%s,%08lx,%p)\n", This, debugstr_w(szNameBuf), lHashVal,
1874 pfName);
1876 *pfName=TRUE;
1877 for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){
1878 if(!memcmp(szNameBuf,pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
1879 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1880 if(!memcmp(szNameBuf,pFInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
1881 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1882 if(!memcmp(szNameBuf,pFInfo->pParamDesc[i].Name, nNameBufLen))
1883 goto ITypeLib2_fnIsName_exit;
1885 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next)
1886 if(!memcmp(szNameBuf,pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
1889 *pfName=FALSE;
1891 ITypeLib2_fnIsName_exit:
1892 TRACE("(%p)slow! search for %s: %s found!\n", This,
1893 debugstr_w(szNameBuf), *pfName?"NOT":"");
1895 return S_OK;
1898 /* ITypeLib::FindName
1900 * Finds occurrences of a type description in a type library. This may be used
1901 * to quickly verify that a name exists in a type library.
1904 static HRESULT WINAPI ITypeLib2_fnFindName(
1905 ITypeLib2 *iface,
1906 LPOLESTR szNameBuf,
1907 ULONG lHashVal,
1908 ITypeInfo **ppTInfo,
1909 MEMBERID *rgMemId,
1910 UINT16 *pcFound)
1912 ICOM_THIS( ITypeLibImpl, iface);
1913 ITypeInfoImpl *pTInfo;
1914 TLBFuncDesc *pFInfo;
1915 TLBVarDesc *pVInfo;
1916 int i,j = 0;
1918 UINT nNameBufLen = SysStringLen(szNameBuf);
1920 for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){
1921 if(!memcmp(szNameBuf,pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnFindName_exit;
1922 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
1923 if(!memcmp(szNameBuf,pFInfo->Name,nNameBufLen)) goto ITypeLib2_fnFindName_exit;
1924 for(i=0;i<pFInfo->funcdesc.cParams;i++)
1925 if(!memcmp(szNameBuf,pFInfo->pParamDesc[i].Name,nNameBufLen))
1926 goto ITypeLib2_fnFindName_exit;
1928 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ;
1929 if(!memcmp(szNameBuf,pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnFindName_exit;
1930 continue;
1931 ITypeLib2_fnFindName_exit:
1932 ITypeInfo_AddRef((ITypeInfo*)pTInfo);
1933 ppTInfo[j]=(LPTYPEINFO)pTInfo;
1934 j++;
1936 TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
1937 This, *pcFound, debugstr_w(szNameBuf), j);
1939 *pcFound=j;
1941 return S_OK;
1944 /* ITypeLib::ReleaseTLibAttr
1946 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
1949 static VOID WINAPI ITypeLib2_fnReleaseTLibAttr(
1950 ITypeLib2 *iface,
1951 TLIBATTR *pTLibAttr)
1953 ICOM_THIS( ITypeLibImpl, iface);
1954 TRACE("freeing (%p)\n",This);
1955 /* nothing to do */
1958 /* ITypeLib2::GetCustData
1960 * gets the custom data
1962 static HRESULT WINAPI ITypeLib2_fnGetCustData(
1963 ITypeLib2 * iface,
1964 REFGUID guid,
1965 VARIANT *pVarVal)
1967 ICOM_THIS( ITypeLibImpl, iface);
1968 TLBCustData *pCData;
1970 for(pCData=This->pCustData; pCData; pCData = pCData->next)
1972 if( IsEqualIID(guid, &pCData->guid)) break;
1975 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
1977 if(pCData)
1979 VariantInit( pVarVal);
1980 VariantCopy( pVarVal, &pCData->data);
1981 return S_OK;
1983 return E_INVALIDARG; /* FIXME: correct? */
1986 /* ITypeLib2::GetLibStatistics
1988 * Returns statistics about a type library that are required for efficient
1989 * sizing of hash tables.
1992 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(
1993 ITypeLib2 * iface,
1994 ULONG *pcUniqueNames,
1995 ULONG *pcchUniqueNames)
1997 ICOM_THIS( ITypeLibImpl, iface);
1999 FIXME("(%p): stub!\n", This);
2001 if(pcUniqueNames) *pcUniqueNames=1;
2002 if(pcchUniqueNames) *pcchUniqueNames=1;
2003 return S_OK;
2006 /* ITypeLib2::GetDocumentation2
2008 * Retrieves the library's documentation string, the complete Help file name
2009 * and path, the localization context to use, and the context ID for the
2010 * library Help topic in the Help file.
2013 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
2014 ITypeLib2 * iface,
2015 INT index,
2016 LCID lcid,
2017 BSTR *pbstrHelpString,
2018 DWORD *pdwHelpStringContext,
2019 BSTR *pbstrHelpStringDll)
2021 ICOM_THIS( ITypeLibImpl, iface);
2022 HRESULT result;
2023 ITypeInfo *pTInfo;
2025 FIXME("(%p) index %d lcid %ld half implemented stub!\n", This, index, lcid);
2027 /* the help string should be obtained from the helpstringdll,
2028 * using the _DLLGetDocumentation function, based on the supplied
2029 * lcid. Nice to do sometime...
2031 if(index<0)
2033 /* documentation for the typelib */
2034 if(pbstrHelpString)
2035 *pbstrHelpString=SysAllocString(This->DocString);
2036 if(pdwHelpStringContext)
2037 *pdwHelpStringContext=This->dwHelpContext;
2038 if(pbstrHelpStringDll)
2039 *pbstrHelpStringDll=SysAllocString(This->HelpStringDll);
2041 else
2043 /* for a typeinfo */
2044 result=ITypeLib2_GetTypeInfo(iface, index, &pTInfo);
2045 if(SUCCEEDED(result))
2047 ITypeInfo2 * pTInfo2;
2048 result = ITypeInfo_QueryInterface(pTInfo, &IID_ITypeInfo2, (LPVOID*) &pTInfo2);
2049 if(SUCCEEDED(result))
2051 result = ITypeInfo2_GetDocumentation2(pTInfo2, MEMBERID_NIL, lcid,
2052 pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
2053 ITypeInfo2_Release(pTInfo2);
2055 ITypeInfo_Release(pTInfo);
2057 if(!SUCCEEDED(result))
2058 return result;
2060 return S_OK;
2063 /* ITypeLib2::GetAllCustData
2065 * Gets all custom data items for the library.
2068 static HRESULT WINAPI ITypeLib2_fnGetAllCustData(
2069 ITypeLib2 * iface,
2070 CUSTDATA *pCustData)
2072 ICOM_THIS( ITypeLibImpl, iface);
2073 TLBCustData *pCData;
2074 int i;
2075 TRACE("(%p) returning %d items\n", This, This->ctCustData);
2076 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
2077 if(pCustData->prgCustData ){
2078 pCustData->cCustData=This->ctCustData;
2079 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
2080 pCustData->prgCustData[i].guid=pCData->guid;
2081 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
2083 }else{
2084 ERR(" OUT OF MEMORY! \n");
2085 return E_OUTOFMEMORY;
2087 return S_OK;
2090 static ICOM_VTABLE(ITypeLib2) tlbvt = {
2091 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2092 ITypeLib2_fnQueryInterface,
2093 ITypeLib2_fnAddRef,
2094 ITypeLib2_fnRelease,
2095 ITypeLib2_fnGetTypeInfoCount,
2096 ITypeLib2_fnGetTypeInfo,
2097 ITypeLib2_fnGetTypeInfoType,
2098 ITypeLib2_fnGetTypeInfoOfGuid,
2099 ITypeLib2_fnGetLibAttr,
2100 ITypeLib2_fnGetTypeComp,
2101 ITypeLib2_fnGetDocumentation,
2102 ITypeLib2_fnIsName,
2103 ITypeLib2_fnFindName,
2104 ITypeLib2_fnReleaseTLibAttr,
2106 ITypeLib2_fnGetCustData,
2107 ITypeLib2_fnGetLibStatistics,
2108 ITypeLib2_fnGetDocumentation2,
2109 ITypeLib2_fnGetAllCustData
2112 /*================== ITypeInfo(2) Methods ===================================*/
2113 static ITypeInfo2 * WINAPI ITypeInfo_Constructor(void)
2115 ITypeInfoImpl * pTypeInfoImpl;
2117 pTypeInfoImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeInfoImpl));
2118 if (pTypeInfoImpl)
2120 ICOM_VTBL(pTypeInfoImpl) = &tinfvt;
2121 pTypeInfoImpl->ref=1;
2123 TRACE("(%p)\n", pTypeInfoImpl);
2124 return (ITypeInfo2*) pTypeInfoImpl;
2127 /* ITypeInfo::QueryInterface
2129 static HRESULT WINAPI ITypeInfo_fnQueryInterface(
2130 ITypeInfo2 *iface,
2131 REFIID riid,
2132 VOID **ppvObject)
2134 ICOM_THIS( ITypeLibImpl, iface);
2136 TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
2138 *ppvObject=NULL;
2139 if(IsEqualIID(riid, &IID_IUnknown) ||
2140 IsEqualIID(riid,&IID_ITypeInfo)||
2141 IsEqualIID(riid,&IID_ITypeInfo2))
2142 *ppvObject = This;
2144 if(*ppvObject){
2145 ITypeInfo_AddRef(iface);
2146 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
2147 return S_OK;
2149 TRACE("-- Interface: E_NOINTERFACE\n");
2150 return E_NOINTERFACE;
2153 /* ITypeInfo::AddRef
2155 static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface)
2157 ICOM_THIS( ITypeInfoImpl, iface);
2158 TRACE("(%p)->ref is %u\n",This, This->ref);
2159 return ++(This->ref);
2162 /* ITypeInfo::Release
2164 static ULONG WINAPI ITypeInfo_fnRelease( ITypeInfo2 *iface)
2166 ICOM_THIS( ITypeInfoImpl, iface);
2167 TRACE("(%p)->(%u)\n",This, This->ref);
2170 if (!--(This->ref))
2172 FIXME("destroy child objects\n");
2174 TRACE(" destroying ITypeInfo(%p)\n",This);
2175 if (This->Name)
2177 SysFreeString(This->Name);
2178 This->Name = 0;
2181 if (This->DocString)
2183 SysFreeString(This->DocString);
2184 This->DocString = 0;
2187 if (This->next)
2189 ITypeInfo_Release((ITypeInfo*)This->next);
2192 HeapFree(GetProcessHeap(),0,This);
2193 return 0;
2195 return This->ref;
2198 /* ITypeInfo::GetTypeAttr
2200 * Retrieves a TYPEATTR structure that contains the attributes of the type
2201 * description.
2204 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface,
2205 LPTYPEATTR *ppTypeAttr)
2207 ICOM_THIS( ITypeInfoImpl, iface);
2208 TRACE("(%p)\n",This);
2209 /* FIXME: must do a copy here */
2210 *ppTypeAttr=&This->TypeAttr;
2211 return S_OK;
2214 /* ITypeInfo::GetTypeComp
2216 * Retrieves the ITypeComp interface for the type description, which enables a
2217 * client compiler to bind to the type description's members.
2220 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( ITypeInfo2 *iface,
2221 ITypeComp * *ppTComp)
2223 ICOM_THIS( ITypeInfoImpl, iface);
2224 FIXME("(%p) stub!\n", This);
2225 return S_OK;
2228 /* ITypeInfo::GetFuncDesc
2230 * Retrieves the FUNCDESC structure that contains information about a
2231 * specified function.
2234 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( ITypeInfo2 *iface, UINT index,
2235 LPFUNCDESC *ppFuncDesc)
2237 ICOM_THIS( ITypeInfoImpl, iface);
2238 int i;
2239 TLBFuncDesc * pFDesc;
2240 TRACE("(%p) index %d\n", This, index);
2241 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
2243 if(pFDesc){
2244 /* FIXME: must do a copy here */
2245 *ppFuncDesc=&pFDesc->funcdesc;
2246 return S_OK;
2248 return E_INVALIDARG;
2251 /* ITypeInfo::GetVarDesc
2253 * Retrieves a VARDESC structure that describes the specified variable.
2256 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( ITypeInfo2 *iface, UINT index,
2257 LPVARDESC *ppVarDesc)
2259 ICOM_THIS( ITypeInfoImpl, iface);
2260 int i;
2261 TLBVarDesc * pVDesc;
2262 TRACE("(%p) index %d\n", This, index);
2263 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next)
2265 if(pVDesc){
2266 /* FIXME: must do a copy here */
2267 *ppVarDesc=&pVDesc->vardesc;
2268 return S_OK;
2270 return E_INVALIDARG;
2273 /* ITypeInfo_GetNames
2275 * Retrieves the variable with the specified member ID (or the name of the
2276 * property or method and its parameters) that correspond to the specified
2277 * function ID.
2279 static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
2280 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
2282 ICOM_THIS( ITypeInfoImpl, iface);
2283 TLBFuncDesc * pFDesc;
2284 TLBVarDesc * pVDesc;
2285 int i;
2286 TRACE("(%p) memid=0x%08lx Maxname=%d\n", This, memid, cMaxNames);
2287 for(pFDesc=This->funclist; pFDesc && pFDesc->funcdesc.memid != memid; pFDesc=pFDesc->next);
2288 if(pFDesc)
2290 /* function found, now return function and parameter names */
2291 for(i=0; i<cMaxNames && i <= pFDesc->funcdesc.cParams; i++)
2293 if(!i)
2294 *rgBstrNames=SysAllocString(pFDesc->Name);
2295 else
2296 rgBstrNames[i]=SysAllocString(pFDesc->pParamDesc[i-1].Name);
2298 *pcNames=i;
2300 else
2302 for(pVDesc=This->varlist; pVDesc && pVDesc->vardesc.memid != memid; pVDesc=pVDesc->next);
2303 if(pVDesc)
2305 *rgBstrNames=SysAllocString(pVDesc->Name);
2306 *pcNames=1;
2308 else
2310 if(This->TypeAttr.typekind==TKIND_INTERFACE && This->TypeAttr.cImplTypes )
2312 /* recursive search */
2313 ITypeInfo *pTInfo;
2314 HRESULT result;
2315 result=ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->reference, &pTInfo);
2316 if(SUCCEEDED(result))
2318 result=ITypeInfo_GetNames(pTInfo, memid, rgBstrNames, cMaxNames, pcNames);
2319 ITypeInfo_Release(pTInfo);
2320 return result;
2322 WARN("Could not search inherited interface!\n");
2324 else
2326 WARN("no names found\n");
2328 *pcNames=0;
2329 return TYPE_E_ELEMENTNOTFOUND;
2332 return S_OK;
2336 /* ITypeInfo::GetRefTypeOfImplType
2338 * If a type description describes a COM class, it retrieves the type
2339 * description of the implemented interface types. For an interface,
2340 * GetRefTypeOfImplType returns the type information for inherited interfaces,
2341 * if any exist.
2344 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType(
2345 ITypeInfo2 *iface,
2346 UINT index,
2347 HREFTYPE *pRefType)
2349 ICOM_THIS( ITypeInfoImpl, iface);
2350 int(i);
2351 TLBRefType *pIref = This->impltypelist;
2353 TRACE("(%p) index %d\n", This, index);
2354 dump_TypeInfo(This);
2357 if(index==(UINT)-1)
2359 /* only valid on dual interfaces;
2360 retrieve the associated TKIND_INTERFACE handle for the current TKIND_DISPATCH
2362 if( This->TypeAttr.typekind != TKIND_DISPATCH) return E_INVALIDARG;
2364 if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDISPATCHABLE &&
2365 This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL )
2367 *pRefType = -1;
2369 else
2371 *pRefType = pIref->reference;
2374 else
2376 /* get element n from linked list */
2377 for(i=0; i<index; i++)
2379 if (!pIref) return TYPE_E_ELEMENTNOTFOUND;
2380 pIref = pIref->next;
2383 *pRefType = pIref->reference;
2386 TRACE("-- 0x%08lx %s\n",pIref->reference, debugstr_guid(&pIref->guid) );
2387 return S_OK;
2391 /* ITypeInfo::GetImplTypeFlags
2393 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
2394 * or base interface in a type description.
2396 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( ITypeInfo2 *iface,
2397 UINT index, INT *pImplTypeFlags)
2399 ICOM_THIS( ITypeInfoImpl, iface);
2400 int(i);
2401 TLBRefType *pIref;
2402 TRACE("(%p) index %d\n", This, index);
2403 for(i=0, pIref=This->impltypelist; i<index && pIref; i++, pIref=pIref->next)
2405 if(i==index && pIref){
2406 *pImplTypeFlags=pIref->flags;
2407 return S_OK;
2409 *pImplTypeFlags=0;
2410 return TYPE_E_ELEMENTNOTFOUND;
2413 /* GetIDsOfNames
2414 * Maps between member names and member IDs, and parameter names and
2415 * parameter IDs.
2417 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface,
2418 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
2420 ICOM_THIS( ITypeInfoImpl, iface);
2421 TLBFuncDesc * pFDesc;
2422 TLBVarDesc * pVDesc;
2423 HRESULT ret=S_OK;
2424 UINT nNameLen = SysStringLen(*rgszNames);
2426 TRACE("(%p) Name %s cNames %d\n", This, debugstr_w(*rgszNames),
2427 cNames);
2428 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) {
2429 int i, j;
2430 if( !memcmp(*rgszNames, pFDesc->Name, nNameLen)) {
2431 if(cNames) *pMemId=pFDesc->funcdesc.memid;
2432 for(i=1; i < cNames; i++){
2433 UINT nParamLen = SysStringLen(rgszNames[i]);
2434 for(j=0; j<pFDesc->funcdesc.cParams; j++)
2435 if(memcmp(rgszNames[i],pFDesc->pParamDesc[j].Name, nParamLen))
2436 break;
2437 if( j<pFDesc->funcdesc.cParams)
2438 pMemId[i]=j;
2439 else
2440 ret=DISP_E_UNKNOWNNAME;
2442 return ret;
2445 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
2446 if( !memcmp(*rgszNames, pVDesc->Name, nNameLen)) {
2447 if(cNames) *pMemId=pVDesc->vardesc.memid;
2448 return ret;
2451 /* not found, see if this is and interface with an inheritance */
2452 if(This->TypeAttr.typekind==TKIND_INTERFACE &&
2453 This->TypeAttr.cImplTypes ){
2454 /* recursive search */
2455 ITypeInfo *pTInfo;
2456 ret=ITypeInfo_GetRefTypeInfo(iface,
2457 This->impltypelist->reference, &pTInfo);
2458 if(SUCCEEDED(ret)){
2459 ret=ITypeInfo_GetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
2460 ITypeInfo_Release(pTInfo);
2461 return ret;
2463 WARN("Could not search inherited interface!\n");
2464 } else
2465 WARN("no names found\n");
2466 return DISP_E_UNKNOWNNAME;
2469 /* ITypeInfo::Invoke
2471 * Invokes a method, or accesses a property of an object, that implements the
2472 * interface described by the type description.
2474 static HRESULT WINAPI ITypeInfo_fnInvoke(
2475 ITypeInfo2 *iface,
2476 VOID *pIUnk,
2477 MEMBERID memid,
2478 UINT16 dwFlags,
2479 DISPPARAMS *pDispParams,
2480 VARIANT *pVarResult,
2481 EXCEPINFO *pExcepInfo,
2482 UINT *pArgErr)
2484 ICOM_THIS( ITypeInfoImpl, iface);
2485 FIXME("(%p)(%p,id=0x%08lx,0x%08x,%p,%p,%p,%p) stub!\n",
2486 This, pIUnk, memid, dwFlags, pDispParams, pVarResult, pExcepInfo, pArgErr );
2487 dump_DispParms(pDispParams);
2488 return S_OK;
2491 /* ITypeInfo::GetDocumentation
2493 * Retrieves the documentation string, the complete Help file name and path,
2494 * and the context ID for the Help topic for a specified type description.
2496 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( ITypeInfo2 *iface,
2497 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
2498 DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
2500 ICOM_THIS( ITypeInfoImpl, iface);
2501 TLBFuncDesc * pFDesc;
2502 TLBVarDesc * pVDesc;
2503 TRACE("(%p) memid %ld Name(%p) DocString(%p)"
2504 " HelpContext(%p) HelpFile(%p)\n",
2505 This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
2506 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
2507 if(pBstrName)
2508 *pBstrName=SysAllocString(This->Name);
2509 if(pBstrDocString)
2510 *pBstrDocString=SysAllocString(This->DocString);
2511 if(pdwHelpContext)
2512 *pdwHelpContext=This->dwHelpContext;
2513 if(pBstrHelpFile)
2514 *pBstrHelpFile=SysAllocString(This->DocString);/* FIXME */
2515 return S_OK;
2516 }else {/* for a member */
2517 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
2518 if(pFDesc->funcdesc.memid==memid){
2519 return S_OK;
2521 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
2522 if(pVDesc->vardesc.memid==memid){
2523 return S_OK;
2526 return TYPE_E_ELEMENTNOTFOUND;
2529 /* ITypeInfo::GetDllEntry
2531 * Retrieves a description or specification of an entry point for a function
2532 * in a DLL.
2534 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid,
2535 INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
2536 WORD *pwOrdinal)
2538 ICOM_THIS( ITypeInfoImpl, iface);
2539 FIXME("(%p) stub!\n", This);
2540 return E_FAIL;
2543 /* ITypeInfo::GetRefTypeInfo
2545 * If a type description references other type descriptions, it retrieves
2546 * the referenced type descriptions.
2548 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
2549 ITypeInfo2 *iface,
2550 HREFTYPE hRefType,
2551 ITypeInfo **ppTInfo)
2553 ICOM_THIS( ITypeInfoImpl, iface);
2554 HRESULT result = E_FAIL;
2556 if(HREFTYPE_INTHISFILE(hRefType))
2558 ITypeLib *pTLib;
2559 int Index;
2560 result = ITypeInfo_GetContainingTypeLib(iface, &pTLib, &Index);
2561 if(SUCCEEDED( result ))
2563 result=ITypeLib2_GetTypeInfo(pTLib, HREFTYPE_INDEX(hRefType), ppTInfo);
2564 ITypeLib2_Release(pTLib );
2567 else if (hRefType == -1 &&
2568 (((ITypeInfoImpl*) This)->TypeAttr.typekind == TKIND_DISPATCH) &&
2569 (((ITypeInfoImpl*) This)->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL))
2571 /* when we meet a DUAL dispinterface, we must create the interface
2572 * version of it.
2574 ITypeInfoImpl* pTypeInfoImpl = (ITypeInfoImpl*) ITypeInfo_Constructor();
2577 /* the interface version contains the same information as the dispinterface
2578 * copy the contents of the structs.
2580 *pTypeInfoImpl = *This;
2581 pTypeInfoImpl->ref = 1;
2583 /* change the type to interface */
2584 pTypeInfoImpl->TypeAttr.typekind = TKIND_INTERFACE;
2586 *ppTInfo = (ITypeInfo*) pTypeInfoImpl;
2588 ITypeInfo_AddRef((ITypeInfo*) pTypeInfoImpl);
2590 result = S_OK;
2592 else
2594 /* imported type lib */
2595 TLBRefType *pRefType = NULL;
2597 /* search in implemented types */
2598 for( pRefType = This->impltypelist;
2599 pRefType && (pRefType->reference != hRefType);
2600 pRefType = pRefType->next);
2602 if(!pRefType)
2604 TYPEATTR* pMyTypeAttr = &This->TypeAttr;
2605 unsigned short cFuncs = pMyTypeAttr->cFuncs;
2606 unsigned short cVars = pMyTypeAttr->cVars;
2608 /* search in arguments */
2609 if (cFuncs > 0)
2611 unsigned short cFuncIndex = 0;
2613 TLBFuncDesc* pCurrFunc = This->funclist;
2615 for (cFuncIndex = 0; !pRefType && cFuncIndex < cFuncs ; ++cFuncIndex)
2617 FUNCDESC* pCurrFuncDesc = &pCurrFunc->funcdesc;
2619 short cParams = pCurrFuncDesc->cParams;
2620 short cParamIndex = 0;
2622 for (cParamIndex = 0 ;
2623 !pRefType && cParamIndex < cParams ;
2624 ++cParamIndex)
2626 TLBParDesc* pCurrParamDesc = &(pCurrFunc->pParamDesc[cParamIndex]);
2628 if ( pCurrParamDesc->pRefType && pCurrParamDesc->pRefType->reference == hRefType)
2630 pRefType = pCurrParamDesc->pRefType;
2631 break; /* also break from outer loop since pRefType != 0 */
2635 pCurrFunc = pCurrFunc->next;
2638 /* search in variables */
2639 else if (cVars > 0)
2641 FIXME("search hreftype in variables, if any\n");
2642 result = E_INVALIDARG; // FIXME : correct?
2646 /* href-referenced typeinfo found! */
2647 if (pRefType || hRefType == -1)
2649 ITypeLibImpl *pTypeLib = pRefType->pImpTLInfo->pImpTypeLib;
2651 if(pTypeLib)
2653 TRACE("typeinfo in imported typelib that is already loaded\n");
2655 result = ITypeLib2_GetTypeInfoOfGuid((LPTYPELIB)pTypeLib,
2656 &pRefType->guid,
2657 ppTInfo);
2659 else
2661 result = LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
2662 pRefType->pImpTLInfo->wVersionMajor,
2663 pRefType->pImpTLInfo->wVersionMinor,
2664 pRefType->pImpTLInfo->lcid,
2665 (LPTYPELIB *)&pTypeLib);
2667 if(!SUCCEEDED(result))
2669 BSTR libnam=SysAllocString(pRefType->pImpTLInfo->name);
2670 TRACE("typeinfo in imported typelib that isn't already loaded\n");
2671 result=LoadTypeLib(libnam, (LPTYPELIB *)&pTypeLib);
2672 SysFreeString(libnam);
2674 if(SUCCEEDED(result))
2676 result=ITypeLib2_GetTypeInfoOfGuid((LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo);
2677 pRefType->pImpTLInfo->pImpTypeLib = pTypeLib;
2678 ITypeLib2_AddRef((ITypeLib*) pTypeLib);
2684 TRACE("(%p) hreftype 0x%04lx loaded %s (%p)\n", This, hRefType,
2685 SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
2686 return result;
2689 /* ITypeInfo::AddressOfMember
2691 * Retrieves the addresses of static functions or variables, such as those
2692 * defined in a DLL.
2694 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface,
2695 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
2697 ICOM_THIS( ITypeInfoImpl, iface);
2698 FIXME("(%p) stub!\n", This);
2699 return S_OK;
2702 /* ITypeInfo::CreateInstance
2704 * Creates a new instance of a type that describes a component object class
2705 * (coclass).
2707 static HRESULT WINAPI ITypeInfo_fnCreateInstance( ITypeInfo2 *iface,
2708 IUnknown *pUnk, REFIID riid, VOID **ppvObj)
2710 ICOM_THIS( ITypeInfoImpl, iface);
2711 FIXME("(%p) stub!\n", This);
2712 return S_OK;
2715 /* ITypeInfo::GetMops
2717 * Retrieves marshaling information.
2719 static HRESULT WINAPI ITypeInfo_fnGetMops( ITypeInfo2 *iface, MEMBERID memid,
2720 BSTR *pBstrMops)
2722 ICOM_THIS( ITypeInfoImpl, iface);
2723 FIXME("(%p) stub!\n", This);
2724 return S_OK;
2727 /* ITypeInfo::GetContainingTypeLib
2729 * Retrieves the containing type library and the index of the type description
2730 * within that type library.
2732 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( ITypeInfo2 *iface,
2733 ITypeLib * *ppTLib, UINT *pIndex)
2735 ICOM_THIS( ITypeInfoImpl, iface);
2736 *ppTLib=(LPTYPELIB )(This->pTypeLib);
2737 *pIndex=This->index;
2738 ITypeLib2_AddRef(*ppTLib);
2739 TRACE("(%p) returns (%p) index %d!\n", This, *ppTLib, *pIndex);
2740 return S_OK;
2743 /* ITypeInfo::ReleaseTypeAttr
2745 * Releases a TYPEATTR previously returned by GetTypeAttr.
2748 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( ITypeInfo2 *iface,
2749 TYPEATTR* pTypeAttr)
2751 ICOM_THIS( ITypeInfoImpl, iface);
2752 TRACE("(%p)->(%p)\n", This, pTypeAttr);
2753 return S_OK;
2756 /* ITypeInfo::ReleaseFuncDesc
2758 * Releases a FUNCDESC previously returned by GetFuncDesc. *
2760 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc(
2761 ITypeInfo2 *iface,
2762 FUNCDESC *pFuncDesc)
2764 ICOM_THIS( ITypeInfoImpl, iface);
2765 TRACE("(%p)->(%p)\n", This, pFuncDesc);
2766 return S_OK;
2769 /* ITypeInfo::ReleaseVarDesc
2771 * Releases a VARDESC previously returned by GetVarDesc.
2773 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( ITypeInfo2 *iface,
2774 VARDESC *pVarDesc)
2776 ICOM_THIS( ITypeInfoImpl, iface);
2777 TRACE("(%p)->(%p)\n", This, pVarDesc);
2778 return S_OK;
2781 /* ITypeInfo2::GetTypeKind
2783 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
2786 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo2 * iface,
2787 TYPEKIND *pTypeKind)
2789 ICOM_THIS( ITypeInfoImpl, iface);
2790 *pTypeKind=This->TypeAttr.typekind;
2791 TRACE("(%p) type 0x%0x\n", This,*pTypeKind);
2792 return S_OK;
2795 /* ITypeInfo2::GetTypeFlags
2797 * Returns the type flags without any allocations. This returns a DWORD type
2798 * flag, which expands the type flags without growing the TYPEATTR (type
2799 * attribute).
2802 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo2 * iface,
2803 UINT *pTypeFlags)
2805 ICOM_THIS( ITypeInfoImpl, iface);
2806 *pTypeFlags=This->TypeAttr.wTypeFlags;
2807 TRACE("(%p) flags 0x%04x\n", This,*pTypeFlags);
2808 return S_OK;
2811 /* ITypeInfo2::GetFuncIndexOfMemId
2812 * Binds to a specific member based on a known DISPID, where the member name
2813 * is not known (for example, when binding to a default member).
2816 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2 * iface,
2817 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
2819 ICOM_THIS( ITypeInfoImpl, iface);
2820 TLBFuncDesc *pFuncInfo;
2821 int i;
2822 HRESULT result;
2823 /* FIXME: should check for invKind??? */
2824 for(i=0, pFuncInfo=This->funclist;pFuncInfo &&
2825 memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next);
2826 if(pFuncInfo){
2827 *pFuncIndex=i;
2828 result= S_OK;
2829 }else{
2830 *pFuncIndex=0;
2831 result=E_INVALIDARG;
2833 TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This,
2834 memid, invKind, SUCCEEDED(result)? "SUCCES":"FAILED");
2835 return result;
2838 /* TypeInfo2::GetVarIndexOfMemId
2840 * Binds to a specific member based on a known DISPID, where the member name
2841 * is not known (for example, when binding to a default member).
2844 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo2 * iface,
2845 MEMBERID memid, UINT *pVarIndex)
2847 ICOM_THIS( ITypeInfoImpl, iface);
2848 TLBVarDesc *pVarInfo;
2849 int i;
2850 HRESULT result;
2851 for(i=0, pVarInfo=This->varlist; pVarInfo &&
2852 memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next)
2854 if(pVarInfo){
2855 *pVarIndex=i;
2856 result= S_OK;
2857 }else{
2858 *pVarIndex=0;
2859 result=E_INVALIDARG;
2861 TRACE("(%p) memid 0x%08lx -> %s\n", This,
2862 memid, SUCCEEDED(result)? "SUCCES":"FAILED");
2863 return result;
2866 /* ITypeInfo2::GetCustData
2868 * Gets the custom data
2870 static HRESULT WINAPI ITypeInfo2_fnGetCustData(
2871 ITypeInfo2 * iface,
2872 REFGUID guid,
2873 VARIANT *pVarVal)
2875 ICOM_THIS( ITypeInfoImpl, iface);
2876 TLBCustData *pCData;
2878 for(pCData=This->pCustData; pCData; pCData = pCData->next)
2879 if( IsEqualIID(guid, &pCData->guid)) break;
2881 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2883 if(pCData)
2885 VariantInit( pVarVal);
2886 VariantCopy( pVarVal, &pCData->data);
2887 return S_OK;
2889 return E_INVALIDARG; /* FIXME: correct? */
2892 /* ITypeInfo2::GetFuncCustData
2894 * Gets the custom data
2896 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData(
2897 ITypeInfo2 * iface,
2898 UINT index,
2899 REFGUID guid,
2900 VARIANT *pVarVal)
2902 ICOM_THIS( ITypeInfoImpl, iface);
2903 TLBCustData *pCData=NULL;
2904 TLBFuncDesc * pFDesc;
2905 int i;
2906 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
2907 pFDesc=pFDesc->next);
2909 if(pFDesc)
2910 for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next)
2911 if( IsEqualIID(guid, &pCData->guid)) break;
2913 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2915 if(pCData){
2916 VariantInit( pVarVal);
2917 VariantCopy( pVarVal, &pCData->data);
2918 return S_OK;
2920 return E_INVALIDARG; /* FIXME: correct? */
2923 /* ITypeInfo2::GetParamCustData
2925 * Gets the custom data
2927 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData(
2928 ITypeInfo2 * iface,
2929 UINT indexFunc,
2930 UINT indexParam,
2931 REFGUID guid,
2932 VARIANT *pVarVal)
2934 ICOM_THIS( ITypeInfoImpl, iface);
2935 TLBCustData *pCData=NULL;
2936 TLBFuncDesc * pFDesc;
2937 int i;
2939 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,pFDesc=pFDesc->next);
2941 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams)
2942 for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData;
2943 pCData = pCData->next)
2944 if( IsEqualIID(guid, &pCData->guid)) break;
2946 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2948 if(pCData)
2950 VariantInit( pVarVal);
2951 VariantCopy( pVarVal, &pCData->data);
2952 return S_OK;
2954 return E_INVALIDARG; /* FIXME: correct? */
2957 /* ITypeInfo2::GetVarcCustData
2959 * Gets the custom data
2961 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData(
2962 ITypeInfo2 * iface,
2963 UINT index,
2964 REFGUID guid,
2965 VARIANT *pVarVal)
2967 ICOM_THIS( ITypeInfoImpl, iface);
2968 TLBCustData *pCData=NULL;
2969 TLBVarDesc * pVDesc;
2970 int i;
2972 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next);
2974 if(pVDesc)
2976 for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next)
2978 if( IsEqualIID(guid, &pCData->guid)) break;
2982 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
2984 if(pCData)
2986 VariantInit( pVarVal);
2987 VariantCopy( pVarVal, &pCData->data);
2988 return S_OK;
2990 return E_INVALIDARG; /* FIXME: correct? */
2993 /* ITypeInfo2::GetImplcCustData
2995 * Gets the custom data
2997 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData(
2998 ITypeInfo2 * iface,
2999 UINT index,
3000 REFGUID guid,
3001 VARIANT *pVarVal)
3003 ICOM_THIS( ITypeInfoImpl, iface);
3004 TLBCustData *pCData=NULL;
3005 TLBRefType * pRDesc;
3006 int i;
3008 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++, pRDesc=pRDesc->next);
3010 if(pRDesc)
3012 for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next)
3014 if( IsEqualIID(guid, &pCData->guid)) break;
3018 TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
3020 if(pCData)
3022 VariantInit( pVarVal);
3023 VariantCopy( pVarVal, &pCData->data);
3024 return S_OK;
3026 return E_INVALIDARG; /* FIXME: correct? */
3029 /* ITypeInfo2::GetDocumentation2
3031 * Retrieves the documentation string, the complete Help file name and path,
3032 * the localization context to use, and the context ID for the library Help
3033 * topic in the Help file.
3036 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(
3037 ITypeInfo2 * iface,
3038 MEMBERID memid,
3039 LCID lcid,
3040 BSTR *pbstrHelpString,
3041 DWORD *pdwHelpStringContext,
3042 BSTR *pbstrHelpStringDll)
3044 ICOM_THIS( ITypeInfoImpl, iface);
3045 TLBFuncDesc * pFDesc;
3046 TLBVarDesc * pVDesc;
3047 TRACE("(%p) memid %ld lcid(0x%lx) HelpString(%p) "
3048 "HelpStringContext(%p) HelpStringDll(%p)\n",
3049 This, memid, lcid, pbstrHelpString, pdwHelpStringContext,
3050 pbstrHelpStringDll );
3051 /* the help string should be obtained from the helpstringdll,
3052 * using the _DLLGetDocumentation function, based on the supplied
3053 * lcid. Nice to do sometime...
3055 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
3056 if(pbstrHelpString)
3057 *pbstrHelpString=SysAllocString(This->Name);
3058 if(pdwHelpStringContext)
3059 *pdwHelpStringContext=This->dwHelpStringContext;
3060 if(pbstrHelpStringDll)
3061 *pbstrHelpStringDll=
3062 SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */
3063 return S_OK;
3064 }else {/* for a member */
3065 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
3066 if(pFDesc->funcdesc.memid==memid){
3067 if(pbstrHelpString)
3068 *pbstrHelpString=SysAllocString(pFDesc->HelpString);
3069 if(pdwHelpStringContext)
3070 *pdwHelpStringContext=pFDesc->HelpStringContext;
3071 if(pbstrHelpStringDll)
3072 *pbstrHelpStringDll=
3073 SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */
3074 return S_OK;
3076 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
3077 if(pVDesc->vardesc.memid==memid){
3078 if(pbstrHelpString)
3079 *pbstrHelpString=SysAllocString(pVDesc->HelpString);
3080 if(pdwHelpStringContext)
3081 *pdwHelpStringContext=pVDesc->HelpStringContext;
3082 if(pbstrHelpStringDll)
3083 *pbstrHelpStringDll=
3084 SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */
3085 return S_OK;
3088 return TYPE_E_ELEMENTNOTFOUND;
3091 /* ITypeInfo2::GetAllCustData
3093 * Gets all custom data items for the Type info.
3096 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData(
3097 ITypeInfo2 * iface,
3098 CUSTDATA *pCustData)
3100 ICOM_THIS( ITypeInfoImpl, iface);
3101 TLBCustData *pCData;
3102 int i;
3104 TRACE("(%p) returning %d items\n", This, This->ctCustData);
3106 pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
3107 if(pCustData->prgCustData ){
3108 pCustData->cCustData=This->ctCustData;
3109 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
3110 pCustData->prgCustData[i].guid=pCData->guid;
3111 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
3113 }else{
3114 ERR(" OUT OF MEMORY! \n");
3115 return E_OUTOFMEMORY;
3117 return S_OK;
3120 /* ITypeInfo2::GetAllFuncCustData
3122 * Gets all custom data items for the specified Function
3125 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData(
3126 ITypeInfo2 * iface,
3127 UINT index,
3128 CUSTDATA *pCustData)
3130 ICOM_THIS( ITypeInfoImpl, iface);
3131 TLBCustData *pCData;
3132 TLBFuncDesc * pFDesc;
3133 int i;
3134 TRACE("(%p) index %d\n", This, index);
3135 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
3136 pFDesc=pFDesc->next)
3138 if(pFDesc){
3139 pCustData->prgCustData =
3140 TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM));
3141 if(pCustData->prgCustData ){
3142 pCustData->cCustData=pFDesc->ctCustData;
3143 for(i=0, pCData=pFDesc->pCustData; pCData; i++,
3144 pCData = pCData->next){
3145 pCustData->prgCustData[i].guid=pCData->guid;
3146 VariantCopy(& pCustData->prgCustData[i].varValue,
3147 & pCData->data);
3149 }else{
3150 ERR(" OUT OF MEMORY! \n");
3151 return E_OUTOFMEMORY;
3153 return S_OK;
3155 return TYPE_E_ELEMENTNOTFOUND;
3158 /* ITypeInfo2::GetAllParamCustData
3160 * Gets all custom data items for the Functions
3163 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo2 * iface,
3164 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
3166 ICOM_THIS( ITypeInfoImpl, iface);
3167 TLBCustData *pCData=NULL;
3168 TLBFuncDesc * pFDesc;
3169 int i;
3170 TRACE("(%p) index %d\n", This, indexFunc);
3171 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
3172 pFDesc=pFDesc->next)
3174 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams){
3175 pCustData->prgCustData =
3176 TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData *
3177 sizeof(CUSTDATAITEM));
3178 if(pCustData->prgCustData ){
3179 pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData;
3180 for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData;
3181 pCData; i++, pCData = pCData->next){
3182 pCustData->prgCustData[i].guid=pCData->guid;
3183 VariantCopy(& pCustData->prgCustData[i].varValue,
3184 & pCData->data);
3186 }else{
3187 ERR(" OUT OF MEMORY! \n");
3188 return E_OUTOFMEMORY;
3190 return S_OK;
3192 return TYPE_E_ELEMENTNOTFOUND;
3195 /* ITypeInfo2::GetAllVarCustData
3197 * Gets all custom data items for the specified Variable
3200 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo2 * iface,
3201 UINT index, CUSTDATA *pCustData)
3203 ICOM_THIS( ITypeInfoImpl, iface);
3204 TLBCustData *pCData;
3205 TLBVarDesc * pVDesc;
3206 int i;
3207 TRACE("(%p) index %d\n", This, index);
3208 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
3209 pVDesc=pVDesc->next)
3211 if(pVDesc){
3212 pCustData->prgCustData =
3213 TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM));
3214 if(pCustData->prgCustData ){
3215 pCustData->cCustData=pVDesc->ctCustData;
3216 for(i=0, pCData=pVDesc->pCustData; pCData; i++,
3217 pCData = pCData->next){
3218 pCustData->prgCustData[i].guid=pCData->guid;
3219 VariantCopy(& pCustData->prgCustData[i].varValue,
3220 & pCData->data);
3222 }else{
3223 ERR(" OUT OF MEMORY! \n");
3224 return E_OUTOFMEMORY;
3226 return S_OK;
3228 return TYPE_E_ELEMENTNOTFOUND;
3231 /* ITypeInfo2::GetAllImplCustData
3233 * Gets all custom data items for the specified implementation type
3236 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData(
3237 ITypeInfo2 * iface,
3238 UINT index,
3239 CUSTDATA *pCustData)
3241 ICOM_THIS( ITypeInfoImpl, iface);
3242 TLBCustData *pCData;
3243 TLBRefType * pRDesc;
3244 int i;
3245 TRACE("(%p) index %d\n", This, index);
3246 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
3247 pRDesc=pRDesc->next)
3249 if(pRDesc){
3250 pCustData->prgCustData =
3251 TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM));
3252 if(pCustData->prgCustData ){
3253 pCustData->cCustData=pRDesc->ctCustData;
3254 for(i=0, pCData=pRDesc->pCustData; pCData; i++,
3255 pCData = pCData->next){
3256 pCustData->prgCustData[i].guid=pCData->guid;
3257 VariantCopy(& pCustData->prgCustData[i].varValue,
3258 & pCData->data);
3260 }else{
3261 ERR(" OUT OF MEMORY! \n");
3262 return E_OUTOFMEMORY;
3264 return S_OK;
3266 return TYPE_E_ELEMENTNOTFOUND;
3269 static ICOM_VTABLE(ITypeInfo2) tinfvt =
3271 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3273 ITypeInfo_fnQueryInterface,
3274 ITypeInfo_fnAddRef,
3275 ITypeInfo_fnRelease,
3277 ITypeInfo_fnGetTypeAttr,
3278 ITypeInfo_fnGetTypeComp,
3279 ITypeInfo_fnGetFuncDesc,
3280 ITypeInfo_fnGetVarDesc,
3281 ITypeInfo_fnGetNames,
3282 ITypeInfo_fnGetRefTypeOfImplType,
3283 ITypeInfo_fnGetImplTypeFlags,
3284 ITypeInfo_fnGetIDsOfNames,
3285 ITypeInfo_fnInvoke,
3286 ITypeInfo_fnGetDocumentation,
3287 ITypeInfo_fnGetDllEntry,
3288 ITypeInfo_fnGetRefTypeInfo,
3289 ITypeInfo_fnAddressOfMember,
3290 ITypeInfo_fnCreateInstance,
3291 ITypeInfo_fnGetMops,
3292 ITypeInfo_fnGetContainingTypeLib,
3293 ITypeInfo_fnReleaseTypeAttr,
3294 ITypeInfo_fnReleaseFuncDesc,
3295 ITypeInfo_fnReleaseVarDesc,
3297 ITypeInfo2_fnGetTypeKind,
3298 ITypeInfo2_fnGetTypeFlags,
3299 ITypeInfo2_fnGetFuncIndexOfMemId,
3300 ITypeInfo2_fnGetVarIndexOfMemId,
3301 ITypeInfo2_fnGetCustData,
3302 ITypeInfo2_fnGetFuncCustData,
3303 ITypeInfo2_fnGetParamCustData,
3304 ITypeInfo2_fnGetVarCustData,
3305 ITypeInfo2_fnGetImplTypeCustData,
3306 ITypeInfo2_fnGetDocumentation2,
3307 ITypeInfo2_fnGetAllCustData,
3308 ITypeInfo2_fnGetAllFuncCustData,
3309 ITypeInfo2_fnGetAllParamCustData,
3310 ITypeInfo2_fnGetAllVarCustData,
3311 ITypeInfo2_fnGetAllImplTypeCustData,