Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / mscorlib / system / runtime / remoting / remotingservices.cs
blob679d4eff45a140b891d573d2bc1bff64f59433d2
1 // ==++==
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // ==--==
6 //
7 // File: RemotingServices.cs
8 //
9 // <OWNER>Microsoft</OWNER>
10 //
11 // Author(s): <EMAIL>Gopal Kakivaya (GopalK)</EMAIL>
12 //
13 // Purpose: Defines various remoting related services such as
14 // marshal, unmarshal, connect, wrap, unwrap etc.
15 //
16 //
17 namespace System.Runtime.Remoting {
18 using System;
19 using System.Text;
20 using System.Collections;
21 using System.Runtime.Serialization;
22 using System.IO;
23 using System.Reflection;
24 using System.Runtime.CompilerServices;
25 using CultureInfo = System.Globalization.CultureInfo;
26 using System.Runtime.InteropServices;
27 using System.Threading;
28 using System.Runtime.Remoting.Activation;
29 using System.Runtime.Remoting.Contexts;
30 using System.Runtime.Remoting.Lifetime;
31 using System.Runtime.Remoting.Messaging;
32 using System.Runtime.Remoting.Metadata;
33 using System.Runtime.Remoting.Proxies;
34 using System.Runtime.Remoting.Channels;
35 using System.Runtime.Remoting.Services;
36 using RemotingConfigInfo = System.Runtime.Remoting.RemotingConfigHandler.RemotingConfigInfo;
37 using System.Runtime.Serialization.Formatters.Binary;
38 using System.Security.Permissions;
39 using System.Runtime.ConstrainedExecution;
40 using System.Runtime.Versioning;
41 using System.Diagnostics.Contracts;
44 // Implements various remoting services
45 [System.Runtime.InteropServices.ComVisible(true)]
46 public static class RemotingServices
49 private const BindingFlags LookupAll = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
50 private const String FieldGetterName = "FieldGetter";
51 private const String FieldSetterName = "FieldSetter";
52 private const String IsInstanceOfTypeName = "IsInstanceOfType";
53 private const String CanCastToXmlTypeName = "CanCastToXmlType";
54 private const String InvokeMemberName = "InvokeMember";
56 private static volatile MethodBase s_FieldGetterMB;
57 private static volatile MethodBase s_FieldSetterMB;
58 private static volatile MethodBase s_IsInstanceOfTypeMB;
59 private static volatile MethodBase s_CanCastToXmlTypeMB;
60 private static volatile MethodBase s_InvokeMemberMB;
62 private static volatile bool s_bRemoteActivationConfigured;
64 // have we registered the well known channels
65 private static volatile bool s_bRegisteredWellKnownChannels;
66 // are we in the middle of registering well known channels
67 private static bool s_bInProcessOfRegisteringWellKnownChannels;
68 private static readonly Object s_delayLoadChannelLock = new Object();
71 //Native Static Methods
73 [System.Security.SecuritySafeCritical] // auto-generated
74 [Pure]
75 [ResourceExposure(ResourceScope.None)]
76 [MethodImplAttribute(MethodImplOptions.InternalCall),
77 ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
78 public static extern bool IsTransparentProxy(Object proxy);
81 // Check whether the given object's context is the same as
82 // the current context.
83 //
86 [System.Security.SecuritySafeCritical] // auto-generated
87 public static bool IsObjectOutOfContext(Object tp)
89 if (!IsTransparentProxy(tp))
91 return false;
94 RealProxy rp = GetRealProxy(tp);
95 Identity id = rp.IdentityObject;
96 ServerIdentity serverID = id as ServerIdentity;
97 if ((null == serverID) || !(rp is RemotingProxy))
99 return true;
102 return(Thread.CurrentContext != serverID.ServerContext);
106 // Check whether the given object's app domain is the same as
107 // the current app domain
111 public static bool IsObjectOutOfAppDomain(Object tp)
113 return IsClientProxy(tp);
114 } // IsObjectOutOfAppDomain
117 internal static bool IsClientProxy(Object obj)
119 MarshalByRefObject mbr = obj as MarshalByRefObject;
120 if (mbr == null)
121 return false;
123 bool bIsClientProxy = false;
125 bool fServer;
126 Identity id = MarshalByRefObject.GetIdentity(mbr, out fServer);
127 // If the identity is null, this is defintely a locally hosted object;
128 // otherwise...(see if statement below).
129 if (id != null)
131 if (!(id is ServerIdentity))
132 bIsClientProxy = true;
135 return bIsClientProxy;
136 } // IsClientProxy
139 // Check whether the given object's process is the same as
140 // the current process
144 [System.Security.SecurityCritical] // auto-generated
145 internal static bool IsObjectOutOfProcess(Object tp)
147 if (!IsTransparentProxy(tp))
148 return false;
150 RealProxy rp = GetRealProxy(tp);
151 Identity id = rp.IdentityObject;
152 if (id is ServerIdentity)
153 return false;
154 else
156 if (null != id)
158 ObjRef objRef = id.ObjectRef;
159 if (objRef != null && objRef.IsFromThisProcess())
161 return false;
163 else
165 return true;
168 // assume out of process
169 return true;
172 } // IsObjectOutOfProcess
174 // Get the real proxy backing the transparent proxy
178 [System.Security.SecurityCritical] // auto-generated_required
179 [ResourceExposure(ResourceScope.None)]
180 [MethodImplAttribute(MethodImplOptions.InternalCall)]
181 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
182 public static extern RealProxy GetRealProxy(Object proxy);
185 // Create a transparent proxy given an instance of a real proxy and type
189 [System.Security.SecurityCritical] // auto-generated
190 [ResourceExposure(ResourceScope.None)]
191 [MethodImplAttribute(MethodImplOptions.InternalCall)]
192 internal static extern Object CreateTransparentProxy(
193 RealProxy rp,
194 RuntimeType typeToProxy,
195 IntPtr stub,
196 Object stubData);
198 // Note: for each of these calls that take a RuntimeXXX reflection
199 // structure, there is a wrapper that takes XXX and throws if it is
200 // not a RuntimeXXX. This is to avoid clutter in code where these
201 // methods are called. <BUGNUM>(48721)</BUGNUM> <
204 [System.Security.SecurityCritical] // auto-generated
205 internal static Object CreateTransparentProxy(
206 RealProxy rp,
207 Type typeToProxy,
208 IntPtr stub,
209 Object stubData)
211 RuntimeType rTypeToProxy = typeToProxy as RuntimeType;
212 if (rTypeToProxy == null)
213 throw new ArgumentException(
214 String.Format(
215 CultureInfo.CurrentCulture, Environment.GetResourceString(
216 "Argument_WrongType"),
217 "typeToProxy"
221 return CreateTransparentProxy(
223 rTypeToProxy,
224 stub,
225 stubData);
230 // Allocate an uninitialized object of the given type.
234 [System.Security.SecurityCritical] // auto-generated
235 [ResourceExposure(ResourceScope.None)]
236 [MethodImplAttribute(MethodImplOptions.InternalCall)]
237 internal static extern MarshalByRefObject AllocateUninitializedObject(
238 RuntimeType objectType);
240 [System.Security.SecurityCritical] // auto-generated
241 [ResourceExposure(ResourceScope.None)]
242 [MethodImplAttribute(MethodImplOptions.InternalCall)]
243 internal static extern void CallDefaultCtor(Object o);
246 [System.Security.SecurityCritical] // auto-generated
247 internal static MarshalByRefObject AllocateUninitializedObject(
248 Type objectType)
250 RuntimeType rObjectType = objectType as RuntimeType;
251 if (rObjectType == null)
252 throw new ArgumentException(
253 String.Format(
254 CultureInfo.CurrentCulture, Environment.GetResourceString(
255 "Argument_WrongType"),
256 "objectType"
259 return AllocateUninitializedObject(
260 rObjectType);
263 // Allocate an Initialized object of the given type.
264 // runs the default constructor
267 [System.Security.SecurityCritical] // auto-generated
268 [ResourceExposure(ResourceScope.None)]
269 [MethodImplAttribute(MethodImplOptions.InternalCall)]
270 internal static extern MarshalByRefObject AllocateInitializedObject(
271 RuntimeType objectType);
274 [System.Security.SecurityCritical] // auto-generated
275 internal static MarshalByRefObject AllocateInitializedObject(
276 Type objectType)
278 RuntimeType rObjectType = objectType as RuntimeType;
279 if (rObjectType == null)
280 throw new ArgumentException(
281 String.Format(
282 CultureInfo.CurrentCulture, Environment.GetResourceString(
283 "Argument_WrongType"),
284 "objectType"
287 return AllocateInitializedObject(
288 rObjectType);
292 [System.Security.SecurityCritical] // auto-generated
293 internal static bool RegisterWellKnownChannels()
295 // Any code coming through this method MUST not exit
296 // until the well known channels have been registered
297 // (unless we are reentering in the call to
298 // RefreshChannelData() while registering a well known
299 // channel).
300 if (!s_bRegisteredWellKnownChannels)
302 bool fLocked = false;
303 Object configLock = Thread.GetDomain().RemotingData.ConfigLock;
304 RuntimeHelpers.PrepareConstrainedRegions();
307 Monitor.Enter(configLock, ref fLocked);
308 if (!s_bRegisteredWellKnownChannels &&
309 !s_bInProcessOfRegisteringWellKnownChannels)
312 // we set this flag true before registering channels to prevent reentrancy
313 // when we go to refresh the channel data at the end of the call to
314 // ChannelServices.RegisterChannel().
315 s_bInProcessOfRegisteringWellKnownChannels = true;
316 CrossAppDomainChannel.RegisterChannel();
317 s_bRegisteredWellKnownChannels = true;
320 finally
322 if (fLocked)
324 Monitor.Exit(configLock);
328 return true;
329 } // RegisterWellKnownChannels
332 [System.Security.SecurityCritical] // auto-generated
333 internal static void InternalSetRemoteActivationConfigured()
335 if (!s_bRemoteActivationConfigured)
337 nSetRemoteActivationConfigured();
338 s_bRemoteActivationConfigured = true;
340 } // InternalSetRemoteActivationConfigured
343 [System.Security.SecurityCritical] // auto-generated
344 [ResourceExposure(ResourceScope.None)]
345 [MethodImplAttribute(MethodImplOptions.InternalCall)]
346 private static extern void nSetRemoteActivationConfigured();
349 [System.Security.SecurityCritical] // auto-generated_required
350 public static String GetSessionIdForMethodMessage(IMethodMessage msg)
352 return msg.Uri;
353 } // GetSessionIdForMessage
355 [System.Security.SecuritySafeCritical] // auto-generated
356 public static Object GetLifetimeService(MarshalByRefObject obj)
358 if(null != obj)
360 return obj.GetLifetimeService();
362 else
364 return null;
368 [System.Security.SecurityCritical] // auto-generated_required
369 public static String GetObjectUri(MarshalByRefObject obj)
371 // Retrieve the uri for the object. If it doesn't have an identity
372 // we'll just return null (this encompasses the case of an actual
373 // object not having been marshalled yet.
375 bool fServer;
376 Identity id = MarshalByRefObject.GetIdentity(obj, out fServer);
378 if(null != id)
379 return id.URI;
380 else
381 return null;
382 } // GetObjectUri
385 [System.Security.SecuritySafeCritical] // auto-generated
386 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)]
387 public static void SetObjectUriForMarshal( MarshalByRefObject obj, String uri)
389 // if obj is ever Marshal'd it should use this uri. If a uri has
390 // already been assigned to the object, it should throw.
392 Message.DebugOut("Entered SetObjectUriForMarshal \n");
394 Identity idObj = null;
395 Identity srvIdObj = null;
397 bool fServer;
398 idObj = MarshalByRefObject.GetIdentity(obj, out fServer);
399 srvIdObj = idObj as ServerIdentity;
401 // Ensure that if we have a transparent proxy then we are not given a remoting
402 // proxy. This routine should only be called for objects that
403 // live in this AppDomains.
404 if ((idObj != null) &&
405 (srvIdObj == null)) // <-- means idObj is not a ServerIdentity
407 throw new RemotingException(
408 Environment.GetResourceString(
409 "Remoting_SetObjectUriForMarshal__ObjectNeedsToBeLocal"));
413 if ((idObj != null) && (idObj.URI != null))
415 throw new RemotingException(
416 Environment.GetResourceString(
417 "Remoting_SetObjectUriForMarshal__UriExists"));
421 if (idObj == null)
423 // obj is not ContextBound
424 Contract.Assert(!(obj is ContextBoundObject), "ContextBoundObject's shouldn't get here.");
426 // Create a new server identity and add it to the
427 // table. IdentityHolder will take care of ----s
428 Context serverCtx = null;
430 serverCtx = Thread.GetDomain().GetDefaultContext();
432 Contract.Assert(null != serverCtx, "null != serverCtx");
434 ServerIdentity serverID = new ServerIdentity(obj, serverCtx, uri);
436 // set the identity
437 idObj = obj.__RaceSetServerIdentity(serverID);
438 Contract.Assert(idObj == MarshalByRefObject.GetIdentity(obj), "Bad ID state!" );
440 // If our serverID isn't used then someone else marshalled the object
441 // before we could set the uri.
442 if (idObj != serverID)
444 throw new RemotingException(
445 Environment.GetResourceString(
446 "Remoting_SetObjectUriForMarshal__UriExists"));
449 else
451 // This is the ContextBoundObject case
452 Contract.Assert(obj is ContextBoundObject, "Object should have been a ContextBoundObject.");
454 idObj.SetOrCreateURI(uri, true);
457 Message.DebugOut("Created ServerIdentity \n");
458 } // SetObjectUriForMarshal
461 [System.Security.SecuritySafeCritical] // auto-generated
462 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)]
463 public static ObjRef Marshal(MarshalByRefObject Obj)
465 return MarshalInternal(Obj, null, null);
468 [System.Security.SecuritySafeCritical] // auto-generated
469 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)]
470 public static ObjRef Marshal(MarshalByRefObject Obj, String URI)
472 return MarshalInternal(Obj, URI, null);
475 [System.Security.SecuritySafeCritical] // auto-generated
476 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)]
477 public static ObjRef Marshal(MarshalByRefObject Obj, String ObjURI, Type RequestedType)
479 return MarshalInternal(Obj, ObjURI, RequestedType);
482 // Internal flavor without security!
483 [System.Security.SecurityCritical] // auto-generated
484 internal static ObjRef MarshalInternal(MarshalByRefObject Obj, String ObjURI, Type RequestedType)
486 return MarshalInternal(Obj, ObjURI, RequestedType, true);
488 // Internal flavor without security!
489 [System.Security.SecurityCritical] // auto-generated
490 internal static ObjRef MarshalInternal(MarshalByRefObject Obj, String ObjURI, Type RequestedType, bool updateChannelData)
492 return MarshalInternal(Obj, ObjURI, RequestedType, updateChannelData, isInitializing: false);
495 // Internal flavor without security!
496 [System.Security.SecurityCritical] // auto-generated
497 internal static ObjRef MarshalInternal(MarshalByRefObject Obj, String ObjURI, Type RequestedType, bool updateChannelData, bool isInitializing)
499 BCLDebug.Trace("REMOTE", "Entered Marshal for URI" + ObjURI + "\n");
501 if (null == Obj)
502 return null;
504 ObjRef objectRef = null;
505 Identity idObj = null;
507 idObj = GetOrCreateIdentity(Obj, ObjURI, isInitializing);
508 if (RequestedType != null)
510 ServerIdentity srvIdObj = idObj as ServerIdentity;
511 if (srvIdObj != null)
513 // If more than one thread, marshals with different types the
514 // results would be non-deterministic, so we just let the last
515 // call win (also allows type to be marshalled a second time
516 // to change the exposed type).
517 srvIdObj.ServerType = RequestedType;
518 srvIdObj.MarshaledAsSpecificType = true;
522 // If there is no objref associated with the identity then go ahead
523 // and create one and stick it back into the identity object
525 #if _DEBUG
526 idObj.AssertValid();
527 #endif
529 Contract.Assert(null != idObj.ObjURI,"null != idObj.ObjURI");
531 Message.DebugOut("RemotingServices::Marshal: trying to create objref\n");
533 // We should definitely have an identity object at this point of time
534 Contract.Assert(null != idObj,"null != idObj");
536 // Extract the objref from the identity
537 objectRef = idObj.ObjectRef;
538 if (null == objectRef)
540 Message.DebugOut("RemotingServices::Marshal: really trying to create objref\n");
542 if (IsTransparentProxy(Obj))
544 RealProxy realProxy = GetRealProxy(Obj);
545 Contract.Assert(null != realProxy,"null != realProxy");
546 objectRef = realProxy.CreateObjRef(RequestedType);
548 else
550 // Create a new object ref which contains the default information
551 objectRef = Obj.CreateObjRef(RequestedType);
554 Message.DebugOut("RemotingServices::Marshal: created objref\n");
555 if (idObj == null || objectRef == null)
556 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidMarshalByRefObject"), "Obj");
558 // The ObjectRef property setter will take care of ----s
559 objectRef = idObj.RaceSetObjRef(objectRef);
563 // Retime lease on every marshal on the server side
564 // and extend lease on every marshal on the client side <EMAIL>- GopalK</EMAIL>
565 ServerIdentity srvId = idObj as ServerIdentity;
566 if (srvId != null)
568 // Ensure that the lease is started soon as the object is
569 // marshaled.
570 MarshalByRefObject obj = null;
571 // This call forces creation of the lifetime lease sink.
572 srvId.GetServerObjectChain(out obj);
574 // Server side ... object being marshaled => give it another
575 // full lease
576 Lease lease = idObj.Lease;
577 if (lease != null)
579 // We always make Identity reference our own Lease though
580 // the actual object implements its own ILease object.
581 // This seems completely broken. Further, ILease interface
582 // should have the activate method. <EMAIL>- GopalK</EMAIL>
584 // This lock ensures coordination with the lifetime service
585 // which might have decided to Disconnect the object about
586 // the same time as it is being marshaled
587 lock (lease)
589 if (lease.CurrentState == LeaseState.Expired)
591 // Lease.Renew is a no-op if LeaseState==Expired
592 // So we do a full ActivateLease
593 lease.ActivateLease();
595 else
597 // Lease is still around. Just increase the time
598 lease.RenewInternal(idObj.Lease.InitialLeaseTime);
603 // Every marshal should also ensure that the channel data
604 // being carried in the objRef reflects the latest data from
605 // regisetered channels
606 // <
607 if (updateChannelData && objectRef.ChannelInfo != null)
609 // Create the channel info
610 Object[] channelData = ChannelServices.CurrentChannelData;
611 // Make sure the channelInfo only has x-appdomain data since the objref is agile while other
612 // channelData might not be and regardless this data is useless for an appdomain proxy
613 if (!(Obj is AppDomain))
614 objectRef.ChannelInfo.ChannelData = channelData;
615 else
617 int channelDataLength = channelData.Length;
618 Object[] newChannelData = new Object[channelDataLength];
619 // Clone the data so that we dont Microsoft the current appdomain data which is stored
620 // as a static
621 Array.Copy(channelData, newChannelData, channelDataLength);
622 for (int i = 0; i < channelDataLength; i++)
624 if (!(newChannelData[i] is CrossAppDomainData))
625 newChannelData[i] = null;
627 objectRef.ChannelInfo.ChannelData = newChannelData;
631 else
633 #if false
639 ILease lease = idObj.Lease;
640 if (lease == null)
642 lease = (ILease)Obj.GetLifetimeService();
644 if (lease != null)
646 lease.Renew(lease.RenewOnCallTime);
648 #endif
651 // Notify TrackingServices that an object has been marshaled
652 // NOTE: This call also keeps the object alive otherwise GC
653 // can report it as dead anytime inside this call when it thinks
654 // that the object will no longer be referenced, either inside
655 // this call or outside.
656 /* <
659 TrackingServices.MarshaledObject(Obj, objectRef);
660 return objectRef;
663 // Gets or generates the identity if one is not present and then returns
664 // it to the caller.
665 [System.Security.SecurityCritical] // auto-generated
666 private static Identity GetOrCreateIdentity(
667 MarshalByRefObject Obj,
668 String ObjURI,
669 bool isInitializing)
671 int idOpsFlags = IdOps.StrongIdentity;
673 // DevDiv 720951 and 911924:
674 // This flag is propagated into the new ServerIdentity to indicate
675 // it is not yet ready for use. CreateWellKnownObject is the only
676 // code path that sets it to 'true'.
677 if (isInitializing)
679 idOpsFlags |= IdOps.IsInitializing;
682 Identity idObj = null;
683 if (IsTransparentProxy(Obj))
685 Message.DebugOut("Marshaling proxy \n");
687 RealProxy realProxy = GetRealProxy(Obj);
688 Contract.Assert(null != realProxy,"null != realProxy");
690 idObj = realProxy.IdentityObject;
691 if(null == idObj)
693 // passing the strongIdentity flag will ensure that a weak
694 // reference to the identity will get converted to a strong
695 // one so as to keep the object alive (and in control of
696 // lifeTimeServices)
698 idObj = IdentityHolder.FindOrCreateServerIdentity(
699 Obj,
700 ObjURI,
701 idOpsFlags);
703 idObj.RaceSetTransparentProxy(Obj);
706 // At this point of time we should have an identity
707 Contract.Assert(null != idObj, "null != idObj");
710 ServerIdentity srvID = idObj as ServerIdentity;
711 if (srvID != null)
713 // We are marshaling a proxy with a serverIdentity
714 // associated with it but with no URI generated yet.
715 // For a genuine proxy case we will always have a URI
716 // AND it will be a client ID!
717 // So if we are here this must be a SrvID
718 // for a ContextBoundObject
719 Contract.Assert(srvID != null && Obj is ContextBoundObject,
720 "This case should only be hit for ContextBoundObjects & ServerIdentity!");
721 Message.DebugOut("Marshal::Looking up server side identity \n");
722 #if _DEBUG
723 srvID.AssertValid();
724 #endif
726 // passing the strongIdentity flag will ensure that a weak
727 // reference to the identity will get converted to a strong
728 // one so as to keep the object alive (and in control of
729 // lifeTimeServices)
731 idObj = IdentityHolder.FindOrCreateServerIdentity(
732 srvID.TPOrObject,
733 ObjURI,
734 idOpsFlags);
736 // if an objURI was specified we need to make sure that
737 // the same one was used.
738 if ((null != ObjURI) &&
739 (ObjURI != Identity.RemoveAppNameOrAppGuidIfNecessary(
740 idObj.ObjURI)))
742 throw new RemotingException(
743 Environment.GetResourceString(
744 "Remoting_URIExists"));
747 // We create a unique ID for an object and never
748 // change it!
749 Contract.Assert(srvID == idObj, "Bad ID Table state!");
751 else
753 // We are marshaling a proxy with a (client)Identity associated with it
754 // It must already have a URI.
755 Message.DebugOut("Marshal::Client side identity \n");
756 Contract.Assert(idObj.ObjURI != null, "Client side id without URI!");
759 // One cannot associate a URI with a proxy generated by us
760 // because either a URI was generated at the server side for the object
761 // it represents or it is a well known object in which case the URI is known.
763 // For custom proxies this restriction is relaxed because we treat the
764 // transparent proxy as the server object for such cases.
766 if ((null != ObjURI) && (ObjURI != idObj.ObjURI))
768 throw new RemotingException(
769 Environment.GetResourceString(
770 "Remoting_URIToProxy"));
774 Contract.Assert(null != idObj.ObjURI,"null != idObj.ObjURI");
776 else
778 // Find or Add the object identity to the identity table
779 Message.DebugOut("Marshaling object \n");
781 // passing the strongIdentity flag will ensure that a weak
782 // reference to the identity will get converted to a strong
783 // one so as to keep the object alive (and in control of
784 // lifeTimeServices)
786 // The object may have an ID if it was marshaled but its lease
787 // timed out.
788 #if _DEBUG
789 ServerIdentity idTmp =
790 (ServerIdentity) MarshalByRefObject.GetIdentity(Obj);
791 #endif
795 idObj = IdentityHolder.FindOrCreateServerIdentity(
796 Obj,
797 ObjURI,
798 idOpsFlags);
800 // If the object had an ID to begin with that is the one
801 // we must have set in the table.
802 #if _DEBUG
803 Contract.Assert(idTmp==null || idTmp == idObj, "Bad ID Table state!");
804 #endif
807 return idObj;
810 [System.Security.SecurityCritical] // auto-generated_required
811 public static void GetObjectData(Object obj, SerializationInfo info, StreamingContext context)
813 if (obj == null)
815 throw new ArgumentNullException("obj");
818 if (info==null) {
819 throw new ArgumentNullException("info");
821 Contract.EndContractBlock();
823 ObjRef or = RemotingServices.MarshalInternal(
824 (MarshalByRefObject)obj,
825 null,
826 null);
828 or.GetObjectData(info, context);
829 } // GetObjectData
831 [System.Security.SecurityCritical] // auto-generated_required
832 public static Object Unmarshal(ObjRef objectRef)
834 return InternalUnmarshal(objectRef, null, false);
837 [System.Security.SecurityCritical] // auto-generated_required
838 public static Object Unmarshal(ObjRef objectRef, bool fRefine)
840 return InternalUnmarshal(objectRef, null, fRefine);
844 [System.Security.SecurityCritical] // auto-generated_required
845 [System.Runtime.InteropServices.ComVisible(true)]
846 public static Object Connect(Type classToProxy, String url)
848 return Unmarshal(classToProxy, url, null);
851 [System.Security.SecurityCritical] // auto-generated_required
852 [System.Runtime.InteropServices.ComVisible(true)]
853 public static Object Connect(Type classToProxy, String url, Object data)
855 return Unmarshal(classToProxy, url, data);
859 [System.Security.SecurityCritical] // auto-generated_required
860 public static bool Disconnect(MarshalByRefObject obj)
862 return Disconnect(obj, true);
865 [System.Security.SecurityCritical] // auto-generated
866 internal static bool Disconnect(MarshalByRefObject obj, bool bResetURI)
868 if (obj == null)
870 throw new ArgumentNullException("obj");
872 Contract.EndContractBlock();
874 BCLDebug.Trace("REMOTE", "RemotingServices.Disconnect ", obj, " for context ", Thread.CurrentContext);
876 // We can extract the identity either from the remoting proxy or
877 // the server object depending on whether we are in the
878 // context/appdomain that the object was created in or outside
879 // the context/appdomain.
880 bool fServer;
881 Identity idrem = MarshalByRefObject.GetIdentity(obj, out fServer);
883 // remove the identity entry for this object (if it exists)
884 bool fDisconnect = false;
885 if(idrem != null)
887 // Disconnect is supported only on the server side currently
888 if(idrem is ServerIdentity)
890 // Disconnect is a no op if the object was never marshaled
891 if(idrem.IsInIDTable())
893 // When a user calls Disconnect we reset the URI but
894 // when lifetime service calls Disconnect we don't
895 IdentityHolder.RemoveIdentity(idrem.URI, bResetURI);
896 fDisconnect = true;
899 else
901 // <
903 throw new RemotingException(
904 Environment.GetResourceString("Remoting_CantDisconnectClientProxy"));
907 // Notify TrackingServices that an object has been disconnected
908 TrackingServices.DisconnectedObject(obj);
911 Message.DebugOut("Disconnect:: returning " + fDisconnect +
912 " for context " + Thread.CurrentContext +
913 "\n");
915 return fDisconnect;
918 [System.Security.SecurityCritical] // auto-generated_required
919 public static IMessageSink GetEnvoyChainForProxy(MarshalByRefObject obj)
921 IMessageSink envoyChain = null;
923 // Extract the envoy chain only if the object is a proxy
924 if(IsObjectOutOfContext(obj))
926 RealProxy rp = GetRealProxy(obj);
927 Identity id = rp.IdentityObject;
928 if(null != id)
930 envoyChain = id.EnvoyChain;
934 return envoyChain;
937 [System.Security.SecurityCritical] // auto-generated_required
938 public static ObjRef GetObjRefForProxy(MarshalByRefObject obj)
940 ObjRef objRef = null;
941 if (!IsTransparentProxy(obj))
943 throw new RemotingException(
944 Environment.GetResourceString(
945 "Remoting_Proxy_BadType"));
947 RealProxy rp = GetRealProxy(obj);
948 Identity id = rp.IdentityObject;
949 if (null != id)
951 objRef = id.ObjectRef;
953 return objRef;
956 [System.Security.SecurityCritical] // auto-generated
957 internal static Object Unmarshal(Type classToProxy, String url)
959 return Unmarshal(classToProxy, url, null);
963 [System.Security.SecurityCritical] // auto-generated
964 internal static Object Unmarshal(Type classToProxy, String url, Object data)
966 if (null == classToProxy)
968 throw new ArgumentNullException("classToProxy");
971 if (null == url)
973 throw new ArgumentNullException("url");
975 Contract.EndContractBlock();
977 if (!classToProxy.IsMarshalByRef && !classToProxy.IsInterface)
979 throw new RemotingException(
980 Environment.GetResourceString(
981 "Remoting_NotRemotableByReference"));
984 BCLDebug.Trace("REMOTE", "RemotingService::Unmarshal for URL" + url + "and for Type" + classToProxy);
986 // See if we have already unmarshaled this (wellKnown) url
987 Identity idObj = IdentityHolder.ResolveIdentity(url);
988 Object proxy = null;
989 if (idObj == null
990 || idObj.ChannelSink == null || idObj.EnvoyChain == null)
992 String objectURI = null;
993 IMessageSink chnlSink = null;
994 IMessageSink envoySink = null;
995 // Create the envoy and channel sinks
996 objectURI = CreateEnvoyAndChannelSinks(url, data, out chnlSink, out envoySink);
998 // ensure that we were able to create a channel sink
999 if (chnlSink == null)
1001 throw new RemotingException(
1002 String.Format(
1003 CultureInfo.CurrentCulture, Environment.GetResourceString(
1004 "Remoting_Connect_CantCreateChannelSink"),
1005 url));
1008 // Do not allow Connect() with null objUri (eg. http://localhost/)
1009 if (objectURI == null)
1011 throw new ArgumentException(
1012 Environment.GetResourceString(
1013 "Argument_InvalidUrl"));
1017 #if false
1018 // GopalK: Return the server object if the object uri is in the IDTable and is of type
1019 // ServerIdentity and the object URI starts with application name
1020 ServerIdentity srvId =
1021 IdentityHolder.ResolveIdentity(objectURI) as ServerIdentity;
1022 if (srvId != null
1023 && objectURI.StartsWith(RemotingConfigHandler.ApplicationName, StringComparison.Ordinal))
1025 return srvId.ServerObject;
1027 #endif
1029 // Try to find an existing identity or create a new one
1030 // Note: we create an identity entry hashed with the full url. This
1031 // means that the same well known object could have multiple
1032 // identities on the client side if it is connected through urls
1033 // that have different string representations.
1035 // <
1039 idObj = IdentityHolder.FindOrCreateIdentity(objectURI, url, null);
1041 // Set the envoy and channel sinks in a thread safe manner
1042 SetEnvoyAndChannelSinks(idObj, chnlSink, envoySink);
1045 // Get the proxy represented by the identity object
1046 proxy = GetOrCreateProxy(classToProxy, idObj);
1048 Message.DebugOut("RemotingService::Unmarshal returning ");
1050 return proxy;
1053 [System.Security.SecurityCritical] // auto-generated
1054 internal static Object Wrap(ContextBoundObject obj)
1056 return Wrap(obj, null, true);
1059 [System.Security.SecurityCritical] // auto-generated
1060 internal static Object Wrap(ContextBoundObject obj, Object proxy, bool fCreateSinks)
1062 Message.DebugOut("Entering Wrap for context " + Thread.CurrentContext + "\n");
1064 if ((null != obj) && (!IsTransparentProxy(obj)))
1066 Contract.Assert(obj.GetType().IsContextful,"objType.IsContextful");
1067 Message.DebugOut("Wrapping object \n");
1068 Identity idObj = null;
1070 if (proxy != null)
1072 // We will come here for strictly x-context activations
1073 // since a proxy has already been created and supplied
1074 // through the construction message frame (GetThisPtr()).
1075 RealProxy rp = GetRealProxy(proxy);
1076 if (rp.UnwrappedServerObject == null)
1078 rp.AttachServerHelper(obj);
1080 idObj = MarshalByRefObject.GetIdentity(obj);
1082 else
1084 // Proxy is null when Wrap() is called the second
1085 // time during activation
1086 // It also will be null when a ContextBoundObject
1087 // is being activated from a remote client.
1088 idObj = IdentityHolder.FindOrCreateServerIdentity(
1089 obj,
1090 null,
1091 IdOps.None);
1094 //********************WARNING*******************************
1095 // Always create the proxy before calling out to user code
1096 // so that any recursive calls by JIT to wrap will return this
1097 // proxy.
1098 //**********************************************************
1099 // Get the proxy represented by the identity object
1100 proxy = GetOrCreateProxy(idObj, proxy, true);
1102 // EXTENSIBILITY:
1103 GetRealProxy(proxy).Wrap();
1105 if (fCreateSinks)
1107 IMessageSink chnlSink = null;
1108 IMessageSink envoySink = null;
1109 // Create the envoy sinks and channel sink
1110 CreateEnvoyAndChannelSinks((MarshalByRefObject)proxy, null, out chnlSink, out envoySink);
1112 // Set the envoy and channel sinks in a thread safe manner
1113 SetEnvoyAndChannelSinks(idObj, chnlSink, envoySink);
1116 // This will handle the case where we call Wrap() with
1117 // a null proxy for real remote activation of ContextFul types.
1118 RealProxy rp2 = GetRealProxy(proxy);
1119 if (rp2.UnwrappedServerObject == null)
1121 rp2.AttachServerHelper(obj);
1123 Message.DebugOut("Leaving Wrap with proxy \n");
1124 return proxy;
1126 else
1128 Message.DebugOut("Leaving Wrap with passed in object\n");
1130 // Default return value is the object itself
1131 return obj;
1133 } // Wrap
1136 // This relies on the fact that no object uri is allowed to contain a slash
1137 // (in some cases, we might want to do something intelligent by parsing
1138 // the uri with the right channel, but that isn't possible in all cases).
1139 internal static String GetObjectUriFromFullUri(String fullUri)
1141 if (fullUri == null)
1142 return null;
1144 int index = fullUri.LastIndexOf('/');
1145 if (index == -1)
1146 return fullUri;
1148 return fullUri.Substring(index + 1);
1149 } // GetObjectUriFromFullUri
1154 [System.Security.SecurityCritical] // auto-generated
1155 [ResourceExposure(ResourceScope.None)]
1156 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1157 internal static extern Object Unwrap(ContextBoundObject obj);
1158 [System.Security.SecurityCritical] // auto-generated
1159 [ResourceExposure(ResourceScope.None)]
1160 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1161 internal static extern Object AlwaysUnwrap(ContextBoundObject obj);
1164 // This method does the actual work of Ma
1167 [System.Security.SecurityCritical] // auto-generated
1168 internal static Object InternalUnmarshal(
1169 ObjRef objectRef,
1170 Object proxy,
1171 bool fRefine)
1173 Object obj = null;
1174 Identity idObj = null;
1176 Context currContext = Thread.CurrentContext;
1177 Message.DebugOut("RemotingServices::InternalUnmarshal: <Begin> Current context id: " + (currContext.ContextID).ToString("x") + "\n");
1179 // This routine can be supplied a custom objref or an objref
1180 // generated by us. We do some sanity checking on the objref
1181 // to make sure that it is valid
1182 if (!ObjRef.IsWellFormed(objectRef))
1184 throw new ArgumentException(
1185 String.Format(
1186 CultureInfo.CurrentCulture, Environment.GetResourceString(
1187 "Argument_BadObjRef"),
1188 "Unmarshal"));
1191 // If it is a well known objectRef we need to just connect to
1192 // the URL inside the objectRef.
1193 if (objectRef.IsWellKnown())
1195 obj = Unmarshal(
1196 typeof(System.MarshalByRefObject),
1197 objectRef.URI);
1198 // ensure that we cache the objectRef in the ID
1199 // this contains type-info and we need it for
1200 // validating casts on the wellknown proxy
1201 // Note: this code path will be relatively rare ... the case
1202 // when a well known proxy is passed to a remote call
1203 // Otherwise it will be wise to another internal flavor of
1204 // Unmarshal call that returns the identity as an out param.
1205 idObj = IdentityHolder.ResolveIdentity(objectRef.URI);
1206 if (idObj.ObjectRef == null)
1208 idObj.RaceSetObjRef(objectRef);
1210 return obj;
1213 Message.DebugOut("RemotingService::InternalUnmarshal IN URI" + objectRef.URI);
1214 // Get the identity for the URI
1215 idObj = IdentityHolder.FindOrCreateIdentity(objectRef.URI, null, objectRef);
1217 currContext = Thread.CurrentContext;
1218 Message.DebugOut("RemotingServices::Unmarshal: <after FindOrCreateIdentity> Current context id: " +
1219 (currContext.ContextID).ToString("x") + "\n");
1221 // If we successfully completed the above method then we should
1222 // have an identity object
1223 BCLDebug.Assert(null != idObj,"null != idObj");
1226 Message.DebugOut("RemotingService::InternalUnmarshal IN URI" + objectRef.URI);
1228 Message.DebugOut("RemotingServices::InternalUnmarshal: <Begin> Current context id: " +
1229 (currContext.ContextID).ToString("x") + "\n");
1232 // Check whether we are on the server side or client-side
1233 ServerIdentity serverID = idObj as ServerIdentity;
1234 if ( serverID != null )
1236 Message.DebugOut("RemotingServices::InternalUnmarshal: Unmarshalling ServerIdentity\n");
1238 // SERVER SIDE
1239 // We are in the app domain of the server object.
1240 // If we are in the same context as the server then
1241 // just return the server object else return the proxy
1243 currContext = Thread.CurrentContext;
1244 Message.DebugOut("RemotingServices::InternalUnmarshal: Current context id: " +
1245 (currContext.ContextID).ToString("x") + "\n");
1246 Message.DebugOut("RemotingServices::InternalUnmarshal: ServerContext id: " +
1247 (serverID.ServerContext.ContextID).ToString("x") + "\n");
1249 if (!serverID.IsContextBound)
1251 BCLDebug.Assert(serverID.ServerType.IsMarshalByRef,
1252 "Object must be at least MarshalByRef in order to be marshaled");
1253 if (proxy != null)
1255 throw new ArgumentException(
1256 String.Format(
1257 CultureInfo.CurrentCulture, Environment.GetResourceString(
1258 "Remoting_BadInternalState_ProxySameAppDomain")));
1260 obj = serverID.TPOrObject;
1262 else
1264 Message.DebugOut("RemotingServices::InternalUnmarshal: Contexts don't match, returning proxy\n");
1266 IMessageSink chnlSink = null;
1267 IMessageSink envoySink = null;
1269 // Create the envoy sinks and channel sink
1270 CreateEnvoyAndChannelSinks(
1271 (MarshalByRefObject)serverID.TPOrObject,
1272 null,
1273 out chnlSink,
1274 out envoySink);
1276 // Set the envoy and channel sinks in a thread safe manner
1277 SetEnvoyAndChannelSinks(idObj, chnlSink, envoySink);
1279 // Get or create the proxy and return
1280 obj = GetOrCreateProxy(idObj, proxy, true);
1281 // This will be a TP
1282 BCLDebug.Assert(IsTransparentProxy(obj), "Unexpected server");
1285 else
1287 // CLIENT SIDE
1289 Message.DebugOut("RemotingServices::InternalUnmarshal: Unmarshalling Client-side Identity\n");
1291 IMessageSink chnlSink = null;
1292 IMessageSink envoySink = null;
1294 // Create the envoy sinks and channel sink
1295 if (!objectRef.IsObjRefLite())
1296 CreateEnvoyAndChannelSinks(null, objectRef, out chnlSink, out envoySink);
1297 else
1298 CreateEnvoyAndChannelSinks(objectRef.URI, null, out chnlSink, out envoySink);
1300 // Set the envoy and channel sinks in a thread safe manner
1301 SetEnvoyAndChannelSinks(idObj, chnlSink, envoySink);
1303 if (objectRef.HasProxyAttribute())
1305 fRefine = true;
1308 // Get or create the proxy and return
1309 obj = GetOrCreateProxy(idObj, proxy, fRefine);
1312 // Notify TrackingServices that we unmarshaled an object
1313 TrackingServices.UnmarshaledObject(obj, objectRef);
1315 // Return the proxy
1316 Message.DebugOut("RemotingService::InternalUnmarshl OUT \n");
1317 return obj;
1323 [System.Security.SecurityCritical] // auto-generated
1324 private static Object GetOrCreateProxy(
1325 Identity idObj, Object proxy, bool fRefine)
1327 Message.DebugOut("Entering GetOrCreateProxy for given proxy\n");
1329 // If we are not supplied a proxy then we have to find an existing
1330 // proxy or create one
1331 if (null == proxy)
1333 // Get the type of the server object
1334 Type serverType;
1335 ServerIdentity serverID = idObj as ServerIdentity;
1336 if (null != serverID)
1338 serverType = serverID.ServerType; // ServerObject.GetType();
1340 else
1342 BCLDebug.Assert(ObjRef.IsWellFormed(idObj.ObjectRef),
1343 "ObjRef.IsWellFormed(idObj.ObjectRef)");
1344 IRemotingTypeInfo serverTypeInfo = idObj.ObjectRef.TypeInfo;
1346 // For system generated type info we create the proxy for
1347 // object type. Later, when the proxy is cast to the appropriate
1348 // type we will update its internal state to refer to the cast type
1349 // This way we avoid loading the server type till cast time.
1351 // For type info generated by others we have no choice but to
1352 // load the type provided by the typeinfo. Sometimes, we
1353 // use this second approach even if the typeinfo has been
1354 // generated by us because this saves us an extra checkcast.
1355 // A typical example of this usage will be when we are
1356 // unmarshaling in parameters. We know that the unmarshal will
1357 // be followed by a check cast to ensure that the parameter type
1358 // matches the signature type, so we do both in one step.
1359 serverType = null;
1360 if (((serverTypeInfo is TypeInfo) && !fRefine) ||
1361 (serverTypeInfo == null))
1363 serverType = typeof(System.MarshalByRefObject);
1365 else
1367 String typeName = serverTypeInfo.TypeName;
1368 if (typeName != null)
1370 String typeNamespace = null;
1371 String assemNamespace = null;
1372 TypeInfo.ParseTypeAndAssembly(typeName, out typeNamespace, out assemNamespace);
1375 Assembly assem = FormatterServices.LoadAssemblyFromStringNoThrow(assemNamespace);
1377 if (assem != null)
1379 serverType = assem.GetType(typeNamespace, false, false);
1386 if (null == serverType)
1388 throw new RemotingException(
1389 String.Format(
1390 CultureInfo.CurrentCulture, Environment.GetResourceString(
1391 "Remoting_BadType"),
1392 serverTypeInfo.TypeName));
1395 Message.DebugOut("Creating Proxy for type " + serverType.FullName + "\n");
1396 proxy = SetOrCreateProxy(idObj, serverType, null);
1398 else
1400 // We have been supplied with a proxy. Set that proxy in
1401 // the identity object
1402 // Assert that this the activation case only as this code path is
1403 // not thread safe otherwise! (We call Wrap to associate an object
1404 // with its proxy during activation).
1405 BCLDebug.Assert(
1406 ((RemotingProxy)GetRealProxy(proxy)).ConstructorMessage!=null,
1407 "Only expect to be here during activation!");
1408 proxy = SetOrCreateProxy(idObj, null, proxy);
1411 // At this point we should have a non-null transparent proxy
1412 if (proxy == null)
1413 throw new RemotingException(Environment.GetResourceString("Remoting_UnexpectedNullTP"));
1415 BCLDebug.Assert(IsTransparentProxy(proxy),"IsTransparentProxy(proxy)");
1417 Message.DebugOut("Leaving GetOrCreateProxy for given proxy\n");
1418 // Return the underlying transparent proxy
1419 return proxy;
1424 // This version of GetOrCreateProxy is used for Connect(URI, type)
1425 [System.Security.SecurityCritical] // auto-generated
1426 private static Object GetOrCreateProxy(Type classToProxy, Identity idObj)
1428 Message.DebugOut("Entering GetOrCreateProxy for given class\n");
1430 Object proxy = idObj.TPOrObject;
1431 if (null == proxy)
1433 // Create the proxy
1434 proxy = SetOrCreateProxy(idObj, classToProxy, null);
1436 // proxy from idObj may be non-null if we are doing a Connect
1437 // under new XXX() ... also if we are connecting to a remote URL
1438 // which we previously connected.
1440 // If we are in the same domain as the server object then we
1441 // can check for type compatibility of the proxy with the given
1442 // type. Otherwise, we will defer this check to method call time.
1443 // If we do not do this now then we run the risk of returning
1444 // a proxy which is different from the type given.
1446 // <
1452 ServerIdentity serverID = idObj as ServerIdentity;
1453 if (null != serverID)
1455 // Check for type compatibility
1456 Type serverType = serverID.ServerType;
1457 if (!classToProxy.IsAssignableFrom(serverType))
1459 throw new InvalidCastException(
1460 String.Format(
1461 CultureInfo.CurrentCulture, Environment.GetResourceString(
1462 "InvalidCast_FromTo"),
1463 serverType.FullName,
1464 classToProxy.FullName));
1469 // At this point we should have a non-null transparent proxy
1470 BCLDebug.Assert(null != proxy && IsTransparentProxy(proxy),"null != proxy && IsTransparentProxy(proxy)");
1472 Message.DebugOut("Leaving GetOrCreateProxy for given class\n");
1473 return proxy;
1477 [System.Security.SecurityCritical] // auto-generated
1478 private static MarshalByRefObject SetOrCreateProxy(
1479 Identity idObj, Type classToProxy, Object proxy)
1482 Message.DebugOut("Entering SetOrCreateProxy for type \n");
1484 RealProxy realProxy = null;
1485 // If a proxy has not been supplied create one
1486 if (null == proxy)
1488 // Create a remoting proxy
1489 Message.DebugOut("SetOrCreateProxy::Creating Proxy for " +
1490 classToProxy.FullName + "\n");
1492 ServerIdentity srvID = idObj as ServerIdentity;
1493 if (idObj.ObjectRef != null)
1495 ProxyAttribute pa = ActivationServices.GetProxyAttribute(classToProxy);
1496 realProxy = pa.CreateProxy(idObj.ObjectRef,
1497 classToProxy,
1498 null, //
1499 null); //
1501 if(null == realProxy)
1503 // The custom proxy attribute does not want to create a proxy. We create a default
1504 // proxy in this case.
1505 ProxyAttribute defaultProxyAttribute = ActivationServices.DefaultProxyAttribute;
1507 realProxy = defaultProxyAttribute.CreateProxy(idObj.ObjectRef,
1508 classToProxy,
1509 null,
1510 (null == srvID ? null :
1511 srvID.ServerContext));
1514 else
1516 BCLDebug.Assert(IsTransparentProxy(proxy),"IsTransparentProxy(proxy)");
1518 // Extract the remoting proxy from the transparent proxy
1519 Message.DebugOut("SetOrCreateProxy::Proxy already created \n");
1520 realProxy = GetRealProxy(proxy);
1523 BCLDebug.Assert(null != realProxy,"null != realProxy");
1525 // Set the back reference to the identity in the proxy object
1526 realProxy.IdentityObject = idObj;
1528 // Set the reference to the proxy in the identity object
1529 proxy = realProxy.GetTransparentProxy();
1530 proxy = idObj.RaceSetTransparentProxy(proxy);
1532 Message.DebugOut("Leaving SetOrCreateProxy\n");
1533 // return the transparent proxy
1534 return (MarshalByRefObject)proxy;
1537 // Check
1538 private static bool AreChannelDataElementsNull(Object[] channelData)
1540 foreach(Object o in channelData)
1542 if (o != null)
1543 return false;
1546 return true;
1550 [System.Security.SecurityCritical] // auto-generated
1551 internal static void CreateEnvoyAndChannelSinks(
1552 MarshalByRefObject tpOrObject,
1553 ObjRef objectRef,
1554 out IMessageSink chnlSink,
1555 out IMessageSink envoySink)
1558 Message.DebugOut("Creating envoy and channel sinks \n");
1559 BCLDebug.Assert(
1560 ((null != tpOrObject) || (null != objectRef)),
1561 "((null != tpOrObject) || (null != objectRef)");
1563 // Set the out parameters
1564 chnlSink = null;
1565 envoySink = null;
1567 if (null == objectRef)
1569 // If the objectRef is not present this is a cross context case
1570 // and we should set the cross context channel sink
1571 chnlSink = ChannelServices.GetCrossContextChannelSink();
1573 envoySink = Thread.CurrentContext.CreateEnvoyChain(tpOrObject);
1575 else
1577 // Extract the channel from the channel data and name embedded
1578 // inside the objectRef
1579 Object[] channelData = objectRef.ChannelInfo.ChannelData;
1580 if (channelData != null && !AreChannelDataElementsNull(channelData))
1582 for (int i = 0; i < channelData.Length; i++)
1584 // Get the first availabe sink
1585 chnlSink = ChannelServices.CreateMessageSink(channelData[i]);
1586 if (null != chnlSink)
1588 break;
1593 // if chnkSink is still null, try to find a channel that can service
1594 // this uri.
1595 if (null == chnlSink)
1597 // NOTE: careful! we are calling user code here after holding
1598 // the delayLoadChannelLock (channel ctor-s for arbitrary channels
1599 // will run while the lock is held).
1600 lock (s_delayLoadChannelLock)
1602 // Check once to ensure that noone beat us in a ----
1603 for (int i = 0; i < channelData.Length; i++)
1605 // Get the first availabe sink
1606 chnlSink = ChannelServices.CreateMessageSink(channelData[i]);
1607 if (null != chnlSink)
1609 break;
1614 if (null == chnlSink)
1616 // We don't have a sink
1617 foreach (Object data in channelData)
1619 String objectURI;
1620 chnlSink =
1621 RemotingConfigHandler.FindDelayLoadChannelForCreateMessageSink(
1622 null, data, out objectURI);
1623 if (null != chnlSink)
1624 break;
1631 // Extract the envoy sinks from the objectRef
1632 if ((null != objectRef.EnvoyInfo) &&
1633 (null != objectRef.EnvoyInfo.EnvoySinks))
1635 envoySink = objectRef.EnvoyInfo.EnvoySinks;
1637 else
1639 envoySink = EnvoyTerminatorSink.MessageSink;
1644 [System.Security.SecurityCritical] // auto-generated
1645 internal static String CreateEnvoyAndChannelSinks(String url,
1646 Object data,
1647 out IMessageSink chnlSink,
1648 out IMessageSink envoySink)
1650 BCLDebug.Assert(null != url,"null != url");
1651 String objectURI = null;
1653 objectURI = CreateChannelSink(url, data, out chnlSink);
1655 envoySink = EnvoyTerminatorSink.MessageSink;
1657 return objectURI;
1660 [System.Security.SecurityCritical] // auto-generated
1661 private static String CreateChannelSink(String url, Object data, out IMessageSink chnlSink)
1663 BCLDebug.Assert(null != url,"null != url");
1664 String objectURI = null;
1666 chnlSink = ChannelServices.CreateMessageSink(url, data, out objectURI);
1668 // if chnkSink is still null, try to find a channel that can service this uri.
1669 if (null == chnlSink)
1671 lock (s_delayLoadChannelLock)
1673 chnlSink = ChannelServices.CreateMessageSink(url, data, out objectURI);
1674 if (null == chnlSink)
1676 chnlSink =
1677 RemotingConfigHandler.FindDelayLoadChannelForCreateMessageSink(
1678 url, data, out objectURI);
1683 return objectURI;
1684 } // CreateChannelSinks
1686 internal static void SetEnvoyAndChannelSinks(Identity idObj,
1687 IMessageSink chnlSink,
1688 IMessageSink envoySink)
1690 Message.DebugOut("Setting up envoy and channel sinks \n");
1691 BCLDebug.Assert(null != idObj,"null != idObj");
1693 // Decide if we need to set the envoy sink chain
1694 if (null == idObj.ChannelSink)
1696 if (null != chnlSink)
1698 idObj.RaceSetChannelSink(chnlSink);
1702 // Decide if we need to set the envoy sink chain
1703 if (null == idObj.EnvoyChain)
1705 if (null != envoySink)
1707 idObj.RaceSetEnvoyChain(envoySink);
1709 else
1711 throw new RemotingException(
1712 String.Format(
1713 CultureInfo.CurrentCulture, Environment.GetResourceString(
1714 "Remoting_BadInternalState_FailEnvoySink")));
1719 // Check whether the transparent proxy backing the real proxy
1720 // is assignable from the given type.
1721 [System.Security.SecurityCritical] // auto-generated
1722 private static bool CheckCast(RealProxy rp, RuntimeType castType)
1724 // NOTE: This is the point where JIT_CheckCastClass ultimately
1725 // lands up in the managed world if the object being cast is
1726 // a transparent proxy.
1727 // If we are here, it means that walking the current EEClass
1728 // up the chain inside the EE was unable to verify the cast.
1730 Message.DebugOut("Entered CheckCast for type " + castType);
1731 bool fCastOK = false;
1733 BCLDebug.Assert(rp != null, "Shouldn't be called with null real proxy.");
1735 // Always return true if cast is to System.Object
1736 if (castType == typeof(Object))
1737 return true;
1739 // We do not allow casting to non-interface types that do not extend
1740 // from System.MarshalByRefObject
1741 if (!castType.IsInterface && !castType.IsMarshalByRef)
1742 return false;
1744 // Note: this is a bit of a hack to allow deserialization of WellKnown
1745 // object refs (in the well known cases, we always return TRUE for
1746 // interface casts but doing so messes us up in the case when
1747 // the object manager is trying to resolve object references since
1748 // it ends up thinking that the proxy we returned needs to be resolved
1749 // further).
1750 if (castType != typeof(IObjectReference))
1752 IRemotingTypeInfo typeInfo = rp as IRemotingTypeInfo;
1753 if(null != typeInfo)
1755 fCastOK = typeInfo.CanCastTo(castType, rp.GetTransparentProxy());
1757 else
1759 // The proxy does not implement IRemotingTypeInfo, so we should
1760 // try to do casting based on the ObjRef type info.
1761 Identity id = rp.IdentityObject;
1762 if (id != null)
1764 ObjRef objRef = id.ObjectRef;
1765 if (objRef != null)
1767 typeInfo = objRef.TypeInfo;
1768 if (typeInfo != null)
1770 fCastOK = typeInfo.CanCastTo(castType, rp.GetTransparentProxy());
1777 Message.DebugOut("CheckCast returning " + fCastOK);
1778 return fCastOK;
1781 [System.Security.SecurityCritical] // auto-generated
1782 internal static bool ProxyCheckCast(RealProxy rp, RuntimeType castType)
1784 return CheckCast(rp, castType);
1785 } // ProxyCheckCast
1788 **CheckCast
1789 **Action: When a proxy to an object is serialized, the MethodTable is only
1790 ** expanded on an on-demand basis. For purely managed operations, this
1791 ** happens in a transparent fashion. However, for delegates (and
1792 ** potentially other types) we need to force this expansion to happen.
1793 **Returns: The newly expanded object. Returns the identity if no expansion is required.
1794 **Arguments: objToExpand -- The object to be expanded.
1795 ** type -- the type to which to expand it.
1796 **Exceptions: None.
1798 [System.Security.SecurityCritical] // auto-generated
1799 [ResourceExposure(ResourceScope.None)]
1800 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1801 internal static extern Object CheckCast(Object objToExpand, RuntimeType type);
1803 [System.Security.SecurityCritical] // auto-generated
1804 internal static GCHandle CreateDelegateInvocation(WaitCallback waitDelegate, Object state)
1806 Object[] delegateCallToken = new Object[2];
1807 delegateCallToken[0] = waitDelegate;
1808 delegateCallToken[1] = state;
1809 return System.Runtime.InteropServices.GCHandle.Alloc(delegateCallToken);
1812 [System.Security.SecurityCritical] // auto-generated
1813 internal static void DisposeDelegateInvocation(GCHandle delegateCallToken)
1815 delegateCallToken.Free();
1818 [System.Security.SecurityCritical] // auto-generated
1819 internal static Object CreateProxyForDomain(int appDomainId, IntPtr defCtxID)
1821 AppDomain proxy = null;
1823 ObjRef objRef = CreateDataForDomain(appDomainId, defCtxID);
1825 // Unmarshal the objref in the old app domain
1826 proxy = (AppDomain)Unmarshal(objRef);
1828 return proxy;
1829 } // CreateProxyForDomain
1831 [System.Security.SecurityCritical] // auto-generated
1832 internal static Object CreateDataForDomainCallback(Object[] args)
1834 // Ensure that the well known channels are registered in this domain too
1835 RegisterWellKnownChannels();
1837 // Marshal the app domain object
1838 ObjRef objref = MarshalInternal(
1839 Thread.CurrentContext.AppDomain,
1840 null,
1841 null,
1842 false);
1844 ServerIdentity si = (ServerIdentity)MarshalByRefObject.GetIdentity(Thread.CurrentContext.AppDomain);
1845 si.SetHandle();
1846 objref.SetServerIdentity(si.GetHandle());
1847 objref.SetDomainID(AppDomain.CurrentDomain.GetId());
1848 return objref;
1851 [System.Security.SecurityCritical] // auto-generated
1852 internal static ObjRef CreateDataForDomain(int appDomainId, IntPtr defCtxID)
1854 // This is a subroutine of CreateProxyForDomain
1855 // so we can segregate the object references
1856 // from different app domains into different frames. This is
1857 // important for the app domain leak checking code.
1859 Message.DebugOut("Creating proxy for domain " + appDomainId + "\n");
1861 RegisterWellKnownChannels();
1863 InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(CreateDataForDomainCallback);
1865 return (ObjRef) Thread.CurrentThread.InternalCrossContextCallback(null, defCtxID, appDomainId, xctxDel, null);
1867 } // CreateDataForDomain
1870 [System.Security.SecurityCritical] // auto-generated_required
1871 public static MethodBase GetMethodBaseFromMethodMessage(IMethodMessage msg)
1873 MethodBase mb = InternalGetMethodBaseFromMethodMessage(msg);
1874 return mb;
1877 [System.Security.SecurityCritical] // auto-generated
1878 internal static MethodBase InternalGetMethodBaseFromMethodMessage(IMethodMessage msg)
1880 if(null == msg)
1882 return null;
1885 Type t = RemotingServices.InternalGetTypeFromQualifiedTypeName(msg.TypeName);
1886 if (t == null)
1888 throw new RemotingException(
1889 String.Format(
1890 CultureInfo.CurrentCulture, Environment.GetResourceString(
1891 "Remoting_BadType"),
1892 msg.TypeName));
1896 // Use the signature, type and method name to determine the
1897 // methodbase via reflection.
1898 Type[] signature = (Type[])msg.MethodSignature;
1899 return GetMethodBase(msg, t, signature);
1902 [System.Security.SecurityCritical] // auto-generated_required
1903 public static bool IsMethodOverloaded(IMethodMessage msg)
1905 RemotingMethodCachedData cache =
1906 InternalRemotingServices.GetReflectionCachedData(msg.MethodBase);
1908 return cache.IsOverloaded();
1909 } // IsMethodOverloaded
1912 [System.Security.SecurityCritical] // auto-generated
1913 private static MethodBase GetMethodBase(IMethodMessage msg, Type t, Type[] signature)
1915 MethodBase mb = null;
1917 // Get the reflection object depending on whether it is a
1918 // constructor call or a method call.
1919 if((msg is IConstructionCallMessage) ||
1920 (msg is IConstructionReturnMessage))
1922 if((null == signature))
1924 BCLDebug.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with null sig ", msg.MethodName);
1925 ConstructorInfo[] ci;
1926 RuntimeType rt = t as RuntimeType;
1927 if (rt == null)
1928 ci = t.GetConstructors();
1929 else
1930 ci = rt.GetConstructors();
1932 if(1 != ci.Length)
1934 // There is more than one constructor defined but
1935 // we do not have a signature to differentiate between
1936 // them.
1937 throw new AmbiguousMatchException(
1938 Environment.GetResourceString(
1939 "Remoting_AmbiguousCTOR"));
1941 mb = ci[0];
1943 else
1945 BCLDebug.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with non-null sig ", msg.MethodName, " ", signature.Length);
1946 RuntimeType rt = t as RuntimeType;
1947 if (rt == null)
1948 mb = t.GetConstructor(signature);
1949 else
1950 mb = rt.GetConstructor(signature);
1953 else if((msg is IMethodCallMessage) || (msg is IMethodReturnMessage))
1955 // We demand reflection permission in the api that calls this
1956 // for non-public types
1957 if(null == signature)
1959 BCLDebug.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with null sig ", msg.MethodName);
1960 RuntimeType rt = t as RuntimeType;
1961 if (rt == null)
1962 mb = t.GetMethod(msg.MethodName, RemotingServices.LookupAll);
1963 else
1964 mb = rt.GetMethod(msg.MethodName, RemotingServices.LookupAll);
1966 else
1968 BCLDebug.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with non-null sig ", msg.MethodName, " ", signature.Length);
1969 RuntimeType rt = t as RuntimeType;
1970 if (rt == null)
1971 mb = t.GetMethod(msg.MethodName, RemotingServices.LookupAll, null, signature, null);
1972 else
1973 mb = rt.GetMethod(msg.MethodName, RemotingServices.LookupAll, null, CallingConventions.Any, signature, null);
1978 return mb;
1981 [System.Security.SecurityCritical] // auto-generated
1982 internal static bool IsMethodAllowedRemotely(MethodBase method)
1984 // MarhsalByRefObject.InvokeMember is allowed to be invoked remotely. It is a wrapper for a com method as represented in managed
1985 // code. The managed code was generated by tlbimpl. A test does not have to be made to make sure that the COM object method is public because
1986 // the tlbimpl will only generate methods which can be invoked remotely.
1988 if (s_FieldGetterMB == null ||
1989 s_FieldSetterMB == null ||
1990 s_IsInstanceOfTypeMB == null ||
1991 s_InvokeMemberMB == null ||
1992 s_CanCastToXmlTypeMB == null)
1994 System.Security.CodeAccessPermission.Assert(true);
1995 if (s_FieldGetterMB == null)
1996 s_FieldGetterMB = typeof(Object).GetMethod(FieldGetterName,RemotingServices.LookupAll);
1998 if (s_FieldSetterMB == null)
1999 s_FieldSetterMB = typeof(Object).GetMethod(FieldSetterName, RemotingServices.LookupAll);
2001 if (s_IsInstanceOfTypeMB == null)
2003 s_IsInstanceOfTypeMB =
2004 typeof(MarshalByRefObject).GetMethod(
2005 IsInstanceOfTypeName, RemotingServices.LookupAll);
2008 if (s_CanCastToXmlTypeMB == null)
2010 s_CanCastToXmlTypeMB =
2011 typeof(MarshalByRefObject).GetMethod(
2012 CanCastToXmlTypeName, RemotingServices.LookupAll);
2015 if (s_InvokeMemberMB == null)
2017 s_InvokeMemberMB =
2018 typeof(MarshalByRefObject).GetMethod(
2019 InvokeMemberName, RemotingServices.LookupAll);
2023 return
2024 method == s_FieldGetterMB ||
2025 method == s_FieldSetterMB ||
2026 method == s_IsInstanceOfTypeMB ||
2027 method == s_InvokeMemberMB ||
2028 method == s_CanCastToXmlTypeMB;
2031 [System.Security.SecurityCritical] // auto-generated_required
2032 public static bool IsOneWay(MethodBase method)
2034 if (method == null)
2035 return false;
2037 RemotingMethodCachedData cache =
2038 InternalRemotingServices.GetReflectionCachedData(method);
2040 return cache.IsOneWayMethod();
2043 // Given a method base object, see if we can find an async version of the
2044 // method on the same class.
2045 internal static bool FindAsyncMethodVersion(MethodInfo method,
2046 out MethodInfo beginMethod,
2047 out MethodInfo endMethod)
2049 beginMethod = null;
2050 endMethod = null;
2052 // determine names of Begin/End versions
2053 String beginName = "Begin" + method.Name;
2054 String endName = "End" + method.Name;
2056 // determine parameter lists for Begin/End versions
2057 ArrayList beginParameters = new ArrayList();
2058 ArrayList endParameters = new ArrayList();
2060 Type beginReturnType = typeof(IAsyncResult);
2061 Type endReturnType = method.ReturnType;
2063 ParameterInfo[] paramList = method.GetParameters();
2064 foreach (ParameterInfo param in paramList)
2066 if (param.IsOut)
2067 endParameters.Add(param);
2068 else
2069 if (param.ParameterType.IsByRef)
2071 beginParameters.Add(param);
2072 endParameters.Add(param);
2074 else
2076 // it's an in parameter
2077 beginParameters.Add(param);
2081 beginParameters.Add(typeof(AsyncCallback));
2082 beginParameters.Add(typeof(Object));
2083 endParameters.Add(typeof(IAsyncResult));
2085 // try to match these signatures with the methods on the type
2086 Type type = method.DeclaringType;
2087 MethodInfo[] methods = type.GetMethods();
2089 foreach (MethodInfo mi in methods)
2091 ParameterInfo[] parameterList = mi.GetParameters();
2093 // see if return value is IAsyncResult
2094 if (mi.Name.Equals(beginName) &&
2095 (mi.ReturnType == beginReturnType) &&
2096 CompareParameterList(beginParameters, parameterList))
2099 beginMethod = mi;
2101 else
2102 if (mi.Name.Equals(endName) &&
2103 (mi.ReturnType == endReturnType) &&
2104 CompareParameterList(endParameters, parameterList))
2106 endMethod = mi;
2110 if ((beginMethod != null) && (endMethod != null))
2111 return true;
2112 else
2113 return false;
2114 } // FindAsyncMethodVersion
2117 // Helper function for FindAsyncMethodVersion
2118 private static bool CompareParameterList(ArrayList params1, ParameterInfo[] params2)
2120 // params1 contains a list of parameters (and possibly some types which are
2121 // assumed to be in parameters)
2122 // param2 just contains the list of parameters from some method
2124 if (params1.Count != params2.Length)
2125 return false;
2127 int co = 0;
2128 foreach (Object obj in params1)
2130 ParameterInfo param = params2[co];
2132 ParameterInfo pi = obj as ParameterInfo;
2133 if (null != pi)
2135 if ((pi.ParameterType != param.ParameterType) ||
2136 (pi.IsIn != param.IsIn) ||
2137 (pi.IsOut != param.IsOut))
2139 return false;
2142 else
2143 if (((Type)obj != param.ParameterType) && param.IsIn)
2144 return false;
2145 co++;
2148 return true;
2149 } // CompareParameterList
2152 [System.Security.SecurityCritical] // auto-generated_required
2153 public static Type GetServerTypeForUri(String URI)
2155 Type svrType = null;
2157 if(null != URI)
2159 ServerIdentity srvID = (ServerIdentity)IdentityHolder.ResolveIdentity(URI);
2161 if(null == srvID)
2163 // Check if this a well-known object which needs to be faulted in
2164 svrType = RemotingConfigHandler.GetServerTypeForUri(URI);
2166 else
2168 svrType = srvID.ServerType;
2172 return svrType;
2176 // This method is called after an appdomain is unloaded from the
2177 // current domain.
2178 [System.Security.SecurityCritical] // auto-generated
2179 internal static void DomainUnloaded(Int32 domainID)
2181 // Remove any client side identities, presumably the driver
2182 // domain has released all references to proxies in the unloaded
2183 // domain.
2184 IdentityHolder.FlushIdentityTable();
2185 // Remove the cross domain channel sink for the unloaded domain
2186 CrossAppDomainSink.DomainUnloaded(domainID);
2189 // This method is called from the VM and helps the appdomain
2190 // folks to get to the server appdomain from a proxy. This is
2191 // expected to be called on strictly cross domain proxies.
2193 // This returns the unmanaged context object for the proxy.
2194 // We fetch the appDomain out of the context in the VM.
2195 // This will return NULL (or 0) if the server for the proxy is
2196 // not from this process or if the server domain is invalid
2197 // or if there is not enough information to determine the server
2198 // context.
2199 [System.Security.SecurityCritical] // auto-generated
2200 internal static IntPtr GetServerContextForProxy(Object tp)
2202 ObjRef objRef = null;
2203 bool bSameDomain;
2204 int domainId;
2205 return GetServerContextForProxy(
2206 tp,
2207 out objRef,
2208 out bSameDomain,
2209 out domainId);
2212 // This returns the domain ID if the proxy is from this process
2213 // whether or not the domain is valid!
2214 [System.Security.SecurityCritical] // auto-generated
2215 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
2216 internal static int GetServerDomainIdForProxy(Object tp)
2218 Contract.Assert(IsTransparentProxy(tp),"Must be called only for TPs");
2219 RealProxy rp=GetRealProxy(tp);
2220 Identity id = rp.IdentityObject;
2221 return id.ObjectRef.GetServerDomainId();
2225 // This will retrieve the server domain and context id
2226 [System.Security.SecurityCritical] // auto-generated
2227 internal static void GetServerContextAndDomainIdForProxy(Object tp,
2228 out IntPtr contextId,
2229 out int domainId)
2231 ObjRef objRef;
2232 bool bSameDomain;
2233 contextId =
2234 GetServerContextForProxy(
2235 tp,
2236 out objRef,
2237 out bSameDomain,
2238 out domainId);
2239 } // GetServerContextAndDomainIdForProxy
2242 // This is a helper for the methods above.
2243 // NOTE:: Returns the unmanaged server context for a proxy
2244 // This is *NOT* the same as "public int Context::ContextID"
2245 [System.Security.SecurityCritical] // auto-generated
2246 private static IntPtr GetServerContextForProxy(
2247 Object tp, out ObjRef objRef, out bool bSameDomain, out int domainId)
2249 // Note: the contextId we return from here should be the address
2250 // of the unmanaged (VM) context object or NULL.
2252 IntPtr contextId = IntPtr.Zero;
2253 objRef = null;
2254 bSameDomain = false;
2255 domainId = 0;
2256 if (IsTransparentProxy(tp))
2258 // This is a transparent proxy. Try to obtain the backing
2259 // RealProxy from it.
2260 RealProxy rp = GetRealProxy(tp);
2262 // Get the identity from the realproxy
2263 Identity id = rp.IdentityObject;
2264 if(null != id)
2266 ServerIdentity serverID = id as ServerIdentity;
2267 if (null != serverID)
2269 // We are in the app domain of the server
2270 bSameDomain = true;
2271 contextId = serverID.ServerContext.InternalContextID;
2272 domainId = Thread.GetDomain().GetId();
2274 else
2276 // Server is from another app domain
2277 // (possibly from another process)
2278 objRef = id.ObjectRef;
2279 if (objRef != null)
2281 contextId = objRef.GetServerContext(out domainId);
2283 else
2285 // Proxy does not have an associated ObjRef
2286 // <
2290 //Contract.Assert(false, "Found proxy without an objref");
2291 contextId = IntPtr.Zero;
2295 else
2297 // This was probably a custom proxy other than RemotingProxy
2298 Contract.Assert(
2299 !(rp is RemotingProxy),
2300 "!(rp is RemotingProxy)");
2302 contextId = Context.DefaultContext.InternalContextID;
2306 return contextId;
2309 // Return the server context of the object provided if the object
2310 // was born in the current appdomain, else return null.
2312 // NOTE: This returns the managed context object that the server
2313 // is associated with ...
2314 // <
2316 [System.Security.SecurityCritical] // auto-generated
2317 internal static Context GetServerContext(MarshalByRefObject obj)
2319 Context serverCtx = null;
2321 if(!IsTransparentProxy(obj) && (obj is ContextBoundObject))
2323 // The object is native to the current context.
2324 serverCtx = Thread.CurrentContext;
2326 else
2328 RealProxy rp = GetRealProxy(obj);
2329 Identity id = rp.IdentityObject;
2330 ServerIdentity serverID = id as ServerIdentity;
2331 if(null != serverID)
2333 // The object was born in the current appdomain.
2334 // Extract the server context.
2335 serverCtx = serverID.ServerContext;
2339 return serverCtx;
2342 // Return the actual type of the server object given the proxy
2345 [System.Security.SecurityCritical] // auto-generated
2346 private static Object GetType(Object tp)
2348 Contract.Assert(IsTransparentProxy(tp), "IsTransparentProxy(tp)");
2350 Type serverType = null;
2352 RealProxy rp = GetRealProxy(tp);
2353 Identity id = rp.IdentityObject;
2354 Contract.Assert(!(id is ServerIdentity), "(!id is ServerIdentity)");
2355 if((null != id) && (null != id.ObjectRef) &&
2356 (null != id.ObjectRef.TypeInfo))
2358 IRemotingTypeInfo serverTypeInfo = id.ObjectRef.TypeInfo;
2359 String typeName = serverTypeInfo.TypeName;
2360 if (typeName != null)
2362 serverType = InternalGetTypeFromQualifiedTypeName(typeName);
2366 return serverType;
2370 [System.Security.SecurityCritical] // auto-generated
2371 internal static byte[] MarshalToBuffer(Object o, bool crossRuntime)
2373 if (crossRuntime)
2375 // Making a call on a MBRO cross-process or cross-runtime likely fails in most common
2376 // scenarios. We check for signs that Remoting is really expected by the user.
2377 if (RemotingServices.IsTransparentProxy(o))
2379 if (RemotingServices.GetRealProxy(o) is RemotingProxy)
2381 // the object uses a default proxy - it means that Remoting may not be expected
2382 if (ChannelServices.RegisteredChannels.Length == 0)
2384 return null;
2388 else
2390 MarshalByRefObject mbro = o as MarshalByRefObject;
2391 if (mbro != null)
2393 ProxyAttribute proxyAttr = ActivationServices.GetProxyAttribute(mbro.GetType());
2394 if (proxyAttr == ActivationServices.DefaultProxyAttribute)
2396 // the object does not use a custom proxy - it means that Remoting may not be expected
2397 if (ChannelServices.RegisteredChannels.Length == 0)
2399 return null;
2406 // serialize headers and args together using the binary formatter
2407 MemoryStream stm = new MemoryStream();
2408 RemotingSurrogateSelector ss = new RemotingSurrogateSelector();
2409 BinaryFormatter fmt = new BinaryFormatter();
2410 fmt.SurrogateSelector = ss;
2411 fmt.Context = new StreamingContext(StreamingContextStates.Other);
2412 fmt.Serialize(stm, o, null, false /* No Security check */);
2414 return stm.GetBuffer();
2417 [System.Security.SecurityCritical] // auto-generated
2418 internal static Object UnmarshalFromBuffer(byte [] b, bool crossRuntime)
2420 MemoryStream stm = new MemoryStream(b);
2421 BinaryFormatter fmt = new BinaryFormatter();
2422 fmt.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; //*******Add this line
2423 fmt.SurrogateSelector = null;
2424 fmt.Context = new StreamingContext(StreamingContextStates.Other);
2425 Object o = fmt.Deserialize(stm, null, false /* No Security check */);
2427 if (crossRuntime && RemotingServices.IsTransparentProxy(o))
2429 // Making a call on a MBRO cross-process or cross-runtime likely fails in most common
2430 // scenarios. We check for signs that Remoting is really expected by the user.
2431 if (!(RemotingServices.GetRealProxy(o) is RemotingProxy))
2433 // the object uses a non-default proxy - this means that Remoting is expected
2434 return o;
2437 if (ChannelServices.RegisteredChannels.Length == 0)
2439 // the object uses the default Remoting proxy but there are no channels registered
2440 return null;
2443 // make a dummy call on the proxy and if it passes use Remoting (the caller of this method
2444 // catches exceptions and interprets them as fallback to COM)
2445 o.GetHashCode();
2448 return o;
2451 internal static Object UnmarshalReturnMessageFromBuffer(byte [] b, IMethodCallMessage msg)
2453 MemoryStream stm = new MemoryStream(b);
2454 BinaryFormatter fmt = new BinaryFormatter();
2455 fmt.SurrogateSelector = null;
2456 fmt.Context = new StreamingContext(StreamingContextStates.Other);
2457 Object o = fmt.DeserializeMethodResponse(stm, null, (IMethodCallMessage)msg);
2458 //= fmt.Deserialize(stm, null, false /* No Security check */);
2459 return o;
2462 [System.Security.SecurityCritical] // auto-generated_required
2463 public static IMethodReturnMessage ExecuteMessage(MarshalByRefObject target,
2464 IMethodCallMessage reqMsg)
2466 // Argument validation
2467 if(null == target)
2469 throw new ArgumentNullException("target");
2471 Contract.EndContractBlock();
2473 RealProxy rp = GetRealProxy(target);
2475 // Check for context match
2476 if( rp is RemotingProxy
2477 && !rp.DoContextsMatch() )
2479 throw new RemotingException(
2480 Environment.GetResourceString("Remoting_Proxy_WrongContext"));
2483 // Dispatch the message
2484 StackBuilderSink dispatcher = new StackBuilderSink(target);
2486 // dispatch the message
2487 IMethodReturnMessage retMsg = (IMethodReturnMessage)dispatcher.SyncProcessMessage(reqMsg);
2489 return retMsg;
2490 } // ExecuteMessage
2495 // Methods for mapping and resolving qualified type names
2496 // A qualified type name describes the name that we use in the ObjRef and
2497 // message TypeName. It consists either of the actual type name or
2498 // "<typeId>:typename" where for now "soap:<soap type name>" is the only
2499 // supported alternative. <
2503 // This is used by the cached type data to figure out which type name
2504 // to use (this should never be publicly exposed; GetDefaultQualifiedTypeName should,
2505 // if anything at all)
2506 [System.Security.SecurityCritical] // auto-generated
2507 internal static String DetermineDefaultQualifiedTypeName(Type type)
2509 if (type == null)
2510 throw new ArgumentNullException("type");
2511 Contract.EndContractBlock();
2513 // see if there is an xml type name
2514 String xmlTypeName = null;
2515 String xmlTypeNamespace = null;
2516 if (SoapServices.GetXmlTypeForInteropType(type, out xmlTypeName, out xmlTypeNamespace))
2518 return "soap:" + xmlTypeName + ", " + xmlTypeNamespace;
2521 // there are no special mappings, so use the fully qualified CLR type name
2522 // <
2523 return type.AssemblyQualifiedName;
2524 } // DetermineDefaultQualifiedTypeName
2527 // retrieves type name from the cache data which uses DetermineDefaultQualifiedTypeName
2528 [System.Security.SecurityCritical] // auto-generated
2529 internal static String GetDefaultQualifiedTypeName(RuntimeType type)
2531 RemotingTypeCachedData cache = (RemotingTypeCachedData)
2532 InternalRemotingServices.GetReflectionCachedData(type);
2534 return cache.QualifiedTypeName;
2535 } // GetDefaultQualifiedTypeName
2538 internal static String InternalGetClrTypeNameFromQualifiedTypeName(String qualifiedTypeName)
2540 // look to see if this is a clr type name
2541 if (qualifiedTypeName.Length > 4) // length of "clr:"
2543 if (String.CompareOrdinal(qualifiedTypeName, 0, "clr:", 0, 4) == 0)
2545 // strip "clr:" off the front
2546 String actualTypeName = qualifiedTypeName.Substring(4);
2547 return actualTypeName;
2550 return null;
2553 private static int IsSoapType(String qualifiedTypeName)
2555 // look to see if this is a soap type name
2556 if (qualifiedTypeName.Length > 5) // length of "soap:"
2558 if (String.CompareOrdinal(qualifiedTypeName, 0, "soap:", 0, 5) == 0)
2560 // find comma starting from just past "soap:"
2561 return qualifiedTypeName.IndexOf(',', 5);
2564 return -1;
2567 [System.Security.SecurityCritical] // auto-generated
2568 internal static String InternalGetSoapTypeNameFromQualifiedTypeName(String xmlTypeName, String xmlTypeNamespace)
2570 // This must be the default encoding of the soap type (or the type wasn't
2571 // preloaded).
2572 String typeNamespace;
2573 String assemblyName;
2574 if (!SoapServices.DecodeXmlNamespaceForClrTypeNamespace(
2575 xmlTypeNamespace,
2576 out typeNamespace, out assemblyName))
2578 return null;
2581 String typeName;
2582 if ((typeNamespace != null) && (typeNamespace.Length > 0))
2583 typeName = typeNamespace + "." + xmlTypeName;
2584 else
2585 typeName = xmlTypeName;
2589 String fullTypeName = typeName + ", " + assemblyName;
2590 return fullTypeName;
2592 catch
2594 // We ignore errors and will just return null below since the type
2595 // isn't set.
2597 return null;
2600 [System.Security.SecurityCritical] // auto-generated
2601 internal static String InternalGetTypeNameFromQualifiedTypeName(String qualifiedTypeName)
2603 if (qualifiedTypeName == null)
2604 throw new ArgumentNullException("qualifiedTypeName");
2605 Contract.EndContractBlock();
2607 String decodedName = InternalGetClrTypeNameFromQualifiedTypeName(qualifiedTypeName);
2608 if (decodedName != null)
2610 return decodedName;
2612 int index = IsSoapType(qualifiedTypeName);
2613 if (index != -1)
2615 // This is a soap type name. We need to parse it and try to
2616 // find the actual type. Format is "soap:xmlTypeName, xmlTypeNamespace"
2618 String xmlTypeName = qualifiedTypeName.Substring(5, index - 5);
2619 // +2 is to skip the comma and following space
2620 String xmlTypeNamespace =
2621 qualifiedTypeName.Substring(index + 2, qualifiedTypeName.Length - (index + 2));
2623 decodedName = InternalGetSoapTypeNameFromQualifiedTypeName(xmlTypeName, xmlTypeNamespace);
2624 if (decodedName != null)
2626 return decodedName;
2629 //no prefix return same
2630 return qualifiedTypeName;
2634 // Retrieves type based on qualified type names. This does not do security checks
2635 // so don't expose this publicly (at least not directly). It returns null if the
2636 // type cannot be loaded.
2637 [System.Security.SecurityCritical] // auto-generated
2638 internal static RuntimeType InternalGetTypeFromQualifiedTypeName(String qualifiedTypeName, bool partialFallback)
2640 if (qualifiedTypeName == null)
2641 throw new ArgumentNullException("qualifiedTypeName");
2642 Contract.EndContractBlock();
2644 String decodedName = InternalGetClrTypeNameFromQualifiedTypeName(qualifiedTypeName);
2645 if (decodedName != null)
2647 return LoadClrTypeWithPartialBindFallback(decodedName, partialFallback);
2650 int index = IsSoapType(qualifiedTypeName);
2651 if (index != -1)
2653 // This is a soap type name. We need to parse it and try to
2654 // find the actual type. Format is "soap:xmlTypeName, xmlTypeNamespace"
2656 String xmlTypeName = qualifiedTypeName.Substring(5, index - 5);
2657 // +2 is to skip the comma and following space
2658 String xmlTypeNamespace =
2659 qualifiedTypeName.Substring(index + 2, qualifiedTypeName.Length - (index + 2));
2661 RuntimeType type = (RuntimeType)SoapServices.GetInteropTypeFromXmlType(xmlTypeName, xmlTypeNamespace);
2662 if (type != null)
2664 return type;
2666 decodedName = InternalGetSoapTypeNameFromQualifiedTypeName(xmlTypeName, xmlTypeNamespace);
2667 if (decodedName != null)
2669 return LoadClrTypeWithPartialBindFallback(decodedName, true);
2673 // There is no prefix, so assume this is a normal CLR type name.
2674 return LoadClrTypeWithPartialBindFallback(qualifiedTypeName, partialFallback);
2675 } // InternalGetTypeFromQualifiedTypeName
2677 [System.Security.SecurityCritical] // auto-generated
2678 internal static Type InternalGetTypeFromQualifiedTypeName(String qualifiedTypeName)
2680 return InternalGetTypeFromQualifiedTypeName(qualifiedTypeName, true);
2683 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
2684 private unsafe static RuntimeType LoadClrTypeWithPartialBindFallback(String typeName, bool partialFallback)
2686 // Try to load a type with fully qualified name if partialFallback is not requested
2687 if (!partialFallback)
2689 return (RuntimeType)Type.GetType(typeName, false);
2691 else
2693 // A hack
2694 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2695 return RuntimeTypeHandle.GetTypeByName(typeName, false, false, false, ref stackMark, true /* hack */);
2697 } // LoadClrTypeWithPartialBindFallback
2700 // end of Methods for mapping and resolving qualified type names
2705 // These are used by the profiling code to profile remoting.
2707 [System.Security.SecurityCritical] // auto-generated
2708 [ResourceExposure(ResourceScope.None)]
2709 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2710 internal static extern bool CORProfilerTrackRemoting();
2712 [System.Security.SecurityCritical] // auto-generated
2713 [ResourceExposure(ResourceScope.None)]
2714 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2715 internal static extern bool CORProfilerTrackRemotingCookie();
2717 [System.Security.SecurityCritical] // auto-generated
2718 [ResourceExposure(ResourceScope.None)]
2719 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2720 internal static extern bool CORProfilerTrackRemotingAsync();
2722 [System.Security.SecurityCritical] // auto-generated
2723 [ResourceExposure(ResourceScope.None)]
2724 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2725 internal static extern void CORProfilerRemotingClientSendingMessage(out Guid id, bool fIsAsync);
2727 [System.Security.SecurityCritical] // auto-generated
2728 [ResourceExposure(ResourceScope.None)]
2729 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2730 internal static extern void CORProfilerRemotingClientReceivingReply(Guid id, bool fIsAsync);
2732 [System.Security.SecurityCritical] // auto-generated
2733 [ResourceExposure(ResourceScope.None)]
2734 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2735 internal static extern void CORProfilerRemotingServerReceivingMessage(Guid id, bool fIsAsync);
2737 [System.Security.SecurityCritical] // auto-generated
2738 [ResourceExposure(ResourceScope.None)]
2739 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2740 internal static extern void CORProfilerRemotingServerSendingReply(out Guid id, bool fIsAsync);
2742 [System.Security.SecurityCritical] // auto-generated_required
2743 [System.Diagnostics.Conditional("REMOTING_PERF")]
2744 [Obsolete("Use of this method is not recommended. The LogRemotingStage existed for internal diagnostic purposes only.")]
2745 public static void LogRemotingStage(int stage) {}
2747 [System.Security.SecurityCritical] // auto-generated
2748 [ResourceExposure(ResourceScope.None)]
2749 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2750 internal static extern void ResetInterfaceCache(Object proxy);
2752 } // RemotingServices
2755 [System.Security.SecurityCritical] // auto-generated_required
2756 [System.Runtime.InteropServices.ComVisible(true)]
2757 public class InternalRemotingServices
2760 [System.Security.SecurityCritical] // auto-generated
2761 [System.Diagnostics.Conditional("_LOGGING")]
2762 public static void DebugOutChnl(String s)
2764 // BCLDebug.Trace("REMOTINGCHANNELS", "CHNL:" + s + "\n");
2765 Message.OutToUnmanagedDebugger("CHNL:"+s+"\n");
2766 // Console.WriteLine("CHNL:"+s+"\n");
2770 [System.Diagnostics.Conditional("_LOGGING")]
2771 public static void RemotingTrace(params Object[]messages)
2773 BCLDebug.Trace("REMOTINGCHANNELS",messages);
2777 [System.Diagnostics.Conditional("_DEBUG")]
2778 public static void RemotingAssert(bool condition, String message)
2780 Contract.Assert(condition, message);
2784 [System.Security.SecurityCritical] // auto-generated
2785 [CLSCompliant(false)]
2786 public static void SetServerIdentity(MethodCall m, Object srvID)
2788 IInternalMessage im = (IInternalMessage) m;
2789 im.ServerIdentityObject = (ServerIdentity)srvID;
2793 // access attribute cached on the reflection object
2794 internal static RemotingMethodCachedData GetReflectionCachedData(MethodBase mi)
2796 RuntimeMethodInfo rmi = null;
2797 RuntimeConstructorInfo rci = null;
2799 if ((rmi = mi as RuntimeMethodInfo) != null)
2801 return rmi.RemotingCache;
2803 else if ((rci = mi as RuntimeConstructorInfo) != null)
2805 return rci.RemotingCache;
2807 else
2808 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeReflectionObject"));
2811 internal static RemotingTypeCachedData GetReflectionCachedData(RuntimeType type)
2813 return type.RemotingCache;
2816 internal static RemotingCachedData GetReflectionCachedData(MemberInfo mi)
2818 MethodBase mb = null;
2819 RuntimeType rt = null;
2820 RuntimeFieldInfo rfi = null;
2821 SerializationFieldInfo sfi = null;
2823 if ((mb = mi as MethodBase) != null)
2824 return GetReflectionCachedData(mb);
2825 else if ((rt = mi as RuntimeType) != null)
2826 return GetReflectionCachedData(rt);
2827 else if ((rfi = mi as RuntimeFieldInfo) != null)
2828 return rfi.RemotingCache;
2829 else if ((sfi = mi as SerializationFieldInfo) != null)
2830 return sfi.RemotingCache;
2831 else
2832 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeReflectionObject"));
2835 internal static RemotingCachedData GetReflectionCachedData(RuntimeParameterInfo reflectionObject)
2837 return reflectionObject.RemotingCache;
2841 [System.Security.SecurityCritical] // auto-generated
2842 public static SoapAttribute GetCachedSoapAttribute(Object reflectionObject)
2844 MemberInfo mi = reflectionObject as MemberInfo;
2845 RuntimeParameterInfo parameter = reflectionObject as RuntimeParameterInfo;
2846 if (mi != null)
2847 return GetReflectionCachedData(mi).GetSoapAttribute();
2848 else if (parameter != null)
2849 return GetReflectionCachedData(parameter).GetSoapAttribute();
2850 else
2851 return null;
2852 } // GetCachedSoapAttribute
2854 } // InternalRemotingServices