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