2009-10-04 Mark Probst <mark.probst@gmail.com>
[mono.git] / mcs / class / corlib / System / AppDomainSetup.cs
1 //
2 // System.AppDomainSetup.cs
3 //
4 // Authors:
5 //      Dietmar Maurer (dietmar@ximian.com)
6 //      Sebastien Pouliot  <sebastien@ximian.com>
7 //
8 // (C) 2001 Ximian, Inc.  http://www.ximian.com
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
10 //
11 // Known Problems:
12 //      Fix serialization compatibility with MS.NET.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System.IO;
35 using System.Runtime.CompilerServices;
36 using System.Runtime.InteropServices;
37 using System.Security;
38 using System.Runtime.Serialization.Formatters.Binary;
39
40 #if NET_2_0 && !NET_2_1
41 using System.Runtime.Hosting;
42 using System.Security.Policy;
43 #endif
44
45 namespace System
46 {
47         [Serializable]
48         [ClassInterface (ClassInterfaceType.None)]
49 #if NET_2_0
50         [ComVisible (true)]
51 #endif
52 #if NET_2_1
53         public sealed class AppDomainSetup
54 #else
55         public sealed class AppDomainSetup : IAppDomainSetup
56 #endif
57         {
58                 string application_base;
59                 string application_name;
60                 string cache_path;
61                 string configuration_file;
62                 string dynamic_base;
63                 string license_file;
64                 string private_bin_path;
65                 string private_bin_path_probe;
66                 string shadow_copy_directories;
67                 string shadow_copy_files;
68                 bool publisher_policy;
69                 private bool path_changed;
70                 private LoaderOptimization loader_optimization;
71                 bool disallow_binding_redirects;
72                 bool disallow_code_downloads;
73
74 #if NET_2_0 && !NET_2_1
75                 private ActivationArguments _activationArguments;
76                 AppDomainInitializer domain_initializer;
77                 [NonSerialized]
78                 ApplicationTrust application_trust;
79                 string [] domain_initializer_args;
80 #else
81                 object _activationArguments;
82                 object domain_initializer; // always null
83                 [NonSerialized]
84                 object application_trust;  // dummy, always null
85                 object domain_initializer_args;
86 #endif
87                 bool disallow_appbase_probe;
88                 byte [] configuration_bytes;
89
90                 byte [] serialized_non_primitives;
91
92                 public AppDomainSetup ()
93                 {
94                 }
95
96                 internal AppDomainSetup (AppDomainSetup setup)
97                 {
98                         application_base = setup.application_base;
99                         application_name = setup.application_name;
100                         cache_path = setup.cache_path;
101                         configuration_file = setup.configuration_file;
102                         dynamic_base = setup.dynamic_base;
103                         license_file = setup.license_file;
104                         private_bin_path = setup.private_bin_path;
105                         private_bin_path_probe = setup.private_bin_path_probe;
106                         shadow_copy_directories = setup.shadow_copy_directories;
107                         shadow_copy_files = setup.shadow_copy_files;
108                         publisher_policy = setup.publisher_policy;
109                         path_changed = setup.path_changed;
110                         loader_optimization = setup.loader_optimization;
111                         disallow_binding_redirects = setup.disallow_binding_redirects;
112                         disallow_code_downloads = setup.disallow_code_downloads;
113 //#if NET_2_0
114                         _activationArguments = setup._activationArguments;
115                         domain_initializer = setup.domain_initializer;
116                         application_trust = setup.application_trust;
117                         domain_initializer_args = setup.domain_initializer_args;
118                         disallow_appbase_probe = setup.disallow_appbase_probe;
119                         configuration_bytes = setup.configuration_bytes;
120 //#endif
121                 }
122
123 #if NET_2_0 && !NET_2_1
124                 public AppDomainSetup (ActivationArguments activationArguments)
125                 {
126                         _activationArguments = activationArguments;
127                 }
128
129                 public AppDomainSetup (ActivationContext activationContext)
130                 {
131                         _activationArguments = new ActivationArguments (activationContext);
132                 }
133 #endif
134
135                 static string GetAppBase (string appBase)
136                 {
137                         if (appBase == null)
138                                 return null;
139
140                         int len = appBase.Length;
141                         if (len >= 8 && appBase.ToLower ().StartsWith ("file://")) {
142                                 appBase = appBase.Substring (7);
143                                 if (Path.DirectorySeparatorChar != '/')
144                                         appBase = appBase.Replace ('/', Path.DirectorySeparatorChar);
145                                 if (Environment.IsRunningOnWindows) {
146                                         // Under Windows prepend "//" to indicate it's a local file
147                                         appBase = "//" + appBase;
148                                 }
149 #if NET_2_0
150                         } else {
151 #else
152                         // under 1.x the ":" gets a special treatment - but it doesn't make sense outside Windows
153                         } else if (!Environment.IsRunningOnWindows || (appBase.IndexOf (':') == -1)) {
154 #endif
155                                 appBase = Path.GetFullPath (appBase);
156                         }
157
158                         return appBase;
159                 }
160
161                 public string ApplicationBase {
162                         get { return GetAppBase (application_base); }
163                         set { application_base = value; } 
164                 }
165
166                 public string ApplicationName {
167                         get {
168                                 return application_name;
169                         }
170                         set {
171                                 application_name = value;
172                         }
173                 }
174 #if !NET_2_1
175                 public string CachePath {
176                         get {
177                                 return cache_path;
178                         }
179                         set {
180                                 cache_path = value;
181                         }
182                 }
183
184                 public string ConfigurationFile {
185                         get {
186                                 if (configuration_file == null)
187                                         return null;
188                                 if (Path.IsPathRooted(configuration_file))
189                                         return configuration_file;
190                                 if (ApplicationBase == null)
191                                         throw new MemberAccessException("The ApplicationBase must be set before retrieving this property.");
192                                 return Path.Combine(ApplicationBase, configuration_file);
193                         }
194                         set {
195                                 configuration_file = value;
196                         }
197                 }
198
199                 public bool DisallowPublisherPolicy {
200                         get {
201                                 return publisher_policy;
202                         }
203                         set {
204                                 publisher_policy = value;
205                         }
206                 }
207
208                 public string DynamicBase {
209                         get {
210                                 if (dynamic_base == null)
211                                         return null;
212
213                                 if (Path.IsPathRooted (dynamic_base))
214                                         return dynamic_base;
215
216                                 if (ApplicationBase == null)
217                                         throw new MemberAccessException ("The ApplicationBase must be set before retrieving this property.");
218                                 
219                                 return Path.Combine (ApplicationBase, dynamic_base);
220                         }
221                         set {
222                                 if (application_name == null)
223                                         throw new MemberAccessException ("ApplicationName must be set before the DynamicBase can be set.");
224                                 uint id = (uint) application_name.GetHashCode ();
225                                 dynamic_base = Path.Combine (value, id.ToString("x"));
226                         }
227                 }
228
229                 public string LicenseFile {
230                         get {
231                                 return license_file;
232                         }
233                         set {
234                                 license_file = value;
235                         }
236                 }
237 #endif
238                 [MonoLimitation ("In Mono this is controlled by the --share-code flag")]
239                 public LoaderOptimization LoaderOptimization {
240                         get {
241                                 return loader_optimization;
242                         }
243                         set {
244                                 loader_optimization = value;
245                         }
246                 }
247 #if !NET_2_1
248                 public string PrivateBinPath {
249                         get {
250                                 return private_bin_path;
251                         }
252                         set {
253                                 private_bin_path = value;
254                                 path_changed = true;
255                         }
256                 }
257
258                 public string PrivateBinPathProbe {
259                         get {
260                                 return private_bin_path_probe;
261                         }
262                         set {
263                                 private_bin_path_probe = value;
264                                 path_changed = true;
265                         }
266                 }
267
268                 public string ShadowCopyDirectories {
269                         get {
270                                 return shadow_copy_directories;
271                         }
272                         set {
273                                 shadow_copy_directories = value;
274                         }
275                 }
276
277                 public string ShadowCopyFiles {
278                         get {
279                                 return shadow_copy_files;
280                         }
281                         set {
282                                 shadow_copy_files = value;
283                         }
284                 }
285
286 #if NET_1_1
287                 public bool DisallowBindingRedirects {
288                         get {
289                                 return disallow_binding_redirects;
290                         }
291                         set {
292                                 disallow_binding_redirects = value;
293                         }
294                 }
295
296                 public bool DisallowCodeDownload {
297                         get {
298                                 return disallow_code_downloads;
299                         }
300                         set {
301                                 disallow_code_downloads = value;
302                         }
303                 }
304 #endif
305
306 #if NET_2_0
307                 public ActivationArguments ActivationArguments {
308                         get {
309                                 if (_activationArguments != null)
310                                         return _activationArguments;
311                                 DeserializeNonPrimitives ();
312                                 return _activationArguments;
313                         }
314                         set { _activationArguments = value; }
315                 }
316
317                 [MonoLimitation ("it needs to be invoked within the created domain")]
318                 public AppDomainInitializer AppDomainInitializer {
319                         get {
320                                 if (domain_initializer != null)
321                                         return domain_initializer;
322                                 DeserializeNonPrimitives ();
323                                 return domain_initializer;
324                         }
325                         set { domain_initializer = value; }
326                 }
327
328                 [MonoLimitation ("it needs to be used to invoke the initializer within the created domain")]
329                 public string [] AppDomainInitializerArguments {
330                         get { return domain_initializer_args; }
331                         set { domain_initializer_args = value; }
332                 }
333
334                 [MonoNotSupported ("This property exists but not considered.")]
335                 public ApplicationTrust ApplicationTrust {
336                         get {
337                                 if (application_trust != null)
338                                         return application_trust;
339                                 DeserializeNonPrimitives ();
340                                 if (application_trust == null)
341                                         application_trust = new ApplicationTrust ();
342                                 return application_trust;
343                         }
344                         set { application_trust = value; }
345                 }
346
347                 [MonoNotSupported ("This property exists but not considered.")]
348                 public bool DisallowApplicationBaseProbing {
349                         get { return disallow_appbase_probe; }
350                         set { disallow_appbase_probe = value; }
351                 }
352
353                 [MonoNotSupported ("This method exists but not considered.")]
354                 public byte [] GetConfigurationBytes ()
355                 {
356                         return configuration_bytes != null ? configuration_bytes.Clone () as byte [] : null;
357                 }
358
359                 [MonoNotSupported ("This method exists but not considered.")]
360                 public void SetConfigurationBytes (byte [] value)
361                 {
362                         configuration_bytes = value;
363                 }
364 #endif
365
366                 private void DeserializeNonPrimitives ()
367                 {
368 #if NET_2_0
369                         lock (this) {
370                                 if (serialized_non_primitives == null)
371                                         return;
372
373                                 BinaryFormatter bf = new BinaryFormatter ();
374                                 MemoryStream ms = new MemoryStream (serialized_non_primitives);
375
376                                 object [] arr = (object []) bf.Deserialize (ms);
377
378                                 _activationArguments = (ActivationArguments) arr [0];
379                                 domain_initializer = (AppDomainInitializer) arr [1];
380                                 application_trust = (ApplicationTrust) arr [2];
381
382                                 serialized_non_primitives = null;
383                         }
384 #endif
385                 }
386
387                 internal void SerializeNonPrimitives ()
388                 {
389 #if NET_2_0
390                         object [] arr = new object [3];
391
392                         arr [0] = _activationArguments;
393                         arr [1] = domain_initializer;
394                         arr [2] = application_trust;
395
396                         BinaryFormatter bf = new BinaryFormatter ();
397                         MemoryStream ms = new MemoryStream ();
398
399                         bf.Serialize (ms, arr);
400
401                         serialized_non_primitives = ms.ToArray ();
402 #endif
403                 }
404 #endif // !NET_2_1
405         }
406 }