In corlib/System.Runtime.InteropServices:
[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                 public void DoCallBack (CrossAppDomainDelegate theDelegate)
441                 {
442                         if (theDelegate != null)
443                                 theDelegate ();
444                 }
445
446                 public int ExecuteAssembly (string assemblyFile)
447                 {
448                         return ExecuteAssembly (assemblyFile, null, null);
449                 }
450
451                 public int ExecuteAssembly (string assemblyFile, Evidence assemblySecurity)
452                 {
453                         return ExecuteAssembly (assemblyFile, assemblySecurity, null);
454                 }
455
456                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
457                 public extern int ExecuteAssembly (string assemblyFile, Evidence assemblySecurity, string[] args);
458
459                 [MonoTODO ("No support for ExecuteAssembly")]
460                 public int ExecuteAssembly (string assemblyFile, Evidence assemblySecurity, string[] args, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
461                 {
462                         throw new NotImplementedException ();
463                 }
464                 
465                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
466                 private extern Assembly [] GetAssemblies (bool refOnly);
467
468                 public Assembly [] GetAssemblies ()
469                 {
470                         return GetAssemblies (false);
471                 }
472
473                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
474                 public extern object GetData (string name);
475
476                 public new Type GetType()
477                 {
478                         return base.GetType ();
479                 }
480
481                 public override object InitializeLifetimeService ()
482                 {
483                         return null;
484                 }
485
486                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
487                 internal extern Assembly LoadAssembly (string assemblyRef, Evidence securityEvidence, bool refOnly);
488
489                 public Assembly Load (AssemblyName assemblyRef)
490                 {
491                         return Load (assemblyRef, null);
492                 }
493
494                 public Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
495                 {
496                         if (assemblyRef == null)
497                                 throw new ArgumentNullException ("assemblyRef");
498
499                         if (assemblyRef.Name == null || assemblyRef.Name.Length == 0) {
500                                 if (assemblyRef.CodeBase != null)
501                                         return Assembly.LoadFrom (assemblyRef.CodeBase, assemblySecurity);
502                                 else
503                                         throw new ArgumentException (Locale.GetText ("assemblyRef.Name cannot be empty."), "assemblyRef");
504                         }
505
506                         return LoadAssembly (assemblyRef.FullName, assemblySecurity, false);
507                 }
508
509                 public Assembly Load (string assemblyString)
510                 {
511                         if (assemblyString == null)
512                                 throw new ArgumentNullException ("assemblyString");
513
514                         return LoadAssembly (assemblyString, null, false);
515                 }
516
517                 public Assembly Load (string assemblyString, Evidence assemblySecurity)
518                 {
519                         return Load (assemblyString, assemblySecurity, false);
520                 }
521                 
522                 internal Assembly Load (string assemblyString, Evidence assemblySecurity, bool refonly)
523                 {
524                         if (assemblyString == null)
525                                 throw new ArgumentNullException ("assemblyString");
526
527                         return LoadAssembly (assemblyString, assemblySecurity, refonly);
528                 }
529
530                 public Assembly Load (byte[] rawAssembly)
531                 {
532                         return Load (rawAssembly, null, null);
533                 }
534
535                 public Assembly Load (byte[] rawAssembly, byte[] rawSymbolStore)
536                 {
537                         return Load (rawAssembly, rawSymbolStore, null);
538                 }
539
540                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
541                 internal extern Assembly LoadAssemblyRaw (byte[] rawAssembly, byte[] rawSymbolStore, Evidence securityEvidence, bool refonly);
542
543                 public Assembly Load (byte[] rawAssembly, byte[] rawSymbolStore, Evidence securityEvidence)
544                 {
545                         return Load (rawAssembly, rawSymbolStore, securityEvidence, false);
546                 }
547
548                 internal Assembly Load (byte [] rawAssembly, byte [] rawSymbolStore, Evidence securityEvidence, bool refonly)
549                 {
550                         if (rawAssembly == null)
551                                 throw new ArgumentNullException ("rawAssembly");
552                                 
553                         Assembly assembly = LoadAssemblyRaw (rawAssembly, rawSymbolStore, securityEvidence, refonly);
554                         assembly.FromByteArray = true;
555                         return assembly;
556                 }
557
558                 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
559                 public void SetAppDomainPolicy (PolicyLevel domainPolicy)
560                 {
561                         if (domainPolicy == null)
562                                 throw new ArgumentNullException ("domainPolicy");
563                         if (_granted != null) {
564                                 throw new PolicyException (Locale.GetText (
565                                         "An AppDomain policy is already specified."));
566                         }
567                         if (IsFinalizingForUnload ())
568                                 throw new AppDomainUnloadedException ();
569
570                         PolicyStatement ps = domainPolicy.Resolve (_evidence);
571                         _granted = ps.PermissionSet;
572                 }
573
574                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
575                 public void SetCachePath (string path)
576                 {
577                         SetupInformationNoCopy.CachePath = path;
578                 }
579
580                 [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
581                 public void SetPrincipalPolicy (PrincipalPolicy policy)
582                 {
583                         if (IsFinalizingForUnload ())
584                                 throw new AppDomainUnloadedException ();
585
586                         _principalPolicy = policy;
587                         _principal = null;
588                 }
589
590                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
591                 public void SetShadowCopyFiles()
592                 {
593                         SetupInformationNoCopy.ShadowCopyFiles = "true";
594                 }
595
596                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
597                 public void SetShadowCopyPath (string path)
598                 {
599                         SetupInformationNoCopy.ShadowCopyDirectories = path;
600                 }
601
602                 [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
603                 public void SetThreadPrincipal (IPrincipal principal)
604                 {
605                         if (principal == null)
606                                 throw new ArgumentNullException ("principal");
607                         if (_principal != null)
608                                 throw new PolicyException (Locale.GetText ("principal already present."));
609                         if (IsFinalizingForUnload ())
610                                 throw new AppDomainUnloadedException ();
611
612                         _principal = principal;
613                 }
614
615                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
616                 private static extern AppDomain InternalSetDomainByID (int domain_id);
617  
618                 // Changes the active domain and returns the old domain
619                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
620                 private static extern AppDomain InternalSetDomain (AppDomain context);
621
622                 // Notifies the runtime that this thread references 'domain'.
623                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
624                 internal static extern void InternalPushDomainRef (AppDomain domain);
625
626                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
627                 internal static extern void InternalPushDomainRefByID (int domain_id);
628
629                 // Undoes the effect of the last PushDomainRef call
630                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
631                 internal static extern void InternalPopDomainRef ();
632
633                 // Changes the active context and returns the old context
634                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
635                 internal static extern Context InternalSetContext (Context context);
636
637                 // Returns the current context
638                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
639                 internal static extern Context InternalGetContext ();
640
641                 // Returns the current context
642                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
643                 internal static extern Context InternalGetDefaultContext ();
644
645                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
646                 internal static extern string InternalGetProcessGuid (string newguid);
647
648                 // This method is handled specially by the runtime
649                 // It is the only managed method which is allowed to set the current
650                 // appdomain
651                 internal static object InvokeInDomain (AppDomain domain, MethodInfo method, object obj, object [] args)
652                 {
653                         AppDomain current = CurrentDomain;
654                         bool pushed = false;
655
656                         try {
657                                 InternalPushDomainRef (domain);
658                                 pushed = true;
659                                 InternalSetDomain (domain);
660                                 return ((MonoMethod) method).InternalInvoke (obj, args);
661                         }
662                         finally {
663                                 InternalSetDomain (current);
664                                 if (pushed)
665                                         InternalPopDomainRef ();
666                         }
667                 }
668
669                 internal static object InvokeInDomainByID (int domain_id, MethodInfo method, object obj, object [] args)
670                 {
671                         AppDomain current = CurrentDomain;
672                         bool pushed = false;
673
674                         try {
675                                 InternalPushDomainRefByID (domain_id);
676                                 pushed = true;
677                                 InternalSetDomainByID (domain_id);
678                                 return ((MonoMethod) method).InternalInvoke (obj, args);
679                         }
680                         finally {
681                                 InternalSetDomain (current);
682                                 if (pushed)
683                                         InternalPopDomainRef ();
684                         }
685                 }
686
687                 internal static String GetProcessGuid ()
688                 {
689                         if (_process_guid == null) {
690                                 _process_guid = InternalGetProcessGuid (Guid.NewGuid().ToString ());
691                         }
692                         return _process_guid;
693                 }
694
695                 public static AppDomain CreateDomain (string friendlyName)
696                 {
697                         return CreateDomain (friendlyName, null, null);
698                 }
699                 
700                 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo)
701                 {
702                         return CreateDomain (friendlyName, securityInfo, null);
703                 }
704
705                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
706                 private static extern AppDomain createDomain (string friendlyName, AppDomainSetup info);
707
708                 [MonoTODO ("Currently it does not allow the setup in the other domain")]
709                 [SecurityPermission (SecurityAction.Demand, ControlAppDomain = true)]
710                 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo, AppDomainSetup info)
711                 {
712                         if (friendlyName == null)
713                                 throw new System.ArgumentNullException ("friendlyName");
714
715                         AppDomain def = AppDomain.DefaultDomain;
716                         if (info == null) {
717                                 // if null, get default domain's SetupInformation       
718                                 if (def == null)
719                                         info = new AppDomainSetup ();   // we're default!
720                                 else
721                                         info = def.SetupInformation;
722                         }
723                         else
724                                 info = new AppDomainSetup (info);       // copy
725
726                         // todo: allow setup in the other domain
727                         if (def != null) {
728                                 if (!info.Equals (def.SetupInformation)) {
729                                         // If not specified use default domain's app base.
730                                         if (info.ApplicationBase == null)
731                                                 info.ApplicationBase = def.SetupInformation.ApplicationBase;
732                                         if (info.ConfigurationFile == null)
733                                                 info.ConfigurationFile = Path.GetFileName (def.SetupInformation.ConfigurationFile);
734                                 }
735                         } else if (info.ConfigurationFile == null)
736                                 info.ConfigurationFile = "[I don't have a config file]";
737
738                         AppDomain ad = (AppDomain) RemotingServices.GetDomainProxy (createDomain (friendlyName, info));
739                         if (securityInfo == null) {
740                                 // get default domain's Evidence (unless we're are the default!)
741                                 if (def == null)
742                                         ad._evidence = null;            // we'll get them later (GetEntryAssembly)
743                                 else
744                                         ad._evidence = def.Evidence;    // new (shallow) copy
745                         }
746                         else
747                                 ad._evidence = new Evidence (securityInfo);     // copy
748
749                         return ad;
750                 }
751
752                 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo,string appBasePath,
753                                                       string appRelativeSearchPath, bool shadowCopyFiles)
754                 {
755                         AppDomainSetup info = new AppDomainSetup ();
756
757                         info.ApplicationBase = appBasePath;
758                         info.PrivateBinPath = appRelativeSearchPath;
759
760                         if (shadowCopyFiles)
761                                 info.ShadowCopyFiles = "true";
762                         else
763                                 info.ShadowCopyFiles = "false";
764
765                         return CreateDomain (friendlyName, securityInfo, info);
766                 }
767
768                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
769                 private static extern bool InternalIsFinalizingForUnload (int domain_id);
770
771                 public bool IsFinalizingForUnload()
772                 {
773                         return InternalIsFinalizingForUnload (getDomainID ());
774                 }
775
776                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
777                 static extern void InternalUnload (int domain_id);
778
779                 // We do this because if the domain is a transparant proxy this
780                 // will still return the correct domain id.
781                 private int getDomainID ()
782                 {
783                         return Thread.GetDomainID ();
784                 }
785
786                 [SecurityPermission (SecurityAction.Demand, ControlAppDomain = true)]
787 #if NET_2_0
788                 [ReliabilityContractAttribute (Consistency.MayCorruptAppDomain, Cer.MayFail)]
789 #endif
790                 public static void Unload (AppDomain domain)
791                 {
792                         if (domain == null)
793                                 throw new ArgumentNullException ("domain");
794
795                         InternalUnload (domain.getDomainID());
796                 }
797
798                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
799                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
800                 public extern void SetData (string name, object data);
801
802                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
803                 public void SetDynamicBase (string path)
804                 {
805                         SetupInformationNoCopy.DynamicBase = path;
806                 }
807
808 #if NET_2_0
809                 [Obsolete ("")]
810 #endif
811                 public static int GetCurrentThreadId ()
812                 {
813                         return Thread.CurrentThreadId;
814                 }
815
816                 public override string ToString ()
817                 {
818                         return getFriendlyName ();
819                 }
820
821                 // The following methods are called from the runtime. Don't change signatures.
822                 private void DoAssemblyLoad (Assembly assembly)
823                 {
824                         if (AssemblyLoad == null)
825                                 return;
826
827                         AssemblyLoad (this, new AssemblyLoadEventArgs (assembly));
828                 }
829
830                 private Assembly DoAssemblyResolve (string name, bool refonly)
831                 {
832 #if NET_2_0
833                         if (refonly && ReflectionOnlyAssemblyResolve == null)
834                                 return null;
835 #endif
836                         if (AssemblyResolve == null)
837                                 return null;
838                         
839                         /* Prevent infinite recursion */
840                         Hashtable ht = assembly_resolve_in_progress;
841                         if (ht == null) {
842                                 ht = new Hashtable ();
843                                 assembly_resolve_in_progress = ht;
844                         }
845
846                         Assembly ass = (Assembly) ht [name];
847 #if NET_2_0
848                         if (ass != null && (ass.ReflectionOnly == refonly))
849                                 return null;
850 #else
851                         if (ass != null)
852                                 return null;
853 #endif
854                         ht [name] = name;
855                         try {
856                                 
857 #if NET_2_0
858                                 Delegate [] invocation_list = refonly ? ReflectionOnlyAssemblyResolve.GetInvocationList () : 
859                                         AssemblyResolve.GetInvocationList ();
860 #else
861                                 Delegate [] invocation_list = AssemblyResolve.GetInvocationList ();
862 #endif
863
864                                 foreach (Delegate eh in invocation_list) {
865                                         ResolveEventHandler handler = (ResolveEventHandler) eh;
866                                         Assembly assembly = handler (this, new ResolveEventArgs (name));
867                                         if (assembly != null)
868                                                 return assembly;
869                                 }
870                                 return null;
871                         }
872                         finally {
873                                 ht.Remove (name);
874                         }
875                 }
876
877                 internal Assembly DoTypeResolve (Object name_or_tb)
878                 {
879                         if (TypeResolve == null)
880                                 return null;
881
882                         string name;
883
884                         if (name_or_tb is TypeBuilder)
885                                 name = ((TypeBuilder) name_or_tb).FullName;
886                         else
887                                 name = (string) name_or_tb;
888
889                         /* Prevent infinite recursion */
890                         Hashtable ht = type_resolve_in_progress;
891                         if (ht == null) {
892                                 ht = new Hashtable ();
893                                 type_resolve_in_progress = ht;
894                         }
895
896                         if (ht.Contains (name))
897                                 return null;
898                         else
899                                 ht [name] = name;
900
901                         try {
902                                 foreach (Delegate d in TypeResolve.GetInvocationList ()) {
903                                         ResolveEventHandler eh = (ResolveEventHandler) d;
904                                         Assembly assembly = eh (this, new ResolveEventArgs (name));
905                                         if (assembly != null)
906                                                 return assembly;
907                                 }
908                                 return null;
909                         }
910                         finally {
911                                 ht.Remove (name);
912                         }
913                 }
914
915                 private void DoDomainUnload ()
916                 {
917                         if (DomainUnload != null)
918                                 DomainUnload(this, null);
919                 }
920
921                 internal byte[] GetMarshalledDomainObjRef ()
922                 {
923                         ObjRef oref = RemotingServices.Marshal (AppDomain.CurrentDomain, null, typeof (AppDomain));
924                         return CADSerializer.SerializeObject (oref).GetBuffer();
925                 }
926
927                 internal void ProcessMessageInDomain (byte[] arrRequest, CADMethodCallMessage cadMsg,
928                                                       out byte[] arrResponse, out CADMethodReturnMessage cadMrm)
929                 {
930                         IMessage reqDomMsg;
931
932                         if (null != arrRequest)
933                                 reqDomMsg = CADSerializer.DeserializeMessage (new MemoryStream(arrRequest), null);
934                         else
935                                 reqDomMsg = new MethodCall (cadMsg);
936
937                         IMessage retDomMsg = ChannelServices.SyncDispatchMessage (reqDomMsg);
938
939                         cadMrm = CADMethodReturnMessage.Create (retDomMsg);
940                         if (null == cadMrm) {
941                                 arrResponse = CADSerializer.SerializeMessage (retDomMsg).GetBuffer();
942                         } 
943                         else
944                                 arrResponse = null;
945                 }
946
947                 // End of methods called from the runtime
948                 
949 #if BOOTSTRAP_WITH_OLDLIB
950                 // older MCS/corlib returns:
951                 // _AppDomain.cs(138) error CS0592: Attribute 'SecurityPermission' is not valid on this declaration type.
952                 // It is valid on 'assembly' 'class' 'constructor' 'method' 'struct'  declarations only.
953                 public event AssemblyLoadEventHandler AssemblyLoad;
954
955                 public event ResolveEventHandler AssemblyResolve;
956
957                 public event EventHandler DomainUnload;
958
959                 public event EventHandler ProcessExit;
960
961                 public event ResolveEventHandler ResourceResolve;
962
963                 public event ResolveEventHandler TypeResolve;
964
965                 public event UnhandledExceptionEventHandler UnhandledException;
966 #else
967                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
968                 public event AssemblyLoadEventHandler AssemblyLoad;
969
970                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
971                 public event ResolveEventHandler AssemblyResolve;
972
973                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
974                 public event EventHandler DomainUnload;
975
976                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
977                 public event EventHandler ProcessExit;
978
979                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
980                 public event ResolveEventHandler ResourceResolve;
981
982                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
983                 public event ResolveEventHandler TypeResolve;
984
985                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
986                 public event UnhandledExceptionEventHandler UnhandledException;
987 #endif
988
989                 /* Avoid warnings for events used only by the runtime */
990                 private void DummyUse () {
991                         ProcessExit += (EventHandler)null;
992                         ResourceResolve += (ResolveEventHandler)null;
993                         UnhandledException += (UnhandledExceptionEventHandler)null;
994                 }
995
996 #if NET_2_0
997
998                 public event ResolveEventHandler ReflectionOnlyAssemblyResolve;
999                 
1000                 private ActivationContext _activation;
1001                 private ApplicationIdentity _applicationIdentity;
1002                 private AppDomainManager _domain_manager;
1003
1004                 // properties
1005
1006                 public ActivationContext ActivationContext {
1007                         get { return _activation; }
1008                 }
1009
1010                 public ApplicationIdentity ApplicationIdentity {
1011                         get { return _applicationIdentity; }
1012                 }
1013
1014                 // default is null
1015                 public AppDomainManager DomainManager {
1016                         get { return _domain_manager; }
1017                 }
1018
1019                 public int Id {
1020                         [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
1021                         get { return getDomainID (); }
1022                 }
1023
1024                 // methods
1025
1026                 [MonoTODO ("This routine only returns the parameter currently")]
1027                 [ComVisible (false)]
1028                 public string ApplyPolicy (string assemblyName)
1029                 {
1030                         if (assemblyName == null)
1031                                 throw new ArgumentNullException ("assemblyName");
1032                         if (assemblyName.Length == 0) // String.Empty
1033                                 throw new ArgumentException ("assemblyName");
1034                         return assemblyName;
1035                 }
1036
1037                 // static methods
1038
1039                 [MonoTODO ("add support for new delegate")]
1040                 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo, string appBasePath,
1041                         string appRelativeSearchPath, bool shadowCopy, AppDomainInitializer adInit, string[] adInitArgs)
1042                 {
1043                         return CreateDomain (friendlyName, securityInfo, appBasePath, appRelativeSearchPath, shadowCopy);
1044                 }
1045
1046                 [MonoTODO ("resolve assemblyName to location")]
1047                 public int ExecuteAssemblyByName (string assemblyName)
1048                 {
1049                         return ExecuteAssemblyByName (assemblyName, null, null);
1050                 }
1051
1052                 [MonoTODO ("resolve assemblyName to location")]
1053                 public int ExecuteAssemblyByName (string assemblyName, Evidence assemblySecurity)
1054                 {
1055                         return ExecuteAssemblyByName (assemblyName, assemblySecurity, null);
1056                 }
1057
1058                 [MonoTODO ("resolve assemblyName to location")]
1059                 public int ExecuteAssemblyByName (string assemblyName, Evidence assemblySecurity, string[] args)
1060                 {
1061                         if (assemblyName == null)
1062                                 throw new ArgumentNullException ("assemblyName");
1063
1064                         AssemblyName an = new AssemblyName (assemblyName);
1065                         return ExecuteAssemblyByName (an, assemblySecurity, args);
1066                 }
1067
1068                 [MonoTODO ("assemblyName may not have a codebase")]
1069                 public int ExecuteAssemblyByName (AssemblyName assemblyName, Evidence assemblySecurity, string[] args)
1070                 {
1071                         if (assemblyName == null)
1072                                 throw new ArgumentNullException ("assemblyName");
1073
1074                         return ExecuteAssembly (assemblyName.CodeBase, assemblySecurity, args);
1075                 }
1076
1077                 public bool IsDefaultAppDomain ()
1078                 {
1079                         return Object.ReferenceEquals (this, DefaultDomain);
1080                 }
1081
1082                 public Assembly[] ReflectionOnlyGetAssemblies ()
1083                 {
1084                         return GetAssemblies (true);
1085                 }
1086 #endif
1087
1088 #if NET_1_1
1089                 void _AppDomain.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1090                 {
1091                         throw new NotImplementedException ();
1092                 }
1093
1094                 void _AppDomain.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
1095                 {
1096                         throw new NotImplementedException ();
1097                 }
1098
1099                 void _AppDomain.GetTypeInfoCount (out uint pcTInfo)
1100                 {
1101                         throw new NotImplementedException ();
1102                 }
1103
1104                 void _AppDomain.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
1105                         IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1106                 {
1107                         throw new NotImplementedException ();
1108                 }
1109 #endif
1110         }
1111 }