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