ReactOS 0.4.16-dev-401-g45b008d
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#include "wine/heap.h"
37
38#define DEFINE_EXPECT(func) \
39 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
40
41#define SET_EXPECT(func) \
42 expect_ ## func = TRUE
43
44#define CHECK_EXPECT2(func) \
45 do { \
46 ok(expect_ ##func, "unexpected call " #func "\n"); \
47 called_ ## func = TRUE; \
48 }while(0)
49
50#define CHECK_EXPECT(func) \
51 do { \
52 CHECK_EXPECT2(func); \
53 expect_ ## func = FALSE; \
54 }while(0)
55
56#define CHECK_CALLED(func) \
57 do { \
58 ok(called_ ## func, "expected " #func "\n"); \
59 expect_ ## func = called_ ## func = FALSE; \
60 }while(0)
61
62static const GUID CLSID_WineTestPSFactoryBuffer = { 0x22222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
63static const GUID CLSID_DfMarshal = { 0x0000030b, 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 * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
67static HRESULT (WINAPI *pDllGetClassObject)(REFCLSID,REFIID,LPVOID);
68
69/* helper macros to make tests a bit leaner */
70#define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
71#define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
72#define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
73#define ok_non_zero_external_conn() do {if (with_external_conn) ok(external_connections, "got no external connections\n");} while(0);
74#define ok_zero_external_conn() do {if (with_external_conn) ok(!external_connections, "got %d external connections\n", external_connections);} while(0);
75#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);
76
77#define OBJREF_SIGNATURE (0x574f454d)
78#define OBJREF_STANDARD (0x1)
79#define OBJREF_CUSTOM (0x4)
80
81typedef struct tagDUALSTRINGARRAY {
82 unsigned short wNumEntries;
83 unsigned short wSecurityOffset;
84 unsigned short aStringArray[1];
86
87typedef UINT64 OXID;
88typedef UINT64 OID;
89typedef GUID IPID;
90
91typedef struct tagSTDOBJREF {
98
99typedef struct tagOBJREF {
103 union {
104 struct OR_STANDARD {
108 struct OR_HANDLER {
111 DUALSTRINGARRAY saResAddr;
113 struct OR_CUSTOM {
114 CLSID clsid;
117 byte *pData;
121
122static const IID IID_IWineTest =
123{
124 0x5201163f,
125 0x8164,
126 0x4fd0,
127 {0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
128}; /* 5201163f-8164-4fd0-a1a2-5d5a3654d3bd */
129
130static const IID IID_IRemUnknown =
131{
132 0x00000131,
133 0x0000,
134 0x0000,
135 {0xc0,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
136};
137
138#define EXTENTID_WineTest IID_IWineTest
139#define CLSID_WineTest IID_IWineTest
140
142{
143 0x5201163f,
144 0x8164,
145 0x4fd0,
146 {0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
147}; /* 5201163f-8164-4fd0-a1a2-5d5a3654d3bd */
148
150{
151 IUnknown *pProxy;
152 IMultiQI *pMQI;
153 HRESULT hr;
154
155 pCoInitializeEx(NULL, COINIT_MULTITHREADED);
156
157 hr = CoCreateInstance(&CLSID_ShellDesktop, NULL, CLSCTX_INPROC, &IID_IUnknown, (void **)&pProxy);
159 hr = IUnknown_QueryInterface(pProxy, &IID_IMultiQI, (void **)&pMQI);
160 ok(hr == S_OK, "created object is not a proxy, so was created in the wrong apartment\n");
161 if (hr == S_OK)
162 IMultiQI_Release(pMQI);
163 IUnknown_Release(pProxy);
164
166}
167
170
171static void LockModule(void)
172{
174}
175
176static void UnlockModule(void)
177{
179}
180
184
186{
187 ok(0, "unexpected call\n");
188 *ppv = NULL;
189 return E_NOINTERFACE;
190}
191
193{
194 return 2;
195}
196
198{
199 return 1;
200}
201
203{
204 trace("add connection\n");
205 return ++external_connections;
206}
207
208
210 DWORD reserved, BOOL fLastReleaseCloses)
211{
212 trace("release connection %d\n", fLastReleaseCloses);
213 last_release_closes = fLastReleaseCloses;
214 return --external_connections;
215}
216
217static const IExternalConnectionVtbl ExternalConnectionVtbl = {
223};
224
226
227
229 LPUNKNOWN iface,
230 REFIID riid,
231 LPVOID *ppvObj)
232{
233 if (ppvObj == NULL) return E_POINTER;
234
236 {
237 *ppvObj = iface;
238 IUnknown_AddRef(iface);
239 return S_OK;
240 }
241
242 *ppvObj = NULL;
243 return E_NOINTERFACE;
244}
245
247{
248 LockModule();
249 return 2; /* non-heap-based object */
250}
251
253{
254 UnlockModule();
255 return 1; /* non-heap-based object */
256}
257
258static const IUnknownVtbl TestUnknown_Vtbl =
259{
263};
264
266
268{
269 UnlockModule();
270 if(!cLocks) {
271 trace("crashing...\n");
272 *(int**)0xc = 0;
273 }
274 return 1; /* non-heap-based object */
275}
276
277static const IUnknownVtbl TestCrashUnknown_Vtbl =
278{
282};
283
285
287 LPCLASSFACTORY iface,
288 REFIID riid,
289 LPVOID *ppvObj)
290{
291 if (ppvObj == NULL) return E_POINTER;
292
295 /* the only other interface Wine is currently able to marshal (for testing two proxies) */
297 {
298 *ppvObj = iface;
299 IClassFactory_AddRef(iface);
300 return S_OK;
301 }
302
303 if (with_external_conn && IsEqualGUID(riid, &IID_IExternalConnection))
304 {
305 *ppvObj = &ExternalConnection;
306 return S_OK;
307 }
308
309 *ppvObj = NULL;
310 return E_NOINTERFACE;
311}
312
313static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
314{
315 LockModule();
316 return 2; /* non-heap-based object */
317}
318
319static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
320{
321 UnlockModule();
322 return 1; /* non-heap-based object */
323}
324
326 LPCLASSFACTORY iface,
327 LPUNKNOWN pUnkOuter,
328 REFIID riid,
329 LPVOID *ppvObj)
330{
331 if (pUnkOuter) return CLASS_E_NOAGGREGATION;
332 return IUnknown_QueryInterface(&Test_Unknown, riid, ppvObj);
333}
334
336 LPCLASSFACTORY iface,
337 BOOL fLock)
338{
339 return S_OK;
340}
341
342static const IClassFactoryVtbl TestClassFactory_Vtbl =
343{
349};
350
352
354DEFINE_EXPECT(CreateStub);
355DEFINE_EXPECT(CreateProxy);
357DEFINE_EXPECT(Disconnect);
358
360{
361 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
362 *ppv = NULL;
363 return E_NOINTERFACE;
364}
365
367{
368 return 2;
369}
370
372{
373 return 1;
374}
375
377{
379 *hwnd = (HWND)0xdeadbeef;
380 return S_OK;
381}
382
383static const IOleWindowVtbl OleWindowVtbl = {
388 /* not needed */
389};
390
392
394{
396 *ppv = iface;
397 else if (IsEqualGUID(riid, &IID_IOleWindow))
399 else
400 {
401 *ppv = NULL;
402 return E_NOINTERFACE;
403 }
404
405 IUnknown_AddRef((IUnknown*)*ppv);
406 return S_OK;
407}
408
410{
411 return 2;
412}
413
415{
416 return 1;
417}
418
419static const IOleClientSiteVtbl OleClientSiteVtbl = {
423 /* we don't need the rest, we never call it */
424};
425
427
428typedef struct {
433
435{
436 return CONTAINING_RECORD(iface, StubBufferWrapper, IRpcStubBuffer_iface);
437}
438
440{
442
443 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IRpcStubBuffer, riid)) {
444 *ppv = &This->IRpcStubBuffer_iface;
445 }else {
446 *ppv = NULL;
447 return E_NOINTERFACE;
448 }
449
450 IUnknown_AddRef((IUnknown*)*ppv);
451 return S_OK;
452}
453
455{
457 return InterlockedIncrement(&This->ref);
458}
459
461{
464 if(!ref) {
465 IRpcStubBuffer_Release(This->buffer);
467 }
468 return ref;
469}
470
472{
473 ok(0, "unexpected call\n");
474 return E_NOTIMPL;
475}
476
478{
479 CHECK_EXPECT(Disconnect);
480}
481
482static HRESULT WINAPI RpcStubBuffer_Invoke(IRpcStubBuffer *iface, RPCOLEMESSAGE *_prpcmsg,
483 IRpcChannelBuffer *_pRpcChannelBuffer)
484{
486 void *dest_context_data;
487 DWORD dest_context;
488 HRESULT hr;
489
490 CHECK_EXPECT(Invoke);
491
492 hr = IRpcChannelBuffer_GetDestCtx(_pRpcChannelBuffer, &dest_context, &dest_context_data);
493 ok(hr == S_OK, "GetDestCtx failed: %08x\n", hr);
494 ok(dest_context == MSHCTX_INPROC, "desc_context = %x\n", dest_context);
495 ok(!dest_context_data, "desc_context_data = %p\n", dest_context_data);
496
497 return IRpcStubBuffer_Invoke(This->buffer, _prpcmsg, _pRpcChannelBuffer);
498}
499
501{
502 ok(0, "unexpected call\n");
503 return NULL;
504}
505
507{
508 ok(0, "unexpected call\n");
509 return E_NOTIMPL;
510}
511
513{
514 ok(0, "unexpected call\n");
515 return E_NOTIMPL;
516}
517
519{
520 ok(0, "unexpected call\n");
521}
522
523static const IRpcStubBufferVtbl RpcStubBufferVtbl = {
534};
535
537
539{
540 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPSFactoryBuffer))
541 *ppv = iface;
542 else
543 {
544 *ppv = NULL;
545 return E_NOINTERFACE;
546 }
547 IUnknown_AddRef((IUnknown*)*ppv);
548 return S_OK;
549}
550
552{
553 return 2;
554}
555
557{
558 return 1;
559}
560
562 REFIID riid, IRpcProxyBuffer **ppProxy, void **ppv)
563{
564 CHECK_EXPECT(CreateProxy);
565 return IPSFactoryBuffer_CreateProxy(ps_factory_buffer, outer, riid, ppProxy, ppv);
566}
567
569 IUnknown *server, IRpcStubBuffer **ppStub)
570{
572 HRESULT hr;
573
574 CHECK_EXPECT(CreateStub);
575
576 ok(server == (IUnknown*)&Test_OleClientSite, "unexpected server %p\n", server);
577
578 stub = heap_alloc(sizeof(*stub));
579 stub->IRpcStubBuffer_iface.lpVtbl = &RpcStubBufferVtbl;
580 stub->ref = 1;
581
582 hr = IPSFactoryBuffer_CreateStub(ps_factory_buffer, riid, server, &stub->buffer);
583 ok(hr == S_OK, "CreateStub failed: %08x\n", hr);
584
585 *ppStub = &stub->IRpcStubBuffer_iface;
586 return S_OK;
587}
588
589static IPSFactoryBufferVtbl PSFactoryBufferVtbl =
590{
596};
597
599
600#define RELEASEMARSHALDATA WM_USER
601
603{
605 const IID *iid;
607 MSHLFLAGS marshal_flags;
612};
613
614#ifndef __REACTOS__ /* FIXME: Inspect */
616#endif
617
619{
620 struct host_object_data *data = p;
621 DWORD registration_key;
622 HRESULT hr;
623 MSG msg;
624
625 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
626
627 if(data->register_object) {
628 hr = CoRegisterClassObject(data->register_clsid, data->register_object,
629 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &registration_key);
630 ok(hr == S_OK, "CoRegisterClassObject failed: %08x\n", hr);
631 }
632
633 if (data->filter)
634 {
635 IMessageFilter * prev_filter = NULL;
636 hr = CoRegisterMessageFilter(data->filter, &prev_filter);
637 if (prev_filter) IMessageFilter_Release(prev_filter);
639 }
640
641 hr = CoMarshalInterface(data->stream, data->iid, data->object, MSHCTX_INPROC, NULL, data->marshal_flags);
643
644 /* force the message queue to be created before signaling parent thread */
646
647 SetEvent(data->marshal_event);
648
649 while (GetMessageA(&msg, NULL, 0, 0))
650 {
651 if (msg.hwnd == NULL && msg.message == RELEASEMARSHALDATA)
652 {
653 CoReleaseMarshalData(data->stream);
654 SetEvent((HANDLE)msg.lParam);
655 }
656 else
658 }
659
661
663
664 return hr;
665}
666
668{
669 DWORD tid = 0;
670 struct host_object_data *data;
671
672 data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data));
673 *data = *object_data;
676
677 /* wait for marshaling to complete before returning */
678 ok( !WaitForSingleObject(data->marshal_event, 10000), "wait timed out\n" );
679 CloseHandle(data->marshal_event);
680
681 return tid;
682}
683
685{
686 struct host_object_data object_data = { stream, riid, object, marshal_flags };
687 return start_host_object2(&object_data, thread);
688}
689
690/* asks thread to release the marshal data because it has to be done by the
691 * same thread that marshaled the interface in the first place. */
693{
696 ok( !WaitForSingleObject(event, 10000), "wait timed out\n" );
698}
699
701{
703 ok(ret, "PostThreadMessage failed with error %d\n", GetLastError());
704 /* be careful of races - don't return until hosting thread has terminated */
705 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
707}
708
709/* tests failure case of interface not having a marshaler specified in the
710 * registry */
711static void test_no_marshaler(void)
712{
713 IStream *pStream;
714 HRESULT hr;
715
716 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
718 hr = CoMarshalInterface(pStream, &IID_IWineTest, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
719 ok(hr == E_NOINTERFACE, "CoMarshalInterface should have returned E_NOINTERFACE instead of 0x%08x\n", hr);
720
721 IStream_Release(pStream);
722}
723
724/* tests normal marshal and then release without unmarshaling */
726{
727 HRESULT hr;
728 IStream *pStream = NULL;
729
730 cLocks = 0;
732
733 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
735 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
737
740
741 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
742 hr = CoReleaseMarshalData(pStream);
744 IStream_Release(pStream);
745
746 ok_no_locks();
749}
750
751/* tests success case of a same-thread marshal and unmarshal */
753{
754 HRESULT hr;
755 IStream *pStream = NULL;
756 IUnknown *pProxy = NULL;
757
758 cLocks = 0;
760
761 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
763 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
765
768
769 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
770 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
772 IStream_Release(pStream);
773
777
778 IUnknown_Release(pProxy);
779
780 ok_no_locks();
781}
782
783/* tests failure case of unmarshaling a freed object */
785{
786 HRESULT hr;
787 IStream *pStream = NULL;
788 IClassFactory *pProxy = NULL;
789 DWORD tid;
790 void * dummy;
792
793 cLocks = 0;
795
796 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
798 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
799
802
803 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
804 hr = CoReleaseMarshalData(pStream);
806
807 ok_no_locks();
810
811 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
812 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
814
815 ok_no_locks();
816
817 if (pProxy)
818 {
819 hr = IClassFactory_CreateInstance(pProxy, NULL, &IID_IUnknown, &dummy);
820 ok(hr == RPC_E_DISCONNECTED, "Remote call should have returned RPC_E_DISCONNECTED, instead of 0x%08x\n", hr);
821
822 IClassFactory_Release(pProxy);
823 }
824
825 IStream_Release(pStream);
826
828}
829
831{
832 HRESULT hr;
833 IStream *pStream;
834 IUnknown *pProxy;
835 static const LARGE_INTEGER llZero;
836
837 cLocks = 0;
839
840 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
842
843 hr = CoMarshalInterface(pStream, &IID_IUnknown, (IUnknown *)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
845
848
849 hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
850 ok_ole_success(hr, IStream_Seek);
851
852 hr = CoUnmarshalInterface(pStream, &IID_IParseDisplayName, (void **)&pProxy);
853 ok(hr == E_NOINTERFACE, "CoUnmarshalInterface should have returned E_NOINTERFACE instead of 0x%08x\n", hr);
854
855 ok_no_locks();
858
859 IStream_Release(pStream);
860}
861
862/* tests success case of an interthread marshal */
864{
865 HRESULT hr;
866 IStream *pStream = NULL;
867 IUnknown *pProxy = NULL;
868 DWORD tid;
870
871 cLocks = 0;
873
874 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
876 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
877
880
881 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
882 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
884 IStream_Release(pStream);
885
888
889 IUnknown_Release(pProxy);
890
891 ok_no_locks();
894
896}
897
898/* the number of external references that Wine's proxy manager normally gives
899 * out, so we can test the border case of running out of references */
900#define NORMALEXTREFS 5
901
902/* tests success case of an interthread marshal and then marshaling the proxy */
904{
905 HRESULT hr;
906 IStream *pStream = NULL;
907 IUnknown *pProxy = NULL;
908 IUnknown *pProxy2 = NULL;
909 DWORD tid;
911 int i;
912
913 cLocks = 0;
915
916 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
918 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
919
922
923 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
924 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
926
928
929 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
930 /* marshal the proxy */
931 hr = CoMarshalInterface(pStream, &IID_IClassFactory, pProxy, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
933
935
936 /* marshal 5 more times to exhaust the normal external references of 5 */
937 for (i = 0; i < NORMALEXTREFS; i++)
938 {
939 hr = CoMarshalInterface(pStream, &IID_IClassFactory, pProxy, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
941 }
942
944
945 /* release the original proxy to test that we successfully keep the
946 * original object alive */
947 IUnknown_Release(pProxy);
948
949 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
950 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
952
955
956 IUnknown_Release(pProxy2);
957
958 /* unmarshal all of the proxies to check that the object stub still exists */
959 for (i = 0; i < NORMALEXTREFS; i++)
960 {
961 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
963
964 IUnknown_Release(pProxy2);
965 }
966
967 ok_no_locks();
970
971 IStream_Release(pStream);
972
974}
975
976/* tests success case of an interthread marshal and then marshaling the proxy
977 * using an iid that hasn't previously been unmarshaled */
979{
980 HRESULT hr;
981 IStream *pStream = NULL;
982 IUnknown *pProxy = NULL;
983 IUnknown *pProxy2 = NULL;
984 DWORD tid;
986
987 cLocks = 0;
989
990 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
992 tid = start_host_object(pStream, &IID_IUnknown, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
993
996
997 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
998 hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
1000
1002
1003 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1004 /* marshal the proxy */
1005 hr = CoMarshalInterface(pStream, &IID_IClassFactory, pProxy, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1007
1009
1010 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1011 /* unmarshal the second proxy to the object */
1012 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
1014 IStream_Release(pStream);
1015
1016 /* now the proxies should be as follows:
1017 * pProxy -> &Test_ClassFactory
1018 * pProxy2 -> &Test_ClassFactory
1019 * they should NOT be as follows:
1020 * pProxy -> &Test_ClassFactory
1021 * pProxy2 -> pProxy
1022 * the above can only really be tested by looking in +ole traces
1023 */
1024
1026
1027 IUnknown_Release(pProxy);
1028
1031
1032 IUnknown_Release(pProxy2);
1033
1034 ok_no_locks();
1037
1039}
1040
1041/* tests success case of an interthread marshal and then table-weak-marshaling the proxy */
1043{
1044 HRESULT hr;
1045 IStream *pStream = NULL;
1046 IUnknown *pProxy = NULL;
1047 IUnknown *pProxy2 = NULL;
1048 DWORD tid;
1049 HANDLE thread;
1050
1051 cLocks = 0;
1053
1054 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1056 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
1057
1060
1061 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1062 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1064
1067
1068 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1069 /* marshal the proxy */
1070 hr = CoMarshalInterface(pStream, &IID_IClassFactory, pProxy, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLEWEAK);
1072
1075
1076 /* release the original proxy to test that we successfully keep the
1077 * original object alive */
1078 IUnknown_Release(pProxy);
1079
1080 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1081 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
1082 todo_wine
1083 ok(hr == CO_E_OBJNOTREG, "CoUnmarshalInterface should return CO_E_OBJNOTREG instead of 0x%08x\n", hr);
1084
1085 ok_no_locks();
1088
1089 IStream_Release(pStream);
1090
1092}
1093
1094/* tests success case of an interthread marshal and then table-strong-marshaling the proxy */
1096{
1097 HRESULT hr;
1098 IStream *pStream = NULL;
1099 IUnknown *pProxy = NULL;
1100 IUnknown *pProxy2 = NULL;
1101 DWORD tid;
1102 HANDLE thread;
1103
1104 cLocks = 0;
1106
1107 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1109 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
1110
1113
1114 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1115 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1117
1120
1121 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1122 /* marshal the proxy */
1123 hr = CoMarshalInterface(pStream, &IID_IClassFactory, pProxy, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG);
1124 ok(hr == S_OK /* WinNT */ || hr == E_INVALIDARG /* Win9x */,
1125 "CoMarshalInterface should have return S_OK or E_INVALIDARG instead of 0x%08x\n", hr);
1126 if (FAILED(hr))
1127 {
1128 IUnknown_Release(pProxy);
1129 goto end;
1130 }
1131
1134
1135 /* release the original proxy to test that we successfully keep the
1136 * original object alive */
1137 IUnknown_Release(pProxy);
1138
1139 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1140 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
1142
1145
1146 IUnknown_Release(pProxy2);
1147
1150
1151end:
1152 IStream_Release(pStream);
1153
1155
1156 ok_no_locks();
1157todo_wine {
1160}
1161}
1162
1163/* tests that stubs are released when the containing apartment is destroyed */
1165{
1166 HRESULT hr;
1167 IStream *pStream = NULL;
1168 IUnknown *pProxy = NULL;
1169 DWORD tid;
1170 HANDLE thread;
1171
1172 cLocks = 0;
1174
1175 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1177 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
1178
1181
1182 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1183 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1185 IStream_Release(pStream);
1186
1189
1191
1192 ok_no_locks();
1193todo_wine {
1196}
1197
1198 IUnknown_Release(pProxy);
1199
1200 ok_no_locks();
1201}
1202
1203/* tests that proxies are released when the containing apartment is destroyed */
1205{
1206 HRESULT hr;
1207 IStream *pStream = NULL;
1209 IUnknown *unk;
1210 ULONG ref;
1211 DWORD tid;
1212 HANDLE thread;
1213
1214 cLocks = 0;
1216
1217 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1219 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
1220
1223
1224 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1225 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&proxy);
1227 IStream_Release(pStream);
1228
1231
1233
1234 ok_no_locks();
1237
1238 hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IUnknown, (void **)&unk);
1239 ok(hr == CO_E_OBJNOTCONNECTED, "got %#x\n", hr);
1240
1241 ref = IClassFactory_Release(proxy);
1242 ok(!ref, "got %d refs\n", ref);
1243
1244 ok_no_locks();
1245
1247
1248 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1249}
1250
1251/* tests that proxies are released when the containing mta apartment is destroyed */
1253{
1254 HRESULT hr;
1255 IStream *pStream = NULL;
1256 IUnknown *pProxy = NULL;
1257 DWORD tid;
1258 HANDLE thread;
1259
1261 pCoInitializeEx(NULL, COINIT_MULTITHREADED);
1262
1263 cLocks = 0;
1265
1266 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1268 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
1269
1272
1273 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1274 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1276 IStream_Release(pStream);
1277
1280
1282
1283 ok_no_locks();
1286
1287 IUnknown_Release(pProxy);
1288
1289 ok_no_locks();
1290
1292
1293 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1294}
1295
1297{
1298 DWORD registration_key;
1299 IUnknown *proxy = NULL;
1300 IOleWindow *ole_window;
1301 HWND hwnd;
1302 CLSID clsid;
1303 DWORD tid;
1304 HANDLE thread;
1305 HRESULT hr;
1306
1308 MSHLFLAGS_NORMAL, NULL, (IUnknown*)&PSFactoryBuffer,
1310
1311 cLocks = 0;
1313
1315 ok_ole_success(hr, "CoGetPSClsid");
1316
1317 hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer,
1318 (void **)&ps_factory_buffer);
1319 ok_ole_success(hr, "CoGetClassObject");
1320
1321 hr = CreateStreamOnHGlobal(NULL, TRUE, &object_data.stream);
1323 tid = start_host_object2(&object_data, &thread);
1324
1325 IStream_Seek(object_data.stream, ullZero, STREAM_SEEK_SET, NULL);
1326 hr = CoUnmarshalInterface(object_data.stream, &IID_IUnknown, (void **)&proxy);
1328 IStream_Release(object_data.stream);
1329
1331 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &registration_key);
1332 ok(hr == S_OK, "CoRegisterClassObject failed: %08x\n", hr);
1333
1335 ok(hr == S_OK, "CoRegisterPSClsid failed: %08x\n", hr);
1336
1337 SET_EXPECT(CreateStub);
1338 SET_EXPECT(CreateProxy);
1339 hr = IUnknown_QueryInterface(proxy, &IID_IOleWindow, (void**)&ole_window);
1340 ok(hr == S_OK, "Could not get IOleWindow iface: %08x\n", hr);
1341 CHECK_CALLED(CreateStub);
1342 CHECK_CALLED(CreateProxy);
1343
1344 SET_EXPECT(Invoke);
1346 hr = IOleWindow_GetWindow(ole_window, &hwnd);
1347 ok(hr == S_OK, "GetWindow failed: %08x\n", hr);
1348 ok((DWORD)(DWORD_PTR)hwnd == 0xdeadbeef, "hwnd = %p\n", hwnd);
1349 CHECK_CALLED(Invoke);
1351
1352 IOleWindow_Release(ole_window);
1353
1354 SET_EXPECT(Disconnect);
1355 IUnknown_Release(proxy);
1357 CHECK_CALLED(Disconnect);
1358
1359 hr = CoRevokeClassObject(registration_key);
1360 ok(hr == S_OK, "CoRevokeClassObject failed: %08x\n", hr);
1361
1363}
1364
1369
1371{
1372 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMarshal)) {
1373 *ppv = iface;
1374 }
1375 else
1376 {
1377 *ppv = NULL;
1378 return E_NOINTERFACE;
1379 }
1380 IUnknown_AddRef((IUnknown*)*ppv);
1381 return S_OK;
1382}
1383
1385{
1386 return 2;
1387}
1388
1390{
1391 return 1;
1392}
1393
1395 void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *clsid)
1396{
1399 return S_OK;
1400}
1401
1403 void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *size)
1404{
1406 ok(size != NULL, "size = NULL\n");
1407
1408 *size = 0;
1409 return S_OK;
1410}
1411
1413 REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
1414{
1415 IMarshal *std_marshal;
1416 STATSTG stat;
1417 HRESULT hr;
1418
1420
1422 return S_OK;
1423
1424 hr = IStream_Stat(stream, &stat, STATFLAG_DEFAULT);
1425 ok_ole_success(hr, IStream_Stat);
1426 ok(U(stat.cbSize).LowPart == 0, "stream is not empty (%d)\n", U(stat.cbSize).LowPart);
1427 ok(U(stat.cbSize).HighPart == 0, "stream is not empty (%d)\n", U(stat.cbSize).HighPart);
1428
1430 dwDestContext, NULL, mshlflags, &std_marshal);
1432 hr = IMarshal_MarshalInterface(std_marshal, stream, riid, pv,
1433 dwDestContext, pvDestContext, mshlflags);
1434 ok_ole_success(hr, IMarshal_MarshalInterface);
1435 IMarshal_Release(std_marshal);
1436
1437 return S_OK;
1438}
1439
1441 IStream *stream, REFIID riid, void **ppv)
1442{
1443 ok(0, "unexpected call\n");
1444 return E_NOTIMPL;
1445}
1446
1448{
1449 ok(0, "unexpected call\n");
1450 return E_NOTIMPL;
1451}
1452
1454{
1455 ok(0, "unexpected call\n");
1456 return E_NOTIMPL;
1457}
1458
1459static IMarshalVtbl CustomMarshalVtbl =
1460{
1470};
1471
1473
1475{
1476 IStream *stream;
1477 IUnknown *unk;
1478 DWORD size;
1479 HRESULT hr;
1480
1483
1488 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1492
1493 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1494 ok_ole_success(hr, IStream_Seek);
1495 hr = CoUnmarshalInterface(stream, &IID_IUnknown, (void**)&unk);
1497 ok(unk == (IUnknown*)&CustomMarshal, "unk != &CustomMarshal\n");
1498 IUnknown_Release(unk);
1499 IStream_Release(stream);
1500
1503
1507 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1511
1512 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1513 ok_ole_success(hr, IStream_Seek);
1516 IStream_Release(stream);
1517
1520 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1523 ok(size == sizeof(OBJREF), "size = %d, expected %d\n", size, (int)sizeof(OBJREF));
1524}
1525
1527{
1528 DWORD size, read;
1529 IStream *stream;
1530 OBJREF objref;
1531 HRESULT hr;
1532
1535
1541 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1546
1547 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1548 ok_ole_success(hr, IStream_Seek);
1549 size = FIELD_OFFSET(OBJREF, u_objref.u_custom.pData);
1550 hr = IStream_Read(stream, &objref, size, &read);
1551 ok_ole_success(hr, IStream_Read);
1552 ok(read == size, "read = %d, expected %d\n", read, size);
1553 ok(objref.signature == OBJREF_SIGNATURE, "objref.signature = %x\n",
1554 objref.signature);
1555 ok(objref.flags == OBJREF_CUSTOM, "objref.flags = %x\n", objref.flags);
1556 ok(IsEqualIID(&objref.iid, &IID_IUnknown), "objref.iid = %s\n",
1557 wine_dbgstr_guid(&objref.iid));
1559 "custom.clsid = %s\n", wine_dbgstr_guid(&objref.u_objref.u_custom.clsid));
1560 ok(!objref.u_objref.u_custom.cbExtension, "custom.cbExtension = %d\n",
1561 objref.u_objref.u_custom.cbExtension);
1562 ok(!objref.u_objref.u_custom.size, "custom.size = %d\n",
1563 objref.u_objref.u_custom.size);
1564
1565 IStream_Release(stream);
1566
1569 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1572 ok(size == sizeof(OBJREF), "size = %d, expected %d\n", size, (int)sizeof(OBJREF));
1573}
1574
1576{
1577 DUALSTRINGARRAY *dualstringarr;
1578 STDOBJREF *stdobjref;
1579 OBJREF objref;
1580 IMarshal *marshal;
1581 DWORD size, read;
1582 IStream *stream;
1583 IUnknown *unk;
1584 CLSID clsid;
1585 HRESULT hr;
1586
1589
1591 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL, &marshal);
1593
1594 hr = IMarshal_GetUnmarshalClass(marshal, &IID_IUnknown, &Test_Unknown,
1595 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL, &clsid);
1596 ok_ole_success(hr, IMarshal_GetUnmarshalClass);
1598
1599 hr = IMarshal_GetMarshalSizeMax(marshal, &IID_IUnknown, &Test_Unknown,
1600 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL, &size);
1601 ok_ole_success(hr, IMarshal_GetMarshalSizeMax);
1603 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1605 ok(size == read, "IMarshal_GetMarshalSizeMax size = %d, expected %d\n", size, read);
1606
1607 hr = IMarshal_MarshalInterface(marshal, stream, &IID_IUnknown,
1608 &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1609 ok_ole_success(hr, IMarshal_MarshalInterface);
1610
1611 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1612 ok_ole_success(hr, IStream_Seek);
1613 size = FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray);
1614 hr = IStream_Read(stream, &objref, size, &read);
1615 ok_ole_success(hr, IStream_Read);
1616 ok(read == size, "read = %d, expected %d\n", read, size);
1617 ok(objref.signature == OBJREF_SIGNATURE, "objref.signature = %x\n",
1618 objref.signature);
1619 ok(objref.flags == OBJREF_STANDARD, "objref.flags = %x\n", objref.flags);
1620 ok(IsEqualIID(&objref.iid, &IID_IUnknown), "objref.iid = %s\n",
1621 wine_dbgstr_guid(&objref.iid));
1622 stdobjref = &objref.u_objref.u_standard.std;
1623 ok(stdobjref->flags == 0, "stdobjref.flags = %d\n", stdobjref->flags);
1624 ok(stdobjref->cPublicRefs == 5, "stdobjref.cPublicRefs = %d\n",
1625 stdobjref->cPublicRefs);
1626 dualstringarr = &objref.u_objref.u_standard.saResAddr;
1627 ok(dualstringarr->wNumEntries == 0, "dualstringarr.wNumEntries = %d\n",
1628 dualstringarr->wNumEntries);
1629 ok(dualstringarr->wSecurityOffset == 0, "dualstringarr.wSecurityOffset = %d\n",
1630 dualstringarr->wSecurityOffset);
1631
1632 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1633 ok_ole_success(hr, IStream_Seek);
1634 hr = IMarshal_UnmarshalInterface(marshal, stream, &IID_IUnknown, (void**)&unk);
1635 ok_ole_success(hr, IMarshal_UnmarshalInterface);
1636 IUnknown_Release(unk);
1637
1638 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1639 ok_ole_success(hr, IStream_Seek);
1640 hr = IMarshal_MarshalInterface(marshal, stream, &IID_IUnknown,
1641 &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1642 ok_ole_success(hr, IMarshal_MarshalInterface);
1643
1644 hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1645 ok_ole_success(hr, IStream_Seek);
1646 hr = IMarshal_ReleaseMarshalData(marshal, stream);
1647 ok_ole_success(hr, IMarshal_ReleaseMarshalData);
1648 IStream_Release(stream);
1649
1650 IMarshal_Release(marshal);
1651}
1653{
1657};
1658
1659/* helper for test_no_couninitialize_server */
1661{
1662 struct ncu_params *ncu_params = p;
1663 HRESULT hr;
1664
1665 pCoInitializeEx(NULL, COINIT_MULTITHREADED);
1666
1667 hr = CoMarshalInterface(ncu_params->stream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1669
1671
1672 ok( !WaitForSingleObject(ncu_params->unmarshal_event, 10000), "wait timed out\n" );
1673
1674 /* die without calling CoUninitialize */
1675
1676 return 0;
1677}
1678
1679/* tests apartment that an apartment with a stub is released without deadlock
1680 * if the owning thread exits */
1682{
1683 HRESULT hr;
1684 IStream *pStream = NULL;
1685 IUnknown *pProxy = NULL;
1686 DWORD tid;
1687 HANDLE thread;
1688 struct ncu_params ncu_params;
1689
1690 cLocks = 0;
1692
1695
1696 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1698 ncu_params.stream = pStream;
1699
1701
1702 ok( !WaitForSingleObject(ncu_params.marshal_event, 10000), "wait timed out\n" );
1705
1706 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1707 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1709 IStream_Release(pStream);
1710
1713
1715 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1716
1717 ok_no_locks();
1718todo_wine {
1721}
1722
1726
1727 IUnknown_Release(pProxy);
1728
1729 ok_no_locks();
1730}
1731
1732/* STA -> STA call during DLL_THREAD_DETACH */
1734{
1735 struct ncu_params *ncu_params = p;
1736 HRESULT hr;
1737 IUnknown *pProxy = NULL;
1738
1739 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1740
1743 IStream_Release(ncu_params->stream);
1744
1746
1747 /* die without calling CoUninitialize */
1748
1749 return 0;
1750}
1751
1752/* tests STA -> STA call during DLL_THREAD_DETACH doesn't deadlock */
1754{
1755 HRESULT hr;
1756 IStream *pStream = NULL;
1757 DWORD tid;
1758 DWORD host_tid;
1759 HANDLE thread;
1760 HANDLE host_thread;
1761 struct ncu_params ncu_params;
1762
1763 cLocks = 0;
1765
1766 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1768 ncu_params.stream = pStream;
1769
1770 /* NOTE: assumes start_host_object uses an STA to host the object, as MTAs
1771 * always deadlock when called from within DllMain */
1772 host_tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown *)&Test_ClassFactory, MSHLFLAGS_NORMAL, &host_thread);
1773 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1774
1777
1779
1780 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1782
1783 ok_no_locks();
1786
1787 end_host_object(host_tid, host_thread);
1788}
1789
1791
1793{
1794 IStream *stream;
1795 HRESULT hr;
1796
1797 cLocks = 0;
1798
1800
1803
1804 hr = CoMarshalInterface(stream, &IID_IUnknown, &TestCrash_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1806
1807 IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
1808
1811
1812 ok_no_locks();
1813
1814 hr = CoMarshalInterface(stream, &IID_IUnknown, &TestCrash_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1816
1818
1819 trace("CoUninitialize >>>\n");
1821 trace("CoUninitialize <<<\n");
1822
1823 ok_no_locks();
1824
1825 IStream_Release(stream);
1827 return 0;
1828}
1829
1831{
1832 HANDLE thread;
1833 DWORD tid;
1834
1835 if(!GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateActCtxW")) {
1836 win_skip("Skipping crash tests on win2k.\n");
1837 return;
1838 }
1839
1842 ok(!WaitForSingleObject(thread, 10000), "wait timed out\n");
1844 ok(crash_thread_success, "Crash thread failed\n");
1845}
1846
1847/* tests success case of a same-thread table-weak marshal, unmarshal, unmarshal */
1849{
1850 HRESULT hr;
1851 IStream *pStream = NULL;
1852 IUnknown *pProxy1 = NULL;
1853 IUnknown *pProxy2 = NULL;
1854 DWORD tid;
1855 HANDLE thread;
1856
1857 cLocks = 0;
1859
1860 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1862 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLEWEAK, &thread);
1863
1866
1867 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1868 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
1870
1873
1874 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1875 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
1877
1879
1880 IUnknown_Release(pProxy1);
1882 IUnknown_Release(pProxy2);
1885
1886 /* When IExternalConnection is present COM's lifetime management
1887 * behaviour is altered; the remaining weak ref prevents stub shutdown. */
1889 {
1891 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1893 }
1894
1895 /* Without IExternalConnection this line is shows the difference between weak and strong table marshaling
1896 * weak has cLocks == 0, strong has cLocks > 0. */
1897 ok_no_locks();
1898
1899 IStream_Release(pStream);
1901}
1902
1903/* tests releasing after unmarshaling one object */
1905{
1906 HRESULT hr;
1907 IStream *pStream = NULL;
1908 IUnknown *pProxy1 = NULL;
1909 IUnknown *pProxy2 = NULL;
1910 DWORD tid;
1911 HANDLE thread;
1912
1913 cLocks = 0;
1915
1916 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1918 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLEWEAK, &thread);
1919
1922
1923 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1924 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
1926
1929
1930 /* release the remaining reference on the object by calling
1931 * CoReleaseMarshalData in the hosting thread */
1932 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1934
1937
1938 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1939 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
1941 IStream_Release(pStream);
1942
1945
1946 IUnknown_Release(pProxy1);
1947
1948 if (pProxy2)
1949 {
1951 IUnknown_Release(pProxy2);
1952 }
1953
1954 /* this line is shows the difference between weak and strong table marshaling:
1955 * weak has cLocks == 0
1956 * strong has cLocks > 0 */
1957 ok_no_locks();
1960
1962}
1963
1964/* tests releasing after unmarshaling one object */
1966{
1967 HRESULT hr;
1968 IStream *pStream = NULL;
1969 IUnknown *pProxy = NULL;
1970 DWORD tid;
1971 HANDLE thread;
1972
1973 cLocks = 0;
1975
1976 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1978 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLEWEAK, &thread);
1979
1982
1983 /* release the remaining reference on the object by calling
1984 * CoReleaseMarshalData in the hosting thread */
1985 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1987
1988 ok_no_locks();
1989
1990 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1991 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1992 todo_wine
1993 {
1994 ok(hr == CO_E_OBJNOTREG,
1995 "CoUnmarshalInterface should have failed with CO_E_OBJNOTREG, but returned 0x%08x instead\n",
1996 hr);
1997 }
1998 IStream_Release(pStream);
1999
2000 ok_no_locks();
2002
2004}
2005
2007{
2012};
2013
2015{
2016 HRESULT hr;
2017 struct duo_marshal_data *data = p;
2018 HANDLE hQuitEvent = data->hQuitEvent;
2019 MSG msg;
2020
2021 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
2022
2023 hr = CoMarshalInterface(data->pStream1, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, data->marshal_flags1);
2024 ok_ole_success(hr, "CoMarshalInterface");
2025
2026 hr = CoMarshalInterface(data->pStream2, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, data->marshal_flags2);
2027 ok_ole_success(hr, "CoMarshalInterface");
2028
2029 /* force the message queue to be created before signaling parent thread */
2031
2032 SetEvent(data->hReadyEvent);
2033
2035 {
2036 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
2037 {
2038 if (msg.hwnd == NULL && msg.message == RELEASEMARSHALDATA)
2039 {
2040 CoReleaseMarshalData(msg.wParam == 1 ? data->pStream1 : data->pStream2);
2041 SetEvent((HANDLE)msg.lParam);
2042 }
2043 else
2045 }
2046 }
2048
2050
2051 return 0;
2052}
2053
2054/* tests interaction between table-weak and normal marshalling of an object */
2056{
2057 HRESULT hr;
2058 IUnknown *pProxyWeak = NULL;
2059 IUnknown *pProxyNormal = NULL;
2060 DWORD tid;
2061 HANDLE thread;
2062 struct duo_marshal_data data;
2063
2064 cLocks = 0;
2066
2067 data.hReadyEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2068 data.hQuitEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2069 data.marshal_flags1 = MSHLFLAGS_TABLEWEAK;
2070 data.marshal_flags2 = MSHLFLAGS_NORMAL;
2071 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.pStream1);
2073 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.pStream2);
2075
2077 ok( !WaitForSingleObject(data.hReadyEvent, 10000), "wait timed out\n" );
2078 CloseHandle(data.hReadyEvent);
2079
2082
2083 /* weak */
2084 IStream_Seek(data.pStream1, ullZero, STREAM_SEEK_SET, NULL);
2085 hr = CoUnmarshalInterface(data.pStream1, &IID_IClassFactory, (void **)&pProxyWeak);
2087
2089
2090 /* normal */
2091 IStream_Seek(data.pStream2, ullZero, STREAM_SEEK_SET, NULL);
2092 hr = CoUnmarshalInterface(data.pStream2, &IID_IClassFactory, (void **)&pProxyNormal);
2094
2096
2097 IUnknown_Release(pProxyNormal);
2098
2101
2102 IUnknown_Release(pProxyWeak);
2103
2106
2107 /* When IExternalConnection is present COM's lifetime management
2108 * behaviour is altered; the remaining weak ref prevents stub shutdown. */
2110 {
2112 IStream_Seek(data.pStream1, ullZero, STREAM_SEEK_SET, NULL);
2114 }
2115 ok_no_locks();
2116
2117 IStream_Release(data.pStream1);
2118 IStream_Release(data.pStream2);
2119
2120 SetEvent(data.hQuitEvent);
2121 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
2123}
2124
2126{
2127 HRESULT hr;
2128 DWORD tid;
2129 HANDLE thread;
2130 struct duo_marshal_data data;
2131
2132 cLocks = 0;
2134
2135 data.hReadyEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2136 data.hQuitEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2137 data.marshal_flags1 = MSHLFLAGS_TABLEWEAK;
2138 data.marshal_flags2 = MSHLFLAGS_NORMAL;
2139 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.pStream1);
2141 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.pStream2);
2143
2145 ok( !WaitForSingleObject(data.hReadyEvent, 10000), "wait timed out\n" );
2146 CloseHandle(data.hReadyEvent);
2147
2150
2151 /* release normal - which in the non-external conn case will free the object despite the weak ref. */
2152 IStream_Seek(data.pStream2, ullZero, STREAM_SEEK_SET, NULL);
2154
2157
2159 {
2161 IStream_Seek(data.pStream1, ullZero, STREAM_SEEK_SET, NULL);
2163 }
2164
2165 ok_no_locks();
2166
2167 IStream_Release(data.pStream1);
2168 IStream_Release(data.pStream2);
2169
2170 SetEvent(data.hQuitEvent);
2171 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
2173}
2174
2176{
2177 HRESULT hr;
2178 DWORD tid;
2179 HANDLE thread;
2180 struct duo_marshal_data data;
2181
2182 cLocks = 0;
2184
2185 data.hReadyEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2186 data.hQuitEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2187 data.marshal_flags1 = MSHLFLAGS_TABLEWEAK;
2188 data.marshal_flags2 = MSHLFLAGS_TABLEWEAK;
2189 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.pStream1);
2191 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.pStream2);
2193
2195 ok( !WaitForSingleObject(data.hReadyEvent, 10000), "wait timed out\n" );
2196 CloseHandle(data.hReadyEvent);
2197
2200
2201 /* release one weak ref - the remaining weak ref will keep the obj alive */
2202 IStream_Seek(data.pStream1, ullZero, STREAM_SEEK_SET, NULL);
2204
2206
2207 IStream_Seek(data.pStream2, ullZero, STREAM_SEEK_SET, NULL);
2209
2210 ok_no_locks();
2211
2212 IStream_Release(data.pStream1);
2213 IStream_Release(data.pStream2);
2214
2215 SetEvent(data.hQuitEvent);
2216 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
2218}
2219
2220/* tests success case of a same-thread table-strong marshal, unmarshal, unmarshal */
2222{
2223 HRESULT hr;
2224 IStream *pStream = NULL;
2225 IUnknown *pProxy1 = NULL;
2226 IUnknown *pProxy2 = NULL;
2227 DWORD tid;
2228 HANDLE thread;
2229
2230 cLocks = 0;
2232
2233 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2235 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLESTRONG, &thread);
2236
2239
2240 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2241 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
2243
2245
2246 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2247 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
2249
2251
2252 if (pProxy1) IUnknown_Release(pProxy1);
2253 if (pProxy2) IUnknown_Release(pProxy2);
2254
2255 /* this line is shows the difference between weak and strong table marshaling:
2256 * weak has cLocks == 0
2257 * strong has cLocks > 0 */
2259
2260 /* release the remaining reference on the object by calling
2261 * CoReleaseMarshalData in the hosting thread */
2262 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2264 IStream_Release(pStream);
2265
2266 ok_no_locks();
2269
2271}
2272
2273/* tests CoLockObjectExternal */
2275{
2276 HRESULT hr;
2277 IStream *pStream = NULL;
2278
2279 cLocks = 0;
2281
2282 /* test the stub manager creation aspect of CoLockObjectExternal when the
2283 * object hasn't been marshaled yet */
2285
2288
2290
2291 ok_no_locks();
2294
2295 /* test our empty stub manager being handled correctly in
2296 * CoMarshalInterface */
2298
2299 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2301 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2303
2305
2308
2309 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2310 hr = CoReleaseMarshalData(pStream);
2312 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2313
2317
2319
2323
2325
2326 ok_no_locks();
2329
2330 /* test CoLockObjectExternal releases reference to object with
2331 * fLastUnlockReleases as TRUE and there are only strong references on
2332 * the object */
2334
2337
2339
2340 ok_no_locks();
2343
2344 /* test CoLockObjectExternal doesn't release the last reference to an
2345 * object with fLastUnlockReleases as TRUE and there is a weak reference
2346 * on the object */
2347 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLEWEAK);
2349
2352
2354
2357
2359
2363
2365
2366 ok_no_locks();
2367
2368 IStream_Release(pStream);
2369}
2370
2371/* tests disconnecting stubs */
2372static void test_disconnect_stub(void)
2373{
2374 HRESULT hr;
2375 IStream *pStream = NULL;
2376
2377 cLocks = 0;
2379
2380 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2382 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2384
2386
2388
2391
2392 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2393 hr = CoReleaseMarshalData(pStream);
2395 IStream_Release(pStream);
2396
2399
2401
2402 ok_no_locks();
2404
2406 ok( hr == E_INVALIDARG, "wrong status %x\n", hr );
2407}
2408
2409/* tests failure case of a same-thread marshal and unmarshal twice */
2411{
2412 HRESULT hr;
2413 IStream *pStream = NULL;
2414 IUnknown *pProxy1 = NULL;
2415 IUnknown *pProxy2 = NULL;
2416
2417 cLocks = 0;
2419
2420 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2422 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2424
2427
2428 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2429 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
2431
2435
2436 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2437 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
2439 "CoUnmarshalInterface should have failed with error CO_E_OBJNOTCONNECTED for double unmarshal, instead of 0x%08x\n", hr);
2440
2441 IStream_Release(pStream);
2442
2444
2445 IUnknown_Release(pProxy1);
2446
2447 ok_no_locks();
2448}
2449
2450/* tests success case of marshaling and unmarshaling an HRESULT */
2452{
2453 HRESULT hr;
2454 HRESULT hr_marshaled = 0;
2455 IStream *pStream = NULL;
2456 static const HRESULT E_DEADBEEF = 0xdeadbeef;
2457
2458 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2460
2461 hr = CoMarshalHresult(pStream, E_DEADBEEF);
2463
2464 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2465 hr = IStream_Read(pStream, &hr_marshaled, sizeof(HRESULT), NULL);
2466 ok_ole_success(hr, IStream_Read);
2467
2468 ok(hr_marshaled == E_DEADBEEF, "Didn't marshal HRESULT as expected: got value 0x%08x instead\n", hr_marshaled);
2469
2470 hr_marshaled = 0;
2471 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2472 hr = CoUnmarshalHresult(pStream, &hr_marshaled);
2474
2475 ok(hr_marshaled == E_DEADBEEF, "Didn't marshal HRESULT as expected: got value 0x%08x instead\n", hr_marshaled);
2476
2477 IStream_Release(pStream);
2478}
2479
2480
2481/* helper for test_proxy_used_in_wrong_thread */
2483{
2484 IClassFactory * cf = p;
2485 HRESULT hr;
2486 IUnknown * proxy = NULL;
2487
2488 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (LPVOID*)&proxy);
2489 todo_wine
2491 "COM should have failed with CO_E_NOTINITIALIZED on using proxy without apartment, but instead returned 0x%08x\n",
2492 hr);
2493
2494 hr = IClassFactory_QueryInterface(cf, &IID_IMultiQI, (LPVOID *)&proxy);
2495 /* Win9x returns S_OK, whilst NT returns RPC_E_WRONG_THREAD */
2496 trace("call to proxy's QueryInterface for local interface without apartment returned 0x%08x\n", hr);
2497 if (SUCCEEDED(hr))
2498 IUnknown_Release(proxy);
2499
2500 hr = IClassFactory_QueryInterface(cf, &IID_IStream, (LPVOID *)&proxy);
2501 /* Win9x returns E_NOINTERFACE, whilst NT returns RPC_E_WRONG_THREAD */
2502 trace("call to proxy's QueryInterface without apartment returned 0x%08x\n", hr);
2503 if (SUCCEEDED(hr))
2504 IUnknown_Release(proxy);
2505
2506 pCoInitializeEx(NULL, COINIT_MULTITHREADED);
2507
2508 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (LPVOID*)&proxy);
2509 if (proxy) IUnknown_Release(proxy);
2511 "COM should have failed with RPC_E_WRONG_THREAD on using proxy from wrong apartment, but instead returned 0x%08x\n",
2512 hr);
2513
2514 hr = IClassFactory_QueryInterface(cf, &IID_IStream, (LPVOID *)&proxy);
2515 /* Win9x returns E_NOINTERFACE, whilst NT returns RPC_E_WRONG_THREAD */
2516 trace("call to proxy's QueryInterface from wrong apartment returned 0x%08x\n", hr);
2517
2518 /* now be really bad and release the proxy from the wrong apartment */
2519 IClassFactory_Release(cf);
2520
2522
2523 return 0;
2524}
2525
2526/* tests failure case of a using a proxy in the wrong apartment */
2528{
2529 HRESULT hr;
2530 IStream *pStream = NULL;
2531 IUnknown *pProxy = NULL;
2532 DWORD tid, tid2;
2533 HANDLE thread;
2534 HANDLE host_thread;
2535
2536 cLocks = 0;
2537
2538 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2540 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &host_thread);
2541
2543
2544 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2545 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
2547 IStream_Release(pStream);
2548
2550
2551 /* do a call that will fail, but result in IRemUnknown being used by the proxy */
2552 IUnknown_QueryInterface(pProxy, &IID_IStream, (LPVOID *)&pStream);
2553
2554 /* create a thread that we can misbehave in */
2555 thread = CreateThread(NULL, 0, bad_thread_proc, pProxy, 0, &tid2);
2556
2557 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
2559
2560 /* do release statement on Win9x that we should have done above */
2561 if (!GetProcAddress(GetModuleHandleA("ole32"), "CoRegisterSurrogateEx"))
2562 IUnknown_Release(pProxy);
2563
2564 ok_no_locks();
2565
2566 end_host_object(tid, host_thread);
2567}
2568
2570{
2571 if (ppvObj == NULL) return E_POINTER;
2572
2573 if (IsEqualGUID(riid, &IID_IUnknown) ||
2575 {
2576 *ppvObj = iface;
2577 IMessageFilter_AddRef(iface);
2578 return S_OK;
2579 }
2580
2581 return E_NOINTERFACE;
2582}
2583
2585{
2586 return 2; /* non-heap object */
2587}
2588
2590{
2591 return 1; /* non-heap object */
2592}
2593
2595 IMessageFilter *iface,
2596 DWORD dwCallType,
2597 HTASK threadIDCaller,
2598 DWORD dwTickCount,
2599 LPINTERFACEINFO lpInterfaceInfo)
2600{
2601 static int callcount = 0;
2602 DWORD ret;
2603 trace("HandleInComingCall\n");
2604 switch (callcount)
2605 {
2606 case 0:
2607 ret = SERVERCALL_REJECTED;
2608 break;
2609 case 1:
2610 ret = SERVERCALL_RETRYLATER;
2611 break;
2612 default:
2613 ret = SERVERCALL_ISHANDLED;
2614 break;
2615 }
2616 callcount++;
2617 return ret;
2618}
2619
2621 IMessageFilter *iface,
2622 HTASK threadIDCallee,
2623 DWORD dwTickCount,
2624 DWORD dwRejectType)
2625{
2626 trace("RetryRejectedCall\n");
2627 return 0;
2628}
2629
2631 IMessageFilter *iface,
2632 HTASK threadIDCallee,
2633 DWORD dwTickCount,
2634 DWORD dwPendingType)
2635{
2636 trace("MessagePending\n");
2637 return PENDINGMSG_WAITNOPROCESS;
2638}
2639
2640static const IMessageFilterVtbl MessageFilter_Vtbl =
2641{
2648};
2649
2651
2652static void test_message_filter(void)
2653{
2654 HRESULT hr;
2656 DWORD tid;
2657 IUnknown *proxy = NULL;
2658 IMessageFilter *prev_filter = NULL;
2659 HANDLE thread;
2660
2662 MSHLFLAGS_NORMAL, &MessageFilter };
2663
2664 cLocks = 0;
2665
2666 hr = CreateStreamOnHGlobal(NULL, TRUE, &object_data.stream);
2668 tid = start_host_object2(&object_data, &thread);
2669
2671
2672 IStream_Seek(object_data.stream, ullZero, STREAM_SEEK_SET, NULL);
2673 hr = CoUnmarshalInterface(object_data.stream, &IID_IClassFactory, (void **)&cf);
2675 IStream_Release(object_data.stream);
2676
2678
2679 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (LPVOID*)&proxy);
2680 ok(hr == RPC_E_CALL_REJECTED, "Call should have returned RPC_E_CALL_REJECTED, but return 0x%08x instead\n", hr);
2681 if (proxy) IUnknown_Release(proxy);
2682 proxy = NULL;
2683
2684 hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
2686
2687 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (LPVOID*)&proxy);
2688 ok_ole_success(hr, IClassFactory_CreateInstance);
2689
2690 IUnknown_Release(proxy);
2691
2692 IClassFactory_Release(cf);
2693
2694 ok_no_locks();
2695
2697
2698 hr = CoRegisterMessageFilter(prev_filter, NULL);
2700}
2701
2702/* test failure case of trying to unmarshal from bad stream */
2704{
2705 HRESULT hr;
2706 IStream *pStream = NULL;
2707
2708 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2710 hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2712
2714
2715 /* try to read beyond end of stream */
2716 hr = CoReleaseMarshalData(pStream);
2717 ok(hr == STG_E_READFAULT, "Should have failed with STG_E_READFAULT, but returned 0x%08x instead\n", hr);
2718
2719 /* now release for real */
2720 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2721 hr = CoReleaseMarshalData(pStream);
2723
2724 IStream_Release(pStream);
2725}
2726
2727/* tests that proxies implement certain interfaces */
2728static void test_proxy_interfaces(void)
2729{
2730 HRESULT hr;
2731 IStream *pStream = NULL;
2732 IUnknown *pProxy = NULL;
2733 IUnknown *pOtherUnknown = NULL;
2734 DWORD tid;
2735 HANDLE thread;
2736
2737 cLocks = 0;
2738
2739 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2741 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
2742
2744
2745 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2746 hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
2748 IStream_Release(pStream);
2749
2751
2752 hr = IUnknown_QueryInterface(pProxy, &IID_IUnknown, (LPVOID*)&pOtherUnknown);
2753 ok_ole_success(hr, IUnknown_QueryInterface IID_IUnknown);
2754 if (hr == S_OK) IUnknown_Release(pOtherUnknown);
2755
2756 hr = IUnknown_QueryInterface(pProxy, &IID_IClientSecurity, (LPVOID*)&pOtherUnknown);
2757 ok_ole_success(hr, IUnknown_QueryInterface IID_IClientSecurity);
2758 if (hr == S_OK) IUnknown_Release(pOtherUnknown);
2759
2760 hr = IUnknown_QueryInterface(pProxy, &IID_IMultiQI, (LPVOID*)&pOtherUnknown);
2761 ok_ole_success(hr, IUnknown_QueryInterface IID_IMultiQI);
2762 if (hr == S_OK) IUnknown_Release(pOtherUnknown);
2763
2764 hr = IUnknown_QueryInterface(pProxy, &IID_IMarshal, (LPVOID*)&pOtherUnknown);
2765 ok_ole_success(hr, IUnknown_QueryInterface IID_IMarshal);
2766 if (hr == S_OK) IUnknown_Release(pOtherUnknown);
2767
2768 /* IMarshal2 is also supported on NT-based systems, but is pretty much
2769 * useless as it has no more methods over IMarshal that it inherits from. */
2770
2771 IUnknown_Release(pProxy);
2772
2773 ok_no_locks();
2774
2776}
2777
2778typedef struct
2779{
2782} HeapUnknown;
2783
2785{
2786 return CONTAINING_RECORD(iface, HeapUnknown, IUnknown_iface);
2787}
2788
2790{
2792 {
2793 IUnknown_AddRef(iface);
2794 *ppv = iface;
2795 return S_OK;
2796 }
2797 *ppv = NULL;
2798 return E_NOINTERFACE;
2799}
2800
2802{
2804 return InterlockedIncrement((LONG*)&This->refs);
2805}
2806
2808{
2810 ULONG refs = InterlockedDecrement((LONG*)&This->refs);
2811 if (!refs) HeapFree(GetProcessHeap(), 0, This);
2812 return refs;
2813}
2814
2815static const IUnknownVtbl HeapUnknown_Vtbl =
2816{
2820};
2821
2823{
2824 HRESULT hr;
2825 IPSFactoryBuffer *psfb;
2827 LPVOID lpvtbl;
2828 ULONG refs;
2829 CLSID clsid;
2830 HeapUnknown *pUnkOuter = HeapAlloc(GetProcessHeap(), 0, sizeof(*pUnkOuter));
2831
2832 pUnkOuter->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl;
2833 pUnkOuter->refs = 1;
2834
2837
2838 hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (LPVOID*)&psfb);
2840
2841 hr = IPSFactoryBuffer_CreateProxy(psfb, &pUnkOuter->IUnknown_iface, riid, &proxy, &lpvtbl);
2842 ok_ole_success(hr, IPSFactoryBuffer_CreateProxy);
2843 ok(lpvtbl != NULL, "IPSFactoryBuffer_CreateProxy succeeded, but returned a NULL vtable!\n");
2844
2845 /* release our reference to the outer unknown object - the PS factory
2846 * buffer will have AddRef's it in the CreateProxy call */
2847 refs = IUnknown_Release(&pUnkOuter->IUnknown_iface);
2848 ok(refs == 1, "Ref count of outer unknown should have been 1 instead of %d\n", refs);
2849
2850 /* Not checking return, unreliable on native. Maybe it leaks references? */
2851 IPSFactoryBuffer_Release(psfb);
2852
2853 refs = IUnknown_Release((IUnknown *)lpvtbl);
2854 ok(refs == 0, "Ref-count leak of %d on IRpcProxyBuffer\n", refs);
2855
2856 refs = IRpcProxyBuffer_Release(proxy);
2857 ok(refs == 0, "Ref-count leak of %d on IRpcProxyBuffer\n", refs);
2858}
2859
2861{
2862 HRESULT hr;
2863 IPSFactoryBuffer *psfb;
2865 ULONG refs;
2866 CLSID clsid;
2867
2868 cLocks = 0;
2869
2872
2873 hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (LPVOID*)&psfb);
2875
2876 hr = IPSFactoryBuffer_CreateStub(psfb, riid, (IUnknown*)&Test_ClassFactory, &stub);
2877 ok_ole_success(hr, IPSFactoryBuffer_CreateStub);
2878
2879 /* Not checking return, unreliable on native. Maybe it leaks references? */
2880 IPSFactoryBuffer_Release(psfb);
2881
2883
2884 IRpcStubBuffer_Disconnect(stub);
2885
2886 ok_no_locks();
2887
2888 refs = IRpcStubBuffer_Release(stub);
2889 ok(refs == 0, "Ref-count leak of %d on IRpcProxyBuffer\n", refs);
2890}
2891
2893
2895 LPCLASSFACTORY iface,
2896 LPUNKNOWN pUnkOuter,
2897 REFIID riid,
2898 LPVOID *ppvObj)
2899{
2900 DWORD_PTR res;
2902 {
2904 ok(ret, "Timed out sending a message to originating window during RPC call\n");
2905 }
2906 *ppvObj = NULL;
2907 return S_FALSE;
2908}
2909
2910static const IClassFactoryVtbl TestREClassFactory_Vtbl =
2911{
2917};
2918
2920
2922{
2923 switch (msg)
2924 {
2925 case WM_USER:
2926 {
2927 HRESULT hr;
2928 IStream *pStream = NULL;
2931 DWORD tid;
2932 HANDLE thread;
2933
2934 cLocks = 0;
2935
2936 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2938 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&TestRE_ClassFactory, MSHLFLAGS_NORMAL, &thread);
2939
2941
2942 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2943 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&proxy);
2945 IStream_Release(pStream);
2946
2948
2949 /* note the use of the magic IID_IWineTest value to tell remote thread
2950 * to try to send a message back to us */
2951 hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IWineTest, (void **)&object);
2952 ok(hr == S_FALSE, "expected S_FALSE, got %d\n", hr);
2953
2954 IClassFactory_Release(proxy);
2955
2956 ok_no_locks();
2957
2959
2960 PostMessageA(hwnd, WM_QUIT, 0, 0);
2961
2962 return 0;
2963 }
2964 case WM_USER+1:
2965 {
2966 HRESULT hr;
2967 IStream *pStream = NULL;
2970 DWORD tid;
2971 HANDLE thread;
2972
2973 cLocks = 0;
2974
2975 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2977 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&TestRE_ClassFactory, MSHLFLAGS_NORMAL, &thread);
2978
2980
2981 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2982 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&proxy);
2984 IStream_Release(pStream);
2985
2987
2988 /* post quit message before a doing a COM call to show that a pending
2989 * WM_QUIT message doesn't stop the call from succeeding */
2990 PostMessageA(hwnd, WM_QUIT, 0, 0);
2991 hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IUnknown, (void **)&object);
2992 ok(hr == S_FALSE, "IClassFactory_CreateInstance returned 0x%08x, expected S_FALSE\n", hr);
2993
2994 IClassFactory_Release(proxy);
2995
2996 ok_no_locks();
2997
2999
3000 return 0;
3001 }
3002 case WM_USER+2:
3003 {
3004 HRESULT hr;
3005 IStream *pStream = NULL;
3008 DWORD tid;
3009 HANDLE thread;
3010
3011 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
3013 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
3014
3015 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
3016 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&proxy);
3018 IStream_Release(pStream);
3019
3020 /* shows that COM calls executed during the processing of sent
3021 * messages should fail */
3022 hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IUnknown, (void **)&object);
3024 "COM call during processing of sent message should return RPC_E_CANTCALLOUT_ININPUTSYNCCALL instead of 0x%08x\n", hr);
3025
3026 IClassFactory_Release(proxy);
3027
3029
3030 PostQuitMessage(0);
3031
3032 return 0;
3033 }
3034 default:
3035 return DefWindowProcA(hwnd, msg, wparam, lparam);
3036 }
3037}
3038
3039static void register_test_window(void)
3040{
3041 WNDCLASSA wndclass;
3042
3043 memset(&wndclass, 0, sizeof(wndclass));
3044 wndclass.lpfnWndProc = window_proc;
3045 wndclass.lpszClassName = "WineCOMTest";
3046 RegisterClassA(&wndclass);
3047}
3048
3050{
3051 MSG msg;
3052
3054 ok(hwnd_app != NULL, "Window creation failed\n");
3055
3056 /* start message re-entrancy test */
3058
3059 while (GetMessageA(&msg, NULL, 0, 0))
3060 {
3063 }
3065}
3066
3068 LPCLASSFACTORY iface,
3069 LPUNKNOWN pUnkOuter,
3070 REFIID riid,
3071 LPVOID *ppvObj)
3072{
3073 *ppvObj = NULL;
3074 SendMessageA(hwnd_app, WM_USER+2, 0, 0);
3075 return S_OK;
3076}
3077
3078static IClassFactoryVtbl TestMsgClassFactory_Vtbl =
3079{
3085};
3086
3088
3089static void test_call_from_message(void)
3090{
3091 MSG msg;
3092 IStream *pStream;
3093 HRESULT hr;
3095 DWORD tid;
3096 HANDLE thread;
3098
3100 ok(hwnd_app != NULL, "Window creation failed\n");
3101
3102 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
3104 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&TestMsg_ClassFactory, MSHLFLAGS_NORMAL, &thread);
3105
3107
3108 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
3109 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&proxy);
3111 IStream_Release(pStream);
3112
3114
3115 /* start message re-entrancy test */
3116 hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IUnknown, (void **)&object);
3117 ok_ole_success(hr, IClassFactory_CreateInstance);
3118
3119 IClassFactory_Release(proxy);
3120
3121 ok_no_locks();
3122
3124
3125 while (GetMessageA(&msg, NULL, 0, 0))
3126 {
3129 }
3131}
3132
3133static void test_WM_QUIT_handling(void)
3134{
3135 MSG msg;
3136
3138 ok(hwnd_app != NULL, "Window creation failed\n");
3139
3140 /* start WM_QUIT handling test */
3141 PostMessageA(hwnd_app, WM_USER+1, 0, 0);
3142
3143 while (GetMessageA(&msg, NULL, 0, 0))
3144 {
3147 }
3148}
3149
3151{
3152 static SIZE_T global_size_alignment = -1;
3153 if (global_size_alignment == -1)
3154 {
3155 void *p = GlobalAlloc(GMEM_FIXED, 1);
3156 global_size_alignment = GlobalSize(p);
3157 GlobalFree(p);
3158 }
3159
3160 return ((size + global_size_alignment - 1) & ~(global_size_alignment - 1));
3161}
3162
3163static void test_freethreadedmarshaldata(IStream *pStream, MSHCTX mshctx, void *ptr, DWORD mshlflags)
3164{
3165 HGLOBAL hglobal;
3166 DWORD size;
3167 char *marshal_data;
3168 HRESULT hr;
3169
3170 hr = GetHGlobalFromStream(pStream, &hglobal);
3172
3173 size = GlobalSize(hglobal);
3174
3175 marshal_data = GlobalLock(hglobal);
3176
3177 if (mshctx == MSHCTX_INPROC)
3178 {
3179 DWORD expected_size = round_global_size(3*sizeof(DWORD) + sizeof(GUID));
3180 ok(size == expected_size ||
3181 broken(size == (2*sizeof(DWORD))) /* Win9x & NT4 */,
3182 "size should have been %d instead of %d\n", expected_size, size);
3183
3184 ok(*(DWORD *)marshal_data == mshlflags, "expected 0x%x, but got 0x%x for mshctx\n", mshlflags, *(DWORD *)marshal_data);
3185 marshal_data += sizeof(DWORD);
3186 ok(*(void **)marshal_data == ptr, "expected %p, but got %p for mshctx\n", ptr, *(void **)marshal_data);
3187 marshal_data += sizeof(void *);
3188 if (sizeof(void*) == 4 && size >= 3*sizeof(DWORD))
3189 {
3190 ok(*(DWORD *)marshal_data == 0, "expected 0x0, but got 0x%x\n", *(DWORD *)marshal_data);
3191 marshal_data += sizeof(DWORD);
3192 }
3193 if (size >= 3*sizeof(DWORD) + sizeof(GUID))
3194 {
3195 trace("got guid data: %s\n", wine_dbgstr_guid((GUID *)marshal_data));
3196 }
3197 }
3198 else
3199 {
3200 ok(size > sizeof(DWORD), "size should have been > sizeof(DWORD), not %d\n", size);
3201 ok(*(DWORD *)marshal_data == 0x574f454d /* MEOW */,
3202 "marshal data should be filled by standard marshal and start with MEOW signature\n");
3203 }
3204
3205 GlobalUnlock(hglobal);
3206}
3207
3209{
3210 HRESULT hr;
3211 IUnknown *pFTUnknown;
3212 IMarshal *pFTMarshal;
3213 IStream *pStream;
3214 IUnknown *pProxy;
3215 static const LARGE_INTEGER llZero;
3216 CLSID clsid;
3217
3218 cLocks = 0;
3219 hr = CoCreateFreeThreadedMarshaler(NULL, &pFTUnknown);
3221 hr = IUnknown_QueryInterface(pFTUnknown, &IID_IMarshal, (void **)&pFTMarshal);
3222 ok_ole_success(hr, IUnknown_QueryInterface);
3223 IUnknown_Release(pFTUnknown);
3224
3225 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
3227
3228 /* inproc normal marshaling */
3229
3230 hr = IMarshal_GetUnmarshalClass(pFTMarshal, &IID_IClassFactory,
3231 &Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL, &clsid);
3232 ok_ole_success(hr, IMarshal_GetUnmarshalClass);
3233 ok(IsEqualIID(&clsid, &CLSID_InProcFreeMarshaler), "clsid = %s\n",
3235
3236 hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory,
3237 &Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
3238 ok_ole_success(hr, IMarshal_MarshalInterface);
3239
3241
3242 test_freethreadedmarshaldata(pStream, MSHCTX_INPROC, &Test_ClassFactory, MSHLFLAGS_NORMAL);
3243
3244 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3245 hr = IMarshal_UnmarshalInterface(pFTMarshal, pStream, &IID_IUnknown, (void **)&pProxy);
3246 ok_ole_success(hr, IMarshal_UnmarshalInterface);
3247
3248 IUnknown_Release(pProxy);
3249
3250 ok_no_locks();
3251
3252 /* inproc table-strong marshaling */
3253
3254 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3255 hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory,
3256 (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, (void *)0xdeadbeef,
3257 MSHLFLAGS_TABLESTRONG);
3258 ok_ole_success(hr, IMarshal_MarshalInterface);
3259
3261
3262 test_freethreadedmarshaldata(pStream, MSHCTX_INPROC, &Test_ClassFactory, MSHLFLAGS_TABLESTRONG);
3263
3264 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3265 hr = IMarshal_UnmarshalInterface(pFTMarshal, pStream, &IID_IUnknown, (void **)&pProxy);
3266 ok_ole_success(hr, IMarshal_UnmarshalInterface);
3267
3268 IUnknown_Release(pProxy);
3269
3271
3272 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3273 hr = IMarshal_ReleaseMarshalData(pFTMarshal, pStream);
3274 ok_ole_success(hr, IMarshal_ReleaseMarshalData);
3275
3276 ok_no_locks();
3277
3278 /* inproc table-weak marshaling */
3279
3280 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3281 hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory,
3282 (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, (void *)0xdeadbeef,
3283 MSHLFLAGS_TABLEWEAK);
3284 ok_ole_success(hr, IMarshal_MarshalInterface);
3285
3286 ok_no_locks();
3287
3288 test_freethreadedmarshaldata(pStream, MSHCTX_INPROC, &Test_ClassFactory, MSHLFLAGS_TABLEWEAK);
3289
3290 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3291 hr = IMarshal_UnmarshalInterface(pFTMarshal, pStream, &IID_IUnknown, (void **)&pProxy);
3292 ok_ole_success(hr, IMarshal_UnmarshalInterface);
3293
3295
3296 IUnknown_Release(pProxy);
3297
3298 ok_no_locks();
3299
3300 /* inproc normal marshaling (for extraordinary cases) */
3301
3302 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3303 hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory,
3304 &Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
3305 ok_ole_success(hr, IMarshal_MarshalInterface);
3306
3308
3309 /* this call shows that DisconnectObject does nothing */
3310 hr = IMarshal_DisconnectObject(pFTMarshal, 0);
3311 ok_ole_success(hr, IMarshal_DisconnectObject);
3312
3314
3315 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3316 hr = IMarshal_ReleaseMarshalData(pFTMarshal, pStream);
3317 ok_ole_success(hr, IMarshal_ReleaseMarshalData);
3318
3319 ok_no_locks();
3320
3321 /* doesn't enforce marshaling rules here and allows us to unmarshal the
3322 * interface, even though it was freed above */
3323 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3324 hr = IMarshal_UnmarshalInterface(pFTMarshal, pStream, &IID_IUnknown, (void **)&pProxy);
3325 ok_ole_success(hr, IMarshal_UnmarshalInterface);
3326
3327 ok_no_locks();
3328
3329 /* local normal marshaling */
3330
3331 hr = IMarshal_GetUnmarshalClass(pFTMarshal, &IID_IClassFactory,
3332 &Test_ClassFactory, MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL, &clsid);
3333 ok_ole_success(hr, IMarshal_GetUnmarshalClass);
3334 ok(IsEqualIID(&clsid, &CLSID_StdMarshal), "clsid = %s\n",
3336
3337 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3338 hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory, &Test_ClassFactory, MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
3339 ok_ole_success(hr, IMarshal_MarshalInterface);
3340
3342
3343 test_freethreadedmarshaldata(pStream, MSHCTX_LOCAL, &Test_ClassFactory, MSHLFLAGS_NORMAL);
3344
3345 IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
3346 hr = CoReleaseMarshalData(pStream);
3348
3349 ok_no_locks();
3350
3351 IStream_Release(pStream);
3352 IMarshal_Release(pFTMarshal);
3353}
3354
3356{
3357 HRESULT hr;
3358 char buffer[256];
3359 LPOLESTR pszClsid;
3360 HKEY hkey;
3361 DWORD dwDisposition;
3362 DWORD error;
3363
3364 hr = StringFromCLSID(&CLSID_WineTest, &pszClsid);
3365 ok_ole_success(hr, "StringFromCLSID");
3366 strcpy(buffer, "CLSID\\");
3367 WideCharToMultiByte(CP_ACP, 0, pszClsid, -1, buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), NULL, NULL);
3368 CoTaskMemFree(pszClsid);
3369 strcat(buffer, "\\InprocHandler32");
3370 if (Register)
3371 {
3372 error = RegCreateKeyExA(HKEY_CLASSES_ROOT, buffer, 0, NULL, 0, KEY_SET_VALUE, NULL, &hkey, &dwDisposition);
3374 {
3375 skip("Not authorized to modify the Classes key\n");
3376 return E_FAIL;
3377 }
3378 ok(error == ERROR_SUCCESS, "RegCreateKeyEx failed with error %d\n", error);
3379 if (error != ERROR_SUCCESS) hr = E_FAIL;
3380 error = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const unsigned char *)"\"ole32.dll\"", strlen("\"ole32.dll\"") + 1);
3381 ok(error == ERROR_SUCCESS, "RegSetValueEx failed with error %d\n", error);
3382 if (error != ERROR_SUCCESS) hr = E_FAIL;
3383 RegCloseKey(hkey);
3384 }
3385 else
3386 {
3388 *strrchr(buffer, '\\') = '\0';
3390 }
3391 return hr;
3392}
3393
3394static void test_inproc_handler(void)
3395{
3396 HRESULT hr;
3398 IUnknown *pObject2;
3399
3401 return;
3402
3403 hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void **)&pObject);
3404 ok_ole_success(hr, "CoCreateInstance");
3405
3406 if (SUCCEEDED(hr))
3407 {
3408 hr = IUnknown_QueryInterface(pObject, &IID_IWineTest, (void **)&pObject2);
3409 ok(hr == E_NOINTERFACE, "IUnknown_QueryInterface on handler for invalid interface returned 0x%08x instead of E_NOINTERFACE\n", hr);
3410
3411 /* it's a handler as it supports IOleObject */
3412 hr = IUnknown_QueryInterface(pObject, &IID_IOleObject, (void **)&pObject2);
3413 ok_ole_success(hr, "IUnknown_QueryInterface(&IID_IOleObject)");
3414 IUnknown_Release(pObject2);
3415
3416 IUnknown_Release(pObject);
3417 }
3418
3420}
3421
3423 IStdMarshalInfo *iface,
3424 REFIID riid,
3425 LPVOID *ppvObj)
3426{
3427 if (ppvObj == NULL) return E_POINTER;
3428
3429 if (IsEqualGUID(riid, &IID_IUnknown) ||
3430 IsEqualGUID(riid, &IID_IStdMarshalInfo))
3431 {
3432 *ppvObj = iface;
3433 IStdMarshalInfo_AddRef(iface);
3434 return S_OK;
3435 }
3436
3437 return E_NOINTERFACE;
3438}
3439
3441{
3442 LockModule();
3443 return 2; /* non-heap-based object */
3444}
3445
3447{
3448 UnlockModule();
3449 return 1; /* non-heap-based object */
3450}
3451
3453 IStdMarshalInfo *iface,
3454 DWORD dwDestContext,
3455 void *pvDestContext,
3456 CLSID *pClsid)
3457{
3458 *pClsid = CLSID_WineTest;
3459 return S_OK;
3460}
3461
3462static const IStdMarshalInfoVtbl Test_SMI_Vtbl =
3463{
3468};
3469
3471
3473{
3474 HRESULT hr;
3475 IStream *pStream = NULL;
3476 IUnknown *pProxy = NULL;
3478 DWORD tid;
3479 HANDLE thread;
3480 static const LARGE_INTEGER ullZero;
3481
3483 return;
3484 cLocks = 0;
3485
3486 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
3487 ok_ole_success(hr, "CreateStreamOnHGlobal");
3488 tid = start_host_object(pStream, &IID_IUnknown, (IUnknown*)&Test_SMI, MSHLFLAGS_NORMAL, &thread);
3489
3491
3492 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
3493 hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
3494 ok_ole_success(hr, "CoUnmarshalInterface");
3495 IStream_Release(pStream);
3496
3497 if(hr == S_OK)
3498 {
3500
3501 hr = IUnknown_QueryInterface(pProxy, &IID_IWineTest, (void **)&pObject);
3502 ok(hr == E_NOINTERFACE, "IUnknown_QueryInterface with unknown IID should have returned E_NOINTERFACE instead of 0x%08x\n", hr);
3503
3504 /* it's a handler as it supports IOleObject */
3505 hr = IUnknown_QueryInterface(pProxy, &IID_IOleObject, (void **)&pObject);
3506 todo_wine
3507 ok_ole_success(hr, "IUnknown_QueryInterface(&IID_IOleObject)");
3508 if (SUCCEEDED(hr)) IUnknown_Release(pObject);
3509
3510 IUnknown_Release(pProxy);
3511
3512 ok_no_locks();
3513 }
3514
3517
3518 /* FIXME: test IPersist interface has the same effect as IStdMarshalInfo */
3519}
3520
3521
3522static void test_client_security(void)
3523{
3524 HRESULT hr;
3525 IStream *pStream = NULL;
3526 IClassFactory *pProxy = NULL;
3527 IUnknown *pProxy2 = NULL;
3528 IUnknown *pUnknown1 = NULL;
3529 IUnknown *pUnknown2 = NULL;
3530 IClientSecurity *pCliSec = NULL;
3531 IMarshal *pMarshal;
3532 DWORD tid;
3533 HANDLE thread;
3534 static const LARGE_INTEGER ullZero;
3535 DWORD dwAuthnSvc;
3536 DWORD dwAuthzSvc;
3537 OLECHAR *pServerPrincName;
3538 DWORD dwAuthnLevel;
3539 DWORD dwImpLevel;
3540 void *pAuthInfo;
3541 DWORD dwCapabilities;
3542 void *pv;
3543
3544 cLocks = 0;
3545
3546 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
3547 ok_ole_success(hr, "CreateStreamOnHGlobal");
3548 tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
3549
3550 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
3551 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
3552 ok_ole_success(hr, "CoUnmarshalInterface");
3553 IStream_Release(pStream);
3554
3555 hr = IClassFactory_QueryInterface(pProxy, &IID_IUnknown, (LPVOID*)&pUnknown1);
3556 ok_ole_success(hr, "IUnknown_QueryInterface IID_IUnknown");
3557
3558 hr = IClassFactory_QueryInterface(pProxy, &IID_IRemUnknown, (LPVOID*)&pProxy2);
3559 ok_ole_success(hr, "IUnknown_QueryInterface IID_IStream");
3560
3561 hr = IUnknown_QueryInterface(pProxy2, &IID_IUnknown, (LPVOID*)&pUnknown2);
3562 ok_ole_success(hr, "IUnknown_QueryInterface IID_IUnknown");
3563
3564 ok(pUnknown1 == pUnknown2, "both proxy's IUnknowns should be the same - %p, %p\n", pUnknown1, pUnknown2);
3565
3566 hr = IClassFactory_QueryInterface(pProxy, &IID_IMarshal, (LPVOID*)&pMarshal);
3567 ok_ole_success(hr, "IUnknown_QueryInterface IID_IMarshal");
3568
3569 hr = IClassFactory_QueryInterface(pProxy, &IID_IClientSecurity, (LPVOID*)&pCliSec);
3570 ok_ole_success(hr, "IUnknown_QueryInterface IID_IClientSecurity");
3571
3572 hr = IClientSecurity_QueryBlanket(pCliSec, (IUnknown *)pProxy, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
3573 todo_wine ok_ole_success(hr, "IClientSecurity_QueryBlanket (all NULLs)");
3574
3575 hr = IClientSecurity_QueryBlanket(pCliSec, (IUnknown *)pMarshal, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
3576 todo_wine ok(hr == E_NOINTERFACE, "IClientSecurity_QueryBlanket with local interface should have returned E_NOINTERFACE instead of 0x%08x\n", hr);
3577
3578 hr = IClientSecurity_QueryBlanket(pCliSec, (IUnknown *)pProxy, &dwAuthnSvc, &dwAuthzSvc, &pServerPrincName, &dwAuthnLevel, &dwImpLevel, &pAuthInfo, &dwCapabilities);
3579 todo_wine ok_ole_success(hr, "IClientSecurity_QueryBlanket");
3580
3581 hr = IClientSecurity_SetBlanket(pCliSec, (IUnknown *)pProxy, dwAuthnSvc, dwAuthzSvc, pServerPrincName, dwAuthnLevel, RPC_C_IMP_LEVEL_IMPERSONATE, pAuthInfo, dwCapabilities);
3582 todo_wine ok_ole_success(hr, "IClientSecurity_SetBlanket");
3583
3584 hr = IClassFactory_CreateInstance(pProxy, NULL, &IID_IWineTest, &pv);
3585 ok(hr == E_NOINTERFACE, "COM call should have succeeded instead of returning 0x%08x\n", hr);
3586
3587 hr = IClientSecurity_SetBlanket(pCliSec, (IUnknown *)pMarshal, dwAuthnSvc, dwAuthzSvc, pServerPrincName, dwAuthnLevel, dwImpLevel, pAuthInfo, dwCapabilities);
3588 todo_wine ok(hr == E_NOINTERFACE, "IClientSecurity_SetBlanket with local interface should have returned E_NOINTERFACE instead of 0x%08x\n", hr);
3589
3590 hr = IClientSecurity_SetBlanket(pCliSec, (IUnknown *)pProxy, 0xdeadbeef, dwAuthzSvc, pServerPrincName, dwAuthnLevel, dwImpLevel, pAuthInfo, dwCapabilities);
3591 todo_wine ok(hr == E_INVALIDARG, "IClientSecurity_SetBlanke with invalid dwAuthnSvc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
3592
3593 CoTaskMemFree(pServerPrincName);
3594
3595 hr = IClientSecurity_QueryBlanket(pCliSec, pUnknown1, &dwAuthnSvc, &dwAuthzSvc, &pServerPrincName, &dwAuthnLevel, &dwImpLevel, &pAuthInfo, &dwCapabilities);
3596 todo_wine ok_ole_success(hr, "IClientSecurity_QueryBlanket(IUnknown)");
3597
3598 CoTaskMemFree(pServerPrincName);
3599
3600 IClassFactory_Release(pProxy);
3601 IUnknown_Release(pProxy2);
3602 IUnknown_Release(pUnknown1);
3603 IUnknown_Release(pUnknown2);
3604 IMarshal_Release(pMarshal);
3605 IClientSecurity_Release(pCliSec);
3606
3608}
3609
3611
3612static void LockModuleOOP(void)
3613{
3614 InterlockedIncrement(&cLocks); /* for test purposes only */
3616}
3617
3618static void UnlockModuleOOP(void)
3619{
3620 InterlockedDecrement(&cLocks); /* for test purposes only */
3623}
3624
3625static HWND hwnd_app;
3626
3628{
3629 IPersist IPersist_iface; /* a nice short interface */
3630};
3631
3633{
3634 *obj = NULL;
3635
3636 if (IsEqualGUID(iid, &IID_IUnknown) ||
3638 *obj = iface;
3639
3640 if (*obj)
3641 {
3642 IPersist_AddRef(iface);
3643 return S_OK;
3644 }
3645 return E_NOINTERFACE;
3646}
3647
3649{
3650 return 2;
3651}
3652
3654{
3655 return 1;
3656}
3657
3659{
3660 HRESULT hr;
3661
3663
3664 /* Test calling CoDisconnectObject within a COM call */
3665 hr = CoDisconnectObject((IUnknown *)iface, 0);
3666 ok(hr == S_OK, "got %08x\n", hr);
3667
3668 /* Initialize and uninitialize the apartment to show that we
3669 * remain in the autojoined mta */
3670 hr = pCoInitializeEx( NULL, COINIT_MULTITHREADED );
3671 ok( hr == S_FALSE, "got %08x\n", hr );
3673
3674 return S_OK;
3675}
3676
3677static const IPersistVtbl local_server_persist_vtbl =
3678{
3683};
3684
3686{
3688};
3689
3691 LPCLASSFACTORY iface,
3692 REFIID riid,
3693 LPVOID *ppvObj)
3694{
3695 if (ppvObj == NULL) return E_POINTER;
3696
3697 if (IsEqualGUID(riid, &IID_IUnknown) ||
3699 {
3700 *ppvObj = iface;
3701 IClassFactory_AddRef(iface);
3702 return S_OK;
3703 }
3704
3705 return E_NOINTERFACE;
3706}
3707
3708static ULONG WINAPI TestOOP_IClassFactory_AddRef(LPCLASSFACTORY iface)
3709{
3710 return 2; /* non-heap-based object */
3711}
3712
3713static ULONG WINAPI TestOOP_IClassFactory_Release(LPCLASSFACTORY iface)
3714{
3715 return 1; /* non-heap-based object */
3716}
3717
3719 LPCLASSFACTORY iface,
3720 LPUNKNOWN pUnkOuter,
3721 REFIID riid,
3722 LPVOID *ppvObj)
3723{
3724 IPersist *persist = &local_server_class.IPersist_iface;
3725 HRESULT hr;
3726 IPersist_AddRef( persist );
3727 hr = IPersist_QueryInterface( persist, riid, ppvObj );
3728 IPersist_Release( persist );
3729 return hr;
3730}
3731
3733 LPCLASSFACTORY iface,
3734 BOOL fLock)
3735{
3736 if (fLock)
3737 LockModuleOOP();
3738 else
3740 return S_OK;
3741}
3742
3743static const IClassFactoryVtbl TestClassFactoryOOP_Vtbl =
3744{
3750};
3751
3753
3755{
3756 DWORD cookie;
3757 HRESULT hr;
3758 HANDLE ready_event;
3759 DWORD wait;
3760 HANDLE handles[2];
3761
3763 ready_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Ready Event");
3764 handles[0] = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Quit Event");
3765 handles[1] = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Repeat Event");
3766
3767again:
3769 CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
3771
3772 SetEvent(ready_event);
3773
3774 do
3775 {
3777 if (wait == WAIT_OBJECT_0+2)
3778 {
3779 MSG msg;
3780
3781 if (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
3782 {
3783 trace("Message 0x%x\n", msg.message);
3786 }
3787 }
3788 else if (wait == WAIT_OBJECT_0+1)
3789 {
3792 goto again;
3793 }
3794 }
3795 while (wait == WAIT_OBJECT_0+2);
3796
3797 ok( wait == WAIT_OBJECT_0, "quit event wait timed out\n" );
3800 CloseHandle(handles[0]);
3801 CloseHandle(handles[1]);
3802}
3803
3805{
3806 char **argv;
3807 char cmdline[MAX_PATH];
3808 BOOL ret;
3810 STARTUPINFOA si = { 0 };
3811 si.cb = sizeof(si);
3812
3813 pi.hThread = NULL;
3814 pi.hProcess = NULL;
3816 sprintf(cmdline, "\"%s\" %s %s", argv[0], argv[1], arg);
3817 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
3818 ok(ret, "CreateProcess failed with error: %u\n", GetLastError());
3819 if (pi.hThread) CloseHandle(pi.hThread);
3820 return pi.hProcess;
3821}
3822
3823/* tests functions commonly used by out of process COM servers */
3824static void test_local_server(void)
3825{
3826 DWORD cookie;
3827 HRESULT hr;
3828 IClassFactory * cf;
3829 IPersist *persist;
3830 DWORD ret;
3832 HANDLE quit_event;
3833 HANDLE ready_event;
3834 HANDLE repeat_event;
3835 CLSID clsid;
3836
3838
3839 cLocks = 0;
3840
3841 /* Start the object suspended */
3843 CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED, &cookie);
3845
3846 /* ... and CoGetClassObject does not find it and fails when it looks for the
3847 * class in the registry */
3848 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER,
3850 ok(hr == REGDB_E_CLASSNOTREG || /* NT */
3851 hr == S_OK /* Win9x */,
3852 "CoGetClassObject should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
3853
3854 /* Resume the object suspended above ... */
3857
3858 /* ... and now it should succeed */
3859 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER,
3862
3863 /* Now check the locking is working */
3864 /* NOTE: we are accessing the class directly, not through a proxy */
3865
3866 ok_no_locks();
3867
3868 hr = IClassFactory_LockServer(cf, TRUE);
3869 ok_ole_success(hr, IClassFactory_LockServer);
3870
3872
3873 IClassFactory_LockServer(cf, FALSE);
3874 ok_ole_success(hr, IClassFactory_LockServer);
3875
3876 ok_no_locks();
3877
3878 IClassFactory_Release(cf);
3879
3880 /* wait for shutdown signal */
3882 ok(ret != WAIT_TIMEOUT, "Server didn't shut down\n");
3883
3884 /* try to connect again after SCM has suspended registered class objects */
3885 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, NULL,
3887 ok(hr == CO_E_SERVER_STOPPING || /* NT */
3888 hr == REGDB_E_CLASSNOTREG || /* win2k */
3889 hr == S_OK /* Win9x */,
3890 "CoGetClassObject should have returned CO_E_SERVER_STOPPING or REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
3891
3894
3896
3897 process = create_target_process("-Embedding");
3898 ok(process != NULL, "couldn't start local server process, error was %d\n", GetLastError());
3899
3900 ready_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Ready Event");
3901 ok( !WaitForSingleObject(ready_event, 10000), "wait timed out\n" );
3902
3903 hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IPersist, (void **)&persist);
3905
3906 IPersist_Release(persist);
3907
3908 hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IPersist, (void **)&persist);
3909 ok(hr == REGDB_E_CLASSNOTREG, "Second CoCreateInstance on REGCLS_SINGLEUSE object should have failed\n");
3910
3911 /* Re-register the class and try calling CoDisconnectObject from within a call to that object */
3912 repeat_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Repeat Event");
3913 SetEvent(repeat_event);
3914 CloseHandle(repeat_event);
3915
3916 ok( !WaitForSingleObject(ready_event, 10000), "wait timed out\n" );
3917 CloseHandle(ready_event);
3918
3919 hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IPersist, (void **)&persist);
3921
3922 /* GetClassID will call CoDisconnectObject */
3923 IPersist_GetClassID(persist, &clsid);
3924 IPersist_Release(persist);
3925
3926 quit_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Quit Event");
3927 SetEvent(quit_event);
3928
3930 CloseHandle(quit_event);
3932}
3933
3935{
3938};
3939
3941{
3942 HRESULT hr;
3943 struct git_params *params = pv;
3945
3946 hr = IGlobalInterfaceTable_GetInterfaceFromGlobal(params->git, params->cookie, &IID_IClassFactory, (void **)&cf);
3948 broken(hr == E_UNEXPECTED) /* win2k */ ||
3949 broken(hr == S_OK) /* NT 4 */,
3950 "IGlobalInterfaceTable_GetInterfaceFromGlobal should have failed with error CO_E_NOTINITIALIZED or E_UNEXPECTED instead of 0x%08x\n",
3951 hr);
3952 if (hr == S_OK)
3953 IClassFactory_Release(cf);
3954
3956
3957 hr = IGlobalInterfaceTable_GetInterfaceFromGlobal(params->git, params->cookie, &IID_IClassFactory, (void **)&cf);
3958 ok_ole_success(hr, IGlobalInterfaceTable_GetInterfaceFromGlobal);
3959
3960 IClassFactory_Release(cf);
3961
3963
3964 return hr;
3965}
3966
3968{
3969 HRESULT hr;
3971 DWORD cookie;
3972 HANDLE thread;
3973 DWORD tid;
3974 struct git_params params;
3975 DWORD ret;
3978 ULONG ref;
3979
3980 trace("test_globalinterfacetable\n");
3981 cLocks = 0;
3982
3983 hr = pDllGetClassObject(&CLSID_StdGlobalInterfaceTable, &IID_IClassFactory, (void**)&cf);
3984 ok(hr == S_OK, "got 0x%08x\n", hr);
3985
3986 hr = IClassFactory_QueryInterface(cf, &IID_IGlobalInterfaceTable, (void**)&object);
3987 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
3988
3989 IClassFactory_Release(cf);
3990
3991 hr = CoCreateInstance(&CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, &IID_IGlobalInterfaceTable, (void **)&git);
3993
3994 ref = IGlobalInterfaceTable_AddRef(git);
3995 ok(ref == 1, "ref=%d\n", ref);
3996 ref = IGlobalInterfaceTable_AddRef(git);
3997 ok(ref == 1, "ref=%d\n", ref);
3998
3999 ref = IGlobalInterfaceTable_Release(git);
4000 ok(ref == 1, "ref=%d\n", ref);
4001 ref = IGlobalInterfaceTable_Release(git);
4002 ok(ref == 1, "ref=%d\n", ref);
4003
4004 hr = IGlobalInterfaceTable_RegisterInterfaceInGlobal(git, (IUnknown *)&Test_ClassFactory, &IID_IClassFactory, &cookie);
4005 ok_ole_success(hr, IGlobalInterfaceTable_RegisterInterfaceInGlobal);
4006
4008
4009 params.cookie = cookie;
4010 params.git = git;
4011 /* note: params is on stack so we MUST wait for get_global_interface_proc
4012 * to exit before we can return */
4014
4016 while (ret == WAIT_OBJECT_0 + 1)
4017 {
4018 MSG msg;
4019 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
4022 }
4023
4025
4026 /* test getting interface from global with different iid */
4027 hr = IGlobalInterfaceTable_GetInterfaceFromGlobal(git, cookie, &IID_IUnknown, (void **)&object);
4028 ok_ole_success(hr, IGlobalInterfaceTable_GetInterfaceFromGlobal);
4029 IUnknown_Release(object);
4030
4031 /* test getting interface from global with same iid */
4032 hr = IGlobalInterfaceTable_GetInterfaceFromGlobal(git, cookie, &IID_IClassFactory, (void **)&object);
4033 ok_ole_success(hr, IGlobalInterfaceTable_GetInterfaceFromGlobal);
4034 IUnknown_Release(object);
4035
4036 hr = IGlobalInterfaceTable_RevokeInterfaceFromGlobal(git, cookie);
4037 ok_ole_success(hr, IGlobalInterfaceTable_RevokeInterfaceFromGlobal);
4038
4039 ok_no_locks();
4040
4041 IGlobalInterfaceTable_Release(git);
4042}
4043
4044static void test_manualresetevent(void)
4045{
4046 ISynchronizeHandle *sync_handle;
4047 ISynchronize *psync1, *psync2;
4048 IUnknown *punk;
4049 HANDLE handle;
4050 LONG ref;
4051 HRESULT hr;
4052
4053 hr = CoCreateInstance(&CLSID_ManualResetEvent, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&punk);
4054 ok(hr == S_OK, "Got 0x%08x\n", hr);
4055 ok(!!punk, "Got NULL.\n");
4056 IUnknown_Release(punk);
4057
4058 hr = CoCreateInstance(&CLSID_ManualResetEvent, NULL, CLSCTX_INPROC_SERVER, &IID_ISynchronize, (void**)&psync1);
4059 ok(hr == S_OK, "Got 0x%08x\n", hr);
4060 ok(!!psync1, "Got NULL.\n");
4061
4062 hr = ISynchronize_Wait(psync1, 0, 5);
4063 ok(hr == RPC_S_CALLPENDING, "Got 0x%08x\n", hr);
4064
4065 hr = ISynchronize_Reset(psync1);
4066 ok(hr == S_OK, "Got 0x%08x\n", hr);
4067 hr = ISynchronize_Signal(psync1);
4068 ok(hr == S_OK, "Got 0x%08x\n", hr);
4069 hr = ISynchronize_Wait(psync1, 0, 5);
4070 ok(hr == S_OK, "Got 0x%08x\n", hr);
4071 hr = ISynchronize_Wait(psync1, 0, 5);
4072 ok(hr == S_OK, "Got 0x%08x\n", hr);
4073 hr = ISynchronize_Reset(psync1);
4074 ok(hr == S_OK, "Got 0x%08x\n", hr);
4075 hr = ISynchronize_Wait(psync1, 0, 5);
4076 ok(hr == RPC_S_CALLPENDING, "Got 0x%08x\n", hr);
4077
4078 hr = CoCreateInstance(&CLSID_ManualResetEvent, NULL, CLSCTX_INPROC_SERVER, &IID_ISynchronize, (void**)&psync2);
4079 ok(hr == S_OK, "Got 0x%08x\n", hr);
4080 ok(!!psync2, "Got NULL.\n");
4081 ok(psync1 != psync2, "psync1 == psync2.\n");
4082
4083 hr = ISynchronize_QueryInterface(psync2, &IID_ISynchronizeHandle, (void**)&sync_handle);
4084 ok(hr == S_OK, "QueryInterface(IID_ISynchronizeHandle) failed: %08x\n", hr);
4085
4086 handle = NULL;
4087 hr = ISynchronizeHandle_GetHandle(sync_handle, &handle);
4088 ok(hr == S_OK, "GetHandle failed: %08x\n", hr);
4089 ok(handle != NULL && handle != INVALID_HANDLE_VALUE, "handle = %p\n", handle);
4090
4091 ISynchronizeHandle_Release(sync_handle);
4092
4093 hr = ISynchronize_Wait(psync2, 0, 5);
4094 ok(hr == RPC_S_CALLPENDING, "Got 0x%08x\n", hr);
4095
4096 hr = ISynchronize_Reset(psync1);
4097 ok(hr == S_OK, "Got 0x%08x\n", hr);
4098 hr = ISynchronize_Reset(psync2);
4099 ok(hr == S_OK, "Got 0x%08x\n", hr);
4100 hr = ISynchronize_Signal(psync1);
4101 ok(hr == S_OK, "Got 0x%08x\n", hr);
4102 hr = ISynchronize_Wait(psync2, 0, 5);
4103 ok(hr == RPC_S_CALLPENDING, "Got 0x%08x\n", hr);
4104
4105 ref = ISynchronize_AddRef(psync1);
4106 ok(ref == 2, "Got ref: %d\n", ref);
4107 ref = ISynchronize_AddRef(psync1);
4108 ok(ref == 3, "Got ref: %d\n", ref);
4109 ref = ISynchronize_Release(psync1);
4110 ok(ref == 2, "Got nonzero ref: %d\n", ref);
4111 ref = ISynchronize_Release(psync2);
4112 ok(!ref, "Got nonzero ref: %d\n", ref);
4113 ref = ISynchronize_Release(psync1);
4114 ok(ref == 1, "Got nonzero ref: %d\n", ref);
4115 ref = ISynchronize_Release(psync1);
4116 ok(!ref, "Got nonzero ref: %d\n", ref);
4117}
4118
4120{
4121 IStream *stream = param;
4123 IUnknown *proxy;
4124 HRESULT hr;
4125
4126 IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
4129
4130 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy);
4131 ok_ole_success(hr, IClassFactory_CreateInstance);
4132
4133 IUnknown_Release(proxy);
4134
4135 /* But if we initialize an STA in this apartment, it becomes the wrong one. */
4137
4138 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy);
4139 ok(hr == RPC_E_WRONG_THREAD, "got %#x\n", hr);
4140
4142
4145
4146 IClassFactory_Release(cf);
4147
4148 ok_no_locks();
4151 return 0;
4152}
4153
4155{
4157 IUnknown *proxy;
4158 HRESULT hr;
4159
4160 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy);
4161 ok_ole_success(hr, IClassFactory_CreateInstance);
4162
4163 IUnknown_Release(proxy);
4164
4165 /* But if we initialize an STA in this apartment, it becomes the wrong one. */
4167
4168 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy);
4169 ok(hr == RPC_E_WRONG_THREAD, "got %#x\n", hr);
4170
4172 return 0;
4173}
4174
4176{
4180};
4181
4183{
4185 HRESULT hr;
4186
4188 (IUnknown *)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
4190
4191 SetEvent(data->start);
4192
4193 ok(!WaitForSingleObject(data->stop, 1000), "wait failed\n");
4194 return 0;
4195}
4196
4197static void test_implicit_mta(void)
4198{
4200 HANDLE host_thread, thread;
4202 IUnknown *proxy;
4203 IStream *stream;
4204 HRESULT hr;
4205 DWORD tid;
4206
4207 cLocks = 0;
4209
4211
4212 /* Firstly: we can unmarshal and use an object while in the implicit MTA. */
4215 tid = start_host_object(stream, &IID_IClassFactory, (IUnknown *)&Test_ClassFactory, MSHLFLAGS_NORMAL, &host_thread);
4216
4219
4221 ok(!WaitForSingleObject(thread, 1000), "wait failed\n");
4223
4224 IStream_Release(stream);
4225 end_host_object(tid, host_thread);
4226
4227 /* Secondly: we can unmarshal an object into the real MTA and then use it
4228 * from the implicit MTA. */
4231 tid = start_host_object(stream, &IID_IClassFactory, (IUnknown *)&Test_ClassFactory, MSHLFLAGS_NORMAL, &host_thread);
4232
4235
4236 IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
4239
4241 ok(!WaitForSingleObject(thread, 1000), "wait failed\n");
4243
4244 IClassFactory_Release(cf);
4245 IStream_Release(stream);
4246
4247 ok_no_locks();
4250
4251 end_host_object(tid, host_thread);
4252
4253 /* Thirdly: we can marshal an object from the implicit MTA and then
4254 * unmarshal it into the real one. */
4255 data.start = CreateEventA(NULL, FALSE, FALSE, NULL);
4256 data.stop = CreateEventA(NULL, FALSE, FALSE, NULL);
4257
4258 hr = CreateStreamOnHGlobal(NULL, TRUE, &data.stream);
4260
4262 ok(!WaitForSingleObject(data.start, 1000), "wait failed\n");
4263
4264 IStream_Seek(data.stream, ullZero, STREAM_SEEK_SET, NULL);
4265 hr = CoUnmarshalInterface(data.stream, &IID_IClassFactory, (void **)&cf);
4267
4268 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy);
4269 ok_ole_success(hr, IClassFactory_CreateInstance);
4270
4271 IUnknown_Release(proxy);
4272
4273 SetEvent(data.stop);
4274 ok(!WaitForSingleObject(thread, 1000), "wait failed\n");
4276
4277 IStream_Release(data.stream);
4278
4280}
4281
4282static const char *debugstr_iid(REFIID riid)
4283{
4284 static char name[256];
4285 HKEY hkeyInterface;
4286 WCHAR bufferW[39];
4287 char buffer[39];
4288 LONG name_size = sizeof(name);
4289 StringFromGUID2(riid, bufferW, ARRAY_SIZE(bufferW));
4290 WideCharToMultiByte(CP_ACP, 0, bufferW, ARRAY_SIZE(bufferW), buffer, sizeof(buffer), NULL, NULL);
4291 if (RegOpenKeyExA(HKEY_CLASSES_ROOT, "Interface", 0, KEY_QUERY_VALUE, &hkeyInterface) != ERROR_SUCCESS)
4292 {
4293 memcpy(name, buffer, sizeof(buffer));
4294 goto done;
4295 }
4296 if (RegQueryValueA(hkeyInterface, buffer, name, &name_size) != ERROR_SUCCESS)
4297 {
4298 memcpy(name, buffer, sizeof(buffer));
4299 goto done;
4300 }
4301 RegCloseKey(hkeyInterface);
4302done:
4303 return name;
4304}
4305
4307{
4308 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IChannelHook))
4309 {
4310 *ppv = iface;
4311 IChannelHook_AddRef(iface);
4312 return S_OK;
4313 }
4314
4315 *ppv = NULL;
4316 return E_NOINTERFACE;
4317}
4318
4320{
4321 return 2;
4322}
4323
4325{
4326 return 1;
4327}
4328
4330static int method, server_tid;
4332
4334{
4340};
4341
4343 IChannelHook *iface,
4344 REFGUID uExtent,
4345 REFIID riid,
4346 ULONG *pDataSize )
4347{
4348 SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
4349 trace("TestChannelHook_ClientGetSize\n");
4350 trace("\t%s\n", debugstr_iid(riid));
4351 if (info->cbSize != sizeof(*info))
4353
4354 if (!new_hook_struct)
4355 {
4356 ok(info->cbSize == sizeof(*info), "cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
4357 ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
4358 ok(info->iMethod == method, "iMethod was %d should be %d\n", info->iMethod, method);
4359 ok(!info->pObject, "pObject should be NULL\n");
4360 if (method == 3)
4361 causality = info->uCausality;
4362 else
4363 ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
4364 }
4365 else
4366 {
4367 struct new_hook_info *new_info = (struct new_hook_info *)riid;
4368 ok(new_info->server_pid == GetCurrentProcessId(), "server pid was 0x%x instead of 0x%x\n", new_info->server_pid,
4370 ok(new_info->server_tid == server_tid, "server tid was 0x%x instead of 0x%x\n", new_info->server_tid,
4371 server_tid);
4372 ok(new_info->method == method, "method was %d instead of %d\n", new_info->method, method);
4373 if (method == 3)
4374 causality = new_info->causality;
4375 else
4376 ok(IsEqualGUID(&new_info->causality, &causality), "causality wasn't correct\n");
4377 }
4378
4379 ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
4380
4381 *pDataSize = 1;
4382}
4383
4385 IChannelHook *iface,
4386 REFGUID uExtent,
4387 REFIID riid,
4388 ULONG *pDataSize,
4389 void *pDataBuffer )
4390{
4391 SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
4392 trace("TestChannelHook_ClientFillBuffer\n");
4393
4394 if (!new_hook_struct)
4395 {
4396 ok(info->cbSize == sizeof(*info), "cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
4397 ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
4398 ok(info->iMethod == method, "iMethod was %d should be %d\n", info->iMethod, method);
4399 ok(!info->pObject, "pObject should be NULL\n");
4400 ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
4401 }
4402 else
4403 {
4404 struct new_hook_info *new_info = (struct new_hook_info *)riid;
4405 ok(new_info->server_pid == GetCurrentProcessId(), "server pid was 0x%x instead of 0x%x\n", new_info->server_pid,
4407 ok(new_info->server_tid == server_tid, "server tid was 0x%x instead of 0x%x\n", new_info->server_tid,
4408 server_tid);
4409 ok(new_info->method == method, "method was %d instead of %d\n", new_info->method, method);
4410 ok(IsEqualGUID(&new_info->causality, &causality), "causality wasn't correct\n");
4411 }
4412
4413 ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
4414
4415 *(unsigned char *)pDataBuffer = 0xcc;
4416 *pDataSize = 1;
4417}
4418
4420 IChannelHook *iface,
4421 REFGUID uExtent,
4422 REFIID riid,
4423 ULONG cbDataSize,
4424 void *pDataBuffer,
4425 DWORD lDataRep,
4426 HRESULT hrFault )
4427{
4428 SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
4429 trace("TestChannelHook_ClientNotify hrFault = 0x%08x\n", hrFault);
4430
4431 if (!new_hook_struct)
4432 {
4433 ok(info->cbSize == sizeof(*info), "cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
4434 ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
4435 ok(info->iMethod == method, "iMethod was %d should be %d\n", info->iMethod, method);
4436 todo_wine {
4437 ok(info->pObject != NULL, "pObject shouldn't be NULL\n");
4438 }
4439 ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
4440 }
4441 else
4442 {
4443 struct new_hook_info *new_info = (struct new_hook_info *)riid;
4444 ok(new_info->server_pid == GetCurrentProcessId(), "server pid was 0x%x instead of 0x%x\n", new_info->server_pid,
4446 ok(new_info->server_tid == server_tid, "server tid was 0x%x instead of 0x%x\n", new_info->server_tid,
4447 server_tid);
4448 ok(new_info->method == method, "method was %d instead of %d\n", new_info->method, method);
4449 ok(IsEqualGUID(&new_info->causality, &causality), "causality wasn't correct\n");
4450 }
4451
4452 ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
4453}
4454
4456 IChannelHook *iface,
4457 REFGUID uExtent,
4458 REFIID riid,
4459 ULONG cbDataSize,
4460 void *pDataBuffer,
4461 DWORD lDataRep )
4462{
4463 SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
4464 trace("TestChannelHook_ServerNotify\n");
4465
4466 if (!new_hook_struct)
4467 {
4468 ok(info->cbSize == sizeof(*info), "cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
4469 ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
4470 ok(info->iMethod == method, "iMethod was %d should be %d\n", info->iMethod, method);
4471 ok(info->pObject != NULL, "pObject shouldn't be NULL\n");
4472 ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
4473 }
4474 else
4475 {
4476 struct new_hook_info *new_info = (struct new_hook_info *)riid;
4477 ok(new_info->server_pid == GetCurrentProcessId(), "server pid was 0x%x instead of 0x%x\n", new_info->server_pid,
4479 ok(new_info->server_tid == server_tid, "server tid was 0x%x instead of 0x%x\n", new_info->server_tid,
4480 server_tid);
4481 ok(new_info->method == method, "method was %d instead of %d\n", new_info->method, method);
4482 ok(IsEqualGUID(&new_info->causality, &causality), "causality wasn't correct\n");
4483 }
4484
4485 ok(cbDataSize == 1, "cbDataSize should have been 1 instead of %d\n", cbDataSize);
4486 ok(*(unsigned char *)pDataBuffer == 0xcc, "pDataBuffer should have contained 0xcc instead of 0x%x\n", *(unsigned char *)pDataBuffer);
4487 ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
4488}
4489
4491 IChannelHook *iface,
4492 REFGUID uExtent,
4493 REFIID riid,
4494 HRESULT hrFault,
4495 ULONG *pDataSize )
4496{
4497 SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
4498 trace("TestChannelHook_ServerGetSize\n");
4499 trace("\t%s\n", debugstr_iid(riid));
4500 if (!new_hook_struct)
4501 {
4502 ok(info->cbSize == sizeof(*info), "cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
4503 ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
4504 ok(info->iMethod == method, "iMethod was %d should be %d\n", info->iMethod, method);
4505 ok(info->pObject != NULL, "pObject shouldn't be NULL\n");
4506 ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
4507 }
4508 else
4509 {
4510 struct new_hook_info *new_info = (struct new_hook_info *)riid;
4511 ok(new_info->server_pid == GetCurrentProcessId(), "server pid was 0x%x instead of 0x%x\n", new_info->server_pid,
4513 ok(new_info->server_tid == server_tid, "server tid was 0x%x instead of 0x%x\n", new_info->server_tid,
4514 server_tid);
4515 ok(new_info->method == method, "method was %d instead of %d\n", new_info->method, method);
4516 ok(IsEqualGUID(&new_info->causality, &causality), "causality wasn't correct\n");
4517 }
4518
4519 ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
4520 if (hrFault != S_OK)
4521 trace("\thrFault = 0x%08x\n", hrFault);
4522
4523 *pDataSize = 0;
4524}
4525
4527 IChannelHook *iface,
4528 REFGUID uExtent,
4529 REFIID riid,
4530 ULONG *pDataSize,
4531 void *pDataBuffer,
4532 HRESULT hrFault )
4533{
4534 trace("TestChannelHook_ServerFillBuffer\n");
4535 ok(0, "TestChannelHook_ServerFillBuffer shouldn't be called\n");
4536}
4537
4538static const IChannelHookVtbl TestChannelHookVtbl =
4539{
4549};
4550
4552
4553static void test_channel_hook(void)
4554{
4556 DWORD tid;
4557 IUnknown *proxy = NULL;
4558 HANDLE thread;
4559 HRESULT hr;
4560
4562 MSHLFLAGS_NORMAL, &MessageFilter };
4563
4566
4569
4570 cLocks = 0;
4571
4572 hr = CreateStreamOnHGlobal(NULL, TRUE, &object_data.stream);
4574 tid = start_host_object2(&object_data, &thread);
4575 server_tid = tid;
4576
4578
4579 IStream_Seek(object_data.stream, ullZero, STREAM_SEEK_SET, NULL);
4580 hr = CoUnmarshalInterface(object_data.stream, &IID_IClassFactory, (void **)&cf);
4582 IStream_Release(object_data.stream);
4583
4585
4586 method = 3;
4587 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (LPVOID*)&proxy);
4588 ok_ole_success(hr, IClassFactory_CreateInstance);
4589
4590 method = 5;
4591 IUnknown_Release(proxy);
4592
4593 IClassFactory_Release(cf);
4594
4595 ok_no_locks();
4596
4598
4601}
4602
4604{
4605 HMODULE hOle32 = GetModuleHandleA("ole32");
4606 int argc;
4607 char **argv;
4608
4609 if (!GetProcAddress(hOle32, "CoRegisterSurrogateEx")) {
4610 win_skip("skipping test on win9x\n");
4611 return;
4612 }
4613
4614 pCoInitializeEx = (void*)GetProcAddress(hOle32, "CoInitializeEx");
4615 pDllGetClassObject = (void*)GetProcAddress(hOle32, "DllGetClassObject");
4616
4618 if (argc > 2 && (!strcmp(argv[2], "-Embedding")))
4619 {
4620 pCoInitializeEx(NULL, COINIT_MULTITHREADED);
4623
4624 return;
4625 }
4626
4628
4631
4632 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
4633
4634 /* FIXME: test CoCreateInstanceEx */
4635
4636 /* lifecycle management and marshaling tests */
4637 do
4638 {
4664
4666 } while (with_external_conn);
4667
4686
4688
4692
4693 /* must be last test as channel hooks can't be unregistered */
4695
4697}
#define CO_E_NOTINITIALIZED
unsigned long long UINT64
static int argc
Definition: ServiceArgs.c:12
@ lparam
Definition: SystemMenu.c:31
@ wparam
Definition: SystemMenu.c:30
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define stat
Definition: acwin.h:99
#define read
Definition: acwin.h:96
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#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 broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define msg(x)
Definition: auth_time.c:54
#define ARRAY_SIZE(A)
Definition: main.h:20
#define U(x)
Definition: wordpad.c:45
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 ERROR_SUCCESS
Definition: deptool.c:10
#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 RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3298
LSTATUS WINAPI RegQueryValueA(HKEY hkey, LPCSTR name, LPSTR data, LPLONG count)
Definition: reg.c:4212
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
#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
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4747
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
HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
Definition: compobj.c:2690
HRESULT WINAPI CoRegisterClassObject(REFCLSID rclsid, LPUNKNOWN pUnk, DWORD dwClsContext, DWORD flags, LPDWORD lpdwRegister)
Definition: compobj.c:2897
ULONG WINAPI CoAddRefServerProcess(void)
Definition: compobj.c:4162
HRESULT WINAPI CoRegisterMessageFilter(LPMESSAGEFILTER lpMessageFilter, LPMESSAGEFILTER *lplpMessageFilter)
Definition: compobj.c:4046
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI CoDisconnectObject(LPUNKNOWN lpUnk, DWORD reserved)
Definition: compobj.c:2149
HRESULT WINAPI DECLSPEC_HOTPATCH CoRevokeClassObject(DWORD dwRegister)
Definition: compobj.c:1086
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3103
HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid)
Definition: compobj.c:2778
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
HRESULT WINAPI CoResumeClassObjects(void)
Definition: compobj.c:3288
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT WINAPI CoRegisterChannelHook(REFGUID guidExtension, IChannelHook *pChannelHook)
Definition: compobj.c:4787
ULONG WINAPI CoReleaseServerProcess(void)
Definition: compobj.c:4193
HRESULT WINAPI CoLockObjectExternal(LPUNKNOWN pUnk, BOOL fLock, BOOL fLastUnlockReleases)
Definition: compobj.c:3743
HRESULT WINAPI StringFromCLSID(REFCLSID id, LPOLESTR *idstr)
Definition: compobj.c:2412
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
HRESULT WINAPI GetHGlobalFromStream(IStream *pstm, HGLOBAL *phglobal)
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
HRESULT WINAPI CoMarshalHresult(LPSTREAM pStm, HRESULT hresult)
Definition: marshal.c:2227
HRESULT WINAPI CoGetStandardMarshal(REFIID riid, IUnknown *pUnk, DWORD dwDestContext, LPVOID pvDestContext, DWORD mshlflags, LPMARSHAL *ppMarshal)
Definition: marshal.c:1676
HRESULT WINAPI CoReleaseMarshalData(IStream *pStream)
Definition: marshal.c:2055
HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
Definition: marshal.c:1981
HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk, DWORD dwDestContext, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:1800
HRESULT WINAPI CoUnmarshalHresult(LPSTREAM pStm, HRESULT *phresult)
Definition: marshal.c:2248
#define NORMALEXTREFS
Definition: marshal.c:43
HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, DWORD dwDestContext, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:1876
method
Definition: dragdrop.c:54
r reserved
Definition: btrfs.c:3006
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
HRESULT WINAPI CoCreateFreeThreadedMarshaler(LPUNKNOWN punkOuter, LPUNKNOWN *ppunkMarshal)
Definition: ftmarshal.c:331
int proxy
Definition: main.c:67
FxObject * pObject
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
struct _cl_event * event
Definition: glext.h:7739
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
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
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
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
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define REG_SZ
Definition: layer.c:22
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static TfClientId tid
#define todo_wine
Definition: custom.c:89
static HRESULT WINAPI CustomMarshal_QueryInterface(IMarshal *iface, REFIID riid, void **ppv)
Definition: marshal.c:1370
#define ok_more_than_one_lock()
Definition: marshal.c:70
#define SET_EXPECT(func)
Definition: marshal.c:41
static HRESULT WINAPI Test_SMI_GetClassForHandler(IStdMarshalInfo *iface, DWORD dwDestContext, void *pvDestContext, CLSID *pClsid)
Definition: marshal.c:3452
static int server_tid
Definition: marshal.c:4330
static DWORD CALLBACK duo_marshal_thread_proc(void *p)
Definition: marshal.c:2014
static void test_client_security(void)
Definition: marshal.c:3522
static void UnlockModuleOOP(void)
Definition: marshal.c:3618
static HeapUnknown * impl_from_IUnknown(IUnknown *iface)
Definition: marshal.c:2784
static LONG cLocks
Definition: marshal.c:169
static HRESULT WINAPI CustomMarshal_DisconnectObject(IMarshal *iface, DWORD res)
Definition: marshal.c:1453
static DWORD external_connections
Definition: marshal.c:182
static IPSFactoryBuffer PSFactoryBuffer
Definition: marshal.c:598
static const IOleClientSiteVtbl OleClientSiteVtbl
Definition: marshal.c:419
static void test_tableweak_and_normal_marshal_and_releasedata(void)
Definition: marshal.c:2125
static void test_proxy_marshal_and_unmarshal_strong(void)
Definition: marshal.c:1095
static void test_normal_marshal_and_unmarshal(void)
Definition: marshal.c:752
static void test_interthread_marshal_and_unmarshal(void)
Definition: marshal.c:863
#define OBJREF_CUSTOM
Definition: marshal.c:79
static HRESULT WINAPI OleClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
Definition: marshal.c:393
static void WINAPI TestChannelHook_ClientGetSize(IChannelHook *iface, REFGUID uExtent, REFIID riid, ULONG *pDataSize)
Definition: marshal.c:4342
static ULONG WINAPI TestChannelHook_AddRef(IChannelHook *iface)
Definition: marshal.c:4319
static void WINAPI RpcStubBuffer_Disconnect(IRpcStubBuffer *iface)
Definition: marshal.c:477
static DWORD dwCoInit
Definition: marshal.c:66
static void release_host_object(DWORD tid, WPARAM wp)
Definition: marshal.c:692
static void test_proxy_interfaces(void)
Definition: marshal.c:2728
static void test_proxy_marshal_and_unmarshal(void)
Definition: marshal.c:903
static IMarshal CustomMarshal
Definition: marshal.c:1472
static void WINAPI TestChannelHook_ClientFillBuffer(IChannelHook *iface, REFGUID uExtent, REFIID riid, ULONG *pDataSize, void *pDataBuffer)
Definition: marshal.c:4384
static void test_tableweak_marshal_and_unmarshal_twice(void)
Definition: marshal.c:1848
static IOleWindow Test_OleWindow
Definition: marshal.c:391
static BOOL last_release_closes
Definition: marshal.c:183
static void test_call_from_message(void)
Definition: marshal.c:3089
static void test_proxy_marshal_and_unmarshal_weak(void)
Definition: marshal.c:1042
static ULONG WINAPI MessageFilter_AddRef(IMessageFilter *iface)
Definition: marshal.c:2584
static HRESULT WINAPI CustomMarshal_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *size)
Definition: marshal.c:1402
static IClassFactory TestMsg_ClassFactory
Definition: marshal.c:3087
static void test_no_marshaler(void)
Definition: marshal.c:711
static IStdMarshalInfo Test_SMI
Definition: marshal.c:3470
static HRESULT WINAPI Test_IUnknown_QueryInterface(LPUNKNOWN iface, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:228
static void test_crash_couninitialize(void)
Definition: marshal.c:1830
static void test_message_filter(void)
Definition: marshal.c:2652
static ULONG WINAPI OleClientSite_Release(IOleClientSite *iface)
Definition: marshal.c:414
static HWND hwnd_app
Definition: marshal.c:2892
static void test_proxy_used_in_wrong_thread(void)
Definition: marshal.c:2527
static const LARGE_INTEGER ullZero
Definition: marshal.c:168
static ULONG WINAPI TestOOP_IClassFactory_Release(LPCLASSFACTORY iface)
Definition: marshal.c:3713
static IChannelHook TestChannelHook
Definition: marshal.c:4551
static void test_implicit_mta(void)
Definition: marshal.c:4197
static void test_freethreadedmarshaldata(IStream *pStream, MSHCTX mshctx, void *ptr, DWORD mshlflags)
Definition: marshal.c:3163
static HRESULT WINAPI CustomMarshal_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *clsid)
Definition: marshal.c:1394
static DWORD CALLBACK bad_thread_proc(LPVOID p)
Definition: marshal.c:2482
static ULONG WINAPI CustomMarshal_Release(IMarshal *iface)
Definition: marshal.c:1389
static HRESULT WINAPI Test_IClassFactory_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:286
static ULONG WINAPI ExternalConnection_Release(IExternalConnection *iface)
Definition: marshal.c:197
static void test_inproc_handler(void)
Definition: marshal.c:3394
static void test_marshal_and_unmarshal_invalid(void)
Definition: marshal.c:784
static void LockModuleOOP(void)
Definition: marshal.c:3612
#define ok_ole_success(hr, func)
Definition: marshal.c:72
static HRESULT WINAPI CustomMarshal_UnmarshalInterface(IMarshal *iface, IStream *stream, REFIID riid, void **ppv)
Definition: marshal.c:1440
struct local_server local_server_class
Definition: marshal.c:3685
static ULONG WINAPI RpcStubBuffer_AddRef(IRpcStubBuffer *iface)
Definition: marshal.c:454
static IClassFactory Test_ClassFactory
Definition: marshal.c:351
static IMarshalVtbl CustomMarshalVtbl
Definition: marshal.c:1459
static ULONG WINAPI Test_SMI_AddRef(IStdMarshalInfo *iface)
Definition: marshal.c:3440
static void test_register_local_server(void)
Definition: marshal.c:3754
static void test_tableweak_marshal_releasedata1(void)
Definition: marshal.c:1904
#define ok_non_zero_external_conn()
Definition: marshal.c:73
static IUnknown Test_Unknown
Definition: marshal.c:265
static const IStdMarshalInfoVtbl Test_SMI_Vtbl
Definition: marshal.c:3462
static void test_freethreadedmarshaler(void)
Definition: marshal.c:3208
static void test_tableweak_and_normal_marshal_and_unmarshal(void)
Definition: marshal.c:2055
#define EXTENTID_WineTest
Definition: marshal.c:138
#define CHECK_EXPECT(func)
Definition: marshal.c:50
static IRpcStubBuffer *WINAPI RpcStubBuffer_IsIIDSupported(IRpcStubBuffer *iface, REFIID riid)
Definition: marshal.c:500
struct tagOBJREF OBJREF
static HRESULT WINAPI RpcStubBuffer_Connect(IRpcStubBuffer *iface, IUnknown *pUnkServer)
Definition: marshal.c:471
static HRESULT reg_unreg_wine_test_class(BOOL Register)
Definition: marshal.c:3355
static const char * debugstr_iid(REFIID riid)
Definition: marshal.c:4282
static ULONG WINAPI Test_IUnknown_Release(LPUNKNOWN iface)
Definition: marshal.c:252
static const IClassFactoryVtbl TestClassFactoryOOP_Vtbl
Definition: marshal.c:3743
static const IUnknownVtbl TestCrashUnknown_Vtbl
Definition: marshal.c:277
static const IClassFactoryVtbl TestREClassFactory_Vtbl
Definition: marshal.c:2910
static HRESULT WINAPI Test_IClassFactory_LockServer(LPCLASSFACTORY iface, BOOL fLock)
Definition: marshal.c:335
static HANDLE heventShutdown
Definition: marshal.c:3610
static void test_tablestrong_marshal_and_unmarshal_twice(void)
Definition: marshal.c:2221
#define DEFINE_EXPECT(func)
Definition: marshal.c:38
static void test_manualresetevent(void)
Definition: marshal.c:4044
static HRESULT WINAPI Test_IClassFactory_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:325
static DWORD CALLBACK get_global_interface_proc(LPVOID pv)
Definition: marshal.c:3940
static DWORD start_host_object(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, HANDLE *thread)
Definition: marshal.c:684
static void test_normal_marshal_and_unmarshal_twice(void)
Definition: marshal.c:2410
static void end_host_object(DWORD tid, HANDLE thread)
Definition: marshal.c:700
static HRESULT WINAPI TestRE_IClassFactory_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:2894
static void test_cocreateinstance_proxy(void)
Definition: marshal.c:149
static ULONG WINAPI HeapUnknown_AddRef(IUnknown *iface)
Definition: marshal.c:2801
static ULONG WINAPI RpcStubBuffer_Release(IRpcStubBuffer *iface)
Definition: marshal.c:460
static const IID IID_IWineTest
Definition: marshal.c:122
static ULONG WINAPI OleClientSite_AddRef(IOleClientSite *iface)
Definition: marshal.c:409
static DWORD start_host_object2(struct host_object_data *object_data, HANDLE *thread)
Definition: marshal.c:667
static void test_message_reentrancy(void)
Definition: marshal.c:3049
static void test_no_couninitialize_server(void)
Definition: marshal.c:1681
static ULONG WINAPI MessageFilter_Release(IMessageFilter *iface)
Definition: marshal.c:2589
static ULONG WINAPI HeapUnknown_Release(IUnknown *iface)
Definition: marshal.c:2807
static void test_local_server(void)
Definition: marshal.c:3824
static const CLSID * unmarshal_class
Definition: marshal.c:1365
static HRESULT WINAPI local_server_GetClassID(IPersist *iface, CLSID *clsid)
Definition: marshal.c:3658
static ULONG WINAPI OleWindow_AddRef(IOleWindow *iface)
Definition: marshal.c:366
static ULONG WINAPI PSFactoryBuffer_AddRef(IPSFactoryBuffer *iface)
Definition: marshal.c:551
static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: marshal.c:2921
static HANDLE create_target_process(const char *arg)
Definition: marshal.c:3804
static GUID causality
Definition: marshal.c:4331
static HRESULT WINAPI OleWindow_GetWindow(IOleWindow *iface, HWND *hwnd)
Definition: marshal.c:376
static IOleClientSite Test_OleClientSite
Definition: marshal.c:426
#define RELEASEMARSHALDATA
Definition: marshal.c:600
static const GUID CLSID_WineTestPSFactoryBuffer
Definition: marshal.c:62
static DWORD CALLBACK no_couninitialize_client_proc(LPVOID p)
Definition: marshal.c:1733
static SIZE_T round_global_size(SIZE_T size)
Definition: marshal.c:3150
static IClassFactoryVtbl TestMsgClassFactory_Vtbl
Definition: marshal.c:3078
static DWORD WINAPI MessageFilter_RetryRejectedCall(IMessageFilter *iface, HTASK threadIDCallee, DWORD dwTickCount, DWORD dwRejectType)
Definition: marshal.c:2620
static void test_two_tableweak_marshal_and_releasedata(void)
Definition: marshal.c:2175
static StubBufferWrapper * impl_from_IRpcStubBuffer(IRpcStubBuffer *iface)
Definition: marshal.c:434
static HRESULT WINAPI local_server_QueryInterface(IPersist *iface, REFIID iid, void **obj)
Definition: marshal.c:3632
static const IRpcStubBufferVtbl RpcStubBufferVtbl
Definition: marshal.c:523
static ULONG WINAPI Test_SMI_Release(IStdMarshalInfo *iface)
Definition: marshal.c:3446
static HRESULT WINAPI PSFactoryBuffer_CreateStub(IPSFactoryBuffer *iface, REFIID riid, IUnknown *server, IRpcStubBuffer **ppStub)
Definition: marshal.c:568
static HRESULT WINAPI TestOOP_IClassFactory_LockServer(LPCLASSFACTORY iface, BOOL fLock)
Definition: marshal.c:3732
static void test_hresult_marshaling(void)
Definition: marshal.c:2451
static ULONG WINAPI PSFactoryBuffer_Release(IPSFactoryBuffer *iface)
Definition: marshal.c:556
static HRESULT WINAPI PSFactoryBuffer_CreateProxy(IPSFactoryBuffer *iface, IUnknown *outer, REFIID riid, IRpcProxyBuffer **ppProxy, void **ppv)
Definition: marshal.c:561
static void WINAPI RpcStubBuffer_DebugServerRelease(IRpcStubBuffer *iface, void *pv)
Definition: marshal.c:518
static DWORD CALLBACK no_couninitialize_server_proc(LPVOID p)
Definition: marshal.c:1660
static void test_marshal_stub_apartment_shutdown(void)
Definition: marshal.c:1164
struct tagDUALSTRINGARRAY DUALSTRINGARRAY
static IExternalConnection ExternalConnection
Definition: marshal.c:225
static DWORD WINAPI MessageFilter_HandleInComingCall(IMessageFilter *iface, DWORD dwCallType, HTASK threadIDCaller, DWORD dwTickCount, LPINTERFACEINFO lpInterfaceInfo)
Definition: marshal.c:2594
static void test_proxybuffer(REFIID riid)
Definition: marshal.c:2822
static DWORD WINAPI ExternalConnection_ReleaseConnection(IExternalConnection *iface, DWORD extconn, DWORD reserved, BOOL fLastReleaseCloses)
Definition: marshal.c:209
static ULONG WINAPI ExternalConnection_AddRef(IExternalConnection *iface)
Definition: marshal.c:192
static HRESULT WINAPI RpcStubBuffer_QueryInterface(IRpcStubBuffer *iface, REFIID riid, void **ppv)
Definition: marshal.c:439
static void test_globalinterfacetable(void)
Definition: marshal.c:3967
static BOOL crash_thread_success
Definition: marshal.c:1790
static void UnlockModule(void)
Definition: marshal.c:176
static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: marshal.c:2789
static HRESULT WINAPI OleWindow_QueryInterface(IOleWindow *iface, REFIID riid, void **ppv)
Definition: marshal.c:359
static HRESULT WINAPI RpcStubBuffer_DebugServerQueryInterface(IRpcStubBuffer *iface, void **ppv)
Definition: marshal.c:512
static HRESULT WINAPI MessageFilter_QueryInterface(IMessageFilter *iface, REFIID riid, void **ppvObj)
Definition: marshal.c:2569
static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
Definition: marshal.c:313
#define ok_no_locks()
Definition: marshal.c:71
static ULONG WINAPI Test_IUnknown_AddRef(LPUNKNOWN iface)
Definition: marshal.c:246
static void WINAPI TestChannelHook_ServerFillBuffer(IChannelHook *iface, REFGUID uExtent, REFIID riid, ULONG *pDataSize, void *pDataBuffer, HRESULT hrFault)
Definition: marshal.c:4526
static void register_test_window(void)
Definition: marshal.c:3039
static HRESULT WINAPI CustomMarshal_ReleaseMarshalData(IMarshal *iface, IStream *stream)
Definition: marshal.c:1447
UINT64 OID
Definition: marshal.c:88
#define ok_zero_external_conn()
Definition: marshal.c:74
static HRESULT WINAPI RpcStubBuffer_Invoke(IRpcStubBuffer *iface, RPCOLEMESSAGE *_prpcmsg, IRpcChannelBuffer *_pRpcChannelBuffer)
Definition: marshal.c:482
static void test_same_apartment_unmarshal_failure(void)
Definition: marshal.c:830
static void test_WM_QUIT_handling(void)
Definition: marshal.c:3133
static HRESULT WINAPI TestChannelHook_QueryInterface(IChannelHook *iface, REFIID riid, void **ppv)
Definition: marshal.c:4306
static void WINAPI TestChannelHook_ServerGetSize(IChannelHook *iface, REFGUID uExtent, REFIID riid, HRESULT hrFault, ULONG *pDataSize)
Definition: marshal.c:4490
static const IMessageFilterVtbl MessageFilter_Vtbl
Definition: marshal.c:2640
static IPSFactoryBuffer * ps_factory_buffer
Definition: marshal.c:536
static void test_CoGetStandardMarshal(void)
Definition: marshal.c:1575
static const IChannelHookVtbl TestChannelHookVtbl
Definition: marshal.c:4538
#define CHECK_CALLED(func)
Definition: marshal.c:56
#define ok_last_release_closes(b)
Definition: marshal.c:75
static HRESULT WINAPI TestOOP_IClassFactory_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:3718
static HRESULT WINAPI ExternalConnection_QueryInterface(IExternalConnection *iface, REFIID riid, void **ppv)
Definition: marshal.c:185
static DWORD CALLBACK implicit_mta_use_proc(void *param)
Definition: marshal.c:4154
static void test_DfMarshal_custom_marshaling(void)
Definition: marshal.c:1526
static const CLSID CLSID_WineOOPTest
Definition: marshal.c:141
static ULONG WINAPI OleWindow_Release(IOleWindow *iface)
Definition: marshal.c:371
static void test_stubbuffer(REFIID riid)
Definition: marshal.c:2860
static ULONG WINAPI CustomMarshal_AddRef(IMarshal *iface)
Definition: marshal.c:1384
static LPVOID
Definition: marshal.c:67
static IUnknown TestCrash_Unknown
Definition: marshal.c:284
static DWORD CALLBACK implicit_mta_unmarshal_proc(void *param)
Definition: marshal.c:4119
#define OBJREF_SIGNATURE
Definition: marshal.c:77
static void test_tableweak_marshal_releasedata2(void)
Definition: marshal.c:1965
static IPSFactoryBufferVtbl PSFactoryBufferVtbl
Definition: marshal.c:589
static DWORD CALLBACK host_object_proc(LPVOID p)
Definition: marshal.c:618
static const IID IID_IRemUnknown
Definition: marshal.c:130
static void test_proxy_marshal_and_unmarshal2(void)
Definition: marshal.c:978
static void test_channel_hook(void)
Definition: marshal.c:4553
static DWORD CALLBACK implicit_mta_marshal_proc(void *param)
Definition: marshal.c:4182
static void test_StdMarshal_custom_marshaling(void)
Definition: marshal.c:1474
static void test_marshal_channel_buffer(void)
Definition: marshal.c:1296
static DWORD WINAPI MessageFilter_MessagePending(IMessageFilter *iface, HTASK threadIDCallee, DWORD dwTickCount, DWORD dwPendingType)
Definition: marshal.c:2630
static void test_disconnect_stub(void)
Definition: marshal.c:2372
static HRESULT WINAPI CustomMarshal_MarshalInterface(IMarshal *iface, IStream *stream, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
Definition: marshal.c:1412
static void test_no_couninitialize_client(void)
Definition: marshal.c:1753
static DWORD CALLBACK crash_couninitialize_proc(void *p)
Definition: marshal.c:1792
#define CLSID_WineTest
Definition: marshal.c:139
static const IClassFactoryVtbl TestClassFactory_Vtbl
Definition: marshal.c:342
static HRESULT WINAPI TestOOP_IClassFactory_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:3690
static ULONG WINAPI local_server_Release(IPersist *iface)
Definition: marshal.c:3653
static void test_marshal_proxy_mta_apartment_shutdown(void)
Definition: marshal.c:1252
static ULONG WINAPI local_server_AddRef(IPersist *iface)
Definition: marshal.c:3648
static void test_handler_marshaling(void)
Definition: marshal.c:3472
static const GUID CLSID_DfMarshal
Definition: marshal.c:63
static int method
Definition: marshal.c:4330
static IMessageFilter MessageFilter
Definition: marshal.c:2650
static void LockModule(void)
Definition: marshal.c:171
static ULONG WINAPI TestOOP_IClassFactory_AddRef(LPCLASSFACTORY iface)
Definition: marshal.c:3708
static void WINAPI TestChannelHook_ServerNotify(IChannelHook *iface, REFGUID uExtent, REFIID riid, ULONG cbDataSize, void *pDataBuffer, DWORD lDataRep)
Definition: marshal.c:4455
static void test_normal_marshal_and_release(void)
Definition: marshal.c:725
static HRESULT WINAPI Test_SMI_QueryInterface(IStdMarshalInfo *iface, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:3422
static const IOleWindowVtbl OleWindowVtbl
Definition: marshal.c:383
static BOOL new_hook_struct
Definition: marshal.c:4329
static DWORD WINAPI ExternalConnection_AddConnection(IExternalConnection *iface, DWORD extconn, DWORD reserved)
Definition: marshal.c:202
static ULONG WINAPI TestChannelHook_Release(IChannelHook *iface)
Definition: marshal.c:4324
static IClassFactory TestOOP_ClassFactory
Definition: marshal.c:3752
static BOOL with_external_conn
Definition: marshal.c:181
static void test_marshal_proxy_apartment_shutdown(void)
Definition: marshal.c:1204
static const IExternalConnectionVtbl ExternalConnectionVtbl
Definition: marshal.c:217
static ULONG WINAPI RpcStubBuffer_CountRefs(IRpcStubBuffer *iface)
Definition: marshal.c:506
GUID IPID
Definition: marshal.c:89
static const IUnknownVtbl HeapUnknown_Vtbl
Definition: marshal.c:2815
static void test_lock_object_external(void)
Definition: marshal.c:2274
static void test_bad_marshal_stream(void)
Definition: marshal.c:2703
static IClassFactory TestRE_ClassFactory
Definition: marshal.c:2919
static const IPersistVtbl local_server_persist_vtbl
Definition: marshal.c:3677
UINT64 OXID
Definition: marshal.c:87
static void WINAPI TestChannelHook_ClientNotify(IChannelHook *iface, REFGUID uExtent, REFIID riid, ULONG cbDataSize, void *pDataBuffer, DWORD lDataRep, HRESULT hrFault)
Definition: marshal.c:4419
#define OBJREF_STANDARD
Definition: marshal.c:78
static const IUnknownVtbl TestUnknown_Vtbl
Definition: marshal.c:258
static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
Definition: marshal.c:319
static HRESULT WINAPI PSFactoryBuffer_QueryInterface(IPSFactoryBuffer *iface, REFIID riid, void **ppv)
Definition: marshal.c:538
struct tagSTDOBJREF STDOBJREF
static HRESULT WINAPI TestMsg_IClassFactory_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
Definition: marshal.c:3067
static ULONG WINAPI TestCrash_IUnknown_Release(LPUNKNOWN iface)
Definition: marshal.c:267
static const LARGE_INTEGER llZero
Definition: moniker.c:1113
static LPOLESTR
Definition: stg_prop.c:27
static refpint_t pi[]
Definition: server.c:96
#define argv
Definition: mplay32.c:18
REFCLSID clsid
Definition: msctf.c:82
Definition: features.h:417
unsigned int UINT
Definition: ndis.h:50
static LPUNKNOWN
Definition: ndr_ole.c:49
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define DWORD
Definition: nt_native.h:44
#define KEY_SET_VALUE
Definition: nt_native.h:1017
@ REGCLS_SUSPENDED
Definition: objbase.h:395
@ REGCLS_MULTIPLEUSE
Definition: objbase.h:393
@ REGCLS_SINGLEUSE
Definition: objbase.h:392
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:278
@ COINIT_MULTITHREADED
Definition: objbase.h:279
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
#define RPC_C_IMP_LEVEL_IMPERSONATE
Definition: rpcdce.h:176
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
#define win_skip
Definition: test.h:163
int winetest_get_mainargs(char ***pargv)
void winetest_wait_child_process(HANDLE process)
#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:2780
ULONG refs
Definition: marshal.c:2781
IRpcStubBuffer * buffer
Definition: marshal.c:431
IRpcStubBuffer IRpcStubBuffer_iface
Definition: marshal.c:429
Definition: scsiwmi.h:51
DWORD cb
Definition: winbase.h:856
LPCSTR lpszClassName
Definition: winuser.h:3175
WNDPROC lpfnWndProc
Definition: winuser.h:3167
Definition: stubgen.c:11
Definition: cookie.c:34
MSHLFLAGS marshal_flags1
Definition: marshal.c:2008
IStream * pStream1
Definition: marshal.c:2009
HANDLE hQuitEvent
Definition: marshal.c:2011
HANDLE hReadyEvent
Definition: marshal.c:2010
IStream * pStream2
Definition: marshal.c:2009
MSHLFLAGS marshal_flags2
Definition: marshal.c:2008
DWORD cookie
Definition: marshal.c:3936
IGlobalInterfaceTable * git
Definition: marshal.c:3937
IMessageFilter * filter
Definition: marshal.c:608
IUnknown * register_object
Definition: marshal.c:609
HANDLE marshal_event
Definition: marshal.c:611
const IID * iid
Definition: marshal.c:605
MSHLFLAGS marshal_flags
Definition: marshal.c:607
IUnknown * object
Definition: marshal.c:606
IStream * stream
Definition: marshal.c:604
const CLSID * register_clsid
Definition: marshal.c:610
IPersist IPersist_iface
Definition: marshal.c:3629
Definition: name.c:39
LPSTREAM stream
Definition: marshal.c:1654
HANDLE unmarshal_event
Definition: marshal.c:1656
HANDLE marshal_event
Definition: marshal.c:1655
DWORD server_tid
Definition: marshal.c:4338
GUID causality
Definition: marshal.c:4336
DWORD server_pid
Definition: marshal.c:4337
Definition: send.c:48
Definition: stat.h:55
Definition: parse.h:23
unsigned short aStringArray[1]
Definition: marshal.c:84
unsigned short wSecurityOffset
Definition: marshal.c:83
unsigned short wNumEntries
Definition: marshal.c:82
CLSID clsid
Definition: marshal.c:110
struct tagOBJREF::@1700::OR_CUSTOM u_custom
ULONG cbExtension
Definition: marshal.c:115
ULONG size
Definition: marshal.c:116
DUALSTRINGARRAY saResAddr
Definition: marshal.c:106
STDOBJREF std
Definition: marshal.c:105
ULONG flags
Definition: marshal.c:101
union tagOBJREF::@1700 u_objref
struct tagOBJREF::@1700::OR_HANDLER u_handler
byte * pData
Definition: marshal.c:117
GUID iid
Definition: marshal.c:102
ULONG signature
Definition: marshal.c:100
struct tagOBJREF::@1700::OR_STANDARD u_standard
OXID oxid
Definition: marshal.c:94
ULONG flags
Definition: marshal.c:92
IPID ipid
Definition: marshal.c:96
ULONG cPublicRefs
Definition: marshal.c:93
struct _stub stub
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:637
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
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:62
static rfbScreenInfoPtr server
Definition: vnc.c:74
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define GMEM_FIXED
Definition: winbase.h:319
#define WAIT_OBJECT_0
Definition: winbase.h:432
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define REGDB_E_CLASSNOTREG
Definition: winerror.h:2696
#define S_FALSE
Definition: winerror.h:2357
#define RPC_E_WRONG_THREAD
Definition: winerror.h:2490
#define E_NOINTERFACE
Definition: winerror.h:2364
#define STG_E_READFAULT
Definition: winerror.h:2576
#define CO_E_OBJNOTCONNECTED
Definition: winerror.h:2816
#define CO_E_OBJNOTREG
Definition: winerror.h:2814
#define RPC_E_CANTCALLOUT_ININPUTSYNCCALL
Definition: winerror.h:2489
#define RPC_S_CALLPENDING
Definition: winerror.h:2497
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define E_UNEXPECTED
Definition: winerror.h:2456
#define CO_E_SERVER_STOPPING
Definition: winerror.h:2863
#define E_POINTER
Definition: winerror.h:2365
#define RPC_E_DISCONNECTED
Definition: winerror.h:2484
#define RPC_E_CALL_REJECTED
Definition: winerror.h:2458
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
#define WM_QUIT
Definition: winuser.h:1626
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:4318
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define SMTO_BLOCK
Definition: winuser.h:1227
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define QS_ALLINPUT
Definition: winuser.h:906
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:1199
#define WM_NULL
Definition: winuser.h:1610
#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:1898
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:1198
__wchar_t WCHAR
Definition: xmlstorage.h:180