[OLEAUT32_WINETEST] Sync with Wine 3.0. CORE-14225
[reactos.git] / modules / rostests / winetests / oleaut32 / typelib.c
1 /*
2 * ITypeLib and ITypeInfo test
3 *
4 * Copyright 2004 Jacek Caban
5 * Copyright 2006,2015 Dmitry Timoshkov
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "precomp.h"
23
24 #include <winreg.h>
25 #include <test_reg.h>
26
27 #define expect_eq(expr, value, type, format) { type _ret = (expr); ok((value) == _ret, #expr " expected " format " got " format "\n", value, _ret); }
28 #define expect_int(expr, value) expect_eq(expr, (int)(value), int, "%d")
29 #define expect_hex(expr, value) expect_eq(expr, (int)(value), int, "0x%x")
30 #define expect_null(expr) expect_eq(expr, NULL, const void *, "%p")
31 #define expect_guid(expected, guid) { ok(IsEqualGUID(expected, guid), "got wrong guid %s\n", wine_dbgstr_guid(guid)); }
32
33 #define expect_wstr_acpval(expr, value) \
34 { \
35 CHAR buf[260]; \
36 expect_eq(!WideCharToMultiByte(CP_ACP, 0, (expr), -1, buf, 260, NULL, NULL), 0, int, "%d"); \
37 ok(strcmp(value, buf) == 0, #expr " expected \"%s\" got \"%s\"\n", value, buf); \
38 }
39
40 #define ole_expect(expr, expect) { \
41 HRESULT r = expr; \
42 ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \
43 }
44
45 #define ole_check(expr) ole_expect(expr, S_OK);
46
47 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
48
49 #ifdef __i386__
50 #define ARCH "x86"
51 #elif defined __x86_64__
52 #define ARCH "amd64"
53 #elif defined __arm__
54 #define ARCH "arm"
55 #elif defined __aarch64__
56 #define ARCH "arm64"
57 #else
58 #define ARCH "none"
59 #endif
60
61 static HRESULT (WINAPI *pRegisterTypeLibForUser)(ITypeLib*,OLECHAR*,OLECHAR*);
62 static HRESULT (WINAPI *pUnRegisterTypeLibForUser)(REFGUID,WORD,WORD,LCID,SYSKIND);
63
64 static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
65 static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
66 static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
67 static VOID (WINAPI *pReleaseActCtx)(HANDLE);
68 static BOOL (WINAPI *pIsWow64Process)(HANDLE,LPBOOL);
69 static LONG (WINAPI *pRegDeleteKeyExW)(HKEY,LPCWSTR,REGSAM,DWORD);
70
71 static const WCHAR wszStdOle2[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
72 static WCHAR wszGUID[] = {'G','U','I','D',0};
73 static WCHAR wszguid[] = {'g','u','i','d',0};
74
75 static const BOOL is_win64 = sizeof(void *) > sizeof(int);
76
77 #ifdef __i386__
78 static const BOOL abi_supports_stdcall = TRUE;
79 #else
80 static const BOOL abi_supports_stdcall = FALSE;
81 #endif
82
83 static HRESULT WINAPI collection_QueryInterface(ICollection *iface, REFIID riid, void **ret)
84 {
85 if (IsEqualIID(riid, &IID_IUnknown) ||
86 IsEqualIID(riid, &IID_IDispatch) ||
87 IsEqualIID(riid, &IID_ICollection))
88 {
89 *ret = iface;
90 return S_OK;
91 }
92
93 return E_NOINTERFACE;
94 }
95
96 static ULONG WINAPI collection_AddRef(ICollection *iface)
97 {
98 return 2;
99 }
100
101 static ULONG WINAPI collection_Release(ICollection *iface)
102 {
103 return 1;
104 }
105
106 static HRESULT WINAPI collection_GetTypeInfoCount(ICollection *iface, UINT *cnt)
107 {
108 ok(0, "unexpected call\n");
109 *cnt = 0;
110 return E_NOTIMPL;
111 }
112
113 static HRESULT WINAPI collection_GetTypeInfo(ICollection *iface, UINT index, LCID lcid, ITypeInfo **ti)
114 {
115 ok(0, "unexpected call\n");
116 return E_NOTIMPL;
117 }
118
119 static HRESULT WINAPI collection_GetIDsOfNames(ICollection *iface, REFIID riid, LPOLESTR *names,
120 UINT cnt, LCID lcid, DISPID *dispid)
121 {
122 ok(0, "unexpected call\n");
123 return E_NOTIMPL;
124 }
125
126 static HRESULT WINAPI collection_Invoke(ICollection *iface, DISPID dispid, REFIID riid,
127 LCID lcid, WORD flags, DISPPARAMS *dispparams, VARIANT *res, EXCEPINFO *ei, UINT *argerr)
128 {
129 if(dispid != DISPID_VALUE) {
130 ok(0, "unexpected call\n");
131 return E_NOTIMPL;
132 }
133
134 ok(flags == (DISPATCH_METHOD|DISPATCH_PROPERTYGET), "flags = %x\n", flags);
135 ok(dispparams != NULL, "dispparams == NULL\n");
136 ok(!dispparams->rgdispidNamedArgs, "dispparams->rgdispidNamedArgs != NULL\n");
137 ok(dispparams->cArgs == 1, "dispparams->cArgs = %d\n", dispparams->cArgs);
138 ok(!dispparams->cNamedArgs, "dispparams->cNamedArgs = %d\n", dispparams->cNamedArgs);
139 ok(V_VT(dispparams->rgvarg) == VT_I4, "V_VT(dispparams->rgvarg) = %d\n", V_VT(dispparams->rgvarg));
140 ok(V_I4(dispparams->rgvarg) == 7, "V_I4(dispparams->rgvarg) = %d\n", V_I4(dispparams->rgvarg));
141 ok(res != NULL, "res == NULL\n");
142 ok(V_VT(res) == VT_EMPTY, "V_VT(res) = %d\n", V_VT(res));
143
144 V_VT(res) = VT_I4;
145 V_I4(res) = 15;
146 return S_OK;
147 }
148
149 static HRESULT WINAPI collection_Item(ICollection *iface, int i, int *p)
150 {
151 ok(0, "unexpected call\n");
152 return E_NOTIMPL;
153 }
154
155 static const ICollectionVtbl collectionvtbl = {
156 collection_QueryInterface,
157 collection_AddRef,
158 collection_Release,
159 collection_GetTypeInfoCount,
160 collection_GetTypeInfo,
161 collection_GetIDsOfNames,
162 collection_Invoke,
163 collection_Item
164 };
165
166 static ICollection collection = { &collectionvtbl };
167
168 static HRESULT WINAPI invoketest_QueryInterface(IInvokeTest *iface, REFIID riid, void **ret)
169 {
170 if (IsEqualIID(riid, &IID_IUnknown) ||
171 IsEqualIID(riid, &IID_IDispatch) ||
172 IsEqualIID(riid, &IID_IInvokeTest))
173 {
174 *ret = iface;
175 return S_OK;
176 }
177
178 return E_NOINTERFACE;
179 }
180
181 static ULONG WINAPI invoketest_AddRef(IInvokeTest *iface)
182 {
183 return 2;
184 }
185
186 static ULONG WINAPI invoketest_Release(IInvokeTest *iface)
187 {
188 return 1;
189 }
190
191 static HRESULT WINAPI invoketest_GetTypeInfoCount(IInvokeTest *iface, UINT *cnt)
192 {
193 ok(0, "unexpected call\n");
194 *cnt = 0;
195 return E_NOTIMPL;
196 }
197
198 static HRESULT WINAPI invoketest_GetTypeInfo(IInvokeTest *iface, UINT index, LCID lcid, ITypeInfo **ti)
199 {
200 ok(0, "unexpected call\n");
201 return E_NOTIMPL;
202 }
203
204 static HRESULT WINAPI invoketest_GetIDsOfNames(IInvokeTest *iface, REFIID riid, LPOLESTR *names,
205 UINT cnt, LCID lcid, DISPID *dispid)
206 {
207 ok(0, "unexpected call\n");
208 return E_NOTIMPL;
209 }
210
211 static HRESULT WINAPI invoketest_Invoke(IInvokeTest *iface, DISPID dispid, REFIID riid,
212 LCID lcid, WORD flags, DISPPARAMS *dispparams, VARIANT *res, EXCEPINFO *ei, UINT *argerr)
213 {
214 ok(0, "unexpected call\n");
215 return E_NOTIMPL;
216 }
217
218 static LONG WINAPI invoketest_get_test(IInvokeTest *iface, LONG i)
219 {
220 return i+1;
221 }
222
223 static LONG WINAPI invoketest_putref_testprop(IInvokeTest *iface, LONG *i)
224 {
225 return *i+2;
226 }
227
228 static LONG WINAPI invoketest_putref_testprop2(IInvokeTest *iface, IUnknown *i)
229 {
230 return 6;
231 }
232
233 static HRESULT WINAPI invoketest_testfunc(IInvokeTest *iface, int i, int *p)
234 {
235 *p = i+1;
236 return S_OK;
237 }
238
239 static HRESULT WINAPI invoketest_testget(IInvokeTest *iface, ICollection **p)
240 {
241 *p = &collection;
242 ICollection_AddRef(&collection);
243 return S_OK;
244 }
245
246 static const IInvokeTestVtbl invoketestvtbl = {
247 invoketest_QueryInterface,
248 invoketest_AddRef,
249 invoketest_Release,
250 invoketest_GetTypeInfoCount,
251 invoketest_GetTypeInfo,
252 invoketest_GetIDsOfNames,
253 invoketest_Invoke,
254 invoketest_get_test,
255 invoketest_putref_testprop,
256 invoketest_putref_testprop2,
257 invoketest_testfunc,
258 invoketest_testget
259 };
260
261 static IInvokeTest invoketest = { &invoketestvtbl };
262
263 static void init_function_pointers(void)
264 {
265 HMODULE hmod = GetModuleHandleA("oleaut32.dll");
266 HMODULE hk32 = GetModuleHandleA("kernel32.dll");
267 HMODULE hadv = GetModuleHandleA("advapi32.dll");
268
269 pRegisterTypeLibForUser = (void *)GetProcAddress(hmod, "RegisterTypeLibForUser");
270 pUnRegisterTypeLibForUser = (void *)GetProcAddress(hmod, "UnRegisterTypeLibForUser");
271 pActivateActCtx = (void *)GetProcAddress(hk32, "ActivateActCtx");
272 pCreateActCtxW = (void *)GetProcAddress(hk32, "CreateActCtxW");
273 pDeactivateActCtx = (void *)GetProcAddress(hk32, "DeactivateActCtx");
274 pReleaseActCtx = (void *)GetProcAddress(hk32, "ReleaseActCtx");
275 pIsWow64Process = (void *)GetProcAddress(hk32, "IsWow64Process");
276 pRegDeleteKeyExW = (void*)GetProcAddress(hadv, "RegDeleteKeyExW");
277 }
278
279 static void ref_count_test(LPCWSTR type_lib)
280 {
281 ITypeLib *iface;
282 ITypeInfo *iti1, *iti2;
283 HRESULT hRes;
284 int ref_count;
285
286 trace("Loading type library\n");
287 hRes = LoadTypeLib(type_lib, &iface);
288 ok(hRes == S_OK, "Could not load type library\n");
289 if(hRes != S_OK)
290 return;
291
292 hRes = ITypeLib_GetTypeInfo(iface, 1, &iti1);
293 ok(hRes == S_OK, "ITypeLib_GetTypeInfo failed on index = 1\n");
294 ref_count = ITypeLib_Release(iface);
295 ok(ref_count > 0, "ITypeLib destroyed while ITypeInfo has back pointer\n");
296 if(!ref_count)
297 return;
298
299 hRes = ITypeLib_GetTypeInfo(iface, 1, &iti2);
300 ok(hRes == S_OK, "ITypeLib_GetTypeInfo failed on index = 1\n");
301 ok(iti1 == iti2, "ITypeLib_GetTypeInfo returned different pointers for same indexes\n");
302
303 ITypeLib_AddRef(iface);
304 ITypeInfo_Release(iti2);
305 ITypeInfo_Release(iti1);
306 ok(ITypeLib_Release(iface) == 0, "ITypeLib should be destroyed here.\n");
307 }
308
309 static void test_TypeComp(void)
310 {
311 ITypeComp *pTypeComp, *tcomp, *pTypeComp_tmp;
312 ITypeInfo *pTypeInfo, *ti, *pFontTypeInfo;
313 ITypeLib *pTypeLib;
314 HRESULT hr;
315 ULONG ulHash;
316 DESCKIND desckind;
317 BINDPTR bindptr;
318 static WCHAR wszStdFunctions[] = {'S','t','d','F','u','n','c','t','i','o','n','s',0};
319 static WCHAR wszSavePicture[] = {'S','a','v','e','P','i','c','t','u','r','e',0};
320 static WCHAR wszOLE_TRISTATE[] = {'O','L','E','_','T','R','I','S','T','A','T','E',0};
321 static WCHAR wszUnchecked[] = {'U','n','c','h','e','c','k','e','d',0};
322 static WCHAR wszIUnknown[] = {'I','U','n','k','n','o','w','n',0};
323 static WCHAR wszFont[] = {'F','o','n','t',0};
324 static WCHAR wszStdPicture[] = {'S','t','d','P','i','c','t','u','r','e',0};
325 static WCHAR wszOLE_COLOR[] = {'O','L','E','_','C','O','L','O','R',0};
326 static WCHAR wszClone[] = {'C','l','o','n','e',0};
327 static WCHAR wszclone[] = {'c','l','o','n','e',0};
328 static WCHAR wszJunk[] = {'J','u','n','k',0};
329 static WCHAR wszAddRef[] = {'A','d','d','R','e','f',0};
330
331 hr = LoadTypeLib(wszStdOle2, &pTypeLib);
332 ok_ole_success(hr, LoadTypeLib);
333
334 hr = ITypeLib_GetTypeComp(pTypeLib, &pTypeComp);
335 ok_ole_success(hr, ITypeLib_GetTypeComp);
336
337 /* test getting a TKIND_MODULE */
338 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdFunctions);
339 hr = ITypeComp_Bind(pTypeComp, wszStdFunctions, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
340 ok_ole_success(hr, ITypeComp_Bind);
341
342 ok(desckind == DESCKIND_TYPECOMP,
343 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
344 desckind);
345 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
346
347 ITypeComp_Release(bindptr.lptcomp);
348
349 /* test getting a TKIND_MODULE with INVOKE_PROPERTYGET */
350 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdFunctions);
351 hr = ITypeComp_Bind(pTypeComp, wszStdFunctions, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
352 ok_ole_success(hr, ITypeComp_Bind);
353
354 ok(desckind == DESCKIND_TYPECOMP,
355 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
356 desckind);
357 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
358 ITypeComp_Release(bindptr.lptcomp);
359
360 /* test getting a function within a TKIND_MODULE */
361 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszSavePicture);
362 hr = ITypeComp_Bind(pTypeComp, wszSavePicture, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
363 ok_ole_success(hr, ITypeComp_Bind);
364
365 ok(desckind == DESCKIND_FUNCDESC,
366 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
367 desckind);
368 ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
369 ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
370 ITypeInfo_Release(pTypeInfo);
371
372 /* test getting a function within a TKIND_MODULE with INVOKE_PROPERTYGET */
373 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszSavePicture);
374 hr = ITypeComp_Bind(pTypeComp, wszSavePicture, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
375 ok(hr == TYPE_E_TYPEMISMATCH,
376 "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n",
377 hr);
378
379 ok(desckind == DESCKIND_NONE,
380 "desckind should have been DESCKIND_NONE instead of %d\n",
381 desckind);
382 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
383 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
384
385 /* test getting a TKIND_ENUM */
386 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszOLE_TRISTATE);
387 hr = ITypeComp_Bind(pTypeComp, wszOLE_TRISTATE, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
388 ok_ole_success(hr, ITypeComp_Bind);
389
390 ok(desckind == DESCKIND_TYPECOMP,
391 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
392 desckind);
393 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
394
395 ITypeComp_Release(bindptr.lptcomp);
396
397 /* test getting a value within a TKIND_ENUM */
398 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszUnchecked);
399 hr = ITypeComp_Bind(pTypeComp, wszUnchecked, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
400 ok_ole_success(hr, ITypeComp_Bind);
401
402 ok(desckind == DESCKIND_VARDESC,
403 "desckind should have been DESCKIND_VARDESC instead of %d\n",
404 desckind);
405 ITypeInfo_ReleaseVarDesc(pTypeInfo, bindptr.lpvardesc);
406 ITypeInfo_Release(pTypeInfo);
407
408 /* test getting a TKIND_INTERFACE */
409 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszIUnknown);
410 hr = ITypeComp_Bind(pTypeComp, wszIUnknown, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
411 ok_ole_success(hr, ITypeComp_Bind);
412
413 ok(desckind == DESCKIND_NONE,
414 "desckind should have been DESCKIND_NONE instead of %d\n",
415 desckind);
416 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
417 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
418
419 /* test getting a TKIND_DISPATCH */
420 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszFont);
421 hr = ITypeComp_Bind(pTypeComp, wszFont, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
422 ok_ole_success(hr, ITypeComp_Bind);
423
424 ok(desckind == DESCKIND_NONE,
425 "desckind should have been DESCKIND_NONE instead of %d\n",
426 desckind);
427 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
428 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
429
430 /* test getting a TKIND_RECORD/TKIND_ALIAS */
431 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
432 hr = ITypeComp_Bind(pTypeComp, wszGUID, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
433 ok_ole_success(hr, ITypeComp_Bind);
434
435 ok(desckind == DESCKIND_NONE,
436 "desckind should have been DESCKIND_NONE instead of %d\n",
437 desckind);
438 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
439 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
440
441 /* test getting a TKIND_ALIAS */
442 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszOLE_COLOR);
443 hr = ITypeComp_Bind(pTypeComp, wszOLE_COLOR, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
444 ok_ole_success(hr, ITypeComp_Bind);
445
446 ok(desckind == DESCKIND_NONE,
447 "desckind should have been DESCKIND_NONE instead of %d\n",
448 desckind);
449 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
450 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
451
452 /* test getting a TKIND_COCLASS */
453 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdPicture);
454 hr = ITypeComp_Bind(pTypeComp, wszStdPicture, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
455 ok_ole_success(hr, ITypeComp_Bind);
456
457 ok(desckind == DESCKIND_NONE,
458 "desckind should have been DESCKIND_NONE instead of %d\n",
459 desckind);
460 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
461 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
462
463 /* test basic BindType argument handling */
464 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
465 hr = ITypeComp_BindType(pTypeComp, wszGUID, ulHash, NULL, NULL);
466 ok(hr == E_INVALIDARG, "Got %08x\n", hr);
467
468 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
469 pTypeInfo = (void*)0xdeadbeef;
470 hr = ITypeComp_BindType(pTypeComp, wszGUID, ulHash, &pTypeInfo, NULL);
471 ok(hr == E_INVALIDARG, "Got %08x\n", hr);
472 ok(pTypeInfo == (void*)0xdeadbeef, "Got %p\n", pTypeInfo);
473
474 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
475 pTypeComp_tmp = (void*)0xdeadbeef;
476 hr = ITypeComp_BindType(pTypeComp, wszGUID, ulHash, NULL, &pTypeComp_tmp);
477 ok(hr == E_INVALIDARG, "Got %08x\n", hr);
478 ok(pTypeComp_tmp == (void*)0xdeadbeef, "Got %p\n", pTypeComp_tmp);
479
480 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
481 pTypeComp_tmp = (void*)0xdeadbeef;
482 pTypeInfo = (void*)0xdeadbeef;
483 hr = ITypeComp_BindType(pTypeComp, NULL, ulHash, &pTypeInfo, &pTypeComp_tmp);
484 ok(hr == E_INVALIDARG, "Got %08x\n", hr);
485 ok(pTypeInfo == (void*)0xdeadbeef, "Got %p\n", pTypeInfo);
486 ok(pTypeComp_tmp == (void*)0xdeadbeef, "Got %p\n", pTypeComp_tmp);
487
488 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
489 pTypeComp_tmp = (void*)0xdeadbeef;
490 pTypeInfo = (void*)0xdeadbeef;
491 hr = ITypeComp_BindType(pTypeComp, wszGUID, ulHash, &pTypeInfo, &pTypeComp_tmp);
492 ok_ole_success(hr, ITypeComp_BindType);
493 ok(pTypeInfo != NULL, "Got NULL pTypeInfo\n");
494 todo_wine ok(pTypeComp_tmp == NULL, "Got pTypeComp_tmp %p\n", pTypeComp_tmp);
495 ITypeInfo_Release(pTypeInfo);
496 if(pTypeComp_tmp) ITypeComp_Release(pTypeComp_tmp); /* fixme */
497
498 /* test BindType case-insensitivity */
499 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszguid);
500 pTypeComp_tmp = (void*)0xdeadbeef;
501 pTypeInfo = (void*)0xdeadbeef;
502 hr = ITypeComp_BindType(pTypeComp, wszguid, ulHash, &pTypeInfo, &pTypeComp_tmp);
503 ok_ole_success(hr, ITypeComp_BindType);
504 ok(pTypeInfo != NULL, "Got NULL pTypeInfo\n");
505 todo_wine ok(pTypeComp_tmp == NULL, "Got pTypeComp_tmp %p\n", pTypeComp_tmp);
506 ITypeInfo_Release(pTypeInfo);
507 if(pTypeComp_tmp) ITypeComp_Release(pTypeComp_tmp); /* fixme */
508
509 ITypeComp_Release(pTypeComp);
510
511 /* tests for ITypeComp on an interface */
512 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IFont, &pFontTypeInfo);
513 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
514
515 hr = ITypeInfo_GetTypeComp(pFontTypeInfo, &pTypeComp);
516 ok_ole_success(hr, ITypeLib_GetTypeComp);
517
518 hr = ITypeInfo_QueryInterface(pFontTypeInfo, &IID_ITypeComp, (void**)&tcomp);
519 ok(hr == S_OK, "got %08x\n", hr);
520 ok(tcomp == pTypeComp, "got %p, was %p\n", tcomp, pTypeComp);
521
522 hr = ITypeComp_QueryInterface(tcomp, &IID_ITypeInfo, (void**)&ti);
523 ok(hr == S_OK, "got %08x\n", hr);
524 ok(ti == pFontTypeInfo, "got %p, was %p\n", ti, pFontTypeInfo);
525 ITypeInfo_Release(ti);
526
527 ITypeComp_Release(tcomp);
528
529 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszClone);
530 hr = ITypeComp_Bind(pTypeComp, wszClone, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
531 ok_ole_success(hr, ITypeComp_Bind);
532
533 ok(desckind == DESCKIND_FUNCDESC,
534 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
535 desckind);
536 ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
537 ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
538 ITypeInfo_Release(pTypeInfo);
539
540 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszClone);
541 hr = ITypeComp_Bind(pTypeComp, wszClone, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
542 ok(hr == TYPE_E_TYPEMISMATCH, "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n", hr);
543
544 ok(desckind == DESCKIND_NONE,
545 "desckind should have been DESCKIND_NONE instead of %d\n",
546 desckind);
547 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
548 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
549
550 /* tests that the compare is case-insensitive */
551 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszclone);
552 hr = ITypeComp_Bind(pTypeComp, wszclone, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
553 ok_ole_success(hr, ITypeComp_Bind);
554
555 ok(desckind == DESCKIND_FUNCDESC,
556 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
557 desckind);
558 ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
559 ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
560 ITypeInfo_Release(pTypeInfo);
561
562 /* tests nonexistent members */
563 desckind = 0xdeadbeef;
564 bindptr.lptcomp = (ITypeComp*)0xdeadbeef;
565 pTypeInfo = (ITypeInfo*)0xdeadbeef;
566 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszJunk);
567 hr = ITypeComp_Bind(pTypeComp, wszJunk, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
568 ok_ole_success(hr, ITypeComp_Bind);
569 ok(desckind == DESCKIND_NONE, "desckind should have been DESCKIND_NONE, was: %d\n", desckind);
570 ok(pTypeInfo == NULL, "pTypeInfo should have been NULL, was: %p\n", pTypeInfo);
571 ok(bindptr.lptcomp == NULL, "bindptr should have been NULL, was: %p\n", bindptr.lptcomp);
572
573 /* tests inherited members */
574 desckind = 0xdeadbeef;
575 bindptr.lpfuncdesc = NULL;
576 pTypeInfo = NULL;
577 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszAddRef);
578 hr = ITypeComp_Bind(pTypeComp, wszAddRef, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
579 ok_ole_success(hr, ITypeComp_Bind);
580 ok(desckind == DESCKIND_FUNCDESC, "desckind should have been DESCKIND_FUNCDESC, was: %d\n", desckind);
581 ok(pTypeInfo != NULL, "pTypeInfo should not have been NULL, was: %p\n", pTypeInfo);
582 ok(bindptr.lpfuncdesc != NULL, "bindptr should not have been NULL, was: %p\n", bindptr.lpfuncdesc);
583 ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
584 ITypeInfo_Release(pTypeInfo);
585
586 ITypeComp_Release(pTypeComp);
587 ITypeInfo_Release(pFontTypeInfo);
588 ITypeLib_Release(pTypeLib);
589 }
590
591 static void test_CreateDispTypeInfo(void)
592 {
593 ITypeInfo *pTypeInfo, *pTI2;
594 HRESULT hr;
595 INTERFACEDATA ifdata;
596 METHODDATA methdata[4];
597 PARAMDATA parms1[2];
598 PARAMDATA parms3[1];
599 TYPEATTR *pTypeAttr;
600 HREFTYPE href;
601 FUNCDESC *pFuncDesc;
602 MEMBERID memid;
603
604 static WCHAR func1[] = {'f','u','n','c','1',0};
605 static const WCHAR func2[] = {'f','u','n','c','2',0};
606 static const WCHAR func3[] = {'f','u','n','c','3',0};
607 static const WCHAR parm1[] = {'p','a','r','m','1',0};
608 static const WCHAR parm2[] = {'p','a','r','m','2',0};
609 OLECHAR *name = func1;
610
611 ifdata.pmethdata = methdata;
612 ifdata.cMembers = sizeof(methdata) / sizeof(methdata[0]);
613
614 methdata[0].szName = SysAllocString(func1);
615 methdata[0].ppdata = parms1;
616 methdata[0].dispid = 0x123;
617 methdata[0].iMeth = 0;
618 methdata[0].cc = CC_STDCALL;
619 methdata[0].cArgs = 2;
620 methdata[0].wFlags = DISPATCH_METHOD;
621 methdata[0].vtReturn = VT_HRESULT;
622 parms1[0].szName = SysAllocString(parm1);
623 parms1[0].vt = VT_I4;
624 parms1[1].szName = SysAllocString(parm2);
625 parms1[1].vt = VT_BSTR;
626
627 methdata[1].szName = SysAllocString(func2);
628 methdata[1].ppdata = NULL;
629 methdata[1].dispid = 0x124;
630 methdata[1].iMeth = 1;
631 methdata[1].cc = CC_STDCALL;
632 methdata[1].cArgs = 0;
633 methdata[1].wFlags = DISPATCH_PROPERTYGET;
634 methdata[1].vtReturn = VT_I4;
635
636 methdata[2].szName = SysAllocString(func3);
637 methdata[2].ppdata = parms3;
638 methdata[2].dispid = 0x125;
639 methdata[2].iMeth = 3;
640 methdata[2].cc = CC_STDCALL;
641 methdata[2].cArgs = 1;
642 methdata[2].wFlags = DISPATCH_PROPERTYPUT;
643 methdata[2].vtReturn = VT_HRESULT;
644 parms3[0].szName = SysAllocString(parm1);
645 parms3[0].vt = VT_I4;
646
647 methdata[3].szName = SysAllocString(func3);
648 methdata[3].ppdata = NULL;
649 methdata[3].dispid = 0x125;
650 methdata[3].iMeth = 4;
651 methdata[3].cc = CC_STDCALL;
652 methdata[3].cArgs = 0;
653 methdata[3].wFlags = DISPATCH_PROPERTYGET;
654 methdata[3].vtReturn = VT_I4;
655
656 hr = CreateDispTypeInfo(&ifdata, LOCALE_NEUTRAL, &pTypeInfo);
657 ok(hr == S_OK, "hr %08x\n", hr);
658
659 hr = ITypeInfo_GetTypeAttr(pTypeInfo, &pTypeAttr);
660 ok(hr == S_OK, "hr %08x\n", hr);
661
662 ok(pTypeAttr->typekind == TKIND_COCLASS, "typekind %0x\n", pTypeAttr->typekind);
663 ok(pTypeAttr->cImplTypes == 1, "cImplTypes %d\n", pTypeAttr->cImplTypes);
664 ok(pTypeAttr->cFuncs == 0, "cFuncs %d\n", pTypeAttr->cFuncs);
665 ok(pTypeAttr->wTypeFlags == 0, "wTypeFlags %04x\n", pTypeAttr->cFuncs);
666 ITypeInfo_ReleaseTypeAttr(pTypeInfo, pTypeAttr);
667
668 hr = ITypeInfo_GetRefTypeOfImplType(pTypeInfo, 0, &href);
669 ok(hr == S_OK, "hr %08x\n", hr);
670 ok(href == 0, "href = 0x%x\n", href);
671 hr = ITypeInfo_GetRefTypeInfo(pTypeInfo, href, &pTI2);
672 ok(hr == S_OK, "hr %08x\n", hr);
673 hr = ITypeInfo_GetTypeAttr(pTI2, &pTypeAttr);
674 ok(hr == S_OK, "hr %08x\n", hr);
675 ok(pTypeAttr->typekind == TKIND_INTERFACE, "typekind %0x\n", pTypeAttr->typekind);
676 ok(pTypeAttr->cFuncs == 4, "cFuncs %d\n", pTypeAttr->cFuncs);
677 ok(IsEqualGUID(&pTypeAttr->guid, &GUID_NULL), "guid {%08x-...}\n", pTypeAttr->guid.Data1);
678 ok(pTypeAttr->wTypeFlags == 0, "typeflags %08x\n", pTypeAttr->wTypeFlags);
679
680 ITypeInfo_ReleaseTypeAttr(pTI2, pTypeAttr);
681
682 hr = ITypeInfo_GetFuncDesc(pTI2, 0, &pFuncDesc);
683 ok(hr == S_OK, "hr %08x\n", hr);
684 ok(pFuncDesc->memid == 0x123, "memid %x\n", pFuncDesc->memid);
685 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
686 ok(pFuncDesc->invkind == methdata[0].wFlags, "invkind %d\n", pFuncDesc->invkind);
687 ok(pFuncDesc->callconv == methdata[0].cc, "callconv %d\n", pFuncDesc->callconv);
688 ok(pFuncDesc->cParams == methdata[0].cArgs, "cParams %d\n", pFuncDesc->cParams);
689 ok(pFuncDesc->oVft == 0, "oVft %d\n", pFuncDesc->oVft);
690 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
691 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
692 ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
693 ok(U(pFuncDesc->lprgelemdescParam[0]).paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", U(pFuncDesc->lprgelemdescParam[0]).paramdesc.wParamFlags);
694
695 ok(pFuncDesc->lprgelemdescParam[1].tdesc.vt == VT_BSTR, "parm 1 vt %x\n", pFuncDesc->lprgelemdescParam[1].tdesc.vt);
696 ok(U(pFuncDesc->lprgelemdescParam[1]).paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 1 flags %x\n", U(pFuncDesc->lprgelemdescParam[1]).paramdesc.wParamFlags);
697 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
698
699 hr = ITypeInfo_GetFuncDesc(pTI2, 1, &pFuncDesc);
700 ok(hr == S_OK, "hr %08x\n", hr);
701 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
702 ok(pFuncDesc->invkind == methdata[1].wFlags, "invkind %d\n", pFuncDesc->invkind);
703 ok(pFuncDesc->callconv == methdata[1].cc, "callconv %d\n", pFuncDesc->callconv);
704 ok(pFuncDesc->cParams == methdata[1].cArgs, "cParams %d\n", pFuncDesc->cParams);
705 ok(pFuncDesc->oVft == sizeof(void *), "oVft %d\n", pFuncDesc->oVft);
706 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
707 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
708 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
709
710 hr = ITypeInfo_GetFuncDesc(pTI2, 2, &pFuncDesc);
711 ok(hr == S_OK, "hr %08x\n", hr);
712 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
713 ok(pFuncDesc->invkind == methdata[2].wFlags, "invkind %d\n", pFuncDesc->invkind);
714 ok(pFuncDesc->callconv == methdata[2].cc, "callconv %d\n", pFuncDesc->callconv);
715 ok(pFuncDesc->cParams == methdata[2].cArgs, "cParams %d\n", pFuncDesc->cParams);
716 ok(pFuncDesc->oVft == 3 * sizeof(void *), "oVft %d\n", pFuncDesc->oVft);
717 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
718 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
719 ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
720 ok(U(pFuncDesc->lprgelemdescParam[0]).paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", U(pFuncDesc->lprgelemdescParam[0]).paramdesc.wParamFlags);
721 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
722
723 hr = ITypeInfo_GetFuncDesc(pTI2, 3, &pFuncDesc);
724 ok(hr == S_OK, "hr %08x\n", hr);
725 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
726 ok(pFuncDesc->invkind == methdata[3].wFlags, "invkind %d\n", pFuncDesc->invkind);
727 ok(pFuncDesc->callconv == methdata[3].cc, "callconv %d\n", pFuncDesc->callconv);
728 ok(pFuncDesc->cParams == methdata[3].cArgs, "cParams %d\n", pFuncDesc->cParams);
729 ok(pFuncDesc->oVft == 4 * sizeof(void *), "oVft %d\n", pFuncDesc->oVft);
730 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
731 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
732 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
733
734 /* test GetIDsOfNames on a coclass to see if it searches its interfaces */
735 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &name, 1, &memid);
736 ok(hr == S_OK, "hr 0x%08x\n", hr);
737 ok(memid == 0x123, "memid 0x%08x\n", memid);
738
739 ITypeInfo_Release(pTI2);
740 ITypeInfo_Release(pTypeInfo);
741
742 SysFreeString(parms1[0].szName);
743 SysFreeString(parms1[1].szName);
744 SysFreeString(parms3[0].szName);
745 SysFreeString(methdata[0].szName);
746 SysFreeString(methdata[1].szName);
747 SysFreeString(methdata[2].szName);
748 SysFreeString(methdata[3].szName);
749 }
750
751 static void write_typelib(int res_no, const char *filename)
752 {
753 DWORD written;
754 HANDLE file;
755 HRSRC res;
756 void *ptr;
757
758 file = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
759 ok( file != INVALID_HANDLE_VALUE, "file creation failed\n" );
760 if (file == INVALID_HANDLE_VALUE) return;
761 res = FindResourceA( GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(res_no), "TYPELIB" );
762 ok( res != 0, "couldn't find resource\n" );
763 ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
764 WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
765 ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
766 CloseHandle( file );
767 }
768
769 static void test_invoke_func(ITypeInfo *typeinfo)
770 {
771 DISPID named_args[3] = { DISPID_THIS };
772 VARIANT args[3], res;
773 DISPPARAMS dp = {args, named_args, 1, 0};
774 UINT i;
775 HRESULT hres;
776
777 V_VT(args) = VT_INT;
778 V_INT(args) = 3;
779 V_VT(&res) = VT_ERROR;
780 hres = ITypeInfo_Invoke(typeinfo, &invoketest, 3, DISPATCH_METHOD, &dp, &res, NULL, &i);
781 ok(hres == S_OK, "got 0x%08x\n", hres);
782 ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res));
783 ok(V_I4(&res) == 4, "got %d\n", V_I4(&res));
784
785 V_VT(args) = VT_DISPATCH;
786 V_DISPATCH(args) = (IDispatch*)&invoketest;
787 V_VT(args+1) = VT_INT;
788 V_INT(args+1) = 3;
789 V_VT(&res) = VT_ERROR;
790 dp.cNamedArgs = 1;
791 dp.cArgs = 2;
792 hres = ITypeInfo_Invoke(typeinfo, &invoketest, 3, DISPATCH_METHOD, &dp, &res, NULL, &i);
793 ok(hres == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hres);
794 }
795
796 static const char *create_test_typelib(int res_no)
797 {
798 static char filename[MAX_PATH];
799
800 GetTempFileNameA( ".", "tlb", 0, filename );
801 write_typelib(res_no, filename);
802 return filename;
803 }
804
805 static void test_TypeInfo(void)
806 {
807 ITypeLib *pTypeLib;
808 ITypeInfo *pTypeInfo, *ti;
809 ITypeInfo2 *pTypeInfo2;
810 HRESULT hr;
811 static WCHAR wszBogus[] = { 'b','o','g','u','s',0 };
812 static WCHAR wszGetTypeInfo[] = { 'G','e','t','T','y','p','e','I','n','f','o',0 };
813 static WCHAR wszClone[] = {'C','l','o','n','e',0};
814 OLECHAR* bogus = wszBogus;
815 OLECHAR* pwszGetTypeInfo = wszGetTypeInfo;
816 OLECHAR* pwszClone = wszClone;
817 DISPID dispidMember;
818 DISPPARAMS dispparams;
819 GUID bogusguid = {0x806afb4f,0x13f7,0x42d2,{0x89,0x2c,0x6c,0x97,0xc3,0x6a,0x36,0xc1}};
820 VARIANT var, res, args[2];
821 UINT count, i;
822 TYPEKIND kind;
823 const char *filenameA;
824 WCHAR filename[MAX_PATH];
825 TYPEATTR *attr;
826 LONG l;
827
828 hr = LoadTypeLib(wszStdOle2, &pTypeLib);
829 ok_ole_success(hr, LoadTypeLib);
830
831 count = ITypeLib_GetTypeInfoCount(pTypeLib);
832 ok(count > 0, "got %d\n", count);
833
834 /* invalid index */
835 hr = ITypeLib_GetTypeInfo(pTypeLib, count, &pTypeInfo);
836 ok(hr == TYPE_E_ELEMENTNOTFOUND, "got 0x%08x\n", hr);
837
838 hr = ITypeLib_GetTypeInfo(pTypeLib, 0, NULL);
839 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
840
841 hr = ITypeLib_GetLibAttr(pTypeLib, NULL);
842 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
843
844 hr = ITypeLib_GetTypeInfoType(pTypeLib, count, &kind);
845 ok(hr == TYPE_E_ELEMENTNOTFOUND, "got 0x%08x\n", hr);
846
847 hr = ITypeLib_GetTypeInfoType(pTypeLib, count, NULL);
848 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
849
850 hr = ITypeLib_GetTypeInfoType(pTypeLib, 0, NULL);
851 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
852
853 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IFont, &pTypeInfo);
854 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
855
856 /* test nonexistent method name */
857 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &bogus, 1, &dispidMember);
858 ok(hr == DISP_E_UNKNOWNNAME,
859 "ITypeInfo_GetIDsOfNames should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n",
860 hr);
861
862 dispparams.cArgs = 0;
863 dispparams.rgdispidNamedArgs = NULL;
864 dispparams.rgvarg = NULL;
865
866 /* test dispparams not NULL */
867
868 /* invalid member id -- wrong flags -- cNamedArgs not bigger than cArgs */
869 dispparams.cNamedArgs = 0;
870 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
871 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
872 /* invalid member id -- correct flags -- cNamedArgs not bigger than cArgs */
873 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
874 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
875
876 /* invalid member id -- wrong flags -- cNamedArgs bigger than cArgs */
877 dispparams.cNamedArgs = 1;
878 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
879 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
880 /* invalid member id -- correct flags -- cNamedArgs bigger than cArgs */
881 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
882 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
883
884
885 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &pwszClone, 1, &dispidMember);
886 ok_ole_success(hr, ITypeInfo_GetIDsOfNames);
887
888 /* correct member id -- wrong flags -- cNamedArgs not bigger than cArgs */
889 dispparams.cNamedArgs = 0;
890 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
891 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
892 /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs */
893 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
894 ok(hr == DISP_E_BADPARAMCOUNT, "ITypeInfo_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
895
896 /* correct member id -- wrong flags -- cNamedArgs bigger than cArgs */
897 dispparams.cNamedArgs = 1;
898 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
899 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
900 /* correct member id -- correct flags -- cNamedArgs bigger than cArgs */
901 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
902 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
903
904 /* test NULL dispparams */
905
906 /* correct member id -- wrong flags -- cNamedArgs not bigger than cArgs */
907 dispparams.cNamedArgs = 0;
908 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
909 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
910 /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs */
911 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, NULL, NULL, NULL, NULL);
912 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
913
914 /* correct member id -- wrong flags -- cNamedArgs bigger than cArgs */
915 dispparams.cNamedArgs = 1;
916 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
917 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
918 /* correct member id -- correct flags -- cNamedArgs bigger than cArgs */
919 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, NULL, NULL, NULL, NULL);
920 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
921
922 ITypeInfo_Release(pTypeInfo);
923
924 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IDispatch, &pTypeInfo);
925 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
926
927 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &pwszGetTypeInfo, 1, &dispidMember);
928 ok_ole_success(hr, ITypeInfo_GetIDsOfNames);
929
930 hr = ITypeInfo_QueryInterface(pTypeInfo, &IID_ITypeInfo2, (void**)&pTypeInfo2);
931 ok_ole_success(hr, ITypeInfo_QueryInterface);
932
933 if (SUCCEEDED(hr))
934 {
935 VariantInit(&var);
936
937 V_VT(&var) = VT_I4;
938
939 /* test unknown guid passed to GetCustData */
940 hr = ITypeInfo2_GetCustData(pTypeInfo2, &bogusguid, &var);
941 ok_ole_success(hr, ITypeInfo_GetCustData);
942 ok(V_VT(&var) == VT_EMPTY, "got %i, expected VT_EMPTY\n", V_VT(&var));
943
944 ITypeInfo2_Release(pTypeInfo2);
945
946 VariantClear(&var);
947 }
948
949 /* Check instance size for IDispatch, typelib is loaded using system SYS_WIN* kind so it always matches
950 system bitness. */
951 hr = ITypeInfo_GetTypeAttr(pTypeInfo, &attr);
952 ok(hr == S_OK, "got 0x%08x\n", hr);
953 ok(attr->cbSizeInstance == sizeof(void*), "got size %d\n", attr->cbSizeInstance);
954 ok(attr->typekind == TKIND_INTERFACE, "got typekind %d\n", attr->typekind);
955 ITypeInfo_ReleaseTypeAttr(pTypeInfo, attr);
956
957 /* same size check with some general interface */
958 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IEnumVARIANT, &ti);
959 ok(hr == S_OK, "got 0x%08x\n", hr);
960 hr = ITypeInfo_GetTypeAttr(ti, &attr);
961 ok(hr == S_OK, "got 0x%08x\n", hr);
962 ok(attr->cbSizeInstance == sizeof(void*), "got size %d\n", attr->cbSizeInstance);
963 ITypeInfo_ReleaseTypeAttr(ti, attr);
964 ITypeInfo_Release(ti);
965
966 /* test invoking a method with a [restricted] keyword */
967
968 /* correct member id -- wrong flags -- cNamedArgs not bigger than cArgs */
969 dispparams.cNamedArgs = 0;
970 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
971 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
972 /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs */
973 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
974 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
975
976 /* correct member id -- wrong flags -- cNamedArgs bigger than cArgs */
977 dispparams.cNamedArgs = 1;
978 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
979 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
980 /* correct member id -- correct flags -- cNamedArgs bigger than cArgs */
981 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
982 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
983
984 /* test NULL dispparams */
985
986 /* correct member id -- wrong flags -- cNamedArgs not bigger than cArgs */
987 dispparams.cNamedArgs = 0;
988 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
989 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
990 /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs */
991 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, NULL, NULL, NULL, NULL);
992 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
993
994 /* correct member id -- wrong flags -- cNamedArgs bigger than cArgs */
995 dispparams.cNamedArgs = 1;
996 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
997 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
998 /* correct member id -- correct flags -- cNamedArgs bigger than cArgs */
999 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, NULL, NULL, NULL, NULL);
1000 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
1001
1002 ITypeInfo_Release(pTypeInfo);
1003 ITypeLib_Release(pTypeLib);
1004
1005 filenameA = create_test_typelib(3);
1006 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filename, MAX_PATH);
1007 hr = LoadTypeLib(filename, &pTypeLib);
1008 ok(hr == S_OK, "got 0x%08x\n", hr);
1009
1010 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IInvokeTest, &pTypeInfo);
1011 ok(hr == S_OK, "got 0x%08x\n", hr);
1012
1013 dispparams.cArgs = 1;
1014 dispparams.cNamedArgs = 0;
1015 dispparams.rgdispidNamedArgs = NULL;
1016 dispparams.rgvarg = args;
1017
1018 V_VT(&args[0]) = VT_I4;
1019 V_I4(&args[0]) = 0;
1020
1021 i = 0;
1022 V_VT(&res) = VT_EMPTY;
1023 V_I4(&res) = 0;
1024 /* call propget with DISPATCH_METHOD|DISPATCH_PROPERTYGET flags */
1025 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, DISPID_VALUE, DISPATCH_METHOD|DISPATCH_PROPERTYGET,
1026 &dispparams, &res, NULL, &i);
1027 ok(hr == S_OK, "got 0x%08x\n", hr);
1028 ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res));
1029 ok(V_I4(&res) == 1, "got %d\n", V_I4(&res));
1030
1031 i = 0;
1032 /* call propget with DISPATCH_METHOD flags */
1033 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, DISPID_VALUE, DISPATCH_METHOD,
1034 &dispparams, &res, NULL, &i);
1035 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x, %d\n", hr, i);
1036
1037 i = 0;
1038 V_VT(&res) = VT_EMPTY;
1039 V_I4(&res) = 0;
1040 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, DISPID_VALUE, DISPATCH_PROPERTYGET,
1041 &dispparams, &res, NULL, &i);
1042 ok(hr == S_OK, "got 0x%08x, %d\n", hr, i);
1043 ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res));
1044 ok(V_I4(&res) == 1, "got %d\n", V_I4(&res));
1045
1046 /* call propget with DISPATCH_METHOD|DISPATCH_PROPERTYGET flags */
1047 V_VT(&args[0]) = VT_I4;
1048 V_I4(&args[0]) = 7;
1049
1050 dispparams.cArgs = 1;
1051 dispparams.rgvarg = args;
1052
1053 i = 0;
1054 V_VT(&res) = VT_EMPTY;
1055 V_I4(&res) = 0;
1056 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, 4, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, &res, NULL, &i);
1057 ok(hr == S_OK, "got 0x%08x, %d\n", hr, i);
1058 ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res));
1059 ok(V_I4(&res) == 15, "got %d\n", V_I4(&res));
1060
1061
1062 /* DISPATCH_PROPERTYPUTREF */
1063 l = 1;
1064 V_VT(&args[0]) = VT_I4|VT_BYREF;
1065 V_I4REF(&args[0]) = &l;
1066
1067 dispidMember = DISPID_PROPERTYPUT;
1068 dispparams.cArgs = 1;
1069 dispparams.cNamedArgs = 1;
1070 dispparams.rgdispidNamedArgs = &dispidMember;
1071 dispparams.rgvarg = args;
1072
1073 i = 0;
1074 V_VT(&res) = VT_EMPTY;
1075 V_I4(&res) = 0;
1076 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, 1, DISPATCH_PROPERTYPUTREF, &dispparams, &res, NULL, &i);
1077 ok(hr == S_OK, "got 0x%08x, %d\n", hr, i);
1078 ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res));
1079 ok(V_I4(&res) == 3, "got %d\n", V_I4(&res));
1080
1081 i = 0;
1082 V_VT(&res) = VT_EMPTY;
1083 V_I4(&res) = 0;
1084 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, 1, DISPATCH_PROPERTYPUT, &dispparams, &res, NULL, &i);
1085 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x, %d\n", hr, i);
1086
1087 i = 0;
1088 V_VT(&args[0]) = VT_UNKNOWN;
1089 V_UNKNOWN(&args[0]) = NULL;
1090
1091 V_VT(&res) = VT_EMPTY;
1092 V_I4(&res) = 0;
1093 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, 2, DISPATCH_PROPERTYPUTREF, &dispparams, &res, NULL, &i);
1094 ok(hr == S_OK, "got 0x%08x, %d\n", hr, i);
1095 ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res));
1096 ok(V_I4(&res) == 6, "got %d\n", V_I4(&res));
1097
1098 i = 0;
1099 V_VT(&res) = VT_EMPTY;
1100 V_I4(&res) = 0;
1101 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, 2, DISPATCH_PROPERTYPUT, &dispparams, &res, NULL, &i);
1102 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x, %d\n", hr, i);
1103
1104 test_invoke_func(pTypeInfo);
1105
1106 ITypeInfo_Release(pTypeInfo);
1107 ITypeLib_Release(pTypeLib);
1108 DeleteFileA(filenameA);
1109 }
1110
1111 static int WINAPI int_func( int a0, int a1, int a2, int a3, int a4 )
1112 {
1113 ok( a0 == 1, "wrong arg0 %x\n", a0 );
1114 ok( a1 == -1, "wrong arg1 %x\n", a1 );
1115 ok( a2 == (0x55550000 | 1234), "wrong arg2 %x\n", a2 );
1116 ok( a3 == 0xdeadbeef, "wrong arg3 %x\n", a3 );
1117 ok( a4 == 0x555555fd, "wrong arg4 %x\n", a4 );
1118 return 4321;
1119 }
1120
1121 static double WINAPI double_func( double a0, float a1, double a2, int a3 )
1122 {
1123 ok( a0 == 1.2, "wrong arg0 %f\n", (double)a0 );
1124 ok( a1 == 3.25, "wrong arg1 %f\n", (double)a1 );
1125 ok( a2 == 1.2e12, "wrong arg2 %f\n", (double)a2);
1126 ok( a3 == -4433.0, "wrong arg3 %f\n", (double)a3 );
1127 return 4321;
1128 }
1129
1130 static LONGLONG WINAPI longlong_func( LONGLONG a0, CY a1 )
1131 {
1132 ok( a0 == (((ULONGLONG)0xdead << 32) | 0xbeef), "wrong arg0 %08x%08x\n", (DWORD)(a0 >> 32), (DWORD)a0);
1133 ok( a1.int64 == ((ULONGLONG)10000 * 12345678), "wrong arg1 %08x%08x\n",
1134 (DWORD)(a1.int64 >> 32), (DWORD)a1.int64 );
1135 return ((ULONGLONG)4321 << 32) | 8765;
1136 }
1137
1138 static VARIANT WINAPI variant_func( int a0, BOOL a1, DECIMAL a2, VARIANT a3 )
1139 {
1140 VARIANT var;
1141 ok( a0 == 2233, "wrong arg0 %x\n", a0 );
1142 ok( a1 == 1 || broken(a1 == 0x55550001), "wrong arg1 %x\n", a1 );
1143 V_VT(&var) = VT_LPWSTR;
1144 V_UI4(&var) = 0xbabe;
1145 ok( a2.Hi32 == 1122, "wrong arg2.Hi32 %x\n", a2.Hi32 );
1146 ok( U1(a2).Lo64 == 3344, "wrong arg2.Lo64 %08x%08x\n", (DWORD)(U1(a2).Lo64 >> 32), (DWORD)U1(a2).Lo64 );
1147 ok( V_VT(&a3) == VT_EMPTY, "wrong arg3 type %x\n", V_VT(&a3) );
1148 ok( V_UI4(&a3) == 0xdeadbeef, "wrong arg3 value %x\n", V_UI4(&a3) );
1149 return var;
1150 }
1151
1152 static int CDECL void_func( int a0, int a1 )
1153 {
1154 if (is_win64) /* VT_EMPTY is passed as real arg on win64 */
1155 {
1156 ok( a0 == 0x55555555, "wrong arg0 %x\n", a0 );
1157 ok( a1 == 1111, "wrong arg1 %x\n", a1 );
1158 }
1159 else
1160 {
1161 ok( a0 == 1111, "wrong arg0 %x\n", a0 );
1162 ok( a1 == 0, "wrong arg1 %x\n", a1 );
1163 }
1164 return 12;
1165 }
1166
1167 static int WINAPI stdcall_func( int a )
1168 {
1169 return 0;
1170 }
1171
1172 static int WINAPI inst_func( void *inst, int a )
1173 {
1174 ok( (*(void ***)inst)[3] == inst_func, "wrong ptr %p\n", inst );
1175 ok( a == 3, "wrong arg %x\n", a );
1176 return a * 2;
1177 }
1178
1179 static HRESULT WINAPI ret_false_func(void)
1180 {
1181 return S_FALSE;
1182 }
1183
1184 static const void *vtable[] = { NULL, NULL, NULL, inst_func };
1185
1186 static void test_DispCallFunc(void)
1187 {
1188 const void **inst = vtable;
1189 HRESULT res;
1190 VARIANT result, args[5];
1191 VARIANTARG *pargs[5];
1192 VARTYPE types[5];
1193 int i;
1194
1195 for (i = 0; i < 5; i++) pargs[i] = &args[i];
1196
1197 memset( args, 0x55, sizeof(args) );
1198 types[0] = VT_UI4;
1199 V_UI4(&args[0]) = 1;
1200 types[1] = VT_I4;
1201 V_I4(&args[1]) = -1;
1202 types[2] = VT_I2;
1203 V_I2(&args[2]) = 1234;
1204 types[3] = VT_UI4;
1205 V_UI4(&args[3]) = 0xdeadbeef;
1206 types[4] = VT_UI4;
1207 V_I1(&args[4]) = -3;
1208 memset( &result, 0xcc, sizeof(result) );
1209 res = DispCallFunc( NULL, (ULONG_PTR)int_func, CC_STDCALL, VT_UI4, 5, types, pargs, &result );
1210 ok( res == S_OK, "DispCallFunc failed %x\n", res );
1211 ok( V_VT(&result) == VT_UI4, "wrong result type %d\n", V_VT(&result) );
1212 ok( V_UI4(&result) == 4321, "wrong result %u\n", V_UI4(&result) );
1213
1214 /* the function checks the argument sizes for stdcall */
1215 if (abi_supports_stdcall)
1216 {
1217 res = DispCallFunc( NULL, (ULONG_PTR)stdcall_func, CC_STDCALL, VT_UI4, 0, types, pargs, &result );
1218 ok( res == DISP_E_BADCALLEE, "DispCallFunc wrong error %x\n", res );
1219 res = DispCallFunc( NULL, (ULONG_PTR)stdcall_func, CC_STDCALL, VT_UI4, 1, types, pargs, &result );
1220 ok( res == S_OK, "DispCallFunc failed %x\n", res );
1221 res = DispCallFunc( NULL, (ULONG_PTR)stdcall_func, CC_STDCALL, VT_UI4, 2, types, pargs, &result );
1222 ok( res == DISP_E_BADCALLEE, "DispCallFunc wrong error %x\n", res );
1223 }
1224
1225 memset( args, 0x55, sizeof(args) );
1226 types[0] = VT_R8;
1227 V_R8(&args[0]) = 1.2;
1228 types[1] = VT_R4;
1229 V_R4(&args[1]) = 3.25;
1230 types[2] = VT_R8;
1231 V_R8(&args[2]) = 1.2e12;
1232 types[3] = VT_I4;
1233 V_I4(&args[3]) = -4433;
1234 memset( &result, 0xcc, sizeof(result) );
1235 res = DispCallFunc( NULL, (ULONG_PTR)double_func, CC_STDCALL, VT_R8, 4, types, pargs, &result );
1236 ok( res == S_OK, "DispCallFunc failed %x\n", res );
1237 ok( V_VT(&result) == VT_R8, "wrong result type %d\n", V_VT(&result) );
1238 ok( V_R8(&result) == 4321, "wrong result %f\n", V_R8(&result) );
1239
1240 memset( args, 0x55, sizeof(args) );
1241 types[0] = VT_I8;
1242 V_I8(&args[0]) = ((ULONGLONG)0xdead << 32) | 0xbeef;
1243 types[1] = VT_CY;
1244 V_CY(&args[1]).int64 = (ULONGLONG)10000 * 12345678;
1245 memset( &result, 0xcc, sizeof(result) );
1246 res = DispCallFunc( NULL, (ULONG_PTR)longlong_func, CC_STDCALL, VT_I8, 2, types, pargs, &result );
1247 ok( res == S_OK || broken(res == E_INVALIDARG), /* longlong not supported on <= win2k */
1248 "DispCallFunc failed %x\n", res );
1249 if (res == S_OK)
1250 {
1251 ok( V_VT(&result) == VT_I8, "wrong result type %d\n", V_VT(&result) );
1252 ok( V_I8(&result) == (((ULONGLONG)4321 << 32) | 8765), "wrong result %08x%08x\n",
1253 (DWORD)(V_I8(&result) >> 32), (DWORD)V_I8(&result) );
1254 }
1255
1256 memset( args, 0x55, sizeof(args) );
1257 types[0] = VT_I4;
1258 V_I4(&args[0]) = 2233;
1259 types[1] = VT_BOOL;
1260 V_BOOL(&args[1]) = 1;
1261 types[2] = VT_DECIMAL;
1262 V_DECIMAL(&args[2]).Hi32 = 1122;
1263 U1(V_DECIMAL(&args[2])).Lo64 = 3344;
1264 types[3] = VT_VARIANT;
1265 V_VT(&args[3]) = VT_EMPTY;
1266 V_UI4(&args[3]) = 0xdeadbeef;
1267 types[4] = VT_EMPTY;
1268 memset( &result, 0xcc, sizeof(result) );
1269 res = DispCallFunc( NULL, (ULONG_PTR)variant_func, CC_STDCALL, VT_VARIANT, 5, types, pargs, &result );
1270 ok( res == S_OK, "DispCallFunc failed %x\n", res );
1271 ok( V_VT(&result) == VT_LPWSTR, "wrong result type %d\n", V_VT(&result) );
1272 ok( V_UI4(&result) == 0xbabe, "wrong result %08x\n", V_UI4(&result) );
1273
1274 memset( args, 0x55, sizeof(args) );
1275 types[0] = VT_EMPTY;
1276 types[1] = VT_I4;
1277 V_I4(&args[1]) = 1111;
1278 types[2] = VT_EMPTY;
1279 types[3] = VT_I4;
1280 V_I4(&args[3]) = 0;
1281 types[4] = VT_EMPTY;
1282 memset( &result, 0xcc, sizeof(result) );
1283 res = DispCallFunc( NULL, (ULONG_PTR)void_func, CC_CDECL, VT_EMPTY, 5, types, pargs, &result );
1284 ok( res == S_OK, "DispCallFunc failed %x\n", res );
1285 ok( V_VT(&result) == VT_EMPTY, "wrong result type %d\n", V_VT(&result) );
1286 if (is_win64)
1287 ok( V_UI4(&result) == 12, "wrong result %08x\n", V_UI4(&result) );
1288 else
1289 ok( V_UI4(&result) == 0xcccccccc, "wrong result %08x\n", V_UI4(&result) );
1290
1291 memset( args, 0x55, sizeof(args) );
1292 types[0] = VT_I4;
1293 V_I4(&args[0]) = 3;
1294 memset( &result, 0xcc, sizeof(result) );
1295 res = DispCallFunc( &inst, 3 * sizeof(void*), CC_STDCALL, VT_I4, 1, types, pargs, &result );
1296 ok( res == S_OK, "DispCallFunc failed %x\n", res );
1297 ok( V_VT(&result) == VT_I4, "wrong result type %d\n", V_VT(&result) );
1298 ok( V_I4(&result) == 6, "wrong result %08x\n", V_I4(&result) );
1299
1300 memset( &result, 0xcc, sizeof(result) );
1301 res = DispCallFunc(NULL, (ULONG_PTR)ret_false_func, CC_STDCALL, VT_ERROR, 0, NULL, NULL, &result);
1302 ok(res == S_OK, "DispCallFunc failed: %08x\n", res);
1303 ok(V_VT(&result) == VT_ERROR, "V_VT(result) = %u\n", V_VT(&result));
1304 ok(V_ERROR(&result) == S_FALSE, "V_ERROR(result) = %08x\n", V_ERROR(&result));
1305
1306 memset( &result, 0xcc, sizeof(result) );
1307 res = DispCallFunc(NULL, (ULONG_PTR)ret_false_func, CC_STDCALL, VT_HRESULT, 0, NULL, NULL, &result);
1308 ok(res == E_INVALIDARG, "DispCallFunc failed: %08x\n", res);
1309 ok(V_VT(&result) == 0xcccc, "V_VT(result) = %u\n", V_VT(&result));
1310 }
1311
1312 /* RegDeleteTreeW from dlls/advapi32/registry.c, plus additional view flag */
1313 static LSTATUS myRegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM view)
1314 {
1315 LONG ret;
1316 DWORD dwMaxSubkeyLen, dwMaxValueLen;
1317 DWORD dwMaxLen, dwSize;
1318 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
1319 HKEY hSubKey = hKey;
1320 view &= (KEY_WOW64_64KEY | KEY_WOW64_32KEY);
1321
1322 if(lpszSubKey)
1323 {
1324 ret = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ | view, &hSubKey);
1325 if (ret) return ret;
1326 }
1327
1328 ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
1329 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
1330 if (ret) goto cleanup;
1331
1332 dwMaxSubkeyLen++;
1333 dwMaxValueLen++;
1334 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
1335 if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR))
1336 {
1337 /* Name too big: alloc a buffer for it */
1338 if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(WCHAR))))
1339 {
1340 ret = ERROR_NOT_ENOUGH_MEMORY;
1341 goto cleanup;
1342 }
1343 }
1344
1345 /* Recursively delete all the subkeys */
1346 while (TRUE)
1347 {
1348 dwSize = dwMaxLen;
1349 if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
1350 NULL, NULL, NULL)) break;
1351
1352 ret = myRegDeleteTreeW(hSubKey, lpszName, view);
1353 if (ret) goto cleanup;
1354 }
1355
1356 if (lpszSubKey)
1357 if (pRegDeleteKeyExW && view != 0)
1358 ret = pRegDeleteKeyExW(hKey, lpszSubKey, view, 0);
1359 else
1360 ret = RegDeleteKeyW(hKey, lpszSubKey);
1361 else
1362 while (TRUE)
1363 {
1364 dwSize = dwMaxLen;
1365 if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
1366 NULL, NULL, NULL, NULL)) break;
1367
1368 ret = RegDeleteValueW(hKey, lpszName);
1369 if (ret) goto cleanup;
1370 }
1371
1372 cleanup:
1373 if (lpszName != szNameBuf)
1374 HeapFree(GetProcessHeap(), 0, lpszName);
1375 if(lpszSubKey)
1376 RegCloseKey(hSubKey);
1377 return ret;
1378 }
1379
1380 static BOOL do_typelib_reg_key(GUID *uid, WORD maj, WORD min, DWORD arch, LPCWSTR base, BOOL remove)
1381 {
1382 static const WCHAR typelibW[] = {'T','y','p','e','l','i','b','\\',0};
1383 static const WCHAR formatW[] = {'\\','%','u','.','%','u','\\','0','\\','w','i','n','%','u',0};
1384 static const WCHAR format2W[] = {'%','s','_','%','u','_','%','u','.','d','l','l',0};
1385 WCHAR buf[128];
1386 HKEY hkey;
1387 BOOL ret = TRUE;
1388 DWORD res;
1389
1390 memcpy(buf, typelibW, sizeof(typelibW));
1391 StringFromGUID2(uid, buf + lstrlenW(buf), 40);
1392
1393 if (remove)
1394 {
1395 ok(myRegDeleteTreeW(HKEY_CLASSES_ROOT, buf, 0) == ERROR_SUCCESS, "SHDeleteKey failed\n");
1396 return TRUE;
1397 }
1398
1399 wsprintfW(buf + lstrlenW(buf), formatW, maj, min, arch);
1400
1401 SetLastError(0xdeadbeef);
1402 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0,
1403 KEY_WRITE, NULL, &hkey, NULL);
1404 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1405 {
1406 win_skip("W-calls are not implemented\n");
1407 return FALSE;
1408 }
1409
1410 if (res != ERROR_SUCCESS)
1411 {
1412 trace("RegCreateKeyExW failed: %u\n", res);
1413 return FALSE;
1414 }
1415
1416 wsprintfW(buf, format2W, base, maj, min);
1417 if (RegSetValueExW(hkey, NULL, 0, REG_SZ,
1418 (BYTE *)buf, (lstrlenW(buf) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS)
1419 {
1420 trace("RegSetValueExW failed\n");
1421 ret = FALSE;
1422 }
1423 RegCloseKey(hkey);
1424 return ret;
1425 }
1426
1427 static void test_QueryPathOfRegTypeLib(DWORD arch)
1428 {
1429 static const struct test_data
1430 {
1431 WORD maj, min;
1432 HRESULT ret;
1433 const WCHAR path[16];
1434 } td[] = {
1435 { 1, 0, TYPE_E_LIBNOTREGISTERED, { 0 } },
1436 { 3, 0, S_OK, {'f','a','k','e','_','3','_','0','.','d','l','l',0 } },
1437 { 3, 1, S_OK, {'f','a','k','e','_','3','_','1','.','d','l','l',0 } },
1438 { 3, 22, S_OK, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
1439 { 3, 37, S_OK, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
1440 { 3, 40, S_OK, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
1441 { 0xffff, 0xffff, S_OK, {'f','a','k','e','_','5','_','3','7','.','d','l','l',0 } },
1442 { 0xffff, 0, TYPE_E_LIBNOTREGISTERED, { 0 } },
1443 { 3, 0xffff, TYPE_E_LIBNOTREGISTERED, { 0 } },
1444 { 5, 0xffff, TYPE_E_LIBNOTREGISTERED, { 0 } },
1445 { 4, 0, TYPE_E_LIBNOTREGISTERED, { 0 } }
1446 };
1447 static const WCHAR base[] = {'f','a','k','e',0};
1448 static const WCHAR wrongW[] = {'w','r','o','n','g',0};
1449 UINT i;
1450 RPC_STATUS status;
1451 GUID uid;
1452 WCHAR uid_str[40];
1453 HRESULT ret;
1454 BSTR path;
1455
1456 status = UuidCreate(&uid);
1457 ok(!status || status == RPC_S_UUID_LOCAL_ONLY, "UuidCreate error %08x\n", status);
1458
1459 StringFromGUID2(&uid, uid_str, 40);
1460 /*trace("GUID: %s\n", wine_dbgstr_w(uid_str));*/
1461
1462 if (!do_typelib_reg_key(&uid, 3, 0, arch, base, FALSE)) return;
1463 if (!do_typelib_reg_key(&uid, 3, 1, arch, base, FALSE)) return;
1464 if (!do_typelib_reg_key(&uid, 3, 37, arch, base, FALSE)) return;
1465 if (!do_typelib_reg_key(&uid, 5, 37, arch, base, FALSE)) return;
1466 if (arch == 64 && !do_typelib_reg_key(&uid, 5, 37, 32, wrongW, FALSE)) return;
1467
1468 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
1469 {
1470 ret = QueryPathOfRegTypeLib(&uid, td[i].maj, td[i].min, LOCALE_NEUTRAL, &path);
1471 ok(ret == td[i].ret, "QueryPathOfRegTypeLib(%u.%u) returned %08x\n", td[i].maj, td[i].min, ret);
1472 if (ret == S_OK)
1473 {
1474 ok(!lstrcmpW(td[i].path, path), "typelib %u.%u path doesn't match\n", td[i].maj, td[i].min);
1475 SysFreeString(path);
1476 }
1477 }
1478
1479 do_typelib_reg_key(&uid, 0, 0, arch, NULL, TRUE);
1480 }
1481
1482 static void test_inheritance(void)
1483 {
1484 HRESULT hr;
1485 ITypeLib *pTL;
1486 ITypeInfo *pTI, *pTI_p;
1487 TYPEATTR *pTA;
1488 HREFTYPE href;
1489 FUNCDESC *pFD;
1490 WCHAR path[MAX_PATH];
1491 CHAR pathA[MAX_PATH];
1492 static const WCHAR tl_path[] = {'.','\\','m','i','d','l','_','t','m','a','r','s','h','a','l','.','t','l','b',0};
1493
1494 BOOL use_midl_tlb = FALSE;
1495
1496 GetModuleFileNameA(NULL, pathA, MAX_PATH);
1497 MultiByteToWideChar(CP_ACP, 0, pathA, -1, path, MAX_PATH);
1498
1499 if(use_midl_tlb)
1500 memcpy(path, tl_path, sizeof(tl_path));
1501
1502 hr = LoadTypeLib(path, &pTL);
1503 if(FAILED(hr)) return;
1504
1505
1506 /* ItestIF3 is a syntax 2 dispinterface */
1507 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF3, &pTI);
1508 ok(hr == S_OK, "hr %08x\n", hr);
1509
1510 hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
1511 ok(hr == S_OK, "hr %08x\n", hr);
1512 ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
1513 ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1514 ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags);
1515 if(use_midl_tlb) {
1516 ok(pTA->cFuncs == 6, "cfuncs %d\n", pTA->cFuncs);
1517 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1518 }
1519 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1520
1521 if(use_midl_tlb) {
1522 hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
1523 ok(hr == S_OK, "hr %08x\n", hr);
1524 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1525 ok(hr == S_OK, "hr %08x\n", hr);
1526 hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
1527 ok(hr == S_OK, "got %08x\n", hr);
1528 ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
1529 ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
1530 ITypeInfo_Release(pTI_p);
1531
1532 /* Should have six methods */
1533 hr = ITypeInfo_GetFuncDesc(pTI, 6, &pFD);
1534 ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
1535 hr = ITypeInfo_GetFuncDesc(pTI, 5, &pFD);
1536 ok(hr == S_OK, "hr %08x\n", hr);
1537 ok(pFD->memid == 0x60020000, "memid %08x\n", pFD->memid);
1538 ok(pFD->oVft == 5 * sizeof(void *), "oVft %d\n", pFD->oVft);
1539 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1540 }
1541 ITypeInfo_Release(pTI);
1542
1543
1544 /* ItestIF4 is a syntax 1 dispinterface */
1545 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF4, &pTI);
1546 ok(hr == S_OK, "hr %08x\n", hr);
1547
1548 hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
1549 ok(hr == S_OK, "hr %08x\n", hr);
1550 ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
1551 ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1552 ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags);
1553 ok(pTA->cFuncs == 1, "cfuncs %d\n", pTA->cFuncs);
1554 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1555 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1556
1557 hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
1558 ok(hr == S_OK, "hr %08x\n", hr);
1559 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1560 ok(hr == S_OK, "hr %08x\n", hr);
1561 hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
1562 ok(hr == S_OK, "got %08x\n", hr);
1563 ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
1564 ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
1565 ITypeInfo_Release(pTI_p);
1566 hr = ITypeInfo_GetFuncDesc(pTI, 1, &pFD);
1567 ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
1568 hr = ITypeInfo_GetFuncDesc(pTI, 0, &pFD);
1569 ok(hr == S_OK, "hr %08x\n", hr);
1570 ok(pFD->memid == 0x1c, "memid %08x\n", pFD->memid);
1571 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1572 ITypeInfo_Release(pTI);
1573
1574
1575 /* ItestIF5 is dual with inherited ifaces which derive from IUnknown but not IDispatch */
1576 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &IID_ItestIF5, &pTI);
1577 ok(hr == S_OK, "hr %08x\n", hr);
1578
1579 hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
1580 ok(hr == S_OK, "hr %08x\n", hr);
1581 if (hr == S_OK)
1582 {
1583 ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
1584 ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1585 if(use_midl_tlb) {
1586 ok(pTA->wTypeFlags == TYPEFLAG_FDUAL, "typeflags %x\n", pTA->wTypeFlags);
1587 }
1588 ok(pTA->cFuncs == 8, "cfuncs %d\n", pTA->cFuncs);
1589 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1590 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1591 }
1592 hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
1593 ok(hr == S_OK, "hr %08x\n", hr);
1594 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1595 ok(hr == S_OK, "hr %08x\n", hr);
1596 hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
1597 ok(hr == S_OK, "got %08x\n", hr);
1598 ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
1599 ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
1600 ITypeInfo_Release(pTI_p);
1601 if(use_midl_tlb) {
1602 hr = ITypeInfo_GetFuncDesc(pTI, 6, &pFD);
1603 ok(hr == S_OK, "hr %08x\n", hr);
1604 ok(pFD->memid == 0x1234, "memid %08x\n", pFD->memid);
1605 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1606 }
1607 ITypeInfo_Release(pTI);
1608
1609 /* ItestIF7 is dual with inherited ifaces which derive from Dispatch */
1610 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &IID_ItestIF7, &pTI);
1611 ok(hr == S_OK, "hr %08x\n", hr);
1612
1613 hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
1614 ok(hr == S_OK, "hr %08x\n", hr);
1615 ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
1616 ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1617 ok(pTA->wTypeFlags == (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL), "typeflags %x\n", pTA->wTypeFlags);
1618 ok(pTA->cFuncs == 10, "cfuncs %d\n", pTA->cFuncs);
1619 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1620 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1621
1622 hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
1623 ok(hr == S_OK, "hr %08x\n", hr);
1624 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1625 ok(hr == S_OK, "hr %08x\n", hr);
1626 hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
1627 ok(hr == S_OK, "got %08x\n", hr);
1628 ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
1629 ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
1630 ITypeInfo_Release(pTI_p);
1631
1632 hr = ITypeInfo_GetFuncDesc(pTI, 9, &pFD);
1633 ok(hr == S_OK, "hr %08x\n", hr);
1634 ok(pFD->memid == 0x1236, "memid %08x\n", pFD->memid);
1635 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1636 ITypeInfo_Release(pTI);
1637
1638 /* ItestIF10 is a syntax 2 dispinterface which doesn't derive from IUnknown */
1639 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF10, &pTI);
1640 ok(hr == S_OK, "hr %08x\n", hr);
1641
1642 hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
1643 ok(hr == S_OK, "hr %08x\n", hr);
1644 ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
1645 ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1646 ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags);
1647 if(use_midl_tlb) {
1648 ok(pTA->cFuncs == 3, "cfuncs %d\n", pTA->cFuncs);
1649 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1650 }
1651 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1652
1653 if(use_midl_tlb) {
1654 hr = ITypeInfo_GetRefTypeOfImplType(pTI, -1, &href);
1655 ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
1656 hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
1657 ok(hr == S_OK, "hr %08x\n", hr);
1658 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1659 ok(hr == S_OK, "hr %08x\n", hr);
1660 hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
1661 ok(hr == S_OK, "got %08x\n", hr);
1662 ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
1663 ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
1664 ITypeInfo_Release(pTI_p);
1665
1666 /* Should have three methods */
1667 hr = ITypeInfo_GetFuncDesc(pTI, 3, &pFD);
1668 ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
1669 hr = ITypeInfo_GetFuncDesc(pTI, 2, &pFD);
1670 ok(hr == S_OK, "hr %08x\n", hr);
1671 ok(pFD->memid == 0x60010000, "memid %08x\n", pFD->memid);
1672 ok(pFD->oVft == 2 * sizeof(void *), "oVft %d\n", pFD->oVft);
1673 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1674 }
1675 ITypeInfo_Release(pTI);
1676
1677 /* ItestIF11 is a syntax 2 dispinterface which derives from IDispatch */
1678 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF11, &pTI);
1679 ok(hr == S_OK, "hr %08x\n", hr);
1680
1681 hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
1682 ok(hr == S_OK, "hr %08x\n", hr);
1683 ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
1684 ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1685 ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags);
1686 if(use_midl_tlb) {
1687 ok(pTA->cFuncs == 10, "cfuncs %d\n", pTA->cFuncs);
1688 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1689 }
1690 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1691
1692 if(use_midl_tlb) {
1693 hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
1694 ok(hr == S_OK, "hr %08x\n", hr);
1695 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1696 ok(hr == S_OK, "hr %08x\n", hr);
1697 hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
1698 ok(hr == S_OK, "got %08x\n", hr);
1699 ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
1700 ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
1701 ITypeInfo_Release(pTI_p);
1702
1703 /* Should have ten methods */
1704 hr = ITypeInfo_GetFuncDesc(pTI, 10, &pFD);
1705 ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
1706 hr = ITypeInfo_GetFuncDesc(pTI, 9, &pFD);
1707 ok(hr == S_OK, "hr %08x\n", hr);
1708 ok(pFD->memid == 0x1236, "memid %08x\n", pFD->memid);
1709 ok(pFD->oVft == 9 * sizeof(void *), "oVft %d\n", pFD->oVft);
1710
1711 /* first argument to 10th function is an HREFTYPE from the impl type */
1712 ok(pFD->cParams == 1, "cParams %i\n", pFD->cParams);
1713 ok(pFD->lprgelemdescParam[0].tdesc.vt == VT_USERDEFINED,
1714 "vt 0x%x\n", pFD->lprgelemdescParam[0].tdesc.vt);
1715 href = U(pFD->lprgelemdescParam[0].tdesc).hreftype;
1716 ok((href & 0xff000000) == 0x04000000, "href 0x%08x\n", href);
1717 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1718 ok(hr == S_OK, "hr %08x\n", hr);
1719 if (SUCCEEDED(hr)) ITypeInfo_Release(pTI_p);
1720 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1721 }
1722 ITypeInfo_Release(pTI);
1723
1724
1725 /* ItestIF2 is an interface which derives from IUnknown */
1726 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &IID_ItestIF2, &pTI);
1727 ok(hr == S_OK, "hr %08x\n", hr);
1728
1729 hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
1730 ok(hr == S_OK, "hr %08x\n", hr);
1731 ok(pTA->typekind == TKIND_INTERFACE, "kind %04x\n", pTA->typekind);
1732 ok(pTA->cbSizeVft == 6 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1733 ok(pTA->wTypeFlags == 0, "typeflags %x\n", pTA->wTypeFlags);
1734 if(use_midl_tlb) {
1735 ok(pTA->cFuncs == 1, "cfuncs %d\n", pTA->cFuncs);
1736 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1737 }
1738 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1739
1740 if(use_midl_tlb) {
1741 /* Should have one method */
1742 hr = ITypeInfo_GetFuncDesc(pTI, 1, &pFD);
1743 ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
1744 hr = ITypeInfo_GetFuncDesc(pTI, 0, &pFD);
1745 ok(hr == S_OK, "hr %08x\n", hr);
1746 ok(pFD->memid == 0x60020000, "memid %08x\n", pFD->memid);
1747 ok(pFD->oVft == 5 * sizeof(void *), "oVft %d\n", pFD->oVft);
1748 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1749 }
1750 ITypeInfo_Release(pTI);
1751
1752 ITypeLib_Release(pTL);
1753
1754 return;
1755 }
1756
1757 static void test_CreateTypeLib(SYSKIND sys) {
1758 static OLECHAR typelibW[] = {'t','y','p','e','l','i','b',0};
1759 static OLECHAR helpfileW[] = {'C',':','\\','b','o','g','u','s','.','h','l','p',0};
1760 static OLECHAR interface1W[] = {'i','n','t','e','r','f','a','c','e','1',0};
1761 static OLECHAR interface2W[] = {'i','n','t','e','r','f','a','c','e','2',0};
1762 static OLECHAR interface3W[] = {'i','n','t','e','r','f','a','c','e','3',0};
1763 static OLECHAR dualW[] = {'d','u','a','l',0};
1764 static OLECHAR coclassW[] = {'c','o','c','l','a','s','s',0};
1765 static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0x3213,0};
1766 static OLECHAR func1W[] = {'f','u','n','c','1',0};
1767 static OLECHAR func2W[] = {'f','u','n','c','2',0};
1768 static OLECHAR prop1W[] = {'P','r','o','p','1',0};
1769 static OLECHAR param1W[] = {'p','a','r','a','m','1',0};
1770 static OLECHAR param2W[] = {'p','a','r','a','m','2',0};
1771 static OLECHAR asdfW[] = {'A','s','d','f',0};
1772 static OLECHAR aliasW[] = {'a','l','i','a','s',0};
1773 static OLECHAR invokeW[] = {'I','n','v','o','k','e',0};
1774 static OLECHAR *names1[] = {func1W, param1W, param2W};
1775 static OLECHAR *names2[] = {func2W, param1W, param2W};
1776 static OLECHAR *propname[] = {prop1W, param1W};
1777 static const GUID tlcustguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x69}};
1778 static const GUID custguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x70}};
1779 static const GUID bogusguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x71}};
1780 static const GUID interfaceguid = {0x3b9ff02f,0x9675,0x4861,{0xb7,0x81,0xce,0xae,0xa4,0x78,0x2a,0xcc}};
1781 static const GUID interface2guid = {0x3b9ff02f,0x9675,0x4861,{0xb7,0x81,0xce,0xae,0xa4,0x78,0x2a,0xcd}};
1782
1783 char filename[MAX_PATH];
1784 WCHAR filenameW[MAX_PATH];
1785 ICreateTypeLib2 *createtl;
1786 ICreateTypeInfo *createti;
1787 ICreateTypeInfo2 *createti2;
1788 ITypeLib *tl, *stdole;
1789 ITypeLib2 *tl2;
1790 ITypeInfo *interface1, *interface2, *dual, *unknown, *dispatch, *ti;
1791 ITypeInfo *tinfos[2];
1792 ITypeInfo2 *ti2;
1793 ITypeComp *tcomp, *tcomp2;
1794 MEMBERID memids[2];
1795 FUNCDESC funcdesc, *pfuncdesc;
1796 ELEMDESC elemdesc[5], *edesc;
1797 PARAMDESCEX paramdescex;
1798 TYPEDESC typedesc1, typedesc2;
1799 TYPEATTR *typeattr;
1800 TLIBATTR *libattr;
1801 HREFTYPE hreftype;
1802 BSTR name, docstring, helpfile, names[3];
1803 DWORD helpcontext, ptr_size, alignment;
1804 int impltypeflags;
1805 unsigned int cnames;
1806 USHORT found;
1807 VARIANT cust_data;
1808 HRESULT hres;
1809 TYPEKIND kind;
1810 DESCKIND desckind;
1811 BINDPTR bindptr;
1812 char nameA[16];
1813 WCHAR nameW[16];
1814
1815 switch(sys){
1816 case SYS_WIN32:
1817 trace("testing SYS_WIN32\n");
1818 ptr_size = 4;
1819 alignment = sizeof(void*);
1820 break;
1821 case SYS_WIN64:
1822 trace("testing SYS_WIN64\n");
1823 ptr_size = 8;
1824 alignment = 4;
1825 break;
1826 default:
1827 return;
1828 }
1829
1830 trace("CreateTypeLib tests\n");
1831
1832 hres = LoadTypeLib(wszStdOle2, &stdole);
1833 ok(hres == S_OK, "got %08x\n", hres);
1834
1835 hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IUnknown, &unknown);
1836 ok(hres == S_OK, "got %08x\n", hres);
1837
1838 hres = ITypeInfo_GetTypeAttr(unknown, &typeattr);
1839 ok(hres == S_OK, "got %08x\n", hres);
1840 ok(typeattr->cbSizeVft == 3 * sizeof(void*), "Got wrong cbSizeVft: %u\n", typeattr->cbSizeVft);
1841 ITypeInfo_ReleaseTypeAttr(unknown, typeattr);
1842
1843 hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &dispatch);
1844 ok(hres == S_OK, "got %08x\n", hres);
1845
1846 GetTempFileNameA(".", "tlb", 0, filename);
1847 MultiByteToWideChar(CP_ACP, 0, filename, -1, filenameW, MAX_PATH);
1848
1849 hres = CreateTypeLib2(sys, filenameW, &createtl);
1850 ok(hres == S_OK, "got %08x\n", hres);
1851
1852 hres = ICreateTypeLib2_QueryInterface(createtl, &IID_ITypeLib, (void**)&tl);
1853 ok(hres == S_OK, "got %08x\n", hres);
1854
1855 hres = ITypeLib_GetTypeInfo(tl, 0, NULL);
1856 ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
1857
1858 hres = ITypeLib_GetTypeInfoType(tl, 0, &kind);
1859 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got 0x%08x\n", hres);
1860
1861 hres = ITypeLib_GetTypeInfoType(tl, 0, NULL);
1862 ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
1863
1864 hres = ITypeLib_GetTypeInfoType(tl, 0, NULL);
1865 ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
1866
1867 hres = ITypeLib_GetLibAttr(tl, NULL);
1868 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1869
1870 hres = ITypeLib_GetLibAttr(tl, &libattr);
1871 ok(hres == S_OK, "got %08x\n", hres);
1872
1873 ok(libattr->syskind == sys, "syskind = %d\n", libattr->syskind);
1874 ok(libattr->wMajorVerNum == 0, "wMajorVer = %d\n", libattr->wMajorVerNum);
1875 ok(libattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", libattr->wMinorVerNum);
1876 ok(libattr->wLibFlags == 0, "wLibFlags = %d\n", libattr->wLibFlags);
1877
1878 ITypeLib_ReleaseTLibAttr(tl, libattr);
1879
1880 name = (BSTR)0xdeadbeef;
1881 hres = ITypeLib_GetDocumentation(tl, -1, &name, &docstring, &helpcontext, &helpfile);
1882 ok(hres == S_OK, "got %08x\n", hres);
1883 ok(name == NULL, "name != NULL\n");
1884 ok(docstring == NULL, "docstring != NULL\n");
1885 ok(helpcontext == 0, "helpcontext != 0\n");
1886 ok(helpfile == NULL, "helpfile != NULL\n");
1887
1888 hres = ITypeLib_GetDocumentation(tl, 0, &name, NULL, NULL, NULL);
1889 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
1890
1891 hres = ICreateTypeLib2_SetName(createtl, typelibW);
1892 ok(hres == S_OK, "got %08x\n", hres);
1893
1894 hres = ICreateTypeLib2_SetHelpFileName(createtl, helpfileW);
1895 ok(hres == S_OK, "got %08x\n", hres);
1896
1897 hres = ITypeLib_GetDocumentation(tl, -1, NULL, NULL, NULL, NULL);
1898 ok(hres == S_OK, "got %08x\n", hres);
1899
1900 hres = ITypeLib_GetDocumentation(tl, -1, &name, NULL, NULL, &helpfile);
1901 ok(hres == S_OK, "got %08x\n", hres);
1902 ok(!memcmp(name, typelibW, sizeof(typelibW)), "name = %s\n", wine_dbgstr_w(name));
1903 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "helpfile = %s\n", wine_dbgstr_w(helpfile));
1904
1905 SysFreeString(name);
1906 SysFreeString(helpfile);
1907
1908 V_VT(&cust_data) = VT_I4;
1909 V_I4(&cust_data) = 1;
1910 hres = ICreateTypeLib2_SetCustData(createtl, &tlcustguid, &cust_data);
1911 ok(hres == S_OK, "got %08x\n", hres);
1912
1913 hres = ITypeLib_QueryInterface(tl, &IID_ITypeLib2, (void**)&tl2);
1914 ok(hres == S_OK, "no ITypeLib2 interface (%x)\n", hres);
1915
1916 V_VT(&cust_data) = VT_EMPTY;
1917 V_I4(&cust_data) = 0;
1918 hres = ITypeLib2_GetCustData(tl2, &tlcustguid, &cust_data);
1919 ok(hres == S_OK, "got %08x\n", hres);
1920 ok(V_VT(&cust_data) == VT_I4, "V_VT(&cust_data) = %d\n", V_VT(&cust_data));
1921 ok(V_I4(&cust_data) == 1, "V_I4(&cust_data) = %d\n", V_I4(&cust_data));
1922
1923 ITypeLib2_Release(tl2);
1924
1925 /* invalid parameters */
1926 hres = ICreateTypeLib2_CreateTypeInfo(createtl, NULL, TKIND_INTERFACE, &createti);
1927 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1928
1929 hres = ICreateTypeLib2_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, NULL);
1930 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1931
1932 hres = ICreateTypeLib2_CreateTypeInfo(createtl, NULL, TKIND_INTERFACE, NULL);
1933 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1934
1935 hres = ICreateTypeLib2_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti);
1936 ok(hres == S_OK, "got %08x\n", hres);
1937
1938 hres = ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo, (void**)&interface1);
1939 ok(hres == S_OK, "got %08x\n", hres);
1940
1941 hres = ITypeLib_GetDocumentation(tl, 0, &name, NULL, NULL, NULL);
1942 ok(hres == S_OK, "got %08x\n", hres);
1943 ok(!memcmp(name, interface1W, sizeof(interface1W)), "name = %s\n", wine_dbgstr_w(name));
1944
1945 SysFreeString(name);
1946
1947 ITypeLib_Release(tl);
1948
1949 name = (BSTR)0xdeadbeef;
1950 helpfile = (BSTR)0xdeadbeef;
1951 hres = ITypeInfo_GetDocumentation(interface1, -1, &name, &docstring, &helpcontext, &helpfile);
1952 ok(hres == S_OK, "got %08x\n", hres);
1953 ok(!memcmp(name, interface1W, sizeof(interface1W)), "name = %s\n", wine_dbgstr_w(name));
1954 ok(docstring == NULL, "docstring != NULL\n");
1955 ok(helpcontext == 0, "helpcontext != 0\n");
1956 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "helpfile = %s\n", wine_dbgstr_w(helpfile));
1957
1958 SysFreeString(name);
1959 SysFreeString(helpfile);
1960
1961 hres = ITypeInfo_GetDocumentation(interface1, 0, &name, NULL, NULL, NULL);
1962 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
1963
1964 hres = ITypeInfo_GetRefTypeInfo(interface1, 0, NULL);
1965 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1966
1967
1968 hres = ICreateTypeInfo_LayOut(createti);
1969 ok(hres == S_OK, "got %08x\n", hres);
1970
1971 hres = ICreateTypeInfo_SetGuid(createti, &interfaceguid);
1972 ok(hres == S_OK, "got %08x\n", hres);
1973
1974 hres = ICreateTypeInfo_AddRefTypeInfo(createti, NULL, &hreftype);
1975 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1976
1977 hres = ICreateTypeInfo_AddRefTypeInfo(createti, unknown, NULL);
1978 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1979
1980 hres = ICreateTypeInfo_AddRefTypeInfo(createti, unknown, &hreftype);
1981 ok(hres == S_OK, "got %08x\n", hres);
1982 if(hres != S_OK) {
1983 skip("Skipping some tests\n");
1984 return;
1985 }
1986
1987 hres = ICreateTypeInfo_AddImplType(createti, 1, hreftype);
1988 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
1989
1990 hres = ICreateTypeInfo_AddImplType(createti, 0, hreftype);
1991 ok(hres == S_OK, "got %08x\n", hres);
1992
1993 hres = ITypeInfo_GetRefTypeOfImplType(interface1, 0, &hreftype);
1994 ok(hres == S_OK, "got %08x\n", hres);
1995 ok(hreftype == 3, "hreftype = %d\n", hreftype);
1996
1997 hres = ITypeInfo_GetRefTypeInfo(interface1, hreftype, &ti);
1998 ok(hres == S_OK, "got %08x\n", hres);
1999
2000 hres = ITypeInfo_GetTypeAttr(ti, &typeattr);
2001 ok(hres == S_OK, "got %08x\n", hres);
2002 ok(typeattr->cbSizeVft == 3 * ptr_size || broken(sys == SYS_WIN32 && typeattr->cbSizeVft == 24) /* xp64 */,
2003 "retrieved IUnknown gave wrong cbSizeVft: %u\n", typeattr->cbSizeVft);
2004 ITypeInfo_ReleaseTypeAttr(ti, typeattr);
2005
2006 ITypeInfo_Release(ti);
2007
2008 hres = ITypeInfo_GetRefTypeOfImplType(interface1, -1, &hreftype);
2009 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
2010
2011 ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo2, (void**)&ti2);
2012
2013 memset(&funcdesc, 0, sizeof(FUNCDESC));
2014 funcdesc.funckind = FUNC_PUREVIRTUAL;
2015 funcdesc.invkind = INVOKE_PROPERTYGET;
2016 funcdesc.callconv = CC_STDCALL;
2017 funcdesc.elemdescFunc.tdesc.vt = VT_BSTR;
2018 U(funcdesc.elemdescFunc).idldesc.wIDLFlags = IDLFLAG_NONE;
2019
2020 hres = ICreateTypeInfo_AddFuncDesc(createti, 0, NULL);
2021 ok(hres == E_INVALIDARG, "got %08x\n", hres);
2022
2023 hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
2024 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
2025
2026 hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
2027 ok(hres == S_OK, "got %08x\n", hres);
2028
2029 hres = ITypeInfo2_GetFuncDesc(ti2, 0, NULL);
2030 ok(hres == E_INVALIDARG, "got %08x\n", hres);
2031
2032 hres = ITypeInfo2_GetFuncDesc(ti2, 1, &pfuncdesc);
2033 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
2034
2035 hres = ITypeInfo2_GetFuncDesc(ti2, 0, &pfuncdesc);
2036 ok(hres == S_OK, "got %08x\n", hres);
2037
2038 ok(pfuncdesc->memid == 0, "got %x\n", pfuncdesc->memid);
2039 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2040 ok(pfuncdesc->lprgelemdescParam == NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2041 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2042 ok(pfuncdesc->invkind == INVOKE_PROPERTYGET, "got 0x%x\n", pfuncdesc->invkind);
2043 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2044 ok(pfuncdesc->cParams == 0, "got %d\n", pfuncdesc->cParams);
2045 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2046 ok(pfuncdesc->oVft == 3 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 24) /* xp64 */,
2047 "got %d\n", pfuncdesc->oVft);
2048 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2049 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_BSTR, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2050 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2051
2052 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2053
2054 hres = ICreateTypeInfo_SetFuncHelpContext(createti, 0, 0xabcdefab);
2055 ok(hres == S_OK, "got %08x\n", hres);
2056
2057 funcdesc.invkind = INVOKE_PROPERTYPUT;
2058 hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
2059 ok(hres == TYPE_E_INCONSISTENTPROPFUNCS, "got %08x\n", hres);
2060
2061 funcdesc.invkind = INVOKE_PROPERTYPUTREF;
2062 hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
2063 ok(hres == TYPE_E_INCONSISTENTPROPFUNCS, "got %08x\n", hres);
2064
2065 elemdesc[0].tdesc.vt = VT_BSTR;
2066 U(elemdesc[0]).idldesc.dwReserved = 0;
2067 U(elemdesc[0]).idldesc.wIDLFlags = IDLFLAG_FIN;
2068
2069 funcdesc.lprgelemdescParam = elemdesc;
2070 funcdesc.invkind = INVOKE_PROPERTYPUT;
2071 funcdesc.cParams = 1;
2072 funcdesc.elemdescFunc.tdesc.vt = VT_VOID;
2073
2074 hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
2075 ok(hres == S_OK, "got %08x\n", hres);
2076
2077 hres = ICreateTypeInfo_SetFuncHelpContext(createti, 1, 0xabcdefab);
2078 ok(hres == S_OK, "got %08x\n", hres);
2079
2080 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 0, propname, 0);
2081 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
2082
2083 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 0, NULL, 1);
2084 ok(hres == E_INVALIDARG, "got %08x\n", hres);
2085
2086 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 0, propname, 1);
2087 ok(hres == S_OK, "got %08x\n", hres);
2088
2089 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 1, propname, 1);
2090 ok(hres == S_OK, "got %08x\n", hres);
2091
2092 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 1, propname, 2);
2093 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
2094
2095 hres = ITypeInfo2_GetFuncDesc(ti2, 1, &pfuncdesc);
2096 ok(hres == S_OK, "got %08x\n", hres);
2097
2098 ok(pfuncdesc->memid == 0, "got %x\n", pfuncdesc->memid);
2099 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2100 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2101 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2102 ok(pfuncdesc->invkind == INVOKE_PROPERTYPUT, "got 0x%x\n", pfuncdesc->invkind);
2103 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2104 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
2105 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2106 ok(pfuncdesc->oVft == 4 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 28) /* xp64 */,
2107 "got %d\n", pfuncdesc->oVft);
2108 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2109 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2110 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2111
2112 edesc = pfuncdesc->lprgelemdescParam;
2113 ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
2114 ok(U(*edesc).idldesc.wIDLFlags == IDLFLAG_FIN, "got: %x\n", U(*edesc).idldesc.wIDLFlags);
2115
2116 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2117
2118
2119 funcdesc.invkind = INVOKE_PROPERTYPUTREF;
2120 hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
2121 ok(hres == S_OK, "got %08x\n", hres);
2122
2123 hres = ICreateTypeInfo_SetFuncHelpContext(createti, 0, 0xabcdefab);
2124 ok(hres == S_OK, "got %08x\n", hres);
2125
2126 hres = ICreateTypeInfo_SetFuncHelpContext(createti, 0, 0x201);
2127 ok(hres == S_OK, "got %08x\n", hres);
2128
2129 funcdesc.memid = 1;
2130 funcdesc.lprgelemdescParam = NULL;
2131 funcdesc.invkind = INVOKE_FUNC;
2132 funcdesc.cParams = 0;
2133 funcdesc.cScodes = 1;
2134 funcdesc.lprgscode = NULL;
2135 hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
2136 ok(hres == S_OK, "got %08x\n", hres);
2137
2138 hres = ITypeInfo2_GetFuncDesc(ti2, 1, &pfuncdesc);
2139 ok(hres == S_OK, "got %08x\n", hres);
2140
2141 ok(pfuncdesc->memid == 1, "got %d\n", pfuncdesc->memid);
2142 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2143 ok(pfuncdesc->lprgelemdescParam == NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2144 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2145 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2146 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2147 ok(pfuncdesc->cParams == 0, "got %d\n", pfuncdesc->cParams);
2148 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2149 ok(pfuncdesc->oVft == 4 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 28), /* xp64 */
2150 "got %d\n", pfuncdesc->oVft);
2151 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2152 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2153 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2154
2155 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2156
2157 funcdesc.memid = MEMBERID_NIL;
2158 hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
2159 ok(hres == S_OK, "got %08x\n", hres);
2160
2161 elemdesc[0].tdesc.vt = VT_PTR;
2162 U(elemdesc[0].tdesc).lptdesc = &typedesc1;
2163 typedesc1.vt = VT_BSTR;
2164 funcdesc.cParams = 1;
2165 funcdesc.lprgelemdescParam = elemdesc;
2166 hres = ICreateTypeInfo_AddFuncDesc(createti, 4, &funcdesc);
2167 ok(hres == S_OK, "got %08x\n", hres);
2168
2169 hres = ITypeInfo2_GetFuncDesc(ti2, 4, &pfuncdesc);
2170 ok(hres == S_OK, "got %08x\n", hres);
2171
2172 ok(pfuncdesc->memid == 0x60010004, "got %x\n", pfuncdesc->memid);
2173 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2174 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2175 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2176 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2177 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2178 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
2179 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2180 ok(pfuncdesc->oVft == 7 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 40) /* xp64 */,
2181 "got %d\n", pfuncdesc->oVft);
2182 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2183 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2184 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2185
2186 edesc = pfuncdesc->lprgelemdescParam;
2187 ok(edesc->tdesc.vt == VT_PTR, "got: %d\n", edesc->tdesc.vt);
2188 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FIN, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2189 ok(U(*edesc).paramdesc.pparamdescex == NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2190 ok(U(edesc->tdesc).lptdesc != NULL, "got: %p\n", U(edesc->tdesc).lptdesc);
2191 ok(U(edesc->tdesc).lptdesc->vt == VT_BSTR, "got: %d\n", U(edesc->tdesc).lptdesc->vt);
2192
2193 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2194
2195 U(elemdesc[0].tdesc).lptdesc = &typedesc2;
2196 typedesc2.vt = VT_PTR;
2197 U(typedesc2).lptdesc = &typedesc1;
2198 hres = ICreateTypeInfo_AddFuncDesc(createti, 4, &funcdesc);
2199 ok(hres == S_OK, "got %08x\n", hres);
2200
2201 hres = ITypeInfo2_GetFuncDesc(ti2, 4, &pfuncdesc);
2202 ok(hres == S_OK, "got %08x\n", hres);
2203
2204 ok(pfuncdesc->memid == 0x60010007, "got %x\n", pfuncdesc->memid);
2205 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2206 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2207 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2208 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2209 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2210 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
2211 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2212 ok(pfuncdesc->oVft == 7 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 40) /* xp64 */,
2213 "got %d\n", pfuncdesc->oVft);
2214 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2215 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2216 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2217
2218 edesc = pfuncdesc->lprgelemdescParam;
2219 ok(edesc->tdesc.vt == VT_PTR, "got: %d\n", edesc->tdesc.vt);
2220 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FIN, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2221 ok(U(*edesc).paramdesc.pparamdescex == NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2222 ok(U(edesc->tdesc).lptdesc != NULL, "got: %p\n", U(edesc->tdesc).lptdesc);
2223 ok(U(edesc->tdesc).lptdesc->vt == VT_PTR, "got: %d\n", U(edesc->tdesc).lptdesc->vt);
2224 ok(U(*U(edesc->tdesc).lptdesc).lptdesc != NULL, "got: %p\n", U(*U(edesc->tdesc).lptdesc).lptdesc);
2225 ok(U(*U(edesc->tdesc).lptdesc).lptdesc->vt == VT_BSTR, "got: %d\n", U(*U(edesc->tdesc).lptdesc).lptdesc->vt);
2226
2227 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2228
2229 elemdesc[0].tdesc.vt = VT_INT;
2230 U(elemdesc[0]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT;
2231 U(elemdesc[0]).paramdesc.pparamdescex = &paramdescex;
2232 V_VT(&paramdescex.varDefaultValue) = VT_INT;
2233 V_INT(&paramdescex.varDefaultValue) = 0x123;
2234 hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
2235 ok(hres == S_OK, "got %08x\n", hres);
2236
2237 hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc);
2238 ok(hres == S_OK, "got %08x\n", hres);
2239
2240 ok(pfuncdesc->memid == 0x60010003, "got %x\n", pfuncdesc->memid);
2241 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2242 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2243 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2244 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2245 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2246 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
2247 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2248 ok(pfuncdesc->oVft == 6 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 36) /* xp64 */,
2249 "got %d\n", pfuncdesc->oVft);
2250 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2251 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2252 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2253
2254 edesc = pfuncdesc->lprgelemdescParam;
2255 ok(edesc->tdesc.vt == VT_INT, "got: %d\n", edesc->tdesc.vt);
2256 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2257 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2258 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
2259 U(*edesc).paramdesc.pparamdescex->cBytes);
2260 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_I4, "got: %d\n",
2261 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2262 ok(V_I4(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0x123, "got: 0x%x\n",
2263 V_I4(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2264
2265 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2266
2267 U(elemdesc[0]).idldesc.dwReserved = 0;
2268 U(elemdesc[0]).idldesc.wIDLFlags = IDLFLAG_FIN;
2269 elemdesc[1].tdesc.vt = VT_UI2;
2270 U(elemdesc[1]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT;
2271 U(elemdesc[1]).paramdesc.pparamdescex = &paramdescex;
2272 V_VT(&paramdescex.varDefaultValue) = VT_UI2;
2273 V_UI2(&paramdescex.varDefaultValue) = 0xffff;
2274 funcdesc.cParams = 2;
2275 hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
2276 ok(hres == S_OK, "got %08x\n", hres);
2277
2278 hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc);
2279 ok(hres == S_OK, "got %08x\n", hres);
2280
2281 ok(pfuncdesc->memid == 0x60010009, "got %x\n", pfuncdesc->memid);
2282 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2283 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2284 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2285 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2286 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2287 ok(pfuncdesc->cParams == 2, "got %d\n", pfuncdesc->cParams);
2288 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2289 ok(pfuncdesc->oVft == 6 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 36) /* xp64 */,
2290 "got %d\n", pfuncdesc->oVft);
2291 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2292 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2293 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2294
2295 edesc = pfuncdesc->lprgelemdescParam;
2296 ok(edesc->tdesc.vt == VT_INT, "got: %d\n", edesc->tdesc.vt);
2297 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FIN, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2298 ok(U(*edesc).paramdesc.pparamdescex == NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2299
2300 edesc = pfuncdesc->lprgelemdescParam + 1;
2301 ok(edesc->tdesc.vt == VT_UI2, "got: %d\n", edesc->tdesc.vt);
2302 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2303 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2304 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
2305 U(*edesc).paramdesc.pparamdescex->cBytes);
2306 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_UI2, "got: %d\n",
2307 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2308 ok(V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0xFFFF, "got: 0x%x\n",
2309 V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2310
2311 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2312
2313 U(elemdesc[0]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT;
2314 U(elemdesc[0]).paramdesc.pparamdescex = &paramdescex;
2315 elemdesc[1].tdesc.vt = VT_INT;
2316 V_VT(&paramdescex.varDefaultValue) = VT_INT;
2317 V_INT(&paramdescex.varDefaultValue) = 0xffffffff;
2318 hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
2319 ok(hres == S_OK, "got %08x\n", hres);
2320
2321 elemdesc[0].tdesc.vt = VT_BSTR;
2322 elemdesc[1].tdesc.vt = VT_BSTR;
2323 V_VT(&paramdescex.varDefaultValue) = VT_BSTR;
2324 V_BSTR(&paramdescex.varDefaultValue) = SysAllocString(defaultW);
2325 hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
2326 ok(hres == S_OK, "got %08x\n", hres);
2327 SysFreeString(V_BSTR(&paramdescex.varDefaultValue));
2328
2329 WideCharToMultiByte(CP_ACP, 0, defaultW, -1, nameA, sizeof(nameA), NULL, NULL);
2330 MultiByteToWideChar(CP_ACP, 0, nameA, -1, nameW, sizeof(nameW)/sizeof(nameW[0]));
2331
2332 hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc);
2333 ok(hres == S_OK, "got %08x\n", hres);
2334
2335 ok(pfuncdesc->memid == 0x6001000b, "got %x\n", pfuncdesc->memid);
2336 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2337 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2338 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2339 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2340 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2341 ok(pfuncdesc->cParams == 2, "got %d\n", pfuncdesc->cParams);
2342 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2343 ok(pfuncdesc->oVft == 6 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 36) /* xp64 */,
2344 "got %d\n", pfuncdesc->oVft);
2345 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2346 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2347 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2348
2349 edesc = pfuncdesc->lprgelemdescParam;
2350 ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
2351 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2352 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2353 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
2354 U(*edesc).paramdesc.pparamdescex->cBytes);
2355 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n",
2356 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2357 ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), nameW),
2358 "got: %s\n",
2359 wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)));
2360
2361 edesc = pfuncdesc->lprgelemdescParam + 1;
2362 ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
2363 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc