oleaut32/tests: Use GetModuleHandle and add a few skip's.
[wine] / dlls / oleaut32 / tests / typelib.c
1 /*
2  * ITypeLib and ITypeInfo test
3  *
4  * Copyright 2004 Jacek Caban
5  * Copyright 2006 Dmitry Timoshkov
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #define COBJMACROS
23
24 #include <wine/test.h>
25 #include <stdarg.h>
26
27 #include "windef.h"
28 #include "winbase.h"
29 #include "oleauto.h"
30 #include "ocidl.h"
31 #include "shlwapi.h"
32 #include "tmarshal.h"
33
34 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
35
36 static const WCHAR wszStdOle2[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
37
38 static void ref_count_test(LPCWSTR type_lib)
39 {
40     ITypeLib *iface;
41     ITypeInfo *iti1, *iti2;
42     HRESULT hRes;
43     int ref_count;
44
45     trace("Loading type library\n");
46     hRes = LoadTypeLib(type_lib, &iface);
47     ok(hRes == S_OK, "Could not load type library\n");
48     if(hRes != S_OK)
49         return;
50
51     hRes = ITypeLib_GetTypeInfo(iface, 1, &iti1);
52     ok(hRes == S_OK, "ITypeLib_GetTypeInfo failed on index = 1\n");
53     ok(ref_count=ITypeLib_Release(iface) > 0, "ITypeLib destroyed while ITypeInfo has back pointer\n");
54     if(!ref_count)
55         return;
56
57     hRes = ITypeLib_GetTypeInfo(iface, 1, &iti2);
58     ok(hRes == S_OK, "ITypeLib_GetTypeInfo failed on index = 1\n");
59     ok(iti1 == iti2, "ITypeLib_GetTypeInfo returned different pointers for same indexes\n");
60
61     ITypeLib_AddRef(iface);
62     ITypeInfo_Release(iti2);
63     ITypeInfo_Release(iti1);
64     ok(ITypeLib_Release(iface) == 0, "ITypeLib should be destroyed here.\n");
65 }
66
67 static void test_TypeComp(void)
68 {
69     ITypeLib *pTypeLib;
70     ITypeComp *pTypeComp;
71     HRESULT hr;
72     ULONG ulHash;
73     DESCKIND desckind;
74     BINDPTR bindptr;
75     ITypeInfo *pTypeInfo;
76     ITypeInfo *pFontTypeInfo;
77     static WCHAR wszStdFunctions[] = {'S','t','d','F','u','n','c','t','i','o','n','s',0};
78     static WCHAR wszSavePicture[] = {'S','a','v','e','P','i','c','t','u','r','e',0};
79     static WCHAR wszOLE_TRISTATE[] = {'O','L','E','_','T','R','I','S','T','A','T','E',0};
80     static WCHAR wszUnchecked[] = {'U','n','c','h','e','c','k','e','d',0};
81     static WCHAR wszIUnknown[] = {'I','U','n','k','n','o','w','n',0};
82     static WCHAR wszFont[] = {'F','o','n','t',0};
83     static WCHAR wszGUID[] = {'G','U','I','D',0};
84     static WCHAR wszStdPicture[] = {'S','t','d','P','i','c','t','u','r','e',0};
85     static WCHAR wszOLE_COLOR[] = {'O','L','E','_','C','O','L','O','R',0};
86     static WCHAR wszClone[] = {'C','l','o','n','e',0};
87     static WCHAR wszclone[] = {'c','l','o','n','e',0};
88
89     hr = LoadTypeLib(wszStdOle2, &pTypeLib);
90     ok_ole_success(hr, LoadTypeLib);
91
92     hr = ITypeLib_GetTypeComp(pTypeLib, &pTypeComp);
93     ok_ole_success(hr, ITypeLib_GetTypeComp);
94
95     /* test getting a TKIND_MODULE */
96     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdFunctions);
97     hr = ITypeComp_Bind(pTypeComp, wszStdFunctions, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
98     ok_ole_success(hr, ITypeComp_Bind);
99
100     ok(desckind == DESCKIND_TYPECOMP,
101         "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
102         desckind);
103     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
104
105     ITypeComp_Release(bindptr.lptcomp);
106
107     /* test getting a TKIND_MODULE with INVOKE_PROPERTYGET */
108     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdFunctions);
109     hr = ITypeComp_Bind(pTypeComp, wszStdFunctions, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
110     ok_ole_success(hr, ITypeComp_Bind);
111
112     ok(desckind == DESCKIND_TYPECOMP,
113         "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
114         desckind);
115     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
116     ITypeComp_Release(bindptr.lptcomp);
117
118     /* test getting a function within a TKIND_MODULE */
119     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszSavePicture);
120     hr = ITypeComp_Bind(pTypeComp, wszSavePicture, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
121     ok_ole_success(hr, ITypeComp_Bind);
122
123     ok(desckind == DESCKIND_FUNCDESC,
124         "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
125         desckind);
126     ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
127     ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
128     ITypeInfo_Release(pTypeInfo);
129
130     /* test getting a function within a TKIND_MODULE with INVOKE_PROPERTYGET */
131     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszSavePicture);
132     hr = ITypeComp_Bind(pTypeComp, wszSavePicture, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
133     todo_wine ok(hr == TYPE_E_TYPEMISMATCH,
134         "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n",
135         hr);
136
137     ok(desckind == DESCKIND_NONE,
138         "desckind should have been DESCKIND_NONE instead of %d\n",
139         desckind);
140     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
141     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
142
143     /* test getting a TKIND_ENUM */
144     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszOLE_TRISTATE);
145     hr = ITypeComp_Bind(pTypeComp, wszOLE_TRISTATE, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
146     ok_ole_success(hr, ITypeComp_Bind);
147
148     ok(desckind == DESCKIND_TYPECOMP,
149         "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
150         desckind);
151     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
152
153     ITypeComp_Release(bindptr.lptcomp);
154
155     /* test getting a value within a TKIND_ENUM */
156     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszUnchecked);
157     hr = ITypeComp_Bind(pTypeComp, wszUnchecked, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
158     ok_ole_success(hr, ITypeComp_Bind);
159
160     ok(desckind == DESCKIND_VARDESC,
161         "desckind should have been DESCKIND_VARDESC instead of %d\n",
162         desckind);
163     ITypeInfo_ReleaseVarDesc(pTypeInfo, bindptr.lpvardesc);
164     ITypeInfo_Release(pTypeInfo);
165
166     /* test getting a TKIND_INTERFACE */
167     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszIUnknown);
168     hr = ITypeComp_Bind(pTypeComp, wszIUnknown, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
169     ok_ole_success(hr, ITypeComp_Bind);
170
171     ok(desckind == DESCKIND_NONE,
172         "desckind should have been DESCKIND_NONE instead of %d\n",
173         desckind);
174     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
175     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
176
177     /* test getting a TKIND_DISPATCH */
178     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszFont);
179     hr = ITypeComp_Bind(pTypeComp, wszFont, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
180     ok_ole_success(hr, ITypeComp_Bind);
181
182     ok(desckind == DESCKIND_NONE,
183         "desckind should have been DESCKIND_NONE instead of %d\n",
184         desckind);
185     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
186     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
187
188     /* test getting a TKIND_RECORD/TKIND_ALIAS */
189     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
190     hr = ITypeComp_Bind(pTypeComp, wszGUID, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
191     ok_ole_success(hr, ITypeComp_Bind);
192
193     ok(desckind == DESCKIND_NONE,
194         "desckind should have been DESCKIND_NONE instead of %d\n",
195         desckind);
196     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
197     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
198
199     /* test getting a TKIND_ALIAS */
200     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszOLE_COLOR);
201     hr = ITypeComp_Bind(pTypeComp, wszOLE_COLOR, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
202     ok_ole_success(hr, ITypeComp_Bind);
203
204     ok(desckind == DESCKIND_NONE,
205         "desckind should have been DESCKIND_NONE instead of %d\n",
206         desckind);
207     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
208     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
209
210     /* test getting a TKIND_COCLASS */
211     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdPicture);
212     hr = ITypeComp_Bind(pTypeComp, wszStdPicture, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
213     ok_ole_success(hr, ITypeComp_Bind);
214
215     ok(desckind == DESCKIND_NONE,
216         "desckind should have been DESCKIND_NONE instead of %d\n",
217         desckind);
218     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
219     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
220
221     ITypeComp_Release(pTypeComp);
222
223     /* tests for ITypeComp on an interface */
224     hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IFont, &pFontTypeInfo);
225     ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
226
227     hr = ITypeInfo_GetTypeComp(pFontTypeInfo, &pTypeComp);
228     ok_ole_success(hr, ITypeLib_GetTypeComp);
229
230     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszClone);
231     hr = ITypeComp_Bind(pTypeComp, wszClone, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
232     ok_ole_success(hr, ITypeComp_Bind);
233
234     ok(desckind == DESCKIND_FUNCDESC,
235         "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
236         desckind);
237     ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
238     ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
239     ITypeInfo_Release(pTypeInfo);
240
241     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszClone);
242     hr = ITypeComp_Bind(pTypeComp, wszClone, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
243     ok(hr == TYPE_E_TYPEMISMATCH, "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n", hr);
244
245     ok(desckind == DESCKIND_NONE,
246         "desckind should have been DESCKIND_NONE instead of %d\n",
247         desckind);
248     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
249     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
250
251     /* tests that the compare is case-insensitive */
252     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszclone);
253     hr = ITypeComp_Bind(pTypeComp, wszclone, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
254     ok_ole_success(hr, ITypeComp_Bind);
255
256     ok(desckind == DESCKIND_FUNCDESC,
257         "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
258         desckind);
259     ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
260     ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
261     ITypeInfo_Release(pTypeInfo);
262
263     ITypeComp_Release(pTypeComp);
264     ITypeInfo_Release(pFontTypeInfo);
265     ITypeLib_Release(pTypeLib);
266 }
267
268 static void test_CreateDispTypeInfo(void)
269 {
270     ITypeInfo *pTypeInfo, *pTI2;
271     HRESULT hr;
272     INTERFACEDATA ifdata;
273     METHODDATA methdata[4];
274     PARAMDATA parms1[2];
275     PARAMDATA parms3[1];
276     TYPEATTR *pTypeAttr;
277     HREFTYPE href;
278     FUNCDESC *pFuncDesc;
279     MEMBERID memid;
280
281     static WCHAR func1[] = {'f','u','n','c','1',0};
282     static const WCHAR func2[] = {'f','u','n','c','2',0};
283     static const WCHAR func3[] = {'f','u','n','c','3',0};
284     static const WCHAR parm1[] = {'p','a','r','m','1',0};
285     static const WCHAR parm2[] = {'p','a','r','m','2',0};
286     OLECHAR *name = func1;
287
288     ifdata.pmethdata = methdata;
289     ifdata.cMembers = sizeof(methdata) / sizeof(methdata[0]);
290
291     methdata[0].szName = SysAllocString(func1);
292     methdata[0].ppdata = parms1;
293     methdata[0].dispid = 0x123;
294     methdata[0].iMeth = 0;
295     methdata[0].cc = CC_STDCALL;
296     methdata[0].cArgs = 2;
297     methdata[0].wFlags = DISPATCH_METHOD;
298     methdata[0].vtReturn = VT_HRESULT;
299     parms1[0].szName = SysAllocString(parm1);
300     parms1[0].vt = VT_I4;
301     parms1[1].szName = SysAllocString(parm2);
302     parms1[1].vt = VT_BSTR;
303
304     methdata[1].szName = SysAllocString(func2);
305     methdata[1].ppdata = NULL;
306     methdata[1].dispid = 0x124;
307     methdata[1].iMeth = 1;
308     methdata[1].cc = CC_STDCALL;
309     methdata[1].cArgs = 0;
310     methdata[1].wFlags = DISPATCH_PROPERTYGET;
311     methdata[1].vtReturn = VT_I4;
312
313     methdata[2].szName = SysAllocString(func3);
314     methdata[2].ppdata = parms3;
315     methdata[2].dispid = 0x125;
316     methdata[2].iMeth = 3;
317     methdata[2].cc = CC_STDCALL;
318     methdata[2].cArgs = 1;
319     methdata[2].wFlags = DISPATCH_PROPERTYPUT;
320     methdata[2].vtReturn = VT_HRESULT;
321     parms3[0].szName = SysAllocString(parm1);
322     parms3[0].vt = VT_I4;
323
324     methdata[3].szName = SysAllocString(func3);
325     methdata[3].ppdata = NULL;
326     methdata[3].dispid = 0x125;
327     methdata[3].iMeth = 4;
328     methdata[3].cc = CC_STDCALL;
329     methdata[3].cArgs = 0;
330     methdata[3].wFlags = DISPATCH_PROPERTYGET;
331     methdata[3].vtReturn = VT_I4;
332
333     hr = CreateDispTypeInfo(&ifdata, LOCALE_NEUTRAL, &pTypeInfo);
334     ok(hr == S_OK, "hr %08x\n", hr);
335
336     hr = ITypeInfo_GetTypeAttr(pTypeInfo, &pTypeAttr);
337     ok(hr == S_OK, "hr %08x\n", hr);
338
339     ok(pTypeAttr->typekind == TKIND_COCLASS, "typekind %0x\n", pTypeAttr->typekind);
340     ok(pTypeAttr->cImplTypes == 1, "cImplTypes %d\n", pTypeAttr->cImplTypes);
341     ok(pTypeAttr->cFuncs == 0, "cFuncs %d\n", pTypeAttr->cFuncs);
342     ok(pTypeAttr->wTypeFlags == 0, "wTypeFlags %04x\n", pTypeAttr->cFuncs);
343     ITypeInfo_ReleaseTypeAttr(pTypeInfo, pTypeAttr);
344
345     hr = ITypeInfo_GetRefTypeOfImplType(pTypeInfo, 0, &href);
346     ok(hr == S_OK, "hr %08x\n", hr);
347     ok(href == 0, "href = 0x%x\n", href);
348     hr = ITypeInfo_GetRefTypeInfo(pTypeInfo, href, &pTI2);
349     ok(hr == S_OK, "hr %08x\n", hr);
350     hr = ITypeInfo_GetTypeAttr(pTI2, &pTypeAttr);
351     ok(hr == S_OK, "hr %08x\n", hr);
352     ok(pTypeAttr->typekind == TKIND_INTERFACE, "typekind %0x\n", pTypeAttr->typekind);
353     ok(pTypeAttr->cFuncs == 4, "cFuncs %d\n", pTypeAttr->cFuncs);
354     ok(IsEqualGUID(&pTypeAttr->guid, &GUID_NULL), "guid {%08x-...}\n", pTypeAttr->guid.Data1);
355     ok(pTypeAttr->wTypeFlags == 0, "typeflags %08x\n", pTypeAttr->wTypeFlags);
356
357     ITypeInfo_ReleaseTypeAttr(pTI2, pTypeAttr);
358
359     hr = ITypeInfo_GetFuncDesc(pTI2, 0, &pFuncDesc);
360     ok(hr == S_OK, "hr %08x\n", hr);
361     ok(pFuncDesc->memid == 0x123, "memid %x\n", pFuncDesc->memid);
362     ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
363     ok(pFuncDesc->invkind == methdata[0].wFlags, "invkind %d\n", pFuncDesc->invkind);
364     ok(pFuncDesc->callconv == methdata[0].cc, "callconv %d\n", pFuncDesc->callconv);
365     ok(pFuncDesc->cParams == methdata[0].cArgs, "cParams %d\n", pFuncDesc->cParams);
366     ok(pFuncDesc->oVft == 0, "oVft %d\n", pFuncDesc->oVft);
367     ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
368     ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
369     ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
370     ok(U(pFuncDesc->lprgelemdescParam[0]).paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", U(pFuncDesc->lprgelemdescParam[0]).paramdesc.wParamFlags);
371
372     ok(pFuncDesc->lprgelemdescParam[1].tdesc.vt == VT_BSTR, "parm 1 vt %x\n", pFuncDesc->lprgelemdescParam[1].tdesc.vt);
373     ok(U(pFuncDesc->lprgelemdescParam[1]).paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 1 flags %x\n", U(pFuncDesc->lprgelemdescParam[1]).paramdesc.wParamFlags);
374     ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
375
376     hr = ITypeInfo_GetFuncDesc(pTI2, 1, &pFuncDesc);
377     ok(hr == S_OK, "hr %08x\n", hr);
378     ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
379     ok(pFuncDesc->invkind == methdata[1].wFlags, "invkind %d\n", pFuncDesc->invkind);
380     ok(pFuncDesc->callconv == methdata[1].cc, "callconv %d\n", pFuncDesc->callconv);
381     ok(pFuncDesc->cParams == methdata[1].cArgs, "cParams %d\n", pFuncDesc->cParams);
382     ok(pFuncDesc->oVft == 4, "oVft %d\n", pFuncDesc->oVft);
383     ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
384     ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
385     ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
386
387     hr = ITypeInfo_GetFuncDesc(pTI2, 2, &pFuncDesc);
388     ok(hr == S_OK, "hr %08x\n", hr);
389     ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
390     ok(pFuncDesc->invkind == methdata[2].wFlags, "invkind %d\n", pFuncDesc->invkind);
391     ok(pFuncDesc->callconv == methdata[2].cc, "callconv %d\n", pFuncDesc->callconv);
392     ok(pFuncDesc->cParams == methdata[2].cArgs, "cParams %d\n", pFuncDesc->cParams);
393     ok(pFuncDesc->oVft == 12, "oVft %d\n", pFuncDesc->oVft);
394     ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
395     ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
396     ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
397     ok(U(pFuncDesc->lprgelemdescParam[0]).paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", U(pFuncDesc->lprgelemdescParam[0]).paramdesc.wParamFlags);
398     ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
399
400     hr = ITypeInfo_GetFuncDesc(pTI2, 3, &pFuncDesc);
401     ok(hr == S_OK, "hr %08x\n", hr);
402     ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
403     ok(pFuncDesc->invkind == methdata[3].wFlags, "invkind %d\n", pFuncDesc->invkind);
404     ok(pFuncDesc->callconv == methdata[3].cc, "callconv %d\n", pFuncDesc->callconv);
405     ok(pFuncDesc->cParams == methdata[3].cArgs, "cParams %d\n", pFuncDesc->cParams);
406     ok(pFuncDesc->oVft == 16, "oVft %d\n", pFuncDesc->oVft);
407     ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
408     ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
409     ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
410
411     /* test GetIDsOfNames on a coclass to see if it searches its interfaces */
412     hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &name, 1, &memid);
413     ok(hr == S_OK, "hr 0x%08x\n", hr);
414     ok(memid == 0x123, "memid 0x%08x\n", memid);
415
416     ITypeInfo_Release(pTI2);
417     ITypeInfo_Release(pTypeInfo);
418
419     SysFreeString(parms1[0].szName);
420     SysFreeString(parms1[1].szName);
421     SysFreeString(parms3[0].szName);
422     SysFreeString(methdata[0].szName);
423     SysFreeString(methdata[1].szName);
424     SysFreeString(methdata[2].szName);
425     SysFreeString(methdata[3].szName);
426 }
427
428 static void test_TypeInfo(void)
429 {
430     ITypeLib *pTypeLib;
431     ITypeInfo *pTypeInfo;
432     HRESULT hr;
433     static WCHAR wszBogus[] = { 'b','o','g','u','s',0 };
434     static WCHAR wszGetTypeInfo[] = { 'G','e','t','T','y','p','e','I','n','f','o',0 };
435     static WCHAR wszClone[] = {'C','l','o','n','e',0};
436     OLECHAR* bogus = wszBogus;
437     OLECHAR* pwszGetTypeInfo = wszGetTypeInfo;
438     OLECHAR* pwszClone = wszClone;
439     DISPID dispidMember;
440     DISPPARAMS dispparams;
441
442     hr = LoadTypeLib(wszStdOle2, &pTypeLib);
443     ok_ole_success(hr, LoadTypeLib);
444
445     hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IFont, &pTypeInfo);
446     ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid); 
447
448     /* test nonexistent method name */
449     hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &bogus, 1, &dispidMember);
450     ok(hr == DISP_E_UNKNOWNNAME,
451        "ITypeInfo_GetIDsOfNames should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n",
452        hr);
453
454     /* test invalid memberid */
455     dispparams.cNamedArgs = 0;
456     dispparams.cArgs = 0;
457     dispparams.rgdispidNamedArgs = NULL;
458     dispparams.rgvarg = NULL;
459     hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
460     ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
461
462     hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &pwszClone, 1, &dispidMember);
463     ok_ole_success(hr, ITypeInfo_GetIDsOfNames);
464
465     /* test correct memberid, but wrong flags */
466     hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
467     ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
468
469     /* test NULL dispparams */
470     hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, NULL, NULL, NULL, NULL);
471     ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
472
473     /* test dispparams->cNamedArgs being bigger than dispparams->cArgs */
474     dispparams.cNamedArgs = 1;
475     hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
476     ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
477
478     ITypeInfo_Release(pTypeInfo);
479
480     hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IDispatch, &pTypeInfo);
481     ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid); 
482
483     hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &pwszGetTypeInfo, 1, &dispidMember);
484     ok_ole_success(hr, ITypeInfo_GetIDsOfNames);
485
486     /* test invoking a method with a [restricted] keyword */
487     hr = ITypeInfo_Invoke(pTypeInfo, NULL, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
488     todo_wine {
489     ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
490     }
491
492     ITypeInfo_Release(pTypeInfo);
493     ITypeLib_Release(pTypeLib);
494 }
495
496 static BOOL do_typelib_reg_key(GUID *uid, WORD maj, WORD min, LPCWSTR base, BOOL remove)
497 {
498     static const WCHAR typelibW[] = {'T','y','p','e','l','i','b','\\',0};
499     static const WCHAR formatW[] = {'\\','%','u','.','%','u','\\','0','\\','w','i','n','3','2',0};
500     static const WCHAR format2W[] = {'%','s','_','%','u','_','%','u','.','d','l','l',0};
501     WCHAR buf[128];
502     HKEY hkey;
503     BOOL ret = TRUE;
504
505     memcpy(buf, typelibW, sizeof(typelibW));
506     StringFromGUID2(uid, buf + lstrlenW(buf), 40);
507
508     if (remove)
509     {
510         ok(SHDeleteKeyW(HKEY_CLASSES_ROOT, buf) == ERROR_SUCCESS, "SHDeleteKey failed\n");
511         return TRUE;
512     }
513
514     wsprintfW(buf + lstrlenW(buf), formatW, maj, min );
515
516     if (RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0,
517                         KEY_WRITE, NULL, &hkey, NULL) != ERROR_SUCCESS)
518     {
519         trace("RegCreateKeyExW failed\n");
520         return FALSE;
521     }
522
523     wsprintfW(buf, format2W, base, maj, min);
524     if (RegSetValueExW(hkey, NULL, 0, REG_SZ,
525                        (BYTE *)buf, (lstrlenW(buf) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS)
526     {
527         trace("RegSetValueExW failed\n");
528         ret = FALSE;
529     }
530     RegCloseKey(hkey);
531     return ret;
532 }
533
534 static void test_QueryPathOfRegTypeLib(void)
535 {
536     static const struct test_data
537     {
538         WORD maj, min;
539         HRESULT ret;
540         const WCHAR path[16];
541     } td[] = {
542         { 1, 0, TYPE_E_LIBNOTREGISTERED, { 0 } },
543         { 3, 0, S_OK, {'f','a','k','e','_','3','_','0','.','d','l','l',0 } },
544         { 3, 1, S_OK, {'f','a','k','e','_','3','_','1','.','d','l','l',0 } },
545         { 3, 22, S_OK, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
546         { 3, 37, S_OK, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
547         { 3, 40, S_OK, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
548         { 4, 0, TYPE_E_LIBNOTREGISTERED, { 0 } }
549     };
550     static const WCHAR base[] = {'f','a','k','e',0};
551     UINT i;
552     RPC_STATUS status;
553     GUID uid;
554     WCHAR uid_str[40];
555     HRESULT ret;
556     BSTR path;
557
558     status = UuidCreate(&uid);
559     ok(!status, "UuidCreate error %08lx\n", status);
560
561     StringFromGUID2(&uid, uid_str, 40);
562     /*trace("GUID: %s\n", wine_dbgstr_w(uid_str));*/
563
564     if (!do_typelib_reg_key(&uid, 3, 0, base, 0)) return;
565     if (!do_typelib_reg_key(&uid, 3, 1, base, 0)) return;
566     if (!do_typelib_reg_key(&uid, 3, 37, base, 0)) return;
567
568     for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
569     {
570         ret = QueryPathOfRegTypeLib(&uid, td[i].maj, td[i].min, 0, &path);
571         ok(ret == td[i].ret, "QueryPathOfRegTypeLib(%u.%u) returned %08x\n", td[i].maj, td[i].min, ret);
572         if (ret == S_OK)
573         {
574             ok(!lstrcmpW(td[i].path, path), "typelib %u.%u path doesn't match\n", td[i].maj, td[i].min);
575             SysFreeString(path);
576         }
577     }
578
579     do_typelib_reg_key(&uid, 0, 0, NULL, 1);
580 }
581
582 static void test_inheritance(void)
583 {
584     HRESULT hr;
585     ITypeLib *pTL;
586     ITypeInfo *pTI, *pTI_p;
587     TYPEATTR *pTA;
588     HREFTYPE href;
589     FUNCDESC *pFD;
590     WCHAR path[MAX_PATH];
591     static const WCHAR tl_path[] = {'.','\\','m','i','d','l','_','t','m','a','r','s','h','a','l','.','t','l','b',0};
592
593     BOOL use_midl_tlb = 0;
594
595     GetModuleFileNameW(NULL, path, MAX_PATH);
596
597     if(use_midl_tlb)
598         memcpy(path, tl_path, sizeof(tl_path));
599
600     hr = LoadTypeLib(path, &pTL);
601     if(FAILED(hr)) return;
602
603
604     /* ItestIF3 is a syntax 2 dispinterface */
605     hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF3, &pTI);
606     ok(hr == S_OK, "hr %08x\n", hr);
607
608     hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
609     ok(hr == S_OK, "hr %08x\n", hr);
610     ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
611     ok(pTA->cbSizeVft == 28, "sizevft %d\n", pTA->cbSizeVft);
612     ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags);
613 if(use_midl_tlb) {
614     ok(pTA->cFuncs == 6, "cfuncs %d\n", pTA->cFuncs);
615     ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
616     ITypeInfo_ReleaseTypeAttr(pTI, pTA);
617
618     hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
619     ok(hr == S_OK, "hr %08x\n", hr);
620     hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
621     ok(hr == S_OK, "hr %08x\n", hr);
622     hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
623     ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
624     ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
625     ITypeInfo_Release(pTI_p);
626
627     /* Should have six methods */
628     hr = ITypeInfo_GetFuncDesc(pTI, 6, &pFD);
629     ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
630     hr = ITypeInfo_GetFuncDesc(pTI, 5, &pFD);
631     ok(hr == S_OK, "hr %08x\n", hr);
632     ok(pFD->memid == 0x60020000, "memid %08x\n", pFD->memid);
633     ok(pFD->oVft == 20, "oVft %d\n", pFD->oVft);
634     ITypeInfo_ReleaseFuncDesc(pTI, pFD);
635 }
636     ITypeInfo_Release(pTI);
637
638
639     /* ItestIF4 is a syntax 1 dispinterface */
640     hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF4, &pTI);
641     ok(hr == S_OK, "hr %08x\n", hr);
642
643     hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
644     ok(hr == S_OK, "hr %08x\n", hr);
645     ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
646     ok(pTA->cbSizeVft == 28, "sizevft %d\n", pTA->cbSizeVft);
647     ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags);
648     ok(pTA->cFuncs == 1, "cfuncs %d\n", pTA->cFuncs);
649     ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
650     ITypeInfo_ReleaseTypeAttr(pTI, pTA);
651
652     hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
653     ok(hr == S_OK, "hr %08x\n", hr);
654     hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
655     ok(hr == S_OK, "hr %08x\n", hr);
656     hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
657     ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
658     ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
659     ITypeInfo_Release(pTI_p);
660     hr = ITypeInfo_GetFuncDesc(pTI, 1, &pFD);
661     ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
662     hr = ITypeInfo_GetFuncDesc(pTI, 0, &pFD);
663     ok(hr == S_OK, "hr %08x\n", hr);
664     ok(pFD->memid == 0x1c, "memid %08x\n", pFD->memid);
665     ITypeInfo_ReleaseFuncDesc(pTI, pFD);
666     ITypeInfo_Release(pTI);
667
668
669     /* ItestIF5 is dual with inherited ifaces which derive from IUnknown but not IDispatch */
670     hr = ITypeLib_GetTypeInfoOfGuid(pTL, &IID_ItestIF5, &pTI);
671     ok(hr == S_OK, "hr %08x\n", hr);
672
673     hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
674     ok(hr == S_OK, "hr %08x\n", hr);
675     ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
676     ok(pTA->cbSizeVft == 28, "sizevft %d\n", pTA->cbSizeVft);
677 if(use_midl_tlb) {
678     ok(pTA->wTypeFlags == TYPEFLAG_FDUAL, "typeflags %x\n", pTA->wTypeFlags);
679  }
680     ok(pTA->cFuncs == 8, "cfuncs %d\n", pTA->cFuncs);
681     ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
682     ITypeInfo_ReleaseTypeAttr(pTI, pTA);
683
684     hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
685     ok(hr == S_OK, "hr %08x\n", hr);
686     hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
687     ok(hr == S_OK, "hr %08x\n", hr);
688     hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
689     ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
690     ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
691     ITypeInfo_Release(pTI_p);
692 if(use_midl_tlb) {
693     hr = ITypeInfo_GetFuncDesc(pTI, 6, &pFD);
694     ok(hr == S_OK, "hr %08x\n", hr);
695     ok(pFD->memid == 0x1234, "memid %08x\n", pFD->memid);
696     ITypeInfo_ReleaseFuncDesc(pTI, pFD);
697 }
698     ITypeInfo_Release(pTI);
699
700     /* ItestIF7 is dual with inherited ifaces which derive from Dispatch */
701     hr = ITypeLib_GetTypeInfoOfGuid(pTL, &IID_ItestIF7, &pTI);
702     ok(hr == S_OK, "hr %08x\n", hr);
703
704     hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
705     ok(hr == S_OK, "hr %08x\n", hr);
706     ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
707     ok(pTA->cbSizeVft == 28, "sizevft %d\n", pTA->cbSizeVft);
708     ok(pTA->wTypeFlags == (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL), "typeflags %x\n", pTA->wTypeFlags);
709     ok(pTA->cFuncs == 10, "cfuncs %d\n", pTA->cFuncs);
710     ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
711     ITypeInfo_ReleaseTypeAttr(pTI, pTA);
712
713     hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
714     ok(hr == S_OK, "hr %08x\n", hr);
715     hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
716     ok(hr == S_OK, "hr %08x\n", hr);
717     hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
718     ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
719     ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
720     ITypeInfo_Release(pTI_p);
721
722     hr = ITypeInfo_GetFuncDesc(pTI, 9, &pFD);
723     ok(hr == S_OK, "hr %08x\n", hr);
724     ok(pFD->memid == 0x1236, "memid %08x\n", pFD->memid);
725     ITypeInfo_ReleaseFuncDesc(pTI, pFD);
726     ITypeInfo_Release(pTI);
727
728     /* ItestIF10 is a syntax 2 dispinterface which doesn't derive from IUnknown */
729     hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF10, &pTI);
730     ok(hr == S_OK, "hr %08x\n", hr);
731
732     hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
733     ok(hr == S_OK, "hr %08x\n", hr);
734     ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
735     ok(pTA->cbSizeVft == 28, "sizevft %d\n", pTA->cbSizeVft);
736     ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags);
737 if(use_midl_tlb) {
738     ok(pTA->cFuncs == 3, "cfuncs %d\n", pTA->cFuncs);
739     ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
740     ITypeInfo_ReleaseTypeAttr(pTI, pTA);
741
742     hr = ITypeInfo_GetRefTypeOfImplType(pTI, -1, &href);
743     ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
744     hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
745     ok(hr == S_OK, "hr %08x\n", hr);
746     hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
747     ok(hr == S_OK, "hr %08x\n", hr);
748     hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
749     ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
750     ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
751     ITypeInfo_Release(pTI_p);
752
753     /* Should have three methods */
754     hr = ITypeInfo_GetFuncDesc(pTI, 3, &pFD);
755     ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
756     hr = ITypeInfo_GetFuncDesc(pTI, 2, &pFD);
757     ok(hr == S_OK, "hr %08x\n", hr);
758     ok(pFD->memid == 0x60010000, "memid %08x\n", pFD->memid);
759     ok(pFD->oVft == 8, "oVft %d\n", pFD->oVft);
760     ITypeInfo_ReleaseFuncDesc(pTI, pFD);
761 }
762     ITypeInfo_Release(pTI);
763
764     /* ItestIF11 is a syntax 2 dispinterface which derives from IDispatch */
765     hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF11, &pTI);
766     ok(hr == S_OK, "hr %08x\n", hr);
767
768     hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
769     ok(hr == S_OK, "hr %08x\n", hr);
770     ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
771     ok(pTA->cbSizeVft == 28, "sizevft %d\n", pTA->cbSizeVft);
772     ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags);
773 if(use_midl_tlb) {
774     ok(pTA->cFuncs == 10, "cfuncs %d\n", pTA->cFuncs);
775     ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
776     ITypeInfo_ReleaseTypeAttr(pTI, pTA);
777
778     hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
779     ok(hr == S_OK, "hr %08x\n", hr);
780     hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
781     ok(hr == S_OK, "hr %08x\n", hr);
782     hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
783     ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
784     ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
785     ITypeInfo_Release(pTI_p);
786
787     /* Should have ten methods */
788     hr = ITypeInfo_GetFuncDesc(pTI, 10, &pFD);
789     ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
790     hr = ITypeInfo_GetFuncDesc(pTI, 9, &pFD);
791     ok(hr == S_OK, "hr %08x\n", hr);
792     ok(pFD->memid == 0x1236, "memid %08x\n", pFD->memid);
793     ok(pFD->oVft == 36, "oVft %d\n", pFD->oVft);
794     ITypeInfo_ReleaseFuncDesc(pTI, pFD);
795 }
796     ITypeInfo_Release(pTI);
797
798
799     /* ItestIF2 is an interface which derives from IUnknown */
800     hr = ITypeLib_GetTypeInfoOfGuid(pTL, &IID_ItestIF2, &pTI);
801     ok(hr == S_OK, "hr %08x\n", hr);
802
803     hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
804     ok(hr == S_OK, "hr %08x\n", hr);
805     ok(pTA->typekind == TKIND_INTERFACE, "kind %04x\n", pTA->typekind);
806     ok(pTA->cbSizeVft == 24, "sizevft %d\n", pTA->cbSizeVft);
807     ok(pTA->wTypeFlags == 0, "typeflags %x\n", pTA->wTypeFlags);
808 if(use_midl_tlb) {
809     ok(pTA->cFuncs == 1, "cfuncs %d\n", pTA->cFuncs);
810     ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
811     ITypeInfo_ReleaseTypeAttr(pTI, pTA);
812
813     /* Should have one method */
814     hr = ITypeInfo_GetFuncDesc(pTI, 1, &pFD);
815     ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
816     hr = ITypeInfo_GetFuncDesc(pTI, 0, &pFD);
817     ok(hr == S_OK, "hr %08x\n", hr);
818     ok(pFD->memid == 0x60020000, "memid %08x\n", pFD->memid);
819     ok(pFD->oVft == 20, "oVft %d\n", pFD->oVft);
820     ITypeInfo_ReleaseFuncDesc(pTI, pFD);
821 }
822     ITypeInfo_Release(pTI);
823
824     ITypeLib_Release(pTL);
825
826     return;
827 }
828
829 START_TEST(typelib)
830 {
831     ref_count_test(wszStdOle2);
832     test_TypeComp();
833     test_CreateDispTypeInfo();
834     test_TypeInfo();
835     test_QueryPathOfRegTypeLib();
836     test_inheritance();
837 }