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