3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // File: RemotingServices.cs
9 // <OWNER>Microsoft</OWNER>
11 // Author(s): <EMAIL>Gopal Kakivaya (GopalK)</EMAIL>
13 // Purpose: Defines various remoting related services such as
14 // marshal, unmarshal, connect, wrap, unwrap etc.
17 namespace System
.Runtime
.Remoting
{
20 using System
.Collections
;
21 using System
.Runtime
.Serialization
;
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
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.
86 [System
.Security
.SecuritySafeCritical
] // auto-generated
87 public static bool IsObjectOutOfContext(Object tp
)
89 if (!IsTransparentProxy(tp
))
94 RealProxy rp
= GetRealProxy(tp
);
95 Identity id
= rp
.IdentityObject
;
96 ServerIdentity serverID
= id
as ServerIdentity
;
97 if ((null == serverID
) || !(rp
is RemotingProxy
))
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
;
123 bool bIsClientProxy
= false;
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).
131 if (!(id
is ServerIdentity
))
132 bIsClientProxy
= true;
135 return bIsClientProxy
;
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
))
150 RealProxy rp
= GetRealProxy(tp
);
151 Identity id
= rp
.IdentityObject
;
152 if (id
is ServerIdentity
)
158 ObjRef objRef
= id
.ObjectRef
;
159 if (objRef
!= null && objRef
.IsFromThisProcess())
168 // assume out of process
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(
194 RuntimeType typeToProxy
,
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(
211 RuntimeType rTypeToProxy
= typeToProxy
as RuntimeType
;
212 if (rTypeToProxy
== null)
213 throw new ArgumentException(
215 CultureInfo
.CurrentCulture
, Environment
.GetResourceString(
216 "Argument_WrongType"),
221 return CreateTransparentProxy(
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(
250 RuntimeType rObjectType
= objectType
as RuntimeType
;
251 if (rObjectType
== null)
252 throw new ArgumentException(
254 CultureInfo
.CurrentCulture
, Environment
.GetResourceString(
255 "Argument_WrongType"),
259 return AllocateUninitializedObject(
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(
278 RuntimeType rObjectType
= objectType
as RuntimeType
;
279 if (rObjectType
== null)
280 throw new ArgumentException(
282 CultureInfo
.CurrentCulture
, Environment
.GetResourceString(
283 "Argument_WrongType"),
287 return AllocateInitializedObject(
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
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;
324 Monitor
.Exit(configLock
);
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
)
353 } // GetSessionIdForMessage
355 [System
.Security
.SecuritySafeCritical
] // auto-generated
356 public static Object
GetLifetimeService(MarshalByRefObject obj
)
360 return obj
.GetLifetimeService();
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.
376 Identity id
= MarshalByRefObject
.GetIdentity(obj
, out fServer
);
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;
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"));
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
);
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"));
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");
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
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
);
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
;
568 // Ensure that the lease is started soon as the object is
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
576 Lease lease
= idObj
.Lease
;
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
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();
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
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
;
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
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
;
639 ILease lease
= idObj
.Lease
;
642 lease
= (ILease
)Obj
.GetLifetimeService();
646 lease
.Renew(lease
.RenewOnCallTime
);
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.
659 TrackingServices
.MarshaledObject(Obj
, objectRef
);
663 // Gets or generates the identity if one is not present and then returns
665 [System
.Security
.SecurityCritical
] // auto-generated
666 private static Identity
GetOrCreateIdentity(
667 MarshalByRefObject Obj
,
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'.
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
;
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
698 idObj
= IdentityHolder
.FindOrCreateServerIdentity(
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
;
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");
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
731 idObj
= IdentityHolder
.FindOrCreateServerIdentity(
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(
742 throw new RemotingException(
743 Environment
.GetResourceString(
744 "Remoting_URIExists"));
747 // We create a unique ID for an object and never
749 Contract
.Assert(srvID
== idObj
, "Bad ID Table state!");
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");
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
786 // The object may have an ID if it was marshaled but its lease
789 ServerIdentity idTmp
=
790 (ServerIdentity
) MarshalByRefObject
.GetIdentity(Obj
);
795 idObj
= IdentityHolder
.FindOrCreateServerIdentity(
800 // If the object had an ID to begin with that is the one
801 // we must have set in the table.
803 Contract
.Assert(idTmp
==null || idTmp
== idObj
, "Bad ID Table state!");
810 [System
.Security
.SecurityCritical
] // auto-generated_required
811 public static void GetObjectData(Object obj
, SerializationInfo info
, StreamingContext context
)
815 throw new ArgumentNullException("obj");
819 throw new ArgumentNullException("info");
821 Contract
.EndContractBlock();
823 ObjRef or
= RemotingServices
.MarshalInternal(
824 (MarshalByRefObject
)obj
,
828 or
.GetObjectData(info
, context
);
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
)
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.
881 Identity idrem
= MarshalByRefObject
.GetIdentity(obj
, out fServer
);
883 // remove the identity entry for this object (if it exists)
884 bool fDisconnect
= false;
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
);
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
+
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
;
930 envoyChain
= id
.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
;
951 objRef
= id
.ObjectRef
;
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");
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
);
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(
1003 CultureInfo
.CurrentCulture
, Environment
.GetResourceString(
1004 "Remoting_Connect_CantCreateChannelSink"),
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"));
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
;
1023 && objectURI
.StartsWith(RemotingConfigHandler
.ApplicationName
, StringComparison
.Ordinal
))
1025 return srvId
.ServerObject
;
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.
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 ");
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;
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
);
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(
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
1098 //**********************************************************
1099 // Get the proxy represented by the identity object
1100 proxy
= GetOrCreateProxy(idObj
, proxy
, true);
1103 GetRealProxy(proxy
).Wrap();
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");
1128 Message
.DebugOut("Leaving Wrap with passed in object\n");
1130 // Default return value is the object itself
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)
1144 int index
= fullUri
.LastIndexOf('/');
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(
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(
1186 CultureInfo
.CurrentCulture
, Environment
.GetResourceString(
1187 "Argument_BadObjRef"),
1191 // If it is a well known objectRef we need to just connect to
1192 // the URL inside the objectRef.
1193 if (objectRef
.IsWellKnown())
1196 typeof(System
.MarshalByRefObject
),
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
);
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");
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");
1255 throw new ArgumentException(
1257 CultureInfo
.CurrentCulture
, Environment
.GetResourceString(
1258 "Remoting_BadInternalState_ProxySameAppDomain")));
1260 obj
= serverID
.TPOrObject
;
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
,
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");
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
);
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())
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
);
1316 Message
.DebugOut("RemotingService::InternalUnmarshl OUT \n");
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
1333 // Get the type of the server object
1335 ServerIdentity serverID
= idObj
as ServerIdentity
;
1336 if (null != serverID
)
1338 serverType
= serverID
.ServerType
; // ServerObject.GetType();
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.
1360 if (((serverTypeInfo
is TypeInfo
) && !fRefine
) ||
1361 (serverTypeInfo
== null))
1363 serverType
= typeof(System
.MarshalByRefObject
);
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
);
1379 serverType
= assem
.GetType(typeNamespace
, false, false);
1386 if (null == serverType
)
1388 throw new RemotingException(
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);
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).
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
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
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
;
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.
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(
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");
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
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
,
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
,
1510 (null == srvID
? null :
1511 srvID
.ServerContext
));
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
;
1538 private static bool AreChannelDataElementsNull(Object
[] channelData
)
1540 foreach(Object o
in channelData
)
1550 [System
.Security
.SecurityCritical
] // auto-generated
1551 internal static void CreateEnvoyAndChannelSinks(
1552 MarshalByRefObject tpOrObject
,
1554 out IMessageSink chnlSink
,
1555 out IMessageSink envoySink
)
1558 Message
.DebugOut("Creating envoy and channel sinks \n");
1560 ((null != tpOrObject
) || (null != objectRef
)),
1561 "((null != tpOrObject) || (null != objectRef)");
1563 // Set the out parameters
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
);
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
)
1593 // if chnkSink is still null, try to find a channel that can service
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
)
1614 if (null == chnlSink
)
1616 // We don't have a sink
1617 foreach (Object data
in channelData
)
1621 RemotingConfigHandler
.FindDelayLoadChannelForCreateMessageSink(
1622 null, data
, out objectURI
);
1623 if (null != chnlSink
)
1631 // Extract the envoy sinks from the objectRef
1632 if ((null != objectRef
.EnvoyInfo
) &&
1633 (null != objectRef
.EnvoyInfo
.EnvoySinks
))
1635 envoySink
= objectRef
.EnvoyInfo
.EnvoySinks
;
1639 envoySink
= EnvoyTerminatorSink
.MessageSink
;
1644 [System
.Security
.SecurityCritical
] // auto-generated
1645 internal static String
CreateEnvoyAndChannelSinks(String url
,
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
;
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
)
1677 RemotingConfigHandler
.FindDelayLoadChannelForCreateMessageSink(
1678 url
, data
, out 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
);
1711 throw new RemotingException(
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
))
1739 // We do not allow casting to non-interface types that do not extend
1740 // from System.MarshalByRefObject
1741 if (!castType
.IsInterface
&& !castType
.IsMarshalByRef
)
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
1750 if (castType
!= typeof(IObjectReference
))
1752 IRemotingTypeInfo typeInfo
= rp
as IRemotingTypeInfo
;
1753 if(null != typeInfo
)
1755 fCastOK
= typeInfo
.CanCastTo(castType
, rp
.GetTransparentProxy());
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
;
1764 ObjRef objRef
= id
.ObjectRef
;
1767 typeInfo
= objRef
.TypeInfo
;
1768 if (typeInfo
!= null)
1770 fCastOK
= typeInfo
.CanCastTo(castType
, rp
.GetTransparentProxy());
1777 Message
.DebugOut("CheckCast returning " + fCastOK
);
1781 [System
.Security
.SecurityCritical
] // auto-generated
1782 internal static bool ProxyCheckCast(RealProxy rp
, RuntimeType castType
)
1784 return CheckCast(rp
, castType
);
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.
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
);
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
,
1844 ServerIdentity si
= (ServerIdentity
)MarshalByRefObject
.GetIdentity(Thread
.CurrentContext
.AppDomain
);
1846 objref
.SetServerIdentity(si
.GetHandle());
1847 objref
.SetDomainID(AppDomain
.CurrentDomain
.GetId());
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
);
1877 [System
.Security
.SecurityCritical
] // auto-generated
1878 internal static MethodBase
InternalGetMethodBaseFromMethodMessage(IMethodMessage msg
)
1885 Type t
= RemotingServices
.InternalGetTypeFromQualifiedTypeName(msg
.TypeName
);
1888 throw new RemotingException(
1890 CultureInfo
.CurrentCulture
, Environment
.GetResourceString(
1891 "Remoting_BadType"),
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
;
1928 ci
= t
.GetConstructors();
1930 ci
= rt
.GetConstructors();
1934 // There is more than one constructor defined but
1935 // we do not have a signature to differentiate between
1937 throw new AmbiguousMatchException(
1938 Environment
.GetResourceString(
1939 "Remoting_AmbiguousCTOR"));
1945 BCLDebug
.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with non-null sig ", msg
.MethodName
, " ", signature
.Length
);
1946 RuntimeType rt
= t
as RuntimeType
;
1948 mb
= t
.GetConstructor(signature
);
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
;
1962 mb
= t
.GetMethod(msg
.MethodName
, RemotingServices
.LookupAll
);
1964 mb
= rt
.GetMethod(msg
.MethodName
, RemotingServices
.LookupAll
);
1968 BCLDebug
.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with non-null sig ", msg
.MethodName
, " ", signature
.Length
);
1969 RuntimeType rt
= t
as RuntimeType
;
1971 mb
= t
.GetMethod(msg
.MethodName
, RemotingServices
.LookupAll
, null, signature
, null);
1973 mb
= rt
.GetMethod(msg
.MethodName
, RemotingServices
.LookupAll
, null, CallingConventions
.Any
, signature
, null);
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)
2018 typeof(MarshalByRefObject
).GetMethod(
2019 InvokeMemberName
, RemotingServices
.LookupAll
);
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
)
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
)
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
)
2067 endParameters
.Add(param
);
2069 if (param
.ParameterType
.IsByRef
)
2071 beginParameters
.Add(param
);
2072 endParameters
.Add(param
);
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
))
2102 if (mi
.Name
.Equals(endName
) &&
2103 (mi
.ReturnType
== endReturnType
) &&
2104 CompareParameterList(endParameters
, parameterList
))
2110 if ((beginMethod
!= null) && (endMethod
!= null))
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
)
2128 foreach (Object obj
in params1
)
2130 ParameterInfo param
= params2
[co
];
2132 ParameterInfo pi
= obj
as ParameterInfo
;
2135 if ((pi
.ParameterType
!= param
.ParameterType
) ||
2136 (pi
.IsIn
!= param
.IsIn
) ||
2137 (pi
.IsOut
!= param
.IsOut
))
2143 if (((Type
)obj
!= param
.ParameterType
) && param
.IsIn
)
2149 } // CompareParameterList
2152 [System
.Security
.SecurityCritical
] // auto-generated_required
2153 public static Type
GetServerTypeForUri(String URI
)
2155 Type svrType
= null;
2159 ServerIdentity srvID
= (ServerIdentity
)IdentityHolder
.ResolveIdentity(URI
);
2163 // Check if this a well-known object which needs to be faulted in
2164 svrType
= RemotingConfigHandler
.GetServerTypeForUri(URI
);
2168 svrType
= srvID
.ServerType
;
2176 // This method is called after an appdomain is unloaded from the
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
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
2199 [System
.Security
.SecurityCritical
] // auto-generated
2200 internal static IntPtr
GetServerContextForProxy(Object tp
)
2202 ObjRef objRef
= null;
2205 return GetServerContextForProxy(
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
,
2234 GetServerContextForProxy(
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
;
2254 bSameDomain
= false;
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
;
2266 ServerIdentity serverID
= id
as ServerIdentity
;
2267 if (null != serverID
)
2269 // We are in the app domain of the server
2271 contextId
= serverID
.ServerContext
.InternalContextID
;
2272 domainId
= Thread
.GetDomain().GetId();
2276 // Server is from another app domain
2277 // (possibly from another process)
2278 objRef
= id
.ObjectRef
;
2281 contextId
= objRef
.GetServerContext(out domainId
);
2285 // Proxy does not have an associated ObjRef
2290 //Contract.Assert(false, "Found proxy without an objref");
2291 contextId
= IntPtr
.Zero
;
2297 // This was probably a custom proxy other than RemotingProxy
2299 !(rp
is RemotingProxy
),
2300 "!(rp is RemotingProxy)");
2302 contextId
= Context
.DefaultContext
.InternalContextID
;
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 ...
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
;
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
;
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
);
2370 [System
.Security
.SecurityCritical
] // auto-generated
2371 internal static byte[] MarshalToBuffer(Object o
, bool 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)
2390 MarshalByRefObject mbro
= o
as MarshalByRefObject
;
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)
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
2437 if (ChannelServices
.RegisteredChannels
.Length
== 0)
2439 // the object uses the default Remoting proxy but there are no channels registered
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)
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 */);
2462 [System
.Security
.SecurityCritical
] // auto-generated_required
2463 public static IMethodReturnMessage
ExecuteMessage(MarshalByRefObject target
,
2464 IMethodCallMessage reqMsg
)
2466 // Argument validation
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
);
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
)
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
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
;
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);
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
2572 String typeNamespace
;
2573 String assemblyName
;
2574 if (!SoapServices
.DecodeXmlNamespaceForClrTypeNamespace(
2576 out typeNamespace
, out assemblyName
))
2582 if ((typeNamespace
!= null) && (typeNamespace
.Length
> 0))
2583 typeName
= typeNamespace
+ "." + xmlTypeName
;
2585 typeName
= xmlTypeName
;
2589 String fullTypeName
= typeName
+ ", " + assemblyName
;
2590 return fullTypeName
;
2594 // We ignore errors and will just return null below since the type
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)
2612 int index
= IsSoapType(qualifiedTypeName
);
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)
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
);
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
);
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);
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
;
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
;
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
;
2847 return GetReflectionCachedData(mi
).GetSoapAttribute();
2848 else if (parameter
!= null)
2849 return GetReflectionCachedData(parameter
).GetSoapAttribute();
2852 } // GetCachedSoapAttribute
2854 } // InternalRemotingServices