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)
10 // Sebastien Pouliot (sebastien@ximian.com)
12 // (C) 2001, 2002 Ximian, Inc. http://www.ximian.com
13 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
14 // Copyright 2011 Xamarin Inc (http://www.xamarin.com).
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System.Collections;
37 using System.Globalization;
39 using System.Reflection;
41 using System.Reflection.Emit;
43 using System.Threading;
44 using System.Runtime.CompilerServices;
45 using System.Runtime.InteropServices;
46 using System.Runtime.Remoting;
47 using System.Runtime.Remoting.Contexts;
48 using System.Runtime.Remoting.Channels;
49 using System.Runtime.Remoting.Messaging;
50 using System.Security;
51 using System.Security.Permissions;
52 using System.Security.Policy;
53 using System.Security.Principal;
54 using System.Configuration.Assemblies;
56 using System.Collections.Generic;
57 using System.Runtime.ConstrainedExecution;
63 #if !NET_2_1 || MOONLIGHT
64 [ComDefaultInterface (typeof (_AppDomain))]
66 [ClassInterface(ClassInterfaceType.None)]
67 [StructLayout (LayoutKind.Sequential)]
69 public sealed class AppDomain : _AppDomain {
71 public sealed class AppDomain : MarshalByRefObject, _AppDomain {
73 public sealed class AppDomain : MarshalByRefObject, _AppDomain, IEvidenceFactory {
75 #pragma warning disable 169
76 #region Sync with object-internals.h
77 IntPtr _mono_app_domain;
79 #pragma warning restore 169
80 static string _process_guid;
83 static Hashtable type_resolve_in_progress;
86 static Hashtable assembly_resolve_in_progress;
89 static Hashtable assembly_resolve_in_progress_refonly;
92 private Evidence _evidence;
93 private PermissionSet _granted;
96 private PrincipalPolicy _principalPolicy;
99 private static IPrincipal _principal;
101 static AppDomain default_domain;
107 [MethodImplAttribute (MethodImplOptions.InternalCall)]
108 private extern AppDomainSetup getSetup ();
113 AppDomainSetup SetupInformationNoCopy {
114 get { return getSetup (); }
117 public AppDomainSetup SetupInformation {
119 AppDomainSetup setup = getSetup ();
120 return new AppDomainSetup (setup);
126 public ApplicationTrust ApplicationTrust {
127 get { throw new NotImplementedException (); }
131 public string BaseDirectory {
133 string path = SetupInformationNoCopy.ApplicationBase;
135 if (SecurityManager.SecurityEnabled && (path != null) && (path.Length > 0)) {
136 // we cannot divulge local file informations
137 new FileIOPermission (FileIOPermissionAccess.PathDiscovery, path).Demand ();
144 public string RelativeSearchPath {
146 string path = SetupInformationNoCopy.PrivateBinPath;
148 if (SecurityManager.SecurityEnabled && (path != null) && (path.Length > 0)) {
149 // we cannot divulge local file informations
150 new FileIOPermission (FileIOPermissionAccess.PathDiscovery, path).Demand ();
157 public string DynamicDirectory {
159 AppDomainSetup setup = SetupInformationNoCopy;
160 if (setup.DynamicBase == null)
163 string path = Path.Combine (setup.DynamicBase, setup.ApplicationName);
165 if (SecurityManager.SecurityEnabled && (path != null) && (path.Length > 0)) {
166 // we cannot divulge local file informations
167 new FileIOPermission (FileIOPermissionAccess.PathDiscovery, path).Demand ();
174 public bool ShadowCopyFiles {
176 return (SetupInformationNoCopy.ShadowCopyFiles == "true");
181 [MethodImplAttribute (MethodImplOptions.InternalCall)]
182 private extern string getFriendlyName ();
184 public string FriendlyName {
186 return getFriendlyName ();
190 public Evidence Evidence {
192 // if the host (runtime) hasn't provided it's own evidence...
193 if (_evidence == null) {
194 // ... we will provide our own
196 // the executed assembly from the "default" appdomain
197 // or null if we're not in the default appdomain or
198 // if there is no entry assembly (embedded mono)
199 Assembly a = Assembly.GetEntryAssembly ();
201 if (this == DefaultDomain)
203 return new Evidence ();
205 _evidence = AppDomain.DefaultDomain.Evidence;
207 _evidence = Evidence.GetDefaultHostEvidence (a);
211 return new Evidence (_evidence); // return a copy
215 internal IPrincipal DefaultPrincipal {
217 if (_principal == null) {
218 switch (_principalPolicy) {
219 case PrincipalPolicy.UnauthenticatedPrincipal:
220 _principal = new GenericPrincipal (
221 new GenericIdentity (String.Empty, String.Empty), null);
223 case PrincipalPolicy.WindowsPrincipal:
224 _principal = new WindowsPrincipal (WindowsIdentity.GetCurrent ());
232 // for AppDomain there is only an allowed (i.e. granted) set
233 // http://msdn.microsoft.com/library/en-us/cpguide/html/cpcondetermininggrantedpermissions.asp
234 internal PermissionSet GrantedPermissionSet {
235 get { return _granted; }
240 public PermissionSet PermissionSet {
241 get { return _granted ?? (_granted = new PermissionSet (PermissionState.Unrestricted)); }
245 [MethodImplAttribute (MethodImplOptions.InternalCall)]
246 private static extern AppDomain getCurDomain ();
248 public static AppDomain CurrentDomain {
250 return getCurDomain ();
254 [MethodImplAttribute (MethodImplOptions.InternalCall)]
255 private static extern AppDomain getRootDomain ();
257 internal static AppDomain DefaultDomain {
259 if (default_domain == null) {
260 AppDomain rd = getRootDomain ();
261 if (rd == CurrentDomain)
264 default_domain = (AppDomain) RemotingServices.GetDomainProxy (rd);
266 return default_domain;
272 [Obsolete ("AppDomain.AppendPrivatePath has been deprecated. Please investigate the use of AppDomainSetup.PrivateBinPath instead.")]
273 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
274 public void AppendPrivatePath (string path)
276 if (path == null || path.Length == 0)
279 AppDomainSetup setup = SetupInformationNoCopy;
281 string pp = setup.PrivateBinPath;
282 if (pp == null || pp.Length == 0) {
283 setup.PrivateBinPath = path;
288 if (pp [pp.Length - 1] != Path.PathSeparator)
289 pp += Path.PathSeparator;
291 setup.PrivateBinPath = pp + path;
294 [Obsolete ("AppDomain.ClearPrivatePath has been deprecated. Please investigate the use of AppDomainSetup.PrivateBinPath instead.")]
295 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
296 public void ClearPrivatePath ()
298 SetupInformationNoCopy.PrivateBinPath = String.Empty;
301 [Obsolete ("Use AppDomainSetup.ShadowCopyDirectories")]
302 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
303 public void ClearShadowCopyPath ()
305 SetupInformationNoCopy.ShadowCopyDirectories = String.Empty;
309 public ObjectHandle CreateComInstanceFrom (string assemblyName, string typeName)
311 return Activator.CreateComInstanceFrom (assemblyName, typeName);
314 public ObjectHandle CreateComInstanceFrom (string assemblyFile, string typeName,
315 byte [] hashValue, AssemblyHashAlgorithm hashAlgorithm)
317 return Activator.CreateComInstanceFrom (assemblyFile, typeName, hashValue ,hashAlgorithm);
322 public ObjectHandle CreateInstance (string assemblyName, string typeName)
324 if (assemblyName == null)
325 throw new ArgumentNullException ("assemblyName");
327 return Activator.CreateInstance (assemblyName, typeName);
330 public ObjectHandle CreateInstance (string assemblyName, string typeName, object[] activationAttributes)
332 if (assemblyName == null)
333 throw new ArgumentNullException ("assemblyName");
335 return Activator.CreateInstance (assemblyName, typeName, activationAttributes);
339 [Obsolete ("Use an overload that does not take an Evidence parameter")]
341 public ObjectHandle CreateInstance (string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr,
342 Binder binder, object[] args, CultureInfo culture, object[] activationAttributes,
343 Evidence securityAttributes)
345 if (assemblyName == null)
346 throw new ArgumentNullException ("assemblyName");
348 return Activator.CreateInstance (assemblyName, typeName, ignoreCase, bindingAttr, binder, args,
349 culture, activationAttributes, securityAttributes);
352 public object CreateInstanceAndUnwrap (string assemblyName, string typeName)
354 ObjectHandle oh = CreateInstance (assemblyName, typeName);
355 return (oh != null) ? oh.Unwrap () : null;
358 public object CreateInstanceAndUnwrap (string assemblyName, string typeName, object [] activationAttributes)
360 ObjectHandle oh = CreateInstance (assemblyName, typeName, activationAttributes);
361 return (oh != null) ? oh.Unwrap () : null;
365 [Obsolete ("Use an overload that does not take an Evidence parameter")]
367 public object CreateInstanceAndUnwrap (string assemblyName, string typeName, bool ignoreCase,
368 BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture,
369 object[] activationAttributes, Evidence securityAttributes)
371 ObjectHandle oh = CreateInstance (assemblyName, typeName, ignoreCase, bindingAttr, binder, args,
372 culture, activationAttributes, securityAttributes);
373 return (oh != null) ? oh.Unwrap () : null;
377 public ObjectHandle CreateInstance (string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr,
378 Binder binder, object[] args, CultureInfo culture, object[] activationAttributes)
380 if (assemblyName == null)
381 throw new ArgumentNullException ("assemblyName");
383 return Activator.CreateInstance (assemblyName, typeName, ignoreCase, bindingAttr, binder, args,
384 culture, activationAttributes, null);
386 public object CreateInstanceAndUnwrap (string assemblyName, string typeName, bool ignoreCase,
387 BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture,
388 object[] activationAttributes)
390 ObjectHandle oh = CreateInstance (assemblyName, typeName, ignoreCase, bindingAttr, binder, args,
391 culture, activationAttributes);
392 return (oh != null) ? oh.Unwrap () : null;
395 public ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase,
396 BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture,
397 object[] activationAttributes)
399 if (assemblyFile == null)
400 throw new ArgumentNullException ("assemblyFile");
402 return Activator.CreateInstanceFrom (assemblyFile, typeName, ignoreCase, bindingAttr, binder, args,
403 culture, activationAttributes, null);
406 public object CreateInstanceFromAndUnwrap (string assemblyFile, string typeName, bool ignoreCase,
407 BindingFlags bindingAttr, Binder binder, object[] args,
408 CultureInfo culture, object[] activationAttributes)
410 ObjectHandle oh = CreateInstanceFrom (assemblyFile, typeName, ignoreCase, bindingAttr, binder, args,
411 culture, activationAttributes);
413 return (oh != null) ? oh.Unwrap () : null;
417 public ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName)
419 if (assemblyFile == null)
420 throw new ArgumentNullException ("assemblyFile");
422 return Activator.CreateInstanceFrom (assemblyFile, typeName);
425 public ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, object[] activationAttributes)
427 if (assemblyFile == null)
428 throw new ArgumentNullException ("assemblyFile");
430 return Activator.CreateInstanceFrom (assemblyFile, typeName, activationAttributes);
434 [Obsolete ("Use an overload that does not take an Evidence parameter")]
436 public ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase,
437 BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture,
438 object[] activationAttributes, Evidence securityAttributes)
440 if (assemblyFile == null)
441 throw new ArgumentNullException ("assemblyFile");
443 return Activator.CreateInstanceFrom (assemblyFile, typeName, ignoreCase, bindingAttr, binder, args,
444 culture, activationAttributes, securityAttributes);
447 public object CreateInstanceFromAndUnwrap (string assemblyName, string typeName)
449 ObjectHandle oh = CreateInstanceFrom (assemblyName, typeName);
450 return (oh != null) ? oh.Unwrap () : null;
453 public object CreateInstanceFromAndUnwrap (string assemblyName, string typeName, object [] activationAttributes)
455 ObjectHandle oh = CreateInstanceFrom (assemblyName, typeName, activationAttributes);
456 return (oh != null) ? oh.Unwrap () : null;
460 [Obsolete ("Use an overload that does not take an Evidence parameter")]
462 public object CreateInstanceFromAndUnwrap (string assemblyName, string typeName, bool ignoreCase,
463 BindingFlags bindingAttr, Binder binder, object[] args,
464 CultureInfo culture, object[] activationAttributes,
465 Evidence securityAttributes)
467 ObjectHandle oh = CreateInstanceFrom (assemblyName, typeName, ignoreCase, bindingAttr, binder, args,
468 culture, activationAttributes, securityAttributes);
470 return (oh != null) ? oh.Unwrap () : null;
473 #if !FULL_AOT_RUNTIME
474 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access)
476 return DefineDynamicAssembly (name, access, null, null, null, null, null, false);
480 [Obsolete ("Declarative security for assembly level is no longer enforced")]
482 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, Evidence evidence)
484 return DefineDynamicAssembly (name, access, null, evidence, null, null, null, false);
487 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir)
489 return DefineDynamicAssembly (name, access, dir, null, null, null, null, false);
493 [Obsolete ("Declarative security for assembly level is no longer enforced")]
495 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
498 return DefineDynamicAssembly (name, access, dir, evidence, null, null, null, false);
502 [Obsolete ("Declarative security for assembly level is no longer enforced")]
504 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access,
505 PermissionSet requiredPermissions,
506 PermissionSet optionalPermissions,
507 PermissionSet refusedPermissions)
509 return DefineDynamicAssembly (name, access, null, null, requiredPermissions, optionalPermissions,
510 refusedPermissions, false);
514 [Obsolete ("Declarative security for assembly level is no longer enforced")]
516 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, Evidence evidence,
517 PermissionSet requiredPermissions,
518 PermissionSet optionalPermissions,
519 PermissionSet refusedPermissions)
521 return DefineDynamicAssembly (name, access, null, evidence, requiredPermissions, optionalPermissions,
522 refusedPermissions, false);
526 [Obsolete ("Declarative security for assembly level is no longer enforced")]
528 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
529 PermissionSet requiredPermissions,
530 PermissionSet optionalPermissions,
531 PermissionSet refusedPermissions)
533 return DefineDynamicAssembly (name, access, dir, null, requiredPermissions, optionalPermissions,
534 refusedPermissions, false);
538 [Obsolete ("Declarative security for assembly level is no longer enforced")]
540 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
542 PermissionSet requiredPermissions,
543 PermissionSet optionalPermissions,
544 PermissionSet refusedPermissions)
546 return DefineDynamicAssembly (name, access, dir, evidence, requiredPermissions, optionalPermissions,
547 refusedPermissions, false);
551 [Obsolete ("Declarative security for assembly level is no longer enforced")]
553 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
555 PermissionSet requiredPermissions,
556 PermissionSet optionalPermissions,
557 PermissionSet refusedPermissions, bool isSynchronized)
560 throw new ArgumentNullException ("name");
561 ValidateAssemblyName (name.Name);
563 // FIXME: examine all other parameters
565 AssemblyBuilder ab = new AssemblyBuilder (name, dir, access, false);
566 ab.AddPermissionRequests (requiredPermissions, optionalPermissions, refusedPermissions);
572 [Obsolete ("Declarative security for assembly level is no longer enforced")]
574 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
576 PermissionSet requiredPermissions,
577 PermissionSet optionalPermissions,
578 PermissionSet refusedPermissions, bool isSynchronized, IEnumerable<CustomAttributeBuilder> assemblyAttributes)
580 AssemblyBuilder ab = DefineDynamicAssembly (name, access, dir, evidence, requiredPermissions, optionalPermissions, refusedPermissions, isSynchronized);
581 if (assemblyAttributes != null)
582 foreach (CustomAttributeBuilder cb in assemblyAttributes) {
583 ab.SetCustomAttribute (cb);
589 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, IEnumerable<CustomAttributeBuilder> assemblyAttributes)
591 return DefineDynamicAssembly (name, access, null, null, null, null, null, false, assemblyAttributes);
595 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir, bool isSynchronized, IEnumerable<CustomAttributeBuilder> assemblyAttributes)
597 return DefineDynamicAssembly (name, access, dir, null, null, null, null, isSynchronized, assemblyAttributes);
600 [MonoLimitation ("The argument securityContextSource is ignored")]
601 public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, IEnumerable<CustomAttributeBuilder> assemblyAttributes, SecurityContextSource securityContextSource)
603 return DefineDynamicAssembly (name, access, assemblyAttributes);
607 internal AssemblyBuilder DefineInternalDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access)
609 return new AssemblyBuilder (name, null, access, true);
614 // AppDomain.DoCallBack works because AppDomain is a MarshalByRefObject
615 // so, when you call AppDomain.DoCallBack, that's a remote call
617 public void DoCallBack (CrossAppDomainDelegate callBackDelegate)
619 if (callBackDelegate != null)
623 public int ExecuteAssembly (string assemblyFile)
625 return ExecuteAssembly (assemblyFile, (Evidence)null, null);
629 [Obsolete ("Use an overload that does not take an Evidence parameter")]
631 public int ExecuteAssembly (string assemblyFile, Evidence assemblySecurity)
633 return ExecuteAssembly (assemblyFile, assemblySecurity, null);
637 [Obsolete ("Use an overload that does not take an Evidence parameter")]
639 public int ExecuteAssembly (string assemblyFile, Evidence assemblySecurity, string[] args)
641 Assembly a = Assembly.LoadFrom (assemblyFile, assemblySecurity);
642 return ExecuteAssemblyInternal (a, args);
646 [Obsolete ("Use an overload that does not take an Evidence parameter")]
648 public int ExecuteAssembly (string assemblyFile, Evidence assemblySecurity, string[] args, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
650 Assembly a = Assembly.LoadFrom (assemblyFile, assemblySecurity, hashValue, hashAlgorithm);
651 return ExecuteAssemblyInternal (a, args);
656 public int ExecuteAssembly (string assemblyFile, string[] args)
658 Assembly a = Assembly.LoadFrom (assemblyFile, null);
659 return ExecuteAssemblyInternal (a, args);
662 public int ExecuteAssembly (string assemblyFile, string[] args, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
664 Assembly a = Assembly.LoadFrom (assemblyFile, null, hashValue, hashAlgorithm);
665 return ExecuteAssemblyInternal (a, args);
669 int ExecuteAssemblyInternal (Assembly a, string[] args)
671 if (a.EntryPoint == null)
672 throw new MissingMethodException ("Entry point not found in assembly '" + a.FullName + "'.");
673 return ExecuteAssembly (a, args);
676 [MethodImplAttribute (MethodImplOptions.InternalCall)]
677 private extern int ExecuteAssembly (Assembly a, string[] args);
679 [MethodImplAttribute (MethodImplOptions.InternalCall)]
680 private extern Assembly [] GetAssemblies (bool refOnly);
682 public Assembly [] GetAssemblies ()
684 return GetAssemblies (false);
687 [MethodImplAttribute (MethodImplOptions.InternalCall)]
688 public extern object GetData (string name);
690 public new Type GetType()
692 return base.GetType ();
696 public override object InitializeLifetimeService ()
702 [MethodImplAttribute (MethodImplOptions.InternalCall)]
703 internal extern Assembly LoadAssembly (string assemblyRef, Evidence securityEvidence, bool refOnly);
705 public Assembly Load (AssemblyName assemblyRef)
707 return Load (assemblyRef, null);
710 internal Assembly LoadSatellite (AssemblyName assemblyRef, bool throwOnError)
712 if (assemblyRef == null)
713 throw new ArgumentNullException ("assemblyRef");
715 Assembly result = LoadAssembly (assemblyRef.FullName, null, false);
716 if (result == null && throwOnError)
717 throw new FileNotFoundException (null, assemblyRef.Name);
722 [Obsolete ("Use an overload that does not take an Evidence parameter")]
724 public Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
726 if (assemblyRef == null)
727 throw new ArgumentNullException ("assemblyRef");
729 if (assemblyRef.Name == null || assemblyRef.Name.Length == 0) {
730 if (assemblyRef.CodeBase != null)
731 return Assembly.LoadFrom (assemblyRef.CodeBase, assemblySecurity);
733 throw new ArgumentException (Locale.GetText ("assemblyRef.Name cannot be empty."), "assemblyRef");
736 Assembly assembly = LoadAssembly (assemblyRef.FullName, assemblySecurity, false);
737 if (assembly != null)
740 if (assemblyRef.CodeBase == null)
741 throw new FileNotFoundException (null, assemblyRef.Name);
743 string cb = assemblyRef.CodeBase;
744 if (cb.ToLower (CultureInfo.InvariantCulture).StartsWith ("file://"))
745 cb = new Mono.Security.Uri (cb).LocalPath;
748 assembly = Assembly.LoadFrom (cb, assemblySecurity);
750 throw new FileNotFoundException (null, assemblyRef.Name);
752 AssemblyName aname = assembly.GetName ();
753 // Name, version, culture, publickeytoken. Anything else?
754 if (assemblyRef.Name != aname.Name)
755 throw new FileNotFoundException (null, assemblyRef.Name);
757 if (assemblyRef.Version != null && assemblyRef.Version != new Version (0, 0, 0, 0) && assemblyRef.Version != aname.Version)
758 throw new FileNotFoundException (null, assemblyRef.Name);
760 if (assemblyRef.CultureInfo != null && assemblyRef.CultureInfo.Equals (aname))
761 throw new FileNotFoundException (null, assemblyRef.Name);
763 byte [] pt = assemblyRef.GetPublicKeyToken ();
764 if (pt != null && pt.Length != 0) {
765 byte [] loaded_pt = aname.GetPublicKeyToken ();
766 if (loaded_pt == null || (pt.Length != loaded_pt.Length))
767 throw new FileNotFoundException (null, assemblyRef.Name);
768 for (int i = pt.Length - 1; i >= 0; i--)
769 if (loaded_pt [i] != pt [i])
770 throw new FileNotFoundException (null, assemblyRef.Name);
775 public Assembly Load (string assemblyString)
777 return Load (assemblyString, null, false);
781 [Obsolete ("Use an overload that does not take an Evidence parameter")]
783 public Assembly Load (string assemblyString, Evidence assemblySecurity)
785 return Load (assemblyString, assemblySecurity, false);
788 internal Assembly Load (string assemblyString, Evidence assemblySecurity, bool refonly)
790 if (assemblyString == null)
791 throw new ArgumentNullException ("assemblyString");
793 if (assemblyString.Length == 0)
794 throw new ArgumentException ("assemblyString cannot have zero length");
796 Assembly assembly = LoadAssembly (assemblyString, assemblySecurity, refonly);
797 if (assembly == null)
798 throw new FileNotFoundException (null, assemblyString);
802 public Assembly Load (byte[] rawAssembly)
804 return Load (rawAssembly, null, null);
807 public Assembly Load (byte[] rawAssembly, byte[] rawSymbolStore)
809 return Load (rawAssembly, rawSymbolStore, null);
812 [MethodImplAttribute (MethodImplOptions.InternalCall)]
813 internal extern Assembly LoadAssemblyRaw (byte[] rawAssembly, byte[] rawSymbolStore, Evidence securityEvidence, bool refonly);
816 [Obsolete ("Use an overload that does not take an Evidence parameter")]
818 public Assembly Load (byte[] rawAssembly, byte[] rawSymbolStore, Evidence securityEvidence)
820 return Load (rawAssembly, rawSymbolStore, securityEvidence, false);
823 internal Assembly Load (byte [] rawAssembly, byte [] rawSymbolStore, Evidence securityEvidence, bool refonly)
825 if (rawAssembly == null)
826 throw new ArgumentNullException ("rawAssembly");
828 Assembly assembly = LoadAssemblyRaw (rawAssembly, rawSymbolStore, securityEvidence, refonly);
829 assembly.FromByteArray = true;
834 [Obsolete ("AppDomain policy levels are obsolete")]
836 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
837 public void SetAppDomainPolicy (PolicyLevel domainPolicy)
839 if (domainPolicy == null)
840 throw new ArgumentNullException ("domainPolicy");
841 if (_granted != null) {
842 throw new PolicyException (Locale.GetText (
843 "An AppDomain policy is already specified."));
845 if (IsFinalizingForUnload ())
846 throw new AppDomainUnloadedException ();
848 PolicyStatement ps = domainPolicy.Resolve (_evidence);
849 _granted = ps.PermissionSet;
852 [Obsolete ("Use AppDomainSetup.SetCachePath")]
853 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
854 public void SetCachePath (string path)
856 SetupInformationNoCopy.CachePath = path;
859 [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
860 public void SetPrincipalPolicy (PrincipalPolicy policy)
862 if (IsFinalizingForUnload ())
863 throw new AppDomainUnloadedException ();
865 _principalPolicy = policy;
869 [Obsolete ("Use AppDomainSetup.ShadowCopyFiles")]
870 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
871 public void SetShadowCopyFiles()
873 SetupInformationNoCopy.ShadowCopyFiles = "true";
876 [Obsolete ("Use AppDomainSetup.ShadowCopyDirectories")]
877 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
878 public void SetShadowCopyPath (string path)
880 SetupInformationNoCopy.ShadowCopyDirectories = path;
883 [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
884 public void SetThreadPrincipal (IPrincipal principal)
886 if (principal == null)
887 throw new ArgumentNullException ("principal");
888 if (_principal != null)
889 throw new PolicyException (Locale.GetText ("principal already present."));
890 if (IsFinalizingForUnload ())
891 throw new AppDomainUnloadedException ();
893 _principal = principal;
896 [MethodImplAttribute (MethodImplOptions.InternalCall)]
897 private static extern AppDomain InternalSetDomainByID (int domain_id);
899 // Changes the active domain and returns the old domain
900 [MethodImplAttribute (MethodImplOptions.InternalCall)]
901 private static extern AppDomain InternalSetDomain (AppDomain context);
903 // Notifies the runtime that this thread references 'domain'.
904 [MethodImplAttribute (MethodImplOptions.InternalCall)]
905 internal static extern void InternalPushDomainRef (AppDomain domain);
907 [MethodImplAttribute (MethodImplOptions.InternalCall)]
908 internal static extern void InternalPushDomainRefByID (int domain_id);
910 // Undoes the effect of the last PushDomainRef call
911 [MethodImplAttribute (MethodImplOptions.InternalCall)]
912 internal static extern void InternalPopDomainRef ();
914 // Changes the active context and returns the old context
915 [MethodImplAttribute (MethodImplOptions.InternalCall)]
916 internal static extern Context InternalSetContext (Context context);
918 // Returns the current context
919 [MethodImplAttribute (MethodImplOptions.InternalCall)]
920 internal static extern Context InternalGetContext ();
922 // Returns the current context
923 [MethodImplAttribute (MethodImplOptions.InternalCall)]
924 internal static extern Context InternalGetDefaultContext ();
926 [MethodImplAttribute (MethodImplOptions.InternalCall)]
927 internal static extern string InternalGetProcessGuid (string newguid);
929 // This method is handled specially by the runtime
930 // It is the only managed method which is allowed to set the current
932 internal static object InvokeInDomain (AppDomain domain, MethodInfo method, object obj, object [] args)
934 AppDomain current = CurrentDomain;
939 InternalPushDomainRef (domain);
941 InternalSetDomain (domain);
942 object o = ((MonoMethod) method).InternalInvoke (obj, args, out exc);
948 InternalSetDomain (current);
950 InternalPopDomainRef ();
954 internal static object InvokeInDomainByID (int domain_id, MethodInfo method, object obj, object [] args)
956 AppDomain current = CurrentDomain;
961 InternalPushDomainRefByID (domain_id);
963 InternalSetDomainByID (domain_id);
964 object o = ((MonoMethod) method).InternalInvoke (obj, args, out exc);
970 InternalSetDomain (current);
972 InternalPopDomainRef ();
976 internal static String GetProcessGuid ()
978 if (_process_guid == null) {
979 _process_guid = InternalGetProcessGuid (Guid.NewGuid().ToString ());
981 return _process_guid;
986 public static AppDomain CreateDomain (string friendlyName)
988 return CreateDomain (friendlyName, null, null);
991 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo)
993 return CreateDomain (friendlyName, securityInfo, null);
996 [MethodImplAttribute (MethodImplOptions.InternalCall)]
997 private static extern AppDomain createDomain (string friendlyName, AppDomainSetup info);
999 [MonoLimitationAttribute ("Currently it does not allow the setup in the other domain")]
1000 [SecurityPermission (SecurityAction.Demand, ControlAppDomain = true)]
1001 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo, AppDomainSetup info)
1003 if (friendlyName == null)
1004 throw new System.ArgumentNullException ("friendlyName");
1006 AppDomain def = AppDomain.DefaultDomain;
1008 // if null, get default domain's SetupInformation
1010 info = new AppDomainSetup (); // we're default!
1012 info = def.SetupInformation;
1015 info = new AppDomainSetup (info); // copy
1017 // todo: allow setup in the other domain
1019 if (!info.Equals (def.SetupInformation)) {
1020 // If not specified use default domain's app base.
1021 if (info.ApplicationBase == null)
1022 info.ApplicationBase = def.SetupInformation.ApplicationBase;
1023 if (info.ConfigurationFile == null)
1024 info.ConfigurationFile = Path.GetFileName (def.SetupInformation.ConfigurationFile);
1026 } else if (info.ConfigurationFile == null)
1027 info.ConfigurationFile = "[I don't have a config file]";
1030 if (info.AppDomainInitializer != null) {
1031 if (!info.AppDomainInitializer.Method.IsStatic)
1032 throw new ArgumentException ("Non-static methods cannot be invoked as an appdomain initializer");
1036 info.SerializeNonPrimitives ();
1038 AppDomain ad = (AppDomain) RemotingServices.GetDomainProxy (createDomain (friendlyName, info));
1039 if (securityInfo == null) {
1040 // get default domain's Evidence (unless we're are the default!)
1042 ad._evidence = null; // we'll get them later (GetEntryAssembly)
1044 ad._evidence = def.Evidence; // new (shallow) copy
1047 ad._evidence = new Evidence (securityInfo); // copy
1050 if (info.AppDomainInitializer != null) {
1051 Loader loader = new Loader (
1052 info.AppDomainInitializer.Method.DeclaringType.Assembly.Location);
1053 ad.DoCallBack (loader.Load);
1055 Initializer initializer = new Initializer (
1056 info.AppDomainInitializer,
1057 info.AppDomainInitializerArguments);
1058 ad.DoCallBack (initializer.Initialize);
1071 public Loader (string assembly)
1073 this.assembly = assembly;
1078 Assembly.LoadFrom (assembly);
1085 AppDomainInitializer initializer;
1086 string [] arguments;
1088 public Initializer (AppDomainInitializer initializer, string [] arguments)
1090 this.initializer = initializer;
1091 this.arguments = arguments;
1094 public void Initialize ()
1096 initializer (arguments);
1101 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo,string appBasePath,
1102 string appRelativeSearchPath, bool shadowCopyFiles)
1104 return CreateDomain (friendlyName, securityInfo, CreateDomainSetup (appBasePath, appRelativeSearchPath, shadowCopyFiles));
1108 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo, AppDomainSetup info,
1109 PermissionSet grantSet, params StrongName [] fullTrustAssemblies)
1112 throw new ArgumentNullException ("info");
1114 info.ApplicationTrust = new ApplicationTrust (grantSet, fullTrustAssemblies ?? new StrongName [0]);
1115 return CreateDomain (friendlyName, securityInfo, info);
1119 static AppDomainSetup CreateDomainSetup (string appBasePath, string appRelativeSearchPath, bool shadowCopyFiles)
1121 AppDomainSetup info = new AppDomainSetup ();
1123 info.ApplicationBase = appBasePath;
1124 info.PrivateBinPath = appRelativeSearchPath;
1126 if (shadowCopyFiles)
1127 info.ShadowCopyFiles = "true";
1129 info.ShadowCopyFiles = "false";
1135 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1136 private static extern bool InternalIsFinalizingForUnload (int domain_id);
1138 public bool IsFinalizingForUnload()
1140 return InternalIsFinalizingForUnload (getDomainID ());
1143 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1144 static extern void InternalUnload (int domain_id);
1146 // We do this because if the domain is a transparant proxy this
1147 // will still return the correct domain id.
1148 private int getDomainID ()
1150 return Thread.GetDomainID ();
1153 [SecurityPermission (SecurityAction.Demand, ControlAppDomain = true)]
1154 [ReliabilityContractAttribute (Consistency.MayCorruptAppDomain, Cer.MayFail)]
1155 public static void Unload (AppDomain domain)
1158 throw new ArgumentNullException ("domain");
1160 InternalUnload (domain.getDomainID());
1163 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1164 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1165 public extern void SetData (string name, object data);
1167 [MonoLimitation ("The permission field is ignored")]
1168 public void SetData (string name, object data, IPermission permission)
1170 SetData (name, data);
1174 [Obsolete ("Use AppDomainSetup.DynamicBase")]
1175 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1176 public void SetDynamicBase (string path)
1178 SetupInformationNoCopy.DynamicBase = path;
1182 [Obsolete ("AppDomain.GetCurrentThreadId has been deprecated"
1183 + " because it does not provide a stable Id when managed"
1184 + " threads are running on fibers (aka lightweight"
1185 + " threads). To get a stable identifier for a managed"
1186 + " thread, use the ManagedThreadId property on Thread.'")]
1187 public static int GetCurrentThreadId ()
1189 return Thread.CurrentThreadId;
1192 public override string ToString ()
1195 return getFriendlyName ();
1197 StringBuilder sb = new StringBuilder ("Name:");
1198 sb.AppendLine (FriendlyName);
1199 sb.AppendLine ("There are no context policies.");
1200 return sb.ToString ();
1204 private static void ValidateAssemblyName (string name)
1206 if (name == null || name.Length == 0)
1207 throw new ArgumentException ("The Name of " +
1208 "AssemblyName cannot be null or a " +
1209 "zero-length string.");
1211 bool isValid = true;
1213 for (int i = 0; i < name.Length; i++) {
1216 // do not allow leading whitespace
1217 if (i == 0 && char.IsWhiteSpace (c)) {
1222 // do not allow /,\ or : in name
1223 if (c == '/' || c == '\\' || c == ':') {
1230 throw new ArgumentException ("The Name of " +
1231 "AssemblyName cannot start with " +
1232 "whitespace, or contain '/', '\\' " +
1236 // The following methods are called from the runtime. Don't change signatures.
1237 #pragma warning disable 169
1238 private void DoAssemblyLoad (Assembly assembly)
1240 if (AssemblyLoad == null)
1243 AssemblyLoad (this, new AssemblyLoadEventArgs (assembly));
1246 private Assembly DoAssemblyResolve (string name, bool refonly)
1248 ResolveEventHandler del;
1251 del = ReflectionOnlyAssemblyResolve;
1253 del = AssemblyResolve;
1255 del = AssemblyResolve;
1260 /* Prevent infinite recursion */
1263 ht = assembly_resolve_in_progress_refonly;
1265 ht = new Hashtable ();
1266 assembly_resolve_in_progress_refonly = ht;
1269 ht = assembly_resolve_in_progress;
1271 ht = new Hashtable ();
1272 assembly_resolve_in_progress = ht;
1276 string s = (string) ht [name];
1281 Delegate[] invocation_list = del.GetInvocationList ();
1283 foreach (Delegate eh in invocation_list) {
1284 ResolveEventHandler handler = (ResolveEventHandler) eh;
1285 Assembly assembly = handler (this, new ResolveEventArgs (name));
1286 if (assembly != null)
1296 internal Assembly DoTypeResolve (Object name_or_tb)
1298 if (TypeResolve == null)
1303 #if !FULL_AOT_RUNTIME
1304 if (name_or_tb is TypeBuilder)
1305 name = ((TypeBuilder) name_or_tb).FullName;
1308 name = (string) name_or_tb;
1310 /* Prevent infinite recursion */
1311 Hashtable ht = type_resolve_in_progress;
1313 ht = new Hashtable ();
1314 type_resolve_in_progress = ht;
1317 if (ht.Contains (name))
1323 foreach (Delegate d in TypeResolve.GetInvocationList ()) {
1324 ResolveEventHandler eh = (ResolveEventHandler) d;
1325 Assembly assembly = eh (this, new ResolveEventArgs (name));
1326 if (assembly != null)
1336 internal Assembly DoResourceResolve (string name, Assembly requesting) {
1337 if (ResourceResolve == null)
1340 Delegate[] invocation_list = ResourceResolve.GetInvocationList ();
1342 foreach (Delegate eh in invocation_list) {
1343 ResolveEventHandler handler = (ResolveEventHandler) eh;
1345 Assembly assembly = handler (this, new ResolveEventArgs (name, requesting));
1347 Assembly assembly = handler (this, new ResolveEventArgs (name));
1349 if (assembly != null)
1355 private void DoDomainUnload ()
1357 if (DomainUnload != null)
1358 DomainUnload(this, null);
1361 internal byte[] GetMarshalledDomainObjRef ()
1363 ObjRef oref = RemotingServices.Marshal (AppDomain.CurrentDomain, null, typeof (AppDomain));
1364 return CADSerializer.SerializeObject (oref).GetBuffer();
1367 internal void ProcessMessageInDomain (byte[] arrRequest, CADMethodCallMessage cadMsg,
1368 out byte[] arrResponse, out CADMethodReturnMessage cadMrm)
1372 if (null != arrRequest)
1373 reqDomMsg = CADSerializer.DeserializeMessage (new MemoryStream(arrRequest), null);
1375 reqDomMsg = new MethodCall (cadMsg);
1377 IMessage retDomMsg = ChannelServices.SyncDispatchMessage (reqDomMsg);
1379 cadMrm = CADMethodReturnMessage.Create (retDomMsg);
1380 if (null == cadMrm) {
1381 arrResponse = CADSerializer.SerializeMessage (retDomMsg).GetBuffer();
1387 #pragma warning restore 169
1389 // End of methods called from the runtime
1391 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1392 public event AssemblyLoadEventHandler AssemblyLoad;
1394 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1395 public event ResolveEventHandler AssemblyResolve;
1397 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1398 public event EventHandler DomainUnload;
1400 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1401 public event EventHandler ProcessExit;
1403 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1404 public event ResolveEventHandler ResourceResolve;
1406 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1407 public event ResolveEventHandler TypeResolve;
1409 [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
1410 public event UnhandledExceptionEventHandler UnhandledException;
1414 public bool IsHomogenous {
1415 get { return true; }
1419 public bool IsFullyTrusted {
1420 get { return true; }
1424 #pragma warning disable 649
1425 private AppDomainManager _domain_manager;
1426 #pragma warning restore 649
1429 public AppDomainManager DomainManager {
1430 get { return _domain_manager; }
1435 public event ResolveEventHandler ReflectionOnlyAssemblyResolve;
1437 #pragma warning disable 649
1438 private ActivationContext _activation;
1439 private ApplicationIdentity _applicationIdentity;
1440 #pragma warning restore 649
1444 public ActivationContext ActivationContext {
1445 get { return _activation; }
1448 public ApplicationIdentity ApplicationIdentity {
1449 get { return _applicationIdentity; }
1453 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
1454 get { return getDomainID (); }
1459 [MonoTODO ("This routine only returns the parameter currently")]
1460 [ComVisible (false)]
1461 public string ApplyPolicy (string assemblyName)
1463 if (assemblyName == null)
1464 throw new ArgumentNullException ("assemblyName");
1465 if (assemblyName.Length == 0) // String.Empty
1466 throw new ArgumentException ("assemblyName");
1467 return assemblyName;
1472 public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo, string appBasePath,
1473 string appRelativeSearchPath, bool shadowCopyFiles, AppDomainInitializer adInit, string[] adInitArgs)
1475 AppDomainSetup info = CreateDomainSetup (appBasePath, appRelativeSearchPath, shadowCopyFiles);
1477 info.AppDomainInitializerArguments = adInitArgs;
1478 info.AppDomainInitializer = adInit;
1480 return CreateDomain (friendlyName, securityInfo, info);
1483 public int ExecuteAssemblyByName (string assemblyName)
1485 return ExecuteAssemblyByName (assemblyName, (Evidence)null, null);
1489 [Obsolete ("Use an overload that does not take an Evidence parameter")]
1491 public int ExecuteAssemblyByName (string assemblyName, Evidence assemblySecurity)
1493 return ExecuteAssemblyByName (assemblyName, assemblySecurity, null);
1497 [Obsolete ("Use an overload that does not take an Evidence parameter")]
1499 public int ExecuteAssemblyByName (string assemblyName, Evidence assemblySecurity, params string[] args)
1501 Assembly a = Assembly.Load (assemblyName, assemblySecurity);
1503 return ExecuteAssemblyInternal (a, args);
1507 [Obsolete ("Use an overload that does not take an Evidence parameter")]
1509 public int ExecuteAssemblyByName (AssemblyName assemblyName, Evidence assemblySecurity, params string[] args)
1511 Assembly a = Assembly.Load (assemblyName, assemblySecurity);
1513 return ExecuteAssemblyInternal (a, args);
1517 public int ExecuteAssemblyByName (string assemblyName, params string[] args)
1519 Assembly a = Assembly.Load (assemblyName, null);
1521 return ExecuteAssemblyInternal (a, args);
1524 public int ExecuteAssemblyByName (AssemblyName assemblyName, params string[] args)
1526 Assembly a = Assembly.Load (assemblyName, null);
1528 return ExecuteAssemblyInternal (a, args);
1532 public bool IsDefaultAppDomain ()
1534 return Object.ReferenceEquals (this, DefaultDomain);
1537 public Assembly[] ReflectionOnlyGetAssemblies ()
1539 return GetAssemblies (true);
1544 public int ExecuteAssemblyByName (string assemblyName)
1546 // critical code in SL that we're not calling in ML
1547 throw new NotImplementedException ();
1552 void _AppDomain.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1554 throw new NotImplementedException ();
1557 void _AppDomain.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
1559 throw new NotImplementedException ();
1562 void _AppDomain.GetTypeInfoCount (out uint pcTInfo)
1564 throw new NotImplementedException ();
1567 void _AppDomain.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
1568 IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1570 throw new NotImplementedException ();
1574 #if NET_4_0 || MOONLIGHT || MOBILE
1575 List<string> compatibility_switch;
1577 public bool? IsCompatibilitySwitchSet (string value)
1580 throw new ArgumentNullException ("value");
1582 // default (at least for SL4) is to return false for unknown values (can't get a null out of it)
1583 return ((compatibility_switch != null) && compatibility_switch.Contains (value));
1586 internal void SetCompatibilitySwitch (string value)
1588 if (compatibility_switch == null)
1589 compatibility_switch = new List<string> ();
1590 compatibility_switch.Add (value);
1593 [MonoTODO ("Currently always returns false")]
1594 public static bool MonitoringIsEnabled {
1595 get { return false; }
1596 set { throw new NotImplementedException (); }
1600 public long MonitoringSurvivedMemorySize {
1601 get { throw new NotImplementedException (); }
1605 public static long MonitoringSurvivedProcessMemorySize {
1606 get { throw new NotImplementedException (); }
1610 public long MonitoringTotalAllocatedMemorySize {
1611 get { throw new NotImplementedException (); }
1615 public TimeSpan MonitoringTotalProcessorTime {
1616 get { throw new NotImplementedException (); }