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