ReactOS 0.4.16-dev-2320-ge1853c6
marshal.c
Go to the documentation of this file.
1/*
2 * Copyright 2002 Juergen Schmied
3 * Copyright 2002 Marcus Meissner
4 * Copyright 2004 Mike Hearn, for CodeWeavers
5 * Copyright 2004 Rob Shearman, for CodeWeavers
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <assert.h>
23
24#define COBJMACROS
25#include "objbase.h"
26
27#include "dcom.h"
28#include "combase_private.h"
29
30#include "wine/debug.h"
31
33
35 const OXID_INFO *oxid_info, const IID *iid,
36 DWORD dest_context, void *dest_context_data,
37 IRpcChannelBuffer **chan, struct apartment *apt);
38
39static HRESULT unmarshal_object(const STDOBJREF *stdobjref, struct apartment *apt,
40 MSHCTX dest_context, void *dest_context_data,
41 REFIID riid, const OXID_INFO *oxid_info,
42 void **object);
43
44/* number of refs given out for normal marshaling */
45#define NORMALEXTREFS 5
46
47/* private flag indicating that the object was marshaled as table-weak */
48#define SORFP_TABLEWEAK SORF_OXRES1
49/* private flag indicating that the caller does not want to notify the stub
50 * when the proxy disconnects or is destroyed */
51#define SORFP_NOLIFETIMEMGMT SORF_OXRES2
52
53/* imported interface proxy */
54struct ifproxy
55{
56 struct list entry; /* entry in proxy_manager list (CS parent->cs) */
57 struct proxy_manager *parent; /* owning proxy_manager (RO) */
58 void *iface; /* interface pointer (RO) */
59 STDOBJREF stdobjref; /* marshal data that represents this object (RO) */
60 IID iid; /* interface ID (RO) */
61 IRpcProxyBuffer *proxy; /* interface proxy (RO) */
62 ULONG refs; /* imported (public) references (LOCK) */
63 IRpcChannelBuffer *chan; /* channel to object (CS parent->cs) */
64};
65
66/* imported object / proxy manager */
68{
72 struct apartment *parent; /* owning apartment (RO) */
73 struct list entry; /* entry in apartment (CS parent->cs) */
74 OXID oxid; /* object exported ID (RO) */
75 OXID_INFO oxid_info; /* string binding, ipid of rem unknown and other information (RO) */
76 OID oid; /* object ID (RO) */
77 struct list interfaces; /* imported interfaces (CS cs) */
78 LONG refs; /* proxy reference count (LOCK); 0 if about to be removed from list */
79 CRITICAL_SECTION cs; /* thread safety for this object and children */
80 ULONG sorflags; /* STDOBJREF flags (RO) */
81 IRemUnknown *remunk; /* proxy to IRemUnknown used for lifecycle management (CS cs) */
82 HANDLE remoting_mutex; /* mutex used for synchronizing access to IRemUnknown */
83 MSHCTX dest_context; /* context used for activating optimisations (LOCK) */
84 void *dest_context_data; /* reserved context value (LOCK) */
85};
86
87static inline struct proxy_manager *impl_from_IMultiQI(IMultiQI *iface)
88{
89 return CONTAINING_RECORD(iface, struct proxy_manager, IMultiQI_iface);
90}
91
92static inline struct proxy_manager *impl_from_IMarshal(IMarshal *iface)
93{
94 return CONTAINING_RECORD(iface, struct proxy_manager, IMarshal_iface);
95}
96
98{
100}
101
103{
108};
109
111{
112 return CONTAINING_RECORD(iface, struct ftmarshaler, IUnknown_inner);
113}
114
116{
117 return CONTAINING_RECORD(iface, struct ftmarshaler, IMarshal_iface);
118}
119
120/***********************************************************************
121 * CoMarshalHresult (combase.@)
122 */
124{
125 return IStream_Write(stream, &hresult, sizeof(hresult), NULL);
126}
127
128/***********************************************************************
129 * CoUnmarshalHresult (combase.@)
130 */
132{
133 return IStream_Read(stream, phresult, sizeof(*phresult), NULL);
134}
135
136/***********************************************************************
137 * CoGetInterfaceAndReleaseStream (combase.@)
138 */
140{
141 HRESULT hr;
142
143 TRACE("%p, %s, %p\n", stream, debugstr_guid(riid), obj);
144
145 if (!stream) return E_INVALIDARG;
147 IStream_Release(stream);
148 return hr;
149}
150
151/***********************************************************************
152 * CoMarshalInterThreadInterfaceInStream (combase.@)
153 */
155{
156 ULARGE_INTEGER xpos;
158 HRESULT hr;
159
160 TRACE("%s, %p, %p\n", debugstr_guid(riid), unk, stream);
161
163 if (FAILED(hr)) return hr;
164 hr = CoMarshalInterface(*stream, riid, unk, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
165
166 if (SUCCEEDED(hr))
167 {
168 memset(&seekto, 0, sizeof(seekto));
169 IStream_Seek(*stream, seekto, STREAM_SEEK_SET, &xpos);
170 }
171 else
172 {
173 IStream_Release(*stream);
174 *stream = NULL;
175 }
176
177 return hr;
178}
179
181{
182 struct ftmarshaler *marshaler = impl_ft_from_IUnknown(iface);
183
184 TRACE("%p, %s, %p\n", iface, debugstr_guid(riid), obj);
185
186 *obj = NULL;
187
189 *obj = &marshaler->IUnknown_inner;
190 else if (IsEqualIID(&IID_IMarshal, riid))
191 *obj = &marshaler->IMarshal_iface;
192 else
193 {
194 FIXME("No interface for %s\n", debugstr_guid(riid));
195 return E_NOINTERFACE;
196 }
197
198 IUnknown_AddRef((IUnknown *)*obj);
199
200 return S_OK;
201}
202
204{
205 struct ftmarshaler *marshaler = impl_ft_from_IUnknown(iface);
207
208 TRACE("%p, refcount %lu\n", iface, refcount);
209
210 return refcount;
211}
212
214{
215 struct ftmarshaler *marshaler = impl_ft_from_IUnknown(iface);
217
218 TRACE("%p, refcount %lu\n", iface, refcount);
219
220 if (!refcount)
221 free(marshaler);
222
223 return refcount;
224}
225
226static const IUnknownVtbl ftmarshaler_inner_vtbl =
227{
231};
232
234{
235 struct ftmarshaler *marshaler = impl_ft_from_IMarshal(iface);
236
237 TRACE("%p, %s, %p\n", iface, debugstr_guid(riid), obj);
238
239 return IUnknown_QueryInterface(marshaler->outer_unk, riid, obj);
240}
241
243{
244 struct ftmarshaler *marshaler = impl_ft_from_IMarshal(iface);
245
246 TRACE("%p\n", iface);
247
248 return IUnknown_AddRef(marshaler->outer_unk);
249}
250
252{
253 struct ftmarshaler *marshaler = impl_ft_from_IMarshal(iface);
254
255 TRACE("%p\n", iface);
256
257 return IUnknown_Release(marshaler->outer_unk);
258}
259
261 DWORD dest_context, void *pvDestContext, DWORD mshlflags, CLSID *clsid)
262{
263 TRACE("%s, %p, %#lx, %p, %#lx, %p\n", debugstr_guid(riid), pv, dest_context, pvDestContext, mshlflags, clsid);
264
265 if (dest_context == MSHCTX_INPROC || dest_context == MSHCTX_CROSSCTX)
267 else
269
270 return S_OK;
271}
272
274{
277};
278
280 DWORD dest_context, void *pvDestContext, DWORD mshlflags, DWORD *size)
281{
282 IMarshal *marshal = NULL;
283 HRESULT hr;
284
285 TRACE("%s, %p, %#lx, %p, %#lx, %p\n", debugstr_guid(riid), pv, dest_context, pvDestContext, mshlflags, size);
286
287 /* If the marshalling happens inside the same process the interface pointer is
288 copied between the apartments */
289 if (dest_context == MSHCTX_INPROC || dest_context == MSHCTX_CROSSCTX)
290 {
291 *size = sizeof(mshlflags) + sizeof(union ftmarshaler_data) + sizeof(GUID);
292 return S_OK;
293 }
294
295 /* Use the standard marshaller to handle all other cases */
296 CoGetStandardMarshal(riid, pv, dest_context, pvDestContext, mshlflags, &marshal);
297 hr = IMarshal_GetMarshalSizeMax(marshal, riid, pv, dest_context, pvDestContext, mshlflags, size);
298 IMarshal_Release(marshal);
299 return hr;
300}
301
303 void *pv, DWORD dest_context, void *pvDestContext, DWORD mshlflags)
304{
305 IMarshal *marshal = NULL;
306 HRESULT hr;
307
308 TRACE("%p, %s, %p, %#lx, %p, %#lx\n", stream, debugstr_guid(riid), pv,
309 dest_context, pvDestContext, mshlflags);
310
311 /* If the marshalling happens inside the same process the interface pointer is
312 copied between the apartments */
313 if (dest_context == MSHCTX_INPROC || dest_context == MSHCTX_CROSSCTX)
314 {
316 GUID unknown_guid = { 0 };
317
318 data.value = 0;
319 hr = IUnknown_QueryInterface((IUnknown *)pv, riid, (void **)&data.object);
320 if (FAILED(hr))
321 return hr;
322
323 /* don't hold a reference to table-weak marshaled interfaces */
324 if (mshlflags & MSHLFLAGS_TABLEWEAK)
325 IUnknown_Release(data.object);
326
327 hr = IStream_Write(stream, &mshlflags, sizeof(mshlflags), NULL);
328 if (hr != S_OK) return STG_E_MEDIUMFULL;
329
330 hr = IStream_Write(stream, &data, sizeof(data), NULL);
331 if (hr != S_OK) return STG_E_MEDIUMFULL;
332
333 hr = IStream_Write(stream, &unknown_guid, sizeof(unknown_guid), NULL);
334 if (hr != S_OK) return STG_E_MEDIUMFULL;
335
336 return S_OK;
337 }
338
339 /* Use the standard marshaler to handle all other cases */
340 CoGetStandardMarshal(riid, pv, dest_context, pvDestContext, mshlflags, &marshal);
341 hr = IMarshal_MarshalInterface(marshal, stream, riid, pv, dest_context, pvDestContext, mshlflags);
342 IMarshal_Release(marshal);
343 return hr;
344}
345
347{
349 DWORD mshlflags;
350 GUID unknown_guid;
351 HRESULT hr;
352
353 TRACE("%p, %s, %p\n", stream, debugstr_guid(riid), ppv);
354
355 hr = IStream_Read(stream, &mshlflags, sizeof(mshlflags), NULL);
356 if (hr != S_OK) return STG_E_READFAULT;
357
358 hr = IStream_Read(stream, &data, sizeof(data), NULL);
359 if (hr != S_OK) return STG_E_READFAULT;
360
361 hr = IStream_Read(stream, &unknown_guid, sizeof(unknown_guid), NULL);
362 if (hr != S_OK) return STG_E_READFAULT;
363
364 hr = IUnknown_QueryInterface(data.object, riid, ppv);
365 if (!(mshlflags & (MSHLFLAGS_TABLEWEAK | MSHLFLAGS_TABLESTRONG)))
366 IUnknown_Release(data.object);
367
368 return hr;
369}
370
372{
374 DWORD mshlflags;
375 GUID unknown_guid;
376 HRESULT hr;
377
378 TRACE("%p\n", stream);
379
380 hr = IStream_Read(stream, &mshlflags, sizeof(mshlflags), NULL);
381 if (hr != S_OK) return STG_E_READFAULT;
382
383 hr = IStream_Read(stream, &data, sizeof(data), NULL);
384 if (hr != S_OK) return STG_E_READFAULT;
385
386 hr = IStream_Read(stream, &unknown_guid, sizeof(unknown_guid), NULL);
387 if (hr != S_OK) return STG_E_READFAULT;
388
389 IUnknown_Release(data.object);
390 return S_OK;
391}
392
394{
395 TRACE("\n");
396
397 /* nothing to do */
398 return S_OK;
399}
400
401static const IMarshalVtbl ftmarshaler_vtbl =
402{
412};
413
414/***********************************************************************
415 * CoCreateFreeThreadedMarshaler (combase.@)
416 */
418{
419 struct ftmarshaler *object;
420
421 TRACE("%p, %p\n", outer, marshaler);
422
423 object = malloc(sizeof(*object));
424 if (!object)
425 return E_OUTOFMEMORY;
426
427 object->IUnknown_inner.lpVtbl = &ftmarshaler_inner_vtbl;
428 object->IMarshal_iface.lpVtbl = &ftmarshaler_vtbl;
429 object->refcount = 1;
430 object->outer_unk = outer ? outer : &object->IUnknown_inner;
431
432 *marshaler = &object->IUnknown_inner;
433
434 return S_OK;
435}
436
437/***********************************************************************
438 * CoGetMarshalSizeMax (combase.@)
439 */
441 DWORD dest_context, void *pvDestContext, DWORD mshlFlags)
442{
443 BOOL std_marshal = FALSE;
444 IMarshal *marshal;
445 HRESULT hr;
446
447 if (!unk)
448 return E_POINTER;
449
450 hr = IUnknown_QueryInterface(unk, &IID_IMarshal, (void **)&marshal);
451 if (hr != S_OK)
452 {
453 std_marshal = TRUE;
454 hr = CoGetStandardMarshal(riid, unk, dest_context, pvDestContext, mshlFlags, &marshal);
455 }
456 if (hr != S_OK)
457 return hr;
458
459 hr = IMarshal_GetMarshalSizeMax(marshal, riid, unk, dest_context, pvDestContext, mshlFlags, size);
460 if (!std_marshal)
461 /* add on the size of the whole OBJREF structure like native does */
462 *size += sizeof(OBJREF);
463
464 IMarshal_Release(marshal);
465 return hr;
466}
467
468static void dump_mshflags(MSHLFLAGS flags)
469{
470 if (flags & MSHLFLAGS_TABLESTRONG)
471 TRACE(" MSHLFLAGS_TABLESTRONG");
472 if (flags & MSHLFLAGS_TABLEWEAK)
473 TRACE(" MSHLFLAGS_TABLEWEAK");
474 if (!(flags & (MSHLFLAGS_TABLESTRONG|MSHLFLAGS_TABLEWEAK)))
475 TRACE(" MSHLFLAGS_NORMAL");
476 if (flags & MSHLFLAGS_NOPING)
477 TRACE(" MSHLFLAGS_NOPING");
478}
479
480/***********************************************************************
481 * CoMarshalInterface (combase.@)
482 */
484 DWORD dest_context, void *pvDestContext, DWORD mshlFlags)
485{
486 CLSID marshaler_clsid;
487 IMarshal *marshal;
488 HRESULT hr;
489
490 TRACE("%p, %s, %p, %lx, %p, ", stream, debugstr_guid(riid), unk, dest_context, pvDestContext);
491 dump_mshflags(mshlFlags);
492 TRACE("\n");
493
494 if (!unk || !stream)
495 return E_INVALIDARG;
496
497 hr = IUnknown_QueryInterface(unk, &IID_IMarshal, (void **)&marshal);
498 if (hr != S_OK)
499 hr = CoGetStandardMarshal(riid, unk, dest_context, pvDestContext, mshlFlags, &marshal);
500 if (hr != S_OK)
501 {
502 ERR("Failed to get marshaller, %#lx\n", hr);
503 return hr;
504 }
505
506 hr = IMarshal_GetUnmarshalClass(marshal, riid, unk, dest_context, pvDestContext, mshlFlags,
507 &marshaler_clsid);
508 if (hr != S_OK)
509 {
510 ERR("IMarshal::GetUnmarshalClass failed, %#lx\n", hr);
511 goto cleanup;
512 }
513
514 /* FIXME: implement handler marshaling too */
515 if (IsEqualCLSID(&marshaler_clsid, &CLSID_StdMarshal))
516 {
517 TRACE("Using standard marshaling\n");
518 }
519 else
520 {
521 OBJREF objref;
522
523 TRACE("Using custom marshaling\n");
525 objref.iid = *riid;
526 objref.flags = OBJREF_CUSTOM;
527 objref.u_objref.u_custom.clsid = marshaler_clsid;
528 objref.u_objref.u_custom.cbExtension = 0;
529 objref.u_objref.u_custom.size = 0;
530 hr = IMarshal_GetMarshalSizeMax(marshal, riid, unk, dest_context, pvDestContext, mshlFlags,
531 &objref.u_objref.u_custom.size);
532 if (hr != S_OK)
533 {
534 ERR("Failed to get max size of marshal data, error %#lx\n", hr);
535 goto cleanup;
536 }
537 /* write constant sized common header and OR_CUSTOM data into stream */
538 hr = IStream_Write(stream, &objref, FIELD_OFFSET(OBJREF, u_objref.u_custom.pData), NULL);
539 if (hr != S_OK)
540 {
541 ERR("Failed to write OR_CUSTOM header to stream with %#lx\n", hr);
542 goto cleanup;
543 }
544 }
545
546 TRACE("Calling IMarshal::MarshalInterface\n");
547
548 hr = IMarshal_MarshalInterface(marshal, stream, riid, unk, dest_context, pvDestContext, mshlFlags);
549 if (hr != S_OK)
550 {
551 ERR("Failed to marshal the interface %s, hr %#lx\n", debugstr_guid(riid), hr);
552 goto cleanup;
553 }
554
555cleanup:
556 IMarshal_Release(marshal);
557
558 TRACE("completed with hr %#lx\n", hr);
559
560 return hr;
561}
562
563/* Creates an IMarshal* object according to the data marshaled to the stream.
564 * The function leaves the stream pointer at the start of the data written
565 * to the stream by the IMarshal* object.
566 */
568{
569 OBJREF objref;
570 HRESULT hr;
571 ULONG res;
572
573 /* read common OBJREF header */
574 hr = IStream_Read(stream, &objref, FIELD_OFFSET(OBJREF, u_objref), &res);
575 if (hr != S_OK || (res != FIELD_OFFSET(OBJREF, u_objref)))
576 {
577 ERR("Failed to read common OBJREF header, %#lx\n", hr);
578 return STG_E_READFAULT;
579 }
580
581 /* sanity check on header */
582 if (objref.signature != OBJREF_SIGNATURE)
583 {
584 ERR("Bad OBJREF signature %#lx\n", objref.signature);
586 }
587
588 if (iid) *iid = objref.iid;
589
590 /* FIXME: handler marshaling */
591 if (objref.flags & OBJREF_STANDARD)
592 {
593 TRACE("Using standard unmarshaling\n");
594 *marshal = NULL;
595 return S_FALSE;
596 }
597 else if (objref.flags & OBJREF_CUSTOM)
598 {
599 ULONG custom_header_size = FIELD_OFFSET(OBJREF, u_objref.u_custom.pData) -
600 FIELD_OFFSET(OBJREF, u_objref.u_custom);
601 TRACE("Using custom unmarshaling\n");
602 /* read constant sized OR_CUSTOM data from stream */
603 hr = IStream_Read(stream, &objref.u_objref.u_custom,
604 custom_header_size, &res);
605 if (hr != S_OK || (res != custom_header_size))
606 {
607 ERR("Failed to read OR_CUSTOM header, %#lx\n", hr);
608 return STG_E_READFAULT;
609 }
610 /* now create the marshaler specified in the stream */
611 hr = CoCreateInstance(&objref.u_objref.u_custom.clsid, NULL,
612 CLSCTX_INPROC_SERVER, &IID_IMarshal,
613 (LPVOID*)marshal);
614 }
615 else
616 {
617 FIXME("Invalid or unimplemented marshaling type specified: %lx\n", objref.flags);
619 }
620
621 if (hr != S_OK)
622 ERR("Failed to create marshal, %#lx\n", hr);
623
624 return hr;
625}
626
628{
629 struct stub_manager *stubmgr;
630 struct OR_STANDARD obj;
631 struct apartment *apt;
632 ULONG res;
633 HRESULT hr;
634
635 hr = IStream_Read(stream, &obj, FIELD_OFFSET(struct OR_STANDARD, saResAddr.aStringArray), &res);
636 if (hr != S_OK) return STG_E_READFAULT;
637
638 if (obj.saResAddr.wNumEntries)
639 {
640 ERR("unsupported size of DUALSTRINGARRAY\n");
641 return E_NOTIMPL;
642 }
643
644 TRACE("oxid = %s, oid = %s, ipid = %s\n", wine_dbgstr_longlong(obj.std.oxid),
645 wine_dbgstr_longlong(obj.std.oid), wine_dbgstr_guid(&obj.std.ipid));
646
647 if (!(apt = apartment_findfromoxid(obj.std.oxid)))
648 {
649 WARN("Could not map OXID %s to apartment object\n",
650 wine_dbgstr_longlong(obj.std.oxid));
652 }
653
654 if (!(stubmgr = get_stub_manager(apt, obj.std.oid)))
655 {
657 ERR("could not map object ID to stub manager, oxid=%s, oid=%s\n",
660 }
661
662 stub_manager_release_marshal_data(stubmgr, obj.std.cPublicRefs, &obj.std.ipid, obj.std.flags & SORFP_TABLEWEAK);
663
666
667 return S_OK;
668}
669
670/***********************************************************************
671 * CoReleaseMarshalData (combase.@)
672 */
674{
675 IMarshal *marshal;
676 HRESULT hr;
677
678 TRACE("%p\n", stream);
679
681 if (hr == S_FALSE)
682 {
684 if (hr != S_OK)
685 ERR("StdMarshal ReleaseMarshalData failed with error %#lx\n", hr);
686 return hr;
687 }
688 if (hr != S_OK)
689 return hr;
690
691 /* call the helper object to do the releasing of marshal data */
692 hr = IMarshal_ReleaseMarshalData(marshal, stream);
693 if (hr != S_OK)
694 ERR("IMarshal::ReleaseMarshalData failed with error %#lx\n", hr);
695
696 IMarshal_Release(marshal);
697 return hr;
698}
699
700static HRESULT std_unmarshal_interface(MSHCTX dest_context, void *dest_context_data,
701 IStream *stream, REFIID riid, void **ppv, BOOL dest_context_known)
702{
703 struct stub_manager *stubmgr = NULL;
704 struct OR_STANDARD obj;
705 ULONG res;
707 struct apartment *apt, *stub_apt;
708
709 TRACE("(...,%s,....)\n", debugstr_guid(riid));
710
711 /* we need an apartment to unmarshal into */
712 if (!(apt = apartment_get_current_or_mta()))
713 {
714 ERR("Apartment not initialized\n");
715 return CO_E_NOTINITIALIZED;
716 }
717
718 /* read STDOBJREF from wire */
719 hres = IStream_Read(stream, &obj, FIELD_OFFSET(struct OR_STANDARD, saResAddr.aStringArray), &res);
720 if (hres != S_OK)
721 {
723 return STG_E_READFAULT;
724 }
725
726 if (obj.saResAddr.wNumEntries)
727 {
728 ERR("unsupported size of DUALSTRINGARRAY\n");
729 return E_NOTIMPL;
730 }
731
732 /* check if we're marshalling back to ourselves */
733 if ((apartment_getoxid(apt) == obj.std.oxid) && (stubmgr = get_stub_manager(apt, obj.std.oid)))
734 {
735 TRACE("Unmarshalling object marshalled in same apartment for iid %s, "
736 "returning original object %p\n", debugstr_guid(riid), stubmgr->object);
737
738 hres = IUnknown_QueryInterface(stubmgr->object, riid, ppv);
739
740 /* unref the ifstub. FIXME: only do this on success? */
741 if (!stub_manager_is_table_marshaled(stubmgr, &obj.std.ipid))
742 stub_manager_ext_release(stubmgr, obj.std.cPublicRefs, obj.std.flags & SORFP_TABLEWEAK, FALSE);
743
746 return hres;
747 }
748
749 /* notify stub manager about unmarshal if process-local object.
750 * note: if the oxid is not found then we and native will quite happily
751 * ignore table marshaling and normal marshaling rules regarding number of
752 * unmarshals, etc, but if you abuse these rules then your proxy could end
753 * up returning RPC_E_DISCONNECTED. */
754 if ((stub_apt = apartment_findfromoxid(obj.std.oxid)))
755 {
756 if ((stubmgr = get_stub_manager(stub_apt, obj.std.oid)))
757 {
758 if (!stub_manager_notify_unmarshal(stubmgr, &obj.std.ipid))
760 if (SUCCEEDED(hres) && !dest_context_known)
761 hres = ipid_get_dest_context(&obj.std.ipid, &dest_context, &dest_context_data);
762 }
763 else
764 {
765 WARN("Couldn't find object for OXID %s, OID %s, assuming disconnected\n",
766 wine_dbgstr_longlong(obj.std.oxid),
767 wine_dbgstr_longlong(obj.std.oid));
769 }
770 }
771 else
772 TRACE("Treating unmarshal from OXID %s as inter-process\n",
773 wine_dbgstr_longlong(obj.std.oxid));
774
775 if (hres == S_OK)
776 hres = unmarshal_object(&obj.std, apt, dest_context,
777 dest_context_data, riid,
778 stubmgr ? &stubmgr->oxid_info : NULL, ppv);
779
780 if (stubmgr) stub_manager_int_release(stubmgr);
781 if (stub_apt) apartment_release(stub_apt);
782
783 if (hres != S_OK) WARN("Failed with error %#lx\n", hres);
784 else TRACE("Successfully created proxy %p\n", *ppv);
785
787 return hres;
788}
789
790/***********************************************************************
791 * CoUnmarshalInterface (combase.@)
792 */
794{
795 IMarshal *marshal;
797 HRESULT hr;
798 IID iid;
799
800 TRACE("%p, %s, %p\n", stream, debugstr_guid(riid), ppv);
801
802 if (!stream || !ppv)
803 return E_INVALIDARG;
804
805 hr = get_unmarshaler_from_stream(stream, &marshal, &iid);
806 if (hr == S_FALSE)
807 {
808 hr = std_unmarshal_interface(0, NULL, stream, &iid, (void **)&object, FALSE);
809 if (hr != S_OK)
810 ERR("StdMarshal UnmarshalInterface failed, hr %#lx\n", hr);
811 }
812 else if (hr == S_OK)
813 {
814 /* call the helper object to do the actual unmarshaling */
815 hr = IMarshal_UnmarshalInterface(marshal, stream, &iid, (void **)&object);
816 IMarshal_Release(marshal);
817 if (hr != S_OK)
818 ERR("IMarshal::UnmarshalInterface failed, hr %#lx\n", hr);
819 }
820
821 if (hr == S_OK)
822 {
823 /* IID_NULL means use the interface ID of the marshaled object */
824 if (!IsEqualIID(riid, &IID_NULL) && !IsEqualIID(riid, &iid))
825 {
826 TRACE("requested interface != marshalled interface, additional QI needed\n");
827 hr = IUnknown_QueryInterface(object, riid, ppv);
828 if (hr != S_OK)
829 ERR("Couldn't query for interface %s, hr %#lx\n", debugstr_guid(riid), hr);
830 IUnknown_Release(object);
831 }
832 else
833 {
834 *ppv = object;
835 }
836 }
837
838 TRACE("completed with hr %#lx\n", hr);
839
840 return hr;
841}
842
843/* Marshalling just passes a unique identifier to the remote client,
844 * that makes it possible to find the passed interface again.
845 *
846 * So basically we need a set of values that make it unique.
847 *
848 * Note that the IUnknown_QI(ob,xiid,&ppv) always returns the SAME ppv value!
849 *
850 * A triple is used: OXID (apt id), OID (stub manager id),
851 * IPID (interface ptr/stub id).
852 *
853 * OXIDs identify an apartment and are network scoped
854 * OIDs identify a stub manager and are apartment scoped
855 * IPIDs identify an interface stub and are apartment scoped
856 */
857
859{
860 HRESULT hr;
861 CLSID clsid;
862
864 if (hr != S_OK)
865 return hr;
866 return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER | CLSCTX_PS_DLL, NULL, &IID_IPSFactoryBuffer, (void **)facbuf);
867}
868
869/* marshals an object into a STDOBJREF structure */
870HRESULT marshal_object(struct apartment *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *object,
871 DWORD dest_context, void *dest_context_data, MSHLFLAGS mshlflags)
872{
873 struct stub_manager *manager;
874 struct ifstub *ifstub;
875 BOOL tablemarshal;
876 HRESULT hr;
877
878 stdobjref->oxid = apartment_getoxid(apt);
879
881 if (hr != S_OK)
882 return hr;
883
884 if (!(manager = get_stub_manager_from_object(apt, object, TRUE)))
885 return E_OUTOFMEMORY;
886
887 stdobjref->flags = SORF_NULL;
888 if (mshlflags & MSHLFLAGS_TABLEWEAK)
889 stdobjref->flags |= SORFP_TABLEWEAK;
890 if (mshlflags & MSHLFLAGS_NOPING)
891 stdobjref->flags |= SORF_NOPING;
892 stdobjref->oid = manager->oid;
893
894 tablemarshal = ((mshlflags & MSHLFLAGS_TABLESTRONG) || (mshlflags & MSHLFLAGS_TABLEWEAK));
895
896 /* make sure ifstub that we are creating is unique */
897 ifstub = stub_manager_find_ifstub(manager, riid, mshlflags);
898 if (!ifstub) {
900
901 /* IUnknown doesn't require a stub buffer, because it never goes out on
902 * the wire */
904 {
905 IPSFactoryBuffer *psfb;
906
907 hr = get_facbuf_for_iid(riid, &psfb);
908 if (hr == S_OK) {
909 hr = IPSFactoryBuffer_CreateStub(psfb, riid, manager->object, &stub);
910 IPSFactoryBuffer_Release(psfb);
911 if (hr != S_OK)
912 ERR("Failed to create an IRpcStubBuffer from IPSFactory for %s with error %#lx\n",
914 }else {
915 WARN("couldn't get IPSFactory buffer for interface %s\n", debugstr_guid(riid));
917 }
918
919 }
920
921 if (hr == S_OK) {
922 ifstub = stub_manager_new_ifstub(manager, stub, riid, dest_context, dest_context_data, mshlflags);
923 if (!ifstub)
925 }
926 if (stub) IRpcStubBuffer_Release(stub);
927
928 if (hr != S_OK) {
930 /* destroy the stub manager if it has no ifstubs by releasing
931 * zero external references */
932 stub_manager_ext_release(manager, 0, FALSE, TRUE);
933 return hr;
934 }
935 }
936
937 if (!tablemarshal)
938 {
939 stdobjref->cPublicRefs = NORMALEXTREFS;
940 stub_manager_ext_addref(manager, stdobjref->cPublicRefs, FALSE);
941 }
942 else
943 {
944 stdobjref->cPublicRefs = 0;
945 if (mshlflags & MSHLFLAGS_TABLESTRONG)
946 stub_manager_ext_addref(manager, 1, FALSE);
947 else
948 stub_manager_ext_addref(manager, 0, TRUE);
949 }
950
951 /* FIXME: check return value */
953
954 stdobjref->ipid = ifstub->ipid;
955
957 return S_OK;
958}
959
960/* Client-side identity of the server object */
961
963static void proxy_manager_destroy(struct proxy_manager * This);
964static HRESULT proxy_manager_find_ifproxy(struct proxy_manager * This, REFIID riid, struct ifproxy ** ifproxy_found);
966
968{
969 HRESULT hr;
970 MULTI_QI mqi;
971
972 TRACE("%s\n", debugstr_guid(riid));
973
974 mqi.pIID = riid;
975 hr = IMultiQI_QueryMultipleInterfaces(iface, 1, &mqi);
976 *ppv = mqi.pItf;
977
978 return hr;
979}
980
982{
983 struct proxy_manager *This = impl_from_IMultiQI(iface);
984 TRACE("%p - before %ld\n", iface, This->refs);
985 return InterlockedIncrement(&This->refs);
986}
987
989{
990 struct proxy_manager *This = impl_from_IMultiQI(iface);
992 TRACE("%p - after %ld\n", iface, refs);
993 if (!refs)
995 return refs;
996}
997
999{
1000 struct proxy_manager *This = impl_from_IMultiQI(iface);
1001 REMQIRESULT *qiresults = NULL;
1002 ULONG nonlocal_mqis = 0;
1003 ULONG i;
1004 ULONG successful_mqis = 0;
1005 IID *iids = malloc(cMQIs * sizeof(*iids));
1006 /* mapping of RemQueryInterface index to QueryMultipleInterfaces index */
1007 ULONG *mapping = malloc(cMQIs * sizeof(*mapping));
1008
1009 TRACE("cMQIs: %ld\n", cMQIs);
1010
1011 /* try to get a local interface - this includes already active proxy
1012 * interfaces and also interfaces exposed by the proxy manager */
1013 for (i = 0; i < cMQIs; i++)
1014 {
1015 TRACE("iid[%ld] = %s\n", i, debugstr_guid(pMQIs[i].pIID));
1016 pMQIs[i].hr = proxy_manager_query_local_interface(This, pMQIs[i].pIID, (void **)&pMQIs[i].pItf);
1017 if (pMQIs[i].hr == S_OK)
1018 successful_mqis++;
1019 else
1020 {
1021 iids[nonlocal_mqis] = *pMQIs[i].pIID;
1022 mapping[nonlocal_mqis] = i;
1023 nonlocal_mqis++;
1024 }
1025 }
1026
1027 TRACE("%ld interfaces not found locally\n", nonlocal_mqis);
1028
1029 /* if we have more than one interface not found locally then we must try
1030 * to query the remote object for it */
1031 if (nonlocal_mqis != 0)
1032 {
1034 HRESULT hr;
1035 IPID *ipid;
1036
1037 /* get the ipid of the first entry */
1038 /* FIXME: should we implement ClientIdentity on the ifproxies instead
1039 * of the proxy_manager so we use the correct ipid here? */
1040 ipid = &LIST_ENTRY(list_head(&This->interfaces), struct ifproxy, entry)->stdobjref.ipid;
1041
1042 /* get IRemUnknown proxy so we can communicate with the remote object */
1044
1045 if (SUCCEEDED(hr))
1046 {
1047 hr = IRemUnknown_RemQueryInterface(remunk, ipid, NORMALEXTREFS,
1048 nonlocal_mqis, iids, &qiresults);
1049 IRemUnknown_Release(remunk);
1050 if (FAILED(hr))
1051 WARN("IRemUnknown_RemQueryInterface failed with error %#lx\n", hr);
1052 }
1053
1054 /* IRemUnknown_RemQueryInterface can return S_FALSE if only some of
1055 * the interfaces were returned */
1056 if (SUCCEEDED(hr))
1057 {
1059
1060 /* try to unmarshal each object returned to us */
1061 for (i = 0; i < nonlocal_mqis; i++)
1062 {
1063 ULONG index = mapping[i];
1064 HRESULT hrobj = qiresults[i].hResult;
1065 if (hrobj == S_OK)
1066 hrobj = unmarshal_object(&qiresults[i].std, apt,
1067 This->dest_context,
1068 This->dest_context_data,
1069 pMQIs[index].pIID, &This->oxid_info,
1070 (void **)&pMQIs[index].pItf);
1071
1072 if (hrobj == S_OK)
1073 successful_mqis++;
1074 else
1075 ERR("Failed to get pointer to interface %s\n", debugstr_guid(pMQIs[index].pIID));
1076 pMQIs[index].hr = hrobj;
1077 }
1078
1079 apartment_release(apt);
1080 }
1081
1082 /* free the memory allocated by the proxy */
1083 CoTaskMemFree(qiresults);
1084 }
1085
1086 TRACE("%ld/%ld successfully queried\n", successful_mqis, cMQIs);
1087
1088 free(iids);
1089 free(mapping);
1090
1091 if (successful_mqis == cMQIs)
1092 return S_OK; /* we got all requested interfaces */
1093 else if (successful_mqis == 0)
1094 return E_NOINTERFACE; /* we didn't get any interfaces */
1095 else
1096 return S_FALSE; /* we got some interfaces */
1097}
1098
1099static const IMultiQIVtbl ClientIdentity_Vtbl =
1100{
1105};
1106
1107static HRESULT StdMarshalImpl_Construct(REFIID, DWORD, void*, void**);
1108
1109static HRESULT WINAPI Proxy_QueryInterface(IMarshal *iface, REFIID riid, void **ppvObject)
1110{
1111 struct proxy_manager *This = impl_from_IMarshal( iface );
1112 return IMultiQI_QueryInterface(&This->IMultiQI_iface, riid, ppvObject);
1113}
1114
1116{
1117 struct proxy_manager *This = impl_from_IMarshal( iface );
1118 return IMultiQI_AddRef(&This->IMultiQI_iface);
1119}
1120
1122{
1123 struct proxy_manager *This = impl_from_IMarshal( iface );
1124 return IMultiQI_Release(&This->IMultiQI_iface);
1125}
1126
1128 IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext,
1129 void* pvDestContext, DWORD mshlflags, CLSID* pCid)
1130{
1131 *pCid = CLSID_StdMarshal;
1132 return S_OK;
1133}
1134
1136 IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext,
1137 void* pvDestContext, DWORD mshlflags, DWORD* pSize)
1138{
1139 *pSize = FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray);
1140 return S_OK;
1141}
1142
1143static void fill_std_objref(OBJREF *objref, const GUID *iid, STDOBJREF *std)
1144{
1145 objref->signature = OBJREF_SIGNATURE;
1146 objref->flags = OBJREF_STANDARD;
1147 objref->iid = *iid;
1148 if(std)
1149 objref->u_objref.u_standard.std = *std;
1150 memset(&objref->u_objref.u_standard.saResAddr, 0,
1151 sizeof(objref->u_objref.u_standard.saResAddr));
1152}
1153
1155 LPMARSHAL iface, IStream *pStm, REFIID riid, void* pv, DWORD dwDestContext,
1156 void* pvDestContext, DWORD mshlflags)
1157{
1158 struct proxy_manager *This = impl_from_IMarshal( iface );
1159 HRESULT hr;
1160 struct ifproxy *ifproxy;
1161
1162 TRACE("(...,%s,...)\n", debugstr_guid(riid));
1163
1165 if (SUCCEEDED(hr))
1166 {
1168
1170
1171 if ((mshlflags != MSHLFLAGS_TABLEWEAK) &&
1172 (mshlflags != MSHLFLAGS_TABLESTRONG))
1173 {
1174 ULONG cPublicRefs = ifproxy->refs;
1175 ULONG cPublicRefsOld;
1176 /* optimization - share out proxy's public references if possible
1177 * instead of making new proxy do a roundtrip through the server */
1178 do
1179 {
1180 ULONG cPublicRefsNew;
1181 cPublicRefsOld = cPublicRefs;
1182 stdobjref.cPublicRefs = cPublicRefs / 2;
1183 cPublicRefsNew = cPublicRefs - stdobjref.cPublicRefs;
1184 cPublicRefs = InterlockedCompareExchange(
1185 (LONG *)&ifproxy->refs, cPublicRefsNew, cPublicRefsOld);
1186 } while (cPublicRefs != cPublicRefsOld);
1187 }
1188
1189 /* normal and table-strong marshaling need at least one reference */
1190 if (!stdobjref.cPublicRefs && (mshlflags != MSHLFLAGS_TABLEWEAK))
1191 {
1192 IRemUnknown *remunk;
1194 if (hr == S_OK)
1195 {
1196 HRESULT hrref = S_OK;
1197 REMINTERFACEREF rif;
1198 rif.ipid = ifproxy->stdobjref.ipid;
1199 rif.cPublicRefs = (mshlflags == MSHLFLAGS_TABLESTRONG) ? 1 : NORMALEXTREFS;
1200 rif.cPrivateRefs = 0;
1201 hr = IRemUnknown_RemAddRef(remunk, 1, &rif, &hrref);
1202 IRemUnknown_Release(remunk);
1203 if (hr == S_OK && hrref == S_OK)
1204 {
1205 /* table-strong marshaling doesn't give the refs to the
1206 * client that unmarshals the STDOBJREF */
1207 if (mshlflags != MSHLFLAGS_TABLESTRONG)
1208 stdobjref.cPublicRefs = rif.cPublicRefs;
1209 }
1210 else
1211 ERR("IRemUnknown_RemAddRef returned with %#lx, hrref = %#lx\n", hr, hrref);
1212 }
1213 }
1214
1215 if (SUCCEEDED(hr))
1216 {
1217 OBJREF objref;
1218
1219 TRACE("writing stdobjref: flags = %#lx cPublicRefs = %ld oxid = %s oid = %s ipid = %s\n",
1224 fill_std_objref(&objref, riid, &stdobjref);
1225 hr = IStream_Write(pStm, &objref, FIELD_OFFSET(OBJREF,
1226 u_objref.u_standard.saResAddr.aStringArray), NULL);
1227 }
1228 }
1229 else
1230 {
1231 /* we don't have the interface already unmarshaled so we have to
1232 * request the object from the server */
1233 IRemUnknown *remunk;
1234 IPID *ipid;
1235 REMQIRESULT *qiresults = NULL;
1236 IID iid = *riid;
1237
1238 /* get the ipid of the first entry */
1239 /* FIXME: should we implement ClientIdentity on the ifproxies instead
1240 * of the proxy_manager so we use the correct ipid here? */
1241 ipid = &LIST_ENTRY(list_head(&This->interfaces), struct ifproxy, entry)->stdobjref.ipid;
1242
1243 /* get IRemUnknown proxy so we can communicate with the remote object */
1245
1246 if (hr == S_OK)
1247 {
1248 hr = IRemUnknown_RemQueryInterface(remunk, ipid, NORMALEXTREFS,
1249 1, &iid, &qiresults);
1250 if (SUCCEEDED(hr))
1251 {
1252 OBJREF objref;
1253
1254 fill_std_objref(&objref, riid, &qiresults->std);
1255 hr = IStream_Write(pStm, &objref, FIELD_OFFSET(OBJREF,
1256 u_objref.u_standard.saResAddr.aStringArray), NULL);
1257 if (FAILED(hr))
1258 {
1259 REMINTERFACEREF rif;
1260 rif.ipid = qiresults->std.ipid;
1261 rif.cPublicRefs = qiresults->std.cPublicRefs;
1262 rif.cPrivateRefs = 0;
1263 IRemUnknown_RemRelease(remunk, 1, &rif);
1264 }
1265 CoTaskMemFree(qiresults);
1266 }
1267 else
1268 ERR("IRemUnknown_RemQueryInterface failed with error %#lx\n", hr);
1269 IRemUnknown_Release(remunk);
1270 }
1271 }
1272
1273 return hr;
1274}
1275
1277 IMarshal *iface, IStream *pStm, REFIID riid, void **ppv)
1278{
1279 struct proxy_manager *This = impl_from_IMarshal( iface );
1280 IMarshal *marshal;
1281 HRESULT hr;
1282
1283 TRACE("(%p, %p, %s, %p)\n", This, pStm, wine_dbgstr_guid(riid), ppv);
1284
1285 hr = StdMarshalImpl_Construct(&IID_IMarshal, This->dest_context,
1286 This->dest_context_data, (void**)&marshal);
1287 if(FAILED(hr))
1288 return hr;
1289
1290 hr = IMarshal_UnmarshalInterface(marshal, pStm, riid, ppv);
1291 IMarshal_Release(marshal);
1292 return hr;
1293}
1294
1296{
1297 struct proxy_manager *This = impl_from_IMarshal( iface );
1298 IMarshal *marshal;
1299 HRESULT hr;
1300
1301 TRACE("(%p, %p)\n", This, pStm);
1302
1303 hr = StdMarshalImpl_Construct(&IID_IMarshal, This->dest_context,
1304 This->dest_context_data, (void**)&marshal);
1305 if(FAILED(hr))
1306 return hr;
1307
1308 hr = IMarshal_ReleaseMarshalData(marshal, pStm);
1309 IMarshal_Release(marshal);
1310 return hr;
1311}
1312
1314{
1315 struct proxy_manager *This = impl_from_IMarshal( iface );
1316 IMarshal *marshal;
1317 HRESULT hr;
1318
1319 TRACE("%p, %#lx\n", This, dwReserved);
1320
1321 hr = StdMarshalImpl_Construct(&IID_IMarshal, This->dest_context,
1322 This->dest_context_data, (void**)&marshal);
1323 if(FAILED(hr))
1324 return hr;
1325
1326 hr = IMarshal_DisconnectObject(marshal, dwReserved);
1327 IMarshal_Release(marshal);
1328 return hr;
1329}
1330
1331static const IMarshalVtbl ProxyMarshal_Vtbl =
1332{
1342};
1343
1345{
1346 struct proxy_manager *This = impl_from_IClientSecurity( iface );
1347 return IMultiQI_QueryInterface(&This->IMultiQI_iface, riid, ppvObject);
1348}
1349
1351{
1352 struct proxy_manager *This = impl_from_IClientSecurity( iface );
1353 return IMultiQI_AddRef(&This->IMultiQI_iface);
1354}
1355
1357{
1358 struct proxy_manager *This = impl_from_IClientSecurity( iface );
1359 return IMultiQI_Release(&This->IMultiQI_iface);
1360}
1361
1363 IUnknown *pProxy,
1364 DWORD *pAuthnSvc,
1365 DWORD *pAuthzSvc,
1366 OLECHAR **ppServerPrincName,
1367 DWORD *pAuthnLevel,
1368 DWORD *pImpLevel,
1369 void **pAuthInfo,
1370 DWORD *pCapabilities)
1371{
1372 FIXME("(%p, %p, %p, %p, %p, %p, %p, %p): stub\n", pProxy, pAuthnSvc,
1373 pAuthzSvc, ppServerPrincName, pAuthnLevel, pImpLevel, pAuthInfo,
1374 pCapabilities);
1375
1376 if (pAuthnSvc)
1377 *pAuthnSvc = 0;
1378 if (pAuthzSvc)
1379 *pAuthzSvc = 0;
1380 if (ppServerPrincName)
1381 *ppServerPrincName = NULL;
1382 if (pAuthnLevel)
1383 *pAuthnLevel = RPC_C_AUTHN_LEVEL_DEFAULT;
1384 if (pImpLevel)
1385 *pImpLevel = RPC_C_IMP_LEVEL_DEFAULT;
1386 if (pAuthInfo)
1387 *pAuthInfo = NULL;
1388 if (pCapabilities)
1389 *pCapabilities = EOAC_NONE;
1390
1391 return E_NOTIMPL;
1392}
1393
1395 IUnknown *pProxy, DWORD AuthnSvc,
1396 DWORD AuthzSvc,
1397 OLECHAR *pServerPrincName,
1398 DWORD AuthnLevel, DWORD ImpLevel,
1399 void *pAuthInfo,
1401{
1402 FIXME("%p, %ld, %ld, %s, %ld, %ld, %p, %#lx: stub\n", pProxy, AuthnSvc, AuthzSvc,
1403 pServerPrincName == COLE_DEFAULT_PRINCIPAL ? "<default principal>" : debugstr_w(pServerPrincName),
1404 AuthnLevel, ImpLevel, pAuthInfo, Capabilities);
1405 return E_NOTIMPL;
1406}
1407
1409 IUnknown *pProxy, IUnknown **ppCopy)
1410{
1411 FIXME("(%p, %p): stub\n", pProxy, ppCopy);
1412 *ppCopy = NULL;
1413 return E_NOTIMPL;
1414}
1415
1416static const IClientSecurityVtbl ProxyCliSec_Vtbl =
1417{
1424};
1425
1427{
1428 HRESULT hr = S_OK;
1429
1430 if (WAIT_OBJECT_0 != WaitForSingleObject(This->parent->remoting_mutex, INFINITE))
1431 {
1432 ERR("Wait failed for ifproxy %p\n", This);
1433 return E_UNEXPECTED;
1434 }
1435
1436 if (This->refs == 0)
1437 {
1439
1440 TRACE("getting public ref for ifproxy %p\n", This);
1441
1443 if (hr == S_OK)
1444 {
1445 HRESULT hrref = S_OK;
1446 REMINTERFACEREF rif;
1447 rif.ipid = This->stdobjref.ipid;
1448 rif.cPublicRefs = NORMALEXTREFS;
1449 rif.cPrivateRefs = 0;
1450 hr = IRemUnknown_RemAddRef(remunk, 1, &rif, &hrref);
1451 IRemUnknown_Release(remunk);
1452 if (hr == S_OK && hrref == S_OK)
1454 else
1455 ERR("IRemUnknown_RemAddRef returned with %#lx, hrref = %#lx\n", hr, hrref);
1456 }
1457 }
1458 ReleaseMutex(This->parent->remoting_mutex);
1459
1460 return hr;
1461}
1462
1464{
1465 HRESULT hr = S_OK;
1466 LONG public_refs;
1467
1468 if (WAIT_OBJECT_0 != WaitForSingleObject(This->parent->remoting_mutex, INFINITE))
1469 {
1470 ERR("Wait failed for ifproxy %p\n", This);
1471 return E_UNEXPECTED;
1472 }
1473
1474 public_refs = This->refs;
1475 if (public_refs > 0)
1476 {
1478
1479 TRACE("releasing %ld refs\n", public_refs);
1480
1482 if (hr == S_OK)
1483 {
1484 REMINTERFACEREF rif;
1485 rif.ipid = This->stdobjref.ipid;
1486 rif.cPublicRefs = public_refs;
1487 rif.cPrivateRefs = 0;
1488 hr = IRemUnknown_RemRelease(remunk, 1, &rif);
1489 IRemUnknown_Release(remunk);
1490 if (hr == S_OK)
1491 InterlockedExchangeAdd((LONG *)&This->refs, -public_refs);
1492 else if (hr == RPC_E_DISCONNECTED)
1493 WARN("couldn't release references because object was "
1494 "disconnected: oxid = %s, oid = %s\n",
1495 wine_dbgstr_longlong(This->parent->oxid),
1496 wine_dbgstr_longlong(This->parent->oid));
1497 else
1498 ERR("IRemUnknown_RemRelease failed with error %#lx\n", hr);
1499 }
1500 }
1501 ReleaseMutex(This->parent->remoting_mutex);
1502
1503 return hr;
1504}
1505
1506/* should be called inside This->parent->cs critical section */
1507static void ifproxy_disconnect(struct ifproxy * This)
1508{
1510 if (This->proxy) IRpcProxyBuffer_Disconnect(This->proxy);
1511
1512 IRpcChannelBuffer_Release(This->chan);
1513 This->chan = NULL;
1514}
1515
1516/* should be called in This->parent->cs critical section if it is an entry in parent's list */
1517static void ifproxy_destroy(struct ifproxy * This)
1518{
1519 TRACE("%p\n", This);
1520
1521 /* release public references to this object so that the stub can know
1522 * when to destroy itself */
1524
1525 list_remove(&This->entry);
1526
1527 if (This->chan)
1528 {
1529 IRpcChannelBuffer_Release(This->chan);
1530 This->chan = NULL;
1531 }
1532
1533 if (This->proxy) IRpcProxyBuffer_Release(This->proxy);
1534
1535 free(This);
1536}
1537
1539 struct apartment * apt, ULONG sorflags, OXID oxid, OID oid,
1540 const OXID_INFO *oxid_info, struct proxy_manager ** proxy_manager)
1541{
1542 struct proxy_manager * This = malloc(sizeof(*This));
1543 if (!This) return E_OUTOFMEMORY;
1544
1545 This->remoting_mutex = CreateMutexW(NULL, FALSE, NULL);
1546 if (!This->remoting_mutex)
1547 {
1548 free(This);
1550 }
1551
1552 if (oxid_info)
1553 {
1554 This->oxid_info.dwPid = oxid_info->dwPid;
1555 This->oxid_info.dwTid = oxid_info->dwTid;
1556 This->oxid_info.ipidRemUnknown = oxid_info->ipidRemUnknown;
1557 This->oxid_info.dwAuthnHint = oxid_info->dwAuthnHint;
1558 This->oxid_info.psa = NULL /* FIXME: copy from oxid_info */;
1559 }
1560 else
1561 {
1562 HRESULT hr = rpc_resolve_oxid(oxid, &This->oxid_info);
1563 if (FAILED(hr))
1564 {
1565 CloseHandle(This->remoting_mutex);
1566 free(This);
1567 return hr;
1568 }
1569 }
1570
1571 This->IMultiQI_iface.lpVtbl = &ClientIdentity_Vtbl;
1572 This->IMarshal_iface.lpVtbl = &ProxyMarshal_Vtbl;
1573 This->IClientSecurity_iface.lpVtbl = &ProxyCliSec_Vtbl;
1574
1575 list_init(&This->entry);
1576 list_init(&This->interfaces);
1577
1579 This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": proxy_manager");
1580
1581 /* the apartment the object was unmarshaled into */
1582 This->parent = apt;
1583
1584 /* the source apartment and id of the object */
1585 This->oxid = oxid;
1586 This->oid = oid;
1587
1588 This->refs = 1;
1589
1590 /* the DCOM draft specification states that the SORF_NOPING flag is
1591 * proxy manager specific, not ifproxy specific, so this implies that we
1592 * should store the STDOBJREF flags here in the proxy manager. */
1593 This->sorflags = sorflags;
1594
1595 /* we create the IRemUnknown proxy on demand */
1596 This->remunk = NULL;
1597
1598 /* initialise these values to the weakest values and they will be
1599 * overwritten in proxy_manager_set_context */
1600 This->dest_context = MSHCTX_INPROC;
1601 This->dest_context_data = NULL;
1602
1603 EnterCriticalSection(&apt->cs);
1604 /* FIXME: we are dependent on the ordering in here to make sure a proxy's
1605 * IRemUnknown proxy doesn't get destroyed before the regular proxy does
1606 * because we need the IRemUnknown proxy during the destruction of the
1607 * regular proxy. Ideally, we should maintain a separate list for the
1608 * IRemUnknown proxies that need late destruction */
1609 list_add_tail(&apt->proxies, &This->entry);
1610 LeaveCriticalSection(&apt->cs);
1611
1612 TRACE("%p created for OXID %s, OID %s\n", This,
1614
1616 return S_OK;
1617}
1618
1620{
1621 MSHCTX old_dest_context;
1622 MSHCTX new_dest_context;
1623
1624 do
1625 {
1626 old_dest_context = This->dest_context;
1627 new_dest_context = old_dest_context;
1628 /* "stronger" values overwrite "weaker" values. stronger values are
1629 * ones that disable more optimisations */
1630 switch (old_dest_context)
1631 {
1632 case MSHCTX_INPROC:
1633 new_dest_context = dest_context;
1634 break;
1635 case MSHCTX_CROSSCTX:
1636 switch (dest_context)
1637 {
1638 case MSHCTX_INPROC:
1639 break;
1640 default:
1641 new_dest_context = dest_context;
1642 }
1643 break;
1644 case MSHCTX_LOCAL:
1645 switch (dest_context)
1646 {
1647 case MSHCTX_INPROC:
1648 case MSHCTX_CROSSCTX:
1649 break;
1650 default:
1651 new_dest_context = dest_context;
1652 }
1653 break;
1654 case MSHCTX_NOSHAREDMEM:
1655 switch (dest_context)
1656 {
1657 case MSHCTX_DIFFERENTMACHINE:
1658 new_dest_context = dest_context;
1659 break;
1660 default:
1661 break;
1662 }
1663 break;
1664 default:
1665 break;
1666 }
1667
1668 if (old_dest_context == new_dest_context) break;
1669
1670 new_dest_context = InterlockedCompareExchange((PLONG)&This->dest_context, new_dest_context, old_dest_context);
1671 } while (new_dest_context != old_dest_context);
1672
1675}
1676
1678{
1679 HRESULT hr;
1680 struct ifproxy * ifproxy;
1681
1682 TRACE("%s\n", debugstr_guid(riid));
1683
1684 if (IsEqualIID(riid, &IID_IUnknown) ||
1685 IsEqualIID(riid, &IID_IMultiQI))
1686 {
1687 *ppv = &This->IMultiQI_iface;
1688 IMultiQI_AddRef(&This->IMultiQI_iface);
1689 return S_OK;
1690 }
1691 if (IsEqualIID(riid, &IID_IMarshal))
1692 {
1693 *ppv = &This->IMarshal_iface;
1694 IMarshal_AddRef(&This->IMarshal_iface);
1695 return S_OK;
1696 }
1697 if (IsEqualIID(riid, &IID_IClientSecurity))
1698 {
1699 *ppv = &This->IClientSecurity_iface;
1700 IClientSecurity_AddRef(&This->IClientSecurity_iface);
1701 return S_OK;
1702 }
1703
1705 if (hr == S_OK)
1706 {
1707 *ppv = ifproxy->iface;
1708 IUnknown_AddRef((IUnknown *)*ppv);
1709 return S_OK;
1710 }
1711
1712 *ppv = NULL;
1713 return E_NOINTERFACE;
1714}
1715
1717 struct proxy_manager * This, const STDOBJREF *stdobjref, REFIID riid,
1718 IRpcChannelBuffer * channel, struct ifproxy ** iif_out)
1719{
1720 HRESULT hr;
1721 IPSFactoryBuffer * psfb;
1722 struct ifproxy * ifproxy = malloc(sizeof(*ifproxy));
1723 if (!ifproxy) return E_OUTOFMEMORY;
1724
1726
1727 ifproxy->parent = This;
1729 ifproxy->iid = *riid;
1730 ifproxy->refs = 0;
1731 ifproxy->proxy = NULL;
1732
1733 assert(channel);
1734 ifproxy->chan = channel; /* FIXME: we should take the binding strings and construct the channel in this function */
1735
1736 /* the IUnknown interface is special because it does not have a
1737 * proxy associated with the ifproxy as we handle IUnknown ourselves */
1739 {
1740 ifproxy->iface = &This->IMultiQI_iface;
1741 IMultiQI_AddRef(&This->IMultiQI_iface);
1742 hr = S_OK;
1743 }
1744 else
1745 {
1746 hr = get_facbuf_for_iid(riid, &psfb);
1747 if (hr == S_OK)
1748 {
1749 /* important note: the outer unknown is set to the proxy manager.
1750 * This ensures the COM identity rules are not violated, by having a
1751 * one-to-one mapping of objects on the proxy side to objects on the
1752 * stub side, no matter which interface you view the object through */
1753 hr = IPSFactoryBuffer_CreateProxy(psfb, (IUnknown*)&This->IMultiQI_iface, riid,
1754 &ifproxy->proxy, &ifproxy->iface);
1755 IPSFactoryBuffer_Release(psfb);
1756 if (hr != S_OK)
1757 ERR("Could not create proxy for interface %s, error %#lx\n", debugstr_guid(riid), hr);
1758 }
1759 else
1760 ERR("Could not get IPSFactoryBuffer for interface %s, error %#lx\n", debugstr_guid(riid), hr);
1761
1762 if (hr == S_OK)
1763 hr = IRpcProxyBuffer_Connect(ifproxy->proxy, ifproxy->chan);
1764 }
1765
1766 if (hr == S_OK)
1767 {
1769 list_add_tail(&This->interfaces, &ifproxy->entry);
1771
1772 *iif_out = ifproxy;
1773 TRACE("ifproxy %p created for IPID %s, interface %s with %lu public refs\n",
1775 }
1776 else
1778
1779 return hr;
1780}
1781
1782static HRESULT proxy_manager_find_ifproxy(struct proxy_manager * This, REFIID riid, struct ifproxy ** ifproxy_found)
1783{
1784 HRESULT hr = E_NOINTERFACE; /* assume not found */
1785 struct ifproxy *ifproxy;
1786
1788 LIST_FOR_EACH_ENTRY(ifproxy, &This->interfaces, struct ifproxy, entry)
1789 {
1790 if (IsEqualIID(riid, &ifproxy->iid))
1791 {
1792 *ifproxy_found = ifproxy;
1793 hr = S_OK;
1794 break;
1795 }
1796 }
1798
1799 return hr;
1800}
1801
1803{
1804 struct ifproxy *ifproxy;
1805
1806 TRACE("oxid = %s, oid = %s\n", wine_dbgstr_longlong(This->oxid),
1808
1810
1811 /* SORFP_NOLIFTIMEMGMT proxies (for IRemUnknown) shouldn't be
1812 * disconnected - it won't do anything anyway, except cause
1813 * problems for other objects that depend on this proxy always
1814 * working */
1815 if (!(This->sorflags & SORFP_NOLIFETIMEMGMT))
1816 {
1817 LIST_FOR_EACH_ENTRY(ifproxy, &This->interfaces, struct ifproxy, entry)
1818 {
1820 }
1821 }
1822
1823 /* apartment is being destroyed so don't keep a pointer around to it */
1824 This->parent = NULL;
1825
1827}
1828
1830{
1831 HRESULT hr = S_OK;
1832 struct apartment *apt;
1833 BOOL called_in_original_apt;
1834
1835 /* we don't want to try and unmarshal or use IRemUnknown if we don't want
1836 * lifetime management */
1837 if (This->sorflags & SORFP_NOLIFETIMEMGMT)
1838 return S_FALSE;
1839
1840 if (!(apt = apartment_get_current_or_mta()))
1841 return CO_E_NOTINITIALIZED;
1842
1843 called_in_original_apt = This->parent && (This->parent->oxid == apt->oxid);
1844
1846 /* only return the cached object if called from the original apartment.
1847 * in future, we might want to make the IRemUnknown proxy callable from any
1848 * apartment to avoid these checks */
1849 if (This->remunk && called_in_original_apt)
1850 {
1851 /* already created - return existing object */
1852 *remunk = This->remunk;
1853 IRemUnknown_AddRef(*remunk);
1854 }
1855 else if (!This->parent)
1856 {
1857 /* disconnected - we can't create IRemUnknown */
1858 *remunk = NULL;
1859 hr = S_FALSE;
1860 }
1861 else
1862 {
1863 STDOBJREF stdobjref;
1864 /* Don't want IRemUnknown lifetime management as this is IRemUnknown!
1865 * We also don't care about whether or not the stub is still alive */
1866 stdobjref.flags = SORFP_NOLIFETIMEMGMT | SORF_NOPING;
1867 stdobjref.cPublicRefs = 1;
1868 /* oxid of destination object */
1869 stdobjref.oxid = This->oxid;
1870 /* FIXME: what should be used for the oid? The DCOM draft doesn't say */
1871 stdobjref.oid = (OID)-1;
1872 stdobjref.ipid = This->oxid_info.ipidRemUnknown;
1873
1874 /* do the unmarshal */
1875 hr = unmarshal_object(&stdobjref, apt, This->dest_context,
1876 This->dest_context_data, &IID_IRemUnknown,
1877 &This->oxid_info, (void**)remunk);
1878 if (hr == S_OK && called_in_original_apt)
1879 {
1880 This->remunk = *remunk;
1881 IRemUnknown_AddRef(This->remunk);
1882 }
1883 }
1885 apartment_release(apt);
1886
1887 TRACE("got IRemUnknown* pointer %p, hr = %#lx\n", *remunk, hr);
1888
1889 return hr;
1890}
1891
1892/*
1893 * Safely increment the reference count of a proxy manager obtained from an
1894 * apartment proxy list.
1895 *
1896 * This function shall be called inside the apartment's critical section.
1897 */
1899{
1900 LONG refs = ReadNoFence(&This->refs);
1901 LONG old_refs, new_refs;
1902
1903 do
1904 {
1905 if (refs == 0)
1906 {
1907 /* This proxy manager is about to be destroyed */
1908 return 0;
1909 }
1910
1911 old_refs = refs;
1912 new_refs = refs + 1;
1913 } while ((refs = InterlockedCompareExchange(&This->refs, new_refs, old_refs)) != old_refs);
1914
1915 return new_refs;
1916}
1917
1918/* destroys a proxy manager, freeing the memory it used.
1919 * Note: this function should not be called from a list iteration in the
1920 * apartment, due to the fact that it removes itself from the apartment and
1921 * it could add a proxy to IRemUnknown into the apartment. */
1923{
1924 struct list * cursor;
1925
1926 TRACE("oxid = %s, oid = %s\n", wine_dbgstr_longlong(This->oxid),
1928
1929 if (This->parent)
1930 {
1931 EnterCriticalSection(&This->parent->cs);
1932
1933 /* remove ourself from the list of proxy objects in the apartment */
1934 LIST_FOR_EACH(cursor, &This->parent->proxies)
1935 {
1936 if (cursor == &This->entry)
1937 {
1938 list_remove(&This->entry);
1939 break;
1940 }
1941 }
1942
1943 LeaveCriticalSection(&This->parent->cs);
1944 }
1945
1946 /* destroy all of the interface proxies */
1947 while ((cursor = list_head(&This->interfaces)))
1948 {
1949 struct ifproxy * ifproxy = LIST_ENTRY(cursor, struct ifproxy, entry);
1951 }
1952
1953 if (This->remunk) IRemUnknown_Release(This->remunk);
1954 CoTaskMemFree(This->oxid_info.psa);
1955
1956 This->cs.DebugInfo->Spare[0] = 0;
1958
1959 CloseHandle(This->remoting_mutex);
1960
1961 free(This);
1962}
1963
1964/* finds the proxy manager corresponding to a given OXID and OID that has
1965 * been unmarshaled in the specified apartment. The caller must release the
1966 * reference to the proxy_manager when the object is no longer used. */
1967static BOOL find_proxy_manager(struct apartment * apt, OXID oxid, OID oid, struct proxy_manager ** proxy_found)
1968{
1969 struct proxy_manager *proxy;
1970 BOOL found = FALSE;
1971
1972 EnterCriticalSection(&apt->cs);
1974 {
1975 if ((oxid == proxy->oxid) && (oid == proxy->oid))
1976 {
1977 /* be careful of a race with ClientIdentity_Release, which would
1978 * cause us to return a proxy which is in the process of being
1979 * destroyed */
1981 {
1982 *proxy_found = proxy;
1983 found = TRUE;
1984 break;
1985 }
1986 }
1987 }
1988 LeaveCriticalSection(&apt->cs);
1989 return found;
1990}
1991
1993{
1994 struct proxy_manager *proxy;
1995
1997 {
1999 }
2000
2001 return S_OK;
2002}
2003
2004/********************** StdMarshal implementation ****************************/
2005
2007{
2012};
2013
2014static inline struct stdmarshal *impl_from_StdMarshal(IMarshal *iface)
2015{
2016 return CONTAINING_RECORD(iface, struct stdmarshal, IMarshal_iface);
2017}
2018
2020{
2021 *ppv = NULL;
2022 if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IMarshal, riid))
2023 {
2024 *ppv = iface;
2025 IMarshal_AddRef(iface);
2026 return S_OK;
2027 }
2028 FIXME("No interface for %s.\n", debugstr_guid(riid));
2029 return E_NOINTERFACE;
2030}
2031
2033{
2034 struct stdmarshal *marshal = impl_from_StdMarshal(iface);
2035 return InterlockedIncrement(&marshal->refcount);
2036}
2037
2039{
2040 struct stdmarshal *marshal = impl_from_StdMarshal(iface);
2042
2043 if (!refcount)
2044 free(marshal);
2045
2046 return refcount;
2047}
2048
2050 DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *pCid)
2051{
2052 *pCid = CLSID_StdMarshal;
2053 return S_OK;
2054}
2055
2057 DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *pSize)
2058{
2059 *pSize = FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray);
2060 return S_OK;
2061}
2062
2064 DWORD dest_context, void *dest_context_data, DWORD mshlflags)
2065{
2066 ULONG res;
2067 HRESULT hr;
2068 OBJREF objref;
2069 struct apartment *apt;
2070
2071 TRACE("(...,%s,...)\n", debugstr_guid(riid));
2072
2073 if (!(apt = apartment_get_current_or_mta()))
2074 {
2075 ERR("Apartment not initialized\n");
2076 return CO_E_NOTINITIALIZED;
2077 }
2078
2079 /* make sure this apartment can be reached from other threads / processes */
2080 rpc_start_remoting(apt);
2081
2082 fill_std_objref(&objref, riid, NULL);
2083 hr = marshal_object(apt, &objref.u_objref.u_standard.std, riid, pv, dest_context,
2084 dest_context_data, mshlflags);
2085 apartment_release(apt);
2086 if (hr != S_OK)
2087 {
2088 ERR("Failed to create ifstub, hr %#lx\n", hr);
2089 return hr;
2090 }
2091
2092 return IStream_Write(stream, &objref, FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray), &res);
2093}
2094
2095/* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with
2096 * no questions asked about the rules surrounding same-apartment unmarshals
2097 * and table marshaling */
2098static HRESULT unmarshal_object(const STDOBJREF *stdobjref, struct apartment *apt, MSHCTX dest_context,
2099 void *dest_context_data, REFIID riid, const OXID_INFO *oxid_info, void **object)
2100{
2102 HRESULT hr = S_OK;
2103
2104 assert(apt);
2105
2106 TRACE("stdobjref: flags = %#lx cPublicRefs = %ld oxid = %s oid = %s ipid = %s\n",
2107 stdobjref->flags, stdobjref->cPublicRefs,
2108 wine_dbgstr_longlong(stdobjref->oxid),
2109 wine_dbgstr_longlong(stdobjref->oid),
2110 debugstr_guid(&stdobjref->ipid));
2111
2112 /* create a new proxy manager if one doesn't already exist for the
2113 * object */
2114 if (!find_proxy_manager(apt, stdobjref->oxid, stdobjref->oid, &proxy_manager))
2115 {
2116 hr = proxy_manager_construct(apt, stdobjref->flags,
2117 stdobjref->oxid, stdobjref->oid, oxid_info,
2118 &proxy_manager);
2119 }
2120 else
2121 TRACE("proxy manager already created, using\n");
2122
2123 if (hr == S_OK)
2124 {
2125 struct ifproxy * ifproxy;
2126
2127 proxy_manager_set_context(proxy_manager, dest_context, dest_context_data);
2128
2130 if (hr == E_NOINTERFACE)
2131 {
2132 IRpcChannelBuffer *chanbuf;
2135 proxy_manager->dest_context_data, &chanbuf, apt);
2136 if (hr == S_OK)
2138 }
2139 else
2140 IUnknown_AddRef((IUnknown *)ifproxy->iface);
2141
2142 if (hr == S_OK)
2143 {
2145 /* get at least one external reference to the object to keep it alive */
2147 if (FAILED(hr))
2149 }
2150
2151 if (hr == S_OK)
2152 *object = ifproxy->iface;
2153 }
2154
2155 /* release our reference to the proxy manager - the client/apartment
2156 * will hold on to the remaining reference for us */
2157 if (proxy_manager) IMultiQI_Release(&proxy_manager->IMultiQI_iface);
2158
2159 return hr;
2160}
2161
2163{
2164 struct stdmarshal *marshal = impl_from_StdMarshal(iface);
2165 OBJREF objref;
2166 HRESULT hr;
2167 ULONG res;
2168
2169 hr = IStream_Read(stream, &objref, FIELD_OFFSET(OBJREF, u_objref), &res);
2170 if (hr != S_OK || (res != FIELD_OFFSET(OBJREF, u_objref)))
2171 {
2172 ERR("Failed to read common OBJREF header, %#lx\n", hr);
2173 return STG_E_READFAULT;
2174 }
2175
2176 if (objref.signature != OBJREF_SIGNATURE)
2177 {
2178 ERR("Bad OBJREF signature %#lx\n", objref.signature);
2179 return RPC_E_INVALID_OBJREF;
2180 }
2181
2182 if (!(objref.flags & OBJREF_STANDARD))
2183 {
2184 FIXME("unsupported objref.flags = %lx\n", objref.flags);
2185 return E_NOTIMPL;
2186 }
2187
2189}
2190
2192{
2193 OBJREF objref;
2194 HRESULT hr;
2195 ULONG res;
2196
2197 TRACE("%p, %p\n", iface, stream);
2198
2199 hr = IStream_Read(stream, &objref, FIELD_OFFSET(OBJREF, u_objref), &res);
2200 if (hr != S_OK || (res != FIELD_OFFSET(OBJREF, u_objref)))
2201 {
2202 ERR("Failed to read common OBJREF header, %#lx\n", hr);
2203 return STG_E_READFAULT;
2204 }
2205
2206 if (objref.signature != OBJREF_SIGNATURE)
2207 {
2208 ERR("Bad OBJREF signature %#lx\n", objref.signature);
2209 return RPC_E_INVALID_OBJREF;
2210 }
2211
2212 if (!(objref.flags & OBJREF_STANDARD))
2213 {
2214 FIXME("unsupported objref.flags = %lx\n", objref.flags);
2215 return E_NOTIMPL;
2216 }
2217
2219}
2220
2222{
2223 FIXME("(), stub!\n");
2224 return S_OK;
2225}
2226
2227static const IMarshalVtbl StdMarshalVtbl =
2228{
2238};
2239
2241{
2242 struct stdmarshal *object;
2243 HRESULT hr;
2244
2245 object = malloc(sizeof(*object));
2246 if (!object)
2247 return E_OUTOFMEMORY;
2248
2249 object->IMarshal_iface.lpVtbl = &StdMarshalVtbl;
2250 object->refcount = 1;
2251 object->dest_context = dest_context;
2252 object->dest_context_data = dest_context_data;
2253
2254 hr = IMarshal_QueryInterface(&object->IMarshal_iface, riid, ppvObject);
2255 IMarshal_Release(&object->IMarshal_iface);
2256
2257 return hr;
2258}
2259
2261{
2263}
2264
2265/***********************************************************************
2266 * CoGetStandardMarshal (combase.@)
2267 */
2269 void *dest_context, DWORD flags, IMarshal **marshal)
2270{
2271 if (pUnk == NULL)
2272 {
2273 FIXME("%s, NULL, %lx, %p, %lx, %p, unimplemented yet.\n", debugstr_guid(riid), dwDestContext,
2274 dest_context, flags, marshal);
2275 return E_NOTIMPL;
2276 }
2277 TRACE("%s, %p, %lx, %p, %lx, %p\n", debugstr_guid(riid), pUnk, dwDestContext, dest_context, flags, marshal);
2278
2279 return StdMarshalImpl_Construct(&IID_IMarshal, dwDestContext, dest_context, (void **)marshal);
2280}
#define CO_E_NOTINITIALIZED
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
HRESULT apartment_createwindowifneeded(struct apartment *apt)
Definition: apartment.c:1250
void apartment_release(struct apartment *apt)
Definition: apartment.c:444
OXID apartment_getoxid(const struct apartment *apt)
Definition: apartment.c:1284
struct apartment * apartment_findfromoxid(OXID oxid)
Definition: apartment.c:635
struct apartment * apartment_get_current_or_mta(void)
Definition: apartment.c:623
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
const CLSID CLSID_StdMarshal
const CLSID CLSID_InProcFreeMarshaler
Definition: list.h:37
struct ifstub * stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, REFIID iid, DWORD dest_context, void *dest_context_data, MSHLFLAGS flags)
Definition: stubmanager.c:71
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases)
Definition: stubmanager.c:437
struct stub_manager * get_stub_manager_from_object(struct apartment *apt, IUnknown *object, BOOL alloc)
Definition: stubmanager.c:335
HRESULT rpc_create_clientchannel(const OXID *oxid, const IPID *ipid, const OXID_INFO *oxid_info, const IID *iid, DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan, struct apartment *apt)
Definition: rpc.c:1642
ULONG stub_manager_int_release(struct stub_manager *stub_manager)
Definition: stubmanager.c:309
void rpc_start_remoting(struct apartment *apt)
Definition: rpc.c:2186
BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid)
Definition: stubmanager.c:630
struct stub_manager * get_stub_manager(struct apartment *apt, OID oid)
Definition: stubmanager.c:381
HRESULT ipid_get_dest_context(const IPID *ipid, MSHCTX *dest_context, void **dest_context_data)
Definition: stubmanager.c:557
BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid)
Definition: stubmanager.c:583
struct ifstub * stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags)
Definition: stubmanager.c:156
HRESULT rpc_resolve_oxid(OXID oxid, OXID_INFO *oxid_info)
Definition: rpc.c:2165
HRESULT rpc_register_interface(REFIID riid)
Definition: rpc.c:2086
void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid, BOOL tableweak)
Definition: stubmanager.c:614
ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak)
Definition: stubmanager.c:406
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
Definition: combase.c:2294
HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(REFCLSID rclsid, DWORD clscontext, COSERVERINFO *server_info, REFIID riid, void **obj)
Definition: combase.c:1925
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL delete_on_release, IStream **stream)
static HRESULT WINAPI Proxy_QueryInterface(IMarshal *iface, REFIID riid, void **ppvObject)
Definition: marshal.c:1109
HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, IUnknown *unk, IStream **stream)
Definition: marshal.c:154
static HRESULT WINAPI ftmarshaler_MarshalInterface(IMarshal *iface, IStream *stream, REFIID riid, void *pv, DWORD dest_context, void *pvDestContext, DWORD mshlflags)
Definition: marshal.c:302
static HRESULT proxy_manager_get_remunknown(struct proxy_manager *This, IRemUnknown **remunk)
Definition: marshal.c:1829
static HRESULT WINAPI ftmarshaler_DisconnectObject(IMarshal *iface, DWORD reserved)
Definition: marshal.c:393
HRESULT WINAPI CoCreateFreeThreadedMarshaler(IUnknown *outer, IUnknown **marshaler)
Definition: marshal.c:417
static HRESULT ifproxy_release_public_refs(struct ifproxy *This)
Definition: marshal.c:1463
static HRESULT proxy_manager_construct(struct apartment *apt, ULONG sorflags, OXID oxid, OID oid, const OXID_INFO *oxid_info, struct proxy_manager **proxy_manager)
Definition: marshal.c:1538
HRESULT WINAPI CoMarshalHresult(IStream *stream, HRESULT hresult)
Definition: marshal.c:123
HRESULT WINAPI CoGetInterfaceAndReleaseStream(IStream *stream, REFIID riid, void **obj)
Definition: marshal.c:139
static ULONG WINAPI ftmarshaler_AddRef(IMarshal *iface)
Definition: marshal.c:242
static HRESULT WINAPI ProxyCliSec_SetBlanket(IClientSecurity *iface, IUnknown *pProxy, DWORD AuthnSvc, DWORD AuthzSvc, OLECHAR *pServerPrincName, DWORD AuthnLevel, DWORD ImpLevel, void *pAuthInfo, DWORD Capabilities)
Definition: marshal.c:1394
static HRESULT WINAPI Proxy_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, void **ppv)
Definition: marshal.c:1276
static HRESULT WINAPI ftmarshaler_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv, DWORD dest_context, void *pvDestContext, DWORD mshlflags, DWORD *size)
Definition: marshal.c:279
static HRESULT proxy_manager_find_ifproxy(struct proxy_manager *This, REFIID riid, struct ifproxy **ifproxy_found)
Definition: marshal.c:1782
static HRESULT WINAPI ProxyCliSec_CopyProxy(IClientSecurity *iface, IUnknown *pProxy, IUnknown **ppCopy)
Definition: marshal.c:1408
static struct proxy_manager * impl_from_IMultiQI(IMultiQI *iface)
Definition: marshal.c:87
static HRESULT WINAPI StdMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *stream)
Definition: marshal.c:2191
static LONG proxy_manager_addref_if_alive(struct proxy_manager *This)
Definition: marshal.c:1898
static ULONG WINAPI StdMarshalImpl_AddRef(IMarshal *iface)
Definition: marshal.c:2032
HRESULT WINAPI CoMarshalInterface(IStream *stream, REFIID riid, IUnknown *unk, DWORD dest_context, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:483
static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal, IID *iid)
Definition: marshal.c:567
static HRESULT std_release_marshal_data(IStream *stream)
Definition: marshal.c:627
static HRESULT WINAPI ftmarshaler_ReleaseMarshalData(IMarshal *iface, IStream *stream)
Definition: marshal.c:371
static ULONG WINAPI ClientIdentity_Release(IMultiQI *iface)
Definition: marshal.c:988
static ULONG WINAPI ProxyCliSec_AddRef(IClientSecurity *iface)
Definition: marshal.c:1350
static ULONG WINAPI ftmarshaler_inner_Release(IUnknown *iface)
Definition: marshal.c:213
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, struct apartment *apt, MSHCTX dest_context, void *dest_context_data, REFIID riid, const OXID_INFO *oxid_info, void **object)
Definition: marshal.c:2098
static HRESULT WINAPI StdMarshalImpl_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *pCid)
Definition: marshal.c:2049
static void ifproxy_destroy(struct ifproxy *This)
Definition: marshal.c:1517
HRESULT apartment_disconnectproxies(struct apartment *apt)
Definition: marshal.c:1992
#define SORFP_TABLEWEAK
Definition: marshal.c:48
static const IUnknownVtbl ftmarshaler_inner_vtbl
Definition: marshal.c:226
static HRESULT WINAPI Proxy_MarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
Definition: marshal.c:1154
static ULONG WINAPI ftmarshaler_inner_AddRef(IUnknown *iface)
Definition: marshal.c:203
HRESULT WINAPI CoUnmarshalHresult(IStream *stream, HRESULT *phresult)
Definition: marshal.c:131
static void ifproxy_disconnect(struct ifproxy *This)
Definition: marshal.c:1507
static struct ftmarshaler * impl_ft_from_IUnknown(IUnknown *iface)
Definition: marshal.c:110
static HRESULT WINAPI ProxyCliSec_QueryInterface(IClientSecurity *iface, REFIID riid, void **ppvObject)
Definition: marshal.c:1344
static const IMultiQIVtbl ClientIdentity_Vtbl
Definition: marshal.c:1099
static HRESULT std_unmarshal_interface(MSHCTX dest_context, void *dest_context_data, IStream *stream, REFIID riid, void **ppv, BOOL dest_context_known)
Definition: marshal.c:700
static HRESULT WINAPI StdMarshalImpl_QueryInterface(IMarshal *iface, REFIID riid, void **ppv)
Definition: marshal.c:2019
static HRESULT WINAPI Proxy_ReleaseMarshalData(IMarshal *iface, IStream *pStm)
Definition: marshal.c:1295
static struct stdmarshal * impl_from_StdMarshal(IMarshal *iface)
Definition: marshal.c:2014
static HRESULT WINAPI ftmarshaler_inner_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
Definition: marshal.c:180
static HRESULT StdMarshalImpl_Construct(REFIID, DWORD, void *, void **)
Definition: marshal.c:2240
static struct ftmarshaler * impl_ft_from_IMarshal(IMarshal *iface)
Definition: marshal.c:115
static ULONG WINAPI ClientIdentity_AddRef(IMultiQI *iface)
Definition: marshal.c:981
static HRESULT ifproxy_get_public_ref(struct ifproxy *This)
Definition: marshal.c:1426
static HRESULT WINAPI StdMarshalImpl_MarshalInterface(IMarshal *iface, IStream *stream, REFIID riid, void *pv, DWORD dest_context, void *dest_context_data, DWORD mshlflags)
Definition: marshal.c:2063
static ULONG WINAPI Proxy_Release(IMarshal *iface)
Definition: marshal.c:1121
static const IMarshalVtbl ProxyMarshal_Vtbl
Definition: marshal.c:1331
static void proxy_manager_set_context(struct proxy_manager *This, MSHCTX dest_context, void *dest_context_data)
Definition: marshal.c:1619
#define SORFP_NOLIFETIMEMGMT
Definition: marshal.c:51
static const IMarshalVtbl ftmarshaler_vtbl
Definition: marshal.c:401
static void proxy_manager_destroy(struct proxy_manager *This)
Definition: marshal.c:1922
static HRESULT proxy_manager_create_ifproxy(struct proxy_manager *This, const STDOBJREF *stdobjref, REFIID riid, IRpcChannelBuffer *channel, struct ifproxy **iif_out)
Definition: marshal.c:1716
static HRESULT WINAPI Proxy_DisconnectObject(IMarshal *iface, DWORD dwReserved)
Definition: marshal.c:1313
static HRESULT WINAPI ftmarshaler_QueryInterface(IMarshal *iface, REFIID riid, void **obj)
Definition: marshal.c:233
HRESULT WINAPI CoGetStandardMarshal(REFIID riid, IUnknown *pUnk, DWORD dwDestContext, void *dest_context, DWORD flags, IMarshal **marshal)
Definition: marshal.c:2268
static ULONG WINAPI ftmarshaler_Release(IMarshal *iface)
Definition: marshal.c:251
static struct proxy_manager * impl_from_IClientSecurity(IClientSecurity *iface)
Definition: marshal.c:97
static ULONG WINAPI StdMarshalImpl_Release(IMarshal *iface)
Definition: marshal.c:2038
HRESULT WINAPI InternalCoStdMarshalObject(REFIID riid, DWORD dest_context, void *dest_context_data, void **ppvObject)
Definition: marshal.c:2260
static ULONG WINAPI Proxy_AddRef(IMarshal *iface)
Definition: marshal.c:1115
static struct proxy_manager * impl_from_IMarshal(IMarshal *iface)
Definition: marshal.c:92
HRESULT marshal_object(struct apartment *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *object, DWORD dest_context, void *dest_context_data, MSHLFLAGS mshlflags)
Definition: marshal.c:870
static HRESULT WINAPI StdMarshalImpl_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *pSize)
Definition: marshal.c:2056
HRESULT WINAPI RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, const OXID_INFO *oxid_info, const IID *iid, DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan, struct apartment *apt)
static const IClientSecurityVtbl ProxyCliSec_Vtbl
Definition: marshal.c:1416
static BOOL find_proxy_manager(struct apartment *apt, OXID oxid, OID oid, struct proxy_manager **proxy_found)
Definition: marshal.c:1967
static void dump_mshflags(MSHLFLAGS flags)
Definition: marshal.c:468
static HRESULT WINAPI ClientIdentity_QueryInterface(IMultiQI *iface, REFIID riid, void **ppv)
Definition: marshal.c:967
static HRESULT WINAPI Proxy_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *pCid)
Definition: marshal.c:1127
HRESULT WINAPI CoReleaseMarshalData(IStream *stream)
Definition: marshal.c:673
static HRESULT WINAPI StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *stream, REFIID riid, void **ppv)
Definition: marshal.c:2162
static HRESULT proxy_manager_query_local_interface(struct proxy_manager *This, REFIID riid, void **ppv)
Definition: marshal.c:1677
#define NORMALEXTREFS
Definition: marshal.c:45
static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, ULONG cMQIs, MULTI_QI *pMQIs)
Definition: marshal.c:998
static HRESULT WINAPI ftmarshaler_UnmarshalInterface(IMarshal *iface, IStream *stream, REFIID riid, void **ppv)
Definition: marshal.c:346
static ULONG WINAPI ProxyCliSec_Release(IClientSecurity *iface)
Definition: marshal.c:1356
static void proxy_manager_disconnect(struct proxy_manager *This)
Definition: marshal.c:1802
static HRESULT WINAPI ProxyCliSec_QueryBlanket(IClientSecurity *iface, IUnknown *pProxy, DWORD *pAuthnSvc, DWORD *pAuthzSvc, OLECHAR **ppServerPrincName, DWORD *pAuthnLevel, DWORD *pImpLevel, void **pAuthInfo, DWORD *pCapabilities)
Definition: marshal.c:1362
static const IMarshalVtbl StdMarshalVtbl
Definition: marshal.c:2227
static HRESULT WINAPI Proxy_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *pSize)
Definition: marshal.c:1135
static void fill_std_objref(OBJREF *objref, const GUID *iid, STDOBJREF *std)
Definition: marshal.c:1143
HRESULT WINAPI CoUnmarshalInterface(IStream *stream, REFIID riid, void **ppv)
Definition: marshal.c:793
HRESULT WINAPI CoGetMarshalSizeMax(ULONG *size, REFIID riid, IUnknown *unk, DWORD dest_context, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:440
static HRESULT WINAPI ftmarshaler_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv, DWORD dest_context, void *pvDestContext, DWORD mshlflags, CLSID *clsid)
Definition: marshal.c:260
static HRESULT WINAPI StdMarshalImpl_DisconnectObject(IMarshal *iface, DWORD reserved)
Definition: marshal.c:2221
static HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
Definition: marshal.c:858
#define CloseHandle
Definition: compat.h:739
WCHAR OLECHAR
Definition: compat.h:2292
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
Definition: sync.c:107
#define assert(_expr)
Definition: assert.h:32
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
r reserved
Definition: btrfs.c:3006
#define INFINITE
Definition: serial.h:102
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
int proxy
Definition: main.c:67
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint res
Definition: glext.h:9613
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
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
_Must_inspect_result_ typedef _Out_ PHIDP_CAPS Capabilities
Definition: hidclass.h:103
const char cursor[]
Definition: icontest.c:13
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define InterlockedExchangeAdd
Definition: interlocked.h:196
#define InterlockedCompareExchange
Definition: interlocked.h:119
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
__forceinline long ReadNoFence(_In_ _Interlocked_operand_ long const volatile *Source)
Definition: memaccess.h:175
#define seekto(pos, errstr)
Definition: mkdosfs.c:1613
HRESULT hres
Definition: protocol.c:465
static IUnknown * outer
Definition: compobj.c:82
#define OBJREF_CUSTOM
Definition: marshal.c:78
struct tagOBJREF OBJREF
UINT64 OID
Definition: marshal.c:87
#define OBJREF_SIGNATURE
Definition: marshal.c:76
static const IID IID_IRemUnknown
Definition: marshal.c:129
UINT64 OXID
Definition: marshal.c:86
#define OBJREF_STANDARD
Definition: marshal.c:77
const CLSID * clsid
Definition: msctf.cpp:50
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:95
Definition: features.h:417
interface IMarshal * LPMARSHAL
Definition: objfwd.h:11
long LONG
Definition: pedump.c:60
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define IID_NULL
Definition: guiddef.h:98
#define IsEqualCLSID(rclsid1, rclsid2)
Definition: guiddef.h:96
#define RPC_C_AUTHN_LEVEL_DEFAULT
Definition: rpcdce.h:145
#define RPC_C_IMP_LEVEL_DEFAULT
Definition: rpcdce.h:173
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:206
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define LIST_FOR_EACH(cursor, list)
Definition: list.h:188
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
Definition: stubgen.c:11
struct list proxies
CRITICAL_SECTION cs
IMarshal IMarshal_iface
Definition: marshal.c:105
LONG refcount
Definition: marshal.c:107
IUnknown * outer_unk
Definition: marshal.c:106
IUnknown IUnknown_inner
Definition: marshal.c:104
IID iid
Definition: marshal.c:60
IRpcChannelBuffer * chan
Definition: marshal.c:63
struct proxy_manager * parent
Definition: marshal.c:57
void * iface
Definition: marshal.c:58
ULONG refs
Definition: marshal.c:62
STDOBJREF stdobjref
Definition: marshal.c:59
struct list entry
Definition: marshal.c:56
IRpcProxyBuffer * proxy
Definition: marshal.c:61
IUnknown * iface
Definition: list.h:15
IClientSecurity IClientSecurity_iface
Definition: marshal.c:71
void * dest_context_data
Definition: marshal.c:84
LONG refs
Definition: marshal.c:78
CRITICAL_SECTION cs
Definition: marshal.c:79
OXID_INFO oxid_info
Definition: marshal.c:75
IMultiQI IMultiQI_iface
Definition: marshal.c:69
MSHCTX dest_context
Definition: marshal.c:83
IMarshal IMarshal_iface
Definition: marshal.c:70
OXID oxid
Definition: marshal.c:74
struct apartment * parent
Definition: marshal.c:72
struct list entry
Definition: marshal.c:73
ULONG sorflags
Definition: marshal.c:80
HANDLE remoting_mutex
Definition: marshal.c:82
IRemUnknown * remunk
Definition: marshal.c:81
struct list interfaces
Definition: marshal.c:77
DWORD dest_context
Definition: marshal.c:2010
LONG refcount
Definition: marshal.c:2009
IMarshal IMarshal_iface
Definition: marshal.c:2008
void * dest_context_data
Definition: marshal.c:2011
Definition: parse.h:23
OXID_INFO oxid_info
IUnknown * object
struct tagOBJREF::@1807::OR_CUSTOM u_custom
STDOBJREF std
Definition: marshal.c:104
ULONG flags
Definition: marshal.c:100
GUID iid
Definition: marshal.c:101
ULONG signature
Definition: marshal.c:99
union tagOBJREF::@1807 u_objref
struct tagOBJREF::@1807::OR_STANDARD u_standard
OXID oxid
Definition: marshal.c:93
ULONG flags
Definition: marshal.c:91
IPID ipid
Definition: marshal.c:95
ULONG cPublicRefs
Definition: marshal.c:92
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:525
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:554
#define LIST_ENTRY(type)
Definition: queue.h:175
#define DWORD_PTR
Definition: treelist.c:76
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int32_t * PLONG
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
UINT64 value
Definition: marshal.c:275
IUnknown * object
Definition: marshal.c:276
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define WAIT_OBJECT_0
Definition: winbase.h:383
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define E_NOINTERFACE
Definition: winerror.h:3479
#define STG_E_READFAULT
Definition: winerror.h:3671
#define CO_E_OBJNOTCONNECTED
Definition: winerror.h:3929
#define E_UNEXPECTED
Definition: winerror.h:3528
#define RPC_E_INVALID_OBJREF
Definition: winerror.h:3577
#define STG_E_MEDIUMFULL
Definition: winerror.h:3676
#define E_POINTER
Definition: winerror.h:3480
#define RPC_E_DISCONNECTED
Definition: winerror.h:3556
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1152