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