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