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