2007-10-25 Lluis Sanchez Gual <lluis@novell.com>
[mono.git] / mcs / class / corlib / System / AppDomain.cs
1 //
2 // System.AppDomain.cs
3 //
4 // Authors:
5 //   Paolo Molaro (lupus@ximian.com)
6 //   Dietmar Maurer (dietmar@ximian.com)
7 //   Miguel de Icaza (miguel@ximian.com)
8 //   Gonzalo Paniagua (gonzalo@ximian.com)
9 //   Patrik Torstensson
10 //   Sebastien Pouliot (sebastien@ximian.com)
11 //
12 // (C) 2001, 2002 Ximian, Inc.  http://www.ximian.com
13 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 using System.Collections;
36 using System.Globalization;
37 using System.IO;
38 using System.Reflection;
39 using System.Reflection.Emit;
40 using System.Threading;
41 using System.Runtime.CompilerServices;
42 using System.Runtime.InteropServices;
43 using System.Runtime.Remoting;
44 using System.Runtime.Remoting.Contexts;
45 using System.Runtime.Remoting.Channels;
46 using System.Runtime.Remoting.Messaging;
47 using System.Security;
48 using System.Security.Permissions;
49 using System.Security.Policy;
50 using System.Security.Principal;
51 using System.Configuration.Assemblies;
52
53 #if NET_2_0
54 using System.Collections.Generic;
55 using System.Runtime.ConstrainedExecution;
56 #endif
57
58 namespace System {
59
60 #if NET_2_0
61         [ComVisible (true)]
62 #endif
63         [ClassInterface(ClassInterfaceType.None)]
64         public sealed class AppDomain : MarshalByRefObject , _AppDomain , IEvidenceFactory
65         {
66                 IntPtr _mono_app_domain;
67                 static string _process_guid;
68
69                 [ThreadStatic]
70                 static Hashtable type_resolve_in_progress;
71
72                 [ThreadStatic]
73                 static Hashtable assembly_resolve_in_progress;
74
75                 // CAS
76                 private Evidence _evidence;
77                 private PermissionSet _granted;
78
79                 // non-CAS
80                 private PrincipalPolicy _principalPolicy;
81
82                 [ThreadStatic]
83                 private static IPrincipal _principal;
84                 
85                 static AppDomain default_domain;
86
87                 private AppDomain ()
88                 {
89                 }
90
91                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
92                 private extern AppDomainSetup getSetup ();
93
94                 AppDomainSetup SetupInformationNoCopy {
95                         get { return getSetup (); }
96                 }
97
98                 public AppDomainSetup SetupInformation {
99                         get {
100                                 AppDomainSetup setup = getSetup ();
101                                 return new AppDomainSetup (setup);
102                         }
103                 }
104
105                 public string BaseDirectory {
106                         get {
107                                 string path = SetupInformationNoCopy.ApplicationBase;
108                                 if (SecurityManager.SecurityEnabled && (path != null) && (path.Length > 0)) {
109                                         // we cannot divulge local file informations
110                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, path).Demand ();
111                                 }
112                                 return path;
113                         }
114                 }
115
116                 public string RelativeSearchPath {
117                         get {
118                                 string path = SetupInformationNoCopy.PrivateBinPath;
119                                 if (SecurityManager.SecurityEnabled && (path != null) && (path.Length > 0)) {
120                                         // we cannot divulge local file informations
121                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, path).Demand ();
122                                 }
123                                 return path;
124                         }
125                 }
126
127                 public string DynamicDirectory {
128                         get {
129                                 AppDomainSetup setup = SetupInformationNoCopy;
130                                 if (setup.DynamicBase == null)
131                                         return null;
132
133                                 string path = Path.Combine (setup.DynamicBase, setup.ApplicationName);
134                                 if (SecurityManager.SecurityEnabled && (path != null) && (path.Length > 0)) {
135                                         // we cannot divulge local file informations
136                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, path).Demand ();
137                                 }
138                                 return path;
139                         }
140                 }
141
142                 public bool ShadowCopyFiles {
143                         get {
144                                 return (SetupInformationNoCopy.ShadowCopyFiles == "true");
145                         }
146                 }
147
148                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
149                 private extern string getFriendlyName ();
150
151                 public string FriendlyName {
152                         get {
153                                 return getFriendlyName ();
154                         }
155                 }
156
157                 public Evidence Evidence {
158                         get {
159                                 // if the host (runtime) hasn't provided it's own evidence...
160                                 if (_evidence == null) {
161                                         // ... we will provide our own
162                                         lock (this) {
163                                                 // the executed assembly from the "default" appdomain
164                                                 // or null if we're not in the default appdomain
165                                                 Assembly a = Assembly.GetEntryAssembly ();
166                                                 if (a == null)
167                                                         _evidence = AppDomain.DefaultDomain.Evidence;
168                                                 else
169                                                         _evidence = Evidence.GetDefaultHostEvidence (a);
170                                         }
171                                 }
172                                 return new Evidence (_evidence);        // return a copy
173                         }
174                 }
175
176                 internal IPrincipal DefaultPrincipal {
177                         get {
178                                 if (_principal == null) {
179                                         switch (_principalPolicy) {
180                                                 case PrincipalPolicy.UnauthenticatedPrincipal:
181                                                         _principal = new GenericPrincipal (
182                                                                 new GenericIdentity (String.Empty, String.Empty), null);
183                                                         break;
184                                                 case PrincipalPolicy.WindowsPrincipal:
185                                                         _principal = new WindowsPrincipal (WindowsIdentity.GetCurrent ());
186                                                         break;
187                                         }
188                                 }
189                                 return _principal; 
190                         }
191                 }
192
193                 // for AppDomain there is only an allowed (i.e. granted) set
194                 // http://msdn.microsoft.com/library/en-us/cpguide/html/cpcondetermininggrantedpermissions.asp
195                 internal PermissionSet GrantedPermissionSet {
196                         get { return _granted; }
197                 }
198
199                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
200                 private static extern AppDomain getCurDomain ();
201                 
202                 public static AppDomain CurrentDomain {
203                         get {
204                                 return getCurDomain ();
205                         }
206                 }
207
208                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
209                 private static extern AppDomain getRootDomain ();
210
211                 internal static AppDomain DefaultDomain {
212                         get {
213                                 if (default_domain == null) {
214                                         AppDomain rd = getRootDomain ();
215                                         if (rd == CurrentDomain)
216                                                 default_domain = rd;
217                                         else
218                                                 default_domain = (AppDomain) RemotingServices.GetDomainProxy (rd);
219                                 }
220                                 return default_domain;
221                         }
222                 }
223
224 #if NET_2_0
225                 [Obsolete ("")]
226 #endif
227                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
228                 public void AppendPrivatePath (string path)
229                 {
230                         if (path == null || path.Length == 0)
231                                 return;
232
233                         AppDomainSetup setup = SetupInformationNoCopy;
234
235                         string pp = setup.PrivateBinPath;
236                         if (pp == null || pp.Length == 0) {
237                                 setup.PrivateBinPath = path;
238                                 return;
239                         }
240
241                         pp = pp.Trim ();
242                         if (pp [pp.Length - 1] != Path.PathSeparator)
243                                 pp += Path.PathSeparator;
244
245                         setup.PrivateBinPath = pp + path;
246                 }
247
248 #if NET_2_0
249                 [Obsolete ("")]
250 #endif
251                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
252                 public void ClearPrivatePath ()
253                 {
254                         SetupInformationNoCopy.PrivateBinPath = String.Empty;
255                 }
256
257                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
258                 public void ClearShadowCopyPath ()
259                 {
260                         SetupInformationNoCopy.ShadowCopyDirectories = String.Empty;
261                 }
262
263                 public ObjectHandle CreateComInstanceFrom (string assemblyName, string typeName)
264                 {
265                         return Activator.CreateComInstanceFrom (assemblyName, typeName);
266                 }
267
268 #if NET_1_1
269                 public ObjectHandle CreateComInstanceFrom (string assemblyName, string typeName,
270                         byte [] hashValue, AssemblyHashAlgorithm hashAlgorithm)
271                 {
272                         return Activator.CreateComInstanceFrom (assemblyName, typeName, hashValue ,hashAlgorithm);
273                 }
274 #endif
275
276                 public ObjectHandle CreateInstance (string assemblyName, string typeName)
277                 {
278                         if (assemblyName == null)
279                                 throw new ArgumentNullException ("assemblyName");
280
281                         return Activator.CreateInstance (assemblyName, typeName);
282                 }
283
284                 public ObjectHandle CreateInstance (string assemblyName, string typeName, object[] activationAttributes)
285                 {
286                         if (assemblyName == null)
287                                 throw new ArgumentNullException ("assemblyName");
288
289                         return Activator.CreateInstance (assemblyName, typeName, activationAttributes);
290                 }
291
292                 public ObjectHandle CreateInstance (string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr,
293                                                     Binder binder, object[] args, CultureInfo culture, object[] activationAttributes,
294                                                     Evidence securityAttributes)
295                 {
296                         if (assemblyName == null)
297                                 throw new ArgumentNullException ("assemblyName");
298
299                         return Activator.CreateInstance (assemblyName, typeName, ignoreCase, bindingAttr, binder, args,
300                                 culture, activationAttributes, securityAttributes);
301                 }
302
303                 public object CreateInstanceAndUnwrap (string assemblyName, string typeName)
304                 {
305                         ObjectHandle oh = CreateInstance (assemblyName, typeName);
306                         return (oh != null) ? oh.Unwrap () : null;
307                 }
308
309                 public object CreateInstanceAndUnwrap (string assemblyName, string typeName, object [] activationAttributes)
310                 {
311                         ObjectHandle oh = CreateInstance (assemblyName, typeName, activationAttributes);
312                         return (oh != null) ? oh.Unwrap () : null;
313                 }
314
315                 public object CreateInstanceAndUnwrap (string assemblyName, string typeName, bool ignoreCase,
316                                                        BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture,
317                                                        object[] activationAttributes, Evidence securityAttributes)
318                 {
319                         ObjectHandle oh = CreateInstance (assemblyName, typeName, ignoreCase, bindingAttr, binder, args,
320                                 culture, activationAttributes, securityAttributes);
321                         return (oh != null) ? oh.Unwrap () : null;
322                 }
323
324                 public ObjectHandle CreateInstanceFrom (string assemblyName, string typeName)
325                 {
326                         if (assemblyName == null)
327                                 throw new ArgumentNullException ("assemblyName");
328
329                         return Activator.CreateInstanceFrom (assemblyName, typeName);
330                 }
331
332                 public ObjectHandle CreateInstanceFrom (string assemblyName, string typeName, object[] activationAttributes)
333                 {
334                         if (assemblyName == null)
335                                 throw new ArgumentNullException ("assemblyName");
336
337                         return Activator.CreateInstanceFrom (assemblyName, typeName, activationAttributes);
338                 }
339
340                 public ObjectHandle CreateInstanceFrom (string assemblyName, string typeName, bool ignoreCase,
341                                                         BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture,
342                                                         object[] activationAttributes, Evidence securityAttributes)
343                 {
344                         if (assemblyName == null)
345                                 throw new ArgumentNullException ("assemblyName");
346
347                         return Activator.CreateInstanceFrom (assemblyName, typeName, ignoreCase, bindingAttr, binder, args,
348                                                              culture, activationAttributes, securityAttributes);
349                 }
350
351                 public object CreateInstanceFromAndUnwrap (string assemblyName, string typeName)
352                 {
353                         ObjectHandle oh = CreateInstanceFrom (assemblyName, typeName);
354                         return (oh != null) ? oh.Unwrap () : null;
355                 }
356
357                 public object CreateInstanceFromAndUnwrap (string assemblyName, string typeName, object [] activationAttributes)
358                 {
359                         ObjectHandle oh = CreateInstanceFrom (assemblyName, typeName, activationAttributes);
360                         return (oh != null) ? oh.Unwrap () : null;
361                 }
362
363                 public object CreateInstanceFromAndUnwrap (string assemblyName, string typeName, bool ignoreCase,
364                                                            BindingFlags bindingAttr, Binder binder, object[] args,
365                                                            CultureInfo culture, object[] activationAttributes,
366                                                            Evidence securityAttributes)
367                 {
368                         ObjectHandle oh = CreateInstanceFrom (assemblyName, typeName, ignoreCase, bindingAttr, binder, args,
369                                 culture, activationAttributes, securityAttributes);
370
371                         return (oh != null) ? oh.Unwrap () : null;
372                 }
373
374                 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access)
375                 {
376                         return DefineDynamicAssembly (name, access, null, null, null, null, null, false);
377                 }
378
379                 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, Evidence evidence)
380                 {
381                         return DefineDynamicAssembly (name, access, null, evidence, null, null, null, false);
382                 }
383
384                 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir)
385                 {
386                         return DefineDynamicAssembly (name, access, dir, null, null, null, null, false);
387                 }
388
389                 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
390                                                               Evidence evidence)
391                 {
392                         return DefineDynamicAssembly (name, access, dir, evidence, null, null, null, false);
393                 }
394
395                 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access,
396                                                               PermissionSet requiredPermissions,
397                                                               PermissionSet optionalPermissions,
398                                                               PermissionSet refusedPermissions)
399                 {
400                         return DefineDynamicAssembly (name, access, null, null, requiredPermissions, optionalPermissions,
401                                 refusedPermissions, false);
402                 }
403
404                 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, Evidence evidence,
405                                                               PermissionSet requiredPermissions,
406                                                               PermissionSet optionalPermissions,
407                                                               PermissionSet refusedPermissions)
408                 {
409                         return DefineDynamicAssembly (name, access, null, evidence, requiredPermissions, optionalPermissions,
410                                 refusedPermissions, false);
411                 }
412
413                 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
414                                                               PermissionSet requiredPermissions,
415                                                               PermissionSet optionalPermissions,
416                                                               PermissionSet refusedPermissions)
417                 {
418                         return DefineDynamicAssembly (name, access, dir, null, requiredPermissions, optionalPermissions,
419                                 refusedPermissions, false);
420                 }
421
422                 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
423                                                               Evidence evidence,
424                                                               PermissionSet requiredPermissions,
425                                                               PermissionSet optionalPermissions,
426                                                               PermissionSet refusedPermissions)
427                 {
428                         return DefineDynamicAssembly (name, access, dir, evidence, requiredPermissions, optionalPermissions,
429                                 refusedPermissions, false);
430                 }
431
432                 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
433                                                               Evidence evidence,
434                                                               PermissionSet requiredPermissions,
435                                                               PermissionSet optionalPermissions,
436                                                               PermissionSet refusedPermissions, bool isSynchronized)
437                 {
438                         // FIXME: examine all other parameters
439                         
440                         AssemblyBuilder ab = new AssemblyBuilder (name, dir, access, false);
441                         ab.AddPermissionRequests (requiredPermissions, optionalPermissions, refusedPermissions);
442                         return ab;
443                 }
444
445 #if NET_2_0
446                 // NET 3.5 method
447                 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
448                                                               Evidence evidence,
449                                                               PermissionSet requiredPermissions,
450                                                               PermissionSet optionalPermissions,
451                                                               PermissionSet refusedPermissions, bool isSynchronized, IEnumerable<CustomAttributeBuilder> assemblyAttributes)
452                 {
453                         AssemblyBuilder ab = DefineDynamicAssembly (name, access, dir, evidence, requiredPermissions, optionalPermissions, refusedPermissions, isSynchronized);
454                         if (assemblyAttributes != null)
455                                 foreach (CustomAttributeBuilder cb in assemblyAttributes) {
456                                         ab.SetCustomAttribute (cb);
457                                 }
458                         return ab;
459                 }
460
461                 // NET 3.5 method
462                 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, IEnumerable<CustomAttributeBuilder> assemblyAttributes) {
463                         return DefineDynamicAssembly (name, access, null, null, null, null, null, false, assemblyAttributes);
464                 }
465 #endif
466
467                 internal AssemblyBuilder DefineInternalDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access)
468                 {
469                         return new AssemblyBuilder (name, null, access, true);
470                 }
471
472                 //
473                 // AppDomain.DoCallBack works because AppDomain is a MarshalByRefObject
474                 // so, when you call AppDomain.DoCallBack, that's a remote call
475                 //
476                 public void DoCallBack (CrossAppDomainDelegate theDelegate)
477                 {
478                         if (theDelegate != null)
479                                 theDelegate ();
480                 }
481
482                 public int ExecuteAssembly (string assemblyFile)
483                 {
484                         return ExecuteAssembly (assemblyFile, null, null);
485                 }
486
487                 public int ExecuteAssembly (string assemblyFile, Evidence assemblySecurity)
488                 {
489                         return ExecuteAssembly (assemblyFile, assemblySecurity, null);
490                 }
491
492                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
493                 public extern int ExecuteAssembly (string assemblyFile, Evidence assemblySecurity, string[] args);
494
495                 [MonoTODO ("No support for ExecuteAssembly")]
496                 public int ExecuteAssembly (string assemblyFile, Evidence assemblySecurity, string[] args, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
497                 {
498                         throw new NotImplementedException ();
499                 }
500                 
501                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
502                 private extern Assembly [] GetAssemblies (bool refOnly);
503
504                 public Assembly [] GetAssemblies ()
505                 {
506                         return GetAssemblies (false);
507                 }
508
509                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
510                 public extern object GetData (string name);
511
512                 public new Type GetType()
513                 {
514                         return base.GetType ();
515                 }
516
517                 public override object InitializeLifetimeService ()
518                 {
519                         return null;
520                 }
521
522                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
523                 internal extern Assembly LoadAssembly (string assemblyRef, Evidence securityEvidence, bool refOnly);
524
525                 public Assembly Load (AssemblyName assemblyRef)
526                 {
527                         return Load (assemblyRef, null);
528                 }
529
530                 public Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
531                 {
532                         if (assemblyRef == null)
533                                 throw new ArgumentNullException ("assemblyRef");
534
535                         if (assemblyRef.Name == null || assemblyRef.Name.Length == 0) {
536                                 if (assemblyRef.CodeBase != null)
537                                         return Assembly.LoadFrom (assemblyRef.CodeBase, assemblySecurity);
538                                 else
539                                         throw new ArgumentException (Locale.GetText ("assemblyRef.Name cannot be empty."), "assemblyRef");
540                         }
541
542                         return LoadAssembly (assemblyRef.FullName, assemblySecurity, false);
543                 }
544
545                 public Assembly Load (string assemblyString)
546                 {
547                         if (assemblyString == null)
548                                 throw new ArgumentNullException ("assemblyString");
549
550                         return LoadAssembly (assemblyString, null, false);
551                 }
552
553                 public Assembly Load (string assemblyString, Evidence assemblySecurity)
554                 {
555                         return Load (assemblyString, assemblySecurity, false);
556                 }
557                 
558                 internal Assembly Load (string assemblyString, Evidence assemblySecurity, bool refonly)
559                 {
560                         if (assemblyString == null)
561                                 throw new ArgumentNullException ("assemblyString");
562
563                         return LoadAssembly (assemblyString, assemblySecurity, refonly);
564                 }
565
566                 public Assembly Load (byte[] rawAssembly)
567                 {
568                         return Load (rawAssembly, null, null);
569                 }
570
571                 public Assembly Load (byte[] rawAssembly, byte[] rawSymbolStore)
572                 {
573                         return Load (rawAssembly, rawSymbolStore, null);
574                 }
575
576                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
577                 internal extern Assembly LoadAssemblyRaw (byte[] rawAssembly, byte[] rawSymbolStore, Evidence securityEvidence, bool refonly);
578
579                 public Assembly Load (byte[] rawAssembly, byte[] rawSymbolStore, Evidence securityEvidence)
580                 {
581                         return Load (rawAssembly, rawSymbolStore, securityEvidence, false);
582                 }
583
584                 internal Assembly Load (byte [] rawAssembly, byte [] rawSymbolStore, Evidence securityEvidence, bool refonly)
585                 {
586                         if (rawAssembly == null)
587                                 throw new ArgumentNullException ("rawAssembly");
588
589                         Assembly assembly = LoadAssemblyRaw (rawAssembly, rawSymbolStore, securityEvidence, refonly);
590                         assembly.FromByteArray = true;
591                         return assembly;
592                 }
593
594                 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
595                 public void SetAppDomainPolicy (PolicyLevel domainPolicy)
596                 {
597                         if (domainPolicy == null)
598                                 throw new ArgumentNullException ("domainPolicy");
599                         if (_granted != null) {
600                                 throw new PolicyException (Locale.GetText (
601                                         "An AppDomain policy is already specified."));
602                         }
603                         if (IsFinalizingForUnload ())
604                                 throw new AppDomainUnloadedException ();
605
606                         PolicyStatement ps = domainPolicy.Resolve (_evidence);
607                         _granted = ps.PermissionSet;
608                 }
609
610                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
611                 public void SetCachePath (string path)
612                 {
613                         SetupInformationNoCopy.CachePath = path;
614                 }
615
616                 [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
617                 public void SetPrincipalPolicy (PrincipalPolicy policy)
618                 {
619                         if (IsFinalizingForUnload ())
620                                 throw new AppDomainUnloadedException ();
621
622                         _principalPolicy = policy;
623                         _principal = null;
624                 }
625
626                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
627                 public void SetShadowCopyFiles()
628                 {
629                         SetupInformationNoCopy.ShadowCopyFiles = "true";
630                 }
631
632                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
633                 public void SetShadowCopyPath (string path)
634                 {
635                         SetupInformationNoCopy.ShadowCopyDirectories = path;
636                 }
637
638                 [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
639                 public void SetThreadPrincipal (IPrincipal principal)
640                 {
641                         if (principal == null)
642                                 throw new ArgumentNullException ("principal");
643                         if (_principal != null)
644                                 throw new PolicyException (Locale.GetText ("principal already present."));
645                         if (IsFinalizingForUnload ())
646                                 throw new AppDomainUnloadedException ();
647
648                         _principal = principal;
649                 }
650
651                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
652                 private static extern AppDomain InternalSetDomainByID (int domain_id);
653  
654                 // Changes the active domain and returns the old domain
655                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
656                 private static extern AppDomain InternalSetDomain (AppDomain context);
657
658                 // Notifies the runtime that this thread references 'domain'.
659                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
660                 internal static extern void InternalPushDomainRef (AppDomain domain);
661
662                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
663                 internal static extern void InternalPushDomainRefByID (int domain_id);
664
665                 // Undoes the effect of the last PushDomainRef call
666                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
667                 internal static extern void InternalPopDomainRef ();
668
669                 // Changes the active context and returns the old context
670                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
671                 internal static extern Context InternalSetContext (Context context);
672
673                 // Returns the current context
674                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
675                 internal static extern Context InternalGetContext ();
676
677                 // Returns the current context
678                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
679                 internal static extern Context InternalGetDefaultContext ();
680
681                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
682                 internal static extern string InternalGetProcessGuid (string newguid);
683
684                 // This method is handled specially by the runtime
685                 // It is the only managed method which is allowed to set the current
686                 // appdomain
687                 internal static object InvokeInDomain (AppDomain domain, MethodInfo method, object obj, object [] args)
688                 {
689                         AppDomain current = CurrentDomain;
690                         bool pushed = false;
691
692                         try {
693                                 InternalPushDomainRef (domain);
694                                 pushed = true;
695                                 InternalSetDomain (domain);
696                                 return ((MonoMethod) method).InternalInvoke (obj, args);
697                         }
698                         finally {
699                                 InternalSetDomain (current);
700                                 if (pushed)
701                                         InternalPopDomainRef ();
702                         }
703                 }
704
705                 internal static object InvokeInDomainByID (int domain_id, MethodInfo method, object obj, object [] args)
706                 {
707                         AppDomain current = CurrentDomain;
708                         bool pushed = false;
709
710                         try {
711                                 InternalPushDomainRefByID (domain_id);
712                                 pushed = true;
713                                 InternalSetDomainByID (domain_id);
714                                 return ((MonoMethod) method).InternalInvoke (obj, args);
715                         }
716                         finally {
717                                 InternalSetDomain (current);
718                                 if (pushed)
719                                         InternalPopDomainRef ();
720                         }
721                 }
722
723                 internal static String GetProcessGuid ()
724                 {
725                         if (_process_guid == null) {
726                                 _process_guid = InternalGetProcessGuid (Guid.NewGuid().ToString ());
727                         }
728                         return _process_guid;
729                 }
730
731                 public static AppDomain CreateDomain (string friendlyName)
732                 {
733                         return CreateDomain (friendlyName, null, null);
734                 }
735                 
736                 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo)
737                 {
738                         return CreateDomain (friendlyName, securityInfo, null);
739                 }
740
741                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
742                 private static extern AppDomain createDomain (string friendlyName, AppDomainSetup info);
743
744                 [MonoTODO ("Currently it does not allow the setup in the other domain")]
745                 [SecurityPermission (SecurityAction.Demand, ControlAppDomain = true)]
746                 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo, AppDomainSetup info)
747                 {
748                         if (friendlyName == null)
749                                 throw new System.ArgumentNullException ("friendlyName");
750
751                         AppDomain def = AppDomain.DefaultDomain;
752                         if (info == null) {
753                                 // if null, get default domain's SetupInformation       
754                                 if (def == null)
755                                         info = new AppDomainSetup ();   // we're default!
756                                 else
757                                         info = def.SetupInformation;
758                         }
759                         else
760                                 info = new AppDomainSetup (info);       // copy
761
762                         // todo: allow setup in the other domain
763                         if (def != null) {
764                                 if (!info.Equals (def.SetupInformation)) {
765                                         // If not specified use default domain's app base.
766                                         if (info.ApplicationBase == null)
767                                                 info.ApplicationBase = def.SetupInformation.ApplicationBase;
768                                         if (info.ConfigurationFile == null)
769                                                 info.ConfigurationFile = Path.GetFileName (def.SetupInformation.ConfigurationFile);
770                                 }
771                         } else if (info.ConfigurationFile == null)
772                                 info.ConfigurationFile = "[I don't have a config file]";
773
774                         AppDomain ad = (AppDomain) RemotingServices.GetDomainProxy (createDomain (friendlyName, info));
775                         if (securityInfo == null) {
776                                 // get default domain's Evidence (unless we're are the default!)
777                                 if (def == null)
778                                         ad._evidence = null;            // we'll get them later (GetEntryAssembly)
779                                 else
780                                         ad._evidence = def.Evidence;    // new (shallow) copy
781                         }
782                         else
783                                 ad._evidence = new Evidence (securityInfo);     // copy
784
785 #if NET_2_0
786                         if (info.AppDomainInitializer != null) {
787                                 if ((info.AppDomainInitializer.Method.Attributes & MethodAttributes.Static) == 0)
788                                         throw new ArgumentException ("Non-static methods cannot be invoked as an appdomain initializer");
789                                 info.AppDomainInitializer (info.AppDomainInitializerArguments);
790                         }
791 #endif
792
793                         return ad;
794                 }
795
796                 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo,string appBasePath,
797                                                       string appRelativeSearchPath, bool shadowCopyFiles)
798                 {
799                         AppDomainSetup info = new AppDomainSetup ();
800
801                         info.ApplicationBase = appBasePath;
802                         info.PrivateBinPath = appRelativeSearchPath;
803
804                         if (shadowCopyFiles)
805                                 info.ShadowCopyFiles = "true";
806                         else
807                                 info.ShadowCopyFiles = "false";
808
809                         return CreateDomain (friendlyName, securityInfo, info);
810                 }
811
812                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
813                 private static extern bool InternalIsFinalizingForUnload (int domain_id);
814
815                 public bool IsFinalizingForUnload()
816                 {
817                         return InternalIsFinalizingForUnload (getDomainID ());
818                 }
819
820                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
821                 static extern void InternalUnload (int domain_id);
822
823                 // We do this because if the domain is a transparant proxy this
824                 // will still return the correct domain id.
825                 private int getDomainID ()
826                 {
827                         return Thread.GetDomainID ();
828                 }
829
830                 [SecurityPermission (SecurityAction.Demand, ControlAppDomain = true)]
831 #if NET_2_0
832                 [ReliabilityContractAttribute (Consistency.MayCorruptAppDomain, Cer.MayFail)]
833 #endif
834                 public static void Unload (AppDomain domain)
835                 {
836                         if (domain == null)
837                                 throw new ArgumentNullException ("domain");
838
839                         InternalUnload (domain.getDomainID());
840                 }
841
842                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
843                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
844                 public extern void SetData (string name, object data);
845
846                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
847                 public void SetDynamicBase (string path)
848                 {
849                         SetupInformationNoCopy.DynamicBase = path;
850                 }
851
852 #if NET_2_0
853                 [Obsolete ("")]
854 #endif
855                 public static int GetCurrentThreadId ()
856                 {
857                         return Thread.CurrentThreadId;
858                 }
859
860                 public override string ToString ()
861                 {
862                         return getFriendlyName ();
863                 }
864
865                 // The following methods are called from the runtime. Don't change signatures.
866                 private void DoAssemblyLoad (Assembly assembly)
867                 {
868                         if (AssemblyLoad == null)
869                                 return;
870
871                         AssemblyLoad (this, new AssemblyLoadEventArgs (assembly));
872                 }
873
874                 private Assembly DoAssemblyResolve (string name, bool refonly)
875                 {
876 #if NET_2_0
877                         if (refonly && ReflectionOnlyAssemblyResolve == null)
878                                 return null;
879 #endif
880                         if (AssemblyResolve == null)
881                                 return null;
882                         
883                         /* Prevent infinite recursion */
884                         Hashtable ht = assembly_resolve_in_progress;
885                         if (ht == null) {
886                                 ht = new Hashtable ();
887                                 assembly_resolve_in_progress = ht;
888                         }
889
890                         Assembly ass = (Assembly) ht [name];
891 #if NET_2_0
892                         if (ass != null && (ass.ReflectionOnly == refonly))
893                                 return null;
894 #else
895                         if (ass != null)
896                                 return null;
897 #endif
898                         ht [name] = name;
899                         try {
900                                 
901 #if NET_2_0
902                                 Delegate [] invocation_list = refonly ? ReflectionOnlyAssemblyResolve.GetInvocationList () : 
903                                         AssemblyResolve.GetInvocationList ();
904 #else
905                                 Delegate [] invocation_list = AssemblyResolve.GetInvocationList ();
906 #endif
907
908                                 foreach (Delegate eh in invocation_list) {
909                                         ResolveEventHandler handler = (ResolveEventHandler) eh;
910                                         Assembly assembly = handler (this, new ResolveEventArgs (name));
911                                         if (assembly != null)
912                                                 return assembly;
913                                 }
914                                 return null;
915                         }
916                         finally {
917                                 ht.Remove (name);
918                         }
919                 }
920
921                 internal Assembly DoTypeResolve (Object name_or_tb)
922                 {
923                         if (TypeResolve == null)
924                                 return null;
925
926                         string name;
927
928                         if (name_or_tb is TypeBuilder)
929                                 name = ((TypeBuilder) name_or_tb).FullName;
930                         else
931                                 name = (string) name_or_tb;
932
933                         /* Prevent infinite recursion */
934                         Hashtable ht = type_resolve_in_progress;
935                         if (ht == null) {
936                                 ht = new Hashtable ();
937                                 type_resolve_in_progress = ht;
938                         }
939
940                         if (ht.Contains (name))
941                                 return null;
942                         else
943                                 ht [name] = name;
944
945                         try {
946                                 foreach (Delegate d in TypeResolve.GetInvocationList ()) {
947                                         ResolveEventHandler eh = (ResolveEventHandler) d;
948                                         Assembly assembly = eh (this, new ResolveEventArgs (name));
949                                         if (assembly != null)
950                                                 return assembly;
951                                 }
952                                 return null;
953                         }
954                         finally {
955                                 ht.Remove (name);
956                         }
957                 }
958
959                 private void DoDomainUnload ()
960                 {
961                         if (DomainUnload != null)
962                                 DomainUnload(this, null);
963                 }
964
965                 internal byte[] GetMarshalledDomainObjRef ()
966                 {
967                         ObjRef oref = RemotingServices.Marshal (AppDomain.CurrentDomain, null, typeof (AppDomain));
968                         return CADSerializer.SerializeObject (oref).GetBuffer();
969                 }
970
971                 internal void ProcessMessageInDomain (byte[] arrRequest, CADMethodCallMessage cadMsg,
972                                                       out byte[] arrResponse, out CADMethodReturnMessage cadMrm)
973                 {
974                         IMessage reqDomMsg;
975
976                         if (null != arrRequest)
977                                 reqDomMsg = CADSerializer.DeserializeMessage (new MemoryStream(arrRequest), null);
978                         else
979                                 reqDomMsg = new MethodCall (cadMsg);
980
981                         IMessage retDomMsg = ChannelServices.SyncDispatchMessage (reqDomMsg);
982
983                         cadMrm = CADMethodReturnMessage.Create (retDomMsg);
984                         if (null == cadMrm) {
985                                 arrResponse = CADSerializer.SerializeMessage (retDomMsg).GetBuffer();
986                         } 
987                         else
988                                 arrResponse = null;
989                 }
990
991                 // End of methods called from the runtime
992                 
993 #if BOOTSTRAP_WITH_OLDLIB
994                 // older MCS/corlib returns:
995                 // _AppDomain.cs(138) error CS0592: Attribute 'SecurityPermission' is not valid on this declaration type.
996                 // It is valid on 'assembly' 'class' 'constructor' 'method' 'struct'  declarations only.
997                 public event AssemblyLoadEventHandler AssemblyLoad;
998
999                 public event ResolveEventHandler AssemblyResolve;
1000
1001                 public event EventHandler DomainUnload;
1002
1003                 public event EventHandler ProcessExit;
1004
1005                 public event ResolveEventHandler ResourceResolve;
1006
1007                 public event ResolveEventHandler TypeResolve;
1008
1009                 public event UnhandledExceptionEventHandler UnhandledException;
1010 #else
1011                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1012                 public event AssemblyLoadEventHandler AssemblyLoad;
1013
1014                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1015                 public event ResolveEventHandler AssemblyResolve;
1016
1017                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1018                 public event EventHandler DomainUnload;
1019
1020                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1021                 public event EventHandler ProcessExit;
1022
1023                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1024                 public event ResolveEventHandler ResourceResolve;
1025
1026                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1027                 public event ResolveEventHandler TypeResolve;
1028
1029                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1030                 public event UnhandledExceptionEventHandler UnhandledException;
1031 #endif
1032
1033                 /* Avoid warnings for events used only by the runtime */
1034                 private void DummyUse () {
1035                         ProcessExit += (EventHandler)null;
1036                         ResourceResolve += (ResolveEventHandler)null;
1037                         UnhandledException += (UnhandledExceptionEventHandler)null;
1038                 }
1039
1040 #if NET_2_0
1041
1042                 public event ResolveEventHandler ReflectionOnlyAssemblyResolve;
1043                 
1044                 private ActivationContext _activation;
1045                 private ApplicationIdentity _applicationIdentity;
1046                 private AppDomainManager _domain_manager;
1047
1048                 // properties
1049
1050                 public ActivationContext ActivationContext {
1051                         get { return _activation; }
1052                 }
1053
1054                 public ApplicationIdentity ApplicationIdentity {
1055                         get { return _applicationIdentity; }
1056                 }
1057
1058                 // default is null
1059                 public AppDomainManager DomainManager {
1060                         get { return _domain_manager; }
1061                 }
1062
1063                 public int Id {
1064                         [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
1065                         get { return getDomainID (); }
1066                 }
1067
1068                 // methods
1069
1070                 [MonoTODO ("This routine only returns the parameter currently")]
1071                 [ComVisible (false)]
1072                 public string ApplyPolicy (string assemblyName)
1073                 {
1074                         if (assemblyName == null)
1075                                 throw new ArgumentNullException ("assemblyName");
1076                         if (assemblyName.Length == 0) // String.Empty
1077                                 throw new ArgumentException ("assemblyName");
1078                         return assemblyName;
1079                 }
1080
1081                 // static methods
1082
1083                 [MonoTODO ("add support for new delegate")]
1084                 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo, string appBasePath,
1085                         string appRelativeSearchPath, bool shadowCopy, AppDomainInitializer adInit, string[] adInitArgs)
1086                 {
1087                         return CreateDomain (friendlyName, securityInfo, appBasePath, appRelativeSearchPath, shadowCopy);
1088                 }
1089
1090                 [MonoTODO ("resolve assemblyName to location")]
1091                 public int ExecuteAssemblyByName (string assemblyName)
1092                 {
1093                         return ExecuteAssemblyByName (assemblyName, null, null);
1094                 }
1095
1096                 [MonoTODO ("resolve assemblyName to location")]
1097                 public int ExecuteAssemblyByName (string assemblyName, Evidence assemblySecurity)
1098                 {
1099                         return ExecuteAssemblyByName (assemblyName, assemblySecurity, null);
1100                 }
1101
1102                 [MonoTODO ("resolve assemblyName to location")]
1103                 public int ExecuteAssemblyByName (string assemblyName, Evidence assemblySecurity, params string[] args)
1104                 {
1105                         if (assemblyName == null)
1106                                 throw new ArgumentNullException ("assemblyName");
1107
1108                         AssemblyName an = new AssemblyName (assemblyName);
1109                         return ExecuteAssemblyByName (an, assemblySecurity, args);
1110                 }
1111
1112                 [MonoTODO ("assemblyName may not have a codebase")]
1113                 public int ExecuteAssemblyByName (AssemblyName assemblyName, Evidence assemblySecurity, params string[] args)
1114                 {
1115                         if (assemblyName == null)
1116                                 throw new ArgumentNullException ("assemblyName");
1117
1118                         return ExecuteAssembly (assemblyName.CodeBase, assemblySecurity, args);
1119                 }
1120
1121                 public bool IsDefaultAppDomain ()
1122                 {
1123                         return Object.ReferenceEquals (this, DefaultDomain);
1124                 }
1125
1126                 public Assembly[] ReflectionOnlyGetAssemblies ()
1127                 {
1128                         return GetAssemblies (true);
1129                 }
1130 #endif
1131
1132 #if NET_1_1
1133                 void _AppDomain.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1134                 {
1135                         throw new NotImplementedException ();
1136                 }
1137
1138                 void _AppDomain.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
1139                 {
1140                         throw new NotImplementedException ();
1141                 }
1142
1143                 void _AppDomain.GetTypeInfoCount (out uint pcTInfo)
1144                 {
1145                         throw new NotImplementedException ();
1146                 }
1147
1148                 void _AppDomain.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
1149                         IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1150                 {
1151                         throw new NotImplementedException ();
1152                 }
1153 #endif
1154         }
1155 }