4 * Copyright 1997 Marcus Meissner
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
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.
49 #include "winreg.h" /* for HKEY_LOCAL_MACHINE */
50 #include "winnls.h" /* for PRIMARYLANGID */
53 #include "wine/obj_base.h"
54 #include "debugtools.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\"
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 */
76 char typelibkey
[100],pathname
[260];
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],
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
);
92 plen
= sizeof(pathname
);
93 if (RegQueryValueA(HKEY_LOCAL_MACHINE
,typelibkey
,pathname
,&plen
)) {
94 /* try again without lang specific id */
96 return QueryPathOfRegTypeLib16(guid
,wMaj
,wMin
,PRIMARYLANGID(lcid
),path
);
97 FIXME("key %s not found\n",typelibkey
);
100 *path
= SysAllocString16(pathname
);
104 /****************************************************************************
105 * QueryPathOfRegTypeLib [OLEAUT32.164]
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 */
122 DWORD dwPathLen
= _MAX_PATH
;
126 char szTypeLibKey
[100];
127 char szPath
[dwPathLen
];
135 FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n", szXGUID
, wMaj
, wMin
, (DWORD
)lcid
, path
);
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],
150 if (RegQueryValueA(HKEY_LOCAL_MACHINE
, szTypeLibKey
, szPath
, &dwPathLen
))
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 */
171 DWORD len
= MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, szPath
, dwPathLen
, NULL
, 0 );
172 BSTR bstrPath
= SysAllocStringLen(NULL
,len
);
174 MultiByteToWideChar(CP_ACP
,
186 TRACE_(typelib
)("%s not found\n", szTypeLibKey
);
191 /******************************************************************************
192 * CreateTypeLib [OLEAUT32] creates a typelib
198 HRESULT WINAPI
CreateTypeLib(
199 SYSKIND syskind
, LPCOLESTR szFile
, ICreateTypeLib
** ppctlib
201 FIXME("(%d,%s,%p), stub!\n",syskind
,debugstr_w(szFile
),ppctlib
);
204 /******************************************************************************
205 * LoadTypeLib [TYPELIB.3] Loads and registers a type library
207 * Docs: OLECHAR FAR* szFile
208 * Docs: iTypeLib FAR* FAR* pptLib
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
);
226 /******************************************************************************
227 * LoadTypeLib [OLEAUT32.161]
228 * Loads and registers a type library
230 * Docs: OLECHAR FAR* szFile
231 * Docs: iTypeLib FAR* FAR* pptLib
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 */
244 return LoadTypeLibEx(szFile
, REGKIND_DEFAULT
, pptLib
);
247 /******************************************************************************
248 * LoadTypeLibEx [OLEAUT32.183]
249 * Loads and optionally registers a type library
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 */
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
);
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 */
287 HRESULT res
=QueryPathOfRegTypeLib( rguid
, wVerMajor
, wVerMinor
, lcid
, &bstr
);
291 res
= LoadTypeLib(bstr
, ppTLib
);
295 TRACE("(IID: %s) load %s (%p)\n",debugstr_guid(rguid
), SUCCEEDED(res
)? "SUCCESS":"FAILED", *ppTLib
);
301 /******************************************************************************
302 * RegisterTypeLib [OLEAUT32.163]
303 * Adds information about a type library to the System Registry
305 * Docs: ITypeLib FAR * ptlib
306 * Docs: OLECHAR FAR* szFullPath
307 * Docs: OLECHAR FAR* szHelpDir
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,
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
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 */
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
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 */
375 FIXME("Version value not known yet. Please investigate it !");
380 /* for better debugging info leave the static out for the time being */
383 /*======================= ITypeLib implementation =======================*/
385 typedef struct tagTLBCustData
389 struct tagTLBCustData
* next
;
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
;
408 /* internal ITypeLib data */
409 typedef struct tagITypeLibImpl
411 ICOM_VFIELD(ITypeLib2
);
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.
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 */
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) */
446 TLBCustData
* pCustData
;/* linked list to custom data; */
447 TLBImpLib
*pImpTLInfo
;
448 struct tagTLBRefType
* next
;
451 /* internal Parameter data */
452 typedef struct tagTLBParDesc
456 TLBCustData
* pCustData
; /* linked list to cust data; */
457 TLBRefType
* pRefType
; /* linked list to referenced types */
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 */
467 int HelpStringContext
;
469 BSTR Entry
; /* if its Hiword==0, it numeric; -1 is not present*/
471 TLBCustData
* pCustData
; /* linked list to cust data; */
472 struct tagTLBFuncDesc
* next
;
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 */
481 int HelpStringContext
; /* fixme: where? */
484 TLBCustData
* pCustData
;/* linked list to cust data; */
485 struct tagTLBVarDesc
* next
;
488 /* internal TypeInfo data */
489 typedef struct tagITypeInfoImpl
491 ICOM_VFIELD(ITypeInfo2
);
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?
501 unsigned long dwHelpContext
;
502 unsigned long dwHelpStringContext
;
505 TLBFuncDesc
* funclist
; /* linked list with function descriptions */
508 TLBVarDesc
* varlist
; /* linked list with variable descriptions */
510 /* Implemented Interfaces */
511 TLBRefType
* impltypelist
;
513 TLBCustData
* pCustData
; /* linked list to cust data; */
514 struct tagITypeInfoImpl
* next
;
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 */
528 ITypeLibImpl
* pLibInfo
;
532 static void TLB_DoRefType(TLBContext
*pcx
, int offset
, TLBRefType
** pprtd
);
537 static void dump_TLBFuncDesc(TLBFuncDesc
* pfd
)
541 TRACE("%s(%u)\n", debugstr_w(pfd
->Name
), pfd
->funcdesc
.cParams
);
545 static void dump_TLBVarDesc(TLBVarDesc
* pvd
)
549 TRACE("%s\n", debugstr_w(pvd
->Name
));
553 static void dump_TLBRefType(TLBRefType
* prt
)
557 TRACE("%s\n", debugstr_guid(&(prt
->guid
)));
558 TRACE(" href:0x%08lx\n", prt
->reference
);
563 static void dump_Variant(VARIANT
* pvar
)
565 TRACE("%p %x\n", pvar
, pvar
?pvar
->vt
:0 );
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
[] =
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},
618 static void TLB_abort()
622 static void * TLB_Alloc(unsigned size
)
625 if((ret
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,size
))==NULL
){
627 ERR("cannot allocate memory\n");
632 static void TLB_Free(void * ptr
)
634 HeapFree(GetProcessHeap(), 0, ptr
);
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
)
648 ERR("seek beyond end (%ld/%d)\n", where
, pcx
->length
);
653 if (pcx
->pos
+ count
> pcx
->length
) count
= pcx
->length
- pcx
->pos
;
654 memcpy( buffer
, (char *)pcx
->mapping
+ pcx
->pos
, 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
));
667 TLB_Read(pGuid
, sizeof(GUID
), pcx
, pcx
->pTblDir
->pGuidTab
.offset
+offset
);
670 BSTR
TLB_ReadName( TLBContext
*pcx
, int offset
)
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 */
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
);
705 BSTR
TLB_ReadString( TLBContext
*pcx
, int offset
)
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
);
719 lengthInChars
= MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
| MB_ERR_INVALID_CHARS
,
720 string
, -1, NULL
, NULL
);
722 /* no invalid characters in string */
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
);
739 * read a value and fill a VARIANT structure
741 static void TLB_ReadValue( VARIANT
* pVar
, int offset
, TLBContext
*pcx
)
747 if(offset
<0) { /* data is packed in here */
748 pVar
->vt
= (offset
& 0x7c000000 )>> 26;
749 V_UNION(pVar
, iVal
) = offset
& 0xffff;
752 TLB_Read(&(pVar
->vt
), sizeof(VARTYPE
), pcx
,
753 pcx
->pTblDir
->pCustData
.offset
+ offset
);
754 TRACE("Vartype = %x\n", 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 */
769 case VT_VOID
: /* FIXME: is this right? */
777 case VT_DECIMAL
: /* FIXME: is this right? */
780 /* pointer types with known behaviour */
783 TLB_Read(&size
, sizeof(INT
), pcx
, DO_NOT_SEEK
);
785 FIXME("BSTR length = %d?\n", size
);
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
];
797 /* FIXME: this will not work AT ALL when the variant contains a pointer */
804 case VT_USERDEFINED
:
810 case VT_STREAMED_OBJECT
:
811 case VT_STORED_OBJECT
:
812 case VT_BLOB_OBJECT
:
817 FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
821 if(size
>0) /* (big|small) endian correct? */
822 TLB_Read(&(V_UNION(pVar
, iVal
)), size
, pcx
, DO_NOT_SEEK
);
826 * create a linked list with custom data
828 static int TLB_CustData( TLBContext
*pcx
, int offset
, TLBCustData
** ppCustData
)
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
;
851 static void TLB_GetTdesc(TLBContext
*pcx
, INT type
,TYPEDESC
* pTd
)
854 pTd
->vt
=type
& VT_TYPEMASK
;
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
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
881 * Third is a equal sized array with file offsets to the name entry
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
;
890 TLBFuncRecord
* pFuncRec
=(TLBFuncRecord
*) recbuf
;
892 int recoffset
=offset
+sizeof(INT
);
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
);
906 TLB_Read(pFuncRec
, reclength
- sizeof(INT
), pcx
, DO_NOT_SEEK
) ;
907 /* do the attributes */
908 nrattributes
=(reclength
-pFuncRec
->nrargs
*3*sizeof(int)-0x18)
911 (*pptfd
)->helpcontext
= pFuncRec
->OptAttr
[0] ;
913 (*pptfd
)->HelpString
= TLB_ReadString(pcx
,
914 pFuncRec
->OptAttr
[1]) ;
916 if(pFuncRec
->FKCCIC
& 0x2000)
917 (*pptfd
)->Entry
= (WCHAR
*) pFuncRec
->OptAttr
[2] ;
919 (*pptfd
)->Entry
= TLB_ReadString(pcx
,
920 pFuncRec
->OptAttr
[2]);
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
*
951 TLB_Read(¶minfo
,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(¶minfo
,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
)
976 lpArgTypeDesc
= lpArgTypeDesc
->u
.lptdesc
;
980 lpArgTypeDesc
= & (lpArgTypeDesc
->u
.lpadesc
->tdescElem
);
984 (*pptfd
)->pParamDesc
[j
].pRefType
= TLB_Alloc(sizeof(TLBRefType
));
985 TLB_DoRefType(pcx
, lpArgTypeDesc
->u
.hreftype
, &((*pptfd
)->pParamDesc
[j
].pRefType
));
986 lpArgTypeDesc
= NULL
;
990 lpArgTypeDesc
= NULL
;
994 /* second time around */
995 for(j
=0;j
<pFuncRec
->nrargs
;j
++){
997 (*pptfd
)->pParamDesc
[j
].Name
=
998 TLB_ReadName(pcx
, (int)(*pptfd
)->pParamDesc
[j
].Name
);
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
),
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
;
1030 TLBVarRecord
* pVarRec
=(TLBVarRecord
*) recbuf
;
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
);
1049 TLB_Read(pVarRec
, reclength
- sizeof(INT
), pcx
, DO_NOT_SEEK
) ;
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
);
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
1080 static void TLB_DoRefType(TLBContext
*pcx
,
1081 int offset
, TLBRefType
** pprtd
)
1085 TRACE("TLB context %p, TLB offset %x\n", pcx
, offset
);
1087 if(!HREFTYPE_INTHISFILE( offset
)) {
1088 /* external typelib */
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
;
1101 (*pprtd
)->reference
=offset
;
1102 (*pprtd
)->pImpTLInfo
= pImpLib
;
1103 TLB_ReadGuid(&(*pprtd
)->guid
, impinfo
.oGuid
, pcx
);
1105 ERR("Cannot find a reference\n");
1106 (*pprtd
)->reference
=-1;
1107 (*pprtd
)->pImpTLInfo
=(void *)-1;
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
)
1121 TLBRefRecord refrec
;
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(
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
) ;
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
));
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 :(
1190 if(ptiRet
->TypeAttr
.cFuncs
>0 )
1191 TLB_DoFuncs(pcx
, ptiRet
->TypeAttr
.cFuncs
,ptiRet
->TypeAttr
.cVars
,
1192 tiBase
.memoffset
, & ptiRet
->funclist
);
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
)
1201 TLB_DoImplTypes(pcx
, ptiRet
->TypeAttr
.cImplTypes
,
1202 tiBase
.datatype1
, & ptiRet
->impltypelist
);
1204 case TKIND_DISPATCH
:
1205 ptiRet
->impltypelist
=TLB_Alloc(sizeof(TLBRefType
));
1207 if (tiBase
.datatype1
!= -1)
1209 TLB_DoRefType(pcx
, tiBase
.datatype1
, & ptiRet
->impltypelist
);
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
,
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;
1235 ptiRet
->impltypelist
=TLB_Alloc(sizeof(TLBRefType
));
1236 TLB_DoRefType(pcx
, tiBase
.datatype1
, & ptiRet
->impltypelist
);
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
]);
1251 /****************************************************************************
1254 * find the type of the typelib file and map the typelib resource into
1257 #define MSFT_SIGNATURE 0x5446534D /* "MSFT" */
1258 int TLB_ReadTypeLib(LPSTR pszFileName
, ITypeLib2
**ppTypeLib
)
1261 DWORD dwSignature
= 0;
1263 int nStrLen
= strlen(pszFileName
);
1266 PCHAR pszTypeLibIndex
= NULL
;
1267 PCHAR pszDllName
= NULL
;
1269 TRACE("%s\n", pszFileName
);
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(),
1296 strncpy(pszDllName
, pszFileName
, nMemToAlloc
);
1298 /* move index string pointer pass the backslash */
1303 /* No index, reset variable to 1 */
1304 pszDllName
= HeapAlloc(GetProcessHeap(),
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
);
1324 LPVOID pBase
= MapViewOfFile(hMapping
, FILE_MAP_READ
, 0, 0, 0);
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
);
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
);
1350 HRSRC hrsrc
= FindResourceA(hinstDLL
, MAKEINTRESOURCEA(atoi(pszTypeLibIndex
)), "TYPELIB");
1353 HGLOBAL hGlobal
= LoadResource(hinstDLL
, hrsrc
);
1356 LPVOID pBase
= LockResource(hGlobal
);
1357 DWORD dwTLBLength
= SizeofResource(hinstDLL
, hrsrc
);
1361 /* try to load as incore resource */
1362 dwSignature
= *((DWORD
*) pBase
);
1363 if ( dwSignature
== MSFT_SIGNATURE
)
1364 *ppTypeLib
= ITypeLib2_Constructor(pBase
, dwTLBLength
);
1366 FIXME("Header type magic 0x%08lx not supported.\n",dwSignature
);
1368 FreeResource( hGlobal
);
1371 FreeLibrary(hinstDLL
);
1375 HeapFree(GetProcessHeap(), 0, pszDllName
);
1380 ERR("Loading of typelib %s failed with error 0x%08lx\n", pszFileName
, GetLastError());
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
)
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 */
1412 cx
.pLibInfo
= pTypeLibImpl
;
1413 cx
.length
= dwTLBLength
;
1416 TLB_Read((void*)&tlbHeader
, sizeof(tlbHeader
), &cx
, 0);
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
);
1423 /* there is a small number of information here until the next important
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
);
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
);
1454 pTypeLibImpl
->DocString
= TLB_ReadString(&cx
, tlbHeader
.helpstring
);
1455 pTypeLibImpl
->HelpFile
= TLB_ReadString(&cx
, tlbHeader
.helpfile
);
1457 if( tlbHeader
.varflags
& HELPDLLFLAG
)
1460 TLB_Read(&offset
, sizeof(offset
), &cx
, sizeof(tlbHeader
));
1461 pTypeLibImpl
->HelpStringDll
= TLB_ReadString(&cx
, offset
);
1464 pTypeLibImpl
->dwHelpContext
= tlbHeader
.helpstringcontext
;
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
));
1477 pTypeLibImpl
->pTypeDesc
= TLB_Alloc( cTD
* sizeof(TYPEDESC
));
1478 TLB_Read(td
, sizeof(td
), &cx
, tlbSegDir
.pTypdescTab
.offset
);
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 */
1487 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lptdesc
)= & stndTypeDesc
[td
[2]];
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 */
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));
1513 V_UNION(&(pTypeLibImpl
->pTypeDesc
[i
]),lpadesc
)->tdescElem
.vt
= td
[0] & VT_TYPEMASK
;
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
);
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
;
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
);
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
;
1564 if(tlbHeader
.nrtypeinfos
>= 0 )
1566 /*pTypeLibImpl->TypeInfoCount=tlbHeader.nrtypeinfos; */
1567 ITypeInfoImpl
**ppTI
= &(pTypeLibImpl
->pTypeInfo
);
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(
1590 ICOM_THIS( ITypeLibImpl
, iface
);
1592 TRACE("(%p)->(IID: %s)\n",This
,debugstr_guid(riid
));
1595 if(IsEqualIID(riid
, &IID_IUnknown
) ||
1596 IsEqualIID(riid
,&IID_ITypeLib
)||
1597 IsEqualIID(riid
,&IID_ITypeLib2
))
1604 ITypeLib2_AddRef(iface
);
1605 TRACE("-- Interface: (%p)->(%p)\n",ppvObject
,*ppvObject
);
1608 TRACE("-- Interface: E_NOINTERFACE\n");
1609 return E_NOINTERFACE
;
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
);
1633 /* fixme destroy child objects */
1635 TRACE(" destroying ITypeLib(%p)\n",This
);
1639 SysFreeString(This
->Name
);
1643 if (This
->DocString
)
1645 SysFreeString(This
->DocString
);
1646 This
->DocString
= NULL
;
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
);
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(
1686 ITypeInfo
**ppTInfo
)
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
;
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
);
1713 /* ITypeLibs::GetTypeInfoType
1715 * Retrieves the type of a type description.
1717 static HRESULT WINAPI
ITypeLib2_fnGetTypeInfoType(
1722 ICOM_THIS( ITypeLibImpl
, iface
);
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
++)
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
);
1746 /* ITypeLib::GetTypeInfoOfGuid
1748 * Retrieves the type description that corresponds to the specified GUID.
1751 static HRESULT WINAPI
ITypeLib2_fnGetTypeInfoOfGuid(
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
;
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
);
1780 /* ITypeLib::GetLibAttr
1782 * Retrieves the structure that contains the library's attributes.
1785 static HRESULT WINAPI
ITypeLib2_fnGetLibAttr(
1787 LPTLIBATTR
*ppTLibAttr
)
1789 ICOM_THIS( ITypeLibImpl
, iface
);
1790 TRACE("(%p)\n",This
);
1791 /* FIXME: must do a copy here */
1792 *ppTLibAttr
=&This
->LibAttr
;
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(
1804 ITypeComp
**ppTComp
)
1806 ICOM_THIS( ITypeLibImpl
, iface
);
1807 FIXME("(%p): stub!\n",This
);
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
1818 static HRESULT WINAPI
ITypeLib2_fnGetDocumentation(
1822 BSTR
*pBstrDocString
,
1823 DWORD
*pdwHelpContext
,
1824 BSTR
*pBstrHelpFile
)
1826 ICOM_THIS( ITypeLibImpl
, iface
);
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 */
1834 *pBstrName
=SysAllocString(This
->Name
);
1836 *pBstrDocString
=SysAllocString(This
->DocString
);
1838 *pdwHelpContext
=This
->dwHelpContext
;
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
))
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(
1866 ICOM_THIS( ITypeLibImpl
, iface
);
1867 ITypeInfoImpl
*pTInfo
;
1868 TLBFuncDesc
*pFInfo
;
1871 UINT nNameBufLen
= SysStringLen(szNameBuf
);
1873 TRACE("(%p)->(%s,%08lx,%p)\n", This
, debugstr_w(szNameBuf
), lHashVal
,
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
;
1891 ITypeLib2_fnIsName_exit
:
1892 TRACE("(%p)slow! search for %s: %s found!\n", This
,
1893 debugstr_w(szNameBuf
), *pfName
?"NOT":"");
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(
1908 ITypeInfo
**ppTInfo
,
1912 ICOM_THIS( ITypeLibImpl
, iface
);
1913 ITypeInfoImpl
*pTInfo
;
1914 TLBFuncDesc
*pFInfo
;
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
;
1931 ITypeLib2_fnFindName_exit
:
1932 ITypeInfo_AddRef((ITypeInfo
*)pTInfo
);
1933 ppTInfo
[j
]=(LPTYPEINFO
)pTInfo
;
1936 TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
1937 This
, *pcFound
, debugstr_w(szNameBuf
), j
);
1944 /* ITypeLib::ReleaseTLibAttr
1946 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
1949 static VOID WINAPI
ITypeLib2_fnReleaseTLibAttr(
1951 TLIBATTR
*pTLibAttr
)
1953 ICOM_THIS( ITypeLibImpl
, iface
);
1954 TRACE("freeing (%p)\n",This
);
1958 /* ITypeLib2::GetCustData
1960 * gets the custom data
1962 static HRESULT WINAPI
ITypeLib2_fnGetCustData(
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");
1979 VariantInit( pVarVal
);
1980 VariantCopy( pVarVal
, &pCData
->data
);
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(
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;
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(
2017 BSTR
*pbstrHelpString
,
2018 DWORD
*pdwHelpStringContext
,
2019 BSTR
*pbstrHelpStringDll
)
2021 ICOM_THIS( ITypeLibImpl
, iface
);
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...
2033 /* documentation for the typelib */
2035 *pbstrHelpString
=SysAllocString(This
->DocString
);
2036 if(pdwHelpStringContext
)
2037 *pdwHelpStringContext
=This
->dwHelpContext
;
2038 if(pbstrHelpStringDll
)
2039 *pbstrHelpStringDll
=SysAllocString(This
->HelpStringDll
);
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
))
2063 /* ITypeLib2::GetAllCustData
2065 * Gets all custom data items for the library.
2068 static HRESULT WINAPI
ITypeLib2_fnGetAllCustData(
2070 CUSTDATA
*pCustData
)
2072 ICOM_THIS( ITypeLibImpl
, iface
);
2073 TLBCustData
*pCData
;
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
);
2084 ERR(" OUT OF MEMORY! \n");
2085 return E_OUTOFMEMORY
;
2090 static ICOM_VTABLE(ITypeLib2
) tlbvt
= {
2091 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2092 ITypeLib2_fnQueryInterface
,
2094 ITypeLib2_fnRelease
,
2095 ITypeLib2_fnGetTypeInfoCount
,
2096 ITypeLib2_fnGetTypeInfo
,
2097 ITypeLib2_fnGetTypeInfoType
,
2098 ITypeLib2_fnGetTypeInfoOfGuid
,
2099 ITypeLib2_fnGetLibAttr
,
2100 ITypeLib2_fnGetTypeComp
,
2101 ITypeLib2_fnGetDocumentation
,
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
));
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(
2134 ICOM_THIS( ITypeLibImpl
, iface
);
2136 TRACE("(%p)->(IID: %s)\n",This
,debugstr_guid(riid
));
2139 if(IsEqualIID(riid
, &IID_IUnknown
) ||
2140 IsEqualIID(riid
,&IID_ITypeInfo
)||
2141 IsEqualIID(riid
,&IID_ITypeInfo2
))
2145 ITypeInfo_AddRef(iface
);
2146 TRACE("-- Interface: (%p)->(%p)\n",ppvObject
,*ppvObject
);
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
);
2172 FIXME("destroy child objects\n");
2174 TRACE(" destroying ITypeInfo(%p)\n",This
);
2177 SysFreeString(This
->Name
);
2181 if (This
->DocString
)
2183 SysFreeString(This
->DocString
);
2184 This
->DocString
= 0;
2189 ITypeInfo_Release((ITypeInfo
*)This
->next
);
2192 HeapFree(GetProcessHeap(),0,This
);
2198 /* ITypeInfo::GetTypeAttr
2200 * Retrieves a TYPEATTR structure that contains the attributes of the type
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
;
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
);
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
);
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
)
2244 /* FIXME: must do a copy here */
2245 *ppFuncDesc
=&pFDesc
->funcdesc
;
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
);
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
)
2266 /* FIXME: must do a copy here */
2267 *ppVarDesc
=&pVDesc
->vardesc
;
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
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
;
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
);
2290 /* function found, now return function and parameter names */
2291 for(i
=0; i
<cMaxNames
&& i
<= pFDesc
->funcdesc
.cParams
; i
++)
2294 *rgBstrNames
=SysAllocString(pFDesc
->Name
);
2296 rgBstrNames
[i
]=SysAllocString(pFDesc
->pParamDesc
[i
-1].Name
);
2302 for(pVDesc
=This
->varlist
; pVDesc
&& pVDesc
->vardesc
.memid
!= memid
; pVDesc
=pVDesc
->next
);
2305 *rgBstrNames
=SysAllocString(pVDesc
->Name
);
2310 if(This
->TypeAttr
.typekind
==TKIND_INTERFACE
&& This
->TypeAttr
.cImplTypes
)
2312 /* recursive search */
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
);
2322 WARN("Could not search inherited interface!\n");
2326 WARN("no names found\n");
2329 return TYPE_E_ELEMENTNOTFOUND
;
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,
2344 static HRESULT WINAPI
ITypeInfo_fnGetRefTypeOfImplType(
2349 ICOM_THIS( ITypeInfoImpl
, iface
);
2351 TLBRefType
*pIref
= This
->impltypelist
;
2353 TRACE("(%p) index %d\n", This
, index
);
2354 dump_TypeInfo(This
);
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
)
2371 *pRefType
= pIref
->reference
;
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
) );
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
);
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
;
2410 return TYPE_E_ELEMENTNOTFOUND
;
2414 * Maps between member names and member IDs, and parameter names and
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
;
2424 UINT nNameLen
= SysStringLen(*rgszNames
);
2426 TRACE("(%p) Name %s cNames %d\n", This
, debugstr_w(*rgszNames
),
2428 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
) {
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
))
2437 if( j
<pFDesc
->funcdesc
.cParams
)
2440 ret
=DISP_E_UNKNOWNNAME
;
2445 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
) {
2446 if( !memcmp(*rgszNames
, pVDesc
->Name
, nNameLen
)) {
2447 if(cNames
) *pMemId
=pVDesc
->vardesc
.memid
;
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 */
2456 ret
=ITypeInfo_GetRefTypeInfo(iface
,
2457 This
->impltypelist
->reference
, &pTInfo
);
2459 ret
=ITypeInfo_GetIDsOfNames(pTInfo
, rgszNames
, cNames
, pMemId
);
2460 ITypeInfo_Release(pTInfo
);
2463 WARN("Could not search inherited interface!\n");
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(
2479 DISPPARAMS
*pDispParams
,
2480 VARIANT
*pVarResult
,
2481 EXCEPINFO
*pExcepInfo
,
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
);
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 */
2508 *pBstrName
=SysAllocString(This
->Name
);
2510 *pBstrDocString
=SysAllocString(This
->DocString
);
2512 *pdwHelpContext
=This
->dwHelpContext
;
2514 *pBstrHelpFile
=SysAllocString(This
->DocString
);/* FIXME */
2516 }else {/* for a member */
2517 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
)
2518 if(pFDesc
->funcdesc
.memid
==memid
){
2521 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
)
2522 if(pVDesc
->vardesc
.memid
==memid
){
2526 return TYPE_E_ELEMENTNOTFOUND
;
2529 /* ITypeInfo::GetDllEntry
2531 * Retrieves a description or specification of an entry point for a function
2534 static HRESULT WINAPI
ITypeInfo_fnGetDllEntry( ITypeInfo2
*iface
, MEMBERID memid
,
2535 INVOKEKIND invKind
, BSTR
*pBstrDllName
, BSTR
*pBstrName
,
2538 ICOM_THIS( ITypeInfoImpl
, iface
);
2539 FIXME("(%p) stub!\n", This
);
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(
2551 ITypeInfo
**ppTInfo
)
2553 ICOM_THIS( ITypeInfoImpl
, iface
);
2554 HRESULT result
= E_FAIL
;
2556 if(HREFTYPE_INTHISFILE(hRefType
))
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
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
);
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
);
2604 TYPEATTR
* pMyTypeAttr
= &This
->TypeAttr
;
2605 unsigned short cFuncs
= pMyTypeAttr
->cFuncs
;
2606 unsigned short cVars
= pMyTypeAttr
->cVars
;
2608 /* search in arguments */
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
;
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 */
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
;
2653 TRACE("typeinfo in imported typelib that is already loaded\n");
2655 result
= ITypeLib2_GetTypeInfoOfGuid((LPTYPELIB
)pTypeLib
,
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
);
2689 /* ITypeInfo::AddressOfMember
2691 * Retrieves the addresses of static functions or variables, such as those
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
);
2702 /* ITypeInfo::CreateInstance
2704 * Creates a new instance of a type that describes a component object class
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
);
2715 /* ITypeInfo::GetMops
2717 * Retrieves marshaling information.
2719 static HRESULT WINAPI
ITypeInfo_fnGetMops( ITypeInfo2
*iface
, MEMBERID memid
,
2722 ICOM_THIS( ITypeInfoImpl
, iface
);
2723 FIXME("(%p) stub!\n", This
);
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
);
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
);
2756 /* ITypeInfo::ReleaseFuncDesc
2758 * Releases a FUNCDESC previously returned by GetFuncDesc. *
2760 static HRESULT WINAPI
ITypeInfo_fnReleaseFuncDesc(
2762 FUNCDESC
*pFuncDesc
)
2764 ICOM_THIS( ITypeInfoImpl
, iface
);
2765 TRACE("(%p)->(%p)\n", This
, pFuncDesc
);
2769 /* ITypeInfo::ReleaseVarDesc
2771 * Releases a VARDESC previously returned by GetVarDesc.
2773 static HRESULT WINAPI
ITypeInfo_fnReleaseVarDesc( ITypeInfo2
*iface
,
2776 ICOM_THIS( ITypeInfoImpl
, iface
);
2777 TRACE("(%p)->(%p)\n", This
, pVarDesc
);
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
);
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
2802 static HRESULT WINAPI
ITypeInfo2_fnGetTypeFlags( ITypeInfo2
* iface
,
2805 ICOM_THIS( ITypeInfoImpl
, iface
);
2806 *pTypeFlags
=This
->TypeAttr
.wTypeFlags
;
2807 TRACE("(%p) flags 0x%04x\n", This
,*pTypeFlags
);
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
;
2823 /* FIXME: should check for invKind??? */
2824 for(i
=0, pFuncInfo
=This
->funclist
;pFuncInfo
&&
2825 memid
!= pFuncInfo
->funcdesc
.memid
; i
++, pFuncInfo
=pFuncInfo
->next
);
2831 result
=E_INVALIDARG
;
2833 TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This
,
2834 memid
, invKind
, SUCCEEDED(result
)? "SUCCES":"FAILED");
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
;
2851 for(i
=0, pVarInfo
=This
->varlist
; pVarInfo
&&
2852 memid
!= pVarInfo
->vardesc
.memid
; i
++, pVarInfo
=pVarInfo
->next
)
2859 result
=E_INVALIDARG
;
2861 TRACE("(%p) memid 0x%08lx -> %s\n", This
,
2862 memid
, SUCCEEDED(result
)? "SUCCES":"FAILED");
2866 /* ITypeInfo2::GetCustData
2868 * Gets the custom data
2870 static HRESULT WINAPI
ITypeInfo2_fnGetCustData(
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");
2885 VariantInit( pVarVal
);
2886 VariantCopy( pVarVal
, &pCData
->data
);
2889 return E_INVALIDARG
; /* FIXME: correct? */
2892 /* ITypeInfo2::GetFuncCustData
2894 * Gets the custom data
2896 static HRESULT WINAPI
ITypeInfo2_fnGetFuncCustData(
2902 ICOM_THIS( ITypeInfoImpl
, iface
);
2903 TLBCustData
*pCData
=NULL
;
2904 TLBFuncDesc
* pFDesc
;
2906 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++,
2907 pFDesc
=pFDesc
->next
);
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");
2916 VariantInit( pVarVal
);
2917 VariantCopy( pVarVal
, &pCData
->data
);
2920 return E_INVALIDARG
; /* FIXME: correct? */
2923 /* ITypeInfo2::GetParamCustData
2925 * Gets the custom data
2927 static HRESULT WINAPI
ITypeInfo2_fnGetParamCustData(
2934 ICOM_THIS( ITypeInfoImpl
, iface
);
2935 TLBCustData
*pCData
=NULL
;
2936 TLBFuncDesc
* pFDesc
;
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");
2950 VariantInit( pVarVal
);
2951 VariantCopy( pVarVal
, &pCData
->data
);
2954 return E_INVALIDARG
; /* FIXME: correct? */
2957 /* ITypeInfo2::GetVarcCustData
2959 * Gets the custom data
2961 static HRESULT WINAPI
ITypeInfo2_fnGetVarCustData(
2967 ICOM_THIS( ITypeInfoImpl
, iface
);
2968 TLBCustData
*pCData
=NULL
;
2969 TLBVarDesc
* pVDesc
;
2972 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++, pVDesc
=pVDesc
->next
);
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");
2986 VariantInit( pVarVal
);
2987 VariantCopy( pVarVal
, &pCData
->data
);
2990 return E_INVALIDARG
; /* FIXME: correct? */
2993 /* ITypeInfo2::GetImplcCustData
2995 * Gets the custom data
2997 static HRESULT WINAPI
ITypeInfo2_fnGetImplTypeCustData(
3003 ICOM_THIS( ITypeInfoImpl
, iface
);
3004 TLBCustData
*pCData
=NULL
;
3005 TLBRefType
* pRDesc
;
3008 for(i
=0, pRDesc
=This
->impltypelist
; i
!=index
&& pRDesc
; i
++, pRDesc
=pRDesc
->next
);
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");
3022 VariantInit( pVarVal
);
3023 VariantCopy( pVarVal
, &pCData
->data
);
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(
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 */
3057 *pbstrHelpString
=SysAllocString(This
->Name
);
3058 if(pdwHelpStringContext
)
3059 *pdwHelpStringContext
=This
->dwHelpStringContext
;
3060 if(pbstrHelpStringDll
)
3061 *pbstrHelpStringDll
=
3062 SysAllocString(This
->pTypeLib
->HelpStringDll
);/* FIXME */
3064 }else {/* for a member */
3065 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
)
3066 if(pFDesc
->funcdesc
.memid
==memid
){
3068 *pbstrHelpString
=SysAllocString(pFDesc
->HelpString
);
3069 if(pdwHelpStringContext
)
3070 *pdwHelpStringContext
=pFDesc
->HelpStringContext
;
3071 if(pbstrHelpStringDll
)
3072 *pbstrHelpStringDll
=
3073 SysAllocString(This
->pTypeLib
->HelpStringDll
);/* FIXME */
3076 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
)
3077 if(pVDesc
->vardesc
.memid
==memid
){
3079 *pbstrHelpString
=SysAllocString(pVDesc
->HelpString
);
3080 if(pdwHelpStringContext
)
3081 *pdwHelpStringContext
=pVDesc
->HelpStringContext
;
3082 if(pbstrHelpStringDll
)
3083 *pbstrHelpStringDll
=
3084 SysAllocString(This
->pTypeLib
->HelpStringDll
);/* FIXME */
3088 return TYPE_E_ELEMENTNOTFOUND
;
3091 /* ITypeInfo2::GetAllCustData
3093 * Gets all custom data items for the Type info.
3096 static HRESULT WINAPI
ITypeInfo2_fnGetAllCustData(
3098 CUSTDATA
*pCustData
)
3100 ICOM_THIS( ITypeInfoImpl
, iface
);
3101 TLBCustData
*pCData
;
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
);
3114 ERR(" OUT OF MEMORY! \n");
3115 return E_OUTOFMEMORY
;
3120 /* ITypeInfo2::GetAllFuncCustData
3122 * Gets all custom data items for the specified Function
3125 static HRESULT WINAPI
ITypeInfo2_fnGetAllFuncCustData(
3128 CUSTDATA
*pCustData
)
3130 ICOM_THIS( ITypeInfoImpl
, iface
);
3131 TLBCustData
*pCData
;
3132 TLBFuncDesc
* pFDesc
;
3134 TRACE("(%p) index %d\n", This
, index
);
3135 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++,
3136 pFDesc
=pFDesc
->next
)
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
,
3150 ERR(" OUT OF MEMORY! \n");
3151 return E_OUTOFMEMORY
;
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
;
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
,
3187 ERR(" OUT OF MEMORY! \n");
3188 return E_OUTOFMEMORY
;
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
;
3207 TRACE("(%p) index %d\n", This
, index
);
3208 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++,
3209 pVDesc
=pVDesc
->next
)
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
,
3223 ERR(" OUT OF MEMORY! \n");
3224 return E_OUTOFMEMORY
;
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(
3239 CUSTDATA
*pCustData
)
3241 ICOM_THIS( ITypeInfoImpl
, iface
);
3242 TLBCustData
*pCData
;
3243 TLBRefType
* pRDesc
;
3245 TRACE("(%p) index %d\n", This
, index
);
3246 for(i
=0, pRDesc
=This
->impltypelist
; i
!=index
&& pRDesc
; i
++,
3247 pRDesc
=pRDesc
->next
)
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
,
3261 ERR(" OUT OF MEMORY! \n");
3262 return E_OUTOFMEMORY
;
3266 return TYPE_E_ELEMENTNOTFOUND
;
3269 static ICOM_VTABLE(ITypeInfo2
) tinfvt
=
3271 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3273 ITypeInfo_fnQueryInterface
,
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
,
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
,