ReactOS 0.4.16-dev-2354-g16de117
marshal.c
Go to the documentation of this file.
1/*
2 * Marshaling Tests
3 *
4 * Copyright 2004 Robert Shearman
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#define _WIN32_DCOM
22#define COBJMACROS
23#define CONST_VTABLE
24
25#include <stdarg.h>
26#include <stdio.h>
27
28#include "windef.h"
29#include "winbase.h"
30#include "objbase.h"
31#include "olectl.h"
32#include "shlguid.h"
33#include "shobjidl.h"
34
35#include "wine/test.h"
36
37#define DEFINE_EXPECT(func) \
38 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
39
40#define SET_EXPECT(func) \
41 expect_ ## func = TRUE
42
43#define CHECK_EXPECT2(func) \
44 do { \
45 ok(expect_ ##func, "unexpected call " #func "\n"); \
46 called_ ## func = TRUE; \
47 }while(0)
48
49#define CHECK_EXPECT(func) \
50 do { \
51 CHECK_EXPECT2(func); \
52 expect_ ## func = FALSE; \
53 }while(0)
54
55#define CHECK_CALLED(func) \
56 do { \
57 ok(called_ ## func, "expected " #func "\n"); \
58 expect_ ## func = called_ ## func = FALSE; \
59 }while(0)
60
61static const GUID CLSID_WineTestPSFactoryBuffer = { 0x22222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
62static const GUID CLSID_DfMarshal = { 0x0000030b, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
63static const GUID CLSID_ft_unmarshaler_1809 = {0x00000359, 0x0000, 0x0000, {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
64
65/* functions that are not present on all versions of Windows */
66static HRESULT (WINAPI *pDllGetClassObject)(REFCLSID,REFIID,LPVOID);
67
68/* helper macros to make tests a bit leaner */
69#define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %ld\n", cLocks)
70#define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %ld\n", cLocks)
71#define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error %#08lx\n", hr)
72#define ok_non_zero_external_conn() do {if (with_external_conn) ok(external_connections, "got no external connections\n");} while(0);
73#define ok_zero_external_conn() do {if (with_external_conn) ok(!external_connections, "got %ld external connections\n", external_connections);} while(0);
74#define ok_last_release_closes(b) do {if (with_external_conn) ok(last_release_closes == b, "got %d expected %d\n", last_release_closes, b);} while(0);
75
76#define OBJREF_SIGNATURE (0x574f454d)
77#define OBJREF_STANDARD (0x1)
78#define OBJREF_CUSTOM (0x4)
79
80typedef struct tagDUALSTRINGARRAY {
81 unsigned short wNumEntries;
82 unsigned short wSecurityOffset;
83 unsigned short aStringArray[1];
85
86typedef UINT64 OXID;
87typedef UINT64 OID;
88typedef GUID IPID;
89
90typedef struct tagSTDOBJREF {
97
98typedef struct tagOBJREF {
102 union {
103 struct OR_STANDARD {
107 struct OR_HANDLER {
110 DUALSTRINGARRAY saResAddr;
112 struct OR_CUSTOM {
113 CLSID clsid;
116 byte *pData;
120
121static const IID IID_IWineTest =
122{
123 0x5201163f,
124 0x8164,
125 0x4fd0,
126 {0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
127}; /* 5201163f-8164-4fd0-a1a2-5d5a3654d3bd */
128
129static const IID IID_IRemUnknown =
130{
131 0x00000131,
132 0x0000,
133 0x0000,
134 {0xc0,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
135};
136
137#define EXTENTID_WineTest IID_IWineTest
138#define CLSID_WineTest IID_IWineTest
139
141{
142 0x5201163f,
143 0x8164,
144 0x4fd0,
145 {0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
146}; /* 5201163f-8164-4fd0-a1a2-5d5a3654d3bd */
147
149{
150 IUnknown *pProxy;
151 IMultiQI *pMQI;
152 HRESULT hr;
153
155
156 hr = CoCreateInstance(&CLSID_ShellDesktop, NULL, CLSCTX_INPROC, &IID_IUnknown, (void **)&pProxy);
158 hr = IUnknown_QueryInterface(pProxy, &IID_IMultiQI, (void **)&pMQI);
159 ok(hr == S_OK, "created object is not a proxy, so was created in the wrong apartment\n");
160 if (hr == S_OK)
161 IMultiQI_Release(pMQI);
162 IUnknown_Release(pProxy);
163
165}
166
169
170static void LockModule(void)
171{
173}
174
175static void UnlockModule(void)
176{
178}
179
183
185{
186 ok(0, "unexpected call\n");
187 *ppv = NULL;
188 return E_NOINTERFACE;
189}
190
192{
193 return 2;
194}
195
197{
198 return 1;
199}
200
202{
203 if (winetest_debug > 1) trace("add connection\n");
204 return ++external_connections;
205}
206
207
209 DWORD reserved, BOOL fLastReleaseCloses)
210{
211 if (winetest_debug > 1) trace("release connection %d\n", fLastReleaseCloses);
212 last_release_closes = fLastReleaseCloses;
213 return --external_connections;
214}
215
216static const IExternalConnectionVtbl ExternalConnectionVtbl = {
222};
223
225
226
228 LPUNKNOWN iface,
229 REFIID riid,
230 LPVOID *ppvObj)
231{
232 if (ppvObj == NULL) return E_POINTER;
233
235 {
236 *ppvObj = iface;
237 IUnknown_AddRef(iface);
238 return S_OK;
239 }
240
241 *ppvObj = NULL;
242 return E_NOINTERFACE;
243}
244
246{
247 LockModule();
248 return 2; /* non-heap-based object */
249}
250
252{
253 UnlockModule();
254 return 1; /* non-heap-based object */
255}
256
257static const IUnknownVtbl TestUnknown_Vtbl =
258{
262};
263
265
267{
268 UnlockModule();
269 if(!cLocks) {
270 trace("crashing...\n");
272 }
273 return 1; /* non-heap-based object */
274}
275
276static const IUnknownVtbl TestCrashUnknown_Vtbl =
277{
281};
282
284
286 LPCLASSFACTORY iface,
287 REFIID riid,
288 LPVOID *ppvObj)
289{
290 if (ppvObj == NULL) return E_POINTER;
291
294 /* the only other interface Wine is currently able to marshal (for testing two proxies) */
296 {
297 *ppvObj = iface;
298 IClassFactory_AddRef(iface);
299 return S_OK;
300 }
301
302 if (with_external_conn && IsEqualGUID(riid, &IID_IExternalConnection))
303 {
304 *ppvObj = &ExternalConnection;
305 return S_OK;
306 }
307
308 *ppvObj = NULL;
309 return E_NOINTERFACE;
310}
311
312static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
313{
314 LockModule();
315 return 2; /* non-heap-based object */
316}
317
318static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
319{
320 UnlockModule();
321 return 1; /* non-heap-based object */
322}
323
325 LPCLASSFACTORY iface,
326 LPUNKNOWN pUnkOuter,
327 REFIID riid,
328 LPVOID *ppvObj)
329{
330 if (pUnkOuter) return CLASS_E_NOAGGREGATION;
331 return IUnknown_QueryInterface(&Test_Unknown, riid, ppvObj);
332}
333
335 LPCLASSFACTORY iface,
336 BOOL fLock)
337{
338 return S_OK;
339}
340
341static const IClassFactoryVtbl TestClassFactory_Vtbl =
342{
348};
349
351
354DEFINE_EXPECT(CreateStub);
355DEFINE_EXPECT(CreateProxy);
359
361{
362 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
363 *ppv = NULL;
364 return E_NOINTERFACE;
365}
366
368{
369 return 2;
370}
371
373{
374 return 1;
375}
376
378{
380 *hwnd = (HWND)0xdeadbeef;
381 return S_OK;
382}
383
384static const IOleWindowVtbl OleWindowVtbl = {
389 /* not needed */
390};
391
393
395{
397 *ppv = iface;
398 else if (IsEqualGUID(riid, &IID_IOleWindow))
400 else
401 {
402 *ppv = NULL;
403 return E_NOINTERFACE;
404 }
405
406 IUnknown_AddRef((IUnknown*)*ppv);
407 return S_OK;
408}
409
411{
412 return 2;
413}
414
416{
417 return 1;
418}
419
420static const IOleClientSiteVtbl OleClientSiteVtbl = {
424 /* we don't need the rest, we never call it */
425};
426
428
429typedef struct {
434
436{
437 return CONTAINING_RECORD(iface, StubBufferWrapper, IRpcStubBuffer_iface);
438}
439
441{
443
444 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IRpcStubBuffer, riid)) {
445 *ppv = &This->IRpcStubBuffer_iface;
446 }else {
447 *ppv = NULL;
448 return E_NOINTERFACE;
449 }
450
451 IUnknown_AddRef((IUnknown*)*ppv);
452 return S_OK;
453}
454
456{
458 return InterlockedIncrement(&This->ref);
459}
460
462{
465 if(!ref) {
466 IRpcStubBuffer_Release(This->buffer);
467 free(This);
468 }
469 return ref;
470}
471
473{
474 ok(0, "unexpected call\n");
475 return E_NOTIMPL;
476}
477
479{
481}
482
483static HRESULT WINAPI RpcStubBuffer_Invoke(IRpcStubBuffer *iface, RPCOLEMESSAGE *_prpcmsg,
484 IRpcChannelBuffer *_pRpcChannelBuffer)
485{
487 void *dest_context_data;
488 DWORD dest_context;
489 HRESULT hr;
490
491 CHECK_EXPECT(Invoke);
492
493 hr = IRpcChannelBuffer_GetDestCtx(_pRpcChannelBuffer, &dest_context, &dest_context_data);
494 ok(hr == S_OK, "GetDestCtx failed: %08lx\n", hr);
495 ok(dest_context == MSHCTX_INPROC, "desc_context = %lx\n", dest_context);
496 ok(!dest_context_data, "desc_context_data = %p\n", dest_context_data);
497
498 return IRpcStubBuffer_Invoke(This->buffer, _prpcmsg, _pRpcChannelBuffer);
499}
500
502{
503 ok(0, "unexpected call\n");
504 return NULL;
505}
506
508{
509 ok(0, "unexpected call\n");
510 return E_NOTIMPL;
511}
512
514{
515 ok(0, "unexpected call\n");
516 return E_NOTIMPL;
517}
518
520{
521 ok(0, "unexpected call\n");
522}
523
524static const IRpcStubBufferVtbl RpcStubBufferVtbl = {
535};
536
537typedef struct {
542
544{
545 return CONTAINING_RECORD(iface, ProxyBufferWrapper, IRpcProxyBuffer_iface);
546}
547
549{
551
552 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IRpcProxyBuffer, riid)) {
553 *ppv = &This->IRpcProxyBuffer_iface;
554 }else {
555 *ppv = NULL;
556 return E_NOINTERFACE;
557 }
558
559 IUnknown_AddRef((IUnknown*)*ppv);
560 return S_OK;
561}
562
564{
566 return InterlockedIncrement(&This->ref);
567}
568
570{
573 if(!ref) {
574 IRpcProxyBuffer_Release(This->buffer);
575 free(This);
576 }
577 return ref;
578}
579
581{
583 void *dest_context_data;
584 DWORD dest_context;
585 HRESULT hr;
586
588
589 hr = IRpcChannelBuffer_GetDestCtx(pRpcChannelBuffer, &dest_context, &dest_context_data);
590 ok(hr == S_OK, "GetDestCtx failed: %08lx\n", hr);
591 ok(dest_context == MSHCTX_INPROC, "desc_context = %lx\n", dest_context);
592 ok(!dest_context_data, "desc_context_data = %p\n", dest_context_data);
593
594 return IRpcProxyBuffer_Connect(This->buffer, pRpcChannelBuffer);
595}
596
598{
600}
601
602static const IRpcProxyBufferVtbl RpcProxyBufferVtbl = {
608};
609
611
613{
614 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPSFactoryBuffer))
615 *ppv = iface;
616 else
617 {
618 *ppv = NULL;
619 return E_NOINTERFACE;
620 }
621 IUnknown_AddRef((IUnknown*)*ppv);
622 return S_OK;
623}
624
626{
627 return 2;
628}
629
631{
632 return 1;
633}
634
636 REFIID riid, IRpcProxyBuffer **ppProxy, void **ppv)
637{
639 HRESULT hr;
640
641 CHECK_EXPECT(CreateProxy);
642 proxy = malloc(sizeof(*proxy));
643 proxy->IRpcProxyBuffer_iface.lpVtbl = &RpcProxyBufferVtbl;
644 proxy->ref = 1;
645
646 hr = IPSFactoryBuffer_CreateProxy(ps_factory_buffer, outer, riid, &proxy->buffer, ppv);
647 ok(hr == S_OK, "CreateProxy failed: %08lx\n", hr);
648
649 *ppProxy = &proxy->IRpcProxyBuffer_iface;
650
651 return S_OK;
652}
653
655 IUnknown *server, IRpcStubBuffer **ppStub)
656{
658 HRESULT hr;
659
660 CHECK_EXPECT(CreateStub);
661
662 ok(server == (IUnknown*)&Test_OleClientSite, "unexpected server %p\n", server);
663
664 stub = malloc(sizeof(*stub));
665 stub->IRpcStubBuffer_iface.lpVtbl = &RpcStubBufferVtbl;
666 stub->ref = 1;
667
668 hr = IPSFactoryBuffer_CreateStub(ps_factory_buffer, riid, server, &stub->buffer);
669 ok(hr == S_OK, "CreateStub failed: %08lx\n", hr);
670
671 *ppStub = &stub->IRpcStubBuffer_iface;
672 return S_OK;
673}
674
675static IPSFactoryBufferVtbl PSFactoryBufferVtbl =
676{
682};
683
685
686#define RELEASEMARSHALDATA WM_USER
687
689{
691 const IID *iid;
693 MSHLFLAGS marshal_flags;
698};
699
701
703{
704 struct host_object_data *data = p;
705 DWORD registration_key;
706 HRESULT hr;
707 MSG msg;
708
710
711 if(data->register_object) {
712 hr = CoRegisterClassObject(data->register_clsid, data->register_object,
713 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &registration_key);
714 ok(hr == S_OK, "CoRegisterClassObject failed: %08lx\n", hr);
715 }
716
717 if (data->filter)
718 {
719 IMessageFilter * prev_filter = NULL;
720 hr = CoRegisterMessageFilter(data->filter, &prev_filter);
721 if (prev_filter) IMessageFilter_Release(prev_filter);
723 }
724
725 hr = CoMarshalInterface(data->stream, data->iid, data->object, MSHCTX_INPROC, NULL, data->marshal_flags);
727
728 /* force the message queue to be created before signaling parent thread */
730
731 SetEvent(data->marshal_event);
732
733 while (GetMessageA(&msg, NULL, 0, 0))
734 {
735 if (msg.hwnd == NULL && msg.message == RELEASEMARSHALDATA)
736 {
737 CoReleaseMarshalData(data->stream);
738 SetEvent((HANDLE)msg.lParam);
739 }
740 else
742 }
743
744 free(data);
745
747
748 return hr;
749}
750
752{
753 DWORD tid = 0;
754 struct host_object_data *data;
755
756 data = malloc(sizeof(*data));
757 *data = *object_data;
760
761 /* wait for marshaling to complete before returning */
762 ok( !WaitForSingleObject(data->marshal_event, 10000), "wait timed out\n" );
763 CloseHandle(data->marshal_event);
764
765 return tid;
766}
767
769{
770 struct host_object_data object_data = { stream, riid, object, marshal_flags };
771 return start_host_object2(&object_data, thread);
772}
773
774/* asks thread to release the marshal data because it has to be done by the
775 * same thread that marshaled the interface in the first place. */
777{
780 ok( !WaitForSingleObject(event, 10000), "wait timed out\n" );
782}
783
785{
787 ok(ret, "PostThreadMessage failed with error %ld\n", GetLastError());
788 /* be careful of races - don't return until hosting thread has terminated */
789 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
791}
792
793/* tests failure case of interface not having a marshaler specified in the
794 * registry */
795static void test_no_marshaler(void)
796{
797 IStream *pStream;
798 HRESULT hr;
799
800 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
802 hr = CoMarshalInterface(pStream, &IID_IWineTest, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
803 ok(hr == E_NOINTERFACE, "CoMarshalInterface should have returned E_NOINTERFACE instead of 0x%08lx\n", hr);
804
805 IStream_Release(pStream);
806}
807
808/* tests normal marshal and then release without unmarshaling */
810{
811 HRESULT hr;
812 IStream *pStream = NULL;
813
814 cLocks = 0;
816
817 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
819 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
821
824
825 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
826 hr = CoReleaseMarshalData(pStream);
828 IStream_Release(pStream);
829
830 ok_no_locks();
833}
834
835/* tests success case of a same-thread marshal and unmarshal */
837{
838 HRESULT hr;
839 IStream *pStream = NULL;
840 IUnknown *pProxy = NULL;
841
842 cLocks = 0;
844
845 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
847 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
849
852
853 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
854 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
856 IStream_Release(pStream);
857
861
862 IUnknown_Release(pProxy);
863
864 ok_no_locks();
865}
866
867/* tests failure case of unmarshaling a freed object */
869{
870 HRESULT hr;
871 IStream *pStream = NULL;
872 IClassFactory *pProxy = NULL;
873 DWORD tid;
874 void * dummy;
876
877 cLocks = 0;
879
880 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
882 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
883
886
887 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
888 hr = CoReleaseMarshalData(pStream);
890
891 ok_no_locks();
894
895 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
896 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
898
899 ok_no_locks();
900
901 if (pProxy)
902 {
903 hr = IClassFactory_CreateInstance(pProxy, NULL, &IID_IUnknown, &dummy);
904 ok(hr == RPC_E_DISCONNECTED, "Remote call should have returned RPC_E_DISCONNECTED, instead of 0x%08lx\n", hr);
905
906 IClassFactory_Release(pProxy);
907 }
908
909 IStream_Release(pStream);
910
912}
913
915{
916 HRESULT hr;
917 IStream *pStream;
918 IUnknown *pProxy;
919 static const LARGE_INTEGER llZero;
920
921 cLocks = 0;
923
924 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
926
927 hr = CoMarshalInterface(pStream, &IID_IUnknown, (IUnknown *)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
929
932
933 hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
934 ok_ole_success(hr, IStream_Seek);
935
936 hr = CoUnmarshalInterface(pStream, &IID_IParseDisplayName, (void **)&pProxy);
937 ok(hr == E_NOINTERFACE, "CoUnmarshalInterface should have returned E_NOINTERFACE instead of 0x%08lx\n", hr);
938
939 ok_no_locks();
942
943 IStream_Release(pStream);
944}
945
946/* tests success case of an interthread marshal */
948{
949 HRESULT hr;
950 IStream *pStream = NULL;
951 IUnknown *pProxy = NULL;
952 DWORD tid;
954
955 cLocks = 0;
957
958 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
960 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
961
964
965 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
966 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
968 IStream_Release(pStream);
969
972
973 IUnknown_Release(pProxy);
974
975 ok_no_locks();
978
980}
981
982/* the number of external references that Wine's proxy manager normally gives
983 * out, so we can test the border case of running out of references */
984#define NORMALEXTREFS 5
985
986/* tests success case of an interthread marshal and then marshaling the proxy */
988{
989 HRESULT hr;
990 IStream *pStream = NULL;
991 IUnknown *pProxy = NULL;
992 IUnknown *pProxy2 = NULL;
993 DWORD tid;
995 int i;
996
997 cLocks = 0;
999
1000 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1002 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
1003
1006
1007 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1008 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1010
1012
1013 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1014 /* marshal the proxy */
1015 hr = CoMarshalInterface(pStream, &IID_IClassFactory, pProxy, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1017
1019
1020 /* marshal 5 more times to exhaust the normal external references of 5 */
1021 for (i = 0; i < NORMALEXTREFS; i++)
1022 {
1023 hr = CoMarshalInterface(pStream, &IID_IClassFactory, pProxy, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1025 }
1026
1028
1029 /* release the original proxy to test that we successfully keep the
1030 * original object alive */
1031 IUnknown_Release(pProxy);
1032
1033 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1034 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
1036
1039
1040 IUnknown_Release(pProxy2);
1041
1042 /* unmarshal all of the proxies to check that the object stub still exists */
1043 for (i = 0; i < NORMALEXTREFS; i++)
1044 {
1045 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
1047
1048 IUnknown_Release(pProxy2);
1049 }
1050
1051 ok_no_locks();
1054
1055 IStream_Release(pStream);
1056
1058}
1059
1060/* tests success case of an interthread marshal and then marshaling the proxy
1061 * using an iid that hasn't previously been unmarshaled */
1063{
1064 HRESULT hr;
1065 IStream *pStream = NULL;
1066 IUnknown *pProxy = NULL;
1067 IUnknown *pProxy2 = NULL;
1068 DWORD tid;
1069 HANDLE thread;
1070
1071 cLocks = 0;
1073
1074 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1076 tid = start_host_object(pStream, &IID_IUnknown, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
1077
1080
1081 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1082 hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
1084
1086
1087 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1088 /* marshal the proxy */
1089 hr = CoMarshalInterface(pStream, &IID_IClassFactory, pProxy, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1091
1093
1094 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1095 /* unmarshal the second proxy to the object */
1096 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
1098 IStream_Release(pStream);
1099
1100 /* now the proxies should be as follows:
1101 * pProxy -> &Test_ClassFactory
1102 * pProxy2 -> &Test_ClassFactory
1103 * they should NOT be as follows:
1104 * pProxy -> &Test_ClassFactory
1105 * pProxy2 -> pProxy
1106 * the above can only really be tested by looking in +ole traces
1107 */
1108
1110
1111 IUnknown_Release(pProxy);
1112
1115
1116 IUnknown_Release(pProxy2);
1117
1118 ok_no_locks();
1121
1123}
1124
1125/* tests success case of an interthread marshal and then table-weak-marshaling the proxy */
1127{
1128 HRESULT hr;
1129 IStream *pStream = NULL;
1130 IUnknown *pProxy = NULL;
1131 IUnknown *pProxy2 = NULL;
1132 DWORD tid;
1133 HANDLE thread;
1134
1135 cLocks = 0;
1137
1138 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1140 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
1141
1144
1145 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1146 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1148
1151
1152 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1153 /* marshal the proxy */
1154 hr = CoMarshalInterface(pStream, &IID_IClassFactory, pProxy, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLEWEAK);
1156
1159
1160 /* release the original proxy to test that we successfully keep the
1161 * original object alive */
1162 IUnknown_Release(pProxy);
1163
1164 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1165 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
1166 todo_wine
1167 ok(hr == CO_E_OBJNOTREG, "CoUnmarshalInterface should return CO_E_OBJNOTREG instead of 0x%08lx\n", hr);
1168
1169 ok_no_locks();
1172
1173 IStream_Release(pStream);
1174
1176}
1177
1178/* tests success case of an interthread marshal and then table-strong-marshaling the proxy */
1180{
1181 HRESULT hr;
1182 IStream *pStream = NULL;
1183 IUnknown *pProxy = NULL;
1184 IUnknown *pProxy2 = NULL;
1185 DWORD tid;
1186 HANDLE thread;
1187
1188 cLocks = 0;
1190
1191 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1193 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
1194
1197
1198 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1199 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1201
1204
1205 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1206 /* marshal the proxy */
1207 hr = CoMarshalInterface(pStream, &IID_IClassFactory, pProxy, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG);
1208 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1209
1212
1213 /* release the original proxy to test that we successfully keep the
1214 * original object alive */
1215 IUnknown_Release(pProxy);
1216
1217 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1218 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
1220
1223
1224 IUnknown_Release(pProxy2);
1225
1228
1229 IStream_Release(pStream);
1230
1232
1233 ok_no_locks();
1234todo_wine {
1237}
1238}
1239
1240/* tests that stubs are released when the containing apartment is destroyed */
1242{
1243 HRESULT hr;
1244 IStream *pStream = NULL;
1245 IUnknown *pProxy = NULL;
1246 DWORD tid;
1247 HANDLE thread;
1248
1249 cLocks = 0;
1251
1252 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1254 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
1255
1258
1259 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1260 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1262 IStream_Release(pStream);
1263
1266
1268
1269 ok_no_locks();
1270todo_wine {
1273}
1274
1275 IUnknown_Release(pProxy);
1276
1277 ok_no_locks();
1278}
1279
1280/* tests that proxies are released when the containing apartment is destroyed */
1282{
1283 HRESULT hr;
1284 IStream *pStream = NULL;
1286 IUnknown *unk;
1287 ULONG ref;
1288 DWORD tid;
1289 HANDLE thread;
1290
1291 cLocks = 0;
1293
1294 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1296 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
1297
1300
1301 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1302 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&proxy);
1304 IStream_Release(pStream);
1305
1308
1310
1311 ok_no_locks();
1314
1315 hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IUnknown, (void **)&unk);
1316 ok(hr == CO_E_OBJNOTCONNECTED, "got %#lx\n", hr);
1317
1318 ref = IClassFactory_Release(proxy);
1319 ok(!ref, "got %ld refs\n", ref);
1320
1321 ok_no_locks();
1322
1324
1326}
1327
1328/* tests that proxies are released when the containing mta apartment is destroyed */
1330{
1331 HRESULT hr;
1332 IStream *pStream = NULL;
1333 IUnknown *pProxy = NULL;
1334 DWORD tid;
1335 HANDLE thread;
1336
1339
1340 cLocks = 0;
1342
1343 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1345 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
1346
1349
1350 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1351 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1353 IStream_Release(pStream);
1354
1357
1359
1360 ok_no_locks();
1363
1364 IUnknown_Release(pProxy);
1365
1366 ok_no_locks();
1367
1369
1371}
1372
1374{
1375 DWORD registration_key;
1376 IUnknown *proxy = NULL;
1377 IOleWindow *ole_window;
1378 HWND hwnd;
1379 CLSID clsid;
1380 DWORD tid;
1381 HANDLE thread;
1382 HRESULT hr;
1383
1385 MSHLFLAGS_NORMAL, NULL, (IUnknown*)&PSFactoryBuffer,
1387
1388 cLocks = 0;
1390
1392 ok_ole_success(hr, "CoGetPSClsid");
1393
1394 hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer,
1395 (void **)&ps_factory_buffer);
1396 ok_ole_success(hr, "CoGetClassObject");
1397
1398 hr = CreateStreamOnHGlobal(NULL, TRUE, &object_data.stream);
1400 tid = start_host_object2(&object_data, &thread);
1401
1402 IStream_Seek(object_data.stream, ullZero, STREAM_SEEK_SET, NULL);
1403 hr = CoUnmarshalInterface(object_data.stream, &IID_IUnknown, (void **)&proxy);
1405 IStream_Release(object_data.stream);
1406
1408 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &registration_key);
1409 ok(hr == S_OK, "CoRegisterClassObject failed: %08lx\n", hr);
1410
1412 ok(hr == S_OK, "CoRegisterPSClsid failed: %08lx\n", hr);
1413
1414 SET_EXPECT(CreateStub);
1415 SET_EXPECT(CreateProxy);
1417 hr = IUnknown_QueryInterface(proxy, &IID_IOleWindow, (void**)&ole_window);
1418 ok(hr == S_OK, "Could not get IOleWindow iface: %08lx\n", hr);
1419 CHECK_CALLED(CreateStub);
1420 CHECK_CALLED(CreateProxy);
1422
1423 SET_EXPECT(Invoke);
1425 hr = IOleWindow_GetWindow(ole_window, &hwnd);
1426 ok(hr == S_OK, "GetWindow failed: %08lx\n", hr);
1427 ok((DWORD)(DWORD_PTR)hwnd == 0xdeadbeef, "hwnd = %p\n", hwnd);
1428 CHECK_CALLED(Invoke);
1430
1431 IOleWindow_Release(ole_window);
1432
1435 IUnknown_Release(proxy);
1436 todo_wine
1438 todo_wine
1440
1441 hr = CoRevokeClassObject(registration_key);
1442 ok(hr == S_OK, "CoRevokeClassObject failed: %08lx\n", hr);
1443
1445}
1446
1451
1453{
1454 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMarshal)) {
1455 *ppv = iface;
1456 }
1457 else
1458 {
1459 *ppv = NULL;
1460 return E_NOINTERFACE;
1461 }
1462 IUnknown_AddRef((IUnknown*)*ppv);
1463 return S_OK;
1464}
1465
1467{
1468 return 2;
1469}
1470
1472{
1473 return 1;
1474}
1475
1477 void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *clsid)
1478{
1481 return S_OK;
1482}
1483
1485 void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *size)
1486{
1488 ok(size != NULL, "size = NULL\n");
1489
1490 *size = 0;
1491 return S_OK;
1492}
1493
1495 REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
1496{
1497 IMarshal *std_marshal;
1498 STATSTG stat;
1499 HRESULT hr;
1500
1502
1504 return S_OK;
1505
1506 hr = IStream_Stat(stream, &stat, STATFLAG_DEFAULT);
1507 ok_ole_success(hr, IStream_Stat);
1508 ok(stat.cbSize.LowPart == 0, "stream is not empty (%ld)\n", stat.cbSize.LowPart);
1509 ok(stat.cbSize.HighPart == 0, "stream is not empty (%ld)\n", stat.cbSize.HighPart);
1510
1512 dwDestContext, NULL, mshlflags, &std_marshal);
1514 hr = IMarshal_MarshalInterface(std_marshal, stream, riid, pv,
1515 dwDestContext, pvDestContext, mshlflags);
1516 ok_ole_success(hr, IMarshal_MarshalInterface);
1517 IMarshal_Release(std_marshal);
1518
1519 return S_OK;
1520}
1521
1523 IStream *stream, REFIID riid, void **ppv)
1524{
1525 ok(0, "unexpected call\n");
1526 return E_NOTIMPL;
1527}
1528
1530{
1531 ok(0, "unexpected call\n");
1532 return E_NOTIMPL;
1533}
1534
1536{
1537 ok(0, "unexpected call\n");
1538 return E_NOTIMPL;
1539}
1540
1541static IMarshalVtbl CustomMarshalVtbl =
1542{
1552};
1553
1555
1557{
1558 IStream *stream;
1559 IUnknown *unk;
1560 DWORD size;
1561 HRESULT hr;
1562
1565
1570 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1574
1575 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1576 ok_ole_success(hr, IStream_Seek);
1577 hr = CoUnmarshalInterface(stream, &IID_IUnknown, (void**)&unk);
1579 ok(unk == (IUnknown*)&CustomMarshal, "unk != &CustomMarshal\n");
1580 IUnknown_Release(unk);
1581 IStream_Release(stream);
1582
1585
1589 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1593
1594 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1595 ok_ole_success(hr, IStream_Seek);
1598 IStream_Release(stream);
1599
1602 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1605 ok(size == sizeof(OBJREF), "size = %ld, expected %d\n", size, (int)sizeof(OBJREF));
1606}
1607
1609{
1610 DWORD size, read;
1611 IStream *stream;
1612 OBJREF objref;
1613 HRESULT hr;
1614
1617
1623 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1628
1629 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1630 ok_ole_success(hr, IStream_Seek);
1631 size = FIELD_OFFSET(OBJREF, u_objref.u_custom.pData);
1632 hr = IStream_Read(stream, &objref, size, &read);
1633 ok_ole_success(hr, IStream_Read);
1634 ok(read == size, "read = %ld, expected %ld\n", read, size);
1635 ok(objref.signature == OBJREF_SIGNATURE, "objref.signature = %lx\n",
1636 objref.signature);
1637 ok(objref.flags == OBJREF_CUSTOM, "objref.flags = %lx\n", objref.flags);
1638 ok(IsEqualIID(&objref.iid, &IID_IUnknown), "objref.iid = %s\n",
1639 wine_dbgstr_guid(&objref.iid));
1641 "custom.clsid = %s\n", wine_dbgstr_guid(&objref.u_objref.u_custom.clsid));
1642 ok(!objref.u_objref.u_custom.cbExtension, "custom.cbExtension = %ld\n",
1643 objref.u_objref.u_custom.cbExtension);
1644 ok(!objref.u_objref.u_custom.size, "custom.size = %ld\n",
1645 objref.u_objref.u_custom.size);
1646
1647 IStream_Release(stream);
1648
1651 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1654 ok(size == sizeof(OBJREF), "size = %ld, expected %d\n", size, (int)sizeof(OBJREF));
1655}
1656
1658{
1659 DUALSTRINGARRAY *dualstringarr;
1660 STDOBJREF *stdobjref;
1661 OBJREF objref;
1662 IMarshal *marshal;
1663 DWORD size, read;
1664 IStream *stream;
1665 IUnknown *unk;
1666 CLSID clsid;
1667 HRESULT hr;
1668
1671
1673 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL, &marshal);
1675
1676 hr = IMarshal_GetUnmarshalClass(marshal, &IID_IUnknown, &Test_Unknown,
1677 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL, &clsid);
1678 ok_ole_success(hr, IMarshal_GetUnmarshalClass);
1680
1681 hr = IMarshal_GetMarshalSizeMax(marshal, &IID_IUnknown, &Test_Unknown,
1682 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL, &size);
1683 ok_ole_success(hr, IMarshal_GetMarshalSizeMax);
1685 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1687 ok(size == read, "IMarshal_GetMarshalSizeMax size = %ld, expected %ld\n", size, read);
1688
1689 hr = IMarshal_MarshalInterface(marshal, stream, &IID_IUnknown,
1690 &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1691 ok_ole_success(hr, IMarshal_MarshalInterface);
1692
1693 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1694 ok_ole_success(hr, IStream_Seek);
1695 size = FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray);
1696 hr = IStream_Read(stream, &objref, size, &read);
1697 ok_ole_success(hr, IStream_Read);
1698 ok(read == size, "read = %ld, expected %ld\n", read, size);
1699 ok(objref.signature == OBJREF_SIGNATURE, "objref.signature = %lx\n",
1700 objref.signature);
1701 ok(objref.flags == OBJREF_STANDARD, "objref.flags = %lx\n", objref.flags);
1702 ok(IsEqualIID(&objref.iid, &IID_IUnknown), "objref.iid = %s\n",
1703 wine_dbgstr_guid(&objref.iid));
1704 stdobjref = &objref.u_objref.u_standard.std;
1705 ok(stdobjref->flags == 0, "stdobjref.flags = %ld\n", stdobjref->flags);
1706 ok(stdobjref->cPublicRefs == 5, "stdobjref.cPublicRefs = %ld\n",
1707 stdobjref->cPublicRefs);
1708 dualstringarr = &objref.u_objref.u_standard.saResAddr;
1709 ok(dualstringarr->wNumEntries == 0, "dualstringarr.wNumEntries = %d\n",
1710 dualstringarr->wNumEntries);
1711 ok(dualstringarr->wSecurityOffset == 0, "dualstringarr.wSecurityOffset = %d\n",
1712 dualstringarr->wSecurityOffset);
1713
1714 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1715 ok_ole_success(hr, IStream_Seek);
1716 hr = IMarshal_UnmarshalInterface(marshal, stream, &IID_IUnknown, (void**)&unk);
1717 ok_ole_success(hr, IMarshal_UnmarshalInterface);
1718 IUnknown_Release(unk);
1719
1720 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1721 ok_ole_success(hr, IStream_Seek);
1722 hr = IMarshal_MarshalInterface(marshal, stream, &IID_IUnknown,
1723 &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1724 ok_ole_success(hr, IMarshal_MarshalInterface);
1725
1726 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1727 ok_ole_success(hr, IStream_Seek);
1728 hr = IMarshal_ReleaseMarshalData(marshal, stream);
1729 ok_ole_success(hr, IMarshal_ReleaseMarshalData);
1730 IStream_Release(stream);
1731
1732 IMarshal_Release(marshal);
1733}
1735{
1739};
1740
1741/* helper for test_no_couninitialize_server */
1743{
1744 struct ncu_params *ncu_params = p;
1745 HRESULT hr;
1746
1748
1749 hr = CoMarshalInterface(ncu_params->stream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1751
1753
1754 ok( !WaitForSingleObject(ncu_params->unmarshal_event, 10000), "wait timed out\n" );
1755
1756 /* die without calling CoUninitialize */
1757
1758 return 0;
1759}
1760
1761/* tests apartment that an apartment with a stub is released without deadlock
1762 * if the owning thread exits */
1764{
1765 HRESULT hr;
1766 IStream *pStream = NULL;
1767 IUnknown *pProxy = NULL;
1768 DWORD tid;
1769 HANDLE thread;
1770 struct ncu_params ncu_params;
1771
1772 cLocks = 0;
1774
1777
1778 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1780 ncu_params.stream = pStream;
1781
1783
1784 ok( !WaitForSingleObject(ncu_params.marshal_event, 10000), "wait timed out\n" );
1787
1788 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1789 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1791 IStream_Release(pStream);
1792
1795
1797 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1798
1799 ok_no_locks();
1800todo_wine {
1803}
1804
1808
1809 IUnknown_Release(pProxy);
1810
1811 ok_no_locks();
1812}
1813
1814/* STA -> STA call during DLL_THREAD_DETACH */
1816{
1817 struct ncu_params *ncu_params = p;
1818 HRESULT hr;
1819 IUnknown *pProxy = NULL;
1820
1822
1825 IStream_Release(ncu_params->stream);
1826
1828
1829 /* die without calling CoUninitialize */
1830
1831 return 0;
1832}
1833
1834/* tests STA -> STA call during DLL_THREAD_DETACH doesn't deadlock */
1836{
1837 HRESULT hr;
1838 IStream *pStream = NULL;
1839 DWORD tid;
1840 DWORD host_tid;
1841 HANDLE thread;
1842 HANDLE host_thread;
1843 struct ncu_params ncu_params;
1844
1845 cLocks = 0;
1847
1848 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1850 ncu_params.stream = pStream;
1851
1852 /* NOTE: assumes start_host_object uses an STA to host the object, as MTAs
1853 * always deadlock when called from within DllMain */
1854 host_tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown *)&Test_ClassFactory, MSHLFLAGS_NORMAL, &host_thread);
1855 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1856
1859
1861
1862 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1864
1865 ok_no_locks();
1868
1869 end_host_object(host_tid, host_thread);
1870}
1871
1873
1875{
1876 IStream *stream;
1877 HRESULT hr;
1878
1879 cLocks = 0;
1880
1882
1885
1886 hr = CoMarshalInterface(stream, &IID_IUnknown, &TestCrash_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1888
1889 IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1890
1893
1894 ok_no_locks();
1895
1896 hr = CoMarshalInterface(stream, &IID_IUnknown, &TestCrash_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1898
1900
1901 trace("CoUninitialize >>>\n");
1903 trace("CoUninitialize <<<\n");
1904
1905 ok_no_locks();
1906
1907 IStream_Release(stream);
1909 return 0;
1910}
1911
1913{
1914 HANDLE thread;
1915 DWORD tid;
1916
1919 ok(!WaitForSingleObject(thread, 10000), "wait timed out\n");
1921 ok(crash_thread_success, "Crash thread failed\n");
1922}
1923
1924/* tests success case of a same-thread table-weak marshal, unmarshal, unmarshal */
1926{
1927 HRESULT hr;
1928 IStream *pStream = NULL;
1929 IUnknown *pProxy1 = NULL;
1930 IUnknown *pProxy2 = NULL;
1931 DWORD tid;
1932 HANDLE thread;
1933
1934 cLocks = 0;
1936
1937 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1939 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLEWEAK, &thread);
1940
1943
1944 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1945 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
1947
1950
1951 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1952 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
1954
1956
1957 IUnknown_Release(pProxy1);
1959 IUnknown_Release(pProxy2);
1962
1963 /* When IExternalConnection is present COM's lifetime management
1964 * behaviour is altered; the remaining weak ref prevents stub shutdown. */
1966 {
1968 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1970 }
1971
1972 /* Without IExternalConnection this line is shows the difference between weak and strong table marshaling
1973 * weak has cLocks == 0, strong has cLocks > 0. */
1974 ok_no_locks();
1975
1976 IStream_Release(pStream);
1978}
1979
1980/* tests releasing after unmarshaling one object */
1982{
1983 HRESULT hr;
1984 IStream *pStream = NULL;
1985 IUnknown *pProxy1 = NULL;
1986 IUnknown *pProxy2 = NULL;
1987 DWORD tid;
1988 HANDLE thread;
1989
1990 cLocks = 0;
1992
1993 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1995 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLEWEAK, &thread);
1996
1999
2000 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2001 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
2003
2006
2007 /* release the remaining reference on the object by calling
2008 * CoReleaseMarshalData in the hosting thread */
2009 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2011
2014
2015 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2016 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
2018 IStream_Release(pStream);
2019
2022
2023 IUnknown_Release(pProxy1);
2024
2025 if (pProxy2)
2026 {
2028 IUnknown_Release(pProxy2);
2029 }
2030
2031 /* this line is shows the difference between weak and strong table marshaling:
2032 * weak has cLocks == 0
2033 * strong has cLocks > 0 */
2034 ok_no_locks();
2037
2039}
2040
2041/* tests releasing after unmarshaling one object */
2043{
2044 HRESULT hr;
2045 IStream *pStream = NULL;
2046 IUnknown *pProxy = NULL;
2047 DWORD tid;
2048 HANDLE thread;
2049
2050 cLocks = 0;
2052
2053 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2055 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLEWEAK, &thread);
2056
2059
2060 /* release the remaining reference on the object by calling
2061 * CoReleaseMarshalData in the hosting thread */
2062 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2064
2065 ok_no_locks();
2066
2067 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2068 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
2069 todo_wine
2070 {
2071 ok(hr == CO_E_OBJNOTREG,
2072 "CoUnmarshalInterface should have failed with CO_E_OBJNOTREG, but returned 0x%08lx instead\n",
2073 hr);
2074 }
2075 IStream_Release(pStream);
2076
2077 ok_no_locks();
2079
2081}
2082
2084{
2089};
2090
2092{
2093 HRESULT hr;
2094 struct duo_marshal_data *data = p;
2095 HANDLE hQuitEvent = data->hQuitEvent;
2096 MSG msg;
2097
2099
2100 hr = CoMarshalInterface(data->pStream1, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, data->marshal_flags1);
2101 ok_ole_success(hr, "CoMarshalInterface");
2102
2103 hr = CoMarshalInterface(data->pStream2, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, data->marshal_flags2);
2104 ok_ole_success(hr, "CoMarshalInterface");
2105
2106 /* force the message queue to be created before signaling parent thread */
2108
2109 SetEvent(data->hReadyEvent);
2110
2112 {
2113 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
2114 {
2115 if (msg.hwnd == NULL && msg.message == RELEASEMARSHALDATA)
2116 {
2117 CoReleaseMarshalData(msg.wParam == 1 ? data->pStream1 : data->pStream2);
2118 SetEvent((HANDLE)msg.lParam);
2119 }
2120 else
2122 }
2123 }
2125
2127
2128 return 0;
2129}
2130
2131/* tests interaction between table-weak and normal marshalling of an object */
2133{
2134 HRESULT hr;
2135 IUnknown *pProxyWeak = NULL;
2136 IUnknown *pProxyNormal = NULL;
2137 DWORD tid;
2138 HANDLE thread;
2139 struct duo_marshal_data data;
2140
2141 cLocks = 0;
2143
2144 data.hReadyEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2145 data.hQuitEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2146 data.marshal_flags1 = MSHLFLAGS_TABLEWEAK;
2147 data.marshal_flags2 = MSHLFLAGS_NORMAL;
2148 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.pStream1);
2150 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.pStream2);
2152
2154 ok( !WaitForSingleObject(data.hReadyEvent, 10000), "wait timed out\n" );
2155 CloseHandle(data.hReadyEvent);
2156
2159
2160 /* weak */
2161 IStream_Seek(data.pStream1, ullZero, STREAM_SEEK_SET, NULL);
2162 hr = CoUnmarshalInterface(data.pStream1, &IID_IClassFactory, (void **)&pProxyWeak);
2164
2166
2167 /* normal */
2168 IStream_Seek(data.pStream2, ullZero, STREAM_SEEK_SET, NULL);
2169 hr = CoUnmarshalInterface(data.pStream2, &IID_IClassFactory, (void **)&pProxyNormal);
2171
2173
2174 IUnknown_Release(pProxyNormal);
2175
2178
2179 IUnknown_Release(pProxyWeak);
2180
2183
2184 /* When IExternalConnection is present COM's lifetime management
2185 * behaviour is altered; the remaining weak ref prevents stub shutdown. */
2187 {
2189 IStream_Seek(data.pStream1, ullZero, STREAM_SEEK_SET, NULL);
2191 }
2192 ok_no_locks();
2193
2194 IStream_Release(data.pStream1);
2195 IStream_Release(data.pStream2);
2196
2197 SetEvent(data.hQuitEvent);
2198 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
2200}
2201
2203{
2204 HRESULT hr;
2205 DWORD tid;
2206 HANDLE thread;
2207 struct duo_marshal_data data;
2208
2209 cLocks = 0;
2211
2212 data.hReadyEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2213 data.hQuitEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2214 data.marshal_flags1 = MSHLFLAGS_TABLEWEAK;
2215 data.marshal_flags2 = MSHLFLAGS_NORMAL;
2216 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.pStream1);
2218 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.pStream2);
2220
2222 ok( !WaitForSingleObject(data.hReadyEvent, 10000), "wait timed out\n" );
2223 CloseHandle(data.hReadyEvent);
2224
2227
2228 /* release normal - which in the non-external conn case will free the object despite the weak ref. */
2229 IStream_Seek(data.pStream2, ullZero, STREAM_SEEK_SET, NULL);
2231
2234
2236 {
2238 IStream_Seek(data.pStream1, ullZero, STREAM_SEEK_SET, NULL);
2240 }
2241
2242 ok_no_locks();
2243
2244 IStream_Release(data.pStream1);
2245 IStream_Release(data.pStream2);
2246
2247 SetEvent(data.hQuitEvent);
2248 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
2250}
2251
2253{
2254 HRESULT hr;
2255 DWORD tid;
2256 HANDLE thread;
2257 struct duo_marshal_data data;
2258
2259 cLocks = 0;
2261
2262 data.hReadyEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2263 data.hQuitEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2264 data.marshal_flags1 = MSHLFLAGS_TABLEWEAK;
2265 data.marshal_flags2 = MSHLFLAGS_TABLEWEAK;
2266 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.pStream1);
2268 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.pStream2);
2270
2272 ok( !WaitForSingleObject(data.hReadyEvent, 10000), "wait timed out\n" );
2273 CloseHandle(data.hReadyEvent);
2274
2277
2278 /* release one weak ref - the remaining weak ref will keep the obj alive */
2279 IStream_Seek(data.pStream1, ullZero, STREAM_SEEK_SET, NULL);
2281
2283
2284 IStream_Seek(data.pStream2, ullZero, STREAM_SEEK_SET, NULL);
2286
2287 ok_no_locks();
2288
2289 IStream_Release(data.pStream1);
2290 IStream_Release(data.pStream2);
2291
2292 SetEvent(data.hQuitEvent);
2293 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
2295}
2296
2297/* tests success case of a same-thread table-strong marshal, unmarshal, unmarshal */
2299{
2300 HRESULT hr;
2301 IStream *pStream = NULL;
2302 IUnknown *pProxy1 = NULL;
2303 IUnknown *pProxy2 = NULL;
2304 DWORD tid;
2305 HANDLE thread;
2306
2307 cLocks = 0;
2309
2310 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2312 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLESTRONG, &thread);
2313
2316
2317 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2318 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
2320
2322
2323 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2324 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
2326
2328
2329 if (pProxy1) IUnknown_Release(pProxy1);
2330 if (pProxy2) IUnknown_Release(pProxy2);
2331
2332 /* this line is shows the difference between weak and strong table marshaling:
2333 * weak has cLocks == 0
2334 * strong has cLocks > 0 */
2336
2337 /* release the remaining reference on the object by calling
2338 * CoReleaseMarshalData in the hosting thread */
2339 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2341 IStream_Release(pStream);
2342
2343 ok_no_locks();
2346
2348}
2349
2350/* tests CoLockObjectExternal */
2352{
2353 HRESULT hr;
2354 IStream *pStream = NULL;
2355
2356 cLocks = 0;
2358
2359 /* test the stub manager creation aspect of CoLockObjectExternal when the
2360 * object hasn't been marshaled yet */
2362
2365
2367
2368 ok_no_locks();
2371
2372 /* test our empty stub manager being handled correctly in
2373 * CoMarshalInterface */
2375
2376 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2378 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2380
2382
2385
2386 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2387 hr = CoReleaseMarshalData(pStream);
2389 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2390
2394
2396
2400
2402
2403 ok_no_locks();
2406
2407 /* test CoLockObjectExternal releases reference to object with
2408 * fLastUnlockReleases as TRUE and there are only strong references on
2409 * the object */
2411
2414
2416
2417 ok_no_locks();
2420
2421 /* test CoLockObjectExternal doesn't release the last reference to an
2422 * object with fLastUnlockReleases as TRUE and there is a weak reference
2423 * on the object */
2424 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLEWEAK);
2426
2429
2431
2434
2436
2440
2442
2443 ok_no_locks();
2444
2445 IStream_Release(pStream);
2446}
2447
2448/* tests disconnecting stubs */
2449static void test_disconnect_stub(void)
2450{
2451 HRESULT hr;
2452 IStream *pStream = NULL;
2453
2454 cLocks = 0;
2456
2457 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2459 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2461
2463
2465
2468
2469 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2470 hr = CoReleaseMarshalData(pStream);
2472 IStream_Release(pStream);
2473
2476
2478
2479 ok_no_locks();
2481
2483 ok( hr == E_INVALIDARG, "wrong status %lx\n", hr );
2484}
2485
2486/* tests failure case of a same-thread marshal and unmarshal twice */
2488{
2489 HRESULT hr;
2490 IStream *pStream = NULL;
2491 IUnknown *pProxy1 = NULL;
2492 IUnknown *pProxy2 = NULL;
2493
2494 cLocks = 0;
2496
2497 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2499 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2501
2504
2505 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2506 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
2508
2512
2513 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2514 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
2516 "CoUnmarshalInterface should have failed with error CO_E_OBJNOTCONNECTED for double unmarshal, instead of 0x%08lx\n", hr);
2517
2518 IStream_Release(pStream);
2519
2521
2522 IUnknown_Release(pProxy1);
2523
2524 ok_no_locks();
2525}
2526
2527/* tests success case of marshaling and unmarshaling an HRESULT */
2529{
2530 HRESULT hr;
2531 HRESULT hr_marshaled = 0;
2532 IStream *pStream = NULL;
2533 static const HRESULT E_DEADBEEF = 0xdeadbeef;
2534
2535 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2537
2538 hr = CoMarshalHresult(pStream, E_DEADBEEF);
2540
2541 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2542 hr = IStream_Read(pStream, &hr_marshaled, sizeof(HRESULT), NULL);
2543 ok_ole_success(hr, IStream_Read);
2544
2545 ok(hr_marshaled == E_DEADBEEF, "Didn't marshal HRESULT as expected: got value 0x%08lx instead\n", hr_marshaled);
2546
2547 hr_marshaled = 0;
2548 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2549 hr = CoUnmarshalHresult(pStream, &hr_marshaled);
2551
2552 ok(hr_marshaled == E_DEADBEEF, "Didn't marshal HRESULT as expected: got value 0x%08lx instead\n", hr_marshaled);
2553
2554 IStream_Release(pStream);
2555}
2556
2557
2558/* helper for test_proxy_used_in_wrong_thread */
2560{
2561 IClassFactory * cf = p;
2562 HRESULT hr;
2563 IUnknown * proxy = NULL;
2564
2565 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (LPVOID*)&proxy);
2566 todo_wine ok(hr == CO_E_NOTINITIALIZED, "Got hr %#lx.\n", hr);
2567
2568 hr = IClassFactory_QueryInterface(cf, &IID_IMultiQI, (LPVOID *)&proxy);
2569 todo_wine ok(hr == RPC_E_WRONG_THREAD, "Got hr %#lx.\n", hr);
2570 if (SUCCEEDED(hr))
2571 IUnknown_Release(proxy);
2572
2573 hr = IClassFactory_QueryInterface(cf, &IID_IStream, (LPVOID *)&proxy);
2574 todo_wine ok(hr == RPC_E_WRONG_THREAD, "Got hr %#lx.\n", hr);
2575 if (SUCCEEDED(hr))
2576 IUnknown_Release(proxy);
2577
2579
2580 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (LPVOID*)&proxy);
2581 if (proxy) IUnknown_Release(proxy);
2583 "COM should have failed with RPC_E_WRONG_THREAD on using proxy from wrong apartment, but instead returned 0x%08lx\n",
2584 hr);
2585
2586 hr = IClassFactory_QueryInterface(cf, &IID_IStream, (LPVOID *)&proxy);
2587 todo_wine ok(hr == RPC_E_WRONG_THREAD, "Got hr %#lx.\n", hr);
2588
2589 /* now be really bad and release the proxy from the wrong apartment */
2590 IClassFactory_Release(cf);
2591
2593
2594 return 0;
2595}
2596
2597/* tests failure case of a using a proxy in the wrong apartment */
2599{
2600 HRESULT hr;
2601 IStream *pStream = NULL;
2602 IUnknown *pProxy = NULL;
2603 DWORD tid, tid2;
2604 HANDLE thread;
2605 HANDLE host_thread;
2606
2607 cLocks = 0;
2608
2609 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2611 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &host_thread);
2612
2614
2615 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2616 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
2618 IStream_Release(pStream);
2619
2621
2622 /* do a call that will fail, but result in IRemUnknown being used by the proxy */
2623 IUnknown_QueryInterface(pProxy, &IID_IStream, (LPVOID *)&pStream);
2624
2625 /* create a thread that we can misbehave in */
2626 thread = CreateThread(NULL, 0, bad_thread_proc, pProxy, 0, &tid2);
2627
2628 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
2630
2631 ok_no_locks();
2632
2633 end_host_object(tid, host_thread);
2634}
2635
2637{
2638 if (ppvObj == NULL) return E_POINTER;
2639
2640 if (IsEqualGUID(riid, &IID_IUnknown) ||
2642 {
2643 *ppvObj = iface;
2644 IMessageFilter_AddRef(iface);
2645 return S_OK;
2646 }
2647
2648 return E_NOINTERFACE;
2649}
2650
2652{
2653 return 2; /* non-heap object */
2654}
2655
2657{
2658 return 1; /* non-heap object */
2659}
2660
2662 IMessageFilter *iface,
2663 DWORD dwCallType,
2664 HTASK threadIDCaller,
2665 DWORD dwTickCount,
2666 LPINTERFACEINFO lpInterfaceInfo)
2667{
2668 static int callcount = 0;
2669 DWORD ret;
2670 if (winetest_debug > 1) trace("HandleInComingCall()\n");
2671 switch (callcount)
2672 {
2673 case 0:
2674 ret = SERVERCALL_REJECTED;
2675 break;
2676 case 1:
2677 ret = SERVERCALL_RETRYLATER;
2678 break;
2679 default:
2680 ret = SERVERCALL_ISHANDLED;
2681 break;
2682 }
2683 callcount++;
2684 return ret;
2685}
2686
2688 IMessageFilter *iface,
2689 HTASK threadIDCallee,
2690 DWORD dwTickCount,
2691 DWORD dwRejectType)
2692{
2693 if (winetest_debug > 1) trace("RetryRejectedCall()\n");
2694 return 0;
2695}
2696
2698 IMessageFilter *iface,
2699 HTASK threadIDCallee,
2700 DWORD dwTickCount,
2701 DWORD dwPendingType)
2702{
2703 if (winetest_debug > 1) trace("MessagePending()\n");
2704 return PENDINGMSG_WAITNOPROCESS;
2705}
2706
2707static const IMessageFilterVtbl MessageFilter_Vtbl =
2708{
2715};
2716
2718
2719static void test_message_filter(void)
2720{
2721 HRESULT hr;
2723 DWORD tid;
2724 IUnknown *proxy = NULL;
2725 IMessageFilter *prev_filter = NULL;
2726 HANDLE thread;
2727
2729 MSHLFLAGS_NORMAL, &MessageFilter };
2730
2731 cLocks = 0;
2732
2733 hr = CreateStreamOnHGlobal(NULL, TRUE, &object_data.stream);
2735 tid = start_host_object2(&object_data, &thread);
2736
2738
2739 IStream_Seek(object_data.stream, ullZero, STREAM_SEEK_SET, NULL);
2740 hr = CoUnmarshalInterface(object_data.stream, &IID_IClassFactory, (void **)&cf);
2742 IStream_Release(object_data.stream);
2743
2745
2746 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (LPVOID*)&proxy);
2747 ok(hr == RPC_E_CALL_REJECTED, "Call should have returned RPC_E_CALL_REJECTED, but return 0x%08lx instead\n", hr);
2748 if (proxy) IUnknown_Release(proxy);
2749 proxy = NULL;
2750
2751 hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
2753
2754 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (LPVOID*)&proxy);
2755 ok_ole_success(hr, IClassFactory_CreateInstance);
2756
2757 IUnknown_Release(proxy);
2758
2759 IClassFactory_Release(cf);
2760
2761 ok_no_locks();
2762
2764
2765 hr = CoRegisterMessageFilter(prev_filter, NULL);
2767}
2768
2769/* test failure case of trying to unmarshal from bad stream */
2771{
2772 HRESULT hr;
2773 IStream *pStream = NULL;
2774
2775 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2777 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2779
2781
2782 /* try to read beyond end of stream */
2783 hr = CoReleaseMarshalData(pStream);
2784 ok(hr == STG_E_READFAULT, "Should have failed with STG_E_READFAULT, but returned 0x%08lx instead\n", hr);
2785
2786 /* now release for real */
2787 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2788 hr = CoReleaseMarshalData(pStream);
2790
2791 IStream_Release(pStream);
2792}
2793
2794/* tests that proxies implement certain interfaces */
2795static void test_proxy_interfaces(void)
2796{
2797 HRESULT hr;
2798 IStream *pStream = NULL;
2799 IUnknown *pProxy = NULL;
2800 IUnknown *pOtherUnknown = NULL;
2801 DWORD tid;
2802 HANDLE thread;
2803
2804 cLocks = 0;
2805
2806 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2808 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
2809
2811
2812 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2813 hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
2815 IStream_Release(pStream);
2816
2818
2819 hr = IUnknown_QueryInterface(pProxy, &IID_IUnknown, (LPVOID*)&pOtherUnknown);
2820 ok_ole_success(hr, IUnknown_QueryInterface IID_IUnknown);
2821 if (hr == S_OK) IUnknown_Release(pOtherUnknown);
2822
2823 hr = IUnknown_QueryInterface(pProxy, &IID_IClientSecurity, (LPVOID*)&pOtherUnknown);
2824 ok_ole_success(hr, IUnknown_QueryInterface IID_IClientSecurity);
2825 if (hr == S_OK) IUnknown_Release(pOtherUnknown);
2826
2827 hr = IUnknown_QueryInterface(pProxy, &IID_IMultiQI, (LPVOID*)&pOtherUnknown);
2828 ok_ole_success(hr, IUnknown_QueryInterface IID_IMultiQI);
2829 if (hr == S_OK) IUnknown_Release(pOtherUnknown);
2830
2831 hr = IUnknown_QueryInterface(pProxy, &IID_IMarshal, (LPVOID*)&pOtherUnknown);
2832 ok_ole_success(hr, IUnknown_QueryInterface IID_IMarshal);
2833 if (hr == S_OK) IUnknown_Release(pOtherUnknown);
2834
2835 /* IMarshal2 is also supported on NT-based systems, but is pretty much
2836 * useless as it has no more methods over IMarshal that it inherits from. */
2837
2838 IUnknown_Release(pProxy);
2839
2840 ok_no_locks();
2841
2843}
2844
2845typedef struct
2846{
2849} HeapUnknown;
2850
2852{
2853 return CONTAINING_RECORD(iface, HeapUnknown, IUnknown_iface);
2854}
2855
2857{
2859 {
2860 IUnknown_AddRef(iface);
2861 *ppv = iface;
2862 return S_OK;
2863 }
2864 *ppv = NULL;
2865 return E_NOINTERFACE;
2866}
2867
2869{
2871 return InterlockedIncrement((LONG*)&This->refs);
2872}
2873
2875{
2877 ULONG refs = InterlockedDecrement((LONG*)&This->refs);
2878 if (!refs) HeapFree(GetProcessHeap(), 0, This);
2879 return refs;
2880}
2881
2882static const IUnknownVtbl HeapUnknown_Vtbl =
2883{
2887};
2888
2890{
2891 HRESULT hr;
2892 IPSFactoryBuffer *psfb;
2894 LPVOID lpvtbl;
2895 ULONG refs;
2896 CLSID clsid;
2897 HeapUnknown *pUnkOuter = HeapAlloc(GetProcessHeap(), 0, sizeof(*pUnkOuter));
2898
2899 pUnkOuter->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl;
2900 pUnkOuter->refs = 1;
2901
2904
2905 hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (LPVOID*)&psfb);
2907
2908 hr = IPSFactoryBuffer_CreateProxy(psfb, &pUnkOuter->IUnknown_iface, riid, &proxy, &lpvtbl);
2909 ok_ole_success(hr, IPSFactoryBuffer_CreateProxy);
2910 ok(lpvtbl != NULL, "IPSFactoryBuffer_CreateProxy succeeded, but returned a NULL vtable!\n");
2911
2912 /* release our reference to the outer unknown object - the PS factory
2913 * buffer will have AddRef's it in the CreateProxy call */
2914 refs = IUnknown_Release(&pUnkOuter->IUnknown_iface);
2915 ok(refs == 1, "Ref count of outer unknown should have been 1 instead of %ld\n", refs);
2916
2917 /* Not checking return, unreliable on native. Maybe it leaks references? */
2918 IPSFactoryBuffer_Release(psfb);
2919
2920 refs = IUnknown_Release((IUnknown *)lpvtbl);
2921 ok(refs == 0, "Ref-count leak of %ld on IRpcProxyBuffer\n", refs);
2922
2923 refs = IRpcProxyBuffer_Release(proxy);
2924 ok(refs == 0, "Ref-count leak of %ld on IRpcProxyBuffer\n", refs);
2925}
2926
2928{
2929 HRESULT hr;
2930 IPSFactoryBuffer *psfb;
2932 ULONG refs;
2933 CLSID clsid;
2934
2935 cLocks = 0;
2936
2939
2940 hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (LPVOID*)&psfb);
2942
2943 hr = IPSFactoryBuffer_CreateStub(psfb, riid, (IUnknown*)&Test_ClassFactory, &stub);
2944 ok_ole_success(hr, IPSFactoryBuffer_CreateStub);
2945
2946 /* Not checking return, unreliable on native. Maybe it leaks references? */
2947 IPSFactoryBuffer_Release(psfb);
2948
2950
2951 IRpcStubBuffer_Disconnect(stub);
2952
2953 ok_no_locks();
2954
2955 refs = IRpcStubBuffer_Release(stub);
2956 ok(refs == 0, "Ref-count leak of %ld on IRpcProxyBuffer\n", refs);
2957}
2958
2960
2962 LPCLASSFACTORY iface,
2963 LPUNKNOWN pUnkOuter,
2964 REFIID riid,
2965 LPVOID *ppvObj)
2966{
2967 DWORD_PTR res;
2969 {
2971 ok(ret, "Timed out sending a message to originating window during RPC call\n");
2972 }
2973 *ppvObj = NULL;
2974 return S_FALSE;
2975}
2976
2977static const IClassFactoryVtbl TestREClassFactory_Vtbl =
2978{
2984};
2985
2987
2989{
2990 switch (msg)
2991 {
2992 case WM_USER:
2993 {
2994 HRESULT hr;
2995 IStream *pStream = NULL;
2998 DWORD tid;
2999 HANDLE thread;
3000
3001 cLocks = 0;
3002
3003 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
3005 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&TestRE_ClassFactory, MSHLFLAGS_NORMAL, &thread);
3006
3008
3009 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
3010 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&proxy);
3012 IStream_Release(pStream);
3013
3015
3016 /* note the use of the magic IID_IWineTest value to tell remote thread
3017 * to try to send a message back to us */
3018 hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IWineTest, (void **)&object);
3019 ok(hr == S_FALSE, "expected S_FALSE, got %ld\n", hr);
3020
3021 IClassFactory_Release(proxy);
3022
3023 ok_no_locks();
3024
3026
3027 PostMessageA(hwnd, WM_QUIT, 0, 0);
3028
3029 return 0;
3030 }
3031 case WM_USER+1:
3032 {
3033 HRESULT hr;
3034 IStream *pStream = NULL;
3037 DWORD tid;
3038 HANDLE thread;
3039
3040 cLocks = 0;
3041
3042 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
3044 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&TestRE_ClassFactory, MSHLFLAGS_NORMAL, &thread);
3045
3047
3048 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
3049 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&proxy);
3051 IStream_Release(pStream);
3052
3054
3055 /* post quit message before a doing a COM call to show that a pending
3056 * WM_QUIT message doesn't stop the call from succeeding */
3057 PostMessageA(hwnd, WM_QUIT, 0, 0);
3058 hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IUnknown, (void **)&object);
3059 ok(hr == S_FALSE, "IClassFactory_CreateInstance returned 0x%08lx, expected S_FALSE\n", hr);
3060
3061 IClassFactory_Release(proxy);
3062
3063 ok_no_locks();
3064
3066
3067 return 0;
3068 }
3069 case WM_USER+2:
3070 {
3071 HRESULT hr;
3072 IStream *pStream = NULL;
3075 DWORD tid;
3076 HANDLE thread;
3077
3078 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
3080 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
3081
3082 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
3083 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&proxy);
3085 IStream_Release(pStream);
3086
3087 /* shows that COM calls executed during the processing of sent
3088 * messages should fail */
3089 hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IUnknown, (void **)&object);
3091 "COM call during processing of sent message should return RPC_E_CANTCALLOUT_ININPUTSYNCCALL instead of 0x%08lx\n", hr);
3092
3093 IClassFactory_Release(proxy);
3094
3096
3097 PostQuitMessage(0);
3098
3099 return 0;
3100 }
3101 default:
3102 return DefWindowProcA(hwnd, msg, wparam, lparam);
3103 }
3104}
3105
3106static void register_test_window(void)
3107{
3108 WNDCLASSA wndclass;
3109
3110 memset(&wndclass, 0, sizeof(wndclass));
3111 wndclass.lpfnWndProc = window_proc;
3112 wndclass.lpszClassName = "WineCOMTest";
3113 RegisterClassA(&wndclass);
3114}
3115
3117{
3118 MSG msg;
3119
3121 ok(hwnd_app != NULL, "Window creation failed\n");
3122
3123 /* start message re-entrancy test */
3125
3126 while (GetMessageA(&msg, NULL, 0, 0))
3127 {
3130 }
3132}
3133
3135 LPCLASSFACTORY iface,
3136 LPUNKNOWN pUnkOuter,
3137 REFIID riid,
3138 LPVOID *ppvObj)
3139{
3140 *ppvObj = NULL;
3141 SendMessageA(hwnd_app, WM_USER+2, 0, 0);
3142 return S_OK;
3143}
3144
3145static IClassFactoryVtbl TestMsgClassFactory_Vtbl =
3146{
3152};
3153
3155
3156static void test_call_from_message(void)
3157{
3158 MSG msg;
3159 IStream *pStream;
3160 HRESULT hr;
3162 DWORD tid;
3163 HANDLE thread;
3165
3167 ok(hwnd_app != NULL, "Window creation failed\n");
3168
3169 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
3171 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&TestMsg_ClassFactory, MSHLFLAGS_NORMAL, &thread);
3172
3174
3175 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
3176 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&proxy);
3178 IStream_Release(pStream);
3179
3181
3182 /* start message re-entrancy test */
3183 hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IUnknown, (void **)&object);
3184 ok_ole_success(hr, IClassFactory_CreateInstance);
3185
3186 IClassFactory_Release(proxy);
3187
3188 ok_no_locks();
3189
3191
3192 while (GetMessageA(&msg, NULL, 0, 0))
3193 {
3196 }
3198}
3199
3200static void test_WM_QUIT_handling(void)
3201{
3202 MSG msg;
3203
3205 ok(hwnd_app != NULL, "Window creation failed\n");
3206
3207 /* start WM_QUIT handling test */
3208 PostMessageA(hwnd_app, WM_USER+1, 0, 0);
3209
3210 while (GetMessageA(&msg, NULL, 0, 0))
3211 {
3214 }
3215}
3216
3218{
3219 static SIZE_T global_size_alignment = -1;
3220 if (global_size_alignment == -1)
3221 {
3222 void *p = GlobalAlloc(GMEM_FIXED, 1);
3223 global_size_alignment = GlobalSize(p);
3224 GlobalFree(p);
3225 }
3226
3227 return ((size + global_size_alignment - 1) & ~(global_size_alignment - 1));
3228}
3229
3230static void test_freethreadedmarshaldata(IStream *pStream, MSHCTX mshctx, void *ptr, DWORD mshlflags)
3231{
3232 HGLOBAL hglobal;
3233 DWORD size;
3234 char *marshal_data;
3235 HRESULT hr;
3236
3237 hr = GetHGlobalFromStream(pStream, &hglobal);
3239
3240 size = GlobalSize(hglobal);
3241
3242 marshal_data = GlobalLock(hglobal);
3243
3244 if (mshctx == MSHCTX_INPROC)
3245 {
3246 DWORD expected_size = round_global_size(3*sizeof(DWORD) + sizeof(GUID));
3247 ok(size == expected_size, "expected size %lu, got %lu\n", expected_size, size);
3248
3249 ok(*(DWORD *)marshal_data == mshlflags, "expected 0x%lx, but got 0x%lx for mshctx\n", mshlflags, *(DWORD *)marshal_data);
3250 marshal_data += sizeof(DWORD);
3251 ok(*(void **)marshal_data == ptr, "expected %p, but got %p for mshctx\n", ptr, *(void **)marshal_data);
3252 marshal_data += sizeof(void *);
3253 if (sizeof(void*) == 4 && size >= 3*sizeof(DWORD))
3254 {
3255 ok(*(DWORD *)marshal_data == 0, "expected 0x0, but got 0x%lx\n", *(DWORD *)marshal_data);
3256 marshal_data += sizeof(DWORD);
3257 }
3258 if (size >= 3*sizeof(DWORD) + sizeof(GUID) && winetest_debug > 1)
3259 {
3260 trace("got guid data: %s\n", wine_dbgstr_guid((GUID *)marshal_data));
3261 }
3262 }
3263 else
3264 {
3265 ok(size > sizeof(DWORD), "size should have been > sizeof(DWORD), not %ld\n", size);
3266 ok(*(DWORD *)marshal_data == 0x574f454d /* MEOW */,
3267 "marshal data should be filled by standard marshal and start with MEOW signature\n");
3268 }
3269
3270 GlobalUnlock(hglobal);
3271}
3272
3274{
3275 DWORD size, expected_size;
3276 HRESULT hr;
3277 IUnknown *pFTUnknown;
3278 IMarshal *pFTMarshal;
3279 IStream *pStream;
3280 IUnknown *pProxy;
3281 static const LARGE_INTEGER llZero;
3282 CLSID clsid;
3283
3284 cLocks = 0;
3285 hr = CoCreateFreeThreadedMarshaler(NULL, &pFTUnknown);
3287 hr = IUnknown_QueryInterface(pFTUnknown, &IID_IMarshal, (void **)&pFTMarshal);
3288 ok_ole_success(hr, IUnknown_QueryInterface);
3289 IUnknown_Release(pFTUnknown);
3290
3291 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
3293
3294 /* inproc normal marshaling */
3295
3296 size = 0;
3297 expected_size = sizeof(DWORD) /* flags */ + sizeof(UINT64) + sizeof(GUID);
3298 hr = IMarshal_GetMarshalSizeMax(pFTMarshal, &IID_IClassFactory, &Test_ClassFactory, MSHCTX_INPROC,
3299 NULL, MSHLFLAGS_NORMAL, &size);
3300 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3301 ok(size == expected_size, "Unexpected marshal size %lu, expected %lu.\n", size, expected_size);
3302
3303 hr = IMarshal_GetUnmarshalClass(pFTMarshal, &IID_IClassFactory,
3304 &Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL, &clsid);
3305 ok_ole_success(hr, IMarshal_GetUnmarshalClass);
3306 ok(IsEqualIID(&clsid, &CLSID_InProcFreeMarshaler), "clsid = %s\n",
3308
3309 hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory,
3310 &Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
3311 ok_ole_success(hr, IMarshal_MarshalInterface);
3312
3314
3315 test_freethreadedmarshaldata(pStream, MSHCTX_INPROC, &Test_ClassFactory, MSHLFLAGS_NORMAL);
3316
3317 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3318 hr = IMarshal_UnmarshalInterface(pFTMarshal, pStream, &IID_IUnknown, (void **)&pProxy);
3319 ok_ole_success(hr, IMarshal_UnmarshalInterface);
3320
3321 IUnknown_Release(pProxy);
3322
3323 ok_no_locks();
3324
3325 /* inproc table-strong marshaling */
3326
3327 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3328 hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory,
3329 (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, (void *)0xdeadbeef,
3330 MSHLFLAGS_TABLESTRONG);
3331 ok_ole_success(hr, IMarshal_MarshalInterface);
3332
3334
3335 test_freethreadedmarshaldata(pStream, MSHCTX_INPROC, &Test_ClassFactory, MSHLFLAGS_TABLESTRONG);
3336
3337 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3338 hr = IMarshal_UnmarshalInterface(pFTMarshal, pStream, &IID_IUnknown, (void **)&pProxy);
3339 ok_ole_success(hr, IMarshal_UnmarshalInterface);
3340
3341 IUnknown_Release(pProxy);
3342
3344
3345 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3346 hr = IMarshal_ReleaseMarshalData(pFTMarshal, pStream);
3347 ok_ole_success(hr, IMarshal_ReleaseMarshalData);
3348
3349 ok_no_locks();
3350
3351 /* inproc table-weak marshaling */
3352
3353 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3354 hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory,
3355 (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, (void *)0xdeadbeef,
3356 MSHLFLAGS_TABLEWEAK);
3357 ok_ole_success(hr, IMarshal_MarshalInterface);
3358
3359 ok_no_locks();
3360
3361 test_freethreadedmarshaldata(pStream, MSHCTX_INPROC, &Test_ClassFactory, MSHLFLAGS_TABLEWEAK);
3362
3363 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3364 hr = IMarshal_UnmarshalInterface(pFTMarshal, pStream, &IID_IUnknown, (void **)&pProxy);
3365 ok_ole_success(hr, IMarshal_UnmarshalInterface);
3366
3368
3369 IUnknown_Release(pProxy);
3370
3371 ok_no_locks();
3372
3373 /* inproc normal marshaling (for extraordinary cases) */
3374
3375 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3376 hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory,
3377 &Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
3378 ok_ole_success(hr, IMarshal_MarshalInterface);
3379
3381
3382 /* this call shows that DisconnectObject does nothing */
3383 hr = IMarshal_DisconnectObject(pFTMarshal, 0);
3384 ok_ole_success(hr, IMarshal_DisconnectObject);
3385
3387
3388 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3389 hr = IMarshal_ReleaseMarshalData(pFTMarshal, pStream);
3390 ok_ole_success(hr, IMarshal_ReleaseMarshalData);
3391
3392 ok_no_locks();
3393
3394 /* doesn't enforce marshaling rules here and allows us to unmarshal the
3395 * interface, even though it was freed above */
3396 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3397 hr = IMarshal_UnmarshalInterface(pFTMarshal, pStream, &IID_IUnknown, (void **)&pProxy);
3398 ok_ole_success(hr, IMarshal_UnmarshalInterface);
3399
3400 ok_no_locks();
3401
3402 /* local normal marshaling */
3403
3404 hr = IMarshal_GetUnmarshalClass(pFTMarshal, &IID_IClassFactory,
3405 &Test_ClassFactory, MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL, &clsid);
3406 ok_ole_success(hr, IMarshal_GetUnmarshalClass);
3408 "clsid = %s\n", wine_dbgstr_guid(&clsid));
3409
3410 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3411 hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory, &Test_ClassFactory, MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
3412 ok_ole_success(hr, IMarshal_MarshalInterface);
3413
3415
3416 test_freethreadedmarshaldata(pStream, MSHCTX_LOCAL, &Test_ClassFactory, MSHLFLAGS_NORMAL);
3417
3418 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3419 hr = CoReleaseMarshalData(pStream);
3421
3422 ok_no_locks();
3423
3424 IStream_Release(pStream);
3425 IMarshal_Release(pFTMarshal);
3426}
3427
3429{
3430 HRESULT hr;
3431 char buffer[256];
3432 LPOLESTR pszClsid;
3433 HKEY hkey;
3434 DWORD dwDisposition;
3435 DWORD error;
3436
3437 hr = StringFromCLSID(&CLSID_WineTest, &pszClsid);
3438 ok_ole_success(hr, "StringFromCLSID");
3439 strcpy(buffer, "CLSID\\");
3440 WideCharToMultiByte(CP_ACP, 0, pszClsid, -1, buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), NULL, NULL);
3441 CoTaskMemFree(pszClsid);
3442 strcat(buffer, "\\InprocHandler32");
3443 if (Register)
3444 {
3445 error = RegCreateKeyExA(HKEY_CLASSES_ROOT, buffer, 0, NULL, 0, KEY_SET_VALUE, NULL, &hkey, &dwDisposition);
3447 {
3448 skip("Not authorized to modify the Classes key\n");
3449 return E_FAIL;
3450 }
3451 ok(error == ERROR_SUCCESS, "RegCreateKeyEx failed with error %ld\n", error);
3452 if (error != ERROR_SUCCESS) hr = E_FAIL;
3453 error = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const unsigned char *)"\"ole32.dll\"", strlen("\"ole32.dll\"") + 1);
3454 ok(error == ERROR_SUCCESS, "RegSetValueEx failed with error %ld\n", error);
3455 if (error != ERROR_SUCCESS) hr = E_FAIL;
3456 RegCloseKey(hkey);
3457 }
3458 else
3459 {
3461 *strrchr(buffer, '\\') = '\0';
3463 }
3464 return hr;
3465}
3466
3467static void test_inproc_handler(void)
3468{
3469 HRESULT hr;
3471 IUnknown *pObject2;
3472
3474 return;
3475
3476 hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void **)&pObject);
3477 ok_ole_success(hr, "CoCreateInstance");
3478
3479 if (SUCCEEDED(hr))
3480 {
3481 hr = IUnknown_QueryInterface(pObject, &IID_IWineTest, (void **)&pObject2);
3482 ok(hr == E_NOINTERFACE, "IUnknown_QueryInterface on handler for invalid interface returned 0x%08lx instead of E_NOINTERFACE\n", hr);
3483
3484 /* it's a handler as it supports IOleObject */
3485 hr = IUnknown_QueryInterface(pObject, &IID_IOleObject, (void **)&pObject2);
3486 ok_ole_success(hr, "IUnknown_QueryInterface(&IID_IOleObject)");
3487 IUnknown_Release(pObject2);
3488
3489 IUnknown_Release(pObject);
3490 }
3491
3493}
3494
3496 IStdMarshalInfo *iface,
3497 REFIID riid,
3498 LPVOID *ppvObj)
3499{
3500 if (ppvObj == NULL) return E_POINTER;
3501
3502 if (IsEqualGUID(riid, &IID_IUnknown) ||
3503 IsEqualGUID(riid, &IID_IStdMarshalInfo))
3504 {
3505 *ppvObj = iface;
3506 IStdMarshalInfo_AddRef(iface);
3507 return S_OK;
3508 }
3509
3510 return E_NOINTERFACE;
3511}
3512
3514{
3515 LockModule();
3516 return 2; /* non-heap-based object */
3517}
3518
3520{
3521 UnlockModule();
3522 return 1; /* non-heap-based object */
3523}
3524
3526 IStdMarshalInfo *iface,
3527 DWORD dwDestContext,
3528 void *pvDestContext,
3529 CLSID *pClsid)
3530{
3531 *pClsid = CLSID_WineTest;
3532 return S_OK;
3533}
3534
3535static const IStdMarshalInfoVtbl Test_SMI_Vtbl =
3536{
3541};
3542
3544
3546{
3547 HRESULT hr;
3548 IStream *pStream = NULL;
3549 IUnknown *pProxy = NULL;
3551 DWORD tid;
3552 HANDLE thread;
3553 static const LARGE_INTEGER ullZero;
3554
3556 return;
3557 cLocks = 0;
3558
3559 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
3560 ok_ole_success(hr, "CreateStreamOnHGlobal");
3561 tid = start_host_object(pStream, &IID_IUnknown, (IUnknown*)&Test_SMI, MSHLFLAGS_NORMAL, &thread);
3562
3564
3565 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
3566 hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
3567 ok_ole_success(hr, "CoUnmarshalInterface");
3568 IStream_Release(pStream);
3569
3570 if(hr == S_OK)
3571 {
3573
3574 hr = IUnknown_QueryInterface(pProxy, &IID_IWineTest, (void **)&pObject);
3575 ok(hr == E_NOINTERFACE, "IUnknown_QueryInterface with unknown IID should have returned E_NOINTERFACE instead of 0x%08lx\n", hr);
3576
3577 /* it's a handler as it supports IOleObject */
3578 hr = IUnknown_QueryInterface(pProxy, &IID_IOleObject, (void **)&pObject);
3579 todo_wine
3580 ok_ole_success(hr, "IUnknown_QueryInterface(&IID_IOleObject)");
3581 if (SUCCEEDED(hr)) IUnknown_Release(pObject);
3582
3583 IUnknown_Release(pProxy);
3584
3585 ok_no_locks();
3586 }
3587
3590
3591 /* FIXME: test IPersist interface has the same effect as IStdMarshalInfo */
3592}
3593
3594
3595static void test_client_security(void)
3596{
3597 HRESULT hr;
3598 IStream *pStream = NULL;
3599 IClassFactory *pProxy = NULL;
3600 IUnknown *pProxy2 = NULL;
3601 IUnknown *pUnknown1 = NULL;
3602 IUnknown *pUnknown2 = NULL;
3603 IClientSecurity *pCliSec = NULL;
3604 IMarshal *pMarshal;
3605 DWORD tid;
3606 HANDLE thread;
3607 static const LARGE_INTEGER ullZero;
3608 DWORD dwAuthnSvc;
3609 DWORD dwAuthzSvc;
3610 OLECHAR *pServerPrincName;
3611 DWORD dwAuthnLevel;
3612 DWORD dwImpLevel;
3613 void *pAuthInfo;
3614 DWORD dwCapabilities;
3615 void *pv;
3616
3617 cLocks = 0;
3618
3619 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
3620 ok_ole_success(hr, "CreateStreamOnHGlobal");
3621 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
3622
3623 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
3624 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
3625 ok_ole_success(hr, "CoUnmarshalInterface");
3626 IStream_Release(pStream);
3627
3628 hr = IClassFactory_QueryInterface(pProxy, &IID_IUnknown, (LPVOID*)&pUnknown1);
3629 ok_ole_success(hr, "IUnknown_QueryInterface IID_IUnknown");
3630
3631 /* Does not work on Windows 10 19xx+ */
3632 if (SUCCEEDED(IClassFactory_QueryInterface(pProxy, &IID_IRemUnknown, (void **)&pProxy2)))
3633 {
3634 hr = IUnknown_QueryInterface(pProxy2, &IID_IUnknown, (void **)&pUnknown2);
3635 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3636
3637 ok(pUnknown1 == pUnknown2, "both proxy's IUnknowns should be the same - %p, %p\n", pUnknown1, pUnknown2);
3638 IUnknown_Release(pUnknown2);
3639
3640 IUnknown_Release(pProxy2);
3641 }
3642
3643 hr = IClassFactory_QueryInterface(pProxy, &IID_IMarshal, (LPVOID*)&pMarshal);
3644 ok_ole_success(hr, "IUnknown_QueryInterface IID_IMarshal");
3645
3646 hr = IClassFactory_QueryInterface(pProxy, &IID_IClientSecurity, (LPVOID*)&pCliSec);
3647 ok_ole_success(hr, "IUnknown_QueryInterface IID_IClientSecurity");
3648
3649 hr = IClientSecurity_QueryBlanket(pCliSec, (IUnknown *)pProxy, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
3650 todo_wine ok_ole_success(hr, "IClientSecurity_QueryBlanket (all NULLs)");
3651
3652 hr = IClientSecurity_QueryBlanket(pCliSec, (IUnknown *)pMarshal, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
3653 todo_wine ok(hr == E_NOINTERFACE, "IClientSecurity_QueryBlanket with local interface should have returned E_NOINTERFACE instead of 0x%08lx\n", hr);
3654
3655 hr = IClientSecurity_QueryBlanket(pCliSec, (IUnknown *)pProxy, &dwAuthnSvc, &dwAuthzSvc, &pServerPrincName, &dwAuthnLevel, &dwImpLevel, &pAuthInfo, &dwCapabilities);
3656 todo_wine ok_ole_success(hr, "IClientSecurity_QueryBlanket");
3657
3658 hr = IClientSecurity_SetBlanket(pCliSec, (IUnknown *)pProxy, dwAuthnSvc, dwAuthzSvc, pServerPrincName, dwAuthnLevel, RPC_C_IMP_LEVEL_IMPERSONATE, pAuthInfo, dwCapabilities);
3659 todo_wine ok_ole_success(hr, "IClientSecurity_SetBlanket");
3660
3661 hr = IClassFactory_CreateInstance(pProxy, NULL, &IID_IWineTest, &pv);
3662 ok(hr == E_NOINTERFACE, "COM call should have succeeded instead of returning 0x%08lx\n", hr);
3663
3664 hr = IClientSecurity_SetBlanket(pCliSec, (IUnknown *)pMarshal, dwAuthnSvc, dwAuthzSvc, pServerPrincName, dwAuthnLevel, dwImpLevel, pAuthInfo, dwCapabilities);
3665 todo_wine ok(hr == E_NOINTERFACE, "IClientSecurity_SetBlanket with local interface should have returned E_NOINTERFACE instead of 0x%08lx\n", hr);
3666
3667 hr = IClientSecurity_SetBlanket(pCliSec, (IUnknown *)pProxy, 0xdeadbeef, dwAuthzSvc, pServerPrincName, dwAuthnLevel, dwImpLevel, pAuthInfo, dwCapabilities);
3668 todo_wine ok(hr == E_INVALIDARG, "IClientSecurity_SetBlanke with invalid dwAuthnSvc should have returned E_INVALIDARG instead of 0x%08lx\n", hr);
3669
3670 CoTaskMemFree(pServerPrincName);
3671
3672 hr = IClientSecurity_QueryBlanket(pCliSec, pUnknown1, &dwAuthnSvc, &dwAuthzSvc, &pServerPrincName, &dwAuthnLevel, &dwImpLevel, &pAuthInfo, &dwCapabilities);
3673 todo_wine ok_ole_success(hr, "IClientSecurity_QueryBlanket(IUnknown)");
3674
3675 CoTaskMemFree(pServerPrincName);
3676
3677 IClassFactory_Release(pProxy);
3678 IUnknown_Release(pUnknown1);
3679 IMarshal_Release(pMarshal);
3680 IClientSecurity_Release(pCliSec);
3681
3683}
3684
3686
3687static void LockModuleOOP(void)
3688{
3689 InterlockedIncrement(&cLocks); /* for test purposes only */
3691}
3692
3693static void UnlockModuleOOP(void)
3694{
3695 InterlockedDecrement(&cLocks); /* for test purposes only */
3698}
3699
3700static HWND hwnd_app;
3701
3702struct local_server
3703{
3704 IPersist IPersist_iface; /* a nice short interface */
3705};
3706
3708{
3709 *obj = NULL;
3710
3711 if (IsEqualGUID(iid, &IID_IUnknown) ||
3713 *obj = iface;
3714
3715 if (*obj)
3716 {
3717 IPersist_AddRef(iface);
3718 return S_OK;
3719 }
3720 return E_NOINTERFACE;
3721}
3722
3724{
3725 return 2;
3726}
3727
3729{
3730 return 1;
3731}
3732
3734{
3735 HRESULT hr;
3736
3738
3739 /* Test calling CoDisconnectObject within a COM call */
3740 hr = CoDisconnectObject((IUnknown *)iface, 0);
3741 ok(hr == S_OK, "got %08lx\n", hr);
3742
3743 /* Initialize and uninitialize the apartment to show that we
3744 * remain in the autojoined mta */
3746 ok( hr == S_FALSE, "got %08lx\n", hr );
3748
3749 return S_OK;
3750}
3751
3752static const IPersistVtbl local_server_persist_vtbl =
3753{
3758};
3759
3761{
3763};
3764
3766 LPCLASSFACTORY iface,
3767 REFIID riid,
3768 LPVOID *ppvObj)
3769{
3770 if (ppvObj == NULL) return E_POINTER;
3771
3772 if (IsEqualGUID(riid, &IID_IUnknown) ||
3774 {
3775 *ppvObj = iface;
3776 IClassFactory_AddRef(iface);
3777 return S_OK;
3778 }
3779
3780 return E_NOINTERFACE;
3781}
3782
3783static ULONG WINAPI TestOOP_IClassFactory_AddRef(LPCLASSFACTORY iface)
3784{
3785 return 2; /* non-heap-based object */
3786}
3787
3788static ULONG WINAPI TestOOP_IClassFactory_Release(LPCLASSFACTORY iface)
3789{
3790 return 1; /* non-heap-based object */
3791}
3792
3794 LPCLASSFACTORY iface,
3795 LPUNKNOWN pUnkOuter,
3796 REFIID riid,
3797 LPVOID *ppvObj)
3798{
3799 IPersist *persist = &local_server_class.IPersist_iface;
3800 HRESULT hr;
3801 IPersist_AddRef( persist );
3802 hr = IPersist_QueryInterface( persist, riid, ppvObj );
3803 IPersist_Release( persist );
3804 return hr;
3805}
3806
3808 LPCLASSFACTORY iface,
3809 BOOL fLock)
3810{
3811 if (fLock)
3812 LockModuleOOP();
3813 else
3815 return S_OK;
3816}
3817
3818static const IClassFactoryVtbl TestClassFactoryOOP_Vtbl =
3819{
3825};
3826
3828
3830{
3831 DWORD cookie;
3832 HRESULT hr;
3833 HANDLE ready_event;
3834 DWORD wait;
3835 HANDLE handles[2];
3836
3838 ready_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Ready Event");
3839 handles[0] = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Quit Event");
3840 handles[1] = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Repeat Event");
3841
3842again:
3844 CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
3846
3847 SetEvent(ready_event);
3848
3849 do
3850 {
3852 if (wait == WAIT_OBJECT_0+2)
3853 {
3854 MSG msg;
3855
3856 if (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
3857 {
3860 }
3861 }
3862 else if (wait == WAIT_OBJECT_0+1)
3863 {
3866 goto again;
3867 }
3868 }
3869 while (wait == WAIT_OBJECT_0+2);
3870
3871 ok( wait == WAIT_OBJECT_0, "quit event wait timed out\n" );
3874 CloseHandle(handles[0]);
3875 CloseHandle(handles[1]);
3876}
3877
3879{
3880 char **argv;
3881 char cmdline[MAX_PATH];
3882 BOOL ret;
3884 STARTUPINFOA si = { 0 };
3885 si.cb = sizeof(si);
3886
3887 pi.hThread = NULL;
3888 pi.hProcess = NULL;
3890 sprintf(cmdline, "\"%s\" %s %s", argv[0], argv[1], arg);
3891 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
3892 ok(ret, "CreateProcess failed with error: %lu\n", GetLastError());
3894 return pi.hProcess;
3895}
3896
3897/* tests functions commonly used by out of process COM servers */
3898static void test_local_server(void)
3899{
3900 DWORD cookie;
3901 HRESULT hr;
3902 IClassFactory * cf;
3903 IPersist *persist;
3904 DWORD ret;
3906 HANDLE quit_event;
3907 HANDLE ready_event;
3908 HANDLE repeat_event;
3909 CLSID clsid;
3910
3912
3913 cLocks = 0;
3914
3915 /* Start the object suspended */
3917 CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED, &cookie);
3919
3920 /* ... and CoGetClassObject does not find it and fails when it looks for the
3921 * class in the registry */
3922 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER,
3924 todo_wine ok(hr == REGDB_E_CLASSNOTREG, "Got hr %#lx.\n", hr);
3925
3926 /* Resume the object suspended above ... */
3929
3930 /* ... and now it should succeed */
3931 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER,
3934
3935 /* Now check the locking is working */
3936 /* NOTE: we are accessing the class directly, not through a proxy */
3937
3938 ok_no_locks();
3939
3940 hr = IClassFactory_LockServer(cf, TRUE);
3941 ok_ole_success(hr, IClassFactory_LockServer);
3942
3944
3945 IClassFactory_LockServer(cf, FALSE);
3946 ok_ole_success(hr, IClassFactory_LockServer);
3947
3948 ok_no_locks();
3949
3950 IClassFactory_Release(cf);
3951
3952 /* wait for shutdown signal */
3954 ok(ret != WAIT_TIMEOUT, "Server didn't shut down\n");
3955
3956 /* try to connect again after SCM has suspended registered class objects */
3957 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, NULL,
3959 todo_wine ok(hr == CO_E_SERVER_STOPPING || hr == REGDB_E_CLASSNOTREG /* Win10 1709+ */, "Got hr %#lx.\n", hr);
3960
3963
3965
3966 process = create_target_process("-Embedding");
3967 ok(process != NULL, "couldn't start local server process, error was %ld\n", GetLastError());
3968
3969 ready_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Ready Event");
3970 ok( !WaitForSingleObject(ready_event, 10000), "wait timed out\n" );
3971
3972 hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IPersist, (void **)&persist);
3974
3975 IPersist_Release(persist);
3976
3977 hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IPersist, (void **)&persist);
3978 ok(hr == REGDB_E_CLASSNOTREG, "Second CoCreateInstance on REGCLS_SINGLEUSE object should have failed\n");
3979
3980 /* Re-register the class and try calling CoDisconnectObject from within a call to that object */
3981 repeat_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Repeat Event");
3982 SetEvent(repeat_event);
3983 CloseHandle(repeat_event);
3984
3985 ok( !WaitForSingleObject(ready_event, 10000), "wait timed out\n" );
3986 CloseHandle(ready_event);
3987
3988 hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IPersist, (void **)&persist);
3990
3991 /* GetClassID will call CoDisconnectObject */
3992 IPersist_GetClassID(persist, &clsid);
3993 IPersist_Release(persist);
3994
3995 quit_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Quit Event");
3996 SetEvent(quit_event);
3997
3999 CloseHandle(quit_event);
4001}
4002
4004{
4007};
4008
4010{
4011 HRESULT hr;
4012 struct git_params *params = pv;
4014
4015 hr = IGlobalInterfaceTable_GetInterfaceFromGlobal(params->git, params->cookie, &IID_IClassFactory, (void **)&cf);
4016 ok(hr == CO_E_NOTINITIALIZED, "Got hr %#lx.\n", hr);
4017
4019
4020 hr = IGlobalInterfaceTable_GetInterfaceFromGlobal(params->git, params->cookie, &IID_IClassFactory, (void **)&cf);
4021 ok_ole_success(hr, IGlobalInterfaceTable_GetInterfaceFromGlobal);
4022
4023 IClassFactory_Release(cf);
4024
4026
4027 return hr;
4028}
4029
4031{
4032 HRESULT hr;
4034 DWORD cookie;
4035 HANDLE thread;
4036 DWORD tid;
4037 struct git_params params;
4038 DWORD ret;
4041 ULONG ref;
4042
4043 cLocks = 0;
4044
4045 hr = pDllGetClassObject(&CLSID_StdGlobalInterfaceTable, &IID_IClassFactory, (void**)&cf);
4046 ok(hr == S_OK, "got 0x%08lx\n", hr);
4047
4048 hr = IClassFactory_QueryInterface(cf, &IID_IGlobalInterfaceTable, (void**)&object);
4049 ok(hr == E_NOINTERFACE, "got 0x%08lx\n", hr);
4050
4051 IClassFactory_Release(cf);
4052
4053 hr = CoCreateInstance(&CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, &IID_IGlobalInterfaceTable, (void **)&git);
4055
4056 ref = IGlobalInterfaceTable_AddRef(git);
4057 ok(ref == 1, "ref=%ld\n", ref);
4058 ref = IGlobalInterfaceTable_AddRef(git);
4059 ok(ref == 1, "ref=%ld\n", ref);
4060
4061 ref = IGlobalInterfaceTable_Release(git);
4062 ok(ref == 1, "ref=%ld\n", ref);
4063 ref = IGlobalInterfaceTable_Release(git);
4064 ok(ref == 1, "ref=%ld\n", ref);
4065
4066 hr = IGlobalInterfaceTable_RegisterInterfaceInGlobal(git, (IUnknown *)&Test_ClassFactory, &IID_IClassFactory, &cookie);
4067 ok_ole_success(hr, IGlobalInterfaceTable_RegisterInterfaceInGlobal);
4068
4070
4071 params.cookie = cookie;
4072 params.git = git;
4073 /* note: params is on stack so we MUST wait for get_global_interface_proc
4074 * to exit before we can return */
4076
4078 while (ret == WAIT_OBJECT_0 + 1)
4079 {
4080 MSG msg;
4081 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
4084 }
4085
4087
4088 /* test getting interface from global with different iid */
4089 hr = IGlobalInterfaceTable_GetInterfaceFromGlobal(git, cookie, &IID_IUnknown, (void **)&object);
4090 ok_ole_success(hr, IGlobalInterfaceTable_GetInterfaceFromGlobal);
4091 IUnknown_Release(object);
4092
4093 /* test getting interface from global with same iid */
4094 hr = IGlobalInterfaceTable_GetInterfaceFromGlobal(git, cookie, &IID_IClassFactory, (void **)&object);
4095 ok_ole_success(hr, IGlobalInterfaceTable_GetInterfaceFromGlobal);
4096 IUnknown_Release(object);
4097
4098 hr = IGlobalInterfaceTable_RevokeInterfaceFromGlobal(git, cookie);
4099 ok_ole_success(hr, IGlobalInterfaceTable_RevokeInterfaceFromGlobal);
4100
4101 ok_no_locks();
4102
4103 IGlobalInterfaceTable_Release(git);
4104
4105 hr = CoGetClassObject(&CLSID_StdGlobalInterfaceTable, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void **)&cf);
4106 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4107 IClassFactory_Release(cf);
4108}
4109
4110static void test_manualresetevent(void)
4111{
4112 ISynchronizeHandle *sync_handle;
4113 ISynchronize *psync1, *psync2;
4115 IUnknown *punk;
4116 HANDLE handle;
4117 LONG ref;
4118 HRESULT hr;
4119
4120 hr = pDllGetClassObject(&CLSID_ManualResetEvent, &IID_IClassFactory, (void **)&factory);
4121 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4122 IClassFactory_Release(factory);
4123
4124 hr = CoGetClassObject(&CLSID_ManualResetEvent, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void **)&factory);
4125 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4126 IClassFactory_Release(factory);
4127
4128 hr = CoCreateInstance(&CLSID_ManualResetEvent, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&punk);
4129 ok(hr == S_OK, "Got 0x%08lx\n", hr);
4130 ok(!!punk, "Got NULL.\n");
4131 IUnknown_Release(punk);
4132
4133 hr = CoCreateInstance(&CLSID_ManualResetEvent, NULL, CLSCTX_INPROC_SERVER, &IID_ISynchronize, (void**)&psync1);
4134 ok(hr == S_OK, "Got 0x%08lx\n", hr);
4135 ok(!!psync1, "Got NULL.\n");
4136
4137 hr = ISynchronize_Wait(psync1, 0, 5);
4138 ok(hr == RPC_S_CALLPENDING, "Got 0x%08lx\n", hr);
4139
4140 hr = ISynchronize_Reset(psync1);
4141 ok(hr == S_OK, "Got 0x%08lx\n", hr);
4142 hr = ISynchronize_Signal(psync1);
4143 ok(hr == S_OK, "Got 0x%08lx\n", hr);
4144 hr = ISynchronize_Wait(psync1, 0, 5);
4145 ok(hr == S_OK, "Got 0x%08lx\n", hr);
4146 hr = ISynchronize_Wait(psync1, 0, 5);
4147 ok(hr == S_OK, "Got 0x%08lx\n", hr);
4148 hr = ISynchronize_Reset(psync1);
4149 ok(hr == S_OK, "Got 0x%08lx\n", hr);
4150 hr = ISynchronize_Wait(psync1, 0, 5);
4151 ok(hr == RPC_S_CALLPENDING, "Got 0x%08lx\n", hr);
4152
4153 hr = CoCreateInstance(&CLSID_ManualResetEvent, NULL, CLSCTX_INPROC_SERVER, &IID_ISynchronize, (void**)&psync2);
4154 ok(hr == S_OK, "Got 0x%08lx\n", hr);
4155 ok(!!psync2, "Got NULL.\n");
4156 ok(psync1 != psync2, "psync1 == psync2.\n");
4157
4158 hr = ISynchronize_QueryInterface(psync2, &IID_ISynchronizeHandle, (void**)&sync_handle);
4159 ok(hr == S_OK, "QueryInterface(IID_ISynchronizeHandle) failed: %08lx\n", hr);
4160
4161 handle = NULL;
4162 hr = ISynchronizeHandle_GetHandle(sync_handle, &handle);
4163 ok(hr == S_OK, "GetHandle failed: %08lx\n", hr);
4164 ok(handle != NULL && handle != INVALID_HANDLE_VALUE, "handle = %p\n", handle);
4165
4166 ISynchronizeHandle_Release(sync_handle);
4167
4168 hr = ISynchronize_Wait(psync2, 0, 5);
4169 ok(hr == RPC_S_CALLPENDING, "Got 0x%08lx\n", hr);
4170
4171 hr = ISynchronize_Reset(psync1);
4172 ok(hr == S_OK, "Got 0x%08lx\n", hr);
4173 hr = ISynchronize_Reset(psync2);
4174 ok(hr == S_OK, "Got 0x%08lx\n", hr);
4175 hr = ISynchronize_Signal(psync1);
4176 ok(hr == S_OK, "Got 0x%08lx\n", hr);
4177 hr = ISynchronize_Wait(psync2, 0, 5);
4178 ok(hr == RPC_S_CALLPENDING, "Got 0x%08lx\n", hr);
4179
4180 ref = ISynchronize_AddRef(psync1);
4181 ok(ref == 2, "Got ref: %ld\n", ref);
4182 ref = ISynchronize_AddRef(psync1);
4183 ok(ref == 3, "Got ref: %ld\n", ref);
4184 ref = ISynchronize_Release(psync1);
4185 ok(ref == 2, "Got nonzero ref: %ld\n", ref);
4186 ref = ISynchronize_Release(psync2);
4187 ok(!ref, "Got nonzero ref: %ld\n", ref);
4188 ref = ISynchronize_Release(psync1);
4189 ok(ref == 1, "Got nonzero ref: %ld\n", ref);
4190 ref = ISynchronize_Release(psync1);
4191 ok(!ref, "Got nonzero ref: %ld\n", ref);
4192}
4193
4195{
4196 IStream *stream = param;
4198 IUnknown *proxy;
4199 HRESULT hr;
4200
4201 IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
4204
4205 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy);
4206 ok_ole_success(hr, IClassFactory_CreateInstance);
4207
4208 IUnknown_Release(proxy);
4209
4210 /* But if we initialize an STA in this apartment, it becomes the wrong one. */
4212
4213 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy);
4214 ok(hr == RPC_E_WRONG_THREAD, "got %#lx\n", hr);
4215
4217
4220
4221 IClassFactory_Release(cf);
4222
4223 ok_no_locks();
4226 return 0;
4227}
4228
4230{
4232 IUnknown *proxy;
4233 HRESULT hr;
4234
4235 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy);
4236 ok_ole_success(hr, IClassFactory_CreateInstance);
4237
4238 IUnknown_Release(proxy);
4239
4240 /* But if we initialize an STA in this apartment, it becomes the wrong one. */
4242
4243 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy);
4244 ok(hr == RPC_E_WRONG_THREAD, "got %#lx\n", hr);
4245
4247 return 0;
4248}
4249
4251{
4255};
4256
4258{
4260 HRESULT hr;
4261
4263 (IUnknown *)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
4265
4266 SetEvent(data->start);
4267
4268 ok(!WaitForSingleObject(data->stop, 1000), "wait failed\n");
4269 return 0;
4270}
4271
4272static void test_implicit_mta(void)
4273{
4275 HANDLE host_thread, thread;
4277 IUnknown *proxy;
4278 IStream *stream;
4279 HRESULT hr;
4280 DWORD tid;
4281
4282 cLocks = 0;
4284
4286
4287 /* Firstly: we can unmarshal and use an object while in the implicit MTA. */
4290 tid = start_host_object(stream, &IID_IClassFactory, (IUnknown *)&Test_ClassFactory, MSHLFLAGS_NORMAL, &host_thread);
4291
4294
4296 ok(!WaitForSingleObject(thread, 1000), "wait failed\n");
4298
4299 IStream_Release(stream);
4300 end_host_object(tid, host_thread);
4301
4302 /* Secondly: we can unmarshal an object into the real MTA and then use it
4303 * from the implicit MTA. */
4306 tid = start_host_object(stream, &IID_IClassFactory, (IUnknown *)&Test_ClassFactory, MSHLFLAGS_NORMAL, &host_thread);
4307
4310
4311 IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
4314
4316 ok(!WaitForSingleObject(thread, 1000), "wait failed\n");
4318
4319 IClassFactory_Release(cf);
4320 IStream_Release(stream);
4321
4322 ok_no_locks();
4325
4326 end_host_object(tid, host_thread);
4327
4328 /* Thirdly: we can marshal an object from the implicit MTA and then
4329 * unmarshal it into the real one. */
4330 data.start = CreateEventA(NULL, FALSE, FALSE, NULL);
4331 data.stop = CreateEventA(NULL, FALSE, FALSE, NULL);
4332
4333 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.stream);
4335
4337 ok(!WaitForSingleObject(data.start, 1000), "wait failed\n");
4338
4339 IStream_Seek(data.stream, ullZero, STREAM_SEEK_SET, NULL);
4340 hr = CoUnmarshalInterface(data.stream, &IID_IClassFactory, (void **)&cf);
4342
4343 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy);
4344 ok_ole_success(hr, IClassFactory_CreateInstance);
4345
4346 IUnknown_Release(proxy);
4347
4348 SetEvent(data.stop);
4349 ok(!WaitForSingleObject(thread, 1000), "wait failed\n");
4351
4352 IStream_Release(data.stream);
4353
4355}
4356
4358{
4359 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IChannelHook))
4360 {
4361 *ppv = iface;
4362 IChannelHook_AddRef(iface);
4363 return S_OK;
4364 }
4365
4366 *ppv = NULL;
4367 return E_NOINTERFACE;
4368}
4369
4371{
4372 return 2;
4373}
4374
4376{
4377 return 1;
4378}
4379
4380static int method;
4382
4384 IChannelHook *iface,
4385 REFGUID uExtent,
4386 REFIID riid,
4387 ULONG *pDataSize )
4388{
4389 SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
4390
4391 if (winetest_debug > 1) trace("IChannelHook::ClientGetSize(iid %s)\n", debugstr_guid(riid));
4392
4393 if (info->cbSize == sizeof(*info))
4394 {
4395 ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%lx instead of 0x%lx\n", info->dwServerPid, GetCurrentProcessId());
4396 ok(info->iMethod == method, "iMethod was %ld should be %d\n", info->iMethod, method);
4397 ok(!info->pObject, "pObject should be NULL\n");
4398 if (method == 3)
4399 causality = info->uCausality;
4400 else
4401 ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
4402 }
4403
4404 ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
4405
4406 *pDataSize = 1;
4407}
4408
4410 IChannelHook *iface,
4411 REFGUID uExtent,
4412 REFIID riid,
4413 ULONG *pDataSize,
4414 void *pDataBuffer )
4415{
4416 SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
4417
4418 if (winetest_debug > 1) trace("IChannelHook::ClientFillBuffer()\n");
4419
4420 if (info->cbSize == sizeof(*info))
4421 {
4422 ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%lx instead of 0x%lx\n", info->dwServerPid, GetCurrentProcessId());
4423 ok(info->iMethod == method, "iMethod was %ld should be %d\n", info->iMethod, method);
4424 ok(!info->pObject, "pObject should be NULL\n");
4425 ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
4426 }
4427
4428 ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
4429
4430 *(unsigned char *)pDataBuffer = 0xcc;
4431 *pDataSize = 1;
4432}
4433
4435 IChannelHook *iface,
4436 REFGUID uExtent,
4437 REFIID riid,
4438 ULONG cbDataSize,
4439 void *pDataBuffer,
4440 DWORD lDataRep,
4441 HRESULT hrFault )
4442{
4443 SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
4444
4445 if (winetest_debug > 1) trace("IChannelHook::ClientNotify(hr %#lx)\n", hrFault);
4446
4447 if (info->cbSize == sizeof(*info))
4448 {
4449 ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%lx instead of 0x%lx\n", info->dwServerPid, GetCurrentProcessId());
4450 ok(info->iMethod == method, "iMethod was %ld should be %d\n", info->iMethod, method);
4451 todo_wine {
4452 ok(info->pObject != NULL, "pObject shouldn't be NULL\n");
4453 }
4454 ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
4455 }
4456
4457 ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
4458}
4459
4461 IChannelHook *iface,
4462 REFGUID uExtent,
4463 REFIID riid,
4464 ULONG cbDataSize,
4465 void *pDataBuffer,
4466 DWORD lDataRep )
4467{
4468 SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
4469
4470 if (winetest_debug > 1) trace("IChannelHook::ServerNotify()\n");
4471
4472 if (info->cbSize == sizeof(*info))
4473 {
4474 ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%lx instead of 0x%lx\n", info->dwServerPid, GetCurrentProcessId());
4475 ok(info->iMethod == method, "iMethod was %ld should be %d\n", info->iMethod, method);
4476 ok(info->pObject != NULL, "pObject shouldn't be NULL\n");
4477 ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
4478 }
4479
4480 ok(cbDataSize == 1, "cbDataSize should have been 1 instead of %ld\n", cbDataSize);
4481 ok(*(unsigned char *)pDataBuffer == 0xcc, "pDataBuffer should have contained 0xcc instead of 0x%x\n", *(unsigned char *)pDataBuffer);
4482 ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
4483}
4484
4486 IChannelHook *iface,
4487 REFGUID uExtent,
4488 REFIID riid,
4489 HRESULT hrFault,
4490 ULONG *pDataSize )
4491{
4492 SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
4493
4494 if (winetest_debug > 1) trace("IChannelHook::ServerGetSize(iid %s, hr %#lx)\n", debugstr_guid(riid), hrFault);
4495
4496 if (info->cbSize == sizeof(*info))
4497 {
4498 ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%lx instead of 0x%lx\n", info->dwServerPid, GetCurrentProcessId());
4499 ok(info->iMethod == method, "iMethod was %ld should be %d\n", info->iMethod, method);
4500 ok(info->pObject != NULL, "pObject shouldn't be NULL\n");
4501 ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
4502 }
4503
4504 ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
4505 *pDataSize = 0;
4506}
4507
4509 IChannelHook *iface,
4510 REFGUID uExtent,
4511 REFIID riid,
4512 ULONG *pDataSize,
4513 void *pDataBuffer,
4514 HRESULT hrFault )
4515{
4516 ok(0, "TestChannelHook_ServerFillBuffer shouldn't be called\n");
4517}
4518
4519static const IChannelHookVtbl TestChannelHookVtbl =
4520{
4530};
4531
4533
4534static void test_channel_hook(void)
4535{
4537 DWORD tid;
4538 IUnknown *proxy = NULL;
4539 HANDLE thread;
4540 HRESULT hr;
4541
4543 MSHLFLAGS_NORMAL, &MessageFilter };
4544
4547
4550
4551 cLocks = 0;
4552
4553 hr = CreateStreamOnHGlobal(NULL, TRUE, &object_data.stream);
4555 tid = start_host_object2(&object_data, &thread);
4556
4558
4559 IStream_Seek(object_data.stream, ullZero, STREAM_SEEK_SET, NULL);
4560 hr = CoUnmarshalInterface(object_data.stream, &IID_IClassFactory, (void **)&cf);
4562 IStream_Release(object_data.stream);
4563
4565
4566 method = 3;
4567 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (LPVOID*)&proxy);
4568 ok_ole_success(hr, IClassFactory_CreateInstance);
4569
4570 method = 5;
4571 IUnknown_Release(proxy);
4572
4573 IClassFactory_Release(cf);
4574
4575 ok_no_locks();
4576
4578
4581}
4582
4584{
4586 HRESULT hr;
4587
4588 /* Second thread now keeps MTA created on first thread alive. */
4591 (IUnknown *)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
4593
4594 SetEvent(data->start);
4595
4596 ok(!WaitForSingleObject(data->stop, 1000), "wait failed\n");
4598 return 0;
4599}
4600
4602{
4605 IUnknown *proxy;
4606 HANDLE thread;
4607 HRESULT hr;
4608
4610
4611 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.stream);
4613
4614 data.start = CreateEventA(NULL, FALSE, FALSE, NULL);
4615 data.stop = CreateEventA(NULL, FALSE, FALSE, NULL);
4616
4618 ok(!WaitForSingleObject(data.start, 1000), "wait failed\n");
4620
4622
4623 IStream_Seek(data.stream, ullZero, STREAM_SEEK_SET, NULL);
4624 hr = CoUnmarshalInterface(data.stream, &IID_IClassFactory, (void **)&cf);
4626
4627 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy);
4628 ok_ole_success(hr, IClassFactory_CreateInstance);
4629
4630 IUnknown_Release(proxy);
4631 IStream_Release(data.stream);
4632
4633 SetEvent(data.stop);
4634 ok(!WaitForSingleObject(thread, 1000), "wait failed\n");
4636
4638}
4639
4641{
4642 HMODULE hOle32 = GetModuleHandleA("ole32");
4643 int argc;
4644 char **argv;
4645
4646 pDllGetClassObject = (void*)GetProcAddress(hOle32, "DllGetClassObject");
4647
4649 if (argc > 2 && (!strcmp(argv[2], "-Embedding")))
4650 {
4654
4655 return;
4656 }
4657
4659
4663
4665
4666 /* FIXME: test CoCreateInstanceEx */
4667
4668 /* lifecycle management and marshaling tests */
4669 do
4670 {
4696
4698 } while (with_external_conn);
4699
4718
4720
4724
4725 /* must be last test as channel hooks can't be unregistered */
4727
4729}
#define CO_E_NOTINITIALIZED
@ lparam
Definition: SystemMenu.c:31
@ wparam
Definition: SystemMenu.c:30
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
#define stat
Definition: acwin.h:99
#define read
Definition: acwin.h:96
#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 skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define msg(x)
Definition: auth_time.c:54
static HANDLE thread
Definition: service.c:33
const GUID IID_IUnknown
const GUID IID_IClassFactory
#define RegCloseKey(hKey)
Definition: registry.h:49
const CLSID CLSID_ManualResetEvent
const CLSID CLSID_StdMarshal
const CLSID CLSID_InProcFreeMarshaler
const CLSID CLSID_StdGlobalInterfaceTable
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
static LPVOID LPUNKNOWN
Definition: dinput.c:53
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4799
LONG WINAPI RegCreateKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD Reserved, _In_ LPSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_ LPDWORD lpdwDisposition)
Definition: reg.c:1034
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1224
HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
Definition: combase.c:2294
ULONG WINAPI CoAddRefServerProcess(void)
Definition: combase.c:3151
HRESULT WINAPI CoRegisterMessageFilter(IMessageFilter *filter, IMessageFilter **ret_filter)
Definition: combase.c:2220
HRESULT WINAPI StringFromCLSID(REFCLSID clsid, LPOLESTR *str)
Definition: combase.c:1515
HRESULT WINAPI DECLSPEC_HOTPATCH CoRevokeClassObject(DWORD cookie)
Definition: combase.c:3107
HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(REFCLSID rclsid, DWORD clscontext, COSERVERINFO *server_info, REFIID riid, void **obj)
Definition: combase.c:1925
HRESULT WINAPI CoDisconnectObject(IUnknown *object, DWORD reserved)
Definition: combase.c:3190
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(void *reserved, DWORD model)
Definition: combase.c:2803
HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid)
Definition: combase.c:2359
HRESULT WINAPI CoResumeClassObjects(void)
Definition: combase.c:3352
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
HRESULT WINAPI CoRegisterChannelHook(REFGUID guidExtension, IChannelHook *channel_hook)
Definition: combase.c:3274
ULONG WINAPI CoReleaseServerProcess(void)
Definition: combase.c:3169
HRESULT WINAPI CoLockObjectExternal(IUnknown *object, BOOL lock, BOOL last_unlock_releases)
Definition: combase.c:3237
HRESULT WINAPI CoRegisterClassObject(REFCLSID rclsid, IUnknown *object, DWORD clscontext, DWORD flags, DWORD *cookie)
Definition: combase.c:2970
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
HRESULT WINAPI GetHGlobalFromStream(IStream *stream, HGLOBAL *phglobal)
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL delete_on_release, IStream **stream)
HRESULT WINAPI CoCreateFreeThreadedMarshaler(IUnknown *outer, IUnknown **marshaler)
Definition: marshal.c:417
HRESULT WINAPI CoMarshalHresult(IStream *stream, HRESULT hresult)
Definition: marshal.c:123
HRESULT WINAPI CoMarshalInterface(IStream *stream, REFIID riid, IUnknown *unk, DWORD dest_context, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:483
HRESULT WINAPI CoUnmarshalHresult(IStream *stream, HRESULT *phresult)
Definition: marshal.c:131
HRESULT WINAPI CoGetStandardMarshal(REFIID riid, IUnknown *pUnk, DWORD dwDestContext, void *dest_context, DWORD flags, IMarshal **marshal)
Definition: marshal.c:2268
HRESULT WINAPI CoReleaseMarshalData(IStream *stream)
Definition: marshal.c:673
#define NORMALEXTREFS
Definition: marshal.c:45
HRESULT WINAPI CoUnmarshalInterface(IStream *stream, REFIID riid, void **ppv)
Definition: marshal.c:793
HRESULT WINAPI CoGetMarshalSizeMax(ULONG *size, REFIID riid, IUnknown *unk, DWORD dest_context, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:440
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
HANDLE HWND
Definition: compat.h:19
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
WCHAR OLECHAR
Definition: compat.h:2292
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
VOID WINAPI RaiseException(_In_ DWORD dwExceptionCode, _In_ DWORD dwExceptionFlags, _In_ DWORD nNumberOfArguments, _In_opt_ const ULONG_PTR *lpArguments)
Definition: except.c:700
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
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
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(const char *app_name, char *cmd_line, SECURITY_ATTRIBUTES *process_attr, SECURITY_ATTRIBUTES *thread_attr, BOOL inherit, DWORD flags, void *env, const char *cur_dir, STARTUPINFOA *startup_info, PROCESS_INFORMATION *info)
Definition: process.c:686
MonoAssembly int argc
Definition: metahost.c:107
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
_ACRTIMP char *__cdecl strrchr(const char *, int)
Definition: string.c:3298
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:531
method
Definition: dragdrop.c:54
return ret
Definition: mutex.c:146
r reserved
Definition: btrfs.c:3006
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
int proxy
Definition: main.c:67
FxObject * pObject
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct _cl_event * event
Definition: glext.h:7739
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLenum const GLfloat * params
Definition: glext.h:5645
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
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
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
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
static ERESOURCE GlobalLock
Definition: sys_arch.c:8
#define debugstr_guid
Definition: kernel32.h:35
_In_ PKSPIN_CONNECT Connect
Definition: ks.h:4536
#define REG_SZ
Definition: layer.c:22
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
int winetest_debug
#define todo_wine
Definition: minitest.h:80
#define EXCEPTION_ACCESS_VIOLATION
Definition: minwinbase.h:44
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
#define error(str)
Definition: mkdosfs.c:1605
static PVOID ptr
Definition: dispmode.c:27
#define sprintf
Definition: sprintf.c:45
static PROCESS_INFORMATION pi
Definition: debugger.c:2303
static SYSTEM_INFO si
Definition: virtual.c:39
static IUnknown * outer
Definition: compobj.c:82
static HRESULT WINAPI CustomMarshal_QueryInterface(IMarshal *iface, REFIID riid, void **ppv)
Definition: marshal.c:1452
#define ok_more_than_one_lock()
Definition: marshal.c:69
#define SET_EXPECT(func)
Definition: marshal.c:40
static HRESULT WINAPI Test_SMI_GetClassForHandler(IStdMarshalInfo *iface, DWORD dwDestContext, void *pvDestContext, CLSID *pClsid)
Definition: marshal.c:3525
static DWORD CALLBACK duo_marshal_thread_proc(void *p)
Definition: marshal.c:2091
static void test_client_security(void)
Definition: marshal.c:3595
static void UnlockModuleOOP(void)
Definition: marshal.c:3693
static HeapUnknown * impl_from_IUnknown(IUnknown *iface)
Definition: marshal.c:2851
static LONG cLocks
Definition: marshal.c:168
static HRESULT WINAPI CustomMarshal_DisconnectObject(IMarshal *iface, DWORD res)
Definition: marshal.c:1535
static DWORD external_connections
Definition: marshal.c:181
static IPSFactoryBuffer PSFactoryBuffer
Definition: marshal.c:684
static const IOleClientSiteVtbl OleClientSiteVtbl
Definition: marshal.c:420
static void test_tableweak_and_normal_marshal_and_releasedata(void)
Definition: marshal.c:2202
static void test_proxy_marshal_and_unmarshal_strong(void)
Definition: marshal.c:1179
static void test_normal_marshal_and_unmarshal(void)
Definition: marshal.c:836
static void test_interthread_marshal_and_unmarshal(void)
Definition: marshal.c:947
#define OBJREF_CUSTOM
Definition: marshal.c:78
static HRESULT WINAPI OleClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
Definition: marshal.c:394
static void WINAPI TestChannelHook_ClientGetSize(IChannelHook *iface, REFGUID uExtent, REFIID riid, ULONG *pDataSize)
Definition: marshal.c:4383
static ULONG WINAPI TestChannelHook_AddRef(IChannelHook *iface)
Definition: marshal.c:4370
static void test_mta_creation_thread_change_apartment(void)
Definition: marshal.c:4601
static void WINAPI RpcStubBuffer_Disconnect(IRpcStubBuffer *iface)
Definition: marshal.c:478
static void release_host_object(DWORD tid, WPARAM wp)
Definition: marshal.c:776
static void WINAPI RpcProxyBuffer_Disconnect(IRpcProxyBuffer *iface)
Definition: marshal.c:597
static void test_proxy_interfaces(void)
Definition: marshal.c:2795
static void test_proxy_marshal_and_unmarshal(void)
Definition: marshal.c:987
static IMarshal CustomMarshal
Definition: marshal.c:1554
static void WINAPI TestChannelHook_ClientFillBuffer(IChannelHook *iface, REFGUID uExtent, REFIID riid, ULONG *pDataSize, void *pDataBuffer)
Definition: marshal.c:4409
static HRESULT WINAPI RpcProxyBuffer_QueryInterface(IRpcProxyBuffer *iface, REFIID riid, void **ppv)
Definition: marshal.c:548
static void test_tableweak_marshal_and_unmarshal_twice(void)
Definition: marshal.c:1925
static IOleWindow Test_OleWindow
Definition: marshal.c:392
static BOOL last_release_closes
Definition: marshal.c:182
static void test_call_from_message(void)
Definition: marshal.c:3156
static void test_proxy_marshal_and_unmarshal_weak(void)
Definition: marshal.c:1126
static ULONG WINAPI MessageFilter_AddRef(IMessageFilter *iface)
Definition: marshal.c:2651
static HRESULT WINAPI CustomMarshal_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *size)
Definition: marshal.c:1484
static IClassFactory TestMsg_ClassFactory
Definition: marshal.c:3154
static void test_no_marshaler(void)
Definition: marshal.c:795
static IStdMarshalInfo Test_SMI
Definition: marshal.c:3543
static HRESULT WINAPI Test_IUnknown_QueryInterface(LPUNKNOWN iface, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:227
static void test_crash_couninitialize(void)
Definition: marshal.c:1912
static void test_message_filter(void)
Definition: marshal.c:2719
static ULONG WINAPI OleClientSite_Release(IOleClientSite *iface)
Definition: marshal.c:415
static HWND hwnd_app
Definition: marshal.c:2959
static void test_proxy_used_in_wrong_thread(void)
Definition: marshal.c:2598
static const LARGE_INTEGER ullZero
Definition: marshal.c:167
static ULONG WINAPI TestOOP_IClassFactory_Release(LPCLASSFACTORY iface)
Definition: marshal.c:3788
static HRESULT WINAPI RpcProxyBuffer_Connect(IRpcProxyBuffer *iface, IRpcChannelBuffer *pRpcChannelBuffer)
Definition: marshal.c:580
static IChannelHook TestChannelHook
Definition: marshal.c:4532
static void test_implicit_mta(void)
Definition: marshal.c:4272
static void test_freethreadedmarshaldata(IStream *pStream, MSHCTX mshctx, void *ptr, DWORD mshlflags)
Definition: marshal.c:3230
static HRESULT WINAPI CustomMarshal_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *clsid)
Definition: marshal.c:1476
static DWORD CALLBACK bad_thread_proc(LPVOID p)
Definition: marshal.c:2559
static ULONG WINAPI CustomMarshal_Release(IMarshal *iface)
Definition: marshal.c:1471
static HRESULT WINAPI Test_IClassFactory_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:285
static ULONG WINAPI ExternalConnection_Release(IExternalConnection *iface)
Definition: marshal.c:196
static void test_inproc_handler(void)
Definition: marshal.c:3467
static void test_marshal_and_unmarshal_invalid(void)
Definition: marshal.c:868
static void LockModuleOOP(void)
Definition: marshal.c:3687
#define ok_ole_success(hr, func)
Definition: marshal.c:71
static HRESULT WINAPI CustomMarshal_UnmarshalInterface(IMarshal *iface, IStream *stream, REFIID riid, void **ppv)
Definition: marshal.c:1522
struct local_server local_server_class
Definition: marshal.c:3760
static ULONG WINAPI RpcStubBuffer_AddRef(IRpcStubBuffer *iface)
Definition: marshal.c:455
static IClassFactory Test_ClassFactory
Definition: marshal.c:350
static IMarshalVtbl CustomMarshalVtbl
Definition: marshal.c:1541
static ULONG WINAPI Test_SMI_AddRef(IStdMarshalInfo *iface)
Definition: marshal.c:3513
static void test_register_local_server(void)
Definition: marshal.c:3829
static void test_tableweak_marshal_releasedata1(void)
Definition: marshal.c:1981
#define ok_non_zero_external_conn()
Definition: marshal.c:72
static IUnknown Test_Unknown
Definition: marshal.c:264
static const IStdMarshalInfoVtbl Test_SMI_Vtbl
Definition: marshal.c:3535
static void test_freethreadedmarshaler(void)
Definition: marshal.c:3273
static void test_tableweak_and_normal_marshal_and_unmarshal(void)
Definition: marshal.c:2132
#define EXTENTID_WineTest
Definition: marshal.c:137
#define CHECK_EXPECT(func)
Definition: marshal.c:49
static IRpcStubBuffer *WINAPI RpcStubBuffer_IsIIDSupported(IRpcStubBuffer *iface, REFIID riid)
Definition: marshal.c:501
struct tagOBJREF OBJREF
static HRESULT WINAPI RpcStubBuffer_Connect(IRpcStubBuffer *iface, IUnknown *pUnkServer)
Definition: marshal.c:472
static HRESULT reg_unreg_wine_test_class(BOOL Register)
Definition: marshal.c:3428
static ULONG WINAPI Test_IUnknown_Release(LPUNKNOWN iface)
Definition: marshal.c:251
static ProxyBufferWrapper * impl_from_IRpcProxyBuffer(IRpcProxyBuffer *iface)
Definition: marshal.c:543
static const IClassFactoryVtbl TestClassFactoryOOP_Vtbl
Definition: marshal.c:3818
static const IUnknownVtbl TestCrashUnknown_Vtbl
Definition: marshal.c:276
static const IClassFactoryVtbl TestREClassFactory_Vtbl
Definition: marshal.c:2977
static HRESULT WINAPI Test_IClassFactory_LockServer(LPCLASSFACTORY iface, BOOL fLock)
Definition: marshal.c:334
static HANDLE heventShutdown
Definition: marshal.c:3685
static void test_tablestrong_marshal_and_unmarshal_twice(void)
Definition: marshal.c:2298
#define DEFINE_EXPECT(func)
Definition: marshal.c:37
static void test_manualresetevent(void)
Definition: marshal.c:4110
static HRESULT WINAPI Test_IClassFactory_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:324
static DWORD CALLBACK get_global_interface_proc(LPVOID pv)
Definition: marshal.c:4009
static DWORD start_host_object(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, HANDLE *thread)
Definition: marshal.c:768
static void test_normal_marshal_and_unmarshal_twice(void)
Definition: marshal.c:2487
static void end_host_object(DWORD tid, HANDLE thread)
Definition: marshal.c:784
static HRESULT WINAPI TestRE_IClassFactory_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:2961
static void test_cocreateinstance_proxy(void)
Definition: marshal.c:148
static ULONG WINAPI HeapUnknown_AddRef(IUnknown *iface)
Definition: marshal.c:2868
static ULONG WINAPI RpcStubBuffer_Release(IRpcStubBuffer *iface)
Definition: marshal.c:461
static const IID IID_IWineTest
Definition: marshal.c:121
static ULONG WINAPI OleClientSite_AddRef(IOleClientSite *iface)
Definition: marshal.c:410
static DWORD start_host_object2(struct host_object_data *object_data, HANDLE *thread)
Definition: marshal.c:751
static void test_message_reentrancy(void)
Definition: marshal.c:3116
static void test_no_couninitialize_server(void)
Definition: marshal.c:1763
static ULONG WINAPI MessageFilter_Release(IMessageFilter *iface)
Definition: marshal.c:2656
static ULONG WINAPI HeapUnknown_Release(IUnknown *iface)
Definition: marshal.c:2874
static void test_local_server(void)
Definition: marshal.c:3898
static ULONG WINAPI RpcProxyBuffer_Release(IRpcProxyBuffer *iface)
Definition: marshal.c:569
static const CLSID * unmarshal_class
Definition: marshal.c:1447
static HRESULT WINAPI local_server_GetClassID(IPersist *iface, CLSID *clsid)
Definition: marshal.c:3733
static ULONG WINAPI OleWindow_AddRef(IOleWindow *iface)
Definition: marshal.c:367
static ULONG WINAPI PSFactoryBuffer_AddRef(IPSFactoryBuffer *iface)
Definition: marshal.c:625
static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: marshal.c:2988
static HANDLE create_target_process(const char *arg)
Definition: marshal.c:3878
static GUID causality
Definition: marshal.c:4381
static HRESULT WINAPI OleWindow_GetWindow(IOleWindow *iface, HWND *hwnd)
Definition: marshal.c:377
static IOleClientSite Test_OleClientSite
Definition: marshal.c:427
#define RELEASEMARSHALDATA
Definition: marshal.c:686
static const GUID CLSID_WineTestPSFactoryBuffer
Definition: marshal.c:61
static const GUID CLSID_ft_unmarshaler_1809
Definition: marshal.c:63
static DWORD CALLBACK no_couninitialize_client_proc(LPVOID p)
Definition: marshal.c:1815
static SIZE_T round_global_size(SIZE_T size)
Definition: marshal.c:3217
static IClassFactoryVtbl TestMsgClassFactory_Vtbl
Definition: marshal.c:3145
static DWORD WINAPI MessageFilter_RetryRejectedCall(IMessageFilter *iface, HTASK threadIDCallee, DWORD dwTickCount, DWORD dwRejectType)
Definition: marshal.c:2687
static void test_two_tableweak_marshal_and_releasedata(void)
Definition: marshal.c:2252
static StubBufferWrapper * impl_from_IRpcStubBuffer(IRpcStubBuffer *iface)
Definition: marshal.c:435
static HRESULT WINAPI local_server_QueryInterface(IPersist *iface, REFIID iid, void **obj)
Definition: marshal.c:3707
static const IRpcStubBufferVtbl RpcStubBufferVtbl
Definition: marshal.c:524
static ULONG WINAPI Test_SMI_Release(IStdMarshalInfo *iface)
Definition: marshal.c:3519
static HRESULT WINAPI PSFactoryBuffer_CreateStub(IPSFactoryBuffer *iface, REFIID riid, IUnknown *server, IRpcStubBuffer **ppStub)
Definition: marshal.c:654
static HRESULT WINAPI TestOOP_IClassFactory_LockServer(LPCLASSFACTORY iface, BOOL fLock)
Definition: marshal.c:3807
static void test_hresult_marshaling(void)
Definition: marshal.c:2528
static ULONG WINAPI PSFactoryBuffer_Release(IPSFactoryBuffer *iface)
Definition: marshal.c:630
static const IRpcProxyBufferVtbl RpcProxyBufferVtbl
Definition: marshal.c:602
static HRESULT WINAPI PSFactoryBuffer_CreateProxy(IPSFactoryBuffer *iface, IUnknown *outer, REFIID riid, IRpcProxyBuffer **ppProxy, void **ppv)
Definition: marshal.c:635
static void WINAPI RpcStubBuffer_DebugServerRelease(IRpcStubBuffer *iface, void *pv)
Definition: marshal.c:519
static DWORD CALLBACK no_couninitialize_server_proc(LPVOID p)
Definition: marshal.c:1742
static void test_marshal_stub_apartment_shutdown(void)
Definition: marshal.c:1241
struct tagDUALSTRINGARRAY DUALSTRINGARRAY
static IExternalConnection ExternalConnection
Definition: marshal.c:224
static DWORD WINAPI MessageFilter_HandleInComingCall(IMessageFilter *iface, DWORD dwCallType, HTASK threadIDCaller, DWORD dwTickCount, LPINTERFACEINFO lpInterfaceInfo)
Definition: marshal.c:2661
static void test_proxybuffer(REFIID riid)
Definition: marshal.c:2889
static DWORD WINAPI ExternalConnection_ReleaseConnection(IExternalConnection *iface, DWORD extconn, DWORD reserved, BOOL fLastReleaseCloses)
Definition: marshal.c:208
static ULONG WINAPI ExternalConnection_AddRef(IExternalConnection *iface)
Definition: marshal.c:191
static HRESULT WINAPI RpcStubBuffer_QueryInterface(IRpcStubBuffer *iface, REFIID riid, void **ppv)
Definition: marshal.c:440
static void test_globalinterfacetable(void)
Definition: marshal.c:4030
#define CHECK_EXPECT2(func)
Definition: marshal.c:43
static BOOL crash_thread_success
Definition: marshal.c:1872
static void UnlockModule(void)
Definition: marshal.c:175
static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: marshal.c:2856
static HRESULT WINAPI OleWindow_QueryInterface(IOleWindow *iface, REFIID riid, void **ppv)
Definition: marshal.c:360
static HRESULT WINAPI RpcStubBuffer_DebugServerQueryInterface(IRpcStubBuffer *iface, void **ppv)
Definition: marshal.c:513
static HRESULT WINAPI MessageFilter_QueryInterface(IMessageFilter *iface, REFIID riid, void **ppvObj)
Definition: marshal.c:2636
static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
Definition: marshal.c:312
#define ok_no_locks()
Definition: marshal.c:70
static ULONG WINAPI Test_IUnknown_AddRef(LPUNKNOWN iface)
Definition: marshal.c:245
static void WINAPI TestChannelHook_ServerFillBuffer(IChannelHook *iface, REFGUID uExtent, REFIID riid, ULONG *pDataSize, void *pDataBuffer, HRESULT hrFault)
Definition: marshal.c:4508
static void register_test_window(void)
Definition: marshal.c:3106
static HRESULT WINAPI CustomMarshal_ReleaseMarshalData(IMarshal *iface, IStream *stream)
Definition: marshal.c:1529
UINT64 OID
Definition: marshal.c:87
#define ok_zero_external_conn()
Definition: marshal.c:73
static HRESULT WINAPI RpcStubBuffer_Invoke(IRpcStubBuffer *iface, RPCOLEMESSAGE *_prpcmsg, IRpcChannelBuffer *_pRpcChannelBuffer)
Definition: marshal.c:483
static void test_same_apartment_unmarshal_failure(void)
Definition: marshal.c:914
static void test_WM_QUIT_handling(void)
Definition: marshal.c:3200
static HRESULT WINAPI TestChannelHook_QueryInterface(IChannelHook *iface, REFIID riid, void **ppv)
Definition: marshal.c:4357
static void WINAPI TestChannelHook_ServerGetSize(IChannelHook *iface, REFGUID uExtent, REFIID riid, HRESULT hrFault, ULONG *pDataSize)
Definition: marshal.c:4485
static const IMessageFilterVtbl MessageFilter_Vtbl
Definition: marshal.c:2707
static IPSFactoryBuffer * ps_factory_buffer
Definition: marshal.c:610
static void test_CoGetStandardMarshal(void)
Definition: marshal.c:1657
static const IChannelHookVtbl TestChannelHookVtbl
Definition: marshal.c:4519
#define CHECK_CALLED(func)
Definition: marshal.c:55
#define ok_last_release_closes(b)
Definition: marshal.c:74
static HRESULT WINAPI TestOOP_IClassFactory_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:3793
static HRESULT WINAPI ExternalConnection_QueryInterface(IExternalConnection *iface, REFIID riid, void **ppv)
Definition: marshal.c:184
static DWORD CALLBACK implicit_mta_use_proc(void *param)
Definition: marshal.c:4229
static void test_DfMarshal_custom_marshaling(void)
Definition: marshal.c:1608
static const CLSID CLSID_WineOOPTest
Definition: marshal.c:140
static ULONG WINAPI OleWindow_Release(IOleWindow *iface)
Definition: marshal.c:372
static void test_stubbuffer(REFIID riid)
Definition: marshal.c:2927
static ULONG WINAPI CustomMarshal_AddRef(IMarshal *iface)
Definition: marshal.c:1466
static LPVOID
Definition: marshal.c:66
static IUnknown TestCrash_Unknown
Definition: marshal.c:283
static DWORD CALLBACK implicit_mta_unmarshal_proc(void *param)
Definition: marshal.c:4194
#define OBJREF_SIGNATURE
Definition: marshal.c:76
static void test_tableweak_marshal_releasedata2(void)
Definition: marshal.c:2042
static IPSFactoryBufferVtbl PSFactoryBufferVtbl
Definition: marshal.c:675
static DWORD CALLBACK host_object_proc(LPVOID p)
Definition: marshal.c:702
static const IID IID_IRemUnknown
Definition: marshal.c:129
static void test_proxy_marshal_and_unmarshal2(void)
Definition: marshal.c:1062
static void test_channel_hook(void)
Definition: marshal.c:4534
static DWORD CALLBACK implicit_mta_marshal_proc(void *param)
Definition: marshal.c:4257
static void test_StdMarshal_custom_marshaling(void)
Definition: marshal.c:1556
static void test_marshal_channel_buffer(void)
Definition: marshal.c:1373
static DWORD WINAPI MessageFilter_MessagePending(IMessageFilter *iface, HTASK threadIDCallee, DWORD dwTickCount, DWORD dwPendingType)
Definition: marshal.c:2697
static void test_disconnect_stub(void)
Definition: marshal.c:2449
static DWORD CALLBACK second_mta_thread_proc(void *param)
Definition: marshal.c:4583
static HRESULT WINAPI CustomMarshal_MarshalInterface(IMarshal *iface, IStream *stream, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
Definition: marshal.c:1494
static void test_no_couninitialize_client(void)
Definition: marshal.c:1835
static DWORD CALLBACK crash_couninitialize_proc(void *p)
Definition: marshal.c:1874
#define CLSID_WineTest
Definition: marshal.c:138
static const IClassFactoryVtbl TestClassFactory_Vtbl
Definition: marshal.c:341
static HRESULT WINAPI TestOOP_IClassFactory_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:3765
static ULONG WINAPI local_server_Release(IPersist *iface)
Definition: marshal.c:3728
static void test_marshal_proxy_mta_apartment_shutdown(void)
Definition: marshal.c:1329
static ULONG WINAPI local_server_AddRef(IPersist *iface)
Definition: marshal.c:3723
static ULONG WINAPI RpcProxyBuffer_AddRef(IRpcProxyBuffer *iface)
Definition: marshal.c:563
static void test_handler_marshaling(void)
Definition: marshal.c:3545
static const GUID CLSID_DfMarshal
Definition: marshal.c:62
static int method
Definition: marshal.c:4380
static IMessageFilter MessageFilter
Definition: marshal.c:2717
static void LockModule(void)
Definition: marshal.c:170
static ULONG WINAPI TestOOP_IClassFactory_AddRef(LPCLASSFACTORY iface)
Definition: marshal.c:3783
static void WINAPI TestChannelHook_ServerNotify(IChannelHook *iface, REFGUID uExtent, REFIID riid, ULONG cbDataSize, void *pDataBuffer, DWORD lDataRep)
Definition: marshal.c:4460
static void test_normal_marshal_and_release(void)
Definition: marshal.c:809
static HRESULT WINAPI Test_SMI_QueryInterface(IStdMarshalInfo *iface, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:3495
static const IOleWindowVtbl OleWindowVtbl
Definition: marshal.c:384
static DWORD WINAPI ExternalConnection_AddConnection(IExternalConnection *iface, DWORD extconn, DWORD reserved)
Definition: marshal.c:201
static ULONG WINAPI TestChannelHook_Release(IChannelHook *iface)
Definition: marshal.c:4375
static IClassFactory TestOOP_ClassFactory
Definition: marshal.c:3827
static BOOL with_external_conn
Definition: marshal.c:180
static void test_marshal_proxy_apartment_shutdown(void)
Definition: marshal.c:1281
static const IExternalConnectionVtbl ExternalConnectionVtbl
Definition: marshal.c:216
static ULONG WINAPI RpcStubBuffer_CountRefs(IRpcStubBuffer *iface)
Definition: marshal.c:507
GUID IPID
Definition: marshal.c:88
static const IUnknownVtbl HeapUnknown_Vtbl
Definition: marshal.c:2882
static void test_lock_object_external(void)
Definition: marshal.c:2351
static void test_bad_marshal_stream(void)
Definition: marshal.c:2770
static IClassFactory TestRE_ClassFactory
Definition: marshal.c:2986
static const IPersistVtbl local_server_persist_vtbl
Definition: marshal.c:3752
UINT64 OXID
Definition: marshal.c:86
static void WINAPI TestChannelHook_ClientNotify(IChannelHook *iface, REFGUID uExtent, REFIID riid, ULONG cbDataSize, void *pDataBuffer, DWORD lDataRep, HRESULT hrFault)
Definition: marshal.c:4434
#define OBJREF_STANDARD
Definition: marshal.c:77
static const IUnknownVtbl TestUnknown_Vtbl
Definition: marshal.c:257
static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
Definition: marshal.c:318
static HRESULT WINAPI PSFactoryBuffer_QueryInterface(IPSFactoryBuffer *iface, REFIID riid, void **ppv)
Definition: marshal.c:612
struct tagSTDOBJREF STDOBJREF
static HRESULT WINAPI TestMsg_IClassFactory_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:3134
static ULONG WINAPI TestCrash_IUnknown_Release(LPUNKNOWN iface)
Definition: marshal.c:266
static const LARGE_INTEGER llZero
Definition: moniker.c:1425
static BSTR *static LPOLESTR
Definition: varformat.c:44
#define argv
Definition: mplay32.c:18
const CLSID * clsid
Definition: msctf.cpp:50
Definition: features.h:417
unsigned int UINT
Definition: ndis.h:50
#define DWORD
Definition: nt_native.h:44
#define KEY_SET_VALUE
Definition: nt_native.h:1020
@ REGCLS_SUSPENDED
Definition: objbase.h:398
@ REGCLS_MULTIPLEUSE
Definition: objbase.h:396
@ REGCLS_SINGLEUSE
Definition: objbase.h:395
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:279
@ COINIT_MULTITHREADED
Definition: objbase.h:280
interface IStream * LPSTREAM
Definition: objfwd.h:10
const GUID IID_IParseDisplayName
const GUID IID_IOleWindow
const GUID IID_IOleClientSite
const GUID IID_IOleObject
long LONG
Definition: pedump.c:60
const GUID IID_IPersist
Definition: proxy.cpp:14
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
_In_opt_ IUnknown * punk
Definition: shlwapi.h:158
#define RPC_C_IMP_LEVEL_IMPERSONATE
Definition: rpcdce.h:176
strcat
Definition: string.h:92
strcpy
Definition: string.h:131
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:206
int winetest_get_mainargs(char ***pargv)
#define wait_child_process
Definition: test.h:177
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
TCHAR * cmdline
Definition: stretchblt.cpp:32
IUnknown IUnknown_iface
Definition: marshal.c:2847
ULONG refs
Definition: marshal.c:2848
IRpcProxyBuffer * buffer
Definition: marshal.c:540
IRpcProxyBuffer IRpcProxyBuffer_iface
Definition: marshal.c:538
IRpcStubBuffer * buffer
Definition: marshal.c:432
IRpcStubBuffer IRpcStubBuffer_iface
Definition: marshal.c:430
Definition: scsiwmi.h:51
LPCSTR lpszClassName
Definition: winuser.h:3274
WNDPROC lpfnWndProc
Definition: winuser.h:3266
Definition: stubgen.c:11
Definition: cookie.c:34
MSHLFLAGS marshal_flags1
Definition: marshal.c:2085
IStream * pStream1
Definition: marshal.c:2086
HANDLE hQuitEvent
Definition: marshal.c:2088
HANDLE hReadyEvent
Definition: marshal.c:2087
IStream * pStream2
Definition: marshal.c:2086
MSHLFLAGS marshal_flags2
Definition: marshal.c:2085
Definition: main.c:439
DWORD cookie
Definition: marshal.c:4005
IGlobalInterfaceTable * git
Definition: marshal.c:4006
IMessageFilter * filter
Definition: marshal.c:694
IUnknown * register_object
Definition: marshal.c:695
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
const CLSID * register_clsid
Definition: marshal.c:696
IPersist IPersist_iface
Definition: marshal.c:3704
LPSTREAM stream
Definition: marshal.c:1736
HANDLE unmarshal_event
Definition: marshal.c:1738
HANDLE marshal_event
Definition: marshal.c:1737
Definition: send.c:48
Definition: stat.h:66
Definition: parse.h:23
unsigned short aStringArray[1]
Definition: marshal.c:83
unsigned short wSecurityOffset
Definition: marshal.c:82
unsigned short wNumEntries
Definition: marshal.c:81
CLSID clsid
Definition: marshal.c:109
ULONG cbExtension
Definition: marshal.c:114
struct tagOBJREF::@1807::OR_CUSTOM u_custom
ULONG size
Definition: marshal.c:115
DUALSTRINGARRAY saResAddr
Definition: marshal.c:105
STDOBJREF std
Definition: marshal.c:104
ULONG flags
Definition: marshal.c:100
byte * pData
Definition: marshal.c:116
GUID iid
Definition: marshal.c:101
ULONG signature
Definition: marshal.c:99
struct tagOBJREF::@1807::OR_HANDLER u_handler
union tagOBJREF::@1807 u_objref
struct tagOBJREF::@1807::OR_STANDARD u_standard
OXID oxid
Definition: marshal.c:93
ULONG flags
Definition: marshal.c:91
IPID ipid
Definition: marshal.c:95
ULONG cPublicRefs
Definition: marshal.c:92
struct _stub stub
#define EXCEPTION_NONCONTINUABLE
Definition: stubs.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
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
static EFI_HANDLE * handles
Definition: uefidisk.c:118
static rfbScreenInfoPtr server
Definition: vnc.c:74
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1156
#define GMEM_FIXED
Definition: winbase.h:317
#define WAIT_OBJECT_0
Definition: winbase.h:383
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define REGDB_E_CLASSNOTREG
Definition: winerror.h:3801
#define S_FALSE
Definition: winerror.h:3451
#define RPC_E_WRONG_THREAD
Definition: winerror.h:3562
#define E_NOINTERFACE
Definition: winerror.h:3479
#define STG_E_READFAULT
Definition: winerror.h:3671
#define CO_E_OBJNOTCONNECTED
Definition: winerror.h:3929
#define CO_E_OBJNOTREG
Definition: winerror.h:3927
#define RPC_E_CANTCALLOUT_ININPUTSYNCCALL
Definition: winerror.h:3561
#define RPC_S_CALLPENDING
Definition: winerror.h:3569
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:3771
#define CO_E_SERVER_STOPPING
Definition: winerror.h:4207
#define E_POINTER
Definition: winerror.h:3480
#define RPC_E_DISCONNECTED
Definition: winerror.h:3556
#define RPC_E_CALL_REJECTED
Definition: winerror.h:3530
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
#define WM_QUIT
Definition: winuser.h:1651
BOOL WINAPI TranslateMessage(_In_ const MSG *)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4417
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define SMTO_BLOCK
Definition: winuser.h:1235
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define QS_ALLINPUT
Definition: winuser.h:914
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
LRESULT WINAPI SendMessageTimeoutA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM, _In_ UINT, _In_ UINT, _Out_opt_ PDWORD_PTR)
#define PM_REMOVE
Definition: winuser.h:1207
#define WM_NULL
Definition: winuser.h:1635
#define CW_USEDEFAULT
Definition: winuser.h:225
HWND WINAPI GetWindow(_In_ HWND, _In_ UINT)
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 DestroyWindow(_In_ HWND)
BOOL WINAPI PostMessageA(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define PM_NOREMOVE
Definition: winuser.h:1206