New test.
[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                         if (info == null) {
716                                 // if null, get default domain's SetupInformation
717                                 AppDomain def = AppDomain.DefaultDomain;
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
728                         AppDomain ad = (AppDomain) RemotingServices.GetDomainProxy (createDomain (friendlyName, info));
729                         if (securityInfo == null) {
730                                 // get default domain's Evidence (unless we're are the default!)
731                                 AppDomain def = AppDomain.DefaultDomain; 
732                                 if (def == null)
733                                         ad._evidence = null;            // we'll get them later (GetEntryAssembly)
734                                 else
735                                         ad._evidence = def.Evidence;    // new (shallow) copy
736                         }
737                         else
738                                 ad._evidence = new Evidence (securityInfo);     // copy
739
740                         return ad;
741                 }
742
743                 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo,string appBasePath,
744                                                       string appRelativeSearchPath, bool shadowCopyFiles)
745                 {
746                         AppDomainSetup info = new AppDomainSetup ();
747
748                         info.ApplicationBase = appBasePath;
749                         info.PrivateBinPath = appRelativeSearchPath;
750
751                         if (shadowCopyFiles)
752                                 info.ShadowCopyFiles = "true";
753                         else
754                                 info.ShadowCopyFiles = "false";
755
756                         return CreateDomain (friendlyName, securityInfo, info);
757                 }
758
759                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
760                 private static extern bool InternalIsFinalizingForUnload (int domain_id);
761
762                 public bool IsFinalizingForUnload()
763                 {
764                         return InternalIsFinalizingForUnload (getDomainID ());
765                 }
766
767                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
768                 static extern void InternalUnload (int domain_id);
769
770                 // We do this because if the domain is a transparant proxy this
771                 // will still return the correct domain id.
772                 private int getDomainID ()
773                 {
774                         return Thread.GetDomainID ();
775                 }
776
777                 [SecurityPermission (SecurityAction.Demand, ControlAppDomain = true)]
778 #if NET_2_0
779                 [ReliabilityContractAttribute (Consistency.MayCorruptAppDomain, Cer.MayFail)]
780 #endif
781                 public static void Unload (AppDomain domain)
782                 {
783                         if (domain == null)
784                                 throw new ArgumentNullException ("domain");
785
786                         InternalUnload (domain.getDomainID());
787                 }
788
789                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
790                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
791                 public extern void SetData (string name, object data);
792
793                 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
794                 public void SetDynamicBase (string path)
795                 {
796                         SetupInformationNoCopy.DynamicBase = path;
797                 }
798
799 #if NET_2_0
800                 [Obsolete ("")]
801 #endif
802                 public static int GetCurrentThreadId ()
803                 {
804                         return Thread.CurrentThreadId;
805                 }
806
807                 public override string ToString ()
808                 {
809                         return getFriendlyName ();
810                 }
811
812                 // The following methods are called from the runtime. Don't change signatures.
813                 private void DoAssemblyLoad (Assembly assembly)
814                 {
815                         if (AssemblyLoad == null)
816                                 return;
817
818                         AssemblyLoad (this, new AssemblyLoadEventArgs (assembly));
819                 }
820
821                 private Assembly DoAssemblyResolve (string name, bool refonly)
822                 {
823 #if NET_2_0
824                         if (refonly && ReflectionOnlyAssemblyResolve == null)
825                                 return null;
826 #endif
827                         if (AssemblyResolve == null)
828                                 return null;
829                         
830                         /* Prevent infinite recursion */
831                         Hashtable ht = assembly_resolve_in_progress;
832                         if (ht == null) {
833                                 ht = new Hashtable ();
834                                 assembly_resolve_in_progress = ht;
835                         }
836
837                         Assembly ass = (Assembly) ht [name];
838 #if NET_2_0
839                         if (ass != null && (ass.ReflectionOnly == refonly))
840                                 return null;
841 #else
842                         if (ass != null)
843                                 return null;
844 #endif
845                         ht [name] = name;
846                         try {
847                                 
848 #if NET_2_0
849                                 Delegate [] invocation_list = refonly ? ReflectionOnlyAssemblyResolve.GetInvocationList () : 
850                                         AssemblyResolve.GetInvocationList ();
851 #else
852                                 Delegate [] invocation_list = AssemblyResolve.GetInvocationList ();
853 #endif
854
855                                 foreach (Delegate eh in invocation_list) {
856                                         ResolveEventHandler handler = (ResolveEventHandler) eh;
857                                         Assembly assembly = handler (this, new ResolveEventArgs (name));
858                                         if (assembly != null)
859                                                 return assembly;
860                                 }
861                                 return null;
862                         }
863                         finally {
864                                 ht.Remove (name);
865                         }
866                 }
867
868                 internal Assembly DoTypeResolve (Object name_or_tb)
869                 {
870                         if (TypeResolve == null)
871                                 return null;
872
873                         string name;
874
875                         if (name_or_tb is TypeBuilder)
876                                 name = ((TypeBuilder) name_or_tb).FullName;
877                         else
878                                 name = (string) name_or_tb;
879
880                         /* Prevent infinite recursion */
881                         Hashtable ht = type_resolve_in_progress;
882                         if (ht == null) {
883                                 ht = new Hashtable ();
884                                 type_resolve_in_progress = ht;
885                         }
886
887                         if (ht.Contains (name))
888                                 return null;
889                         else
890                                 ht [name] = name;
891
892                         try {
893                                 foreach (Delegate d in TypeResolve.GetInvocationList ()) {
894                                         ResolveEventHandler eh = (ResolveEventHandler) d;
895                                         Assembly assembly = eh (this, new ResolveEventArgs (name));
896                                         if (assembly != null)
897                                                 return assembly;
898                                 }
899                                 return null;
900                         }
901                         finally {
902                                 ht.Remove (name);
903                         }
904                 }
905
906                 private void DoDomainUnload ()
907                 {
908                         if (DomainUnload != null)
909                                 DomainUnload(this, null);
910                 }
911
912                 internal byte[] GetMarshalledDomainObjRef ()
913                 {
914                         ObjRef oref = RemotingServices.Marshal (AppDomain.CurrentDomain, null, typeof (AppDomain));
915                         return CADSerializer.SerializeObject (oref).GetBuffer();
916                 }
917
918                 internal void ProcessMessageInDomain (byte[] arrRequest, CADMethodCallMessage cadMsg,
919                                                       out byte[] arrResponse, out CADMethodReturnMessage cadMrm)
920                 {
921                         IMessage reqDomMsg;
922
923                         if (null != arrRequest)
924                                 reqDomMsg = CADSerializer.DeserializeMessage (new MemoryStream(arrRequest), null);
925                         else
926                                 reqDomMsg = new MethodCall (cadMsg);
927
928                         IMessage retDomMsg = ChannelServices.SyncDispatchMessage (reqDomMsg);
929
930                         cadMrm = CADMethodReturnMessage.Create (retDomMsg);
931                         if (null == cadMrm) {
932                                 arrResponse = CADSerializer.SerializeMessage (retDomMsg).GetBuffer();
933                         } 
934                         else
935                                 arrResponse = null;
936                 }
937
938                 // End of methods called from the runtime
939                 
940 #if BOOTSTRAP_WITH_OLDLIB
941                 // older MCS/corlib returns:
942                 // _AppDomain.cs(138) error CS0592: Attribute 'SecurityPermission' is not valid on this declaration type.
943                 // It is valid on 'assembly' 'class' 'constructor' 'method' 'struct'  declarations only.
944                 public event AssemblyLoadEventHandler AssemblyLoad;
945
946                 public event ResolveEventHandler AssemblyResolve;
947
948                 public event EventHandler DomainUnload;
949
950                 public event EventHandler ProcessExit;
951
952                 public event ResolveEventHandler ResourceResolve;
953
954                 public event ResolveEventHandler TypeResolve;
955
956                 public event UnhandledExceptionEventHandler UnhandledException;
957 #else
958                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
959                 public event AssemblyLoadEventHandler AssemblyLoad;
960
961                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
962                 public event ResolveEventHandler AssemblyResolve;
963
964                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
965                 public event EventHandler DomainUnload;
966
967                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
968                 public event EventHandler ProcessExit;
969
970                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
971                 public event ResolveEventHandler ResourceResolve;
972
973                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
974                 public event ResolveEventHandler TypeResolve;
975
976                 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
977                 public event UnhandledExceptionEventHandler UnhandledException;
978 #endif
979
980                 /* Avoid warnings for events used only by the runtime */
981                 private void DummyUse () {
982                         ProcessExit += (EventHandler)null;
983                         ResourceResolve += (ResolveEventHandler)null;
984                         UnhandledException += (UnhandledExceptionEventHandler)null;
985                 }
986
987 #if NET_2_0
988
989                 public event ResolveEventHandler ReflectionOnlyAssemblyResolve;
990                 
991                 private ActivationContext _activation;
992                 private ApplicationIdentity _applicationIdentity;
993                 private AppDomainManager _domain_manager;
994
995                 // properties
996
997                 public ActivationContext ActivationContext {
998                         get { return _activation; }
999                 }
1000
1001                 public ApplicationIdentity ApplicationIdentity {
1002                         get { return _applicationIdentity; }
1003                 }
1004
1005                 // default is null
1006                 public AppDomainManager DomainManager {
1007                         get { return _domain_manager; }
1008                 }
1009
1010                 public int Id {
1011                         [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
1012                         get { return getDomainID (); }
1013                 }
1014
1015                 // methods
1016
1017                 [MonoTODO ("This routine only returns the parameter currently")]
1018                 [ComVisible (false)]
1019                 public string ApplyPolicy (string assemblyName)
1020                 {
1021                         if (assemblyName == null)
1022                                 throw new ArgumentNullException ("assemblyName");
1023                         if (assemblyName.Length == 0) // String.Empty
1024                                 throw new ArgumentException ("assemblyName");
1025                         return assemblyName;
1026                 }
1027
1028                 // static methods
1029
1030                 [MonoTODO ("add support for new delegate")]
1031                 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo, string appBasePath,
1032                         string appRelativeSearchPath, bool shadowCopy, AppDomainInitializer adInit, string[] adInitArgs)
1033                 {
1034                         return CreateDomain (friendlyName, securityInfo, appBasePath, appRelativeSearchPath, shadowCopy);
1035                 }
1036
1037                 [MonoTODO ("resolve assemblyName to location")]
1038                 public int ExecuteAssemblyByName (string assemblyName)
1039                 {
1040                         return ExecuteAssemblyByName (assemblyName, null, null);
1041                 }
1042
1043                 [MonoTODO ("resolve assemblyName to location")]
1044                 public int ExecuteAssemblyByName (string assemblyName, Evidence assemblySecurity)
1045                 {
1046                         return ExecuteAssemblyByName (assemblyName, assemblySecurity, null);
1047                 }
1048
1049                 [MonoTODO ("resolve assemblyName to location")]
1050                 public int ExecuteAssemblyByName (string assemblyName, Evidence assemblySecurity, string[] args)
1051                 {
1052                         if (assemblyName == null)
1053                                 throw new ArgumentNullException ("assemblyName");
1054
1055                         AssemblyName an = new AssemblyName (assemblyName);
1056                         return ExecuteAssemblyByName (an, assemblySecurity, args);
1057                 }
1058
1059                 [MonoTODO ("assemblyName may not have a codebase")]
1060                 public int ExecuteAssemblyByName (AssemblyName assemblyName, Evidence assemblySecurity, string[] args)
1061                 {
1062                         if (assemblyName == null)
1063                                 throw new ArgumentNullException ("assemblyName");
1064
1065                         return ExecuteAssembly (assemblyName.CodeBase, assemblySecurity, args);
1066                 }
1067
1068                 public bool IsDefaultAppDomain ()
1069                 {
1070                         return Object.ReferenceEquals (this, DefaultDomain);
1071                 }
1072
1073                 public Assembly[] ReflectionOnlyGetAssemblies ()
1074                 {
1075                         return GetAssemblies (true);
1076                 }
1077 #endif
1078
1079 #if NET_1_1
1080                 void _AppDomain.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1081                 {
1082                         throw new NotImplementedException ();
1083                 }
1084
1085                 void _AppDomain.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
1086                 {
1087                         throw new NotImplementedException ();
1088                 }
1089
1090                 void _AppDomain.GetTypeInfoCount (out uint pcTInfo)
1091                 {
1092                         throw new NotImplementedException ();
1093                 }
1094
1095                 void _AppDomain.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
1096                         IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1097                 {
1098                         throw new NotImplementedException ();
1099                 }
1100 #endif
1101         }
1102 }