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