2 * Copyright (C) 2005-2006 Robert Shearman for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/test.h"
30 #include "tmarshal_dispids.h"
32 static HRESULT (WINAPI
*pVarAdd
)(LPVARIANT
,LPVARIANT
,LPVARIANT
);
35 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
38 static const int tmarshal_todo
= 0;
40 static const int tmarshal_todo
= 1;
43 /* ULL suffix is not portable */
44 #define ULL_CONST(dw1, dw2) ((((ULONGLONG)dw1) << 32) | (ULONGLONG)dw2)
46 const MYSTRUCT MYSTRUCT_BYVAL
= {0x12345678, ULL_CONST(0xdeadbeef, 0x98765432), {0,1,2,3,4,5,6,7}};
47 const MYSTRUCT MYSTRUCT_BYPTR
= {0x91827364, ULL_CONST(0x88776655, 0x44332211), {0,1,2,3,4,5,6,7}};
48 const MYSTRUCT MYSTRUCT_ARRAY
[5] = {
49 {0x1a1b1c1d, ULL_CONST(0x1e1f1011, 0x12131415), {0,1,2,3,4,5,6,7}},
50 {0x2a2b2c2d, ULL_CONST(0x2e2f2021, 0x22232425), {0,1,2,3,4,5,6,7}},
51 {0x3a3b3c3d, ULL_CONST(0x3e3f3031, 0x32333435), {0,1,2,3,4,5,6,7}},
52 {0x4a4b4c4d, ULL_CONST(0x4e4f4041, 0x42434445), {0,1,2,3,4,5,6,7}},
53 {0x5a5b5c5d, ULL_CONST(0x5e5f5051, 0x52535455), {0,1,2,3,4,5,6,7}},
57 #define RELEASEMARSHALDATA WM_USER
59 struct host_object_data
64 MSHLFLAGS marshal_flags
;
66 IMessageFilter
*filter
;
69 static DWORD CALLBACK
host_object_proc(LPVOID p
)
71 struct host_object_data
*data
= p
;
75 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
79 IMessageFilter
* prev_filter
= NULL
;
80 hr
= CoRegisterMessageFilter(data
->filter
, &prev_filter
);
81 if (prev_filter
) IMessageFilter_Release(prev_filter
);
82 ok_ole_success(hr
, CoRegisterMessageFilter
);
85 hr
= CoMarshalInterface(data
->stream
, &data
->iid
, data
->object
, MSHCTX_INPROC
, NULL
, data
->marshal_flags
);
86 ok_ole_success(hr
, CoMarshalInterface
);
88 /* force the message queue to be created before signaling parent thread */
89 PeekMessageA(&msg
, NULL
, WM_USER
, WM_USER
, PM_NOREMOVE
);
91 SetEvent(data
->marshal_event
);
93 while (GetMessageA(&msg
, NULL
, 0, 0))
95 if (msg
.hwnd
== NULL
&& msg
.message
== RELEASEMARSHALDATA
)
97 trace("releasing marshal data\n");
98 CoReleaseMarshalData(data
->stream
);
99 SetEvent((HANDLE
)msg
.lParam
);
102 DispatchMessageA(&msg
);
105 HeapFree(GetProcessHeap(), 0, data
);
112 static DWORD
start_host_object2(IStream
*stream
, REFIID riid
, IUnknown
*object
, MSHLFLAGS marshal_flags
, IMessageFilter
*filter
, HANDLE
*thread
)
115 HANDLE marshal_event
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
116 struct host_object_data
*data
= HeapAlloc(GetProcessHeap(), 0, sizeof(*data
));
118 data
->stream
= stream
;
120 data
->object
= object
;
121 data
->marshal_flags
= marshal_flags
;
122 data
->marshal_event
= marshal_event
;
123 data
->filter
= filter
;
125 *thread
= CreateThread(NULL
, 0, host_object_proc
, data
, 0, &tid
);
127 /* wait for marshaling to complete before returning */
128 WaitForSingleObject(marshal_event
, INFINITE
);
129 CloseHandle(marshal_event
);
134 static DWORD
start_host_object(IStream
*stream
, REFIID riid
, IUnknown
*object
, MSHLFLAGS marshal_flags
, HANDLE
*thread
)
136 return start_host_object2(stream
, riid
, object
, marshal_flags
, NULL
, thread
);
140 /* asks thread to release the marshal data because it has to be done by the
141 * same thread that marshaled the interface in the first place. */
142 static void release_host_object(DWORD tid
)
144 HANDLE event
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
145 PostThreadMessageA(tid
, RELEASEMARSHALDATA
, 0, (LPARAM
)event
);
146 WaitForSingleObject(event
, INFINITE
);
151 static void end_host_object(DWORD tid
, HANDLE thread
)
153 BOOL ret
= PostThreadMessageA(tid
, WM_QUIT
, 0, 0);
154 ok(ret
, "PostThreadMessage failed with error %d\n", GetLastError());
155 /* be careful of races - don't return until hosting thread has terminated */
156 WaitForSingleObject(thread
, INFINITE
);
160 static int external_connections
;
161 static BOOL expect_last_release_closes
;
163 static HRESULT WINAPI
ExternalConnection_QueryInterface(IExternalConnection
*iface
, REFIID riid
, void **ppv
)
165 ok(0, "unexpected call\n");
167 return E_NOINTERFACE
;
170 static ULONG WINAPI
ExternalConnection_AddRef(IExternalConnection
*iface
)
175 static ULONG WINAPI
ExternalConnection_Release(IExternalConnection
*iface
)
180 static DWORD WINAPI
ExternalConnection_AddConnection(IExternalConnection
*iface
, DWORD extconn
, DWORD reserved
)
182 trace("add connection\n");
184 ok(extconn
== EXTCONN_STRONG
, "extconn = %d\n", extconn
);
185 ok(!reserved
, "reserved = %x\n", reserved
);
186 return ++external_connections
;
189 static DWORD WINAPI
ExternalConnection_ReleaseConnection(IExternalConnection
*iface
, DWORD extconn
,
190 DWORD reserved
, BOOL fLastReleaseCloses
)
192 trace("release connection\n");
194 ok(extconn
== EXTCONN_STRONG
, "extconn = %d\n", extconn
);
195 ok(!reserved
, "reserved = %x\n", reserved
);
197 ok(fLastReleaseCloses
== expect_last_release_closes
, "fLastReleaseCloses = %x, expected %x\n",
198 fLastReleaseCloses
, expect_last_release_closes
);
199 return --external_connections
;
202 static const IExternalConnectionVtbl ExternalConnectionVtbl
= {
203 ExternalConnection_QueryInterface
,
204 ExternalConnection_AddRef
,
205 ExternalConnection_Release
,
206 ExternalConnection_AddConnection
,
207 ExternalConnection_ReleaseConnection
210 static IExternalConnection ExternalConnection
= { &ExternalConnectionVtbl
};
212 static ItestDual TestDual
, TestDualDisp
;
214 static HRESULT WINAPI
TestSecondIface_QueryInterface(ITestSecondIface
*iface
, REFIID riid
, void **ppv
)
216 return ItestDual_QueryInterface(&TestDual
, riid
, ppv
);
219 static ULONG WINAPI
TestSecondIface_AddRef(ITestSecondIface
*iface
)
224 static ULONG WINAPI
TestSecondIface_Release(ITestSecondIface
*iface
)
229 static HRESULT WINAPI
TestSecondIface_test(ITestSecondIface
*iface
)
234 static const ITestSecondIfaceVtbl TestSecondIfaceVtbl
= {
235 TestSecondIface_QueryInterface
,
236 TestSecondIface_AddRef
,
237 TestSecondIface_Release
,
241 static ITestSecondIface TestSecondIface
= { &TestSecondIfaceVtbl
};
243 static HRESULT WINAPI
TestSecondDisp_QueryInterface(ITestSecondDisp
*iface
, REFIID riid
, void **ppv
)
245 return ItestDual_QueryInterface(&TestDual
, riid
, ppv
);
248 static ULONG WINAPI
TestSecondDisp_AddRef(ITestSecondDisp
*iface
)
253 static ULONG WINAPI
TestSecondDisp_Release(ITestSecondDisp
*iface
)
258 static HRESULT WINAPI
TestSecondDisp_GetTypeInfoCount(ITestSecondDisp
*iface
, UINT
*pctinfo
)
260 ok(0, "unexpected call\n");
264 static HRESULT WINAPI
TestSecondDisp_GetTypeInfo(ITestSecondDisp
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
266 ok(0, "unexpected call\n");
270 static HRESULT WINAPI
TestSecondDisp_GetIDsOfNames(ITestSecondDisp
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
271 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
273 ok(0, "unexpected call\n");
277 static HRESULT WINAPI
TestSecondDisp_Invoke(ITestSecondDisp
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
278 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
,
281 ok(0, "unexpected call\n");
285 static HRESULT WINAPI
TestSecondDisp_test(ITestSecondDisp
*iface
)
287 ok(0, "unexpected call\n");
291 static ITestSecondDispVtbl TestSecondDispVtbl
= {
292 TestSecondDisp_QueryInterface
,
293 TestSecondDisp_AddRef
,
294 TestSecondDisp_Release
,
295 TestSecondDisp_GetTypeInfoCount
,
296 TestSecondDisp_GetTypeInfo
,
297 TestSecondDisp_GetIDsOfNames
,
298 TestSecondDisp_Invoke
,
302 static ITestSecondDisp TestSecondDisp
= { &TestSecondDispVtbl
};
304 static HRESULT WINAPI
TestDual_QueryInterface(ItestDual
*iface
, REFIID riid
, void **ppvObject
)
306 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDispatch
)) {
307 *ppvObject
= &TestDualDisp
;
309 }else if(IsEqualGUID(riid
, &IID_ItestDual
)) {
310 *ppvObject
= &TestDual
;
312 }else if(IsEqualGUID(riid
, &IID_ITestSecondIface
)) {
313 *ppvObject
= &TestSecondIface
;
315 }else if(IsEqualGUID(riid
, &IID_ITestSecondDisp
)) {
316 *ppvObject
= &TestSecondDisp
;
318 }else if (IsEqualGUID(riid
, &IID_IExternalConnection
)) {
319 trace("QI external connection\n");
320 *ppvObject
= &ExternalConnection
;
325 return E_NOINTERFACE
;
328 static ULONG WINAPI
TestDual_AddRef(ItestDual
*iface
)
333 static ULONG WINAPI
TestDual_Release(ItestDual
*iface
)
338 static HRESULT WINAPI
TestDual_GetTypeInfoCount(ItestDual
*iface
, UINT
*pctinfo
)
340 ok(0, "unexpected call\n");
344 static HRESULT WINAPI
TestDual_GetTypeInfo(ItestDual
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
346 ok(0, "unexpected call\n");
350 static HRESULT WINAPI
TestDual_GetIDsOfNames(ItestDual
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
351 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
353 ok(0, "unexpected call\n");
357 static HRESULT WINAPI
TestDual_Invoke(ItestDual
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
358 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
,
361 ok(0, "unexpected call\n");
365 static ItestDualVtbl TestDualVtbl
= {
366 TestDual_QueryInterface
,
369 TestDual_GetTypeInfoCount
,
370 TestDual_GetTypeInfo
,
371 TestDual_GetIDsOfNames
,
375 static ItestDual TestDual
= { &TestDualVtbl
};
376 static ItestDual TestDualDisp
= { &TestDualVtbl
};
378 typedef struct Widget
380 IWidget IWidget_iface
;
382 IUnknown
*pDispatchUnknown
;
385 static inline Widget
*impl_from_IWidget(IWidget
*iface
)
387 return CONTAINING_RECORD(iface
, Widget
, IWidget_iface
);
390 static HRESULT WINAPI
Widget_QueryInterface(
392 /* [in] */ REFIID riid
,
393 /* [iid_is][out] */ void __RPC_FAR
*__RPC_FAR
*ppvObject
)
395 if (IsEqualIID(riid
, &IID_IWidget
) || IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDispatch
))
397 IWidget_AddRef(iface
);
404 return E_NOINTERFACE
;
408 static ULONG WINAPI
Widget_AddRef(
411 Widget
*This
= impl_from_IWidget(iface
);
413 return InterlockedIncrement(&This
->refs
);
416 static ULONG WINAPI
Widget_Release(
419 Widget
*This
= impl_from_IWidget(iface
);
420 ULONG refs
= InterlockedDecrement(&This
->refs
);
423 IUnknown_Release(This
->pDispatchUnknown
);
424 memset(This
, 0xcc, sizeof(*This
));
425 HeapFree(GetProcessHeap(), 0, This
);
426 trace("Widget destroyed!\n");
432 static HRESULT WINAPI
Widget_GetTypeInfoCount(
434 /* [out] */ UINT __RPC_FAR
*pctinfo
)
436 Widget
*This
= impl_from_IWidget(iface
);
437 IDispatch
*pDispatch
;
438 HRESULT hr
= IUnknown_QueryInterface(This
->pDispatchUnknown
, &IID_IDispatch
, (void **)&pDispatch
);
441 hr
= IDispatch_GetTypeInfoCount(pDispatch
, pctinfo
);
442 IDispatch_Release(pDispatch
);
447 static HRESULT WINAPI
Widget_GetTypeInfo(
448 IWidget __RPC_FAR
* iface
,
449 /* [in] */ UINT iTInfo
,
450 /* [in] */ LCID lcid
,
451 /* [out] */ ITypeInfo __RPC_FAR
*__RPC_FAR
*ppTInfo
)
453 Widget
*This
= impl_from_IWidget(iface
);
454 IDispatch
*pDispatch
;
455 HRESULT hr
= IUnknown_QueryInterface(This
->pDispatchUnknown
, &IID_IDispatch
, (void **)&pDispatch
);
458 hr
= IDispatch_GetTypeInfo(pDispatch
, iTInfo
, lcid
, ppTInfo
);
459 IDispatch_Release(pDispatch
);
464 static HRESULT WINAPI
Widget_GetIDsOfNames(
465 IWidget __RPC_FAR
* iface
,
466 /* [in] */ REFIID riid
,
467 /* [size_is][in] */ LPOLESTR __RPC_FAR
*rgszNames
,
468 /* [in] */ UINT cNames
,
469 /* [in] */ LCID lcid
,
470 /* [size_is][out] */ DISPID __RPC_FAR
*rgDispId
)
472 Widget
*This
= impl_from_IWidget(iface
);
473 IDispatch
*pDispatch
;
474 HRESULT hr
= IUnknown_QueryInterface(This
->pDispatchUnknown
, &IID_IDispatch
, (void **)&pDispatch
);
477 hr
= IDispatch_GetIDsOfNames(pDispatch
, riid
, rgszNames
, cNames
, lcid
, rgDispId
);
478 IDispatch_Release(pDispatch
);
483 static HRESULT WINAPI
Widget_Invoke(
484 IWidget __RPC_FAR
* iface
,
485 /* [in] */ DISPID dispIdMember
,
486 /* [in] */ REFIID riid
,
487 /* [in] */ LCID lcid
,
488 /* [in] */ WORD wFlags
,
489 /* [out][in] */ DISPPARAMS __RPC_FAR
*pDispParams
,
490 /* [out] */ VARIANT __RPC_FAR
*pVarResult
,
491 /* [out] */ EXCEPINFO __RPC_FAR
*pExcepInfo
,
492 /* [out] */ UINT __RPC_FAR
*puArgErr
)
494 Widget
*This
= impl_from_IWidget(iface
);
495 IDispatch
*pDispatch
;
496 HRESULT hr
= IUnknown_QueryInterface(This
->pDispatchUnknown
, &IID_IDispatch
, (void **)&pDispatch
);
499 hr
= IDispatch_Invoke(pDispatch
, dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
500 IDispatch_Release(pDispatch
);
505 static HRESULT WINAPI
Widget_put_Name(
506 IWidget __RPC_FAR
* iface
,
507 /* [in] */ BSTR name
)
509 trace("put_Name(%s)\n", wine_dbgstr_w(name
));
513 static HRESULT WINAPI
Widget_get_Name(
514 IWidget __RPC_FAR
* iface
,
515 /* [out] */ BSTR __RPC_FAR
*name
)
517 static const WCHAR szCat
[] = { 'C','a','t',0 };
518 trace("get_Name()\n");
519 *name
= SysAllocString(szCat
);
523 static HRESULT WINAPI
Widget_DoSomething(
524 IWidget __RPC_FAR
* iface
,
525 /* [in] */ double number
,
526 /* [out] */ BSTR
*str1
,
527 /* [defaultvalue][in] */ BSTR str2
,
528 /* [optional][in] */ VARIANT __RPC_FAR
*opt
)
530 static const WCHAR szString
[] = { 'S','t','r','i','n','g',0 };
531 trace("DoSomething()\n");
533 ok(number
== 3.141, "number(%f) != 3.141\n", number
);
534 ok(*str2
== '\0', "str2(%s) != \"\"\n", wine_dbgstr_w(str2
));
535 ok(V_VT(opt
) == VT_ERROR
, "V_VT(opt) should be VT_ERROR instead of 0x%x\n", V_VT(opt
));
536 ok(V_ERROR(opt
) == DISP_E_PARAMNOTFOUND
, "V_ERROR(opt) should be DISP_E_PARAMNOTFOUND instead of 0x%08x\n", V_ERROR(opt
));
537 *str1
= SysAllocString(szString
);
542 static HRESULT WINAPI
Widget_get_State(
543 IWidget __RPC_FAR
* iface
,
544 /* [retval][out] */ STATE __RPC_FAR
*state
)
546 trace("get_State() = STATE_WIDGETIFIED\n");
547 *state
= STATE_WIDGETIFIED
;
551 static HRESULT WINAPI
Widget_put_State(
552 IWidget __RPC_FAR
* iface
,
553 /* [in] */ STATE state
)
555 trace("put_State(%d)\n", state
);
559 static HRESULT WINAPI
Widget_Map(
564 trace("Map(%s, %p)\n", wine_dbgstr_w(bstrId
), sValue
);
565 *sValue
= SysAllocString(bstrId
);
569 static HRESULT WINAPI
Widget_SetOleColor(
573 trace("SetOleColor(0x%x)\n", val
);
577 static HRESULT WINAPI
Widget_GetOleColor(
581 trace("GetOleColor() = 0x8000000f\n");
586 static HRESULT WINAPI
Widget_Clone(
591 return Widget_QueryInterface(iface
, &IID_IWidget
, (void **)ppVal
);
594 static HRESULT WINAPI
Widget_CloneDispatch(
598 trace("CloneDispatch()\n");
599 return Widget_QueryInterface(iface
, &IID_IWidget
, (void **)ppVal
);
602 static HRESULT WINAPI
Widget_CloneCoclass(
604 ApplicationObject2
**ppVal
)
606 trace("CloneCoclass()\n");
607 return Widget_QueryInterface(iface
, &IID_IWidget
, (void **)ppVal
);
610 static HRESULT WINAPI
Widget_Value(
611 IWidget __RPC_FAR
* iface
,
615 trace("Value(%p, %p)\n", value
, retval
);
616 ok(V_VT(value
) == VT_I2
, "V_VT(value) was %d instead of VT_I2\n", V_VT(value
));
617 ok(V_I2(value
) == 1, "V_I2(value) was %d instead of 1\n", V_I2(value
));
618 V_VT(retval
) = VT_I2
;
623 static HRESULT WINAPI
Widget_Array(
627 trace("Array(%p)\n", values
);
631 static HRESULT WINAPI
Widget_VariantArrayPtr(
635 trace("VariantArrayPtr(%p)\n", values
);
639 static HRESULT WINAPI
Widget_VariantCArray(
646 trace("VariantCArray(%u,%p)\n", count
, values
);
648 ok(count
== 2, "count is %d\n", count
);
649 for (i
= 0; i
< count
; i
++)
650 ok(V_VT(&values
[i
]) == VT_I4
, "values[%d] is not VT_I4\n", i
);
659 for (i
= 0; i
< count
; i
++) {
661 hr
= pVarAdd(&values
[i
], &inc
, &res
);
663 ok(0, "VarAdd failed at %u with error 0x%x\n", i
, hr
);
666 hr
= VariantCopy(&values
[i
], &res
);
668 ok(0, "VariantCopy failed at %u with error 0x%x\n", i
, hr
);
674 win_skip("VarAdd is not available\n");
679 static HRESULT WINAPI
Widget_Variant(
680 IWidget __RPC_FAR
* iface
,
683 trace("Variant()\n");
684 ok(V_VT(&var
) == VT_CY
, "V_VT(&var) was %d\n", V_VT(&var
));
685 ok(S(V_CY(&var
)).Hi
== 0xdababe, "V_CY(&var).Hi was 0x%x\n", S(V_CY(&var
)).Hi
);
686 ok(S(V_CY(&var
)).Lo
== 0xdeadbeef, "V_CY(&var).Lo was 0x%x\n", S(V_CY(&var
)).Lo
);
690 static HRESULT WINAPI
Widget_VarArg(
695 LONG lbound
, ubound
, i
;
699 trace("VarArg(%p)\n", values
);
701 hr
= SafeArrayGetLBound(values
, 1, &lbound
);
702 ok(hr
== S_OK
, "SafeArrayGetLBound failed with %x\n", hr
);
703 ok(lbound
== 0, "SafeArrayGetLBound returned %d\n", lbound
);
705 hr
= SafeArrayGetUBound(values
, 1, &ubound
);
706 ok(hr
== S_OK
, "SafeArrayGetUBound failed with %x\n", hr
);
707 ok(ubound
== numexpect
-1, "SafeArrayGetUBound returned %d, but expected %d\n", ubound
, numexpect
-1);
709 hr
= SafeArrayAccessData(values
, (LPVOID
)&data
);
710 ok(hr
== S_OK
, "SafeArrayAccessData failed with %x\n", hr
);
712 for (i
=0; i
<=ubound
-lbound
; i
++)
714 ok(V_VT(&data
[i
]) == VT_I4
, "V_VT(&data[%d]) was %d\n", i
, V_VT(&data
[i
]));
715 ok(V_I4(&data
[i
]) == i
, "V_I4(&data[%d]) was %d\n", i
, V_I4(&data
[i
]));
718 hr
= SafeArrayUnaccessData(values
);
719 ok(hr
== S_OK
, "SafeArrayUnaccessData failed with %x\n", hr
);
725 static BOOL
mystruct_uint_ordered(MYSTRUCT
*mystruct
)
728 for (i
= 0; i
< sizeof(mystruct
->uarr
)/sizeof(mystruct
->uarr
[0]); i
++)
729 if (mystruct
->uarr
[i
] != i
)
734 static HRESULT WINAPI
Widget_StructArgs(
741 ok(byval
.field1
== MYSTRUCT_BYVAL
.field1
&&
742 byval
.field2
== MYSTRUCT_BYVAL
.field2
&&
743 mystruct_uint_ordered(&byval
),
744 "Struct parameter passed by value corrupted\n");
745 ok(byptr
->field1
== MYSTRUCT_BYPTR
.field1
&&
746 byptr
->field2
== MYSTRUCT_BYPTR
.field2
&&
747 mystruct_uint_ordered(byptr
),
748 "Struct parameter passed by pointer corrupted\n");
749 for (i
= 0; i
< 5; i
++)
750 if (arr
[i
].field1
!= MYSTRUCT_ARRAY
[i
].field1
||
751 arr
[i
].field2
!= MYSTRUCT_ARRAY
[i
].field2
||
752 ! mystruct_uint_ordered(&arr
[i
]))
754 ok(diff
== 0, "Array of structs corrupted\n");
759 static HRESULT WINAPI
Widget_Error(
760 IWidget __RPC_FAR
* iface
)
766 static HRESULT WINAPI
Widget_CloneInterface(
767 IWidget __RPC_FAR
* iface
,
768 ISomethingFromDispatch
**ppVal
)
770 trace("CloneInterface()\n");
775 static HRESULT WINAPI
Widget_put_prop_with_lcid(
776 IWidget
* iface
, LONG lcid
, INT i
)
778 trace("put_prop_with_lcid(%08x, %x)\n", lcid
, i
);
779 ok(lcid
== MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), "got lcid %08x\n", lcid
);
780 ok(i
== 0xcafe, "got %08x\n", i
);
784 static HRESULT WINAPI
Widget_get_prop_with_lcid(
785 IWidget
* iface
, LONG lcid
, INT
*i
)
787 trace("get_prop_with_lcid(%08x, %p)\n", lcid
, i
);
788 ok(lcid
== MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), "got lcid %08x\n", lcid
);
793 static HRESULT WINAPI
Widget_get_prop_int(
794 IWidget
* iface
, INT
*i
)
796 trace("get_prop_int(%p)\n", i
);
801 static HRESULT WINAPI
Widget_get_prop_uint(
802 IWidget
* iface
, UINT
*i
)
804 trace("get_prop_uint(%p)\n", i
);
809 static HRESULT WINAPI
Widget_ByRefUInt(
810 IWidget
* iface
, UINT
*i
)
816 static HRESULT WINAPI
Widget_put_prop_opt_arg(
817 IWidget
* iface
, INT opt
, INT i
)
819 trace("put_prop_opt_arg(%08x, %08x)\n", opt
, i
);
820 todo_wine
ok(opt
== 0, "got opt=%08x\n", opt
);
821 ok(i
== 0xcafe, "got i=%08x\n", i
);
825 static HRESULT WINAPI
Widget_put_prop_req_arg(
826 IWidget
* iface
, INT req
, INT i
)
828 trace("put_prop_req_arg(%08x, %08x)\n", req
, i
);
829 ok(req
== 0x5678, "got req=%08x\n", req
);
830 ok(i
== 0x1234, "got i=%08x\n", i
);
834 static HRESULT WINAPI
Widget_pos_restrict(IWidget
* iface
, INT
*i
)
837 *i
= DISPID_TM_RESTRICTED
;
841 static HRESULT WINAPI
Widget_neg_restrict(IWidget
* iface
, INT
*i
)
843 trace("neg_restrict\n");
844 *i
= DISPID_TM_NEG_RESTRICTED
;
848 static HRESULT WINAPI
Widget_VarArg_Run(
849 IWidget
*iface
, BSTR name
, SAFEARRAY
*params
, VARIANT
*result
)
851 static const WCHAR catW
[] = { 'C','a','t',0 };
852 static const WCHAR supermanW
[] = { 'S','u','p','e','r','m','a','n',0 };
858 trace("VarArg_Run(%p,%p,%p)\n", name
, params
, result
);
860 ok(!lstrcmpW(name
, catW
), "got %s\n", wine_dbgstr_w(name
));
862 hr
= SafeArrayGetLBound(params
, 1, &bound
);
863 ok(hr
== S_OK
, "SafeArrayGetLBound error %#x\n", hr
);
864 ok(bound
== 0, "expected 0, got %d\n", bound
);
866 hr
= SafeArrayGetUBound(params
, 1, &bound
);
867 ok(hr
== S_OK
, "SafeArrayGetUBound error %#x\n", hr
);
868 ok(bound
== 0, "expected 0, got %d\n", bound
);
870 hr
= SafeArrayAccessData(params
, (void **)&var
);
871 ok(hr
== S_OK
, "SafeArrayAccessData failed with %x\n", hr
);
873 ok(V_VT(&var
[0]) == VT_BSTR
, "expected VT_BSTR, got %d\n", V_VT(&var
[0]));
874 bstr
= V_BSTR(&var
[0]);
875 ok(!lstrcmpW(bstr
, supermanW
), "got %s\n", wine_dbgstr_w(bstr
));
877 hr
= SafeArrayUnaccessData(params
);
878 ok(hr
== S_OK
, "SafeArrayUnaccessData error %#x\n", hr
);
883 static HRESULT WINAPI
Widget_VarArg_Ref_Run(
884 IWidget
*iface
, BSTR name
, SAFEARRAY
**params
, VARIANT
*result
)
886 static const WCHAR catW
[] = { 'C','a','t',0 };
887 static const WCHAR supermanW
[] = { 'S','u','p','e','r','m','a','n',0 };
893 trace("VarArg_Ref_Run(%p,%p,%p)\n", name
, params
, result
);
895 ok(!lstrcmpW(name
, catW
), "got %s\n", wine_dbgstr_w(name
));
897 hr
= SafeArrayGetLBound(*params
, 1, &bound
);
898 ok(hr
== S_OK
, "SafeArrayGetLBound error %#x\n", hr
);
899 ok(bound
== 0, "expected 0, got %d\n", bound
);
901 hr
= SafeArrayGetUBound(*params
, 1, &bound
);
902 ok(hr
== S_OK
, "SafeArrayGetUBound error %#x\n", hr
);
903 ok(bound
== 0, "expected 0, got %d\n", bound
);
905 hr
= SafeArrayAccessData(*params
, (void **)&var
);
906 ok(hr
== S_OK
, "SafeArrayAccessData error %#x\n", hr
);
908 ok(V_VT(&var
[0]) == VT_BSTR
, "expected VT_BSTR, got %d\n", V_VT(&var
[0]));
909 bstr
= V_BSTR(&var
[0]);
910 ok(!lstrcmpW(bstr
, supermanW
), "got %s\n", wine_dbgstr_w(bstr
));
912 hr
= SafeArrayUnaccessData(*params
);
913 ok(hr
== S_OK
, "SafeArrayUnaccessData error %#x\n", hr
);
918 static HRESULT WINAPI
Widget_Coclass(
919 IWidget
*iface
, ApplicationObject2
*param
)
921 trace("Coclass(%p)\n", param
);
922 ok(param
== (ApplicationObject2
*)iface
, "expected param == %p, got %p\n", iface
, param
);
926 static const struct IWidgetVtbl Widget_VTable
=
928 Widget_QueryInterface
,
931 Widget_GetTypeInfoCount
,
933 Widget_GetIDsOfNames
,
944 Widget_CloneDispatch
,
948 Widget_VariantArrayPtr
,
949 Widget_VariantCArray
,
954 Widget_CloneInterface
,
955 Widget_put_prop_with_lcid
,
956 Widget_get_prop_with_lcid
,
958 Widget_get_prop_uint
,
960 Widget_put_prop_opt_arg
,
961 Widget_put_prop_req_arg
,
965 Widget_VarArg_Ref_Run
,
969 static HRESULT WINAPI
StaticWidget_QueryInterface(IStaticWidget
*iface
, REFIID riid
, void **ppvObject
)
971 if (IsEqualIID(riid
, &IID_IStaticWidget
) || IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDispatch
))
973 IStaticWidget_AddRef(iface
);
979 return E_NOINTERFACE
;
982 static ULONG WINAPI
StaticWidget_AddRef(IStaticWidget
*iface
)
987 static ULONG WINAPI
StaticWidget_Release(IStaticWidget
*iface
)
992 static HRESULT WINAPI
StaticWidget_GetTypeInfoCount(IStaticWidget
*iface
, UINT
*pctinfo
)
994 ok(0, "unexpected call\n");
998 static HRESULT WINAPI
StaticWidget_GetTypeInfo(IStaticWidget
*iface
, UINT iTInfo
, LCID lcid
,
1001 ok(0, "unexpected call\n");
1005 static HRESULT WINAPI
StaticWidget_GetIDsOfNames(IStaticWidget
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
1006 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1008 ok(0, "unexpected call\n");
1012 static HRESULT WINAPI
StaticWidget_Invoke(IStaticWidget
*iface
, DISPID dispIdMember
, REFIID riid
,
1013 LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
,
1016 ok(0, "unexpected call\n");
1020 static HRESULT WINAPI
StaticWidget_TestDual(IStaticWidget
*iface
, ItestDual
*p
)
1022 trace("TestDual()\n");
1023 ok(p
== &TestDual
, "wrong ItestDual\n");
1027 static HRESULT WINAPI
StaticWidget_TestSecondIface(IStaticWidget
*iface
, ITestSecondIface
*p
)
1029 trace("TestSecondIface()\n");
1030 ok(p
== &TestSecondIface
, "wrong ItestSecondIface\n");
1034 static const IStaticWidgetVtbl StaticWidgetVtbl
= {
1035 StaticWidget_QueryInterface
,
1036 StaticWidget_AddRef
,
1037 StaticWidget_Release
,
1038 StaticWidget_GetTypeInfoCount
,
1039 StaticWidget_GetTypeInfo
,
1040 StaticWidget_GetIDsOfNames
,
1041 StaticWidget_Invoke
,
1042 StaticWidget_TestDual
,
1043 StaticWidget_TestSecondIface
1046 static IStaticWidget StaticWidget
= { &StaticWidgetVtbl
};
1048 typedef struct KindaEnum
1050 IKindaEnumWidget IKindaEnumWidget_iface
;
1054 static inline KindaEnum
*impl_from_IKindaEnumWidget(IKindaEnumWidget
*iface
)
1056 return CONTAINING_RECORD(iface
, KindaEnum
, IKindaEnumWidget_iface
);
1059 static HRESULT
register_current_module_typelib(void)
1061 WCHAR path
[MAX_PATH
];
1062 CHAR pathA
[MAX_PATH
];
1066 GetModuleFileNameA(NULL
, pathA
, MAX_PATH
);
1067 MultiByteToWideChar(CP_ACP
, 0, pathA
, -1, path
, MAX_PATH
);
1069 hr
= LoadTypeLib(path
, &typelib
);
1072 hr
= RegisterTypeLib(typelib
, path
, NULL
);
1073 ITypeLib_Release(typelib
);
1078 static ITypeInfo
*get_type_info(REFIID riid
)
1080 ITypeInfo
*pTypeInfo
;
1084 hr
= LoadRegTypeLib(&LIBID_TestTypelib
, 2, 5, LOCALE_NEUTRAL
, &pTypeLib
);
1085 ok_ole_success(hr
, LoadRegTypeLib
);
1089 hr
= ITypeLib_GetTypeInfoOfGuid(pTypeLib
, riid
, &pTypeInfo
);
1090 ITypeLib_Release(pTypeLib
);
1091 ok_ole_success(hr
, ITypeLib_GetTypeInfoOfGuid
);
1098 static IWidget
*Widget_Create(void)
1101 ITypeInfo
*pTypeInfo
;
1102 HRESULT hr
= E_FAIL
;
1104 pTypeInfo
= get_type_info(&IID_IWidget
);
1108 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
1109 This
->IWidget_iface
.lpVtbl
= &Widget_VTable
;
1111 This
->pDispatchUnknown
= NULL
;
1113 hr
= CreateStdDispatch((IUnknown
*)&This
->IWidget_iface
, This
, pTypeInfo
,
1114 &This
->pDispatchUnknown
);
1115 ok_ole_success(hr
, CreateStdDispatch
);
1116 ITypeInfo_Release(pTypeInfo
);
1119 return &This
->IWidget_iface
;
1122 HeapFree(GetProcessHeap(), 0, This
);
1127 static HRESULT WINAPI
KindaEnum_QueryInterface(
1128 IKindaEnumWidget
*iface
,
1129 /* [in] */ REFIID riid
,
1130 /* [iid_is][out] */ void __RPC_FAR
*__RPC_FAR
*ppvObject
)
1132 if (IsEqualIID(riid
, &IID_IKindaEnumWidget
) || IsEqualIID(riid
, &IID_IUnknown
))
1134 IKindaEnumWidget_AddRef(iface
);
1141 return E_NOINTERFACE
;
1145 static ULONG WINAPI
KindaEnum_AddRef(
1146 IKindaEnumWidget
*iface
)
1148 KindaEnum
*This
= impl_from_IKindaEnumWidget(iface
);
1150 return InterlockedIncrement(&This
->refs
);
1153 static ULONG WINAPI
KindaEnum_Release(
1154 IKindaEnumWidget
*iface
)
1156 KindaEnum
*This
= impl_from_IKindaEnumWidget(iface
);
1157 ULONG refs
= InterlockedDecrement(&This
->refs
);
1160 memset(This
, 0xcc, sizeof(*This
));
1161 HeapFree(GetProcessHeap(), 0, This
);
1162 trace("KindaEnumWidget destroyed!\n");
1168 static HRESULT WINAPI
KindaEnum_Next(
1169 IKindaEnumWidget
*iface
,
1170 /* [out] */ IWidget __RPC_FAR
*__RPC_FAR
*widget
)
1172 *widget
= Widget_Create();
1176 return E_OUTOFMEMORY
;
1179 static HRESULT WINAPI
KindaEnum_Count(
1180 IKindaEnumWidget
*iface
,
1181 /* [out] */ ULONG __RPC_FAR
*count
)
1186 static HRESULT WINAPI
KindaEnum_Reset(
1187 IKindaEnumWidget
*iface
)
1192 static HRESULT WINAPI
KindaEnum_Clone(
1193 IKindaEnumWidget
*iface
,
1194 /* [out] */ IKindaEnumWidget __RPC_FAR
*__RPC_FAR
*ppenum
)
1199 static const IKindaEnumWidgetVtbl KindaEnumWidget_VTable
=
1201 KindaEnum_QueryInterface
,
1210 static IKindaEnumWidget
*KindaEnumWidget_Create(void)
1214 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
1215 if (!This
) return NULL
;
1216 This
->IKindaEnumWidget_iface
.lpVtbl
= &KindaEnumWidget_VTable
;
1218 return &This
->IKindaEnumWidget_iface
;
1221 static HRESULT WINAPI
NonOleAutomation_QueryInterface(INonOleAutomation
*iface
, REFIID riid
, void **ppv
)
1223 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_INonOleAutomation
))
1225 *(INonOleAutomation
**)ppv
= iface
;
1229 return E_NOINTERFACE
;
1232 static ULONG WINAPI
NonOleAutomation_AddRef(INonOleAutomation
*iface
)
1237 static ULONG WINAPI
NonOleAutomation_Release(INonOleAutomation
*iface
)
1242 static BSTR WINAPI
NonOleAutomation_BstrRet(INonOleAutomation
*iface
)
1244 static const WCHAR wszTestString
[] = {'T','h','i','s',' ','i','s',' ','a',' ','t','e','s','t',' ','s','t','r','i','n','g',0};
1245 return SysAllocString(wszTestString
);
1248 static HRESULT WINAPI
NonOleAutomation_Error(INonOleAutomation
*iface
)
1253 static INonOleAutomationVtbl NonOleAutomation_VTable
=
1255 NonOleAutomation_QueryInterface
,
1256 NonOleAutomation_AddRef
,
1257 NonOleAutomation_Release
,
1258 NonOleAutomation_BstrRet
,
1259 NonOleAutomation_Error
1262 static INonOleAutomation NonOleAutomation
= { &NonOleAutomation_VTable
};
1264 static ITypeInfo
*NonOleAutomation_GetTypeInfo(void)
1267 HRESULT hr
= LoadRegTypeLib(&LIBID_TestTypelib
, 2, 5, LOCALE_NEUTRAL
, &pTypeLib
);
1268 ok_ole_success(hr
, LoadRegTypeLib
);
1271 ITypeInfo
*pTypeInfo
;
1272 hr
= ITypeLib_GetTypeInfoOfGuid(pTypeLib
, &IID_INonOleAutomation
, &pTypeInfo
);
1273 ok_ole_success(hr
, ITypeLib_GetTypeInfoOfGuid
);
1274 ITypeLib_Release(pTypeLib
);
1280 static void test_typelibmarshal(void)
1282 static const WCHAR szCat
[] = { 'C','a','t',0 };
1283 static const WCHAR szTestTest
[] = { 'T','e','s','t','T','e','s','t',0 };
1284 static const WCHAR szSuperman
[] = { 'S','u','p','e','r','m','a','n',0 };
1286 IKindaEnumWidget
*pKEW
= KindaEnumWidget_Create();
1289 IDispatch
*pDispatch
;
1290 static const LARGE_INTEGER ullZero
;
1291 EXCEPINFO excepinfo
;
1293 DISPID dispidNamed
= DISPID_PROPERTYPUT
;
1294 DISPPARAMS dispparams
;
1295 VARIANTARG vararg
[4];
1300 ITypeInfo
*pTypeInfo
;
1302 MYSTRUCT mystructArray
[5];
1305 ok(pKEW
!= NULL
, "Widget creation failed\n");
1307 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &pStream
);
1308 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1309 tid
= start_host_object(pStream
, &IID_IKindaEnumWidget
, (IUnknown
*)pKEW
, MSHLFLAGS_NORMAL
, &thread
);
1310 IKindaEnumWidget_Release(pKEW
);
1312 IStream_Seek(pStream
, ullZero
, STREAM_SEEK_SET
, NULL
);
1313 hr
= CoUnmarshalInterface(pStream
, &IID_IKindaEnumWidget
, (void **)&pKEW
);
1314 todo_wine_if(tmarshal_todo
)
1315 ok_ole_success(hr
, CoUnmarshalInterface
);
1316 IStream_Release(pStream
);
1318 hr
= IKindaEnumWidget_Next(pKEW
, &pWidget
);
1319 ok_ole_success(hr
, IKindaEnumWidget_Next
);
1321 IKindaEnumWidget_Release(pKEW
);
1323 /* call GetTypeInfoCount (direct) */
1324 hr
= IWidget_GetTypeInfoCount(pWidget
, &uval
);
1325 ok_ole_success(hr
, IWidget_GetTypeInfoCount
);
1326 hr
= IWidget_GetTypeInfoCount(pWidget
, &uval
);
1327 ok_ole_success(hr
, IWidget_GetTypeInfoCount
);
1329 hr
= IWidget_QueryInterface(pWidget
, &IID_IDispatch
, (void **)&pDispatch
);
1330 ok_ole_success(hr
, IWidget_QueryInterface
);
1333 VariantInit(&vararg
[0]);
1334 dispparams
.cNamedArgs
= 1;
1335 dispparams
.rgdispidNamedArgs
= &dispidNamed
;
1336 dispparams
.cArgs
= 1;
1337 dispparams
.rgvarg
= vararg
;
1338 VariantInit(&varresult
);
1339 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_NAME
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_PROPERTYPUT
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1340 ok_ole_success(hr
, IDispatch_Invoke
);
1341 todo_wine_if(tmarshal_todo
)
1342 ok(excepinfo
.wCode
== 0x0 && excepinfo
.scode
== S_OK
,
1343 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n",
1344 excepinfo
.wCode
, excepinfo
.scode
);
1345 VariantClear(&varresult
);
1347 /* call put_Name (direct) */
1348 bstr
= SysAllocString(szSuperman
);
1349 hr
= IWidget_put_Name(pWidget
, bstr
);
1350 ok_ole_success(hr
, IWidget_put_Name
);
1351 SysFreeString(bstr
);
1354 dispparams
.cNamedArgs
= 0;
1355 dispparams
.rgdispidNamedArgs
= NULL
;
1356 dispparams
.cArgs
= 0;
1357 dispparams
.rgvarg
= NULL
;
1358 VariantInit(&varresult
);
1359 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_NAME
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1360 ok_ole_success(hr
, IDispatch_Invoke
);
1361 todo_wine_if(tmarshal_todo
)
1362 ok(excepinfo
.wCode
== 0x0 && excepinfo
.scode
== S_OK
,
1363 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n",
1364 excepinfo
.wCode
, excepinfo
.scode
);
1365 trace("Name = %s\n", wine_dbgstr_w(V_BSTR(&varresult
)));
1366 VariantClear(&varresult
);
1368 /* call get_Name (direct) */
1369 bstr
= (void *)0xdeadbeef;
1370 hr
= IWidget_get_Name(pWidget
, &bstr
);
1371 ok_ole_success(hr
, IWidget_get_Name
);
1372 ok(!lstrcmpW(bstr
, szCat
), "IWidget_get_Name should have returned string \"Cat\" instead of %s\n", wine_dbgstr_w(bstr
));
1373 SysFreeString(bstr
);
1375 /* call DoSomething without optional arguments */
1376 VariantInit(&vararg
[0]);
1377 VariantInit(&vararg
[1]);
1378 V_VT(&vararg
[1]) = VT_R8
;
1379 V_R8(&vararg
[1]) = 3.141;
1380 dispparams
.cNamedArgs
= 0;
1381 dispparams
.cArgs
= 2;
1382 dispparams
.rgdispidNamedArgs
= NULL
;
1383 dispparams
.rgvarg
= vararg
;
1384 VariantInit(&varresult
);
1385 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_DOSOMETHING
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1386 ok_ole_success(hr
, IDispatch_Invoke
);
1387 ok(V_VT(&varresult
) == VT_EMPTY
, "varresult should be VT_EMPTY\n");
1388 VariantClear(&varresult
);
1390 /* call DoSomething with optional argument set to VT_EMPTY */
1391 VariantInit(&vararg
[0]);
1392 VariantInit(&vararg
[1]);
1393 VariantInit(&vararg
[2]);
1394 V_VT(&vararg
[2]) = VT_R8
;
1395 V_R8(&vararg
[2]) = 3.141;
1396 dispparams
.cNamedArgs
= 0;
1397 dispparams
.cArgs
= 3;
1398 dispparams
.rgdispidNamedArgs
= NULL
;
1399 dispparams
.rgvarg
= vararg
;
1400 VariantInit(&varresult
);
1401 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_DOSOMETHING
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1402 ok_ole_success(hr
, IDispatch_Invoke
);
1403 ok(V_VT(&varresult
) == VT_EMPTY
, "varresult should be VT_EMPTY\n");
1404 VariantClear(&varresult
);
1406 /* call DoSomething with optional arguments set to VT_ERROR/DISP_E_PARAMNOTFOUND */
1407 VariantInit(&vararg
[0]);
1408 VariantInit(&vararg
[1]);
1409 VariantInit(&vararg
[2]);
1410 VariantInit(&vararg
[3]);
1411 V_VT(&vararg
[3]) = VT_R8
;
1412 V_R8(&vararg
[3]) = 3.141;
1413 V_VT(&vararg
[1]) = VT_ERROR
;
1414 V_ERROR(&vararg
[1]) = DISP_E_PARAMNOTFOUND
;
1415 V_VT(&vararg
[0]) = VT_ERROR
;
1416 V_ERROR(&vararg
[0]) = DISP_E_PARAMNOTFOUND
;
1417 dispparams
.cNamedArgs
= 0;
1418 dispparams
.cArgs
= 4;
1419 dispparams
.rgdispidNamedArgs
= NULL
;
1420 dispparams
.rgvarg
= vararg
;
1421 VariantInit(&varresult
);
1422 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_DOSOMETHING
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1423 ok_ole_success(hr
, IDispatch_Invoke
);
1424 ok(V_VT(&varresult
) == VT_EMPTY
, "varresult should be VT_EMPTY\n");
1425 VariantClear(&varresult
);
1427 /* call get_State */
1428 dispparams
.cNamedArgs
= 0;
1429 dispparams
.cArgs
= 0;
1430 dispparams
.rgdispidNamedArgs
= NULL
;
1431 dispparams
.rgvarg
= NULL
;
1432 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_STATE
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1433 ok_ole_success(hr
, IDispatch_Invoke
);
1434 ok((V_VT(&varresult
) == VT_I4
) && (V_I4(&varresult
) == STATE_WIDGETIFIED
), "Return val mismatch\n");
1436 /* call get_State (direct) */
1437 hr
= IWidget_get_State(pWidget
, &the_state
);
1438 ok_ole_success(hr
, IWidget_get_state
);
1439 ok(the_state
== STATE_WIDGETIFIED
, "should have returned WIDGET_WIDGETIFIED instead of %d\n", the_state
);
1441 /* call put_State */
1442 the_state
= STATE_WIDGETIFIED
;
1443 VariantInit(&vararg
[0]);
1444 V_VT(&vararg
[0]) = VT_BYREF
|VT_I4
;
1445 V_I4REF(&vararg
[0]) = (int *)&the_state
;
1446 dispparams
.cNamedArgs
= 1;
1447 dispparams
.cArgs
= 1;
1448 dispparams
.rgdispidNamedArgs
= &dispidNamed
;
1449 dispparams
.rgvarg
= vararg
;
1450 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_STATE
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_PROPERTYPUT
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1451 ok_ole_success(hr
, IDispatch_Invoke
);
1454 bstr
= SysAllocString(szTestTest
);
1455 VariantInit(&vararg
[0]);
1456 V_VT(&vararg
[0]) = VT_BYREF
|VT_BSTR
;
1457 V_BSTRREF(&vararg
[0]) = &bstr
;
1458 dispparams
.cNamedArgs
= 0;
1459 dispparams
.cArgs
= 1;
1460 dispparams
.rgdispidNamedArgs
= NULL
;
1461 dispparams
.rgvarg
= vararg
;
1462 VariantInit(&varresult
);
1463 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_MAP
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1464 ok_ole_success(hr
, IDispatch_Invoke
);
1465 ok(V_VT(&varresult
) == VT_BSTR
, "Return value should be of type BSTR instead of %d\n", V_VT(&varresult
));
1466 ok(!lstrcmpW(V_BSTR(&varresult
), szTestTest
), "Return value should have been \"TestTest\" instead of %s\n", wine_dbgstr_w(V_BSTR(&varresult
)));
1467 VariantClear(&varresult
);
1468 SysFreeString(bstr
);
1470 /* call SetOleColor with large negative VT_I4 param */
1471 VariantInit(&vararg
[0]);
1472 V_VT(&vararg
[0]) = VT_I4
;
1473 V_I4(&vararg
[0]) = 0x80000005;
1474 dispparams
.cNamedArgs
= 0;
1475 dispparams
.cArgs
= 1;
1476 dispparams
.rgdispidNamedArgs
= NULL
;
1477 dispparams
.rgvarg
= vararg
;
1478 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_SETOLECOLOR
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, NULL
, &excepinfo
, NULL
);
1479 ok_ole_success(hr
, IDispatch_Invoke
);
1481 /* call GetOleColor */
1482 dispparams
.cNamedArgs
= 0;
1483 dispparams
.cArgs
= 0;
1484 dispparams
.rgdispidNamedArgs
= NULL
;
1485 dispparams
.rgvarg
= NULL
;
1486 VariantInit(&varresult
);
1487 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_GETOLECOLOR
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1488 ok_ole_success(hr
, IDispatch_Invoke
);
1489 VariantClear(&varresult
);
1491 /* call StructArgs (direct) */
1492 mystruct
= MYSTRUCT_BYPTR
;
1493 memcpy(mystructArray
, MYSTRUCT_ARRAY
, sizeof(mystructArray
));
1494 hr
= IWidget_StructArgs(pWidget
, MYSTRUCT_BYVAL
, &mystruct
, mystructArray
);
1495 ok_ole_success(hr
, IWidget_StructArgs
);
1498 dispparams
.cNamedArgs
= 0;
1499 dispparams
.cArgs
= 0;
1500 dispparams
.rgdispidNamedArgs
= NULL
;
1501 dispparams
.rgvarg
= NULL
;
1502 VariantInit(&varresult
);
1503 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_CLONE
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1504 ok_ole_success(hr
, IDispatch_Invoke
);
1505 ok(V_VT(&varresult
) == VT_DISPATCH
, "vt %x\n", V_VT(&varresult
));
1506 VariantClear(&varresult
);
1508 /* call CloneInterface */
1509 dispparams
.cNamedArgs
= 0;
1510 dispparams
.cArgs
= 0;
1511 dispparams
.rgdispidNamedArgs
= NULL
;
1512 dispparams
.rgvarg
= NULL
;
1513 VariantInit(&varresult
);
1514 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_CLONEINTERFACE
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1515 ok_ole_success(hr
, IDispatch_Invoke
);
1516 ok(V_VT(&varresult
) == VT_DISPATCH
, "vt %x\n", V_VT(&varresult
));
1517 VariantClear(&varresult
);
1519 /* call CloneDispatch with automatic value getting */
1520 V_VT(&vararg
[0]) = VT_I2
;
1521 V_I2(&vararg
[0]) = 1;
1522 dispparams
.cNamedArgs
= 0;
1523 dispparams
.rgdispidNamedArgs
= NULL
;
1524 dispparams
.cArgs
= 1;
1525 dispparams
.rgvarg
= vararg
;
1526 VariantInit(&varresult
);
1527 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_CLONEDISPATCH
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1528 ok_ole_success(hr
, IDispatch_Invoke
);
1530 todo_wine_if(tmarshal_todo
)
1531 ok(excepinfo
.wCode
== 0x0 && excepinfo
.scode
== S_OK
,
1532 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n",
1533 excepinfo
.wCode
, excepinfo
.scode
);
1535 ok(V_VT(&varresult
) == VT_I2
, "V_VT(&varresult) was %d instead of VT_I2\n", V_VT(&varresult
));
1536 ok(V_I2(&varresult
) == 1234, "V_I2(&varresult) was %d instead of 1234\n", V_I2(&varresult
));
1537 VariantClear(&varresult
);
1539 /* call CloneCoclass */
1540 dispparams
.cNamedArgs
= 0;
1541 dispparams
.cArgs
= 0;
1542 dispparams
.rgdispidNamedArgs
= NULL
;
1543 dispparams
.rgvarg
= NULL
;
1544 VariantInit(&varresult
);
1545 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_CLONECOCLASS
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1546 ok_ole_success(hr
, IDispatch_Invoke
);
1548 todo_wine_if(tmarshal_todo
)
1549 ok(excepinfo
.wCode
== 0x0 && excepinfo
.scode
== S_OK
,
1550 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n",
1551 excepinfo
.wCode
, excepinfo
.scode
);
1553 ok(V_VT(&varresult
) == VT_DISPATCH
, "V_VT(&varresult) was %d instead of VT_DISPATCH\n", V_VT(&varresult
));
1554 ok(V_DISPATCH(&varresult
) != NULL
, "expected V_DISPATCH(&varresult) != NULL\n");
1556 /* call Coclass with VT_DISPATCH type */
1557 vararg
[0] = varresult
;
1558 dispparams
.cNamedArgs
= 0;
1559 dispparams
.rgdispidNamedArgs
= NULL
;
1560 dispparams
.cArgs
= 1;
1561 dispparams
.rgvarg
= vararg
;
1562 VariantInit(&varresult
);
1563 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_COCLASS
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1564 ok_ole_success(hr
, IDispatch_Invoke
);
1565 todo_wine_if(tmarshal_todo
)
1566 ok(excepinfo
.wCode
== 0x0 && excepinfo
.scode
== S_OK
,
1567 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n",
1568 excepinfo
.wCode
, excepinfo
.scode
);
1569 VariantClear(&varresult
);
1571 /* call CoClass (direct) */
1572 hr
= IWidget_Coclass(pWidget
, (void *)V_DISPATCH(&vararg
[0]));
1573 ok_ole_success(hr
, IWidget_Coclass
);
1574 VariantClear(&vararg
[0]);
1576 /* call Value with a VT_VARIANT|VT_BYREF type */
1577 V_VT(&vararg
[0]) = VT_VARIANT
|VT_BYREF
;
1578 V_VARIANTREF(&vararg
[0]) = &vararg
[1];
1579 V_VT(&vararg
[1]) = VT_I2
;
1580 V_I2(&vararg
[1]) = 1;
1581 dispparams
.cNamedArgs
= 0;
1582 dispparams
.rgdispidNamedArgs
= NULL
;
1583 dispparams
.cArgs
= 1;
1584 dispparams
.rgvarg
= vararg
;
1585 VariantInit(&varresult
);
1586 hr
= IDispatch_Invoke(pDispatch
, DISPID_VALUE
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1587 ok_ole_success(hr
, IDispatch_Invoke
);
1589 todo_wine_if(tmarshal_todo
)
1590 ok(excepinfo
.wCode
== 0x0 && excepinfo
.scode
== S_OK
,
1591 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n",
1592 excepinfo
.wCode
, excepinfo
.scode
);
1594 ok(V_VT(&varresult
) == VT_I2
, "V_VT(&varresult) was %d instead of VT_I2\n", V_VT(&varresult
));
1595 ok(V_I2(&varresult
) == 1234, "V_I2(&varresult) was %d instead of 1234\n", V_I2(&varresult
));
1596 VariantClear(&varresult
);
1598 /* call Variant - exercises variant copying in ITypeInfo::Invoke and
1599 * handling of void return types */
1600 /* use a big type to ensure that the variant was properly copied into the
1601 * destination function's args */
1602 V_VT(&vararg
[0]) = VT_CY
;
1603 S(V_CY(&vararg
[0])).Hi
= 0xdababe;
1604 S(V_CY(&vararg
[0])).Lo
= 0xdeadbeef;
1605 dispparams
.cNamedArgs
= 0;
1606 dispparams
.cArgs
= 1;
1607 dispparams
.rgdispidNamedArgs
= NULL
;
1608 dispparams
.rgvarg
= vararg
;
1609 VariantInit(&varresult
);
1610 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_VARIANT
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
1611 ok_ole_success(hr
, IDispatch_Invoke
);
1612 VariantClear(&varresult
);
1614 /* call Array with BSTR argument - type mismatch */
1615 VariantInit(&vararg
[0]);
1616 V_VT(&vararg
[0]) = VT_BSTR
;
1617 V_BSTR(&vararg
[0]) = SysAllocString(szSuperman
);
1618 dispparams
.cNamedArgs
= 0;
1619 dispparams
.cArgs
= 1;
1620 dispparams
.rgdispidNamedArgs
= NULL
;
1621 dispparams
.rgvarg
= vararg
;
1622 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_ARRAY
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
1623 ok(hr
== DISP_E_TYPEMISMATCH
|| hr
== DISP_E_BADVARTYPE
, "expected DISP_E_TYPEMISMATCH, got %#x\n", hr
);
1624 SysFreeString(V_BSTR(&vararg
[0]));
1626 /* call ArrayPtr with BSTR argument - type mismatch */
1627 VariantInit(&vararg
[0]);
1628 V_VT(&vararg
[0]) = VT_BSTR
;
1629 V_BSTR(&vararg
[0]) = SysAllocString(szSuperman
);
1630 dispparams
.cNamedArgs
= 0;
1631 dispparams
.cArgs
= 1;
1632 dispparams
.rgdispidNamedArgs
= NULL
;
1633 dispparams
.rgvarg
= vararg
;
1634 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_VARARRAYPTR
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
1635 ok(hr
== DISP_E_TYPEMISMATCH
|| hr
== DISP_E_BADVARTYPE
, "expected DISP_E_TYPEMISMATCH, got %#x\n", hr
);
1636 SysFreeString(V_BSTR(&vararg
[0]));
1638 /* call VariantCArray - test marshaling of variant arrays */
1639 V_VT(&vararg
[0]) = VT_I4
;
1640 V_I4(&vararg
[0]) = 1;
1641 V_VT(&vararg
[1]) = VT_I4
;
1642 V_I4(&vararg
[1]) = 2;
1643 hr
= IWidget_VariantCArray(pWidget
, 2, vararg
);
1644 ok_ole_success(hr
, IWidget_VariantCArray
);
1645 todo_wine_if(!tmarshal_todo
)
1646 ok(V_VT(&vararg
[0]) == VT_I4
&& V_I4(&vararg
[0]) == 2, "vararg[0] = %d[%d]\n", V_VT(&vararg
[0]), V_I4(&vararg
[0]));
1647 todo_wine_if(!tmarshal_todo
)
1648 ok(V_VT(&vararg
[1]) == VT_I4
&& V_I4(&vararg
[1]) == 3, "vararg[1] = %d[%d]\n", V_VT(&vararg
[1]), V_I4(&vararg
[1]));
1651 VariantInit(&vararg
[3]);
1652 V_VT(&vararg
[3]) = VT_I4
;
1653 V_I4(&vararg
[3]) = 3;
1654 VariantInit(&vararg
[2]);
1655 V_VT(&vararg
[2]) = VT_I4
;
1656 V_I4(&vararg
[2]) = 0;
1657 VariantInit(&vararg
[1]);
1658 V_VT(&vararg
[1]) = VT_I4
;
1659 V_I4(&vararg
[1]) = 1;
1660 VariantInit(&vararg
[0]);
1661 V_VT(&vararg
[0]) = VT_I4
;
1662 V_I4(&vararg
[0]) = 2;
1663 dispparams
.cNamedArgs
= 0;
1664 dispparams
.cArgs
= 4;
1665 dispparams
.rgdispidNamedArgs
= NULL
;
1666 dispparams
.rgvarg
= vararg
;
1667 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_VARARG
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
1668 ok_ole_success(hr
, IDispatch_Invoke
);
1670 /* call VarArg, even one (non-optional, non-safearray) named argument is not allowed */
1672 dispparams
.cNamedArgs
= 1;
1673 dispparams
.rgdispidNamedArgs
= &dispidNamed
;
1674 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_VARARG
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
1675 ok(hr
== DISP_E_NONAMEDARGS
, "IDispatch_Invoke should have returned DISP_E_NONAMEDARGS instead of 0x%08x\n", hr
);
1676 dispidNamed
= DISPID_PROPERTYPUT
;
1678 /* call VarArg_Run */
1679 VariantInit(&vararg
[1]);
1680 V_VT(&vararg
[1]) = VT_BSTR
;
1681 V_BSTR(&vararg
[1]) = SysAllocString(szCat
);
1682 VariantInit(&vararg
[0]);
1683 V_VT(&vararg
[0]) = VT_BSTR
;
1684 V_BSTR(&vararg
[0]) = SysAllocString(szSuperman
);
1685 dispparams
.cNamedArgs
= 0;
1686 dispparams
.cArgs
= 2;
1687 dispparams
.rgdispidNamedArgs
= NULL
;
1688 dispparams
.rgvarg
= vararg
;
1689 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_VARARG_RUN
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
1690 ok_ole_success(hr
, IDispatch_Invoke
);
1691 SysFreeString(V_BSTR(&vararg
[1]));
1692 SysFreeString(V_BSTR(&vararg
[0]));
1694 /* call VarArg_Ref_Run */
1695 VariantInit(&vararg
[1]);
1696 V_VT(&vararg
[1]) = VT_BSTR
;
1697 V_BSTR(&vararg
[1]) = SysAllocString(szCat
);
1698 VariantInit(&vararg
[0]);
1699 V_VT(&vararg
[0]) = VT_BSTR
;
1700 V_BSTR(&vararg
[0]) = SysAllocString(szSuperman
);
1701 dispparams
.cNamedArgs
= 0;
1702 dispparams
.cArgs
= 2;
1703 dispparams
.rgdispidNamedArgs
= NULL
;
1704 dispparams
.rgvarg
= vararg
;
1705 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_VARARG_REF_RUN
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, NULL
, NULL
, NULL
);
1706 ok_ole_success(hr
, IDispatch_Invoke
);
1707 SysFreeString(V_BSTR(&vararg
[1]));
1708 SysFreeString(V_BSTR(&vararg
[0]));
1711 dispparams
.cNamedArgs
= 0;
1712 dispparams
.cArgs
= 0;
1713 dispparams
.rgdispidNamedArgs
= NULL
;
1714 dispparams
.rgvarg
= NULL
;
1715 VariantInit(&varresult
);
1716 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_ERROR
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, NULL
, &excepinfo
, NULL
);
1717 ok(hr
== DISP_E_EXCEPTION
, "IDispatch_Invoke should have returned DISP_E_EXCEPTION instead of 0x%08x\n", hr
);
1718 todo_wine_if(tmarshal_todo
)
1719 ok(excepinfo
.wCode
== 0x0 && excepinfo
.scode
== E_NOTIMPL
,
1720 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n",
1721 excepinfo
.wCode
, excepinfo
.scode
);
1722 VariantClear(&varresult
);
1725 pTypeInfo
= NonOleAutomation_GetTypeInfo();
1726 dispparams
.cNamedArgs
= 0;
1727 dispparams
.cArgs
= 0;
1728 dispparams
.rgdispidNamedArgs
= NULL
;
1729 dispparams
.rgvarg
= NULL
;
1730 VariantInit(&varresult
);
1731 hr
= ITypeInfo_Invoke(pTypeInfo
, &NonOleAutomation
, DISPID_NOA_BSTRRET
, DISPATCH_METHOD
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1732 ok_ole_success(hr
, ITypeInfo_Invoke
);
1733 ok(V_VT(&varresult
) == VT_BSTR
, "V_VT(&varresult) should be VT_BSTR instead of %d\n", V_VT(&varresult
));
1734 ok(V_BSTR(&varresult
) != NULL
, "V_BSTR(&varresult) should not be NULL\n");
1736 VariantClear(&varresult
);
1738 dispparams
.cNamedArgs
= 0;
1739 dispparams
.cArgs
= 0;
1740 dispparams
.rgdispidNamedArgs
= NULL
;
1741 dispparams
.rgvarg
= NULL
;
1742 hr
= ITypeInfo_Invoke(pTypeInfo
, &NonOleAutomation
, DISPID_NOA_ERROR
, DISPATCH_METHOD
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1743 ok(hr
== DISP_E_EXCEPTION
, "ITypeInfo_Invoke should have returned DISP_E_EXCEPTION instead of 0x%08x\n", hr
);
1744 ok(V_VT(&varresult
) == VT_EMPTY
, "V_VT(&varresult) should be VT_EMPTY instead of %d\n", V_VT(&varresult
));
1745 todo_wine_if(tmarshal_todo
)
1746 ok(excepinfo
.wCode
== 0x0 && excepinfo
.scode
== E_NOTIMPL
,
1747 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n",
1748 excepinfo
.wCode
, excepinfo
.scode
);
1749 VariantClear(&varresult
);
1751 ITypeInfo_Release(pTypeInfo
);
1753 /* tests call put_Name without named arg */
1754 VariantInit(&vararg
[0]);
1755 dispparams
.cNamedArgs
= 0;
1756 dispparams
.rgdispidNamedArgs
= NULL
;
1757 dispparams
.cArgs
= 1;
1758 dispparams
.rgvarg
= vararg
;
1759 VariantInit(&varresult
);
1760 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_NAME
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_PROPERTYPUT
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1761 ok(hr
== DISP_E_PARAMNOTFOUND
, "IDispatch_Invoke should have returned DISP_E_PARAMNOTFOUND instead of 0x%08x\n", hr
);
1762 VariantClear(&varresult
);
1764 /* tests param type that cannot be coerced */
1765 VariantInit(&vararg
[0]);
1766 V_VT(&vararg
[0]) = VT_UNKNOWN
;
1767 V_UNKNOWN(&vararg
[0]) = NULL
;
1768 dispparams
.cNamedArgs
= 1;
1769 dispparams
.rgdispidNamedArgs
= &dispidNamed
;
1770 dispparams
.cArgs
= 1;
1771 dispparams
.rgvarg
= vararg
;
1772 VariantInit(&varresult
);
1773 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_NAME
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_PROPERTYPUT
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1774 ok(hr
== DISP_E_TYPEMISMATCH
, "IDispatch_Invoke should have returned DISP_E_TYPEMISMATCH instead of 0x%08x\n", hr
);
1775 VariantClear(&varresult
);
1777 /* tests bad param type */
1778 VariantInit(&vararg
[0]);
1779 V_VT(&vararg
[0]) = VT_CLSID
;
1780 V_BYREF(&vararg
[0]) = NULL
;
1781 dispparams
.cNamedArgs
= 1;
1782 dispparams
.rgdispidNamedArgs
= &dispidNamed
;
1783 dispparams
.cArgs
= 1;
1784 dispparams
.rgvarg
= vararg
;
1785 VariantInit(&varresult
);
1786 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_NAME
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_PROPERTYPUT
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1787 ok(hr
== DISP_E_BADVARTYPE
, "IDispatch_Invoke should have returned DISP_E_BADVARTYPE instead of 0x%08x\n", hr
);
1788 VariantClear(&varresult
);
1790 /* tests too small param count */
1791 dispparams
.cNamedArgs
= 0;
1792 dispparams
.rgdispidNamedArgs
= NULL
;
1793 dispparams
.cArgs
= 0;
1794 dispparams
.rgvarg
= NULL
;
1795 VariantInit(&varresult
);
1796 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_DOSOMETHING
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1797 ok(hr
== DISP_E_BADPARAMCOUNT
, "IDispatch_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
1798 VariantClear(&varresult
);
1800 /* tests propget function with large param count */
1801 VariantInit(&vararg
[0]);
1802 V_VT(&vararg
[0]) = VT_BSTR
;
1803 V_BSTR(&vararg
[0]) = NULL
;
1804 V_VT(&vararg
[1]) = VT_I4
;
1805 V_I4(&vararg
[1]) = 1;
1806 dispparams
.cNamedArgs
= 0;
1807 dispparams
.cArgs
= 2;
1808 dispparams
.rgdispidNamedArgs
= NULL
;
1809 dispparams
.rgvarg
= vararg
;
1810 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_STATE
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1811 ok(hr
== DISP_E_NOTACOLLECTION
, "IDispatch_Invoke should have returned DISP_E_NOTACOLLECTION instead of 0x%08x\n", hr
);
1813 /* test propput with lcid */
1815 /* the lcid passed to the function is the first lcid in the typelib header.
1816 Since we don't explicitly set an lcid in the idl, it'll default to US English. */
1817 VariantInit(&vararg
[0]);
1818 V_VT(&vararg
[0]) = VT_I4
;
1819 V_I4(&vararg
[0]) = 0xcafe;
1820 dispparams
.cNamedArgs
= 1;
1821 dispparams
.rgdispidNamedArgs
= &dispidNamed
;
1822 dispparams
.cArgs
= 1;
1823 dispparams
.rgvarg
= vararg
;
1824 VariantInit(&varresult
);
1825 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_PROP_WITH_LCID
, &IID_NULL
, 0x40c, DISPATCH_PROPERTYPUT
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1826 ok_ole_success(hr
, ITypeInfo_Invoke
);
1827 VariantClear(&varresult
);
1829 /* test propget with lcid */
1830 dispparams
.cNamedArgs
= 0;
1831 dispparams
.cArgs
= 0;
1832 dispparams
.rgvarg
= NULL
;
1833 dispparams
.rgdispidNamedArgs
= NULL
;
1834 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_PROP_WITH_LCID
, &IID_NULL
, 0x40c, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1835 ok_ole_success(hr
, ITypeInfo_Invoke
);
1836 ok(V_VT(&varresult
) == VT_I4
, "got %x\n", V_VT(&varresult
));
1837 ok(V_I4(&varresult
) == 0x409, "got %x\n", V_I4(&varresult
));
1838 VariantClear(&varresult
);
1840 /* test propget of INT value */
1841 dispparams
.cNamedArgs
= 0;
1842 dispparams
.cArgs
= 0;
1843 dispparams
.rgvarg
= NULL
;
1844 dispparams
.rgdispidNamedArgs
= NULL
;
1845 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_PROP_INT
, &IID_NULL
, 0x40c, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1846 ok_ole_success(hr
, ITypeInfo_Invoke
);
1847 ok(V_VT(&varresult
) == VT_I4
, "got %x\n", V_VT(&varresult
));
1848 ok(V_I4(&varresult
) == -13, "got %x\n", V_I4(&varresult
));
1849 VariantClear(&varresult
);
1851 /* test propget of INT value */
1852 dispparams
.cNamedArgs
= 0;
1853 dispparams
.cArgs
= 0;
1854 dispparams
.rgvarg
= NULL
;
1855 dispparams
.rgdispidNamedArgs
= NULL
;
1856 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_PROP_UINT
, &IID_NULL
, 0x40c, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1857 ok_ole_success(hr
, ITypeInfo_Invoke
);
1858 ok(V_VT(&varresult
) == VT_UI4
, "got %x\n", V_VT(&varresult
));
1859 ok(V_UI4(&varresult
) == 42, "got %x\n", V_UI4(&varresult
));
1860 VariantClear(&varresult
);
1862 /* test byref marshalling */
1864 VariantInit(&vararg
[0]);
1865 V_VT(&vararg
[0]) = VT_UI4
|VT_BYREF
;
1866 V_UI4REF(&vararg
[0]) = &uval
;
1867 dispparams
.cNamedArgs
= 0;
1868 dispparams
.cArgs
= 1;
1869 dispparams
.rgvarg
= vararg
;
1870 dispparams
.rgdispidNamedArgs
= NULL
;
1871 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_BYREF_UINT
, &IID_NULL
, LOCALE_NEUTRAL
, DISPATCH_METHOD
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1872 ok_ole_success(hr
, ITypeInfo_Invoke
);
1873 ok(V_VT(&varresult
) == VT_EMPTY
, "varresult should be VT_EMPTY\n");
1874 ok(V_VT(&vararg
[0]) == (VT_UI4
|VT_BYREF
), "arg VT not unmarshalled correctly: %x\n", V_VT(&vararg
[0]));
1875 ok(V_UI4REF(&vararg
[0]) == &uval
, "Byref pointer not preserved: %p/%p\n", &uval
, V_UI4REF(&vararg
[0]));
1876 ok(*V_UI4REF(&vararg
[0]) == 42, "Expected 42 to be returned instead of %u\n", *V_UI4REF(&vararg
[0]));
1877 VariantClear(&varresult
);
1878 VariantClear(&vararg
[0]);
1880 /* test propput with optional argument. */
1881 VariantInit(&vararg
[0]);
1882 V_VT(&vararg
[0]) = VT_I4
;
1883 V_I4(&vararg
[0]) = 0xcafe;
1884 dispparams
.cNamedArgs
= 1;
1885 dispparams
.rgdispidNamedArgs
= &dispidNamed
;
1886 dispparams
.cArgs
= 1;
1887 dispparams
.rgvarg
= vararg
;
1888 VariantInit(&varresult
);
1889 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_PROP_OPT_ARG
, &IID_NULL
, 0x40c, DISPATCH_PROPERTYPUT
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1890 ok_ole_success(hr
, ITypeInfo_Invoke
);
1891 VariantClear(&varresult
);
1893 /* test propput with required argument. */
1894 VariantInit(&vararg
[0]);
1895 VariantInit(&vararg
[1]);
1896 V_VT(&vararg
[0]) = VT_I4
;
1897 V_I4(&vararg
[0]) = 0x1234;
1898 V_VT(&vararg
[1]) = VT_I4
;
1899 V_I4(&vararg
[1]) = 0x5678;
1900 dispparams
.cNamedArgs
= 1;
1901 dispparams
.rgdispidNamedArgs
= &dispidNamed
;
1902 dispparams
.cArgs
= 2;
1903 dispparams
.rgvarg
= vararg
;
1904 VariantInit(&varresult
);
1905 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_PROP_REQ_ARG
, &IID_NULL
, 0x40c, DISPATCH_PROPERTYPUT
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1906 ok_ole_success(hr
, ITypeInfo_Invoke
);
1907 VariantClear(&varresult
);
1909 /* restricted member */
1910 dispparams
.cNamedArgs
= 0;
1911 dispparams
.rgdispidNamedArgs
= NULL
;
1912 dispparams
.cArgs
= 0;
1913 dispparams
.rgvarg
= NULL
;
1914 VariantInit(&varresult
);
1915 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_RESTRICTED
, &IID_NULL
, 0x40c, DISPATCH_METHOD
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1916 ok( hr
== DISP_E_MEMBERNOTFOUND
, "got %08x\n", hr
);
1917 VariantClear(&varresult
);
1919 /* restricted member with -ve memid (not restricted) */
1920 dispparams
.cNamedArgs
= 0;
1921 dispparams
.rgdispidNamedArgs
= NULL
;
1922 dispparams
.cArgs
= 0;
1923 dispparams
.rgvarg
= NULL
;
1924 VariantInit(&varresult
);
1925 hr
= IDispatch_Invoke(pDispatch
, DISPID_TM_NEG_RESTRICTED
, &IID_NULL
, 0x40c, DISPATCH_METHOD
, &dispparams
, &varresult
, &excepinfo
, NULL
);
1926 ok( hr
== S_OK
, "got %08x\n", hr
);
1927 ok(V_VT(&varresult
) == VT_I4
, "got %x\n", V_VT(&varresult
));
1928 ok(V_I4(&varresult
) == DISPID_TM_NEG_RESTRICTED
, "got %x\n", V_I4(&varresult
));
1929 VariantClear(&varresult
);
1931 IDispatch_Release(pDispatch
);
1932 IWidget_Release(pWidget
);
1934 trace("calling end_host_object\n");
1935 end_host_object(tid
, thread
);
1938 static void test_DispCallFunc(void)
1940 static const WCHAR szEmpty
[] = { 0 };
1941 VARTYPE rgvt
[] = { VT_R8
, VT_BSTR
, VT_BSTR
, VT_VARIANT
|VT_BYREF
};
1942 VARIANTARG vararg
[4];
1944 VARIANTARG
*rgpvarg
[4] = { &vararg
[0], &vararg
[1], &vararg
[2], &vararg
[3] };
1945 VARIANTARG varresult
;
1947 IWidget
*pWidget
= Widget_Create();
1948 V_VT(&vararg
[0]) = VT_R8
;
1949 V_R8(&vararg
[0]) = 3.141;
1950 V_VT(&vararg
[1]) = VT_BSTR
;
1951 V_BSTRREF(&vararg
[1]) = CoTaskMemAlloc(sizeof(BSTR
));
1952 V_VT(&vararg
[2]) = VT_BSTR
;
1953 V_BSTR(&vararg
[2]) = SysAllocString(szEmpty
);
1954 V_VT(&vararg
[3]) = VT_VARIANT
|VT_BYREF
;
1955 V_VARIANTREF(&vararg
[3]) = &varref
;
1956 V_VT(&varref
) = VT_ERROR
;
1957 V_ERROR(&varref
) = DISP_E_PARAMNOTFOUND
;
1958 VariantInit(&varresult
);
1959 hr
= DispCallFunc(pWidget
, 9*sizeof(void*), CC_STDCALL
, VT_UI4
, 4, rgvt
, rgpvarg
, &varresult
);
1960 ok_ole_success(hr
, DispCallFunc
);
1961 VariantClear(&varresult
);
1962 SysFreeString(*V_BSTRREF(&vararg
[1]));
1963 CoTaskMemFree(V_BSTRREF(&vararg
[1]));
1964 VariantClear(&vararg
[2]);
1965 IWidget_Release(pWidget
);
1968 static void test_StaticWidget(void)
1970 ITypeInfo
*type_info
;
1971 DISPPARAMS dispparams
;
1972 VARIANTARG vararg
[4];
1973 EXCEPINFO excepinfo
;
1977 type_info
= get_type_info(&IID_IStaticWidget
);
1980 dispparams
.cNamedArgs
= 0;
1981 dispparams
.cArgs
= 1;
1982 dispparams
.rgdispidNamedArgs
= NULL
;
1983 dispparams
.rgvarg
= vararg
;
1984 V_VT(vararg
) = VT_DISPATCH
;
1985 V_DISPATCH(vararg
) = (IDispatch
*)&TestDualDisp
;
1986 VariantInit(&varresult
);
1987 hr
= ITypeInfo_Invoke(type_info
, &StaticWidget
, DISPID_TM_TESTDUAL
, DISPATCH_METHOD
,
1988 &dispparams
, &varresult
, &excepinfo
, NULL
);
1989 ok_ole_success(hr
, IDispatch_Invoke
);
1990 ok(V_VT(&varresult
) == VT_EMPTY
, "vt %x\n", V_VT(&varresult
));
1991 VariantClear(&varresult
);
1993 /* call TestSecondIface */
1994 dispparams
.cNamedArgs
= 0;
1995 dispparams
.cArgs
= 1;
1996 dispparams
.rgdispidNamedArgs
= NULL
;
1997 dispparams
.rgvarg
= vararg
;
1998 V_VT(vararg
) = VT_DISPATCH
;
1999 V_DISPATCH(vararg
) = (IDispatch
*)&TestDualDisp
;
2000 VariantInit(&varresult
);
2001 hr
= ITypeInfo_Invoke(type_info
, &StaticWidget
, DISPID_TM_TESTSECONDIFACE
, DISPATCH_METHOD
,
2002 &dispparams
, &varresult
, &excepinfo
, NULL
);
2003 ok_ole_success(hr
, IDispatch_Invoke
);
2004 ok(V_VT(&varresult
) == VT_EMPTY
, "vt %x\n", V_VT(&varresult
));
2005 VariantClear(&varresult
);
2007 ITypeInfo_Release(type_info
);
2010 static void test_libattr(void)
2016 hr
= LoadRegTypeLib(&LIBID_TestTypelib
, 2, 5, LOCALE_NEUTRAL
, &pTypeLib
);
2017 ok_ole_success(hr
, LoadRegTypeLib
);
2021 hr
= ITypeLib_GetLibAttr(pTypeLib
, &pattr
);
2022 ok_ole_success(hr
, GetLibAttr
);
2025 ok(pattr
->lcid
== MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
), "lcid %x\n", pattr
->lcid
);
2027 ITypeLib_ReleaseTLibAttr(pTypeLib
, pattr
);
2030 ITypeLib_Release(pTypeLib
);
2033 static void test_external_connection(void)
2035 IStream
*stream
, *stream2
;
2036 ITestSecondDisp
*second
;
2042 static const LARGE_INTEGER zero
;
2044 trace("Testing IExternalConnection...\n");
2046 external_connections
= 0;
2048 /* Marshaling an interface increases external connection count. */
2049 expect_last_release_closes
= FALSE
;
2050 hres
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
2051 ok(hres
== S_OK
, "CreateStreamOnHGlobal failed: %08x\n", hres
);
2052 tid
= start_host_object(stream
, &IID_ItestDual
, (IUnknown
*)&TestDual
, MSHLFLAGS_NORMAL
, &thread
);
2053 ok(external_connections
== 1, "external_connections = %d\n", external_connections
);
2055 IStream_Seek(stream
, zero
, STREAM_SEEK_SET
, NULL
);
2056 hres
= CoUnmarshalInterface(stream
, &IID_ItestDual
, (void**)&iface
);
2057 todo_wine_if(tmarshal_todo
)
2058 ok(hres
== S_OK
, "CoUnmarshalInterface failed: %08x\n", hres
);
2059 ok(external_connections
== 1, "external_connections = %d\n", external_connections
);
2061 IStream_Release(stream
);
2062 ok(external_connections
== 1, "external_connections = %d\n", external_connections
);
2064 /* Creating a stub for new iface causes new external connection. */
2065 hres
= ItestDual_QueryInterface(iface
, &IID_ITestSecondDisp
, (void**)&second
);
2066 todo_wine_if(tmarshal_todo
)
2067 ok(hres
== S_OK
, "Could not get ITestSecondDisp iface: %08x\n", hres
);
2069 ok(external_connections
== 2, "external_connections = %d\n", external_connections
);
2072 ITestSecondDisp_Release(second
);
2074 ok(external_connections
== 2, "external_connections = %d\n", external_connections
);
2076 expect_last_release_closes
= TRUE
;
2077 ItestDual_Release(iface
);
2078 todo_wine_if(tmarshal_todo
)
2079 ok(external_connections
== 0, "external_connections = %d\n", external_connections
);
2081 end_host_object(tid
, thread
);
2083 /* A test with direct CoMarshalInterface call. */
2084 hres
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
2085 ok(hres
== S_OK
, "CreateStreamOnHGlobal failed: %08x\n", hres
);
2087 expect_last_release_closes
= FALSE
;
2088 hres
= CoMarshalInterface(stream
, &IID_ItestDual
, (IUnknown
*)&TestDual
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
2089 ok(hres
== S_OK
, "CoMarshalInterface failed: %08x\n", hres
);
2090 todo_wine_if(tmarshal_todo
)
2091 ok(external_connections
== 1, "external_connections = %d\n", external_connections
);
2093 expect_last_release_closes
= TRUE
;
2094 IStream_Seek(stream
, zero
, STREAM_SEEK_SET
, NULL
);
2095 hres
= CoReleaseMarshalData(stream
);
2096 ok(hres
== S_OK
, "CoReleaseMarshalData failed: %08x\n", hres
);
2097 todo_wine_if(tmarshal_todo
)
2098 ok(external_connections
== 0, "external_connections = %d\n", external_connections
);
2100 /* Two separated marshal data are still one external connection. */
2101 hres
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream2
);
2102 ok(hres
== S_OK
, "CreateStreamOnHGlobal failed: %08x\n", hres
);
2104 expect_last_release_closes
= FALSE
;
2105 IStream_Seek(stream
, zero
, STREAM_SEEK_SET
, NULL
);
2106 hres
= CoMarshalInterface(stream
, &IID_ItestDual
, (IUnknown
*)&TestDual
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
2107 ok(hres
== S_OK
, "CoMarshalInterface failed: %08x\n", hres
);
2108 todo_wine_if(tmarshal_todo
)
2109 ok(external_connections
== 1, "external_connections = %d\n", external_connections
);
2111 hres
= CoMarshalInterface(stream2
, &IID_ItestDual
, (IUnknown
*)&TestDual
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
2112 ok(hres
== S_OK
, "CoMarshalInterface failed: %08x\n", hres
);
2113 todo_wine_if(tmarshal_todo
)
2114 ok(external_connections
== 1, "external_connections = %d\n", external_connections
);
2116 IStream_Seek(stream
, zero
, STREAM_SEEK_SET
, NULL
);
2117 hres
= CoReleaseMarshalData(stream
);
2118 ok(hres
== S_OK
, "CoReleaseMarshalData failed: %08x\n", hres
);
2119 todo_wine_if(tmarshal_todo
)
2120 ok(external_connections
== 1, "external_connections = %d\n", external_connections
);
2122 expect_last_release_closes
= TRUE
;
2123 IStream_Seek(stream2
, zero
, STREAM_SEEK_SET
, NULL
);
2124 hres
= CoReleaseMarshalData(stream2
);
2125 ok(hres
== S_OK
, "CoReleaseMarshalData failed: %08x\n", hres
);
2126 todo_wine_if(tmarshal_todo
)
2127 ok(external_connections
== 0, "external_connections = %d\n", external_connections
);
2129 IStream_Release(stream
);
2130 IStream_Release(stream2
);
2132 /* Weak table marshaling does not increment external connections */
2133 hres
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
2134 ok(hres
== S_OK
, "CreateStreamOnHGlobal failed: %08x\n", hres
);
2136 hres
= CoMarshalInterface(stream
, &IID_ItestDual
, (IUnknown
*)&TestDual
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_TABLEWEAK
);
2137 ok(hres
== S_OK
, "CoMarshalInterface failed: %08x\n", hres
);
2138 todo_wine_if(tmarshal_todo
)
2139 ok(external_connections
== 0, "external_connections = %d\n", external_connections
);
2141 IStream_Seek(stream
, zero
, STREAM_SEEK_SET
, NULL
);
2142 hres
= CoUnmarshalInterface(stream
, &IID_ItestDual
, (void**)&iface
);
2143 ok(hres
== S_OK
, "CoUnmarshalInterface failed: %08x\n", hres
);
2144 todo_wine_if(tmarshal_todo
)
2145 ok(external_connections
== 0, "external_connections = %d\n", external_connections
);
2146 ItestDual_Release(iface
);
2148 IStream_Seek(stream
, zero
, STREAM_SEEK_SET
, NULL
);
2149 hres
= CoReleaseMarshalData(stream
);
2150 ok(hres
== S_OK
, "CoReleaseMarshalData failed: %08x\n", hres
);
2151 todo_wine_if(tmarshal_todo
)
2152 ok(external_connections
== 0, "external_connections = %d\n", external_connections
);
2154 IStream_Release(stream
);
2157 START_TEST(tmarshal
)
2160 HANDLE hOleaut32
= GetModuleHandleA("oleaut32.dll");
2161 pVarAdd
= (void*)GetProcAddress(hOleaut32
, "VarAdd");
2163 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
2165 hr
= register_current_module_typelib();
2169 win_skip("Registration of the test typelib failed, skipping tests\n");
2173 test_typelibmarshal();
2174 test_DispCallFunc();
2175 test_StaticWidget();
2177 test_external_connection();
2179 hr
= UnRegisterTypeLib(&LIBID_TestTypelib
, 2, 5, LOCALE_NEUTRAL
,
2180 sizeof(void*) == 8 ? SYS_WIN64
: SYS_WIN32
);
2181 ok_ole_success(hr
, UnRegisterTypeLib
);