New tests.
[mono.git] / mcs / class / corlib / System.Reflection / Assembly.cs
1 //
2 // System.Reflection/Assembly.cs
3 //
4 // Author:
5 //   Paolo Molaro (lupus@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.  http://www.ximian.com
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System.Security;
31 using System.Security.Policy;
32 using System.Security.Permissions;
33 using System.Runtime.Serialization;
34 using System.Reflection.Emit;
35 using System.IO;
36 using System.Globalization;
37 using System.Runtime.CompilerServices;
38 using System.Runtime.InteropServices;
39 using System.Collections;
40 using System.Configuration.Assemblies;
41
42 using Mono.Security;
43
44 namespace System.Reflection {
45
46 #if NET_2_0
47         [ComVisible (true)]
48         [ComDefaultInterfaceAttribute (typeof (_Assembly))]
49 #endif
50         [Serializable]
51         [ClassInterface(ClassInterfaceType.None)]
52         public class Assembly : System.Reflection.ICustomAttributeProvider, _Assembly,
53                 System.Security.IEvidenceFactory, System.Runtime.Serialization.ISerializable {
54
55                 internal class ResolveEventHolder {
56                         public event ModuleResolveEventHandler ModuleResolve;
57                 }
58
59                 // Note: changes to fields must be reflected in _MonoReflectionAssembly struct (object-internals.h)
60                 private IntPtr _mono_assembly;
61
62                 private ResolveEventHolder resolve_event_holder;
63                 private Evidence _evidence;
64                 internal PermissionSet _minimum;        // for SecurityAction.RequestMinimum
65                 internal PermissionSet _optional;       // for SecurityAction.RequestOptional
66                 internal PermissionSet _refuse;         // for SecurityAction.RequestRefuse
67                 private PermissionSet _granted;         // for the resolved assembly granted permissions
68                 private PermissionSet _denied;          // for the resolved assembly denied permissions
69                 private bool fromByteArray;
70                 private string assemblyName;
71
72                 internal Assembly () 
73                 {
74                         resolve_event_holder = new ResolveEventHolder ();
75                 }
76
77                 //
78                 // We can't store the event directly in this class, since the
79                 // compiler would silently insert the fields before _mono_assembly
80                 //
81                 public event ModuleResolveEventHandler ModuleResolve {
82                         [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
83                         add {
84                                 resolve_event_holder.ModuleResolve += value;
85                         }
86                         [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
87                         remove {
88                                 resolve_event_holder.ModuleResolve -= value;
89                         }
90                 }
91
92                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
93                 private extern string get_code_base (bool escaped);
94
95                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
96                 private extern string get_location ();
97
98                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
99                 private extern string InternalImageRuntimeVersion ();
100
101                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
102                 private extern bool get_global_assembly_cache ();
103
104                 // SECURITY: this should be the only caller to icall get_code_base
105                 private string GetCodeBase (bool escaped)
106                 {
107                         string cb = get_code_base (escaped);
108                         if (SecurityManager.SecurityEnabled) {
109                                 // we cannot divulge local file informations
110                                 if (String.Compare ("FILE://", 0, cb, 0, 7, true, CultureInfo.InvariantCulture) == 0) {
111                                         string file = cb.Substring (7);
112                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, file).Demand ();
113                                 }
114                         }
115                         return cb;
116                 }
117
118                 public virtual string CodeBase {
119                         get { return GetCodeBase (false); }
120                 }
121
122                 public virtual string EscapedCodeBase {
123                         get { return GetCodeBase (true); }
124                 }
125
126                 public virtual string FullName {
127                         get {
128                                 //
129                                 // FIXME: This is wrong, but it gets us going
130                                 // in the compiler for now
131                                 //
132                                 return ToString ();
133                         }
134                 }
135
136                 public virtual extern MethodInfo EntryPoint {
137                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
138                         get;
139                 }
140
141                 public virtual Evidence Evidence {
142                         [SecurityPermission (SecurityAction.Demand, ControlEvidence = true)]
143                         get { return UnprotectedGetEvidence (); }
144                 }
145
146                 // note: the security runtime requires evidences but may be unable to do so...
147                 internal Evidence UnprotectedGetEvidence ()
148                 {
149                         // if the host (runtime) hasn't provided it's own evidence...
150                         if (_evidence == null) {
151                                 // ... we will provide our own
152                                 lock (this) {
153                                         _evidence = Evidence.GetDefaultHostEvidence (this);
154                                 }
155                         }
156                         return _evidence;
157                 }
158
159                 public bool GlobalAssemblyCache {
160                         get {
161                                 return get_global_assembly_cache ();
162                         }
163                 }
164
165                 internal bool FromByteArray {
166                         set { fromByteArray = true; }
167                 }
168
169                 public virtual String Location {
170                         get {
171                                 if (fromByteArray)
172                                         return String.Empty;
173
174                                 string loc = get_location ();
175                                 if ((loc != String.Empty) && SecurityManager.SecurityEnabled) {
176                                         // we cannot divulge local file informations
177                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, loc).Demand ();
178                                 }
179                                 return loc;
180                         }
181                 }
182
183 #if NET_1_1
184                 [ComVisible (false)]
185                 public virtual string ImageRuntimeVersion {
186                         get {
187                                 return InternalImageRuntimeVersion ();
188                         }
189                 }
190 #endif
191
192                 [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
193                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
194                 {
195                         if (info == null)
196                                 throw new ArgumentNullException ("info");
197
198                         UnitySerializationHolder.GetAssemblyData (this, info, context);
199                 }
200
201 #if ONLY_1_1
202                 public new Type GetType ()
203                 {
204                         return base.GetType ();
205                 }
206 #endif
207
208                 public virtual bool IsDefined (Type attributeType, bool inherit)
209                 {
210                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
211                 }
212
213                 public virtual object [] GetCustomAttributes (bool inherit)
214                 {
215                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
216                 }
217
218                 public virtual object [] GetCustomAttributes (Type attributeType, bool inherit)
219                 {
220                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
221                 }
222
223                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
224                 private extern object GetFilesInternal (String name, bool getResourceModules);
225
226                 public virtual FileStream[] GetFiles ()
227                 {
228                         return GetFiles (false);
229                 }
230
231                 public virtual FileStream [] GetFiles (bool getResourceModules)
232                 {
233                         string[] names = (string[]) GetFilesInternal (null, getResourceModules);
234                         if (names == null)
235                                 return new FileStream [0];
236
237                         FileStream[] res = new FileStream [names.Length];
238                         for (int i = 0; i < names.Length; ++i)
239                                 res [i] = new FileStream (names [i], FileMode.Open, FileAccess.Read);
240                         return res;
241                 }
242
243                 public virtual FileStream GetFile (String name)
244                 {
245                         if (name == null)
246                                 throw new ArgumentNullException ("name");
247                         if (name.Length == 0)
248                                 throw new ArgumentException ("name");
249
250                         string filename = (string)GetFilesInternal (name, true);
251                         if (filename != null)
252                                 return new FileStream (filename, FileMode.Open, FileAccess.Read);
253                         else
254                                 return null;
255                 }
256
257                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
258                 internal extern IntPtr GetManifestResourceInternal (String name, out int size, out Module module);
259
260                 public virtual Stream GetManifestResourceStream (String name)
261                 {
262                         if (name == null)
263                                 throw new ArgumentNullException ("name");
264                         if (name.Length == 0)
265                                 throw new ArgumentException ("String cannot have zero length.",
266                                         "name");
267
268                         ManifestResourceInfo info = GetManifestResourceInfo (name);
269                         if (info == null)
270                                 return null;
271
272                         if (info.ReferencedAssembly != null)
273                                 return info.ReferencedAssembly.GetManifestResourceStream (name);
274                         if ((info.FileName != null) && (info.ResourceLocation == 0)) {
275                                 if (fromByteArray)
276 #if NET_2_0
277                                         throw new FileNotFoundException (info.FileName);
278 #else
279                                         return null;
280 #endif
281
282                                 string filename = Path.Combine (Path.GetDirectoryName (Location),
283                                                                                         info.FileName);
284                                 return new FileStream (filename, FileMode.Open, FileAccess.Read);
285                         }
286
287                         int size;
288                         Module module;
289                         IntPtr data = GetManifestResourceInternal (name, out size, out module);
290                         if (data == (IntPtr) 0)
291                                 return null;
292                         else {
293                                 IntPtrStream stream = new IntPtrStream (data, size);
294                                 /* 
295                                  * The returned pointer points inside metadata, so
296                                  * we have to increase the refcount of the module, and decrease
297                                  * it when the stream is finalized.
298                                  */
299                                 stream.Closed += new EventHandler (new ResourceCloseHandler (module).OnClose);
300                                 return stream;
301                         }
302                 }
303
304                 public virtual Stream GetManifestResourceStream (Type type, String name)
305                 {
306                         string ns;
307                         if (type != null) {
308                                 ns = type.Namespace;
309                         } else {
310                                 if (name == null)
311                                         throw new ArgumentNullException ("type");
312                                 ns = null;
313                         }
314
315                         if (ns == null || ns.Length == 0)
316                                 return GetManifestResourceStream (name);
317                         else
318                                 return GetManifestResourceStream (ns + "." + name);
319                 }
320
321                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
322                 private extern Type[] GetTypes (bool exportedOnly);
323                 
324                 public virtual Type[] GetTypes ()
325                 {
326                         return GetTypes (false);
327                 }
328
329                 public virtual Type[] GetExportedTypes ()
330                 {
331                         return GetTypes (true);
332                 }
333
334                 public virtual Type GetType (String name, Boolean throwOnError)
335                 {
336                         return GetType (name, throwOnError, false);
337                 }
338
339                 public virtual Type GetType (String name) {
340                         return GetType (name, false, false);
341                 }
342
343                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
344                 internal extern Type InternalGetType (Module module, String name, Boolean throwOnError, Boolean ignoreCase);
345
346                 public Type GetType (string name, bool throwOnError, bool ignoreCase)
347                 {
348                         if (name == null)
349                                 throw new ArgumentNullException (name);
350
351                         return InternalGetType (null, name, throwOnError, ignoreCase);
352                 }
353
354                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
355                 internal extern static void InternalGetAssemblyName (string assemblyFile, AssemblyName aname);
356                 
357                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
358                 static extern void FillName (Assembly ass, AssemblyName aname);
359
360                 [MonoTODO ("copiedName == true is not supported")]
361                 public virtual AssemblyName GetName (Boolean copiedName)
362                 {
363                         // CodeBase, which is restricted, will be copied into the AssemblyName object so...
364                         if (SecurityManager.SecurityEnabled) {
365                                 GetCodeBase (true); // this will ensure the Demand is made
366                         }
367                         return UnprotectedGetName ();
368                 }
369
370                 public virtual AssemblyName GetName ()
371                 {
372                         return GetName (false);
373                 }
374
375                 // the security runtime requires access to the assemblyname (e.g. to get the strongname)
376                 internal virtual AssemblyName UnprotectedGetName ()
377                 {
378                         AssemblyName aname = new AssemblyName ();
379                         FillName (this, aname);
380                         return aname;
381                 }
382
383                 public override string ToString ()
384                 {
385                         // note: ToString work without requiring CodeBase (so no checks are needed)
386
387                         if (assemblyName != null)
388                                 return assemblyName;
389
390                         AssemblyName aname = new AssemblyName ();
391                         FillName (this, aname);
392                         assemblyName = aname.ToString ();
393
394                         return assemblyName;
395                 }
396
397                 public static String CreateQualifiedName (String assemblyName, String typeName) 
398                 {
399                         return typeName + ", " + assemblyName;
400                 }
401
402                 public static Assembly GetAssembly (Type type)
403                 {
404                         if (type != null)
405                                 return type.Assembly;
406                         throw new ArgumentNullException ("type");
407                 }
408
409
410                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
411                 public static extern Assembly GetEntryAssembly();
412
413                 public Assembly GetSatelliteAssembly (CultureInfo culture)
414                 {
415                         return GetSatelliteAssembly (culture, null);
416                 }
417
418                 public Assembly GetSatelliteAssembly (CultureInfo culture, Version version)
419                 {
420                         if (culture == null)
421                                 throw new ArgumentException ("culture");
422
423                         AssemblyName aname = GetName (true);
424                         if (version != null)
425                                 aname.Version = version;
426
427                         aname.CultureInfo = culture;
428                         aname.Name = aname.Name + ".resources";
429                         return Load (aname);
430                 }
431                 
432                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
433                 private extern static Assembly LoadFrom (String assemblyFile, bool refonly);
434
435                 public static Assembly LoadFrom (String assemblyFile)
436                 {
437                         return LoadFrom (assemblyFile, false);
438                 }
439
440                 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence)
441                 {
442                         Assembly a = LoadFrom (assemblyFile, false);
443                         if ((a != null) && (securityEvidence != null)) {
444                                 // merge evidence (i.e. replace defaults with provided evidences)
445                                 a.Evidence.Merge (securityEvidence);
446                         }
447                         return a;
448                 }
449
450 #if NET_1_1
451
452                 [MonoTODO("This overload is not currently implemented")]
453                 // FIXME: What are we missing?
454                 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
455                 {
456                         if (assemblyFile == null)
457                                 throw new ArgumentNullException ("assemblyFile");
458                         if (assemblyFile == String.Empty)
459                                 throw new ArgumentException ("Name can't be the empty string", "assemblyFile");
460                         throw new NotImplementedException ();
461                 }
462
463                 public static Assembly LoadFile (String path, Evidence securityEvidence)
464                 {
465                         if (path == null)
466                                 throw new ArgumentNullException ("path");
467                         if (path == String.Empty)
468                                 throw new ArgumentException ("Path can't be empty", "path");
469                         // FIXME: Make this do the right thing
470                         return LoadFrom (path, securityEvidence);
471                 }
472
473                 public static Assembly LoadFile (String path)
474                 {
475                         return LoadFile (path, null);
476                 }
477 #endif
478
479                 public static Assembly Load (String assemblyString)
480                 {
481                         return AppDomain.CurrentDomain.Load (assemblyString);
482                 }
483                 
484                 public static Assembly Load (String assemblyString, Evidence assemblySecurity)
485                 {
486                         return AppDomain.CurrentDomain.Load (assemblyString, assemblySecurity);
487                 }
488
489                 public static Assembly Load (AssemblyName assemblyRef)
490                 {
491                         return AppDomain.CurrentDomain.Load (assemblyRef);
492                 }
493
494                 public static Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
495                 {
496                         return AppDomain.CurrentDomain.Load (assemblyRef, assemblySecurity);
497                 }
498
499                 public static Assembly Load (Byte[] rawAssembly)
500                 {
501                         return AppDomain.CurrentDomain.Load (rawAssembly);
502                 }
503
504                 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore)
505                 {
506                         return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore);
507                 }
508
509                 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore,
510                                              Evidence securityEvidence)
511                 {
512                         return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore, securityEvidence);
513                 }
514
515 #if NET_2_0
516                 public static Assembly ReflectionOnlyLoad (byte[] rawAssembly)
517                 {
518                         return AppDomain.CurrentDomain.Load (rawAssembly, null, null, true);
519                 }
520
521                 public static Assembly ReflectionOnlyLoad (string assemblyName) 
522                 {
523                         return AppDomain.CurrentDomain.Load (assemblyName, null, true);
524                 }
525
526                 public static Assembly ReflectionOnlyLoadFrom (string assemblyFile) 
527                 {
528                         if (assemblyFile == null)
529                                 throw new ArgumentNullException ("assemblyFile");
530                         
531                         return LoadFrom (assemblyFile, true);
532                 }
533 #endif
534
535 #if NET_2_0
536                 [Obsolete ("")]
537 #endif
538                 public static Assembly LoadWithPartialName (string partialName)
539                 {
540                         return LoadWithPartialName (partialName, null);
541                 }
542
543                 [MonoTODO ("Not implemented")]
544                 public Module LoadModule (string moduleName, byte [] rawModule)
545                 {
546                         throw new NotImplementedException ();
547                 }
548
549                 [MonoTODO ("Not implemented")]
550                 public Module LoadModule (string moduleName, byte [] rawModule, byte [] rawSymbolStore)
551                 {
552                         throw new NotImplementedException ();
553                 }
554
555                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
556                 private static extern Assembly load_with_partial_name (string name, Evidence e);
557
558 #if NET_2_0
559                 [Obsolete ("")]
560 #endif
561                 public static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence)
562                 {
563                         return LoadWithPartialName (partialName, securityEvidence, true);
564                 }
565
566                 /**
567                  * LAMESPEC: It is possible for this method to throw exceptions IF the name supplied
568                  * is a valid gac name and contains filesystem entry charachters at the end of the name
569                  * ie System/// will throw an exception. However ////System will not as that is canocolized
570                  * out of the name.
571                  */
572
573                 // FIXME: LoadWithPartialName must look cache (no CAS) or read from disk (CAS)
574                 internal static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence, bool oldBehavior)
575                 {
576                         if (!oldBehavior)
577                                 throw new NotImplementedException ();
578
579                         if (partialName == null)
580                                 throw new NullReferenceException ();
581
582                         return load_with_partial_name (partialName, securityEvidence);
583                 }
584
585                 public Object CreateInstance (String typeName) 
586                 {
587                         return CreateInstance (typeName, false);
588                 }
589
590                 public Object CreateInstance (String typeName, Boolean ignoreCase)
591                 {
592                         Type t = GetType (typeName, false, ignoreCase);
593                         if (t == null)
594                                 return null;
595
596                         try {
597                                 return Activator.CreateInstance (t);
598                         } catch (InvalidOperationException) {
599                                 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
600                         }
601                 }
602
603                 public Object CreateInstance (String typeName, Boolean ignoreCase,
604                                               BindingFlags bindingAttr, Binder binder,
605                                               Object[] args, CultureInfo culture,
606                                               Object[] activationAttributes)
607                 {
608                         Type t = GetType (typeName, false, ignoreCase);
609                         if (t == null)
610                                 return null;
611
612                         try {
613                                 return Activator.CreateInstance (t, bindingAttr, binder, args, culture, activationAttributes);
614                         } catch (InvalidOperationException) {
615                                 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
616                         }
617                 }
618
619                 public Module[] GetLoadedModules ()
620                 {
621                         return GetLoadedModules (false);
622                 }
623
624                 // FIXME: Currently, the two sets of modules are equal
625                 public Module[] GetLoadedModules (bool getResourceModules)
626                 {
627                         return GetModules (getResourceModules);
628                 }
629
630                 public Module[] GetModules ()
631                 {
632                         return GetModules (false);
633                 }
634
635                 public Module GetModule (String name)
636                 {
637                         if (name == null)
638                                 throw new ArgumentNullException ("name");
639                         if (name.Length == 0)
640                                 throw new ArgumentException ("Name can't be empty");
641
642                         Module[] modules = GetModules (true);
643                         foreach (Module module in modules) {
644                                 if (module.ScopeName == name)
645                                         return module;
646                         }
647
648                         return null;
649                 }
650
651                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
652                 internal extern Module[] GetModulesInternal ();
653
654                 public Module[] GetModules (bool getResourceModules) {
655                         Module[] modules = GetModulesInternal ();
656
657                         if (!getResourceModules) {
658                                 ArrayList result = new ArrayList (modules.Length);
659                                 foreach (Module m in modules)
660                                         if (!m.IsResource ())
661                                                 result.Add (m);
662                                 return (Module[])result.ToArray (typeof (Module));
663                         }
664                         else
665                                 return modules;
666                 }
667
668                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
669                 internal extern string[] GetNamespaces ();
670                 
671                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
672                 public extern virtual String[] GetManifestResourceNames ();
673
674                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
675                 public extern static Assembly GetExecutingAssembly ();
676
677                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
678                 public extern static Assembly GetCallingAssembly ();
679
680                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
681                 public extern AssemblyName[] GetReferencedAssemblies ();
682
683                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
684                 private extern bool GetManifestResourceInfoInternal (String name, ManifestResourceInfo info);
685
686                 public virtual ManifestResourceInfo GetManifestResourceInfo (String resourceName)
687                 {
688                         if (resourceName == null)
689                                 throw new ArgumentNullException ("resourceName");
690                         if (resourceName.Length == 0)
691                                 throw new ArgumentException ("String cannot have zero length.");
692                         ManifestResourceInfo result = new ManifestResourceInfo ();
693                         bool found = GetManifestResourceInfoInternal (resourceName, result);
694                         if (found)
695                                 return result;
696                         else
697                                 return null;
698                 }
699
700                 private class ResourceCloseHandler {
701
702                         Module module;
703
704                         public ResourceCloseHandler (Module module) {
705                                 this.module = module;
706                         }
707
708                         public void OnClose (object sender, EventArgs e) {
709                                 // The module dtor will take care of things
710                                 module = null;
711                         }
712                 }
713
714                 //
715                 // The following functions are only for the Mono Debugger.
716                 //
717
718                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
719                 internal static extern int MonoDebugger_GetMethodToken (MethodBase method);
720
721 #if NET_2_0
722                 [MonoTODO ("Always returns zero")]
723                 [ComVisible (false)]
724                 public long HostContext {
725                         get { return 0; }
726                 }
727
728                 [ComVisible (false)]
729                 public Module ManifestModule {
730                         get {
731                                 return GetManifestModule ();
732                         }
733                 }
734
735                 internal virtual Module GetManifestModule () {
736                         return GetManifestModuleInternal ();
737                 }
738
739                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
740                 internal extern Module GetManifestModuleInternal ();
741
742                 [ComVisible (false)]
743                 public virtual extern bool ReflectionOnly {
744                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
745                         get;
746                 }
747 #endif
748
749                 // Code Access Security
750
751                 internal void Resolve () 
752                 {
753                         lock (this) {
754                                 // FIXME: As we (currently) delay the resolution until the first CAS
755                                 // Demand it's too late to evaluate the Minimum permission set as a 
756                                 // condition to load the assembly into the AppDomain
757                                 LoadAssemblyPermissions ();
758                                 Evidence e = new Evidence (UnprotectedGetEvidence ()); // we need a copy to add PRE
759                                 e.AddHost (new PermissionRequestEvidence (_minimum, _optional, _refuse));
760                                 _granted = SecurityManager.ResolvePolicy (e,
761                                         _minimum, _optional, _refuse, out _denied);
762                         }
763                 }
764
765                 internal PermissionSet GrantedPermissionSet {
766                         get {
767                                 if (_granted == null) {
768                                         if (SecurityManager.ResolvingPolicyLevel != null) {
769                                                 if (SecurityManager.ResolvingPolicyLevel.IsFullTrustAssembly (this))
770                                                         return DefaultPolicies.FullTrust;
771                                                 else
772                                                         return null; // we can't resolve during resolution
773                                         }
774                                         Resolve ();
775                                 }
776                                 return _granted;
777                         }
778                 }
779
780                 internal PermissionSet DeniedPermissionSet {
781                         get {
782                                 // yes we look for granted, as denied may be null
783                                 if (_granted == null) {
784                                         if (SecurityManager.ResolvingPolicyLevel != null) {
785                                                 if (SecurityManager.ResolvingPolicyLevel.IsFullTrustAssembly (this))
786                                                         return null;
787                                                 else
788                                                         return DefaultPolicies.FullTrust; // deny unrestricted
789                                         }
790                                         Resolve ();
791                                 }
792                                 return _denied;
793                         }
794                 }
795
796                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
797                 extern internal static bool LoadPermissions (Assembly a, 
798                         ref IntPtr minimum, ref int minLength,
799                         ref IntPtr optional, ref int optLength,
800                         ref IntPtr refused, ref int refLength);
801
802                 // Support for SecurityAction.RequestMinimum, RequestOptional and RequestRefuse
803                 private void LoadAssemblyPermissions ()
804                 {
805                         IntPtr minimum = IntPtr.Zero, optional = IntPtr.Zero, refused = IntPtr.Zero;
806                         int minLength = 0, optLength = 0, refLength = 0;
807                         if (LoadPermissions (this, ref minimum, ref minLength, ref optional,
808                                 ref optLength, ref refused, ref refLength)) {
809
810                                 // Note: no need to cache these permission sets as they will only be created once
811                                 // at assembly resolution time.
812                                 if (minLength > 0) {
813                                         byte[] data = new byte [minLength];
814                                         Marshal.Copy (minimum, data, 0, minLength);
815                                         _minimum = SecurityManager.Decode (data);
816                                 }
817                                 if (optLength > 0) {
818                                         byte[] data = new byte [optLength];
819                                         Marshal.Copy (optional, data, 0, optLength);
820                                         _optional = SecurityManager.Decode (data);
821                                 }
822                                 if (refLength > 0) {
823                                         byte[] data = new byte [refLength];
824                                         Marshal.Copy (refused, data, 0, refLength);
825                                         _refuse = SecurityManager.Decode (data);
826                                 }
827                         }
828                 }
829         }
830 }