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