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