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