4 * Copyright 1997 Marcus Meissner
6 * 2000 Francois Jacques
7 * 2001 Huw D M Davies for CodeWeavers
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * --------------------------------------------------------------------------------------
24 * Known problems (2000, Francois Jacques)
26 * - Tested using OLEVIEW (Platform SDK tool) only.
28 * - dual interface dispinterfaces. vtable-interface ITypeInfo instances are
29 * creating by doing a straight copy of the dispinterface instance and just changing
30 * its typekind. Pointed structures aren't copied - only the address of the pointers.
31 * So when you release the dispinterface, you delete the vtable-interface structures
32 * as well... fortunately, clean up of structures is not implemented.
34 * - locale stuff is partially implemented but hasn't been tested.
36 * - typelib file is still read in its entirety, but it is released now.
37 * - some garbage is read from function names on some very rare occasions.
39 * --------------------------------------------------------------------------------------
40 * Known problems left from previous implementation (1999, Rein Klazes) :
42 * -. Data structures are straightforward, but slow for look-ups.
43 * -. (related) nothing is hashed
44 * -. there are a number of stubs in ITypeLib and ITypeInfo interfaces. Most
45 * of them I don't know yet how to implement them.
46 * -. Most error return values are just guessed not checked with windows
48 * -. didn't bother with a c++ interface
49 * -. lousy fatal error handling
50 * -. some methods just return pointers to internal data structures, this is
51 * partly laziness, partly I want to check how windows does it.
56 #include "wine/port.h"
64 #include "winnls.h" /* for PRIMARYLANGID */
65 #include "winreg.h" /* for HKEY_LOCAL_MACHINE */
68 #include "wine/unicode.h"
69 #include "wine/obj_base.h"
73 #include "wine/debug.h"
75 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
76 WINE_DECLARE_DEBUG_CHANNEL(typelib
);
78 /****************************************************************************
79 * QueryPathOfRegTypeLib [TYPELIB.14]
81 * the path is "Classes\Typelib\<guid>\<major>.<minor>\<lcid>\win16\"
86 QueryPathOfRegTypeLib16(
87 REFGUID guid
, /* [in] referenced guid */
88 WORD wMaj
, /* [in] major version */
89 WORD wMin
, /* [in] minor version */
90 LCID lcid
, /* [in] locale id */
91 LPBSTR16 path
/* [out] path of typelib */
94 char typelibkey
[100],pathname
[260];
100 sprintf( typelibkey
, "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win16",
101 guid
->Data1
, guid
->Data2
, guid
->Data3
,
102 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
103 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7],
106 sprintf(xguid
,"<guid 0x%08lx>",(DWORD
)guid
);
107 FIXME("(%s,%d,%d,0x%04lx,%p),can't handle non-string guids.\n",xguid
,wMaj
,wMin
,(DWORD
)lcid
,path
);
110 plen
= sizeof(pathname
);
111 if (RegQueryValueA(HKEY_LOCAL_MACHINE
,typelibkey
,pathname
,&plen
)) {
112 /* try again without lang specific id */
114 return QueryPathOfRegTypeLib16(guid
,wMaj
,wMin
,PRIMARYLANGID(lcid
),path
);
115 FIXME("key %s not found\n",typelibkey
);
118 *path
= SysAllocString16(pathname
);
122 /****************************************************************************
123 * QueryPathOfRegTypeLib [OLEAUT32.164]
128 QueryPathOfRegTypeLib(
129 REFGUID guid
, /* [in] referenced guid */
130 WORD wMaj
, /* [in] major version */
131 WORD wMin
, /* [in] minor version */
132 LCID lcid
, /* [in] locale id */
133 LPBSTR path
) /* [out] path of typelib */
135 /* don't need to ZeroMemory those arrays since sprintf and RegQueryValue add
136 string termination character on output strings */
143 char szTypeLibKey
[100];
144 char szPath
[MAX_PATH
];
145 DWORD dwPathLen
= sizeof(szPath
);
153 FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n", szXGUID
, wMaj
, wMin
, (DWORD
)lcid
, path
);
159 sprintf(szTypeLibKey
,
160 "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win32",
161 guid
->Data1
, guid
->Data2
, guid
->Data3
,
162 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
163 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7],
168 if (RegQueryValueA(HKEY_LOCAL_MACHINE
, szTypeLibKey
, szPath
, &dwPathLen
))
172 else if (myLCID
== lcid
)
174 /* try with sub-langid */
175 myLCID
= SUBLANGID(lcid
);
177 else if ((myLCID
== SUBLANGID(lcid
)) && myLCID
)
179 /* try with system langid */
189 DWORD len
= MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, szPath
, dwPathLen
, NULL
, 0 );
190 BSTR bstrPath
= SysAllocStringLen(NULL
,len
);
192 MultiByteToWideChar(CP_ACP
,
204 TRACE_(typelib
)("%s not found\n", szTypeLibKey
);
209 /******************************************************************************
210 * CreateTypeLib [OLEAUT32.160] creates a typelib
216 HRESULT WINAPI
CreateTypeLib(
217 SYSKIND syskind
, LPCOLESTR szFile
, ICreateTypeLib
** ppctlib
219 FIXME("(%d,%s,%p), stub!\n",syskind
,debugstr_w(szFile
),ppctlib
);
222 /******************************************************************************
223 * LoadTypeLib [TYPELIB.3] Loads and registers a type library
225 * Docs: OLECHAR FAR* szFile
226 * Docs: iTypeLib FAR* FAR* pptLib
232 HRESULT WINAPI
LoadTypeLib16(
233 LPOLESTR szFile
, /* [in] Name of file to load from */
234 ITypeLib
** pptLib
) /* [out] Pointer to pointer to loaded type library */
236 FIXME("(%s,%p): stub\n",debugstr_w((LPWSTR
)szFile
),pptLib
);
244 /******************************************************************************
245 * LoadTypeLib [OLEAUT32.161]
246 * Loads and registers a type library
248 * Docs: OLECHAR FAR* szFile
249 * Docs: iTypeLib FAR* FAR* pptLib
255 int TLB_ReadTypeLib(LPCWSTR file
, INT index
, ITypeLib2
**ppTypelib
);
257 HRESULT WINAPI
LoadTypeLib(
258 const OLECHAR
*szFile
,/* [in] Name of file to load from */
259 ITypeLib
* *pptLib
) /* [out] Pointer to pointer to loaded type library */
262 return LoadTypeLibEx(szFile
, REGKIND_DEFAULT
, pptLib
);
265 /******************************************************************************
266 * LoadTypeLibEx [OLEAUT32.183]
267 * Loads and optionally registers a type library
273 HRESULT WINAPI
LoadTypeLibEx(
274 LPCOLESTR szFile
, /* [in] Name of file to load from */
275 REGKIND regkind
, /* [in] Specify kind of registration */
276 ITypeLib
**pptLib
) /* [out] Pointer to pointer to loaded type library */
278 WCHAR szPath
[MAX_PATH
+1], szFileCopy
[MAX_PATH
+1];
282 TRACE("(%s,%d,%p)\n",debugstr_w(szFile
), regkind
, pptLib
);
284 if(!SearchPathW(NULL
,szFile
,NULL
,sizeof(szPath
)/sizeof(WCHAR
),szPath
,
287 /* Look for a trailing '\\' followed by an index */
288 pIndexStr
= strrchrW(szFile
, '\\');
289 if(pIndexStr
&& pIndexStr
!= szFile
&& *++pIndexStr
!= '\0') {
290 index
= atoiW(pIndexStr
);
291 memcpy(szFileCopy
, szFile
,
292 (pIndexStr
- szFile
- 1) * sizeof(WCHAR
));
293 szFileCopy
[pIndexStr
- szFile
- 1] = '\0';
294 if(!SearchPathW(NULL
,szFileCopy
,NULL
,sizeof(szPath
)/sizeof(WCHAR
),
296 return TYPE_E_CANTLOADLIBRARY
;
297 if (GetFileAttributesW(szFileCopy
) & FILE_ATTRIBUTE_DIRECTORY
)
298 return TYPE_E_CANTLOADLIBRARY
;
300 return TYPE_E_CANTLOADLIBRARY
;
303 TRACE("File %s index %d\n", debugstr_w(szPath
), index
);
305 res
= TLB_ReadTypeLib(szPath
, index
, (ITypeLib2
**)pptLib
);
310 case REGKIND_DEFAULT
:
311 /* FIXME: is this correct? */
312 if (!szFile
|| !szFile
[0] ||
313 (szFile
[0] != '\\' && szFile
[0] != '/' && szFile
[1] != ':'))
315 /* else fall-through */
316 case REGKIND_REGISTER
:
317 /* FIXME: Help path? */
318 if (!SUCCEEDED(res
= RegisterTypeLib(*pptLib
, (LPOLESTR
)szFile
, NULL
)))
320 IUnknown_Release(*pptLib
);
328 TRACE(" returns %08lx\n",res
);
332 /******************************************************************************
333 * LoadRegTypeLib [OLEAUT32.162]
335 HRESULT WINAPI
LoadRegTypeLib(
336 REFGUID rguid
, /* [in] referenced guid */
337 WORD wVerMajor
, /* [in] major version */
338 WORD wVerMinor
, /* [in] minor version */
339 LCID lcid
, /* [in] locale id */
340 ITypeLib
**ppTLib
) /* [out] path of typelib */
343 HRESULT res
=QueryPathOfRegTypeLib( rguid
, wVerMajor
, wVerMinor
, lcid
, &bstr
);
347 res
= LoadTypeLib(bstr
, ppTLib
);
351 TRACE("(IID: %s) load %s (%p)\n",debugstr_guid(rguid
), SUCCEEDED(res
)? "SUCCESS":"FAILED", *ppTLib
);
357 /******************************************************************************
358 * RegisterTypeLib [OLEAUT32.163]
359 * Adds information about a type library to the System Registry
361 * Docs: ITypeLib FAR * ptlib
362 * Docs: OLECHAR FAR* szFullPath
363 * Docs: OLECHAR FAR* szHelpDir
369 HRESULT WINAPI
RegisterTypeLib(
370 ITypeLib
* ptlib
, /* [in] Pointer to the library*/
371 OLECHAR
* szFullPath
, /* [in] full Path of the library*/
372 OLECHAR
* szHelpDir
) /* [in] dir to the helpfile for the library,
383 static const char *PSOA
= "{00020424-0000-0000-C000-000000000046}";
385 if (ptlib
== NULL
|| szFullPath
== NULL
)
388 if (!SUCCEEDED(ITypeLib_GetLibAttr(ptlib
, &attr
)))
391 StringFromGUID2(&attr
->guid
, guid
, 80);
392 guidA
= HEAP_strdupWtoA(GetProcessHeap(), 0, guid
);
393 snprintf(keyName
, sizeof(keyName
), "TypeLib\\%s\\%x.%x",
394 guidA
, attr
->wMajorVerNum
, attr
->wMinorVerNum
);
395 HeapFree(GetProcessHeap(), 0, guidA
);
398 if (RegCreateKeyExA(HKEY_CLASSES_ROOT
, keyName
, 0, NULL
, 0,
399 KEY_WRITE
, NULL
, &key
, NULL
) == ERROR_SUCCESS
)
403 if (SUCCEEDED(ITypeLib_GetDocumentation(ptlib
, -1, NULL
, &doc
, NULL
, NULL
)))
405 if (RegSetValueExW(key
, NULL
, 0, REG_SZ
,
406 (BYTE
*)doc
, lstrlenW(doc
) * sizeof(OLECHAR
)) != ERROR_SUCCESS
)
414 /* FIXME: This *seems* to be 0 always, not sure though */
415 if (res
== S_OK
&& RegCreateKeyExA(key
, "0\\win32", 0, NULL
, 0,
416 KEY_WRITE
, NULL
, &subKey
, NULL
) == ERROR_SUCCESS
)
418 if (RegSetValueExW(subKey
, NULL
, 0, REG_SZ
,
419 (BYTE
*)szFullPath
, lstrlenW(szFullPath
) * sizeof(OLECHAR
)) != ERROR_SUCCESS
)
427 if (res
== S_OK
&& RegCreateKeyExA(key
, "FLAGS", 0, NULL
, 0,
428 KEY_WRITE
, NULL
, &subKey
, NULL
) == ERROR_SUCCESS
)
431 /* FIXME: is %u correct? */
432 snprintf(buf
, sizeof(buf
), "%u", attr
->wLibFlags
);
433 if (RegSetValueExA(subKey
, NULL
, 0, REG_SZ
,
434 buf
, lstrlenA(buf
) + 1) != ERROR_SUCCESS
)
442 /* register OLE Automation-compatible interfaces for this typelib */
443 types
= ITypeLib_GetTypeInfoCount(ptlib
);
444 for (tidx
=0; tidx
<types
; tidx
++) {
445 if (SUCCEEDED(ITypeLib_GetTypeInfoType(ptlib
, tidx
, &kind
))) {
446 LPOLESTR name
= NULL
;
447 ITypeInfo
*tinfo
= NULL
;
449 ITypeLib_GetDocumentation(ptlib
, tidx
, &name
, NULL
, NULL
, NULL
);
451 case TKIND_INTERFACE
:
452 TRACE_(typelib
)("%d: interface %s\n", tidx
, debugstr_w(name
));
453 ITypeLib_GetTypeInfo(ptlib
, tidx
, &tinfo
);
456 TRACE_(typelib
)("%d: dispinterface %s\n", tidx
, debugstr_w(name
));
457 /* ITypeLib_GetTypeInfo(ptlib, tidx, &tinfo); */
460 TRACE_(typelib
)("%d: coclass %s\n", tidx
, debugstr_w(name
));
461 /* coclasses should probably not be registered? */
464 TRACE_(typelib
)("%d: %s\n", tidx
, debugstr_w(name
));
468 TYPEATTR
*tattr
= NULL
;
469 ITypeInfo_GetTypeAttr(tinfo
, &tattr
);
471 TRACE_(typelib
)("guid=%s, flags=%04x (",
472 debugstr_guid(&tattr
->guid
),
474 if (TRACE_ON(typelib
)) {
475 #define XX(x) if (TYPEFLAG_##x & tattr->wTypeFlags) MESSAGE(#x"|");
495 * FIXME: The 1 is just here until we implement rpcrt4
496 * stub/proxy handling. Until then it helps IShield
499 if (1 || (tattr
->wTypeFlags
& TYPEFLAG_FOLEAUTOMATION
))
501 /* register interface<->typelib coupling */
502 StringFromGUID2(&tattr
->guid
, guid
, 80);
503 guidA
= HEAP_strdupWtoA(GetProcessHeap(), 0, guid
);
504 snprintf(keyName
, sizeof(keyName
), "Interface\\%s", guidA
);
505 HeapFree(GetProcessHeap(), 0, guidA
);
507 if (RegCreateKeyExA(HKEY_CLASSES_ROOT
, keyName
, 0, NULL
, 0,
508 KEY_WRITE
, NULL
, &key
, NULL
) == ERROR_SUCCESS
) {
510 RegSetValueExW(key
, NULL
, 0, REG_SZ
,
511 (BYTE
*)name
, lstrlenW(name
) * sizeof(OLECHAR
));
513 if (RegCreateKeyExA(key
, "ProxyStubClsid", 0, NULL
, 0,
514 KEY_WRITE
, NULL
, &subKey
, NULL
) == ERROR_SUCCESS
) {
515 RegSetValueExA(subKey
, NULL
, 0, REG_SZ
,
519 if (RegCreateKeyExA(key
, "ProxyStubClsid32", 0, NULL
, 0,
520 KEY_WRITE
, NULL
, &subKey
, NULL
) == ERROR_SUCCESS
) {
521 RegSetValueExA(subKey
, NULL
, 0, REG_SZ
,
526 if (RegCreateKeyExA(key
, "TypeLib", 0, NULL
, 0,
527 KEY_WRITE
, NULL
, &subKey
, NULL
) == ERROR_SUCCESS
) {
529 StringFromGUID2(&attr
->guid
, guid
, 80);
530 snprintf(ver
, sizeof(ver
), "%x.%x",
531 attr
->wMajorVerNum
, attr
->wMinorVerNum
);
532 RegSetValueExW(subKey
, NULL
, 0, REG_SZ
,
533 (BYTE
*)guid
, lstrlenW(guid
) * sizeof(OLECHAR
));
534 RegSetValueExA(subKey
, "Version", 0, REG_SZ
,
541 ITypeInfo_ReleaseTypeAttr(tinfo
, tattr
);
543 ITypeInfo_Release(tinfo
);
550 ITypeLib_ReleaseTLibAttr(ptlib
, attr
);
556 /******************************************************************************
557 * UnRegisterTypeLib [OLEAUT32.186]
558 * Removes information about a type library from the System Registry
565 HRESULT WINAPI
UnRegisterTypeLib(
566 REFGUID libid
, /* [in] Guid of the library */
567 WORD wVerMajor
, /* [in] major version */
568 WORD wVerMinor
, /* [in] minor version */
569 LCID lcid
, /* [in] locale id */
572 TRACE("(IID: %s): stub\n",debugstr_guid(libid
));
573 return S_OK
; /* FIXME: pretend everything is OK */
576 /****************************************************************************
577 * OaBuildVersion (TYPELIB.15)
579 * known TYPELIB.DLL versions:
581 * OLE 2.01 no OaBuildVersion() avail 1993 -- ---
582 * OLE 2.02 1993-94 02 3002
585 * OLE 2.03 W98 SE orig. file !! 1993-95 10 3024
586 * OLE 2.1 NT 1993-95 ?? ???
587 * OLE 2.3.1 W95 23 700
588 * OLE2 4.0 NT4SP6 1993-98 40 4277
590 DWORD WINAPI
OaBuildVersion16(void)
592 /* FIXME: I'd like to return the highest currently known version value
593 * in case the user didn't force a --winver, but I don't know how
594 * to retrieve the "versionForced" info from misc/version.c :(
595 * (this would be useful in other places, too) */
596 FIXME("If you get version error messages, please report them\n");
597 switch(GetVersion() & 0x8000ffff) /* mask off build number */
599 case 0x80000a03: /* WIN31 */
600 return MAKELONG(3027, 3); /* WfW 3.11 */
601 case 0x80000004: /* WIN95 */
602 return MAKELONG(700, 23); /* Win95A */
603 case 0x80000a04: /* WIN98 */
604 return MAKELONG(3024, 10); /* W98 SE */
605 case 0x00000004: /* NT4 */
606 return MAKELONG(4277, 40); /* NT4 SP6 */
608 FIXME("Version value not known yet. Please investigate it!\n");
613 /* for better debugging info leave the static out for the time being */
616 /*======================= ITypeLib implementation =======================*/
618 typedef struct tagTLBCustData
622 struct tagTLBCustData
* next
;
625 /* data structure for import typelibs */
626 typedef struct tagTLBImpLib
628 int offset
; /* offset in the file (MSFT)
629 offset in nametable (SLTG)
630 just used to identify library while reading
632 GUID guid
; /* libid */
633 BSTR name
; /* name */
635 LCID lcid
; /* lcid of imported typelib */
637 WORD wVersionMajor
; /* major version number */
638 WORD wVersionMinor
; /* minor version number */
640 struct tagITypeLibImpl
*pImpTypeLib
; /* pointer to loaded typelib, or
641 NULL if not yet loaded */
642 struct tagTLBImpLib
* next
;
645 /* internal ITypeLib data */
646 typedef struct tagITypeLibImpl
648 ICOM_VFIELD(ITypeLib2
);
650 TLIBATTR LibAttr
; /* guid,lcid,syskind,version,flags */
652 /* strings can be stored in tlb as multibyte strings BUT they are *always*
653 * exported to the application as a UNICODE string.
659 unsigned long dwHelpContext
;
660 int TypeInfoCount
; /* nr of typeinfo's in librarry */
661 struct tagITypeInfoImpl
*pTypeInfo
; /* linked list of type info data */
662 int ctCustData
; /* number of items in cust data list */
663 TLBCustData
* pCustData
; /* linked list to cust data */
664 TLBImpLib
* pImpLibs
; /* linked list to all imported typelibs */
665 TYPEDESC
* pTypeDesc
; /* array of TypeDescriptions found in the
666 libary. Only used while read MSFT
670 static struct ICOM_VTABLE(ITypeLib2
) tlbvt
;
672 /* ITypeLib methods */
673 static ITypeLib2
* ITypeLib2_Constructor_MSFT(LPVOID pLib
, DWORD dwTLBLength
);
674 static ITypeLib2
* ITypeLib2_Constructor_SLTG(LPVOID pLib
, DWORD dwTLBLength
);
676 /*======================= ITypeInfo implementation =======================*/
678 /* data for refernced types */
679 typedef struct tagTLBRefType
681 INT index
; /* Type index for internal ref or for external ref
682 it the format is SLTG. -2 indicates to
685 GUID guid
; /* guid of the referenced type */
686 /* if index == TLB_REF_USE_GUID */
688 HREFTYPE reference
; /* The href of this ref */
689 TLBImpLib
*pImpTLInfo
; /* If ref is external ptr to library data
690 TLB_REF_INTERNAL for internal refs
691 TLB_REF_NOT_FOUND for broken refs */
693 struct tagTLBRefType
* next
;
696 #define TLB_REF_USE_GUID -2
698 #define TLB_REF_INTERNAL (void*)-2
699 #define TLB_REF_NOT_FOUND (void*)-1
701 /* internal Parameter data */
702 typedef struct tagTLBParDesc
706 TLBCustData
* pCustData
; /* linked list to cust data */
709 /* internal Function data */
710 typedef struct tagTLBFuncDesc
712 FUNCDESC funcdesc
; /* lots of info on the function and its attributes. */
713 BSTR Name
; /* the name of this function */
714 TLBParDesc
*pParamDesc
; /* array with param names and custom data */
716 int HelpStringContext
;
718 BSTR Entry
; /* if its Hiword==0, it numeric; -1 is not present*/
720 TLBCustData
* pCustData
; /* linked list to cust data; */
721 struct tagTLBFuncDesc
* next
;
724 /* internal Variable data */
725 typedef struct tagTLBVarDesc
727 VARDESC vardesc
; /* lots of info on the variable and its attributes. */
728 BSTR Name
; /* the name of this variable */
730 int HelpStringContext
; /* FIXME: where? */
733 TLBCustData
* pCustData
;/* linked list to cust data; */
734 struct tagTLBVarDesc
* next
;
737 /* internal implemented interface data */
738 typedef struct tagTLBImplType
740 HREFTYPE hRef
; /* hRef of interface */
741 int implflags
; /* IMPLFLAG_*s */
743 TLBCustData
* pCustData
;/* linked list to custom data; */
744 struct tagTLBImplType
*next
;
747 /* internal TypeInfo data */
748 typedef struct tagITypeInfoImpl
750 ICOM_VFIELD(ITypeInfo2
);
752 TYPEATTR TypeAttr
; /* _lots_ of type information. */
753 ITypeLibImpl
* pTypeLib
; /* back pointer to typelib */
754 int index
; /* index in this typelib; */
755 /* type libs seem to store the doc strings in ascii
756 * so why should we do it in unicode?
760 unsigned long dwHelpContext
;
761 unsigned long dwHelpStringContext
;
764 TLBFuncDesc
* funclist
; /* linked list with function descriptions */
767 TLBVarDesc
* varlist
; /* linked list with variable descriptions */
769 /* Implemented Interfaces */
770 TLBImplType
* impltypelist
;
772 TLBRefType
* reflist
;
774 TLBCustData
* pCustData
; /* linked list to cust data; */
775 struct tagITypeInfoImpl
* next
;
778 static struct ICOM_VTABLE(ITypeInfo2
) tinfvt
;
780 static ITypeInfo2
* WINAPI
ITypeInfo_Constructor();
782 typedef struct tagTLBContext
784 unsigned int oStart
; /* start of TLB in file */
785 unsigned int pos
; /* current pos */
786 unsigned int length
; /* total length */
787 void *mapping
; /* memory mapping */
788 MSFT_SegDir
* pTblDir
;
789 ITypeLibImpl
* pLibInfo
;
793 static void MSFT_DoRefType(TLBContext
*pcx
, ITypeInfoImpl
*pTI
, int offset
);
798 static void dump_VarType(VARTYPE vt
,char *szVarType
) {
799 /* FIXME : we could have better trace here, depending on the VARTYPE
802 if (vt
& VT_RESERVED
)
803 szVarType
+= strlen(strcpy(szVarType
, "reserved | "));
805 szVarType
+= strlen(strcpy(szVarType
, "ref to "));
807 szVarType
+= strlen(strcpy(szVarType
, "array of "));
809 szVarType
+= strlen(strcpy(szVarType
, "vector of "));
810 switch(vt
& VT_TYPEMASK
) {
811 case VT_UI1
: sprintf(szVarType
, "VT_UI"); break;
812 case VT_I2
: sprintf(szVarType
, "VT_I2"); break;
813 case VT_I4
: sprintf(szVarType
, "VT_I4"); break;
814 case VT_R4
: sprintf(szVarType
, "VT_R4"); break;
815 case VT_R8
: sprintf(szVarType
, "VT_R8"); break;
816 case VT_BOOL
: sprintf(szVarType
, "VT_BOOL"); break;
817 case VT_ERROR
: sprintf(szVarType
, "VT_ERROR"); break;
818 case VT_CY
: sprintf(szVarType
, "VT_CY"); break;
819 case VT_DATE
: sprintf(szVarType
, "VT_DATE"); break;
820 case VT_BSTR
: sprintf(szVarType
, "VT_BSTR"); break;
821 case VT_UNKNOWN
: sprintf(szVarType
, "VT_UNKNOWN"); break;
822 case VT_DISPATCH
: sprintf(szVarType
, "VT_DISPATCH"); break;
823 case VT_I1
: sprintf(szVarType
, "VT_I1"); break;
824 case VT_UI2
: sprintf(szVarType
, "VT_UI2"); break;
825 case VT_UI4
: sprintf(szVarType
, "VT_UI4"); break;
826 case VT_INT
: sprintf(szVarType
, "VT_INT"); break;
827 case VT_UINT
: sprintf(szVarType
, "VT_UINT"); break;
828 case VT_VARIANT
: sprintf(szVarType
, "VT_VARIANT"); break;
829 case VT_VOID
: sprintf(szVarType
, "VT_VOID"); break;
830 case VT_USERDEFINED
: sprintf(szVarType
, "VT_USERDEFINED\n"); break;
831 default: sprintf(szVarType
, "unknown(%d)", vt
& VT_TYPEMASK
); break;
835 static void dump_TypeDesc(TYPEDESC
*pTD
,char *szVarType
) {
836 if (pTD
->vt
& VT_RESERVED
)
837 szVarType
+= strlen(strcpy(szVarType
, "reserved | "));
838 if (pTD
->vt
& VT_BYREF
)
839 szVarType
+= strlen(strcpy(szVarType
, "ref to "));
840 if (pTD
->vt
& VT_ARRAY
)
841 szVarType
+= strlen(strcpy(szVarType
, "array of "));
842 if (pTD
->vt
& VT_VECTOR
)
843 szVarType
+= strlen(strcpy(szVarType
, "vector of "));
844 switch(pTD
->vt
& VT_TYPEMASK
) {
845 case VT_UI1
: sprintf(szVarType
, "VT_UI1"); break;
846 case VT_I2
: sprintf(szVarType
, "VT_I2"); break;
847 case VT_I4
: sprintf(szVarType
, "VT_I4"); break;
848 case VT_R4
: sprintf(szVarType
, "VT_R4"); break;
849 case VT_R8
: sprintf(szVarType
, "VT_R8"); break;
850 case VT_BOOL
: sprintf(szVarType
, "VT_BOOL"); break;
851 case VT_ERROR
: sprintf(szVarType
, "VT_ERROR"); break;
852 case VT_CY
: sprintf(szVarType
, "VT_CY"); break;
853 case VT_DATE
: sprintf(szVarType
, "VT_DATE"); break;
854 case VT_BSTR
: sprintf(szVarType
, "VT_BSTR"); break;
855 case VT_UNKNOWN
: sprintf(szVarType
, "VT_UNKNOWN"); break;
856 case VT_DISPATCH
: sprintf(szVarType
, "VT_DISPATCH"); break;
857 case VT_I1
: sprintf(szVarType
, "VT_I1"); break;
858 case VT_UI2
: sprintf(szVarType
, "VT_UI2"); break;
859 case VT_UI4
: sprintf(szVarType
, "VT_UI4"); break;
860 case VT_INT
: sprintf(szVarType
, "VT_INT"); break;
861 case VT_UINT
: sprintf(szVarType
, "VT_UINT"); break;
862 case VT_VARIANT
: sprintf(szVarType
, "VT_VARIANT"); break;
863 case VT_VOID
: sprintf(szVarType
, "VT_VOID"); break;
864 case VT_USERDEFINED
: sprintf(szVarType
, "VT_USERDEFINED ref = %lx",
865 pTD
->u
.hreftype
); break;
866 case VT_PTR
: sprintf(szVarType
, "ptr to ");
867 dump_TypeDesc(pTD
->u
.lptdesc
, szVarType
+ 7);
869 case VT_SAFEARRAY
: sprintf(szVarType
, "safearray of ");
870 dump_TypeDesc(pTD
->u
.lptdesc
, szVarType
+ 13);
872 case VT_CARRAY
: sprintf(szVarType
, "%d dim array of ",
873 pTD
->u
.lpadesc
->cDims
); /* FIXME print out sizes */
874 dump_TypeDesc(&pTD
->u
.lpadesc
->tdescElem
, szVarType
+ strlen(szVarType
));
877 default: sprintf(szVarType
, "unknown(%d)", pTD
->vt
& VT_TYPEMASK
); break;
881 static void dump_ELEMDESC(ELEMDESC
*edesc
) {
883 dump_TypeDesc(&edesc
->tdesc
,buf
);
884 MESSAGE("\t\ttdesc.vartype %d (%s)\n",edesc
->tdesc
.vt
,buf
);
885 MESSAGE("\t\tu.parmadesc.flags %x\n",edesc
->u
.paramdesc
.wParamFlags
);
886 MESSAGE("\t\tu.parmadesc.lpex %p\n",edesc
->u
.paramdesc
.pparamdescex
);
888 static void dump_FUNCDESC(FUNCDESC
*funcdesc
) {
890 MESSAGE("memid is %08lx\n",funcdesc
->memid
);
891 for (i
=0;i
<funcdesc
->cParams
;i
++) {
892 MESSAGE("Param %d:\n",i
);
893 dump_ELEMDESC(funcdesc
->lprgelemdescParam
+i
);
895 MESSAGE("\tfunckind: %d (",funcdesc
->funckind
);
896 switch (funcdesc
->funckind
) {
897 case FUNC_VIRTUAL
: MESSAGE("virtual");break;
898 case FUNC_PUREVIRTUAL
: MESSAGE("pure virtual");break;
899 case FUNC_NONVIRTUAL
: MESSAGE("nonvirtual");break;
900 case FUNC_STATIC
: MESSAGE("static");break;
901 case FUNC_DISPATCH
: MESSAGE("dispatch");break;
902 default: MESSAGE("unknown");break;
904 MESSAGE(")\n\tinvkind: %d (",funcdesc
->invkind
);
905 switch (funcdesc
->invkind
) {
906 case INVOKE_FUNC
: MESSAGE("func");break;
907 case INVOKE_PROPERTYGET
: MESSAGE("property get");break;
908 case INVOKE_PROPERTYPUT
: MESSAGE("property put");break;
909 case INVOKE_PROPERTYPUTREF
: MESSAGE("property put ref");break;
911 MESSAGE(")\n\tcallconv: %d (",funcdesc
->callconv
);
912 switch (funcdesc
->callconv
) {
913 case CC_CDECL
: MESSAGE("cdecl");break;
914 case CC_PASCAL
: MESSAGE("pascal");break;
915 case CC_STDCALL
: MESSAGE("stdcall");break;
916 case CC_SYSCALL
: MESSAGE("syscall");break;
919 MESSAGE(")\n\toVft: %d\n", funcdesc
->oVft
);
920 MESSAGE("\tcParamsOpt: %d\n", funcdesc
->cParamsOpt
);
921 MESSAGE("\twFlags: %x\n", funcdesc
->wFuncFlags
);
923 static void dump_TLBFuncDescOne(TLBFuncDesc
* pfd
)
926 if (!TRACE_ON(typelib
))
928 MESSAGE("%s(%u)\n", debugstr_w(pfd
->Name
), pfd
->funcdesc
.cParams
);
929 for (i
=0;i
<pfd
->funcdesc
.cParams
;i
++)
930 MESSAGE("\tparm%d: %s\n",i
,debugstr_w(pfd
->pParamDesc
[i
].Name
));
933 dump_FUNCDESC(&(pfd
->funcdesc
));
935 MESSAGE("\thelpstring: %s\n", debugstr_w(pfd
->HelpString
));
936 MESSAGE("\tentry: %s\n", debugstr_w(pfd
->Entry
));
938 static void dump_TLBFuncDesc(TLBFuncDesc
* pfd
)
942 dump_TLBFuncDescOne(pfd
);
946 static void dump_TLBVarDesc(TLBVarDesc
* pvd
)
950 TRACE_(typelib
)("%s\n", debugstr_w(pvd
->Name
));
955 static void dump_TLBImpLib(TLBImpLib
*import
)
957 TRACE_(typelib
)("%s %s\n", debugstr_guid(&(import
->guid
)),
958 debugstr_w(import
->name
));
959 TRACE_(typelib
)("v%d.%d lcid=%lx offset=%x\n", import
->wVersionMajor
,
960 import
->wVersionMinor
, import
->lcid
, import
->offset
);
963 static void dump_TLBRefType(TLBRefType
* prt
)
967 TRACE_(typelib
)("href:0x%08lx\n", prt
->reference
);
969 TRACE_(typelib
)("%s\n", debugstr_guid(&(prt
->guid
)));
971 TRACE_(typelib
)("type no: %d\n", prt
->index
);
973 if(prt
->pImpTLInfo
!= TLB_REF_INTERNAL
&&
974 prt
->pImpTLInfo
!= TLB_REF_NOT_FOUND
) {
975 TRACE_(typelib
)("in lib\n");
976 dump_TLBImpLib(prt
->pImpTLInfo
);
982 static void dump_TLBImplType(TLBImplType
* impl
)
986 "implementing/inheriting interface hRef = %lx implflags %x\n",
987 impl
->hRef
, impl
->implflags
);
992 static void dump_Variant(VARIANT
* pvar
)
997 TRACE("(%p)\n", pvar
);
1001 ZeroMemory(szVarType
, sizeof(szVarType
));
1003 /* FIXME : we could have better trace here, depending on the VARTYPE
1006 dump_VarType(V_VT(pvar
),szVarType
);
1008 TRACE("VARTYPE: %s\n", szVarType
);
1010 if (V_VT(pvar
) & VT_BYREF
) {
1011 ref
= V_UNION(pvar
, byref
);
1014 else ref
= &V_UNION(pvar
, cVal
);
1016 if (V_VT(pvar
) & VT_ARRAY
) {
1020 if (V_VT(pvar
) & VT_VECTOR
) {
1028 TRACE("%d\n", *(short*)ref
);
1032 TRACE("%d\n", *(INT
*)ref
);
1036 TRACE("%3.3e\n", *(float*)ref
);
1040 TRACE("%3.3e\n", *(double*)ref
);
1044 TRACE("%s\n", *(VARIANT_BOOL
*)ref
? "TRUE" : "FALSE");
1048 TRACE("%s\n", debugstr_w(*(BSTR
*)ref
));
1053 TRACE("%p\n", *(LPVOID
*)ref
);
1057 if (V_VT(pvar
) & VT_BYREF
) dump_Variant(ref
);
1061 TRACE("(?)%ld\n", *(long*)ref
);
1066 static void dump_DispParms(DISPPARAMS
* pdp
)
1070 TRACE("args=%u named args=%u\n", pdp
->cArgs
, pdp
->cNamedArgs
);
1072 while (index
< pdp
->cArgs
)
1074 dump_Variant( &pdp
->rgvarg
[index
] );
1079 static char * typekind_desc
[] =
1092 static void dump_TypeInfo(ITypeInfoImpl
* pty
)
1094 TRACE("%p ref=%u\n", pty
, pty
->ref
);
1095 TRACE("attr:%s\n", debugstr_guid(&(pty
->TypeAttr
.guid
)));
1096 TRACE("kind:%s\n", typekind_desc
[pty
->TypeAttr
.typekind
]);
1097 TRACE("fct:%u var:%u impl:%u\n",
1098 pty
->TypeAttr
.cFuncs
, pty
->TypeAttr
.cVars
, pty
->TypeAttr
.cImplTypes
);
1099 TRACE("parent tlb:%p index in TLB:%u\n",pty
->pTypeLib
, pty
->index
);
1100 TRACE("%s %s\n", debugstr_w(pty
->Name
), debugstr_w(pty
->DocString
));
1101 dump_TLBFuncDesc(pty
->funclist
);
1102 dump_TLBVarDesc(pty
->varlist
);
1103 dump_TLBImplType(pty
->impltypelist
);
1106 static TYPEDESC stndTypeDesc
[VT_LPWSTR
+1]=
1108 /* VT_LPWSTR is largest type that */
1109 /* may appear in type description*/
1110 {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
1111 {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
1112 {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
1113 {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
1114 {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
1115 {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
1119 static void TLB_abort()
1123 static void * TLB_Alloc(unsigned size
)
1126 if((ret
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,size
))==NULL
){
1128 ERR("cannot allocate memory\n");
1133 static void TLB_Free(void * ptr
)
1135 HeapFree(GetProcessHeap(), 0, ptr
);
1139 /**********************************************************************
1141 * Functions for reading MSFT typelibs (those created by CreateTypeLib2)
1144 DWORD
MSFT_Read(void *buffer
, DWORD count
, TLBContext
*pcx
, long where
)
1146 TRACE_(typelib
)("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n",
1147 pcx
->pos
, count
, pcx
->oStart
, pcx
->length
, where
);
1149 if (where
!= DO_NOT_SEEK
)
1151 where
+= pcx
->oStart
;
1152 if (where
> pcx
->length
)
1155 ERR("seek beyond end (%ld/%d)\n", where
, pcx
->length
);
1160 if (pcx
->pos
+ count
> pcx
->length
) count
= pcx
->length
- pcx
->pos
;
1161 memcpy( buffer
, (char *)pcx
->mapping
+ pcx
->pos
, count
);
1166 static void MSFT_ReadGuid( GUID
*pGuid
, int offset
, TLBContext
*pcx
)
1168 TRACE_(typelib
)("%s\n", debugstr_guid(pGuid
));
1170 if(offset
<0 || pcx
->pTblDir
->pGuidTab
.offset
<0){
1171 memset(pGuid
,0, sizeof(GUID
));
1174 MSFT_Read(pGuid
, sizeof(GUID
), pcx
, pcx
->pTblDir
->pGuidTab
.offset
+offset
);
1177 BSTR
MSFT_ReadName( TLBContext
*pcx
, int offset
)
1180 MSFT_NameIntro niName
;
1182 WCHAR
* pwstring
= NULL
;
1183 BSTR bstrName
= NULL
;
1185 MSFT_Read(&niName
, sizeof(niName
), pcx
,
1186 pcx
->pTblDir
->pNametab
.offset
+offset
);
1187 niName
.namelen
&= 0xFF; /* FIXME: correct ? */
1188 name
=TLB_Alloc((niName
.namelen
& 0xff) +1);
1189 MSFT_Read(name
, (niName
.namelen
& 0xff), pcx
, DO_NOT_SEEK
);
1190 name
[niName
.namelen
& 0xff]='\0';
1192 lengthInChars
= MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
| MB_ERR_INVALID_CHARS
,
1195 /* no invalid characters in string */
1198 pwstring
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*lengthInChars
);
1200 /* don't check for invalid character since this has been done previously */
1201 MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, name
, -1, pwstring
, lengthInChars
);
1203 bstrName
= SysAllocStringLen(pwstring
, lengthInChars
);
1204 lengthInChars
= SysStringLen(bstrName
);
1205 HeapFree(GetProcessHeap(), 0, pwstring
);
1208 TRACE_(typelib
)("%s %d\n", debugstr_w(bstrName
), lengthInChars
);
1212 BSTR
MSFT_ReadString( TLBContext
*pcx
, int offset
)
1219 if(offset
<0) return NULL
;
1220 MSFT_Read(&length
, sizeof(INT16
), pcx
, pcx
->pTblDir
->pStringtab
.offset
+offset
);
1221 if(length
<= 0) return 0;
1222 string
=TLB_Alloc(length
+1);
1223 MSFT_Read(string
, length
, pcx
, DO_NOT_SEEK
);
1224 string
[length
]='\0';
1226 lengthInChars
= MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
| MB_ERR_INVALID_CHARS
,
1227 string
, -1, NULL
, 0);
1229 /* no invalid characters in string */
1232 WCHAR
* pwstring
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*lengthInChars
);
1234 /* don't check for invalid character since this has been done previously */
1235 MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, string
, -1, pwstring
, lengthInChars
);
1237 bstr
= SysAllocStringLen(pwstring
, lengthInChars
);
1238 lengthInChars
= SysStringLen(bstr
);
1239 HeapFree(GetProcessHeap(), 0, pwstring
);
1242 TRACE_(typelib
)("%s %d\n", debugstr_w(bstr
), lengthInChars
);
1246 * read a value and fill a VARIANT structure
1248 static void MSFT_ReadValue( VARIANT
* pVar
, int offset
, TLBContext
*pcx
)
1252 TRACE_(typelib
)("\n");
1254 if(offset
<0) { /* data are packed in here */
1255 V_VT(pVar
) = (offset
& 0x7c000000 )>> 26;
1256 V_UNION(pVar
, iVal
) = offset
& 0xffff;
1259 MSFT_Read(&(V_VT(pVar
)), sizeof(VARTYPE
), pcx
,
1260 pcx
->pTblDir
->pCustData
.offset
+ offset
);
1261 TRACE_(typelib
)("Vartype = %x\n", V_VT(pVar
));
1262 switch (V_VT(pVar
)){
1263 case VT_EMPTY
: /* FIXME: is this right? */
1264 case VT_NULL
: /* FIXME: is this right? */
1265 case VT_I2
: /* this should not happen */
1276 case VT_VOID
: /* FIXME: is this right? */
1284 case VT_DECIMAL
: /* FIXME: is this right? */
1287 /* pointer types with known behaviour */
1290 MSFT_Read(&size
, sizeof(INT
), pcx
, DO_NOT_SEEK
);
1292 FIXME("BSTR length = %d?\n", size
);
1294 ptr
=TLB_Alloc(size
);/* allocate temp buffer */
1295 MSFT_Read(ptr
, size
, pcx
, DO_NOT_SEEK
);/* read string (ANSI) */
1296 V_UNION(pVar
, bstrVal
)=SysAllocStringLen(NULL
,size
);
1297 /* FIXME: do we need a AtoW conversion here? */
1298 V_UNION(pVar
, bstrVal
[size
])=L
'\0';
1299 while(size
--) V_UNION(pVar
, bstrVal
[size
])=ptr
[size
];
1304 /* FIXME: this will not work AT ALL when the variant contains a pointer */
1311 case VT_USERDEFINED
:
1317 case VT_STREAMED_OBJECT
:
1318 case VT_STORED_OBJECT
:
1319 case VT_BLOB_OBJECT
:
1324 FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
1328 if(size
>0) /* (big|small) endian correct? */
1329 MSFT_Read(&(V_UNION(pVar
, iVal
)), size
, pcx
, DO_NOT_SEEK
);
1333 * create a linked list with custom data
1335 static int MSFT_CustData( TLBContext
*pcx
, int offset
, TLBCustData
** ppCustData
)
1341 TRACE_(typelib
)("\n");
1345 pNew
=TLB_Alloc(sizeof(TLBCustData
));
1346 MSFT_Read(&entry
, sizeof(entry
), pcx
,
1347 pcx
->pTblDir
->pCDGuids
.offset
+offset
);
1348 MSFT_ReadGuid(&(pNew
->guid
), entry
.GuidOffset
, pcx
);
1349 MSFT_ReadValue(&(pNew
->data
), entry
.DataOffset
, pcx
);
1350 /* add new custom data at head of the list */
1351 pNew
->next
=*ppCustData
;
1353 offset
= entry
.next
;
1358 static void MSFT_GetTdesc(TLBContext
*pcx
, INT type
, TYPEDESC
*pTd
,
1362 pTd
->vt
=type
& VT_TYPEMASK
;
1364 *pTd
=pcx
->pLibInfo
->pTypeDesc
[type
/(2*sizeof(INT
))];
1366 if(pTd
->vt
== VT_USERDEFINED
)
1367 MSFT_DoRefType(pcx
, pTI
, pTd
->u
.hreftype
);
1369 TRACE_(typelib
)("vt type = %X\n", pTd
->vt
);
1373 MSFT_DoFuncs(TLBContext
* pcx
,
1378 TLBFuncDesc
** pptfd
)
1381 * member information is stored in a data structure at offset
1382 * indicated by the memoffset field of the typeinfo structure
1383 * There are several distinctive parts.
1384 * the first part starts with a field that holds the total length
1385 * of this (first) part excluding this field. Then follow the records,
1386 * for each member there is one record.
1388 * First entry is always the length of the record (excluding this
1390 * Rest of the record depends on the type of the member. If there is
1391 * a field indicating the member type (function variable intereface etc)
1392 * I have not found it yet. At this time we depend on the information
1393 * in the type info and the usual order how things are stored.
1395 * Second follows an array sized nrMEM*sizeof(INT) with a memeber id
1398 * Third is a equal sized array with file offsets to the name entry
1401 * Forth and last (?) part is an array with offsets to the records in the
1402 * first part of this file segment.
1405 int infolen
, nameoffset
, reclength
, nrattributes
, i
;
1406 int recoffset
= offset
+ sizeof(INT
);
1409 MSFT_FuncRecord
* pFuncRec
=(MSFT_FuncRecord
*) recbuf
;
1411 TRACE_(typelib
)("\n");
1413 MSFT_Read(&infolen
, sizeof(INT
), pcx
, offset
);
1415 for ( i
= 0; i
< cFuncs
; i
++ )
1417 *pptfd
= TLB_Alloc(sizeof(TLBFuncDesc
));
1419 /* name, eventually add to a hash table */
1420 MSFT_Read(&nameoffset
,
1423 offset
+ infolen
+ (cFuncs
+ cVars
+ i
+ 1) * sizeof(INT
));
1425 (*pptfd
)->Name
= MSFT_ReadName(pcx
, nameoffset
);
1427 /* read the function information record */
1428 MSFT_Read(&reclength
, sizeof(INT
), pcx
, recoffset
);
1432 MSFT_Read(pFuncRec
, reclength
- sizeof(INT
), pcx
, DO_NOT_SEEK
) ;
1434 /* do the attributes */
1435 nrattributes
= (reclength
- pFuncRec
->nrargs
* 3 * sizeof(int) - 0x18)
1438 if ( nrattributes
> 0 )
1440 (*pptfd
)->helpcontext
= pFuncRec
->OptAttr
[0] ;
1442 if ( nrattributes
> 1 )
1444 (*pptfd
)->HelpString
= MSFT_ReadString(pcx
,
1445 pFuncRec
->OptAttr
[1]) ;
1447 if ( nrattributes
> 2 )
1449 if ( pFuncRec
->FKCCIC
& 0x2000 )
1451 (*pptfd
)->Entry
= (WCHAR
*) pFuncRec
->OptAttr
[2] ;
1455 (*pptfd
)->Entry
= MSFT_ReadString(pcx
,
1456 pFuncRec
->OptAttr
[2]);
1458 if( nrattributes
> 5 )
1460 (*pptfd
)->HelpStringContext
= pFuncRec
->OptAttr
[5] ;
1462 if ( nrattributes
> 6 && pFuncRec
->FKCCIC
& 0x80 )
1465 pFuncRec
->OptAttr
[6],
1466 &(*pptfd
)->pCustData
);
1473 /* fill the FuncDesc Structure */
1474 MSFT_Read( & (*pptfd
)->funcdesc
.memid
,
1476 offset
+ infolen
+ ( i
+ 1) * sizeof(INT
));
1478 (*pptfd
)->funcdesc
.funckind
= (pFuncRec
->FKCCIC
) & 0x7;
1479 (*pptfd
)->funcdesc
.invkind
= (pFuncRec
->FKCCIC
) >> 3 & 0xF;
1480 (*pptfd
)->funcdesc
.callconv
= (pFuncRec
->FKCCIC
) >> 8 & 0xF;
1481 (*pptfd
)->funcdesc
.cParams
= pFuncRec
->nrargs
;
1482 (*pptfd
)->funcdesc
.cParamsOpt
= pFuncRec
->nroargs
;
1483 (*pptfd
)->funcdesc
.oVft
= pFuncRec
->VtableOffset
;
1484 (*pptfd
)->funcdesc
.wFuncFlags
= LOWORD(pFuncRec
->Flags
) ;
1488 &(*pptfd
)->funcdesc
.elemdescFunc
.tdesc
,
1491 /* do the parameters/arguments */
1492 if(pFuncRec
->nrargs
)
1495 MSFT_ParameterInfo paraminfo
;
1497 (*pptfd
)->funcdesc
.lprgelemdescParam
=
1498 TLB_Alloc(pFuncRec
->nrargs
* sizeof(ELEMDESC
));
1500 (*pptfd
)->pParamDesc
=
1501 TLB_Alloc(pFuncRec
->nrargs
* sizeof(TLBParDesc
));
1503 MSFT_Read(¶minfo
,
1506 recoffset
+ reclength
-
1507 pFuncRec
->nrargs
* sizeof(MSFT_ParameterInfo
));
1509 for ( j
= 0 ; j
< pFuncRec
->nrargs
; j
++ )
1511 TYPEDESC
* lpArgTypeDesc
= 0;
1515 &(*pptfd
)->funcdesc
.lprgelemdescParam
[j
].tdesc
,
1518 (*pptfd
)->funcdesc
.lprgelemdescParam
[j
].u
.paramdesc
.wParamFlags
= paraminfo
.Flags
;
1520 (*pptfd
)->pParamDesc
[j
].Name
= (void *) paraminfo
.oName
;
1522 /* SEEK value = jump to offset,
1523 * from there jump to the end of record,
1524 * go back by (j-1) arguments
1526 MSFT_Read( ¶minfo
,
1527 sizeof(MSFT_ParameterInfo
), pcx
,
1528 recoffset
+ reclength
- ((pFuncRec
->nrargs
- j
- 1)
1529 * sizeof(MSFT_ParameterInfo
)));
1531 & ((*pptfd
)->funcdesc
.lprgelemdescParam
[j
].tdesc
);
1533 while ( lpArgTypeDesc
!= NULL
)
1535 switch ( lpArgTypeDesc
->vt
)
1538 lpArgTypeDesc
= lpArgTypeDesc
->u
.lptdesc
;
1542 lpArgTypeDesc
= & (lpArgTypeDesc
->u
.lpadesc
->tdescElem
);
1545 case VT_USERDEFINED
:
1546 MSFT_DoRefType(pcx
, pTI
,
1547 lpArgTypeDesc
->u
.hreftype
);
1549 lpArgTypeDesc
= NULL
;
1553 lpArgTypeDesc
= NULL
;
1559 /* parameter is the return value! */
1560 if ( paraminfo
.Flags
& PARAMFLAG_FRETVAL
)
1562 TYPEDESC
* lpArgTypeDesc
;
1564 (*pptfd
)->funcdesc
.elemdescFunc
=
1565 (*pptfd
)->funcdesc
.lprgelemdescParam
[j
];
1567 lpArgTypeDesc
= & ((*pptfd
)->funcdesc
.elemdescFunc
.tdesc
) ;
1569 while ( lpArgTypeDesc
!= NULL
)
1571 switch ( lpArgTypeDesc
->vt
)
1574 lpArgTypeDesc
= lpArgTypeDesc
->u
.lptdesc
;
1578 & (lpArgTypeDesc
->u
.lpadesc
->tdescElem
);
1582 case VT_USERDEFINED
:
1585 lpArgTypeDesc
->u
.hreftype
);
1587 lpArgTypeDesc
= NULL
;
1591 lpArgTypeDesc
= NULL
;
1596 /* second time around */
1597 for(j
=0;j
<pFuncRec
->nrargs
;j
++)
1600 (*pptfd
)->pParamDesc
[j
].Name
=
1601 MSFT_ReadName( pcx
, (int)(*pptfd
)->pParamDesc
[j
].Name
);
1604 if ( (PARAMFLAG_FHASDEFAULT
&
1605 (*pptfd
)->funcdesc
.lprgelemdescParam
[j
].u
.paramdesc
.wParamFlags
) &&
1606 ((pFuncRec
->FKCCIC
) & 0x1000) )
1608 INT
* pInt
= (INT
*)((char *)pFuncRec
+
1610 (pFuncRec
->nrargs
* 4 + 1) * sizeof(INT
) );
1612 PARAMDESC
* pParamDesc
= & (*pptfd
)->funcdesc
.lprgelemdescParam
[j
].u
.paramdesc
;
1614 pParamDesc
->pparamdescex
= TLB_Alloc(sizeof(PARAMDESCEX
));
1615 pParamDesc
->pparamdescex
->cBytes
= sizeof(PARAMDESCEX
);
1617 MSFT_ReadValue(&(pParamDesc
->pparamdescex
->varDefaultValue
),
1621 if ( nrattributes
> 7 + j
&& pFuncRec
->FKCCIC
& 0x80 )
1624 pFuncRec
->OptAttr
[7+j
],
1625 &(*pptfd
)->pParamDesc
[j
].pCustData
);
1630 /* scode is not used: archaic win16 stuff FIXME: right? */
1631 (*pptfd
)->funcdesc
.cScodes
= 0 ;
1632 (*pptfd
)->funcdesc
.lprgscode
= NULL
;
1634 pptfd
= & ((*pptfd
)->next
);
1635 recoffset
+= reclength
;
1638 static void MSFT_DoVars(TLBContext
*pcx
, ITypeInfoImpl
*pTI
, int cFuncs
,
1639 int cVars
, int offset
, TLBVarDesc
** pptvd
)
1641 int infolen
, nameoffset
, reclength
;
1643 MSFT_VarRecord
* pVarRec
=(MSFT_VarRecord
*) recbuf
;
1647 TRACE_(typelib
)("\n");
1649 MSFT_Read(&infolen
,sizeof(INT
), pcx
, offset
);
1650 MSFT_Read(&recoffset
,sizeof(INT
), pcx
, offset
+ infolen
+
1651 ((cFuncs
+cVars
)*2+cFuncs
+ 1)*sizeof(INT
));
1652 recoffset
+= offset
+sizeof(INT
);
1653 for(i
=0;i
<cVars
;i
++){
1654 *pptvd
=TLB_Alloc(sizeof(TLBVarDesc
));
1655 /* name, eventually add to a hash table */
1656 MSFT_Read(&nameoffset
, sizeof(INT
), pcx
,
1657 offset
+ infolen
+ (cFuncs
+ cVars
+ i
+ 1) * sizeof(INT
));
1658 (*pptvd
)->Name
=MSFT_ReadName(pcx
, nameoffset
);
1659 /* read the variable information record */
1660 MSFT_Read(&reclength
, sizeof(INT
), pcx
, recoffset
);
1662 MSFT_Read(pVarRec
, reclength
- sizeof(INT
), pcx
, DO_NOT_SEEK
) ;
1664 if(reclength
>(6*sizeof(INT
)) )
1665 (*pptvd
)->HelpContext
=pVarRec
->HelpContext
;
1666 if(reclength
>(7*sizeof(INT
)) )
1667 (*pptvd
)->HelpString
= MSFT_ReadString(pcx
, pVarRec
->oHelpString
) ;
1668 if(reclength
>(8*sizeof(INT
)) )
1669 if(reclength
>(9*sizeof(INT
)) )
1670 (*pptvd
)->HelpStringContext
=pVarRec
->HelpStringContext
;
1671 /* fill the VarDesc Structure */
1672 MSFT_Read(&(*pptvd
)->vardesc
.memid
, sizeof(INT
), pcx
,
1673 offset
+ infolen
+ ( i
+ 1) * sizeof(INT
));
1674 (*pptvd
)->vardesc
.varkind
= pVarRec
->VarKind
;
1675 (*pptvd
)->vardesc
.wVarFlags
= pVarRec
->Flags
;
1676 MSFT_GetTdesc(pcx
, pVarRec
->DataType
,
1677 &(*pptvd
)->vardesc
.elemdescVar
.tdesc
, pTI
);
1678 /* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */
1679 if(pVarRec
->VarKind
== VAR_CONST
){
1680 (*pptvd
)->vardesc
.u
.lpvarValue
=TLB_Alloc(sizeof(VARIANT
));
1681 MSFT_ReadValue((*pptvd
)->vardesc
.u
.lpvarValue
,
1682 pVarRec
->OffsValue
, pcx
);
1684 (*pptvd
)->vardesc
.u
.oInst
=pVarRec
->OffsValue
;
1685 pptvd
=&((*pptvd
)->next
);
1686 recoffset
+= reclength
;
1689 /* fill in data for a hreftype (offset). When the refernced type is contained
1690 * in the typelib, it's just an (file) offset in the type info base dir.
1691 * If comes from import, it's an offset+1 in the ImpInfo table
1693 static void MSFT_DoRefType(TLBContext
*pcx
, ITypeInfoImpl
*pTI
,
1697 TLBRefType
**ppRefType
= &pTI
->reflist
;
1699 TRACE_(typelib
)("TLB context %p, TLB offset %x\n", pcx
, offset
);
1702 if((*ppRefType
)->reference
== offset
)
1704 ppRefType
= &(*ppRefType
)->next
;
1707 *ppRefType
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1708 sizeof(**ppRefType
));
1710 if(!MSFT_HREFTYPE_INTHISFILE( offset
)) {
1711 /* external typelib */
1712 MSFT_ImpInfo impinfo
;
1713 TLBImpLib
*pImpLib
=(pcx
->pLibInfo
->pImpLibs
);
1715 TRACE_(typelib
)("offset %x, masked offset %x\n", offset
, offset
+ (offset
& 0xfffffffc));
1717 MSFT_Read(&impinfo
, sizeof(impinfo
), pcx
,
1718 pcx
->pTblDir
->pImpInfo
.offset
+ (offset
& 0xfffffffc));
1719 for(j
=0;pImpLib
;j
++){ /* search the known offsets of all import libraries */
1720 if(pImpLib
->offset
==impinfo
.oImpFile
) break;
1721 pImpLib
=pImpLib
->next
;
1724 (*ppRefType
)->reference
=offset
;
1725 (*ppRefType
)->pImpTLInfo
= pImpLib
;
1726 MSFT_ReadGuid(&(*ppRefType
)->guid
, impinfo
.oGuid
, pcx
);
1727 (*ppRefType
)->index
= TLB_REF_USE_GUID
;
1729 ERR("Cannot find a reference\n");
1730 (*ppRefType
)->reference
=-1;
1731 (*ppRefType
)->pImpTLInfo
=TLB_REF_NOT_FOUND
;
1734 /* in this typelib */
1735 (*ppRefType
)->index
= MSFT_HREFTYPE_INDEX(offset
);
1736 (*ppRefType
)->reference
=offset
;
1737 (*ppRefType
)->pImpTLInfo
=TLB_REF_INTERNAL
;
1741 /* process Implemented Interfaces of a com class */
1742 static void MSFT_DoImplTypes(TLBContext
*pcx
, ITypeInfoImpl
*pTI
, int count
,
1746 MSFT_RefRecord refrec
;
1747 TLBImplType
**ppImpl
= &pTI
->impltypelist
;
1749 TRACE_(typelib
)("\n");
1751 for(i
=0;i
<count
;i
++){
1752 if(offset
<0) break; /* paranoia */
1753 *ppImpl
=TLB_Alloc(sizeof(**ppImpl
));
1754 MSFT_Read(&refrec
,sizeof(refrec
),pcx
,offset
+pcx
->pTblDir
->pRefTab
.offset
);
1755 MSFT_DoRefType(pcx
, pTI
, refrec
.reftype
);
1756 (*ppImpl
)->hRef
= refrec
.reftype
;
1757 (*ppImpl
)->implflags
=refrec
.flags
;
1758 (*ppImpl
)->ctCustData
=
1759 MSFT_CustData(pcx
, refrec
.oCustData
, &(*ppImpl
)->pCustData
);
1760 offset
=refrec
.onext
;
1761 ppImpl
=&((*ppImpl
)->next
);
1765 * process a typeinfo record
1767 ITypeInfoImpl
* MSFT_DoTypeInfo(
1770 ITypeLibImpl
* pLibInfo
)
1772 MSFT_TypeInfoBase tiBase
;
1773 ITypeInfoImpl
*ptiRet
;
1775 TRACE_(typelib
)("count=%u\n", count
);
1777 ptiRet
= (ITypeInfoImpl
*) ITypeInfo_Constructor();
1778 MSFT_Read(&tiBase
, sizeof(tiBase
) ,pcx
,
1779 pcx
->pTblDir
->pTypeInfoTab
.offset
+count
*sizeof(tiBase
));
1780 /* this is where we are coming from */
1781 ptiRet
->pTypeLib
= pLibInfo
;
1782 ITypeLib2_AddRef((ITypeLib2
*)pLibInfo
);
1783 ptiRet
->index
=count
;
1784 /* fill in the typeattr fields */
1785 FIXME("Assign constructor/destructor memid\n");
1787 MSFT_ReadGuid(&ptiRet
->TypeAttr
.guid
, tiBase
.posguid
, pcx
);
1788 ptiRet
->TypeAttr
.lcid
=pLibInfo
->LibAttr
.lcid
; /* FIXME: correct? */
1789 ptiRet
->TypeAttr
.memidConstructor
=MEMBERID_NIL
;/* FIXME */
1790 ptiRet
->TypeAttr
.memidDestructor
=MEMBERID_NIL
; /* FIXME */
1791 ptiRet
->TypeAttr
.lpstrSchema
=NULL
; /* reserved */
1792 ptiRet
->TypeAttr
.cbSizeInstance
=tiBase
.size
;
1793 ptiRet
->TypeAttr
.typekind
=tiBase
.typekind
& 0xF;
1794 ptiRet
->TypeAttr
.cFuncs
=LOWORD(tiBase
.cElement
);
1795 ptiRet
->TypeAttr
.cVars
=HIWORD(tiBase
.cElement
);
1796 ptiRet
->TypeAttr
.cbAlignment
=(tiBase
.typekind
>> 11 )& 0x1F; /* there are more flags there */
1797 ptiRet
->TypeAttr
.wTypeFlags
=tiBase
.flags
;
1798 ptiRet
->TypeAttr
.wMajorVerNum
=LOWORD(tiBase
.version
);
1799 ptiRet
->TypeAttr
.wMinorVerNum
=HIWORD(tiBase
.version
);
1800 ptiRet
->TypeAttr
.cImplTypes
=tiBase
.cImplTypes
;
1801 ptiRet
->TypeAttr
.cbSizeVft
=tiBase
.cbSizeVft
; /* FIXME: this is only the non inherited part */
1802 if(ptiRet
->TypeAttr
.typekind
== TKIND_ALIAS
)
1803 MSFT_GetTdesc(pcx
, tiBase
.datatype1
,
1804 &ptiRet
->TypeAttr
.tdescAlias
, ptiRet
);
1807 /* IDLDESC idldescType; *//* never saw this one != zero */
1809 /* name, eventually add to a hash table */
1810 ptiRet
->Name
=MSFT_ReadName(pcx
, tiBase
.NameOffset
);
1811 TRACE_(typelib
)("reading %s\n", debugstr_w(ptiRet
->Name
));
1813 ptiRet
->DocString
=MSFT_ReadString(pcx
, tiBase
.docstringoffs
);
1814 ptiRet
->dwHelpStringContext
=tiBase
.helpstringcontext
;
1815 ptiRet
->dwHelpContext
=tiBase
.helpcontext
;
1816 /* note: InfoType's Help file and HelpStringDll come from the containing
1817 * library. Further HelpString and Docstring appear to be the same thing :(
1820 if(ptiRet
->TypeAttr
.cFuncs
>0 )
1821 MSFT_DoFuncs(pcx
, ptiRet
, ptiRet
->TypeAttr
.cFuncs
,
1822 ptiRet
->TypeAttr
.cVars
,
1823 tiBase
.memoffset
, & ptiRet
->funclist
);
1825 if(ptiRet
->TypeAttr
.cVars
>0 )
1826 MSFT_DoVars(pcx
, ptiRet
, ptiRet
->TypeAttr
.cFuncs
,
1827 ptiRet
->TypeAttr
.cVars
,
1828 tiBase
.memoffset
, & ptiRet
->varlist
);
1829 if(ptiRet
->TypeAttr
.cImplTypes
>0 ) {
1830 switch(ptiRet
->TypeAttr
.typekind
)
1833 MSFT_DoImplTypes(pcx
, ptiRet
, ptiRet
->TypeAttr
.cImplTypes
,
1836 case TKIND_DISPATCH
:
1837 ptiRet
->impltypelist
=TLB_Alloc(sizeof(TLBImplType
));
1839 if (tiBase
.datatype1
!= -1)
1841 MSFT_DoRefType(pcx
, ptiRet
, tiBase
.datatype1
);
1842 ptiRet
->impltypelist
->hRef
= tiBase
.datatype1
;
1845 { /* FIXME: This is a really bad hack to add IDispatch */
1846 char* szStdOle
= "stdole2.tlb\0";
1847 int nStdOleLen
= strlen(szStdOle
);
1848 TLBRefType
**ppRef
= &ptiRet
->reflist
;
1851 if((*ppRef
)->reference
== -1)
1853 ppRef
= &(*ppRef
)->next
;
1856 *ppRef
= TLB_Alloc(sizeof(**ppRef
));
1857 (*ppRef
)->guid
= IID_IDispatch
;
1858 (*ppRef
)->reference
= -1;
1859 (*ppRef
)->index
= TLB_REF_USE_GUID
;
1860 (*ppRef
)->pImpTLInfo
= TLB_Alloc(sizeof(TLBImpLib
));
1861 (*ppRef
)->pImpTLInfo
->guid
= IID_StdOle
;
1862 (*ppRef
)->pImpTLInfo
->name
= SysAllocStringLen(NULL
,
1865 MultiByteToWideChar(CP_ACP
,
1869 (*ppRef
)->pImpTLInfo
->name
,
1870 SysStringLen((*ppRef
)->pImpTLInfo
->name
));
1872 (*ppRef
)->pImpTLInfo
->lcid
= 0;
1873 (*ppRef
)->pImpTLInfo
->wVersionMajor
= 2;
1874 (*ppRef
)->pImpTLInfo
->wVersionMinor
= 0;
1879 ptiRet
->impltypelist
=TLB_Alloc(sizeof(TLBImplType
));
1880 MSFT_DoRefType(pcx
, ptiRet
, tiBase
.datatype1
);
1881 ptiRet
->impltypelist
->hRef
= tiBase
.datatype1
;
1886 MSFT_CustData(pcx
, tiBase
.oCustData
, &ptiRet
->pCustData
);
1888 TRACE_(typelib
)("%s guid: %s kind:%s\n",
1889 debugstr_w(ptiRet
->Name
),
1890 debugstr_guid(&ptiRet
->TypeAttr
.guid
),
1891 typekind_desc
[ptiRet
->TypeAttr
.typekind
]);
1896 /****************************************************************************
1899 * find the type of the typelib file and map the typelib resource into
1902 #define MSFT_SIGNATURE 0x5446534D /* "MSFT" */
1903 #define SLTG_SIGNATURE 0x47544c53 /* "SLTG" */
1904 int TLB_ReadTypeLib(LPCWSTR pszFileName
, INT index
, ITypeLib2
**ppTypeLib
)
1906 int ret
= TYPE_E_CANTLOADLIBRARY
;
1907 DWORD dwSignature
= 0;
1910 TRACE_(typelib
)("%s:%d\n", debugstr_w(pszFileName
), index
);
1914 /* check the signature of the file */
1915 hFile
= CreateFileW( pszFileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, 0 );
1916 if (INVALID_HANDLE_VALUE
!= hFile
)
1918 HANDLE hMapping
= CreateFileMappingA( hFile
, NULL
, PAGE_READONLY
| SEC_COMMIT
, 0, 0, NULL
);
1921 LPVOID pBase
= MapViewOfFile(hMapping
, FILE_MAP_READ
, 0, 0, 0);
1924 /* retrieve file size */
1925 DWORD dwTLBLength
= GetFileSize(hFile
, NULL
);
1927 /* first try to load as *.tlb */
1928 dwSignature
= *((DWORD
*) pBase
);
1929 if ( dwSignature
== MSFT_SIGNATURE
)
1931 *ppTypeLib
= ITypeLib2_Constructor_MSFT(pBase
, dwTLBLength
);
1933 else if ( dwSignature
== SLTG_SIGNATURE
)
1935 *ppTypeLib
= ITypeLib2_Constructor_SLTG(pBase
, dwTLBLength
);
1937 UnmapViewOfFile(pBase
);
1939 CloseHandle(hMapping
);
1944 if( (WORD
)dwSignature
== IMAGE_DOS_SIGNATURE
)
1946 /* find the typelibrary resource*/
1947 HINSTANCE hinstDLL
= LoadLibraryExW(pszFileName
, 0, DONT_RESOLVE_DLL_REFERENCES
|
1948 LOAD_LIBRARY_AS_DATAFILE
|LOAD_WITH_ALTERED_SEARCH_PATH
);
1951 HRSRC hrsrc
= FindResourceA(hinstDLL
, MAKEINTRESOURCEA(index
),
1955 HGLOBAL hGlobal
= LoadResource(hinstDLL
, hrsrc
);
1958 LPVOID pBase
= LockResource(hGlobal
);
1959 DWORD dwTLBLength
= SizeofResource(hinstDLL
, hrsrc
);
1963 /* try to load as incore resource */
1964 dwSignature
= *((DWORD
*) pBase
);
1965 if ( dwSignature
== MSFT_SIGNATURE
)
1967 *ppTypeLib
= ITypeLib2_Constructor_MSFT(pBase
, dwTLBLength
);
1969 else if ( dwSignature
== SLTG_SIGNATURE
)
1971 *ppTypeLib
= ITypeLib2_Constructor_SLTG(pBase
, dwTLBLength
);
1975 FIXME("Header type magic 0x%08lx not supported.\n",dwSignature
);
1978 FreeResource( hGlobal
);
1981 FreeLibrary(hinstDLL
);
1988 ERR("Loading of typelib %s failed with error %ld\n",
1989 debugstr_w(pszFileName
), GetLastError());
1994 /*================== ITypeLib(2) Methods ===================================*/
1996 /****************************************************************************
1997 * ITypeLib2_Constructor_MSFT
1999 * loading an MSFT typelib from an in-memory image
2001 static ITypeLib2
* ITypeLib2_Constructor_MSFT(LPVOID pLib
, DWORD dwTLBLength
)
2005 MSFT_Header tlbHeader
;
2006 MSFT_SegDir tlbSegDir
;
2007 ITypeLibImpl
* pTypeLibImpl
;
2009 TRACE("%p, TLB length = %ld\n", pLib
, dwTLBLength
);
2011 pTypeLibImpl
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ITypeLibImpl
));
2012 if (!pTypeLibImpl
) return NULL
;
2014 ICOM_VTBL(pTypeLibImpl
) = &tlbvt
;
2015 pTypeLibImpl
->ref
= 1;
2017 /* get pointer to beginning of typelib data */
2021 cx
.pLibInfo
= pTypeLibImpl
;
2022 cx
.length
= dwTLBLength
;
2025 MSFT_Read((void*)&tlbHeader
, sizeof(tlbHeader
), &cx
, 0);
2027 TRACE("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader
.magic1
,tlbHeader
.magic2
);
2028 if (memcmp(&tlbHeader
.magic1
,TLBMAGIC2
,4)) {
2029 FIXME("Header type magic 0x%08x not supported.\n",tlbHeader
.magic1
);
2032 /* there is a small amount of information here until the next important
2034 * the segment directory . Try to calculate the amount of data */
2035 lPSegDir
= sizeof(tlbHeader
) + (tlbHeader
.nrtypeinfos
)*4 + ((tlbHeader
.varflags
& HELPDLLFLAG
)? 4 :0);
2037 /* now read the segment directory */
2038 TRACE("read segment directory (at %ld)\n",lPSegDir
);
2039 MSFT_Read((void*)&tlbSegDir
, sizeof(tlbSegDir
), &cx
, lPSegDir
);
2040 cx
.pTblDir
= &tlbSegDir
;
2042 /* just check two entries */
2043 if ( tlbSegDir
.pTypeInfoTab
.res0c
!= 0x0F || tlbSegDir
.pImpInfo
.res0c
!= 0x0F)
2045 ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir
);
2046 HeapFree(GetProcessHeap(),0,pTypeLibImpl
);
2050 /* now fill our internal data */
2051 /* TLIBATTR fields */
2052 MSFT_ReadGuid(&pTypeLibImpl
->LibAttr
.guid
, tlbHeader
.posguid
, &cx
);
2054 /* pTypeLibImpl->LibAttr.lcid = tlbHeader.lcid;*/
2055 /* Windows seems to have zero here, is this correct? */
2056 if(SUBLANGID(tlbHeader
.lcid
) == SUBLANG_NEUTRAL
)
2057 pTypeLibImpl
->LibAttr
.lcid
= PRIMARYLANGID(tlbHeader
.lcid
);
2059 pTypeLibImpl
->LibAttr
.lcid
= 0;
2061 pTypeLibImpl
->LibAttr
.syskind
= tlbHeader
.varflags
& 0x0f; /* check the mask */
2062 pTypeLibImpl
->LibAttr
.wMajorVerNum
= LOWORD(tlbHeader
.version
);
2063 pTypeLibImpl
->LibAttr
.wMinorVerNum
= HIWORD(tlbHeader
.version
);
2064 pTypeLibImpl
->LibAttr
.wLibFlags
= (WORD
) tlbHeader
.flags
& 0xffff;/* check mask */
2066 /* name, eventually add to a hash table */
2067 pTypeLibImpl
->Name
= MSFT_ReadName(&cx
, tlbHeader
.NameOffset
);
2070 pTypeLibImpl
->DocString
= MSFT_ReadString(&cx
, tlbHeader
.helpstring
);
2071 pTypeLibImpl
->HelpFile
= MSFT_ReadString(&cx
, tlbHeader
.helpfile
);
2073 if( tlbHeader
.varflags
& HELPDLLFLAG
)
2076 MSFT_Read(&offset
, sizeof(offset
), &cx
, sizeof(tlbHeader
));
2077 pTypeLibImpl
->HelpStringDll
= MSFT_ReadString(&cx
, offset
);
2080 pTypeLibImpl
->dwHelpContext
= tlbHeader
.helpstringcontext
;
2083 if(tlbHeader
.CustomDataOffset
>= 0)
2085 pTypeLibImpl
->ctCustData
= MSFT_CustData(&cx
, tlbHeader
.CustomDataOffset
, &pTypeLibImpl
->pCustData
);
2088 /* fill in typedescriptions */
2089 if(tlbSegDir
.pTypdescTab
.length
> 0)
2091 int i
, j
, cTD
= tlbSegDir
.pTypdescTab
.length
/ (2*sizeof(INT
));
2093 pTypeLibImpl
->pTypeDesc
= TLB_Alloc( cTD
* sizeof(TYPEDESC
));
2094 MSFT_Read(td
, sizeof(td
), &cx
, tlbSegDir
.pTypdescTab
.offset
);
2097 /* FIXME: add several sanity checks here */
2098 pTypeLibImpl
->pTypeDesc
[i
].vt
= td
[0] & VT_TYPEMASK
;
2099 if(td
[0] == VT_PTR
|| td
[0] == VT_SAFEARRAY
)
2101 /* FIXME: check safearray */
2103 pTypeLibImpl
->pTypeDesc
[i
].u
.lptdesc
= & stndTypeDesc
[td
[2]];
2105 pTypeLibImpl
->pTypeDesc
[i
].u
.lptdesc
= & pTypeLibImpl
->pTypeDesc
[td
[2]/8];
2107 else if(td
[0] == VT_CARRAY
)
2109 /* array descr table here */
2110 pTypeLibImpl
->pTypeDesc
[i
].u
.lpadesc
= (void *)((int) td
[2]); /* temp store offset in*/
2112 else if(td
[0] == VT_USERDEFINED
)
2114 pTypeLibImpl
->pTypeDesc
[i
].u
.hreftype
= MAKELONG(td
[2],td
[3]);
2116 if(++i
<cTD
) MSFT_Read(td
, sizeof(td
), &cx
, DO_NOT_SEEK
);
2119 /* second time around to fill the array subscript info */
2122 if(pTypeLibImpl
->pTypeDesc
[i
].vt
!= VT_CARRAY
) continue;
2123 if(tlbSegDir
.pArrayDescriptions
.offset
>0)
2125 MSFT_Read(td
, sizeof(td
), &cx
, tlbSegDir
.pArrayDescriptions
.offset
+ (int) pTypeLibImpl
->pTypeDesc
[i
].u
.lpadesc
);
2126 pTypeLibImpl
->pTypeDesc
[i
].u
.lpadesc
= TLB_Alloc(sizeof(ARRAYDESC
)+sizeof(SAFEARRAYBOUND
)*(td
[3]-1));
2129 pTypeLibImpl
->pTypeDesc
[i
].u
.lpadesc
->tdescElem
.vt
= td
[0] & VT_TYPEMASK
;
2131 pTypeLibImpl
->pTypeDesc
[i
].u
.lpadesc
->tdescElem
= stndTypeDesc
[td
[0]/8];
2133 pTypeLibImpl
->pTypeDesc
[i
].u
.lpadesc
->cDims
= td
[2];
2135 for(j
= 0; j
<td
[2]; j
++)
2137 MSFT_Read(& pTypeLibImpl
->pTypeDesc
[i
].u
.lpadesc
->rgbounds
[j
].cElements
,
2138 sizeof(INT
), &cx
, DO_NOT_SEEK
);
2139 MSFT_Read(& pTypeLibImpl
->pTypeDesc
[i
].u
.lpadesc
->rgbounds
[j
].lLbound
,
2140 sizeof(INT
), &cx
, DO_NOT_SEEK
);
2145 pTypeLibImpl
->pTypeDesc
[i
].u
.lpadesc
= NULL
;
2146 ERR("didn't find array description data\n");
2151 /* imported type libs */
2152 if(tlbSegDir
.pImpFiles
.offset
>0)
2154 TLBImpLib
**ppImpLib
= &(pTypeLibImpl
->pImpLibs
);
2155 int oGuid
, offset
= tlbSegDir
.pImpFiles
.offset
;
2158 while(offset
< tlbSegDir
.pImpFiles
.offset
+tlbSegDir
.pImpFiles
.length
)
2160 *ppImpLib
= TLB_Alloc(sizeof(TLBImpLib
));
2161 (*ppImpLib
)->offset
= offset
- tlbSegDir
.pImpFiles
.offset
;
2162 MSFT_Read(&oGuid
, sizeof(INT
), &cx
, offset
);
2164 MSFT_Read(&(*ppImpLib
)->lcid
, sizeof(LCID
), &cx
, DO_NOT_SEEK
);
2165 MSFT_Read(&(*ppImpLib
)->wVersionMajor
, sizeof(WORD
), &cx
, DO_NOT_SEEK
);
2166 MSFT_Read(&(*ppImpLib
)->wVersionMinor
, sizeof(WORD
), &cx
, DO_NOT_SEEK
);
2167 MSFT_Read(& size
, sizeof(UINT16
), &cx
, DO_NOT_SEEK
);
2170 (*ppImpLib
)->name
= TLB_Alloc(size
+1);
2171 MSFT_Read((*ppImpLib
)->name
, size
, &cx
, DO_NOT_SEEK
);
2172 MSFT_ReadGuid(&(*ppImpLib
)->guid
, oGuid
, &cx
);
2173 offset
= (offset
+ sizeof(INT
) + sizeof(DWORD
) + sizeof(LCID
) + sizeof(UINT16
) + size
+ 3) & 0xfffffffc;
2175 ppImpLib
= &(*ppImpLib
)->next
;
2180 if(tlbHeader
.nrtypeinfos
>= 0 )
2182 /*pTypeLibImpl->TypeInfoCount=tlbHeader.nrtypeinfos; */
2183 ITypeInfoImpl
**ppTI
= &(pTypeLibImpl
->pTypeInfo
);
2186 for(i
= 0; i
<(int)tlbHeader
.nrtypeinfos
; i
++)
2188 *ppTI
= MSFT_DoTypeInfo(&cx
, i
, pTypeLibImpl
);
2190 ITypeInfo_AddRef((ITypeInfo
*) *ppTI
);
2191 ppTI
= &((*ppTI
)->next
);
2192 (pTypeLibImpl
->TypeInfoCount
)++;
2196 TRACE("(%p)\n", pTypeLibImpl
);
2197 return (ITypeLib2
*) pTypeLibImpl
;
2201 static BSTR
TLB_MultiByteToBSTR(char *ptr
)
2207 len
= MultiByteToWideChar(CP_ACP
, 0, ptr
, -1, NULL
, 0);
2208 nameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2209 MultiByteToWideChar(CP_ACP
, 0, ptr
, -1, nameW
, len
);
2210 ret
= SysAllocString(nameW
);
2211 HeapFree(GetProcessHeap(), 0, nameW
);
2215 static BOOL
TLB_GUIDFromString(char *str
, GUID
*guid
)
2221 if(sscanf(str
, "%lx-%hx-%hx-%hx", &guid
->Data1
, &guid
->Data2
, &guid
->Data3
, &s
) != 4) {
2222 FIXME("Can't parse guid %s\n", debugstr_guid(guid
));
2226 guid
->Data4
[0] = s
>> 8;
2227 guid
->Data4
[1] = s
& 0xff;
2230 for(i
= 0; i
< 6; i
++) {
2231 memcpy(b
, str
+ 24 + 2 * i
, 2);
2232 guid
->Data4
[i
+ 2] = strtol(b
, NULL
, 16);
2237 static WORD
SLTG_ReadString(char *ptr
, BSTR
*pBstr
)
2244 bytelen
= *(WORD
*)ptr
;
2245 if(bytelen
== 0xffff) return 2;
2246 len
= MultiByteToWideChar(CP_ACP
, 0, ptr
+ 2, bytelen
, NULL
, 0);
2247 nameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2248 len
= MultiByteToWideChar(CP_ACP
, 0, ptr
+ 2, bytelen
, nameW
, len
);
2249 *pBstr
= SysAllocStringLen(nameW
, len
);
2250 HeapFree(GetProcessHeap(), 0, nameW
);
2254 static WORD
SLTG_ReadStringA(char *ptr
, char **str
)
2259 bytelen
= *(WORD
*)ptr
;
2260 if(bytelen
== 0xffff) return 2;
2261 *str
= HeapAlloc(GetProcessHeap(), 0, bytelen
+ 1);
2262 memcpy(*str
, ptr
+ 2, bytelen
);
2263 (*str
)[bytelen
] = '\0';
2267 static DWORD
SLTG_ReadLibBlk(LPVOID pLibBlk
, ITypeLibImpl
*pTypeLibImpl
)
2269 char *ptr
= pLibBlk
;
2272 if((w
= *(WORD
*)ptr
) != SLTG_LIBBLK_MAGIC
) {
2273 FIXME("libblk magic = %04x\n", w
);
2278 if((w
= *(WORD
*)ptr
) != 0xffff) {
2279 FIXME("LibBlk.res06 = %04x. Assumung string and skipping\n", w
);
2284 ptr
+= SLTG_ReadString(ptr
, &pTypeLibImpl
->DocString
);
2286 ptr
+= SLTG_ReadString(ptr
, &pTypeLibImpl
->HelpFile
);
2288 pTypeLibImpl
->dwHelpContext
= *(DWORD
*)ptr
;
2291 pTypeLibImpl
->LibAttr
.syskind
= *(WORD
*)ptr
;
2294 pTypeLibImpl
->LibAttr
.lcid
= *(WORD
*)ptr
;
2297 ptr
+= 4; /* skip res12 */
2299 pTypeLibImpl
->LibAttr
.wLibFlags
= *(WORD
*)ptr
;
2302 pTypeLibImpl
->LibAttr
.wMajorVerNum
= *(WORD
*)ptr
;
2305 pTypeLibImpl
->LibAttr
.wMinorVerNum
= *(WORD
*)ptr
;
2308 memcpy(&pTypeLibImpl
->LibAttr
.guid
, ptr
, sizeof(GUID
));
2309 ptr
+= sizeof(GUID
);
2311 return ptr
- (char*)pLibBlk
;
2314 static WORD
*SLTG_DoType(WORD
*pType
, char *pBlk
, ELEMDESC
*pElem
)
2317 TYPEDESC
*pTD
= &pElem
->tdesc
;
2319 /* Handle [in/out] first */
2320 if((*pType
& 0xc000) == 0xc000)
2321 pElem
->u
.paramdesc
.wParamFlags
= PARAMFLAG_NONE
;
2322 else if(*pType
& 0x8000)
2323 pElem
->u
.paramdesc
.wParamFlags
= PARAMFLAG_FIN
| PARAMFLAG_FOUT
;
2324 else if(*pType
& 0x4000)
2325 pElem
->u
.paramdesc
.wParamFlags
= PARAMFLAG_FOUT
;
2327 pElem
->u
.paramdesc
.wParamFlags
= PARAMFLAG_FIN
;
2330 pElem
->u
.paramdesc
.wParamFlags
|= PARAMFLAG_FLCID
;
2333 pElem
->u
.paramdesc
.wParamFlags
|= PARAMFLAG_FRETVAL
;
2336 if((*pType
& 0xe00) == 0xe00) {
2338 pTD
->u
.lptdesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2340 pTD
= pTD
->u
.lptdesc
;
2342 switch(*pType
& 0x7f) {
2345 pTD
->u
.lptdesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2347 pTD
= pTD
->u
.lptdesc
;
2350 case VT_USERDEFINED
:
2351 pTD
->vt
= VT_USERDEFINED
;
2352 pTD
->u
.hreftype
= *(++pType
) / 4;
2358 /* *(pType+1) is offset to a SAFEARRAY, *(pType+2) is type of
2361 SAFEARRAY
*pSA
= (SAFEARRAY
*)(pBlk
+ *(++pType
));
2363 pTD
->vt
= VT_CARRAY
;
2364 pTD
->u
.lpadesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2366 (pSA
->cDims
- 1) * sizeof(SAFEARRAYBOUND
));
2367 pTD
->u
.lpadesc
->cDims
= pSA
->cDims
;
2368 memcpy(pTD
->u
.lpadesc
->rgbounds
, pSA
->rgsabound
,
2369 pSA
->cDims
* sizeof(SAFEARRAYBOUND
));
2371 pTD
= &pTD
->u
.lpadesc
->tdescElem
;
2377 /* FIXME: *(pType+1) gives an offset to SAFEARRAY, is this
2381 pTD
->vt
= VT_SAFEARRAY
;
2382 pTD
->u
.lptdesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2384 pTD
= pTD
->u
.lptdesc
;
2388 pTD
->vt
= *pType
& 0x7f;
2398 static void SLTG_DoRefs(SLTG_RefInfo
*pRef
, ITypeInfoImpl
*pTI
,
2403 TLBRefType
**ppRefType
;
2405 if(pRef
->magic
!= SLTG_REF_MAGIC
) {
2406 FIXME("Ref magic = %x\n", pRef
->magic
);
2409 name
= ( (char*)(&pRef
->names
) + pRef
->number
);
2411 ppRefType
= &pTI
->reflist
;
2412 for(ref
= 0; ref
< pRef
->number
>> 3; ref
++) {
2414 unsigned int lib_offs
, type_num
;
2416 *ppRefType
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2417 sizeof(**ppRefType
));
2419 name
+= SLTG_ReadStringA(name
, &refname
);
2420 if(sscanf(refname
, "*\\R%x*#%x", &lib_offs
, &type_num
) != 2)
2421 FIXME("Can't sscanf ref\n");
2422 if(lib_offs
!= 0xffff) {
2423 TLBImpLib
**import
= &pTI
->pTypeLib
->pImpLibs
;
2426 if((*import
)->offset
== lib_offs
)
2428 import
= &(*import
)->next
;
2431 char fname
[MAX_PATH
+1];
2434 *import
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2436 (*import
)->offset
= lib_offs
;
2437 TLB_GUIDFromString( pNameTable
+ lib_offs
+ 4,
2439 if(sscanf(pNameTable
+ lib_offs
+ 40, "}#%hd.%hd#%lx#%s",
2440 &(*import
)->wVersionMajor
,
2441 &(*import
)->wVersionMinor
,
2442 &(*import
)->lcid
, fname
) != 4) {
2443 FIXME("can't sscanf ref %s\n",
2444 pNameTable
+ lib_offs
+ 40);
2446 len
= strlen(fname
);
2447 if(fname
[len
-1] != '#')
2448 FIXME("fname = %s\n", fname
);
2449 fname
[len
-1] = '\0';
2450 (*import
)->name
= TLB_MultiByteToBSTR(fname
);
2452 (*ppRefType
)->pImpTLInfo
= *import
;
2453 } else { /* internal ref */
2454 (*ppRefType
)->pImpTLInfo
= TLB_REF_INTERNAL
;
2456 (*ppRefType
)->reference
= ref
;
2457 (*ppRefType
)->index
= type_num
;
2459 HeapFree(GetProcessHeap(), 0, refname
);
2460 ppRefType
= &(*ppRefType
)->next
;
2462 if((BYTE
)*name
!= SLTG_REF_MAGIC
)
2463 FIXME("End of ref block magic = %x\n", *name
);
2464 dump_TLBRefType(pTI
->reflist
);
2467 static char *SLTG_DoImpls(char *pBlk
, ITypeInfoImpl
*pTI
,
2470 SLTG_ImplInfo
*info
;
2471 TLBImplType
**ppImplType
= &pTI
->impltypelist
;
2472 /* I don't really get this structure, usually it's 0x16 bytes
2473 long, but iuser.tlb contains some that are 0x18 bytes long.
2474 That's ok because we can use the next ptr to jump to the next
2475 one. But how do we know the length of the last one? The WORD
2476 at offs 0x8 might be the clue. For now I'm just assuming that
2477 the last one is the regular 0x16 bytes. */
2479 info
= (SLTG_ImplInfo
*)pBlk
;
2481 *ppImplType
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2482 sizeof(**ppImplType
));
2483 (*ppImplType
)->hRef
= info
->ref
;
2484 (*ppImplType
)->implflags
= info
->impltypeflags
;
2485 pTI
->TypeAttr
.cImplTypes
++;
2486 ppImplType
= &(*ppImplType
)->next
;
2488 if(info
->next
== 0xffff)
2491 FIXME("Interface inheriting more than one interface\n");
2492 info
= (SLTG_ImplInfo
*)(pBlk
+ info
->next
);
2494 info
++; /* see comment at top of function */
2498 static SLTG_TypeInfoTail
*SLTG_ProcessCoClass(char *pBlk
, ITypeInfoImpl
*pTI
,
2501 SLTG_TypeInfoHeader
*pTIHeader
= (SLTG_TypeInfoHeader
*)pBlk
;
2502 SLTG_MemberHeader
*pMemHeader
;
2503 char *pFirstItem
, *pNextItem
;
2505 if(pTIHeader
->href_table
!= 0xffffffff) {
2506 SLTG_DoRefs((SLTG_RefInfo
*)(pBlk
+ pTIHeader
->href_table
), pTI
,
2511 pMemHeader
= (SLTG_MemberHeader
*)(pBlk
+ pTIHeader
->elem_table
);
2513 pFirstItem
= pNextItem
= (char*)(pMemHeader
+ 1);
2515 if(*(WORD
*)pFirstItem
== SLTG_IMPL_MAGIC
) {
2516 pNextItem
= SLTG_DoImpls(pFirstItem
, pTI
, FALSE
);
2519 return (SLTG_TypeInfoTail
*)(pFirstItem
+ pMemHeader
->cbExtra
);
2523 static SLTG_TypeInfoTail
*SLTG_ProcessInterface(char *pBlk
, ITypeInfoImpl
*pTI
,
2526 SLTG_TypeInfoHeader
*pTIHeader
= (SLTG_TypeInfoHeader
*)pBlk
;
2527 SLTG_MemberHeader
*pMemHeader
;
2528 SLTG_Function
*pFunc
;
2529 char *pFirstItem
, *pNextItem
;
2530 TLBFuncDesc
**ppFuncDesc
= &pTI
->funclist
;
2533 if(pTIHeader
->href_table
!= 0xffffffff) {
2534 SLTG_DoRefs((SLTG_RefInfo
*)(pBlk
+ pTIHeader
->href_table
), pTI
,
2538 pMemHeader
= (SLTG_MemberHeader
*)(pBlk
+ pTIHeader
->elem_table
);
2540 pFirstItem
= pNextItem
= (char*)(pMemHeader
+ 1);
2542 if(*(WORD
*)pFirstItem
== SLTG_IMPL_MAGIC
) {
2543 pNextItem
= SLTG_DoImpls(pFirstItem
, pTI
, TRUE
);
2546 for(pFunc
= (SLTG_Function
*)pNextItem
, num
= 1; 1;
2547 pFunc
= (SLTG_Function
*)(pFirstItem
+ pFunc
->next
), num
++) {
2552 if(pFunc
->magic
!= SLTG_FUNCTION_MAGIC
&&
2553 pFunc
->magic
!= SLTG_FUNCTION_WITH_FLAGS_MAGIC
) {
2554 FIXME("func magic = %02x\n", pFunc
->magic
);
2557 *ppFuncDesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2558 sizeof(**ppFuncDesc
));
2559 (*ppFuncDesc
)->Name
= TLB_MultiByteToBSTR(pFunc
->name
+ pNameTable
);
2561 (*ppFuncDesc
)->funcdesc
.memid
= pFunc
->dispid
;
2562 (*ppFuncDesc
)->funcdesc
.invkind
= pFunc
->inv
>> 4;
2563 (*ppFuncDesc
)->funcdesc
.callconv
= pFunc
->nacc
& 0x7;
2564 (*ppFuncDesc
)->funcdesc
.cParams
= pFunc
->nacc
>> 3;
2565 (*ppFuncDesc
)->funcdesc
.cParamsOpt
= (pFunc
->retnextopt
& 0x7e) >> 1;
2566 (*ppFuncDesc
)->funcdesc
.oVft
= pFunc
->vtblpos
;
2568 if(pFunc
->magic
== SLTG_FUNCTION_WITH_FLAGS_MAGIC
)
2569 (*ppFuncDesc
)->funcdesc
.wFuncFlags
= pFunc
->funcflags
;
2571 if(pFunc
->retnextopt
& 0x80)
2572 pType
= &pFunc
->rettype
;
2574 pType
= (WORD
*)(pFirstItem
+ pFunc
->rettype
);
2577 SLTG_DoType(pType
, pFirstItem
, &(*ppFuncDesc
)->funcdesc
.elemdescFunc
);
2579 (*ppFuncDesc
)->funcdesc
.lprgelemdescParam
=
2580 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2581 (*ppFuncDesc
)->funcdesc
.cParams
* sizeof(ELEMDESC
));
2582 (*ppFuncDesc
)->pParamDesc
=
2583 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2584 (*ppFuncDesc
)->funcdesc
.cParams
* sizeof(TLBParDesc
));
2586 pArg
= (WORD
*)(pFirstItem
+ pFunc
->arg_off
);
2588 for(param
= 0; param
< (*ppFuncDesc
)->funcdesc
.cParams
; param
++) {
2589 char *paramName
= pNameTable
+ *pArg
;
2591 /* If arg type follows then paramName points to the 2nd
2592 letter of the name, else the next WORD is an offset to
2593 the arg type and paramName points to the first letter.
2594 So let's take one char off paramName and see if we're
2595 pointing at an alpha-numeric char. However if *pArg is
2596 0xffff or 0xfffe then the param has no name, the former
2597 meaning that the next WORD is the type, the latter
2598 meaning the the next WORD is an offset to the type. */
2603 else if(*pArg
== 0xfffe) {
2607 else if(!isalnum(*(paramName
-1)))
2612 if(HaveOffs
) { /* the next word is an offset to type */
2613 pType
= (WORD
*)(pFirstItem
+ *pArg
);
2614 SLTG_DoType(pType
, pFirstItem
,
2615 &(*ppFuncDesc
)->funcdesc
.lprgelemdescParam
[param
]);
2620 pArg
= SLTG_DoType(pArg
, pFirstItem
,
2621 &(*ppFuncDesc
)->funcdesc
.lprgelemdescParam
[param
]);
2624 /* Are we an optional param ? */
2625 if((*ppFuncDesc
)->funcdesc
.cParams
- param
<=
2626 (*ppFuncDesc
)->funcdesc
.cParamsOpt
)
2627 (*ppFuncDesc
)->funcdesc
.lprgelemdescParam
[param
].u
.paramdesc
.wParamFlags
|= PARAMFLAG_FOPT
;
2630 (*ppFuncDesc
)->pParamDesc
[param
].Name
=
2631 TLB_MultiByteToBSTR(paramName
);
2635 ppFuncDesc
= &((*ppFuncDesc
)->next
);
2636 if(pFunc
->next
== 0xffff) break;
2638 pTI
->TypeAttr
.cFuncs
= num
;
2639 dump_TLBFuncDesc(pTI
->funclist
);
2640 return (SLTG_TypeInfoTail
*)(pFirstItem
+ pMemHeader
->cbExtra
);
2643 static SLTG_TypeInfoTail
*SLTG_ProcessRecord(char *pBlk
, ITypeInfoImpl
*pTI
,
2646 SLTG_TypeInfoHeader
*pTIHeader
= (SLTG_TypeInfoHeader
*)pBlk
;
2647 SLTG_MemberHeader
*pMemHeader
;
2648 SLTG_RecordItem
*pItem
;
2650 TLBVarDesc
**ppVarDesc
= &pTI
->varlist
;
2655 pMemHeader
= (SLTG_MemberHeader
*)(pBlk
+ pTIHeader
->elem_table
);
2657 pFirstItem
= (char*)(pMemHeader
+ 1);
2658 for(pItem
= (SLTG_RecordItem
*)pFirstItem
, num
= 1; 1;
2659 pItem
= (SLTG_RecordItem
*)(pFirstItem
+ pItem
->next
), num
++) {
2660 if(pItem
->magic
!= SLTG_RECORD_MAGIC
) {
2661 FIXME("record magic = %02x\n", pItem
->magic
);
2664 *ppVarDesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2665 sizeof(**ppVarDesc
));
2666 (*ppVarDesc
)->Name
= TLB_MultiByteToBSTR(pItem
->name
+ pNameTable
);
2667 (*ppVarDesc
)->vardesc
.memid
= pItem
->memid
;
2668 (*ppVarDesc
)->vardesc
.u
.oInst
= pItem
->byte_offs
;
2669 (*ppVarDesc
)->vardesc
.varkind
= VAR_PERINSTANCE
;
2671 if(pItem
->typepos
== 0x02)
2672 pType
= &pItem
->type
;
2673 else if(pItem
->typepos
== 0x00)
2674 pType
= (WORD
*)(pFirstItem
+ pItem
->type
);
2676 FIXME("typepos = %02x\n", pItem
->typepos
);
2680 SLTG_DoType(pType
, pFirstItem
,
2681 &(*ppVarDesc
)->vardesc
.elemdescVar
);
2683 /* FIXME("helpcontext, helpstring\n"); */
2685 dump_TypeDesc(&(*ppVarDesc
)->vardesc
.elemdescVar
.tdesc
, buf
);
2687 ppVarDesc
= &((*ppVarDesc
)->next
);
2688 if(pItem
->next
== 0xffff) break;
2690 pTI
->TypeAttr
.cVars
= num
;
2691 return (SLTG_TypeInfoTail
*)(pFirstItem
+ pMemHeader
->cbExtra
);
2694 static SLTG_TypeInfoTail
*SLTG_ProcessEnum(char *pBlk
, ITypeInfoImpl
*pTI
,
2697 SLTG_TypeInfoHeader
*pTIHeader
= (SLTG_TypeInfoHeader
*)pBlk
;
2698 SLTG_MemberHeader
*pMemHeader
;
2699 SLTG_EnumItem
*pItem
;
2701 TLBVarDesc
**ppVarDesc
= &pTI
->varlist
;
2704 pMemHeader
= (SLTG_MemberHeader
*)(pBlk
+ pTIHeader
->elem_table
);
2706 pFirstItem
= (char*)(pMemHeader
+ 1);
2707 for(pItem
= (SLTG_EnumItem
*)pFirstItem
, num
= 1; 1;
2708 pItem
= (SLTG_EnumItem
*)(pFirstItem
+ pItem
->next
), num
++) {
2709 if(pItem
->magic
!= SLTG_ENUMITEM_MAGIC
) {
2710 FIXME("enumitem magic = %04x\n", pItem
->magic
);
2713 *ppVarDesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2714 sizeof(**ppVarDesc
));
2715 (*ppVarDesc
)->Name
= TLB_MultiByteToBSTR(pItem
->name
+ pNameTable
);
2716 (*ppVarDesc
)->vardesc
.memid
= pItem
->memid
;
2717 (*ppVarDesc
)->vardesc
.u
.lpvarValue
= HeapAlloc(GetProcessHeap(), 0,
2719 V_VT((*ppVarDesc
)->vardesc
.u
.lpvarValue
) = VT_INT
;
2720 V_UNION((*ppVarDesc
)->vardesc
.u
.lpvarValue
, intVal
) =
2721 *(INT
*)(pItem
->value
+ pFirstItem
);
2722 (*ppVarDesc
)->vardesc
.elemdescVar
.tdesc
.vt
= VT_I4
;
2723 (*ppVarDesc
)->vardesc
.varkind
= VAR_CONST
;
2724 /* FIXME("helpcontext, helpstring\n"); */
2726 ppVarDesc
= &((*ppVarDesc
)->next
);
2727 if(pItem
->next
== 0xffff) break;
2729 pTI
->TypeAttr
.cVars
= num
;
2730 return (SLTG_TypeInfoTail
*)(pFirstItem
+ pMemHeader
->cbExtra
);
2733 /* Because SLTG_OtherTypeInfo is such a painfull struct, we make a more
2734 managable copy of it into this */
2747 } SLTG_InternalOtherTypeInfo
;
2749 /****************************************************************************
2750 * ITypeLib2_Constructor_SLTG
2752 * loading a SLTG typelib from an in-memory image
2754 static ITypeLib2
* ITypeLib2_Constructor_SLTG(LPVOID pLib
, DWORD dwTLBLength
)
2756 ITypeLibImpl
*pTypeLibImpl
;
2757 SLTG_Header
*pHeader
;
2758 SLTG_BlkEntry
*pBlkEntry
;
2762 LPVOID pBlk
, pFirstBlk
;
2763 SLTG_LibBlk
*pLibBlk
;
2764 SLTG_InternalOtherTypeInfo
*pOtherTypeInfoBlks
;
2765 char *pAfterOTIBlks
= NULL
;
2766 char *pNameTable
, *ptr
;
2769 ITypeInfoImpl
**ppTypeInfoImpl
;
2771 TRACE("%p, TLB length = %ld\n", pLib
, dwTLBLength
);
2773 pTypeLibImpl
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ITypeLibImpl
));
2774 if (!pTypeLibImpl
) return NULL
;
2776 ICOM_VTBL(pTypeLibImpl
) = &tlbvt
;
2777 pTypeLibImpl
->ref
= 1;
2782 TRACE("\tmagic=0x%08lx, file blocks = %d\n", pHeader
->SLTG_magic
,
2783 pHeader
->nrOfFileBlks
);
2784 if (memcmp(&pHeader
->SLTG_magic
, TLBMAGIC1
, 4)) {
2785 FIXME("Header type magic 0x%08lx not supported.\n",
2786 pHeader
->SLTG_magic
);
2790 /* There are pHeader->nrOfFileBlks - 2 TypeInfo records in this typelib */
2791 pTypeLibImpl
->TypeInfoCount
= pHeader
->nrOfFileBlks
- 2;
2793 /* This points to pHeader->nrOfFileBlks - 1 of SLTG_BlkEntry */
2794 pBlkEntry
= (SLTG_BlkEntry
*)(pHeader
+ 1);
2796 /* Next we have a magic block */
2797 pMagic
= (SLTG_Magic
*)(pBlkEntry
+ pHeader
->nrOfFileBlks
- 1);
2799 /* Let's see if we're still in sync */
2800 if(memcmp(pMagic
->CompObj_magic
, SLTG_COMPOBJ_MAGIC
,
2801 sizeof(SLTG_COMPOBJ_MAGIC
))) {
2802 FIXME("CompObj magic = %s\n", pMagic
->CompObj_magic
);
2805 if(memcmp(pMagic
->dir_magic
, SLTG_DIR_MAGIC
,
2806 sizeof(SLTG_DIR_MAGIC
))) {
2807 FIXME("dir magic = %s\n", pMagic
->dir_magic
);
2811 pIndex
= (SLTG_Index
*)(pMagic
+1);
2813 pPad9
= (SLTG_Pad9
*)(pIndex
+ pTypeLibImpl
->TypeInfoCount
);
2815 pFirstBlk
= (LPVOID
)(pPad9
+ 1);
2817 /* We'll set up a ptr to the main library block, which is the last one. */
2819 for(pBlk
= pFirstBlk
, order
= pHeader
->first_blk
- 1, i
= 0;
2820 pBlkEntry
[order
].next
!= 0;
2821 order
= pBlkEntry
[order
].next
- 1, i
++) {
2822 pBlk
+= pBlkEntry
[order
].len
;
2826 len
= SLTG_ReadLibBlk(pLibBlk
, pTypeLibImpl
);
2828 /* Now there's 0x40 bytes of 0xffff with the numbers 0 to TypeInfoCount
2833 /* And now TypeInfoCount of SLTG_OtherTypeInfo */
2835 pOtherTypeInfoBlks
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2836 sizeof(*pOtherTypeInfoBlks
) *
2837 pTypeLibImpl
->TypeInfoCount
);
2840 ptr
= (char*)pLibBlk
+ len
;
2842 for(i
= 0; i
< pTypeLibImpl
->TypeInfoCount
; i
++) {
2846 pOtherTypeInfoBlks
[i
].small_no
= *(WORD
*)ptr
;
2848 w
= *(WORD
*)(ptr
+ 2);
2851 pOtherTypeInfoBlks
[i
].index_name
= HeapAlloc(GetProcessHeap(),0,
2853 memcpy(pOtherTypeInfoBlks
[i
].index_name
, ptr
+ 4, w
);
2854 pOtherTypeInfoBlks
[i
].index_name
[w
] = '\0';
2856 w
= *(WORD
*)(ptr
+ 4 + len
);
2858 TRACE("\twith %s\n", debugstr_an(ptr
+ 6 + len
, w
));
2860 pOtherTypeInfoBlks
[i
].other_name
= HeapAlloc(GetProcessHeap(),0,
2862 memcpy(pOtherTypeInfoBlks
[i
].other_name
, ptr
+ 6 + len
, w
);
2863 pOtherTypeInfoBlks
[i
].other_name
[w
] = '\0';
2865 pOtherTypeInfoBlks
[i
].res1a
= *(WORD
*)(ptr
+ len
+ 6);
2866 pOtherTypeInfoBlks
[i
].name_offs
= *(WORD
*)(ptr
+ len
+ 8);
2867 extra
= pOtherTypeInfoBlks
[i
].more_bytes
= *(WORD
*)(ptr
+ 10 + len
);
2869 pOtherTypeInfoBlks
[i
].extra
= HeapAlloc(GetProcessHeap(),0,
2871 memcpy(pOtherTypeInfoBlks
[i
].extra
, ptr
+ 12, extra
);
2874 pOtherTypeInfoBlks
[i
].res20
= *(WORD
*)(ptr
+ 12 + len
);
2875 pOtherTypeInfoBlks
[i
].helpcontext
= *(DWORD
*)(ptr
+ 14 + len
);
2876 pOtherTypeInfoBlks
[i
].res26
= *(WORD
*)(ptr
+ 18 + len
);
2877 memcpy(&pOtherTypeInfoBlks
[i
].uuid
, ptr
+ 20 + len
, sizeof(GUID
));
2878 len
+= sizeof(SLTG_OtherTypeInfo
);
2882 pAfterOTIBlks
= ptr
;
2884 /* Skip this WORD and get the next DWORD */
2885 len
= *(DWORD
*)(pAfterOTIBlks
+ 2);
2887 /* Now add this to pLibBLk and then add 0x216, sprinkle a bit a
2888 magic dust and we should be pointing at the beginning of the name
2891 pNameTable
= (char*)pLibBlk
+ len
+ 0x216;
2895 TRACE("Library name is %s\n", pNameTable
+ pLibBlk
->name
);
2897 pTypeLibImpl
->Name
= TLB_MultiByteToBSTR(pNameTable
+ pLibBlk
->name
);
2900 /* Hopefully we now have enough ptrs set up to actually read in
2901 some TypeInfos. It's not clear which order to do them in, so
2902 I'll just follow the links along the BlkEntry chain and read
2903 them in in the order in which they're in the file */
2905 ppTypeInfoImpl
= &(pTypeLibImpl
->pTypeInfo
);
2907 for(pBlk
= pFirstBlk
, order
= pHeader
->first_blk
- 1, i
= 0;
2908 pBlkEntry
[order
].next
!= 0;
2909 order
= pBlkEntry
[order
].next
- 1, i
++) {
2911 SLTG_TypeInfoHeader
*pTIHeader
;
2912 SLTG_TypeInfoTail
*pTITail
;
2914 if(strcmp(pBlkEntry
[order
].index_string
+ (char*)pMagic
,
2915 pOtherTypeInfoBlks
[i
].index_name
)) {
2916 FIXME("Index strings don't match\n");
2921 if(pTIHeader
->magic
!= SLTG_TIHEADER_MAGIC
) {
2922 FIXME("TypeInfoHeader magic = %04x\n", pTIHeader
->magic
);
2925 *ppTypeInfoImpl
= (ITypeInfoImpl
*)ITypeInfo_Constructor();
2926 (*ppTypeInfoImpl
)->pTypeLib
= pTypeLibImpl
;
2927 ITypeLib2_AddRef((ITypeLib2
*)pTypeLibImpl
);
2928 (*ppTypeInfoImpl
)->index
= i
;
2929 (*ppTypeInfoImpl
)->Name
= TLB_MultiByteToBSTR(
2930 pOtherTypeInfoBlks
[i
].name_offs
+
2932 (*ppTypeInfoImpl
)->dwHelpContext
= pOtherTypeInfoBlks
[i
].helpcontext
;
2933 memcpy(&((*ppTypeInfoImpl
)->TypeAttr
.guid
), &pOtherTypeInfoBlks
[i
].uuid
,
2935 (*ppTypeInfoImpl
)->TypeAttr
.typekind
= pTIHeader
->typekind
;
2936 (*ppTypeInfoImpl
)->TypeAttr
.wMajorVerNum
= pTIHeader
->major_version
;
2937 (*ppTypeInfoImpl
)->TypeAttr
.wMinorVerNum
= pTIHeader
->minor_version
;
2938 (*ppTypeInfoImpl
)->TypeAttr
.wTypeFlags
=
2939 (pTIHeader
->typeflags1
>> 3) | (pTIHeader
->typeflags2
<< 5);
2941 if((pTIHeader
->typeflags1
& 7) != 2)
2942 FIXME("typeflags1 = %02x\n", pTIHeader
->typeflags1
);
2943 if(pTIHeader
->typeflags3
!= 2)
2944 FIXME("typeflags3 = %02x\n", pTIHeader
->typeflags3
);
2946 TRACE("TypeInfo %s of kind %s guid %s typeflags %04x\n",
2947 debugstr_w((*ppTypeInfoImpl
)->Name
),
2948 typekind_desc
[pTIHeader
->typekind
],
2949 debugstr_guid(&(*ppTypeInfoImpl
)->TypeAttr
.guid
),
2950 (*ppTypeInfoImpl
)->TypeAttr
.wTypeFlags
);
2952 switch(pTIHeader
->typekind
) {
2954 pTITail
= SLTG_ProcessEnum(pBlk
, *ppTypeInfoImpl
, pNameTable
);
2958 pTITail
= SLTG_ProcessRecord(pBlk
, *ppTypeInfoImpl
, pNameTable
);
2961 case TKIND_INTERFACE
:
2962 pTITail
= SLTG_ProcessInterface(pBlk
, *ppTypeInfoImpl
, pNameTable
);
2966 pTITail
= SLTG_ProcessCoClass(pBlk
, *ppTypeInfoImpl
, pNameTable
);
2970 FIXME("Not processing typekind %d\n", pTIHeader
->typekind
);
2976 if(pTITail
) { /* could get cFuncs, cVars and cImplTypes from here
2977 but we've already set those */
2978 (*ppTypeInfoImpl
)->TypeAttr
.cbAlignment
= pTITail
->cbAlignment
;
2979 (*ppTypeInfoImpl
)->TypeAttr
.cbSizeInstance
= pTITail
->cbSizeInstance
;
2980 (*ppTypeInfoImpl
)->TypeAttr
.cbSizeVft
= pTITail
->cbSizeVft
;
2982 ppTypeInfoImpl
= &((*ppTypeInfoImpl
)->next
);
2983 pBlk
+= pBlkEntry
[order
].len
;
2986 if(i
!= pTypeLibImpl
->TypeInfoCount
) {
2987 FIXME("Somehow processed %d TypeInfos\n", i
);
2991 HeapFree(GetProcessHeap(), 0, pOtherTypeInfoBlks
);
2992 return (ITypeLib2
*)pTypeLibImpl
;
2995 /* ITypeLib::QueryInterface
2997 static HRESULT WINAPI
ITypeLib2_fnQueryInterface(
3002 ICOM_THIS( ITypeLibImpl
, iface
);
3004 TRACE("(%p)->(IID: %s)\n",This
,debugstr_guid(riid
));
3007 if(IsEqualIID(riid
, &IID_IUnknown
) ||
3008 IsEqualIID(riid
,&IID_ITypeLib
)||
3009 IsEqualIID(riid
,&IID_ITypeLib2
))
3016 ITypeLib2_AddRef(iface
);
3017 TRACE("-- Interface: (%p)->(%p)\n",ppvObject
,*ppvObject
);
3020 TRACE("-- Interface: E_NOINTERFACE\n");
3021 return E_NOINTERFACE
;
3026 static ULONG WINAPI
ITypeLib2_fnAddRef( ITypeLib2
*iface
)
3028 ICOM_THIS( ITypeLibImpl
, iface
);
3030 TRACE("(%p)->ref is %u\n",This
, This
->ref
);
3032 return ++(This
->ref
);
3035 /* ITypeLib::Release
3037 static ULONG WINAPI
ITypeLib2_fnRelease( ITypeLib2
*iface
)
3039 ICOM_THIS( ITypeLibImpl
, iface
);
3043 TRACE("(%p)->(%u)\n",This
, This
->ref
);
3047 /* FIXME destroy child objects */
3049 TRACE(" destroying ITypeLib(%p)\n",This
);
3053 SysFreeString(This
->Name
);
3057 if (This
->DocString
)
3059 SysFreeString(This
->DocString
);
3060 This
->DocString
= NULL
;
3065 SysFreeString(This
->HelpFile
);
3066 This
->HelpFile
= NULL
;
3069 if (This
->HelpStringDll
)
3071 SysFreeString(This
->HelpStringDll
);
3072 This
->HelpStringDll
= NULL
;
3075 ITypeInfo_Release((ITypeInfo
*) This
->pTypeInfo
);
3076 HeapFree(GetProcessHeap(),0,This
);
3083 /* ITypeLib::GetTypeInfoCount
3085 * Returns the number of type descriptions in the type library
3087 static UINT WINAPI
ITypeLib2_fnGetTypeInfoCount( ITypeLib2
*iface
)
3089 ICOM_THIS( ITypeLibImpl
, iface
);
3090 TRACE("(%p)->count is %d\n",This
, This
->TypeInfoCount
);
3091 return This
->TypeInfoCount
;
3094 /* ITypeLib::GetTypeInfo
3096 * retrieves the specified type description in the library.
3098 static HRESULT WINAPI
ITypeLib2_fnGetTypeInfo(
3101 ITypeInfo
**ppTInfo
)
3105 ICOM_THIS( ITypeLibImpl
, iface
);
3106 ITypeInfoImpl
*pTypeInfo
= This
->pTypeInfo
;
3108 TRACE("(%p)->(index=%d) \n", This
, index
);
3110 if (!ppTInfo
) return E_INVALIDARG
;
3112 /* search element n in list */
3113 for(i
=0; i
< index
; i
++)
3115 pTypeInfo
= pTypeInfo
->next
;
3118 TRACE("-- element not found\n");
3119 return TYPE_E_ELEMENTNOTFOUND
;
3123 *ppTInfo
= (ITypeInfo
*) pTypeInfo
;
3125 ITypeInfo_AddRef(*ppTInfo
);
3126 TRACE("-- found (%p)\n",*ppTInfo
);
3131 /* ITypeLibs::GetTypeInfoType
3133 * Retrieves the type of a type description.
3135 static HRESULT WINAPI
ITypeLib2_fnGetTypeInfoType(
3140 ICOM_THIS( ITypeLibImpl
, iface
);
3142 ITypeInfoImpl
*pTInfo
= This
->pTypeInfo
;
3144 TRACE("(%p) index %d \n",This
, index
);
3146 if(!pTKind
) return E_INVALIDARG
;
3148 /* search element n in list */
3149 for(i
=0; i
< index
; i
++)
3153 TRACE("-- element not found\n");
3154 return TYPE_E_ELEMENTNOTFOUND
;
3156 pTInfo
= pTInfo
->next
;
3159 *pTKind
= pTInfo
->TypeAttr
.typekind
;
3160 TRACE("-- found Type (%d)\n", *pTKind
);
3164 /* ITypeLib::GetTypeInfoOfGuid
3166 * Retrieves the type description that corresponds to the specified GUID.
3169 static HRESULT WINAPI
ITypeLib2_fnGetTypeInfoOfGuid(
3172 ITypeInfo
**ppTInfo
)
3174 ICOM_THIS( ITypeLibImpl
, iface
);
3175 ITypeInfoImpl
*pTypeInfo
= This
->pTypeInfo
; /* head of list */
3177 TRACE("(%p)\n\tguid:\t%s)\n",This
,debugstr_guid(guid
));
3179 if (!pTypeInfo
) return TYPE_E_ELEMENTNOTFOUND
;
3181 /* search linked list for guid */
3182 while( !IsEqualIID(guid
,&pTypeInfo
->TypeAttr
.guid
) )
3184 pTypeInfo
= pTypeInfo
->next
;
3188 /* end of list reached */
3189 TRACE("-- element not found\n");
3190 return TYPE_E_ELEMENTNOTFOUND
;
3194 TRACE("-- found (%p, %s)\n",
3196 debugstr_w(pTypeInfo
->Name
));
3198 *ppTInfo
= (ITypeInfo
*)pTypeInfo
;
3199 ITypeInfo_AddRef(*ppTInfo
);
3203 /* ITypeLib::GetLibAttr
3205 * Retrieves the structure that contains the library's attributes.
3208 static HRESULT WINAPI
ITypeLib2_fnGetLibAttr(
3210 LPTLIBATTR
*ppTLibAttr
)
3212 ICOM_THIS( ITypeLibImpl
, iface
);
3213 TRACE("(%p)\n",This
);
3214 *ppTLibAttr
= HeapAlloc(GetProcessHeap(), 0, sizeof(**ppTLibAttr
));
3215 memcpy(*ppTLibAttr
, &This
->LibAttr
, sizeof(**ppTLibAttr
));
3219 /* ITypeLib::GetTypeComp
3221 * Enables a client compiler to bind to a library's types, variables,
3222 * constants, and global functions.
3225 static HRESULT WINAPI
ITypeLib2_fnGetTypeComp(
3227 ITypeComp
**ppTComp
)
3229 ICOM_THIS( ITypeLibImpl
, iface
);
3230 FIXME("(%p): stub!\n",This
);
3234 /* ITypeLib::GetDocumentation
3236 * Retrieves the library's documentation string, the complete Help file name
3237 * and path, and the context identifier for the library Help topic in the Help
3240 * On a successful return all non-null BSTR pointers will have been set,
3243 static HRESULT WINAPI
ITypeLib2_fnGetDocumentation(
3247 BSTR
*pBstrDocString
,
3248 DWORD
*pdwHelpContext
,
3249 BSTR
*pBstrHelpFile
)
3251 ICOM_THIS( ITypeLibImpl
, iface
);
3253 HRESULT result
= E_INVALIDARG
;
3258 TRACE("(%p) index %d Name(%p) DocString(%p) HelpContext(%p) HelpFile(%p)\n",
3260 pBstrName
, pBstrDocString
,
3261 pdwHelpContext
, pBstrHelpFile
);
3265 /* documentation for the typelib */
3269 if(!(*pBstrName
= SysAllocString(This
->Name
))) goto memerr1
;else;
3275 if (This
->DocString
)
3276 if(!(*pBstrDocString
= SysAllocString(This
->DocString
))) goto memerr2
;else;
3277 else if (This
->Name
)
3278 if(!(*pBstrDocString
= SysAllocString(This
->Name
))) goto memerr2
;else;
3280 *pBstrDocString
= NULL
;
3284 *pdwHelpContext
= This
->dwHelpContext
;
3289 if(!(*pBstrHelpFile
= SysAllocString(This
->HelpFile
))) goto memerr3
;else;
3291 *pBstrHelpFile
= NULL
;
3298 /* for a typeinfo */
3299 result
= ITypeLib2_fnGetTypeInfo(iface
, index
, &pTInfo
);
3301 if(SUCCEEDED(result
))
3303 result
= ITypeInfo_GetDocumentation(pTInfo
,
3307 pdwHelpContext
, pBstrHelpFile
);
3309 ITypeInfo_Release(pTInfo
);
3314 if (pBstrDocString
) SysFreeString (*pBstrDocString
);
3316 if (pBstrName
) SysFreeString (*pBstrName
);
3318 return STG_E_INSUFFICIENTMEMORY
;
3323 * Indicates whether a passed-in string contains the name of a type or member
3324 * described in the library.
3327 static HRESULT WINAPI
ITypeLib2_fnIsName(
3333 ICOM_THIS( ITypeLibImpl
, iface
);
3334 ITypeInfoImpl
*pTInfo
;
3335 TLBFuncDesc
*pFInfo
;
3338 UINT nNameBufLen
= SysStringLen(szNameBuf
);
3340 TRACE("(%p)->(%s,%08lx,%p)\n", This
, debugstr_w(szNameBuf
), lHashVal
,
3344 for(pTInfo
=This
->pTypeInfo
;pTInfo
;pTInfo
=pTInfo
->next
){
3345 if(!memcmp(szNameBuf
,pTInfo
->Name
, nNameBufLen
)) goto ITypeLib2_fnIsName_exit
;
3346 for(pFInfo
=pTInfo
->funclist
;pFInfo
;pFInfo
=pFInfo
->next
) {
3347 if(!memcmp(szNameBuf
,pFInfo
->Name
, nNameBufLen
)) goto ITypeLib2_fnIsName_exit
;
3348 for(i
=0;i
<pFInfo
->funcdesc
.cParams
;i
++)
3349 if(!memcmp(szNameBuf
,pFInfo
->pParamDesc
[i
].Name
, nNameBufLen
))
3350 goto ITypeLib2_fnIsName_exit
;
3352 for(pVInfo
=pTInfo
->varlist
;pVInfo
;pVInfo
=pVInfo
->next
)
3353 if(!memcmp(szNameBuf
,pVInfo
->Name
, nNameBufLen
)) goto ITypeLib2_fnIsName_exit
;
3358 ITypeLib2_fnIsName_exit
:
3359 TRACE("(%p)slow! search for %s: %s found!\n", This
,
3360 debugstr_w(szNameBuf
), *pfName
?"NOT":"");
3365 /* ITypeLib::FindName
3367 * Finds occurrences of a type description in a type library. This may be used
3368 * to quickly verify that a name exists in a type library.
3371 static HRESULT WINAPI
ITypeLib2_fnFindName(
3375 ITypeInfo
**ppTInfo
,
3379 ICOM_THIS( ITypeLibImpl
, iface
);
3380 ITypeInfoImpl
*pTInfo
;
3381 TLBFuncDesc
*pFInfo
;
3385 UINT nNameBufLen
= SysStringLen(szNameBuf
);
3387 for(pTInfo
=This
->pTypeInfo
;pTInfo
&& j
<*pcFound
; pTInfo
=pTInfo
->next
){
3388 if(!memcmp(szNameBuf
,pTInfo
->Name
, nNameBufLen
)) goto ITypeLib2_fnFindName_exit
;
3389 for(pFInfo
=pTInfo
->funclist
;pFInfo
;pFInfo
=pFInfo
->next
) {
3390 if(!memcmp(szNameBuf
,pFInfo
->Name
,nNameBufLen
)) goto ITypeLib2_fnFindName_exit
;
3391 for(i
=0;i
<pFInfo
->funcdesc
.cParams
;i
++)
3392 if(!memcmp(szNameBuf
,pFInfo
->pParamDesc
[i
].Name
,nNameBufLen
))
3393 goto ITypeLib2_fnFindName_exit
;
3395 for(pVInfo
=pTInfo
->varlist
;pVInfo
;pVInfo
=pVInfo
->next
)
3396 if(!memcmp(szNameBuf
,pVInfo
->Name
, nNameBufLen
)) goto ITypeLib2_fnFindName_exit
;
3398 ITypeLib2_fnFindName_exit
:
3399 ITypeInfo_AddRef((ITypeInfo
*)pTInfo
);
3400 ppTInfo
[j
]=(LPTYPEINFO
)pTInfo
;
3403 TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
3404 This
, *pcFound
, debugstr_w(szNameBuf
), j
);
3411 /* ITypeLib::ReleaseTLibAttr
3413 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
3416 static VOID WINAPI
ITypeLib2_fnReleaseTLibAttr(
3418 TLIBATTR
*pTLibAttr
)
3420 ICOM_THIS( ITypeLibImpl
, iface
);
3421 TRACE("freeing (%p)\n",This
);
3422 HeapFree(GetProcessHeap(),0,pTLibAttr
);
3426 /* ITypeLib2::GetCustData
3428 * gets the custom data
3430 static HRESULT WINAPI
ITypeLib2_fnGetCustData(
3435 ICOM_THIS( ITypeLibImpl
, iface
);
3436 TLBCustData
*pCData
;
3438 for(pCData
=This
->pCustData
; pCData
; pCData
= pCData
->next
)
3440 if( IsEqualIID(guid
, &pCData
->guid
)) break;
3443 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
3447 VariantInit( pVarVal
);
3448 VariantCopy( pVarVal
, &pCData
->data
);
3451 return E_INVALIDARG
; /* FIXME: correct? */
3454 /* ITypeLib2::GetLibStatistics
3456 * Returns statistics about a type library that are required for efficient
3457 * sizing of hash tables.
3460 static HRESULT WINAPI
ITypeLib2_fnGetLibStatistics(
3462 ULONG
*pcUniqueNames
,
3463 ULONG
*pcchUniqueNames
)
3465 ICOM_THIS( ITypeLibImpl
, iface
);
3467 FIXME("(%p): stub!\n", This
);
3469 if(pcUniqueNames
) *pcUniqueNames
=1;
3470 if(pcchUniqueNames
) *pcchUniqueNames
=1;
3474 /* ITypeLib2::GetDocumentation2
3476 * Retrieves the library's documentation string, the complete Help file name
3477 * and path, the localization context to use, and the context ID for the
3478 * library Help topic in the Help file.
3481 static HRESULT WINAPI
ITypeLib2_fnGetDocumentation2(
3485 BSTR
*pbstrHelpString
,
3486 DWORD
*pdwHelpStringContext
,
3487 BSTR
*pbstrHelpStringDll
)
3489 ICOM_THIS( ITypeLibImpl
, iface
);
3493 FIXME("(%p) index %d lcid %ld half implemented stub!\n", This
, index
, lcid
);
3495 /* the help string should be obtained from the helpstringdll,
3496 * using the _DLLGetDocumentation function, based on the supplied
3497 * lcid. Nice to do sometime...
3501 /* documentation for the typelib */
3503 *pbstrHelpString
=SysAllocString(This
->DocString
);
3504 if(pdwHelpStringContext
)
3505 *pdwHelpStringContext
=This
->dwHelpContext
;
3506 if(pbstrHelpStringDll
)
3507 *pbstrHelpStringDll
=SysAllocString(This
->HelpStringDll
);
3513 /* for a typeinfo */
3514 result
=ITypeLib2_GetTypeInfo(iface
, index
, &pTInfo
);
3516 if(SUCCEEDED(result
))
3518 ITypeInfo2
* pTInfo2
;
3519 result
= ITypeInfo_QueryInterface(pTInfo
,
3521 (LPVOID
*) &pTInfo2
);
3523 if(SUCCEEDED(result
))
3525 result
= ITypeInfo2_GetDocumentation2(pTInfo2
,
3529 pdwHelpStringContext
,
3530 pbstrHelpStringDll
);
3532 ITypeInfo2_Release(pTInfo2
);
3535 ITypeInfo_Release(pTInfo
);
3541 /* ITypeLib2::GetAllCustData
3543 * Gets all custom data items for the library.
3546 static HRESULT WINAPI
ITypeLib2_fnGetAllCustData(
3548 CUSTDATA
*pCustData
)
3550 ICOM_THIS( ITypeLibImpl
, iface
);
3551 TLBCustData
*pCData
;
3553 TRACE("(%p) returning %d items\n", This
, This
->ctCustData
);
3554 pCustData
->prgCustData
= TLB_Alloc(This
->ctCustData
* sizeof(CUSTDATAITEM
));
3555 if(pCustData
->prgCustData
){
3556 pCustData
->cCustData
=This
->ctCustData
;
3557 for(i
=0, pCData
=This
->pCustData
; pCData
; i
++, pCData
= pCData
->next
){
3558 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
3559 VariantCopy(& pCustData
->prgCustData
[i
].varValue
, & pCData
->data
);
3562 ERR(" OUT OF MEMORY! \n");
3563 return E_OUTOFMEMORY
;
3568 static ICOM_VTABLE(ITypeLib2
) tlbvt
= {
3569 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3570 ITypeLib2_fnQueryInterface
,
3572 ITypeLib2_fnRelease
,
3573 ITypeLib2_fnGetTypeInfoCount
,
3574 ITypeLib2_fnGetTypeInfo
,
3575 ITypeLib2_fnGetTypeInfoType
,
3576 ITypeLib2_fnGetTypeInfoOfGuid
,
3577 ITypeLib2_fnGetLibAttr
,
3578 ITypeLib2_fnGetTypeComp
,
3579 ITypeLib2_fnGetDocumentation
,
3581 ITypeLib2_fnFindName
,
3582 ITypeLib2_fnReleaseTLibAttr
,
3584 ITypeLib2_fnGetCustData
,
3585 ITypeLib2_fnGetLibStatistics
,
3586 ITypeLib2_fnGetDocumentation2
,
3587 ITypeLib2_fnGetAllCustData
3590 /*================== ITypeInfo(2) Methods ===================================*/
3591 static ITypeInfo2
* WINAPI
ITypeInfo_Constructor(void)
3593 ITypeInfoImpl
* pTypeInfoImpl
;
3595 pTypeInfoImpl
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ITypeInfoImpl
));
3598 ICOM_VTBL(pTypeInfoImpl
) = &tinfvt
;
3599 pTypeInfoImpl
->ref
=1;
3601 TRACE("(%p)\n", pTypeInfoImpl
);
3602 return (ITypeInfo2
*) pTypeInfoImpl
;
3605 /* ITypeInfo::QueryInterface
3607 static HRESULT WINAPI
ITypeInfo_fnQueryInterface(
3612 ICOM_THIS( ITypeLibImpl
, iface
);
3614 TRACE("(%p)->(IID: %s)\n",This
,debugstr_guid(riid
));
3617 if(IsEqualIID(riid
, &IID_IUnknown
) ||
3618 IsEqualIID(riid
,&IID_ITypeInfo
)||
3619 IsEqualIID(riid
,&IID_ITypeInfo2
))
3623 ITypeInfo_AddRef(iface
);
3624 TRACE("-- Interface: (%p)->(%p)\n",ppvObject
,*ppvObject
);
3627 TRACE("-- Interface: E_NOINTERFACE\n");
3628 return E_NOINTERFACE
;
3631 /* ITypeInfo::AddRef
3633 static ULONG WINAPI
ITypeInfo_fnAddRef( ITypeInfo2
*iface
)
3635 ICOM_THIS( ITypeInfoImpl
, iface
);
3639 TRACE("(%p)->ref is %u\n",This
, This
->ref
);
3643 /* ITypeInfo::Release
3645 static ULONG WINAPI
ITypeInfo_fnRelease( ITypeInfo2
*iface
)
3647 ICOM_THIS( ITypeInfoImpl
, iface
);
3651 TRACE("(%p)->(%u)\n",This
, This
->ref
);
3655 FIXME("destroy child objects\n");
3657 TRACE("destroying ITypeInfo(%p)\n",This
);
3660 SysFreeString(This
->Name
);
3664 if (This
->DocString
)
3666 SysFreeString(This
->DocString
);
3667 This
->DocString
= 0;
3672 ITypeInfo_Release((ITypeInfo
*)This
->next
);
3675 HeapFree(GetProcessHeap(),0,This
);
3681 /* ITypeInfo::GetTypeAttr
3683 * Retrieves a TYPEATTR structure that contains the attributes of the type
3687 static HRESULT WINAPI
ITypeInfo_fnGetTypeAttr( ITypeInfo2
*iface
,
3688 LPTYPEATTR
*ppTypeAttr
)
3690 ICOM_THIS( ITypeInfoImpl
, iface
);
3691 TRACE("(%p)\n",This
);
3692 /* FIXME: must do a copy here */
3693 *ppTypeAttr
=&This
->TypeAttr
;
3697 /* ITypeInfo::GetTypeComp
3699 * Retrieves the ITypeComp interface for the type description, which enables a
3700 * client compiler to bind to the type description's members.
3703 static HRESULT WINAPI
ITypeInfo_fnGetTypeComp( ITypeInfo2
*iface
,
3704 ITypeComp
* *ppTComp
)
3706 ICOM_THIS( ITypeInfoImpl
, iface
);
3707 FIXME("(%p) stub!\n", This
);
3711 /* ITypeInfo::GetFuncDesc
3713 * Retrieves the FUNCDESC structure that contains information about a
3714 * specified function.
3717 static HRESULT WINAPI
ITypeInfo_fnGetFuncDesc( ITypeInfo2
*iface
, UINT index
,
3718 LPFUNCDESC
*ppFuncDesc
)
3720 ICOM_THIS( ITypeInfoImpl
, iface
);
3722 TLBFuncDesc
* pFDesc
;
3723 TRACE("(%p) index %d\n", This
, index
);
3724 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++, pFDesc
=pFDesc
->next
)
3727 /* FIXME: must do a copy here */
3728 *ppFuncDesc
=&pFDesc
->funcdesc
;
3731 return E_INVALIDARG
;
3734 /* ITypeInfo::GetVarDesc
3736 * Retrieves a VARDESC structure that describes the specified variable.
3739 static HRESULT WINAPI
ITypeInfo_fnGetVarDesc( ITypeInfo2
*iface
, UINT index
,
3740 LPVARDESC
*ppVarDesc
)
3742 ICOM_THIS( ITypeInfoImpl
, iface
);
3744 TLBVarDesc
* pVDesc
;
3745 TRACE("(%p) index %d\n", This
, index
);
3746 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++, pVDesc
=pVDesc
->next
)
3749 /* FIXME: must do a copy here */
3750 *ppVarDesc
=&pVDesc
->vardesc
;
3753 return E_INVALIDARG
;
3756 /* ITypeInfo_GetNames
3758 * Retrieves the variable with the specified member ID (or the name of the
3759 * property or method and its parameters) that correspond to the specified
3762 static HRESULT WINAPI
ITypeInfo_fnGetNames( ITypeInfo2
*iface
, MEMBERID memid
,
3763 BSTR
*rgBstrNames
, UINT cMaxNames
, UINT
*pcNames
)
3765 ICOM_THIS( ITypeInfoImpl
, iface
);
3766 TLBFuncDesc
* pFDesc
;
3767 TLBVarDesc
* pVDesc
;
3769 TRACE("(%p) memid=0x%08lx Maxname=%d\n", This
, memid
, cMaxNames
);
3770 for(pFDesc
=This
->funclist
; pFDesc
&& pFDesc
->funcdesc
.memid
!= memid
; pFDesc
=pFDesc
->next
);
3773 /* function found, now return function and parameter names */
3774 for(i
=0; i
<cMaxNames
&& i
<= pFDesc
->funcdesc
.cParams
; i
++)
3777 *rgBstrNames
=SysAllocString(pFDesc
->Name
);
3779 rgBstrNames
[i
]=SysAllocString(pFDesc
->pParamDesc
[i
-1].Name
);
3785 for(pVDesc
=This
->varlist
; pVDesc
&& pVDesc
->vardesc
.memid
!= memid
; pVDesc
=pVDesc
->next
);
3788 *rgBstrNames
=SysAllocString(pVDesc
->Name
);
3793 if(This
->TypeAttr
.typekind
==TKIND_INTERFACE
&& This
->TypeAttr
.cImplTypes
)
3795 /* recursive search */
3798 result
=ITypeInfo_GetRefTypeInfo(iface
, This
->impltypelist
->hRef
,
3800 if(SUCCEEDED(result
))
3802 result
=ITypeInfo_GetNames(pTInfo
, memid
, rgBstrNames
, cMaxNames
, pcNames
);
3803 ITypeInfo_Release(pTInfo
);
3806 WARN("Could not search inherited interface!\n");
3810 WARN("no names found\n");
3813 return TYPE_E_ELEMENTNOTFOUND
;
3820 /* ITypeInfo::GetRefTypeOfImplType
3822 * If a type description describes a COM class, it retrieves the type
3823 * description of the implemented interface types. For an interface,
3824 * GetRefTypeOfImplType returns the type information for inherited interfaces,
3828 static HRESULT WINAPI
ITypeInfo_fnGetRefTypeOfImplType(
3833 ICOM_THIS( ITypeInfoImpl
, iface
);
3835 TLBImplType
*pImpl
= This
->impltypelist
;
3837 TRACE("(%p) index %d\n", This
, index
);
3838 dump_TypeInfo(This
);
3842 /* only valid on dual interfaces;
3843 retrieve the associated TKIND_INTERFACE handle for the current TKIND_DISPATCH
3845 if( This
->TypeAttr
.typekind
!= TKIND_DISPATCH
) return E_INVALIDARG
;
3847 if (This
->TypeAttr
.wTypeFlags
& TYPEFLAG_FDISPATCHABLE
&&
3848 This
->TypeAttr
.wTypeFlags
& TYPEFLAG_FDUAL
)
3854 if (!pImpl
) return TYPE_E_ELEMENTNOTFOUND
;
3855 *pRefType
= pImpl
->hRef
;
3860 /* get element n from linked list */
3861 for(i
=0; pImpl
&& i
<index
; i
++)
3863 pImpl
= pImpl
->next
;
3866 if (!pImpl
) return TYPE_E_ELEMENTNOTFOUND
;
3868 *pRefType
= pImpl
->hRef
;
3870 TRACE("-- 0x%08lx\n", pImpl
->hRef
);
3877 /* ITypeInfo::GetImplTypeFlags
3879 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
3880 * or base interface in a type description.
3882 static HRESULT WINAPI
ITypeInfo_fnGetImplTypeFlags( ITypeInfo2
*iface
,
3883 UINT index
, INT
*pImplTypeFlags
)
3885 ICOM_THIS( ITypeInfoImpl
, iface
);
3889 TRACE("(%p) index %d\n", This
, index
);
3890 for(i
=0, pImpl
=This
->impltypelist
; i
<index
&& pImpl
;
3891 i
++, pImpl
=pImpl
->next
)
3893 if(i
==index
&& pImpl
){
3894 *pImplTypeFlags
=pImpl
->implflags
;
3898 return TYPE_E_ELEMENTNOTFOUND
;
3902 * Maps between member names and member IDs, and parameter names and
3905 static HRESULT WINAPI
ITypeInfo_fnGetIDsOfNames( ITypeInfo2
*iface
,
3906 LPOLESTR
*rgszNames
, UINT cNames
, MEMBERID
*pMemId
)
3908 ICOM_THIS( ITypeInfoImpl
, iface
);
3909 TLBFuncDesc
* pFDesc
;
3910 TLBVarDesc
* pVDesc
;
3913 TRACE("(%p) Name %s cNames %d\n", This
, debugstr_w(*rgszNames
),
3915 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
) {
3917 if(!lstrcmpiW(*rgszNames
, pFDesc
->Name
)) {
3918 if(cNames
) *pMemId
=pFDesc
->funcdesc
.memid
;
3919 for(i
=1; i
< cNames
; i
++){
3920 for(j
=0; j
<pFDesc
->funcdesc
.cParams
; j
++)
3921 if(!lstrcmpiW(rgszNames
[i
],pFDesc
->pParamDesc
[j
].Name
))
3923 if( j
<pFDesc
->funcdesc
.cParams
)
3926 ret
=DISP_E_UNKNOWNNAME
;
3931 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
) {
3932 if(!lstrcmpiW(*rgszNames
, pVDesc
->Name
)) {
3933 if(cNames
) *pMemId
=pVDesc
->vardesc
.memid
;
3937 /* not found, see if this is and interface with an inheritance */
3938 if(This
->TypeAttr
.typekind
==TKIND_INTERFACE
&&
3939 This
->TypeAttr
.cImplTypes
){
3940 /* recursive search */
3942 ret
=ITypeInfo_GetRefTypeInfo(iface
,
3943 This
->impltypelist
->hRef
, &pTInfo
);
3945 ret
=ITypeInfo_GetIDsOfNames(pTInfo
, rgszNames
, cNames
, pMemId
);
3946 ITypeInfo_Release(pTInfo
);
3949 WARN("Could not search inherited interface!\n");
3951 WARN("no names found\n");
3952 return DISP_E_UNKNOWNNAME
;
3955 /* ITypeInfo::Invoke
3957 * Invokes a method, or accesses a property of an object, that implements the
3958 * interface described by the type description.
3961 _invoke(LPVOID func
,CALLCONV callconv
, int nrargs
, DWORD
*args
) {
3964 if (TRACE_ON(ole
)) {
3966 MESSAGE("Calling %p(",func
);
3967 for (i
=0;i
<nrargs
;i
++) MESSAGE("%08lx,",args
[i
]);
3976 DWORD (WINAPI
*xfunc
)() = func
;
3981 DWORD (WINAPI
*xfunc
)(DWORD
) = func
;
3982 res
= xfunc(args
[0]);
3986 DWORD (WINAPI
*xfunc
)(DWORD
,DWORD
) = func
;
3987 res
= xfunc(args
[0],args
[1]);
3991 DWORD (WINAPI
*xfunc
)(DWORD
,DWORD
,DWORD
) = func
;
3992 res
= xfunc(args
[0],args
[1],args
[2]);
3996 DWORD (WINAPI
*xfunc
)(DWORD
,DWORD
,DWORD
,DWORD
) = func
;
3997 res
= xfunc(args
[0],args
[1],args
[2],args
[3]);
4001 DWORD (WINAPI
*xfunc
)(DWORD
,DWORD
,DWORD
,DWORD
,DWORD
) = func
;
4002 res
= xfunc(args
[0],args
[1],args
[2],args
[3],args
[4]);
4006 DWORD (WINAPI
*xfunc
)(DWORD
,DWORD
,DWORD
,DWORD
,DWORD
,DWORD
) = func
;
4007 res
= xfunc(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5]);
4011 DWORD (WINAPI
*xfunc
)(DWORD
,DWORD
,DWORD
,DWORD
,DWORD
,DWORD
,DWORD
) = func
;
4012 res
= xfunc(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],args
[6]);
4016 FIXME("unsupported number of arguments %d in stdcall\n",nrargs
);
4022 FIXME("unsupported calling convention %d\n",callconv
);
4026 TRACE("returns %08lx\n",res
);
4030 static HRESULT WINAPI
ITypeInfo_fnInvoke(
4035 DISPPARAMS
*pDispParams
,
4036 VARIANT
*pVarResult
,
4037 EXCEPINFO
*pExcepInfo
,
4040 ICOM_THIS( ITypeInfoImpl
, iface
);
4041 TLBFuncDesc
* pFDesc
;
4042 TLBVarDesc
* pVDesc
;
4045 TRACE("(%p)(%p,id=%ld,flags=0x%08x,%p,%p,%p,%p) partial stub!\n",
4046 This
,pIUnk
,memid
,dwFlags
,pDispParams
,pVarResult
,pExcepInfo
,pArgErr
4048 dump_DispParms(pDispParams
);
4050 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
)
4051 if (pFDesc
->funcdesc
.memid
== memid
) {
4052 if (pFDesc
->funcdesc
.invkind
& dwFlags
)
4056 dump_TLBFuncDescOne(pFDesc
);
4057 switch (pFDesc
->funcdesc
.funckind
) {
4058 case FUNC_PUREVIRTUAL
:
4059 case FUNC_VIRTUAL
: {
4061 DWORD
*args
= (DWORD
*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD
)*(pFDesc
->funcdesc
.cParams
+1));
4062 DWORD
*args2
= (DWORD
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(DWORD
)*(pFDesc
->funcdesc
.cParams
));
4063 args
[0] = (DWORD
)pIUnk
;
4065 for (i
=0;i
<pFDesc
->funcdesc
.cParams
;i
++) {
4066 if (i
<pDispParams
->cArgs
) {
4067 TRACE("set %d to disparg type %d vs %d\n",i
,
4068 V_VT(&pDispParams
->rgvarg
[pDispParams
->cArgs
-i
-1]),
4069 pFDesc
->funcdesc
.lprgelemdescParam
[i
].tdesc
.vt
4071 args
[i
+1] = V_UNION(&pDispParams
->rgvarg
[pDispParams
->cArgs
-i
-1],lVal
);
4073 TYPEDESC
*tdesc
= &(pFDesc
->funcdesc
.lprgelemdescParam
[i
].tdesc
);
4074 TRACE("set %d to pointer for get (type is %d)\n",i
,tdesc
->vt
);
4075 /*FIXME: give pointers for the rest, so propertyget works*/
4076 args
[i
+1] = (DWORD
)&args2
[i
];
4078 /* If pointer to variant, pass reference to variant
4079 * in result variant array.
4081 if ((tdesc
->vt
== VT_PTR
) &&
4082 (tdesc
->u
.lptdesc
->vt
== VT_VARIANT
) &&
4085 args
[i
+1] = (DWORD
)(pVarResult
+(i
-pDispParams
->cArgs
));
4088 if (pFDesc
->funcdesc
.cParamsOpt
)
4089 FIXME("Does not support optional parameters (%d)\n",
4090 pFDesc
->funcdesc
.cParamsOpt
4093 res
= _invoke((*(DWORD
***)pIUnk
)[pFDesc
->funcdesc
.oVft
/4],
4094 pFDesc
->funcdesc
.callconv
,
4095 pFDesc
->funcdesc
.cParams
+1,
4098 if (pVarResult
&& (dwFlags
& (DISPATCH_PROPERTYGET
))) {
4099 for (i
=0;i
<pFDesc
->funcdesc
.cParams
-pDispParams
->cArgs
;i
++) {
4100 TYPEDESC
*tdesc
= &(pFDesc
->funcdesc
.lprgelemdescParam
[i
+pDispParams
->cArgs
].tdesc
);
4101 /* If we are a pointer to a variant, we are done already */
4102 if ((tdesc
->vt
==VT_PTR
)&&(tdesc
->u
.lptdesc
->vt
==VT_VARIANT
))
4105 VariantInit(&pVarResult
[i
]);
4106 V_UNION(pVarResult
+i
,intVal
) = args2
[i
+pDispParams
->cArgs
];
4108 if (tdesc
->vt
== VT_PTR
)
4109 tdesc
= tdesc
->u
.lptdesc
;
4110 V_VT(pVarResult
+i
) = tdesc
->vt
;
4112 /* HACK: VB5 likes this.
4113 * I do not know why. There is 1 example in MSDN which uses
4114 * this which appears broken (mixes int vals and
4117 if ((tdesc
->vt
== VT_PTR
) && (dwFlags
& DISPATCH_METHOD
))
4118 V_VT(pVarResult
+i
) = VT_DISPATCH
;
4119 TRACE("storing into variant: [%d]\n", i
);
4120 dump_Variant(pVarResult
+i
);
4123 HeapFree(GetProcessHeap(),0,args2
);
4124 HeapFree(GetProcessHeap(),0,args
);
4127 case FUNC_DISPATCH
: {
4131 hr
= IUnknown_QueryInterface((LPUNKNOWN
)pIUnk
,&IID_IDispatch
,(LPVOID
*)&disp
);
4133 FIXME("FUNC_DISPATCH used on object without IDispatch iface?\n");
4136 FIXME("Calling Invoke in IDispatch iface. untested!\n");
4137 hr
= IDispatch_Invoke(
4138 disp
,memid
,&IID_NULL
,LOCALE_USER_DEFAULT
,dwFlags
,pDispParams
,
4139 pVarResult
,pExcepInfo
,pArgErr
4142 FIXME("IDispatch::Invoke failed with %08lx. (Could be not a real error?)\n",hr
);
4143 IDispatch_Release(disp
);
4147 FIXME("Unknown function invocation type %d\n",pFDesc
->funcdesc
.funckind
);
4151 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
) {
4152 if (pVDesc
->vardesc
.memid
== memid
) {
4153 FIXME("varseek: Found memid name %s, but variable-based invoking not supported\n",debugstr_w(((LPWSTR
)pVDesc
->Name
)));
4154 dump_TLBVarDesc(pVDesc
);
4159 /* not found, look for it in inherited interfaces */
4160 if (This
->TypeAttr
.typekind
==TKIND_INTERFACE
&& This
->TypeAttr
.cImplTypes
) {
4161 /* recursive search */
4164 hr
=ITypeInfo_GetRefTypeInfo(iface
, This
->impltypelist
->hRef
, &pTInfo
);
4166 hr
=ITypeInfo_Invoke(pTInfo
,pIUnk
,memid
,dwFlags
,pDispParams
,pVarResult
,pExcepInfo
,pArgErr
);
4167 ITypeInfo_Release(pTInfo
);
4170 WARN("Could not search inherited interface!\n");
4172 ERR("did not find member id %d, flags %d!\n", (int)memid
, dwFlags
);
4173 return DISP_E_MEMBERNOTFOUND
;
4176 /* ITypeInfo::GetDocumentation
4178 * Retrieves the documentation string, the complete Help file name and path,
4179 * and the context ID for the Help topic for a specified type description.
4181 static HRESULT WINAPI
ITypeInfo_fnGetDocumentation( ITypeInfo2
*iface
,
4182 MEMBERID memid
, BSTR
*pBstrName
, BSTR
*pBstrDocString
,
4183 DWORD
*pdwHelpContext
, BSTR
*pBstrHelpFile
)
4185 ICOM_THIS( ITypeInfoImpl
, iface
);
4186 TLBFuncDesc
* pFDesc
;
4187 TLBVarDesc
* pVDesc
;
4188 TRACE("(%p) memid %ld Name(%p) DocString(%p)"
4189 " HelpContext(%p) HelpFile(%p)\n",
4190 This
, memid
, pBstrName
, pBstrDocString
, pdwHelpContext
, pBstrHelpFile
);
4191 if(memid
==MEMBERID_NIL
){ /* documentation for the typeinfo */
4193 *pBstrName
=SysAllocString(This
->Name
);
4195 *pBstrDocString
=SysAllocString(This
->DocString
);
4197 *pdwHelpContext
=This
->dwHelpContext
;
4199 *pBstrHelpFile
=SysAllocString(This
->DocString
);/* FIXME */
4201 }else {/* for a member */
4202 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
)
4203 if(pFDesc
->funcdesc
.memid
==memid
){
4205 *pBstrName
= SysAllocString(pFDesc
->Name
);
4207 *pBstrDocString
=SysAllocString(pFDesc
->HelpString
);
4209 *pdwHelpContext
=pFDesc
->helpcontext
;
4212 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
)
4213 if(pVDesc
->vardesc
.memid
==memid
){
4214 FIXME("Not implemented\n");
4218 return TYPE_E_ELEMENTNOTFOUND
;
4221 /* ITypeInfo::GetDllEntry
4223 * Retrieves a description or specification of an entry point for a function
4226 static HRESULT WINAPI
ITypeInfo_fnGetDllEntry( ITypeInfo2
*iface
, MEMBERID memid
,
4227 INVOKEKIND invKind
, BSTR
*pBstrDllName
, BSTR
*pBstrName
,
4230 ICOM_THIS( ITypeInfoImpl
, iface
);
4231 FIXME("(%p) stub!\n", This
);
4235 /* ITypeInfo::GetRefTypeInfo
4237 * If a type description references other type descriptions, it retrieves
4238 * the referenced type descriptions.
4240 static HRESULT WINAPI
ITypeInfo_fnGetRefTypeInfo(
4243 ITypeInfo
**ppTInfo
)
4245 ICOM_THIS( ITypeInfoImpl
, iface
);
4246 HRESULT result
= E_FAIL
;
4249 if (hRefType
== -1 &&
4250 (((ITypeInfoImpl
*) This
)->TypeAttr
.typekind
== TKIND_DISPATCH
) &&
4251 (((ITypeInfoImpl
*) This
)->TypeAttr
.wTypeFlags
& TYPEFLAG_FDUAL
))
4253 /* when we meet a DUAL dispinterface, we must create the interface
4256 ITypeInfoImpl
* pTypeInfoImpl
= (ITypeInfoImpl
*) ITypeInfo_Constructor();
4259 /* the interface version contains the same information as the dispinterface
4260 * copy the contents of the structs.
4262 *pTypeInfoImpl
= *This
;
4263 pTypeInfoImpl
->ref
= 1;
4265 /* change the type to interface */
4266 pTypeInfoImpl
->TypeAttr
.typekind
= TKIND_INTERFACE
;
4268 *ppTInfo
= (ITypeInfo
*) pTypeInfoImpl
;
4270 ITypeInfo_AddRef((ITypeInfo
*) pTypeInfoImpl
);
4275 TLBRefType
*pRefType
;
4276 for(pRefType
= This
->reflist
; pRefType
; pRefType
= pRefType
->next
) {
4277 if(pRefType
->reference
== hRefType
)
4281 FIXME("Can't find pRefType for ref %lx\n", hRefType
);
4282 if(pRefType
&& hRefType
!= -1) {
4283 ITypeLib
*pTLib
= NULL
;
4285 if(pRefType
->pImpTLInfo
== TLB_REF_INTERNAL
) {
4287 result
= ITypeInfo_GetContainingTypeLib(iface
, &pTLib
, &Index
);
4289 if(pRefType
->pImpTLInfo
->pImpTypeLib
) {
4290 TRACE("typeinfo in imported typelib that is already loaded\n");
4291 pTLib
= (ITypeLib
*)pRefType
->pImpTLInfo
->pImpTypeLib
;
4292 ITypeLib2_AddRef((ITypeLib
*) pTLib
);
4295 TRACE("typeinfo in imported typelib that isn't already loaded\n");
4296 result
= LoadRegTypeLib( &pRefType
->pImpTLInfo
->guid
,
4297 pRefType
->pImpTLInfo
->wVersionMajor
,
4298 pRefType
->pImpTLInfo
->wVersionMinor
,
4299 pRefType
->pImpTLInfo
->lcid
,
4302 if(!SUCCEEDED(result
)) {
4303 BSTR libnam
=SysAllocString(pRefType
->pImpTLInfo
->name
);
4304 result
=LoadTypeLib(libnam
, &pTLib
);
4305 SysFreeString(libnam
);
4307 if(SUCCEEDED(result
)) {
4308 pRefType
->pImpTLInfo
->pImpTypeLib
= (ITypeLibImpl
*)pTLib
;
4309 ITypeLib2_AddRef(pTLib
);
4313 if(SUCCEEDED(result
)) {
4314 if(pRefType
->index
== TLB_REF_USE_GUID
)
4315 result
= ITypeLib2_GetTypeInfoOfGuid(pTLib
,
4319 result
= ITypeLib2_GetTypeInfo(pTLib
, pRefType
->index
,
4323 ITypeLib2_Release(pTLib
);
4327 TRACE("(%p) hreftype 0x%04lx loaded %s (%p)\n", This
, hRefType
,
4328 SUCCEEDED(result
)? "SUCCESS":"FAILURE", *ppTInfo
);
4332 /* ITypeInfo::AddressOfMember
4334 * Retrieves the addresses of static functions or variables, such as those
4337 static HRESULT WINAPI
ITypeInfo_fnAddressOfMember( ITypeInfo2
*iface
,
4338 MEMBERID memid
, INVOKEKIND invKind
, PVOID
*ppv
)
4340 ICOM_THIS( ITypeInfoImpl
, iface
);
4341 FIXME("(%p) stub!\n", This
);
4345 /* ITypeInfo::CreateInstance
4347 * Creates a new instance of a type that describes a component object class
4350 static HRESULT WINAPI
ITypeInfo_fnCreateInstance( ITypeInfo2
*iface
,
4351 IUnknown
*pUnk
, REFIID riid
, VOID
**ppvObj
)
4353 ICOM_THIS( ITypeInfoImpl
, iface
);
4354 FIXME("(%p) stub!\n", This
);
4358 /* ITypeInfo::GetMops
4360 * Retrieves marshaling information.
4362 static HRESULT WINAPI
ITypeInfo_fnGetMops( ITypeInfo2
*iface
, MEMBERID memid
,
4365 ICOM_THIS( ITypeInfoImpl
, iface
);
4366 FIXME("(%p) stub!\n", This
);
4370 /* ITypeInfo::GetContainingTypeLib
4372 * Retrieves the containing type library and the index of the type description
4373 * within that type library.
4375 static HRESULT WINAPI
ITypeInfo_fnGetContainingTypeLib( ITypeInfo2
*iface
,
4376 ITypeLib
* *ppTLib
, UINT
*pIndex
)
4378 ICOM_THIS( ITypeInfoImpl
, iface
);
4380 return E_INVALIDARG
;
4381 *ppTLib
=(LPTYPELIB
)(This
->pTypeLib
);
4382 *pIndex
=This
->index
;
4383 ITypeLib2_AddRef(*ppTLib
);
4384 TRACE("(%p) returns (%p) index %d!\n", This
, *ppTLib
, *pIndex
);
4388 /* ITypeInfo::ReleaseTypeAttr
4390 * Releases a TYPEATTR previously returned by GetTypeAttr.
4393 static HRESULT WINAPI
ITypeInfo_fnReleaseTypeAttr( ITypeInfo2
*iface
,
4394 TYPEATTR
* pTypeAttr
)
4396 ICOM_THIS( ITypeInfoImpl
, iface
);
4397 TRACE("(%p)->(%p)\n", This
, pTypeAttr
);
4401 /* ITypeInfo::ReleaseFuncDesc
4403 * Releases a FUNCDESC previously returned by GetFuncDesc. *
4405 static HRESULT WINAPI
ITypeInfo_fnReleaseFuncDesc(
4407 FUNCDESC
*pFuncDesc
)
4409 ICOM_THIS( ITypeInfoImpl
, iface
);
4410 TRACE("(%p)->(%p)\n", This
, pFuncDesc
);
4414 /* ITypeInfo::ReleaseVarDesc
4416 * Releases a VARDESC previously returned by GetVarDesc.
4418 static HRESULT WINAPI
ITypeInfo_fnReleaseVarDesc( ITypeInfo2
*iface
,
4421 ICOM_THIS( ITypeInfoImpl
, iface
);
4422 TRACE("(%p)->(%p)\n", This
, pVarDesc
);
4426 /* ITypeInfo2::GetTypeKind
4428 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
4431 static HRESULT WINAPI
ITypeInfo2_fnGetTypeKind( ITypeInfo2
* iface
,
4432 TYPEKIND
*pTypeKind
)
4434 ICOM_THIS( ITypeInfoImpl
, iface
);
4435 *pTypeKind
=This
->TypeAttr
.typekind
;
4436 TRACE("(%p) type 0x%0x\n", This
,*pTypeKind
);
4440 /* ITypeInfo2::GetTypeFlags
4442 * Returns the type flags without any allocations. This returns a DWORD type
4443 * flag, which expands the type flags without growing the TYPEATTR (type
4447 static HRESULT WINAPI
ITypeInfo2_fnGetTypeFlags( ITypeInfo2
* iface
,
4450 ICOM_THIS( ITypeInfoImpl
, iface
);
4451 *pTypeFlags
=This
->TypeAttr
.wTypeFlags
;
4452 TRACE("(%p) flags 0x%04x\n", This
,*pTypeFlags
);
4456 /* ITypeInfo2::GetFuncIndexOfMemId
4457 * Binds to a specific member based on a known DISPID, where the member name
4458 * is not known (for example, when binding to a default member).
4461 static HRESULT WINAPI
ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2
* iface
,
4462 MEMBERID memid
, INVOKEKIND invKind
, UINT
*pFuncIndex
)
4464 ICOM_THIS( ITypeInfoImpl
, iface
);
4465 TLBFuncDesc
*pFuncInfo
;
4468 /* FIXME: should check for invKind??? */
4469 for(i
=0, pFuncInfo
=This
->funclist
;pFuncInfo
&&
4470 memid
!= pFuncInfo
->funcdesc
.memid
; i
++, pFuncInfo
=pFuncInfo
->next
);
4476 result
=E_INVALIDARG
;
4478 TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This
,
4479 memid
, invKind
, SUCCEEDED(result
)? "SUCCES":"FAILED");
4483 /* TypeInfo2::GetVarIndexOfMemId
4485 * Binds to a specific member based on a known DISPID, where the member name
4486 * is not known (for example, when binding to a default member).
4489 static HRESULT WINAPI
ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo2
* iface
,
4490 MEMBERID memid
, UINT
*pVarIndex
)
4492 ICOM_THIS( ITypeInfoImpl
, iface
);
4493 TLBVarDesc
*pVarInfo
;
4496 for(i
=0, pVarInfo
=This
->varlist
; pVarInfo
&&
4497 memid
!= pVarInfo
->vardesc
.memid
; i
++, pVarInfo
=pVarInfo
->next
)
4504 result
=E_INVALIDARG
;
4506 TRACE("(%p) memid 0x%08lx -> %s\n", This
,
4507 memid
, SUCCEEDED(result
)? "SUCCES":"FAILED");
4511 /* ITypeInfo2::GetCustData
4513 * Gets the custom data
4515 static HRESULT WINAPI
ITypeInfo2_fnGetCustData(
4520 ICOM_THIS( ITypeInfoImpl
, iface
);
4521 TLBCustData
*pCData
;
4523 for(pCData
=This
->pCustData
; pCData
; pCData
= pCData
->next
)
4524 if( IsEqualIID(guid
, &pCData
->guid
)) break;
4526 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
4530 VariantInit( pVarVal
);
4531 VariantCopy( pVarVal
, &pCData
->data
);
4534 return E_INVALIDARG
; /* FIXME: correct? */
4537 /* ITypeInfo2::GetFuncCustData
4539 * Gets the custom data
4541 static HRESULT WINAPI
ITypeInfo2_fnGetFuncCustData(
4547 ICOM_THIS( ITypeInfoImpl
, iface
);
4548 TLBCustData
*pCData
=NULL
;
4549 TLBFuncDesc
* pFDesc
;
4551 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++,
4552 pFDesc
=pFDesc
->next
);
4555 for(pCData
=pFDesc
->pCustData
; pCData
; pCData
= pCData
->next
)
4556 if( IsEqualIID(guid
, &pCData
->guid
)) break;
4558 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
4561 VariantInit( pVarVal
);
4562 VariantCopy( pVarVal
, &pCData
->data
);
4565 return E_INVALIDARG
; /* FIXME: correct? */
4568 /* ITypeInfo2::GetParamCustData
4570 * Gets the custom data
4572 static HRESULT WINAPI
ITypeInfo2_fnGetParamCustData(
4579 ICOM_THIS( ITypeInfoImpl
, iface
);
4580 TLBCustData
*pCData
=NULL
;
4581 TLBFuncDesc
* pFDesc
;
4584 for(i
=0, pFDesc
=This
->funclist
; i
!=indexFunc
&& pFDesc
; i
++,pFDesc
=pFDesc
->next
);
4586 if(pFDesc
&& indexParam
>=0 && indexParam
<pFDesc
->funcdesc
.cParams
)
4587 for(pCData
=pFDesc
->pParamDesc
[indexParam
].pCustData
; pCData
;
4588 pCData
= pCData
->next
)
4589 if( IsEqualIID(guid
, &pCData
->guid
)) break;
4591 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
4595 VariantInit( pVarVal
);
4596 VariantCopy( pVarVal
, &pCData
->data
);
4599 return E_INVALIDARG
; /* FIXME: correct? */
4602 /* ITypeInfo2::GetVarCustData
4604 * Gets the custom data
4606 static HRESULT WINAPI
ITypeInfo2_fnGetVarCustData(
4612 ICOM_THIS( ITypeInfoImpl
, iface
);
4613 TLBCustData
*pCData
=NULL
;
4614 TLBVarDesc
* pVDesc
;
4617 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++, pVDesc
=pVDesc
->next
);
4621 for(pCData
=pVDesc
->pCustData
; pCData
; pCData
= pCData
->next
)
4623 if( IsEqualIID(guid
, &pCData
->guid
)) break;
4627 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
4631 VariantInit( pVarVal
);
4632 VariantCopy( pVarVal
, &pCData
->data
);
4635 return E_INVALIDARG
; /* FIXME: correct? */
4638 /* ITypeInfo2::GetImplCustData
4640 * Gets the custom data
4642 static HRESULT WINAPI
ITypeInfo2_fnGetImplTypeCustData(
4648 ICOM_THIS( ITypeInfoImpl
, iface
);
4649 TLBCustData
*pCData
=NULL
;
4650 TLBImplType
* pRDesc
;
4653 for(i
=0, pRDesc
=This
->impltypelist
; i
!=index
&& pRDesc
; i
++, pRDesc
=pRDesc
->next
);
4657 for(pCData
=pRDesc
->pCustData
; pCData
; pCData
= pCData
->next
)
4659 if( IsEqualIID(guid
, &pCData
->guid
)) break;
4663 TRACE("(%p) guid %s %s found!x)\n", This
, debugstr_guid(guid
), pCData
? "" : "NOT");
4667 VariantInit( pVarVal
);
4668 VariantCopy( pVarVal
, &pCData
->data
);
4671 return E_INVALIDARG
; /* FIXME: correct? */
4674 /* ITypeInfo2::GetDocumentation2
4676 * Retrieves the documentation string, the complete Help file name and path,
4677 * the localization context to use, and the context ID for the library Help
4678 * topic in the Help file.
4681 static HRESULT WINAPI
ITypeInfo2_fnGetDocumentation2(
4685 BSTR
*pbstrHelpString
,
4686 DWORD
*pdwHelpStringContext
,
4687 BSTR
*pbstrHelpStringDll
)
4689 ICOM_THIS( ITypeInfoImpl
, iface
);
4690 TLBFuncDesc
* pFDesc
;
4691 TLBVarDesc
* pVDesc
;
4692 TRACE("(%p) memid %ld lcid(0x%lx) HelpString(%p) "
4693 "HelpStringContext(%p) HelpStringDll(%p)\n",
4694 This
, memid
, lcid
, pbstrHelpString
, pdwHelpStringContext
,
4695 pbstrHelpStringDll
);
4696 /* the help string should be obtained from the helpstringdll,
4697 * using the _DLLGetDocumentation function, based on the supplied
4698 * lcid. Nice to do sometime...
4700 if(memid
==MEMBERID_NIL
){ /* documentation for the typeinfo */
4702 *pbstrHelpString
=SysAllocString(This
->Name
);
4703 if(pdwHelpStringContext
)
4704 *pdwHelpStringContext
=This
->dwHelpStringContext
;
4705 if(pbstrHelpStringDll
)
4706 *pbstrHelpStringDll
=
4707 SysAllocString(This
->pTypeLib
->HelpStringDll
);/* FIXME */
4709 }else {/* for a member */
4710 for(pFDesc
=This
->funclist
; pFDesc
; pFDesc
=pFDesc
->next
)
4711 if(pFDesc
->funcdesc
.memid
==memid
){
4713 *pbstrHelpString
=SysAllocString(pFDesc
->HelpString
);
4714 if(pdwHelpStringContext
)
4715 *pdwHelpStringContext
=pFDesc
->HelpStringContext
;
4716 if(pbstrHelpStringDll
)
4717 *pbstrHelpStringDll
=
4718 SysAllocString(This
->pTypeLib
->HelpStringDll
);/* FIXME */
4721 for(pVDesc
=This
->varlist
; pVDesc
; pVDesc
=pVDesc
->next
)
4722 if(pVDesc
->vardesc
.memid
==memid
){
4724 *pbstrHelpString
=SysAllocString(pVDesc
->HelpString
);
4725 if(pdwHelpStringContext
)
4726 *pdwHelpStringContext
=pVDesc
->HelpStringContext
;
4727 if(pbstrHelpStringDll
)
4728 *pbstrHelpStringDll
=
4729 SysAllocString(This
->pTypeLib
->HelpStringDll
);/* FIXME */
4733 return TYPE_E_ELEMENTNOTFOUND
;
4736 /* ITypeInfo2::GetAllCustData
4738 * Gets all custom data items for the Type info.
4741 static HRESULT WINAPI
ITypeInfo2_fnGetAllCustData(
4743 CUSTDATA
*pCustData
)
4745 ICOM_THIS( ITypeInfoImpl
, iface
);
4746 TLBCustData
*pCData
;
4749 TRACE("(%p) returning %d items\n", This
, This
->ctCustData
);
4751 pCustData
->prgCustData
= TLB_Alloc(This
->ctCustData
* sizeof(CUSTDATAITEM
));
4752 if(pCustData
->prgCustData
){
4753 pCustData
->cCustData
=This
->ctCustData
;
4754 for(i
=0, pCData
=This
->pCustData
; pCData
; i
++, pCData
= pCData
->next
){
4755 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
4756 VariantCopy(& pCustData
->prgCustData
[i
].varValue
, & pCData
->data
);
4759 ERR(" OUT OF MEMORY! \n");
4760 return E_OUTOFMEMORY
;
4765 /* ITypeInfo2::GetAllFuncCustData
4767 * Gets all custom data items for the specified Function
4770 static HRESULT WINAPI
ITypeInfo2_fnGetAllFuncCustData(
4773 CUSTDATA
*pCustData
)
4775 ICOM_THIS( ITypeInfoImpl
, iface
);
4776 TLBCustData
*pCData
;
4777 TLBFuncDesc
* pFDesc
;
4779 TRACE("(%p) index %d\n", This
, index
);
4780 for(i
=0, pFDesc
=This
->funclist
; i
!=index
&& pFDesc
; i
++,
4781 pFDesc
=pFDesc
->next
)
4784 pCustData
->prgCustData
=
4785 TLB_Alloc(pFDesc
->ctCustData
* sizeof(CUSTDATAITEM
));
4786 if(pCustData
->prgCustData
){
4787 pCustData
->cCustData
=pFDesc
->ctCustData
;
4788 for(i
=0, pCData
=pFDesc
->pCustData
; pCData
; i
++,
4789 pCData
= pCData
->next
){
4790 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
4791 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
4795 ERR(" OUT OF MEMORY! \n");
4796 return E_OUTOFMEMORY
;
4800 return TYPE_E_ELEMENTNOTFOUND
;
4803 /* ITypeInfo2::GetAllParamCustData
4805 * Gets all custom data items for the Functions
4808 static HRESULT WINAPI
ITypeInfo2_fnGetAllParamCustData( ITypeInfo2
* iface
,
4809 UINT indexFunc
, UINT indexParam
, CUSTDATA
*pCustData
)
4811 ICOM_THIS( ITypeInfoImpl
, iface
);
4812 TLBCustData
*pCData
=NULL
;
4813 TLBFuncDesc
* pFDesc
;
4815 TRACE("(%p) index %d\n", This
, indexFunc
);
4816 for(i
=0, pFDesc
=This
->funclist
; i
!=indexFunc
&& pFDesc
; i
++,
4817 pFDesc
=pFDesc
->next
)
4819 if(pFDesc
&& indexParam
>=0 && indexParam
<pFDesc
->funcdesc
.cParams
){
4820 pCustData
->prgCustData
=
4821 TLB_Alloc(pFDesc
->pParamDesc
[indexParam
].ctCustData
*
4822 sizeof(CUSTDATAITEM
));
4823 if(pCustData
->prgCustData
){
4824 pCustData
->cCustData
=pFDesc
->pParamDesc
[indexParam
].ctCustData
;
4825 for(i
=0, pCData
=pFDesc
->pParamDesc
[indexParam
].pCustData
;
4826 pCData
; i
++, pCData
= pCData
->next
){
4827 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
4828 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
4832 ERR(" OUT OF MEMORY! \n");
4833 return E_OUTOFMEMORY
;
4837 return TYPE_E_ELEMENTNOTFOUND
;
4840 /* ITypeInfo2::GetAllVarCustData
4842 * Gets all custom data items for the specified Variable
4845 static HRESULT WINAPI
ITypeInfo2_fnGetAllVarCustData( ITypeInfo2
* iface
,
4846 UINT index
, CUSTDATA
*pCustData
)
4848 ICOM_THIS( ITypeInfoImpl
, iface
);
4849 TLBCustData
*pCData
;
4850 TLBVarDesc
* pVDesc
;
4852 TRACE("(%p) index %d\n", This
, index
);
4853 for(i
=0, pVDesc
=This
->varlist
; i
!=index
&& pVDesc
; i
++,
4854 pVDesc
=pVDesc
->next
)
4857 pCustData
->prgCustData
=
4858 TLB_Alloc(pVDesc
->ctCustData
* sizeof(CUSTDATAITEM
));
4859 if(pCustData
->prgCustData
){
4860 pCustData
->cCustData
=pVDesc
->ctCustData
;
4861 for(i
=0, pCData
=pVDesc
->pCustData
; pCData
; i
++,
4862 pCData
= pCData
->next
){
4863 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
4864 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
4868 ERR(" OUT OF MEMORY! \n");
4869 return E_OUTOFMEMORY
;
4873 return TYPE_E_ELEMENTNOTFOUND
;
4876 /* ITypeInfo2::GetAllImplCustData
4878 * Gets all custom data items for the specified implementation type
4881 static HRESULT WINAPI
ITypeInfo2_fnGetAllImplTypeCustData(
4884 CUSTDATA
*pCustData
)
4886 ICOM_THIS( ITypeInfoImpl
, iface
);
4887 TLBCustData
*pCData
;
4888 TLBImplType
* pRDesc
;
4890 TRACE("(%p) index %d\n", This
, index
);
4891 for(i
=0, pRDesc
=This
->impltypelist
; i
!=index
&& pRDesc
; i
++,
4892 pRDesc
=pRDesc
->next
)
4895 pCustData
->prgCustData
=
4896 TLB_Alloc(pRDesc
->ctCustData
* sizeof(CUSTDATAITEM
));
4897 if(pCustData
->prgCustData
){
4898 pCustData
->cCustData
=pRDesc
->ctCustData
;
4899 for(i
=0, pCData
=pRDesc
->pCustData
; pCData
; i
++,
4900 pCData
= pCData
->next
){
4901 pCustData
->prgCustData
[i
].guid
=pCData
->guid
;
4902 VariantCopy(& pCustData
->prgCustData
[i
].varValue
,
4906 ERR(" OUT OF MEMORY! \n");
4907 return E_OUTOFMEMORY
;
4911 return TYPE_E_ELEMENTNOTFOUND
;
4914 static ICOM_VTABLE(ITypeInfo2
) tinfvt
=
4916 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4918 ITypeInfo_fnQueryInterface
,
4920 ITypeInfo_fnRelease
,
4922 ITypeInfo_fnGetTypeAttr
,
4923 ITypeInfo_fnGetTypeComp
,
4924 ITypeInfo_fnGetFuncDesc
,
4925 ITypeInfo_fnGetVarDesc
,
4926 ITypeInfo_fnGetNames
,
4927 ITypeInfo_fnGetRefTypeOfImplType
,
4928 ITypeInfo_fnGetImplTypeFlags
,
4929 ITypeInfo_fnGetIDsOfNames
,
4931 ITypeInfo_fnGetDocumentation
,
4932 ITypeInfo_fnGetDllEntry
,
4933 ITypeInfo_fnGetRefTypeInfo
,
4934 ITypeInfo_fnAddressOfMember
,
4935 ITypeInfo_fnCreateInstance
,
4936 ITypeInfo_fnGetMops
,
4937 ITypeInfo_fnGetContainingTypeLib
,
4938 ITypeInfo_fnReleaseTypeAttr
,
4939 ITypeInfo_fnReleaseFuncDesc
,
4940 ITypeInfo_fnReleaseVarDesc
,
4942 ITypeInfo2_fnGetTypeKind
,
4943 ITypeInfo2_fnGetTypeFlags
,
4944 ITypeInfo2_fnGetFuncIndexOfMemId
,
4945 ITypeInfo2_fnGetVarIndexOfMemId
,
4946 ITypeInfo2_fnGetCustData
,
4947 ITypeInfo2_fnGetFuncCustData
,
4948 ITypeInfo2_fnGetParamCustData
,
4949 ITypeInfo2_fnGetVarCustData
,
4950 ITypeInfo2_fnGetImplTypeCustData
,
4951 ITypeInfo2_fnGetDocumentation2
,
4952 ITypeInfo2_fnGetAllCustData
,
4953 ITypeInfo2_fnGetAllFuncCustData
,
4954 ITypeInfo2_fnGetAllParamCustData
,
4955 ITypeInfo2_fnGetAllVarCustData
,
4956 ITypeInfo2_fnGetAllImplTypeCustData
,