// // System.Runtime.Remoting.ObjRef.cs // // Author: // Miguel de Icaza (miguel@ximian.com) // Dietmar Maurer (dietmar@ximian.com) // Lluis Sanchez Gual (lluis@ideary.com) // Patrik Torstensson // // (C) Ximian, Inc. http://www.ximian.com // // // Copyright (C) 2004 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Proxies; using System.Runtime.ConstrainedExecution; namespace System.Runtime.Remoting { [Serializable] [System.Runtime.InteropServices.ComVisible (true)] public class ObjRef : IObjectReference, ISerializable { IChannelInfo channel_info; string uri; IRemotingTypeInfo typeInfo; IEnvoyInfo envoyInfo; int flags; Type _serverType; static int MarshalledObjectRef = 1; static int WellKnowObjectRef = 2; public ObjRef () { // no idea why this needs to be public UpdateChannelInfo(); } internal ObjRef (string uri, IChannelInfo cinfo) { this.uri = uri; this.channel_info = cinfo; } internal ObjRef DeserializeInTheCurrentDomain (int domainId, byte[] tInfo) { string local_uri = string.Copy (this.uri); ChannelInfo cinfo = new ChannelInfo (new CrossAppDomainData (domainId)); ObjRef res = new ObjRef (local_uri, cinfo); IRemotingTypeInfo typeInfo = (IRemotingTypeInfo)CADSerializer.DeserializeObjectSafe (tInfo); res.typeInfo = typeInfo; return res; } internal byte[] SerializeType () { // FIXME: Assert self and typeinfo in same domain if (typeInfo == null) throw new Exception ("Attempt to serialize a null TypeInfo."); MemoryStream stm = CADSerializer.SerializeObject (typeInfo); return stm.GetBuffer (); } internal ObjRef (ObjRef o, bool unmarshalAsProxy) { channel_info = o.channel_info; uri = o.uri; typeInfo = o.typeInfo; envoyInfo = o.envoyInfo; flags = o.flags; if (unmarshalAsProxy) flags |= MarshalledObjectRef; } public ObjRef (MarshalByRefObject o, Type requestedType) { if (o == null) throw new ArgumentNullException ("o"); if (requestedType == null) throw new ArgumentNullException ("requestedType"); // The ObjRef can only be constructed if the given o // has already been marshalled using RemotingServices.Marshall uri = RemotingServices.GetObjectUri (o); typeInfo = new TypeInfo (requestedType); if (!requestedType.IsInstanceOfType (o)) throw new RemotingException ("The server object type cannot be cast to the requested type " + requestedType.FullName); UpdateChannelInfo(); } internal ObjRef (Type type, string url, object remoteChannelData) { uri = url; typeInfo = new TypeInfo(type); if (remoteChannelData != null) channel_info = new ChannelInfo (remoteChannelData); flags |= WellKnowObjectRef; } protected ObjRef (SerializationInfo info, StreamingContext context) { SerializationInfoEnumerator en = info.GetEnumerator(); // Info to serialize: uri, objrefFlags, typeInfo, envoyInfo, channelInfo bool marshalledValue = true; while (en.MoveNext ()) { switch (en.Name) { case "uri": uri = (string)en.Value; break; case "typeInfo": typeInfo = (IRemotingTypeInfo)en.Value; break; case "channelInfo": channel_info = (IChannelInfo)en.Value; break; case "envoyInfo": envoyInfo = (IEnvoyInfo)en.Value; break; case "fIsMarshalled": int status; Object o = en.Value; if (o is string) status = ((IConvertible) o).ToInt32(null); else status = (int) o; if (status == 0) marshalledValue = false; break; case "objrefFlags": flags = Convert.ToInt32 (en.Value); break; default: throw new NotSupportedException (); } } if (marshalledValue) flags |= MarshalledObjectRef; } internal bool IsPossibleToCAD () { // we should check if this obj ref belongs to a cross app context. // Return false. If not, serialization of this ObjRef will not work // on the target AD. return false; } internal bool IsReferenceToWellKnow { get { return (flags & WellKnowObjectRef) > 0; } } public virtual IChannelInfo ChannelInfo { [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)] get { return channel_info; } set { channel_info = value; } } public virtual IEnvoyInfo EnvoyInfo { get { return envoyInfo; } set { envoyInfo = value; } } public virtual IRemotingTypeInfo TypeInfo { get { return typeInfo; } set { typeInfo = value; } } public virtual string URI { get { return uri; } set { uri = value; } } public virtual void GetObjectData (SerializationInfo info, StreamingContext context) { info.SetType (GetType()); info.AddValue ("uri", uri); info.AddValue ("typeInfo", typeInfo, typeof (IRemotingTypeInfo)); info.AddValue ("envoyInfo", envoyInfo, typeof (IEnvoyInfo)); info.AddValue ("channelInfo", channel_info, typeof(IChannelInfo)); info.AddValue ("objrefFlags", flags); } public virtual object GetRealObject (StreamingContext context) { if ((flags & MarshalledObjectRef) > 0) return RemotingServices.Unmarshal (this); else return this; } public bool IsFromThisAppDomain () { Identity identity = RemotingServices.GetIdentityForUri (uri); if (identity == null) return false; // URI not registered in this domain return identity.IsFromThisAppDomain; } [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)] public bool IsFromThisProcess () { foreach (object data in channel_info.ChannelData) { if (data is CrossAppDomainData) { string refProcId = ((CrossAppDomainData)data).ProcessID; return (refProcId == RemotingConfiguration.ProcessId); } } return true; } internal void UpdateChannelInfo() { channel_info = new ChannelInfo (); } internal Type ServerType { get { if (_serverType == null) _serverType = Type.GetType (typeInfo.TypeName); return _serverType; } } internal void SetDomainID (int id) { } } }