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>
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")
42 #define expect_wstr_acpval(expr, value) \
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); \
49 #define ole_expect(expr, expect) { \
51 ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \
54 #define ole_check(expr) ole_expect(expr, S_OK);
56 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
58 static HRESULT
WINAPI (*pRegisterTypeLibForUser
)(ITypeLib
*,OLECHAR
*,OLECHAR
*);
59 static HRESULT
WINAPI (*pUnRegisterTypeLibForUser
)(REFGUID
,WORD
,WORD
,LCID
,SYSKIND
);
61 static const WCHAR wszStdOle2
[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
63 static const int is_win64
= sizeof(void *) > sizeof(int);
65 static void init_function_pointers(void)
67 HMODULE hmod
= GetModuleHandleA("oleaut32.dll");
69 pRegisterTypeLibForUser
= (void *)GetProcAddress(hmod
, "RegisterTypeLibForUser");
70 pUnRegisterTypeLibForUser
= (void *)GetProcAddress(hmod
, "UnRegisterTypeLibForUser");
73 static void ref_count_test(LPCWSTR type_lib
)
76 ITypeInfo
*iti1
, *iti2
;
80 trace("Loading type library\n");
81 hRes
= LoadTypeLib(type_lib
, &iface
);
82 ok(hRes
== S_OK
, "Could not load type library\n");
86 hRes
= ITypeLib_GetTypeInfo(iface
, 1, &iti1
);
87 ok(hRes
== S_OK
, "ITypeLib_GetTypeInfo failed on index = 1\n");
88 ok(ref_count
=ITypeLib_Release(iface
) > 0, "ITypeLib destroyed while ITypeInfo has back pointer\n");
92 hRes
= ITypeLib_GetTypeInfo(iface
, 1, &iti2
);
93 ok(hRes
== S_OK
, "ITypeLib_GetTypeInfo failed on index = 1\n");
94 ok(iti1
== iti2
, "ITypeLib_GetTypeInfo returned different pointers for same indexes\n");
96 ITypeLib_AddRef(iface
);
97 ITypeInfo_Release(iti2
);
98 ITypeInfo_Release(iti1
);
99 ok(ITypeLib_Release(iface
) == 0, "ITypeLib should be destroyed here.\n");
102 static void test_TypeComp(void)
105 ITypeComp
*pTypeComp
;
110 ITypeInfo
*pTypeInfo
;
111 ITypeInfo
*pFontTypeInfo
;
112 static WCHAR wszStdFunctions
[] = {'S','t','d','F','u','n','c','t','i','o','n','s',0};
113 static WCHAR wszSavePicture
[] = {'S','a','v','e','P','i','c','t','u','r','e',0};
114 static WCHAR wszOLE_TRISTATE
[] = {'O','L','E','_','T','R','I','S','T','A','T','E',0};
115 static WCHAR wszUnchecked
[] = {'U','n','c','h','e','c','k','e','d',0};
116 static WCHAR wszIUnknown
[] = {'I','U','n','k','n','o','w','n',0};
117 static WCHAR wszFont
[] = {'F','o','n','t',0};
118 static WCHAR wszGUID
[] = {'G','U','I','D',0};
119 static WCHAR wszStdPicture
[] = {'S','t','d','P','i','c','t','u','r','e',0};
120 static WCHAR wszOLE_COLOR
[] = {'O','L','E','_','C','O','L','O','R',0};
121 static WCHAR wszClone
[] = {'C','l','o','n','e',0};
122 static WCHAR wszclone
[] = {'c','l','o','n','e',0};
123 static WCHAR wszJunk
[] = {'J','u','n','k',0};
124 static WCHAR wszAddRef
[] = {'A','d','d','R','e','f',0};
126 hr
= LoadTypeLib(wszStdOle2
, &pTypeLib
);
127 ok_ole_success(hr
, LoadTypeLib
);
129 hr
= ITypeLib_GetTypeComp(pTypeLib
, &pTypeComp
);
130 ok_ole_success(hr
, ITypeLib_GetTypeComp
);
132 /* test getting a TKIND_MODULE */
133 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszStdFunctions
);
134 hr
= ITypeComp_Bind(pTypeComp
, wszStdFunctions
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
135 ok_ole_success(hr
, ITypeComp_Bind
);
137 ok(desckind
== DESCKIND_TYPECOMP
,
138 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
140 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
142 ITypeComp_Release(bindptr
.lptcomp
);
144 /* test getting a TKIND_MODULE with INVOKE_PROPERTYGET */
145 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszStdFunctions
);
146 hr
= ITypeComp_Bind(pTypeComp
, wszStdFunctions
, ulHash
, INVOKE_PROPERTYGET
, &pTypeInfo
, &desckind
, &bindptr
);
147 ok_ole_success(hr
, ITypeComp_Bind
);
149 ok(desckind
== DESCKIND_TYPECOMP
,
150 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
152 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
153 ITypeComp_Release(bindptr
.lptcomp
);
155 /* test getting a function within a TKIND_MODULE */
156 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszSavePicture
);
157 hr
= ITypeComp_Bind(pTypeComp
, wszSavePicture
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
158 ok_ole_success(hr
, ITypeComp_Bind
);
160 ok(desckind
== DESCKIND_FUNCDESC
,
161 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
163 ok(bindptr
.lpfuncdesc
!= NULL
, "bindptr.lpfuncdesc should not have been set to NULL\n");
164 ITypeInfo_ReleaseFuncDesc(pTypeInfo
, bindptr
.lpfuncdesc
);
165 ITypeInfo_Release(pTypeInfo
);
167 /* test getting a function within a TKIND_MODULE with INVOKE_PROPERTYGET */
168 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszSavePicture
);
169 hr
= ITypeComp_Bind(pTypeComp
, wszSavePicture
, ulHash
, INVOKE_PROPERTYGET
, &pTypeInfo
, &desckind
, &bindptr
);
170 ok(hr
== TYPE_E_TYPEMISMATCH
,
171 "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n",
174 ok(desckind
== DESCKIND_NONE
,
175 "desckind should have been DESCKIND_NONE instead of %d\n",
177 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
178 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
180 /* test getting a TKIND_ENUM */
181 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszOLE_TRISTATE
);
182 hr
= ITypeComp_Bind(pTypeComp
, wszOLE_TRISTATE
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
183 ok_ole_success(hr
, ITypeComp_Bind
);
185 ok(desckind
== DESCKIND_TYPECOMP
,
186 "desckind should have been DESCKIND_TYPECOMP instead of %d\n",
188 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
190 ITypeComp_Release(bindptr
.lptcomp
);
192 /* test getting a value within a TKIND_ENUM */
193 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszUnchecked
);
194 hr
= ITypeComp_Bind(pTypeComp
, wszUnchecked
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
195 ok_ole_success(hr
, ITypeComp_Bind
);
197 ok(desckind
== DESCKIND_VARDESC
,
198 "desckind should have been DESCKIND_VARDESC instead of %d\n",
200 ITypeInfo_ReleaseVarDesc(pTypeInfo
, bindptr
.lpvardesc
);
201 ITypeInfo_Release(pTypeInfo
);
203 /* test getting a TKIND_INTERFACE */
204 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszIUnknown
);
205 hr
= ITypeComp_Bind(pTypeComp
, wszIUnknown
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
206 ok_ole_success(hr
, ITypeComp_Bind
);
208 ok(desckind
== DESCKIND_NONE
,
209 "desckind should have been DESCKIND_NONE instead of %d\n",
211 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
212 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
214 /* test getting a TKIND_DISPATCH */
215 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszFont
);
216 hr
= ITypeComp_Bind(pTypeComp
, wszFont
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
217 ok_ole_success(hr
, ITypeComp_Bind
);
219 ok(desckind
== DESCKIND_NONE
,
220 "desckind should have been DESCKIND_NONE instead of %d\n",
222 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
223 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
225 /* test getting a TKIND_RECORD/TKIND_ALIAS */
226 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszGUID
);
227 hr
= ITypeComp_Bind(pTypeComp
, wszGUID
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
228 ok_ole_success(hr
, ITypeComp_Bind
);
230 ok(desckind
== DESCKIND_NONE
,
231 "desckind should have been DESCKIND_NONE instead of %d\n",
233 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
234 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
236 /* test getting a TKIND_ALIAS */
237 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszOLE_COLOR
);
238 hr
= ITypeComp_Bind(pTypeComp
, wszOLE_COLOR
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
239 ok_ole_success(hr
, ITypeComp_Bind
);
241 ok(desckind
== DESCKIND_NONE
,
242 "desckind should have been DESCKIND_NONE instead of %d\n",
244 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
245 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
247 /* test getting a TKIND_COCLASS */
248 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszStdPicture
);
249 hr
= ITypeComp_Bind(pTypeComp
, wszStdPicture
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
250 ok_ole_success(hr
, ITypeComp_Bind
);
252 ok(desckind
== DESCKIND_NONE
,
253 "desckind should have been DESCKIND_NONE instead of %d\n",
255 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
256 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
258 ITypeComp_Release(pTypeComp
);
260 /* tests for ITypeComp on an interface */
261 hr
= ITypeLib_GetTypeInfoOfGuid(pTypeLib
, &IID_IFont
, &pFontTypeInfo
);
262 ok_ole_success(hr
, ITypeLib_GetTypeInfoOfGuid
);
264 hr
= ITypeInfo_GetTypeComp(pFontTypeInfo
, &pTypeComp
);
265 ok_ole_success(hr
, ITypeLib_GetTypeComp
);
267 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszClone
);
268 hr
= ITypeComp_Bind(pTypeComp
, wszClone
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
269 ok_ole_success(hr
, ITypeComp_Bind
);
271 ok(desckind
== DESCKIND_FUNCDESC
,
272 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
274 ok(bindptr
.lpfuncdesc
!= NULL
, "bindptr.lpfuncdesc should not have been set to NULL\n");
275 ITypeInfo_ReleaseFuncDesc(pTypeInfo
, bindptr
.lpfuncdesc
);
276 ITypeInfo_Release(pTypeInfo
);
278 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszClone
);
279 hr
= ITypeComp_Bind(pTypeComp
, wszClone
, ulHash
, INVOKE_PROPERTYGET
, &pTypeInfo
, &desckind
, &bindptr
);
280 ok(hr
== TYPE_E_TYPEMISMATCH
, "ITypeComp_Bind should have failed with TYPE_E_TYPEMISMATCH instead of 0x%08x\n", hr
);
282 ok(desckind
== DESCKIND_NONE
,
283 "desckind should have been DESCKIND_NONE instead of %d\n",
285 ok(!pTypeInfo
, "pTypeInfo should have been set to NULL\n");
286 ok(!bindptr
.lptcomp
, "bindptr should have been set to NULL\n");
288 /* tests that the compare is case-insensitive */
289 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszclone
);
290 hr
= ITypeComp_Bind(pTypeComp
, wszclone
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
291 ok_ole_success(hr
, ITypeComp_Bind
);
293 ok(desckind
== DESCKIND_FUNCDESC
,
294 "desckind should have been DESCKIND_FUNCDESC instead of %d\n",
296 ok(bindptr
.lpfuncdesc
!= NULL
, "bindptr.lpfuncdesc should not have been set to NULL\n");
297 ITypeInfo_ReleaseFuncDesc(pTypeInfo
, bindptr
.lpfuncdesc
);
298 ITypeInfo_Release(pTypeInfo
);
300 /* tests nonexistent members */
301 desckind
= 0xdeadbeef;
302 bindptr
.lptcomp
= (ITypeComp
*)0xdeadbeef;
303 pTypeInfo
= (ITypeInfo
*)0xdeadbeef;
304 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszJunk
);
305 hr
= ITypeComp_Bind(pTypeComp
, wszJunk
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
306 ok_ole_success(hr
, ITypeComp_Bind
);
307 ok(desckind
== DESCKIND_NONE
, "desckind should have been DESCKIND_NONE, was: %d\n", desckind
);
308 ok(pTypeInfo
== NULL
, "pTypeInfo should have been NULL, was: %p\n", pTypeInfo
);
309 ok(bindptr
.lptcomp
== NULL
, "bindptr should have been NULL, was: %p\n", bindptr
.lptcomp
);
311 /* tests inherited members */
312 desckind
= 0xdeadbeef;
313 bindptr
.lpfuncdesc
= NULL
;
315 ulHash
= LHashValOfNameSys(SYS_WIN32
, LOCALE_NEUTRAL
, wszAddRef
);
316 hr
= ITypeComp_Bind(pTypeComp
, wszAddRef
, ulHash
, 0, &pTypeInfo
, &desckind
, &bindptr
);
317 ok_ole_success(hr
, ITypeComp_Bind
);
318 ok(desckind
== DESCKIND_FUNCDESC
, "desckind should have been DESCKIND_FUNCDESC, was: %d\n", desckind
);
319 ok(pTypeInfo
!= NULL
, "pTypeInfo should not have been NULL, was: %p\n", pTypeInfo
);
320 ok(bindptr
.lpfuncdesc
!= NULL
, "bindptr should not have been NULL, was: %p\n", bindptr
.lpfuncdesc
);
321 ITypeInfo_ReleaseFuncDesc(pTypeInfo
, bindptr
.lpfuncdesc
);
322 ITypeInfo_Release(pTypeInfo
);
324 ITypeComp_Release(pTypeComp
);
325 ITypeInfo_Release(pFontTypeInfo
);
326 ITypeLib_Release(pTypeLib
);
329 static void test_CreateDispTypeInfo(void)
331 ITypeInfo
*pTypeInfo
, *pTI2
;
333 INTERFACEDATA ifdata
;
334 METHODDATA methdata
[4];
342 static WCHAR func1
[] = {'f','u','n','c','1',0};
343 static const WCHAR func2
[] = {'f','u','n','c','2',0};
344 static const WCHAR func3
[] = {'f','u','n','c','3',0};
345 static const WCHAR parm1
[] = {'p','a','r','m','1',0};
346 static const WCHAR parm2
[] = {'p','a','r','m','2',0};
347 OLECHAR
*name
= func1
;
349 ifdata
.pmethdata
= methdata
;
350 ifdata
.cMembers
= sizeof(methdata
) / sizeof(methdata
[0]);
352 methdata
[0].szName
= SysAllocString(func1
);
353 methdata
[0].ppdata
= parms1
;
354 methdata
[0].dispid
= 0x123;
355 methdata
[0].iMeth
= 0;
356 methdata
[0].cc
= CC_STDCALL
;
357 methdata
[0].cArgs
= 2;
358 methdata
[0].wFlags
= DISPATCH_METHOD
;
359 methdata
[0].vtReturn
= VT_HRESULT
;
360 parms1
[0].szName
= SysAllocString(parm1
);
361 parms1
[0].vt
= VT_I4
;
362 parms1
[1].szName
= SysAllocString(parm2
);
363 parms1
[1].vt
= VT_BSTR
;
365 methdata
[1].szName
= SysAllocString(func2
);
366 methdata
[1].ppdata
= NULL
;
367 methdata
[1].dispid
= 0x124;
368 methdata
[1].iMeth
= 1;
369 methdata
[1].cc
= CC_STDCALL
;
370 methdata
[1].cArgs
= 0;
371 methdata
[1].wFlags
= DISPATCH_PROPERTYGET
;
372 methdata
[1].vtReturn
= VT_I4
;
374 methdata
[2].szName
= SysAllocString(func3
);
375 methdata
[2].ppdata
= parms3
;
376 methdata
[2].dispid
= 0x125;
377 methdata
[2].iMeth
= 3;
378 methdata
[2].cc
= CC_STDCALL
;
379 methdata
[2].cArgs
= 1;
380 methdata
[2].wFlags
= DISPATCH_PROPERTYPUT
;
381 methdata
[2].vtReturn
= VT_HRESULT
;
382 parms3
[0].szName
= SysAllocString(parm1
);
383 parms3
[0].vt
= VT_I4
;
385 methdata
[3].szName
= SysAllocString(func3
);
386 methdata
[3].ppdata
= NULL
;
387 methdata
[3].dispid
= 0x125;
388 methdata
[3].iMeth
= 4;
389 methdata
[3].cc
= CC_STDCALL
;
390 methdata
[3].cArgs
= 0;
391 methdata
[3].wFlags
= DISPATCH_PROPERTYGET
;
392 methdata
[3].vtReturn
= VT_I4
;
394 hr
= CreateDispTypeInfo(&ifdata
, LOCALE_NEUTRAL
, &pTypeInfo
);
395 ok(hr
== S_OK
, "hr %08x\n", hr
);
397 hr
= ITypeInfo_GetTypeAttr(pTypeInfo
, &pTypeAttr
);
398 ok(hr
== S_OK
, "hr %08x\n", hr
);
400 ok(pTypeAttr
->typekind
== TKIND_COCLASS
, "typekind %0x\n", pTypeAttr
->typekind
);
401 ok(pTypeAttr
->cImplTypes
== 1, "cImplTypes %d\n", pTypeAttr
->cImplTypes
);
402 ok(pTypeAttr
->cFuncs
== 0, "cFuncs %d\n", pTypeAttr
->cFuncs
);
403 ok(pTypeAttr
->wTypeFlags
== 0, "wTypeFlags %04x\n", pTypeAttr
->cFuncs
);
404 ITypeInfo_ReleaseTypeAttr(pTypeInfo
, pTypeAttr
);
406 hr
= ITypeInfo_GetRefTypeOfImplType(pTypeInfo
, 0, &href
);
407 ok(hr
== S_OK
, "hr %08x\n", hr
);
408 ok(href
== 0, "href = 0x%x\n", href
);
409 hr
= ITypeInfo_GetRefTypeInfo(pTypeInfo
, href
, &pTI2
);
410 ok(hr
== S_OK
, "hr %08x\n", hr
);
411 hr
= ITypeInfo_GetTypeAttr(pTI2
, &pTypeAttr
);
412 ok(hr
== S_OK
, "hr %08x\n", hr
);
413 ok(pTypeAttr
->typekind
== TKIND_INTERFACE
, "typekind %0x\n", pTypeAttr
->typekind
);
414 ok(pTypeAttr
->cFuncs
== 4, "cFuncs %d\n", pTypeAttr
->cFuncs
);
415 ok(IsEqualGUID(&pTypeAttr
->guid
, &GUID_NULL
), "guid {%08x-...}\n", pTypeAttr
->guid
.Data1
);
416 ok(pTypeAttr
->wTypeFlags
== 0, "typeflags %08x\n", pTypeAttr
->wTypeFlags
);
418 ITypeInfo_ReleaseTypeAttr(pTI2
, pTypeAttr
);
420 hr
= ITypeInfo_GetFuncDesc(pTI2
, 0, &pFuncDesc
);
421 ok(hr
== S_OK
, "hr %08x\n", hr
);
422 ok(pFuncDesc
->memid
== 0x123, "memid %x\n", pFuncDesc
->memid
);
423 ok(pFuncDesc
->funckind
== FUNC_VIRTUAL
, "funckind %d\n", pFuncDesc
->funckind
);
424 ok(pFuncDesc
->invkind
== methdata
[0].wFlags
, "invkind %d\n", pFuncDesc
->invkind
);
425 ok(pFuncDesc
->callconv
== methdata
[0].cc
, "callconv %d\n", pFuncDesc
->callconv
);
426 ok(pFuncDesc
->cParams
== methdata
[0].cArgs
, "cParams %d\n", pFuncDesc
->cParams
);
427 ok(pFuncDesc
->oVft
== 0, "oVft %d\n", pFuncDesc
->oVft
);
428 ok(pFuncDesc
->wFuncFlags
== 0, "oVft %d\n", pFuncDesc
->wFuncFlags
);
429 ok(pFuncDesc
->elemdescFunc
.tdesc
.vt
== VT_HRESULT
, "ret vt %x\n", pFuncDesc
->elemdescFunc
.tdesc
.vt
);
430 ok(pFuncDesc
->lprgelemdescParam
[0].tdesc
.vt
== VT_I4
, "parm 0 vt %x\n", pFuncDesc
->lprgelemdescParam
[0].tdesc
.vt
);
431 ok(U(pFuncDesc
->lprgelemdescParam
[0]).paramdesc
.wParamFlags
== PARAMFLAG_NONE
, "parm 0 flags %x\n", U(pFuncDesc
->lprgelemdescParam
[0]).paramdesc
.wParamFlags
);
433 ok(pFuncDesc
->lprgelemdescParam
[1].tdesc
.vt
== VT_BSTR
, "parm 1 vt %x\n", pFuncDesc
->lprgelemdescParam
[1].tdesc
.vt
);
434 ok(U(pFuncDesc
->lprgelemdescParam
[1]).paramdesc
.wParamFlags
== PARAMFLAG_NONE
, "parm 1 flags %x\n", U(pFuncDesc
->lprgelemdescParam
[1]).paramdesc
.wParamFlags
);
435 ITypeInfo_ReleaseFuncDesc(pTI2
, pFuncDesc
);
437 hr
= ITypeInfo_GetFuncDesc(pTI2
, 1, &pFuncDesc
);
438 ok(hr
== S_OK
, "hr %08x\n", hr
);
439 ok(pFuncDesc
->funckind
== FUNC_VIRTUAL
, "funckind %d\n", pFuncDesc
->funckind
);
440 ok(pFuncDesc
->invkind
== methdata
[1].wFlags
, "invkind %d\n", pFuncDesc
->invkind
);
441 ok(pFuncDesc
->callconv
== methdata
[1].cc
, "callconv %d\n", pFuncDesc
->callconv
);
442 ok(pFuncDesc
->cParams
== methdata
[1].cArgs
, "cParams %d\n", pFuncDesc
->cParams
);
443 ok(pFuncDesc
->oVft
== sizeof(void *), "oVft %d\n", pFuncDesc
->oVft
);
444 ok(pFuncDesc
->wFuncFlags
== 0, "oVft %d\n", pFuncDesc
->wFuncFlags
);
445 ok(pFuncDesc
->elemdescFunc
.tdesc
.vt
== VT_I4
, "ret vt %x\n", pFuncDesc
->elemdescFunc
.tdesc
.vt
);
446 ITypeInfo_ReleaseFuncDesc(pTI2
, pFuncDesc
);
448 hr
= ITypeInfo_GetFuncDesc(pTI2
, 2, &pFuncDesc
);
449 ok(hr
== S_OK
, "hr %08x\n", hr
);
450 ok(pFuncDesc
->funckind
== FUNC_VIRTUAL
, "funckind %d\n", pFuncDesc
->funckind
);
451 ok(pFuncDesc
->invkind
== methdata
[2].wFlags
, "invkind %d\n", pFuncDesc
->invkind
);
452 ok(pFuncDesc
->callconv
== methdata
[2].cc
, "callconv %d\n", pFuncDesc
->callconv
);
453 ok(pFuncDesc
->cParams
== methdata
[2].cArgs
, "cParams %d\n", pFuncDesc
->cParams
);
454 ok(pFuncDesc
->oVft
== 3 * sizeof(void *), "oVft %d\n", pFuncDesc
->oVft
);
455 ok(pFuncDesc
->wFuncFlags
== 0, "oVft %d\n", pFuncDesc
->wFuncFlags
);
456 ok(pFuncDesc
->elemdescFunc
.tdesc
.vt
== VT_HRESULT
, "ret vt %x\n", pFuncDesc
->elemdescFunc
.tdesc
.vt
);
457 ok(pFuncDesc
->lprgelemdescParam
[0].tdesc
.vt
== VT_I4
, "parm 0 vt %x\n", pFuncDesc
->lprgelemdescParam
[0].tdesc
.vt
);
458 ok(U(pFuncDesc
->lprgelemdescParam
[0]).paramdesc
.wParamFlags
== PARAMFLAG_NONE
, "parm 0 flags %x\n", U(pFuncDesc
->lprgelemdescParam
[0]).paramdesc
.wParamFlags
);
459 ITypeInfo_ReleaseFuncDesc(pTI2
, pFuncDesc
);
461 hr
= ITypeInfo_GetFuncDesc(pTI2
, 3, &pFuncDesc
);
462 ok(hr
== S_OK
, "hr %08x\n", hr
);
463 ok(pFuncDesc
->funckind
== FUNC_VIRTUAL
, "funckind %d\n", pFuncDesc
->funckind
);
464 ok(pFuncDesc
->invkind
== methdata
[3].wFlags
, "invkind %d\n", pFuncDesc
->invkind
);
465 ok(pFuncDesc
->callconv
== methdata
[3].cc
, "callconv %d\n", pFuncDesc
->callconv
);
466 ok(pFuncDesc
->cParams
== methdata
[3].cArgs
, "cParams %d\n", pFuncDesc
->cParams
);
467 ok(pFuncDesc
->oVft
== 4 * sizeof(void *), "oVft %d\n", pFuncDesc
->oVft
);
468 ok(pFuncDesc
->wFuncFlags
== 0, "oVft %d\n", pFuncDesc
->wFuncFlags
);
469 ok(pFuncDesc
->elemdescFunc
.tdesc
.vt
== VT_I4
, "ret vt %x\n", pFuncDesc
->elemdescFunc
.tdesc
.vt
);
470 ITypeInfo_ReleaseFuncDesc(pTI2
, pFuncDesc
);
472 /* test GetIDsOfNames on a coclass to see if it searches its interfaces */
473 hr
= ITypeInfo_GetIDsOfNames(pTypeInfo
, &name
, 1, &memid
);
474 ok(hr
== S_OK
, "hr 0x%08x\n", hr
);
475 ok(memid
== 0x123, "memid 0x%08x\n", memid
);
477 ITypeInfo_Release(pTI2
);
478 ITypeInfo_Release(pTypeInfo
);
480 SysFreeString(parms1
[0].szName
);
481 SysFreeString(parms1
[1].szName
);
482 SysFreeString(parms3
[0].szName
);
483 SysFreeString(methdata
[0].szName
);
484 SysFreeString(methdata
[1].szName
);
485 SysFreeString(methdata
[2].szName
);
486 SysFreeString(methdata
[3].szName
);
489 static void test_TypeInfo(void)
492 ITypeInfo
*pTypeInfo
;
493 ITypeInfo2
*pTypeInfo2
;
495 static WCHAR wszBogus
[] = { 'b','o','g','u','s',0 };
496 static WCHAR wszGetTypeInfo
[] = { 'G','e','t','T','y','p','e','I','n','f','o',0 };
497 static WCHAR wszClone
[] = {'C','l','o','n','e',0};
498 OLECHAR
* bogus
= wszBogus
;
499 OLECHAR
* pwszGetTypeInfo
= wszGetTypeInfo
;
500 OLECHAR
* pwszClone
= wszClone
;
502 DISPPARAMS dispparams
;
503 GUID bogusguid
= {0x806afb4f,0x13f7,0x42d2,{0x89,0x2c,0x6c,0x97,0xc3,0x6a,0x36,0xc1}};
506 hr
= LoadTypeLib(wszStdOle2
, &pTypeLib
);
507 ok_ole_success(hr
, LoadTypeLib
);
509 hr
= ITypeLib_GetTypeInfoOfGuid(pTypeLib
, &IID_IFont
, &pTypeInfo
);
510 ok_ole_success(hr
, ITypeLib_GetTypeInfoOfGuid
);
512 /* test nonexistent method name */
513 hr
= ITypeInfo_GetIDsOfNames(pTypeInfo
, &bogus
, 1, &dispidMember
);
514 ok(hr
== DISP_E_UNKNOWNNAME
,
515 "ITypeInfo_GetIDsOfNames should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n",
518 dispparams
.cArgs
= 0;
519 dispparams
.rgdispidNamedArgs
= NULL
;
520 dispparams
.rgvarg
= NULL
;
522 /* test dispparams not NULL */
524 /* invalid member id -- wrong flags -- cNamedArgs not bigger than cArgs */
525 dispparams
.cNamedArgs
= 0;
526 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_PROPERTYGET
, &dispparams
, NULL
, NULL
, NULL
);
527 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
528 /* invalid member id -- correct flags -- cNamedArgs not bigger than cArgs */
529 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
530 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
532 /* invalid member id -- wrong flags -- cNamedArgs bigger than cArgs */
533 dispparams
.cNamedArgs
= 1;
534 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_PROPERTYGET
, &dispparams
, NULL
, NULL
, NULL
);
535 ok(hr
== E_INVALIDARG
, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
536 /* invalid member id -- correct flags -- cNamedArgs bigger than cArgs */
537 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, 0xdeadbeef, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
538 ok(hr
== E_INVALIDARG
, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
541 hr
= ITypeInfo_GetIDsOfNames(pTypeInfo
, &pwszClone
, 1, &dispidMember
);
542 ok_ole_success(hr
, ITypeInfo_GetIDsOfNames
);
544 /* correct member id -- wrong flags -- cNamedArgs not bigger than cArgs */
545 dispparams
.cNamedArgs
= 0;
546 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_PROPERTYGET
, &dispparams
, NULL
, NULL
, NULL
);
547 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
548 /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs
549 hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
550 ok(hr == 0x8002000e, "ITypeInfo_Invoke should have returned 0x8002000e instead of 0x%08x\n", hr); */
552 /* correct member id -- wrong flags -- cNamedArgs bigger than cArgs */
553 dispparams
.cNamedArgs
= 1;
554 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_PROPERTYGET
, &dispparams
, NULL
, NULL
, NULL
);
555 ok(hr
== E_INVALIDARG
, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
556 /* correct member id -- correct flags -- cNamedArgs bigger than cArgs */
557 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
558 ok(hr
== E_INVALIDARG
, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
560 /* test NULL dispparams */
562 /* correct member id -- wrong flags -- cNamedArgs not bigger than cArgs */
563 dispparams
.cNamedArgs
= 0;
564 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_PROPERTYGET
, NULL
, NULL
, NULL
, NULL
);
565 ok(hr
== E_INVALIDARG
, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
566 /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs */
567 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_METHOD
, NULL
, NULL
, NULL
, NULL
);
568 ok(hr
== E_INVALIDARG
, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
570 /* correct member id -- wrong flags -- cNamedArgs bigger than cArgs */
571 dispparams
.cNamedArgs
= 1;
572 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_PROPERTYGET
, NULL
, NULL
, NULL
, NULL
);
573 ok(hr
== E_INVALIDARG
, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
574 /* correct member id -- correct flags -- cNamedArgs bigger than cArgs */
575 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_METHOD
, NULL
, NULL
, NULL
, NULL
);
576 ok(hr
== E_INVALIDARG
, "ITypeInfo_Invoke should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
578 ITypeInfo_Release(pTypeInfo
);
582 hr
= ITypeLib_GetTypeInfoOfGuid(pTypeLib
, &IID_IDispatch
, &pTypeInfo
);
583 ok_ole_success(hr
, ITypeLib_GetTypeInfoOfGuid
);
585 hr
= ITypeInfo_GetIDsOfNames(pTypeInfo
, &pwszGetTypeInfo
, 1, &dispidMember
);
586 ok_ole_success(hr
, ITypeInfo_GetIDsOfNames
);
588 hr
= ITypeInfo_QueryInterface(pTypeInfo
, &IID_ITypeInfo2
, (void**)&pTypeInfo2
);
589 ok_ole_success(hr
, ITypeInfo_QueryInterface
);
597 /* test unknown guid passed to GetCustData */
598 hr
= ITypeInfo2_GetCustData(pTypeInfo2
, &bogusguid
, &var
);
599 ok_ole_success(hr
, ITypeInfo_GetCustData
);
600 ok(V_VT(&var
) == VT_EMPTY
, "got %i, expected VT_EMPTY\n", V_VT(&var
));
602 ITypeInfo2_Release(pTypeInfo2
);
607 /* test invoking a method with a [restricted] keyword */
609 /* correct member id -- wrong flags -- cNamedArgs not bigger than cArgs */
610 dispparams
.cNamedArgs
= 0;
611 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_PROPERTYGET
, &dispparams
, NULL
, NULL
, NULL
);
612 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
613 /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs */
614 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
615 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
617 /* correct member id -- wrong flags -- cNamedArgs bigger than cArgs */
618 dispparams
.cNamedArgs
= 1;
619 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_PROPERTYGET
, &dispparams
, NULL
, NULL
, NULL
);
620 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
621 /* correct member id -- correct flags -- cNamedArgs bigger than cArgs */
622 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
623 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
625 /* test NULL dispparams */
627 /* correct member id -- wrong flags -- cNamedArgs not bigger than cArgs */
628 dispparams
.cNamedArgs
= 0;
629 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_PROPERTYGET
, NULL
, NULL
, NULL
, NULL
);
630 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
631 /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs */
632 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_METHOD
, NULL
, NULL
, NULL
, NULL
);
633 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
635 /* correct member id -- wrong flags -- cNamedArgs bigger than cArgs */
636 dispparams
.cNamedArgs
= 1;
637 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_PROPERTYGET
, NULL
, NULL
, NULL
, NULL
);
638 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
639 /* correct member id -- correct flags -- cNamedArgs bigger than cArgs */
640 hr
= ITypeInfo_Invoke(pTypeInfo
, (void *)0xdeadbeef, dispidMember
, DISPATCH_METHOD
, NULL
, NULL
, NULL
, NULL
);
641 ok(hr
== DISP_E_MEMBERNOTFOUND
, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
643 ITypeInfo_Release(pTypeInfo
);
644 ITypeLib_Release(pTypeLib
);
647 static int WINAPI
int_func( int a0
, int a1
, int a2
, int a3
, int a4
)
649 ok( a0
== 1, "wrong arg0 %x\n", a0
);
650 ok( a1
== -1, "wrong arg1 %x\n", a1
);
651 ok( a2
== (0x55550000 | 1234), "wrong arg2 %x\n", a2
);
652 ok( a3
== 0xdeadbeef, "wrong arg3 %x\n", a3
);
653 ok( a4
== 0x555555fd, "wrong arg4 %x\n", a4
);
657 static double WINAPI
double_func( double a0
, float a1
, double a2
, int a3
)
659 ok( a0
== 1.2, "wrong arg0 %f\n", (double)a0
);
660 ok( a1
== 3.25, "wrong arg1 %f\n", (double)a1
);
661 ok( a2
== 1.2e12
, "wrong arg2 %f\n", (double)a2
);
662 ok( a3
== -4433.0, "wrong arg3 %f\n", (double)a3
);
666 static LONGLONG WINAPI
longlong_func( LONGLONG a0
, CY a1
)
668 ok( a0
== (((ULONGLONG
)0xdead << 32) | 0xbeef), "wrong arg0 %08x%08x\n", (DWORD
)(a0
>> 32), (DWORD
)a0
);
669 ok( a1
.int64
== ((ULONGLONG
)10000 * 12345678), "wrong arg1 %08x%08x\n",
670 (DWORD
)(a1
.int64
>> 32), (DWORD
)a1
.int64
);
671 return ((ULONGLONG
)4321 << 32) | 8765;
674 static VARIANT WINAPI
variant_func( int a0
, BOOL a1
, DECIMAL a2
, VARIANT a3
)
677 ok( a0
== 2233, "wrong arg0 %x\n", a0
);
678 ok( a1
== 1 || broken(a1
== 0x55550001), "wrong arg1 %x\n", a1
);
679 V_VT(&var
) = VT_LPWSTR
;
680 V_UI4(&var
) = 0xbabe;
681 ok( a2
.Hi32
== 1122, "wrong arg2.Hi32 %x\n", a2
.Hi32
);
682 ok( U1(a2
).Lo64
== 3344, "wrong arg2.Lo64 %08x%08x\n", (DWORD
)(U1(a2
).Lo64
>> 32), (DWORD
)U1(a2
).Lo64
);
683 ok( V_VT(&a3
) == VT_EMPTY
, "wrong arg3 type %x\n", V_VT(&a3
) );
684 ok( V_UI4(&a3
) == 0xdeadbeef, "wrong arg3 value %x\n", V_UI4(&a3
) );
688 static int CDECL
void_func( int a0
, int a1
)
690 if (is_win64
) /* VT_EMPTY is passed as real arg on win64 */
692 ok( a0
== 0x55555555, "wrong arg0 %x\n", a0
);
693 ok( a1
== 1111, "wrong arg1 %x\n", a1
);
697 ok( a0
== 1111, "wrong arg0 %x\n", a0
);
698 ok( a1
== 0, "wrong arg1 %x\n", a1
);
703 static int WINAPI
stdcall_func( int a
)
708 static int WINAPI
inst_func( void *inst
, int a
)
710 ok( (*(void ***)inst
)[3] == inst_func
, "wrong ptr %p\n", inst
);
711 ok( a
== 3, "wrong arg %x\n", a
);
715 static const void *vtable
[] = { NULL
, NULL
, NULL
, inst_func
};
717 static void test_DispCallFunc(void)
719 const void **inst
= vtable
;
721 VARIANT result
, args
[5];
722 VARIANTARG
*pargs
[5];
726 for (i
= 0; i
< 5; i
++) pargs
[i
] = &args
[i
];
728 memset( args
, 0x55, sizeof(args
) );
734 V_I2(&args
[2]) = 1234;
736 V_UI4(&args
[3]) = 0xdeadbeef;
739 memset( &result
, 0xcc, sizeof(result
) );
740 res
= DispCallFunc( NULL
, (ULONG_PTR
)int_func
, CC_STDCALL
, VT_UI4
, 5, types
, pargs
, &result
);
741 ok( res
== S_OK
, "DispCallFunc failed %x\n", res
);
742 ok( V_VT(&result
) == VT_UI4
, "wrong result type %d\n", V_VT(&result
) );
743 ok( V_UI4(&result
) == 4321, "wrong result %u\n", V_UI4(&result
) );
745 /* the function checks the argument sizes for stdcall */
746 if (!is_win64
) /* no stdcall on 64-bit */
748 res
= DispCallFunc( NULL
, (ULONG_PTR
)stdcall_func
, CC_STDCALL
, VT_UI4
, 0, types
, pargs
, &result
);
749 ok( res
== DISP_E_BADCALLEE
, "DispCallFunc wrong error %x\n", res
);
750 res
= DispCallFunc( NULL
, (ULONG_PTR
)stdcall_func
, CC_STDCALL
, VT_UI4
, 1, types
, pargs
, &result
);
751 ok( res
== S_OK
, "DispCallFunc failed %x\n", res
);
752 res
= DispCallFunc( NULL
, (ULONG_PTR
)stdcall_func
, CC_STDCALL
, VT_UI4
, 2, types
, pargs
, &result
);
753 ok( res
== DISP_E_BADCALLEE
, "DispCallFunc wrong error %x\n", res
);
756 memset( args
, 0x55, sizeof(args
) );
758 V_R8(&args
[0]) = 1.2;
760 V_R4(&args
[1]) = 3.25;
762 V_R8(&args
[2]) = 1.2e12
;
764 V_I4(&args
[3]) = -4433;
765 memset( &result
, 0xcc, sizeof(result
) );
766 res
= DispCallFunc( NULL
, (ULONG_PTR
)double_func
, CC_STDCALL
, VT_R8
, 4, types
, pargs
, &result
);
767 ok( res
== S_OK
, "DispCallFunc failed %x\n", res
);
768 ok( V_VT(&result
) == VT_R8
, "wrong result type %d\n", V_VT(&result
) );
769 ok( V_R8(&result
) == 4321, "wrong result %f\n", V_R8(&result
) );
771 memset( args
, 0x55, sizeof(args
) );
773 V_I8(&args
[0]) = ((ULONGLONG
)0xdead << 32) | 0xbeef;
775 V_CY(&args
[1]).int64
= (ULONGLONG
)10000 * 12345678;
776 memset( &result
, 0xcc, sizeof(result
) );
777 res
= DispCallFunc( NULL
, (ULONG_PTR
)longlong_func
, CC_STDCALL
, VT_I8
, 2, types
, pargs
, &result
);
778 ok( res
== S_OK
|| broken(res
== E_INVALIDARG
), /* longlong not supported on <= win2k */
779 "DispCallFunc failed %x\n", res
);
782 ok( V_VT(&result
) == VT_I8
, "wrong result type %d\n", V_VT(&result
) );
783 ok( V_I8(&result
) == (((ULONGLONG
)4321 << 32) | 8765), "wrong result %08x%08x\n",
784 (DWORD
)(V_I8(&result
) >> 32), (DWORD
)V_I8(&result
) );
787 memset( args
, 0x55, sizeof(args
) );
789 V_I4(&args
[0]) = 2233;
791 V_BOOL(&args
[1]) = 1;
792 types
[2] = VT_DECIMAL
;
793 V_DECIMAL(&args
[2]).Hi32
= 1122;
794 U1(V_DECIMAL(&args
[2])).Lo64
= 3344;
795 types
[3] = VT_VARIANT
;
796 V_VT(&args
[3]) = VT_EMPTY
;
797 V_UI4(&args
[3]) = 0xdeadbeef;
799 memset( &result
, 0xcc, sizeof(result
) );
800 res
= DispCallFunc( NULL
, (ULONG_PTR
)variant_func
, CC_STDCALL
, VT_VARIANT
, 5, types
, pargs
, &result
);
801 ok( res
== S_OK
, "DispCallFunc failed %x\n", res
);
802 ok( V_VT(&result
) == VT_LPWSTR
, "wrong result type %d\n", V_VT(&result
) );
803 ok( V_UI4(&result
) == 0xbabe, "wrong result %08x\n", V_UI4(&result
) );
805 memset( args
, 0x55, sizeof(args
) );
808 V_I4(&args
[1]) = 1111;
813 memset( &result
, 0xcc, sizeof(result
) );
814 res
= DispCallFunc( NULL
, (ULONG_PTR
)void_func
, CC_CDECL
, VT_EMPTY
, 5, types
, pargs
, &result
);
815 ok( res
== S_OK
, "DispCallFunc failed %x\n", res
);
816 ok( V_VT(&result
) == VT_EMPTY
, "wrong result type %d\n", V_VT(&result
) );
818 ok( V_UI4(&result
) == 12, "wrong result %08x\n", V_UI4(&result
) );
820 ok( V_UI4(&result
) == 0xcccccccc, "wrong result %08x\n", V_UI4(&result
) );
822 memset( args
, 0x55, sizeof(args
) );
825 memset( &result
, 0xcc, sizeof(result
) );
826 res
= DispCallFunc( &inst
, 3 * sizeof(void*), CC_STDCALL
, VT_I4
, 1, types
, pargs
, &result
);
827 ok( res
== S_OK
, "DispCallFunc failed %x\n", res
);
828 ok( V_VT(&result
) == VT_I4
, "wrong result type %d\n", V_VT(&result
) );
829 ok( V_I4(&result
) == 6, "wrong result %08x\n", V_I4(&result
) );
832 /* RegDeleteTreeW from dlls/advapi32/registry.c */
833 static LSTATUS
myRegDeleteTreeW(HKEY hKey
, LPCWSTR lpszSubKey
)
836 DWORD dwMaxSubkeyLen
, dwMaxValueLen
;
837 DWORD dwMaxLen
, dwSize
;
838 WCHAR szNameBuf
[MAX_PATH
], *lpszName
= szNameBuf
;
843 ret
= RegOpenKeyExW(hKey
, lpszSubKey
, 0, KEY_READ
, &hSubKey
);
847 ret
= RegQueryInfoKeyW(hSubKey
, NULL
, NULL
, NULL
, NULL
,
848 &dwMaxSubkeyLen
, NULL
, NULL
, &dwMaxValueLen
, NULL
, NULL
, NULL
);
849 if (ret
) goto cleanup
;
853 dwMaxLen
= max(dwMaxSubkeyLen
, dwMaxValueLen
);
854 if (dwMaxLen
> sizeof(szNameBuf
)/sizeof(WCHAR
))
856 /* Name too big: alloc a buffer for it */
857 if (!(lpszName
= HeapAlloc( GetProcessHeap(), 0, dwMaxLen
*sizeof(WCHAR
))))
859 ret
= ERROR_NOT_ENOUGH_MEMORY
;
864 /* Recursively delete all the subkeys */
868 if (RegEnumKeyExW(hSubKey
, 0, lpszName
, &dwSize
, NULL
,
869 NULL
, NULL
, NULL
)) break;
871 ret
= myRegDeleteTreeW(hSubKey
, lpszName
);
872 if (ret
) goto cleanup
;
876 ret
= RegDeleteKeyW(hKey
, lpszSubKey
);
881 if (RegEnumValueW(hKey
, 0, lpszName
, &dwSize
,
882 NULL
, NULL
, NULL
, NULL
)) break;
884 ret
= RegDeleteValueW(hKey
, lpszName
);
885 if (ret
) goto cleanup
;
889 if (lpszName
!= szNameBuf
)
890 HeapFree(GetProcessHeap(), 0, lpszName
);
892 RegCloseKey(hSubKey
);
896 static BOOL
do_typelib_reg_key(GUID
*uid
, WORD maj
, WORD min
, DWORD arch
, LPCWSTR base
, BOOL remove
)
898 static const WCHAR typelibW
[] = {'T','y','p','e','l','i','b','\\',0};
899 static const WCHAR formatW
[] = {'\\','%','u','.','%','u','\\','0','\\','w','i','n','%','u',0};
900 static const WCHAR format2W
[] = {'%','s','_','%','u','_','%','u','.','d','l','l',0};
906 memcpy(buf
, typelibW
, sizeof(typelibW
));
907 StringFromGUID2(uid
, buf
+ lstrlenW(buf
), 40);
911 ok(myRegDeleteTreeW(HKEY_CLASSES_ROOT
, buf
) == ERROR_SUCCESS
, "SHDeleteKey failed\n");
915 wsprintfW(buf
+ lstrlenW(buf
), formatW
, maj
, min
, arch
);
917 SetLastError(0xdeadbeef);
918 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, buf
, 0, NULL
, 0,
919 KEY_WRITE
, NULL
, &hkey
, NULL
);
920 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
922 win_skip("W-calls are not implemented\n");
926 if (res
!= ERROR_SUCCESS
)
928 trace("RegCreateKeyExW failed: %u\n", res
);
932 wsprintfW(buf
, format2W
, base
, maj
, min
);
933 if (RegSetValueExW(hkey
, NULL
, 0, REG_SZ
,
934 (BYTE
*)buf
, (lstrlenW(buf
) + 1) * sizeof(WCHAR
)) != ERROR_SUCCESS
)
936 trace("RegSetValueExW failed\n");
943 static void test_QueryPathOfRegTypeLib(DWORD arch
)
945 static const struct test_data
949 const WCHAR path
[16];
951 { 1, 0, TYPE_E_LIBNOTREGISTERED
, { 0 } },
952 { 3, 0, S_OK
, {'f','a','k','e','_','3','_','0','.','d','l','l',0 } },
953 { 3, 1, S_OK
, {'f','a','k','e','_','3','_','1','.','d','l','l',0 } },
954 { 3, 22, S_OK
, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
955 { 3, 37, S_OK
, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
956 { 3, 40, S_OK
, {'f','a','k','e','_','3','_','3','7','.','d','l','l',0 } },
957 { 0xffff, 0xffff, S_OK
, {'f','a','k','e','_','5','_','3','7','.','d','l','l',0 } },
958 { 0xffff, 0, TYPE_E_LIBNOTREGISTERED
, { 0 } },
959 { 3, 0xffff, TYPE_E_LIBNOTREGISTERED
, { 0 } },
960 { 5, 0xffff, TYPE_E_LIBNOTREGISTERED
, { 0 } },
961 { 4, 0, TYPE_E_LIBNOTREGISTERED
, { 0 } }
963 static const WCHAR base
[] = {'f','a','k','e',0};
964 static const WCHAR wrongW
[] = {'w','r','o','n','g',0};
972 status
= UuidCreate(&uid
);
973 ok(!status
|| status
== RPC_S_UUID_LOCAL_ONLY
, "UuidCreate error %08x\n", status
);
975 StringFromGUID2(&uid
, uid_str
, 40);
976 /*trace("GUID: %s\n", wine_dbgstr_w(uid_str));*/
978 if (!do_typelib_reg_key(&uid
, 3, 0, arch
, base
, 0)) return;
979 if (!do_typelib_reg_key(&uid
, 3, 1, arch
, base
, 0)) return;
980 if (!do_typelib_reg_key(&uid
, 3, 37, arch
, base
, 0)) return;
981 if (!do_typelib_reg_key(&uid
, 5, 37, arch
, base
, 0)) return;
982 if (arch
== 64 && !do_typelib_reg_key(&uid
, 5, 37, 32, wrongW
, 0)) return;
984 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
986 ret
= QueryPathOfRegTypeLib(&uid
, td
[i
].maj
, td
[i
].min
, 0, &path
);
987 ok(ret
== td
[i
].ret
, "QueryPathOfRegTypeLib(%u.%u) returned %08x\n", td
[i
].maj
, td
[i
].min
, ret
);
990 ok(!lstrcmpW(td
[i
].path
, path
), "typelib %u.%u path doesn't match\n", td
[i
].maj
, td
[i
].min
);
995 do_typelib_reg_key(&uid
, 0, 0, arch
, NULL
, 1);
998 static void test_inheritance(void)
1002 ITypeInfo
*pTI
, *pTI_p
;
1006 WCHAR path
[MAX_PATH
];
1007 CHAR pathA
[MAX_PATH
];
1008 static const WCHAR tl_path
[] = {'.','\\','m','i','d','l','_','t','m','a','r','s','h','a','l','.','t','l','b',0};
1010 BOOL use_midl_tlb
= 0;
1012 GetModuleFileNameA(NULL
, pathA
, MAX_PATH
);
1013 MultiByteToWideChar(CP_ACP
, 0, pathA
, -1, path
, MAX_PATH
);
1016 memcpy(path
, tl_path
, sizeof(tl_path
));
1018 hr
= LoadTypeLib(path
, &pTL
);
1019 if(FAILED(hr
)) return;
1022 /* ItestIF3 is a syntax 2 dispinterface */
1023 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &DIID_ItestIF3
, &pTI
);
1024 ok(hr
== S_OK
, "hr %08x\n", hr
);
1026 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
1027 ok(hr
== S_OK
, "hr %08x\n", hr
);
1028 ok(pTA
->typekind
== TKIND_DISPATCH
, "kind %04x\n", pTA
->typekind
);
1029 ok(pTA
->cbSizeVft
== 7 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
1030 ok(pTA
->wTypeFlags
== TYPEFLAG_FDISPATCHABLE
, "typeflags %x\n", pTA
->wTypeFlags
);
1032 ok(pTA
->cFuncs
== 6, "cfuncs %d\n", pTA
->cFuncs
);
1033 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
1035 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
1038 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, 0, &href
);
1039 ok(hr
== S_OK
, "hr %08x\n", hr
);
1040 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
1041 ok(hr
== S_OK
, "hr %08x\n", hr
);
1042 hr
= ITypeInfo_GetTypeAttr(pTI_p
, &pTA
);
1043 ok(IsEqualGUID(&pTA
->guid
, &IID_IDispatch
), "guid {%08x-....\n", pTA
->guid
.Data1
);
1044 ITypeInfo_ReleaseTypeAttr(pTI_p
, pTA
);
1045 ITypeInfo_Release(pTI_p
);
1047 /* Should have six methods */
1048 hr
= ITypeInfo_GetFuncDesc(pTI
, 6, &pFD
);
1049 ok(hr
== TYPE_E_ELEMENTNOTFOUND
, "hr %08x\n", hr
);
1050 hr
= ITypeInfo_GetFuncDesc(pTI
, 5, &pFD
);
1051 ok(hr
== S_OK
, "hr %08x\n", hr
);
1052 ok(pFD
->memid
== 0x60020000, "memid %08x\n", pFD
->memid
);
1053 ok(pFD
->oVft
== 5 * sizeof(void *), "oVft %d\n", pFD
->oVft
);
1054 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
1056 ITypeInfo_Release(pTI
);
1059 /* ItestIF4 is a syntax 1 dispinterface */
1060 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &DIID_ItestIF4
, &pTI
);
1061 ok(hr
== S_OK
, "hr %08x\n", hr
);
1063 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
1064 ok(hr
== S_OK
, "hr %08x\n", hr
);
1065 ok(pTA
->typekind
== TKIND_DISPATCH
, "kind %04x\n", pTA
->typekind
);
1066 ok(pTA
->cbSizeVft
== 7 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
1067 ok(pTA
->wTypeFlags
== TYPEFLAG_FDISPATCHABLE
, "typeflags %x\n", pTA
->wTypeFlags
);
1068 ok(pTA
->cFuncs
== 1, "cfuncs %d\n", pTA
->cFuncs
);
1069 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
1070 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
1072 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, 0, &href
);
1073 ok(hr
== S_OK
, "hr %08x\n", hr
);
1074 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
1075 ok(hr
== S_OK
, "hr %08x\n", hr
);
1076 hr
= ITypeInfo_GetTypeAttr(pTI_p
, &pTA
);
1077 ok(IsEqualGUID(&pTA
->guid
, &IID_IDispatch
), "guid {%08x-....\n", pTA
->guid
.Data1
);
1078 ITypeInfo_ReleaseTypeAttr(pTI_p
, pTA
);
1079 ITypeInfo_Release(pTI_p
);
1080 hr
= ITypeInfo_GetFuncDesc(pTI
, 1, &pFD
);
1081 ok(hr
== TYPE_E_ELEMENTNOTFOUND
, "hr %08x\n", hr
);
1082 hr
= ITypeInfo_GetFuncDesc(pTI
, 0, &pFD
);
1083 ok(hr
== S_OK
, "hr %08x\n", hr
);
1084 ok(pFD
->memid
== 0x1c, "memid %08x\n", pFD
->memid
);
1085 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
1086 ITypeInfo_Release(pTI
);
1089 /* ItestIF5 is dual with inherited ifaces which derive from IUnknown but not IDispatch */
1090 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &IID_ItestIF5
, &pTI
);
1091 ok(hr
== S_OK
, "hr %08x\n", hr
);
1093 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
1094 ok(hr
== S_OK
, "hr %08x\n", hr
);
1097 ok(pTA
->typekind
== TKIND_DISPATCH
, "kind %04x\n", pTA
->typekind
);
1098 ok(pTA
->cbSizeVft
== 7 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
1100 ok(pTA
->wTypeFlags
== TYPEFLAG_FDUAL
, "typeflags %x\n", pTA
->wTypeFlags
);
1102 ok(pTA
->cFuncs
== 8, "cfuncs %d\n", pTA
->cFuncs
);
1103 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
1104 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
1106 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, 0, &href
);
1107 ok(hr
== S_OK
, "hr %08x\n", hr
);
1108 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
1109 ok(hr
== S_OK
, "hr %08x\n", hr
);
1110 hr
= ITypeInfo_GetTypeAttr(pTI_p
, &pTA
);
1111 ok(IsEqualGUID(&pTA
->guid
, &IID_IDispatch
), "guid {%08x-....\n", pTA
->guid
.Data1
);
1112 ITypeInfo_ReleaseTypeAttr(pTI_p
, pTA
);
1113 ITypeInfo_Release(pTI_p
);
1115 hr
= ITypeInfo_GetFuncDesc(pTI
, 6, &pFD
);
1116 ok(hr
== S_OK
, "hr %08x\n", hr
);
1117 ok(pFD
->memid
== 0x1234, "memid %08x\n", pFD
->memid
);
1118 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
1120 ITypeInfo_Release(pTI
);
1122 /* ItestIF7 is dual with inherited ifaces which derive from Dispatch */
1123 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &IID_ItestIF7
, &pTI
);
1124 ok(hr
== S_OK
, "hr %08x\n", hr
);
1126 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
1127 ok(hr
== S_OK
, "hr %08x\n", hr
);
1128 ok(pTA
->typekind
== TKIND_DISPATCH
, "kind %04x\n", pTA
->typekind
);
1129 ok(pTA
->cbSizeVft
== 7 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
1130 ok(pTA
->wTypeFlags
== (TYPEFLAG_FDISPATCHABLE
|TYPEFLAG_FDUAL
), "typeflags %x\n", pTA
->wTypeFlags
);
1131 ok(pTA
->cFuncs
== 10, "cfuncs %d\n", pTA
->cFuncs
);
1132 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
1133 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
1135 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, 0, &href
);
1136 ok(hr
== S_OK
, "hr %08x\n", hr
);
1137 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
1138 ok(hr
== S_OK
, "hr %08x\n", hr
);
1139 hr
= ITypeInfo_GetTypeAttr(pTI_p
, &pTA
);
1140 ok(IsEqualGUID(&pTA
->guid
, &IID_IDispatch
), "guid {%08x-....\n", pTA
->guid
.Data1
);
1141 ITypeInfo_ReleaseTypeAttr(pTI_p
, pTA
);
1142 ITypeInfo_Release(pTI_p
);
1144 hr
= ITypeInfo_GetFuncDesc(pTI
, 9, &pFD
);
1145 ok(hr
== S_OK
, "hr %08x\n", hr
);
1146 ok(pFD
->memid
== 0x1236, "memid %08x\n", pFD
->memid
);
1147 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
1148 ITypeInfo_Release(pTI
);
1150 /* ItestIF10 is a syntax 2 dispinterface which doesn't derive from IUnknown */
1151 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &DIID_ItestIF10
, &pTI
);
1152 ok(hr
== S_OK
, "hr %08x\n", hr
);
1154 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
1155 ok(hr
== S_OK
, "hr %08x\n", hr
);
1156 ok(pTA
->typekind
== TKIND_DISPATCH
, "kind %04x\n", pTA
->typekind
);
1157 ok(pTA
->cbSizeVft
== 7 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
1158 ok(pTA
->wTypeFlags
== TYPEFLAG_FDISPATCHABLE
, "typeflags %x\n", pTA
->wTypeFlags
);
1160 ok(pTA
->cFuncs
== 3, "cfuncs %d\n", pTA
->cFuncs
);
1161 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
1163 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
1166 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, -1, &href
);
1167 ok(hr
== TYPE_E_ELEMENTNOTFOUND
, "hr %08x\n", hr
);
1168 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, 0, &href
);
1169 ok(hr
== S_OK
, "hr %08x\n", hr
);
1170 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
1171 ok(hr
== S_OK
, "hr %08x\n", hr
);
1172 hr
= ITypeInfo_GetTypeAttr(pTI_p
, &pTA
);
1173 ok(IsEqualGUID(&pTA
->guid
, &IID_IDispatch
), "guid {%08x-....\n", pTA
->guid
.Data1
);
1174 ITypeInfo_ReleaseTypeAttr(pTI_p
, pTA
);
1175 ITypeInfo_Release(pTI_p
);
1177 /* Should have three methods */
1178 hr
= ITypeInfo_GetFuncDesc(pTI
, 3, &pFD
);
1179 ok(hr
== TYPE_E_ELEMENTNOTFOUND
, "hr %08x\n", hr
);
1180 hr
= ITypeInfo_GetFuncDesc(pTI
, 2, &pFD
);
1181 ok(hr
== S_OK
, "hr %08x\n", hr
);
1182 ok(pFD
->memid
== 0x60010000, "memid %08x\n", pFD
->memid
);
1183 ok(pFD
->oVft
== 2 * sizeof(void *), "oVft %d\n", pFD
->oVft
);
1184 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
1186 ITypeInfo_Release(pTI
);
1188 /* ItestIF11 is a syntax 2 dispinterface which derives from IDispatch */
1189 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &DIID_ItestIF11
, &pTI
);
1190 ok(hr
== S_OK
, "hr %08x\n", hr
);
1192 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
1193 ok(hr
== S_OK
, "hr %08x\n", hr
);
1194 ok(pTA
->typekind
== TKIND_DISPATCH
, "kind %04x\n", pTA
->typekind
);
1195 ok(pTA
->cbSizeVft
== 7 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
1196 ok(pTA
->wTypeFlags
== TYPEFLAG_FDISPATCHABLE
, "typeflags %x\n", pTA
->wTypeFlags
);
1198 ok(pTA
->cFuncs
== 10, "cfuncs %d\n", pTA
->cFuncs
);
1199 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
1201 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
1204 hr
= ITypeInfo_GetRefTypeOfImplType(pTI
, 0, &href
);
1205 ok(hr
== S_OK
, "hr %08x\n", hr
);
1206 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
1207 ok(hr
== S_OK
, "hr %08x\n", hr
);
1208 hr
= ITypeInfo_GetTypeAttr(pTI_p
, &pTA
);
1209 ok(IsEqualGUID(&pTA
->guid
, &IID_IDispatch
), "guid {%08x-....\n", pTA
->guid
.Data1
);
1210 ITypeInfo_ReleaseTypeAttr(pTI_p
, pTA
);
1211 ITypeInfo_Release(pTI_p
);
1213 /* Should have ten methods */
1214 hr
= ITypeInfo_GetFuncDesc(pTI
, 10, &pFD
);
1215 ok(hr
== TYPE_E_ELEMENTNOTFOUND
, "hr %08x\n", hr
);
1216 hr
= ITypeInfo_GetFuncDesc(pTI
, 9, &pFD
);
1217 ok(hr
== S_OK
, "hr %08x\n", hr
);
1218 ok(pFD
->memid
== 0x1236, "memid %08x\n", pFD
->memid
);
1219 ok(pFD
->oVft
== 9 * sizeof(void *), "oVft %d\n", pFD
->oVft
);
1221 /* first argument to 10th function is an HREFTYPE from the impl type */
1222 ok(pFD
->cParams
== 1, "cParams %i\n", pFD
->cParams
);
1223 ok(pFD
->lprgelemdescParam
[0].tdesc
.vt
== VT_USERDEFINED
,
1224 "vt 0x%x\n", pFD
->lprgelemdescParam
[0].tdesc
.vt
);
1225 href
= U(pFD
->lprgelemdescParam
[0].tdesc
).hreftype
;
1226 ok((href
& 0xff000000) == 0x04000000, "href 0x%08x\n", href
);
1227 hr
= ITypeInfo_GetRefTypeInfo(pTI
, href
, &pTI_p
);
1228 ok(SUCCEEDED(hr
), "hr %08x\n", hr
);
1229 if (SUCCEEDED(hr
)) ITypeInfo_Release(pTI_p
);
1230 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
1232 ITypeInfo_Release(pTI
);
1235 /* ItestIF2 is an interface which derives from IUnknown */
1236 hr
= ITypeLib_GetTypeInfoOfGuid(pTL
, &IID_ItestIF2
, &pTI
);
1237 ok(hr
== S_OK
, "hr %08x\n", hr
);
1239 hr
= ITypeInfo_GetTypeAttr(pTI
, &pTA
);
1240 ok(hr
== S_OK
, "hr %08x\n", hr
);
1241 ok(pTA
->typekind
== TKIND_INTERFACE
, "kind %04x\n", pTA
->typekind
);
1242 ok(pTA
->cbSizeVft
== 6 * sizeof(void *), "sizevft %d\n", pTA
->cbSizeVft
);
1243 ok(pTA
->wTypeFlags
== 0, "typeflags %x\n", pTA
->wTypeFlags
);
1245 ok(pTA
->cFuncs
== 1, "cfuncs %d\n", pTA
->cFuncs
);
1246 ok(pTA
->cImplTypes
== 1, "cimpltypes %d\n", pTA
->cImplTypes
);
1248 ITypeInfo_ReleaseTypeAttr(pTI
, pTA
);
1251 /* Should have one method */
1252 hr
= ITypeInfo_GetFuncDesc(pTI
, 1, &pFD
);
1253 ok(hr
== TYPE_E_ELEMENTNOTFOUND
, "hr %08x\n", hr
);
1254 hr
= ITypeInfo_GetFuncDesc(pTI
, 0, &pFD
);
1255 ok(hr
== S_OK
, "hr %08x\n", hr
);
1256 ok(pFD
->memid
== 0x60020000, "memid %08x\n", pFD
->memid
);
1257 ok(pFD
->oVft
== 5 * sizeof(void *), "oVft %d\n", pFD
->oVft
);
1258 ITypeInfo_ReleaseFuncDesc(pTI
, pFD
);
1260 ITypeInfo_Release(pTI
);
1262 ITypeLib_Release(pTL
);
1267 static void test_CreateTypeLib(void) {
1268 static const WCHAR stdoleW
[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
1269 static OLECHAR typelibW
[] = {'t','y','p','e','l','i','b',0};
1270 static OLECHAR helpfileW
[] = {'C',':','\\','b','o','g','u','s','.','h','l','p',0};
1271 static OLECHAR interface1W
[] = {'i','n','t','e','r','f','a','c','e','1',0};
1272 static OLECHAR interface2W
[] = {'i','n','t','e','r','f','a','c','e','2',0};
1273 static OLECHAR interface3W
[] = {'i','n','t','e','r','f','a','c','e','3',0};
1274 static OLECHAR dualW
[] = {'d','u','a','l',0};
1275 static OLECHAR coclassW
[] = {'c','o','c','l','a','s','s',0};
1276 static WCHAR defaultW
[] = {'d','e','f','a','u','l','t',0x3213,0};
1277 static WCHAR defaultQW
[] = {'d','e','f','a','u','l','t','?',0};
1278 static OLECHAR func1W
[] = {'f','u','n','c','1',0};
1279 static OLECHAR func2W
[] = {'f','u','n','c','2',0};
1280 static OLECHAR prop1W
[] = {'P','r','o','p','1',0};
1281 static OLECHAR param1W
[] = {'p','a','r','a','m','1',0};
1282 static OLECHAR param2W
[] = {'p','a','r','a','m','2',0};
1283 static OLECHAR asdfW
[] = {'A','s','d','f',0};
1284 static OLECHAR
*names1
[] = {func1W
, param1W
, param2W
};
1285 static OLECHAR
*names2
[] = {func2W
, param1W
, param2W
};
1286 static OLECHAR
*propname
[] = {prop1W
, param1W
};
1287 static const GUID custguid
= {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x70}};
1288 static const GUID bogusguid
= {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x71}};
1290 char filename
[MAX_PATH
];
1291 WCHAR filenameW
[MAX_PATH
];
1292 ICreateTypeLib2
*createtl
;
1293 ICreateTypeInfo
*createti
;
1294 ICreateTypeInfo2
*createti2
;
1295 ITypeLib
*tl
, *stdole
;
1296 ITypeInfo
*interface1
, *interface2
, *dual
, *unknown
, *dispatch
, *ti
;
1298 FUNCDESC funcdesc
, *pfuncdesc
;
1299 ELEMDESC elemdesc
[5], *edesc
;
1300 PARAMDESCEX paramdescex
;
1301 TYPEDESC typedesc1
, typedesc2
;
1305 BSTR name
, docstring
, helpfile
;
1311 trace("CreateTypeLib tests\n");
1313 hres
= LoadTypeLib(stdoleW
, &stdole
);
1314 ok(hres
== S_OK
, "got %08x\n", hres
);
1316 hres
= ITypeLib_GetTypeInfoOfGuid(stdole
, &IID_IUnknown
, &unknown
);
1317 ok(hres
== S_OK
, "got %08x\n", hres
);
1319 hres
= ITypeLib_GetTypeInfoOfGuid(stdole
, &IID_IDispatch
, &dispatch
);
1320 ok(hres
== S_OK
, "got %08x\n", hres
);
1322 GetTempFileNameA(".", "tlb", 0, filename
);
1323 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filenameW
, MAX_PATH
);
1325 hres
= CreateTypeLib2(SYS_WIN32
, filenameW
, &createtl
);
1326 ok(hres
== S_OK
, "got %08x\n", hres
);
1328 hres
= ICreateTypeLib_QueryInterface(createtl
, &IID_ITypeLib
, (void**)&tl
);
1329 ok(hres
== S_OK
, "got %08x\n", hres
);
1331 hres
= ITypeLib_GetLibAttr(tl
, &libattr
);
1332 ok(hres
== S_OK
, "got %08x\n", hres
);
1334 ok(libattr
->syskind
== SYS_WIN32
, "syskind = %d\n", libattr
->syskind
);
1335 ok(libattr
->wMajorVerNum
== 0, "wMajorVer = %d\n", libattr
->wMajorVerNum
);
1336 ok(libattr
->wMinorVerNum
== 0, "wMinorVerNum = %d\n", libattr
->wMinorVerNum
);
1337 ok(libattr
->wLibFlags
== 0, "wLibFlags = %d\n", libattr
->wLibFlags
);
1339 ITypeLib_ReleaseTLibAttr(tl
, libattr
);
1341 name
= (BSTR
)0xdeadbeef;
1342 hres
= ITypeLib_GetDocumentation(tl
, -1, &name
, &docstring
, &helpcontext
, &helpfile
);
1343 ok(hres
== S_OK
, "got %08x\n", hres
);
1344 ok(name
== NULL
, "name != NULL\n");
1345 ok(docstring
== NULL
, "docstring != NULL\n");
1346 ok(helpcontext
== 0, "helpcontext != 0\n");
1347 ok(helpfile
== NULL
, "helpfile != NULL\n");
1349 hres
= ITypeLib_GetDocumentation(tl
, 0, &name
, NULL
, NULL
, NULL
);
1350 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1352 hres
= ICreateTypeLib_SetName(createtl
, typelibW
);
1353 ok(hres
== S_OK
, "got %08x\n", hres
);
1355 hres
= ICreateTypeLib_SetHelpFileName(createtl
, helpfileW
);
1356 ok(hres
== S_OK
, "got %08x\n", hres
);
1358 hres
= ITypeLib_GetDocumentation(tl
, -1, NULL
, NULL
, NULL
, NULL
);
1359 ok(hres
== S_OK
, "got %08x\n", hres
);
1361 hres
= ITypeLib_GetDocumentation(tl
, -1, &name
, NULL
, NULL
, &helpfile
);
1362 ok(hres
== S_OK
, "got %08x\n", hres
);
1363 ok(!memcmp(name
, typelibW
, sizeof(typelibW
)), "name = %s\n", wine_dbgstr_w(name
));
1364 ok(!memcmp(helpfile
, helpfileW
, sizeof(helpfileW
)), "helpfile = %s\n", wine_dbgstr_w(helpfile
));
1366 SysFreeString(name
);
1367 SysFreeString(helpfile
);
1369 hres
= ICreateTypeLib_CreateTypeInfo(createtl
, interface1W
, TKIND_INTERFACE
, &createti
);
1370 ok(hres
== S_OK
, "got %08x\n", hres
);
1372 hres
= ICreateTypeInfo_QueryInterface(createti
, &IID_ITypeInfo
, (void**)&interface1
);
1373 ok(hres
== S_OK
, "got %08x\n", hres
);
1375 hres
= ITypeLib_GetDocumentation(tl
, 0, &name
, NULL
, NULL
, NULL
);
1376 ok(hres
== S_OK
, "got %08x\n", hres
);
1377 ok(!memcmp(name
, interface1W
, sizeof(interface1W
)), "name = %s\n", wine_dbgstr_w(name
));
1379 SysFreeString(name
);
1381 ITypeLib_Release(tl
);
1383 name
= (BSTR
)0xdeadbeef;
1384 helpfile
= (BSTR
)0xdeadbeef;
1385 hres
= ITypeInfo_GetDocumentation(interface1
, -1, &name
, &docstring
, &helpcontext
, &helpfile
);
1386 ok(hres
== S_OK
, "got %08x\n", hres
);
1387 ok(!memcmp(name
, interface1W
, sizeof(interface1W
)), "name = %s\n", wine_dbgstr_w(name
));
1388 ok(docstring
== NULL
, "docstring != NULL\n");
1389 ok(helpcontext
== 0, "helpcontext != 0\n");
1390 ok(!memcmp(helpfile
, helpfileW
, sizeof(helpfileW
)), "helpfile = %s\n", wine_dbgstr_w(helpfile
));
1392 SysFreeString(name
);
1393 SysFreeString(helpfile
);
1395 hres
= ITypeInfo_GetDocumentation(interface1
, 0, &name
, NULL
, NULL
, NULL
);
1396 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1398 hres
= ITypeInfo_GetRefTypeInfo(interface1
, 0, NULL
);
1399 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1402 hres
= ICreateTypeInfo_LayOut(createti
);
1403 ok(hres
== S_OK
, "got %08x\n", hres
);
1405 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, NULL
, &hreftype
);
1406 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1408 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, unknown
, NULL
);
1409 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1411 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, unknown
, &hreftype
);
1412 ok(hres
== S_OK
, "got %08x\n", hres
);
1414 skip("Skipping some tests\n");
1418 hres
= ICreateTypeInfo_AddImplType(createti
, 1, hreftype
);
1419 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1421 hres
= ICreateTypeInfo_AddImplType(createti
, 0, hreftype
);
1422 ok(hres
== S_OK
, "got %08x\n", hres
);
1424 hres
= ITypeInfo_GetRefTypeOfImplType(interface1
, 0, &hreftype
);
1425 ok(hres
== S_OK
, "got %08x\n", hres
);
1426 ok(hreftype
== 3, "hreftype = %d\n", hreftype
);
1428 hres
= ITypeInfo_GetRefTypeOfImplType(interface1
, -1, &hreftype
);
1429 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1431 ICreateTypeInfo_QueryInterface(createti
, &IID_ITypeInfo2
, (void**)&ti2
);
1433 memset(&funcdesc
, 0, sizeof(FUNCDESC
));
1434 funcdesc
.funckind
= FUNC_PUREVIRTUAL
;
1435 funcdesc
.invkind
= INVOKE_PROPERTYGET
;
1436 funcdesc
.callconv
= CC_STDCALL
;
1437 funcdesc
.elemdescFunc
.tdesc
.vt
= VT_BSTR
;
1438 U(funcdesc
.elemdescFunc
).idldesc
.wIDLFlags
= IDLFLAG_NONE
;
1440 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 0, NULL
);
1441 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1443 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 1, &funcdesc
);
1444 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1446 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 0, &funcdesc
);
1447 ok(hres
== S_OK
, "got %08x\n", hres
);
1449 hres
= ITypeInfo2_GetFuncDesc(ti2
, 0, NULL
);
1450 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1452 hres
= ITypeInfo2_GetFuncDesc(ti2
, 1, &pfuncdesc
);
1453 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1455 hres
= ITypeInfo2_GetFuncDesc(ti2
, 0, &pfuncdesc
);
1456 ok(hres
== S_OK
, "got %08x\n", hres
);
1458 ok(pfuncdesc
->memid
== 0, "got %x\n", pfuncdesc
->memid
);
1459 ok(pfuncdesc
->lprgscode
== NULL
, "got %p\n", pfuncdesc
->lprgscode
);
1460 ok(pfuncdesc
->lprgelemdescParam
== NULL
, "got %p\n", pfuncdesc
->lprgelemdescParam
);
1461 ok(pfuncdesc
->funckind
== FUNC_PUREVIRTUAL
, "got 0x%x\n", pfuncdesc
->funckind
);
1462 ok(pfuncdesc
->invkind
== INVOKE_PROPERTYGET
, "got 0x%x\n", pfuncdesc
->invkind
);
1463 ok(pfuncdesc
->callconv
== CC_STDCALL
, "got 0x%x\n", pfuncdesc
->callconv
);
1464 ok(pfuncdesc
->cParams
== 0, "got %d\n", pfuncdesc
->cParams
);
1465 ok(pfuncdesc
->cParamsOpt
== 0, "got %d\n", pfuncdesc
->cParamsOpt
);
1466 todo_wine
ok(pfuncdesc
->oVft
== 12 ||
1467 broken(pfuncdesc
->oVft
== 24) /* xp64 */,
1468 "got %d\n", pfuncdesc
->oVft
);
1469 ok(pfuncdesc
->cScodes
== 0, "got %d\n", pfuncdesc
->cScodes
);
1470 ok(pfuncdesc
->elemdescFunc
.tdesc
.vt
== VT_BSTR
, "got %d\n", pfuncdesc
->elemdescFunc
.tdesc
.vt
);
1471 ok(pfuncdesc
->wFuncFlags
== 0, "got 0x%x\n", pfuncdesc
->wFuncFlags
);
1473 ITypeInfo2_ReleaseFuncDesc(ti2
, pfuncdesc
);
1475 hres
= ICreateTypeInfo_SetFuncHelpContext(createti
, 0, 0xabcdefab);
1476 ok(hres
== S_OK
, "got %08x\n", hres
);
1478 funcdesc
.invkind
= INVOKE_PROPERTYPUT
;
1479 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 1, &funcdesc
);
1480 ok(hres
== TYPE_E_INCONSISTENTPROPFUNCS
, "got %08x\n", hres
);
1482 funcdesc
.invkind
= INVOKE_PROPERTYPUTREF
;
1483 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 1, &funcdesc
);
1484 ok(hres
== TYPE_E_INCONSISTENTPROPFUNCS
, "got %08x\n", hres
);
1486 elemdesc
[0].tdesc
.vt
= VT_BSTR
;
1487 U(elemdesc
[0]).idldesc
.dwReserved
= 0;
1488 U(elemdesc
[0]).idldesc
.wIDLFlags
= IDLFLAG_FIN
;
1490 funcdesc
.lprgelemdescParam
= elemdesc
;
1491 funcdesc
.invkind
= INVOKE_PROPERTYPUT
;
1492 funcdesc
.cParams
= 1;
1493 funcdesc
.elemdescFunc
.tdesc
.vt
= VT_VOID
;
1495 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 1, &funcdesc
);
1496 ok(hres
== S_OK
, "got %08x\n", hres
);
1498 hres
= ICreateTypeInfo_SetFuncHelpContext(createti
, 1, 0xabcdefab);
1499 ok(hres
== S_OK
, "got %08x\n", hres
);
1501 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 0, propname
, 1);
1502 ok(hres
== S_OK
, "got %08x\n", hres
);
1504 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 1, propname
, 1);
1505 ok(hres
== S_OK
, "got %08x\n", hres
);
1507 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 1, propname
, 2);
1508 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1510 hres
= ITypeInfo2_GetFuncDesc(ti2
, 1, &pfuncdesc
);
1511 ok(hres
== S_OK
, "got %08x\n", hres
);
1513 ok(pfuncdesc
->memid
== 0, "got %x\n", pfuncdesc
->memid
);
1514 ok(pfuncdesc
->lprgscode
== NULL
, "got %p\n", pfuncdesc
->lprgscode
);
1515 ok(pfuncdesc
->lprgelemdescParam
!= NULL
, "got %p\n", pfuncdesc
->lprgelemdescParam
);
1516 ok(pfuncdesc
->funckind
== FUNC_PUREVIRTUAL
, "got 0x%x\n", pfuncdesc
->funckind
);
1517 ok(pfuncdesc
->invkind
== INVOKE_PROPERTYPUT
, "got 0x%x\n", pfuncdesc
->invkind
);
1518 ok(pfuncdesc
->callconv
== CC_STDCALL
, "got 0x%x\n", pfuncdesc
->callconv
);
1519 ok(pfuncdesc
->cParams
== 1, "got %d\n", pfuncdesc
->cParams
);
1520 ok(pfuncdesc
->cParamsOpt
== 0, "got %d\n", pfuncdesc
->cParamsOpt
);
1521 todo_wine
ok(pfuncdesc
->oVft
== 16 ||
1522 broken(pfuncdesc
->oVft
== 28) /* xp64 */,
1523 "got %d\n", pfuncdesc
->oVft
);
1524 ok(pfuncdesc
->cScodes
== 0, "got %d\n", pfuncdesc
->cScodes
);
1525 ok(pfuncdesc
->elemdescFunc
.tdesc
.vt
== VT_VOID
, "got %d\n", pfuncdesc
->elemdescFunc
.tdesc
.vt
);
1526 ok(pfuncdesc
->wFuncFlags
== 0, "got 0x%x\n", pfuncdesc
->wFuncFlags
);
1528 edesc
= pfuncdesc
->lprgelemdescParam
;
1529 ok(edesc
->tdesc
.vt
== VT_BSTR
, "got: %d\n", edesc
->tdesc
.vt
);
1530 ok(U(*edesc
).idldesc
.wIDLFlags
== IDLFLAG_FIN
, "got: %x\n", U(*edesc
).idldesc
.wIDLFlags
);
1532 ITypeInfo2_ReleaseFuncDesc(ti2
, pfuncdesc
);
1535 funcdesc
.invkind
= INVOKE_PROPERTYPUTREF
;
1536 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 0, &funcdesc
);
1537 ok(hres
== S_OK
, "got %08x\n", hres
);
1539 hres
= ICreateTypeInfo_SetFuncHelpContext(createti
, 0, 0xabcdefab);
1540 ok(hres
== S_OK
, "got %08x\n", hres
);
1542 hres
= ICreateTypeInfo_SetFuncHelpContext(createti
, 0, 0x201);
1543 ok(hres
== S_OK
, "got %08x\n", hres
);
1546 funcdesc
.lprgelemdescParam
= NULL
;
1547 funcdesc
.invkind
= INVOKE_FUNC
;
1548 funcdesc
.cParams
= 0;
1549 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 1, &funcdesc
);
1550 ok(hres
== S_OK
, "got %08x\n", hres
);
1552 hres
= ITypeInfo2_GetFuncDesc(ti2
, 1, &pfuncdesc
);
1553 ok(hres
== S_OK
, "got %08x\n", hres
);
1555 ok(pfuncdesc
->memid
== 1, "got %d\n", pfuncdesc
->memid
);
1556 ok(pfuncdesc
->lprgscode
== NULL
, "got %p\n", pfuncdesc
->lprgscode
);
1557 ok(pfuncdesc
->lprgelemdescParam
== NULL
, "got %p\n", pfuncdesc
->lprgelemdescParam
);
1558 ok(pfuncdesc
->funckind
== FUNC_PUREVIRTUAL
, "got 0x%x\n", pfuncdesc
->funckind
);
1559 ok(pfuncdesc
->invkind
== INVOKE_FUNC
, "got 0x%x\n", pfuncdesc
->invkind
);
1560 ok(pfuncdesc
->callconv
== CC_STDCALL
, "got 0x%x\n", pfuncdesc
->callconv
);
1561 ok(pfuncdesc
->cParams
== 0, "got %d\n", pfuncdesc
->cParams
);
1562 ok(pfuncdesc
->cParamsOpt
== 0, "got %d\n", pfuncdesc
->cParamsOpt
);
1563 todo_wine
ok(pfuncdesc
->oVft
== 16 ||
1564 broken(pfuncdesc
->oVft
== 28), /* xp64 */
1565 "got %d\n", pfuncdesc
->oVft
);
1566 ok(pfuncdesc
->cScodes
== 0, "got %d\n", pfuncdesc
->cScodes
);
1567 ok(pfuncdesc
->elemdescFunc
.tdesc
.vt
== VT_VOID
, "got %d\n", pfuncdesc
->elemdescFunc
.tdesc
.vt
);
1568 ok(pfuncdesc
->wFuncFlags
== 0, "got 0x%x\n", pfuncdesc
->wFuncFlags
);
1570 ITypeInfo2_ReleaseFuncDesc(ti2
, pfuncdesc
);
1572 funcdesc
.memid
= MEMBERID_NIL
;
1573 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 1, &funcdesc
);
1574 ok(hres
== S_OK
, "got %08x\n", hres
);
1576 elemdesc
[0].tdesc
.vt
= VT_PTR
;
1577 U(elemdesc
[0].tdesc
).lptdesc
= &typedesc1
;
1578 typedesc1
.vt
= VT_BSTR
;
1579 funcdesc
.cParams
= 1;
1580 funcdesc
.lprgelemdescParam
= elemdesc
;
1581 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 4, &funcdesc
);
1582 ok(hres
== S_OK
, "got %08x\n", hres
);
1584 hres
= ITypeInfo2_GetFuncDesc(ti2
, 4, &pfuncdesc
);
1585 ok(hres
== S_OK
, "got %08x\n", hres
);
1587 ok(pfuncdesc
->memid
== 0x60010004, "got %x\n", pfuncdesc
->memid
);
1588 ok(pfuncdesc
->lprgscode
== NULL
, "got %p\n", pfuncdesc
->lprgscode
);
1589 ok(pfuncdesc
->lprgelemdescParam
!= NULL
, "got %p\n", pfuncdesc
->lprgelemdescParam
);
1590 ok(pfuncdesc
->funckind
== FUNC_PUREVIRTUAL
, "got 0x%x\n", pfuncdesc
->funckind
);
1591 ok(pfuncdesc
->invkind
== INVOKE_FUNC
, "got 0x%x\n", pfuncdesc
->invkind
);
1592 ok(pfuncdesc
->callconv
== CC_STDCALL
, "got 0x%x\n", pfuncdesc
->callconv
);
1593 ok(pfuncdesc
->cParams
== 1, "got %d\n", pfuncdesc
->cParams
);
1594 ok(pfuncdesc
->cParamsOpt
== 0, "got %d\n", pfuncdesc
->cParamsOpt
);
1595 todo_wine
ok(pfuncdesc
->oVft
== 28 ||
1596 broken(pfuncdesc
->oVft
== 40) /* xp64 */,
1597 "got %d\n", pfuncdesc
->oVft
);
1598 ok(pfuncdesc
->cScodes
== 0, "got %d\n", pfuncdesc
->cScodes
);
1599 ok(pfuncdesc
->elemdescFunc
.tdesc
.vt
== VT_VOID
, "got %d\n", pfuncdesc
->elemdescFunc
.tdesc
.vt
);
1600 ok(pfuncdesc
->wFuncFlags
== 0, "got 0x%x\n", pfuncdesc
->wFuncFlags
);
1602 edesc
= pfuncdesc
->lprgelemdescParam
;
1603 ok(edesc
->tdesc
.vt
== VT_PTR
, "got: %d\n", edesc
->tdesc
.vt
);
1604 ok(U(*edesc
).paramdesc
.wParamFlags
== PARAMFLAG_FIN
, "got: 0x%x\n", U(*edesc
).paramdesc
.wParamFlags
);
1605 ok(U(*edesc
).paramdesc
.pparamdescex
== NULL
, "got: %p\n", U(*edesc
).paramdesc
.pparamdescex
);
1606 ok(U(edesc
->tdesc
).lptdesc
!= NULL
, "got: %p\n", U(edesc
->tdesc
).lptdesc
);
1607 ok(U(edesc
->tdesc
).lptdesc
->vt
== VT_BSTR
, "got: %d\n", U(edesc
->tdesc
).lptdesc
->vt
);
1609 ITypeInfo2_ReleaseFuncDesc(ti2
, pfuncdesc
);
1611 U(elemdesc
[0].tdesc
).lptdesc
= &typedesc2
;
1612 typedesc2
.vt
= VT_PTR
;
1613 U(typedesc2
).lptdesc
= &typedesc1
;
1614 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 4, &funcdesc
);
1615 ok(hres
== S_OK
, "got %08x\n", hres
);
1617 hres
= ITypeInfo2_GetFuncDesc(ti2
, 4, &pfuncdesc
);
1618 ok(hres
== S_OK
, "got %08x\n", hres
);
1620 ok(pfuncdesc
->memid
== 0x60010007, "got %x\n", pfuncdesc
->memid
);
1621 ok(pfuncdesc
->lprgscode
== NULL
, "got %p\n", pfuncdesc
->lprgscode
);
1622 ok(pfuncdesc
->lprgelemdescParam
!= NULL
, "got %p\n", pfuncdesc
->lprgelemdescParam
);
1623 ok(pfuncdesc
->funckind
== FUNC_PUREVIRTUAL
, "got 0x%x\n", pfuncdesc
->funckind
);
1624 ok(pfuncdesc
->invkind
== INVOKE_FUNC
, "got 0x%x\n", pfuncdesc
->invkind
);
1625 ok(pfuncdesc
->callconv
== CC_STDCALL
, "got 0x%x\n", pfuncdesc
->callconv
);
1626 ok(pfuncdesc
->cParams
== 1, "got %d\n", pfuncdesc
->cParams
);
1627 ok(pfuncdesc
->cParamsOpt
== 0, "got %d\n", pfuncdesc
->cParamsOpt
);
1628 todo_wine
ok(pfuncdesc
->oVft
== 28 ||
1629 broken(pfuncdesc
->oVft
== 40) /* xp64 */,
1630 "got %d\n", pfuncdesc
->oVft
);
1631 ok(pfuncdesc
->cScodes
== 0, "got %d\n", pfuncdesc
->cScodes
);
1632 ok(pfuncdesc
->elemdescFunc
.tdesc
.vt
== VT_VOID
, "got %d\n", pfuncdesc
->elemdescFunc
.tdesc
.vt
);
1633 ok(pfuncdesc
->wFuncFlags
== 0, "got 0x%x\n", pfuncdesc
->wFuncFlags
);
1635 edesc
= pfuncdesc
->lprgelemdescParam
;
1636 ok(edesc
->tdesc
.vt
== VT_PTR
, "got: %d\n", edesc
->tdesc
.vt
);
1637 ok(U(*edesc
).paramdesc
.wParamFlags
== PARAMFLAG_FIN
, "got: 0x%x\n", U(*edesc
).paramdesc
.wParamFlags
);
1638 ok(U(*edesc
).paramdesc
.pparamdescex
== NULL
, "got: %p\n", U(*edesc
).paramdesc
.pparamdescex
);
1639 ok(U(edesc
->tdesc
).lptdesc
!= NULL
, "got: %p\n", U(edesc
->tdesc
).lptdesc
);
1640 ok(U(edesc
->tdesc
).lptdesc
->vt
== VT_PTR
, "got: %d\n", U(edesc
->tdesc
).lptdesc
->vt
);
1641 ok(U(*U(edesc
->tdesc
).lptdesc
).lptdesc
!= NULL
, "got: %p\n", U(*U(edesc
->tdesc
).lptdesc
).lptdesc
);
1642 ok(U(*U(edesc
->tdesc
).lptdesc
).lptdesc
->vt
== VT_BSTR
, "got: %d\n", U(*U(edesc
->tdesc
).lptdesc
).lptdesc
->vt
);
1644 ITypeInfo2_ReleaseFuncDesc(ti2
, pfuncdesc
);
1646 elemdesc
[0].tdesc
.vt
= VT_INT
;
1647 U(elemdesc
[0]).paramdesc
.wParamFlags
= PARAMFLAG_FHASDEFAULT
;
1648 U(elemdesc
[0]).paramdesc
.pparamdescex
= ¶mdescex
;
1649 V_VT(¶mdescex
.varDefaultValue
) = VT_INT
;
1650 V_INT(¶mdescex
.varDefaultValue
) = 0x123;
1651 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 3, &funcdesc
);
1652 ok(hres
== S_OK
, "got %08x\n", hres
);
1654 hres
= ITypeInfo2_GetFuncDesc(ti2
, 3, &pfuncdesc
);
1655 ok(hres
== S_OK
, "got %08x\n", hres
);
1657 ok(pfuncdesc
->memid
== 0x60010003, "got %x\n", pfuncdesc
->memid
);
1658 ok(pfuncdesc
->lprgscode
== NULL
, "got %p\n", pfuncdesc
->lprgscode
);
1659 ok(pfuncdesc
->lprgelemdescParam
!= NULL
, "got %p\n", pfuncdesc
->lprgelemdescParam
);
1660 ok(pfuncdesc
->funckind
== FUNC_PUREVIRTUAL
, "got 0x%x\n", pfuncdesc
->funckind
);
1661 ok(pfuncdesc
->invkind
== INVOKE_FUNC
, "got 0x%x\n", pfuncdesc
->invkind
);
1662 ok(pfuncdesc
->callconv
== CC_STDCALL
, "got 0x%x\n", pfuncdesc
->callconv
);
1663 ok(pfuncdesc
->cParams
== 1, "got %d\n", pfuncdesc
->cParams
);
1664 ok(pfuncdesc
->cParamsOpt
== 0, "got %d\n", pfuncdesc
->cParamsOpt
);
1665 todo_wine
ok(pfuncdesc
->oVft
== 24 ||
1666 broken(pfuncdesc
->oVft
== 36) /* xp64 */,
1667 "got %d\n", pfuncdesc
->oVft
);
1668 ok(pfuncdesc
->cScodes
== 0, "got %d\n", pfuncdesc
->cScodes
);
1669 ok(pfuncdesc
->elemdescFunc
.tdesc
.vt
== VT_VOID
, "got %d\n", pfuncdesc
->elemdescFunc
.tdesc
.vt
);
1670 ok(pfuncdesc
->wFuncFlags
== 0, "got 0x%x\n", pfuncdesc
->wFuncFlags
);
1672 edesc
= pfuncdesc
->lprgelemdescParam
;
1673 ok(edesc
->tdesc
.vt
== VT_INT
, "got: %d\n", edesc
->tdesc
.vt
);
1674 ok(U(*edesc
).paramdesc
.wParamFlags
== PARAMFLAG_FHASDEFAULT
, "got: 0x%x\n", U(*edesc
).paramdesc
.wParamFlags
);
1675 ok(U(*edesc
).paramdesc
.pparamdescex
!= NULL
, "got: %p\n", U(*edesc
).paramdesc
.pparamdescex
);
1676 ok(U(*edesc
).paramdesc
.pparamdescex
->cBytes
== sizeof(PARAMDESCEX
), "got: %d\n",
1677 U(*edesc
).paramdesc
.pparamdescex
->cBytes
);
1678 ok(V_VT(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
) == VT_I4
, "got: %d\n",
1679 V_VT(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
));
1680 ok(V_I4(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
) == 0x123, "got: 0x%x\n",
1681 V_I4(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
));
1683 ITypeInfo2_ReleaseFuncDesc(ti2
, pfuncdesc
);
1685 U(elemdesc
[0]).idldesc
.dwReserved
= 0;
1686 U(elemdesc
[0]).idldesc
.wIDLFlags
= IDLFLAG_FIN
;
1687 elemdesc
[1].tdesc
.vt
= VT_UI2
;
1688 U(elemdesc
[1]).paramdesc
.wParamFlags
= PARAMFLAG_FHASDEFAULT
;
1689 U(elemdesc
[1]).paramdesc
.pparamdescex
= ¶mdescex
;
1690 V_VT(¶mdescex
.varDefaultValue
) = VT_UI2
;
1691 V_UI2(¶mdescex
.varDefaultValue
) = 0xffff;
1692 funcdesc
.cParams
= 2;
1693 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 3, &funcdesc
);
1694 ok(hres
== S_OK
, "got %08x\n", hres
);
1696 hres
= ITypeInfo2_GetFuncDesc(ti2
, 3, &pfuncdesc
);
1697 ok(hres
== S_OK
, "got %08x\n", hres
);
1699 ok(pfuncdesc
->memid
== 0x60010009, "got %x\n", pfuncdesc
->memid
);
1700 ok(pfuncdesc
->lprgscode
== NULL
, "got %p\n", pfuncdesc
->lprgscode
);
1701 ok(pfuncdesc
->lprgelemdescParam
!= NULL
, "got %p\n", pfuncdesc
->lprgelemdescParam
);
1702 ok(pfuncdesc
->funckind
== FUNC_PUREVIRTUAL
, "got 0x%x\n", pfuncdesc
->funckind
);
1703 ok(pfuncdesc
->invkind
== INVOKE_FUNC
, "got 0x%x\n", pfuncdesc
->invkind
);
1704 ok(pfuncdesc
->callconv
== CC_STDCALL
, "got 0x%x\n", pfuncdesc
->callconv
);
1705 ok(pfuncdesc
->cParams
== 2, "got %d\n", pfuncdesc
->cParams
);
1706 ok(pfuncdesc
->cParamsOpt
== 0, "got %d\n", pfuncdesc
->cParamsOpt
);
1707 todo_wine
ok(pfuncdesc
->oVft
== 24 ||
1708 broken(pfuncdesc
->oVft
== 36) /* xp64 */,
1709 "got %d\n", pfuncdesc
->oVft
);
1710 ok(pfuncdesc
->cScodes
== 0, "got %d\n", pfuncdesc
->cScodes
);
1711 ok(pfuncdesc
->elemdescFunc
.tdesc
.vt
== VT_VOID
, "got %d\n", pfuncdesc
->elemdescFunc
.tdesc
.vt
);
1712 ok(pfuncdesc
->wFuncFlags
== 0, "got 0x%x\n", pfuncdesc
->wFuncFlags
);
1714 edesc
= pfuncdesc
->lprgelemdescParam
;
1715 ok(edesc
->tdesc
.vt
== VT_INT
, "got: %d\n", edesc
->tdesc
.vt
);
1716 ok(U(*edesc
).paramdesc
.wParamFlags
== PARAMFLAG_FIN
, "got: 0x%x\n", U(*edesc
).paramdesc
.wParamFlags
);
1717 ok(U(*edesc
).paramdesc
.pparamdescex
== NULL
, "got: %p\n", U(*edesc
).paramdesc
.pparamdescex
);
1719 edesc
= pfuncdesc
->lprgelemdescParam
+ 1;
1720 ok(edesc
->tdesc
.vt
== VT_UI2
, "got: %d\n", edesc
->tdesc
.vt
);
1721 ok(U(*edesc
).paramdesc
.wParamFlags
== PARAMFLAG_FHASDEFAULT
, "got: 0x%x\n", U(*edesc
).paramdesc
.wParamFlags
);
1722 ok(U(*edesc
).paramdesc
.pparamdescex
!= NULL
, "got: %p\n", U(*edesc
).paramdesc
.pparamdescex
);
1723 ok(U(*edesc
).paramdesc
.pparamdescex
->cBytes
== sizeof(PARAMDESCEX
), "got: %d\n",
1724 U(*edesc
).paramdesc
.pparamdescex
->cBytes
);
1725 ok(V_VT(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
) == VT_UI2
, "got: %d\n",
1726 V_VT(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
));
1727 ok(V_UI2(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
) == 0xFFFF, "got: 0x%x\n",
1728 V_UI2(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
));
1730 ITypeInfo2_ReleaseFuncDesc(ti2
, pfuncdesc
);
1732 U(elemdesc
[0]).paramdesc
.wParamFlags
= PARAMFLAG_FHASDEFAULT
;
1733 U(elemdesc
[0]).paramdesc
.pparamdescex
= ¶mdescex
;
1734 elemdesc
[1].tdesc
.vt
= VT_INT
;
1735 V_VT(¶mdescex
.varDefaultValue
) = VT_INT
;
1736 V_INT(¶mdescex
.varDefaultValue
) = 0xffffffff;
1737 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 3, &funcdesc
);
1738 ok(hres
== S_OK
, "got %08x\n", hres
);
1740 elemdesc
[0].tdesc
.vt
= VT_BSTR
;
1741 elemdesc
[1].tdesc
.vt
= VT_BSTR
;
1742 V_VT(¶mdescex
.varDefaultValue
) = VT_BSTR
;
1743 V_BSTR(¶mdescex
.varDefaultValue
) = SysAllocString(defaultW
);
1744 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 3, &funcdesc
);
1745 ok(hres
== S_OK
, "got %08x\n", hres
);
1747 hres
= ITypeInfo2_GetFuncDesc(ti2
, 3, &pfuncdesc
);
1748 ok(hres
== S_OK
, "got %08x\n", hres
);
1750 ok(pfuncdesc
->memid
== 0x6001000b, "got %x\n", pfuncdesc
->memid
);
1751 ok(pfuncdesc
->lprgscode
== NULL
, "got %p\n", pfuncdesc
->lprgscode
);
1752 ok(pfuncdesc
->lprgelemdescParam
!= NULL
, "got %p\n", pfuncdesc
->lprgelemdescParam
);
1753 ok(pfuncdesc
->funckind
== FUNC_PUREVIRTUAL
, "got 0x%x\n", pfuncdesc
->funckind
);
1754 ok(pfuncdesc
->invkind
== INVOKE_FUNC
, "got 0x%x\n", pfuncdesc
->invkind
);
1755 ok(pfuncdesc
->callconv
== CC_STDCALL
, "got 0x%x\n", pfuncdesc
->callconv
);
1756 ok(pfuncdesc
->cParams
== 2, "got %d\n", pfuncdesc
->cParams
);
1757 ok(pfuncdesc
->cParamsOpt
== 0, "got %d\n", pfuncdesc
->cParamsOpt
);
1758 todo_wine
ok(pfuncdesc
->oVft
== 24 ||
1759 broken(pfuncdesc
->oVft
== 36) /* xp64 */,
1760 "got %d\n", pfuncdesc
->oVft
);
1761 ok(pfuncdesc
->cScodes
== 0, "got %d\n", pfuncdesc
->cScodes
);
1762 ok(pfuncdesc
->elemdescFunc
.tdesc
.vt
== VT_VOID
, "got %d\n", pfuncdesc
->elemdescFunc
.tdesc
.vt
);
1763 ok(pfuncdesc
->wFuncFlags
== 0, "got 0x%x\n", pfuncdesc
->wFuncFlags
);
1765 edesc
= pfuncdesc
->lprgelemdescParam
;
1766 ok(edesc
->tdesc
.vt
== VT_BSTR
, "got: %d\n", edesc
->tdesc
.vt
);
1767 ok(U(*edesc
).paramdesc
.wParamFlags
== PARAMFLAG_FHASDEFAULT
, "got: 0x%x\n", U(*edesc
).paramdesc
.wParamFlags
);
1768 ok(U(*edesc
).paramdesc
.pparamdescex
!= NULL
, "got: %p\n", U(*edesc
).paramdesc
.pparamdescex
);
1769 ok(U(*edesc
).paramdesc
.pparamdescex
->cBytes
== sizeof(PARAMDESCEX
), "got: %d\n",
1770 U(*edesc
).paramdesc
.pparamdescex
->cBytes
);
1771 ok(V_VT(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
) == VT_BSTR
, "got: %d\n",
1772 V_VT(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
));
1773 ok(!lstrcmpW(V_BSTR(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
), defaultQW
),
1775 wine_dbgstr_w(V_BSTR(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
)));
1777 edesc
= pfuncdesc
->lprgelemdescParam
+ 1;
1778 ok(edesc
->tdesc
.vt
== VT_BSTR
, "got: %d\n", edesc
->tdesc
.vt
);
1779 ok(U(*edesc
).paramdesc
.wParamFlags
== PARAMFLAG_FHASDEFAULT
, "got: 0x%x\n", U(*edesc
).paramdesc
.wParamFlags
);
1780 ok(U(*edesc
).paramdesc
.pparamdescex
!= NULL
, "got: %p\n", U(*edesc
).paramdesc
.pparamdescex
);
1781 ok(U(*edesc
).paramdesc
.pparamdescex
->cBytes
== sizeof(PARAMDESCEX
), "got: %d\n",
1782 U(*edesc
).paramdesc
.pparamdescex
->cBytes
);
1783 ok(V_VT(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
) == VT_BSTR
, "got: %d\n",
1784 V_VT(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
));
1785 ok(!lstrcmpW(V_BSTR(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
), defaultQW
),
1787 wine_dbgstr_w(V_BSTR(&U(*edesc
).paramdesc
.pparamdescex
->varDefaultValue
)));
1789 ITypeInfo2_ReleaseFuncDesc(ti2
, pfuncdesc
);
1791 elemdesc
[0].tdesc
.vt
= VT_USERDEFINED
;
1792 U(elemdesc
[0].tdesc
).hreftype
= hreftype
;
1793 U(elemdesc
[0]).paramdesc
.pparamdescex
= NULL
;
1794 U(elemdesc
[0]).paramdesc
.wParamFlags
= 0;
1796 funcdesc
.lprgelemdescParam
= elemdesc
;
1797 funcdesc
.invkind
= INVOKE_FUNC
;
1798 funcdesc
.cParams
= 1;
1799 funcdesc
.elemdescFunc
.tdesc
.vt
= VT_VOID
;
1801 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 5, &funcdesc
);
1802 ok(hres
== S_OK
, "got %08x\n", hres
);
1804 hres
= ITypeInfo2_GetFuncDesc(ti2
, 5, &pfuncdesc
);
1805 ok(hres
== S_OK
, "got %08x\n", hres
);
1807 ok(pfuncdesc
->memid
== 0x60010005, "got %x\n", pfuncdesc
->memid
);
1808 ok(pfuncdesc
->lprgscode
== NULL
, "got %p\n", pfuncdesc
->lprgscode
);
1809 ok(pfuncdesc
->lprgelemdescParam
!= NULL
, "got %p\n", pfuncdesc
->lprgelemdescParam
);
1810 ok(pfuncdesc
->funckind
== FUNC_PUREVIRTUAL
, "got 0x%x\n", pfuncdesc
->funckind
);
1811 ok(pfuncdesc
->invkind
== INVOKE_FUNC
, "got 0x%x\n", pfuncdesc
->invkind
);
1812 ok(pfuncdesc
->callconv
== CC_STDCALL
, "got 0x%x\n", pfuncdesc
->callconv
);
1813 ok(pfuncdesc
->cParams
== 1, "got %d\n", pfuncdesc
->cParams
);
1814 ok(pfuncdesc
->cParamsOpt
== 0, "got %d\n", pfuncdesc
->cParamsOpt
);
1815 todo_wine
ok(pfuncdesc
->oVft
== 32 ||
1816 broken(pfuncdesc
->oVft
== 44), /* xp64 */
1817 "got %d\n", pfuncdesc
->oVft
);
1818 ok(pfuncdesc
->cScodes
== 0, "got %d\n", pfuncdesc
->cScodes
);
1819 ok(pfuncdesc
->elemdescFunc
.tdesc
.vt
== VT_VOID
, "got %d\n", pfuncdesc
->elemdescFunc
.tdesc
.vt
);
1820 ok(pfuncdesc
->wFuncFlags
== 0, "got 0x%x\n", pfuncdesc
->wFuncFlags
);
1822 edesc
= pfuncdesc
->lprgelemdescParam
;
1823 ok(U(*edesc
).paramdesc
.pparamdescex
== NULL
, "got: %p\n", U(*edesc
).paramdesc
.pparamdescex
);
1824 ok(U(*edesc
).paramdesc
.wParamFlags
== 0, "got: 0x%x\n", U(*edesc
).paramdesc
.wParamFlags
);
1825 ok(edesc
->tdesc
.vt
== VT_USERDEFINED
, "got: %d\n", edesc
->tdesc
.vt
);
1826 ok(U(edesc
->tdesc
).hreftype
== hreftype
, "got: 0x%x\n", U(edesc
->tdesc
).hreftype
);
1828 ITypeInfo2_ReleaseFuncDesc(ti2
, pfuncdesc
);
1830 hres
= ITypeInfo_GetDocumentation(interface1
, 0, &name
, &docstring
, &helpcontext
, &helpfile
);
1831 ok(hres
== S_OK
, "got %08x\n", hres
);
1832 ok(name
== NULL
, "name != NULL\n");
1833 ok(docstring
== NULL
, "docstring != NULL\n");
1834 ok(helpcontext
== 0x201, "helpcontext != 0x201\n");
1835 ok(!memcmp(helpfile
, helpfileW
, sizeof(helpfileW
)), "helpfile = %s\n", wine_dbgstr_w(helpfile
));
1837 SysFreeString(helpfile
);
1839 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 1000, NULL
, 1);
1840 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1842 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 1000, names1
, 1);
1843 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1845 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 0, names1
, 2);
1846 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1848 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 0, names2
, 1);
1849 ok(hres
== S_OK
, "got %08x\n", hres
);
1851 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 0, names1
, 1);
1852 ok(hres
== S_OK
, "got %08x\n", hres
);
1854 hres
= ITypeInfo_GetDocumentation(interface1
, 0, &name
, NULL
, NULL
, NULL
);
1855 ok(hres
== S_OK
, "got %08x\n", hres
);
1856 ok(!memcmp(name
, func1W
, sizeof(func1W
)), "name = %s\n", wine_dbgstr_w(name
));
1858 SysFreeString(name
);
1860 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 3, names2
, 3);
1861 ok(hres
== S_OK
, "got %08x\n", hres
);
1863 hres
= ICreateTypeInfo_SetFuncAndParamNames(createti
, 3, names1
, 3);
1864 ok(hres
== TYPE_E_AMBIGUOUSNAME
, "got %08x\n", hres
);
1866 ITypeInfo2_Release(ti2
);
1867 ICreateTypeInfo_Release(createti
);
1869 hres
= ICreateTypeLib_CreateTypeInfo(createtl
, interface1W
, TKIND_INTERFACE
, &createti
);
1870 ok(hres
== TYPE_E_NAMECONFLICT
, "got %08x\n", hres
);
1872 hres
= ICreateTypeLib_CreateTypeInfo(createtl
, interface2W
, TKIND_INTERFACE
, &createti
);
1873 ok(hres
== S_OK
, "got %08x\n", hres
);
1875 hres
= ICreateTypeInfo_QueryInterface(createti
, &IID_ITypeInfo
, (void**)&interface2
);
1876 ok(hres
== S_OK
, "got %08x\n", hres
);
1878 hres
= ITypeInfo_GetRefTypeOfImplType(interface2
, 0, &hreftype
);
1879 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1881 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, interface1
, &hreftype
);
1882 ok(hres
== S_OK
, "got %08x\n", hres
);
1884 hres
= ITypeInfo_GetRefTypeInfo(interface2
, 0, &ti
);
1885 ok(hres
== S_OK
, "got %08x\n", hres
);
1886 ok(ti
== interface1
, "Received and added interfaces are different\n");
1888 ITypeInfo_Release(ti
);
1890 hres
= ICreateTypeInfo_AddImplType(createti
, 0, hreftype
);
1891 ok(hres
== S_OK
, "got %08x\n", hres
);
1893 hres
= ITypeInfo_GetRefTypeOfImplType(interface2
, 0, &hreftype
);
1894 ok(hres
== S_OK
, "got %08x\n", hres
);
1895 ok(hreftype
== 2, "hreftype = %d\n", hreftype
);
1897 hres
= ITypeInfo_GetRefTypeOfImplType(interface2
, -1, &hreftype
);
1898 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1900 hres
= ICreateTypeInfo_SetImplTypeFlags(createti
, 0, IMPLTYPEFLAG_FDEFAULT
);
1901 ok(hres
== TYPE_E_BADMODULEKIND
, "got %08x\n", hres
);
1903 hres
= ITypeInfo_GetImplTypeFlags(interface2
, 0, &impltypeflags
);
1904 ok(hres
== S_OK
, "got %08x\n", hres
);
1905 ok(impltypeflags
== 0, "impltypeflags = %x\n", impltypeflags
);
1907 hres
= ITypeInfo_GetImplTypeFlags(interface2
, 1, &impltypeflags
);
1908 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
1910 funcdesc
.oVft
= 0xaaac;
1911 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 0, &funcdesc
);
1912 ok(hres
== S_OK
, "got %08x\n", hres
);
1913 funcdesc
.oVft
= 0xaaa8;
1914 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 0, &funcdesc
);
1915 ok(hres
== S_OK
, "got %08x\n", hres
);
1918 ICreateTypeInfo_Release(createti
);
1920 VariantInit(&cust_data
);
1922 hres
= ICreateTypeLib_CreateTypeInfo(createtl
, interface3W
, TKIND_INTERFACE
, &createti
);
1923 ok(hres
== S_OK
, "got %08x\n", hres
);
1925 hres
= ICreateTypeInfo_QueryInterface(createti
, &IID_ICreateTypeInfo2
, (void**)&createti2
);
1926 ok(hres
== S_OK
, "got %08x\n", hres
);
1928 hres
= ICreateTypeInfo2_QueryInterface(createti2
, &IID_ITypeInfo2
, (void**)&ti2
);
1929 ok(hres
== S_OK
, "got %08x\n", hres
);
1931 hres
= ITypeInfo2_GetCustData(ti2
, NULL
, NULL
);
1932 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1934 hres
= ITypeInfo2_GetCustData(ti2
, &custguid
, NULL
);
1935 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1937 hres
= ITypeInfo2_GetCustData(ti2
, &custguid
, &cust_data
);
1938 ok(hres
== S_OK
, "got %08x\n", hres
);
1940 hres
= ICreateTypeInfo2_SetCustData(createti2
, NULL
, NULL
);
1941 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1943 hres
= ICreateTypeInfo2_SetCustData(createti2
, &custguid
, NULL
);
1944 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
1946 hres
= ICreateTypeInfo2_SetCustData(createti2
, &custguid
, &cust_data
);
1947 ok(hres
== DISP_E_BADVARTYPE
, "got %08x\n", hres
);
1949 V_VT(&cust_data
) = VT_UI4
;
1950 V_I4(&cust_data
) = 0xdeadbeef;
1952 hres
= ICreateTypeInfo2_SetCustData(createti2
, &custguid
, &cust_data
);
1953 ok(hres
== S_OK
, "got %08x\n", hres
);
1955 V_I4(&cust_data
) = 0;
1956 V_VT(&cust_data
) = VT_EMPTY
;
1958 hres
= ITypeInfo2_GetCustData(ti2
, &custguid
, &cust_data
);
1959 ok(hres
== S_OK
, "got %08x\n", hres
);
1961 ok(V_VT(&cust_data
) == VT_UI4
, "got %d\n", V_VT(&cust_data
));
1962 ok(V_I4(&cust_data
) == 0xdeadbeef, "got 0x%08x\n", V_I4(&cust_data
));
1964 V_VT(&cust_data
) = VT_UI4
;
1965 V_I4(&cust_data
) = 12345678;
1967 hres
= ICreateTypeInfo2_SetCustData(createti2
, &custguid
, &cust_data
);
1968 ok(hres
== S_OK
, "got %08x\n", hres
);
1970 V_I4(&cust_data
) = 0;
1971 V_VT(&cust_data
) = VT_EMPTY
;
1973 hres
= ITypeInfo2_GetCustData(ti2
, &custguid
, &cust_data
);
1974 ok(hres
== S_OK
, "got %08x\n", hres
);
1976 ok(V_VT(&cust_data
) == VT_UI4
, "got %d\n", V_VT(&cust_data
));
1977 ok(V_I4(&cust_data
) == 12345678, "got 0x%08x\n", V_I4(&cust_data
));
1979 V_VT(&cust_data
) = VT_BSTR
;
1980 V_BSTR(&cust_data
) = SysAllocString(asdfW
);
1982 hres
= ICreateTypeInfo2_SetCustData(createti2
, &custguid
, &cust_data
);
1983 ok(hres
== S_OK
, "got %08x\n", hres
);
1985 SysFreeString(V_BSTR(&cust_data
));
1986 V_I4(&cust_data
) = 0;
1987 V_VT(&cust_data
) = VT_EMPTY
;
1989 hres
= ITypeInfo2_GetCustData(ti2
, &custguid
, &cust_data
);
1990 ok(hres
== S_OK
, "got %08x\n", hres
);
1992 ok(V_VT(&cust_data
) == VT_BSTR
, "got %d\n", V_VT(&cust_data
));
1993 ok(!lstrcmpW(V_BSTR(&cust_data
), asdfW
), "got %s\n", wine_dbgstr_w(V_BSTR(&cust_data
)));
1994 SysFreeString(V_BSTR(&cust_data
));
1996 V_VT(&cust_data
) = VT_UI4
;
1997 V_UI4(&cust_data
) = 17;
1999 hres
= ITypeInfo2_GetCustData(ti2
, &bogusguid
, &cust_data
);
2000 ok(hres
== S_OK
, "got %08x\n", hres
);
2002 ok(V_VT(&cust_data
) == VT_EMPTY
, "got: %d\n", V_VT(&cust_data
));
2004 ITypeInfo2_Release(ti2
);
2005 ICreateTypeInfo2_Release(createti2
);
2006 ICreateTypeInfo_Release(createti
);
2008 hres
= ICreateTypeLib_CreateTypeInfo(createtl
, coclassW
, TKIND_COCLASS
, &createti
);
2009 ok(hres
== S_OK
, "got %08x\n", hres
);
2011 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, interface1
, &hreftype
);
2012 ok(hres
== S_OK
, "got %08x\n", hres
);
2014 hres
= ICreateTypeInfo_AddImplType(createti
, 0, hreftype
);
2015 ok(hres
== S_OK
, "got %08x\n", hres
);
2017 hres
= ICreateTypeInfo_AddImplType(createti
, 0, hreftype
);
2018 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
2020 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, unknown
, &hreftype
);
2021 ok(hres
== S_OK
, "got %08x\n", hres
);
2023 hres
= ICreateTypeInfo_AddImplType(createti
, 1, hreftype
);
2024 ok(hres
== S_OK
, "got %08x\n", hres
);
2026 hres
= ICreateTypeInfo_AddImplType(createti
, 1, hreftype
);
2027 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
2029 hres
= ICreateTypeInfo_AddImplType(createti
, 2, hreftype
);
2030 ok(hres
== S_OK
, "got %08x\n", hres
);
2032 hres
= ICreateTypeInfo_SetImplTypeFlags(createti
, 0, IMPLTYPEFLAG_FDEFAULT
);
2033 ok(hres
== S_OK
, "got %08x\n", hres
);
2035 hres
= ICreateTypeInfo_SetImplTypeFlags(createti
, 1, IMPLTYPEFLAG_FRESTRICTED
);
2036 ok(hres
== S_OK
, "got %08x\n", hres
);
2038 hres
= ICreateTypeInfo_QueryInterface(createti
, &IID_ITypeInfo
, (void**)&ti
);
2039 ok(hres
== S_OK
, "got %08x\n", hres
);
2041 hres
= ITypeInfo_GetImplTypeFlags(ti
, 0, NULL
);
2042 ok(hres
== E_INVALIDARG
, "got %08x\n", hres
);
2044 hres
= ITypeInfo_GetImplTypeFlags(ti
, 0, &impltypeflags
);
2045 ok(hres
== S_OK
, "got %08x\n", hres
);
2046 ok(impltypeflags
== IMPLTYPEFLAG_FDEFAULT
, "impltypeflags = %x\n", impltypeflags
);
2048 hres
= ITypeInfo_GetImplTypeFlags(ti
, 1, &impltypeflags
);
2049 ok(hres
== S_OK
, "got %08x\n", hres
);
2050 ok(impltypeflags
== IMPLTYPEFLAG_FRESTRICTED
, "impltypeflags = %x\n", impltypeflags
);
2052 hres
= ITypeInfo_GetImplTypeFlags(ti
, 2, &impltypeflags
);
2053 ok(hres
== S_OK
, "got %08x\n", hres
);
2054 ok(impltypeflags
== 0, "impltypeflags = %x\n", impltypeflags
);
2056 hres
= ITypeInfo_GetRefTypeOfImplType(ti
, 0, &hreftype
);
2057 ok(hres
== S_OK
, "got %08x\n", hres
);
2058 ok(hreftype
== 0, "hreftype = %d\n", hreftype
);
2060 hres
= ITypeInfo_GetRefTypeOfImplType(ti
, 1, &hreftype
);
2061 ok(hres
== S_OK
, "got %08x\n", hres
);
2062 ok(hreftype
== 1, "hreftype = %d\n", hreftype
);
2064 hres
= ITypeInfo_GetRefTypeOfImplType(ti
, 2, &hreftype
);
2065 ok(hres
== S_OK
, "got %08x\n", hres
);
2066 ok(hreftype
== 1, "hreftype = %d\n", hreftype
);
2068 hres
= ITypeInfo_GetRefTypeOfImplType(ti
, -1, &hreftype
);
2069 ok(hres
== TYPE_E_ELEMENTNOTFOUND
, "got %08x\n", hres
);
2071 ITypeInfo_Release(ti
);
2073 ICreateTypeInfo_Release(createti
);
2075 hres
= ICreateTypeLib_CreateTypeInfo(createtl
, dualW
, TKIND_INTERFACE
, &createti
);
2076 ok(hres
== S_OK
, "got %08x\n", hres
);
2078 hres
= ICreateTypeInfo_SetTypeFlags(createti
, TYPEFLAG_FDUAL
);
2079 ok(hres
== S_OK
, "got %08x\n", hres
);
2081 hres
= ICreateTypeInfo_AddFuncDesc(createti
, 0, &funcdesc
);
2082 ok(hres
== S_OK
, "got %08x\n", hres
);
2084 hres
= ICreateTypeInfo_AddRefTypeInfo(createti
, dispatch
, &hreftype
);
2085 ok(hres
== S_OK
, "got %08x\n", hres
);
2087 hres
= ICreateTypeInfo_AddImplType(createti
, 0, hreftype
);
2088 ok(hres
== S_OK
, "got %08x\n", hres
);
2090 hres
= ICreateTypeInfo_QueryInterface(createti
, &IID_ITypeInfo
, (void**)&dual
);
2091 ok(hres
== S_OK
, "got %08x\n", hres
);
2093 hres
= ITypeInfo_GetTypeAttr(dual
, &typeattr
);
2094 ok(hres
== S_OK
, "got %08x\n", hres
);
2095 ok(typeattr
->cbSizeInstance
== 4, "cbSizeInstance = %d\n", typeattr
->cbSizeInstance
);
2096 ok(typeattr
->typekind
== 3, "typekind = %d\n", typeattr
->typekind
);
2097 ok(typeattr
->cFuncs
== 1, "cFuncs = %d\n", typeattr
->cFuncs
);
2098 ok(typeattr
->cVars
== 0, "cVars = %d\n", typeattr
->cVars
);
2099 ok(typeattr
->cImplTypes
== 1, "cImplTypes = %d\n", typeattr
->cImplTypes
);
2100 ok(typeattr
->cbSizeVft
== 32 || broken(typeattr
->cbSizeVft
== 7 * sizeof(void *) + 4), /* xp64 */
2101 "cbSizeVft = %d\n", typeattr
->cbSizeVft
);
2102 ok(typeattr
->cbAlignment
== 4, "cbAlignment = %d\n", typeattr
->cbAlignment
);
2103 ok(typeattr
->wTypeFlags
== (TYPEFLAG_FDISPATCHABLE
|TYPEFLAG_FDUAL
), "wTypeFlags = %d\n", typeattr
->wTypeFlags
);
2104 ok(typeattr
->wMajorVerNum
== 0, "wMajorVerNum = %d\n", typeattr
->wMajorVerNum
);
2105 ok(typeattr
->wMinorVerNum
== 0, "wMinorVerNum = %d\n", typeattr
->wMinorVerNum
);
2107 ITypeInfo_ReleaseTypeAttr(dual
, typeattr
);
2109 hres
= ITypeInfo_GetRefTypeOfImplType(dual
, -1, &hreftype
);
2110 ok(hres
== S_OK
, "got %08x\n", hres
);
2111 ok(hreftype
== -2, "got %08x\n", hreftype
);
2113 hres
= ITypeInfo_GetRefTypeInfo(dual
, -2, &ti
);
2114 ok(hres
== S_OK
, "got %08x\n", hres
);
2116 hres
= ITypeInfo_GetTypeAttr(ti
, &typeattr
);
2117 ok(hres
== S_OK
, "got %08x\n", hres
);
2118 ok(typeattr
->cbSizeInstance
== 4, "cbSizeInstance = %d\n", typeattr
->cbSizeInstance
);
2119 ok(typeattr
->typekind
== 4, "typekind = %d\n", typeattr
->typekind
);
2120 ok(typeattr
->cFuncs
== 8, "cFuncs = %d\n", typeattr
->cFuncs
);
2121 ok(typeattr
->cVars
== 0, "cVars = %d\n", typeattr
->cVars
);
2122 ok(typeattr
->cImplTypes
== 1, "cImplTypes = %d\n", typeattr
->cImplTypes
);
2123 ok(typeattr
->cbSizeVft
== 7 * sizeof(void *), "cbSizeVft = %d\n", typeattr
->cbSizeVft
);
2124 ok(typeattr
->cbAlignment
== 4, "cbAlignment = %d\n", typeattr
->cbAlignment
);
2125 ok(typeattr
->wTypeFlags
== (TYPEFLAG_FDISPATCHABLE
|TYPEFLAG_FDUAL
), "wTypeFlags = %d\n", typeattr
->wTypeFlags
);
2126 ok(typeattr
->wMajorVerNum
== 0, "wMajorVerNum = %d\n", typeattr
->wMajorVerNum
);
2127 ok(typeattr
->wMinorVerNum
== 0, "wMinorVerNum = %d\n", typeattr
->wMinorVerNum
);
2129 ITypeInfo_ReleaseTypeAttr(ti
, typeattr
);
2131 ITypeInfo_Release(ti
);
2133 ICreateTypeInfo_Release(createti
);
2135 hres
= ITypeInfo_GetTypeAttr(interface1
, &typeattr
);
2136 ok(hres
== S_OK
, "got %08x\n", hres
);
2137 ok(typeattr
->cbSizeInstance
== 4, "cbSizeInstance = %d\n", typeattr
->cbSizeInstance
);
2138 ok(typeattr
->typekind
== 3, "typekind = %d\n", typeattr
->typekind
);
2139 ok(typeattr
->cFuncs
== 12, "cFuncs = %d\n", typeattr
->cFuncs
);
2140 ok(typeattr
->cVars
== 0, "cVars = %d\n", typeattr
->cVars
);
2141 ok(typeattr
->cImplTypes
== 1, "cImplTypes = %d\n", typeattr
->cImplTypes
);
2142 ok(typeattr
->cbSizeVft
== 60 || broken(typeattr
->cbSizeVft
== 3 * sizeof(void *) + 48), /* xp64 */
2143 "cbSizeVft = %d\n", typeattr
->cbSizeVft
);
2144 ok(typeattr
->cbAlignment
== 4, "cbAlignment = %d\n", typeattr
->cbAlignment
);
2145 ok(typeattr
->wTypeFlags
== 0, "wTypeFlags = %d\n", typeattr
->wTypeFlags
);
2146 ok(typeattr
->wMajorVerNum
== 0, "wMajorVerNum = %d\n", typeattr
->wMajorVerNum
);
2147 ok(typeattr
->wMinorVerNum
== 0, "wMinorVerNum = %d\n", typeattr
->wMinorVerNum
);
2149 ITypeInfo_ReleaseTypeAttr(interface1
, typeattr
);
2151 hres
= ITypeInfo_GetTypeAttr(interface2
, &typeattr
);
2152 ok(hres
== S_OK
, "got %08x\n", hres
);
2153 ok(typeattr
->cbSizeInstance
== 4, "cbSizeInstance = %d\n", typeattr
->cbSizeInstance
);
2154 ok(typeattr
->typekind
== 3, "typekind = %d\n", typeattr
->typekind
);
2155 ok(typeattr
->cFuncs
== 2, "cFuncs = %d\n", typeattr
->cFuncs
);
2156 ok(typeattr
->cVars
== 0, "cVars = %d\n", typeattr
->cVars
);
2157 ok(typeattr
->cImplTypes
== 1, "cImplTypes = %d\n", typeattr
->cImplTypes
);
2158 ok(typeattr
->cbSizeVft
== 43696, "cbSizeVft = %d\n", typeattr
->cbSizeVft
);
2159 ok(typeattr
->cbAlignment
== 4, "cbAlignment = %d\n", typeattr
->cbAlignment
);
2160 ok(typeattr
->wTypeFlags
== 0, "wTypeFlags = %d\n", typeattr
->wTypeFlags
);
2161 ok(typeattr
->wMajorVerNum
== 0, "wMajorVerNum = %d\n", typeattr
->wMajorVerNum
);
2162 ok(typeattr
->wMinorVerNum
== 0, "wMinorVerNum = %d\n", typeattr
->wMinorVerNum
);
2164 ITypeInfo_ReleaseTypeAttr(interface2
, typeattr
);
2166 hres
= ICreateTypeLib2_SaveAllChanges(createtl
);
2167 ok(hres
== S_OK
, "got %08x\n", hres
);
2169 ok(ITypeInfo_Release(interface2
)==0, "Object should be freed\n");
2170 ok(ITypeInfo_Release(interface1
)==0, "Object should be freed\n");
2171 ok(ITypeInfo_Release(dual
)==0, "Object should be freed\n");
2172 ok(ICreateTypeLib2_Release(createtl
)==0, "Object should be freed\n");
2174 ok(ITypeInfo_Release(dispatch
)==0, "Object should be freed\n");
2175 ok(ITypeInfo_Release(unknown
)==0, "Object should be freed\n");
2176 ok(ITypeLib_Release(stdole
)==0, "Object should be freed\n");
2178 hres
= LoadTypeLibEx(filenameW
, REGKIND_NONE
, &tl
);
2179 ok(hres
== S_OK
, "got %08x\n", hres
);
2180 ok(ITypeLib_Release(tl
)==0, "Object should be freed\n");
2182 DeleteFileA(filename
);
2185 #if 0 /* use this to generate more tests */
2187 #define OLE_CHECK(x) { HRESULT hr = x; if (FAILED(hr)) { printf(#x "failed - %x\n", hr); return; } }
2189 static char *dump_string(LPWSTR wstr
)
2191 int size
= lstrlenW(wstr
)+3;
2192 char *out
= CoTaskMemAlloc(size
);
2193 WideCharToMultiByte(20127, 0, wstr
, -1, out
+1, size
, NULL
, NULL
);
2205 #define MAP_ENTRY(x) { x, #x }
2206 static const struct map_entry tkind_map
[] = {
2207 MAP_ENTRY(TKIND_ENUM
),
2208 MAP_ENTRY(TKIND_RECORD
),
2209 MAP_ENTRY(TKIND_MODULE
),
2210 MAP_ENTRY(TKIND_INTERFACE
),
2211 MAP_ENTRY(TKIND_DISPATCH
),
2212 MAP_ENTRY(TKIND_COCLASS
),
2213 MAP_ENTRY(TKIND_ALIAS
),
2214 MAP_ENTRY(TKIND_UNION
),
2215 MAP_ENTRY(TKIND_MAX
),
2219 static const struct map_entry funckind_map
[] = {
2220 MAP_ENTRY(FUNC_VIRTUAL
),
2221 MAP_ENTRY(FUNC_PUREVIRTUAL
),
2222 MAP_ENTRY(FUNC_NONVIRTUAL
),
2223 MAP_ENTRY(FUNC_STATIC
),
2224 MAP_ENTRY(FUNC_DISPATCH
),
2228 static const struct map_entry invkind_map
[] = {
2229 MAP_ENTRY(INVOKE_FUNC
),
2230 MAP_ENTRY(INVOKE_PROPERTYGET
),
2231 MAP_ENTRY(INVOKE_PROPERTYPUT
),
2232 MAP_ENTRY(INVOKE_PROPERTYPUTREF
),
2238 static const char *map_value(DWORD val
, const struct map_entry
*map
)
2241 static char bufs
[16][256];
2246 if (map
->value
== val
)
2251 buf
= bufs
[(map_id
++)%16];
2252 sprintf(buf
, "0x%x", val
);
2256 static void test_dump_typelib(const char *name
)
2258 WCHAR wszString
[260];
2264 MultiByteToWideChar(CP_ACP
, 0, name
, -1, wszString
, 260);
2265 OLE_CHECK(LoadTypeLib(wszString
, &lib
));
2266 count
= ITypeLib_GetTypeInfoCount(lib
);
2267 printf("/* interfaces count: %d */\n", count
);
2268 for (i
= 0; i
< count
; i
++)
2274 OLE_CHECK(ITypeLib_GetDocumentation(lib
, i
, &name
, NULL
, NULL
, NULL
));
2276 " %s,\n", dump_string(name
));
2277 SysFreeString(name
);
2279 OLE_CHECK(ITypeLib_GetTypeInfo(lib
, i
, &info
));
2280 ITypeInfo_GetTypeAttr(info
, &attr
);
2281 printf(" /*kind*/ %s, /*flags*/ 0x%x, /*align*/ %d, /*size*/ %d,\n"
2282 " /*#vtbl*/ %d, /*#func*/ %d,\n"
2284 map_value(attr
->typekind
, tkind_map
), attr
->wTypeFlags
, attr
->cbAlignment
, attr
->cbSizeInstance
, attr
->cbSizeVft
,
2286 ITypeInfo_ReleaseTypeAttr(info
, attr
);
2294 if (FAILED(ITypeInfo_GetFuncDesc(info
, f
, &desc
)))
2297 " 0x%x, /*func*/ %s, /*inv*/ %s, /*call*/ 0x%x,\n",
2298 desc
->memid
, map_value(desc
->funckind
, funckind_map
), map_value(desc
->invkind
, invkind_map
),
2300 printf(" /*#param*/ %d, /*#opt*/ %d, /*vtbl*/ %d, /*#scodes*/ %d, /*flags*/ 0x%x,\n",
2301 desc
->cParams
, desc
->cParamsOpt
, desc
->oVft
, desc
->cScodes
, desc
->wFuncFlags
);
2302 printf(" {%d, %x}, /* ret */\n", desc
->elemdescFunc
.tdesc
.vt
, desc
->elemdescFunc
.paramdesc
.wParamFlags
);
2303 printf(" { /* params */\n");
2304 for (p
= 0; p
< desc
->cParams
; p
++)
2306 ELEMDESC e
= desc
->lprgelemdescParam
[p
];
2307 printf(" {%d, %x},\n", e
.tdesc
.vt
, e
.paramdesc
.wParamFlags
);
2309 printf(" {-1, -1}\n");
2311 printf(" { /* names */\n");
2312 OLE_CHECK(ITypeInfo_GetNames(info
, desc
->memid
, tab
, 256, &cNames
));
2313 for (p
= 0; p
< cNames
; p
++)
2315 printf(" %s,\n", dump_string(tab
[p
]));
2316 SysFreeString(tab
[p
]);
2321 ITypeInfo_ReleaseFuncDesc(info
, desc
);
2326 ITypeInfo_Release(info
);
2328 ITypeLib_Release(lib
);
2333 typedef struct _element_info
2339 typedef struct _function_info
2350 element_info ret_type
;
2351 element_info params
[15];
2355 typedef struct _interface_info
2361 USHORT cbSizeInstance
;
2364 function_info funcs
[20];
2367 static const interface_info info
[] = {
2368 /* interfaces count: 2 */
2371 /*kind*/ TKIND_DISPATCH
, /*flags*/ 0x1040, /*align*/ 4, /*size*/ 4,
2372 /*#vtbl*/ 7, /*#func*/ 8,
2375 0x60000000, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
2376 /*#param*/ 2, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0x1,
2391 0x60000001, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
2392 /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 1, /*#scodes*/ 0, /*flags*/ 0x1,
2403 0x60000002, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
2404 /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 2, /*#scodes*/ 0, /*flags*/ 0x1,
2415 0x60010000, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
2416 /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 3, /*#scodes*/ 0, /*flags*/ 0x1,
2429 0x60010001, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
2430 /*#param*/ 3, /*#opt*/ 0, /*vtbl*/ 4, /*#scodes*/ 0, /*flags*/ 0x1,
2447 0x60010002, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
2448 /*#param*/ 5, /*#opt*/ 0, /*vtbl*/ 5, /*#scodes*/ 0, /*flags*/ 0x1,
2469 0x60010003, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
2470 /*#param*/ 8, /*#opt*/ 0, /*vtbl*/ 6, /*#scodes*/ 0, /*flags*/ 0x1,
2497 0x60020000, /*func*/ FUNC_DISPATCH
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
2498 /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0x0,
2512 /*kind*/ TKIND_INTERFACE
, /*flags*/ 0x1000, /*align*/ 4, /*size*/ 4,
2513 /*#vtbl*/ 8, /*#func*/ 1,
2516 0x60020000, /*func*/ FUNC_PUREVIRTUAL
, /*inv*/ INVOKE_FUNC
, /*call*/ 0x4,
2517 /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0x0,
2531 #define check_type(elem, info) { \
2532 expect_int((elem)->tdesc.vt, (info)->vt); \
2533 expect_hex(U(*(elem)).paramdesc.wParamFlags, (info)->wParamFlags); \
2536 static void test_dump_typelib(const char *name
)
2538 WCHAR wszName
[MAX_PATH
];
2540 int ifcount
= sizeof(info
)/sizeof(info
[0]);
2543 MultiByteToWideChar(CP_ACP
, 0, name
, -1, wszName
, MAX_PATH
);
2544 ole_check(LoadTypeLibEx(wszName
, REGKIND_NONE
, &typelib
));
2545 expect_eq(ITypeLib_GetTypeInfoCount(typelib
), ifcount
, UINT
, "%d");
2546 for (iface
= 0; iface
< ifcount
; iface
++)
2548 const interface_info
*if_info
= &info
[iface
];
2549 ITypeInfo
*typeinfo
;
2553 trace("Interface %s\n", if_info
->name
);
2554 ole_check(ITypeLib_GetTypeInfo(typelib
, iface
, &typeinfo
));
2555 ole_check(ITypeLib_GetDocumentation(typelib
, iface
, &bstrIfName
, NULL
, NULL
, NULL
));
2556 expect_wstr_acpval(bstrIfName
, if_info
->name
);
2557 SysFreeString(bstrIfName
);
2559 ole_check(ITypeInfo_GetTypeAttr(typeinfo
, &typeattr
));
2560 expect_int(typeattr
->typekind
, if_info
->type
);
2561 expect_hex(typeattr
->wTypeFlags
, if_info
->wTypeFlags
);
2562 expect_int(typeattr
->cbAlignment
, if_info
->cbAlignment
);
2563 expect_int(typeattr
->cbSizeInstance
, if_info
->cbSizeInstance
);
2564 expect_int(typeattr
->cbSizeVft
, if_info
->cbSizeVft
* sizeof(void*));
2565 expect_int(typeattr
->cFuncs
, if_info
->cFuncs
);
2567 for (func
= 0; func
< typeattr
->cFuncs
; func
++)
2569 function_info
*fn_info
= (function_info
*)&if_info
->funcs
[func
];
2575 trace("Function %s\n", fn_info
->names
[0]);
2576 ole_check(ITypeInfo_GetFuncDesc(typeinfo
, func
, &desc
));
2577 expect_int(desc
->memid
, fn_info
->memid
);
2578 expect_int(desc
->funckind
, fn_info
->funckind
);
2579 expect_int(desc
->invkind
, fn_info
->invkind
);
2580 expect_int(desc
->callconv
, fn_info
->callconv
);
2581 expect_int(desc
->cParams
, fn_info
->cParams
);
2582 expect_int(desc
->cParamsOpt
, fn_info
->cParamsOpt
);
2583 ok( desc
->oVft
== fn_info
->vtbl_index
* sizeof(void*) ||
2584 broken(desc
->oVft
== fn_info
->vtbl_index
* 4), /* xp64 */
2585 "desc->oVft got %u\n", desc
->oVft
);
2586 expect_int(desc
->cScodes
, fn_info
->cScodes
);
2587 expect_int(desc
->wFuncFlags
, fn_info
->wFuncFlags
);
2588 ole_check(ITypeInfo_GetNames(typeinfo
, desc
->memid
, namesTab
, 256, &cNames
));
2589 for (i
= 0; i
< cNames
; i
++)
2591 expect_wstr_acpval(namesTab
[i
], fn_info
->names
[i
]);
2592 SysFreeString(namesTab
[i
]);
2594 expect_null(fn_info
->names
[cNames
]);
2596 check_type(&desc
->elemdescFunc
, &fn_info
->ret_type
);
2597 for (i
= 0 ; i
< desc
->cParams
; i
++)
2599 check_type(&desc
->lprgelemdescParam
[i
], &fn_info
->params
[i
]);
2601 expect_int(fn_info
->params
[desc
->cParams
].vt
, (VARTYPE
)-1);
2603 ITypeInfo_ReleaseFuncDesc(typeinfo
, desc
);
2606 ITypeInfo_ReleaseTypeAttr(typeinfo
, typeattr
);
2607 ITypeInfo_Release(typeinfo
);
2609 ITypeLib_Release(typelib
);
2614 static const char *create_test_typelib(int res_no
)
2616 static char filename
[MAX_PATH
];
2622 GetTempFileNameA( ".", "tlb", 0, filename
);
2623 file
= CreateFile( filename
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2624 ok( file
!= INVALID_HANDLE_VALUE
, "file creation failed\n" );
2625 if (file
== INVALID_HANDLE_VALUE
) return NULL
;
2626 res
= FindResource( GetModuleHandle(0), MAKEINTRESOURCE(res_no
), "TYPELIB" );
2627 ok( res
!= 0, "couldn't find resource\n" );
2628 ptr
= LockResource( LoadResource( GetModuleHandle(0), res
));
2629 WriteFile( file
, ptr
, SizeofResource( GetModuleHandle(0), res
), &written
, NULL
);
2630 ok( written
== SizeofResource( GetModuleHandle(0), res
), "couldn't write resource\n" );
2631 CloseHandle( file
);
2635 static void test_create_typelib_lcid(LCID lcid
)
2637 char filename
[MAX_PATH
];
2638 WCHAR name
[MAX_PATH
];
2640 ICreateTypeLib2
*tl
;
2642 DWORD msft_header
[5]; /* five is enough for now */
2645 GetTempFileNameA( ".", "tlb", 0, filename
);
2646 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, name
, MAX_PATH
);
2648 hr
= CreateTypeLib2(SYS_WIN32
, name
, &tl
);
2649 ok(hr
== S_OK
, "got %08x\n", hr
);
2651 hr
= ICreateTypeLib2_SetLcid(tl
, lcid
);
2652 ok(hr
== S_OK
, "got %08x\n", hr
);
2654 hr
= ICreateTypeLib2_SaveAllChanges(tl
);
2655 ICreateTypeLib2_Release(tl
);
2657 file
= CreateFileA( filename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0 );
2658 ok( file
!= INVALID_HANDLE_VALUE
, "file creation failed\n" );
2660 ReadFile( file
, msft_header
, sizeof(msft_header
), &read
, NULL
);
2661 ok(read
== sizeof(msft_header
), "read %d\n", read
);
2662 CloseHandle( file
);
2664 ok(msft_header
[0] == 0x5446534d, "got %08x\n", msft_header
[0]);
2665 ok(msft_header
[1] == 0x00010002, "got %08x\n", msft_header
[1]);
2666 ok(msft_header
[2] == 0xffffffff, "got %08x\n", msft_header
[2]);
2667 ok(msft_header
[3] == (lcid
? lcid
: 0x409), "got %08x (lcid %08x)\n", msft_header
[3], lcid
);
2668 ok(msft_header
[4] == lcid
, "got %08x (lcid %08x)\n", msft_header
[4], lcid
);
2670 DeleteFileA(filename
);
2673 static void test_create_typelibs(void)
2675 test_create_typelib_lcid(LOCALE_SYSTEM_DEFAULT
);
2676 test_create_typelib_lcid(LOCALE_USER_DEFAULT
);
2677 test_create_typelib_lcid(LOCALE_NEUTRAL
);
2679 test_create_typelib_lcid(0x009);
2680 test_create_typelib_lcid(0x409);
2681 test_create_typelib_lcid(0x809);
2683 test_create_typelib_lcid(0x007);
2684 test_create_typelib_lcid(0x407);
2688 static void test_register_typelib(BOOL system_registration
)
2691 WCHAR filename
[MAX_PATH
];
2692 const char *filenameA
;
2695 char key_name
[MAX_PATH
], uuid
[40];
2696 LONG ret
, expect_ret
;
2705 { TKIND_INTERFACE
, 0 },
2706 { TKIND_INTERFACE
, TYPEFLAG_FDISPATCHABLE
},
2707 { TKIND_INTERFACE
, TYPEFLAG_FOLEAUTOMATION
},
2708 { TKIND_INTERFACE
, TYPEFLAG_FDISPATCHABLE
| TYPEFLAG_FOLEAUTOMATION
},
2709 { TKIND_DISPATCH
, 0 /* TYPEFLAG_FDUAL - widl clears this flag for non-IDispatch derived interfaces */ },
2710 { TKIND_DISPATCH
, 0 /* TYPEFLAG_FDUAL - widl clears this flag for non-IDispatch derived interfaces */ },
2711 { TKIND_DISPATCH
, TYPEFLAG_FDISPATCHABLE
| TYPEFLAG_FDUAL
},
2712 { TKIND_DISPATCH
, TYPEFLAG_FDISPATCHABLE
| TYPEFLAG_FDUAL
},
2713 { TKIND_DISPATCH
, TYPEFLAG_FDISPATCHABLE
},
2714 { TKIND_DISPATCH
, TYPEFLAG_FDISPATCHABLE
},
2715 { TKIND_DISPATCH
, TYPEFLAG_FDISPATCHABLE
}
2718 trace("Starting %s typelib registration tests\n",
2719 system_registration
? "system" : "user");
2721 if (!system_registration
&& (!pRegisterTypeLibForUser
|| !pUnRegisterTypeLibForUser
))
2723 win_skip("User typelib registration functions are not available\n");
2727 filenameA
= create_test_typelib(3);
2728 MultiByteToWideChar(CP_ACP
, 0, filenameA
, -1, filename
, MAX_PATH
);
2730 hr
= LoadTypeLibEx(filename
, REGKIND_NONE
, &typelib
);
2731 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2733 if (system_registration
)
2734 hr
= RegisterTypeLib(typelib
, filename
, NULL
);
2736 hr
= pRegisterTypeLibForUser(typelib
, filename
, NULL
);
2737 if (hr
== TYPE_E_REGISTRYACCESS
)
2739 win_skip("Insufficient privileges to register typelib in the registry\n");
2740 ITypeLib_Release(typelib
);
2741 DeleteFileA(filenameA
);
2744 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2746 count
= ITypeLib_GetTypeInfoCount(typelib
);
2747 ok(count
== 11, "got %d\n", count
);
2749 for(i
= 0; i
< count
; i
++)
2751 ITypeInfo
*typeinfo
;
2754 hr
= ITypeLib_GetTypeInfo(typelib
, i
, &typeinfo
);
2755 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2757 hr
= ITypeInfo_GetTypeAttr(typeinfo
, &attr
);
2758 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2760 ok(attr
->typekind
== attrs
[i
].kind
, "%d: got kind %d\n", i
, attr
->typekind
);
2761 ok(attr
->wTypeFlags
== attrs
[i
].flags
, "%d: got flags %04x\n", i
, attr
->wTypeFlags
);
2763 if(attr
->typekind
== TKIND_DISPATCH
&& (attr
->wTypeFlags
& TYPEFLAG_FDUAL
))
2766 ITypeInfo
*dual_info
;
2767 TYPEATTR
*dual_attr
;
2769 hr
= ITypeInfo_GetRefTypeOfImplType(typeinfo
, -1, &reftype
);
2770 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2772 hr
= ITypeInfo_GetRefTypeInfo(typeinfo
, reftype
, &dual_info
);
2773 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2775 hr
= ITypeInfo_GetTypeAttr(dual_info
, &dual_attr
);
2776 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2778 ok(dual_attr
->typekind
== TKIND_INTERFACE
, "%d: got kind %d\n", i
, dual_attr
->typekind
);
2779 ok(dual_attr
->wTypeFlags
== (TYPEFLAG_FDISPATCHABLE
| TYPEFLAG_FOLEAUTOMATION
| TYPEFLAG_FDUAL
), "%d: got flags %04x\n", i
, dual_attr
->wTypeFlags
);
2781 ITypeInfo_ReleaseTypeAttr(dual_info
, dual_attr
);
2782 ITypeInfo_Release(dual_info
);
2786 StringFromGUID2(&attr
->guid
, uuidW
, sizeof(uuidW
) / sizeof(uuidW
[0]));
2787 WideCharToMultiByte(CP_ACP
, 0, uuidW
, -1, uuid
, sizeof(uuid
), NULL
, NULL
);
2788 sprintf(key_name
, "Interface\\%s", uuid
);
2790 /* All dispinterfaces will be registered (this includes dual interfaces) as well
2791 as oleautomation interfaces */
2792 if((attr
->typekind
== TKIND_INTERFACE
&& (attr
->wTypeFlags
& TYPEFLAG_FOLEAUTOMATION
)) ||
2793 attr
->typekind
== TKIND_DISPATCH
)
2794 expect_ret
= ERROR_SUCCESS
;
2796 expect_ret
= ERROR_FILE_NOT_FOUND
;
2798 ret
= RegOpenKeyExA(HKEY_CLASSES_ROOT
, key_name
, 0, KEY_READ
, &hkey
);
2799 ok(ret
== expect_ret
, "%d: got %d\n", i
, ret
);
2800 if(ret
== ERROR_SUCCESS
) RegCloseKey(hkey
);
2802 ITypeInfo_ReleaseTypeAttr(typeinfo
, attr
);
2803 ITypeInfo_Release(typeinfo
);
2806 if (system_registration
)
2807 hr
= UnRegisterTypeLib(&LIBID_register_test
, 1, 0, LOCALE_NEUTRAL
, is_win64
? SYS_WIN64
: SYS_WIN32
);
2809 hr
= pUnRegisterTypeLibForUser(&LIBID_register_test
, 1, 0, LOCALE_NEUTRAL
, is_win64
? SYS_WIN64
: SYS_WIN32
);
2810 ok(SUCCEEDED(hr
), "got %08x\n", hr
);
2812 ITypeLib_Release(typelib
);
2813 DeleteFileA( filenameA
);
2818 const char *filename
;
2820 init_function_pointers();
2822 ref_count_test(wszStdOle2
);
2824 test_CreateDispTypeInfo();
2826 test_DispCallFunc();
2827 test_QueryPathOfRegTypeLib(32);
2828 if(sizeof(void*) == 8)
2829 test_QueryPathOfRegTypeLib(64);
2831 test_CreateTypeLib();
2833 if ((filename
= create_test_typelib(2)))
2835 test_dump_typelib( filename
);
2836 DeleteFile( filename
);
2839 test_register_typelib(TRUE
);
2840 test_register_typelib(FALSE
);
2841 test_create_typelibs();