45587f88dab2c566628527fa7a984ed50dc90680
[reactos.git] / 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
43 #include <test_reg.h>
44 #include <test_tlb.h>
45
46 #define expect_eq(expr, value, type, format) { type _ret = (expr); ok((value) == _ret, #expr " expected " format " got " format "\n", value, _ret); }
47 #define expect_int(expr, value) expect_eq(expr, (int)(value), int, "%d")
48 #define expect_hex(expr, value) expect_eq(expr, (int)(value), int, "0x%x")
49 #define expect_null(expr) expect_eq(expr, NULL, const void *, "%p")
50 #define expect_guid(expected, guid) { ok(IsEqualGUID(expected, guid), "got wrong guid %s\n", wine_dbgstr_guid(guid)); }
51
52 #define expect_wstr_acpval(expr, value) \
53 { \
54 CHAR buf[260]; \
55 expect_eq(!WideCharToMultiByte(CP_ACP, 0, (expr), -1, buf, 260, NULL, NULL), 0, int, "%d"); \
56 ok(strcmp(value, buf) == 0, #expr " expected \"%s\" got \"%s\"\n", value, buf); \
57 }
58
59 #define ole_expect(expr, expect) { \
60 HRESULT r = expr; \
61 ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \
62 }
63
64 #define ole_check(expr) ole_expect(expr, S_OK);
65
66 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
67
68 #ifdef __i386__
69 #define ARCH "x86"
70 #elif defined __x86_64__
71 #define ARCH "amd64"
72 #elif defined __arm__
73 #define ARCH "arm"
74 #elif defined __aarch64__
75 #define ARCH "arm64"
76 #else
77 #define ARCH "none"
78 #endif
79
80 static HRESULT (WINAPI *pRegisterTypeLibForUser)(ITypeLib*,OLECHAR*,OLECHAR*);
81 static HRESULT (WINAPI *pUnRegisterTypeLibForUser)(REFGUID,WORD,WORD,LCID,SYSKIND);
82
83 static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
84 static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
85 static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
86 static VOID (WINAPI *pReleaseActCtx)(HANDLE);
87 static BOOL (WINAPI *pIsWow64Process)(HANDLE,LPBOOL);
88 static LONG (WINAPI *pRegDeleteKeyExW)(HKEY,LPCWSTR,REGSAM,DWORD);
89
90 static const WCHAR wszStdOle2[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
91 static WCHAR wszGUID[] = {'G','U','I','D',0};
92 static WCHAR wszguid[] = {'g','u','i','d',0};
93
94 static const BOOL is_win64 = sizeof(void *) > sizeof(int);
95
96 static HRESULT WINAPI invoketest_QueryInterface(IInvokeTest *iface, REFIID riid, void **ret)
97 {
98 if (IsEqualIID(riid, &IID_IUnknown) ||
99 IsEqualIID(riid, &IID_IDispatch) ||
100 IsEqualIID(riid, &IID_IInvokeTest))
101 {
102 *ret = iface;
103 return S_OK;
104 }
105
106 return E_NOINTERFACE;
107 }
108
109 static ULONG WINAPI invoketest_AddRef(IInvokeTest *iface)
110 {
111 return 2;
112 }
113
114 static ULONG WINAPI invoketest_Release(IInvokeTest *iface)
115 {
116 return 1;
117 }
118
119 static HRESULT WINAPI invoketest_GetTypeInfoCount(IInvokeTest *iface, UINT *cnt)
120 {
121 ok(0, "unexpected call\n");
122 *cnt = 0;
123 return E_NOTIMPL;
124 }
125
126 static HRESULT WINAPI invoketest_GetTypeInfo(IInvokeTest *iface, UINT index, LCID lcid, ITypeInfo **ti)
127 {
128 ok(0, "unexpected call\n");
129 return E_NOTIMPL;
130 }
131
132 static HRESULT WINAPI invoketest_GetIDsOfNames(IInvokeTest *iface, REFIID riid, LPOLESTR *names,
133 UINT cnt, LCID lcid, DISPID *dispid)
134 {
135 ok(0, "unexpected call\n");
136 return E_NOTIMPL;
137 }
138
139 static HRESULT WINAPI invoketest_Invoke(IInvokeTest *iface, DISPID dispid, REFIID riid,
140 LCID lcid, WORD flags, DISPPARAMS *dispparams, VARIANT *res, EXCEPINFO *ei, UINT *argerr)
141 {
142 ok(0, "unexpected call\n");
143 return E_NOTIMPL;
144 }
145
146 static LONG WINAPI invoketest_get_test(IInvokeTest *iface, LONG i)
147 {
148 return i+1;
149 }
150
151 static LONG WINAPI invoketest_putref_testprop(IInvokeTest *iface, LONG *i)
152 {
153 return *i+2;
154 }
155
156 static LONG WINAPI invoketest_putref_testprop2(IInvokeTest *iface, IUnknown *i)
157 {
158 return 6;
159 }
160
161 static const IInvokeTestVtbl invoketestvtbl = {
162 invoketest_QueryInterface,
163 invoketest_AddRef,
164 invoketest_Release,
165 invoketest_GetTypeInfoCount,
166 invoketest_GetTypeInfo,
167 invoketest_GetIDsOfNames,
168 invoketest_Invoke,
169 invoketest_get_test,
170 invoketest_putref_testprop,
171 invoketest_putref_testprop2
172 };
173
174 static IInvokeTest invoketest = { &invoketestvtbl };
175
176 static void init_function_pointers(void)
177 {
178 HMODULE hmod = GetModuleHandleA("oleaut32.dll");
179 HMODULE hk32 = GetModuleHandleA("kernel32.dll");
180 HMODULE hadv = GetModuleHandleA("advapi32.dll");
181
182 pRegisterTypeLibForUser = (void *)GetProcAddress(hmod, "RegisterTypeLibForUser");
183 pUnRegisterTypeLibForUser = (void *)GetProcAddress(hmod, "UnRegisterTypeLibForUser");
184 pActivateActCtx = (void *)GetProcAddress(hk32, "ActivateActCtx");
185 pCreateActCtxW = (void *)GetProcAddress(hk32, "CreateActCtxW");
186 pDeactivateActCtx = (void *)GetProcAddress(hk32, "DeactivateActCtx");
187 pReleaseActCtx = (void *)GetProcAddress(hk32, "ReleaseActCtx");
188 pIsWow64Process = (void *)GetProcAddress(hk32, "IsWow64Process");
189 pRegDeleteKeyExW = (void*)GetProcAddress(hadv, "RegDeleteKeyExW");
190 }
191
192 static void ref_count_test(LPCWSTR type_lib)
193 {
194 ITypeLib *iface;
195 ITypeInfo *iti1, *iti2;
196 HRESULT hRes;
197 int ref_count;
198
199 trace("Loading type library\n");
200 hRes = LoadTypeLib(type_lib, &iface);
201 ok(hRes == S_OK, "Could not load type library\n");
202 if(hRes != S_OK)
203 return;
204
205 hRes = ITypeLib_GetTypeInfo(iface, 1, &iti1);
206 ok(hRes == S_OK, "ITypeLib_GetTypeInfo failed on index = 1\n");
207 ok(ref_count=ITypeLib_Release(iface) > 0, "ITypeLib destroyed while ITypeInfo has back pointer\n");
208 if(!ref_count)
209 return;
210
211 hRes = ITypeLib_GetTypeInfo(iface, 1, &iti2);
212 ok(hRes == S_OK, "ITypeLib_GetTypeInfo failed on index = 1\n");
213 ok(iti1 == iti2, "ITypeLib_GetTypeInfo returned different pointers for same indexes\n");
214
215 ITypeLib_AddRef(iface);
216 ITypeInfo_Release(iti2);
217 ITypeInfo_Release(iti1);
218 ok(ITypeLib_Release(iface) == 0, "ITypeLib should be destroyed here.\n");
219 }
220
221 static void test_TypeComp(void)
222 {
223 ITypeLib *pTypeLib;
224 ITypeComp *pTypeComp;
225 HRESULT hr;
226 ULONG ulHash;
227 DESCKIND desckind;
228 BINDPTR bindptr;
229 ITypeInfo *pTypeInfo;
230 ITypeInfo *pFontTypeInfo;
231 ITypeComp *pTypeComp_tmp;
232 static WCHAR wszStdFunctions[] = {'S','t','d','F','u','n','c','t','i','o','n','s',0};
233 static WCHAR wszSavePicture[] = {'S','a','v','e','P','i','c','t','u','r','e',0};
234 static WCHAR wszOLE_TRISTATE[] = {'O','L','E','_','T','R','I','S','T','A','T','E',0};
235 static WCHAR wszUnchecked[] = {'U','n','c','h','e','c','k','e','d',0};
236 static WCHAR wszIUnknown[] = {'I','U','n','k','n','o','w','n',0};
237 static WCHAR wszFont[] = {'F','o','n','t',0};
238 static WCHAR wszStdPicture[] = {'S','t','d','P','i','c','t','u','r','e',0};
239 static WCHAR wszOLE_COLOR[] = {'O','L','E','_','C','O','L','O','R',0};
240 static WCHAR wszClone[] = {'C','l','o','n','e',0};
241 static WCHAR wszclone[] = {'c','l','o','n','e',0};
242 static WCHAR wszJunk[] = {'J','u','n','k',0};
243 static WCHAR wszAddRef[] = {'A','d','d','R','e','f',0};
244
245 hr = LoadTypeLib(wszStdOle2, &pTypeLib);
246 ok_ole_success(hr, LoadTypeLib);
247
248 hr = ITypeLib_GetTypeComp(pTypeLib, &pTypeComp);
249 ok_ole_success(hr, ITypeLib_GetTypeComp);
250
251 /* test getting a TKIND_MODULE */
252 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdFunctions);
253 hr = ITypeComp_Bind(pTypeComp, wszStdFunctions, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
254 ok_ole_success(hr, ITypeComp_Bind);
255
256 ok(desckind == DESCKIND_TYPECOMP,
257 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
258 desckind);
259 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
260
261 ITypeComp_Release(bindptr.lptcomp);
262
263 /* test getting a TKIND_MODULE with INVOKE_PROPERTYGET */
264 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdFunctions);
265 hr = ITypeComp_Bind(pTypeComp, wszStdFunctions, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
266 ok_ole_success(hr, ITypeComp_Bind);
267
268 ok(desckind == DESCKIND_TYPECOMP,
269 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
270 desckind);
271 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
272 ITypeComp_Release(bindptr.lptcomp);
273
274 /* test getting a function within a TKIND_MODULE */
275 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszSavePicture);
276 hr = ITypeComp_Bind(pTypeComp, wszSavePicture, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
277 ok_ole_success(hr, ITypeComp_Bind);
278
279 ok(desckind == DESCKIND_FUNCDESC,
280 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
281 desckind);
282 ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
283 ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
284 ITypeInfo_Release(pTypeInfo);
285
286 /* test getting a function within a TKIND_MODULE with INVOKE_PROPERTYGET */
287 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszSavePicture);
288 hr = ITypeComp_Bind(pTypeComp, wszSavePicture, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
289 ok(hr == TYPE_E_TYPEMISMATCH,
290 "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n",
291 hr);
292
293 ok(desckind == DESCKIND_NONE,
294 "desckind should have been DESCKIND_NONE instead of %d\n",
295 desckind);
296 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
297 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
298
299 /* test getting a TKIND_ENUM */
300 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszOLE_TRISTATE);
301 hr = ITypeComp_Bind(pTypeComp, wszOLE_TRISTATE, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
302 ok_ole_success(hr, ITypeComp_Bind);
303
304 ok(desckind == DESCKIND_TYPECOMP,
305 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
306 desckind);
307 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
308
309 ITypeComp_Release(bindptr.lptcomp);
310
311 /* test getting a value within a TKIND_ENUM */
312 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszUnchecked);
313 hr = ITypeComp_Bind(pTypeComp, wszUnchecked, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
314 ok_ole_success(hr, ITypeComp_Bind);
315
316 ok(desckind == DESCKIND_VARDESC,
317 "desckind should have been DESCKIND_VARDESC instead of %d\n",
318 desckind);
319 ITypeInfo_ReleaseVarDesc(pTypeInfo, bindptr.lpvardesc);
320 ITypeInfo_Release(pTypeInfo);
321
322 /* test getting a TKIND_INTERFACE */
323 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszIUnknown);
324 hr = ITypeComp_Bind(pTypeComp, wszIUnknown, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
325 ok_ole_success(hr, ITypeComp_Bind);
326
327 ok(desckind == DESCKIND_NONE,
328 "desckind should have been DESCKIND_NONE instead of %d\n",
329 desckind);
330 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
331 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
332
333 /* test getting a TKIND_DISPATCH */
334 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszFont);
335 hr = ITypeComp_Bind(pTypeComp, wszFont, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
336 ok_ole_success(hr, ITypeComp_Bind);
337
338 ok(desckind == DESCKIND_NONE,
339 "desckind should have been DESCKIND_NONE instead of %d\n",
340 desckind);
341 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
342 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
343
344 /* test getting a TKIND_RECORD/TKIND_ALIAS */
345 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
346 hr = ITypeComp_Bind(pTypeComp, wszGUID, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
347 ok_ole_success(hr, ITypeComp_Bind);
348
349 ok(desckind == DESCKIND_NONE,
350 "desckind should have been DESCKIND_NONE instead of %d\n",
351 desckind);
352 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
353 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
354
355 /* test getting a TKIND_ALIAS */
356 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszOLE_COLOR);
357 hr = ITypeComp_Bind(pTypeComp, wszOLE_COLOR, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
358 ok_ole_success(hr, ITypeComp_Bind);
359
360 ok(desckind == DESCKIND_NONE,
361 "desckind should have been DESCKIND_NONE instead of %d\n",
362 desckind);
363 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
364 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
365
366 /* test getting a TKIND_COCLASS */
367 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszStdPicture);
368 hr = ITypeComp_Bind(pTypeComp, wszStdPicture, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
369 ok_ole_success(hr, ITypeComp_Bind);
370
371 ok(desckind == DESCKIND_NONE,
372 "desckind should have been DESCKIND_NONE instead of %d\n",
373 desckind);
374 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
375 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
376
377 /* test basic BindType argument handling */
378 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
379 hr = ITypeComp_BindType(pTypeComp, wszGUID, ulHash, NULL, NULL);
380 ok(hr == E_INVALIDARG, "Got %08x\n", hr);
381
382 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
383 pTypeInfo = (void*)0xdeadbeef;
384 hr = ITypeComp_BindType(pTypeComp, wszGUID, ulHash, &pTypeInfo, NULL);
385 ok(hr == E_INVALIDARG, "Got %08x\n", hr);
386 ok(pTypeInfo == (void*)0xdeadbeef, "Got %p\n", pTypeInfo);
387
388 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
389 pTypeComp_tmp = (void*)0xdeadbeef;
390 hr = ITypeComp_BindType(pTypeComp, wszGUID, ulHash, NULL, &pTypeComp_tmp);
391 ok(hr == E_INVALIDARG, "Got %08x\n", hr);
392 ok(pTypeComp_tmp == (void*)0xdeadbeef, "Got %p\n", pTypeComp_tmp);
393
394 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
395 pTypeComp_tmp = (void*)0xdeadbeef;
396 pTypeInfo = (void*)0xdeadbeef;
397 hr = ITypeComp_BindType(pTypeComp, NULL, ulHash, &pTypeInfo, &pTypeComp_tmp);
398 ok(hr == E_INVALIDARG, "Got %08x\n", hr);
399 ok(pTypeInfo == (void*)0xdeadbeef, "Got %p\n", pTypeInfo);
400 ok(pTypeComp_tmp == (void*)0xdeadbeef, "Got %p\n", pTypeComp_tmp);
401
402 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
403 pTypeComp_tmp = (void*)0xdeadbeef;
404 pTypeInfo = (void*)0xdeadbeef;
405 hr = ITypeComp_BindType(pTypeComp, wszGUID, ulHash, &pTypeInfo, &pTypeComp_tmp);
406 ok_ole_success(hr, ITypeComp_BindType);
407 ok(pTypeInfo != NULL, "Got NULL pTypeInfo\n");
408 todo_wine ok(pTypeComp_tmp == NULL, "Got pTypeComp_tmp %p\n", pTypeComp_tmp);
409 ITypeInfo_Release(pTypeInfo);
410 if(pTypeComp_tmp) ITypeComp_Release(pTypeComp_tmp); /* fixme */
411
412 /* test BindType case-insensitivity */
413 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszguid);
414 pTypeComp_tmp = (void*)0xdeadbeef;
415 pTypeInfo = (void*)0xdeadbeef;
416 hr = ITypeComp_BindType(pTypeComp, wszguid, ulHash, &pTypeInfo, &pTypeComp_tmp);
417 ok_ole_success(hr, ITypeComp_BindType);
418 ok(pTypeInfo != NULL, "Got NULL pTypeInfo\n");
419 todo_wine ok(pTypeComp_tmp == NULL, "Got pTypeComp_tmp %p\n", pTypeComp_tmp);
420 ITypeInfo_Release(pTypeInfo);
421 if(pTypeComp_tmp) ITypeComp_Release(pTypeComp_tmp); /* fixme */
422
423 ITypeComp_Release(pTypeComp);
424
425 /* tests for ITypeComp on an interface */
426 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IFont, &pFontTypeInfo);
427 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
428
429 hr = ITypeInfo_GetTypeComp(pFontTypeInfo, &pTypeComp);
430 ok_ole_success(hr, ITypeLib_GetTypeComp);
431
432 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszClone);
433 hr = ITypeComp_Bind(pTypeComp, wszClone, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
434 ok_ole_success(hr, ITypeComp_Bind);
435
436 ok(desckind == DESCKIND_FUNCDESC,
437 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
438 desckind);
439 ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
440 ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
441 ITypeInfo_Release(pTypeInfo);
442
443 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszClone);
444 hr = ITypeComp_Bind(pTypeComp, wszClone, ulHash, INVOKE_PROPERTYGET, &pTypeInfo, &desckind, &bindptr);
445 ok(hr == TYPE_E_TYPEMISMATCH, "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n", hr);
446
447 ok(desckind == DESCKIND_NONE,
448 "desckind should have been DESCKIND_NONE instead of %d\n",
449 desckind);
450 ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
451 ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
452
453 /* tests that the compare is case-insensitive */
454 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszclone);
455 hr = ITypeComp_Bind(pTypeComp, wszclone, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
456 ok_ole_success(hr, ITypeComp_Bind);
457
458 ok(desckind == DESCKIND_FUNCDESC,
459 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
460 desckind);
461 ok(bindptr.lpfuncdesc != NULL, "bindptr.lpfuncdesc should not have been set to NULL\n");
462 ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
463 ITypeInfo_Release(pTypeInfo);
464
465 /* tests nonexistent members */
466 desckind = 0xdeadbeef;
467 bindptr.lptcomp = (ITypeComp*)0xdeadbeef;
468 pTypeInfo = (ITypeInfo*)0xdeadbeef;
469 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszJunk);
470 hr = ITypeComp_Bind(pTypeComp, wszJunk, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
471 ok_ole_success(hr, ITypeComp_Bind);
472 ok(desckind == DESCKIND_NONE, "desckind should have been DESCKIND_NONE, was: %d\n", desckind);
473 ok(pTypeInfo == NULL, "pTypeInfo should have been NULL, was: %p\n", pTypeInfo);
474 ok(bindptr.lptcomp == NULL, "bindptr should have been NULL, was: %p\n", bindptr.lptcomp);
475
476 /* tests inherited members */
477 desckind = 0xdeadbeef;
478 bindptr.lpfuncdesc = NULL;
479 pTypeInfo = NULL;
480 ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszAddRef);
481 hr = ITypeComp_Bind(pTypeComp, wszAddRef, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
482 ok_ole_success(hr, ITypeComp_Bind);
483 ok(desckind == DESCKIND_FUNCDESC, "desckind should have been DESCKIND_FUNCDESC, was: %d\n", desckind);
484 ok(pTypeInfo != NULL, "pTypeInfo should not have been NULL, was: %p\n", pTypeInfo);
485 ok(bindptr.lpfuncdesc != NULL, "bindptr should not have been NULL, was: %p\n", bindptr.lpfuncdesc);
486 ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
487 ITypeInfo_Release(pTypeInfo);
488
489 ITypeComp_Release(pTypeComp);
490 ITypeInfo_Release(pFontTypeInfo);
491 ITypeLib_Release(pTypeLib);
492 }
493
494 static void test_CreateDispTypeInfo(void)
495 {
496 ITypeInfo *pTypeInfo, *pTI2;
497 HRESULT hr;
498 INTERFACEDATA ifdata;
499 METHODDATA methdata[4];
500 PARAMDATA parms1[2];
501 PARAMDATA parms3[1];
502 TYPEATTR *pTypeAttr;
503 HREFTYPE href;
504 FUNCDESC *pFuncDesc;
505 MEMBERID memid;
506
507 static WCHAR func1[] = {'f','u','n','c','1',0};
508 static const WCHAR func2[] = {'f','u','n','c','2',0};
509 static const WCHAR func3[] = {'f','u','n','c','3',0};
510 static const WCHAR parm1[] = {'p','a','r','m','1',0};
511 static const WCHAR parm2[] = {'p','a','r','m','2',0};
512 OLECHAR *name = func1;
513
514 ifdata.pmethdata = methdata;
515 ifdata.cMembers = sizeof(methdata) / sizeof(methdata[0]);
516
517 methdata[0].szName = SysAllocString(func1);
518 methdata[0].ppdata = parms1;
519 methdata[0].dispid = 0x123;
520 methdata[0].iMeth = 0;
521 methdata[0].cc = CC_STDCALL;
522 methdata[0].cArgs = 2;
523 methdata[0].wFlags = DISPATCH_METHOD;
524 methdata[0].vtReturn = VT_HRESULT;
525 parms1[0].szName = SysAllocString(parm1);
526 parms1[0].vt = VT_I4;
527 parms1[1].szName = SysAllocString(parm2);
528 parms1[1].vt = VT_BSTR;
529
530 methdata[1].szName = SysAllocString(func2);
531 methdata[1].ppdata = NULL;
532 methdata[1].dispid = 0x124;
533 methdata[1].iMeth = 1;
534 methdata[1].cc = CC_STDCALL;
535 methdata[1].cArgs = 0;
536 methdata[1].wFlags = DISPATCH_PROPERTYGET;
537 methdata[1].vtReturn = VT_I4;
538
539 methdata[2].szName = SysAllocString(func3);
540 methdata[2].ppdata = parms3;
541 methdata[2].dispid = 0x125;
542 methdata[2].iMeth = 3;
543 methdata[2].cc = CC_STDCALL;
544 methdata[2].cArgs = 1;
545 methdata[2].wFlags = DISPATCH_PROPERTYPUT;
546 methdata[2].vtReturn = VT_HRESULT;
547 parms3[0].szName = SysAllocString(parm1);
548 parms3[0].vt = VT_I4;
549
550 methdata[3].szName = SysAllocString(func3);
551 methdata[3].ppdata = NULL;
552 methdata[3].dispid = 0x125;
553 methdata[3].iMeth = 4;
554 methdata[3].cc = CC_STDCALL;
555 methdata[3].cArgs = 0;
556 methdata[3].wFlags = DISPATCH_PROPERTYGET;
557 methdata[3].vtReturn = VT_I4;
558
559 hr = CreateDispTypeInfo(&ifdata, LOCALE_NEUTRAL, &pTypeInfo);
560 ok(hr == S_OK, "hr %08x\n", hr);
561
562 hr = ITypeInfo_GetTypeAttr(pTypeInfo, &pTypeAttr);
563 ok(hr == S_OK, "hr %08x\n", hr);
564
565 ok(pTypeAttr->typekind == TKIND_COCLASS, "typekind %0x\n", pTypeAttr->typekind);
566 ok(pTypeAttr->cImplTypes == 1, "cImplTypes %d\n", pTypeAttr->cImplTypes);
567 ok(pTypeAttr->cFuncs == 0, "cFuncs %d\n", pTypeAttr->cFuncs);
568 ok(pTypeAttr->wTypeFlags == 0, "wTypeFlags %04x\n", pTypeAttr->cFuncs);
569 ITypeInfo_ReleaseTypeAttr(pTypeInfo, pTypeAttr);
570
571 hr = ITypeInfo_GetRefTypeOfImplType(pTypeInfo, 0, &href);
572 ok(hr == S_OK, "hr %08x\n", hr);
573 ok(href == 0, "href = 0x%x\n", href);
574 hr = ITypeInfo_GetRefTypeInfo(pTypeInfo, href, &pTI2);
575 ok(hr == S_OK, "hr %08x\n", hr);
576 hr = ITypeInfo_GetTypeAttr(pTI2, &pTypeAttr);
577 ok(hr == S_OK, "hr %08x\n", hr);
578 ok(pTypeAttr->typekind == TKIND_INTERFACE, "typekind %0x\n", pTypeAttr->typekind);
579 ok(pTypeAttr->cFuncs == 4, "cFuncs %d\n", pTypeAttr->cFuncs);
580 ok(IsEqualGUID(&pTypeAttr->guid, &GUID_NULL), "guid {%08x-...}\n", pTypeAttr->guid.Data1);
581 ok(pTypeAttr->wTypeFlags == 0, "typeflags %08x\n", pTypeAttr->wTypeFlags);
582
583 ITypeInfo_ReleaseTypeAttr(pTI2, pTypeAttr);
584
585 hr = ITypeInfo_GetFuncDesc(pTI2, 0, &pFuncDesc);
586 ok(hr == S_OK, "hr %08x\n", hr);
587 ok(pFuncDesc->memid == 0x123, "memid %x\n", pFuncDesc->memid);
588 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
589 ok(pFuncDesc->invkind == methdata[0].wFlags, "invkind %d\n", pFuncDesc->invkind);
590 ok(pFuncDesc->callconv == methdata[0].cc, "callconv %d\n", pFuncDesc->callconv);
591 ok(pFuncDesc->cParams == methdata[0].cArgs, "cParams %d\n", pFuncDesc->cParams);
592 ok(pFuncDesc->oVft == 0, "oVft %d\n", pFuncDesc->oVft);
593 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
594 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
595 ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
596 ok(U(pFuncDesc->lprgelemdescParam[0]).paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", U(pFuncDesc->lprgelemdescParam[0]).paramdesc.wParamFlags);
597
598 ok(pFuncDesc->lprgelemdescParam[1].tdesc.vt == VT_BSTR, "parm 1 vt %x\n", pFuncDesc->lprgelemdescParam[1].tdesc.vt);
599 ok(U(pFuncDesc->lprgelemdescParam[1]).paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 1 flags %x\n", U(pFuncDesc->lprgelemdescParam[1]).paramdesc.wParamFlags);
600 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
601
602 hr = ITypeInfo_GetFuncDesc(pTI2, 1, &pFuncDesc);
603 ok(hr == S_OK, "hr %08x\n", hr);
604 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
605 ok(pFuncDesc->invkind == methdata[1].wFlags, "invkind %d\n", pFuncDesc->invkind);
606 ok(pFuncDesc->callconv == methdata[1].cc, "callconv %d\n", pFuncDesc->callconv);
607 ok(pFuncDesc->cParams == methdata[1].cArgs, "cParams %d\n", pFuncDesc->cParams);
608 ok(pFuncDesc->oVft == sizeof(void *), "oVft %d\n", pFuncDesc->oVft);
609 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
610 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
611 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
612
613 hr = ITypeInfo_GetFuncDesc(pTI2, 2, &pFuncDesc);
614 ok(hr == S_OK, "hr %08x\n", hr);
615 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
616 ok(pFuncDesc->invkind == methdata[2].wFlags, "invkind %d\n", pFuncDesc->invkind);
617 ok(pFuncDesc->callconv == methdata[2].cc, "callconv %d\n", pFuncDesc->callconv);
618 ok(pFuncDesc->cParams == methdata[2].cArgs, "cParams %d\n", pFuncDesc->cParams);
619 ok(pFuncDesc->oVft == 3 * sizeof(void *), "oVft %d\n", pFuncDesc->oVft);
620 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
621 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_HRESULT, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
622 ok(pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_I4, "parm 0 vt %x\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt);
623 ok(U(pFuncDesc->lprgelemdescParam[0]).paramdesc.wParamFlags == PARAMFLAG_NONE, "parm 0 flags %x\n", U(pFuncDesc->lprgelemdescParam[0]).paramdesc.wParamFlags);
624 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
625
626 hr = ITypeInfo_GetFuncDesc(pTI2, 3, &pFuncDesc);
627 ok(hr == S_OK, "hr %08x\n", hr);
628 ok(pFuncDesc->funckind == FUNC_VIRTUAL, "funckind %d\n", pFuncDesc->funckind);
629 ok(pFuncDesc->invkind == methdata[3].wFlags, "invkind %d\n", pFuncDesc->invkind);
630 ok(pFuncDesc->callconv == methdata[3].cc, "callconv %d\n", pFuncDesc->callconv);
631 ok(pFuncDesc->cParams == methdata[3].cArgs, "cParams %d\n", pFuncDesc->cParams);
632 ok(pFuncDesc->oVft == 4 * sizeof(void *), "oVft %d\n", pFuncDesc->oVft);
633 ok(pFuncDesc->wFuncFlags == 0, "oVft %d\n", pFuncDesc->wFuncFlags);
634 ok(pFuncDesc->elemdescFunc.tdesc.vt == VT_I4, "ret vt %x\n", pFuncDesc->elemdescFunc.tdesc.vt);
635 ITypeInfo_ReleaseFuncDesc(pTI2, pFuncDesc);
636
637 /* test GetIDsOfNames on a coclass to see if it searches its interfaces */
638 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &name, 1, &memid);
639 ok(hr == S_OK, "hr 0x%08x\n", hr);
640 ok(memid == 0x123, "memid 0x%08x\n", memid);
641
642 ITypeInfo_Release(pTI2);
643 ITypeInfo_Release(pTypeInfo);
644
645 SysFreeString(parms1[0].szName);
646 SysFreeString(parms1[1].szName);
647 SysFreeString(parms3[0].szName);
648 SysFreeString(methdata[0].szName);
649 SysFreeString(methdata[1].szName);
650 SysFreeString(methdata[2].szName);
651 SysFreeString(methdata[3].szName);
652 }
653
654 static void write_typelib(int res_no, const char *filename)
655 {
656 DWORD written;
657 HANDLE file;
658 HRSRC res;
659 void *ptr;
660
661 file = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
662 ok( file != INVALID_HANDLE_VALUE, "file creation failed\n" );
663 if (file == INVALID_HANDLE_VALUE) return;
664 res = FindResourceA( GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(res_no), "TYPELIB" );
665 ok( res != 0, "couldn't find resource\n" );
666 ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
667 WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
668 ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
669 CloseHandle( file );
670 }
671
672 static const char *create_test_typelib(int res_no)
673 {
674 static char filename[MAX_PATH];
675
676 GetTempFileNameA( ".", "tlb", 0, filename );
677 write_typelib(res_no, filename);
678 return filename;
679 }
680
681 static void test_TypeInfo(void)
682 {
683 ITypeLib *pTypeLib;
684 ITypeInfo *pTypeInfo, *ti;
685 ITypeInfo2 *pTypeInfo2;
686 HRESULT hr;
687 static WCHAR wszBogus[] = { 'b','o','g','u','s',0 };
688 static WCHAR wszGetTypeInfo[] = { 'G','e','t','T','y','p','e','I','n','f','o',0 };
689 static WCHAR wszClone[] = {'C','l','o','n','e',0};
690 OLECHAR* bogus = wszBogus;
691 OLECHAR* pwszGetTypeInfo = wszGetTypeInfo;
692 OLECHAR* pwszClone = wszClone;
693 DISPID dispidMember;
694 DISPPARAMS dispparams;
695 GUID bogusguid = {0x806afb4f,0x13f7,0x42d2,{0x89,0x2c,0x6c,0x97,0xc3,0x6a,0x36,0xc1}};
696 VARIANT var, res, args[2];
697 UINT count, i;
698 TYPEKIND kind;
699 const char *filenameA;
700 WCHAR filename[MAX_PATH];
701 TYPEATTR *attr;
702 LONG l;
703
704 hr = LoadTypeLib(wszStdOle2, &pTypeLib);
705 ok_ole_success(hr, LoadTypeLib);
706
707 count = ITypeLib_GetTypeInfoCount(pTypeLib);
708 ok(count > 0, "got %d\n", count);
709
710 /* invalid index */
711 hr = ITypeLib_GetTypeInfo(pTypeLib, count, &pTypeInfo);
712 ok(hr == TYPE_E_ELEMENTNOTFOUND, "got 0x%08x\n", hr);
713
714 hr = ITypeLib_GetTypeInfo(pTypeLib, 0, NULL);
715 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
716
717 hr = ITypeLib_GetLibAttr(pTypeLib, NULL);
718 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
719
720 hr = ITypeLib_GetTypeInfoType(pTypeLib, count, &kind);
721 ok(hr == TYPE_E_ELEMENTNOTFOUND, "got 0x%08x\n", hr);
722
723 hr = ITypeLib_GetTypeInfoType(pTypeLib, count, NULL);
724 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
725
726 hr = ITypeLib_GetTypeInfoType(pTypeLib, 0, NULL);
727 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
728
729 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IFont, &pTypeInfo);
730 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
731
732 /* test nonexistent method name */
733 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &bogus, 1, &dispidMember);
734 ok(hr == DISP_E_UNKNOWNNAME,
735 "ITypeInfo_GetIDsOfNames should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n",
736 hr);
737
738 dispparams.cArgs = 0;
739 dispparams.rgdispidNamedArgs = NULL;
740 dispparams.rgvarg = NULL;
741
742 /* test dispparams not NULL */
743
744 /* invalid member id -- wrong flags -- cNamedArgs not bigger than cArgs */
745 dispparams.cNamedArgs = 0;
746 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
747 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
748 /* invalid member id -- correct flags -- cNamedArgs not bigger than cArgs */
749 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
750 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
751
752 /* invalid member id -- wrong flags -- cNamedArgs bigger than cArgs */
753 dispparams.cNamedArgs = 1;
754 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
755 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
756 /* invalid member id -- correct flags -- cNamedArgs bigger than cArgs */
757 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
758 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
759
760
761 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &pwszClone, 1, &dispidMember);
762 ok_ole_success(hr, ITypeInfo_GetIDsOfNames);
763
764 /* correct member id -- wrong flags -- cNamedArgs not bigger than cArgs */
765 dispparams.cNamedArgs = 0;
766 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
767 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
768 /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs */
769 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
770 ok(hr == DISP_E_BADPARAMCOUNT, "ITypeInfo_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
771
772 /* correct member id -- wrong flags -- cNamedArgs bigger than cArgs */
773 dispparams.cNamedArgs = 1;
774 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
775 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
776 /* correct member id -- correct flags -- cNamedArgs bigger than cArgs */
777 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
778 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
779
780 /* test NULL dispparams */
781
782 /* correct member id -- wrong flags -- cNamedArgs not bigger than cArgs */
783 dispparams.cNamedArgs = 0;
784 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
785 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
786 /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs */
787 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, NULL, NULL, NULL, NULL);
788 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
789
790 /* correct member id -- wrong flags -- cNamedArgs bigger than cArgs */
791 dispparams.cNamedArgs = 1;
792 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
793 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
794 /* correct member id -- correct flags -- cNamedArgs bigger than cArgs */
795 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, NULL, NULL, NULL, NULL);
796 ok(hr == E_INVALIDARG, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr);
797
798 ITypeInfo_Release(pTypeInfo);
799
800 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IDispatch, &pTypeInfo);
801 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
802
803 hr = ITypeInfo_GetIDsOfNames(pTypeInfo, &pwszGetTypeInfo, 1, &dispidMember);
804 ok_ole_success(hr, ITypeInfo_GetIDsOfNames);
805
806 hr = ITypeInfo_QueryInterface(pTypeInfo, &IID_ITypeInfo2, (void**)&pTypeInfo2);
807 ok_ole_success(hr, ITypeInfo_QueryInterface);
808
809 if (SUCCEEDED(hr))
810 {
811 VariantInit(&var);
812
813 V_VT(&var) = VT_I4;
814
815 /* test unknown guid passed to GetCustData */
816 hr = ITypeInfo2_GetCustData(pTypeInfo2, &bogusguid, &var);
817 ok_ole_success(hr, ITypeInfo_GetCustData);
818 ok(V_VT(&var) == VT_EMPTY, "got %i, expected VT_EMPTY\n", V_VT(&var));
819
820 ITypeInfo2_Release(pTypeInfo2);
821
822 VariantClear(&var);
823 }
824
825 /* Check instance size for IDispatch, typelib is loaded using system SYS_WIN* kind so it always matches
826 system bitness. */
827 hr = ITypeInfo_GetTypeAttr(pTypeInfo, &attr);
828 ok(hr == S_OK, "got 0x%08x\n", hr);
829 ok(attr->cbSizeInstance == sizeof(void*), "got size %d\n", attr->cbSizeInstance);
830 ok(attr->typekind == TKIND_INTERFACE, "got typekind %d\n", attr->typekind);
831 ITypeInfo_ReleaseTypeAttr(pTypeInfo, attr);
832
833 /* same size check with some general interface */
834 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IEnumVARIANT, &ti);
835 ok(hr == S_OK, "got 0x%08x\n", hr);
836 hr = ITypeInfo_GetTypeAttr(ti, &attr);
837 ok(hr == S_OK, "got 0x%08x\n", hr);
838 ok(attr->cbSizeInstance == sizeof(void*), "got size %d\n", attr->cbSizeInstance);
839 ITypeInfo_ReleaseTypeAttr(ti, attr);
840 ITypeInfo_Release(ti);
841
842 /* test invoking a method with a [restricted] keyword */
843
844 /* correct member id -- wrong flags -- cNamedArgs not bigger than cArgs */
845 dispparams.cNamedArgs = 0;
846 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
847 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
848 /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs */
849 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
850 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
851
852 /* correct member id -- wrong flags -- cNamedArgs bigger than cArgs */
853 dispparams.cNamedArgs = 1;
854 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
855 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
856 /* correct member id -- correct flags -- cNamedArgs bigger than cArgs */
857 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
858 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
859
860 /* test NULL dispparams */
861
862 /* correct member id -- wrong flags -- cNamedArgs not bigger than cArgs */
863 dispparams.cNamedArgs = 0;
864 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
865 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
866 /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs */
867 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, NULL, NULL, NULL, NULL);
868 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
869
870 /* correct member id -- wrong flags -- cNamedArgs bigger than cArgs */
871 dispparams.cNamedArgs = 1;
872 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
873 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
874 /* correct member id -- correct flags -- cNamedArgs bigger than cArgs */
875 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, NULL, NULL, NULL, NULL);
876 ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
877
878 ITypeInfo_Release(pTypeInfo);
879 ITypeLib_Release(pTypeLib);
880
881 filenameA = create_test_typelib(3);
882 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filename, MAX_PATH);
883 hr = LoadTypeLib(filename, &pTypeLib);
884 ok(hr == S_OK, "got 0x%08x\n", hr);
885
886 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IInvokeTest, &pTypeInfo);
887 ok(hr == S_OK, "got 0x%08x\n", hr);
888
889 dispparams.cArgs = 1;
890 dispparams.cNamedArgs = 0;
891 dispparams.rgdispidNamedArgs = NULL;
892 dispparams.rgvarg = args;
893
894 V_VT(&args[0]) = VT_I4;
895 V_I4(&args[0]) = 0;
896
897 i = 0;
898 V_VT(&res) = VT_EMPTY;
899 V_I4(&res) = 0;
900 /* call propget with DISPATCH_METHOD|DISPATCH_PROPERTYGET flags */
901 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, DISPID_VALUE, DISPATCH_METHOD|DISPATCH_PROPERTYGET,
902 &dispparams, &res, NULL, &i);
903 ok(hr == S_OK, "got 0x%08x\n", hr);
904 ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res));
905 ok(V_I4(&res) == 1, "got %d\n", V_I4(&res));
906
907 i = 0;
908 /* call propget with DISPATCH_METHOD flags */
909 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, DISPID_VALUE, DISPATCH_METHOD,
910 &dispparams, &res, NULL, &i);
911 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x, %d\n", hr, i);
912
913 i = 0;
914 V_VT(&res) = VT_EMPTY;
915 V_I4(&res) = 0;
916 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, DISPID_VALUE, DISPATCH_PROPERTYGET,
917 &dispparams, &res, NULL, &i);
918 ok(hr == S_OK, "got 0x%08x, %d\n", hr, i);
919 ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res));
920 ok(V_I4(&res) == 1, "got %d\n", V_I4(&res));
921
922 /* DISPATCH_PROPERTYPUTREF */
923 l = 1;
924 V_VT(&args[0]) = VT_I4|VT_BYREF;
925 V_I4REF(&args[0]) = &l;
926
927 dispidMember = DISPID_PROPERTYPUT;
928 dispparams.cArgs = 1;
929 dispparams.cNamedArgs = 1;
930 dispparams.rgdispidNamedArgs = &dispidMember;
931 dispparams.rgvarg = args;
932
933 i = 0;
934 V_VT(&res) = VT_EMPTY;
935 V_I4(&res) = 0;
936 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, 1, DISPATCH_PROPERTYPUTREF, &dispparams, &res, NULL, &i);
937 ok(hr == S_OK, "got 0x%08x, %d\n", hr, i);
938 ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res));
939 ok(V_I4(&res) == 3, "got %d\n", V_I4(&res));
940
941 i = 0;
942 V_VT(&res) = VT_EMPTY;
943 V_I4(&res) = 0;
944 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, 1, DISPATCH_PROPERTYPUT, &dispparams, &res, NULL, &i);
945 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x, %d\n", hr, i);
946
947 i = 0;
948 V_VT(&args[0]) = VT_UNKNOWN;
949 V_UNKNOWN(&args[0]) = NULL;
950
951 V_VT(&res) = VT_EMPTY;
952 V_I4(&res) = 0;
953 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, 2, DISPATCH_PROPERTYPUTREF, &dispparams, &res, NULL, &i);
954 ok(hr == S_OK, "got 0x%08x, %d\n", hr, i);
955 ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res));
956 ok(V_I4(&res) == 6, "got %d\n", V_I4(&res));
957
958 i = 0;
959 V_VT(&res) = VT_EMPTY;
960 V_I4(&res) = 0;
961 hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, 2, DISPATCH_PROPERTYPUT, &dispparams, &res, NULL, &i);
962 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x, %d\n", hr, i);
963
964 ITypeInfo_Release(pTypeInfo);
965 ITypeLib_Release(pTypeLib);
966 DeleteFileA(filenameA);
967 }
968
969 static int WINAPI int_func( int a0, int a1, int a2, int a3, int a4 )
970 {
971 ok( a0 == 1, "wrong arg0 %x\n", a0 );
972 ok( a1 == -1, "wrong arg1 %x\n", a1 );
973 ok( a2 == (0x55550000 | 1234), "wrong arg2 %x\n", a2 );
974 ok( a3 == 0xdeadbeef, "wrong arg3 %x\n", a3 );
975 ok( a4 == 0x555555fd, "wrong arg4 %x\n", a4 );
976 return 4321;
977 }
978
979 static double WINAPI double_func( double a0, float a1, double a2, int a3 )
980 {
981 ok( a0 == 1.2, "wrong arg0 %f\n", (double)a0 );
982 ok( a1 == 3.25, "wrong arg1 %f\n", (double)a1 );
983 ok( a2 == 1.2e12, "wrong arg2 %f\n", (double)a2);
984 ok( a3 == -4433.0, "wrong arg3 %f\n", (double)a3 );
985 return 4321;
986 }
987
988 static LONGLONG WINAPI longlong_func( LONGLONG a0, CY a1 )
989 {
990 ok( a0 == (((ULONGLONG)0xdead << 32) | 0xbeef), "wrong arg0 %08x%08x\n", (DWORD)(a0 >> 32), (DWORD)a0);
991 ok( a1.int64 == ((ULONGLONG)10000 * 12345678), "wrong arg1 %08x%08x\n",
992 (DWORD)(a1.int64 >> 32), (DWORD)a1.int64 );
993 return ((ULONGLONG)4321 << 32) | 8765;
994 }
995
996 static VARIANT WINAPI variant_func( int a0, BOOL a1, DECIMAL a2, VARIANT a3 )
997 {
998 VARIANT var;
999 ok( a0 == 2233, "wrong arg0 %x\n", a0 );
1000 ok( a1 == 1 || broken(a1 == 0x55550001), "wrong arg1 %x\n", a1 );
1001 V_VT(&var) = VT_LPWSTR;
1002 V_UI4(&var) = 0xbabe;
1003 ok( a2.Hi32 == 1122, "wrong arg2.Hi32 %x\n", a2.Hi32 );
1004 ok( U1(a2).Lo64 == 3344, "wrong arg2.Lo64 %08x%08x\n", (DWORD)(U1(a2).Lo64 >> 32), (DWORD)U1(a2).Lo64 );
1005 ok( V_VT(&a3) == VT_EMPTY, "wrong arg3 type %x\n", V_VT(&a3) );
1006 ok( V_UI4(&a3) == 0xdeadbeef, "wrong arg3 value %x\n", V_UI4(&a3) );
1007 return var;
1008 }
1009
1010 static int CDECL void_func( int a0, int a1 )
1011 {
1012 if (is_win64) /* VT_EMPTY is passed as real arg on win64 */
1013 {
1014 ok( a0 == 0x55555555, "wrong arg0 %x\n", a0 );
1015 ok( a1 == 1111, "wrong arg1 %x\n", a1 );
1016 }
1017 else
1018 {
1019 ok( a0 == 1111, "wrong arg0 %x\n", a0 );
1020 ok( a1 == 0, "wrong arg1 %x\n", a1 );
1021 }
1022 return 12;
1023 }
1024
1025 static int WINAPI stdcall_func( int a )
1026 {
1027 return 0;
1028 }
1029
1030 static int WINAPI inst_func( void *inst, int a )
1031 {
1032 ok( (*(void ***)inst)[3] == inst_func, "wrong ptr %p\n", inst );
1033 ok( a == 3, "wrong arg %x\n", a );
1034 return a * 2;
1035 }
1036
1037 static HRESULT WINAPI ret_false_func(void)
1038 {
1039 return S_FALSE;
1040 }
1041
1042 static const void *vtable[] = { NULL, NULL, NULL, inst_func };
1043
1044 static void test_DispCallFunc(void)
1045 {
1046 const void **inst = vtable;
1047 HRESULT res;
1048 VARIANT result, args[5];
1049 VARIANTARG *pargs[5];
1050 VARTYPE types[5];
1051 int i;
1052
1053 for (i = 0; i < 5; i++) pargs[i] = &args[i];
1054
1055 memset( args, 0x55, sizeof(args) );
1056 types[0] = VT_UI4;
1057 V_UI4(&args[0]) = 1;
1058 types[1] = VT_I4;
1059 V_I4(&args[1]) = -1;
1060 types[2] = VT_I2;
1061 V_I2(&args[2]) = 1234;
1062 types[3] = VT_UI4;
1063 V_UI4(&args[3]) = 0xdeadbeef;
1064 types[4] = VT_UI4;
1065 V_I1(&args[4]) = -3;
1066 memset( &result, 0xcc, sizeof(result) );
1067 res = DispCallFunc( NULL, (ULONG_PTR)int_func, CC_STDCALL, VT_UI4, 5, types, pargs, &result );
1068 ok( res == S_OK, "DispCallFunc failed %x\n", res );
1069 ok( V_VT(&result) == VT_UI4, "wrong result type %d\n", V_VT(&result) );
1070 ok( V_UI4(&result) == 4321, "wrong result %u\n", V_UI4(&result) );
1071
1072 /* the function checks the argument sizes for stdcall */
1073 if (!is_win64) /* no stdcall on 64-bit */
1074 {
1075 res = DispCallFunc( NULL, (ULONG_PTR)stdcall_func, CC_STDCALL, VT_UI4, 0, types, pargs, &result );
1076 ok( res == DISP_E_BADCALLEE, "DispCallFunc wrong error %x\n", res );
1077 res = DispCallFunc( NULL, (ULONG_PTR)stdcall_func, CC_STDCALL, VT_UI4, 1, types, pargs, &result );
1078 ok( res == S_OK, "DispCallFunc failed %x\n", res );
1079 res = DispCallFunc( NULL, (ULONG_PTR)stdcall_func, CC_STDCALL, VT_UI4, 2, types, pargs, &result );
1080 ok( res == DISP_E_BADCALLEE, "DispCallFunc wrong error %x\n", res );
1081 }
1082
1083 memset( args, 0x55, sizeof(args) );
1084 types[0] = VT_R8;
1085 V_R8(&args[0]) = 1.2;
1086 types[1] = VT_R4;
1087 V_R4(&args[1]) = 3.25;
1088 types[2] = VT_R8;
1089 V_R8(&args[2]) = 1.2e12;
1090 types[3] = VT_I4;
1091 V_I4(&args[3]) = -4433;
1092 memset( &result, 0xcc, sizeof(result) );
1093 res = DispCallFunc( NULL, (ULONG_PTR)double_func, CC_STDCALL, VT_R8, 4, types, pargs, &result );
1094 ok( res == S_OK, "DispCallFunc failed %x\n", res );
1095 ok( V_VT(&result) == VT_R8, "wrong result type %d\n", V_VT(&result) );
1096 ok( V_R8(&result) == 4321, "wrong result %f\n", V_R8(&result) );
1097
1098 memset( args, 0x55, sizeof(args) );
1099 types[0] = VT_I8;
1100 V_I8(&args[0]) = ((ULONGLONG)0xdead << 32) | 0xbeef;
1101 types[1] = VT_CY;
1102 V_CY(&args[1]).int64 = (ULONGLONG)10000 * 12345678;
1103 memset( &result, 0xcc, sizeof(result) );
1104 res = DispCallFunc( NULL, (ULONG_PTR)longlong_func, CC_STDCALL, VT_I8, 2, types, pargs, &result );
1105 ok( res == S_OK || broken(res == E_INVALIDARG), /* longlong not supported on <= win2k */
1106 "DispCallFunc failed %x\n", res );
1107 if (res == S_OK)
1108 {
1109 ok( V_VT(&result) == VT_I8, "wrong result type %d\n", V_VT(&result) );
1110 ok( V_I8(&result) == (((ULONGLONG)4321 << 32) | 8765), "wrong result %08x%08x\n",
1111 (DWORD)(V_I8(&result) >> 32), (DWORD)V_I8(&result) );
1112 }
1113
1114 memset( args, 0x55, sizeof(args) );
1115 types[0] = VT_I4;
1116 V_I4(&args[0]) = 2233;
1117 types[1] = VT_BOOL;
1118 V_BOOL(&args[1]) = 1;
1119 types[2] = VT_DECIMAL;
1120 V_DECIMAL(&args[2]).Hi32 = 1122;
1121 U1(V_DECIMAL(&args[2])).Lo64 = 3344;
1122 types[3] = VT_VARIANT;
1123 V_VT(&args[3]) = VT_EMPTY;
1124 V_UI4(&args[3]) = 0xdeadbeef;
1125 types[4] = VT_EMPTY;
1126 memset( &result, 0xcc, sizeof(result) );
1127 res = DispCallFunc( NULL, (ULONG_PTR)variant_func, CC_STDCALL, VT_VARIANT, 5, types, pargs, &result );
1128 ok( res == S_OK, "DispCallFunc failed %x\n", res );
1129 ok( V_VT(&result) == VT_LPWSTR, "wrong result type %d\n", V_VT(&result) );
1130 ok( V_UI4(&result) == 0xbabe, "wrong result %08x\n", V_UI4(&result) );
1131
1132 memset( args, 0x55, sizeof(args) );
1133 types[0] = VT_EMPTY;
1134 types[1] = VT_I4;
1135 V_I4(&args[1]) = 1111;
1136 types[2] = VT_EMPTY;
1137 types[3] = VT_I4;
1138 V_I4(&args[3]) = 0;
1139 types[4] = VT_EMPTY;
1140 memset( &result, 0xcc, sizeof(result) );
1141 res = DispCallFunc( NULL, (ULONG_PTR)void_func, CC_CDECL, VT_EMPTY, 5, types, pargs, &result );
1142 ok( res == S_OK, "DispCallFunc failed %x\n", res );
1143 ok( V_VT(&result) == VT_EMPTY, "wrong result type %d\n", V_VT(&result) );
1144 if (is_win64)
1145 ok( V_UI4(&result) == 12, "wrong result %08x\n", V_UI4(&result) );
1146 else
1147 ok( V_UI4(&result) == 0xcccccccc, "wrong result %08x\n", V_UI4(&result) );
1148
1149 memset( args, 0x55, sizeof(args) );
1150 types[0] = VT_I4;
1151 V_I4(&args[0]) = 3;
1152 memset( &result, 0xcc, sizeof(result) );
1153 res = DispCallFunc( &inst, 3 * sizeof(void*), CC_STDCALL, VT_I4, 1, types, pargs, &result );
1154 ok( res == S_OK, "DispCallFunc failed %x\n", res );
1155 ok( V_VT(&result) == VT_I4, "wrong result type %d\n", V_VT(&result) );
1156 ok( V_I4(&result) == 6, "wrong result %08x\n", V_I4(&result) );
1157
1158 memset( &result, 0xcc, sizeof(result) );
1159 res = DispCallFunc(NULL, (ULONG_PTR)ret_false_func, CC_STDCALL, VT_ERROR, 0, NULL, NULL, &result);
1160 ok(res == S_OK, "DispCallFunc failed: %08x\n", res);
1161 ok(V_VT(&result) == VT_ERROR, "V_VT(result) = %u\n", V_VT(&result));
1162 ok(V_ERROR(&result) == S_FALSE, "V_ERROR(result) = %08x\n", V_ERROR(&result));
1163
1164 memset( &result, 0xcc, sizeof(result) );
1165 res = DispCallFunc(NULL, (ULONG_PTR)ret_false_func, CC_STDCALL, VT_HRESULT, 0, NULL, NULL, &result);
1166 ok(res == E_INVALIDARG, "DispCallFunc failed: %08x\n", res);
1167 ok(V_VT(&result) == 0xcccc, "V_VT(result) = %u\n", V_VT(&result));
1168 }
1169
1170 /* RegDeleteTreeW from dlls/advapi32/registry.c, plus additional view flag */
1171 static LSTATUS myRegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM view)
1172 {
1173 LONG ret;
1174 DWORD dwMaxSubkeyLen, dwMaxValueLen;
1175 DWORD dwMaxLen, dwSize;
1176 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
1177 HKEY hSubKey = hKey;
1178 view &= (KEY_WOW64_64KEY | KEY_WOW64_32KEY);
1179
1180 if(lpszSubKey)
1181 {
1182 ret = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ | view, &hSubKey);
1183 if (ret) return ret;
1184 }
1185
1186 ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
1187 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
1188 if (ret) goto cleanup;
1189
1190 dwMaxSubkeyLen++;
1191 dwMaxValueLen++;
1192 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
1193 if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR))
1194 {
1195 /* Name too big: alloc a buffer for it */
1196 if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(WCHAR))))
1197 {
1198 ret = ERROR_NOT_ENOUGH_MEMORY;
1199 goto cleanup;
1200 }
1201 }
1202
1203 /* Recursively delete all the subkeys */
1204 while (TRUE)
1205 {
1206 dwSize = dwMaxLen;
1207 if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
1208 NULL, NULL, NULL)) break;
1209
1210 ret = myRegDeleteTreeW(hSubKey, lpszName, view);
1211 if (ret) goto cleanup;
1212 }
1213
1214 if (lpszSubKey)
1215 if (pRegDeleteKeyExW && view != 0)
1216 ret = pRegDeleteKeyExW(hKey, lpszSubKey, view, 0);
1217 else
1218 ret = RegDeleteKeyW(hKey, lpszSubKey);
1219 else
1220 while (TRUE)
1221 {
1222 dwSize = dwMaxLen;
1223 if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
1224 NULL, NULL, NULL, NULL)) break;
1225
1226 ret = RegDeleteValueW(hKey, lpszName);
1227 if (ret) goto cleanup;
1228 }
1229
1230 cleanup:
1231 if (lpszName != szNameBuf)
1232 HeapFree(GetProcessHeap(), 0, lpszName);
1233 if(lpszSubKey)
1234 RegCloseKey(hSubKey);
1235 return ret;
1236 }
1237
1238 static BOOL do_typelib_reg_key(GUID *uid, WORD maj, WORD min, DWORD arch, LPCWSTR base, BOOL remove)
1239 {
1240 static const WCHAR typelibW[] = {'T','y','p','e','l','i','b','\\',0};
1241 static const WCHAR formatW[] = {'\\','%','u','.','%','u','\\','0','\\','w','i','n','%','u',0};
1242 static const WCHAR format2W[] = {'%','s','_','%','u','_','%','u','.','d','l','l',0};
1243 WCHAR buf[128];
1244 HKEY hkey;
1245 BOOL ret = TRUE;
1246 DWORD res;
1247
1248 memcpy(buf, typelibW, sizeof(typelibW));
1249 StringFromGUID2(uid, buf + lstrlenW(buf), 40);
1250
1251 if (remove)
1252 {
1253 ok(myRegDeleteTreeW(HKEY_CLASSES_ROOT, buf, 0) == ERROR_SUCCESS, "SHDeleteKey failed\n");
1254 return TRUE;
1255 }
1256
1257 wsprintfW(buf + lstrlenW(buf), formatW, maj, min, arch);
1258
1259 SetLastError(0xdeadbeef);
1260 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0,
1261 KEY_WRITE, NULL, &hkey, NULL);
1262 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1263 {
1264 win_skip("W-calls are not implemented\n");
1265 return FALSE;
1266 }
1267
1268 if (res != ERROR_SUCCESS)
1269 {
1270 trace("RegCreateKeyExW failed: %u\n", res);
1271 return FALSE;
1272 }
1273
1274 wsprintfW(buf, format2W, base, maj, min);
1275 if (RegSetValueExW(hkey, NULL, 0, REG_SZ,
1276 (BYTE *)buf, (lstrlenW(buf) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS)
1277 {
1278 trace("RegSetValueExW failed\n");
1279 ret = FALSE;
1280 }
1281 RegCloseKey(hkey);
1282 return ret;
1283 }
1284
1285 static void test_QueryPathOfRegTypeLib(DWORD arch)
1286 {
1287 static const struct test_data
1288 {
1289 WORD maj, min;
1290 HRESULT ret;
1291 const WCHAR path[16];
1292 } td[] = {
1293 { 1, 0, TYPE_E_LIBNOTREGISTERED, { 0 } },
1294 { 3, 0, S_OK, {'f','a','k','e','_','3','_','0','.','d','l','l',0 } },
1295 { 3, 1, S_OK, {'f','a','k','e','_','3','_','1','.','d','l','l',0 } },
1296 { 3, 22, S_OK, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
1297 { 3, 37, S_OK, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
1298 { 3, 40, S_OK, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
1299 { 0xffff, 0xffff, S_OK, {'f','a','k','e','_','5','_','3','7','.','d','l','l',0 } },
1300 { 0xffff, 0, TYPE_E_LIBNOTREGISTERED, { 0 } },
1301 { 3, 0xffff, TYPE_E_LIBNOTREGISTERED, { 0 } },
1302 { 5, 0xffff, TYPE_E_LIBNOTREGISTERED, { 0 } },
1303 { 4, 0, TYPE_E_LIBNOTREGISTERED, { 0 } }
1304 };
1305 static const WCHAR base[] = {'f','a','k','e',0};
1306 static const WCHAR wrongW[] = {'w','r','o','n','g',0};
1307 UINT i;
1308 RPC_STATUS status;
1309 GUID uid;
1310 WCHAR uid_str[40];
1311 HRESULT ret;
1312 BSTR path;
1313
1314 status = UuidCreate(&uid);
1315 ok(!status || status == RPC_S_UUID_LOCAL_ONLY, "UuidCreate error %08x\n", status);
1316
1317 StringFromGUID2(&uid, uid_str, 40);
1318 /*trace("GUID: %s\n", wine_dbgstr_w(uid_str));*/
1319
1320 if (!do_typelib_reg_key(&uid, 3, 0, arch, base, FALSE)) return;
1321 if (!do_typelib_reg_key(&uid, 3, 1, arch, base, FALSE)) return;
1322 if (!do_typelib_reg_key(&uid, 3, 37, arch, base, FALSE)) return;
1323 if (!do_typelib_reg_key(&uid, 5, 37, arch, base, FALSE)) return;
1324 if (arch == 64 && !do_typelib_reg_key(&uid, 5, 37, 32, wrongW, FALSE)) return;
1325
1326 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
1327 {
1328 ret = QueryPathOfRegTypeLib(&uid, td[i].maj, td[i].min, LOCALE_NEUTRAL, &path);
1329 ok(ret == td[i].ret, "QueryPathOfRegTypeLib(%u.%u) returned %08x\n", td[i].maj, td[i].min, ret);
1330 if (ret == S_OK)
1331 {
1332 ok(!lstrcmpW(td[i].path, path), "typelib %u.%u path doesn't match\n", td[i].maj, td[i].min);
1333 SysFreeString(path);
1334 }
1335 }
1336
1337 do_typelib_reg_key(&uid, 0, 0, arch, NULL, TRUE);
1338 }
1339
1340 static void test_inheritance(void)
1341 {
1342 HRESULT hr;
1343 ITypeLib *pTL;
1344 ITypeInfo *pTI, *pTI_p;
1345 TYPEATTR *pTA;
1346 HREFTYPE href;
1347 FUNCDESC *pFD;
1348 WCHAR path[MAX_PATH];
1349 CHAR pathA[MAX_PATH];
1350 static const WCHAR tl_path[] = {'.','\\','m','i','d','l','_','t','m','a','r','s','h','a','l','.','t','l','b',0};
1351
1352 BOOL use_midl_tlb = FALSE;
1353
1354 GetModuleFileNameA(NULL, pathA, MAX_PATH);
1355 MultiByteToWideChar(CP_ACP, 0, pathA, -1, path, MAX_PATH);
1356
1357 if(use_midl_tlb)
1358 memcpy(path, tl_path, sizeof(tl_path));
1359
1360 hr = LoadTypeLib(path, &pTL);
1361 if(FAILED(hr)) return;
1362
1363
1364 /* ItestIF3 is a syntax 2 dispinterface */
1365 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF3, &pTI);
1366 ok(hr == S_OK, "hr %08x\n", hr);
1367
1368 hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
1369 ok(hr == S_OK, "hr %08x\n", hr);
1370 ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
1371 ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1372 ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags);
1373 if(use_midl_tlb) {
1374 ok(pTA->cFuncs == 6, "cfuncs %d\n", pTA->cFuncs);
1375 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1376 }
1377 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1378
1379 if(use_midl_tlb) {
1380 hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
1381 ok(hr == S_OK, "hr %08x\n", hr);
1382 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1383 ok(hr == S_OK, "hr %08x\n", hr);
1384 hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
1385 ok(hr == S_OK, "got %08x\n", hr);
1386 ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
1387 ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
1388 ITypeInfo_Release(pTI_p);
1389
1390 /* Should have six methods */
1391 hr = ITypeInfo_GetFuncDesc(pTI, 6, &pFD);
1392 ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
1393 hr = ITypeInfo_GetFuncDesc(pTI, 5, &pFD);
1394 ok(hr == S_OK, "hr %08x\n", hr);
1395 ok(pFD->memid == 0x60020000, "memid %08x\n", pFD->memid);
1396 ok(pFD->oVft == 5 * sizeof(void *), "oVft %d\n", pFD->oVft);
1397 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1398 }
1399 ITypeInfo_Release(pTI);
1400
1401
1402 /* ItestIF4 is a syntax 1 dispinterface */
1403 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF4, &pTI);
1404 ok(hr == S_OK, "hr %08x\n", hr);
1405
1406 hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
1407 ok(hr == S_OK, "hr %08x\n", hr);
1408 ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
1409 ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1410 ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags);
1411 ok(pTA->cFuncs == 1, "cfuncs %d\n", pTA->cFuncs);
1412 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1413 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1414
1415 hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
1416 ok(hr == S_OK, "hr %08x\n", hr);
1417 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1418 ok(hr == S_OK, "hr %08x\n", hr);
1419 hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
1420 ok(hr == S_OK, "got %08x\n", hr);
1421 ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
1422 ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
1423 ITypeInfo_Release(pTI_p);
1424 hr = ITypeInfo_GetFuncDesc(pTI, 1, &pFD);
1425 ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
1426 hr = ITypeInfo_GetFuncDesc(pTI, 0, &pFD);
1427 ok(hr == S_OK, "hr %08x\n", hr);
1428 ok(pFD->memid == 0x1c, "memid %08x\n", pFD->memid);
1429 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1430 ITypeInfo_Release(pTI);
1431
1432
1433 /* ItestIF5 is dual with inherited ifaces which derive from IUnknown but not IDispatch */
1434 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &IID_ItestIF5, &pTI);
1435 ok(hr == S_OK, "hr %08x\n", hr);
1436
1437 hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
1438 ok(hr == S_OK, "hr %08x\n", hr);
1439 if (hr == S_OK)
1440 {
1441 ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
1442 ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1443 if(use_midl_tlb) {
1444 ok(pTA->wTypeFlags == TYPEFLAG_FDUAL, "typeflags %x\n", pTA->wTypeFlags);
1445 }
1446 ok(pTA->cFuncs == 8, "cfuncs %d\n", pTA->cFuncs);
1447 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1448 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1449 }
1450 hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
1451 ok(hr == S_OK, "hr %08x\n", hr);
1452 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1453 ok(hr == S_OK, "hr %08x\n", hr);
1454 hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
1455 ok(hr == S_OK, "got %08x\n", hr);
1456 ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
1457 ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
1458 ITypeInfo_Release(pTI_p);
1459 if(use_midl_tlb) {
1460 hr = ITypeInfo_GetFuncDesc(pTI, 6, &pFD);
1461 ok(hr == S_OK, "hr %08x\n", hr);
1462 ok(pFD->memid == 0x1234, "memid %08x\n", pFD->memid);
1463 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1464 }
1465 ITypeInfo_Release(pTI);
1466
1467 /* ItestIF7 is dual with inherited ifaces which derive from Dispatch */
1468 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &IID_ItestIF7, &pTI);
1469 ok(hr == S_OK, "hr %08x\n", hr);
1470
1471 hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
1472 ok(hr == S_OK, "hr %08x\n", hr);
1473 ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
1474 ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1475 ok(pTA->wTypeFlags == (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL), "typeflags %x\n", pTA->wTypeFlags);
1476 ok(pTA->cFuncs == 10, "cfuncs %d\n", pTA->cFuncs);
1477 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1478 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1479
1480 hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
1481 ok(hr == S_OK, "hr %08x\n", hr);
1482 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1483 ok(hr == S_OK, "hr %08x\n", hr);
1484 hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
1485 ok(hr == S_OK, "got %08x\n", hr);
1486 ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
1487 ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
1488 ITypeInfo_Release(pTI_p);
1489
1490 hr = ITypeInfo_GetFuncDesc(pTI, 9, &pFD);
1491 ok(hr == S_OK, "hr %08x\n", hr);
1492 ok(pFD->memid == 0x1236, "memid %08x\n", pFD->memid);
1493 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1494 ITypeInfo_Release(pTI);
1495
1496 /* ItestIF10 is a syntax 2 dispinterface which doesn't derive from IUnknown */
1497 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF10, &pTI);
1498 ok(hr == S_OK, "hr %08x\n", hr);
1499
1500 hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
1501 ok(hr == S_OK, "hr %08x\n", hr);
1502 ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
1503 ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1504 ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags);
1505 if(use_midl_tlb) {
1506 ok(pTA->cFuncs == 3, "cfuncs %d\n", pTA->cFuncs);
1507 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1508 }
1509 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1510
1511 if(use_midl_tlb) {
1512 hr = ITypeInfo_GetRefTypeOfImplType(pTI, -1, &href);
1513 ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
1514 hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
1515 ok(hr == S_OK, "hr %08x\n", hr);
1516 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1517 ok(hr == S_OK, "hr %08x\n", hr);
1518 hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
1519 ok(hr == S_OK, "got %08x\n", hr);
1520 ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
1521 ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
1522 ITypeInfo_Release(pTI_p);
1523
1524 /* Should have three methods */
1525 hr = ITypeInfo_GetFuncDesc(pTI, 3, &pFD);
1526 ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
1527 hr = ITypeInfo_GetFuncDesc(pTI, 2, &pFD);
1528 ok(hr == S_OK, "hr %08x\n", hr);
1529 ok(pFD->memid == 0x60010000, "memid %08x\n", pFD->memid);
1530 ok(pFD->oVft == 2 * sizeof(void *), "oVft %d\n", pFD->oVft);
1531 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1532 }
1533 ITypeInfo_Release(pTI);
1534
1535 /* ItestIF11 is a syntax 2 dispinterface which derives from IDispatch */
1536 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &DIID_ItestIF11, &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 ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
1542 ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1543 ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags);
1544 if(use_midl_tlb) {
1545 ok(pTA->cFuncs == 10, "cfuncs %d\n", pTA->cFuncs);
1546 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1547 }
1548 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1549
1550 if(use_midl_tlb) {
1551 hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
1552 ok(hr == S_OK, "hr %08x\n", hr);
1553 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1554 ok(hr == S_OK, "hr %08x\n", hr);
1555 hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
1556 ok(hr == S_OK, "got %08x\n", hr);
1557 ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
1558 ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
1559 ITypeInfo_Release(pTI_p);
1560
1561 /* Should have ten methods */
1562 hr = ITypeInfo_GetFuncDesc(pTI, 10, &pFD);
1563 ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
1564 hr = ITypeInfo_GetFuncDesc(pTI, 9, &pFD);
1565 ok(hr == S_OK, "hr %08x\n", hr);
1566 ok(pFD->memid == 0x1236, "memid %08x\n", pFD->memid);
1567 ok(pFD->oVft == 9 * sizeof(void *), "oVft %d\n", pFD->oVft);
1568
1569 /* first argument to 10th function is an HREFTYPE from the impl type */
1570 ok(pFD->cParams == 1, "cParams %i\n", pFD->cParams);
1571 ok(pFD->lprgelemdescParam[0].tdesc.vt == VT_USERDEFINED,
1572 "vt 0x%x\n", pFD->lprgelemdescParam[0].tdesc.vt);
1573 href = U(pFD->lprgelemdescParam[0].tdesc).hreftype;
1574 ok((href & 0xff000000) == 0x04000000, "href 0x%08x\n", href);
1575 hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
1576 ok(hr == S_OK, "hr %08x\n", hr);
1577 if (SUCCEEDED(hr)) ITypeInfo_Release(pTI_p);
1578 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1579 }
1580 ITypeInfo_Release(pTI);
1581
1582
1583 /* ItestIF2 is an interface which derives from IUnknown */
1584 hr = ITypeLib_GetTypeInfoOfGuid(pTL, &IID_ItestIF2, &pTI);
1585 ok(hr == S_OK, "hr %08x\n", hr);
1586
1587 hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
1588 ok(hr == S_OK, "hr %08x\n", hr);
1589 ok(pTA->typekind == TKIND_INTERFACE, "kind %04x\n", pTA->typekind);
1590 ok(pTA->cbSizeVft == 6 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
1591 ok(pTA->wTypeFlags == 0, "typeflags %x\n", pTA->wTypeFlags);
1592 if(use_midl_tlb) {
1593 ok(pTA->cFuncs == 1, "cfuncs %d\n", pTA->cFuncs);
1594 ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
1595 }
1596 ITypeInfo_ReleaseTypeAttr(pTI, pTA);
1597
1598 if(use_midl_tlb) {
1599 /* Should have one method */
1600 hr = ITypeInfo_GetFuncDesc(pTI, 1, &pFD);
1601 ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr);
1602 hr = ITypeInfo_GetFuncDesc(pTI, 0, &pFD);
1603 ok(hr == S_OK, "hr %08x\n", hr);
1604 ok(pFD->memid == 0x60020000, "memid %08x\n", pFD->memid);
1605 ok(pFD->oVft == 5 * sizeof(void *), "oVft %d\n", pFD->oVft);
1606 ITypeInfo_ReleaseFuncDesc(pTI, pFD);
1607 }
1608 ITypeInfo_Release(pTI);
1609
1610 ITypeLib_Release(pTL);
1611
1612 return;
1613 }
1614
1615 static void test_CreateTypeLib(SYSKIND sys) {
1616 static OLECHAR typelibW[] = {'t','y','p','e','l','i','b',0};
1617 static OLECHAR helpfileW[] = {'C',':','\\','b','o','g','u','s','.','h','l','p',0};
1618 static OLECHAR interface1W[] = {'i','n','t','e','r','f','a','c','e','1',0};
1619 static OLECHAR interface2W[] = {'i','n','t','e','r','f','a','c','e','2',0};
1620 static OLECHAR interface3W[] = {'i','n','t','e','r','f','a','c','e','3',0};
1621 static OLECHAR dualW[] = {'d','u','a','l',0};
1622 static OLECHAR coclassW[] = {'c','o','c','l','a','s','s',0};
1623 static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0x3213,0};
1624 static const WCHAR defaultQW[] = {'d','e','f','a','u','l','t','?',0};
1625 static OLECHAR func1W[] = {'f','u','n','c','1',0};
1626 static OLECHAR func2W[] = {'f','u','n','c','2',0};
1627 static OLECHAR prop1W[] = {'P','r','o','p','1',0};
1628 static OLECHAR param1W[] = {'p','a','r','a','m','1',0};
1629 static OLECHAR param2W[] = {'p','a','r','a','m','2',0};
1630 static OLECHAR asdfW[] = {'A','s','d','f',0};
1631 static OLECHAR aliasW[] = {'a','l','i','a','s',0};
1632 static OLECHAR invokeW[] = {'I','n','v','o','k','e',0};
1633 static OLECHAR *names1[] = {func1W, param1W, param2W};
1634 static OLECHAR *names2[] = {func2W, param1W, param2W};
1635 static OLECHAR *propname[] = {prop1W, param1W};
1636 static const GUID custguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x70}};
1637 static const GUID bogusguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x71}};
1638 static const GUID interfaceguid = {0x3b9ff02f,0x9675,0x4861,{0xb7,0x81,0xce,0xae,0xa4,0x78,0x2a,0xcc}};
1639 static const GUID interface2guid = {0x3b9ff02f,0x9675,0x4861,{0xb7,0x81,0xce,0xae,0xa4,0x78,0x2a,0xcd}};
1640
1641 char filename[MAX_PATH];
1642 WCHAR filenameW[MAX_PATH];
1643 ICreateTypeLib2 *createtl;
1644 ICreateTypeInfo *createti;
1645 ICreateTypeInfo2 *createti2;
1646 ITypeLib *tl, *stdole;
1647 ITypeInfo *interface1, *interface2, *dual, *unknown, *dispatch, *ti;
1648 ITypeInfo *tinfos[2];
1649 ITypeInfo2 *ti2;
1650 ITypeComp *tcomp;
1651 MEMBERID memids[2];
1652 FUNCDESC funcdesc, *pfuncdesc;
1653 ELEMDESC elemdesc[5], *edesc;
1654 PARAMDESCEX paramdescex;
1655 TYPEDESC typedesc1, typedesc2;
1656 TYPEATTR *typeattr;
1657 TLIBATTR *libattr;
1658 HREFTYPE hreftype;
1659 BSTR name, docstring, helpfile, names[3];
1660 DWORD helpcontext, ptr_size, alignment;
1661 int impltypeflags;
1662 unsigned int cnames;
1663 USHORT found;
1664 VARIANT cust_data;
1665 HRESULT hres;
1666 TYPEKIND kind;
1667 DESCKIND desckind;
1668 BINDPTR bindptr;
1669
1670 switch(sys){
1671 case SYS_WIN32:
1672 trace("testing SYS_WIN32\n");
1673 ptr_size = 4;
1674 alignment = sizeof(void*);
1675 break;
1676 case SYS_WIN64:
1677 trace("testing SYS_WIN64\n");
1678 ptr_size = 8;
1679 alignment = 4;
1680 break;
1681 default:
1682 return;
1683 }
1684
1685 trace("CreateTypeLib tests\n");
1686
1687 hres = LoadTypeLib(wszStdOle2, &stdole);
1688 ok(hres == S_OK, "got %08x\n", hres);
1689
1690 hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IUnknown, &unknown);
1691 ok(hres == S_OK, "got %08x\n", hres);
1692
1693 hres = ITypeInfo_GetTypeAttr(unknown, &typeattr);
1694 ok(hres == S_OK, "got %08x\n", hres);
1695 ok(typeattr->cbSizeVft == 3 * sizeof(void*), "Got wrong cbSizeVft: %u\n", typeattr->cbSizeVft);
1696 ITypeInfo_ReleaseTypeAttr(unknown, typeattr);
1697
1698 hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &dispatch);
1699 ok(hres == S_OK, "got %08x\n", hres);
1700
1701 GetTempFileNameA(".", "tlb", 0, filename);
1702 MultiByteToWideChar(CP_ACP, 0, filename, -1, filenameW, MAX_PATH);
1703
1704 hres = CreateTypeLib2(sys, filenameW, &createtl);
1705 ok(hres == S_OK, "got %08x\n", hres);
1706
1707 hres = ICreateTypeLib2_QueryInterface(createtl, &IID_ITypeLib, (void**)&tl);
1708 ok(hres == S_OK, "got %08x\n", hres);
1709
1710 hres = ITypeLib_GetTypeInfo(tl, 0, NULL);
1711 ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
1712
1713 hres = ITypeLib_GetTypeInfoType(tl, 0, &kind);
1714 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got 0x%08x\n", hres);
1715
1716 hres = ITypeLib_GetTypeInfoType(tl, 0, NULL);
1717 ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
1718
1719 hres = ITypeLib_GetTypeInfoType(tl, 0, NULL);
1720 ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
1721
1722 hres = ITypeLib_GetLibAttr(tl, NULL);
1723 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1724
1725 hres = ITypeLib_GetLibAttr(tl, &libattr);
1726 ok(hres == S_OK, "got %08x\n", hres);
1727
1728 ok(libattr->syskind == sys, "syskind = %d\n", libattr->syskind);
1729 ok(libattr->wMajorVerNum == 0, "wMajorVer = %d\n", libattr->wMajorVerNum);
1730 ok(libattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", libattr->wMinorVerNum);
1731 ok(libattr->wLibFlags == 0, "wLibFlags = %d\n", libattr->wLibFlags);
1732
1733 ITypeLib_ReleaseTLibAttr(tl, libattr);
1734
1735 name = (BSTR)0xdeadbeef;
1736 hres = ITypeLib_GetDocumentation(tl, -1, &name, &docstring, &helpcontext, &helpfile);
1737 ok(hres == S_OK, "got %08x\n", hres);
1738 ok(name == NULL, "name != NULL\n");
1739 ok(docstring == NULL, "docstring != NULL\n");
1740 ok(helpcontext == 0, "helpcontext != 0\n");
1741 ok(helpfile == NULL, "helpfile != NULL\n");
1742
1743 hres = ITypeLib_GetDocumentation(tl, 0, &name, NULL, NULL, NULL);
1744 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
1745
1746 hres = ICreateTypeLib2_SetName(createtl, typelibW);
1747 ok(hres == S_OK, "got %08x\n", hres);
1748
1749 hres = ICreateTypeLib2_SetHelpFileName(createtl, helpfileW);
1750 ok(hres == S_OK, "got %08x\n", hres);
1751
1752 hres = ITypeLib_GetDocumentation(tl, -1, NULL, NULL, NULL, NULL);
1753 ok(hres == S_OK, "got %08x\n", hres);
1754
1755 hres = ITypeLib_GetDocumentation(tl, -1, &name, NULL, NULL, &helpfile);
1756 ok(hres == S_OK, "got %08x\n", hres);
1757 ok(!memcmp(name, typelibW, sizeof(typelibW)), "name = %s\n", wine_dbgstr_w(name));
1758 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "helpfile = %s\n", wine_dbgstr_w(helpfile));
1759
1760 SysFreeString(name);
1761 SysFreeString(helpfile);
1762
1763 /* invalid parameters */
1764 hres = ICreateTypeLib2_CreateTypeInfo(createtl, NULL, TKIND_INTERFACE, &createti);
1765 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1766
1767 hres = ICreateTypeLib2_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, NULL);
1768 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1769
1770 hres = ICreateTypeLib2_CreateTypeInfo(createtl, NULL, TKIND_INTERFACE, NULL);
1771 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1772
1773 hres = ICreateTypeLib2_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti);
1774 ok(hres == S_OK, "got %08x\n", hres);
1775
1776 hres = ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo, (void**)&interface1);
1777 ok(hres == S_OK, "got %08x\n", hres);
1778
1779 hres = ITypeLib_GetDocumentation(tl, 0, &name, NULL, NULL, NULL);
1780 ok(hres == S_OK, "got %08x\n", hres);
1781 ok(!memcmp(name, interface1W, sizeof(interface1W)), "name = %s\n", wine_dbgstr_w(name));
1782
1783 SysFreeString(name);
1784
1785 ITypeLib_Release(tl);
1786
1787 name = (BSTR)0xdeadbeef;
1788 helpfile = (BSTR)0xdeadbeef;
1789 hres = ITypeInfo_GetDocumentation(interface1, -1, &name, &docstring, &helpcontext, &helpfile);
1790 ok(hres == S_OK, "got %08x\n", hres);
1791 ok(!memcmp(name, interface1W, sizeof(interface1W)), "name = %s\n", wine_dbgstr_w(name));
1792 ok(docstring == NULL, "docstring != NULL\n");
1793 ok(helpcontext == 0, "helpcontext != 0\n");
1794 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "helpfile = %s\n", wine_dbgstr_w(helpfile));
1795
1796 SysFreeString(name);
1797 SysFreeString(helpfile);
1798
1799 hres = ITypeInfo_GetDocumentation(interface1, 0, &name, NULL, NULL, NULL);
1800 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
1801
1802 hres = ITypeInfo_GetRefTypeInfo(interface1, 0, NULL);
1803 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1804
1805
1806 hres = ICreateTypeInfo_LayOut(createti);
1807 ok(hres == S_OK, "got %08x\n", hres);
1808
1809 hres = ICreateTypeInfo_SetGuid(createti, &interfaceguid);
1810 ok(hres == S_OK, "got %08x\n", hres);
1811
1812 hres = ICreateTypeInfo_AddRefTypeInfo(createti, NULL, &hreftype);
1813 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1814
1815 hres = ICreateTypeInfo_AddRefTypeInfo(createti, unknown, NULL);
1816 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1817
1818 hres = ICreateTypeInfo_AddRefTypeInfo(createti, unknown, &hreftype);
1819 ok(hres == S_OK, "got %08x\n", hres);
1820 if(hres != S_OK) {
1821 skip("Skipping some tests\n");
1822 return;
1823 }
1824
1825 hres = ICreateTypeInfo_AddImplType(createti, 1, hreftype);
1826 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
1827
1828 hres = ICreateTypeInfo_AddImplType(createti, 0, hreftype);
1829 ok(hres == S_OK, "got %08x\n", hres);
1830
1831 hres = ITypeInfo_GetRefTypeOfImplType(interface1, 0, &hreftype);
1832 ok(hres == S_OK, "got %08x\n", hres);
1833 ok(hreftype == 3, "hreftype = %d\n", hreftype);
1834
1835 hres = ITypeInfo_GetRefTypeInfo(interface1, hreftype, &ti);
1836 ok(hres == S_OK, "got %08x\n", hres);
1837
1838 hres = ITypeInfo_GetTypeAttr(ti, &typeattr);
1839 ok(hres == S_OK, "got %08x\n", hres);
1840 ok(typeattr->cbSizeVft == 3 * ptr_size || broken(sys == SYS_WIN32 && typeattr->cbSizeVft == 24) /* xp64 */,
1841 "retrieved IUnknown gave wrong cbSizeVft: %u\n", typeattr->cbSizeVft);
1842 ITypeInfo_ReleaseTypeAttr(ti, typeattr);
1843
1844 ITypeInfo_Release(ti);
1845
1846 hres = ITypeInfo_GetRefTypeOfImplType(interface1, -1, &hreftype);
1847 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
1848
1849 ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo2, (void**)&ti2);
1850
1851 memset(&funcdesc, 0, sizeof(FUNCDESC));
1852 funcdesc.funckind = FUNC_PUREVIRTUAL;
1853 funcdesc.invkind = INVOKE_PROPERTYGET;
1854 funcdesc.callconv = CC_STDCALL;
1855 funcdesc.elemdescFunc.tdesc.vt = VT_BSTR;
1856 U(funcdesc.elemdescFunc).idldesc.wIDLFlags = IDLFLAG_NONE;
1857
1858 hres = ICreateTypeInfo_AddFuncDesc(createti, 0, NULL);
1859 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1860
1861 hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
1862 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
1863
1864 hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
1865 ok(hres == S_OK, "got %08x\n", hres);
1866
1867 hres = ITypeInfo2_GetFuncDesc(ti2, 0, NULL);
1868 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1869
1870 hres = ITypeInfo2_GetFuncDesc(ti2, 1, &pfuncdesc);
1871 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
1872
1873 hres = ITypeInfo2_GetFuncDesc(ti2, 0, &pfuncdesc);
1874 ok(hres == S_OK, "got %08x\n", hres);
1875
1876 ok(pfuncdesc->memid == 0, "got %x\n", pfuncdesc->memid);
1877 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
1878 ok(pfuncdesc->lprgelemdescParam == NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
1879 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
1880 ok(pfuncdesc->invkind == INVOKE_PROPERTYGET, "got 0x%x\n", pfuncdesc->invkind);
1881 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
1882 ok(pfuncdesc->cParams == 0, "got %d\n", pfuncdesc->cParams);
1883 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
1884 ok(pfuncdesc->oVft == 3 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 24) /* xp64 */,
1885 "got %d\n", pfuncdesc->oVft);
1886 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
1887 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_BSTR, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
1888 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
1889
1890 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
1891
1892 hres = ICreateTypeInfo_SetFuncHelpContext(createti, 0, 0xabcdefab);
1893 ok(hres == S_OK, "got %08x\n", hres);
1894
1895 funcdesc.invkind = INVOKE_PROPERTYPUT;
1896 hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
1897 ok(hres == TYPE_E_INCONSISTENTPROPFUNCS, "got %08x\n", hres);
1898
1899 funcdesc.invkind = INVOKE_PROPERTYPUTREF;
1900 hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
1901 ok(hres == TYPE_E_INCONSISTENTPROPFUNCS, "got %08x\n", hres);
1902
1903 elemdesc[0].tdesc.vt = VT_BSTR;
1904 U(elemdesc[0]).idldesc.dwReserved = 0;
1905 U(elemdesc[0]).idldesc.wIDLFlags = IDLFLAG_FIN;
1906
1907 funcdesc.lprgelemdescParam = elemdesc;
1908 funcdesc.invkind = INVOKE_PROPERTYPUT;
1909 funcdesc.cParams = 1;
1910 funcdesc.elemdescFunc.tdesc.vt = VT_VOID;
1911
1912 hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
1913 ok(hres == S_OK, "got %08x\n", hres);
1914
1915 hres = ICreateTypeInfo_SetFuncHelpContext(createti, 1, 0xabcdefab);
1916 ok(hres == S_OK, "got %08x\n", hres);
1917
1918 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 0, propname, 0);
1919 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
1920
1921 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 0, NULL, 1);
1922 ok(hres == E_INVALIDARG, "got %08x\n", hres);
1923
1924 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 0, propname, 1);
1925 ok(hres == S_OK, "got %08x\n", hres);
1926
1927 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 1, propname, 1);
1928 ok(hres == S_OK, "got %08x\n", hres);
1929
1930 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 1, propname, 2);
1931 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
1932
1933 hres = ITypeInfo2_GetFuncDesc(ti2, 1, &pfuncdesc);
1934 ok(hres == S_OK, "got %08x\n", hres);
1935
1936 ok(pfuncdesc->memid == 0, "got %x\n", pfuncdesc->memid);
1937 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
1938 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
1939 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
1940 ok(pfuncdesc->invkind == INVOKE_PROPERTYPUT, "got 0x%x\n", pfuncdesc->invkind);
1941 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
1942 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
1943 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
1944 ok(pfuncdesc->oVft == 4 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 28) /* xp64 */,
1945 "got %d\n", pfuncdesc->oVft);
1946 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
1947 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
1948 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
1949
1950 edesc = pfuncdesc->lprgelemdescParam;
1951 ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
1952 ok(U(*edesc).idldesc.wIDLFlags == IDLFLAG_FIN, "got: %x\n", U(*edesc).idldesc.wIDLFlags);
1953
1954 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
1955
1956
1957 funcdesc.invkind = INVOKE_PROPERTYPUTREF;
1958 hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
1959 ok(hres == S_OK, "got %08x\n", hres);
1960
1961 hres = ICreateTypeInfo_SetFuncHelpContext(createti, 0, 0xabcdefab);
1962 ok(hres == S_OK, "got %08x\n", hres);
1963
1964 hres = ICreateTypeInfo_SetFuncHelpContext(createti, 0, 0x201);
1965 ok(hres == S_OK, "got %08x\n", hres);
1966
1967 funcdesc.memid = 1;
1968 funcdesc.lprgelemdescParam = NULL;
1969 funcdesc.invkind = INVOKE_FUNC;
1970 funcdesc.cParams = 0;
1971 hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
1972 ok(hres == S_OK, "got %08x\n", hres);
1973
1974 hres = ITypeInfo2_GetFuncDesc(ti2, 1, &pfuncdesc);
1975 ok(hres == S_OK, "got %08x\n", hres);
1976
1977 ok(pfuncdesc->memid == 1, "got %d\n", pfuncdesc->memid);
1978 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
1979 ok(pfuncdesc->lprgelemdescParam == NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
1980 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
1981 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
1982 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
1983 ok(pfuncdesc->cParams == 0, "got %d\n", pfuncdesc->cParams);
1984 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
1985 ok(pfuncdesc->oVft == 4 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 28), /* xp64 */
1986 "got %d\n", pfuncdesc->oVft);
1987 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
1988 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
1989 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
1990
1991 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
1992
1993 funcdesc.memid = MEMBERID_NIL;
1994 hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
1995 ok(hres == S_OK, "got %08x\n", hres);
1996
1997 elemdesc[0].tdesc.vt = VT_PTR;
1998 U(elemdesc[0].tdesc).lptdesc = &typedesc1;
1999 typedesc1.vt = VT_BSTR;
2000 funcdesc.cParams = 1;
2001 funcdesc.lprgelemdescParam = elemdesc;
2002 hres = ICreateTypeInfo_AddFuncDesc(createti, 4, &funcdesc);
2003 ok(hres == S_OK, "got %08x\n", hres);
2004
2005 hres = ITypeInfo2_GetFuncDesc(ti2, 4, &pfuncdesc);
2006 ok(hres == S_OK, "got %08x\n", hres);
2007
2008 ok(pfuncdesc->memid == 0x60010004, "got %x\n", pfuncdesc->memid);
2009 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2010 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2011 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2012 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2013 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2014 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
2015 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2016 ok(pfuncdesc->oVft == 7 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 40) /* xp64 */,
2017 "got %d\n", pfuncdesc->oVft);
2018 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2019 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2020 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2021
2022 edesc = pfuncdesc->lprgelemdescParam;
2023 ok(edesc->tdesc.vt == VT_PTR, "got: %d\n", edesc->tdesc.vt);
2024 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FIN, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2025 ok(U(*edesc).paramdesc.pparamdescex == NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2026 ok(U(edesc->tdesc).lptdesc != NULL, "got: %p\n", U(edesc->tdesc).lptdesc);
2027 ok(U(edesc->tdesc).lptdesc->vt == VT_BSTR, "got: %d\n", U(edesc->tdesc).lptdesc->vt);
2028
2029 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2030
2031 U(elemdesc[0].tdesc).lptdesc = &typedesc2;
2032 typedesc2.vt = VT_PTR;
2033 U(typedesc2).lptdesc = &typedesc1;
2034 hres = ICreateTypeInfo_AddFuncDesc(createti, 4, &funcdesc);
2035 ok(hres == S_OK, "got %08x\n", hres);
2036
2037 hres = ITypeInfo2_GetFuncDesc(ti2, 4, &pfuncdesc);
2038 ok(hres == S_OK, "got %08x\n", hres);
2039
2040 ok(pfuncdesc->memid == 0x60010007, "got %x\n", pfuncdesc->memid);
2041 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2042 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2043 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2044 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2045 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2046 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
2047 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2048 ok(pfuncdesc->oVft == 7 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 40) /* xp64 */,
2049 "got %d\n", pfuncdesc->oVft);
2050 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2051 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2052 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2053
2054 edesc = pfuncdesc->lprgelemdescParam;
2055 ok(edesc->tdesc.vt == VT_PTR, "got: %d\n", edesc->tdesc.vt);
2056 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FIN, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2057 ok(U(*edesc).paramdesc.pparamdescex == NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2058 ok(U(edesc->tdesc).lptdesc != NULL, "got: %p\n", U(edesc->tdesc).lptdesc);
2059 ok(U(edesc->tdesc).lptdesc->vt == VT_PTR, "got: %d\n", U(edesc->tdesc).lptdesc->vt);
2060 ok(U(*U(edesc->tdesc).lptdesc).lptdesc != NULL, "got: %p\n", U(*U(edesc->tdesc).lptdesc).lptdesc);
2061 ok(U(*U(edesc->tdesc).lptdesc).lptdesc->vt == VT_BSTR, "got: %d\n", U(*U(edesc->tdesc).lptdesc).lptdesc->vt);
2062
2063 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2064
2065 elemdesc[0].tdesc.vt = VT_INT;
2066 U(elemdesc[0]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT;
2067 U(elemdesc[0]).paramdesc.pparamdescex = &paramdescex;
2068 V_VT(&paramdescex.varDefaultValue) = VT_INT;
2069 V_INT(&paramdescex.varDefaultValue) = 0x123;
2070 hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
2071 ok(hres == S_OK, "got %08x\n", hres);
2072
2073 hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc);
2074 ok(hres == S_OK, "got %08x\n", hres);
2075
2076 ok(pfuncdesc->memid == 0x60010003, "got %x\n", pfuncdesc->memid);
2077 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2078 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2079 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2080 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2081 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2082 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
2083 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2084 ok(pfuncdesc->oVft == 6 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 36) /* xp64 */,
2085 "got %d\n", pfuncdesc->oVft);
2086 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2087 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2088 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2089
2090 edesc = pfuncdesc->lprgelemdescParam;
2091 ok(edesc->tdesc.vt == VT_INT, "got: %d\n", edesc->tdesc.vt);
2092 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2093 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2094 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
2095 U(*edesc).paramdesc.pparamdescex->cBytes);
2096 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_I4, "got: %d\n",
2097 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2098 ok(V_I4(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0x123, "got: 0x%x\n",
2099 V_I4(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2100
2101 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2102
2103 U(elemdesc[0]).idldesc.dwReserved = 0;
2104 U(elemdesc[0]).idldesc.wIDLFlags = IDLFLAG_FIN;
2105 elemdesc[1].tdesc.vt = VT_UI2;
2106 U(elemdesc[1]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT;
2107 U(elemdesc[1]).paramdesc.pparamdescex = &paramdescex;
2108 V_VT(&paramdescex.varDefaultValue) = VT_UI2;
2109 V_UI2(&paramdescex.varDefaultValue) = 0xffff;
2110 funcdesc.cParams = 2;
2111 hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
2112 ok(hres == S_OK, "got %08x\n", hres);
2113
2114 hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc);
2115 ok(hres == S_OK, "got %08x\n", hres);
2116
2117 ok(pfuncdesc->memid == 0x60010009, "got %x\n", pfuncdesc->memid);
2118 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2119 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2120 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2121 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2122 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2123 ok(pfuncdesc->cParams == 2, "got %d\n", pfuncdesc->cParams);
2124 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2125 ok(pfuncdesc->oVft == 6 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 36) /* xp64 */,
2126 "got %d\n", pfuncdesc->oVft);
2127 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2128 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2129 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2130
2131 edesc = pfuncdesc->lprgelemdescParam;
2132 ok(edesc->tdesc.vt == VT_INT, "got: %d\n", edesc->tdesc.vt);
2133 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FIN, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2134 ok(U(*edesc).paramdesc.pparamdescex == NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2135
2136 edesc = pfuncdesc->lprgelemdescParam + 1;
2137 ok(edesc->tdesc.vt == VT_UI2, "got: %d\n", edesc->tdesc.vt);
2138 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2139 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2140 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
2141 U(*edesc).paramdesc.pparamdescex->cBytes);
2142 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_UI2, "got: %d\n",
2143 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2144 ok(V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0xFFFF, "got: 0x%x\n",
2145 V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2146
2147 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2148
2149 U(elemdesc[0]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT;
2150 U(elemdesc[0]).paramdesc.pparamdescex = &paramdescex;
2151 elemdesc[1].tdesc.vt = VT_INT;
2152 V_VT(&paramdescex.varDefaultValue) = VT_INT;
2153 V_INT(&paramdescex.varDefaultValue) = 0xffffffff;
2154 hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
2155 ok(hres == S_OK, "got %08x\n", hres);
2156
2157 elemdesc[0].tdesc.vt = VT_BSTR;
2158 elemdesc[1].tdesc.vt = VT_BSTR;
2159 V_VT(&paramdescex.varDefaultValue) = VT_BSTR;
2160 V_BSTR(&paramdescex.varDefaultValue) = SysAllocString(defaultW);
2161 hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
2162 ok(hres == S_OK, "got %08x\n", hres);
2163 SysFreeString(V_BSTR(&paramdescex.varDefaultValue));
2164
2165 hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc);
2166 ok(hres == S_OK, "got %08x\n", hres);
2167
2168 ok(pfuncdesc->memid == 0x6001000b, "got %x\n", pfuncdesc->memid);
2169 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2170 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2171 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2172 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2173 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2174 ok(pfuncdesc->cParams == 2, "got %d\n", pfuncdesc->cParams);
2175 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2176 ok(pfuncdesc->oVft == 6 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 36) /* xp64 */,
2177 "got %d\n", pfuncdesc->oVft);
2178 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2179 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2180 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2181
2182 edesc = pfuncdesc->lprgelemdescParam;
2183 ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
2184 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2185 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2186 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
2187 U(*edesc).paramdesc.pparamdescex->cBytes);
2188 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n",
2189 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2190 ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW),
2191 "got: %s\n",
2192 wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)));
2193
2194 edesc = pfuncdesc->lprgelemdescParam + 1;
2195 ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
2196 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2197 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2198 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
2199 U(*edesc).paramdesc.pparamdescex->cBytes);
2200 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n",
2201 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2202 ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW),
2203 "got: %s\n",
2204 wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)));
2205
2206 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2207
2208 elemdesc[0].tdesc.vt = VT_USERDEFINED;
2209 U(elemdesc[0].tdesc).hreftype = hreftype;
2210 U(elemdesc[0]).paramdesc.pparamdescex = &paramdescex;
2211 U(elemdesc[0]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT;
2212 V_VT(&paramdescex.varDefaultValue) = VT_INT;
2213 V_INT(&paramdescex.varDefaultValue) = 0x789;
2214
2215 funcdesc.lprgelemdescParam = elemdesc;
2216 funcdesc.invkind = INVOKE_FUNC;
2217 funcdesc.cParams = 1;
2218 funcdesc.elemdescFunc.tdesc.vt = VT_VOID;
2219
2220 hres = ICreateTypeInfo_AddFuncDesc(createti, 5, &funcdesc);
2221 ok(hres == S_OK, "got %08x\n", hres);
2222
2223 hres = ITypeInfo2_GetFuncDesc(ti2, 5, &pfuncdesc);
2224 ok(hres == S_OK, "got %08x\n", hres);
2225
2226 ok(pfuncdesc->memid == 0x60010005, "got %x\n", pfuncdesc->memid);
2227 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2228 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2229 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2230 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2231 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2232 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
2233 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2234 ok(pfuncdesc->oVft == 8 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 44), /* xp64 */
2235 "got %d\n", pfuncdesc->oVft);
2236 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2237 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2238 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2239
2240 edesc = pfuncdesc->lprgelemdescParam;
2241 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2242 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT,
2243 "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2244 ok(edesc->tdesc.vt == VT_USERDEFINED, "got: %d\n", edesc->tdesc.vt);
2245 ok(U(edesc->tdesc).hreftype == hreftype, "got: 0x%x\n", U(edesc->tdesc).hreftype);
2246 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_INT, "got: %d\n",
2247 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2248 ok(V_INT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0x789, "got: %d\n",
2249 V_INT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2250
2251 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2252
2253 elemdesc[0].tdesc.vt = VT_VARIANT;
2254 U(elemdesc[0]).paramdesc.pparamdescex = &paramdescex;
2255 U(elemdesc[0]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT;
2256 V_VT(&paramdescex.varDefaultValue) = VT_INT;
2257 V_INT(&paramdescex.varDefaultValue) = 3;
2258
2259 funcdesc.lprgelemdescParam = elemdesc;
2260 funcdesc.invkind = INVOKE_FUNC;
2261 funcdesc.cParams = 1;
2262 funcdesc.elemdescFunc.tdesc.vt = VT_VARIANT;
2263
2264 hres = ICreateTypeInfo_AddFuncDesc(createti, 6, &funcdesc);
2265 ok(hres == S_OK, "got %08x\n", hres);
2266
2267 hres = ITypeInfo2_GetFuncDesc(ti2, 6, &pfuncdesc);
2268 ok(hres == S_OK, "got %08x\n", hres);
2269
2270 ok(pfuncdesc->memid == 0x60010006, "got %x\n", pfuncdesc->memid);
2271 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2272 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2273 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2274 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2275 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2276 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
2277 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2278 ok(pfuncdesc->oVft == 9 * ptr_size || broken(sys == SYS_WIN32 && pfuncdesc->oVft == 48), /* xp64 */
2279 "got %d\n", pfuncdesc->oVft);
2280 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2281 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VARIANT, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2282 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2283
2284 edesc = pfuncdesc->lprgelemdescParam;
2285 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2286 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT,
2287 "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2288 ok(edesc->tdesc.vt == VT_VARIANT, "got: %d\n", edesc->tdesc.vt);
2289 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_INT, "got: %d\n",
2290 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2291 ok(V_INT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 3, "got: %d\n",
2292 V_INT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2293
2294 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2295
2296 hres = ITypeInfo_GetDocumentation(interface1, 0, &name, &docstring, &helpcontext, &helpfile);
2297 ok(hres == S_OK, "got %08x\n", hres);
2298 ok(name == NULL, "name != NULL\n");
2299 ok(docstring == NULL, "docstring != NULL\n");
2300 ok(helpcontext == 0x201, "helpcontext != 0x201\n");
2301 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "helpfile = %s\n", wine_dbgstr_w(helpfile));
2302
2303 SysFreeString(helpfile);
2304
2305 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 1000, NULL, 1);
2306 ok(hres == E_INVALIDARG, "got %08x\n", hres);
2307
2308 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 1000, names1, 1);
2309 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
2310
2311 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 0, names1, 2);
2312 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
2313
2314 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 0, names2, 1);
2315 ok(hres == S_OK, "got %08x\n", hres);
2316
2317 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 0, names1, 1);
2318 ok(hres == S_OK, "got %08x\n", hres);
2319
2320 hres = ITypeInfo_GetDocumentation(interface1, 0, &name, NULL, NULL, NULL);
2321 ok(hres == S_OK, "got %08x\n", hres);
2322 ok(!memcmp(name, func1W, sizeof(func1W)), "name = %s\n", wine_dbgstr_w(name));
2323
2324 SysFreeString(name);
2325
2326 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 3, names2, 3);
2327 ok(hres == S_OK, "got %08x\n", hres);
2328
2329 hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 3, names1, 3);
2330 ok(hres == TYPE_E_AMBIGUOUSNAME, "got %08x\n", hres);
2331
2332 ITypeInfo2_Release(ti2);
2333 ICreateTypeInfo_Release(createti);
2334
2335 hres = ICreateTypeLib2_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti);
2336 ok(hres == TYPE_E_NAMECONFLICT, "got %08x\n", hres);
2337
2338 hres = ICreateTypeLib2_CreateTypeInfo(createtl, interface2W, TKIND_INTERFACE, &createti);
2339 ok(hres == S_OK, "got %08x\n", hres);
2340
2341 hres = ICreateTypeInfo_SetGuid(createti, &interface2guid);
2342 ok(hres == S_OK, "got %08x\n", hres);
2343
2344 hres = ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo, (void**)&interface2);
2345 ok(hres == S_OK, "got %08x\n", hres);
2346
2347 hres = ITypeInfo_GetRefTypeOfImplType(interface2, 0, &hreftype);
2348 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
2349
2350 hres = ICreateTypeInfo_AddRefTypeInfo(createti, interface1, &hreftype);
2351 ok(hres == S_OK, "got %08x\n", hres);
2352
2353 hres = ITypeInfo_GetRefTypeInfo(interface2, 0, &ti);
2354 ok(hres == S_OK, "got %08x\n", hres);
2355 ok(ti == interface1, "Received and added interfaces are different\n");
2356
2357 ITypeInfo_Release(ti);
2358
2359 hres = ICreateTypeInfo_AddImplType(createti, 0, hreftype);
2360 ok(hres == S_OK, "got %08x\n", hres);
2361
2362 hres = ITypeInfo_GetRefTypeOfImplType(interface2, 0, &hreftype);
2363 ok(hres == S_OK, "got %08x\n", hres);
2364 ok(hreftype == 2, "hreftype = %d\n", hreftype);
2365
2366 hres = ITypeInfo_GetRefTypeOfImplType(interface2, -1, &hreftype);
2367 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
2368
2369 hres = ICreateTypeInfo_SetImplTypeFlags(createti, 0, IMPLTYPEFLAG_FDEFAULT);
2370 ok(hres == TYPE_E_BADMODULEKIND, "got %08x\n", hres);
2371
2372 hres = ITypeInfo_GetImplTypeFlags(interface2, 0, &impltypeflags);
2373 ok(hres == S_OK, "got %08x\n", hres);
2374 ok(impltypeflags == 0, "impltypeflags = %x\n", impltypeflags);
2375
2376 hres = ITypeInfo_GetImplTypeFlags(interface2, 1, &impltypeflags);
2377 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
2378
2379 funcdesc.elemdescFunc.tdesc.vt = VT_VOID;
2380 funcdesc.oVft = 0xaaac;
2381 hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
2382 if(sys == SYS_WIN64){
2383 ok(hres == E_INVALIDARG, "got %08x\n", hres);
2384 funcdesc.oVft = 0xaab0;
2385 hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
2386 }
2387 ok(hres == S_OK, "got %08x\n", hres);
2388 funcdesc.oVft = 0xaaa8;
2389 hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
2390 ok(hres == S_OK, "got %08x\n", hres);
2391
2392 hres = ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo, (void**)&ti2);
2393 ok(hres == S_OK, "got %08x\n", hres);
2394
2395 hres = ITypeInfo2_GetFuncDesc(ti2, 0, &pfuncdesc);
2396 ok(hres == S_OK, "got %08x\n", hres);
2397
2398 ok(pfuncdesc->memid == 0x60020000, "got %x\n", pfuncdesc->memid);
2399 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2400 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2401 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2402 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2403 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2404 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
2405 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2406 ok(pfuncdesc->oVft == (short)0xaaa8, "got %d\n", pfuncdesc->oVft);
2407 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2408 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2409 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2410
2411 ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
2412 ITypeInfo2_Release(ti2);
2413
2414 funcdesc.oVft = 0;
2415
2416 ICreateTypeInfo_Release(createti);
2417
2418 VariantInit(&cust_data);
2419
2420 hres = ICreateTypeLib2_CreateTypeInfo(createtl, interface3W, TKIND_INTERFACE, &createti);
2421 ok(hres == S_OK, "got %08x\n", hres);
2422
2423 hres = ICreateTypeInfo_QueryInterface(createti, &IID_ICreateTypeInfo2, (void**)&createti2);
2424 ok(hres == S_OK, "got %08x\n", hres);
2425
2426 hres = ICreateTypeInfo2_QueryInterface(createti2, &IID_ITypeInfo2, (void**)&ti2);
2427 ok(hres == S_OK, "got %08x\n", hres);
2428
2429 hres = ITypeInfo2_GetCustData(ti2, NULL, NULL);
2430 ok(hres == E_INVALIDARG, "got %08x\n", hres);
2431
2432 hres = ITypeInfo2_GetCustData(ti2, &custguid, NULL);
2433 ok(hres == E_INVALIDARG, "got %08x\n", hres);
2434
2435 hres = ITypeInfo2_GetCustData(ti2, &custguid, &cust_data);
2436 ok(hres == S_OK, "got %08x\n", hres);
2437
2438 hres = ICreateTypeInfo2_SetCustData(createti2, NULL, NULL);
2439 ok(hres == E_INVALIDARG, "got %08x\n", hres);
2440
2441 hres = ICreateTypeInfo2_SetCustData(createti2, &custguid, NULL);
2442 ok(hres == E_INVALIDARG, "got %08x\n", hres);
2443
2444 hres = ICreateTypeInfo2_SetCustData(createti2, &custguid, &cust_data);
2445 ok(hres == DISP_E_BADVARTYPE, "got %08x\n", hres);
2446
2447 V_VT(&cust_data) = VT_UI4;
2448 V_I4(&cust_data) = 0xdeadbeef;
2449
2450 hres = ICreateTypeInfo2_SetCustData(createti2, &custguid, &cust_data);
2451 ok(hres == S_OK, "got %08x\n", hres);
2452
2453 V_I4(&cust_data) = 0;
2454 V_VT(&cust_data) = VT_EMPTY;
2455
2456 hres = ITypeInfo2_GetCustData(ti2, &custguid, &cust_data);
2457 ok(hres == S_OK, "got %08x\n", hres);
2458
2459 ok(V_VT(&cust_data) == VT_UI4, "got %d\n", V_VT(&cust_data));
2460 ok(V_I4(&cust_data) == 0xdeadbeef, "got 0x%08x\n", V_I4(&cust_data));
2461
2462 V_VT(&cust_data) = VT_UI4;
2463 V_I4(&cust_data) = 12345678;
2464
2465 hres = ICreateTypeInfo2_SetCustData(createti2, &custguid, &cust_data);
2466 ok(hres == S_OK, "got %08x\n", hres);
2467
2468 V_I4(&cust_data) = 0;
2469 V_VT(&cust_data) = VT_EMPTY;
2470
2471 hres = ITypeInfo2_GetCustData(ti2, &custguid, &cust_data);
2472 ok(hres == S_OK, "got %08x\n", hres);
2473
2474 ok(V_VT(&cust_data) == VT_UI4, "got %d\n", V_VT(&cust_data));
2475 ok(V_I4(&cust_data) == 12345678, "got 0x%08x\n", V_I4(&cust_data));
2476
2477 V_VT(&cust_data) = VT_BSTR;
2478 V_BSTR(&cust_data) = SysAllocString(asdfW);
2479
2480 hres = ICreateTypeInfo2_SetCustData(createti2, &custguid, &cust_data);
2481 ok(hres == S_OK, "got %08x\n", hres);
2482
2483 SysFreeString(V_BSTR(&cust_data));
2484 V_I4(&cust_data) = 0;
2485 V_VT(&cust_data) = VT_EMPTY;
2486
2487 hres = ITypeInfo2_GetCustData(ti2, &custguid, &cust_data);
2488 ok(hres == S_OK, "got %08x\n", hres);
2489
2490 ok(V_VT(&cust_data) == VT_BSTR, "got %d\n", V_VT(&cust_data));
2491 ok(!lstrcmpW(V_BSTR(&cust_data), asdfW), "got %s\n", wine_dbgstr_w(V_BSTR(&cust_data)));
2492 SysFreeString(V_BSTR(&cust_data));
2493
2494 V_VT(&cust_data) = VT_UI4;
2495 V_UI4(&cust_data) = 17;
2496
2497 hres = ITypeInfo2_GetCustData(ti2, &bogusguid, &cust_data);
2498 ok(hres == S_OK, "got %08x\n", hres);
2499
2500 ok(V_VT(&cust_data) == VT_EMPTY, "got: %d\n", V_VT(&cust_data));
2501
2502 ITypeInfo2_Release(ti2);
2503 ICreateTypeInfo2_Release(createti2);
2504 ICreateTypeInfo_Release(createti);
2505
2506 hres = ICreateTypeLib2_CreateTypeInfo(createtl, coclassW, TKIND_COCLASS, &createti);
2507 ok(hres == S_OK, "got %08x\n", hres);
2508
2509 hres = ICreateTypeInfo_AddRefTypeInfo(createti, interface1, &hreftype);
2510 ok(hres == S_OK, "got %08x\n", hres);
2511
2512 hres = ICreateTypeInfo_AddImplType(createti, 0, hreftype);
2513 ok(hres == S_OK, "got %08x\n", hres);
2514
2515 hres = ICreateTypeInfo_AddImplType(createti, 0, hreftype);
2516 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
2517
2518 hres = ICreateTypeInfo_AddRefTypeInfo(createti, unknown, &hreftype);
2519 ok(hres == S_OK, "got %08x\n", hres);
2520
2521 hres = ICreateTypeInfo_AddImplType(createti, 1, hreftype);
2522 ok(hres == S_OK, "got %08x\n", hres);
2523
2524 hres = ICreateTypeInfo_AddImplType(createti, 1, hreftype);
2525 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
2526
2527 hres = ICreateTypeInfo_AddImplType(createti, 2, hreftype);
2528 ok(hres == S_OK, "got %08x\n", hres);
2529
2530 hres = ICreateTypeInfo_SetImplTypeFlags(createti, 0, IMPLTYPEFLAG_FDEFAULT);
2531 ok(hres == S_OK, "got %08x\n", hres);
2532
2533 hres = ICreateTypeInfo_SetImplTypeFlags(createti, 1, IMPLTYPEFLAG_FRESTRICTED);
2534 ok(hres == S_OK, "got %08x\n", hres);
2535
2536 hres = ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo, (void**)&ti);
2537 ok(hres == S_OK, "got %08x\n", hres);
2538
2539 hres = ITypeInfo_GetImplTypeFlags(ti, 0, NULL);
2540 ok(hres == E_INVALIDARG, "got %08x\n", hres);
2541
2542 hres = ITypeInfo_GetImplTypeFlags(ti, 0, &impltypeflags);
2543 ok(hres == S_OK, "got %08x\n", hres);
2544 ok(impltypeflags == IMPLTYPEFLAG_FDEFAULT, "impltypeflags = %x\n", impltypeflags);
2545
2546 hres = ITypeInfo_GetImplTypeFlags(ti, 1, &impltypeflags);
2547 ok(hres == S_OK, "got %08x\n", hres);
2548 ok(impltypeflags == IMPLTYPEFLAG_FRESTRICTED, "impltypeflags = %x\n", impltypeflags);
2549
2550 hres = ITypeInfo_GetImplTypeFlags(ti, 2, &impltypeflags);
2551 ok(hres == S_OK, "got %08x\n", hres);
2552 ok(impltypeflags == 0, "impltypeflags = %x\n", impltypeflags);
2553
2554 hres = ITypeInfo_GetRefTypeOfImplType(ti, 0, &hreftype);
2555 ok(hres == S_OK, "got %08x\n", hres);
2556 ok(hreftype == 0, "hreftype = %d\n", hreftype);
2557
2558 hres = ITypeInfo_GetRefTypeOfImplType(ti, 1, &hreftype);
2559 ok(hres == S_OK, "got %08x\n", hres);
2560 ok(hreftype == 1, "hreftype = %d\n", hreftype);
2561
2562 hres = ITypeInfo_GetRefTypeOfImplType(ti, 2, &hreftype);
2563 ok(hres == S_OK, "got %08x\n", hres);
2564 ok(hreftype == 1, "hreftype = %d\n", hreftype);
2565
2566 hres = ITypeInfo_GetRefTypeOfImplType(ti, -1, &hreftype);
2567 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
2568
2569 ITypeInfo_Release(ti);
2570
2571 ICreateTypeInfo_Release(createti);
2572
2573 hres = ICreateTypeLib2_CreateTypeInfo(createtl, dualW, TKIND_INTERFACE, &createti);
2574 ok(hres == S_OK, "got %08x\n", hres);
2575
2576 hres = ICreateTypeInfo_SetTypeFlags(createti, TYPEFLAG_FDUAL);
2577 ok(hres == S_OK, "got %08x\n", hres);
2578
2579 hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
2580 ok(hres == S_OK, "got %08x\n", hres);
2581
2582 hres = ICreateTypeInfo_AddRefTypeInfo(createti, dispatch, &hreftype);
2583 ok(hres == S_OK, "got %08x\n", hres);
2584
2585 hres = ICreateTypeInfo_AddImplType(createti, 0, hreftype);
2586 ok(hres == S_OK, "got %08x\n", hres);
2587
2588 hres = ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo, (void**)&dual);
2589 ok(hres == S_OK, "got %08x\n", hres);
2590
2591 hres = ITypeInfo_GetTypeAttr(dual, &typeattr);
2592 ok(hres == S_OK, "got %08x\n", hres);
2593 ok(typeattr->cbSizeInstance == ptr_size, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
2594 ok(typeattr->typekind == 3, "typekind = %d\n", typeattr->typekind);
2595 ok(typeattr->cFuncs == 1, "cFuncs = %d\n", typeattr->cFuncs);
2596 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
2597 ok(typeattr->cImplTypes == 1, "cImplTypes = %d\n", typeattr->cImplTypes);
2598 ok(typeattr->cbSizeVft == 8 * ptr_size || broken(sys == SYS_WIN32 && typeattr->cbSizeVft == 7 * sizeof(void *) + 4), /* xp64 */
2599 "cbSizeVft = %d\n", typeattr->cbSizeVft);
2600 ok(typeattr->cbAlignment == 4, "cbAlignment = %d\n", typeattr->cbAlignment);
2601 ok(typeattr->wTypeFlags == (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL), "wTypeFlags = %d\n", typeattr->wTypeFlags);
2602 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
2603 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
2604
2605 ITypeInfo_ReleaseTypeAttr(dual, typeattr);
2606
2607 hres = ITypeInfo_GetRefTypeOfImplType(dual, -1, &hreftype);
2608 ok(hres == S_OK, "got %08x\n", hres);
2609 ok(hreftype == -2, "got %08x\n", hreftype);
2610
2611 hres = ITypeInfo_GetRefTypeInfo(dual, -2, &ti);
2612 ok(hres == S_OK, "got %08x\n", hres);
2613
2614 hres = ITypeInfo_GetTypeAttr(ti, &typeattr);
2615 ok(hres == S_OK, "got %08x\n", hres);
2616 ok(typeattr->cbSizeInstance == ptr_size, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
2617 ok(typeattr->typekind == 4, "typekind = %d\n", typeattr->typekind);
2618 ok(typeattr->cFuncs == 8, "cFuncs = %d\n", typeattr->cFuncs);
2619 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
2620 ok(typeattr->cImplTypes == 1, "cImplTypes = %d\n", typeattr->cImplTypes);
2621 ok(typeattr->cbSizeVft == 7 * sizeof(void *), "cbSizeVft = %d\n", typeattr->cbSizeVft);
2622 ok(typeattr->cbAlignment == 4, "cbAlignment = %d\n", typeattr->cbAlignment);
2623 ok(typeattr->wTypeFlags == (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL), "wTypeFlags = %d\n", typeattr->wTypeFlags);
2624 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
2625 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
2626
2627 ITypeInfo_ReleaseTypeAttr(ti, typeattr);
2628
2629 ITypeInfo_Release(ti);
2630
2631 hres = ICreateTypeInfo_SetTypeDescAlias(createti, &typedesc1);
2632 ok(hres == TYPE_E_BADMODULEKIND, "got %08x\n", hres);
2633
2634 ICreateTypeInfo_Release(createti);
2635
2636 hres = ITypeInfo_GetTypeAttr(interface1, &typeattr);
2637 ok(hres == S_OK, "got %08x\n", hres);
2638 ok(typeattr->cbSizeInstance == ptr_size, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
2639 ok(typeattr->typekind == 3, "typekind = %d\n", typeattr->typekind);
2640 ok(typeattr->cFuncs == 13, "cFuncs = %d\n", typeattr->cFuncs);
2641 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
2642 ok(typeattr->cImplTypes == 1, "cImplTypes = %d\n", typeattr->cImplTypes);
2643 ok(typeattr->cbSizeVft == 16 * ptr_size || broken(sys == SYS_WIN32 && typeattr->cbSizeVft == 3 * sizeof(void *) + 52), /* xp64 */
2644 "cbSizeVft = %d\n", typeattr->cbSizeVft);
2645 ok(typeattr->cbAlignment == 4, "cbAlignment = %d\n", typeattr->cbAlignment);
2646 ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
2647 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
2648 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
2649
2650 ITypeInfo_ReleaseTypeAttr(interface1, typeattr);
2651
2652 hres = ITypeInfo_GetTypeAttr(interface2, &typeattr);
2653 ok(hres == S_OK, "got %08x\n", hres);
2654 ok(typeattr->cbSizeInstance == ptr_size, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
2655 ok(typeattr->typekind == 3, "typekind = %d\n", typeattr->typekind);
2656 ok(typeattr->cFuncs == 2, "cFuncs = %d\n", typeattr->cFuncs);
2657 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
2658 ok(typeattr->cImplTypes == 1, "cImplTypes = %d\n", typeattr->cImplTypes);
2659 ok((sys == SYS_WIN32 && typeattr->cbSizeVft == 0xaab0) ||
2660 (sys == SYS_WIN64 && typeattr->cbSizeVft == 0xaab8),
2661 "cbSizeVft = 0x%x\n", typeattr->cbSizeVft);
2662 ok(typeattr->cbAlignment == 4, "cbAlignment = %d\n", typeattr->cbAlignment);
2663 ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
2664 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
2665 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
2666
2667 ITypeInfo_ReleaseTypeAttr(interface2, typeattr);
2668
2669 ok(ITypeInfo_Release(interface2)==0, "Object should be freed\n");
2670 ok(ITypeInfo_Release(interface1)==0, "Object should be freed\n");
2671 ok(ITypeInfo_Release(dual)==0, "Object should be freed\n");
2672
2673 hres = ICreateTypeLib2_CreateTypeInfo(createtl, aliasW, TKIND_ALIAS, &createti);
2674 ok(hres == S_OK, "got %08x\n", hres);
2675
2676 hres = ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo, (void**)&interface1);
2677 ok(hres == S_OK, "got %08x\n", hres);
2678
2679 if(0){
2680 /* windows gives invalid values here, and even breaks the typeinfo permanently
2681 * on winxp. only call GetTypeAttr() on a TKIND_ALIAS after SetTypeDescAlias. */
2682 hres = ITypeInfo_GetTypeAttr(interface1, &typeattr);
2683 ok(hres == S_OK, "got %08x\n", hres);
2684 ok(typeattr->cbSizeInstance == 0xffffffb4, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
2685 ok(typeattr->typekind == TKIND_ALIAS, "typekind = %d\n", typeattr->typekind);
2686 ok(typeattr->cFuncs == 0, "cFuncs = %d\n", typeattr->cFuncs);
2687 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
2688 ok(typeattr->cImplTypes == 0, "cImplTypes = %d\n", typeattr->cImplTypes);
2689 ok(typeattr->cbSizeVft == 0, "cbSizeVft = %d\n", typeattr->cbSizeVft);
2690 ok(typeattr->cbAlignment == 0, "cbAlignment = %d\n", typeattr->cbAlignment);
2691 ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
2692 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
2693 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
2694 ok(typeattr->tdescAlias.vt == VT_EMPTY, "Got wrong tdescAlias.vt: %u\n", typeattr->tdescAlias.vt);
2695 ITypeInfo_ReleaseTypeAttr(interface1, typeattr);
2696 }
2697
2698 hres = ICreateTypeInfo_SetTypeDescAlias(createti, NULL);
2699 ok(hres == E_INVALIDARG, "got %08x\n", hres);
2700
2701 typedesc1.vt = VT_I1;
2702 hres = ICreateTypeInfo_SetTypeDescAlias(createti, &typedesc1);
2703 ok(hres == S_OK, "got %08x\n", hres);
2704
2705 hres = ITypeInfo_GetTypeAttr(interface1, &typeattr);
2706 ok(hres == S_OK, "got %08x\n", hres);
2707 ok(typeattr->cbSizeInstance == 1, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
2708 ok(typeattr->typekind == TKIND_ALIAS, "typekind = %d\n", typeattr->typekind);
2709 ok(typeattr->cFuncs == 0, "cFuncs = %d\n", typeattr->cFuncs);
2710 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
2711 ok(typeattr->cImplTypes == 0, "cImplTypes = %d\n", typeattr->cImplTypes);
2712 ok(typeattr->cbSizeVft == 0, "cbSizeVft = %d\n", typeattr->cbSizeVft);
2713 ok(typeattr->cbAlignment == 1, "cbAlignment = %d\n", typeattr->cbAlignment);
2714 ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
2715 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
2716 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
2717 ok(typeattr->tdescAlias.vt == VT_I1, "Got wrong tdescAlias.vt: %u\n", typeattr->tdescAlias.vt);
2718 ITypeInfo_ReleaseTypeAttr(interface1, typeattr);
2719
2720 typedesc1.vt = VT_R8;
2721 hres = ICreateTypeInfo_SetTypeDescAlias(createti, &typedesc1);
2722 ok(hres == S_OK, "got %08x\n", hres);
2723
2724 hres = ITypeInfo_GetTypeAttr(interface1, &typeattr);
2725 ok(hres == S_OK, "got %08x\n", hres);
2726 ok(typeattr->cbSizeInstance == 8, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
2727 ok(typeattr->typekind == TKIND_ALIAS, "typekind = %d\n", typeattr->typekind);
2728 ok(typeattr->cFuncs == 0, "cFuncs = %d\n", typeattr->cFuncs);
2729 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
2730 ok(typeattr->cImplTypes == 0, "cImplTypes = %d\n", typeattr->cImplTypes);
2731 ok(typeattr->cbSizeVft == 0, "cbSizeVft = %d\n", typeattr->cbSizeVft);
2732 ok(typeattr->cbAlignment == 4, "cbAlignment = %d\n", typeattr->cbAlignment);
2733 ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
2734 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
2735 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
2736 ok(typeattr->tdescAlias.vt == VT_R8, "Got wrong tdescAlias.vt: %u\n", typeattr->tdescAlias.vt);
2737 ITypeInfo_ReleaseTypeAttr(interface1, typeattr);
2738
2739 ITypeInfo_Release(interface1);
2740 ICreateTypeInfo_Release(createti);
2741
2742 hres = ICreateTypeLib2_SaveAllChanges(createtl);
2743 ok(hres == S_OK, "got %08x\n", hres);
2744
2745 ok(ICreateTypeLib2_Release(createtl)==0, "Object should be freed\n");
2746
2747 ok(ITypeInfo_Release(dispatch)==0, "Object should be freed\n");
2748 ok(ITypeInfo_Release(unknown)==0, "Object should be freed\n");
2749 ok(ITypeLib_Release(stdole)==0, "Object should be freed\n");
2750
2751 hres = LoadTypeLibEx(filenameW, REGKIND_NONE, &tl);
2752 ok(hres == S_OK, "got %08x\n", hres);
2753
2754 hres = ITypeLib_GetLibAttr(tl, &libattr);
2755 ok(hres == S_OK, "got %08x\n", hres);
2756 ok(libattr->syskind == sys, "syskind = %d\n", libattr->syskind);
2757 ok(libattr->wMajorVerNum == 0, "wMajorVer = %d\n", libattr->wMajorVerNum);
2758 ok(libattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", libattr->wMinorVerNum);
2759 ok(libattr->wLibFlags == LIBFLAG_FHASDISKIMAGE, "wLibFlags = %d\n", libattr->wLibFlags);
2760 ITypeLib_ReleaseTLibAttr(tl, libattr);
2761
2762 found = 2;
2763 memset(tinfos, 0, sizeof(tinfos));
2764 memids[0] = 0xdeadbeef;
2765 memids[1] = 0xdeadbeef;
2766 hres = ITypeLib_FindName(tl, param1W, 0, tinfos, memids, &found);
2767 ok(hres == S_OK, "got: %08x\n", hres);
2768 ok(found == 0, "got wrong count: %u\n", found);
2769 ok(tinfos[0] == NULL, "got invalid typeinfo[0]\n");
2770 ok(tinfos[1] == NULL, "got invalid typeinfo[1]\n");
2771 ok(memids[0] == 0xdeadbeef, "got invalid memid[0]\n");
2772 ok(memids[1] == 0xdeadbeef, "got invalid memid[1]\n");
2773
2774 found = 2;
2775 memset(tinfos, 0, sizeof(tinfos));
2776 memids[0] = 0xdeadbeef;
2777 memids[1] = 0xdeadbeef;
2778 hres = ITypeLib_FindName(tl, func1W, 0, tinfos, memids, &found);
2779 ok(hres == S_OK, "got: %08x\n", hres);
2780 ok(found == 1, "got wrong count: %u\n", found);
2781 ok(tinfos[0] != NULL, "got invalid typeinfo[0]\n");
2782 ok(tinfos[1] == NULL, "got invalid typeinfo[1]\n");
2783 ok(memids[0] == 0, "got invalid memid[0]\n");
2784 ok(memids[1] == 0xdeadbeef, "got invalid memid[1]\n");
2785 if(tinfos[0])
2786 ITypeInfo_Release(tinfos[0]);
2787
2788 found = 2;
2789 memset(tinfos, 0, sizeof(tinfos));
2790 memids[0] = 0xdeadbeef;
2791 memids[1] = 0xdeadbeef;
2792 hres = ITypeLib_FindName(tl, interface1W, 0, tinfos, memids, &found);
2793 ok(hres == S_OK, "got: %08x\n", hres);
2794 ok(found == 1, "got wrong count: %u\n", found);
2795 ok(tinfos[0] != NULL, "got invalid typeinfo[0]\n");
2796 ok(tinfos[1] == NULL, "got invalid typeinfo[1]\n");
2797 ok(memids[0] == MEMBERID_NIL, "got invalid memid[0]: %x\n", memids[0]);
2798 ok(memids[1] == 0xdeadbeef, "got invalid memid[1]\n");
2799 if(tinfos[0])
2800 ITypeInfo_Release(tinfos[0]);
2801
2802 hres = ITypeLib_GetDocumentation(tl, -1, &name, &docstring, &helpcontext, &helpfile);
2803 ok(hres == S_OK, "got %08x\n", hres);
2804 ok(memcmp(typelibW, name, sizeof(typelibW)) == 0, "got wrong typelib name: %s\n",
2805 wine_dbgstr_w(name));
2806 ok(docstring == NULL, "got wrong docstring: %s\n", wine_dbgstr_w(docstring));
2807 ok(helpcontext == 0, "got wrong helpcontext: 0x%x\n", helpcontext);
2808 ok(memcmp(helpfileW, helpfile, sizeof(helpfileW)) == 0,
2809 "got wrong helpfile: %s\n", wine_dbgstr_w(helpfile));
2810 SysFreeString(name);
2811 SysFreeString(helpfile);
2812
2813 hres = ITypeLib_GetDocumentation(tl, 0, &name, &docstring, &helpcontext, &helpfile);
2814 ok(hres == S_OK, "got %08x\n", hres);
2815 ok(memcmp(interface1W, name, sizeof(interface1W)) == 0, "got wrong typeinfo name: %s\n",
2816 wine_dbgstr_w(name));
2817 ok(docstring == NULL, "got wrong docstring: %s\n", wine_dbgstr_w(docstring));
2818 ok(helpcontext == 0, "got wrong helpcontext: 0x%x\n", helpcontext);
2819 ok(memcmp(helpfileW, helpfile, sizeof(helpfileW)) == 0,
2820 "got wrong helpfile: %s\n", wine_dbgstr_w(helpfile));
2821 SysFreeString(name);
2822 SysFreeString(helpfile);
2823
2824 hres = ITypeLib_GetTypeInfo(tl, 0, &ti);
2825 ok(hres == S_OK, "got %08x\n", hres);
2826
2827 hres = ITypeInfo_GetTypeAttr(ti, &typeattr);
2828 ok(hres == S_OK, "got %08x\n", hres);
2829 ok(typeattr->cbSizeInstance == sizeof(void*), "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
2830 ok(typeattr->typekind == TKIND_INTERFACE, "typekind = %d\n", typeattr->typekind);
2831 ok(typeattr->cFuncs == 13, "cFuncs = %d\n", typeattr->cFuncs);
2832 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
2833 ok(typeattr->cImplTypes == 1, "cImplTypes = %d\n", typeattr->cImplTypes);
2834 #ifdef _WIN64
2835 if(sys == SYS_WIN32)
2836 todo_wine ok(typeattr->cbSizeVft == 16 * sizeof(void*), "cbSizeVft = %d\n", typeattr->cbSizeVft);
2837 else
2838 #endif
2839 ok(typeattr->cbSizeVft == 16 * sizeof(void*), "cbSizeVft = %d\n", typeattr->cbSizeVft);
2840 ok(typeattr->cbAlignment == alignment, "cbAlignment = %d\n", typeattr->cbAlignment);
2841 ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
2842 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
2843 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
2844 ITypeInfo_ReleaseTypeAttr(ti, typeattr);
2845
2846 hres = ITypeInfo_GetRefTypeOfImplType(ti, 0, &hreftype);
2847 ok(hres == S_OK, "got %08x\n", hres);
2848 ok(hreftype == 3, "hreftype = %d\n", hreftype);
2849
2850 hres = ITypeInfo_GetRefTypeInfo(ti, hreftype, &unknown);
2851 ok(hres == S_OK, "got %08x\n", hres);
2852
2853 hres = ITypeInfo_GetTypeAttr(unknown, &typeattr);
2854 ok(hres == S_OK, "got %08x\n", hres);
2855 ok(IsEqualGUID(&typeattr->guid, &IID_IUnknown), "got wrong reftypeinfo\n");
2856 ITypeInfo_ReleaseTypeAttr(unknown, typeattr);
2857
2858 ITypeInfo_Release(unknown);
2859
2860 hres = ITypeInfo_GetFuncDesc(ti, 0, &pfuncdesc);
2861 ok(hres == S_OK, "got %08x\n", hres);
2862 ok(pfuncdesc->memid == 0, "got %x\n", pfuncdesc->memid);
2863 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2864 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2865 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2866 ok(pfuncdesc->invkind == INVOKE_PROPERTYPUTREF, "got 0x%x\n", pfuncdesc->invkind);
2867 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2868 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
2869 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2870 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2871 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2872 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2873 edesc = pfuncdesc->lprgelemdescParam;
2874 ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
2875 ok(U(*edesc).idldesc.wIDLFlags == IDLFLAG_FIN, "got: %x\n", U(*edesc).idldesc.wIDLFlags);
2876
2877 hres = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &name, &docstring, &helpcontext, &helpfile);
2878 ok(hres == S_OK, "got: %08x\n", hres);
2879 ok(!memcmp(name, func1W, sizeof(func1W)), "got name: %s\n", wine_dbgstr_w(name));
2880 ok(docstring == NULL, "got docstring: %s\n", wine_dbgstr_w(docstring));
2881 ok(helpcontext == 0x201, "got helpcontext: 0x%x\n", helpcontext);
2882 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "got helpfile: %s\n", wine_dbgstr_w(helpfile));
2883 SysFreeString(name);
2884 SysFreeString(helpfile);
2885
2886 hres = ITypeInfo_GetNames(ti, pfuncdesc->memid, NULL, 0, &cnames);
2887 ok(hres == E_INVALIDARG, "got: %08x\n", hres);
2888
2889 cnames = 8;
2890 hres = ITypeInfo_GetNames(ti, pfuncdesc->memid, names, 0, &cnames);
2891 ok(hres == S_OK, "got: %08x\n", hres);
2892 ok(cnames == 0, "got: %u\n", cnames);
2893
2894 hres = ITypeInfo_GetNames(ti, pfuncdesc->memid, names, sizeof(names) / sizeof(*names), &cnames);
2895 ok(hres == S_OK, "got: %08x\n", hres);
2896 ok(cnames == 1, "got: %u\n", cnames);
2897 ok(!memcmp(names[0], func1W, sizeof(func1W)), "got names[0]: %s\n", wine_dbgstr_w(names[0]));
2898 SysFreeString(names[0]);
2899
2900 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
2901
2902 hres = ITypeInfo_GetFuncDesc(ti, 1, &pfuncdesc);
2903 ok(hres == S_OK, "got %08x\n", hres);
2904 ok(pfuncdesc->memid == 0x60010001, "got %x\n", pfuncdesc->memid);
2905 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2906 ok(pfuncdesc->lprgelemdescParam == NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2907 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2908 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2909 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2910 ok(pfuncdesc->cParams == 0, "got %d\n", pfuncdesc->cParams);
2911 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2912 #ifdef _WIN64
2913 if(sys == SYS_WIN32)
2914 todo_wine ok(pfuncdesc->oVft == 4 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
2915 else
2916 #endif
2917 ok(pfuncdesc->oVft == 4 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
2918 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2919 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2920 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2921
2922 hres = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &name, &docstring, &helpcontext, &helpfile);
2923 ok(hres == S_OK, "got: %08x\n", hres);
2924 ok(name == NULL, "got name: %s\n", wine_dbgstr_w(name));
2925 ok(docstring == NULL, "got docstring: %s\n", wine_dbgstr_w(docstring));
2926 ok(helpcontext == 0, "got helpcontext: 0x%x\n", helpcontext);
2927 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "got helpfile: %s\n", wine_dbgstr_w(helpfile));
2928 SysFreeString(helpfile);
2929 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
2930
2931 hres = ITypeInfo_GetFuncDesc(ti, 2, &pfuncdesc);
2932 ok(hres == S_OK, "got %08x\n", hres);
2933 ok(pfuncdesc->memid == 0x1, "got %x\n", pfuncdesc->memid);
2934 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2935 ok(pfuncdesc->lprgelemdescParam == NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2936 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2937 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2938 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2939 ok(pfuncdesc->cParams == 0, "got %d\n", pfuncdesc->cParams);
2940 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2941 #ifdef _WIN64
2942 if(sys == SYS_WIN32)
2943 todo_wine ok(pfuncdesc->oVft == 5 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
2944 else
2945 #endif
2946 ok(pfuncdesc->oVft == 5 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
2947 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2948 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2949 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2950
2951 hres = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &name, &docstring, &helpcontext, &helpfile);
2952 ok(hres == S_OK, "got: %08x\n", hres);
2953 ok(name == NULL, "got name: %s\n", wine_dbgstr_w(name));
2954 ok(docstring == NULL, "got docstring: %s\n", wine_dbgstr_w(docstring));
2955 ok(helpcontext == 0, "got helpcontext: 0x%x\n", helpcontext);
2956 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "got helpfile: %s\n", wine_dbgstr_w(helpfile));
2957 SysFreeString(helpfile);
2958 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
2959
2960 hres = ITypeInfo_GetFuncDesc(ti, 3, &pfuncdesc);
2961 ok(hres == S_OK, "got %08x\n", hres);
2962 ok(pfuncdesc->memid == 0x6001000b, "got %x\n", pfuncdesc->memid);
2963 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
2964 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
2965 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
2966 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
2967 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
2968 ok(pfuncdesc->cParams == 2, "got %d\n", pfuncdesc->cParams);
2969 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
2970 #ifdef _WIN64
2971 if(sys == SYS_WIN32)
2972 todo_wine ok(pfuncdesc->oVft == 6 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
2973 else
2974 #endif
2975 ok(pfuncdesc->oVft == 6 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
2976 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
2977 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
2978 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
2979
2980 edesc = pfuncdesc->lprgelemdescParam;
2981 ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
2982 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2983 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2984 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
2985 U(*edesc).paramdesc.pparamdescex->cBytes);
2986 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n",
2987 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
2988 ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW),
2989 "got: %s\n",
2990 wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)));
2991
2992 edesc = pfuncdesc->lprgelemdescParam + 1;
2993 ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
2994 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
2995 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
2996 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
2997 U(*edesc).paramdesc.pparamdescex->cBytes);
2998 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n",
2999 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3000 ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW),
3001 "got: %s\n",
3002 wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)));
3003
3004 hres = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &name, &docstring, &helpcontext, &helpfile);
3005 ok(hres == S_OK, "got: %08x\n", hres);
3006 ok(!memcmp(name, func2W, sizeof(func2W)), "got name: %s\n", wine_dbgstr_w(name));
3007 ok(docstring == NULL, "got docstring: %s\n", wine_dbgstr_w(docstring));
3008 ok(helpcontext == 0, "got helpcontext: 0x%x\n", helpcontext);
3009 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "got helpfile: %s\n", wine_dbgstr_w(helpfile));
3010 SysFreeString(name);
3011 SysFreeString(helpfile);
3012
3013 hres = ITypeInfo_GetNames(ti, pfuncdesc->memid, names, sizeof(names) / sizeof(*names), &cnames);
3014 ok(hres == S_OK, "got: %08x\n", hres);
3015 ok(cnames == 3, "got: %u\n", cnames);
3016 ok(!memcmp(names[0], func2W, sizeof(func2W)), "got names[0]: %s\n", wine_dbgstr_w(names[0]));
3017 ok(!memcmp(names[1], param1W, sizeof(func2W)), "got names[1]: %s\n", wine_dbgstr_w(names[1]));
3018 ok(!memcmp(names[2], param2W, sizeof(func2W)), "got names[2]: %s\n", wine_dbgstr_w(names[2]));
3019 SysFreeString(names[0]);
3020 SysFreeString(names[1]);
3021 SysFreeString(names[2]);
3022 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
3023
3024 hres = ITypeInfo_GetFuncDesc(ti, 4, &pfuncdesc);
3025 ok(hres == S_OK, "got %08x\n", hres);
3026 ok(pfuncdesc->memid == 0x6001000c, "got %x\n", pfuncdesc->memid);
3027 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
3028 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
3029 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
3030 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
3031 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
3032 ok(pfuncdesc->cParams == 2, "got %d\n", pfuncdesc->cParams);
3033 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
3034 #ifdef _WIN64
3035 if(sys == SYS_WIN32)
3036 todo_wine ok(pfuncdesc->oVft == 7 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3037 else
3038 #endif
3039 ok(pfuncdesc->oVft == 7 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3040 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
3041 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
3042 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
3043
3044 edesc = pfuncdesc->lprgelemdescParam;
3045 ok(edesc->tdesc.vt == VT_INT, "got: %d\n", edesc->tdesc.vt);
3046 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
3047 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
3048 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
3049 U(*edesc).paramdesc.pparamdescex->cBytes);
3050 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_I4, "got: %d\n",
3051 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3052 ok(V_I4(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0xFFFFFFFF,
3053 "got: 0x%x\n", V_I4(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3054
3055 edesc = pfuncdesc->lprgelemdescParam + 1;
3056 ok(edesc->tdesc.vt == VT_INT, "got: %d\n", edesc->tdesc.vt);
3057 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
3058 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
3059 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
3060 U(*edesc).paramdesc.pparamdescex->cBytes);
3061 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_I4, "got: %d\n",
3062 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3063 ok(V_I4(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0xFFFFFFFF,
3064 "got: 0x%x\n", V_I4(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3065
3066 hres = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &name, &docstring, &helpcontext, &helpfile);
3067 ok(hres == S_OK, "got: %08x\n", hres);
3068 ok(name == NULL, "got name: %s\n", wine_dbgstr_w(name));
3069 ok(docstring == NULL, "got docstring: %s\n", wine_dbgstr_w(docstring));
3070 ok(helpcontext == 0, "got helpcontext: 0x%x\n", helpcontext);
3071 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "got helpfile: %s\n", wine_dbgstr_w(helpfile));
3072 SysFreeString(helpfile);
3073 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
3074
3075 hres = ITypeInfo_GetFuncDesc(ti, 5, &pfuncdesc);
3076 ok(hres == S_OK, "got %08x\n", hres);
3077 ok(pfuncdesc->memid == 0x60010005, "got %x\n", pfuncdesc->memid);
3078 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
3079 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
3080 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
3081 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
3082 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
3083 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
3084 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
3085 #ifdef _WIN64
3086 if(sys == SYS_WIN32)
3087 todo_wine ok(pfuncdesc->oVft == 8 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3088 else
3089 #endif
3090 ok(pfuncdesc->oVft == 8 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3091 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
3092 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
3093 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
3094
3095 edesc = pfuncdesc->lprgelemdescParam;
3096 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
3097 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
3098 U(*edesc).paramdesc.pparamdescex->cBytes);
3099 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_INT, "got: %d\n",
3100 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3101 ok(V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0x789, "got: 0x%x\n",
3102 V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3103 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT,
3104 "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
3105 ok(edesc->tdesc.vt == VT_USERDEFINED, "got: %d\n", edesc->tdesc.vt);
3106 ok(U(edesc->tdesc).hreftype == hreftype, "got: 0x%x\n", U(edesc->tdesc).hreftype);
3107
3108 hres = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &name, &docstring, &helpcontext, &helpfile);
3109 ok(hres == S_OK, "got: %08x\n", hres);
3110 ok(name == NULL, "got name: %s\n", wine_dbgstr_w(name));
3111 ok(docstring == NULL, "got docstring: %s\n", wine_dbgstr_w(docstring));
3112 ok(helpcontext == 0, "got helpcontext: 0x%x\n", helpcontext);
3113 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "got helpfile: %s\n", wine_dbgstr_w(helpfile));
3114 SysFreeString(helpfile);
3115 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
3116
3117 hres = ITypeInfo_GetFuncDesc(ti, 6, &pfuncdesc);
3118 ok(hres == S_OK, "got %08x\n", hres);
3119 ok(pfuncdesc->memid == 0x60010006, "got %x\n", pfuncdesc->memid);
3120 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
3121 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
3122 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
3123 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
3124 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
3125 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
3126 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
3127 #ifdef _WIN64
3128 if(sys == SYS_WIN32)
3129 todo_wine ok(pfuncdesc->oVft == 9 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3130 else
3131 #endif
3132 ok(pfuncdesc->oVft == 9 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3133 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
3134 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VARIANT, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
3135 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
3136
3137 edesc = pfuncdesc->lprgelemdescParam;
3138 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
3139 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
3140 U(*edesc).paramdesc.pparamdescex->cBytes);
3141 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_INT, "got: %d\n",
3142 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3143 ok(V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0x3, "got: 0x%x\n",
3144 V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3145 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT,
3146 "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
3147 ok(edesc->tdesc.vt == VT_VARIANT, "got: %d\n", edesc->tdesc.vt);
3148 ok(U(edesc->tdesc).hreftype == 0, "got: 0x%x\n", U(edesc->tdesc).hreftype);
3149
3150 hres = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &name, &docstring, &helpcontext, &helpfile);
3151 ok(hres == S_OK, "got: %08x\n", hres);
3152 ok(name == NULL, "got name: %s\n", wine_dbgstr_w(name));
3153 ok(docstring == NULL, "got docstring: %s\n", wine_dbgstr_w(docstring));
3154 ok(helpcontext == 0, "got helpcontext: 0x%x\n", helpcontext);
3155 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "got helpfile: %s\n", wine_dbgstr_w(helpfile));
3156 SysFreeString(helpfile);
3157 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
3158
3159 hres = ITypeInfo_GetFuncDesc(ti, 7, &pfuncdesc);
3160 ok(hres == S_OK, "got %08x\n", hres);
3161 ok(pfuncdesc->memid == 0x60010009, "got %x\n", pfuncdesc->memid);
3162 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
3163 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
3164 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
3165 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
3166 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
3167 ok(pfuncdesc->cParams == 2, "got %d\n", pfuncdesc->cParams);
3168 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
3169 #ifdef _WIN64
3170 if(sys == SYS_WIN32)
3171 todo_wine ok(pfuncdesc->oVft == 10 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3172 else
3173 #endif
3174 ok(pfuncdesc->oVft == 10 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3175 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
3176 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
3177 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
3178
3179 edesc = pfuncdesc->lprgelemdescParam;
3180 ok(edesc->tdesc.vt == VT_INT, "got: %d\n", edesc->tdesc.vt);
3181 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FIN, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
3182 ok(U(*edesc).paramdesc.pparamdescex == NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
3183
3184 edesc = pfuncdesc->lprgelemdescParam + 1;
3185 ok(edesc->tdesc.vt == VT_UI2, "got: %d\n", edesc->tdesc.vt);
3186 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
3187 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
3188 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
3189 U(*edesc).paramdesc.pparamdescex->cBytes);
3190 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_UI2, "got: %d\n",
3191 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3192 ok(V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0xFFFF, "got: 0x%x\n",
3193 V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3194
3195 hres = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &name, &docstring, &helpcontext, &helpfile);
3196 ok(hres == S_OK, "got: %08x\n", hres);
3197 ok(name == NULL, "got name: %s\n", wine_dbgstr_w(name));
3198 ok(docstring == NULL, "got docstring: %s\n", wine_dbgstr_w(docstring));
3199 ok(helpcontext == 0, "got helpcontext: 0x%x\n", helpcontext);
3200 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "got helpfile: %s\n", wine_dbgstr_w(helpfile));
3201 SysFreeString(helpfile);
3202 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
3203
3204 hres = ITypeInfo_GetFuncDesc(ti, 8, &pfuncdesc);
3205 ok(hres == S_OK, "got %08x\n", hres);
3206 ok(pfuncdesc->memid == 0x60010003, "got %x\n", pfuncdesc->memid);
3207 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
3208 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
3209 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
3210 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
3211 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
3212 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
3213 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
3214 #ifdef _WIN64
3215 if(sys == SYS_WIN32)
3216 todo_wine ok(pfuncdesc->oVft == 11 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3217 else
3218 #endif
3219 ok(pfuncdesc->oVft == 11 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3220 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
3221 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
3222 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
3223
3224 edesc = pfuncdesc->lprgelemdescParam;
3225 ok(edesc->tdesc.vt == VT_INT, "got: %d\n", edesc->tdesc.vt);
3226 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
3227 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
3228 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
3229 U(*edesc).paramdesc.pparamdescex->cBytes);
3230 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_I4, "got: %d\n",
3231 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3232 ok(V_I4(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0x123, "got: 0x%x\n",
3233 V_I4(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3234
3235 hres = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &name, &docstring, &helpcontext, &helpfile);
3236 ok(hres == S_OK, "got: %08x\n", hres);
3237 ok(name == NULL, "got name: %s\n", wine_dbgstr_w(name));
3238 ok(docstring == NULL, "got docstring: %s\n", wine_dbgstr_w(docstring));
3239 ok(helpcontext == 0, "got helpcontext: 0x%x\n", helpcontext);
3240 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "got helpfile: %s\n", wine_dbgstr_w(helpfile));
3241 SysFreeString(helpfile);
3242 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
3243
3244 hres = ITypeInfo_GetFuncDesc(ti, 9, &pfuncdesc);
3245 ok(hres == S_OK, "got %08x\n", hres);
3246 ok(pfuncdesc->memid == 0, "got %x\n", pfuncdesc->memid);
3247 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
3248 ok(pfuncdesc->lprgelemdescParam == NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
3249 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
3250 ok(pfuncdesc->invkind == INVOKE_PROPERTYGET, "got 0x%x\n", pfuncdesc->invkind);
3251 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
3252 ok(pfuncdesc->cParams == 0, "got %d\n", pfuncdesc->cParams);
3253 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
3254 #ifdef _WIN64
3255 if(sys == SYS_WIN32)
3256 todo_wine ok(pfuncdesc->oVft == 12 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3257 else
3258 #endif
3259 ok(pfuncdesc->oVft == 12 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3260 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
3261 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_BSTR, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
3262 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
3263
3264 hres = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &name, &docstring, &helpcontext, &helpfile);
3265 ok(hres == S_OK, "got: %08x\n", hres);
3266 ok(!memcmp(name, func1W, sizeof(func1W)), "got name: %s\n", wine_dbgstr_w(name));
3267 ok(docstring == NULL, "got docstring: %s\n", wine_dbgstr_w(docstring));
3268 ok(helpcontext == 0x201, "got helpcontext: 0x%x\n", helpcontext);
3269 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "got helpfile: %s\n", wine_dbgstr_w(helpfile));
3270 SysFreeString(name);
3271 SysFreeString(helpfile);
3272
3273 hres = ITypeInfo_GetNames(ti, pfuncdesc->memid, names, sizeof(names) / sizeof(*names), &cnames);
3274 ok(hres == S_OK, "got: %08x\n", hres);
3275 ok(cnames == 1, "got: %u\n", cnames);
3276 ok(!memcmp(names[0], func1W, sizeof(func1W)), "got names[0]: %s\n", wine_dbgstr_w(names[0]));
3277 SysFreeString(names[0]);
3278 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
3279
3280 hres = ITypeInfo_GetFuncDesc(ti, 10, &pfuncdesc);
3281 ok(hres == S_OK, "got %08x\n", hres);
3282 ok(pfuncdesc->memid == 0x60010007, "got %x\n", pfuncdesc->memid);
3283 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
3284 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
3285 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
3286 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
3287 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
3288 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
3289 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
3290 #ifdef _WIN64
3291 if(sys == SYS_WIN32)
3292 todo_wine ok(pfuncdesc->oVft == 13 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3293 else
3294 #endif
3295 ok(pfuncdesc->oVft == 13 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3296 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
3297 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
3298 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
3299
3300 edesc = pfuncdesc->lprgelemdescParam;
3301 ok(edesc->tdesc.vt == VT_PTR, "got: %d\n", edesc->tdesc.vt);
3302 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FIN, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
3303 ok(U(*edesc).paramdesc.pparamdescex == NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
3304 ok(U(edesc->tdesc).lptdesc != NULL, "got: %p\n", U(edesc->tdesc).lptdesc);
3305 ok(U(edesc->tdesc).lptdesc->vt == VT_PTR, "got: %d\n", U(edesc->tdesc).lptdesc->vt);
3306 ok(U(*U(edesc->tdesc).lptdesc).lptdesc != NULL, "got: %p\n", U(*U(edesc->tdesc).lptdesc).lptdesc);
3307 ok(U(*U(edesc->tdesc).lptdesc).lptdesc->vt == VT_BSTR, "got: %d\n", U(*U(edesc->tdesc).lptdesc).lptdesc->vt);
3308
3309 hres = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &name, &docstring, &helpcontext, &helpfile);
3310 ok(hres == S_OK, "got: %08x\n", hres);
3311 ok(name == NULL, "got name: %s\n", wine_dbgstr_w(name));
3312 ok(docstring == NULL, "got docstring: %s\n", wine_dbgstr_w(docstring));
3313 ok(helpcontext == 0, "got helpcontext: 0x%x\n", helpcontext);
3314 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "got helpfile: %s\n", wine_dbgstr_w(helpfile));
3315 SysFreeString(helpfile);
3316 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
3317
3318 hres = ITypeInfo_GetFuncDesc(ti, 11, &pfuncdesc);
3319 ok(hres == S_OK, "got %08x\n", hres);
3320 ok(pfuncdesc->memid == 0x60010004, "got %x\n", pfuncdesc->memid);
3321 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
3322 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
3323 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
3324 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
3325 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
3326 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
3327 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
3328 #ifdef _WIN64
3329 if(sys == SYS_WIN32)
3330 todo_wine ok(pfuncdesc->oVft == 14 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3331 else
3332 #endif
3333 ok(pfuncdesc->oVft == 14 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3334 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
3335 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
3336 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
3337
3338 edesc = pfuncdesc->lprgelemdescParam;
3339 ok(edesc->tdesc.vt == VT_PTR, "got: %d\n", edesc->tdesc.vt);
3340 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FIN, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
3341 ok(U(*edesc).paramdesc.pparamdescex == NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
3342 ok(U(edesc->tdesc).lptdesc != NULL, "got: %p\n", U(edesc->tdesc).lptdesc);
3343 ok(U(edesc->tdesc).lptdesc->vt == VT_BSTR, "got: %d\n", U(edesc->tdesc).lptdesc->vt);
3344
3345 hres = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &name, &docstring, &helpcontext, &helpfile);
3346 ok(hres == S_OK, "got: %08x\n", hres);
3347 ok(name == NULL, "got name: %s\n", wine_dbgstr_w(name));
3348 ok(docstring == NULL, "got docstring: %s\n", wine_dbgstr_w(docstring));
3349 ok(helpcontext == 0, "got helpcontext: 0x%x\n", helpcontext);
3350 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "got helpfile: %s\n", wine_dbgstr_w(helpfile));
3351 SysFreeString(helpfile);
3352 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
3353
3354 hres = ITypeInfo_GetFuncDesc(ti, 12, &pfuncdesc);
3355 ok(hres == S_OK, "got %08x\n", hres);
3356 ok(pfuncdesc->memid == 0, "got %x\n", pfuncdesc->memid);
3357 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
3358 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
3359 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
3360 ok(pfuncdesc->invkind == INVOKE_PROPERTYPUT, "got 0x%x\n", pfuncdesc->invkind);
3361 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
3362 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
3363 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
3364 #ifdef _WIN64
3365 if(sys == SYS_WIN32)
3366 todo_wine ok(pfuncdesc->oVft == 15 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3367 else
3368 #endif
3369 ok(pfuncdesc->oVft == 15 * sizeof(void*), "got %d\n", pfuncdesc->oVft);
3370 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
3371 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
3372 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
3373
3374 edesc = pfuncdesc->lprgelemdescParam;
3375 ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
3376 ok(U(*edesc).idldesc.wIDLFlags == IDLFLAG_FIN, "got: %x\n", U(*edesc).idldesc.wIDLFlags);
3377
3378 hres = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &name, &docstring, &helpcontext, &helpfile);
3379 ok(hres == S_OK, "got: %08x\n", hres);
3380 ok(!memcmp(name, func1W, sizeof(func1W)), "got name: %s\n", wine_dbgstr_w(name));
3381 ok(docstring == NULL, "got docstring: %s\n", wine_dbgstr_w(docstring));
3382 ok(helpcontext == 0x201, "got helpcontext: 0x%x\n", helpcontext);
3383 ok(!memcmp(helpfile, helpfileW, sizeof(helpfileW)), "got helpfile: %s\n", wine_dbgstr_w(helpfile));
3384 SysFreeString(name);
3385 SysFreeString(helpfile);
3386
3387 hres = ITypeInfo_GetNames(ti, pfuncdesc->memid, names, sizeof(names) / sizeof(*names), &cnames);
3388 ok(hres == S_OK, "got: %08x\n", hres);
3389 ok(cnames == 1, "got: %u\n", cnames);
3390 ok(!memcmp(names[0], func1W, sizeof(func1W)), "got names[0]: %s\n", wine_dbgstr_w(names[0]));
3391 SysFreeString(names[0]);
3392 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
3393
3394 hres = ITypeInfo_GetFuncDesc(ti, 13, &pfuncdesc);
3395 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
3396
3397 ok(ITypeInfo_Release(ti) == 0, "Object should be freed\n");
3398
3399 hres = ITypeLib_GetTypeInfo(tl, 1, &ti);
3400 ok(hres == S_OK, "got %08x\n", hres);
3401
3402 hres = ITypeInfo_GetTypeAttr(ti, &typeattr);
3403 ok(hres == S_OK, "got %08x\n", hres);
3404 ok(typeattr->cbSizeInstance == sizeof(void*), "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
3405 ok(typeattr->typekind == TKIND_INTERFACE, "typekind = %d\n", typeattr->typekind);
3406 ok(typeattr->cFuncs == 2, "cFuncs = %d\n", typeattr->cFuncs);
3407 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
3408 ok(typeattr->cImplTypes == 1, "cImplTypes = %d\n", typeattr->cImplTypes);
3409 ok(typeattr->cbSizeVft == 0xaab8 || typeattr->cbSizeVft == 0xaab0 ||
3410 typeattr->cbSizeVft == 0x5560, "cbSizeVft = 0x%x\n", typeattr->cbSizeVft);
3411 ok(typeattr->cbAlignment == alignment, "cbAlignment = %d\n", typeattr->cbAlignment);
3412 ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
3413 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
3414 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
3415 ITypeInfo_ReleaseTypeAttr(ti, typeattr);
3416
3417 hres = ITypeInfo_GetRefTypeOfImplType(ti, 0, &hreftype);
3418 ok(hres == S_OK, "got %08x\n", hres);
3419
3420 hres = ITypeInfo_GetFuncDesc(ti, 0, &pfuncdesc);
3421 ok(hres == S_OK, "got %08x\n", hres);
3422 ok(pfuncdesc->memid == 0x60020000, "got %x\n", pfuncdesc->memid);
3423 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
3424 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
3425 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
3426 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
3427 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
3428 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
3429 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
3430 ok(pfuncdesc->oVft == 0xffffaaa8 ||
3431 pfuncdesc->oVft == 0x5550, "got %x\n", pfuncdesc->oVft);
3432 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
3433 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
3434 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
3435
3436 edesc = pfuncdesc->lprgelemdescParam;
3437 ok(edesc->tdesc.vt == VT_VARIANT, "got: %d\n", edesc->tdesc.vt);
3438 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT,
3439 "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
3440 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
3441 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
3442 U(*edesc).paramdesc.pparamdescex->cBytes);
3443 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_INT, "got: %d\n",
3444 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3445 ok(V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0x3, "got: 0x%x\n",
3446 V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3447 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT,
3448 "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
3449 ok(U(edesc->tdesc).lptdesc == NULL, "got: %p\n", U(edesc->tdesc).lptdesc);
3450 ok(U(edesc->tdesc).hreftype == 0, "got: %d\n", U(edesc->tdesc).hreftype);
3451 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
3452
3453 hres = ITypeInfo_GetFuncDesc(ti, 1, &pfuncdesc);
3454 ok(hres == S_OK, "got %08x\n", hres);
3455 ok(pfuncdesc->memid == 0x60020001, "got %x\n", pfuncdesc->memid);
3456 ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
3457 ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
3458 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
3459 ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
3460 ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
3461 ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
3462 ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
3463 ok(pfuncdesc->oVft == 0xffffaaac ||
3464 pfuncdesc->oVft == 0xffffaab0 ||
3465 pfuncdesc->oVft == 0x5558, "got %x\n", pfuncdesc->oVft);
3466 ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
3467 ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
3468 ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
3469
3470 edesc = pfuncdesc->lprgelemdescParam;
3471 ok(edesc->tdesc.vt == VT_VARIANT, "got: %d\n", edesc->tdesc.vt);
3472 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT,
3473 "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
3474 ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
3475 ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
3476 U(*edesc).paramdesc.pparamdescex->cBytes);
3477 ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_INT, "got: %d\n",
3478 V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3479 ok(V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0x3, "got: 0x%x\n",
3480 V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
3481 ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT,
3482 "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
3483 ok(U(edesc->tdesc).lptdesc == NULL, "got: %p\n", U(edesc->tdesc).lptdesc);
3484 ok(U(edesc->tdesc).hreftype == 0, "got: %d\n", U(edesc->tdesc).hreftype);
3485 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
3486
3487 ok(ITypeInfo_Release(ti) == 0, "Object should be freed\n");
3488
3489 hres = ITypeLib_GetTypeInfo(tl, 2, &ti);
3490 ok(hres == S_OK, "got %08x\n", hres);
3491
3492 hres = ITypeInfo_QueryInterface(ti, &IID_ITypeInfo2, (void**)&ti2);
3493 ok(hres == S_OK, "got %08x\n", hres);
3494
3495 hres = ITypeInfo_GetTypeAttr(ti, &typeattr);
3496 ok(hres == S_OK, "got %08x\n", hres);
3497 ok(typeattr->cbSizeInstance == sizeof(void*), "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
3498 ok(typeattr->typekind == TKIND_INTERFACE, "typekind = %d\n", typeattr->typekind);
3499 ok(typeattr->cFuncs == 0, "cFuncs = %d\n", typeattr->cFuncs);
3500 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
3501 ok(typeattr->cImplTypes == 0, "cImplTypes = %d\n", typeattr->cImplTypes);
3502 ok(typeattr->cbSizeVft == 0, "cbSizeVft = %d\n", typeattr->cbSizeVft);
3503 ok(typeattr->cbAlignment == alignment, "cbAlignment = %d\n", typeattr->cbAlignment);
3504 ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
3505 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
3506 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
3507 ITypeInfo_ReleaseTypeAttr(ti, typeattr);
3508
3509 VariantClear(&cust_data);
3510 hres = ITypeInfo2_GetCustData(ti2, &custguid, &cust_data);
3511 ok(hres == S_OK, "got %08x\n", hres);
3512 ok(V_VT(&cust_data) == VT_BSTR, "got wrong custdata type: %u\n", V_VT(&cust_data));
3513 ok(!lstrcmpW(V_BSTR(&cust_data), asdfW), "got wrong custdata value: %s\n", wine_dbgstr_w(V_BSTR(&cust_data)));
3514 SysFreeString(V_BSTR(&cust_data));
3515
3516 ITypeInfo2_Release(ti2);
3517 ok(ITypeInfo_Release(ti) == 0, "Object should be freed\n");
3518
3519 hres = ITypeLib_GetTypeInfo(tl, 3, &ti);
3520 ok(hres == S_OK, "got %08x\n", hres);
3521
3522 hres = ITypeInfo_GetTypeAttr(ti, &typeattr);
3523 ok(hres == S_OK, "got %08x\n", hres);
3524 ok(typeattr->cbSizeInstance == sizeof(void*), "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
3525 ok(typeattr->typekind == TKIND_COCLASS, "typekind = %d\n", typeattr->typekind);
3526 ok(typeattr->cFuncs == 0, "cFuncs = %d\n", typeattr->cFuncs);
3527 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
3528 ok(typeattr->cImplTypes == 3, "cImplTypes = %d\n", typeattr->cImplTypes);
3529 ok(typeattr->cbSizeVft == 0, "cbSizeVft = %d\n", typeattr->cbSizeVft);
3530 ok(typeattr->cbAlignment == alignment, "cbAlignment = %d\n", typeattr->cbAlignment);
3531 ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
3532 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
3533 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
3534 ITypeInfo_ReleaseTypeAttr(ti, typeattr);
3535
3536 hres = ITypeInfo_GetRefTypeOfImplType(ti, 0, &hreftype);
3537 ok(hres == S_OK, "got %08x\n", hres);
3538 ok(hreftype == 0, "got wrong hreftype: %x\n", hreftype);
3539
3540 hres = ITypeInfo_GetImplTypeFlags(ti, 0, &impltypeflags);
3541 ok(hres == S_OK, "got %08x\n", hres);
3542 ok(impltypeflags == IMPLTYPEFLAG_FDEFAULT, "got wrong flag: %x\n", impltypeflags);
3543
3544 hres = ITypeInfo_GetRefTypeOfImplType(ti, 1, &hreftype);
3545 ok(hres == S_OK, "got %08x\n", hres);
3546 ok(hreftype == 1, "got wrong hreftype: %x\n", hreftype);
3547
3548 hres = ITypeInfo_GetImplTypeFlags(ti, 1, &impltypeflags);
3549 ok(hres == S_OK, "got %08x\n", hres);
3550 ok(impltypeflags == IMPLTYPEFLAG_FRESTRICTED, "got wrong flag: %x\n", impltypeflags);
3551
3552 hres = ITypeInfo_GetRefTypeOfImplType(ti, 2, &hreftype);
3553 ok(hres == S_OK, "got %08x\n", hres);
3554 ok(hreftype == 1, "got wrong hreftype: %x\n", hreftype);
3555
3556 hres = ITypeInfo_GetImplTypeFlags(ti, 2, &impltypeflags);
3557 ok(hres == S_OK, "got %08x\n", hres);
3558 ok(impltypeflags == 0, "got wrong flag: %x\n", impltypeflags);
3559
3560 hres = ITypeInfo_GetRefTypeOfImplType(ti, 3, &hreftype);
3561 ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
3562
3563 ok(ITypeInfo_Release(ti) == 0, "Object should be freed\n");
3564
3565 hres = ITypeLib_GetTypeInfo(tl, 4, &ti);
3566 ok(hres == S_OK, "got %08x\n", hres);
3567
3568 hres = ITypeInfo_GetTypeAttr(ti, &typeattr);
3569 ok(hres == S_OK, "got %08x\n", hres);
3570 ok(typeattr->cbSizeInstance == sizeof(void*), "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
3571 ok(typeattr->typekind == TKIND_DISPATCH, "typekind = %d\n", typeattr->typekind);
3572 ok(typeattr->cFuncs == 8, "cFuncs = %d\n", typeattr->cFuncs);
3573 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
3574 ok(typeattr->cImplTypes == 1, "cImplTypes = %d\n", typeattr->cImplTypes);
3575 ok(typeattr->cbSizeVft == 7 * sizeof(void*), "cbSizeVft = %d\n", typeattr->cbSizeVft);
3576 ok(typeattr->cbAlignment == alignment, "cbAlignment = %d\n", typeattr->cbAlignment);
3577 ok(typeattr->wTypeFlags == (TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FDUAL), "wTypeFlags = 0x%x\n", typeattr->wTypeFlags);
3578 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
3579 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
3580 ITypeInfo_ReleaseTypeAttr(ti, typeattr);
3581
3582 hres = ITypeInfo_GetTypeComp(ti, &tcomp);
3583 ok(hres == S_OK, "got %08x\n", hres);
3584
3585 hres = ITypeComp_Bind(tcomp, invokeW, 0, INVOKE_FUNC, &interface1, &desckind, &bindptr);
3586 ok(hres == S_OK, "got %08x\n", hres);
3587 ok(desckind == DESCKIND_FUNCDESC, "got wrong desckind: 0x%x\n", desckind);
3588 ok(bindptr.lpfuncdesc->memid == 0x60010003, "got %x\n", bindptr.lpfuncdesc->memid);
3589 ok(bindptr.lpfuncdesc->lprgscode == NULL, "got %p\n", bindptr.lpfuncdesc->lprgscode);
3590 ok(bindptr.lpfuncdesc->lprgelemdescParam != NULL, "got %p\n", bindptr.lpfuncdesc->lprgelemdescParam);
3591 ok(bindptr.lpfuncdesc->funckind == FUNC_DISPATCH, "got 0x%x\n", bindptr.lpfuncdesc->funckind);
3592 ok(bindptr.lpfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", bindptr.lpfuncdesc->invkind);
3593 ok(bindptr.lpfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", bindptr.lpfuncdesc->callconv);
3594 ok(bindptr.lpfuncdesc->cParams == 8, "got %d\n", bindptr.lpfuncdesc->cParams);
3595 ok(bindptr.lpfuncdesc->cParamsOpt == 0, "got %d\n", bindptr.lpfuncdesc->cParamsOpt);
3596 #ifdef _WIN64
3597 if(sys == SYS_WIN32)
3598 todo_wine ok(bindptr.lpfuncdesc->oVft == 6 * sizeof(void*), "got %x\n", bindptr.lpfuncdesc->oVft);
3599 else
3600 #endif
3601 ok(bindptr.lpfuncdesc->oVft == 6 * sizeof(void*), "got %x\n", bindptr.lpfuncdesc->oVft);
3602 ok(bindptr.lpfuncdesc->cScodes == 0, "got %d\n", bindptr.lpfuncdesc->cScodes);
3603 ok(bindptr.lpfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", bindptr.lpfuncdesc->elemdescFunc.tdesc.vt);
3604 ok(bindptr.lpfuncdesc->wFuncFlags == FUNCFLAG_FRESTRICTED, "got 0x%x\n", bindptr.lpfuncdesc->wFuncFlags);
3605
3606 ITypeInfo_ReleaseFuncDesc(interface1, bindptr.lpfuncdesc);
3607 ITypeInfo_Release(interface1);
3608 ITypeComp_Release(tcomp);
3609
3610 hres = ITypeInfo_GetRefTypeOfImplType(ti, -1, &hreftype);
3611 ok(hres == S_OK, "got %08x\n", hres);
3612 ok(hreftype == -2, "got wrong hreftype: %x\n", hreftype);
3613
3614 hres = ITypeInfo_GetRefTypeInfo(ti, hreftype, &interface1);
3615 ok(hres == S_OK, "got %08x\n", hres);
3616
3617 hres = ITypeInfo_GetTypeAttr(interface1, &typeattr);
3618 ok(hres == S_OK, "got %08x\n", hres);
3619 ok(typeattr->cbSizeInstance == sizeof(void*), "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
3620 ok(typeattr->typekind == TKIND_INTERFACE, "typekind = %d\n", typeattr->typekind);
3621 ok(typeattr->cFuncs == 1, "cFuncs = %d\n", typeattr->cFuncs);
3622 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
3623 ok(typeattr->cImplTypes == 1, "cImplTypes = %d\n", typeattr->cImplTypes);
3624 #ifdef _WIN64
3625 if(sys == SYS_WIN32)
3626 todo_wine ok(typeattr->cbSizeVft == 8 * sizeof(void*), "cbSizeVft = %d\n", typeattr->cbSizeVft);
3627 else
3628 #endif
3629 ok(typeattr->cbSizeVft == 8 * sizeof(void*), "cbSizeVft = %d\n", typeattr->cbSizeVft);
3630 ok(typeattr->cbAlignment == alignment, "cbAlignment = %d\n", typeattr->cbAlignment);
3631 ok(typeattr->wTypeFlags == (TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FDUAL), "wTypeFlags = 0x%x\n", typeattr->wTypeFlags);
3632 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
3633 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
3634 ITypeInfo_ReleaseTypeAttr(interface1, typeattr);
3635
3636 ITypeInfo_Release(interface1);
3637
3638 ok(ITypeInfo_Release(ti) == 0, "Object should be freed\n");
3639
3640 hres = ITypeLib_GetTypeInfo(tl, 5, &ti);
3641 ok(hres == S_OK, "got %08x\n", hres);
3642
3643 hres = ITypeInfo_GetTypeAttr(ti, &typeattr);
3644 ok(hres == S_OK, "got %08x\n", hres);
3645 ok(typeattr->cbSizeInstance == 8, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
3646 ok(typeattr->typekind == TKIND_ALIAS, "typekind = %d\n", typeattr->typekind);
3647 ok(typeattr->cFuncs == 0, "cFuncs = %d\n", typeattr->cFuncs);
3648 ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
3649 ok(typeattr->cImplTypes == 0, "cImplTypes = %d\n", typeattr->cImplTypes);
3650 ok(typeattr->cbSizeVft == 0, "cbSizeVft = %d\n", typeattr->cbSizeVft);
3651 ok(typeattr->cbAlignment == alignment, "cbAlignment = %d\n", typeattr->cbAlignment);
3652 ok(typeattr->wTypeFlags == 0, "wTypeFlags = 0x%x\n", typeattr->wTypeFlags);
3653 ok(typeattr->wMajorVerNum == 0, "wMajorVerNum = %d\n", typeattr->wMajorVerNum);
3654 ok(typeattr->wMinorVerNum == 0, "wMinorVerNum = %d\n", typeattr->wMinorVerNum);
3655 ok(typeattr->tdescAlias.vt == VT_R8, "Got wrong tdescAlias.vt: %u\n", typeattr->tdescAlias.vt);
3656 ITypeInfo_ReleaseTypeAttr(ti, typeattr);
3657
3658 ok(ITypeInfo_Release(ti) == 0, "Object should be freed\n");
3659
3660 ok(ITypeLib_Release(tl)==0, "Object should be freed\n");
3661
3662 DeleteFileA(filename);
3663 }
3664
3665 #if 0 /* use this to generate more tests */
3666
3667 #define OLE_CHECK(x) { HRESULT hr = x; if (FAILED(hr)) { printf(#x "failed - %x\n", hr); return; } }
3668
3669 static char *dump_string(LPWSTR wstr)
3670 {
3671 int size = lstrlenW(wstr)+1;
3672 char *out = CoTaskMemAlloc(size);
3673 WideCharToMultiByte(20127, 0, wstr, -1, out, size, NULL, NULL);
3674 return out;
3675 }
3676
3677 struct map_entry
3678 {
3679 DWORD value;
3680 const char *name;
3681 };
3682
3683 #define MAP_ENTRY(x) { x, #x }
3684 static const struct map_entry tkind_map[] = {
3685 MAP_ENTRY(TKIND_ENUM),
3686 MAP_ENTRY(TKIND_RECORD),
3687 MAP_ENTRY(TKIND_MODULE),
3688 MAP_ENTRY(TKIND_INTERFACE),
3689 MAP_ENTRY(TKIND_DISPATCH),
3690 MAP_ENTRY(TKIND_COCLASS),
3691 MAP_ENTRY(TKIND_ALIAS),
3692 MAP_ENTRY(TKIND_UNION),
3693 MAP_ENTRY(TKIND_MAX),
3694 {0, NULL}
3695 };
3696
3697 static const struct map_entry funckind_map[] = {
3698 MAP_ENTRY(FUNC_VIRTUAL),
3699 MAP_ENTRY(FUNC_PUREVIRTUAL),
3700 MAP_ENTRY(FUNC_NONVIRTUAL),
3701 MAP_ENTRY(FUNC_STATIC),
3702 MAP_ENTRY(FUNC_DISPATCH),
3703 {0, NULL}
3704 };
3705
3706 static const struct map_entry invkind_map[] = {
3707 MAP_ENTRY(INVOKE_FUNC),
3708 MAP_ENTRY(INVOKE_PROPERTYGET),
3709 MAP_ENTRY(INVOKE_PROPERTYPUT),
3710 MAP_ENTRY(INVOKE_PROPERTYPUTREF),
3711 {0, NULL}
3712 };
3713
3714 static const struct map_entry callconv_map[] = {
3715 MAP_ENTRY(CC_FASTCALL),
3716 MAP_ENTRY(CC_CDECL),
3717 MAP_ENTRY(CC_PASCAL),
3718 MAP_ENTRY(CC_MACPASCAL),
3719 MAP_ENTRY(CC_STDCALL),
3720 MAP_ENTRY(CC_FPFASTCALL),
3721 MAP_ENTRY(CC_SYSCALL),
3722 MAP_ENTRY(CC_MPWCDECL),
3723 MAP_ENTRY(CC_MPWPASCAL),
3724 {0, NULL}
3725 };
3726
3727 static const struct map_entry vt_map[] = {
3728 MAP_ENTRY(VT_EMPTY),
3729 MAP_ENTRY(VT_NULL),
3730 MAP_ENTRY(VT_I2),
3731 MAP_ENTRY(VT_I4),
3732 MAP_ENTRY(VT_R4),
3733 MAP_ENTRY(VT_R8),
3734 MAP_ENTRY(VT_CY),
3735 MAP_ENTRY(VT_DATE),
3736 MAP_ENTRY(VT_BSTR),
3737 MAP_ENTRY(VT_DISPATCH),
3738 MAP_ENTRY(VT_ERROR),
3739 MAP_ENTRY(VT_BOOL),
3740 MAP_ENTRY(VT_VARIANT),
3741 MAP_ENTRY(VT_UNKNOWN),
3742 MAP_ENTRY(VT_DECIMAL),
3743 MAP_ENTRY(15),
3744 MAP_ENTRY(VT_I1),
3745 MAP_ENTRY(VT_UI1),
3746 MAP_ENTRY(VT_UI2),
3747 MAP_ENTRY(VT_UI4),
3748 MAP_ENTRY(VT_I8),
3749 MAP_ENTRY(VT_UI8),
3750 MAP_ENTRY(VT_INT),
3751 MAP_ENTRY(VT_UINT),
3752 MAP_ENTRY(VT_VOID),
3753 MAP_ENTRY(VT_HRESULT),
3754 MAP_ENTRY(VT_PTR),
3755 MAP_ENTRY(VT_SAFEARRAY),
3756 MAP_ENTRY(VT_CARRAY),
3757 MAP_ENTRY(VT_USERDEFINED),
3758 MAP_ENTRY(VT_LPSTR),
3759 MAP_ENTRY(VT_LPWSTR),
3760 MAP_ENTRY(VT_RECORD),
3761 MAP_ENTRY(VT_INT_PTR),
3762 MAP_ENTRY(VT_UINT_PTR),
3763 MAP_ENTRY(39),
3764 MAP_ENTRY(40),
3765 MAP_ENTRY(41),
3766 MAP_ENTRY(42),
3767 MAP_ENTRY(43),
3768 MAP_ENTRY(44),
3769 MAP_ENTRY(45),
3770 MAP_ENTRY(46),
3771 MAP_ENTRY(47),
3772 MAP_ENTRY(48),
3773 MAP_ENTRY(49),
3774 MAP_ENTRY(50),
3775 MAP_ENTRY(51),
3776 MAP_ENTRY(52),
3777 MAP_ENTRY(53),
3778 MAP_ENTRY(54),
3779 MAP_ENTRY(55),
3780 MAP_ENTRY(56),
3781 MAP_ENTRY(57),
3782 MAP_ENTRY(58),
3783 MAP_ENTRY(59),
3784 MAP_ENTRY(60),
3785 MAP_ENTRY(61),
3786 MAP_ENTRY(62),
3787 MAP_ENTRY(63),
3788 MAP_ENTRY(VT_FILETIME),
3789 MAP_ENTRY(VT_BLOB),
3790 MAP_ENTRY(VT_STREAM),
3791 MAP_ENTRY(VT_STORAGE),
3792 MAP_ENTRY(VT_STREAMED_OBJECT),
3793 MAP_ENTRY(VT_STORED_OBJECT),
3794 MAP_ENTRY(VT_BLOB_OBJECT),
3795 MAP_ENTRY(VT_CF),
3796 MAP_ENTRY(VT_CLSID),
3797 {0, NULL}
3798 };
3799
3800 #undef MAP_ENTRY
3801
3802 static const char *map_value(int val, const struct map_entry *map)
3803 {
3804 static int map_id;
3805 static char bufs[16][256];
3806 char *buf;
3807
3808 while (map->name)
3809 {
3810 if (map->value == val)
3811 return map->name;
3812 map++;
3813 }
3814
3815 buf = bufs[(map_id++)%16];
3816 sprintf(buf, "%d", val);
3817 return buf;
3818 }
3819
3820 static const char *dump_type_flags(DWORD flags)
3821 {
3822 static char buf[256];
3823
3824 if (!flags) return "0";
3825
3826 buf[0] = 0;
3827
3828 #define ADD_FLAG(x) if (flags & x) { if (buf[0]) strcat(buf, "|"); strcat(buf, #x); flags &= ~x; }
3829 ADD_FLAG(TYPEFLAG_FPROXY)
3830 ADD_FLAG(TYPEFLAG_FREVERSEBIND)
3831 ADD_FLAG(TYPEFLAG_FDISPATCHABLE)
3832 ADD_FLAG(TYPEFLAG_FREPLACEABLE)
3833 ADD_FLAG(TYPEFLAG_FAGGREGATABLE)
3834 ADD_FLAG(TYPEFLAG_FRESTRICTED)
3835 ADD_FLAG(TYPEFLAG_FOLEAUTOMATION)
3836 ADD_FLAG(TYPEFLAG_FNONEXTENSIBLE)
3837 ADD_FLAG(TYPEFLAG_FDUAL)
3838 ADD_FLAG(TYPEFLAG_FCONTROL)
3839 ADD_FLAG(TYPEFLAG_FHIDDEN)
3840 ADD_FLAG(TYPEFLAG_FPREDECLID)
3841 ADD_FLAG(TYPEFLAG_FLICENSED)
3842 ADD_FLAG(TYPEFLAG_FCANCREATE)
3843 ADD_FLAG(TYPEFLAG_FAPPOBJECT)
3844 #undef ADD_FLAG
3845
3846 assert(!flags);
3847 assert(strlen(buf) < sizeof(buf));
3848
3849 return buf;
3850 }
3851
3852 static char *print_size(BSTR name, TYPEATTR *attr)
3853 {
3854 static char buf[256];
3855
3856 switch (attr->typekind)
3857 {
3858 case TKIND_DISPATCH:
3859 case TKIND_INTERFACE:
3860 sprintf(buf, "sizeof(%s*)", dump_string(name));
3861 break;
3862
3863 case TKIND_RECORD:
3864 sprintf(buf, "sizeof(struct %s)", dump_string(name));
3865 break;
3866
3867 case TKIND_UNION:
3868 sprintf(buf, "sizeof(union %s)", dump_string(name));
3869 break;
3870
3871 case TKIND_ENUM:
3872 case TKIND_ALIAS:
3873 sprintf(buf, "4");
3874 break;
3875
3876 default:
3877 assert(0);
3878 return NULL;
3879 }
3880
3881 return buf;
3882 }
3883
3884 static const char *dump_param_flags(DWORD flags)
3885 {
3886 static char buf[256];
3887
3888 if (!flags) return "PARAMFLAG_NONE";
3889
3890 buf[0] = 0;
3891
3892 #define ADD_FLAG(x) if (flags & x) { if (buf[0]) strcat(buf, "|"); strcat(buf, #x); flags &= ~x; }
3893 ADD_FLAG(PARAMFLAG_FIN)
3894 ADD_FLAG(PARAMFLAG_FOUT)
3895 ADD_FLAG(PARAMFLAG_FLCID)
3896 ADD_FLAG(PARAMFLAG_FRETVAL)
3897 ADD_FLAG(PARAMFLAG_FOPT)
3898 ADD_FLAG(PARAMFLAG_FHASDEFAULT)
3899 ADD_FLAG(PARAMFLAG_FHASCUSTDATA)
3900 #undef ADD_FLAG
3901
3902 assert(!flags);
3903 assert(strlen(buf) < sizeof(buf));
3904
3905 return buf;
3906 }
3907
3908 static const char *dump_func_flags(DWORD flags)
3909 {
3910 static char buf[256];
3911
3912 if (!flags) return "0";
3913
3914 buf[0] = 0;
3915
3916 #define ADD_FLAG(x) if (flags & x) { if (buf[0]) strcat(buf, "|"); strcat(buf, #x); flags &= ~x; }
3917 ADD_FLAG(FUNCFLAG_FRESTRICTED)
3918 ADD_FLAG(FUNCFLAG_FSOURCE)
3919 ADD_FLAG(FUNCFLAG_FBINDABLE)
3920 ADD_FLAG(FUNCFLAG_FREQUESTEDIT)
3921 ADD_FLAG(FUNCFLAG_FDISPLAYBIND)
3922 ADD_FLAG(FUNCFLAG_FDEFAULTBIND)
3923 ADD_FLAG(FUNCFLAG_FHIDDEN)
3924 ADD_FLAG(FUNCFLAG_FUSESGETLASTERROR)
3925 ADD_FLAG(FUNCFLAG_FDEFAULTCOLLELEM)
3926 ADD_FLAG(FUNCFLAG_FUIDEFAULT)
3927 ADD_FLAG(FUNCFLAG_FNONBROWSABLE)
3928 ADD_FLAG(FUNCFLAG_FREPLACEABLE)
3929 ADD_FLAG(FUNCFLAG_FIMMEDIATEBIND)
3930 #undef ADD_FLAG
3931
3932 assert(!flags);
3933 assert(strlen(buf) < sizeof(buf));
3934
3935 return buf;
3936 }
3937
3938 static int get_href_type(ITypeInfo *info, TYPEDESC *tdesc)
3939 {
3940 int href_type = -1;
3941
3942 if (tdesc->vt == VT_USERDEFINED)
3943 {
3944 HRESULT hr;
3945 ITypeInfo *param;
3946 TYPEATTR *attr;
3947
3948 hr = ITypeInfo_GetRefTypeInfo(info, U(*tdesc).hreftype, &param);
3949 ok(hr == S_OK, "GetRefTypeInfo error %#x\n", hr);
3950 hr = ITypeInfo_GetTypeAttr(param, &attr);
3951 ok(hr == S_OK, "GetTypeAttr error %#x\n", hr);
3952
3953 href_type = attr->typekind;
3954
3955 ITypeInfo_ReleaseTypeAttr(param, attr);
3956 ITypeInfo_Release(param);
3957 }
3958
3959 return href_type;
3960 }
3961
3962 static void test_dump_typelib(const char *name)
3963 {
3964 WCHAR wszString[260];
3965 ITypeInfo *info;
3966 ITypeLib *lib;
3967 int count;
3968 int i;
3969
3970 MultiByteToWideChar(CP_ACP, 0, name, -1, wszString, 260);
3971 OLE_CHECK(LoadTypeLib(wszString, &lib));
3972
3973 printf("/*** Autogenerated data. Do not edit, change the generator above instead. ***/\n");
3974
3975 count = ITypeLib_GetTypeInfoCount(lib);
3976 for (i = 0; i < count; i++)
3977 {
3978 TYPEATTR *attr;
3979 BSTR name;
3980 DWORD help_ctx;
3981 int f = 0;
3982
3983 OLE_CHECK(ITypeLib_GetDocumentation(lib, i, &name, NULL, &help_ctx, NULL));
3984 printf("{\n"
3985 " \"%s\",\n", dump_string(name));
3986
3987 OLE_CHECK(ITypeLib_GetTypeInfo(lib, i, &info));
3988 OLE_CHECK(ITypeInfo_GetTypeAttr(info, &attr));
3989
3990 printf(" \"%s\",\n", wine_dbgstr_guid(&attr->guid));
3991
3992 printf(" /*kind*/ %s, /*flags*/ %s, /*align*/ %d, /*size*/ %s,\n"
3993 " /*helpctx*/ 0x%04x, /*version*/ 0x%08x, /*#vtbl*/ %d, /*#func*/ %d",
3994 map_value(attr->typekind, tkind_map), dump_type_flags(attr->wTypeFlags),
3995 attr->cbAlignment, print_size(name, attr),
3996 help_ctx, MAKELONG(attr->wMinorVerNum, attr->wMajorVerNum),
3997 attr->cbSizeVft/sizeof(void*), attr->cFuncs);
3998
3999 if (attr->cFuncs) printf(",\n {\n");
4000 else printf("\n");
4001
4002 while (1)
4003 {
4004 FUNCDESC *desc;
4005 BSTR tab[256];
4006 UINT cNames;
4007 int p;
4008
4009 if (FAILED(ITypeInfo_GetFuncDesc(info, f, &desc)))
4010 break;
4011 printf(" {\n"
4012 " /*id*/ 0x%x, /*func*/ %s, /*inv*/ %s, /*call*/ %s,\n",
4013 desc->memid, map_value(desc->funckind, funckind_map), map_value(desc->invkind, invkind_map),
4014 map_value(desc->callconv, callconv_map));
4015 printf(" /*#param*/ %d, /*#opt*/ %d, /*vtbl*/ %d, /*#scodes*/ %d, /*flags*/ %s,\n",
4016 desc->cParams, desc->cParamsOpt, desc->oVft/sizeof(void*), desc->cScodes, dump_func_flags(desc->wFuncFlags));
4017 printf(" {%s, %s, %s}, /* ret */\n", map_value(desc->elemdescFunc.tdesc.vt, vt_map),
4018 map_value(get_href_type(info, &desc->elemdescFunc.tdesc), tkind_map), dump_param_flags(U(desc->elemdescFunc).paramdesc.wParamFlags));
4019 printf(" { /* params */\n");
4020 for (p = 0; p < desc->cParams; p++)
4021 {
4022 ELEMDESC e = desc->lprgelemdescParam[p];
4023 printf(" {%s, %s, %s},\n", map_value(e.tdesc.vt, vt_map),
4024 map_value(get_href_type(info, &e.tdesc), tkind_map), dump_param_flags(U(e).paramdesc.wParamFlags));
4025 }
4026 printf(" {-1, 0, 0}\n");
4027 printf(" },\n");
4028 printf(" { /* names */\n");
4029 OLE_CHECK(ITypeInfo_GetNames(info, desc->memid, tab, 256, &cNames));
4030 for (p = 0; p < cNames; p++)
4031 {
4032 printf(" \"%s\",\n", dump_string(tab[p]));
4033 SysFreeString(tab[p]);
4034 }
4035 printf(" NULL,\n");
4036 printf(" },\n");
4037 printf(" },\n");
4038 ITypeInfo_ReleaseFuncDesc(info, desc);
4039 f++;
4040 }
4041 if (attr->cFuncs) printf(" }\n");
4042 printf("},\n");
4043 ITypeInfo_ReleaseTypeAttr(info, attr);
4044 ITypeInfo_Release(info);
4045 SysFreeString(name);
4046 }
4047 ITypeLib_Release(lib);
4048 }
4049
4050 #else
4051
4052 typedef struct _element_info
4053 {
4054 VARTYPE vt;
4055 TYPEKIND type;
4056 USHORT wParamFlags;
4057 } element_info;
4058
4059 typedef struct _function_info
4060 {
4061 MEMBERID memid;
4062 FUNCKIND funckind;
4063 INVOKEKIND invkind;
4064 CALLCONV callconv;
4065 short cParams;
4066 short cParamsOpt;
4067 short vtbl_index;
4068 short cScodes;
4069 WORD wFuncFlags;
4070 element_info ret_type;
4071 element_info params[15];
4072 LPCSTR names[15];
4073 } function_info;
4074
4075 typedef struct _type_info
4076 {
4077 LPCSTR name;
4078 LPCSTR uuid;
4079 TYPEKIND type;
4080 WORD wTypeFlags;
4081 USHORT cbAlignment;
4082 USHORT cbSizeInstance;
4083 USHORT help_ctx;
4084 DWORD version;
4085 USHORT cbSizeVft;
4086 USHORT cFuncs;
4087 function_info funcs[20];
4088 } type_info;
4089
4090 static const type_info info[] = {
4091 /*** Autogenerated data. Do not edit, change the generator above instead. ***/
4092 {
4093 "g",
4094 "{b14b6bb5-904e-4ff9-b247-bd361f7a0001}",
4095 /*kind*/ TKIND_RECORD, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(struct g),
4096 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4097 },
4098 {
4099 "test_iface",
4100 "{b14b6bb5-904e-4ff9-b247-bd361f7a0002}",
4101 /*kind*/ TKIND_INTERFACE, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(test_iface*),
4102 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 4, /*#func*/ 1,
4103 {
4104 {
4105 /*id*/ 0x60010000, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4106 /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 3, /*#scodes*/ 0, /*flags*/ 0,
4107 {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
4108 { /* params */
4109 {VT_PTR, -1, PARAMFLAG_FIN},
4110 {-1, 0, 0}
4111 },
4112 { /* names */
4113 "Test",
4114 "ptr",
4115 NULL,
4116 },
4117 },
4118 }
4119 },
4120 {
4121 "parent_iface",
4122 "{b14b6bb5-904e-4ff9-b247-bd361f7aa001}",
4123 /*kind*/ TKIND_INTERFACE, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(parent_iface*),
4124 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 4, /*#func*/ 1,
4125 {
4126 {
4127 /*id*/ 0x60010000, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4128 /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 3, /*#scodes*/ 0, /*flags*/ 0,
4129 {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
4130 { /* params */
4131 {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL},
4132 {-1, 0, 0}
4133 },
4134 { /* names */
4135 "test1",
4136 "iface",
4137 NULL,
4138 },
4139 },
4140 }
4141 },
4142 {
4143 "child_iface",
4144 "{b14b6bb5-904e-4ff9-b247-bd361f7aa002}",
4145 /*kind*/ TKIND_INTERFACE, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(child_iface*),
4146 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 5, /*#func*/ 1,
4147 {
4148 {
4149 /*id*/ 0x60020000, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4150 /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 4, /*#scodes*/ 0, /*flags*/ 0,
4151 {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
4152 { /* params */
4153 {-1, 0, 0}
4154 },
4155 { /* names */
4156 "test2",
4157 NULL,
4158 },
4159 },
4160 }
4161 },
4162 {
4163 "_n",
4164 "{016fe2ec-b2c8-45f8-b23b-39e53a753903}",
4165 /*kind*/ TKIND_RECORD, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(struct _n),
4166 /*helpctx*/ 0x0003, /*version*/ 0x00010002, /*#vtbl*/ 0, /*#func*/ 0
4167 },
4168 {
4169 "n",
4170 "{016fe2ec-b2c8-45f8-b23b-39e53a753902}",
4171 /*kind*/ TKIND_ALIAS, /*flags*/ TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4,
4172 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4173 },
4174 {
4175 "nn",
4176 "{00000000-0000-0000-0000-000000000000}",
4177 /*kind*/ TKIND_ALIAS, /*flags*/ 0, /*align*/ 4, /*size*/ 4,
4178 /*helpctx*/ 0x0003, /*version*/ 0x00010002, /*#vtbl*/ 0, /*#func*/ 0
4179 },
4180 {
4181 "_m",
4182 "{016fe2ec-b2c8-45f8-b23b-39e53a753906}",
4183 /*kind*/ TKIND_RECORD, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(struct _m),
4184 /*helpctx*/ 0x0003, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4185 },
4186 {
4187 "m",
4188 "{016fe2ec-b2c8-45f8-b23b-39e53a753905}",
4189 /*kind*/ TKIND_ALIAS, /*flags*/ TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4,
4190 /*helpctx*/ 0x0000, /*version*/ 0x00010002, /*#vtbl*/ 0, /*#func*/ 0
4191 },
4192 {
4193 "mm",
4194 "{00000000-0000-0000-0000-000000000000}",
4195 /*kind*/ TKIND_ALIAS, /*flags*/ 0, /*align*/ 4, /*size*/ 4,
4196 /*helpctx*/ 0x0003, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4197 },
4198 {
4199 "IDualIface",
4200 "{b14b6bb5-904e-4ff9-b247-bd361f7aaedd}",
4201 /*kind*/ TKIND_DISPATCH, /*flags*/ TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL, /*align*/ 4, /*size*/ sizeof(IDualIface*),
4202 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 7, /*#func*/ 8,
4203 {
4204 {
4205 /*id*/ 0x60000000, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4206 /*#param*/ 2, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
4207 {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
4208 { /* params */
4209 {VT_PTR, -1, PARAMFLAG_FIN},
4210 {VT_PTR, -1, PARAMFLAG_FOUT},
4211 {-1, 0, 0}
4212 },
4213 { /* names */
4214 "QueryInterface",
4215 "riid",
4216 "ppvObj",
4217 NULL,
4218 },
4219 },
4220 {
4221 /*id*/ 0x60000001, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4222 /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 1, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
4223 {VT_UI4, -1, PARAMFLAG_NONE}, /* ret */
4224 { /* params */
4225 {-1, 0, 0}
4226 },
4227 { /* names */
4228 "AddRef",
4229 NULL,
4230 },
4231 },
4232 {
4233 /*id*/ 0x60000002, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4234 /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 2, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
4235 {VT_UI4, -1, PARAMFLAG_NONE}, /* ret */
4236 { /* params */
4237 {-1, 0, 0}
4238 },
4239 { /* names */
4240 "Release",
4241 NULL,
4242 },
4243 },
4244 {
4245 /*id*/ 0x60010000, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4246 /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 3, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
4247 {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
4248 { /* params */
4249 {VT_PTR, -1, PARAMFLAG_FOUT},
4250 {-1, 0, 0}
4251 },
4252 { /* names */
4253 "GetTypeInfoCount",
4254 "pctinfo",
4255 NULL,
4256 },
4257 },
4258 {
4259 /*id*/ 0x60010001, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4260 /*#param*/ 3, /*#opt*/ 0, /*vtbl*/ 4, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
4261 {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
4262 { /* params */
4263 {VT_UINT, -1, PARAMFLAG_FIN},
4264 {VT_UI4, -1, PARAMFLAG_FIN},
4265 {VT_PTR, -1, PARAMFLAG_FOUT},
4266 {-1, 0, 0}
4267 },
4268 { /* names */
4269 "GetTypeInfo",
4270 "itinfo",
4271 "lcid",
4272 "pptinfo",
4273 NULL,
4274 },
4275 },
4276 {
4277 /*id*/ 0x60010002, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4278 /*#param*/ 5, /*#opt*/ 0, /*vtbl*/ 5, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
4279 {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
4280 { /* params */
4281 {VT_PTR, -1, PARAMFLAG_FIN},
4282 {VT_PTR, -1, PARAMFLAG_FIN},
4283 {VT_UINT, -1, PARAMFLAG_FIN},
4284 {VT_UI4, -1, PARAMFLAG_FIN},
4285 {VT_PTR, -1, PARAMFLAG_FOUT},
4286 {-1, 0, 0}
4287 },
4288 { /* names */
4289 "GetIDsOfNames",
4290 "riid",
4291 "rgszNames",
4292 "cNames",
4293 "lcid",
4294 "rgdispid",
4295 NULL,
4296 },
4297 },
4298 {
4299 /*id*/ 0x60010003, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4300 /*#param*/ 8, /*#opt*/ 0, /*vtbl*/ 6, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED,
4301 {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
4302 { /* params */
4303 {VT_I4, -1, PARAMFLAG_FIN},
4304 {VT_PTR, -1, PARAMFLAG_FIN},
4305 {VT_UI4, -1, PARAMFLAG_FIN},
4306 {VT_UI2, -1, PARAMFLAG_FIN},
4307 {VT_PTR, -1, PARAMFLAG_FIN},
4308 {VT_PTR, -1, PARAMFLAG_FOUT},
4309 {VT_PTR, -1, PARAMFLAG_FOUT},
4310 {VT_PTR, -1, PARAMFLAG_FOUT},
4311 {-1, 0, 0}
4312 },
4313 { /* names */
4314 "Invoke",
4315 "dispidMember",
4316 "riid",
4317 "lcid",
4318 "wFlags",
4319 "pdispparams",
4320 "pvarResult",
4321 "pexcepinfo",
4322 "puArgErr",
4323 NULL,
4324 },
4325 },
4326 {
4327 /*id*/ 0x60020000, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4328 /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0,
4329 {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */
4330 { /* params */
4331 {-1, 0, 0}
4332 },
4333 { /* names */
4334 "Test",
4335 NULL,
4336 },
4337 },
4338 }
4339 },
4340 {
4341 "ISimpleIface",
4342 "{ec5dfcd6-eeb0-4cd6-b51e-8030e1dac009}",
4343 /*kind*/ TKIND_INTERFACE, /*flags*/ TYPEFLAG_FDISPATCHABLE, /*align*/ 4, /*size*/ sizeof(ISimpleIface*),
4344 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 8, /*#func*/ 1,
4345 {
4346 {
4347 /*id*/ 0x60020000, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4348 /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0,
4349 {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
4350 { /* params */
4351 {-1, 0, 0}
4352 },
4353 { /* names */
4354 "Test",
4355 NULL,
4356 },
4357 },
4358 }
4359 },
4360 {
4361 "test_struct",
4362 "{4029f190-ca4a-4611-aeb9-673983cb96dd}",
4363 /*kind*/ TKIND_RECORD, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(struct test_struct),
4364 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4365 },
4366 {
4367 "test_struct2",
4368 "{4029f190-ca4a-4611-aeb9-673983cb96de}",
4369 /*kind*/ TKIND_RECORD, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(struct test_struct2),
4370 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4371 },
4372 {
4373 "t_INT",
4374 "{016fe2ec-b2c8-45f8-b23b-39e53a75396a}",
4375 /*kind*/ TKIND_ALIAS, /*flags*/ TYPEFLAG_FRESTRICTED, /*align*/ 4, /*size*/ 4,
4376 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4377 },
4378 {
4379 "a",
4380 "{00000000-0000-0000-0000-000000000000}",
4381 /*kind*/ TKIND_ALIAS, /*flags*/ 0, /*align*/ 4, /*size*/ 4,
4382 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4383 },
4384 {
4385 "_a",
4386 "{00000000-0000-0000-0000-000000000000}",
4387 /*kind*/ TKIND_ENUM, /*flags*/ 0, /*align*/ 4, /*size*/ 4,
4388 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4389 },
4390 {
4391 "aa",
4392 "{00000000-0000-0000-0000-000000000000}",
4393 /*kind*/ TKIND_ENUM, /*flags*/ 0, /*align*/ 4, /*size*/ 4,
4394 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4395 },
4396 {
4397 "_b",
4398 "{00000000-0000-0000-0000-000000000000}",
4399 /*kind*/ TKIND_ENUM, /*flags*/ 0, /*align*/ 4, /*size*/ 4,
4400 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4401 },
4402 {
4403 "bb",
4404 "{00000000-0000-0000-0000-000000000000}",
4405 /*kind*/ TKIND_ENUM, /*flags*/ 0, /*align*/ 4, /*size*/ 4,
4406 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4407 },
4408 {
4409 "c",
4410 "{016fe2ec-b2c8-45f8-b23b-39e53a75396b}",
4411 /*kind*/ TKIND_ALIAS, /*flags*/ 0, /*align*/ 4, /*size*/ 4,
4412 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4413 },
4414 {
4415 "_c",
4416 "{00000000-0000-0000-0000-000000000000}",
4417 /*kind*/ TKIND_ENUM, /*flags*/ 0, /*align*/ 4, /*size*/ 4,
4418 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4419 },
4420 {
4421 "cc",
4422 "{016fe2ec-b2c8-45f8-b23b-39e53a75396c}",
4423 /*kind*/ TKIND_ENUM, /*flags*/ 0, /*align*/ 4, /*size*/ 4,
4424 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4425 },
4426 {
4427 "d",
4428 "{016fe2ec-b2c8-45f8-b23b-39e53a75396d}",
4429 /*kind*/ TKIND_ALIAS, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4,
4430 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4431 },
4432 {
4433 "_d",
4434 "{00000000-0000-0000-0000-000000000000}",
4435 /*kind*/ TKIND_ENUM, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4,
4436 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4437 },
4438 {
4439 "dd",
4440 "{016fe2ec-b2c8-45f8-b23b-39e53a75396e}",
4441 /*kind*/ TKIND_ENUM, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4,
4442 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4443 },
4444 {
4445 "e",
4446 "{016fe2ec-b2c8-45f8-b23b-39e53a753970}",
4447 /*kind*/ TKIND_ALIAS, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4,
4448 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4449 },
4450 {
4451 "_e",
4452 "{00000000-0000-0000-0000-000000000000}",
4453 /*kind*/ TKIND_RECORD, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ sizeof(struct _e),
4454 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4455 },
4456 {
4457 "ee",
4458 "{016fe2ec-b2c8-45f8-b23b-39e53a753971}",
4459 /*kind*/ TKIND_RECORD, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ sizeof(struct ee),
4460 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4461 },
4462 {
4463 "f",
4464 "{016fe2ec-b2c8-45f8-b23b-39e53a753972}",
4465 /*kind*/ TKIND_ALIAS, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4,
4466 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4467 },
4468 {
4469 "_f",
4470 "{00000000-0000-0000-0000-000000000000}",
4471 /*kind*/ TKIND_UNION, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ sizeof(union _f),
4472 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4473 },
4474 {
4475 "ff",
4476 "{016fe2ec-b2c8-45f8-b23b-39e53a753973}",
4477 /*kind*/ TKIND_UNION, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ sizeof(union ff),
4478 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0
4479 },
4480 {
4481 "ITestIface",
4482 "{ec5dfcd6-eeb0-4cd6-b51e-8030e1dac00a}",
4483 /*kind*/ TKIND_INTERFACE, /*flags*/ TYPEFLAG_FDISPATCHABLE, /*align*/ 4, /*size*/ sizeof(ITestIface*),
4484 /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 13, /*#func*/ 6,
4485 {
4486 {
4487 /*id*/ 0x60020000, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4488 /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0,
4489 {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
4490 { /* params */
4491 {VT_USERDEFINED, TKIND_ALIAS, PARAMFLAG_NONE},
4492 {-1, 0, 0}
4493 },
4494 { /* names */
4495 "test1",
4496 "value",
4497 NULL,
4498 },
4499 },
4500 {
4501 /*id*/ 0x60020001, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4502 /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 8, /*#scodes*/ 0, /*flags*/ 0,
4503 {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
4504 { /* params */
4505 {VT_USERDEFINED, TKIND_ENUM, PARAMFLAG_NONE},
4506 {-1, 0, 0}
4507 },
4508 { /* names */
4509 "test2",
4510 "value",
4511 NULL,
4512 },
4513 },
4514 {
4515 /*id*/ 0x60020002, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4516 /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 9, /*#scodes*/ 0, /*flags*/ 0,
4517 {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
4518 { /* params */
4519 {VT_USERDEFINED, TKIND_ALIAS, PARAMFLAG_NONE},
4520 {-1, 0, 0}
4521 },
4522 { /* names */
4523 "test3",
4524 "value",
4525 NULL,
4526 },
4527 },
4528 {
4529 /*id*/ 0x60020003, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4530 /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 10, /*#scodes*/ 0, /*flags*/ 0,
4531 {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
4532 { /* params */
4533 {VT_USERDEFINED, TKIND_ALIAS, PARAMFLAG_NONE},
4534 {-1, 0, 0}
4535 },
4536 { /* names */
4537 "test4",
4538 "value",
4539 NULL,
4540 },
4541 },
4542 {
4543 /*id*/ 0x60020004, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4544 /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 11, /*#scodes*/ 0, /*flags*/ 0,
4545 {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
4546 { /* params */
4547 {VT_USERDEFINED, TKIND_ALIAS, PARAMFLAG_NONE},
4548 {-1, 0, 0}
4549 },
4550 { /* names */
4551 "test5",
4552 "value",
4553 NULL,
4554 },
4555 },
4556 {
4557 /*id*/ 0x60020005, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL,
4558 /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 12, /*#scodes*/ 0, /*flags*/ 0,
4559 {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */
4560 { /* params */
4561 {VT_USERDEFINED, TKIND_ALIAS, PARAMFLAG_NONE},
4562 {-1, 0, 0}
4563 },
4564 { /* names */
4565 "test6",
4566 "value",
4567 NULL,
4568 },
4569 },
4570 }
4571 }
4572 };
4573
4574 #define check_type(elem, info) { \
4575 expect_int((elem)->tdesc.vt, (info)->vt); \
4576 expect_hex(U(*(elem)).paramdesc.wParamFlags, (info)->wParamFlags); \
4577 }
4578
4579 static void test_dump_typelib(const char *name)
4580 {
4581 WCHAR wszName[MAX_PATH];
4582 ITypeLib *typelib;
4583 int ticount = sizeof(info)/sizeof(info[0]);
4584 int iface, func;
4585
4586 MultiByteToWideChar(CP_ACP, 0, name, -1, wszName, MAX_PATH);
4587 ole_check(LoadTypeLibEx(wszName, REGKIND_NONE, &typelib));
4588 expect_eq(ITypeLib_GetTypeInfoCount(typelib), ticount, UINT, "%d");
4589 for (iface = 0; iface < ticount; iface++)
4590 {
4591 const type_info *ti = &info[iface];
4592 ITypeInfo *typeinfo;
4593 TYPEATTR *typeattr;
4594 BSTR bstrIfName;
4595 DWORD help_ctx;
4596
4597 trace("Interface %s\n", ti->name);
4598 ole_check(ITypeLib_GetTypeInfo(typelib, iface, &typeinfo));
4599 ole_check(ITypeLib_GetDocumentation(typelib, iface, &bstrIfName, NULL, &help_ctx, NULL));
4600 expect_wstr_acpval(bstrIfName, ti->name);
4601 SysFreeString(bstrIfName);
4602
4603 ole_check(ITypeInfo_GetTypeAttr(typeinfo, &typeattr));
4604 expect_int(typeattr->typekind, ti->type);
4605 expect_hex(typeattr->wTypeFlags, ti->wTypeFlags);
4606 /* FIXME: remove once widl is fixed */
4607 if (typeattr->typekind == TKIND_ALIAS && typeattr->cbAlignment != ti->cbAlignment)
4608 {
4609 todo_wine /* widl generates broken typelib and typeattr just reflects that */
4610 ok(typeattr->cbAlignment == ti->cbAlignment || broken(typeattr->cbAlignment == 1),
4611 "expected %d, got %d\n", ti->cbAlignment, typeattr->cbAlignment);
4612 todo_wine /* widl generates broken typelib and typeattr just reflects that */
4613 ok(typeattr->cbSizeInstance == ti->cbSizeInstance || broken(typeattr->cbSizeInstance == 0),
4614 "expected %d, got %d\n", ti->cbSizeInstance, typeattr->cbSizeInstance);
4615 }
4616 else
4617 {
4618 expect_int(typeattr->cbAlignment, ti->cbAlignment);
4619 expect_int(typeattr->cbSizeInstance, ti->cbSizeInstance);
4620 }
4621 expect_int(help_ctx, ti->help_ctx);
4622 expect_int(MAKELONG(typeattr->wMinorVerNum, typeattr->wMajorVerNum), ti->version);
4623 expect_int(typeattr->cbSizeVft, ti->cbSizeVft * sizeof(void*));
4624 expect_int(typeattr->cFuncs, ti->cFuncs);
4625
4626 /* compare type uuid */
4627 if (ti->uuid && *ti->uuid)
4628 {
4629 WCHAR guidW[39];
4630 ITypeInfo *typeinfo2;
4631 HRESULT hr;
4632 GUID guid;
4633
4634 MultiByteToWideChar(CP_ACP, 0, ti->uuid, -1, guidW, sizeof(guidW)/sizeof(guidW[0]));
4635 IIDFromString(guidW, &guid);
4636 expect_guid(&guid, &typeattr->guid);
4637
4638 /* check that it's possible to search using this uuid */
4639 typeinfo2 = NULL;
4640 hr = ITypeLib_GetTypeInfoOfGuid(typelib, &guid, &typeinfo2);
4641 ok(hr == S_OK || (IsEqualGUID(&guid, &IID_NULL) && hr == TYPE_E_ELEMENTNOTFOUND), "got 0x%08x\n", hr);
4642 if (hr == S_OK) ITypeInfo_Release(typeinfo2);
4643 }
4644
4645 for (func = 0; func < typeattr->cFuncs; func++)
4646 {
4647 function_info *fn_info = (function_info *)&ti->funcs[func];
4648 FUNCDESC *desc;
4649 BSTR namesTab[256];
4650 UINT cNames;
4651 int i;
4652
4653 trace("Function %s\n", fn_info->names[0]);
4654 ole_check(ITypeInfo_GetFuncDesc(typeinfo, func, &desc));
4655 expect_int(desc->memid, fn_info->memid);
4656 expect_int(desc->funckind, fn_info->funckind);
4657 expect_int(desc->invkind, fn_info->invkind);
4658 expect_int(desc->callconv, fn_info->callconv);
4659 expect_int(desc->cParams, fn_info->cParams);
4660 expect_int(desc->cParamsOpt, fn_info->cParamsOpt);
4661 ok( desc->oVft == fn_info->vtbl_index * sizeof(void*) ||
4662 broken(desc->oVft == fn_info->vtbl_index * 4), /* xp64 */
4663 "desc->oVft got %u\n", desc->oVft );
4664 expect_int(desc->cScodes, fn_info->cScodes);
4665 expect_int(desc->wFuncFlags, fn_info->wFuncFlags);
4666 ole_check(ITypeInfo_GetNames(typeinfo, desc->memid, namesTab, 256, &cNames));
4667 for (i = 0; i < cNames; i++)
4668 {
4669 expect_wstr_acpval(namesTab[i], fn_info->names[i]);
4670 SysFreeString(namesTab[i]);
4671 }
4672 expect_null(fn_info->names[cNames]);
4673
4674 check_type(&desc->elemdescFunc, &fn_info->ret_type);
4675 for (i = 0 ; i < desc->cParams; i++)
4676 {
4677 check_type(&desc->lprgelemdescParam[i], &fn_info->params[i]);
4678
4679 if (desc->lprgelemdescParam[i].tdesc.vt == VT_USERDEFINED)
4680 {
4681 ITypeInfo *param;
4682 TYPEATTR *var_attr;
4683
4684 ole_check(ITypeInfo_GetRefTypeInfo(typeinfo, U(desc->lprgelemdescParam[i].tdesc).hreftype, &param));
4685 ole_check(ITypeInfo_GetTypeAttr(param, &var_attr));
4686
4687 ok(var_attr->typekind == fn_info->params[i].type, "expected %#x, got %#x\n", fn_info->params[i].type, var_attr->typekind);
4688
4689 ITypeInfo_ReleaseTypeAttr(param, var_attr);
4690 ITypeInfo_Release(param);
4691 }
4692 }
4693 expect_int(fn_info->params[desc->cParams].vt, (VARTYPE)-1);
4694
4695 ITypeInfo_ReleaseFuncDesc(typeinfo, desc);
4696 }
4697
4698 ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
4699 ITypeInfo_Release(typeinfo);
4700 }
4701 ITypeLib_Release(typelib);
4702 }
4703
4704 #endif
4705
4706 static void test_create_typelib_lcid(LCID lcid)
4707 {
4708 char filename[MAX_PATH];
4709 WCHAR name[MAX_PATH];
4710 HRESULT hr;
4711 ICreateTypeLib2 *tl;
4712 HANDLE file;
4713 DWORD msft_header[8];
4714 ITypeLib *typelib;
4715 TLIBATTR *attr;
4716 DWORD read;
4717
4718 GetTempFileNameA( ".", "tlb", 0, filename );
4719 MultiByteToWideChar(CP_ACP, 0, filename, -1, name, MAX_PATH);
4720
4721 hr = CreateTypeLib2(SYS_WIN32, name, &tl);
4722 ok(hr == S_OK, "got %08x\n", hr);
4723
4724 hr = ICreateTypeLib2_QueryInterface(tl, &IID_ITypeLib, (void**)&typelib);
4725 ok(hr == S_OK, "got %08x\n", hr);
4726
4727 hr = ITypeLib_GetLibAttr(typelib, &attr);
4728 ok(hr == S_OK, "got %08x\n", hr);
4729 ok(attr->wLibFlags == 0, "flags 0x%x\n", attr->wLibFlags);
4730 ITypeLib_ReleaseTLibAttr(typelib, attr);
4731
4732 hr = ICreateTypeLib2_SetLcid(tl, lcid);
4733 ok(hr == S_OK, "got %08x\n", hr);
4734
4735 hr = ICreateTypeLib2_SetVersion(tl, 3, 4);
4736 ok(hr == S_OK, "got %08x\n", hr);
4737
4738 hr = ICreateTypeLib2_SaveAllChanges(tl);
4739 ok(hr == S_OK, "got %08x\n", hr);
4740
4741 hr = ITypeLib_GetLibAttr(typelib, &attr);
4742 ok(hr == S_OK, "got %08x\n", hr);
4743 ok(attr->wLibFlags == 0, "flags 0x%x\n", attr->wLibFlags);
4744 ITypeLib_ReleaseTLibAttr(typelib, attr);
4745
4746 ITypeLib_Release(typelib);
4747 ICreateTypeLib2_Release(tl);
4748
4749 file = CreateFileA( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
4750 ok( file != INVALID_HANDLE_VALUE, "file creation failed\n" );
4751
4752 ReadFile( file, msft_header, sizeof(msft_header), &read, NULL );
4753 ok(read == sizeof(msft_header), "read %d\n", read);
4754 CloseHandle( file );
4755
4756 ok(msft_header[0] == 0x5446534d, "got %08x\n", msft_header[0]);
4757 ok(msft_header[1] == 0x00010002, "got %08x\n", msft_header[1]);
4758 ok(msft_header[2] == 0xffffffff, "got %08x\n", msft_header[2]);
4759 ok(msft_header[3] == (lcid ? lcid : 0x409), "got %08x (lcid %08x)\n", msft_header[3], lcid);
4760 ok(msft_header[4] == lcid, "got %08x (lcid %08x)\n", msft_header[4], lcid);
4761 ok(msft_header[6] == 0x00040003, "got %08x\n", msft_header[6]);
4762 ok(msft_header[7] == 0, "got %08x\n", msft_header[7]);
4763
4764 /* check flags after loading */
4765 hr = LoadTypeLib(name, &typelib);
4766 ok(hr == S_OK, "got %08x\n", hr);
4767
4768 hr = ITypeLib_GetLibAttr(typelib, &attr);
4769 ok(hr == S_OK, "got %08x\n", hr);
4770 ok(attr->wLibFlags == LIBFLAG_FHASDISKIMAGE, "flags 0x%x\n", attr->wLibFlags);
4771 ITypeLib_ReleaseTLibAttr(typelib, attr);
4772 ITypeLib_Release(typelib);
4773
4774 DeleteFileA(filename);
4775 }
4776
4777 static void test_create_typelibs(void)
4778 {
4779 test_create_typelib_lcid(LOCALE_SYSTEM_DEFAULT);
4780 test_create_typelib_lcid(LOCALE_USER_DEFAULT);
4781 test_create_typelib_lcid(LOCALE_NEUTRAL);
4782
4783 test_create_typelib_lcid(0x009);
4784 test_create_typelib_lcid(0x409);
4785 test_create_typelib_lcid(0x809);
4786
4787 test_create_typelib_lcid(0x007);
4788 test_create_typelib_lcid(0x407);
4789 }
4790
4791
4792 static void test_register_typelib(BOOL system_registration)
4793 {
4794 HRESULT hr;
4795 WCHAR filename[MAX_PATH];
4796 const char *filenameA;
4797 ITypeLib *typelib;
4798 WCHAR uuidW[40];
4799 char key_name[MAX_PATH], uuid[40];
4800 LONG ret, expect_ret;
4801 UINT count, i;
4802 HKEY hkey;
4803 REGSAM opposite = (sizeof(void*) == 8 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY);
4804 BOOL is_wow64 = FALSE;
4805 struct
4806 {
4807 TYPEKIND kind;
4808 WORD flags;
4809 } attrs[13] =
4810 {
4811 { TKIND_INTERFACE, 0 },
4812 { TKIND_INTERFACE, TYPEFLAG_FDISPATCHABLE },
4813 { TKIND_INTERFACE, TYPEFLAG_FOLEAUTOMATION },
4814 { TKIND_INTERFACE, TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FOLEAUTOMATION },
4815 { TKIND_DISPATCH, 0 /* TYPEFLAG_FDUAL - widl clears this flag for non-IDispatch derived interfaces */ },
4816 { TKIND_DISPATCH, 0 /* TYPEFLAG_FDUAL - widl clears this flag for non-IDispatch derived interfaces */ },
4817 { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FDUAL },
4818 { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FDUAL },
4819 { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE },
4820 { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE },
4821 { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE },
4822 { TKIND_INTERFACE, TYPEFLAG_FDISPATCHABLE },
4823 { TKIND_RECORD, 0 }
4824 };
4825
4826 trace("Starting %s typelib registration tests\n",
4827 system_registration ? "system" : "user");
4828
4829 if (!system_registration && (!pRegisterTypeLibForUser || !pUnRegisterTypeLibForUser))
4830 {
4831 win_skip("User typelib registration functions are not available\n");
4832 return;
4833 }
4834
4835 if (pIsWow64Process)
4836 pIsWow64Process(GetCurrentProcess(), &is_wow64);
4837
4838 filenameA = create_test_typelib(3);
4839 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filename, MAX_PATH);
4840
4841 hr = LoadTypeLibEx(filename, REGKIND_NONE, &typelib);
4842 ok(hr == S_OK, "got %08x\n", hr);
4843
4844 if (system_registration)
4845 hr = RegisterTypeLib(typelib, filename, NULL);
4846 else
4847 hr = pRegisterTypeLibForUser(typelib, filename, NULL);
4848 if (hr == TYPE_E_REGISTRYACCESS)
4849 {
4850 win_skip("Insufficient privileges to register typelib in the registry\n");
4851 ITypeLib_Release(typelib);
4852 DeleteFileA(filenameA);
4853 return;
4854 }
4855 ok(hr == S_OK, "got %08x\n", hr);
4856
4857 count = ITypeLib_GetTypeInfoCount(typelib);
4858 ok(count == 13, "got %d\n", count);
4859
4860 for(i = 0; i < count; i++)
4861 {
4862 ITypeInfo *typeinfo;
4863 TYPEATTR *attr;
4864
4865 hr = ITypeLib_GetTypeInfo(typelib, i, &typeinfo);
4866 ok(hr == S_OK, "got %08x\n", hr);
4867
4868 hr = ITypeInfo_GetTypeAttr(typeinfo, &attr);
4869 ok(hr == S_OK, "got %08x\n", hr);
4870
4871 ok(attr->typekind == attrs[i].kind, "%d: got kind %d\n", i, attr->typekind);
4872 ok(attr->wTypeFlags == attrs[i].flags, "%d: got flags %04x\n", i, attr->wTypeFlags);
4873
4874 if(attr->typekind == TKIND_DISPATCH && (attr->wTypeFlags & TYPEFLAG_FDUAL))
4875 {
4876 HREFTYPE reftype;
4877 ITypeInfo *dual_info;
4878 TYPEATTR *dual_attr;
4879
4880 hr = ITypeInfo_GetRefTypeOfImplType(typeinfo, -1, &reftype);
4881 ok(hr == S_OK, "got %08x\n", hr);
4882
4883 hr = ITypeInfo_GetRefTypeInfo(typeinfo, reftype, &dual_info);
4884 ok(hr == S_OK, "got %08x\n", hr);
4885
4886 hr = ITypeInfo_GetTypeAttr(dual_info, &dual_attr);
4887 ok(hr == S_OK, "got %08x\n", hr);
4888
4889 ok(dual_attr->typekind == TKIND_INTERFACE, "%d: got kind %d\n", i, dual_attr->typekind);
4890 ok(dual_attr->wTypeFlags == (TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FOLEAUTOMATION | TYPEFLAG_FDUAL), "%d: got flags %04x\n", i, dual_attr->wTypeFlags);
4891
4892 ITypeInfo_ReleaseTypeAttr(dual_info, dual_attr);
4893 ITypeInfo_Release(dual_info);
4894
4895 }
4896
4897 StringFromGUID2(&attr->guid, uuidW, sizeof(uuidW) / sizeof(uuidW[0]));
4898 WideCharToMultiByte(CP_ACP, 0, uuidW, -1, uuid, sizeof(uuid), NULL, NULL);
4899 sprintf(key_name, "Interface\\%s", uuid);
4900
4901 /* All dispinterfaces will be registered (this includes dual interfaces) as well
4902 as oleautomation interfaces */
4903 if((attr->typekind == TKIND_INTERFACE && (attr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) ||
4904 attr->typekind == TKIND_DISPATCH)
4905 expect_ret = ERROR_SUCCESS;
4906 else
4907 expect_ret = ERROR_FILE_NOT_FOUND;
4908
4909 ret = RegOpenKeyExA(HKEY_CLASSES_ROOT, key_name, 0, KEY_READ, &hkey);
4910 ok(ret == expect_ret, "%d: got %d\n", i, ret);
4911 if(ret == ERROR_SUCCESS) RegCloseKey(hkey);
4912
4913 /* 32-bit typelibs should be registered into both registry bit modes */
4914 if (is_win64 || is_wow64)
4915 {
4916 ret = RegOpenKeyExA(HKEY_CLASSES_ROOT, key_name, 0, KEY_READ | opposite, &hkey);
4917 ok(ret == expect_ret, "%d: got %d\n", i, ret);
4918 if(ret == ERROR_SUCCESS) RegCloseKey(hkey);
4919 }
4920
4921 ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
4922 ITypeInfo_Release(typeinfo);
4923 }
4924
4925 if (system_registration)
4926 hr = UnRegisterTypeLib(&LIBID_register_test, 1, 0, LOCALE_NEUTRAL, is_win64 ? SYS_WIN64 : SYS_WIN32);
4927 else
4928 hr = pUnRegisterTypeLibForUser(&LIBID_register_test, 1, 0, LOCALE_NEUTRAL, is_win64 ? SYS_WIN64 : SYS_WIN32);
4929 ok(hr == S_OK, "got %08x\n", hr);
4930
4931 for(i = 0; i < count; i++)
4932 {
4933 ITypeInfo *typeinfo;
4934 TYPEATTR *attr;
4935
4936 hr = ITypeLib_GetTypeInfo(typelib, i, &typeinfo);
4937 ok(hr == S_OK, "got %08x\n", hr);
4938
4939 hr = ITypeInfo_GetTypeAttr(typeinfo, &attr);
4940 ok(hr == S_OK, "got %08x\n", hr);
4941
4942 if((attr->typekind == TKIND_INTERFACE && (attr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) ||
4943 attr->typekind == TKIND_DISPATCH)
4944 {
4945 StringFromGUID2(&attr->guid, uuidW, sizeof(uuidW) / sizeof(uuidW[0]));
4946 WideCharToMultiByte(CP_ACP, 0, uuidW, -1, uuid, sizeof(uuid), NULL, NULL);
4947 sprintf(key_name, "Interface\\%s", uuid);
4948
4949 ret = RegOpenKeyExA(HKEY_CLASSES_ROOT, key_name, 0, KEY_READ, &hkey);
4950 ok(ret == ERROR_FILE_NOT_FOUND, "Interface registry remains in %s (%d)\n", key_name, i);
4951 if (is_win64 || is_wow64)
4952 {
4953 ret = RegOpenKeyExA(HKEY_CLASSES_ROOT, key_name, 0, KEY_READ | opposite, &hkey);
4954 ok(ret == ERROR_FILE_NOT_FOUND, "Interface registry remains in %s (%d)\n", key_name, i);
4955 }
4956 }
4957 ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
4958 ITypeInfo_Release(typeinfo);
4959 }
4960
4961 ITypeLib_Release(typelib);
4962 DeleteFileA( filenameA );
4963 }
4964
4965 static void test_LoadTypeLib(void)
4966 {
4967 ITypeLib *tl;
4968 HRESULT hres;
4969
4970 static const WCHAR kernel32_dllW[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
4971
4972 hres = LoadTypeLib(kernel32_dllW, &tl);
4973 ok(hres == TYPE_E_CANTLOADLIBRARY, "LoadTypeLib returned: %08x, expected TYPE_E_CANTLOADLIBRARY\n", hres);
4974 }
4975
4976 static void test_SetVarHelpContext(void)
4977 {
4978 static OLECHAR nameW[] = {'n','a','m','e',0};
4979 CHAR filenameA[MAX_PATH];
4980 WCHAR filenameW[MAX_PATH];
4981 ICreateTypeLib2 *ctl;
4982 ICreateTypeInfo *cti;
4983 ITypeLib *tl;
4984 ITypeInfo *ti;
4985 VARDESC desc, *pdesc;
4986 HRESULT hr;
4987 DWORD ctx;
4988 VARIANT v;
4989
4990 GetTempFileNameA(".", "tlb", 0, filenameA);
4991 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filenameW, MAX_PATH);
4992
4993 hr = CreateTypeLib2(SYS_WIN32, filenameW, &ctl);
4994 ok(hr == S_OK, "got %08x\n", hr);
4995
4996 hr = ICreateTypeLib2_CreateTypeInfo(ctl, nameW, TKIND_ENUM, &cti);
4997 ok(hr == S_OK, "got %08x\n", hr);
4998
4999 hr = ICreateTypeInfo_SetVarHelpContext(cti, 0, 0);
5000 ok(hr == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hr);
5001
5002 memset(&desc, 0, sizeof(desc));
5003 desc.memid = MEMBERID_NIL;
5004 desc.elemdescVar.tdesc.vt = VT_INT;
5005 desc.varkind = VAR_CONST;
5006
5007 V_VT(&v) = VT_INT;
5008 V_INT(&v) = 1;
5009 U(desc).lpvarValue = &v;
5010 hr = ICreateTypeInfo_AddVarDesc(cti, 0, &desc);
5011 ok(hr == S_OK, "got %08x\n", hr);
5012
5013 hr = ICreateTypeInfo_SetVarHelpContext(cti, 0, 0);
5014 ok(hr == S_OK, "got %08x\n", hr);
5015
5016 /* another time */
5017 hr = ICreateTypeInfo_SetVarHelpContext(cti, 0, 1);
5018 ok(hr == S_OK, "got %08x\n", hr);
5019
5020 /* wrong index now */
5021 hr = ICreateTypeInfo_SetVarHelpContext(cti, 1, 0);
5022 ok(hr == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hr);
5023
5024 ICreateTypeInfo_Release(cti);
5025
5026 hr = ICreateTypeLib2_SaveAllChanges(ctl);
5027 ok(hr == S_OK, "got: %08x\n", hr);
5028
5029 ICreateTypeLib2_Release(ctl);
5030
5031 hr = LoadTypeLib(filenameW, &tl);
5032 ok(hr == S_OK, "got: %08x\n", hr);
5033
5034 hr = ITypeLib_GetTypeInfo(tl, 0, &ti);
5035 ok(hr == S_OK, "got %08x\n", hr);
5036
5037 hr = ITypeInfo_GetVarDesc(ti, 0, &pdesc);
5038 ok(hr == S_OK, "got %08x\n", hr);
5039 ok(pdesc->memid == 0x40000000, "got wrong memid: %x\n", pdesc->memid);
5040 ok(pdesc->elemdescVar.tdesc.vt == VT_INT, "got wrong vardesc type: %u\n", pdesc->elemdescVar.tdesc.vt);
5041 ok(pdesc->varkind == VAR_CONST, "got wrong varkind: %u\n", pdesc->varkind);
5042 ok(V_VT(U(*pdesc).lpvarValue) == VT_INT, "got wrong value type: %u\n", V_VT(U(*pdesc).lpvarValue));
5043 ok(V_INT(U(*pdesc).lpvarValue) == 1, "got wrong value: 0x%x\n", V_INT(U(*pdesc).lpvarValue));
5044
5045 hr = ITypeInfo_GetDocumentation(ti, pdesc->memid, NULL, NULL, &ctx, NULL);
5046 ok(hr == S_OK, "got %08x\n", hr);
5047 ok(ctx == 1, "got wrong help context: 0x%x\n", ctx);
5048
5049 ITypeInfo_ReleaseVarDesc(ti, pdesc);
5050 ITypeInfo_Release(ti);
5051 ITypeLib_Release(tl);
5052
5053 DeleteFileA(filenameA);
5054 }
5055
5056 static void test_SetFuncAndParamNames(void)
5057 {
5058 static OLECHAR nameW[] = {'n','a','m','e',0};
5059 static OLECHAR name2W[] = {'n','a','m','e','2',0};
5060 static OLECHAR prop[] = {'p','r','o','p',0};
5061 static OLECHAR *propW[] = {prop};
5062 static OLECHAR func[] = {'f','u','n','c',0};
5063 static OLECHAR *funcW[] = {func, NULL};
5064 CHAR filenameA[MAX_PATH];
5065 WCHAR filenameW[MAX_PATH];
5066 ICreateTypeLib2 *ctl;
5067 ICreateTypeInfo *cti;
5068 ITypeLib *tl;
5069 ITypeInfo *infos[3];
5070 MEMBERID memids[3];
5071 FUNCDESC funcdesc;
5072 ELEMDESC edesc;
5073 HRESULT hr;
5074 USHORT found;
5075
5076 GetTempFileNameA(".", "tlb", 0, filenameA);
5077 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filenameW, MAX_PATH);
5078
5079 hr = CreateTypeLib2(SYS_WIN32, filenameW, &ctl);
5080 ok(hr == S_OK, "got %08x\n", hr);
5081
5082 hr = ICreateTypeLib2_CreateTypeInfo(ctl, nameW, TKIND_DISPATCH, &cti);
5083 ok(hr == S_OK, "got %08x\n", hr);
5084
5085 /* get method */
5086 memset(&funcdesc, 0, sizeof(FUNCDESC));
5087 funcdesc.funckind = FUNC_DISPATCH;
5088 funcdesc.callconv = CC_STDCALL;
5089 funcdesc.elemdescFunc.tdesc.vt = VT_VOID;
5090 funcdesc.wFuncFlags = FUNCFLAG_FBINDABLE;
5091
5092 /* put method */
5093 memset(&edesc, 0, sizeof(edesc));
5094 edesc.tdesc.vt = VT_BSTR;
5095 U(edesc).idldesc.dwReserved = 0;
5096 U(edesc).idldesc.wIDLFlags = IDLFLAG_FIN;
5097
5098 funcdesc.lprgelemdescParam = &edesc;
5099 funcdesc.invkind = INVOKE_PROPERTYPUT;
5100 funcdesc.cParams = 1;
5101
5102 hr = ICreateTypeInfo_AddFuncDesc(cti, 0, &funcdesc);
5103 ok(hr == S_OK, "got 0x%08x\n", hr);
5104
5105 /* setter name */
5106 hr = ICreateTypeInfo_SetFuncAndParamNames(cti, 0, propW, 1);
5107 ok(hr == S_OK, "got 0x%08x\n", hr);
5108
5109 /* putref method */
5110 funcdesc.invkind = INVOKE_PROPERTYPUTREF;
5111 hr = ICreateTypeInfo_AddFuncDesc(cti, 1, &funcdesc);
5112 ok(hr == S_OK, "got 0x%08x\n", hr);
5113
5114 /* putref name */
5115 hr = ICreateTypeInfo_SetFuncAndParamNames(cti, 1, propW, 1);
5116 ok(hr == S_OK, "got 0x%08x\n", hr);
5117
5118 funcdesc.invkind = INVOKE_PROPERTYGET;
5119 funcdesc.cParams = 0;
5120 hr = ICreateTypeInfo_AddFuncDesc(cti, 2, &funcdesc);
5121 ok(hr == S_OK, "got 0x%08x\n", hr);
5122
5123 /* getter name */
5124 hr = ICreateTypeInfo_SetFuncAndParamNames(cti, 2, propW, 1);
5125 ok(hr == S_OK, "got 0x%08x\n", hr);
5126
5127 hr = ICreateTypeInfo_AddFuncDesc(cti, 3, &funcdesc);
5128 ok(hr == S_OK, "got 0x%08x\n", hr);
5129
5130 /* getter name again */
5131 hr = ICreateTypeInfo_SetFuncAndParamNames(cti, 3, propW, 1);
5132 ok(hr == TYPE_E_AMBIGUOUSNAME, "got 0x%08x\n", hr);
5133
5134 /* regular function */
5135 funcdesc.invkind = INVOKE_FUNC;
5136 funcdesc.cParams = 1;
5137 hr = ICreateTypeInfo_AddFuncDesc(cti, 4, &funcdesc);
5138 ok(hr == S_OK, "got 0x%08x\n", hr);
5139
5140 hr = ICreateTypeInfo_SetFuncAndParamNames(cti, 4, funcW, 2);
5141 ok(hr == S_OK, "got 0x%08x\n", hr);
5142
5143 ICreateTypeInfo_Release(cti);
5144
5145 hr = ICreateTypeLib2_CreateTypeInfo(ctl, name2W, TKIND_INTERFACE, &cti);
5146 ok(hr == S_OK, "got %08x\n", hr);
5147
5148 funcdesc.funckind = FUNC_PUREVIRTUAL;
5149 funcdesc.invkind = INVOKE_FUNC;
5150 funcdesc.cParams = 0;
5151 funcdesc.lprgelemdescParam = NULL;
5152 hr = ICreateTypeInfo_AddFuncDesc(cti, 0, &funcdesc);
5153 ok(hr == S_OK, "got 0x%08x\n", hr);
5154
5155 hr = ICreateTypeInfo_SetFuncAndParamNames(cti, 0, funcW, 1);
5156 ok(hr == S_OK, "got 0x%08x\n", hr);
5157
5158 ICreateTypeInfo_Release(cti);
5159
5160 hr = ICreateTypeLib2_QueryInterface(ctl, &IID_ITypeLib, (void**)&tl);
5161 ok(hr == S_OK, "got %08x\n", hr);
5162
5163 found = 1;
5164 memset(infos, 0, sizeof(infos));
5165 memids[0] = 0xdeadbeef;
5166 memids[1] = 0xdeadbeef;
5167 memids[2] = 0xdeadbeef;
5168 hr = ITypeLib_FindName(tl, func, 0, infos, memids, &found);
5169 ok(hr == S_OK, "got %08x\n", hr);
5170 ok(found == 1, "got wrong count: %u\n", found);
5171 ok(infos[0] && !infos[1] && !infos[2], "got wrong typeinfo\n");
5172 ok(memids[0] == 0, "got wrong memid[0]\n");
5173 ok(memids[1] == 0xdeadbeef && memids[2] == 0xdeadbeef, "got wrong memids\n");
5174
5175 found = 3;
5176 memset(infos, 0, sizeof(infos));
5177 memids[0] = 0xdeadbeef;
5178 memids[1] = 0xdeadbeef;
5179 memids[2] = 0xdeadbeef;
5180 hr = ITypeLib_FindName(tl, func, 0, infos, memids, &found);
5181 ok(hr == S_OK, "got %08x\n", hr);
5182 ok(found == 2, "got wrong count: %u\n", found);
5183 ok(infos[0] && infos[1] && infos[0] != infos[1], "got same typeinfo\n");
5184 ok(memids[0] == 0, "got wrong memid[0]\n");
5185 ok(memids[1] == 0, "got wrong memid[1]\n");
5186
5187 ITypeLib_Release(tl);
5188 ICreateTypeLib2_Release(ctl);
5189 DeleteFileA(filenameA);
5190 }
5191
5192 static void test_SetDocString(void)
5193 {
5194 static OLECHAR nameW[] = {'n','a','m','e',0};
5195 static OLECHAR name2W[] = {'n','a','m','e','2',0};
5196 static OLECHAR doc1W[] = {'d','o','c','1',0};
5197 static OLECHAR doc2W[] = {'d','o','c','2',0};
5198 static OLECHAR var_nameW[] = {'v','a','r','n','a','m','e',0};
5199 CHAR filenameA[MAX_PATH];
5200 WCHAR filenameW[MAX_PATH];
5201 ICreateTypeLib2 *ctl;
5202 ICreateTypeInfo *cti;
5203 ITypeLib *tl;
5204 ITypeInfo *ti;
5205 BSTR namestr, docstr;
5206 VARDESC desc, *pdesc;
5207 FUNCDESC funcdesc, *pfuncdesc;
5208 HRESULT hr;
5209 VARIANT v;
5210
5211 GetTempFileNameA(".", "tlb", 0, filenameA);
5212 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filenameW, MAX_PATH);
5213
5214 hr = CreateTypeLib2(SYS_WIN32, filenameW, &ctl);
5215 ok(hr == S_OK, "got %08x\n", hr);
5216
5217 hr = ICreateTypeLib2_CreateTypeInfo(ctl, nameW, TKIND_ENUM, &cti);
5218 ok(hr == S_OK, "got %08x\n", hr);
5219
5220 hr = ICreateTypeInfo_SetVarDocString(cti, 0, doc1W);
5221 ok(hr == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hr);
5222
5223 hr = ICreateTypeInfo_SetVarDocString(cti, 0, NULL);
5224 ok(hr == E_INVALIDARG, "got %08x\n", hr);
5225
5226 memset(&desc, 0, sizeof(desc));
5227 desc.memid = MEMBERID_NIL;
5228 desc.elemdescVar.tdesc.vt = VT_INT;
5229 desc.varkind = VAR_CONST;
5230
5231 V_VT(&v) = VT_INT;
5232 V_INT(&v) = 1;
5233 U(desc).lpvarValue = &v;
5234 hr = ICreateTypeInfo_AddVarDesc(cti, 0, &desc);
5235 ok(hr == S_OK, "got %08x\n", hr);
5236
5237 hr = ICreateTypeInfo_SetVarName(cti, 0, NULL);
5238 ok(hr == E_INVALIDARG, "got %08x\n", hr);
5239
5240 hr = ICreateTypeInfo_SetVarName(cti, 1, var_nameW);
5241 ok(hr == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hr);
5242
5243 hr = ICreateTypeInfo_SetVarName(cti, 0, var_nameW);
5244 ok(hr == S_OK, "got %08x\n", hr);
5245
5246 hr = ICreateTypeInfo_SetVarDocString(cti, 0, NULL);
5247 ok(hr == E_INVALIDARG, "got %08x\n", hr);
5248
5249 hr = ICreateTypeInfo_SetVarDocString(cti, 0, doc1W);
5250 ok(hr == S_OK, "got %08x\n", hr);
5251
5252 /* already set */
5253 hr = ICreateTypeInfo_SetVarDocString(cti, 0, doc2W);
5254 ok(hr == S_OK, "got %08x\n", hr);
5255
5256 /* wrong index now */
5257 hr = ICreateTypeInfo_SetVarDocString(cti, 1, doc1W);
5258 ok(hr == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hr);
5259
5260 ICreateTypeInfo_Release(cti);
5261
5262 hr = ICreateTypeLib2_CreateTypeInfo(ctl, name2W, TKIND_INTERFACE, &cti);
5263 ok(hr == S_OK, "got %08x\n", hr);
5264
5265 hr = ICreateTypeInfo_SetFuncDocString(cti, 0, doc1W);
5266 ok(hr == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hr);
5267
5268 hr = ICreateTypeInfo_SetFuncDocString(cti, 0, NULL);
5269 ok(hr == E_INVALIDARG, "got %08x\n", hr);
5270
5271 memset(&funcdesc, 0, sizeof(funcdesc));
5272 funcdesc.memid = MEMBERID_NIL;
5273 funcdesc.funckind = FUNC_PUREVIRTUAL;
5274 funcdesc.invkind = INVOKE_FUNC;
5275 funcdesc.callconv = CC_STDCALL;
5276
5277 hr = ICreateTypeInfo_AddFuncDesc(cti, 0, &funcdesc);
5278 ok(hr == S_OK, "got %08x\n", hr);
5279
5280 hr = ICreateTypeInfo_SetFuncDocString(cti, 0, doc1W);
5281 ok(hr == S_OK, "got %08x\n", hr);
5282
5283 ICreateTypeInfo_Release(cti);
5284
5285 hr = ICreateTypeLib2_SaveAllChanges(ctl);
5286 ok(hr == S_OK, "got: %08x\n", hr);
5287
5288 ICreateTypeLib2_Release(ctl);
5289
5290 hr = LoadTypeLib(filenameW, &tl);
5291 ok(hr == S_OK, "got: %08x\n", hr);
5292
5293 hr = ITypeLib_GetTypeInfo(tl, 0, &ti);
5294 ok(hr == S_OK, "got %08x\n", hr);
5295
5296 hr = ITypeInfo_GetVarDesc(ti, 0, &pdesc);
5297 ok(hr == S_OK, "got %08x\n", hr);
5298 ok(pdesc->memid == 0x40000000, "got wrong memid: %x\n", pdesc->memid);
5299 ok(pdesc->elemdescVar.tdesc.vt == VT_INT, "got wrong vardesc type: %u\n", pdesc->elemdescVar.tdesc.vt);
5300 ok(pdesc->varkind == VAR_CONST, "got wrong varkind: %u\n", pdesc->varkind);
5301 ok(V_VT(U(*pdesc).lpvarValue) == VT_INT, "got wrong value type: %u\n", V_VT(U(*pdesc).lpvarValue));
5302 ok(V_INT(U(*pdesc).lpvarValue) == 1, "got wrong value: 0x%x\n", V_INT(U(*pdesc).lpvarValue));
5303
5304 hr = ITypeInfo_GetDocumentation(ti, pdesc->memid, &namestr, &docstr, NULL, NULL);
5305 ok(hr == S_OK, "got %08x\n", hr);
5306 ok(memcmp(namestr, var_nameW, sizeof(var_nameW)) == 0, "got wrong name: %s\n", wine_dbgstr_w(namestr));
5307 ok(memcmp(docstr, doc2W, sizeof(doc2W)) == 0, "got wrong docstring: %s\n", wine_dbgstr_w(docstr));
5308
5309 SysFreeString(namestr);
5310 SysFreeString(docstr);
5311
5312 ITypeInfo_ReleaseVarDesc(ti, pdesc);
5313 ITypeInfo_Release(ti);
5314
5315 hr = ITypeLib_GetTypeInfo(tl, 1, &ti);
5316 ok(hr == S_OK, "got %08x\n", hr);
5317
5318 hr = ITypeInfo_GetFuncDesc(ti, 0, &pfuncdesc);
5319 ok(hr == S_OK, "got %08x\n", hr);
5320 ok(pfuncdesc->memid == 0x60000000, "got wrong memid: %x\n", pfuncdesc->memid);
5321 ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got wrong funckind: %x\n", pfuncdesc->funckind);
5322 ok(pfuncdesc->invkind == INVOKE_FUNC, "got wrong invkind: %x\n", pfuncdesc->invkind);
5323 ok(pfuncdesc->callconv == CC_STDCALL, "got wrong callconv: %x\n", pfuncdesc->callconv);
5324
5325 hr = ITypeInfo_GetDocumentation(ti, pfuncdesc->memid, &namestr, &docstr, NULL, NULL);
5326 ok(hr == S_OK, "got %08x\n", hr);
5327 ok(namestr == NULL, "got wrong name: %s\n", wine_dbgstr_w(namestr));
5328 ok(memcmp(docstr, doc1W, sizeof(doc1W)) == 0, "got wrong docstring: %s\n", wine_dbgstr_w(docstr));
5329
5330 SysFreeString(docstr);
5331
5332 ITypeInfo_ReleaseFuncDesc(ti, pfuncdesc);
5333 ITypeInfo_Release(ti);
5334
5335 ITypeLib_Release(tl);
5336
5337 DeleteFileA(filenameA);
5338 }
5339
5340 static void test_FindName(void)
5341 {
5342 static const WCHAR invalidW[] = {'i','n','v','a','l','i','d',0};
5343 WCHAR buffW[100];
5344 MEMBERID memid;
5345 ITypeInfo *ti;
5346 ITypeLib *tl;
5347 HRESULT hr;
5348 UINT16 c;
5349
5350 hr = LoadTypeLib(wszStdOle2, &tl);
5351 ok(hr == S_OK, "got 0x%08x\n", hr);
5352
5353 hr = ITypeLib_FindName(tl, NULL, 0, NULL, NULL, NULL);
5354 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
5355
5356 lstrcpyW(buffW, wszGUID);
5357 hr = ITypeLib_FindName(tl, buffW, 0, NULL, NULL, NULL);
5358 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
5359
5360 c = 0;
5361 ti = (void*)0xdeadbeef;
5362 hr = ITypeLib_FindName(tl, buffW, 0, &ti, NULL, &c);
5363 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
5364 ok(c == 0, "got %d\n", c);
5365 ok(ti == (void*)0xdeadbeef, "got %p\n", ti);
5366
5367 c = 1;
5368 ti = (void*)0xdeadbeef;
5369 hr = ITypeLib_FindName(tl, buffW, 0, &ti, NULL, &c);
5370 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
5371 ok(c == 1, "got %d\n", c);
5372 ok(ti == (void*)0xdeadbeef, "got %p\n", ti);
5373
5374 c = 1;
5375 memid = 0;
5376 ti = (void*)0xdeadbeef;
5377 hr = ITypeLib_FindName(tl, buffW, 0, &ti, &memid, &c);
5378 ok(hr == S_OK, "got 0x%08x\n", hr);
5379 ok(memid == MEMBERID_NIL, "got %d\n", memid);
5380 ok(!lstrcmpW(buffW, wszGUID), "got %s\n", wine_dbgstr_w(buffW));
5381 ok(c == 1, "got %d\n", c);
5382 ITypeInfo_Release(ti);
5383
5384 c = 1;
5385 memid = 0;
5386 lstrcpyW(buffW, wszguid);
5387 ti = (void*)0xdeadbeef;
5388 hr = ITypeLib_FindName(tl, buffW, 0, &ti, &memid, &c);
5389 ok(hr == S_OK, "got 0x%08x\n", hr);
5390 todo_wine {
5391 ok(memid == MEMBERID_NIL, "got %d\n", memid);
5392 ok(!lstrcmpW(buffW, wszGUID), "got %s\n", wine_dbgstr_w(buffW));
5393 ok(c == 1, "got %d\n", c);
5394 }
5395 if (c == 1)
5396 ITypeInfo_Release(ti);
5397
5398 c = 1;
5399 memid = -1;
5400 lstrcpyW(buffW, invalidW);
5401 ti = (void*)0xdeadbeef;
5402 hr = ITypeLib_FindName(tl, buffW, 0, &ti, &memid, &c);
5403 ok(hr == S_OK, "got 0x%08x\n", hr);
5404 ok(memid == MEMBERID_NIL, "got %d\n", memid);
5405 ok(!lstrcmpW(buffW, invalidW), "got %s\n", wine_dbgstr_w(buffW));
5406 ok(c == 0, "got %d\n", c);
5407 ok(ti == (void*)0xdeadbeef, "got %p\n", ti);
5408
5409 ITypeLib_Release(tl);
5410 }
5411
5412 static void test_TypeInfo2_GetContainingTypeLib(void)
5413 {
5414 static const WCHAR test[] = {'t','e','s','t','.','t','l','b',0};
5415 static OLECHAR testTI[] = {'t','e','s','t','T','y','p','e','I','n','f','o',0};
5416
5417 ICreateTypeLib2 *ctl2;
5418 ICreateTypeInfo *cti;
5419 ITypeInfo2 *ti2;
5420 ITypeLib *tl;
5421 UINT Index;
5422 HRESULT hr;
5423
5424 hr = CreateTypeLib2(SYS_WIN32, test, &ctl2);
5425 ok_ole_success(hr, CreateTypeLib2);
5426
5427 hr = ICreateTypeLib2_CreateTypeInfo(ctl2, testTI, TKIND_DISPATCH, &cti);
5428 ok_ole_success(hr, ICreateTypeLib2_CreateTypeInfo);
5429
5430 hr = ICreateTypeInfo_QueryInterface(cti, &IID_ITypeInfo2, (void**)&ti2);
5431 ok_ole_success(hr, ICreateTypeInfo2_QueryInterface);
5432
5433 tl = NULL;
5434 Index = 888;
5435 hr = ITypeInfo2_GetContainingTypeLib(ti2, &tl, &Index);
5436 ok_ole_success(hr, ITypeInfo2_GetContainingTypeLib);
5437 ok(tl != NULL, "ITypeInfo2_GetContainingTypeLib returned empty TypeLib\n");
5438 ok(Index == 0, "ITypeInfo2_GetContainingTypeLib returned Index = %u, expected 0\n", Index);
5439 if(tl) ITypeLib_Release(tl);
5440
5441 tl = NULL;
5442 hr = ITypeInfo2_GetContainingTypeLib(ti2, &tl, NULL);
5443 ok_ole_success(hr, ITypeInfo2_GetContainingTypeLib);
5444 ok(tl != NULL, "ITypeInfo2_GetContainingTypeLib returned empty TypeLib\n");
5445 if(tl) ITypeLib_Release(tl);
5446
5447 Index = 888;
5448 hr = ITypeInfo2_GetContainingTypeLib(ti2, NULL, &Index);
5449 ok_ole_success(hr, ITypeInfo2_GetContainingTypeLib);
5450 ok(Index == 0, "ITypeInfo2_GetContainingTypeLib returned Index = %u, expected 0\n", Index);
5451
5452 hr = ITypeInfo2_GetContainingTypeLib(ti2, NULL, NULL);
5453 ok_ole_success(hr, ITypeInfo2_GetContainingTypeLib);
5454
5455 ITypeInfo2_Release(ti2);
5456 ICreateTypeInfo_Release(cti);
5457 ICreateTypeLib2_Release(ctl2);
5458 }
5459
5460 static void create_manifest_file(const char *filename, const char *manifest)
5461 {
5462 HANDLE file;
5463 DWORD size;
5464
5465 file = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
5466 FILE_ATTRIBUTE_NORMAL, NULL);
5467 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
5468 WriteFile(file, manifest, strlen(manifest), &size, NULL);
5469 CloseHandle(file);
5470 }
5471
5472 static HANDLE create_actctx(const char *file)
5473 {
5474 WCHAR path[MAX_PATH];
5475 ACTCTXW actctx;
5476 HANDLE handle;
5477
5478 MultiByteToWideChar(CP_ACP, 0, file, -1, path, MAX_PATH);
5479 memset(&actctx, 0, sizeof(ACTCTXW));
5480 actctx.cbSize = sizeof(ACTCTXW);
5481 actctx.lpSource = path;
5482
5483 handle = pCreateActCtxW(&actctx);
5484 ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError());
5485
5486 ok(actctx.cbSize == sizeof(actctx), "actctx.cbSize=%d\n", actctx.cbSize);
5487 ok(actctx.dwFlags == 0, "actctx.dwFlags=%d\n", actctx.dwFlags);
5488 ok(actctx.lpSource == path, "actctx.lpSource=%p\n", actctx.lpSource);
5489 ok(actctx.wProcessorArchitecture == 0, "actctx.wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
5490 ok(actctx.wLangId == 0, "actctx.wLangId=%d\n", actctx.wLangId);
5491 ok(actctx.lpAssemblyDirectory == NULL, "actctx.lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
5492 ok(actctx.lpResourceName == NULL, "actctx.lpResourceName=%p\n", actctx.lpResourceName);
5493 ok(actctx.lpApplicationName == NULL, "actctx.lpApplicationName=%p\n",
5494 actctx.lpApplicationName);
5495 ok(actctx.hModule == NULL, "actctx.hModule=%p\n", actctx.hModule);
5496
5497 return handle;
5498 }
5499
5500 static const char manifest_dep[] =
5501 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
5502 "<assemblyIdentity version=\"1.2.3.4\" name=\"testdep\" type=\"win32\" processorArchitecture=\"" ARCH "\"/>"
5503 "<file name=\"test_actctx_tlb.tlb\">"
5504 " <typelib tlbid=\"{d96d8a3e-78b6-4c8d-8f27-059db959be8a}\" version=\"2.7\" helpdir=\"\" resourceid=\"409\""
5505 " flags=\"Restricted,cONTROL\""
5506 " />"
5507 "</file>"
5508 "<file name=\"test_actctx_tlb2.tlb\">"
5509 " <typelib tlbid=\"{a2cfdbd3-2bbf-4b1c-a414-5a5904e634c9}\" version=\"2.0\" helpdir=\"\" resourceid=\"409\""
5510 " flags=\"RESTRICTED,CONTROL\""
5511 " />"
5512 "</file>"
5513 "</assembly>";
5514
5515 static const char manifest_main[] =
5516 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
5517 "<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
5518 "<dependency>"
5519 " <dependentAssembly>"
5520 " <assemblyIdentity type=\"win32\" name=\"testdep\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH "\" />"
5521 " </dependentAssembly>"
5522 "</dependency>"
5523 "</assembly>";
5524
5525 static void test_LoadRegTypeLib(void)
5526 {
5527 LCID lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5528 LCID lcid_ru = MAKELCID(MAKELANGID(LANG_RUSSIAN, SUBLANG_NEUTRAL), SORT_DEFAULT);
5529 ULONG_PTR cookie;
5530 TLIBATTR *attr;
5531 HANDLE handle;
5532 ITypeLib *tl;
5533 HRESULT hr;
5534 BSTR path;
5535 BOOL ret;
5536
5537 if (!pActivateActCtx)
5538 {
5539 win_skip("Activation contexts not supported, skipping LoadRegTypeLib tests\n");
5540 return;
5541 }
5542
5543 create_manifest_file("testdep.manifest", manifest_dep);
5544 create_manifest_file("main.manifest", manifest_main);
5545
5546 handle = create_actctx("main.manifest");
5547 DeleteFileA("testdep.manifest");
5548 DeleteFileA("main.manifest");
5549
5550 /* create typelib file */
5551 write_typelib(1, "test_actctx_tlb.tlb");
5552 write_typelib(3, "test_actctx_tlb2.tlb");
5553
5554 hr = LoadRegTypeLib(&LIBID_TestTypelib, 1, 0, LOCALE_NEUTRAL, &tl);
5555 ok(hr == TYPE_E_LIBNOTREGISTERED, "got 0x%08x\n", hr);
5556
5557 hr = LoadRegTypeLib(&LIBID_register_test, 1, 0, LOCALE_NEUTRAL, &tl);
5558 ok(hr == TYPE_E_LIBNOTREGISTERED, "got 0x%08x\n", hr);
5559
5560 hr = QueryPathOfRegTypeLib(&LIBID_TestTypelib, 2, 0, LOCALE_NEUTRAL, &path);
5561 ok(hr == TYPE_E_LIBNOTREGISTERED, "got 0x%08x\n", hr);
5562
5563 ret = pActivateActCtx(handle, &cookie);
5564 ok(ret, "ActivateActCtx failed: %u\n", GetLastError());
5565
5566 path = NULL;
5567 hr = QueryPathOfRegTypeLib(&LIBID_TestTypelib, 2, 0, LOCALE_NEUTRAL, &path);
5568 ok(hr == S_OK, "got 0x%08x\n", hr);
5569 SysFreeString(path);
5570
5571 path = NULL;
5572 hr = QueryPathOfRegTypeLib(&LIBID_TestTypelib, 2, 0, lcid_en, &path);
5573 ok(hr == S_OK, "got 0x%08x\n", hr);
5574 SysFreeString(path);
5575
5576 path = NULL;
5577 hr = QueryPathOfRegTypeLib(&LIBID_TestTypelib, 2, 0, lcid_ru, &path);
5578 ok(hr == S_OK, "got 0x%08x\n", hr);
5579 SysFreeString(path);
5580
5581 hr = QueryPathOfRegTypeLib(&LIBID_TestTypelib, 2, 8, LOCALE_NEUTRAL, &path);
5582 ok(hr == TYPE_E_LIBNOTREGISTERED || broken(hr == S_OK) /* winxp */, "got 0x%08x\n", hr);
5583
5584 path = NULL;
5585 hr = QueryPathOfRegTypeLib(&LIBID_TestTypelib, 2, 7, LOCALE_NEUTRAL, &path);
5586 ok(hr == S_OK, "got 0x%08x\n", hr);
5587 SysFreeString(path);
5588
5589 path = NULL;
5590 hr = QueryPathOfRegTypeLib(&LIBID_TestTypelib, 1, 0, LOCALE_NEUTRAL, &path);
5591 ok(hr == TYPE_E_LIBNOTREGISTERED || broken(hr == S_OK) /* winxp */, "got 0x%08x\n", hr);
5592 SysFreeString(path);
5593
5594 /* manifest version is 2.0, actual is 1.0 */
5595 hr = LoadRegTypeLib(&LIBID_register_test, 1, 0, LOCALE_NEUTRAL, &tl);
5596 ok(hr == TYPE_E_LIBNOTREGISTERED || broken(hr == S_OK) /* winxp */, "got 0x%08x\n", hr);
5597 if (hr == S_OK) ITypeLib_Release(tl);
5598
5599 hr = LoadRegTypeLib(&LIBID_register_test, 2, 0, LOCALE_NEUTRAL, &tl);
5600 ok(hr == TYPE_E_LIBNOTREGISTERED, "got 0x%08x\n", hr);
5601
5602 /* manifest version is 2.7, actual is 2.5 */
5603 hr = LoadRegTypeLib(&LIBID_TestTypelib, 2, 0, LOCALE_NEUTRAL, &tl);
5604 ok(hr == S_OK, "got 0x%08x\n", hr);
5605 if (hr == S_OK) ITypeLib_Release(tl);
5606
5607 hr = LoadRegTypeLib(&LIBID_TestTypelib, 2, 1, LOCALE_NEUTRAL, &tl);
5608 ok(hr == S_OK, "got 0x%08x\n", hr);
5609 if (hr == S_OK) ITypeLib_Release(tl);
5610
5611 hr = LoadRegTypeLib(&LIBID_TestTypelib, 2, 0, lcid_en, &tl);
5612 ok(hr == S_OK, "got 0x%08x\n", hr);
5613 if (hr == S_OK) ITypeLib_Release(tl);
5614
5615 hr = LoadRegTypeLib(&LIBID_TestTypelib, 2, 0, lcid_ru, &tl);
5616 ok(hr == S_OK, "got 0x%08x\n", hr);
5617 if (hr == S_OK) ITypeLib_Release(tl);
5618
5619 hr = LoadRegTypeLib(&LIBID_TestTypelib, 2, 7, LOCALE_NEUTRAL, &tl);
5620 ok(hr == TYPE_E_LIBNOTREGISTERED, "got 0x%08x\n", hr);
5621
5622 hr = LoadRegTypeLib(&LIBID_TestTypelib, 2, 5, LOCALE_NEUTRAL, &tl);
5623 ok(hr == S_OK, "got 0x%08x\n", hr);
5624
5625 hr = ITypeLib_GetLibAttr(tl, &attr);
5626 ok(hr == S_OK, "got 0x%08x\n", hr);
5627
5628 ok(attr->lcid == 0, "got %x\n", attr->lcid);
5629 ok(attr->wMajorVerNum == 2, "got %d\n", attr->wMajorVerNum);
5630 ok(attr->wMinorVerNum == 5, "got %d\n", attr->wMinorVerNum);
5631 ok(attr->wLibFlags == LIBFLAG_FHASDISKIMAGE, "got %x\n", attr->wLibFlags);
5632
5633 ITypeLib_ReleaseTLibAttr(tl, attr);
5634 ITypeLib_Release(tl);
5635
5636 hr = LoadRegTypeLib(&LIBID_TestTypelib, 1, 7, LOCALE_NEUTRAL, &tl);
5637 ok(hr == TYPE_E_LIBNOTREGISTERED, "got 0x%08x\n", hr);
5638
5639 DeleteFileA("test_actctx_tlb.tlb");
5640 DeleteFileA("test_actctx_tlb2.tlb");
5641
5642 ret = pDeactivateActCtx(0, cookie);
5643 ok(ret, "DeactivateActCtx failed: %u\n", GetLastError());
5644
5645 pReleaseActCtx(handle);
5646 }
5647
5648 #define AUX_HREF 1
5649 #define AUX_TDESC 2
5650 #define AUX_ADESC 3
5651 static struct _TDATest {
5652 VARTYPE vt;
5653 ULONG size; /* -1 == typelib ptr size */
5654 WORD align;
5655 WORD align3264; /* for 32-bit typelibs loaded in 64-bit mode */
5656 DWORD aux;
5657 TYPEDESC tdesc;
5658 ARRAYDESC adesc;
5659 } TDATests[] = {
5660 { VT_I2, 2, 2, 2 },
5661 { VT_I4, 4, 4, 4 },
5662 { VT_R4, 4, 4, 4 },
5663 { VT_R8, 8, 4, 8 },
5664 { VT_CY, 8, 4, 8 },
5665 { VT_DATE, 8, 4, 8 },
5666 { VT_BSTR, -1, 4, 8 },
5667 { VT_DISPATCH, -1, 4, 8 },
5668 { VT_ERROR, 4, 4, 4 },
5669 { VT_BOOL, 2, 2, 2 },
5670 { VT_VARIANT, 0 /* see code below */, 4, 8 },
5671 { VT_UNKNOWN, -1, 4, 8 },
5672 { VT_DECIMAL, 16, 4, 8 },
5673 { VT_I1, 1, 1, 1 },
5674 { VT_UI1, 1, 1, 1 },
5675 { VT_UI2, 2, 2, 2 },
5676 { VT_UI4, 4, 4, 4 },
5677 { VT_I8, 8, 4, 8 },
5678 { VT_UI8, 8, 4, 8 },
5679 { VT_INT, 4, 4, 4 },
5680 { VT_UINT, 4, 4, 4 },
5681 { VT_VOID, 0, 0, 0 },
5682 { VT_HRESULT, 4, 4, 4 },
5683 { VT_PTR, -1, 4, 8, AUX_TDESC, { { 0 }, VT_INT } },
5684 { VT_SAFEARRAY, -1, 4, 8, AUX_TDESC, { { 0 }, VT_INT } },
5685 { VT_CARRAY, 16 /* == 4 * sizeof(int) */, 4, 4, AUX_ADESC, { { 0 } }, { { { 0 }, VT_INT }, 1, { { 4, 0 } } } },
5686 { VT_USERDEFINED, 0, 0, 0, AUX_HREF },
5687 { VT_LPSTR, -1, 4, 8 },
5688 { VT_LPWSTR, -1, 4, 8 },
5689 { 0 }
5690 };
5691
5692 static void testTDA(ITypeLib *tl, struct _TDATest *TDATest,
5693 ULONG ptr_size, HREFTYPE hreftype, ULONG href_cbSizeInstance,
5694 WORD href_cbAlignment, BOOL create)
5695 {
5696 TYPEDESC tdesc;
5697 WCHAR nameW[32];
5698 ITypeInfo *ti;
5699 ICreateTypeInfo *cti;
5700 ICreateTypeLib2 *ctl;
5701 ULONG size;
5702 WORD alignment;
5703 TYPEATTR *typeattr;
5704 HRESULT hr;
5705
5706 static const WCHAR name_fmtW[] = {'a','l','i','a','s','%','0','2','u',0};
5707
5708 wsprintfW(nameW, name_fmtW, TDATest->vt);
5709
5710 if(create){
5711 hr = ITypeLib_QueryInterface(tl, &IID_ICreateTypeLib2, (void**)&ctl);
5712 ok(hr == S_OK, "got %08x\n", hr);
5713
5714 hr = ICreateTypeLib2_CreateTypeInfo(ctl, nameW, TKIND_ALIAS, &cti);
5715 ok(hr == S_OK, "got %08x\n", hr);
5716
5717 tdesc.vt = TDATest->vt;
5718 if(TDATest->aux == AUX_TDESC)
5719 U(tdesc).lptdesc = &TDATest->tdesc;
5720 else if(TDATest->aux == AUX_ADESC)
5721 U(tdesc).lpadesc = &TDATest->adesc;
5722 else if(TDATest->aux == AUX_HREF)
5723 U(tdesc).hreftype = hreftype;
5724
5725 hr = ICreateTypeInfo_SetTypeDescAlias(cti, &tdesc);
5726 ok(hr == S_OK, "for VT %u, got %08x\n", TDATest->vt, hr);
5727
5728 hr = ICreateTypeInfo_QueryInterface(cti, &IID_ITypeInfo, (void**)&ti);
5729 ok(hr == S_OK, "got %08x\n", hr);
5730
5731 ICreateTypeInfo_Release(cti);
5732 ICreateTypeLib2_Release(ctl);
5733 }else{
5734 USHORT found = 1;
5735 MEMBERID memid;
5736
5737 hr = ITypeLib_FindName(tl, nameW, 0, &ti, &memid, &found);
5738 ok(hr == S_OK, "for VT %u, got %08x\n", TDATest->vt, hr);
5739 }
5740
5741 hr = ITypeInfo_GetTypeAttr(ti, &typeattr);
5742 ok(hr == S_OK, "got %08x\n", hr);
5743
5744 if(TDATest->aux == AUX_HREF){
5745 size = href_cbSizeInstance;
5746 alignment = href_cbAlignment;
5747 }else{
5748 size = TDATest->size;
5749 if(size == -1){
5750 if(create)
5751 size = ptr_size;
5752 else
5753 size = sizeof(void*);
5754 }else if(TDATest->vt == VT_VARIANT){
5755 if(create){
5756 size = sizeof(VARIANT);
5757 #ifdef _WIN64
5758 if(ptr_size != sizeof(void*))
5759 size -= 8; /* 32-bit variant is 4 bytes smaller than 64-bit variant */
5760 #endif
5761 }else
5762 size = sizeof(VARIANT);
5763 }
5764 alignment = TDATest->align;
5765 #ifdef _WIN64
5766 if(!create && ptr_size != sizeof(void*))
5767 alignment = TDATest->align3264;
5768 #endif
5769 }
5770
5771 ok(typeattr->cbSizeInstance == size ||
5772 broken(TDATest->vt == VT_VARIANT && ptr_size != sizeof(void*) && typeattr->cbSizeInstance == sizeof(VARIANT)) /* winxp64 */,
5773 "got wrong size for VT %u: 0x%x\n", TDATest->vt, typeattr->cbSizeInstance);
5774 ok(typeattr->cbAlignment == alignment, "got wrong alignment for VT %u: 0x%x\n", TDATest->vt, typeattr->cbAlignment);
5775 ok(typeattr->tdescAlias.vt == TDATest->vt, "got wrong VT for VT %u: 0x%x\n", TDATest->vt, typeattr->tdescAlias.vt);
5776
5777 switch(TDATest->aux){
5778 case AUX_HREF:
5779 ok(U(typeattr->tdescAlias).hreftype == hreftype, "got wrong hreftype for VT %u: 0x%x\n", TDATest->vt, U(typeattr->tdescAlias).hreftype);
5780 break;
5781 case AUX_TDESC:
5782 ok(U(typeattr->tdescAlias).lptdesc->vt == TDATest->tdesc.vt, "got wrong typedesc VT for VT %u: 0x%x\n", TDATest->vt, U(typeattr->tdescAlias).lptdesc->vt);
5783 break;
5784 case AUX_ADESC:
5785 ok(U(typeattr->tdescAlias).lpadesc->tdescElem.vt == TDATest->adesc.tdescElem.vt, "got wrong arraydesc element VT for VT %u: 0x%x\n", TDATest->vt, U(typeattr->tdescAlias).lpadesc->tdescElem.vt);
5786 ok(U(typeattr->tdescAlias).lpadesc->cDims == TDATest->adesc.cDims, "got wrong arraydesc dimension count for VT %u: 0x%x\n", TDATest->vt, U(typeattr->tdescAlias).lpadesc->cDims);
5787 ok(U(typeattr->tdescAlias).lpadesc->rgbounds[0].cElements == TDATest->adesc.rgbounds[0].cElements, "got wrong arraydesc element count for VT %u: 0x%x\n", TDATest->vt, U(typeattr->tdescAlias).lpadesc->rgbounds[0].cElements);
5788 ok(U(typeattr->tdescAlias).lpadesc->rgbounds[0].lLbound == TDATest->adesc.rgbounds[0].lLbound, "got wrong arraydesc lower bound for VT %u: 0x%x\n", TDATest->vt, U(typeattr->tdescAlias).lpadesc->rgbounds[0].lLbound);
5789 break;
5790 }
5791
5792 ITypeInfo_ReleaseTypeAttr(ti, typeattr);
5793 ITypeInfo_Release(ti);
5794 }
5795
5796 static void test_SetTypeDescAlias(SYSKIND kind)
5797 {
5798 CHAR filenameA[MAX_PATH];
5799 WCHAR filenameW[MAX_PATH];
5800 ITypeLib *tl;
5801 ICreateTypeLib2 *ctl;
5802 ITypeInfo *ti;
5803 ICreateTypeInfo *cti;
5804 HREFTYPE hreftype;
5805 TYPEATTR *typeattr;
5806 ULONG href_cbSizeInstance, i;
5807 WORD href_cbAlignment, ptr_size;
5808 HRESULT hr;
5809
5810 static OLECHAR interfaceW[] = {'i','n','t','e','r','f','a','c','e',0};
5811
5812 switch(kind){
5813 case SYS_WIN32:
5814 trace("testing SYS_WIN32\n");
5815 ptr_size = 4;
5816 break;
5817 case SYS_WIN64:
5818 trace("testing SYS_WIN64\n");
5819 ptr_size = 8;
5820 break;
5821 default:
5822 return;
5823 }
5824
5825 GetTempFileNameA(".", "tlb", 0, filenameA);
5826 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filenameW, MAX_PATH);
5827
5828 hr = CreateTypeLib2(kind, filenameW, &ctl);
5829 ok(hr == S_OK, "got %08x\n", hr);
5830
5831 hr = ICreateTypeLib2_CreateTypeInfo(ctl, interfaceW, TKIND_INTERFACE, &cti);
5832 ok(hr == S_OK, "got %08x\n", hr);
5833
5834 hr = ICreateTypeInfo_QueryInterface(cti, &IID_ITypeInfo, (void**)&ti);
5835 ok(hr == S_OK, "got %08x\n", hr);
5836
5837 hr = ICreateTypeInfo_AddRefTypeInfo(cti, ti, &hreftype);
5838 ok(hr == S_OK, "got %08x\n", hr);
5839
5840 hr = ITypeInfo_GetTypeAttr(ti, &typeattr);
5841 ok(hr == S_OK, "got %08x\n", hr);
5842
5843 href_cbSizeInstance = typeattr->cbSizeInstance;
5844 href_cbAlignment = typeattr->cbAlignment;
5845
5846 ITypeInfo_ReleaseTypeAttr(ti, typeattr);
5847
5848 ITypeInfo_Release(ti);
5849 ICreateTypeInfo_Release(cti);
5850
5851 hr = ICreateTypeLib2_QueryInterface(ctl, &IID_ITypeLib, (void**)&tl);
5852 ok(hr == S_OK, "got %08x\n", hr);
5853
5854 for(i = 0; TDATests[i].vt; ++i)
5855 testTDA(tl, &TDATests[i], ptr_size, hreftype, href_cbSizeInstance, href_cbAlignment, TRUE);
5856
5857 hr = ICreateTypeLib2_SaveAllChanges(ctl);
5858 ok(hr == S_OK, "got %08x\n", hr);
5859
5860 ITypeLib_Release(tl);
5861 ok(0 == ICreateTypeLib2_Release(ctl), "typelib should have been released\n");
5862
5863 trace("after save...\n");
5864
5865 hr = LoadTypeLibEx(filenameW, REGKIND_NONE, &tl);
5866 ok(hr == S_OK, "got %08x\n", hr);
5867
5868 hr = ITypeLib_GetTypeInfo(tl, 0, &ti);
5869 ok(hr == S_OK, "got %08x\n", hr);
5870
5871 hr = ITypeInfo_GetTypeAttr(ti, &typeattr);
5872 ok(hr == S_OK, "got %08x\n", hr);
5873
5874 href_cbSizeInstance = typeattr->cbSizeInstance;
5875 href_cbAlignment = typeattr->cbAlignment;
5876
5877 ITypeInfo_ReleaseTypeAttr(ti, typeattr);
5878 ITypeInfo_Release(ti);
5879
5880 for(i = 0; TDATests[i].vt; ++i)
5881 testTDA(tl, &TDATests[i], ptr_size, hreftype, href_cbSizeInstance, href_cbAlignment, FALSE);
5882
5883 ok(0 == ITypeLib_Release(tl), "typelib should have been released\n");
5884
5885 DeleteFileA(filenameA);
5886 }
5887
5888 static void test_GetLibAttr(void)
5889 {
5890 ULONG ref1, ref2;
5891 TLIBATTR *attr;
5892 ITypeLib *tl;
5893 HRESULT hr;
5894
5895 hr = LoadTypeLib(wszStdOle2, &tl);
5896 ok(hr == S_OK, "got 0x%08x\n", hr);
5897
5898 ref1 = ITypeLib_AddRef(tl);
5899 ITypeLib_Release(tl);
5900
5901 hr = ITypeLib_GetLibAttr(tl, &attr);
5902 ok(hr == S_OK, "got 0x%08x\n", hr);
5903
5904 ref2 = ITypeLib_AddRef(tl);
5905 ITypeLib_Release(tl);
5906 ok(ref2 == ref1, "got %d, %d\n", ref2, ref1);
5907
5908 ITypeLib_ReleaseTLibAttr(tl, attr);
5909 ITypeLib_Release(tl);
5910 }
5911
5912 static HRESULT WINAPI uk_QueryInterface(IUnknown *obj, REFIID iid, void **out)
5913 {
5914 return E_NOINTERFACE;
5915 }
5916
5917 static ULONG WINAPI uk_AddRef(IUnknown *obj)
5918 {
5919 return 2;
5920 }
5921
5922 static ULONG WINAPI uk_Release(IUnknown *obj)
5923 {
5924 return 1;
5925 }
5926
5927 IUnknownVtbl vt = {
5928 uk_QueryInterface,
5929 uk_AddRef,
5930 uk_Release,
5931 };
5932
5933 IUnknown uk = {&vt};
5934
5935 static void test_stub(void)
5936 {
5937 BOOL is_wow64 = FALSE;
5938 DWORD *sam_list;
5939 HRESULT hr;
5940 ITypeLib *stdole;
5941 ICreateTypeLib2 *ctl;
5942 ICreateTypeInfo *cti;
5943 ITypeLib *tl;
5944 ITypeInfo *unk, *ti;
5945 HREFTYPE href;
5946 char filenameA[MAX_PATH];
5947 WCHAR filenameW[MAX_PATH];
5948 int i;
5949
5950 static const GUID libguid = {0x3b9ff02e,0x9675,0x4861,{0xb7,0x81,0xce,0xae,0xa4,0x78,0x2a,0xcc}};
5951 static const GUID interfaceguid = {0x3b9ff02f,0x9675,0x4861,{0xb7,0x81,0xce,0xae,0xa4,0x78,0x2a,0xcc}};
5952 static const GUID coclassguid = {0x3b9ff030,0x9675,0x4861,{0xb7,0x81,0xce,0xae,0xa4,0x78,0x2a,0xcc}};
5953 static OLECHAR interfaceW[] = {'i','n','t','e','r','f','a','c','e',0};
5954 static OLECHAR classW[] = {'c','l','a','s','s',0};
5955 static DWORD sam_list32[] = { 0, ~0 };
5956 static DWORD sam_list64[] = { 0, KEY_WOW64_32KEY, KEY_WOW64_64KEY, ~0 };
5957
5958 if (pIsWow64Process)
5959 pIsWow64Process(GetCurrentProcess(), &is_wow64);
5960 if (is_wow64 || is_win64)
5961 sam_list = sam_list64;
5962 else
5963 sam_list = sam_list32;
5964
5965 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
5966
5967 hr = LoadTypeLib(wszStdOle2, &stdole);
5968 ok(hr == S_OK, "got %08x\n", hr);
5969
5970 hr = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IUnknown, &unk);
5971 ok(hr == S_OK, "got %08x\n", hr);
5972
5973 GetTempFileNameA(".", "tlb", 0, filenameA);
5974 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filenameW, MAX_PATH);
5975
5976 hr = CreateTypeLib2(SYS_WIN32, filenameW, &ctl);
5977 ok(hr == S_OK, "got %08x\n", hr);
5978
5979 hr = ICreateTypeLib2_SetGuid(ctl, &libguid);
5980 ok(hr == S_OK, "got %08x\n", hr);
5981
5982 hr = ICreateTypeLib2_SetLcid(ctl, LOCALE_NEUTRAL);
5983 ok(hr == S_OK, "got %08x\n", hr);
5984
5985 hr = ICreateTypeLib2_CreateTypeInfo(ctl, interfaceW, TKIND_INTERFACE, &cti);
5986 ok(hr == S_OK, "got %08x\n", hr);
5987
5988 hr = ICreateTypeInfo_SetGuid(cti, &interfaceguid);
5989 ok(hr == S_OK, "got %08x\n", hr);
5990
5991 hr = ICreateTypeInfo_SetTypeFlags(cti, TYPEFLAG_FOLEAUTOMATION);
5992 ok(hr == S_OK, "got %08x\n", hr);
5993
5994 hr = ICreateTypeInfo_AddRefTypeInfo(cti, unk, &href);
5995 ok(hr == S_OK, "got %08x\n", hr);
5996
5997 hr = ICreateTypeInfo_AddImplType(cti, 0, href);
5998 ok(hr == S_OK, "got %08x\n", hr);
5999
6000 hr = ICreateTypeInfo_QueryInterface(cti, &IID_ITypeInfo, (void**)&ti);
6001 ok(hr == S_OK, "got %08x\n", hr);
6002
6003 ICreateTypeInfo_Release(cti);
6004 ITypeInfo_Release(unk);
6005 ITypeLib_Release(stdole);
6006
6007 hr = ICreateTypeLib2_CreateTypeInfo(ctl, classW, TKIND_COCLASS, &cti);
6008 ok(hr == S_OK, "got %08x\n", hr);
6009
6010 hr = ICreateTypeInfo_SetGuid(cti, &coclassguid);
6011 ok(hr == S_OK, "got %08x\n", hr);
6012
6013 hr = ICreateTypeInfo_AddRefTypeInfo(cti, ti, &href);
6014 ok(hr == S_OK, "got %08x\n", hr);
6015
6016 hr = ICreateTypeInfo_AddImplType(cti, 0, href);
6017 ok(hr == S_OK, "got %08x\n", hr);
6018
6019 ITypeInfo_Release(ti);
6020 ICreateTypeInfo_Release(cti);
6021
6022 hr = ICreateTypeLib2_SaveAllChanges(ctl);
6023 ok(hr == S_OK, "got %08x\n", hr);
6024
6025 hr = ICreateTypeLib2_QueryInterface(ctl, &IID_ITypeLib, (void**)&tl);
6026 ok(hr == S_OK, "got %08x\n", hr);
6027
6028 for (i = 0; sam_list[i] != ~0; i++)
6029 {
6030 IPSFactoryBuffer *factory;
6031 IRpcStubBuffer *base_stub;
6032 REGSAM side = sam_list[i];
6033 CLSID clsid;
6034 HKEY hkey;
6035 LONG lr;
6036
6037 hr = RegisterTypeLib(tl, filenameW, NULL);
6038 if (hr == TYPE_E_REGISTRYACCESS)
6039 {
6040 win_skip("Insufficient privileges to register typelib in the registry\n");
6041 break;
6042 }
6043 ok(hr == S_OK, "got %08x, side: %04x\n", hr, side);
6044
6045 /* SYS_WIN32 typelibs should be registered only as 32-bit */
6046 lr = RegOpenKeyExA(HKEY_CLASSES_ROOT, "TypeLib\\{3b9ff02e-9675-4861-b781-ceaea4782acc}\\0.0\\0\\win64", 0, KEY_READ | side, &hkey);
6047 ok(lr == ERROR_FILE_NOT_FOUND, "got wrong return code: %u, side: %04x\n", lr, side);
6048
6049 lr = RegOpenKeyExA(HKEY_CLASSES_ROOT, "TypeLib\\{3b9ff02e-9675-4861-b781-ceaea4782acc}\\0.0\\0\\win32", 0, KEY_READ | side, &hkey);
6050 ok(lr == ERROR_SUCCESS, "got wrong return code: %u, side: %04x\n", lr, side);
6051 RegCloseKey(hkey);
6052
6053 /* Simulate pre-win7 installers that create interface key on one side */
6054 if (side != 0)
6055 {
6056 WCHAR guidW[40];
6057 REGSAM opposite = side ^ (KEY_WOW64_64KEY | KEY_WOW64_32KEY);
6058
6059 StringFromGUID2(&interfaceguid, guidW, sizeof(guidW)/sizeof(guidW[0]));
6060
6061 /* Delete the opposite interface key */
6062 lr = RegOpenKeyExA(HKEY_CLASSES_ROOT, "Interface", 0, KEY_READ | opposite, &hkey);
6063 ok(lr == ERROR_SUCCESS, "got wrong return code: %u, side: %04x\n", lr, side);
6064 lr = myRegDeleteTreeW(hkey, guidW, opposite);
6065 ok(lr == ERROR_SUCCESS, "got wrong return code: %u, side: %04x\n", lr, side);
6066 RegCloseKey(hkey);
6067
6068 /* Is our side interface key affected by above operation? */
6069 lr = RegOpenKeyExA(HKEY_CLASSES_ROOT, "Interface\\{3b9ff02f-9675-4861-b781-ceaea4782acc}", 0, KEY_READ | side, &hkey);
6070 ok(lr == ERROR_SUCCESS || broken(lr == ERROR_FILE_NOT_FOUND), "got wrong return code: %u, side: %04x\n", lr, side);
6071 if (lr == ERROR_FILE_NOT_FOUND)
6072 {
6073 /* win2k3, vista, 2008 */
6074 win_skip("Registry reflection is enabled on this platform.\n");
6075 goto next;
6076 }
6077 RegCloseKey(hkey);
6078
6079 /* Opposite side typelib key still exists */
6080 lr = RegOpenKeyExA(HKEY_CLASSES_ROOT, "TypeLib\\{3b9ff02e-9675-4861-b781-ceaea4782acc}\\0.0\\0\\win32", 0, KEY_READ | opposite, &hkey);
6081 ok(lr == ERROR_SUCCESS, "got wrong return code: %u, side: %04x\n", lr, side);
6082 RegCloseKey(hkey);
6083 }
6084
6085 hr = CoGetPSClsid(&interfaceguid, &clsid);
6086 ok(hr == S_OK, "got: %x, side: %04x\n", hr, side);
6087
6088 hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL,
6089 &IID_IPSFactoryBuffer, (void **)&factory);
6090 ok(hr == S_OK, "got: %x, side: %04x\n", hr, side);
6091
6092 hr = IPSFactoryBuffer_CreateStub(factory, &interfaceguid, &uk, &base_stub);
6093 ok(hr == S_OK, "got: %x, side: %04x\n", hr, side);
6094 IRpcStubBuffer_Release(base_stub);
6095
6096 IPSFactoryBuffer_Release(factory);
6097 next:
6098 hr = UnRegisterTypeLib(&libguid, 0, 0, 0, SYS_WIN32);
6099 ok(hr == S_OK, "got: %x, side: %04x\n", hr, side);
6100 }
6101
6102 ITypeLib_Release(tl);
6103 ok(0 == ICreateTypeLib2_Release(ctl), "Typelib still has references\n");
6104
6105 DeleteFileW(filenameW);
6106
6107 CoUninitialize();
6108 }
6109
6110 static void test_dep(void) {
6111 HRESULT hr;
6112 const char *refFilename;
6113 WCHAR refFilenameW[MAX_PATH];
6114 ITypeLib *preftLib;
6115 ITypeInfo *preftInfo;
6116 char filename[MAX_PATH];
6117 WCHAR filenameW[MAX_PATH];
6118 ICreateTypeLib2 *pctLib;
6119 ICreateTypeInfo *pctInfo;
6120 ITypeLib *ptLib;
6121 ITypeInfo *ptInfo;
6122 ITypeInfo *ptInfoExt = NULL;
6123 HREFTYPE refType;
6124
6125 static WCHAR ifacenameW[] = {'I','T','e','s','t','D','e','p',0};
6126
6127 static const GUID libguid = {0xe0228f26,0x2946,0x478c,{0xb6,0x4a,0x93,0xfe,0xef,0xa5,0x05,0x32}};
6128 static const GUID ifaceguid = {0x394376dd,0x3bb8,0x4804,{0x8c,0xcc,0x95,0x59,0x43,0x40,0x04,0xf3}};
6129
6130 trace("Starting typelib dependency tests\n");
6131
6132 refFilename = create_test_typelib(2);
6133 MultiByteToWideChar(CP_ACP, 0, refFilename, -1, refFilenameW, MAX_PATH);
6134
6135 hr = LoadTypeLibEx(refFilenameW, REGKIND_NONE, &preftLib);
6136 ok(hr == S_OK, "got %08x\n", hr);
6137
6138 hr = ITypeLib_GetTypeInfoOfGuid(preftLib, &IID_ISimpleIface, &preftInfo);
6139 ok(hr == S_OK, "got %08x\n", hr);
6140
6141 GetTempFileNameA(".", "tlb", 0, filename);
6142 MultiByteToWideChar(CP_ACP, 0, filename, -1, filenameW, MAX_PATH);
6143
6144 if(sizeof(void*) == 8) {
6145 hr = CreateTypeLib2(SYS_WIN64, filenameW, &pctLib);
6146 ok(hr == S_OK, "got %08x\n", hr);
6147 } else {
6148 hr = CreateTypeLib2(SYS_WIN32, filenameW, &pctLib);
6149 ok(hr == S_OK, "got %08x\n", hr);
6150 }
6151
6152 hr = ICreateTypeLib2_SetGuid(pctLib, &libguid);
6153 ok(hr == S_OK, "got %08x\n", hr);
6154
6155 hr = ICreateTypeLib2_SetLcid(pctLib, LOCALE_NEUTRAL);
6156 ok(hr == S_OK, "got %08x\n", hr);
6157
6158 hr = ICreateTypeLib2_CreateTypeInfo(pctLib, ifacenameW, TKIND_INTERFACE, &pctInfo);
6159 ok(hr == S_OK, "got %08x\n", hr);
6160
6161 hr = ICreateTypeInfo_SetGuid(pctInfo, &ifaceguid);
6162 ok(hr == S_OK, "got %08x\n", hr);
6163
6164 hr = ICreateTypeInfo_SetTypeFlags(pctInfo, TYPEFLAG_FOLEAUTOMATION);
6165 ok(hr == S_OK, "got %08x\n", hr);
6166
6167 hr = ICreateTypeInfo_AddRefTypeInfo(pctInfo, preftInfo, &refType);
6168 ok(hr == S_OK, "got %08x\n", hr);
6169
6170 hr = ICreateTypeInfo_AddImplType(pctInfo, 0, refType);
6171 ok(hr == S_OK, "got %08x\n", hr);
6172
6173 ICreateTypeInfo_Release(pctInfo);
6174
6175 hr = ICreateTypeLib2_SaveAllChanges(pctLib);
6176 ok(hr == S_OK, "got %08x\n", hr);
6177
6178 ICreateTypeLib2_Release(pctLib);
6179
6180 ITypeInfo_Release(preftInfo);
6181 ITypeLib_Release(preftLib);
6182
6183 DeleteFileW(refFilenameW);
6184
6185 hr = LoadTypeLibEx(filenameW, REGKIND_NONE, &ptLib);
6186 ok(hr == S_OK, "got: %x\n", hr);
6187
6188 hr = ITypeLib_GetTypeInfoOfGuid(ptLib, &ifaceguid, &ptInfo);
6189 ok(hr == S_OK, "got: %x\n", hr);
6190
6191 hr = ITypeInfo_GetRefTypeOfImplType(ptInfo, 0, &refType);
6192 ok(hr == S_OK, "got: %x\n", hr);
6193
6194 hr = ITypeInfo_GetRefTypeInfo(ptInfo, refType, &ptInfoExt);
6195 ok(hr == S_OK || broken(hr == TYPE_E_CANTLOADLIBRARY) /* win 2000 */, "got: %x\n", hr);
6196
6197 ITypeInfo_Release(ptInfo);
6198 if(ptInfoExt)
6199 ITypeInfo_Release(ptInfoExt);
6200 ITypeLib_Release(ptLib);
6201
6202 DeleteFileW(filenameW);
6203 }
6204
6205 START_TEST(typelib)
6206 {
6207 const char *filename;
6208
6209 init_function_pointers();
6210
6211 ref_count_test(wszStdOle2);
6212 test_TypeComp();
6213 test_CreateDispTypeInfo();
6214 test_TypeInfo();
6215 test_DispCallFunc();
6216 test_QueryPathOfRegTypeLib(32);
6217 if(sizeof(void*) == 8){
6218 test_QueryPathOfRegTypeLib(64);
6219 test_CreateTypeLib(SYS_WIN64);
6220 test_SetTypeDescAlias(SYS_WIN64);
6221 }
6222 test_CreateTypeLib(SYS_WIN32);
6223 test_SetTypeDescAlias(SYS_WIN32);
6224 test_inheritance();
6225 test_SetVarHelpContext();
6226 test_SetFuncAndParamNames();
6227 test_SetDocString();
6228 test_FindName();
6229
6230 if ((filename = create_test_typelib(2)))
6231 {
6232 test_dump_typelib( filename );
6233 DeleteFileA( filename );
6234 }
6235
6236 test_register_typelib(TRUE);
6237 test_register_typelib(FALSE);
6238 test_create_typelibs();
6239 test_LoadTypeLib();
6240 test_TypeInfo2_GetContainingTypeLib();
6241 test_LoadRegTypeLib();
6242 test_GetLibAttr();
6243 test_stub();
6244 test_dep();
6245 }