2 * ITypeLib and ITypeInfo test
4 * Copyright 2004 Jacek Caban
5 * Copyright 2006 Dmitry Timoshkov
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.
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.
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
24 #include <wine/test.h>
38 #define expect_eq(expr, value, type, format) { type _ret = (expr); ok((value) == _ret, #expr " expected " format " got " format "\n", value, _ret); }
39 #define expect_int(expr, value) expect_eq(expr, (int)(value), int, "%d")
40 #define expect_hex(expr, value) expect_eq(expr, (int)(value), int, "0x%x")
41 #define expect_null(expr) expect_eq(expr, NULL, const void *, "%p")
43 #define expect_wstr_acpval(expr, value) \
46 expect_eq(!WideCharToMultiByte(CP_ACP, 0, (expr), -1, buf, 260, NULL, NULL), 0, int, "%d"); \
47 ok(lstrcmp(value, buf) == 0, #expr " expected \"%s\" got \"%s\"\n", value, buf); \
50 #define ole_expect(expr, expect) { \
52 ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \
55 #define ole_check(expr) ole_expect(expr, S_OK);
57 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
59 static const WCHAR wszStdOle2
[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
61 static void ref_count_test(LPCWSTR type_lib
)
64 ITypeInfo
*iti1
, *iti2
;
68 trace("Loading type library\n");
69 hRes
= LoadTypeLib(type_lib
, &iface
);
70 ok(hRes
== S_OK
, "Could not load type library\n");
74 hRes
= ITypeLib_GetTypeInfo(iface
, 1, &iti1
);
75 ok(hRes
== S_OK
, "ITypeLib_GetTypeInfo failed on index = 1\n");
76 ok(ref_count
=ITypeLib_Release(iface
) > 0, "ITypeLib destroyed while ITypeInfo has back pointer\n");
80 hRes
= ITypeLib_GetTypeInfo(iface
, 1, &iti2
);
81 ok(hRes
== S_OK
, "ITypeLib_GetTypeInfo failed on index = 1\n");
82 ok(iti1
== iti2
, "ITypeLib_GetTypeInfo returned different pointers for same indexes\n");
84 ITypeLib_AddRef(iface
);
85 ITypeInfo_Release(iti2
);
86 ITypeInfo_Release(iti1
);
87 ok(ITypeLib_Release(iface
) == 0, "ITypeLib should be destroyed here.\n");
90 static void test_TypeComp(void)
99 ITypeInfo
*pFontTypeInfo
;
100 static WCHAR wszStdFunctions
[] = {'S','t','d','F','u','n','c','t','i','o','n','s',0};
101 static WCHAR wszSavePicture
[] = {'S','a','v','e','P','i','c','t','u','r','e',0};
102 static WCHAR wszOLE_TRISTATE
[] = {'O','L','E','_','T','R','I','S','T','A','T','E',0};
103 static WCHAR wszUnchecked
[] = {'U','n','c','h','e','c','k','e','d',0};
104 static WCHAR wszIUnknown
[] = {'I','U','n','k','n','o','w','n',0};
105 static WCHAR wszFont
[] = {'F','o','n','t',0};
106 static WCHAR wszGUID
[] = {'G','U','I','D',0};
107 static WCHAR wszStdPicture
[] = {'S','t','d','P','i','c','t','u','r','e',0};
108 static WCHAR wszOLE_COLOR
[] = {'O','L','E','_','C','O','L','O','R',0};
109 static WCHAR wszClone
[] = {'C','l','o','n','e',0};
110 static WCHAR wszclone
[] = {'c','l','o','n','e',0};
112 hr
= LoadTypeLib(wszStdOle2
, &pTypeLib
);
113 ok_ole_success(hr
, LoadTypeLib
);
115 hr
= ITypeLib_GetTypeComp(pTypeLib
, &pTypeComp
);
116 ok_ole_success(hr
, ITypeLib_GetTypeComp
);
118 /* test getting a TKIND_MODULE */
119 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszStdFunctions
);
120 hr
= ITypeComp_Bind(pTypeComp
, wszStdFunctions
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
121 ok_ole_success(hr
, ITypeComp_Bind
);
123 ok(desckind
== DESCKIND_TYPECOMP
,
124 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
126 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
128 ITypeComp_Release(bindptr
.lptcomp
);
130 /* test getting a TKIND_MODULE with INVOKE_PROPERTYGET */
131 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszStdFunctions
);
132 hr
= ITypeComp_Bind(pTypeComp
, wszStdFunctions
, ulHash
, INVOKE_PROPERTYGET
, &pTypeInfo
, &desckind
, &bindptr
);
133 ok_ole_success(hr
, ITypeComp_Bind
);
135 ok(desckind
== DESCKIND_TYPECOMP
,
136 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
138 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
139 ITypeComp_Release(bindptr
.lptcomp
);
141 /* test getting a function within a TKIND_MODULE */
142 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszSavePicture
);
143 hr
= ITypeComp_Bind(pTypeComp
, wszSavePicture
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
144 ok_ole_success(hr
, ITypeComp_Bind
);
146 ok(desckind
== DESCKIND_FUNCDESC
,
147 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
149 ok(bindptr
.lpfuncdesc
!= NULL
, "bindptr.lpfuncdesc should not have been set to NULL\n");
150 ITypeInfo_ReleaseFuncDesc(pTypeInfo
, bindptr
.lpfuncdesc
);
151 ITypeInfo_Release(pTypeInfo
);
153 /* test getting a function within a TKIND_MODULE with INVOKE_PROPERTYGET */
154 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszSavePicture
);
155 hr
= ITypeComp_Bind(pTypeComp
, wszSavePicture
, ulHash
, INVOKE_PROPERTYGET
, &pTypeInfo
, &desckind
, &bindptr
);
156 ok(hr
== TYPE_E_TYPEMISMATCH
,
157 "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n",
160 ok(desckind
== DESCKIND_NONE
,
161 "desckind should have been DESCKIND_NONE instead of %d\n",
163 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
164 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
166 /* test getting a TKIND_ENUM */
167 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszOLE_TRISTATE
);
168 hr
= ITypeComp_Bind(pTypeComp
, wszOLE_TRISTATE
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
169 ok_ole_success(hr
, ITypeComp_Bind
);
171 ok(desckind
== DESCKIND_TYPECOMP
,
172 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
174 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
176 ITypeComp_Release(bindptr
.lptcomp
);
178 /* test getting a value within a TKIND_ENUM */
179 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszUnchecked
);
180 hr
= ITypeComp_Bind(pTypeComp
, wszUnchecked
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
181 ok_ole_success(hr
, ITypeComp_Bind
);
183 ok(desckind
== DESCKIND_VARDESC
,
184 "desckind should have been DESCKIND_VARDESC instead of %d\n",
186 ITypeInfo_ReleaseVarDesc(pTypeInfo
, bindptr
.lpvardesc
);
187 ITypeInfo_Release(pTypeInfo
);
189 /* test getting a TKIND_INTERFACE */
190 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszIUnknown
);
191 hr
= ITypeComp_Bind(pTypeComp
, wszIUnknown
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
192 ok_ole_success(hr
, ITypeComp_Bind
);
194 ok(desckind
== DESCKIND_NONE
,
195 "desckind should have been DESCKIND_NONE instead of %d\n",
197 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
198 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
200 /* test getting a TKIND_DISPATCH */
201 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszFont
);
202 hr
= ITypeComp_Bind(pTypeComp
, wszFont
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
203 ok_ole_success(hr
, ITypeComp_Bind
);
205 ok(desckind
== DESCKIND_NONE
,
206 "desckind should have been DESCKIND_NONE instead of %d\n",
208 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
209 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
211 /* test getting a TKIND_RECORD/TKIND_ALIAS */
212 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszGUID
);
213 hr
= ITypeComp_Bind(pTypeComp
, wszGUID
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
214 ok_ole_success(hr
, ITypeComp_Bind
);
216 ok(desckind
== DESCKIND_NONE
,
217 "desckind should have been DESCKIND_NONE instead of %d\n",
219 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
220 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
222 /* test getting a TKIND_ALIAS */
223 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszOLE_COLOR
);
224 hr
= ITypeComp_Bind(pTypeComp
, wszOLE_COLOR
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
225 ok_ole_success(hr
, ITypeComp_Bind
);
227 ok(desckind
== DESCKIND_NONE
,
228 "desckind should have been DESCKIND_NONE instead of %d\n",
230 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
231 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
233 /* test getting a TKIND_COCLASS */
234 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszStdPicture
);
235 hr
= ITypeComp_Bind(pTypeComp
, wszStdPicture
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
236 ok_ole_success(hr
, ITypeComp_Bind
);
238 ok(desckind
== DESCKIND_NONE
,
239 "desckind should have been DESCKIND_NONE instead of %d\n",
241 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
242 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
244 ITypeComp_Release(pTypeComp
);
246 /* tests for ITypeComp on an interface */
247 hr
= ITypeLib_GetTypeInfoOfGuid(pTypeLib
, &IID_IFont
, &pFontTypeInfo
);
248 ok_ole_success(hr
, ITypeLib_GetTypeInfoOfGuid
);
250 hr
= ITypeInfo_GetTypeComp(pFontTypeInfo
, &pTypeComp
);
251 ok_ole_success(hr
, ITypeLib_GetTypeComp
);
253 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszClone
);
254 hr
= ITypeComp_Bind(pTypeComp
, wszClone
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
255 ok_ole_success(hr
, ITypeComp_Bind
);
257 ok(desckind
== DESCKIND_FUNCDESC
,
258 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
260 ok(bindptr
.lpfuncdesc
!= NULL
, "bindptr.lpfuncdesc should not have been set to NULL\n");
261 ITypeInfo_ReleaseFuncDesc(pTypeInfo
, bindptr
.lpfuncdesc
);
262 ITypeInfo_Release(pTypeInfo
);
264 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszClone
);
265 hr
= ITypeComp_Bind(pTypeComp
, wszClone
, ulHash
, INVOKE_PROPERTYGET
, &pTypeInfo
, &desckind
, &bindptr
);
266 ok(hr
== TYPE_E_TYPEMISMATCH
, "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n", hr
);
268 ok(desckind
== DESCKIND_NONE
,
269 "desckind should have been DESCKIND_NONE instead of %d\n",
271 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
272 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
274 /* tests that the compare is case-insensitive */
275 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszclone
);
276 hr
= ITypeComp_Bind(pTypeComp
, wszclone
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
277 ok_ole_success(hr
, ITypeComp_Bind
);
279 ok(desckind
== DESCKIND_FUNCDESC
,
280 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
282 ok(bindptr
.lpfuncdesc
!= NULL
, "bindptr.lpfuncdesc should not have been set to NULL\n");
283 ITypeInfo_ReleaseFuncDesc(pTypeInfo
, bindptr
.lpfuncdesc
);
284 ITypeInfo_Release(pTypeInfo
);
286 ITypeComp_Release(pTypeComp
);
287 ITypeInfo_Release(pFontTypeInfo
);
288 ITypeLib_Release(pTypeLib
);
291 static void test_CreateDispTypeInfo(void)
293 ITypeInfo
*pTypeInfo
, *pTI2
;
295 INTERFACEDATA ifdata
;
296 METHODDATA methdata
[4];
304 static WCHAR func1
[] = {'f','u','n','c','1',0};
305 static const WCHAR func2
[] = {'f','u','n','c','2',0};
306 static const WCHAR func3
[] = {'f','u','n','c','3',0};
307 static const WCHAR parm1
[] = {'p','a','r','m','1',0};
308 static const WCHAR parm2
[] = {'p','a','r','m','2',0};
309 OLECHAR
*name
= func1
;
311 ifdata
.pmethdata
= methdata
;
312 ifdata
.cMembers
= sizeof(methdata
) / sizeof(methdata
[0]);
314 methdata
[0].szName
= SysAllocString(func1
);
315 methdata
[0].ppdata
= parms1
;
316 methdata
[0].dispid
= 0x123;
317 methdata
[0].iMeth
= 0;
318 methdata
[0].cc
= CC_STDCALL
;
319 methdata
[0].cArgs
= 2;
320 methdata
[0].wFlags
= DISPATCH_METHOD
;
321 methdata
[0].vtReturn
= VT_HRESULT
;
322 parms1
[0].szName
= SysAllocString(parm1
);
323 parms1
[0].vt
= VT_I4
;
324 parms1
[1].szName
= SysAllocString(parm2
);
325 parms1
[1].vt
= VT_BSTR
;
327 methdata
[1].szName
= SysAllocString(func2
);
328 methdata
[1].ppdata
= NULL
;
329 methdata
[1].dispid
= 0x124;
330 methdata
[1].iMeth
= 1;
331 methdata
[1].cc
= CC_STDCALL
;
332 methdata
[1].cArgs
= 0;
333 methdata
[1].wFlags
= DISPATCH_PROPERTYGET
;
334 methdata
[1].vtReturn
= VT_I4
;
336 methdata
[2].szName
= SysAllocString(func3
);
337 methdata
[2].ppdata
= parms3
;
338 methdata
[2].dispid
= 0x125;
339 methdata
[2].iMeth
= 3;
340 methdata
[2].cc
= CC_STDCALL
;
341 methdata
[2].cArgs
= 1;
342 methdata
[2].wFlags
= DISPATCH_PROPERTYPUT
;
343 methdata
[2].vtReturn
= VT_HRESULT
;
344 parms3
[0].szName
= SysAllocString(parm1
);
345 parms3
[0].vt
= VT_I4
;
347 methdata
[3].szName
= SysAllocString(func3
);
348 methdata
[3].ppdata
= NULL
;
349 methdata
[3].dispid
= 0x125;
350 methdata
[3].iMeth
= 4;
351 methdata
[3].cc
= CC_STDCALL
;
352 methdata
[3].cArgs
= 0;
353 methdata
[3].wFlags
= DISPATCH_PROPERTYGET
;
354 methdata
[3].vtReturn
= VT_I4
;
356 hr
= CreateDispTypeInfo(&ifdata
, LOCALE_NEUTRAL
, &pTypeInfo
);
357 ok(hr
== S_OK
, "hr %08x\n", hr
);
359 hr
= ITypeInfo_GetTypeAttr(pTypeInfo
, &pTypeAttr
);
360 ok(hr
== S_OK
, "hr %08x\n", hr
);
362 ok(pTypeAttr
->typekind
== TKIND_COCLASS
, "typekind %0x\n", pTypeAttr
->typekind
);
363 ok(pTypeAttr
->cImplTypes
== 1, "cImplTypes %d\n", pTypeAttr
->cImplTypes
);
364 ok(pTypeAttr
->cFuncs
== 0, "cFuncs %d\n", pTypeAttr
->cFuncs
);
365 ok(pTypeAttr
->wTypeFlags
== 0, "wTypeFlags %04x\n", pTypeAttr
->cFuncs
);
366 ITypeInfo_ReleaseTypeAttr(pTypeInfo
, pTypeAttr
);
368 hr
= ITypeInfo_GetRefTypeOfImplType(pTypeInfo
, 0, &href
);
369 ok(hr
== S_OK
, "hr %08x\n", hr
);
370 ok(href
== 0, "href = 0x%x\n", href
);
371 hr
= ITypeInfo_GetRefTypeInfo(pTypeInfo
, href
, &pTI2
);
372 ok(hr
== S_OK
, "hr %08x\n", hr
);
373 hr
= ITypeInfo_GetTypeAttr(pTI2
, &pTypeAttr
);
374 ok(hr
== S_OK
, "hr %08x\n", hr
);
375 ok(pTypeAttr
->typekind
== TKIND_INTERFACE
, "typekind %0x\n", pTypeAttr
->typekind
);
376 ok(pTypeAttr
->cFuncs
== 4, "cFuncs %d\n", pTypeAttr
->cFuncs
);
377 ok(IsEqualGUID(&pTypeAttr
->guid
, &GUID_NULL
), "guid {%08x-...}\n", pTypeAttr
->guid
.Data1
);
378 ok(pTypeAttr
->wTypeFlags
== 0, "typeflags %08x\n", pTypeAttr
->wTypeFlags
);
380 ITypeInfo_ReleaseTypeAttr(pTI2
, pTypeAttr
);
382 hr
= ITypeInfo_GetFuncDesc(pTI2
, 0, &pFuncDesc
);
383 ok(hr
== S_OK
, "hr %08x\n", hr
);
384 ok(pFuncDesc
->memid
== 0x123, "memid %x\n", pFuncDesc
->memid
);
385 ok(pFuncDesc
->funckind
== FUNC_VIRTUAL
, "funckind %d\n", pFuncDesc
->funckind
);
386 ok(pFuncDesc
->invkind
== methdata
[0].wFlags
, "invkind %d\n", pFuncDesc
->invkind
);
387 ok(pFuncDesc
->callconv
== methdata
[0].cc
, "callconv %d\n", pFuncDesc
->callconv
);
388 ok(pFuncDesc
->cParams
== methdata
[0].cArgs
, "cParams %d\n", pFuncDesc
->cParams
);
389 ok(pFuncDesc
->oVft
== 0, "oVft %d\n", pFuncDesc
->oVft
);
390 ok(pFuncDesc
->wFuncFlags
== 0, "oVft %d\n", pFuncDesc
->wFuncFlags
);
391 ok(pFuncDesc
->elemdescFunc
.tdesc
.vt
== VT_HRESULT
, "ret vt %x\n", pFuncDesc
->elemdescFunc
.tdesc
.vt
);
392 ok(pFuncDesc
->lprgelemdescParam
[0].tdesc
.vt
== VT_I4
, "parm 0 vt %x\n", pFuncDesc
->lprgelemdescParam
[0].tdesc
.vt
);
393 ok(U(pFuncDesc
->lprgelemdescParam
[0]).paramdesc
.wParamFlags
== PARAMFLAG_NONE
, "parm 0 flags %x\n", U(pFuncDesc
->lprgelemdescParam
[0]).paramdesc
.wParamFlags
);
395 ok(pFuncDesc
->lprgelemdescParam
[1].tdesc
.vt
== VT_BSTR
, "parm 1 vt %x\n", pFuncDesc
->lprgelemdescParam
[1].tdesc
.vt
);
396 ok(U(pFuncDesc
->lprgelemdescParam
[1]).paramdesc
.wParamFlags
== PARAMFLAG_NONE
, "parm 1 flags %x\n", U(pFuncDesc
->lprgelemdescParam
[1]).paramdesc
.wParamFlags
);
397 ITypeInfo_ReleaseFuncDesc(pTI2
, pFuncDesc
);
399 hr
= ITypeInfo_GetFuncDesc(pTI2
, 1, &pFuncDesc
);
400 ok(hr
== S_OK
, "hr %08x\n", hr
);
401 ok(pFuncDesc
->funckind
== FUNC_VIRTUAL
, "funckind %d\n", pFuncDesc
->funckind
);
402 ok(pFuncDesc
->invkind
== methdata
[1].wFlags
, "invkind %d\n", pFuncDesc
->invkind
);
403 ok(pFuncDesc
->callconv
== methdata
[1].cc
, "callconv %d\n", pFuncDesc
->callconv
);
404 ok(pFuncDesc
->cParams
== methdata
[1].cArgs
, "cParams %d\n", pFuncDesc
->cParams
);
405 ok(pFuncDesc
->oVft
== sizeof(void *), "oVft %d\n", pFuncDesc
->oVft
);
406 ok(pFuncDesc
->wFuncFlags
== 0, "oVft %d\n", pFuncDesc
->wFuncFlags
);
407 ok(pFuncDesc
->elemdescFunc
.tdesc
.vt
== VT_I4
, "ret vt %x\n", pFuncDesc
->elemdescFunc
.tdesc
.vt
);
408 ITypeInfo_ReleaseFuncDesc(pTI2
, pFuncDesc
);
410 hr
= ITypeInfo_GetFuncDesc(pTI2
, 2, &pFuncDesc
);
411 ok(hr
== S_OK
, "hr %08x\n", hr
);
412 ok(pFuncDesc
->funckind
== FUNC_VIRTUAL
, "funckind %d\n", pFuncDesc
->funckind
);
413 ok(pFuncDesc
->invkind
== methdata
[2].wFlags
, "invkind %d\n", pFuncDesc
->invkind
);
414 ok(pFuncDesc
->callconv
== methdata
[2].cc
, "callconv %d\n", pFuncDesc
->callconv
);
415 ok(pFuncDesc
->cParams
== methdata
[2].cArgs
, "cParams %d\n", pFuncDesc
->cParams
);
416 ok(pFuncDesc
->oVft
== 3 * sizeof(void *), "oVft %d\n", pFuncDesc
->oVft
);
417 ok(pFuncDesc
->wFuncFlags
== 0, "oVft %d\n", pFuncDesc
->wFuncFlags
);
418 ok(pFuncDesc
->elemdescFunc
.tdesc
.vt
== VT_HRESULT
, "ret vt %x\n", pFuncDesc
->elemdescFunc
.tdesc
.vt
);
419 ok(pFuncDesc
->lprgelemdescParam
[0].tdesc
.vt
== VT_I4
, "parm 0 vt %x\n", pFuncDesc
->lprgelemdescParam
[0].tdesc
.vt
);
420 ok(U(pFuncDesc
->lprgelemdescParam
[0]).paramdesc
.wParamFlags
== PARAMFLAG_NONE
, "parm 0 flags %x\n", U(pFuncDesc
->lprgelemdescParam
[0]).paramdesc
.wParamFlags
);
421 ITypeInfo_ReleaseFuncDesc(pTI2
, pFuncDesc
);
423 hr
= ITypeInfo_GetFuncDesc(pTI2
, 3, &pFuncDesc
);
424 ok(hr
== S_OK
, "hr %08x\n", hr
);
425 ok(pFuncDesc
->funckind
== FUNC_VIRTUAL
, "funckind %d\n", pFuncDesc
->funckind
);
426 ok(pFuncDesc
->invkind
== methdata
[3].wFlags
, "invkind %d\n", pFuncDesc
->invkind
);
427 ok(pFuncDesc
->callconv
== methdata
[3].cc
, "callconv %d\n", pFuncDesc
->callconv
);
428 ok(pFuncDesc
->cParams
== methdata
[3].cArgs
, "cParams %d\n", pFuncDesc
->cParams
);
429 ok(pFuncDesc
->oVft
== 4 * sizeof(void *), "oVft %d\n", pFuncDesc
->oVft
);
430 ok(pFuncDesc
->wFuncFlags
== 0, "oVft %d\n", pFuncDesc
->wFuncFlags
);
431 ok(pFuncDesc
->elemdescFunc
.tdesc
.vt
== VT_I4
, "ret vt %x\n", pFuncDesc
->elemdescFunc
.tdesc
.vt
);
432 ITypeInfo_ReleaseFuncDesc(pTI2
, pFuncDesc
);
434 /* test GetIDsOfNames on a coclass to see if it searches its interfaces */
435 hr
= ITypeInfo_GetIDsOfNames(pTypeInfo
, &name
, 1, &memid
);
436 ok(hr
== S_OK
, "hr 0x%08x\n", hr
);
437 ok(memid
== 0x123, "memid 0x%08x\n", memid
);
439 ITypeInfo_Release(pTI2
);
440 ITypeInfo_Release(pTypeInfo
);
442 SysFreeString(parms1
[0].szName
);
443 SysFreeString(parms1
[1].szName
);
444 SysFreeString(parms3
[0].szName
);
445 SysFreeString(methdata
[0].szName
);
446 SysFreeString(methdata
[1].szName
);
447 SysFreeString(methdata
[2].szName
);
448 SysFreeString(methdata
[3].szName
);
451 static void test_TypeInfo(void)
454 ITypeInfo
*pTypeInfo
;
455 ITypeInfo2
*pTypeInfo2
;
457 static WCHAR wszBogus
[] = { 'b','o','g','u','s',0 };
458 static WCHAR wszGetTypeInfo
[] = { 'G','e','t','T','y','p','e','I','n','f','o',0 };
459 static WCHAR wszClone
[] = {'C','l','o','n','e',0};
460 OLECHAR
* bogus
= wszBogus
;
461 OLECHAR
* pwszGetTypeInfo
= wszGetTypeInfo
;
462 OLECHAR
* pwszClone
= wszClone
;
464 DISPPARAMS dispparams
;
465 GUID bogusguid
= {0x806afb4f,0x13f7,0x42d2,{0x89,0x2c,0x6c,0x97,0xc3,0x6a,0x36,0xc1}};
468 hr
= LoadTypeLib(wszStdOle2
, &pTypeLib
);
469 ok_ole_success(hr
, LoadTypeLib
);
471 hr
= ITypeLib_GetTypeInfoOfGuid(pTypeLib
, &IID_IFont
, &pTypeInfo
);
472 ok_ole_success(hr
, ITypeLib_GetTypeInfoOfGuid
);
474 /* test nonexistent method name */
475 hr
= ITypeInfo_GetIDsOfNames(pTypeInfo
, &bogus
, 1, &dispidMember
);
476 ok(hr
== DISP_E_UNKNOWNNAME
,
477 "ITypeInfo_GetIDsOfNames should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n",
480 /* test invalid memberid */
481 dispparams
.cNamedArgs
= 0;
482 dispparams
.cArgs
= 0;
483 dispparams
.rgdispidNamedArgs
= NULL
;
484 dispparams
.rgvarg
= NULL
;
485 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
486 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
488 hr
= ITypeInfo_GetIDsOfNames(pTypeInfo
, &pwszClone
, 1, &dispidMember
);
489 ok_ole_success(hr
, ITypeInfo_GetIDsOfNames
);
491 /* test correct memberid, but wrong flags */
492 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_PROPERTYGET
, &dispparams
, NULL
, NULL
, NULL
);
493 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
495 /* test NULL dispparams */
496 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_METHOD
, NULL
, NULL
, NULL
, NULL
);
497 ok(hr
== E_INVALIDARG
, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
499 /* test dispparams->cNamedArgs being bigger than dispparams->cArgs */
500 dispparams
.cNamedArgs
= 1;
501 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
502 ok(hr
== E_INVALIDARG
, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
504 ITypeInfo_Release(pTypeInfo
);
506 hr
= ITypeLib_GetTypeInfoOfGuid(pTypeLib
, &IID_IDispatch
, &pTypeInfo
);
507 ok_ole_success(hr
, ITypeLib_GetTypeInfoOfGuid
);
509 hr
= ITypeInfo_GetIDsOfNames(pTypeInfo
, &pwszGetTypeInfo
, 1, &dispidMember
);
510 ok_ole_success(hr
, ITypeInfo_GetIDsOfNames
);
512 hr
= ITypeInfo_QueryInterface(pTypeInfo
, &IID_ITypeInfo2
, (void**)&pTypeInfo2
);
513 ok_ole_success(hr
, ITypeInfo_QueryInterface
);
521 /* test unknown guid passed to GetCustData */
522 hr
= ITypeInfo2_GetCustData(pTypeInfo2
, &bogusguid
, &var
);
523 ok_ole_success(hr
, ITypeInfo_GetCustData
);
524 ok(V_VT(&var
) == VT_EMPTY
, "got %i, expected VT_EMPTY\n", V_VT(&var
));
526 ITypeInfo2_Release(pTypeInfo2
);
531 /* test invoking a method with a [restricted] keyword */
532 hr
= ITypeInfo_Invoke(pTypeInfo
, NULL
, dispidMember
, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
534 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
537 ITypeInfo_Release(pTypeInfo
);
538 ITypeLib_Release(pTypeLib
);
541 /* RegDeleteTreeW from dlls/advapi32/registry.c */
542 static LSTATUS
myRegDeleteTreeW(HKEY hKey
, LPCWSTR lpszSubKey
)
545 DWORD dwMaxSubkeyLen
, dwMaxValueLen
;
546 DWORD dwMaxLen
, dwSize
;
547 WCHAR szNameBuf
[MAX_PATH
], *lpszName
= szNameBuf
;
552 ret
= RegOpenKeyExW(hKey
, lpszSubKey
, 0, KEY_READ
, &hSubKey
);
556 ret
= RegQueryInfoKeyW(hSubKey
, NULL
, NULL
, NULL
, NULL
,
557 &dwMaxSubkeyLen
, NULL
, NULL
, &dwMaxValueLen
, NULL
, NULL
, NULL
);
558 if (ret
) goto cleanup
;
562 dwMaxLen
= max(dwMaxSubkeyLen
, dwMaxValueLen
);
563 if (dwMaxLen
> sizeof(szNameBuf
)/sizeof(WCHAR
))
565 /* Name too big: alloc a buffer for it */
566 if (!(lpszName
= HeapAlloc( GetProcessHeap(), 0, dwMaxLen
*sizeof(WCHAR
))))
568 ret
= ERROR_NOT_ENOUGH_MEMORY
;
573 /* Recursively delete all the subkeys */
577 if (RegEnumKeyExW(hSubKey
, 0, lpszName
, &dwSize
, NULL
,
578 NULL
, NULL
, NULL
)) break;
580 ret
= myRegDeleteTreeW(hSubKey
, lpszName
);
581 if (ret
) goto cleanup
;
585 ret
= RegDeleteKeyW(hKey
, lpszSubKey
);
590 if (RegEnumValueW(hKey
, 0, lpszName
, &dwSize
,
591 NULL
, NULL
, NULL
, NULL
)) break;
593 ret
= RegDeleteValueW(hKey
, lpszName
);
594 if (ret
) goto cleanup
;
598 if (lpszName
!= szNameBuf
)
599 HeapFree(GetProcessHeap(), 0, lpszName
);
601 RegCloseKey(hSubKey
);
605 static BOOL
do_typelib_reg_key(GUID
*uid
, WORD maj
, WORD min
, LPCWSTR base
, BOOL remove
)
607 static const WCHAR typelibW
[] = {'T','y','p','e','l','i','b','\\',0};
608 static const WCHAR formatW
[] = {'\\','%','u','.','%','u','\\','0','\\','w','i','n','3','2',0};
609 static const WCHAR format2W
[] = {'%','s','_','%','u','_','%','u','.','d','l','l',0};
615 memcpy(buf
, typelibW
, sizeof(typelibW
));
616 StringFromGUID2(uid
, buf
+ lstrlenW(buf
), 40);
620 ok(myRegDeleteTreeW(HKEY_CLASSES_ROOT
, buf
) == ERROR_SUCCESS
, "SHDeleteKey failed\n");
624 wsprintfW(buf
+ lstrlenW(buf
), formatW
, maj
, min
);
626 SetLastError(0xdeadbeef);
627 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, buf
, 0, NULL
, 0,
628 KEY_WRITE
, NULL
, &hkey
, NULL
);
629 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
631 win_skip("W-calls are not implemented\n");
635 if (res
!= ERROR_SUCCESS
)
637 trace("RegCreateKeyExW failed\n");
641 wsprintfW(buf
, format2W
, base
, maj
, min
);
642 if (RegSetValueExW(hkey
, NULL
, 0, REG_SZ
,
643 (BYTE
*)buf
, (lstrlenW(buf
) + 1) * sizeof(WCHAR
)) != ERROR_SUCCESS
)
645 trace("RegSetValueExW failed\n");
652 static void test_QueryPathOfRegTypeLib(void)
654 static const struct test_data
658 const WCHAR path
[16];
660 { 1, 0, TYPE_E_LIBNOTREGISTERED
, { 0 } },
661 { 3, 0, S_OK
, {'f','a','k','e','_','3','_','0','.','d','l','l',0 } },
662 { 3, 1, S_OK
, {'f','a','k','e','_','3','_','1','.','d','l','l',0 } },
663 { 3, 22, S_OK
, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
664 { 3, 37, S_OK
, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
665 { 3, 40, S_OK
, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
666 { 0xffff, 0xffff, S_OK
, {'f','a','k','e','_','5','_','3','7','.','d','l','l',0 } },
667 { 0xffff, 0, TYPE_E_LIBNOTREGISTERED
, { 0 } },
668 { 3, 0xffff, TYPE_E_LIBNOTREGISTERED
, { 0 } },
669 { 5, 0xffff, TYPE_E_LIBNOTREGISTERED
, { 0 } },
670 { 4, 0, TYPE_E_LIBNOTREGISTERED
, { 0 } }
672 static const WCHAR base
[] = {'f','a','k','e',0};
680 status
= UuidCreate(&uid
);
681 ok(!status
|| status
== RPC_S_UUID_LOCAL_ONLY
, "UuidCreate error %08x\n", status
);
683 StringFromGUID2(&uid
, uid_str
, 40);
684 /*trace("GUID: %s\n", wine_dbgstr_w(uid_str));*/
686 if (!do_typelib_reg_key(&uid
, 3, 0, base
, 0)) return;
687 if (!do_typelib_reg_key(&uid
, 3, 1, base
, 0)) return;
688 if (!do_typelib_reg_key(&uid
, 3, 37, base
, 0)) return;
689 if (!do_typelib_reg_key(&uid
, 5, 37, base
, 0)) return;
691 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
693 ret
= QueryPathOfRegTypeLib(&uid
, td
[i
].maj
, td
[i
].min
, 0, &path
);
694 ok(ret
== td
[i
].ret
, "QueryPathOfRegTypeLib(%u.%u) returned %08x\n", td
[i
].maj
, td
[i
].min
, ret
);
697 ok(!lstrcmpW(td
[i
].path
, path
), "typelib %u.%u path doesn't match\n", td
[i
].maj
, td
[i
].min
);
702 do_typelib_reg_key(&uid
, 0, 0, NULL
, 1);
705 static void test_inheritance(void)
709 ITypeInfo
*pTI
, *pTI_p
;
713 WCHAR path
[MAX_PATH
];
714 CHAR pathA
[MAX_PATH
];
715 static const WCHAR tl_path
[] = {'.','\\','m','i','d','l','_','t','m','a','r','s','h','a','l','.','t','l','b',0};
717 BOOL use_midl_tlb
= 0;
719 GetModuleFileNameA(NULL
, pathA
, MAX_PATH
);
720 MultiByteToWideChar(CP_ACP
, 0, pathA
, -1, path
, MAX_PATH
);
723 memcpy(path
, tl_path
, sizeof(tl_path
));
725 hr
= LoadTypeLib(path
, &pTL
);
726 if(FAILED(hr
)) return;
729 /* ItestIF3 is a syntax 2 dispinterface */
730 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &DIID_ItestIF3
, &pTI
);
731 ok(hr
== S_OK
, "hr %08x\n", hr
);
733 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
734 ok(hr
== S_OK
, "hr %08x\n", hr
);
735 ok(pTA
->typekind
== TKIND_DISPATCH
, "kind %04x\n", pTA
->typekind
);
736 ok(pTA
->cbSizeVft
== 7 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
737 ok(pTA
->wTypeFlags
== TYPEFLAG_FDISPATCHABLE
, "typeflags %x\n", pTA
->wTypeFlags
);
739 ok(pTA
->cFuncs
== 6, "cfuncs %d\n", pTA
->cFuncs
);
740 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
742 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
745 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, 0, &href
);
746 ok(hr
== S_OK
, "hr %08x\n", hr
);
747 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
748 ok(hr
== S_OK
, "hr %08x\n", hr
);
749 hr
= ITypeInfo_GetTypeAttr(pTI_p
, &pTA
);
750 ok(IsEqualGUID(&pTA
->guid
, &IID_IDispatch
), "guid {%08x-....\n", pTA
->guid
.Data1
);
751 ITypeInfo_ReleaseTypeAttr(pTI_p
, pTA
);
752 ITypeInfo_Release(pTI_p
);
754 /* Should have six methods */
755 hr
= ITypeInfo_GetFuncDesc(pTI
, 6, &pFD
);
756 ok(hr
== TYPE_E_ELEMENTNOTFOUND
, "hr %08x\n", hr
);
757 hr
= ITypeInfo_GetFuncDesc(pTI
, 5, &pFD
);
758 ok(hr
== S_OK
, "hr %08x\n", hr
);
759 ok(pFD
->memid
== 0x60020000, "memid %08x\n", pFD
->memid
);
760 ok(pFD
->oVft
== 5 * sizeof(void *), "oVft %d\n", pFD
->oVft
);
761 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
763 ITypeInfo_Release(pTI
);
766 /* ItestIF4 is a syntax 1 dispinterface */
767 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &DIID_ItestIF4
, &pTI
);
768 ok(hr
== S_OK
, "hr %08x\n", hr
);
770 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
771 ok(hr
== S_OK
, "hr %08x\n", hr
);
772 ok(pTA
->typekind
== TKIND_DISPATCH
, "kind %04x\n", pTA
->typekind
);
773 ok(pTA
->cbSizeVft
== 7 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
774 ok(pTA
->wTypeFlags
== TYPEFLAG_FDISPATCHABLE
, "typeflags %x\n", pTA
->wTypeFlags
);
775 ok(pTA
->cFuncs
== 1, "cfuncs %d\n", pTA
->cFuncs
);
776 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
777 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
779 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, 0, &href
);
780 ok(hr
== S_OK
, "hr %08x\n", hr
);
781 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
782 ok(hr
== S_OK
, "hr %08x\n", hr
);
783 hr
= ITypeInfo_GetTypeAttr(pTI_p
, &pTA
);
784 ok(IsEqualGUID(&pTA
->guid
, &IID_IDispatch
), "guid {%08x-....\n", pTA
->guid
.Data1
);
785 ITypeInfo_ReleaseTypeAttr(pTI_p
, pTA
);
786 ITypeInfo_Release(pTI_p
);
787 hr
= ITypeInfo_GetFuncDesc(pTI
, 1, &pFD
);
788 ok(hr
== TYPE_E_ELEMENTNOTFOUND
, "hr %08x\n", hr
);
789 hr
= ITypeInfo_GetFuncDesc(pTI
, 0, &pFD
);
790 ok(hr
== S_OK
, "hr %08x\n", hr
);
791 ok(pFD
->memid
== 0x1c, "memid %08x\n", pFD
->memid
);
792 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
793 ITypeInfo_Release(pTI
);
796 /* ItestIF5 is dual with inherited ifaces which derive from IUnknown but not IDispatch */
797 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &IID_ItestIF5
, &pTI
);
798 ok(hr
== S_OK
, "hr %08x\n", hr
);
800 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
801 ok(hr
== S_OK
, "hr %08x\n", hr
);
804 ok(pTA
->typekind
== TKIND_DISPATCH
, "kind %04x\n", pTA
->typekind
);
805 ok(pTA
->cbSizeVft
== 7 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
807 ok(pTA
->wTypeFlags
== TYPEFLAG_FDUAL
, "typeflags %x\n", pTA
->wTypeFlags
);
809 ok(pTA
->cFuncs
== 8, "cfuncs %d\n", pTA
->cFuncs
);
810 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
811 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
813 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, 0, &href
);
814 ok(hr
== S_OK
, "hr %08x\n", hr
);
815 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
816 ok(hr
== S_OK
, "hr %08x\n", hr
);
817 hr
= ITypeInfo_GetTypeAttr(pTI_p
, &pTA
);
818 ok(IsEqualGUID(&pTA
->guid
, &IID_IDispatch
), "guid {%08x-....\n", pTA
->guid
.Data1
);
819 ITypeInfo_ReleaseTypeAttr(pTI_p
, pTA
);
820 ITypeInfo_Release(pTI_p
);
822 hr
= ITypeInfo_GetFuncDesc(pTI
, 6, &pFD
);
823 ok(hr
== S_OK
, "hr %08x\n", hr
);
824 ok(pFD
->memid
== 0x1234, "memid %08x\n", pFD
->memid
);
825 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
827 ITypeInfo_Release(pTI
);
829 /* ItestIF7 is dual with inherited ifaces which derive from Dispatch */
830 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &IID_ItestIF7
, &pTI
);
831 ok(hr
== S_OK
, "hr %08x\n", hr
);
833 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
834 ok(hr
== S_OK
, "hr %08x\n", hr
);
835 ok(pTA
->typekind
== TKIND_DISPATCH
, "kind %04x\n", pTA
->typekind
);
836 ok(pTA
->cbSizeVft
== 7 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
837 ok(pTA
->wTypeFlags
== (TYPEFLAG_FDISPATCHABLE
|TYPEFLAG_FDUAL
), "typeflags %x\n", pTA
->wTypeFlags
);
838 ok(pTA
->cFuncs
== 10, "cfuncs %d\n", pTA
->cFuncs
);
839 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
840 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
842 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, 0, &href
);
843 ok(hr
== S_OK
, "hr %08x\n", hr
);
844 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
845 ok(hr
== S_OK
, "hr %08x\n", hr
);
846 hr
= ITypeInfo_GetTypeAttr(pTI_p
, &pTA
);
847 ok(IsEqualGUID(&pTA
->guid
, &IID_IDispatch
), "guid {%08x-....\n", pTA
->guid
.Data1
);
848 ITypeInfo_ReleaseTypeAttr(pTI_p
, pTA
);
849 ITypeInfo_Release(pTI_p
);
851 hr
= ITypeInfo_GetFuncDesc(pTI
, 9, &pFD
);
852 ok(hr
== S_OK
, "hr %08x\n", hr
);
853 ok(pFD
->memid
== 0x1236, "memid %08x\n", pFD
->memid
);
854 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
855 ITypeInfo_Release(pTI
);
857 /* ItestIF10 is a syntax 2 dispinterface which doesn't derive from IUnknown */
858 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &DIID_ItestIF10
, &pTI
);
859 ok(hr
== S_OK
, "hr %08x\n", hr
);
861 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
862 ok(hr
== S_OK
, "hr %08x\n", hr
);
863 ok(pTA
->typekind
== TKIND_DISPATCH
, "kind %04x\n", pTA
->typekind
);
864 ok(pTA
->cbSizeVft
== 7 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
865 ok(pTA
->wTypeFlags
== TYPEFLAG_FDISPATCHABLE
, "typeflags %x\n", pTA
->wTypeFlags
);
867 ok(pTA
->cFuncs
== 3, "cfuncs %d\n", pTA
->cFuncs
);
868 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
870 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
873 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, -1, &href
);
874 ok(hr
== TYPE_E_ELEMENTNOTFOUND
, "hr %08x\n", hr
);
875 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, 0, &href
);
876 ok(hr
== S_OK
, "hr %08x\n", hr
);
877 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
878 ok(hr
== S_OK
, "hr %08x\n", hr
);
879 hr
= ITypeInfo_GetTypeAttr(pTI_p
, &pTA
);
880 ok(IsEqualGUID(&pTA
->guid
, &IID_IDispatch
), "guid {%08x-....\n", pTA
->guid
.Data1
);
881 ITypeInfo_ReleaseTypeAttr(pTI_p
, pTA
);
882 ITypeInfo_Release(pTI_p
);
884 /* Should have three methods */
885 hr
= ITypeInfo_GetFuncDesc(pTI
, 3, &pFD
);
886 ok(hr
== TYPE_E_ELEMENTNOTFOUND
, "hr %08x\n", hr
);
887 hr
= ITypeInfo_GetFuncDesc(pTI
, 2, &pFD
);
888 ok(hr
== S_OK
, "hr %08x\n", hr
);
889 ok(pFD
->memid
== 0x60010000, "memid %08x\n", pFD
->memid
);
890 ok(pFD
->oVft
== 2 * sizeof(void *), "oVft %d\n", pFD
->oVft
);
891 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
893 ITypeInfo_Release(pTI
);
895 /* ItestIF11 is a syntax 2 dispinterface which derives from IDispatch */
896 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &DIID_ItestIF11
, &pTI
);
897 ok(hr
== S_OK
, "hr %08x\n", hr
);
899 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
900 ok(hr
== S_OK
, "hr %08x\n", hr
);
901 ok(pTA
->typekind
== TKIND_DISPATCH
, "kind %04x\n", pTA
->typekind
);
902 ok(pTA
->cbSizeVft
== 7 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
903 ok(pTA
->wTypeFlags
== TYPEFLAG_FDISPATCHABLE
, "typeflags %x\n", pTA
->wTypeFlags
);
905 ok(pTA
->cFuncs
== 10, "cfuncs %d\n", pTA
->cFuncs
);
906 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
908 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
911 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, 0, &href
);
912 ok(hr
== S_OK
, "hr %08x\n", hr
);
913 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
914 ok(hr
== S_OK
, "hr %08x\n", hr
);
915 hr
= ITypeInfo_GetTypeAttr(pTI_p
, &pTA
);
916 ok(IsEqualGUID(&pTA
->guid
, &IID_IDispatch
), "guid {%08x-....\n", pTA
->guid
.Data1
);
917 ITypeInfo_ReleaseTypeAttr(pTI_p
, pTA
);
918 ITypeInfo_Release(pTI_p
);
920 /* Should have ten methods */
921 hr
= ITypeInfo_GetFuncDesc(pTI
, 10, &pFD
);
922 ok(hr
== TYPE_E_ELEMENTNOTFOUND
, "hr %08x\n", hr
);
923 hr
= ITypeInfo_GetFuncDesc(pTI
, 9, &pFD
);
924 ok(hr
== S_OK
, "hr %08x\n", hr
);
925 ok(pFD
->memid
== 0x1236, "memid %08x\n", pFD
->memid
);
926 ok(pFD
->oVft
== 9 * sizeof(void *), "oVft %d\n", pFD
->oVft
);
928 /* first argument to 10th function is an HREFTYPE from the impl type */
929 ok(pFD
->cParams
== 1, "cParams %i\n", pFD
->cParams
);
930 ok(pFD
->lprgelemdescParam
[0].tdesc
.vt
== VT_USERDEFINED
,
931 "vt 0x%x\n", pFD
->lprgelemdescParam
[0].tdesc
.vt
);
932 href
= U(pFD
->lprgelemdescParam
[0].tdesc
).hreftype
;
933 ok((href
& 0xff000000) == 0x04000000, "href 0x%08x\n", href
);
934 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
935 ok(SUCCEEDED(hr
), "hr %08x\n", hr
);
936 if (SUCCEEDED(hr
)) ITypeInfo_Release(pTI_p
);
937 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
939 ITypeInfo_Release(pTI
);
942 /* ItestIF2 is an interface which derives from IUnknown */
943 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &IID_ItestIF2
, &pTI
);
944 ok(hr
== S_OK
, "hr %08x\n", hr
);
946 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
947 ok(hr
== S_OK
, "hr %08x\n", hr
);
948 ok(pTA
->typekind
== TKIND_INTERFACE
, "kind %04x\n", pTA
->typekind
);
949 ok(pTA
->cbSizeVft
== 6 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
950 ok(pTA
->wTypeFlags
== 0, "typeflags %x\n", pTA
->wTypeFlags
);
952 ok(pTA
->cFuncs
== 1, "cfuncs %d\n", pTA
->cFuncs
);
953 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
955 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
958 /* Should have one method */
959 hr
= ITypeInfo_GetFuncDesc(pTI
, 1, &pFD
);
960 ok(hr
== TYPE_E_ELEMENTNOTFOUND
, "hr %08x\n", hr
);
961 hr
= ITypeInfo_GetFuncDesc(pTI
, 0, &pFD
);
962 ok(hr
== S_OK
, "hr %08x\n", hr
);
963 ok(pFD
->memid
== 0x60020000, "memid %08x\n", pFD
->memid
);
964 ok(pFD
->oVft
== 5 * sizeof(void *), "oVft %d\n", pFD
->oVft
);
965 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
967 ITypeInfo_Release(pTI
);
969 ITypeLib_Release(pTL
);
974 static void test_CreateTypeLib(void) {
975 static const WCHAR stdoleW
[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
976 static OLECHAR typelibW
[] = {'t','y','p','e','l','i','b',0};
977 static OLECHAR helpfileW
[] = {'C',':','\\','b','o','g','u','s','.','h','l','p',0};
978 static OLECHAR interface1W
[] = {'i','n','t','e','r','f','a','c','e','1',0};
979 static OLECHAR interface2W
[] = {'i','n','t','e','r','f','a','c','e','2',0};
980 static OLECHAR interface3W
[] = {'i','n','t','e','r','f','a','c','e','3',0};
981 static OLECHAR dualW
[] = {'d','u','a','l',0};
982 static OLECHAR coclassW
[] = {'c','o','c','l','a','s','s',0};
983 static WCHAR defaultW
[] = {'d','e','f','a','u','l','t',0x3213,0};
984 static OLECHAR func1W
[] = {'f','u','n','c','1',0};
985 static OLECHAR func2W
[] = {'f','u','n','c','2',0};
986 static OLECHAR prop1W
[] = {'P','r','o','p','1',0};
987 static OLECHAR param1W
[] = {'p','a','r','a','m','1',0};
988 static OLECHAR param2W
[] = {'p','a','r','a','m','2',0};
989 static OLECHAR
*names1
[] = {func1W
, param1W
, param2W
};
990 static OLECHAR
*names2
[] = {func2W
, param1W
, param2W
};
991 static OLECHAR
*propname
[] = {prop1W
, param1W
};
992 static const GUID custguid
= {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x70}};
994 char filename
[MAX_PATH
];
995 WCHAR filenameW
[MAX_PATH
];
996 ICreateTypeLib2
*createtl
;
997 ICreateTypeInfo
*createti
;
998 ICreateTypeInfo2
*createti2
;
999 ITypeLib
*tl
, *stdole
;
1000 ITypeInfo
*interface1
, *interface2
, *dual
, *unknown
, *dispatch
, *ti
;
1003 ELEMDESC elemdesc
[5];
1004 PARAMDESCEX paramdescex
;
1005 TYPEDESC typedesc1
, typedesc2
;
1009 BSTR name
, docstring
, helpfile
;
1015 trace("CreateTypeLib tests\n");
1017 hres
= LoadTypeLib(stdoleW
, &stdole
);
1018 ok(hres
== S_OK
, "got %08x\n", hres
);
1020 hres
= ITypeLib_GetTypeInfoOfGuid(stdole
, &IID_IUnknown
, &unknown
);
1021 ok(hres
== S_OK
, "got %08x\n", hres
);
1023 hres
= ITypeLib_GetTypeInfoOfGuid(stdole
, &IID_IDispatch
, &dispatch
);
1024 ok(hres
== S_OK
, "got %08x\n", hres
);
1026 GetTempFileNameA(".", "tlb", 0, filename
);
1027 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filenameW
, MAX_PATH
);
1029 hres
= CreateTypeLib2(SYS_WIN32
, filenameW
, &createtl
);
1030 ok(hres
== S_OK
, "got %08x\n", hres
);
1032 hres
= ICreateTypeLib_QueryInterface(createtl
, &IID_ITypeLib
, (void**)&tl
);
1033 ok(hres
== S_OK
, "got %08x\n", hres
);
1035 hres
= ITypeLib_GetLibAttr(tl
, &libattr
);
1036 ok(hres
== S_OK
, "got %08x\n", hres
);
1038 ok(libattr
->syskind
== SYS_WIN32
, "syskind = %d\n", libattr
->syskind
);
1039 ok(libattr
->wMajorVerNum
== 0, "wMajorVer = %d\n", libattr
->wMajorVerNum
);
1040 ok(libattr
->wMinorVerNum
== 0, "wMinorVerNum = %d\n", libattr
->wMinorVerNum
);
1041 ok(libattr
->wLibFlags
== 0, "wLibFlags = %d\n", libattr
->wLibFlags
);
1043 ITypeLib_ReleaseTLibAttr(tl
, libattr
);
1045 name
= (BSTR
)0xdeadbeef;
1046 hres
= ITypeLib_GetDocumentation(tl
, -1, &name
, &docstring
, &helpcontext
, &helpfile
);
1047 ok(hres
== S_OK
, "got %08x\n", hres
);
1048 ok(name
== NULL
, "name != NULL\n");
1049 ok(docstring
== NULL
, "docstring != NULL\n");
1050 ok(helpcontext
== 0, "helpcontext != 0\n");
1051 ok(helpfile
== NULL
, "helpfile != NULL\n");
1053 hres
= ITypeLib_GetDocumentation(tl
, 0, &name
, NULL
, NULL
, NULL
);
1054 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1056 hres
= ICreateTypeLib_SetName(createtl
, typelibW
);
1057 ok(hres
== S_OK
, "got %08x\n", hres
);
1059 hres
= ICreateTypeLib_SetHelpFileName(createtl
, helpfileW
);
1060 ok(hres
== S_OK
, "got %08x\n", hres
);
1062 hres
= ITypeLib_GetDocumentation(tl
, -1, NULL
, NULL
, NULL
, NULL
);
1063 ok(hres
== S_OK
, "got %08x\n", hres
);
1065 hres
= ITypeLib_GetDocumentation(tl
, -1, &name
, NULL
, NULL
, &helpfile
);
1066 ok(hres
== S_OK
, "got %08x\n", hres
);
1067 ok(!memcmp(name
, typelibW
, sizeof(typelibW
)), "name = %s\n", wine_dbgstr_w(name
));
1068 ok(!memcmp(helpfile
, helpfileW
, sizeof(helpfileW
)), "helpfile = %s\n", wine_dbgstr_w(helpfile
));
1070 SysFreeString(name
);
1071 SysFreeString(helpfile
);
1073 hres
= ICreateTypeLib_CreateTypeInfo(createtl
, interface1W
, TKIND_INTERFACE
, &createti
);
1074 ok(hres
== S_OK
, "got %08x\n", hres
);
1076 hres
= ICreateTypeInfo_QueryInterface(createti
, &IID_ITypeInfo
, (void**)&interface1
);
1077 ok(hres
== S_OK
, "got %08x\n", hres
);
1079 hres
= ITypeLib_GetDocumentation(tl
, 0, &name
, NULL
, NULL
, NULL
);
1080 ok(hres
== S_OK
, "got %08x\n", hres
);
1081 ok(!memcmp(name
, interface1W
, sizeof(interface1W
)), "name = %s\n", wine_dbgstr_w(name
));
1083 SysFreeString(name
);
1085 ITypeLib_Release(tl
);
1087 name
= (BSTR
)0xdeadbeef;
1088 helpfile
= (BSTR
)0xdeadbeef;
1089 hres
= ITypeInfo_GetDocumentation(interface1
, -1, &name
, &docstring
, &helpcontext
, &helpfile
);
1090 ok(hres
== S_OK
, "got %08x\n", hres
);
1091 ok(!memcmp(name
, interface1W
, sizeof(interface1W
)), "name = %s\n", wine_dbgstr_w(name
));
1092 ok(docstring
== NULL
, "docstring != NULL\n");
1093 ok(helpcontext
== 0, "helpcontext != 0\n");
1094 ok(!memcmp(helpfile
, helpfileW
, sizeof(helpfileW
)), "helpfile = %s\n", wine_dbgstr_w(helpfile
));
1096 SysFreeString(name
);
1097 SysFreeString(helpfile
);
1099 hres
= ITypeInfo_GetDocumentation(interface1
, 0, &name
, NULL
, NULL
, NULL
);
1100 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1102 hres
= ITypeInfo_GetRefTypeInfo(interface1
, 0, NULL
);
1103 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1106 hres
= ICreateTypeInfo_LayOut(createti
);
1107 ok(hres
== S_OK
, "got %08x\n", hres
);
1109 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, NULL
, &hreftype
);
1110 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1112 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, unknown
, NULL
);
1113 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1115 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, unknown
, &hreftype
);
1116 ok(hres
== S_OK
, "got %08x\n", hres
);
1118 skip("Skipping some tests\n");
1122 hres
= ICreateTypeInfo_AddImplType(createti
, 1, hreftype
);
1123 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1125 hres
= ICreateTypeInfo_AddImplType(createti
, 0, hreftype
);
1126 ok(hres
== S_OK
, "got %08x\n", hres
);
1128 hres
= ITypeInfo_GetRefTypeOfImplType(interface1
, 0, &hreftype
);
1129 ok(hres
== S_OK
, "got %08x\n", hres
);
1130 ok(hreftype
== 3, "hreftype = %d\n", hreftype
);
1132 hres
= ITypeInfo_GetRefTypeOfImplType(interface1
, -1, &hreftype
);
1133 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1135 memset(&funcdesc
, 0, sizeof(FUNCDESC
));
1136 funcdesc
.funckind
= FUNC_PUREVIRTUAL
;
1137 funcdesc
.invkind
= INVOKE_PROPERTYGET
;
1138 funcdesc
.callconv
= CC_STDCALL
;
1139 funcdesc
.elemdescFunc
.tdesc
.vt
= VT_BSTR
;
1140 U(funcdesc
.elemdescFunc
).idldesc
.wIDLFlags
= IDLFLAG_NONE
;
1142 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 0, NULL
);
1143 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1145 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 1, &funcdesc
);
1146 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1148 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 0, &funcdesc
);
1149 ok(hres
== S_OK
, "got %08x\n", hres
);
1151 hres
= ICreateTypeInfo_SetFuncHelpContext(createti
, 0, 0xabcdefab);
1152 ok(hres
== S_OK
, "got %08x\n", hres
);
1154 funcdesc
.invkind
= INVOKE_PROPERTYPUT
;
1155 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 1, &funcdesc
);
1156 ok(hres
== TYPE_E_INCONSISTENTPROPFUNCS
, "got %08x\n", hres
);
1158 funcdesc
.invkind
= INVOKE_PROPERTYPUTREF
;
1159 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 1, &funcdesc
);
1160 ok(hres
== TYPE_E_INCONSISTENTPROPFUNCS
, "got %08x\n", hres
);
1162 elemdesc
[0].tdesc
.vt
= VT_BSTR
;
1163 U(elemdesc
[0]).idldesc
.dwReserved
= 0;
1164 U(elemdesc
[0]).idldesc
.wIDLFlags
= IDLFLAG_FIN
;
1166 funcdesc
.lprgelemdescParam
= elemdesc
;
1167 funcdesc
.invkind
= INVOKE_PROPERTYPUT
;
1168 funcdesc
.cParams
= 1;
1169 funcdesc
.elemdescFunc
.tdesc
.vt
= VT_VOID
;
1171 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 1, &funcdesc
);
1172 ok(hres
== S_OK
, "got %08x\n", hres
);
1174 hres
= ICreateTypeInfo_SetFuncHelpContext(createti
, 1, 0xabcdefab);
1175 ok(hres
== S_OK
, "got %08x\n", hres
);
1177 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 0, propname
, 1);
1178 ok(hres
== S_OK
, "got %08x\n", hres
);
1180 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 1, propname
, 1);
1181 ok(hres
== S_OK
, "got %08x\n", hres
);
1183 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 1, propname
, 2);
1184 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1187 funcdesc
.invkind
= INVOKE_PROPERTYPUTREF
;
1188 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 0, &funcdesc
);
1189 ok(hres
== S_OK
, "got %08x\n", hres
);
1191 hres
= ICreateTypeInfo_SetFuncHelpContext(createti
, 0, 0xabcdefab);
1192 ok(hres
== S_OK
, "got %08x\n", hres
);
1194 hres
= ICreateTypeInfo_SetFuncHelpContext(createti
, 0, 0x201);
1195 ok(hres
== S_OK
, "got %08x\n", hres
);
1198 funcdesc
.lprgelemdescParam
= NULL
;
1199 funcdesc
.invkind
= INVOKE_FUNC
;
1200 funcdesc
.cParams
= 0;
1201 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 1, &funcdesc
);
1202 ok(hres
== S_OK
, "got %08x\n", hres
);
1204 funcdesc
.memid
= MEMBERID_NIL
;
1205 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 1, &funcdesc
);
1206 ok(hres
== S_OK
, "got %08x\n", hres
);
1208 elemdesc
[0].tdesc
.vt
= VT_PTR
;
1209 U(elemdesc
[0].tdesc
).lptdesc
= &typedesc1
;
1210 typedesc1
.vt
= VT_BSTR
;
1211 funcdesc
.cParams
= 1;
1212 funcdesc
.lprgelemdescParam
= elemdesc
;
1213 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 4, &funcdesc
);
1214 ok(hres
== S_OK
, "got %08x\n", hres
);
1216 U(elemdesc
[0].tdesc
).lptdesc
= &typedesc2
;
1217 typedesc2
.vt
= VT_PTR
;
1218 U(typedesc2
).lptdesc
= &typedesc1
;
1219 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 4, &funcdesc
);
1220 ok(hres
== S_OK
, "got %08x\n", hres
);
1222 elemdesc
[0].tdesc
.vt
= VT_INT
;
1223 U(elemdesc
[0]).paramdesc
.wParamFlags
= PARAMFLAG_FHASDEFAULT
;
1224 U(elemdesc
[0]).paramdesc
.pparamdescex
= ¶mdescex
;
1225 V_VT(¶mdescex
.varDefaultValue
) = VT_INT
;
1226 V_INT(¶mdescex
.varDefaultValue
) = 0x123;
1227 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 3, &funcdesc
);
1228 ok(hres
== S_OK
, "got %08x\n", hres
);
1230 U(elemdesc
[0]).idldesc
.dwReserved
= 0;
1231 U(elemdesc
[0]).idldesc
.wIDLFlags
= IDLFLAG_FIN
;
1232 elemdesc
[1].tdesc
.vt
= VT_UI2
;
1233 U(elemdesc
[1]).paramdesc
.wParamFlags
= PARAMFLAG_FHASDEFAULT
;
1234 U(elemdesc
[1]).paramdesc
.pparamdescex
= ¶mdescex
;
1235 V_VT(¶mdescex
.varDefaultValue
) = VT_UI2
;
1236 V_UI2(¶mdescex
.varDefaultValue
) = 0xffff;
1237 funcdesc
.cParams
= 2;
1238 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 3, &funcdesc
);
1239 ok(hres
== S_OK
, "got %08x\n", hres
);
1241 U(elemdesc
[0]).paramdesc
.wParamFlags
= PARAMFLAG_FHASDEFAULT
;
1242 U(elemdesc
[0]).paramdesc
.pparamdescex
= ¶mdescex
;
1243 elemdesc
[1].tdesc
.vt
= VT_INT
;
1244 V_VT(¶mdescex
.varDefaultValue
) = VT_INT
;
1245 V_INT(¶mdescex
.varDefaultValue
) = 0xffffffff;
1246 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 3, &funcdesc
);
1247 ok(hres
== S_OK
, "got %08x\n", hres
);
1249 elemdesc
[0].tdesc
.vt
= VT_BSTR
;
1250 elemdesc
[1].tdesc
.vt
= VT_BSTR
;
1251 V_VT(¶mdescex
.varDefaultValue
) = VT_BSTR
;
1252 V_BSTR(¶mdescex
.varDefaultValue
) = SysAllocString(defaultW
);
1253 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 3, &funcdesc
);
1254 ok(hres
== S_OK
, "got %08x\n", hres
);
1256 hres
= ITypeInfo_GetDocumentation(interface1
, 0, &name
, &docstring
, &helpcontext
, &helpfile
);
1257 ok(hres
== S_OK
, "got %08x\n", hres
);
1258 ok(name
== NULL
, "name != NULL\n");
1259 ok(docstring
== NULL
, "docstring != NULL\n");
1260 ok(helpcontext
== 0x201, "helpcontext != 0x201\n");
1261 ok(!memcmp(helpfile
, helpfileW
, sizeof(helpfileW
)), "helpfile = %s\n", wine_dbgstr_w(helpfile
));
1263 SysFreeString(helpfile
);
1265 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 1000, NULL
, 1);
1266 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1268 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 1000, names1
, 1);
1269 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1271 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 0, names1
, 2);
1272 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1274 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 0, names2
, 1);
1275 ok(hres
== S_OK
, "got %08x\n", hres
);
1277 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 0, names1
, 1);
1278 ok(hres
== S_OK
, "got %08x\n", hres
);
1280 hres
= ITypeInfo_GetDocumentation(interface1
, 0, &name
, NULL
, NULL
, NULL
);
1281 ok(hres
== S_OK
, "got %08x\n", hres
);
1282 ok(!memcmp(name
, func1W
, sizeof(func1W
)), "name = %s\n", wine_dbgstr_w(name
));
1284 SysFreeString(name
);
1286 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 3, names2
, 3);
1287 ok(hres
== S_OK
, "got %08x\n", hres
);
1289 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 3, names1
, 3);
1290 ok(hres
== TYPE_E_AMBIGUOUSNAME
, "got %08x\n", hres
);
1292 ICreateTypeInfo_Release(createti
);
1294 hres
= ICreateTypeLib_CreateTypeInfo(createtl
, interface1W
, TKIND_INTERFACE
, &createti
);
1295 ok(hres
== TYPE_E_NAMECONFLICT
, "got %08x\n", hres
);
1297 hres
= ICreateTypeLib_CreateTypeInfo(createtl
, interface2W
, TKIND_INTERFACE
, &createti
);
1298 ok(hres
== S_OK
, "got %08x\n", hres
);
1300 hres
= ICreateTypeInfo_QueryInterface(createti
, &IID_ITypeInfo
, (void**)&interface2
);
1301 ok(hres
== S_OK
, "got %08x\n", hres
);
1303 hres
= ITypeInfo_GetRefTypeOfImplType(interface2
, 0, &hreftype
);
1304 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1306 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, interface1
, &hreftype
);
1307 ok(hres
== S_OK
, "got %08x\n", hres
);
1309 hres
= ITypeInfo_GetRefTypeInfo(interface2
, 0, &ti
);
1310 ok(hres
== S_OK
, "got %08x\n", hres
);
1311 ok(ti
== interface1
, "Received and added interfaces are different\n");
1313 ITypeInfo_Release(ti
);
1315 hres
= ICreateTypeInfo_AddImplType(createti
, 0, hreftype
);
1316 ok(hres
== S_OK
, "got %08x\n", hres
);
1318 hres
= ITypeInfo_GetRefTypeOfImplType(interface2
, 0, &hreftype
);
1319 ok(hres
== S_OK
, "got %08x\n", hres
);
1320 ok(hreftype
== 2, "hreftype = %d\n", hreftype
);
1322 hres
= ITypeInfo_GetRefTypeOfImplType(interface2
, -1, &hreftype
);
1323 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1325 hres
= ICreateTypeInfo_SetImplTypeFlags(createti
, 0, IMPLTYPEFLAG_FDEFAULT
);
1326 ok(hres
== TYPE_E_BADMODULEKIND
, "got %08x\n", hres
);
1328 hres
= ITypeInfo_GetImplTypeFlags(interface2
, 0, &impltypeflags
);
1329 ok(hres
== S_OK
, "got %08x\n", hres
);
1330 ok(impltypeflags
== 0, "impltypeflags = %x\n", impltypeflags
);
1332 hres
= ITypeInfo_GetImplTypeFlags(interface2
, 1, &impltypeflags
);
1333 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1335 funcdesc
.oVft
= 0xaaac;
1336 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 0, &funcdesc
);
1337 ok(hres
== S_OK
, "got %08x\n", hres
);
1338 funcdesc
.oVft
= 0xaaa8;
1339 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 0, &funcdesc
);
1340 ok(hres
== S_OK
, "got %08x\n", hres
);
1343 ICreateTypeInfo_Release(createti
);
1345 VariantInit(&cust_data
);
1347 hres
= ICreateTypeLib_CreateTypeInfo(createtl
, interface3W
, TKIND_INTERFACE
, &createti
);
1348 ok(hres
== S_OK
, "got %08x\n", hres
);
1350 hres
= ICreateTypeInfo_QueryInterface(createti
, &IID_ICreateTypeInfo2
, (void**)&createti2
);
1351 ok(hres
== S_OK
, "got %08x\n", hres
);
1353 hres
= ICreateTypeInfo2_QueryInterface(createti2
, &IID_ITypeInfo2
, (void**)&ti2
);
1354 ok(hres
== S_OK
, "got %08x\n", hres
);
1356 hres
= ITypeInfo2_GetCustData(ti2
, NULL
, NULL
);
1358 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1360 hres
= ITypeInfo2_GetCustData(ti2
, &custguid
, NULL
);
1362 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1364 hres
= ITypeInfo2_GetCustData(ti2
, &custguid
, &cust_data
);
1366 ok(hres
== S_OK
, "got %08x\n", hres
);
1368 hres
= ICreateTypeInfo2_SetCustData(createti2
, NULL
, NULL
);
1369 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1371 hres
= ICreateTypeInfo2_SetCustData(createti2
, &custguid
, NULL
);
1372 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1374 hres
= ICreateTypeInfo2_SetCustData(createti2
, &custguid
, &cust_data
);
1375 ok(hres
== DISP_E_BADVARTYPE
, "got %08x\n", hres
);
1377 V_VT(&cust_data
) = VT_UI4
;
1378 V_I4(&cust_data
) = 0xdeadbeef;
1380 hres
= ICreateTypeInfo2_SetCustData(createti2
, &custguid
, &cust_data
);
1381 ok(hres
== S_OK
, "got %08x\n", hres
);
1383 V_I4(&cust_data
) = 0;
1384 V_VT(&cust_data
) = VT_EMPTY
;
1386 hres
= ITypeInfo2_GetCustData(ti2
, &custguid
, &cust_data
);
1388 ok(hres
== S_OK
, "got %08x\n", hres
);
1391 ok(V_VT(&cust_data
) == VT_UI4
, "got %d\n", V_VT(&cust_data
));
1393 ok(V_I4(&cust_data
) == 0xdeadbeef, "got 0x%08x\n", V_I4(&cust_data
));
1395 V_VT(&cust_data
) = VT_UI4
;
1396 V_I4(&cust_data
) = 12345678;
1398 hres
= ICreateTypeInfo2_SetCustData(createti2
, &custguid
, &cust_data
);
1399 ok(hres
== S_OK
, "got %08x\n", hres
);
1401 V_I4(&cust_data
) = 0;
1402 V_VT(&cust_data
) = VT_EMPTY
;
1404 hres
= ITypeInfo2_GetCustData(ti2
, &custguid
, &cust_data
);
1406 ok(hres
== S_OK
, "got %08x\n", hres
);
1409 ok(V_VT(&cust_data
) == VT_UI4
, "got %d\n", V_VT(&cust_data
));
1411 ok(V_I4(&cust_data
) == 12345678, "got 0x%08x\n", V_I4(&cust_data
));
1413 ITypeInfo2_Release(ti2
);
1414 ICreateTypeInfo2_Release(createti2
);
1415 ICreateTypeInfo_Release(createti
);
1417 hres
= ICreateTypeLib_CreateTypeInfo(createtl
, coclassW
, TKIND_COCLASS
, &createti
);
1418 ok(hres
== S_OK
, "got %08x\n", hres
);
1420 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, interface1
, &hreftype
);
1421 ok(hres
== S_OK
, "got %08x\n", hres
);
1423 hres
= ICreateTypeInfo_AddImplType(createti
, 0, hreftype
);
1424 ok(hres
== S_OK
, "got %08x\n", hres
);
1426 hres
= ICreateTypeInfo_AddImplType(createti
, 0, hreftype
);
1427 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1429 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, unknown
, &hreftype
);
1430 ok(hres
== S_OK
, "got %08x\n", hres
);
1432 hres
= ICreateTypeInfo_AddImplType(createti
, 1, hreftype
);
1433 ok(hres
== S_OK
, "got %08x\n", hres
);
1435 hres
= ICreateTypeInfo_AddImplType(createti
, 1, hreftype
);
1436 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1438 hres
= ICreateTypeInfo_AddImplType(createti
, 2, hreftype
);
1439 ok(hres
== S_OK
, "got %08x\n", hres
);
1441 hres
= ICreateTypeInfo_SetImplTypeFlags(createti
, 0, IMPLTYPEFLAG_FDEFAULT
);
1442 ok(hres
== S_OK
, "got %08x\n", hres
);
1444 hres
= ICreateTypeInfo_SetImplTypeFlags(createti
, 1, IMPLTYPEFLAG_FRESTRICTED
);
1445 ok(hres
== S_OK
, "got %08x\n", hres
);
1447 hres
= ICreateTypeInfo_QueryInterface(createti
, &IID_ITypeInfo
, (void**)&ti
);
1448 ok(hres
== S_OK
, "got %08x\n", hres
);
1450 hres
= ITypeInfo_GetImplTypeFlags(ti
, 0, NULL
);
1451 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1453 hres
= ITypeInfo_GetImplTypeFlags(ti
, 0, &impltypeflags
);
1454 ok(hres
== S_OK
, "got %08x\n", hres
);
1455 ok(impltypeflags
== IMPLTYPEFLAG_FDEFAULT
, "impltypeflags = %x\n", impltypeflags
);
1457 hres
= ITypeInfo_GetImplTypeFlags(ti
, 1, &impltypeflags
);
1458 ok(hres
== S_OK
, "got %08x\n", hres
);
1459 ok(impltypeflags
== IMPLTYPEFLAG_FRESTRICTED
, "impltypeflags = %x\n", impltypeflags
);
1461 hres
= ITypeInfo_GetImplTypeFlags(ti
, 2, &impltypeflags
);
1462 ok(hres
== S_OK
, "got %08x\n", hres
);
1463 ok(impltypeflags
== 0, "impltypeflags = %x\n", impltypeflags
);
1465 hres
= ITypeInfo_GetRefTypeOfImplType(ti
, 0, &hreftype
);
1466 ok(hres
== S_OK
, "got %08x\n", hres
);
1467 ok(hreftype
== 0, "hreftype = %d\n", hreftype
);
1469 hres
= ITypeInfo_GetRefTypeOfImplType(ti
, 1, &hreftype
);
1470 ok(hres
== S_OK
, "got %08x\n", hres
);
1471 ok(hreftype
== 1, "hreftype = %d\n", hreftype
);
1473 hres
= ITypeInfo_GetRefTypeOfImplType(ti
, 2, &hreftype
);
1474 ok(hres
== S_OK
, "got %08x\n", hres
);
1475 ok(hreftype
== 1, "hreftype = %d\n", hreftype
);
1477 hres
= ITypeInfo_GetRefTypeOfImplType(ti
, -1, &hreftype
);
1478 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1480 ITypeInfo_Release(ti
);
1482 ICreateTypeInfo_Release(createti
);
1484 hres
= ICreateTypeLib_CreateTypeInfo(createtl
, dualW
, TKIND_INTERFACE
, &createti
);
1485 ok(hres
== S_OK
, "got %08x\n", hres
);
1487 hres
= ICreateTypeInfo_SetTypeFlags(createti
, TYPEFLAG_FDUAL
);
1488 ok(hres
== S_OK
, "got %08x\n", hres
);
1490 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 0, &funcdesc
);
1491 ok(hres
== S_OK
, "got %08x\n", hres
);
1493 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, dispatch
, &hreftype
);
1494 ok(hres
== S_OK
, "got %08x\n", hres
);
1496 hres
= ICreateTypeInfo_AddImplType(createti
, 0, hreftype
);
1497 ok(hres
== S_OK
, "got %08x\n", hres
);
1499 hres
= ICreateTypeInfo_QueryInterface(createti
, &IID_ITypeInfo
, (void**)&dual
);
1500 ok(hres
== S_OK
, "got %08x\n", hres
);
1502 hres
= ITypeInfo_GetTypeAttr(dual
, &typeattr
);
1503 ok(hres
== S_OK
, "got %08x\n", hres
);
1504 ok(typeattr
->cbSizeInstance
== 4, "cbSizeInstance = %d\n", typeattr
->cbSizeInstance
);
1505 ok(typeattr
->typekind
== 3, "typekind = %d\n", typeattr
->typekind
);
1506 ok(typeattr
->cFuncs
== 1, "cFuncs = %d\n", typeattr
->cFuncs
);
1507 ok(typeattr
->cVars
== 0, "cVars = %d\n", typeattr
->cVars
);
1508 ok(typeattr
->cImplTypes
== 1, "cImplTypes = %d\n", typeattr
->cImplTypes
);
1509 ok(typeattr
->cbSizeVft
== 32 || broken(typeattr
->cbSizeVft
== 7 * sizeof(void *) + 4), /* xp64 */
1510 "cbSizeVft = %d\n", typeattr
->cbSizeVft
);
1511 ok(typeattr
->cbAlignment
== 4, "cbAlignment = %d\n", typeattr
->cbAlignment
);
1512 ok(typeattr
->wTypeFlags
== (TYPEFLAG_FDISPATCHABLE
|TYPEFLAG_FDUAL
), "wTypeFlags = %d\n", typeattr
->wTypeFlags
);
1513 ok(typeattr
->wMajorVerNum
== 0, "wMajorVerNum = %d\n", typeattr
->wMajorVerNum
);
1514 ok(typeattr
->wMinorVerNum
== 0, "wMinorVerNum = %d\n", typeattr
->wMinorVerNum
);
1516 ITypeInfo_ReleaseTypeAttr(dual
, typeattr
);
1518 hres
= ITypeInfo_GetRefTypeOfImplType(dual
, -1, &hreftype
);
1519 ok(hres
== S_OK
, "got %08x\n", hres
);
1520 ok(hreftype
== -2, "got %08x\n", hreftype
);
1522 hres
= ITypeInfo_GetRefTypeInfo(dual
, -2, &ti
);
1523 ok(hres
== S_OK
, "got %08x\n", hres
);
1525 hres
= ITypeInfo_GetTypeAttr(ti
, &typeattr
);
1526 ok(hres
== S_OK
, "got %08x\n", hres
);
1527 ok(typeattr
->cbSizeInstance
== 4, "cbSizeInstance = %d\n", typeattr
->cbSizeInstance
);
1528 ok(typeattr
->typekind
== 4, "typekind = %d\n", typeattr
->typekind
);
1529 ok(typeattr
->cFuncs
== 8, "cFuncs = %d\n", typeattr
->cFuncs
);
1530 ok(typeattr
->cVars
== 0, "cVars = %d\n", typeattr
->cVars
);
1531 ok(typeattr
->cImplTypes
== 1, "cImplTypes = %d\n", typeattr
->cImplTypes
);
1532 ok(typeattr
->cbSizeVft
== 7 * sizeof(void *), "cbSizeVft = %d\n", typeattr
->cbSizeVft
);
1533 ok(typeattr
->cbAlignment
== 4, "cbAlignment = %d\n", typeattr
->cbAlignment
);
1534 ok(typeattr
->wTypeFlags
== (TYPEFLAG_FDISPATCHABLE
|TYPEFLAG_FDUAL
), "wTypeFlags = %d\n", typeattr
->wTypeFlags
);
1535 ok(typeattr
->wMajorVerNum
== 0, "wMajorVerNum = %d\n", typeattr
->wMajorVerNum
);
1536 ok(typeattr
->wMinorVerNum
== 0, "wMinorVerNum = %d\n", typeattr
->wMinorVerNum
);
1538 ITypeInfo_ReleaseTypeAttr(ti
, typeattr
);
1540 ITypeInfo_Release(ti
);
1542 ICreateTypeInfo_Release(createti
);
1544 hres
= ITypeInfo_GetTypeAttr(interface1
, &typeattr
);
1545 ok(hres
== S_OK
, "got %08x\n", hres
);
1546 ok(typeattr
->cbSizeInstance
== 4, "cbSizeInstance = %d\n", typeattr
->cbSizeInstance
);
1547 ok(typeattr
->typekind
== 3, "typekind = %d\n", typeattr
->typekind
);
1548 ok(typeattr
->cFuncs
== 11, "cFuncs = %d\n", typeattr
->cFuncs
);
1549 ok(typeattr
->cVars
== 0, "cVars = %d\n", typeattr
->cVars
);
1550 ok(typeattr
->cImplTypes
== 1, "cImplTypes = %d\n", typeattr
->cImplTypes
);
1551 ok(typeattr
->cbSizeVft
== 56 || broken(typeattr
->cbSizeVft
== 3 * sizeof(void *) + 44), /* xp64 */
1552 "cbSizeVft = %d\n", typeattr
->cbSizeVft
);
1553 ok(typeattr
->cbAlignment
== 4, "cbAlignment = %d\n", typeattr
->cbAlignment
);
1554 ok(typeattr
->wTypeFlags
== 0, "wTypeFlags = %d\n", typeattr
->wTypeFlags
);
1555 ok(typeattr
->wMajorVerNum
== 0, "wMajorVerNum = %d\n", typeattr
->wMajorVerNum
);
1556 ok(typeattr
->wMinorVerNum
== 0, "wMinorVerNum = %d\n", typeattr
->wMinorVerNum
);
1558 ITypeInfo_ReleaseTypeAttr(interface1
, typeattr
);
1560 hres
= ITypeInfo_GetTypeAttr(interface2
, &typeattr
);
1561 ok(hres
== S_OK
, "got %08x\n", hres
);
1562 ok(typeattr
->cbSizeInstance
== 4, "cbSizeInstance = %d\n", typeattr
->cbSizeInstance
);
1563 ok(typeattr
->typekind
== 3, "typekind = %d\n", typeattr
->typekind
);
1564 ok(typeattr
->cFuncs
== 2, "cFuncs = %d\n", typeattr
->cFuncs
);
1565 ok(typeattr
->cVars
== 0, "cVars = %d\n", typeattr
->cVars
);
1566 ok(typeattr
->cImplTypes
== 1, "cImplTypes = %d\n", typeattr
->cImplTypes
);
1567 ok(typeattr
->cbSizeVft
== 43696, "cbSizeVft = %d\n", typeattr
->cbSizeVft
);
1568 ok(typeattr
->cbAlignment
== 4, "cbAlignment = %d\n", typeattr
->cbAlignment
);
1569 ok(typeattr
->wTypeFlags
== 0, "wTypeFlags = %d\n", typeattr
->wTypeFlags
);
1570 ok(typeattr
->wMajorVerNum
== 0, "wMajorVerNum = %d\n", typeattr
->wMajorVerNum
);
1571 ok(typeattr
->wMinorVerNum
== 0, "wMinorVerNum = %d\n", typeattr
->wMinorVerNum
);
1573 ITypeInfo_ReleaseTypeAttr(interface2
, typeattr
);
1575 hres
= ICreateTypeLib2_SaveAllChanges(createtl
);
1576 ok(hres
== S_OK
, "got %08x\n", hres
);
1578 ok(ITypeInfo_Release(interface2
)==0, "Object should be freed\n");
1579 ok(ITypeInfo_Release(interface1
)==0, "Object should be freed\n");
1580 ok(ITypeInfo_Release(dual
)==0, "Object should be freed\n");
1581 ok(ICreateTypeLib2_Release(createtl
)==0, "Object should be freed\n");
1583 ok(ITypeInfo_Release(dispatch
)==0, "Object should be freed\n");
1584 ok(ITypeInfo_Release(unknown
)==0, "Object should be freed\n");
1585 ok(ITypeLib_Release(stdole
)==0, "Object should be freed\n");
1587 hres
= LoadTypeLibEx(filenameW
, REGKIND_NONE
, &tl
);
1588 ok(hres
== S_OK
, "got %08x\n", hres
);
1589 ok(ITypeLib_Release(tl
)==0, "Object should be freed\n");
1591 DeleteFileA(filename
);
1594 #if 0 /* use this to generate more tests */
1596 #define OLE_CHECK(x) { HRESULT hr = x; if (FAILED(hr)) { printf(#x "failed - %x\n", hr); return; } }
1598 static char *dump_string(LPWSTR wstr
)
1600 int size
= lstrlenW(wstr
)+3;
1601 char *out
= CoTaskMemAlloc(size
);
1602 WideCharToMultiByte(20127, 0, wstr
, -1, out
+1, size
, NULL
, NULL
);
1614 #define MAP_ENTRY(x) { x, #x }
1615 static const struct map_entry tkind_map
[] = {
1616 MAP_ENTRY(TKIND_ENUM
),
1617 MAP_ENTRY(TKIND_RECORD
),
1618 MAP_ENTRY(TKIND_MODULE
),
1619 MAP_ENTRY(TKIND_INTERFACE
),
1620 MAP_ENTRY(TKIND_DISPATCH
),
1621 MAP_ENTRY(TKIND_COCLASS
),
1622 MAP_ENTRY(TKIND_ALIAS
),
1623 MAP_ENTRY(TKIND_UNION
),
1624 MAP_ENTRY(TKIND_MAX
),
1628 static const struct map_entry funckind_map
[] = {
1629 MAP_ENTRY(FUNC_VIRTUAL
),
1630 MAP_ENTRY(FUNC_PUREVIRTUAL
),
1631 MAP_ENTRY(FUNC_NONVIRTUAL
),
1632 MAP_ENTRY(FUNC_STATIC
),
1633 MAP_ENTRY(FUNC_DISPATCH
),
1637 static const struct map_entry invkind_map
[] = {
1638 MAP_ENTRY(INVOKE_FUNC
),
1639 MAP_ENTRY(INVOKE_PROPERTYGET
),
1640 MAP_ENTRY(INVOKE_PROPERTYPUT
),
1641 MAP_ENTRY(INVOKE_PROPERTYPUTREF
),
1647 static const char *map_value(DWORD val
, const struct map_entry
*map
)
1650 static char bufs
[16][256];
1655 if (map
->value
== val
)
1660 buf
= bufs
[(map_id
++)%16];
1661 sprintf(buf
, "0x%x", val
);
1665 static void test_dump_typelib(const char *name
)
1667 WCHAR wszString
[260];
1673 MultiByteToWideChar(CP_ACP
, 0, name
, -1, wszString
, 260);
1674 OLE_CHECK(LoadTypeLib(wszString
, &lib
));
1675 count
= ITypeLib_GetTypeInfoCount(lib
);
1676 printf("/* interfaces count: %d */\n", count
);
1677 for (i
= 0; i
< count
; i
++)
1683 OLE_CHECK(ITypeLib_GetDocumentation(lib
, i
, &name
, NULL
, NULL
, NULL
));
1685 " %s,\n", dump_string(name
));
1686 SysFreeString(name
);
1688 OLE_CHECK(ITypeLib_GetTypeInfo(lib
, i
, &info
));
1689 ITypeInfo_GetTypeAttr(info
, &attr
);
1690 printf(" /*kind*/ %s, /*flags*/ 0x%x, /*align*/ %d, /*size*/ %d,\n"
1691 " /*#vtbl*/ %d, /*#func*/ %d,\n"
1693 map_value(attr
->typekind
, tkind_map
), attr
->wTypeFlags
, attr
->cbAlignment
, attr
->cbSizeInstance
, attr
->cbSizeVft
,
1695 ITypeInfo_ReleaseTypeAttr(info
, attr
);
1703 if (FAILED(ITypeInfo_GetFuncDesc(info
, f
, &desc
)))
1706 " 0x%x, /*func*/ %s, /*inv*/ %s, /*call*/ 0x%x,\n",
1707 desc
->memid
, map_value(desc
->funckind
, funckind_map
), map_value(desc
->invkind
, invkind_map
),
1709 printf(" /*#param*/ %d, /*#opt*/ %d, /*vtbl*/ %d, /*#scodes*/ %d, /*flags*/ 0x%x,\n",
1710 desc
->cParams
, desc
->cParamsOpt
, desc
->oVft
, desc
->cScodes
, desc
->wFuncFlags
);
1711 printf(" {%d, %x}, /* ret */\n", desc
->elemdescFunc
.tdesc
.vt
, desc
->elemdescFunc
.paramdesc
.wParamFlags
);
1712 printf(" { /* params */\n");
1713 for (p
= 0; p
< desc
->cParams
; p
++)
1715 ELEMDESC e
= desc
->lprgelemdescParam
[p
];
1716 printf(" {%d, %x},\n", e
.tdesc
.vt
, e
.paramdesc
.wParamFlags
);
1718 printf(" {-1, -1}\n");
1720 printf(" { /* names */\n");
1721 OLE_CHECK(ITypeInfo_GetNames(info
, desc
->memid
, tab
, 256, &cNames
));
1722 for (p
= 0; p
< cNames
; p
++)
1724 printf(" %s,\n", dump_string(tab
[p
]));
1725 SysFreeString(tab
[p
]);
1730 ITypeInfo_ReleaseFuncDesc(info
, desc
);
1735 ITypeInfo_Release(info
);
1737 ITypeLib_Release(lib
);
1742 typedef struct _element_info
1748 typedef struct _function_info
1759 element_info ret_type
;
1760 element_info params
[15];
1764 typedef struct _interface_info
1770 USHORT cbSizeInstance
;
1773 function_info funcs
[20];
1776 static const interface_info info
[] = {
1777 /* interfaces count: 2 */
1780 /*kind*/ TKIND_DISPATCH
, /*flags*/ 0x1040, /*align*/ 4, /*size*/ 4,
1781 /*#vtbl*/ 7, /*#func*/ 8,
1784 0x60000000, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
1785 /*#param*/ 2, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0x1,
1800 0x60000001, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
1801 /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 1, /*#scodes*/ 0, /*flags*/ 0x1,
1812 0x60000002, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
1813 /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 2, /*#scodes*/ 0, /*flags*/ 0x1,
1824 0x60010000, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
1825 /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 3, /*#scodes*/ 0, /*flags*/ 0x1,
1838 0x60010001, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
1839 /*#param*/ 3, /*#opt*/ 0, /*vtbl*/ 4, /*#scodes*/ 0, /*flags*/ 0x1,
1856 0x60010002, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
1857 /*#param*/ 5, /*#opt*/ 0, /*vtbl*/ 5, /*#scodes*/ 0, /*flags*/ 0x1,
1878 0x60010003, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
1879 /*#param*/ 8, /*#opt*/ 0, /*vtbl*/ 6, /*#scodes*/ 0, /*flags*/ 0x1,
1906 0x60020000, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
1907 /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0x0,
1921 /*kind*/ TKIND_INTERFACE
, /*flags*/ 0x1000, /*align*/ 4, /*size*/ 4,
1922 /*#vtbl*/ 8, /*#func*/ 1,
1925 0x60020000, /*func*/ FUNC_PUREVIRTUAL
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
1926 /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0x0,
1940 #define check_type(elem, info) { \
1941 expect_int((elem)->tdesc.vt, (info)->vt); \
1942 expect_hex(U(*(elem)).paramdesc.wParamFlags, (info)->wParamFlags); \
1945 static void test_dump_typelib(const char *name
)
1947 WCHAR wszName
[MAX_PATH
];
1949 int ifcount
= sizeof(info
)/sizeof(info
[0]);
1952 MultiByteToWideChar(CP_ACP
, 0, name
, -1, wszName
, MAX_PATH
);
1953 ole_check(LoadTypeLibEx(wszName
, REGKIND_NONE
, &typelib
));
1954 expect_eq(ITypeLib_GetTypeInfoCount(typelib
), ifcount
, UINT
, "%d");
1955 for (iface
= 0; iface
< ifcount
; iface
++)
1957 const interface_info
*if_info
= &info
[iface
];
1958 ITypeInfo
*typeinfo
;
1962 trace("Interface %s\n", if_info
->name
);
1963 ole_check(ITypeLib_GetTypeInfo(typelib
, iface
, &typeinfo
));
1964 ole_check(ITypeLib_GetDocumentation(typelib
, iface
, &bstrIfName
, NULL
, NULL
, NULL
));
1965 expect_wstr_acpval(bstrIfName
, if_info
->name
);
1966 SysFreeString(bstrIfName
);
1968 ole_check(ITypeInfo_GetTypeAttr(typeinfo
, &typeattr
));
1969 expect_int(typeattr
->typekind
, if_info
->type
);
1970 expect_hex(typeattr
->wTypeFlags
, if_info
->wTypeFlags
);
1971 expect_int(typeattr
->cbAlignment
, if_info
->cbAlignment
);
1972 expect_int(typeattr
->cbSizeInstance
, if_info
->cbSizeInstance
);
1973 expect_int(typeattr
->cbSizeVft
, if_info
->cbSizeVft
* sizeof(void*));
1974 expect_int(typeattr
->cFuncs
, if_info
->cFuncs
);
1976 for (func
= 0; func
< typeattr
->cFuncs
; func
++)
1978 function_info
*fn_info
= (function_info
*)&if_info
->funcs
[func
];
1984 trace("Function %s\n", fn_info
->names
[0]);
1985 ole_check(ITypeInfo_GetFuncDesc(typeinfo
, func
, &desc
));
1986 expect_int(desc
->memid
, fn_info
->memid
);
1987 expect_int(desc
->funckind
, fn_info
->funckind
);
1988 expect_int(desc
->invkind
, fn_info
->invkind
);
1989 expect_int(desc
->callconv
, fn_info
->callconv
);
1990 expect_int(desc
->cParams
, fn_info
->cParams
);
1991 expect_int(desc
->cParamsOpt
, fn_info
->cParamsOpt
);
1992 ok( desc
->oVft
== fn_info
->vtbl_index
* sizeof(void*) ||
1993 broken(desc
->oVft
== fn_info
->vtbl_index
* 4), /* xp64 */
1994 "desc->oVft got %u\n", desc
->oVft
);
1995 expect_int(desc
->cScodes
, fn_info
->cScodes
);
1996 expect_int(desc
->wFuncFlags
, fn_info
->wFuncFlags
);
1997 ole_check(ITypeInfo_GetNames(typeinfo
, desc
->memid
, namesTab
, 256, &cNames
));
1998 for (i
= 0; i
< cNames
; i
++)
2000 expect_wstr_acpval(namesTab
[i
], fn_info
->names
[i
]);
2001 SysFreeString(namesTab
[i
]);
2003 expect_null(fn_info
->names
[cNames
]);
2005 check_type(&desc
->elemdescFunc
, &fn_info
->ret_type
);
2006 for (i
= 0 ; i
< desc
->cParams
; i
++)
2008 check_type(&desc
->lprgelemdescParam
[i
], &fn_info
->params
[i
]);
2010 expect_int(fn_info
->params
[desc
->cParams
].vt
, (VARTYPE
)-1);
2012 ITypeInfo_ReleaseFuncDesc(typeinfo
, desc
);
2015 ITypeInfo_ReleaseTypeAttr(typeinfo
, typeattr
);
2016 ITypeInfo_Release(typeinfo
);
2018 ITypeLib_Release(typelib
);
2023 static const char *create_test_typelib(int res_no
)
2025 static char filename
[MAX_PATH
];
2031 GetTempFileNameA( ".", "tlb", 0, filename
);
2032 file
= CreateFile( filename
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2033 ok( file
!= INVALID_HANDLE_VALUE
, "file creation failed\n" );
2034 if (file
== INVALID_HANDLE_VALUE
) return NULL
;
2035 res
= FindResource( GetModuleHandle(0), MAKEINTRESOURCE(res_no
), "TYPELIB" );
2036 ok( res
!= 0, "couldn't find resource\n" );
2037 ptr
= LockResource( LoadResource( GetModuleHandle(0), res
));
2038 WriteFile( file
, ptr
, SizeofResource( GetModuleHandle(0), res
), &written
, NULL
);
2039 ok( written
== SizeofResource( GetModuleHandle(0), res
), "couldn't write resource\n" );
2040 CloseHandle( file
);
2044 static void test_create_typelib_lcid(LCID lcid
)
2046 char filename
[MAX_PATH
];
2047 WCHAR name
[MAX_PATH
];
2049 ICreateTypeLib2
*tl
;
2051 DWORD msft_header
[5]; /* five is enough for now */
2054 GetTempFileNameA( ".", "tlb", 0, filename
);
2055 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, name
, MAX_PATH
);
2057 hr
= CreateTypeLib2(SYS_WIN32
, name
, &tl
);
2058 ok(hr
== S_OK
, "got %08x\n", hr
);
2060 hr
= ICreateTypeLib2_SetLcid(tl
, lcid
);
2061 ok(hr
== S_OK
, "got %08x\n", hr
);
2063 hr
= ICreateTypeLib2_SaveAllChanges(tl
);
2064 ICreateTypeLib2_Release(tl
);
2066 file
= CreateFileA( filename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0 );
2067 ok( file
!= INVALID_HANDLE_VALUE
, "file creation failed\n" );
2069 ReadFile( file
, msft_header
, sizeof(msft_header
), &read
, NULL
);
2070 ok(read
== sizeof(msft_header
), "read %d\n", read
);
2071 CloseHandle( file
);
2073 ok(msft_header
[0] == 0x5446534d, "got %08x\n", msft_header
[0]);
2074 ok(msft_header
[1] == 0x00010002, "got %08x\n", msft_header
[1]);
2075 ok(msft_header
[2] == 0xffffffff, "got %08x\n", msft_header
[2]);
2076 ok(msft_header
[3] == (lcid
? lcid
: 0x409), "got %08x (lcid %08x)\n", msft_header
[3], lcid
);
2077 ok(msft_header
[4] == lcid
, "got %08x (lcid %08x)\n", msft_header
[4], lcid
);
2079 DeleteFileA(filename
);
2082 static void test_create_typelibs(void)
2084 test_create_typelib_lcid(LOCALE_SYSTEM_DEFAULT
);
2085 test_create_typelib_lcid(LOCALE_USER_DEFAULT
);
2086 test_create_typelib_lcid(LOCALE_NEUTRAL
);
2088 test_create_typelib_lcid(0x009);
2089 test_create_typelib_lcid(0x409);
2090 test_create_typelib_lcid(0x809);
2092 test_create_typelib_lcid(0x007);
2093 test_create_typelib_lcid(0x407);
2097 static void test_register_typelib(void)
2100 WCHAR filename
[MAX_PATH
];
2101 const char *filenameA
;
2104 char key_name
[MAX_PATH
], uuid
[40];
2105 LONG ret
, expect_ret
;
2114 { TKIND_INTERFACE
, 0 },
2115 { TKIND_INTERFACE
, TYPEFLAG_FDISPATCHABLE
},
2116 { TKIND_INTERFACE
, TYPEFLAG_FOLEAUTOMATION
},
2117 { TKIND_INTERFACE
, TYPEFLAG_FDISPATCHABLE
| TYPEFLAG_FOLEAUTOMATION
},
2118 { TKIND_DISPATCH
, 0 /* TYPEFLAG_FDUAL - widl clears this flag for non-IDispatch derived interfaces */ },
2119 { TKIND_DISPATCH
, 0 /* TYPEFLAG_FDUAL - widl clears this flag for non-IDispatch derived interfaces */ },
2120 { TKIND_DISPATCH
, TYPEFLAG_FDISPATCHABLE
| TYPEFLAG_FDUAL
},
2121 { TKIND_DISPATCH
, TYPEFLAG_FDISPATCHABLE
| TYPEFLAG_FDUAL
},
2122 { TKIND_DISPATCH
, TYPEFLAG_FDISPATCHABLE
},
2123 { TKIND_DISPATCH
, TYPEFLAG_FDISPATCHABLE
},
2124 { TKIND_DISPATCH
, TYPEFLAG_FDISPATCHABLE
}
2127 filenameA
= create_test_typelib(3);
2128 MultiByteToWideChar(CP_ACP
, 0, filenameA
, -1, filename
, MAX_PATH
);
2130 hr
= LoadTypeLibEx(filename
, REGKIND_NONE
, &typelib
);
2131 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2133 hr
= RegisterTypeLib(typelib
, filename
, NULL
);
2134 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2136 count
= ITypeLib_GetTypeInfoCount(typelib
);
2137 ok(count
== 11, "got %d\n", count
);
2139 for(i
= 0; i
< count
; i
++)
2141 ITypeInfo
*typeinfo
;
2144 hr
= ITypeLib_GetTypeInfo(typelib
, i
, &typeinfo
);
2145 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2147 hr
= ITypeInfo_GetTypeAttr(typeinfo
, &attr
);
2148 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2150 ok(attr
->typekind
== attrs
[i
].kind
, "%d: got kind %d\n", i
, attr
->typekind
);
2151 ok(attr
->wTypeFlags
== attrs
[i
].flags
, "%d: got flags %04x\n", i
, attr
->wTypeFlags
);
2153 if(attr
->typekind
== TKIND_DISPATCH
&& (attr
->wTypeFlags
& TYPEFLAG_FDUAL
))
2156 ITypeInfo
*dual_info
;
2157 TYPEATTR
*dual_attr
;
2159 hr
= ITypeInfo_GetRefTypeOfImplType(typeinfo
, -1, &reftype
);
2160 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2162 hr
= ITypeInfo_GetRefTypeInfo(typeinfo
, reftype
, &dual_info
);
2163 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2165 hr
= ITypeInfo_GetTypeAttr(dual_info
, &dual_attr
);
2166 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2168 ok(dual_attr
->typekind
== TKIND_INTERFACE
, "%d: got kind %d\n", i
, dual_attr
->typekind
);
2169 ok(dual_attr
->wTypeFlags
== (TYPEFLAG_FDISPATCHABLE
| TYPEFLAG_FOLEAUTOMATION
| TYPEFLAG_FDUAL
), "%d: got flags %04x\n", i
, dual_attr
->wTypeFlags
);
2171 ITypeInfo_ReleaseTypeAttr(dual_info
, dual_attr
);
2172 ITypeInfo_Release(dual_info
);
2176 StringFromGUID2(&attr
->guid
, uuidW
, sizeof(uuidW
) / sizeof(uuidW
[0]));
2177 WideCharToMultiByte(CP_ACP
, 0, uuidW
, -1, uuid
, sizeof(uuid
), NULL
, NULL
);
2178 sprintf(key_name
, "Interface\\%s", uuid
);
2180 /* All dispinterfaces will be registered (this includes dual interfaces) as well
2181 as oleautomation interfaces */
2182 if((attr
->typekind
== TKIND_INTERFACE
&& (attr
->wTypeFlags
& TYPEFLAG_FOLEAUTOMATION
)) ||
2183 attr
->typekind
== TKIND_DISPATCH
)
2184 expect_ret
= ERROR_SUCCESS
;
2186 expect_ret
= ERROR_FILE_NOT_FOUND
;
2188 ret
= RegOpenKeyExA(HKEY_CLASSES_ROOT
, key_name
, 0, KEY_READ
, &hkey
);
2189 ok(ret
== expect_ret
, "%d: got %d\n", i
, ret
);
2190 if(ret
== ERROR_SUCCESS
) RegCloseKey(hkey
);
2192 ITypeInfo_ReleaseTypeAttr(typeinfo
, attr
);
2193 ITypeInfo_Release(typeinfo
);
2196 hr
= UnRegisterTypeLib(&LIBID_register_test
, 1, 0, LOCALE_NEUTRAL
, sizeof(void*) == 8 ? SYS_WIN64
: SYS_WIN32
);
2197 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2199 ITypeLib_Release(typelib
);
2200 DeleteFileA( filenameA
);
2205 const char *filename
;
2207 ref_count_test(wszStdOle2
);
2209 test_CreateDispTypeInfo();
2211 test_QueryPathOfRegTypeLib();
2213 test_CreateTypeLib();
2215 if ((filename
= create_test_typelib(2)))
2217 test_dump_typelib( filename
);
2218 DeleteFile( filename
);
2221 test_register_typelib();
2222 test_create_typelibs();