oleaut32/tests: Win64 printf format warning fixes.
[wine] / dlls / oleaut32 / tests / typelib.c
1 /*
2  * ITypeLib and ITypeInfo test
3  *
4  * Copyright 2004 Jacek Caban
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define COBJMACROS
22 #define NONAMELESSUNION
23 #define NONAMELESSSTRUCT
24
25 #include <wine/test.h>
26 #include <stdarg.h>
27
28 #include "windef.h"
29 #include "winbase.h"
30 #include "oleauto.h"
31 #include "ocidl.h"
32
33 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
34
35 static const WCHAR wszStdOle2[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
36
37 static void ref_count_test(LPCWSTR type_lib)
38 {
39     ITypeLib *iface;
40     ITypeInfo *iti1, *iti2;
41     HRESULT hRes;
42     int ref_count;
43
44     trace("Loading type library\n");
45     hRes = LoadTypeLib(type_lib, &iface);
46     ok(hRes == S_OK, "Could not load type library\n");
47     if(hRes != S_OK)
48         return;
49
50     hRes = ITypeLib_GetTypeInfo(iface, 1, &iti1);
51     ok(hRes == S_OK, "ITypeLib_GetTypeInfo failed on index = 1\n");
52     ok(ref_count=ITypeLib_Release(iface) > 0, "ITypeLib destroyed while ITypeInfo has back pointer\n");
53     if(!ref_count)
54         return;
55
56     hRes = ITypeLib_GetTypeInfo(iface, 1, &iti2);
57     ok(hRes == S_OK, "ITypeLib_GetTypeInfo failed on index = 1\n");
58     ok(iti1 == iti2, "ITypeLib_GetTypeInfo returned different pointers for same indexes\n");
59
60     ITypeLib_AddRef(iface);
61     ITypeInfo_Release(iti2);
62     ITypeInfo_Release(iti1);
63     ok(ITypeLib_Release(iface) == 0, "ITypeLib should be destroyed here.\n");
64 }
65
66 static void test_TypeComp(void)
67 {
68     ITypeLib *pTypeLib;
69     ITypeComp *pTypeComp;
70     HRESULT hr;
71     ULONG ulHash;
72     DESCKIND desckind;
73     BINDPTR bindptr;
74     ITypeInfo *pTypeInfo;
75     ITypeInfo *pFontTypeInfo;
76     static WCHAR wszStdFunctions[] = {'S','t','d','F','u','n','c','t','i','o','n','s',0};
77     static WCHAR wszSavePicture[] = {'S','a','v','e','P','i','c','t','u','r','e',0};
78     static WCHAR wszOLE_TRISTATE[] = {'O','L','E','_','T','R','I','S','T','A','T','E',0};
79     static WCHAR wszUnchecked[] = {'U','n','c','h','e','c','k','e','d',0};
80     static WCHAR wszIUnknown[] = {'I','U','n','k','n','o','w','n',0};
81     static WCHAR wszFont[] = {'F','o','n','t',0};
82     static WCHAR wszGUID[] = {'G','U','I','D',0};
83     static WCHAR wszStdPicture[] = {'S','t','d','P','i','c','t','u','r','e',0};
84     static WCHAR wszOLE_COLOR[] = {'O','L','E','_','C','O','L','O','R',0};
85     static WCHAR wszClone[] = {'C','l','o','n','e',0};
86     static WCHAR wszclone[] = {'c','l','o','n','e',0};
87
88     hr = LoadTypeLib(wszStdOle2, &pTypeLib);
89     ok_ole_success(hr, LoadTypeLib);
90
91     hr = ITypeLib_GetTypeComp(pTypeLib, &pTypeComp);
92     ok_ole_success(hr, ITypeLib_GetTypeComp);
93
94     /* test getting a TKIND_MODULE */
95     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdFunctions);
96     hr = ITypeComp_Bind(pTypeComp, wszStdFunctions, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
97     ok_ole_success(hr, ITypeComp_Bind);
98
99     ok(desckind == DESCKIND_TYPECOMP,
100         "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
101         desckind);
102     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
103
104     ITypeComp_Release(bindptr.lptcomp);
105
106     /* test getting a TKIND_MODULE with INVOKE_PROPERTYGET */
107     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdFunctions);
108     hr = ITypeComp_Bind(pTypeComp, wszStdFunctions, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
109     ok_ole_success(hr, ITypeComp_Bind);
110
111     ok(desckind == DESCKIND_TYPECOMP,
112         "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
113         desckind);
114     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
115
116     /* test getting a function within a TKIND_MODULE */
117     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszSavePicture);
118     hr = ITypeComp_Bind(pTypeComp, wszSavePicture, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
119     ok_ole_success(hr, ITypeComp_Bind);
120
121     ok(desckind == DESCKIND_FUNCDESC,
122         "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
123         desckind);
124     ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
125     ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
126     ITypeInfo_Release(pTypeInfo);
127
128     /* test getting a function within a TKIND_MODULE with INVOKE_PROPERTYGET */
129     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszSavePicture);
130     hr = ITypeComp_Bind(pTypeComp, wszSavePicture, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
131     todo_wine ok(hr == TYPE_E_TYPEMISMATCH,
132         "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n",
133         hr);
134
135     ok(desckind == DESCKIND_NONE,
136         "desckind should have been DESCKIND_NONE instead of %d\n",
137         desckind);
138     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
139     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
140
141     /* test getting a TKIND_ENUM */
142     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszOLE_TRISTATE);
143     hr = ITypeComp_Bind(pTypeComp, wszOLE_TRISTATE, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
144     ok_ole_success(hr, ITypeComp_Bind);
145
146     ok(desckind == DESCKIND_TYPECOMP,
147         "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
148         desckind);
149     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
150
151     ITypeComp_Release(bindptr.lptcomp);
152
153     /* test getting a value within a TKIND_ENUM */
154     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszUnchecked);
155     hr = ITypeComp_Bind(pTypeComp, wszUnchecked, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
156     ok_ole_success(hr, ITypeComp_Bind);
157
158     ok(desckind == DESCKIND_VARDESC,
159         "desckind should have been DESCKIND_VARDESC instead of %d\n",
160         desckind);
161     ITypeInfo_ReleaseVarDesc(pTypeInfo, bindptr.lpvardesc);
162     ITypeInfo_Release(pTypeInfo);
163
164     /* test getting a TKIND_INTERFACE */
165     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszIUnknown);
166     hr = ITypeComp_Bind(pTypeComp, wszIUnknown, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
167     ok_ole_success(hr, ITypeComp_Bind);
168
169     ok(desckind == DESCKIND_NONE,
170         "desckind should have been DESCKIND_NONE instead of %d\n",
171         desckind);
172     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
173     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
174
175     /* test getting a TKIND_DISPATCH */
176     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszFont);
177     hr = ITypeComp_Bind(pTypeComp, wszFont, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
178     ok_ole_success(hr, ITypeComp_Bind);
179
180     ok(desckind == DESCKIND_NONE,
181         "desckind should have been DESCKIND_NONE instead of %d\n",
182         desckind);
183     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
184     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
185
186     /* test getting a TKIND_RECORD/TKIND_ALIAS */
187     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
188     hr = ITypeComp_Bind(pTypeComp, wszGUID, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
189     ok_ole_success(hr, ITypeComp_Bind);
190
191     ok(desckind == DESCKIND_NONE,
192         "desckind should have been DESCKIND_NONE instead of %d\n",
193         desckind);
194     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
195     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
196
197     /* test getting a TKIND_ALIAS */
198     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszOLE_COLOR);
199     hr = ITypeComp_Bind(pTypeComp, wszOLE_COLOR, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
200     ok_ole_success(hr, ITypeComp_Bind);
201
202     ok(desckind == DESCKIND_NONE,
203         "desckind should have been DESCKIND_NONE instead of %d\n",
204         desckind);
205     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
206     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
207
208     /* test getting a TKIND_COCLASS */
209     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdPicture);
210     hr = ITypeComp_Bind(pTypeComp, wszStdPicture, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
211     ok_ole_success(hr, ITypeComp_Bind);
212
213     ok(desckind == DESCKIND_NONE,
214         "desckind should have been DESCKIND_NONE instead of %d\n",
215         desckind);
216     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
217     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
218
219     ITypeComp_Release(pTypeComp);
220
221     /* tests for ITypeComp on an interface */
222     hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IFont, &pFontTypeInfo);
223     ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
224
225     hr = ITypeInfo_GetTypeComp(pFontTypeInfo, &pTypeComp);
226     ok_ole_success(hr, ITypeLib_GetTypeComp);
227
228     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszClone);
229     hr = ITypeComp_Bind(pTypeComp, wszClone, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
230     ok_ole_success(hr, ITypeComp_Bind);
231
232     ok(desckind == DESCKIND_FUNCDESC,
233         "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
234         desckind);
235     ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
236     ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
237     ITypeInfo_Release(pTypeInfo);
238
239     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszClone);
240     hr = ITypeComp_Bind(pTypeComp, wszClone, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
241     ok(hr == TYPE_E_TYPEMISMATCH, "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n", hr);
242
243     ok(desckind == DESCKIND_NONE,
244         "desckind should have been DESCKIND_NONE instead of %d\n",
245         desckind);
246     ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
247     ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
248
249     /* tests that the compare is case-insensitive */
250     ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszclone);
251     hr = ITypeComp_Bind(pTypeComp, wszclone, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
252     ok_ole_success(hr, ITypeComp_Bind);
253
254     ok(desckind == DESCKIND_FUNCDESC,
255         "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
256         desckind);
257     ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
258     ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
259     ITypeInfo_Release(pTypeInfo);
260
261     ITypeComp_Release(pTypeComp);
262     ITypeInfo_Release(pFontTypeInfo);
263     ITypeLib_Release(pTypeLib);
264 }
265
266 static void test_CreateDispTypeInfo(void)
267 {
268     ITypeInfo *pTypeInfo, *pTI2;
269     HRESULT hr;
270     INTERFACEDATA ifdata;
271     METHODDATA methdata[4];
272     PARAMDATA parms1[2];
273     PARAMDATA parms3[1];
274     TYPEATTR *pTypeAttr;
275     HREFTYPE href;
276     FUNCDESC *pFuncDesc;
277     MEMBERID memid;
278
279     static const WCHAR func1[] = {'f','u','n','c','1',0};
280     static const WCHAR func2[] = {'f','u','n','c','2',0};
281     static const WCHAR func3[] = {'f','u','n','c','3',0};
282     static const WCHAR parm1[] = {'p','a','r','m','1',0};
283     static const WCHAR parm2[] = {'p','a','r','m','2',0};
284     OLECHAR *name = (OLECHAR *)func1;
285
286     ifdata.pmethdata = methdata;
287     ifdata.cMembers = sizeof(methdata) / sizeof(methdata[0]);
288
289     methdata[0].szName = SysAllocString(func1);
290     methdata[0].ppdata = parms1;
291     methdata[0].dispid = 0x123;
292     methdata[0].iMeth = 0;
293     methdata[0].cc = CC_STDCALL;
294     methdata[0].cArgs = 2;
295     methdata[0].wFlags = DISPATCH_METHOD;
296     methdata[0].vtReturn = VT_HRESULT;
297     parms1[0].szName = SysAllocString(parm1);
298     parms1[0].vt = VT_I4;
299     parms1[1].szName = SysAllocString(parm2);
300     parms1[1].vt = VT_BSTR;
301
302     methdata[1].szName = SysAllocString(func2);
303     methdata[1].ppdata = NULL;
304     methdata[1].dispid = 0x124;
305     methdata[1].iMeth = 1;
306     methdata[1].cc = CC_STDCALL;
307     methdata[1].cArgs = 0;
308     methdata[1].wFlags = DISPATCH_PROPERTYGET;
309     methdata[1].vtReturn = VT_I4;
310
311     methdata[2].szName = SysAllocString(func3);
312     methdata[2].ppdata = parms3;
313     methdata[2].dispid = 0x125;
314     methdata[2].iMeth = 3;
315     methdata[2].cc = CC_STDCALL;
316     methdata[2].cArgs = 1;
317     methdata[2].wFlags = DISPATCH_PROPERTYPUT;
318     methdata[2].vtReturn = VT_HRESULT;
319     parms3[0].szName = SysAllocString(parm1);
320     parms3[0].vt = VT_I4;
321
322     methdata[3].szName = SysAllocString(func3);
323     methdata[3].ppdata = NULL;
324     methdata[3].dispid = 0x125;
325     methdata[3].iMeth = 4;
326     methdata[3].cc = CC_STDCALL;
327     methdata[3].cArgs = 0;
328     methdata[3].wFlags = DISPATCH_PROPERTYGET;
329     methdata[3].vtReturn = VT_I4;
330
331     hr = CreateDispTypeInfo(&ifdata, LOCALE_NEUTRAL, &pTypeInfo);
332     ok(hr == S_OK, "hr %08x\n", hr);
333
334     hr = ITypeInfo_GetTypeAttr(pTypeInfo, &pTypeAttr);
335     ok(hr == S_OK, "hr %08x\n", hr);
336
337     ok(pTypeAttr->typekind == TKIND_COCLASS, "typekind %0x\n", pTypeAttr->typekind);
338     ok(pTypeAttr->cImplTypes == 1, "cImplTypes %d\n", pTypeAttr->cImplTypes);
339     ok(pTypeAttr->cFuncs == 0, "cFuncs %d\n", pTypeAttr->cFuncs);
340     ok(pTypeAttr->wTypeFlags == 0, "wTypeFlags %04x\n", pTypeAttr->cFuncs);
341     ITypeInfo_ReleaseTypeAttr(pTypeInfo, pTypeAttr);
342
343     hr = ITypeInfo_GetRefTypeOfImplType(pTypeInfo, 0, &href);
344     ok(hr == S_OK, "hr %08x\n", hr);
345     todo_wine {
346     ok(href == 0, "href = 0x%x\n", href);
347     }
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     ITypeInfo_ReleaseTypeAttr(pTI2, pTypeAttr);
354
355     hr = ITypeInfo_GetFuncDesc(pTI2, 0, &pFuncDesc);
356     ok(hr == S_OK, "hr %08x\n", hr);
357     ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
358     ok(pFuncDesc->invkind == methdata[0].wFlags, "invkind %d\n", pFuncDesc->invkind);
359     ok(pFuncDesc->callconv == methdata[0].cc, "callconv %d\n", pFuncDesc->callconv);
360     ok(pFuncDesc->cParams == methdata[0].cArgs, "cParams %d\n", pFuncDesc->cParams);
361     ok(pFuncDesc->oVft == 0, "oVft %d\n", pFuncDesc->oVft);
362     ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
363     ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
364     ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
365     ok(pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags);
366
367     ok(pFuncDesc->lprgelemdescParam[1].tdesc.vt == VT_BSTR, "parm 1 vt %x\n", pFuncDesc->lprgelemdescParam[1].tdesc.vt);
368     ok(pFuncDesc->lprgelemdescParam[1].u.paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 1 flags %x\n", pFuncDesc->lprgelemdescParam[1].u.paramdesc.wParamFlags);
369     ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
370
371     hr = ITypeInfo_GetFuncDesc(pTI2, 1, &pFuncDesc);
372     ok(hr == S_OK, "hr %08x\n", hr);
373     ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
374     ok(pFuncDesc->invkind == methdata[1].wFlags, "invkind %d\n", pFuncDesc->invkind);
375     ok(pFuncDesc->callconv == methdata[1].cc, "callconv %d\n", pFuncDesc->callconv);
376     ok(pFuncDesc->cParams == methdata[1].cArgs, "cParams %d\n", pFuncDesc->cParams);
377     ok(pFuncDesc->oVft == 4, "oVft %d\n", pFuncDesc->oVft);
378     ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
379     ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
380     ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
381
382     hr = ITypeInfo_GetFuncDesc(pTI2, 2, &pFuncDesc);
383     ok(hr == S_OK, "hr %08x\n", hr);
384     ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
385     ok(pFuncDesc->invkind == methdata[2].wFlags, "invkind %d\n", pFuncDesc->invkind);
386     ok(pFuncDesc->callconv == methdata[2].cc, "callconv %d\n", pFuncDesc->callconv);
387     ok(pFuncDesc->cParams == methdata[2].cArgs, "cParams %d\n", pFuncDesc->cParams);
388     ok(pFuncDesc->oVft == 12, "oVft %d\n", pFuncDesc->oVft);
389     ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
390     ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
391     ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
392     ok(pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags);
393     ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
394
395     hr = ITypeInfo_GetFuncDesc(pTI2, 3, &pFuncDesc);
396     ok(hr == S_OK, "hr %08x\n", hr);
397     ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
398     ok(pFuncDesc->invkind == methdata[3].wFlags, "invkind %d\n", pFuncDesc->invkind);
399     ok(pFuncDesc->callconv == methdata[3].cc, "callconv %d\n", pFuncDesc->callconv);
400     ok(pFuncDesc->cParams == methdata[3].cArgs, "cParams %d\n", pFuncDesc->cParams);
401     ok(pFuncDesc->oVft == 16, "oVft %d\n", pFuncDesc->oVft);
402     ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
403     ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
404     ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
405
406     /* test GetIDsOfNames on a coclass to see if it searches its interfaces */
407     hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &name, 1, &memid);
408     ok(hr == S_OK, "hr 0x%08x\n", hr);
409     ok(memid == 0x123, "memid 0x%08x\n", memid);
410
411     ITypeInfo_Release(pTI2);
412     ITypeInfo_Release(pTypeInfo);
413
414     SysFreeString(parms1[0].szName);
415     SysFreeString(parms1[1].szName);
416     SysFreeString(parms3[0].szName);
417     SysFreeString(methdata[0].szName);
418     SysFreeString(methdata[1].szName);
419     SysFreeString(methdata[2].szName);
420     SysFreeString(methdata[3].szName);
421 }
422
423 static void test_TypeInfo(void)
424 {
425     ITypeLib *pTypeLib;
426     ITypeInfo *pTypeInfo;
427     HRESULT hr;
428     static WCHAR wszBogus[] = { 'b','o','g','u','s',0 };
429     static WCHAR wszGetTypeInfo[] = { 'G','e','t','T','y','p','e','I','n','f','o',0 };
430     static WCHAR wszClone[] = {'C','l','o','n','e',0};
431     OLECHAR* bogus = wszBogus;
432     OLECHAR* pwszGetTypeInfo = wszGetTypeInfo;
433     OLECHAR* pwszClone = wszClone;
434     DISPID dispidMember;
435     DISPPARAMS dispparams;
436
437     hr = LoadTypeLib(wszStdOle2, &pTypeLib);
438     ok_ole_success(hr, LoadTypeLib);
439
440     hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IFont, &pTypeInfo);
441     ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid); 
442
443     /* test nonexistent method name */
444     hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &bogus, 1, &dispidMember);
445     ok(hr == DISP_E_UNKNOWNNAME,
446        "ITypeInfo_GetIDsOfNames should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n",
447        hr);
448
449     /* test invalid memberid */
450     dispparams.cNamedArgs = 0;
451     dispparams.cArgs = 0;
452     dispparams.rgdispidNamedArgs = NULL;
453     dispparams.rgvarg = NULL;
454     hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
455     ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
456
457     hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &pwszClone, 1, &dispidMember);
458     ok_ole_success(hr, ITypeInfo_GetIDsOfNames);
459
460     /* test correct memberid, but wrong flags */
461     hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
462     ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
463
464     /* test NULL dispparams */
465     hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, NULL, NULL, NULL, NULL);
466     ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
467
468     /* test dispparams->cNamedArgs being bigger than dispparams->cArgs */
469     dispparams.cNamedArgs = 1;
470     hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
471     ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
472
473     ITypeInfo_Release(pTypeInfo);
474
475     hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IDispatch, &pTypeInfo);
476     ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid); 
477
478     hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &pwszGetTypeInfo, 1, &dispidMember);
479     ok_ole_success(hr, ITypeInfo_GetIDsOfNames);
480
481     /* test invoking a method with a [restricted] keyword */
482     hr = ITypeInfo_Invoke(pTypeInfo, NULL, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
483     todo_wine {
484     ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
485     }
486
487     ITypeInfo_Release(pTypeInfo);
488     ITypeLib_Release(pTypeLib);
489 }
490
491 START_TEST(typelib)
492 {
493     ref_count_test(wszStdOle2);
494     test_TypeComp();
495     test_CreateDispTypeInfo();
496     test_TypeInfo();
497 }