Merge pull request #1218 from AndreyAkinshin/master
[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.Collections.Generic;
35 using System.IO;
36 using System.Runtime.CompilerServices;
37 using System.Runtime.InteropServices;
38 using System.Security;
39 using System.Runtime.Serialization.Formatters.Binary;
40
41 using System.Runtime.Hosting;
42 using System.Security.Policy;
43
44 namespace System
45 {
46         [Serializable]
47         [ClassInterface (ClassInterfaceType.None)]
48         [ComVisible (true)]
49         [StructLayout (LayoutKind.Sequential)]
50 #if NET_2_1
51         public sealed class AppDomainSetup
52 #else
53         public sealed class AppDomainSetup : IAppDomainSetup
54 #endif
55         {
56                 string application_base;
57                 string application_name;
58                 string cache_path;
59                 string configuration_file;
60                 string dynamic_base;
61                 string license_file;
62                 string private_bin_path;
63                 string private_bin_path_probe;
64                 string shadow_copy_directories;
65                 string shadow_copy_files;
66                 bool publisher_policy;
67                 private bool path_changed;
68 #if MOBILE
69                 private int loader_optimization;
70 #else
71                 private LoaderOptimization loader_optimization;
72 #endif
73                 bool disallow_binding_redirects;
74                 bool disallow_code_downloads;
75
76 #if MOBILE
77                 object _activationArguments;
78                 object domain_initializer;
79                 object application_trust;
80 #else
81                 private ActivationArguments _activationArguments;
82                 AppDomainInitializer domain_initializer;
83                 [NonSerialized]
84                 ApplicationTrust application_trust;
85 #endif
86                 string [] domain_initializer_args;
87
88                 bool disallow_appbase_probe;
89                 byte [] configuration_bytes;
90
91                 byte [] serialized_non_primitives;
92
93                 public AppDomainSetup ()
94                 {
95                 }
96
97                 internal AppDomainSetup (AppDomainSetup setup)
98                 {
99                         application_base = setup.application_base;
100                         application_name = setup.application_name;
101                         cache_path = setup.cache_path;
102                         configuration_file = setup.configuration_file;
103                         dynamic_base = setup.dynamic_base;
104                         license_file = setup.license_file;
105                         private_bin_path = setup.private_bin_path;
106                         private_bin_path_probe = setup.private_bin_path_probe;
107                         shadow_copy_directories = setup.shadow_copy_directories;
108                         shadow_copy_files = setup.shadow_copy_files;
109                         publisher_policy = setup.publisher_policy;
110                         path_changed = setup.path_changed;
111                         loader_optimization = setup.loader_optimization;
112                         disallow_binding_redirects = setup.disallow_binding_redirects;
113                         disallow_code_downloads = setup.disallow_code_downloads;
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                 }
121
122                 public AppDomainSetup (ActivationArguments activationArguments)
123                 {
124                         _activationArguments = activationArguments;
125                 }
126
127                 public AppDomainSetup (ActivationContext activationContext)
128                 {
129                         _activationArguments = new ActivationArguments (activationContext);
130                 }
131
132                 static string GetAppBase (string appBase)
133                 {
134                         if (appBase == null)
135                                 return null;
136
137                         int len = appBase.Length;
138                         if (len >= 8 && appBase.ToLower ().StartsWith ("file://")) {
139                                 appBase = appBase.Substring (7);
140                                 if (Path.DirectorySeparatorChar != '/')
141                                         appBase = appBase.Replace ('/', Path.DirectorySeparatorChar);
142                                 if (Environment.IsRunningOnWindows) {
143                                         // Under Windows prepend "//" to indicate it's a local file
144                                         appBase = "//" + appBase;
145                                 }
146                         } else {
147                                 appBase = Path.GetFullPath (appBase);
148                         }
149
150                         return appBase;
151                 }
152
153                 public string ApplicationBase {
154                         get { return GetAppBase (application_base); }
155                         set { application_base = value; } 
156                 }
157
158                 public string ApplicationName {
159                         get {
160                                 return application_name;
161                         }
162                         set {
163                                 application_name = value;
164                         }
165                 }
166
167                 public string CachePath {
168                         get {
169                                 return cache_path;
170                         }
171                         set {
172                                 cache_path = value;
173                         }
174                 }
175
176                 public string ConfigurationFile {
177                         get {
178                                 if (configuration_file == null)
179                                         return null;
180                                 if (Path.IsPathRooted(configuration_file))
181                                         return configuration_file;
182                                 if (ApplicationBase == null)
183                                         throw new MemberAccessException("The ApplicationBase must be set before retrieving this property.");
184                                 return Path.Combine(ApplicationBase, configuration_file);
185                         }
186                         set {
187                                 configuration_file = value;
188                         }
189                 }
190
191                 public bool DisallowPublisherPolicy {
192                         get {
193                                 return publisher_policy;
194                         }
195                         set {
196                                 publisher_policy = value;
197                         }
198                 }
199
200                 public string DynamicBase {
201                         get {
202                                 if (dynamic_base == null)
203                                         return null;
204
205                                 if (Path.IsPathRooted (dynamic_base))
206                                         return dynamic_base;
207
208                                 if (ApplicationBase == null)
209                                         throw new MemberAccessException ("The ApplicationBase must be set before retrieving this property.");
210                                 
211                                 return Path.Combine (ApplicationBase, dynamic_base);
212                         }
213                         set {
214                                 if (application_name == null)
215                                         throw new MemberAccessException ("ApplicationName must be set before the DynamicBase can be set.");
216                                 uint id = (uint) application_name.GetHashCode ();
217                                 dynamic_base = Path.Combine (value, id.ToString("x"));
218                         }
219                 }
220
221                 public string LicenseFile {
222                         get {
223                                 return license_file;
224                         }
225                         set {
226                                 license_file = value;
227                         }
228                 }
229
230                 [MonoLimitation ("In Mono this is controlled by the --share-code flag")]
231                 public LoaderOptimization LoaderOptimization {
232                         get {
233                                 return (LoaderOptimization)loader_optimization;
234                         }
235                         set {
236 #if MOBILE
237                                 loader_optimization = (int)value;
238 #else
239                                 loader_optimization = value;
240 #endif
241                         }
242                 }
243
244                 public string PrivateBinPath {
245                         get {
246                                 return private_bin_path;
247                         }
248                         set {
249                                 private_bin_path = value;
250                                 path_changed = true;
251                         }
252                 }
253
254                 public string PrivateBinPathProbe {
255                         get {
256                                 return private_bin_path_probe;
257                         }
258                         set {
259                                 private_bin_path_probe = value;
260                                 path_changed = true;
261                         }
262                 }
263
264                 public string ShadowCopyDirectories {
265                         get {
266                                 return shadow_copy_directories;
267                         }
268                         set {
269                                 shadow_copy_directories = value;
270                         }
271                 }
272
273                 public string ShadowCopyFiles {
274                         get {
275                                 return shadow_copy_files;
276                         }
277                         set {
278                                 shadow_copy_files = value;
279                         }
280                 }
281
282                 public bool DisallowBindingRedirects {
283                         get {
284                                 return disallow_binding_redirects;
285                         }
286                         set {
287                                 disallow_binding_redirects = value;
288                         }
289                 }
290
291                 public bool DisallowCodeDownload {
292                         get {
293                                 return disallow_code_downloads;
294                         }
295                         set {
296                                 disallow_code_downloads = value;
297                         }
298                 }
299
300                 public string TargetFrameworkName { get; set; }
301
302                 public ActivationArguments ActivationArguments {
303                         get {
304                                 if (_activationArguments != null)
305                                         return (ActivationArguments)_activationArguments;
306                                 DeserializeNonPrimitives ();
307                                 return (ActivationArguments)_activationArguments;
308                         }
309                         set { _activationArguments = value; }
310                 }
311
312                 [MonoLimitation ("it needs to be invoked within the created domain")]
313                 public AppDomainInitializer AppDomainInitializer {
314                         get {
315                                 if (domain_initializer != null)
316                                         return (AppDomainInitializer)domain_initializer;
317                                 DeserializeNonPrimitives ();
318                                 return (AppDomainInitializer)domain_initializer;
319                         }
320                         set { domain_initializer = value; }
321                 }
322
323                 [MonoLimitation ("it needs to be used to invoke the initializer within the created domain")]
324                 public string [] AppDomainInitializerArguments {
325                         get { return domain_initializer_args; }
326                         set { domain_initializer_args = value; }
327                 }
328
329                 [MonoNotSupported ("This property exists but not considered.")]
330                 public ApplicationTrust ApplicationTrust {
331                         get {
332                                 if (application_trust != null)
333                                         return (ApplicationTrust)application_trust;
334                                 DeserializeNonPrimitives ();
335                                 if (application_trust == null)
336                                         application_trust = new ApplicationTrust ();
337                                 return (ApplicationTrust)application_trust;
338                         }
339                         set { application_trust = value; }
340                 }
341
342                 [MonoNotSupported ("This property exists but not considered.")]
343                 public bool DisallowApplicationBaseProbing {
344                         get { return disallow_appbase_probe; }
345                         set { disallow_appbase_probe = value; }
346                 }
347
348                 [MonoNotSupported ("This method exists but not considered.")]
349                 public byte [] GetConfigurationBytes ()
350                 {
351                         return configuration_bytes != null ? configuration_bytes.Clone () as byte [] : null;
352                 }
353
354                 [MonoNotSupported ("This method exists but not considered.")]
355                 public void SetConfigurationBytes (byte [] value)
356                 {
357                         configuration_bytes = value;
358                 }
359
360                 private void DeserializeNonPrimitives ()
361                 {
362                         lock (this) {
363                                 if (serialized_non_primitives == null)
364                                         return;
365
366                                 BinaryFormatter bf = new BinaryFormatter ();
367                                 MemoryStream ms = new MemoryStream (serialized_non_primitives);
368
369                                 object [] arr = (object []) bf.Deserialize (ms);
370
371                                 _activationArguments = (ActivationArguments) arr [0];
372                                 domain_initializer = (AppDomainInitializer) arr [1];
373                                 application_trust = (ApplicationTrust) arr [2];
374
375                                 serialized_non_primitives = null;
376                         }
377                 }
378
379                 internal void SerializeNonPrimitives ()
380                 {
381                         object [] arr = new object [3];
382
383                         arr [0] = _activationArguments;
384                         arr [1] = domain_initializer;
385                         arr [2] = application_trust;
386
387                         BinaryFormatter bf = new BinaryFormatter ();
388                         MemoryStream ms = new MemoryStream ();
389
390                         bf.Serialize (ms, arr);
391
392                         serialized_non_primitives = ms.ToArray ();
393                 }
394
395                 [MonoTODO ("not implemented, does not throw because it's used in testing moonlight")]
396                 public void SetCompatibilitySwitches (IEnumerable<string> switches)
397                 {
398                 }
399         }
400 }