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
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
26 #include <wine/test.h>
35 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
37 static const WCHAR wszStdOle2[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
39 static void ref_count_test(LPCWSTR type_lib)
42 ITypeInfo *iti1, *iti2;
46 trace("Loading type library\n");
47 hRes = LoadTypeLib(type_lib, &iface);
48 ok(hRes == S_OK, "Could not load type library\n");
52 hRes = ITypeLib_GetTypeInfo(iface, 1, &iti1);
53 ok(hRes == S_OK, "ITypeLib_GetTypeInfo failed on index = 1\n");
54 ok(ref_count=ITypeLib_Release(iface) > 0, "ITypeLib destroyed while ITypeInfo has back pointer\n");
58 hRes = ITypeLib_GetTypeInfo(iface, 1, &iti2);
59 ok(hRes == S_OK, "ITypeLib_GetTypeInfo failed on index = 1\n");
60 ok(iti1 == iti2, "ITypeLib_GetTypeInfo returned different pointers for same indexes\n");
62 ITypeLib_AddRef(iface);
63 ITypeInfo_Release(iti2);
64 ITypeInfo_Release(iti1);
65 ok(ITypeLib_Release(iface) == 0, "ITypeLib should be destroyed here.\n");
68 static void test_TypeComp(void)
77 ITypeInfo *pFontTypeInfo;
78 static WCHAR wszStdFunctions[] = {'S','t','d','F','u','n','c','t','i','o','n','s',0};
79 static WCHAR wszSavePicture[] = {'S','a','v','e','P','i','c','t','u','r','e',0};
80 static WCHAR wszOLE_TRISTATE[] = {'O','L','E','_','T','R','I','S','T','A','T','E',0};
81 static WCHAR wszUnchecked[] = {'U','n','c','h','e','c','k','e','d',0};
82 static WCHAR wszIUnknown[] = {'I','U','n','k','n','o','w','n',0};
83 static WCHAR wszFont[] = {'F','o','n','t',0};
84 static WCHAR wszGUID[] = {'G','U','I','D',0};
85 static WCHAR wszStdPicture[] = {'S','t','d','P','i','c','t','u','r','e',0};
86 static WCHAR wszOLE_COLOR[] = {'O','L','E','_','C','O','L','O','R',0};
87 static WCHAR wszClone[] = {'C','l','o','n','e',0};
88 static WCHAR wszclone[] = {'c','l','o','n','e',0};
90 hr = LoadTypeLib(wszStdOle2, &pTypeLib);
91 ok_ole_success(hr, LoadTypeLib);
93 hr = ITypeLib_GetTypeComp(pTypeLib, &pTypeComp);
94 ok_ole_success(hr, ITypeLib_GetTypeComp);
96 /* test getting a TKIND_MODULE */
97 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdFunctions);
98 hr = ITypeComp_Bind(pTypeComp, wszStdFunctions, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
99 ok_ole_success(hr, ITypeComp_Bind);
101 ok(desckind == DESCKIND_TYPECOMP,
102 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
104 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
106 ITypeComp_Release(bindptr.lptcomp);
108 /* test getting a TKIND_MODULE with INVOKE_PROPERTYGET */
109 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdFunctions);
110 hr = ITypeComp_Bind(pTypeComp, wszStdFunctions, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
111 ok_ole_success(hr, ITypeComp_Bind);
113 ok(desckind == DESCKIND_TYPECOMP,
114 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
116 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
117 ITypeComp_Release(bindptr.lptcomp);
119 /* test getting a function within a TKIND_MODULE */
120 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszSavePicture);
121 hr = ITypeComp_Bind(pTypeComp, wszSavePicture, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
122 ok_ole_success(hr, ITypeComp_Bind);
124 ok(desckind == DESCKIND_FUNCDESC,
125 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
127 ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
128 ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
129 ITypeInfo_Release(pTypeInfo);
131 /* test getting a function within a TKIND_MODULE with INVOKE_PROPERTYGET */
132 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszSavePicture);
133 hr = ITypeComp_Bind(pTypeComp, wszSavePicture, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
134 todo_wine ok(hr == TYPE_E_TYPEMISMATCH,
135 "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n",
138 ok(desckind == DESCKIND_NONE,
139 "desckind should have been DESCKIND_NONE instead of %d\n",
141 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
142 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
144 /* test getting a TKIND_ENUM */
145 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszOLE_TRISTATE);
146 hr = ITypeComp_Bind(pTypeComp, wszOLE_TRISTATE, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
147 ok_ole_success(hr, ITypeComp_Bind);
149 ok(desckind == DESCKIND_TYPECOMP,
150 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
152 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
154 ITypeComp_Release(bindptr.lptcomp);
156 /* test getting a value within a TKIND_ENUM */
157 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszUnchecked);
158 hr = ITypeComp_Bind(pTypeComp, wszUnchecked, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
159 ok_ole_success(hr, ITypeComp_Bind);
161 ok(desckind == DESCKIND_VARDESC,
162 "desckind should have been DESCKIND_VARDESC instead of %d\n",
164 ITypeInfo_ReleaseVarDesc(pTypeInfo, bindptr.lpvardesc);
165 ITypeInfo_Release(pTypeInfo);
167 /* test getting a TKIND_INTERFACE */
168 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszIUnknown);
169 hr = ITypeComp_Bind(pTypeComp, wszIUnknown, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
170 ok_ole_success(hr, ITypeComp_Bind);
172 ok(desckind == DESCKIND_NONE,
173 "desckind should have been DESCKIND_NONE instead of %d\n",
175 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
176 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
178 /* test getting a TKIND_DISPATCH */
179 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszFont);
180 hr = ITypeComp_Bind(pTypeComp, wszFont, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
181 ok_ole_success(hr, ITypeComp_Bind);
183 ok(desckind == DESCKIND_NONE,
184 "desckind should have been DESCKIND_NONE instead of %d\n",
186 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
187 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
189 /* test getting a TKIND_RECORD/TKIND_ALIAS */
190 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
191 hr = ITypeComp_Bind(pTypeComp, wszGUID, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
192 ok_ole_success(hr, ITypeComp_Bind);
194 ok(desckind == DESCKIND_NONE,
195 "desckind should have been DESCKIND_NONE instead of %d\n",
197 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
198 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
200 /* test getting a TKIND_ALIAS */
201 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszOLE_COLOR);
202 hr = ITypeComp_Bind(pTypeComp, wszOLE_COLOR, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
203 ok_ole_success(hr, ITypeComp_Bind);
205 ok(desckind == DESCKIND_NONE,
206 "desckind should have been DESCKIND_NONE instead of %d\n",
208 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
209 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
211 /* test getting a TKIND_COCLASS */
212 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdPicture);
213 hr = ITypeComp_Bind(pTypeComp, wszStdPicture, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
214 ok_ole_success(hr, ITypeComp_Bind);
216 ok(desckind == DESCKIND_NONE,
217 "desckind should have been DESCKIND_NONE instead of %d\n",
219 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
220 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
222 ITypeComp_Release(pTypeComp);
224 /* tests for ITypeComp on an interface */
225 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IFont, &pFontTypeInfo);
226 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
228 hr = ITypeInfo_GetTypeComp(pFontTypeInfo, &pTypeComp);
229 ok_ole_success(hr, ITypeLib_GetTypeComp);
231 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszClone);
232 hr = ITypeComp_Bind(pTypeComp, wszClone, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
233 ok_ole_success(hr, ITypeComp_Bind);
235 ok(desckind == DESCKIND_FUNCDESC,
236 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
238 ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
239 ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
240 ITypeInfo_Release(pTypeInfo);
242 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszClone);
243 hr = ITypeComp_Bind(pTypeComp, wszClone, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
244 ok(hr == TYPE_E_TYPEMISMATCH, "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n", hr);
246 ok(desckind == DESCKIND_NONE,
247 "desckind should have been DESCKIND_NONE instead of %d\n",
249 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
250 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
252 /* tests that the compare is case-insensitive */
253 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszclone);
254 hr = ITypeComp_Bind(pTypeComp, wszclone, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
255 ok_ole_success(hr, ITypeComp_Bind);
257 ok(desckind == DESCKIND_FUNCDESC,
258 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
260 ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
261 ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
262 ITypeInfo_Release(pTypeInfo);
264 ITypeComp_Release(pTypeComp);
265 ITypeInfo_Release(pFontTypeInfo);
266 ITypeLib_Release(pTypeLib);
269 static void test_CreateDispTypeInfo(void)
271 ITypeInfo *pTypeInfo, *pTI2;
273 INTERFACEDATA ifdata;
274 METHODDATA methdata[4];
282 static const WCHAR func1[] = {'f','u','n','c','1',0};
283 static const WCHAR func2[] = {'f','u','n','c','2',0};
284 static const WCHAR func3[] = {'f','u','n','c','3',0};
285 static const WCHAR parm1[] = {'p','a','r','m','1',0};
286 static const WCHAR parm2[] = {'p','a','r','m','2',0};
287 OLECHAR *name = (OLECHAR *)func1;
289 ifdata.pmethdata = methdata;
290 ifdata.cMembers = sizeof(methdata) / sizeof(methdata[0]);
292 methdata[0].szName = SysAllocString(func1);
293 methdata[0].ppdata = parms1;
294 methdata[0].dispid = 0x123;
295 methdata[0].iMeth = 0;
296 methdata[0].cc = CC_STDCALL;
297 methdata[0].cArgs = 2;
298 methdata[0].wFlags = DISPATCH_METHOD;
299 methdata[0].vtReturn = VT_HRESULT;
300 parms1[0].szName = SysAllocString(parm1);
301 parms1[0].vt = VT_I4;
302 parms1[1].szName = SysAllocString(parm2);
303 parms1[1].vt = VT_BSTR;
305 methdata[1].szName = SysAllocString(func2);
306 methdata[1].ppdata = NULL;
307 methdata[1].dispid = 0x124;
308 methdata[1].iMeth = 1;
309 methdata[1].cc = CC_STDCALL;
310 methdata[1].cArgs = 0;
311 methdata[1].wFlags = DISPATCH_PROPERTYGET;
312 methdata[1].vtReturn = VT_I4;
314 methdata[2].szName = SysAllocString(func3);
315 methdata[2].ppdata = parms3;
316 methdata[2].dispid = 0x125;
317 methdata[2].iMeth = 3;
318 methdata[2].cc = CC_STDCALL;
319 methdata[2].cArgs = 1;
320 methdata[2].wFlags = DISPATCH_PROPERTYPUT;
321 methdata[2].vtReturn = VT_HRESULT;
322 parms3[0].szName = SysAllocString(parm1);
323 parms3[0].vt = VT_I4;
325 methdata[3].szName = SysAllocString(func3);
326 methdata[3].ppdata = NULL;
327 methdata[3].dispid = 0x125;
328 methdata[3].iMeth = 4;
329 methdata[3].cc = CC_STDCALL;
330 methdata[3].cArgs = 0;
331 methdata[3].wFlags = DISPATCH_PROPERTYGET;
332 methdata[3].vtReturn = VT_I4;
334 hr = CreateDispTypeInfo(&ifdata, LOCALE_NEUTRAL, &pTypeInfo);
335 ok(hr == S_OK, "hr %08x\n", hr);
337 hr = ITypeInfo_GetTypeAttr(pTypeInfo, &pTypeAttr);
338 ok(hr == S_OK, "hr %08x\n", hr);
340 ok(pTypeAttr->typekind == TKIND_COCLASS, "typekind %0x\n", pTypeAttr->typekind);
341 ok(pTypeAttr->cImplTypes == 1, "cImplTypes %d\n", pTypeAttr->cImplTypes);
342 ok(pTypeAttr->cFuncs == 0, "cFuncs %d\n", pTypeAttr->cFuncs);
343 ok(pTypeAttr->wTypeFlags == 0, "wTypeFlags %04x\n", pTypeAttr->cFuncs);
344 ITypeInfo_ReleaseTypeAttr(pTypeInfo, pTypeAttr);
346 hr = ITypeInfo_GetRefTypeOfImplType(pTypeInfo, 0, &href);
347 ok(hr == S_OK, "hr %08x\n", hr);
349 ok(href == 0, "href = 0x%x\n", href);
351 hr = ITypeInfo_GetRefTypeInfo(pTypeInfo, href, &pTI2);
352 ok(hr == S_OK, "hr %08x\n", hr);
353 hr = ITypeInfo_GetTypeAttr(pTI2, &pTypeAttr);
354 ok(hr == S_OK, "hr %08x\n", hr);
355 ok(pTypeAttr->typekind == TKIND_INTERFACE, "typekind %0x\n", pTypeAttr->typekind);
356 ITypeInfo_ReleaseTypeAttr(pTI2, pTypeAttr);
358 hr = ITypeInfo_GetFuncDesc(pTI2, 0, &pFuncDesc);
359 ok(hr == S_OK, "hr %08x\n", hr);
360 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
361 ok(pFuncDesc->invkind == methdata[0].wFlags, "invkind %d\n", pFuncDesc->invkind);
362 ok(pFuncDesc->callconv == methdata[0].cc, "callconv %d\n", pFuncDesc->callconv);
363 ok(pFuncDesc->cParams == methdata[0].cArgs, "cParams %d\n", pFuncDesc->cParams);
364 ok(pFuncDesc->oVft == 0, "oVft %d\n", pFuncDesc->oVft);
365 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
366 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
367 ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
368 ok(pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags);
370 ok(pFuncDesc->lprgelemdescParam[1].tdesc.vt == VT_BSTR, "parm 1 vt %x\n", pFuncDesc->lprgelemdescParam[1].tdesc.vt);
371 ok(pFuncDesc->lprgelemdescParam[1].u.paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 1 flags %x\n", pFuncDesc->lprgelemdescParam[1].u.paramdesc.wParamFlags);
372 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
374 hr = ITypeInfo_GetFuncDesc(pTI2, 1, &pFuncDesc);
375 ok(hr == S_OK, "hr %08x\n", hr);
376 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
377 ok(pFuncDesc->invkind == methdata[1].wFlags, "invkind %d\n", pFuncDesc->invkind);
378 ok(pFuncDesc->callconv == methdata[1].cc, "callconv %d\n", pFuncDesc->callconv);
379 ok(pFuncDesc->cParams == methdata[1].cArgs, "cParams %d\n", pFuncDesc->cParams);
380 ok(pFuncDesc->oVft == 4, "oVft %d\n", pFuncDesc->oVft);
381 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
382 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
383 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
385 hr = ITypeInfo_GetFuncDesc(pTI2, 2, &pFuncDesc);
386 ok(hr == S_OK, "hr %08x\n", hr);
387 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
388 ok(pFuncDesc->invkind == methdata[2].wFlags, "invkind %d\n", pFuncDesc->invkind);
389 ok(pFuncDesc->callconv == methdata[2].cc, "callconv %d\n", pFuncDesc->callconv);
390 ok(pFuncDesc->cParams == methdata[2].cArgs, "cParams %d\n", pFuncDesc->cParams);
391 ok(pFuncDesc->oVft == 12, "oVft %d\n", pFuncDesc->oVft);
392 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
393 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
394 ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
395 ok(pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", pFuncDesc->lprgelemdescParam[0].u.paramdesc.wParamFlags);
396 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
398 hr = ITypeInfo_GetFuncDesc(pTI2, 3, &pFuncDesc);
399 ok(hr == S_OK, "hr %08x\n", hr);
400 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
401 ok(pFuncDesc->invkind == methdata[3].wFlags, "invkind %d\n", pFuncDesc->invkind);
402 ok(pFuncDesc->callconv == methdata[3].cc, "callconv %d\n", pFuncDesc->callconv);
403 ok(pFuncDesc->cParams == methdata[3].cArgs, "cParams %d\n", pFuncDesc->cParams);
404 ok(pFuncDesc->oVft == 16, "oVft %d\n", pFuncDesc->oVft);
405 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
406 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
407 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
409 /* test GetIDsOfNames on a coclass to see if it searches its interfaces */
410 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &name, 1, &memid);
411 ok(hr == S_OK, "hr 0x%08x\n", hr);
412 ok(memid == 0x123, "memid 0x%08x\n", memid);
414 ITypeInfo_Release(pTI2);
415 ITypeInfo_Release(pTypeInfo);
417 SysFreeString(parms1[0].szName);
418 SysFreeString(parms1[1].szName);
419 SysFreeString(parms3[0].szName);
420 SysFreeString(methdata[0].szName);
421 SysFreeString(methdata[1].szName);
422 SysFreeString(methdata[2].szName);
423 SysFreeString(methdata[3].szName);
426 static void test_TypeInfo(void)
429 ITypeInfo *pTypeInfo;
431 static WCHAR wszBogus[] = { 'b','o','g','u','s',0 };
432 static WCHAR wszGetTypeInfo[] = { 'G','e','t','T','y','p','e','I','n','f','o',0 };
433 static WCHAR wszClone[] = {'C','l','o','n','e',0};
434 OLECHAR* bogus = wszBogus;
435 OLECHAR* pwszGetTypeInfo = wszGetTypeInfo;
436 OLECHAR* pwszClone = wszClone;
438 DISPPARAMS dispparams;
440 hr = LoadTypeLib(wszStdOle2, &pTypeLib);
441 ok_ole_success(hr, LoadTypeLib);
443 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IFont, &pTypeInfo);
444 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
446 /* test nonexistent method name */
447 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &bogus, 1, &dispidMember);
448 ok(hr == DISP_E_UNKNOWNNAME,
449 "ITypeInfo_GetIDsOfNames should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n",
452 /* test invalid memberid */
453 dispparams.cNamedArgs = 0;
454 dispparams.cArgs = 0;
455 dispparams.rgdispidNamedArgs = NULL;
456 dispparams.rgvarg = NULL;
457 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
458 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
460 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &pwszClone, 1, &dispidMember);
461 ok_ole_success(hr, ITypeInfo_GetIDsOfNames);
463 /* test correct memberid, but wrong flags */
464 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
465 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
467 /* test NULL dispparams */
468 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, NULL, NULL, NULL, NULL);
469 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
471 /* test dispparams->cNamedArgs being bigger than dispparams->cArgs */
472 dispparams.cNamedArgs = 1;
473 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
474 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
476 ITypeInfo_Release(pTypeInfo);
478 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IDispatch, &pTypeInfo);
479 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
481 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &pwszGetTypeInfo, 1, &dispidMember);
482 ok_ole_success(hr, ITypeInfo_GetIDsOfNames);
484 /* test invoking a method with a [restricted] keyword */
485 hr = ITypeInfo_Invoke(pTypeInfo, NULL, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
487 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
490 ITypeInfo_Release(pTypeInfo);
491 ITypeLib_Release(pTypeLib);
494 static BOOL do_typelib_reg_key(GUID *uid, WORD maj, WORD min, LPCWSTR base, BOOL remove)
496 static const WCHAR typelibW[] = {'T','y','p','e','l','i','b','\\',0};
497 static const WCHAR formatW[] = {'\\','%','u','.','%','u','\\','0','\\','w','i','n','3','2',0};
498 static const WCHAR format2W[] = {'%','s','_','%','u','_','%','u','.','d','l','l',0};
503 memcpy(buf, typelibW, sizeof(typelibW));
504 StringFromGUID2(uid, buf + lstrlenW(buf), 40);
509 ok(SHDeleteKeyW(HKEY_CLASSES_ROOT, buf) == ERROR_SUCCESS, "SHDeleteKey failed\n");
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");
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");
534 static void test_QueryPathOfRegTypeLib(void)
536 static const struct test_data
540 const WCHAR path[16];
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};
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);
574 ok(!lstrcmpW(td[i].path, path), "typelib %u.%u path doesn't match\n", td[i].maj, td[i].min);
579 do_typelib_reg_key(&uid, 0, 0, NULL, 1);
584 ref_count_test(wszStdOle2);
586 test_CreateDispTypeInfo();
588 test_QueryPathOfRegTypeLib();