2005-06-06 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / corlib / System.Runtime.Remoting / ObjRef.cs
1 //
2 // System.Runtime.Remoting.ObjRef.cs
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //   Dietmar Maurer (dietmar@ximian.com)
7 //   Lluis Sanchez Gual (lluis@ideary.com)
8 //   Patrik Torstensson
9 //
10 // (C) Ximian, Inc.  http://www.ximian.com
11 //
12
13 //
14 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
23 // 
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 // 
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 //
35
36 using System;
37 using System.Runtime.Serialization;
38 using System.Runtime.Remoting.Channels;
39 using System.Runtime.Remoting.Messaging;
40 using System.Runtime.Remoting.Proxies;
41
42 #if NET_2_0
43 using System.Runtime.ConstrainedExecution;
44 #endif
45
46 namespace System.Runtime.Remoting {
47
48         [Serializable]
49         public class ObjRef : IObjectReference, ISerializable 
50         {
51                 IChannelInfo channel_info;
52                 string uri;
53                 IRemotingTypeInfo typeInfo;
54                 IEnvoyInfo envoyInfo;
55                 int flags;
56                 Type _serverType;
57
58                 static int MarshalledObjectRef = 1;
59                 static int WellKnowObjectRef = 2;
60                 
61                 public ObjRef ()
62                 {
63                         // no idea why this needs to be public
64
65                         UpdateChannelInfo();
66                 }
67
68                 internal ObjRef (string typeName, string uri, IChannelInfo cinfo) 
69                 {
70                         this.uri = uri;
71                         channel_info = cinfo;
72                         typeInfo = new TypeInfo (Type.GetType (typeName));
73                 }
74
75                 internal ObjRef (ObjRef o, bool unmarshalAsProxy) {
76                         channel_info = o.channel_info;
77                         uri = o.uri;
78         
79                         typeInfo = o.typeInfo;
80                         envoyInfo = o.envoyInfo;
81                         flags = o.flags;
82                         if (unmarshalAsProxy) flags |= MarshalledObjectRef;
83                 }
84
85                 public ObjRef (MarshalByRefObject mbr, Type type)
86                 {
87                         if (mbr == null)
88                                 throw new ArgumentNullException ("mbr");
89                         
90                         if (type == null)
91                                 throw new ArgumentNullException ("type");
92
93                         // The ObjRef can only be constructed if the given mbr
94                         // has already been marshalled using RemotingServices.Marshall
95
96                         uri = RemotingServices.GetObjectUri(mbr);
97                         typeInfo = new TypeInfo(type);
98
99                         if (!type.IsInstanceOfType (mbr))
100                                 throw new RemotingException ("The server object type cannot be cast to the requested type " + type.FullName + ".");
101
102                         UpdateChannelInfo();
103                 }
104
105                 internal ObjRef (Type type, string url, object remoteChannelData)
106                 {
107                         uri = url;
108                         typeInfo = new TypeInfo(type);
109
110                         if (remoteChannelData != null)
111                                 channel_info = new ChannelInfo (remoteChannelData);
112
113                         flags |= WellKnowObjectRef;
114                 }
115
116                 protected ObjRef (SerializationInfo si, StreamingContext sc)
117                 {
118                         SerializationInfoEnumerator en = si.GetEnumerator();
119                         // Info to serialize: uri, objrefFlags, typeInfo, envoyInfo, channelInfo
120
121                         bool marshalledValue = true;
122
123                         while (en.MoveNext ()) {
124                                 switch (en.Name) {
125                                 case "uri":
126                                         uri = (string)en.Value;
127                                         break;
128                                 case "typeInfo":
129                                         typeInfo = (IRemotingTypeInfo)en.Value;
130                                         break;
131                                 case "channelInfo":
132                                         channel_info = (IChannelInfo)en.Value;
133                                         break;
134                                 case "envoyInfo":
135                                         envoyInfo = (IEnvoyInfo)en.Value;
136                                         break;
137                                 case "fIsMarshalled":
138                                         int status;
139                                         Object o = en.Value;
140                                         if (o is string)
141                                                 status = ((IConvertible) o).ToInt32(null);
142                                         else
143                                                 status = (int) o;
144
145                                         if (status == 0)
146                                                 marshalledValue = false;
147                                         break;
148                                 case "objrefFlags":
149                                         flags = Convert.ToInt32 (en.Value);
150                                         break;
151                                 default:
152                                         throw new NotSupportedException ();
153                                 }
154                         }
155                         if (marshalledValue) flags |= MarshalledObjectRef;
156                 }
157
158                 internal bool IsPossibleToCAD () 
159                 {
160                         // we should check if this obj ref belongs to a cross app context.
161
162                         // Return false. If not, serialization of this ObjRef will not work
163                         // on the target AD.
164                         return false;
165                 }
166
167                 internal bool IsReferenceToWellKnow
168                 {
169                         get { return (flags & WellKnowObjectRef) > 0; }
170                 }
171
172                 public virtual IChannelInfo ChannelInfo {
173 #if NET_2_0
174                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
175 #endif
176                         get {
177                                 return channel_info;
178                         }
179                         
180                         set {
181                                 channel_info = value;
182                         }
183                 }
184                 
185                 public virtual IEnvoyInfo EnvoyInfo {
186                         get {
187                                 return envoyInfo;
188                         }
189                         set {
190                                 envoyInfo = value;
191                         }
192                 }
193                 
194                 public virtual IRemotingTypeInfo TypeInfo {
195                         get {
196                                 return typeInfo;
197                         }
198                         set {
199                                 typeInfo = value;
200                         }
201                 }
202                 
203                 public virtual string URI {
204                         get {
205                                 return uri;
206                         }
207                         set {
208                                 uri = value;
209                         }
210                 }
211
212                 public virtual void GetObjectData (SerializationInfo si, StreamingContext sc)
213                 {
214                         si.SetType (GetType());
215                         si.AddValue ("uri", uri);
216                         si.AddValue ("typeInfo", typeInfo, typeof (IRemotingTypeInfo));
217                         si.AddValue ("envoyInfo", envoyInfo, typeof (IEnvoyInfo));
218                         si.AddValue ("channelInfo", channel_info, typeof(IChannelInfo));
219                         si.AddValue ("objrefFlags", flags);
220                 }
221
222                 public virtual object GetRealObject (StreamingContext sc)
223                 {
224                         if ((flags & MarshalledObjectRef) > 0)
225                                 return RemotingServices.Unmarshal (this);
226                         else
227                                 return this;
228                 }
229
230                 public bool IsFromThisAppDomain ()
231                 {
232                         Identity identity = RemotingServices.GetIdentityForUri (uri);
233                         if (identity == null) return false;             // URI not registered in this domain
234
235                         return identity.IsFromThisAppDomain;
236                 }
237
238 #if NET_2_0
239                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
240 #endif
241                 public bool IsFromThisProcess ()
242                 {
243                         foreach (object data in channel_info.ChannelData)
244                         {
245                                 if (data is CrossAppDomainData)
246                                 {
247                                         string refProcId = ((CrossAppDomainData)data).ProcessID;
248                                         return (refProcId == RemotingConfiguration.ProcessId);
249                                 }
250                         }
251                         
252                         return true;
253                 }
254
255                 internal void UpdateChannelInfo()
256                 {
257                         channel_info = new ChannelInfo ();
258                 }
259
260                 internal Type ServerType
261                 {
262                         get
263                         {
264                                 if (_serverType == null) _serverType = Type.GetType (typeInfo.TypeName);
265                                 return _serverType;
266                         }
267                 }
268         }
269 }