Release 0.9.39.
[wine/gsoc-2012-control.git] / dlls / oleaut32 / tests / typelib.c
blobd19afd3038af08bd068c507f2f43a8381329721d
1 /*
2 * ITypeLib and ITypeInfo test
4 * Copyright 2004 Jacek Caban
5 * Copyright 2006 Dmitry Timoshkov
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.
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.
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
22 #define COBJMACROS
24 #include <wine/test.h>
25 #include <stdarg.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "oleauto.h"
30 #include "ocidl.h"
31 #include "shlwapi.h"
32 #include "tmarshal.h"
34 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
36 static const WCHAR wszStdOle2[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
38 static void ref_count_test(LPCWSTR type_lib)
40 ITypeLib *iface;
41 ITypeInfo *iti1, *iti2;
42 HRESULT hRes;
43 int ref_count;
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;
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;
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");
61 ITypeLib_AddRef(iface);
62 ITypeInfo_Release(iti2);
63 ITypeInfo_Release(iti1);
64 ok(ITypeLib_Release(iface) == 0, "ITypeLib should be destroyed here.\n");
67 static void test_TypeComp(void)
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};
89 hr = LoadTypeLib(wszStdOle2, &pTypeLib);
90 ok_ole_success(hr, LoadTypeLib);
92 hr = ITypeLib_GetTypeComp(pTypeLib, &pTypeComp);
93 ok_ole_success(hr, ITypeLib_GetTypeComp);
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);
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");
105 ITypeComp_Release(bindptr.lptcomp);
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);
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);
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);
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);
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);
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");
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);
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");
153 ITypeComp_Release(bindptr.lptcomp);
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);
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);
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);
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");
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);
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");
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);
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");
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);
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");
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);
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");
221 ITypeComp_Release(pTypeComp);
223 /* tests for ITypeComp on an interface */
224 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IFont, &pFontTypeInfo);
225 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
227 hr = ITypeInfo_GetTypeComp(pFontTypeInfo, &pTypeComp);
228 ok_ole_success(hr, ITypeLib_GetTypeComp);
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);
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);
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);
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");
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);
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);
263 ITypeComp_Release(pTypeComp);
264 ITypeInfo_Release(pFontTypeInfo);
265 ITypeLib_Release(pTypeLib);
268 static void test_CreateDispTypeInfo(void)
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;
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;
288 ifdata.pmethdata = methdata;
289 ifdata.cMembers = sizeof(methdata) / sizeof(methdata[0]);
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;
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;
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;
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;
333 hr = CreateDispTypeInfo(&ifdata, LOCALE_NEUTRAL, &pTypeInfo);
334 ok(hr == S_OK, "hr %08x\n", hr);
336 hr = ITypeInfo_GetTypeAttr(pTypeInfo, &pTypeAttr);
337 ok(hr == S_OK, "hr %08x\n", hr);
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);
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);
357 ITypeInfo_ReleaseTypeAttr(pTI2, pTypeAttr);
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);
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);
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);
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);
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);
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);
416 ITypeInfo_Release(pTI2);
417 ITypeInfo_Release(pTypeInfo);
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);
428 static void test_TypeInfo(void)
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;
442 hr = LoadTypeLib(wszStdOle2, &pTypeLib);
443 ok_ole_success(hr, LoadTypeLib);
445 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IFont, &pTypeInfo);
446 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
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);
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);
462 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &pwszClone, 1, &dispidMember);
463 ok_ole_success(hr, ITypeInfo_GetIDsOfNames);
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);
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);
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);
478 ITypeInfo_Release(pTypeInfo);
480 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IDispatch, &pTypeInfo);
481 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
483 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &pwszGetTypeInfo, 1, &dispidMember);
484 ok_ole_success(hr, ITypeInfo_GetIDsOfNames);
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);
492 ITypeInfo_Release(pTypeInfo);
493 ITypeLib_Release(pTypeLib);
496 static BOOL do_typelib_reg_key(GUID *uid, WORD maj, WORD min, LPCWSTR base, BOOL remove)
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;
505 memcpy(buf, typelibW, sizeof(typelibW));
506 StringFromGUID2(uid, buf + lstrlenW(buf), 40);
508 if (remove)
510 ok(SHDeleteKeyW(HKEY_CLASSES_ROOT, buf) == ERROR_SUCCESS, "SHDeleteKey failed\n");
511 return TRUE;
514 wsprintfW(buf + lstrlenW(buf), formatW, maj, min );
516 if (RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0,
517 KEY_WRITE, NULL, &hkey, NULL) != ERROR_SUCCESS)
519 trace("RegCreateKeyExW failed\n");
520 return FALSE;
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)
527 trace("RegSetValueExW failed\n");
528 ret = FALSE;
530 RegCloseKey(hkey);
531 return ret;
534 static void test_QueryPathOfRegTypeLib(void)
536 static const struct test_data
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 } }
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;
558 status = UuidCreate(&uid);
559 ok(!status, "UuidCreate error %08lx\n", status);
561 StringFromGUID2(&uid, uid_str, 40);
562 /*trace("GUID: %s\n", wine_dbgstr_w(uid_str));*/
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;
568 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
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)
574 ok(!lstrcmpW(td[i].path, path), "typelib %u.%u path doesn't match\n", td[i].maj, td[i].min);
575 SysFreeString(path);
579 do_typelib_reg_key(&uid, 0, 0, NULL, 1);
582 static void test_inheritance(void)
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};
593 BOOL use_midl_tlb = 0;
595 GetModuleFileNameW(NULL, path, MAX_PATH);
597 if(use_midl_tlb)
598 memcpy(path, tl_path, sizeof(tl_path));
600 hr = LoadTypeLib(path, &pTL);
601 if(FAILED(hr)) return;
604 /* ItestIF3 is a syntax 2 dispinterface */
605 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF3, &pTI);
606 ok(hr == S_OK, "hr %08x\n", hr);
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);
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);
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);
636 ITypeInfo_Release(pTI);
639 /* ItestIF4 is a syntax 1 dispinterface */
640 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF4, &pTI);
641 ok(hr == S_OK, "hr %08x\n", hr);
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);
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);
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);
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);
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);
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);
698 ITypeInfo_Release(pTI);
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);
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);
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);
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);
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);
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);
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);
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);
762 ITypeInfo_Release(pTI);
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);
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);
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);
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);
796 ITypeInfo_Release(pTI);
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);
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);
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);
822 ITypeInfo_Release(pTI);
824 ITypeLib_Release(pTL);
826 return;
829 START_TEST(typelib)
831 ref_count_test(wszStdOle2);
832 test_TypeComp();
833 test_CreateDispTypeInfo();
834 test_TypeInfo();
835 test_QueryPathOfRegTypeLib();
836 test_inheritance();