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