ReactOS 0.4.17-dev-357-ga8f14ff
tmarshal.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2005-2006 Robert Shearman for CodeWeavers
3 *
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.
8 *
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.
13 *
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
17 *
18 */
19
20#include <stdbool.h>
21#include <math.h>
22
23#define COBJMACROS
24#define CONST_VTABLE
25
26#include <windows.h>
27#include <ocidl.h>
28#include <stdio.h>
29
30#include "wine/test.h"
31
32#include "tmarshal.h"
33
34#define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error %#08lx\n", hr)
35static inline void release_iface_(unsigned int line, void *iface)
36{
37 ULONG ref = IUnknown_Release((IUnknown *)iface);
38 ok_(__FILE__, line)(!ref, "Got outstanding refcount %ld.\n", ref);
39 if (ref == 1) IUnknown_Release((IUnknown *)iface);
40}
41#define release_iface(a) release_iface_(__LINE__, a)
42
43static const WCHAR test_bstr1[] = {'f','o','o',0,'b','a','r'};
44static const WCHAR test_bstr2[] = {'t','e','s','t',0};
45static const WCHAR test_bstr3[] = {'q','u','x',0};
46static const WCHAR test_bstr4[] = {'a','b','c',0};
47
48static const MYSTRUCT test_mystruct1 = {0x12345678, 0xdeadbeef98765432ull, {0,1,2,3,4,5,6,7}};
49static const MYSTRUCT test_mystruct2 = {0x91827364, 0x8877665544332211ull, {3,6,1,4,0,1,3,0}};
50static const MYSTRUCT test_mystruct3 = {0x1a1b1c1d, 0x1e1f101112131415ull, {9,2,4,5,6,5,1,3}};
51static const MYSTRUCT test_mystruct4 = {0x2a2b2c2d, 0x2e2f202122232425ull, {0,4,6,7,3,6,7,4}};
52static const MYSTRUCT test_mystruct5 = {0x3a3b3c3d, 0x3e3f303132333435ull, {1,6,7,3,8,4,6,5}};
53static const MYSTRUCT test_mystruct6 = {0x4a4b4c4d, 0x4e4f404142434445ull, {3,6,5,3,4,8,0,9}};
54static const MYSTRUCT test_mystruct7 = {0x5a5b5c5d, 0x5e5f505152535455ull, {1,8,4,4,4,2,3,1}};
55
56static const struct thin test_thin_struct = {-456, 78};
57
58static const RECT test_rect1 = {1,2,3,4};
59static const RECT test_rect2 = {5,6,7,8};
60static const RECT test_rect3 = {9,10,11,12};
61static const RECT test_rect4 = {13,14,15,16};
62static const RECT test_rect5 = {17,18,19,20};
63static const RECT test_rect6 = {21,22,23,24};
64static const RECT test_rect7 = {25,26,27,28};
65
66static const array_t test_array1 = {1,2,3,4};
67static const array_t test_array2 = {5,6,7,8};
68static const array_t test_array3 = {9,10,11,12};
69static const array_t test_array4 = {13,14,15,16};
70static const array_t test_array5 = {17,18,19,20};
71static const array_t test_array6 = {21,22,23,24};
72
73#define RELEASEMARSHALDATA WM_USER
74
76{
78 IID iid;
80 MSHLFLAGS marshal_flags;
83};
84
86{
87 struct host_object_data *data = p;
88 HRESULT hr;
89 MSG msg;
90
92
93 if (data->filter)
94 {
95 IMessageFilter * prev_filter = NULL;
96 hr = CoRegisterMessageFilter(data->filter, &prev_filter);
97 if (prev_filter) IMessageFilter_Release(prev_filter);
99 }
100
101 hr = CoMarshalInterface(data->stream, &data->iid, data->object, MSHCTX_INPROC, NULL, data->marshal_flags);
103
104 /* force the message queue to be created before signaling parent thread */
106
107 SetEvent(data->marshal_event);
108
109 while (GetMessageA(&msg, NULL, 0, 0))
110 {
111 if (msg.hwnd == NULL && msg.message == RELEASEMARSHALDATA)
112 {
113 trace("releasing marshal data\n");
114 CoReleaseMarshalData(data->stream);
115 SetEvent((HANDLE)msg.lParam);
116 }
117 else
119 }
120
122
124
125 return hr;
126}
127
129{
130 DWORD tid = 0;
132 struct host_object_data *data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data));
133
134 data->stream = stream;
135 data->iid = *riid;
136 data->object = object;
137 data->marshal_flags = marshal_flags;
138 data->marshal_event = marshal_event;
139 data->filter = filter;
140
142
143 /* wait for marshaling to complete before returning */
146
147 return tid;
148}
149
151{
153}
154
155#if 0 /* not used */
156/* asks thread to release the marshal data because it has to be done by the
157 * same thread that marshaled the interface in the first place. */
158static void release_host_object(DWORD tid)
159{
164}
165#endif
166
168{
170 ok(ret, "PostThreadMessage failed with error %ld\n", GetLastError());
171 /* be careful of races - don't return until hosting thread has terminated */
174}
175
178
180{
181 ok(0, "unexpected call\n");
182 *ppv = NULL;
183 return E_NOINTERFACE;
184}
185
187{
188 return 2;
189}
190
192{
193 return 1;
194}
195
197{
198 trace("add connection\n");
199
200 ok(extconn == EXTCONN_STRONG, "extconn = %ld\n", extconn);
201 ok(!reserved, "reserved = %lx\n", reserved);
202 return ++external_connections;
203}
204
206 DWORD reserved, BOOL fLastReleaseCloses)
207{
208 trace("release connection\n");
209
210 ok(extconn == EXTCONN_STRONG, "extconn = %ld\n", extconn);
211 ok(!reserved, "reserved = %lx\n", reserved);
212
213 ok(fLastReleaseCloses == expect_last_release_closes, "fLastReleaseCloses = %x, expected %x\n",
214 fLastReleaseCloses, expect_last_release_closes);
215 return --external_connections;
216}
217
218static const IExternalConnectionVtbl ExternalConnectionVtbl = {
224};
225
227
228static ItestDual TestDual, TestDualDisp;
229
230static HRESULT WINAPI TestSecondIface_QueryInterface(ITestSecondIface *iface, REFIID riid, void **ppv)
231{
232 return ItestDual_QueryInterface(&TestDual, riid, ppv);
233}
234
235static ULONG WINAPI TestSecondIface_AddRef(ITestSecondIface *iface)
236{
237 return 2;
238}
239
240static ULONG WINAPI TestSecondIface_Release(ITestSecondIface *iface)
241{
242 return 1;
243}
244
245static HRESULT WINAPI TestSecondIface_test(ITestSecondIface *iface)
246{
247 return 1;
248}
249
250static const ITestSecondIfaceVtbl TestSecondIfaceVtbl = {
255};
256
257static ITestSecondIface TestSecondIface = { &TestSecondIfaceVtbl };
258
259static HRESULT WINAPI TestSecondDisp_QueryInterface(ITestSecondDisp *iface, REFIID riid, void **ppv)
260{
261 return ItestDual_QueryInterface(&TestDual, riid, ppv);
262}
263
264static ULONG WINAPI TestSecondDisp_AddRef(ITestSecondDisp *iface)
265{
266 return 2;
267}
268
269static ULONG WINAPI TestSecondDisp_Release(ITestSecondDisp *iface)
270{
271 return 1;
272}
273
274static HRESULT WINAPI TestSecondDisp_GetTypeInfoCount(ITestSecondDisp *iface, UINT *pctinfo)
275{
276 ok(0, "unexpected call\n");
277 return E_NOTIMPL;
278}
279
280static HRESULT WINAPI TestSecondDisp_GetTypeInfo(ITestSecondDisp *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
281{
282 ok(0, "unexpected call\n");
283 return E_NOTIMPL;
284}
285
286static HRESULT WINAPI TestSecondDisp_GetIDsOfNames(ITestSecondDisp *iface, REFIID riid, LPOLESTR *rgszNames,
287 UINT cNames, LCID lcid, DISPID *rgDispId)
288{
289 ok(0, "unexpected call\n");
290 return E_NOTIMPL;
291}
292
293static HRESULT WINAPI TestSecondDisp_Invoke(ITestSecondDisp *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
294 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
295 UINT *puArgErr)
296{
297 ok(0, "unexpected call\n");
298 return E_NOTIMPL;
299}
300
301static HRESULT WINAPI TestSecondDisp_test(ITestSecondDisp *iface)
302{
303 ok(0, "unexpected call\n");
304 return E_NOTIMPL;
305}
306
307static ITestSecondDispVtbl TestSecondDispVtbl = {
316};
317
318static ITestSecondDisp TestSecondDisp = { &TestSecondDispVtbl };
319
320static HRESULT WINAPI TestDual_QueryInterface(ItestDual *iface, REFIID riid, void **ppvObject)
321{
323 *ppvObject = &TestDualDisp;
324 return S_OK;
325 }else if(IsEqualGUID(riid, &IID_ItestDual)) {
326 *ppvObject = &TestDual;
327 return S_OK;
328 }else if(IsEqualGUID(riid, &IID_ITestSecondIface)) {
329 *ppvObject = &TestSecondIface;
330 return S_OK;
331 }else if(IsEqualGUID(riid, &IID_ITestSecondDisp)) {
332 *ppvObject = &TestSecondDisp;
333 return S_OK;
334 }else if (IsEqualGUID(riid, &IID_IExternalConnection)) {
335 trace("QI external connection\n");
336 *ppvObject = &ExternalConnection;
337 return S_OK;
338 }
339
340 *ppvObject = NULL;
341 return E_NOINTERFACE;
342}
343
344static ULONG WINAPI TestDual_AddRef(ItestDual *iface)
345{
346 return 2;
347}
348
349static ULONG WINAPI TestDual_Release(ItestDual *iface)
350{
351 return 1;
352}
353
354static HRESULT WINAPI TestDual_GetTypeInfoCount(ItestDual *iface, UINT *pctinfo)
355{
356 ok(0, "unexpected call\n");
357 return E_NOTIMPL;
358}
359
360static HRESULT WINAPI TestDual_GetTypeInfo(ItestDual *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
361{
362 ok(0, "unexpected call\n");
363 return E_NOTIMPL;
364}
365
366static HRESULT WINAPI TestDual_GetIDsOfNames(ItestDual *iface, REFIID riid, LPOLESTR *rgszNames,
367 UINT cNames, LCID lcid, DISPID *rgDispId)
368{
369 ok(0, "unexpected call\n");
370 return E_NOTIMPL;
371}
372
373static HRESULT WINAPI TestDual_Invoke(ItestDual *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
374 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
375 UINT *puArgErr)
376{
377 ok(0, "unexpected call\n");
378 return E_NOTIMPL;
379}
380
381static ItestDualVtbl TestDualVtbl = {
389};
390
391static ItestDual TestDual = { &TestDualVtbl };
392static ItestDual TestDualDisp = { &TestDualVtbl };
393
395{
396 ISomethingFromDispatch ISomethingFromDispatch_iface;
399};
400
401static inline struct disp_obj *impl_from_ISomethingFromDispatch(ISomethingFromDispatch *iface)
402{
404}
405
406static HRESULT WINAPI disp_obj_QueryInterface(ISomethingFromDispatch *iface, REFIID iid, void **out)
407{
409
410 if (!obj->support_idispatch)
411 ok(!IsEqualGUID(iid, &IID_IDispatch), "Expected no query for IDispatch.\n");
412
414 || IsEqualGUID(iid, &IID_ISomethingFromDispatch)
415 || IsEqualGUID(iid, &DIID_ItestIF4))
416 {
417 *out = iface;
418 ISomethingFromDispatch_AddRef(iface);
419 return S_OK;
420 }
421
422 *out = NULL;
423 return E_NOINTERFACE;
424}
425
426static ULONG WINAPI disp_obj_AddRef(ISomethingFromDispatch *iface)
427{
429 return ++obj->ref;
430}
431
432static ULONG WINAPI disp_obj_Release(ISomethingFromDispatch *iface)
433{
435 LONG ref = --obj->ref;
436 if (!ref)
438 return ref;
439}
440
441static HRESULT WINAPI disp_obj_GetTypeInfoCount(ISomethingFromDispatch *iface, UINT *count)
442{
443 ok(0, "unexpected call\n");
444 return E_NOTIMPL;
445}
446
447static HRESULT WINAPI disp_obj_GetTypeInfo(ISomethingFromDispatch *iface,
449{
450 ok(index == 0xdeadbeef, "Got unexpected index %#x.\n", index);
451 return 0xbeefdead;
452}
453
454static HRESULT WINAPI disp_obj_GetIDsOfNames(ISomethingFromDispatch *iface,
455 REFIID iid, LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
456{
457 ok(0, "unexpected call\n");
458 return E_NOTIMPL;
459}
460
461static HRESULT WINAPI disp_obj_Invoke(ISomethingFromDispatch *iface, DISPID id, REFIID iid, LCID lcid,
462 WORD flags, DISPPARAMS *dispparams, VARIANT *result, EXCEPINFO *excepinfo, UINT *errarg)
463{
464 ok(0, "unexpected call\n");
465 return E_NOTIMPL;
466}
467
468static HRESULT WINAPI disp_obj_anotherfn(ISomethingFromDispatch *iface)
469{
470 return 0x01234567;
471}
472
473static const ISomethingFromDispatchVtbl disp_obj_vtbl =
474{
483};
484
485static ISomethingFromDispatch *create_disp_obj2(bool support_idispatch)
486{
487 struct disp_obj *obj = CoTaskMemAlloc(sizeof(*obj));
488 obj->ISomethingFromDispatch_iface.lpVtbl = &disp_obj_vtbl;
489 obj->ref = 1;
490 obj->support_idispatch = support_idispatch;
491 return &obj->ISomethingFromDispatch_iface;
492}
493
494static ISomethingFromDispatch *create_disp_obj(void)
495{
496 return create_disp_obj2(true);
497}
498
500{
504};
505
506static inline struct coclass_obj *impl_from_ICoclass1(ICoclass1 *iface)
507{
508 return CONTAINING_RECORD(iface, struct coclass_obj, ICoclass1_iface);
509}
510
511static inline struct coclass_obj *impl_from_ICoclass2(ICoclass2 *iface)
512{
513 return CONTAINING_RECORD(iface, struct coclass_obj, ICoclass2_iface);
514}
515
516static HRESULT WINAPI coclass1_QueryInterface(ICoclass1 *iface, REFIID iid, void **out)
517{
518 struct coclass_obj *obj = impl_from_ICoclass1(iface);
519
520 if (IsEqualGUID(iid, &IID_IUnknown)
521 || IsEqualGUID(iid, &IID_IDispatch)
522 || IsEqualGUID(iid, &IID_ICoclass1))
523 {
524 *out = iface;
525 ICoclass1_AddRef(iface);
526 return S_OK;
527 }
528 else if (IsEqualGUID(iid, &IID_ICoclass2))
529 {
530 *out = &obj->ICoclass2_iface;
531 ICoclass2_AddRef(*out);
532 return S_OK;
533 }
534
535 *out = NULL;
536 return E_NOINTERFACE;
537}
538
539static ULONG WINAPI coclass1_AddRef(ICoclass1 *iface)
540{
541 struct coclass_obj *obj = impl_from_ICoclass1(iface);
542 return ++obj->ref;
543}
544
545static ULONG WINAPI coclass1_Release(ICoclass1 *iface)
546{
547 struct coclass_obj *obj = impl_from_ICoclass1(iface);
548 LONG ref = --obj->ref;
549 if (!ref)
551 return ref;
552}
553
555{
556 ok(0, "unexpected call\n");
557 return E_NOTIMPL;
558}
559
562{
563 ok(index == 0xdeadbeef, "Got unexpected index %#x.\n", index);
564 return 0xbeefdead;
565}
566
567static HRESULT WINAPI coclass1_GetIDsOfNames(ICoclass1 *iface, REFIID iid,
568 LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
569{
570 ok(0, "unexpected call\n");
571 return E_NOTIMPL;
572}
573
574static HRESULT WINAPI coclass1_Invoke(ICoclass1 *iface, DISPID id, REFIID iid, LCID lcid,
575 WORD flags, DISPPARAMS *dispparams, VARIANT *result, EXCEPINFO *excepinfo, UINT *errarg)
576{
577 ok(0, "unexpected call\n");
578 return E_NOTIMPL;
579}
580
581static HRESULT WINAPI coclass1_test(ICoclass1 *iface)
582{
583 return 1;
584}
585
586static HRESULT WINAPI coclass2_QueryInterface(ICoclass2 *iface, REFIID iid, void **out)
587{
588 struct coclass_obj *obj = impl_from_ICoclass2(iface);
589 return ICoclass1_QueryInterface(&obj->ICoclass1_iface, iid, out);
590}
591
592static ULONG WINAPI coclass2_AddRef(ICoclass2 *iface)
593{
594 struct coclass_obj *obj = impl_from_ICoclass2(iface);
595 return ICoclass1_AddRef(&obj->ICoclass1_iface);
596}
597
598static ULONG WINAPI coclass2_Release(ICoclass2 *iface)
599{
600 struct coclass_obj *obj = impl_from_ICoclass2(iface);
601 return ICoclass1_Release(&obj->ICoclass1_iface);
602}
603
605{
606 ok(0, "unexpected call\n");
607 return E_NOTIMPL;
608}
609
612{
613 ok(index == 0xdeadbeef, "Got unexpected index %#x.\n", index);
614 return 0xbeefdead;
615}
616
617static HRESULT WINAPI coclass2_GetIDsOfNames(ICoclass2 *iface, REFIID iid,
618 LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
619{
620 ok(0, "unexpected call\n");
621 return E_NOTIMPL;
622}
623
624static HRESULT WINAPI coclass2_Invoke(ICoclass2 *iface, DISPID id, REFIID iid, LCID lcid,
625 WORD flags, DISPPARAMS *dispparams, VARIANT *result, EXCEPINFO *excepinfo, UINT *errarg)
626{
627 ok(0, "unexpected call\n");
628 return E_NOTIMPL;
629}
630
631static HRESULT WINAPI coclass2_test(ICoclass2 *iface)
632{
633 return 2;
634}
635
636static const ICoclass1Vtbl coclass1_vtbl =
637{
646};
647
648static const ICoclass2Vtbl coclass2_vtbl =
649{
658};
659
660static struct coclass_obj *create_coclass_obj(void)
661{
662 struct coclass_obj *obj = CoTaskMemAlloc(sizeof(*obj));
663 obj->ICoclass1_iface.lpVtbl = &coclass1_vtbl;
664 obj->ICoclass2_iface.lpVtbl = &coclass2_vtbl;
665 obj->ref = 1;
666 return obj;
667};
668
669static int testmode;
670
671typedef struct Widget
672{
677
678static inline Widget *impl_from_IWidget(IWidget *iface)
679{
680 return CONTAINING_RECORD(iface, Widget, IWidget_iface);
681}
682
684 IWidget *iface,
685 /* [in] */ REFIID riid,
686 /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
687{
689 {
690 IWidget_AddRef(iface);
691 *ppvObject = iface;
692 return S_OK;
693 }
694 else
695 {
696 *ppvObject = NULL;
697 return E_NOINTERFACE;
698 }
699}
700
702 IWidget *iface)
703{
704 Widget *This = impl_from_IWidget(iface);
705
706 return InterlockedIncrement(&This->refs);
707}
708
710 IWidget *iface)
711{
712 Widget *This = impl_from_IWidget(iface);
713 ULONG refs = InterlockedDecrement(&This->refs);
714 if (!refs)
715 {
716 IUnknown_Release(This->pDispatchUnknown);
717 memset(This, 0xcc, sizeof(*This));
719 trace("Widget destroyed!\n");
720 }
721
722 return refs;
723}
724
726 IWidget *iface,
727 /* [out] */ UINT __RPC_FAR *pctinfo)
728{
729 Widget *This = impl_from_IWidget(iface);
730 IDispatch *pDispatch;
731 HRESULT hr = IUnknown_QueryInterface(This->pDispatchUnknown, &IID_IDispatch, (void **)&pDispatch);
732 if (SUCCEEDED(hr))
733 {
734 hr = IDispatch_GetTypeInfoCount(pDispatch, pctinfo);
735 IDispatch_Release(pDispatch);
736 }
737 return hr;
738}
739
741 IWidget __RPC_FAR * iface,
742 /* [in] */ UINT iTInfo,
743 /* [in] */ LCID lcid,
744 /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
745{
746 Widget *This = impl_from_IWidget(iface);
747 IDispatch *pDispatch;
748 HRESULT hr = IUnknown_QueryInterface(This->pDispatchUnknown, &IID_IDispatch, (void **)&pDispatch);
749 if (SUCCEEDED(hr))
750 {
751 hr = IDispatch_GetTypeInfo(pDispatch, iTInfo, lcid, ppTInfo);
752 IDispatch_Release(pDispatch);
753 }
754 return hr;
755}
756
758 IWidget __RPC_FAR * iface,
759 /* [in] */ REFIID riid,
760 /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
761 /* [in] */ UINT cNames,
762 /* [in] */ LCID lcid,
763 /* [size_is][out] */ DISPID __RPC_FAR *rgDispId)
764{
765 Widget *This = impl_from_IWidget(iface);
766 IDispatch *pDispatch;
767 HRESULT hr = IUnknown_QueryInterface(This->pDispatchUnknown, &IID_IDispatch, (void **)&pDispatch);
768 if (SUCCEEDED(hr))
769 {
770 hr = IDispatch_GetIDsOfNames(pDispatch, riid, rgszNames, cNames, lcid, rgDispId);
771 IDispatch_Release(pDispatch);
772 }
773 return hr;
774}
775
777 IWidget __RPC_FAR * iface,
778 /* [in] */ DISPID dispIdMember,
779 /* [in] */ REFIID riid,
780 /* [in] */ LCID lcid,
781 /* [in] */ WORD wFlags,
782 /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
783 /* [out] */ VARIANT __RPC_FAR *pVarResult,
784 /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
785 /* [out] */ UINT __RPC_FAR *puArgErr)
786{
787 Widget *This = impl_from_IWidget(iface);
788 IDispatch *pDispatch;
789 HRESULT hr = IUnknown_QueryInterface(This->pDispatchUnknown, &IID_IDispatch, (void **)&pDispatch);
790 if (SUCCEEDED(hr))
791 {
792 hr = IDispatch_Invoke(pDispatch, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
793 IDispatch_Release(pDispatch);
794 }
795 return hr;
796}
797
799 IWidget __RPC_FAR * iface,
800 /* [in] */ BSTR name)
801{
802 trace("put_Name(%s)\n", wine_dbgstr_w(name));
803 return S_OK;
804}
805
807 IWidget __RPC_FAR * iface,
808 /* [out] */ BSTR __RPC_FAR *name)
809{
810 static const WCHAR szCat[] = { 'C','a','t',0 };
811 trace("get_Name()\n");
812 *name = SysAllocString(szCat);
813 return S_OK;
814}
815
817 IWidget __RPC_FAR * iface,
818 /* [in] */ double number,
819 /* [out] */ BSTR *str1,
820 /* [defaultvalue][in] */ BSTR str2,
821 /* [optional][in] */ VARIANT __RPC_FAR *opt)
822{
823 static const WCHAR szString[] = { 'S','t','r','i','n','g',0 };
824 trace("DoSomething()\n");
825
826 ok(number == 3.141, "number(%f) != 3.141\n", number);
827 ok(*str2 == '\0', "str2(%s) != \"\"\n", wine_dbgstr_w(str2));
828 ok(V_VT(opt) == VT_ERROR, "V_VT(opt) should be VT_ERROR instead of 0x%x\n", V_VT(opt));
829 ok(V_ERROR(opt) == DISP_E_PARAMNOTFOUND, "V_ERROR(opt) should be DISP_E_PARAMNOTFOUND instead of 0x%08lx\n", V_ERROR(opt));
830 *str1 = SysAllocString(szString);
831
832 return S_FALSE;
833}
834
836 IWidget __RPC_FAR * iface,
837 /* [retval][out] */ STATE __RPC_FAR *state)
838{
839 trace("get_State() = STATE_WIDGETIFIED\n");
840 *state = STATE_WIDGETIFIED;
841 return S_OK;
842}
843
845 IWidget __RPC_FAR * iface,
846 /* [in] */ STATE state)
847{
848 trace("put_State(%d)\n", state);
849 return S_OK;
850}
851
853 IWidget * iface,
854 BSTR bstrId,
855 BSTR *sValue)
856{
857 trace("Map(%s, %p)\n", wine_dbgstr_w(bstrId), sValue);
858 *sValue = SysAllocString(bstrId);
859 return S_OK;
860}
861
863 IWidget * iface,
864 OLE_COLOR val)
865{
866 trace("SetOleColor(0x%lx)\n", val);
867 return S_OK;
868}
869
871 IWidget * iface,
872 OLE_COLOR *pVal)
873{
874 trace("GetOleColor() = 0x8000000f\n");
875 *pVal = 0x8000000f;
876 return S_FALSE;
877}
878
880 IWidget *iface,
881 IWidget **ppVal)
882{
883 trace("Clone()\n");
884 return Widget_QueryInterface(iface, &IID_IWidget, (void **)ppVal);
885}
886
888 IWidget *iface,
889 IDispatch **ppVal)
890{
891 trace("CloneDispatch()\n");
892 return Widget_QueryInterface(iface, &IID_IWidget, (void **)ppVal);
893}
894
896 IWidget *iface,
897 ApplicationObject2 **ppVal)
898{
899 trace("CloneCoclass()\n");
900 return Widget_QueryInterface(iface, &IID_IWidget, (void **)ppVal);
901}
902
904 IWidget __RPC_FAR * iface,
905 VARIANT *value,
907{
908 trace("Value(%p, %p)\n", value, retval);
909 ok(V_VT(value) == VT_I2, "V_VT(value) was %d instead of VT_I2\n", V_VT(value));
910 ok(V_I2(value) == 1, "V_I2(value) was %d instead of 1\n", V_I2(value));
911 V_VT(retval) = VT_I2;
912 V_I2(retval) = 1234;
913 return S_OK;
914}
915
917 IWidget * iface,
918 SAFEARRAY ** values)
919{
920 trace("VariantArrayPtr(%p)\n", values);
921 return S_OK;
922}
923
925 IWidget * iface,
926 int numexpect,
928{
929 LONG lbound, ubound, i;
930 VARIANT * data;
931 HRESULT hr;
932
933 trace("VarArg(%p)\n", values);
934
935 ok( values->cDims == 1, "wrong cDims %u\n", values->cDims );
936 ok( values->cbElements == (numexpect ? sizeof(VARIANT) : 0),
937 "wrong cbElements %lu\n", values->cbElements );
938
939 hr = SafeArrayGetLBound(values, 1, &lbound);
940 ok(hr == S_OK, "SafeArrayGetLBound failed with %lx\n", hr);
941 ok(lbound == 0, "SafeArrayGetLBound returned %ld\n", lbound);
942
943 hr = SafeArrayGetUBound(values, 1, &ubound);
944 ok(hr == S_OK, "SafeArrayGetUBound failed with %lx\n", hr);
945 ok(ubound == numexpect-1, "SafeArrayGetUBound returned %ld, but expected %d\n", ubound, numexpect-1);
946
948 ok(hr == S_OK, "SafeArrayAccessData failed with %lx\n", hr);
949
950 for (i=0; i<=ubound-lbound; i++)
951 {
952 ok(V_VT(&data[i]) == VT_I4, "V_VT(&data[%ld]) was %d\n", i, V_VT(&data[i]));
953 ok(V_I4(&data[i]) == i, "V_I4(&data[%ld]) was %ld\n", i, V_I4(&data[i]));
954 }
955
957 ok(hr == S_OK, "SafeArrayUnaccessData failed with %lx\n", hr);
958
959 return S_OK;
960}
961
963 IWidget __RPC_FAR * iface)
964{
965 trace("Error()\n");
966 return E_NOTIMPL;
967}
968
970 IWidget __RPC_FAR * iface,
971 ISomethingFromDispatch **ppVal)
972{
973 trace("CloneInterface()\n");
974 *ppVal = 0;
975 return S_OK;
976}
977
979 IWidget* iface, LONG lcid, INT i)
980{
981 trace("put_prop_with_lcid(%08lx, %x)\n", lcid, i);
982 ok(lcid == MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), "got lcid %08lx\n", lcid);
983 ok(i == 0xcafe, "got %08x\n", i);
984 return S_OK;
985}
986
988 IWidget* iface, LONG lcid, INT *i)
989{
990 trace("get_prop_with_lcid(%08lx, %p)\n", lcid, i);
991 ok(lcid == MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), "got lcid %08lx\n", lcid);
992 *i = lcid;
993 return S_OK;
994}
995
997 IWidget* iface, INT *i)
998{
999 trace("get_prop_int(%p)\n", i);
1000 *i = -13;
1001 return S_OK;
1002}
1003
1005 IWidget* iface, UINT *i)
1006{
1007 trace("get_prop_uint(%p)\n", i);
1008 *i = 42;
1009 return S_OK;
1010}
1011
1013 IWidget* iface, UINT *i)
1014{
1015 *i = 42;
1016 return S_OK;
1017}
1018
1020 IWidget* iface, INT opt, INT i)
1021{
1022 trace("put_prop_opt_arg(%08x, %08x)\n", opt, i);
1023 todo_wine ok(opt == 0, "got opt=%08x\n", opt);
1024 ok(i == 0xcafe, "got i=%08x\n", i);
1025 return S_OK;
1026}
1027
1029 IWidget* iface, INT req, INT i)
1030{
1031 trace("put_prop_req_arg(%08x, %08x)\n", req, i);
1032 ok(req == 0x5678, "got req=%08x\n", req);
1033 ok(i == 0x1234, "got i=%08x\n", i);
1034 return S_OK;
1035}
1036
1037static HRESULT WINAPI Widget_pos_restrict(IWidget* iface, INT *i)
1038{
1039 trace("restrict\n");
1041 return S_OK;
1042}
1043
1044static HRESULT WINAPI Widget_neg_restrict(IWidget* iface, INT *i)
1045{
1046 trace("neg_restrict\n");
1048 return S_OK;
1049}
1050
1052 IWidget *iface, BSTR name, SAFEARRAY *params, VARIANT *result)
1053{
1054 static const WCHAR catW[] = { 'C','a','t',0 };
1055 static const WCHAR supermanW[] = { 'S','u','p','e','r','m','a','n',0 };
1056 LONG bound;
1057 VARIANT *var;
1058 BSTR bstr;
1059 HRESULT hr;
1060
1061 trace("VarArg_Run(%p,%p,%p)\n", name, params, result);
1062
1063 ok(!lstrcmpW(name, catW), "got %s\n", wine_dbgstr_w(name));
1064
1065 if (!params->cbElements) /* no varargs */
1066 {
1067 hr = SafeArrayGetUBound(params, 1, &bound);
1068 ok(hr == S_OK, "SafeArrayGetUBound error %#lx\n", hr);
1069 ok(bound == -1, "expected -1, got %ld\n", bound);
1070 return S_OK;
1071 }
1072
1073 ok( params->cbElements == sizeof(VARIANT), "wrong cbElements %lu\n", params->cbElements );
1074
1075 hr = SafeArrayGetLBound(params, 1, &bound);
1076 ok(hr == S_OK, "SafeArrayGetLBound error %#lx\n", hr);
1077 ok(bound == 0, "expected 0, got %ld\n", bound);
1078
1079 hr = SafeArrayGetUBound(params, 1, &bound);
1080 ok(hr == S_OK, "SafeArrayGetUBound error %#lx\n", hr);
1081 ok(bound == 0, "expected 0, got %ld\n", bound);
1082
1083 hr = SafeArrayAccessData(params, (void **)&var);
1084 ok(hr == S_OK, "SafeArrayAccessData failed with %lx\n", hr);
1085
1086 ok(V_VT(&var[0]) == VT_BSTR, "expected VT_BSTR, got %d\n", V_VT(&var[0]));
1087 bstr = V_BSTR(&var[0]);
1088 ok(!lstrcmpW(bstr, supermanW), "got %s\n", wine_dbgstr_w(bstr));
1089
1091 ok(hr == S_OK, "SafeArrayUnaccessData error %#lx\n", hr);
1092
1093 return S_OK;
1094}
1095
1097 IWidget *iface, BSTR name, SAFEARRAY **params, VARIANT *result)
1098{
1099 static const WCHAR catW[] = { 'C','a','t',0 };
1100 static const WCHAR supermanW[] = { 'S','u','p','e','r','m','a','n',0 };
1101 LONG bound;
1102 VARIANT *var;
1103 BSTR bstr;
1104 HRESULT hr;
1105
1106 trace("VarArg_Ref_Run(%p,%p,%p)\n", name, params, result);
1107
1108 ok(!lstrcmpW(name, catW), "got %s\n", wine_dbgstr_w(name));
1109
1110 if (!(*params)->cbElements) /* no varargs */
1111 {
1112 hr = SafeArrayGetUBound(*params, 1, &bound);
1113 ok(hr == S_OK, "SafeArrayGetUBound error %#lx\n", hr);
1114 ok(bound == -1, "expected -1, got %ld\n", bound);
1115 return S_OK;
1116 }
1117
1118 ok( (*params)->cbElements == sizeof(VARIANT), "wrong cbElements %lu\n", (*params)->cbElements );
1119
1120 hr = SafeArrayGetLBound(*params, 1, &bound);
1121 ok(hr == S_OK, "SafeArrayGetLBound error %#lx\n", hr);
1122 ok(bound == 0, "expected 0, got %ld\n", bound);
1123
1124 hr = SafeArrayGetUBound(*params, 1, &bound);
1125 ok(hr == S_OK, "SafeArrayGetUBound error %#lx\n", hr);
1126 ok(bound == 0, "expected 0, got %ld\n", bound);
1127
1128 hr = SafeArrayAccessData(*params, (void **)&var);
1129 ok(hr == S_OK, "SafeArrayAccessData error %#lx\n", hr);
1130
1131 ok(V_VT(&var[0]) == VT_BSTR, "expected VT_BSTR, got %d\n", V_VT(&var[0]));
1132 bstr = V_BSTR(&var[0]);
1133 ok(!lstrcmpW(bstr, supermanW), "got %s\n", wine_dbgstr_w(bstr));
1134
1136 ok(hr == S_OK, "SafeArrayUnaccessData error %#lx\n", hr);
1137
1138 return S_OK;
1139}
1140
1141static HRESULT WINAPI Widget_basetypes_in(IWidget *iface, signed char c, short s, LONG l, hyper h,
1142 unsigned char uc, unsigned short us, ULONG ul, MIDL_uhyper uh,
1143 float f, double d, STATE st)
1144{
1145 ok(c == 5, "Got char %d.\n", c);
1146 ok(s == -123, "Got short %d.\n", s);
1147 ok(l == -100000, "Got int %ld.\n", l);
1148 ok(h == (LONGLONG)-100000 * 1000000, "Got hyper %s.\n", wine_dbgstr_longlong(h));
1149 ok(uc == 0, "Got unsigned char %u.\n", uc);
1150 ok(us == 456, "Got unsigned short %u.\n", us);
1151 ok(ul == 0xdeadbeef, "Got unsigned int %lu.\n", ul);
1152 ok(uh == (ULONGLONG)1234567890 * 9876543210, "Got unsigned hyper %s.\n", wine_dbgstr_longlong(uh));
1153 ok(f == (float)M_PI, "Got float %f.\n", f);
1154 ok(d == M_E, "Got double %f.\n", d);
1155 ok(st == STATE_WIDGETIFIED, "Got state %u.\n", st);
1156
1157 return S_OK;
1158}
1159
1160static HRESULT WINAPI Widget_basetypes_out(IWidget *iface, signed char *c, short *s, LONG *l, hyper *h,
1161 unsigned char *uc, unsigned short *us, ULONG *ul, MIDL_uhyper *uh,
1162 float *f, double *d, STATE *st)
1163{
1164 *c = 10;
1165 *s = -321;
1166 *l = -200000;
1167 *h = (LONGLONG)-200000 * 1000000;
1168 *uc = 254;
1169 *us = 256;
1170 *ul = 0xf00dfade;
1171 *uh = 0xabcdef0123456789ull;
1172 *f = M_LN2;
1173 *d = M_LN10;
1174 *st = STATE_UNWIDGETIFIED;
1175
1176 return S_OK;
1177}
1178
1179static HRESULT WINAPI Widget_float_abi(IWidget *iface, float f, double d, int i, float f2, double d2)
1180{
1181 ok(f == 1.0f, "Got float %f.\n", f);
1182 ok(d == 2.0, "Got double %f.\n", d);
1183 ok(i == 3, "Got int %d.\n", i);
1184 ok(f2 == 4.0f, "Got float %f.\n", f2);
1185 ok(d2 == 5.0, "Got double %f.\n", d2);
1186
1187 return S_OK;
1188}
1189
1190static HRESULT WINAPI Widget_long_ptr(IWidget *iface, LONG *in, LONG *out, LONG *in_out)
1191{
1192 ok(*in == 123, "Got [in] %ld.\n", *in);
1193 if (testmode == 0) /* Invoke() */
1194 ok(*out == 456, "Got [out] %ld.\n", *out);
1195 else if (testmode == 1)
1196 ok(!*out, "Got [out] %ld.\n", *out);
1197 ok(*in_out == 789, "Got [in, out] %ld.\n", *in_out);
1198
1199 *in = 987;
1200 *out = 654;
1201 *in_out = 321;
1202
1203 return S_OK;
1204}
1205
1206static HRESULT WINAPI Widget_long_ptr_ptr(IWidget *iface, LONG **in, LONG **out, LONG **in_out)
1207{
1208 ok(!*out, "Got [out] %p.\n", *out);
1209 if (testmode == 0)
1210 {
1211 ok(!*in, "Got [in] %p.\n", *in);
1212 ok(!*in_out, "Got [in, out] %p.\n", *in_out);
1213 }
1214 else if (testmode == 1)
1215 {
1216 ok(!*in, "Got [in] %p.\n", *in);
1217 ok(!*in_out, "Got [in, out] %p.\n", *in_out);
1218
1219 *out = CoTaskMemAlloc(sizeof(int));
1220 **out = 654;
1221 *in_out = CoTaskMemAlloc(sizeof(int));
1222 **in_out = 321;
1223 }
1224 else if (testmode == 2)
1225 {
1226 ok(**in == 123, "Got [in] %ld.\n", **in);
1227 ok(**in_out == 789, "Got [in, out] %ld.\n", **in_out);
1228
1229 *out = CoTaskMemAlloc(sizeof(int));
1230 **out = 654;
1231 **in_out = 321;
1232 }
1233 else if (testmode == 3)
1234 {
1235 ok(**in_out == 789, "Got [in, out] %ld.\n", **in_out);
1236 *in_out = NULL;
1237 }
1238
1239 return S_OK;
1240}
1241
1242/* Call methods to check that we have valid proxies to each interface. */
1243static void check_iface_marshal(IUnknown *unk, IDispatch *disp, ISomethingFromDispatch *sfd)
1244{
1245 ISomethingFromDispatch *sfd2;
1247 HRESULT hr;
1248
1249 hr = IUnknown_QueryInterface(unk, &IID_ISomethingFromDispatch, (void **)&sfd2);
1250 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1251 ISomethingFromDispatch_Release(sfd2);
1252
1253 hr = IDispatch_GetTypeInfo(disp, 0xdeadbeef, 0, &typeinfo);
1254 ok(hr == 0xbeefdead, "Got hr %#lx.\n", hr);
1255
1256 hr = ISomethingFromDispatch_anotherfn(sfd);
1257 ok(hr == 0x01234567, "Got hr %#lx.\n", hr);
1258}
1259
1260static HRESULT WINAPI Widget_iface_in(IWidget *iface, IUnknown *unk, IDispatch *disp, ISomethingFromDispatch *sfd)
1261{
1262 if (testmode == 0)
1263 check_iface_marshal(unk, disp, sfd);
1264 else if (testmode == 1)
1265 {
1266 ok(!unk, "Got iface %p.\n", unk);
1267 ok(!disp, "Got iface %p.\n", disp);
1268 ok(!sfd, "Got iface %p.\n", sfd);
1269 }
1270 return S_OK;
1271}
1272
1273static HRESULT WINAPI Widget_iface_out(IWidget *iface, IUnknown **unk, IDispatch **disp, ISomethingFromDispatch **sfd)
1274{
1275 ok(!*unk, "Got iface %p.\n", *unk);
1276 ok(!*disp, "Got iface %p.\n", *disp);
1277 ok(!*sfd, "Got iface %p.\n", *sfd);
1278
1279 if (testmode == 0)
1280 {
1281 *unk = (IUnknown *)create_disp_obj();
1282 *disp = (IDispatch *)create_disp_obj();
1283 *sfd = create_disp_obj();
1284 }
1285 return S_OK;
1286}
1287
1288static HRESULT WINAPI Widget_iface_ptr(IWidget *iface, ISomethingFromDispatch **in,
1289 ISomethingFromDispatch **out, ISomethingFromDispatch **in_out)
1290{
1291 HRESULT hr;
1292
1293 ok(!*out, "Got [out] %p.\n", *out);
1294 if (testmode == 0 || testmode == 1)
1295 {
1296 hr = ISomethingFromDispatch_anotherfn(*in);
1297 ok(hr == 0x01234567, "Got hr %#lx.\n", hr);
1298 hr = ISomethingFromDispatch_anotherfn(*in_out);
1299 ok(hr == 0x01234567, "Got hr %#lx.\n", hr);
1300 }
1301
1302 if (testmode == 1)
1303 {
1304 *out = create_disp_obj();
1305 ISomethingFromDispatch_Release(*in_out);
1306 *in_out = create_disp_obj();
1307 }
1308 else if (testmode == 2)
1309 {
1310 ok(!*in, "Got [in] %p.\n", *in);
1311 ok(!*in_out, "Got [in, out] %p.\n", *in_out);
1312 *in_out = create_disp_obj();
1313 }
1314 else if (testmode == 3)
1315 {
1316 hr = ISomethingFromDispatch_anotherfn(*in_out);
1317 ok(hr == 0x01234567, "Got hr %#lx.\n", hr);
1318 ISomethingFromDispatch_Release(*in_out);
1319 *in_out = NULL;
1320 }
1321
1322 return S_OK;
1323}
1324
1325static HRESULT WINAPI Widget_iface_noptr(IWidget *iface, IUnknown unk, IDispatch disp, ISomethingFromDispatch sfd)
1326{
1327 check_iface_marshal((IUnknown *)unk.lpVtbl, (IDispatch *)disp.lpVtbl, (ISomethingFromDispatch *)sfd.lpVtbl);
1328 return S_OK;
1329}
1330
1331static HRESULT WINAPI Widget_bstr(IWidget *iface, BSTR in, BSTR *out, BSTR *in_ptr, BSTR *in_out)
1332{
1333 UINT len;
1334
1335 if (testmode == 0)
1336 {
1338 ok(len == sizeof(test_bstr1), "Got wrong length %u.\n", len);
1339 ok(!memcmp(in, test_bstr1, len), "Got string %s.\n", wine_dbgstr_wn(in, len / sizeof(WCHAR)));
1340 ok(!*out, "Got unexpected output %p.\n", *out);
1341 len = SysStringLen(*in_ptr);
1342 ok(len == lstrlenW(test_bstr2), "Got wrong length %u.\n", len);
1343 ok(!memcmp(*in_ptr, test_bstr2, len), "Got string %s.\n", wine_dbgstr_w(*in_ptr));
1344 len = SysStringLen(*in_out);
1345 ok(len == lstrlenW(test_bstr3), "Got wrong length %u.\n", len);
1346 ok(!memcmp(*in_out, test_bstr3, len), "Got string %s.\n", wine_dbgstr_w(*in_out));
1347
1349 in[1] = (*in_ptr)[1] = (*in_out)[1] = 'X';
1350 }
1351 else if (testmode == 1)
1352 {
1353 ok(!in, "Got string %s.\n", wine_dbgstr_w(in));
1354 ok(!*out, "Got string %s.\n", wine_dbgstr_w(*out));
1355 ok(!*in_ptr, "Got string %s.\n", wine_dbgstr_w(*in_ptr));
1356 ok(!*in_out, "Got string %s.\n", wine_dbgstr_w(*in_out));
1357 }
1358 return S_OK;
1359}
1360
1361static HRESULT WINAPI Widget_variant(IWidget *iface, VARIANT in, VARIANT *out, VARIANT *in_ptr, VARIANT *in_out)
1362{
1363 ok(V_VT(&in) == VT_CY, "Got wrong type %#x.\n", V_VT(&in));
1364 ok(V_CY(&in).Hi == 0xdababe && V_CY(&in).Lo == 0xdeadbeef,
1365 "Got wrong value %s.\n", wine_dbgstr_longlong(V_CY(&in).int64));
1366 if (testmode == 0)
1367 {
1368 ok(V_VT(out) == VT_I4, "Got wrong type %u.\n", V_VT(out));
1369 ok(V_I4(out) == 1, "Got wrong value %ld.\n", V_I4(out));
1370 }
1371 else
1372 ok(V_VT(out) == VT_EMPTY, "Got wrong type %u.\n", V_VT(out));
1373 ok(V_VT(in_ptr) == VT_I4, "Got wrong type %u.\n", V_VT(in_ptr));
1374 ok(V_I4(in_ptr) == -1, "Got wrong value %ld.\n", V_I4(in_ptr));
1375 ok(V_VT(in_out) == VT_BSTR, "Got wrong type %u.\n", V_VT(in_out));
1376 ok(!lstrcmpW(V_BSTR(in_out), test_bstr2), "Got wrong value %s.\n",
1377 wine_dbgstr_w(V_BSTR(in_out)));
1378
1379 V_VT(&in) = VT_I4;
1380 V_I4(&in) = 2;
1381 V_VT(out) = VT_UI1;
1382 V_UI1(out) = 3;
1383 V_VT(in_ptr) = VT_I2;
1384 V_I2(in_ptr) = 4;
1385 VariantClear(in_out);
1386 V_VT(in_out) = VT_I1;
1387 V_I1(in_out) = 5;
1388 return S_OK;
1389}
1390
1392{
1394 int i, *data;
1395
1396 SafeArrayAccessData(sa, (void **)&data);
1397 for (i = 0; i < len; ++i)
1398 data[i] = len + i;
1400
1401 return sa;
1402}
1403
1405{
1406 LONG len, i, *data;
1407 HRESULT hr;
1408
1409 hr = SafeArrayGetUBound(sa, 1, &len);
1410 len++;
1411 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1412 ok(len == expect, "Expected len %ld, got %ld.\n", expect, len);
1413
1414 hr = SafeArrayAccessData(sa, (void **)&data);
1415 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1416
1417 for (i = 0; i < len; ++i)
1418 ok(data[i] == len + i, "Expected data %ld at %ld, got %ld.\n", len + i, i, data[i]);
1419
1421}
1422
1423static HRESULT WINAPI Widget_safearray(IWidget *iface, SAFEARRAY *in, SAFEARRAY **out, SAFEARRAY **in_ptr, SAFEARRAY **in_out)
1424{
1425 HRESULT hr;
1426
1427 check_safearray(in, 3);
1428 ok(!*out, "Got array %p.\n", *out);
1429 check_safearray(*in_ptr, 7);
1430 check_safearray(*in_out, 9);
1431
1432 hr = SafeArrayDestroy(*in_out);
1433 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1434
1435 *out = make_safearray(4);
1436 *in_out = make_safearray(6);
1437
1438 return S_OK;
1439}
1440
1441static HRESULT WINAPI Widget_mystruct(IWidget *iface, MYSTRUCT in, MYSTRUCT *out, MYSTRUCT *in_ptr, MYSTRUCT *in_out)
1442{
1443 static const MYSTRUCT empty = {0};
1444 ok(!memcmp(&in, &test_mystruct1, sizeof(in)), "Structs didn't match.\n");
1445 ok(!memcmp(out, &empty, sizeof(*out)), "Structs didn't match.\n");
1446 ok(!memcmp(in_ptr, &test_mystruct3, sizeof(*in_ptr)), "Structs didn't match.\n");
1447 ok(!memcmp(in_out, &test_mystruct4, sizeof(*in_out)), "Structs didn't match.\n");
1448
1449 memcpy(out, &test_mystruct5, sizeof(*out));
1450 memcpy(in_ptr, &test_mystruct6, sizeof(*in_ptr));
1451 memcpy(in_out, &test_mystruct7, sizeof(*in_out));
1452 return S_OK;
1453}
1454
1455static HRESULT WINAPI Widget_mystruct_ptr_ptr(IWidget *iface, MYSTRUCT **in)
1456{
1457 ok(!memcmp(*in, &test_mystruct1, sizeof(**in)), "Structs didn't match.\n");
1458 return S_OK;
1459}
1460
1461static HRESULT WINAPI Widget_thin_struct(IWidget *iface, struct thin in)
1462{
1463 ok(!memcmp(&in, &test_thin_struct, sizeof(in)), "Structs didn't match.\n");
1464 return S_OK;
1465}
1466
1467static HRESULT WINAPI Widget_rect(IWidget *iface, RECT in, RECT *out, RECT *in_ptr, RECT *in_out)
1468{
1469 static const RECT empty = {0};
1470 ok(EqualRect(&in, &test_rect1), "Rects didn't match.\n");
1471 ok(EqualRect(out, &empty), "Rects didn't match.\n");
1472 ok(EqualRect(in_ptr, &test_rect3), "Rects didn't match.\n");
1473 ok(EqualRect(in_out, &test_rect4), "Rects didn't match.\n");
1474
1475 *out = test_rect5;
1476 *in_ptr = test_rect6;
1477 *in_out = test_rect7;
1478 return S_OK;
1479}
1480
1481static HRESULT WINAPI Widget_complex_struct(IWidget *iface, struct complex in)
1482{
1483 HRESULT hr;
1484
1485 ok(in.c == 98, "Got char %d.\n", in.c);
1486 ok(in.i == 76543, "Got int %d.\n", in.i);
1487 ok(*in.pi == 2, "Got int pointer %d.\n", *in.pi);
1488 ok(**in.ppi == 10, "Got int double pointer %d.\n", **in.ppi);
1489 hr = ISomethingFromDispatch_anotherfn(in.iface);
1490 ok(hr == 0x01234567, "Got wrong hr %#lx.\n", hr);
1491 hr = ISomethingFromDispatch_anotherfn(*in.iface_ptr);
1492 ok(hr == 0x01234567, "Got wrong hr %#lx.\n", hr);
1493 ok(!lstrcmpW(in.bstr, test_bstr2), "Got string %s.\n", wine_dbgstr_w(in.bstr));
1494 ok(V_VT(&in.var) == VT_I4, "Got wrong type %u.\n", V_VT(&in.var));
1495 ok(V_I4(&in.var) == 123, "Got wrong value %ld.\n", V_I4(&in.var));
1496 ok(!memcmp(&in.mystruct, &test_mystruct1, sizeof(MYSTRUCT)), "Structs didn't match.\n");
1497 ok(!memcmp(in.arr, test_array1, sizeof(array_t)), "Arrays didn't match.\n");
1498 ok(in.myint == 456, "Got int %d.\n", in.myint);
1499
1500 return S_OK;
1501}
1502
1503static HRESULT WINAPI Widget_array(IWidget *iface, array_t in, array_t out, array_t in_out)
1504{
1505 static const array_t empty = {0};
1506 ok(!memcmp(in, test_array1, sizeof(array_t)), "Arrays didn't match.\n");
1507 ok(!memcmp(out, empty, sizeof(array_t)), "Arrays didn't match.\n");
1508 ok(!memcmp(in_out, test_array3, sizeof(array_t)), "Arrays didn't match.\n");
1509
1510 memcpy(in, test_array4, sizeof(array_t));
1511 memcpy(out, test_array5, sizeof(array_t));
1512 memcpy(in_out, test_array6, sizeof(array_t));
1513
1514 return S_OK;
1515}
1516
1517static HRESULT WINAPI Widget_variant_array(IWidget *iface, VARIANT in[2], VARIANT out[2], VARIANT in_out[2])
1518{
1519 ok(V_VT(&in[0]) == VT_I4, "Got wrong type %u.\n", V_VT(&in[0]));
1520 ok(V_I4(&in[0]) == 1, "Got wrong value %ld.\n", V_I4(&in[0]));
1521 ok(V_VT(&in[1]) == (VT_BYREF|VT_I4), "Got wrong type %u.\n", V_VT(&in[1]));
1522 ok(*V_I4REF(&in[1]) == 2, "Got wrong value %ld.\n", *V_I4REF(&in[1]));
1523 ok(V_VT(&out[0]) == VT_EMPTY, "Got wrong type %u.\n", V_VT(&out[0]));
1524 ok(V_VT(&out[1]) == VT_EMPTY, "Got wrong type %u.\n", V_VT(&out[1]));
1525 ok(V_VT(&in_out[0]) == VT_I4, "Got wrong type %u.\n", V_VT(&in_out[0]));
1526 ok(V_I4(&in_out[0]) == 5, "Got wrong type %u.\n", V_VT(&in_out[0]));
1527 ok(V_VT(&in_out[1]) == VT_BSTR, "Got wrong type %u.\n", V_VT(&in_out[1]));
1528 ok(!lstrcmpW(V_BSTR(&in_out[1]), test_bstr1), "Got wrong value %s.\n", wine_dbgstr_w(V_BSTR(&in[1])));
1529
1530 V_VT(&in[0]) = VT_I1; V_I1(&in[0]) = 7;
1531 V_VT(&in[1]) = VT_I1; V_I1(&in[1]) = 8;
1532 V_VT(&out[0]) = VT_I1; V_I1(&out[0]) = 9;
1534 V_VT(&in_out[0]) = VT_I1; V_I1(&in_out[0]) = 11;
1535 V_VT(&in_out[1]) = VT_UNKNOWN; V_UNKNOWN(&in_out[1]) = (IUnknown *)create_disp_obj();
1536
1537 return S_OK;
1538}
1539
1540static HRESULT WINAPI Widget_mystruct_array(IWidget *iface, MYSTRUCT in[2])
1541{
1542 ok(!memcmp(&in[0], &test_mystruct1, sizeof(MYSTRUCT)), "Structs didn't match.\n");
1543 ok(!memcmp(&in[1], &test_mystruct2, sizeof(MYSTRUCT)), "Structs didn't match.\n");
1544 return S_OK;
1545}
1546
1547static HRESULT WINAPI Widget_myint(IWidget *iface, myint_t val, myint_t *ptr, myint_t **ptr_ptr)
1548{
1549 ok(val == 123, "Got value %d.\n", val);
1550 ok(*ptr == 456, "Got single ptr ref %d.\n", *ptr);
1551 ok(**ptr_ptr == 789, "Got double ptr ref %d.\n", **ptr_ptr);
1552 return S_OK;
1553}
1554
1555static HRESULT WINAPI Widget_Coclass(IWidget *iface, Coclass1 *class1, Coclass2 *class2, Coclass3 *class3)
1556{
1557 HRESULT hr;
1558
1559 hr = ICoclass1_test((ICoclass1 *)class1);
1560 ok(hr == 1, "Got hr %#lx.\n", hr);
1561
1562 hr = ICoclass2_test((ICoclass2 *)class2);
1563 ok(hr == 2, "Got hr %#lx.\n", hr);
1564
1565 hr = ICoclass1_test((ICoclass1 *)class3);
1566 ok(hr == 1, "Got hr %#lx.\n", hr);
1567
1568 return S_OK;
1569}
1570
1571static HRESULT WINAPI Widget_Coclass_ptr(IWidget *iface, Coclass1 **in, Coclass1 **out, Coclass1 **in_out)
1572{
1573 struct coclass_obj *obj;
1574 HRESULT hr;
1575
1576 ok(!*out, "Got [out] %p.\n", *out);
1577 if (testmode == 0 || testmode == 1)
1578 {
1579 hr = ICoclass1_test((ICoclass1 *)*in);
1580 ok(hr == 1, "Got hr %#lx.\n", hr);
1581 hr = ICoclass1_test((ICoclass1 *)*in_out);
1582 ok(hr == 1, "Got hr %#lx.\n", hr);
1583 }
1584
1585 if (testmode == 1)
1586 {
1588 *out = (Coclass1 *)&obj->ICoclass1_iface;
1589
1590 ICoclass1_Release((ICoclass1 *)*in_out);
1592 *in_out = (Coclass1 *)&obj->ICoclass1_iface;
1593 }
1594 else if (testmode == 2)
1595 {
1596 ok(!*in_out, "Got [in, out] %p.\n", *in_out);
1598 *in_out = (Coclass1 *)&obj->ICoclass1_iface;
1599 }
1600 else if (testmode == 3)
1601 {
1602 hr = ICoclass1_test((ICoclass1 *)*in_out);
1603 ok(hr == 1, "Got hr %#lx.\n", hr);
1604 ICoclass1_Release((ICoclass1 *)*in_out);
1605 *in_out = NULL;
1606 }
1607
1608 return S_OK;
1609}
1610
1611static HRESULT WINAPI Widget_Coclass_noptr(IWidget *iface, Coclass1 class1, Coclass2 class2, Coclass3 class3)
1612{
1613 HRESULT hr;
1614
1615 hr = ICoclass1_test(class1.iface);
1616 ok(hr == 1, "Got hr %#lx.\n", hr);
1617
1618 hr = ICoclass2_test(class2.iface);
1619 ok(hr == 2, "Got hr %#lx.\n", hr);
1620
1621 hr = ICoclass1_test(class3.iface);
1622 ok(hr == 1, "Got hr %#lx.\n", hr);
1623
1624 return S_OK;
1625}
1626
1627static HRESULT WINAPI Widget_no_in_out(IWidget *iface, BSTR str, int i)
1628{
1629 ok(SysStringLen(str) == 4, "unexpected len\n");
1630 ok(!lstrcmpW(str, L"test"), "unexpected str %s\n", wine_dbgstr_w(str));
1631 ok(i == 5, "i = %d\n", i);
1632 return S_OK;
1633}
1634
1635static const struct IWidgetVtbl Widget_VTable =
1636{
1649 Widget_Map,
1696};
1697
1698static HRESULT WINAPI StaticWidget_QueryInterface(IStaticWidget *iface, REFIID riid, void **ppvObject)
1699{
1700 if (IsEqualIID(riid, &IID_IStaticWidget) || IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
1701 {
1702 IStaticWidget_AddRef(iface);
1703 *ppvObject = iface;
1704 return S_OK;
1705 }
1706
1707 *ppvObject = NULL;
1708 return E_NOINTERFACE;
1709}
1710
1711static ULONG WINAPI StaticWidget_AddRef(IStaticWidget *iface)
1712{
1713 return 2;
1714}
1715
1716static ULONG WINAPI StaticWidget_Release(IStaticWidget *iface)
1717{
1718 return 1;
1719}
1720
1721static HRESULT WINAPI StaticWidget_GetTypeInfoCount(IStaticWidget *iface, UINT *pctinfo)
1722{
1723 ok(0, "unexpected call\n");
1724 return E_NOTIMPL;
1725}
1726
1727static HRESULT WINAPI StaticWidget_GetTypeInfo(IStaticWidget *iface, UINT iTInfo, LCID lcid,
1728 ITypeInfo **ppTInfo)
1729{
1730 ok(0, "unexpected call\n");
1731 return E_NOTIMPL;
1732}
1733
1734static HRESULT WINAPI StaticWidget_GetIDsOfNames(IStaticWidget *iface, REFIID riid, LPOLESTR *rgszNames,
1735 UINT cNames, LCID lcid, DISPID *rgDispId)
1736{
1737 ok(0, "unexpected call\n");
1738 return E_NOTIMPL;
1739}
1740
1741static HRESULT WINAPI StaticWidget_Invoke(IStaticWidget *iface, DISPID dispIdMember, REFIID riid,
1742 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1743 UINT *puArgErr)
1744{
1745 ok(0, "unexpected call\n");
1746 return E_NOTIMPL;
1747}
1748
1749static HRESULT WINAPI StaticWidget_TestDual(IStaticWidget *iface, ItestDual *p)
1750{
1751 trace("TestDual()\n");
1752 ok(p == &TestDual, "wrong ItestDual\n");
1753 return S_OK;
1754}
1755
1756static HRESULT WINAPI StaticWidget_TestSecondIface(IStaticWidget *iface, ITestSecondIface *p)
1757{
1758 trace("TestSecondIface()\n");
1759 ok(p == &TestSecondIface, "wrong ItestSecondIface\n");
1760 return S_OK;
1761}
1762
1763static const IStaticWidgetVtbl StaticWidgetVtbl = {
1773};
1774
1775static IStaticWidget StaticWidget = { &StaticWidgetVtbl };
1776
1777typedef struct KindaEnum
1778{
1779 IKindaEnumWidget IKindaEnumWidget_iface;
1782
1783static inline KindaEnum *impl_from_IKindaEnumWidget(IKindaEnumWidget *iface)
1784{
1785 return CONTAINING_RECORD(iface, KindaEnum, IKindaEnumWidget_iface);
1786}
1787
1789{
1792 HRESULT hr;
1794
1797
1799 if (SUCCEEDED(hr))
1800 {
1802 ITypeLib_Release(typelib);
1803 }
1804 return hr;
1805}
1806
1808{
1809 ITypeInfo *pTypeInfo;
1810 ITypeLib *pTypeLib;
1811 HRESULT hr;
1812
1813 hr = LoadRegTypeLib(&LIBID_TestTypelib, 2, 5, LOCALE_NEUTRAL, &pTypeLib);
1815 if (FAILED(hr))
1816 return NULL;
1817
1818 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, riid, &pTypeInfo);
1819 ITypeLib_Release(pTypeLib);
1820 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
1821 if (FAILED(hr))
1822 return NULL;
1823
1824 return pTypeInfo;
1825}
1826
1827static IWidget *Widget_Create(void)
1828{
1829 Widget *This;
1830 ITypeInfo *pTypeInfo;
1831 HRESULT hr = E_FAIL;
1832
1833 pTypeInfo = get_type_info(&IID_IWidget);
1834 if(!pTypeInfo)
1835 return NULL;
1836
1837 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1838 This->IWidget_iface.lpVtbl = &Widget_VTable;
1839 This->refs = 1;
1840 This->pDispatchUnknown = NULL;
1841
1842 hr = CreateStdDispatch((IUnknown *)&This->IWidget_iface, This, pTypeInfo,
1843 &This->pDispatchUnknown);
1845 ITypeInfo_Release(pTypeInfo);
1846
1847 if (SUCCEEDED(hr))
1848 return &This->IWidget_iface;
1849 else
1850 {
1852 return NULL;
1853 }
1854}
1855
1857 IKindaEnumWidget *iface,
1858 /* [in] */ REFIID riid,
1859 /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
1860{
1861 if (IsEqualIID(riid, &IID_IKindaEnumWidget) || IsEqualIID(riid, &IID_IUnknown))
1862 {
1863 IKindaEnumWidget_AddRef(iface);
1864 *ppvObject = iface;
1865 return S_OK;
1866 }
1867 else
1868 {
1869 *ppvObject = NULL;
1870 return E_NOINTERFACE;
1871 }
1872}
1873
1875 IKindaEnumWidget *iface)
1876{
1878
1879 return InterlockedIncrement(&This->refs);
1880}
1881
1883 IKindaEnumWidget *iface)
1884{
1886 ULONG refs = InterlockedDecrement(&This->refs);
1887 if (!refs)
1888 {
1889 memset(This, 0xcc, sizeof(*This));
1891 trace("KindaEnumWidget destroyed!\n");
1892 }
1893
1894 return refs;
1895}
1896
1898 IKindaEnumWidget *iface,
1899 /* [out] */ IWidget __RPC_FAR *__RPC_FAR *widget)
1900{
1901 *widget = Widget_Create();
1902 if (*widget)
1903 return S_OK;
1904 else
1905 return E_OUTOFMEMORY;
1906}
1907
1909 IKindaEnumWidget *iface,
1910 /* [out] */ ULONG __RPC_FAR *count)
1911{
1912 return E_NOTIMPL;
1913}
1914
1916 IKindaEnumWidget *iface)
1917{
1918 return E_NOTIMPL;
1919}
1920
1922 IKindaEnumWidget *iface,
1923 /* [out] */ IKindaEnumWidget __RPC_FAR *__RPC_FAR *ppenum)
1924{
1925 return E_NOTIMPL;
1926}
1927
1928static const IKindaEnumWidgetVtbl KindaEnumWidget_VTable =
1929{
1937};
1938
1939static IKindaEnumWidget *KindaEnumWidget_Create(void)
1940{
1941 KindaEnum *This;
1942
1943 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1944 if (!This) return NULL;
1945 This->IKindaEnumWidget_iface.lpVtbl = &KindaEnumWidget_VTable;
1946 This->refs = 1;
1947 return &This->IKindaEnumWidget_iface;
1948}
1949
1950static HRESULT WINAPI NonOleAutomation_QueryInterface(INonOleAutomation *iface, REFIID riid, void **ppv)
1951{
1952 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_INonOleAutomation))
1953 {
1954 *(INonOleAutomation **)ppv = iface;
1955 return S_OK;
1956 }
1957 *ppv = NULL;
1958 return E_NOINTERFACE;
1959}
1960
1961static ULONG WINAPI NonOleAutomation_AddRef(INonOleAutomation *iface)
1962{
1963 return 2;
1964}
1965
1966static ULONG WINAPI NonOleAutomation_Release(INonOleAutomation *iface)
1967{
1968 return 1;
1969}
1970
1971static BSTR WINAPI NonOleAutomation_BstrRet(INonOleAutomation *iface)
1972{
1973 static const WCHAR wszTestString[] = {'T','h','i','s',' ','i','s',' ','a',' ','t','e','s','t',' ','s','t','r','i','n','g',0};
1974 return SysAllocString(wszTestString);
1975}
1976
1977static HRESULT WINAPI NonOleAutomation_Error(INonOleAutomation *iface)
1978{
1979 return E_NOTIMPL;
1980}
1981
1982static INonOleAutomationVtbl NonOleAutomation_VTable =
1983{
1989};
1990
1991static INonOleAutomation NonOleAutomation = { &NonOleAutomation_VTable };
1992
1994{
1995 ITypeLib *pTypeLib;
1996 HRESULT hr = LoadRegTypeLib(&LIBID_TestTypelib, 2, 5, LOCALE_NEUTRAL, &pTypeLib);
1998 if (SUCCEEDED(hr))
1999 {
2000 ITypeInfo *pTypeInfo;
2001 hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_INonOleAutomation, &pTypeInfo);
2002 ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
2003 ITypeLib_Release(pTypeLib);
2004 return pTypeInfo;
2005 }
2006 return NULL;
2007}
2008
2009static void test_marshal_basetypes(IWidget *widget, IDispatch *disp)
2010{
2011 VARIANTARG arg[11];
2012 DISPPARAMS dispparams = {arg, NULL, ARRAY_SIZE(arg), 0};
2013 HRESULT hr;
2014
2015 signed char c;
2016 short s;
2017 LONG l;
2018 int i, i2, *pi;
2019 hyper h;
2020 unsigned char uc;
2021 unsigned short us;
2022 ULONG ul;
2023 MIDL_uhyper uh;
2024 float f;
2025 double d;
2026 STATE st;
2027
2028 V_VT(&arg[10]) = VT_I1; V_I1(&arg[10]) = 5;
2029 V_VT(&arg[9]) = VT_I2; V_I2(&arg[9]) = -123;
2030 V_VT(&arg[8]) = VT_I4; V_I4(&arg[8]) = -100000;
2031 V_VT(&arg[7]) = VT_I8; V_I8(&arg[7]) = (LONGLONG)-100000 * 1000000;
2032 V_VT(&arg[6]) = VT_UI1; V_UI1(&arg[6]) = 0;
2033 V_VT(&arg[5]) = VT_UI2; V_UI2(&arg[5]) = 456;
2034 V_VT(&arg[4]) = VT_UI4; V_UI4(&arg[4]) = 0xdeadbeef;
2035 V_VT(&arg[3]) = VT_UI8; V_UI8(&arg[3]) = (ULONGLONG)1234567890 * 9876543210;
2036 V_VT(&arg[2]) = VT_R4; V_R4(&arg[2]) = M_PI;
2037 V_VT(&arg[1]) = VT_R8; V_R8(&arg[1]) = M_E;
2038 V_VT(&arg[0]) = VT_I4; V_I4(&arg[0]) = STATE_WIDGETIFIED;
2039 hr = IDispatch_Invoke(disp, DISPID_TM_BASETYPES_IN, &IID_NULL, LOCALE_NEUTRAL,
2040 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2041 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2042
2043 hr = IWidget_basetypes_in(widget, 5, -123, -100000, (LONGLONG)-100000 * 1000000, 0, 456,
2044 0xdeadbeef, (ULONGLONG)1234567890 * 9876543210, M_PI, M_E, STATE_WIDGETIFIED);
2045 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2046
2047 c = s = l = h = uc = us = ul = uh = f = d = st = 0;
2048
2049 V_VT(&arg[10]) = VT_BYREF|VT_I1; V_I1REF(&arg[10]) = &c;
2050 V_VT(&arg[9]) = VT_BYREF|VT_I2; V_I2REF(&arg[9]) = &s;
2051 V_VT(&arg[8]) = VT_BYREF|VT_I4; V_I4REF(&arg[8]) = &l;
2052 V_VT(&arg[7]) = VT_BYREF|VT_I8; V_I8REF(&arg[7]) = &h;
2053 V_VT(&arg[6]) = VT_BYREF|VT_UI1; V_UI1REF(&arg[6]) = &uc;
2054 V_VT(&arg[5]) = VT_BYREF|VT_UI2; V_UI2REF(&arg[5]) = &us;
2055 V_VT(&arg[4]) = VT_BYREF|VT_UI4; V_UI4REF(&arg[4]) = &ul;
2056 V_VT(&arg[3]) = VT_BYREF|VT_UI8; V_UI8REF(&arg[3]) = &uh;
2057 V_VT(&arg[2]) = VT_BYREF|VT_R4; V_R4REF(&arg[2]) = &f;
2058 V_VT(&arg[1]) = VT_BYREF|VT_R8; V_R8REF(&arg[1]) = &d;
2059 V_VT(&arg[0]) = VT_BYREF|VT_I4; V_I4REF(&arg[0]) = (LONG *)&st;
2060 hr = IDispatch_Invoke(disp, DISPID_TM_BASETYPES_OUT, &IID_NULL, LOCALE_NEUTRAL,
2061 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2062 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2063 ok(c == 10, "Got char %d.\n", c);
2064 ok(s == -321, "Got short %d.\n", s);
2065 ok(l == -200000, "Got int %ld.\n", l);
2066 ok(h == (LONGLONG)-200000 * 1000000L, "Got hyper %s.\n", wine_dbgstr_longlong(h));
2067 ok(uc == 254, "Got unsigned char %u.\n", uc);
2068 ok(us == 256, "Got unsigned short %u.\n", us);
2069 ok(ul == 0xf00dfade, "Got unsigned int %li.\n", ul);
2070 ok(uh == 0xabcdef0123456789ull, "Got unsigned hyper %s.\n", wine_dbgstr_longlong(uh));
2071 ok(f == (float)M_LN2, "Got float %f.\n", f);
2072 ok(d == M_LN10, "Got double %f.\n", d);
2073 ok(st == STATE_UNWIDGETIFIED, "Got state %u.\n", st);
2074
2075 c = s = l = h = uc = us = ul = uh = f = d = st = 0;
2076
2077 hr = IWidget_basetypes_out(widget, &c, &s, &l, &h, &uc, &us, &ul, &uh, &f, &d, &st);
2078 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2079 ok(c == 10, "Got char %d.\n", c);
2080 ok(s == -321, "Got short %d.\n", s);
2081 ok(l == -200000, "Got int %ld.\n", l);
2082 ok(h == (LONGLONG)-200000 * 1000000L, "Got hyper %s.\n", wine_dbgstr_longlong(h));
2083 ok(uc == 254, "Got unsigned char %u.\n", uc);
2084 ok(us == 256, "Got unsigned short %u.\n", us);
2085 ok(ul == 0xf00dfade, "Got unsigned int %li.\n", ul);
2086 ok(uh == 0xabcdef0123456789ull, "Got unsigned hyper %s.\n", wine_dbgstr_longlong(uh));
2087 ok(f == (float)M_LN2, "Got float %f.\n", f);
2088 ok(d == M_LN10, "Got double %f.\n", d);
2089 ok(st == STATE_UNWIDGETIFIED, "Got state %u.\n", st);
2090
2091 /* Test marshalling of public typedefs. */
2092
2093 i = 456;
2094 i2 = 789;
2095 pi = &i2;
2096 hr = IWidget_myint(widget, 123, &i, &pi);
2097 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2098
2099 /* Test that different float ABIs are correctly handled. */
2100
2101 hr = IWidget_float_abi(widget, 1.0f, 2.0, 3, 4.0f, 5.0);
2102 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2103}
2104
2105static void test_marshal_pointer(IWidget *widget, IDispatch *disp)
2106{
2107 VARIANTARG arg[3];
2108 DISPPARAMS dispparams = {arg, NULL, ARRAY_SIZE(arg), 0};
2109 LONG in, out, in_out, *in_ptr, *out_ptr, *in_out_ptr;
2110 HRESULT hr;
2111
2112 testmode = 0;
2113
2114 in = 123;
2115 out = 456;
2116 in_out = 789;
2117 V_VT(&arg[2]) = VT_BYREF|VT_I4; V_I4REF(&arg[2]) = &in;
2118 V_VT(&arg[1]) = VT_BYREF|VT_I4; V_I4REF(&arg[1]) = &out;
2119 V_VT(&arg[0]) = VT_BYREF|VT_I4; V_I4REF(&arg[0]) = &in_out;
2120 hr = IDispatch_Invoke(disp, DISPID_TM_INT_PTR, &IID_NULL, LOCALE_NEUTRAL,
2121 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2122 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2123 ok(in == 987, "Got [in] %ld.\n", in);
2124 ok(out == 654, "Got [out] %ld.\n", out);
2125 ok(in_out == 321, "Got [in, out] %ld.\n", in_out);
2126
2127 testmode = 1;
2128
2129 in = 123;
2130 out = 456;
2131 in_out = 789;
2132 hr = IWidget_long_ptr(widget, &in, &out, &in_out);
2133 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2134 ok(in == 123, "Got [in] %ld.\n", in);
2135 ok(out == 654, "Got [out] %ld.\n", out);
2136 ok(in_out == 321, "Got [in, out] %ld.\n", in_out);
2137
2138 out = in_out = -1;
2139 hr = IWidget_long_ptr(widget, NULL, &out, &in_out);
2140 ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#lx.\n", hr);
2141 ok(!out, "[out] parameter should have been cleared.\n");
2142 ok(in_out == -1, "[in, out] parameter should not have been cleared.\n");
2143
2144 in = in_out = -1;
2145 hr = IWidget_long_ptr(widget, &in, NULL, &in_out);
2146 ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#lx.\n", hr);
2147 ok(in == -1, "[in] parameter should not have been cleared.\n");
2148 ok(in_out == -1, "[in, out] parameter should not have been cleared.\n");
2149
2150 in = out = -1;
2151 hr = IWidget_long_ptr(widget, &in, &out, NULL);
2152 ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#lx.\n", hr);
2153 ok(in == -1, "[in] parameter should not have been cleared.\n");
2154 ok(!out, "[out] parameter should have been cleared.\n");
2155
2156 /* We can't test Invoke() with double pointers, as it is not possible to fit
2157 * more than one level of indirection into a VARIANTARG. */
2158
2159 testmode = 0;
2160 in_ptr = out_ptr = in_out_ptr = NULL;
2161 hr = IWidget_long_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
2162 ok(hr == S_OK, "Got hr %#lx\n", hr);
2163 ok(!in_ptr, "Got [in] %p.\n", in_ptr);
2164 ok(!out_ptr, "Got [out] %p.\n", out_ptr);
2165 ok(!in_out_ptr, "Got [in, out] %p.\n", in_out_ptr);
2166
2167 testmode = 1;
2168 hr = IWidget_long_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
2169 ok(hr == S_OK, "Got hr %#lx\n", hr);
2170 ok(*out_ptr == 654, "Got [out] %ld.\n", *out_ptr);
2171 ok(*in_out_ptr == 321, "Got [in, out] %ld.\n", *in_out_ptr);
2172 CoTaskMemFree(out_ptr);
2173 CoTaskMemFree(in_out_ptr);
2174
2175 testmode = 2;
2176 in = 123;
2177 out = 456;
2178 in_out = 789;
2179 in_ptr = &in;
2180 out_ptr = &out;
2181 in_out_ptr = &in_out;
2182 hr = IWidget_long_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
2183 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2184 ok(out_ptr != &out, "[out] ptr should have changed.\n");
2185 ok(in_out_ptr == &in_out, "[in, out] ptr should not have changed.\n");
2186 ok(*out_ptr == 654, "Got [out] %ld.\n", *out_ptr);
2187 ok(*in_out_ptr == 321, "Got [in, out] %ld.\n", *in_out_ptr);
2188
2189 testmode = 3;
2190 in_ptr = out_ptr = NULL;
2191 in_out = 789;
2192 in_out_ptr = &in_out;
2193 hr = IWidget_long_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
2194 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2195 ok(!in_out_ptr, "Got [in, out] %p.\n", in_out_ptr);
2196
2197 out_ptr = &out;
2198 in_out_ptr = &in_out;
2199 hr = IWidget_long_ptr_ptr(widget, NULL, &out_ptr, &in_out_ptr);
2200 ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#lx.\n", hr);
2201 ok(!out_ptr, "[out] parameter should have been cleared.\n");
2202 ok(in_out_ptr == &in_out, "[in, out] parameter should not have been cleared.\n");
2203
2204 in_ptr = &in;
2205 in_out_ptr = &in_out;
2206 hr = IWidget_long_ptr_ptr(widget, &in_ptr, NULL, &in_out_ptr);
2207 ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#lx.\n", hr);
2208 ok(in_ptr == &in, "[in] parameter should not have been cleared.\n");
2209 ok(in_out_ptr == &in_out, "[in, out] parameter should not have been cleared.\n");
2210
2211 in_ptr = &in;
2212 out_ptr = &out;
2213 hr = IWidget_long_ptr_ptr(widget, &in_ptr, &out_ptr, NULL);
2214 ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#lx.\n", hr);
2215 ok(in_ptr == &in, "[in] parameter should not have been cleared.\n");
2216 ok(!out_ptr, "[out] parameter should have been cleared.\n");
2217}
2218
2219static void test_marshal_iface(IWidget *widget, IDispatch *disp)
2220{
2221 VARIANTARG arg[3];
2222 DISPPARAMS dispparams = {arg, NULL, ARRAY_SIZE(arg), 0};
2223 ISomethingFromDispatch *sfd1, *sfd2, *sfd3, *proxy_sfd, *sfd_in, *sfd_out, *sfd_in_out;
2224 IUnknown *proxy_unk, *proxy_unk2, *unk_in, *unk_out, *unk_in_out;
2225 IDispatch *proxy_disp;
2226 IUnknown unk_noptr;
2227 IDispatch disp_noptr;
2228 ISomethingFromDispatch sfd_noptr;
2229 HRESULT hr;
2230
2231 testmode = 0;
2232 sfd1 = create_disp_obj();
2233 sfd2 = create_disp_obj();
2234 sfd3 = create_disp_obj();
2235 hr = IWidget_iface_in(widget, (IUnknown *)sfd1,
2236 (IDispatch *)sfd2, sfd3);
2237 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2238 release_iface(sfd1);
2239 release_iface(sfd2);
2240 release_iface(sfd3);
2241
2242 testmode = 1;
2243 hr = IWidget_iface_in(widget, NULL, NULL, NULL);
2244 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2245
2246 testmode = 0;
2247 proxy_unk = (IUnknown *)0xdeadbeef;
2248 proxy_disp = (IDispatch *)0xdeadbeef;
2249 proxy_sfd = (ISomethingFromDispatch *)0xdeadbeef;
2250 hr = IWidget_iface_out(widget, &proxy_unk, &proxy_disp, &proxy_sfd);
2251 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2252 check_iface_marshal(proxy_unk, proxy_disp, proxy_sfd);
2253 release_iface(proxy_unk);
2254 release_iface(proxy_disp);
2255 release_iface(proxy_sfd);
2256
2257 testmode = 1;
2258 hr = IWidget_iface_out(widget, &proxy_unk, &proxy_disp, &proxy_sfd);
2259 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2260 ok(!proxy_unk, "Got unexpected proxy %p.\n", proxy_unk);
2261 ok(!proxy_disp, "Got unexpected proxy %p.\n", proxy_disp);
2262 ok(!proxy_sfd, "Got unexpected proxy %p.\n", proxy_sfd);
2263
2264 testmode = 0;
2265 sfd_in = sfd1 = create_disp_obj();
2266 sfd_out = sfd2 = create_disp_obj();
2267 sfd_in_out = sfd3 = create_disp_obj();
2268 hr = IWidget_iface_ptr(widget, &sfd_in, &sfd_out, &sfd_in_out);
2269 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2270 ok(sfd_in == sfd1, "[in] parameter should not have changed.\n");
2271 ok(!sfd_out, "[out] parameter should have been cleared.\n");
2272 ok(sfd_in_out == sfd3, "[in, out] parameter should not have changed.\n");
2273 release_iface(sfd1);
2274 release_iface(sfd2);
2275 release_iface(sfd3);
2276
2277 testmode = 1;
2278 sfd_in = sfd1 = create_disp_obj();
2279 sfd_in_out = sfd3 = create_disp_obj();
2280 ISomethingFromDispatch_AddRef(sfd_in_out);
2281 hr = IWidget_iface_ptr(widget, &sfd_in, &sfd_out, &sfd_in_out);
2282 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2283 hr = ISomethingFromDispatch_anotherfn(sfd_out);
2284 ok(hr == 0x01234567, "Got hr %#lx.\n", hr);
2285 ok(sfd_in_out != sfd3, "[in, out] parameter should have changed.\n");
2286 hr = ISomethingFromDispatch_anotherfn(sfd_in_out);
2287 ok(hr == 0x01234567, "Got hr %#lx.\n", hr);
2288 release_iface(sfd_out);
2289 release_iface(sfd_in_out);
2290 release_iface(sfd1);
2291 release_iface(sfd3);
2292
2293 testmode = 2;
2294 sfd_in = sfd_out = sfd_in_out = NULL;
2295 hr = IWidget_iface_ptr(widget, &sfd_in, &sfd_out, &sfd_in_out);
2296 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2297 ok(!sfd_out, "[out] parameter should not have been set.\n");
2298 hr = ISomethingFromDispatch_anotherfn(sfd_in_out);
2299 ok(hr == 0x01234567, "Got hr %#lx.\n", hr);
2300 release_iface(sfd_in_out);
2301
2302 testmode = 3;
2303 sfd_in = sfd_out = NULL;
2304 sfd_in_out = sfd3 = create_disp_obj();
2305 ISomethingFromDispatch_AddRef(sfd_in_out);
2306 hr = IWidget_iface_ptr(widget, &sfd_in, &sfd_out, &sfd_in_out);
2307 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2308 ok(!sfd_in_out, "Got [in, out] %p.\n", sfd_in_out);
2309 release_iface(sfd3);
2310
2311 sfd1 = create_disp_obj();
2312 sfd2 = create_disp_obj();
2313 sfd3 = create_disp_obj();
2314 unk_noptr.lpVtbl = (IUnknownVtbl *)sfd1;
2315 disp_noptr.lpVtbl = (IDispatchVtbl *)sfd2;
2316 sfd_noptr.lpVtbl = (ISomethingFromDispatchVtbl *)sfd3;
2317 hr = IWidget_iface_noptr(widget, unk_noptr, disp_noptr, sfd_noptr);
2318 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2319 release_iface(sfd1);
2320 release_iface(sfd2);
2321 release_iface(sfd3);
2322
2323 /* Test with Invoke(). Note that since we pass VT_UNKNOWN, we don't get our
2324 * interface back, but rather an IUnknown. */
2325
2326 testmode = 0;
2327 sfd1 = create_disp_obj();
2328 sfd2 = create_disp_obj();
2329 sfd3 = create_disp_obj();
2330
2331 V_VT(&arg[2]) = VT_UNKNOWN; V_UNKNOWN(&arg[2]) = (IUnknown *)sfd1;
2332 V_VT(&arg[1]) = VT_UNKNOWN; V_UNKNOWN(&arg[1]) = (IUnknown *)sfd2;
2333 V_VT(&arg[0]) = VT_UNKNOWN; V_UNKNOWN(&arg[0]) = (IUnknown *)sfd3;
2334 hr = IDispatch_Invoke(disp, DISPID_TM_IFACE_IN, &IID_NULL, LOCALE_NEUTRAL,
2335 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2336 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2337
2338 V_VT(&arg[2]) = VT_DISPATCH; V_DISPATCH(&arg[2]) = (IDispatch *)sfd1;
2339 V_VT(&arg[1]) = VT_DISPATCH; V_DISPATCH(&arg[1]) = (IDispatch *)sfd2;
2340 V_VT(&arg[0]) = VT_DISPATCH; V_DISPATCH(&arg[0]) = (IDispatch *)sfd3;
2341 hr = IDispatch_Invoke(disp, DISPID_TM_IFACE_IN, &IID_NULL, LOCALE_NEUTRAL,
2342 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2343 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2344
2345 release_iface(sfd1);
2346 release_iface(sfd2);
2347 release_iface(sfd3);
2348
2349 testmode = 1;
2350 V_VT(&arg[2]) = VT_UNKNOWN; V_UNKNOWN(&arg[2]) = NULL;
2351 V_VT(&arg[1]) = VT_UNKNOWN; V_UNKNOWN(&arg[1]) = NULL;
2352 V_VT(&arg[0]) = VT_UNKNOWN; V_UNKNOWN(&arg[0]) = NULL;
2353 hr = IDispatch_Invoke(disp, DISPID_TM_IFACE_IN, &IID_NULL, LOCALE_NEUTRAL,
2354 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2355 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2356
2357 testmode = 0;
2358 proxy_unk = proxy_unk2 = NULL;
2359 proxy_disp = NULL;
2360 V_VT(&arg[2]) = VT_UNKNOWN|VT_BYREF; V_UNKNOWNREF(&arg[2]) = &proxy_unk;
2361 V_VT(&arg[1]) = VT_DISPATCH|VT_BYREF; V_DISPATCHREF(&arg[1]) = &proxy_disp;
2362 V_VT(&arg[0]) = VT_UNKNOWN|VT_BYREF; V_UNKNOWNREF(&arg[0]) = &proxy_unk2;
2363 hr = IDispatch_Invoke(disp, DISPID_TM_IFACE_OUT, &IID_NULL, LOCALE_NEUTRAL,
2364 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2365 todo_wine
2366 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2367if (hr == S_OK) {
2368 hr = IUnknown_QueryInterface(proxy_unk2, &IID_ISomethingFromDispatch, (void **)&proxy_sfd);
2369 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2370 check_iface_marshal(proxy_unk, proxy_disp, proxy_sfd);
2371 ISomethingFromDispatch_Release(proxy_sfd);
2372 release_iface(proxy_unk);
2373 release_iface(proxy_disp);
2374 release_iface(proxy_unk2);
2375}
2376
2377 testmode = 1;
2378 proxy_unk = proxy_unk2 = NULL;
2379 proxy_disp = NULL;
2380 hr = IDispatch_Invoke(disp, DISPID_TM_IFACE_OUT, &IID_NULL, LOCALE_NEUTRAL,
2381 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2382 todo_wine
2383 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2384 ok(!proxy_unk, "Got unexpected proxy %p.\n", proxy_unk);
2385 ok(!proxy_disp, "Got unexpected proxy %p.\n", proxy_disp);
2386 ok(!proxy_unk2, "Got unexpected proxy %p.\n", proxy_unk2);
2387
2388 testmode = 0;
2389 sfd1 = create_disp_obj();
2390 sfd3 = create_disp_obj();
2391 unk_in = (IUnknown *)sfd1;
2392 unk_out = NULL;
2393 unk_in_out = (IUnknown *)sfd3;
2396 V_VT(&arg[0]) = VT_UNKNOWN|VT_BYREF; V_UNKNOWNREF(&arg[0]) = &unk_in_out;
2397 hr = IDispatch_Invoke(disp, DISPID_TM_IFACE_PTR, &IID_NULL, LOCALE_NEUTRAL,
2398 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2399 todo_wine
2400 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2401 ok(unk_in == (IUnknown *)sfd1, "[in] parameter should not have changed.\n");
2402 ok(!unk_out, "[out] parameter should have been cleared.\n");
2403 ok(unk_in_out == (IUnknown *)sfd3, "[in, out] parameter should not have changed.\n");
2404 release_iface(sfd1);
2405 release_iface(sfd3);
2406
2407 testmode = 1;
2408 sfd1 = create_disp_obj();
2409 sfd3 = create_disp_obj();
2410 unk_in = (IUnknown *)sfd1;
2411 unk_out = NULL;
2412 unk_in_out = (IUnknown *)sfd3;
2413 IUnknown_AddRef(unk_in_out);
2414 hr = IDispatch_Invoke(disp, DISPID_TM_IFACE_PTR, &IID_NULL, LOCALE_NEUTRAL,
2415 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2416 todo_wine
2417 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2418
2419if (hr == S_OK) {
2420 hr = IUnknown_QueryInterface(unk_out, &IID_ISomethingFromDispatch, (void **)&sfd_out);
2421 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2422 hr = ISomethingFromDispatch_anotherfn(sfd_out);
2423 ok(hr == 0x01234567, "Got hr %#lx.\n", hr);
2424 ISomethingFromDispatch_Release(sfd_out);
2425
2426 ok(unk_in_out != (IUnknown *)sfd3, "[in, out] parameter should have changed.\n");
2427 hr = IUnknown_QueryInterface(unk_in_out, &IID_ISomethingFromDispatch, (void **)&sfd_in_out);
2428 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2429 hr = ISomethingFromDispatch_anotherfn(sfd_in_out);
2430 ok(hr == 0x01234567, "Got hr %#lx.\n", hr);
2431 ISomethingFromDispatch_Release(sfd_in_out);
2432
2434 release_iface(unk_in_out);
2435}
2436 release_iface(sfd1);
2437 todo_wine
2438 release_iface(sfd3);
2439
2440 testmode = 2;
2441 unk_in = unk_out = unk_in_out = NULL;
2442 hr = IDispatch_Invoke(disp, DISPID_TM_IFACE_PTR, &IID_NULL, LOCALE_NEUTRAL,
2443 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2444 todo_wine
2445 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2446
2447 ok(!unk_out, "[out] parameter should not have been set.\n");
2448if (hr == S_OK) {
2449 hr = IUnknown_QueryInterface(unk_in_out, &IID_ISomethingFromDispatch, (void **)&sfd_in_out);
2450 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2451 hr = ISomethingFromDispatch_anotherfn(sfd_in_out);
2452 ok(hr == 0x01234567, "Got hr %#lx.\n", hr);
2453 ISomethingFromDispatch_Release(sfd_in_out);
2454
2455 release_iface(unk_in_out);
2456}
2457
2458 testmode = 3;
2459 unk_in = unk_out = NULL;
2460 sfd3 = create_disp_obj();
2461 unk_in_out = (IUnknown *)sfd3;
2462 IUnknown_AddRef(unk_in_out);
2463 hr = IDispatch_Invoke(disp, DISPID_TM_IFACE_PTR, &IID_NULL, LOCALE_NEUTRAL,
2464 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2465todo_wine {
2466 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2467 ok(!unk_in_out, "[in, out] parameter should have been cleared.\n");
2468 release_iface(sfd3);
2469}
2470}
2471
2472static void test_marshal_bstr(IWidget *widget, IDispatch *disp)
2473{
2474 VARIANTARG arg[4];
2475 DISPPARAMS dispparams = {arg, NULL, ARRAY_SIZE(arg), 0};
2476 BSTR in, out, in_ptr, in_out;
2477 HRESULT hr;
2478 UINT len;
2479
2480 testmode = 0;
2482 out = NULL;
2483 in_ptr = SysAllocString(test_bstr2);
2484 in_out = SysAllocString(test_bstr3);
2485
2486 V_VT(&arg[3]) = VT_BSTR; V_BSTR(&arg[3]) = in;
2487 V_VT(&arg[2]) = VT_BSTR|VT_BYREF; V_BSTRREF(&arg[2]) = &out;
2488 V_VT(&arg[1]) = VT_BSTR|VT_BYREF; V_BSTRREF(&arg[1]) = &in_ptr;
2489 V_VT(&arg[0]) = VT_BSTR|VT_BYREF; V_BSTRREF(&arg[0]) = &in_out;
2490 hr = IDispatch_Invoke(disp, DISPID_TM_BSTR, &IID_NULL, LOCALE_NEUTRAL,
2491 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2492 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2493 ok(in[1] == test_bstr1[1], "[in] parameter should not be changed.\n");
2494 ok(in_ptr[1] == 'X', "[in] pointer should be changed.\n");
2495 ok(in_out[1] == 'X', "[in, out] parameter should be changed.\n");
2496 len = SysStringLen(out);
2497 ok(len == lstrlenW(test_bstr4), "Got wrong length %d.\n", len);
2498 ok(!memcmp(out, test_bstr4, len), "Got string %s.\n", wine_dbgstr_wn(out, len));
2499
2500 in[1] = test_bstr1[1];
2501 in_ptr[1] = test_bstr2[1];
2502 in_out[1] = test_bstr3[1];
2504 out = (BSTR)0xdeadbeef;
2505 hr = IWidget_bstr(widget, in, &out, &in_ptr, &in_out);
2506 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2507 ok(in[1] == test_bstr1[1], "[in] parameter should not be changed.\n");
2508 ok(in_ptr[1] == test_bstr2[1], "[in] pointer should not be changed.\n");
2509 ok(in_out[1] == 'X', "[in, out] parameter should be changed.\n");
2510 len = SysStringLen(out);
2511 ok(len == lstrlenW(test_bstr4), "Got wrong length %d.\n", len);
2512 ok(!memcmp(out, test_bstr4, len), "Got string %s.\n", wine_dbgstr_wn(out, len));
2515 SysFreeString(in_ptr);
2516 SysFreeString(in_out);
2517
2518 testmode = 1;
2519 out = in_ptr = in_out = NULL;
2520 hr = IWidget_bstr(widget, NULL, &out, &in_ptr, &in_out);
2521 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2522
2523 in = SysAllocString(L"test");
2524 hr = IWidget_no_in_out(widget, in, 5);
2525 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2526}
2527
2528static void test_marshal_variant(IWidget *widget, IDispatch *disp)
2529{
2530 VARIANTARG arg[4];
2531 DISPPARAMS dispparams = {arg, NULL, ARRAY_SIZE(arg), 0};
2532 VARIANT out, in_ptr, in_out;
2533 HRESULT hr;
2534 BSTR bstr;
2535
2536 testmode = 0;
2537 V_VT(&out) = VT_I4;
2538 V_I4(&out) = 1;
2539 V_VT(&in_ptr) = VT_I4;
2540 V_I4(&in_ptr) = -1;
2541 V_VT(&in_out) = VT_BSTR;
2542 V_BSTR(&in_out) = bstr = SysAllocString(test_bstr2);
2543
2544 V_VT(&arg[3]) = VT_CY;
2545 V_CY(&arg[3]).Hi = 0xdababe;
2546 V_CY(&arg[3]).Lo = 0xdeadbeef;
2547 V_VT(&arg[2]) = VT_VARIANT|VT_BYREF; V_VARIANTREF(&arg[2]) = &out;
2548 V_VT(&arg[1]) = VT_VARIANT|VT_BYREF; V_VARIANTREF(&arg[1]) = &in_ptr;
2549 V_VT(&arg[0]) = VT_VARIANT|VT_BYREF; V_VARIANTREF(&arg[0]) = &in_out;
2550 hr = IDispatch_Invoke(disp, DISPID_TM_VARIANT, &IID_NULL, LOCALE_NEUTRAL,
2551 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2552 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2553 ok(V_VT(&arg[3]) == VT_CY, "Got wrong type %u.\n", V_VT(&arg[3]));
2554 ok(V_VT(&out) == VT_UI1, "Got wrong type %u.\n", V_VT(&out));
2555 ok(V_UI1(&out) == 3, "Got wrong value %d.\n", V_UI1(&out));
2556 VariantClear(&out);
2557 ok(V_VT(&in_ptr) == VT_I2, "Got wrong type %u.\n", V_VT(&in_ptr));
2558 ok(V_I2(&in_ptr) == 4, "Got wrong value %d.\n", V_I1(&in_ptr));
2559 ok(V_VT(&in_out) == VT_I1, "Got wrong type %u.\n", V_VT(&in_out));
2560 ok(V_I1(&in_out) == 5, "Got wrong value %d.\n", V_I1(&in_out));
2561
2562 testmode = 1;
2563 V_VT(&out) = VT_I4;
2564 V_I4(&out) = 1;
2565 V_VT(&in_ptr) = VT_I4;
2566 V_I4(&in_ptr) = -1;
2567 V_VT(&in_out) = VT_BSTR;
2568 V_BSTR(&in_out) = bstr = SysAllocString(test_bstr2);
2569 hr = IWidget_variant(widget, arg[3], &out, &in_ptr, &in_out);
2570 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2571 ok(V_VT(&arg[3]) == VT_CY, "Got wrong type %u.\n", V_VT(&arg[3]));
2572 ok(V_VT(&out) == VT_UI1, "Got wrong type %u.\n", V_VT(&out));
2573 ok(V_UI1(&out) == 3, "Got wrong value %d.\n", V_UI1(&out));
2574 ok(V_VT(&in_ptr) == VT_I4, "Got wrong type %u.\n", V_VT(&in_ptr));
2575 ok(V_I2(&in_ptr) == -1, "Got wrong value %d.\n", V_I1(&in_ptr));
2576 ok(V_VT(&in_out) == VT_I1, "Got wrong type %u.\n", V_VT(&in_out));
2577 ok(V_I1(&in_out) == 5, "Got wrong value %d.\n", V_I1(&in_out));
2578}
2579
2580static void test_marshal_safearray(IWidget *widget, IDispatch *disp)
2581{
2582 SAFEARRAY *in, *out, *out2, *in_ptr, *in_out;
2583 HRESULT hr;
2584
2585 in = make_safearray(3);
2586 out = out2 = make_safearray(5);
2587 in_ptr = make_safearray(7);
2588 in_out = make_safearray(9);
2589 hr = IWidget_safearray(widget, in, &out, &in_ptr, &in_out);
2590 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2591 check_safearray(in, 3);
2592 check_safearray(out, 4);
2593 check_safearray(out2, 5);
2594 check_safearray(in_ptr, 7);
2595 check_safearray(in_out, 6);
2596
2599 SafeArrayDestroy(out2);
2600 SafeArrayDestroy(in_ptr);
2601 SafeArrayDestroy(in_out);
2602}
2603
2604static void test_marshal_struct(IWidget *widget, IDispatch *disp)
2605{
2606 MYSTRUCT out, in_ptr, in_out, *in_ptr_ptr;
2607 RECT rect_out, rect_in_ptr, rect_in_out;
2608 ISomethingFromDispatch *sfd;
2609 struct complex complex;
2610 int i, i2, *pi = &i2;
2611 HRESULT hr;
2612
2613 memcpy(&out, &test_mystruct2, sizeof(MYSTRUCT));
2614 memcpy(&in_ptr, &test_mystruct3, sizeof(MYSTRUCT));
2615 memcpy(&in_out, &test_mystruct4, sizeof(MYSTRUCT));
2616 hr = IWidget_mystruct(widget, test_mystruct1, &out, &in_ptr, &in_out);
2617 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2618 ok(!memcmp(&out, &test_mystruct5, sizeof(MYSTRUCT)), "Structs didn't match.\n");
2619 ok(!memcmp(&in_ptr, &test_mystruct3, sizeof(MYSTRUCT)), "Structs didn't match.\n");
2620 ok(!memcmp(&in_out, &test_mystruct7, sizeof(MYSTRUCT)), "Structs didn't match.\n");
2621
2622 memcpy(&in_ptr, &test_mystruct1, sizeof(MYSTRUCT));
2623 in_ptr_ptr = &in_ptr;
2624 hr = IWidget_mystruct_ptr_ptr(widget, &in_ptr_ptr);
2625 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2626
2627 /* Make sure that "thin" structs (<=8 bytes) are handled correctly in x86-64. */
2628
2629 hr = IWidget_thin_struct(widget, test_thin_struct);
2630 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2631
2632 /* Make sure we can handle an imported type. */
2633
2634 rect_out = test_rect2;
2635 rect_in_ptr = test_rect3;
2636 rect_in_out = test_rect4;
2637 hr = IWidget_rect(widget, test_rect1, &rect_out, &rect_in_ptr, &rect_in_out);
2638 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2639 ok(EqualRect(&rect_out, &test_rect5), "Rects didn't match.\n");
2640 ok(EqualRect(&rect_in_ptr, &test_rect3), "Rects didn't match.\n");
2641 ok(EqualRect(&rect_in_out, &test_rect7), "Rects didn't match.\n");
2642
2643 /* Test complex structs. */
2644 complex.c = 98;
2645 complex.i = 76543;
2646 i = 2;
2647 complex.pi = &i;
2648 i2 = 10;
2649 complex.ppi = &pi;
2650 complex.iface = create_disp_obj();
2651 sfd = create_disp_obj();
2652 complex.iface_ptr = &sfd;
2654 V_VT(&complex.var) = VT_I4;
2655 V_I4(&complex.var) = 123;
2656 memcpy(&complex.mystruct, &test_mystruct1, sizeof(MYSTRUCT));
2657 memcpy(complex.arr, test_array1, sizeof(array_t));
2658 complex.myint = 456;
2659 hr = IWidget_complex_struct(widget, complex);
2660 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2661}
2662
2663static void test_marshal_array(IWidget *widget, IDispatch *disp)
2664{
2665 VARIANT var_in[2], var_out[2], var_in_out[2];
2666 ISomethingFromDispatch *proxy_sfd;
2667 array_t in, out, in_out;
2668 MYSTRUCT struct_in[2];
2669 HRESULT hr;
2670 LONG l = 2;
2671
2672 memcpy(in, test_array1, sizeof(array_t));
2673 memcpy(out, test_array2, sizeof(array_t));
2674 memcpy(in_out, test_array3, sizeof(array_t));
2675 hr = IWidget_array(widget, in, out, in_out);
2676 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2677 ok(!memcmp(&in, &test_array1, sizeof(array_t)), "Arrays didn't match.\n");
2678 ok(!memcmp(&out, &test_array5, sizeof(array_t)), "Arrays didn't match.\n");
2679 ok(!memcmp(&in_out, &test_array6, sizeof(array_t)), "Arrays didn't match.\n");
2680
2681 V_VT(&var_in[0]) = VT_I4; V_I4(&var_in[0]) = 1;
2682 V_VT(&var_in[1]) = VT_BYREF|VT_I4; V_I4REF(&var_in[1]) = &l;
2683 V_VT(&var_out[0]) = VT_I4; V_I4(&var_out[0]) = 3;
2684 V_VT(&var_out[1]) = VT_I4; V_I4(&var_out[1]) = 4;
2685 V_VT(&var_in_out[0]) = VT_I4; V_I4(&var_in_out[0]) = 5;
2686 V_VT(&var_in_out[1]) = VT_BSTR; V_BSTR(&var_in_out[1]) = SysAllocString(test_bstr1);
2687 hr = IWidget_variant_array(widget, var_in, var_out, var_in_out);
2688 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2689 ok(V_VT(&var_in[0]) == VT_I4, "Got wrong type %u.\n", V_VT(&var_in[0]));
2690 ok(V_I4(&var_in[0]) == 1, "Got wrong value %ld.\n", V_I4(&var_in[0]));
2691 ok(V_VT(&var_in[1]) == (VT_BYREF|VT_I4), "Got wrong type %u.\n", V_VT(&var_in[1]));
2692 ok(V_I4REF(&var_in[1]) == &l, "Got wrong value %p.\n", V_I4REF(&var_in[1]));
2693 ok(l == 2, "Got wrong value %ld.\n", l);
2694 ok(V_VT(&var_out[0]) == VT_I1, "Got wrong type %u.\n", V_VT(&var_out[0]));
2695 ok(V_I1(&var_out[0]) == 9, "Got wrong value %u.\n", V_VT(&var_out[0]));
2696 ok(V_VT(&var_out[1]) == VT_BSTR, "Got wrong type %u.\n", V_VT(&var_out[1]));
2697 ok(!lstrcmpW(V_BSTR(&var_out[1]), test_bstr2), "Got wrong value %s.\n", wine_dbgstr_w(V_BSTR(&var_out[1])));
2698 ok(V_VT(&var_in_out[0]) == VT_I1, "Got wrong type %u.\n", V_VT(&var_in_out[0]));
2699 ok(V_I1(&var_in_out[0]) == 11, "Got wrong value %u.\n", V_VT(&var_in_out[0]));
2700 ok(V_VT(&var_in_out[1]) == VT_UNKNOWN, "Got wrong type %u.\n", V_VT(&var_in_out[1]));
2701 hr = IUnknown_QueryInterface(V_UNKNOWN(&var_in_out[1]), &IID_ISomethingFromDispatch, (void **)&proxy_sfd);
2702 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2703 hr = ISomethingFromDispatch_anotherfn(proxy_sfd);
2704 ok(hr == 0x01234567, "Got hr %#lx.\n", hr);
2705 ISomethingFromDispatch_Release(proxy_sfd);
2706 release_iface(V_UNKNOWN(&var_in_out[1]));
2707
2708 memcpy(&struct_in[0], &test_mystruct1, sizeof(MYSTRUCT));
2709 memcpy(&struct_in[1], &test_mystruct2, sizeof(MYSTRUCT));
2710 hr = IWidget_mystruct_array(widget, struct_in);
2711 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2712}
2713
2714static void test_marshal_coclass(IWidget *widget, IDispatch *disp)
2715{
2716 VARIANTARG arg[3];
2717 DISPPARAMS dispparams = {arg, NULL, ARRAY_SIZE(arg), 0};
2718 struct coclass_obj *class1, *class2, *class3;
2719 IUnknown *unk_in, *unk_out, *unk_in_out;
2720 ICoclass1 *in, *out, *in_out;
2721 Coclass1 class1_noptr;
2722 Coclass2 class2_noptr;
2723 Coclass3 class3_noptr;
2724 HRESULT hr;
2725
2726 class1 = create_coclass_obj();
2727 class2 = create_coclass_obj();
2728 class3 = create_coclass_obj();
2729
2730 hr = IWidget_Coclass(widget, (Coclass1 *)&class1->ICoclass1_iface,
2731 (Coclass2 *)&class2->ICoclass1_iface, (Coclass3 *)&class3->ICoclass1_iface);
2732 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2733
2734 hr = IWidget_Coclass(widget, (Coclass1 *)&class1->ICoclass2_iface,
2735 (Coclass2 *)&class2->ICoclass2_iface, (Coclass3 *)&class3->ICoclass2_iface);
2736 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2737
2741
2742 testmode = 0;
2743 class1 = create_coclass_obj();
2744 class2 = create_coclass_obj();
2745 class3 = create_coclass_obj();
2746 in = &class1->ICoclass1_iface;
2747 out = &class2->ICoclass1_iface;
2748 in_out = &class3->ICoclass1_iface;
2749 hr = IWidget_Coclass_ptr(widget, (Coclass1 **)&in, (Coclass1 **)&out, (Coclass1 **)&in_out);
2750 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2751 ok(in == &class1->ICoclass1_iface, "[in] parameter should not have changed.\n");
2752 ok(!out, "[out] parameter should have been cleared.\n");
2753 ok(in_out == &class3->ICoclass1_iface, "[in, out] parameter should not have changed.\n");
2757
2758 testmode = 1;
2759 class1 = create_coclass_obj();
2760 class3 = create_coclass_obj();
2761 in = &class1->ICoclass1_iface;
2762 in_out = &class3->ICoclass1_iface;
2763 ICoclass1_AddRef(in_out);
2764 hr = IWidget_Coclass_ptr(widget, (Coclass1 **)&in,
2765 (Coclass1 **)&out, (Coclass1 **)&in_out);
2766 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2767 hr = ICoclass1_test(out);
2768 ok(hr == 1, "Got hr %#lx.\n", hr);
2769 ok(in_out != &class3->ICoclass1_iface, "[in, out] parameter should have changed.\n");
2770 hr = ICoclass1_test(in_out);
2771 ok(hr == 1, "Got hr %#lx.\n", hr);
2773 release_iface(in_out);
2776
2777 testmode = 2;
2778 in = out = in_out = NULL;
2779 hr = IWidget_Coclass_ptr(widget, (Coclass1 **)&in,
2780 (Coclass1 **)&out, (Coclass1 **)&in_out);
2781 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2782 hr = ICoclass1_test(in_out);
2783 ok(hr == 1, "Got hr %#lx.\n", hr);
2784 release_iface(in_out);
2785
2786 testmode = 3;
2787 in = out = NULL;
2788 class3 = create_coclass_obj();
2789 in_out = &class3->ICoclass1_iface;
2790 hr = IWidget_Coclass_ptr(widget, (Coclass1 **)&in,
2791 (Coclass1 **)&out, (Coclass1 **)&in_out);
2792 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2793 ok(!in_out, "Got [in, out] %p.\n", in_out);
2794
2795 class1 = create_coclass_obj();
2796 class2 = create_coclass_obj();
2797 class3 = create_coclass_obj();
2798 class1_noptr.iface = &class1->ICoclass1_iface;
2799 class2_noptr.iface = &class2->ICoclass2_iface;
2800 class3_noptr.iface = &class3->ICoclass1_iface;
2801 hr = IWidget_Coclass_noptr(widget, class1_noptr, class2_noptr, class3_noptr);
2802 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2806
2807 /* Test with Invoke(). Note that since we pass VT_UNKNOWN, we don't get our
2808 * interface back, but rather an IUnknown. */
2809
2810 class1 = create_coclass_obj();
2811 class2 = create_coclass_obj();
2812 class3 = create_coclass_obj();
2813
2814 V_VT(&arg[2]) = VT_UNKNOWN; V_UNKNOWN(&arg[2]) = (IUnknown *)&class1->ICoclass1_iface;
2815 V_VT(&arg[1]) = VT_UNKNOWN; V_UNKNOWN(&arg[1]) = (IUnknown *)&class2->ICoclass1_iface;
2816 V_VT(&arg[0]) = VT_UNKNOWN; V_UNKNOWN(&arg[0]) = (IUnknown *)&class3->ICoclass1_iface;
2817 hr = IDispatch_Invoke(disp, DISPID_TM_COCLASS, &IID_NULL, LOCALE_NEUTRAL,
2818 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2819 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2820
2821 V_VT(&arg[2]) = VT_UNKNOWN; V_UNKNOWN(&arg[2]) = (IUnknown *)&class1->ICoclass2_iface;
2822 V_VT(&arg[1]) = VT_UNKNOWN; V_UNKNOWN(&arg[1]) = (IUnknown *)&class2->ICoclass2_iface;
2823 V_VT(&arg[0]) = VT_UNKNOWN; V_UNKNOWN(&arg[0]) = (IUnknown *)&class3->ICoclass2_iface;
2824 hr = IDispatch_Invoke(disp, DISPID_TM_COCLASS, &IID_NULL, LOCALE_NEUTRAL,
2825 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2826 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2827
2828 V_VT(&arg[2]) = VT_DISPATCH; V_DISPATCH(&arg[2]) = (IDispatch *)&class1->ICoclass1_iface;
2829 V_VT(&arg[1]) = VT_DISPATCH; V_DISPATCH(&arg[1]) = (IDispatch *)&class2->ICoclass1_iface;
2830 V_VT(&arg[0]) = VT_DISPATCH; V_DISPATCH(&arg[0]) = (IDispatch *)&class3->ICoclass1_iface;
2831 hr = IDispatch_Invoke(disp, DISPID_TM_COCLASS, &IID_NULL, LOCALE_NEUTRAL,
2832 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2833 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2834
2838
2839 testmode = 0;
2840 class1 = create_coclass_obj();
2841 class3 = create_coclass_obj();
2842 unk_in = (IUnknown *)&class1->ICoclass1_iface;
2843 unk_out = NULL;
2844 unk_in_out = (IUnknown *)&class3->ICoclass1_iface;
2847 V_VT(&arg[0]) = VT_UNKNOWN|VT_BYREF; V_UNKNOWNREF(&arg[0]) = &unk_in_out;
2848 hr = IDispatch_Invoke(disp, DISPID_TM_COCLASS_PTR, &IID_NULL, LOCALE_NEUTRAL,
2849 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2850 todo_wine
2851 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2852 ok(unk_in == (IUnknown *)&class1->ICoclass1_iface, "[in] parameter should not have changed.\n");
2853 ok(!unk_out, "[out] parameter should have been cleared.\n");
2854 ok(unk_in_out == (IUnknown *)&class3->ICoclass1_iface, "[in, out] parameter should not have changed.\n");
2857
2858 testmode = 1;
2859 class1 = create_coclass_obj();
2860 class3 = create_coclass_obj();
2861 unk_in = (IUnknown *)&class1->ICoclass1_iface;
2862 unk_out = NULL;
2863 unk_in_out = (IUnknown *)&class3->ICoclass1_iface;
2864 IUnknown_AddRef(unk_in_out);
2865 hr = IDispatch_Invoke(disp, DISPID_TM_COCLASS_PTR, &IID_NULL, LOCALE_NEUTRAL,
2866 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2867 todo_wine
2868 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2869
2870if (hr == S_OK) {
2871 hr = IUnknown_QueryInterface(unk_out, &IID_ICoclass1, (void **)&out);
2872 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2873 hr = ICoclass1_test(out);
2874 ok(hr == 1, "Got hr %#lx.\n", hr);
2875 ICoclass1_Release(out);
2876
2877 ok(unk_in_out != (IUnknown *)&class3->ICoclass1_iface, "[in, out] parameter should have changed.\n");
2878 hr = IUnknown_QueryInterface(unk_in_out, &IID_ICoclass1, (void **)&in_out);
2879 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2880 hr = ICoclass1_test(in_out);
2881 ok(hr == 1, "Got hr %#lx.\n", hr);
2882 ICoclass1_Release(in_out);
2883
2885 release_iface(unk_in_out);
2886}
2888 todo_wine
2890
2891 testmode = 2;
2892 unk_in = unk_out = unk_in_out = NULL;
2893 hr = IDispatch_Invoke(disp, DISPID_TM_COCLASS_PTR, &IID_NULL, LOCALE_NEUTRAL,
2894 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2895 todo_wine
2896 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2897
2898 ok(!unk_out, "[out] parameter should not have been set.\n");
2899if (hr == S_OK) {
2900 hr = IUnknown_QueryInterface(unk_in_out, &IID_ICoclass1, (void **)&in_out);
2901 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2902 hr = ICoclass1_test(in_out);
2903 ok(hr == 1, "Got hr %#lx.\n", hr);
2904 ICoclass1_Release(in_out);
2905
2906 release_iface(unk_in_out);
2907}
2908
2909 testmode = 3;
2910 unk_in = unk_out = NULL;
2911 class3 = create_coclass_obj();
2912 unk_in_out = (IUnknown *)&class3->ICoclass1_iface;
2913 IUnknown_AddRef(unk_in_out);
2914 hr = IDispatch_Invoke(disp, DISPID_TM_COCLASS_PTR, &IID_NULL, LOCALE_NEUTRAL,
2915 DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
2916 todo_wine
2917 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2918 todo_wine
2919 ok(!unk_in_out, "[in, out] parameter should have been cleared.\n");
2920
2921 todo_wine
2923}
2924
2925static void test_typelibmarshal(void)
2926{
2927 static const WCHAR szCat[] = { 'C','a','t',0 };
2928 static const WCHAR szTestTest[] = { 'T','e','s','t','T','e','s','t',0 };
2929 static const WCHAR szSuperman[] = { 'S','u','p','e','r','m','a','n',0 };
2930 HRESULT hr;
2931 IKindaEnumWidget *pKEW = KindaEnumWidget_Create();
2932 IWidget *pWidget;
2933 IStream *pStream;
2934 IDispatch *pDispatch;
2935 static const LARGE_INTEGER ullZero;
2936 EXCEPINFO excepinfo;
2937 VARIANT varresult;
2938 DISPID dispidNamed = DISPID_PROPERTYPUT;
2939 DISPPARAMS dispparams;
2940 VARIANTARG vararg[4];
2941 STATE the_state;
2942 HANDLE thread;
2943 DWORD tid;
2944 BSTR bstr;
2945 ITypeInfo *pTypeInfo;
2946 UINT uval;
2947
2948 ok(pKEW != NULL, "Widget creation failed\n");
2949
2950 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2952 tid = start_host_object(pStream, &IID_IKindaEnumWidget, (IUnknown *)pKEW, MSHLFLAGS_NORMAL, &thread);
2953 IKindaEnumWidget_Release(pKEW);
2954
2955 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2956 hr = CoUnmarshalInterface(pStream, &IID_IKindaEnumWidget, (void **)&pKEW);
2958 IStream_Release(pStream);
2959 if (FAILED(hr))
2960 {
2962 return;
2963 }
2964
2965 hr = IKindaEnumWidget_Next(pKEW, &pWidget);
2966 ok_ole_success(hr, IKindaEnumWidget_Next);
2967
2968 IKindaEnumWidget_Release(pKEW);
2969
2970 /* call GetTypeInfoCount (direct) */
2971 hr = IWidget_GetTypeInfoCount(pWidget, &uval);
2972 ok_ole_success(hr, IWidget_GetTypeInfoCount);
2973 hr = IWidget_GetTypeInfoCount(pWidget, &uval);
2974 ok_ole_success(hr, IWidget_GetTypeInfoCount);
2975
2976 hr = IWidget_QueryInterface(pWidget, &IID_IDispatch, (void **)&pDispatch);
2977 ok_ole_success(hr, IWidget_QueryInterface);
2978
2979 /* call put_Name */
2980 VariantInit(&vararg[0]);
2981 dispparams.cNamedArgs = 1;
2982 dispparams.rgdispidNamedArgs = &dispidNamed;
2983 dispparams.cArgs = 1;
2984 dispparams.rgvarg = vararg;
2985 VariantInit(&varresult);
2986 hr = IDispatch_Invoke(pDispatch, DISPID_TM_NAME, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL);
2987 ok_ole_success(hr, IDispatch_Invoke);
2988 ok(excepinfo.wCode == 0x0 && excepinfo.scode == S_OK,
2989 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08lx\n",
2990 excepinfo.wCode, excepinfo.scode);
2991 VariantClear(&varresult);
2992
2993 /* call put_Name (direct) */
2994 bstr = SysAllocString(szSuperman);
2995 hr = IWidget_put_Name(pWidget, bstr);
2996 ok_ole_success(hr, IWidget_put_Name);
2997 SysFreeString(bstr);
2998
2999 /* call get_Name */
3000 dispparams.cNamedArgs = 0;
3001 dispparams.rgdispidNamedArgs = NULL;
3002 dispparams.cArgs = 0;
3003 dispparams.rgvarg = NULL;
3004 VariantInit(&varresult);
3005 hr = IDispatch_Invoke(pDispatch, DISPID_TM_NAME, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL);
3006 ok_ole_success(hr, IDispatch_Invoke);
3007 ok(excepinfo.wCode == 0x0 && excepinfo.scode == S_OK,
3008 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08lx\n",
3009 excepinfo.wCode, excepinfo.scode);
3010 trace("Name = %s\n", wine_dbgstr_w(V_BSTR(&varresult)));
3011 VariantClear(&varresult);
3012
3013 /* call get_Name (direct) */
3014 bstr = (void *)0xdeadbeef;
3015 hr = IWidget_get_Name(pWidget, &bstr);
3016 ok_ole_success(hr, IWidget_get_Name);
3017 ok(!lstrcmpW(bstr, szCat), "IWidget_get_Name should have returned string \"Cat\" instead of %s\n", wine_dbgstr_w(bstr));
3018 SysFreeString(bstr);
3019
3020 /* call DoSomething without optional arguments */
3021 VariantInit(&vararg[0]);
3022 VariantInit(&vararg[1]);
3023 V_VT(&vararg[1]) = VT_R8;
3024 V_R8(&vararg[1]) = 3.141;
3025 dispparams.cNamedArgs = 0;
3026 dispparams.cArgs = 2;
3027 dispparams.rgdispidNamedArgs = NULL;
3028 dispparams.rgvarg = vararg;
3029 VariantInit(&varresult);
3030 hr = IDispatch_Invoke(pDispatch, DISPID_TM_DOSOMETHING, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
3031 ok_ole_success(hr, IDispatch_Invoke);
3032 ok(V_VT(&varresult) == VT_EMPTY, "varresult should be VT_EMPTY\n");
3033 VariantClear(&varresult);
3034
3035 /* call DoSomething with optional argument set to VT_EMPTY */
3036 VariantInit(&vararg[0]);
3037 VariantInit(&vararg[1]);
3038 VariantInit(&vararg[2]);
3039 V_VT(&vararg[2]) = VT_R8;
3040 V_R8(&vararg[2]) = 3.141;
3041 dispparams.cNamedArgs = 0;
3042 dispparams.cArgs = 3;
3043 dispparams.rgdispidNamedArgs = NULL;
3044 dispparams.rgvarg = vararg;
3045 VariantInit(&varresult);
3046 hr = IDispatch_Invoke(pDispatch, DISPID_TM_DOSOMETHING, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
3047 ok_ole_success(hr, IDispatch_Invoke);
3048 ok(V_VT(&varresult) == VT_EMPTY, "varresult should be VT_EMPTY\n");
3049 VariantClear(&varresult);
3050
3051 /* call DoSomething with optional arguments set to VT_ERROR/DISP_E_PARAMNOTFOUND */
3052 VariantInit(&vararg[0]);
3053 VariantInit(&vararg[1]);
3054 VariantInit(&vararg[2]);
3055 VariantInit(&vararg[3]);
3056 V_VT(&vararg[3]) = VT_R8;
3057 V_R8(&vararg[3]) = 3.141;
3058 V_VT(&vararg[1]) = VT_ERROR;
3059 V_ERROR(&vararg[1]) = DISP_E_PARAMNOTFOUND;
3060 V_VT(&vararg[0]) = VT_ERROR;
3061 V_ERROR(&vararg[0]) = DISP_E_PARAMNOTFOUND;
3062 dispparams.cNamedArgs = 0;
3063 dispparams.cArgs = 4;
3064 dispparams.rgdispidNamedArgs = NULL;
3065 dispparams.rgvarg = vararg;
3066 VariantInit(&varresult);
3067 hr = IDispatch_Invoke(pDispatch, DISPID_TM_DOSOMETHING, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
3068 ok_ole_success(hr, IDispatch_Invoke);
3069 ok(V_VT(&varresult) == VT_EMPTY, "varresult should be VT_EMPTY\n");
3070 VariantClear(&varresult);
3071
3072 /* call get_State */
3073 dispparams.cNamedArgs = 0;
3074 dispparams.cArgs = 0;
3075 dispparams.rgdispidNamedArgs = NULL;
3076 dispparams.rgvarg = NULL;
3077 hr = IDispatch_Invoke(pDispatch, DISPID_TM_STATE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL);
3078 ok_ole_success(hr, IDispatch_Invoke);
3079 ok((V_VT(&varresult) == VT_I4) && (V_I4(&varresult) == STATE_WIDGETIFIED), "Return val mismatch\n");
3080
3081 /* call get_State (direct) */
3082 hr = IWidget_get_State(pWidget, &the_state);
3083 ok_ole_success(hr, IWidget_get_state);
3084 ok(the_state == STATE_WIDGETIFIED, "should have returned WIDGET_WIDGETIFIED instead of %d\n", the_state);
3085
3086 /* call put_State */
3087 the_state = STATE_WIDGETIFIED;
3088 VariantInit(&vararg[0]);
3089 V_VT(&vararg[0]) = VT_BYREF|VT_I4;
3090 V_I4REF(&vararg[0]) = (LONG *)&the_state;
3091 dispparams.cNamedArgs = 1;
3092 dispparams.cArgs = 1;
3093 dispparams.rgdispidNamedArgs = &dispidNamed;
3094 dispparams.rgvarg = vararg;
3095 hr = IDispatch_Invoke(pDispatch, DISPID_TM_STATE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL);
3096 ok_ole_success(hr, IDispatch_Invoke);
3097
3098 /* call Map */
3099 bstr = SysAllocString(szTestTest);
3100 VariantInit(&vararg[0]);
3101 V_VT(&vararg[0]) = VT_BYREF|VT_BSTR;
3102 V_BSTRREF(&vararg[0]) = &bstr;
3103 dispparams.cNamedArgs = 0;
3104 dispparams.cArgs = 1;
3105 dispparams.rgdispidNamedArgs = NULL;
3106 dispparams.rgvarg = vararg;
3107 VariantInit(&varresult);
3108 hr = IDispatch_Invoke(pDispatch, DISPID_TM_MAP, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
3109 ok_ole_success(hr, IDispatch_Invoke);
3110 ok(V_VT(&varresult) == VT_BSTR, "Return value should be of type BSTR instead of %d\n", V_VT(&varresult));
3111 ok(!lstrcmpW(V_BSTR(&varresult), szTestTest), "Return value should have been \"TestTest\" instead of %s\n", wine_dbgstr_w(V_BSTR(&varresult)));
3112 VariantClear(&varresult);
3113 SysFreeString(bstr);
3114
3115 /* call SetOleColor with large negative VT_I4 param */
3116 VariantInit(&vararg[0]);
3117 V_VT(&vararg[0]) = VT_I4;
3118 V_I4(&vararg[0]) = 0x80000005;
3119 dispparams.cNamedArgs = 0;
3120 dispparams.cArgs = 1;
3121 dispparams.rgdispidNamedArgs = NULL;
3122 dispparams.rgvarg = vararg;
3123 hr = IDispatch_Invoke(pDispatch, DISPID_TM_SETOLECOLOR, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, &excepinfo, NULL);
3124 ok_ole_success(hr, IDispatch_Invoke);
3125
3126 /* call GetOleColor */
3127 dispparams.cNamedArgs = 0;
3128 dispparams.cArgs = 0;
3129 dispparams.rgdispidNamedArgs = NULL;
3130 dispparams.rgvarg = NULL;
3131 VariantInit(&varresult);
3132 hr = IDispatch_Invoke(pDispatch, DISPID_TM_GETOLECOLOR, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
3133 ok_ole_success(hr, IDispatch_Invoke);
3134 VariantClear(&varresult);
3135
3136 /* call Clone */
3137 dispparams.cNamedArgs = 0;
3138 dispparams.cArgs = 0;
3139 dispparams.rgdispidNamedArgs = NULL;
3140 dispparams.rgvarg = NULL;
3141 VariantInit(&varresult);
3142 hr = IDispatch_Invoke(pDispatch, DISPID_TM_CLONE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL);
3143 ok_ole_success(hr, IDispatch_Invoke);
3144 ok(V_VT(&varresult) == VT_DISPATCH, "vt %x\n", V_VT(&varresult));
3145 VariantClear(&varresult);
3146
3147 /* call CloneInterface */
3148 dispparams.cNamedArgs = 0;
3149 dispparams.cArgs = 0;
3150 dispparams.rgdispidNamedArgs = NULL;
3151 dispparams.rgvarg = NULL;
3152 VariantInit(&varresult);
3153 hr = IDispatch_Invoke(pDispatch, DISPID_TM_CLONEINTERFACE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL);
3154 ok_ole_success(hr, IDispatch_Invoke);
3155 ok(V_VT(&varresult) == VT_DISPATCH, "vt %x\n", V_VT(&varresult));
3156 VariantClear(&varresult);
3157
3158 /* call CloneDispatch with automatic value getting */
3159 V_VT(&vararg[0]) = VT_I2;
3160 V_I2(&vararg[0]) = 1;
3161 dispparams.cNamedArgs = 0;
3162 dispparams.rgdispidNamedArgs = NULL;
3163 dispparams.cArgs = 1;
3164 dispparams.rgvarg = vararg;
3165 VariantInit(&varresult);
3166 hr = IDispatch_Invoke(pDispatch, DISPID_TM_CLONEDISPATCH, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL);
3167 ok_ole_success(hr, IDispatch_Invoke);
3168
3169 ok(excepinfo.wCode == 0x0 && excepinfo.scode == S_OK,
3170 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08lx\n",
3171 excepinfo.wCode, excepinfo.scode);
3172
3173 ok(V_VT(&varresult) == VT_I2, "V_VT(&varresult) was %d instead of VT_I2\n", V_VT(&varresult));
3174 ok(V_I2(&varresult) == 1234, "V_I2(&varresult) was %d instead of 1234\n", V_I2(&varresult));
3175 VariantClear(&varresult);
3176
3177 /* call CloneCoclass */
3178 dispparams.cNamedArgs = 0;
3179 dispparams.cArgs = 0;
3180 dispparams.rgdispidNamedArgs = NULL;
3181 dispparams.rgvarg = NULL;
3182 VariantInit(&varresult);
3183 hr = IDispatch_Invoke(pDispatch, DISPID_TM_CLONECOCLASS, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL);
3184 ok_ole_success(hr, IDispatch_Invoke);
3185
3186 ok(excepinfo.wCode == 0x0 && excepinfo.scode == S_OK,
3187 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08lx\n",
3188 excepinfo.wCode, excepinfo.scode);
3189
3190 ok(V_VT(&varresult) == VT_DISPATCH, "V_VT(&varresult) was %d instead of VT_DISPATCH\n", V_VT(&varresult));
3191 ok(V_DISPATCH(&varresult) != NULL, "expected V_DISPATCH(&varresult) != NULL\n");
3192
3193 /* call Value with a VT_VARIANT|VT_BYREF type */
3194 V_VT(&vararg[0]) = VT_VARIANT|VT_BYREF;
3195 V_VARIANTREF(&vararg[0]) = &vararg[1];
3196 V_VT(&vararg[1]) = VT_I2;
3197 V_I2(&vararg[1]) = 1;
3198 dispparams.cNamedArgs = 0;
3199 dispparams.rgdispidNamedArgs = NULL;
3200 dispparams.cArgs = 1;
3201 dispparams.rgvarg = vararg;
3202 VariantInit(&varresult);
3203 hr = IDispatch_Invoke(pDispatch, DISPID_VALUE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL);
3204 ok_ole_success(hr, IDispatch_Invoke);
3205
3206 ok(excepinfo.wCode == 0x0 && excepinfo.scode == S_OK,
3207 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08lx\n",
3208 excepinfo.wCode, excepinfo.scode);
3209
3210 ok(V_VT(&varresult) == VT_I2, "V_VT(&varresult) was %d instead of VT_I2\n", V_VT(&varresult));
3211 ok(V_I2(&varresult) == 1234, "V_I2(&varresult) was %d instead of 1234\n", V_I2(&varresult));
3212 VariantClear(&varresult);
3213
3214 /* call Array with BSTR argument - type mismatch */
3215 VariantInit(&vararg[0]);
3216 V_VT(&vararg[0]) = VT_BSTR;
3217 V_BSTR(&vararg[0]) = SysAllocString(szSuperman);
3218 dispparams.cNamedArgs = 0;
3219 dispparams.cArgs = 1;
3220 dispparams.rgdispidNamedArgs = NULL;
3221 dispparams.rgvarg = vararg;
3222 hr = IDispatch_Invoke(pDispatch, DISPID_TM_ARRAY, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
3223 ok(hr == DISP_E_TYPEMISMATCH || hr == DISP_E_BADVARTYPE, "expected DISP_E_TYPEMISMATCH, got %#lx\n", hr);
3224 SysFreeString(V_BSTR(&vararg[0]));
3225
3226 /* call ArrayPtr with BSTR argument - type mismatch */
3227 VariantInit(&vararg[0]);
3228 V_VT(&vararg[0]) = VT_BSTR;
3229 V_BSTR(&vararg[0]) = SysAllocString(szSuperman);
3230 dispparams.cNamedArgs = 0;
3231 dispparams.cArgs = 1;
3232 dispparams.rgdispidNamedArgs = NULL;
3233 dispparams.rgvarg = vararg;
3234 hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARRAYPTR, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
3235 ok(hr == DISP_E_TYPEMISMATCH || hr == DISP_E_BADVARTYPE, "expected DISP_E_TYPEMISMATCH, got %#lx\n", hr);
3236 SysFreeString(V_BSTR(&vararg[0]));
3237
3238 /* call VarArg */
3239 VariantInit(&vararg[3]);
3240 V_VT(&vararg[3]) = VT_I4;
3241 V_I4(&vararg[3]) = 3;
3242 VariantInit(&vararg[2]);
3243 V_VT(&vararg[2]) = VT_I4;
3244 V_I4(&vararg[2]) = 0;
3245 VariantInit(&vararg[1]);
3246 V_VT(&vararg[1]) = VT_I4;
3247 V_I4(&vararg[1]) = 1;
3248 VariantInit(&vararg[0]);
3249 V_VT(&vararg[0]) = VT_I4;
3250 V_I4(&vararg[0]) = 2;
3251 dispparams.cNamedArgs = 0;
3252 dispparams.cArgs = 4;
3253 dispparams.rgdispidNamedArgs = NULL;
3254 dispparams.rgvarg = vararg;
3255 hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
3256 ok_ole_success(hr, IDispatch_Invoke);
3257
3258 /* without any varargs */
3259 dispparams.cArgs = 1;
3260 V_I4(&vararg[0]) = 0;
3261 hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
3262 ok_ole_success(hr, IDispatch_Invoke);
3263
3264 /* call VarArg, even one (non-optional, non-safearray) named argument is not allowed */
3265 dispidNamed = 0;
3266 dispparams.cNamedArgs = 1;
3267 dispparams.rgdispidNamedArgs = &dispidNamed;
3268 hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
3269 ok(hr == DISP_E_NONAMEDARGS, "IDispatch_Invoke should have returned DISP_E_NONAMEDARGS instead of 0x%08lx\n", hr);
3270 dispidNamed = DISPID_PROPERTYPUT;
3271
3272 /* call VarArg_Run */
3273 VariantInit(&vararg[1]);
3274 V_VT(&vararg[1]) = VT_BSTR;
3275 V_BSTR(&vararg[1]) = SysAllocString(szCat);
3276 VariantInit(&vararg[0]);
3277 V_VT(&vararg[0]) = VT_BSTR;
3278 V_BSTR(&vararg[0]) = SysAllocString(szSuperman);
3279 dispparams.cNamedArgs = 0;
3280 dispparams.cArgs = 2;
3281 dispparams.rgdispidNamedArgs = NULL;
3282 dispparams.rgvarg = vararg;
3283 hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG_RUN, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
3284 ok_ole_success(hr, IDispatch_Invoke);
3285 /* without any varargs */
3286 dispparams.cArgs = 1;
3287 dispparams.rgvarg = vararg + 1;
3288 hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG_RUN, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
3289 ok_ole_success(hr, IDispatch_Invoke);
3290 SysFreeString(V_BSTR(&vararg[1]));
3291 SysFreeString(V_BSTR(&vararg[0]));
3292
3293 /* call VarArg_Ref_Run */
3294 VariantInit(&vararg[1]);
3295 V_VT(&vararg[1]) = VT_BSTR;
3296 V_BSTR(&vararg[1]) = SysAllocString(szCat);
3297 VariantInit(&vararg[0]);
3298 V_VT(&vararg[0]) = VT_BSTR;
3299 V_BSTR(&vararg[0]) = SysAllocString(szSuperman);
3300 dispparams.cNamedArgs = 0;
3301 dispparams.cArgs = 2;
3302 dispparams.rgdispidNamedArgs = NULL;
3303 dispparams.rgvarg = vararg;
3304 hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG_REF_RUN, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
3305 ok_ole_success(hr, IDispatch_Invoke);
3306 /* without any varargs */
3307 dispparams.cArgs = 1;
3308 dispparams.rgvarg = vararg + 1;
3309 hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG_REF_RUN, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
3310 ok_ole_success(hr, IDispatch_Invoke);
3311 SysFreeString(V_BSTR(&vararg[1]));
3312 SysFreeString(V_BSTR(&vararg[0]));
3313
3314 /* call Error */
3315 dispparams.cNamedArgs = 0;
3316 dispparams.cArgs = 0;
3317 dispparams.rgdispidNamedArgs = NULL;
3318 dispparams.rgvarg = NULL;
3319 VariantInit(&varresult);
3320 hr = IDispatch_Invoke(pDispatch, DISPID_TM_ERROR, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, &excepinfo, NULL);
3321 ok(hr == DISP_E_EXCEPTION, "IDispatch_Invoke should have returned DISP_E_EXCEPTION instead of 0x%08lx\n", hr);
3322 ok(excepinfo.wCode == 0x0 && excepinfo.scode == E_NOTIMPL,
3323 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08lx\n",
3324 excepinfo.wCode, excepinfo.scode);
3325 VariantClear(&varresult);
3326
3327 /* call BstrRet */
3328 pTypeInfo = NonOleAutomation_GetTypeInfo();
3329 dispparams.cNamedArgs = 0;
3330 dispparams.cArgs = 0;
3331 dispparams.rgdispidNamedArgs = NULL;
3332 dispparams.rgvarg = NULL;
3333 VariantInit(&varresult);
3334 hr = ITypeInfo_Invoke(pTypeInfo, &NonOleAutomation, DISPID_NOA_BSTRRET, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
3335 ok_ole_success(hr, ITypeInfo_Invoke);
3336 ok(V_VT(&varresult) == VT_BSTR, "V_VT(&varresult) should be VT_BSTR instead of %d\n", V_VT(&varresult));
3337 ok(V_BSTR(&varresult) != NULL, "V_BSTR(&varresult) should not be NULL\n");
3338
3339 VariantClear(&varresult);
3340
3341 dispparams.cNamedArgs = 0;
3342 dispparams.cArgs = 0;
3343 dispparams.rgdispidNamedArgs = NULL;
3344 dispparams.rgvarg = NULL;
3345 hr = ITypeInfo_Invoke(pTypeInfo, &NonOleAutomation, DISPID_NOA_ERROR, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
3346 ok(hr == DISP_E_EXCEPTION, "ITypeInfo_Invoke should have returned DISP_E_EXCEPTION instead of 0x%08lx\n", hr);
3347 ok(V_VT(&varresult) == VT_EMPTY, "V_VT(&varresult) should be VT_EMPTY instead of %d\n", V_VT(&varresult));
3348 ok(excepinfo.wCode == 0x0 && excepinfo.scode == E_NOTIMPL,
3349 "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08lx\n",
3350 excepinfo.wCode, excepinfo.scode);
3351 VariantClear(&varresult);
3352
3353 ITypeInfo_Release(pTypeInfo);
3354
3355 /* tests call put_Name without named arg */
3356 VariantInit(&vararg[0]);
3357 dispparams.cNamedArgs = 0;
3358 dispparams.rgdispidNamedArgs = NULL;
3359 dispparams.cArgs = 1;
3360 dispparams.rgvarg = vararg;
3361 VariantInit(&varresult);
3362 hr = IDispatch_Invoke(pDispatch, DISPID_TM_NAME, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL);
3363 ok(hr == DISP_E_PARAMNOTFOUND, "IDispatch_Invoke should have returned DISP_E_PARAMNOTFOUND instead of 0x%08lx\n", hr);
3364 VariantClear(&varresult);
3365
3366 /* tests param type that cannot be coerced */
3367 VariantInit(&vararg[0]);
3368 V_VT(&vararg[0]) = VT_UNKNOWN;
3369 V_UNKNOWN(&vararg[0]) = NULL;
3370 dispparams.cNamedArgs = 1;
3371 dispparams.rgdispidNamedArgs = &dispidNamed;
3372 dispparams.cArgs = 1;
3373 dispparams.rgvarg = vararg;
3374 VariantInit(&varresult);
3375 hr = IDispatch_Invoke(pDispatch, DISPID_TM_NAME, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL);
3376 ok(hr == DISP_E_TYPEMISMATCH, "IDispatch_Invoke should have returned DISP_E_TYPEMISMATCH instead of 0x%08lx\n", hr);
3377 VariantClear(&varresult);
3378
3379 /* tests bad param type */
3380 VariantInit(&vararg[0]);
3381 V_VT(&vararg[0]) = VT_CLSID;
3382 V_BYREF(&vararg[0]) = NULL;
3383 dispparams.cNamedArgs = 1;
3384 dispparams.rgdispidNamedArgs = &dispidNamed;
3385 dispparams.cArgs = 1;
3386 dispparams.rgvarg = vararg;
3387 VariantInit(&varresult);
3388 hr = IDispatch_Invoke(pDispatch, DISPID_TM_NAME, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL);
3389 ok(hr == DISP_E_BADVARTYPE, "IDispatch_Invoke should have returned DISP_E_BADVARTYPE instead of 0x%08lx\n", hr);
3390 VariantClear(&varresult);
3391
3392 /* tests too small param count */
3393 dispparams.cNamedArgs = 0;
3394 dispparams.rgdispidNamedArgs = NULL;
3395 dispparams.cArgs = 0;
3396 dispparams.rgvarg = NULL;
3397 VariantInit(&varresult);
3398 hr = IDispatch_Invoke(pDispatch, DISPID_TM_DOSOMETHING, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
3399 ok(hr == DISP_E_BADPARAMCOUNT, "IDispatch_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08lx\n", hr);
3400 VariantClear(&varresult);
3401
3402 /* tests propget function with large param count */
3403 VariantInit(&vararg[0]);
3404 V_VT(&vararg[0]) = VT_BSTR;
3405 V_BSTR(&vararg[0]) = NULL;
3406 V_VT(&vararg[1]) = VT_I4;
3407 V_I4(&vararg[1]) = 1;
3408 dispparams.cNamedArgs = 0;
3409 dispparams.cArgs = 2;
3410 dispparams.rgdispidNamedArgs = NULL;
3411 dispparams.rgvarg = vararg;
3412 hr = IDispatch_Invoke(pDispatch, DISPID_TM_STATE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL);
3413 ok(hr == DISP_E_NOTACOLLECTION, "IDispatch_Invoke should have returned DISP_E_NOTACOLLECTION instead of 0x%08lx\n", hr);
3414
3415 /* test propput with lcid */
3416
3417 /* the lcid passed to the function is the first lcid in the typelib header.
3418 Since we don't explicitly set an lcid in the idl, it'll default to US English. */
3419 VariantInit(&vararg[0]);
3420 V_VT(&vararg[0]) = VT_I4;
3421 V_I4(&vararg[0]) = 0xcafe;
3422 dispparams.cNamedArgs = 1;
3423 dispparams.rgdispidNamedArgs = &dispidNamed;
3424 dispparams.cArgs = 1;
3425 dispparams.rgvarg = vararg;
3426 VariantInit(&varresult);
3427 hr = IDispatch_Invoke(pDispatch, DISPID_TM_PROP_WITH_LCID, &IID_NULL, 0x40c, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL);
3428 ok_ole_success(hr, ITypeInfo_Invoke);
3429 VariantClear(&varresult);
3430
3431 /* test propget with lcid */
3432 dispparams.cNamedArgs = 0;
3433 dispparams.cArgs = 0;
3434 dispparams.rgvarg = NULL;
3435 dispparams.rgdispidNamedArgs = NULL;
3436 hr = IDispatch_Invoke(pDispatch, DISPID_TM_PROP_WITH_LCID, &IID_NULL, 0x40c, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL);
3437 ok_ole_success(hr, ITypeInfo_Invoke);
3438 ok(V_VT(&varresult) == VT_I4, "got %x\n", V_VT(&varresult));
3439 ok(V_I4(&varresult) == 0x409, "got %lx\n", V_I4(&varresult));
3440 VariantClear(&varresult);
3441
3442 /* test propget of INT value */
3443 dispparams.cNamedArgs = 0;
3444 dispparams.cArgs = 0;
3445 dispparams.rgvarg = NULL;
3446 dispparams.rgdispidNamedArgs = NULL;
3447 hr = IDispatch_Invoke(pDispatch, DISPID_TM_PROP_INT, &IID_NULL, 0x40c, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL);
3448 ok_ole_success(hr, ITypeInfo_Invoke);
3449 ok(V_VT(&varresult) == VT_I4, "got %x\n", V_VT(&varresult));
3450 ok(V_I4(&varresult) == -13, "got %lx\n", V_I4(&varresult));
3451 VariantClear(&varresult);
3452
3453 /* test propget of INT value */
3454 dispparams.cNamedArgs = 0;
3455 dispparams.cArgs = 0;
3456 dispparams.rgvarg = NULL;
3457 dispparams.rgdispidNamedArgs = NULL;
3458 hr = IDispatch_Invoke(pDispatch, DISPID_TM_PROP_UINT, &IID_NULL, 0x40c, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL);
3459 ok_ole_success(hr, ITypeInfo_Invoke);
3460 ok(V_VT(&varresult) == VT_UI4, "got %x\n", V_VT(&varresult));
3461 ok(V_UI4(&varresult) == 42, "got %lx\n", V_UI4(&varresult));
3462 VariantClear(&varresult);
3463
3464 /* test byref marshalling */
3465 uval = 666;
3466 VariantInit(&vararg[0]);
3467 V_VT(&vararg[0]) = VT_UI4|VT_BYREF;
3468 V_UI4REF(&vararg[0]) = (ULONG *)&uval;
3469 dispparams.cNamedArgs = 0;
3470 dispparams.cArgs = 1;
3471 dispparams.rgvarg = vararg;
3472 dispparams.rgdispidNamedArgs = NULL;
3473 hr = IDispatch_Invoke(pDispatch, DISPID_TM_BYREF_UINT, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
3474 ok_ole_success(hr, ITypeInfo_Invoke);
3475 ok(V_VT(&varresult) == VT_EMPTY, "varresult should be VT_EMPTY\n");
3476 ok(V_VT(&vararg[0]) == (VT_UI4|VT_BYREF), "arg VT not unmarshalled correctly: %x\n", V_VT(&vararg[0]));
3477 ok(V_UI4REF(&vararg[0]) == (ULONG *)&uval, "Byref pointer not preserved: %p/%p\n", &uval, V_UI4REF(&vararg[0]));
3478 ok(*V_UI4REF(&vararg[0]) == 42, "Expected 42 to be returned instead of %lu\n", *V_UI4REF(&vararg[0]));
3479 VariantClear(&varresult);
3480 VariantClear(&vararg[0]);
3481
3482 /* test propput with optional argument. */
3483 VariantInit(&vararg[0]);
3484 V_VT(&vararg[0]) = VT_I4;
3485 V_I4(&vararg[0]) = 0xcafe;
3486 dispparams.cNamedArgs = 1;
3487 dispparams.rgdispidNamedArgs = &dispidNamed;
3488 dispparams.cArgs = 1;
3489 dispparams.rgvarg = vararg;
3490 VariantInit(&varresult);
3491 hr = IDispatch_Invoke(pDispatch, DISPID_TM_PROP_OPT_ARG, &IID_NULL, 0x40c, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL);
3492 ok_ole_success(hr, ITypeInfo_Invoke);
3493 VariantClear(&varresult);
3494
3495 /* test propput with required argument. */
3496 VariantInit(&vararg[0]);
3497 VariantInit(&vararg[1]);
3498 V_VT(&vararg[0]) = VT_I4;
3499 V_I4(&vararg[0]) = 0x1234;
3500 V_VT(&vararg[1]) = VT_I4;
3501 V_I4(&vararg[1]) = 0x5678;
3502 dispparams.cNamedArgs = 1;
3503 dispparams.rgdispidNamedArgs = &dispidNamed;
3504 dispparams.cArgs = 2;
3505 dispparams.rgvarg = vararg;
3506 VariantInit(&varresult);
3507 hr = IDispatch_Invoke(pDispatch, DISPID_TM_PROP_REQ_ARG, &IID_NULL, 0x40c, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL);
3508 ok_ole_success(hr, ITypeInfo_Invoke);
3509 VariantClear(&varresult);
3510
3511 /* restricted member */
3512 dispparams.cNamedArgs = 0;
3513 dispparams.rgdispidNamedArgs = NULL;
3514 dispparams.cArgs = 0;
3515 dispparams.rgvarg = NULL;
3516 VariantInit(&varresult);
3517 hr = IDispatch_Invoke(pDispatch, DISPID_TM_RESTRICTED, &IID_NULL, 0x40c, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
3518 ok( hr == DISP_E_MEMBERNOTFOUND, "got %08lx\n", hr );
3519 VariantClear(&varresult);
3520
3521 /* restricted member with -ve memid (not restricted) */
3522 dispparams.cNamedArgs = 0;
3523 dispparams.rgdispidNamedArgs = NULL;
3524 dispparams.cArgs = 0;
3525 dispparams.rgvarg = NULL;
3526 VariantInit(&varresult);
3527 hr = IDispatch_Invoke(pDispatch, DISPID_TM_NEG_RESTRICTED, &IID_NULL, 0x40c, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
3528 ok( hr == S_OK, "got %08lx\n", hr );
3529 ok(V_VT(&varresult) == VT_I4, "got %x\n", V_VT(&varresult));
3530 ok(V_I4(&varresult) == DISPID_TM_NEG_RESTRICTED, "got %lx\n", V_I4(&varresult));
3531 VariantClear(&varresult);
3532
3533 test_marshal_basetypes(pWidget, pDispatch);
3534 test_marshal_pointer(pWidget, pDispatch);
3535 test_marshal_iface(pWidget, pDispatch);
3536 test_marshal_bstr(pWidget, pDispatch);
3537 test_marshal_variant(pWidget, pDispatch);
3538 test_marshal_safearray(pWidget, pDispatch);
3539 test_marshal_struct(pWidget, pDispatch);
3540 test_marshal_array(pWidget, pDispatch);
3541 test_marshal_coclass(pWidget, pDispatch);
3542
3543 IDispatch_Release(pDispatch);
3544 IWidget_Release(pWidget);
3545
3546 trace("calling end_host_object\n");
3548}
3549
3550static void test_DispCallFunc(void)
3551{
3552 static const WCHAR szEmpty[] = { 0 };
3554 VARIANTARG vararg[4];
3555 VARIANTARG varref;
3556 VARIANTARG *rgpvarg[4] = { &vararg[0], &vararg[1], &vararg[2], &vararg[3] };
3557 VARIANTARG varresult;
3558 HRESULT hr;
3559 IWidget *pWidget = Widget_Create();
3560 V_VT(&vararg[0]) = VT_R8;
3561 V_R8(&vararg[0]) = 3.141;
3562 V_VT(&vararg[1]) = VT_BSTR;
3563 V_BSTRREF(&vararg[1]) = CoTaskMemAlloc(sizeof(BSTR));
3564 V_VT(&vararg[2]) = VT_BSTR;
3565 V_BSTR(&vararg[2]) = SysAllocString(szEmpty);
3566 V_VT(&vararg[3]) = VT_VARIANT|VT_BYREF;
3567 V_VARIANTREF(&vararg[3]) = &varref;
3568 V_VT(&varref) = VT_ERROR;
3569 V_ERROR(&varref) = DISP_E_PARAMNOTFOUND;
3570 VariantInit(&varresult);
3571 hr = DispCallFunc(pWidget, 9*sizeof(void*), CC_STDCALL, VT_UI4, 4, rgvt, rgpvarg, &varresult);
3573 VariantClear(&varresult);
3574 SysFreeString(*V_BSTRREF(&vararg[1]));
3575 CoTaskMemFree(V_BSTRREF(&vararg[1]));
3576 VariantClear(&vararg[2]);
3577 IWidget_Release(pWidget);
3578}
3579
3580static void test_StaticWidget(void)
3581{
3583 DISPPARAMS dispparams;
3584 VARIANTARG vararg[4];
3585 EXCEPINFO excepinfo;
3586 VARIANT varresult;
3587 HRESULT hr;
3588
3589 type_info = get_type_info(&IID_IStaticWidget);
3590
3591 /* call TestDual */
3592 dispparams.cNamedArgs = 0;
3593 dispparams.cArgs = 1;
3594 dispparams.rgdispidNamedArgs = NULL;
3595 dispparams.rgvarg = vararg;
3596 V_VT(vararg) = VT_DISPATCH;
3597 V_DISPATCH(vararg) = (IDispatch*)&TestDualDisp;
3598 VariantInit(&varresult);
3600 &dispparams, &varresult, &excepinfo, NULL);
3601 ok_ole_success(hr, IDispatch_Invoke);
3602 ok(V_VT(&varresult) == VT_EMPTY, "vt %x\n", V_VT(&varresult));
3603 VariantClear(&varresult);
3604
3605 /* call TestSecondIface */
3606 dispparams.cNamedArgs = 0;
3607 dispparams.cArgs = 1;
3608 dispparams.rgdispidNamedArgs = NULL;
3609 dispparams.rgvarg = vararg;
3610 V_VT(vararg) = VT_DISPATCH;
3611 V_DISPATCH(vararg) = (IDispatch*)&TestDualDisp;
3612 VariantInit(&varresult);
3614 &dispparams, &varresult, &excepinfo, NULL);
3615 ok_ole_success(hr, IDispatch_Invoke);
3616 ok(V_VT(&varresult) == VT_EMPTY, "vt %x\n", V_VT(&varresult));
3617 VariantClear(&varresult);
3618
3619 ITypeInfo_Release(type_info);
3620}
3621
3622static void test_libattr(void)
3623{
3624 ITypeLib *pTypeLib;
3625 HRESULT hr;
3626 TLIBATTR *pattr;
3627
3628 hr = LoadRegTypeLib(&LIBID_TestTypelib, 2, 5, LOCALE_NEUTRAL, &pTypeLib);
3630 if (FAILED(hr))
3631 return;
3632
3633 hr = ITypeLib_GetLibAttr(pTypeLib, &pattr);
3634 ok_ole_success(hr, GetLibAttr);
3635 if (SUCCEEDED(hr))
3636 {
3637 ok(pattr->lcid == MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), "lcid %lx\n", pattr->lcid);
3638
3639 ITypeLib_ReleaseTLibAttr(pTypeLib, pattr);
3640 }
3641
3642 ITypeLib_Release(pTypeLib);
3643}
3644
3646{
3647 IStream *stream, *stream2;
3648 ITestSecondDisp *second;
3649 ItestDual *iface;
3650 HANDLE thread;
3651 DWORD tid;
3652 HRESULT hres;
3653
3654 static const LARGE_INTEGER zero;
3655
3656 trace("Testing IExternalConnection...\n");
3657
3659
3660 /* Marshaling an interface increases external connection count. */
3663 ok(hres == S_OK, "CreateStreamOnHGlobal failed: %08lx\n", hres);
3664 tid = start_host_object(stream, &IID_ItestDual, (IUnknown*)&TestDual, MSHLFLAGS_NORMAL, &thread);
3665 ok(external_connections == 1, "external_connections = %d\n", external_connections);
3666
3667 IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
3668 hres = CoUnmarshalInterface(stream, &IID_ItestDual, (void**)&iface);
3669 ok(hres == S_OK, "CoUnmarshalInterface failed: %08lx\n", hres);
3670 if (FAILED(hres))
3671 {
3673 IStream_Release(stream);
3674 return;
3675 }
3676 ok(external_connections == 1, "external_connections = %d\n", external_connections);
3677
3678 IStream_Release(stream);
3679 ok(external_connections == 1, "external_connections = %d\n", external_connections);
3680
3681 /* Creating a stub for new iface causes new external connection. */
3682 hres = ItestDual_QueryInterface(iface, &IID_ITestSecondDisp, (void**)&second);
3683 ok(hres == S_OK, "Could not get ITestSecondDisp iface: %08lx\n", hres);
3684 todo_wine
3685 ok(external_connections == 2, "external_connections = %d\n", external_connections);
3686
3687 ITestSecondDisp_Release(second);
3688 todo_wine
3689 ok(external_connections == 2, "external_connections = %d\n", external_connections);
3690
3692 ItestDual_Release(iface);
3693 ok(external_connections == 0, "external_connections = %d\n", external_connections);
3694
3696
3697 /* A test with direct CoMarshalInterface call. */
3699 ok(hres == S_OK, "CreateStreamOnHGlobal failed: %08lx\n", hres);
3700
3702 hres = CoMarshalInterface(stream, &IID_ItestDual, (IUnknown*)&TestDual, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
3703 ok(hres == S_OK, "CoMarshalInterface failed: %08lx\n", hres);
3704 ok(external_connections == 1, "external_connections = %d\n", external_connections);
3705
3707 IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
3709 ok(hres == S_OK, "CoReleaseMarshalData failed: %08lx\n", hres);
3710 ok(external_connections == 0, "external_connections = %d\n", external_connections);
3711
3712 /* Two separated marshal data are still one external connection. */
3713 hres = CreateStreamOnHGlobal(NULL, TRUE, &stream2);
3714 ok(hres == S_OK, "CreateStreamOnHGlobal failed: %08lx\n", hres);
3715
3717 IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
3718 hres = CoMarshalInterface(stream, &IID_ItestDual, (IUnknown*)&TestDual, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
3719 ok(hres == S_OK, "CoMarshalInterface failed: %08lx\n", hres);
3720 ok(external_connections == 1, "external_connections = %d\n", external_connections);
3721
3722 hres = CoMarshalInterface(stream2, &IID_ItestDual, (IUnknown*)&TestDual, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
3723 ok(hres == S_OK, "CoMarshalInterface failed: %08lx\n", hres);
3724 ok(external_connections == 1, "external_connections = %d\n", external_connections);
3725
3726 IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
3728 ok(hres == S_OK, "CoReleaseMarshalData failed: %08lx\n", hres);
3729 ok(external_connections == 1, "external_connections = %d\n", external_connections);
3730
3732 IStream_Seek(stream2, zero, STREAM_SEEK_SET, NULL);
3733 hres = CoReleaseMarshalData(stream2);
3734 ok(hres == S_OK, "CoReleaseMarshalData failed: %08lx\n", hres);
3735 ok(external_connections == 0, "external_connections = %d\n", external_connections);
3736
3737 IStream_Release(stream);
3738 IStream_Release(stream2);
3739
3740 /* Weak table marshaling does not increment external connections */
3742 ok(hres == S_OK, "CreateStreamOnHGlobal failed: %08lx\n", hres);
3743
3744 hres = CoMarshalInterface(stream, &IID_ItestDual, (IUnknown*)&TestDual, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLEWEAK);
3745 ok(hres == S_OK, "CoMarshalInterface failed: %08lx\n", hres);
3746 ok(external_connections == 0, "external_connections = %d\n", external_connections);
3747
3748 IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
3749 hres = CoUnmarshalInterface(stream, &IID_ItestDual, (void**)&iface);
3750 ok(hres == S_OK, "CoUnmarshalInterface failed: %08lx\n", hres);
3751 ok(external_connections == 0, "external_connections = %d\n", external_connections);
3752 ItestDual_Release(iface);
3753
3754 IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
3756 ok(hres == S_OK, "CoReleaseMarshalData failed: %08lx\n", hres);
3757 ok(external_connections == 0, "external_connections = %d\n", external_connections);
3758
3759 IStream_Release(stream);
3760}
3761
3763{
3764 static const LARGE_INTEGER zero;
3765
3766 ISomethingFromDispatch *disp_obj = create_disp_obj2(false);
3768 IDispatch *proxy_disp;
3769 IStream *stream;
3770 HANDLE thread;
3771 HRESULT hr;
3772 ULONG ref;
3773 DWORD tid;
3774
3776 tid = start_host_object(stream, &DIID_ItestIF4, (IUnknown *)disp_obj, MSHLFLAGS_NORMAL, &thread);
3777 IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
3778 hr = CoUnmarshalInterface(stream, &DIID_ItestIF4, (void **)&proxy_disp);
3779 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3780
3781 hr = IDispatch_GetTypeInfo(proxy_disp, 0xdeadbeef, 0, &typeinfo);
3782 ok(hr == 0xbeefdead, "Got hr %#lx.\n", hr);
3783
3784 ref = IDispatch_Release(proxy_disp);
3785 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3786 ref = IStream_Release(stream);
3787 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3789 ref = ISomethingFromDispatch_Release(disp_obj);
3790 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3791}
3792
3793START_TEST(tmarshal)
3794{
3795 HRESULT hr;
3796
3798
3800 if (FAILED(hr))
3801 {
3803 win_skip("Registration of the test typelib failed, skipping tests\n");
3804 return;
3805 }
3806
3810 test_libattr();
3813
3814 hr = UnRegisterTypeLib(&LIBID_TestTypelib, 2, 5, LOCALE_NEUTRAL,
3815 sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32);
3817
3819}
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
static int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define msg(x)
Definition: auth_time.c:54
#define ARRAY_SIZE(A)
Definition: main.h:20
static HANDLE thread
Definition: service.c:33
const GUID IID_IUnknown
r l[0]
Definition: byte_order.h:168
struct __type_info type_info
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR szEmpty[]
Definition: provider.c:50
HRESULT WINAPI CoRegisterMessageFilter(IMessageFilter *filter, IMessageFilter **ret_filter)
Definition: combase.c:2220
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(void *reserved, DWORD model)
Definition: combase.c:2803
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL delete_on_release, IStream **stream)
void *WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: malloc.c:381
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
HRESULT WINAPI CoMarshalInterface(IStream *stream, REFIID riid, IUnknown *unk, DWORD dest_context, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:483
HRESULT WINAPI CoReleaseMarshalData(IStream *stream)
Definition: marshal.c:673
HRESULT WINAPI CoUnmarshalInterface(IStream *stream, REFIID riid, void **ppv)
Definition: marshal.c:793
static const WCHAR empty[1]
Definition: string.c:47
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
OLECHAR * BSTR
Definition: compat.h:2293
#define MAX_PATH
Definition: compat.h:34
unsigned short VARTYPE
Definition: compat.h:2254
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define MultiByteToWideChar
Definition: compat.h:110
@ VT_UI8
Definition: compat.h:2315
@ VT_BSTR
Definition: compat.h:2303
@ VT_R4
Definition: compat.h:2299
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_BYREF
Definition: compat.h:2342
@ VT_UI2
Definition: compat.h:2312
@ VT_ERROR
Definition: compat.h:2305
@ VT_CLSID
Definition: compat.h:2337
@ VT_R8
Definition: compat.h:2300
@ VT_CY
Definition: compat.h:2301
@ VT_VARIANT
Definition: compat.h:2307
@ VT_I8
Definition: compat.h:2314
@ VT_I1
Definition: compat.h:2310
@ VT_I4
Definition: compat.h:2298
@ VT_I2
Definition: compat.h:2297
@ VT_UI4
Definition: compat.h:2313
@ VT_EMPTY
Definition: compat.h:2295
@ VT_DISPATCH
Definition: compat.h:2304
@ VT_UI1
Definition: compat.h:2311
#define lstrlenW
Definition: compat.h:750
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4152
LCID lcid
Definition: locale.c:5660
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
#define M_LN10
Definition: math.h:408
#define M_LN2
Definition: math.h:407
#define M_E
Definition: math.h:404
HRESULT WINAPI CreateStdDispatch(IUnknown *punkOuter, void *pvThis, ITypeInfo *ptinfo, IUnknown **stddisp)
Definition: dispatch.c:434
HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
Definition: safearray.c:1033
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
SAFEARRAY *WINAPI SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements)
Definition: safearray.c:677
HRESULT WINAPI SafeArrayGetLBound(SAFEARRAY *psa, UINT nDim, LONG *plLbound)
Definition: safearray.c:1066
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
HRESULT WINAPI LoadRegTypeLib(REFGUID rguid, WORD wVerMajor, WORD wVerMinor, LCID lcid, ITypeLib **ppTLib)
Definition: typelib.c:531
HRESULT WINAPI RegisterTypeLib(ITypeLib *ptlib, const WCHAR *szFullPath, const WCHAR *szHelpDir)
Definition: typelib.c:656
HRESULT WINAPI DispCallFunc(void *pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals, VARTYPE *prgvt, VARIANTARG **prgpvarg, VARIANT *pvargResult)
Definition: typelib.c:7071
HRESULT WINAPI UnRegisterTypeLib(REFGUID libid, WORD wVerMajor, WORD wVerMinor, LCID lcid, SYSKIND syskind)
Definition: typelib.c:882
HRESULT WINAPI LoadTypeLib(const OLECHAR *szFile, ITypeLib **pptLib)
Definition: typelib.c:458
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
r reserved
Definition: btrfs.c:3006
long long int64
Definition: platform.h:13
#define INFINITE
Definition: serial.h:102
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct _cl_event * event
Definition: glext.h:7739
GLuint * ids
Definition: glext.h:5907
GLuint GLuint * names
Definition: glext.h:11545
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLfloat f
Definition: glext.h:7540
GLenum const GLfloat * params
Definition: glext.h:5645
GLuint in
Definition: glext.h:9616
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLuint pathA
Definition: glext.h:11719
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
static TfClientId tid
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define d
Definition: ke_i.h:81
#define f
Definition: ke_i.h:83
#define c
Definition: ke_i.h:80
#define wine_dbgstr_w
Definition: kernel32.h:34
#define M_PI
Definition: macros.h:263
#define win_skip
Definition: minitest.h:67
#define todo_wine
Definition: minitest.h:80
LONG_PTR LPARAM
Definition: minwindef.h:175
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
static const BYTE us[]
Definition: encode.c:671
const char * var
Definition: shader.c:5666
static unsigned int number
Definition: dsound.c:1479
HRESULT hres
Definition: protocol.c:465
static PROCESS_INFORMATION pi
Definition: debugger.c:2303
static const LARGE_INTEGER ullZero
Definition: capture.c:45
static EXCEPINFO excepinfo
Definition: automation.c:47
static void release_host_object(DWORD tid, WPARAM wp)
Definition: marshal.c:776
static VARIANTARG static DISPID
Definition: ordinal.c:49
static RefUnk unk_in
Definition: misc.c:2110
static RefUnk unk_out
Definition: misc.c:2110
unsigned int UINT
Definition: ndis.h:50
#define LOCALE_NEUTRAL
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:279
UINT WINAPI SysStringByteLen(BSTR str)
Definition: oleaut.c:215
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
#define V_ERROR(A)
Definition: oleauto.h:241
#define V_UI1(A)
Definition: oleauto.h:266
#define V_I8(A)
Definition: oleauto.h:249
#define V_UI2REF(A)
Definition: oleauto.h:269
#define V_BSTRREF(A)
Definition: oleauto.h:227
#define V_R4REF(A)
Definition: oleauto.h:261
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_UI4REF(A)
Definition: oleauto.h:271
#define V_UNKNOWNREF(A)
Definition: oleauto.h:282
#define V_UI2(A)
Definition: oleauto.h:268
#define V_I1(A)
Definition: oleauto.h:243
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008
#define DISPATCH_METHOD
Definition: oleauto.h:1006
#define V_I8REF(A)
Definition: oleauto.h:250
#define V_VARIANTREF(A)
Definition: oleauto.h:283
#define V_VT(A)
Definition: oleauto.h:211
#define V_DISPATCHREF(A)
Definition: oleauto.h:240
#define V_UI8REF(A)
Definition: oleauto.h:273
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_BYREF(A)
Definition: oleauto.h:228
#define V_I4(A)
Definition: oleauto.h:247
#define V_R4(A)
Definition: oleauto.h:260
#define V_CY(A)
Definition: oleauto.h:229
#define V_UI4(A)
Definition: oleauto.h:270
#define V_DISPATCH(A)
Definition: oleauto.h:239
#define V_R8(A)
Definition: oleauto.h:262
#define DISPATCH_PROPERTYGET
Definition: oleauto.h:1007
#define V_I2REF(A)
Definition: oleauto.h:246
#define V_UI1REF(A)
Definition: oleauto.h:267
#define V_I1REF(A)
Definition: oleauto.h:244
#define V_UI8(A)
Definition: oleauto.h:272
#define V_R8REF(A)
Definition: oleauto.h:263
#define V_I2(A)
Definition: oleauto.h:245
#define V_I4REF(A)
Definition: oleauto.h:248
const GUID IID_IDispatch
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
char CHAR
Definition: pedump.c:57
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define IID_NULL
Definition: guiddef.h:98
#define wine_dbgstr_wn
Definition: testlist.c:2
const WCHAR * str
UINT64 MIDL_uhyper
Definition: rpcndr.h:78
INT64 hyper
Definition: rpcndr.h:77
#define LANG_NEUTRAL
Definition: nls.h:22
#define MAKELANGID(p, s)
Definition: nls.h:15
#define LANG_ENGLISH
Definition: nls.h:52
#define SUBLANG_NEUTRAL
Definition: nls.h:167
DWORD LCID
Definition: nls.h:13
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
#define __RPC_FAR
Definition: rpc.h:52
XML_HIDDEN void xmlParserErrors const char const xmlChar const xmlChar * str2
Definition: parser.h:35
XML_HIDDEN void xmlParserErrors const char const xmlChar * str1
Definition: parser.h:35
#define f2(x, y, z)
Definition: sha1.c:31
#define memset(x, y, z)
Definition: compat.h:39
int zero
Definition: sehframes.cpp:29
@ CC_STDCALL
Definition: spec2def.c:94
IKindaEnumWidget IKindaEnumWidget_iface
Definition: tmarshal.c:1779
LONG refs
Definition: tmarshal.c:1780
Definition: userinit.h:57
LONG refs
Definition: tmarshal.c:674
IWidget IWidget_iface
Definition: tmarshal.c:673
IUnknown * pDispatchUnknown
Definition: tmarshal.c:675
ICoclass1 ICoclass1_iface
Definition: tmarshal.c:501
LONG ref
Definition: tmarshal.c:503
ICoclass2 ICoclass2_iface
Definition: tmarshal.c:502
ISomethingFromDispatch ISomethingFromDispatch_iface
Definition: tmarshal.c:396
bool support_idispatch
Definition: tmarshal.c:398
LONG ref
Definition: tmarshal.c:397
IMessageFilter * filter
Definition: marshal.c:694
HANDLE marshal_event
Definition: marshal.c:697
const IID * iid
Definition: marshal.c:691
MSHLFLAGS marshal_flags
Definition: marshal.c:693
IUnknown * object
Definition: marshal.c:692
IStream * stream
Definition: marshal.c:690
Definition: parser.c:49
Definition: name.c:39
Definition: send.c:48
Definition: parse.h:23
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:573
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
static HRESULT WINAPI Widget_complex_struct(IWidget *iface, struct complex in)
Definition: tmarshal.c:1481
static const IStaticWidgetVtbl StaticWidgetVtbl
Definition: tmarshal.c:1763
static void test_marshal_struct(IWidget *widget, IDispatch *disp)
Definition: tmarshal.c:2604
static HRESULT WINAPI Widget_get_Name(IWidget __RPC_FAR *iface, BSTR __RPC_FAR *name)
Definition: tmarshal.c:806
static HRESULT WINAPI coclass2_GetTypeInfo(ICoclass2 *iface, UINT index, LCID lcid, ITypeInfo **typeinfo)
Definition: tmarshal.c:610
static HRESULT WINAPI NonOleAutomation_QueryInterface(INonOleAutomation *iface, REFIID riid, void **ppv)
Definition: tmarshal.c:1950
static HRESULT WINAPI TestDual_QueryInterface(ItestDual *iface, REFIID riid, void **ppvObject)
Definition: tmarshal.c:320
static IKindaEnumWidget * KindaEnumWidget_Create(void)
Definition: tmarshal.c:1939
static HRESULT WINAPI Widget_CloneCoclass(IWidget *iface, ApplicationObject2 **ppVal)
Definition: tmarshal.c:895
static HRESULT WINAPI Widget_Value(IWidget __RPC_FAR *iface, VARIANT *value, VARIANT *retval)
Definition: tmarshal.c:903
static ULONG WINAPI KindaEnum_Release(IKindaEnumWidget *iface)
Definition: tmarshal.c:1882
static void test_marshal_pointer(IWidget *widget, IDispatch *disp)
Definition: tmarshal.c:2105
static void test_marshal_array(IWidget *widget, IDispatch *disp)
Definition: tmarshal.c:2663
static HRESULT WINAPI disp_obj_GetTypeInfo(ISomethingFromDispatch *iface, UINT index, LCID lcid, ITypeInfo **typeinfo)
Definition: tmarshal.c:447
static void test_marshal_variant(IWidget *widget, IDispatch *disp)
Definition: tmarshal.c:2528
static ITestSecondDisp TestSecondDisp
Definition: tmarshal.c:318
static HRESULT WINAPI coclass1_test(ICoclass1 *iface)
Definition: tmarshal.c:581
static struct coclass_obj * impl_from_ICoclass1(ICoclass1 *iface)
Definition: tmarshal.c:506
static HRESULT WINAPI KindaEnum_Count(IKindaEnumWidget *iface, ULONG __RPC_FAR *count)
Definition: tmarshal.c:1908
static HRESULT WINAPI TestSecondIface_test(ITestSecondIface *iface)
Definition: tmarshal.c:245
static HRESULT WINAPI Widget_iface_in(IWidget *iface, IUnknown *unk, IDispatch *disp, ISomethingFromDispatch *sfd)
Definition: tmarshal.c:1260
static ItestDual TestDual
Definition: tmarshal.c:228
static const MYSTRUCT test_mystruct3
Definition: tmarshal.c:50
static const ISomethingFromDispatchVtbl disp_obj_vtbl
Definition: tmarshal.c:473
static HRESULT WINAPI coclass1_GetTypeInfo(ICoclass1 *iface, UINT index, LCID lcid, ITypeInfo **typeinfo)
Definition: tmarshal.c:560
static void test_StaticWidget(void)
Definition: tmarshal.c:3580
static void test_marshal_dispinterface(void)
Definition: tmarshal.c:3762
static HRESULT WINAPI Widget_GetTypeInfoCount(IWidget *iface, UINT __RPC_FAR *pctinfo)
Definition: tmarshal.c:725
static HRESULT WINAPI Widget_Map(IWidget *iface, BSTR bstrId, BSTR *sValue)
Definition: tmarshal.c:852
static IStaticWidget StaticWidget
Definition: tmarshal.c:1775
static HRESULT WINAPI Widget_VarArg(IWidget *iface, int numexpect, SAFEARRAY *values)
Definition: tmarshal.c:924
static const RECT test_rect1
Definition: tmarshal.c:58
static const ITestSecondIfaceVtbl TestSecondIfaceVtbl
Definition: tmarshal.c:250
static HRESULT WINAPI Widget_put_prop_with_lcid(IWidget *iface, LONG lcid, INT i)
Definition: tmarshal.c:978
static HRESULT WINAPI coclass2_QueryInterface(ICoclass2 *iface, REFIID iid, void **out)
Definition: tmarshal.c:586
static void test_marshal_basetypes(IWidget *widget, IDispatch *disp)
Definition: tmarshal.c:2009
static struct coclass_obj * impl_from_ICoclass2(ICoclass2 *iface)
Definition: tmarshal.c:511
static HRESULT WINAPI Widget_CloneDispatch(IWidget *iface, IDispatch **ppVal)
Definition: tmarshal.c:887
static HRESULT WINAPI StaticWidget_QueryInterface(IStaticWidget *iface, REFIID riid, void **ppvObject)
Definition: tmarshal.c:1698
static ULONG WINAPI coclass2_Release(ICoclass2 *iface)
Definition: tmarshal.c:598
#define release_iface(a)
Definition: tmarshal.c:41
static HRESULT WINAPI Widget_Coclass_ptr(IWidget *iface, Coclass1 **in, Coclass1 **out, Coclass1 **in_out)
Definition: tmarshal.c:1571
static ULONG WINAPI NonOleAutomation_AddRef(INonOleAutomation *iface)
Definition: tmarshal.c:1961
static ULONG WINAPI Widget_Release(IWidget *iface)
Definition: tmarshal.c:709
static HRESULT WINAPI coclass2_Invoke(ICoclass2 *iface, DISPID id, REFIID iid, LCID lcid, WORD flags, DISPPARAMS *dispparams, VARIANT *result, EXCEPINFO *excepinfo, UINT *errarg)
Definition: tmarshal.c:624
static ULONG WINAPI disp_obj_AddRef(ISomethingFromDispatch *iface)
Definition: tmarshal.c:426
static const ICoclass2Vtbl coclass2_vtbl
Definition: tmarshal.c:648
static HRESULT WINAPI Widget_Coclass_noptr(IWidget *iface, Coclass1 class1, Coclass2 class2, Coclass3 class3)
Definition: tmarshal.c:1611
static const array_t test_array4
Definition: tmarshal.c:69
static HRESULT WINAPI StaticWidget_TestDual(IStaticWidget *iface, ItestDual *p)
Definition: tmarshal.c:1749
static HRESULT WINAPI Widget_long_ptr(IWidget *iface, LONG *in, LONG *out, LONG *in_out)
Definition: tmarshal.c:1190
static const RECT test_rect5
Definition: tmarshal.c:62
static HRESULT WINAPI Widget_DoSomething(IWidget __RPC_FAR *iface, double number, BSTR *str1, BSTR str2, VARIANT __RPC_FAR *opt)
Definition: tmarshal.c:816
static HRESULT WINAPI Widget_Coclass(IWidget *iface, Coclass1 *class1, Coclass2 *class2, Coclass3 *class3)
Definition: tmarshal.c:1555
static ItestDual TestDualDisp
Definition: tmarshal.c:228
static ULONG WINAPI ExternalConnection_Release(IExternalConnection *iface)
Definition: tmarshal.c:191
static const RECT test_rect4
Definition: tmarshal.c:61
static ULONG WINAPI disp_obj_Release(ISomethingFromDispatch *iface)
Definition: tmarshal.c:432
static HRESULT WINAPI StaticWidget_GetIDsOfNames(IStaticWidget *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
Definition: tmarshal.c:1734
static HRESULT WINAPI Widget_Invoke(IWidget __RPC_FAR *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS __RPC_FAR *pDispParams, VARIANT __RPC_FAR *pVarResult, EXCEPINFO __RPC_FAR *pExcepInfo, UINT __RPC_FAR *puArgErr)
Definition: tmarshal.c:776
#define ok_ole_success(hr, func)
Definition: tmarshal.c:34
static const IKindaEnumWidgetVtbl KindaEnumWidget_VTable
Definition: tmarshal.c:1928
static HRESULT WINAPI TestDual_GetTypeInfo(ItestDual *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
Definition: tmarshal.c:360
static HRESULT WINAPI KindaEnum_Clone(IKindaEnumWidget *iface, IKindaEnumWidget __RPC_FAR *__RPC_FAR *ppenum)
Definition: tmarshal.c:1921
static HRESULT WINAPI TestSecondDisp_Invoke(ITestSecondDisp *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: tmarshal.c:293
static int external_connections
Definition: tmarshal.c:176
static ITestSecondDispVtbl TestSecondDispVtbl
Definition: tmarshal.c:307
static HRESULT WINAPI KindaEnum_Reset(IKindaEnumWidget *iface)
Definition: tmarshal.c:1915
static void test_marshal_safearray(IWidget *widget, IDispatch *disp)
Definition: tmarshal.c:2580
static ITestSecondIface TestSecondIface
Definition: tmarshal.c:257
static HRESULT WINAPI Widget_variant(IWidget *iface, VARIANT in, VARIANT *out, VARIANT *in_ptr, VARIANT *in_out)
Definition: tmarshal.c:1361
static HRESULT WINAPI Widget_Clone(IWidget *iface, IWidget **ppVal)
Definition: tmarshal.c:879
static HRESULT WINAPI Widget_variant_array(IWidget *iface, VARIANT in[2], VARIANT out[2], VARIANT in_out[2])
Definition: tmarshal.c:1517
static HRESULT WINAPI TestSecondDisp_GetTypeInfo(ITestSecondDisp *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
Definition: tmarshal.c:280
static ULONG WINAPI coclass1_Release(ICoclass1 *iface)
Definition: tmarshal.c:545
static HRESULT WINAPI Widget_mystruct_ptr_ptr(IWidget *iface, MYSTRUCT **in)
Definition: tmarshal.c:1455
static HRESULT WINAPI Widget_put_prop_req_arg(IWidget *iface, INT req, INT i)
Definition: tmarshal.c:1028
static HRESULT WINAPI coclass1_Invoke(ICoclass1 *iface, DISPID id, REFIID iid, LCID lcid, WORD flags, DISPPARAMS *dispparams, VARIANT *result, EXCEPINFO *excepinfo, UINT *errarg)
Definition: tmarshal.c:574
static HRESULT WINAPI disp_obj_QueryInterface(ISomethingFromDispatch *iface, REFIID iid, void **out)
Definition: tmarshal.c:406
static HRESULT WINAPI Widget_put_prop_opt_arg(IWidget *iface, INT opt, INT i)
Definition: tmarshal.c:1019
static HRESULT WINAPI Widget_GetTypeInfo(IWidget __RPC_FAR *iface, UINT iTInfo, LCID lcid, ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
Definition: tmarshal.c:740
static HRESULT WINAPI coclass1_QueryInterface(ICoclass1 *iface, REFIID iid, void **out)
Definition: tmarshal.c:516
static const RECT test_rect2
Definition: tmarshal.c:59
static HRESULT WINAPI Widget_get_prop_int(IWidget *iface, INT *i)
Definition: tmarshal.c:996
static const array_t test_array2
Definition: tmarshal.c:67
static HRESULT WINAPI Widget_get_prop_with_lcid(IWidget *iface, LONG lcid, INT *i)
Definition: tmarshal.c:987
static void check_safearray(SAFEARRAY *sa, LONG expect)
Definition: tmarshal.c:1404
static const MYSTRUCT test_mystruct6
Definition: tmarshal.c:53
static const array_t test_array3
Definition: tmarshal.c:68
static DWORD start_host_object(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, HANDLE *thread)
Definition: tmarshal.c:150
static BSTR WINAPI NonOleAutomation_BstrRet(INonOleAutomation *iface)
Definition: tmarshal.c:1971
static HRESULT WINAPI KindaEnum_QueryInterface(IKindaEnumWidget *iface, REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject)
Definition: tmarshal.c:1856
static void end_host_object(DWORD tid, HANDLE thread)
Definition: tmarshal.c:167
static HRESULT WINAPI Widget_put_State(IWidget __RPC_FAR *iface, STATE state)
Definition: tmarshal.c:844
static HRESULT WINAPI Widget_array(IWidget *iface, array_t in, array_t out, array_t in_out)
Definition: tmarshal.c:1503
static HRESULT WINAPI disp_obj_anotherfn(ISomethingFromDispatch *iface)
Definition: tmarshal.c:468
static const struct IWidgetVtbl Widget_VTable
Definition: tmarshal.c:1635
static ULONG WINAPI TestSecondIface_Release(ITestSecondIface *iface)
Definition: tmarshal.c:240
static HRESULT WINAPI TestDual_Invoke(ItestDual *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: tmarshal.c:373
static HRESULT register_current_module_typelib(void)
Definition: tmarshal.c:1788
static HRESULT WINAPI Widget_Error(IWidget __RPC_FAR *iface)
Definition: tmarshal.c:962
static HRESULT WINAPI Widget_neg_restrict(IWidget *iface, INT *i)
Definition: tmarshal.c:1044
static HRESULT WINAPI Widget_long_ptr_ptr(IWidget *iface, LONG **in, LONG **out, LONG **in_out)
Definition: tmarshal.c:1206
static const MYSTRUCT test_mystruct2
Definition: tmarshal.c:49
static HRESULT WINAPI Widget_basetypes_out(IWidget *iface, signed char *c, short *s, LONG *l, hyper *h, unsigned char *uc, unsigned short *us, ULONG *ul, MIDL_uhyper *uh, float *f, double *d, STATE *st)
Definition: tmarshal.c:1160
static HRESULT WINAPI Widget_GetIDsOfNames(IWidget __RPC_FAR *iface, REFIID riid, LPOLESTR __RPC_FAR *rgszNames, UINT cNames, LCID lcid, DISPID __RPC_FAR *rgDispId)
Definition: tmarshal.c:757
static ULONG WINAPI NonOleAutomation_Release(INonOleAutomation *iface)
Definition: tmarshal.c:1966
static HRESULT WINAPI Widget_ByRefUInt(IWidget *iface, UINT *i)
Definition: tmarshal.c:1012
#define RELEASEMARSHALDATA
Definition: tmarshal.c:73
static const array_t test_array1
Definition: tmarshal.c:66
static HRESULT WINAPI TestSecondDisp_GetIDsOfNames(ITestSecondDisp *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
Definition: tmarshal.c:286
static HRESULT WINAPI StaticWidget_GetTypeInfo(IStaticWidget *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
Definition: tmarshal.c:1727
static void check_iface_marshal(IUnknown *unk, IDispatch *disp, ISomethingFromDispatch *sfd)
Definition: tmarshal.c:1243
static ULONG WINAPI TestDual_Release(ItestDual *iface)
Definition: tmarshal.c:349
static HRESULT WINAPI Widget_iface_out(IWidget *iface, IUnknown **unk, IDispatch **disp, ISomethingFromDispatch **sfd)
Definition: tmarshal.c:1273
static ITypeInfo * get_type_info(REFIID riid)
Definition: tmarshal.c:1807
static HRESULT WINAPI Widget_no_in_out(IWidget *iface, BSTR str, int i)
Definition: tmarshal.c:1627
static BOOL expect_last_release_closes
Definition: tmarshal.c:177
static ULONG WINAPI Widget_AddRef(IWidget *iface)
Definition: tmarshal.c:701
static IExternalConnection ExternalConnection
Definition: tmarshal.c:226
static ULONG WINAPI StaticWidget_Release(IStaticWidget *iface)
Definition: tmarshal.c:1716
static DWORD WINAPI ExternalConnection_ReleaseConnection(IExternalConnection *iface, DWORD extconn, DWORD reserved, BOOL fLastReleaseCloses)
Definition: tmarshal.c:205
static ULONG WINAPI ExternalConnection_AddRef(IExternalConnection *iface)
Definition: tmarshal.c:186
static HRESULT WINAPI Widget_put_Name(IWidget __RPC_FAR *iface, BSTR name)
Definition: tmarshal.c:798
static HRESULT WINAPI Widget_iface_ptr(IWidget *iface, ISomethingFromDispatch **in, ISomethingFromDispatch **out, ISomethingFromDispatch **in_out)
Definition: tmarshal.c:1288
static void test_DispCallFunc(void)
Definition: tmarshal.c:3550
static INonOleAutomationVtbl NonOleAutomation_VTable
Definition: tmarshal.c:1982
static const MYSTRUCT test_mystruct1
Definition: tmarshal.c:48
static Widget * impl_from_IWidget(IWidget *iface)
Definition: tmarshal.c:678
static HRESULT WINAPI TestSecondIface_QueryInterface(ITestSecondIface *iface, REFIID riid, void **ppv)
Definition: tmarshal.c:230
static ULONG WINAPI coclass1_AddRef(ICoclass1 *iface)
Definition: tmarshal.c:539
static ISomethingFromDispatch * create_disp_obj(void)
Definition: tmarshal.c:494
static struct coclass_obj * create_coclass_obj(void)
Definition: tmarshal.c:660
static HRESULT WINAPI Widget_CloneInterface(IWidget __RPC_FAR *iface, ISomethingFromDispatch **ppVal)
Definition: tmarshal.c:969
static ULONG WINAPI TestSecondDisp_Release(ITestSecondDisp *iface)
Definition: tmarshal.c:269
static HRESULT WINAPI Widget_pos_restrict(IWidget *iface, INT *i)
Definition: tmarshal.c:1037
static HRESULT WINAPI TestSecondDisp_QueryInterface(ITestSecondDisp *iface, REFIID riid, void **ppv)
Definition: tmarshal.c:259
static const struct thin test_thin_struct
Definition: tmarshal.c:56
static HRESULT WINAPI Widget_basetypes_in(IWidget *iface, signed char c, short s, LONG l, hyper h, unsigned char uc, unsigned short us, ULONG ul, MIDL_uhyper uh, float f, double d, STATE st)
Definition: tmarshal.c:1141
static HRESULT WINAPI coclass2_GetTypeInfoCount(ICoclass2 *iface, UINT *count)
Definition: tmarshal.c:604
static HRESULT WINAPI Widget_QueryInterface(IWidget *iface, REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject)
Definition: tmarshal.c:683
static HRESULT WINAPI coclass2_test(ICoclass2 *iface)
Definition: tmarshal.c:631
static DWORD start_host_object2(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, IMessageFilter *filter, HANDLE *thread)
Definition: tmarshal.c:128
static void test_libattr(void)
Definition: tmarshal.c:3622
static HRESULT WINAPI Widget_mystruct_array(IWidget *iface, MYSTRUCT in[2])
Definition: tmarshal.c:1540
static KindaEnum * impl_from_IKindaEnumWidget(IKindaEnumWidget *iface)
Definition: tmarshal.c:1783
static HRESULT WINAPI disp_obj_GetIDsOfNames(ISomethingFromDispatch *iface, REFIID iid, LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
Definition: tmarshal.c:454
static HRESULT WINAPI ExternalConnection_QueryInterface(IExternalConnection *iface, REFIID riid, void **ppv)
Definition: tmarshal.c:179
static HRESULT WINAPI Widget_get_State(IWidget __RPC_FAR *iface, STATE __RPC_FAR *state)
Definition: tmarshal.c:835
static const RECT test_rect6
Definition: tmarshal.c:63
static SAFEARRAY * make_safearray(ULONG len)
Definition: tmarshal.c:1391
static HRESULT WINAPI TestDual_GetTypeInfoCount(ItestDual *iface, UINT *pctinfo)
Definition: tmarshal.c:354
static HRESULT WINAPI coclass1_GetIDsOfNames(ICoclass1 *iface, REFIID iid, LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
Definition: tmarshal.c:567
static const array_t test_array6
Definition: tmarshal.c:71
static HRESULT WINAPI Widget_thin_struct(IWidget *iface, struct thin in)
Definition: tmarshal.c:1461
static HRESULT WINAPI Widget_iface_noptr(IWidget *iface, IUnknown unk, IDispatch disp, ISomethingFromDispatch sfd)
Definition: tmarshal.c:1325
static IWidget * Widget_Create(void)
Definition: tmarshal.c:1827
static const RECT test_rect3
Definition: tmarshal.c:60
static HRESULT WINAPI KindaEnum_Next(IKindaEnumWidget *iface, IWidget __RPC_FAR *__RPC_FAR *widget)
Definition: tmarshal.c:1897
static HRESULT WINAPI Widget_VarArg_Run(IWidget *iface, BSTR name, SAFEARRAY *params, VARIANT *result)
Definition: tmarshal.c:1051
static HRESULT WINAPI StaticWidget_Invoke(IStaticWidget *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: tmarshal.c:1741
static HRESULT WINAPI Widget_safearray(IWidget *iface, SAFEARRAY *in, SAFEARRAY **out, SAFEARRAY **in_ptr, SAFEARRAY **in_out)
Definition: tmarshal.c:1423
static const WCHAR test_bstr2[]
Definition: tmarshal.c:44
static DWORD CALLBACK host_object_proc(LPVOID p)
Definition: tmarshal.c:85
static HRESULT WINAPI TestDual_GetIDsOfNames(ItestDual *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
Definition: tmarshal.c:366
static HRESULT WINAPI TestSecondDisp_GetTypeInfoCount(ITestSecondDisp *iface, UINT *pctinfo)
Definition: tmarshal.c:274
static INonOleAutomation NonOleAutomation
Definition: tmarshal.c:1991
static ULONG WINAPI coclass2_AddRef(ICoclass2 *iface)
Definition: tmarshal.c:592
static void test_external_connection(void)
Definition: tmarshal.c:3645
static HRESULT WINAPI Widget_VariantArrayPtr(IWidget *iface, SAFEARRAY **values)
Definition: tmarshal.c:916
static void release_iface_(unsigned int line, void *iface)
Definition: tmarshal.c:35
static const array_t test_array5
Definition: tmarshal.c:70
static HRESULT WINAPI disp_obj_Invoke(ISomethingFromDispatch *iface, DISPID id, REFIID iid, LCID lcid, WORD flags, DISPPARAMS *dispparams, VARIANT *result, EXCEPINFO *excepinfo, UINT *errarg)
Definition: tmarshal.c:461
static const MYSTRUCT test_mystruct4
Definition: tmarshal.c:51
static HRESULT WINAPI disp_obj_GetTypeInfoCount(ISomethingFromDispatch *iface, UINT *count)
Definition: tmarshal.c:441
static ISomethingFromDispatch * create_disp_obj2(bool support_idispatch)
Definition: tmarshal.c:485
static HRESULT WINAPI Widget_VarArg_Ref_Run(IWidget *iface, BSTR name, SAFEARRAY **params, VARIANT *result)
Definition: tmarshal.c:1096
static HRESULT WINAPI Widget_mystruct(IWidget *iface, MYSTRUCT in, MYSTRUCT *out, MYSTRUCT *in_ptr, MYSTRUCT *in_out)
Definition: tmarshal.c:1441
static HRESULT WINAPI Widget_bstr(IWidget *iface, BSTR in, BSTR *out, BSTR *in_ptr, BSTR *in_out)
Definition: tmarshal.c:1331
static ItestDualVtbl TestDualVtbl
Definition: tmarshal.c:381
static ITypeInfo * NonOleAutomation_GetTypeInfo(void)
Definition: tmarshal.c:1993
static ULONG WINAPI TestSecondIface_AddRef(ITestSecondIface *iface)
Definition: tmarshal.c:235
static void test_marshal_bstr(IWidget *widget, IDispatch *disp)
Definition: tmarshal.c:2472
static int testmode
Definition: tmarshal.c:669
static HRESULT WINAPI coclass2_GetIDsOfNames(ICoclass2 *iface, REFIID iid, LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
Definition: tmarshal.c:617
static HRESULT WINAPI StaticWidget_TestSecondIface(IStaticWidget *iface, ITestSecondIface *p)
Definition: tmarshal.c:1756
static const MYSTRUCT test_mystruct7
Definition: tmarshal.c:54
static DWORD WINAPI ExternalConnection_AddConnection(IExternalConnection *iface, DWORD extconn, DWORD reserved)
Definition: tmarshal.c:196
static ULONG WINAPI TestSecondDisp_AddRef(ITestSecondDisp *iface)
Definition: tmarshal.c:264
static HRESULT WINAPI Widget_SetOleColor(IWidget *iface, OLE_COLOR val)
Definition: tmarshal.c:862
static const IExternalConnectionVtbl ExternalConnectionVtbl
Definition: tmarshal.c:218
static ULONG WINAPI StaticWidget_AddRef(IStaticWidget *iface)
Definition: tmarshal.c:1711
static HRESULT WINAPI Widget_GetOleColor(IWidget *iface, OLE_COLOR *pVal)
Definition: tmarshal.c:870
static HRESULT WINAPI coclass1_GetTypeInfoCount(ICoclass1 *iface, UINT *count)
Definition: tmarshal.c:554
static HRESULT WINAPI Widget_get_prop_uint(IWidget *iface, UINT *i)
Definition: tmarshal.c:1004
static HRESULT WINAPI TestSecondDisp_test(ITestSecondDisp *iface)
Definition: tmarshal.c:301
static struct disp_obj * impl_from_ISomethingFromDispatch(ISomethingFromDispatch *iface)
Definition: tmarshal.c:401
static const WCHAR test_bstr1[]
Definition: tmarshal.c:43
static ULONG WINAPI KindaEnum_AddRef(IKindaEnumWidget *iface)
Definition: tmarshal.c:1874
static const MYSTRUCT test_mystruct5
Definition: tmarshal.c:52
static HRESULT WINAPI Widget_myint(IWidget *iface, myint_t val, myint_t *ptr, myint_t **ptr_ptr)
Definition: tmarshal.c:1547
static void test_typelibmarshal(void)
Definition: tmarshal.c:2925
static const RECT test_rect7
Definition: tmarshal.c:64
static const WCHAR test_bstr3[]
Definition: tmarshal.c:45
static void test_marshal_coclass(IWidget *widget, IDispatch *disp)
Definition: tmarshal.c:2714
static ULONG WINAPI TestDual_AddRef(ItestDual *iface)
Definition: tmarshal.c:344
static const WCHAR test_bstr4[]
Definition: tmarshal.c:46
static HRESULT WINAPI Widget_rect(IWidget *iface, RECT in, RECT *out, RECT *in_ptr, RECT *in_out)
Definition: tmarshal.c:1467
static const ICoclass1Vtbl coclass1_vtbl
Definition: tmarshal.c:636
static HRESULT WINAPI Widget_float_abi(IWidget *iface, float f, double d, int i, float f2, double d2)
Definition: tmarshal.c:1179
static void test_marshal_iface(IWidget *widget, IDispatch *disp)
Definition: tmarshal.c:2219
static HRESULT WINAPI NonOleAutomation_Error(INonOleAutomation *iface)
Definition: tmarshal.c:1977
static HRESULT WINAPI StaticWidget_GetTypeInfoCount(IStaticWidget *iface, UINT *pctinfo)
Definition: tmarshal.c:1721
@ DISPID_TM_COCLASS_PTR
Definition: tmarshal.idl:75
@ DISPID_TM_IFACE_PTR
Definition: tmarshal.idl:60
@ DISPID_TM_BASETYPES_OUT
Definition: tmarshal.idl:54
@ DISPID_TM_IFACE_OUT
Definition: tmarshal.idl:59
@ DISPID_TM_IFACE_IN
Definition: tmarshal.idl:58
@ DISPID_TM_INT_PTR
Definition: tmarshal.idl:56
@ DISPID_TM_BSTR
Definition: tmarshal.idl:62
@ DISPID_TM_BASETYPES_IN
Definition: tmarshal.idl:53
#define DISPID_TM_CLONE
#define DISPID_TM_BYREF_UINT
#define DISPID_TM_COCLASS
#define DISPID_TM_PROP_INT
#define DISPID_TM_VARARG_REF_RUN
#define DISPID_NOA_BSTRRET
#define DISPID_TM_VARARRAYPTR
#define DISPID_TM_CLONEDISPATCH
#define DISPID_NOA_ERROR
#define DISPID_TM_ARRAY
#define DISPID_TM_STATE
#define DISPID_TM_DOSOMETHING
#define DISPID_TM_ERROR
#define DISPID_TM_PROP_REQ_ARG
#define DISPID_TM_SETOLECOLOR
#define DISPID_TM_RESTRICTED
#define DISPID_TM_TESTSECONDIFACE
#define DISPID_TM_PROP_UINT
#define DISPID_TM_NEG_RESTRICTED
#define DISPID_TM_VARARG
#define DISPID_TM_TESTDUAL
#define DISPID_TM_PROP_OPT_ARG
#define DISPID_TM_MAP
#define DISPID_TM_GETOLECOLOR
#define DISPID_TM_CLONECOCLASS
#define DISPID_TM_CLONEINTERFACE
#define DISPID_TM_NAME
#define DISPID_TM_VARARG_RUN
#define DISPID_TM_VARIANT
#define DISPID_TM_PROP_WITH_LCID
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int64_t LONGLONG
Definition: typedefs.h:68
int32_t INT
Definition: typedefs.h:58
uint64_t ULONGLONG
Definition: typedefs.h:67
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:96
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
int retval
Definition: wcstombs.cpp:91
@ SYS_WIN32
Definition: widltypes.h:647
@ SYS_WIN64
Definition: widltypes.h:649
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
WINBASEAPI _In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon_undoc.h:337
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define DISP_E_PARAMNOTFOUND
Definition: winerror.h:3616
#define DISP_E_NONAMEDARGS
Definition: winerror.h:3619
#define E_NOINTERFACE
Definition: winerror.h:3479
#define DISP_E_BADVARTYPE
Definition: winerror.h:3620
#define DISP_E_BADPARAMCOUNT
Definition: winerror.h:3626
#define DISP_E_NOTACOLLECTION
Definition: winerror.h:3629
#define DISP_E_MEMBERNOTFOUND
Definition: winerror.h:3615
#define RPC_X_NULL_REF_POINTER
Definition: winerror.h:1444
#define DISP_E_EXCEPTION
Definition: winerror.h:3621
#define DISP_E_TYPEMISMATCH
Definition: winerror.h:3617
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
#define WM_QUIT
Definition: winuser.h:1651
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define WM_USER
Definition: winuser.h:1923
BOOL WINAPI PostThreadMessageA(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
BOOL WINAPI EqualRect(_In_ LPCRECT, _In_ LPCRECT)
#define PM_NOREMOVE
Definition: winuser.h:1206