2 * ITypeLib and ITypeInfo test
4 * Copyright 2004 Jacek Caban
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #define NONAMELESSUNION
23 #define NONAMELESSSTRUCT
25 #include <wine/test.h>
32 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08lx\n", hr)
34 static const WCHAR wszStdOle2[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
36 static void ref_count_test(LPCWSTR type_lib)
39 ITypeInfo *iti1, *iti2;
43 trace("Loading type library\n");
44 hRes = LoadTypeLib(type_lib, &iface);
45 ok(hRes == S_OK, "Could not load type library\n");
49 hRes = ITypeLib_GetTypeInfo(iface, 1, &iti1);
50 ok(hRes == S_OK, "ITypeLib_GetTypeInfo failed on index = 1\n");
51 ok(ref_count=ITypeLib_Release(iface) > 0, "ITypeLib destroyed while ITypeInfo has back pointer\n");
55 hRes = ITypeLib_GetTypeInfo(iface, 1, &iti2);
56 ok(hRes == S_OK, "ITypeLib_GetTypeInfo failed on index = 1\n");
57 ok(iti1 == iti2, "ITypeLib_GetTypeInfo returned different pointers for same indexes\n");
59 ITypeLib_AddRef(iface);
60 ITypeInfo_Release(iti2);
61 ITypeInfo_Release(iti1);
62 ok(ITypeLib_Release(iface) == 0, "ITypeLib should be destroyed here.\n");
65 static void test_TypeComp(void)
74 static WCHAR wszStdFunctions[] = {'S','t','d','F','u','n','c','t','i','o','n','s',0};
75 static WCHAR wszSavePicture[] = {'S','a','v','e','P','i','c','t','u','r','e',0};
76 static WCHAR wszOLE_TRISTATE[] = {'O','L','E','_','T','R','I','S','T','A','T','E',0};
77 static WCHAR wszUnchecked[] = {'U','n','c','h','e','c','k','e','d',0};
78 static WCHAR wszIUnknown[] = {'I','U','n','k','n','o','w','n',0};
79 static WCHAR wszFont[] = {'F','o','n','t',0};
80 static WCHAR wszGUID[] = {'G','U','I','D',0};
81 static WCHAR wszStdPicture[] = {'S','t','d','P','i','c','t','u','r','e',0};
82 static WCHAR wszOLE_COLOR[] = {'O','L','E','_','C','O','L','O','R',0};
84 hr = LoadTypeLib(wszStdOle2, &pTypeLib);
85 ok_ole_success(hr, LoadTypeLib);
87 hr = ITypeLib_GetTypeComp(pTypeLib, &pTypeComp);
88 ok_ole_success(hr, ITypeLib_GetTypeComp);
90 /* test getting a TKIND_MODULE */
91 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdFunctions);
92 hr = ITypeComp_Bind(pTypeComp, wszStdFunctions, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
93 ok_ole_success(hr, ITypeComp_Bind);
95 ok(desckind == DESCKIND_TYPECOMP,
96 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
98 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
100 ITypeComp_Release(bindptr.lptcomp);
102 /* test getting a TKIND_MODULE with INVOKE_PROPERTYGET */
103 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdFunctions);
104 hr = ITypeComp_Bind(pTypeComp, wszStdFunctions, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
105 ok_ole_success(hr, ITypeComp_Bind);
107 ok(desckind == DESCKIND_TYPECOMP,
108 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
110 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
112 /* test getting a function within a TKIND_MODULE */
113 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszSavePicture);
114 hr = ITypeComp_Bind(pTypeComp, wszSavePicture, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
115 ok_ole_success(hr, ITypeComp_Bind);
117 ok(desckind == DESCKIND_FUNCDESC,
118 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
120 ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
121 ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
122 ITypeInfo_Release(pTypeInfo);
124 /* test getting a function within a TKIND_MODULE with INVOKE_PROPERTYGET */
125 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszSavePicture);
126 hr = ITypeComp_Bind(pTypeComp, wszSavePicture, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
127 todo_wine ok(hr == TYPE_E_TYPEMISMATCH,
128 "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08lx\n",
131 ok(desckind == DESCKIND_NONE,
132 "desckind should have been DESCKIND_NONE instead of %d\n",
134 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
135 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
137 /* test getting a TKIND_ENUM */
138 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszOLE_TRISTATE);
139 hr = ITypeComp_Bind(pTypeComp, wszOLE_TRISTATE, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
140 ok_ole_success(hr, ITypeComp_Bind);
142 ok(desckind == DESCKIND_TYPECOMP,
143 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
145 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
147 ITypeComp_Release(bindptr.lptcomp);
149 /* test getting a value within a TKIND_ENUM */
150 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszUnchecked);
151 hr = ITypeComp_Bind(pTypeComp, wszUnchecked, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
152 ok_ole_success(hr, ITypeComp_Bind);
154 ok(desckind == DESCKIND_VARDESC,
155 "desckind should have been DESCKIND_VARDESC instead of %d\n",
157 ITypeInfo_ReleaseVarDesc(pTypeInfo, bindptr.lpvardesc);
158 ITypeInfo_Release(pTypeInfo);
160 /* test getting a TKIND_INTERFACE */
161 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszIUnknown);
162 hr = ITypeComp_Bind(pTypeComp, wszIUnknown, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
163 ok_ole_success(hr, ITypeComp_Bind);
165 ok(desckind == DESCKIND_NONE,
166 "desckind should have been DESCKIND_NONE instead of %d\n",
168 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
169 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
171 /* test getting a TKIND_DISPATCH */
172 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszFont);
173 hr = ITypeComp_Bind(pTypeComp, wszFont, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
174 ok_ole_success(hr, ITypeComp_Bind);
176 ok(desckind == DESCKIND_NONE,
177 "desckind should have been DESCKIND_NONE instead of %d\n",
179 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
180 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
182 /* test getting a TKIND_RECORD/TKIND_ALIAS */
183 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
184 hr = ITypeComp_Bind(pTypeComp, wszGUID, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
185 ok_ole_success(hr, ITypeComp_Bind);
187 ok(desckind == DESCKIND_NONE,
188 "desckind should have been DESCKIND_NONE instead of %d\n",
190 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
191 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
193 /* test getting a TKIND_ALIAS */
194 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszOLE_COLOR);
195 hr = ITypeComp_Bind(pTypeComp, wszOLE_COLOR, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
196 ok_ole_success(hr, ITypeComp_Bind);
198 ok(desckind == DESCKIND_NONE,
199 "desckind should have been DESCKIND_NONE instead of %d\n",
201 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
202 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
204 /* test getting a TKIND_COCLASS */
205 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdPicture);
206 hr = ITypeComp_Bind(pTypeComp, wszStdPicture, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
207 ok_ole_success(hr, ITypeComp_Bind);
209 ok(desckind == DESCKIND_NONE,
210 "desckind should have been DESCKIND_NONE instead of %d\n",
212 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
213 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
215 ITypeComp_Release(pTypeComp);
216 ITypeLib_Release(pTypeLib);
219 static void test_CreateDispTypeInfo(void)
221 ITypeInfo *pTypeInfo, *pTI2;
223 INTERFACEDATA ifdata;
224 METHODDATA methdata[4];
232 static const WCHAR func1[] = {'f','u','n','c','1',0};
233 static const WCHAR func2[] = {'f','u','n','c','2',0};
234 static const WCHAR func3[] = {'f','u','n','c','3',0};
235 static const WCHAR parm1[] = {'p','a','r','m','1',0};
236 static const WCHAR parm2[] = {'p','a','r','m','2',0};
237 OLECHAR *name = (OLECHAR *)func1;
239 ifdata.pmethdata = methdata;
240 ifdata.cMembers = sizeof(methdata) / sizeof(methdata[0]);
242 methdata[0].szName = SysAllocString(func1);
243 methdata[0].ppdata = parms1;
244 methdata[0].dispid = 0x123;
245 methdata[0].iMeth = 0;
246 methdata[0].cc = CC_STDCALL;
247 methdata[0].cArgs = 2;
248 methdata[0].wFlags = DISPATCH_METHOD;
249 methdata[0].vtReturn = VT_HRESULT;
250 parms1[0].szName = SysAllocString(parm1);
251 parms1[0].vt = VT_I4;
252 parms1[1].szName = SysAllocString(parm2);
253 parms1[1].vt = VT_BSTR;
255 methdata[1].szName = SysAllocString(func2);
256 methdata[1].ppdata = NULL;
257 methdata[1].dispid = 0x124;
258 methdata[1].iMeth = 1;
259 methdata[1].cc = CC_STDCALL;
260 methdata[1].cArgs = 0;
261 methdata[1].wFlags = DISPATCH_PROPERTYGET;
262 methdata[1].vtReturn = VT_I4;
264 methdata[2].szName = SysAllocString(func3);
265 methdata[2].ppdata = parms3;
266 methdata[2].dispid = 0x125;
267 methdata[2].iMeth = 3;
268 methdata[2].cc = CC_STDCALL;
269 methdata[2].cArgs = 1;
270 methdata[2].wFlags = DISPATCH_PROPERTYPUT;
271 methdata[2].vtReturn = VT_HRESULT;
272 parms3[0].szName = SysAllocString(parm1);
273 parms3[0].vt = VT_I4;
275 methdata[3].szName = SysAllocString(func3);
276 methdata[3].ppdata = NULL;
277 methdata[3].dispid = 0x125;
278 methdata[3].iMeth = 4;
279 methdata[3].cc = CC_STDCALL;
280 methdata[3].cArgs = 0;
281 methdata[3].wFlags = DISPATCH_PROPERTYGET;
282 methdata[3].vtReturn = VT_I4;
284 hr = CreateDispTypeInfo(&ifdata, LOCALE_NEUTRAL, &pTypeInfo);
285 ok(hr == S_OK, "hr %08lx\n", hr);
287 hr = ITypeInfo_GetTypeAttr(pTypeInfo, &pTypeAttr);
288 ok(hr == S_OK, "hr %08lx\n", hr);
290 ok(pTypeAttr->typekind == TKIND_COCLASS, "typekind %0x\n", pTypeAttr->typekind);
291 ok(pTypeAttr->cImplTypes == 1, "cImplTypes %d\n", pTypeAttr->cImplTypes);
292 ok(pTypeAttr->cFuncs == 0, "cFuncs %d\n", pTypeAttr->cFuncs);
293 ok(pTypeAttr->wTypeFlags == 0, "wTypeFlags %04x\n", pTypeAttr->cFuncs);
294 ITypeInfo_ReleaseTypeAttr(pTypeInfo, pTypeAttr);
296 hr = ITypeInfo_GetRefTypeOfImplType(pTypeInfo, 0, &href);
297 ok(hr == S_OK, "hr %08lx\n", hr);
299 ok(href == 0, "href = 0x%lx\n", href);
301 hr = ITypeInfo_GetRefTypeInfo(pTypeInfo, href, &pTI2);
302 ok(hr == S_OK, "hr %08lx\n", hr);
303 hr = ITypeInfo_GetTypeAttr(pTI2, &pTypeAttr);
304 ok(hr == S_OK, "hr %08lx\n", hr);
305 ok(pTypeAttr->typekind == TKIND_INTERFACE, "typekind %0x\n", pTypeAttr->typekind);
306 ITypeInfo_ReleaseTypeAttr(pTI2, pTypeAttr);
308 hr = ITypeInfo_GetFuncDesc(pTI2, 0, &pFuncDesc);
309 ok(hr == S_OK, "hr %08lx\n", hr);
310 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
311 ok(pFuncDesc->invkind == methdata[0].wFlags, "invkind %d\n", pFuncDesc->invkind);
312 ok(pFuncDesc->callconv == methdata[0].cc, "callconv %d\n", pFuncDesc->callconv);
313 ok(pFuncDesc->cParams == methdata[0].cArgs, "cParams %d\n", pFuncDesc->cParams);
314 ok(pFuncDesc->oVft == 0, "oVft %d\n", pFuncDesc->oVft);
315 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
316 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
317 ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
318 ok(pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags);
320 ok(pFuncDesc->lprgelemdescParam[1].tdesc.vt == VT_BSTR, "parm 1 vt %x\n", pFuncDesc->lprgelemdescParam[1].tdesc.vt);
321 ok(pFuncDesc->lprgelemdescParam[1].u.paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 1 flags %x\n", pFuncDesc->lprgelemdescParam[1].u.paramdesc.wParamFlags);
322 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
324 hr = ITypeInfo_GetFuncDesc(pTI2, 1, &pFuncDesc);
325 ok(hr == S_OK, "hr %08lx\n", hr);
326 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
327 ok(pFuncDesc->invkind == methdata[1].wFlags, "invkind %d\n", pFuncDesc->invkind);
328 ok(pFuncDesc->callconv == methdata[1].cc, "callconv %d\n", pFuncDesc->callconv);
329 ok(pFuncDesc->cParams == methdata[1].cArgs, "cParams %d\n", pFuncDesc->cParams);
330 ok(pFuncDesc->oVft == 4, "oVft %d\n", pFuncDesc->oVft);
331 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
332 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
333 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
335 hr = ITypeInfo_GetFuncDesc(pTI2, 2, &pFuncDesc);
336 ok(hr == S_OK, "hr %08lx\n", hr);
337 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
338 ok(pFuncDesc->invkind == methdata[2].wFlags, "invkind %d\n", pFuncDesc->invkind);
339 ok(pFuncDesc->callconv == methdata[2].cc, "callconv %d\n", pFuncDesc->callconv);
340 ok(pFuncDesc->cParams == methdata[2].cArgs, "cParams %d\n", pFuncDesc->cParams);
341 ok(pFuncDesc->oVft == 12, "oVft %d\n", pFuncDesc->oVft);
342 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
343 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
344 ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
345 ok(pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags);
346 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
348 hr = ITypeInfo_GetFuncDesc(pTI2, 3, &pFuncDesc);
349 ok(hr == S_OK, "hr %08lx\n", hr);
350 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
351 ok(pFuncDesc->invkind == methdata[3].wFlags, "invkind %d\n", pFuncDesc->invkind);
352 ok(pFuncDesc->callconv == methdata[3].cc, "callconv %d\n", pFuncDesc->callconv);
353 ok(pFuncDesc->cParams == methdata[3].cArgs, "cParams %d\n", pFuncDesc->cParams);
354 ok(pFuncDesc->oVft == 16, "oVft %d\n", pFuncDesc->oVft);
355 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
356 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
357 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
359 /* test GetIDsOfNames on a coclass to see if it searches its interfaces */
360 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &name, 1, &memid);
361 ok(hr == S_OK, "hr 0x%08lx\n", hr);
362 ok(memid == 0x123, "memid 0x%08lx\n", memid);
364 ITypeInfo_Release(pTI2);
365 ITypeInfo_Release(pTypeInfo);
367 SysFreeString(parms1[0].szName);
368 SysFreeString(parms1[1].szName);
369 SysFreeString(parms3[0].szName);
370 SysFreeString(methdata[0].szName);
371 SysFreeString(methdata[1].szName);
372 SysFreeString(methdata[2].szName);
373 SysFreeString(methdata[3].szName);
376 static void test_TypeInfo(void)
379 ITypeInfo *pTypeInfo;
381 static WCHAR szBogus[] = { 'b','o','g','u','s',0 };
382 OLECHAR* bogus = szBogus;
384 DISPPARAMS dispparams;
386 hr = LoadTypeLib(wszStdOle2, &pTypeLib);
387 ok_ole_success(hr, LoadTypeLib);
389 hr = ITypeLib_GetTypeInfo(pTypeLib, 1, &pTypeInfo);
390 ok_ole_success(hr, ITypeLib_GetTypeInfo);
391 ITypeLib_Release(pTypeLib);
393 /* test nonexistent method name */
394 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &bogus, 1, &dispidMember);
395 ok(hr == DISP_E_UNKNOWNNAME,
396 "ITypeInfo_GetIDsOfNames should have returned DISP_E_UNKNOWNNAME instead of 0x%08lx\n",
399 /* test invalid memberid */
400 dispparams.cNamedArgs = 0;
401 dispparams.cArgs = 0;
402 dispparams.rgdispidNamedArgs = NULL;
403 dispparams.rgvarg = NULL;
404 hr = ITypeInfo_Invoke(pTypeInfo, NULL, 0xdeadbeef, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
405 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08lx\n", hr);
407 ITypeInfo_Release(pTypeInfo);
412 ref_count_test(wszStdOle2);
414 test_CreateDispTypeInfo();